diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md new file mode 100644 index 00000000..e2c1bdb8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -0,0 +1,44 @@ +--- +name: Bug report +about: Report an issue or unexpected behavior with GameHub +--- + + + +###### Expected behavior + + + +###### Actual behavior + + + +###### Steps to reproduce + + + +###### Version and environment + + +``` +PASTE VERSION INFO HERE +``` diff --git a/.github/ISSUE_TEMPLATE/crash.md b/.github/ISSUE_TEMPLATE/crash.md new file mode 100644 index 00000000..03cc8ae8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/crash.md @@ -0,0 +1,57 @@ +--- +name: Crash report +about: Report GameHub crashing under some circumstances +--- + + + +###### Steps to reproduce + + + +###### Version and environment + + +``` +PASTE VERSION INFO HERE +``` + +###### GDB log + + + +
+GDB log + +``` +PASTE LOG HERE +``` + +
diff --git a/.github/ISSUE_TEMPLATE/feature.md b/.github/ISSUE_TEMPLATE/feature.md new file mode 100644 index 00000000..c388685c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature.md @@ -0,0 +1,10 @@ +--- +name: New feature +about: Request new functionality +--- + + diff --git a/.github/ISSUE_TEMPLATE/improvement.md b/.github/ISSUE_TEMPLATE/improvement.md new file mode 100644 index 00000000..8eb0d6b8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/improvement.md @@ -0,0 +1,10 @@ +--- +name: Improvement +about: Request a change that isn't a bug or new feature +--- + + diff --git a/.gitignore b/.gitignore index 567609b1..68fa3114 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,20 @@ build/ + +debian/* +!debian/source/ +!debian/changelog +!debian/changelog.in +!debian/compat +!debian/control.in +!debian/copyright +!debian/rules.in + +flatpak/com.github.tkashkin.gamehub.json +flatpak/.flatpak-builder/ + +*~ + +.buildconfig + +snap/* +!snap/snapcraft.yaml diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..75336a76 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "flatpak/libs/shared"] + path = flatpak/libs/shared + url = https://github.com/flathub/shared-modules.git diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..d81c0620 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,28 @@ +--- + +language: node_js + +node_js: + - lts/* + +sudo: required + +services: + - docker + +addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - libstdc++-5-dev + +cache: + directories: + - /tmp/liftoff + +install: + - npm install @elementaryos/houston + +script: + - houston ci diff --git a/COPYING b/COPYING index 8cffccc1..f288702d 100644 --- a/COPYING +++ b/COPYING @@ -1,13 +1,674 @@ - DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE - Version 2, December 2004 + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 - Copyright (C) 2004 Sam Hocevar + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. - Everyone is permitted to copy and distribute verbatim or modified - copies of this license document, and changing it is allowed as long - as the name is changed. + Preamble - DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + The GNU General Public License is a free, copyleft license for +software and other kinds of works. - 0. You just DO WHAT THE FUCK YOU WANT TO. \ No newline at end of file + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 00000000..d36f659e --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,145 @@ +# Installation + +## Table of contents + +* [Distribution-specific packages](#distribution-specific-packages) + - [Arch-based distributions](#arch-based-distributions) + - [Debian](#debian) + - [Fedora](#fedora) + - [OpenMandriva](#openmandriva) + - [openSUSE](#opensuse) + - [Pop!\_OS](#pop_os) + - [Solus](#Solus) + - [Ubuntu-based distributions](#ubuntu-based-distributions) +* [Portable packages](#portable-packages) + - [AppImage](#appimage) + - [Flatpak](#flatpak) +* [Prebuilt releases](#prebuilt-releases) +* [Build from source](#build-from-source) + - [Dependencies](#dependencies) + - [Debian and Ubuntu-based distributions](#debian-and-ubuntu-based-distributions) + - [Other distributions](#other-distributions) + +## Distribution-specific packages + +### Arch-based distributions +[`gamehub-git`](https://aur.archlinux.org/packages/gamehub-git) and [`gamehub`](https://aur.archlinux.org/packages/gamehub) are available in AUR. + +### Debian +Install Debian package from the [releases page](https://github.com/tkashkin/GameHub/releases) or import the [PPA](https://launchpad.net/~tkashkin/+archive/ubuntu/gamehub): +```bash +sudo apt install dirmngr +sudo sh -c "echo 'deb http://ppa.launchpad.net/tkashkin/gamehub/ubuntu focal main' > /etc/apt/sources.list.d/gamehub-ppa.list" +sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 5B63B42CE14BA47CC1B69E7C32B600D632AF380D +sudo apt update +sudo apt install com.github.tkashkin.gamehub +``` + +### Fedora +Package is available in Fedora repository: +```bash +sudo dnf install gamehub +``` + +### OpenMandriva +[`gamehub`](https://abf.openmandriva.org/openmandriva/gamehub/build_lists) is available in the OpenMandriva repository. + +### openSUSE +```bash +sudo zypper install gamehub +``` + +### Pop!\_OS +Package is available in Pop!\_OS repository: +```bash +sudo apt install com.github.tkashkin.gamehub +``` + +### Solus +Package is available in Solus repository: +```bash +sudo eopkg install gamehub +``` + + +### Ubuntu-based distributions +Install Debian package from the [releases page](https://github.com/tkashkin/GameHub/releases) or import the [PPA](https://launchpad.net/~tkashkin/+archive/ubuntu/gamehub): +```bash +# install if `add-apt-repository` is not available +sudo apt install --no-install-recommends software-properties-common + +sudo add-apt-repository ppa:tkashkin/gamehub +sudo apt update +sudo apt install com.github.tkashkin.gamehub +``` + +## Portable packages + +### AppImage +AppImages can be found in the [releases page](https://github.com/tkashkin/GameHub/releases). + +**WARNING: AppImages are unstable! You might experience issues.** + +### Flatpak +Flatpak releases can be found in the [releases page](https://github.com/tkashkin/GameHub/releases). + +**WARNING: Flatpak releases are unstable! You might experience issues.** + +Install the package by executing this command: +```bash +flatpak install GameHub-*.flatpak +``` + +If you want to build it from source instead of installing the binary, execute the commands: +```bash +git clone https://github.com/tkashkin/GameHub.git +cd GameHub +scripts/build.sh build_flatpak +``` + +## Prebuilt releases +Prebuilt releases can be found in the [releases page](https://github.com/tkashkin/GameHub/releases). + +## Build from source + +### Dependencies +* `meson` +* `valac` +* `libgtk-3-dev` +* `libglib2.0-dev` +* `libwebkit2gtk-4.0-dev` +* `libjson-glib-dev` +* `libgee-0.8-dev` +* `libsoup2.4-dev` +* `libsqlite3-dev` +* `libxml2-dev` +* `libpolkit-gobject-1-dev` +* `libunity-dev` (optional, required for launcher icon quicklist, progress indicator and counter; pass `-Duse_libunity=true` to `meson` to use) +* `libmanette-0.2-dev`, `libx11-dev`, `libxtst-dev` (optional, required for gamepad support) + +### Debian and Ubuntu-based distributions +* Build a .deb package (this will build `GameHub-*.deb` package in the parent directory): +```bash +git clone https://github.com/tkashkin/GameHub.git +cd GameHub +scripts/build.sh build_deb +``` +* Install built package: +```bash +sudo apt install ../GameHub-*.deb +``` + +### Other distributions +* Build: +```bash +git clone https://github.com/tkashkin/GameHub.git +cd GameHub +meson build --prefix=/usr --buildtype=debug +cd build +ninja +``` +* Install: +```bash +sudo ninja install +``` +Do not remove build directory if you want to uninstall GameHub later, build directory is used in uninstallation process. diff --git a/README.md b/README.md index 63eac847..71b13ec1 100644 --- a/README.md +++ b/README.md @@ -1 +1,43 @@ -# GameHub +# [GameHub](https://tkashkin.tk/projects/gamehub) [![Build status](https://ci.appveyor.com/api/projects/status/cgw5hc4kos4uvmy9/branch/master?svg=true)](https://ci.appveyor.com/project/tkashkin/gamehub/branch/master) [![Translation status](https://hosted.weblate.org/widgets/gamehub/-/translations/svg-badge.svg)](https://hosted.weblate.org/engage/gamehub/?utm_source=widget) +Mirrors: [GitHub](https://github.com/tkashkin/GameHub), [codeberg.org](https://codeberg.org/tkashkin/GameHub), [repo.or.cz](https://repo.or.cz/GameHub.git), [git.froggi.es](https://git.froggi.es/tkashkin/gamehub) + +## Overview +GameHub is a unified library for all your games. It allows you to store your games from different platforms into one program to make it easier for you to manage your games. + +### [Features](https://tkashkin.tk/projects/gamehub/#/features) +With GameHub, you can: +* store your games in one place +* login to multiple platforms +* install games from the supported sources +* download game installers, DLCs and bonus content +* automatically find artwork for games on [SteamGridDB](https://steamgriddb.com) +* setup emulators and automatically import emulated games + +GameHub also has features like: +* [Overlays](https://tkashkin.tk/projects/gamehub/#/overlays) — multiple directories applied on top of each other. Each overlay is stored separately and doesn't affect other overlays. Overlays can be useful to manage DLCs and mods +* [Tweaks](https://github.com/tkashkin/GameHub/wiki/Tweaks) — environment variable and command line overrides that can be applied to games automatically + +GameHub supports: +* native games for Linux +* multiple [compatibility layers](https://github.com/tkashkin/GameHub/wiki/Compatibility-layers): + - Wine + - Proton + - DOSBox + - RetroArch + - ScummVM + - [WineWrap](https://www.gog.com/forum/general/adamhms_linux_wine_wrappers_news_faq_discussion/post1) — a set of preconfigured wrappers for [supported games](https://www.gog.com/forum/general/adamhms_linux_wine_wrappers_news_faq_discussion/post3); + - custom emulators +* multiple game platforms: + - Steam + - GOG + - Humble Bundle (including Humble Trove) + - itch.io + +## Installation +See [INSTALL.md](INSTALL.md). + +## Building +See [INSTALL.md#Source](INSTALL.md#build-from-source). + +## [Screenshots](https://tkashkin.tk/projects/gamehub/#/screenshots) +

diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 00000000..52b9470b --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,45 @@ +version: 0.16.0-{build}-{branch} + +pull_requests: + do_not_increment_build_number: true + +skip_tags: true + +image: + - Ubuntu1804 +# - Ubuntu1604 # skip xenial builds because dependencies are broken + +clone_folder: ~/build/GameHub + +environment: + keys_enc_secret: + secure: VBUP6GQXENGa7E+H90WDhA== + +build_script: + - sh: bash scripts/build.sh gen_changelogs + - sh: bash scripts/build.sh build_deb + - sh: bash scripts/build.sh build_appimage + - sh: bash scripts/build.sh build_flatpak + +install: + - sh: bash scripts/build.sh import_keys + - sh: bash scripts/build.sh deps + +test: off + +artifacts: + - path: build/*/*.deb + name: deb + - path: build/appimage/GameHub*.AppImage + name: AppImage + - path: build/flatpak/GameHub*.flatpak + name: flatpak + +deploy: + - provider: GitHub + description: CI build + auth_token: + secure: J2LCcNeVYvzbvHRa/LChp+SmN6UKbg1ELsA4jmxnObCbX+ZyZ9DFH+S2aQIoA3dG + artifact: deb,AppImage,flatpak + draft: false + prerelease: true diff --git a/data/GameHub.css b/data/GameHub.css deleted file mode 100644 index ce713e6d..00000000 --- a/data/GameHub.css +++ /dev/null @@ -1,13 +0,0 @@ -.gamecard -{ - border-radius: 2px; -} - -.gamecard GtkLabel -{ - color: rgba(255, 255, 255, 0.9); - font-weight: bold; - font-size: 1.3em; - text-shadow: 0 2px 4px rgba(0, 0, 0, 0.6); - background-image: linear-gradient(to top, rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0)); -} diff --git a/data/com.github.tkashkin.gamehub-overlayfs-helper b/data/com.github.tkashkin.gamehub-overlayfs-helper new file mode 100755 index 00000000..ad3a14d4 --- /dev/null +++ b/data/com.github.tkashkin.gamehub-overlayfs-helper @@ -0,0 +1,26 @@ +#!/bin/bash + +if [[ $EUID -ne 0 ]]; then + echo "This script requires root permissions" + exit 1 +fi + +ACTION="$1" +OVERLAY_ID="$2" + +case "$ACTION" in + mount) + MOUNT_OPTIONS="$3" + TARGET="$4" + mount -t overlay "$OVERLAY_ID" -o "$MOUNT_OPTIONS" "$TARGET" + ;; + + umount) + umount "$OVERLAY_ID" + ;; + + *) + echo "This script only allows to (u)mount overlays" + exit 2 + ;; +esac diff --git a/data/com.github.tkashkin.gamehub.appdata.xml.in b/data/com.github.tkashkin.gamehub.appdata.xml.in index 9ce9ea03..5e9ea637 100644 --- a/data/com.github.tkashkin.gamehub.appdata.xml.in +++ b/data/com.github.tkashkin.gamehub.appdata.xml.in @@ -1,30 +1,57 @@ - com.github.tkashkin.gamehub.desktop - + com.github.tkashkin.gamehub + CC0-1.0 - WTFPL - + GPL-3.0+ + GameHub All your games in one place - + -

Manage your Steam and GOG games in one place.

+

Manage your Steam, GOG and Humble Bundle games in one place.

- - tkashkin - https://github.com/tkashkin/GameHub + + Anatoliy Kashkin + ​tkashkin@gmail.com + https://tkashkin.tk/projects/gamehub https://github.com/tkashkin/GameHub/issues - + https://hosted.weblate.org/engage/gamehub + com.github.tkashkin.gamehub com.github.tkashkin.gamehub.desktop - + + https://raw.githubusercontent.com/tkashkin/GameHub/e380a848b89498904e96e73fa72a07aa823151ce/data/icon/128.svg?sanitize=true + + + + https://raw.githubusercontent.com/tkashkin/GameHub/ff8ed17491681757f2e08618d6d052cdfcec9357/data/screenshots/light/welcome.png + + + https://raw.githubusercontent.com/tkashkin/GameHub/ff8ed17491681757f2e08618d6d052cdfcec9357/data/screenshots/dark/grid.png + + + https://raw.githubusercontent.com/tkashkin/GameHub/ff8ed17491681757f2e08618d6d052cdfcec9357/data/screenshots/light/list.png + + + https://raw.githubusercontent.com/tkashkin/GameHub/ff8ed17491681757f2e08618d6d052cdfcec9357/data/screenshots/dark/details.png + + + https://raw.githubusercontent.com/tkashkin/GameHub/ff8ed17491681757f2e08618d6d052cdfcec9357/data/screenshots/light/properties.png + + + - 1 + #7239b3 + #ffffff - + + + @CHANGELOG@ + + none none diff --git a/data/com.github.tkashkin.gamehub.changelog.xml b/data/com.github.tkashkin.gamehub.changelog.xml new file mode 100644 index 00000000..d20dfaa0 --- /dev/null +++ b/data/com.github.tkashkin.gamehub.changelog.xml @@ -0,0 +1,2746 @@ + + +
    +
  • Merge pull request #312 from Lucki/patch-1 [6075c9f]
  • +
  • Allow enabling d9vk [86b7d57]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Turkish) [006ff9f]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Turkish) [4d0a243]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Finnish) [4236830]
  • +
  • Translated using Weblate (Finnish) [8ae0e75]
  • +
  • Translated using Weblate (Catalan) [79c06dc]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Catalan) [7427529]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Finnish) [b20005b]
  • +
+
+
+ + +
    +
  • Added translation using Weblate (Finnish) [51f4546]
  • +
+
+
+ + +
    +
  • Added translation using Weblate (Catalan) [68f69e9]
  • +
+
+
+ + +
    +
  • Translated using Weblate (French) [cf641ac]
  • +
+
+
+ + +
    +
  • Translated using Weblate (French) [184c6e7]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Arabic) [f3ea1ed]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Arabic) [e851f70]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Arabic) [79598e1]
  • +
+
+
+ + +
    +
  • Translated using Weblate (French) [2c90003]
  • +
+
+
+ + +
    +
  • Translated using Weblate (French) [8f7f70c]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Indonesian) [a3a2e89]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Norwegian Bokmål) [4693bf5]
  • +
  • Translated using Weblate (Dutch) [6057099]
  • +
+
+
+ + +
    +
  • Added translation using Weblate (Korean) [07f10c6]
  • +
+
+
+ + +
    +
  • Performance and memory usage improvements (#57) SteamGridDB image sizes support Added menu when IGDB returns multiple results [30b9b5e]
  • +
  • Image cache changes Vertical game images support [a785155]
  • +
  • Translated using Weblate (German) [833d510]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Portuguese (Portugal)) [2a7ac4c]
  • +
+
+
+ + +
    +
  • Added translation using Weblate (Portuguese (Portugal)) [a5403de]
  • +
  • [ci skip] Fix ellipsis in string (#301) [905f530]
  • +
+
+
+ + +
    +
  • Translated using Weblate (French) [f02b1a6]
  • +
  • Translated using Weblate (German) [a7d2474]
  • +
  • [ci skip] Update translations [654105c]
  • +
+
+
+ + +
    +
  • Added translation using Weblate (Arabic) [1a969ce]
  • +
+
+
+ + +
    +
  • Prevent multiple game launches (#280, #281) [fcb80e5]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Norwegian Bokmål) [404b8bb]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Dutch) [3821042]
  • +
  • Translated using Weblate (Portuguese (Brazil)) [27c29ff]
  • +
+
+
+ + +
    +
  • Games grid size customization [8a89a89]
  • +
+
+
+ + +
    +
  • Steam-like game launch command overrides (#297) Improved GOG API error handling Small UI tweaks [075168a]
  • +
+
+
+ + +
    +
  • Refresh GOG access token on error (#294) [dfab162]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Telugu) [8e019ba]
  • +
+
+
+ + +
    +
  • Added translation using Weblate (Telugu) [5d97064]
  • +
+
+
+ + +
    +
  • Added translation using Weblate (Hindi) [f804511]
  • +
+
+
+ + +
    +
  • Fix `Game.get_file()` (#291) [eecf1db]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Persian) [9b67620]
  • +
+
+
+ + +
    +
  • Fix overlays detection (#291) [6498058]
  • +
+
+
+ + +
    +
  • Add type checks in `Proton.find_proton_versions` (#292, #101) [9b022f2]
  • +
  • Translated using Weblate (Persian) [d1df472]
  • +
+
+
+ + +
    +
  • Added translation using Weblate (Persian) [62adec9]
  • +
  • [ci skip] Update `scripts/build.sh` [97b2775]
  • +
+
+
+ + +
    +
  • Parse `appinfo.vdf` to find Proton versions (#292, #101) [788bb28]
  • +
+
+
+ + +
    +
  • Add `/opt/` and `/var/opt/` to FSOverlay allowed paths list (#290) Wait for overlays to mount before updating game status (#291) [f28cc89]
  • +
  • [ci skip] Update mirrors [4bb1b7f]
  • +
  • [ci skip] Update source code mirrors [a1fb490]
  • +
+
+
+ + +
    +
  • Merge branch 'dev' of https://hosted.weblate.org/git/gamehub/translations into dev [9548658]
  • +
  • Translated using Weblate (Portuguese (Brazil)) [0ae8e38]
  • +
  • Fix sort func in `GameTagsList` Improved portability: GameHub now can be built on Windows in MSYS2 environment (doesn't work yet) [acfec61]
  • +
+
+
+ + +
    +
  • Fix build with older `glib` and/or without `libmanette` [42aac9c]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Portuguese (Brazil)) [3eda1c3]
  • +
+
+
+ + +
    +
  • [ci skip] Bump version [be55ac0]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Norwegian Bokmål) [526c6f8]
  • +
  • Translated using Weblate (Dutch) [ad827dc]
  • +
+
+
+ + +
    +
  • Game details view improvements [c77df04]
  • +
  • Translated using Weblate (Chinese (Simplified)) [bece03f]
  • +
  • Translated using Weblate (Norwegian Bokmål) [aed8a1a]
  • +
  • Translated using Weblate (Dutch) [2462da6]
  • +
+
+
+ + +
    +
  • Unset ld env variables in `Utils.run*` for AppImage builds (#267) [bd9635c]
  • +
+
+
+ + +
    +
  • Add IGDB request quota warning [f9fb59c]
  • +
+
+
+ + +
    +
  • Prioritize user games over installed games over uninstalled games when all sources are shown (#282) Fix some merging bugs [8ac1f27]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Chinese (Simplified)) [de84182]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Norwegian Bokmål) [aa1d50d]
  • +
  • Translated using Weblate (Dutch) [8a917b4]
  • +
+
+
+ + +
    +
  • Fix slashes for DOSBox data_dirs (#279) [ff9270b]
  • +
+
+
+ + +
    +
  • DOSBox: verbose logging for data_dirs (#279) [2f7c584]
  • +
+
+
+ + +
    +
  • Add 'Open screenshots directory' action for Steam games (#277) [8865f62]
  • +
+
+
+ + +
    +
  • DOSBox improvements (#273) [c6bb7a8]
  • +
+
+
+ + +
    +
  • Add timeout after exiting game to prevent immediate restart due to keypresses (#275) [5dc13a8]
  • +
+
+
+ + +
    +
  • Add DOS exe/bat/com support to DOSBox CompatTool (#273) Reorder CompatTools Clear IGDB data cache for game when games is renamed (#274) [b286d46]
  • +
+
+
+ + +
    +
  • Allow to run executables in DOSBox without configs (#273) [e4b9623]
  • +
+
+
+ + +
    +
  • Fix Humble authentication page styles (#272) [2b9cb90]
  • +
+
+
+ + +
    +
  • Fix build with newer Vala compiler (#271) [9d0ff03]
  • +
+
+
+ + +
    +
  • Fix segfault in `GameListRow.update_style` (#255) [34b0109]
  • +
+
+
+ + +
    +
  • Reduce games list paddings (#265) [5c2fccf]
  • +
  • Translated using Weblate (Norwegian Bokmål) [c199c12]
  • +
  • Translated using Weblate (Dutch) [26a6755]
  • +
+
+
+ + +
    +
  • Merge translations [15a67ea]
  • +
  • Games list grouping options (#265) [5572bc1]
  • +
  • Translated using Weblate (Chinese (Simplified)) [bf75533]
  • +
  • Translated using Weblate (Norwegian Bokmål) [164b834]
  • +
  • Translated using Weblate (Dutch) [4c7b155]
  • +
+
+
+ + +
    +
  • Additional games list style options (#265) [e1292ae]
  • +
+
+
+ + +
    +
  • Tags can be removed (#266) Fix tags toggling (#268) [fa3012a]
  • +
+
+
+ + +
    +
  • Fix segfault when installing/downloading multiple games [a82e30a]
  • +
+
+
+ + +
    +
  • [ci skip] Bump version to 0.14.1 [dbb655c]
  • +
+
+
+ + +
    +
  • Remove `granite` dependency [e7bffdf]
  • +
  • FS overlays can now be removed/disabled (#120, #254) `GameFSOverlaysDialog` will now show warning or error depending on game's `install_dir` (#254) [c7ddab0]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Norwegian Bokmål) [d78eab3]
  • +
  • Translated using Weblate (Dutch) [5353619]
  • +
+
+
+ + +
    +
  • Added translation using Weblate (Greek) [371a9c9]
  • +
+
+
+ + +
    +
  • Allow multiple selection in games list Add actions for selected games (#262) Batch tag editing for selected games [f88b0a4]
  • +
  • Translated using Weblate (Norwegian Bokmål) [e1d59d3]
  • +
  • Translated using Weblate (Norwegian Bokmål) [78f5793]
  • +
  • Translated using Weblate (Dutch) [ad15bf6]
  • +
+
+
+ + +
    +
  • Add configurable blacklists for libretro cores and game file extensions (#103) [2729433]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Norwegian Bokmål) [63cbf1b]
  • +
+
+
+ + +
    +
  • Games merging tweaks Update Humble Trove parsing (#32) [480c20f]
  • +
+
+
+ + +
    +
  • Fix trying to get nonexistent platform from Steam game info Show default icons for games in list and details [603316b]
  • +
+
+
+ + +
    +
  • Merge branch 'dev' of github.com:tkashkin/GameHub into dev [b19073e]
  • +
  • Only match files when importing emulated games (#258) Do not try to show merged games when merging is disabled (#259) [b126539]
  • +
  • Translated using Weblate (Dutch) [4f34efd]
  • +
+
+
+ + +
    +
  • Allow to skip WelcomeView when no sources are setup (#257) [4f32825]
  • +
+
+
+ + +
    +
  • Add `Emulated` as a separate platform (#103) Improved image scaling Fix images downloader popup being cut off in some cases (#249) [1543581]
  • +
  • Translated using Weblate (Portuguese (Brazil)) [1288cc9]
  • +
+
+
+ + +
    +
  • Translated using Weblate (French) [19ed4a5]
  • +
  • Translated using Weblate (Portuguese (Brazil)) [aa824d1]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Dutch) [ce65666]
  • +
+
+
+ + +
    +
  • Added translation using Weblate (Chinese (Traditional)) [da8a821]
  • +
+
+
+ + +
    +
  • Maybe fix #255 Add log filtering to hide useless debug messages [2713b16]
  • +
+
+
+ + +
    +
  • UI tweaks [42d2657]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Norwegian Bokmål) [ec093ed]
  • +
  • Translated using Weblate (Dutch) [e8607ba]
  • +
+
+
+ + +
    +
  • Try to also match primary game platforms (#247) [74da09f]
  • +
+
+
+ + +
    +
  • `dconf` settings rework Theme-based icon style Filter games by platform [0f1c47b]
  • +
+
+
+ + +
    +
  • Update dput.cf [99e2a70]
  • +
  • List all platforms for merged games when source is not filtered (#247) Show submenus for merged games in `GameContextMenu` [2c240b9]
  • +
  • Fix dependency installation prompts in build script [adc63ca]
  • +
  • `GamePropertiesDialog` tweaks Update `GameCard` and `GameListRow` when filtered source changes (#247) [69132ad]
  • +
  • Fix SteamGridDB authentication (#249) IGDB description visibility settings [530e231]
  • +
  • Translated using Weblate (Norwegian Bokmål) [443a90b]
  • +
  • Translated using Weblate (Dutch) [d39b3e3]
  • +
  • Translated using Weblate (Norwegian Bokmål) [173ebcc]
  • +
  • Translated using Weblate (Norwegian Bokmål) [6b09afb]
  • +
+
+
+ + +
    +
  • Merge branch 'dev' of github.com:tkashkin/GameHub into dev [164e55c]
  • +
  • IGDB integration [9f1d67c]
  • +
  • Translated using Weblate (Norwegian Bokmål) [3f9c5dd]
  • +
  • Translated using Weblate (Dutch) [362a848]
  • +
  • Translated using Weblate (Portuguese (Brazil)) [2313120]
  • +
+
+
+ + +
    +
  • Simplified `ImportEmulatedGamesDialog` (#103) Images and icon patterns for custom emulators Added button to download all missing images for games Added data providers page to settings [e4486e7]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Norwegian Bokmål) [b100729]
  • +
  • Translated using Weblate (Norwegian Bokmål) [a535e9d]
  • +
  • Translated using Weblate (Norwegian Bokmål) [bfa122c]
  • +
+
+
+ + +
    +
  • Add game images providers [66e085e]
  • +
+
+
+ + +
    +
  • `ImportEmulatedGamesDialog` tweaks (#103) [843d4d2]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Dutch) [52186ff]
  • +
+
+
+ + +
    +
  • Add emulated games scanning (#103) [f5b3ad0]
  • +
  • Translated using Weblate (German) [9e366e0]
  • +
+
+
+ + +
    +
  • Fix Utils.get_language_name [96029f0]
  • +
+
+
+ + +
    +
  • Release 0.14.0 [6343d16]
  • +
  • [ci skip] Update AppStream data [72d1b55]
  • +
  • [ci skip] Bump version to 0.14.0 Update README.md Update screenshots [ff8ed17]
  • +
  • Merge branch 'master' of github.com:tkashkin/GameHub [1f713f3]
  • +
  • [ci skip] Merge pull request #172 from friday/issue-templates [fab595b]
  • +
  • Create git issue templates [600652a]
  • +
  • [ci skip] Update README.md [a242568]
  • +
  • Merge `dev` into `master` [cd4ff2c]
  • +
+
+
+ + +
    +
  • Disable `libunity` by default, enable with `-Duse_libunity=true` [31eb28a]
  • +
  • Remove `libunity-dev` from build script [ad8bc0f]
  • +
  • Remove `libunity-dev` from debian dependencies [5cc0ae7]
  • +
  • Translated using Weblate (Chinese (Simplified)) [0d8bea6]
  • +
  • Translated using Weblate (Chinese (Simplified)) [21d8a01]
  • +
  • Translated using Weblate (Polish) [39f6735]
  • +
  • Added translation using Weblate (Chinese (Simplified)) [d17ad07]
  • +
+
+
+ + +
    +
  • Fix crash in SoupDownloader.await_queue() (#220) [9024fef]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Norwegian Bokmål) [d04ad42]
  • +
  • Translated using Weblate (Dutch) [583c98c]
  • +
+
+
+ + +
    +
  • Queue installer downloads (#220) [87c7f3d]
  • +
  • Settings dialog improvements Controller exit shortcut (#75) Ignored controllers option [f05d464]
  • +
  • Translated using Weblate (German) [aa0c1c4]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Norwegian Bokmål) [cd2da98]
  • +
  • Translated using Weblate (Dutch) [67bfd23]
  • +
+
+
+ + +
    +
  • Settings dialog redesign [bc53e7c]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Norwegian Bokmål) [0a3db13]
  • +
  • Translated using Weblate (Dutch) [0dad19a]
  • +
  • Translated using Weblate (German) [416198f]
  • +
+
+
+ + +
    +
  • Fix flatpak libs [3b52419]
  • +
+
+
+ + +
    +
  • Fix Humble collection directory name (#244) Bundle more libs for flatpak [4138055]
  • +
  • Merge branch 'origin/dev' into Weblate. [201ce95]
  • +
  • Translated using Weblate (Norwegian Bokmål) [723f43b]
  • +
  • Translated using Weblate (Dutch) [dd634ba]
  • +
+
+
+ + +
    +
  • Add $platform and $platform_name variables for Collection (#244) [44ba7b8]
  • +
+
+
+ + +
    +
  • Bundle libmanette snapshot for flatpak [e08606c]
  • +
+
+
+ + +
    +
  • Bundle libmanette snapshot for flatpak because remote downloads on AppVeyor are unreliable [d7b7fdc]
  • +
  • In-memory image cache CLI option to restart app with gdb and G_DEBUG=fatal-criticals [6090578]
  • +
+
+
+ + +
    +
  • Fix AppVeyor artifacts upload [b8b527e]
  • +
  • Set more Wine-related env variables (#242) Don't try to init Proton prefix if it's already initialized [202e4d2]
  • +
  • Fix build script [93ba8e1]
  • +
  • Fix libmanette for flatpak [0062a8b]
  • +
  • Build launchpad source packages for multiple distros [a40fd62]
  • +
  • Build launchpad source packages for multiple distros [5cd101e]
  • +
+
+
+ + +
    +
  • Translated using Weblate (German) [3081514]
  • +
+
+
+ + +
    +
  • Translated using Weblate (German) [488ff43]
  • +
+
+
+ + +
    +
  • Fix launchpad build script Add icon to .appdata.xml [5e849c0]
  • +
+
+
+ + +
    +
  • Fix running Game.update_game_info() multiple times in threads (#237) [7a4f9e1]
  • +
+
+
+ + +
    +
  • Translated using Weblate (German) [79de66d]
  • +
+
+
+ + +
    +
  • Revert: Attempt to add game views in batches instead of all at once (#57) [c6994ef]
  • +
  • Fix AutoSizeImage scaling Fix Games DB cache threaded crashes Attempt to add game views in batches instead of all at once (#57) [cac6092]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Norwegian Bokmål) [3b27e88]
  • +
  • Translated using Weblate (Dutch) [e11b410]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Norwegian Bokmål) [4179176]
  • +
+
+
+ + +
    +
  • Merge branch 'origin/dev' into Weblate. [d3ec7c7]
  • +
  • Translated using Weblate (Dutch) [c45ba0f]
  • +
+
+
+ + +
    +
  • Make libunity optional Improve AutoSizeImage resizing Reimplement status indicator [07806a8]
  • +
+
+
+ + +
    +
  • Update launcher menu in GamesAdapter [642e452]
  • +
+
+
+ + +
    +
  • Merge branch 'origin/dev' into Weblate. [f32037e]
  • +
  • Translated using Weblate (Norwegian Bokmål) [60a0416]
  • +
  • Translated using Weblate (German) [af70e10]
  • +
  • Translated using Weblate (Dutch) [ad3ecc9]
  • +
  • Add config button to CompatToolPicker [3ac3d07]
  • +
+
+
+ + +
    +
  • Merge branch 'dev' of github.com:tkashkin/GameHub into dev [a0d7c1a]
  • +
  • GamesView refactoring (#57) [d5cb0e5]
  • +
  • [ci skip] Add new Game subcategory to desktop file (#233) [9d02815]
  • +
+
+
+ + +
    +
  • Improved Steam client integration [20047cc]
  • +
+
+
+ + +
    +
  • Add controller settings (#122) [3628f0b]
  • +
+
+
+ + +
    +
  • Translated using Weblate (German) [d18ad6b]
  • +
+
+
+ + +
    +
  • Fix GOG install segfault (#232) [abc24ad]
  • +
+
+
+ + +
    +
  • Fix GOG games installers parsing (#57) [cbac777]
  • +
+
+
+ + +
    +
  • Add default game icon (#204) [2334f9b]
  • +
+
+
+ + +
    +
  • Non-shallow git clone for AppVeyor [2541409]
  • +
  • Fix build script [9be335f]
  • +
+
+
+ + +
    +
  • Fix changelogs for flatpak [422ab93]
  • +
+
+
+ + +
    +
  • Set git user for AppVeyor [1176725]
  • +
  • Fix build script [bd542e3]
  • +
  • Generate changelogs automatically from git commits [517a32a]
  • +
+
+
+ + +
    +
  • Fix appstream data [f89dc4b]
  • +
+
+
+ + +
    +
  • Fix libunity dependency for flatpak [5741f06]
  • +
+
+
+ + +
    +
  • More null checks for GOG player stats (#228) [1acb171]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Norwegian Bokmål) [5cd0e94]
  • +
  • Translated using Weblate (Dutch) [81a9fa1]
  • +
+
+
+ + +
    +
  • Merge branch 'dev' of github.com:tkashkin/GameHub into dev [0f1c862]
  • +
  • [ci skip] Update issue templates (#212) [701f14e]
  • +
+
+
+ + +
    +
  • Merge branch 'origin/dev' into Weblate. [30fb590]
  • +
  • Translated using Weblate (Turkish) [23377e7]
  • +
  • About dialog (#212) [069613e]
  • +
+
+
+ + +
    +
  • Use case-insensitive paths for Steam (#227) [f6b77e8]
  • +
+
+
+ + +
    +
  • Implement libunity quicklist and progress (#225) [3084beb]
  • +
  • Allow multiple merged games from same source (#224) [8ccd0ca]
  • +
+
+
+ + +
    +
  • Enter to run first matching game in search (#223) [f9fd217]
  • +
+
+
+ + +
    +
  • GAction-based hotkeys [5bf5bdd]
  • +
+
+
+ + +
    +
  • Fix .gameinfo-background background-color for Pop!_OS GTK theme [974067a]
  • +
+
+
+ + +
    +
  • Add "Proton (latest)" to compat tools list (#222) [5f7bd3b]
  • +
+
+
+ + +
    +
  • Merge pull request #221 from Lucki/patch-1 [ade4818]
  • +
  • Add Proton 4.2 [837530a]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Norwegian Bokmål) [592ba39]
  • +
  • Translated using Weblate (German) [9f33b47]
  • +
  • Translated using Weblate (Dutch) [059e6c5]
  • +
+
+
+ + +
    +
  • Fix long titles in games grid (#219) [41668e6]
  • +
+
+
+ + +
    +
  • Fix FSUtils.mv_up() to allow directories merging (#216) [bec8757]
  • +
+
+
+ + +
    +
  • Add option to run games with double click (#213) [41d8c8f]
  • +
+
+
+ + +
    +
  • Bump minimal innoextract version to 1.8 (#208) [169dc6e]
  • +
+
+
+ + +
    +
  • Fix `is_game_merged` db query (#210, #211) [db1b38a]
  • +
+
+
+ + +
    +
  • Merge pull request #205 from Lucki/patch-1 [e1d8f5c]
  • +
  • Make overlays remountable [f0b0044]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Norwegian Bokmål) [efc9541]
  • +
+
+
+ + +
    +
  • Added translation using Weblate (Turkish) [e4c792a]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Norwegian Bokmål) [ac109bf]
  • +
+
+
+ + +
    +
  • Merge pull request #200 from spinozaure/flatpak-fixes [f6eb643]
  • +
  • Change 32bit library path for flatpak [269393c]
  • +
+
+
+ + +
    +
  • Move app/__support/app to game's install_dir for innoextract (#197) [cd84abf]
  • +
+
+
+ + +
    +
  • Change Steam packages check for elementary (#199) [3254279]
  • +
+
+
+ + +
    +
  • FSUtils.mv_up() dir existence check [d48c261]
  • +
+
+
+ + +
    +
  • Quickfix for #197 (#198) [e558a6b]
  • +
+
+
+ + +
    +
  • Fix GOG Windows game actions parsing if FSOverlays are enabled (#120) [678b18e]
  • +
+
+
+ + +
    +
  • Move game files from _gamehub_{game|app}_root for InnoSetup games installed with Wine/Proton (#192) [bee3890]
  • +
+
+
+ + +
    +
  • FileChooserEntry.set_default_directory (#182) UI tweaks [3b43850]
  • +
+
+
+ + +
    +
  • Update LINGUAS [a0af8c9]
  • +
  • Translated using Weblate (French) [0ef1423]
  • +
  • Deleted translation using Weblate (French) [2e8457e]
  • +
+
+
+ + +
    +
  • Added translation using Weblate (French) [4ecf8bf]
  • +
+
+
+ + +
    +
  • Translated using Weblate (German) [360dd70]
  • +
+
+
+ + +
    +
  • Fix game args parsing (#194) [eef7ba5]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Dutch) [bf41a58]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Dutch) [b749939]
  • +
+
+
+ + +
    +
  • Fix broken AppVeyor build by installing fakeroot in build script explicitly [0f0167e]
  • +
  • Remove max_width_chars for compat tool warnings [b098dee]
  • +
  • Warn user if the innoextract is not up-to-date (#193) [68f4a5f]
  • +
+
+
+ + +
    +
  • Small fixes GOG DLC UI improvements [ea5cc72]
  • +
+
+
+ + +
    +
  • Remember GOG bonus content filenames Improve GOG bonus content UI [d44618d]
  • +
+
+
+ + +
    +
  • Small UI fixes [0abbc80]
  • +
+
+
+ + +
    +
  • Expand `~` in FileChooserEntry [85d1268]
  • +
  • Fix #190 [fe36384]
  • +
  • Merge branch 'dev' of github.com:tkashkin/GameHub into dev [cae97d1]
  • +
  • Translated using Weblate (German) [d7ef194]
  • +
  • Merge branch 'dev' of github.com:tkashkin/GameHub into dev [ef0d8e5]
  • +
  • Merge branch 'master' into dev [cd7e38c]
  • +
  • Merge `dev` into `master` [72b076b]
  • +
  • [ci skip] Merge dev into master [3fe313b]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Polish) [b55aeb8]
  • +
  • Translated using Weblate (Polish) [4ec002d]
  • +
+
+
+ + +
    +
  • Added translation using Weblate (Polish) [a7225b5]
  • +
+
+
+ + +
    +
  • Merge branch 'master' of github.com:tkashkin/GameHub [1f713f3]
  • +
  • Merge branch 'master' into dev [cd7e38c]
  • +
  • [ci skip] Prepare 0.13.1 [03fdbe5]
  • +
  • Translated using Weblate (German) [512af52]
  • +
  • [ci skip] Merge pull request #172 from friday/issue-templates [fab595b]
  • +
  • Create git issue templates [600652a]
  • +
  • [ci skip] Update README.md [a242568]
  • +
  • Merge `dev` into `master` [cd4ff2c]
  • +
  • Merge `dev` into `master` [72b076b]
  • +
  • [ci skip] Merge dev into master [3fe313b]
  • +
+
+
+ + +
    +
  • Fix controller button hints for accented headerbar on elementary (#170) [cdf4a0f]
  • +
+
+
+ + +
    +
  • Merge branch 'origin/dev' into Weblate. [7dc1619]
  • +
  • Translated using Weblate (German) [ec198b7]
  • +
  • Possibly fix Humble token escaping (#32, #9) [3dd7dbe]
  • +
+
+
+ + +
    +
  • Fix welcome screen flat titlebar text/buttons color (#170) [c975c2a]
  • +
+
+
+ + +
    +
  • Add primary color for elementary theme (#170) More verbose logging for Humble Trove with `--verbose` option (#32) [3c67adf]
  • +
+
+
+ + +
    +
  • Update icon (#170) Add purple accent color Fix compat regression with previous commit [e380a84]
  • +
+
+
+ + +
    +
  • Probably fix install_dir after uninstalling and changing games directory (#111) Fix some games not saving in database after 352ba23 [4c53b00]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Norwegian Bokmål) [5e3d6f0]
  • +
  • Translated using Weblate (Dutch) [4134253]
  • +
+
+
+ + +
    +
  • Remove Steam Runtime libraries since they are not used (#181) [4011083]
  • +
+
+
+ + +
    +
  • Add a warning if games directory contains space (#111) [07068e5]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Dutch) [7ef671b]
  • +
+
+
+ + +
    +
  • Merge branch 'origin/dev' into Weblate. [1760318]
  • +
  • Translated using Weblate (Norwegian Bokmål) [e51aa9f]
  • +
  • Don't fetch Humble orders if they are not changed (#57) Temporarily disable `update_games()` to test [352ba23]
  • +
+
+
+ + +
    +
  • Fix moving children up from inner directory for installed games Fix xgettext not extracting some strings due to having a forward slash in source file anywhere before these strings [04ab0ed]
  • +
+
+
+ + +
    +
  • Remove sleeps while adding games (#57) Add games to GamesView in batches [06749a4]
  • +
+
+
+ + +
    +
  • Fix Humble games install path after uninstalling Fix having multiple instances of same Game in memory in some cases (for example if game properties dialog is opened via notification): * Fix cases when properties dialog used another Game instance and changes were not updating for the first instance * Slightly reduce memory usage [8263dd6]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Norwegian Bokmål) [d3f5249]
  • +
  • Translated using Weblate (Dutch) [ef04ff5]
  • +
  • Merge remote-tracking branch 'weblate/dev' into dev [fb92145]
  • +
  • Translated using Weblate (Dutch) [13bda3a]
  • +
+
+
+ + +
    +
  • Less verbose logging by default [e2604e5]
  • +
+
+
+ + +
    +
  • Bump version Update copyright years [4610e43]
  • +
+
+
+ + +
    +
  • Experimental version with ThreadPool thread count option (#57) [cd55bb5]
  • +
+
+
+ + +
    +
  • Merge branch 'origin/dev' into Weblate. [9d98a71]
  • +
  • Translated using Weblate (Norwegian Bokmål) [6ebe38d]
  • +
  • Notify user if executable for game can't be detected automatically (#157) Fix Proton prefix initialization [a0512ca]
  • +
+
+
+ + +
    +
  • Merge branch 'origin/dev' into Weblate. [534de0c]
  • +
  • Translated using Weblate (Norwegian Bokmål) [ae095ce]
  • +
+
+
+ + +
    +
  • New GActions and CLI options Better installer checksum mismatch handling for DEs which do not support buttons in notifications [a09fdda]
  • +
+
+
+ + +
    +
  • Translated using Weblate (French) [272ad4d]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Dutch) [21cd5dc]
  • +
+
+
+ + +
    +
  • Merge remote-tracking branch 'weblate/dev' into dev [484412b]
  • +
  • Translated using Weblate (Norwegian Bokmål) [739e575]
  • +
+
+
+ + +
    +
  • Rework CLI options parsing (#175) Restart with GDB in the same terminal session (#172) [0bbe7ee]
  • +
+
+
+ + +
    +
  • Merge branch 'origin/dev' into Weblate. [c2541cb]
  • +
  • Translated using Weblate (Norwegian Bokmål) [6ca0a09]
  • +
+
+
+ + +
    +
  • Add a CLI option to run with GDB attached (#172) [4f2e093]
  • +
  • [ci skip] Remove unused strings, try to fix a few bugged plurals for Weblate [c7f6bef]
  • +
+
+
+ + +
    +
  • Prettier log Don't capture child process output when it's not needed Possibly fix #163 [841b051]
  • +
  • [ci skip] Fix option group name to fit better with default GTK help [af68fda]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Russian) [d07f4b3]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Norwegian Bokmål) [8f8563d]
  • +
+
+
+ + +
    +
  • Merge branch 'dev' of github.com:tkashkin/GameHub into dev [52da673]
  • +
  • Pass git branch and commit via meson options (#172) [5c7c5cd]
  • +
+
+
+ + +
    +
  • Merge branch 'origin/dev' into Weblate. [8c28072]
  • +
  • Translated using Weblate (Dutch) [5e7b1c1]
  • +
  • Call Application.init() after printing version (#172) [0707816]
  • +
  • [ci skip] Update issue templates (#172) [c40d2e8]
  • +
  • [ci skip] Create git issue templates (#172) [3012de1]
  • +
  • Merge branch 'origin/dev' into Weblate. [5fc975a]
  • +
  • Translated using Weblate (Dutch) [cf1f402]
  • +
+
+
+ + +
    +
  • Add `--version`/`-v` option (#172) Add `--log-workers` option (#172) Migrate to `Gtk.Application` from `Granite.Application` [70741b5]
  • +
+
+
+ + +
    +
  • Make auth and downloader logging optional and disabled by default (#172) [93f62c1]
  • +
+
+
+ + +
    +
  • Add a bit more height to compact ActionButton (#165, #171) [82debb2]
  • +
+
+
+ + +
    +
  • Compact ActionButton (#165, #171) [684568d]
  • +
+
+
+ + +
    +
  • Merge branch 'dev' of github.com:tkashkin/GameHub into dev [ec1c3e4]
  • +
  • Fix headerbar buttons valign (#165) [c95609a]
  • +
+
+
+ + +
    +
  • Merge branch 'origin/dev' into Weblate. [ca747d2]
  • +
  • Translated using Weblate (Norwegian Bokmål) [ae349ab]
  • +
  • Translated using Weblate (Dutch) [9ae4503]
  • +
  • Use smaller icons for headerbar if symbolic (#165) [acbd2aa]
  • +
+
+
+ + +
    +
  • Merge branch 'origin/dev' into Weblate. [03b2a09]
  • +
  • Translated using Weblate (Norwegian Bokmål) [3b15c50]
  • +
  • Translated using Weblate (Dutch) [b40b1de]
  • +
  • Add an option to use symbolic icons (#165) [3a15402]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Russian) [108c6de]
  • +
  • Update localization files [891f938]
  • +
  • Support custom Wine/Proton prefixes (#160) [9d953c6]
  • +
+
+
+ + +
    +
  • Replace download checkbox with a button (#168) [1a7b13a]
  • +
+
+
+ + +
    +
  • Translated using Weblate (French) [1537eed]
  • +
+
+
+ + +
    +
  • Check for `wingpanel` gsettings schema before trying to use `Granite.DateTime.get_relative_datetime` (#164) [2e06716]
  • +
+
+
+ + +
    +
  • Split installers list by platform (#167) [d9364a7]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Russian) [5a833c2]
  • +
+
+
+ + +
    +
  • Merge games by normalized name (#166) [b3cece5]
  • +
+
+
+ + +
    +
  • Sort games by normalized names (#166) [ee86ced]
  • +
+
+
+ + +
    +
  • Use linuxdeployqt 5 instead of continuous due to https://github.com/probonopd/linuxdeployqt/issues/340 Revert to building a separate debian source package [8e9fc46]
  • +
  • `*_amd64.changes` -> `*_source.changes` [f17330f]
  • +
  • Rename *_amd64.changes to *.changes [ad701ad]
  • +
  • `sed` -> `sed -i` [8bd4054]
  • +
  • Modify .changes to convert debian package to a source-only package [234eb59]
  • +
  • Merge branch 'origin/dev' into Weblate. [6e9fa63]
  • +
  • Translated using Weblate (French) [2b9fd27]
  • +
  • Fix launchpad upload to not try to upload binary [42d895f]
  • +
  • Added translation using Weblate (French) [3032b26]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Portuguese (Brazil)) [e05ce9b]
  • +
+
+
+ + +
    +
  • Merge branch 'origin/dev' into Weblate. [5bfaa0c]
  • +
  • Translated using Weblate (Dutch) [99fd3e2]
  • +
  • Parse game actions from gameinfo for GOG Windows games Set executable and arguments automatically for Windows GOG games using primary action when possible (#157) [d02c24c]
  • +
+
+
+ + +
    +
  • Add Proton 3.16 Beta id (#101) Fix Proton prefix init Add simple download speed counter [1825920]
  • +
+
+
+ + +
    +
  • Fix changelog syntax [11c751f]
  • +
  • Update build scripts [1f7aaf7]
  • +
  • Update README.md (#108) [e989add]
  • +
+
+
+ + +
    +
  • Fix Humble Trove url signing (#32) [4798294]
  • +
+
+
+ + +
    +
  • Update Humble Trove support (#32) [9d040db]
  • +
+
+
+ + +
    +
  • Probably fix #154 [28e6f8d]
  • +
+
+
+ + +
    +
  • Quick fix for #146 (#147) [a8970ce]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Norwegian Bokmål) [aa5174a]
  • +
  • Translated using Weblate (German) [a222b57]
  • +
  • Translated using Weblate (Dutch) [3161f00]
  • +
+
+
+ + +
    +
  • msi installer support (#151) Installer checksum mismatch notification [46cf5b4]
  • +
  • Translated using Weblate (Norwegian Bokmål) [1330dbb]
  • +
  • Translated using Weblate (German) [370e7e2]
  • +
  • Translated using Weblate (Dutch) [81bf8ec]
  • +
+
+
+ + +
    +
  • Merge branch 'dev' of github.com:tkashkin/GameHub into dev [3f8460b]
  • +
  • Update WineWrap integration (#108) Implement installer hash checks (#29) [3ac55b0]
  • +
+
+
+ + +
    +
  • Translated using Weblate (German) [2bfb81c]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Norwegian Bokmål) [56399f6]
  • +
  • Translated using Weblate (Dutch) [18242b8]
  • +
+
+
+ + +
    +
  • Merge branch 'origin/dev' into Weblate [db10ad3]
  • +
  • Translated using Weblate (Norwegian Bokmål) [0f94487]
  • +
  • Translated using Weblate (German) [e7efc06]
  • +
  • Add binary vdf parser/writer Add games to the Steam library (#149) [d5add8c]
  • +
+
+
+ + +
    +
  • Merge branch 'origin/dev' into Weblate [5beeebc]
  • +
  • Translated using Weblate (Dutch) [11fb981]
  • +
  • Bundle polkit for flatpak [91b5060]
  • +
  • Fix run args margin [6335c6c]
  • +
  • Command line option to run game (#149) [e4a9f54]
  • +
+
+
+ + +
    +
  • Save version of used installer (GOG only) (#148) Show updates indicator for updated GOG games (#78) [b479cbd]
  • +
+
+
+ + +
    +
  • Translated using Weblate (German) [16c13da]
  • +
  • Translated using Weblate (Russian) [d149357]
  • +
  • Translated using Weblate (German) [5aa2dd0]
  • +
  • Translated using Weblate (Dutch) [1cf730a]
  • +
  • Translated using Weblate (Dutch) [1a3ddd3]
  • +
+
+
+ + +
    +
  • Initial integration with adamhm's wine wrappers (#108) [a2efef1]
  • +
+
+
+ + +
    +
  • Translated using Weblate (German) [c64e772]
  • +
  • Translated using Weblate (German) [732a22a]
  • +
  • Translated using Weblate (German) [9f4e56c]
  • +
+
+
+ + +
    +
  • Added translation using Weblate (German) [9b045a7]
  • +
  • Translated using Weblate (Indonesian) [8be6cd4]
  • +
  • Translated using Weblate (Dutch) [ec6702a]
  • +
+
+
+ + +
    +
  • Added translation using Weblate (Dutch) [e4e8423]
  • +
+
+
+ + +
    +
  • Translated using Weblate (Indonesian) [c590c09]
  • +
  • Translated using Weblate (Norwegian Bokmål) [0630207]
  • +
  • Translated using Weblate (Russian) [8077361]
  • +
+
+
+ + +
    +
  • Fix option to hide icons (#141) [7559ff7]
  • +
+
+
+ + +
    +
  • Fix nb_NO translation [ad49c12]
  • +
  • Merge remote-tracking branch 'weblate/dev' into dev [3236a82]
  • +
  • Add an option to hide icons in grid view (#141) [ff3ff38]
  • +
  • Merge branch 'origin/dev' into Weblate [9c65aed]
  • +
  • [ci skip] Update README.md [d0bd26f]
  • +
  • Translated using Weblate (Norwegian Bokmål) [8b057a3]
  • +
  • Translated using Weblate (Norwegian Bokmål) [b338984]
  • +
  • Translated using Weblate (Norwegian Bokmål) [7135c95]
  • +
+
+
+ + +
    +
  • Merge `dev` into `master` [cd4ff2c]
  • +
  • [ci skip] Bump version [0a1e7d6]
  • +
  • [ci skip] Fix broken weblate [b360886]
  • +
  • Merge `dev` into `master` [72b076b]
  • +
  • [ci skip] Merge dev into master [3fe313b]
  • +
+
+
+ + +
    +
  • More secure polkit policy (#120) [09c458a]
  • +
+
+
+ + +
    +
  • Playtime sort mode (#139) [a828310]
  • +
  • [ci skip] Update pt_BR.po (#140) [ad86a6f]
  • +
+
+
+ + +
    +
  • Add running indicator (#138) [a4cd434]
  • +
+
+
+ + +
    +
  • UI tweaks [9a14a0e]
  • +
+
+
+ + +
    +
  • Import playtime from Steam and GOG Show version for installed native GOG games Improve image rendering in AutoSizeImage [49018e2]
  • +
+
+
+ + +
    +
  • Achievements (#130) [9b5535e]
  • +
+
+
+ + +
    +
  • Add ScummVM (#52) [187c708]
  • +
  • Allow to launch custom emulators from game directory (#52) [cd8105d]
  • +
+
+
+ + +
    +
  • Fix images update in GamePropertiesDialog (#131) [3a5473a]
  • +
+
+
+ + +
    +
  • Update xenial deps to fix xenial AppVeyor build [25b2a01]
  • +
+
+
+ + +
    +
  • Fix FileChooserEntry (#131) [484aee5]
  • +
  • [ci skip] Update pt_BR localization (#135) [6af5df4]
  • +
+
+
+ + +
    +
  • Replace FileChooserButtons with custom FileChooserEntry (#131) [fca3a8a]
  • +
+
+
+ + +
    +
  • Fix #114 [bcae45c]
  • +
+
+
+ + +
    +
  • Merge `dev` into `master` [72b076b]
  • +
  • [ci skip] 0.12.0 [e03158d]
  • +
  • [ci skip] Merge dev into master [3fe313b]
  • +
+
+
+ + +
    +
  • Update localization template [de1064b]
  • +
+
+
+ + +
    +
  • One more fix for #124 [28d9a7b]
  • +
  • Probably fix #124 [877f42b]
  • +
+
+
+ + +
    +
  • Fix build with GTK < 3.22 [27c7e4f]
  • +
+
+
+ + +
    +
  • Implement #126 [cc8ed76]
  • +
+
+
+ + +
    +
  • Fixes for #120 [1c78c4f]
  • +
  • Fixes for #120 Update screenshots in AppStream data [9148625]
  • +
  • [ci skip] Update README.md [489ac63]
  • +
  • [ci skip] Update README.md and screenshots [8b321ac]
  • +
  • [ci skip] Update README.md [769284e]
  • +
  • [ci skip] Update README.md, Fix #123 [5a232b4]
  • +
+
+
+ + +
    +
  • Overlays (#120) [2071a8e]
  • +
+
+
+ + +
    +
  • Fix build with polkit [9968cc2]
  • +
+
+
+ + +
    +
  • Initial OverlayFS impplementation for #120 [e36f1b5]
  • +
+
+
+ + +
    +
  • Wine/Proton improvements Bugfixes for #106 [f4a4847]
  • +
+
+
+ + +
    +
  • Custom emulators can be installed with installers (#106) [0f374be]
  • +
+
+
+ + +
    +
  • UI improvements [d6eccf5]
  • +
+
+
+ + +
    +
  • Improve GOG DLC support (#118) [6a72d84]
  • +
+
+
+ + +
    +
  • Restrict NSIS installers unpacking with `file-roller` Support adding custom games using installers (#106) Implement custom emulators removal [7e443e4]
  • +
+
+
+ + +
    +
  • Fix compat settings and launch time saving for non-native games (#92) [75a5015]
  • +
+
+
+ + +
    +
  • Improve bundled DOSBox detection for GOG Windows games (#113) [3b3427e]
  • +
+
+
+ + +
    +
  • New useless feature: press R to select random game [842bc32]
  • +
+
+
+ + +
    +
  • Add logout buttons for GOG and Humble (#40) Add NSIS installer support (#96) [d18ac39]
  • +
+
+
+ + +
    +
  • Fix #38, #109 [4d35615]
  • +
+
+
+ + +
    +
  • Custom emulator support (#103) Download only mode (#107) [4150ba2]
  • +
+
+
+ + +
    +
  • Fix #105 Fix GOG bonus content download info [226fc5c]
  • +
+
+
+ + +
    +
  • Fix DEB_BUILD_OPTIONS [81f11b6]
  • +
  • Keyboard/gamepad navigation improvements WINEARCH fixes Version bump [5de360a]
  • +
  • Controller mode improvements (#75) [e5b5298]
  • +
  • Possibly fix debian/rules to disable optimizations Do not show compat dialog if parameters for game are saved (#75) [394cd6d]
  • +
+
+
+ + +
    +
  • Set DEB_BUILD_OPTIONS in debian/rules [24f83f1]
  • +
+
+
+ + +
    +
  • Fix add game button insensitivity Disable optimizations Update README.md [393c96e]
  • +
+
+
+ + +
    +
  • Add RetroArch compatibility tool [7a896a5]
  • +
+
+
+ + +
    +
  • Fix last launch time sorting [c2640f4]
  • +
+
+
+ + +
    +
  • Prevent multiple games launch at the same time (#92) Possibly fix flatpak errors (#15, #61) [6029659]
  • +
+
+
+ + +
    +
  • Update flatpak libs [7ccc7a5]
  • +
+
+
+ + +
    +
  • Remove flatpak runtime libs [6db7eed]
  • +
+
+
+ + +
    +
  • Games can be sorted by last launch time Imported tags can be disabled (#47) Experimental flatpak changes (#15) [cb4c384]
  • +
+
+
+ + +
    +
  • Unified games sorting (#102) Possibly fix some of random crashes [8dfd66a]
  • +
+
+
+ + +
    +
  • Update flatpak manifest and build script [c48a7f1]
  • +
+
+
+ + +
    +
  • Merge branch 'dev' of github.com:tkashkin/GameHub into dev [b1639e3]
  • +
  • Cleanup flatpak build directory [b5717ba]
  • +
  • Cleanup flatpak build directory [4510625]
  • +
  • Update flatpak build script Update flatpak manifest Move flatpak manifest from its branch [8788426]
  • +
+
+
+ + +
    +
  • Update build script [8abf5b8]
  • +
+
+
+ + + +
    +
  • Update build script and fix xenial build [0b81f04]
  • +
+
+
+ + +
    +
  • Update build script [7b9bdae]
  • +
+
+
+ + + +
    +
  • Try to fix build for xenial and flatpak [ef33bc5]
  • +
+
+
+ + +
    +
  • Fix build on xenial [245936b]
  • +
+
+
+ + +
    +
  • Release all keys on gamepad disconnect [a93f616]
  • +
  • Fix focus stealing from search field Update readme [3aca6fe]
  • +
+
+
+ + +
    +
  • Controller UI mode [79578c7]
  • +
+
+
+ + +
    +
  • Fix build [3d005c2]
  • +
  • Improved keyboard events using xtest instead of calling xdotool [923715a]
  • +
+
+
+ + +
    +
  • Improved gamepad navigation, stick support [e3d214c]
  • +
+
+
+ + +
    +
  • Update build script [c7ef68f]
  • +
  • UI tweaks Proton 3.16 support Basic keyboard/gamepad navigation in grid view (#75) [4c29f49]
  • +
+
+
+ + +
    +
  • Bump version [cd50494]
  • +
  • Use WINEARCH env variable Fix building with older libsoup [507c293]
  • +
+
+
+ + +
    +
  • Use correct gpg package and binary on xenial [048f365]
  • +
  • One more flatpak try [4feb1f6]
  • +
+
+
+ + +
    +
  • Update README.md Possibly fix flatpak build and xenial launchpad source package upload [6b04a97]
  • +
  • Revert libwebkit2gtk workarounds [bac13e2]
  • +
  • set +e in build_flatpak() [cf2cdd1]
  • +
  • Update build script [511903f]
  • +
  • Try to use older libwebkit2gtk for launchpad [3885762]
  • +
  • Update debian/control [8e75319]
  • +
  • Update debian/control [12449cd]
  • +
  • Update debian/control [dd5e720]
  • +
  • Update flatpak build script Try to blacklist webkit2gtk again [8cab19b]
  • +
  • Merge branch 'dev' of github.com:tkashkin/GameHub into dev [3e55b94]
  • +
  • Try to use libwebkit2gtk-4.0-dev=2.20.1-1 if available Try to build flatpak [4b5d555]
  • +
  • Merge pull request #95 from cho2/l10n-dev [66ecef0]
  • +
  • Update Indonesian translation [3c11ab1]
  • +
+
+
+ + +
    +
  • Build source-only package for launchpad [1b8ae91]
  • +
  • Disable GPG signature check for dput [f927210]
  • +
  • Force gpg1 for dput [f471ae7]
  • +
  • Try to use gpg1 [160d118]
  • +
  • Try to use gpg1 [3ba17a0]
  • +
  • Try to start gpg-agent [823d832]
  • +
  • Try to start gpg-agent [78bfa66]
  • +
  • Force older webkit libs again [2f4433c]
  • +
  • Force older libwebkit2gtk [78a6efc]
  • +
  • Blacklist libwebkit2gtk-4.0-dev 2.22.2-0ubuntu0.18.04.1 [16b042d]
  • +
  • No fail on key import [fa39130]
  • +
  • Try to start gpg-agent [d3ef42c]
  • +
  • Update build script [690ad06]
  • +
  • Update localization template Update build scripts Trying to setup a PPA Update license [e146c44]
  • +
  • Update debian build instructions (#91) [e943ed5]
  • +
+
+
+ + +
    +
  • Fix GOG token refresh when there's no internet connection [40d7849]
  • +
+
+
+ + +
    +
  • Slightly modified #90 [6d80079]
  • +
+
+
+ + +
    +
  • Merge pull request #88 from neuromancer/patch-1 [51b3653]
  • +
  • complete gecko popup removal when creating a new wine prefix [c167f08]
  • +
+
+
+ + +
    +
  • Enhancements for #83 [fc62026]
  • +
+
+
+ + +
    +
  • Game command line parameters User-added games (#83) [0fad67c]
  • +
+
+
+ + +
    +
  • Fixes for CompatTools [24600df]
  • +
  • Merge pull request #84 from tkashkin/master [f193fb6]
  • +
+
+
+ + +
    +
  • Fix AppImage repacking [aa60f85]
  • +
  • Update AppVeyor config [a840b8b]
  • +
  • Add xenial dependencies [b74ef25]
  • +
  • Update build script [861be4c]
  • +
  • Update AppVeyor config [a8f959e]
  • +
  • Update AppVeyor config [edea459]
  • +
  • Update AppVeyor config [ab8831f]
  • +
  • Try to build on Ubuntu 16.04 [6c4ba32]
  • +
  • Update AppImage build and run scripts [39e00ef]
  • +
  • [ci skip] Fix building with GTK < 3.22 [d50095c]
  • +
+
+
+ + +
    +
  • Update AppVeyor config [364765d]
  • +
  • Update AppVeyor artifact paths [6a91e63]
  • +
  • Bump version Update AppVeyor config and AppImage build script [14580cb]
  • +
  • Remove Travis CI from README.md [b2acce4]
  • +
  • Update AppVeyor config [783aab2]
  • +
  • Update AppVeyor config [1ebcb51]
  • +
  • Update pt_BR localization [2533558]
  • +
+
+
+ + +
    +
  • Merge pull request #80 from tkashkin/dev [6dd4d6b]
  • +
  • Merge pull request #79 from tkashkin/appimage [3802672]
  • +
  • 0.11.0 release [7362f95]
  • +
  • Restore Travis to Houston CI (Travis doesn't support Ubuntu newer than trusty :confused:) Try to migrate to AppVeyor [4b9c3b6]
  • +
  • Add AppImage support [a565890]
  • +
  • Add libxml2-dev dependency to debian/control [6bff75d]
  • +
  • Another fix attempt for #77 [53fbb2f]
  • +
  • Fix force_compat Probably fix Trove.sing_url (#77) [22b0ab5]
  • +
  • Add DOSBox CompatTool (#71) Allow to force compat even for games which do support Linux (#51, #52, #71) [36b90dc]
  • +
  • Add CustomScript tool (#71) [99bf86c]
  • +
  • Maybe fix Humble URL ttl (#73) [67c77a8]
  • +
  • One more try (#67) [55fadbc]
  • +
  • GamesView postponed updates (#67) "Installed" tag (#69) Fix Utils.strip_name (#70) Partly update localizations [5e03bce]
  • +
  • Fix #68 [04e2799]
  • +
  • Implement Humble Trove support (#32) [9e3dc15]
  • +
  • Log working directory [c134e48]
  • +
  • Log all run methods [e6d6d60]
  • +
  • Added install options for compat tools [3cd2745]
  • +
  • Pass target directory to windows installers (for now assuming all of them are InnoSetup) [b62ec93]
  • +
  • Fix appstream info [2a114af]
  • +
  • Version bump [2177acc]
  • +
  • Database rewrite (refactoring, versioning, migrations, #64) UI tweaks Added tag icons [6c48e09]
  • +
  • Game properties dialog Improvements for #59 [bef7791]
  • +
  • Compatibility tools selection (#59, #60) [7752ad9]
  • +
  • Experimental Proton/wine support (#54) [fd5a0e5]
  • +
  • Fix flatpak build [53e10bb]
  • +
+
+
+ + +
    +
  • Prepare 0.9.0 release [01ef0c6]
  • +
  • [ci skip] Update README (new AUR package) [e399e6f]
  • +
  • Implement #50, #33 [c64646e]
  • +
  • [ci skip] Update README.md [08585aa]
  • +
  • Add Proton beta appid check [707f6ed]
  • +
  • Use ThreadPool instead of spawning endless threads Run game merging only for new games (may not merge all games correctly, needs testing) Finally fix #48 (maybe) [ea5b143]
  • +
  • Fixes for humble and #48 [4a3f01d]
  • +
  • Game tags dialog User tags creation [1f27c50]
  • +
  • Tags (#47) are working (no user tags yet) Games context menu [6765826]
  • +
  • Started work on #47: * GamesDB refactoring * Game tags * Tags import from GOG * FiltersPopover (just basic UI now, not hooked to anything) [c4e0f3f]
  • +
  • Sort cached games by name [d8c36a3]
  • +
  • Remove tmp installer extension [699de05]
  • +
  • Fixes [b02797c]
  • +
  • Refactoring Non-native games support Steam Play support [16b3f84]
  • +
  • Fix GOG bonus content/DLC loading [c232c37]
  • +
  • Refactored DownloadProgressView to allow more download types (not only games) Implemented GOG bonus content downloading [7c7ef29]
  • +
  • Actually disable merging (loading cache) when merging toggle is disabled [2560717]
  • +
  • Basic collection management (#29) [055c51a]
  • +
  • Fixed #38 [41f45fc]
  • +
  • Fix games counter [668172f]
  • +
  • Improved merging [ee79571]
  • +
  • Threaded loading Threaded merging Merging cache [b02381e]
  • +
  • Fixes for #42, #43 Fixed GameDetaisView/GameDetailsDialog background color for non-elementary gtk themes [8dc569a]
  • +
  • Fixes for #39 Added Collection tab in settings dialog (does nothing yet) [e201431]
  • +
  • Started implementing #29 Fetching bonus content and DLCs (no download yet) Bugfixes [42816ef]
  • +
  • Fix flatpak Steam path [3855cf6]
  • +
  • Fix flatpak Steam path [4a6407a]
  • +
  • Flatpak build error fix [ecda4c5]
  • +
+
+
+ + +
    +
  • Option to merge games from different sources [9906b6a]
  • +
  • Add null check in Utils.cache_image [eff0aab]
  • +
+
+
+ + +
    +
  • Settings dialog rework Compact games list [b9712bb]
  • +
+
+
+ + +
    +
  • Trying to fix Humble Bundle access token extraction [3a8a79c]
  • +
+
+
+ + +
    +
  • Search crash fix and UI improvements [7800da0]
  • +
+
+
+ + +
    +
  • Additional info for Steam games Pass locale to APIs when possible to get localized data [882cef7]
  • +
  • Merge branch 'master' of github.com:tkashkin/GameHub [464adc3]
  • +
  • Initial snap is at least working now (still broken as hell) Fixes for old GTK+3 [0945f04]
  • +
  • Update Indonesian translation (#28) [0ab322a]
  • +
  • UI fixes Initial snap [f7f57b5]
  • +
  • Update pt_BR.po (#25) [8cc0b6f]
  • +
  • Update README.md [a0ea12a]
  • +
+
+
+ + +
    +
  • Downloader rewrite: now it's possible to pause and cancel downloads Downloads can be resumed after interruption UI improvements [e2f0c9e]
  • +
  • [ci skip] Fix Humble Bundle installers cache [1d65ac3]
  • +
+
+
+ + +
    +
  • Yet another locale fix Installers cache management [1cc9b24]
  • +
+
+
+ + +
    +
  • Fix crash for GOG "games" like Hotline Miami 2 Digital Comics Fix building with GTK+3 < 3.22 [e2674e7]
  • +
  • Fix GOG pagination (#22) [7c60162]
  • +
+
+
+ + +
    +
  • Bugfixes Design changes Compatibility [268bdfe]
  • +
  • Bundle ivy [7c887d7]
  • +
  • Update .travis.yml [2c9d334]
  • +
  • Update README.md [30edc21]
  • +
  • [ci skip] Update README.md [fe5b112]
  • +
  • Show additional info for GOG games [abf3f04]
  • +
+
+
+ + +
    +
  • [ci skip] Yet anothed locale fix [e26aef4]
  • +
  • 0.5.4 release [0d539cd]
  • +
+
+
+ + +
    +
  • Merge branch 'master' of github.com:tkashkin/GameHub [a13ea49]
  • +
  • [ci skip] Fix launching for flatpak [732aad7]
  • +
  • [ci skip] Update launcher script [4c97be9]
  • +
  • [ci skip] Wrong args fix [d479056]
  • +
  • [ci skip] Missing ; [71b86bd]
  • +
  • 0.5.3 release [ac2ee74]
  • +
  • id language (#11) [69381fa]
  • +
+
+
+ + +
    +
  • 0.5.2 release Added localizations: * pt_BR * pl * uk * de [f26eee5]
  • +
  • pt_BR language (#10) [f37e27b]
  • +
+
+
+ + +
    +
  • Prepare 0.5.1 release [f2faa51]
  • +
  • [ci skip] Fix AutoSizeImage resizing while image is not loaded [f332c71]
  • +
  • [ci skip] Fix image loading for flathub [5d2a96c]
  • +
  • [ci skip] Trying to fix network for flatpak [e1f396d]
  • +
  • [ci skip] Better error handling for images caching [80f753a]
  • +
  • Initial flatpak build support [WIP] [2b0e729]
  • +
+
+
+ + +
    +
  • [ci skip] Disable WebKit hardware acceleration [f878bbd]
  • +
  • [ci skip] Cache path [e6286cd]
  • +
  • Enum fixes [b9a4792]
  • +
  • Enum fixes [c9a4d0e]
  • +
  • [ci skip] Appstream data changes [8270d4e]
  • +
  • Downloads list fixes [1f33028]
  • +
  • Games list view Game details view/dialog Games grid improvements Bug fixes [cc083bb]
  • +
+
+
+ + +
    +
  • Small features [4424a8a]
  • +
+
+
+ + +
    +
  • Unneeded game sources now can be disabled Bug fixes [7b8a735]
  • +
  • Probably fix Humble auth [54a5b4f]
  • +
  • Debug logging Small UI fixes [2d315c0]
  • +
  • Hide toolbar buttons while loading [341a3a4]
  • +
  • Flat welcome window [b7cdb7c]
  • +
+
+
+ + +
    +
  • Humble Bundle authentication fix Humble Bundle game icons fix [2ba374a]
  • +
+
+
+ + +
    +
  • Humble Bundle support 0.3.0 release [89968b4]
  • +
  • Update post_install script [0310078]
  • +
+
+
+ + +
    +
  • Prepare 0.2.5 release [dd02dd2]
  • +
  • Fix game installation segfault [b213b2f]
  • +
  • Fix for GOG games with ':' in title [a652a78]
  • +
  • [ci skip] Update README.md [9638c69]
  • +
  • Create .travis.yml [bbff2ea]
  • +
+
+
+ + +
    +
  • Settings dialog [554b658]
  • +
+
+
+ + +
    +
  • Fixes [e0f80f7]
  • +
  • Update version [323e09f]
  • +
  • Update readme and version [cf950e1]
  • +
  • Remove ivy again [068bc3b]
  • +
  • Update changelog [8f23bad]
  • +
  • GOG games installation and running Various improvements [b0b9111]
  • +
  • Steam game launch and installation Games grid style tweaks [0b801cc]
  • +
  • Grid selection mode [fb11b0b]
  • +
  • Grid autosizing [7ebee54]
  • +
  • Almost perfect grid autosizing [03c53c4]
  • +
  • [WIP] Games grid autosizing Juno fixes [0183150]
  • +
+
+
+ + +
    +
  • Update changelog [533ff4d]
  • +
  • Fix Steam config path\nUpdate .gitignore [17695d8]
  • +
+
+
diff --git a/data/com.github.tkashkin.gamehub.desktop.in b/data/com.github.tkashkin.gamehub.desktop.in index 9c5d2b20..c5d6b046 100644 --- a/data/com.github.tkashkin.gamehub.desktop.in +++ b/data/com.github.tkashkin.gamehub.desktop.in @@ -2,8 +2,8 @@ Name=GameHub GenericName=GameHub Comment=All your games in one place -Categories=Game;Utility; -Keywords=Game;Hub;Steam;GOG; +Categories=Game;Amusement; +Keywords=Game;Hub;Steam;GOG;Humble;HumbleBundle; Exec=com.github.tkashkin.gamehub X-GNOME-Gettext-Domain=com.github.tkashkin.gamehub Icon=com.github.tkashkin.gamehub diff --git a/data/com.github.tkashkin.gamehub.gresource.xml b/data/com.github.tkashkin.gamehub.gresource.xml index 6f9b6ab4..127a483e 100644 --- a/data/com.github.tkashkin.gamehub.gresource.xml +++ b/data/com.github.tkashkin.gamehub.gresource.xml @@ -1,6 +1,7 @@ - - GameHub.css + + css/app.css + css/themes/elementary.css diff --git a/data/com.github.tkashkin.gamehub.gschema.xml.in b/data/com.github.tkashkin.gamehub.gschema.xml.in new file mode 100644 index 00000000..134b2287 --- /dev/null +++ b/data/com.github.tkashkin.gamehub.gschema.xml.in @@ -0,0 +1,359 @@ + + + + + + + + + + + + + "Normal" + Saved window state + + + -1 + Window width + + + -1 + Window height + + + -1 + Window x position + + + -1 + Window y position + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + "Grid" + Selected view style + + + "Name" + Selected sort mode + + + "Status" + Selected group mode + + + '' + Selected game source filter + + + "All" + Selected platform filter + + + + + + + + + + + + + false + Dark theme + + + "Theme-based" + Icon style + + + ['installed-icon', 'installed-title-bold', 'installed-status', 'uninstalled-icon', 'uninstalled-dim'] + List style + + + true + Show platform icons in grid view + + + 460 + Grid view game card width + + + 215 + Grid view game card height + + + + + + + false + Run games with doubleclick + + + true + Merge games from different sources + + + true + Import tags + + + + + + + true + Is Steam enabled + + + false + Did user agree to read Steam configs + + + '@PREF_API_KEY_STEAM@' + Steam API key + + + + + + true + Is GOG enabled + + + false + Is user authenticated + + + '' + GOG access token + + + '' + GOG refresh token + + + + + + true + Is Humble enabled + + + false + Is user authenticated + + + '' + Humble access token + + + true + Is Trove enabled + + + + + + true + Is itch.io enabled + + + false + Did user agree to read itch.io configs + + + '@PREF_API_KEY_ITCH@' + itch.io API key + + + + + + + '~/.steam' + Steam installation directory + + + '~/Games/GOG' + GOG games directory + + + '~/Games/HumbleBundle' + Humble games directory + + + '~/.config/itch' + itch.io config/installation directory + + + '~/Games/itch' + itch.io games directory + + + + + + + '~/Games/_Collection' + Collection root directory + + + + + + '$root/GOG/$game' + GOG collection: game directory + + + '$game_dir' + GOG collection: installers directory + + + '$game_dir/dlc' + GOG collection: dlc directory + + + '$game_dir/bonus' + GOG collection: bonus content directory + + + + + + '$root/Humble Bundle/$game' + Humble collection: game directory + + + '$game_dir' + Humble collection: installers directory + + + + + + + true + Is controller support enabled + + + true + Should main window be focused when Guide button is pressed + + + [] + Known controllers list + + + [] + Ignored controllers list + + + + + + + '@PREF_LIBRETRO_CORE_DIR@' + libretro cores directory + + + '@PREF_LIBRETRO_CORE_INFO_DIR@' + libretro core info directory + + + '3dengine|ffmpeg|dosbox|dosbox_svn|dosbox_svn_glide' + Ignored libretro cores list (separated by '|') + + + 'bin|dat|exe|zip|7z|gz' + Ignored game file extensions list (separated by '|') + + + + + + + true + Is SteamGridDB enabled + + + '@PREF_API_KEY_STEAMGRIDDB@' + SteamGridDB API key + + + + + + true + Is Jinx's Steam Grid View Images enabled + + + + + + true + Is Steam image search enabled + + + + + + + + + + + + + true + Is IGDB enabled + + + '@PREF_API_KEY_IGDB@' + IGDB API key + + + "Game" + Preferred description source + + + + + + + [] + Global tweaks list + + + diff --git a/data/com.github.tkashkin.gamehub.policy.in b/data/com.github.tkashkin.gamehub.policy.in new file mode 100644 index 00000000..7758e7ae --- /dev/null +++ b/data/com.github.tkashkin.gamehub.policy.in @@ -0,0 +1,18 @@ + + + + Anatoliy Kashkin + https://tkashkin.tk/projects/gamehub + + + Manage overlays + Authentication is required to manage overlays + drive-removable-media + + yes + yes + yes + + @BINDIR@/@PROJECT_NAME@-overlayfs-helper + + diff --git a/data/com.github.tkashkin.gamehub.svg b/data/com.github.tkashkin.gamehub.svg deleted file mode 100644 index a56b96bc..00000000 --- a/data/com.github.tkashkin.gamehub.svg +++ /dev/null @@ -1,174 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/data/css/app.css b/data/css/app.css new file mode 100755 index 00000000..dcdb24e1 --- /dev/null +++ b/data/css/app.css @@ -0,0 +1,679 @@ +@define-color settings_separator alpha(shade(@theme_fg_color, 0.8), 0.15); +@define-color settings_separator_shadow alpha(shade(@theme_bg_color, 0.8), 0.2); + +.gamecard +{ + opacity: 0.75; + transition: 100ms; + background-color: alpha(#999, 0.5); + color: white; + -gtk-icon-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); +} + +.gamecard, .gamecard border +{ + border: none; + border-radius: 4px; +} + +.gamecard.installed, .gamecard.static +{ + opacity: 1; +} + +.gamecard.hover:not(.installed), +.games-grid flowboxchild:focus .gamecard:not(.installed), +.games-grid flowboxchild:selected .gamecard:not(.installed) +{ + opacity: 0.8; +} + +.gamecard GtkLabel, .gamecard label +{ + color: rgba(255, 255, 255, 0.9); + font-weight: bold; + margin-top: 16px; + font-size: 1.3em; + text-shadow: 0 2px 4px rgba(0, 0, 0, 0.6); +} + +.gamecard GtkLabel.status, .gamecard label.status +{ + color: rgba(255, 255, 255, 0.6); + font-size: 0.9em; + margin-top: -8px; + margin-bottom: -16px; + opacity: 0; + transition: 100ms; +} + +.gamecard.installing GtkLabel.status, .gamecard.installing label.status, +.gamecard.hover GtkLabel.status, .gamecard.hover label.status, +.gamecard.running GtkLabel.status, .gamecard.running label.status, +.games-grid flowboxchild:focus .gamecard GtkLabel.status, .games-grid flowboxchild:focus .gamecard label.status, +.games-grid flowboxchild:selected .gamecard GtkLabel.status, .games-grid flowboxchild:selected .gamecard label.status +{ + margin-bottom: 0px; + opacity: 1; +} + +.gamecard.downloading GtkLabel.status, .gamecard.downloading label.status, +.gamecard.downloading.hover GtkLabel.status, .gamecard.downloading.hover label.status, +.games-grid flowboxchild:focus .gamecard.downloading GtkLabel.status, .games-grid flowboxchild:focus .gamecard.downloading label.status, +.games-grid flowboxchild:selected .gamecard.downloading GtkLabel.status, .games-grid flowboxchild:selected .gamecard.downloading label.status +{ + margin-bottom: 8px; + opacity: 1; +} + +.gamecard .info +{ + background-color: transparent; + background-image: linear-gradient(to top, rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0)); + border-radius: 0 0 4px 4px; + border: none; + outline: none; + box-shadow: none; +} + +.gamecard .actions +{ + background-color: rgba(0, 0, 0, 0.4); + border: 1px rgba(0, 0, 0, 0.6) solid; + border-radius: 4px; + transition: 100ms; +} + +.gamecard.installed .actions, .gamecard.static .actions +{ + background-color: rgba(0, 0, 0, 0); +} + +.gamecard.hover .actions, +.games-grid flowboxchild:focus .gamecard .actions, +.games-grid flowboxchild:selected .gamecard .actions +{ + background-color: rgba(0, 0, 0, 0.2); +} + +.gamecard.installed.hover .actions, +.games-grid flowboxchild:focus .gamecard.installed .actions, +.games-grid flowboxchild:selected .gamecard.installed .actions +{ + background-color: rgba(255, 255, 255, 0.2); +} + +.gamecard .progress +{ + background-color: rgba(255, 255, 255, 0.6); + border-radius: 4px; + transition: 100ms; + margin-bottom: -16px; + opacity: 0; +} + +.gamecard.downloading .progress +{ + margin-bottom: 0; + opacity: 1; +} + +.gamecard image +{ + opacity: 0.6; + transition: 100ms; +} + +.gamecard.hover image, +.games-grid flowboxchild:focus image, +.games-grid flowboxchild:selected image +{ + opacity: 0.8; +} + +.games-grid flowboxchild +{ + border-radius: 4px; + padding: 0; +} + +.games-grid flowboxchild:focus +{ + background: @theme_selected_bg_color; +} + +.gamecard.running .actions, +.gamecard.hover.running .actions, +.games-grid flowboxchild:focus .gamecard.running .actions, +.games-grid flowboxchild:selected .gamecard.running .actions +{ + background-color: rgba(0, 0, 0, 0.6); +} +.gamecard .running-indicator, +.gamecard .no-image-indicator +{ + opacity: 1; +} + +.gamecard .images-download-button +{ + color: white; + background: alpha(#333, 0.5); + border-radius: 50%; + border: none; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); + min-width: 28px; + min-height: 28px; + padding: 0; +} +.gamecard .images-download-button image +{ + opacity: 1; +} +.gamecard .images-download-button:checked +{ + background: alpha(#333, 0.8); +} + +.h1 +{ + font-size: 24pt; +} +.h2 +{ + font-weight: 300; + font-size: 18pt; +} +.h3 +{ + font-size: 11pt; +} +.h4, .category-label +{ + font-weight: bold; +} +.h4, .gameinfo-singleline-value, .gameinfo-multiline-value +{ + padding-bottom: 6px; + padding-top: 6px; +} +.gameinfo-multiline-value +{ + padding-top: 0; +} +.description-header +{ + padding-bottom: 0; +} +GtkList .h4, list .h4 +{ + padding-left: 6px; + padding-right: 6px; +} +GtkButton GtkLabel, button label +{ + padding: 0 6px; +} +.card +{ + border: none; + border-color: transparent; + box-shadow: 0 0 0 1px alpha(#000, 0.05), 0 3px 3px alpha(#000, 0.22); + border-radius: 4px; +} +GtkListBox:not(:backdrop) .list-row:selected:focus GtkLabel.category-label, +list:not(:backdrop) row:selected:focus label.category-label +{ + color: alpha(#ffffff, 0.8); +} +.overlay-bar +{ + background-color: alpha(#222, 0.9); + border-radius: 3px; + border-width: 0; + box-shadow: 0 1px 3px alpha(#000, 0.12), 0 1px 2px alpha(#000, 0.24); + color: #fff; + padding: 3px 6px; + text-shadow: 0 1px 2px alpha(#000, 0.6); + margin: 3px; +} +.overlay-bar label +{ + color: #fff; + text-shadow: 0 1px 2px alpha(#000, 0.6); +} + +.installers-list +{ + background: transparent; +} + +.installers-list .list-row, +.installers-list row +{ + border-radius: 2px; +} + +.downloads-list .list-row, +.downloads-list row +{ + background: transparent; + border-bottom: 1px alpha(#333, 0.3) solid; + outline: none; +} +.downloads-list .list-row:last-child, +.downloads-list row:last-child +{ + border-bottom: none; +} +.downloads-list .list-row:selected, +.downloads-list row:selected +{ + background: transparent; + outline: none; +} +.downloads-list .list-row:focus, +.downloads-list row:focus +{ + background: transparent; + outline: none; +} + +.games-list-header +{ + background: shade(@theme_bg_color, 0.95); + border-top: 1px shade(@theme_bg_color, 0.7) solid; + border-bottom: 1px shade(@theme_bg_color, 0.7) solid; + padding: 6px 5px; +} +.games-list-header.first +{ + border-top: none; +} +.games-list-header > label +{ + padding: 0 3px; +} + +.game-list-row +{ + padding: 0; + outline: none; +} +.game-list-row .title +{ + padding: 0; +} +.game-list-row .title.bold +{ + font-weight: bold; +} +.game-list-row .status +{ + font-size: 8pt; + opacity: 0.8; + padding: 0; +} + +.game-list-row.dim +{ + opacity: 0.6; +} + +.gameinfo-background :not(.igdb-data-container-scrollable-value) > undershoot.left +{ + background: linear-gradient(to left, alpha(@theme_bg_color, 0) 50%, @theme_bg_color); +} +.gameinfo-background :not(.igdb-data-container-scrollable-value) > undershoot.right +{ + background: linear-gradient(to right, alpha(@theme_bg_color, 0) 50%, @theme_bg_color); +} +.dl-progress-type-icon +{ + padding: 4px; + background-color: shade(@theme_bg_color, 0.95); + border-radius: 50%; + border: 1px shade(@theme_bg_color, 0.75) solid; + color: @theme_fg_color; +} + +GtkListBox.gameinfo-content-list, +list.gameinfo-content-list +{ + background: transparent; +} +GtkListBox.gameinfo-content-list .list-row, +list.gameinfo-content-list row +{ + background: transparent; + border-bottom: 1px alpha(#888, 0.2) solid; + outline: none; + padding: 0; + margin: 0; +} +GtkListBox.gameinfo-content-list .list-row:last-child, +list.gameinfo-content-list row:last-child +{ + border-bottom: none; +} +GtkListBox.gameinfo-content-list .list-row:selected, +list.gameinfo-content-list row:selected +{ + outline: none; +} +GtkListBox.gameinfo-content-list .list-row:focus, +list.gameinfo-content-list row:focus +{ + background: transparent; + outline: none; +} +GtkListBox.gameinfo-content-list .list-row:hover, +list.gameinfo-content-list row:hover +{ + background: alpha(#888, 0.1); +} + +.gameinfo-content-list .progress +{ + border: none; + outline: none; + background: alpha(#888, 0.2); + opacity: 0; + transition: 100ms; +} +.gameinfo-content-list .progress.downloading +{ + opacity: 1; +} + +.gameinfo-toolbar +{ + border: none; + border-bottom: 1px shade(@theme_bg_color, 0.7) solid; + box-shadow: none; + border-radius: 0; + padding: 2px 16px; + margin: 0; + background: shade(@theme_bg_color, 0.95); +} + +.gameinfo-toolbar revealer, .gameinfo-toolbar box +{ + border: none; + box-shadow: none; + border-radius: 0; + padding: 0; + margin: 0; + background: transparent; +} + +.dark .gameinfo-toolbar +{ + border-bottom: 1px alpha(#333, 0.8) solid; + background: alpha(#333, 0.3); +} + +dialog .gameinfo-toolbar, dialog .dark .gameinfo-toolbar +{ + background: transparent; +} + +GtkListBox.tags-list, +list.tags-list +{ + background: transparent; +} +GtkListBox.tags-list .list-row, +list.tags-list row +{ + background: transparent; + outline: none; + padding: 0; + margin: 0; + border-radius: 2px; +} +GtkListBox.tags-list.not-rounded .list-row, +list.tags-list.not-rounded row +{ + border-radius: 0; +} +GtkListBox.tags-list .list-row:last-child, +list.tags-list row:last-child +{ + border-bottom: none; +} +GtkListBox.tags-list .list-row:selected, +list.tags-list row:selected +{ + outline: none; +} +GtkListBox.tags-list .list-row:focus, +list.tags-list row:focus +{ + background: @theme_selected_bg_color; + color: @theme_selected_fg_color; + outline: none; +} +GtkListBox.tags-list .list-row:hover, +list.tags-list row:hover +{ + background: alpha(#888, 0.1); +} +GtkListBox.tags-list .list-row:focus:hover, +list.tags-list row:focus:hover +{ + background: shade(@theme_selected_bg_color, 0.9); +} + +.tags-list-header.hover +{ + background: alpha(#888, 0.1); +} +.tags-list-header label +{ + padding: 2px 0; +} +.tags-list-header:focus +{ + background: @theme_selected_bg_color; + color: @theme_selected_fg_color; +} +.tags-list-header.hover:focus +{ + background: shade(@theme_selected_bg_color, 0.9); +} +.tags-list-header:focus label +{ + color: @theme_selected_fg_color; +} + +GtkListBox.overlays-list, +list.overlays-list +{ + background: transparent; +} +GtkListBox.overlays-list .list-row, +list.overlays-list row +{ + background: transparent; + outline: none; + padding: 0; + margin: 0; + border-radius: 2px; + border-bottom: 1px alpha(#888, 0.2) solid; +} +GtkListBox.overlays-list .list-row:last-child, +list.overlays-list row:last-child +{ + border-bottom: none; +} +GtkListBox.overlays-list .list-row:selected, +list.overlays-list row:selected +{ + outline: none; +} +GtkListBox.overlays-list .list-row:hover, +list.overlays-list row:hover +{ + background: alpha(#888, 0.1); +} + +.link, .link label +{ + padding: 0; +} + +button.file label +{ + padding: 0 2px; +} + +checkbutton:not(.default-padding), checkbutton:not(.default-padding) check +{ + padding: 0; + margin: 0; +} + +dialog .sidebar, +dialog .sidebar list +{ + background: transparent; +} + +.icons-modebutton > *, .installer-platforms-list > * +{ + padding: 4px; + min-width: 16px; + min-height: 16px; +} +.icons-modebutton > * > image, .installer-platforms-list > * > image +{ + padding: 0; + margin: 0; +} + +.menuitem-game-action:dir(ltr), .menuitem-merged-game:dir(ltr) +{ + border-left: 8px alpha(#888, 0.2) solid; +} +.menuitem-game-action > label:dir(ltr), .menuitem-merged-game > label:dir(ltr) +{ + margin-left: -8px; +} +.menuitem-game-action:dir(rtl), .menuitem-merged-game:dir(rtl) +{ + border-right: 8px alpha(#888, 0.2) solid; +} +.menuitem-game-action > label:dir(rtl), .menuitem-merged-game > label:dir(rtl) +{ + margin-right: -8px; +} +.menuitem-game-action.primary +{ + font-weight: bold; +} + +.stack-switcher .text-button +{ + min-width: 32px; +} + +.settings-dialog actionbar, .settings-dialog actionbar > revealer +{ + padding: 0; +} +.settings-dialog actionbar > revealer > box +{ + padding: 4px; +} + +.settings-dialog:dir(ltr) +{ + background-image: linear-gradient(to right, + shade(@theme_bg_color, 0.95) 202px, + @settings_separator 202px, @settings_separator 203px, + @settings_separator_shadow 203px, @settings_separator_shadow 204px, + transparent 204px, transparent); +} +.settings-dialog headerbar:dir(ltr) +{ + background-image: linear-gradient(to right, + alpha(shade(@theme_bg_color, 0.1), 0.05) 202px, + @settings_separator 202px, @settings_separator 203px, + @settings_separator_shadow 203px, @settings_separator_shadow 204px, + transparent 204px, transparent); +} +.settings-dialog:dir(rtl) +{ + background-image: linear-gradient(to left, + shade(@theme_bg_color, 0.95) 202px, + @settings_separator 202px, @settings_separator 203px, + @settings_separator_shadow 203px, @settings_separator_shadow 204px, + transparent 204px, transparent); +} +.settings-dialog headerbar:dir(rtl) +{ + background-image: linear-gradient(to left, + alpha(shade(@theme_bg_color, 0.1), 0.05) 202px, + @settings_separator 202px, @settings_separator 203px, + @settings_separator_shadow 203px, @settings_separator_shadow 204px, + transparent 204px, transparent); +} + +.settings-dialog .settings-pages-sidebar list +{ + background: shade(@theme_bg_color, 0.95); +} + +.igdb-data-container, .gameinfo-sidebar-block +{ + background: shade(@theme_bg_color, 0.95); + border-radius: 4px; + border: 1px shade(@theme_bg_color, 0.7) solid; +} + +.igdb-data-container-scrollable-header +{ + padding-bottom: 0; +} + +.flat-list .list-row:not(:last-child), .flat-list row:not(:last-child) +{ + border-bottom: 1px shade(@theme_bg_color, 0.7) solid; +} + +.separated-list .list-row:not(:last-child), .separated-list row:not(:last-child) +{ + border-bottom: 1px shade(@theme_bg_color, 0.9) solid; +} + +.provider-settings +{ + background: alpha(shade(@theme_bg_color, 0.95), 0.5); +} + +.import-emulated-games-dialog .select-all +{ + margin: 0; + padding: 0; +} +.import-emulated-games-dialog .select-all > check +{ + margin: 0 16px 0 0; + padding: 0; +} +.import-emulated-games-dialog .select-all > label +{ + margin: 0; + padding: 0; +} +.import-emulated-games-dialog .dialog-action-box +{ + margin: 0; + padding: 0 8px 2px 8px; +} +.import-emulated-games-dialog .dialog-action-area +{ + margin: 0; + padding: 0 8px; +} diff --git a/data/css/themes/elementary.css b/data/css/themes/elementary.css new file mode 100644 index 00000000..6326fe82 --- /dev/null +++ b/data/css/themes/elementary.css @@ -0,0 +1,86 @@ +@define-color colorPrimary mix(#7239b3, @titlebar_color, 0.2); +@define-color colorAccent #8c53cb; +@define-color selected_bg_color @colorAccent; +@define-color theme_selected_bg_color @colorAccent; +@define-color textColorPrimary mix(@colorPrimary, #fafafa, 0.95); +@define-color textColorPrimaryShadow alpha(#7239b3, 0.4); + +@define-color textColorPrimaryDefault mix(@titlebar_color, @text_color, 0.75); +@define-color textColorPrimaryShadowDefault alpha(shade(@titlebar_color, 1.4), 0.4); + +@define-color settings_separator @menu_separator; +@define-color settings_separator_shadow @menu_separator_shadow; + +.titlebar.flat .title, +.titlebar.flat .subtitle, +.titlebar.flat .titlebutton, +.titlebar.flat button, +.titlebar.flat label, +.titlebar.flat *:not(entry) image +{ + color: @textColorPrimaryDefault; + text-shadow: 0 1px @textColorPrimaryShadowDefault; + -gtk-icon-shadow: 0 1px @textColorPrimaryShadowDefault; +} + +.titlebar.flat .title:backdrop, +.titlebar.flat .subtitle:backdrop, +.titlebar.flat .titlebutton:backdrop, +.titlebar.flat button:backdrop, +.titlebar.flat label:backdrop, +.titlebar.flat *:not(entry) image:backdrop +{ + color: mix(@textColorPrimaryDefault, @titlebar_color, 0.3); + text-shadow: none; + -gtk-icon-shadow: none; +} + +.titlebar:not(.flat) label +{ + color: @textColorPrimary; + text-shadow: 0 1px @textColorPrimaryShadow; + -gtk-icon-shadow: 0 1px @textColorPrimaryShadow; +} + +.titlebar:not(.flat) label:backdrop +{ + color: mix(@textColorPrimary, @titlebar_color, 0.3); + text-shadow: none; + -gtk-icon-shadow: none; +} + +infobar.frame.compat-tool-warning +{ + margin: -1px -3px -1px -7px; +} + +infobar.frame.settings-info +{ + margin: -1px -3px -1px -3px; +} + +.import-emulated-games-dialog .select-all +{ + margin: 0; + padding: 0; +} +.import-emulated-games-dialog .select-all > check +{ + margin: 0 12px 0 0; + padding: 0; +} +.import-emulated-games-dialog .select-all > label +{ + margin: 0; + padding: 0; +} +.import-emulated-games-dialog .dialog-action-box +{ + margin: 0; + padding: 0 8px 2px 8px; +} +.import-emulated-games-dialog .dialog-action-area +{ + margin: 0; + padding: 0; +} diff --git a/data/icon/128.svg b/data/icon/128.svg new file mode 100644 index 00000000..d68694d6 --- /dev/null +++ b/data/icon/128.svg @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/data/icon/32.svg b/data/icon/32.svg new file mode 100644 index 00000000..5a0bd752 --- /dev/null +++ b/data/icon/32.svg @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/data/icon/48.svg b/data/icon/48.svg new file mode 100644 index 00000000..2f09f4a6 --- /dev/null +++ b/data/icon/48.svg @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/data/icon/64.svg b/data/icon/64.svg new file mode 100644 index 00000000..f4c8356f --- /dev/null +++ b/data/icon/64.svg @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/data/icons/gog-white.svg b/data/icons/gog-white.svg deleted file mode 100644 index 7f997e80..00000000 --- a/data/icons/gog-white.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/data/icons/gog.svg b/data/icons/gog.svg deleted file mode 100644 index f439d5fc..00000000 --- a/data/icons/gog.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/data/icons/icons.gresource.xml b/data/icons/icons.gresource.xml index 5a0725f0..bf13ca6a 100644 --- a/data/icons/icons.gresource.xml +++ b/data/icons/icons.gresource.xml @@ -1,11 +1,75 @@ - steam.svg - steam-symbolic.svg - gog.svg - - steam-symbolic-white.svg - gog-white.svg + symbolic/sources/sources-all.svg + symbolic/sources/steam.svg + symbolic/sources/gog.svg + symbolic/sources/humble.svg + symbolic/sources/humble-trove.svg + symbolic/sources/itch.svg + + symbolic/emu/retroarch.svg + + symbolic/platforms/linux.svg + symbolic/platforms/windows.svg + symbolic/platforms/macos.svg + + symbolic/tools/wine.svg + symbolic/tools/dosbox.svg + symbolic/tools/scummvm.svg + + normal/providers/data/IGDB.svg + normal/providers/images/SteamGridDB.svg + + normal/tags/tag.svg + symbolic/tags/tag.svg + + symbolic/tags/tag.svg + symbolic/tags/tag-add.svg + symbolic/tags/tag-remove.svg + symbolic/tags/tag-multiple.svg + symbolic/tags/tag-favorites.svg + symbolic/tags/tag-hidden.svg + + symbolic/game-favorite.svg + symbolic/game-updated.svg + + symbolic/gamehub.svg + + normal/controller/a.svg + normal/controller/b.svg + normal/controller/x.svg + normal/controller/y.svg + normal/controller/start.svg + normal/controller/guide.svg + normal/controller/select.svg + normal/controller/bumper-left.svg + normal/controller/bumper-right.svg + normal/controller/trigger-left.svg + normal/controller/trigger-right.svg + normal/controller/grip-left.svg + normal/controller/grip-right.svg + + symbolic/related-links/app-android.svg + symbolic/related-links/app-ipad.svg + symbolic/related-links/app-iphone.svg + symbolic/related-links/discord.svg + symbolic/related-links/facebook.svg + symbolic/related-links/google-plus.svg + symbolic/related-links/instagram.svg + symbolic/related-links/linkedin.svg + symbolic/related-links/pinterest.svg + symbolic/related-links/reddit.svg + symbolic/related-links/soundcloud.svg + symbolic/related-links/tumblr.svg + symbolic/related-links/twitch.svg + symbolic/related-links/twitter.svg + symbolic/related-links/wikipedia.svg + symbolic/related-links/youtube.svg + + symbolic/about-links/git.svg + symbolic/about-links/github.svg + symbolic/about-links/codeberg.org.svg + symbolic/about-links/git.froggi.es.svg diff --git a/data/icons/normal/controller/a.svg b/data/icons/normal/controller/a.svg new file mode 100644 index 00000000..d57790ad --- /dev/null +++ b/data/icons/normal/controller/a.svg @@ -0,0 +1,72 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/data/icons/normal/controller/b.svg b/data/icons/normal/controller/b.svg new file mode 100644 index 00000000..b5bd3255 --- /dev/null +++ b/data/icons/normal/controller/b.svg @@ -0,0 +1,72 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/data/icons/normal/controller/bumper-left.svg b/data/icons/normal/controller/bumper-left.svg new file mode 100644 index 00000000..c794ab3c --- /dev/null +++ b/data/icons/normal/controller/bumper-left.svg @@ -0,0 +1,72 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/data/icons/normal/controller/bumper-right.svg b/data/icons/normal/controller/bumper-right.svg new file mode 100644 index 00000000..2fdc1788 --- /dev/null +++ b/data/icons/normal/controller/bumper-right.svg @@ -0,0 +1,72 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/data/icons/normal/controller/grip-left.svg b/data/icons/normal/controller/grip-left.svg new file mode 100644 index 00000000..6adcb2d6 --- /dev/null +++ b/data/icons/normal/controller/grip-left.svg @@ -0,0 +1,72 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/data/icons/normal/controller/grip-right.svg b/data/icons/normal/controller/grip-right.svg new file mode 100644 index 00000000..4099368c --- /dev/null +++ b/data/icons/normal/controller/grip-right.svg @@ -0,0 +1,72 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/data/icons/normal/controller/guide.svg b/data/icons/normal/controller/guide.svg new file mode 100644 index 00000000..62d4bc9c --- /dev/null +++ b/data/icons/normal/controller/guide.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/data/icons/normal/controller/select.svg b/data/icons/normal/controller/select.svg new file mode 100644 index 00000000..46664a25 --- /dev/null +++ b/data/icons/normal/controller/select.svg @@ -0,0 +1,72 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/data/icons/normal/controller/start.svg b/data/icons/normal/controller/start.svg new file mode 100644 index 00000000..fa3bf8e9 --- /dev/null +++ b/data/icons/normal/controller/start.svg @@ -0,0 +1,72 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/data/icons/normal/controller/trigger-left.svg b/data/icons/normal/controller/trigger-left.svg new file mode 100644 index 00000000..e9344b24 --- /dev/null +++ b/data/icons/normal/controller/trigger-left.svg @@ -0,0 +1,72 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/data/icons/normal/controller/trigger-right.svg b/data/icons/normal/controller/trigger-right.svg new file mode 100644 index 00000000..267530b7 --- /dev/null +++ b/data/icons/normal/controller/trigger-right.svg @@ -0,0 +1,72 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/data/icons/normal/controller/x.svg b/data/icons/normal/controller/x.svg new file mode 100644 index 00000000..550c2e46 --- /dev/null +++ b/data/icons/normal/controller/x.svg @@ -0,0 +1,72 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/data/icons/normal/controller/y.svg b/data/icons/normal/controller/y.svg new file mode 100644 index 00000000..1b5fe9c8 --- /dev/null +++ b/data/icons/normal/controller/y.svg @@ -0,0 +1,72 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/data/icons/normal/providers/data/IGDB.svg b/data/icons/normal/providers/data/IGDB.svg new file mode 100644 index 00000000..86892d83 --- /dev/null +++ b/data/icons/normal/providers/data/IGDB.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/icons/normal/providers/images/SteamGridDB.svg b/data/icons/normal/providers/images/SteamGridDB.svg new file mode 100644 index 00000000..da91e31b --- /dev/null +++ b/data/icons/normal/providers/images/SteamGridDB.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/data/icons/normal/tags/tag.svg b/data/icons/normal/tags/tag.svg new file mode 100644 index 00000000..5b33820a --- /dev/null +++ b/data/icons/normal/tags/tag.svg @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/data/icons/steam-symbolic-white.svg b/data/icons/steam-symbolic-white.svg deleted file mode 100644 index b063e66e..00000000 --- a/data/icons/steam-symbolic-white.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/data/icons/steam-symbolic.svg b/data/icons/steam-symbolic.svg deleted file mode 100644 index a89e27f6..00000000 --- a/data/icons/steam-symbolic.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/data/icons/steam.svg b/data/icons/steam.svg deleted file mode 100644 index 0c27cadc..00000000 --- a/data/icons/steam.svg +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/data/icons/symbolic/about-links/codeberg.org.svg b/data/icons/symbolic/about-links/codeberg.org.svg new file mode 100644 index 00000000..3ce48bb6 --- /dev/null +++ b/data/icons/symbolic/about-links/codeberg.org.svg @@ -0,0 +1,6 @@ + + + + + codeberg + diff --git a/data/icons/symbolic/about-links/git.froggi.es.svg b/data/icons/symbolic/about-links/git.froggi.es.svg new file mode 100644 index 00000000..8dcba9cb --- /dev/null +++ b/data/icons/symbolic/about-links/git.froggi.es.svg @@ -0,0 +1,2 @@ + +image/svg+xml \ No newline at end of file diff --git a/data/icons/symbolic/about-links/git.svg b/data/icons/symbolic/about-links/git.svg new file mode 100644 index 00000000..ac8f623f --- /dev/null +++ b/data/icons/symbolic/about-links/git.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/about-links/github.svg b/data/icons/symbolic/about-links/github.svg new file mode 100644 index 00000000..616df56b --- /dev/null +++ b/data/icons/symbolic/about-links/github.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/emu/retroarch.svg b/data/icons/symbolic/emu/retroarch.svg new file mode 100644 index 00000000..7ce5bc72 --- /dev/null +++ b/data/icons/symbolic/emu/retroarch.svg @@ -0,0 +1,3 @@ + + + diff --git a/data/icons/symbolic/game-favorite.svg b/data/icons/symbolic/game-favorite.svg new file mode 100644 index 00000000..279c90cd --- /dev/null +++ b/data/icons/symbolic/game-favorite.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/game-updated.svg b/data/icons/symbolic/game-updated.svg new file mode 100644 index 00000000..5920b08c --- /dev/null +++ b/data/icons/symbolic/game-updated.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/gamehub.svg b/data/icons/symbolic/gamehub.svg new file mode 100644 index 00000000..0d1d9c70 --- /dev/null +++ b/data/icons/symbolic/gamehub.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/platforms/linux.svg b/data/icons/symbolic/platforms/linux.svg new file mode 100644 index 00000000..174b7348 --- /dev/null +++ b/data/icons/symbolic/platforms/linux.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/data/icons/symbolic/platforms/macos.svg b/data/icons/symbolic/platforms/macos.svg new file mode 100644 index 00000000..609f73b5 --- /dev/null +++ b/data/icons/symbolic/platforms/macos.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/data/icons/symbolic/platforms/windows.svg b/data/icons/symbolic/platforms/windows.svg new file mode 100644 index 00000000..831cb31f --- /dev/null +++ b/data/icons/symbolic/platforms/windows.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/data/icons/symbolic/related-links/app-android.svg b/data/icons/symbolic/related-links/app-android.svg new file mode 100644 index 00000000..61cf09ed --- /dev/null +++ b/data/icons/symbolic/related-links/app-android.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/related-links/app-ipad.svg b/data/icons/symbolic/related-links/app-ipad.svg new file mode 100644 index 00000000..4ad10913 --- /dev/null +++ b/data/icons/symbolic/related-links/app-ipad.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/related-links/app-iphone.svg b/data/icons/symbolic/related-links/app-iphone.svg new file mode 100644 index 00000000..f10d9a10 --- /dev/null +++ b/data/icons/symbolic/related-links/app-iphone.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/related-links/discord.svg b/data/icons/symbolic/related-links/discord.svg new file mode 100644 index 00000000..15b4539d --- /dev/null +++ b/data/icons/symbolic/related-links/discord.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/related-links/facebook.svg b/data/icons/symbolic/related-links/facebook.svg new file mode 100644 index 00000000..a5f4a7cc --- /dev/null +++ b/data/icons/symbolic/related-links/facebook.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/related-links/google-plus.svg b/data/icons/symbolic/related-links/google-plus.svg new file mode 100644 index 00000000..a69f6ac8 --- /dev/null +++ b/data/icons/symbolic/related-links/google-plus.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/related-links/instagram.svg b/data/icons/symbolic/related-links/instagram.svg new file mode 100644 index 00000000..c2591413 --- /dev/null +++ b/data/icons/symbolic/related-links/instagram.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/related-links/linkedin.svg b/data/icons/symbolic/related-links/linkedin.svg new file mode 100644 index 00000000..554c7e53 --- /dev/null +++ b/data/icons/symbolic/related-links/linkedin.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/related-links/pinterest.svg b/data/icons/symbolic/related-links/pinterest.svg new file mode 100644 index 00000000..29d79693 --- /dev/null +++ b/data/icons/symbolic/related-links/pinterest.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/related-links/reddit.svg b/data/icons/symbolic/related-links/reddit.svg new file mode 100644 index 00000000..5abb5e3b --- /dev/null +++ b/data/icons/symbolic/related-links/reddit.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/related-links/soundcloud.svg b/data/icons/symbolic/related-links/soundcloud.svg new file mode 100644 index 00000000..f43044ed --- /dev/null +++ b/data/icons/symbolic/related-links/soundcloud.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/related-links/tumblr.svg b/data/icons/symbolic/related-links/tumblr.svg new file mode 100644 index 00000000..e23e5882 --- /dev/null +++ b/data/icons/symbolic/related-links/tumblr.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/related-links/twitch.svg b/data/icons/symbolic/related-links/twitch.svg new file mode 100644 index 00000000..c2f53014 --- /dev/null +++ b/data/icons/symbolic/related-links/twitch.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/related-links/twitter.svg b/data/icons/symbolic/related-links/twitter.svg new file mode 100644 index 00000000..4ea8e0a2 --- /dev/null +++ b/data/icons/symbolic/related-links/twitter.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/related-links/wikipedia.svg b/data/icons/symbolic/related-links/wikipedia.svg new file mode 100644 index 00000000..7adb51b9 --- /dev/null +++ b/data/icons/symbolic/related-links/wikipedia.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/related-links/youtube.svg b/data/icons/symbolic/related-links/youtube.svg new file mode 100644 index 00000000..92f643d7 --- /dev/null +++ b/data/icons/symbolic/related-links/youtube.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/sources/gog.svg b/data/icons/symbolic/sources/gog.svg new file mode 100644 index 00000000..83f27ee4 --- /dev/null +++ b/data/icons/symbolic/sources/gog.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/data/icons/symbolic/sources/humble-trove.svg b/data/icons/symbolic/sources/humble-trove.svg new file mode 100644 index 00000000..2f65244d --- /dev/null +++ b/data/icons/symbolic/sources/humble-trove.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/sources/humble.svg b/data/icons/symbolic/sources/humble.svg new file mode 100644 index 00000000..71eee6e0 --- /dev/null +++ b/data/icons/symbolic/sources/humble.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/data/icons/symbolic/sources/itch.svg b/data/icons/symbolic/sources/itch.svg new file mode 100644 index 00000000..99ee59e2 --- /dev/null +++ b/data/icons/symbolic/sources/itch.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/sources/sources-all.svg b/data/icons/symbolic/sources/sources-all.svg new file mode 100644 index 00000000..67a89712 --- /dev/null +++ b/data/icons/symbolic/sources/sources-all.svg @@ -0,0 +1,13 @@ + + + + + + diff --git a/data/icons/symbolic/sources/steam.svg b/data/icons/symbolic/sources/steam.svg new file mode 100644 index 00000000..e6abb6de --- /dev/null +++ b/data/icons/symbolic/sources/steam.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/data/icons/symbolic/tags/tag-add.svg b/data/icons/symbolic/tags/tag-add.svg new file mode 100644 index 00000000..98dcaf5b --- /dev/null +++ b/data/icons/symbolic/tags/tag-add.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/tags/tag-favorites.svg b/data/icons/symbolic/tags/tag-favorites.svg new file mode 100644 index 00000000..bb2a2d32 --- /dev/null +++ b/data/icons/symbolic/tags/tag-favorites.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/tags/tag-hidden.svg b/data/icons/symbolic/tags/tag-hidden.svg new file mode 100644 index 00000000..8317d839 --- /dev/null +++ b/data/icons/symbolic/tags/tag-hidden.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/tags/tag-multiple.svg b/data/icons/symbolic/tags/tag-multiple.svg new file mode 100644 index 00000000..165a4353 --- /dev/null +++ b/data/icons/symbolic/tags/tag-multiple.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/tags/tag-remove.svg b/data/icons/symbolic/tags/tag-remove.svg new file mode 100644 index 00000000..c129ae72 --- /dev/null +++ b/data/icons/symbolic/tags/tag-remove.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/tags/tag.svg b/data/icons/symbolic/tags/tag.svg new file mode 100644 index 00000000..28661e25 --- /dev/null +++ b/data/icons/symbolic/tags/tag.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/tools/dosbox.svg b/data/icons/symbolic/tools/dosbox.svg new file mode 100644 index 00000000..0d785564 --- /dev/null +++ b/data/icons/symbolic/tools/dosbox.svg @@ -0,0 +1,3 @@ + + + diff --git a/data/icons/symbolic/tools/scummvm.svg b/data/icons/symbolic/tools/scummvm.svg new file mode 100644 index 00000000..722844f0 --- /dev/null +++ b/data/icons/symbolic/tools/scummvm.svg @@ -0,0 +1,4 @@ + + + + diff --git a/data/icons/symbolic/tools/wine.svg b/data/icons/symbolic/tools/wine.svg new file mode 100644 index 00000000..f0ebad6f --- /dev/null +++ b/data/icons/symbolic/tools/wine.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/data/meson.build b/data/meson.build index ceb91917..d7055d05 100644 --- a/data/meson.build +++ b/data/meson.build @@ -1,32 +1,82 @@ -install_data( - meson.project_name() + '.svg', - install_dir: join_paths(get_option('datadir'), 'icons', 'hicolor', 'scalable', 'apps') +icon_sizes = ['32', '48', '64', '128'] + +foreach i : icon_sizes + install_data( + join_paths('icon', i + '.svg'), + install_dir: join_paths(get_option('prefix'), get_option('datadir'), 'icons', 'hicolor', i + 'x' + i, 'apps'), + rename: meson.project_name() + '.svg' + ) + install_data( + join_paths('icon', i + '.svg'), + install_dir: join_paths(get_option('prefix'), get_option('datadir'), 'icons', 'hicolor', i + 'x' + i + '@2', 'apps'), + rename: meson.project_name() + '.svg' + ) +endforeach + +gschema_conf = configuration_data() +gschema_conf.set('SCHEMA_ID', meson.project_name()) +gschema_conf.set('SCHEMA_PATH', '/' + ('/'.join(meson.project_name().split('.')))) # meson.project_name().replace('.', '/') +gschema_conf.set('PREF_API_KEY_STEAM', get_option('api_key_steam')) +gschema_conf.set('PREF_API_KEY_ITCH', get_option('api_key_itch')) +gschema_conf.set('PREF_API_KEY_IGDB', get_option('api_key_igdb')) +gschema_conf.set('PREF_API_KEY_STEAMGRIDDB', get_option('api_key_steamgriddb')) +gschema_conf.set('PREF_LIBRETRO_CORE_DIR', get_option('libretro_core_dir')) +gschema_conf.set('PREF_LIBRETRO_CORE_INFO_DIR', get_option('libretro_core_info_dir')) + +configure_file( + input: meson.project_name() + '.gschema.xml.in', + output: meson.project_name() + '.gschema.xml', + configuration: gschema_conf, + install: true, + install_dir: join_paths(get_option('prefix'), get_option('datadir'), 'glib-2.0', 'schemas') ) +install_subdir('share/compat', install_dir: join_paths(get_option('prefix'), get_option('datadir'), meson.project_name())) +install_subdir('share/tweaks', install_dir: join_paths(get_option('prefix'), get_option('datadir'), meson.project_name())) + i18n.merge_file( - input: meson.project_name() + '.desktop.in', - output: meson.project_name() + '.desktop', - po_dir: join_paths(meson.source_root(), 'po'), - type: 'desktop', - install: true, - install_dir: join_paths(get_option('datadir'), 'applications') + input: meson.project_name() + '.desktop.in', + output: meson.project_name() + '.desktop', + po_dir: join_paths(meson.source_root(), 'po'), + type: 'desktop', + install: true, + install_dir: join_paths(get_option('prefix'), get_option('datadir'), 'applications') ) -i18n.merge_file( - input: meson.project_name() + '.appdata.xml.in', - output: meson.project_name() + '.appdata.xml', - po_dir: join_paths(meson.source_root(), 'po'), - install: true, - install_dir: join_paths(get_option('datadir'), 'metainfo') +appdata_changelog_conf = configuration_data() +appdata_changelog_conf.set('CHANGELOG', run_command('cat', files(meson.project_name() + '.changelog.xml')).stdout().strip()) + +configure_file( + input: meson.project_name() + '.appdata.xml.in', + output: meson.project_name() + '.appdata.xml', + configuration: appdata_changelog_conf, + install: true, + install_dir: join_paths(get_option('prefix'), get_option('datadir'), 'metainfo') +) + +polkit_policy = configure_file( + input: meson.project_name() + '.policy.in', + output: meson.project_name() + '.policy', + configuration: conf_data +) + +install_data( + polkit_policy, + install_dir: join_paths(get_option('prefix'), get_option('datadir'), 'polkit-1', 'actions') +) + +install_data( + meson.project_name() + '-overlayfs-helper', + install_dir: join_paths(get_option('prefix'), get_option('bindir')) ) icons_gresource = gnome.compile_resources( - 'gresource_icons', - 'icons/icons.gresource.xml', - source_dir: 'icons' + 'gresource_icons', + 'icons/icons.gresource.xml', + source_dir: 'icons' ) css_gresource = gnome.compile_resources( - 'gresource_css', - meson.project_name() + '.gresource.xml' + 'gresource_css', + meson.project_name() + '.gresource.xml' ) diff --git a/data/screenshots/dark/details.png b/data/screenshots/dark/details.png new file mode 100644 index 00000000..783883d5 Binary files /dev/null and b/data/screenshots/dark/details.png differ diff --git a/data/screenshots/dark/grid.png b/data/screenshots/dark/grid.png new file mode 100644 index 00000000..4539b6bb Binary files /dev/null and b/data/screenshots/dark/grid.png differ diff --git a/data/screenshots/dark/grid_controller.png b/data/screenshots/dark/grid_controller.png new file mode 100644 index 00000000..d9583a15 Binary files /dev/null and b/data/screenshots/dark/grid_controller.png differ diff --git a/data/screenshots/dark/install.png b/data/screenshots/dark/install.png new file mode 100644 index 00000000..ebea5f07 Binary files /dev/null and b/data/screenshots/dark/install.png differ diff --git a/data/screenshots/dark/install_compat.png b/data/screenshots/dark/install_compat.png new file mode 100644 index 00000000..52074453 Binary files /dev/null and b/data/screenshots/dark/install_compat.png differ diff --git a/data/screenshots/dark/list.png b/data/screenshots/dark/list.png new file mode 100644 index 00000000..b1ec75c6 Binary files /dev/null and b/data/screenshots/dark/list.png differ diff --git a/data/screenshots/dark/overlays.png b/data/screenshots/dark/overlays.png new file mode 100644 index 00000000..9f6fcbe7 Binary files /dev/null and b/data/screenshots/dark/overlays.png differ diff --git a/data/screenshots/dark/properties.png b/data/screenshots/dark/properties.png new file mode 100644 index 00000000..ab4088c5 Binary files /dev/null and b/data/screenshots/dark/properties.png differ diff --git a/data/screenshots/dark/settings_collection.png b/data/screenshots/dark/settings_collection.png new file mode 100644 index 00000000..fd13ebb4 Binary files /dev/null and b/data/screenshots/dark/settings_collection.png differ diff --git a/data/screenshots/dark/settings_controller.png b/data/screenshots/dark/settings_controller.png new file mode 100644 index 00000000..0533a568 Binary files /dev/null and b/data/screenshots/dark/settings_controller.png differ diff --git a/data/screenshots/dark/welcome.png b/data/screenshots/dark/welcome.png new file mode 100644 index 00000000..a8757e0c Binary files /dev/null and b/data/screenshots/dark/welcome.png differ diff --git a/data/screenshots/light/details.png b/data/screenshots/light/details.png new file mode 100644 index 00000000..ced471e8 Binary files /dev/null and b/data/screenshots/light/details.png differ diff --git a/data/screenshots/light/grid.png b/data/screenshots/light/grid.png new file mode 100644 index 00000000..b344acf8 Binary files /dev/null and b/data/screenshots/light/grid.png differ diff --git a/data/screenshots/light/grid_controller.png b/data/screenshots/light/grid_controller.png new file mode 100644 index 00000000..22c0b08e Binary files /dev/null and b/data/screenshots/light/grid_controller.png differ diff --git a/data/screenshots/light/install.png b/data/screenshots/light/install.png new file mode 100644 index 00000000..404a4b96 Binary files /dev/null and b/data/screenshots/light/install.png differ diff --git a/data/screenshots/light/install_compat.png b/data/screenshots/light/install_compat.png new file mode 100644 index 00000000..755265b8 Binary files /dev/null and b/data/screenshots/light/install_compat.png differ diff --git a/data/screenshots/light/list.png b/data/screenshots/light/list.png new file mode 100644 index 00000000..4465ca1a Binary files /dev/null and b/data/screenshots/light/list.png differ diff --git a/data/screenshots/light/overlays.png b/data/screenshots/light/overlays.png new file mode 100644 index 00000000..58ed0bb1 Binary files /dev/null and b/data/screenshots/light/overlays.png differ diff --git a/data/screenshots/light/properties.png b/data/screenshots/light/properties.png new file mode 100644 index 00000000..23a72018 Binary files /dev/null and b/data/screenshots/light/properties.png differ diff --git a/data/screenshots/light/settings_collection.png b/data/screenshots/light/settings_collection.png new file mode 100644 index 00000000..de3d21c0 Binary files /dev/null and b/data/screenshots/light/settings_collection.png differ diff --git a/data/screenshots/light/settings_controller.png b/data/screenshots/light/settings_controller.png new file mode 100644 index 00000000..331c9912 Binary files /dev/null and b/data/screenshots/light/settings_controller.png differ diff --git a/data/screenshots/light/welcome.png b/data/screenshots/light/welcome.png new file mode 100644 index 00000000..f37cd9e7 Binary files /dev/null and b/data/screenshots/light/welcome.png differ diff --git a/data/share/compat/dosbox/windowed.conf b/data/share/compat/dosbox/windowed.conf new file mode 100644 index 00000000..9bc83426 --- /dev/null +++ b/data/share/compat/dosbox/windowed.conf @@ -0,0 +1,5 @@ +description=Disable fullscreen +enabled=true + +[sdl] +fullscreen=false diff --git a/data/share/tweaks/amd.json b/data/share/tweaks/amd.json new file mode 100644 index 00000000..05d30d78 --- /dev/null +++ b/data/share/tweaks/amd.json @@ -0,0 +1,12 @@ +{ + "id": "amdgpu_vulkan_aco", + "name": "AMD: Radeon ACO Vulkan Compiler", + "description": "Enable ACO based Vulkan shader compiler for RADV instead of LLVM", + "url": "https://github.com/mesa3d/mesa", + "applicable_to": { + "kmod": ["amdgpu"] + }, + "env": { + "RADV_PERFTEST": "aco" + } +} diff --git a/data/share/tweaks/gamemode.json b/data/share/tweaks/gamemode.json new file mode 100644 index 00000000..92e85a2c --- /dev/null +++ b/data/share/tweaks/gamemode.json @@ -0,0 +1,7 @@ +{ + "id": "gamemode", + "name": "Feral GameMode", + "description": "Temporarily apply a set of optimizations to a game process and OS. Requires Feral GameMode to be installed", + "url": "https://github.com/FeralInteractive/gamemode", + "command": "gamemoderun ${command}" +} diff --git a/data/share/tweaks/proton.json b/data/share/tweaks/proton.json new file mode 100644 index 00000000..076d0cf0 --- /dev/null +++ b/data/share/tweaks/proton.json @@ -0,0 +1,80 @@ +[ + { + "id": "dx_dxvk_hud", + "name": "DXVK: Show HUD", + "description": "Enable DXVK HUD", + "url": "https://github.com/doitsujin/dxvk#hud", + "applicable_to": { + "platforms": ["windows"], + "compat": ["wine", "proton"] + }, + "env": { + "DXVK_HUD": "devinfo,fps" + } + }, + { + "id": "proton_dx_wined3d", + "name": "Proton: Use WineD3D", + "description": "Use OpenGL-based WineD3D for D3D11, D3D10 and D3D9 instead of Vulkan-based DXVK", + "url": "https://github.com/ValveSoftware/Proton#runtime-config-options", + "applicable_to": { + "platforms": ["windows"], + "compat": ["proton"] + }, + "env": { + "PROTON_USE_WINED3D": "1" + } + }, + { + "id": "proton_dx_disable_d3d11", + "name": "Proton: Disable D3D11", + "description": "Disable d3d11.dll, for D3D11 games which can fall back to and run better with D3D9", + "url": "https://github.com/ValveSoftware/Proton#runtime-config-options", + "applicable_to": { + "platforms": ["windows"], + "compat": ["proton"] + }, + "env": { + "PROTON_NO_D3D11": "1" + } + }, + { + "id": "proton_dx_disable_d3d10", + "name": "Proton: Disable D3D10", + "description": "Disable d3d10.dll and dxgi.dll, for D3D10 games which can fall back to and run better with D3D9", + "url": "https://github.com/ValveSoftware/Proton#runtime-config-options", + "applicable_to": { + "platforms": ["windows"], + "compat": ["proton"] + }, + "env": { + "PROTON_NO_D3D10": "1" + } + }, + { + "id": "proton_no_esync", + "name": "Proton: Disable esync", + "description": "Disable eventfd-based in-process synchronization primitives", + "url": "https://github.com/ValveSoftware/Proton#runtime-config-options", + "applicable_to": { + "platforms": ["windows"], + "compat": ["proton"] + }, + "env": { + "PROTON_NO_ESYNC": "1" + } + }, + { + "id": "proton_no_fsync", + "name": "Proton: Disable fsync", + "description": "Disable futex-based in-process synchronization primitives", + "url": "https://github.com/ValveSoftware/Proton#runtime-config-options", + "applicable_to": { + "platforms": ["windows"], + "compat": ["proton"] + }, + "env": { + "PROTON_NO_FSYNC": "1" + } + } +] diff --git a/debian/changelog b/debian/changelog index c7a5d603..a6550b1e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,2075 @@ -com.github.tkashkin.gamehub (0.1) loki; urgency=low +com.github.tkashkin.gamehub (0.14.2-51-dev~elementary5.0) juno; urgency=low + * Merge pull request #312 from Lucki/patch-1 [6075c9f] + * Allow enabling d9vk [86b7d57] - * Initial Release. + -- Anatoliy Kashkin Fri, 15 Nov 2019 21:48:18 +0300 - -- tkashkin Thu, 24 May 2018 07:56:30 +0300 +com.github.tkashkin.gamehub (0.14.2-50-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Turkish) [006ff9f] + + -- Oğuz Ersen Wed, 13 Nov 2019 17:53:16 +0000 + +com.github.tkashkin.gamehub (0.14.2-49-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Turkish) [4d0a243] + + -- Oğuz Ersen Mon, 11 Nov 2019 19:07:16 +0000 + +com.github.tkashkin.gamehub (0.14.2-48-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Finnish) [4236830] + * Translated using Weblate (Finnish) [8ae0e75] + * Translated using Weblate (Catalan) [79c06dc] + + -- Tuomas Lähteenmäki Sat, 9 Nov 2019 21:43:37 +0000 + +com.github.tkashkin.gamehub (0.14.2-46-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Catalan) [7427529] + + -- Marc Riera Wed, 6 Nov 2019 23:28:04 +0000 + +com.github.tkashkin.gamehub (0.14.2-45-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Finnish) [b20005b] + + -- Tuomas Lähteenmäki Thu, 7 Nov 2019 02:44:04 +0000 + +com.github.tkashkin.gamehub (0.14.2-44-dev~elementary5.0) juno; urgency=low + * Added translation using Weblate (Finnish) [51f4546] + + -- Tuomas Lähteenmäki Thu, 7 Nov 2019 02:43:02 +0000 + +com.github.tkashkin.gamehub (0.14.2-43-dev~elementary5.0) juno; urgency=low + * Added translation using Weblate (Catalan) [68f69e9] + + -- Marc Riera Wed, 6 Nov 2019 19:18:42 +0000 + +com.github.tkashkin.gamehub (0.14.2-42-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (French) [cf641ac] + + -- Éfrit Mon, 21 Oct 2019 22:23:29 +0000 + +com.github.tkashkin.gamehub (0.14.2-41-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (French) [184c6e7] + + -- Nathan Sat, 19 Oct 2019 10:30:13 +0000 + +com.github.tkashkin.gamehub (0.14.2-40-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Arabic) [f3ea1ed] + + -- abidin toumi Fri, 18 Oct 2019 08:46:39 +0000 + +com.github.tkashkin.gamehub (0.14.2-39-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Arabic) [e851f70] + + -- abidin toumi Thu, 17 Oct 2019 06:52:42 +0000 + +com.github.tkashkin.gamehub (0.14.2-38-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Arabic) [79598e1] + + -- abidin toumi Mon, 14 Oct 2019 10:59:54 +0000 + +com.github.tkashkin.gamehub (0.14.2-37-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (French) [2c90003] + + -- Nathan Sat, 12 Oct 2019 16:37:46 +0000 + +com.github.tkashkin.gamehub (0.14.2-36-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (French) [8f7f70c] + + -- Nathan Fri, 11 Oct 2019 07:20:26 +0000 + +com.github.tkashkin.gamehub (0.14.2-35-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Indonesian) [a3a2e89] + + -- ekickx Wed, 9 Oct 2019 21:39:16 +0000 + +com.github.tkashkin.gamehub (0.14.2-34-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Norwegian Bokmål) [4693bf5] + * Translated using Weblate (Dutch) [6057099] + + -- Allan Nordhøy Thu, 3 Oct 2019 02:43:08 +0000 + +com.github.tkashkin.gamehub (0.14.2-33-dev~elementary5.0) juno; urgency=low + * Added translation using Weblate (Korean) [07f10c6] + + -- ParkSeongSoo Thu, 3 Oct 2019 11:08:26 +0000 + +com.github.tkashkin.gamehub (0.14.2-32-dev~elementary5.0) juno; urgency=low + * Performance and memory usage improvements (#57) SteamGridDB image sizes support Added menu when IGDB returns multiple results [30b9b5e] + * Image cache changes Vertical game images support [a785155] + * Translated using Weblate (German) [833d510] + + -- tkashkin Thu, 3 Oct 2019 00:54:29 +0300 + +com.github.tkashkin.gamehub (0.14.2-29-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Portuguese (Portugal)) [2a7ac4c] + + -- Manuela Silva Fri, 6 Sep 2019 10:34:38 +0000 + +com.github.tkashkin.gamehub (0.14.2-28-dev~elementary5.0) juno; urgency=low + * Added translation using Weblate (Portuguese (Portugal)) [a5403de] + * [ci skip] Fix ellipsis in string (#301) [905f530] + + -- Manuela Silva Fri, 6 Sep 2019 10:34:09 +0000 + +com.github.tkashkin.gamehub (0.14.2-27-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (French) [f02b1a6] + * Translated using Weblate (German) [a7d2474] + * [ci skip] Update translations [654105c] + + -- Swann Martinet Tue, 3 Sep 2019 03:37:33 +0000 + +com.github.tkashkin.gamehub (0.14.2-25-dev~elementary5.0) juno; urgency=low + * Added translation using Weblate (Arabic) [1a969ce] + + -- Omar Aglan Mon, 2 Sep 2019 01:18:30 +0000 + +com.github.tkashkin.gamehub (0.14.2-23-dev~elementary5.0) juno; urgency=low + * Prevent multiple game launches (#280, #281) [fcb80e5] + + -- tkashkin Sat, 31 Aug 2019 20:20:47 +0300 + +com.github.tkashkin.gamehub (0.14.2-21-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Norwegian Bokmål) [404b8bb] + + -- Allan Nordhøy Wed, 28 Aug 2019 16:50:24 +0000 + +com.github.tkashkin.gamehub (0.14.2-19-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Dutch) [3821042] + * Translated using Weblate (Portuguese (Brazil)) [27c29ff] + + -- Heimen Stoffels Wed, 21 Aug 2019 14:39:18 +0000 + +com.github.tkashkin.gamehub (0.14.2-18-dev~elementary5.0) juno; urgency=low + * Games grid size customization [8a89a89] + + -- tkashkin Wed, 21 Aug 2019 11:08:38 +0300 + +com.github.tkashkin.gamehub (0.14.2-17-dev~elementary5.0) juno; urgency=low + * Steam-like game launch command overrides (#297) Improved GOG API error handling Small UI tweaks [075168a] + + -- tkashkin Wed, 21 Aug 2019 05:55:45 +0300 + +com.github.tkashkin.gamehub (0.14.2-16-dev~elementary5.0) juno; urgency=low + * Refresh GOG access token on error (#294) [dfab162] + + -- tkashkin Tue, 13 Aug 2019 04:44:20 +0300 + +com.github.tkashkin.gamehub (0.14.2-15-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Telugu) [8e019ba] + + -- asher hrudai Sat, 10 Aug 2019 07:24:18 +0000 + +com.github.tkashkin.gamehub (0.14.2-14-dev~elementary5.0) juno; urgency=low + * Added translation using Weblate (Telugu) [5d97064] + + -- asher hrudai Sat, 10 Aug 2019 07:21:39 +0000 + +com.github.tkashkin.gamehub (0.14.2-13-dev~elementary5.0) juno; urgency=low + * Added translation using Weblate (Hindi) [f804511] + + -- asher hrudai Sat, 10 Aug 2019 07:18:28 +0000 + +com.github.tkashkin.gamehub (0.14.2-12-dev~elementary5.0) juno; urgency=low + * Fix `Game.get_file()` (#291) [eecf1db] + + -- tkashkin Sun, 4 Aug 2019 13:53:49 +0300 + +com.github.tkashkin.gamehub (0.14.2-11-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Persian) [9b67620] + + -- Goudarz Jafari Fri, 2 Aug 2019 19:39:28 +0000 + +com.github.tkashkin.gamehub (0.14.2-10-dev~elementary5.0) juno; urgency=low + * Fix overlays detection (#291) [6498058] + + -- tkashkin Fri, 2 Aug 2019 23:14:11 +0300 + +com.github.tkashkin.gamehub (0.14.2-9-dev~elementary5.0) juno; urgency=low + * Add type checks in `Proton.find_proton_versions` (#292, #101) [9b022f2] + * Translated using Weblate (Persian) [d1df472] + + -- tkashkin Fri, 2 Aug 2019 17:04:44 +0300 + +com.github.tkashkin.gamehub (0.14.2-7-dev~elementary5.0) juno; urgency=low + * Added translation using Weblate (Persian) [62adec9] + * [ci skip] Update `scripts/build.sh` [97b2775] + + -- Goudarz Jafari Fri, 2 Aug 2019 08:16:37 +0000 + +com.github.tkashkin.gamehub (0.14.2-6-dev~elementary5.0) juno; urgency=low + * Parse `appinfo.vdf` to find Proton versions (#292, #101) [788bb28] + + -- tkashkin Wed, 31 Jul 2019 13:58:40 +0300 + +com.github.tkashkin.gamehub (0.14.2-5-dev~elementary5.0) juno; urgency=low + * Add `/opt/` and `/var/opt/` to FSOverlay allowed paths list (#290) Wait for overlays to mount before updating game status (#291) [f28cc89] + * [ci skip] Update mirrors [4bb1b7f] + * [ci skip] Update source code mirrors [a1fb490] + + -- tkashkin Mon, 29 Jul 2019 19:58:36 +0300 + +com.github.tkashkin.gamehub (0.14.2-4-dev~elementary5.0) juno; urgency=low + * Merge branch 'dev' of https://hosted.weblate.org/git/gamehub/translations into dev [9548658] + * Translated using Weblate (Portuguese (Brazil)) [0ae8e38] + * Fix sort func in `GameTagsList` Improved portability: GameHub now can be built on Windows in MSYS2 environment (doesn't work yet) [acfec61] + + -- tkashkin Sun, 28 Jul 2019 14:42:12 +0300 + +com.github.tkashkin.gamehub (0.14.2-3-dev~elementary5.0) juno; urgency=low + * Fix build with older `glib` and/or without `libmanette` [42aac9c] + + -- tkashkin Fri, 26 Jul 2019 06:44:55 +0300 + +com.github.tkashkin.gamehub (0.14.2-2-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Portuguese (Brazil)) [3eda1c3] + + -- Wilker Santana da Silva Mon, 22 Jul 2019 04:52:43 +0000 + +com.github.tkashkin.gamehub (0.14.2-1-master~elementary5.0) juno; urgency=low + * [ci skip] Bump version [be55ac0] + + -- tkashkin Sat, 13 Jul 2019 21:26:50 +0300 + +com.github.tkashkin.gamehub (0.14.1-25-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Norwegian Bokmål) [526c6f8] + * Translated using Weblate (Dutch) [ad827dc] + + -- Allan Nordhøy Thu, 11 Jul 2019 22:51:43 +0000 + +com.github.tkashkin.gamehub (0.14.1-24-dev~elementary5.0) juno; urgency=low + * Game details view improvements [c77df04] + * Translated using Weblate (Chinese (Simplified)) [bece03f] + * Translated using Weblate (Norwegian Bokmål) [aed8a1a] + * Translated using Weblate (Dutch) [2462da6] + + -- tkashkin Fri, 12 Jul 2019 01:23:28 +0300 + +com.github.tkashkin.gamehub (0.14.1-23-dev~elementary5.0) juno; urgency=low + * Unset ld env variables in `Utils.run*` for AppImage builds (#267) [bd9635c] + + -- tkashkin Thu, 11 Jul 2019 03:09:29 +0300 + +com.github.tkashkin.gamehub (0.14.1-22-dev~elementary5.0) juno; urgency=low + * Add IGDB request quota warning [f9fb59c] + + -- tkashkin Thu, 11 Jul 2019 02:59:39 +0300 + +com.github.tkashkin.gamehub (0.14.1-21-dev~elementary5.0) juno; urgency=low + * Prioritize user games over installed games over uninstalled games when all sources are shown (#282) Fix some merging bugs [8ac1f27] + + -- tkashkin Wed, 10 Jul 2019 23:05:59 +0300 + +com.github.tkashkin.gamehub (0.14.1-20-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Chinese (Simplified)) [de84182] + + -- tofuHero Mon, 8 Jul 2019 01:21:06 +0000 + +com.github.tkashkin.gamehub (0.14.1-19-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Norwegian Bokmål) [aa1d50d] + * Translated using Weblate (Dutch) [8a917b4] + + -- Allan Nordhøy Sat, 6 Jul 2019 00:16:54 +0000 + +com.github.tkashkin.gamehub (0.14.1-18-dev~elementary5.0) juno; urgency=low + * Fix slashes for DOSBox data_dirs (#279) [ff9270b] + + -- tkashkin Sat, 6 Jul 2019 20:33:46 +0300 + +com.github.tkashkin.gamehub (0.14.1-17-dev~elementary5.0) juno; urgency=low + * DOSBox: verbose logging for data_dirs (#279) [2f7c584] + + -- tkashkin Sat, 6 Jul 2019 19:37:42 +0300 + +com.github.tkashkin.gamehub (0.14.1-16-dev~elementary5.0) juno; urgency=low + * Add 'Open screenshots directory' action for Steam games (#277) [8865f62] + + -- tkashkin Fri, 5 Jul 2019 20:48:47 +0300 + +com.github.tkashkin.gamehub (0.14.1-15-dev~elementary5.0) juno; urgency=low + * DOSBox improvements (#273) [c6bb7a8] + + -- tkashkin Fri, 5 Jul 2019 18:30:02 +0300 + +com.github.tkashkin.gamehub (0.14.1-14-dev~elementary5.0) juno; urgency=low + * Add timeout after exiting game to prevent immediate restart due to keypresses (#275) [5dc13a8] + + -- tkashkin Thu, 4 Jul 2019 23:47:41 +0300 + +com.github.tkashkin.gamehub (0.14.1-13-dev~elementary5.0) juno; urgency=low + * Add DOS exe/bat/com support to DOSBox CompatTool (#273) Reorder CompatTools Clear IGDB data cache for game when games is renamed (#274) [b286d46] + + -- tkashkin Thu, 4 Jul 2019 22:59:22 +0300 + +com.github.tkashkin.gamehub (0.14.1-12-dev~elementary5.0) juno; urgency=low + * Allow to run executables in DOSBox without configs (#273) [e4b9623] + + -- tkashkin Thu, 4 Jul 2019 20:16:20 +0300 + +com.github.tkashkin.gamehub (0.14.1-11-dev~elementary5.0) juno; urgency=low + * Fix Humble authentication page styles (#272) [2b9cb90] + + -- tkashkin Thu, 4 Jul 2019 12:12:42 +0300 + +com.github.tkashkin.gamehub (0.14.1-10-dev~elementary5.0) juno; urgency=low + * Fix build with newer Vala compiler (#271) [9d0ff03] + + -- tkashkin Wed, 3 Jul 2019 20:25:44 +0300 + +com.github.tkashkin.gamehub (0.14.1-9-dev~elementary5.0) juno; urgency=low + * Fix segfault in `GameListRow.update_style` (#255) [34b0109] + + -- tkashkin Tue, 2 Jul 2019 23:06:46 +0300 + +com.github.tkashkin.gamehub (0.14.1-8-dev~elementary5.0) juno; urgency=low + * Reduce games list paddings (#265) [5c2fccf] + * Translated using Weblate (Norwegian Bokmål) [c199c12] + * Translated using Weblate (Dutch) [26a6755] + + -- tkashkin Mon, 1 Jul 2019 10:51:09 +0300 + +com.github.tkashkin.gamehub (0.14.1-6-dev~elementary5.0) juno; urgency=low + * Merge translations [15a67ea] + * Games list grouping options (#265) [5572bc1] + * Translated using Weblate (Chinese (Simplified)) [bf75533] + * Translated using Weblate (Norwegian Bokmål) [164b834] + * Translated using Weblate (Dutch) [4c7b155] + + -- tkashkin Sun, 30 Jun 2019 17:30:25 +0300 + +com.github.tkashkin.gamehub (0.14.1-4-dev~elementary5.0) juno; urgency=low + * Additional games list style options (#265) [e1292ae] + + -- tkashkin Sat, 29 Jun 2019 04:09:28 +0300 + +com.github.tkashkin.gamehub (0.14.1-3-dev~elementary5.0) juno; urgency=low + * Tags can be removed (#266) Fix tags toggling (#268) [fa3012a] + + -- tkashkin Fri, 28 Jun 2019 23:49:19 +0300 + +com.github.tkashkin.gamehub (0.14.1-2-master~elementary5.0) juno; urgency=low + * Fix segfault when installing/downloading multiple games [a82e30a] + + -- Anatoliy Kashkin Thu, 27 Jun 2019 22:31:05 +0300 + +com.github.tkashkin.gamehub (0.14.1-1-master~elementary5.0) juno; urgency=low + * [ci skip] Bump version to 0.14.1 [dbb655c] + + -- tkashkin Thu, 27 Jun 2019 20:51:51 +0300 + +com.github.tkashkin.gamehub (0.14.0-42-dev~elementary5.0) juno; urgency=low + * Remove `granite` dependency [e7bffdf] + * FS overlays can now be removed/disabled (#120, #254) `GameFSOverlaysDialog` will now show warning or error depending on game's `install_dir` (#254) [c7ddab0] + + -- tkashkin Thu, 27 Jun 2019 19:37:14 +0300 + +com.github.tkashkin.gamehub (0.14.0-40-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Norwegian Bokmål) [d78eab3] + * Translated using Weblate (Dutch) [5353619] + + -- Allan Nordhøy Tue, 25 Jun 2019 16:39:27 +0000 + +com.github.tkashkin.gamehub (0.14.0-39-dev~elementary5.0) juno; urgency=low + * Added translation using Weblate (Greek) [371a9c9] + + -- THANOS SIOURDAKIS Tue, 25 Jun 2019 19:32:45 +0000 + +com.github.tkashkin.gamehub (0.14.0-38-dev~elementary5.0) juno; urgency=low + * Allow multiple selection in games list Add actions for selected games (#262) Batch tag editing for selected games [f88b0a4] + * Translated using Weblate (Norwegian Bokmål) [e1d59d3] + * Translated using Weblate (Norwegian Bokmål) [78f5793] + * Translated using Weblate (Dutch) [ad15bf6] + + -- tkashkin Tue, 25 Jun 2019 15:57:09 +0300 + +com.github.tkashkin.gamehub (0.14.0-35-dev~elementary5.0) juno; urgency=low + * Add configurable blacklists for libretro cores and game file extensions (#103) [2729433] + + -- tkashkin Sun, 23 Jun 2019 07:50:57 +0300 + +com.github.tkashkin.gamehub (0.14.0-34-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Norwegian Bokmål) [63cbf1b] + + -- Allan Nordhøy Sat, 22 Jun 2019 01:19:26 +0000 + +com.github.tkashkin.gamehub (0.14.0-33-dev~elementary5.0) juno; urgency=low + * Games merging tweaks Update Humble Trove parsing (#32) [480c20f] + + -- tkashkin Sat, 22 Jun 2019 07:11:51 +0300 + +com.github.tkashkin.gamehub (0.14.0-32-dev~elementary5.0) juno; urgency=low + * Fix trying to get nonexistent platform from Steam game info Show default icons for games in list and details [603316b] + + -- tkashkin Sat, 22 Jun 2019 04:50:10 +0300 + +com.github.tkashkin.gamehub (0.14.0-31-dev~elementary5.0) juno; urgency=low + * Merge branch 'dev' of github.com:tkashkin/GameHub into dev [b19073e] + * Only match files when importing emulated games (#258) Do not try to show merged games when merging is disabled (#259) [b126539] + * Translated using Weblate (Dutch) [4f34efd] + + -- tkashkin Fri, 21 Jun 2019 23:52:14 +0300 + +com.github.tkashkin.gamehub (0.14.0-29-dev~elementary5.0) juno; urgency=low + * Allow to skip WelcomeView when no sources are setup (#257) [4f32825] + + -- tkashkin Fri, 21 Jun 2019 01:38:55 +0300 + +com.github.tkashkin.gamehub (0.14.0-28-dev~elementary5.0) juno; urgency=low + * Add `Emulated` as a separate platform (#103) Improved image scaling Fix images downloader popup being cut off in some cases (#249) [1543581] + * Translated using Weblate (Portuguese (Brazil)) [1288cc9] + + -- tkashkin Fri, 21 Jun 2019 00:14:30 +0300 + +com.github.tkashkin.gamehub (0.14.0-26-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (French) [19ed4a5] + * Translated using Weblate (Portuguese (Brazil)) [aa824d1] + + -- Anatoliy Kashkin Wed, 19 Jun 2019 23:40:49 +0000 + +com.github.tkashkin.gamehub (0.14.0-25-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Dutch) [ce65666] + + -- Heimen Stoffels Tue, 18 Jun 2019 10:29:42 +0000 + +com.github.tkashkin.gamehub (0.14.0-24-dev~elementary5.0) juno; urgency=low + * Added translation using Weblate (Chinese (Traditional)) [da8a821] + + -- Jeff Huang Tue, 18 Jun 2019 04:28:47 +0000 + +com.github.tkashkin.gamehub (0.14.0-23-dev~elementary5.0) juno; urgency=low + * Maybe fix #255 Add log filtering to hide useless debug messages [2713b16] + + -- tkashkin Tue, 18 Jun 2019 05:40:23 +0300 + +com.github.tkashkin.gamehub (0.14.0-22-dev~elementary5.0) juno; urgency=low + * UI tweaks [42d2657] + + -- tkashkin Tue, 18 Jun 2019 03:19:52 +0300 + +com.github.tkashkin.gamehub (0.14.0-21-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Norwegian Bokmål) [ec093ed] + * Translated using Weblate (Dutch) [e8607ba] + + -- Allan Nordhøy Mon, 17 Jun 2019 07:30:09 +0000 + +com.github.tkashkin.gamehub (0.14.0-20-dev~elementary5.0) juno; urgency=low + * Try to also match primary game platforms (#247) [74da09f] + + -- tkashkin Mon, 17 Jun 2019 02:20:11 +0300 + +com.github.tkashkin.gamehub (0.14.0-19-dev~elementary5.0) juno; urgency=low + * `dconf` settings rework Theme-based icon style Filter games by platform [0f1c47b] + + -- tkashkin Mon, 17 Jun 2019 01:05:48 +0300 + +com.github.tkashkin.gamehub (0.14.0-18-dev~elementary5.0) juno; urgency=low + * Update dput.cf [99e2a70] + * List all platforms for merged games when source is not filtered (#247) Show submenus for merged games in `GameContextMenu` [2c240b9] + * Fix dependency installation prompts in build script [adc63ca] + * `GamePropertiesDialog` tweaks Update `GameCard` and `GameListRow` when filtered source changes (#247) [69132ad] + * Fix SteamGridDB authentication (#249) IGDB description visibility settings [530e231] + * Translated using Weblate (Norwegian Bokmål) [443a90b] + * Translated using Weblate (Dutch) [d39b3e3] + * Translated using Weblate (Norwegian Bokmål) [173ebcc] + * Translated using Weblate (Norwegian Bokmål) [6b09afb] + + -- tkashkin Sun, 16 Jun 2019 06:39:31 +0300 + +com.github.tkashkin.gamehub (0.14.0-11-dev~elementary5.0) juno; urgency=low + * Merge branch 'dev' of github.com:tkashkin/GameHub into dev [164e55c] + * IGDB integration [9f1d67c] + * Translated using Weblate (Norwegian Bokmål) [3f9c5dd] + * Translated using Weblate (Dutch) [362a848] + * Translated using Weblate (Portuguese (Brazil)) [2313120] + + -- tkashkin Fri, 14 Jun 2019 00:10:49 +0300 + +com.github.tkashkin.gamehub (0.14.0-9-dev~elementary5.0) juno; urgency=low + * Simplified `ImportEmulatedGamesDialog` (#103) Images and icon patterns for custom emulators Added button to download all missing images for games Added data providers page to settings [e4486e7] + + -- tkashkin Thu, 13 Jun 2019 03:45:27 +0300 + +com.github.tkashkin.gamehub (0.14.0-8-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Norwegian Bokmål) [b100729] + * Translated using Weblate (Norwegian Bokmål) [a535e9d] + * Translated using Weblate (Norwegian Bokmål) [bfa122c] + + -- Anatoliy Kashkin Wed, 12 Jun 2019 15:29:43 +0000 + +com.github.tkashkin.gamehub (0.14.0-6-dev~elementary5.0) juno; urgency=low + * Add game images providers [66e085e] + + -- tkashkin Wed, 12 Jun 2019 02:52:06 +0300 + +com.github.tkashkin.gamehub (0.14.0-5-dev~elementary5.0) juno; urgency=low + * `ImportEmulatedGamesDialog` tweaks (#103) [843d4d2] + + -- tkashkin Mon, 10 Jun 2019 19:40:38 +0300 + +com.github.tkashkin.gamehub (0.14.0-4-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Dutch) [52186ff] + + -- Heimen Stoffels Sun, 9 Jun 2019 09:55:40 +0000 + +com.github.tkashkin.gamehub (0.14.0-3-dev~elementary5.0) juno; urgency=low + * Add emulated games scanning (#103) [f5b3ad0] + * Translated using Weblate (German) [9e366e0] + + -- tkashkin Sun, 9 Jun 2019 11:10:49 +0300 + +com.github.tkashkin.gamehub (0.14.0-2-master~elementary5.0) juno; urgency=low + * Fix Utils.get_language_name [96029f0] + + -- tkashkin Sat, 8 Jun 2019 03:42:44 +0300 + +com.github.tkashkin.gamehub (0.14.0-1-master~elementary5.0) juno; urgency=low + * Release 0.14.0 [6343d16] + * [ci skip] Update AppStream data [72d1b55] + * [ci skip] Bump version to 0.14.0 Update README.md Update screenshots [ff8ed17] + * Merge branch 'master' of github.com:tkashkin/GameHub [1f713f3] + * [ci skip] Merge pull request #172 from friday/issue-templates [fab595b] + * Create git issue templates [600652a] + * [ci skip] Update README.md [a242568] + * Merge `dev` into `master` [cd4ff2c] + + -- tkashkin Sat, 8 Jun 2019 02:58:02 +0300 + +com.github.tkashkin.gamehub (0.13.1-115-dev~elementary5.0) juno; urgency=low + * Disable `libunity` by default, enable with `-Duse_libunity=true` [31eb28a] + * Remove `libunity-dev` from build script [ad8bc0f] + * Remove `libunity-dev` from debian dependencies [5cc0ae7] + * Translated using Weblate (Chinese (Simplified)) [0d8bea6] + * Translated using Weblate (Chinese (Simplified)) [21d8a01] + * Translated using Weblate (Polish) [39f6735] + * Added translation using Weblate (Chinese (Simplified)) [d17ad07] + + -- tkashkin Fri, 7 Jun 2019 20:03:02 +0300 + +com.github.tkashkin.gamehub (0.13.1-109-dev~elementary5.0) juno; urgency=low + * Fix crash in SoupDownloader.await_queue() (#220) [9024fef] + + -- tkashkin Mon, 3 Jun 2019 21:23:12 +0300 + +com.github.tkashkin.gamehub (0.13.1-108-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Norwegian Bokmål) [d04ad42] + * Translated using Weblate (Dutch) [583c98c] + + -- Allan Nordhøy Sun, 2 Jun 2019 23:51:33 +0000 + +com.github.tkashkin.gamehub (0.13.1-107-dev~elementary5.0) juno; urgency=low + * Queue installer downloads (#220) [87c7f3d] + * Settings dialog improvements Controller exit shortcut (#75) Ignored controllers option [f05d464] + * Translated using Weblate (German) [aa0c1c4] + + -- tkashkin Mon, 3 Jun 2019 02:35:31 +0300 + +com.github.tkashkin.gamehub (0.13.1-103-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Norwegian Bokmål) [cd2da98] + * Translated using Weblate (Dutch) [67bfd23] + + -- Allan Nordhøy Tue, 28 May 2019 12:18:45 +0000 + +com.github.tkashkin.gamehub (0.13.1-102-dev~elementary5.0) juno; urgency=low + * Settings dialog redesign [bc53e7c] + + -- tkashkin Tue, 28 May 2019 14:48:58 +0300 + +com.github.tkashkin.gamehub (0.13.1-101-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Norwegian Bokmål) [0a3db13] + * Translated using Weblate (Dutch) [0dad19a] + * Translated using Weblate (German) [416198f] + + -- Allan Nordhøy Sun, 26 May 2019 22:05:21 +0000 + +com.github.tkashkin.gamehub (0.13.1-100-dev~elementary5.0) juno; urgency=low + * Fix flatpak libs [3b52419] + + -- tkashkin Sat, 25 May 2019 10:07:35 +0300 + +com.github.tkashkin.gamehub (0.13.1-99-dev~elementary5.0) juno; urgency=low + * Fix Humble collection directory name (#244) Bundle more libs for flatpak [4138055] + * Merge branch 'origin/dev' into Weblate. [201ce95] + * Translated using Weblate (Norwegian Bokmål) [723f43b] + * Translated using Weblate (Dutch) [dd634ba] + + -- tkashkin Sat, 25 May 2019 09:42:08 +0300 + +com.github.tkashkin.gamehub (0.13.1-97-dev~elementary5.0) juno; urgency=low + * Add $platform and $platform_name variables for Collection (#244) [44ba7b8] + + -- tkashkin Sat, 25 May 2019 02:43:12 +0300 + +com.github.tkashkin.gamehub (0.13.1-96-dev~elementary5.0) juno; urgency=low + * Bundle libmanette snapshot for flatpak [e08606c] + + -- tkashkin Fri, 24 May 2019 05:25:13 +0300 + +com.github.tkashkin.gamehub (0.13.1-95-dev~elementary5.0) juno; urgency=low + * Bundle libmanette snapshot for flatpak because remote downloads on AppVeyor are unreliable [d7b7fdc] + * In-memory image cache CLI option to restart app with gdb and G_DEBUG=fatal-criticals [6090578] + + -- tkashkin Fri, 24 May 2019 05:11:20 +0300 + +com.github.tkashkin.gamehub (0.13.1-92-dev~elementary5.0) juno; urgency=low + * Fix AppVeyor artifacts upload [b8b527e] + * Set more Wine-related env variables (#242) Don't try to init Proton prefix if it's already initialized [202e4d2] + * Fix build script [93ba8e1] + * Fix libmanette for flatpak [0062a8b] + * Build launchpad source packages for multiple distros [a40fd62] + * Build launchpad source packages for multiple distros [5cd101e] + + -- tkashkin Sun, 5 May 2019 18:43:06 +0300 + +com.github.tkashkin.gamehub (0.13.1-85-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (German) [3081514] + + -- ssantos Thu, 18 Apr 2019 18:12:16 +0000 + +com.github.tkashkin.gamehub (0.13.1-84-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (German) [488ff43] + + -- CurlingTongs Wed, 17 Apr 2019 00:32:48 +0000 + +com.github.tkashkin.gamehub (0.13.1-83-dev~elementary5.0) juno; urgency=low + * Fix launchpad build script Add icon to .appdata.xml [5e849c0] + + -- tkashkin Tue, 16 Apr 2019 16:26:25 +0300 + +com.github.tkashkin.gamehub (0.13.1-82-dev~elementary5.0) juno; urgency=low + * Fix running Game.update_game_info() multiple times in threads (#237) [7a4f9e1] + + -- tkashkin Sun, 14 Apr 2019 11:48:10 +0300 + +com.github.tkashkin.gamehub (0.13.1-81-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (German) [79de66d] + + -- ssantos Sat, 13 Apr 2019 21:58:23 +0000 + +com.github.tkashkin.gamehub (0.13.1-80-dev~elementary5.0) juno; urgency=low + * Revert: Attempt to add game views in batches instead of all at once (#57) [c6994ef] + * Fix AutoSizeImage scaling Fix Games DB cache threaded crashes Attempt to add game views in batches instead of all at once (#57) [cac6092] + + -- tkashkin Thu, 11 Apr 2019 12:47:53 +0300 + +com.github.tkashkin.gamehub (0.13.1-77-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Norwegian Bokmål) [3b27e88] + * Translated using Weblate (Dutch) [e11b410] + + -- Anatoliy Kashkin Wed, 10 Apr 2019 22:17:35 +0000 + +com.github.tkashkin.gamehub (0.13.1-76-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Norwegian Bokmål) [4179176] + + -- Allan Nordhøy Wed, 10 Apr 2019 09:57:56 +0000 + +com.github.tkashkin.gamehub (0.13.1-75-dev~elementary5.0) juno; urgency=low + * Merge branch 'origin/dev' into Weblate. [d3ec7c7] + * Translated using Weblate (Dutch) [c45ba0f] + + -- Hosted Weblate Wed, 10 Apr 2019 11:19:44 +0200 + +com.github.tkashkin.gamehub (0.13.1-74-dev~elementary5.0) juno; urgency=low + * Make libunity optional Improve AutoSizeImage resizing Reimplement status indicator [07806a8] + + -- tkashkin Wed, 10 Apr 2019 12:19:35 +0300 + +com.github.tkashkin.gamehub (0.13.1-73-dev~elementary5.0) juno; urgency=low + * Update launcher menu in GamesAdapter [642e452] + + -- tkashkin Tue, 9 Apr 2019 17:18:15 +0300 + +com.github.tkashkin.gamehub (0.13.1-72-dev~elementary5.0) juno; urgency=low + * Merge branch 'origin/dev' into Weblate. [f32037e] + * Translated using Weblate (Norwegian Bokmål) [60a0416] + * Translated using Weblate (German) [af70e10] + * Translated using Weblate (Dutch) [ad3ecc9] + * Add config button to CompatToolPicker [3ac3d07] + + -- Hosted Weblate Tue, 9 Apr 2019 16:00:14 +0200 + +com.github.tkashkin.gamehub (0.13.1-70-dev~elementary5.0) juno; urgency=low + * Merge branch 'dev' of github.com:tkashkin/GameHub into dev [a0d7c1a] + * GamesView refactoring (#57) [d5cb0e5] + * [ci skip] Add new Game subcategory to desktop file (#233) [9d02815] + + -- tkashkin Tue, 9 Apr 2019 16:00:55 +0300 + +com.github.tkashkin.gamehub (0.13.1-69-dev~elementary5.0) juno; urgency=low + * Improved Steam client integration [20047cc] + + -- tkashkin Mon, 8 Apr 2019 10:17:39 +0300 + +com.github.tkashkin.gamehub (0.13.1-68-dev~elementary5.0) juno; urgency=low + * Add controller settings (#122) [3628f0b] + + -- tkashkin Mon, 8 Apr 2019 07:52:07 +0300 + +com.github.tkashkin.gamehub (0.13.1-67-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (German) [d18ad6b] + + -- ssantos Sun, 7 Apr 2019 06:18:02 +0000 + +com.github.tkashkin.gamehub (0.13.1-66-dev~elementary5.0) juno; urgency=low + * Fix GOG install segfault (#232) [abc24ad] + + -- tkashkin Wed, 3 Apr 2019 14:30:44 +0300 + +com.github.tkashkin.gamehub (0.13.1-65-dev~elementary5.0) juno; urgency=low + * Fix GOG games installers parsing (#57) [cbac777] + + -- tkashkin Wed, 3 Apr 2019 12:03:17 +0300 + +com.github.tkashkin.gamehub (0.13.1-64-dev~elementary5.0) juno; urgency=low + * Add default game icon (#204) [2334f9b] + + -- tkashkin Wed, 3 Apr 2019 10:11:30 +0300 + +com.github.tkashkin.gamehub (0.13.1-63-dev~elementary5.0) juno; urgency=low + * Non-shallow git clone for AppVeyor [2541409] + * Fix build script [9be335f] + + -- tkashkin Wed, 3 Apr 2019 08:16:38 +0300 + +com.github.tkashkin.gamehub (0.13.1-61-dev~elementary5.0) juno; urgency=low + * Fix changelogs for flatpak [422ab93] + + -- tkashkin Wed, 3 Apr 2019 07:39:57 +0300 + +com.github.tkashkin.gamehub (0.13.1-60-dev~elementary5.0) juno; urgency=low + * Set git user for AppVeyor [1176725] + * Fix build script [bd542e3] + * Generate changelogs automatically from git commits [517a32a] + + -- tkashkin Wed, 3 Apr 2019 07:14:39 +0300 + +com.github.tkashkin.gamehub (0.13.1-57-dev~elementary5.0) juno; urgency=low + * Fix appstream data [f89dc4b] + + -- tkashkin Tue, 2 Apr 2019 15:10:01 +0300 + +com.github.tkashkin.gamehub (0.13.1-54-dev~elementary5.0) juno; urgency=low + * Fix libunity dependency for flatpak [5741f06] + + -- tkashkin Tue, 2 Apr 2019 14:41:09 +0300 + +com.github.tkashkin.gamehub (0.13.1-53-dev~elementary5.0) juno; urgency=low + * More null checks for GOG player stats (#228) [1acb171] + + -- tkashkin Sun, 31 Mar 2019 21:30:37 +0300 + +com.github.tkashkin.gamehub (0.13.1-52-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Norwegian Bokmål) [5cd0e94] + * Translated using Weblate (Dutch) [81a9fa1] + + -- Allan Nordhøy Sun, 31 Mar 2019 10:26:40 +0000 + +com.github.tkashkin.gamehub (0.13.1-51-dev~elementary5.0) juno; urgency=low + * Merge branch 'dev' of github.com:tkashkin/GameHub into dev [0f1c862] + * [ci skip] Update issue templates (#212) [701f14e] + + -- tkashkin Sat, 30 Mar 2019 23:47:17 +0300 + +com.github.tkashkin.gamehub (0.13.1-50-dev~elementary5.0) juno; urgency=low + * Merge branch 'origin/dev' into Weblate. [30fb590] + * Translated using Weblate (Turkish) [23377e7] + * About dialog (#212) [069613e] + + -- Hosted Weblate Sat, 30 Mar 2019 21:30:24 +0100 + +com.github.tkashkin.gamehub (0.13.1-48-dev~elementary5.0) juno; urgency=low + * Use case-insensitive paths for Steam (#227) [f6b77e8] + + -- tkashkin Fri, 29 Mar 2019 18:12:25 +0300 + +com.github.tkashkin.gamehub (0.13.1-47-dev~elementary5.0) juno; urgency=low + * Implement libunity quicklist and progress (#225) [3084beb] + * Allow multiple merged games from same source (#224) [8ccd0ca] + + -- tkashkin Fri, 29 Mar 2019 03:57:19 +0300 + +com.github.tkashkin.gamehub (0.13.1-45-dev~elementary5.0) juno; urgency=low + * Enter to run first matching game in search (#223) [f9fd217] + + -- tkashkin Thu, 28 Mar 2019 22:13:38 +0300 + +com.github.tkashkin.gamehub (0.13.1-44-dev~elementary5.0) juno; urgency=low + * GAction-based hotkeys [5bf5bdd] + + -- tkashkin Thu, 28 Mar 2019 20:57:47 +0300 + +com.github.tkashkin.gamehub (0.13.1-43-dev~elementary5.0) juno; urgency=low + * Fix .gameinfo-background background-color for Pop!_OS GTK theme [974067a] + + -- tkashkin Thu, 28 Mar 2019 04:07:53 +0300 + +com.github.tkashkin.gamehub (0.13.1-42-dev~elementary5.0) juno; urgency=low + * Add "Proton (latest)" to compat tools list (#222) [5f7bd3b] + + -- tkashkin Wed, 27 Mar 2019 17:14:55 +0300 + +com.github.tkashkin.gamehub (0.13.1-41-dev~elementary5.0) juno; urgency=low + * Merge pull request #221 from Lucki/patch-1 [ade4818] + * Add Proton 4.2 [837530a] + + -- Anatoliy Kashkin Wed, 27 Mar 2019 02:28:05 +0300 + +com.github.tkashkin.gamehub (0.13.1-40-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Norwegian Bokmål) [592ba39] + * Translated using Weblate (German) [9f33b47] + * Translated using Weblate (Dutch) [059e6c5] + + -- Allan Nordhøy Sat, 23 Mar 2019 01:20:27 +0000 + +com.github.tkashkin.gamehub (0.13.1-39-dev~elementary5.0) juno; urgency=low + * Fix long titles in games grid (#219) [41668e6] + + -- tkashkin Sun, 24 Mar 2019 22:54:05 +0300 + +com.github.tkashkin.gamehub (0.13.1-38-dev~elementary5.0) juno; urgency=low + * Fix FSUtils.mv_up() to allow directories merging (#216) [bec8757] + + -- tkashkin Sun, 24 Mar 2019 17:02:27 +0300 + +com.github.tkashkin.gamehub (0.13.1-37-dev~elementary5.0) juno; urgency=low + * Add option to run games with double click (#213) [41d8c8f] + + -- tkashkin Fri, 22 Mar 2019 23:25:20 +0300 + +com.github.tkashkin.gamehub (0.13.1-36-dev~elementary5.0) juno; urgency=low + * Bump minimal innoextract version to 1.8 (#208) [169dc6e] + + -- tkashkin Fri, 22 Mar 2019 22:19:36 +0300 + +com.github.tkashkin.gamehub (0.13.1-35-dev~elementary5.0) juno; urgency=low + * Fix `is_game_merged` db query (#210, #211) [db1b38a] + + -- tkashkin Fri, 22 Mar 2019 19:04:16 +0300 + +com.github.tkashkin.gamehub (0.13.1-34-dev~elementary5.0) juno; urgency=low + * Merge pull request #205 from Lucki/patch-1 [e1d8f5c] + * Make overlays remountable [f0b0044] + + -- Anatoliy Kashkin Tue, 12 Mar 2019 01:04:23 +0300 + +com.github.tkashkin.gamehub (0.13.1-33-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Norwegian Bokmål) [efc9541] + + -- Allan Nordhøy Thu, 7 Mar 2019 11:04:32 +0000 + +com.github.tkashkin.gamehub (0.13.1-32-dev~elementary5.0) juno; urgency=low + * Added translation using Weblate (Turkish) [e4c792a] + + -- Kemal Oktay Aktoğan Fri, 8 Mar 2019 09:06:00 +0000 + +com.github.tkashkin.gamehub (0.13.1-31-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Norwegian Bokmål) [ac109bf] + + -- Allan Nordhøy Sun, 24 Feb 2019 02:28:40 +0000 + +com.github.tkashkin.gamehub (0.13.1-30-dev~elementary5.0) juno; urgency=low + * Merge pull request #200 from spinozaure/flatpak-fixes [f6eb643] + * Change 32bit library path for flatpak [269393c] + + -- Anatoliy Kashkin Mon, 18 Feb 2019 22:07:12 +0300 + +com.github.tkashkin.gamehub (0.13.1-29-dev~elementary5.0) juno; urgency=low + * Move app/__support/app to game's install_dir for innoextract (#197) [cd84abf] + + -- tkashkin Fri, 15 Feb 2019 14:59:00 +0300 + +com.github.tkashkin.gamehub (0.13.1-28-dev~elementary5.0) juno; urgency=low + * Change Steam packages check for elementary (#199) [3254279] + + -- tkashkin Thu, 14 Feb 2019 17:37:30 +0300 + +com.github.tkashkin.gamehub (0.13.1-27-dev~elementary5.0) juno; urgency=low + * FSUtils.mv_up() dir existence check [d48c261] + + -- tkashkin Thu, 14 Feb 2019 11:10:57 +0300 + +com.github.tkashkin.gamehub (0.13.1-26-dev~elementary5.0) juno; urgency=low + * Quickfix for #197 (#198) [e558a6b] + + -- neuromancer Thu, 14 Feb 2019 05:05:43 -0300 + +com.github.tkashkin.gamehub (0.13.1-25-dev~elementary5.0) juno; urgency=low + * Fix GOG Windows game actions parsing if FSOverlays are enabled (#120) [678b18e] + + -- tkashkin Wed, 13 Feb 2019 22:35:32 +0300 + +com.github.tkashkin.gamehub (0.13.1-24-dev~elementary5.0) juno; urgency=low + * Move game files from _gamehub_{game|app}_root for InnoSetup games installed with Wine/Proton (#192) [bee3890] + + -- tkashkin Tue, 12 Feb 2019 13:32:10 +0300 + +com.github.tkashkin.gamehub (0.13.1-23-dev~elementary5.0) juno; urgency=low + * FileChooserEntry.set_default_directory (#182) UI tweaks [3b43850] + + -- tkashkin Tue, 12 Feb 2019 12:53:01 +0300 + +com.github.tkashkin.gamehub (0.13.1-22-dev~elementary5.0) juno; urgency=low + * Update LINGUAS [a0af8c9] + * Translated using Weblate (French) [0ef1423] + * Deleted translation using Weblate (French) [2e8457e] + + -- Anatoliy Kashkin Mon, 11 Feb 2019 17:13:03 +0300 + +com.github.tkashkin.gamehub (0.13.1-20-dev~elementary5.0) juno; urgency=low + * Added translation using Weblate (French) [4ecf8bf] + + -- King Claudy Mon, 11 Feb 2019 10:18:51 +0000 + +com.github.tkashkin.gamehub (0.13.1-19-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (German) [360dd70] + + -- ssantos Fri, 8 Feb 2019 13:42:08 +0000 + +com.github.tkashkin.gamehub (0.13.1-18-dev~elementary5.0) juno; urgency=low + * Fix game args parsing (#194) [eef7ba5] + + -- tkashkin Wed, 6 Feb 2019 23:05:05 +0300 + +com.github.tkashkin.gamehub (0.13.1-17-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Dutch) [bf41a58] + + -- Anatoliy Kashkin Tue, 5 Feb 2019 20:27:46 +0000 + +com.github.tkashkin.gamehub (0.13.1-16-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Dutch) [b749939] + + -- Heimen Stoffels Tue, 5 Feb 2019 12:28:59 +0000 + +com.github.tkashkin.gamehub (0.13.1-15-dev~elementary5.0) juno; urgency=low + * Fix broken AppVeyor build by installing fakeroot in build script explicitly [0f0167e] + * Remove max_width_chars for compat tool warnings [b098dee] + * Warn user if the innoextract is not up-to-date (#193) [68f4a5f] + + -- tkashkin Tue, 5 Feb 2019 06:43:26 +0300 + +com.github.tkashkin.gamehub (0.13.1-12-dev~elementary5.0) juno; urgency=low + * Small fixes GOG DLC UI improvements [ea5cc72] + + -- tkashkin Mon, 4 Feb 2019 13:30:52 +0300 + +com.github.tkashkin.gamehub (0.13.1-11-dev~elementary5.0) juno; urgency=low + * Remember GOG bonus content filenames Improve GOG bonus content UI [d44618d] + + -- tkashkin Mon, 4 Feb 2019 11:49:16 +0300 + +com.github.tkashkin.gamehub (0.13.1-10-dev~elementary5.0) juno; urgency=low + * Small UI fixes [0abbc80] + + -- tkashkin Mon, 4 Feb 2019 10:32:29 +0300 + +com.github.tkashkin.gamehub (0.13.1-9-dev~elementary5.0) juno; urgency=low + * Expand `~` in FileChooserEntry [85d1268] + * Fix #190 [fe36384] + * Merge branch 'dev' of github.com:tkashkin/GameHub into dev [cae97d1] + * Translated using Weblate (German) [d7ef194] + * Merge branch 'dev' of github.com:tkashkin/GameHub into dev [ef0d8e5] + * Merge branch 'master' into dev [cd7e38c] + * Merge `dev` into `master` [72b076b] + * [ci skip] Merge dev into master [3fe313b] + + -- tkashkin Mon, 4 Feb 2019 09:13:10 +0300 + +com.github.tkashkin.gamehub (0.13.1-5-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Polish) [b55aeb8] + * Translated using Weblate (Polish) [4ec002d] + + -- Anatoliy Kashkin Mon, 4 Feb 2019 02:39:45 +0000 + +com.github.tkashkin.gamehub (0.13.1-2-dev~elementary5.0) juno; urgency=low + * Added translation using Weblate (Polish) [a7225b5] + + -- AngryPenguinPL Mon, 4 Feb 2019 00:20:58 +0000 + +com.github.tkashkin.gamehub (0.13.1-1-master~elementary5.0) juno; urgency=low + * Merge branch 'master' of github.com:tkashkin/GameHub [1f713f3] + * Merge branch 'master' into dev [cd7e38c] + * [ci skip] Prepare 0.13.1 [03fdbe5] + * Translated using Weblate (German) [512af52] + * [ci skip] Merge pull request #172 from friday/issue-templates [fab595b] + * Create git issue templates [600652a] + * [ci skip] Update README.md [a242568] + * Merge `dev` into `master` [cd4ff2c] + * Merge `dev` into `master` [72b076b] + * [ci skip] Merge dev into master [3fe313b] + + -- tkashkin Mon, 28 Jan 2019 19:30:30 +0300 + +com.github.tkashkin.gamehub (0.13.0-19-dev~elementary5.0) juno; urgency=low + * Fix controller button hints for accented headerbar on elementary (#170) [cdf4a0f] + + -- tkashkin Wed, 23 Jan 2019 20:09:33 +0300 + +com.github.tkashkin.gamehub (0.13.0-18-dev~elementary5.0) juno; urgency=low + * Merge branch 'origin/dev' into Weblate. [7dc1619] + * Translated using Weblate (German) [ec198b7] + * Possibly fix Humble token escaping (#32, #9) [3dd7dbe] + + -- Hosted Weblate Wed, 23 Jan 2019 15:02:19 +0100 + +com.github.tkashkin.gamehub (0.13.0-16-dev~elementary5.0) juno; urgency=low + * Fix welcome screen flat titlebar text/buttons color (#170) [c975c2a] + + -- tkashkin Wed, 23 Jan 2019 05:33:37 +0300 + +com.github.tkashkin.gamehub (0.13.0-15-dev~elementary5.0) juno; urgency=low + * Add primary color for elementary theme (#170) More verbose logging for Humble Trove with `--verbose` option (#32) [3c67adf] + + -- tkashkin Wed, 23 Jan 2019 05:08:53 +0300 + +com.github.tkashkin.gamehub (0.13.0-14-dev~elementary5.0) juno; urgency=low + * Update icon (#170) Add purple accent color Fix compat regression with previous commit [e380a84] + + -- tkashkin Wed, 23 Jan 2019 00:33:58 +0300 + +com.github.tkashkin.gamehub (0.13.0-13-dev~elementary5.0) juno; urgency=low + * Probably fix install_dir after uninstalling and changing games directory (#111) Fix some games not saving in database after 352ba23 [4c53b00] + + -- tkashkin Tue, 22 Jan 2019 19:26:01 +0300 + +com.github.tkashkin.gamehub (0.13.0-12-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Norwegian Bokmål) [5e3d6f0] + * Translated using Weblate (Dutch) [4134253] + + -- Allan Nordhøy Sun, 20 Jan 2019 20:08:46 +0000 + +com.github.tkashkin.gamehub (0.13.0-11-dev~elementary5.0) juno; urgency=low + * Remove Steam Runtime libraries since they are not used (#181) [4011083] + + -- tkashkin Sun, 20 Jan 2019 22:41:05 +0300 + +com.github.tkashkin.gamehub (0.13.0-10-dev~elementary5.0) juno; urgency=low + * Add a warning if games directory contains space (#111) [07068e5] + + -- tkashkin Sun, 20 Jan 2019 22:38:50 +0300 + +com.github.tkashkin.gamehub (0.13.0-9-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Dutch) [7ef671b] + + -- Heimen Stoffels Sun, 20 Jan 2019 11:13:57 +0000 + +com.github.tkashkin.gamehub (0.13.0-8-dev~elementary5.0) juno; urgency=low + * Merge branch 'origin/dev' into Weblate. [1760318] + * Translated using Weblate (Norwegian Bokmål) [e51aa9f] + * Don't fetch Humble orders if they are not changed (#57) Temporarily disable `update_games()` to test [352ba23] + + -- Hosted Weblate Sun, 20 Jan 2019 11:44:53 +0100 + +com.github.tkashkin.gamehub (0.13.0-6-dev~elementary5.0) juno; urgency=low + * Fix moving children up from inner directory for installed games Fix xgettext not extracting some strings due to having a forward slash in source file anywhere before these strings [04ab0ed] + + -- tkashkin Sun, 20 Jan 2019 02:17:47 +0300 + +com.github.tkashkin.gamehub (0.13.0-5-dev~elementary5.0) juno; urgency=low + * Remove sleeps while adding games (#57) Add games to GamesView in batches [06749a4] + + -- tkashkin Sat, 19 Jan 2019 19:54:34 +0300 + +com.github.tkashkin.gamehub (0.13.0-4-dev~elementary5.0) juno; urgency=low + * Fix Humble games install path after uninstalling Fix having multiple instances of same Game in memory in some cases (for example if game properties dialog is opened via notification): * Fix cases when properties dialog used another Game instance and changes were not updating for the first instance * Slightly reduce memory usage [8263dd6] + + -- tkashkin Sat, 19 Jan 2019 17:17:30 +0300 + +com.github.tkashkin.gamehub (0.13.0-3-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Norwegian Bokmål) [d3f5249] + * Translated using Weblate (Dutch) [ef04ff5] + * Merge remote-tracking branch 'weblate/dev' into dev [fb92145] + * Translated using Weblate (Dutch) [13bda3a] + + -- Allan Nordhøy Wed, 16 Jan 2019 23:24:57 +0000 + +com.github.tkashkin.gamehub (0.13.0-2-dev~elementary5.0) juno; urgency=low + * Less verbose logging by default [e2604e5] + + -- tkashkin Wed, 16 Jan 2019 17:06:58 +0300 + +com.github.tkashkin.gamehub (0.13.0-1-dev~elementary5.0) juno; urgency=low + * Bump version Update copyright years [4610e43] + + -- tkashkin Wed, 16 Jan 2019 13:25:18 +0300 + +com.github.tkashkin.gamehub (0.12.1-91-dev~elementary5.0) juno; urgency=low + * Experimental version with ThreadPool thread count option (#57) [cd55bb5] + + -- tkashkin Wed, 16 Jan 2019 01:42:32 +0300 + +com.github.tkashkin.gamehub (0.12.1-90-dev~elementary5.0) juno; urgency=low + * Merge branch 'origin/dev' into Weblate. [9d98a71] + * Translated using Weblate (Norwegian Bokmål) [6ebe38d] + * Notify user if executable for game can't be detected automatically (#157) Fix Proton prefix initialization [a0512ca] + + -- Hosted Weblate Tue, 15 Jan 2019 23:18:33 +0100 + +com.github.tkashkin.gamehub (0.12.1-88-dev~elementary5.0) juno; urgency=low + * Merge branch 'origin/dev' into Weblate. [534de0c] + * Translated using Weblate (Norwegian Bokmål) [ae095ce] + + -- Hosted Weblate Tue, 15 Jan 2019 22:53:28 +0100 + +com.github.tkashkin.gamehub (0.12.1-87-dev~elementary5.0) juno; urgency=low + * New GActions and CLI options Better installer checksum mismatch handling for DEs which do not support buttons in notifications [a09fdda] + + -- tkashkin Wed, 16 Jan 2019 00:53:19 +0300 + +com.github.tkashkin.gamehub (0.12.1-86-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (French) [272ad4d] + + -- Anatoliy Kashkin Tue, 15 Jan 2019 16:25:27 +0000 + +com.github.tkashkin.gamehub (0.12.1-85-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Dutch) [21cd5dc] + + -- Heimen Stoffels Tue, 15 Jan 2019 11:00:24 +0000 + +com.github.tkashkin.gamehub (0.12.1-84-dev~elementary5.0) juno; urgency=low + * Merge remote-tracking branch 'weblate/dev' into dev [484412b] + * Translated using Weblate (Norwegian Bokmål) [739e575] + + -- tkashkin Tue, 15 Jan 2019 13:44:03 +0300 + +com.github.tkashkin.gamehub (0.12.1-83-dev~elementary5.0) juno; urgency=low + * Rework CLI options parsing (#175) Restart with GDB in the same terminal session (#172) [0bbe7ee] + + -- tkashkin Tue, 15 Jan 2019 13:39:00 +0300 + +com.github.tkashkin.gamehub (0.12.1-82-dev~elementary5.0) juno; urgency=low + * Merge branch 'origin/dev' into Weblate. [c2541cb] + * Translated using Weblate (Norwegian Bokmål) [6ca0a09] + + -- Hosted Weblate Tue, 15 Jan 2019 00:23:13 +0100 + +com.github.tkashkin.gamehub (0.12.1-81-dev~elementary5.0) juno; urgency=low + * Add a CLI option to run with GDB attached (#172) [4f2e093] + * [ci skip] Remove unused strings, try to fix a few bugged plurals for Weblate [c7f6bef] + + -- tkashkin Tue, 15 Jan 2019 02:23:00 +0300 + +com.github.tkashkin.gamehub (0.12.1-80-dev~elementary5.0) juno; urgency=low + * Prettier log Don't capture child process output when it's not needed Possibly fix #163 [841b051] + * [ci skip] Fix option group name to fit better with default GTK help [af68fda] + + -- tkashkin Mon, 14 Jan 2019 19:09:40 +0300 + +com.github.tkashkin.gamehub (0.12.1-79-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Russian) [d07f4b3] + + -- Anatoliy Kashkin Mon, 14 Jan 2019 12:16:12 +0000 + +com.github.tkashkin.gamehub (0.12.1-78-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Norwegian Bokmål) [8f8563d] + + -- Allan Nordhøy Sun, 13 Jan 2019 21:31:47 +0000 + +com.github.tkashkin.gamehub (0.12.1-77-dev~elementary5.0) juno; urgency=low + * Merge branch 'dev' of github.com:tkashkin/GameHub into dev [52da673] + * Pass git branch and commit via meson options (#172) [5c7c5cd] + + -- tkashkin Sun, 13 Jan 2019 22:35:44 +0300 + +com.github.tkashkin.gamehub (0.12.1-76-dev~elementary5.0) juno; urgency=low + * Merge branch 'origin/dev' into Weblate. [8c28072] + * Translated using Weblate (Dutch) [5e7b1c1] + * Call Application.init() after printing version (#172) [0707816] + * [ci skip] Update issue templates (#172) [c40d2e8] + * [ci skip] Create git issue templates (#172) [3012de1] + * Merge branch 'origin/dev' into Weblate. [5fc975a] + * Translated using Weblate (Dutch) [cf1f402] + + -- Hosted Weblate Sun, 13 Jan 2019 19:47:03 +0100 + +com.github.tkashkin.gamehub (0.12.1-73-dev~elementary5.0) juno; urgency=low + * Add `--version`/`-v` option (#172) Add `--log-workers` option (#172) Migrate to `Gtk.Application` from `Granite.Application` [70741b5] + + -- tkashkin Sun, 13 Jan 2019 20:59:36 +0300 + +com.github.tkashkin.gamehub (0.12.1-72-dev~elementary5.0) juno; urgency=low + * Make auth and downloader logging optional and disabled by default (#172) [93f62c1] + + -- tkashkin Sun, 13 Jan 2019 19:21:24 +0300 + +com.github.tkashkin.gamehub (0.12.1-71-dev~elementary5.0) juno; urgency=low + * Add a bit more height to compact ActionButton (#165, #171) [82debb2] + + -- tkashkin Sun, 13 Jan 2019 03:35:29 +0300 + +com.github.tkashkin.gamehub (0.12.1-70-dev~elementary5.0) juno; urgency=low + * Compact ActionButton (#165, #171) [684568d] + + -- tkashkin Sun, 13 Jan 2019 03:29:17 +0300 + +com.github.tkashkin.gamehub (0.12.1-69-dev~elementary5.0) juno; urgency=low + * Merge branch 'dev' of github.com:tkashkin/GameHub into dev [ec1c3e4] + * Fix headerbar buttons valign (#165) [c95609a] + + -- tkashkin Sun, 13 Jan 2019 01:08:26 +0300 + +com.github.tkashkin.gamehub (0.12.1-68-dev~elementary5.0) juno; urgency=low + * Merge branch 'origin/dev' into Weblate. [ca747d2] + * Translated using Weblate (Norwegian Bokmål) [ae349ab] + * Translated using Weblate (Dutch) [9ae4503] + * Use smaller icons for headerbar if symbolic (#165) [acbd2aa] + + -- Hosted Weblate Sat, 12 Jan 2019 23:01:18 +0100 + +com.github.tkashkin.gamehub (0.12.1-66-dev~elementary5.0) juno; urgency=low + * Merge branch 'origin/dev' into Weblate. [03b2a09] + * Translated using Weblate (Norwegian Bokmål) [3b15c50] + * Translated using Weblate (Dutch) [b40b1de] + * Add an option to use symbolic icons (#165) [3a15402] + + -- Hosted Weblate Sat, 12 Jan 2019 21:12:40 +0100 + +com.github.tkashkin.gamehub (0.12.1-64-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Russian) [108c6de] + * Update localization files [891f938] + * Support custom Wine/Proton prefixes (#160) [9d953c6] + + -- Anatoliy Kashkin Sat, 12 Jan 2019 17:44:08 +0000 + +com.github.tkashkin.gamehub (0.12.1-61-dev~elementary5.0) juno; urgency=low + * Replace download checkbox with a button (#168) [1a7b13a] + + -- tkashkin Sat, 12 Jan 2019 11:59:01 +0300 + +com.github.tkashkin.gamehub (0.12.1-60-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (French) [1537eed] + + -- King Claudy Wed, 9 Jan 2019 20:55:32 +0000 + +com.github.tkashkin.gamehub (0.12.1-59-dev~elementary5.0) juno; urgency=low + * Check for `wingpanel` gsettings schema before trying to use `Granite.DateTime.get_relative_datetime` (#164) [2e06716] + + -- tkashkin Tue, 8 Jan 2019 09:15:10 +0300 + +com.github.tkashkin.gamehub (0.12.1-58-dev~elementary5.0) juno; urgency=low + * Split installers list by platform (#167) [d9364a7] + + -- tkashkin Tue, 8 Jan 2019 05:21:35 +0300 + +com.github.tkashkin.gamehub (0.12.1-57-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Russian) [5a833c2] + + -- Anatoliy Kashkin Tue, 8 Jan 2019 01:23:14 +0000 + +com.github.tkashkin.gamehub (0.12.1-56-dev~elementary5.0) juno; urgency=low + * Merge games by normalized name (#166) [b3cece5] + + -- tkashkin Tue, 8 Jan 2019 04:12:25 +0300 + +com.github.tkashkin.gamehub (0.12.1-55-dev~elementary5.0) juno; urgency=low + * Sort games by normalized names (#166) [ee86ced] + + -- tkashkin Tue, 8 Jan 2019 04:08:47 +0300 + +com.github.tkashkin.gamehub (0.12.1-54-dev~elementary5.0) juno; urgency=low + * Use linuxdeployqt 5 instead of continuous due to https://github.com/probonopd/linuxdeployqt/issues/340 Revert to building a separate debian source package [8e9fc46] + * `*_amd64.changes` -> `*_source.changes` [f17330f] + * Rename *_amd64.changes to *.changes [ad701ad] + * `sed` -> `sed -i` [8bd4054] + * Modify .changes to convert debian package to a source-only package [234eb59] + * Merge branch 'origin/dev' into Weblate. [6e9fa63] + * Translated using Weblate (French) [2b9fd27] + * Fix launchpad upload to not try to upload binary [42d895f] + * Added translation using Weblate (French) [3032b26] + + -- tkashkin Mon, 7 Jan 2019 18:28:40 +0300 + +com.github.tkashkin.gamehub (0.12.1-44-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Portuguese (Brazil)) [e05ce9b] + + -- Leandro Stanger Tue, 1 Jan 2019 00:00:55 +0000 + +com.github.tkashkin.gamehub (0.12.1-43-dev~elementary5.0) juno; urgency=low + * Merge branch 'origin/dev' into Weblate. [5bfaa0c] + * Translated using Weblate (Dutch) [99fd3e2] + * Parse game actions from gameinfo for GOG Windows games Set executable and arguments automatically for Windows GOG games using primary action when possible (#157) [d02c24c] + + -- Hosted Weblate Sat, 29 Dec 2018 01:42:41 +0100 + +com.github.tkashkin.gamehub (0.12.1-41-dev~elementary5.0) juno; urgency=low + * Add Proton 3.16 Beta id (#101) Fix Proton prefix init Add simple download speed counter [1825920] + + -- tkashkin Fri, 28 Dec 2018 14:48:35 +0300 + +com.github.tkashkin.gamehub (0.12.1-40-dev~elementary5.0) juno; urgency=low + * Fix changelog syntax [11c751f] + * Update build scripts [1f7aaf7] + * Update README.md (#108) [e989add] + + -- tkashkin Fri, 28 Dec 2018 13:11:17 +0300 + +com.github.tkashkin.gamehub (0.12.1-37-dev~elementary5.0) juno; urgency=low + * Fix Humble Trove url signing (#32) [4798294] + + -- tkashkin Fri, 21 Dec 2018 18:49:01 +0300 + +com.github.tkashkin.gamehub (0.12.1-36-dev~elementary5.0) juno; urgency=low + * Update Humble Trove support (#32) [9d040db] + + -- tkashkin Fri, 21 Dec 2018 17:08:08 +0300 + +com.github.tkashkin.gamehub (0.12.1-35-dev~elementary5.0) juno; urgency=low + * Probably fix #154 [28e6f8d] + + -- tkashkin Thu, 20 Dec 2018 18:59:37 +0300 + +com.github.tkashkin.gamehub (0.12.1-34-dev~elementary5.0) juno; urgency=low + * Quick fix for #146 (#147) [a8970ce] + + -- neuromancer Wed, 19 Dec 2018 10:53:05 -0300 + +com.github.tkashkin.gamehub (0.12.1-33-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Norwegian Bokmål) [aa5174a] + * Translated using Weblate (German) [a222b57] + * Translated using Weblate (Dutch) [3161f00] + + -- Allan Nordhøy Sun, 16 Dec 2018 06:12:12 +0000 + +com.github.tkashkin.gamehub (0.12.1-32-dev~elementary5.0) juno; urgency=low + * msi installer support (#151) Installer checksum mismatch notification [46cf5b4] + * Translated using Weblate (Norwegian Bokmål) [1330dbb] + * Translated using Weblate (German) [370e7e2] + * Translated using Weblate (Dutch) [81bf8ec] + + -- tkashkin Sun, 16 Dec 2018 03:40:45 +0300 + +com.github.tkashkin.gamehub (0.12.1-30-dev~elementary5.0) juno; urgency=low + * Merge branch 'dev' of github.com:tkashkin/GameHub into dev [3f8460b] + * Update WineWrap integration (#108) Implement installer hash checks (#29) [3ac55b0] + + -- tkashkin Sat, 15 Dec 2018 01:52:23 +0300 + +com.github.tkashkin.gamehub (0.12.1-29-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (German) [2bfb81c] + + -- ssantos Sat, 8 Dec 2018 17:21:11 +0000 + +com.github.tkashkin.gamehub (0.12.1-28-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Norwegian Bokmål) [56399f6] + * Translated using Weblate (Dutch) [18242b8] + + -- Allan Nordhøy Fri, 7 Dec 2018 18:02:46 +0000 + +com.github.tkashkin.gamehub (0.12.1-27-dev~elementary5.0) juno; urgency=low + * Merge branch 'origin/dev' into Weblate [db10ad3] + * Translated using Weblate (Norwegian Bokmål) [0f94487] + * Translated using Weblate (German) [e7efc06] + * Add binary vdf parser/writer Add games to the Steam library (#149) [d5add8c] + + -- Hosted Weblate Fri, 7 Dec 2018 07:42:18 +0100 + +com.github.tkashkin.gamehub (0.12.1-25-dev~elementary5.0) juno; urgency=low + * Merge branch 'origin/dev' into Weblate [5beeebc] + * Translated using Weblate (Dutch) [11fb981] + * Bundle polkit for flatpak [91b5060] + * Fix run args margin [6335c6c] + * Command line option to run game (#149) [e4a9f54] + + -- Hosted Weblate Thu, 6 Dec 2018 14:16:05 +0100 + +com.github.tkashkin.gamehub (0.12.1-18-dev~elementary5.0) juno; urgency=low + * Save version of used installer (GOG only) (#148) Show updates indicator for updated GOG games (#78) [b479cbd] + + -- tkashkin Sun, 2 Dec 2018 22:00:46 +0300 + +com.github.tkashkin.gamehub (0.12.1-17-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (German) [16c13da] + * Translated using Weblate (Russian) [d149357] + * Translated using Weblate (German) [5aa2dd0] + * Translated using Weblate (Dutch) [1cf730a] + * Translated using Weblate (Dutch) [1a3ddd3] + + -- Ettore Atalan Fri, 30 Nov 2018 01:47:21 +0000 + +com.github.tkashkin.gamehub (0.12.1-15-dev~elementary5.0) juno; urgency=low + * Initial integration with adamhm's wine wrappers (#108) [a2efef1] + + -- tkashkin Wed, 28 Nov 2018 12:06:57 +0300 + +com.github.tkashkin.gamehub (0.12.1-14-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (German) [c64e772] + * Translated using Weblate (German) [732a22a] + * Translated using Weblate (German) [9f4e56c] + + -- Anatoliy Kashkin Tue, 27 Nov 2018 13:50:44 +0000 + +com.github.tkashkin.gamehub (0.12.1-11-dev~elementary5.0) juno; urgency=low + * Added translation using Weblate (German) [9b045a7] + * Translated using Weblate (Indonesian) [8be6cd4] + * Translated using Weblate (Dutch) [ec6702a] + + -- jonathanschaefer Mon, 26 Nov 2018 17:58:45 +0000 + +com.github.tkashkin.gamehub (0.12.1-9-dev~elementary5.0) juno; urgency=low + * Added translation using Weblate (Dutch) [e4e8423] + + -- Heimen Stoffels Sat, 24 Nov 2018 16:27:37 +0000 + +com.github.tkashkin.gamehub (0.12.1-8-dev~elementary5.0) juno; urgency=low + * Translated using Weblate (Indonesian) [c590c09] + * Translated using Weblate (Norwegian Bokmål) [0630207] + * Translated using Weblate (Russian) [8077361] + + -- Anatoliy Kashkin Sat, 24 Nov 2018 09:37:02 +0000 + +com.github.tkashkin.gamehub (0.12.1-6-dev~elementary5.0) juno; urgency=low + * Fix option to hide icons (#141) [7559ff7] + + -- tkashkin Wed, 21 Nov 2018 07:28:45 +0300 + +com.github.tkashkin.gamehub (0.12.1-4-dev~elementary5.0) juno; urgency=low + * Fix nb_NO translation [ad49c12] + * Merge remote-tracking branch 'weblate/dev' into dev [3236a82] + * Add an option to hide icons in grid view (#141) [ff3ff38] + * Merge branch 'origin/dev' into Weblate [9c65aed] + * [ci skip] Update README.md [d0bd26f] + * Translated using Weblate (Norwegian Bokmål) [8b057a3] + * Translated using Weblate (Norwegian Bokmål) [b338984] + * Translated using Weblate (Norwegian Bokmål) [7135c95] + + -- tkashkin Wed, 21 Nov 2018 06:13:20 +0300 + +com.github.tkashkin.gamehub (0.12.1-1-master~elementary5.0) juno; urgency=low + * Merge `dev` into `master` [cd4ff2c] + * [ci skip] Bump version [0a1e7d6] + * [ci skip] Fix broken weblate [b360886] + * Merge `dev` into `master` [72b076b] + * [ci skip] Merge dev into master [3fe313b] + + -- Anatoliy Kashkin Tue, 20 Nov 2018 02:08:28 +0300 + +com.github.tkashkin.gamehub (0.12.0-16-dev~elementary5.0) juno; urgency=low + * More secure polkit policy (#120) [09c458a] + + -- tkashkin Sun, 18 Nov 2018 23:16:07 +0300 + +com.github.tkashkin.gamehub (0.12.0-15-dev~elementary5.0) juno; urgency=low + * Playtime sort mode (#139) [a828310] + * [ci skip] Update pt_BR.po (#140) [ad86a6f] + + -- tkashkin Tue, 13 Nov 2018 04:57:12 +0300 + +com.github.tkashkin.gamehub (0.12.0-14-dev~elementary5.0) juno; urgency=low + * Add running indicator (#138) [a4cd434] + + -- tkashkin Mon, 12 Nov 2018 16:39:01 +0300 + +com.github.tkashkin.gamehub (0.12.0-13-dev~elementary5.0) juno; urgency=low + * UI tweaks [9a14a0e] + + -- tkashkin Mon, 12 Nov 2018 05:54:37 +0300 + +com.github.tkashkin.gamehub (0.12.0-12-dev~elementary5.0) juno; urgency=low + * Import playtime from Steam and GOG Show version for installed native GOG games Improve image rendering in AutoSizeImage [49018e2] + + -- tkashkin Mon, 12 Nov 2018 02:25:20 +0300 + +com.github.tkashkin.gamehub (0.12.0-10-dev~elementary5.0) juno; urgency=low + * Achievements (#130) [9b5535e] + + -- tkashkin Sun, 11 Nov 2018 06:20:39 +0300 + +com.github.tkashkin.gamehub (0.12.0-9-dev~elementary5.0) juno; urgency=low + * Add ScummVM (#52) [187c708] + * Allow to launch custom emulators from game directory (#52) [cd8105d] + + -- tkashkin Sun, 11 Nov 2018 02:24:07 +0300 + +com.github.tkashkin.gamehub (0.12.0-7-dev~elementary5.0) juno; urgency=low + * Fix images update in GamePropertiesDialog (#131) [3a5473a] + + -- tkashkin Sun, 11 Nov 2018 00:54:58 +0300 + +com.github.tkashkin.gamehub (0.12.0-6-dev~elementary5.0) juno; urgency=low + * Update xenial deps to fix xenial AppVeyor build [25b2a01] + + -- tkashkin Sat, 10 Nov 2018 23:17:15 +0300 + +com.github.tkashkin.gamehub (0.12.0-5-dev~elementary5.0) juno; urgency=low + * Fix FileChooserEntry (#131) [484aee5] + * [ci skip] Update pt_BR localization (#135) [6af5df4] + + -- tkashkin Sat, 10 Nov 2018 22:34:19 +0300 + +com.github.tkashkin.gamehub (0.12.0-4-dev~elementary5.0) juno; urgency=low + * Replace FileChooserButtons with custom FileChooserEntry (#131) [fca3a8a] + + -- tkashkin Sat, 10 Nov 2018 05:04:40 +0300 + +com.github.tkashkin.gamehub (0.12.0-3-dev~elementary5.0) juno; urgency=low + * Fix #114 [bcae45c] + + -- tkashkin Fri, 9 Nov 2018 03:51:38 +0300 + +com.github.tkashkin.gamehub (0.12.0-1-master~elementary5.0) juno; urgency=low + * Merge `dev` into `master` [72b076b] + * [ci skip] 0.12.0 [e03158d] + * [ci skip] Merge dev into master [3fe313b] + + -- Anatoliy Kashkin Fri, 9 Nov 2018 01:34:01 +0300 + +com.github.tkashkin.gamehub (0.11.7-8-dev~elementary5.0) juno; urgency=low + * Update localization template [de1064b] + + -- tkashkin Thu, 8 Nov 2018 23:28:08 +0300 + +com.github.tkashkin.gamehub (0.11.7-7-dev~elementary5.0) juno; urgency=low + * One more fix for #124 [28d9a7b] + * Probably fix #124 [877f42b] + + -- tkashkin Thu, 8 Nov 2018 15:25:58 +0300 + +com.github.tkashkin.gamehub (0.11.7-5-dev~elementary5.0) juno; urgency=low + * Fix build with GTK < 3.22 [27c7e4f] + + -- tkashkin Thu, 8 Nov 2018 02:35:44 +0300 + +com.github.tkashkin.gamehub (0.11.7-4-dev~elementary5.0) juno; urgency=low + * Implement #126 [cc8ed76] + + -- tkashkin Thu, 8 Nov 2018 02:06:33 +0300 + +com.github.tkashkin.gamehub (0.11.7-3-dev~elementary5.0) juno; urgency=low + * Fixes for #120 [1c78c4f] + * Fixes for #120 Update screenshots in AppStream data [9148625] + * [ci skip] Update README.md [489ac63] + * [ci skip] Update README.md and screenshots [8b321ac] + * [ci skip] Update README.md [769284e] + * [ci skip] Update README.md, Fix #123 [5a232b4] + + -- tkashkin Wed, 7 Nov 2018 22:49:19 +0300 + +com.github.tkashkin.gamehub (0.11.7-1-dev~elementary5.0) juno; urgency=low + * Overlays (#120) [2071a8e] + + -- tkashkin Mon, 5 Nov 2018 05:48:50 +0300 + +com.github.tkashkin.gamehub (0.11.6-15-dev~elementary5.0) juno; urgency=low + * Fix build with polkit [9968cc2] + + -- tkashkin Sun, 4 Nov 2018 16:48:43 +0300 + +com.github.tkashkin.gamehub (0.11.6-14-dev~elementary5.0) juno; urgency=low + * Initial OverlayFS impplementation for #120 [e36f1b5] + + -- tkashkin Sun, 4 Nov 2018 16:20:16 +0300 + +com.github.tkashkin.gamehub (0.11.6-13-dev~elementary5.0) juno; urgency=low + * Wine/Proton improvements Bugfixes for #106 [f4a4847] + + -- tkashkin Sun, 4 Nov 2018 02:31:55 +0300 + +com.github.tkashkin.gamehub (0.11.6-12-dev~elementary5.0) juno; urgency=low + * Custom emulators can be installed with installers (#106) [0f374be] + + -- tkashkin Sat, 3 Nov 2018 23:08:49 +0300 + +com.github.tkashkin.gamehub (0.11.6-11-dev~elementary5.0) juno; urgency=low + * UI improvements [d6eccf5] + + -- tkashkin Sat, 3 Nov 2018 18:49:56 +0300 + +com.github.tkashkin.gamehub (0.11.6-10-dev~elementary5.0) juno; urgency=low + * Improve GOG DLC support (#118) [6a72d84] + + -- tkashkin Sat, 3 Nov 2018 03:49:42 +0300 + +com.github.tkashkin.gamehub (0.11.6-9-dev~elementary5.0) juno; urgency=low + * Restrict NSIS installers unpacking with `file-roller` Support adding custom games using installers (#106) Implement custom emulators removal [7e443e4] + + -- tkashkin Thu, 1 Nov 2018 08:20:07 +0300 + +com.github.tkashkin.gamehub (0.11.6-8-dev~elementary5.0) juno; urgency=low + * Fix compat settings and launch time saving for non-native games (#92) [75a5015] + + -- tkashkin Thu, 1 Nov 2018 05:31:22 +0300 + +com.github.tkashkin.gamehub (0.11.6-7-dev~elementary5.0) juno; urgency=low + * Improve bundled DOSBox detection for GOG Windows games (#113) [3b3427e] + + -- tkashkin Thu, 1 Nov 2018 02:11:41 +0300 + +com.github.tkashkin.gamehub (0.11.6-6-dev~elementary5.0) juno; urgency=low + * New useless feature: press R to select random game [842bc32] + + -- tkashkin Thu, 1 Nov 2018 01:05:13 +0300 + +com.github.tkashkin.gamehub (0.11.6-5-dev~elementary5.0) juno; urgency=low + * Add logout buttons for GOG and Humble (#40) Add NSIS installer support (#96) [d18ac39] + + -- tkashkin Thu, 1 Nov 2018 00:21:47 +0300 + +com.github.tkashkin.gamehub (0.11.6-4-dev~elementary5.0) juno; urgency=low + * Fix #38, #109 [4d35615] + + -- tkashkin Wed, 31 Oct 2018 03:50:25 +0300 + +com.github.tkashkin.gamehub (0.11.6-3-dev~elementary5.0) juno; urgency=low + * Custom emulator support (#103) Download only mode (#107) [4150ba2] + + -- tkashkin Fri, 26 Oct 2018 18:58:21 +0300 + +com.github.tkashkin.gamehub (0.11.6-2-dev~elementary5.0) juno; urgency=low + * Fix #105 Fix GOG bonus content download info [226fc5c] + + -- tkashkin Wed, 24 Oct 2018 18:40:06 +0300 + +com.github.tkashkin.gamehub (0.11.6-1-dev~elementary5.0) juno; urgency=low + * Fix DEB_BUILD_OPTIONS [81f11b6] + * Keyboard/gamepad navigation improvements WINEARCH fixes Version bump [5de360a] + * Controller mode improvements (#75) [e5b5298] + * Possibly fix debian/rules to disable optimizations Do not show compat dialog if parameters for game are saved (#75) [394cd6d] + + -- tkashkin Tue, 23 Oct 2018 15:36:21 +0300 + +com.github.tkashkin.gamehub (0.11.5-29-dev~elementary5.0) juno; urgency=low + * Set DEB_BUILD_OPTIONS in debian/rules [24f83f1] + + -- tkashkin Mon, 22 Oct 2018 02:41:47 +0300 + +com.github.tkashkin.gamehub (0.11.5-28-dev~elementary5.0) juno; urgency=low + * Fix add game button insensitivity Disable optimizations Update README.md [393c96e] + + -- tkashkin Mon, 22 Oct 2018 01:19:01 +0300 + +com.github.tkashkin.gamehub (0.11.5-26-dev~elementary5.0) juno; urgency=low + * Add RetroArch compatibility tool [7a896a5] + + -- tkashkin Sun, 21 Oct 2018 22:07:43 +0300 + +com.github.tkashkin.gamehub (0.11.5-25-dev~elementary5.0) juno; urgency=low + * Fix last launch time sorting [c2640f4] + + -- tkashkin Sat, 20 Oct 2018 21:32:21 +0300 + +com.github.tkashkin.gamehub (0.11.5-24-dev~elementary5.0) juno; urgency=low + * Prevent multiple games launch at the same time (#92) Possibly fix flatpak errors (#15, #61) [6029659] + + -- tkashkin Sat, 20 Oct 2018 21:07:06 +0300 + +com.github.tkashkin.gamehub (0.11.5-23-dev~elementary5.0) juno; urgency=low + * Update flatpak libs [7ccc7a5] + + -- tkashkin Sat, 20 Oct 2018 00:08:13 +0300 + +com.github.tkashkin.gamehub (0.11.5-22-dev~elementary5.0) juno; urgency=low + * Remove flatpak runtime libs [6db7eed] + + -- tkashkin Fri, 19 Oct 2018 23:52:13 +0300 + +com.github.tkashkin.gamehub (0.11.5-21-dev~elementary5.0) juno; urgency=low + * Games can be sorted by last launch time Imported tags can be disabled (#47) Experimental flatpak changes (#15) [cb4c384] + + -- tkashkin Fri, 19 Oct 2018 23:39:19 +0300 + +com.github.tkashkin.gamehub (0.11.5-20-dev~elementary5.0) juno; urgency=low + * Unified games sorting (#102) Possibly fix some of random crashes [8dfd66a] + + -- tkashkin Fri, 19 Oct 2018 01:37:56 +0300 + +com.github.tkashkin.gamehub (0.11.5-19-dev~elementary5.0) juno; urgency=low + * Update flatpak manifest and build script [c48a7f1] + + -- tkashkin Thu, 18 Oct 2018 16:00:31 +0300 + +com.github.tkashkin.gamehub (0.11.5-17-dev~elementary5.0) juno; urgency=low + * Merge branch 'dev' of github.com:tkashkin/GameHub into dev [b1639e3] + * Cleanup flatpak build directory [b5717ba] + * Cleanup flatpak build directory [4510625] + * Update flatpak build script Update flatpak manifest Move flatpak manifest from its branch [8788426] + + -- tkashkin Wed, 17 Oct 2018 22:50:44 +0300 + +com.github.tkashkin.gamehub (0.11.5-14-dev~elementary5.0) juno; urgency=low + * Update build script [8abf5b8] + + -- tkashkin Wed, 17 Oct 2018 00:31:03 +0300 + +com.github.tkashkin.gamehub (0.11.5-13-dev~elementary5.0) juno; urgency=low + * + + -- tkashkin Tue, 16 Oct 2018 23:20:58 +0300 + +com.github.tkashkin.gamehub (0.11.5-12-dev~elementary5.0) juno; urgency=low + * Update build script and fix xenial build [0b81f04] + + -- tkashkin Tue, 16 Oct 2018 23:20:58 +0300 + +com.github.tkashkin.gamehub (0.11.5-11-dev~elementary5.0) juno; urgency=low + * Update build script [7b9bdae] + + -- tkashkin Tue, 16 Oct 2018 22:16:50 +0300 + +com.github.tkashkin.gamehub (0.11.5-10-dev~elementary5.0) juno; urgency=low + * + + -- tkashkin Tue, 16 Oct 2018 21:04:01 +0300 + +com.github.tkashkin.gamehub (0.11.5-9-dev~elementary5.0) juno; urgency=low + * Try to fix build for xenial and flatpak [ef33bc5] + + -- tkashkin Tue, 16 Oct 2018 21:04:01 +0300 + +com.github.tkashkin.gamehub (0.11.5-8-dev~elementary5.0) juno; urgency=low + * Fix build on xenial [245936b] + + -- tkashkin Tue, 16 Oct 2018 19:46:03 +0300 + +com.github.tkashkin.gamehub (0.11.5-7-dev~elementary5.0) juno; urgency=low + * Release all keys on gamepad disconnect [a93f616] + * Fix focus stealing from search field Update readme [3aca6fe] + + -- tkashkin Tue, 16 Oct 2018 18:22:47 +0300 + +com.github.tkashkin.gamehub (0.11.5-5-dev~elementary5.0) juno; urgency=low + * Controller UI mode [79578c7] + + -- tkashkin Mon, 15 Oct 2018 01:03:00 +0300 + +com.github.tkashkin.gamehub (0.11.5-4-dev~elementary5.0) juno; urgency=low + * Fix build [3d005c2] + * Improved keyboard events using xtest instead of calling xdotool [923715a] + + -- tkashkin Sun, 14 Oct 2018 22:57:19 +0300 + +com.github.tkashkin.gamehub (0.11.5-2-dev~elementary5.0) juno; urgency=low + * Improved gamepad navigation, stick support [e3d214c] + + -- tkashkin Sun, 14 Oct 2018 15:39:11 +0300 + +com.github.tkashkin.gamehub (0.11.5-1-dev~elementary5.0) juno; urgency=low + * Update build script [c7ef68f] + * UI tweaks Proton 3.16 support Basic keyboard/gamepad navigation in grid view (#75) [4c29f49] + + -- tkashkin Sun, 14 Oct 2018 01:43:15 +0300 + +com.github.tkashkin.gamehub (0.11.4-1-dev~elementary5.0) juno; urgency=low + * Bump version [cd50494] + * Use WINEARCH env variable Fix building with older libsoup [507c293] + + -- tkashkin Fri, 12 Oct 2018 00:00:31 +0300 + +com.github.tkashkin.gamehub (0.11.3-14-dev~elementary5.0) juno; urgency=low + * Use correct gpg package and binary on xenial [048f365] + * One more flatpak try [4feb1f6] + + -- tkashkin Wed, 10 Oct 2018 20:09:44 +0300 + +com.github.tkashkin.gamehub (0.11.3-12-dev~elementary5.0) juno; urgency=low + * Update README.md Possibly fix flatpak build and xenial launchpad source package upload [6b04a97] + * Revert libwebkit2gtk workarounds [bac13e2] + * set +e in build_flatpak() [cf2cdd1] + * Update build script [511903f] + * Try to use older libwebkit2gtk for launchpad [3885762] + * Update debian/control [8e75319] + * Update debian/control [12449cd] + * Update debian/control [dd5e720] + * Update flatpak build script Try to blacklist webkit2gtk again [8cab19b] + * Merge branch 'dev' of github.com:tkashkin/GameHub into dev [3e55b94] + * Try to use libwebkit2gtk-4.0-dev=2.20.1-1 if available Try to build flatpak [4b5d555] + * Merge pull request #95 from cho2/l10n-dev [66ecef0] + * Update Indonesian translation [3c11ab1] + + -- tkashkin Wed, 10 Oct 2018 19:45:43 +0300 + +com.github.tkashkin.gamehub (0.11.3-1-dev~elementary5.0) juno; urgency=low + * Build source-only package for launchpad [1b8ae91] + * Disable GPG signature check for dput [f927210] + * Force gpg1 for dput [f471ae7] + * Try to use gpg1 [160d118] + * Try to use gpg1 [3ba17a0] + * Try to start gpg-agent [823d832] + * Try to start gpg-agent [78bfa66] + * Force older webkit libs again [2f4433c] + * Force older libwebkit2gtk [78a6efc] + * Blacklist libwebkit2gtk-4.0-dev 2.22.2-0ubuntu0.18.04.1 [16b042d] + * No fail on key import [fa39130] + * Try to start gpg-agent [d3ef42c] + * Update build script [690ad06] + * Update localization template Update build scripts Trying to setup a PPA Update license [e146c44] + * Update debian build instructions (#91) [e943ed5] + + -- tkashkin Sat, 6 Oct 2018 14:04:59 +0300 + +com.github.tkashkin.gamehub (0.11.2-6-dev~elementary5.0) juno; urgency=low + * Fix GOG token refresh when there's no internet connection [40d7849] + + -- tkashkin Sat, 29 Sep 2018 13:58:51 +0300 + +com.github.tkashkin.gamehub (0.11.2-5-dev~elementary5.0) juno; urgency=low + * Slightly modified #90 [6d80079] + + -- tkashkin Thu, 27 Sep 2018 20:10:13 +0300 + +com.github.tkashkin.gamehub (0.11.2-4-dev~elementary5.0) juno; urgency=low + * Merge pull request #88 from neuromancer/patch-1 [51b3653] + * complete gecko popup removal when creating a new wine prefix [c167f08] + + -- Anatoliy Kashkin Wed, 26 Sep 2018 19:36:11 +0300 + +com.github.tkashkin.gamehub (0.11.2-3-dev~elementary5.0) juno; urgency=low + * Enhancements for #83 [fc62026] + + -- tkashkin Tue, 25 Sep 2018 08:02:35 +0300 + +com.github.tkashkin.gamehub (0.11.2-2-dev~elementary5.0) juno; urgency=low + * Game command line parameters User-added games (#83) [0fad67c] + + -- tkashkin Mon, 24 Sep 2018 13:28:48 +0300 + +com.github.tkashkin.gamehub (0.11.2-1-dev~elementary5.0) juno; urgency=low + * Fixes for CompatTools [24600df] + * Merge pull request #84 from tkashkin/master [f193fb6] + + -- tkashkin Sun, 23 Sep 2018 08:56:16 +0300 + +com.github.tkashkin.gamehub (0.11.1-2-master~elementary5.0) juno; urgency=low + * Fix AppImage repacking [aa60f85] + * Update AppVeyor config [a840b8b] + * Add xenial dependencies [b74ef25] + * Update build script [861be4c] + * Update AppVeyor config [a8f959e] + * Update AppVeyor config [edea459] + * Update AppVeyor config [ab8831f] + * Try to build on Ubuntu 16.04 [6c4ba32] + * Update AppImage build and run scripts [39e00ef] + * [ci skip] Fix building with GTK < 3.22 [d50095c] + + -- tkashkin Fri, 21 Sep 2018 08:16:14 +0300 + +com.github.tkashkin.gamehub (0.11.1-1-master~elementary5.0) juno; urgency=low + * Update AppVeyor config [364765d] + * Update AppVeyor artifact paths [6a91e63] + * Bump version Update AppVeyor config and AppImage build script [14580cb] + * Remove Travis CI from README.md [b2acce4] + * Update AppVeyor config [783aab2] + * Update AppVeyor config [1ebcb51] + * Update pt_BR localization [2533558] + + -- tkashkin Wed, 19 Sep 2018 03:48:01 +0300 + +com.github.tkashkin.gamehub (0.11.0~elementary5.0) juno; urgency=low + * Merge pull request #80 from tkashkin/dev [6dd4d6b] + * Merge pull request #79 from tkashkin/appimage [3802672] + * 0.11.0 release [7362f95] + * Restore Travis to Houston CI (Travis doesn't support Ubuntu newer than trusty :confused:) Try to migrate to AppVeyor [4b9c3b6] + * Add AppImage support [a565890] + * Add libxml2-dev dependency to debian/control [6bff75d] + * Another fix attempt for #77 [53fbb2f] + * Fix force_compat Probably fix Trove.sing_url (#77) [22b0ab5] + * Add DOSBox CompatTool (#71) Allow to force compat even for games which do support Linux (#51, #52, #71) [36b90dc] + * Add CustomScript tool (#71) [99bf86c] + * Maybe fix Humble URL ttl (#73) [67c77a8] + * One more try (#67) [55fadbc] + * GamesView postponed updates (#67) "Installed" tag (#69) Fix Utils.strip_name (#70) Partly update localizations [5e03bce] + * Fix #68 [04e2799] + * Implement Humble Trove support (#32) [9e3dc15] + * Log working directory [c134e48] + * Log all run methods [e6d6d60] + * Added install options for compat tools [3cd2745] + * Pass target directory to windows installers (for now assuming all of them are InnoSetup) [b62ec93] + * Fix appstream info [2a114af] + * Version bump [2177acc] + * Database rewrite (refactoring, versioning, migrations, #64) UI tweaks Added tag icons [6c48e09] + * Game properties dialog Improvements for #59 [bef7791] + * Compatibility tools selection (#59, #60) [7752ad9] + * Experimental Proton/wine support (#54) [fd5a0e5] + * Fix flatpak build [53e10bb] + + -- Anatoliy Kashkin Tue, 18 Sep 2018 09:25:15 +0300 + +com.github.tkashkin.gamehub (0.9.0~elementary5.0) juno; urgency=low + * Prepare 0.9.0 release [01ef0c6] + * [ci skip] Update README (new AUR package) [e399e6f] + * Implement #50, #33 [c64646e] + * [ci skip] Update README.md [08585aa] + * Add Proton beta appid check [707f6ed] + * Use ThreadPool instead of spawning endless threads Run game merging only for new games (may not merge all games correctly, needs testing) Finally fix #48 (maybe) [ea5b143] + * Fixes for humble and #48 [4a3f01d] + * Game tags dialog User tags creation [1f27c50] + * Tags (#47) are working (no user tags yet) Games context menu [6765826] + * Started work on #47: * GamesDB refactoring * Game tags * Tags import from GOG * FiltersPopover (just basic UI now, not hooked to anything) [c4e0f3f] + * Sort cached games by name [d8c36a3] + * Remove tmp installer extension [699de05] + * Fixes [b02797c] + * Refactoring Non-native games support Steam Play support [16b3f84] + * Fix GOG bonus content/DLC loading [c232c37] + * Refactored DownloadProgressView to allow more download types (not only games) Implemented GOG bonus content downloading [7c7ef29] + * Actually disable merging (loading cache) when merging toggle is disabled [2560717] + * Basic collection management (#29) [055c51a] + * Fixed #38 [41f45fc] + * Fix games counter [668172f] + * Improved merging [ee79571] + * Threaded loading Threaded merging Merging cache [b02381e] + * Fixes for #42, #43 Fixed GameDetaisView/GameDetailsDialog background color for non-elementary gtk themes [8dc569a] + * Fixes for #39 Added Collection tab in settings dialog (does nothing yet) [e201431] + * Started implementing #29 Fetching bonus content and DLCs (no download yet) Bugfixes [42816ef] + * Fix flatpak Steam path [3855cf6] + * Fix flatpak Steam path [4a6407a] + * Flatpak build error fix [ecda4c5] + + -- tkashkin Tue, 4 Sep 2018 09:48:50 +0300 + +com.github.tkashkin.gamehub (0.8.0~elementary5.0) juno; urgency=low + * Option to merge games from different sources [9906b6a] + * Add null check in Utils.cache_image [eff0aab] + + -- tkashkin Wed, 15 Aug 2018 16:26:15 +0300 + +com.github.tkashkin.gamehub (0.7.0~elementary5.0) juno; urgency=low + * Settings dialog rework Compact games list [b9712bb] + + -- tkashkin Thu, 9 Aug 2018 20:29:22 +0300 + +com.github.tkashkin.gamehub (0.6.3~elementary5.0) juno; urgency=low + * Trying to fix Humble Bundle access token extraction [3a8a79c] + + -- tkashkin Mon, 6 Aug 2018 14:21:16 +0300 + +com.github.tkashkin.gamehub (0.6.2~elementary5.0) juno; urgency=low + * Search crash fix and UI improvements [7800da0] + + -- tkashkin Wed, 25 Jul 2018 20:22:36 +0300 + +com.github.tkashkin.gamehub (0.6.1~elementary5.0) juno; urgency=low + * Additional info for Steam games Pass locale to APIs when possible to get localized data [882cef7] + * Merge branch 'master' of github.com:tkashkin/GameHub [464adc3] + * Initial snap is at least working now (still broken as hell) Fixes for old GTK+3 [0945f04] + * Update Indonesian translation (#28) [0ab322a] + * UI fixes Initial snap [f7f57b5] + * Update pt_BR.po (#25) [8cc0b6f] + * Update README.md [a0ea12a] + + -- tkashkin Tue, 24 Jul 2018 08:03:14 +0300 + +com.github.tkashkin.gamehub (0.6.0~elementary5.0) juno; urgency=low + * Downloader rewrite: now it's possible to pause and cancel downloads Downloads can be resumed after interruption UI improvements [e2f0c9e] + * [ci skip] Fix Humble Bundle installers cache [1d65ac3] + + -- tkashkin Sun, 22 Jul 2018 17:53:23 +0300 + +com.github.tkashkin.gamehub (0.5.7~elementary5.0) juno; urgency=low + * Yet another locale fix Installers cache management [1cc9b24] + + -- tkashkin Sat, 21 Jul 2018 02:48:46 +0300 + +com.github.tkashkin.gamehub (0.5.6~elementary5.0) juno; urgency=low + * Fix crash for GOG "games" like Hotline Miami 2 Digital Comics Fix building with GTK+3 < 3.22 [e2674e7] + * Fix GOG pagination (#22) [7c60162] + + -- tkashkin Fri, 20 Jul 2018 19:17:50 +0300 + +com.github.tkashkin.gamehub (0.5.5~elementary5.0) juno; urgency=low + * Bugfixes Design changes Compatibility [268bdfe] + * Bundle ivy [7c887d7] + * Update .travis.yml [2c9d334] + * Update README.md [30edc21] + * [ci skip] Update README.md [fe5b112] + * Show additional info for GOG games [abf3f04] + + -- tkashkin Fri, 20 Jul 2018 17:15:57 +0300 + +com.github.tkashkin.gamehub (0.5.4~elementary5.0) juno; urgency=low + * [ci skip] Yet anothed locale fix [e26aef4] + * 0.5.4 release [0d539cd] + + -- tkashkin Mon, 16 Jul 2018 06:38:24 +0300 + +com.github.tkashkin.gamehub (0.5.3~elementary5.0) juno; urgency=low + * Merge branch 'master' of github.com:tkashkin/GameHub [a13ea49] + * [ci skip] Fix launching for flatpak [732aad7] + * [ci skip] Update launcher script [4c97be9] + * [ci skip] Wrong args fix [d479056] + * [ci skip] Missing ; [71b86bd] + * 0.5.3 release [ac2ee74] + * id language (#11) [69381fa] + + -- tkashkin Sun, 15 Jul 2018 15:31:27 +0300 + +com.github.tkashkin.gamehub (0.5.2~elementary5.0) juno; urgency=low + * 0.5.2 release Added localizations: * pt_BR * pl * uk * de [f26eee5] + * pt_BR language (#10) [f37e27b] + + -- tkashkin Sat, 14 Jul 2018 02:58:55 +0300 + +com.github.tkashkin.gamehub (0.5.1~elementary5.0) juno; urgency=low + * Prepare 0.5.1 release [f2faa51] + * [ci skip] Fix AutoSizeImage resizing while image is not loaded [f332c71] + * [ci skip] Fix image loading for flathub [5d2a96c] + * [ci skip] Trying to fix network for flatpak [e1f396d] + * [ci skip] Better error handling for images caching [80f753a] + * Initial flatpak build support [WIP] [2b0e729] + + -- tkashkin Fri, 13 Jul 2018 05:31:57 +0300 + +com.github.tkashkin.gamehub (0.5.0~elementary5.0) juno; urgency=low + * [ci skip] Disable WebKit hardware acceleration [f878bbd] + * [ci skip] Cache path [e6286cd] + * Enum fixes [b9a4792] + * Enum fixes [c9a4d0e] + * [ci skip] Appstream data changes [8270d4e] + * Downloads list fixes [1f33028] + * Games list view Game details view/dialog Games grid improvements Bug fixes [cc083bb] + + -- tkashkin Thu, 12 Jul 2018 11:37:43 +0300 + +com.github.tkashkin.gamehub (0.4.1~elementary5.0) juno; urgency=low + * Small features [4424a8a] + + -- tkashkin Sat, 7 Jul 2018 10:05:21 +0300 + +com.github.tkashkin.gamehub (0.4.0~elementary5.0) juno; urgency=low + * Unneeded game sources now can be disabled Bug fixes [7b8a735] + * Probably fix Humble auth [54a5b4f] + * Debug logging Small UI fixes [2d315c0] + * Hide toolbar buttons while loading [341a3a4] + * Flat welcome window [b7cdb7c] + + -- tkashkin Tue, 3 Jul 2018 05:00:52 +0300 + +com.github.tkashkin.gamehub (0.3.1~elementary5.0) juno; urgency=low + * Humble Bundle authentication fix Humble Bundle game icons fix [2ba374a] + + -- tkashkin Fri, 22 Jun 2018 18:04:49 +0300 + +com.github.tkashkin.gamehub (0.3.0~elementary5.0) juno; urgency=low + * Humble Bundle support 0.3.0 release [89968b4] + * Update post_install script [0310078] + + -- tkashkin Sun, 17 Jun 2018 07:11:24 +0300 + +com.github.tkashkin.gamehub (0.2.5~elementary5.0) juno; urgency=low + * Prepare 0.2.5 release [dd02dd2] + * Fix game installation segfault [b213b2f] + * Fix for GOG games with ':' in title [a652a78] + * [ci skip] Update README.md [9638c69] + * Create .travis.yml [bbff2ea] + + -- tkashkin Tue, 12 Jun 2018 01:26:22 +0300 + +com.github.tkashkin.gamehub (0.2.4~elementary5.0) juno; urgency=low + * Settings dialog [554b658] + + -- tkashkin Sat, 2 Jun 2018 05:57:32 +0300 + +com.github.tkashkin.gamehub (0.2.3~elementary5.0) juno; urgency=low + * Fixes [e0f80f7] + * Update version [323e09f] + * Update readme and version [cf950e1] + * Remove ivy again [068bc3b] + * Update changelog [8f23bad] + * GOG games installation and running Various improvements [b0b9111] + * Steam game launch and installation Games grid style tweaks [0b801cc] + * Grid selection mode [fb11b0b] + * Grid autosizing [7ebee54] + * Almost perfect grid autosizing [03c53c4] + * [WIP] Games grid autosizing Juno fixes [0183150] + + -- tkashkin Fri, 1 Jun 2018 14:40:32 +0300 + +com.github.tkashkin.gamehub (0.1.3~elementary5.0) juno; urgency=low + * Update changelog [533ff4d] + * Fix Steam config path\nUpdate .gitignore [17695d8] + + -- tkashkin Mon, 28 May 2018 02:30:49 +0300 diff --git a/debian/changelog.in b/debian/changelog.in new file mode 100644 index 00000000..7583252c --- /dev/null +++ b/debian/changelog.in @@ -0,0 +1,2075 @@ +com.github.tkashkin.gamehub (0.14.2-51-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge pull request #312 from Lucki/patch-1 [6075c9f] + * Allow enabling d9vk [86b7d57] + + -- Anatoliy Kashkin Fri, 15 Nov 2019 21:48:18 +0300 + +com.github.tkashkin.gamehub (0.14.2-50-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Turkish) [006ff9f] + + -- Oğuz Ersen Wed, 13 Nov 2019 17:53:16 +0000 + +com.github.tkashkin.gamehub (0.14.2-49-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Turkish) [4d0a243] + + -- Oğuz Ersen Mon, 11 Nov 2019 19:07:16 +0000 + +com.github.tkashkin.gamehub (0.14.2-48-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Finnish) [4236830] + * Translated using Weblate (Finnish) [8ae0e75] + * Translated using Weblate (Catalan) [79c06dc] + + -- Tuomas Lähteenmäki Sat, 9 Nov 2019 21:43:37 +0000 + +com.github.tkashkin.gamehub (0.14.2-46-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Catalan) [7427529] + + -- Marc Riera Wed, 6 Nov 2019 23:28:04 +0000 + +com.github.tkashkin.gamehub (0.14.2-45-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Finnish) [b20005b] + + -- Tuomas Lähteenmäki Thu, 7 Nov 2019 02:44:04 +0000 + +com.github.tkashkin.gamehub (0.14.2-44-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Added translation using Weblate (Finnish) [51f4546] + + -- Tuomas Lähteenmäki Thu, 7 Nov 2019 02:43:02 +0000 + +com.github.tkashkin.gamehub (0.14.2-43-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Added translation using Weblate (Catalan) [68f69e9] + + -- Marc Riera Wed, 6 Nov 2019 19:18:42 +0000 + +com.github.tkashkin.gamehub (0.14.2-42-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (French) [cf641ac] + + -- Éfrit Mon, 21 Oct 2019 22:23:29 +0000 + +com.github.tkashkin.gamehub (0.14.2-41-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (French) [184c6e7] + + -- Nathan Sat, 19 Oct 2019 10:30:13 +0000 + +com.github.tkashkin.gamehub (0.14.2-40-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Arabic) [f3ea1ed] + + -- abidin toumi Fri, 18 Oct 2019 08:46:39 +0000 + +com.github.tkashkin.gamehub (0.14.2-39-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Arabic) [e851f70] + + -- abidin toumi Thu, 17 Oct 2019 06:52:42 +0000 + +com.github.tkashkin.gamehub (0.14.2-38-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Arabic) [79598e1] + + -- abidin toumi Mon, 14 Oct 2019 10:59:54 +0000 + +com.github.tkashkin.gamehub (0.14.2-37-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (French) [2c90003] + + -- Nathan Sat, 12 Oct 2019 16:37:46 +0000 + +com.github.tkashkin.gamehub (0.14.2-36-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (French) [8f7f70c] + + -- Nathan Fri, 11 Oct 2019 07:20:26 +0000 + +com.github.tkashkin.gamehub (0.14.2-35-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Indonesian) [a3a2e89] + + -- ekickx Wed, 9 Oct 2019 21:39:16 +0000 + +com.github.tkashkin.gamehub (0.14.2-34-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Norwegian Bokmål) [4693bf5] + * Translated using Weblate (Dutch) [6057099] + + -- Allan Nordhøy Thu, 3 Oct 2019 02:43:08 +0000 + +com.github.tkashkin.gamehub (0.14.2-33-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Added translation using Weblate (Korean) [07f10c6] + + -- ParkSeongSoo Thu, 3 Oct 2019 11:08:26 +0000 + +com.github.tkashkin.gamehub (0.14.2-32-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Performance and memory usage improvements (#57) SteamGridDB image sizes support Added menu when IGDB returns multiple results [30b9b5e] + * Image cache changes Vertical game images support [a785155] + * Translated using Weblate (German) [833d510] + + -- tkashkin Thu, 3 Oct 2019 00:54:29 +0300 + +com.github.tkashkin.gamehub (0.14.2-29-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Portuguese (Portugal)) [2a7ac4c] + + -- Manuela Silva Fri, 6 Sep 2019 10:34:38 +0000 + +com.github.tkashkin.gamehub (0.14.2-28-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Added translation using Weblate (Portuguese (Portugal)) [a5403de] + * [ci skip] Fix ellipsis in string (#301) [905f530] + + -- Manuela Silva Fri, 6 Sep 2019 10:34:09 +0000 + +com.github.tkashkin.gamehub (0.14.2-27-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (French) [f02b1a6] + * Translated using Weblate (German) [a7d2474] + * [ci skip] Update translations [654105c] + + -- Swann Martinet Tue, 3 Sep 2019 03:37:33 +0000 + +com.github.tkashkin.gamehub (0.14.2-25-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Added translation using Weblate (Arabic) [1a969ce] + + -- Omar Aglan Mon, 2 Sep 2019 01:18:30 +0000 + +com.github.tkashkin.gamehub (0.14.2-23-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Prevent multiple game launches (#280, #281) [fcb80e5] + + -- tkashkin Sat, 31 Aug 2019 20:20:47 +0300 + +com.github.tkashkin.gamehub (0.14.2-21-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Norwegian Bokmål) [404b8bb] + + -- Allan Nordhøy Wed, 28 Aug 2019 16:50:24 +0000 + +com.github.tkashkin.gamehub (0.14.2-19-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Dutch) [3821042] + * Translated using Weblate (Portuguese (Brazil)) [27c29ff] + + -- Heimen Stoffels Wed, 21 Aug 2019 14:39:18 +0000 + +com.github.tkashkin.gamehub (0.14.2-18-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Games grid size customization [8a89a89] + + -- tkashkin Wed, 21 Aug 2019 11:08:38 +0300 + +com.github.tkashkin.gamehub (0.14.2-17-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Steam-like game launch command overrides (#297) Improved GOG API error handling Small UI tweaks [075168a] + + -- tkashkin Wed, 21 Aug 2019 05:55:45 +0300 + +com.github.tkashkin.gamehub (0.14.2-16-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Refresh GOG access token on error (#294) [dfab162] + + -- tkashkin Tue, 13 Aug 2019 04:44:20 +0300 + +com.github.tkashkin.gamehub (0.14.2-15-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Telugu) [8e019ba] + + -- asher hrudai Sat, 10 Aug 2019 07:24:18 +0000 + +com.github.tkashkin.gamehub (0.14.2-14-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Added translation using Weblate (Telugu) [5d97064] + + -- asher hrudai Sat, 10 Aug 2019 07:21:39 +0000 + +com.github.tkashkin.gamehub (0.14.2-13-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Added translation using Weblate (Hindi) [f804511] + + -- asher hrudai Sat, 10 Aug 2019 07:18:28 +0000 + +com.github.tkashkin.gamehub (0.14.2-12-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix `Game.get_file()` (#291) [eecf1db] + + -- tkashkin Sun, 4 Aug 2019 13:53:49 +0300 + +com.github.tkashkin.gamehub (0.14.2-11-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Persian) [9b67620] + + -- Goudarz Jafari Fri, 2 Aug 2019 19:39:28 +0000 + +com.github.tkashkin.gamehub (0.14.2-10-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix overlays detection (#291) [6498058] + + -- tkashkin Fri, 2 Aug 2019 23:14:11 +0300 + +com.github.tkashkin.gamehub (0.14.2-9-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Add type checks in `Proton.find_proton_versions` (#292, #101) [9b022f2] + * Translated using Weblate (Persian) [d1df472] + + -- tkashkin Fri, 2 Aug 2019 17:04:44 +0300 + +com.github.tkashkin.gamehub (0.14.2-7-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Added translation using Weblate (Persian) [62adec9] + * [ci skip] Update `scripts/build.sh` [97b2775] + + -- Goudarz Jafari Fri, 2 Aug 2019 08:16:37 +0000 + +com.github.tkashkin.gamehub (0.14.2-6-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Parse `appinfo.vdf` to find Proton versions (#292, #101) [788bb28] + + -- tkashkin Wed, 31 Jul 2019 13:58:40 +0300 + +com.github.tkashkin.gamehub (0.14.2-5-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Add `/opt/` and `/var/opt/` to FSOverlay allowed paths list (#290) Wait for overlays to mount before updating game status (#291) [f28cc89] + * [ci skip] Update mirrors [4bb1b7f] + * [ci skip] Update source code mirrors [a1fb490] + + -- tkashkin Mon, 29 Jul 2019 19:58:36 +0300 + +com.github.tkashkin.gamehub (0.14.2-4-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge branch 'dev' of https://hosted.weblate.org/git/gamehub/translations into dev [9548658] + * Translated using Weblate (Portuguese (Brazil)) [0ae8e38] + * Fix sort func in `GameTagsList` Improved portability: GameHub now can be built on Windows in MSYS2 environment (doesn't work yet) [acfec61] + + -- tkashkin Sun, 28 Jul 2019 14:42:12 +0300 + +com.github.tkashkin.gamehub (0.14.2-3-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix build with older `glib` and/or without `libmanette` [42aac9c] + + -- tkashkin Fri, 26 Jul 2019 06:44:55 +0300 + +com.github.tkashkin.gamehub (0.14.2-2-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Portuguese (Brazil)) [3eda1c3] + + -- Wilker Santana da Silva Mon, 22 Jul 2019 04:52:43 +0000 + +com.github.tkashkin.gamehub (0.14.2-1-master~$VERSION_SUFFIX) $DISTRO; urgency=low + * [ci skip] Bump version [be55ac0] + + -- tkashkin Sat, 13 Jul 2019 21:26:50 +0300 + +com.github.tkashkin.gamehub (0.14.1-25-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Norwegian Bokmål) [526c6f8] + * Translated using Weblate (Dutch) [ad827dc] + + -- Allan Nordhøy Thu, 11 Jul 2019 22:51:43 +0000 + +com.github.tkashkin.gamehub (0.14.1-24-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Game details view improvements [c77df04] + * Translated using Weblate (Chinese (Simplified)) [bece03f] + * Translated using Weblate (Norwegian Bokmål) [aed8a1a] + * Translated using Weblate (Dutch) [2462da6] + + -- tkashkin Fri, 12 Jul 2019 01:23:28 +0300 + +com.github.tkashkin.gamehub (0.14.1-23-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Unset ld env variables in `Utils.run*` for AppImage builds (#267) [bd9635c] + + -- tkashkin Thu, 11 Jul 2019 03:09:29 +0300 + +com.github.tkashkin.gamehub (0.14.1-22-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Add IGDB request quota warning [f9fb59c] + + -- tkashkin Thu, 11 Jul 2019 02:59:39 +0300 + +com.github.tkashkin.gamehub (0.14.1-21-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Prioritize user games over installed games over uninstalled games when all sources are shown (#282) Fix some merging bugs [8ac1f27] + + -- tkashkin Wed, 10 Jul 2019 23:05:59 +0300 + +com.github.tkashkin.gamehub (0.14.1-20-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Chinese (Simplified)) [de84182] + + -- tofuHero Mon, 8 Jul 2019 01:21:06 +0000 + +com.github.tkashkin.gamehub (0.14.1-19-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Norwegian Bokmål) [aa1d50d] + * Translated using Weblate (Dutch) [8a917b4] + + -- Allan Nordhøy Sat, 6 Jul 2019 00:16:54 +0000 + +com.github.tkashkin.gamehub (0.14.1-18-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix slashes for DOSBox data_dirs (#279) [ff9270b] + + -- tkashkin Sat, 6 Jul 2019 20:33:46 +0300 + +com.github.tkashkin.gamehub (0.14.1-17-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * DOSBox: verbose logging for data_dirs (#279) [2f7c584] + + -- tkashkin Sat, 6 Jul 2019 19:37:42 +0300 + +com.github.tkashkin.gamehub (0.14.1-16-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Add 'Open screenshots directory' action for Steam games (#277) [8865f62] + + -- tkashkin Fri, 5 Jul 2019 20:48:47 +0300 + +com.github.tkashkin.gamehub (0.14.1-15-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * DOSBox improvements (#273) [c6bb7a8] + + -- tkashkin Fri, 5 Jul 2019 18:30:02 +0300 + +com.github.tkashkin.gamehub (0.14.1-14-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Add timeout after exiting game to prevent immediate restart due to keypresses (#275) [5dc13a8] + + -- tkashkin Thu, 4 Jul 2019 23:47:41 +0300 + +com.github.tkashkin.gamehub (0.14.1-13-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Add DOS exe/bat/com support to DOSBox CompatTool (#273) Reorder CompatTools Clear IGDB data cache for game when games is renamed (#274) [b286d46] + + -- tkashkin Thu, 4 Jul 2019 22:59:22 +0300 + +com.github.tkashkin.gamehub (0.14.1-12-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Allow to run executables in DOSBox without configs (#273) [e4b9623] + + -- tkashkin Thu, 4 Jul 2019 20:16:20 +0300 + +com.github.tkashkin.gamehub (0.14.1-11-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix Humble authentication page styles (#272) [2b9cb90] + + -- tkashkin Thu, 4 Jul 2019 12:12:42 +0300 + +com.github.tkashkin.gamehub (0.14.1-10-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix build with newer Vala compiler (#271) [9d0ff03] + + -- tkashkin Wed, 3 Jul 2019 20:25:44 +0300 + +com.github.tkashkin.gamehub (0.14.1-9-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix segfault in `GameListRow.update_style` (#255) [34b0109] + + -- tkashkin Tue, 2 Jul 2019 23:06:46 +0300 + +com.github.tkashkin.gamehub (0.14.1-8-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Reduce games list paddings (#265) [5c2fccf] + * Translated using Weblate (Norwegian Bokmål) [c199c12] + * Translated using Weblate (Dutch) [26a6755] + + -- tkashkin Mon, 1 Jul 2019 10:51:09 +0300 + +com.github.tkashkin.gamehub (0.14.1-6-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge translations [15a67ea] + * Games list grouping options (#265) [5572bc1] + * Translated using Weblate (Chinese (Simplified)) [bf75533] + * Translated using Weblate (Norwegian Bokmål) [164b834] + * Translated using Weblate (Dutch) [4c7b155] + + -- tkashkin Sun, 30 Jun 2019 17:30:25 +0300 + +com.github.tkashkin.gamehub (0.14.1-4-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Additional games list style options (#265) [e1292ae] + + -- tkashkin Sat, 29 Jun 2019 04:09:28 +0300 + +com.github.tkashkin.gamehub (0.14.1-3-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Tags can be removed (#266) Fix tags toggling (#268) [fa3012a] + + -- tkashkin Fri, 28 Jun 2019 23:49:19 +0300 + +com.github.tkashkin.gamehub (0.14.1-2-master~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix segfault when installing/downloading multiple games [a82e30a] + + -- Anatoliy Kashkin Thu, 27 Jun 2019 22:31:05 +0300 + +com.github.tkashkin.gamehub (0.14.1-1-master~$VERSION_SUFFIX) $DISTRO; urgency=low + * [ci skip] Bump version to 0.14.1 [dbb655c] + + -- tkashkin Thu, 27 Jun 2019 20:51:51 +0300 + +com.github.tkashkin.gamehub (0.14.0-42-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Remove `granite` dependency [e7bffdf] + * FS overlays can now be removed/disabled (#120, #254) `GameFSOverlaysDialog` will now show warning or error depending on game's `install_dir` (#254) [c7ddab0] + + -- tkashkin Thu, 27 Jun 2019 19:37:14 +0300 + +com.github.tkashkin.gamehub (0.14.0-40-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Norwegian Bokmål) [d78eab3] + * Translated using Weblate (Dutch) [5353619] + + -- Allan Nordhøy Tue, 25 Jun 2019 16:39:27 +0000 + +com.github.tkashkin.gamehub (0.14.0-39-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Added translation using Weblate (Greek) [371a9c9] + + -- THANOS SIOURDAKIS Tue, 25 Jun 2019 19:32:45 +0000 + +com.github.tkashkin.gamehub (0.14.0-38-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Allow multiple selection in games list Add actions for selected games (#262) Batch tag editing for selected games [f88b0a4] + * Translated using Weblate (Norwegian Bokmål) [e1d59d3] + * Translated using Weblate (Norwegian Bokmål) [78f5793] + * Translated using Weblate (Dutch) [ad15bf6] + + -- tkashkin Tue, 25 Jun 2019 15:57:09 +0300 + +com.github.tkashkin.gamehub (0.14.0-35-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Add configurable blacklists for libretro cores and game file extensions (#103) [2729433] + + -- tkashkin Sun, 23 Jun 2019 07:50:57 +0300 + +com.github.tkashkin.gamehub (0.14.0-34-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Norwegian Bokmål) [63cbf1b] + + -- Allan Nordhøy Sat, 22 Jun 2019 01:19:26 +0000 + +com.github.tkashkin.gamehub (0.14.0-33-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Games merging tweaks Update Humble Trove parsing (#32) [480c20f] + + -- tkashkin Sat, 22 Jun 2019 07:11:51 +0300 + +com.github.tkashkin.gamehub (0.14.0-32-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix trying to get nonexistent platform from Steam game info Show default icons for games in list and details [603316b] + + -- tkashkin Sat, 22 Jun 2019 04:50:10 +0300 + +com.github.tkashkin.gamehub (0.14.0-31-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge branch 'dev' of github.com:tkashkin/GameHub into dev [b19073e] + * Only match files when importing emulated games (#258) Do not try to show merged games when merging is disabled (#259) [b126539] + * Translated using Weblate (Dutch) [4f34efd] + + -- tkashkin Fri, 21 Jun 2019 23:52:14 +0300 + +com.github.tkashkin.gamehub (0.14.0-29-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Allow to skip WelcomeView when no sources are setup (#257) [4f32825] + + -- tkashkin Fri, 21 Jun 2019 01:38:55 +0300 + +com.github.tkashkin.gamehub (0.14.0-28-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Add `Emulated` as a separate platform (#103) Improved image scaling Fix images downloader popup being cut off in some cases (#249) [1543581] + * Translated using Weblate (Portuguese (Brazil)) [1288cc9] + + -- tkashkin Fri, 21 Jun 2019 00:14:30 +0300 + +com.github.tkashkin.gamehub (0.14.0-26-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (French) [19ed4a5] + * Translated using Weblate (Portuguese (Brazil)) [aa824d1] + + -- Anatoliy Kashkin Wed, 19 Jun 2019 23:40:49 +0000 + +com.github.tkashkin.gamehub (0.14.0-25-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Dutch) [ce65666] + + -- Heimen Stoffels Tue, 18 Jun 2019 10:29:42 +0000 + +com.github.tkashkin.gamehub (0.14.0-24-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Added translation using Weblate (Chinese (Traditional)) [da8a821] + + -- Jeff Huang Tue, 18 Jun 2019 04:28:47 +0000 + +com.github.tkashkin.gamehub (0.14.0-23-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Maybe fix #255 Add log filtering to hide useless debug messages [2713b16] + + -- tkashkin Tue, 18 Jun 2019 05:40:23 +0300 + +com.github.tkashkin.gamehub (0.14.0-22-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * UI tweaks [42d2657] + + -- tkashkin Tue, 18 Jun 2019 03:19:52 +0300 + +com.github.tkashkin.gamehub (0.14.0-21-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Norwegian Bokmål) [ec093ed] + * Translated using Weblate (Dutch) [e8607ba] + + -- Allan Nordhøy Mon, 17 Jun 2019 07:30:09 +0000 + +com.github.tkashkin.gamehub (0.14.0-20-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Try to also match primary game platforms (#247) [74da09f] + + -- tkashkin Mon, 17 Jun 2019 02:20:11 +0300 + +com.github.tkashkin.gamehub (0.14.0-19-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * `dconf` settings rework Theme-based icon style Filter games by platform [0f1c47b] + + -- tkashkin Mon, 17 Jun 2019 01:05:48 +0300 + +com.github.tkashkin.gamehub (0.14.0-18-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Update dput.cf [99e2a70] + * List all platforms for merged games when source is not filtered (#247) Show submenus for merged games in `GameContextMenu` [2c240b9] + * Fix dependency installation prompts in build script [adc63ca] + * `GamePropertiesDialog` tweaks Update `GameCard` and `GameListRow` when filtered source changes (#247) [69132ad] + * Fix SteamGridDB authentication (#249) IGDB description visibility settings [530e231] + * Translated using Weblate (Norwegian Bokmål) [443a90b] + * Translated using Weblate (Dutch) [d39b3e3] + * Translated using Weblate (Norwegian Bokmål) [173ebcc] + * Translated using Weblate (Norwegian Bokmål) [6b09afb] + + -- tkashkin Sun, 16 Jun 2019 06:39:31 +0300 + +com.github.tkashkin.gamehub (0.14.0-11-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge branch 'dev' of github.com:tkashkin/GameHub into dev [164e55c] + * IGDB integration [9f1d67c] + * Translated using Weblate (Norwegian Bokmål) [3f9c5dd] + * Translated using Weblate (Dutch) [362a848] + * Translated using Weblate (Portuguese (Brazil)) [2313120] + + -- tkashkin Fri, 14 Jun 2019 00:10:49 +0300 + +com.github.tkashkin.gamehub (0.14.0-9-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Simplified `ImportEmulatedGamesDialog` (#103) Images and icon patterns for custom emulators Added button to download all missing images for games Added data providers page to settings [e4486e7] + + -- tkashkin Thu, 13 Jun 2019 03:45:27 +0300 + +com.github.tkashkin.gamehub (0.14.0-8-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Norwegian Bokmål) [b100729] + * Translated using Weblate (Norwegian Bokmål) [a535e9d] + * Translated using Weblate (Norwegian Bokmål) [bfa122c] + + -- Anatoliy Kashkin Wed, 12 Jun 2019 15:29:43 +0000 + +com.github.tkashkin.gamehub (0.14.0-6-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Add game images providers [66e085e] + + -- tkashkin Wed, 12 Jun 2019 02:52:06 +0300 + +com.github.tkashkin.gamehub (0.14.0-5-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * `ImportEmulatedGamesDialog` tweaks (#103) [843d4d2] + + -- tkashkin Mon, 10 Jun 2019 19:40:38 +0300 + +com.github.tkashkin.gamehub (0.14.0-4-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Dutch) [52186ff] + + -- Heimen Stoffels Sun, 9 Jun 2019 09:55:40 +0000 + +com.github.tkashkin.gamehub (0.14.0-3-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Add emulated games scanning (#103) [f5b3ad0] + * Translated using Weblate (German) [9e366e0] + + -- tkashkin Sun, 9 Jun 2019 11:10:49 +0300 + +com.github.tkashkin.gamehub (0.14.0-2-master~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix Utils.get_language_name [96029f0] + + -- tkashkin Sat, 8 Jun 2019 03:42:44 +0300 + +com.github.tkashkin.gamehub (0.14.0-1-master~$VERSION_SUFFIX) $DISTRO; urgency=low + * Release 0.14.0 [6343d16] + * [ci skip] Update AppStream data [72d1b55] + * [ci skip] Bump version to 0.14.0 Update README.md Update screenshots [ff8ed17] + * Merge branch 'master' of github.com:tkashkin/GameHub [1f713f3] + * [ci skip] Merge pull request #172 from friday/issue-templates [fab595b] + * Create git issue templates [600652a] + * [ci skip] Update README.md [a242568] + * Merge `dev` into `master` [cd4ff2c] + + -- tkashkin Sat, 8 Jun 2019 02:58:02 +0300 + +com.github.tkashkin.gamehub (0.13.1-115-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Disable `libunity` by default, enable with `-Duse_libunity=true` [31eb28a] + * Remove `libunity-dev` from build script [ad8bc0f] + * Remove `libunity-dev` from debian dependencies [5cc0ae7] + * Translated using Weblate (Chinese (Simplified)) [0d8bea6] + * Translated using Weblate (Chinese (Simplified)) [21d8a01] + * Translated using Weblate (Polish) [39f6735] + * Added translation using Weblate (Chinese (Simplified)) [d17ad07] + + -- tkashkin Fri, 7 Jun 2019 20:03:02 +0300 + +com.github.tkashkin.gamehub (0.13.1-109-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix crash in SoupDownloader.await_queue() (#220) [9024fef] + + -- tkashkin Mon, 3 Jun 2019 21:23:12 +0300 + +com.github.tkashkin.gamehub (0.13.1-108-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Norwegian Bokmål) [d04ad42] + * Translated using Weblate (Dutch) [583c98c] + + -- Allan Nordhøy Sun, 2 Jun 2019 23:51:33 +0000 + +com.github.tkashkin.gamehub (0.13.1-107-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Queue installer downloads (#220) [87c7f3d] + * Settings dialog improvements Controller exit shortcut (#75) Ignored controllers option [f05d464] + * Translated using Weblate (German) [aa0c1c4] + + -- tkashkin Mon, 3 Jun 2019 02:35:31 +0300 + +com.github.tkashkin.gamehub (0.13.1-103-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Norwegian Bokmål) [cd2da98] + * Translated using Weblate (Dutch) [67bfd23] + + -- Allan Nordhøy Tue, 28 May 2019 12:18:45 +0000 + +com.github.tkashkin.gamehub (0.13.1-102-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Settings dialog redesign [bc53e7c] + + -- tkashkin Tue, 28 May 2019 14:48:58 +0300 + +com.github.tkashkin.gamehub (0.13.1-101-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Norwegian Bokmål) [0a3db13] + * Translated using Weblate (Dutch) [0dad19a] + * Translated using Weblate (German) [416198f] + + -- Allan Nordhøy Sun, 26 May 2019 22:05:21 +0000 + +com.github.tkashkin.gamehub (0.13.1-100-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix flatpak libs [3b52419] + + -- tkashkin Sat, 25 May 2019 10:07:35 +0300 + +com.github.tkashkin.gamehub (0.13.1-99-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix Humble collection directory name (#244) Bundle more libs for flatpak [4138055] + * Merge branch 'origin/dev' into Weblate. [201ce95] + * Translated using Weblate (Norwegian Bokmål) [723f43b] + * Translated using Weblate (Dutch) [dd634ba] + + -- tkashkin Sat, 25 May 2019 09:42:08 +0300 + +com.github.tkashkin.gamehub (0.13.1-97-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Add $platform and $platform_name variables for Collection (#244) [44ba7b8] + + -- tkashkin Sat, 25 May 2019 02:43:12 +0300 + +com.github.tkashkin.gamehub (0.13.1-96-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Bundle libmanette snapshot for flatpak [e08606c] + + -- tkashkin Fri, 24 May 2019 05:25:13 +0300 + +com.github.tkashkin.gamehub (0.13.1-95-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Bundle libmanette snapshot for flatpak because remote downloads on AppVeyor are unreliable [d7b7fdc] + * In-memory image cache CLI option to restart app with gdb and G_DEBUG=fatal-criticals [6090578] + + -- tkashkin Fri, 24 May 2019 05:11:20 +0300 + +com.github.tkashkin.gamehub (0.13.1-92-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix AppVeyor artifacts upload [b8b527e] + * Set more Wine-related env variables (#242) Don't try to init Proton prefix if it's already initialized [202e4d2] + * Fix build script [93ba8e1] + * Fix libmanette for flatpak [0062a8b] + * Build launchpad source packages for multiple distros [a40fd62] + * Build launchpad source packages for multiple distros [5cd101e] + + -- tkashkin Sun, 5 May 2019 18:43:06 +0300 + +com.github.tkashkin.gamehub (0.13.1-85-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (German) [3081514] + + -- ssantos Thu, 18 Apr 2019 18:12:16 +0000 + +com.github.tkashkin.gamehub (0.13.1-84-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (German) [488ff43] + + -- CurlingTongs Wed, 17 Apr 2019 00:32:48 +0000 + +com.github.tkashkin.gamehub (0.13.1-83-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix launchpad build script Add icon to .appdata.xml [5e849c0] + + -- tkashkin Tue, 16 Apr 2019 16:26:25 +0300 + +com.github.tkashkin.gamehub (0.13.1-82-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix running Game.update_game_info() multiple times in threads (#237) [7a4f9e1] + + -- tkashkin Sun, 14 Apr 2019 11:48:10 +0300 + +com.github.tkashkin.gamehub (0.13.1-81-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (German) [79de66d] + + -- ssantos Sat, 13 Apr 2019 21:58:23 +0000 + +com.github.tkashkin.gamehub (0.13.1-80-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Revert: Attempt to add game views in batches instead of all at once (#57) [c6994ef] + * Fix AutoSizeImage scaling Fix Games DB cache threaded crashes Attempt to add game views in batches instead of all at once (#57) [cac6092] + + -- tkashkin Thu, 11 Apr 2019 12:47:53 +0300 + +com.github.tkashkin.gamehub (0.13.1-77-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Norwegian Bokmål) [3b27e88] + * Translated using Weblate (Dutch) [e11b410] + + -- Anatoliy Kashkin Wed, 10 Apr 2019 22:17:35 +0000 + +com.github.tkashkin.gamehub (0.13.1-76-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Norwegian Bokmål) [4179176] + + -- Allan Nordhøy Wed, 10 Apr 2019 09:57:56 +0000 + +com.github.tkashkin.gamehub (0.13.1-75-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge branch 'origin/dev' into Weblate. [d3ec7c7] + * Translated using Weblate (Dutch) [c45ba0f] + + -- Hosted Weblate Wed, 10 Apr 2019 11:19:44 +0200 + +com.github.tkashkin.gamehub (0.13.1-74-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Make libunity optional Improve AutoSizeImage resizing Reimplement status indicator [07806a8] + + -- tkashkin Wed, 10 Apr 2019 12:19:35 +0300 + +com.github.tkashkin.gamehub (0.13.1-73-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Update launcher menu in GamesAdapter [642e452] + + -- tkashkin Tue, 9 Apr 2019 17:18:15 +0300 + +com.github.tkashkin.gamehub (0.13.1-72-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge branch 'origin/dev' into Weblate. [f32037e] + * Translated using Weblate (Norwegian Bokmål) [60a0416] + * Translated using Weblate (German) [af70e10] + * Translated using Weblate (Dutch) [ad3ecc9] + * Add config button to CompatToolPicker [3ac3d07] + + -- Hosted Weblate Tue, 9 Apr 2019 16:00:14 +0200 + +com.github.tkashkin.gamehub (0.13.1-70-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge branch 'dev' of github.com:tkashkin/GameHub into dev [a0d7c1a] + * GamesView refactoring (#57) [d5cb0e5] + * [ci skip] Add new Game subcategory to desktop file (#233) [9d02815] + + -- tkashkin Tue, 9 Apr 2019 16:00:55 +0300 + +com.github.tkashkin.gamehub (0.13.1-69-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Improved Steam client integration [20047cc] + + -- tkashkin Mon, 8 Apr 2019 10:17:39 +0300 + +com.github.tkashkin.gamehub (0.13.1-68-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Add controller settings (#122) [3628f0b] + + -- tkashkin Mon, 8 Apr 2019 07:52:07 +0300 + +com.github.tkashkin.gamehub (0.13.1-67-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (German) [d18ad6b] + + -- ssantos Sun, 7 Apr 2019 06:18:02 +0000 + +com.github.tkashkin.gamehub (0.13.1-66-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix GOG install segfault (#232) [abc24ad] + + -- tkashkin Wed, 3 Apr 2019 14:30:44 +0300 + +com.github.tkashkin.gamehub (0.13.1-65-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix GOG games installers parsing (#57) [cbac777] + + -- tkashkin Wed, 3 Apr 2019 12:03:17 +0300 + +com.github.tkashkin.gamehub (0.13.1-64-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Add default game icon (#204) [2334f9b] + + -- tkashkin Wed, 3 Apr 2019 10:11:30 +0300 + +com.github.tkashkin.gamehub (0.13.1-63-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Non-shallow git clone for AppVeyor [2541409] + * Fix build script [9be335f] + + -- tkashkin Wed, 3 Apr 2019 08:16:38 +0300 + +com.github.tkashkin.gamehub (0.13.1-61-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix changelogs for flatpak [422ab93] + + -- tkashkin Wed, 3 Apr 2019 07:39:57 +0300 + +com.github.tkashkin.gamehub (0.13.1-60-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Set git user for AppVeyor [1176725] + * Fix build script [bd542e3] + * Generate changelogs automatically from git commits [517a32a] + + -- tkashkin Wed, 3 Apr 2019 07:14:39 +0300 + +com.github.tkashkin.gamehub (0.13.1-57-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix appstream data [f89dc4b] + + -- tkashkin Tue, 2 Apr 2019 15:10:01 +0300 + +com.github.tkashkin.gamehub (0.13.1-54-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix libunity dependency for flatpak [5741f06] + + -- tkashkin Tue, 2 Apr 2019 14:41:09 +0300 + +com.github.tkashkin.gamehub (0.13.1-53-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * More null checks for GOG player stats (#228) [1acb171] + + -- tkashkin Sun, 31 Mar 2019 21:30:37 +0300 + +com.github.tkashkin.gamehub (0.13.1-52-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Norwegian Bokmål) [5cd0e94] + * Translated using Weblate (Dutch) [81a9fa1] + + -- Allan Nordhøy Sun, 31 Mar 2019 10:26:40 +0000 + +com.github.tkashkin.gamehub (0.13.1-51-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge branch 'dev' of github.com:tkashkin/GameHub into dev [0f1c862] + * [ci skip] Update issue templates (#212) [701f14e] + + -- tkashkin Sat, 30 Mar 2019 23:47:17 +0300 + +com.github.tkashkin.gamehub (0.13.1-50-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge branch 'origin/dev' into Weblate. [30fb590] + * Translated using Weblate (Turkish) [23377e7] + * About dialog (#212) [069613e] + + -- Hosted Weblate Sat, 30 Mar 2019 21:30:24 +0100 + +com.github.tkashkin.gamehub (0.13.1-48-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Use case-insensitive paths for Steam (#227) [f6b77e8] + + -- tkashkin Fri, 29 Mar 2019 18:12:25 +0300 + +com.github.tkashkin.gamehub (0.13.1-47-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Implement libunity quicklist and progress (#225) [3084beb] + * Allow multiple merged games from same source (#224) [8ccd0ca] + + -- tkashkin Fri, 29 Mar 2019 03:57:19 +0300 + +com.github.tkashkin.gamehub (0.13.1-45-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Enter to run first matching game in search (#223) [f9fd217] + + -- tkashkin Thu, 28 Mar 2019 22:13:38 +0300 + +com.github.tkashkin.gamehub (0.13.1-44-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * GAction-based hotkeys [5bf5bdd] + + -- tkashkin Thu, 28 Mar 2019 20:57:47 +0300 + +com.github.tkashkin.gamehub (0.13.1-43-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix .gameinfo-background background-color for Pop!_OS GTK theme [974067a] + + -- tkashkin Thu, 28 Mar 2019 04:07:53 +0300 + +com.github.tkashkin.gamehub (0.13.1-42-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Add "Proton (latest)" to compat tools list (#222) [5f7bd3b] + + -- tkashkin Wed, 27 Mar 2019 17:14:55 +0300 + +com.github.tkashkin.gamehub (0.13.1-41-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge pull request #221 from Lucki/patch-1 [ade4818] + * Add Proton 4.2 [837530a] + + -- Anatoliy Kashkin Wed, 27 Mar 2019 02:28:05 +0300 + +com.github.tkashkin.gamehub (0.13.1-40-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Norwegian Bokmål) [592ba39] + * Translated using Weblate (German) [9f33b47] + * Translated using Weblate (Dutch) [059e6c5] + + -- Allan Nordhøy Sat, 23 Mar 2019 01:20:27 +0000 + +com.github.tkashkin.gamehub (0.13.1-39-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix long titles in games grid (#219) [41668e6] + + -- tkashkin Sun, 24 Mar 2019 22:54:05 +0300 + +com.github.tkashkin.gamehub (0.13.1-38-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix FSUtils.mv_up() to allow directories merging (#216) [bec8757] + + -- tkashkin Sun, 24 Mar 2019 17:02:27 +0300 + +com.github.tkashkin.gamehub (0.13.1-37-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Add option to run games with double click (#213) [41d8c8f] + + -- tkashkin Fri, 22 Mar 2019 23:25:20 +0300 + +com.github.tkashkin.gamehub (0.13.1-36-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Bump minimal innoextract version to 1.8 (#208) [169dc6e] + + -- tkashkin Fri, 22 Mar 2019 22:19:36 +0300 + +com.github.tkashkin.gamehub (0.13.1-35-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix `is_game_merged` db query (#210, #211) [db1b38a] + + -- tkashkin Fri, 22 Mar 2019 19:04:16 +0300 + +com.github.tkashkin.gamehub (0.13.1-34-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge pull request #205 from Lucki/patch-1 [e1d8f5c] + * Make overlays remountable [f0b0044] + + -- Anatoliy Kashkin Tue, 12 Mar 2019 01:04:23 +0300 + +com.github.tkashkin.gamehub (0.13.1-33-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Norwegian Bokmål) [efc9541] + + -- Allan Nordhøy Thu, 7 Mar 2019 11:04:32 +0000 + +com.github.tkashkin.gamehub (0.13.1-32-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Added translation using Weblate (Turkish) [e4c792a] + + -- Kemal Oktay Aktoğan Fri, 8 Mar 2019 09:06:00 +0000 + +com.github.tkashkin.gamehub (0.13.1-31-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Norwegian Bokmål) [ac109bf] + + -- Allan Nordhøy Sun, 24 Feb 2019 02:28:40 +0000 + +com.github.tkashkin.gamehub (0.13.1-30-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge pull request #200 from spinozaure/flatpak-fixes [f6eb643] + * Change 32bit library path for flatpak [269393c] + + -- Anatoliy Kashkin Mon, 18 Feb 2019 22:07:12 +0300 + +com.github.tkashkin.gamehub (0.13.1-29-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Move app/__support/app to game's install_dir for innoextract (#197) [cd84abf] + + -- tkashkin Fri, 15 Feb 2019 14:59:00 +0300 + +com.github.tkashkin.gamehub (0.13.1-28-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Change Steam packages check for elementary (#199) [3254279] + + -- tkashkin Thu, 14 Feb 2019 17:37:30 +0300 + +com.github.tkashkin.gamehub (0.13.1-27-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * FSUtils.mv_up() dir existence check [d48c261] + + -- tkashkin Thu, 14 Feb 2019 11:10:57 +0300 + +com.github.tkashkin.gamehub (0.13.1-26-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Quickfix for #197 (#198) [e558a6b] + + -- neuromancer Thu, 14 Feb 2019 05:05:43 -0300 + +com.github.tkashkin.gamehub (0.13.1-25-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix GOG Windows game actions parsing if FSOverlays are enabled (#120) [678b18e] + + -- tkashkin Wed, 13 Feb 2019 22:35:32 +0300 + +com.github.tkashkin.gamehub (0.13.1-24-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Move game files from _gamehub_{game|app}_root for InnoSetup games installed with Wine/Proton (#192) [bee3890] + + -- tkashkin Tue, 12 Feb 2019 13:32:10 +0300 + +com.github.tkashkin.gamehub (0.13.1-23-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * FileChooserEntry.set_default_directory (#182) UI tweaks [3b43850] + + -- tkashkin Tue, 12 Feb 2019 12:53:01 +0300 + +com.github.tkashkin.gamehub (0.13.1-22-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Update LINGUAS [a0af8c9] + * Translated using Weblate (French) [0ef1423] + * Deleted translation using Weblate (French) [2e8457e] + + -- Anatoliy Kashkin Mon, 11 Feb 2019 17:13:03 +0300 + +com.github.tkashkin.gamehub (0.13.1-20-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Added translation using Weblate (French) [4ecf8bf] + + -- King Claudy Mon, 11 Feb 2019 10:18:51 +0000 + +com.github.tkashkin.gamehub (0.13.1-19-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (German) [360dd70] + + -- ssantos Fri, 8 Feb 2019 13:42:08 +0000 + +com.github.tkashkin.gamehub (0.13.1-18-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix game args parsing (#194) [eef7ba5] + + -- tkashkin Wed, 6 Feb 2019 23:05:05 +0300 + +com.github.tkashkin.gamehub (0.13.1-17-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Dutch) [bf41a58] + + -- Anatoliy Kashkin Tue, 5 Feb 2019 20:27:46 +0000 + +com.github.tkashkin.gamehub (0.13.1-16-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Dutch) [b749939] + + -- Heimen Stoffels Tue, 5 Feb 2019 12:28:59 +0000 + +com.github.tkashkin.gamehub (0.13.1-15-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix broken AppVeyor build by installing fakeroot in build script explicitly [0f0167e] + * Remove max_width_chars for compat tool warnings [b098dee] + * Warn user if the innoextract is not up-to-date (#193) [68f4a5f] + + -- tkashkin Tue, 5 Feb 2019 06:43:26 +0300 + +com.github.tkashkin.gamehub (0.13.1-12-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Small fixes GOG DLC UI improvements [ea5cc72] + + -- tkashkin Mon, 4 Feb 2019 13:30:52 +0300 + +com.github.tkashkin.gamehub (0.13.1-11-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Remember GOG bonus content filenames Improve GOG bonus content UI [d44618d] + + -- tkashkin Mon, 4 Feb 2019 11:49:16 +0300 + +com.github.tkashkin.gamehub (0.13.1-10-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Small UI fixes [0abbc80] + + -- tkashkin Mon, 4 Feb 2019 10:32:29 +0300 + +com.github.tkashkin.gamehub (0.13.1-9-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Expand `~` in FileChooserEntry [85d1268] + * Fix #190 [fe36384] + * Merge branch 'dev' of github.com:tkashkin/GameHub into dev [cae97d1] + * Translated using Weblate (German) [d7ef194] + * Merge branch 'dev' of github.com:tkashkin/GameHub into dev [ef0d8e5] + * Merge branch 'master' into dev [cd7e38c] + * Merge `dev` into `master` [72b076b] + * [ci skip] Merge dev into master [3fe313b] + + -- tkashkin Mon, 4 Feb 2019 09:13:10 +0300 + +com.github.tkashkin.gamehub (0.13.1-5-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Polish) [b55aeb8] + * Translated using Weblate (Polish) [4ec002d] + + -- Anatoliy Kashkin Mon, 4 Feb 2019 02:39:45 +0000 + +com.github.tkashkin.gamehub (0.13.1-2-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Added translation using Weblate (Polish) [a7225b5] + + -- AngryPenguinPL Mon, 4 Feb 2019 00:20:58 +0000 + +com.github.tkashkin.gamehub (0.13.1-1-master~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge branch 'master' of github.com:tkashkin/GameHub [1f713f3] + * Merge branch 'master' into dev [cd7e38c] + * [ci skip] Prepare 0.13.1 [03fdbe5] + * Translated using Weblate (German) [512af52] + * [ci skip] Merge pull request #172 from friday/issue-templates [fab595b] + * Create git issue templates [600652a] + * [ci skip] Update README.md [a242568] + * Merge `dev` into `master` [cd4ff2c] + * Merge `dev` into `master` [72b076b] + * [ci skip] Merge dev into master [3fe313b] + + -- tkashkin Mon, 28 Jan 2019 19:30:30 +0300 + +com.github.tkashkin.gamehub (0.13.0-19-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix controller button hints for accented headerbar on elementary (#170) [cdf4a0f] + + -- tkashkin Wed, 23 Jan 2019 20:09:33 +0300 + +com.github.tkashkin.gamehub (0.13.0-18-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge branch 'origin/dev' into Weblate. [7dc1619] + * Translated using Weblate (German) [ec198b7] + * Possibly fix Humble token escaping (#32, #9) [3dd7dbe] + + -- Hosted Weblate Wed, 23 Jan 2019 15:02:19 +0100 + +com.github.tkashkin.gamehub (0.13.0-16-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix welcome screen flat titlebar text/buttons color (#170) [c975c2a] + + -- tkashkin Wed, 23 Jan 2019 05:33:37 +0300 + +com.github.tkashkin.gamehub (0.13.0-15-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Add primary color for elementary theme (#170) More verbose logging for Humble Trove with `--verbose` option (#32) [3c67adf] + + -- tkashkin Wed, 23 Jan 2019 05:08:53 +0300 + +com.github.tkashkin.gamehub (0.13.0-14-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Update icon (#170) Add purple accent color Fix compat regression with previous commit [e380a84] + + -- tkashkin Wed, 23 Jan 2019 00:33:58 +0300 + +com.github.tkashkin.gamehub (0.13.0-13-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Probably fix install_dir after uninstalling and changing games directory (#111) Fix some games not saving in database after 352ba23 [4c53b00] + + -- tkashkin Tue, 22 Jan 2019 19:26:01 +0300 + +com.github.tkashkin.gamehub (0.13.0-12-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Norwegian Bokmål) [5e3d6f0] + * Translated using Weblate (Dutch) [4134253] + + -- Allan Nordhøy Sun, 20 Jan 2019 20:08:46 +0000 + +com.github.tkashkin.gamehub (0.13.0-11-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Remove Steam Runtime libraries since they are not used (#181) [4011083] + + -- tkashkin Sun, 20 Jan 2019 22:41:05 +0300 + +com.github.tkashkin.gamehub (0.13.0-10-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Add a warning if games directory contains space (#111) [07068e5] + + -- tkashkin Sun, 20 Jan 2019 22:38:50 +0300 + +com.github.tkashkin.gamehub (0.13.0-9-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Dutch) [7ef671b] + + -- Heimen Stoffels Sun, 20 Jan 2019 11:13:57 +0000 + +com.github.tkashkin.gamehub (0.13.0-8-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge branch 'origin/dev' into Weblate. [1760318] + * Translated using Weblate (Norwegian Bokmål) [e51aa9f] + * Don't fetch Humble orders if they are not changed (#57) Temporarily disable `update_games()` to test [352ba23] + + -- Hosted Weblate Sun, 20 Jan 2019 11:44:53 +0100 + +com.github.tkashkin.gamehub (0.13.0-6-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix moving children up from inner directory for installed games Fix xgettext not extracting some strings due to having a forward slash in source file anywhere before these strings [04ab0ed] + + -- tkashkin Sun, 20 Jan 2019 02:17:47 +0300 + +com.github.tkashkin.gamehub (0.13.0-5-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Remove sleeps while adding games (#57) Add games to GamesView in batches [06749a4] + + -- tkashkin Sat, 19 Jan 2019 19:54:34 +0300 + +com.github.tkashkin.gamehub (0.13.0-4-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix Humble games install path after uninstalling Fix having multiple instances of same Game in memory in some cases (for example if game properties dialog is opened via notification): * Fix cases when properties dialog used another Game instance and changes were not updating for the first instance * Slightly reduce memory usage [8263dd6] + + -- tkashkin Sat, 19 Jan 2019 17:17:30 +0300 + +com.github.tkashkin.gamehub (0.13.0-3-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Norwegian Bokmål) [d3f5249] + * Translated using Weblate (Dutch) [ef04ff5] + * Merge remote-tracking branch 'weblate/dev' into dev [fb92145] + * Translated using Weblate (Dutch) [13bda3a] + + -- Allan Nordhøy Wed, 16 Jan 2019 23:24:57 +0000 + +com.github.tkashkin.gamehub (0.13.0-2-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Less verbose logging by default [e2604e5] + + -- tkashkin Wed, 16 Jan 2019 17:06:58 +0300 + +com.github.tkashkin.gamehub (0.13.0-1-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Bump version Update copyright years [4610e43] + + -- tkashkin Wed, 16 Jan 2019 13:25:18 +0300 + +com.github.tkashkin.gamehub (0.12.1-91-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Experimental version with ThreadPool thread count option (#57) [cd55bb5] + + -- tkashkin Wed, 16 Jan 2019 01:42:32 +0300 + +com.github.tkashkin.gamehub (0.12.1-90-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge branch 'origin/dev' into Weblate. [9d98a71] + * Translated using Weblate (Norwegian Bokmål) [6ebe38d] + * Notify user if executable for game can't be detected automatically (#157) Fix Proton prefix initialization [a0512ca] + + -- Hosted Weblate Tue, 15 Jan 2019 23:18:33 +0100 + +com.github.tkashkin.gamehub (0.12.1-88-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge branch 'origin/dev' into Weblate. [534de0c] + * Translated using Weblate (Norwegian Bokmål) [ae095ce] + + -- Hosted Weblate Tue, 15 Jan 2019 22:53:28 +0100 + +com.github.tkashkin.gamehub (0.12.1-87-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * New GActions and CLI options Better installer checksum mismatch handling for DEs which do not support buttons in notifications [a09fdda] + + -- tkashkin Wed, 16 Jan 2019 00:53:19 +0300 + +com.github.tkashkin.gamehub (0.12.1-86-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (French) [272ad4d] + + -- Anatoliy Kashkin Tue, 15 Jan 2019 16:25:27 +0000 + +com.github.tkashkin.gamehub (0.12.1-85-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Dutch) [21cd5dc] + + -- Heimen Stoffels Tue, 15 Jan 2019 11:00:24 +0000 + +com.github.tkashkin.gamehub (0.12.1-84-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge remote-tracking branch 'weblate/dev' into dev [484412b] + * Translated using Weblate (Norwegian Bokmål) [739e575] + + -- tkashkin Tue, 15 Jan 2019 13:44:03 +0300 + +com.github.tkashkin.gamehub (0.12.1-83-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Rework CLI options parsing (#175) Restart with GDB in the same terminal session (#172) [0bbe7ee] + + -- tkashkin Tue, 15 Jan 2019 13:39:00 +0300 + +com.github.tkashkin.gamehub (0.12.1-82-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge branch 'origin/dev' into Weblate. [c2541cb] + * Translated using Weblate (Norwegian Bokmål) [6ca0a09] + + -- Hosted Weblate Tue, 15 Jan 2019 00:23:13 +0100 + +com.github.tkashkin.gamehub (0.12.1-81-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Add a CLI option to run with GDB attached (#172) [4f2e093] + * [ci skip] Remove unused strings, try to fix a few bugged plurals for Weblate [c7f6bef] + + -- tkashkin Tue, 15 Jan 2019 02:23:00 +0300 + +com.github.tkashkin.gamehub (0.12.1-80-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Prettier log Don't capture child process output when it's not needed Possibly fix #163 [841b051] + * [ci skip] Fix option group name to fit better with default GTK help [af68fda] + + -- tkashkin Mon, 14 Jan 2019 19:09:40 +0300 + +com.github.tkashkin.gamehub (0.12.1-79-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Russian) [d07f4b3] + + -- Anatoliy Kashkin Mon, 14 Jan 2019 12:16:12 +0000 + +com.github.tkashkin.gamehub (0.12.1-78-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Norwegian Bokmål) [8f8563d] + + -- Allan Nordhøy Sun, 13 Jan 2019 21:31:47 +0000 + +com.github.tkashkin.gamehub (0.12.1-77-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge branch 'dev' of github.com:tkashkin/GameHub into dev [52da673] + * Pass git branch and commit via meson options (#172) [5c7c5cd] + + -- tkashkin Sun, 13 Jan 2019 22:35:44 +0300 + +com.github.tkashkin.gamehub (0.12.1-76-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge branch 'origin/dev' into Weblate. [8c28072] + * Translated using Weblate (Dutch) [5e7b1c1] + * Call Application.init() after printing version (#172) [0707816] + * [ci skip] Update issue templates (#172) [c40d2e8] + * [ci skip] Create git issue templates (#172) [3012de1] + * Merge branch 'origin/dev' into Weblate. [5fc975a] + * Translated using Weblate (Dutch) [cf1f402] + + -- Hosted Weblate Sun, 13 Jan 2019 19:47:03 +0100 + +com.github.tkashkin.gamehub (0.12.1-73-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Add `--version`/`-v` option (#172) Add `--log-workers` option (#172) Migrate to `Gtk.Application` from `Granite.Application` [70741b5] + + -- tkashkin Sun, 13 Jan 2019 20:59:36 +0300 + +com.github.tkashkin.gamehub (0.12.1-72-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Make auth and downloader logging optional and disabled by default (#172) [93f62c1] + + -- tkashkin Sun, 13 Jan 2019 19:21:24 +0300 + +com.github.tkashkin.gamehub (0.12.1-71-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Add a bit more height to compact ActionButton (#165, #171) [82debb2] + + -- tkashkin Sun, 13 Jan 2019 03:35:29 +0300 + +com.github.tkashkin.gamehub (0.12.1-70-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Compact ActionButton (#165, #171) [684568d] + + -- tkashkin Sun, 13 Jan 2019 03:29:17 +0300 + +com.github.tkashkin.gamehub (0.12.1-69-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge branch 'dev' of github.com:tkashkin/GameHub into dev [ec1c3e4] + * Fix headerbar buttons valign (#165) [c95609a] + + -- tkashkin Sun, 13 Jan 2019 01:08:26 +0300 + +com.github.tkashkin.gamehub (0.12.1-68-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge branch 'origin/dev' into Weblate. [ca747d2] + * Translated using Weblate (Norwegian Bokmål) [ae349ab] + * Translated using Weblate (Dutch) [9ae4503] + * Use smaller icons for headerbar if symbolic (#165) [acbd2aa] + + -- Hosted Weblate Sat, 12 Jan 2019 23:01:18 +0100 + +com.github.tkashkin.gamehub (0.12.1-66-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge branch 'origin/dev' into Weblate. [03b2a09] + * Translated using Weblate (Norwegian Bokmål) [3b15c50] + * Translated using Weblate (Dutch) [b40b1de] + * Add an option to use symbolic icons (#165) [3a15402] + + -- Hosted Weblate Sat, 12 Jan 2019 21:12:40 +0100 + +com.github.tkashkin.gamehub (0.12.1-64-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Russian) [108c6de] + * Update localization files [891f938] + * Support custom Wine/Proton prefixes (#160) [9d953c6] + + -- Anatoliy Kashkin Sat, 12 Jan 2019 17:44:08 +0000 + +com.github.tkashkin.gamehub (0.12.1-61-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Replace download checkbox with a button (#168) [1a7b13a] + + -- tkashkin Sat, 12 Jan 2019 11:59:01 +0300 + +com.github.tkashkin.gamehub (0.12.1-60-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (French) [1537eed] + + -- King Claudy Wed, 9 Jan 2019 20:55:32 +0000 + +com.github.tkashkin.gamehub (0.12.1-59-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Check for `wingpanel` gsettings schema before trying to use `Granite.DateTime.get_relative_datetime` (#164) [2e06716] + + -- tkashkin Tue, 8 Jan 2019 09:15:10 +0300 + +com.github.tkashkin.gamehub (0.12.1-58-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Split installers list by platform (#167) [d9364a7] + + -- tkashkin Tue, 8 Jan 2019 05:21:35 +0300 + +com.github.tkashkin.gamehub (0.12.1-57-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Russian) [5a833c2] + + -- Anatoliy Kashkin Tue, 8 Jan 2019 01:23:14 +0000 + +com.github.tkashkin.gamehub (0.12.1-56-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge games by normalized name (#166) [b3cece5] + + -- tkashkin Tue, 8 Jan 2019 04:12:25 +0300 + +com.github.tkashkin.gamehub (0.12.1-55-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Sort games by normalized names (#166) [ee86ced] + + -- tkashkin Tue, 8 Jan 2019 04:08:47 +0300 + +com.github.tkashkin.gamehub (0.12.1-54-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Use linuxdeployqt 5 instead of continuous due to https://github.com/probonopd/linuxdeployqt/issues/340 Revert to building a separate debian source package [8e9fc46] + * `*_amd64.changes` -> `*_source.changes` [f17330f] + * Rename *_amd64.changes to *.changes [ad701ad] + * `sed` -> `sed -i` [8bd4054] + * Modify .changes to convert debian package to a source-only package [234eb59] + * Merge branch 'origin/dev' into Weblate. [6e9fa63] + * Translated using Weblate (French) [2b9fd27] + * Fix launchpad upload to not try to upload binary [42d895f] + * Added translation using Weblate (French) [3032b26] + + -- tkashkin Mon, 7 Jan 2019 18:28:40 +0300 + +com.github.tkashkin.gamehub (0.12.1-44-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Portuguese (Brazil)) [e05ce9b] + + -- Leandro Stanger Tue, 1 Jan 2019 00:00:55 +0000 + +com.github.tkashkin.gamehub (0.12.1-43-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge branch 'origin/dev' into Weblate. [5bfaa0c] + * Translated using Weblate (Dutch) [99fd3e2] + * Parse game actions from gameinfo for GOG Windows games Set executable and arguments automatically for Windows GOG games using primary action when possible (#157) [d02c24c] + + -- Hosted Weblate Sat, 29 Dec 2018 01:42:41 +0100 + +com.github.tkashkin.gamehub (0.12.1-41-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Add Proton 3.16 Beta id (#101) Fix Proton prefix init Add simple download speed counter [1825920] + + -- tkashkin Fri, 28 Dec 2018 14:48:35 +0300 + +com.github.tkashkin.gamehub (0.12.1-40-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix changelog syntax [11c751f] + * Update build scripts [1f7aaf7] + * Update README.md (#108) [e989add] + + -- tkashkin Fri, 28 Dec 2018 13:11:17 +0300 + +com.github.tkashkin.gamehub (0.12.1-37-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix Humble Trove url signing (#32) [4798294] + + -- tkashkin Fri, 21 Dec 2018 18:49:01 +0300 + +com.github.tkashkin.gamehub (0.12.1-36-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Update Humble Trove support (#32) [9d040db] + + -- tkashkin Fri, 21 Dec 2018 17:08:08 +0300 + +com.github.tkashkin.gamehub (0.12.1-35-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Probably fix #154 [28e6f8d] + + -- tkashkin Thu, 20 Dec 2018 18:59:37 +0300 + +com.github.tkashkin.gamehub (0.12.1-34-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Quick fix for #146 (#147) [a8970ce] + + -- neuromancer Wed, 19 Dec 2018 10:53:05 -0300 + +com.github.tkashkin.gamehub (0.12.1-33-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Norwegian Bokmål) [aa5174a] + * Translated using Weblate (German) [a222b57] + * Translated using Weblate (Dutch) [3161f00] + + -- Allan Nordhøy Sun, 16 Dec 2018 06:12:12 +0000 + +com.github.tkashkin.gamehub (0.12.1-32-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * msi installer support (#151) Installer checksum mismatch notification [46cf5b4] + * Translated using Weblate (Norwegian Bokmål) [1330dbb] + * Translated using Weblate (German) [370e7e2] + * Translated using Weblate (Dutch) [81bf8ec] + + -- tkashkin Sun, 16 Dec 2018 03:40:45 +0300 + +com.github.tkashkin.gamehub (0.12.1-30-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge branch 'dev' of github.com:tkashkin/GameHub into dev [3f8460b] + * Update WineWrap integration (#108) Implement installer hash checks (#29) [3ac55b0] + + -- tkashkin Sat, 15 Dec 2018 01:52:23 +0300 + +com.github.tkashkin.gamehub (0.12.1-29-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (German) [2bfb81c] + + -- ssantos Sat, 8 Dec 2018 17:21:11 +0000 + +com.github.tkashkin.gamehub (0.12.1-28-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Norwegian Bokmål) [56399f6] + * Translated using Weblate (Dutch) [18242b8] + + -- Allan Nordhøy Fri, 7 Dec 2018 18:02:46 +0000 + +com.github.tkashkin.gamehub (0.12.1-27-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge branch 'origin/dev' into Weblate [db10ad3] + * Translated using Weblate (Norwegian Bokmål) [0f94487] + * Translated using Weblate (German) [e7efc06] + * Add binary vdf parser/writer Add games to the Steam library (#149) [d5add8c] + + -- Hosted Weblate Fri, 7 Dec 2018 07:42:18 +0100 + +com.github.tkashkin.gamehub (0.12.1-25-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge branch 'origin/dev' into Weblate [5beeebc] + * Translated using Weblate (Dutch) [11fb981] + * Bundle polkit for flatpak [91b5060] + * Fix run args margin [6335c6c] + * Command line option to run game (#149) [e4a9f54] + + -- Hosted Weblate Thu, 6 Dec 2018 14:16:05 +0100 + +com.github.tkashkin.gamehub (0.12.1-18-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Save version of used installer (GOG only) (#148) Show updates indicator for updated GOG games (#78) [b479cbd] + + -- tkashkin Sun, 2 Dec 2018 22:00:46 +0300 + +com.github.tkashkin.gamehub (0.12.1-17-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (German) [16c13da] + * Translated using Weblate (Russian) [d149357] + * Translated using Weblate (German) [5aa2dd0] + * Translated using Weblate (Dutch) [1cf730a] + * Translated using Weblate (Dutch) [1a3ddd3] + + -- Ettore Atalan Fri, 30 Nov 2018 01:47:21 +0000 + +com.github.tkashkin.gamehub (0.12.1-15-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Initial integration with adamhm's wine wrappers (#108) [a2efef1] + + -- tkashkin Wed, 28 Nov 2018 12:06:57 +0300 + +com.github.tkashkin.gamehub (0.12.1-14-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (German) [c64e772] + * Translated using Weblate (German) [732a22a] + * Translated using Weblate (German) [9f4e56c] + + -- Anatoliy Kashkin Tue, 27 Nov 2018 13:50:44 +0000 + +com.github.tkashkin.gamehub (0.12.1-11-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Added translation using Weblate (German) [9b045a7] + * Translated using Weblate (Indonesian) [8be6cd4] + * Translated using Weblate (Dutch) [ec6702a] + + -- jonathanschaefer Mon, 26 Nov 2018 17:58:45 +0000 + +com.github.tkashkin.gamehub (0.12.1-9-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Added translation using Weblate (Dutch) [e4e8423] + + -- Heimen Stoffels Sat, 24 Nov 2018 16:27:37 +0000 + +com.github.tkashkin.gamehub (0.12.1-8-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Translated using Weblate (Indonesian) [c590c09] + * Translated using Weblate (Norwegian Bokmål) [0630207] + * Translated using Weblate (Russian) [8077361] + + -- Anatoliy Kashkin Sat, 24 Nov 2018 09:37:02 +0000 + +com.github.tkashkin.gamehub (0.12.1-6-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix option to hide icons (#141) [7559ff7] + + -- tkashkin Wed, 21 Nov 2018 07:28:45 +0300 + +com.github.tkashkin.gamehub (0.12.1-4-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix nb_NO translation [ad49c12] + * Merge remote-tracking branch 'weblate/dev' into dev [3236a82] + * Add an option to hide icons in grid view (#141) [ff3ff38] + * Merge branch 'origin/dev' into Weblate [9c65aed] + * [ci skip] Update README.md [d0bd26f] + * Translated using Weblate (Norwegian Bokmål) [8b057a3] + * Translated using Weblate (Norwegian Bokmål) [b338984] + * Translated using Weblate (Norwegian Bokmål) [7135c95] + + -- tkashkin Wed, 21 Nov 2018 06:13:20 +0300 + +com.github.tkashkin.gamehub (0.12.1-1-master~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge `dev` into `master` [cd4ff2c] + * [ci skip] Bump version [0a1e7d6] + * [ci skip] Fix broken weblate [b360886] + * Merge `dev` into `master` [72b076b] + * [ci skip] Merge dev into master [3fe313b] + + -- Anatoliy Kashkin Tue, 20 Nov 2018 02:08:28 +0300 + +com.github.tkashkin.gamehub (0.12.0-16-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * More secure polkit policy (#120) [09c458a] + + -- tkashkin Sun, 18 Nov 2018 23:16:07 +0300 + +com.github.tkashkin.gamehub (0.12.0-15-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Playtime sort mode (#139) [a828310] + * [ci skip] Update pt_BR.po (#140) [ad86a6f] + + -- tkashkin Tue, 13 Nov 2018 04:57:12 +0300 + +com.github.tkashkin.gamehub (0.12.0-14-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Add running indicator (#138) [a4cd434] + + -- tkashkin Mon, 12 Nov 2018 16:39:01 +0300 + +com.github.tkashkin.gamehub (0.12.0-13-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * UI tweaks [9a14a0e] + + -- tkashkin Mon, 12 Nov 2018 05:54:37 +0300 + +com.github.tkashkin.gamehub (0.12.0-12-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Import playtime from Steam and GOG Show version for installed native GOG games Improve image rendering in AutoSizeImage [49018e2] + + -- tkashkin Mon, 12 Nov 2018 02:25:20 +0300 + +com.github.tkashkin.gamehub (0.12.0-10-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Achievements (#130) [9b5535e] + + -- tkashkin Sun, 11 Nov 2018 06:20:39 +0300 + +com.github.tkashkin.gamehub (0.12.0-9-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Add ScummVM (#52) [187c708] + * Allow to launch custom emulators from game directory (#52) [cd8105d] + + -- tkashkin Sun, 11 Nov 2018 02:24:07 +0300 + +com.github.tkashkin.gamehub (0.12.0-7-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix images update in GamePropertiesDialog (#131) [3a5473a] + + -- tkashkin Sun, 11 Nov 2018 00:54:58 +0300 + +com.github.tkashkin.gamehub (0.12.0-6-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Update xenial deps to fix xenial AppVeyor build [25b2a01] + + -- tkashkin Sat, 10 Nov 2018 23:17:15 +0300 + +com.github.tkashkin.gamehub (0.12.0-5-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix FileChooserEntry (#131) [484aee5] + * [ci skip] Update pt_BR localization (#135) [6af5df4] + + -- tkashkin Sat, 10 Nov 2018 22:34:19 +0300 + +com.github.tkashkin.gamehub (0.12.0-4-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Replace FileChooserButtons with custom FileChooserEntry (#131) [fca3a8a] + + -- tkashkin Sat, 10 Nov 2018 05:04:40 +0300 + +com.github.tkashkin.gamehub (0.12.0-3-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix #114 [bcae45c] + + -- tkashkin Fri, 9 Nov 2018 03:51:38 +0300 + +com.github.tkashkin.gamehub (0.12.0-1-master~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge `dev` into `master` [72b076b] + * [ci skip] 0.12.0 [e03158d] + * [ci skip] Merge dev into master [3fe313b] + + -- Anatoliy Kashkin Fri, 9 Nov 2018 01:34:01 +0300 + +com.github.tkashkin.gamehub (0.11.7-8-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Update localization template [de1064b] + + -- tkashkin Thu, 8 Nov 2018 23:28:08 +0300 + +com.github.tkashkin.gamehub (0.11.7-7-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * One more fix for #124 [28d9a7b] + * Probably fix #124 [877f42b] + + -- tkashkin Thu, 8 Nov 2018 15:25:58 +0300 + +com.github.tkashkin.gamehub (0.11.7-5-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix build with GTK < 3.22 [27c7e4f] + + -- tkashkin Thu, 8 Nov 2018 02:35:44 +0300 + +com.github.tkashkin.gamehub (0.11.7-4-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Implement #126 [cc8ed76] + + -- tkashkin Thu, 8 Nov 2018 02:06:33 +0300 + +com.github.tkashkin.gamehub (0.11.7-3-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fixes for #120 [1c78c4f] + * Fixes for #120 Update screenshots in AppStream data [9148625] + * [ci skip] Update README.md [489ac63] + * [ci skip] Update README.md and screenshots [8b321ac] + * [ci skip] Update README.md [769284e] + * [ci skip] Update README.md, Fix #123 [5a232b4] + + -- tkashkin Wed, 7 Nov 2018 22:49:19 +0300 + +com.github.tkashkin.gamehub (0.11.7-1-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Overlays (#120) [2071a8e] + + -- tkashkin Mon, 5 Nov 2018 05:48:50 +0300 + +com.github.tkashkin.gamehub (0.11.6-15-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix build with polkit [9968cc2] + + -- tkashkin Sun, 4 Nov 2018 16:48:43 +0300 + +com.github.tkashkin.gamehub (0.11.6-14-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Initial OverlayFS impplementation for #120 [e36f1b5] + + -- tkashkin Sun, 4 Nov 2018 16:20:16 +0300 + +com.github.tkashkin.gamehub (0.11.6-13-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Wine/Proton improvements Bugfixes for #106 [f4a4847] + + -- tkashkin Sun, 4 Nov 2018 02:31:55 +0300 + +com.github.tkashkin.gamehub (0.11.6-12-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Custom emulators can be installed with installers (#106) [0f374be] + + -- tkashkin Sat, 3 Nov 2018 23:08:49 +0300 + +com.github.tkashkin.gamehub (0.11.6-11-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * UI improvements [d6eccf5] + + -- tkashkin Sat, 3 Nov 2018 18:49:56 +0300 + +com.github.tkashkin.gamehub (0.11.6-10-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Improve GOG DLC support (#118) [6a72d84] + + -- tkashkin Sat, 3 Nov 2018 03:49:42 +0300 + +com.github.tkashkin.gamehub (0.11.6-9-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Restrict NSIS installers unpacking with `file-roller` Support adding custom games using installers (#106) Implement custom emulators removal [7e443e4] + + -- tkashkin Thu, 1 Nov 2018 08:20:07 +0300 + +com.github.tkashkin.gamehub (0.11.6-8-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix compat settings and launch time saving for non-native games (#92) [75a5015] + + -- tkashkin Thu, 1 Nov 2018 05:31:22 +0300 + +com.github.tkashkin.gamehub (0.11.6-7-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Improve bundled DOSBox detection for GOG Windows games (#113) [3b3427e] + + -- tkashkin Thu, 1 Nov 2018 02:11:41 +0300 + +com.github.tkashkin.gamehub (0.11.6-6-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * New useless feature: press R to select random game [842bc32] + + -- tkashkin Thu, 1 Nov 2018 01:05:13 +0300 + +com.github.tkashkin.gamehub (0.11.6-5-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Add logout buttons for GOG and Humble (#40) Add NSIS installer support (#96) [d18ac39] + + -- tkashkin Thu, 1 Nov 2018 00:21:47 +0300 + +com.github.tkashkin.gamehub (0.11.6-4-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix #38, #109 [4d35615] + + -- tkashkin Wed, 31 Oct 2018 03:50:25 +0300 + +com.github.tkashkin.gamehub (0.11.6-3-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Custom emulator support (#103) Download only mode (#107) [4150ba2] + + -- tkashkin Fri, 26 Oct 2018 18:58:21 +0300 + +com.github.tkashkin.gamehub (0.11.6-2-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix #105 Fix GOG bonus content download info [226fc5c] + + -- tkashkin Wed, 24 Oct 2018 18:40:06 +0300 + +com.github.tkashkin.gamehub (0.11.6-1-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix DEB_BUILD_OPTIONS [81f11b6] + * Keyboard/gamepad navigation improvements WINEARCH fixes Version bump [5de360a] + * Controller mode improvements (#75) [e5b5298] + * Possibly fix debian/rules to disable optimizations Do not show compat dialog if parameters for game are saved (#75) [394cd6d] + + -- tkashkin Tue, 23 Oct 2018 15:36:21 +0300 + +com.github.tkashkin.gamehub (0.11.5-29-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Set DEB_BUILD_OPTIONS in debian/rules [24f83f1] + + -- tkashkin Mon, 22 Oct 2018 02:41:47 +0300 + +com.github.tkashkin.gamehub (0.11.5-28-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix add game button insensitivity Disable optimizations Update README.md [393c96e] + + -- tkashkin Mon, 22 Oct 2018 01:19:01 +0300 + +com.github.tkashkin.gamehub (0.11.5-26-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Add RetroArch compatibility tool [7a896a5] + + -- tkashkin Sun, 21 Oct 2018 22:07:43 +0300 + +com.github.tkashkin.gamehub (0.11.5-25-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix last launch time sorting [c2640f4] + + -- tkashkin Sat, 20 Oct 2018 21:32:21 +0300 + +com.github.tkashkin.gamehub (0.11.5-24-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Prevent multiple games launch at the same time (#92) Possibly fix flatpak errors (#15, #61) [6029659] + + -- tkashkin Sat, 20 Oct 2018 21:07:06 +0300 + +com.github.tkashkin.gamehub (0.11.5-23-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Update flatpak libs [7ccc7a5] + + -- tkashkin Sat, 20 Oct 2018 00:08:13 +0300 + +com.github.tkashkin.gamehub (0.11.5-22-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Remove flatpak runtime libs [6db7eed] + + -- tkashkin Fri, 19 Oct 2018 23:52:13 +0300 + +com.github.tkashkin.gamehub (0.11.5-21-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Games can be sorted by last launch time Imported tags can be disabled (#47) Experimental flatpak changes (#15) [cb4c384] + + -- tkashkin Fri, 19 Oct 2018 23:39:19 +0300 + +com.github.tkashkin.gamehub (0.11.5-20-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Unified games sorting (#102) Possibly fix some of random crashes [8dfd66a] + + -- tkashkin Fri, 19 Oct 2018 01:37:56 +0300 + +com.github.tkashkin.gamehub (0.11.5-19-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Update flatpak manifest and build script [c48a7f1] + + -- tkashkin Thu, 18 Oct 2018 16:00:31 +0300 + +com.github.tkashkin.gamehub (0.11.5-17-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge branch 'dev' of github.com:tkashkin/GameHub into dev [b1639e3] + * Cleanup flatpak build directory [b5717ba] + * Cleanup flatpak build directory [4510625] + * Update flatpak build script Update flatpak manifest Move flatpak manifest from its branch [8788426] + + -- tkashkin Wed, 17 Oct 2018 22:50:44 +0300 + +com.github.tkashkin.gamehub (0.11.5-14-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Update build script [8abf5b8] + + -- tkashkin Wed, 17 Oct 2018 00:31:03 +0300 + +com.github.tkashkin.gamehub (0.11.5-13-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * + + -- tkashkin Tue, 16 Oct 2018 23:20:58 +0300 + +com.github.tkashkin.gamehub (0.11.5-12-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Update build script and fix xenial build [0b81f04] + + -- tkashkin Tue, 16 Oct 2018 23:20:58 +0300 + +com.github.tkashkin.gamehub (0.11.5-11-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Update build script [7b9bdae] + + -- tkashkin Tue, 16 Oct 2018 22:16:50 +0300 + +com.github.tkashkin.gamehub (0.11.5-10-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * + + -- tkashkin Tue, 16 Oct 2018 21:04:01 +0300 + +com.github.tkashkin.gamehub (0.11.5-9-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Try to fix build for xenial and flatpak [ef33bc5] + + -- tkashkin Tue, 16 Oct 2018 21:04:01 +0300 + +com.github.tkashkin.gamehub (0.11.5-8-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix build on xenial [245936b] + + -- tkashkin Tue, 16 Oct 2018 19:46:03 +0300 + +com.github.tkashkin.gamehub (0.11.5-7-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Release all keys on gamepad disconnect [a93f616] + * Fix focus stealing from search field Update readme [3aca6fe] + + -- tkashkin Tue, 16 Oct 2018 18:22:47 +0300 + +com.github.tkashkin.gamehub (0.11.5-5-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Controller UI mode [79578c7] + + -- tkashkin Mon, 15 Oct 2018 01:03:00 +0300 + +com.github.tkashkin.gamehub (0.11.5-4-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix build [3d005c2] + * Improved keyboard events using xtest instead of calling xdotool [923715a] + + -- tkashkin Sun, 14 Oct 2018 22:57:19 +0300 + +com.github.tkashkin.gamehub (0.11.5-2-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Improved gamepad navigation, stick support [e3d214c] + + -- tkashkin Sun, 14 Oct 2018 15:39:11 +0300 + +com.github.tkashkin.gamehub (0.11.5-1-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Update build script [c7ef68f] + * UI tweaks Proton 3.16 support Basic keyboard/gamepad navigation in grid view (#75) [4c29f49] + + -- tkashkin Sun, 14 Oct 2018 01:43:15 +0300 + +com.github.tkashkin.gamehub (0.11.4-1-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Bump version [cd50494] + * Use WINEARCH env variable Fix building with older libsoup [507c293] + + -- tkashkin Fri, 12 Oct 2018 00:00:31 +0300 + +com.github.tkashkin.gamehub (0.11.3-14-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Use correct gpg package and binary on xenial [048f365] + * One more flatpak try [4feb1f6] + + -- tkashkin Wed, 10 Oct 2018 20:09:44 +0300 + +com.github.tkashkin.gamehub (0.11.3-12-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Update README.md Possibly fix flatpak build and xenial launchpad source package upload [6b04a97] + * Revert libwebkit2gtk workarounds [bac13e2] + * set +e in build_flatpak() [cf2cdd1] + * Update build script [511903f] + * Try to use older libwebkit2gtk for launchpad [3885762] + * Update debian/control [8e75319] + * Update debian/control [12449cd] + * Update debian/control [dd5e720] + * Update flatpak build script Try to blacklist webkit2gtk again [8cab19b] + * Merge branch 'dev' of github.com:tkashkin/GameHub into dev [3e55b94] + * Try to use libwebkit2gtk-4.0-dev=2.20.1-1 if available Try to build flatpak [4b5d555] + * Merge pull request #95 from cho2/l10n-dev [66ecef0] + * Update Indonesian translation [3c11ab1] + + -- tkashkin Wed, 10 Oct 2018 19:45:43 +0300 + +com.github.tkashkin.gamehub (0.11.3-1-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Build source-only package for launchpad [1b8ae91] + * Disable GPG signature check for dput [f927210] + * Force gpg1 for dput [f471ae7] + * Try to use gpg1 [160d118] + * Try to use gpg1 [3ba17a0] + * Try to start gpg-agent [823d832] + * Try to start gpg-agent [78bfa66] + * Force older webkit libs again [2f4433c] + * Force older libwebkit2gtk [78a6efc] + * Blacklist libwebkit2gtk-4.0-dev 2.22.2-0ubuntu0.18.04.1 [16b042d] + * No fail on key import [fa39130] + * Try to start gpg-agent [d3ef42c] + * Update build script [690ad06] + * Update localization template Update build scripts Trying to setup a PPA Update license [e146c44] + * Update debian build instructions (#91) [e943ed5] + + -- tkashkin Sat, 6 Oct 2018 14:04:59 +0300 + +com.github.tkashkin.gamehub (0.11.2-6-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix GOG token refresh when there's no internet connection [40d7849] + + -- tkashkin Sat, 29 Sep 2018 13:58:51 +0300 + +com.github.tkashkin.gamehub (0.11.2-5-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Slightly modified #90 [6d80079] + + -- tkashkin Thu, 27 Sep 2018 20:10:13 +0300 + +com.github.tkashkin.gamehub (0.11.2-4-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge pull request #88 from neuromancer/patch-1 [51b3653] + * complete gecko popup removal when creating a new wine prefix [c167f08] + + -- Anatoliy Kashkin Wed, 26 Sep 2018 19:36:11 +0300 + +com.github.tkashkin.gamehub (0.11.2-3-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Enhancements for #83 [fc62026] + + -- tkashkin Tue, 25 Sep 2018 08:02:35 +0300 + +com.github.tkashkin.gamehub (0.11.2-2-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Game command line parameters User-added games (#83) [0fad67c] + + -- tkashkin Mon, 24 Sep 2018 13:28:48 +0300 + +com.github.tkashkin.gamehub (0.11.2-1-dev~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fixes for CompatTools [24600df] + * Merge pull request #84 from tkashkin/master [f193fb6] + + -- tkashkin Sun, 23 Sep 2018 08:56:16 +0300 + +com.github.tkashkin.gamehub (0.11.1-2-master~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix AppImage repacking [aa60f85] + * Update AppVeyor config [a840b8b] + * Add xenial dependencies [b74ef25] + * Update build script [861be4c] + * Update AppVeyor config [a8f959e] + * Update AppVeyor config [edea459] + * Update AppVeyor config [ab8831f] + * Try to build on Ubuntu 16.04 [6c4ba32] + * Update AppImage build and run scripts [39e00ef] + * [ci skip] Fix building with GTK < 3.22 [d50095c] + + -- tkashkin Fri, 21 Sep 2018 08:16:14 +0300 + +com.github.tkashkin.gamehub (0.11.1-1-master~$VERSION_SUFFIX) $DISTRO; urgency=low + * Update AppVeyor config [364765d] + * Update AppVeyor artifact paths [6a91e63] + * Bump version Update AppVeyor config and AppImage build script [14580cb] + * Remove Travis CI from README.md [b2acce4] + * Update AppVeyor config [783aab2] + * Update AppVeyor config [1ebcb51] + * Update pt_BR localization [2533558] + + -- tkashkin Wed, 19 Sep 2018 03:48:01 +0300 + +com.github.tkashkin.gamehub (0.11.0~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge pull request #80 from tkashkin/dev [6dd4d6b] + * Merge pull request #79 from tkashkin/appimage [3802672] + * 0.11.0 release [7362f95] + * Restore Travis to Houston CI (Travis doesn't support Ubuntu newer than trusty :confused:) Try to migrate to AppVeyor [4b9c3b6] + * Add AppImage support [a565890] + * Add libxml2-dev dependency to debian/control [6bff75d] + * Another fix attempt for #77 [53fbb2f] + * Fix force_compat Probably fix Trove.sing_url (#77) [22b0ab5] + * Add DOSBox CompatTool (#71) Allow to force compat even for games which do support Linux (#51, #52, #71) [36b90dc] + * Add CustomScript tool (#71) [99bf86c] + * Maybe fix Humble URL ttl (#73) [67c77a8] + * One more try (#67) [55fadbc] + * GamesView postponed updates (#67) "Installed" tag (#69) Fix Utils.strip_name (#70) Partly update localizations [5e03bce] + * Fix #68 [04e2799] + * Implement Humble Trove support (#32) [9e3dc15] + * Log working directory [c134e48] + * Log all run methods [e6d6d60] + * Added install options for compat tools [3cd2745] + * Pass target directory to windows installers (for now assuming all of them are InnoSetup) [b62ec93] + * Fix appstream info [2a114af] + * Version bump [2177acc] + * Database rewrite (refactoring, versioning, migrations, #64) UI tweaks Added tag icons [6c48e09] + * Game properties dialog Improvements for #59 [bef7791] + * Compatibility tools selection (#59, #60) [7752ad9] + * Experimental Proton/wine support (#54) [fd5a0e5] + * Fix flatpak build [53e10bb] + + -- Anatoliy Kashkin Tue, 18 Sep 2018 09:25:15 +0300 + +com.github.tkashkin.gamehub (0.9.0~$VERSION_SUFFIX) $DISTRO; urgency=low + * Prepare 0.9.0 release [01ef0c6] + * [ci skip] Update README (new AUR package) [e399e6f] + * Implement #50, #33 [c64646e] + * [ci skip] Update README.md [08585aa] + * Add Proton beta appid check [707f6ed] + * Use ThreadPool instead of spawning endless threads Run game merging only for new games (may not merge all games correctly, needs testing) Finally fix #48 (maybe) [ea5b143] + * Fixes for humble and #48 [4a3f01d] + * Game tags dialog User tags creation [1f27c50] + * Tags (#47) are working (no user tags yet) Games context menu [6765826] + * Started work on #47: * GamesDB refactoring * Game tags * Tags import from GOG * FiltersPopover (just basic UI now, not hooked to anything) [c4e0f3f] + * Sort cached games by name [d8c36a3] + * Remove tmp installer extension [699de05] + * Fixes [b02797c] + * Refactoring Non-native games support Steam Play support [16b3f84] + * Fix GOG bonus content/DLC loading [c232c37] + * Refactored DownloadProgressView to allow more download types (not only games) Implemented GOG bonus content downloading [7c7ef29] + * Actually disable merging (loading cache) when merging toggle is disabled [2560717] + * Basic collection management (#29) [055c51a] + * Fixed #38 [41f45fc] + * Fix games counter [668172f] + * Improved merging [ee79571] + * Threaded loading Threaded merging Merging cache [b02381e] + * Fixes for #42, #43 Fixed GameDetaisView/GameDetailsDialog background color for non-elementary gtk themes [8dc569a] + * Fixes for #39 Added Collection tab in settings dialog (does nothing yet) [e201431] + * Started implementing #29 Fetching bonus content and DLCs (no download yet) Bugfixes [42816ef] + * Fix flatpak Steam path [3855cf6] + * Fix flatpak Steam path [4a6407a] + * Flatpak build error fix [ecda4c5] + + -- tkashkin Tue, 4 Sep 2018 09:48:50 +0300 + +com.github.tkashkin.gamehub (0.8.0~$VERSION_SUFFIX) $DISTRO; urgency=low + * Option to merge games from different sources [9906b6a] + * Add null check in Utils.cache_image [eff0aab] + + -- tkashkin Wed, 15 Aug 2018 16:26:15 +0300 + +com.github.tkashkin.gamehub (0.7.0~$VERSION_SUFFIX) $DISTRO; urgency=low + * Settings dialog rework Compact games list [b9712bb] + + -- tkashkin Thu, 9 Aug 2018 20:29:22 +0300 + +com.github.tkashkin.gamehub (0.6.3~$VERSION_SUFFIX) $DISTRO; urgency=low + * Trying to fix Humble Bundle access token extraction [3a8a79c] + + -- tkashkin Mon, 6 Aug 2018 14:21:16 +0300 + +com.github.tkashkin.gamehub (0.6.2~$VERSION_SUFFIX) $DISTRO; urgency=low + * Search crash fix and UI improvements [7800da0] + + -- tkashkin Wed, 25 Jul 2018 20:22:36 +0300 + +com.github.tkashkin.gamehub (0.6.1~$VERSION_SUFFIX) $DISTRO; urgency=low + * Additional info for Steam games Pass locale to APIs when possible to get localized data [882cef7] + * Merge branch 'master' of github.com:tkashkin/GameHub [464adc3] + * Initial snap is at least working now (still broken as hell) Fixes for old GTK+3 [0945f04] + * Update Indonesian translation (#28) [0ab322a] + * UI fixes Initial snap [f7f57b5] + * Update pt_BR.po (#25) [8cc0b6f] + * Update README.md [a0ea12a] + + -- tkashkin Tue, 24 Jul 2018 08:03:14 +0300 + +com.github.tkashkin.gamehub (0.6.0~$VERSION_SUFFIX) $DISTRO; urgency=low + * Downloader rewrite: now it's possible to pause and cancel downloads Downloads can be resumed after interruption UI improvements [e2f0c9e] + * [ci skip] Fix Humble Bundle installers cache [1d65ac3] + + -- tkashkin Sun, 22 Jul 2018 17:53:23 +0300 + +com.github.tkashkin.gamehub (0.5.7~$VERSION_SUFFIX) $DISTRO; urgency=low + * Yet another locale fix Installers cache management [1cc9b24] + + -- tkashkin Sat, 21 Jul 2018 02:48:46 +0300 + +com.github.tkashkin.gamehub (0.5.6~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fix crash for GOG "games" like Hotline Miami 2 Digital Comics Fix building with GTK+3 < 3.22 [e2674e7] + * Fix GOG pagination (#22) [7c60162] + + -- tkashkin Fri, 20 Jul 2018 19:17:50 +0300 + +com.github.tkashkin.gamehub (0.5.5~$VERSION_SUFFIX) $DISTRO; urgency=low + * Bugfixes Design changes Compatibility [268bdfe] + * Bundle ivy [7c887d7] + * Update .travis.yml [2c9d334] + * Update README.md [30edc21] + * [ci skip] Update README.md [fe5b112] + * Show additional info for GOG games [abf3f04] + + -- tkashkin Fri, 20 Jul 2018 17:15:57 +0300 + +com.github.tkashkin.gamehub (0.5.4~$VERSION_SUFFIX) $DISTRO; urgency=low + * [ci skip] Yet anothed locale fix [e26aef4] + * 0.5.4 release [0d539cd] + + -- tkashkin Mon, 16 Jul 2018 06:38:24 +0300 + +com.github.tkashkin.gamehub (0.5.3~$VERSION_SUFFIX) $DISTRO; urgency=low + * Merge branch 'master' of github.com:tkashkin/GameHub [a13ea49] + * [ci skip] Fix launching for flatpak [732aad7] + * [ci skip] Update launcher script [4c97be9] + * [ci skip] Wrong args fix [d479056] + * [ci skip] Missing ; [71b86bd] + * 0.5.3 release [ac2ee74] + * id language (#11) [69381fa] + + -- tkashkin Sun, 15 Jul 2018 15:31:27 +0300 + +com.github.tkashkin.gamehub (0.5.2~$VERSION_SUFFIX) $DISTRO; urgency=low + * 0.5.2 release Added localizations: * pt_BR * pl * uk * de [f26eee5] + * pt_BR language (#10) [f37e27b] + + -- tkashkin Sat, 14 Jul 2018 02:58:55 +0300 + +com.github.tkashkin.gamehub (0.5.1~$VERSION_SUFFIX) $DISTRO; urgency=low + * Prepare 0.5.1 release [f2faa51] + * [ci skip] Fix AutoSizeImage resizing while image is not loaded [f332c71] + * [ci skip] Fix image loading for flathub [5d2a96c] + * [ci skip] Trying to fix network for flatpak [e1f396d] + * [ci skip] Better error handling for images caching [80f753a] + * Initial flatpak build support [WIP] [2b0e729] + + -- tkashkin Fri, 13 Jul 2018 05:31:57 +0300 + +com.github.tkashkin.gamehub (0.5.0~$VERSION_SUFFIX) $DISTRO; urgency=low + * [ci skip] Disable WebKit hardware acceleration [f878bbd] + * [ci skip] Cache path [e6286cd] + * Enum fixes [b9a4792] + * Enum fixes [c9a4d0e] + * [ci skip] Appstream data changes [8270d4e] + * Downloads list fixes [1f33028] + * Games list view Game details view/dialog Games grid improvements Bug fixes [cc083bb] + + -- tkashkin Thu, 12 Jul 2018 11:37:43 +0300 + +com.github.tkashkin.gamehub (0.4.1~$VERSION_SUFFIX) $DISTRO; urgency=low + * Small features [4424a8a] + + -- tkashkin Sat, 7 Jul 2018 10:05:21 +0300 + +com.github.tkashkin.gamehub (0.4.0~$VERSION_SUFFIX) $DISTRO; urgency=low + * Unneeded game sources now can be disabled Bug fixes [7b8a735] + * Probably fix Humble auth [54a5b4f] + * Debug logging Small UI fixes [2d315c0] + * Hide toolbar buttons while loading [341a3a4] + * Flat welcome window [b7cdb7c] + + -- tkashkin Tue, 3 Jul 2018 05:00:52 +0300 + +com.github.tkashkin.gamehub (0.3.1~$VERSION_SUFFIX) $DISTRO; urgency=low + * Humble Bundle authentication fix Humble Bundle game icons fix [2ba374a] + + -- tkashkin Fri, 22 Jun 2018 18:04:49 +0300 + +com.github.tkashkin.gamehub (0.3.0~$VERSION_SUFFIX) $DISTRO; urgency=low + * Humble Bundle support 0.3.0 release [89968b4] + * Update post_install script [0310078] + + -- tkashkin Sun, 17 Jun 2018 07:11:24 +0300 + +com.github.tkashkin.gamehub (0.2.5~$VERSION_SUFFIX) $DISTRO; urgency=low + * Prepare 0.2.5 release [dd02dd2] + * Fix game installation segfault [b213b2f] + * Fix for GOG games with ':' in title [a652a78] + * [ci skip] Update README.md [9638c69] + * Create .travis.yml [bbff2ea] + + -- tkashkin Tue, 12 Jun 2018 01:26:22 +0300 + +com.github.tkashkin.gamehub (0.2.4~$VERSION_SUFFIX) $DISTRO; urgency=low + * Settings dialog [554b658] + + -- tkashkin Sat, 2 Jun 2018 05:57:32 +0300 + +com.github.tkashkin.gamehub (0.2.3~$VERSION_SUFFIX) $DISTRO; urgency=low + * Fixes [e0f80f7] + * Update version [323e09f] + * Update readme and version [cf950e1] + * Remove ivy again [068bc3b] + * Update changelog [8f23bad] + * GOG games installation and running Various improvements [b0b9111] + * Steam game launch and installation Games grid style tweaks [0b801cc] + * Grid selection mode [fb11b0b] + * Grid autosizing [7ebee54] + * Almost perfect grid autosizing [03c53c4] + * [WIP] Games grid autosizing Juno fixes [0183150] + + -- tkashkin Fri, 1 Jun 2018 14:40:32 +0300 + +com.github.tkashkin.gamehub (0.1.3~$VERSION_SUFFIX) $DISTRO; urgency=low + * Update changelog [533ff4d] + * Fix Steam config path\nUpdate .gitignore [17695d8] + + -- tkashkin Mon, 28 May 2018 02:30:49 +0300 diff --git a/debian/control b/debian/control deleted file mode 100644 index 081d911f..00000000 --- a/debian/control +++ /dev/null @@ -1,14 +0,0 @@ -Source: com.github.tkashkin.gamehub -Section: x11 -Priority: extra -Maintainer: tkashkin -Build-Depends: cmake (>= 2.8), - debhelper (>= 9), - libgtk-3-dev, - valac (>= 0.16) -Standards-Version: 3.9.3 - -Package: com.github.tkashkin.gamehub -Architecture: any -Depends: ${misc:Depends}, ${shlibs:Depends} -Description: Have all your games in one place diff --git a/debian/control.in b/debian/control.in new file mode 100644 index 00000000..778c51ca --- /dev/null +++ b/debian/control.in @@ -0,0 +1,25 @@ +Source: com.github.tkashkin.gamehub +Section: x11 +Priority: optional +Maintainer: tkashkin +Build-Depends: meson (>= 0.40), + valac (>= 0.16), + debhelper (>= 9), + libgtk-3-dev, + libglib2.0-dev, + libwebkit2gtk-4.0-dev, + libjson-glib-dev, + libgee-0.8-dev, + libsoup2.4-dev, + libsqlite3-dev, + libxml2-dev, + libpolkit-gobject-1-dev, + libx11-dev, libmanette-0.2-dev, libxtst-dev +Standards-Version: 4.1.4 + +Package: com.github.tkashkin.gamehub +Architecture: any +Depends: ${misc:Depends}, ${shlibs:Depends} +Recommends: file-roller, innoextract, wine, dosbox +Suggests: steam +Description: All your games in one place diff --git a/debian/copyright b/debian/copyright index 081c4178..de0034c7 100644 --- a/debian/copyright +++ b/debian/copyright @@ -3,20 +3,20 @@ Upstream-Name: com.github.tkashkin.gamehub Source: https://github.com/tkashkin/GameHub Files: * -Copyright: 2018 tkashkin -License: WTFPL - -License: WTFPL - DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE - Version 2, December 2004 - - Copyright (C) 2004 Sam Hocevar - - Everyone is permitted to copy and distribute verbatim or modified - copies of this license document, and changing it is allowed as long - as the name is changed. - - DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. You just DO WHAT THE FUCK YOU WANT TO. +Copyright: 2018-2019 Anatoliy Kashkin +License: GPL-3.0+ + 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 package 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 . + . + On Debian systems, the complete text of the GNU General + Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". diff --git a/debian/rules b/debian/rules deleted file mode 100755 index f82cad85..00000000 --- a/debian/rules +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/make -f -# -*- makefile -*- -# Sample debian/rules that uses debhelper. -# This file was originally written by Joey Hess and Craig Small. -# As a special exception, when this file is copied by dh-make into a -# dh-make output file, you may use that output file without restriction. -# This special exception was added by Craig Small in version 0.37 of dh-make. - -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 - -%: - dh $@ --buildsystem=meson diff --git a/debian/rules.in b/debian/rules.in new file mode 100755 index 00000000..e8c9fcbc --- /dev/null +++ b/debian/rules.in @@ -0,0 +1,24 @@ +#!/usr/bin/make -f +# -*- makefile -*- +#export DH_VERBOSE=1 +DEB_BUILD_OPTIONS=noopt nostrip nocheck +CFLAGS+=-O0 + +%: + dh $@ + +override_dh_auto_clean: + rm -rf debian/build + +override_dh_auto_configure: + mkdir -p debian/build + cd debian/build && meson --prefix=/usr --buildtype=debug -Ddistro=debian -Dgit_branch=$_GH_BRANCH -Dgit_commit=$_GH_COMMIT -Dgit_commit_short=$_GH_COMMIT_SHORT ../.. + +override_dh_auto_build: + cd debian/build && ninja -v + +override_dh_auto_test: + cd debian/build && ninja test + +override_dh_auto_install: + cd debian/build && DESTDIR=${CURDIR}/debian/com.github.tkashkin.gamehub ninja install diff --git a/flatpak/README.md b/flatpak/README.md new file mode 100644 index 00000000..5e9dfd85 --- /dev/null +++ b/flatpak/README.md @@ -0,0 +1,32 @@ +# flatpak +This directory contains flatpak manifest + +#### Runtime dependencies + +* `org.gnome.Platform//3.28` +* `org.freedesktop.Platform//1.6` +* `io.elementary.Loki.BaseApp//stable` + +#### Build dependencies + +* `org.gnome.Sdk//3.28` + +## Building + +#### Add flathub repo + +```bash +flatpak remote-add [--user] --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo +``` + +#### Install dependencies and build + +```bash +scripts/build.sh build_flatpak +``` + +#### Run + +```bash +flatpak run [-v] com.github.tkashkin.gamehub [--debug] +``` diff --git a/flatpak/bin/bin.json b/flatpak/bin/bin.json new file mode 100644 index 00000000..e278e679 --- /dev/null +++ b/flatpak/bin/bin.json @@ -0,0 +1,19 @@ +{ + "name": "bin", + "buildsystem": "simple", + "sources": [ + { + "type": "file", + "path": "file-roller" + }, + { + "type": "file", + "path": "org.gnome.FileRoller.gschema.xml" + } + ], + "build-commands": [ + "install -Dm755 file-roller /app/bin/file-roller", + "install -Dm644 org.gnome.FileRoller.gschema.xml /app/share/glib-2.0/schemas/org.gnome.FileRoller.gschema.xml", + "glib-compile-schemas /app/share/glib-2.0/schemas/" + ] +} diff --git a/flatpak/bin/file-roller b/flatpak/bin/file-roller new file mode 100755 index 00000000..69a32847 Binary files /dev/null and b/flatpak/bin/file-roller differ diff --git a/flatpak/bin/org.gnome.FileRoller.gschema.xml b/flatpak/bin/org.gnome.FileRoller.gschema.xml new file mode 100644 index 00000000..385d1bd5 --- /dev/null +++ b/flatpak/bin/org.gnome.FileRoller.gschema.xml @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 'name' + How to sort files + What criteria must be used to arrange files. Possible values: name, size, type, time, path. + + + 'ascending' + Sort type + Whether to sort in ascending or descending direction. Possible values: ascending, descending. + + + 'as-folder' + List Mode + Use “all-files” to view all the files in the archive in a single list, use “as-folder” to navigate the archive as a folder. + + + true + Display type + Display the type column in the main window. + + + true + Display size + Display the size column in the main window. + + + true + Display time + Display the time column in the main window. + + + true + Display path + Display the path column in the main window. + + + 250 + Name column width + The default width of the name column in the file list. + + + + + + 600 + + + 480 + + + 200 + + + false + View the sidebar + Whether to display the sidebar. + + + + + + (-1, -1) + + + false + + + -1 + + + + + + [] + Editors + List of applications entered in the “Open File” dialog and not associated with the file type. + + + 'normal' + Compression level + Compression level used when adding files to an archive. Possible values: very-fast, fast, normal, maximum. + + + false + Encrypt the archive header + Whether to encrypt the archive header. If the header is encrypted the password will be required to list the archive content as well. + + + + + + + + + + + + + false + Do not overwrite newer files + + + true + Recreate the folders stored in the archive + + + + + + '.tar.gz' + + + false + + + false + Encrypt the archive header + Whether to encrypt the archive header. If the header is encrypted the password will be required to list the archive content as well. + + + 0 + Default volume size + The default size for volumes. + + + + + + '' + + + [] + + + '' + + + '' + + + '' + + + '' + + + false + + + true + + + true + + + + + + -1 + + + -1 + + + + diff --git a/flatpak/com.github.tkashkin.gamehub.json.in b/flatpak/com.github.tkashkin.gamehub.json.in new file mode 100644 index 00000000..a1c6b3f3 --- /dev/null +++ b/flatpak/com.github.tkashkin.gamehub.json.in @@ -0,0 +1,91 @@ +{ + "app-id": "com.github.tkashkin.gamehub", + "base": "io.elementary.BaseApp", + "base-version": "juno", + "runtime": "org.gnome.Platform", + "runtime-version": "3.28", + "sdk": "org.gnome.Sdk", + "command": "com.github.tkashkin.gamehub", + "separate-locales": false, + "build-options": { + "env": { + "PKG_CONFIG_GOBJECT_INTROSPECTION_1_0_GIRDIR": "/app/share/gir-1.0", + "PKG_CONFIG_GOBJECT_INTROSPECTION_1_0_TYPELIBDIR": "/app/lib/girepository-1.0" + } + }, + "finish-args": [ + "--allow=devel", + "--share=ipc", "--socket=x11", + "--socket=pulseaudio", + "--device=dri", + "--socket=wayland", + "--share=network", + "--talk-name=org.gnome.SettingsDaemon", + "--talk-name=org.freedesktop.NetworkManager", + "--talk-name=org.kde.StatusNotifierWatcher", + "--talk-name=org.freedesktop.Flatpak", + "--system-talk-name=org.freedesktop.PolicyKit1", + "--socket=session-bus", + + "--persist=.", + "--device=all", + "--allow=multiarch", + + "--extension=org.freedesktop.Platform.Compat32=directory=lib/32bit", + "--extension=org.freedesktop.Platform.Compat32=version=1.6", + "--extension=org.freedesktop.Platform.GL32=directory=lib/32bit/lib/GL", + "--extension=org.freedesktop.Platform.GL32=version=1.4", + "--extension=org.freedesktop.Platform.GL32=versions=1.6;1.4", + "--extension=org.freedesktop.Platform.GL32=subdirectories=true", + "--extension=org.freedesktop.Platform.GL32=no-autodownload=true", + "--extension=org.freedesktop.Platform.GL32=autodelete=false", + "--extension=org.freedesktop.Platform.GL32=add-ld-path=lib", + "--extension=org.freedesktop.Platform.GL32=merge-dirs=vulkan/icd.d;glvnd/egl_vendor.d", + "--extension=org.freedesktop.Platform.GL32=download-if=active-gl-driver", + "--extension=org.freedesktop.Platform.GL32=enable-if=active-gl-driver", + "--filesystem=/sys/module/nvidia:ro", + + "--talk-name=ca.desrt.dconf", + "--filesystem=xdg-run/dconf", + "--filesystem=~/.config/dconf:ro", + "--env=DCONF_USER_CONFIG_DIR=.config/dconf", + + "--filesystem=host", + "--filesystem=home", + "--filesystem=~/.var/app/com.valvesoftware.Steam" + ], + "cleanup": [ + "/include", + "/lib/pkgconfig", + "/lib/*.la", + "/lib/*.a", + "/share/gir-1.0", + "/lib/girepository-1.0", + "/share/vala", + "/share/gtk-doc" + ], + "modules": [ + "libs/libs.json", + + { + "name": "gamehub", + "buildsystem": "meson", + "config-opts": [ + "--buildtype=debug", + "-Dpackage=flatpak", + "-Dgit_branch=$BRANCH", + "-Dgit_commit=$COMMIT", + "-Dgit_commit_short=$COMMIT_SHORT" + ], + "sources": [ + { + "type": "git", + "path": "../", + "branch": "$BRANCH" + } + ] + }, + + "bin/bin.json" + ] +} diff --git a/flatpak/flathub.json b/flatpak/flathub.json new file mode 100644 index 00000000..d39c5a15 --- /dev/null +++ b/flatpak/flathub.json @@ -0,0 +1,3 @@ +{ + "only-arches": ["i386", "x86_64"] +} diff --git a/flatpak/libs/bundled/libmanette-0.2.2.tar.gz b/flatpak/libs/bundled/libmanette-0.2.2.tar.gz new file mode 100644 index 00000000..c9b4f697 Binary files /dev/null and b/flatpak/libs/bundled/libmanette-0.2.2.tar.gz differ diff --git a/flatpak/libs/ld.so.conf b/flatpak/libs/ld.so.conf new file mode 100644 index 00000000..d4e82f9f --- /dev/null +++ b/flatpak/libs/ld.so.conf @@ -0,0 +1,7 @@ +# We just make any GL32 extension have higher priority +include /run/flatpak/ld.so.conf.d/app-*-org.freedesktop.Platform.GL32.*.conf + +include /run/flatpak/ld.so.conf.d/*.conf + +/app/lib +/app/lib/32bit/lib diff --git a/flatpak/libs/libopenssl/configure_i386 b/flatpak/libs/libopenssl/configure_i386 new file mode 100755 index 00000000..c0800b2d --- /dev/null +++ b/flatpak/libs/libopenssl/configure_i386 @@ -0,0 +1,23 @@ +#!/bin/bash + +echo "OPENSSL CONFIGURE" +./Configure \ + $@ zlib enable-camellia enable-seed enable-rfc3779 enable-sctp enable-cms enable-md2 enable-rc5 enable-ssl3 enable-ssl3-method no-mdc2 no-ec2m no-gost no-srp shared linux-elf +echo "OPENSSL MAKE DEPEND" +make depend +echo "OPENSSL MAKE BUILD_LIBS" +make build_libs +echo "OPENSSL COPY STUFF" +cp libssl.so /app/lib/ +cp libcrypto.so /app/lib/ +cd /app/lib +ln -s libssl.so libssl.so.1.0.0 +ln -s libcrypto.so libcrypto.so.1.0.0 +cd - +echo "OPENSSL END" +cat < Makefile +install: + true +all: + true +EOF diff --git a/flatpak/libs/libopenssl/configure_x86_64 b/flatpak/libs/libopenssl/configure_x86_64 new file mode 100755 index 00000000..01609eeb --- /dev/null +++ b/flatpak/libs/libopenssl/configure_x86_64 @@ -0,0 +1,24 @@ +#!/bin/bash + +set -eu + +echo "OPENSSL CONFIGURE" +./config $@ shared +echo "OPENSSL MAKE DEPEND" +make depend +echo "OPENSSL MAKE BUILD_LIBS" +make build_libs +echo "OPENSSL COPY STUFF" +cp libssl.so /app/lib/ +cp libcrypto.so /app/lib/ +cd /app/lib +ln -s libssl.so libssl.so.1.0.0 +ln -s libcrypto.so libcrypto.so.1.0.0 +cd - +echo "OPENSSL END" +cat < Makefile +install: + true +all: + true +EOF diff --git a/flatpak/libs/libopenssl/libopenssl.json b/flatpak/libs/libopenssl/libopenssl.json new file mode 100644 index 00000000..f3b38e5f --- /dev/null +++ b/flatpak/libs/libopenssl/libopenssl.json @@ -0,0 +1,25 @@ +{ + "name": "libopenssl", + "no-autogen": true, + "sources": [ + { + "type": "archive", + "url": "https://www.openssl.org/source/old/1.0.0/openssl-1.0.0k.tar.gz", + "sha256": "2982b2e9697a857b336c5c1b1b7b463747e5c1d560f25f6ace95365791b1efd1" + }, + { + "type": "file", + "only-arches": ["i386"], + "path": "configure_i386", + "dest-filename": "configure", + "sha256": "f2dc21cb3749c3e751a0989490287cce151071220fe4a0d2817d9ad360f394f1" + }, + { + "type": "file", + "only-arches": ["x86_64"], + "path": "configure_x86_64", + "dest-filename": "configure", + "sha256": "cd578ac0a2096e95ce323cd4143cca0bd422423f29abba33fbae208583604c6c" + } + ] +} diff --git a/flatpak/libs/libs.json b/flatpak/libs/libs.json new file mode 100644 index 00000000..e7c97ee5 --- /dev/null +++ b/flatpak/libs/libs.json @@ -0,0 +1,41 @@ +{ + "name": "libs", + "buildsystem": "simple", + "sources": [ + { + "type": "file", + "path": "ld.so.conf" + } + ], + "build-commands": [ + "mkdir -p /app/lib/32bit/lib/GL", + "mkdir -p /app/lib/GL", + "ln -s /app/lib/32bit/lib/ld-linux.so.2 /app/lib/ld-linux.so.2", + "install -Dm644 ld.so.conf /app/etc/ld.so.conf" + ], + + "modules": [ + "polkit/polkit.json", + + { + "name": "libevdev", + "sources": [ + { + "type": "git", + "url": "https://gitlab.freedesktop.org/libevdev/libevdev.git" + } + ] + }, + { + "name": "manette", + "buildsystem": "meson", + "config-opts": ["--libdir=lib"], + "sources": [ + { + "type": "archive", + "path": "bundled/libmanette-0.2.2.tar.gz" + } + ] + } + ] +} diff --git a/flatpak/libs/polkit/polkit-0.113.tar.gz b/flatpak/libs/polkit/polkit-0.113.tar.gz new file mode 100644 index 00000000..0f692d5a Binary files /dev/null and b/flatpak/libs/polkit/polkit-0.113.tar.gz differ diff --git a/flatpak/libs/polkit/polkit-autogen b/flatpak/libs/polkit/polkit-autogen new file mode 100755 index 00000000..3ba457e5 --- /dev/null +++ b/flatpak/libs/polkit/polkit-autogen @@ -0,0 +1,4 @@ +#!/bin/sh + +gtkdocize --flavour no-tmpl +autoreconf -if diff --git a/flatpak/libs/polkit/polkit-build-Add-option-to-build-without-polkitd.patch b/flatpak/libs/polkit/polkit-build-Add-option-to-build-without-polkitd.patch new file mode 100644 index 00000000..f201c204 --- /dev/null +++ b/flatpak/libs/polkit/polkit-build-Add-option-to-build-without-polkitd.patch @@ -0,0 +1,101 @@ +From dab179770380918462d0d76e08b11e4abe55c933 Mon Sep 17 00:00:00 2001 +From: Patrick Griffis +Date: Thu, 8 Sep 2016 16:15:54 -0400 +Subject: [PATCH] build: Add option to build without polkitd + +This is for any consumer that needs libpolkit but does +not need polkitd. For example an application running in +flatpak. +--- + configure.ac | 29 ++++++++++++++++++++--------- + src/Makefile.am | 6 +++++- + test/Makefile.am | 6 +++++- + 3 files changed, 30 insertions(+), 11 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 97d4222..a08785c 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -129,20 +129,30 @@ AC_DEFINE([GLIB_VERSION_MIN_REQUIRED], [GLIB_VERSION_2_30], + AC_DEFINE([GLIB_VERSION_MAX_ALLOWED], [G_ENCODE_VERSION(2,34)], + [Notify us when we'll need to transition away from g_type_init()]) + ++ ++AC_ARG_ENABLE([polkitd], ++ [AS_HELP_STRING([--disable-polkitd], [Do not build polkitd])], ++ [enable_polkitd=$enableval], [enable_polkitd=yes]) ++AM_CONDITIONAL(BUILD_POLKITD, [test x${enable_polkitd} = yes]) ++ ++ + AC_ARG_WITH(mozjs, AS_HELP_STRING([--with-mozjs=@<:@mozjs185/mozjs-17.0|auto@:>@], + [Specify version of Spidermonkey to use]),, + with_mozjs=auto) +-AS_IF([test x${with_mozjs} != xauto], [ +- PKG_CHECK_MODULES(LIBJS, ${with_mozjs}) +-], [ +- PKG_CHECK_MODULES(LIBJS, [mozjs185], have_mozjs185=yes, have_mozjs185=no) +- AS_IF([test x${have_mozjs185} = xno], [ +- PKG_CHECK_MODULES(LIBJS, [mozjs-17.0], have_mozjs17=yes, +- [AC_MSG_ERROR([Could not find mozjs185 or mozjs-17.0; see http://ftp.mozilla.org/pub/mozilla.org/js/])]) ++ ++AS_IF([test x${enable_polkitd} = yes], [ ++ AS_IF([test x${with_mozjs} != xauto], [ ++ PKG_CHECK_MODULES(LIBJS, ${with_mozjs}) ++ ], [ ++ PKG_CHECK_MODULES(LIBJS, [mozjs185], have_mozjs185=yes, have_mozjs185=no) ++ AS_IF([test x${have_mozjs185} = xno], [ ++ PKG_CHECK_MODULES(LIBJS, [mozjs-17.0], have_mozjs17=yes, ++ [AC_MSG_ERROR([Could not find mozjs185 or mozjs-17.0; see http://ftp.mozilla.org/pub/mozilla.org/js/])]) ++ ]) + ]) ++ AC_SUBST(LIBJS_CFLAGS) ++ AC_SUBST(LIBJS_LIBS) + ]) +-AC_SUBST(LIBJS_CFLAGS) +-AC_SUBST(LIBJS_LIBS) + + EXPAT_LIB="" + AC_ARG_WITH(expat, [ --with-expat= Use expat from here], +@@ -605,6 +615,7 @@ echo " + Session tracking: ${SESSION_TRACKING} + PAM support: ${have_pam} + systemdsystemunitdir: ${systemdsystemunitdir} ++ polkitd: ${enable_polkitd} + polkitd user: ${POLKITD_USER}" + + if test "$have_pam" = yes ; then +diff --git a/src/Makefile.am b/src/Makefile.am +index 09fc7b3..c6fe91b 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -1,5 +1,9 @@ + +-SUBDIRS = polkit polkitbackend polkitagent programs ++SUBDIRS = polkit polkitagent programs ++ ++if BUILD_POLKITD ++SUBDIRS += polkitbackend ++endif + + if BUILD_EXAMPLES + SUBDIRS += examples +diff --git a/test/Makefile.am b/test/Makefile.am +index 59d0680..d43b0fe 100644 +--- a/test/Makefile.am ++++ b/test/Makefile.am +@@ -1,7 +1,11 @@ + +-SUBDIRS = mocklibc . polkit polkitbackend ++SUBDIRS = mocklibc . polkit + AM_CFLAGS = $(GLIB_CFLAGS) + ++if BUILD_POLKITD ++SUBDIRS += polkitbackend ++endif ++ + noinst_LTLIBRARIES = libpolkit-test-helper.la + libpolkit_test_helper_la_SOURCES = polkittesthelper.c polkittesthelper.h + libpolkit_test_helper_la_LIBADD = $(GLIB_LIBS) +-- +2.9.3 + diff --git a/flatpak/libs/polkit/polkit.json b/flatpak/libs/polkit/polkit.json new file mode 100644 index 00000000..d7f595bd --- /dev/null +++ b/flatpak/libs/polkit/polkit.json @@ -0,0 +1,28 @@ +{ + "name": "polkit", + "config-opts": ["--disable-polkitd", "--disable-man-pages", "--disable-introspection"], + "rm-configure": true, + "cleanup": [ + "/bin/*", + "/etc/pam.d", + "/etc/dbus-1", + "/share/dbus-1/system-services/*", + "/share/polkit-1/actions/*", + "/lib/polkit-1" + ], + "sources": [ + { + "type": "archive", + "path": "polkit-0.113.tar.gz" + }, + { + "type": "patch", + "path": "polkit-build-Add-option-to-build-without-polkitd.patch" + }, + { + "type": "file", + "path": "polkit-autogen", + "dest-filename": "autogen.sh" + } + ] +} diff --git a/flatpak/libs/shared b/flatpak/libs/shared new file mode 160000 index 00000000..fe0c3d93 --- /dev/null +++ b/flatpak/libs/shared @@ -0,0 +1 @@ +Subproject commit fe0c3d93636875e90362e2bbc5ba88114d98e482 diff --git a/meson.build b/meson.build index 48e82f23..5afbc855 100644 --- a/meson.build +++ b/meson.build @@ -1,56 +1,45 @@ -project('com.github.tkashkin.gamehub', 'vala', 'c') +project('com.github.tkashkin.gamehub', 'vala', 'c', version: '0.16.0') i18n = import('i18n') gnome = import('gnome') -add_global_arguments('-g', language: 'vala') -add_global_arguments('-X', language: 'vala') -add_global_arguments('-rdynamic', language: 'vala') -add_global_arguments('-DGETTEXT_PACKAGE="@0@"'.format(meson.project_name()), language: 'c') +add_global_arguments('-O0', '-DGETTEXT_PACKAGE="@0@"'.format(meson.project_name()), language: 'c') + +if get_option('package') == 'appimage' + add_global_arguments('-D', 'PKG_APPIMAGE', language: 'vala') +elif get_option('package') == 'flatpak' + add_global_arguments('-D', 'PKG_FLATPAK', language: 'vala') +endif + +if get_option('distro') == 'debian' + add_global_arguments('-D', 'DISTRO_DEBIAN', '-D', 'PM_APT', language: 'vala') +elif get_option('distro') == 'arch' + add_global_arguments('-D', 'DISTRO_ARCH', '-D', 'PM_PACMAN', language: 'vala') +endif + +if get_option('perf_images_memcache') + add_global_arguments('-D', 'PERF_IMAGES_MEMCACHE', language: 'vala') +endif + +if get_option('perf_gamecard_unload_images') + add_global_arguments('-D', 'PERF_GAMECARD_UNLOAD_IMAGES', language: 'vala') +endif + +conf_data = configuration_data() +conf_data.set('PROJECT_NAME', meson.project_name()) +conf_data.set('GETTEXT_PACKAGE', meson.project_name()) +conf_data.set('GETTEXT_DIR', join_paths(get_option('prefix'), get_option('localedir'))) +conf_data.set('VERSION', meson.project_version()) +conf_data.set('GIT_BRANCH', get_option('git_branch')) +conf_data.set('GIT_COMMIT', get_option('git_commit')) +conf_data.set('GIT_COMMIT_SHORT', get_option('git_commit_short')) +conf_data.set('PREFIX', get_option('prefix')) +conf_data.set('DATADIR', join_paths(get_option('prefix'), get_option('datadir'))) +conf_data.set('BINDIR', join_paths(get_option('prefix'), get_option('bindir'))) +conf_data.set('RUNTIME', get_option('runtime')) subdir('data') +subdir('src') subdir('po') -executable( - meson.project_name(), - - 'src/app.vala', - - 'src/data/Game.vala', - 'src/data/GameSource.vala', - - 'src/data/sources/steam/Steam.vala', - 'src/data/sources/steam/SteamGame.vala', - - 'src/data/sources/gog/GOG.vala', - 'src/data/sources/gog/GOGGame.vala', - - 'src/ui/windows/MainWindow.vala', - 'src/ui/windows/WebAuthWindow.vala', - - 'src/ui/views/BaseView.vala', - 'src/ui/views/WelcomeView.vala', - - 'src/ui/views/GamesGridView/GamesGridView.vala', - 'src/ui/views/GamesGridView/GameCard.vala', - - 'src/utils/Utils.vala', - 'src/utils/FSUtils.vala', - 'src/utils/Parser.vala', - - icons_gresource, - css_gresource, - - dependencies: [ - dependency('granite'), - dependency('gtk+-3.0'), - dependency('gdk-3.0'), - dependency('webkit2gtk-4.0'), - dependency('glib-2.0'), - dependency('json-glib-1.0'), - dependency('gee-0.8'), - dependency('libsoup-2.4'), - dependency('ivy') - ], - install: true -) +meson.add_install_script('meson/post_install.py') diff --git a/meson/post_install.py b/meson/post_install.py new file mode 100644 index 00000000..dfb71eb9 --- /dev/null +++ b/meson/post_install.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 + +import os +import subprocess + +prefix = os.environ.get('MESON_INSTALL_PREFIX', '/usr/local') +datadir = os.path.join(prefix, 'share') +bindir = os.path.join(prefix, 'bin') +schemadir = os.path.join(os.environ['MESON_INSTALL_PREFIX'], 'share', 'glib-2.0', 'schemas') + +if os.environ.get('MESON_INSTALL_DESTDIR_PREFIX'): + subprocess.call(['ln', '-s', 'com.github.tkashkin.gamehub', os.path.join(os.environ.get('MESON_INSTALL_DESTDIR_PREFIX'), 'bin', 'gamehub')]) + +if not os.environ.get('DESTDIR'): + print('Updating icon cache...') + icon_cache_dir = os.path.join(datadir, 'icons', 'hicolor') + if not os.path.exists(icon_cache_dir): + os.makedirs(icon_cache_dir) + subprocess.call(['gtk-update-icon-cache', '-qtf', icon_cache_dir]) + + print('Compiling gsettings schemas...') + subprocess.call(['glib-compile-schemas', schemadir]) + + print('Updating desktop database...') + desktop_database_dir = os.path.join(datadir, 'applications') + if not os.path.exists(desktop_database_dir): + os.makedirs(desktop_database_dir) + subprocess.call(['update-desktop-database', '-q', desktop_database_dir]) diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 00000000..e5bb23d8 --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,23 @@ +option('git_branch', type: 'string', value: '@GIT_BRANCH@') +option('git_commit', type: 'string', value: '@GIT_COMMIT@') +option('git_commit_short', type: 'string', value: '@GIT_COMMIT_SHORT@') + +option('os', type: 'combo', choices: ['linux', 'windows', 'macos'], value: 'linux') +option('distro', type: 'combo', choices: ['generic', 'debian', 'arch'], value: 'generic') +option('package', type: 'combo', choices: ['generic', 'appimage', 'flatpak'], value: 'generic') + +option('feature_overlayfs', type: 'boolean', value: true) + +option('perf_images_memcache', type: 'boolean', value: false) +option('perf_gamecard_unload_images', type: 'boolean', value: true) + +option('libretro_core_dir', type: 'string', value: '/usr/lib/libretro') +option('libretro_core_info_dir', type: 'string', value: '/usr/share/libretro/info') + +option('api_key_steam', type: 'string', value: '8B10B604CAC6AC90F57AACE025DD904C') +option('api_key_itch', type: 'string', value: '') +option('api_key_igdb', type: 'string', value: 'e0a54818580e4085b596c5aa613b1c53') +option('api_key_steamgriddb', type: 'string', value: '711485c5b6c9b8ca87f6052f6dda04e8') + +option('runtime', type: 'string', value: '') +option('use_libunity', type: 'boolean', value: false) diff --git a/po/LINGUAS b/po/LINGUAS index 562ba4cf..41bc1cd4 100644 --- a/po/LINGUAS +++ b/po/LINGUAS @@ -1 +1,24 @@ ru +pt_BR +pt_PT +id +nb_NO +nl +de +fr +pl +tr +el +fa +hi +te +ar +ko +ca +fi +es_MX +it +zh_CN +zh_HK +zh_TW +mr diff --git a/po/POTFILES b/po/POTFILES index 329fa12e..6f75bfb7 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -1,10 +1,9 @@ -data/com.github.tkashkin.gamehub.appdata.xml.in -data/com.github.tkashkin.gamehub.desktop.in - src/app.vala +src/data/Runnable.vala src/data/Game.vala src/data/GameSource.vala +src/data/Emulator.vala src/data/sources/steam/Steam.vala src/data/sources/steam/SteamGame.vala @@ -12,15 +11,141 @@ src/data/sources/steam/SteamGame.vala src/data/sources/gog/GOG.vala src/data/sources/gog/GOGGame.vala +src/data/sources/humble/Humble.vala +src/data/sources/humble/HumbleGame.vala +src/data/sources/humble/Trove.vala + +src/data/sources/itch/Itch.vala +src/data/sources/itch/ItchGame.vala +src/data/sources/itch/ItchDownloader.vala +src/data/sources/itch/ButlerDaemon.vala +src/data/sources/itch/ButlerConnection.vala +src/data/sources/itch/ButlerClient.vala + +src/data/sources/user/User.vala +src/data/sources/user/UserGame.vala + +src/data/db/Database.vala +src/data/db/Table.vala +src/data/db/tables/Games.vala +src/data/db/tables/Tags.vala +src/data/db/tables/Merges.vala +src/data/db/tables/Emulators.vala +src/data/db/tables/IGDBData.vala + +src/data/CompatTool.vala +src/data/compat/CustomScript.vala +src/data/compat/Innoextract.vala +src/data/compat/WineWrap.vala +src/data/compat/Proton.vala +src/data/compat/Wine.vala +src/data/compat/DOSBox.vala +src/data/compat/ScummVM.vala +src/data/compat/RetroArch.vala +src/data/compat/CustomEmulator.vala + +src/data/adapters/GamesAdapter.vala + +src/data/providers/Provider.vala +src/data/providers/ImagesProvider.vala +src/data/providers/DataProvider.vala +src/data/providers/images/Steam.vala +src/data/providers/images/SteamGridDB.vala +src/data/providers/images/JinxSGVI.vala +src/data/providers/data/IGDB.vala + +src/data/tweaks/Tweak.vala + src/ui/windows/MainWindow.vala src/ui/windows/WebAuthWindow.vala +src/ui/dialogs/SettingsDialog/SettingsDialog.vala +src/ui/dialogs/SettingsDialog/SettingsDialogPage.vala + +src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala +src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala +src/ui/dialogs/SettingsDialog/pages/general/Collection.vala +src/ui/dialogs/SettingsDialog/pages/general/Controller.vala +src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala +src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala +src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala +src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala +src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala +src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala +src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala +src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala +src/ui/dialogs/SettingsDialog/pages/About.vala + +src/ui/dialogs/InstallDialog.vala +src/ui/dialogs/GameDetailsDialog.vala +src/ui/dialogs/GamePropertiesDialog.vala +src/ui/dialogs/GameFSOverlaysDialog.vala +src/ui/dialogs/CompatRunDialog.vala +src/ui/dialogs/CorruptedInstallerDialog.vala +src/ui/dialogs/ImportEmulatedGamesDialog.vala +src/ui/dialogs/GameTweaksDialog.vala + src/ui/views/BaseView.vala src/ui/views/WelcomeView.vala -src/ui/views/GamesGridView/GamesGridView.vala -src/ui/views/GamesGridView/GameCard.vala +src/ui/views/GamesView/GamesView.vala + +src/ui/views/GamesView/grid/GamesGrid.vala +src/ui/views/GamesView/grid/GameCard.vala + +src/ui/views/GamesView/list/GamesList.vala +src/ui/views/GamesView/list/GameListRow.vala + +src/ui/views/GamesView/DownloadProgressView.vala +src/ui/views/GamesView/FiltersPopover.vala +src/ui/views/GamesView/AddGamePopover.vala +src/ui/views/GamesView/GameContextMenu.vala + +src/ui/views/GameDetailsView/GameDetailsView.vala +src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala +src/ui/views/GameDetailsView/GameDetailsPage.vala + +src/ui/views/GameDetailsView/GameDetailsBlock.vala +src/ui/views/GameDetailsView/blocks/Artwork.vala +src/ui/views/GameDetailsView/blocks/Playtime.vala +src/ui/views/GameDetailsView/blocks/Achievements.vala +src/ui/views/GameDetailsView/blocks/Description.vala +src/ui/views/GameDetailsView/blocks/GOGDetails.vala +src/ui/views/GameDetailsView/blocks/SteamDetails.vala +src/ui/views/GameDetailsView/blocks/IGDBInfo.vala + +src/ui/widgets/AutoSizeImage.vala +src/ui/widgets/ActionButton.vala +src/ui/widgets/FileChooserEntry.vala +src/ui/widgets/ExtendedStackSwitcher.vala +src/ui/widgets/ImagesDownloadPopover.vala +src/ui/widgets/CompatToolOptions.vala +src/ui/widgets/CompatToolPicker.vala +src/ui/widgets/GameTagsList.vala +src/ui/widgets/TagRow.vala +src/ui/widgets/Styles.vala +src/ui/widgets/AlertView.vala +src/ui/widgets/ModeButton.vala +src/ui/widgets/OverlayBar.vala +src/ui/widgets/Welcome.vala +src/ui/widgets/SettingsSidebar.vala +src/ui/widgets/TweaksList.vala src/utils/Utils.vala +src/utils/ImageCache.vala src/utils/FSUtils.vala +src/utils/FSOverlay.vala src/utils/Parser.vala +src/utils/BinaryVDF.vala + +src/settings/Settings.vala +src/settings/UI.vala +src/settings/SavedState.vala +src/settings/Auth.vala +src/settings/Compat.vala +src/settings/Providers.vala +src/settings/Controller.vala +src/settings/Tweaks.vala + +src/utils/downloader/Downloader.vala +src/utils/downloader/SoupDownloader.vala diff --git a/po/ar.po b/po/ar.po new file mode 100644 index 00000000..e38ca3b4 --- /dev/null +++ b/po/ar.po @@ -0,0 +1,1879 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the com.github.tkashkin.gamehub package. +# Omar Aglan , 2019. +# abidin toumi , 2019. +msgid "" +msgstr "" +"Project-Id-Version: com.github.tkashkin.gamehub\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-26 06:40+0300\n" +"PO-Revision-Date: 2019-10-19 08:53+0000\n" +"Last-Translator: abidin toumi \n" +"Language-Team: Arabic \n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"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" +"X-Generator: Weblate 3.9.1-dev\n" + +#: src/app.vala:91 +msgid "Show help" +msgstr "عرض التعليمات" + +#: src/app.vala:92 +msgid "Show application version and exit" +msgstr "عرض اصدار التطبيق والخروج" + +#: src/app.vala:93 +msgid "Restart with GDB debugger attached" +msgstr "أعد التشغيل بإرفاق منقح GDB" + +#: src/app.vala:94 +msgid "Show full GDB backtrace" +msgstr "" + +#: src/app.vala:95 +msgid "Treat fatal errors as criticals and crash application" +msgstr "" + +#: src/app.vala:99 +msgid "Show main window" +msgstr "عرض النافذة الرئيسية" + +#: src/app.vala:100 +msgid "Show application settings dialog" +msgstr "اعرض اعدادات التطبيق" + +#: src/app.vala:101 +msgid "Show about dialog" +msgstr "أظهر نافذة حول" + +#: src/app.vala:102 +msgid "Maximum number of background worker threads" +msgstr "العدد الاقصى للخيوط" + +#: src/app.vala:106 +msgid "Run game" +msgstr "شغل اللعبة" + +#: src/app.vala:107 +msgid "Show compatibility options dialog" +msgstr "اعرض اعدادات التوافق" + +#: src/app.vala:108 +msgid "Open game details" +msgstr "اعرض معلومات اللعبة" + +#: src/app.vala:109 +msgid "Open game properties" +msgstr "افتح خصائص اللعبة" + +#: src/app.vala:113 +msgid "Enable debug logging" +msgstr "" + +#: src/app.vala:114 +msgid "" +"Log authentication process and sensitive information like authentication " +"tokens" +msgstr "سجل عملية المصادقة والمعلومات الحساسة مثل رموز المصادقة" + +#: src/app.vala:115 +msgid "Log download manager" +msgstr "" + +#: src/app.vala:116 +msgid "Log background workers start/stop" +msgstr "" + +#: src/app.vala:117 +msgid "Disable log messages filtering" +msgstr "عطل فلترت رسائل السجل" + +#: src/app.vala:118 +msgid "Verbose logging" +msgstr "" + +#: src/app.vala:247 +msgid "Game Options:" +msgstr "خيارات اللعبة:" + +#: src/app.vala:247 +msgid "Show game options help" +msgstr "اعرض التعليمات لخيارت اللعبة" + +#: src/app.vala:255 +msgid "Logging Options:" +msgstr "خيارات الولوج:" + +#: src/app.vala:255 +msgid "Show logging options help" +msgstr "اعرض التعليمات لخيارات الولوج" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +msgid "Select executable" +msgstr "حدد الملف التنفيذي" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:181 src/ui/views/GamesView/GamesView.vala:330 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select" +msgstr "حدد" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:180 src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +#, fuzzy +msgid "Cancel" +msgstr "إلغاء" + +#: src/data/Runnable.vala:166 src/ui/widgets/FileChooserEntry.vala:49 +msgid "Select directory" +msgstr "إختر دليل" + +#: src/data/Runnable.vala:619 +#, c-format +msgid "Part %1$u of %2$u: %3$s" +msgstr "" + +#: src/data/Runnable.vala:642 src/ui/dialogs/CorruptedInstallerDialog.vala:48 +#, c-format +msgid "%s: corrupted installer" +msgstr "%s: مثبت تالف" + +#: src/data/Runnable.vala:643 +#, c-format +msgid "Checksum mismatch in %s" +msgstr "" + +#: src/data/Runnable.vala:657 src/ui/dialogs/CorruptedInstallerDialog.vala:126 +msgid "Show file" +msgstr "إعرض الملف" + +#: src/data/Runnable.vala:658 src/ui/dialogs/CorruptedInstallerDialog.vala:132 +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#: src/ui/widgets/TagRow.vala:146 +msgid "Remove" +msgstr "أزِل" + +#: src/data/Runnable.vala:659 src/ui/dialogs/CorruptedInstallerDialog.vala:128 +msgid "Backup" +msgstr "نسخة إحتياطية" + +#: src/data/Runnable.vala:778 +#, c-format +msgid "%s: cannot detect main executable" +msgstr "%s: لا يمكن التعرف على الملف التنفيذي الرئيسي" + +#: src/data/Runnable.vala:779 +msgid "" +"Main executable file for this game cannot be detected automatically.\n" +"Please set main executable in game's properties." +msgstr "" +"لا يمكن التعرف على الملف التنفيذي للعبة.\n" +"يرجى تعيينه في خصائص اللعبة." + +#: src/data/Runnable.vala:908 +msgctxt "platform" +msgid "Emulated" +msgstr "مُحاكى" + +#: src/data/Game.vala:625 +msgctxt "status" +msgid "Running" +msgstr "يشتغل" + +#: src/data/Game.vala:628 +msgctxt "status" +msgid "Installed" +msgstr "مثبت" + +#: src/data/Game.vala:629 +msgctxt "status" +msgid "Installing" +msgstr "تثبيت" + +#: src/data/Game.vala:630 +msgctxt "status" +msgid "Verifying installer integrity" +msgstr "التحقق من صحة المثبت" + +#: src/data/Game.vala:631 +msgctxt "status" +msgid "Download started" +msgstr "بدأ التحميل" + +#: src/data/Game.vala:633 +msgctxt "status" +msgid "Not installed" +msgstr "لم تثبت" + +#: src/data/Game.vala:643 +msgctxt "status_header" +msgid "Installed" +msgstr "تم التثيت" + +#: src/data/Game.vala:644 +msgctxt "status_header" +msgid "Installing" +msgstr "تثبيت" + +#: src/data/Game.vala:646 +msgctxt "status_header" +msgid "Downloading" +msgstr "يحمل" + +#: src/data/Game.vala:648 +msgctxt "status_header" +msgid "Not installed" +msgstr "لم يثبت" + +#: src/data/GameSource.vala:31 +#, c-format +msgid "%s games" +msgstr "%s ألعاب" + +#: src/data/sources/steam/Steam.vala:43 +msgid "Your SteamID will be read from Steam configuration file" +msgstr "سيتم قراءة المعرف من Steam" + +#: src/data/sources/steam/Steam.vala:46 +msgid "" +"Steam config file not found.\n" +"Login into your account in Steam client and return to GameHub" +msgstr "" +"لم يُعثر على ملف اعدادات ستيم.\n" +"سجل دخولك في عميل ستيم ثم عد الى GameHub" + +#: src/data/sources/gog/GOGGame.vala:983 +#, c-format +msgid "DLC: %s" +msgstr "" + +#: src/data/sources/humble/HumbleGame.vala:343 +#, c-format +msgid "%s: no available installers" +msgstr "%s: المثبت غير متوفر" + +#: src/data/sources/humble/HumbleGame.vala:344 +msgid "" +"Cannot get Trove download URL.\n" +"Make sure your Humble Monthly subscription is active." +msgstr "" +"لم يتم الحصول على رابط التحميل.\n" +"تأكد من أن اشتراكك الشهري في Humble مفعل." + +#: src/data/sources/itch/ItchDownloader.vala:192 +#, c-format +msgctxt "itch_dl_status" +msgid "%s left;" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:195 +#, c-format +msgctxt "itch_dl_status" +msgid "%d%%" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:198 +#, c-format +msgctxt "itch_dl_status" +msgid "(%1$s / %2$s)" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:201 +#, c-format +msgctxt "itch_dl_status" +msgid "[%s/s]" +msgstr "" + +#: src/data/sources/user/User.vala:30 +msgid "User games" +msgstr "ألعاب المستخدم" + +#: src/data/db/tables/Tags.vala:225 +msgctxt "tag" +msgid "Favorites" +msgstr "المفضلة" + +#: src/data/db/tables/Tags.vala:226 +msgctxt "tag" +msgid "Not installed" +msgstr "لم تثبت" + +#: src/data/db/tables/Tags.vala:227 +msgctxt "tag" +msgid "Installed" +msgstr "مثبت" + +#: src/data/db/tables/Tags.vala:228 +msgctxt "tag" +msgid "Hidden" +msgstr "مخفي" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit script" +msgstr "عدل البرنامج النصي" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit custom script" +msgstr "عدل برنامج نصي مخصص" + +#: src/data/compat/Innoextract.vala:55 +#, c-format +msgid "" +"Innoextract %1$s is not supported and may not be able to extract some " +"games correctly.\n" +"Install innoextract %2$s or newer." +msgstr "" +"Innoextract %1$s غير مدعوم وقد لا يتمكن من استخراج اللعبة بشكل صحيح\n" +"قم بتثبيت النسخة %2$s أو احدث" + +#: src/data/compat/WineWrap.vala:61 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:242 +#: src/ui/dialogs/CompatRunDialog.vala:102 +#: src/ui/views/GamesView/GameContextMenu.vala:53 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:234 +msgid "Run" +msgstr "شغل" + +#: src/data/compat/WineWrap.vala:64 +msgid "Show WineWrap menu" +msgstr "" + +#: src/data/compat/WineWrap.vala:67 src/data/compat/Proton.vala:122 +#: src/data/compat/Wine.vala:83 +msgid "Kill apps in prefix" +msgstr "" + +#: src/data/compat/Proton.vala:47 +msgid "Proton prefix" +msgstr "" + +#: src/data/compat/Proton.vala:110 src/data/compat/Wine.vala:71 +msgid "Open prefix directory" +msgstr "" + +#: src/data/compat/Proton.vala:113 src/data/compat/Wine.vala:74 +msgid "Run winecfg" +msgstr "شغل اعدادات wine" + +#: src/data/compat/Proton.vala:116 src/data/compat/Wine.vala:77 +msgid "Run winetricks" +msgstr "شَغِّل winetricks" + +#: src/data/compat/Proton.vala:119 src/data/compat/Wine.vala:80 +msgid "Run taskmgr" +msgstr "شغل مدير المهام" + +#: src/data/compat/Wine.vala:53 +msgid "Wine prefix" +msgstr "" + +#: src/data/compat/Wine.vala:55 +#, fuzzy +msgid "Environment variables" +msgstr "متغيرات البيئة" + +#: src/data/compat/Wine.vala:60 +msgid "InnoSetup default options" +msgstr "خيارات InnoSetup الافتراضية" + +#: src/data/compat/RetroArch.vala:53 +msgid "Libretro core file" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:43 +msgid "Custom emulator" +msgstr "محاكي مخصص" + +#: src/data/compat/CustomEmulator.vala:48 +msgid "Emulator" +msgstr "محاكي" + +#: src/data/compat/CustomEmulator.vala:49 +msgid "Launch in game directory" +msgstr "شغل في دليل اللعبة" + +#: src/data/adapters/GamesAdapter.vala:440 +msgctxt "status_header" +msgid "Favorites" +msgstr "المفضلة" + +#: src/data/adapters/GamesAdapter.vala:445 +#, c-format +msgctxt "status_header" +msgid "%s: Favorites" +msgstr "%s: مفضلة" + +#: src/data/adapters/GamesAdapter.vala:491 +msgid "Merging games" +msgstr "دمج الالعاب" + +#: src/data/adapters/GamesAdapter.vala:504 +#, c-format +msgid "Merging games from %s" +msgstr "دمج الالعاب من %s" + +#: src/data/adapters/GamesAdapter.vala:551 +#, c-format +msgid "Loading games from %s" +msgstr "تحميل الألعاب من %s" + +#: src/data/adapters/GamesAdapter.vala:678 +msgctxt "sort_mode" +msgid "By name" +msgstr "بالإسم" + +#: src/data/adapters/GamesAdapter.vala:679 +msgctxt "sort_mode" +msgid "By last launch" +msgstr "بالأحدث تشغيلا" + +#: src/data/adapters/GamesAdapter.vala:680 +msgctxt "sort_mode" +msgid "By playtime" +msgstr "بمدة اللعب" + +#: src/data/adapters/GamesAdapter.vala:705 +msgctxt "group_mode" +msgid "Do not group" +msgstr "لا تجمع" + +#: src/data/adapters/GamesAdapter.vala:706 +msgctxt "group_mode" +msgid "By status" +msgstr "بالحالة" + +#: src/data/adapters/GamesAdapter.vala:707 +msgctxt "group_mode" +msgid "By source" +msgstr "بالمصدر" + +#: src/data/providers/images/SteamGridDB.vala:151 +#: src/data/providers/data/IGDB.vala:431 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:217 +msgid "Default" +msgstr "إفتراضي" + +#: src/data/providers/images/SteamGridDB.vala:158 +#: src/data/providers/data/IGDB.vala:438 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:225 +msgid "Restore default API key" +msgstr "استعد مفتاح API الافتراضي" + +#: src/data/providers/images/SteamGridDB.vala:169 +#: src/data/providers/data/IGDB.vala:449 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:108 +msgid "API key" +msgstr "مفتاح API" + +#: src/data/providers/images/SteamGridDB.vala:177 +#: src/data/providers/data/IGDB.vala:457 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:53 +msgid "Generate key" +msgstr "توليد مفتاح" + +#: src/data/providers/images/SteamGridDB.vala:208 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Style" +msgstr "نمط" + +#: src/data/providers/images/SteamGridDB.vala:209 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Score" +msgstr "التقييم" + +#: src/data/providers/images/SteamGridDB.vala:213 +#, fuzzy +msgctxt "imagesource_steamgriddb_image_property" +msgid "Author" +msgstr "المالك" + +#: src/data/providers/images/SteamGridDB.vala:225 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Alternate" +msgstr "بديل" + +#: src/data/providers/images/SteamGridDB.vala:226 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Blurred" +msgstr "" + +#. TRANSLATORS: Flat / Material Design image style. Probably should not be translated +#: src/data/providers/images/SteamGridDB.vala:228 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Material" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:229 +msgctxt "imagesource_steamgriddb_image_style" +msgid "No logo" +msgstr "بدون شعار" + +#: src/data/providers/images/SteamGridDB.vala:230 +msgctxt "imagesource_steamgriddb_image_style" +msgid "White logo" +msgstr "شعار أبيض" + +#: src/data/providers/data/IGDB.vala:147 +msgid "" +"Monthly IGDB request quota has been reached. Set your own API key to use " +"IGDB data or disable IGDB." +msgstr "" + +#: src/data/providers/data/IGDB.vala:148 +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:40 +#: src/ui/views/WelcomeView.vala:53 src/ui/views/WelcomeView.vala:78 +#: src/ui/views/GamesView/GamesView.vala:230 +#: src/ui/views/GamesView/GamesView.vala:629 +msgid "Settings" +msgstr "إعدادات" + +#: src/data/providers/data/IGDB.vala:356 +msgctxt "igdb_related_link" +msgid "Official website" +msgstr "الموقع الرسمي" + +#: src/data/providers/data/IGDB.vala:469 +msgctxt "igdb_preferred_description" +msgid "When game has description, show description" +msgstr "عند توفر وصف للعبة إعرضه" + +#: src/data/providers/data/IGDB.vala:476 +msgctxt "igdb_preferred_description" +msgid "of game" +msgstr "للعبة" + +#: src/data/providers/data/IGDB.vala:477 +msgctxt "igdb_preferred_description" +msgid "from IGDB" +msgstr "من IGDB" + +#: src/data/providers/data/IGDB.vala:478 +msgctxt "igdb_preferred_description" +msgid "both" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:65 +msgid "Some settings will be applied after application restart" +msgstr "بعض الاعدادات تحتاج لإعادة التشغيل لتطبيقها" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:71 +msgid "Games directory contains space. It may cause problems for some games" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:36 +msgid "Interface" +msgstr "الواجهة" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:37 +msgid "Appearance" +msgstr "المظهر" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:38 +msgid "General interface settings" +msgstr "إعدادات الواجهة العامة" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:48 +msgid "Dark theme" +msgstr "السمة الليلية" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:53 +msgctxt "icon_style" +msgid "Theme-based" +msgstr "مبني على السمة" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:54 +msgctxt "icon_style" +msgid "Symbolic" +msgstr "رمزي" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:55 +msgctxt "icon_style" +msgid "Colored" +msgstr "ملون" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:57 +msgctxt "icon_style" +msgid "Icon style" +msgstr "سمة الايقونات" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:84 +msgid "Game card" +msgstr "بطاقة اللعبة" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:86 +msgid "Show platform icons" +msgstr "إعرض أيقونات المنصة" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:99 +msgctxt "grid_size" +msgid "Card size" +msgstr "حجم البطاقة" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:117 +msgctxt "grid_size_preset" +msgid "Presets" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:139 +msgid "Games list: installed" +msgstr "قائمة الألعاب: المثبتت" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:140 +msgid "Games list: not installed" +msgstr "قائمة الألعاب: غير المثبتت" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:142 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:146 +msgctxt "list_style" +msgid "Show icon" +msgstr "إعرض الايقونة" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:143 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:147 +msgctxt "list_style" +msgid "Bold title" +msgstr "عنوان عريض" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:144 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:148 +msgctxt "list_style" +msgid "Show status" +msgstr "عرض الحالة" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:149 +msgctxt "list_style" +msgid "Dim" +msgstr "معتم" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:151 +msgid "Grid options" +msgstr "خيارات التخطيط" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:152 +msgid "List options" +msgstr "خيارات القائمة" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:31 +msgid "Behavior" +msgstr "السلوك" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:32 +msgid "Behavior settings" +msgstr "خيارات السلوك" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:42 +msgid "Run games with double click" +msgstr "شغل الألعاب عند النقر المزدوج" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:46 +msgid "Merge games from different sources" +msgstr "دمج الألعاب من مصادر مختلفة" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:50 +msgid "Use imported tags" +msgstr "استخدم الوسوم المستوردة" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:51 +msgid "General" +msgstr "عام" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:52 +msgid "Collection" +msgstr "التجميعة" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:53 +msgid "Empty" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:65 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:85 +msgid "Collection directory" +msgstr "دليل المجموعة" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:70 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:78 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:87 +msgid "Game directory" +msgstr "دليل اللعبة" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:71 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:79 +msgid "Installers" +msgstr "المثبتات" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:72 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:98 +msgid "DLC" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:73 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:197 +msgid "Bonus content" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:84 +msgid "Variable syntax: $var or ${var}" +msgstr "سياق المتغير: $var أو ${var}" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:86 +msgid "Game name" +msgstr "اسم اللعبة" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:88 +#: src/ui/views/GamesView/FiltersPopover.vala:127 +msgid "Platform" +msgstr "المنصة" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:36 +msgid "Controller" +msgstr "يد التحكم" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +msgid "Enabled" +msgstr "مفعل" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:53 +msgid "Focus GameHub window with Guide button" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:57 +msgid "Controllers" +msgstr "أيدي التحكم" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:89 +msgid "Move focus" +msgstr "أنقل التحديد" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:91 +msgid "Exit" +msgstr "غادر" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:40 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:108 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:92 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:95 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:36 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:77 +msgid "Disabled" +msgstr "مٌعطل" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:47 +#: src/ui/dialogs/GameTweaksDialog.vala:53 +#: src/ui/views/GamesView/GameContextMenu.vala:183 +msgid "Tweaks" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:34 +msgid "Tweak launch options and apply them to games automatically" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:79 +msgid "" +"Tweaks are loaded from following directories in order\n" +"Last tweak overrides previous tweaks with same identifiers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:83 +msgid "Click to open" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:93 +#, c-format +msgid "Tweaks are loaded from %1$s and %2$d more directories (?)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:38 +msgid "Game sources" +msgstr "مصادر اللعبة" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +msgid "Steam API keys have limited number of uses per day" +msgstr "مرات استخدام مفتاح Steam API محدودة باليوم" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:63 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:57 +msgid "Installation directory" +msgstr "دليل التثبيت" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:176 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:81 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:34 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:75 +msgid "Not installed" +msgstr "لم يثبت" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:116 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:96 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:99 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:85 +msgid "Not authenticated" +msgstr "بدون توثيق" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +#, c-format +msgid "Authenticated as %s" +msgstr "موثق ک %s" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:103 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +msgid "Authenticated" +msgstr "موثق" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:183 +#: src/ui/dialogs/InstallDialog.vala:53 src/ui/dialogs/InstallDialog.vala:111 +#: src/ui/views/GamesView/GameContextMenu.vala:80 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:233 +#: src/ui/widgets/TweaksList.vala:95 +msgid "Install" +msgstr "ثبت" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:236 +msgid "Steam API key" +msgstr "مفتاح Steam API" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:50 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:54 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:48 +msgid "Games directory" +msgstr "دليل الالعاب" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:63 +msgid "Logout" +msgstr "خروج" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:50 +msgid "Load games from Humble Trove" +msgstr "حمل الالعاب من Humble Trove" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:45 +msgid "Emulators" +msgstr "المحاكيات" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:45 +msgid "Libretro core directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:46 +msgid "Libretro core info directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:50 +msgid "Ignored libretro cores" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:54 +msgid "Ignored game file extensions" +msgstr "تجاهل ملحق ملف اللعبة" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:66 +msgid "No cores found" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:70 +#, c-format +msgid "%u core found" +msgid_plural "%u cores found" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" +msgstr[4] "" +msgstr[5] "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:46 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:168 +msgid "No custom emulators" +msgstr "بدون محاكي مخصص" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:164 +#, c-format +msgid "%u custom emulator" +msgid_plural "%u custom emulators" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" +msgstr[4] "" +msgstr[5] "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:237 +msgid "Save" +msgstr "احفظ" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:250 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:312 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/dialogs/GamePropertiesDialog.vala:168 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +#: src/ui/views/GamesView/AddGamePopover.vala:67 +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Executable" +msgstr "الملف التنفيذي" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:251 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/views/GamesView/AddGamePopover.vala:68 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Installer" +msgstr "مثبت" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:256 +#: src/ui/dialogs/GamePropertiesDialog.vala:64 +#: src/ui/dialogs/GamePropertiesDialog.vala:69 +#: src/ui/views/GamesView/AddGamePopover.vala:73 +msgid "Name" +msgstr "الاسم" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:272 +#: src/ui/dialogs/GamePropertiesDialog.vala:201 +#: src/ui/views/GamesView/AddGamePopover.vala:78 +msgid "Arguments" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:276 +msgid "Variables" +msgstr "المتغيرات" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:277 +msgid "Game executable" +msgstr "الملف التنفيذي للعبة" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:278 +msgid "Game arguments" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:80 +#: src/ui/views/GamesView/AddGamePopover.vala:82 +#, fuzzy +msgid "Directory" +msgstr "الدليل" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +msgid "Select emulator directory" +msgstr "حدد دليل المحاكي" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:292 +#: src/ui/dialogs/GamePropertiesDialog.vala:219 +msgid "Force compatibility mode" +msgstr "افرض وضع التوافق" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:307 +msgid "Game file patterns" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:315 +msgid "Image" +msgstr "صورة" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:318 +msgid "Icon" +msgstr "أيقونة" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:325 +msgid "" +"findutils-compatible glob patterns\n" +"\n" +" Multiple patterns can be separated with |\n" +" Start pattern with ./ to match relative path\n" +" $basename variable will be replaced with game's executable " +"name (without extension)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:38 +msgid "Data" +msgstr "البيانات" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:39 +msgid "Providers" +msgstr "الناشر" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:40 +msgid "Third-party data providers" +msgstr "ناشر بيانات الطرف الثالث" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:55 +msgid "Image providers" +msgstr "موفر الصورة" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:68 +msgid "Metadata providers" +msgstr "موفِر البيانات الوصفية" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:137 +msgid "Open website" +msgstr "افتح الموقع" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:36 +msgid "About" +msgstr "حول" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:71 +msgid "Copy application version and environment info" +msgstr "انسخ اصدار التطبيق ومعلومات البيئة" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:78 +#: src/ui/views/WelcomeView.vala:57 +msgid "All your games in one place" +msgstr "كل ألعابك في مكان واحد" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:92 +msgctxt "about_link" +msgid "Website" +msgstr "الموقع" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:96 +msgctxt "about_link" +msgid "Source code on GitHub" +msgstr "الكود المصدري على GitHub" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:103 +msgctxt "about_link" +msgid "Report a problem" +msgstr "أبلغ عن مشكلة" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:104 +msgctxt "about_link" +msgid "Suggest translations" +msgstr "اقترح ترجمة" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:110 +msgctxt "about_link" +msgid "Issues" +msgstr "علل" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:111 +msgctxt "about_link" +msgid "Contributors" +msgstr "المساهمون" + +#. TRANSLATORS: Likely it should not be translated. GitHub Pulse is a page that shows recent repository activity: https://github.com/tkashkin/GameHub/pulse +#: src/ui/dialogs/SettingsDialog/pages/About.vala:114 +msgctxt "about_link" +msgid "Pulse" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:115 +msgctxt "about_link" +msgid "Forks" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:109 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:129 +msgid "Import" +msgstr "استورد" + +#: src/ui/dialogs/InstallDialog.vala:110 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:153 +msgid "Download" +msgstr "حمل" + +#: src/ui/dialogs/InstallDialog.vala:207 +msgid "Select installer" +msgstr "اختر مثبت" + +#: src/ui/dialogs/InstallDialog.vala:216 +#, c-format +msgid "Installer size: %s" +msgstr "حجم التثبيت: %s" + +#: src/ui/dialogs/InstallDialog.vala:348 +msgid "Unknown" +msgstr "مجهول" + +#: src/ui/dialogs/GamePropertiesDialog.vala:49 +#, c-format +msgid "%s: Properties" +msgstr "%s: خصائص" + +#: src/ui/dialogs/GamePropertiesDialog.vala:84 +msgid "Images" +msgstr "صور" + +#: src/ui/dialogs/GamePropertiesDialog.vala:126 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:160 +#: src/ui/views/GameDetailsView/blocks/Artwork.vala:62 +msgid "Download images" +msgstr "حمِل الصور" + +#: src/ui/dialogs/GamePropertiesDialog.vala:144 +msgid "Image URL" +msgstr "رابط الصورة" + +#: src/ui/dialogs/GamePropertiesDialog.vala:148 +msgid "Vertical image URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:157 +msgid "Icon URL" +msgstr "رابط الأيقونة" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +#, fuzzy +msgid "Select working directory" +msgstr "إختر دليل" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +#, fuzzy +msgid "Working directory" +msgstr "افتح الدليل" + +#: src/ui/dialogs/GamePropertiesDialog.vala:214 +msgid "Compatibility" +msgstr "التوافق" + +#: src/ui/dialogs/GamePropertiesDialog.vala:236 +msgid "Launch from terminal" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:252 +msgid "Copy to clipboard" +msgstr "انسخ الى الحافظة" + +#: src/ui/dialogs/GamePropertiesDialog.vala:254 +msgid "Add to Steam" +msgstr "أضف الى ستيم" + +#: src/ui/dialogs/GamePropertiesDialog.vala:255 +msgid "Add to the Steam library" +msgstr "أضف الى مكتبة ستيم" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:53 +#, c-format +msgid "%s: Overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "Overlays are disabled" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "" +"Enable overlays to manage DLCs and mods\n" +"\n" +"Enabling will move game to the “base“ overlay" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:77 +#: src/ui/views/GamesView/GameContextMenu.vala:175 +msgid "Overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:105 +msgid "Overlay ID (directory name)" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:110 +msgid "Overlay name (optional)" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:112 +msgid "Add" +msgstr "أضف" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:127 +msgid "Enable overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:182 +#, c-format +msgid "" +"Overlay usage at this path may be unsafe\n" +"Proceed at your own risk\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:187 +#, c-format +msgid "" +"Overlay usage at this path is not supported\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:266 +msgid "Open directory" +msgstr "افتح الدليل" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:271 +msgid "Remove overlay" +msgstr "" + +#: src/ui/dialogs/CompatRunDialog.vala:48 +#: src/ui/views/GamesView/GameContextMenu.vala:46 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:235 +msgid "Run with compatibility layer" +msgstr "" + +#: src/ui/dialogs/CorruptedInstallerDialog.vala:71 +msgid "Corrupted installer: checksum mismatch in" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:57 +#: src/ui/views/GamesView/AddGamePopover.vala:105 +msgid "Import emulated games" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:75 +msgid "Select directory with emulated games" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:83 +msgid "Detected games" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:107 +msgid "Select all" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:115 +msgid "Select directory to import" +msgstr "" + +#: src/ui/dialogs/GameTweaksDialog.vala:40 +#, c-format +msgid "%s: Tweaks" +msgstr "" + +#: src/ui/views/WelcomeView.vala:52 +msgid "No enabled game sources" +msgstr "" + +#: src/ui/views/WelcomeView.vala:52 +msgid "Enable some game sources in settings" +msgstr "" + +#: src/ui/views/WelcomeView.vala:57 +msgid "Let's get started" +msgstr "" + +#: src/ui/views/WelcomeView.vala:71 +msgid "Skip" +msgstr "" + +#: src/ui/views/WelcomeView.vala:141 +msgid "Ready" +msgstr "" + +#: src/ui/views/WelcomeView.vala:147 +msgid "Authentication required" +msgstr "" + +#: src/ui/views/WelcomeView.vala:152 +msgid "Authenticating…" +msgstr "" + +#: src/ui/views/WelcomeView.vala:163 +#, c-format +msgid "Install %s" +msgstr "" + +#: src/ui/views/WelcomeView.vala:164 +msgid "Return to GameHub after installing" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "No games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "Get some games or enable some game sources in settings" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:150 +msgid "Grid view" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:151 +msgid "List view" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:159 +msgid "All games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:182 +msgid "Downloads" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:208 +msgid "Filters" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:216 +#: src/ui/views/GamesView/AddGamePopover.vala:84 +msgid "Add game" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:223 +msgid "Search" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:328 +msgid "Menu" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:329 +#: src/ui/views/GameDetailsView/GameDetailsView.vala:104 +msgid "Back" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:550 +#, fuzzy, c-format +msgid "%u game" +msgid_plural "%u games" +msgstr[0] "شغل اللعبة" +msgstr[1] "شغل اللعبة" +msgstr[2] "شغل اللعبة" +msgstr[3] "شغل اللعبة" +msgstr[4] "شغل اللعبة" +msgstr[5] "شغل اللعبة" + +#: src/ui/views/GamesView/GamesView.vala:553 +#, c-format +msgctxt "games_view_subtitle_filtered_games" +msgid "%1$u / %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:557 +#, c-format +msgctxt "games_view_subtitle" +msgid "%1$s: %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:568 +msgid "No user-added games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:569 +msgid "Add some games using plus button" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:573 +#, c-format +msgid "No %s games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:574 +msgid "Get some Linux-compatible games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:584 +#, c-format +msgid "No games matching “%s”" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:589 +#, c-format +msgid "No %1$s games matching “%2$s”" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:627 +msgid "" +"No games were loaded from Steam. Set your games list privacy to public or " +"use your own Steam API key in settings." +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:628 +msgid "Privacy" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:739 +msgid "Downloading images" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:753 +#, c-format +msgid "Downloading image: %s" +msgstr "" + +#: src/ui/views/GamesView/DownloadProgressView.vala:131 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:162 +msgid "Pause download" +msgstr "" + +#: src/ui/views/GamesView/DownloadProgressView.vala:137 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:168 +msgid "Resume download" +msgstr "" + +#: src/ui/views/GamesView/DownloadProgressView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:174 +msgid "Cancel download" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:77 +msgid "Group" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:102 +msgid "Sort" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:234 +#: src/ui/widgets/GameTagsList.vala:58 +msgid "Tags" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:353 +msgid "All platforms" +msgstr "" + +#: src/ui/views/GamesView/AddGamePopover.vala:77 +msgid "Select game executable" +msgstr "" + +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Select game directory" +msgstr "" + +#: src/ui/views/GamesView/AddGamePopover.vala:111 +msgid "Download game images" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:87 +msgid "Details" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:117 +msgctxt "game_context_menu" +msgid "Favorite" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:121 +msgctxt "game_context_menu" +msgid "Hidden" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:133 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:236 +msgid "Open installation directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:142 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:237 +msgid "Open installers collection directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:151 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:238 +msgid "Open bonus collection directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:160 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:239 +msgid "Open screenshots directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +msgid "Uninstall" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:192 +msgid "Properties" +msgstr "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:100 +#, c-format +msgid "%d game selected" +msgid_plural "%d games selected" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" +msgstr[4] "" +msgstr[5] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:144 +#, c-format +msgid "%d game will be installed" +msgid_plural "%d games will be installed" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" +msgstr[4] "" +msgstr[5] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:154 +#, c-format +msgid "%d game will be downloaded" +msgid_plural "%d games will be downloaded" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" +msgstr[4] "" +msgstr[5] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:161 +#, c-format +msgid "Image for %d game will be searched" +msgid_plural "Images for %d games will be searched" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" +msgstr[4] "" +msgstr[5] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:168 +#, c-format +msgid "%d game will be uninstalled" +msgid_plural "%d games will be uninstalled" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" +msgstr[4] "" +msgstr[5] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:174 +msgid "Refresh" +msgstr "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:175 +#, c-format +msgid "" +"%d game will be removed from database. Restart GameHub to fetch new data" +msgid_plural "" +"%d games will be removed from database. Restart GameHub to fetch new data" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" +msgstr[4] "" +msgstr[5] "" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:240 +msgid "Open store page" +msgstr "" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:242 +msgid "Game properties" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:46 +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:60 +msgid "Playtime" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:52 +msgid "Playtime (local)" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:69 +msgid "Last launch" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:46 +msgid "Achievements" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:85 +#, c-format +msgid "Unlocked: %s" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:90 +#, c-format +msgid "Global percentage: %g%%" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:77 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:103 +msgid "Language" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:80 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:106 +msgid "Languages" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:147 +#, fuzzy, c-format +msgid "%u DLCs cannot be installed" +msgstr "%s: مثبت تالف" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:71 +msgid "Category" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:74 +msgid "Categories" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:90 +msgid "Genre" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:93 +msgid "Genres" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:109 +msgctxt "igdb" +msgid "Popularity" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:115 +msgctxt "igdb" +msgid "Aggregated rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:116 +msgctxt "igdb" +msgid "IGDB user rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:117 +msgctxt "igdb" +msgid "Total rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:126 +msgctxt "igdb" +msgid "Release date" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:133 +msgctxt "igdb" +msgid "Platforms" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:139 +msgctxt "igdb" +msgid "Genres" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:145 +msgctxt "igdb" +msgid "Keywords" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:152 +msgctxt "igdb" +msgid "Links" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:208 +#, c-format +msgid "Based on %d rating" +msgid_plural "Based on %d ratings" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" +msgstr[4] "" +msgstr[5] "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:290 +msgctxt "igdb" +msgid "Summary" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:301 +msgctxt "igdb" +msgid "Storyline" +msgstr "" + +#: src/ui/widgets/FileChooserEntry.vala:49 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select file" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "No images" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "" +"There are no images found for this game\n" +"Make sure game name is correct" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:94 +msgid "Search images:" +msgstr "" + +#: src/ui/widgets/CompatToolPicker.vala:53 +msgid "Compatibility layer:" +msgstr "" + +#: src/ui/widgets/CompatToolPicker.vala:92 +msgid "Configure" +msgstr "" + +#: src/ui/widgets/GameTagsList.vala:109 +msgid "Add tag" +msgstr "" + +#: src/ui/widgets/TweaksList.vala:86 +msgid "No description" +msgstr "" + +#: src/ui/widgets/TweaksList.vala:124 +#, fuzzy +msgid "Edit file" +msgstr "عدل البرنامج النصي" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dh" +msgstr "" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dm" +msgstr "" + +#: src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%ds" +msgstr "" + +#: src/settings/UI.vala:153 +msgctxt "grid_size_preset" +msgid "Steam" +msgstr "" + +#: src/settings/UI.vala:154 +msgctxt "grid_size_preset" +msgid "Steam (vertical)" +msgstr "" + +#: src/settings/UI.vala:155 +msgctxt "grid_size_preset" +msgid "GOG" +msgstr "" + +#: src/settings/UI.vala:156 +msgctxt "grid_size_preset" +msgid "GOG (vertical)" +msgstr "" + +#: src/settings/UI.vala:157 +msgctxt "grid_size_preset" +msgid "Square" +msgstr "" + +#: src/settings/UI.vala:158 +msgctxt "grid_size_preset" +msgid "Custom" +msgstr "" + +#: src/utils/downloader/Downloader.vala:200 +msgctxt "dl_status" +msgid "Queued" +msgstr "" + +#: src/utils/downloader/Downloader.vala:201 +msgctxt "dl_status" +msgid "Starting download" +msgstr "" + +#: src/utils/downloader/Downloader.vala:202 +msgctxt "dl_status" +msgid "Download started" +msgstr "" + +#: src/utils/downloader/Downloader.vala:203 +msgctxt "dl_status" +msgid "Download finished" +msgstr "" + +#: src/utils/downloader/Downloader.vala:204 +msgctxt "dl_status" +msgid "Download failed" +msgstr "" + +#: src/utils/downloader/Downloader.vala:208 +#, fuzzy, c-format +msgctxt "dl_status" +msgid "Downloading: %s" +msgstr "يحمل" + +#: src/utils/downloader/Downloader.vala:210 +#, fuzzy +msgctxt "dl_status" +msgid "Downloading" +msgstr "يحمل" + +#: src/utils/downloader/Downloader.vala:214 +#, c-format +msgctxt "dl_status" +msgid "Paused: %s" +msgstr "" + +#: src/utils/downloader/Downloader.vala:216 +msgctxt "dl_status" +msgid "Paused" +msgstr "" + +#: src/utils/downloader/Downloader.vala:218 +msgctxt "dl_status" +msgid "Download cancelled" +msgstr "" + +#. TRANSLATORS: Download progress template. %1$d - percentage, %2$s / %3$s - downloaded portion and total file size, %4$s - download speed +#: src/utils/downloader/Downloader.vala:262 +#, c-format +msgctxt "dl_status" +msgid "%1$d%% (%2$s / %3$s) [%4$s/s]" +msgstr "" + +#~ msgid "Disable esync" +#~ msgstr "عطل esync" + +#~ msgid "Disable DirectX 11 compatibility layer" +#~ msgstr "عطل طبقة توافق DirectX 11" + +#~ msgid "Use WineD3D11 as DirectX 11 compatibility layer" +#~ msgstr "استخدم WineD3D11 كطبقة توافق DirectX 11" + +#, fuzzy +#~ msgid "Enable DirectX 9 compatibility layer" +#~ msgstr "عطل طبقة توافق DirectX 11" + +#~ msgid "Silent installation" +#~ msgstr "تثبيت صامت" + +#~ msgid "Very silent installation" +#~ msgstr "تثبيت اكثر صمتاَ" + +#~ msgid "No GUI" +#~ msgstr "بدون واجهة" diff --git a/po/ca.po b/po/ca.po new file mode 100644 index 00000000..c580a929 --- /dev/null +++ b/po/ca.po @@ -0,0 +1,1880 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the com.github.tkashkin.gamehub package. +# Marc Riera , 2019. +# Marc Riera , 2019, 2020. +msgid "" +msgstr "" +"Project-Id-Version: com.github.tkashkin.gamehub\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-26 06:40+0300\n" +"PO-Revision-Date: 2020-01-14 18:21+0000\n" +"Last-Translator: Marc Riera \n" +"Language-Team: Catalan \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 3.11-dev\n" + +#: src/app.vala:91 +msgid "Show help" +msgstr "Mostra l'ajuda" + +#: src/app.vala:92 +msgid "Show application version and exit" +msgstr "Mostra la versió de l'aplicació i surt" + +#: src/app.vala:93 +msgid "Restart with GDB debugger attached" +msgstr "Reinicia amb el depurador del GDB acoblat" + +#: src/app.vala:94 +msgid "Show full GDB backtrace" +msgstr "Mostra la traça inversa completa del GDB" + +#: src/app.vala:95 +msgid "Treat fatal errors as criticals and crash application" +msgstr "Tracta els errors fatals com a crítics i fes fallar l'aplicació" + +#: src/app.vala:99 +msgid "Show main window" +msgstr "Mostra la finestra principal" + +#: src/app.vala:100 +msgid "Show application settings dialog" +msgstr "Mostra el quadre de diàleg de paràmetres de l'aplicació" + +#: src/app.vala:101 +msgid "Show about dialog" +msgstr "Mostra el quadre de diàleg Quant a" + +#: src/app.vala:102 +msgid "Maximum number of background worker threads" +msgstr "Nombre màxim de fils del procés de treball en segon pla" + +#: src/app.vala:106 +msgid "Run game" +msgstr "Executa el joc" + +#: src/app.vala:107 +msgid "Show compatibility options dialog" +msgstr "Mostra el quadre de diàleg d'opcions de compatibilitat" + +#: src/app.vala:108 +msgid "Open game details" +msgstr "Obre els detalls del joc" + +#: src/app.vala:109 +msgid "Open game properties" +msgstr "Obre les propietats del joc" + +#: src/app.vala:113 +msgid "Enable debug logging" +msgstr "Habilita el registre de depuració" + +#: src/app.vala:114 +msgid "" +"Log authentication process and sensitive information like authentication " +"tokens" +msgstr "" +"Registra el procés d'autenticació i informació confidencial com els " +"testimonis d'autenticació" + +#: src/app.vala:115 +msgid "Log download manager" +msgstr "Registra el gestor de baixades" + +#: src/app.vala:116 +msgid "Log background workers start/stop" +msgstr "Registra els inicis i aturades dels processos de treball en segon pla" + +#: src/app.vala:117 +msgid "Disable log messages filtering" +msgstr "Inhabilita el filtratge dels missatges de registre" + +#: src/app.vala:118 +msgid "Verbose logging" +msgstr "Registre detallat" + +#: src/app.vala:247 +msgid "Game Options:" +msgstr "Opcions del joc:" + +#: src/app.vala:247 +msgid "Show game options help" +msgstr "Mostra l'ajuda de les opcions del joc" + +#: src/app.vala:255 +msgid "Logging Options:" +msgstr "Opcions del registre:" + +#: src/app.vala:255 +msgid "Show logging options help" +msgstr "Mostra l'ajuda de les opcions del registre" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +msgid "Select executable" +msgstr "Seleccioneu un executable" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:181 src/ui/views/GamesView/GamesView.vala:330 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select" +msgstr "Selecciona" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:180 src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Cancel" +msgstr "Cancel·la" + +#: src/data/Runnable.vala:166 src/ui/widgets/FileChooserEntry.vala:49 +msgid "Select directory" +msgstr "Seleccioneu un directori" + +#: src/data/Runnable.vala:619 +#, c-format +msgid "Part %1$u of %2$u: %3$s" +msgstr "Part %1$u de %2$u: %3$s" + +#: src/data/Runnable.vala:642 src/ui/dialogs/CorruptedInstallerDialog.vala:48 +#, c-format +msgid "%s: corrupted installer" +msgstr "%s: l'instal·lador està malmès." + +#: src/data/Runnable.vala:643 +#, c-format +msgid "Checksum mismatch in %s" +msgstr "La suma de verificació no coincideix a %s." + +#: src/data/Runnable.vala:657 src/ui/dialogs/CorruptedInstallerDialog.vala:126 +msgid "Show file" +msgstr "Mostra el fitxer" + +#: src/data/Runnable.vala:658 src/ui/dialogs/CorruptedInstallerDialog.vala:132 +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#: src/ui/widgets/TagRow.vala:146 +msgid "Remove" +msgstr "Elimina" + +#: src/data/Runnable.vala:659 src/ui/dialogs/CorruptedInstallerDialog.vala:128 +msgid "Backup" +msgstr "Còpia de seguretat" + +#: src/data/Runnable.vala:778 +#, c-format +msgid "%s: cannot detect main executable" +msgstr "%s: no es pot detectar l'executable principal" + +#: src/data/Runnable.vala:779 +msgid "" +"Main executable file for this game cannot be detected automatically.\n" +"Please set main executable in game's properties." +msgstr "" +"No es pot detectar automàticament l'executable principal d'aquest joc.\n" +"Definiu l'executable principal a les propietats del joc." + +#: src/data/Runnable.vala:908 +msgctxt "platform" +msgid "Emulated" +msgstr "Emulat" + +#: src/data/Game.vala:625 +msgctxt "status" +msgid "Running" +msgstr "En execució" + +#: src/data/Game.vala:628 +msgctxt "status" +msgid "Installed" +msgstr "Instal·lat" + +#: src/data/Game.vala:629 +msgctxt "status" +msgid "Installing" +msgstr "S'està instal·lant" + +#: src/data/Game.vala:630 +msgctxt "status" +msgid "Verifying installer integrity" +msgstr "S'està comprovant la integritat de l'instal·lador" + +#: src/data/Game.vala:631 +msgctxt "status" +msgid "Download started" +msgstr "S'ha iniciat la baixada" + +#: src/data/Game.vala:633 +msgctxt "status" +msgid "Not installed" +msgstr "No instal·lat" + +#: src/data/Game.vala:643 +msgctxt "status_header" +msgid "Installed" +msgstr "Instal·lat" + +#: src/data/Game.vala:644 +msgctxt "status_header" +msgid "Installing" +msgstr "S'està instal·lant" + +#: src/data/Game.vala:646 +msgctxt "status_header" +msgid "Downloading" +msgstr "S'està baixant" + +#: src/data/Game.vala:648 +msgctxt "status_header" +msgid "Not installed" +msgstr "No instal·lat" + +#: src/data/GameSource.vala:31 +#, c-format +msgid "%s games" +msgstr "Jocs de %s" + +#: src/data/sources/steam/Steam.vala:43 +msgid "Your SteamID will be read from Steam configuration file" +msgstr "Es llegirà el vostre SteamID del fitxer de configuració de Steam." + +#: src/data/sources/steam/Steam.vala:46 +msgid "" +"Steam config file not found.\n" +"Login into your account in Steam client and return to GameHub" +msgstr "" +"No s'ha trobat el fitxer de configuració de Steam.\n" +"Inicieu la sessió al client de Steam i torneu al GameHub." + +#: src/data/sources/gog/GOGGame.vala:983 +#, c-format +msgid "DLC: %s" +msgstr "" + +#: src/data/sources/humble/HumbleGame.vala:343 +#, c-format +msgid "%s: no available installers" +msgstr "%s: no hi ha cap instal·lador disponible" + +#: src/data/sources/humble/HumbleGame.vala:344 +msgid "" +"Cannot get Trove download URL.\n" +"Make sure your Humble Monthly subscription is active." +msgstr "" +"No es pot obtenir l'URL de baixada de Trove.\n" +"Assegureu-vos que la vostra subscripció a Humble Monthly es troba activa." + +#: src/data/sources/itch/ItchDownloader.vala:192 +#, c-format +msgctxt "itch_dl_status" +msgid "%s left;" +msgstr "%s restant;" + +#: src/data/sources/itch/ItchDownloader.vala:195 +#, c-format +msgctxt "itch_dl_status" +msgid "%d%%" +msgstr "%d%%" + +#: src/data/sources/itch/ItchDownloader.vala:198 +#, c-format +msgctxt "itch_dl_status" +msgid "(%1$s / %2$s)" +msgstr "(%1$s / %2$s)" + +#: src/data/sources/itch/ItchDownloader.vala:201 +#, c-format +msgctxt "itch_dl_status" +msgid "[%s/s]" +msgstr "[%s/s]" + +#: src/data/sources/user/User.vala:30 +msgid "User games" +msgstr "Jocs de l'usuari" + +#: src/data/db/tables/Tags.vala:225 +msgctxt "tag" +msgid "Favorites" +msgstr "Preferits" + +#: src/data/db/tables/Tags.vala:226 +msgctxt "tag" +msgid "Not installed" +msgstr "No instal·lat" + +#: src/data/db/tables/Tags.vala:227 +msgctxt "tag" +msgid "Installed" +msgstr "Instal·lat" + +#: src/data/db/tables/Tags.vala:228 +msgctxt "tag" +msgid "Hidden" +msgstr "Ocult" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit script" +msgstr "Edita l'script" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit custom script" +msgstr "Edita l'script personalitzat" + +#: src/data/compat/Innoextract.vala:55 +#, c-format +msgid "" +"Innoextract %1$s is not supported and may not be able to extract some " +"games correctly.\n" +"Install innoextract %2$s or newer." +msgstr "" +"L'Innoextract %1$s no és compatible i pot ser que no pugui extreure " +"alguns jocs correctament.\n" +"Instal·leu l'Innoextract %2$s o posterior." + +#: src/data/compat/WineWrap.vala:61 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:242 +#: src/ui/dialogs/CompatRunDialog.vala:102 +#: src/ui/views/GamesView/GameContextMenu.vala:53 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:234 +msgid "Run" +msgstr "Executa" + +#: src/data/compat/WineWrap.vala:64 +msgid "Show WineWrap menu" +msgstr "Mostra el menú del WineWrap" + +#: src/data/compat/WineWrap.vala:67 src/data/compat/Proton.vala:122 +#: src/data/compat/Wine.vala:83 +msgid "Kill apps in prefix" +msgstr "Mata les aplicacions al prefix" + +#: src/data/compat/Proton.vala:47 +msgid "Proton prefix" +msgstr "Prefix del Proton" + +#: src/data/compat/Proton.vala:110 src/data/compat/Wine.vala:71 +msgid "Open prefix directory" +msgstr "Obre el directori del prefix" + +#: src/data/compat/Proton.vala:113 src/data/compat/Wine.vala:74 +msgid "Run winecfg" +msgstr "Executa el winecfg" + +#: src/data/compat/Proton.vala:116 src/data/compat/Wine.vala:77 +msgid "Run winetricks" +msgstr "Executa el winetricks" + +#: src/data/compat/Proton.vala:119 src/data/compat/Wine.vala:80 +msgid "Run taskmgr" +msgstr "Executa el taskmgr" + +#: src/data/compat/Wine.vala:53 +msgid "Wine prefix" +msgstr "Prefix del Wine" + +#: src/data/compat/Wine.vala:55 +msgid "Environment variables" +msgstr "Variables d'entorn" + +#: src/data/compat/Wine.vala:60 +msgid "InnoSetup default options" +msgstr "Opcions per defecte de l'InnoSetup" + +#: src/data/compat/RetroArch.vala:53 +msgid "Libretro core file" +msgstr "Fitxer de nucli del Libretro" + +#: src/data/compat/CustomEmulator.vala:43 +msgid "Custom emulator" +msgstr "Emulador personalitzat" + +#: src/data/compat/CustomEmulator.vala:48 +msgid "Emulator" +msgstr "Emulador" + +#: src/data/compat/CustomEmulator.vala:49 +msgid "Launch in game directory" +msgstr "Executa al directori del joc" + +#: src/data/adapters/GamesAdapter.vala:440 +msgctxt "status_header" +msgid "Favorites" +msgstr "Preferits" + +#: src/data/adapters/GamesAdapter.vala:445 +#, c-format +msgctxt "status_header" +msgid "%s: Favorites" +msgstr "%s: Preferits" + +#: src/data/adapters/GamesAdapter.vala:491 +msgid "Merging games" +msgstr "S'estan fusionant els jocs" + +#: src/data/adapters/GamesAdapter.vala:504 +#, c-format +msgid "Merging games from %s" +msgstr "S'estan fusionant els jocs de %s" + +#: src/data/adapters/GamesAdapter.vala:551 +#, c-format +msgid "Loading games from %s" +msgstr "S'estan carregant els jocs de %s" + +#: src/data/adapters/GamesAdapter.vala:678 +msgctxt "sort_mode" +msgid "By name" +msgstr "Per nom" + +#: src/data/adapters/GamesAdapter.vala:679 +msgctxt "sort_mode" +msgid "By last launch" +msgstr "Per darrera execució" + +#: src/data/adapters/GamesAdapter.vala:680 +msgctxt "sort_mode" +msgid "By playtime" +msgstr "Per temps de joc" + +#: src/data/adapters/GamesAdapter.vala:705 +msgctxt "group_mode" +msgid "Do not group" +msgstr "No agrupis" + +#: src/data/adapters/GamesAdapter.vala:706 +msgctxt "group_mode" +msgid "By status" +msgstr "Per estat" + +#: src/data/adapters/GamesAdapter.vala:707 +msgctxt "group_mode" +msgid "By source" +msgstr "Per origen" + +#: src/data/providers/images/SteamGridDB.vala:151 +#: src/data/providers/data/IGDB.vala:431 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:217 +msgid "Default" +msgstr "Per defecte" + +#: src/data/providers/images/SteamGridDB.vala:158 +#: src/data/providers/data/IGDB.vala:438 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:225 +msgid "Restore default API key" +msgstr "Restaura la clau API per defecte" + +#: src/data/providers/images/SteamGridDB.vala:169 +#: src/data/providers/data/IGDB.vala:449 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:108 +msgid "API key" +msgstr "Clau API" + +#: src/data/providers/images/SteamGridDB.vala:177 +#: src/data/providers/data/IGDB.vala:457 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:53 +msgid "Generate key" +msgstr "Genera una clau" + +#: src/data/providers/images/SteamGridDB.vala:208 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Style" +msgstr "Estil" + +#: src/data/providers/images/SteamGridDB.vala:209 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Score" +msgstr "Puntuació" + +#: src/data/providers/images/SteamGridDB.vala:213 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Author" +msgstr "Autor/a" + +#: src/data/providers/images/SteamGridDB.vala:225 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Alternate" +msgstr "Alternatiu" + +#: src/data/providers/images/SteamGridDB.vala:226 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Blurred" +msgstr "Difuminat" + +#. TRANSLATORS: Flat / Material Design image style. Probably should not be translated +#: src/data/providers/images/SteamGridDB.vala:228 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Material" +msgstr "Material" + +#: src/data/providers/images/SteamGridDB.vala:229 +msgctxt "imagesource_steamgriddb_image_style" +msgid "No logo" +msgstr "Sense logotip" + +#: src/data/providers/images/SteamGridDB.vala:230 +msgctxt "imagesource_steamgriddb_image_style" +msgid "White logo" +msgstr "Logotip blanc" + +#: src/data/providers/data/IGDB.vala:147 +msgid "" +"Monthly IGDB request quota has been reached. Set your own API key to use " +"IGDB data or disable IGDB." +msgstr "" +"S'ha assolit el límit de sol·licituds a IGDB mensual. Definiu la vostra " +"pròpia clau API per utilitzar dades d'IGDB o inhabiliteu IGDB." + +#: src/data/providers/data/IGDB.vala:148 +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:40 +#: src/ui/views/WelcomeView.vala:53 src/ui/views/WelcomeView.vala:78 +#: src/ui/views/GamesView/GamesView.vala:230 +#: src/ui/views/GamesView/GamesView.vala:629 +msgid "Settings" +msgstr "Paràmetres" + +#: src/data/providers/data/IGDB.vala:356 +msgctxt "igdb_related_link" +msgid "Official website" +msgstr "Lloc web oficial" + +#: src/data/providers/data/IGDB.vala:469 +msgctxt "igdb_preferred_description" +msgid "When game has description, show description" +msgstr "Quan un joc tingui una descripció, mostra la descripció" + +#: src/data/providers/data/IGDB.vala:476 +msgctxt "igdb_preferred_description" +msgid "of game" +msgstr "del joc" + +#: src/data/providers/data/IGDB.vala:477 +msgctxt "igdb_preferred_description" +msgid "from IGDB" +msgstr "d'IGDB" + +#: src/data/providers/data/IGDB.vala:478 +msgctxt "igdb_preferred_description" +msgid "both" +msgstr "de tots dos" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:65 +msgid "Some settings will be applied after application restart" +msgstr "Alguns paràmetres s'aplicaran després de reiniciar l'aplicació" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:71 +msgid "Games directory contains space. It may cause problems for some games" +msgstr "" +"El directori de jocs conté espais. Pot causar problemes amb alguns jocs" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:36 +msgid "Interface" +msgstr "Interfície" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:37 +msgid "Appearance" +msgstr "Aparença" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:38 +msgid "General interface settings" +msgstr "Paràmetres generals de la interfície" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:48 +msgid "Dark theme" +msgstr "Tema fosc" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:53 +msgctxt "icon_style" +msgid "Theme-based" +msgstr "Basat en el tema" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:54 +msgctxt "icon_style" +msgid "Symbolic" +msgstr "Simbòlic" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:55 +msgctxt "icon_style" +msgid "Colored" +msgstr "Acolorit" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:57 +msgctxt "icon_style" +msgid "Icon style" +msgstr "Estil de les icones" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:84 +msgid "Game card" +msgstr "Targeta del joc" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:86 +msgid "Show platform icons" +msgstr "Mostra les icones de la plataforma" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:99 +msgctxt "grid_size" +msgid "Card size" +msgstr "Mida de la targeta" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:117 +msgctxt "grid_size_preset" +msgid "Presets" +msgstr "Valors predefinits" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:139 +msgid "Games list: installed" +msgstr "Llista de jocs: instal·lats" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:140 +msgid "Games list: not installed" +msgstr "Llista de jocs: no instal·lats" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:142 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:146 +msgctxt "list_style" +msgid "Show icon" +msgstr "Mostra la icona" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:143 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:147 +msgctxt "list_style" +msgid "Bold title" +msgstr "Títol en negreta" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:144 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:148 +msgctxt "list_style" +msgid "Show status" +msgstr "Mostra l'estat" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:149 +msgctxt "list_style" +msgid "Dim" +msgstr "Enfosqueix" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:151 +msgid "Grid options" +msgstr "Opcions de la quadrícula" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:152 +msgid "List options" +msgstr "Opcions de la llista" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:31 +msgid "Behavior" +msgstr "Comportament" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:32 +msgid "Behavior settings" +msgstr "Paràmetres del comportament" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:42 +msgid "Run games with double click" +msgstr "Executa els jocs fent-hi doble clic" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:46 +msgid "Merge games from different sources" +msgstr "Uneix els jocs d'orígens diferents" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:50 +msgid "Use imported tags" +msgstr "Utilitza les etiquetes importades" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:51 +msgid "General" +msgstr "General" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:52 +msgid "Collection" +msgstr "Col·lecció" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:53 +msgid "Empty" +msgstr "Buida" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:65 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:85 +msgid "Collection directory" +msgstr "Directori de la col·lecció" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:70 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:78 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:87 +msgid "Game directory" +msgstr "Directori dels jocs" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:71 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:79 +msgid "Installers" +msgstr "Instal·ladors" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:72 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:98 +msgid "DLC" +msgstr "Contingut addicional" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:73 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:197 +msgid "Bonus content" +msgstr "Contingut de bonificació" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:84 +msgid "Variable syntax: $var or ${var}" +msgstr "Sintaxi de les variables: $var o ${var}" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:86 +msgid "Game name" +msgstr "Nom del joc" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:88 +#: src/ui/views/GamesView/FiltersPopover.vala:127 +msgid "Platform" +msgstr "Plataforma" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:36 +msgid "Controller" +msgstr "Comandament" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +msgid "Enabled" +msgstr "Habilitat" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:53 +msgid "Focus GameHub window with Guide button" +msgstr "Focalitza la finestra del GameHub amb el botó Guia" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:57 +msgid "Controllers" +msgstr "Comandaments" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:89 +msgid "Move focus" +msgstr "Canvia el focus" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:91 +msgid "Exit" +msgstr "Surt" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:40 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:108 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:92 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:95 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:36 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:77 +msgid "Disabled" +msgstr "Inhabilitat" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:47 +#: src/ui/dialogs/GameTweaksDialog.vala:53 +#: src/ui/views/GamesView/GameContextMenu.vala:183 +msgid "Tweaks" +msgstr "Ajustaments" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:34 +#, fuzzy +msgid "Tweak launch options and apply them to games automatically" +msgstr "Ajusteu les opcions d'execució i apliqueu-les als jocs automàticament" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:79 +msgid "" +"Tweaks are loaded from following directories in order\n" +"Last tweak overrides previous tweaks with same identifiers" +msgstr "" +"Els ajustaments es carreguen dels directoris següents en ordre.\n" +"L'últim ajustament anul·la els ajustaments anteriors amb els mateixos " +"identificadors." + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:83 +msgid "Click to open" +msgstr "Feu clic per obrir" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:93 +#, c-format +msgid "Tweaks are loaded from %1$s and %2$d more directories (?)" +msgstr "" +"Els ajustaments es carreguen des de %1$s i %2$d directoris més " +"(?)" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:38 +msgid "Game sources" +msgstr "Orígens de jocs" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +msgid "Steam API keys have limited number of uses per day" +msgstr "Les claus API de Steam tenen un nombre limitat d'usos per dia" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:63 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:57 +msgid "Installation directory" +msgstr "Directori d'instal·lació" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:176 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:81 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:34 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:75 +msgid "Not installed" +msgstr "No instal·lat" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:116 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:96 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:99 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:85 +msgid "Not authenticated" +msgstr "No autenticat" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +#, c-format +msgid "Authenticated as %s" +msgstr "Autenticat com a %s" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:103 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +msgid "Authenticated" +msgstr "Autenticat" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:183 +#: src/ui/dialogs/InstallDialog.vala:53 src/ui/dialogs/InstallDialog.vala:111 +#: src/ui/views/GamesView/GameContextMenu.vala:80 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:233 +#: src/ui/widgets/TweaksList.vala:95 +msgid "Install" +msgstr "Instal·la" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:236 +msgid "Steam API key" +msgstr "Clau API de Steam" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:50 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:54 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:48 +msgid "Games directory" +msgstr "Directori dels jocs" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:63 +msgid "Logout" +msgstr "Surt" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:50 +msgid "Load games from Humble Trove" +msgstr "Carrega els jocs de Humble Trove" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:45 +msgid "Emulators" +msgstr "Emuladors" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:45 +msgid "Libretro core directory" +msgstr "Directori de nuclis del Libretro" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:46 +msgid "Libretro core info directory" +msgstr "Directori d'informació dels nuclis del Libretro" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:50 +msgid "Ignored libretro cores" +msgstr "Nuclis del Libretro ignorats" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:54 +msgid "Ignored game file extensions" +msgstr "Extensions de fitxer de jocs ignorades" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:66 +msgid "No cores found" +msgstr "No s'han trobat nuclis" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:70 +#, c-format +msgid "%u core found" +msgid_plural "%u cores found" +msgstr[0] "S'ha trobat %u nucli" +msgstr[1] "S'han trobat %u nuclis" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:46 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:168 +msgid "No custom emulators" +msgstr "No hi ha emuladors personalitzats" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:164 +#, c-format +msgid "%u custom emulator" +msgid_plural "%u custom emulators" +msgstr[0] "%u emulador personalitzat" +msgstr[1] "%u emuladors personalitzats" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:237 +msgid "Save" +msgstr "Desa" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:250 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:312 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/dialogs/GamePropertiesDialog.vala:168 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +#: src/ui/views/GamesView/AddGamePopover.vala:67 +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Executable" +msgstr "Executable" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:251 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/views/GamesView/AddGamePopover.vala:68 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Installer" +msgstr "Instal·lador" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:256 +#: src/ui/dialogs/GamePropertiesDialog.vala:64 +#: src/ui/dialogs/GamePropertiesDialog.vala:69 +#: src/ui/views/GamesView/AddGamePopover.vala:73 +msgid "Name" +msgstr "Nom" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:272 +#: src/ui/dialogs/GamePropertiesDialog.vala:201 +#: src/ui/views/GamesView/AddGamePopover.vala:78 +msgid "Arguments" +msgstr "Arguments" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:276 +msgid "Variables" +msgstr "Variables" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:277 +msgid "Game executable" +msgstr "Executable del joc" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:278 +msgid "Game arguments" +msgstr "Arguments del joc" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:80 +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Directory" +msgstr "Directori" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +msgid "Select emulator directory" +msgstr "Selecciona el directori de l'emulador" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:292 +#: src/ui/dialogs/GamePropertiesDialog.vala:219 +msgid "Force compatibility mode" +msgstr "Força el mode de compatibilitat" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:307 +msgid "Game file patterns" +msgstr "Patrons dels fitxers del joc" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:315 +msgid "Image" +msgstr "Imatge" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:318 +msgid "Icon" +msgstr "Icona" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:325 +msgid "" +"findutils-compatible glob patterns\n" +"\n" +" Multiple patterns can be separated with |\n" +" Start pattern with ./ to match relative path\n" +" $basename variable will be replaced with game's executable " +"name (without extension)" +msgstr "" +"Patrons del glob compatibles amb el findutils\n" +"\n" +" Es poden separar diversos patrons amb |.\n" +" Inicieu el patró amb ./ per fer-lo coincidir amb un camí " +"relatiu.\n" +" La variable $basename es reemplaçarà pel nom de l'executable " +"del joc (sense extensió)." + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:38 +msgid "Data" +msgstr "Dades" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:39 +msgid "Providers" +msgstr "Proveïdors" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:40 +msgid "Third-party data providers" +msgstr "Proveïdors de dades de tercers" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:55 +msgid "Image providers" +msgstr "Proveïdors d'imatges" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:68 +msgid "Metadata providers" +msgstr "Proveïdors de metadades" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:137 +msgid "Open website" +msgstr "Obre el lloc web" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:36 +msgid "About" +msgstr "Quant a" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:71 +msgid "Copy application version and environment info" +msgstr "Copia la versió de l'aplicació i la informació de l'entorn" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:78 +#: src/ui/views/WelcomeView.vala:57 +msgid "All your games in one place" +msgstr "Tots els teus jocs en un lloc" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:92 +msgctxt "about_link" +msgid "Website" +msgstr "Lloc web" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:96 +msgctxt "about_link" +msgid "Source code on GitHub" +msgstr "Codi font a GitHub" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:103 +msgctxt "about_link" +msgid "Report a problem" +msgstr "Informa d'un problema" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:104 +msgctxt "about_link" +msgid "Suggest translations" +msgstr "Suggereix traduccions" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:110 +msgctxt "about_link" +msgid "Issues" +msgstr "Incidències" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:111 +msgctxt "about_link" +msgid "Contributors" +msgstr "Col·laboradors" + +#. TRANSLATORS: Likely it should not be translated. GitHub Pulse is a page that shows recent repository activity: https://github.com/tkashkin/GameHub/pulse +#: src/ui/dialogs/SettingsDialog/pages/About.vala:114 +msgctxt "about_link" +msgid "Pulse" +msgstr "Activitat" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:115 +msgctxt "about_link" +msgid "Forks" +msgstr "Bifurcacions" + +#: src/ui/dialogs/InstallDialog.vala:109 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:129 +msgid "Import" +msgstr "Importa" + +#: src/ui/dialogs/InstallDialog.vala:110 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:153 +msgid "Download" +msgstr "Baixa" + +#: src/ui/dialogs/InstallDialog.vala:207 +msgid "Select installer" +msgstr "Seleccioneu un instal·lador" + +#: src/ui/dialogs/InstallDialog.vala:216 +#, c-format +msgid "Installer size: %s" +msgstr "Mida de l'instal·lador: %s" + +#: src/ui/dialogs/InstallDialog.vala:348 +msgid "Unknown" +msgstr "Desconegut" + +#: src/ui/dialogs/GamePropertiesDialog.vala:49 +#, c-format +msgid "%s: Properties" +msgstr "%s: Propietats" + +#: src/ui/dialogs/GamePropertiesDialog.vala:84 +msgid "Images" +msgstr "Imatges" + +#: src/ui/dialogs/GamePropertiesDialog.vala:126 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:160 +#: src/ui/views/GameDetailsView/blocks/Artwork.vala:62 +msgid "Download images" +msgstr "Baixa imatges" + +#: src/ui/dialogs/GamePropertiesDialog.vala:144 +msgid "Image URL" +msgstr "URL de la imatge" + +#: src/ui/dialogs/GamePropertiesDialog.vala:148 +msgid "Vertical image URL" +msgstr "URL de la imatge vertical" + +#: src/ui/dialogs/GamePropertiesDialog.vala:157 +msgid "Icon URL" +msgstr "URL de la icona" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +#, fuzzy +msgid "Select working directory" +msgstr "Seleccioneu un directori" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +#, fuzzy +msgid "Working directory" +msgstr "Obre un directori" + +#: src/ui/dialogs/GamePropertiesDialog.vala:214 +msgid "Compatibility" +msgstr "Compatibilitat" + +#: src/ui/dialogs/GamePropertiesDialog.vala:236 +msgid "Launch from terminal" +msgstr "Executa des del terminal" + +#: src/ui/dialogs/GamePropertiesDialog.vala:252 +msgid "Copy to clipboard" +msgstr "Copia al porta-retalls" + +#: src/ui/dialogs/GamePropertiesDialog.vala:254 +msgid "Add to Steam" +msgstr "Afegeix a Steam" + +#: src/ui/dialogs/GamePropertiesDialog.vala:255 +msgid "Add to the Steam library" +msgstr "Afegeix a la biblioteca de Steam" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:53 +#, c-format +msgid "%s: Overlays" +msgstr "%s: Capes" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "Overlays are disabled" +msgstr "Les capes estan inhabilitades" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "" +"Enable overlays to manage DLCs and mods\n" +"\n" +"Enabling will move game to the “base“ overlay" +msgstr "" +"Habiliteu les capes per gestionar continguts addicionals i modificacions.\n" +"\n" +"Si les habiliteu, el joc es mourà a la capa «base»." + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:77 +#: src/ui/views/GamesView/GameContextMenu.vala:175 +msgid "Overlays" +msgstr "Capes" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:105 +msgid "Overlay ID (directory name)" +msgstr "ID de la capa (nom del directori)" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:110 +msgid "Overlay name (optional)" +msgstr "Nom de la capa (opcional)" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:112 +msgid "Add" +msgstr "Afegeix" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:127 +msgid "Enable overlays" +msgstr "Habilita les capes" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:182 +#, c-format +msgid "" +"Overlay usage at this path may be unsafe\n" +"Proceed at your own risk\n" +"\n" +"Path: %s" +msgstr "" +"L'ús de capes en aquest camí pot ser poc segur.\n" +"Continueu sota la vostra responsabilitat.\n" +"\n" +"Camí: %s" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:187 +#, c-format +msgid "" +"Overlay usage at this path is not supported\n" +"\n" +"Path: %s" +msgstr "" +"No s'admet l'ús de capes en aquest camí.\n" +"\n" +"Camí: %s" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:266 +msgid "Open directory" +msgstr "Obre un directori" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:271 +msgid "Remove overlay" +msgstr "Suprimeix la capa" + +#: src/ui/dialogs/CompatRunDialog.vala:48 +#: src/ui/views/GamesView/GameContextMenu.vala:46 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:235 +msgid "Run with compatibility layer" +msgstr "Executa amb la capa de compatibilitat" + +#: src/ui/dialogs/CorruptedInstallerDialog.vala:71 +msgid "Corrupted installer: checksum mismatch in" +msgstr "L'instal·lador està malmès: la suma de verificació no coincideix a" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:57 +#: src/ui/views/GamesView/AddGamePopover.vala:105 +msgid "Import emulated games" +msgstr "Importa jocs emulats" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:75 +msgid "Select directory with emulated games" +msgstr "Seleccioneu un directori amb jocs emulats" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:83 +msgid "Detected games" +msgstr "Jocs detectats" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:107 +msgid "Select all" +msgstr "Selecciona-ho tot" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:115 +msgid "Select directory to import" +msgstr "Seleccioneu un directori per a importar-lo" + +#: src/ui/dialogs/GameTweaksDialog.vala:40 +#, c-format +msgid "%s: Tweaks" +msgstr "%s: Ajustaments" + +#: src/ui/views/WelcomeView.vala:52 +msgid "No enabled game sources" +msgstr "No hi ha cap origen de jocs habilitat" + +#: src/ui/views/WelcomeView.vala:52 +msgid "Enable some game sources in settings" +msgstr "Habiliteu alguns orígens de jocs als paràmetres" + +#: src/ui/views/WelcomeView.vala:57 +msgid "Let's get started" +msgstr "Comencem" + +#: src/ui/views/WelcomeView.vala:71 +msgid "Skip" +msgstr "Omet" + +#: src/ui/views/WelcomeView.vala:141 +msgid "Ready" +msgstr "Tot a punt" + +#: src/ui/views/WelcomeView.vala:147 +msgid "Authentication required" +msgstr "Cal autenticar-se" + +#: src/ui/views/WelcomeView.vala:152 +msgid "Authenticating…" +msgstr "S'està autenticant…" + +#: src/ui/views/WelcomeView.vala:163 +#, c-format +msgid "Install %s" +msgstr "Instal·la %s" + +#: src/ui/views/WelcomeView.vala:164 +msgid "Return to GameHub after installing" +msgstr "Torna al GameHub després de la instal·lació" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "No games" +msgstr "No hi ha jocs" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "Get some games or enable some game sources in settings" +msgstr "Obteniu alguns jocs o habiliteu alguns orígens de jocs als paràmetres" + +#: src/ui/views/GamesView/GamesView.vala:150 +msgid "Grid view" +msgstr "Visualització de quadrícula" + +#: src/ui/views/GamesView/GamesView.vala:151 +msgid "List view" +msgstr "Visualització de llista" + +#: src/ui/views/GamesView/GamesView.vala:159 +msgid "All games" +msgstr "Tots els jocs" + +#: src/ui/views/GamesView/GamesView.vala:182 +msgid "Downloads" +msgstr "Baixades" + +#: src/ui/views/GamesView/GamesView.vala:208 +msgid "Filters" +msgstr "Filtres" + +#: src/ui/views/GamesView/GamesView.vala:216 +#: src/ui/views/GamesView/AddGamePopover.vala:84 +msgid "Add game" +msgstr "Afegeix un joc" + +#: src/ui/views/GamesView/GamesView.vala:223 +msgid "Search" +msgstr "Cerca" + +#: src/ui/views/GamesView/GamesView.vala:328 +msgid "Menu" +msgstr "Menú" + +#: src/ui/views/GamesView/GamesView.vala:329 +#: src/ui/views/GameDetailsView/GameDetailsView.vala:104 +msgid "Back" +msgstr "Enrere" + +#: src/ui/views/GamesView/GamesView.vala:550 +#, c-format +msgid "%u game" +msgid_plural "%u games" +msgstr[0] "%u joc" +msgstr[1] "%u jocs" + +#: src/ui/views/GamesView/GamesView.vala:553 +#, fuzzy, c-format +msgctxt "games_view_subtitle_filtered_games" +msgid "%1$u / %2$s" +msgstr "(%1$s / %2$s)" + +#: src/ui/views/GamesView/GamesView.vala:557 +#, fuzzy, c-format +msgctxt "games_view_subtitle" +msgid "%1$s: %2$s" +msgstr "(%1$s / %2$s)" + +#: src/ui/views/GamesView/GamesView.vala:568 +msgid "No user-added games" +msgstr "No hi ha cap joc afegit per l'usuari" + +#: src/ui/views/GamesView/GamesView.vala:569 +msgid "Add some games using plus button" +msgstr "Afegiu alguns jocs mitjançant el botó «+»" + +#: src/ui/views/GamesView/GamesView.vala:573 +#, c-format +msgid "No %s games" +msgstr "No hi ha jocs de %s" + +#: src/ui/views/GamesView/GamesView.vala:574 +msgid "Get some Linux-compatible games" +msgstr "Obteniu alguns jocs compatibles amb el Linux" + +#: src/ui/views/GamesView/GamesView.vala:584 +#, c-format +msgid "No games matching “%s”" +msgstr "No hi ha jocs que coincideixin amb «%s»" + +#: src/ui/views/GamesView/GamesView.vala:589 +#, c-format +msgid "No %1$s games matching “%2$s”" +msgstr "No hi ha jocs de %1$s que coincideixin amb «%2$s»" + +#: src/ui/views/GamesView/GamesView.vala:627 +msgid "" +"No games were loaded from Steam. Set your games list privacy to public or " +"use your own Steam API key in settings." +msgstr "" +"No s'ha carregat cap joc des de Steam. Definiu la privadesa de la vostra " +"llista de jocs com a pública o utilitzeu la vostra pròpia clau API de Steam " +"als paràmetres." + +#: src/ui/views/GamesView/GamesView.vala:628 +msgid "Privacy" +msgstr "Privadesa" + +#: src/ui/views/GamesView/GamesView.vala:739 +msgid "Downloading images" +msgstr "S'estan baixant les imatges" + +#: src/ui/views/GamesView/GamesView.vala:753 +#, c-format +msgid "Downloading image: %s" +msgstr "S'està baixant la imatge: %s" + +#: src/ui/views/GamesView/DownloadProgressView.vala:131 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:162 +msgid "Pause download" +msgstr "Pausa la baixada" + +#: src/ui/views/GamesView/DownloadProgressView.vala:137 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:168 +msgid "Resume download" +msgstr "Reprèn la baixada" + +#: src/ui/views/GamesView/DownloadProgressView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:174 +msgid "Cancel download" +msgstr "Cancel·la la baixada" + +#: src/ui/views/GamesView/FiltersPopover.vala:77 +msgid "Group" +msgstr "Agrupa" + +#: src/ui/views/GamesView/FiltersPopover.vala:102 +msgid "Sort" +msgstr "Ordena" + +#: src/ui/views/GamesView/FiltersPopover.vala:234 +#: src/ui/widgets/GameTagsList.vala:58 +msgid "Tags" +msgstr "Etiquetes" + +#: src/ui/views/GamesView/FiltersPopover.vala:353 +msgid "All platforms" +msgstr "Totes les plataformes" + +#: src/ui/views/GamesView/AddGamePopover.vala:77 +msgid "Select game executable" +msgstr "Seleccioneu l'executable del joc" + +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Select game directory" +msgstr "Seleccioneu el directori del joc" + +#: src/ui/views/GamesView/AddGamePopover.vala:111 +msgid "Download game images" +msgstr "Baixa imatges del joc" + +#: src/ui/views/GamesView/GameContextMenu.vala:87 +msgid "Details" +msgstr "Detalls" + +#: src/ui/views/GamesView/GameContextMenu.vala:117 +msgctxt "game_context_menu" +msgid "Favorite" +msgstr "Preferit" + +#: src/ui/views/GamesView/GameContextMenu.vala:121 +msgctxt "game_context_menu" +msgid "Hidden" +msgstr "Ocult" + +#: src/ui/views/GamesView/GameContextMenu.vala:133 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:236 +msgid "Open installation directory" +msgstr "Obre el directori d'instal·lació" + +#: src/ui/views/GamesView/GameContextMenu.vala:142 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:237 +msgid "Open installers collection directory" +msgstr "Obre el directori de col·leccions d'instal·ladors" + +#: src/ui/views/GamesView/GameContextMenu.vala:151 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:238 +msgid "Open bonus collection directory" +msgstr "Obre el directori de col·leccions de bonificació" + +#: src/ui/views/GamesView/GameContextMenu.vala:160 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:239 +msgid "Open screenshots directory" +msgstr "Obre el directori de captures de pantalla" + +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +msgid "Uninstall" +msgstr "Desinstal·la" + +#: src/ui/views/GamesView/GameContextMenu.vala:192 +msgid "Properties" +msgstr "Propietats" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:100 +#, c-format +msgid "%d game selected" +msgid_plural "%d games selected" +msgstr[0] "%d joc seleccionat" +msgstr[1] "%d jocs seleccionats" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:144 +#, c-format +msgid "%d game will be installed" +msgid_plural "%d games will be installed" +msgstr[0] "S'instal·larà %d joc" +msgstr[1] "S'instal·laran %d jocs" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:154 +#, c-format +msgid "%d game will be downloaded" +msgid_plural "%d games will be downloaded" +msgstr[0] "Es baixarà %d joc" +msgstr[1] "Es baixaran %d jocs" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:161 +#, c-format +msgid "Image for %d game will be searched" +msgid_plural "Images for %d games will be searched" +msgstr[0] "Se cercaran imatges per a %d joc" +msgstr[1] "Se cercaran imatges per a %d jocs" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:168 +#, c-format +msgid "%d game will be uninstalled" +msgid_plural "%d games will be uninstalled" +msgstr[0] "Es desinstal·larà %d joc" +msgstr[1] "Es desinstal·laran %d jocs" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:174 +msgid "Refresh" +msgstr "Actualitza" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:175 +#, c-format +msgid "" +"%d game will be removed from database. Restart GameHub to fetch new data" +msgid_plural "" +"%d games will be removed from database. Restart GameHub to fetch new data" +msgstr[0] "" +"Se suprimirà %d joc de la base de dades. Reinicieu el GameHub per obtenir " +"dades noves." +msgstr[1] "" +"Se suprimiran %d jocs de la base de dades. Reinicieu el GameHub per obtenir " +"dades noves." + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:240 +msgid "Open store page" +msgstr "Obre la pàgina de la botiga" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:242 +msgid "Game properties" +msgstr "Propietats del joc" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:46 +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:60 +msgid "Playtime" +msgstr "Temps de joc" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:52 +msgid "Playtime (local)" +msgstr "Temps de joc (local)" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:69 +msgid "Last launch" +msgstr "Darrera execució" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:46 +msgid "Achievements" +msgstr "Assoliments" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:85 +#, c-format +msgid "Unlocked: %s" +msgstr "Heu aconseguit: %s" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:90 +#, c-format +msgid "Global percentage: %g%%" +msgstr "Percentatge global: %g%%" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:77 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:103 +msgid "Language" +msgstr "Llengua" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:80 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:106 +msgid "Languages" +msgstr "Llengües" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:147 +#, fuzzy, c-format +msgid "%u DLCs cannot be installed" +msgstr "%s: l'instal·lador està malmès." + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:71 +msgid "Category" +msgstr "Categoria" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:74 +msgid "Categories" +msgstr "Categories" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:90 +msgid "Genre" +msgstr "Gènere" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:93 +msgid "Genres" +msgstr "Gèneres" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:109 +msgctxt "igdb" +msgid "Popularity" +msgstr "Popularitat" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:115 +msgctxt "igdb" +msgid "Aggregated rating" +msgstr "Puntuació global" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:116 +msgctxt "igdb" +msgid "IGDB user rating" +msgstr "Valoració dels usuaris d'IGDB" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:117 +msgctxt "igdb" +msgid "Total rating" +msgstr "Puntuació total" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:126 +msgctxt "igdb" +msgid "Release date" +msgstr "Data de llançament" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:133 +msgctxt "igdb" +msgid "Platforms" +msgstr "Plataformes" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:139 +msgctxt "igdb" +msgid "Genres" +msgstr "Gèneres" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:145 +msgctxt "igdb" +msgid "Keywords" +msgstr "Paraules clau" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:152 +msgctxt "igdb" +msgid "Links" +msgstr "Enllaços" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:208 +#, c-format +msgid "Based on %d rating" +msgid_plural "Based on %d ratings" +msgstr[0] "Segons %d valoració" +msgstr[1] "Segons %d valoracions" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:290 +msgctxt "igdb" +msgid "Summary" +msgstr "Resum" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:301 +msgctxt "igdb" +msgid "Storyline" +msgstr "Trama" + +#: src/ui/widgets/FileChooserEntry.vala:49 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select file" +msgstr "Seleccioneu un fitxer" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "No images" +msgstr "No hi ha imatges" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "" +"There are no images found for this game\n" +"Make sure game name is correct" +msgstr "" +"No s'han trobat imatges per a aquest joc.\n" +"Assegureu-vos que el nom del joc és correcte." + +#: src/ui/widgets/ImagesDownloadPopover.vala:94 +msgid "Search images:" +msgstr "Cerca d'imatges:" + +#: src/ui/widgets/CompatToolPicker.vala:53 +msgid "Compatibility layer:" +msgstr "Capa de compatibilitat:" + +#: src/ui/widgets/CompatToolPicker.vala:92 +msgid "Configure" +msgstr "Configura" + +#: src/ui/widgets/GameTagsList.vala:109 +msgid "Add tag" +msgstr "Afegeix una etiqueta" + +#: src/ui/widgets/TweaksList.vala:86 +msgid "No description" +msgstr "" + +#: src/ui/widgets/TweaksList.vala:124 +#, fuzzy +msgid "Edit file" +msgstr "Edita el fitxer" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dh" +msgstr "%d h" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dm" +msgstr "%d min" + +#: src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%ds" +msgstr "%ds" + +#: src/settings/UI.vala:153 +msgctxt "grid_size_preset" +msgid "Steam" +msgstr "Steam" + +#: src/settings/UI.vala:154 +msgctxt "grid_size_preset" +msgid "Steam (vertical)" +msgstr "Steam (vertical)" + +#: src/settings/UI.vala:155 +msgctxt "grid_size_preset" +msgid "GOG" +msgstr "GOG" + +#: src/settings/UI.vala:156 +msgctxt "grid_size_preset" +msgid "GOG (vertical)" +msgstr "GOG (vertical)" + +#: src/settings/UI.vala:157 +msgctxt "grid_size_preset" +msgid "Square" +msgstr "Quadrada" + +#: src/settings/UI.vala:158 +msgctxt "grid_size_preset" +msgid "Custom" +msgstr "Personalitzada" + +#: src/utils/downloader/Downloader.vala:200 +msgctxt "dl_status" +msgid "Queued" +msgstr "A la cua" + +#: src/utils/downloader/Downloader.vala:201 +msgctxt "dl_status" +msgid "Starting download" +msgstr "S'està iniciant la baixada" + +#: src/utils/downloader/Downloader.vala:202 +msgctxt "dl_status" +msgid "Download started" +msgstr "S'ha iniciat la baixada" + +#: src/utils/downloader/Downloader.vala:203 +msgctxt "dl_status" +msgid "Download finished" +msgstr "S'ha finalitzat la baixada" + +#: src/utils/downloader/Downloader.vala:204 +msgctxt "dl_status" +msgid "Download failed" +msgstr "Ha fallat la baixada" + +#: src/utils/downloader/Downloader.vala:208 +#, c-format +msgctxt "dl_status" +msgid "Downloading: %s" +msgstr "S'està baixant: %s" + +#: src/utils/downloader/Downloader.vala:210 +msgctxt "dl_status" +msgid "Downloading" +msgstr "S'està baixant" + +#: src/utils/downloader/Downloader.vala:214 +#, c-format +msgctxt "dl_status" +msgid "Paused: %s" +msgstr "En pausa: %s" + +#: src/utils/downloader/Downloader.vala:216 +msgctxt "dl_status" +msgid "Paused" +msgstr "En pausa" + +#: src/utils/downloader/Downloader.vala:218 +msgctxt "dl_status" +msgid "Download cancelled" +msgstr "S'ha cancel·lat la baixada" + +#. TRANSLATORS: Download progress template. %1$d - percentage, %2$s / %3$s - downloaded portion and total file size, %4$s - download speed +#: src/utils/downloader/Downloader.vala:262 +#, c-format +msgctxt "dl_status" +msgid "%1$d%% (%2$s / %3$s) [%4$s/s]" +msgstr "%1$d%% (%2$s / %3$s) [%4$s/s]" + +#~ msgid "Disable esync" +#~ msgstr "Inhabilita l'esync" + +#~ msgid "Force LARGE_ADDRESS_AWARE flag" +#~ msgstr "Força el senyalador LARGE_ADDRESS_AWARE" + +#~ msgid "Disable DirectX 11 compatibility layer" +#~ msgstr "Inhabilita la capa de compatibilitat amb el DirectX 11" + +#~ msgid "Use WineD3D11 as DirectX 11 compatibility layer" +#~ msgstr "" +#~ "Utilitza el WineD3D11 com a capa de compatibilitat amb el DirectX 11" + +#~ msgid "Show DXVK info overlay" +#~ msgstr "Superposa la informació del DXVK" + +#~ msgid "Enable DirectX 9 compatibility layer" +#~ msgstr "Habilita la capa de compatibilitat amb el DirectX 9" + +#~ msgid "Silent installation" +#~ msgstr "Instal·lació silenciosa" + +#~ msgid "Very silent installation" +#~ msgstr "Instal·lació molt silenciosa" + +#~ msgid "Suppress messages" +#~ msgstr "Suprimeix els missatges" + +#~ msgid "No GUI" +#~ msgstr "Sense GUI" diff --git a/po/com.github.tkashkin.gamehub.pot b/po/com.github.tkashkin.gamehub.pot index a6723c34..2ccd47c6 100644 --- a/po/com.github.tkashkin.gamehub.pot +++ b/po/com.github.tkashkin.gamehub.pot @@ -8,65 +8,1792 @@ msgid "" msgstr "" "Project-Id-Version: com.github.tkashkin.gamehub\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-05-27 03:39+0300\n" +"POT-Creation-Date: 2020-01-26 06:40+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" +"Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" -#: data/com.github.tkashkin.gamehub.appdata.xml.in:8 -#: data/com.github.tkashkin.gamehub.desktop.in:3 -#: data/com.github.tkashkin.gamehub.desktop.in:4 -msgid "GameHub" +#: src/app.vala:91 +msgid "Show help" msgstr "" -#: data/com.github.tkashkin.gamehub.appdata.xml.in:9 -#: data/com.github.tkashkin.gamehub.desktop.in:5 -#: src/ui/views/WelcomeView.vala:16 +#: src/app.vala:92 +msgid "Show application version and exit" +msgstr "" + +#: src/app.vala:93 +msgid "Restart with GDB debugger attached" +msgstr "" + +#: src/app.vala:94 +msgid "Show full GDB backtrace" +msgstr "" + +#: src/app.vala:95 +msgid "Treat fatal errors as criticals and crash application" +msgstr "" + +#: src/app.vala:99 +msgid "Show main window" +msgstr "" + +#: src/app.vala:100 +msgid "Show application settings dialog" +msgstr "" + +#: src/app.vala:101 +msgid "Show about dialog" +msgstr "" + +#: src/app.vala:102 +msgid "Maximum number of background worker threads" +msgstr "" + +#: src/app.vala:106 +msgid "Run game" +msgstr "" + +#: src/app.vala:107 +msgid "Show compatibility options dialog" +msgstr "" + +#: src/app.vala:108 +msgid "Open game details" +msgstr "" + +#: src/app.vala:109 +msgid "Open game properties" +msgstr "" + +#: src/app.vala:113 +msgid "Enable debug logging" +msgstr "" + +#: src/app.vala:114 +msgid "" +"Log authentication process and sensitive information like authentication " +"tokens" +msgstr "" + +#: src/app.vala:115 +msgid "Log download manager" +msgstr "" + +#: src/app.vala:116 +msgid "Log background workers start/stop" +msgstr "" + +#: src/app.vala:117 +msgid "Disable log messages filtering" +msgstr "" + +#: src/app.vala:118 +msgid "Verbose logging" +msgstr "" + +#: src/app.vala:247 +msgid "Game Options:" +msgstr "" + +#: src/app.vala:247 +msgid "Show game options help" +msgstr "" + +#: src/app.vala:255 +msgid "Logging Options:" +msgstr "" + +#: src/app.vala:255 +msgid "Show logging options help" +msgstr "" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +msgid "Select executable" +msgstr "" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:181 src/ui/views/GamesView/GamesView.vala:330 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select" +msgstr "" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:180 src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Cancel" +msgstr "" + +#: src/data/Runnable.vala:166 src/ui/widgets/FileChooserEntry.vala:49 +msgid "Select directory" +msgstr "" + +#: src/data/Runnable.vala:619 +#, c-format +msgid "Part %1$u of %2$u: %3$s" +msgstr "" + +#: src/data/Runnable.vala:642 src/ui/dialogs/CorruptedInstallerDialog.vala:48 +#, c-format +msgid "%s: corrupted installer" +msgstr "" + +#: src/data/Runnable.vala:643 +#, c-format +msgid "Checksum mismatch in %s" +msgstr "" + +#: src/data/Runnable.vala:657 src/ui/dialogs/CorruptedInstallerDialog.vala:126 +msgid "Show file" +msgstr "" + +#: src/data/Runnable.vala:658 src/ui/dialogs/CorruptedInstallerDialog.vala:132 +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#: src/ui/widgets/TagRow.vala:146 +msgid "Remove" +msgstr "" + +#: src/data/Runnable.vala:659 src/ui/dialogs/CorruptedInstallerDialog.vala:128 +msgid "Backup" +msgstr "" + +#: src/data/Runnable.vala:778 +#, c-format +msgid "%s: cannot detect main executable" +msgstr "" + +#: src/data/Runnable.vala:779 +msgid "" +"Main executable file for this game cannot be detected automatically.\n" +"Please set main executable in game's properties." +msgstr "" + +#: src/data/Runnable.vala:908 +msgctxt "platform" +msgid "Emulated" +msgstr "" + +#: src/data/Game.vala:625 +msgctxt "status" +msgid "Running" +msgstr "" + +#: src/data/Game.vala:628 +msgctxt "status" +msgid "Installed" +msgstr "" + +#: src/data/Game.vala:629 +msgctxt "status" +msgid "Installing" +msgstr "" + +#: src/data/Game.vala:630 +msgctxt "status" +msgid "Verifying installer integrity" +msgstr "" + +#: src/data/Game.vala:631 +msgctxt "status" +msgid "Download started" +msgstr "" + +#: src/data/Game.vala:633 +msgctxt "status" +msgid "Not installed" +msgstr "" + +#: src/data/Game.vala:643 +msgctxt "status_header" +msgid "Installed" +msgstr "" + +#: src/data/Game.vala:644 +msgctxt "status_header" +msgid "Installing" +msgstr "" + +#: src/data/Game.vala:646 +msgctxt "status_header" +msgid "Downloading" +msgstr "" + +#: src/data/Game.vala:648 +msgctxt "status_header" +msgid "Not installed" +msgstr "" + +#: src/data/GameSource.vala:31 +#, c-format +msgid "%s games" +msgstr "" + +#: src/data/sources/steam/Steam.vala:43 +msgid "Your SteamID will be read from Steam configuration file" +msgstr "" + +#: src/data/sources/steam/Steam.vala:46 +msgid "" +"Steam config file not found.\n" +"Login into your account in Steam client and return to GameHub" +msgstr "" + +#: src/data/sources/gog/GOGGame.vala:983 +#, c-format +msgid "DLC: %s" +msgstr "" + +#: src/data/sources/humble/HumbleGame.vala:343 +#, c-format +msgid "%s: no available installers" +msgstr "" + +#: src/data/sources/humble/HumbleGame.vala:344 +msgid "" +"Cannot get Trove download URL.\n" +"Make sure your Humble Monthly subscription is active." +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:192 +#, c-format +msgctxt "itch_dl_status" +msgid "%s left;" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:195 +#, c-format +msgctxt "itch_dl_status" +msgid "%d%%" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:198 +#, c-format +msgctxt "itch_dl_status" +msgid "(%1$s / %2$s)" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:201 +#, c-format +msgctxt "itch_dl_status" +msgid "[%s/s]" +msgstr "" + +#: src/data/sources/user/User.vala:30 +msgid "User games" +msgstr "" + +#: src/data/db/tables/Tags.vala:225 +msgctxt "tag" +msgid "Favorites" +msgstr "" + +#: src/data/db/tables/Tags.vala:226 +msgctxt "tag" +msgid "Not installed" +msgstr "" + +#: src/data/db/tables/Tags.vala:227 +msgctxt "tag" +msgid "Installed" +msgstr "" + +#: src/data/db/tables/Tags.vala:228 +msgctxt "tag" +msgid "Hidden" +msgstr "" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit script" +msgstr "" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit custom script" +msgstr "" + +#: src/data/compat/Innoextract.vala:55 +#, c-format +msgid "" +"Innoextract %1$s is not supported and may not be able to extract some " +"games correctly.\n" +"Install innoextract %2$s or newer." +msgstr "" + +#: src/data/compat/WineWrap.vala:61 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:242 +#: src/ui/dialogs/CompatRunDialog.vala:102 +#: src/ui/views/GamesView/GameContextMenu.vala:53 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:234 +msgid "Run" +msgstr "" + +#: src/data/compat/WineWrap.vala:64 +msgid "Show WineWrap menu" +msgstr "" + +#: src/data/compat/WineWrap.vala:67 src/data/compat/Proton.vala:122 +#: src/data/compat/Wine.vala:83 +msgid "Kill apps in prefix" +msgstr "" + +#: src/data/compat/Proton.vala:47 +msgid "Proton prefix" +msgstr "" + +#: src/data/compat/Proton.vala:110 src/data/compat/Wine.vala:71 +msgid "Open prefix directory" +msgstr "" + +#: src/data/compat/Proton.vala:113 src/data/compat/Wine.vala:74 +msgid "Run winecfg" +msgstr "" + +#: src/data/compat/Proton.vala:116 src/data/compat/Wine.vala:77 +msgid "Run winetricks" +msgstr "" + +#: src/data/compat/Proton.vala:119 src/data/compat/Wine.vala:80 +msgid "Run taskmgr" +msgstr "" + +#: src/data/compat/Wine.vala:53 +msgid "Wine prefix" +msgstr "" + +#: src/data/compat/Wine.vala:55 +msgid "Environment variables" +msgstr "" + +#: src/data/compat/Wine.vala:60 +msgid "InnoSetup default options" +msgstr "" + +#: src/data/compat/RetroArch.vala:53 +msgid "Libretro core file" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:43 +msgid "Custom emulator" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:48 +msgid "Emulator" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:49 +msgid "Launch in game directory" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:440 +msgctxt "status_header" +msgid "Favorites" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:445 +#, c-format +msgctxt "status_header" +msgid "%s: Favorites" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:491 +msgid "Merging games" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:504 +#, c-format +msgid "Merging games from %s" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:551 +#, c-format +msgid "Loading games from %s" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:678 +msgctxt "sort_mode" +msgid "By name" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:679 +msgctxt "sort_mode" +msgid "By last launch" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:680 +msgctxt "sort_mode" +msgid "By playtime" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:705 +msgctxt "group_mode" +msgid "Do not group" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:706 +msgctxt "group_mode" +msgid "By status" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:707 +msgctxt "group_mode" +msgid "By source" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:151 +#: src/data/providers/data/IGDB.vala:431 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:217 +msgid "Default" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:158 +#: src/data/providers/data/IGDB.vala:438 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:225 +msgid "Restore default API key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:169 +#: src/data/providers/data/IGDB.vala:449 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:108 +msgid "API key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:177 +#: src/data/providers/data/IGDB.vala:457 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:53 +msgid "Generate key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:208 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Style" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:209 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Score" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:213 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Author" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:225 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Alternate" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:226 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Blurred" +msgstr "" + +#. TRANSLATORS: Flat / Material Design image style. Probably should not be translated +#: src/data/providers/images/SteamGridDB.vala:228 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Material" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:229 +msgctxt "imagesource_steamgriddb_image_style" +msgid "No logo" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:230 +msgctxt "imagesource_steamgriddb_image_style" +msgid "White logo" +msgstr "" + +#: src/data/providers/data/IGDB.vala:147 +msgid "" +"Monthly IGDB request quota has been reached. Set your own API key to use " +"IGDB data or disable IGDB." +msgstr "" + +#: src/data/providers/data/IGDB.vala:148 +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:40 +#: src/ui/views/WelcomeView.vala:53 src/ui/views/WelcomeView.vala:78 +#: src/ui/views/GamesView/GamesView.vala:230 +#: src/ui/views/GamesView/GamesView.vala:629 +msgid "Settings" +msgstr "" + +#: src/data/providers/data/IGDB.vala:356 +msgctxt "igdb_related_link" +msgid "Official website" +msgstr "" + +#: src/data/providers/data/IGDB.vala:469 +msgctxt "igdb_preferred_description" +msgid "When game has description, show description" +msgstr "" + +#: src/data/providers/data/IGDB.vala:476 +msgctxt "igdb_preferred_description" +msgid "of game" +msgstr "" + +#: src/data/providers/data/IGDB.vala:477 +msgctxt "igdb_preferred_description" +msgid "from IGDB" +msgstr "" + +#: src/data/providers/data/IGDB.vala:478 +msgctxt "igdb_preferred_description" +msgid "both" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:65 +msgid "Some settings will be applied after application restart" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:71 +msgid "Games directory contains space. It may cause problems for some games" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:36 +msgid "Interface" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:37 +msgid "Appearance" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:38 +msgid "General interface settings" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:48 +msgid "Dark theme" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:53 +msgctxt "icon_style" +msgid "Theme-based" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:54 +msgctxt "icon_style" +msgid "Symbolic" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:55 +msgctxt "icon_style" +msgid "Colored" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:57 +msgctxt "icon_style" +msgid "Icon style" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:84 +msgid "Game card" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:86 +msgid "Show platform icons" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:99 +msgctxt "grid_size" +msgid "Card size" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:117 +msgctxt "grid_size_preset" +msgid "Presets" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:139 +msgid "Games list: installed" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:140 +msgid "Games list: not installed" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:142 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:146 +msgctxt "list_style" +msgid "Show icon" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:143 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:147 +msgctxt "list_style" +msgid "Bold title" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:144 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:148 +msgctxt "list_style" +msgid "Show status" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:149 +msgctxt "list_style" +msgid "Dim" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:151 +msgid "Grid options" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:152 +msgid "List options" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:31 +msgid "Behavior" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:32 +msgid "Behavior settings" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:42 +msgid "Run games with double click" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:46 +msgid "Merge games from different sources" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:50 +msgid "Use imported tags" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:51 +msgid "General" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:52 +msgid "Collection" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:53 +msgid "Empty" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:65 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:85 +msgid "Collection directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:70 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:78 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:87 +msgid "Game directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:71 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:79 +msgid "Installers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:72 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:98 +msgid "DLC" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:73 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:197 +msgid "Bonus content" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:84 +msgid "Variable syntax: $var or ${var}" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:86 +msgid "Game name" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:88 +#: src/ui/views/GamesView/FiltersPopover.vala:127 +msgid "Platform" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:36 +msgid "Controller" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +msgid "Enabled" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:53 +msgid "Focus GameHub window with Guide button" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:57 +msgid "Controllers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:89 +msgid "Move focus" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:91 +msgid "Exit" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:40 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:108 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:92 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:95 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:36 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:77 +msgid "Disabled" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:47 +#: src/ui/dialogs/GameTweaksDialog.vala:53 +#: src/ui/views/GamesView/GameContextMenu.vala:183 +msgid "Tweaks" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:34 +msgid "Tweak launch options and apply them to games automatically" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:79 +msgid "" +"Tweaks are loaded from following directories in order\n" +"Last tweak overrides previous tweaks with same identifiers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:83 +msgid "Click to open" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:93 +#, c-format +msgid "Tweaks are loaded from %1$s and %2$d more directories (?)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:38 +msgid "Game sources" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +msgid "Steam API keys have limited number of uses per day" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:63 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:57 +msgid "Installation directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:176 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:81 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:34 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:75 +msgid "Not installed" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:116 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:96 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:99 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:85 +msgid "Not authenticated" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +#, c-format +msgid "Authenticated as %s" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:103 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +msgid "Authenticated" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:183 +#: src/ui/dialogs/InstallDialog.vala:53 src/ui/dialogs/InstallDialog.vala:111 +#: src/ui/views/GamesView/GameContextMenu.vala:80 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:233 +#: src/ui/widgets/TweaksList.vala:95 +msgid "Install" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:236 +msgid "Steam API key" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:50 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:54 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:48 +msgid "Games directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:63 +msgid "Logout" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:50 +msgid "Load games from Humble Trove" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:45 +msgid "Emulators" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:45 +msgid "Libretro core directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:46 +msgid "Libretro core info directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:50 +msgid "Ignored libretro cores" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:54 +msgid "Ignored game file extensions" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:66 +msgid "No cores found" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:70 +#, c-format +msgid "%u core found" +msgid_plural "%u cores found" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:46 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:168 +msgid "No custom emulators" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:164 +#, c-format +msgid "%u custom emulator" +msgid_plural "%u custom emulators" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:237 +msgid "Save" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:250 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:312 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/dialogs/GamePropertiesDialog.vala:168 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +#: src/ui/views/GamesView/AddGamePopover.vala:67 +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Executable" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:251 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/views/GamesView/AddGamePopover.vala:68 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Installer" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:256 +#: src/ui/dialogs/GamePropertiesDialog.vala:64 +#: src/ui/dialogs/GamePropertiesDialog.vala:69 +#: src/ui/views/GamesView/AddGamePopover.vala:73 +msgid "Name" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:272 +#: src/ui/dialogs/GamePropertiesDialog.vala:201 +#: src/ui/views/GamesView/AddGamePopover.vala:78 +msgid "Arguments" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:276 +msgid "Variables" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:277 +msgid "Game executable" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:278 +msgid "Game arguments" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:80 +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +msgid "Select emulator directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:292 +#: src/ui/dialogs/GamePropertiesDialog.vala:219 +msgid "Force compatibility mode" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:307 +msgid "Game file patterns" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:315 +msgid "Image" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:318 +msgid "Icon" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:325 +msgid "" +"findutils-compatible glob patterns\n" +"\n" +" Multiple patterns can be separated with |\n" +" Start pattern with ./ to match relative path\n" +" $basename variable will be replaced with game's executable " +"name (without extension)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:38 +msgid "Data" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:39 +msgid "Providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:40 +msgid "Third-party data providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:55 +msgid "Image providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:68 +msgid "Metadata providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:137 +msgid "Open website" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:36 +msgid "About" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:71 +msgid "Copy application version and environment info" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:78 +#: src/ui/views/WelcomeView.vala:57 msgid "All your games in one place" msgstr "" -#: data/com.github.tkashkin.gamehub.appdata.xml.in:12 -msgid "Manage your Steam and GOG games in one place." +#: src/ui/dialogs/SettingsDialog/pages/About.vala:92 +msgctxt "about_link" +msgid "Website" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:96 +msgctxt "about_link" +msgid "Source code on GitHub" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:103 +msgctxt "about_link" +msgid "Report a problem" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:104 +msgctxt "about_link" +msgid "Suggest translations" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:110 +msgctxt "about_link" +msgid "Issues" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:111 +msgctxt "about_link" +msgid "Contributors" +msgstr "" + +#. TRANSLATORS: Likely it should not be translated. GitHub Pulse is a page that shows recent repository activity: https://github.com/tkashkin/GameHub/pulse +#: src/ui/dialogs/SettingsDialog/pages/About.vala:114 +msgctxt "about_link" +msgid "Pulse" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:115 +msgctxt "about_link" +msgid "Forks" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:109 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:129 +msgid "Import" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:110 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:153 +msgid "Download" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:207 +msgid "Select installer" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:216 +#, c-format +msgid "Installer size: %s" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:348 +msgid "Unknown" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:49 +#, c-format +msgid "%s: Properties" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:84 +msgid "Images" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:126 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:160 +#: src/ui/views/GameDetailsView/blocks/Artwork.vala:62 +msgid "Download images" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:144 +msgid "Image URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:148 +msgid "Vertical image URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:157 +msgid "Icon URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Select working directory" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Working directory" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:214 +msgid "Compatibility" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:236 +msgid "Launch from terminal" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:252 +msgid "Copy to clipboard" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:254 +msgid "Add to Steam" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:255 +msgid "Add to the Steam library" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:53 +#, c-format +msgid "%s: Overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "Overlays are disabled" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "" +"Enable overlays to manage DLCs and mods\n" +"\n" +"Enabling will move game to the “base“ overlay" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:77 +#: src/ui/views/GamesView/GameContextMenu.vala:175 +msgid "Overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:105 +msgid "Overlay ID (directory name)" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:110 +msgid "Overlay name (optional)" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:112 +msgid "Add" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:127 +msgid "Enable overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:182 +#, c-format +msgid "" +"Overlay usage at this path may be unsafe\n" +"Proceed at your own risk\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:187 +#, c-format +msgid "" +"Overlay usage at this path is not supported\n" +"\n" +"Path: %s" msgstr "" -#: data/com.github.tkashkin.gamehub.appdata.xml.in:15 -msgid "tkashkin" +#: src/ui/dialogs/GameFSOverlaysDialog.vala:266 +msgid "Open directory" msgstr "" -#: data/com.github.tkashkin.gamehub.desktop.in:7 -msgid "Game;Hub;Steam;GOG;" +#: src/ui/dialogs/GameFSOverlaysDialog.vala:271 +msgid "Remove overlay" msgstr "" -#: data/com.github.tkashkin.gamehub.desktop.in:10 -msgid "com.github.tkashkin.gamehub" +#: src/ui/dialogs/CompatRunDialog.vala:48 +#: src/ui/views/GamesView/GameContextMenu.vala:46 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:235 +msgid "Run with compatibility layer" msgstr "" -#: src/data/sources/steam/Steam.vala:13 -msgid "Your SteamID will be read from Steam configuration file" +#: src/ui/dialogs/CorruptedInstallerDialog.vala:71 +msgid "Corrupted installer: checksum mismatch in" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:57 +#: src/ui/views/GamesView/AddGamePopover.vala:105 +msgid "Import emulated games" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:75 +msgid "Select directory with emulated games" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:83 +msgid "Detected games" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:107 +msgid "Select all" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:115 +msgid "Select directory to import" +msgstr "" + +#: src/ui/dialogs/GameTweaksDialog.vala:40 +#, c-format +msgid "%s: Tweaks" +msgstr "" + +#: src/ui/views/WelcomeView.vala:52 +msgid "No enabled game sources" +msgstr "" + +#: src/ui/views/WelcomeView.vala:52 +msgid "Enable some game sources in settings" msgstr "" -#: src/ui/views/WelcomeView.vala:16 +#: src/ui/views/WelcomeView.vala:57 msgid "Let's get started" msgstr "" -#: src/ui/views/WelcomeView.vala:24 +#: src/ui/views/WelcomeView.vala:71 msgid "Skip" msgstr "" -#: src/ui/views/WelcomeView.vala:60 -#, c-format -msgid "%d games loaded" +#: src/ui/views/WelcomeView.vala:141 +msgid "Ready" msgstr "" -#: src/ui/views/WelcomeView.vala:65 +#: src/ui/views/WelcomeView.vala:147 msgid "Authentication required" msgstr "" -#: src/ui/views/WelcomeView.vala:70 +#: src/ui/views/WelcomeView.vala:152 +msgid "Authenticating…" +msgstr "" + +#: src/ui/views/WelcomeView.vala:163 #, c-format msgid "Install %s" msgstr "" + +#: src/ui/views/WelcomeView.vala:164 +msgid "Return to GameHub after installing" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "No games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "Get some games or enable some game sources in settings" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:150 +msgid "Grid view" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:151 +msgid "List view" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:159 +msgid "All games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:182 +msgid "Downloads" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:208 +msgid "Filters" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:216 +#: src/ui/views/GamesView/AddGamePopover.vala:84 +msgid "Add game" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:223 +msgid "Search" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:328 +msgid "Menu" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:329 +#: src/ui/views/GameDetailsView/GameDetailsView.vala:104 +msgid "Back" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:550 +#, c-format +msgid "%u game" +msgid_plural "%u games" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GamesView/GamesView.vala:553 +#, c-format +msgctxt "games_view_subtitle_filtered_games" +msgid "%1$u / %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:557 +#, c-format +msgctxt "games_view_subtitle" +msgid "%1$s: %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:568 +msgid "No user-added games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:569 +msgid "Add some games using plus button" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:573 +#, c-format +msgid "No %s games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:574 +msgid "Get some Linux-compatible games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:584 +#, c-format +msgid "No games matching “%s”" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:589 +#, c-format +msgid "No %1$s games matching “%2$s”" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:627 +msgid "" +"No games were loaded from Steam. Set your games list privacy to public or " +"use your own Steam API key in settings." +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:628 +msgid "Privacy" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:739 +msgid "Downloading images" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:753 +#, c-format +msgid "Downloading image: %s" +msgstr "" + +#: src/ui/views/GamesView/DownloadProgressView.vala:131 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:162 +msgid "Pause download" +msgstr "" + +#: src/ui/views/GamesView/DownloadProgressView.vala:137 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:168 +msgid "Resume download" +msgstr "" + +#: src/ui/views/GamesView/DownloadProgressView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:174 +msgid "Cancel download" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:77 +msgid "Group" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:102 +msgid "Sort" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:234 +#: src/ui/widgets/GameTagsList.vala:58 +msgid "Tags" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:353 +msgid "All platforms" +msgstr "" + +#: src/ui/views/GamesView/AddGamePopover.vala:77 +msgid "Select game executable" +msgstr "" + +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Select game directory" +msgstr "" + +#: src/ui/views/GamesView/AddGamePopover.vala:111 +msgid "Download game images" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:87 +msgid "Details" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:117 +msgctxt "game_context_menu" +msgid "Favorite" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:121 +msgctxt "game_context_menu" +msgid "Hidden" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:133 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:236 +msgid "Open installation directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:142 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:237 +msgid "Open installers collection directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:151 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:238 +msgid "Open bonus collection directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:160 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:239 +msgid "Open screenshots directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +msgid "Uninstall" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:192 +msgid "Properties" +msgstr "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:100 +#, c-format +msgid "%d game selected" +msgid_plural "%d games selected" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:144 +#, c-format +msgid "%d game will be installed" +msgid_plural "%d games will be installed" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:154 +#, c-format +msgid "%d game will be downloaded" +msgid_plural "%d games will be downloaded" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:161 +#, c-format +msgid "Image for %d game will be searched" +msgid_plural "Images for %d games will be searched" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:168 +#, c-format +msgid "%d game will be uninstalled" +msgid_plural "%d games will be uninstalled" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:174 +msgid "Refresh" +msgstr "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:175 +#, c-format +msgid "" +"%d game will be removed from database. Restart GameHub to fetch new data" +msgid_plural "" +"%d games will be removed from database. Restart GameHub to fetch new data" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:240 +msgid "Open store page" +msgstr "" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:242 +msgid "Game properties" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:46 +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:60 +msgid "Playtime" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:52 +msgid "Playtime (local)" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:69 +msgid "Last launch" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:46 +msgid "Achievements" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:85 +#, c-format +msgid "Unlocked: %s" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:90 +#, c-format +msgid "Global percentage: %g%%" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:77 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:103 +msgid "Language" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:80 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:106 +msgid "Languages" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:147 +#, c-format +msgid "%u DLCs cannot be installed" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:71 +msgid "Category" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:74 +msgid "Categories" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:90 +msgid "Genre" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:93 +msgid "Genres" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:109 +msgctxt "igdb" +msgid "Popularity" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:115 +msgctxt "igdb" +msgid "Aggregated rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:116 +msgctxt "igdb" +msgid "IGDB user rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:117 +msgctxt "igdb" +msgid "Total rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:126 +msgctxt "igdb" +msgid "Release date" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:133 +msgctxt "igdb" +msgid "Platforms" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:139 +msgctxt "igdb" +msgid "Genres" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:145 +msgctxt "igdb" +msgid "Keywords" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:152 +msgctxt "igdb" +msgid "Links" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:208 +#, c-format +msgid "Based on %d rating" +msgid_plural "Based on %d ratings" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:290 +msgctxt "igdb" +msgid "Summary" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:301 +msgctxt "igdb" +msgid "Storyline" +msgstr "" + +#: src/ui/widgets/FileChooserEntry.vala:49 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select file" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "No images" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "" +"There are no images found for this game\n" +"Make sure game name is correct" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:94 +msgid "Search images:" +msgstr "" + +#: src/ui/widgets/CompatToolPicker.vala:53 +msgid "Compatibility layer:" +msgstr "" + +#: src/ui/widgets/CompatToolPicker.vala:92 +msgid "Configure" +msgstr "" + +#: src/ui/widgets/GameTagsList.vala:109 +msgid "Add tag" +msgstr "" + +#: src/ui/widgets/TweaksList.vala:86 +msgid "No description" +msgstr "" + +#: src/ui/widgets/TweaksList.vala:124 +msgid "Edit file" +msgstr "" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dh" +msgstr "" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dm" +msgstr "" + +#: src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%ds" +msgstr "" + +#: src/settings/UI.vala:153 +msgctxt "grid_size_preset" +msgid "Steam" +msgstr "" + +#: src/settings/UI.vala:154 +msgctxt "grid_size_preset" +msgid "Steam (vertical)" +msgstr "" + +#: src/settings/UI.vala:155 +msgctxt "grid_size_preset" +msgid "GOG" +msgstr "" + +#: src/settings/UI.vala:156 +msgctxt "grid_size_preset" +msgid "GOG (vertical)" +msgstr "" + +#: src/settings/UI.vala:157 +msgctxt "grid_size_preset" +msgid "Square" +msgstr "" + +#: src/settings/UI.vala:158 +msgctxt "grid_size_preset" +msgid "Custom" +msgstr "" + +#: src/utils/downloader/Downloader.vala:200 +msgctxt "dl_status" +msgid "Queued" +msgstr "" + +#: src/utils/downloader/Downloader.vala:201 +msgctxt "dl_status" +msgid "Starting download" +msgstr "" + +#: src/utils/downloader/Downloader.vala:202 +msgctxt "dl_status" +msgid "Download started" +msgstr "" + +#: src/utils/downloader/Downloader.vala:203 +msgctxt "dl_status" +msgid "Download finished" +msgstr "" + +#: src/utils/downloader/Downloader.vala:204 +msgctxt "dl_status" +msgid "Download failed" +msgstr "" + +#: src/utils/downloader/Downloader.vala:208 +#, c-format +msgctxt "dl_status" +msgid "Downloading: %s" +msgstr "" + +#: src/utils/downloader/Downloader.vala:210 +msgctxt "dl_status" +msgid "Downloading" +msgstr "" + +#: src/utils/downloader/Downloader.vala:214 +#, c-format +msgctxt "dl_status" +msgid "Paused: %s" +msgstr "" + +#: src/utils/downloader/Downloader.vala:216 +msgctxt "dl_status" +msgid "Paused" +msgstr "" + +#: src/utils/downloader/Downloader.vala:218 +msgctxt "dl_status" +msgid "Download cancelled" +msgstr "" + +#. TRANSLATORS: Download progress template. %1$d - percentage, %2$s / %3$s - downloaded portion and total file size, %4$s - download speed +#: src/utils/downloader/Downloader.vala:262 +#, c-format +msgctxt "dl_status" +msgid "%1$d%% (%2$s / %3$s) [%4$s/s]" +msgstr "" diff --git a/po/de.po b/po/de.po new file mode 100644 index 00000000..ad9e8054 --- /dev/null +++ b/po/de.po @@ -0,0 +1,1932 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the com.github.tkashkin.gamehub package. +# jonathanschaefer , 2018. +# ssantos , 2018, 2019. +# Anatoliy Kashkin , 2018, 2019. +# Ettore Atalan , 2018. +# CurlingTongs , 2019. +# Swann Martinet , 2019. +# tinect , 2019. +# anonymous , 2020. +# Sascha Bohrmann , 2020. +# Sascha Bohrmann , 2020. +msgid "" +msgstr "" +"Project-Id-Version: com.github.tkashkin.gamehub\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-26 06:40+0300\n" +"PO-Revision-Date: 2020-03-20 10:36+0000\n" +"Last-Translator: anonymous \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.0-dev\n" + +#: src/app.vala:91 +msgid "Show help" +msgstr "Hilfe anzeigen" + +#: src/app.vala:92 +msgid "Show application version and exit" +msgstr "Anwendungsversion anzeigen und beenden" + +#: src/app.vala:93 +msgid "Restart with GDB debugger attached" +msgstr "Neustart mit verbundenem GDB-Debugger" + +#: src/app.vala:94 +msgid "Show full GDB backtrace" +msgstr "Vollständige GDB-Backtrace anzeigen" + +#: src/app.vala:95 +msgid "Treat fatal errors as criticals and crash application" +msgstr "Schwerwiegende Fehler als kritisch und Crash-Anwendung behandeln" + +#: src/app.vala:99 +msgid "Show main window" +msgstr "Hauptfenster anzeigen" + +#: src/app.vala:100 +msgid "Show application settings dialog" +msgstr "Dialogfeld für Anwendungseinstellungen anzeigen" + +#: src/app.vala:101 +msgid "Show about dialog" +msgstr "Infodialog anzeigen" + +#: src/app.vala:102 +msgid "Maximum number of background worker threads" +msgstr "Maximale Anzahl von Hintergrund-Worker-Threads" + +#: src/app.vala:106 +msgid "Run game" +msgstr "Spiel starten" + +#: src/app.vala:107 +msgid "Show compatibility options dialog" +msgstr "Kompatibilitätsoptionen-Dialog anzeigen" + +#: src/app.vala:108 +msgid "Open game details" +msgstr "Spieldetails öffnen" + +#: src/app.vala:109 +msgid "Open game properties" +msgstr "Spieleigenschaften öffnen" + +#: src/app.vala:113 +msgid "Enable debug logging" +msgstr "Debug-Protokollierung aktivieren" + +#: src/app.vala:114 +msgid "" +"Log authentication process and sensitive information like authentication " +"tokens" +msgstr "" +"Den Authentifizierungsprozess und sensible Informationen wie " +"Authentifizierungstoken protokollieren" + +#: src/app.vala:115 +msgid "Log download manager" +msgstr "Download-Manager protokollieren" + +#: src/app.vala:116 +msgid "Log background workers start/stop" +msgstr "Start/Stopp von Hintergrund-Workern protokollieren" + +#: src/app.vala:117 +msgid "Disable log messages filtering" +msgstr "Deaktiviere Log-Nachrichten Filterung" + +#: src/app.vala:118 +msgid "Verbose logging" +msgstr "Ausführliche Protokollierung" + +#: src/app.vala:247 +msgid "Game Options:" +msgstr "Spieloptionen:" + +#: src/app.vala:247 +msgid "Show game options help" +msgstr "Hilfe zu den Spieloptionen anzeigen" + +#: src/app.vala:255 +msgid "Logging Options:" +msgstr "Protokollierungsoptionen:" + +#: src/app.vala:255 +msgid "Show logging options help" +msgstr "Hilfe zu den Protokollierungsoptionen anzeigen" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +msgid "Select executable" +msgstr "Ausführbare Datei auswählen" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:181 src/ui/views/GamesView/GamesView.vala:330 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select" +msgstr "Auswählen" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:180 src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Cancel" +msgstr "Abbrechen" + +#: src/data/Runnable.vala:166 src/ui/widgets/FileChooserEntry.vala:49 +msgid "Select directory" +msgstr "Ordner auswählen" + +#: src/data/Runnable.vala:619 +#, c-format +msgid "Part %1$u of %2$u: %3$s" +msgstr "Teil %1$u von %2$u: %3$s" + +#: src/data/Runnable.vala:642 src/ui/dialogs/CorruptedInstallerDialog.vala:48 +#, c-format +msgid "%s: corrupted installer" +msgstr "%s: fehlerhafter Installer" + +#: src/data/Runnable.vala:643 +#, c-format +msgid "Checksum mismatch in %s" +msgstr "Prüfsummenfehler in %s" + +#: src/data/Runnable.vala:657 src/ui/dialogs/CorruptedInstallerDialog.vala:126 +msgid "Show file" +msgstr "Datei anzeigen" + +#: src/data/Runnable.vala:658 src/ui/dialogs/CorruptedInstallerDialog.vala:132 +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#: src/ui/widgets/TagRow.vala:146 +msgid "Remove" +msgstr "Entfernen" + +#: src/data/Runnable.vala:659 src/ui/dialogs/CorruptedInstallerDialog.vala:128 +msgid "Backup" +msgstr "Sicherung" + +#: src/data/Runnable.vala:778 +#, c-format +msgid "%s: cannot detect main executable" +msgstr "%s: die Hauptausführdatei kann nicht identifiziert werden" + +#: src/data/Runnable.vala:779 +msgid "" +"Main executable file for this game cannot be detected automatically.\n" +"Please set main executable in game's properties." +msgstr "" +"Die Hauptausführungsdatei für dieses Spiel kann nicht automatisch erkannt " +"werden.\n" +"Bitte stelle die Hauptausführungsdatei in den Spieleigenschaften ein." + +#: src/data/Runnable.vala:908 +msgctxt "platform" +msgid "Emulated" +msgstr "Emuliert" + +#: src/data/Game.vala:625 +msgctxt "status" +msgid "Running" +msgstr "Läuft" + +#: src/data/Game.vala:628 +msgctxt "status" +msgid "Installed" +msgstr "Installiert" + +#: src/data/Game.vala:629 +msgctxt "status" +msgid "Installing" +msgstr "Installation" + +#: src/data/Game.vala:630 +msgctxt "status" +msgid "Verifying installer integrity" +msgstr "Integrität des Installers wird überprüft" + +#: src/data/Game.vala:631 +msgctxt "status" +msgid "Download started" +msgstr "Download gestartet" + +#: src/data/Game.vala:633 +msgctxt "status" +msgid "Not installed" +msgstr "Nicht installiert" + +#: src/data/Game.vala:643 +msgctxt "status_header" +msgid "Installed" +msgstr "Installiert" + +#: src/data/Game.vala:644 +msgctxt "status_header" +msgid "Installing" +msgstr "Installation" + +#: src/data/Game.vala:646 +msgctxt "status_header" +msgid "Downloading" +msgstr "Herunterladen" + +#: src/data/Game.vala:648 +msgctxt "status_header" +msgid "Not installed" +msgstr "Nicht installiert" + +#: src/data/GameSource.vala:31 +#, c-format +msgid "%s games" +msgstr "%s Spiele" + +#: src/data/sources/steam/Steam.vala:43 +msgid "Your SteamID will be read from Steam configuration file" +msgstr "Ihre SteamID wird aus der Steam-Konfigurationsdatei gelesen" + +#: src/data/sources/steam/Steam.vala:46 +msgid "" +"Steam config file not found.\n" +"Login into your account in Steam client and return to GameHub" +msgstr "" +"Steam-Konfigurationsdatei nicht gefunden.\n" +"Bitte melden Sie sich in Steam an" + +#: src/data/sources/gog/GOGGame.vala:983 +#, c-format +msgid "DLC: %s" +msgstr "DLC: %s" + +#: src/data/sources/humble/HumbleGame.vala:343 +#, c-format +msgid "%s: no available installers" +msgstr "%s: keine Installationsprogramme verfügbare" + +#: src/data/sources/humble/HumbleGame.vala:344 +msgid "" +"Cannot get Trove download URL.\n" +"Make sure your Humble Monthly subscription is active." +msgstr "" +"Die Download-URL von Trove kann nicht abgerufen werden.\n" +"Stellen Sie sicher, dass Ihr Humble Monthly Abonnement aktiv ist." + +#: src/data/sources/itch/ItchDownloader.vala:192 +#, c-format +msgctxt "itch_dl_status" +msgid "%s left;" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:195 +#, c-format +msgctxt "itch_dl_status" +msgid "%d%%" +msgstr "%d%%" + +#: src/data/sources/itch/ItchDownloader.vala:198 +#, c-format +msgctxt "itch_dl_status" +msgid "(%1$s / %2$s)" +msgstr "(%1$s / %2$s)" + +#: src/data/sources/itch/ItchDownloader.vala:201 +#, c-format +msgctxt "itch_dl_status" +msgid "[%s/s]" +msgstr "[%s/s]" + +#: src/data/sources/user/User.vala:30 +msgid "User games" +msgstr "Benutzerspiele" + +#: src/data/db/tables/Tags.vala:225 +msgctxt "tag" +msgid "Favorites" +msgstr "Favoriten" + +#: src/data/db/tables/Tags.vala:226 +msgctxt "tag" +msgid "Not installed" +msgstr "Nicht installiert" + +#: src/data/db/tables/Tags.vala:227 +msgctxt "tag" +msgid "Installed" +msgstr "Installiert" + +#: src/data/db/tables/Tags.vala:228 +msgctxt "tag" +msgid "Hidden" +msgstr "Versteckt" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit script" +msgstr "Skript bearbeiten" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit custom script" +msgstr "Benutzerdefiniertes Skript bearbeiten" + +#: src/data/compat/Innoextract.vala:55 +#, c-format +msgid "" +"Innoextract %1$s is not supported and may not be able to extract some " +"games correctly.\n" +"Install innoextract %2$s or newer." +msgstr "" +"Innoextract %1$s wird nicht unterstützt und kann einige Spiele " +"möglicherweise nicht korrekt extrahieren.\n" +"Innoextract %2$s oder neuer installieren." + +#: src/data/compat/WineWrap.vala:61 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:242 +#: src/ui/dialogs/CompatRunDialog.vala:102 +#: src/ui/views/GamesView/GameContextMenu.vala:53 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:234 +msgid "Run" +msgstr "Ausführen" + +#: src/data/compat/WineWrap.vala:64 +msgid "Show WineWrap menu" +msgstr "WineWrap-Menü anzeigen" + +#: src/data/compat/WineWrap.vala:67 src/data/compat/Proton.vala:122 +#: src/data/compat/Wine.vala:83 +msgid "Kill apps in prefix" +msgstr "Apps im Präfix beenden" + +#: src/data/compat/Proton.vala:47 +msgid "Proton prefix" +msgstr "Proton-Präfix" + +#: src/data/compat/Proton.vala:110 src/data/compat/Wine.vala:71 +msgid "Open prefix directory" +msgstr "Präfixverzeichnis öffnen" + +#: src/data/compat/Proton.vala:113 src/data/compat/Wine.vala:74 +msgid "Run winecfg" +msgstr "winecfg ausführen" + +#: src/data/compat/Proton.vala:116 src/data/compat/Wine.vala:77 +msgid "Run winetricks" +msgstr "winetricks ausführen" + +#: src/data/compat/Proton.vala:119 src/data/compat/Wine.vala:80 +msgid "Run taskmgr" +msgstr "taskmgr ausführen" + +#: src/data/compat/Wine.vala:53 +msgid "Wine prefix" +msgstr "Wine-Präfix" + +#: src/data/compat/Wine.vala:55 +msgid "Environment variables" +msgstr "Umgebungsvariablen" + +#: src/data/compat/Wine.vala:60 +msgid "InnoSetup default options" +msgstr "Standardoptionen für InnoSetup" + +#: src/data/compat/RetroArch.vala:53 +msgid "Libretro core file" +msgstr "Libretro-Kerndatei" + +#: src/data/compat/CustomEmulator.vala:43 +msgid "Custom emulator" +msgstr "Benutzerdefinierter Emulator" + +#: src/data/compat/CustomEmulator.vala:48 +msgid "Emulator" +msgstr "Emulator" + +#: src/data/compat/CustomEmulator.vala:49 +msgid "Launch in game directory" +msgstr "Im Spielverzeichnis starten" + +#: src/data/adapters/GamesAdapter.vala:440 +msgctxt "status_header" +msgid "Favorites" +msgstr "Favoriten" + +#: src/data/adapters/GamesAdapter.vala:445 +#, c-format +msgctxt "status_header" +msgid "%s: Favorites" +msgstr "%s: Favoriten" + +#: src/data/adapters/GamesAdapter.vala:491 +msgid "Merging games" +msgstr "Zusammenführung von Spielen" + +#: src/data/adapters/GamesAdapter.vala:504 +#, c-format +msgid "Merging games from %s" +msgstr "Zusammenführen von Spielen aus %s" + +#: src/data/adapters/GamesAdapter.vala:551 +#, c-format +msgid "Loading games from %s" +msgstr "Laden von Spielen aus %s" + +#: src/data/adapters/GamesAdapter.vala:678 +msgctxt "sort_mode" +msgid "By name" +msgstr "Nach Name" + +#: src/data/adapters/GamesAdapter.vala:679 +msgctxt "sort_mode" +msgid "By last launch" +msgstr "Nach letztem Start" + +#: src/data/adapters/GamesAdapter.vala:680 +msgctxt "sort_mode" +msgid "By playtime" +msgstr "Nach Spielzeit" + +#: src/data/adapters/GamesAdapter.vala:705 +msgctxt "group_mode" +msgid "Do not group" +msgstr "Nicht gruppieren" + +#: src/data/adapters/GamesAdapter.vala:706 +msgctxt "group_mode" +msgid "By status" +msgstr "nach Status" + +#: src/data/adapters/GamesAdapter.vala:707 +msgctxt "group_mode" +msgid "By source" +msgstr "nach Spielquellen" + +#: src/data/providers/images/SteamGridDB.vala:151 +#: src/data/providers/data/IGDB.vala:431 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:217 +msgid "Default" +msgstr "Standard" + +#: src/data/providers/images/SteamGridDB.vala:158 +#: src/data/providers/data/IGDB.vala:438 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:225 +msgid "Restore default API key" +msgstr "Standard-API-Schlüssel wiederherstellen" + +#: src/data/providers/images/SteamGridDB.vala:169 +#: src/data/providers/data/IGDB.vala:449 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:108 +msgid "API key" +msgstr "API-Schlüssel" + +#: src/data/providers/images/SteamGridDB.vala:177 +#: src/data/providers/data/IGDB.vala:457 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:53 +msgid "Generate key" +msgstr "Schlüssel generieren" + +#: src/data/providers/images/SteamGridDB.vala:208 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Style" +msgstr "Design" + +#: src/data/providers/images/SteamGridDB.vala:209 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Score" +msgstr "Bewertung" + +#: src/data/providers/images/SteamGridDB.vala:213 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Author" +msgstr "Autor" + +#: src/data/providers/images/SteamGridDB.vala:225 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Alternate" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:226 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Blurred" +msgstr "Verwischt" + +#. TRANSLATORS: Flat / Material Design image style. Probably should not be translated +#: src/data/providers/images/SteamGridDB.vala:228 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Material" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:229 +msgctxt "imagesource_steamgriddb_image_style" +msgid "No logo" +msgstr "Kein Logo" + +#: src/data/providers/images/SteamGridDB.vala:230 +msgctxt "imagesource_steamgriddb_image_style" +msgid "White logo" +msgstr "Weißes Logo" + +#: src/data/providers/data/IGDB.vala:147 +msgid "" +"Monthly IGDB request quota has been reached. Set your own API key to use " +"IGDB data or disable IGDB." +msgstr "" +"Monatliche IGDB Anfragen-Quote erreicht. Nutze deinen eigenen API-Schlüssel " +"um die IGDB-Daten weiter zu nutzen oder deaktiviere IGDB." + +#: src/data/providers/data/IGDB.vala:148 +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:40 +#: src/ui/views/WelcomeView.vala:53 src/ui/views/WelcomeView.vala:78 +#: src/ui/views/GamesView/GamesView.vala:230 +#: src/ui/views/GamesView/GamesView.vala:629 +msgid "Settings" +msgstr "Einstellungen" + +#: src/data/providers/data/IGDB.vala:356 +msgctxt "igdb_related_link" +msgid "Official website" +msgstr "Offizielle Webseite" + +#: src/data/providers/data/IGDB.vala:469 +msgctxt "igdb_preferred_description" +msgid "When game has description, show description" +msgstr "Zeige die Beschreibung, sollte das Spiel eine besitzen" + +#: src/data/providers/data/IGDB.vala:476 +msgctxt "igdb_preferred_description" +msgid "of game" +msgstr "vom Spiel" + +#: src/data/providers/data/IGDB.vala:477 +msgctxt "igdb_preferred_description" +msgid "from IGDB" +msgstr "von IGDB" + +#: src/data/providers/data/IGDB.vala:478 +msgctxt "igdb_preferred_description" +msgid "both" +msgstr "beide" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:65 +msgid "Some settings will be applied after application restart" +msgstr "Einige Einstellungen werden nach dem Neustart übernommen" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:71 +msgid "Games directory contains space. It may cause problems for some games" +msgstr "" +"Das Spielverzeichnis enthält Leerzeichen. Das kann bei einigen Spielen zu " +"Problemen führen" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:36 +msgid "Interface" +msgstr "Schnittstelle" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:37 +msgid "Appearance" +msgstr "Aussehen" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:38 +msgid "General interface settings" +msgstr "Allgemeine Schnittstelleneinstellungen" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:48 +msgid "Dark theme" +msgstr "Dunkles Thema" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:53 +msgctxt "icon_style" +msgid "Theme-based" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:54 +msgctxt "icon_style" +msgid "Symbolic" +msgstr "Symbolisch" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:55 +msgctxt "icon_style" +msgid "Colored" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:57 +msgctxt "icon_style" +msgid "Icon style" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:84 +#, fuzzy +msgid "Game card" +msgstr "Spielname" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:86 +msgid "Show platform icons" +msgstr "Plattformsymbole anzeigen" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:99 +msgctxt "grid_size" +msgid "Card size" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:117 +msgctxt "grid_size_preset" +msgid "Presets" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:139 +msgid "Games list: installed" +msgstr "Spieleliste: installiert" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:140 +msgid "Games list: not installed" +msgstr "Spieleliste: nicht installiert" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:142 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:146 +msgctxt "list_style" +msgid "Show icon" +msgstr "Symbol anzeigen" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:143 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:147 +msgctxt "list_style" +msgid "Bold title" +msgstr "Titelname Fett anzeigen" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:144 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:148 +msgctxt "list_style" +msgid "Show status" +msgstr "Zeige Status" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:149 +msgctxt "list_style" +msgid "Dim" +msgstr "Schrift dimmen" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:151 +msgid "Grid options" +msgstr "Grid-Optionen" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:152 +msgid "List options" +msgstr "Listenoptionen" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:31 +msgid "Behavior" +msgstr "Verhalten" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:32 +msgid "Behavior settings" +msgstr "Verhaltenseinstellungen" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:42 +msgid "Run games with double click" +msgstr "Spiele per Doppelklick starten" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:46 +msgid "Merge games from different sources" +msgstr "Spiele aus verschiedenen Quellen zusammenführen" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:50 +msgid "Use imported tags" +msgstr "Importierte Tags verwenden" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:51 +msgid "General" +msgstr "Allgemein" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:52 +msgid "Collection" +msgstr "Sammlung" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:53 +#, fuzzy +msgid "Empty" +msgstr "Leer" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:65 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:85 +msgid "Collection directory" +msgstr "Sammelverzeichnis" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:70 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:78 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:87 +msgid "Game directory" +msgstr "Spielverzeichnis" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:71 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:79 +msgid "Installers" +msgstr "Installer" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:72 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:98 +msgid "DLC" +msgstr "DLC" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:73 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:197 +msgid "Bonus content" +msgstr "Bonusinhalte" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:84 +msgid "Variable syntax: $var or ${var}" +msgstr "Syntax: $var or ${var}" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:86 +msgid "Game name" +msgstr "Spielname" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:88 +#: src/ui/views/GamesView/FiltersPopover.vala:127 +msgid "Platform" +msgstr "Plattform" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:36 +msgid "Controller" +msgstr "Steuergerät" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +msgid "Enabled" +msgstr "Aktiviert" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:53 +msgid "Focus GameHub window with Guide button" +msgstr "GameHub-Fenster mit Guide-Taste fokussieren" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:57 +msgid "Controllers" +msgstr "Steuergeräte" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:89 +msgid "Move focus" +msgstr "Fokus verschieben" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:91 +msgid "Exit" +msgstr "Verlassen" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:40 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:108 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:92 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:95 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:36 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:77 +msgid "Disabled" +msgstr "Deaktiviert" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:47 +#: src/ui/dialogs/GameTweaksDialog.vala:53 +#: src/ui/views/GamesView/GameContextMenu.vala:183 +msgid "Tweaks" +msgstr "Tweaks" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:34 +msgid "Tweak launch options and apply them to games automatically" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:79 +msgid "" +"Tweaks are loaded from following directories in order\n" +"Last tweak overrides previous tweaks with same identifiers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:83 +msgid "Click to open" +msgstr "Klicke zum Öffnen" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:93 +#, c-format +msgid "Tweaks are loaded from %1$s and %2$d more directories (?)" +msgstr "" +"Tweaks wurden von %1$s und %2$d weiteren Ordnern geladen (?)" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:38 +msgid "Game sources" +msgstr "Spielquellen" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +msgid "Steam API keys have limited number of uses per day" +msgstr "" +"Steam-API-Schlüssel haben eine begrenzte Anzahl von Anwendungen pro Tag" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:63 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:57 +msgid "Installation directory" +msgstr "Installationsverzeichnis" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:176 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:81 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:34 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:75 +msgid "Not installed" +msgstr "Nicht installiert" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:116 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:96 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:99 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:85 +msgid "Not authenticated" +msgstr "Nicht authentifiziert" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +#, c-format +msgid "Authenticated as %s" +msgstr "Authentifiziert als %s" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:103 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +msgid "Authenticated" +msgstr "Authentifiziert" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:183 +#: src/ui/dialogs/InstallDialog.vala:53 src/ui/dialogs/InstallDialog.vala:111 +#: src/ui/views/GamesView/GameContextMenu.vala:80 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:233 +#: src/ui/widgets/TweaksList.vala:95 +msgid "Install" +msgstr "Installieren" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:236 +msgid "Steam API key" +msgstr "Steam-API-Schlüssel" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:50 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:54 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:48 +msgid "Games directory" +msgstr "Spieleverzeichnis" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:63 +msgid "Logout" +msgstr "Abmeldung" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:50 +msgid "Load games from Humble Trove" +msgstr "Spiele aus Humble Trove laden" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:45 +msgid "Emulators" +msgstr "Emulatoren" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:45 +msgid "Libretro core directory" +msgstr "Libretro-Kernverzeichnis" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:46 +msgid "Libretro core info directory" +msgstr "Libretro-Kern-Infoverzeichnis" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:50 +msgid "Ignored libretro cores" +msgstr "Ignorierte Libretro-Kerne" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:54 +msgid "Ignored game file extensions" +msgstr "Ignorierte Spiel Datei Erweiterungen" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:66 +msgid "No cores found" +msgstr "Keine Kerne gefunden" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:70 +#, c-format +msgid "%u core found" +msgid_plural "%u cores found" +msgstr[0] "%u Kern gefunden" +msgstr[1] "%u Kerne gefunden" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:46 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:168 +msgid "No custom emulators" +msgstr "Keine benutzerdefinierten Emulatoren" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:164 +#, c-format +msgid "%u custom emulator" +msgid_plural "%u custom emulators" +msgstr[0] "%u benutzerdefinierter Emulator" +msgstr[1] "%u benutzerdefinierte Emulatoren" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:237 +msgid "Save" +msgstr "Speichern" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:250 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:312 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/dialogs/GamePropertiesDialog.vala:168 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +#: src/ui/views/GamesView/AddGamePopover.vala:67 +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Executable" +msgstr "Ausführbare Datei" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:251 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/views/GamesView/AddGamePopover.vala:68 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Installer" +msgstr "Installer" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:256 +#: src/ui/dialogs/GamePropertiesDialog.vala:64 +#: src/ui/dialogs/GamePropertiesDialog.vala:69 +#: src/ui/views/GamesView/AddGamePopover.vala:73 +msgid "Name" +msgstr "Name" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:272 +#: src/ui/dialogs/GamePropertiesDialog.vala:201 +#: src/ui/views/GamesView/AddGamePopover.vala:78 +msgid "Arguments" +msgstr "Argumente" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:276 +msgid "Variables" +msgstr "Variablen" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:277 +msgid "Game executable" +msgstr "Ausführbare Spieldatei auswählen" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:278 +msgid "Game arguments" +msgstr "Argumente" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:80 +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Directory" +msgstr "Verzeichnis" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +msgid "Select emulator directory" +msgstr "Emulatorverzeichnis auswählen" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:292 +#: src/ui/dialogs/GamePropertiesDialog.vala:219 +msgid "Force compatibility mode" +msgstr "Kompatibilitätsmodus erzwingen" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:307 +msgid "Game file patterns" +msgstr "Spieldateien auswählen" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:315 +msgid "Image" +msgstr "Bilder" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:318 +msgid "Icon" +msgstr "Icon" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:325 +msgid "" +"findutils-compatible glob patterns\n" +"\n" +" Multiple patterns can be separated with |\n" +" Start pattern with ./ to match relative path\n" +" $basename variable will be replaced with game's executable " +"name (without extension)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:38 +msgid "Data" +msgstr "Daten" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:39 +msgid "Providers" +msgstr "Anbieter" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:40 +msgid "Third-party data providers" +msgstr "Externe Daten Anbieter" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:55 +msgid "Image providers" +msgstr "Bildanbieter" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:68 +msgid "Metadata providers" +msgstr "Metadaten Anbieter" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:137 +msgid "Open website" +msgstr "Öffne Webseite" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:36 +msgid "About" +msgstr "Über" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:71 +msgid "Copy application version and environment info" +msgstr "Anwendungsversion und Umgebungsinformationen kopieren" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:78 +#: src/ui/views/WelcomeView.vala:57 +msgid "All your games in one place" +msgstr "Alle Ihre Spiele an einem Ort" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:92 +msgctxt "about_link" +msgid "Website" +msgstr "Website" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:96 +msgctxt "about_link" +msgid "Source code on GitHub" +msgstr "Quellcode auf GitHub" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:103 +msgctxt "about_link" +msgid "Report a problem" +msgstr "Ein Problem melden" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:104 +msgctxt "about_link" +msgid "Suggest translations" +msgstr "Übersetzungen vorschlagen" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:110 +msgctxt "about_link" +msgid "Issues" +msgstr "Probleme" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:111 +msgctxt "about_link" +msgid "Contributors" +msgstr "Mitwirkende" + +#. TRANSLATORS: Likely it should not be translated. GitHub Pulse is a page that shows recent repository activity: https://github.com/tkashkin/GameHub/pulse +#: src/ui/dialogs/SettingsDialog/pages/About.vala:114 +msgctxt "about_link" +msgid "Pulse" +msgstr "Pulse" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:115 +msgctxt "about_link" +msgid "Forks" +msgstr "Forks" + +#: src/ui/dialogs/InstallDialog.vala:109 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:129 +msgid "Import" +msgstr "Importieren" + +#: src/ui/dialogs/InstallDialog.vala:110 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:153 +msgid "Download" +msgstr "Herunterladen" + +#: src/ui/dialogs/InstallDialog.vala:207 +msgid "Select installer" +msgstr "Installationsprogramm auswählen" + +#: src/ui/dialogs/InstallDialog.vala:216 +#, c-format +msgid "Installer size: %s" +msgstr "Größe des Installers: %s" + +#: src/ui/dialogs/InstallDialog.vala:348 +msgid "Unknown" +msgstr "Unbekannt" + +#: src/ui/dialogs/GamePropertiesDialog.vala:49 +#, c-format +msgid "%s: Properties" +msgstr "%s: Eigenschaften" + +#: src/ui/dialogs/GamePropertiesDialog.vala:84 +msgid "Images" +msgstr "Bilder" + +#: src/ui/dialogs/GamePropertiesDialog.vala:126 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:160 +#: src/ui/views/GameDetailsView/blocks/Artwork.vala:62 +msgid "Download images" +msgstr "Bilder herunterladen" + +#: src/ui/dialogs/GamePropertiesDialog.vala:144 +msgid "Image URL" +msgstr "Bild-URL" + +#: src/ui/dialogs/GamePropertiesDialog.vala:148 +msgid "Vertical image URL" +msgstr "Vertikale Bild URL" + +#: src/ui/dialogs/GamePropertiesDialog.vala:157 +msgid "Icon URL" +msgstr "Symbol-URL" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Select working directory" +msgstr "Wähle Arbeitsverzeichnis" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Working directory" +msgstr "Verzeichnis öffnen" + +#: src/ui/dialogs/GamePropertiesDialog.vala:214 +msgid "Compatibility" +msgstr "Kompatibilität" + +#: src/ui/dialogs/GamePropertiesDialog.vala:236 +msgid "Launch from terminal" +msgstr "Vom Terminal starten" + +#: src/ui/dialogs/GamePropertiesDialog.vala:252 +msgid "Copy to clipboard" +msgstr "In die Zwischenablage kopieren" + +#: src/ui/dialogs/GamePropertiesDialog.vala:254 +msgid "Add to Steam" +msgstr "Zu Steam hinzufügen" + +#: src/ui/dialogs/GamePropertiesDialog.vala:255 +msgid "Add to the Steam library" +msgstr "Zur Steam-Bibliothek hinzufügen" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:53 +#, c-format +msgid "%s: Overlays" +msgstr "%s: Overlays" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "Overlays are disabled" +msgstr "Overlays sind deaktiviert" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "" +"Enable overlays to manage DLCs and mods\n" +"\n" +"Enabling will move game to the “base“ overlay" +msgstr "" +"Aktivieren von Overlays zur Verwaltung von DLCs und Mods\n" +"\n" +"Durch das Aktivieren wird das Spiel auf das „base“-Overlay verschoben" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:77 +#: src/ui/views/GamesView/GameContextMenu.vala:175 +msgid "Overlays" +msgstr "Overlays" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:105 +msgid "Overlay ID (directory name)" +msgstr "Overlay-ID (Verzeichnisname)" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:110 +msgid "Overlay name (optional)" +msgstr "Overlay-Name (optional)" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:112 +msgid "Add" +msgstr "Hinzufügen" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:127 +msgid "Enable overlays" +msgstr "Overlays aktivieren" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:182 +#, c-format +msgid "" +"Overlay usage at this path may be unsafe\n" +"Proceed at your own risk\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:187 +#, c-format +msgid "" +"Overlay usage at this path is not supported\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:266 +msgid "Open directory" +msgstr "Verzeichnis öffnen" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:271 +#, fuzzy +msgid "Remove overlay" +msgstr "Overlays aktivieren" + +#: src/ui/dialogs/CompatRunDialog.vala:48 +#: src/ui/views/GamesView/GameContextMenu.vala:46 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:235 +msgid "Run with compatibility layer" +msgstr "Mit Kompatibilitätsschicht ausführen" + +#: src/ui/dialogs/CorruptedInstallerDialog.vala:71 +msgid "Corrupted installer: checksum mismatch in" +msgstr "Fehlerhafter Installer: Prüfsummenfehler in" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:57 +#: src/ui/views/GamesView/AddGamePopover.vala:105 +#, fuzzy +msgid "Import emulated games" +msgstr "Keine vom Benutzer hinzugefügten Spiele" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:75 +#, fuzzy +msgid "Select directory with emulated games" +msgstr "Ordner auswählen" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:83 +#, fuzzy +msgid "Detected games" +msgstr "Keine vom Benutzer hinzugefügten Spiele" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:107 +#, fuzzy +msgid "Select all" +msgstr "Installationsprogramm auswählen" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:115 +#, fuzzy +msgid "Select directory to import" +msgstr "Ordner auswählen" + +#: src/ui/dialogs/GameTweaksDialog.vala:40 +#, fuzzy, c-format +msgid "%s: Tweaks" +msgstr "%s: Overlays" + +#: src/ui/views/WelcomeView.vala:52 +msgid "No enabled game sources" +msgstr "Keine aktivierten Spielquellen" + +#: src/ui/views/WelcomeView.vala:52 +msgid "Enable some game sources in settings" +msgstr "Einige Spielquellen in den Einstellungen aktivieren" + +#: src/ui/views/WelcomeView.vala:57 +msgid "Let's get started" +msgstr "Fangen wir an" + +#: src/ui/views/WelcomeView.vala:71 +msgid "Skip" +msgstr "Überspringen" + +#: src/ui/views/WelcomeView.vala:141 +msgid "Ready" +msgstr "Bereit" + +#: src/ui/views/WelcomeView.vala:147 +msgid "Authentication required" +msgstr "Authentifizierung erforderlich" + +#: src/ui/views/WelcomeView.vala:152 +msgid "Authenticating…" +msgstr "Authentifizierung …" + +#: src/ui/views/WelcomeView.vala:163 +#, c-format +msgid "Install %s" +msgstr "%s installieren" + +#: src/ui/views/WelcomeView.vala:164 +msgid "Return to GameHub after installing" +msgstr "Zurück zu GameHub nach der Installation" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "No games" +msgstr "Keine Spiele" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "Get some games or enable some game sources in settings" +msgstr "" +"Holen Sie sich einige Spiele oder aktivieren Sie einige Spielquellen in den " +"Einstellungen" + +#: src/ui/views/GamesView/GamesView.vala:150 +msgid "Grid view" +msgstr "Rasteransicht" + +#: src/ui/views/GamesView/GamesView.vala:151 +msgid "List view" +msgstr "Listenansicht" + +#: src/ui/views/GamesView/GamesView.vala:159 +msgid "All games" +msgstr "Alle Spiele" + +#: src/ui/views/GamesView/GamesView.vala:182 +msgid "Downloads" +msgstr "Downloads" + +#: src/ui/views/GamesView/GamesView.vala:208 +msgid "Filters" +msgstr "Filter" + +#: src/ui/views/GamesView/GamesView.vala:216 +#: src/ui/views/GamesView/AddGamePopover.vala:84 +msgid "Add game" +msgstr "Spiel hinzufügen" + +#: src/ui/views/GamesView/GamesView.vala:223 +msgid "Search" +msgstr "Suche" + +#: src/ui/views/GamesView/GamesView.vala:328 +msgid "Menu" +msgstr "Menü" + +#: src/ui/views/GamesView/GamesView.vala:329 +#: src/ui/views/GameDetailsView/GameDetailsView.vala:104 +msgid "Back" +msgstr "Zurück" + +#: src/ui/views/GamesView/GamesView.vala:550 +#, c-format +msgid "%u game" +msgid_plural "%u games" +msgstr[0] "%u Spiel" +msgstr[1] "%u Spiele" + +#: src/ui/views/GamesView/GamesView.vala:553 +#, c-format +msgctxt "games_view_subtitle_filtered_games" +msgid "%1$u / %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:557 +#, c-format +msgctxt "games_view_subtitle" +msgid "%1$s: %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:568 +msgid "No user-added games" +msgstr "Keine vom Benutzer hinzugefügten Spiele" + +#: src/ui/views/GamesView/GamesView.vala:569 +msgid "Add some games using plus button" +msgstr "Einige Spiele mit der Plus-Taste hinzufügen" + +#: src/ui/views/GamesView/GamesView.vala:573 +#, c-format +msgid "No %s games" +msgstr "Keine %s Spiele" + +#: src/ui/views/GamesView/GamesView.vala:574 +msgid "Get some Linux-compatible games" +msgstr "Holen Sie sich einige Linux-kompatible Spiele" + +#: src/ui/views/GamesView/GamesView.vala:584 +#, c-format +msgid "No games matching “%s”" +msgstr "Keine Spiele entsprechen „%s“" + +#: src/ui/views/GamesView/GamesView.vala:589 +#, c-format +msgid "No %1$s games matching “%2$s”" +msgstr "Keine %1$s Spiele entsprechen „%2$s“" + +#: src/ui/views/GamesView/GamesView.vala:627 +msgid "" +"No games were loaded from Steam. Set your games list privacy to public or " +"use your own Steam API key in settings." +msgstr "" +"Es wurden keine Spiele von Steam geladen. Stellen Sie Ihre Spieleliste auf " +"öffentlich oder verwenden Sie Ihren eigenen Steam-API-Schlüssel." + +#: src/ui/views/GamesView/GamesView.vala:628 +msgid "Privacy" +msgstr "Datenschutz" + +#: src/ui/views/GamesView/GamesView.vala:739 +#, fuzzy +msgid "Downloading images" +msgstr "Herunterladen" + +#: src/ui/views/GamesView/GamesView.vala:753 +#, fuzzy, c-format +msgid "Downloading image: %s" +msgstr "Herunterladen" + +#: src/ui/views/GamesView/DownloadProgressView.vala:131 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:162 +msgid "Pause download" +msgstr "Download anhalten" + +#: src/ui/views/GamesView/DownloadProgressView.vala:137 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:168 +msgid "Resume download" +msgstr "Download fortsetzen" + +#: src/ui/views/GamesView/DownloadProgressView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:174 +msgid "Cancel download" +msgstr "Download abbrechen" + +#: src/ui/views/GamesView/FiltersPopover.vala:77 +msgid "Group" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:102 +msgid "Sort" +msgstr "Sortieren" + +#: src/ui/views/GamesView/FiltersPopover.vala:234 +#: src/ui/widgets/GameTagsList.vala:58 +msgid "Tags" +msgstr "Tags" + +#: src/ui/views/GamesView/FiltersPopover.vala:353 +#, fuzzy +msgid "All platforms" +msgstr "Plattform" + +#: src/ui/views/GamesView/AddGamePopover.vala:77 +msgid "Select game executable" +msgstr "Ausführbare Spieldatei auswählen" + +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Select game directory" +msgstr "Spielverzeichnis auswählen" + +#: src/ui/views/GamesView/AddGamePopover.vala:111 +#, fuzzy +msgid "Download game images" +msgstr "Herunterladen" + +#: src/ui/views/GamesView/GameContextMenu.vala:87 +msgid "Details" +msgstr "Details" + +#: src/ui/views/GamesView/GameContextMenu.vala:117 +msgctxt "game_context_menu" +msgid "Favorite" +msgstr "Favorit" + +#: src/ui/views/GamesView/GameContextMenu.vala:121 +msgctxt "game_context_menu" +msgid "Hidden" +msgstr "Versteckt" + +#: src/ui/views/GamesView/GameContextMenu.vala:133 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:236 +msgid "Open installation directory" +msgstr "Installationsverzeichnis öffnen" + +#: src/ui/views/GamesView/GameContextMenu.vala:142 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:237 +msgid "Open installers collection directory" +msgstr "Sammelverzeichnis des Installers öffnen" + +#: src/ui/views/GamesView/GameContextMenu.vala:151 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:238 +msgid "Open bonus collection directory" +msgstr "Bonus-Sammelverzeichnis öffnen" + +#: src/ui/views/GamesView/GameContextMenu.vala:160 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:239 +#, fuzzy +msgid "Open screenshots directory" +msgstr "Präfixverzeichnis öffnen" + +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +msgid "Uninstall" +msgstr "Deinstallieren" + +#: src/ui/views/GamesView/GameContextMenu.vala:192 +msgid "Properties" +msgstr "Eigenschaften" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:100 +#, fuzzy, c-format +msgid "%d game selected" +msgid_plural "%d games selected" +msgstr[0] "%s: keine Installationsprogramme verfügbare" +msgstr[1] "%s: keine Installationsprogramme verfügbare" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:144 +#, fuzzy, c-format +msgid "%d game will be installed" +msgid_plural "%d games will be installed" +msgstr[0] "%s: keine Installationsprogramme verfügbare" +msgstr[1] "%s: keine Installationsprogramme verfügbare" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:154 +#, fuzzy, c-format +msgid "%d game will be downloaded" +msgid_plural "%d games will be downloaded" +msgstr[0] "%s: keine Installationsprogramme verfügbare" +msgstr[1] "%s: keine Installationsprogramme verfügbare" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:161 +#, fuzzy, c-format +msgid "Image for %d game will be searched" +msgid_plural "Images for %d games will be searched" +msgstr[0] "%s: keine Installationsprogramme verfügbare" +msgstr[1] "%s: keine Installationsprogramme verfügbare" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:168 +#, fuzzy, c-format +msgid "%d game will be uninstalled" +msgid_plural "%d games will be uninstalled" +msgstr[0] "%s: keine Installationsprogramme verfügbare" +msgstr[1] "%s: keine Installationsprogramme verfügbare" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:174 +msgid "Refresh" +msgstr "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:175 +#, c-format +msgid "" +"%d game will be removed from database. Restart GameHub to fetch new data" +msgid_plural "" +"%d games will be removed from database. Restart GameHub to fetch new data" +msgstr[0] "" +"%d Spiel wird aus der Datenbank entfernt. Starten Sie GameHub neu, um neue " +"Daten abzurufen" +msgstr[1] "" +"%d Spiele werden aus der Datenbank entfernt. Starten Sie GameHub neu, um " +"neue Daten abzurufen" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:240 +msgid "Open store page" +msgstr "Shop-Seite öffnen" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:242 +msgid "Game properties" +msgstr "Spieleigenschaften" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:46 +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:60 +msgid "Playtime" +msgstr "Spielzeit" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:52 +msgid "Playtime (local)" +msgstr "Spielzeit (lokal)" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:69 +msgid "Last launch" +msgstr "Letzter Start" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:46 +msgid "Achievements" +msgstr "Erfolge" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:85 +#, c-format +msgid "Unlocked: %s" +msgstr "Freigeschaltet: %s" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:90 +#, c-format +msgid "Global percentage: %g%%" +msgstr "Globaler Prozentsatz: %g %%" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:77 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:103 +msgid "Language" +msgstr "Sprache" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:80 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:106 +msgid "Languages" +msgstr "Sprachen" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:147 +#, fuzzy, c-format +msgid "%u DLCs cannot be installed" +msgstr "%s: fehlerhafter Installer" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:71 +msgid "Category" +msgstr "Kategorie" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:74 +msgid "Categories" +msgstr "Kategorien" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:90 +msgid "Genre" +msgstr "Genre" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:93 +msgid "Genres" +msgstr "Genres" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:109 +msgctxt "igdb" +msgid "Popularity" +msgstr "Popularität" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:115 +msgctxt "igdb" +msgid "Aggregated rating" +msgstr "Gesamtbewertung" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:116 +#, fuzzy +msgctxt "igdb" +msgid "IGDB user rating" +msgstr "IGDB Benutzerbewertung" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:117 +#, fuzzy +msgctxt "igdb" +msgid "Total rating" +msgstr "Gesamtbewertung" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:126 +#, fuzzy +msgctxt "igdb" +msgid "Release date" +msgstr "Veröffentlichungsdatum" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:133 +#, fuzzy +msgctxt "igdb" +msgid "Platforms" +msgstr "Plattform" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:139 +#, fuzzy +msgctxt "igdb" +msgid "Genres" +msgstr "Genres" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:145 +#, fuzzy +msgctxt "igdb" +msgid "Keywords" +msgstr "Stichwörter" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:152 +msgctxt "igdb" +msgid "Links" +msgstr "Links" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:208 +#, c-format +msgid "Based on %d rating" +msgid_plural "Based on %d ratings" +msgstr[0] "Basierend auf %d Bewertung" +msgstr[1] "Basierend auf %d Bewertungen" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:290 +msgctxt "igdb" +msgid "Summary" +msgstr "Zusammenfassung" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:301 +msgctxt "igdb" +msgid "Storyline" +msgstr "Handlung" + +#: src/ui/widgets/FileChooserEntry.vala:49 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select file" +msgstr "Datei auswählen" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +#, fuzzy +msgid "No images" +msgstr "Bilder" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +#, fuzzy +msgid "" +"There are no images found for this game\n" +"Make sure game name is correct" +msgstr "" +"Es wurden keine Bilder für dieses Spiel gefunden.\n" +"Stellen Sie sicher, dass der Spielname korrekt ist" + +#: src/ui/widgets/ImagesDownloadPopover.vala:94 +msgid "Search images:" +msgstr "Bilder suchen:" + +#: src/ui/widgets/CompatToolPicker.vala:53 +msgid "Compatibility layer:" +msgstr "Kompatibilitätsschicht:" + +#: src/ui/widgets/CompatToolPicker.vala:92 +msgid "Configure" +msgstr "Konfigurieren" + +#: src/ui/widgets/GameTagsList.vala:109 +msgid "Add tag" +msgstr "Tag hinzufügen" + +#: src/ui/widgets/TweaksList.vala:86 +#, fuzzy +msgid "No description" +msgstr "Beschreibung" + +#: src/ui/widgets/TweaksList.vala:124 +#, fuzzy +msgid "Edit file" +msgstr "Datei auswählen" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dh" +msgstr "%d h" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dm" +msgstr "%d m" + +#: src/utils/Utils.vala:464 +#, fuzzy, c-format +msgctxt "time" +msgid "%ds" +msgstr "%d h" + +#: src/settings/UI.vala:153 +msgctxt "grid_size_preset" +msgid "Steam" +msgstr "Steam" + +#: src/settings/UI.vala:154 +msgctxt "grid_size_preset" +msgid "Steam (vertical)" +msgstr "Steam (Vertikal)" + +#: src/settings/UI.vala:155 +msgctxt "grid_size_preset" +msgid "GOG" +msgstr "GOG" + +#: src/settings/UI.vala:156 +msgctxt "grid_size_preset" +msgid "GOG (vertical)" +msgstr "GOG (Vertikal)" + +#: src/settings/UI.vala:157 +msgctxt "grid_size_preset" +msgid "Square" +msgstr "" + +#: src/settings/UI.vala:158 +#, fuzzy +msgctxt "grid_size_preset" +msgid "Custom" +msgstr "Benutzerdefiniert" + +#: src/utils/downloader/Downloader.vala:200 +msgctxt "dl_status" +msgid "Queued" +msgstr "In der Warteschlange" + +#: src/utils/downloader/Downloader.vala:201 +msgctxt "dl_status" +msgid "Starting download" +msgstr "Download wird gestartet" + +#: src/utils/downloader/Downloader.vala:202 +msgctxt "dl_status" +msgid "Download started" +msgstr "Download gestartet" + +#: src/utils/downloader/Downloader.vala:203 +msgctxt "dl_status" +msgid "Download finished" +msgstr "Download abgeschlossen" + +#: src/utils/downloader/Downloader.vala:204 +msgctxt "dl_status" +msgid "Download failed" +msgstr "Download fehlgeschlagen" + +#: src/utils/downloader/Downloader.vala:208 +#, fuzzy, c-format +msgctxt "dl_status" +msgid "Downloading: %s" +msgstr "Herunterladen" + +#: src/utils/downloader/Downloader.vala:210 +#, fuzzy +msgctxt "dl_status" +msgid "Downloading" +msgstr "Herunterladen" + +#: src/utils/downloader/Downloader.vala:214 +#, fuzzy, c-format +msgctxt "dl_status" +msgid "Paused: %s" +msgstr "Angehalten: %d %% (%s / %s)" + +#: src/utils/downloader/Downloader.vala:216 +#, fuzzy +msgctxt "dl_status" +msgid "Paused" +msgstr "Download anhalten" + +#: src/utils/downloader/Downloader.vala:218 +msgctxt "dl_status" +msgid "Download cancelled" +msgstr "Download abgebrochen" + +#. TRANSLATORS: Download progress template. %1$d - percentage, %2$s / %3$s - downloaded portion and total file size, %4$s - download speed +#: src/utils/downloader/Downloader.vala:262 +#, fuzzy, c-format +msgctxt "dl_status" +msgid "%1$d%% (%2$s / %3$s) [%4$s/s]" +msgstr "Herunterladen: %d %% (%s / %s) [%s/s]" + +#~ msgid "Disable esync" +#~ msgstr "esync deaktivieren" + +#~ msgid "Force LARGE_ADDRESS_AWARE flag" +#~ msgstr "LARGE_ADDRESS_AWARE-Flag erzwingen" + +#~ msgid "Disable DirectX 11 compatibility layer" +#~ msgstr "DirectX11-Kompatibilitätsschicht deaktivieren" + +#~ msgid "Use WineD3D11 as DirectX 11 compatibility layer" +#~ msgstr "WineD3D11 als Kompatibilitätsschicht für DirectX 11 verwenden" + +#~ msgid "Show DXVK info overlay" +#~ msgstr "DXVK-Info-Overlay anzeigen" + +#, fuzzy +#~ msgid "Enable DirectX 9 compatibility layer" +#~ msgstr "DirectX11-Kompatibilitätsschicht deaktivieren" + +#~ msgid "Silent installation" +#~ msgstr "Stille Installation" + +#~ msgid "Very silent installation" +#~ msgstr "Sehr stille Installation" + +#~ msgid "Suppress messages" +#~ msgstr "Nachrichten unterdrücken" + +#~ msgid "No GUI" +#~ msgstr "Kein GUI" + +#~ msgid "Disable fullscreen" +#~ msgstr "Vollbild deaktivieren" + +#~ msgid "Windowed" +#~ msgstr "Fenstermodus" + +#~ msgid "Compact list" +#~ msgstr "Kompakte Liste" + +#~ msgid "Show non-native games" +#~ msgstr "Nicht native Spiele anzeigen" + +#~ msgid "Use compatibility layers and consider Windows games compatible" +#~ msgstr "" +#~ "Kompatibilitätsebenen verwenden und Windows-Spiele als kompatibel ansehen" + +#~ msgid "About GameHub" +#~ msgstr "Über GameHub" + +#~ msgid "Use symbolic icons instead of colored icons" +#~ msgstr "Sinnbildliche Symbole anstelle von farbigen Symbolen verwenden" + +#~ msgid "Enable controller support" +#~ msgstr "Unterstützung der Steuerung aktivieren" + +#~ msgid "Reload" +#~ msgstr "Neu laden" + +#~ msgid "Updating game info" +#~ msgstr "Aktualisieren von Spielinformationen" + +#~ msgid "Updating %s game info" +#~ msgstr "Aktualisierung von %s Spielinformationen" + +#~ msgid "Merging %s (%s)" +#~ msgstr "Zusammenführen von %s und (%s)" diff --git a/po/el.po b/po/el.po new file mode 100644 index 00000000..8f90c2da --- /dev/null +++ b/po/el.po @@ -0,0 +1,1797 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the com.github.tkashkin.gamehub package. +# THANOS SIOURDAKIS , 2019. +msgid "" +msgstr "" +"Project-Id-Version: com.github.tkashkin.gamehub\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-26 06:40+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#: src/app.vala:91 +msgid "Show help" +msgstr "" + +#: src/app.vala:92 +msgid "Show application version and exit" +msgstr "" + +#: src/app.vala:93 +msgid "Restart with GDB debugger attached" +msgstr "" + +#: src/app.vala:94 +msgid "Show full GDB backtrace" +msgstr "" + +#: src/app.vala:95 +msgid "Treat fatal errors as criticals and crash application" +msgstr "" + +#: src/app.vala:99 +msgid "Show main window" +msgstr "" + +#: src/app.vala:100 +msgid "Show application settings dialog" +msgstr "" + +#: src/app.vala:101 +msgid "Show about dialog" +msgstr "" + +#: src/app.vala:102 +msgid "Maximum number of background worker threads" +msgstr "" + +#: src/app.vala:106 +msgid "Run game" +msgstr "" + +#: src/app.vala:107 +msgid "Show compatibility options dialog" +msgstr "" + +#: src/app.vala:108 +msgid "Open game details" +msgstr "" + +#: src/app.vala:109 +msgid "Open game properties" +msgstr "" + +#: src/app.vala:113 +msgid "Enable debug logging" +msgstr "" + +#: src/app.vala:114 +msgid "" +"Log authentication process and sensitive information like authentication " +"tokens" +msgstr "" + +#: src/app.vala:115 +msgid "Log download manager" +msgstr "" + +#: src/app.vala:116 +msgid "Log background workers start/stop" +msgstr "" + +#: src/app.vala:117 +msgid "Disable log messages filtering" +msgstr "" + +#: src/app.vala:118 +msgid "Verbose logging" +msgstr "" + +#: src/app.vala:247 +msgid "Game Options:" +msgstr "" + +#: src/app.vala:247 +msgid "Show game options help" +msgstr "" + +#: src/app.vala:255 +msgid "Logging Options:" +msgstr "" + +#: src/app.vala:255 +msgid "Show logging options help" +msgstr "" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +msgid "Select executable" +msgstr "" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:181 src/ui/views/GamesView/GamesView.vala:330 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select" +msgstr "" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:180 src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Cancel" +msgstr "" + +#: src/data/Runnable.vala:166 src/ui/widgets/FileChooserEntry.vala:49 +msgid "Select directory" +msgstr "" + +#: src/data/Runnable.vala:619 +#, c-format +msgid "Part %1$u of %2$u: %3$s" +msgstr "" + +#: src/data/Runnable.vala:642 src/ui/dialogs/CorruptedInstallerDialog.vala:48 +#, c-format +msgid "%s: corrupted installer" +msgstr "" + +#: src/data/Runnable.vala:643 +#, c-format +msgid "Checksum mismatch in %s" +msgstr "" + +#: src/data/Runnable.vala:657 src/ui/dialogs/CorruptedInstallerDialog.vala:126 +msgid "Show file" +msgstr "" + +#: src/data/Runnable.vala:658 src/ui/dialogs/CorruptedInstallerDialog.vala:132 +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#: src/ui/widgets/TagRow.vala:146 +msgid "Remove" +msgstr "" + +#: src/data/Runnable.vala:659 src/ui/dialogs/CorruptedInstallerDialog.vala:128 +msgid "Backup" +msgstr "" + +#: src/data/Runnable.vala:778 +#, c-format +msgid "%s: cannot detect main executable" +msgstr "" + +#: src/data/Runnable.vala:779 +msgid "" +"Main executable file for this game cannot be detected automatically.\n" +"Please set main executable in game's properties." +msgstr "" + +#: src/data/Runnable.vala:908 +msgctxt "platform" +msgid "Emulated" +msgstr "" + +#: src/data/Game.vala:625 +msgctxt "status" +msgid "Running" +msgstr "" + +#: src/data/Game.vala:628 +msgctxt "status" +msgid "Installed" +msgstr "" + +#: src/data/Game.vala:629 +msgctxt "status" +msgid "Installing" +msgstr "" + +#: src/data/Game.vala:630 +msgctxt "status" +msgid "Verifying installer integrity" +msgstr "" + +#: src/data/Game.vala:631 +msgctxt "status" +msgid "Download started" +msgstr "" + +#: src/data/Game.vala:633 +msgctxt "status" +msgid "Not installed" +msgstr "" + +#: src/data/Game.vala:643 +msgctxt "status_header" +msgid "Installed" +msgstr "" + +#: src/data/Game.vala:644 +msgctxt "status_header" +msgid "Installing" +msgstr "" + +#: src/data/Game.vala:646 +msgctxt "status_header" +msgid "Downloading" +msgstr "" + +#: src/data/Game.vala:648 +msgctxt "status_header" +msgid "Not installed" +msgstr "" + +#: src/data/GameSource.vala:31 +#, c-format +msgid "%s games" +msgstr "" + +#: src/data/sources/steam/Steam.vala:43 +msgid "Your SteamID will be read from Steam configuration file" +msgstr "" + +#: src/data/sources/steam/Steam.vala:46 +msgid "" +"Steam config file not found.\n" +"Login into your account in Steam client and return to GameHub" +msgstr "" + +#: src/data/sources/gog/GOGGame.vala:983 +#, c-format +msgid "DLC: %s" +msgstr "" + +#: src/data/sources/humble/HumbleGame.vala:343 +#, c-format +msgid "%s: no available installers" +msgstr "" + +#: src/data/sources/humble/HumbleGame.vala:344 +msgid "" +"Cannot get Trove download URL.\n" +"Make sure your Humble Monthly subscription is active." +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:192 +#, c-format +msgctxt "itch_dl_status" +msgid "%s left;" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:195 +#, c-format +msgctxt "itch_dl_status" +msgid "%d%%" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:198 +#, c-format +msgctxt "itch_dl_status" +msgid "(%1$s / %2$s)" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:201 +#, c-format +msgctxt "itch_dl_status" +msgid "[%s/s]" +msgstr "" + +#: src/data/sources/user/User.vala:30 +msgid "User games" +msgstr "" + +#: src/data/db/tables/Tags.vala:225 +msgctxt "tag" +msgid "Favorites" +msgstr "" + +#: src/data/db/tables/Tags.vala:226 +msgctxt "tag" +msgid "Not installed" +msgstr "" + +#: src/data/db/tables/Tags.vala:227 +msgctxt "tag" +msgid "Installed" +msgstr "" + +#: src/data/db/tables/Tags.vala:228 +msgctxt "tag" +msgid "Hidden" +msgstr "" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit script" +msgstr "" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit custom script" +msgstr "" + +#: src/data/compat/Innoextract.vala:55 +#, c-format +msgid "" +"Innoextract %1$s is not supported and may not be able to extract some " +"games correctly.\n" +"Install innoextract %2$s or newer." +msgstr "" + +#: src/data/compat/WineWrap.vala:61 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:242 +#: src/ui/dialogs/CompatRunDialog.vala:102 +#: src/ui/views/GamesView/GameContextMenu.vala:53 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:234 +msgid "Run" +msgstr "" + +#: src/data/compat/WineWrap.vala:64 +msgid "Show WineWrap menu" +msgstr "" + +#: src/data/compat/WineWrap.vala:67 src/data/compat/Proton.vala:122 +#: src/data/compat/Wine.vala:83 +msgid "Kill apps in prefix" +msgstr "" + +#: src/data/compat/Proton.vala:47 +msgid "Proton prefix" +msgstr "" + +#: src/data/compat/Proton.vala:110 src/data/compat/Wine.vala:71 +msgid "Open prefix directory" +msgstr "" + +#: src/data/compat/Proton.vala:113 src/data/compat/Wine.vala:74 +msgid "Run winecfg" +msgstr "" + +#: src/data/compat/Proton.vala:116 src/data/compat/Wine.vala:77 +msgid "Run winetricks" +msgstr "" + +#: src/data/compat/Proton.vala:119 src/data/compat/Wine.vala:80 +msgid "Run taskmgr" +msgstr "" + +#: src/data/compat/Wine.vala:53 +msgid "Wine prefix" +msgstr "" + +#: src/data/compat/Wine.vala:55 +msgid "Environment variables" +msgstr "" + +#: src/data/compat/Wine.vala:60 +msgid "InnoSetup default options" +msgstr "" + +#: src/data/compat/RetroArch.vala:53 +msgid "Libretro core file" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:43 +msgid "Custom emulator" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:48 +msgid "Emulator" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:49 +msgid "Launch in game directory" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:440 +msgctxt "status_header" +msgid "Favorites" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:445 +#, c-format +msgctxt "status_header" +msgid "%s: Favorites" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:491 +msgid "Merging games" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:504 +#, c-format +msgid "Merging games from %s" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:551 +#, c-format +msgid "Loading games from %s" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:678 +msgctxt "sort_mode" +msgid "By name" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:679 +msgctxt "sort_mode" +msgid "By last launch" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:680 +msgctxt "sort_mode" +msgid "By playtime" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:705 +msgctxt "group_mode" +msgid "Do not group" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:706 +msgctxt "group_mode" +msgid "By status" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:707 +msgctxt "group_mode" +msgid "By source" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:151 +#: src/data/providers/data/IGDB.vala:431 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:217 +msgid "Default" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:158 +#: src/data/providers/data/IGDB.vala:438 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:225 +msgid "Restore default API key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:169 +#: src/data/providers/data/IGDB.vala:449 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:108 +msgid "API key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:177 +#: src/data/providers/data/IGDB.vala:457 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:53 +msgid "Generate key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:208 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Style" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:209 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Score" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:213 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Author" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:225 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Alternate" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:226 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Blurred" +msgstr "" + +#. TRANSLATORS: Flat / Material Design image style. Probably should not be translated +#: src/data/providers/images/SteamGridDB.vala:228 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Material" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:229 +msgctxt "imagesource_steamgriddb_image_style" +msgid "No logo" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:230 +msgctxt "imagesource_steamgriddb_image_style" +msgid "White logo" +msgstr "" + +#: src/data/providers/data/IGDB.vala:147 +msgid "" +"Monthly IGDB request quota has been reached. Set your own API key to use " +"IGDB data or disable IGDB." +msgstr "" + +#: src/data/providers/data/IGDB.vala:148 +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:40 +#: src/ui/views/WelcomeView.vala:53 src/ui/views/WelcomeView.vala:78 +#: src/ui/views/GamesView/GamesView.vala:230 +#: src/ui/views/GamesView/GamesView.vala:629 +msgid "Settings" +msgstr "" + +#: src/data/providers/data/IGDB.vala:356 +msgctxt "igdb_related_link" +msgid "Official website" +msgstr "" + +#: src/data/providers/data/IGDB.vala:469 +msgctxt "igdb_preferred_description" +msgid "When game has description, show description" +msgstr "" + +#: src/data/providers/data/IGDB.vala:476 +msgctxt "igdb_preferred_description" +msgid "of game" +msgstr "" + +#: src/data/providers/data/IGDB.vala:477 +msgctxt "igdb_preferred_description" +msgid "from IGDB" +msgstr "" + +#: src/data/providers/data/IGDB.vala:478 +msgctxt "igdb_preferred_description" +msgid "both" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:65 +msgid "Some settings will be applied after application restart" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:71 +msgid "Games directory contains space. It may cause problems for some games" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:36 +msgid "Interface" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:37 +msgid "Appearance" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:38 +msgid "General interface settings" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:48 +msgid "Dark theme" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:53 +msgctxt "icon_style" +msgid "Theme-based" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:54 +msgctxt "icon_style" +msgid "Symbolic" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:55 +msgctxt "icon_style" +msgid "Colored" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:57 +msgctxt "icon_style" +msgid "Icon style" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:84 +msgid "Game card" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:86 +msgid "Show platform icons" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:99 +msgctxt "grid_size" +msgid "Card size" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:117 +msgctxt "grid_size_preset" +msgid "Presets" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:139 +msgid "Games list: installed" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:140 +msgid "Games list: not installed" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:142 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:146 +msgctxt "list_style" +msgid "Show icon" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:143 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:147 +msgctxt "list_style" +msgid "Bold title" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:144 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:148 +msgctxt "list_style" +msgid "Show status" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:149 +msgctxt "list_style" +msgid "Dim" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:151 +msgid "Grid options" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:152 +msgid "List options" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:31 +msgid "Behavior" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:32 +msgid "Behavior settings" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:42 +msgid "Run games with double click" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:46 +msgid "Merge games from different sources" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:50 +msgid "Use imported tags" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:51 +msgid "General" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:52 +msgid "Collection" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:53 +msgid "Empty" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:65 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:85 +msgid "Collection directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:70 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:78 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:87 +msgid "Game directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:71 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:79 +msgid "Installers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:72 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:98 +msgid "DLC" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:73 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:197 +msgid "Bonus content" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:84 +msgid "Variable syntax: $var or ${var}" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:86 +msgid "Game name" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:88 +#: src/ui/views/GamesView/FiltersPopover.vala:127 +msgid "Platform" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:36 +msgid "Controller" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +msgid "Enabled" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:53 +msgid "Focus GameHub window with Guide button" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:57 +msgid "Controllers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:89 +msgid "Move focus" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:91 +msgid "Exit" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:40 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:108 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:92 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:95 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:36 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:77 +msgid "Disabled" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:47 +#: src/ui/dialogs/GameTweaksDialog.vala:53 +#: src/ui/views/GamesView/GameContextMenu.vala:183 +msgid "Tweaks" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:34 +msgid "Tweak launch options and apply them to games automatically" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:79 +msgid "" +"Tweaks are loaded from following directories in order\n" +"Last tweak overrides previous tweaks with same identifiers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:83 +msgid "Click to open" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:93 +#, c-format +msgid "Tweaks are loaded from %1$s and %2$d more directories (?)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:38 +msgid "Game sources" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +msgid "Steam API keys have limited number of uses per day" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:63 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:57 +msgid "Installation directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:176 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:81 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:34 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:75 +msgid "Not installed" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:116 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:96 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:99 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:85 +msgid "Not authenticated" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +#, c-format +msgid "Authenticated as %s" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:103 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +msgid "Authenticated" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:183 +#: src/ui/dialogs/InstallDialog.vala:53 src/ui/dialogs/InstallDialog.vala:111 +#: src/ui/views/GamesView/GameContextMenu.vala:80 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:233 +#: src/ui/widgets/TweaksList.vala:95 +msgid "Install" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:236 +msgid "Steam API key" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:50 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:54 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:48 +msgid "Games directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:63 +msgid "Logout" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:50 +msgid "Load games from Humble Trove" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:45 +msgid "Emulators" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:45 +msgid "Libretro core directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:46 +msgid "Libretro core info directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:50 +msgid "Ignored libretro cores" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:54 +msgid "Ignored game file extensions" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:66 +msgid "No cores found" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:70 +#, c-format +msgid "%u core found" +msgid_plural "%u cores found" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:46 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:168 +msgid "No custom emulators" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:164 +#, c-format +msgid "%u custom emulator" +msgid_plural "%u custom emulators" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:237 +msgid "Save" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:250 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:312 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/dialogs/GamePropertiesDialog.vala:168 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +#: src/ui/views/GamesView/AddGamePopover.vala:67 +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Executable" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:251 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/views/GamesView/AddGamePopover.vala:68 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Installer" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:256 +#: src/ui/dialogs/GamePropertiesDialog.vala:64 +#: src/ui/dialogs/GamePropertiesDialog.vala:69 +#: src/ui/views/GamesView/AddGamePopover.vala:73 +msgid "Name" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:272 +#: src/ui/dialogs/GamePropertiesDialog.vala:201 +#: src/ui/views/GamesView/AddGamePopover.vala:78 +msgid "Arguments" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:276 +msgid "Variables" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:277 +msgid "Game executable" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:278 +msgid "Game arguments" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:80 +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +msgid "Select emulator directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:292 +#: src/ui/dialogs/GamePropertiesDialog.vala:219 +msgid "Force compatibility mode" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:307 +msgid "Game file patterns" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:315 +msgid "Image" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:318 +msgid "Icon" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:325 +msgid "" +"findutils-compatible glob patterns\n" +"\n" +" Multiple patterns can be separated with |\n" +" Start pattern with ./ to match relative path\n" +" $basename variable will be replaced with game's executable " +"name (without extension)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:38 +msgid "Data" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:39 +msgid "Providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:40 +msgid "Third-party data providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:55 +msgid "Image providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:68 +msgid "Metadata providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:137 +msgid "Open website" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:36 +msgid "About" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:71 +msgid "Copy application version and environment info" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:78 +#: src/ui/views/WelcomeView.vala:57 +msgid "All your games in one place" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:92 +msgctxt "about_link" +msgid "Website" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:96 +msgctxt "about_link" +msgid "Source code on GitHub" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:103 +msgctxt "about_link" +msgid "Report a problem" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:104 +msgctxt "about_link" +msgid "Suggest translations" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:110 +msgctxt "about_link" +msgid "Issues" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:111 +msgctxt "about_link" +msgid "Contributors" +msgstr "" + +#. TRANSLATORS: Likely it should not be translated. GitHub Pulse is a page that shows recent repository activity: https://github.com/tkashkin/GameHub/pulse +#: src/ui/dialogs/SettingsDialog/pages/About.vala:114 +msgctxt "about_link" +msgid "Pulse" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:115 +msgctxt "about_link" +msgid "Forks" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:109 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:129 +msgid "Import" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:110 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:153 +msgid "Download" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:207 +msgid "Select installer" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:216 +#, c-format +msgid "Installer size: %s" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:348 +msgid "Unknown" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:49 +#, c-format +msgid "%s: Properties" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:84 +msgid "Images" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:126 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:160 +#: src/ui/views/GameDetailsView/blocks/Artwork.vala:62 +msgid "Download images" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:144 +msgid "Image URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:148 +msgid "Vertical image URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:157 +msgid "Icon URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Select working directory" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Working directory" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:214 +msgid "Compatibility" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:236 +msgid "Launch from terminal" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:252 +msgid "Copy to clipboard" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:254 +msgid "Add to Steam" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:255 +msgid "Add to the Steam library" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:53 +#, c-format +msgid "%s: Overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "Overlays are disabled" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "" +"Enable overlays to manage DLCs and mods\n" +"\n" +"Enabling will move game to the “base“ overlay" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:77 +#: src/ui/views/GamesView/GameContextMenu.vala:175 +msgid "Overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:105 +msgid "Overlay ID (directory name)" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:110 +msgid "Overlay name (optional)" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:112 +msgid "Add" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:127 +msgid "Enable overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:182 +#, c-format +msgid "" +"Overlay usage at this path may be unsafe\n" +"Proceed at your own risk\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:187 +#, c-format +msgid "" +"Overlay usage at this path is not supported\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:266 +msgid "Open directory" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:271 +msgid "Remove overlay" +msgstr "" + +#: src/ui/dialogs/CompatRunDialog.vala:48 +#: src/ui/views/GamesView/GameContextMenu.vala:46 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:235 +msgid "Run with compatibility layer" +msgstr "" + +#: src/ui/dialogs/CorruptedInstallerDialog.vala:71 +msgid "Corrupted installer: checksum mismatch in" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:57 +#: src/ui/views/GamesView/AddGamePopover.vala:105 +msgid "Import emulated games" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:75 +msgid "Select directory with emulated games" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:83 +msgid "Detected games" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:107 +msgid "Select all" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:115 +msgid "Select directory to import" +msgstr "" + +#: src/ui/dialogs/GameTweaksDialog.vala:40 +#, c-format +msgid "%s: Tweaks" +msgstr "" + +#: src/ui/views/WelcomeView.vala:52 +msgid "No enabled game sources" +msgstr "" + +#: src/ui/views/WelcomeView.vala:52 +msgid "Enable some game sources in settings" +msgstr "" + +#: src/ui/views/WelcomeView.vala:57 +msgid "Let's get started" +msgstr "" + +#: src/ui/views/WelcomeView.vala:71 +msgid "Skip" +msgstr "" + +#: src/ui/views/WelcomeView.vala:141 +msgid "Ready" +msgstr "" + +#: src/ui/views/WelcomeView.vala:147 +msgid "Authentication required" +msgstr "" + +#: src/ui/views/WelcomeView.vala:152 +msgid "Authenticating…" +msgstr "" + +#: src/ui/views/WelcomeView.vala:163 +#, c-format +msgid "Install %s" +msgstr "" + +#: src/ui/views/WelcomeView.vala:164 +msgid "Return to GameHub after installing" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "No games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "Get some games or enable some game sources in settings" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:150 +msgid "Grid view" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:151 +msgid "List view" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:159 +msgid "All games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:182 +msgid "Downloads" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:208 +msgid "Filters" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:216 +#: src/ui/views/GamesView/AddGamePopover.vala:84 +msgid "Add game" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:223 +msgid "Search" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:328 +msgid "Menu" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:329 +#: src/ui/views/GameDetailsView/GameDetailsView.vala:104 +msgid "Back" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:550 +#, c-format +msgid "%u game" +msgid_plural "%u games" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GamesView/GamesView.vala:553 +#, c-format +msgctxt "games_view_subtitle_filtered_games" +msgid "%1$u / %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:557 +#, c-format +msgctxt "games_view_subtitle" +msgid "%1$s: %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:568 +msgid "No user-added games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:569 +msgid "Add some games using plus button" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:573 +#, c-format +msgid "No %s games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:574 +msgid "Get some Linux-compatible games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:584 +#, c-format +msgid "No games matching “%s”" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:589 +#, c-format +msgid "No %1$s games matching “%2$s”" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:627 +msgid "" +"No games were loaded from Steam. Set your games list privacy to public or " +"use your own Steam API key in settings." +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:628 +msgid "Privacy" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:739 +msgid "Downloading images" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:753 +#, c-format +msgid "Downloading image: %s" +msgstr "" + +#: src/ui/views/GamesView/DownloadProgressView.vala:131 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:162 +msgid "Pause download" +msgstr "" + +#: src/ui/views/GamesView/DownloadProgressView.vala:137 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:168 +msgid "Resume download" +msgstr "" + +#: src/ui/views/GamesView/DownloadProgressView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:174 +msgid "Cancel download" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:77 +msgid "Group" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:102 +msgid "Sort" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:234 +#: src/ui/widgets/GameTagsList.vala:58 +msgid "Tags" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:353 +msgid "All platforms" +msgstr "" + +#: src/ui/views/GamesView/AddGamePopover.vala:77 +msgid "Select game executable" +msgstr "" + +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Select game directory" +msgstr "" + +#: src/ui/views/GamesView/AddGamePopover.vala:111 +msgid "Download game images" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:87 +msgid "Details" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:117 +msgctxt "game_context_menu" +msgid "Favorite" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:121 +msgctxt "game_context_menu" +msgid "Hidden" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:133 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:236 +msgid "Open installation directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:142 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:237 +msgid "Open installers collection directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:151 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:238 +msgid "Open bonus collection directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:160 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:239 +msgid "Open screenshots directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +msgid "Uninstall" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:192 +msgid "Properties" +msgstr "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:100 +#, c-format +msgid "%d game selected" +msgid_plural "%d games selected" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:144 +#, c-format +msgid "%d game will be installed" +msgid_plural "%d games will be installed" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:154 +#, c-format +msgid "%d game will be downloaded" +msgid_plural "%d games will be downloaded" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:161 +#, c-format +msgid "Image for %d game will be searched" +msgid_plural "Images for %d games will be searched" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:168 +#, c-format +msgid "%d game will be uninstalled" +msgid_plural "%d games will be uninstalled" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:174 +msgid "Refresh" +msgstr "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:175 +#, c-format +msgid "" +"%d game will be removed from database. Restart GameHub to fetch new data" +msgid_plural "" +"%d games will be removed from database. Restart GameHub to fetch new data" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:240 +msgid "Open store page" +msgstr "" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:242 +msgid "Game properties" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:46 +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:60 +msgid "Playtime" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:52 +msgid "Playtime (local)" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:69 +msgid "Last launch" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:46 +msgid "Achievements" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:85 +#, c-format +msgid "Unlocked: %s" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:90 +#, c-format +msgid "Global percentage: %g%%" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:77 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:103 +msgid "Language" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:80 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:106 +msgid "Languages" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:147 +#, c-format +msgid "%u DLCs cannot be installed" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:71 +msgid "Category" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:74 +msgid "Categories" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:90 +msgid "Genre" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:93 +msgid "Genres" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:109 +msgctxt "igdb" +msgid "Popularity" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:115 +msgctxt "igdb" +msgid "Aggregated rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:116 +msgctxt "igdb" +msgid "IGDB user rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:117 +msgctxt "igdb" +msgid "Total rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:126 +msgctxt "igdb" +msgid "Release date" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:133 +msgctxt "igdb" +msgid "Platforms" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:139 +msgctxt "igdb" +msgid "Genres" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:145 +msgctxt "igdb" +msgid "Keywords" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:152 +msgctxt "igdb" +msgid "Links" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:208 +#, c-format +msgid "Based on %d rating" +msgid_plural "Based on %d ratings" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:290 +msgctxt "igdb" +msgid "Summary" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:301 +msgctxt "igdb" +msgid "Storyline" +msgstr "" + +#: src/ui/widgets/FileChooserEntry.vala:49 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select file" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "No images" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "" +"There are no images found for this game\n" +"Make sure game name is correct" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:94 +msgid "Search images:" +msgstr "" + +#: src/ui/widgets/CompatToolPicker.vala:53 +msgid "Compatibility layer:" +msgstr "" + +#: src/ui/widgets/CompatToolPicker.vala:92 +msgid "Configure" +msgstr "" + +#: src/ui/widgets/GameTagsList.vala:109 +msgid "Add tag" +msgstr "" + +#: src/ui/widgets/TweaksList.vala:86 +msgid "No description" +msgstr "" + +#: src/ui/widgets/TweaksList.vala:124 +msgid "Edit file" +msgstr "" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dh" +msgstr "" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dm" +msgstr "" + +#: src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%ds" +msgstr "" + +#: src/settings/UI.vala:153 +msgctxt "grid_size_preset" +msgid "Steam" +msgstr "" + +#: src/settings/UI.vala:154 +msgctxt "grid_size_preset" +msgid "Steam (vertical)" +msgstr "" + +#: src/settings/UI.vala:155 +msgctxt "grid_size_preset" +msgid "GOG" +msgstr "" + +#: src/settings/UI.vala:156 +msgctxt "grid_size_preset" +msgid "GOG (vertical)" +msgstr "" + +#: src/settings/UI.vala:157 +msgctxt "grid_size_preset" +msgid "Square" +msgstr "" + +#: src/settings/UI.vala:158 +msgctxt "grid_size_preset" +msgid "Custom" +msgstr "" + +#: src/utils/downloader/Downloader.vala:200 +msgctxt "dl_status" +msgid "Queued" +msgstr "" + +#: src/utils/downloader/Downloader.vala:201 +msgctxt "dl_status" +msgid "Starting download" +msgstr "" + +#: src/utils/downloader/Downloader.vala:202 +msgctxt "dl_status" +msgid "Download started" +msgstr "" + +#: src/utils/downloader/Downloader.vala:203 +msgctxt "dl_status" +msgid "Download finished" +msgstr "" + +#: src/utils/downloader/Downloader.vala:204 +msgctxt "dl_status" +msgid "Download failed" +msgstr "" + +#: src/utils/downloader/Downloader.vala:208 +#, c-format +msgctxt "dl_status" +msgid "Downloading: %s" +msgstr "" + +#: src/utils/downloader/Downloader.vala:210 +msgctxt "dl_status" +msgid "Downloading" +msgstr "" + +#: src/utils/downloader/Downloader.vala:214 +#, c-format +msgctxt "dl_status" +msgid "Paused: %s" +msgstr "" + +#: src/utils/downloader/Downloader.vala:216 +msgctxt "dl_status" +msgid "Paused" +msgstr "" + +#: src/utils/downloader/Downloader.vala:218 +msgctxt "dl_status" +msgid "Download cancelled" +msgstr "" + +#. TRANSLATORS: Download progress template. %1$d - percentage, %2$s / %3$s - downloaded portion and total file size, %4$s - download speed +#: src/utils/downloader/Downloader.vala:262 +#, c-format +msgctxt "dl_status" +msgid "%1$d%% (%2$s / %3$s) [%4$s/s]" +msgstr "" diff --git a/po/es_MX.po b/po/es_MX.po new file mode 100644 index 00000000..67d4049a --- /dev/null +++ b/po/es_MX.po @@ -0,0 +1,1903 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the com.github.tkashkin.gamehub package. +# juliomorales98 , 2019. +# Anderson Guzman Abreu , 2020. +msgid "" +msgstr "" +"Project-Id-Version: com.github.tkashkin.gamehub\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-26 06:40+0300\n" +"PO-Revision-Date: 2020-02-24 05:27+0000\n" +"Last-Translator: Anderson Guzman Abreu \n" +"Language-Team: Spanish (Mexico) \n" +"Language: es_MX\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.0-dev\n" + +#: src/app.vala:91 +msgid "Show help" +msgstr "Mostrar ayuda" + +#: src/app.vala:92 +msgid "Show application version and exit" +msgstr "Mostrar versión de aplicación y salir" + +#: src/app.vala:93 +msgid "Restart with GDB debugger attached" +msgstr "Reiniciar con el debugger GDB incluido" + +#: src/app.vala:94 +msgid "Show full GDB backtrace" +msgstr "" + +#: src/app.vala:95 +msgid "Treat fatal errors as criticals and crash application" +msgstr "Tratar errores fatales como críticos y terminar aplicación" + +#: src/app.vala:99 +msgid "Show main window" +msgstr "Mostrar ventana principal" + +#: src/app.vala:100 +msgid "Show application settings dialog" +msgstr "Mostrar diálogo de configuración de la aplicación" + +#: src/app.vala:101 +msgid "Show about dialog" +msgstr "Mostrar diálogo \"Acerca de\"" + +#: src/app.vala:102 +msgid "Maximum number of background worker threads" +msgstr "Número máximo de hilos trabajando en segundo plano" + +#: src/app.vala:106 +msgid "Run game" +msgstr "Iniciar juego" + +#: src/app.vala:107 +msgid "Show compatibility options dialog" +msgstr "Mostrar diálogo de opciones de compatibilidad" + +#: src/app.vala:108 +msgid "Open game details" +msgstr "Abrir detalles del juego" + +#: src/app.vala:109 +msgid "Open game properties" +msgstr "Abrir propiedades del juego" + +#: src/app.vala:113 +msgid "Enable debug logging" +msgstr "Habilitar el registro de depuración" + +#: src/app.vala:114 +msgid "" +"Log authentication process and sensitive information like authentication " +"tokens" +msgstr "" + +#: src/app.vala:115 +msgid "Log download manager" +msgstr "" + +#: src/app.vala:116 +msgid "Log background workers start/stop" +msgstr "" + +#: src/app.vala:117 +msgid "Disable log messages filtering" +msgstr "Deshabilita el filtro de los mensajes del registro" + +#: src/app.vala:118 +msgid "Verbose logging" +msgstr "" + +#: src/app.vala:247 +msgid "Game Options:" +msgstr "Opciones del juego:" + +#: src/app.vala:247 +msgid "Show game options help" +msgstr "Mostrar ayuda de las opciones del juego" + +#: src/app.vala:255 +msgid "Logging Options:" +msgstr "Opciones del registro:" + +#: src/app.vala:255 +msgid "Show logging options help" +msgstr "Muestra la ayuda de las opciones del registro" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +msgid "Select executable" +msgstr "Seleccionar ejecutable" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:181 src/ui/views/GamesView/GamesView.vala:330 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select" +msgstr "Seleccionar" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:180 src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Cancel" +msgstr "Cancelar" + +#: src/data/Runnable.vala:166 src/ui/widgets/FileChooserEntry.vala:49 +msgid "Select directory" +msgstr "Seleccionar directorio" + +#: src/data/Runnable.vala:619 +#, c-format +msgid "Part %1$u of %2$u: %3$s" +msgstr "Parte %1$u de %2$u: %3$s" + +#: src/data/Runnable.vala:642 src/ui/dialogs/CorruptedInstallerDialog.vala:48 +#, c-format +msgid "%s: corrupted installer" +msgstr "%s: instalador dañado" + +#: src/data/Runnable.vala:643 +#, c-format +msgid "Checksum mismatch in %s" +msgstr "" + +#: src/data/Runnable.vala:657 src/ui/dialogs/CorruptedInstallerDialog.vala:126 +msgid "Show file" +msgstr "Mostrar archivo" + +#: src/data/Runnable.vala:658 src/ui/dialogs/CorruptedInstallerDialog.vala:132 +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#: src/ui/widgets/TagRow.vala:146 +msgid "Remove" +msgstr "Eliminar" + +#: src/data/Runnable.vala:659 src/ui/dialogs/CorruptedInstallerDialog.vala:128 +msgid "Backup" +msgstr "Respaldo" + +#: src/data/Runnable.vala:778 +#, c-format +msgid "%s: cannot detect main executable" +msgstr "%s: no se puede detectar el ejecutable principal" + +#: src/data/Runnable.vala:779 +msgid "" +"Main executable file for this game cannot be detected automatically.\n" +"Please set main executable in game's properties." +msgstr "" +"El ejecutable principal para este juego no puede ser detectado " +"automáticamente.\n" +"Por favor establece el ejecutable principal en las propiedades del juego." + +#: src/data/Runnable.vala:908 +msgctxt "platform" +msgid "Emulated" +msgstr "Emulado" + +#: src/data/Game.vala:625 +msgctxt "status" +msgid "Running" +msgstr "Ejecutándose" + +#: src/data/Game.vala:628 +msgctxt "status" +msgid "Installed" +msgstr "Instalado" + +#: src/data/Game.vala:629 +msgctxt "status" +msgid "Installing" +msgstr "Instalando" + +#: src/data/Game.vala:630 +msgctxt "status" +msgid "Verifying installer integrity" +msgstr "Verificando integridad del instalador" + +#: src/data/Game.vala:631 +msgctxt "status" +msgid "Download started" +msgstr "Descarga iniciada" + +#: src/data/Game.vala:633 +msgctxt "status" +msgid "Not installed" +msgstr "No instalado" + +#: src/data/Game.vala:643 +msgctxt "status_header" +msgid "Installed" +msgstr "Instalado" + +#: src/data/Game.vala:644 +msgctxt "status_header" +msgid "Installing" +msgstr "Instalando" + +#: src/data/Game.vala:646 +msgctxt "status_header" +msgid "Downloading" +msgstr "Descargando" + +#: src/data/Game.vala:648 +msgctxt "status_header" +msgid "Not installed" +msgstr "No instalado" + +#: src/data/GameSource.vala:31 +#, c-format +msgid "%s games" +msgstr "%s juegos" + +#: src/data/sources/steam/Steam.vala:43 +msgid "Your SteamID will be read from Steam configuration file" +msgstr "Tu ID de Steam será leído desde el archivo de configuración de Steam" + +#: src/data/sources/steam/Steam.vala:46 +msgid "" +"Steam config file not found.\n" +"Login into your account in Steam client and return to GameHub" +msgstr "" +"El archivo de configuración de Steam no fue encontrado.\n" +"Inicia sesión en tu cliente de Steam y regresa a GameHub" + +#: src/data/sources/gog/GOGGame.vala:983 +#, c-format +msgid "DLC: %s" +msgstr "DLC: %s" + +#: src/data/sources/humble/HumbleGame.vala:343 +#, c-format +msgid "%s: no available installers" +msgstr "%s: ningún instalador disponible" + +#: src/data/sources/humble/HumbleGame.vala:344 +msgid "" +"Cannot get Trove download URL.\n" +"Make sure your Humble Monthly subscription is active." +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:192 +#, c-format +msgctxt "itch_dl_status" +msgid "%s left;" +msgstr "%s restante;" + +#: src/data/sources/itch/ItchDownloader.vala:195 +#, c-format +msgctxt "itch_dl_status" +msgid "%d%%" +msgstr "%d %%" + +#: src/data/sources/itch/ItchDownloader.vala:198 +#, c-format +msgctxt "itch_dl_status" +msgid "(%1$s / %2$s)" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:201 +#, c-format +msgctxt "itch_dl_status" +msgid "[%s/s]" +msgstr "" + +#: src/data/sources/user/User.vala:30 +msgid "User games" +msgstr "Juegos del usuario" + +#: src/data/db/tables/Tags.vala:225 +msgctxt "tag" +msgid "Favorites" +msgstr "Favoritos" + +#: src/data/db/tables/Tags.vala:226 +msgctxt "tag" +msgid "Not installed" +msgstr "No instalado" + +#: src/data/db/tables/Tags.vala:227 +msgctxt "tag" +msgid "Installed" +msgstr "Instalado" + +#: src/data/db/tables/Tags.vala:228 +msgctxt "tag" +msgid "Hidden" +msgstr "Oculto" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit script" +msgstr "Editar script" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit custom script" +msgstr "Editar script personalizado" + +#: src/data/compat/Innoextract.vala:55 +#, c-format +msgid "" +"Innoextract %1$s is not supported and may not be able to extract some " +"games correctly.\n" +"Install innoextract %2$s or newer." +msgstr "" +"Innoextract %1$s no está soportado y puede ser que no extraiga " +"algunos juegos correctamente.\n" +"Instala Innoextract %2$s o más reciente." + +#: src/data/compat/WineWrap.vala:61 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:242 +#: src/ui/dialogs/CompatRunDialog.vala:102 +#: src/ui/views/GamesView/GameContextMenu.vala:53 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:234 +msgid "Run" +msgstr "Iniciar" + +#: src/data/compat/WineWrap.vala:64 +#, fuzzy +msgid "Show WineWrap menu" +msgstr "Mostrar menú WineWrap" + +#: src/data/compat/WineWrap.vala:67 src/data/compat/Proton.vala:122 +#: src/data/compat/Wine.vala:83 +#, fuzzy +msgid "Kill apps in prefix" +msgstr "Mata a todas las apps en el prefijo" + +#: src/data/compat/Proton.vala:47 +msgid "Proton prefix" +msgstr "" + +#: src/data/compat/Proton.vala:110 src/data/compat/Wine.vala:71 +msgid "Open prefix directory" +msgstr "" + +#: src/data/compat/Proton.vala:113 src/data/compat/Wine.vala:74 +msgid "Run winecfg" +msgstr "Iniciar winecfg" + +#: src/data/compat/Proton.vala:116 src/data/compat/Wine.vala:77 +msgid "Run winetricks" +msgstr "Iniciar winetricks" + +#: src/data/compat/Proton.vala:119 src/data/compat/Wine.vala:80 +msgid "Run taskmgr" +msgstr "Iniciar taskmgr" + +#: src/data/compat/Wine.vala:53 +msgid "Wine prefix" +msgstr "" + +#: src/data/compat/Wine.vala:55 +msgid "Environment variables" +msgstr "Variables de entorno" + +#: src/data/compat/Wine.vala:60 +msgid "InnoSetup default options" +msgstr "Opciones predeterminadas de InnoSetup" + +#: src/data/compat/RetroArch.vala:53 +msgid "Libretro core file" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:43 +msgid "Custom emulator" +msgstr "Emulador personalizado" + +#: src/data/compat/CustomEmulator.vala:48 +msgid "Emulator" +msgstr "Emulador" + +#: src/data/compat/CustomEmulator.vala:49 +msgid "Launch in game directory" +msgstr "Lanzar en directorio del juego" + +#: src/data/adapters/GamesAdapter.vala:440 +msgctxt "status_header" +msgid "Favorites" +msgstr "Favoritos" + +#: src/data/adapters/GamesAdapter.vala:445 +#, c-format +msgctxt "status_header" +msgid "%s: Favorites" +msgstr "%s: Favoritos" + +#: src/data/adapters/GamesAdapter.vala:491 +msgid "Merging games" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:504 +#, fuzzy, c-format +msgid "Merging games from %s" +msgstr "Uniendo juegos de %s" + +#: src/data/adapters/GamesAdapter.vala:551 +#, c-format +msgid "Loading games from %s" +msgstr "Cargando juegos de %s" + +#: src/data/adapters/GamesAdapter.vala:678 +msgctxt "sort_mode" +msgid "By name" +msgstr "Por nombre" + +#: src/data/adapters/GamesAdapter.vala:679 +#, fuzzy +msgctxt "sort_mode" +msgid "By last launch" +msgstr "Por último lanzado" + +#: src/data/adapters/GamesAdapter.vala:680 +msgctxt "sort_mode" +msgid "By playtime" +msgstr "Por tiempo de juego" + +#: src/data/adapters/GamesAdapter.vala:705 +msgctxt "group_mode" +msgid "Do not group" +msgstr "No agrupar" + +#: src/data/adapters/GamesAdapter.vala:706 +msgctxt "group_mode" +msgid "By status" +msgstr "Por estatus" + +#: src/data/adapters/GamesAdapter.vala:707 +#, fuzzy +msgctxt "group_mode" +msgid "By source" +msgstr "Por fuente" + +#: src/data/providers/images/SteamGridDB.vala:151 +#: src/data/providers/data/IGDB.vala:431 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:217 +msgid "Default" +msgstr "Por defecto" + +#: src/data/providers/images/SteamGridDB.vala:158 +#: src/data/providers/data/IGDB.vala:438 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:225 +msgid "Restore default API key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:169 +#: src/data/providers/data/IGDB.vala:449 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:108 +msgid "API key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:177 +#: src/data/providers/data/IGDB.vala:457 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:53 +msgid "Generate key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:208 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Style" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:209 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Score" +msgstr "Puntaje" + +#: src/data/providers/images/SteamGridDB.vala:213 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Author" +msgstr "Autor" + +#: src/data/providers/images/SteamGridDB.vala:225 +#, fuzzy +msgctxt "imagesource_steamgriddb_image_style" +msgid "Alternate" +msgstr "Cambiar" + +#: src/data/providers/images/SteamGridDB.vala:226 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Blurred" +msgstr "" + +#. TRANSLATORS: Flat / Material Design image style. Probably should not be translated +#: src/data/providers/images/SteamGridDB.vala:228 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Material" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:229 +msgctxt "imagesource_steamgriddb_image_style" +msgid "No logo" +msgstr "Sin logo" + +#: src/data/providers/images/SteamGridDB.vala:230 +msgctxt "imagesource_steamgriddb_image_style" +msgid "White logo" +msgstr "Logo blanco" + +#: src/data/providers/data/IGDB.vala:147 +#, fuzzy +msgid "" +"Monthly IGDB request quota has been reached. Set your own API key to use " +"IGDB data or disable IGDB." +msgstr "" +"Cuota mensual de peticiones IGDB ha sido alcanzada. Establece tu propia " +"llave API para usar IGDB o deshabilita IGDB." + +#: src/data/providers/data/IGDB.vala:148 +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:40 +#: src/ui/views/WelcomeView.vala:53 src/ui/views/WelcomeView.vala:78 +#: src/ui/views/GamesView/GamesView.vala:230 +#: src/ui/views/GamesView/GamesView.vala:629 +msgid "Settings" +msgstr "Configuración" + +#: src/data/providers/data/IGDB.vala:356 +msgctxt "igdb_related_link" +msgid "Official website" +msgstr "Sitio oficial" + +#: src/data/providers/data/IGDB.vala:469 +msgctxt "igdb_preferred_description" +msgid "When game has description, show description" +msgstr "Cuando el juego cuente con descripción, mostrar descripción" + +#: src/data/providers/data/IGDB.vala:476 +#, fuzzy +msgctxt "igdb_preferred_description" +msgid "of game" +msgstr "del juego" + +#: src/data/providers/data/IGDB.vala:477 +msgctxt "igdb_preferred_description" +msgid "from IGDB" +msgstr "desde IGDB" + +#: src/data/providers/data/IGDB.vala:478 +msgctxt "igdb_preferred_description" +msgid "both" +msgstr "ambos" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:65 +msgid "Some settings will be applied after application restart" +msgstr "" +"Algunas configuraciones serán aplicadas después de reiniciar la aplicación" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:71 +msgid "Games directory contains space. It may cause problems for some games" +msgstr "" +"Directorio de juegos contiene espacio. Esto podría causar problemas para " +"algunos juegos" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:36 +msgid "Interface" +msgstr "Interfaz" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:37 +msgid "Appearance" +msgstr "Apariencia" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:38 +#, fuzzy +msgid "General interface settings" +msgstr "Configuración general de interfaz" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:48 +msgid "Dark theme" +msgstr "Tema obscuro" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:53 +msgctxt "icon_style" +msgid "Theme-based" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:54 +msgctxt "icon_style" +msgid "Symbolic" +msgstr "Simbólico" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:55 +msgctxt "icon_style" +msgid "Colored" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:57 +msgctxt "icon_style" +msgid "Icon style" +msgstr "Estilo de icono" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:84 +msgid "Game card" +msgstr "Tarjeta de juego" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:86 +#, fuzzy +msgid "Show platform icons" +msgstr "Mostrar iconos de plataforma" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:99 +msgctxt "grid_size" +msgid "Card size" +msgstr "Tamaño de tarjeta" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:117 +msgctxt "grid_size_preset" +msgid "Presets" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:139 +#, fuzzy +msgid "Games list: installed" +msgstr "Lista de juegos: instalado" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:140 +#, fuzzy +msgid "Games list: not installed" +msgstr "Lista de juego: no instalado" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:142 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:146 +msgctxt "list_style" +msgid "Show icon" +msgstr "Mostrar icono" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:143 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:147 +#, fuzzy +msgctxt "list_style" +msgid "Bold title" +msgstr "Título en negritas" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:144 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:148 +msgctxt "list_style" +msgid "Show status" +msgstr "Mostrar estatus" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:149 +msgctxt "list_style" +msgid "Dim" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:151 +msgid "Grid options" +msgstr "Opciones del grid" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:152 +#, fuzzy +msgid "List options" +msgstr "Lista de opciones" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:31 +msgid "Behavior" +msgstr "Comportamiento" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:32 +msgid "Behavior settings" +msgstr "Configuración del comportamiento" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:42 +msgid "Run games with double click" +msgstr "Iniciar juegos con doble clic" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:46 +msgid "Merge games from different sources" +msgstr "Mezclar juegos de diferentes fuentes" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:50 +msgid "Use imported tags" +msgstr "Usar etiquetas importadas" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:51 +msgid "General" +msgstr "General" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:52 +msgid "Collection" +msgstr "Colección" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:53 +msgid "Empty" +msgstr "Vacío" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:65 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:85 +msgid "Collection directory" +msgstr "Directorio de colección" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:70 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:78 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:87 +msgid "Game directory" +msgstr "Directorio de juego" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:71 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:79 +msgid "Installers" +msgstr "Instaladores" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:72 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:98 +msgid "DLC" +msgstr "DLC" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:73 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:197 +msgid "Bonus content" +msgstr "Contenido adicional" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:84 +#, fuzzy +msgid "Variable syntax: $var or ${var}" +msgstr "Sintaxis variable: $var ó ${var}" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:86 +msgid "Game name" +msgstr "Nombre del juego" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:88 +#: src/ui/views/GamesView/FiltersPopover.vala:127 +msgid "Platform" +msgstr "Plataforma" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:36 +#, fuzzy +msgid "Controller" +msgstr "Control" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +msgid "Enabled" +msgstr "Habilitado" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:53 +msgid "Focus GameHub window with Guide button" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:57 +#, fuzzy +msgid "Controllers" +msgstr "Controles" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:89 +#, fuzzy +msgid "Move focus" +msgstr "Mover enfoque" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:91 +msgid "Exit" +msgstr "Salir" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:40 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:108 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:92 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:95 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:36 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:77 +msgid "Disabled" +msgstr "Deshabilitado" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:47 +#: src/ui/dialogs/GameTweaksDialog.vala:53 +#: src/ui/views/GamesView/GameContextMenu.vala:183 +msgid "Tweaks" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:34 +msgid "Tweak launch options and apply them to games automatically" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:79 +msgid "" +"Tweaks are loaded from following directories in order\n" +"Last tweak overrides previous tweaks with same identifiers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:83 +msgid "Click to open" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:93 +#, c-format +msgid "Tweaks are loaded from %1$s and %2$d more directories (?)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:38 +msgid "Game sources" +msgstr "Fuentes de juegos" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +#, fuzzy +msgid "Steam API keys have limited number of uses per day" +msgstr "Llaves de Steam API tienen número limitado de usos por día" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:63 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:57 +msgid "Installation directory" +msgstr "Directorio de instalación" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:176 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:81 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:34 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:75 +msgid "Not installed" +msgstr "No instalado" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:116 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:96 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:99 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:85 +msgid "Not authenticated" +msgstr "No autenticado" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +#, c-format +msgid "Authenticated as %s" +msgstr "Autenticado como %s" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:103 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +msgid "Authenticated" +msgstr "Autenticado" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:183 +#: src/ui/dialogs/InstallDialog.vala:53 src/ui/dialogs/InstallDialog.vala:111 +#: src/ui/views/GamesView/GameContextMenu.vala:80 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:233 +#: src/ui/widgets/TweaksList.vala:95 +msgid "Install" +msgstr "Instalar" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:236 +#, fuzzy +msgid "Steam API key" +msgstr "Llave de Steam API" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:50 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:54 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:48 +msgid "Games directory" +msgstr "Directorio de juegos" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:63 +#, fuzzy +msgid "Logout" +msgstr "Cerrar sesión" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:50 +msgid "Load games from Humble Trove" +msgstr "Cargar juegos desde Huble Trove" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:45 +msgid "Emulators" +msgstr "Emuladores" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:45 +msgid "Libretro core directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:46 +msgid "Libretro core info directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:50 +msgid "Ignored libretro cores" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:54 +msgid "Ignored game file extensions" +msgstr "Extensiones de juego ignoradas" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:66 +#, fuzzy +msgid "No cores found" +msgstr "No se han encontrado núcleos" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:70 +#, c-format +msgid "%u core found" +msgid_plural "%u cores found" +msgstr[0] "%u núcleo encontrado" +msgstr[1] "%u núcleos encontrados" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:46 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:168 +msgid "No custom emulators" +msgstr "Sin emuladores personalizados" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:164 +#, c-format +msgid "%u custom emulator" +msgid_plural "%u custom emulators" +msgstr[0] "%u emulador personalizado" +msgstr[1] "%u emuladores personalizados" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:237 +msgid "Save" +msgstr "Guardar" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:250 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:312 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/dialogs/GamePropertiesDialog.vala:168 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +#: src/ui/views/GamesView/AddGamePopover.vala:67 +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Executable" +msgstr "Ejecutable" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:251 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/views/GamesView/AddGamePopover.vala:68 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Installer" +msgstr "Instalador" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:256 +#: src/ui/dialogs/GamePropertiesDialog.vala:64 +#: src/ui/dialogs/GamePropertiesDialog.vala:69 +#: src/ui/views/GamesView/AddGamePopover.vala:73 +msgid "Name" +msgstr "Nombre" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:272 +#: src/ui/dialogs/GamePropertiesDialog.vala:201 +#: src/ui/views/GamesView/AddGamePopover.vala:78 +msgid "Arguments" +msgstr "Argumentos" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:276 +msgid "Variables" +msgstr "Variables" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:277 +msgid "Game executable" +msgstr "Ejecutable del juego" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:278 +msgid "Game arguments" +msgstr "Argumentos del juego" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:80 +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Directory" +msgstr "Directorio" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +msgid "Select emulator directory" +msgstr "Selecciona directorio del emulador" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:292 +#: src/ui/dialogs/GamePropertiesDialog.vala:219 +msgid "Force compatibility mode" +msgstr "Forzar modo de compatibilidad" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:307 +msgid "Game file patterns" +msgstr "Patrones de filtro del juego" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:315 +msgid "Image" +msgstr "Imagen" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:318 +msgid "Icon" +msgstr "Icono" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:325 +msgid "" +"findutils-compatible glob patterns\n" +"\n" +" Multiple patterns can be separated with |\n" +" Start pattern with ./ to match relative path\n" +" $basename variable will be replaced with game's executable " +"name (without extension)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:38 +msgid "Data" +msgstr "Datos" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:39 +msgid "Providers" +msgstr "Proveedores" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:40 +#, fuzzy +msgid "Third-party data providers" +msgstr "Datos de terceros" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:55 +#, fuzzy +msgid "Image providers" +msgstr "Proveedores de imagen" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:68 +msgid "Metadata providers" +msgstr "Proveedores de metadatos" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:137 +#, fuzzy +msgid "Open website" +msgstr "Sitio abierto" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:36 +msgid "About" +msgstr "Acerca de" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:71 +#, fuzzy +msgid "Copy application version and environment info" +msgstr "Copiar versión e información del entorno de aplicación" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:78 +#: src/ui/views/WelcomeView.vala:57 +#, fuzzy +msgid "All your games in one place" +msgstr "Todos tus juegos en un lugar" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:92 +msgctxt "about_link" +msgid "Website" +msgstr "Sitio web" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:96 +msgctxt "about_link" +msgid "Source code on GitHub" +msgstr "Código fuente en GitHub" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:103 +msgctxt "about_link" +msgid "Report a problem" +msgstr "Reportar un problema" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:104 +#, fuzzy +msgctxt "about_link" +msgid "Suggest translations" +msgstr "Recomendar traducciones" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:110 +#, fuzzy +msgctxt "about_link" +msgid "Issues" +msgstr "Asuntos" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:111 +msgctxt "about_link" +msgid "Contributors" +msgstr "Contribuidores" + +#. TRANSLATORS: Likely it should not be translated. GitHub Pulse is a page that shows recent repository activity: https://github.com/tkashkin/GameHub/pulse +#: src/ui/dialogs/SettingsDialog/pages/About.vala:114 +msgctxt "about_link" +msgid "Pulse" +msgstr "Pulse" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:115 +msgctxt "about_link" +msgid "Forks" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:109 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:129 +msgid "Import" +msgstr "Importar" + +#: src/ui/dialogs/InstallDialog.vala:110 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:153 +msgid "Download" +msgstr "Descargar" + +#: src/ui/dialogs/InstallDialog.vala:207 +#, fuzzy +msgid "Select installer" +msgstr "Seleccionar instalador" + +#: src/ui/dialogs/InstallDialog.vala:216 +#, c-format +msgid "Installer size: %s" +msgstr "Tamaño del instalador: %s" + +#: src/ui/dialogs/InstallDialog.vala:348 +msgid "Unknown" +msgstr "Desconocido" + +#: src/ui/dialogs/GamePropertiesDialog.vala:49 +#, c-format +msgid "%s: Properties" +msgstr "%s: Propiedades" + +#: src/ui/dialogs/GamePropertiesDialog.vala:84 +msgid "Images" +msgstr "Imágenes" + +#: src/ui/dialogs/GamePropertiesDialog.vala:126 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:160 +#: src/ui/views/GameDetailsView/blocks/Artwork.vala:62 +msgid "Download images" +msgstr "Descargar imágenes" + +#: src/ui/dialogs/GamePropertiesDialog.vala:144 +msgid "Image URL" +msgstr "Imagen URL" + +#: src/ui/dialogs/GamePropertiesDialog.vala:148 +msgid "Vertical image URL" +msgstr "Imagen URL vertical" + +#: src/ui/dialogs/GamePropertiesDialog.vala:157 +msgid "Icon URL" +msgstr "Icono URL" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +#, fuzzy +msgid "Select working directory" +msgstr "Seleccionar directorio" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +#, fuzzy +msgid "Working directory" +msgstr "Abrir directorio" + +#: src/ui/dialogs/GamePropertiesDialog.vala:214 +msgid "Compatibility" +msgstr "Compatibilidad" + +#: src/ui/dialogs/GamePropertiesDialog.vala:236 +msgid "Launch from terminal" +msgstr "Iniciar desde terminal" + +#: src/ui/dialogs/GamePropertiesDialog.vala:252 +msgid "Copy to clipboard" +msgstr "Copiar al portapapeles" + +#: src/ui/dialogs/GamePropertiesDialog.vala:254 +msgid "Add to Steam" +msgstr "Añadir a Steam" + +#: src/ui/dialogs/GamePropertiesDialog.vala:255 +msgid "Add to the Steam library" +msgstr "Añadir a la librería de Steam" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:53 +#, c-format +msgid "%s: Overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "Overlays are disabled" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "" +"Enable overlays to manage DLCs and mods\n" +"\n" +"Enabling will move game to the “base“ overlay" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:77 +#: src/ui/views/GamesView/GameContextMenu.vala:175 +msgid "Overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:105 +msgid "Overlay ID (directory name)" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:110 +msgid "Overlay name (optional)" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:112 +msgid "Add" +msgstr "Añadir" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:127 +msgid "Enable overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:182 +#, c-format +msgid "" +"Overlay usage at this path may be unsafe\n" +"Proceed at your own risk\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:187 +#, c-format +msgid "" +"Overlay usage at this path is not supported\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:266 +msgid "Open directory" +msgstr "Abrir directorio" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:271 +msgid "Remove overlay" +msgstr "" + +#: src/ui/dialogs/CompatRunDialog.vala:48 +#: src/ui/views/GamesView/GameContextMenu.vala:46 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:235 +msgid "Run with compatibility layer" +msgstr "Iniciar con la capa de compatibilidad" + +#: src/ui/dialogs/CorruptedInstallerDialog.vala:71 +msgid "Corrupted installer: checksum mismatch in" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:57 +#: src/ui/views/GamesView/AddGamePopover.vala:105 +msgid "Import emulated games" +msgstr "Importar juegos emulados" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:75 +msgid "Select directory with emulated games" +msgstr "Seleccionar directorio con juegos emulados" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:83 +msgid "Detected games" +msgstr "Juegos detectados" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:107 +msgid "Select all" +msgstr "Seleccionar todo" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:115 +msgid "Select directory to import" +msgstr "Seleccionar directorio a importar" + +#: src/ui/dialogs/GameTweaksDialog.vala:40 +#, c-format +msgid "%s: Tweaks" +msgstr "" + +#: src/ui/views/WelcomeView.vala:52 +msgid "No enabled game sources" +msgstr "Sin fuentes de juegos habilitadas" + +#: src/ui/views/WelcomeView.vala:52 +msgid "Enable some game sources in settings" +msgstr "Habilita algunas fuentes de juegos en configuraciones" + +#: src/ui/views/WelcomeView.vala:57 +#, fuzzy +msgid "Let's get started" +msgstr "Vamos a iniciar" + +#: src/ui/views/WelcomeView.vala:71 +msgid "Skip" +msgstr "Saltar" + +#: src/ui/views/WelcomeView.vala:141 +msgid "Ready" +msgstr "Listo" + +#: src/ui/views/WelcomeView.vala:147 +msgid "Authentication required" +msgstr "Autenticación requerida" + +#: src/ui/views/WelcomeView.vala:152 +msgid "Authenticating…" +msgstr "Autenticando…" + +#: src/ui/views/WelcomeView.vala:163 +#, fuzzy, c-format +msgid "Install %s" +msgstr "Instalación %s" + +#: src/ui/views/WelcomeView.vala:164 +msgid "Return to GameHub after installing" +msgstr "Regresar a GameHub después instalar" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "No games" +msgstr "Sin juegos" + +#: src/ui/views/GamesView/GamesView.vala:136 +#, fuzzy +msgid "Get some games or enable some game sources in settings" +msgstr "" +"Adquiere algunos juegos o habilita algunas fuentes de juegos en configuración" + +#: src/ui/views/GamesView/GamesView.vala:150 +#, fuzzy +msgid "Grid view" +msgstr "Vista de cuadricula" + +#: src/ui/views/GamesView/GamesView.vala:151 +msgid "List view" +msgstr "Vista de lista" + +#: src/ui/views/GamesView/GamesView.vala:159 +msgid "All games" +msgstr "Todos los juegos" + +#: src/ui/views/GamesView/GamesView.vala:182 +msgid "Downloads" +msgstr "Descargas" + +#: src/ui/views/GamesView/GamesView.vala:208 +msgid "Filters" +msgstr "Filtros" + +#: src/ui/views/GamesView/GamesView.vala:216 +#: src/ui/views/GamesView/AddGamePopover.vala:84 +msgid "Add game" +msgstr "Añadir juego" + +#: src/ui/views/GamesView/GamesView.vala:223 +msgid "Search" +msgstr "Buscar" + +#: src/ui/views/GamesView/GamesView.vala:328 +msgid "Menu" +msgstr "Menú" + +#: src/ui/views/GamesView/GamesView.vala:329 +#: src/ui/views/GameDetailsView/GameDetailsView.vala:104 +msgid "Back" +msgstr "Regresar" + +#: src/ui/views/GamesView/GamesView.vala:550 +#, c-format +msgid "%u game" +msgid_plural "%u games" +msgstr[0] "%u juego" +msgstr[1] "%u juegos" + +#: src/ui/views/GamesView/GamesView.vala:553 +#, c-format +msgctxt "games_view_subtitle_filtered_games" +msgid "%1$u / %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:557 +#, c-format +msgctxt "games_view_subtitle" +msgid "%1$s: %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:568 +#, fuzzy +msgid "No user-added games" +msgstr "Sin juegos añadidos por el usuario" + +#: src/ui/views/GamesView/GamesView.vala:569 +msgid "Add some games using plus button" +msgstr "Añade algunos juegos usando el botón de más" + +#: src/ui/views/GamesView/GamesView.vala:573 +#, c-format +msgid "No %s games" +msgstr "Sin %s juegos" + +#: src/ui/views/GamesView/GamesView.vala:574 +msgid "Get some Linux-compatible games" +msgstr "Obtén algunos juegos compatibles con Linux" + +#: src/ui/views/GamesView/GamesView.vala:584 +#, c-format +msgid "No games matching “%s”" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:589 +#, c-format +msgid "No %1$s games matching “%2$s”" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:627 +#, fuzzy +msgid "" +"No games were loaded from Steam. Set your games list privacy to public or " +"use your own Steam API key in settings." +msgstr "" +"Ningún juego fue cargado desde Steam. Establece tu lista de privacidad de " +"juegos a público o usa tu propia llave de Steam API en configuración." + +#: src/ui/views/GamesView/GamesView.vala:628 +msgid "Privacy" +msgstr "Privacidad" + +#: src/ui/views/GamesView/GamesView.vala:739 +msgid "Downloading images" +msgstr "Descargar imágenes" + +#: src/ui/views/GamesView/GamesView.vala:753 +#, c-format +msgid "Downloading image: %s" +msgstr "Descargando imagen: %s" + +#: src/ui/views/GamesView/DownloadProgressView.vala:131 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:162 +msgid "Pause download" +msgstr "Pausar descarga" + +#: src/ui/views/GamesView/DownloadProgressView.vala:137 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:168 +msgid "Resume download" +msgstr "Reanudar descarga" + +#: src/ui/views/GamesView/DownloadProgressView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:174 +msgid "Cancel download" +msgstr "Cancelar descarga" + +#: src/ui/views/GamesView/FiltersPopover.vala:77 +#, fuzzy +msgid "Group" +msgstr "Agrupar" + +#: src/ui/views/GamesView/FiltersPopover.vala:102 +msgid "Sort" +msgstr "Ordenar" + +#: src/ui/views/GamesView/FiltersPopover.vala:234 +#: src/ui/widgets/GameTagsList.vala:58 +msgid "Tags" +msgstr "Etiquetas" + +#: src/ui/views/GamesView/FiltersPopover.vala:353 +msgid "All platforms" +msgstr "Todas las plataformas" + +#: src/ui/views/GamesView/AddGamePopover.vala:77 +msgid "Select game executable" +msgstr "Seleccionar ejecutable de juego" + +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Select game directory" +msgstr "Seleccionar directorio de juego" + +#: src/ui/views/GamesView/AddGamePopover.vala:111 +msgid "Download game images" +msgstr "Descargar imágenes de juego" + +#: src/ui/views/GamesView/GameContextMenu.vala:87 +msgid "Details" +msgstr "Detalles" + +#: src/ui/views/GamesView/GameContextMenu.vala:117 +msgctxt "game_context_menu" +msgid "Favorite" +msgstr "Favorito" + +#: src/ui/views/GamesView/GameContextMenu.vala:121 +msgctxt "game_context_menu" +msgid "Hidden" +msgstr "Oculto" + +#: src/ui/views/GamesView/GameContextMenu.vala:133 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:236 +msgid "Open installation directory" +msgstr "Abrir directorio de instalación" + +#: src/ui/views/GamesView/GameContextMenu.vala:142 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:237 +msgid "Open installers collection directory" +msgstr "Abrir directorio de colección de instaladores" + +#: src/ui/views/GamesView/GameContextMenu.vala:151 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:238 +msgid "Open bonus collection directory" +msgstr "Abrir directorio de colección de bonus" + +#: src/ui/views/GamesView/GameContextMenu.vala:160 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:239 +msgid "Open screenshots directory" +msgstr "Abrir directorio de capturas de pantalla" + +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +msgid "Uninstall" +msgstr "Desinstalar" + +#: src/ui/views/GamesView/GameContextMenu.vala:192 +msgid "Properties" +msgstr "Propiedades" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:100 +#, c-format +msgid "%d game selected" +msgid_plural "%d games selected" +msgstr[0] "%d juego seleccionado" +msgstr[1] "%d juegos seleccionados" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:144 +#, c-format +msgid "%d game will be installed" +msgid_plural "%d games will be installed" +msgstr[0] "%d juego será instalado" +msgstr[1] "%d juegos serán instalados" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:154 +#, c-format +msgid "%d game will be downloaded" +msgid_plural "%d games will be downloaded" +msgstr[0] "%d juego será descargado" +msgstr[1] "%d juegos serán descargados" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:161 +#, c-format +msgid "Image for %d game will be searched" +msgid_plural "Images for %d games will be searched" +msgstr[0] "Imagen para %d juego será buscada" +msgstr[1] "Imágenes para %d juegos serán buscadas" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:168 +#, c-format +msgid "%d game will be uninstalled" +msgid_plural "%d games will be uninstalled" +msgstr[0] "%d juego será desinstalado" +msgstr[1] "%d juegos serán desinstalados" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:174 +msgid "Refresh" +msgstr "Actualizar" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:175 +#, fuzzy, c-format +msgid "" +"%d game will be removed from database. Restart GameHub to fetch new data" +msgid_plural "" +"%d games will be removed from database. Restart GameHub to fetch new data" +msgstr[0] "" +"%d juego será removido de la base de datos. Reinicia GameHub para extraer " +"nueva información" +msgstr[1] "" +"%d juegos serán removidos de la base de datos. Reinicia GameHub para extraer " +"nueva información" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:240 +#, fuzzy +msgid "Open store page" +msgstr "Abrir página de la tienda" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:242 +#, fuzzy +msgid "Game properties" +msgstr "Propiedades de juego" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:46 +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:60 +#, fuzzy +msgid "Playtime" +msgstr "Tiempo de juego" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:52 +#, fuzzy +msgid "Playtime (local)" +msgstr "Tiempo de juego (local)" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:69 +#, fuzzy +msgid "Last launch" +msgstr "Último inicio" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:46 +msgid "Achievements" +msgstr "Logros" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:85 +#, c-format +msgid "Unlocked: %s" +msgstr "Desbloqueado: %s" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:90 +#, c-format +msgid "Global percentage: %g%%" +msgstr "Porcentaje global: %g%%" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:77 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:103 +msgid "Language" +msgstr "Lenguaje" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:80 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:106 +msgid "Languages" +msgstr "Lenguajes" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:147 +#, fuzzy, c-format +msgid "%u DLCs cannot be installed" +msgstr "%s: instalador dañado" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:71 +msgid "Category" +msgstr "Categoría" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:74 +msgid "Categories" +msgstr "Categorías" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:90 +msgid "Genre" +msgstr "Género" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:93 +msgid "Genres" +msgstr "Géneros" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:109 +msgctxt "igdb" +msgid "Popularity" +msgstr "Popularidad" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:115 +#, fuzzy +msgctxt "igdb" +msgid "Aggregated rating" +msgstr "Clasificación agregada" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:116 +#, fuzzy +msgctxt "igdb" +msgid "IGDB user rating" +msgstr "Clasificación de usuario IGDB" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:117 +#, fuzzy +msgctxt "igdb" +msgid "Total rating" +msgstr "Clasificación total" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:126 +msgctxt "igdb" +msgid "Release date" +msgstr "Fecha de lanzamiento" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:133 +msgctxt "igdb" +msgid "Platforms" +msgstr "Plataformas" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:139 +msgctxt "igdb" +msgid "Genres" +msgstr "Géneros" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:145 +#, fuzzy +msgctxt "igdb" +msgid "Keywords" +msgstr "Palabras clave" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:152 +msgctxt "igdb" +msgid "Links" +msgstr "Links" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:208 +#, fuzzy, c-format +msgid "Based on %d rating" +msgid_plural "Based on %d ratings" +msgstr[0] "Basado en %d clasificación" +msgstr[1] "Basado en %d clasificaciones" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:290 +#, fuzzy +msgctxt "igdb" +msgid "Summary" +msgstr "Resumen" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:301 +msgctxt "igdb" +msgid "Storyline" +msgstr "" + +#: src/ui/widgets/FileChooserEntry.vala:49 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +#, fuzzy +msgid "Select file" +msgstr "Seleccionar archivo" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "No images" +msgstr "Sin imágenes" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "" +"There are no images found for this game\n" +"Make sure game name is correct" +msgstr "" +"No se encontraron imágenes para este juego.\n" +"Asegurate de que el nombre del juego sea correcto" + +#: src/ui/widgets/ImagesDownloadPopover.vala:94 +msgid "Search images:" +msgstr "Buscar imágenes:" + +#: src/ui/widgets/CompatToolPicker.vala:53 +msgid "Compatibility layer:" +msgstr "Capa de compatibilidad:" + +#: src/ui/widgets/CompatToolPicker.vala:92 +#, fuzzy +msgid "Configure" +msgstr "Configurar" + +#: src/ui/widgets/GameTagsList.vala:109 +msgid "Add tag" +msgstr "Añadir etiqueta" + +#: src/ui/widgets/TweaksList.vala:86 +msgid "No description" +msgstr "" + +#: src/ui/widgets/TweaksList.vala:124 +#, fuzzy +msgid "Edit file" +msgstr "Seleccionar archivo" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dh" +msgstr "%dh" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dm" +msgstr "%dm" + +#: src/utils/Utils.vala:464 +#, fuzzy, c-format +msgctxt "time" +msgid "%ds" +msgstr "%dh" + +#: src/settings/UI.vala:153 +msgctxt "grid_size_preset" +msgid "Steam" +msgstr "Steam" + +#: src/settings/UI.vala:154 +msgctxt "grid_size_preset" +msgid "Steam (vertical)" +msgstr "Steam (vertical)" + +#: src/settings/UI.vala:155 +msgctxt "grid_size_preset" +msgid "GOG" +msgstr "GOG" + +#: src/settings/UI.vala:156 +msgctxt "grid_size_preset" +msgid "GOG (vertical)" +msgstr "GOG (vertical)" + +#: src/settings/UI.vala:157 +#, fuzzy +msgctxt "grid_size_preset" +msgid "Square" +msgstr "Cuadrado" + +#: src/settings/UI.vala:158 +msgctxt "grid_size_preset" +msgid "Custom" +msgstr "Personalizado" + +#: src/utils/downloader/Downloader.vala:200 +msgctxt "dl_status" +msgid "Queued" +msgstr "Añadido a la cola" + +#: src/utils/downloader/Downloader.vala:201 +msgctxt "dl_status" +msgid "Starting download" +msgstr "Iniciando descarga" + +#: src/utils/downloader/Downloader.vala:202 +msgctxt "dl_status" +msgid "Download started" +msgstr "Descarga iniciada" + +#: src/utils/downloader/Downloader.vala:203 +msgctxt "dl_status" +msgid "Download finished" +msgstr "Descarga finalizada" + +#: src/utils/downloader/Downloader.vala:204 +msgctxt "dl_status" +msgid "Download failed" +msgstr "Descarga fallida" + +#: src/utils/downloader/Downloader.vala:208 +#, fuzzy, c-format +msgctxt "dl_status" +msgid "Downloading: %s" +msgstr "Descargando" + +#: src/utils/downloader/Downloader.vala:210 +#, fuzzy +msgctxt "dl_status" +msgid "Downloading" +msgstr "Descargando" + +#: src/utils/downloader/Downloader.vala:214 +#, fuzzy, c-format +msgctxt "dl_status" +msgid "Paused: %s" +msgstr "Pausado: %d%% (%s / %s)" + +#: src/utils/downloader/Downloader.vala:216 +#, fuzzy +msgctxt "dl_status" +msgid "Paused" +msgstr "Pausar descarga" + +#: src/utils/downloader/Downloader.vala:218 +msgctxt "dl_status" +msgid "Download cancelled" +msgstr "Descarga cancelada" + +#. TRANSLATORS: Download progress template. %1$d - percentage, %2$s / %3$s - downloaded portion and total file size, %4$s - download speed +#: src/utils/downloader/Downloader.vala:262 +#, fuzzy, c-format +msgctxt "dl_status" +msgid "%1$d%% (%2$s / %3$s) [%4$s/s]" +msgstr "Descargando: %d%% (%s / %s) [%s/s]" + +#, fuzzy +#~ msgid "Disable esync" +#~ msgstr "Deshabilitar esync" + +#, fuzzy +#~ msgid "Force LARGE_ADDRESS_AWARE flag" +#~ msgstr "Forzar bandera LARGE_ADDRESS_AWARE" + +#~ msgid "Disable DirectX 11 compatibility layer" +#~ msgstr "Deshabilitar capa de compatibilidad con DirectX 11" + +#~ msgid "Use WineD3D11 as DirectX 11 compatibility layer" +#~ msgstr "Usar WineD3D11 como capa de compatibilidad de DirectX 11" + +#, fuzzy +#~ msgid "Enable DirectX 9 compatibility layer" +#~ msgstr "Deshabilitar capa de compatibilidad con DirectX 11" + +#~ msgid "Silent installation" +#~ msgstr "Instalación silenciosa" + +#, fuzzy +#~ msgid "Very silent installation" +#~ msgstr "Instalación muy silenciosa" + +#~ msgid "No GUI" +#~ msgstr "Sin GUI" diff --git a/po/fa.po b/po/fa.po new file mode 100644 index 00000000..efe1f987 --- /dev/null +++ b/po/fa.po @@ -0,0 +1,1806 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the com.github.tkashkin.gamehub package. +# Goudarz Jafari , 2019. +msgid "" +msgstr "" +"Project-Id-Version: com.github.tkashkin.gamehub\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-26 06:40+0300\n" +"PO-Revision-Date: 2019-08-03 20:23+0000\n" +"Last-Translator: Goudarz Jafari \n" +"Language-Team: Persian \n" +"Language: fa\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 3.8-dev\n" + +#: src/app.vala:91 +msgid "Show help" +msgstr "نمایش راهنما" + +#: src/app.vala:92 +msgid "Show application version and exit" +msgstr "نمایش نسخه برنامه و خروج" + +#: src/app.vala:93 +msgid "Restart with GDB debugger attached" +msgstr "" + +#: src/app.vala:94 +msgid "Show full GDB backtrace" +msgstr "" + +#: src/app.vala:95 +msgid "Treat fatal errors as criticals and crash application" +msgstr "" + +#: src/app.vala:99 +msgid "Show main window" +msgstr "نمایش پنجره اصلی" + +#: src/app.vala:100 +msgid "Show application settings dialog" +msgstr "" + +#: src/app.vala:101 +msgid "Show about dialog" +msgstr "" + +#: src/app.vala:102 +msgid "Maximum number of background worker threads" +msgstr "" + +#: src/app.vala:106 +msgid "Run game" +msgstr "اجرای بازی" + +#: src/app.vala:107 +msgid "Show compatibility options dialog" +msgstr "" + +#: src/app.vala:108 +msgid "Open game details" +msgstr "جزئیات بازی را باز کن" + +#: src/app.vala:109 +msgid "Open game properties" +msgstr "" + +#: src/app.vala:113 +msgid "Enable debug logging" +msgstr "" + +#: src/app.vala:114 +msgid "" +"Log authentication process and sensitive information like authentication " +"tokens" +msgstr "" + +#: src/app.vala:115 +msgid "Log download manager" +msgstr "" + +#: src/app.vala:116 +msgid "Log background workers start/stop" +msgstr "" + +#: src/app.vala:117 +msgid "Disable log messages filtering" +msgstr "" + +#: src/app.vala:118 +msgid "Verbose logging" +msgstr "" + +#: src/app.vala:247 +msgid "Game Options:" +msgstr "تنظیمات بازی:" + +#: src/app.vala:247 +msgid "Show game options help" +msgstr "نمایش راهنمای تنظیمات بازی" + +#: src/app.vala:255 +msgid "Logging Options:" +msgstr "" + +#: src/app.vala:255 +msgid "Show logging options help" +msgstr "" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +msgid "Select executable" +msgstr "" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:181 src/ui/views/GamesView/GamesView.vala:330 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select" +msgstr "انتخاب کنید" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:180 src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Cancel" +msgstr "انصراف" + +#: src/data/Runnable.vala:166 src/ui/widgets/FileChooserEntry.vala:49 +msgid "Select directory" +msgstr "دایرکتوری را انتخاب کنید" + +#: src/data/Runnable.vala:619 +#, c-format +msgid "Part %1$u of %2$u: %3$s" +msgstr "" + +#: src/data/Runnable.vala:642 src/ui/dialogs/CorruptedInstallerDialog.vala:48 +#, c-format +msgid "%s: corrupted installer" +msgstr "" + +#: src/data/Runnable.vala:643 +#, c-format +msgid "Checksum mismatch in %s" +msgstr "" + +#: src/data/Runnable.vala:657 src/ui/dialogs/CorruptedInstallerDialog.vala:126 +msgid "Show file" +msgstr "نمایش فایل" + +#: src/data/Runnable.vala:658 src/ui/dialogs/CorruptedInstallerDialog.vala:132 +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#: src/ui/widgets/TagRow.vala:146 +msgid "Remove" +msgstr "حذف" + +#: src/data/Runnable.vala:659 src/ui/dialogs/CorruptedInstallerDialog.vala:128 +msgid "Backup" +msgstr "پشتیبان گیری" + +#: src/data/Runnable.vala:778 +#, c-format +msgid "%s: cannot detect main executable" +msgstr "" + +#: src/data/Runnable.vala:779 +msgid "" +"Main executable file for this game cannot be detected automatically.\n" +"Please set main executable in game's properties." +msgstr "" + +#: src/data/Runnable.vala:908 +msgctxt "platform" +msgid "Emulated" +msgstr "" + +#: src/data/Game.vala:625 +msgctxt "status" +msgid "Running" +msgstr "در حال اجرا" + +#: src/data/Game.vala:628 +msgctxt "status" +msgid "Installed" +msgstr "نصب شده" + +#: src/data/Game.vala:629 +msgctxt "status" +msgid "Installing" +msgstr "در حال نصب" + +#: src/data/Game.vala:630 +msgctxt "status" +msgid "Verifying installer integrity" +msgstr "" + +#: src/data/Game.vala:631 +msgctxt "status" +msgid "Download started" +msgstr "دانلود شروع شد" + +#: src/data/Game.vala:633 +msgctxt "status" +msgid "Not installed" +msgstr "نصب نشد" + +#: src/data/Game.vala:643 +msgctxt "status_header" +msgid "Installed" +msgstr "نصب شده" + +#: src/data/Game.vala:644 +msgctxt "status_header" +msgid "Installing" +msgstr "در حال نصب" + +#: src/data/Game.vala:646 +msgctxt "status_header" +msgid "Downloading" +msgstr "در حال دانلود" + +#: src/data/Game.vala:648 +msgctxt "status_header" +msgid "Not installed" +msgstr "نصب نشد" + +#: src/data/GameSource.vala:31 +#, c-format +msgid "%s games" +msgstr "%s بازی" + +#: src/data/sources/steam/Steam.vala:43 +msgid "Your SteamID will be read from Steam configuration file" +msgstr "استیم آی‌دی شما از پرونده پیکربندی استیم خوانده می‌شود" + +#: src/data/sources/steam/Steam.vala:46 +msgid "" +"Steam config file not found.\n" +"Login into your account in Steam client and return to GameHub" +msgstr "" +"پرونده پیکربندی استیم یافت نشد.\n" +"وارد حساب کاربری خود در استیم کلاینت شوید و به GameHub بازگردید" + +#: src/data/sources/gog/GOGGame.vala:983 +#, c-format +msgid "DLC: %s" +msgstr "" + +#: src/data/sources/humble/HumbleGame.vala:343 +#, c-format +msgid "%s: no available installers" +msgstr "" + +#: src/data/sources/humble/HumbleGame.vala:344 +msgid "" +"Cannot get Trove download URL.\n" +"Make sure your Humble Monthly subscription is active." +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:192 +#, c-format +msgctxt "itch_dl_status" +msgid "%s left;" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:195 +#, c-format +msgctxt "itch_dl_status" +msgid "%d%%" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:198 +#, c-format +msgctxt "itch_dl_status" +msgid "(%1$s / %2$s)" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:201 +#, c-format +msgctxt "itch_dl_status" +msgid "[%s/s]" +msgstr "" + +#: src/data/sources/user/User.vala:30 +msgid "User games" +msgstr "" + +#: src/data/db/tables/Tags.vala:225 +msgctxt "tag" +msgid "Favorites" +msgstr "مورد علاقه‌ها" + +#: src/data/db/tables/Tags.vala:226 +msgctxt "tag" +msgid "Not installed" +msgstr "نصب نشد" + +#: src/data/db/tables/Tags.vala:227 +msgctxt "tag" +msgid "Installed" +msgstr "نصب شده" + +#: src/data/db/tables/Tags.vala:228 +msgctxt "tag" +msgid "Hidden" +msgstr "" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit script" +msgstr "ویرایش اسکریپت" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit custom script" +msgstr "ویرایش اسکریپت سفارشی" + +#: src/data/compat/Innoextract.vala:55 +#, c-format +msgid "" +"Innoextract %1$s is not supported and may not be able to extract some " +"games correctly.\n" +"Install innoextract %2$s or newer." +msgstr "" + +#: src/data/compat/WineWrap.vala:61 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:242 +#: src/ui/dialogs/CompatRunDialog.vala:102 +#: src/ui/views/GamesView/GameContextMenu.vala:53 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:234 +msgid "Run" +msgstr "اجرا" + +#: src/data/compat/WineWrap.vala:64 +msgid "Show WineWrap menu" +msgstr "نمایش منوی WineWrap" + +#: src/data/compat/WineWrap.vala:67 src/data/compat/Proton.vala:122 +#: src/data/compat/Wine.vala:83 +msgid "Kill apps in prefix" +msgstr "" + +#: src/data/compat/Proton.vala:47 +msgid "Proton prefix" +msgstr "" + +#: src/data/compat/Proton.vala:110 src/data/compat/Wine.vala:71 +msgid "Open prefix directory" +msgstr "" + +#: src/data/compat/Proton.vala:113 src/data/compat/Wine.vala:74 +msgid "Run winecfg" +msgstr "" + +#: src/data/compat/Proton.vala:116 src/data/compat/Wine.vala:77 +msgid "Run winetricks" +msgstr "" + +#: src/data/compat/Proton.vala:119 src/data/compat/Wine.vala:80 +msgid "Run taskmgr" +msgstr "" + +#: src/data/compat/Wine.vala:53 +msgid "Wine prefix" +msgstr "" + +#: src/data/compat/Wine.vala:55 +msgid "Environment variables" +msgstr "" + +#: src/data/compat/Wine.vala:60 +msgid "InnoSetup default options" +msgstr "" + +#: src/data/compat/RetroArch.vala:53 +msgid "Libretro core file" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:43 +msgid "Custom emulator" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:48 +msgid "Emulator" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:49 +msgid "Launch in game directory" +msgstr "راه‌اندازی در دایرکتوری بازی" + +#: src/data/adapters/GamesAdapter.vala:440 +msgctxt "status_header" +msgid "Favorites" +msgstr "مورد علاقه‌ها" + +#: src/data/adapters/GamesAdapter.vala:445 +#, c-format +msgctxt "status_header" +msgid "%s: Favorites" +msgstr "%s: مورد علاقه" + +#: src/data/adapters/GamesAdapter.vala:491 +msgid "Merging games" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:504 +#, c-format +msgid "Merging games from %s" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:551 +#, c-format +msgid "Loading games from %s" +msgstr "بارگیری بازی‌ها از %s" + +#: src/data/adapters/GamesAdapter.vala:678 +msgctxt "sort_mode" +msgid "By name" +msgstr "براساس نام" + +#: src/data/adapters/GamesAdapter.vala:679 +msgctxt "sort_mode" +msgid "By last launch" +msgstr "براساس آخرین راه‌اندازی" + +#: src/data/adapters/GamesAdapter.vala:680 +msgctxt "sort_mode" +msgid "By playtime" +msgstr "براساس زمان بازی" + +#: src/data/adapters/GamesAdapter.vala:705 +msgctxt "group_mode" +msgid "Do not group" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:706 +msgctxt "group_mode" +msgid "By status" +msgstr "براساس وضعیت" + +#: src/data/adapters/GamesAdapter.vala:707 +msgctxt "group_mode" +msgid "By source" +msgstr "براساس منبع" + +#: src/data/providers/images/SteamGridDB.vala:151 +#: src/data/providers/data/IGDB.vala:431 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:217 +msgid "Default" +msgstr "پیش‌فرض" + +#: src/data/providers/images/SteamGridDB.vala:158 +#: src/data/providers/data/IGDB.vala:438 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:225 +msgid "Restore default API key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:169 +#: src/data/providers/data/IGDB.vala:449 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:108 +msgid "API key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:177 +#: src/data/providers/data/IGDB.vala:457 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:53 +msgid "Generate key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:208 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Style" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:209 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Score" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:213 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Author" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:225 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Alternate" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:226 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Blurred" +msgstr "" + +#. TRANSLATORS: Flat / Material Design image style. Probably should not be translated +#: src/data/providers/images/SteamGridDB.vala:228 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Material" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:229 +msgctxt "imagesource_steamgriddb_image_style" +msgid "No logo" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:230 +msgctxt "imagesource_steamgriddb_image_style" +msgid "White logo" +msgstr "" + +#: src/data/providers/data/IGDB.vala:147 +msgid "" +"Monthly IGDB request quota has been reached. Set your own API key to use " +"IGDB data or disable IGDB." +msgstr "" + +#: src/data/providers/data/IGDB.vala:148 +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:40 +#: src/ui/views/WelcomeView.vala:53 src/ui/views/WelcomeView.vala:78 +#: src/ui/views/GamesView/GamesView.vala:230 +#: src/ui/views/GamesView/GamesView.vala:629 +msgid "Settings" +msgstr "تنظیمات" + +#: src/data/providers/data/IGDB.vala:356 +msgctxt "igdb_related_link" +msgid "Official website" +msgstr "وب‌سایت رسمی" + +#: src/data/providers/data/IGDB.vala:469 +msgctxt "igdb_preferred_description" +msgid "When game has description, show description" +msgstr "هنگامی که بازی توضیحی دارد، توضیحات را نشان دهید" + +#: src/data/providers/data/IGDB.vala:476 +msgctxt "igdb_preferred_description" +msgid "of game" +msgstr "" + +#: src/data/providers/data/IGDB.vala:477 +msgctxt "igdb_preferred_description" +msgid "from IGDB" +msgstr "" + +#: src/data/providers/data/IGDB.vala:478 +msgctxt "igdb_preferred_description" +msgid "both" +msgstr "هر دو" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:65 +msgid "Some settings will be applied after application restart" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:71 +msgid "Games directory contains space. It may cause problems for some games" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:36 +msgid "Interface" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:37 +msgid "Appearance" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:38 +msgid "General interface settings" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:48 +msgid "Dark theme" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:53 +msgctxt "icon_style" +msgid "Theme-based" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:54 +msgctxt "icon_style" +msgid "Symbolic" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:55 +msgctxt "icon_style" +msgid "Colored" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:57 +msgctxt "icon_style" +msgid "Icon style" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:84 +msgid "Game card" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:86 +msgid "Show platform icons" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:99 +msgctxt "grid_size" +msgid "Card size" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:117 +msgctxt "grid_size_preset" +msgid "Presets" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:139 +msgid "Games list: installed" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:140 +msgid "Games list: not installed" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:142 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:146 +msgctxt "list_style" +msgid "Show icon" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:143 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:147 +msgctxt "list_style" +msgid "Bold title" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:144 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:148 +msgctxt "list_style" +msgid "Show status" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:149 +msgctxt "list_style" +msgid "Dim" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:151 +#, fuzzy +msgid "Grid options" +msgstr "تنظیمات بازی:" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:152 +msgid "List options" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:31 +msgid "Behavior" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:32 +msgid "Behavior settings" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:42 +msgid "Run games with double click" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:46 +msgid "Merge games from different sources" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:50 +msgid "Use imported tags" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:51 +msgid "General" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:52 +msgid "Collection" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:53 +msgid "Empty" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:65 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:85 +msgid "Collection directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:70 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:78 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:87 +msgid "Game directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:71 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:79 +msgid "Installers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:72 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:98 +msgid "DLC" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:73 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:197 +msgid "Bonus content" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:84 +msgid "Variable syntax: $var or ${var}" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:86 +msgid "Game name" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:88 +#: src/ui/views/GamesView/FiltersPopover.vala:127 +msgid "Platform" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:36 +msgid "Controller" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +msgid "Enabled" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:53 +msgid "Focus GameHub window with Guide button" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:57 +msgid "Controllers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:89 +msgid "Move focus" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:91 +msgid "Exit" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:40 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:108 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:92 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:95 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:36 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:77 +msgid "Disabled" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:47 +#: src/ui/dialogs/GameTweaksDialog.vala:53 +#: src/ui/views/GamesView/GameContextMenu.vala:183 +msgid "Tweaks" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:34 +msgid "Tweak launch options and apply them to games automatically" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:79 +msgid "" +"Tweaks are loaded from following directories in order\n" +"Last tweak overrides previous tweaks with same identifiers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:83 +msgid "Click to open" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:93 +#, c-format +msgid "Tweaks are loaded from %1$s and %2$d more directories (?)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:38 +msgid "Game sources" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +msgid "Steam API keys have limited number of uses per day" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:63 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:57 +msgid "Installation directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:176 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:81 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:34 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:75 +msgid "Not installed" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:116 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:96 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:99 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:85 +msgid "Not authenticated" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +#, c-format +msgid "Authenticated as %s" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:103 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +msgid "Authenticated" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:183 +#: src/ui/dialogs/InstallDialog.vala:53 src/ui/dialogs/InstallDialog.vala:111 +#: src/ui/views/GamesView/GameContextMenu.vala:80 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:233 +#: src/ui/widgets/TweaksList.vala:95 +msgid "Install" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:236 +msgid "Steam API key" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:50 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:54 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:48 +msgid "Games directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:63 +msgid "Logout" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:50 +msgid "Load games from Humble Trove" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:45 +msgid "Emulators" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:45 +msgid "Libretro core directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:46 +msgid "Libretro core info directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:50 +msgid "Ignored libretro cores" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:54 +msgid "Ignored game file extensions" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:66 +msgid "No cores found" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:70 +#, c-format +msgid "%u core found" +msgid_plural "%u cores found" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:46 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:168 +msgid "No custom emulators" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:164 +#, c-format +msgid "%u custom emulator" +msgid_plural "%u custom emulators" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:237 +msgid "Save" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:250 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:312 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/dialogs/GamePropertiesDialog.vala:168 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +#: src/ui/views/GamesView/AddGamePopover.vala:67 +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Executable" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:251 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/views/GamesView/AddGamePopover.vala:68 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Installer" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:256 +#: src/ui/dialogs/GamePropertiesDialog.vala:64 +#: src/ui/dialogs/GamePropertiesDialog.vala:69 +#: src/ui/views/GamesView/AddGamePopover.vala:73 +msgid "Name" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:272 +#: src/ui/dialogs/GamePropertiesDialog.vala:201 +#: src/ui/views/GamesView/AddGamePopover.vala:78 +msgid "Arguments" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:276 +msgid "Variables" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:277 +msgid "Game executable" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:278 +msgid "Game arguments" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:80 +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +msgid "Select emulator directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:292 +#: src/ui/dialogs/GamePropertiesDialog.vala:219 +msgid "Force compatibility mode" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:307 +msgid "Game file patterns" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:315 +msgid "Image" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:318 +msgid "Icon" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:325 +msgid "" +"findutils-compatible glob patterns\n" +"\n" +" Multiple patterns can be separated with |\n" +" Start pattern with ./ to match relative path\n" +" $basename variable will be replaced with game's executable " +"name (without extension)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:38 +msgid "Data" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:39 +msgid "Providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:40 +msgid "Third-party data providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:55 +msgid "Image providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:68 +msgid "Metadata providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:137 +msgid "Open website" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:36 +msgid "About" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:71 +msgid "Copy application version and environment info" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:78 +#: src/ui/views/WelcomeView.vala:57 +msgid "All your games in one place" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:92 +msgctxt "about_link" +msgid "Website" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:96 +msgctxt "about_link" +msgid "Source code on GitHub" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:103 +msgctxt "about_link" +msgid "Report a problem" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:104 +msgctxt "about_link" +msgid "Suggest translations" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:110 +msgctxt "about_link" +msgid "Issues" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:111 +msgctxt "about_link" +msgid "Contributors" +msgstr "" + +#. TRANSLATORS: Likely it should not be translated. GitHub Pulse is a page that shows recent repository activity: https://github.com/tkashkin/GameHub/pulse +#: src/ui/dialogs/SettingsDialog/pages/About.vala:114 +msgctxt "about_link" +msgid "Pulse" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:115 +msgctxt "about_link" +msgid "Forks" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:109 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:129 +msgid "Import" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:110 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:153 +msgid "Download" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:207 +msgid "Select installer" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:216 +#, c-format +msgid "Installer size: %s" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:348 +msgid "Unknown" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:49 +#, c-format +msgid "%s: Properties" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:84 +msgid "Images" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:126 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:160 +#: src/ui/views/GameDetailsView/blocks/Artwork.vala:62 +msgid "Download images" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:144 +msgid "Image URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:148 +msgid "Vertical image URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:157 +msgid "Icon URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +#, fuzzy +msgid "Select working directory" +msgstr "دایرکتوری را انتخاب کنید" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +#, fuzzy +msgid "Working directory" +msgstr "راه‌اندازی در دایرکتوری بازی" + +#: src/ui/dialogs/GamePropertiesDialog.vala:214 +msgid "Compatibility" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:236 +msgid "Launch from terminal" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:252 +msgid "Copy to clipboard" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:254 +msgid "Add to Steam" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:255 +msgid "Add to the Steam library" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:53 +#, c-format +msgid "%s: Overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "Overlays are disabled" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "" +"Enable overlays to manage DLCs and mods\n" +"\n" +"Enabling will move game to the “base“ overlay" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:77 +#: src/ui/views/GamesView/GameContextMenu.vala:175 +msgid "Overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:105 +msgid "Overlay ID (directory name)" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:110 +msgid "Overlay name (optional)" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:112 +msgid "Add" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:127 +msgid "Enable overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:182 +#, c-format +msgid "" +"Overlay usage at this path may be unsafe\n" +"Proceed at your own risk\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:187 +#, c-format +msgid "" +"Overlay usage at this path is not supported\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:266 +msgid "Open directory" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:271 +msgid "Remove overlay" +msgstr "" + +#: src/ui/dialogs/CompatRunDialog.vala:48 +#: src/ui/views/GamesView/GameContextMenu.vala:46 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:235 +msgid "Run with compatibility layer" +msgstr "" + +#: src/ui/dialogs/CorruptedInstallerDialog.vala:71 +msgid "Corrupted installer: checksum mismatch in" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:57 +#: src/ui/views/GamesView/AddGamePopover.vala:105 +msgid "Import emulated games" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:75 +msgid "Select directory with emulated games" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:83 +msgid "Detected games" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:107 +msgid "Select all" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:115 +msgid "Select directory to import" +msgstr "" + +#: src/ui/dialogs/GameTweaksDialog.vala:40 +#, c-format +msgid "%s: Tweaks" +msgstr "" + +#: src/ui/views/WelcomeView.vala:52 +msgid "No enabled game sources" +msgstr "" + +#: src/ui/views/WelcomeView.vala:52 +msgid "Enable some game sources in settings" +msgstr "" + +#: src/ui/views/WelcomeView.vala:57 +msgid "Let's get started" +msgstr "" + +#: src/ui/views/WelcomeView.vala:71 +msgid "Skip" +msgstr "" + +#: src/ui/views/WelcomeView.vala:141 +msgid "Ready" +msgstr "" + +#: src/ui/views/WelcomeView.vala:147 +msgid "Authentication required" +msgstr "" + +#: src/ui/views/WelcomeView.vala:152 +msgid "Authenticating…" +msgstr "" + +#: src/ui/views/WelcomeView.vala:163 +#, c-format +msgid "Install %s" +msgstr "" + +#: src/ui/views/WelcomeView.vala:164 +msgid "Return to GameHub after installing" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "No games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "Get some games or enable some game sources in settings" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:150 +msgid "Grid view" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:151 +msgid "List view" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:159 +msgid "All games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:182 +msgid "Downloads" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:208 +msgid "Filters" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:216 +#: src/ui/views/GamesView/AddGamePopover.vala:84 +msgid "Add game" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:223 +msgid "Search" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:328 +msgid "Menu" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:329 +#: src/ui/views/GameDetailsView/GameDetailsView.vala:104 +msgid "Back" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:550 +#, fuzzy, c-format +msgid "%u game" +msgid_plural "%u games" +msgstr[0] "اجرای بازی" +msgstr[1] "اجرای بازی" + +#: src/ui/views/GamesView/GamesView.vala:553 +#, c-format +msgctxt "games_view_subtitle_filtered_games" +msgid "%1$u / %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:557 +#, c-format +msgctxt "games_view_subtitle" +msgid "%1$s: %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:568 +msgid "No user-added games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:569 +msgid "Add some games using plus button" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:573 +#, c-format +msgid "No %s games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:574 +msgid "Get some Linux-compatible games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:584 +#, c-format +msgid "No games matching “%s”" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:589 +#, c-format +msgid "No %1$s games matching “%2$s”" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:627 +msgid "" +"No games were loaded from Steam. Set your games list privacy to public or " +"use your own Steam API key in settings." +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:628 +msgid "Privacy" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:739 +msgid "Downloading images" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:753 +#, c-format +msgid "Downloading image: %s" +msgstr "" + +#: src/ui/views/GamesView/DownloadProgressView.vala:131 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:162 +msgid "Pause download" +msgstr "" + +#: src/ui/views/GamesView/DownloadProgressView.vala:137 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:168 +msgid "Resume download" +msgstr "" + +#: src/ui/views/GamesView/DownloadProgressView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:174 +msgid "Cancel download" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:77 +msgid "Group" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:102 +msgid "Sort" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:234 +#: src/ui/widgets/GameTagsList.vala:58 +msgid "Tags" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:353 +msgid "All platforms" +msgstr "" + +#: src/ui/views/GamesView/AddGamePopover.vala:77 +msgid "Select game executable" +msgstr "" + +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Select game directory" +msgstr "" + +#: src/ui/views/GamesView/AddGamePopover.vala:111 +msgid "Download game images" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:87 +msgid "Details" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:117 +msgctxt "game_context_menu" +msgid "Favorite" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:121 +msgctxt "game_context_menu" +msgid "Hidden" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:133 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:236 +msgid "Open installation directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:142 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:237 +msgid "Open installers collection directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:151 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:238 +msgid "Open bonus collection directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:160 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:239 +msgid "Open screenshots directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +msgid "Uninstall" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:192 +msgid "Properties" +msgstr "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:100 +#, c-format +msgid "%d game selected" +msgid_plural "%d games selected" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:144 +#, c-format +msgid "%d game will be installed" +msgid_plural "%d games will be installed" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:154 +#, c-format +msgid "%d game will be downloaded" +msgid_plural "%d games will be downloaded" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:161 +#, c-format +msgid "Image for %d game will be searched" +msgid_plural "Images for %d games will be searched" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:168 +#, c-format +msgid "%d game will be uninstalled" +msgid_plural "%d games will be uninstalled" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:174 +msgid "Refresh" +msgstr "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:175 +#, c-format +msgid "" +"%d game will be removed from database. Restart GameHub to fetch new data" +msgid_plural "" +"%d games will be removed from database. Restart GameHub to fetch new data" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:240 +msgid "Open store page" +msgstr "" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:242 +msgid "Game properties" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:46 +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:60 +msgid "Playtime" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:52 +msgid "Playtime (local)" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:69 +msgid "Last launch" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:46 +msgid "Achievements" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:85 +#, c-format +msgid "Unlocked: %s" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:90 +#, c-format +msgid "Global percentage: %g%%" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:77 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:103 +msgid "Language" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:80 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:106 +msgid "Languages" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:147 +#, c-format +msgid "%u DLCs cannot be installed" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:71 +msgid "Category" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:74 +msgid "Categories" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:90 +msgid "Genre" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:93 +msgid "Genres" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:109 +msgctxt "igdb" +msgid "Popularity" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:115 +msgctxt "igdb" +msgid "Aggregated rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:116 +msgctxt "igdb" +msgid "IGDB user rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:117 +msgctxt "igdb" +msgid "Total rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:126 +msgctxt "igdb" +msgid "Release date" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:133 +msgctxt "igdb" +msgid "Platforms" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:139 +msgctxt "igdb" +msgid "Genres" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:145 +msgctxt "igdb" +msgid "Keywords" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:152 +msgctxt "igdb" +msgid "Links" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:208 +#, c-format +msgid "Based on %d rating" +msgid_plural "Based on %d ratings" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:290 +msgctxt "igdb" +msgid "Summary" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:301 +msgctxt "igdb" +msgid "Storyline" +msgstr "" + +#: src/ui/widgets/FileChooserEntry.vala:49 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select file" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "No images" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "" +"There are no images found for this game\n" +"Make sure game name is correct" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:94 +msgid "Search images:" +msgstr "" + +#: src/ui/widgets/CompatToolPicker.vala:53 +msgid "Compatibility layer:" +msgstr "" + +#: src/ui/widgets/CompatToolPicker.vala:92 +msgid "Configure" +msgstr "" + +#: src/ui/widgets/GameTagsList.vala:109 +msgid "Add tag" +msgstr "" + +#: src/ui/widgets/TweaksList.vala:86 +msgid "No description" +msgstr "" + +#: src/ui/widgets/TweaksList.vala:124 +#, fuzzy +msgid "Edit file" +msgstr "ویرایش اسکریپت" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dh" +msgstr "" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dm" +msgstr "" + +#: src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%ds" +msgstr "" + +#: src/settings/UI.vala:153 +msgctxt "grid_size_preset" +msgid "Steam" +msgstr "" + +#: src/settings/UI.vala:154 +msgctxt "grid_size_preset" +msgid "Steam (vertical)" +msgstr "" + +#: src/settings/UI.vala:155 +msgctxt "grid_size_preset" +msgid "GOG" +msgstr "" + +#: src/settings/UI.vala:156 +msgctxt "grid_size_preset" +msgid "GOG (vertical)" +msgstr "" + +#: src/settings/UI.vala:157 +msgctxt "grid_size_preset" +msgid "Square" +msgstr "" + +#: src/settings/UI.vala:158 +msgctxt "grid_size_preset" +msgid "Custom" +msgstr "" + +#: src/utils/downloader/Downloader.vala:200 +msgctxt "dl_status" +msgid "Queued" +msgstr "" + +#: src/utils/downloader/Downloader.vala:201 +msgctxt "dl_status" +msgid "Starting download" +msgstr "" + +#: src/utils/downloader/Downloader.vala:202 +msgctxt "dl_status" +msgid "Download started" +msgstr "" + +#: src/utils/downloader/Downloader.vala:203 +msgctxt "dl_status" +msgid "Download finished" +msgstr "" + +#: src/utils/downloader/Downloader.vala:204 +msgctxt "dl_status" +msgid "Download failed" +msgstr "" + +#: src/utils/downloader/Downloader.vala:208 +#, fuzzy, c-format +msgctxt "dl_status" +msgid "Downloading: %s" +msgstr "در حال دانلود" + +#: src/utils/downloader/Downloader.vala:210 +#, fuzzy +msgctxt "dl_status" +msgid "Downloading" +msgstr "در حال دانلود" + +#: src/utils/downloader/Downloader.vala:214 +#, c-format +msgctxt "dl_status" +msgid "Paused: %s" +msgstr "" + +#: src/utils/downloader/Downloader.vala:216 +msgctxt "dl_status" +msgid "Paused" +msgstr "" + +#: src/utils/downloader/Downloader.vala:218 +msgctxt "dl_status" +msgid "Download cancelled" +msgstr "" + +#. TRANSLATORS: Download progress template. %1$d - percentage, %2$s / %3$s - downloaded portion and total file size, %4$s - download speed +#: src/utils/downloader/Downloader.vala:262 +#, c-format +msgctxt "dl_status" +msgid "%1$d%% (%2$s / %3$s) [%4$s/s]" +msgstr "" diff --git a/po/fi.po b/po/fi.po new file mode 100644 index 00000000..adbbbb4d --- /dev/null +++ b/po/fi.po @@ -0,0 +1,1876 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the com.github.tkashkin.gamehub package. +# Tuomas Lähteenmäki , 2019, 2020. +msgid "" +msgstr "" +"Project-Id-Version: com.github.tkashkin.gamehub\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-26 06:40+0300\n" +"PO-Revision-Date: 2020-03-08 07:22+0000\n" +"Last-Translator: Tuomas Lähteenmäki \n" +"Language-Team: Finnish \n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.0-dev\n" + +#: src/app.vala:91 +msgid "Show help" +msgstr "Näytä ohje" + +#: src/app.vala:92 +msgid "Show application version and exit" +msgstr "Näytä ohjelmiston versio ja sulje" + +#: src/app.vala:93 +msgid "Restart with GDB debugger attached" +msgstr "Käynnistä uudelleen kun GDB-virheenkorjain on liitetty" + +#: src/app.vala:94 +msgid "Show full GDB backtrace" +msgstr "Näytä GDB-jälkiseuranta kokonaan" + +#: src/app.vala:95 +msgid "Treat fatal errors as criticals and crash application" +msgstr "Kohtele kohtalokkaita virheitä kriittisinä ja kaada sovellus" + +#: src/app.vala:99 +msgid "Show main window" +msgstr "Näytä pääikkuna" + +#: src/app.vala:100 +msgid "Show application settings dialog" +msgstr "Näytä sovellusasetukset-valintaikkuna" + +#: src/app.vala:101 +msgid "Show about dialog" +msgstr "Näytä tietoja valintaikkuna" + +#: src/app.vala:102 +msgid "Maximum number of background worker threads" +msgstr "Taustalla työskentelevien säikeiden enimmäismäärä" + +#: src/app.vala:106 +msgid "Run game" +msgstr "Käynnistä peli" + +#: src/app.vala:107 +msgid "Show compatibility options dialog" +msgstr "Näytä yhteensopivuusasetukset-valintaikkuna" + +#: src/app.vala:108 +msgid "Open game details" +msgstr "Avaa pelin lisätiedot" + +#: src/app.vala:109 +msgid "Open game properties" +msgstr "Avaa pelin ominaisuudet" + +#: src/app.vala:113 +msgid "Enable debug logging" +msgstr "Ota virheenkorjaus käyttöön" + +#: src/app.vala:114 +msgid "" +"Log authentication process and sensitive information like authentication " +"tokens" +msgstr "" +"Kirjaa lokiin tunnistusprosessi ja arkaluontoiset tiedot, kuten " +"todennuslomakkeet" + +#: src/app.vala:115 +msgid "Log download manager" +msgstr "Lokita latausten hallinta" + +#: src/app.vala:116 +msgid "Log background workers start/stop" +msgstr "Lokita taustalla aloita/lopeta" + +#: src/app.vala:117 +msgid "Disable log messages filtering" +msgstr "Poista loki sanomien suodatus käytöstä" + +#: src/app.vala:118 +msgid "Verbose logging" +msgstr "Selväkielinen kirjaaminen lokiin" + +#: src/app.vala:247 +msgid "Game Options:" +msgstr "Pelin asetukset:" + +#: src/app.vala:247 +msgid "Show game options help" +msgstr "Näytä pelin asetuksien ohje" + +#: src/app.vala:255 +msgid "Logging Options:" +msgstr "Lokituksen asetukset:" + +#: src/app.vala:255 +msgid "Show logging options help" +msgstr "Näytä kirjaus asetuksien ohje" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +msgid "Select executable" +msgstr "Valitse suoritettava tiedosto" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:181 src/ui/views/GamesView/GamesView.vala:330 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select" +msgstr "Valitse" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:180 src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Cancel" +msgstr "Peruuta" + +#: src/data/Runnable.vala:166 src/ui/widgets/FileChooserEntry.vala:49 +msgid "Select directory" +msgstr "Valitse hakemisto" + +#: src/data/Runnable.vala:619 +#, c-format +msgid "Part %1$u of %2$u: %3$s" +msgstr "Osa %1$u / %2$u: %3$s" + +#: src/data/Runnable.vala:642 src/ui/dialogs/CorruptedInstallerDialog.vala:48 +#, c-format +msgid "%s: corrupted installer" +msgstr "%s: viallinen asennusohjelma" + +#: src/data/Runnable.vala:643 +#, c-format +msgid "Checksum mismatch in %s" +msgstr "Tarkistussumma on ristiriitainen %s" + +#: src/data/Runnable.vala:657 src/ui/dialogs/CorruptedInstallerDialog.vala:126 +msgid "Show file" +msgstr "Näytä tiedosto" + +#: src/data/Runnable.vala:658 src/ui/dialogs/CorruptedInstallerDialog.vala:132 +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#: src/ui/widgets/TagRow.vala:146 +msgid "Remove" +msgstr "Poista" + +#: src/data/Runnable.vala:659 src/ui/dialogs/CorruptedInstallerDialog.vala:128 +msgid "Backup" +msgstr "Varmuuskopioi" + +#: src/data/Runnable.vala:778 +#, c-format +msgid "%s: cannot detect main executable" +msgstr "%s: ei havaitse suoritettavaa tiedostoa" + +#: src/data/Runnable.vala:779 +msgid "" +"Main executable file for this game cannot be detected automatically.\n" +"Please set main executable in game's properties." +msgstr "" +"Tämän pelin suoritettavaa tiedostoa ei voida tunnistaa automaattisesti.\n" +"Aseta suoritettava tiedosto pelin ominaisuuksista." + +#: src/data/Runnable.vala:908 +msgctxt "platform" +msgid "Emulated" +msgstr "Emuloitu" + +#: src/data/Game.vala:625 +msgctxt "status" +msgid "Running" +msgstr "Käynnissä" + +#: src/data/Game.vala:628 +msgctxt "status" +msgid "Installed" +msgstr "Asennettu" + +#: src/data/Game.vala:629 +msgctxt "status" +msgid "Installing" +msgstr "Asentaa" + +#: src/data/Game.vala:630 +msgctxt "status" +msgid "Verifying installer integrity" +msgstr "Tarkistaa asennuksen eheyttä" + +#: src/data/Game.vala:631 +msgctxt "status" +msgid "Download started" +msgstr "Lataus aloitettu" + +#: src/data/Game.vala:633 +msgctxt "status" +msgid "Not installed" +msgstr "Ei asennettu" + +#: src/data/Game.vala:643 +msgctxt "status_header" +msgid "Installed" +msgstr "Asennettu" + +#: src/data/Game.vala:644 +msgctxt "status_header" +msgid "Installing" +msgstr "Asentaa" + +#: src/data/Game.vala:646 +msgctxt "status_header" +msgid "Downloading" +msgstr "Lataa" + +#: src/data/Game.vala:648 +msgctxt "status_header" +msgid "Not installed" +msgstr "Ei asennettu" + +#: src/data/GameSource.vala:31 +#, c-format +msgid "%s games" +msgstr "%s pelit" + +#: src/data/sources/steam/Steam.vala:43 +msgid "Your SteamID will be read from Steam configuration file" +msgstr "SteamID-tunnuksesi luetaan Steam-määritystiedostosta" + +#: src/data/sources/steam/Steam.vala:46 +msgid "" +"Steam config file not found.\n" +"Login into your account in Steam client and return to GameHub" +msgstr "" +"Steamin konfiguraatiotiedostoa ei löydy.\n" +"Kirjaudu tiliisi Steam-asiakasohjelmassa ja palaa GameHub ohjelmaan" + +#: src/data/sources/gog/GOGGame.vala:983 +#, c-format +msgid "DLC: %s" +msgstr "Lisäosa: %s" + +#: src/data/sources/humble/HumbleGame.vala:343 +#, c-format +msgid "%s: no available installers" +msgstr "%s: ei käytettävissä olevaa asennusohjelmaa" + +#: src/data/sources/humble/HumbleGame.vala:344 +msgid "" +"Cannot get Trove download URL.\n" +"Make sure your Humble Monthly subscription is active." +msgstr "" +"Troven lataus URL-osoitetta ei saada.\n" +"Varmista, että Humble Monthly -tilaus on aktiivinen." + +#: src/data/sources/itch/ItchDownloader.vala:192 +#, c-format +msgctxt "itch_dl_status" +msgid "%s left;" +msgstr "%s jäljellä;" + +#: src/data/sources/itch/ItchDownloader.vala:195 +#, c-format +msgctxt "itch_dl_status" +msgid "%d%%" +msgstr "%d%%" + +#: src/data/sources/itch/ItchDownloader.vala:198 +#, c-format +msgctxt "itch_dl_status" +msgid "(%1$s / %2$s)" +msgstr "(%1$s / %2$s)" + +#: src/data/sources/itch/ItchDownloader.vala:201 +#, c-format +msgctxt "itch_dl_status" +msgid "[%s/s]" +msgstr "[%s/s]" + +#: src/data/sources/user/User.vala:30 +msgid "User games" +msgstr "Käyttäjän pelit" + +#: src/data/db/tables/Tags.vala:225 +msgctxt "tag" +msgid "Favorites" +msgstr "Suosikit" + +#: src/data/db/tables/Tags.vala:226 +msgctxt "tag" +msgid "Not installed" +msgstr "Ei asennettu" + +#: src/data/db/tables/Tags.vala:227 +msgctxt "tag" +msgid "Installed" +msgstr "Asennettu" + +#: src/data/db/tables/Tags.vala:228 +msgctxt "tag" +msgid "Hidden" +msgstr "Piilotettu" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit script" +msgstr "Muokkaa skriptiä" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit custom script" +msgstr "Muokkaa mukautettua skriptiä" + +#: src/data/compat/Innoextract.vala:55 +#, c-format +msgid "" +"Innoextract %1$s is not supported and may not be able to extract some " +"games correctly.\n" +"Install innoextract %2$s or newer." +msgstr "" +"Innoextract %1$s sovellusta ei tueta ja se ei ehkä pysty purkamaan " +"joitain pelejä oikein.\n" +"Asenna innoextract %2$s tai uudempi." + +#: src/data/compat/WineWrap.vala:61 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:242 +#: src/ui/dialogs/CompatRunDialog.vala:102 +#: src/ui/views/GamesView/GameContextMenu.vala:53 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:234 +msgid "Run" +msgstr "Käynnistä" + +#: src/data/compat/WineWrap.vala:64 +msgid "Show WineWrap menu" +msgstr "Näytä WineWrap-valikko" + +#: src/data/compat/WineWrap.vala:67 src/data/compat/Proton.vala:122 +#: src/data/compat/Wine.vala:83 +msgid "Kill apps in prefix" +msgstr "Tapa sovellukset prefixistä" + +#: src/data/compat/Proton.vala:47 +msgid "Proton prefix" +msgstr "Proton prefiksi" + +#: src/data/compat/Proton.vala:110 src/data/compat/Wine.vala:71 +msgid "Open prefix directory" +msgstr "Avaa prefix hakemisto" + +#: src/data/compat/Proton.vala:113 src/data/compat/Wine.vala:74 +msgid "Run winecfg" +msgstr "Käynnistä winecfg" + +#: src/data/compat/Proton.vala:116 src/data/compat/Wine.vala:77 +msgid "Run winetricks" +msgstr "Käynnistä winetricks" + +#: src/data/compat/Proton.vala:119 src/data/compat/Wine.vala:80 +msgid "Run taskmgr" +msgstr "Käynnistä tehtävämanageri" + +#: src/data/compat/Wine.vala:53 +msgid "Wine prefix" +msgstr "Winen prefix" + +#: src/data/compat/Wine.vala:55 +msgid "Environment variables" +msgstr "Ympäristömuuttujat" + +#: src/data/compat/Wine.vala:60 +msgid "InnoSetup default options" +msgstr "InnoSetupin oletusasetukset" + +#: src/data/compat/RetroArch.vala:53 +msgid "Libretro core file" +msgstr "Libretro core tiedosto" + +#: src/data/compat/CustomEmulator.vala:43 +msgid "Custom emulator" +msgstr "Mukautettu emulaattori" + +#: src/data/compat/CustomEmulator.vala:48 +msgid "Emulator" +msgstr "Emulaattori" + +#: src/data/compat/CustomEmulator.vala:49 +msgid "Launch in game directory" +msgstr "Käynnistä pelihakemistossa" + +#: src/data/adapters/GamesAdapter.vala:440 +msgctxt "status_header" +msgid "Favorites" +msgstr "Suosikit" + +#: src/data/adapters/GamesAdapter.vala:445 +#, c-format +msgctxt "status_header" +msgid "%s: Favorites" +msgstr "%s: Suosikkeja" + +#: src/data/adapters/GamesAdapter.vala:491 +msgid "Merging games" +msgstr "Pelien yhdistäminen" + +#: src/data/adapters/GamesAdapter.vala:504 +#, c-format +msgid "Merging games from %s" +msgstr "Pelien yhdistäminen %s" + +#: src/data/adapters/GamesAdapter.vala:551 +#, c-format +msgid "Loading games from %s" +msgstr "Ladataan pelejä %s" + +#: src/data/adapters/GamesAdapter.vala:678 +msgctxt "sort_mode" +msgid "By name" +msgstr "Nimeltä" + +#: src/data/adapters/GamesAdapter.vala:679 +msgctxt "sort_mode" +msgid "By last launch" +msgstr "Viimeisen käynnistyksen mukaan" + +#: src/data/adapters/GamesAdapter.vala:680 +msgctxt "sort_mode" +msgid "By playtime" +msgstr "Peliajan" + +#: src/data/adapters/GamesAdapter.vala:705 +msgctxt "group_mode" +msgid "Do not group" +msgstr "Älä ryhmitä" + +#: src/data/adapters/GamesAdapter.vala:706 +msgctxt "group_mode" +msgid "By status" +msgstr "Tila" + +#: src/data/adapters/GamesAdapter.vala:707 +msgctxt "group_mode" +msgid "By source" +msgstr "Lähteen" + +#: src/data/providers/images/SteamGridDB.vala:151 +#: src/data/providers/data/IGDB.vala:431 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:217 +msgid "Default" +msgstr "Oletus" + +#: src/data/providers/images/SteamGridDB.vala:158 +#: src/data/providers/data/IGDB.vala:438 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:225 +msgid "Restore default API key" +msgstr "Palauta oletus API-avain" + +#: src/data/providers/images/SteamGridDB.vala:169 +#: src/data/providers/data/IGDB.vala:449 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:108 +msgid "API key" +msgstr "API-avain" + +#: src/data/providers/images/SteamGridDB.vala:177 +#: src/data/providers/data/IGDB.vala:457 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:53 +msgid "Generate key" +msgstr "Generoi avain" + +#: src/data/providers/images/SteamGridDB.vala:208 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Style" +msgstr "Tyyli" + +#: src/data/providers/images/SteamGridDB.vala:209 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Score" +msgstr "Pisteet" + +#: src/data/providers/images/SteamGridDB.vala:213 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Author" +msgstr "Tekijä" + +#: src/data/providers/images/SteamGridDB.vala:225 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Alternate" +msgstr "Vaihtoehtoinen" + +#: src/data/providers/images/SteamGridDB.vala:226 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Blurred" +msgstr "Sumennettu" + +#. TRANSLATORS: Flat / Material Design image style. Probably should not be translated +#: src/data/providers/images/SteamGridDB.vala:228 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Material" +msgstr "Materiaali" + +#: src/data/providers/images/SteamGridDB.vala:229 +msgctxt "imagesource_steamgriddb_image_style" +msgid "No logo" +msgstr "Ei logoa" + +#: src/data/providers/images/SteamGridDB.vala:230 +msgctxt "imagesource_steamgriddb_image_style" +msgid "White logo" +msgstr "Valkoinen logo" + +#: src/data/providers/data/IGDB.vala:147 +msgid "" +"Monthly IGDB request quota has been reached. Set your own API key to use " +"IGDB data or disable IGDB." +msgstr "" +"Kuukausittainen IGDB-pyyntökiintiö on saavutettu. Aseta oma API-avaimesi " +"käyttämään IGDB-tietoja tai poista IGDB käytöstä." + +#: src/data/providers/data/IGDB.vala:148 +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:40 +#: src/ui/views/WelcomeView.vala:53 src/ui/views/WelcomeView.vala:78 +#: src/ui/views/GamesView/GamesView.vala:230 +#: src/ui/views/GamesView/GamesView.vala:629 +msgid "Settings" +msgstr "Asetukset" + +#: src/data/providers/data/IGDB.vala:356 +msgctxt "igdb_related_link" +msgid "Official website" +msgstr "Virallinen kotisivu" + +#: src/data/providers/data/IGDB.vala:469 +msgctxt "igdb_preferred_description" +msgid "When game has description, show description" +msgstr "Kun pelillä on kuvaus, näytä kuvaus" + +#: src/data/providers/data/IGDB.vala:476 +msgctxt "igdb_preferred_description" +msgid "of game" +msgstr "pelin" + +#: src/data/providers/data/IGDB.vala:477 +msgctxt "igdb_preferred_description" +msgid "from IGDB" +msgstr "IGDB" + +#: src/data/providers/data/IGDB.vala:478 +msgctxt "igdb_preferred_description" +msgid "both" +msgstr "molemmat" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:65 +msgid "Some settings will be applied after application restart" +msgstr "" +"Jotkut asetukset otetaan käyttöön sovelluksen uudelleenkäynnistyksen jälkeen" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:71 +msgid "Games directory contains space. It may cause problems for some games" +msgstr "" +"Pelihakemiston nimi sisältää tyhjiä merkkejä. Se voi aiheuttaa ongelmia " +"joillekin peleille" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:36 +msgid "Interface" +msgstr "Käyttöliittymä" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:37 +msgid "Appearance" +msgstr "Ulkomuoto" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:38 +msgid "General interface settings" +msgstr "Yleiset käyttöliittymäasetukset" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:48 +msgid "Dark theme" +msgstr "Tumma teema" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:53 +msgctxt "icon_style" +msgid "Theme-based" +msgstr "Teemapohjainen" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:54 +msgctxt "icon_style" +msgid "Symbolic" +msgstr "Symbolinen" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:55 +msgctxt "icon_style" +msgid "Colored" +msgstr "Värillinen" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:57 +msgctxt "icon_style" +msgid "Icon style" +msgstr "Kuvakkeiden tyyli" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:84 +msgid "Game card" +msgstr "Pelikortti tyylinen" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:86 +msgid "Show platform icons" +msgstr "Näytä käyttöjärjestelmien kuvakkeet" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:99 +msgctxt "grid_size" +msgid "Card size" +msgstr "Kortin koko" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:117 +msgctxt "grid_size_preset" +msgid "Presets" +msgstr "Esiasetukset" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:139 +msgid "Games list: installed" +msgstr "Pelilista: asennettu" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:140 +msgid "Games list: not installed" +msgstr "Pelilista: ei asennettu" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:142 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:146 +msgctxt "list_style" +msgid "Show icon" +msgstr "Näytä kuvakkeet" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:143 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:147 +msgctxt "list_style" +msgid "Bold title" +msgstr "Lihavoi pelin nimi" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:144 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:148 +msgctxt "list_style" +msgid "Show status" +msgstr "Näytä tila" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:149 +msgctxt "list_style" +msgid "Dim" +msgstr "Sumenna" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:151 +msgid "Grid options" +msgstr "Ruudukkovaihtoehdot" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:152 +msgid "List options" +msgstr "Listavaihtoehdot" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:31 +msgid "Behavior" +msgstr "Käytös" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:32 +msgid "Behavior settings" +msgstr "Käyttäytymisasetukset" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:42 +msgid "Run games with double click" +msgstr "Käynnistä peli kaksoisnapsautuksella" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:46 +msgid "Merge games from different sources" +msgstr "Yhdistä pelit eri lähteistä" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:50 +msgid "Use imported tags" +msgstr "Käytä tuotuja tunnisteita" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:51 +msgid "General" +msgstr "Yleinen" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:52 +msgid "Collection" +msgstr "Kokoelma" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:53 +msgid "Empty" +msgstr "Tyhjä" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:65 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:85 +msgid "Collection directory" +msgstr "Peli kokoelman hakemisto" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:70 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:78 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:87 +msgid "Game directory" +msgstr "Pelihakemisto" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:71 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:79 +msgid "Installers" +msgstr "Asentajat" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:72 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:98 +msgid "DLC" +msgstr "Lisäosa (DLC)" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:73 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:197 +msgid "Bonus content" +msgstr "Bonus-sisältö" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:84 +msgid "Variable syntax: $var or ${var}" +msgstr "Muuttuva syntaksi: $var tai ${var}" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:86 +msgid "Game name" +msgstr "Pelin nimi" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:88 +#: src/ui/views/GamesView/FiltersPopover.vala:127 +msgid "Platform" +msgstr "Pelialusta" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:36 +msgid "Controller" +msgstr "Ohjain" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +msgid "Enabled" +msgstr "Käytössä" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:53 +msgid "Focus GameHub window with Guide button" +msgstr "Tarkenna GameHub-ikkuna opaspainikkeella" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:57 +msgid "Controllers" +msgstr "Ohjaimet" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:89 +msgid "Move focus" +msgstr "Siirrä tarkennus" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:91 +msgid "Exit" +msgstr "Poistu" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:40 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:108 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:92 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:95 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:36 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:77 +msgid "Disabled" +msgstr "Poistettu käytöstä" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:47 +#: src/ui/dialogs/GameTweaksDialog.vala:53 +#: src/ui/views/GamesView/GameContextMenu.vala:183 +msgid "Tweaks" +msgstr "Hienosäädöt" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:34 +msgid "Tweak launch options and apply them to games automatically" +msgstr "" +"Hienosäädä käynnistysvaihtoehtoja ja käytä niitä peleihin automaattisesti" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:79 +msgid "" +"Tweaks are loaded from following directories in order\n" +"Last tweak overrides previous tweaks with same identifiers" +msgstr "" +"Hienosäädöt ladataan seuraavista hakemistoista järjestyksessä\n" +"Viimeinen sääntö ohittaa aiemman tarkistuksen samoilla tunnisteilla" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:83 +msgid "Click to open" +msgstr "Avaa napsauttamalla" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:93 +#, c-format +msgid "Tweaks are loaded from %1$s and %2$d more directories (?)" +msgstr "" +"Pelien hienosäädöt on ladattu %1$s ja %2$d ja muusta hakemistosta " +"(?)" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:38 +msgid "Game sources" +msgstr "Pelilähteet" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +msgid "Steam API keys have limited number of uses per day" +msgstr "Steam API-avaimilla on rajoitettu määrä käyttöjä päivässä" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:63 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:57 +msgid "Installation directory" +msgstr "Asennushakemisto" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:176 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:81 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:34 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:75 +msgid "Not installed" +msgstr "Ei asennettu" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:116 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:96 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:99 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:85 +msgid "Not authenticated" +msgstr "Ei todennettu" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +#, c-format +msgid "Authenticated as %s" +msgstr "Todennettu nimellä %s" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:103 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +msgid "Authenticated" +msgstr "Todennettu" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:183 +#: src/ui/dialogs/InstallDialog.vala:53 src/ui/dialogs/InstallDialog.vala:111 +#: src/ui/views/GamesView/GameContextMenu.vala:80 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:233 +#: src/ui/widgets/TweaksList.vala:95 +msgid "Install" +msgstr "Asenna" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:236 +msgid "Steam API key" +msgstr "Steam API-avain" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:50 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:54 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:48 +msgid "Games directory" +msgstr "Pelien hakemisto" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:63 +msgid "Logout" +msgstr "Kirjaudu ulos" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:50 +msgid "Load games from Humble Trove" +msgstr "Lataa pelit Humble Trovesta" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:45 +msgid "Emulators" +msgstr "Emulaattorit" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:45 +msgid "Libretro core directory" +msgstr "Libretro core hakemisto" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:46 +msgid "Libretro core info directory" +msgstr "Libretro core info hakemisto" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:50 +msgid "Ignored libretro cores" +msgstr "Sivuuta libretro ytimiä" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:54 +msgid "Ignored game file extensions" +msgstr "Ohita pelilaajennokset" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:66 +msgid "No cores found" +msgstr "Ytimiä ei löytynyt" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:70 +#, c-format +msgid "%u core found" +msgid_plural "%u cores found" +msgstr[0] "%u ydin löydetty" +msgstr[1] "%u ydintä löydetty" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:46 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:168 +msgid "No custom emulators" +msgstr "Ei räätälöityjä emulaattoreita" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:164 +#, c-format +msgid "%u custom emulator" +msgid_plural "%u custom emulators" +msgstr[0] "%u kustomoitu emulaattoria" +msgstr[1] "%u kustomoitua emulaattoria" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:237 +msgid "Save" +msgstr "Tallenna" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:250 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:312 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/dialogs/GamePropertiesDialog.vala:168 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +#: src/ui/views/GamesView/AddGamePopover.vala:67 +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Executable" +msgstr "Suoritettava" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:251 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/views/GamesView/AddGamePopover.vala:68 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Installer" +msgstr "Asentaja" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:256 +#: src/ui/dialogs/GamePropertiesDialog.vala:64 +#: src/ui/dialogs/GamePropertiesDialog.vala:69 +#: src/ui/views/GamesView/AddGamePopover.vala:73 +msgid "Name" +msgstr "Nimi" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:272 +#: src/ui/dialogs/GamePropertiesDialog.vala:201 +#: src/ui/views/GamesView/AddGamePopover.vala:78 +msgid "Arguments" +msgstr "Käynnistysasetukset" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:276 +msgid "Variables" +msgstr "Muuttujat" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:277 +msgid "Game executable" +msgstr "Pelin suoritettava tiedosto" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:278 +msgid "Game arguments" +msgstr "Pelin käynnistys asetukset" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:80 +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Directory" +msgstr "Hakemisto" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +msgid "Select emulator directory" +msgstr "Valitse emulaattorin hakemisto" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:292 +#: src/ui/dialogs/GamePropertiesDialog.vala:219 +msgid "Force compatibility mode" +msgstr "Pakota yhteensopivuustila" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:307 +msgid "Game file patterns" +msgstr "Pelitiedostokuviot" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:315 +msgid "Image" +msgstr "Kuva" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:318 +msgid "Icon" +msgstr "Kuvake" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:325 +msgid "" +"findutils-compatible glob patterns\n" +"\n" +" Multiple patterns can be separated with |\n" +" Start pattern with ./ to match relative path\n" +" $basename variable will be replaced with game's executable " +"name (without extension)" +msgstr "" +"findutils-yhteensopivat polut\n" +"\n" +" Useita tiedostopäätteitä voidaan erottaa |-merkillä\n" +" Aloita tiedostopääte merkillä./vastaamaan suhteellista " +"polkua\n" +" $basenamemuuttuja korvataan pelin suoritettavalla nimellä " +"(ilman laajennusta)" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:38 +msgid "Data" +msgstr "Data" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:39 +msgid "Providers" +msgstr "Tarjoajat" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:40 +msgid "Third-party data providers" +msgstr "Kolmansien osapuolten tietojen tarjoajat" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:55 +msgid "Image providers" +msgstr "Kuvien tarjoajat" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:68 +msgid "Metadata providers" +msgstr "Metatietojen tarjoajat" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:137 +msgid "Open website" +msgstr "Avaa www-sivu" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:36 +msgid "About" +msgstr "Tietoja" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:71 +msgid "Copy application version and environment info" +msgstr "Kopioi sovellusversio ja ympäristöntiedot" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:78 +#: src/ui/views/WelcomeView.vala:57 +msgid "All your games in one place" +msgstr "Kaikki pelisi yhdessä paikassa" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:92 +msgctxt "about_link" +msgid "Website" +msgstr "WWW-sivu" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:96 +msgctxt "about_link" +msgid "Source code on GitHub" +msgstr "Lähdekoodi GitHubissa" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:103 +msgctxt "about_link" +msgid "Report a problem" +msgstr "Raportoi ongelma" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:104 +msgctxt "about_link" +msgid "Suggest translations" +msgstr "Ehdota käännöstä" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:110 +msgctxt "about_link" +msgid "Issues" +msgstr "Kysymykset" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:111 +msgctxt "about_link" +msgid "Contributors" +msgstr "Osallistujat" + +#. TRANSLATORS: Likely it should not be translated. GitHub Pulse is a page that shows recent repository activity: https://github.com/tkashkin/GameHub/pulse +#: src/ui/dialogs/SettingsDialog/pages/About.vala:114 +msgctxt "about_link" +msgid "Pulse" +msgstr "Pulssi" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:115 +msgctxt "about_link" +msgid "Forks" +msgstr "Haaraumat" + +#: src/ui/dialogs/InstallDialog.vala:109 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:129 +msgid "Import" +msgstr "Tuo" + +#: src/ui/dialogs/InstallDialog.vala:110 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:153 +msgid "Download" +msgstr "Lataa" + +#: src/ui/dialogs/InstallDialog.vala:207 +msgid "Select installer" +msgstr "Valitse asentaja" + +#: src/ui/dialogs/InstallDialog.vala:216 +#, c-format +msgid "Installer size: %s" +msgstr "Asentajan koko: %s" + +#: src/ui/dialogs/InstallDialog.vala:348 +msgid "Unknown" +msgstr "Tuntematon" + +#: src/ui/dialogs/GamePropertiesDialog.vala:49 +#, c-format +msgid "%s: Properties" +msgstr "%s: ominaisuudet" + +#: src/ui/dialogs/GamePropertiesDialog.vala:84 +msgid "Images" +msgstr "Kuvat" + +#: src/ui/dialogs/GamePropertiesDialog.vala:126 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:160 +#: src/ui/views/GameDetailsView/blocks/Artwork.vala:62 +msgid "Download images" +msgstr "Ladataan kuvia" + +#: src/ui/dialogs/GamePropertiesDialog.vala:144 +msgid "Image URL" +msgstr "Kuvan URL" + +#: src/ui/dialogs/GamePropertiesDialog.vala:148 +msgid "Vertical image URL" +msgstr "Pystykuvan URL" + +#: src/ui/dialogs/GamePropertiesDialog.vala:157 +msgid "Icon URL" +msgstr "Kuvakkeen URL" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Select working directory" +msgstr "Valitse työhakemisto" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Working directory" +msgstr "Työhakemisto" + +#: src/ui/dialogs/GamePropertiesDialog.vala:214 +msgid "Compatibility" +msgstr "Yhteensopivuus" + +#: src/ui/dialogs/GamePropertiesDialog.vala:236 +msgid "Launch from terminal" +msgstr "Käynnistä terminaalista" + +#: src/ui/dialogs/GamePropertiesDialog.vala:252 +msgid "Copy to clipboard" +msgstr "Kopioi leikepöydälle" + +#: src/ui/dialogs/GamePropertiesDialog.vala:254 +msgid "Add to Steam" +msgstr "Lisää Steamiin" + +#: src/ui/dialogs/GamePropertiesDialog.vala:255 +msgid "Add to the Steam library" +msgstr "Lisää Steamin kirjastoon" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:53 +#, c-format +msgid "%s: Overlays" +msgstr "%s: Päällekkäiskuvat" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "Overlays are disabled" +msgstr "Päällekkäiskuvat on poissa käytöstä" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "" +"Enable overlays to manage DLCs and mods\n" +"\n" +"Enabling will move game to the “base“ overlay" +msgstr "" +"Ota peittokuvat käyttöön lisäosien (DLC) ja modien hallitsemiseksi\n" +"\n" +"Aktivointi siirtää pelin ”base” -peittokuvaan" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:77 +#: src/ui/views/GamesView/GameContextMenu.vala:175 +msgid "Overlays" +msgstr "Peittokuvat" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:105 +msgid "Overlay ID (directory name)" +msgstr "Peittokuvan ID (hakemiston nimi)" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:110 +msgid "Overlay name (optional)" +msgstr "Peittokuvan nimi (valinnainen)" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:112 +msgid "Add" +msgstr "Lisää" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:127 +msgid "Enable overlays" +msgstr "Ota peittokuvat käyttöön" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:182 +#, c-format +msgid "" +"Overlay usage at this path may be unsafe\n" +"Proceed at your own risk\n" +"\n" +"Path: %s" +msgstr "" +"Peittokuvan käyttö tällä polulla voi olla vaarallista\n" +"Jatka omalla vastuulla\n" +"\n" +"Polku: %s" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:187 +#, c-format +msgid "" +"Overlay usage at this path is not supported\n" +"\n" +"Path: %s" +msgstr "" +"Peittokuvan käyttöä tällä polulla ei tueta\n" +"\n" +"Polku: %s" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:266 +msgid "Open directory" +msgstr "Avaa hakemisto" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:271 +msgid "Remove overlay" +msgstr "Poista peittokuva" + +#: src/ui/dialogs/CompatRunDialog.vala:48 +#: src/ui/views/GamesView/GameContextMenu.vala:46 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:235 +msgid "Run with compatibility layer" +msgstr "Suorita yhteensopivuuskerroksen kanssa" + +#: src/ui/dialogs/CorruptedInstallerDialog.vala:71 +msgid "Corrupted installer: checksum mismatch in" +msgstr "Vioittunut asentaja: tarkistussumman epäsuhta" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:57 +#: src/ui/views/GamesView/AddGamePopover.vala:105 +msgid "Import emulated games" +msgstr "Tuo emuloidut pelit" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:75 +msgid "Select directory with emulated games" +msgstr "Valitse hakemisto emuloiduille peleille" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:83 +msgid "Detected games" +msgstr "Havaitut pelit" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:107 +msgid "Select all" +msgstr "Valitse kaikki" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:115 +msgid "Select directory to import" +msgstr "Valitse tuotava hakemisto" + +#: src/ui/dialogs/GameTweaksDialog.vala:40 +#, c-format +msgid "%s: Tweaks" +msgstr "%s: Hienosäädöt" + +#: src/ui/views/WelcomeView.vala:52 +msgid "No enabled game sources" +msgstr "Ei pelilähteitä käytössä" + +#: src/ui/views/WelcomeView.vala:52 +msgid "Enable some game sources in settings" +msgstr "Ota joitain pelilähteitä käyttöön asetuksissa" + +#: src/ui/views/WelcomeView.vala:57 +msgid "Let's get started" +msgstr "Aloitetaan" + +#: src/ui/views/WelcomeView.vala:71 +msgid "Skip" +msgstr "Ohita" + +#: src/ui/views/WelcomeView.vala:141 +msgid "Ready" +msgstr "Valmis" + +#: src/ui/views/WelcomeView.vala:147 +msgid "Authentication required" +msgstr "Todennus vaaditaan" + +#: src/ui/views/WelcomeView.vala:152 +msgid "Authenticating…" +msgstr "Todennetaan…" + +#: src/ui/views/WelcomeView.vala:163 +#, c-format +msgid "Install %s" +msgstr "Asentaa %s" + +#: src/ui/views/WelcomeView.vala:164 +msgid "Return to GameHub after installing" +msgstr "Palaa GameHubiin asennuksen jälkeen" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "No games" +msgstr "Ei pelejä" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "Get some games or enable some game sources in settings" +msgstr "Hanki joitain pelejä tai ota käyttöön pelilähteet asetuksissa" + +#: src/ui/views/GamesView/GamesView.vala:150 +msgid "Grid view" +msgstr "Ruudukkonäkymä" + +#: src/ui/views/GamesView/GamesView.vala:151 +msgid "List view" +msgstr "Listanäkymä" + +#: src/ui/views/GamesView/GamesView.vala:159 +msgid "All games" +msgstr "Kaikki pelit" + +#: src/ui/views/GamesView/GamesView.vala:182 +msgid "Downloads" +msgstr "Lataukset" + +#: src/ui/views/GamesView/GamesView.vala:208 +msgid "Filters" +msgstr "Filtterit" + +#: src/ui/views/GamesView/GamesView.vala:216 +#: src/ui/views/GamesView/AddGamePopover.vala:84 +msgid "Add game" +msgstr "Lisää peli" + +#: src/ui/views/GamesView/GamesView.vala:223 +msgid "Search" +msgstr "Etsi" + +#: src/ui/views/GamesView/GamesView.vala:328 +msgid "Menu" +msgstr "Valikko" + +#: src/ui/views/GamesView/GamesView.vala:329 +#: src/ui/views/GameDetailsView/GameDetailsView.vala:104 +msgid "Back" +msgstr "Takaisin" + +#: src/ui/views/GamesView/GamesView.vala:550 +#, c-format +msgid "%u game" +msgid_plural "%u games" +msgstr[0] "%u peli" +msgstr[1] "%u peliä" + +#: src/ui/views/GamesView/GamesView.vala:553 +#, c-format +msgctxt "games_view_subtitle_filtered_games" +msgid "%1$u / %2$s" +msgstr "%1$u / %2$s" + +#: src/ui/views/GamesView/GamesView.vala:557 +#, c-format +msgctxt "games_view_subtitle" +msgid "%1$s: %2$s" +msgstr "%1$s: %2$s" + +#: src/ui/views/GamesView/GamesView.vala:568 +msgid "No user-added games" +msgstr "Ei käyttäjän lisäämiä pelejä" + +#: src/ui/views/GamesView/GamesView.vala:569 +msgid "Add some games using plus button" +msgstr "Lisää joitain pelejä plus-painikkeella" + +#: src/ui/views/GamesView/GamesView.vala:573 +#, c-format +msgid "No %s games" +msgstr "Ei %s peliä" + +#: src/ui/views/GamesView/GamesView.vala:574 +msgid "Get some Linux-compatible games" +msgstr "Hanki joitain Linux-yhteensopivia pelejä" + +#: src/ui/views/GamesView/GamesView.vala:584 +#, c-format +msgid "No games matching “%s”" +msgstr "Ei pelejä, jotka vastaavat“%s”" + +#: src/ui/views/GamesView/GamesView.vala:589 +#, c-format +msgid "No %1$s games matching “%2$s”" +msgstr "Ei %1$s peliä, jotka vastaavat “%2$s”" + +#: src/ui/views/GamesView/GamesView.vala:627 +msgid "" +"No games were loaded from Steam. Set your games list privacy to public or " +"use your own Steam API key in settings." +msgstr "" +"Steamistä ei ladattu mitään pelejä. Aseta peliluettelosi yksityisyys " +"julkiseksi tai käytä omaa Steam API -avainta asetuksissa." + +#: src/ui/views/GamesView/GamesView.vala:628 +msgid "Privacy" +msgstr "Yksityisyys" + +#: src/ui/views/GamesView/GamesView.vala:739 +msgid "Downloading images" +msgstr "Kuvien lataaminen" + +#: src/ui/views/GamesView/GamesView.vala:753 +#, c-format +msgid "Downloading image: %s" +msgstr "Ladataan kuvaa: %s" + +#: src/ui/views/GamesView/DownloadProgressView.vala:131 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:162 +msgid "Pause download" +msgstr "Keskeytä lataus" + +#: src/ui/views/GamesView/DownloadProgressView.vala:137 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:168 +msgid "Resume download" +msgstr "Jatka lataamista" + +#: src/ui/views/GamesView/DownloadProgressView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:174 +msgid "Cancel download" +msgstr "Peruuta lataus" + +#: src/ui/views/GamesView/FiltersPopover.vala:77 +msgid "Group" +msgstr "Ryhmä" + +#: src/ui/views/GamesView/FiltersPopover.vala:102 +msgid "Sort" +msgstr "Lajittele" + +#: src/ui/views/GamesView/FiltersPopover.vala:234 +#: src/ui/widgets/GameTagsList.vala:58 +msgid "Tags" +msgstr "Tunnisteet" + +#: src/ui/views/GamesView/FiltersPopover.vala:353 +msgid "All platforms" +msgstr "Kaikki alustat" + +#: src/ui/views/GamesView/AddGamePopover.vala:77 +msgid "Select game executable" +msgstr "Valitse suoritettava peli" + +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Select game directory" +msgstr "Valitse pelikansio" + +#: src/ui/views/GamesView/AddGamePopover.vala:111 +msgid "Download game images" +msgstr "Lataa pelikuvia" + +#: src/ui/views/GamesView/GameContextMenu.vala:87 +msgid "Details" +msgstr "Yksityiskohdat" + +#: src/ui/views/GamesView/GameContextMenu.vala:117 +msgctxt "game_context_menu" +msgid "Favorite" +msgstr "Suosikki" + +#: src/ui/views/GamesView/GameContextMenu.vala:121 +msgctxt "game_context_menu" +msgid "Hidden" +msgstr "Piilotettu" + +#: src/ui/views/GamesView/GameContextMenu.vala:133 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:236 +msgid "Open installation directory" +msgstr "Avaa asennus hakemisto" + +#: src/ui/views/GamesView/GameContextMenu.vala:142 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:237 +msgid "Open installers collection directory" +msgstr "Avaa asennusohjelmien kokoelmahakemisto" + +#: src/ui/views/GamesView/GameContextMenu.vala:151 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:238 +msgid "Open bonus collection directory" +msgstr "Avaa bonus-sisällön kansio" + +#: src/ui/views/GamesView/GameContextMenu.vala:160 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:239 +msgid "Open screenshots directory" +msgstr "Avaa kuvakaappaus hakemisto" + +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +msgid "Uninstall" +msgstr "Poista" + +#: src/ui/views/GamesView/GameContextMenu.vala:192 +msgid "Properties" +msgstr "Ominaisuudet" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:100 +#, c-format +msgid "%d game selected" +msgid_plural "%d games selected" +msgstr[0] "%d peli valittu" +msgstr[1] "%d pelit valittu" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:144 +#, c-format +msgid "%d game will be installed" +msgid_plural "%d games will be installed" +msgstr[0] "%d peli tullaan asentamaan" +msgstr[1] "%d pelit tullaan asentamaan" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:154 +#, c-format +msgid "%d game will be downloaded" +msgid_plural "%d games will be downloaded" +msgstr[0] "%d peli tullaan lataamaan" +msgstr[1] "%d pelit tullaan lataamaan" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:161 +#, c-format +msgid "Image for %d game will be searched" +msgid_plural "Images for %d games will be searched" +msgstr[0] "%d pelin kuvaa etsitään" +msgstr[1] "%d pelien kuvia etsitään" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:168 +#, c-format +msgid "%d game will be uninstalled" +msgid_plural "%d games will be uninstalled" +msgstr[0] "%d peli tullaan poistamaan" +msgstr[1] "%d pelit tullaan poistamaan" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:174 +msgid "Refresh" +msgstr "Virkistä" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:175 +#, c-format +msgid "" +"%d game will be removed from database. Restart GameHub to fetch new data" +msgid_plural "" +"%d games will be removed from database. Restart GameHub to fetch new data" +msgstr[0] "" +"%d niminen peli poistetaan tietokannasta. Käynnistä GameHub uudestaan " +"noutaaksesi uudet tiedot" +msgstr[1] "" +"%d nimiset pelit poistetaan tietokannasta. Käynnistä GameHub uudestaan " +"noutaaksesi uudet tiedot" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:240 +msgid "Open store page" +msgstr "Avaa kauppasivu" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:242 +msgid "Game properties" +msgstr "Pelin ominaisuudet" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:46 +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:60 +msgid "Playtime" +msgstr "Peliaika" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:52 +msgid "Playtime (local)" +msgstr "Peliaika (paikallinen)" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:69 +msgid "Last launch" +msgstr "Viimeisin käynnistys" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:46 +msgid "Achievements" +msgstr "Saavutukset" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:85 +#, c-format +msgid "Unlocked: %s" +msgstr "Avattu: %s" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:90 +#, c-format +msgid "Global percentage: %g%%" +msgstr "Kokonaisprosentti: %g%%" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:77 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:103 +msgid "Language" +msgstr "Kieli" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:80 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:106 +msgid "Languages" +msgstr "Kielet" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:147 +#, c-format +msgid "%u DLCs cannot be installed" +msgstr "%u Lisäosaa (DLC) ei voi asentaa" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:71 +msgid "Category" +msgstr "Luokka" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:74 +msgid "Categories" +msgstr "Luokat" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:90 +msgid "Genre" +msgstr "Tyylilaji" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:93 +msgid "Genres" +msgstr "Tyylilajit" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:109 +msgctxt "igdb" +msgid "Popularity" +msgstr "Suosio" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:115 +msgctxt "igdb" +msgid "Aggregated rating" +msgstr "Kokonaisarvio" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:116 +msgctxt "igdb" +msgid "IGDB user rating" +msgstr "IGDB-käyttäjäarvostelut" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:117 +msgctxt "igdb" +msgid "Total rating" +msgstr "Kokonaisarvosana" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:126 +msgctxt "igdb" +msgid "Release date" +msgstr "Julkaisupäivä" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:133 +msgctxt "igdb" +msgid "Platforms" +msgstr "Alustat" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:139 +msgctxt "igdb" +msgid "Genres" +msgstr "Tyylilajit" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:145 +msgctxt "igdb" +msgid "Keywords" +msgstr "Avainsanat" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:152 +msgctxt "igdb" +msgid "Links" +msgstr "Linkit" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:208 +#, c-format +msgid "Based on %d rating" +msgid_plural "Based on %d ratings" +msgstr[0] "Perustuu %d arvioon" +msgstr[1] "Perustuu %d arvioon" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:290 +msgctxt "igdb" +msgid "Summary" +msgstr "Yhteenveto" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:301 +msgctxt "igdb" +msgid "Storyline" +msgstr "Juoni" + +#: src/ui/widgets/FileChooserEntry.vala:49 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select file" +msgstr "Valitse tiedosto" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "No images" +msgstr "Ei kuvia" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "" +"There are no images found for this game\n" +"Make sure game name is correct" +msgstr "" +"Tälle pelille ei löydy kuvia\n" +"Varmista, että pelin nimi on oikea" + +#: src/ui/widgets/ImagesDownloadPopover.vala:94 +msgid "Search images:" +msgstr "Etsi kuvia:" + +#: src/ui/widgets/CompatToolPicker.vala:53 +msgid "Compatibility layer:" +msgstr "Yhteensopivuuskerros:" + +#: src/ui/widgets/CompatToolPicker.vala:92 +msgid "Configure" +msgstr "Määritä" + +#: src/ui/widgets/GameTagsList.vala:109 +msgid "Add tag" +msgstr "Lisää tagi" + +#: src/ui/widgets/TweaksList.vala:86 +msgid "No description" +msgstr "Ei kuvausta" + +#: src/ui/widgets/TweaksList.vala:124 +msgid "Edit file" +msgstr "Muokkaa tiedostoa" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dh" +msgstr "%dt" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dm" +msgstr "%dkk" + +#: src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%ds" +msgstr "%ds" + +#: src/settings/UI.vala:153 +msgctxt "grid_size_preset" +msgid "Steam" +msgstr "Steam" + +#: src/settings/UI.vala:154 +msgctxt "grid_size_preset" +msgid "Steam (vertical)" +msgstr "Steam (pystysuora)" + +#: src/settings/UI.vala:155 +msgctxt "grid_size_preset" +msgid "GOG" +msgstr "GOG" + +#: src/settings/UI.vala:156 +msgctxt "grid_size_preset" +msgid "GOG (vertical)" +msgstr "GOG (pystysuora)" + +#: src/settings/UI.vala:157 +msgctxt "grid_size_preset" +msgid "Square" +msgstr "Neliö" + +#: src/settings/UI.vala:158 +msgctxt "grid_size_preset" +msgid "Custom" +msgstr "Kustomi" + +#: src/utils/downloader/Downloader.vala:200 +msgctxt "dl_status" +msgid "Queued" +msgstr "Jonossa" + +#: src/utils/downloader/Downloader.vala:201 +msgctxt "dl_status" +msgid "Starting download" +msgstr "Aloitetaan lataamaan" + +#: src/utils/downloader/Downloader.vala:202 +msgctxt "dl_status" +msgid "Download started" +msgstr "Lataus aloitettu" + +#: src/utils/downloader/Downloader.vala:203 +msgctxt "dl_status" +msgid "Download finished" +msgstr "Lataus valmistui" + +#: src/utils/downloader/Downloader.vala:204 +msgctxt "dl_status" +msgid "Download failed" +msgstr "Lataus epäonnistui" + +#: src/utils/downloader/Downloader.vala:208 +#, c-format +msgctxt "dl_status" +msgid "Downloading: %s" +msgstr "Ladataan: %s" + +#: src/utils/downloader/Downloader.vala:210 +msgctxt "dl_status" +msgid "Downloading" +msgstr "Lataa" + +#: src/utils/downloader/Downloader.vala:214 +#, c-format +msgctxt "dl_status" +msgid "Paused: %s" +msgstr "Keskeytetty: %s" + +#: src/utils/downloader/Downloader.vala:216 +msgctxt "dl_status" +msgid "Paused" +msgstr "Keskeytetty" + +#: src/utils/downloader/Downloader.vala:218 +msgctxt "dl_status" +msgid "Download cancelled" +msgstr "Lataus peruutettu" + +#. TRANSLATORS: Download progress template. %1$d - percentage, %2$s / %3$s - downloaded portion and total file size, %4$s - download speed +#: src/utils/downloader/Downloader.vala:262 +#, c-format +msgctxt "dl_status" +msgid "%1$d%% (%2$s / %3$s) [%4$s/s]" +msgstr "%1$d%% (%2$s / %3$s) [%4$s/s]" + +#~ msgid "Disable esync" +#~ msgstr "Poista esync käytöstä" + +#~ msgid "Force LARGE_ADDRESS_AWARE flag" +#~ msgstr "Pakota LARGE_ADDRESS_AWARE lippu" + +#~ msgid "Disable DirectX 11 compatibility layer" +#~ msgstr "Poista DirectX 11 -yhteensopivuustaso käytöstä" + +#~ msgid "Use WineD3D11 as DirectX 11 compatibility layer" +#~ msgstr "Käytä WineD3D11:sta DirectX 11 -yhteensopivuustason sijaan" + +#~ msgid "Show DXVK info overlay" +#~ msgstr "Näytä DXVK infon yleiskerros" + +#, fuzzy +#~ msgid "Enable DirectX 9 compatibility layer" +#~ msgstr "Poista DirectX 11 -yhteensopivuustaso käytöstä" + +#~ msgid "Silent installation" +#~ msgstr "Hiljainen asennus" + +#~ msgid "Very silent installation" +#~ msgstr "Erittäin hiljainen asennus" + +#~ msgid "Suppress messages" +#~ msgstr "Tukahduta viestit" + +#~ msgid "No GUI" +#~ msgstr "Ei GUI:ta" diff --git a/po/fr.po b/po/fr.po new file mode 100644 index 00000000..dabf6665 --- /dev/null +++ b/po/fr.po @@ -0,0 +1,1901 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the com.github.tkashkin.gamehub package. +# King Claudy , 2019. +# Anatoliy Kashkin , 2019. +# Swann Martinet , 2019. +# Nathan , 2019, 2020. +# Éfrit , 2019, 2020. +msgid "" +msgstr "" +"Project-Id-Version: com.github.tkashkin.gamehub\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-26 06:40+0300\n" +"PO-Revision-Date: 2020-03-18 01:36+0000\n" +"Last-Translator: Éfrit \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 4.0-dev\n" + +#: src/app.vala:91 +msgid "Show help" +msgstr "Afficher l’aide" + +#: src/app.vala:92 +msgid "Show application version and exit" +msgstr "Afficher la version de l’application et quitter" + +#: src/app.vala:93 +msgid "Restart with GDB debugger attached" +msgstr "Redémarrer avec le débogueur GDB attaché" + +#: src/app.vala:94 +msgid "Show full GDB backtrace" +msgstr "Afficher l’intégralité de la trace d’appels de GDB" + +#: src/app.vala:95 +msgid "Treat fatal errors as criticals and crash application" +msgstr "Traiter les erreurs fatales comme cruciales et planter l’application" + +#: src/app.vala:99 +msgid "Show main window" +msgstr "Afficher la fenêtre principale" + +#: src/app.vala:100 +msgid "Show application settings dialog" +msgstr "Afficher les paramètres de l’application" + +#: src/app.vala:101 +msgid "Show about dialog" +msgstr "À propos de GameHub" + +#: src/app.vala:102 +msgid "Maximum number of background worker threads" +msgstr "Nombre maximal d’unités de traitement en arrière-plan" + +#: src/app.vala:106 +msgid "Run game" +msgstr "Lancer le jeu" + +#: src/app.vala:107 +msgid "Show compatibility options dialog" +msgstr "Afficher les options de compatibilité" + +#: src/app.vala:108 +msgid "Open game details" +msgstr "Afficher les détails du jeu" + +#: src/app.vala:109 +msgid "Open game properties" +msgstr "Afficher les propriétés du jeu" + +#: src/app.vala:113 +msgid "Enable debug logging" +msgstr "Activer la journalisation du débogage" + +#: src/app.vala:114 +msgid "" +"Log authentication process and sensitive information like authentication " +"tokens" +msgstr "" +"Journaliser le processus d’authentification et les informations sensibles " +"comme les jetons d’authentification" + +#: src/app.vala:115 +msgid "Log download manager" +msgstr "Journaliser le gestionnaire de téléchargement" + +#: src/app.vala:116 +msgid "Log background workers start/stop" +msgstr "" +"Journaliser les démarrages et arrêts des unités de traitement en arrière-plan" + +#: src/app.vala:117 +msgid "Disable log messages filtering" +msgstr "Désactiver le filtrage des messages du journal" + +#: src/app.vala:118 +msgid "Verbose logging" +msgstr "Journalisation détaillée" + +#: src/app.vala:247 +msgid "Game Options:" +msgstr "Options du jeu :" + +#: src/app.vala:247 +msgid "Show game options help" +msgstr "Afficher l’aide pour les options du jeu" + +#: src/app.vala:255 +msgid "Logging Options:" +msgstr "Options de journalisation :" + +#: src/app.vala:255 +msgid "Show logging options help" +msgstr "Afficher l’aide pour les options de journalisation" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +msgid "Select executable" +msgstr "Choisir l’exécutable" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:181 src/ui/views/GamesView/GamesView.vala:330 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select" +msgstr "Choisir" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:180 src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Cancel" +msgstr "Annuler" + +#: src/data/Runnable.vala:166 src/ui/widgets/FileChooserEntry.vala:49 +msgid "Select directory" +msgstr "Choisir le répertoire" + +#: src/data/Runnable.vala:619 +#, c-format +msgid "Part %1$u of %2$u: %3$s" +msgstr "Partie %1$u sur %2$u : %3$s" + +#: src/data/Runnable.vala:642 src/ui/dialogs/CorruptedInstallerDialog.vala:48 +#, c-format +msgid "%s: corrupted installer" +msgstr "%s : installateur corrompu" + +#: src/data/Runnable.vala:643 +#, c-format +msgid "Checksum mismatch in %s" +msgstr "Différence de somme de contrôle dans %s" + +#: src/data/Runnable.vala:657 src/ui/dialogs/CorruptedInstallerDialog.vala:126 +msgid "Show file" +msgstr "Afficher le fichier" + +#: src/data/Runnable.vala:658 src/ui/dialogs/CorruptedInstallerDialog.vala:132 +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#: src/ui/widgets/TagRow.vala:146 +msgid "Remove" +msgstr "Enlever" + +#: src/data/Runnable.vala:659 src/ui/dialogs/CorruptedInstallerDialog.vala:128 +msgid "Backup" +msgstr "Sauvegarder" + +#: src/data/Runnable.vala:778 +#, c-format +msgid "%s: cannot detect main executable" +msgstr "%s : impossible de détecter l’exécutable principal" + +#: src/data/Runnable.vala:779 +msgid "" +"Main executable file for this game cannot be detected automatically.\n" +"Please set main executable in game's properties." +msgstr "" +"L’exécutable principal pour ce jeu ne peut être détecté automatiquement.\n" +"Veuillez le paramétrer dans les propriétés du jeu." + +#: src/data/Runnable.vala:908 +msgctxt "platform" +msgid "Emulated" +msgstr "Émulé" + +#: src/data/Game.vala:625 +msgctxt "status" +msgid "Running" +msgstr "En exécution" + +#: src/data/Game.vala:628 +msgctxt "status" +msgid "Installed" +msgstr "Installé" + +#: src/data/Game.vala:629 +msgctxt "status" +msgid "Installing" +msgstr "En cours d’installation" + +#: src/data/Game.vala:630 +msgctxt "status" +msgid "Verifying installer integrity" +msgstr "Vérification de l’intégrité de l’installateur" + +#: src/data/Game.vala:631 +msgctxt "status" +msgid "Download started" +msgstr "Téléchargement commencé" + +#: src/data/Game.vala:633 +msgctxt "status" +msgid "Not installed" +msgstr "Non installé" + +#: src/data/Game.vala:643 +msgctxt "status_header" +msgid "Installed" +msgstr "Installé" + +#: src/data/Game.vala:644 +msgctxt "status_header" +msgid "Installing" +msgstr "En cours d’installation" + +#: src/data/Game.vala:646 +msgctxt "status_header" +msgid "Downloading" +msgstr "En cours de téléchargement" + +#: src/data/Game.vala:648 +msgctxt "status_header" +msgid "Not installed" +msgstr "Non installé" + +#: src/data/GameSource.vala:31 +#, c-format +msgid "%s games" +msgstr "%s jeux" + +#: src/data/sources/steam/Steam.vala:43 +msgid "Your SteamID will be read from Steam configuration file" +msgstr "" +"Votre identifiant Steam sera lu à partir du fichier de configuration Steam" + +#: src/data/sources/steam/Steam.vala:46 +msgid "" +"Steam config file not found.\n" +"Login into your account in Steam client and return to GameHub" +msgstr "" +"Fichier de configuration Steam introuvable.\n" +"Connectez-vous à votre compte dans le client Steam puis revenez dans GameHub" + +#: src/data/sources/gog/GOGGame.vala:983 +#, c-format +msgid "DLC: %s" +msgstr "Contenu téléchargeable : %s" + +#: src/data/sources/humble/HumbleGame.vala:343 +#, c-format +msgid "%s: no available installers" +msgstr "%s : aucun installateur disponible" + +#: src/data/sources/humble/HumbleGame.vala:344 +msgid "" +"Cannot get Trove download URL.\n" +"Make sure your Humble Monthly subscription is active." +msgstr "" +"Impossible d’obtenir le lien de téléchargement pour Trove.\n" +"Veuillez vérifier que votre abonnement à Humble Monthly est actif." + +#: src/data/sources/itch/ItchDownloader.vala:192 +#, c-format +msgctxt "itch_dl_status" +msgid "%s left;" +msgstr "%s restant ;" + +#: src/data/sources/itch/ItchDownloader.vala:195 +#, c-format +msgctxt "itch_dl_status" +msgid "%d%%" +msgstr "%d%%" + +#: src/data/sources/itch/ItchDownloader.vala:198 +#, c-format +msgctxt "itch_dl_status" +msgid "(%1$s / %2$s)" +msgstr "(%1$s / %2$s)" + +#: src/data/sources/itch/ItchDownloader.vala:201 +#, c-format +msgctxt "itch_dl_status" +msgid "[%s/s]" +msgstr "[%s/s]" + +#: src/data/sources/user/User.vala:30 +msgid "User games" +msgstr "Jeux de l’utilisateur" + +#: src/data/db/tables/Tags.vala:225 +msgctxt "tag" +msgid "Favorites" +msgstr "Favoris" + +#: src/data/db/tables/Tags.vala:226 +msgctxt "tag" +msgid "Not installed" +msgstr "Non installé" + +#: src/data/db/tables/Tags.vala:227 +msgctxt "tag" +msgid "Installed" +msgstr "Installé" + +#: src/data/db/tables/Tags.vala:228 +msgctxt "tag" +msgid "Hidden" +msgstr "Caché" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit script" +msgstr "Modifier le script" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit custom script" +msgstr "Modifier le script personnalisé" + +#: src/data/compat/Innoextract.vala:55 +#, c-format +msgid "" +"Innoextract %1$s is not supported and may not be able to extract some " +"games correctly.\n" +"Install innoextract %2$s or newer." +msgstr "" +"Innoextract %1$s n’est pas pris en charge et peut ne être pas en " +"mesure d’extraire certains jeux correctement.\n" +"Installer innoextract %2$s ou plus récent." + +#: src/data/compat/WineWrap.vala:61 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:242 +#: src/ui/dialogs/CompatRunDialog.vala:102 +#: src/ui/views/GamesView/GameContextMenu.vala:53 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:234 +msgid "Run" +msgstr "Lancer" + +#: src/data/compat/WineWrap.vala:64 +msgid "Show WineWrap menu" +msgstr "Afficher le menu WineWrap" + +#: src/data/compat/WineWrap.vala:67 src/data/compat/Proton.vala:122 +#: src/data/compat/Wine.vala:83 +msgid "Kill apps in prefix" +msgstr "Tuer les applications dans prefix" + +#: src/data/compat/Proton.vala:47 +msgid "Proton prefix" +msgstr "Préfixe de Proton" + +#: src/data/compat/Proton.vala:110 src/data/compat/Wine.vala:71 +msgid "Open prefix directory" +msgstr "Ouvrir le répertoire prefix" + +#: src/data/compat/Proton.vala:113 src/data/compat/Wine.vala:74 +msgid "Run winecfg" +msgstr "Lancer winecfg" + +#: src/data/compat/Proton.vala:116 src/data/compat/Wine.vala:77 +msgid "Run winetricks" +msgstr "Lancer winetricks" + +#: src/data/compat/Proton.vala:119 src/data/compat/Wine.vala:80 +msgid "Run taskmgr" +msgstr "Lancer taskmgr" + +#: src/data/compat/Wine.vala:53 +msgid "Wine prefix" +msgstr "Préfixe Wine" + +#: src/data/compat/Wine.vala:55 +msgid "Environment variables" +msgstr "Variables d’environnement" + +#: src/data/compat/Wine.vala:60 +msgid "InnoSetup default options" +msgstr "Options par défaut d’InnoSetup" + +#: src/data/compat/RetroArch.vala:53 +msgid "Libretro core file" +msgstr "Fichier de base Libretro" + +#: src/data/compat/CustomEmulator.vala:43 +msgid "Custom emulator" +msgstr "Émulateur personnalisé" + +#: src/data/compat/CustomEmulator.vala:48 +msgid "Emulator" +msgstr "Émulateur" + +#: src/data/compat/CustomEmulator.vala:49 +msgid "Launch in game directory" +msgstr "Lancer dans le répertoire du jeu" + +#: src/data/adapters/GamesAdapter.vala:440 +msgctxt "status_header" +msgid "Favorites" +msgstr "Favoris" + +#: src/data/adapters/GamesAdapter.vala:445 +#, c-format +msgctxt "status_header" +msgid "%s: Favorites" +msgstr "%s : favoris" + +#: src/data/adapters/GamesAdapter.vala:491 +msgid "Merging games" +msgstr "Fusion des jeux" + +#: src/data/adapters/GamesAdapter.vala:504 +#, c-format +msgid "Merging games from %s" +msgstr "Fusion des jeux depuis %s" + +#: src/data/adapters/GamesAdapter.vala:551 +#, c-format +msgid "Loading games from %s" +msgstr "Chargement des jeux depuis %s" + +#: src/data/adapters/GamesAdapter.vala:678 +msgctxt "sort_mode" +msgid "By name" +msgstr "Par nom" + +#: src/data/adapters/GamesAdapter.vala:679 +msgctxt "sort_mode" +msgid "By last launch" +msgstr "Par dernier lancement" + +#: src/data/adapters/GamesAdapter.vala:680 +msgctxt "sort_mode" +msgid "By playtime" +msgstr "Par temps de jeu" + +#: src/data/adapters/GamesAdapter.vala:705 +msgctxt "group_mode" +msgid "Do not group" +msgstr "Ne pas grouper" + +#: src/data/adapters/GamesAdapter.vala:706 +msgctxt "group_mode" +msgid "By status" +msgstr "Par statut" + +#: src/data/adapters/GamesAdapter.vala:707 +msgctxt "group_mode" +msgid "By source" +msgstr "Par source" + +#: src/data/providers/images/SteamGridDB.vala:151 +#: src/data/providers/data/IGDB.vala:431 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:217 +msgid "Default" +msgstr "Par défaut" + +#: src/data/providers/images/SteamGridDB.vala:158 +#: src/data/providers/data/IGDB.vala:438 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:225 +msgid "Restore default API key" +msgstr "Restaurer la clé par défaut de l’API" + +#: src/data/providers/images/SteamGridDB.vala:169 +#: src/data/providers/data/IGDB.vala:449 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:108 +msgid "API key" +msgstr "Clé API" + +#: src/data/providers/images/SteamGridDB.vala:177 +#: src/data/providers/data/IGDB.vala:457 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:53 +msgid "Generate key" +msgstr "Générer la clé" + +#: src/data/providers/images/SteamGridDB.vala:208 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Style" +msgstr "Style" + +#: src/data/providers/images/SteamGridDB.vala:209 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Score" +msgstr "Score" + +#: src/data/providers/images/SteamGridDB.vala:213 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Author" +msgstr "Auteur" + +#: src/data/providers/images/SteamGridDB.vala:225 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Alternate" +msgstr "Alterné" + +#: src/data/providers/images/SteamGridDB.vala:226 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Blurred" +msgstr "Flouté" + +#. TRANSLATORS: Flat / Material Design image style. Probably should not be translated +#: src/data/providers/images/SteamGridDB.vala:228 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Material" +msgstr "Material" + +#: src/data/providers/images/SteamGridDB.vala:229 +msgctxt "imagesource_steamgriddb_image_style" +msgid "No logo" +msgstr "Aucun logo" + +#: src/data/providers/images/SteamGridDB.vala:230 +msgctxt "imagesource_steamgriddb_image_style" +msgid "White logo" +msgstr "Logo blanc" + +#: src/data/providers/data/IGDB.vala:147 +msgid "" +"Monthly IGDB request quota has been reached. Set your own API key to use " +"IGDB data or disable IGDB." +msgstr "" +"Le quota mensuel de requêtes vers IGBD a été atteint. Définissez votre " +"propre clé d’API pour utiliser les données de IGDB ou désactivez IGDB." + +#: src/data/providers/data/IGDB.vala:148 +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:40 +#: src/ui/views/WelcomeView.vala:53 src/ui/views/WelcomeView.vala:78 +#: src/ui/views/GamesView/GamesView.vala:230 +#: src/ui/views/GamesView/GamesView.vala:629 +msgid "Settings" +msgstr "Paramètres" + +#: src/data/providers/data/IGDB.vala:356 +msgctxt "igdb_related_link" +msgid "Official website" +msgstr "Site Web officiel" + +#: src/data/providers/data/IGDB.vala:469 +msgctxt "igdb_preferred_description" +msgid "When game has description, show description" +msgstr "Lorsque le jeu possède une description, affiche la description" + +#: src/data/providers/data/IGDB.vala:476 +msgctxt "igdb_preferred_description" +msgid "of game" +msgstr "du jeu" + +#: src/data/providers/data/IGDB.vala:477 +msgctxt "igdb_preferred_description" +msgid "from IGDB" +msgstr "depuis IGDB" + +#: src/data/providers/data/IGDB.vala:478 +msgctxt "igdb_preferred_description" +msgid "both" +msgstr "les deux" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:65 +msgid "Some settings will be applied after application restart" +msgstr "" +"Certains paramètres seront appliqués après le redémarrage de l’application" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:71 +msgid "Games directory contains space. It may cause problems for some games" +msgstr "" +"Le nom de dossier des jeux contient des espaces. Cela peut poser problème " +"pour certains jeux" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:36 +msgid "Interface" +msgstr "Interface" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:37 +msgid "Appearance" +msgstr "Apparance" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:38 +msgid "General interface settings" +msgstr "Paramètres généraux de l'interface" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:48 +msgid "Dark theme" +msgstr "Thème sombre" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:53 +msgctxt "icon_style" +msgid "Theme-based" +msgstr "Basé sur le thème" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:54 +msgctxt "icon_style" +msgid "Symbolic" +msgstr "Symbolique" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:55 +msgctxt "icon_style" +msgid "Colored" +msgstr "Coloré" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:57 +msgctxt "icon_style" +msgid "Icon style" +msgstr "Style d'icône" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:84 +msgid "Game card" +msgstr "Carte de jeu" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:86 +msgid "Show platform icons" +msgstr "Afficher l'icône des plateformes" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:99 +msgctxt "grid_size" +msgid "Card size" +msgstr "Taille de la carte" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:117 +msgctxt "grid_size_preset" +msgid "Presets" +msgstr "Paramètres prédéfinis" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:139 +msgid "Games list: installed" +msgstr "Liste des jeux : installé" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:140 +msgid "Games list: not installed" +msgstr "Liste des jeux : non installé" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:142 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:146 +msgctxt "list_style" +msgid "Show icon" +msgstr "Afficher l'icône" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:143 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:147 +msgctxt "list_style" +msgid "Bold title" +msgstr "Titre en gras" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:144 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:148 +msgctxt "list_style" +msgid "Show status" +msgstr "Afficher l'état" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:149 +msgctxt "list_style" +msgid "Dim" +msgstr "Variable" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:151 +msgid "Grid options" +msgstr "Options de grille" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:152 +msgid "List options" +msgstr "Options de liste" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:31 +msgid "Behavior" +msgstr "Comportement" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:32 +msgid "Behavior settings" +msgstr "Paramètres comportementaux" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:42 +msgid "Run games with double click" +msgstr "Lancer le jeu avec un double-clic" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:46 +msgid "Merge games from different sources" +msgstr "Fusionner les jeux de différentes sources" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:50 +msgid "Use imported tags" +msgstr "Utiliser les étiquettes importées" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:51 +msgid "General" +msgstr "Général" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:52 +msgid "Collection" +msgstr "Ludothèque" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:53 +msgid "Empty" +msgstr "Vide" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:65 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:85 +msgid "Collection directory" +msgstr "Dossier de la ludothèque" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:70 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:78 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:87 +msgid "Game directory" +msgstr "Répertoire du jeu" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:71 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:79 +msgid "Installers" +msgstr "Installateurs" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:72 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:98 +msgid "DLC" +msgstr "Contenu téléchargeable" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:73 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:197 +msgid "Bonus content" +msgstr "Contenu bonus" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:84 +msgid "Variable syntax: $var or ${var}" +msgstr "Syntaxe variable : $var ou ${var}" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:86 +msgid "Game name" +msgstr "Nom du jeu" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:88 +#: src/ui/views/GamesView/FiltersPopover.vala:127 +msgid "Platform" +msgstr "Plateforme" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:36 +msgid "Controller" +msgstr "Contrôle" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +msgid "Enabled" +msgstr "Activé" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:53 +msgid "Focus GameHub window with Guide button" +msgstr "Afficher la fenêtre de GameHub au premier plan avec le bouton Guide" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:57 +msgid "Controllers" +msgstr "Contrôles du jeu" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:89 +msgid "Move focus" +msgstr "Déplacer le premier plan" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:91 +msgid "Exit" +msgstr "Quitter" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:40 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:108 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:92 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:95 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:36 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:77 +msgid "Disabled" +msgstr "Désactivé" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:47 +#: src/ui/dialogs/GameTweaksDialog.vala:53 +#: src/ui/views/GamesView/GameContextMenu.vala:183 +msgid "Tweaks" +msgstr "Ajustements" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:34 +msgid "Tweak launch options and apply them to games automatically" +msgstr "" +"Ajustez les options de démarrage et appliquez les automatiquement aux jeux" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:79 +msgid "" +"Tweaks are loaded from following directories in order\n" +"Last tweak overrides previous tweaks with same identifiers" +msgstr "" +"Les ajustements sont chargés depuis les dossiers suivants dans l'ordre\n" +"Les derniers ajustements écrasent les précédents de même identifiants" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:83 +msgid "Click to open" +msgstr "Cliquez pour ouvrir" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:93 +#, c-format +msgid "Tweaks are loaded from %1$s and %2$d more directories (?)" +msgstr "" +"Les ajustements sont chargés depuis %1$s et %2$d dossiers " +"supplémentaires (?)" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:38 +msgid "Game sources" +msgstr "Sources des jeux" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +msgid "Steam API keys have limited number of uses per day" +msgstr "Les clés API ont un nombre limité d'utilisation par jour" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:63 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:57 +msgid "Installation directory" +msgstr "Répertoire d'installation" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:176 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:81 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:34 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:75 +msgid "Not installed" +msgstr "Non installé" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:116 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:96 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:99 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:85 +msgid "Not authenticated" +msgstr "Non authentifié" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +#, c-format +msgid "Authenticated as %s" +msgstr "Authentifié comme %s" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:103 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +msgid "Authenticated" +msgstr "Authentifié" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:183 +#: src/ui/dialogs/InstallDialog.vala:53 src/ui/dialogs/InstallDialog.vala:111 +#: src/ui/views/GamesView/GameContextMenu.vala:80 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:233 +#: src/ui/widgets/TweaksList.vala:95 +msgid "Install" +msgstr "Installer" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:236 +msgid "Steam API key" +msgstr "Clé de l'API Steam" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:50 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:54 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:48 +msgid "Games directory" +msgstr "Répertoire des jeux" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:63 +msgid "Logout" +msgstr "Déconnexion" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:50 +msgid "Load games from Humble Trove" +msgstr "Charger des jeux d'Humble Trove" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:45 +msgid "Emulators" +msgstr "Émulateurs" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:45 +msgid "Libretro core directory" +msgstr "Répertoire de base de Libretro" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:46 +msgid "Libretro core info directory" +msgstr "Répertoire d'informations de base de Libretro" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:50 +msgid "Ignored libretro cores" +msgstr "Noyaux de libretro ignorés" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:54 +msgid "Ignored game file extensions" +msgstr "Extensions de fichiers de jeu ignorées" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:66 +msgid "No cores found" +msgstr "Aucun noyau trouvé" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:70 +#, c-format +msgid "%u core found" +msgid_plural "%u cores found" +msgstr[0] "%u noyau trouvé" +msgstr[1] "%u noyaux trouvés" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:46 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:168 +msgid "No custom emulators" +msgstr "Émulateur personnalisé" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:164 +#, c-format +msgid "%u custom emulator" +msgid_plural "%u custom emulators" +msgstr[0] "%u émulateur personnalisé" +msgstr[1] "%u émulateurs personnalisés" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:237 +msgid "Save" +msgstr "Sauvegarder" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:250 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:312 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/dialogs/GamePropertiesDialog.vala:168 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +#: src/ui/views/GamesView/AddGamePopover.vala:67 +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Executable" +msgstr "Exécutable" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:251 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/views/GamesView/AddGamePopover.vala:68 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Installer" +msgstr "Installateur" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:256 +#: src/ui/dialogs/GamePropertiesDialog.vala:64 +#: src/ui/dialogs/GamePropertiesDialog.vala:69 +#: src/ui/views/GamesView/AddGamePopover.vala:73 +msgid "Name" +msgstr "Nom" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:272 +#: src/ui/dialogs/GamePropertiesDialog.vala:201 +#: src/ui/views/GamesView/AddGamePopover.vala:78 +msgid "Arguments" +msgstr "Arguments" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:276 +msgid "Variables" +msgstr "Variables" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:277 +msgid "Game executable" +msgstr "Choisir l'exécutable" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:278 +msgid "Game arguments" +msgstr "Arguments du jeu" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:80 +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Directory" +msgstr "Répertoire" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +msgid "Select emulator directory" +msgstr "Sélectionner le répertoire de l'émulateur" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:292 +#: src/ui/dialogs/GamePropertiesDialog.vala:219 +msgid "Force compatibility mode" +msgstr "Force le mode de compatibilité" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:307 +msgid "Game file patterns" +msgstr "Modèles de fichiers de jeu" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:315 +msgid "Image" +msgstr "Image" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:318 +msgid "Icon" +msgstr "Icône" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:325 +msgid "" +"findutils-compatible glob patterns\n" +"\n" +" Multiple patterns can be separated with |\n" +" Start pattern with ./ to match relative path\n" +" $basename variable will be replaced with game's executable " +"name (without extension)" +msgstr "" +"findutils modèles compatibles glob\n" +"\n" +" Plusieurs motifs peuvent être séparés avec |\n" +" Démarrez le modèle avec ./ pour correspondre au chemin " +"relatif\n" +" $basename variable qui sera remplacée par le nom de " +"l'exécutable du jeu (sans extension)" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:38 +msgid "Data" +msgstr "Données" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:39 +msgid "Providers" +msgstr "Fournisseurs" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:40 +msgid "Third-party data providers" +msgstr "Fournisseurs de données tiers" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:55 +msgid "Image providers" +msgstr "Fournisseurs d'images" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:68 +msgid "Metadata providers" +msgstr "Fournisseurs de métadonnées" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:137 +msgid "Open website" +msgstr "Ouvrir le site web" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:36 +msgid "About" +msgstr "À propos" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:71 +msgid "Copy application version and environment info" +msgstr "Copier la version de l'application et les informations d'environnement" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:78 +#: src/ui/views/WelcomeView.vala:57 +msgid "All your games in one place" +msgstr "Tous vos jeux en un endroit" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:92 +msgctxt "about_link" +msgid "Website" +msgstr "Site web" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:96 +msgctxt "about_link" +msgid "Source code on GitHub" +msgstr "Code source sur GitHub" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:103 +msgctxt "about_link" +msgid "Report a problem" +msgstr "Signaler un problème" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:104 +msgctxt "about_link" +msgid "Suggest translations" +msgstr "Suggérer des traductions" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:110 +msgctxt "about_link" +msgid "Issues" +msgstr "Problèmes" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:111 +msgctxt "about_link" +msgid "Contributors" +msgstr "Contributeurs" + +#. TRANSLATORS: Likely it should not be translated. GitHub Pulse is a page that shows recent repository activity: https://github.com/tkashkin/GameHub/pulse +#: src/ui/dialogs/SettingsDialog/pages/About.vala:114 +msgctxt "about_link" +msgid "Pulse" +msgstr "Pulse" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:115 +msgctxt "about_link" +msgid "Forks" +msgstr "Forks" + +#: src/ui/dialogs/InstallDialog.vala:109 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:129 +msgid "Import" +msgstr "Importer" + +#: src/ui/dialogs/InstallDialog.vala:110 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:153 +msgid "Download" +msgstr "Télécharger" + +#: src/ui/dialogs/InstallDialog.vala:207 +msgid "Select installer" +msgstr "Sélectionner l'installateur" + +#: src/ui/dialogs/InstallDialog.vala:216 +#, c-format +msgid "Installer size: %s" +msgstr "Taille de l'installateur : %s" + +#: src/ui/dialogs/InstallDialog.vala:348 +msgid "Unknown" +msgstr "Inconnu" + +#: src/ui/dialogs/GamePropertiesDialog.vala:49 +#, c-format +msgid "%s: Properties" +msgstr "%s : Propriétés" + +#: src/ui/dialogs/GamePropertiesDialog.vala:84 +msgid "Images" +msgstr "Images" + +#: src/ui/dialogs/GamePropertiesDialog.vala:126 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:160 +#: src/ui/views/GameDetailsView/blocks/Artwork.vala:62 +msgid "Download images" +msgstr "Télécharger les images" + +#: src/ui/dialogs/GamePropertiesDialog.vala:144 +msgid "Image URL" +msgstr "URL de l’image" + +#: src/ui/dialogs/GamePropertiesDialog.vala:148 +msgid "Vertical image URL" +msgstr "URL de l'image verticale" + +#: src/ui/dialogs/GamePropertiesDialog.vala:157 +msgid "Icon URL" +msgstr "URL de l’icône" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Select working directory" +msgstr "Sélectionner le dossier" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Working directory" +msgstr "Dossier" + +#: src/ui/dialogs/GamePropertiesDialog.vala:214 +msgid "Compatibility" +msgstr "Compatibilité" + +#: src/ui/dialogs/GamePropertiesDialog.vala:236 +msgid "Launch from terminal" +msgstr "Lancer depuis le terminal" + +#: src/ui/dialogs/GamePropertiesDialog.vala:252 +msgid "Copy to clipboard" +msgstr "Copier dans le presse-papier" + +#: src/ui/dialogs/GamePropertiesDialog.vala:254 +msgid "Add to Steam" +msgstr "Ajouter à Steam" + +#: src/ui/dialogs/GamePropertiesDialog.vala:255 +msgid "Add to the Steam library" +msgstr "Ajouter à la bibliothèque Steam" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:53 +#, c-format +msgid "%s: Overlays" +msgstr "%s : superpositions" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "Overlays are disabled" +msgstr "Les superpositions sont désactivées" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "" +"Enable overlays to manage DLCs and mods\n" +"\n" +"Enabling will move game to the “base“ overlay" +msgstr "" +"Activez les overlays pour gérer les DLC et les mods\n" +"\n" +"L'activation fera passer le jeu à l'overlay par défaut" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:77 +#: src/ui/views/GamesView/GameContextMenu.vala:175 +msgid "Overlays" +msgstr "Overlays" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:105 +msgid "Overlay ID (directory name)" +msgstr "Identifiant de l'overlay (nom du dossier)" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:110 +msgid "Overlay name (optional)" +msgstr "Nom de l'overlay (facultatif)" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:112 +msgid "Add" +msgstr "Ajouter" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:127 +msgid "Enable overlays" +msgstr "Activer les superpositions" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:182 +#, c-format +msgid "" +"Overlay usage at this path may be unsafe\n" +"Proceed at your own risk\n" +"\n" +"Path: %s" +msgstr "" +"L'utilisation de l'overlay à ce chemin peut être dangereuse.\n" +"Procédez à vos risques et périls\n" +"\n" +"Chemin : %s" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:187 +#, c-format +msgid "" +"Overlay usage at this path is not supported\n" +"\n" +"Path: %s" +msgstr "" +"L'utilisation de l'overlay à ce chemin n'est pas prise en charge.\n" +"\n" +"Chemin : %s" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:266 +msgid "Open directory" +msgstr "Ouvrir le dossier" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:271 +msgid "Remove overlay" +msgstr "Enlever la superposition" + +#: src/ui/dialogs/CompatRunDialog.vala:48 +#: src/ui/views/GamesView/GameContextMenu.vala:46 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:235 +msgid "Run with compatibility layer" +msgstr "Lancer avec une couche de compatibilité" + +#: src/ui/dialogs/CorruptedInstallerDialog.vala:71 +msgid "Corrupted installer: checksum mismatch in" +msgstr "Installeur corrompu : différence dans la somme de contrôle dans" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:57 +#: src/ui/views/GamesView/AddGamePopover.vala:105 +msgid "Import emulated games" +msgstr "Importer des jeux émulés" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:75 +msgid "Select directory with emulated games" +msgstr "Choisir le dossier des jeux émulés" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:83 +msgid "Detected games" +msgstr "Jeux détectés" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:107 +msgid "Select all" +msgstr "Tout sélectionner" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:115 +msgid "Select directory to import" +msgstr "Sélectionner le dossier à importer" + +#: src/ui/dialogs/GameTweaksDialog.vala:40 +#, c-format +msgid "%s: Tweaks" +msgstr "%s : Ajustements" + +#: src/ui/views/WelcomeView.vala:52 +msgid "No enabled game sources" +msgstr "Pas de source de jeu activée" + +#: src/ui/views/WelcomeView.vala:52 +msgid "Enable some game sources in settings" +msgstr "Activez des sources de jeux dans les paramètres" + +#: src/ui/views/WelcomeView.vala:57 +msgid "Let's get started" +msgstr "C'est parti" + +#: src/ui/views/WelcomeView.vala:71 +msgid "Skip" +msgstr "Ignorer" + +#: src/ui/views/WelcomeView.vala:141 +msgid "Ready" +msgstr "Prêt" + +#: src/ui/views/WelcomeView.vala:147 +msgid "Authentication required" +msgstr "Authentification nécessaire" + +#: src/ui/views/WelcomeView.vala:152 +msgid "Authenticating…" +msgstr "Authentification…" + +#: src/ui/views/WelcomeView.vala:163 +#, c-format +msgid "Install %s" +msgstr "Installer %s" + +#: src/ui/views/WelcomeView.vala:164 +msgid "Return to GameHub after installing" +msgstr "Revenir sur GameHub après l'installation" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "No games" +msgstr "Aucun jeu" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "Get some games or enable some game sources in settings" +msgstr "Obtenez des jeux ou activez des sources de jeu dans les paramètres" + +#: src/ui/views/GamesView/GamesView.vala:150 +msgid "Grid view" +msgstr "Vue en grille" + +#: src/ui/views/GamesView/GamesView.vala:151 +msgid "List view" +msgstr "Vue en liste" + +#: src/ui/views/GamesView/GamesView.vala:159 +msgid "All games" +msgstr "Tous les jeux" + +#: src/ui/views/GamesView/GamesView.vala:182 +msgid "Downloads" +msgstr "Téléchargements" + +#: src/ui/views/GamesView/GamesView.vala:208 +msgid "Filters" +msgstr "Filtres" + +#: src/ui/views/GamesView/GamesView.vala:216 +#: src/ui/views/GamesView/AddGamePopover.vala:84 +msgid "Add game" +msgstr "Ajouter un jeu" + +#: src/ui/views/GamesView/GamesView.vala:223 +msgid "Search" +msgstr "Rechercher" + +#: src/ui/views/GamesView/GamesView.vala:328 +msgid "Menu" +msgstr "Menu" + +#: src/ui/views/GamesView/GamesView.vala:329 +#: src/ui/views/GameDetailsView/GameDetailsView.vala:104 +msgid "Back" +msgstr "Retour" + +#: src/ui/views/GamesView/GamesView.vala:550 +#, c-format +msgid "%u game" +msgid_plural "%u games" +msgstr[0] "%u jeu" +msgstr[1] "%u jeux" + +#: src/ui/views/GamesView/GamesView.vala:553 +#, c-format +msgctxt "games_view_subtitle_filtered_games" +msgid "%1$u / %2$s" +msgstr "(%1$u / %2$s)" + +#: src/ui/views/GamesView/GamesView.vala:557 +#, c-format +msgctxt "games_view_subtitle" +msgid "%1$s: %2$s" +msgstr "%1$s : %2$s" + +#: src/ui/views/GamesView/GamesView.vala:568 +msgid "No user-added games" +msgstr "Aucun jeu ajouté par l'utilisateur" + +#: src/ui/views/GamesView/GamesView.vala:569 +msgid "Add some games using plus button" +msgstr "Ajoutez des jeux en appuyant sur le bouton plus" + +#: src/ui/views/GamesView/GamesView.vala:573 +#, c-format +msgid "No %s games" +msgstr "Aucun jeu %s" + +#: src/ui/views/GamesView/GamesView.vala:574 +msgid "Get some Linux-compatible games" +msgstr "Obtenez des jeux compatibles avec Linux" + +#: src/ui/views/GamesView/GamesView.vala:584 +#, c-format +msgid "No games matching “%s”" +msgstr "Aucun jeu correspondant à « %s »" + +#: src/ui/views/GamesView/GamesView.vala:589 +#, c-format +msgid "No %1$s games matching “%2$s”" +msgstr "Aucun jeu %1$s correspondant à « %2$s »" + +#: src/ui/views/GamesView/GamesView.vala:627 +msgid "" +"No games were loaded from Steam. Set your games list privacy to public or " +"use your own Steam API key in settings." +msgstr "" +"Aucun jeu n'a été chargé depuis Steam. Définissez votre liste de jeux à " +"public pour utiliser votre propre clé d'API de Steam dans les paramètres." + +#: src/ui/views/GamesView/GamesView.vala:628 +msgid "Privacy" +msgstr "Confidentialité" + +#: src/ui/views/GamesView/GamesView.vala:739 +msgid "Downloading images" +msgstr "Téléchargement des images" + +#: src/ui/views/GamesView/GamesView.vala:753 +#, c-format +msgid "Downloading image: %s" +msgstr "Téléchargement de l'image : %s" + +#: src/ui/views/GamesView/DownloadProgressView.vala:131 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:162 +msgid "Pause download" +msgstr "Mettre le téléchargement en pause" + +#: src/ui/views/GamesView/DownloadProgressView.vala:137 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:168 +msgid "Resume download" +msgstr "Reprendre le téléchargement" + +#: src/ui/views/GamesView/DownloadProgressView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:174 +msgid "Cancel download" +msgstr "Annuler le téléchargement" + +#: src/ui/views/GamesView/FiltersPopover.vala:77 +msgid "Group" +msgstr "Grouper" + +#: src/ui/views/GamesView/FiltersPopover.vala:102 +msgid "Sort" +msgstr "Trier" + +#: src/ui/views/GamesView/FiltersPopover.vala:234 +#: src/ui/widgets/GameTagsList.vala:58 +msgid "Tags" +msgstr "Étiquettes" + +#: src/ui/views/GamesView/FiltersPopover.vala:353 +msgid "All platforms" +msgstr "Toutes les plateformes" + +#: src/ui/views/GamesView/AddGamePopover.vala:77 +msgid "Select game executable" +msgstr "Sélectionner l'exécutable du jeu" + +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Select game directory" +msgstr "Sélectionner le dossier du jeu" + +#: src/ui/views/GamesView/AddGamePopover.vala:111 +msgid "Download game images" +msgstr "Télécharger les images du jeu" + +#: src/ui/views/GamesView/GameContextMenu.vala:87 +msgid "Details" +msgstr "Détails" + +#: src/ui/views/GamesView/GameContextMenu.vala:117 +msgctxt "game_context_menu" +msgid "Favorite" +msgstr "Favoris" + +#: src/ui/views/GamesView/GameContextMenu.vala:121 +msgctxt "game_context_menu" +msgid "Hidden" +msgstr "Masqué" + +#: src/ui/views/GamesView/GameContextMenu.vala:133 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:236 +msgid "Open installation directory" +msgstr "Ouvrir le répertoire d'installation" + +#: src/ui/views/GamesView/GameContextMenu.vala:142 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:237 +msgid "Open installers collection directory" +msgstr "Ouvrir le dossier des installateurs" + +#: src/ui/views/GamesView/GameContextMenu.vala:151 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:238 +msgid "Open bonus collection directory" +msgstr "Ouvrir le dossier des bonus" + +#: src/ui/views/GamesView/GameContextMenu.vala:160 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:239 +msgid "Open screenshots directory" +msgstr "Ouvrir le dossier des captures d'écran" + +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +msgid "Uninstall" +msgstr "Désinstaller" + +#: src/ui/views/GamesView/GameContextMenu.vala:192 +msgid "Properties" +msgstr "Propriétés" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:100 +#, c-format +msgid "%d game selected" +msgid_plural "%d games selected" +msgstr[0] "%d jeu sélectionné" +msgstr[1] "%d jeux sélectionnés" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:144 +#, c-format +msgid "%d game will be installed" +msgid_plural "%d games will be installed" +msgstr[0] "%d jeu va être installé" +msgstr[1] "%d jeux vont être installés" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:154 +#, c-format +msgid "%d game will be downloaded" +msgid_plural "%d games will be downloaded" +msgstr[0] "%d jeu va être téléchargé" +msgstr[1] "%d jeux vont être téléchargés" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:161 +#, c-format +msgid "Image for %d game will be searched" +msgid_plural "Images for %d games will be searched" +msgstr[0] "Une image pour %d jeu va être recherchée" +msgstr[1] "Des images pour %d jeux vont êtres recherchées" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:168 +#, c-format +msgid "%d game will be uninstalled" +msgid_plural "%d games will be uninstalled" +msgstr[0] "%d jeu va être désinstallé" +msgstr[1] "%d jeux vont être désinstallés" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:174 +msgid "Refresh" +msgstr "Actualiser" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:175 +#, c-format +msgid "" +"%d game will be removed from database. Restart GameHub to fetch new data" +msgid_plural "" +"%d games will be removed from database. Restart GameHub to fetch new data" +msgstr[0] "" +"%d jeu va être supprimé de la base de données. Redémarrez GameHub pour " +"récupérer les nouvelles données" +msgstr[1] "" +"%d jeux vont être supprimés de la base de données. Redémarrez GameHub pour " +"récupérer les nouvelles données" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:240 +msgid "Open store page" +msgstr "Ouvrir la page de la boutique" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:242 +msgid "Game properties" +msgstr "Propriétés du jeu" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:46 +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:60 +msgid "Playtime" +msgstr "Temps de jeu" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:52 +msgid "Playtime (local)" +msgstr "Temps de jeu (local)" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:69 +msgid "Last launch" +msgstr "Dernier lancement" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:46 +msgid "Achievements" +msgstr "Succès" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:85 +#, c-format +msgid "Unlocked: %s" +msgstr "Déverrouillé : %s" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:90 +#, c-format +msgid "Global percentage: %g%%" +msgstr "Pourcentage global : %g%%" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:77 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:103 +msgid "Language" +msgstr "Langue" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:80 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:106 +msgid "Languages" +msgstr "Langues" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:147 +#, c-format +msgid "%u DLCs cannot be installed" +msgstr "%u : Les DLC n'ont pas pu être installés" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:71 +msgid "Category" +msgstr "Catégorie" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:74 +msgid "Categories" +msgstr "Catégories" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:90 +msgid "Genre" +msgstr "Genre" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:93 +msgid "Genres" +msgstr "Genres" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:109 +msgctxt "igdb" +msgid "Popularity" +msgstr "Popularité" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:115 +msgctxt "igdb" +msgid "Aggregated rating" +msgstr "Avis général" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:116 +msgctxt "igdb" +msgid "IGDB user rating" +msgstr "Avis des utilisateurs de IGDB" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:117 +msgctxt "igdb" +msgid "Total rating" +msgstr "Avis global" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:126 +msgctxt "igdb" +msgid "Release date" +msgstr "Date de sortie" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:133 +msgctxt "igdb" +msgid "Platforms" +msgstr "Plateformes" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:139 +msgctxt "igdb" +msgid "Genres" +msgstr "Genres" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:145 +msgctxt "igdb" +msgid "Keywords" +msgstr "Mots-clés" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:152 +msgctxt "igdb" +msgid "Links" +msgstr "Liens" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:208 +#, c-format +msgid "Based on %d rating" +msgid_plural "Based on %d ratings" +msgstr[0] "Basé sur %d avis" +msgstr[1] "Basé sur %d avis" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:290 +msgctxt "igdb" +msgid "Summary" +msgstr "Résumé" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:301 +msgctxt "igdb" +msgid "Storyline" +msgstr "Intrigue" + +#: src/ui/widgets/FileChooserEntry.vala:49 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select file" +msgstr "Sélectionner le fichier" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "No images" +msgstr "Aucune image" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "" +"There are no images found for this game\n" +"Make sure game name is correct" +msgstr "" +"Aucune image n'a été trouvée pour ce jeu\n" +"Veuillez vérifier que le nom du jeu est correct" + +#: src/ui/widgets/ImagesDownloadPopover.vala:94 +msgid "Search images:" +msgstr "Rechercher des images :" + +#: src/ui/widgets/CompatToolPicker.vala:53 +msgid "Compatibility layer:" +msgstr "Couche de compatibilité :" + +#: src/ui/widgets/CompatToolPicker.vala:92 +msgid "Configure" +msgstr "Configurer" + +#: src/ui/widgets/GameTagsList.vala:109 +msgid "Add tag" +msgstr "Ajouter une étiquette" + +#: src/ui/widgets/TweaksList.vala:86 +msgid "No description" +msgstr "Pas de description" + +#: src/ui/widgets/TweaksList.vala:124 +msgid "Edit file" +msgstr "Modifier le fichier" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dh" +msgstr "%dh" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dm" +msgstr "%dm" + +#: src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%ds" +msgstr "%ds" + +#: src/settings/UI.vala:153 +msgctxt "grid_size_preset" +msgid "Steam" +msgstr "Steam" + +#: src/settings/UI.vala:154 +msgctxt "grid_size_preset" +msgid "Steam (vertical)" +msgstr "Steam (vertical)" + +#: src/settings/UI.vala:155 +msgctxt "grid_size_preset" +msgid "GOG" +msgstr "GOG" + +#: src/settings/UI.vala:156 +msgctxt "grid_size_preset" +msgid "GOG (vertical)" +msgstr "GOG (vertical)" + +#: src/settings/UI.vala:157 +msgctxt "grid_size_preset" +msgid "Square" +msgstr "Carré" + +#: src/settings/UI.vala:158 +msgctxt "grid_size_preset" +msgid "Custom" +msgstr "Personnalisé" + +#: src/utils/downloader/Downloader.vala:200 +msgctxt "dl_status" +msgid "Queued" +msgstr "Mis en attente" + +#: src/utils/downloader/Downloader.vala:201 +msgctxt "dl_status" +msgid "Starting download" +msgstr "Démarrage du téléchargement" + +#: src/utils/downloader/Downloader.vala:202 +msgctxt "dl_status" +msgid "Download started" +msgstr "Téléchargement démarré" + +#: src/utils/downloader/Downloader.vala:203 +msgctxt "dl_status" +msgid "Download finished" +msgstr "Téléchargement terminé" + +#: src/utils/downloader/Downloader.vala:204 +msgctxt "dl_status" +msgid "Download failed" +msgstr "Echec du téléchargement" + +#: src/utils/downloader/Downloader.vala:208 +#, c-format +msgctxt "dl_status" +msgid "Downloading: %s" +msgstr "Téléchargement : %s" + +#: src/utils/downloader/Downloader.vala:210 +msgctxt "dl_status" +msgid "Downloading" +msgstr "En cours de téléchargement" + +#: src/utils/downloader/Downloader.vala:214 +#, c-format +msgctxt "dl_status" +msgid "Paused: %s" +msgstr "En pause : %s" + +#: src/utils/downloader/Downloader.vala:216 +msgctxt "dl_status" +msgid "Paused" +msgstr "Mis en pause" + +#: src/utils/downloader/Downloader.vala:218 +msgctxt "dl_status" +msgid "Download cancelled" +msgstr "Téléchargement annulé" + +#. TRANSLATORS: Download progress template. %1$d - percentage, %2$s / %3$s - downloaded portion and total file size, %4$s - download speed +#: src/utils/downloader/Downloader.vala:262 +#, c-format +msgctxt "dl_status" +msgid "%1$d%% (%2$s / %3$s) [%4$s/s]" +msgstr "%1$d%% (%2$s / %3$s) [%4$s/s]" + +#~ msgid "Disable esync" +#~ msgstr "Désactiver esync" + +#~ msgid "Force LARGE_ADDRESS_AWARE flag" +#~ msgstr "Forcer LARGE_ADDRESS_AWARE" + +#~ msgid "Disable DirectX 11 compatibility layer" +#~ msgstr "Désactiver la couche de compatibilité pour DirectX 11" + +#~ msgid "Use WineD3D11 as DirectX 11 compatibility layer" +#~ msgstr "Utiliser WineD3D11 comme couche de compatibilité pour DirectX 11" + +#~ msgid "Show DXVK info overlay" +#~ msgstr "Afficher les infos DXVK en surimpression" + +#~ msgid "Enable DirectX 9 compatibility layer" +#~ msgstr "Activer la couche de compatibilité pour DirectX 9" + +#~ msgid "Silent installation" +#~ msgstr "Installation silencieuse" + +#~ msgid "Very silent installation" +#~ msgstr "Installation très silencieuse" + +#~ msgid "Suppress messages" +#~ msgstr "Supprimer les messages" + +#~ msgid "No GUI" +#~ msgstr "Pas d'interface graphique" + +#~ msgid "Disable fullscreen" +#~ msgstr "Désactiver le plein écran" + +#~ msgid "Windowed" +#~ msgstr "Fenêtré" + +#~ msgid "Compact list" +#~ msgstr "Liste compacte" + +#~ msgid "Show non-native games" +#~ msgstr "Afficher les jeux non natifs" + +#~ msgid "Use compatibility layers and consider Windows games compatible" +#~ msgstr "" +#~ "Utilisez les couches de compatibilité et considérez les jeux Windows " +#~ "compatibles" + +#~ msgid "Use symbolic icons instead of colored icons" +#~ msgstr "Utilisez les icônes symboliques au lieu des icônes de couleur" diff --git a/po/hi.po b/po/hi.po new file mode 100644 index 00000000..2c836a72 --- /dev/null +++ b/po/hi.po @@ -0,0 +1,1797 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the com.github.tkashkin.gamehub package. +# asher hrudai , 2019. +msgid "" +msgstr "" +"Project-Id-Version: com.github.tkashkin.gamehub\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-26 06:40+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: hi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" + +#: src/app.vala:91 +msgid "Show help" +msgstr "" + +#: src/app.vala:92 +msgid "Show application version and exit" +msgstr "" + +#: src/app.vala:93 +msgid "Restart with GDB debugger attached" +msgstr "" + +#: src/app.vala:94 +msgid "Show full GDB backtrace" +msgstr "" + +#: src/app.vala:95 +msgid "Treat fatal errors as criticals and crash application" +msgstr "" + +#: src/app.vala:99 +msgid "Show main window" +msgstr "" + +#: src/app.vala:100 +msgid "Show application settings dialog" +msgstr "" + +#: src/app.vala:101 +msgid "Show about dialog" +msgstr "" + +#: src/app.vala:102 +msgid "Maximum number of background worker threads" +msgstr "" + +#: src/app.vala:106 +msgid "Run game" +msgstr "" + +#: src/app.vala:107 +msgid "Show compatibility options dialog" +msgstr "" + +#: src/app.vala:108 +msgid "Open game details" +msgstr "" + +#: src/app.vala:109 +msgid "Open game properties" +msgstr "" + +#: src/app.vala:113 +msgid "Enable debug logging" +msgstr "" + +#: src/app.vala:114 +msgid "" +"Log authentication process and sensitive information like authentication " +"tokens" +msgstr "" + +#: src/app.vala:115 +msgid "Log download manager" +msgstr "" + +#: src/app.vala:116 +msgid "Log background workers start/stop" +msgstr "" + +#: src/app.vala:117 +msgid "Disable log messages filtering" +msgstr "" + +#: src/app.vala:118 +msgid "Verbose logging" +msgstr "" + +#: src/app.vala:247 +msgid "Game Options:" +msgstr "" + +#: src/app.vala:247 +msgid "Show game options help" +msgstr "" + +#: src/app.vala:255 +msgid "Logging Options:" +msgstr "" + +#: src/app.vala:255 +msgid "Show logging options help" +msgstr "" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +msgid "Select executable" +msgstr "" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:181 src/ui/views/GamesView/GamesView.vala:330 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select" +msgstr "" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:180 src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Cancel" +msgstr "" + +#: src/data/Runnable.vala:166 src/ui/widgets/FileChooserEntry.vala:49 +msgid "Select directory" +msgstr "" + +#: src/data/Runnable.vala:619 +#, c-format +msgid "Part %1$u of %2$u: %3$s" +msgstr "" + +#: src/data/Runnable.vala:642 src/ui/dialogs/CorruptedInstallerDialog.vala:48 +#, c-format +msgid "%s: corrupted installer" +msgstr "" + +#: src/data/Runnable.vala:643 +#, c-format +msgid "Checksum mismatch in %s" +msgstr "" + +#: src/data/Runnable.vala:657 src/ui/dialogs/CorruptedInstallerDialog.vala:126 +msgid "Show file" +msgstr "" + +#: src/data/Runnable.vala:658 src/ui/dialogs/CorruptedInstallerDialog.vala:132 +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#: src/ui/widgets/TagRow.vala:146 +msgid "Remove" +msgstr "" + +#: src/data/Runnable.vala:659 src/ui/dialogs/CorruptedInstallerDialog.vala:128 +msgid "Backup" +msgstr "" + +#: src/data/Runnable.vala:778 +#, c-format +msgid "%s: cannot detect main executable" +msgstr "" + +#: src/data/Runnable.vala:779 +msgid "" +"Main executable file for this game cannot be detected automatically.\n" +"Please set main executable in game's properties." +msgstr "" + +#: src/data/Runnable.vala:908 +msgctxt "platform" +msgid "Emulated" +msgstr "" + +#: src/data/Game.vala:625 +msgctxt "status" +msgid "Running" +msgstr "" + +#: src/data/Game.vala:628 +msgctxt "status" +msgid "Installed" +msgstr "" + +#: src/data/Game.vala:629 +msgctxt "status" +msgid "Installing" +msgstr "" + +#: src/data/Game.vala:630 +msgctxt "status" +msgid "Verifying installer integrity" +msgstr "" + +#: src/data/Game.vala:631 +msgctxt "status" +msgid "Download started" +msgstr "" + +#: src/data/Game.vala:633 +msgctxt "status" +msgid "Not installed" +msgstr "" + +#: src/data/Game.vala:643 +msgctxt "status_header" +msgid "Installed" +msgstr "" + +#: src/data/Game.vala:644 +msgctxt "status_header" +msgid "Installing" +msgstr "" + +#: src/data/Game.vala:646 +msgctxt "status_header" +msgid "Downloading" +msgstr "" + +#: src/data/Game.vala:648 +msgctxt "status_header" +msgid "Not installed" +msgstr "" + +#: src/data/GameSource.vala:31 +#, c-format +msgid "%s games" +msgstr "" + +#: src/data/sources/steam/Steam.vala:43 +msgid "Your SteamID will be read from Steam configuration file" +msgstr "" + +#: src/data/sources/steam/Steam.vala:46 +msgid "" +"Steam config file not found.\n" +"Login into your account in Steam client and return to GameHub" +msgstr "" + +#: src/data/sources/gog/GOGGame.vala:983 +#, c-format +msgid "DLC: %s" +msgstr "" + +#: src/data/sources/humble/HumbleGame.vala:343 +#, c-format +msgid "%s: no available installers" +msgstr "" + +#: src/data/sources/humble/HumbleGame.vala:344 +msgid "" +"Cannot get Trove download URL.\n" +"Make sure your Humble Monthly subscription is active." +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:192 +#, c-format +msgctxt "itch_dl_status" +msgid "%s left;" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:195 +#, c-format +msgctxt "itch_dl_status" +msgid "%d%%" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:198 +#, c-format +msgctxt "itch_dl_status" +msgid "(%1$s / %2$s)" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:201 +#, c-format +msgctxt "itch_dl_status" +msgid "[%s/s]" +msgstr "" + +#: src/data/sources/user/User.vala:30 +msgid "User games" +msgstr "" + +#: src/data/db/tables/Tags.vala:225 +msgctxt "tag" +msgid "Favorites" +msgstr "" + +#: src/data/db/tables/Tags.vala:226 +msgctxt "tag" +msgid "Not installed" +msgstr "" + +#: src/data/db/tables/Tags.vala:227 +msgctxt "tag" +msgid "Installed" +msgstr "" + +#: src/data/db/tables/Tags.vala:228 +msgctxt "tag" +msgid "Hidden" +msgstr "" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit script" +msgstr "" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit custom script" +msgstr "" + +#: src/data/compat/Innoextract.vala:55 +#, c-format +msgid "" +"Innoextract %1$s is not supported and may not be able to extract some " +"games correctly.\n" +"Install innoextract %2$s or newer." +msgstr "" + +#: src/data/compat/WineWrap.vala:61 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:242 +#: src/ui/dialogs/CompatRunDialog.vala:102 +#: src/ui/views/GamesView/GameContextMenu.vala:53 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:234 +msgid "Run" +msgstr "" + +#: src/data/compat/WineWrap.vala:64 +msgid "Show WineWrap menu" +msgstr "" + +#: src/data/compat/WineWrap.vala:67 src/data/compat/Proton.vala:122 +#: src/data/compat/Wine.vala:83 +msgid "Kill apps in prefix" +msgstr "" + +#: src/data/compat/Proton.vala:47 +msgid "Proton prefix" +msgstr "" + +#: src/data/compat/Proton.vala:110 src/data/compat/Wine.vala:71 +msgid "Open prefix directory" +msgstr "" + +#: src/data/compat/Proton.vala:113 src/data/compat/Wine.vala:74 +msgid "Run winecfg" +msgstr "" + +#: src/data/compat/Proton.vala:116 src/data/compat/Wine.vala:77 +msgid "Run winetricks" +msgstr "" + +#: src/data/compat/Proton.vala:119 src/data/compat/Wine.vala:80 +msgid "Run taskmgr" +msgstr "" + +#: src/data/compat/Wine.vala:53 +msgid "Wine prefix" +msgstr "" + +#: src/data/compat/Wine.vala:55 +msgid "Environment variables" +msgstr "" + +#: src/data/compat/Wine.vala:60 +msgid "InnoSetup default options" +msgstr "" + +#: src/data/compat/RetroArch.vala:53 +msgid "Libretro core file" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:43 +msgid "Custom emulator" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:48 +msgid "Emulator" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:49 +msgid "Launch in game directory" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:440 +msgctxt "status_header" +msgid "Favorites" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:445 +#, c-format +msgctxt "status_header" +msgid "%s: Favorites" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:491 +msgid "Merging games" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:504 +#, c-format +msgid "Merging games from %s" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:551 +#, c-format +msgid "Loading games from %s" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:678 +msgctxt "sort_mode" +msgid "By name" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:679 +msgctxt "sort_mode" +msgid "By last launch" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:680 +msgctxt "sort_mode" +msgid "By playtime" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:705 +msgctxt "group_mode" +msgid "Do not group" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:706 +msgctxt "group_mode" +msgid "By status" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:707 +msgctxt "group_mode" +msgid "By source" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:151 +#: src/data/providers/data/IGDB.vala:431 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:217 +msgid "Default" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:158 +#: src/data/providers/data/IGDB.vala:438 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:225 +msgid "Restore default API key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:169 +#: src/data/providers/data/IGDB.vala:449 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:108 +msgid "API key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:177 +#: src/data/providers/data/IGDB.vala:457 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:53 +msgid "Generate key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:208 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Style" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:209 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Score" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:213 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Author" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:225 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Alternate" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:226 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Blurred" +msgstr "" + +#. TRANSLATORS: Flat / Material Design image style. Probably should not be translated +#: src/data/providers/images/SteamGridDB.vala:228 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Material" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:229 +msgctxt "imagesource_steamgriddb_image_style" +msgid "No logo" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:230 +msgctxt "imagesource_steamgriddb_image_style" +msgid "White logo" +msgstr "" + +#: src/data/providers/data/IGDB.vala:147 +msgid "" +"Monthly IGDB request quota has been reached. Set your own API key to use " +"IGDB data or disable IGDB." +msgstr "" + +#: src/data/providers/data/IGDB.vala:148 +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:40 +#: src/ui/views/WelcomeView.vala:53 src/ui/views/WelcomeView.vala:78 +#: src/ui/views/GamesView/GamesView.vala:230 +#: src/ui/views/GamesView/GamesView.vala:629 +msgid "Settings" +msgstr "" + +#: src/data/providers/data/IGDB.vala:356 +msgctxt "igdb_related_link" +msgid "Official website" +msgstr "" + +#: src/data/providers/data/IGDB.vala:469 +msgctxt "igdb_preferred_description" +msgid "When game has description, show description" +msgstr "" + +#: src/data/providers/data/IGDB.vala:476 +msgctxt "igdb_preferred_description" +msgid "of game" +msgstr "" + +#: src/data/providers/data/IGDB.vala:477 +msgctxt "igdb_preferred_description" +msgid "from IGDB" +msgstr "" + +#: src/data/providers/data/IGDB.vala:478 +msgctxt "igdb_preferred_description" +msgid "both" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:65 +msgid "Some settings will be applied after application restart" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:71 +msgid "Games directory contains space. It may cause problems for some games" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:36 +msgid "Interface" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:37 +msgid "Appearance" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:38 +msgid "General interface settings" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:48 +msgid "Dark theme" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:53 +msgctxt "icon_style" +msgid "Theme-based" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:54 +msgctxt "icon_style" +msgid "Symbolic" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:55 +msgctxt "icon_style" +msgid "Colored" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:57 +msgctxt "icon_style" +msgid "Icon style" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:84 +msgid "Game card" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:86 +msgid "Show platform icons" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:99 +msgctxt "grid_size" +msgid "Card size" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:117 +msgctxt "grid_size_preset" +msgid "Presets" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:139 +msgid "Games list: installed" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:140 +msgid "Games list: not installed" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:142 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:146 +msgctxt "list_style" +msgid "Show icon" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:143 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:147 +msgctxt "list_style" +msgid "Bold title" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:144 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:148 +msgctxt "list_style" +msgid "Show status" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:149 +msgctxt "list_style" +msgid "Dim" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:151 +msgid "Grid options" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:152 +msgid "List options" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:31 +msgid "Behavior" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:32 +msgid "Behavior settings" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:42 +msgid "Run games with double click" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:46 +msgid "Merge games from different sources" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:50 +msgid "Use imported tags" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:51 +msgid "General" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:52 +msgid "Collection" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:53 +msgid "Empty" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:65 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:85 +msgid "Collection directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:70 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:78 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:87 +msgid "Game directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:71 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:79 +msgid "Installers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:72 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:98 +msgid "DLC" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:73 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:197 +msgid "Bonus content" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:84 +msgid "Variable syntax: $var or ${var}" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:86 +msgid "Game name" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:88 +#: src/ui/views/GamesView/FiltersPopover.vala:127 +msgid "Platform" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:36 +msgid "Controller" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +msgid "Enabled" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:53 +msgid "Focus GameHub window with Guide button" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:57 +msgid "Controllers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:89 +msgid "Move focus" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:91 +msgid "Exit" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:40 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:108 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:92 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:95 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:36 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:77 +msgid "Disabled" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:47 +#: src/ui/dialogs/GameTweaksDialog.vala:53 +#: src/ui/views/GamesView/GameContextMenu.vala:183 +msgid "Tweaks" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:34 +msgid "Tweak launch options and apply them to games automatically" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:79 +msgid "" +"Tweaks are loaded from following directories in order\n" +"Last tweak overrides previous tweaks with same identifiers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:83 +msgid "Click to open" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:93 +#, c-format +msgid "Tweaks are loaded from %1$s and %2$d more directories (?)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:38 +msgid "Game sources" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +msgid "Steam API keys have limited number of uses per day" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:63 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:57 +msgid "Installation directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:176 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:81 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:34 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:75 +msgid "Not installed" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:116 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:96 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:99 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:85 +msgid "Not authenticated" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +#, c-format +msgid "Authenticated as %s" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:103 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +msgid "Authenticated" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:183 +#: src/ui/dialogs/InstallDialog.vala:53 src/ui/dialogs/InstallDialog.vala:111 +#: src/ui/views/GamesView/GameContextMenu.vala:80 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:233 +#: src/ui/widgets/TweaksList.vala:95 +msgid "Install" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:236 +msgid "Steam API key" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:50 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:54 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:48 +msgid "Games directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:63 +msgid "Logout" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:50 +msgid "Load games from Humble Trove" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:45 +msgid "Emulators" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:45 +msgid "Libretro core directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:46 +msgid "Libretro core info directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:50 +msgid "Ignored libretro cores" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:54 +msgid "Ignored game file extensions" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:66 +msgid "No cores found" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:70 +#, c-format +msgid "%u core found" +msgid_plural "%u cores found" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:46 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:168 +msgid "No custom emulators" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:164 +#, c-format +msgid "%u custom emulator" +msgid_plural "%u custom emulators" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:237 +msgid "Save" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:250 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:312 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/dialogs/GamePropertiesDialog.vala:168 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +#: src/ui/views/GamesView/AddGamePopover.vala:67 +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Executable" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:251 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/views/GamesView/AddGamePopover.vala:68 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Installer" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:256 +#: src/ui/dialogs/GamePropertiesDialog.vala:64 +#: src/ui/dialogs/GamePropertiesDialog.vala:69 +#: src/ui/views/GamesView/AddGamePopover.vala:73 +msgid "Name" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:272 +#: src/ui/dialogs/GamePropertiesDialog.vala:201 +#: src/ui/views/GamesView/AddGamePopover.vala:78 +msgid "Arguments" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:276 +msgid "Variables" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:277 +msgid "Game executable" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:278 +msgid "Game arguments" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:80 +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +msgid "Select emulator directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:292 +#: src/ui/dialogs/GamePropertiesDialog.vala:219 +msgid "Force compatibility mode" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:307 +msgid "Game file patterns" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:315 +msgid "Image" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:318 +msgid "Icon" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:325 +msgid "" +"findutils-compatible glob patterns\n" +"\n" +" Multiple patterns can be separated with |\n" +" Start pattern with ./ to match relative path\n" +" $basename variable will be replaced with game's executable " +"name (without extension)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:38 +msgid "Data" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:39 +msgid "Providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:40 +msgid "Third-party data providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:55 +msgid "Image providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:68 +msgid "Metadata providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:137 +msgid "Open website" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:36 +msgid "About" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:71 +msgid "Copy application version and environment info" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:78 +#: src/ui/views/WelcomeView.vala:57 +msgid "All your games in one place" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:92 +msgctxt "about_link" +msgid "Website" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:96 +msgctxt "about_link" +msgid "Source code on GitHub" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:103 +msgctxt "about_link" +msgid "Report a problem" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:104 +msgctxt "about_link" +msgid "Suggest translations" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:110 +msgctxt "about_link" +msgid "Issues" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:111 +msgctxt "about_link" +msgid "Contributors" +msgstr "" + +#. TRANSLATORS: Likely it should not be translated. GitHub Pulse is a page that shows recent repository activity: https://github.com/tkashkin/GameHub/pulse +#: src/ui/dialogs/SettingsDialog/pages/About.vala:114 +msgctxt "about_link" +msgid "Pulse" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:115 +msgctxt "about_link" +msgid "Forks" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:109 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:129 +msgid "Import" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:110 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:153 +msgid "Download" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:207 +msgid "Select installer" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:216 +#, c-format +msgid "Installer size: %s" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:348 +msgid "Unknown" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:49 +#, c-format +msgid "%s: Properties" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:84 +msgid "Images" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:126 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:160 +#: src/ui/views/GameDetailsView/blocks/Artwork.vala:62 +msgid "Download images" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:144 +msgid "Image URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:148 +msgid "Vertical image URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:157 +msgid "Icon URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Select working directory" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Working directory" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:214 +msgid "Compatibility" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:236 +msgid "Launch from terminal" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:252 +msgid "Copy to clipboard" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:254 +msgid "Add to Steam" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:255 +msgid "Add to the Steam library" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:53 +#, c-format +msgid "%s: Overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "Overlays are disabled" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "" +"Enable overlays to manage DLCs and mods\n" +"\n" +"Enabling will move game to the “base“ overlay" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:77 +#: src/ui/views/GamesView/GameContextMenu.vala:175 +msgid "Overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:105 +msgid "Overlay ID (directory name)" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:110 +msgid "Overlay name (optional)" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:112 +msgid "Add" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:127 +msgid "Enable overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:182 +#, c-format +msgid "" +"Overlay usage at this path may be unsafe\n" +"Proceed at your own risk\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:187 +#, c-format +msgid "" +"Overlay usage at this path is not supported\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:266 +msgid "Open directory" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:271 +msgid "Remove overlay" +msgstr "" + +#: src/ui/dialogs/CompatRunDialog.vala:48 +#: src/ui/views/GamesView/GameContextMenu.vala:46 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:235 +msgid "Run with compatibility layer" +msgstr "" + +#: src/ui/dialogs/CorruptedInstallerDialog.vala:71 +msgid "Corrupted installer: checksum mismatch in" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:57 +#: src/ui/views/GamesView/AddGamePopover.vala:105 +msgid "Import emulated games" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:75 +msgid "Select directory with emulated games" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:83 +msgid "Detected games" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:107 +msgid "Select all" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:115 +msgid "Select directory to import" +msgstr "" + +#: src/ui/dialogs/GameTweaksDialog.vala:40 +#, c-format +msgid "%s: Tweaks" +msgstr "" + +#: src/ui/views/WelcomeView.vala:52 +msgid "No enabled game sources" +msgstr "" + +#: src/ui/views/WelcomeView.vala:52 +msgid "Enable some game sources in settings" +msgstr "" + +#: src/ui/views/WelcomeView.vala:57 +msgid "Let's get started" +msgstr "" + +#: src/ui/views/WelcomeView.vala:71 +msgid "Skip" +msgstr "" + +#: src/ui/views/WelcomeView.vala:141 +msgid "Ready" +msgstr "" + +#: src/ui/views/WelcomeView.vala:147 +msgid "Authentication required" +msgstr "" + +#: src/ui/views/WelcomeView.vala:152 +msgid "Authenticating…" +msgstr "" + +#: src/ui/views/WelcomeView.vala:163 +#, c-format +msgid "Install %s" +msgstr "" + +#: src/ui/views/WelcomeView.vala:164 +msgid "Return to GameHub after installing" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "No games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "Get some games or enable some game sources in settings" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:150 +msgid "Grid view" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:151 +msgid "List view" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:159 +msgid "All games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:182 +msgid "Downloads" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:208 +msgid "Filters" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:216 +#: src/ui/views/GamesView/AddGamePopover.vala:84 +msgid "Add game" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:223 +msgid "Search" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:328 +msgid "Menu" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:329 +#: src/ui/views/GameDetailsView/GameDetailsView.vala:104 +msgid "Back" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:550 +#, c-format +msgid "%u game" +msgid_plural "%u games" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GamesView/GamesView.vala:553 +#, c-format +msgctxt "games_view_subtitle_filtered_games" +msgid "%1$u / %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:557 +#, c-format +msgctxt "games_view_subtitle" +msgid "%1$s: %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:568 +msgid "No user-added games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:569 +msgid "Add some games using plus button" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:573 +#, c-format +msgid "No %s games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:574 +msgid "Get some Linux-compatible games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:584 +#, c-format +msgid "No games matching “%s”" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:589 +#, c-format +msgid "No %1$s games matching “%2$s”" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:627 +msgid "" +"No games were loaded from Steam. Set your games list privacy to public or " +"use your own Steam API key in settings." +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:628 +msgid "Privacy" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:739 +msgid "Downloading images" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:753 +#, c-format +msgid "Downloading image: %s" +msgstr "" + +#: src/ui/views/GamesView/DownloadProgressView.vala:131 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:162 +msgid "Pause download" +msgstr "" + +#: src/ui/views/GamesView/DownloadProgressView.vala:137 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:168 +msgid "Resume download" +msgstr "" + +#: src/ui/views/GamesView/DownloadProgressView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:174 +msgid "Cancel download" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:77 +msgid "Group" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:102 +msgid "Sort" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:234 +#: src/ui/widgets/GameTagsList.vala:58 +msgid "Tags" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:353 +msgid "All platforms" +msgstr "" + +#: src/ui/views/GamesView/AddGamePopover.vala:77 +msgid "Select game executable" +msgstr "" + +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Select game directory" +msgstr "" + +#: src/ui/views/GamesView/AddGamePopover.vala:111 +msgid "Download game images" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:87 +msgid "Details" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:117 +msgctxt "game_context_menu" +msgid "Favorite" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:121 +msgctxt "game_context_menu" +msgid "Hidden" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:133 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:236 +msgid "Open installation directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:142 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:237 +msgid "Open installers collection directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:151 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:238 +msgid "Open bonus collection directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:160 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:239 +msgid "Open screenshots directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +msgid "Uninstall" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:192 +msgid "Properties" +msgstr "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:100 +#, c-format +msgid "%d game selected" +msgid_plural "%d games selected" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:144 +#, c-format +msgid "%d game will be installed" +msgid_plural "%d games will be installed" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:154 +#, c-format +msgid "%d game will be downloaded" +msgid_plural "%d games will be downloaded" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:161 +#, c-format +msgid "Image for %d game will be searched" +msgid_plural "Images for %d games will be searched" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:168 +#, c-format +msgid "%d game will be uninstalled" +msgid_plural "%d games will be uninstalled" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:174 +msgid "Refresh" +msgstr "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:175 +#, c-format +msgid "" +"%d game will be removed from database. Restart GameHub to fetch new data" +msgid_plural "" +"%d games will be removed from database. Restart GameHub to fetch new data" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:240 +msgid "Open store page" +msgstr "" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:242 +msgid "Game properties" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:46 +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:60 +msgid "Playtime" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:52 +msgid "Playtime (local)" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:69 +msgid "Last launch" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:46 +msgid "Achievements" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:85 +#, c-format +msgid "Unlocked: %s" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:90 +#, c-format +msgid "Global percentage: %g%%" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:77 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:103 +msgid "Language" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:80 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:106 +msgid "Languages" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:147 +#, c-format +msgid "%u DLCs cannot be installed" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:71 +msgid "Category" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:74 +msgid "Categories" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:90 +msgid "Genre" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:93 +msgid "Genres" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:109 +msgctxt "igdb" +msgid "Popularity" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:115 +msgctxt "igdb" +msgid "Aggregated rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:116 +msgctxt "igdb" +msgid "IGDB user rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:117 +msgctxt "igdb" +msgid "Total rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:126 +msgctxt "igdb" +msgid "Release date" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:133 +msgctxt "igdb" +msgid "Platforms" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:139 +msgctxt "igdb" +msgid "Genres" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:145 +msgctxt "igdb" +msgid "Keywords" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:152 +msgctxt "igdb" +msgid "Links" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:208 +#, c-format +msgid "Based on %d rating" +msgid_plural "Based on %d ratings" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:290 +msgctxt "igdb" +msgid "Summary" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:301 +msgctxt "igdb" +msgid "Storyline" +msgstr "" + +#: src/ui/widgets/FileChooserEntry.vala:49 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select file" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "No images" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "" +"There are no images found for this game\n" +"Make sure game name is correct" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:94 +msgid "Search images:" +msgstr "" + +#: src/ui/widgets/CompatToolPicker.vala:53 +msgid "Compatibility layer:" +msgstr "" + +#: src/ui/widgets/CompatToolPicker.vala:92 +msgid "Configure" +msgstr "" + +#: src/ui/widgets/GameTagsList.vala:109 +msgid "Add tag" +msgstr "" + +#: src/ui/widgets/TweaksList.vala:86 +msgid "No description" +msgstr "" + +#: src/ui/widgets/TweaksList.vala:124 +msgid "Edit file" +msgstr "" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dh" +msgstr "" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dm" +msgstr "" + +#: src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%ds" +msgstr "" + +#: src/settings/UI.vala:153 +msgctxt "grid_size_preset" +msgid "Steam" +msgstr "" + +#: src/settings/UI.vala:154 +msgctxt "grid_size_preset" +msgid "Steam (vertical)" +msgstr "" + +#: src/settings/UI.vala:155 +msgctxt "grid_size_preset" +msgid "GOG" +msgstr "" + +#: src/settings/UI.vala:156 +msgctxt "grid_size_preset" +msgid "GOG (vertical)" +msgstr "" + +#: src/settings/UI.vala:157 +msgctxt "grid_size_preset" +msgid "Square" +msgstr "" + +#: src/settings/UI.vala:158 +msgctxt "grid_size_preset" +msgid "Custom" +msgstr "" + +#: src/utils/downloader/Downloader.vala:200 +msgctxt "dl_status" +msgid "Queued" +msgstr "" + +#: src/utils/downloader/Downloader.vala:201 +msgctxt "dl_status" +msgid "Starting download" +msgstr "" + +#: src/utils/downloader/Downloader.vala:202 +msgctxt "dl_status" +msgid "Download started" +msgstr "" + +#: src/utils/downloader/Downloader.vala:203 +msgctxt "dl_status" +msgid "Download finished" +msgstr "" + +#: src/utils/downloader/Downloader.vala:204 +msgctxt "dl_status" +msgid "Download failed" +msgstr "" + +#: src/utils/downloader/Downloader.vala:208 +#, c-format +msgctxt "dl_status" +msgid "Downloading: %s" +msgstr "" + +#: src/utils/downloader/Downloader.vala:210 +msgctxt "dl_status" +msgid "Downloading" +msgstr "" + +#: src/utils/downloader/Downloader.vala:214 +#, c-format +msgctxt "dl_status" +msgid "Paused: %s" +msgstr "" + +#: src/utils/downloader/Downloader.vala:216 +msgctxt "dl_status" +msgid "Paused" +msgstr "" + +#: src/utils/downloader/Downloader.vala:218 +msgctxt "dl_status" +msgid "Download cancelled" +msgstr "" + +#. TRANSLATORS: Download progress template. %1$d - percentage, %2$s / %3$s - downloaded portion and total file size, %4$s - download speed +#: src/utils/downloader/Downloader.vala:262 +#, c-format +msgctxt "dl_status" +msgid "%1$d%% (%2$s / %3$s) [%4$s/s]" +msgstr "" diff --git a/po/id.po b/po/id.po new file mode 100644 index 00000000..e2880988 --- /dev/null +++ b/po/id.po @@ -0,0 +1,1891 @@ +# Indonesian translations for com.github.tkashkin.gamehub package. +# Copyright (C) 2018 THE com.github.tkashkin.gamehub'S COPYRIGHT HOLDER +# This file is distributed under the same license as the com.github.tkashkin.gamehub package. +# Automatically generated, 2018. +# Anatoliy Kashkin , 2018. +# ditokp , 2018. +# ekickx , 2019. +# frottle , 2020. +msgid "" +msgstr "" +"Project-Id-Version: com.github.tkashkin.gamehub\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-26 06:40+0300\n" +"PO-Revision-Date: 2020-03-09 16:33+0000\n" +"Last-Translator: frottle \n" +"Language-Team: Indonesian \n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 4.0-dev\n" + +#: src/app.vala:91 +msgid "Show help" +msgstr "Tampilkan bantuan" + +#: src/app.vala:92 +msgid "Show application version and exit" +msgstr "Tampilkan versi aplikasi lalu keluar" + +#: src/app.vala:93 +msgid "Restart with GDB debugger attached" +msgstr "Mulai ulang dengan debugger GDB terpasang" + +#: src/app.vala:94 +msgid "Show full GDB backtrace" +msgstr "Tampilkan semua backtrace GDB" + +#: src/app.vala:95 +msgid "Treat fatal errors as criticals and crash application" +msgstr "Perlakukan kesalahan fatal sebagai kritikal dan lumpuhkan aplikasi" + +#: src/app.vala:99 +msgid "Show main window" +msgstr "Tampilkan jendela utama" + +#: src/app.vala:100 +msgid "Show application settings dialog" +msgstr "Tampilkan dialog setelan aplikasi" + +#: src/app.vala:101 +msgid "Show about dialog" +msgstr "Tampilkan dialog tentang" + +#: src/app.vala:102 +msgid "Maximum number of background worker threads" +msgstr "Jumlah maksimum dari thread pekerja latar belakang" + +#: src/app.vala:106 +msgid "Run game" +msgstr "Jalankan permainan" + +#: src/app.vala:107 +msgid "Show compatibility options dialog" +msgstr "Tampilkan dialog opsi kompatibilitas" + +#: src/app.vala:108 +msgid "Open game details" +msgstr "Buka rincian permainan" + +#: src/app.vala:109 +msgid "Open game properties" +msgstr "Buka properti permainan" + +#: src/app.vala:113 +msgid "Enable debug logging" +msgstr "Aktifkan pencatatan debug" + +#: src/app.vala:114 +msgid "" +"Log authentication process and sensitive information like authentication " +"tokens" +msgstr "" +"Catat proses autentikasi dan informasi sensitif seperti token autentikasi" + +#: src/app.vala:115 +msgid "Log download manager" +msgstr "Catat pengelola unduhan" + +#: src/app.vala:116 +msgid "Log background workers start/stop" +msgstr "Catat mulai/berhentinya pekerja latar belakang" + +#: src/app.vala:117 +msgid "Disable log messages filtering" +msgstr "Non-aktifkan penyaringan pesan pencatatan" + +#: src/app.vala:118 +msgid "Verbose logging" +msgstr "Pencatatan panjang" + +#: src/app.vala:247 +msgid "Game Options:" +msgstr "Opsi permainan:" + +#: src/app.vala:247 +msgid "Show game options help" +msgstr "Tampilkan bantuan opsi permainan" + +#: src/app.vala:255 +msgid "Logging Options:" +msgstr "Opsi Pencatatan:" + +#: src/app.vala:255 +msgid "Show logging options help" +msgstr "Tampilkan bantuan opsi pencatatan" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +msgid "Select executable" +msgstr "Pilih berkas yang dapat dieksekusi" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:181 src/ui/views/GamesView/GamesView.vala:330 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select" +msgstr "Memilih" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:180 src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Cancel" +msgstr "Batal" + +#: src/data/Runnable.vala:166 src/ui/widgets/FileChooserEntry.vala:49 +msgid "Select directory" +msgstr "Pilih direktori" + +#: src/data/Runnable.vala:619 +#, c-format +msgid "Part %1$u of %2$u: %3$s" +msgstr "Bagian %1$u dari %2$u: %3$s" + +#: src/data/Runnable.vala:642 src/ui/dialogs/CorruptedInstallerDialog.vala:48 +#, c-format +msgid "%s: corrupted installer" +msgstr "%s: penginstal rusak" + +#: src/data/Runnable.vala:643 +#, c-format +msgid "Checksum mismatch in %s" +msgstr "Checksum tidak cocok pada %s" + +#: src/data/Runnable.vala:657 src/ui/dialogs/CorruptedInstallerDialog.vala:126 +msgid "Show file" +msgstr "Tampilkan berkas" + +#: src/data/Runnable.vala:658 src/ui/dialogs/CorruptedInstallerDialog.vala:132 +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#: src/ui/widgets/TagRow.vala:146 +msgid "Remove" +msgstr "Hapus" + +#: src/data/Runnable.vala:659 src/ui/dialogs/CorruptedInstallerDialog.vala:128 +msgid "Backup" +msgstr "Cadangkan" + +#: src/data/Runnable.vala:778 +#, c-format +msgid "%s: cannot detect main executable" +msgstr "%s: tidak dapat mendeteksi berkas utama yang dapat dieksekusi" + +#: src/data/Runnable.vala:779 +msgid "" +"Main executable file for this game cannot be detected automatically.\n" +"Please set main executable in game's properties." +msgstr "" +"Berkas utama yang dapat dieksekusi untuk permainan ini tidak dapat " +"terdeteksi secara otomatis.\n" +"Silakan menetapkan berkas utama yang dapat dieksekusi pada properti " +"permainan." + +#: src/data/Runnable.vala:908 +msgctxt "platform" +msgid "Emulated" +msgstr "Teremulasi" + +#: src/data/Game.vala:625 +msgctxt "status" +msgid "Running" +msgstr "Berjalan" + +#: src/data/Game.vala:628 +msgctxt "status" +msgid "Installed" +msgstr "Terpasang" + +#: src/data/Game.vala:629 +msgctxt "status" +msgid "Installing" +msgstr "Memasang" + +#: src/data/Game.vala:630 +msgctxt "status" +msgid "Verifying installer integrity" +msgstr "Memverifikasi integritas penginstal" + +#: src/data/Game.vala:631 +msgctxt "status" +msgid "Download started" +msgstr "Unduhan dimulai" + +#: src/data/Game.vala:633 +msgctxt "status" +msgid "Not installed" +msgstr "Tidak terpasang" + +#: src/data/Game.vala:643 +msgctxt "status_header" +msgid "Installed" +msgstr "Terpasang" + +#: src/data/Game.vala:644 +msgctxt "status_header" +msgid "Installing" +msgstr "Memasang" + +#: src/data/Game.vala:646 +msgctxt "status_header" +msgid "Downloading" +msgstr "Mengunduh" + +#: src/data/Game.vala:648 +msgctxt "status_header" +msgid "Not installed" +msgstr "Tidak terpasang" + +#: src/data/GameSource.vala:31 +#, c-format +msgid "%s games" +msgstr "%s permainan" + +#: src/data/sources/steam/Steam.vala:43 +msgid "Your SteamID will be read from Steam configuration file" +msgstr "SteamID Anda akan dibaca dari berkas konfigurasi Steam" + +#: src/data/sources/steam/Steam.vala:46 +msgid "" +"Steam config file not found.\n" +"Login into your account in Steam client and return to GameHub" +msgstr "" +"Berkas konfigurasi Steam tidak ditemukan.\n" +"Masuk ke akun Anda di klien Steam dan kembali ke GameHub" + +#: src/data/sources/gog/GOGGame.vala:983 +#, c-format +msgid "DLC: %s" +msgstr "DLC: %s" + +#: src/data/sources/humble/HumbleGame.vala:343 +#, c-format +msgid "%s: no available installers" +msgstr "%s: tidak ada penginstal yang tersedia" + +#: src/data/sources/humble/HumbleGame.vala:344 +msgid "" +"Cannot get Trove download URL.\n" +"Make sure your Humble Monthly subscription is active." +msgstr "" +"Tidak dapat mengambil URL unduhan Trove.\n" +"Pastikan layanan langganan Humble Monthly Anda masih aktif." + +#: src/data/sources/itch/ItchDownloader.vala:192 +#, c-format +msgctxt "itch_dl_status" +msgid "%s left;" +msgstr "tersisa %s;" + +#: src/data/sources/itch/ItchDownloader.vala:195 +#, c-format +msgctxt "itch_dl_status" +msgid "%d%%" +msgstr "%d%%" + +#: src/data/sources/itch/ItchDownloader.vala:198 +#, c-format +msgctxt "itch_dl_status" +msgid "(%1$s / %2$s)" +msgstr "(%1$s / %2$s)" + +#: src/data/sources/itch/ItchDownloader.vala:201 +#, c-format +msgctxt "itch_dl_status" +msgid "[%s/s]" +msgstr "[%s/s]" + +#: src/data/sources/user/User.vala:30 +msgid "User games" +msgstr "Game pengguna" + +#: src/data/db/tables/Tags.vala:225 +msgctxt "tag" +msgid "Favorites" +msgstr "Favorit" + +#: src/data/db/tables/Tags.vala:226 +msgctxt "tag" +msgid "Not installed" +msgstr "Tidak terpasang" + +#: src/data/db/tables/Tags.vala:227 +msgctxt "tag" +msgid "Installed" +msgstr "Terpasang" + +#: src/data/db/tables/Tags.vala:228 +msgctxt "tag" +msgid "Hidden" +msgstr "Tersembunyi" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit script" +msgstr "Sunting skrip" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit custom script" +msgstr "Sunting skrip kustom" + +#: src/data/compat/Innoextract.vala:55 +#, c-format +msgid "" +"Innoextract %1$s is not supported and may not be able to extract some " +"games correctly.\n" +"Install innoextract %2$s or newer." +msgstr "" +"Innoextract %1$s tidak didukung dan kemungkinan tidak bisa " +"mengekstrak beberapa permainan dengan benar.\n" +"Silakan memasang innoextract %2$s atau yang lebih baru." + +#: src/data/compat/WineWrap.vala:61 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:242 +#: src/ui/dialogs/CompatRunDialog.vala:102 +#: src/ui/views/GamesView/GameContextMenu.vala:53 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:234 +msgid "Run" +msgstr "Jalankan" + +#: src/data/compat/WineWrap.vala:64 +msgid "Show WineWrap menu" +msgstr "Tampilkan menu WineWrap" + +#: src/data/compat/WineWrap.vala:67 src/data/compat/Proton.vala:122 +#: src/data/compat/Wine.vala:83 +msgid "Kill apps in prefix" +msgstr "Matikan aplikasi dalam prefiks" + +#: src/data/compat/Proton.vala:47 +msgid "Proton prefix" +msgstr "Prefiks Proton" + +#: src/data/compat/Proton.vala:110 src/data/compat/Wine.vala:71 +msgid "Open prefix directory" +msgstr "Buka direktori prefiks" + +#: src/data/compat/Proton.vala:113 src/data/compat/Wine.vala:74 +msgid "Run winecfg" +msgstr "Jalankan winecfg" + +#: src/data/compat/Proton.vala:116 src/data/compat/Wine.vala:77 +msgid "Run winetricks" +msgstr "Jalankan winetricks" + +#: src/data/compat/Proton.vala:119 src/data/compat/Wine.vala:80 +msgid "Run taskmgr" +msgstr "Jalankan taskmgr" + +#: src/data/compat/Wine.vala:53 +msgid "Wine prefix" +msgstr "Prefiks Wine" + +#: src/data/compat/Wine.vala:55 +msgid "Environment variables" +msgstr "Variabel lingkungan" + +#: src/data/compat/Wine.vala:60 +msgid "InnoSetup default options" +msgstr "Opsi bawaan InnoSetup" + +#: src/data/compat/RetroArch.vala:53 +msgid "Libretro core file" +msgstr "Berkas inti Libretro" + +#: src/data/compat/CustomEmulator.vala:43 +msgid "Custom emulator" +msgstr "Emulator kustom" + +#: src/data/compat/CustomEmulator.vala:48 +msgid "Emulator" +msgstr "Emulator" + +#: src/data/compat/CustomEmulator.vala:49 +msgid "Launch in game directory" +msgstr "Luncurkan di direktori permainan" + +#: src/data/adapters/GamesAdapter.vala:440 +msgctxt "status_header" +msgid "Favorites" +msgstr "Favorit" + +#: src/data/adapters/GamesAdapter.vala:445 +#, c-format +msgctxt "status_header" +msgid "%s: Favorites" +msgstr "%s Favorit" + +#: src/data/adapters/GamesAdapter.vala:491 +msgid "Merging games" +msgstr "Menggabungkan permainan" + +#: src/data/adapters/GamesAdapter.vala:504 +#, c-format +msgid "Merging games from %s" +msgstr "Menggabungkan permainan dari %s" + +#: src/data/adapters/GamesAdapter.vala:551 +#, c-format +msgid "Loading games from %s" +msgstr "Memuat game dari %s" + +#: src/data/adapters/GamesAdapter.vala:678 +msgctxt "sort_mode" +msgid "By name" +msgstr "Berdasarkan nama" + +#: src/data/adapters/GamesAdapter.vala:679 +msgctxt "sort_mode" +msgid "By last launch" +msgstr "Berdasarkan terakhir diluncurkan" + +#: src/data/adapters/GamesAdapter.vala:680 +msgctxt "sort_mode" +msgid "By playtime" +msgstr "Berdasarkan waktu main" + +#: src/data/adapters/GamesAdapter.vala:705 +msgctxt "group_mode" +msgid "Do not group" +msgstr "Jangan dikelompokkan" + +#: src/data/adapters/GamesAdapter.vala:706 +msgctxt "group_mode" +msgid "By status" +msgstr "Berdasarkan status" + +#: src/data/adapters/GamesAdapter.vala:707 +msgctxt "group_mode" +msgid "By source" +msgstr "Berdasarkan sumber" + +#: src/data/providers/images/SteamGridDB.vala:151 +#: src/data/providers/data/IGDB.vala:431 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:217 +msgid "Default" +msgstr "Bawaan" + +#: src/data/providers/images/SteamGridDB.vala:158 +#: src/data/providers/data/IGDB.vala:438 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:225 +msgid "Restore default API key" +msgstr "Pulihkan kunci API bawaan" + +#: src/data/providers/images/SteamGridDB.vala:169 +#: src/data/providers/data/IGDB.vala:449 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:108 +msgid "API key" +msgstr "Kunci API" + +#: src/data/providers/images/SteamGridDB.vala:177 +#: src/data/providers/data/IGDB.vala:457 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:53 +msgid "Generate key" +msgstr "Hasilkan kunci" + +#: src/data/providers/images/SteamGridDB.vala:208 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Style" +msgstr "Gaya" + +#: src/data/providers/images/SteamGridDB.vala:209 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Score" +msgstr "Nilai" + +#: src/data/providers/images/SteamGridDB.vala:213 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Author" +msgstr "Pembuat" + +#: src/data/providers/images/SteamGridDB.vala:225 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Alternate" +msgstr "Alternatif" + +#: src/data/providers/images/SteamGridDB.vala:226 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Blurred" +msgstr "Dikaburkan" + +#. TRANSLATORS: Flat / Material Design image style. Probably should not be translated +#: src/data/providers/images/SteamGridDB.vala:228 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Material" +msgstr "Material" + +#: src/data/providers/images/SteamGridDB.vala:229 +msgctxt "imagesource_steamgriddb_image_style" +msgid "No logo" +msgstr "Tanpa logo" + +#: src/data/providers/images/SteamGridDB.vala:230 +msgctxt "imagesource_steamgriddb_image_style" +msgid "White logo" +msgstr "Logo putih" + +#: src/data/providers/data/IGDB.vala:147 +msgid "" +"Monthly IGDB request quota has been reached. Set your own API key to use " +"IGDB data or disable IGDB." +msgstr "" +"Kuota permintaan bulanan IGDB sudah habis. Tetapkan kunci API Anda sendiri " +"untuk menggunakan data IGDB atau non-aktifkan IGDB." + +#: src/data/providers/data/IGDB.vala:148 +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:40 +#: src/ui/views/WelcomeView.vala:53 src/ui/views/WelcomeView.vala:78 +#: src/ui/views/GamesView/GamesView.vala:230 +#: src/ui/views/GamesView/GamesView.vala:629 +msgid "Settings" +msgstr "Pengaturan" + +#: src/data/providers/data/IGDB.vala:356 +msgctxt "igdb_related_link" +msgid "Official website" +msgstr "Situs web resmi" + +#: src/data/providers/data/IGDB.vala:469 +msgctxt "igdb_preferred_description" +msgid "When game has description, show description" +msgstr "Jika permainan memiliki deskripsi, tampilkan deskripsi" + +#: src/data/providers/data/IGDB.vala:476 +msgctxt "igdb_preferred_description" +msgid "of game" +msgstr "dari permainan" + +#: src/data/providers/data/IGDB.vala:477 +msgctxt "igdb_preferred_description" +msgid "from IGDB" +msgstr "dari IGDB" + +#: src/data/providers/data/IGDB.vala:478 +msgctxt "igdb_preferred_description" +msgid "both" +msgstr "keduanya" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:65 +msgid "Some settings will be applied after application restart" +msgstr "Beberapa pengaturan akan diterapkan setelah aplikasi dimulai ulang" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:71 +msgid "Games directory contains space. It may cause problems for some games" +msgstr "" +"Terdapat spasi pada direktori permainan. Ini dapat menyebabkan masalah pada " +"beberapa permainan" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:36 +msgid "Interface" +msgstr "Antarmuka" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:37 +msgid "Appearance" +msgstr "Tampilan" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:38 +msgid "General interface settings" +msgstr "Pengaturan antarmuka umum" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:48 +msgid "Dark theme" +msgstr "Tema gelap" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:53 +msgctxt "icon_style" +msgid "Theme-based" +msgstr "Berdasarkan tema" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:54 +msgctxt "icon_style" +msgid "Symbolic" +msgstr "Simbolis" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:55 +msgctxt "icon_style" +msgid "Colored" +msgstr "Berwarna" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:57 +msgctxt "icon_style" +msgid "Icon style" +msgstr "Gaya ikon" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:84 +msgid "Game card" +msgstr "Kartu permainan" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:86 +msgid "Show platform icons" +msgstr "Tampilkan ikon platform" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:99 +msgctxt "grid_size" +msgid "Card size" +msgstr "Ukuran kartu" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:117 +msgctxt "grid_size_preset" +msgid "Presets" +msgstr "Prasetel" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:139 +msgid "Games list: installed" +msgstr "Daftar permainan: terpasang" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:140 +msgid "Games list: not installed" +msgstr "Daftar permainan: tidak terpasang" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:142 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:146 +msgctxt "list_style" +msgid "Show icon" +msgstr "Tampilkan ikon" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:143 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:147 +msgctxt "list_style" +msgid "Bold title" +msgstr "Judul tebal" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:144 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:148 +msgctxt "list_style" +msgid "Show status" +msgstr "Tampilkan status" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:149 +msgctxt "list_style" +msgid "Dim" +msgstr "Redup" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:151 +msgid "Grid options" +msgstr "Opsi grid" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:152 +msgid "List options" +msgstr "Opsi daftar" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:31 +msgid "Behavior" +msgstr "Perilaku" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:32 +msgid "Behavior settings" +msgstr "Pengaturan perilaku" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:42 +msgid "Run games with double click" +msgstr "Jalankan permainan dengan klik dua kali" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:46 +msgid "Merge games from different sources" +msgstr "Gabungkan permainan dari berbagai sumber" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:50 +msgid "Use imported tags" +msgstr "Gunakan label yang diimpor" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:51 +msgid "General" +msgstr "Umum" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:52 +msgid "Collection" +msgstr "Koleksi" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:53 +msgid "Empty" +msgstr "Kosong" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:65 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:85 +msgid "Collection directory" +msgstr "Direktori koleksi" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:70 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:78 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:87 +msgid "Game directory" +msgstr "Direktori permainan" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:71 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:79 +msgid "Installers" +msgstr "Penginstal" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:72 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:98 +msgid "DLC" +msgstr "DLC" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:73 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:197 +msgid "Bonus content" +msgstr "Konten bonus" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:84 +msgid "Variable syntax: $var or ${var}" +msgstr "Sintaks variabel: $var atau ${var}" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:86 +msgid "Game name" +msgstr "Nama permainan" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:88 +#: src/ui/views/GamesView/FiltersPopover.vala:127 +msgid "Platform" +msgstr "Platform" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:36 +msgid "Controller" +msgstr "Kontroler" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +msgid "Enabled" +msgstr "Diaktifkan" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:53 +msgid "Focus GameHub window with Guide button" +msgstr "Fokuskan jendela GameHub dengan tombol Guide" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:57 +msgid "Controllers" +msgstr "Kontroler" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:89 +msgid "Move focus" +msgstr "Pindahkan fokus" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:91 +msgid "Exit" +msgstr "Keluar" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:40 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:108 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:92 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:95 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:36 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:77 +msgid "Disabled" +msgstr "Non-aktif" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:47 +#: src/ui/dialogs/GameTweaksDialog.vala:53 +#: src/ui/views/GamesView/GameContextMenu.vala:183 +msgid "Tweaks" +msgstr "Penyesuaian" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:34 +msgid "Tweak launch options and apply them to games automatically" +msgstr "Sesuaikan opsi peluncuran dan terapkan pada permainan secara otomatis" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:79 +msgid "" +"Tweaks are loaded from following directories in order\n" +"Last tweak overrides previous tweaks with same identifiers" +msgstr "" +"Penyesuaian dimuat dari direktori berikut secara berurutan\n" +"Penyesuaian terakhir" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:83 +msgid "Click to open" +msgstr "Klik untuk membuka" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:93 +#, c-format +msgid "Tweaks are loaded from %1$s and %2$d more directories (?)" +msgstr "" +"Penyesuaian dimuat dari %1$s dan %2$d direktori lainnya (?)" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:38 +msgid "Game sources" +msgstr "Sumber permainan" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +msgid "Steam API keys have limited number of uses per day" +msgstr "Kunci API Steam memiliki jumlah penggunaan terbatas per hari" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:63 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:57 +msgid "Installation directory" +msgstr "Direktori pemasangan" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:176 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:81 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:34 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:75 +msgid "Not installed" +msgstr "Tidak terpasang" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:116 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:96 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:99 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:85 +msgid "Not authenticated" +msgstr "Belum diautentikasi" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +#, c-format +msgid "Authenticated as %s" +msgstr "Mengautentikasi sebagai %s" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:103 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +msgid "Authenticated" +msgstr "Terautentikasi" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:183 +#: src/ui/dialogs/InstallDialog.vala:53 src/ui/dialogs/InstallDialog.vala:111 +#: src/ui/views/GamesView/GameContextMenu.vala:80 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:233 +#: src/ui/widgets/TweaksList.vala:95 +msgid "Install" +msgstr "Pasang" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:236 +msgid "Steam API key" +msgstr "Kunci API Steam" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:50 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:54 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:48 +msgid "Games directory" +msgstr "Direktori permainan" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:63 +msgid "Logout" +msgstr "Keluar" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:50 +msgid "Load games from Humble Trove" +msgstr "Muat permainan dari Humble Trove" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:45 +msgid "Emulators" +msgstr "Emulator" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:45 +msgid "Libretro core directory" +msgstr "Direktori inti Libretro" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:46 +msgid "Libretro core info directory" +msgstr "Info direktori inti Libretro" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:50 +msgid "Ignored libretro cores" +msgstr "Inti libretro yang diabaikan" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:54 +msgid "Ignored game file extensions" +msgstr "Ekstensi berkas permainan yang diabaikan" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:66 +msgid "No cores found" +msgstr "Tidak ada inti yang ditemukan" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:70 +#, c-format +msgid "%u core found" +msgid_plural "%u cores found" +msgstr[0] "%u inti ditemukan" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:46 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:168 +msgid "No custom emulators" +msgstr "Tidak ada emulator kustom" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:164 +#, c-format +msgid "%u custom emulator" +msgid_plural "%u custom emulators" +msgstr[0] "%u emulator kustom" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:237 +msgid "Save" +msgstr "Simpan" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:250 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:312 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/dialogs/GamePropertiesDialog.vala:168 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +#: src/ui/views/GamesView/AddGamePopover.vala:67 +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Executable" +msgstr "Dapat dieksekusi" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:251 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/views/GamesView/AddGamePopover.vala:68 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Installer" +msgstr "Penginstal" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:256 +#: src/ui/dialogs/GamePropertiesDialog.vala:64 +#: src/ui/dialogs/GamePropertiesDialog.vala:69 +#: src/ui/views/GamesView/AddGamePopover.vala:73 +msgid "Name" +msgstr "Nama" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:272 +#: src/ui/dialogs/GamePropertiesDialog.vala:201 +#: src/ui/views/GamesView/AddGamePopover.vala:78 +msgid "Arguments" +msgstr "Argumen" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:276 +msgid "Variables" +msgstr "Variabel" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:277 +msgid "Game executable" +msgstr "Berkas permainan yang dapat dieksekusi" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:278 +msgid "Game arguments" +msgstr "Argumen permainan" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:80 +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Directory" +msgstr "Direktori" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +msgid "Select emulator directory" +msgstr "Pilih direktori emulator" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:292 +#: src/ui/dialogs/GamePropertiesDialog.vala:219 +msgid "Force compatibility mode" +msgstr "Paksakan mode kompatibilitas" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:307 +msgid "Game file patterns" +msgstr "Susunan berkas permainan" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:315 +msgid "Image" +msgstr "Gambar" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:318 +msgid "Icon" +msgstr "Ikon" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:325 +msgid "" +"findutils-compatible glob patterns\n" +"\n" +" Multiple patterns can be separated with |\n" +" Start pattern with ./ to match relative path\n" +" $basename variable will be replaced with game's executable " +"name (without extension)" +msgstr "" +"findutils-susunan glob yang kompatibel\n" +"\n" +" Susunan ganda dapat dipisahkan dengan |\n" +" Mulai susunan dengan ./ agar sesuai dengan jalur relatif\n" +" Variabel $basename akan ditukar dengan nama berkas permainan " +"yang dapat dieksekusi (tanpa ekstensi)" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:38 +msgid "Data" +msgstr "Data" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:39 +msgid "Providers" +msgstr "Penyedia" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:40 +msgid "Third-party data providers" +msgstr "Penyedia data pihak ke-tiga" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:55 +msgid "Image providers" +msgstr "Penyedia gambar" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:68 +msgid "Metadata providers" +msgstr "Penyedia metadata" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:137 +msgid "Open website" +msgstr "Buka situs web" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:36 +msgid "About" +msgstr "Tentang" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:71 +msgid "Copy application version and environment info" +msgstr "Salin versi aplikasi dan informasi lingkungan" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:78 +#: src/ui/views/WelcomeView.vala:57 +msgid "All your games in one place" +msgstr "Semua permainan Anda di satu tempat" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:92 +msgctxt "about_link" +msgid "Website" +msgstr "Situs web" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:96 +msgctxt "about_link" +msgid "Source code on GitHub" +msgstr "Kode sumber di GitHub" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:103 +msgctxt "about_link" +msgid "Report a problem" +msgstr "Laporkan masalah" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:104 +msgctxt "about_link" +msgid "Suggest translations" +msgstr "Ajukan terjemahan" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:110 +msgctxt "about_link" +msgid "Issues" +msgstr "Isu" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:111 +msgctxt "about_link" +msgid "Contributors" +msgstr "Kontributor" + +#. TRANSLATORS: Likely it should not be translated. GitHub Pulse is a page that shows recent repository activity: https://github.com/tkashkin/GameHub/pulse +#: src/ui/dialogs/SettingsDialog/pages/About.vala:114 +msgctxt "about_link" +msgid "Pulse" +msgstr "Pulse" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:115 +msgctxt "about_link" +msgid "Forks" +msgstr "Fork" + +#: src/ui/dialogs/InstallDialog.vala:109 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:129 +msgid "Import" +msgstr "Impor" + +#: src/ui/dialogs/InstallDialog.vala:110 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:153 +msgid "Download" +msgstr "Unduh" + +#: src/ui/dialogs/InstallDialog.vala:207 +msgid "Select installer" +msgstr "Pilih penginstal" + +#: src/ui/dialogs/InstallDialog.vala:216 +#, c-format +msgid "Installer size: %s" +msgstr "Ukuran penginstal: %s" + +#: src/ui/dialogs/InstallDialog.vala:348 +msgid "Unknown" +msgstr "Tidak diketahui" + +#: src/ui/dialogs/GamePropertiesDialog.vala:49 +#, c-format +msgid "%s: Properties" +msgstr "%s: Properti" + +#: src/ui/dialogs/GamePropertiesDialog.vala:84 +msgid "Images" +msgstr "Gambar" + +#: src/ui/dialogs/GamePropertiesDialog.vala:126 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:160 +#: src/ui/views/GameDetailsView/blocks/Artwork.vala:62 +msgid "Download images" +msgstr "Unduh gambar" + +#: src/ui/dialogs/GamePropertiesDialog.vala:144 +msgid "Image URL" +msgstr "URL gambar" + +#: src/ui/dialogs/GamePropertiesDialog.vala:148 +msgid "Vertical image URL" +msgstr "URL gambar vertikal" + +#: src/ui/dialogs/GamePropertiesDialog.vala:157 +msgid "Icon URL" +msgstr "URL ikon" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Select working directory" +msgstr "Pilih direktori kerja" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Working directory" +msgstr "Direktori kerja" + +#: src/ui/dialogs/GamePropertiesDialog.vala:214 +msgid "Compatibility" +msgstr "Kompatibilitas" + +#: src/ui/dialogs/GamePropertiesDialog.vala:236 +msgid "Launch from terminal" +msgstr "Luncurkan terminal" + +#: src/ui/dialogs/GamePropertiesDialog.vala:252 +msgid "Copy to clipboard" +msgstr "Salin ke papan klip" + +#: src/ui/dialogs/GamePropertiesDialog.vala:254 +msgid "Add to Steam" +msgstr "Tambahkan ke Steam" + +#: src/ui/dialogs/GamePropertiesDialog.vala:255 +msgid "Add to the Steam library" +msgstr "Tambahkan ke pustaka Steam" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:53 +#, c-format +msgid "%s: Overlays" +msgstr "%s: Pelapisan" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "Overlays are disabled" +msgstr "Pelapisan dinon-aktifkan" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "" +"Enable overlays to manage DLCs and mods\n" +"\n" +"Enabling will move game to the “base“ overlay" +msgstr "" +"Aktifkan pelapisan untuk mengatur DLC dan mod\n" +"\n" +"Permainan akan dipindahkan ke \"dasar\" pelapisan bila diaktifkan" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:77 +#: src/ui/views/GamesView/GameContextMenu.vala:175 +msgid "Overlays" +msgstr "Pelapisan" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:105 +msgid "Overlay ID (directory name)" +msgstr "ID pelapisan (nama direktori)" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:110 +msgid "Overlay name (optional)" +msgstr "Nama pelapisan" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:112 +msgid "Add" +msgstr "Tambahkan" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:127 +msgid "Enable overlays" +msgstr "Aktifkan pelapisan" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:182 +#, c-format +msgid "" +"Overlay usage at this path may be unsafe\n" +"Proceed at your own risk\n" +"\n" +"Path: %s" +msgstr "" +"Penggunaan pelapisan pada jalur ini mungkin tidak aman\n" +"Risiko ditanggung pengguna\n" +"\n" +"Jalur: %s" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:187 +#, c-format +msgid "" +"Overlay usage at this path is not supported\n" +"\n" +"Path: %s" +msgstr "" +"Jalur ini tidak mendukung penggunaan pelapisan\n" +"\n" +"Jalur: %s" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:266 +msgid "Open directory" +msgstr "Buka direktori" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:271 +msgid "Remove overlay" +msgstr "Hapus pelapisan" + +#: src/ui/dialogs/CompatRunDialog.vala:48 +#: src/ui/views/GamesView/GameContextMenu.vala:46 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:235 +msgid "Run with compatibility layer" +msgstr "Jalankan dengan lapisan kompatibilitas" + +#: src/ui/dialogs/CorruptedInstallerDialog.vala:71 +msgid "Corrupted installer: checksum mismatch in" +msgstr "Penginstal rusak: checksum tidak cocok pada" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:57 +#: src/ui/views/GamesView/AddGamePopover.vala:105 +msgid "Import emulated games" +msgstr "Impor permainan yang teremulasi" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:75 +msgid "Select directory with emulated games" +msgstr "Pilih direktori yang berisi permainan teremulasi" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:83 +msgid "Detected games" +msgstr "Permainan yang terdeteksi" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:107 +msgid "Select all" +msgstr "Pilih semua" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:115 +msgid "Select directory to import" +msgstr "Pilih direktori untuk diimpor" + +#: src/ui/dialogs/GameTweaksDialog.vala:40 +#, c-format +msgid "%s: Tweaks" +msgstr "%s: Penyesuaian" + +#: src/ui/views/WelcomeView.vala:52 +msgid "No enabled game sources" +msgstr "Tidak ada sumber permainan yang diaktifkan" + +#: src/ui/views/WelcomeView.vala:52 +msgid "Enable some game sources in settings" +msgstr "Aktifkan beberapa sumber permainan di pengaturan" + +#: src/ui/views/WelcomeView.vala:57 +msgid "Let's get started" +msgstr "Mari kita mulai" + +#: src/ui/views/WelcomeView.vala:71 +msgid "Skip" +msgstr "Lewati" + +#: src/ui/views/WelcomeView.vala:141 +msgid "Ready" +msgstr "Siap" + +#: src/ui/views/WelcomeView.vala:147 +msgid "Authentication required" +msgstr "Diperlukan autentikasi" + +#: src/ui/views/WelcomeView.vala:152 +msgid "Authenticating…" +msgstr "Mengautentikasi…" + +#: src/ui/views/WelcomeView.vala:163 +#, c-format +msgid "Install %s" +msgstr "Pasang %s" + +#: src/ui/views/WelcomeView.vala:164 +msgid "Return to GameHub after installing" +msgstr "Kembali ke GameHub setelah memasang" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "No games" +msgstr "Tidak ada permainan" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "Get some games or enable some game sources in settings" +msgstr "" +"Dapatkan beberapa permainan atau aktifkan beberapa sumber permainan di " +"pengaturan" + +#: src/ui/views/GamesView/GamesView.vala:150 +msgid "Grid view" +msgstr "Tampilan grid" + +#: src/ui/views/GamesView/GamesView.vala:151 +msgid "List view" +msgstr "Tampilan daftar" + +#: src/ui/views/GamesView/GamesView.vala:159 +msgid "All games" +msgstr "Semua permainan" + +#: src/ui/views/GamesView/GamesView.vala:182 +msgid "Downloads" +msgstr "Unduhan" + +#: src/ui/views/GamesView/GamesView.vala:208 +msgid "Filters" +msgstr "Penyaring" + +#: src/ui/views/GamesView/GamesView.vala:216 +#: src/ui/views/GamesView/AddGamePopover.vala:84 +msgid "Add game" +msgstr "Tambah permainan" + +#: src/ui/views/GamesView/GamesView.vala:223 +msgid "Search" +msgstr "Cari" + +#: src/ui/views/GamesView/GamesView.vala:328 +msgid "Menu" +msgstr "Menu" + +#: src/ui/views/GamesView/GamesView.vala:329 +#: src/ui/views/GameDetailsView/GameDetailsView.vala:104 +msgid "Back" +msgstr "Kembali" + +#: src/ui/views/GamesView/GamesView.vala:550 +#, c-format +msgid "%u game" +msgid_plural "%u games" +msgstr[0] "%u permainan" +msgstr[1] "%u permainan" + +#: src/ui/views/GamesView/GamesView.vala:553 +#, c-format +msgctxt "games_view_subtitle_filtered_games" +msgid "%1$u / %2$s" +msgstr "%1$u / %2$s" + +#: src/ui/views/GamesView/GamesView.vala:557 +#, c-format +msgctxt "games_view_subtitle" +msgid "%1$s: %2$s" +msgstr "%1$s: %2$s" + +#: src/ui/views/GamesView/GamesView.vala:568 +msgid "No user-added games" +msgstr "Tidak ada permainan yang ditambahkan pengguna" + +#: src/ui/views/GamesView/GamesView.vala:569 +msgid "Add some games using plus button" +msgstr "Tambahkan beberapa permainan menggunakan tombol plus" + +#: src/ui/views/GamesView/GamesView.vala:573 +#, c-format +msgid "No %s games" +msgstr "Tidak ada %s permainan" + +#: src/ui/views/GamesView/GamesView.vala:574 +msgid "Get some Linux-compatible games" +msgstr "Dapatkan beberapa permainan Linux yang kompatibel" + +#: src/ui/views/GamesView/GamesView.vala:584 +#, c-format +msgid "No games matching “%s”" +msgstr "Tidak ada permainan yang cocok dengan “%s”" + +#: src/ui/views/GamesView/GamesView.vala:589 +#, c-format +msgid "No %1$s games matching “%2$s”" +msgstr "Tidak ada permainan dari %1$s yang cocok dengan “%2$s”" + +#: src/ui/views/GamesView/GamesView.vala:627 +msgid "" +"No games were loaded from Steam. Set your games list privacy to public or " +"use your own Steam API key in settings." +msgstr "" +"Tidak ada permainan yang dimuat dari Steam. Setel privasi daftar permainan " +"anda ke publik atau gunakan kunci API Steam anda sendiri dalam pengaturan." + +#: src/ui/views/GamesView/GamesView.vala:628 +msgid "Privacy" +msgstr "Privasi" + +#: src/ui/views/GamesView/GamesView.vala:739 +msgid "Downloading images" +msgstr "Mengunduh gambar" + +#: src/ui/views/GamesView/GamesView.vala:753 +#, c-format +msgid "Downloading image: %s" +msgstr "Mengunduh gambar: %s" + +#: src/ui/views/GamesView/DownloadProgressView.vala:131 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:162 +msgid "Pause download" +msgstr "Jeda unduhan" + +#: src/ui/views/GamesView/DownloadProgressView.vala:137 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:168 +msgid "Resume download" +msgstr "Lanjutkan unduhan" + +#: src/ui/views/GamesView/DownloadProgressView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:174 +msgid "Cancel download" +msgstr "Batalkan unduhan" + +#: src/ui/views/GamesView/FiltersPopover.vala:77 +msgid "Group" +msgstr "Kelompok" + +#: src/ui/views/GamesView/FiltersPopover.vala:102 +msgid "Sort" +msgstr "Sortir" + +#: src/ui/views/GamesView/FiltersPopover.vala:234 +#: src/ui/widgets/GameTagsList.vala:58 +msgid "Tags" +msgstr "Label" + +#: src/ui/views/GamesView/FiltersPopover.vala:353 +msgid "All platforms" +msgstr "Semua platform" + +#: src/ui/views/GamesView/AddGamePopover.vala:77 +msgid "Select game executable" +msgstr "Pilih berkas permainan yang dapat dieksekusi" + +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Select game directory" +msgstr "Pilih direktori permainan" + +#: src/ui/views/GamesView/AddGamePopover.vala:111 +msgid "Download game images" +msgstr "Unduh gambar permainan" + +#: src/ui/views/GamesView/GameContextMenu.vala:87 +msgid "Details" +msgstr "Detail" + +#: src/ui/views/GamesView/GameContextMenu.vala:117 +msgctxt "game_context_menu" +msgid "Favorite" +msgstr "Favorit" + +#: src/ui/views/GamesView/GameContextMenu.vala:121 +msgctxt "game_context_menu" +msgid "Hidden" +msgstr "Tersembunyi" + +#: src/ui/views/GamesView/GameContextMenu.vala:133 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:236 +msgid "Open installation directory" +msgstr "Buka direktori pemasangan" + +#: src/ui/views/GamesView/GameContextMenu.vala:142 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:237 +msgid "Open installers collection directory" +msgstr "Buka direktori koleksi penginstal" + +#: src/ui/views/GamesView/GameContextMenu.vala:151 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:238 +msgid "Open bonus collection directory" +msgstr "Buka direktori koleksi bonus" + +#: src/ui/views/GamesView/GameContextMenu.vala:160 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:239 +msgid "Open screenshots directory" +msgstr "Buka direktori tangkapan layar" + +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +msgid "Uninstall" +msgstr "Copot pemasangan" + +#: src/ui/views/GamesView/GameContextMenu.vala:192 +msgid "Properties" +msgstr "Properti" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:100 +#, c-format +msgid "%d game selected" +msgid_plural "%d games selected" +msgstr[0] "%d permainan dipilih" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:144 +#, c-format +msgid "%d game will be installed" +msgid_plural "%d games will be installed" +msgstr[0] "%d permainan akan dipasang" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:154 +#, c-format +msgid "%d game will be downloaded" +msgid_plural "%d games will be downloaded" +msgstr[0] "%d permainan akan diunduh" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:161 +#, c-format +msgid "Image for %d game will be searched" +msgid_plural "Images for %d games will be searched" +msgstr[0] "Gambar untuk %d permainan akan dicari" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:168 +#, c-format +msgid "%d game will be uninstalled" +msgid_plural "%d games will be uninstalled" +msgstr[0] "%d permainan akan dicopot" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:174 +msgid "Refresh" +msgstr "Segarkan" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:175 +#, c-format +msgid "" +"%d game will be removed from database. Restart GameHub to fetch new data" +msgid_plural "" +"%d games will be removed from database. Restart GameHub to fetch new data" +msgstr[0] "" +"%d permainan akan dihapus dari basis data. Mulai ulang GameHub untuk " +"mengambil data baru" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:240 +msgid "Open store page" +msgstr "Buka halaman toko" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:242 +msgid "Game properties" +msgstr "Properti permainan" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:46 +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:60 +msgid "Playtime" +msgstr "Waktu main" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:52 +msgid "Playtime (local)" +msgstr "Waktu main (lokal)" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:69 +msgid "Last launch" +msgstr "Terakhir diluncurkan" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:46 +msgid "Achievements" +msgstr "Penghargaan" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:85 +#, c-format +msgid "Unlocked: %s" +msgstr "Terbuka: %s" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:90 +#, c-format +msgid "Global percentage: %g%%" +msgstr "Persentase global: %g%%" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:77 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:103 +msgid "Language" +msgstr "Bahasa" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:80 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:106 +msgid "Languages" +msgstr "Bahasa" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:147 +#, c-format +msgid "%u DLCs cannot be installed" +msgstr "%u DLC tidak dapat dipasang" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:71 +msgid "Category" +msgstr "Kategori" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:74 +msgid "Categories" +msgstr "Kategori" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:90 +msgid "Genre" +msgstr "Genre" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:93 +msgid "Genres" +msgstr "Genre" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:109 +msgctxt "igdb" +msgid "Popularity" +msgstr "Popularitas" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:115 +msgctxt "igdb" +msgid "Aggregated rating" +msgstr "Peringkat teragregasi" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:116 +msgctxt "igdb" +msgid "IGDB user rating" +msgstr "Peringkat pengguna IGDB" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:117 +msgctxt "igdb" +msgid "Total rating" +msgstr "Peringkat total" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:126 +msgctxt "igdb" +msgid "Release date" +msgstr "Tanggal rilis" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:133 +msgctxt "igdb" +msgid "Platforms" +msgstr "Platform" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:139 +msgctxt "igdb" +msgid "Genres" +msgstr "Genre" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:145 +msgctxt "igdb" +msgid "Keywords" +msgstr "Kata kunci" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:152 +msgctxt "igdb" +msgid "Links" +msgstr "Tautan" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:208 +#, c-format +msgid "Based on %d rating" +msgid_plural "Based on %d ratings" +msgstr[0] "Berdasarkan %d peringkat" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:290 +msgctxt "igdb" +msgid "Summary" +msgstr "Ringkasan" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:301 +msgctxt "igdb" +msgid "Storyline" +msgstr "Alur cerita" + +#: src/ui/widgets/FileChooserEntry.vala:49 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select file" +msgstr "Pilih berkas" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "No images" +msgstr "Tidak ada gambar" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "" +"There are no images found for this game\n" +"Make sure game name is correct" +msgstr "" +"Tidak ada gambar ditemukan untuk permainan ini\n" +"Pastikan nama permainan sudah benar" + +#: src/ui/widgets/ImagesDownloadPopover.vala:94 +msgid "Search images:" +msgstr "Cari gambar:" + +#: src/ui/widgets/CompatToolPicker.vala:53 +msgid "Compatibility layer:" +msgstr "Lapisan kompatibilitas:" + +#: src/ui/widgets/CompatToolPicker.vala:92 +msgid "Configure" +msgstr "Konfigurasikan" + +#: src/ui/widgets/GameTagsList.vala:109 +msgid "Add tag" +msgstr "Tambahkan label" + +#: src/ui/widgets/TweaksList.vala:86 +msgid "No description" +msgstr "Tidak ada deskripsi" + +#: src/ui/widgets/TweaksList.vala:124 +msgid "Edit file" +msgstr "Sunting berkas" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dh" +msgstr "%dj" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dm" +msgstr "%dm" + +#: src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%ds" +msgstr "%dd" + +#: src/settings/UI.vala:153 +msgctxt "grid_size_preset" +msgid "Steam" +msgstr "Steam" + +#: src/settings/UI.vala:154 +msgctxt "grid_size_preset" +msgid "Steam (vertical)" +msgstr "Steam (vertikal)" + +#: src/settings/UI.vala:155 +msgctxt "grid_size_preset" +msgid "GOG" +msgstr "GOG" + +#: src/settings/UI.vala:156 +msgctxt "grid_size_preset" +msgid "GOG (vertical)" +msgstr "GOG (vertikal)" + +#: src/settings/UI.vala:157 +msgctxt "grid_size_preset" +msgid "Square" +msgstr "Persegi" + +#: src/settings/UI.vala:158 +msgctxt "grid_size_preset" +msgid "Custom" +msgstr "Kustom" + +#: src/utils/downloader/Downloader.vala:200 +msgctxt "dl_status" +msgid "Queued" +msgstr "Diantrekan" + +#: src/utils/downloader/Downloader.vala:201 +msgctxt "dl_status" +msgid "Starting download" +msgstr "Memulai unduhan" + +#: src/utils/downloader/Downloader.vala:202 +msgctxt "dl_status" +msgid "Download started" +msgstr "Unduhan dimulai" + +#: src/utils/downloader/Downloader.vala:203 +msgctxt "dl_status" +msgid "Download finished" +msgstr "Unduhan selesai" + +#: src/utils/downloader/Downloader.vala:204 +msgctxt "dl_status" +msgid "Download failed" +msgstr "Unduhan gagal" + +#: src/utils/downloader/Downloader.vala:208 +#, c-format +msgctxt "dl_status" +msgid "Downloading: %s" +msgstr "Mengunduh: %s" + +#: src/utils/downloader/Downloader.vala:210 +msgctxt "dl_status" +msgid "Downloading" +msgstr "Mengunduh" + +#: src/utils/downloader/Downloader.vala:214 +#, c-format +msgctxt "dl_status" +msgid "Paused: %s" +msgstr "Dijeda: %s" + +#: src/utils/downloader/Downloader.vala:216 +msgctxt "dl_status" +msgid "Paused" +msgstr "Dijeda" + +#: src/utils/downloader/Downloader.vala:218 +msgctxt "dl_status" +msgid "Download cancelled" +msgstr "Unduhan dibatalkan" + +#. TRANSLATORS: Download progress template. %1$d - percentage, %2$s / %3$s - downloaded portion and total file size, %4$s - download speed +#: src/utils/downloader/Downloader.vala:262 +#, c-format +msgctxt "dl_status" +msgid "%1$d%% (%2$s / %3$s) [%4$s/s]" +msgstr "%1$d%% (%2$s / %3$s) [%4$s/s]" + +#~ msgid "Disable esync" +#~ msgstr "Nonaktifkan esync" + +#~ msgid "Disable DirectX 11 compatibility layer" +#~ msgstr "Nonaktifkan lapisan kompatibilitas DirectX 11" + +#~ msgid "Use WineD3D11 as DirectX 11 compatibility layer" +#~ msgstr "Gunakan WineD3D11 sebagai lapisan kompatibilitas DirectX 11" + +#~ msgid "Show DXVK info overlay" +#~ msgstr "Tampilkan info overlay DXVK" + +#, fuzzy +#~ msgid "Enable DirectX 9 compatibility layer" +#~ msgstr "Nonaktifkan lapisan kompatibilitas DirectX 11" + +#~ msgid "Silent installation" +#~ msgstr "Pemasangan senyap" + +#~ msgid "Very silent installation" +#~ msgstr "Pemasangan sangat senyap" + +#~ msgid "Suppress messages" +#~ msgstr "Menekan pesan" + +#~ msgid "No GUI" +#~ msgstr "Tidak ada GUI" + +#~ msgid "Disable fullscreen" +#~ msgstr "Nonaktifkan layar penuh" + +#~ msgid "Windowed" +#~ msgstr "Jendela" + +#~ msgid "Compact list" +#~ msgstr "Daftar kompak" + +#~ msgid "Show non-native games" +#~ msgstr "Tampilkan game non-native" + +#~ msgid "Use compatibility layers and consider Windows games compatible" +#~ msgstr "" +#~ "Gunakan lapisan kompatibilitas dan pertimbangkan permainan Windows yang " +#~ "kompatibel" + +#~ msgid "Reload" +#~ msgstr "Muat ulang" + +#~ msgid "Updating game info" +#~ msgstr "Memperbarui info game" + +#~ msgid "Updating %s game info" +#~ msgstr "Memperbarui info game %s" diff --git a/po/it.po b/po/it.po new file mode 100644 index 00000000..5542349d --- /dev/null +++ b/po/it.po @@ -0,0 +1,1889 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the com.github.tkashkin.gamehub package. +# Mirko Brombin , 2019. +# Francesco Bisignani , 2020. +# Albano Battistella , 2021. +msgid "" +msgstr "" +"Project-Id-Version: com.github.tkashkin.gamehub\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-26 06:40+0300\n" +"PO-Revision-Date: 2021-07-18 16:21+0200\n" +"Last-Translator: Francesco Bisignani \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 3.11-dev\n" + +#: src/app.vala:91 +msgid "Show help" +msgstr "Mostra aiuto" + +#: src/app.vala:92 +msgid "Show application version and exit" +msgstr "Mostra versione e chiudi" + +#: src/app.vala:93 +msgid "Restart with GDB debugger attached" +msgstr "Riavvia con il debugger GDB collegato" + +#: src/app.vala:94 +msgid "Show full GDB backtrace" +msgstr "Mostra backtrace GDB completo" + +#: src/app.vala:95 +msgid "Treat fatal errors as criticals and crash application" +msgstr "Tratta gli errori fatali come critici e l'applicazione di crash" + +#: src/app.vala:99 +msgid "Show main window" +msgstr "Mostra finestra principale" + +#: src/app.vala:100 +msgid "Show application settings dialog" +msgstr "Mostra impostazioni" + +#: src/app.vala:101 +msgid "Show about dialog" +msgstr "Mostra informazioni" + +#: src/app.vala:102 +msgid "Maximum number of background worker threads" +msgstr "Numero massimo di worker thread in background" + +#: src/app.vala:106 +msgid "Run game" +msgstr "Avvia gioco" + +#: src/app.vala:107 +msgid "Show compatibility options dialog" +msgstr "Mostra la finestra di dialogo delle opzioni di compatibilità" + +#: src/app.vala:108 +msgid "Open game details" +msgstr "Apri dettagli gioco" + +#: src/app.vala:109 +msgid "Open game properties" +msgstr "Apri proprietà gioco" + +#: src/app.vala:113 +msgid "Enable debug logging" +msgstr "Abita log debug" + +#: src/app.vala:114 +msgid "" +"Log authentication process and sensitive information like authentication " +"tokens" +msgstr "" +"Registra il processo di autenticazione e informazioni sensibili come i token " +"di autenticazione" + +#: src/app.vala:115 +msgid "Log download manager" +msgstr "Log del download manager" + +#: src/app.vala:116 +msgid "Log background workers start/stop" +msgstr "Registra inizio/fine worker in background" + +#: src/app.vala:117 +msgid "Disable log messages filtering" +msgstr "Disattiva il filtro del log" + +#: src/app.vala:118 +msgid "Verbose logging" +msgstr "Registrazione dettagliata" + +#: src/app.vala:247 +msgid "Game Options:" +msgstr "Opzioni Gioco:" + +#: src/app.vala:247 +msgid "Show game options help" +msgstr "Mostra aiuto opzioni gioco" + +#: src/app.vala:255 +msgid "Logging Options:" +msgstr "Opzioni Log:" + +#: src/app.vala:255 +msgid "Show logging options help" +msgstr "Mostra aiuto nelle opzioni log" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +msgid "Select executable" +msgstr "Seleziona eseguibile" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:181 src/ui/views/GamesView/GamesView.vala:330 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select" +msgstr "Seleziona" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:180 src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Cancel" +msgstr "Annulla" + +#: src/data/Runnable.vala:166 src/ui/widgets/FileChooserEntry.vala:49 +msgid "Select directory" +msgstr "Seleziona posizione" + +#: src/data/Runnable.vala:619 +#, c-format +msgid "Part %1$u of %2$u: %3$s" +msgstr "Parte %1$u di %2$u : %3$s" + +#: src/data/Runnable.vala:642 src/ui/dialogs/CorruptedInstallerDialog.vala:48 +#, c-format +msgid "%s: corrupted installer" +msgstr "%s : Installer corrotto" + +#: src/data/Runnable.vala:643 +#, c-format +msgid "Checksum mismatch in %s" +msgstr "Checksum errata %s" + +#: src/data/Runnable.vala:657 src/ui/dialogs/CorruptedInstallerDialog.vala:126 +msgid "Show file" +msgstr "Mostra file" + +#: src/data/Runnable.vala:658 src/ui/dialogs/CorruptedInstallerDialog.vala:132 +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#: src/ui/widgets/TagRow.vala:146 +msgid "Remove" +msgstr "Riimuovi" + +#: src/data/Runnable.vala:659 src/ui/dialogs/CorruptedInstallerDialog.vala:128 +msgid "Backup" +msgstr "Backup" + +#: src/data/Runnable.vala:778 +#, c-format +msgid "%s: cannot detect main executable" +msgstr "%s: impossibile trovare l'eseguibile principale" + +#: src/data/Runnable.vala:779 +msgid "" +"Main executable file for this game cannot be detected automatically.\n" +"Please set main executable in game's properties." +msgstr "" +"Il file eseguibile principale per questo gioco non può essere rilevato " +"automaticamente.\n" +"Imposta l'eseguibile principale nelle proprietà del gioco." + +#: src/data/Runnable.vala:908 +msgctxt "platform" +msgid "Emulated" +msgstr "Emulato" + +#: src/data/Game.vala:625 +msgctxt "status" +msgid "Running" +msgstr "In esecuzione" + +#: src/data/Game.vala:628 +msgctxt "status" +msgid "Installed" +msgstr "Installato" + +#: src/data/Game.vala:629 +msgctxt "status" +msgid "Installing" +msgstr "Installando" + +#: src/data/Game.vala:630 +msgctxt "status" +msgid "Verifying installer integrity" +msgstr "Verificando l'integrità dell'installer" + +#: src/data/Game.vala:631 +msgctxt "status" +msgid "Download started" +msgstr "Download iniziato" + +#: src/data/Game.vala:633 +msgctxt "status" +msgid "Not installed" +msgstr "Non installato" + +#: src/data/Game.vala:643 +msgctxt "status_header" +msgid "Installed" +msgstr "Installato" + +#: src/data/Game.vala:644 +msgctxt "status_header" +msgid "Installing" +msgstr "Installando" + +#: src/data/Game.vala:646 +msgctxt "status_header" +msgid "Downloading" +msgstr "Scaricando" + +#: src/data/Game.vala:648 +msgctxt "status_header" +msgid "Not installed" +msgstr "Non installato" + +#: src/data/GameSource.vala:31 +#, c-format +msgid "%s games" +msgstr "%s giochi" + +#: src/data/sources/steam/Steam.vala:43 +msgid "Your SteamID will be read from Steam configuration file" +msgstr "SteamID verrà letto dal file di configurazione di Steam" + +#: src/data/sources/steam/Steam.vala:46 +msgid "" +"Steam config file not found.\n" +"Login into your account in Steam client and return to GameHub" +msgstr "" +"File di configurazione di Steam non trovato.\n" +"Accedi al tuo account nel client Steam e torna a GameHub" + +#: src/data/sources/gog/GOGGame.vala:983 +#, c-format +msgid "DLC: %s" +msgstr "" + +#: src/data/sources/humble/HumbleGame.vala:343 +#, c-format +msgid "%s: no available installers" +msgstr "%s : nessun installer disponibile" + +#: src/data/sources/humble/HumbleGame.vala:344 +msgid "" +"Cannot get Trove download URL.\n" +"Make sure your Humble Monthly subscription is active." +msgstr "" +"Impossibile ottenere l'URL di download di Trove.\n" +"Assicurati che l'abbonamento mensile Humble sia attivo." + +#: src/data/sources/itch/ItchDownloader.vala:192 +#, c-format +msgctxt "itch_dl_status" +msgid "%s left;" +msgstr "%s rimanenti;" + +#: src/data/sources/itch/ItchDownloader.vala:195 +#, c-format +msgctxt "itch_dl_status" +msgid "%d%%" +msgstr "%d%%" + +#: src/data/sources/itch/ItchDownloader.vala:198 +#, c-format +msgctxt "itch_dl_status" +msgid "(%1$s / %2$s)" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:201 +#, c-format +msgctxt "itch_dl_status" +msgid "[%s/s]" +msgstr "" + +#: src/data/sources/user/User.vala:30 +msgid "User games" +msgstr "Giochi dell'utente" + +#: src/data/db/tables/Tags.vala:225 +msgctxt "tag" +msgid "Favorites" +msgstr "Preferiti" + +#: src/data/db/tables/Tags.vala:226 +msgctxt "tag" +msgid "Not installed" +msgstr "Non installato" + +#: src/data/db/tables/Tags.vala:227 +msgctxt "tag" +msgid "Installed" +msgstr "Installato" + +#: src/data/db/tables/Tags.vala:228 +msgctxt "tag" +msgid "Hidden" +msgstr "Nascosto" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit script" +msgstr "Modifica script" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit custom script" +msgstr "Modifica script personalizzato" + +#: src/data/compat/Innoextract.vala:55 +#, c-format +msgid "" +"Innoextract %1$s is not supported and may not be able to extract some " +"games correctly.\n" +"Install innoextract %2$s or newer." +msgstr "" +"Innoextract %1$s non è supportato e potrebbe non essere in grado di " +"estrarre correttamente alcuni giochi.\n" +"Installa innoextract %2$s o più recente." + +#: src/data/compat/WineWrap.vala:61 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:242 +#: src/ui/dialogs/CompatRunDialog.vala:102 +#: src/ui/views/GamesView/GameContextMenu.vala:53 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:234 +msgid "Run" +msgstr "Avvia" + +#: src/data/compat/WineWrap.vala:64 +msgid "Show WineWrap menu" +msgstr "Monstra menu WineWrap" + +#: src/data/compat/WineWrap.vala:67 src/data/compat/Proton.vala:122 +#: src/data/compat/Wine.vala:83 +msgid "Kill apps in prefix" +msgstr "Termina applicazioni nel prefisso" + +#: src/data/compat/Proton.vala:47 +msgid "Proton prefix" +msgstr "Prefisso Proton" + +#: src/data/compat/Proton.vala:110 src/data/compat/Wine.vala:71 +msgid "Open prefix directory" +msgstr "Apri la posizione del prefisso" + +#: src/data/compat/Proton.vala:113 src/data/compat/Wine.vala:74 +msgid "Run winecfg" +msgstr "Avvia winecfg" + +#: src/data/compat/Proton.vala:116 src/data/compat/Wine.vala:77 +msgid "Run winetricks" +msgstr "Avvia winetricks" + +#: src/data/compat/Proton.vala:119 src/data/compat/Wine.vala:80 +msgid "Run taskmgr" +msgstr "Avvia taskmgr" + +#: src/data/compat/Wine.vala:53 +msgid "Wine prefix" +msgstr "Prefissi Wine" + +#: src/data/compat/Wine.vala:55 +msgid "Environment variables" +msgstr "Variabili ambiente" + +#: src/data/compat/Wine.vala:60 +msgid "InnoSetup default options" +msgstr "Impostazioni iniziali di InnoSetup" + +#: src/data/compat/RetroArch.vala:53 +msgid "Libretro core file" +msgstr "Core file Libretro" + +#: src/data/compat/CustomEmulator.vala:43 +msgid "Custom emulator" +msgstr "Emulatore personalizzato" + +#: src/data/compat/CustomEmulator.vala:48 +msgid "Emulator" +msgstr "Emulatore" + +#: src/data/compat/CustomEmulator.vala:49 +msgid "Launch in game directory" +msgstr "Avvia nella posizione del gioco" + +#: src/data/adapters/GamesAdapter.vala:440 +msgctxt "status_header" +msgid "Favorites" +msgstr "Favoriti" + +#: src/data/adapters/GamesAdapter.vala:445 +#, c-format +msgctxt "status_header" +msgid "%s: Favorites" +msgstr "%s : Favoriti" + +#: src/data/adapters/GamesAdapter.vala:491 +msgid "Merging games" +msgstr "Unendo i giochi" + +#: src/data/adapters/GamesAdapter.vala:504 +#, c-format +msgid "Merging games from %s" +msgstr "Unendo giochi da %s" + +#: src/data/adapters/GamesAdapter.vala:551 +#, c-format +msgid "Loading games from %s" +msgstr "Loggando giochi da %s" + +#: src/data/adapters/GamesAdapter.vala:678 +msgctxt "sort_mode" +msgid "By name" +msgstr "Dal nome" + +#: src/data/adapters/GamesAdapter.vala:679 +msgctxt "sort_mode" +msgid "By last launch" +msgstr "Dall'ultimo lancio" + +#: src/data/adapters/GamesAdapter.vala:680 +msgctxt "sort_mode" +msgid "By playtime" +msgstr "Dal tempo di gioco" + +#: src/data/adapters/GamesAdapter.vala:705 +msgctxt "group_mode" +msgid "Do not group" +msgstr "Non in gruppo" + +#: src/data/adapters/GamesAdapter.vala:706 +msgctxt "group_mode" +msgid "By status" +msgstr "Dallo stato" + +#: src/data/adapters/GamesAdapter.vala:707 +msgctxt "group_mode" +msgid "By source" +msgstr "Dal sorgente" + +#: src/data/providers/images/SteamGridDB.vala:151 +#: src/data/providers/data/IGDB.vala:431 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:217 +msgid "Default" +msgstr "Default" + +#: src/data/providers/images/SteamGridDB.vala:158 +#: src/data/providers/data/IGDB.vala:438 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:225 +msgid "Restore default API key" +msgstr "Ripristina API key originale" + +#: src/data/providers/images/SteamGridDB.vala:169 +#: src/data/providers/data/IGDB.vala:449 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:108 +msgid "API key" +msgstr "Chiave API" + +#: src/data/providers/images/SteamGridDB.vala:177 +#: src/data/providers/data/IGDB.vala:457 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:53 +msgid "Generate key" +msgstr "Genera chiave" + +#: src/data/providers/images/SteamGridDB.vala:208 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Style" +msgstr "Stile" + +#: src/data/providers/images/SteamGridDB.vala:209 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Score" +msgstr "Punteggio" + +#: src/data/providers/images/SteamGridDB.vala:213 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Author" +msgstr "Autore" + +#: src/data/providers/images/SteamGridDB.vala:225 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Alternate" +msgstr "Alterna" + +#: src/data/providers/images/SteamGridDB.vala:226 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Blurred" +msgstr "Blur" + +#. TRANSLATORS: Flat / Material Design image style. Probably should not be translated +#: src/data/providers/images/SteamGridDB.vala:228 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Material" +msgstr "Material" + +#: src/data/providers/images/SteamGridDB.vala:229 +msgctxt "imagesource_steamgriddb_image_style" +msgid "No logo" +msgstr "Senza logo" + +#: src/data/providers/images/SteamGridDB.vala:230 +msgctxt "imagesource_steamgriddb_image_style" +msgid "White logo" +msgstr "Logo bianco" + +#: src/data/providers/data/IGDB.vala:147 +msgid "" +"Monthly IGDB request quota has been reached. Set your own API key to use " +"IGDB data or disable IGDB." +msgstr "" +"È stata raggiunta la quota mensile di richiesta IGDB. Imposta la tua chiave " +"API per utilizzare i dati IGDB o disabilitare IGDB." + +#: src/data/providers/data/IGDB.vala:148 +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:40 +#: src/ui/views/WelcomeView.vala:53 src/ui/views/WelcomeView.vala:78 +#: src/ui/views/GamesView/GamesView.vala:230 +#: src/ui/views/GamesView/GamesView.vala:629 +msgid "Settings" +msgstr "Impostazioni" + +#: src/data/providers/data/IGDB.vala:356 +msgctxt "igdb_related_link" +msgid "Official website" +msgstr "Sito ufficiale" + +#: src/data/providers/data/IGDB.vala:469 +msgctxt "igdb_preferred_description" +msgid "When game has description, show description" +msgstr "Quando i giochi hanno la descrizione, mostrala" + +#: src/data/providers/data/IGDB.vala:476 +msgctxt "igdb_preferred_description" +msgid "of game" +msgstr "del gioco" + +#: src/data/providers/data/IGDB.vala:477 +msgctxt "igdb_preferred_description" +msgid "from IGDB" +msgstr "da IGDB" + +#: src/data/providers/data/IGDB.vala:478 +msgctxt "igdb_preferred_description" +msgid "both" +msgstr "entrambi" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:65 +msgid "Some settings will be applied after application restart" +msgstr "" +"Alcune impostazioni verranno applicate dopo il riavvio dell'applicazione" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:71 +msgid "Games directory contains space. It may cause problems for some games" +msgstr "" +"La directory dei giochi contiene spazio. Potrebbe causare problemi per " +"alcuni giochi" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:36 +msgid "Interface" +msgstr "Interfaccia" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:37 +msgid "Appearance" +msgstr "Apparenza" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:38 +msgid "General interface settings" +msgstr "Impostazioni generali dell'interfaccia" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:48 +msgid "Dark theme" +msgstr "Tema scuro" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:53 +msgctxt "icon_style" +msgid "Theme-based" +msgstr "Basato sul tema" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:54 +msgctxt "icon_style" +msgid "Symbolic" +msgstr "Simbolico" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:55 +msgctxt "icon_style" +msgid "Colored" +msgstr "Colorato" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:57 +msgctxt "icon_style" +msgid "Icon style" +msgstr "Stile delle icone" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:84 +msgid "Game card" +msgstr "Card gioco" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:86 +msgid "Show platform icons" +msgstr "Mostra icone piattaforma" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:99 +msgctxt "grid_size" +msgid "Card size" +msgstr "Dimensione card" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:117 +msgctxt "grid_size_preset" +msgid "Presets" +msgstr "Predefiniti" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:139 +msgid "Games list: installed" +msgstr "installato" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:140 +msgid "Games list: not installed" +msgstr "non installato" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:142 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:146 +msgctxt "list_style" +msgid "Show icon" +msgstr "Mostra icona" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:143 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:147 +msgctxt "list_style" +msgid "Bold title" +msgstr "Titolo grassetto" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:144 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:148 +msgctxt "list_style" +msgid "Show status" +msgstr "Mostra stato" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:149 +msgctxt "list_style" +msgid "Dim" +msgstr "Variabile" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:151 +msgid "Grid options" +msgstr "Opzioni griglia" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:152 +msgid "List options" +msgstr "Opzioni lista" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:31 +msgid "Behavior" +msgstr "Comportamento" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:32 +msgid "Behavior settings" +msgstr "Parametri comportamento" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:42 +msgid "Run games with double click" +msgstr "Avvia gioco col doppio click" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:46 +msgid "Merge games from different sources" +msgstr "Più giochi da sorgente differente" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:50 +msgid "Use imported tags" +msgstr "Usa tag importati" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:51 +msgid "General" +msgstr "Generale" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:52 +msgid "Collection" +msgstr "Collezione" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:53 +msgid "Empty" +msgstr "Vuoto" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:65 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:85 +msgid "Collection directory" +msgstr "Collezione posizione" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:70 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:78 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:87 +msgid "Game directory" +msgstr "Posizione gioco" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:71 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:79 +msgid "Installers" +msgstr "Installatori" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:72 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:98 +msgid "DLC" +msgstr "DLC" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:73 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:197 +msgid "Bonus content" +msgstr "Contenuto bonus" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:84 +msgid "Variable syntax: $var or ${var}" +msgstr "Sintassi variabile : $var o ${var}" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:86 +msgid "Game name" +msgstr "Nome gioco" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:88 +#: src/ui/views/GamesView/FiltersPopover.vala:127 +msgid "Platform" +msgstr "Piattaforma" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:36 +msgid "Controller" +msgstr "Controller" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +msgid "Enabled" +msgstr "Abilitato" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:53 +msgid "Focus GameHub window with Guide button" +msgstr "Attiva focus sulla finestra GameHub dal pulsante Guida" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:57 +msgid "Controllers" +msgstr "Controllers" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:89 +msgid "Move focus" +msgstr "Muovi focus" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:91 +msgid "Exit" +msgstr "Chiudi" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:40 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:108 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:92 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:95 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:36 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:77 +msgid "Disabled" +msgstr "Disattivato" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:47 +#: src/ui/dialogs/GameTweaksDialog.vala:53 +#: src/ui/views/GamesView/GameContextMenu.vala:183 +msgid "Tweaks" +msgstr "Modifiche" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:34 +msgid "Tweak launch options and apply them to games automatically" +msgstr "Modifica le opzioni di avvio e applicale automaticamente ai giochi" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:79 +msgid "" +"Tweaks are loaded from following directories in order\n" +"Last tweak overrides previous tweaks with same identifiers" +msgstr "" +"Le modifiche vengono caricate dalle seguenti directory in ordine\n" +"L'ultima modifica sovrascrive le modifiche precedenti con gli stessi identificatori" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:83 +msgid "Click to open" +msgstr "Clicca per aprire" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:93 +#, c-format +msgid "Tweaks are loaded from %1$s and %2$d more directories (?)" +msgstr "Le modifiche vengono caricate da %1$s e %2$d altre directory (?)" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:38 +msgid "Game sources" +msgstr "Sorgenti gioco" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +msgid "Steam API keys have limited number of uses per day" +msgstr "Le chiavi API di Steam hanno un numero limitato di usi al giorno" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:63 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:57 +msgid "Installation directory" +msgstr "Posizione installazione" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:176 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:81 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:34 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:75 +msgid "Not installed" +msgstr "Non installato" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:116 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:96 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:99 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:85 +msgid "Not authenticated" +msgstr "Non autenticato" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +#, c-format +msgid "Authenticated as %s" +msgstr "Autenticato come %s" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:103 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +msgid "Authenticated" +msgstr "Autenticato" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:183 +#: src/ui/dialogs/InstallDialog.vala:53 src/ui/dialogs/InstallDialog.vala:111 +#: src/ui/views/GamesView/GameContextMenu.vala:80 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:233 +#: src/ui/widgets/TweaksList.vala:95 +msgid "Install" +msgstr "Installa" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:236 +msgid "Steam API key" +msgstr "Chiave API Steam" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:50 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:54 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:48 +msgid "Games directory" +msgstr "Posizione dei giochi" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:63 +msgid "Logout" +msgstr "Esci" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:50 +msgid "Load games from Humble Trove" +msgstr "Carica giochi da Humble Trove" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:45 +msgid "Emulators" +msgstr "Emulatori" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:45 +msgid "Libretro core directory" +msgstr "Posizione Libretro core" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:46 +msgid "Libretro core info directory" +msgstr "Info posizione Libretro core" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:50 +msgid "Ignored libretro cores" +msgstr "Libretro cores ignorati" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:54 +msgid "Ignored game file extensions" +msgstr "Estensioni di gioco ignorate" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:66 +msgid "No cores found" +msgstr "Nessun core trovato" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:70 +#, c-format +msgid "%u core found" +msgid_plural "%u cores found" +msgstr[0] "%u core trovato" +msgstr[1] "%u core trovati" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:46 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:168 +msgid "No custom emulators" +msgstr "Nessun emulatore personalizzato" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:164 +#, c-format +msgid "%u custom emulator" +msgid_plural "%u custom emulators" +msgstr[0] "%u emulatore personalizzato" +msgstr[1] "%u emulatori personalizzati" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:237 +msgid "Save" +msgstr "Salva" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:250 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:312 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/dialogs/GamePropertiesDialog.vala:168 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +#: src/ui/views/GamesView/AddGamePopover.vala:67 +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Executable" +msgstr "Eseguibile" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:251 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/views/GamesView/AddGamePopover.vala:68 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Installer" +msgstr "Installatore" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:256 +#: src/ui/dialogs/GamePropertiesDialog.vala:64 +#: src/ui/dialogs/GamePropertiesDialog.vala:69 +#: src/ui/views/GamesView/AddGamePopover.vala:73 +msgid "Name" +msgstr "Nome" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:272 +#: src/ui/dialogs/GamePropertiesDialog.vala:201 +#: src/ui/views/GamesView/AddGamePopover.vala:78 +msgid "Arguments" +msgstr "Argomenti" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:276 +msgid "Variables" +msgstr "Variaibli" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:277 +msgid "Game executable" +msgstr "Eseguibile del gioco" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:278 +msgid "Game arguments" +msgstr "Argomenti del gioco" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:80 +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Directory" +msgstr "Posizione" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +msgid "Select emulator directory" +msgstr "Seleziona posizione emulatore" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:292 +#: src/ui/dialogs/GamePropertiesDialog.vala:219 +msgid "Force compatibility mode" +msgstr "Forza modalità compatibilità" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:307 +msgid "Game file patterns" +msgstr "Pattern file di gioco" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:315 +msgid "Image" +msgstr "Immagine" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:318 +msgid "Icon" +msgstr "Icona" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:325 +msgid "" +"findutils-compatible glob patterns\n" +"\n" +" Multiple patterns can be separated with |\n" +" Start pattern with ./ to match relative path\n" +" $basename variable will be replaced with game's executable " +"name (without extension)" +msgstr "" +"pattern glob compatibili con findutils\n" +"\n" +" È possibile separare più motivi con |\n" +" Inizia il modello con ./ per abbinare il percorso relativo\n" +"La variabile $ basename verrà sostituita con il nome " +"eseguibile del gioco (senza estensione)" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:38 +msgid "Data" +msgstr "Data" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:39 +msgid "Providers" +msgstr "Fornitori" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:40 +msgid "Third-party data providers" +msgstr "Providers data di terze parti" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:55 +msgid "Image providers" +msgstr "Providers immagini" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:68 +msgid "Metadata providers" +msgstr "Providers metadata" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:137 +msgid "Open website" +msgstr "Apri sito web" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:36 +msgid "About" +msgstr "Info" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:71 +msgid "Copy application version and environment info" +msgstr "Copia la versione dell'applicazione e le informazioni sull'ambiente" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:78 +#: src/ui/views/WelcomeView.vala:57 +msgid "All your games in one place" +msgstr "Tutti i tuoi giochi in un unico posto" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:92 +msgctxt "about_link" +msgid "Website" +msgstr "Sito web" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:96 +msgctxt "about_link" +msgid "Source code on GitHub" +msgstr "Codice sorgente su GitHub" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:103 +msgctxt "about_link" +msgid "Report a problem" +msgstr "Segnala un problema" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:104 +msgctxt "about_link" +msgid "Suggest translations" +msgstr "Suggerisci traduzioni" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:110 +msgctxt "about_link" +msgid "Issues" +msgstr "Problemi" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:111 +msgctxt "about_link" +msgid "Contributors" +msgstr "Contributori" + +#. TRANSLATORS: Likely it should not be translated. GitHub Pulse is a page that shows recent repository activity: https://github.com/tkashkin/GameHub/pulse +#: src/ui/dialogs/SettingsDialog/pages/About.vala:114 +msgctxt "about_link" +msgid "Pulse" +msgstr "Pulse" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:115 +msgctxt "about_link" +msgid "Forks" +msgstr "Forks" + +#: src/ui/dialogs/InstallDialog.vala:109 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:129 +msgid "Import" +msgstr "Importa" + +#: src/ui/dialogs/InstallDialog.vala:110 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:153 +msgid "Download" +msgstr "Download" + +#: src/ui/dialogs/InstallDialog.vala:207 +msgid "Select installer" +msgstr "Seleziona installer" + +#: src/ui/dialogs/InstallDialog.vala:216 +#, c-format +msgid "Installer size: %s" +msgstr "Dimensione installer : %s" + +#: src/ui/dialogs/InstallDialog.vala:348 +msgid "Unknown" +msgstr "Sconosciuto" + +#: src/ui/dialogs/GamePropertiesDialog.vala:49 +#, c-format +msgid "%s: Properties" +msgstr "%s : Proprietà" + +#: src/ui/dialogs/GamePropertiesDialog.vala:84 +msgid "Images" +msgstr "Immagini" + +#: src/ui/dialogs/GamePropertiesDialog.vala:126 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:160 +#: src/ui/views/GameDetailsView/blocks/Artwork.vala:62 +msgid "Download images" +msgstr "Scarica immagini" + +#: src/ui/dialogs/GamePropertiesDialog.vala:144 +msgid "Image URL" +msgstr "URL immagine" + +#: src/ui/dialogs/GamePropertiesDialog.vala:148 +msgid "Vertical image URL" +msgstr "URL immagine verticale" + +#: src/ui/dialogs/GamePropertiesDialog.vala:157 +msgid "Icon URL" +msgstr "URL icona" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Select working directory" +msgstr "seleziona la directory di lavoro" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Working directory" +msgstr "Directory di lavoro" + +#: src/ui/dialogs/GamePropertiesDialog.vala:214 +msgid "Compatibility" +msgstr "Compatibilità" + +#: src/ui/dialogs/GamePropertiesDialog.vala:236 +msgid "Launch from terminal" +msgstr "Avvia dal terminale" + +#: src/ui/dialogs/GamePropertiesDialog.vala:252 +msgid "Copy to clipboard" +msgstr "Copia negli appunti" + +#: src/ui/dialogs/GamePropertiesDialog.vala:254 +msgid "Add to Steam" +msgstr "Aggiungi a Steam" + +#: src/ui/dialogs/GamePropertiesDialog.vala:255 +msgid "Add to the Steam library" +msgstr "Aggiungi alla libreria di Steam" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:53 +#, c-format +msgid "%s: Overlays" +msgstr "%s : Sovrapposizioni" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "Overlays are disabled" +msgstr "Le sovrapposizioni sono disattivate" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "" +"Enable overlays to manage DLCs and mods\n" +"\n" +"Enabling will move game to the “base“ overlay" +msgstr "" +"Abilita le sovrapposizioni per gestire DLC e mod\n" +"\n" +"L'abilitazione sposta il gioco nella sovrapposizione \"base\"" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:77 +#: src/ui/views/GamesView/GameContextMenu.vala:175 +msgid "Overlays" +msgstr "Sovrapposizioni" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:105 +msgid "Overlay ID (directory name)" +msgstr "ID Sovrapposizioni (nome posizione)" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:110 +msgid "Overlay name (optional)" +msgstr "Nome sovrapposizione (opzionale)" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:112 +msgid "Add" +msgstr "Aggiungi" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:127 +msgid "Enable overlays" +msgstr "Abilita sovrapposizioni" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:182 +#, c-format +msgid "" +"Overlay usage at this path may be unsafe\n" +"Proceed at your own risk\n" +"\n" +"Path: %s" +msgstr "" +"L'uso della sovrapposizione in questo percorso potrebbe non essere sicuro\n" +"Procedete a vostro rischio\n" +"\n" +"Percorso: %s" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:187 +#, c-format +msgid "" +"Overlay usage at this path is not supported\n" +"\n" +"Path: %s" +msgstr "" +"L'uso delle sovrapposizioni in questo percorso non è supportato\n" +"\n" +"Percorso: %s" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:266 +msgid "Open directory" +msgstr "Apri posizione" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:271 +msgid "Remove overlay" +msgstr "Rimuovi sovrapposizione" + +#: src/ui/dialogs/CompatRunDialog.vala:48 +#: src/ui/views/GamesView/GameContextMenu.vala:46 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:235 +msgid "Run with compatibility layer" +msgstr "Avvia col livello di compatibilità" + +#: src/ui/dialogs/CorruptedInstallerDialog.vala:71 +msgid "Corrupted installer: checksum mismatch in" +msgstr "Installer danneggiato: checksum non corrispondente" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:57 +#: src/ui/views/GamesView/AddGamePopover.vala:105 +msgid "Import emulated games" +msgstr "Imposta giochi emulati" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:75 +msgid "Select directory with emulated games" +msgstr "Seleziona la posizione dei giochi emulati" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:83 +msgid "Detected games" +msgstr "Giochi rilevati" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:107 +msgid "Select all" +msgstr "Seleziona tutto" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:115 +msgid "Select directory to import" +msgstr "Selezione posizione da importare" + +#: src/ui/dialogs/GameTweaksDialog.vala:40 +msgid "%s: Tweaks" +msgstr "%s : Modifiche" + +#: src/ui/views/WelcomeView.vala:52 +msgid "No enabled game sources" +msgstr "Nessun sorgente di gioco abilitato" + +#: src/ui/views/WelcomeView.vala:52 +msgid "Enable some game sources in settings" +msgstr "Abilita qualche sorgente di gioco nelle impostazioni" + +#: src/ui/views/WelcomeView.vala:57 +msgid "Let's get started" +msgstr "Iniziamo" + +#: src/ui/views/WelcomeView.vala:71 +msgid "Skip" +msgstr "Ignora" + +#: src/ui/views/WelcomeView.vala:141 +msgid "Ready" +msgstr "Pronto" + +#: src/ui/views/WelcomeView.vala:147 +msgid "Authentication required" +msgstr "Autenticazione richiesta" + +#: src/ui/views/WelcomeView.vala:152 +msgid "Authenticating…" +msgstr "Autenticando…" + +#: src/ui/views/WelcomeView.vala:163 +#, c-format +msgid "Install %s" +msgstr "Installa %s" + +#: src/ui/views/WelcomeView.vala:164 +msgid "Return to GameHub after installing" +msgstr "Ritorna a GameHub dopo l'installazione" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "No games" +msgstr "No giochi" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "Get some games or enable some game sources in settings" +msgstr "" +"Ottieni alcuni giochi o abilita alcune fonti di gioco nelle impostazioni" + +#: src/ui/views/GamesView/GamesView.vala:150 +msgid "Grid view" +msgstr "Vista a griglia" + +#: src/ui/views/GamesView/GamesView.vala:151 +msgid "List view" +msgstr "Vista a lista" + +#: src/ui/views/GamesView/GamesView.vala:159 +msgid "All games" +msgstr "Tutti i giochi" + +#: src/ui/views/GamesView/GamesView.vala:182 +msgid "Downloads" +msgstr "Downloads" + +#: src/ui/views/GamesView/GamesView.vala:208 +msgid "Filters" +msgstr "Filtri" + +#: src/ui/views/GamesView/GamesView.vala:216 +#: src/ui/views/GamesView/AddGamePopover.vala:84 +msgid "Add game" +msgstr "Aggiungi gioco" + +#: src/ui/views/GamesView/GamesView.vala:223 +msgid "Search" +msgstr "Cerca" + +#: src/ui/views/GamesView/GamesView.vala:328 +msgid "Menu" +msgstr "Menu" + +#: src/ui/views/GamesView/GamesView.vala:329 +#: src/ui/views/GameDetailsView/GameDetailsView.vala:104 +msgid "Back" +msgstr "Indietro" + +#: src/ui/views/GamesView/GamesView.vala:550 +#, c-format +msgid "%u game" +msgid_plural "%u games" +msgstr[0] "%u gioco" +msgstr[1] "%u giochi" + +#: src/ui/views/GamesView/GamesView.vala:553 +#, c-format +msgctxt "games_view_subtitle_filtered_games" +msgid "%1$u / %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:557 +#, c-format +msgctxt "games_view_subtitle" +msgid "%1$s: %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:568 +msgid "No user-added games" +msgstr "Nessun gioco aggiunto dall'utente" + +#: src/ui/views/GamesView/GamesView.vala:569 +msgid "Add some games using plus button" +msgstr "Aggiungi qualche gioco dal pulsante più" + +#: src/ui/views/GamesView/GamesView.vala:573 +#, c-format +msgid "No %s games" +msgstr "No %s giochi" + +#: src/ui/views/GamesView/GamesView.vala:574 +msgid "Get some Linux-compatible games" +msgstr "Ottieni alcuni giochi compatibili con Linux" + +#: src/ui/views/GamesView/GamesView.vala:584 +#, c-format +msgid "No games matching “%s”" +msgstr "Aucun jeu correspondant à « %s »" + +#: src/ui/views/GamesView/GamesView.vala:589 +#, c-format +msgid "No %1$s games matching “%2$s”" +msgstr "Nessun gioco %1$s corrispondente a “%2$s”" + +#: src/ui/views/GamesView/GamesView.vala:627 +msgid "" +"No games were loaded from Steam. Set your games list privacy to public or " +"use your own Steam API key in settings." +msgstr "" +"Nessun gioco è stato caricato da Steam. Imposta la privacy dell'elenco dei " +"giochi su pubblica o usa la tua chiave API di Steam nelle impostazioni." + +#: src/ui/views/GamesView/GamesView.vala:628 +msgid "Privacy" +msgstr "Privacy" + +#: src/ui/views/GamesView/GamesView.vala:739 +msgid "Downloading images" +msgstr "Scaricando immagini" + +#: src/ui/views/GamesView/GamesView.vala:753 +#, c-format +msgid "Downloading image: %s" +msgstr "Scaricando l'immagine : %s" + +#: src/ui/views/GamesView/DownloadProgressView.vala:131 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:162 +msgid "Pause download" +msgstr "Metti in pausa download" + +#: src/ui/views/GamesView/DownloadProgressView.vala:137 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:168 +msgid "Resume download" +msgstr "Riprendi download" + +#: src/ui/views/GamesView/DownloadProgressView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:174 +msgid "Cancel download" +msgstr "Annulla download" + +#: src/ui/views/GamesView/FiltersPopover.vala:77 +msgid "Group" +msgstr "Gruppo" + +#: src/ui/views/GamesView/FiltersPopover.vala:102 +msgid "Sort" +msgstr "Ordina" + +#: src/ui/views/GamesView/FiltersPopover.vala:234 +#: src/ui/widgets/GameTagsList.vala:58 +msgid "Tags" +msgstr "Tags" + +#: src/ui/views/GamesView/FiltersPopover.vala:353 +msgid "All platforms" +msgstr "Tutte le piattaforme" + +#: src/ui/views/GamesView/AddGamePopover.vala:77 +msgid "Select game executable" +msgstr "Seleziona eseguibile gioco" + +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Select game directory" +msgstr "Seleziona posizione gioco" + +#: src/ui/views/GamesView/AddGamePopover.vala:111 +msgid "Download game images" +msgstr "Scarica immagini gioco" + +#: src/ui/views/GamesView/GameContextMenu.vala:87 +msgid "Details" +msgstr "Dettagli" + +#: src/ui/views/GamesView/GameContextMenu.vala:117 +msgctxt "game_context_menu" +msgid "Favorite" +msgstr "Favoriti" + +#: src/ui/views/GamesView/GameContextMenu.vala:121 +msgctxt "game_context_menu" +msgid "Hidden" +msgstr "Nascosto" + +#: src/ui/views/GamesView/GameContextMenu.vala:133 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:236 +msgid "Open installation directory" +msgstr "Apri posizione installazione" + +#: src/ui/views/GamesView/GameContextMenu.vala:142 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:237 +msgid "Open installers collection directory" +msgstr "Apri posizione installatori" + +#: src/ui/views/GamesView/GameContextMenu.vala:151 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:238 +msgid "Open bonus collection directory" +msgstr "Apri posizione bonus" + +#: src/ui/views/GamesView/GameContextMenu.vala:160 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:239 +msgid "Open screenshots directory" +msgstr "Apri posizione screenshosts" + +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +msgid "Uninstall" +msgstr "Disinstalla" + +#: src/ui/views/GamesView/GameContextMenu.vala:192 +msgid "Properties" +msgstr "Proprietà" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:100 +#, c-format +msgid "%d game selected" +msgid_plural "%d games selected" +msgstr[0] "%d gioco selezionato" +msgstr[1] "%d giochi selezionati" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:144 +#, c-format +msgid "%d game will be installed" +msgid_plural "%d games will be installed" +msgstr[0] "%d gioco installato" +msgstr[1] "%d giochi installati" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:154 +#, c-format +msgid "%d game will be downloaded" +msgid_plural "%d games will be downloaded" +msgstr[0] "%d gioco verrà scaricato" +msgstr[1] "%d giochi verranno scaricati" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:161 +#, c-format +msgid "Image for %d game will be searched" +msgid_plural "Images for %d games will be searched" +msgstr[0] "Immagine per %d verrà cercata" +msgstr[1] "Immagini per %d verranno cercate" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:168 +#, c-format +msgid "%d game will be uninstalled" +msgid_plural "%d games will be uninstalled" +msgstr[0] "%d gioco verrà disinstallato" +msgstr[1] "%d giochi verranno disinstallati" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:174 +msgid "Refresh" +msgstr "Ricarica" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:175 +#, c-format +msgid "" +"%d game will be removed from database. Restart GameHub to fetch new data" +msgid_plural "" +"%d games will be removed from database. Restart GameHub to fetch new data" +msgstr[0] "" +"Il gioco %d verrà rimosso dal database. Riavvia GameHub per recuperare nuovi " +"dati" +msgstr[1] "" +"I giochi %d verranno rimossi dal database. Riavvia GameHub per recuperare i " +"nuovi dati" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:240 +msgid "Open store page" +msgstr "Apri la pagina dello store" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:242 +msgid "Game properties" +msgstr "Proprietà del gioco" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:46 +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:60 +msgid "Playtime" +msgstr "Tempo di gioco" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:52 +msgid "Playtime (local)" +msgstr "Tempo di gioco (locale)" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:69 +msgid "Last launch" +msgstr "Ultimo avvio" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:46 +msgid "Achievements" +msgstr "Successi" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:85 +#, c-format +msgid "Unlocked: %s" +msgstr "Sbloccati: %s" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:90 +#, c-format +msgid "Global percentage: %g%%" +msgstr "Percentuale globale : %g%%" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:77 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:103 +msgid "Language" +msgstr "Lingua" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:80 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:106 +msgid "Languages" +msgstr "Lingue" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:147 +msgid "%u DLCs cannot be installed" +msgstr "%u I DLC non possono essere installati" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:71 +msgid "Category" +msgstr "Categoria" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:74 +msgid "Categories" +msgstr "Categorie" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:90 +msgid "Genre" +msgstr "Genere" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:93 +msgid "Genres" +msgstr "Generi" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:109 +msgctxt "igdb" +msgid "Popularity" +msgstr "Popolarità" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:115 +msgctxt "igdb" +msgid "Aggregated rating" +msgstr "Valutazione generale" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:116 +msgctxt "igdb" +msgid "IGDB user rating" +msgstr "Valutazione utente IGDB" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:117 +msgctxt "igdb" +msgid "Total rating" +msgstr "Valutazione totale" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:126 +msgctxt "igdb" +msgid "Release date" +msgstr "Data di rilascio" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:133 +msgctxt "igdb" +msgid "Platforms" +msgstr "Piattaforme" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:139 +msgctxt "igdb" +msgid "Genres" +msgstr "Generi" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:145 +msgctxt "igdb" +msgid "Keywords" +msgstr "Parole chiave" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:152 +msgctxt "igdb" +msgid "Links" +msgstr "Links" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:208 +#, c-format +msgid "Based on %d rating" +msgid_plural "Based on %d ratings" +msgstr[0] "Basato sulla valutazione %d" +msgstr[1] "Basato sulle valutazioni %d" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:290 +msgctxt "igdb" +msgid "Summary" +msgstr "Sommario" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:301 +msgctxt "igdb" +msgid "Storyline" +msgstr "Trama" + +#: src/ui/widgets/FileChooserEntry.vala:49 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select file" +msgstr "Seleziona file" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "No images" +msgstr "No immagini" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "" +"There are no images found for this game\n" +"Make sure game name is correct" +msgstr "" +"Non ci sono immagini trovate per questo gioco\n" +"Assicurati che il nome del gioco sia corretto" + +#: src/ui/widgets/ImagesDownloadPopover.vala:94 +msgid "Search images:" +msgstr "Cerca immagini:" + +#: src/ui/widgets/CompatToolPicker.vala:53 +msgid "Compatibility layer:" +msgstr "Livello di compatibilità:" + +#: src/ui/widgets/CompatToolPicker.vala:92 +msgid "Configure" +msgstr "Configura" + +#: src/ui/widgets/GameTagsList.vala:109 +msgid "Add tag" +msgstr "Aggiungi tag" + +#: src/ui/widgets/TweaksList.vala:86 +msgid "No description" +msgstr "Nessuna descrizione" + +#: src/ui/widgets/TweaksList.vala:124 +msgid "Edit file" +msgstr "Modifica file" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dh" +msgstr "%dh" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dm" +msgstr "%dm" + +#: src/utils/Utils.vala:464 +msgctxt "time" +msgid "%ds" +msgstr "%ds" + +#: src/settings/UI.vala:153 +msgctxt "grid_size_preset" +msgid "Steam" +msgstr "Steam" + +#: src/settings/UI.vala:154 +msgctxt "grid_size_preset" +msgid "Steam (vertical)" +msgstr "Steam (verticale)" + +#: src/settings/UI.vala:155 +msgctxt "grid_size_preset" +msgid "GOG" +msgstr "GOG" + +#: src/settings/UI.vala:156 +msgctxt "grid_size_preset" +msgid "GOG (vertical)" +msgstr "GOG (verticale)" + +#: src/settings/UI.vala:157 +msgctxt "grid_size_preset" +msgid "Square" +msgstr "Squadrato" + +#: src/settings/UI.vala:158 +msgctxt "grid_size_preset" +msgid "Custom" +msgstr "Personalizzato" + +#: src/utils/downloader/Downloader.vala:200 +msgctxt "dl_status" +msgid "Queued" +msgstr "In coda" + +#: src/utils/downloader/Downloader.vala:201 +msgctxt "dl_status" +msgid "Starting download" +msgstr "Avviando download" + +#: src/utils/downloader/Downloader.vala:202 +msgctxt "dl_status" +msgid "Download started" +msgstr "Download avviato" + +#: src/utils/downloader/Downloader.vala:203 +msgctxt "dl_status" +msgid "Download finished" +msgstr "Download terminato" + +#: src/utils/downloader/Downloader.vala:204 +msgctxt "dl_status" +msgid "Download failed" +msgstr "Download fallito" + +#: src/utils/downloader/Downloader.vala:208 +msgctxt "dl_status" +msgid "Downloading: %s" +msgstr "Scaricamento: %s" + +#: src/utils/downloader/Downloader.vala:210 +msgctxt "dl_status" +msgid "Downloading" +msgstr "Scaricamento" + +#: src/utils/downloader/Downloader.vala:214 +msgctxt "dl_status" +msgid "Paused: %s" +msgstr "In pausa: %s" + +#: src/utils/downloader/Downloader.vala:216 +msgctxt "dl_status" +msgid "Paused" +msgstr "In pausa" + +#: src/utils/downloader/Downloader.vala:218 +msgctxt "dl_status" +msgid "Download cancelled" +msgstr "Download cancellato" + +#. TRANSLATORS: Download progress template. %1$d - percentage, %2$s / %3$s - downloaded portion and total file size, %4$s - download speed +#: src/utils/downloader/Downloader.vala:262 +msgctxt "dl_status" +msgid "%1$d%% (%2$s / %3$s) [%4$s/s]" +msgstr "%1$d%% (%2$s / %3$s) [%4$s/s]" + +#~ msgid "Disable esync" +#~ msgstr "Disabilita esync" + +#~ msgid "Force LARGE_ADDRESS_AWARE flag" +#~ msgstr "Forza la flag LARGE_ADDRESS_AWARE" + +#~ msgid "Disable DirectX 11 compatibility layer" +#~ msgstr "Disattiva il livello di compatibilità per DirectX 11" + +#~ msgid "Use WineD3D11 as DirectX 11 compatibility layer" +#~ msgstr "Utilizza WineD3D11 come livello di compatibilità per DirectX 11" + +#~ msgid "Show DXVK info overlay" +#~ msgstr "Mostra le informazioni DXVK su schermo" + +#~ msgid "Enable DirectX 9 compatibility layer" +#~ msgstr "Abilita livello di compatibilità DirectX 9" + +#~ msgid "Silent installation" +#~ msgstr "Installazione silenziosa" + +#~ msgid "Very silent installation" +#~ msgstr "Vera installazione silenziosa" + +#~ msgid "Suppress messages" +#~ msgstr "Sopprimi messaggi" + +#~ msgid "No GUI" +#~ msgstr "Nessuna GUI" + +#~ msgid "Disable fullscreen" +#~ msgstr "Disattiva fullscreen" + +#~ msgid "Windowed" +#~ msgstr "In finestra" + +#~ msgid "Compact list" +#~ msgstr "Lista compatta" + +#~ msgid "Show non-native games" +#~ msgstr "Mostra giochi non nativi" + +#~ msgid "Use compatibility layers and consider Windows games compatible" +#~ msgstr "" +#~ "Usa livello di compatibilità e considera i giochi Windows come " +#~ "compatibili " + +#~ msgid "Use symbolic icons instead of colored icons" +#~ msgstr "Usa icone simboliche anzichè le colorate" diff --git a/po/ko.po b/po/ko.po new file mode 100644 index 00000000..8b717462 --- /dev/null +++ b/po/ko.po @@ -0,0 +1,1787 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the com.github.tkashkin.gamehub package. +# ParkSeongSoo , 2019. +msgid "" +msgstr "" +"Project-Id-Version: com.github.tkashkin.gamehub\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-26 06:40+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: src/app.vala:91 +msgid "Show help" +msgstr "" + +#: src/app.vala:92 +msgid "Show application version and exit" +msgstr "" + +#: src/app.vala:93 +msgid "Restart with GDB debugger attached" +msgstr "" + +#: src/app.vala:94 +msgid "Show full GDB backtrace" +msgstr "" + +#: src/app.vala:95 +msgid "Treat fatal errors as criticals and crash application" +msgstr "" + +#: src/app.vala:99 +msgid "Show main window" +msgstr "" + +#: src/app.vala:100 +msgid "Show application settings dialog" +msgstr "" + +#: src/app.vala:101 +msgid "Show about dialog" +msgstr "" + +#: src/app.vala:102 +msgid "Maximum number of background worker threads" +msgstr "" + +#: src/app.vala:106 +msgid "Run game" +msgstr "" + +#: src/app.vala:107 +msgid "Show compatibility options dialog" +msgstr "" + +#: src/app.vala:108 +msgid "Open game details" +msgstr "" + +#: src/app.vala:109 +msgid "Open game properties" +msgstr "" + +#: src/app.vala:113 +msgid "Enable debug logging" +msgstr "" + +#: src/app.vala:114 +msgid "" +"Log authentication process and sensitive information like authentication " +"tokens" +msgstr "" + +#: src/app.vala:115 +msgid "Log download manager" +msgstr "" + +#: src/app.vala:116 +msgid "Log background workers start/stop" +msgstr "" + +#: src/app.vala:117 +msgid "Disable log messages filtering" +msgstr "" + +#: src/app.vala:118 +msgid "Verbose logging" +msgstr "" + +#: src/app.vala:247 +msgid "Game Options:" +msgstr "" + +#: src/app.vala:247 +msgid "Show game options help" +msgstr "" + +#: src/app.vala:255 +msgid "Logging Options:" +msgstr "" + +#: src/app.vala:255 +msgid "Show logging options help" +msgstr "" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +msgid "Select executable" +msgstr "" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:181 src/ui/views/GamesView/GamesView.vala:330 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select" +msgstr "" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:180 src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Cancel" +msgstr "" + +#: src/data/Runnable.vala:166 src/ui/widgets/FileChooserEntry.vala:49 +msgid "Select directory" +msgstr "" + +#: src/data/Runnable.vala:619 +#, c-format +msgid "Part %1$u of %2$u: %3$s" +msgstr "" + +#: src/data/Runnable.vala:642 src/ui/dialogs/CorruptedInstallerDialog.vala:48 +#, c-format +msgid "%s: corrupted installer" +msgstr "" + +#: src/data/Runnable.vala:643 +#, c-format +msgid "Checksum mismatch in %s" +msgstr "" + +#: src/data/Runnable.vala:657 src/ui/dialogs/CorruptedInstallerDialog.vala:126 +msgid "Show file" +msgstr "" + +#: src/data/Runnable.vala:658 src/ui/dialogs/CorruptedInstallerDialog.vala:132 +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#: src/ui/widgets/TagRow.vala:146 +msgid "Remove" +msgstr "" + +#: src/data/Runnable.vala:659 src/ui/dialogs/CorruptedInstallerDialog.vala:128 +msgid "Backup" +msgstr "" + +#: src/data/Runnable.vala:778 +#, c-format +msgid "%s: cannot detect main executable" +msgstr "" + +#: src/data/Runnable.vala:779 +msgid "" +"Main executable file for this game cannot be detected automatically.\n" +"Please set main executable in game's properties." +msgstr "" + +#: src/data/Runnable.vala:908 +msgctxt "platform" +msgid "Emulated" +msgstr "" + +#: src/data/Game.vala:625 +msgctxt "status" +msgid "Running" +msgstr "" + +#: src/data/Game.vala:628 +msgctxt "status" +msgid "Installed" +msgstr "" + +#: src/data/Game.vala:629 +msgctxt "status" +msgid "Installing" +msgstr "" + +#: src/data/Game.vala:630 +msgctxt "status" +msgid "Verifying installer integrity" +msgstr "" + +#: src/data/Game.vala:631 +msgctxt "status" +msgid "Download started" +msgstr "" + +#: src/data/Game.vala:633 +msgctxt "status" +msgid "Not installed" +msgstr "" + +#: src/data/Game.vala:643 +msgctxt "status_header" +msgid "Installed" +msgstr "" + +#: src/data/Game.vala:644 +msgctxt "status_header" +msgid "Installing" +msgstr "" + +#: src/data/Game.vala:646 +msgctxt "status_header" +msgid "Downloading" +msgstr "" + +#: src/data/Game.vala:648 +msgctxt "status_header" +msgid "Not installed" +msgstr "" + +#: src/data/GameSource.vala:31 +#, c-format +msgid "%s games" +msgstr "" + +#: src/data/sources/steam/Steam.vala:43 +msgid "Your SteamID will be read from Steam configuration file" +msgstr "" + +#: src/data/sources/steam/Steam.vala:46 +msgid "" +"Steam config file not found.\n" +"Login into your account in Steam client and return to GameHub" +msgstr "" + +#: src/data/sources/gog/GOGGame.vala:983 +#, c-format +msgid "DLC: %s" +msgstr "" + +#: src/data/sources/humble/HumbleGame.vala:343 +#, c-format +msgid "%s: no available installers" +msgstr "" + +#: src/data/sources/humble/HumbleGame.vala:344 +msgid "" +"Cannot get Trove download URL.\n" +"Make sure your Humble Monthly subscription is active." +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:192 +#, c-format +msgctxt "itch_dl_status" +msgid "%s left;" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:195 +#, c-format +msgctxt "itch_dl_status" +msgid "%d%%" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:198 +#, c-format +msgctxt "itch_dl_status" +msgid "(%1$s / %2$s)" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:201 +#, c-format +msgctxt "itch_dl_status" +msgid "[%s/s]" +msgstr "" + +#: src/data/sources/user/User.vala:30 +msgid "User games" +msgstr "" + +#: src/data/db/tables/Tags.vala:225 +msgctxt "tag" +msgid "Favorites" +msgstr "" + +#: src/data/db/tables/Tags.vala:226 +msgctxt "tag" +msgid "Not installed" +msgstr "" + +#: src/data/db/tables/Tags.vala:227 +msgctxt "tag" +msgid "Installed" +msgstr "" + +#: src/data/db/tables/Tags.vala:228 +msgctxt "tag" +msgid "Hidden" +msgstr "" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit script" +msgstr "" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit custom script" +msgstr "" + +#: src/data/compat/Innoextract.vala:55 +#, c-format +msgid "" +"Innoextract %1$s is not supported and may not be able to extract some " +"games correctly.\n" +"Install innoextract %2$s or newer." +msgstr "" + +#: src/data/compat/WineWrap.vala:61 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:242 +#: src/ui/dialogs/CompatRunDialog.vala:102 +#: src/ui/views/GamesView/GameContextMenu.vala:53 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:234 +msgid "Run" +msgstr "" + +#: src/data/compat/WineWrap.vala:64 +msgid "Show WineWrap menu" +msgstr "" + +#: src/data/compat/WineWrap.vala:67 src/data/compat/Proton.vala:122 +#: src/data/compat/Wine.vala:83 +msgid "Kill apps in prefix" +msgstr "" + +#: src/data/compat/Proton.vala:47 +msgid "Proton prefix" +msgstr "" + +#: src/data/compat/Proton.vala:110 src/data/compat/Wine.vala:71 +msgid "Open prefix directory" +msgstr "" + +#: src/data/compat/Proton.vala:113 src/data/compat/Wine.vala:74 +msgid "Run winecfg" +msgstr "" + +#: src/data/compat/Proton.vala:116 src/data/compat/Wine.vala:77 +msgid "Run winetricks" +msgstr "" + +#: src/data/compat/Proton.vala:119 src/data/compat/Wine.vala:80 +msgid "Run taskmgr" +msgstr "" + +#: src/data/compat/Wine.vala:53 +msgid "Wine prefix" +msgstr "" + +#: src/data/compat/Wine.vala:55 +msgid "Environment variables" +msgstr "" + +#: src/data/compat/Wine.vala:60 +msgid "InnoSetup default options" +msgstr "" + +#: src/data/compat/RetroArch.vala:53 +msgid "Libretro core file" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:43 +msgid "Custom emulator" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:48 +msgid "Emulator" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:49 +msgid "Launch in game directory" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:440 +msgctxt "status_header" +msgid "Favorites" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:445 +#, c-format +msgctxt "status_header" +msgid "%s: Favorites" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:491 +msgid "Merging games" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:504 +#, c-format +msgid "Merging games from %s" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:551 +#, c-format +msgid "Loading games from %s" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:678 +msgctxt "sort_mode" +msgid "By name" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:679 +msgctxt "sort_mode" +msgid "By last launch" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:680 +msgctxt "sort_mode" +msgid "By playtime" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:705 +msgctxt "group_mode" +msgid "Do not group" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:706 +msgctxt "group_mode" +msgid "By status" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:707 +msgctxt "group_mode" +msgid "By source" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:151 +#: src/data/providers/data/IGDB.vala:431 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:217 +msgid "Default" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:158 +#: src/data/providers/data/IGDB.vala:438 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:225 +msgid "Restore default API key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:169 +#: src/data/providers/data/IGDB.vala:449 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:108 +msgid "API key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:177 +#: src/data/providers/data/IGDB.vala:457 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:53 +msgid "Generate key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:208 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Style" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:209 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Score" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:213 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Author" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:225 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Alternate" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:226 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Blurred" +msgstr "" + +#. TRANSLATORS: Flat / Material Design image style. Probably should not be translated +#: src/data/providers/images/SteamGridDB.vala:228 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Material" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:229 +msgctxt "imagesource_steamgriddb_image_style" +msgid "No logo" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:230 +msgctxt "imagesource_steamgriddb_image_style" +msgid "White logo" +msgstr "" + +#: src/data/providers/data/IGDB.vala:147 +msgid "" +"Monthly IGDB request quota has been reached. Set your own API key to use " +"IGDB data or disable IGDB." +msgstr "" + +#: src/data/providers/data/IGDB.vala:148 +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:40 +#: src/ui/views/WelcomeView.vala:53 src/ui/views/WelcomeView.vala:78 +#: src/ui/views/GamesView/GamesView.vala:230 +#: src/ui/views/GamesView/GamesView.vala:629 +msgid "Settings" +msgstr "" + +#: src/data/providers/data/IGDB.vala:356 +msgctxt "igdb_related_link" +msgid "Official website" +msgstr "" + +#: src/data/providers/data/IGDB.vala:469 +msgctxt "igdb_preferred_description" +msgid "When game has description, show description" +msgstr "" + +#: src/data/providers/data/IGDB.vala:476 +msgctxt "igdb_preferred_description" +msgid "of game" +msgstr "" + +#: src/data/providers/data/IGDB.vala:477 +msgctxt "igdb_preferred_description" +msgid "from IGDB" +msgstr "" + +#: src/data/providers/data/IGDB.vala:478 +msgctxt "igdb_preferred_description" +msgid "both" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:65 +msgid "Some settings will be applied after application restart" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:71 +msgid "Games directory contains space. It may cause problems for some games" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:36 +msgid "Interface" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:37 +msgid "Appearance" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:38 +msgid "General interface settings" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:48 +msgid "Dark theme" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:53 +msgctxt "icon_style" +msgid "Theme-based" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:54 +msgctxt "icon_style" +msgid "Symbolic" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:55 +msgctxt "icon_style" +msgid "Colored" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:57 +msgctxt "icon_style" +msgid "Icon style" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:84 +msgid "Game card" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:86 +msgid "Show platform icons" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:99 +msgctxt "grid_size" +msgid "Card size" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:117 +msgctxt "grid_size_preset" +msgid "Presets" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:139 +msgid "Games list: installed" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:140 +msgid "Games list: not installed" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:142 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:146 +msgctxt "list_style" +msgid "Show icon" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:143 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:147 +msgctxt "list_style" +msgid "Bold title" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:144 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:148 +msgctxt "list_style" +msgid "Show status" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:149 +msgctxt "list_style" +msgid "Dim" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:151 +msgid "Grid options" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:152 +msgid "List options" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:31 +msgid "Behavior" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:32 +msgid "Behavior settings" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:42 +msgid "Run games with double click" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:46 +msgid "Merge games from different sources" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:50 +msgid "Use imported tags" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:51 +msgid "General" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:52 +msgid "Collection" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:53 +msgid "Empty" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:65 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:85 +msgid "Collection directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:70 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:78 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:87 +msgid "Game directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:71 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:79 +msgid "Installers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:72 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:98 +msgid "DLC" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:73 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:197 +msgid "Bonus content" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:84 +msgid "Variable syntax: $var or ${var}" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:86 +msgid "Game name" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:88 +#: src/ui/views/GamesView/FiltersPopover.vala:127 +msgid "Platform" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:36 +msgid "Controller" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +msgid "Enabled" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:53 +msgid "Focus GameHub window with Guide button" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:57 +msgid "Controllers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:89 +msgid "Move focus" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:91 +msgid "Exit" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:40 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:108 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:92 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:95 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:36 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:77 +msgid "Disabled" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:47 +#: src/ui/dialogs/GameTweaksDialog.vala:53 +#: src/ui/views/GamesView/GameContextMenu.vala:183 +msgid "Tweaks" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:34 +msgid "Tweak launch options and apply them to games automatically" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:79 +msgid "" +"Tweaks are loaded from following directories in order\n" +"Last tweak overrides previous tweaks with same identifiers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:83 +msgid "Click to open" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:93 +#, c-format +msgid "Tweaks are loaded from %1$s and %2$d more directories (?)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:38 +msgid "Game sources" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +msgid "Steam API keys have limited number of uses per day" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:63 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:57 +msgid "Installation directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:176 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:81 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:34 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:75 +msgid "Not installed" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:116 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:96 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:99 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:85 +msgid "Not authenticated" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +#, c-format +msgid "Authenticated as %s" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:103 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +msgid "Authenticated" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:183 +#: src/ui/dialogs/InstallDialog.vala:53 src/ui/dialogs/InstallDialog.vala:111 +#: src/ui/views/GamesView/GameContextMenu.vala:80 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:233 +#: src/ui/widgets/TweaksList.vala:95 +msgid "Install" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:236 +msgid "Steam API key" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:50 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:54 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:48 +msgid "Games directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:63 +msgid "Logout" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:50 +msgid "Load games from Humble Trove" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:45 +msgid "Emulators" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:45 +msgid "Libretro core directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:46 +msgid "Libretro core info directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:50 +msgid "Ignored libretro cores" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:54 +msgid "Ignored game file extensions" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:66 +msgid "No cores found" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:70 +#, c-format +msgid "%u core found" +msgid_plural "%u cores found" +msgstr[0] "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:46 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:168 +msgid "No custom emulators" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:164 +#, c-format +msgid "%u custom emulator" +msgid_plural "%u custom emulators" +msgstr[0] "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:237 +msgid "Save" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:250 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:312 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/dialogs/GamePropertiesDialog.vala:168 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +#: src/ui/views/GamesView/AddGamePopover.vala:67 +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Executable" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:251 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/views/GamesView/AddGamePopover.vala:68 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Installer" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:256 +#: src/ui/dialogs/GamePropertiesDialog.vala:64 +#: src/ui/dialogs/GamePropertiesDialog.vala:69 +#: src/ui/views/GamesView/AddGamePopover.vala:73 +msgid "Name" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:272 +#: src/ui/dialogs/GamePropertiesDialog.vala:201 +#: src/ui/views/GamesView/AddGamePopover.vala:78 +msgid "Arguments" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:276 +msgid "Variables" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:277 +msgid "Game executable" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:278 +msgid "Game arguments" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:80 +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +msgid "Select emulator directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:292 +#: src/ui/dialogs/GamePropertiesDialog.vala:219 +msgid "Force compatibility mode" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:307 +msgid "Game file patterns" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:315 +msgid "Image" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:318 +msgid "Icon" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:325 +msgid "" +"findutils-compatible glob patterns\n" +"\n" +" Multiple patterns can be separated with |\n" +" Start pattern with ./ to match relative path\n" +" $basename variable will be replaced with game's executable " +"name (without extension)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:38 +msgid "Data" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:39 +msgid "Providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:40 +msgid "Third-party data providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:55 +msgid "Image providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:68 +msgid "Metadata providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:137 +msgid "Open website" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:36 +msgid "About" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:71 +msgid "Copy application version and environment info" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:78 +#: src/ui/views/WelcomeView.vala:57 +msgid "All your games in one place" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:92 +msgctxt "about_link" +msgid "Website" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:96 +msgctxt "about_link" +msgid "Source code on GitHub" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:103 +msgctxt "about_link" +msgid "Report a problem" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:104 +msgctxt "about_link" +msgid "Suggest translations" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:110 +msgctxt "about_link" +msgid "Issues" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:111 +msgctxt "about_link" +msgid "Contributors" +msgstr "" + +#. TRANSLATORS: Likely it should not be translated. GitHub Pulse is a page that shows recent repository activity: https://github.com/tkashkin/GameHub/pulse +#: src/ui/dialogs/SettingsDialog/pages/About.vala:114 +msgctxt "about_link" +msgid "Pulse" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:115 +msgctxt "about_link" +msgid "Forks" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:109 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:129 +msgid "Import" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:110 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:153 +msgid "Download" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:207 +msgid "Select installer" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:216 +#, c-format +msgid "Installer size: %s" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:348 +msgid "Unknown" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:49 +#, c-format +msgid "%s: Properties" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:84 +msgid "Images" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:126 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:160 +#: src/ui/views/GameDetailsView/blocks/Artwork.vala:62 +msgid "Download images" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:144 +msgid "Image URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:148 +msgid "Vertical image URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:157 +msgid "Icon URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Select working directory" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Working directory" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:214 +msgid "Compatibility" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:236 +msgid "Launch from terminal" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:252 +msgid "Copy to clipboard" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:254 +msgid "Add to Steam" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:255 +msgid "Add to the Steam library" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:53 +#, c-format +msgid "%s: Overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "Overlays are disabled" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "" +"Enable overlays to manage DLCs and mods\n" +"\n" +"Enabling will move game to the “base“ overlay" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:77 +#: src/ui/views/GamesView/GameContextMenu.vala:175 +msgid "Overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:105 +msgid "Overlay ID (directory name)" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:110 +msgid "Overlay name (optional)" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:112 +msgid "Add" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:127 +msgid "Enable overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:182 +#, c-format +msgid "" +"Overlay usage at this path may be unsafe\n" +"Proceed at your own risk\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:187 +#, c-format +msgid "" +"Overlay usage at this path is not supported\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:266 +msgid "Open directory" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:271 +msgid "Remove overlay" +msgstr "" + +#: src/ui/dialogs/CompatRunDialog.vala:48 +#: src/ui/views/GamesView/GameContextMenu.vala:46 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:235 +msgid "Run with compatibility layer" +msgstr "" + +#: src/ui/dialogs/CorruptedInstallerDialog.vala:71 +msgid "Corrupted installer: checksum mismatch in" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:57 +#: src/ui/views/GamesView/AddGamePopover.vala:105 +msgid "Import emulated games" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:75 +msgid "Select directory with emulated games" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:83 +msgid "Detected games" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:107 +msgid "Select all" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:115 +msgid "Select directory to import" +msgstr "" + +#: src/ui/dialogs/GameTweaksDialog.vala:40 +#, c-format +msgid "%s: Tweaks" +msgstr "" + +#: src/ui/views/WelcomeView.vala:52 +msgid "No enabled game sources" +msgstr "" + +#: src/ui/views/WelcomeView.vala:52 +msgid "Enable some game sources in settings" +msgstr "" + +#: src/ui/views/WelcomeView.vala:57 +msgid "Let's get started" +msgstr "" + +#: src/ui/views/WelcomeView.vala:71 +msgid "Skip" +msgstr "" + +#: src/ui/views/WelcomeView.vala:141 +msgid "Ready" +msgstr "" + +#: src/ui/views/WelcomeView.vala:147 +msgid "Authentication required" +msgstr "" + +#: src/ui/views/WelcomeView.vala:152 +msgid "Authenticating…" +msgstr "" + +#: src/ui/views/WelcomeView.vala:163 +#, c-format +msgid "Install %s" +msgstr "" + +#: src/ui/views/WelcomeView.vala:164 +msgid "Return to GameHub after installing" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "No games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "Get some games or enable some game sources in settings" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:150 +msgid "Grid view" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:151 +msgid "List view" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:159 +msgid "All games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:182 +msgid "Downloads" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:208 +msgid "Filters" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:216 +#: src/ui/views/GamesView/AddGamePopover.vala:84 +msgid "Add game" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:223 +msgid "Search" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:328 +msgid "Menu" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:329 +#: src/ui/views/GameDetailsView/GameDetailsView.vala:104 +msgid "Back" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:550 +#, c-format +msgid "%u game" +msgid_plural "%u games" +msgstr[0] "" + +#: src/ui/views/GamesView/GamesView.vala:553 +#, c-format +msgctxt "games_view_subtitle_filtered_games" +msgid "%1$u / %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:557 +#, c-format +msgctxt "games_view_subtitle" +msgid "%1$s: %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:568 +msgid "No user-added games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:569 +msgid "Add some games using plus button" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:573 +#, c-format +msgid "No %s games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:574 +msgid "Get some Linux-compatible games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:584 +#, c-format +msgid "No games matching “%s”" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:589 +#, c-format +msgid "No %1$s games matching “%2$s”" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:627 +msgid "" +"No games were loaded from Steam. Set your games list privacy to public or " +"use your own Steam API key in settings." +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:628 +msgid "Privacy" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:739 +msgid "Downloading images" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:753 +#, c-format +msgid "Downloading image: %s" +msgstr "" + +#: src/ui/views/GamesView/DownloadProgressView.vala:131 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:162 +msgid "Pause download" +msgstr "" + +#: src/ui/views/GamesView/DownloadProgressView.vala:137 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:168 +msgid "Resume download" +msgstr "" + +#: src/ui/views/GamesView/DownloadProgressView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:174 +msgid "Cancel download" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:77 +msgid "Group" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:102 +msgid "Sort" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:234 +#: src/ui/widgets/GameTagsList.vala:58 +msgid "Tags" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:353 +msgid "All platforms" +msgstr "" + +#: src/ui/views/GamesView/AddGamePopover.vala:77 +msgid "Select game executable" +msgstr "" + +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Select game directory" +msgstr "" + +#: src/ui/views/GamesView/AddGamePopover.vala:111 +msgid "Download game images" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:87 +msgid "Details" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:117 +msgctxt "game_context_menu" +msgid "Favorite" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:121 +msgctxt "game_context_menu" +msgid "Hidden" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:133 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:236 +msgid "Open installation directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:142 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:237 +msgid "Open installers collection directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:151 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:238 +msgid "Open bonus collection directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:160 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:239 +msgid "Open screenshots directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +msgid "Uninstall" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:192 +msgid "Properties" +msgstr "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:100 +#, c-format +msgid "%d game selected" +msgid_plural "%d games selected" +msgstr[0] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:144 +#, c-format +msgid "%d game will be installed" +msgid_plural "%d games will be installed" +msgstr[0] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:154 +#, c-format +msgid "%d game will be downloaded" +msgid_plural "%d games will be downloaded" +msgstr[0] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:161 +#, c-format +msgid "Image for %d game will be searched" +msgid_plural "Images for %d games will be searched" +msgstr[0] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:168 +#, c-format +msgid "%d game will be uninstalled" +msgid_plural "%d games will be uninstalled" +msgstr[0] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:174 +msgid "Refresh" +msgstr "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:175 +#, c-format +msgid "" +"%d game will be removed from database. Restart GameHub to fetch new data" +msgid_plural "" +"%d games will be removed from database. Restart GameHub to fetch new data" +msgstr[0] "" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:240 +msgid "Open store page" +msgstr "" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:242 +msgid "Game properties" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:46 +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:60 +msgid "Playtime" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:52 +msgid "Playtime (local)" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:69 +msgid "Last launch" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:46 +msgid "Achievements" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:85 +#, c-format +msgid "Unlocked: %s" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:90 +#, c-format +msgid "Global percentage: %g%%" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:77 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:103 +msgid "Language" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:80 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:106 +msgid "Languages" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:147 +#, c-format +msgid "%u DLCs cannot be installed" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:71 +msgid "Category" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:74 +msgid "Categories" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:90 +msgid "Genre" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:93 +msgid "Genres" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:109 +msgctxt "igdb" +msgid "Popularity" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:115 +msgctxt "igdb" +msgid "Aggregated rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:116 +msgctxt "igdb" +msgid "IGDB user rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:117 +msgctxt "igdb" +msgid "Total rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:126 +msgctxt "igdb" +msgid "Release date" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:133 +msgctxt "igdb" +msgid "Platforms" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:139 +msgctxt "igdb" +msgid "Genres" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:145 +msgctxt "igdb" +msgid "Keywords" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:152 +msgctxt "igdb" +msgid "Links" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:208 +#, c-format +msgid "Based on %d rating" +msgid_plural "Based on %d ratings" +msgstr[0] "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:290 +msgctxt "igdb" +msgid "Summary" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:301 +msgctxt "igdb" +msgid "Storyline" +msgstr "" + +#: src/ui/widgets/FileChooserEntry.vala:49 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select file" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "No images" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "" +"There are no images found for this game\n" +"Make sure game name is correct" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:94 +msgid "Search images:" +msgstr "" + +#: src/ui/widgets/CompatToolPicker.vala:53 +msgid "Compatibility layer:" +msgstr "" + +#: src/ui/widgets/CompatToolPicker.vala:92 +msgid "Configure" +msgstr "" + +#: src/ui/widgets/GameTagsList.vala:109 +msgid "Add tag" +msgstr "" + +#: src/ui/widgets/TweaksList.vala:86 +msgid "No description" +msgstr "" + +#: src/ui/widgets/TweaksList.vala:124 +msgid "Edit file" +msgstr "" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dh" +msgstr "" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dm" +msgstr "" + +#: src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%ds" +msgstr "" + +#: src/settings/UI.vala:153 +msgctxt "grid_size_preset" +msgid "Steam" +msgstr "" + +#: src/settings/UI.vala:154 +msgctxt "grid_size_preset" +msgid "Steam (vertical)" +msgstr "" + +#: src/settings/UI.vala:155 +msgctxt "grid_size_preset" +msgid "GOG" +msgstr "" + +#: src/settings/UI.vala:156 +msgctxt "grid_size_preset" +msgid "GOG (vertical)" +msgstr "" + +#: src/settings/UI.vala:157 +msgctxt "grid_size_preset" +msgid "Square" +msgstr "" + +#: src/settings/UI.vala:158 +msgctxt "grid_size_preset" +msgid "Custom" +msgstr "" + +#: src/utils/downloader/Downloader.vala:200 +msgctxt "dl_status" +msgid "Queued" +msgstr "" + +#: src/utils/downloader/Downloader.vala:201 +msgctxt "dl_status" +msgid "Starting download" +msgstr "" + +#: src/utils/downloader/Downloader.vala:202 +msgctxt "dl_status" +msgid "Download started" +msgstr "" + +#: src/utils/downloader/Downloader.vala:203 +msgctxt "dl_status" +msgid "Download finished" +msgstr "" + +#: src/utils/downloader/Downloader.vala:204 +msgctxt "dl_status" +msgid "Download failed" +msgstr "" + +#: src/utils/downloader/Downloader.vala:208 +#, c-format +msgctxt "dl_status" +msgid "Downloading: %s" +msgstr "" + +#: src/utils/downloader/Downloader.vala:210 +msgctxt "dl_status" +msgid "Downloading" +msgstr "" + +#: src/utils/downloader/Downloader.vala:214 +#, c-format +msgctxt "dl_status" +msgid "Paused: %s" +msgstr "" + +#: src/utils/downloader/Downloader.vala:216 +msgctxt "dl_status" +msgid "Paused" +msgstr "" + +#: src/utils/downloader/Downloader.vala:218 +msgctxt "dl_status" +msgid "Download cancelled" +msgstr "" + +#. TRANSLATORS: Download progress template. %1$d - percentage, %2$s / %3$s - downloaded portion and total file size, %4$s - download speed +#: src/utils/downloader/Downloader.vala:262 +#, c-format +msgctxt "dl_status" +msgid "%1$d%% (%2$s / %3$s) [%4$s/s]" +msgstr "" diff --git a/po/meson.build b/po/meson.build index fc761bef..3fb59396 100644 --- a/po/meson.build +++ b/po/meson.build @@ -1,3 +1,4 @@ -i18n.gettext(meson.project_name(), - args: ['--directory='+meson.source_root(), '--from-code=UTF-8'] +import('i18n').gettext(meson.project_name(), + args: ['--directory=' + meson.source_root(), '--from-code=UTF-8'], + preset: 'glib' ) diff --git a/po/mr.po b/po/mr.po new file mode 100644 index 00000000..04adf762 --- /dev/null +++ b/po/mr.po @@ -0,0 +1,1799 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the com.github.tkashkin.gamehub package. +# Prachi Joshi , 2020. +msgid "" +msgstr "" +"Project-Id-Version: com.github.tkashkin.gamehub\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-26 06:40+0300\n" +"PO-Revision-Date: 2020-03-03 19:33+0000\n" +"Last-Translator: Prachi Joshi \n" +"Language-Team: Marathi \n" +"Language: mr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.0-dev\n" + +#: src/app.vala:91 +msgid "Show help" +msgstr "मदत दर्शवा" + +#: src/app.vala:92 +msgid "Show application version and exit" +msgstr "अनुप्रयोग आवृत्ती दर्शवा आणि बाहेर पडा" + +#: src/app.vala:93 +msgid "Restart with GDB debugger attached" +msgstr "संलग्न जीडीबी डीबगरसह रीस्टार्ट करा" + +#: src/app.vala:94 +msgid "Show full GDB backtrace" +msgstr "" + +#: src/app.vala:95 +msgid "Treat fatal errors as criticals and crash application" +msgstr "" + +#: src/app.vala:99 +msgid "Show main window" +msgstr "" + +#: src/app.vala:100 +msgid "Show application settings dialog" +msgstr "" + +#: src/app.vala:101 +msgid "Show about dialog" +msgstr "" + +#: src/app.vala:102 +msgid "Maximum number of background worker threads" +msgstr "" + +#: src/app.vala:106 +msgid "Run game" +msgstr "" + +#: src/app.vala:107 +msgid "Show compatibility options dialog" +msgstr "" + +#: src/app.vala:108 +msgid "Open game details" +msgstr "" + +#: src/app.vala:109 +msgid "Open game properties" +msgstr "" + +#: src/app.vala:113 +msgid "Enable debug logging" +msgstr "" + +#: src/app.vala:114 +msgid "" +"Log authentication process and sensitive information like authentication " +"tokens" +msgstr "" + +#: src/app.vala:115 +msgid "Log download manager" +msgstr "" + +#: src/app.vala:116 +msgid "Log background workers start/stop" +msgstr "" + +#: src/app.vala:117 +msgid "Disable log messages filtering" +msgstr "" + +#: src/app.vala:118 +msgid "Verbose logging" +msgstr "" + +#: src/app.vala:247 +msgid "Game Options:" +msgstr "" + +#: src/app.vala:247 +msgid "Show game options help" +msgstr "" + +#: src/app.vala:255 +msgid "Logging Options:" +msgstr "" + +#: src/app.vala:255 +msgid "Show logging options help" +msgstr "" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +msgid "Select executable" +msgstr "" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:181 src/ui/views/GamesView/GamesView.vala:330 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select" +msgstr "" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:180 src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Cancel" +msgstr "" + +#: src/data/Runnable.vala:166 src/ui/widgets/FileChooserEntry.vala:49 +msgid "Select directory" +msgstr "" + +#: src/data/Runnable.vala:619 +#, c-format +msgid "Part %1$u of %2$u: %3$s" +msgstr "" + +#: src/data/Runnable.vala:642 src/ui/dialogs/CorruptedInstallerDialog.vala:48 +#, c-format +msgid "%s: corrupted installer" +msgstr "" + +#: src/data/Runnable.vala:643 +#, c-format +msgid "Checksum mismatch in %s" +msgstr "" + +#: src/data/Runnable.vala:657 src/ui/dialogs/CorruptedInstallerDialog.vala:126 +msgid "Show file" +msgstr "" + +#: src/data/Runnable.vala:658 src/ui/dialogs/CorruptedInstallerDialog.vala:132 +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#: src/ui/widgets/TagRow.vala:146 +msgid "Remove" +msgstr "" + +#: src/data/Runnable.vala:659 src/ui/dialogs/CorruptedInstallerDialog.vala:128 +msgid "Backup" +msgstr "" + +#: src/data/Runnable.vala:778 +#, c-format +msgid "%s: cannot detect main executable" +msgstr "" + +#: src/data/Runnable.vala:779 +msgid "" +"Main executable file for this game cannot be detected automatically.\n" +"Please set main executable in game's properties." +msgstr "" + +#: src/data/Runnable.vala:908 +msgctxt "platform" +msgid "Emulated" +msgstr "" + +#: src/data/Game.vala:625 +msgctxt "status" +msgid "Running" +msgstr "" + +#: src/data/Game.vala:628 +msgctxt "status" +msgid "Installed" +msgstr "" + +#: src/data/Game.vala:629 +msgctxt "status" +msgid "Installing" +msgstr "" + +#: src/data/Game.vala:630 +msgctxt "status" +msgid "Verifying installer integrity" +msgstr "" + +#: src/data/Game.vala:631 +msgctxt "status" +msgid "Download started" +msgstr "" + +#: src/data/Game.vala:633 +msgctxt "status" +msgid "Not installed" +msgstr "" + +#: src/data/Game.vala:643 +msgctxt "status_header" +msgid "Installed" +msgstr "" + +#: src/data/Game.vala:644 +msgctxt "status_header" +msgid "Installing" +msgstr "" + +#: src/data/Game.vala:646 +msgctxt "status_header" +msgid "Downloading" +msgstr "" + +#: src/data/Game.vala:648 +msgctxt "status_header" +msgid "Not installed" +msgstr "" + +#: src/data/GameSource.vala:31 +#, c-format +msgid "%s games" +msgstr "" + +#: src/data/sources/steam/Steam.vala:43 +msgid "Your SteamID will be read from Steam configuration file" +msgstr "" + +#: src/data/sources/steam/Steam.vala:46 +msgid "" +"Steam config file not found.\n" +"Login into your account in Steam client and return to GameHub" +msgstr "" + +#: src/data/sources/gog/GOGGame.vala:983 +#, c-format +msgid "DLC: %s" +msgstr "" + +#: src/data/sources/humble/HumbleGame.vala:343 +#, c-format +msgid "%s: no available installers" +msgstr "" + +#: src/data/sources/humble/HumbleGame.vala:344 +msgid "" +"Cannot get Trove download URL.\n" +"Make sure your Humble Monthly subscription is active." +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:192 +#, c-format +msgctxt "itch_dl_status" +msgid "%s left;" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:195 +#, c-format +msgctxt "itch_dl_status" +msgid "%d%%" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:198 +#, c-format +msgctxt "itch_dl_status" +msgid "(%1$s / %2$s)" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:201 +#, c-format +msgctxt "itch_dl_status" +msgid "[%s/s]" +msgstr "" + +#: src/data/sources/user/User.vala:30 +msgid "User games" +msgstr "" + +#: src/data/db/tables/Tags.vala:225 +msgctxt "tag" +msgid "Favorites" +msgstr "" + +#: src/data/db/tables/Tags.vala:226 +msgctxt "tag" +msgid "Not installed" +msgstr "" + +#: src/data/db/tables/Tags.vala:227 +msgctxt "tag" +msgid "Installed" +msgstr "" + +#: src/data/db/tables/Tags.vala:228 +msgctxt "tag" +msgid "Hidden" +msgstr "" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit script" +msgstr "" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit custom script" +msgstr "" + +#: src/data/compat/Innoextract.vala:55 +#, c-format +msgid "" +"Innoextract %1$s is not supported and may not be able to extract some " +"games correctly.\n" +"Install innoextract %2$s or newer." +msgstr "" + +#: src/data/compat/WineWrap.vala:61 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:242 +#: src/ui/dialogs/CompatRunDialog.vala:102 +#: src/ui/views/GamesView/GameContextMenu.vala:53 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:234 +msgid "Run" +msgstr "" + +#: src/data/compat/WineWrap.vala:64 +msgid "Show WineWrap menu" +msgstr "" + +#: src/data/compat/WineWrap.vala:67 src/data/compat/Proton.vala:122 +#: src/data/compat/Wine.vala:83 +msgid "Kill apps in prefix" +msgstr "" + +#: src/data/compat/Proton.vala:47 +msgid "Proton prefix" +msgstr "" + +#: src/data/compat/Proton.vala:110 src/data/compat/Wine.vala:71 +msgid "Open prefix directory" +msgstr "" + +#: src/data/compat/Proton.vala:113 src/data/compat/Wine.vala:74 +msgid "Run winecfg" +msgstr "" + +#: src/data/compat/Proton.vala:116 src/data/compat/Wine.vala:77 +msgid "Run winetricks" +msgstr "" + +#: src/data/compat/Proton.vala:119 src/data/compat/Wine.vala:80 +msgid "Run taskmgr" +msgstr "" + +#: src/data/compat/Wine.vala:53 +msgid "Wine prefix" +msgstr "" + +#: src/data/compat/Wine.vala:55 +msgid "Environment variables" +msgstr "" + +#: src/data/compat/Wine.vala:60 +msgid "InnoSetup default options" +msgstr "" + +#: src/data/compat/RetroArch.vala:53 +msgid "Libretro core file" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:43 +msgid "Custom emulator" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:48 +msgid "Emulator" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:49 +msgid "Launch in game directory" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:440 +msgctxt "status_header" +msgid "Favorites" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:445 +#, c-format +msgctxt "status_header" +msgid "%s: Favorites" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:491 +msgid "Merging games" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:504 +#, c-format +msgid "Merging games from %s" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:551 +#, c-format +msgid "Loading games from %s" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:678 +msgctxt "sort_mode" +msgid "By name" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:679 +msgctxt "sort_mode" +msgid "By last launch" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:680 +msgctxt "sort_mode" +msgid "By playtime" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:705 +msgctxt "group_mode" +msgid "Do not group" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:706 +msgctxt "group_mode" +msgid "By status" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:707 +msgctxt "group_mode" +msgid "By source" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:151 +#: src/data/providers/data/IGDB.vala:431 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:217 +msgid "Default" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:158 +#: src/data/providers/data/IGDB.vala:438 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:225 +msgid "Restore default API key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:169 +#: src/data/providers/data/IGDB.vala:449 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:108 +msgid "API key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:177 +#: src/data/providers/data/IGDB.vala:457 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:53 +msgid "Generate key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:208 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Style" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:209 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Score" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:213 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Author" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:225 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Alternate" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:226 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Blurred" +msgstr "" + +#. TRANSLATORS: Flat / Material Design image style. Probably should not be translated +#: src/data/providers/images/SteamGridDB.vala:228 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Material" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:229 +msgctxt "imagesource_steamgriddb_image_style" +msgid "No logo" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:230 +msgctxt "imagesource_steamgriddb_image_style" +msgid "White logo" +msgstr "" + +#: src/data/providers/data/IGDB.vala:147 +msgid "" +"Monthly IGDB request quota has been reached. Set your own API key to use " +"IGDB data or disable IGDB." +msgstr "" + +#: src/data/providers/data/IGDB.vala:148 +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:40 +#: src/ui/views/WelcomeView.vala:53 src/ui/views/WelcomeView.vala:78 +#: src/ui/views/GamesView/GamesView.vala:230 +#: src/ui/views/GamesView/GamesView.vala:629 +msgid "Settings" +msgstr "" + +#: src/data/providers/data/IGDB.vala:356 +msgctxt "igdb_related_link" +msgid "Official website" +msgstr "" + +#: src/data/providers/data/IGDB.vala:469 +msgctxt "igdb_preferred_description" +msgid "When game has description, show description" +msgstr "" + +#: src/data/providers/data/IGDB.vala:476 +msgctxt "igdb_preferred_description" +msgid "of game" +msgstr "" + +#: src/data/providers/data/IGDB.vala:477 +msgctxt "igdb_preferred_description" +msgid "from IGDB" +msgstr "" + +#: src/data/providers/data/IGDB.vala:478 +msgctxt "igdb_preferred_description" +msgid "both" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:65 +msgid "Some settings will be applied after application restart" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:71 +msgid "Games directory contains space. It may cause problems for some games" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:36 +msgid "Interface" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:37 +msgid "Appearance" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:38 +msgid "General interface settings" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:48 +msgid "Dark theme" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:53 +msgctxt "icon_style" +msgid "Theme-based" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:54 +msgctxt "icon_style" +msgid "Symbolic" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:55 +msgctxt "icon_style" +msgid "Colored" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:57 +msgctxt "icon_style" +msgid "Icon style" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:84 +msgid "Game card" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:86 +msgid "Show platform icons" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:99 +msgctxt "grid_size" +msgid "Card size" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:117 +msgctxt "grid_size_preset" +msgid "Presets" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:139 +msgid "Games list: installed" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:140 +msgid "Games list: not installed" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:142 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:146 +msgctxt "list_style" +msgid "Show icon" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:143 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:147 +msgctxt "list_style" +msgid "Bold title" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:144 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:148 +msgctxt "list_style" +msgid "Show status" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:149 +msgctxt "list_style" +msgid "Dim" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:151 +msgid "Grid options" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:152 +msgid "List options" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:31 +msgid "Behavior" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:32 +msgid "Behavior settings" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:42 +msgid "Run games with double click" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:46 +msgid "Merge games from different sources" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:50 +msgid "Use imported tags" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:51 +msgid "General" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:52 +msgid "Collection" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:53 +msgid "Empty" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:65 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:85 +msgid "Collection directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:70 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:78 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:87 +msgid "Game directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:71 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:79 +msgid "Installers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:72 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:98 +msgid "DLC" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:73 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:197 +msgid "Bonus content" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:84 +msgid "Variable syntax: $var or ${var}" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:86 +msgid "Game name" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:88 +#: src/ui/views/GamesView/FiltersPopover.vala:127 +msgid "Platform" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:36 +msgid "Controller" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +msgid "Enabled" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:53 +msgid "Focus GameHub window with Guide button" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:57 +msgid "Controllers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:89 +msgid "Move focus" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:91 +msgid "Exit" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:40 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:108 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:92 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:95 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:36 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:77 +msgid "Disabled" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:47 +#: src/ui/dialogs/GameTweaksDialog.vala:53 +#: src/ui/views/GamesView/GameContextMenu.vala:183 +msgid "Tweaks" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:34 +msgid "Tweak launch options and apply them to games automatically" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:79 +msgid "" +"Tweaks are loaded from following directories in order\n" +"Last tweak overrides previous tweaks with same identifiers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:83 +msgid "Click to open" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:93 +#, c-format +msgid "Tweaks are loaded from %1$s and %2$d more directories (?)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:38 +msgid "Game sources" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +msgid "Steam API keys have limited number of uses per day" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:63 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:57 +msgid "Installation directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:176 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:81 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:34 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:75 +msgid "Not installed" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:116 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:96 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:99 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:85 +msgid "Not authenticated" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +#, c-format +msgid "Authenticated as %s" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:103 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +msgid "Authenticated" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:183 +#: src/ui/dialogs/InstallDialog.vala:53 src/ui/dialogs/InstallDialog.vala:111 +#: src/ui/views/GamesView/GameContextMenu.vala:80 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:233 +#: src/ui/widgets/TweaksList.vala:95 +msgid "Install" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:236 +msgid "Steam API key" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:50 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:54 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:48 +msgid "Games directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:63 +msgid "Logout" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:50 +msgid "Load games from Humble Trove" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:45 +msgid "Emulators" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:45 +msgid "Libretro core directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:46 +msgid "Libretro core info directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:50 +msgid "Ignored libretro cores" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:54 +msgid "Ignored game file extensions" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:66 +msgid "No cores found" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:70 +#, c-format +msgid "%u core found" +msgid_plural "%u cores found" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:46 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:168 +msgid "No custom emulators" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:164 +#, c-format +msgid "%u custom emulator" +msgid_plural "%u custom emulators" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:237 +msgid "Save" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:250 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:312 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/dialogs/GamePropertiesDialog.vala:168 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +#: src/ui/views/GamesView/AddGamePopover.vala:67 +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Executable" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:251 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/views/GamesView/AddGamePopover.vala:68 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Installer" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:256 +#: src/ui/dialogs/GamePropertiesDialog.vala:64 +#: src/ui/dialogs/GamePropertiesDialog.vala:69 +#: src/ui/views/GamesView/AddGamePopover.vala:73 +msgid "Name" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:272 +#: src/ui/dialogs/GamePropertiesDialog.vala:201 +#: src/ui/views/GamesView/AddGamePopover.vala:78 +msgid "Arguments" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:276 +msgid "Variables" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:277 +msgid "Game executable" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:278 +msgid "Game arguments" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:80 +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +msgid "Select emulator directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:292 +#: src/ui/dialogs/GamePropertiesDialog.vala:219 +msgid "Force compatibility mode" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:307 +msgid "Game file patterns" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:315 +msgid "Image" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:318 +msgid "Icon" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:325 +msgid "" +"findutils-compatible glob patterns\n" +"\n" +" Multiple patterns can be separated with |\n" +" Start pattern with ./ to match relative path\n" +" $basename variable will be replaced with game's executable " +"name (without extension)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:38 +msgid "Data" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:39 +msgid "Providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:40 +msgid "Third-party data providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:55 +msgid "Image providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:68 +msgid "Metadata providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:137 +msgid "Open website" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:36 +msgid "About" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:71 +msgid "Copy application version and environment info" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:78 +#: src/ui/views/WelcomeView.vala:57 +msgid "All your games in one place" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:92 +msgctxt "about_link" +msgid "Website" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:96 +msgctxt "about_link" +msgid "Source code on GitHub" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:103 +msgctxt "about_link" +msgid "Report a problem" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:104 +msgctxt "about_link" +msgid "Suggest translations" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:110 +msgctxt "about_link" +msgid "Issues" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:111 +msgctxt "about_link" +msgid "Contributors" +msgstr "" + +#. TRANSLATORS: Likely it should not be translated. GitHub Pulse is a page that shows recent repository activity: https://github.com/tkashkin/GameHub/pulse +#: src/ui/dialogs/SettingsDialog/pages/About.vala:114 +msgctxt "about_link" +msgid "Pulse" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:115 +msgctxt "about_link" +msgid "Forks" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:109 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:129 +msgid "Import" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:110 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:153 +msgid "Download" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:207 +msgid "Select installer" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:216 +#, c-format +msgid "Installer size: %s" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:348 +msgid "Unknown" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:49 +#, c-format +msgid "%s: Properties" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:84 +msgid "Images" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:126 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:160 +#: src/ui/views/GameDetailsView/blocks/Artwork.vala:62 +msgid "Download images" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:144 +msgid "Image URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:148 +msgid "Vertical image URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:157 +msgid "Icon URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Select working directory" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Working directory" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:214 +msgid "Compatibility" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:236 +msgid "Launch from terminal" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:252 +msgid "Copy to clipboard" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:254 +msgid "Add to Steam" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:255 +msgid "Add to the Steam library" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:53 +#, c-format +msgid "%s: Overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "Overlays are disabled" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "" +"Enable overlays to manage DLCs and mods\n" +"\n" +"Enabling will move game to the “base“ overlay" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:77 +#: src/ui/views/GamesView/GameContextMenu.vala:175 +msgid "Overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:105 +msgid "Overlay ID (directory name)" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:110 +msgid "Overlay name (optional)" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:112 +msgid "Add" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:127 +msgid "Enable overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:182 +#, c-format +msgid "" +"Overlay usage at this path may be unsafe\n" +"Proceed at your own risk\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:187 +#, c-format +msgid "" +"Overlay usage at this path is not supported\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:266 +msgid "Open directory" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:271 +msgid "Remove overlay" +msgstr "" + +#: src/ui/dialogs/CompatRunDialog.vala:48 +#: src/ui/views/GamesView/GameContextMenu.vala:46 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:235 +msgid "Run with compatibility layer" +msgstr "" + +#: src/ui/dialogs/CorruptedInstallerDialog.vala:71 +msgid "Corrupted installer: checksum mismatch in" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:57 +#: src/ui/views/GamesView/AddGamePopover.vala:105 +msgid "Import emulated games" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:75 +msgid "Select directory with emulated games" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:83 +msgid "Detected games" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:107 +msgid "Select all" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:115 +msgid "Select directory to import" +msgstr "" + +#: src/ui/dialogs/GameTweaksDialog.vala:40 +#, c-format +msgid "%s: Tweaks" +msgstr "" + +#: src/ui/views/WelcomeView.vala:52 +msgid "No enabled game sources" +msgstr "" + +#: src/ui/views/WelcomeView.vala:52 +msgid "Enable some game sources in settings" +msgstr "" + +#: src/ui/views/WelcomeView.vala:57 +msgid "Let's get started" +msgstr "" + +#: src/ui/views/WelcomeView.vala:71 +msgid "Skip" +msgstr "" + +#: src/ui/views/WelcomeView.vala:141 +msgid "Ready" +msgstr "" + +#: src/ui/views/WelcomeView.vala:147 +msgid "Authentication required" +msgstr "" + +#: src/ui/views/WelcomeView.vala:152 +msgid "Authenticating…" +msgstr "" + +#: src/ui/views/WelcomeView.vala:163 +#, c-format +msgid "Install %s" +msgstr "" + +#: src/ui/views/WelcomeView.vala:164 +msgid "Return to GameHub after installing" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "No games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "Get some games or enable some game sources in settings" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:150 +msgid "Grid view" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:151 +msgid "List view" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:159 +msgid "All games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:182 +msgid "Downloads" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:208 +msgid "Filters" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:216 +#: src/ui/views/GamesView/AddGamePopover.vala:84 +msgid "Add game" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:223 +msgid "Search" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:328 +msgid "Menu" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:329 +#: src/ui/views/GameDetailsView/GameDetailsView.vala:104 +msgid "Back" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:550 +#, c-format +msgid "%u game" +msgid_plural "%u games" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GamesView/GamesView.vala:553 +#, c-format +msgctxt "games_view_subtitle_filtered_games" +msgid "%1$u / %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:557 +#, c-format +msgctxt "games_view_subtitle" +msgid "%1$s: %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:568 +msgid "No user-added games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:569 +msgid "Add some games using plus button" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:573 +#, c-format +msgid "No %s games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:574 +msgid "Get some Linux-compatible games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:584 +#, c-format +msgid "No games matching “%s”" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:589 +#, c-format +msgid "No %1$s games matching “%2$s”" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:627 +msgid "" +"No games were loaded from Steam. Set your games list privacy to public or " +"use your own Steam API key in settings." +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:628 +msgid "Privacy" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:739 +msgid "Downloading images" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:753 +#, c-format +msgid "Downloading image: %s" +msgstr "" + +#: src/ui/views/GamesView/DownloadProgressView.vala:131 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:162 +msgid "Pause download" +msgstr "" + +#: src/ui/views/GamesView/DownloadProgressView.vala:137 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:168 +msgid "Resume download" +msgstr "" + +#: src/ui/views/GamesView/DownloadProgressView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:174 +msgid "Cancel download" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:77 +msgid "Group" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:102 +msgid "Sort" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:234 +#: src/ui/widgets/GameTagsList.vala:58 +msgid "Tags" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:353 +msgid "All platforms" +msgstr "" + +#: src/ui/views/GamesView/AddGamePopover.vala:77 +msgid "Select game executable" +msgstr "" + +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Select game directory" +msgstr "" + +#: src/ui/views/GamesView/AddGamePopover.vala:111 +msgid "Download game images" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:87 +msgid "Details" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:117 +msgctxt "game_context_menu" +msgid "Favorite" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:121 +msgctxt "game_context_menu" +msgid "Hidden" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:133 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:236 +msgid "Open installation directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:142 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:237 +msgid "Open installers collection directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:151 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:238 +msgid "Open bonus collection directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:160 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:239 +msgid "Open screenshots directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +msgid "Uninstall" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:192 +msgid "Properties" +msgstr "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:100 +#, c-format +msgid "%d game selected" +msgid_plural "%d games selected" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:144 +#, c-format +msgid "%d game will be installed" +msgid_plural "%d games will be installed" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:154 +#, c-format +msgid "%d game will be downloaded" +msgid_plural "%d games will be downloaded" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:161 +#, c-format +msgid "Image for %d game will be searched" +msgid_plural "Images for %d games will be searched" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:168 +#, c-format +msgid "%d game will be uninstalled" +msgid_plural "%d games will be uninstalled" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:174 +msgid "Refresh" +msgstr "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:175 +#, c-format +msgid "" +"%d game will be removed from database. Restart GameHub to fetch new data" +msgid_plural "" +"%d games will be removed from database. Restart GameHub to fetch new data" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:240 +msgid "Open store page" +msgstr "" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:242 +msgid "Game properties" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:46 +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:60 +msgid "Playtime" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:52 +msgid "Playtime (local)" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:69 +msgid "Last launch" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:46 +msgid "Achievements" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:85 +#, c-format +msgid "Unlocked: %s" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:90 +#, c-format +msgid "Global percentage: %g%%" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:77 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:103 +msgid "Language" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:80 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:106 +msgid "Languages" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:147 +#, c-format +msgid "%u DLCs cannot be installed" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:71 +msgid "Category" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:74 +msgid "Categories" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:90 +msgid "Genre" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:93 +msgid "Genres" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:109 +msgctxt "igdb" +msgid "Popularity" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:115 +msgctxt "igdb" +msgid "Aggregated rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:116 +msgctxt "igdb" +msgid "IGDB user rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:117 +msgctxt "igdb" +msgid "Total rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:126 +msgctxt "igdb" +msgid "Release date" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:133 +msgctxt "igdb" +msgid "Platforms" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:139 +msgctxt "igdb" +msgid "Genres" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:145 +msgctxt "igdb" +msgid "Keywords" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:152 +msgctxt "igdb" +msgid "Links" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:208 +#, c-format +msgid "Based on %d rating" +msgid_plural "Based on %d ratings" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:290 +msgctxt "igdb" +msgid "Summary" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:301 +msgctxt "igdb" +msgid "Storyline" +msgstr "" + +#: src/ui/widgets/FileChooserEntry.vala:49 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select file" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "No images" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "" +"There are no images found for this game\n" +"Make sure game name is correct" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:94 +msgid "Search images:" +msgstr "" + +#: src/ui/widgets/CompatToolPicker.vala:53 +msgid "Compatibility layer:" +msgstr "" + +#: src/ui/widgets/CompatToolPicker.vala:92 +msgid "Configure" +msgstr "" + +#: src/ui/widgets/GameTagsList.vala:109 +msgid "Add tag" +msgstr "" + +#: src/ui/widgets/TweaksList.vala:86 +msgid "No description" +msgstr "" + +#: src/ui/widgets/TweaksList.vala:124 +msgid "Edit file" +msgstr "" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dh" +msgstr "" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dm" +msgstr "" + +#: src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%ds" +msgstr "" + +#: src/settings/UI.vala:153 +msgctxt "grid_size_preset" +msgid "Steam" +msgstr "" + +#: src/settings/UI.vala:154 +msgctxt "grid_size_preset" +msgid "Steam (vertical)" +msgstr "" + +#: src/settings/UI.vala:155 +msgctxt "grid_size_preset" +msgid "GOG" +msgstr "" + +#: src/settings/UI.vala:156 +msgctxt "grid_size_preset" +msgid "GOG (vertical)" +msgstr "" + +#: src/settings/UI.vala:157 +msgctxt "grid_size_preset" +msgid "Square" +msgstr "" + +#: src/settings/UI.vala:158 +msgctxt "grid_size_preset" +msgid "Custom" +msgstr "" + +#: src/utils/downloader/Downloader.vala:200 +msgctxt "dl_status" +msgid "Queued" +msgstr "" + +#: src/utils/downloader/Downloader.vala:201 +msgctxt "dl_status" +msgid "Starting download" +msgstr "" + +#: src/utils/downloader/Downloader.vala:202 +msgctxt "dl_status" +msgid "Download started" +msgstr "" + +#: src/utils/downloader/Downloader.vala:203 +msgctxt "dl_status" +msgid "Download finished" +msgstr "" + +#: src/utils/downloader/Downloader.vala:204 +msgctxt "dl_status" +msgid "Download failed" +msgstr "" + +#: src/utils/downloader/Downloader.vala:208 +#, c-format +msgctxt "dl_status" +msgid "Downloading: %s" +msgstr "" + +#: src/utils/downloader/Downloader.vala:210 +msgctxt "dl_status" +msgid "Downloading" +msgstr "" + +#: src/utils/downloader/Downloader.vala:214 +#, c-format +msgctxt "dl_status" +msgid "Paused: %s" +msgstr "" + +#: src/utils/downloader/Downloader.vala:216 +msgctxt "dl_status" +msgid "Paused" +msgstr "" + +#: src/utils/downloader/Downloader.vala:218 +msgctxt "dl_status" +msgid "Download cancelled" +msgstr "" + +#. TRANSLATORS: Download progress template. %1$d - percentage, %2$s / %3$s - downloaded portion and total file size, %4$s - download speed +#: src/utils/downloader/Downloader.vala:262 +#, c-format +msgctxt "dl_status" +msgid "%1$d%% (%2$s / %3$s) [%4$s/s]" +msgstr "" diff --git a/po/nb_NO.po b/po/nb_NO.po new file mode 100644 index 00000000..c099b7b1 --- /dev/null +++ b/po/nb_NO.po @@ -0,0 +1,1927 @@ +# Norwegian Bokmal translations for com.github.tkashkin.gamehub package. +# Copyright (C) 2018 THE com.github.tkashkin.gamehub'S COPYRIGHT HOLDER +# This file is distributed under the same license as the com.github.tkashkin.gamehub package. +# Automatically generated, 2018. +# Anatoliy Kashkin , 2018, 2019. +# Allan Nordhøy , 2018, 2019, 2020. +msgid "" +msgstr "" +"Project-Id-Version: com.github.tkashkin.gamehub\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-26 06:40+0300\n" +"PO-Revision-Date: 2020-02-01 07:50+0000\n" +"Last-Translator: Allan Nordhøy \n" +"Language-Team: Norwegian Bokmål \n" +"Language: nb_NO\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 3.11-dev\n" + +#: src/app.vala:91 +msgid "Show help" +msgstr "Vis hjelp" + +#: src/app.vala:92 +msgid "Show application version and exit" +msgstr "Vis programversjon og avslutt" + +#: src/app.vala:93 +msgid "Restart with GDB debugger attached" +msgstr "Start på nytt med GDB-feilsporer tilknyttet" + +#: src/app.vala:94 +msgid "Show full GDB backtrace" +msgstr "Vis full GDB-tilbakesporing" + +#: src/app.vala:95 +msgid "Treat fatal errors as criticals and crash application" +msgstr "Behandle fatale feil som kritiske og kræsj programmet" + +#: src/app.vala:99 +msgid "Show main window" +msgstr "Vis hovedvindu" + +#: src/app.vala:100 +msgid "Show application settings dialog" +msgstr "Vis programinnstillingsdialogvindu" + +#: src/app.vala:101 +msgid "Show about dialog" +msgstr "Vis \"Om\"-dialogvindu" + +#: src/app.vala:102 +msgid "Maximum number of background worker threads" +msgstr "Maksimalt antall bakgrunnsarbeidertråder" + +#: src/app.vala:106 +msgid "Run game" +msgstr "Kjør spill" + +#: src/app.vala:107 +msgid "Show compatibility options dialog" +msgstr "Vis valg for kompabilitetsmodus" + +#: src/app.vala:108 +msgid "Open game details" +msgstr "Åpne spilldetaljer" + +#: src/app.vala:109 +msgid "Open game properties" +msgstr "Åpne spillegenskaper" + +#: src/app.vala:113 +msgid "Enable debug logging" +msgstr "Skru på feilrettingslogging" + +#: src/app.vala:114 +msgid "" +"Log authentication process and sensitive information like authentication " +"tokens" +msgstr "" +"Loggfør identitetsbekreftelsesprosess og sensitiv info som " +"identitetsbekreftelsessymboler" + +#: src/app.vala:115 +msgid "Log download manager" +msgstr "Loggfør nedlastingsbehandler" + +#: src/app.vala:116 +msgid "Log background workers start/stop" +msgstr "Loggfør oppstart/stopp av bakgrunnsarbeidere" + +#: src/app.vala:117 +msgid "Disable log messages filtering" +msgstr "Skru av loggmeldingsfiltrering" + +#: src/app.vala:118 +msgid "Verbose logging" +msgstr "Detaljrik loggføring" + +#: src/app.vala:247 +msgid "Game Options:" +msgstr "Spillegenskaper:" + +#: src/app.vala:247 +msgid "Show game options help" +msgstr "Vis spillvalghjelp" + +#: src/app.vala:255 +msgid "Logging Options:" +msgstr "Loggføringsvalg:" + +#: src/app.vala:255 +msgid "Show logging options help" +msgstr "Vis hjelp for loggføringsvalg" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +msgid "Select executable" +msgstr "Velg kjørbar fil" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:181 src/ui/views/GamesView/GamesView.vala:330 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select" +msgstr "Velg" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:180 src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Cancel" +msgstr "Avbryt" + +#: src/data/Runnable.vala:166 src/ui/widgets/FileChooserEntry.vala:49 +msgid "Select directory" +msgstr "Velg mappe" + +#: src/data/Runnable.vala:619 +#, c-format +msgid "Part %1$u of %2$u: %3$s" +msgstr "Del %1$u av %2$u: %3$s" + +#: src/data/Runnable.vala:642 src/ui/dialogs/CorruptedInstallerDialog.vala:48 +#, c-format +msgid "%s: corrupted installer" +msgstr "%s: Skadet installasjonskandidat" + +#: src/data/Runnable.vala:643 +#, c-format +msgid "Checksum mismatch in %s" +msgstr "Sjekksum stemmer ikke overens i %s" + +#: src/data/Runnable.vala:657 src/ui/dialogs/CorruptedInstallerDialog.vala:126 +msgid "Show file" +msgstr "Vis fil" + +#: src/data/Runnable.vala:658 src/ui/dialogs/CorruptedInstallerDialog.vala:132 +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#: src/ui/widgets/TagRow.vala:146 +msgid "Remove" +msgstr "Fjern" + +#: src/data/Runnable.vala:659 src/ui/dialogs/CorruptedInstallerDialog.vala:128 +msgid "Backup" +msgstr "Sikkerhetskopi" + +#: src/data/Runnable.vala:778 +#, c-format +msgid "%s: cannot detect main executable" +msgstr "%s: Kan ikke fastslå hoved-kjørbar fil" + +#: src/data/Runnable.vala:779 +msgid "" +"Main executable file for this game cannot be detected automatically.\n" +"Please set main executable in game's properties." +msgstr "" +"Kan ikke oppdage primær kjørbar fil for dette spillet automatisk.\n" +"Sett den i spillets egenskaper." + +#: src/data/Runnable.vala:908 +msgctxt "platform" +msgid "Emulated" +msgstr "Emulerte" + +#: src/data/Game.vala:625 +msgctxt "status" +msgid "Running" +msgstr "Kjører" + +#: src/data/Game.vala:628 +msgctxt "status" +msgid "Installed" +msgstr "Installert" + +#: src/data/Game.vala:629 +msgctxt "status" +msgid "Installing" +msgstr "Installerer" + +#: src/data/Game.vala:630 +msgctxt "status" +msgid "Verifying installer integrity" +msgstr "Bekrefter installasjonskandidatfila" + +#: src/data/Game.vala:631 +msgctxt "status" +msgid "Download started" +msgstr "Nedlasting startet" + +#: src/data/Game.vala:633 +msgctxt "status" +msgid "Not installed" +msgstr "Ikke installert" + +#: src/data/Game.vala:643 +msgctxt "status_header" +msgid "Installed" +msgstr "Installert" + +#: src/data/Game.vala:644 +msgctxt "status_header" +msgid "Installing" +msgstr "Installerer" + +#: src/data/Game.vala:646 +msgctxt "status_header" +msgid "Downloading" +msgstr "Laster ned" + +#: src/data/Game.vala:648 +msgctxt "status_header" +msgid "Not installed" +msgstr "Ikke installert" + +#: src/data/GameSource.vala:31 +#, c-format +msgid "%s games" +msgstr "%s spill" + +#: src/data/sources/steam/Steam.vala:43 +msgid "Your SteamID will be read from Steam configuration file" +msgstr "Din SteamID vil bli lest fra Steam-oppsettsfilen" + +#: src/data/sources/steam/Steam.vala:46 +msgid "" +"Steam config file not found.\n" +"Login into your account in Steam client and return to GameHub" +msgstr "" +"Fant ikke Steamoppsettsfilen.\n" +"Logg inn på din konto i Steamklienten og kom tilbake til GameHub" + +#: src/data/sources/gog/GOGGame.vala:983 +#, c-format, fuzzy +msgid "DLC: %s" +msgstr "DLC: %s" + +#: src/data/sources/humble/HumbleGame.vala:343 +#, c-format +msgid "%s: no available installers" +msgstr "%s: Ingen tilgjengelige installasjonskandidater" + +#: src/data/sources/humble/HumbleGame.vala:344 +msgid "" +"Cannot get Trove download URL.\n" +"Make sure your Humble Monthly subscription is active." +msgstr "" +"Kan ikke hente nedlastingsnettadresse for Trove.\n" +"Forsikre deg om at ditt månedlige Humble-abonnement er aktivt." + +#: src/data/sources/itch/ItchDownloader.vala:192 +#, fuzzy, c-format +msgctxt "itch_dl_status" +msgid "%s left;" +msgstr "%s igjen;" + +#: src/data/sources/itch/ItchDownloader.vala:195 +#, c-format +msgctxt "itch_dl_status" +msgid "%d%%" +msgstr "%d%%" + +#: src/data/sources/itch/ItchDownloader.vala:198 +#, c-format +msgctxt "itch_dl_status" +msgid "(%1$s / %2$s)" +msgstr "(%1$s / %2$s)" + +#: src/data/sources/itch/ItchDownloader.vala:201 +#, c-format +msgctxt "itch_dl_status" +msgid "[%s/s]" +msgstr "[%s/s]" + +#: src/data/sources/user/User.vala:30 +msgid "User games" +msgstr "Brukerspill" + +#: src/data/db/tables/Tags.vala:225 +msgctxt "tag" +msgid "Favorites" +msgstr "Favoritter" + +#: src/data/db/tables/Tags.vala:226 +msgctxt "tag" +msgid "Not installed" +msgstr "Ikke installert" + +#: src/data/db/tables/Tags.vala:227 +msgctxt "tag" +msgid "Installed" +msgstr "Installert" + +#: src/data/db/tables/Tags.vala:228 +msgctxt "tag" +msgid "Hidden" +msgstr "Skjult" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit script" +msgstr "Rediger skript" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit custom script" +msgstr "Rediger egendefinert skript" + +#: src/data/compat/Innoextract.vala:55 +#, c-format +msgid "" +"Innoextract %1$s is not supported and may not be able to extract some " +"games correctly.\n" +"Install innoextract %2$s or newer." +msgstr "" +"Innoextract %1$s støttes ikke, og det kan hende noen spill ikke vil " +"kunne pakkes ut rett.\n" +"Installer innoextract %2$s eller nyere." + +#: src/data/compat/WineWrap.vala:61 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:242 +#: src/ui/dialogs/CompatRunDialog.vala:102 +#: src/ui/views/GamesView/GameContextMenu.vala:53 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:234 +msgid "Run" +msgstr "Kjør" + +#: src/data/compat/WineWrap.vala:64 +msgid "Show WineWrap menu" +msgstr "Vis WineWrap-meny" + +#: src/data/compat/WineWrap.vala:67 src/data/compat/Proton.vala:122 +#: src/data/compat/Wine.vala:83 +msgid "Kill apps in prefix" +msgstr "Drep programmer i prefiks" + +#: src/data/compat/Proton.vala:47 +msgid "Proton prefix" +msgstr "Proton-prefiks" + +#: src/data/compat/Proton.vala:110 src/data/compat/Wine.vala:71 +msgid "Open prefix directory" +msgstr "Åpne prefiks-mappe" + +#: src/data/compat/Proton.vala:113 src/data/compat/Wine.vala:74 +msgid "Run winecfg" +msgstr "Kjør winecfg" + +#: src/data/compat/Proton.vala:116 src/data/compat/Wine.vala:77 +msgid "Run winetricks" +msgstr "Kjør winetricks" + +#: src/data/compat/Proton.vala:119 src/data/compat/Wine.vala:80 +msgid "Run taskmgr" +msgstr "Kjør taskmgr" + +#: src/data/compat/Wine.vala:53 +msgid "Wine prefix" +msgstr "Wine-prefiks" + +#: src/data/compat/Wine.vala:55 +msgid "Environment variables" +msgstr "Miljøvariabler" + +#: src/data/compat/Wine.vala:60 +msgid "InnoSetup default options" +msgstr "Forvalgte valg for InnoSetup" + +#: src/data/compat/RetroArch.vala:53 +msgid "Libretro core file" +msgstr "Libretro-kjernefil" + +#: src/data/compat/CustomEmulator.vala:43 +msgid "Custom emulator" +msgstr "Egendefinert emulator" + +#: src/data/compat/CustomEmulator.vala:48 +msgid "Emulator" +msgstr "Emulator" + +#: src/data/compat/CustomEmulator.vala:49 +msgid "Launch in game directory" +msgstr "Kjør i spillmappe" + +#: src/data/adapters/GamesAdapter.vala:440 +msgctxt "status_header" +msgid "Favorites" +msgstr "Favoritter" + +#: src/data/adapters/GamesAdapter.vala:445 +#, c-format +msgctxt "status_header" +msgid "%s: Favorites" +msgstr "%s: Favoritter" + +#: src/data/adapters/GamesAdapter.vala:491 +msgid "Merging games" +msgstr "Fletter spill" + +#: src/data/adapters/GamesAdapter.vala:504 +#, c-format +msgid "Merging games from %s" +msgstr "Fletter spill fra %s" + +#: src/data/adapters/GamesAdapter.vala:551 +#, c-format +msgid "Loading games from %s" +msgstr "Laster spill fra %s" + +#: src/data/adapters/GamesAdapter.vala:678 +msgctxt "sort_mode" +msgid "By name" +msgstr "Etter navn" + +#: src/data/adapters/GamesAdapter.vala:679 +msgctxt "sort_mode" +msgid "By last launch" +msgstr "Etter siste kjøring" + +#: src/data/adapters/GamesAdapter.vala:680 +msgctxt "sort_mode" +msgid "By playtime" +msgstr "Etter spilltid" + +#: src/data/adapters/GamesAdapter.vala:705 +msgctxt "group_mode" +msgid "Do not group" +msgstr "Ikke grupper" + +#: src/data/adapters/GamesAdapter.vala:706 +msgctxt "group_mode" +msgid "By status" +msgstr "Etter status" + +#: src/data/adapters/GamesAdapter.vala:707 +msgctxt "group_mode" +msgid "By source" +msgstr "Etter kilde" + +#: src/data/providers/images/SteamGridDB.vala:151 +#: src/data/providers/data/IGDB.vala:431 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:217 +msgid "Default" +msgstr "Forvalg" + +#: src/data/providers/images/SteamGridDB.vala:158 +#: src/data/providers/data/IGDB.vala:438 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:225 +msgid "Restore default API key" +msgstr "Gjenopprett forvalgt API-nøkkel" + +#: src/data/providers/images/SteamGridDB.vala:169 +#: src/data/providers/data/IGDB.vala:449 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:108 +msgid "API key" +msgstr "API-nøkkel" + +#: src/data/providers/images/SteamGridDB.vala:177 +#: src/data/providers/data/IGDB.vala:457 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:53 +msgid "Generate key" +msgstr "Generer nøkkel" + +#: src/data/providers/images/SteamGridDB.vala:208 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Style" +msgstr "Stil" + +#: src/data/providers/images/SteamGridDB.vala:209 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Score" +msgstr "Poengsum" + +#: src/data/providers/images/SteamGridDB.vala:213 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Author" +msgstr "Utvikler" + +#: src/data/providers/images/SteamGridDB.vala:225 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Alternate" +msgstr "Alternativt" + +#: src/data/providers/images/SteamGridDB.vala:226 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Blurred" +msgstr "Sløret" + +#. TRANSLATORS: Flat / Material Design image style. Probably should not be translated +#: src/data/providers/images/SteamGridDB.vala:228 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Material" +msgstr "Materielt" + +#: src/data/providers/images/SteamGridDB.vala:229 +msgctxt "imagesource_steamgriddb_image_style" +msgid "No logo" +msgstr "Ingen logo" + +#: src/data/providers/images/SteamGridDB.vala:230 +msgctxt "imagesource_steamgriddb_image_style" +msgid "White logo" +msgstr "Hvit logo" + +#: src/data/providers/data/IGDB.vala:147 +msgid "" +"Monthly IGDB request quota has been reached. Set your own API key to use " +"IGDB data or disable IGDB." +msgstr "" +"Månedlig IGDB-forespørselskvote oppbrukt. Benytt din egen API-nøkkel for å " +"bruke IGDB-data, eller skru av IGDB." + +#: src/data/providers/data/IGDB.vala:148 +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:40 +#: src/ui/views/WelcomeView.vala:53 src/ui/views/WelcomeView.vala:78 +#: src/ui/views/GamesView/GamesView.vala:230 +#: src/ui/views/GamesView/GamesView.vala:629 +msgid "Settings" +msgstr "Innstillinger" + +#: src/data/providers/data/IGDB.vala:356 +msgctxt "igdb_related_link" +msgid "Official website" +msgstr "Offisiell nettside" + +#: src/data/providers/data/IGDB.vala:469 +msgctxt "igdb_preferred_description" +msgid "When game has description, show description" +msgstr "Vis beskrivelse når spillet har det" + +#: src/data/providers/data/IGDB.vala:476 +msgctxt "igdb_preferred_description" +msgid "of game" +msgstr "av spill" + +#: src/data/providers/data/IGDB.vala:477 +msgctxt "igdb_preferred_description" +msgid "from IGDB" +msgstr "fra IGDB" + +#: src/data/providers/data/IGDB.vala:478 +msgctxt "igdb_preferred_description" +msgid "both" +msgstr "begge" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:65 +msgid "Some settings will be applied after application restart" +msgstr "Noen innstillinger vil tre i kraft etter omstart av programmet" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:71 +msgid "Games directory contains space. It may cause problems for some games" +msgstr "" +"Spillmappe inneholder mellomrom. Det kan forårsake problemer for noen spill" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:36 +msgid "Interface" +msgstr "Grensesnitt" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:37 +msgid "Appearance" +msgstr "Utseende" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:38 +msgid "General interface settings" +msgstr "Generelle grensesnittsinnstillinger" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:48 +msgid "Dark theme" +msgstr "Mørk drakt" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:53 +msgctxt "icon_style" +msgid "Theme-based" +msgstr "Drakt-basert" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:54 +msgctxt "icon_style" +msgid "Symbolic" +msgstr "Symbolske" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:55 +msgctxt "icon_style" +msgid "Colored" +msgstr "Farget" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:57 +msgctxt "icon_style" +msgid "Icon style" +msgstr "Ikonstil" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:84 +#, fuzzy +msgid "Game card" +msgstr "Spillnavn" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:86 +#, fuzzy +msgid "Show platform icons" +msgstr "Vis plattformsikoner i rutenettvisning" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:99 +msgctxt "grid_size" +msgid "Card size" +msgstr "Kortstørrelse" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:117 +msgctxt "grid_size_preset" +msgid "Presets" +msgstr "Forhåndsinnstillinger" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:139 +#, fuzzy +msgid "Games list: installed" +msgstr "Spilliste: Installert" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:140 +#, fuzzy +msgid "Games list: not installed" +msgstr "Spilliste: Ikke installert" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:142 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:146 +msgctxt "list_style" +msgid "Show icon" +msgstr "Vis ikon" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:143 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:147 +msgctxt "list_style" +msgid "Bold title" +msgstr "Fet tittel" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:144 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:148 +msgctxt "list_style" +msgid "Show status" +msgstr "Vis status" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:149 +msgctxt "list_style" +msgid "Dim" +msgstr "Demp" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:151 +#, fuzzy +msgid "Grid options" +msgstr "Spillegenskaper:" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:152 +#, fuzzy +msgid "List options" +msgstr "Loggføringsvalg:" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:31 +msgid "Behavior" +msgstr "Oppførsel" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:32 +msgid "Behavior settings" +msgstr "Oppførselsinnstillinger" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:42 +msgid "Run games with double click" +msgstr "Start spill med dobbeltklikk" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:46 +msgid "Merge games from different sources" +msgstr "Flett spill fra forskjellige kilder" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:50 +msgid "Use imported tags" +msgstr "Bruk importerte etiketter" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:51 +msgid "General" +msgstr "Generelt" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:52 +msgid "Collection" +msgstr "Samling" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:53 +msgid "Empty" +msgstr "Tom" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:65 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:85 +msgid "Collection directory" +msgstr "Samlingsmappe" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:70 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:78 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:87 +msgid "Game directory" +msgstr "Spillmappe" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:71 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:79 +msgid "Installers" +msgstr "Installasjonskandidater" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:72 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:98 +msgid "DLC" +msgstr "Nedlastbart innhold" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:73 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:197 +msgid "Bonus content" +msgstr "Bonusinnhold" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:84 +msgid "Variable syntax: $var or ${var}" +msgstr "Variabel syntaks: $var eller ${var}" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:86 +msgid "Game name" +msgstr "Spillnavn" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:88 +#: src/ui/views/GamesView/FiltersPopover.vala:127 +msgid "Platform" +msgstr "Plattform" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:36 +msgid "Controller" +msgstr "Kontroller" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +msgid "Enabled" +msgstr "Påskrudd" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:53 +msgid "Focus GameHub window with Guide button" +msgstr "Fokuser GameHub-vinduet med Guide-knappen" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:57 +msgid "Controllers" +msgstr "Kontrollere" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:89 +msgid "Move focus" +msgstr "Flytt fokus" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:91 +msgid "Exit" +msgstr "Avslutt" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:40 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:108 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:92 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:95 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:36 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:77 +msgid "Disabled" +msgstr "Avskrudd" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:47 +#: src/ui/dialogs/GameTweaksDialog.vala:53 +#: src/ui/views/GamesView/GameContextMenu.vala:183 +msgid "Tweaks" +msgstr "Tilpasninger" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:34 +msgid "Tweak launch options and apply them to games automatically" +msgstr "Tilpass oppstartsvalg og utfør dem for spill automatisk" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:79 +#, fuzzy +msgid "" +"Tweaks are loaded from following directories in order\n" +"Last tweak overrides previous tweaks with same identifiers" +msgstr "" +"Tilpasninger lastes inn fra følgende mapper i rekkefølge\n" +"Siste tilpasning overskriver forrige tilpasning med samme identifikatorer" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:83 +msgid "Click to open" +msgstr "Klikk for å åpne" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:93 +#, c-format +msgid "Tweaks are loaded from %1$s and %2$d more directories (?)" +msgstr "" +"Tilpasninger lastes inn fra %1$s og %2$d flere mapper (?)" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:38 +msgid "Game sources" +msgstr "Spillkilder" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +msgid "Steam API keys have limited number of uses per day" +msgstr "API-nøkler fra Steam kan brukes kun et par ganger om dagen" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:63 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:57 +msgid "Installation directory" +msgstr "Installasjonsmappe" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:176 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:81 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:34 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:75 +msgid "Not installed" +msgstr "Ikke installert" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:116 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:96 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:99 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:85 +msgid "Not authenticated" +msgstr "Identitetsbekreftelse kreves" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +#, c-format +msgid "Authenticated as %s" +msgstr "Identitetsbekreftet som %s" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:103 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +msgid "Authenticated" +msgstr "Identitetsbekreftet" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:183 +#: src/ui/dialogs/InstallDialog.vala:53 src/ui/dialogs/InstallDialog.vala:111 +#: src/ui/views/GamesView/GameContextMenu.vala:80 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:233 +#: src/ui/widgets/TweaksList.vala:95 +msgid "Install" +msgstr "Installer" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:236 +msgid "Steam API key" +msgstr "API-nøkkel fra Steam" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:50 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:54 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:48 +msgid "Games directory" +msgstr "Spillmappe" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:63 +msgid "Logout" +msgstr "Logg ut" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:50 +msgid "Load games from Humble Trove" +msgstr "Last inn spill fra Humble-skattekisten" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:45 +msgid "Emulators" +msgstr "Emulatorer" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:45 +msgid "Libretro core directory" +msgstr "Libretro-kjernemappe" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:46 +msgid "Libretro core info directory" +msgstr "Libretro-kjerneinfomappe" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:50 +msgid "Ignored libretro cores" +msgstr "Ignorerte libretro-kjerner" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:54 +msgid "Ignored game file extensions" +msgstr "Ignorerte spillfilendelser" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:66 +msgid "No cores found" +msgstr "Fant ingen kjerner" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:70 +#, c-format +msgid "%u core found" +msgid_plural "%u cores found" +msgstr[0] "Fant én kjerne" +msgstr[1] "Fant %u kjerner" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:46 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:168 +msgid "No custom emulators" +msgstr "Ingen egendefinerte emulatorer" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:164 +#, c-format +msgid "%u custom emulator" +msgid_plural "%u custom emulators" +msgstr[0] "én egendefinert emulator" +msgstr[1] "%u egendefinerte emulatorer" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:237 +msgid "Save" +msgstr "Lagre" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:250 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:312 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/dialogs/GamePropertiesDialog.vala:168 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +#: src/ui/views/GamesView/AddGamePopover.vala:67 +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Executable" +msgstr "Kjørbar fil" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:251 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/views/GamesView/AddGamePopover.vala:68 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Installer" +msgstr "Installasjonskandidat" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:256 +#: src/ui/dialogs/GamePropertiesDialog.vala:64 +#: src/ui/dialogs/GamePropertiesDialog.vala:69 +#: src/ui/views/GamesView/AddGamePopover.vala:73 +msgid "Name" +msgstr "Navn" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:272 +#: src/ui/dialogs/GamePropertiesDialog.vala:201 +#: src/ui/views/GamesView/AddGamePopover.vala:78 +msgid "Arguments" +msgstr "Argumenter" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:276 +msgid "Variables" +msgstr "Variabler" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:277 +msgid "Game executable" +msgstr "Kjørbar spillfil" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:278 +msgid "Game arguments" +msgstr "Spillargumenter" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:80 +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Directory" +msgstr "Mappe" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +msgid "Select emulator directory" +msgstr "Velg emulatormappe" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:292 +#: src/ui/dialogs/GamePropertiesDialog.vala:219 +msgid "Force compatibility mode" +msgstr "Tving gjennom kompabilitetsmodus" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:307 +msgid "Game file patterns" +msgstr "Spillfilmønster" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:315 +msgid "Image" +msgstr "Bilde" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:318 +msgid "Icon" +msgstr "Ikon" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:325 +msgid "" +"findutils-compatible glob patterns\n" +"\n" +" Multiple patterns can be separated with |\n" +" Start pattern with ./ to match relative path\n" +" $basename variable will be replaced with game's executable " +"name (without extension)" +msgstr "" +"findutils-kompatible glob-mønster\n" +"\n" +" Flerfoldige mønster kan inndeles med |\n" +" Start mønsteret med ./ for å jamføre med relativ sti\n" +" $basename-variabel erstattes av navnet på spillets kjørbare " +"fil (uten filendelse)" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:38 +msgid "Data" +msgstr "Data" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:39 +msgid "Providers" +msgstr "Tilbydere" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:40 +msgid "Third-party data providers" +msgstr "Tredjeparts datatilbydere" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:55 +msgid "Image providers" +msgstr "Bildetilbydere" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:68 +msgid "Metadata providers" +msgstr "Metadatatilbydere" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:137 +msgid "Open website" +msgstr "Åpne nettside" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:36 +msgid "About" +msgstr "Om" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:71 +msgid "Copy application version and environment info" +msgstr "Vis programversjon og miljøinformasjon" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:78 +#: src/ui/views/WelcomeView.vala:57 +msgid "All your games in one place" +msgstr "Alle dine spill på ett sted" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:92 +msgctxt "about_link" +msgid "Website" +msgstr "Nettside" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:96 +msgctxt "about_link" +msgid "Source code on GitHub" +msgstr "Kildekode på GitHub" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:103 +msgctxt "about_link" +msgid "Report a problem" +msgstr "Innrapporter et problem" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:104 +msgctxt "about_link" +msgid "Suggest translations" +msgstr "Foreslå oversettelser" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:110 +msgctxt "about_link" +msgid "Issues" +msgstr "Problemer" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:111 +msgctxt "about_link" +msgid "Contributors" +msgstr "Bidragsytere" + +#. TRANSLATORS: Likely it should not be translated. GitHub Pulse is a page that shows recent repository activity: https://github.com/tkashkin/GameHub/pulse +#: src/ui/dialogs/SettingsDialog/pages/About.vala:114 +msgctxt "about_link" +msgid "Pulse" +msgstr "Puls" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:115 +msgctxt "about_link" +msgid "Forks" +msgstr "Forgreninger" + +#: src/ui/dialogs/InstallDialog.vala:109 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:129 +msgid "Import" +msgstr "Importer" + +#: src/ui/dialogs/InstallDialog.vala:110 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:153 +msgid "Download" +msgstr "Last ned" + +#: src/ui/dialogs/InstallDialog.vala:207 +msgid "Select installer" +msgstr "Velg installasjonskandidat" + +#: src/ui/dialogs/InstallDialog.vala:216 +#, c-format +msgid "Installer size: %s" +msgstr "Installasjonsstørrelse: %s" + +#: src/ui/dialogs/InstallDialog.vala:348 +msgid "Unknown" +msgstr "Ukjent" + +#: src/ui/dialogs/GamePropertiesDialog.vala:49 +#, c-format +msgid "%s: Properties" +msgstr "%s: Egenskaper" + +#: src/ui/dialogs/GamePropertiesDialog.vala:84 +msgid "Images" +msgstr "Bilder" + +#: src/ui/dialogs/GamePropertiesDialog.vala:126 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:160 +#: src/ui/views/GameDetailsView/blocks/Artwork.vala:62 +msgid "Download images" +msgstr "Last ned bilder" + +#: src/ui/dialogs/GamePropertiesDialog.vala:144 +msgid "Image URL" +msgstr "Bildenettadresse" + +#: src/ui/dialogs/GamePropertiesDialog.vala:148 +msgid "Vertical image URL" +msgstr "Nettadresse til loddrett bilde" + +#: src/ui/dialogs/GamePropertiesDialog.vala:157 +msgid "Icon URL" +msgstr "Ikonnettadresse" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +#, fuzzy +msgid "Select working directory" +msgstr "Velg mappe" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +#, fuzzy +msgid "Working directory" +msgstr "Åpne mappe" + +#: src/ui/dialogs/GamePropertiesDialog.vala:214 +msgid "Compatibility" +msgstr "Kompabilitet" + +#: src/ui/dialogs/GamePropertiesDialog.vala:236 +msgid "Launch from terminal" +msgstr "Kjør fra terminal" + +#: src/ui/dialogs/GamePropertiesDialog.vala:252 +msgid "Copy to clipboard" +msgstr "Kopier til utklippstavle" + +#: src/ui/dialogs/GamePropertiesDialog.vala:254 +msgid "Add to Steam" +msgstr "Legg til på Steam" + +#: src/ui/dialogs/GamePropertiesDialog.vala:255 +msgid "Add to the Steam library" +msgstr "Legg til i Steam-bibliotek" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:53 +#, c-format +msgid "%s: Overlays" +msgstr "%s: Overlag" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "Overlays are disabled" +msgstr "Overlag er avskrudd" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "" +"Enable overlays to manage DLCs and mods\n" +"\n" +"Enabling will move game to the “base“ overlay" +msgstr "" +"Skru på overlegg for å behandle nedlastbart innhold og mod-er\n" +"\n" +"Å skru dette på vil flytte spillet til \"base\"-overlegget" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:77 +#: src/ui/views/GamesView/GameContextMenu.vala:175 +msgid "Overlays" +msgstr "Overlag" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:105 +msgid "Overlay ID (directory name)" +msgstr "Overlags-ID (mappenavn)" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:110 +msgid "Overlay name (optional)" +msgstr "Overlagsnavn (valgfritt)" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:112 +msgid "Add" +msgstr "Legg til" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:127 +msgid "Enable overlays" +msgstr "Skru på overlag" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:182 +#, c-format +msgid "" +"Overlay usage at this path may be unsafe\n" +"Proceed at your own risk\n" +"\n" +"Path: %s" +msgstr "" +"Overlagsbruk i denne stien kan være utrygt\n" +"Fortsett på egen risiko\n" +"\n" +"Sti: %s" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:187 +#, c-format +msgid "" +"Overlay usage at this path is not supported\n" +"\n" +"Path: %s" +msgstr "" +"Overlagsbruk i denne stien støttes ikke\n" +"\n" +"Sti: %s" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:266 +msgid "Open directory" +msgstr "Åpne mappe" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:271 +msgid "Remove overlay" +msgstr "Fjern overlag" + +#: src/ui/dialogs/CompatRunDialog.vala:48 +#: src/ui/views/GamesView/GameContextMenu.vala:46 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:235 +msgid "Run with compatibility layer" +msgstr "Kjør med kompabilitetslag" + +#: src/ui/dialogs/CorruptedInstallerDialog.vala:71 +msgid "Corrupted installer: checksum mismatch in" +msgstr "Skadet installasjonskandidat: sjekksum stemmer ikke overens i" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:57 +#: src/ui/views/GamesView/AddGamePopover.vala:105 +msgid "Import emulated games" +msgstr "Importer emulerte spill" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:75 +msgid "Select directory with emulated games" +msgstr "Velg mappe inneholdende emulerte spill" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:83 +msgid "Detected games" +msgstr "Oppdagede spill" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:107 +msgid "Select all" +msgstr "Velg alt" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:115 +msgid "Select directory to import" +msgstr "Velg mappe å importere" + +#: src/ui/dialogs/GameTweaksDialog.vala:40 +#, fuzzy, c-format +msgid "%s: Tweaks" +msgstr "%s: Overlag" + +#: src/ui/views/WelcomeView.vala:52 +msgid "No enabled game sources" +msgstr "Ingen påskrudde spillkilder" + +#: src/ui/views/WelcomeView.vala:52 +msgid "Enable some game sources in settings" +msgstr "Skru på noen spillkilder i innstillingene" + +#: src/ui/views/WelcomeView.vala:57 +msgid "Let's get started" +msgstr "La oss komme igang" + +#: src/ui/views/WelcomeView.vala:71 +msgid "Skip" +msgstr "Hopp over" + +#: src/ui/views/WelcomeView.vala:141 +msgid "Ready" +msgstr "Klar" + +#: src/ui/views/WelcomeView.vala:147 +msgid "Authentication required" +msgstr "Identitetsbekreftelse kreves" + +#: src/ui/views/WelcomeView.vala:152 +#, fuzzy +msgid "Authenticating…" +msgstr "Identitetsbekrefter…" + +#: src/ui/views/WelcomeView.vala:163 +#, c-format +msgid "Install %s" +msgstr "Installer %s" + +#: src/ui/views/WelcomeView.vala:164 +msgid "Return to GameHub after installing" +msgstr "Gå tilbake til GameHub etter installasjon" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "No games" +msgstr "Ingen spill" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "Get some games or enable some game sources in settings" +msgstr "Hent noen spill eller skru på noen spillkilder i innstillingene" + +#: src/ui/views/GamesView/GamesView.vala:150 +msgid "Grid view" +msgstr "Rutenettvisning" + +#: src/ui/views/GamesView/GamesView.vala:151 +msgid "List view" +msgstr "Listevisning" + +#: src/ui/views/GamesView/GamesView.vala:159 +msgid "All games" +msgstr "Alle spill" + +#: src/ui/views/GamesView/GamesView.vala:182 +msgid "Downloads" +msgstr "Nedlastinger" + +#: src/ui/views/GamesView/GamesView.vala:208 +msgid "Filters" +msgstr "Filtre" + +#: src/ui/views/GamesView/GamesView.vala:216 +#: src/ui/views/GamesView/AddGamePopover.vala:84 +msgid "Add game" +msgstr "Legg til spill" + +#: src/ui/views/GamesView/GamesView.vala:223 +msgid "Search" +msgstr "Søk" + +#: src/ui/views/GamesView/GamesView.vala:328 +msgid "Menu" +msgstr "Meny" + +#: src/ui/views/GamesView/GamesView.vala:329 +#: src/ui/views/GameDetailsView/GameDetailsView.vala:104 +msgid "Back" +msgstr "Tilbake" + +#: src/ui/views/GamesView/GamesView.vala:550 +#, c-format +msgid "%u game" +msgid_plural "%u games" +msgstr[0] "%u spill" +msgstr[1] "%u spill" + +#: src/ui/views/GamesView/GamesView.vala:553 +#, fuzzy, c-format +msgctxt "games_view_subtitle_filtered_games" +msgid "%1$u / %2$s" +msgstr "(%1$s / %2$s)" + +#: src/ui/views/GamesView/GamesView.vala:557 +#, fuzzy, c-format +msgctxt "games_view_subtitle" +msgid "%1$s: %2$s" +msgstr "(%1$s / %2$s)" + +#: src/ui/views/GamesView/GamesView.vala:568 +msgid "No user-added games" +msgstr "Ingen brukertillagte spill" + +#: src/ui/views/GamesView/GamesView.vala:569 +msgid "Add some games using plus button" +msgstr "Legg till noen spill med pluss-knappen" + +#: src/ui/views/GamesView/GamesView.vala:573 +#, c-format +msgid "No %s games" +msgstr "Ingen %s-spill" + +#: src/ui/views/GamesView/GamesView.vala:574 +msgid "Get some Linux-compatible games" +msgstr "Hent noen Linux-kompatible spill" + +#: src/ui/views/GamesView/GamesView.vala:584 +#, c-format +msgid "No games matching “%s”" +msgstr "Ingen spill samsvarer med \"%s\"" + +#: src/ui/views/GamesView/GamesView.vala:589 +#, c-format +msgid "No %1$s games matching “%2$s”" +msgstr "Ingen %1$s-spill samsvarer med \"%2$s\"" + +#: src/ui/views/GamesView/GamesView.vala:627 +msgid "" +"No games were loaded from Steam. Set your games list privacy to public or " +"use your own Steam API key in settings." +msgstr "" +"Ingen spill ble innlastet fra Steam. Sett ditt spilllistepersonvern til " +"\"offentlig\" for å bruke din egen Steam-API-nøkkel i innstillingene." + +#: src/ui/views/GamesView/GamesView.vala:628 +msgid "Privacy" +msgstr "Personvern" + +#: src/ui/views/GamesView/GamesView.vala:739 +msgid "Downloading images" +msgstr "Laster ned bilder" + +#: src/ui/views/GamesView/GamesView.vala:753 +#, c-format +msgid "Downloading image: %s" +msgstr "Laster ned bilde: %s" + +#: src/ui/views/GamesView/DownloadProgressView.vala:131 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:162 +msgid "Pause download" +msgstr "Pause nedlasting" + +#: src/ui/views/GamesView/DownloadProgressView.vala:137 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:168 +msgid "Resume download" +msgstr "Fortsett nedlasting" + +#: src/ui/views/GamesView/DownloadProgressView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:174 +msgid "Cancel download" +msgstr "Avbryt nedlasting" + +#: src/ui/views/GamesView/FiltersPopover.vala:77 +msgid "Group" +msgstr "Gruppe" + +#: src/ui/views/GamesView/FiltersPopover.vala:102 +msgid "Sort" +msgstr "Sorter" + +#: src/ui/views/GamesView/FiltersPopover.vala:234 +#: src/ui/widgets/GameTagsList.vala:58 +msgid "Tags" +msgstr "Etiketter" + +#: src/ui/views/GamesView/FiltersPopover.vala:353 +msgid "All platforms" +msgstr "Alle plattformer" + +#: src/ui/views/GamesView/AddGamePopover.vala:77 +msgid "Select game executable" +msgstr "Velg kjørbar spillfil" + +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Select game directory" +msgstr "Velg spillmappe" + +#: src/ui/views/GamesView/AddGamePopover.vala:111 +msgid "Download game images" +msgstr "Last ned spillbilder" + +#: src/ui/views/GamesView/GameContextMenu.vala:87 +msgid "Details" +msgstr "Detaljer" + +#: src/ui/views/GamesView/GameContextMenu.vala:117 +msgctxt "game_context_menu" +msgid "Favorite" +msgstr "Favoritt" + +#: src/ui/views/GamesView/GameContextMenu.vala:121 +msgctxt "game_context_menu" +msgid "Hidden" +msgstr "Skjult" + +#: src/ui/views/GamesView/GameContextMenu.vala:133 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:236 +msgid "Open installation directory" +msgstr "Åpne installasjonsmappe" + +#: src/ui/views/GamesView/GameContextMenu.vala:142 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:237 +msgid "Open installers collection directory" +msgstr "Åpne installasjonskandidatssamlingsmappe" + +#: src/ui/views/GamesView/GameContextMenu.vala:151 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:238 +msgid "Open bonus collection directory" +msgstr "Åpne bonussamlingsmappe" + +#: src/ui/views/GamesView/GameContextMenu.vala:160 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:239 +msgid "Open screenshots directory" +msgstr "Åpne skjermavbildningsmappe" + +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +msgid "Uninstall" +msgstr "Avinstaller" + +#: src/ui/views/GamesView/GameContextMenu.vala:192 +msgid "Properties" +msgstr "Egenskaper" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:100 +#, c-format +msgid "%d game selected" +msgid_plural "%d games selected" +msgstr[0] "%d spill valgt" +msgstr[1] "%d spill valgt" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:144 +#, c-format +msgid "%d game will be installed" +msgid_plural "%d games will be installed" +msgstr[0] "%d spill vil bli installert" +msgstr[1] "%d spill vil bli installert" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:154 +#, c-format +msgid "%d game will be downloaded" +msgid_plural "%d games will be downloaded" +msgstr[0] "%d spill vil bli lastet ned" +msgstr[1] "%d spill vil bli lastet ned" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:161 +#, c-format +msgid "Image for %d game will be searched" +msgid_plural "Images for %d games will be searched" +msgstr[0] "Vil søke etter bilde for %d spill" +msgstr[1] "Vil søke etter bilde for %d spill" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:168 +#, c-format +msgid "%d game will be uninstalled" +msgid_plural "%d games will be uninstalled" +msgstr[0] "%d spill vil bli avinstallert" +msgstr[1] "%d spill vil bli avinstallert" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:174 +msgid "Refresh" +msgstr "Gjenoppfrisk" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:175 +#, c-format +msgid "" +"%d game will be removed from database. Restart GameHub to fetch new data" +msgid_plural "" +"%d games will be removed from database. Restart GameHub to fetch new data" +msgstr[0] "" +"%d spill vil bli fjernet fra databasen. Start GameHub på ny for å hente ny " +"data" +msgstr[1] "" +"%d spill vil bli fjernet fra databasen. Start GameHub på ny for å hente ny " +"data" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:240 +msgid "Open store page" +msgstr "Åpne butikkside" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:242 +msgid "Game properties" +msgstr "Spillegenskaper" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:46 +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:60 +msgid "Playtime" +msgstr "Spilltid" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:52 +msgid "Playtime (local)" +msgstr "Spilltid (lokal)" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:69 +msgid "Last launch" +msgstr "Sist kjørt" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:46 +msgid "Achievements" +msgstr "Prestasjoner" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:85 +#, c-format +msgid "Unlocked: %s" +msgstr "Opplåst: %s" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:90 +#, c-format +msgid "Global percentage: %g%%" +msgstr "Global prosentsats: %g%%" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:77 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:103 +msgid "Language" +msgstr "Språk" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:80 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:106 +msgid "Languages" +msgstr "Språk" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:147 +#, fuzzy, c-format +msgid "%u DLCs cannot be installed" +msgstr "%s: Skadet installasjonskandidat" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:71 +msgid "Category" +msgstr "Kategori" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:74 +msgid "Categories" +msgstr "Kategorier" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:90 +msgid "Genre" +msgstr "Sjanger" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:93 +msgid "Genres" +msgstr "Sjangre" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:109 +msgctxt "igdb" +msgid "Popularity" +msgstr "Popularitet" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:115 +msgctxt "igdb" +msgid "Aggregated rating" +msgstr "Samlet vurdering" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:116 +msgctxt "igdb" +msgid "IGDB user rating" +msgstr "IGDB-brukervurdering" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:117 +msgctxt "igdb" +msgid "Total rating" +msgstr "Totalvurdering" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:126 +msgctxt "igdb" +msgid "Release date" +msgstr "Utgivelsesdato" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:133 +msgctxt "igdb" +msgid "Platforms" +msgstr "Plattformer" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:139 +msgctxt "igdb" +msgid "Genres" +msgstr "Sjangere" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:145 +msgctxt "igdb" +msgid "Keywords" +msgstr "Nøkkelord" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:152 +msgctxt "igdb" +msgid "Links" +msgstr "Lenker" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:208 +#, c-format +msgid "Based on %d rating" +msgid_plural "Based on %d ratings" +msgstr[0] "Basert på én vurdering" +msgstr[1] "Basert på %d vurderinger" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:290 +msgctxt "igdb" +msgid "Summary" +msgstr "Sammendrag" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:301 +msgctxt "igdb" +msgid "Storyline" +msgstr "Handling" + +#: src/ui/widgets/FileChooserEntry.vala:49 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select file" +msgstr "Velg fil" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "No images" +msgstr "Ingen bilder" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "" +"There are no images found for this game\n" +"Make sure game name is correct" +msgstr "" +"Fant ikke noen bilder for dette spillet\n" +"Forsikre deg om at spillnavnet er riktig" + +#: src/ui/widgets/ImagesDownloadPopover.vala:94 +msgid "Search images:" +msgstr "Søk etter bilder:" + +#: src/ui/widgets/CompatToolPicker.vala:53 +msgid "Compatibility layer:" +msgstr "Kompabilitetslag:" + +#: src/ui/widgets/CompatToolPicker.vala:92 +msgid "Configure" +msgstr "Sett opp" + +#: src/ui/widgets/GameTagsList.vala:109 +msgid "Add tag" +msgstr "Legg til etikett" + +#: src/ui/widgets/TweaksList.vala:86 +#, fuzzy +msgid "No description" +msgstr "Beskrivelse" + +#: src/ui/widgets/TweaksList.vala:124 +#, fuzzy +msgid "Edit file" +msgstr "Velg fil" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dh" +msgstr "%dt" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dm" +msgstr "%dm" + +#: src/utils/Utils.vala:464 +#, fuzzy, c-format +msgctxt "time" +msgid "%ds" +msgstr "%dt" + +#: src/settings/UI.vala:153 +msgctxt "grid_size_preset" +msgid "Steam" +msgstr "Steam" + +#: src/settings/UI.vala:154 +msgctxt "grid_size_preset" +msgid "Steam (vertical)" +msgstr "Steam (vertikalt)" + +#: src/settings/UI.vala:155 +msgctxt "grid_size_preset" +msgid "GOG" +msgstr "GOG" + +#: src/settings/UI.vala:156 +msgctxt "grid_size_preset" +msgid "GOG (vertical)" +msgstr "GOG (vertikalt)" + +#: src/settings/UI.vala:157 +msgctxt "grid_size_preset" +msgid "Square" +msgstr "Firkantig" + +#: src/settings/UI.vala:158 +msgctxt "grid_size_preset" +msgid "Custom" +msgstr "Egendefinert" + +#: src/utils/downloader/Downloader.vala:200 +msgctxt "dl_status" +msgid "Queued" +msgstr "I kø" + +#: src/utils/downloader/Downloader.vala:201 +msgctxt "dl_status" +msgid "Starting download" +msgstr "Starter nedlasting" + +#: src/utils/downloader/Downloader.vala:202 +msgctxt "dl_status" +msgid "Download started" +msgstr "Nedlasting startet" + +#: src/utils/downloader/Downloader.vala:203 +msgctxt "dl_status" +msgid "Download finished" +msgstr "Nedlasting fullført" + +#: src/utils/downloader/Downloader.vala:204 +msgctxt "dl_status" +msgid "Download failed" +msgstr "Nedlasting mislyktes" + +#: src/utils/downloader/Downloader.vala:208 +#, fuzzy, c-format +msgctxt "dl_status" +msgid "Downloading: %s" +msgstr "Laster ned" + +#: src/utils/downloader/Downloader.vala:210 +#, fuzzy +msgctxt "dl_status" +msgid "Downloading" +msgstr "Laster ned" + +#: src/utils/downloader/Downloader.vala:214 +#, fuzzy, c-format +msgctxt "dl_status" +msgid "Paused: %s" +msgstr "Pauset: %d%% (%s / %s)" + +#: src/utils/downloader/Downloader.vala:216 +#, fuzzy +msgctxt "dl_status" +msgid "Paused" +msgstr "Pause nedlasting" + +#: src/utils/downloader/Downloader.vala:218 +msgctxt "dl_status" +msgid "Download cancelled" +msgstr "Nedlasting avbrutt" + +#. TRANSLATORS: Download progress template. %1$d - percentage, %2$s / %3$s - downloaded portion and total file size, %4$s - download speed +#: src/utils/downloader/Downloader.vala:262 +#, fuzzy, c-format +msgctxt "dl_status" +msgid "%1$d%% (%2$s / %3$s) [%4$s/s]" +msgstr "Laster ned: %d%% (%s / %s) [%s/s]" + +#~ msgid "Disable esync" +#~ msgstr "Skru av esync" + +#~ msgid "Force LARGE_ADDRESS_AWARE flag" +#~ msgstr "Påtving LARGE_ADDRESS_AWARE-flagg" + +#~ msgid "Disable DirectX 11 compatibility layer" +#~ msgstr "Skru av DirextX 11-kompabilitetslag" + +#~ msgid "Use WineD3D11 as DirectX 11 compatibility layer" +#~ msgstr "Bruk WineD3D11 som DirectX 11-kompabilitetslag" + +#~ msgid "Show DXVK info overlay" +#~ msgstr "Vis DXVK-infooverlag" + +#, fuzzy +#~ msgid "Enable DirectX 9 compatibility layer" +#~ msgstr "Skru av DirextX 11-kompabilitetslag" + +#~ msgid "Silent installation" +#~ msgstr "Stille installasjon" + +#~ msgid "Very silent installation" +#~ msgstr "Veldig stille installasjon" + +#~ msgid "Suppress messages" +#~ msgstr "Undertrykk meldinger" + +#~ msgid "No GUI" +#~ msgstr "Inget grensesnitt" + +#~ msgctxt "igdb" +#~ msgid "%s on IGDB" +#~ msgstr "%s på IGDB" + +#~ msgid "Disable fullscreen" +#~ msgstr "Skru av fullskjermsvisning" + +#~ msgid "Windowed" +#~ msgstr "Vindusvisning" + +#~ msgid "Compact list" +#~ msgstr "Kompakt liste" + +#~ msgid "Show non-native games" +#~ msgstr "Vis spill som ikke er lokale for plattformen" + +#~ msgid "Use compatibility layers and consider Windows games compatible" +#~ msgstr "Bruk kompabilitetslag og anse Windows-spill som kompatible" + +#~ msgid "About GameHub" +#~ msgstr "Om GameHub" + +#~ msgid "Use symbolic icons instead of colored icons" +#~ msgstr "Bruk symbolske ikoner istedenfor fargede ikoner" + +#~ msgid "Enable controller support" +#~ msgstr "Skru på kontrollerstøtte" + +#~ msgid "Reload" +#~ msgstr "Gjeninnlast" + +#~ msgid "Updating game info" +#~ msgstr "Oppdaterer spillinfo" + +#~ msgid "Updating %s game info" +#~ msgstr "Oppdaterer %s spillinfo" + +#~ msgid "Merging %s (%s)" +#~ msgstr "Fletter %s (%s)" diff --git a/po/nl.po b/po/nl.po new file mode 100644 index 00000000..040d1ab3 --- /dev/null +++ b/po/nl.po @@ -0,0 +1,1917 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the com.github.tkashkin.gamehub package. +# Heimen Stoffels , 2018, 2019, 2020. +# Anatoliy Kashkin , 2018, 2019. +msgid "" +msgstr "" +"Project-Id-Version: com.github.tkashkin.gamehub\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-26 06:40+0300\n" +"PO-Revision-Date: 2020-01-27 13:21+0000\n" +"Last-Translator: Heimen Stoffels \n" +"Language-Team: Dutch \n" +"Language: nl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 3.11-dev\n" + +#: src/app.vala:91 +msgid "Show help" +msgstr "Hulp tonen" + +#: src/app.vala:92 +msgid "Show application version and exit" +msgstr "Applicatieversie tonen en afsluiten" + +#: src/app.vala:93 +msgid "Restart with GDB debugger attached" +msgstr "Herstarten met GDB-foutopsporing" + +#: src/app.vala:94 +msgid "Show full GDB backtrace" +msgstr "Volledige GDB-backtrace tonen" + +#: src/app.vala:95 +msgid "Treat fatal errors as criticals and crash application" +msgstr "Fatale fouten opvatten als kritiek en app laten crashen" + +#: src/app.vala:99 +msgid "Show main window" +msgstr "Hoofdvenster tonen" + +#: src/app.vala:100 +msgid "Show application settings dialog" +msgstr "Applicatie-instellingen tonen" + +#: src/app.vala:101 +msgid "Show about dialog" +msgstr "Over-venster tonen" + +#: src/app.vala:102 +msgid "Maximum number of background worker threads" +msgstr "Maximum aantal achtergrondprocessen" + +#: src/app.vala:106 +msgid "Run game" +msgstr "Spel starten" + +#: src/app.vala:107 +msgid "Show compatibility options dialog" +msgstr "Comptabiliteitsmodus-opties tonen" + +#: src/app.vala:108 +msgid "Open game details" +msgstr "Spelgegevens openen" + +#: src/app.vala:109 +msgid "Open game properties" +msgstr "Speleigenschappen openen" + +#: src/app.vala:113 +msgid "Enable debug logging" +msgstr "Foutopsporingslogs inschakelen" + +#: src/app.vala:114 +msgid "" +"Log authentication process and sensitive information like authentication " +"tokens" +msgstr "" +"Authenticatieproces en gevoelige informatie, zoals authenticatiesleutels, " +"vastleggen in logbestand" + +#: src/app.vala:115 +msgid "Log download manager" +msgstr "Downloadbeheer vastleggen in logbestand" + +#: src/app.vala:116 +msgid "Log background workers start/stop" +msgstr "Achtergronddiensten van loggen starten/stoppen" + +#: src/app.vala:117 +msgid "Disable log messages filtering" +msgstr "Logberichtfiltering uitschakelen" + +#: src/app.vala:118 +msgid "Verbose logging" +msgstr "Uitgebreid loggen" + +#: src/app.vala:247 +msgid "Game Options:" +msgstr "Spelopties:" + +#: src/app.vala:247 +msgid "Show game options help" +msgstr "Hulp bij opties van spel tonen" + +#: src/app.vala:255 +msgid "Logging Options:" +msgstr "Opties voor loggen:" + +#: src/app.vala:255 +msgid "Show logging options help" +msgstr "Hulp bij opties voor loggen tonen en afsluiten" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +msgid "Select executable" +msgstr "Kies uitvoerbaar bestand" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:181 src/ui/views/GamesView/GamesView.vala:330 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select" +msgstr "Kiezen" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:180 src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Cancel" +msgstr "Annuleren" + +#: src/data/Runnable.vala:166 src/ui/widgets/FileChooserEntry.vala:49 +msgid "Select directory" +msgstr "Kies map" + +#: src/data/Runnable.vala:619 +#, c-format +msgid "Part %1$u of %2$u: %3$s" +msgstr "Deel %1$u van %2$u: %3$s" + +#: src/data/Runnable.vala:642 src/ui/dialogs/CorruptedInstallerDialog.vala:48 +#, c-format +msgid "%s: corrupted installer" +msgstr "%s: kapot installatiebestand" + +#: src/data/Runnable.vala:643 +#, c-format +msgid "Checksum mismatch in %s" +msgstr "Controlesom komt niet overeen voor %s" + +#: src/data/Runnable.vala:657 src/ui/dialogs/CorruptedInstallerDialog.vala:126 +msgid "Show file" +msgstr "Bestand tonen" + +#: src/data/Runnable.vala:658 src/ui/dialogs/CorruptedInstallerDialog.vala:132 +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#: src/ui/widgets/TagRow.vala:146 +msgid "Remove" +msgstr "Verwijderen" + +#: src/data/Runnable.vala:659 src/ui/dialogs/CorruptedInstallerDialog.vala:128 +msgid "Backup" +msgstr "Back-up" + +#: src/data/Runnable.vala:778 +#, c-format +msgid "%s: cannot detect main executable" +msgstr "%s: kan uitvoerbaar bestand niet detecteren" + +#: src/data/Runnable.vala:779 +msgid "" +"Main executable file for this game cannot be detected automatically.\n" +"Please set main executable in game's properties." +msgstr "" +"Het algemene uitvoerbare bestand van dit spel kan niet automatisch worden " +"gedetecteerd.\n" +"Stel dit handmatig in in de speleigenschappen." + +#: src/data/Runnable.vala:908 +msgctxt "platform" +msgid "Emulated" +msgstr "Geëmuleerd" + +#: src/data/Game.vala:625 +msgctxt "status" +msgid "Running" +msgstr "Actief" + +#: src/data/Game.vala:628 +msgctxt "status" +msgid "Installed" +msgstr "Geïnstalleerd" + +#: src/data/Game.vala:629 +msgctxt "status" +msgid "Installing" +msgstr "Bezig met installeren" + +#: src/data/Game.vala:630 +msgctxt "status" +msgid "Verifying installer integrity" +msgstr "Bezig met verifiëren van integriteit" + +#: src/data/Game.vala:631 +msgctxt "status" +msgid "Download started" +msgstr "Downloaden gestart" + +#: src/data/Game.vala:633 +msgctxt "status" +msgid "Not installed" +msgstr "Niet-geïnstalleerd" + +#: src/data/Game.vala:643 +msgctxt "status_header" +msgid "Installed" +msgstr "Geïnstalleerd" + +#: src/data/Game.vala:644 +msgctxt "status_header" +msgid "Installing" +msgstr "Bezig met installeren" + +#: src/data/Game.vala:646 +msgctxt "status_header" +msgid "Downloading" +msgstr "Bezig met downloaden" + +#: src/data/Game.vala:648 +msgctxt "status_header" +msgid "Not installed" +msgstr "Niet geïnstalleerd" + +#: src/data/GameSource.vala:31 +#, c-format +msgid "%s games" +msgstr "%s spellen" + +#: src/data/sources/steam/Steam.vala:43 +msgid "Your SteamID will be read from Steam configuration file" +msgstr "Je SteamID wordt uitgelezen uit het Steam-configuratiebestand" + +#: src/data/sources/steam/Steam.vala:46 +msgid "" +"Steam config file not found.\n" +"Login into your account in Steam client and return to GameHub" +msgstr "" +"Steam-configuratiebestand niet aangetroffen.\n" +"Log in op je account in de Steam-client en keer terug naar GameHub" + +#: src/data/sources/gog/GOGGame.vala:983 +#, c-format +msgid "DLC: %s" +msgstr "DLC: %s" + +#: src/data/sources/humble/HumbleGame.vala:343 +#, c-format +msgid "%s: no available installers" +msgstr "%s: geen installatiebestanden beschikbaar" + +#: src/data/sources/humble/HumbleGame.vala:344 +msgid "" +"Cannot get Trove download URL.\n" +"Make sure your Humble Monthly subscription is active." +msgstr "" +"Kan de Trove-downloadurl niet opvragen.\n" +"Zorg ervoor dat je maandelijkse Humble-abonnement actief is." + +#: src/data/sources/itch/ItchDownloader.vala:192 +#, c-format +msgctxt "itch_dl_status" +msgid "%s left;" +msgstr "%s resterend;" + +#: src/data/sources/itch/ItchDownloader.vala:195 +#, c-format +msgctxt "itch_dl_status" +msgid "%d%%" +msgstr "%d%%" + +#: src/data/sources/itch/ItchDownloader.vala:198 +#, c-format +msgctxt "itch_dl_status" +msgid "(%1$s / %2$s)" +msgstr "(%1$s / %2$s)" + +#: src/data/sources/itch/ItchDownloader.vala:201 +#, c-format +msgctxt "itch_dl_status" +msgid "[%s/s]" +msgstr "[%s/s]" + +#: src/data/sources/user/User.vala:30 +msgid "User games" +msgstr "Gebruikersspellen" + +#: src/data/db/tables/Tags.vala:225 +msgctxt "tag" +msgid "Favorites" +msgstr "Favorieten" + +#: src/data/db/tables/Tags.vala:226 +msgctxt "tag" +msgid "Not installed" +msgstr "Niet-geïnstalleerd" + +#: src/data/db/tables/Tags.vala:227 +msgctxt "tag" +msgid "Installed" +msgstr "Geïnstalleerd" + +#: src/data/db/tables/Tags.vala:228 +msgctxt "tag" +msgid "Hidden" +msgstr "Verborgen" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit script" +msgstr "Script bewerken" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit custom script" +msgstr "Aangepast script bewerken" + +#: src/data/compat/Innoextract.vala:55 +#, c-format +msgid "" +"Innoextract %1$s is not supported and may not be able to extract some " +"games correctly.\n" +"Install innoextract %2$s or newer." +msgstr "" +"Innoextract %1$s wordt niet ondersteund en kan daardoor sommige " +"spellen mogelijk niet goed uitpakken.\n" +"Installeer innoextract %2$s of hoger." + +#: src/data/compat/WineWrap.vala:61 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:242 +#: src/ui/dialogs/CompatRunDialog.vala:102 +#: src/ui/views/GamesView/GameContextMenu.vala:53 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:234 +msgid "Run" +msgstr "Uitvoeren" + +#: src/data/compat/WineWrap.vala:64 +msgid "Show WineWrap menu" +msgstr "WineWrap-menu tonen" + +#: src/data/compat/WineWrap.vala:67 src/data/compat/Proton.vala:122 +#: src/data/compat/Wine.vala:83 +msgid "Kill apps in prefix" +msgstr "Wine-apps beëindigen" + +#: src/data/compat/Proton.vala:47 +msgid "Proton prefix" +msgstr "Proton-voorvoegsel" + +#: src/data/compat/Proton.vala:110 src/data/compat/Wine.vala:71 +msgid "Open prefix directory" +msgstr "Wine-profielmap openen" + +#: src/data/compat/Proton.vala:113 src/data/compat/Wine.vala:74 +msgid "Run winecfg" +msgstr "winecfg uitvoeren" + +#: src/data/compat/Proton.vala:116 src/data/compat/Wine.vala:77 +msgid "Run winetricks" +msgstr "winetricks uitvoeren" + +#: src/data/compat/Proton.vala:119 src/data/compat/Wine.vala:80 +msgid "Run taskmgr" +msgstr "Taakbeheer uitvoeren" + +#: src/data/compat/Wine.vala:53 +msgid "Wine prefix" +msgstr "Wine-voorvoegsel" + +#: src/data/compat/Wine.vala:55 +msgid "Environment variables" +msgstr "Omgevingsvariabelen" + +#: src/data/compat/Wine.vala:60 +msgid "InnoSetup default options" +msgstr "Standaardopties voor InnoSetup" + +#: src/data/compat/RetroArch.vala:53 +msgid "Libretro core file" +msgstr "Libretro-corebestand" + +#: src/data/compat/CustomEmulator.vala:43 +msgid "Custom emulator" +msgstr "Aangepaste emulator" + +#: src/data/compat/CustomEmulator.vala:48 +msgid "Emulator" +msgstr "Emulator" + +#: src/data/compat/CustomEmulator.vala:49 +msgid "Launch in game directory" +msgstr "Uitvoeren in spelmap" + +#: src/data/adapters/GamesAdapter.vala:440 +msgctxt "status_header" +msgid "Favorites" +msgstr "Favorieten" + +#: src/data/adapters/GamesAdapter.vala:445 +#, c-format +msgctxt "status_header" +msgid "%s: Favorites" +msgstr "%s: Favorieten" + +#: src/data/adapters/GamesAdapter.vala:491 +msgid "Merging games" +msgstr "Bezig met samenvoegen van spellen" + +#: src/data/adapters/GamesAdapter.vala:504 +#, c-format +msgid "Merging games from %s" +msgstr "Bezig met samenvoegen van spellen uit %s" + +#: src/data/adapters/GamesAdapter.vala:551 +#, c-format +msgid "Loading games from %s" +msgstr "Bezig met laden van spellen uit %s" + +#: src/data/adapters/GamesAdapter.vala:678 +msgctxt "sort_mode" +msgid "By name" +msgstr "Op naam" + +#: src/data/adapters/GamesAdapter.vala:679 +msgctxt "sort_mode" +msgid "By last launch" +msgstr "Op laatst opgestart" + +#: src/data/adapters/GamesAdapter.vala:680 +msgctxt "sort_mode" +msgid "By playtime" +msgstr "Op speeltijd" + +#: src/data/adapters/GamesAdapter.vala:705 +msgctxt "group_mode" +msgid "Do not group" +msgstr "Niet groeperen" + +#: src/data/adapters/GamesAdapter.vala:706 +msgctxt "group_mode" +msgid "By status" +msgstr "Op status" + +#: src/data/adapters/GamesAdapter.vala:707 +msgctxt "group_mode" +msgid "By source" +msgstr "Op bron" + +#: src/data/providers/images/SteamGridDB.vala:151 +#: src/data/providers/data/IGDB.vala:431 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:217 +msgid "Default" +msgstr "Standaard" + +#: src/data/providers/images/SteamGridDB.vala:158 +#: src/data/providers/data/IGDB.vala:438 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:225 +msgid "Restore default API key" +msgstr "Standaard API-sleutel herstellen" + +#: src/data/providers/images/SteamGridDB.vala:169 +#: src/data/providers/data/IGDB.vala:449 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:108 +msgid "API key" +msgstr "API-sleutel" + +#: src/data/providers/images/SteamGridDB.vala:177 +#: src/data/providers/data/IGDB.vala:457 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:53 +msgid "Generate key" +msgstr "Sleutel genereren" + +#: src/data/providers/images/SteamGridDB.vala:208 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Style" +msgstr "Stijl" + +#: src/data/providers/images/SteamGridDB.vala:209 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Score" +msgstr "Score" + +#: src/data/providers/images/SteamGridDB.vala:213 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Author" +msgstr "Maker" + +#: src/data/providers/images/SteamGridDB.vala:225 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Alternate" +msgstr "Alternatief" + +#: src/data/providers/images/SteamGridDB.vala:226 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Blurred" +msgstr "Vervaagd" + +#. TRANSLATORS: Flat / Material Design image style. Probably should not be translated +#: src/data/providers/images/SteamGridDB.vala:228 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Material" +msgstr "Material" + +#: src/data/providers/images/SteamGridDB.vala:229 +msgctxt "imagesource_steamgriddb_image_style" +msgid "No logo" +msgstr "Zonder logo" + +#: src/data/providers/images/SteamGridDB.vala:230 +msgctxt "imagesource_steamgriddb_image_style" +msgid "White logo" +msgstr "Wit logo" + +#: src/data/providers/data/IGDB.vala:147 +msgid "" +"Monthly IGDB request quota has been reached. Set your own API key to use " +"IGDB data or disable IGDB." +msgstr "" +"Het maandelijkse IGDB-verzoekquotum is overschreden. Stel je eigen API-" +"sleutel in of schakel IGDB uit." + +#: src/data/providers/data/IGDB.vala:148 +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:40 +#: src/ui/views/WelcomeView.vala:53 src/ui/views/WelcomeView.vala:78 +#: src/ui/views/GamesView/GamesView.vala:230 +#: src/ui/views/GamesView/GamesView.vala:629 +msgid "Settings" +msgstr "Instellingen" + +#: src/data/providers/data/IGDB.vala:356 +msgctxt "igdb_related_link" +msgid "Official website" +msgstr "Officiële website" + +#: src/data/providers/data/IGDB.vala:469 +msgctxt "igdb_preferred_description" +msgid "When game has description, show description" +msgstr "Spelomschrijving tonen (inden beschikbaar)" + +#: src/data/providers/data/IGDB.vala:476 +msgctxt "igdb_preferred_description" +msgid "of game" +msgstr "van spel" + +#: src/data/providers/data/IGDB.vala:477 +msgctxt "igdb_preferred_description" +msgid "from IGDB" +msgstr "van IGDB" + +#: src/data/providers/data/IGDB.vala:478 +msgctxt "igdb_preferred_description" +msgid "both" +msgstr "beide" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:65 +msgid "Some settings will be applied after application restart" +msgstr "" +"Sommige instellingen worden pas toegepast na het herstarten van de applicatie" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:71 +msgid "Games directory contains space. It may cause problems for some games" +msgstr "" +"De spelmap bevat een spatie; dit kan problemen opleveren bij sommige spellen" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:36 +msgid "Interface" +msgstr "Uiterlijk" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:37 +msgid "Appearance" +msgstr "Uiterlijk" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:38 +msgid "General interface settings" +msgstr "Algemene instellingen" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:48 +msgid "Dark theme" +msgstr "Donker thema" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:53 +msgctxt "icon_style" +msgid "Theme-based" +msgstr "Op basis van thema" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:54 +msgctxt "icon_style" +msgid "Symbolic" +msgstr "Symbolisch" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:55 +msgctxt "icon_style" +msgid "Colored" +msgstr "Met kleur" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:57 +msgctxt "icon_style" +msgid "Icon style" +msgstr "Pictogramstijl" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:84 +msgid "Game card" +msgstr "Spelkaart" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:86 +msgid "Show platform icons" +msgstr "Platformpictogrammen tonen" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:99 +msgctxt "grid_size" +msgid "Card size" +msgstr "Kaartgrootte" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:117 +msgctxt "grid_size_preset" +msgid "Presets" +msgstr "Voorinstellingen" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:139 +msgid "Games list: installed" +msgstr "Spellenlijst: geïnstalleerd" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:140 +msgid "Games list: not installed" +msgstr "Spellenlijst: niet geïnstalleerd" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:142 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:146 +msgctxt "list_style" +msgid "Show icon" +msgstr "Pictogram tonen" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:143 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:147 +msgctxt "list_style" +msgid "Bold title" +msgstr "Vetgedrukte titel" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:144 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:148 +msgctxt "list_style" +msgid "Show status" +msgstr "Status tonen" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:149 +msgctxt "list_style" +msgid "Dim" +msgstr "Dimmen" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:151 +msgid "Grid options" +msgstr "Rasteropties" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:152 +msgid "List options" +msgstr "Lijstopties" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:31 +msgid "Behavior" +msgstr "Gedrag" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:32 +msgid "Behavior settings" +msgstr "Gedragsinstellingen" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:42 +msgid "Run games with double click" +msgstr "Spellen starten d.m.v. dubbelklikken" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:46 +msgid "Merge games from different sources" +msgstr "Spellen uit verschillende bronnen samenvoegen" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:50 +msgid "Use imported tags" +msgstr "Geïmporteerde labels gebruiken" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:51 +msgid "General" +msgstr "Algemeen" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:52 +msgid "Collection" +msgstr "Verzameling" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:53 +msgid "Empty" +msgstr "Leeg" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:65 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:85 +msgid "Collection directory" +msgstr "Verzamelingsmap" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:70 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:78 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:87 +msgid "Game directory" +msgstr "Spelmap" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:71 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:79 +msgid "Installers" +msgstr "Installatiebestanden" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:72 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:98 +msgid "DLC" +msgstr "DLC" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:73 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:197 +msgid "Bonus content" +msgstr "Bonusinhoud" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:84 +msgid "Variable syntax: $var or ${var}" +msgstr "Variabele syntax: $var or ${var}" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:86 +msgid "Game name" +msgstr "Spelnaam" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:88 +#: src/ui/views/GamesView/FiltersPopover.vala:127 +msgid "Platform" +msgstr "Platform" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:36 +msgid "Controller" +msgstr "Controller" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +msgid "Enabled" +msgstr "Ingeschakeld" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:53 +msgid "Focus GameHub window with Guide button" +msgstr "GameHub-venster focussen met Gids-knop" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:57 +msgid "Controllers" +msgstr "Controllers" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:89 +msgid "Move focus" +msgstr "Focus verplaatsen" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:91 +msgid "Exit" +msgstr "Afsluiten" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:40 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:108 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:92 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:95 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:36 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:77 +msgid "Disabled" +msgstr "Uitgeschakeld" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:47 +#: src/ui/dialogs/GameTweaksDialog.vala:53 +#: src/ui/views/GamesView/GameContextMenu.vala:183 +msgid "Tweaks" +msgstr "Tweaks" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:34 +msgid "Tweak launch options and apply them to games automatically" +msgstr "Pas de opstartopties van spellen aan en pas ze automatisch toe" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:79 +msgid "" +"Tweaks are loaded from following directories in order\n" +"Last tweak overrides previous tweaks with same identifiers" +msgstr "" +"Tweaks worden geladen uit de volgende mappen, op volgorde\n" +"De recentste tweak overschrijft vorige tweaks met dezelfde id's" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:83 +msgid "Click to open" +msgstr "Klik om te openen" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:93 +#, c-format +msgid "Tweaks are loaded from %1$s and %2$d more directories (?)" +msgstr "Tweaks worden geladen uit %1$s en %2$d andere mappen (?)" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:38 +msgid "Game sources" +msgstr "Spelbronnen" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +msgid "Steam API keys have limited number of uses per day" +msgstr "Steam API-sleutels mogen per dag slechts beperkt worden gebruikt" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:63 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:57 +msgid "Installation directory" +msgstr "Installatiemap" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:176 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:81 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:34 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:75 +msgid "Not installed" +msgstr "Niet-geïnstalleerd" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:116 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:96 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:99 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:85 +msgid "Not authenticated" +msgstr "Geen authenticatie" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +#, c-format +msgid "Authenticated as %s" +msgstr "Geauthenticeerd als %s" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:103 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +msgid "Authenticated" +msgstr "Geacthenticeerd" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:183 +#: src/ui/dialogs/InstallDialog.vala:53 src/ui/dialogs/InstallDialog.vala:111 +#: src/ui/views/GamesView/GameContextMenu.vala:80 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:233 +#: src/ui/widgets/TweaksList.vala:95 +msgid "Install" +msgstr "Installeren" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:236 +msgid "Steam API key" +msgstr "Steam API-sleutel" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:50 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:54 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:48 +msgid "Games directory" +msgstr "Spellenmap" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:63 +msgid "Logout" +msgstr "Uitloggen" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:50 +msgid "Load games from Humble Trove" +msgstr "Spellen laden uit Humble Trove" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:45 +msgid "Emulators" +msgstr "Emulators" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:45 +msgid "Libretro core directory" +msgstr "Libretro-coremap" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:46 +msgid "Libretro core info directory" +msgstr "Libretro-core-informatiemap" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:50 +msgid "Ignored libretro cores" +msgstr "Genegeerde libretro-corebestanden" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:54 +msgid "Ignored game file extensions" +msgstr "Genegeerde bestandsextensies" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:66 +msgid "No cores found" +msgstr "Geen kernen aangetroffen" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:70 +#, c-format +msgid "%u core found" +msgid_plural "%u cores found" +msgstr[0] "%u kern aangetroffen" +msgstr[1] "%u kernen aangetroffen" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:46 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:168 +msgid "No custom emulators" +msgstr "Geen aangepaste emulators" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:164 +#, c-format +msgid "%u custom emulator" +msgid_plural "%u custom emulators" +msgstr[0] "%u aangepaste emulator" +msgstr[1] "%u aangepaste emulators" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:237 +msgid "Save" +msgstr "Opslaan" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:250 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:312 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/dialogs/GamePropertiesDialog.vala:168 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +#: src/ui/views/GamesView/AddGamePopover.vala:67 +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Executable" +msgstr "Uitvoerbaar bestand" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:251 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/views/GamesView/AddGamePopover.vala:68 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Installer" +msgstr "Installatiebestand" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:256 +#: src/ui/dialogs/GamePropertiesDialog.vala:64 +#: src/ui/dialogs/GamePropertiesDialog.vala:69 +#: src/ui/views/GamesView/AddGamePopover.vala:73 +msgid "Name" +msgstr "Naam" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:272 +#: src/ui/dialogs/GamePropertiesDialog.vala:201 +#: src/ui/views/GamesView/AddGamePopover.vala:78 +msgid "Arguments" +msgstr "Extra opties" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:276 +msgid "Variables" +msgstr "Variabelen" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:277 +msgid "Game executable" +msgstr "Uitvoerbaar bestand" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:278 +msgid "Game arguments" +msgstr "Extra opties" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:80 +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Directory" +msgstr "Map" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +msgid "Select emulator directory" +msgstr "Kies emulatormap" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:292 +#: src/ui/dialogs/GamePropertiesDialog.vala:219 +msgid "Force compatibility mode" +msgstr "Comptabiliteitsmodus afdwingen" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:307 +msgid "Game file patterns" +msgstr "Uitvoerbaar bestandspatronen" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:315 +msgid "Image" +msgstr "Afbeelding" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:318 +msgid "Icon" +msgstr "Pictogram" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:325 +msgid "" +"findutils-compatible glob patterns\n" +"\n" +" Multiple patterns can be separated with |\n" +" Start pattern with ./ to match relative path\n" +" $basename variable will be replaced with game's executable " +"name (without extension)" +msgstr "" +"findutils-compatibele glob-patronen\n" +"\n" +" Scheid meerdere patronen middels |\n" +" Begin een patroon met ./ om overeen te komen met het " +"relatieve pad\n" +" De $basename-variabel wordt vervangen door de naam van het " +"uitvoerbare bestand (zonder extensie)" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:38 +msgid "Data" +msgstr "Gegevens" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:39 +msgid "Providers" +msgstr "Providers" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:40 +msgid "Third-party data providers" +msgstr "Externe gegevensproviders" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:55 +msgid "Image providers" +msgstr "Afbeeldingsproviders" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:68 +msgid "Metadata providers" +msgstr "Metagegevens-providers" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:137 +msgid "Open website" +msgstr "Website openen" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:36 +msgid "About" +msgstr "Over" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:71 +msgid "Copy application version and environment info" +msgstr "Applicatieversie en werkomgevingsinformatie kopiëren" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:78 +#: src/ui/views/WelcomeView.vala:57 +msgid "All your games in one place" +msgstr "Al je spellen op één plek" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:92 +msgctxt "about_link" +msgid "Website" +msgstr "Website" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:96 +msgctxt "about_link" +msgid "Source code on GitHub" +msgstr "Broncode op GitHub" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:103 +msgctxt "about_link" +msgid "Report a problem" +msgstr "Meld een probleem" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:104 +msgctxt "about_link" +msgid "Suggest translations" +msgstr "Stel vertalingen voor" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:110 +msgctxt "about_link" +msgid "Issues" +msgstr "Problemen" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:111 +msgctxt "about_link" +msgid "Contributors" +msgstr "Bijdragers" + +#. TRANSLATORS: Likely it should not be translated. GitHub Pulse is a page that shows recent repository activity: https://github.com/tkashkin/GameHub/pulse +#: src/ui/dialogs/SettingsDialog/pages/About.vala:114 +msgctxt "about_link" +msgid "Pulse" +msgstr "Pulse" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:115 +msgctxt "about_link" +msgid "Forks" +msgstr "Forks" + +#: src/ui/dialogs/InstallDialog.vala:109 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:129 +msgid "Import" +msgstr "Importeren" + +#: src/ui/dialogs/InstallDialog.vala:110 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:153 +msgid "Download" +msgstr "Downloaden" + +#: src/ui/dialogs/InstallDialog.vala:207 +msgid "Select installer" +msgstr "Kies installatiebestand" + +#: src/ui/dialogs/InstallDialog.vala:216 +#, c-format +msgid "Installer size: %s" +msgstr "Grootte van installatiebestand: %s" + +#: src/ui/dialogs/InstallDialog.vala:348 +msgid "Unknown" +msgstr "Onbekend" + +#: src/ui/dialogs/GamePropertiesDialog.vala:49 +#, c-format +msgid "%s: Properties" +msgstr "%s: Eigenschappen" + +#: src/ui/dialogs/GamePropertiesDialog.vala:84 +msgid "Images" +msgstr "Afbeeldingen" + +#: src/ui/dialogs/GamePropertiesDialog.vala:126 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:160 +#: src/ui/views/GameDetailsView/blocks/Artwork.vala:62 +msgid "Download images" +msgstr "Afbeeldingen downloaden" + +#: src/ui/dialogs/GamePropertiesDialog.vala:144 +msgid "Image URL" +msgstr "Afbeeldings-URL" + +#: src/ui/dialogs/GamePropertiesDialog.vala:148 +msgid "Vertical image URL" +msgstr "URL van verticale afbeelding" + +#: src/ui/dialogs/GamePropertiesDialog.vala:157 +msgid "Icon URL" +msgstr "Pictogram-URL" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Select working directory" +msgstr "Kies de werkmap" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Working directory" +msgstr "Werkmap" + +#: src/ui/dialogs/GamePropertiesDialog.vala:214 +msgid "Compatibility" +msgstr "Comptabiliteit" + +#: src/ui/dialogs/GamePropertiesDialog.vala:236 +msgid "Launch from terminal" +msgstr "Opstarten in terminalvenster" + +#: src/ui/dialogs/GamePropertiesDialog.vala:252 +msgid "Copy to clipboard" +msgstr "Kopiëren naar klembord" + +#: src/ui/dialogs/GamePropertiesDialog.vala:254 +msgid "Add to Steam" +msgstr "Toevoegen aan Steam" + +#: src/ui/dialogs/GamePropertiesDialog.vala:255 +msgid "Add to the Steam library" +msgstr "Toevoegen aan de Steam-bibliotheek" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:53 +#, c-format +msgid "%s: Overlays" +msgstr "%s: Overlays" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "Overlays are disabled" +msgstr "Overlays zijn uitgeschakeld" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "" +"Enable overlays to manage DLCs and mods\n" +"\n" +"Enabling will move game to the “base“ overlay" +msgstr "" +"Schakel overlays in om DLC's en mods te beheren\n" +"\n" +"Door dit in te schakelen wordt het spel verplaatst naar de \"base\"-overlay" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:77 +#: src/ui/views/GamesView/GameContextMenu.vala:175 +msgid "Overlays" +msgstr "Overlays" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:105 +msgid "Overlay ID (directory name)" +msgstr "Overlay-ID (mapnaam)" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:110 +msgid "Overlay name (optional)" +msgstr "Overlay-naam (optioneel)" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:112 +msgid "Add" +msgstr "Toevoegen" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:127 +msgid "Enable overlays" +msgstr "Overlays inschakelen" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:182 +#, c-format +msgid "" +"Overlay usage at this path may be unsafe\n" +"Proceed at your own risk\n" +"\n" +"Path: %s" +msgstr "" +"Het gebruik van overlays binnen dit pad kan onveilig zijn.\n" +"Doorgaan is op eigen risico.\n" +"\n" +"Pad: %s" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:187 +#, c-format +msgid "" +"Overlay usage at this path is not supported\n" +"\n" +"Path: %s" +msgstr "" +"Het gebruik van overlays binnen dit pad wordt niet ondersteund.\n" +"\n" +"Pad: %s" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:266 +msgid "Open directory" +msgstr "Map openen" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:271 +msgid "Remove overlay" +msgstr "Overlay verwijderen" + +#: src/ui/dialogs/CompatRunDialog.vala:48 +#: src/ui/views/GamesView/GameContextMenu.vala:46 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:235 +msgid "Run with compatibility layer" +msgstr "Uitvoeren met comptabiliteit" + +#: src/ui/dialogs/CorruptedInstallerDialog.vala:71 +msgid "Corrupted installer: checksum mismatch in" +msgstr "Kapot installatiebestand: controlesom komt niet overeen voor" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:57 +#: src/ui/views/GamesView/AddGamePopover.vala:105 +msgid "Import emulated games" +msgstr "Geëmuleerde spellen importeren" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:75 +msgid "Select directory with emulated games" +msgstr "Kies map met geëmuleerde spellen" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:83 +msgid "Detected games" +msgstr "Aangetroffen spellen" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:107 +msgid "Select all" +msgstr "Alles selecteren" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:115 +msgid "Select directory to import" +msgstr "Kies de te importeren map" + +#: src/ui/dialogs/GameTweaksDialog.vala:40 +#, c-format +msgid "%s: Tweaks" +msgstr "%s: Tweaks" + +#: src/ui/views/WelcomeView.vala:52 +msgid "No enabled game sources" +msgstr "Geen spelbronnen ingeschakeld" + +#: src/ui/views/WelcomeView.vala:52 +msgid "Enable some game sources in settings" +msgstr "Schakel spelbronnen in via de instellingen" + +#: src/ui/views/WelcomeView.vala:57 +msgid "Let's get started" +msgstr "Laten we beginnen" + +#: src/ui/views/WelcomeView.vala:71 +msgid "Skip" +msgstr "Overslaan" + +#: src/ui/views/WelcomeView.vala:141 +msgid "Ready" +msgstr "Voltooid" + +#: src/ui/views/WelcomeView.vala:147 +msgid "Authentication required" +msgstr "Authenticatie vereist" + +#: src/ui/views/WelcomeView.vala:152 +msgid "Authenticating…" +msgstr "Bezig met authenticeren…" + +#: src/ui/views/WelcomeView.vala:163 +#, c-format +msgid "Install %s" +msgstr "%s installeren" + +#: src/ui/views/WelcomeView.vala:164 +msgid "Return to GameHub after installing" +msgstr "Keer na het installeren terug naar GameHub" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "No games" +msgstr "Geen spellen" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "Get some games or enable some game sources in settings" +msgstr "Installeer spellen of schakel spelbronnen in via de instellingen" + +#: src/ui/views/GamesView/GamesView.vala:150 +msgid "Grid view" +msgstr "Rasterweergave" + +#: src/ui/views/GamesView/GamesView.vala:151 +msgid "List view" +msgstr "Lijstweergave" + +#: src/ui/views/GamesView/GamesView.vala:159 +msgid "All games" +msgstr "Alle spellen" + +#: src/ui/views/GamesView/GamesView.vala:182 +msgid "Downloads" +msgstr "Downloads" + +#: src/ui/views/GamesView/GamesView.vala:208 +msgid "Filters" +msgstr "Filters" + +#: src/ui/views/GamesView/GamesView.vala:216 +#: src/ui/views/GamesView/AddGamePopover.vala:84 +msgid "Add game" +msgstr "Spel toevoegen" + +#: src/ui/views/GamesView/GamesView.vala:223 +msgid "Search" +msgstr "Zoeken" + +#: src/ui/views/GamesView/GamesView.vala:328 +msgid "Menu" +msgstr "Menu" + +#: src/ui/views/GamesView/GamesView.vala:329 +#: src/ui/views/GameDetailsView/GameDetailsView.vala:104 +msgid "Back" +msgstr "Terug" + +#: src/ui/views/GamesView/GamesView.vala:550 +#, c-format +msgid "%u game" +msgid_plural "%u games" +msgstr[0] "%u spel" +msgstr[1] "%u spellen" + +#: src/ui/views/GamesView/GamesView.vala:553 +#, c-format +msgctxt "games_view_subtitle_filtered_games" +msgid "%1$u / %2$s" +msgstr "%1$u / %2$s" + +#: src/ui/views/GamesView/GamesView.vala:557 +#, c-format +msgctxt "games_view_subtitle" +msgid "%1$s: %2$s" +msgstr "%1$s: %2$s" + +#: src/ui/views/GamesView/GamesView.vala:568 +msgid "No user-added games" +msgstr "Geen door de gebruiker toegevoegde spellen" + +#: src/ui/views/GamesView/GamesView.vala:569 +msgid "Add some games using plus button" +msgstr "Voeg spellen toe via de plus-knop" + +#: src/ui/views/GamesView/GamesView.vala:573 +#, c-format +msgid "No %s games" +msgstr "Geen %s-spellen" + +#: src/ui/views/GamesView/GamesView.vala:574 +msgid "Get some Linux-compatible games" +msgstr "Installeer met Linux compatibele spellen" + +#: src/ui/views/GamesView/GamesView.vala:584 +#, c-format +msgid "No games matching “%s”" +msgstr "Er zijn geen spellen die overeenkomen met \"%s\"" + +#: src/ui/views/GamesView/GamesView.vala:589 +#, c-format +msgid "No %1$s games matching “%2$s”" +msgstr "Er zijn geen %1$s-spellen die overeenkomen met \"%2$s\"" + +#: src/ui/views/GamesView/GamesView.vala:627 +msgid "" +"No games were loaded from Steam. Set your games list privacy to public or " +"use your own Steam API key in settings." +msgstr "" +"Er zijn geen spellen geladen vanuit Steam. Maak je spellijst openbaar of " +"voeg je eigen Steam API-sleutel toe via de instellingen." + +#: src/ui/views/GamesView/GamesView.vala:628 +msgid "Privacy" +msgstr "Privacy" + +#: src/ui/views/GamesView/GamesView.vala:739 +msgid "Downloading images" +msgstr "Bezig met downloaden van afbeeldingen" + +#: src/ui/views/GamesView/GamesView.vala:753 +#, c-format +msgid "Downloading image: %s" +msgstr "Bezig met downloaden van afbeelding: %s" + +#: src/ui/views/GamesView/DownloadProgressView.vala:131 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:162 +msgid "Pause download" +msgstr "Downloaden pauzeren" + +#: src/ui/views/GamesView/DownloadProgressView.vala:137 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:168 +msgid "Resume download" +msgstr "Downloaden hervatten" + +#: src/ui/views/GamesView/DownloadProgressView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:174 +msgid "Cancel download" +msgstr "Downloaden annuleren" + +#: src/ui/views/GamesView/FiltersPopover.vala:77 +msgid "Group" +msgstr "Groeperen" + +#: src/ui/views/GamesView/FiltersPopover.vala:102 +msgid "Sort" +msgstr "Sorteren" + +#: src/ui/views/GamesView/FiltersPopover.vala:234 +#: src/ui/widgets/GameTagsList.vala:58 +msgid "Tags" +msgstr "Labels" + +#: src/ui/views/GamesView/FiltersPopover.vala:353 +msgid "All platforms" +msgstr "Alle platformen" + +#: src/ui/views/GamesView/AddGamePopover.vala:77 +msgid "Select game executable" +msgstr "Kies uitvoerbaar bestand" + +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Select game directory" +msgstr "Kies spelmap" + +#: src/ui/views/GamesView/AddGamePopover.vala:111 +msgid "Download game images" +msgstr "Spelafbeeldingen downloaden" + +#: src/ui/views/GamesView/GameContextMenu.vala:87 +msgid "Details" +msgstr "Details" + +#: src/ui/views/GamesView/GameContextMenu.vala:117 +msgctxt "game_context_menu" +msgid "Favorite" +msgstr "Favoriet" + +#: src/ui/views/GamesView/GameContextMenu.vala:121 +msgctxt "game_context_menu" +msgid "Hidden" +msgstr "Verborgen" + +#: src/ui/views/GamesView/GameContextMenu.vala:133 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:236 +msgid "Open installation directory" +msgstr "Open installatiemap" + +#: src/ui/views/GamesView/GameContextMenu.vala:142 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:237 +msgid "Open installers collection directory" +msgstr "Open verzamelmap met installatiebestanden" + +#: src/ui/views/GamesView/GameContextMenu.vala:151 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:238 +msgid "Open bonus collection directory" +msgstr "Open bonusverzamelmap" + +#: src/ui/views/GamesView/GameContextMenu.vala:160 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:239 +msgid "Open screenshots directory" +msgstr "Schermafdrukmap openen" + +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +msgid "Uninstall" +msgstr "Deïnstalleren" + +#: src/ui/views/GamesView/GameContextMenu.vala:192 +msgid "Properties" +msgstr "Eigenschappen" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:100 +#, c-format +msgid "%d game selected" +msgid_plural "%d games selected" +msgstr[0] "%d spel geselecteerd" +msgstr[1] "%d spellen geselecteerd" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:144 +#, c-format +msgid "%d game will be installed" +msgid_plural "%d games will be installed" +msgstr[0] "Er wordt %d spel geïnstalleerd" +msgstr[1] "Er worden %d spellen geïnstalleerd" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:154 +#, c-format +msgid "%d game will be downloaded" +msgid_plural "%d games will be downloaded" +msgstr[0] "Er wordt %d spel gedownload" +msgstr[1] "Er worden %d spellen gedownload" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:161 +#, c-format +msgid "Image for %d game will be searched" +msgid_plural "Images for %d games will be searched" +msgstr[0] "Er wordt gezocht naar een afbeelding voor %d spel" +msgstr[1] "Er wordt gezocht naar een afbeelding voor %d spellen" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:168 +#, c-format +msgid "%d game will be uninstalled" +msgid_plural "%d games will be uninstalled" +msgstr[0] "Er wordt %d spel verwijderd" +msgstr[1] "Er worden %d spellen verwijderd" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:174 +msgid "Refresh" +msgstr "Verversen" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:175 +#, c-format +msgid "" +"%d game will be removed from database. Restart GameHub to fetch new data" +msgid_plural "" +"%d games will be removed from database. Restart GameHub to fetch new data" +msgstr[0] "" +"Er wordt %d spel verwijderd uit de databank. Herstart GameHub om nieuwe " +"gegevens op te halen." +msgstr[1] "" +"Er worden %d spellen verwijderd uit de databank. Herstart GameHub om nieuwe " +"gegevens op te halen." + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:240 +msgid "Open store page" +msgstr "Winkelpagina openen" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:242 +msgid "Game properties" +msgstr "Speleigenschappen" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:46 +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:60 +msgid "Playtime" +msgstr "Speeltijd" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:52 +msgid "Playtime (local)" +msgstr "Speeltijd (lokaal)" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:69 +msgid "Last launch" +msgstr "Laatst opgestart" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:46 +msgid "Achievements" +msgstr "Prestaties" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:85 +#, c-format +msgid "Unlocked: %s" +msgstr "Ontgrendeld: %s" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:90 +#, c-format +msgid "Global percentage: %g%%" +msgstr "Algemeen percentage: %g %%" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:77 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:103 +msgid "Language" +msgstr "Taal" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:80 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:106 +msgid "Languages" +msgstr "Talen" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:147 +#, c-format +msgid "%u DLCs cannot be installed" +msgstr "%u: DLC's kunnen niet worden geïnstalleerd" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:71 +msgid "Category" +msgstr "Categorie" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:74 +msgid "Categories" +msgstr "Categorieën" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:90 +msgid "Genre" +msgstr "Genre" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:93 +msgid "Genres" +msgstr "Genres" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:109 +msgctxt "igdb" +msgid "Popularity" +msgstr "Populariteit" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:115 +msgctxt "igdb" +msgid "Aggregated rating" +msgstr "Algehele waardering" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:116 +msgctxt "igdb" +msgid "IGDB user rating" +msgstr "IGDB-gebruikerswaardering" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:117 +msgctxt "igdb" +msgid "Total rating" +msgstr "Totale waardering" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:126 +msgctxt "igdb" +msgid "Release date" +msgstr "Verschijningsdatum" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:133 +msgctxt "igdb" +msgid "Platforms" +msgstr "Platformen" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:139 +msgctxt "igdb" +msgid "Genres" +msgstr "Genres" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:145 +msgctxt "igdb" +msgid "Keywords" +msgstr "Trefwoorden" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:152 +msgctxt "igdb" +msgid "Links" +msgstr "Links" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:208 +#, c-format +msgid "Based on %d rating" +msgid_plural "Based on %d ratings" +msgstr[0] "Op basis van %d waardering" +msgstr[1] "Op basis van %d waarderingen" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:290 +msgctxt "igdb" +msgid "Summary" +msgstr "Samenvatting" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:301 +msgctxt "igdb" +msgid "Storyline" +msgstr "Verhaallijn" + +#: src/ui/widgets/FileChooserEntry.vala:49 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select file" +msgstr "Kies bestand" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "No images" +msgstr "Geen afbeeldingen" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "" +"There are no images found for this game\n" +"Make sure game name is correct" +msgstr "" +"Er zijn geen afbeeldingen gevonden bij dit spel\n" +"Controleer de naam van het spel" + +#: src/ui/widgets/ImagesDownloadPopover.vala:94 +msgid "Search images:" +msgstr "Afbeeldingen zoeken:" + +#: src/ui/widgets/CompatToolPicker.vala:53 +msgid "Compatibility layer:" +msgstr "Comptabiliteit:" + +#: src/ui/widgets/CompatToolPicker.vala:92 +msgid "Configure" +msgstr "Instellen" + +#: src/ui/widgets/GameTagsList.vala:109 +msgid "Add tag" +msgstr "Label toevoegen" + +#: src/ui/widgets/TweaksList.vala:86 +msgid "No description" +msgstr "Geen omschrijving" + +#: src/ui/widgets/TweaksList.vala:124 +msgid "Edit file" +msgstr "Bestand aanpassen" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dh" +msgstr "%du" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dm" +msgstr "%dm" + +#: src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%ds" +msgstr "%ds" + +#: src/settings/UI.vala:153 +msgctxt "grid_size_preset" +msgid "Steam" +msgstr "Steam" + +#: src/settings/UI.vala:154 +msgctxt "grid_size_preset" +msgid "Steam (vertical)" +msgstr "Steam (verticaal)" + +#: src/settings/UI.vala:155 +msgctxt "grid_size_preset" +msgid "GOG" +msgstr "GOG" + +#: src/settings/UI.vala:156 +msgctxt "grid_size_preset" +msgid "GOG (vertical)" +msgstr "GOG (verticaal)" + +#: src/settings/UI.vala:157 +msgctxt "grid_size_preset" +msgid "Square" +msgstr "Vierkant" + +#: src/settings/UI.vala:158 +msgctxt "grid_size_preset" +msgid "Custom" +msgstr "Aangepast" + +#: src/utils/downloader/Downloader.vala:200 +msgctxt "dl_status" +msgid "Queued" +msgstr "In wachtrij" + +#: src/utils/downloader/Downloader.vala:201 +msgctxt "dl_status" +msgid "Starting download" +msgstr "Bezig met starten van download" + +#: src/utils/downloader/Downloader.vala:202 +msgctxt "dl_status" +msgid "Download started" +msgstr "Downloaden gestart" + +#: src/utils/downloader/Downloader.vala:203 +msgctxt "dl_status" +msgid "Download finished" +msgstr "Downloaden voltooid" + +#: src/utils/downloader/Downloader.vala:204 +msgctxt "dl_status" +msgid "Download failed" +msgstr "Downloaden mislukt" + +#: src/utils/downloader/Downloader.vala:208 +#, c-format +msgctxt "dl_status" +msgid "Downloading: %s" +msgstr "Bezig met downloaden: %s" + +#: src/utils/downloader/Downloader.vala:210 +msgctxt "dl_status" +msgid "Downloading" +msgstr "Bezig met downloaden" + +#: src/utils/downloader/Downloader.vala:214 +#, c-format +msgctxt "dl_status" +msgid "Paused: %s" +msgstr "Gepauzeerd: %s" + +#: src/utils/downloader/Downloader.vala:216 +msgctxt "dl_status" +msgid "Paused" +msgstr "Gepauzeerd" + +#: src/utils/downloader/Downloader.vala:218 +msgctxt "dl_status" +msgid "Download cancelled" +msgstr "Downloaden geannuleerd" + +#. TRANSLATORS: Download progress template. %1$d - percentage, %2$s / %3$s - downloaded portion and total file size, %4$s - download speed +#: src/utils/downloader/Downloader.vala:262 +#, c-format +msgctxt "dl_status" +msgid "%1$d%% (%2$s / %3$s) [%4$s/s]" +msgstr "%1$d%% (%2$s / %3$s) [%4$s/s]" + +#~ msgid "Disable esync" +#~ msgstr "esync uitschakelen" + +#~ msgid "Force LARGE_ADDRESS_AWARE flag" +#~ msgstr "LARE_ADDRESS_AWARE-functie afdwingen" + +#~ msgid "Disable DirectX 11 compatibility layer" +#~ msgstr "DirectX 11-comptabiliteit uitschakelen" + +#~ msgid "Use WineD3D11 as DirectX 11 compatibility layer" +#~ msgstr "WineD3D11 gebruiken voor DirectX 11-comptabiliteit" + +#~ msgid "Show DXVK info overlay" +#~ msgstr "DXVK-informatieoverlay tonen" + +#~ msgid "Enable DirectX 9 compatibility layer" +#~ msgstr "DirectX 9-comptabiliteit inschakelen" + +#~ msgid "Silent installation" +#~ msgstr "Stille installatie" + +#~ msgid "Very silent installation" +#~ msgstr "Erg stille installatie" + +#~ msgid "Suppress messages" +#~ msgstr "Berichten onderdrukken" + +#~ msgid "No GUI" +#~ msgstr "Zonder grafisch venster" + +#~ msgctxt "igdb" +#~ msgid "%s on IGDB" +#~ msgstr "%s op IGDB" + +#~ msgid "Disable fullscreen" +#~ msgstr "Volledig scherm uitschakelen" + +#~ msgid "Windowed" +#~ msgstr "Venster" + +#~ msgid "Compact list" +#~ msgstr "Compacte lijst" + +#~ msgid "Show non-native games" +#~ msgstr "Wine-spellen tonen" + +#~ msgid "Use compatibility layers and consider Windows games compatible" +#~ msgstr "" +#~ "Comptabiliteit gebruiken en Windows-spellen aanmerken als compatibel" + +#~ msgid "Glob patterns separated with |" +#~ msgstr "Scheid algemene patronen met |" + +#~ msgid "About GameHub" +#~ msgstr "Over GameHub" + +#~ msgid "Use symbolic icons instead of colored icons" +#~ msgstr "Symbolische pictogrammen gebruiken in plaats van gekleurde" + +#~ msgid "Enable controller support" +#~ msgstr "Controller-ondersteuning inschakelen" + +#~ msgid "Reload" +#~ msgstr "Herladen" + +#~ msgid "Updating game info" +#~ msgstr "Bezig met bijwerken van spelinformatie" + +#~ msgid "Updating %s game info" +#~ msgstr "Bezig met bijwerken van %s-spelinformatie" + +#~ msgid "Merging %s (%s)" +#~ msgstr "Bezig met samenvoegen van %s (%s)" diff --git a/po/pl.po b/po/pl.po new file mode 100644 index 00000000..7f8080ea --- /dev/null +++ b/po/pl.po @@ -0,0 +1,1946 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the com.github.tkashkin.gamehub package. +# AngryPenguinPL , 2019. +# Anatoliy Kashkin , 2019. +# Antek Karaś , 2019. +# Garreciq , 2020. +msgid "" +msgstr "" +"Project-Id-Version: com.github.tkashkin.gamehub\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-26 06:40+0300\n" +"PO-Revision-Date: 2020-02-04 23:50+0000\n" +"Last-Translator: Garreciq \n" +"Language-Team: Polish \n" +"Language: pl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 3.11-dev\n" + +#: src/app.vala:91 +msgid "Show help" +msgstr "Pokaż pomoc" + +#: src/app.vala:92 +msgid "Show application version and exit" +msgstr "Pokaż wersję aplikacji i wyjdź" + +#: src/app.vala:93 +msgid "Restart with GDB debugger attached" +msgstr "Zrestartuj z załączonym debuggerem GDB" + +#: src/app.vala:94 +msgid "Show full GDB backtrace" +msgstr "Pokaż pełen log z GDB" + +#: src/app.vala:95 +msgid "Treat fatal errors as criticals and crash application" +msgstr "" + +#: src/app.vala:99 +msgid "Show main window" +msgstr "Pokaż główne okno" + +#: src/app.vala:100 +msgid "Show application settings dialog" +msgstr "Pokaż okno z ustawieniami aplikacji" + +#: src/app.vala:101 +#, fuzzy +msgid "Show about dialog" +msgstr "Pokaż okno opcji kompatybilności" + +#: src/app.vala:102 +msgid "Maximum number of background worker threads" +msgstr "Maksymalna liczba wątków działających w tle" + +#: src/app.vala:106 +msgid "Run game" +msgstr "Uruchom grę" + +#: src/app.vala:107 +msgid "Show compatibility options dialog" +msgstr "Pokaż okno opcji kompatybilności" + +#: src/app.vala:108 +msgid "Open game details" +msgstr "Otwórz szczegóły gry" + +#: src/app.vala:109 +msgid "Open game properties" +msgstr "Otwórz właściwości gry" + +#: src/app.vala:113 +msgid "Enable debug logging" +msgstr "Włącz rejestrowanie debugowania" + +#: src/app.vala:114 +msgid "" +"Log authentication process and sensitive information like authentication " +"tokens" +msgstr "" +"Rejestruj proces uwierzytelniania i informacji poufnych takich jak tokeny " +"uwierzytelniania" + +#: src/app.vala:115 +msgid "Log download manager" +msgstr "Monitoruj menadżer pobierania" + +#: src/app.vala:116 +msgid "Log background workers start/stop" +msgstr "Rejestruj w tle zadania start/stop" + +#: src/app.vala:117 +msgid "Disable log messages filtering" +msgstr "" + +#: src/app.vala:118 +msgid "Verbose logging" +msgstr "Pełne rejestrowanie" + +#: src/app.vala:247 +msgid "Game Options:" +msgstr "Opcje gry:" + +#: src/app.vala:247 +msgid "Show game options help" +msgstr "Pokaż pomoc dla opcji gry" + +#: src/app.vala:255 +msgid "Logging Options:" +msgstr "Opcje rejestrowania:" + +#: src/app.vala:255 +msgid "Show logging options help" +msgstr "Pokaż pomoc dotyczącą opcji rejestrowania" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +msgid "Select executable" +msgstr "Wybierz plik wykonywalny" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:181 src/ui/views/GamesView/GamesView.vala:330 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select" +msgstr "Wybierz" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:180 src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Cancel" +msgstr "Anuluj" + +#: src/data/Runnable.vala:166 src/ui/widgets/FileChooserEntry.vala:49 +msgid "Select directory" +msgstr "Wybierz katalog" + +#: src/data/Runnable.vala:619 +#, c-format +msgid "Part %1$u of %2$u: %3$s" +msgstr "Część %1$u of %2$u: %3$s" + +#: src/data/Runnable.vala:642 src/ui/dialogs/CorruptedInstallerDialog.vala:48 +#, c-format +msgid "%s: corrupted installer" +msgstr "%s: uszkodzony instalator" + +#: src/data/Runnable.vala:643 +#, c-format +msgid "Checksum mismatch in %s" +msgstr "Błędna suma kontrolna in %s" + +#: src/data/Runnable.vala:657 src/ui/dialogs/CorruptedInstallerDialog.vala:126 +msgid "Show file" +msgstr "Pokaż plik" + +#: src/data/Runnable.vala:658 src/ui/dialogs/CorruptedInstallerDialog.vala:132 +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#: src/ui/widgets/TagRow.vala:146 +msgid "Remove" +msgstr "Usuń" + +#: src/data/Runnable.vala:659 src/ui/dialogs/CorruptedInstallerDialog.vala:128 +msgid "Backup" +msgstr "Kopia zapasowa" + +#: src/data/Runnable.vala:778 +#, c-format +msgid "%s: cannot detect main executable" +msgstr "%s: nie można wykryć głównego pliku wykonywalnego" + +#: src/data/Runnable.vala:779 +msgid "" +"Main executable file for this game cannot be detected automatically.\n" +"Please set main executable in game's properties." +msgstr "" +"Główny plik wykonywalny nie może zostać wykryty automatycznie.\n" +"Proszę ustawić główny plik wykonywalny we właściwościach gry." + +#: src/data/Runnable.vala:908 +#, fuzzy +msgctxt "platform" +msgid "Emulated" +msgstr "Emulator" + +#: src/data/Game.vala:625 +msgctxt "status" +msgid "Running" +msgstr "Działa" + +#: src/data/Game.vala:628 +msgctxt "status" +msgid "Installed" +msgstr "Zainstalowany" + +#: src/data/Game.vala:629 +msgctxt "status" +msgid "Installing" +msgstr "Instalowanie" + +#: src/data/Game.vala:630 +msgctxt "status" +msgid "Verifying installer integrity" +msgstr "Weryfikowanie integralności instalatora" + +#: src/data/Game.vala:631 +msgctxt "status" +msgid "Download started" +msgstr "Pobieranie rozpoczęte" + +#: src/data/Game.vala:633 +msgctxt "status" +msgid "Not installed" +msgstr "Nie zainstalowany" + +#: src/data/Game.vala:643 +msgctxt "status_header" +msgid "Installed" +msgstr "Zainstalowany" + +#: src/data/Game.vala:644 +msgctxt "status_header" +msgid "Installing" +msgstr "Instalowanie" + +#: src/data/Game.vala:646 +msgctxt "status_header" +msgid "Downloading" +msgstr "Pobieranie" + +#: src/data/Game.vala:648 +msgctxt "status_header" +msgid "Not installed" +msgstr "Nie zainstalowano" + +#: src/data/GameSource.vala:31 +#, c-format +msgid "%s games" +msgstr "%s gier" + +#: src/data/sources/steam/Steam.vala:43 +msgid "Your SteamID will be read from Steam configuration file" +msgstr "" +"Twój identyfikator SteamID będzie odczytany z pliku konfiguracyjnego Steam" + +#: src/data/sources/steam/Steam.vala:46 +msgid "" +"Steam config file not found.\n" +"Login into your account in Steam client and return to GameHub" +msgstr "" +"Plik konfiguracji Steam nie znaleziony.\n" +"Zaloguj się na swoje konto w kliencie Steam i powróć do GameHub" + +#: src/data/sources/gog/GOGGame.vala:983 +#, c-format +msgid "DLC: %s" +msgstr "" + +#: src/data/sources/humble/HumbleGame.vala:343 +#, c-format +msgid "%s: no available installers" +msgstr "%s: niema dostępnych instalatorów" + +#: src/data/sources/humble/HumbleGame.vala:344 +msgid "" +"Cannot get Trove download URL.\n" +"Make sure your Humble Monthly subscription is active." +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:192 +#, c-format +msgctxt "itch_dl_status" +msgid "%s left;" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:195 +#, c-format +msgctxt "itch_dl_status" +msgid "%d%%" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:198 +#, c-format +msgctxt "itch_dl_status" +msgid "(%1$s / %2$s)" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:201 +#, c-format +msgctxt "itch_dl_status" +msgid "[%s/s]" +msgstr "" + +#: src/data/sources/user/User.vala:30 +msgid "User games" +msgstr "Użytkownik gier" + +#: src/data/db/tables/Tags.vala:225 +msgctxt "tag" +msgid "Favorites" +msgstr "Ulubione" + +#: src/data/db/tables/Tags.vala:226 +msgctxt "tag" +msgid "Not installed" +msgstr "Nie zainstalowany" + +#: src/data/db/tables/Tags.vala:227 +msgctxt "tag" +msgid "Installed" +msgstr "Zainstalowany" + +#: src/data/db/tables/Tags.vala:228 +msgctxt "tag" +msgid "Hidden" +msgstr "Ukryty" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit script" +msgstr "Edycja skryptu" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit custom script" +msgstr "Edycja niestandardowego skryptu" + +#: src/data/compat/Innoextract.vala:55 +#, c-format +msgid "" +"Innoextract %1$s is not supported and may not be able to extract some " +"games correctly.\n" +"Install innoextract %2$s or newer." +msgstr "" + +#: src/data/compat/WineWrap.vala:61 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:242 +#: src/ui/dialogs/CompatRunDialog.vala:102 +#: src/ui/views/GamesView/GameContextMenu.vala:53 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:234 +msgid "Run" +msgstr "Uruchom" + +#: src/data/compat/WineWrap.vala:64 +msgid "Show WineWrap menu" +msgstr "Pokaż menu WineWrap" + +#: src/data/compat/WineWrap.vala:67 src/data/compat/Proton.vala:122 +#: src/data/compat/Wine.vala:83 +msgid "Kill apps in prefix" +msgstr "Zabij aplikacje w prefiksie" + +#: src/data/compat/Proton.vala:47 +msgid "Proton prefix" +msgstr "Proton prefiks" + +#: src/data/compat/Proton.vala:110 src/data/compat/Wine.vala:71 +msgid "Open prefix directory" +msgstr "Otwórz katalog prefiksu" + +#: src/data/compat/Proton.vala:113 src/data/compat/Wine.vala:74 +msgid "Run winecfg" +msgstr "Uruchom winecfg" + +#: src/data/compat/Proton.vala:116 src/data/compat/Wine.vala:77 +msgid "Run winetricks" +msgstr "Uruchom winetricks" + +#: src/data/compat/Proton.vala:119 src/data/compat/Wine.vala:80 +msgid "Run taskmgr" +msgstr "Uruchom taskmgr" + +#: src/data/compat/Wine.vala:53 +msgid "Wine prefix" +msgstr "Wine prefiks" + +#: src/data/compat/Wine.vala:55 +msgid "Environment variables" +msgstr "Zmienne środowiska" + +#: src/data/compat/Wine.vala:60 +msgid "InnoSetup default options" +msgstr "InnoSetup opcje domyślne" + +#: src/data/compat/RetroArch.vala:53 +msgid "Libretro core file" +msgstr "Libretro plik core" + +#: src/data/compat/CustomEmulator.vala:43 +msgid "Custom emulator" +msgstr "Niestandardowy emulator" + +#: src/data/compat/CustomEmulator.vala:48 +msgid "Emulator" +msgstr "Emulator" + +#: src/data/compat/CustomEmulator.vala:49 +msgid "Launch in game directory" +msgstr "Uruchom w katalogu gry" + +#: src/data/adapters/GamesAdapter.vala:440 +msgctxt "status_header" +msgid "Favorites" +msgstr "Ulubione" + +#: src/data/adapters/GamesAdapter.vala:445 +#, fuzzy, c-format +msgctxt "status_header" +msgid "%s: Favorites" +msgstr "Ulubione" + +#: src/data/adapters/GamesAdapter.vala:491 +msgid "Merging games" +msgstr "Łączenie gier" + +#: src/data/adapters/GamesAdapter.vala:504 +#, c-format +msgid "Merging games from %s" +msgstr "Łączenie gier z %s" + +#: src/data/adapters/GamesAdapter.vala:551 +#, c-format +msgid "Loading games from %s" +msgstr "Wczytywanie gier z %s" + +#: src/data/adapters/GamesAdapter.vala:678 +msgctxt "sort_mode" +msgid "By name" +msgstr "Wg nazwy" + +#: src/data/adapters/GamesAdapter.vala:679 +msgctxt "sort_mode" +msgid "By last launch" +msgstr "Wg ostatniego uruchomienia" + +#: src/data/adapters/GamesAdapter.vala:680 +msgctxt "sort_mode" +msgid "By playtime" +msgstr "Wg czasu gry" + +#: src/data/adapters/GamesAdapter.vala:705 +msgctxt "group_mode" +msgid "Do not group" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:706 +msgctxt "group_mode" +msgid "By status" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:707 +#, fuzzy +msgctxt "group_mode" +msgid "By source" +msgstr "Właściwości gry" + +#: src/data/providers/images/SteamGridDB.vala:151 +#: src/data/providers/data/IGDB.vala:431 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:217 +msgid "Default" +msgstr "Domyślne" + +#: src/data/providers/images/SteamGridDB.vala:158 +#: src/data/providers/data/IGDB.vala:438 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:225 +msgid "Restore default API key" +msgstr "Przywróć domyślny klucz API" + +#: src/data/providers/images/SteamGridDB.vala:169 +#: src/data/providers/data/IGDB.vala:449 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:108 +#, fuzzy +msgid "API key" +msgstr "klucz Steam API" + +#: src/data/providers/images/SteamGridDB.vala:177 +#: src/data/providers/data/IGDB.vala:457 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:53 +msgid "Generate key" +msgstr "Wygeneruj klucz" + +#: src/data/providers/images/SteamGridDB.vala:208 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Style" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:209 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Score" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:213 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Author" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:225 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Alternate" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:226 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Blurred" +msgstr "" + +#. TRANSLATORS: Flat / Material Design image style. Probably should not be translated +#: src/data/providers/images/SteamGridDB.vala:228 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Material" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:229 +msgctxt "imagesource_steamgriddb_image_style" +msgid "No logo" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:230 +msgctxt "imagesource_steamgriddb_image_style" +msgid "White logo" +msgstr "" + +#: src/data/providers/data/IGDB.vala:147 +msgid "" +"Monthly IGDB request quota has been reached. Set your own API key to use " +"IGDB data or disable IGDB." +msgstr "" + +#: src/data/providers/data/IGDB.vala:148 +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:40 +#: src/ui/views/WelcomeView.vala:53 src/ui/views/WelcomeView.vala:78 +#: src/ui/views/GamesView/GamesView.vala:230 +#: src/ui/views/GamesView/GamesView.vala:629 +msgid "Settings" +msgstr "Ustawienia" + +#: src/data/providers/data/IGDB.vala:356 +msgctxt "igdb_related_link" +msgid "Official website" +msgstr "" + +#: src/data/providers/data/IGDB.vala:469 +msgctxt "igdb_preferred_description" +msgid "When game has description, show description" +msgstr "" + +#: src/data/providers/data/IGDB.vala:476 +#, fuzzy +msgctxt "igdb_preferred_description" +msgid "of game" +msgstr "Brak gier" + +#: src/data/providers/data/IGDB.vala:477 +msgctxt "igdb_preferred_description" +msgid "from IGDB" +msgstr "" + +#: src/data/providers/data/IGDB.vala:478 +msgctxt "igdb_preferred_description" +msgid "both" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:65 +msgid "Some settings will be applied after application restart" +msgstr "" +"Niektóre ustawienia zostaną zastosowane po ponownym uruchomieniu aplikacji" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:71 +msgid "Games directory contains space. It may cause problems for some games" +msgstr "" +"Katalog gier zawiera spację. To może powodować problemy dla niektórych gier" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:36 +msgid "Interface" +msgstr "Interfejs" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:37 +msgid "Appearance" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:38 +msgid "General interface settings" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:48 +#, fuzzy +msgid "Dark theme" +msgstr "Użyj ciemnego motywu" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:53 +msgctxt "icon_style" +msgid "Theme-based" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:54 +msgctxt "icon_style" +msgid "Symbolic" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:55 +msgctxt "icon_style" +msgid "Colored" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:57 +msgctxt "icon_style" +msgid "Icon style" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:84 +#, fuzzy +msgid "Game card" +msgstr "Nazwa gry" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:86 +#, fuzzy +msgid "Show platform icons" +msgstr "Pokaż ikonę platformy w widoku siatki" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:99 +msgctxt "grid_size" +msgid "Card size" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:117 +msgctxt "grid_size_preset" +msgid "Presets" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:139 +#, fuzzy +msgid "Games list: installed" +msgstr "%s: niema dostępnych instalatorów" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:140 +#, fuzzy +msgid "Games list: not installed" +msgstr "%s: niema dostępnych instalatorów" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:142 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:146 +#, fuzzy +msgctxt "list_style" +msgid "Show icon" +msgstr "Pokaż plik" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:143 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:147 +msgctxt "list_style" +msgid "Bold title" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:144 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:148 +msgctxt "list_style" +msgid "Show status" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:149 +msgctxt "list_style" +msgid "Dim" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:151 +#, fuzzy +msgid "Grid options" +msgstr "Opcje gry:" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:152 +#, fuzzy +msgid "List options" +msgstr "Opcje rejestrowania:" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:31 +msgid "Behavior" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:32 +msgid "Behavior settings" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:42 +msgid "Run games with double click" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:46 +msgid "Merge games from different sources" +msgstr "Więcej gier z różnych źródeł" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:50 +msgid "Use imported tags" +msgstr "Użyj zaimportowanych tagów" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:51 +#, fuzzy +msgid "General" +msgstr "Wygeneruj klucz" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:52 +msgid "Collection" +msgstr "Kolekcja" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:53 +msgid "Empty" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:65 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:85 +msgid "Collection directory" +msgstr "Katalog kolekcji" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:70 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:78 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:87 +msgid "Game directory" +msgstr "Katalog gry" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:71 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:79 +msgid "Installers" +msgstr "Instalatory" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:72 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:98 +msgid "DLC" +msgstr "DLC" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:73 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:197 +msgid "Bonus content" +msgstr "Dodatkowa zawartość" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:84 +msgid "Variable syntax: $var or ${var}" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:86 +msgid "Game name" +msgstr "Nazwa gry" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:88 +#: src/ui/views/GamesView/FiltersPopover.vala:127 +#, fuzzy +msgid "Platform" +msgstr "Wszystkie gry" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:36 +#, fuzzy +msgid "Controller" +msgstr "Instalator" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +msgid "Enabled" +msgstr "Włączone" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:53 +msgid "Focus GameHub window with Guide button" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:57 +#, fuzzy +msgid "Controllers" +msgstr "Instalator" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:89 +msgid "Move focus" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:91 +msgid "Exit" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:40 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:108 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:92 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:95 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:36 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:77 +#, fuzzy +msgid "Disabled" +msgstr "Wyłącz esync" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:47 +#: src/ui/dialogs/GameTweaksDialog.vala:53 +#: src/ui/views/GamesView/GameContextMenu.vala:183 +msgid "Tweaks" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:34 +msgid "Tweak launch options and apply them to games automatically" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:79 +msgid "" +"Tweaks are loaded from following directories in order\n" +"Last tweak overrides previous tweaks with same identifiers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:83 +msgid "Click to open" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:93 +#, c-format +msgid "Tweaks are loaded from %1$s and %2$d more directories (?)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:38 +#, fuzzy +msgid "Game sources" +msgstr "Właściwości gry" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +msgid "Steam API keys have limited number of uses per day" +msgstr "Klucze Steam API mają ograniczoną liczę użyć na każdy dzień" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:63 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:57 +msgid "Installation directory" +msgstr "Katalog instalacji" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:176 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:81 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:34 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:75 +#, fuzzy +msgid "Not installed" +msgstr "Nie zainstalowany" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:116 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:96 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:99 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:85 +#, fuzzy +msgid "Not authenticated" +msgstr "Uwierzytelnienie wymagane" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +#, fuzzy, c-format +msgid "Authenticated as %s" +msgstr "Uwierzytelnianie..." + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:103 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +#, fuzzy +msgid "Authenticated" +msgstr "Uwierzytelnianie..." + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:183 +#: src/ui/dialogs/InstallDialog.vala:53 src/ui/dialogs/InstallDialog.vala:111 +#: src/ui/views/GamesView/GameContextMenu.vala:80 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:233 +#: src/ui/widgets/TweaksList.vala:95 +msgid "Install" +msgstr "Instaluj" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:236 +msgid "Steam API key" +msgstr "klucz Steam API" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:50 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:54 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:48 +msgid "Games directory" +msgstr "Katalog gier" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:63 +msgid "Logout" +msgstr "Wyloguj" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:50 +msgid "Load games from Humble Trove" +msgstr "Wczytaj gry z Humble Trove" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:45 +msgid "Emulators" +msgstr "Emulatory" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:45 +msgid "Libretro core directory" +msgstr "Katalog Libretro core" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:46 +msgid "Libretro core info directory" +msgstr "Informacje o katalogu Libretro core" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:50 +#, fuzzy +msgid "Ignored libretro cores" +msgstr "Libretro plik core" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:54 +msgid "Ignored game file extensions" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:66 +msgid "No cores found" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:70 +#, c-format +msgid "%u core found" +msgid_plural "%u cores found" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:46 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:168 +#, fuzzy +msgid "No custom emulators" +msgstr "Niestandardowy emulator" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:164 +#, fuzzy, c-format +msgid "%u custom emulator" +msgid_plural "%u custom emulators" +msgstr[0] "Niestandardowy emulator" +msgstr[1] "Niestandardowy emulator" +msgstr[2] "Niestandardowy emulator" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:237 +msgid "Save" +msgstr "Zapisz" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:250 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:312 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/dialogs/GamePropertiesDialog.vala:168 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +#: src/ui/views/GamesView/AddGamePopover.vala:67 +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Executable" +msgstr "Wykonywalny" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:251 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/views/GamesView/AddGamePopover.vala:68 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Installer" +msgstr "Instalator" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:256 +#: src/ui/dialogs/GamePropertiesDialog.vala:64 +#: src/ui/dialogs/GamePropertiesDialog.vala:69 +#: src/ui/views/GamesView/AddGamePopover.vala:73 +msgid "Name" +msgstr "Nazwa" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:272 +#: src/ui/dialogs/GamePropertiesDialog.vala:201 +#: src/ui/views/GamesView/AddGamePopover.vala:78 +msgid "Arguments" +msgstr "Argumenty" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:276 +msgid "Variables" +msgstr "Zmienne" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:277 +#, fuzzy +msgid "Game executable" +msgstr "Wybierz plik wykonywalny gry" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:278 +#, fuzzy +msgid "Game arguments" +msgstr "Argumenty" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:80 +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Directory" +msgstr "Katalog" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +msgid "Select emulator directory" +msgstr "Wybierz katalog emulatora" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:292 +#: src/ui/dialogs/GamePropertiesDialog.vala:219 +msgid "Force compatibility mode" +msgstr "Wymuś warstwę kompatybilności" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:307 +#, fuzzy +msgid "Game file patterns" +msgstr "Wybierz plik wykonywalny gry" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:315 +#, fuzzy +msgid "Image" +msgstr "Obrazy" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:318 +#, fuzzy +msgid "Icon" +msgstr "URL ikony" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:325 +msgid "" +"findutils-compatible glob patterns\n" +"\n" +" Multiple patterns can be separated with |\n" +" Start pattern with ./ to match relative path\n" +" $basename variable will be replaced with game's executable " +"name (without extension)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:38 +msgid "Data" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:39 +#, fuzzy +msgid "Providers" +msgstr "Właściwości gry" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:40 +#, fuzzy +msgid "Third-party data providers" +msgstr "Właściwości gry" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:55 +#, fuzzy +msgid "Image providers" +msgstr "Właściwości gry" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:68 +#, fuzzy +msgid "Metadata providers" +msgstr "Właściwości gry" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:137 +msgid "Open website" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:36 +msgid "About" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:71 +#, fuzzy +msgid "Copy application version and environment info" +msgstr "Pokaż wersję aplikacji i wyjdź" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:78 +#: src/ui/views/WelcomeView.vala:57 +msgid "All your games in one place" +msgstr "Wszystkie twoje gry w jednym miejscu" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:92 +msgctxt "about_link" +msgid "Website" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:96 +msgctxt "about_link" +msgid "Source code on GitHub" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:103 +msgctxt "about_link" +msgid "Report a problem" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:104 +#, fuzzy +msgctxt "about_link" +msgid "Suggest translations" +msgstr "Cicha instalacja" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:110 +msgctxt "about_link" +msgid "Issues" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:111 +#, fuzzy +msgctxt "about_link" +msgid "Contributors" +msgstr "Instalator" + +#. TRANSLATORS: Likely it should not be translated. GitHub Pulse is a page that shows recent repository activity: https://github.com/tkashkin/GameHub/pulse +#: src/ui/dialogs/SettingsDialog/pages/About.vala:114 +msgctxt "about_link" +msgid "Pulse" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:115 +msgctxt "about_link" +msgid "Forks" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:109 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:129 +msgid "Import" +msgstr "Importuj" + +#: src/ui/dialogs/InstallDialog.vala:110 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:153 +msgid "Download" +msgstr "Pobierz" + +#: src/ui/dialogs/InstallDialog.vala:207 +msgid "Select installer" +msgstr "Wybierz instalator" + +#: src/ui/dialogs/InstallDialog.vala:216 +#, c-format +msgid "Installer size: %s" +msgstr "Rozmiar instalatora: %s" + +#: src/ui/dialogs/InstallDialog.vala:348 +msgid "Unknown" +msgstr "Nieznany" + +#: src/ui/dialogs/GamePropertiesDialog.vala:49 +#, c-format +msgid "%s: Properties" +msgstr "%s: Właściwości" + +#: src/ui/dialogs/GamePropertiesDialog.vala:84 +msgid "Images" +msgstr "Obrazy" + +#: src/ui/dialogs/GamePropertiesDialog.vala:126 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:160 +#: src/ui/views/GameDetailsView/blocks/Artwork.vala:62 +#, fuzzy +msgid "Download images" +msgstr "Pobieranie" + +#: src/ui/dialogs/GamePropertiesDialog.vala:144 +msgid "Image URL" +msgstr "URL obrazu" + +#: src/ui/dialogs/GamePropertiesDialog.vala:148 +msgid "Vertical image URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:157 +msgid "Icon URL" +msgstr "URL ikony" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +#, fuzzy +msgid "Select working directory" +msgstr "Wybierz katalog" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +#, fuzzy +msgid "Working directory" +msgstr "Otwórz katalog" + +#: src/ui/dialogs/GamePropertiesDialog.vala:214 +msgid "Compatibility" +msgstr "Kompatybilność" + +#: src/ui/dialogs/GamePropertiesDialog.vala:236 +msgid "Launch from terminal" +msgstr "Uruchom z terminala" + +#: src/ui/dialogs/GamePropertiesDialog.vala:252 +msgid "Copy to clipboard" +msgstr "Kopiuj do schowka" + +#: src/ui/dialogs/GamePropertiesDialog.vala:254 +msgid "Add to Steam" +msgstr "Dodaj do Steam" + +#: src/ui/dialogs/GamePropertiesDialog.vala:255 +msgid "Add to the Steam library" +msgstr "Dodaj do biblioteki Steam" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:53 +#, c-format +msgid "%s: Overlays" +msgstr "%s: Nakładki" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "Overlays are disabled" +msgstr "Nakładki są wyłączone" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "" +"Enable overlays to manage DLCs and mods\n" +"\n" +"Enabling will move game to the “base“ overlay" +msgstr "" +"Włącz nakładki aby zarządzać DLC i modami\n" +"\n" +"Aktywacja przeniesie grę do podstawowej nakładki" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:77 +#: src/ui/views/GamesView/GameContextMenu.vala:175 +msgid "Overlays" +msgstr "Nakładki" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:105 +msgid "Overlay ID (directory name)" +msgstr "ID nakładki (nazwa katalogu)" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:110 +msgid "Overlay name (optional)" +msgstr "Nazwa nakładki (opcjonalnie)" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:112 +msgid "Add" +msgstr "Dodaj" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:127 +msgid "Enable overlays" +msgstr "Włącz nakładki" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:182 +#, c-format +msgid "" +"Overlay usage at this path may be unsafe\n" +"Proceed at your own risk\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:187 +#, c-format +msgid "" +"Overlay usage at this path is not supported\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:266 +msgid "Open directory" +msgstr "Otwórz katalog" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:271 +#, fuzzy +msgid "Remove overlay" +msgstr "Włącz nakładki" + +#: src/ui/dialogs/CompatRunDialog.vala:48 +#: src/ui/views/GamesView/GameContextMenu.vala:46 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:235 +msgid "Run with compatibility layer" +msgstr "Uruchom z warstwą kompatybilności" + +#: src/ui/dialogs/CorruptedInstallerDialog.vala:71 +msgid "Corrupted installer: checksum mismatch in" +msgstr "Instalator uszkodzony: sumy kontrolne błędne w" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:57 +#: src/ui/views/GamesView/AddGamePopover.vala:105 +#, fuzzy +msgid "Import emulated games" +msgstr "Brak gier dodanych przez użytkownika" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:75 +#, fuzzy +msgid "Select directory with emulated games" +msgstr "Wybierz katalog" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:83 +#, fuzzy +msgid "Detected games" +msgstr "Brak gier dodanych przez użytkownika" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:107 +#, fuzzy +msgid "Select all" +msgstr "Wybierz instalator" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:115 +#, fuzzy +msgid "Select directory to import" +msgstr "Wybierz katalog" + +#: src/ui/dialogs/GameTweaksDialog.vala:40 +#, fuzzy, c-format +msgid "%s: Tweaks" +msgstr "%s: Nakładki" + +#: src/ui/views/WelcomeView.vala:52 +msgid "No enabled game sources" +msgstr "Brak aktywnych źródeł gry" + +#: src/ui/views/WelcomeView.vala:52 +msgid "Enable some game sources in settings" +msgstr "Włącz niektóre źródła gry w opcjach" + +#: src/ui/views/WelcomeView.vala:57 +msgid "Let's get started" +msgstr "Zacznijmy" + +#: src/ui/views/WelcomeView.vala:71 +msgid "Skip" +msgstr "Pomiń" + +#: src/ui/views/WelcomeView.vala:141 +msgid "Ready" +msgstr "Gotowy" + +#: src/ui/views/WelcomeView.vala:147 +msgid "Authentication required" +msgstr "Uwierzytelnienie wymagane" + +#: src/ui/views/WelcomeView.vala:152 +#, fuzzy +msgid "Authenticating…" +msgstr "Uwierzytelnianie..." + +#: src/ui/views/WelcomeView.vala:163 +#, c-format +msgid "Install %s" +msgstr "Zainstaluj %s" + +#: src/ui/views/WelcomeView.vala:164 +msgid "Return to GameHub after installing" +msgstr "Powróć do GameHub po instalacji" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "No games" +msgstr "Brak gier" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "Get some games or enable some game sources in settings" +msgstr "Zdobądź trochę gier lub aktywuj trochę źródeł gier w opcjach" + +#: src/ui/views/GamesView/GamesView.vala:150 +msgid "Grid view" +msgstr "Widok siatki" + +#: src/ui/views/GamesView/GamesView.vala:151 +msgid "List view" +msgstr "Widok listy" + +#: src/ui/views/GamesView/GamesView.vala:159 +msgid "All games" +msgstr "Wszystkie gry" + +#: src/ui/views/GamesView/GamesView.vala:182 +msgid "Downloads" +msgstr "Pobrane" + +#: src/ui/views/GamesView/GamesView.vala:208 +msgid "Filters" +msgstr "Filtry" + +#: src/ui/views/GamesView/GamesView.vala:216 +#: src/ui/views/GamesView/AddGamePopover.vala:84 +msgid "Add game" +msgstr "Dodaj grę" + +#: src/ui/views/GamesView/GamesView.vala:223 +msgid "Search" +msgstr "Wyszukaj" + +#: src/ui/views/GamesView/GamesView.vala:328 +msgid "Menu" +msgstr "Menu" + +#: src/ui/views/GamesView/GamesView.vala:329 +#: src/ui/views/GameDetailsView/GameDetailsView.vala:104 +msgid "Back" +msgstr "Powrót" + +#: src/ui/views/GamesView/GamesView.vala:550 +#, c-format +msgid "%u game" +msgid_plural "%u games" +msgstr[0] "%u gra" +msgstr[1] "%u gry" +msgstr[2] "%u gier" + +#: src/ui/views/GamesView/GamesView.vala:553 +#, c-format +msgctxt "games_view_subtitle_filtered_games" +msgid "%1$u / %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:557 +#, c-format +msgctxt "games_view_subtitle" +msgid "%1$s: %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:568 +msgid "No user-added games" +msgstr "Brak gier dodanych przez użytkownika" + +#: src/ui/views/GamesView/GamesView.vala:569 +msgid "Add some games using plus button" +msgstr "Dodaj jakieś gry używając przycisku plusa" + +#: src/ui/views/GamesView/GamesView.vala:573 +#, c-format +msgid "No %s games" +msgstr "Brak %s gier" + +#: src/ui/views/GamesView/GamesView.vala:574 +msgid "Get some Linux-compatible games" +msgstr "Zdobądź jakieś gry kompatybilne z Linuksem" + +#: src/ui/views/GamesView/GamesView.vala:584 +#, c-format +msgid "No games matching “%s”" +msgstr "Brak pasujących gier “%s”" + +#: src/ui/views/GamesView/GamesView.vala:589 +#, c-format +msgid "No %1$s games matching “%2$s”" +msgstr "Brak %1$s pasujących gier “%2$s”" + +#: src/ui/views/GamesView/GamesView.vala:627 +msgid "" +"No games were loaded from Steam. Set your games list privacy to public or " +"use your own Steam API key in settings." +msgstr "" +"Gry nie zostały wczytane ze Steam. Ustaw prywatność swojej listy gier na " +"publiczną lub użyj własnego klucza Steam API w opcjach." + +#: src/ui/views/GamesView/GamesView.vala:628 +msgid "Privacy" +msgstr "Prywatność" + +#: src/ui/views/GamesView/GamesView.vala:739 +#, fuzzy +msgid "Downloading images" +msgstr "Pobieranie" + +#: src/ui/views/GamesView/GamesView.vala:753 +#, fuzzy, c-format +msgid "Downloading image: %s" +msgstr "Pobieranie" + +#: src/ui/views/GamesView/DownloadProgressView.vala:131 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:162 +msgid "Pause download" +msgstr "Wstrzymaj pobieranie" + +#: src/ui/views/GamesView/DownloadProgressView.vala:137 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:168 +msgid "Resume download" +msgstr "Wznów pobieranie" + +#: src/ui/views/GamesView/DownloadProgressView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:174 +msgid "Cancel download" +msgstr "Anuluj pobieranie" + +#: src/ui/views/GamesView/FiltersPopover.vala:77 +msgid "Group" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:102 +#, fuzzy +msgid "Sort" +msgstr "Sortuj:" + +#: src/ui/views/GamesView/FiltersPopover.vala:234 +#: src/ui/widgets/GameTagsList.vala:58 +msgid "Tags" +msgstr "Tagi" + +#: src/ui/views/GamesView/FiltersPopover.vala:353 +#, fuzzy +msgid "All platforms" +msgstr "Wszystkie gry" + +#: src/ui/views/GamesView/AddGamePopover.vala:77 +msgid "Select game executable" +msgstr "Wybierz plik wykonywalny gry" + +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Select game directory" +msgstr "Wybierz katalog gry" + +#: src/ui/views/GamesView/AddGamePopover.vala:111 +#, fuzzy +msgid "Download game images" +msgstr "Pobieranie" + +#: src/ui/views/GamesView/GameContextMenu.vala:87 +msgid "Details" +msgstr "Szczegóły" + +#: src/ui/views/GamesView/GameContextMenu.vala:117 +msgctxt "game_context_menu" +msgid "Favorite" +msgstr "Ulubione" + +#: src/ui/views/GamesView/GameContextMenu.vala:121 +msgctxt "game_context_menu" +msgid "Hidden" +msgstr "Ukryte" + +#: src/ui/views/GamesView/GameContextMenu.vala:133 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:236 +msgid "Open installation directory" +msgstr "Otwórz katalog instalacji" + +#: src/ui/views/GamesView/GameContextMenu.vala:142 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:237 +msgid "Open installers collection directory" +msgstr "Otwórz katalog kolekcji instalatorów" + +#: src/ui/views/GamesView/GameContextMenu.vala:151 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:238 +msgid "Open bonus collection directory" +msgstr "Otwórz katalog bonusowej kolekcji" + +#: src/ui/views/GamesView/GameContextMenu.vala:160 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:239 +#, fuzzy +msgid "Open screenshots directory" +msgstr "Otwórz katalog prefiksu" + +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +msgid "Uninstall" +msgstr "Odinstaluj" + +#: src/ui/views/GamesView/GameContextMenu.vala:192 +msgid "Properties" +msgstr "Właściwości" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:100 +#, fuzzy, c-format +msgid "%d game selected" +msgid_plural "%d games selected" +msgstr[0] "%s: niema dostępnych instalatorów" +msgstr[1] "%s: niema dostępnych instalatorów" +msgstr[2] "%s: niema dostępnych instalatorów" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:144 +#, fuzzy, c-format +msgid "%d game will be installed" +msgid_plural "%d games will be installed" +msgstr[0] "%s: niema dostępnych instalatorów" +msgstr[1] "%s: niema dostępnych instalatorów" +msgstr[2] "%s: niema dostępnych instalatorów" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:154 +#, fuzzy, c-format +msgid "%d game will be downloaded" +msgid_plural "%d games will be downloaded" +msgstr[0] "%s: niema dostępnych instalatorów" +msgstr[1] "%s: niema dostępnych instalatorów" +msgstr[2] "%s: niema dostępnych instalatorów" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:161 +#, fuzzy, c-format +msgid "Image for %d game will be searched" +msgid_plural "Images for %d games will be searched" +msgstr[0] "%s: niema dostępnych instalatorów" +msgstr[1] "%s: niema dostępnych instalatorów" +msgstr[2] "%s: niema dostępnych instalatorów" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:168 +#, fuzzy, c-format +msgid "%d game will be uninstalled" +msgid_plural "%d games will be uninstalled" +msgstr[0] "%s: niema dostępnych instalatorów" +msgstr[1] "%s: niema dostępnych instalatorów" +msgstr[2] "%s: niema dostępnych instalatorów" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:174 +msgid "Refresh" +msgstr "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:175 +#, c-format +msgid "" +"%d game will be removed from database. Restart GameHub to fetch new data" +msgid_plural "" +"%d games will be removed from database. Restart GameHub to fetch new data" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:240 +msgid "Open store page" +msgstr "Otwórz stronę sklepu" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:242 +msgid "Game properties" +msgstr "Właściwości gry" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:46 +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:60 +msgid "Playtime" +msgstr "Czas gry" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:52 +msgid "Playtime (local)" +msgstr "Czas gry (lokalny)" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:69 +msgid "Last launch" +msgstr "Ostatnie uruchomienie" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:46 +msgid "Achievements" +msgstr "Osiągnięcia" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:85 +#, c-format +msgid "Unlocked: %s" +msgstr "Odblokowano: %s" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:90 +#, c-format +msgid "Global percentage: %g%%" +msgstr "Globalny odsetek: %g%%" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:77 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:103 +msgid "Language" +msgstr "Język" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:80 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:106 +msgid "Languages" +msgstr "Języki" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:147 +#, fuzzy, c-format +msgid "%u DLCs cannot be installed" +msgstr "%s: uszkodzony instalator" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:71 +msgid "Category" +msgstr "Kategoria" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:74 +msgid "Categories" +msgstr "Kategorie" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:90 +msgid "Genre" +msgstr "Gatunek" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:93 +msgid "Genres" +msgstr "Gatunki" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:109 +msgctxt "igdb" +msgid "Popularity" +msgstr "Popularność" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:115 +msgctxt "igdb" +msgid "Aggregated rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:116 +msgctxt "igdb" +msgid "IGDB user rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:117 +msgctxt "igdb" +msgid "Total rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:126 +msgctxt "igdb" +msgid "Release date" +msgstr "Data wydania" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:133 +#, fuzzy +msgctxt "igdb" +msgid "Platforms" +msgstr "Wszystkie gry" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:139 +#, fuzzy +msgctxt "igdb" +msgid "Genres" +msgstr "Gatunki" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:145 +msgctxt "igdb" +msgid "Keywords" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:152 +msgctxt "igdb" +msgid "Links" +msgstr "Linki" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:208 +#, c-format +msgid "Based on %d rating" +msgid_plural "Based on %d ratings" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:290 +msgctxt "igdb" +msgid "Summary" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:301 +msgctxt "igdb" +msgid "Storyline" +msgstr "" + +#: src/ui/widgets/FileChooserEntry.vala:49 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select file" +msgstr "Wybierz pliki" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +#, fuzzy +msgid "No images" +msgstr "Obrazy" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "" +"There are no images found for this game\n" +"Make sure game name is correct" +msgstr "" +"Nie znaleziono obrazów dla tej gry\n" +"Upewnij się, że nazwa gry jest poprawna" + +#: src/ui/widgets/ImagesDownloadPopover.vala:94 +msgid "Search images:" +msgstr "Wyszukaj grafikę:" + +#: src/ui/widgets/CompatToolPicker.vala:53 +msgid "Compatibility layer:" +msgstr "Warstwa kompatybilności:" + +#: src/ui/widgets/CompatToolPicker.vala:92 +msgid "Configure" +msgstr "Konfiguruj" + +#: src/ui/widgets/GameTagsList.vala:109 +msgid "Add tag" +msgstr "Dodaj tag" + +#: src/ui/widgets/TweaksList.vala:86 +#, fuzzy +msgid "No description" +msgstr "Opis" + +#: src/ui/widgets/TweaksList.vala:124 +#, fuzzy +msgid "Edit file" +msgstr "Wybierz pliki" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dh" +msgstr "%dg" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dm" +msgstr "%dm" + +#: src/utils/Utils.vala:464 +#, fuzzy, c-format +msgctxt "time" +msgid "%ds" +msgstr "%dg" + +#: src/settings/UI.vala:153 +msgctxt "grid_size_preset" +msgid "Steam" +msgstr "" + +#: src/settings/UI.vala:154 +msgctxt "grid_size_preset" +msgid "Steam (vertical)" +msgstr "" + +#: src/settings/UI.vala:155 +msgctxt "grid_size_preset" +msgid "GOG" +msgstr "" + +#: src/settings/UI.vala:156 +msgctxt "grid_size_preset" +msgid "GOG (vertical)" +msgstr "" + +#: src/settings/UI.vala:157 +msgctxt "grid_size_preset" +msgid "Square" +msgstr "" + +#: src/settings/UI.vala:158 +msgctxt "grid_size_preset" +msgid "Custom" +msgstr "" + +#: src/utils/downloader/Downloader.vala:200 +msgctxt "dl_status" +msgid "Queued" +msgstr "W kolejce" + +#: src/utils/downloader/Downloader.vala:201 +msgctxt "dl_status" +msgid "Starting download" +msgstr "Rozpoczynanie pobierania" + +#: src/utils/downloader/Downloader.vala:202 +msgctxt "dl_status" +msgid "Download started" +msgstr "Pobieranie rozpoczęte" + +#: src/utils/downloader/Downloader.vala:203 +msgctxt "dl_status" +msgid "Download finished" +msgstr "Pobieranie zakończone" + +#: src/utils/downloader/Downloader.vala:204 +msgctxt "dl_status" +msgid "Download failed" +msgstr "Niepowodzenie pobierania" + +#: src/utils/downloader/Downloader.vala:208 +#, fuzzy, c-format +msgctxt "dl_status" +msgid "Downloading: %s" +msgstr "Pobieranie" + +#: src/utils/downloader/Downloader.vala:210 +#, fuzzy +msgctxt "dl_status" +msgid "Downloading" +msgstr "Pobieranie" + +#: src/utils/downloader/Downloader.vala:214 +#, fuzzy, c-format +msgctxt "dl_status" +msgid "Paused: %s" +msgstr "Wstrzymano: %d%% (%s / %s)" + +#: src/utils/downloader/Downloader.vala:216 +#, fuzzy +msgctxt "dl_status" +msgid "Paused" +msgstr "Wstrzymaj pobieranie" + +#: src/utils/downloader/Downloader.vala:218 +msgctxt "dl_status" +msgid "Download cancelled" +msgstr "Pobieranie anulowane" + +#. TRANSLATORS: Download progress template. %1$d - percentage, %2$s / %3$s - downloaded portion and total file size, %4$s - download speed +#: src/utils/downloader/Downloader.vala:262 +#, fuzzy, c-format +msgctxt "dl_status" +msgid "%1$d%% (%2$s / %3$s) [%4$s/s]" +msgstr "Pobieranie: %d%% (%s / %s) [%s/s]" + +#~ msgid "Disable esync" +#~ msgstr "Wyłącz esync" + +#~ msgid "Force LARGE_ADDRESS_AWARE flag" +#~ msgstr "Wymuś LARGE_ADDRESS_AWARE flagę" + +#~ msgid "Disable DirectX 11 compatibility layer" +#~ msgstr "Wyłącz warstwę kompatybilności z DirectX 11" + +#~ msgid "Use WineD3D11 as DirectX 11 compatibility layer" +#~ msgstr "Użyj WineD3D11 jako warstwy kompatybilności z DirectX 11" + +#~ msgid "Show DXVK info overlay" +#~ msgstr "Pokaż nakładkę informacyjną DXVK" + +#, fuzzy +#~ msgid "Enable DirectX 9 compatibility layer" +#~ msgstr "Wyłącz warstwę kompatybilności z DirectX 11" + +#~ msgid "Silent installation" +#~ msgstr "Cicha instalacja" + +#~ msgid "Very silent installation" +#~ msgstr "Bardzo cicha instalacja" + +#~ msgid "Suppress messages" +#~ msgstr "Ukryj wiadomości" + +#~ msgid "No GUI" +#~ msgstr "Bez GUI" + +#~ msgid "Disable fullscreen" +#~ msgstr "Wyłącz pełen ekran" + +#~ msgid "Windowed" +#~ msgstr "W oknie" + +#~ msgid "Compact list" +#~ msgstr "Podręczna lista" + +#~ msgid "Show non-native games" +#~ msgstr "Pokaż nienatywne gry" + +#~ msgid "Use compatibility layers and consider Windows games compatible" +#~ msgstr "" +#~ "Użyj warstwy kompatybilności i traktuj gry dla Windows jako kompatybilne" + +#~ msgid "Use symbolic icons instead of colored icons" +#~ msgstr "Używaj symbolicznych ikon zamiast kolorowych" + +#~ msgid "Reload" +#~ msgstr "Wczytaj ponownie" + +#~ msgid "Updating game info" +#~ msgstr "Uaktualnianie informacji o grze" + +#~ msgid "Updating %s game info" +#~ msgstr "Uaktualnianie %s informacji o grze" diff --git a/po/pt_BR.po b/po/pt_BR.po new file mode 100644 index 00000000..6bc56731 --- /dev/null +++ b/po/pt_BR.po @@ -0,0 +1,1915 @@ +# Portuguese translations for com.github.tkashkin.gamehub package. +# Copyright (C) 2018 THE com.github.tkashkin.gamehub'S COPYRIGHT HOLDER +# This file is distributed under the same license as the com.github.tkashkin.gamehub package. +# Automatically generated, 2018. +# Leandro Stanger , 2019. +# Kassin Dornelles , 2019. +# Anatoliy Kashkin , 2019. +# Wilker Santana da Silva , 2019, 2020. +# Wellington Terumi Uemura , 2020. +msgid "" +msgstr "" +"Project-Id-Version: com.github.tkashkin.gamehub\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-26 06:40+0300\n" +"PO-Revision-Date: 2020-04-03 12:21+0000\n" +"Last-Translator: Wilker Santana da Silva \n" +"Language-Team: Portuguese (Brazil) \n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 4.0-dev\n" + +#: src/app.vala:91 +msgid "Show help" +msgstr "Mostrar ajuda" + +#: src/app.vala:92 +msgid "Show application version and exit" +msgstr "Mostrar versão do aplicativo e sair" + +#: src/app.vala:93 +msgid "Restart with GDB debugger attached" +msgstr "Reiniciar com o depurador do GDB vinculado" + +#: src/app.vala:94 +msgid "Show full GDB backtrace" +msgstr "Mostrar registro completo do GDB" + +#: src/app.vala:95 +msgid "Treat fatal errors as criticals and crash application" +msgstr "Tratar erros fatais como críticos e fechar a aplicação" + +#: src/app.vala:99 +msgid "Show main window" +msgstr "Mostrar janela principal" + +#: src/app.vala:100 +msgid "Show application settings dialog" +msgstr "Mostrar diálogo de opções do aplicativo" + +#: src/app.vala:101 +msgid "Show about dialog" +msgstr "Mostrar o dialogo de \"Sobre\"" + +#: src/app.vala:102 +msgid "Maximum number of background worker threads" +msgstr "Número máximo de threads em trabalho em segundo plano" + +#: src/app.vala:106 +msgid "Run game" +msgstr "Executar o jogo" + +#: src/app.vala:107 +msgid "Show compatibility options dialog" +msgstr "Mostrar caixa de diálogo de opções de compatibilidade" + +#: src/app.vala:108 +msgid "Open game details" +msgstr "Abrir detalhes do jogo" + +#: src/app.vala:109 +msgid "Open game properties" +msgstr "Abrir propriedades do jogo" + +#: src/app.vala:113 +msgid "Enable debug logging" +msgstr "Ativar log de depuração" + +#: src/app.vala:114 +msgid "" +"Log authentication process and sensitive information like authentication " +"tokens" +msgstr "" +"Registrar processo de autenticação e informações sensíveis como tokens de " +"autenticação" + +#: src/app.vala:115 +msgid "Log download manager" +msgstr "Log do gerenciador de download" + +#: src/app.vala:116 +msgid "Log background workers start/stop" +msgstr "Registrar trabalhadores de fundo iniciar/parar" + +#: src/app.vala:117 +msgid "Disable log messages filtering" +msgstr "Desativar filtro de registro de mensagens" + +#: src/app.vala:118 +msgid "Verbose logging" +msgstr "Registro detalhado" + +#: src/app.vala:247 +msgid "Game Options:" +msgstr "Opções do Jogo:" + +#: src/app.vala:247 +msgid "Show game options help" +msgstr "Mostrar ajuda de opções de jogo" + +#: src/app.vala:255 +msgid "Logging Options:" +msgstr "Opções de Logs:" + +#: src/app.vala:255 +msgid "Show logging options help" +msgstr "Mostrar ajuda sobre logs" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +msgid "Select executable" +msgstr "Selecione o executável" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:181 src/ui/views/GamesView/GamesView.vala:330 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select" +msgstr "Selecione" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:180 src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Cancel" +msgstr "Cancelar" + +#: src/data/Runnable.vala:166 src/ui/widgets/FileChooserEntry.vala:49 +msgid "Select directory" +msgstr "Selecione o diretório" + +#: src/data/Runnable.vala:619 +#, c-format +msgid "Part %1$u of %2$u: %3$s" +msgstr "Parte %1$u de %2$u: %3$s" + +#: src/data/Runnable.vala:642 src/ui/dialogs/CorruptedInstallerDialog.vala:48 +#, c-format +msgid "%s: corrupted installer" +msgstr "%s: instalador corrompido" + +#: src/data/Runnable.vala:643 +#, c-format +msgid "Checksum mismatch in %s" +msgstr "Incompatibilidade de soma de verificação em %s" + +#: src/data/Runnable.vala:657 src/ui/dialogs/CorruptedInstallerDialog.vala:126 +msgid "Show file" +msgstr "Exibir arquivo" + +#: src/data/Runnable.vala:658 src/ui/dialogs/CorruptedInstallerDialog.vala:132 +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#: src/ui/widgets/TagRow.vala:146 +msgid "Remove" +msgstr "Remover" + +#: src/data/Runnable.vala:659 src/ui/dialogs/CorruptedInstallerDialog.vala:128 +msgid "Backup" +msgstr "Cópia de segurança" + +#: src/data/Runnable.vala:778 +#, c-format +msgid "%s: cannot detect main executable" +msgstr "%s: não foi possível detectar o executável principal" + +#: src/data/Runnable.vala:779 +msgid "" +"Main executable file for this game cannot be detected automatically.\n" +"Please set main executable in game's properties." +msgstr "" +"O arquivo executável principal deste jogo não pode ser detectado " +"automaticamente.\n" +"Por favor, defina o executável principal nas propriedades do jogo." + +#: src/data/Runnable.vala:908 +msgctxt "platform" +msgid "Emulated" +msgstr "Emulado" + +#: src/data/Game.vala:625 +msgctxt "status" +msgid "Running" +msgstr "Correndo" + +#: src/data/Game.vala:628 +msgctxt "status" +msgid "Installed" +msgstr "Instalado" + +#: src/data/Game.vala:629 +msgctxt "status" +msgid "Installing" +msgstr "Instalando" + +#: src/data/Game.vala:630 +msgctxt "status" +msgid "Verifying installer integrity" +msgstr "Verificando a integridade do instalador" + +#: src/data/Game.vala:631 +msgctxt "status" +msgid "Download started" +msgstr "Download iniciado" + +#: src/data/Game.vala:633 +msgctxt "status" +msgid "Not installed" +msgstr "Não instalado" + +#: src/data/Game.vala:643 +msgctxt "status_header" +msgid "Installed" +msgstr "Instalado" + +#: src/data/Game.vala:644 +msgctxt "status_header" +msgid "Installing" +msgstr "Instalando" + +#: src/data/Game.vala:646 +msgctxt "status_header" +msgid "Downloading" +msgstr "Baixando" + +#: src/data/Game.vala:648 +msgctxt "status_header" +msgid "Not installed" +msgstr "Não instalado" + +#: src/data/GameSource.vala:31 +#, c-format +msgid "%s games" +msgstr "%s jogos" + +#: src/data/sources/steam/Steam.vala:43 +msgid "Your SteamID will be read from Steam configuration file" +msgstr "Seu SteamID será lido a partir do arquivo de configuração do Steam" + +#: src/data/sources/steam/Steam.vala:46 +msgid "" +"Steam config file not found.\n" +"Login into your account in Steam client and return to GameHub" +msgstr "" +"Arquivo de configuração do Steam não encontrado.\n" +"Entre na sua conta no cliente Steam e retorne ao GameHub" + +#: src/data/sources/gog/GOGGame.vala:983 +#, c-format +msgid "DLC: %s" +msgstr "DLC: %s" + +#: src/data/sources/humble/HumbleGame.vala:343 +#, c-format +msgid "%s: no available installers" +msgstr "%s: instaladores não disponíveis" + +#: src/data/sources/humble/HumbleGame.vala:344 +msgid "" +"Cannot get Trove download URL.\n" +"Make sure your Humble Monthly subscription is active." +msgstr "" +"Não é possível obter o URL de download do Trove.\n" +"Certifique-se de que sua assinatura do Humble Monthly esteja ativa." + +#: src/data/sources/itch/ItchDownloader.vala:192 +#, c-format +msgctxt "itch_dl_status" +msgid "%s left;" +msgstr "%s esquerda;" + +#: src/data/sources/itch/ItchDownloader.vala:195 +#, c-format +msgctxt "itch_dl_status" +msgid "%d%%" +msgstr "%d%%" + +#: src/data/sources/itch/ItchDownloader.vala:198 +#, c-format +msgctxt "itch_dl_status" +msgid "(%1$s / %2$s)" +msgstr "(%1$s / %2$s)" + +#: src/data/sources/itch/ItchDownloader.vala:201 +#, c-format +msgctxt "itch_dl_status" +msgid "[%s/s]" +msgstr "[%s/s]" + +#: src/data/sources/user/User.vala:30 +msgid "User games" +msgstr "Jogos do usuário" + +#: src/data/db/tables/Tags.vala:225 +msgctxt "tag" +msgid "Favorites" +msgstr "Favoritos" + +#: src/data/db/tables/Tags.vala:226 +msgctxt "tag" +msgid "Not installed" +msgstr "Não instalado" + +#: src/data/db/tables/Tags.vala:227 +msgctxt "tag" +msgid "Installed" +msgstr "Instalado" + +#: src/data/db/tables/Tags.vala:228 +msgctxt "tag" +msgid "Hidden" +msgstr "Escondido" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit script" +msgstr "Editar script" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit custom script" +msgstr "Editar script personalizado" + +#: src/data/compat/Innoextract.vala:55 +#, c-format +msgid "" +"Innoextract %1$s is not supported and may not be able to extract some " +"games correctly.\n" +"Install innoextract %2$s or newer." +msgstr "" +"O Innoextract %1$s não é suportado e pode não conseguir extrair " +"alguns jogos corretamente.\n" +"Instale o innoextract %2$s ou mais recente." + +#: src/data/compat/WineWrap.vala:61 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:242 +#: src/ui/dialogs/CompatRunDialog.vala:102 +#: src/ui/views/GamesView/GameContextMenu.vala:53 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:234 +msgid "Run" +msgstr "Jogar" + +#: src/data/compat/WineWrap.vala:64 +msgid "Show WineWrap menu" +msgstr "Mostrar menu do WineWrap" + +#: src/data/compat/WineWrap.vala:67 src/data/compat/Proton.vala:122 +#: src/data/compat/Wine.vala:83 +msgid "Kill apps in prefix" +msgstr "Mate aplicativos no prefixo" + +#: src/data/compat/Proton.vala:47 +msgid "Proton prefix" +msgstr "Prefixo do Proton" + +#: src/data/compat/Proton.vala:110 src/data/compat/Wine.vala:71 +msgid "Open prefix directory" +msgstr "Abrir diretório de prefixo" + +#: src/data/compat/Proton.vala:113 src/data/compat/Wine.vala:74 +msgid "Run winecfg" +msgstr "Executar winecfg" + +#: src/data/compat/Proton.vala:116 src/data/compat/Wine.vala:77 +msgid "Run winetricks" +msgstr "Executar winetricks" + +#: src/data/compat/Proton.vala:119 src/data/compat/Wine.vala:80 +msgid "Run taskmgr" +msgstr "Executar taskmgr" + +#: src/data/compat/Wine.vala:53 +msgid "Wine prefix" +msgstr "Prefixo do wine" + +#: src/data/compat/Wine.vala:55 +msgid "Environment variables" +msgstr "Variáveis ambientais" + +#: src/data/compat/Wine.vala:60 +msgid "InnoSetup default options" +msgstr "Opções padrão do InnoSetup" + +#: src/data/compat/RetroArch.vala:53 +msgid "Libretro core file" +msgstr "Arquivo principal do Libretro" + +#: src/data/compat/CustomEmulator.vala:43 +msgid "Custom emulator" +msgstr "Emulador personalizado" + +#: src/data/compat/CustomEmulator.vala:48 +msgid "Emulator" +msgstr "Emulador" + +#: src/data/compat/CustomEmulator.vala:49 +msgid "Launch in game directory" +msgstr "Lançamento no diretório do jogo" + +#: src/data/adapters/GamesAdapter.vala:440 +msgctxt "status_header" +msgid "Favorites" +msgstr "Favoritos" + +#: src/data/adapters/GamesAdapter.vala:445 +#, c-format +msgctxt "status_header" +msgid "%s: Favorites" +msgstr "%s: Favoritos" + +#: src/data/adapters/GamesAdapter.vala:491 +msgid "Merging games" +msgstr "Mesclando jogos" + +#: src/data/adapters/GamesAdapter.vala:504 +#, c-format +msgid "Merging games from %s" +msgstr "Mesclando jogos de %s" + +#: src/data/adapters/GamesAdapter.vala:551 +#, c-format +msgid "Loading games from %s" +msgstr "Carregando jogos de %s" + +#: src/data/adapters/GamesAdapter.vala:678 +msgctxt "sort_mode" +msgid "By name" +msgstr "Por nome" + +#: src/data/adapters/GamesAdapter.vala:679 +msgctxt "sort_mode" +msgid "By last launch" +msgstr "Pelo último lançamento" + +#: src/data/adapters/GamesAdapter.vala:680 +msgctxt "sort_mode" +msgid "By playtime" +msgstr "Por tempo jogado" + +#: src/data/adapters/GamesAdapter.vala:705 +msgctxt "group_mode" +msgid "Do not group" +msgstr "Não agrupar" + +#: src/data/adapters/GamesAdapter.vala:706 +msgctxt "group_mode" +msgid "By status" +msgstr "Por status" + +#: src/data/adapters/GamesAdapter.vala:707 +msgctxt "group_mode" +msgid "By source" +msgstr "Por fonte" + +#: src/data/providers/images/SteamGridDB.vala:151 +#: src/data/providers/data/IGDB.vala:431 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:217 +msgid "Default" +msgstr "Padrão" + +#: src/data/providers/images/SteamGridDB.vala:158 +#: src/data/providers/data/IGDB.vala:438 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:225 +msgid "Restore default API key" +msgstr "Restaurar chave de API padrão" + +#: src/data/providers/images/SteamGridDB.vala:169 +#: src/data/providers/data/IGDB.vala:449 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:108 +msgid "API key" +msgstr "Chave de API" + +#: src/data/providers/images/SteamGridDB.vala:177 +#: src/data/providers/data/IGDB.vala:457 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:53 +msgid "Generate key" +msgstr "Gerar chave" + +#: src/data/providers/images/SteamGridDB.vala:208 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Style" +msgstr "Estilo" + +#: src/data/providers/images/SteamGridDB.vala:209 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Score" +msgstr "Pontuação" + +#: src/data/providers/images/SteamGridDB.vala:213 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Author" +msgstr "Autor" + +#: src/data/providers/images/SteamGridDB.vala:225 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Alternate" +msgstr "Alternado" + +#: src/data/providers/images/SteamGridDB.vala:226 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Blurred" +msgstr "Borrado" + +#. TRANSLATORS: Flat / Material Design image style. Probably should not be translated +#: src/data/providers/images/SteamGridDB.vala:228 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Material" +msgstr "Material" + +#: src/data/providers/images/SteamGridDB.vala:229 +msgctxt "imagesource_steamgriddb_image_style" +msgid "No logo" +msgstr "Sem logotipo" + +#: src/data/providers/images/SteamGridDB.vala:230 +msgctxt "imagesource_steamgriddb_image_style" +msgid "White logo" +msgstr "Logomarca branca" + +#: src/data/providers/data/IGDB.vala:147 +msgid "" +"Monthly IGDB request quota has been reached. Set your own API key to use " +"IGDB data or disable IGDB." +msgstr "" +"Cota mensal de pedidos do IGDB foi alcançada. Defina sua própria chave de " +"API para usar dados do IGDB ou desative IGDB." + +#: src/data/providers/data/IGDB.vala:148 +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:40 +#: src/ui/views/WelcomeView.vala:53 src/ui/views/WelcomeView.vala:78 +#: src/ui/views/GamesView/GamesView.vala:230 +#: src/ui/views/GamesView/GamesView.vala:629 +msgid "Settings" +msgstr "Configurações" + +#: src/data/providers/data/IGDB.vala:356 +msgctxt "igdb_related_link" +msgid "Official website" +msgstr "Website oficial" + +#: src/data/providers/data/IGDB.vala:469 +msgctxt "igdb_preferred_description" +msgid "When game has description, show description" +msgstr "Quando o jogo tem descrição, mostra a descrição" + +#: src/data/providers/data/IGDB.vala:476 +msgctxt "igdb_preferred_description" +msgid "of game" +msgstr "do jogo" + +#: src/data/providers/data/IGDB.vala:477 +msgctxt "igdb_preferred_description" +msgid "from IGDB" +msgstr "do IGDB" + +#: src/data/providers/data/IGDB.vala:478 +msgctxt "igdb_preferred_description" +msgid "both" +msgstr "ambos" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:65 +msgid "Some settings will be applied after application restart" +msgstr "" +"Algumas configurações serão aplicadas após a reinicialização do aplicativo" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:71 +msgid "Games directory contains space. It may cause problems for some games" +msgstr "" +"Diretório de jogos contém espaço. Isso pode causar problemas para alguns " +"jogos" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:36 +msgid "Interface" +msgstr "Interface" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:37 +msgid "Appearance" +msgstr "Aparência" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:38 +msgid "General interface settings" +msgstr "Configurações gerais da interface" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:48 +msgid "Dark theme" +msgstr "Tema escuro" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:53 +msgctxt "icon_style" +msgid "Theme-based" +msgstr "Baseado no tema" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:54 +msgctxt "icon_style" +msgid "Symbolic" +msgstr "Simbólico" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:55 +msgctxt "icon_style" +msgid "Colored" +msgstr "Colorido" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:57 +msgctxt "icon_style" +msgid "Icon style" +msgstr "Estilo de ícone" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:84 +msgid "Game card" +msgstr "Cartão de jogo" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:86 +msgid "Show platform icons" +msgstr "Mostrar ícones de plataforma" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:99 +msgctxt "grid_size" +msgid "Card size" +msgstr "Tamanho do cartão" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:117 +msgctxt "grid_size_preset" +msgid "Presets" +msgstr "Pré-definições" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:139 +msgid "Games list: installed" +msgstr "Lista de jogos: instalados" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:140 +msgid "Games list: not installed" +msgstr "Lista de jogos: não instalados" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:142 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:146 +msgctxt "list_style" +msgid "Show icon" +msgstr "Exibir ícone" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:143 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:147 +msgctxt "list_style" +msgid "Bold title" +msgstr "Título em negrito" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:144 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:148 +msgctxt "list_style" +msgid "Show status" +msgstr "Exibir status" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:149 +msgctxt "list_style" +msgid "Dim" +msgstr "Escura" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:151 +msgid "Grid options" +msgstr "Opções de grade" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:152 +msgid "List options" +msgstr "Opções de lista" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:31 +msgid "Behavior" +msgstr "Comportamento" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:32 +msgid "Behavior settings" +msgstr "Configurações de comportamento" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:42 +msgid "Run games with double click" +msgstr "Executar jogos com duplo clique" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:46 +msgid "Merge games from different sources" +msgstr "Mesclar jogos de diferentes fontes" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:50 +msgid "Use imported tags" +msgstr "Use tags importadas" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:51 +msgid "General" +msgstr "Geral" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:52 +msgid "Collection" +msgstr "Coleção" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:53 +msgid "Empty" +msgstr "Vazio" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:65 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:85 +msgid "Collection directory" +msgstr "Diretório de coleção" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:70 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:78 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:87 +msgid "Game directory" +msgstr "Diretório de jogos" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:71 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:79 +msgid "Installers" +msgstr "Instaladores" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:72 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:98 +msgid "DLC" +msgstr "DLC" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:73 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:197 +msgid "Bonus content" +msgstr "Conteúdo de bônus" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:84 +msgid "Variable syntax: $var or ${var}" +msgstr "Syntax de variável: $var ou ${var}" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:86 +msgid "Game name" +msgstr "Nome do jogo" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:88 +#: src/ui/views/GamesView/FiltersPopover.vala:127 +msgid "Platform" +msgstr "Plataforma" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:36 +msgid "Controller" +msgstr "Controle" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +msgid "Enabled" +msgstr "Ativado" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:53 +msgid "Focus GameHub window with Guide button" +msgstr "Dar foco à janela do GameHub com o botão Guia" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:57 +msgid "Controllers" +msgstr "Controles" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:89 +msgid "Move focus" +msgstr "Mover foco" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:91 +msgid "Exit" +msgstr "Sair" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:40 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:108 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:92 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:95 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:36 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:77 +msgid "Disabled" +msgstr "Desativado" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:47 +#: src/ui/dialogs/GameTweaksDialog.vala:53 +#: src/ui/views/GamesView/GameContextMenu.vala:183 +msgid "Tweaks" +msgstr "Ajustes" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:34 +msgid "Tweak launch options and apply them to games automatically" +msgstr "Ajuste as opções de lançamento e aplique-as aos jogos automaticamente" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:79 +msgid "" +"Tweaks are loaded from following directories in order\n" +"Last tweak overrides previous tweaks with same identifiers" +msgstr "" +"Os ajustes são carregados a partir dos seguintes diretórios em ordem\n" +"O último ajuste substitui os ajustes anteriores com os mesmos identificadores" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:83 +msgid "Click to open" +msgstr "Clique para abrir" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:93 +#, c-format +msgid "Tweaks are loaded from %1$s and %2$d more directories (?)" +msgstr "" +"Os ajustes são carregados a partir de %1$s e %2$d em conjunto com os " +"diretórios (?)" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:38 +msgid "Game sources" +msgstr "Fontes de jogos" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +msgid "Steam API keys have limited number of uses per day" +msgstr "" +"As chaves da API do Steam têm um número limitado de utilizações por dia" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:63 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:57 +msgid "Installation directory" +msgstr "Diretório de instalação" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:176 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:81 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:34 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:75 +msgid "Not installed" +msgstr "Não instalado" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:116 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:96 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:99 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:85 +msgid "Not authenticated" +msgstr "Não autenticado" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +#, c-format +msgid "Authenticated as %s" +msgstr "Autenticado(a) como %s" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:103 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +msgid "Authenticated" +msgstr "Autenticado" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:183 +#: src/ui/dialogs/InstallDialog.vala:53 src/ui/dialogs/InstallDialog.vala:111 +#: src/ui/views/GamesView/GameContextMenu.vala:80 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:233 +#: src/ui/widgets/TweaksList.vala:95 +msgid "Install" +msgstr "Instalar" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:236 +msgid "Steam API key" +msgstr "Chave da API do Steam" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:50 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:54 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:48 +msgid "Games directory" +msgstr "Diretório de jogos" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:63 +msgid "Logout" +msgstr "Sair" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:50 +msgid "Load games from Humble Trove" +msgstr "Carregar jogos de Humble Trove" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:45 +msgid "Emulators" +msgstr "Emuladores" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:45 +msgid "Libretro core directory" +msgstr "Diretório do núcleo do Libretro" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:46 +msgid "Libretro core info directory" +msgstr "Diretório de informações do núcleo do Libretro" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:50 +msgid "Ignored libretro cores" +msgstr "Ignorados núcleos de Libretro" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:54 +msgid "Ignored game file extensions" +msgstr "Extenções de arquivos de jogos ignoradas" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:66 +msgid "No cores found" +msgstr "Nenhum núcleo encontrado" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:70 +#, c-format +msgid "%u core found" +msgid_plural "%u cores found" +msgstr[0] "%u núcleo encontrado" +msgstr[1] "%u núcleos encontrados" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:46 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:168 +msgid "No custom emulators" +msgstr "Nenhum emulador personalizado" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:164 +#, c-format +msgid "%u custom emulator" +msgid_plural "%u custom emulators" +msgstr[0] "%u Emulador personalizado" +msgstr[1] "%u Emuladores personalizados" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:237 +msgid "Save" +msgstr "Salve" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:250 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:312 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/dialogs/GamePropertiesDialog.vala:168 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +#: src/ui/views/GamesView/AddGamePopover.vala:67 +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Executable" +msgstr "Executável" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:251 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/views/GamesView/AddGamePopover.vala:68 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Installer" +msgstr "Instalar" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:256 +#: src/ui/dialogs/GamePropertiesDialog.vala:64 +#: src/ui/dialogs/GamePropertiesDialog.vala:69 +#: src/ui/views/GamesView/AddGamePopover.vala:73 +msgid "Name" +msgstr "Nome" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:272 +#: src/ui/dialogs/GamePropertiesDialog.vala:201 +#: src/ui/views/GamesView/AddGamePopover.vala:78 +msgid "Arguments" +msgstr "Argumentos" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:276 +msgid "Variables" +msgstr "Variáveis" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:277 +msgid "Game executable" +msgstr "Executável do jogo" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:278 +msgid "Game arguments" +msgstr "Argumentos do jogo" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:80 +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Directory" +msgstr "Diretório" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +msgid "Select emulator directory" +msgstr "Selecione o diretório do emulador" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:292 +#: src/ui/dialogs/GamePropertiesDialog.vala:219 +msgid "Force compatibility mode" +msgstr "Forçar o modo de compatibilidade" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:307 +msgid "Game file patterns" +msgstr "Sequências de arquivos de jogos" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:315 +msgid "Image" +msgstr "Imagem" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:318 +msgid "Icon" +msgstr "Ícone" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:325 +msgid "" +"findutils-compatible glob patterns\n" +"\n" +" Multiple patterns can be separated with |\n" +" Start pattern with ./ to match relative path\n" +" $basename variable will be replaced with game's executable " +"name (without extension)" +msgstr "" +"Sequências de glob compatíveis com findutils\n" +"\n" +" Várias sequências podem ser combinadas com |\n" +" Inicie sequência com ./ para referenciar um caminho " +"relativo\n" +" A variável $basename será substituída pelo nome do " +"executável do jogo (sem extensão)" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:38 +msgid "Data" +msgstr "Dados" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:39 +msgid "Providers" +msgstr "Provedores" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:40 +msgid "Third-party data providers" +msgstr "Provedores de dados de terceiros" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:55 +msgid "Image providers" +msgstr "Provedores de imagens" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:68 +msgid "Metadata providers" +msgstr "Provedores de metadados" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:137 +msgid "Open website" +msgstr "Abrir website" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:36 +msgid "About" +msgstr "Sobre" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:71 +msgid "Copy application version and environment info" +msgstr "Copiar versão do aplicativo e informações do ambiente" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:78 +#: src/ui/views/WelcomeView.vala:57 +msgid "All your games in one place" +msgstr "Todos os seus jogos em um só lugar" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:92 +msgctxt "about_link" +msgid "Website" +msgstr "Website" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:96 +msgctxt "about_link" +msgid "Source code on GitHub" +msgstr "Código-fonte no Github" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:103 +msgctxt "about_link" +msgid "Report a problem" +msgstr "Relatar um problema" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:104 +msgctxt "about_link" +msgid "Suggest translations" +msgstr "Surgerir traduções" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:110 +msgctxt "about_link" +msgid "Issues" +msgstr "Questões" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:111 +msgctxt "about_link" +msgid "Contributors" +msgstr "Contribuidores" + +#. TRANSLATORS: Likely it should not be translated. GitHub Pulse is a page that shows recent repository activity: https://github.com/tkashkin/GameHub/pulse +#: src/ui/dialogs/SettingsDialog/pages/About.vala:114 +msgctxt "about_link" +msgid "Pulse" +msgstr "Pulso" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:115 +msgctxt "about_link" +msgid "Forks" +msgstr "Garfos" + +#: src/ui/dialogs/InstallDialog.vala:109 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:129 +msgid "Import" +msgstr "Importar" + +#: src/ui/dialogs/InstallDialog.vala:110 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:153 +msgid "Download" +msgstr "Transferências" + +#: src/ui/dialogs/InstallDialog.vala:207 +msgid "Select installer" +msgstr "Selecione o instalador" + +#: src/ui/dialogs/InstallDialog.vala:216 +#, c-format +msgid "Installer size: %s" +msgstr "Tamanho do instalador: %s" + +#: src/ui/dialogs/InstallDialog.vala:348 +msgid "Unknown" +msgstr "Desconhecido" + +#: src/ui/dialogs/GamePropertiesDialog.vala:49 +#, c-format +msgid "%s: Properties" +msgstr "%s: Propriedades" + +#: src/ui/dialogs/GamePropertiesDialog.vala:84 +msgid "Images" +msgstr "Imagens" + +#: src/ui/dialogs/GamePropertiesDialog.vala:126 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:160 +#: src/ui/views/GameDetailsView/blocks/Artwork.vala:62 +msgid "Download images" +msgstr "Baixar imagens" + +#: src/ui/dialogs/GamePropertiesDialog.vala:144 +msgid "Image URL" +msgstr "URL da imagem" + +#: src/ui/dialogs/GamePropertiesDialog.vala:148 +msgid "Vertical image URL" +msgstr "URL vertical da imagem" + +#: src/ui/dialogs/GamePropertiesDialog.vala:157 +msgid "Icon URL" +msgstr "URL do ícone" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Select working directory" +msgstr "Selecione o diretório de trabalho" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Working directory" +msgstr "Diretório de trabalho" + +#: src/ui/dialogs/GamePropertiesDialog.vala:214 +msgid "Compatibility" +msgstr "Compatibilidade" + +#: src/ui/dialogs/GamePropertiesDialog.vala:236 +msgid "Launch from terminal" +msgstr "Lançamento do terminal" + +#: src/ui/dialogs/GamePropertiesDialog.vala:252 +msgid "Copy to clipboard" +msgstr "Copiar para área de transferência" + +#: src/ui/dialogs/GamePropertiesDialog.vala:254 +msgid "Add to Steam" +msgstr "Adicionar ao Steam" + +#: src/ui/dialogs/GamePropertiesDialog.vala:255 +msgid "Add to the Steam library" +msgstr "Adicionar à biblioteca do Steam" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:53 +#, c-format +msgid "%s: Overlays" +msgstr "%s: Sobreposições" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "Overlays are disabled" +msgstr "As sobreposições estão desativadas" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "" +"Enable overlays to manage DLCs and mods\n" +"\n" +"Enabling will move game to the “base“ overlay" +msgstr "" +"Ativar sobreposições para gerenciar DLCs e mods\n" +"\n" +"Ativar moverá o jogo para a sobreposição de “base”" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:77 +#: src/ui/views/GamesView/GameContextMenu.vala:175 +msgid "Overlays" +msgstr "Sobreposições" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:105 +msgid "Overlay ID (directory name)" +msgstr "ID de sobreposição (nome do diretório)" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:110 +msgid "Overlay name (optional)" +msgstr "Nome da sobreposição (opcional)" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:112 +msgid "Add" +msgstr "Adicionar" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:127 +msgid "Enable overlays" +msgstr "Ativar sobreposições" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:182 +#, c-format +msgid "" +"Overlay usage at this path may be unsafe\n" +"Proceed at your own risk\n" +"\n" +"Path: %s" +msgstr "" +"O uso de sobreposições neste caminho pode ser inseguro\n" +"Prossiga por sua conta e risco\n" +"\n" +"Caminho: %s" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:187 +#, c-format +msgid "" +"Overlay usage at this path is not supported\n" +"\n" +"Path: %s" +msgstr "" +"O uso de sobreposições neste caminho não é suportado\n" +"\n" +"Caminho: %s" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:266 +msgid "Open directory" +msgstr "Diretório aberto" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:271 +msgid "Remove overlay" +msgstr "Remover sobreposições" + +#: src/ui/dialogs/CompatRunDialog.vala:48 +#: src/ui/views/GamesView/GameContextMenu.vala:46 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:235 +msgid "Run with compatibility layer" +msgstr "Jogar com camada de compatibilidade do Windows" + +#: src/ui/dialogs/CorruptedInstallerDialog.vala:71 +msgid "Corrupted installer: checksum mismatch in" +msgstr "Instalador corrompido: incompatibilidade de soma de verificação em" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:57 +#: src/ui/views/GamesView/AddGamePopover.vala:105 +msgid "Import emulated games" +msgstr "Importar jogos emulados" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:75 +msgid "Select directory with emulated games" +msgstr "Selecionar diretório com jogos emulados" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:83 +msgid "Detected games" +msgstr "Jogos detectados" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:107 +msgid "Select all" +msgstr "Selecionar tudo" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:115 +msgid "Select directory to import" +msgstr "Selecione o diretório para importar" + +#: src/ui/dialogs/GameTweaksDialog.vala:40 +#, c-format +msgid "%s: Tweaks" +msgstr "%s: Ajustes" + +#: src/ui/views/WelcomeView.vala:52 +msgid "No enabled game sources" +msgstr "Nenhuma fonte de jogo habilitada" + +#: src/ui/views/WelcomeView.vala:52 +msgid "Enable some game sources in settings" +msgstr "Ativar algumas fontes de jogos nas configurações" + +#: src/ui/views/WelcomeView.vala:57 +msgid "Let's get started" +msgstr "Vamos começar" + +#: src/ui/views/WelcomeView.vala:71 +msgid "Skip" +msgstr "Pular" + +#: src/ui/views/WelcomeView.vala:141 +msgid "Ready" +msgstr "Pronto" + +#: src/ui/views/WelcomeView.vala:147 +msgid "Authentication required" +msgstr "Autentificação requerida" + +#: src/ui/views/WelcomeView.vala:152 +msgid "Authenticating…" +msgstr "Autenticando…" + +#: src/ui/views/WelcomeView.vala:163 +#, c-format +msgid "Install %s" +msgstr "Instale %s" + +#: src/ui/views/WelcomeView.vala:164 +msgid "Return to GameHub after installing" +msgstr "Retornar ao GameHub depois de instalar" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "No games" +msgstr "Sem jogos" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "Get some games or enable some game sources in settings" +msgstr "" +"Obtenha alguns jogos ou ative algumas origens de jogos nas configurações" + +#: src/ui/views/GamesView/GamesView.vala:150 +msgid "Grid view" +msgstr "Vista de grade" + +#: src/ui/views/GamesView/GamesView.vala:151 +msgid "List view" +msgstr "Exibição de lista" + +#: src/ui/views/GamesView/GamesView.vala:159 +msgid "All games" +msgstr "Todos os jogos" + +#: src/ui/views/GamesView/GamesView.vala:182 +msgid "Downloads" +msgstr "Transferências" + +#: src/ui/views/GamesView/GamesView.vala:208 +msgid "Filters" +msgstr "Filtros" + +#: src/ui/views/GamesView/GamesView.vala:216 +#: src/ui/views/GamesView/AddGamePopover.vala:84 +msgid "Add game" +msgstr "Adicionar jogo" + +#: src/ui/views/GamesView/GamesView.vala:223 +msgid "Search" +msgstr "Procurar" + +#: src/ui/views/GamesView/GamesView.vala:328 +msgid "Menu" +msgstr "Menu" + +#: src/ui/views/GamesView/GamesView.vala:329 +#: src/ui/views/GameDetailsView/GameDetailsView.vala:104 +msgid "Back" +msgstr "Voltar" + +#: src/ui/views/GamesView/GamesView.vala:550 +#, c-format +msgid "%u game" +msgid_plural "%u games" +msgstr[0] "%u jogo" +msgstr[1] "%u jogos" + +#: src/ui/views/GamesView/GamesView.vala:553 +#, c-format +msgctxt "games_view_subtitle_filtered_games" +msgid "%1$u / %2$s" +msgstr "%1$u / %2$s" + +#: src/ui/views/GamesView/GamesView.vala:557 +#, c-format +msgctxt "games_view_subtitle" +msgid "%1$s: %2$s" +msgstr "%1$s: %2$s" + +#: src/ui/views/GamesView/GamesView.vala:568 +msgid "No user-added games" +msgstr "Nenhum jogo adicionado pelo usuário" + +#: src/ui/views/GamesView/GamesView.vala:569 +msgid "Add some games using plus button" +msgstr "Adicione alguns jogos usando o botão mais" + +#: src/ui/views/GamesView/GamesView.vala:573 +#, c-format +msgid "No %s games" +msgstr "Nenhum %s jogos" + +#: src/ui/views/GamesView/GamesView.vala:574 +msgid "Get some Linux-compatible games" +msgstr "Obtenha alguns jogos compatíveis com o Linux" + +#: src/ui/views/GamesView/GamesView.vala:584 +#, c-format +msgid "No games matching “%s”" +msgstr "Nenhum jogo corresponde a “%s”" + +#: src/ui/views/GamesView/GamesView.vala:589 +#, c-format +msgid "No %1$s games matching “%2$s”" +msgstr "Nenhum jogo %1$s que corresponde a “%2$s”" + +#: src/ui/views/GamesView/GamesView.vala:627 +msgid "" +"No games were loaded from Steam. Set your games list privacy to public or " +"use your own Steam API key in settings." +msgstr "" +"Nenhum jogo foi carregado do Steam. Defina a privacidade da lista de jogos " +"como pública ou use sua própria chave de API do Steam nas configurações." + +#: src/ui/views/GamesView/GamesView.vala:628 +msgid "Privacy" +msgstr "Privacidade" + +#: src/ui/views/GamesView/GamesView.vala:739 +msgid "Downloading images" +msgstr "Baixando imagens" + +#: src/ui/views/GamesView/GamesView.vala:753 +#, c-format +msgid "Downloading image: %s" +msgstr "Baixando imagem: %s" + +#: src/ui/views/GamesView/DownloadProgressView.vala:131 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:162 +msgid "Pause download" +msgstr "Pausar download" + +#: src/ui/views/GamesView/DownloadProgressView.vala:137 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:168 +msgid "Resume download" +msgstr "Retomar download" + +#: src/ui/views/GamesView/DownloadProgressView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:174 +msgid "Cancel download" +msgstr "Cancelar o download" + +#: src/ui/views/GamesView/FiltersPopover.vala:77 +msgid "Group" +msgstr "Agrupar" + +#: src/ui/views/GamesView/FiltersPopover.vala:102 +msgid "Sort" +msgstr "Ordenar" + +#: src/ui/views/GamesView/FiltersPopover.vala:234 +#: src/ui/widgets/GameTagsList.vala:58 +msgid "Tags" +msgstr "Tags" + +#: src/ui/views/GamesView/FiltersPopover.vala:353 +msgid "All platforms" +msgstr "Todas as plataformas" + +#: src/ui/views/GamesView/AddGamePopover.vala:77 +msgid "Select game executable" +msgstr "Selecione o executável do jogo" + +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Select game directory" +msgstr "Selecione o diretório do jogo" + +#: src/ui/views/GamesView/AddGamePopover.vala:111 +msgid "Download game images" +msgstr "Baixar imagens de jogos" + +#: src/ui/views/GamesView/GameContextMenu.vala:87 +msgid "Details" +msgstr "Detalhes" + +#: src/ui/views/GamesView/GameContextMenu.vala:117 +msgctxt "game_context_menu" +msgid "Favorite" +msgstr "Favorito" + +#: src/ui/views/GamesView/GameContextMenu.vala:121 +msgctxt "game_context_menu" +msgid "Hidden" +msgstr "Escondido" + +#: src/ui/views/GamesView/GameContextMenu.vala:133 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:236 +msgid "Open installation directory" +msgstr "Abra o diretório de instalação" + +#: src/ui/views/GamesView/GameContextMenu.vala:142 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:237 +msgid "Open installers collection directory" +msgstr "Abrir diretório de coleção de instaladores" + +#: src/ui/views/GamesView/GameContextMenu.vala:151 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:238 +msgid "Open bonus collection directory" +msgstr "Abra o diretório de coleção de bônus" + +#: src/ui/views/GamesView/GameContextMenu.vala:160 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:239 +msgid "Open screenshots directory" +msgstr "Abrir diretório de capturas de tela" + +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +msgid "Uninstall" +msgstr "Desinstalar" + +#: src/ui/views/GamesView/GameContextMenu.vala:192 +msgid "Properties" +msgstr "Propriedades" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:100 +#, c-format +msgid "%d game selected" +msgid_plural "%d games selected" +msgstr[0] "%d jogo selecionado" +msgstr[1] "%d jogos selecionados" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:144 +#, c-format +msgid "%d game will be installed" +msgid_plural "%d games will be installed" +msgstr[0] "%d jogo será instalado" +msgstr[1] "%d jogos serão instalados" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:154 +#, c-format +msgid "%d game will be downloaded" +msgid_plural "%d games will be downloaded" +msgstr[0] "%d jogo será baixado" +msgstr[1] "%d jogos serão baixados" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:161 +#, c-format +msgid "Image for %d game will be searched" +msgid_plural "Images for %d games will be searched" +msgstr[0] "Imagem para %d jogo será pesquisada" +msgstr[1] "Imagens para %d jogos serão pesquisadas" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:168 +#, c-format +msgid "%d game will be uninstalled" +msgid_plural "%d games will be uninstalled" +msgstr[0] "%d jogo será desinstalado" +msgstr[1] "%d jogos serão desinstalados" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:174 +msgid "Refresh" +msgstr "Recarregar" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:175 +#, c-format +msgid "" +"%d game will be removed from database. Restart GameHub to fetch new data" +msgid_plural "" +"%d games will be removed from database. Restart GameHub to fetch new data" +msgstr[0] "" +"%d jogo será removido da base de dados. Reinicie o GameHub para buscar novos " +"dados" +msgstr[1] "" +"%d jogos serão removidos da base de dados. Reinicie o GameHub para buscar " +"novos dados" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:240 +msgid "Open store page" +msgstr "Abra a página da loja" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:242 +msgid "Game properties" +msgstr "Propriedades do jogo" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:46 +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:60 +msgid "Playtime" +msgstr "Tempo de reprodução" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:52 +msgid "Playtime (local)" +msgstr "Tempo de reprodução (local)" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:69 +msgid "Last launch" +msgstr "Último lançamento" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:46 +msgid "Achievements" +msgstr "Conquistas" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:85 +#, c-format +msgid "Unlocked: %s" +msgstr "Desbloqueado: %s" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:90 +#, c-format +msgid "Global percentage: %g%%" +msgstr "Porcentagem global: %g%%" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:77 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:103 +msgid "Language" +msgstr "Língua" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:80 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:106 +msgid "Languages" +msgstr "Línguas" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:147 +#, c-format +msgid "%u DLCs cannot be installed" +msgstr "%u Os DLCs não podem ser instalados" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:71 +msgid "Category" +msgstr "Categoria" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:74 +msgid "Categories" +msgstr "Categorias" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:90 +msgid "Genre" +msgstr "Gênero" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:93 +msgid "Genres" +msgstr "Gêneros" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:109 +msgctxt "igdb" +msgid "Popularity" +msgstr "Popularidade" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:115 +msgctxt "igdb" +msgid "Aggregated rating" +msgstr "Avaliação agregada" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:116 +msgctxt "igdb" +msgid "IGDB user rating" +msgstr "Nota de usuários no IGDB" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:117 +msgctxt "igdb" +msgid "Total rating" +msgstr "Avaliação total" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:126 +msgctxt "igdb" +msgid "Release date" +msgstr "Data de lançamento" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:133 +msgctxt "igdb" +msgid "Platforms" +msgstr "Plataformas" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:139 +msgctxt "igdb" +msgid "Genres" +msgstr "Gêneros" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:145 +msgctxt "igdb" +msgid "Keywords" +msgstr "Palavras-chave" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:152 +msgctxt "igdb" +msgid "Links" +msgstr "Links" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:208 +#, c-format +msgid "Based on %d rating" +msgid_plural "Based on %d ratings" +msgstr[0] "Baseado em %d avaliação" +msgstr[1] "Baseado em %d avaliações" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:290 +msgctxt "igdb" +msgid "Summary" +msgstr "Resumo" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:301 +msgctxt "igdb" +msgid "Storyline" +msgstr "Enredo" + +#: src/ui/widgets/FileChooserEntry.vala:49 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select file" +msgstr "Selecione o arquivo" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "No images" +msgstr "Sem imagens" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "" +"There are no images found for this game\n" +"Make sure game name is correct" +msgstr "" +"Não foi encontrado imagens para este jogo\n" +"Certifique-se de que o nome do jogo esteja correto" + +#: src/ui/widgets/ImagesDownloadPopover.vala:94 +msgid "Search images:" +msgstr "Pesquisar imagens:" + +#: src/ui/widgets/CompatToolPicker.vala:53 +msgid "Compatibility layer:" +msgstr "Camada de compatibilidade:" + +#: src/ui/widgets/CompatToolPicker.vala:92 +msgid "Configure" +msgstr "Configurar" + +#: src/ui/widgets/GameTagsList.vala:109 +msgid "Add tag" +msgstr "Adicionar etiqueta" + +#: src/ui/widgets/TweaksList.vala:86 +msgid "No description" +msgstr "Sem descrição" + +#: src/ui/widgets/TweaksList.vala:124 +msgid "Edit file" +msgstr "Editar o arquivo" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dh" +msgstr "%dh" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dm" +msgstr "%dm" + +#: src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%ds" +msgstr "%ds" + +#: src/settings/UI.vala:153 +msgctxt "grid_size_preset" +msgid "Steam" +msgstr "Steam" + +#: src/settings/UI.vala:154 +msgctxt "grid_size_preset" +msgid "Steam (vertical)" +msgstr "Steam (vertical)" + +#: src/settings/UI.vala:155 +msgctxt "grid_size_preset" +msgid "GOG" +msgstr "GOG" + +#: src/settings/UI.vala:156 +msgctxt "grid_size_preset" +msgid "GOG (vertical)" +msgstr "GOG (vertical)" + +#: src/settings/UI.vala:157 +msgctxt "grid_size_preset" +msgid "Square" +msgstr "Quadrado" + +#: src/settings/UI.vala:158 +msgctxt "grid_size_preset" +msgid "Custom" +msgstr "Personalizado" + +#: src/utils/downloader/Downloader.vala:200 +msgctxt "dl_status" +msgid "Queued" +msgstr "Na fila" + +#: src/utils/downloader/Downloader.vala:201 +msgctxt "dl_status" +msgid "Starting download" +msgstr "Iniciando o download" + +#: src/utils/downloader/Downloader.vala:202 +msgctxt "dl_status" +msgid "Download started" +msgstr "Download iniciado" + +#: src/utils/downloader/Downloader.vala:203 +msgctxt "dl_status" +msgid "Download finished" +msgstr "Download finalizado" + +#: src/utils/downloader/Downloader.vala:204 +msgctxt "dl_status" +msgid "Download failed" +msgstr "Falha no download" + +#: src/utils/downloader/Downloader.vala:208 +#, c-format +msgctxt "dl_status" +msgid "Downloading: %s" +msgstr "Baixando: %s" + +#: src/utils/downloader/Downloader.vala:210 +msgctxt "dl_status" +msgid "Downloading" +msgstr "Baixando" + +#: src/utils/downloader/Downloader.vala:214 +#, c-format +msgctxt "dl_status" +msgid "Paused: %s" +msgstr "Pausado: %s" + +#: src/utils/downloader/Downloader.vala:216 +msgctxt "dl_status" +msgid "Paused" +msgstr "Pausado" + +#: src/utils/downloader/Downloader.vala:218 +msgctxt "dl_status" +msgid "Download cancelled" +msgstr "Download cancelado" + +#. TRANSLATORS: Download progress template. %1$d - percentage, %2$s / %3$s - downloaded portion and total file size, %4$s - download speed +#: src/utils/downloader/Downloader.vala:262 +#, c-format +msgctxt "dl_status" +msgid "%1$d%% (%2$s / %3$s) [%4$s/s]" +msgstr "%1$d%% (%2$s / %3$s) [%4$s/s]" + +#~ msgid "Disable esync" +#~ msgstr "Desativar esync" + +#~ msgid "Force LARGE_ADDRESS_AWARE flag" +#~ msgstr "Forçar sinalizador LARGE_ADDRESS_AWARE" + +#~ msgid "Disable DirectX 11 compatibility layer" +#~ msgstr "Desativar camada de compatibilidade do DirectX 11" + +#~ msgid "Use WineD3D11 as DirectX 11 compatibility layer" +#~ msgstr "Use WineD3D11 como camada de compatibilidade DirectX 11" + +#~ msgid "Show DXVK info overlay" +#~ msgstr "Mostrar sobreposição de informações do DXVK" + +#, fuzzy +#~ msgid "Enable DirectX 9 compatibility layer" +#~ msgstr "Desativar camada de compatibilidade do DirectX 11" + +#~ msgid "Silent installation" +#~ msgstr "Instalação silenciosa" + +#~ msgid "Very silent installation" +#~ msgstr "Instalação muito silenciosa" + +#~ msgid "Suppress messages" +#~ msgstr "Suprimir mensagens" + +#~ msgid "No GUI" +#~ msgstr "Sem GUI" + +#~ msgctxt "igdb" +#~ msgid "%s on IGDB" +#~ msgstr "%s no IGDB" + +#~ msgid "Disable fullscreen" +#~ msgstr "Desativar tela inteira" + +#~ msgid "Windowed" +#~ msgstr "Windowed" + +#~ msgid "Compact list" +#~ msgstr "Lista compacta" + +#~ msgid "Show non-native games" +#~ msgstr "Mostrar jogos não nativos" + +#~ msgid "Use compatibility layers and consider Windows games compatible" +#~ msgstr "" +#~ "Use camadas de compatibilidade e considere os jogos do Windows compatíveis" + +#~ msgid "Reload" +#~ msgstr "Recarregar" + +#~ msgid "Updating game info" +#~ msgstr "Atualizando informações do jogo" + +#~ msgid "Updating %s game info" +#~ msgstr "Atualizando as informações do jogo de %s" + +#~ msgid "Merging %s (%s)" +#~ msgstr "Mesclando %s (%s)" diff --git a/po/pt_PT.po b/po/pt_PT.po new file mode 100644 index 00000000..0ac05d7b --- /dev/null +++ b/po/pt_PT.po @@ -0,0 +1,1823 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the com.github.tkashkin.gamehub package. +# Manuela Silva , 2019. +msgid "" +msgstr "" +"Project-Id-Version: com.github.tkashkin.gamehub\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-26 06:40+0300\n" +"PO-Revision-Date: 2019-09-07 12:25+0000\n" +"Last-Translator: Manuela Silva \n" +"Language-Team: Portuguese (Portugal) \n" +"Language: pt_PT\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 3.9-dev\n" + +#: src/app.vala:91 +msgid "Show help" +msgstr "Mostrar ajuda" + +#: src/app.vala:92 +msgid "Show application version and exit" +msgstr "Mostrar versão da aplicação e sair" + +#: src/app.vala:93 +msgid "Restart with GDB debugger attached" +msgstr "Reiniciar com o depurador GDB anexado" + +#: src/app.vala:94 +msgid "Show full GDB backtrace" +msgstr "" + +#: src/app.vala:95 +msgid "Treat fatal errors as criticals and crash application" +msgstr "" + +#: src/app.vala:99 +msgid "Show main window" +msgstr "Mostrar janela principal" + +#: src/app.vala:100 +msgid "Show application settings dialog" +msgstr "Mostrar janela das definições da aplicação" + +#: src/app.vala:101 +msgid "Show about dialog" +msgstr "Mostrar janela sobre" + +#: src/app.vala:102 +msgid "Maximum number of background worker threads" +msgstr "" + +#: src/app.vala:106 +msgid "Run game" +msgstr "Iniciar jogo" + +#: src/app.vala:107 +msgid "Show compatibility options dialog" +msgstr "Mostrar janela das opções de compatibilidade" + +#: src/app.vala:108 +msgid "Open game details" +msgstr "Abrir detalhes do jogo" + +#: src/app.vala:109 +msgid "Open game properties" +msgstr "Abrir propriedades do jogo" + +#: src/app.vala:113 +msgid "Enable debug logging" +msgstr "Ativar registo da depuração" + +#: src/app.vala:114 +msgid "" +"Log authentication process and sensitive information like authentication " +"tokens" +msgstr "" +"Processo de autenticação de registo e informação confidencial, tal como " +"códigos de autenticação" + +#: src/app.vala:115 +msgid "Log download manager" +msgstr "Gestor de transferências de registo" + +#: src/app.vala:116 +msgid "Log background workers start/stop" +msgstr "" + +#: src/app.vala:117 +msgid "Disable log messages filtering" +msgstr "" + +#: src/app.vala:118 +msgid "Verbose logging" +msgstr "" + +#: src/app.vala:247 +msgid "Game Options:" +msgstr "Opções do jogo:" + +#: src/app.vala:247 +msgid "Show game options help" +msgstr "Mostrar ajuda das opções do jogo" + +#: src/app.vala:255 +msgid "Logging Options:" +msgstr "Opções de registo:" + +#: src/app.vala:255 +msgid "Show logging options help" +msgstr "Mostrar ajuda das opções de registo" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +msgid "Select executable" +msgstr "Selecionar executável" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:181 src/ui/views/GamesView/GamesView.vala:330 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select" +msgstr "Selecionar" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:180 src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Cancel" +msgstr "Cancelar" + +#: src/data/Runnable.vala:166 src/ui/widgets/FileChooserEntry.vala:49 +msgid "Select directory" +msgstr "Selecionar diretoria" + +#: src/data/Runnable.vala:619 +#, c-format +msgid "Part %1$u of %2$u: %3$s" +msgstr "Parte %1$u de %2$u: %3$s" + +#: src/data/Runnable.vala:642 src/ui/dialogs/CorruptedInstallerDialog.vala:48 +#, c-format +msgid "%s: corrupted installer" +msgstr "%s: instalador corrompido" + +#: src/data/Runnable.vala:643 +#, c-format +msgid "Checksum mismatch in %s" +msgstr "" + +#: src/data/Runnable.vala:657 src/ui/dialogs/CorruptedInstallerDialog.vala:126 +msgid "Show file" +msgstr "Mostrar ficheiro" + +#: src/data/Runnable.vala:658 src/ui/dialogs/CorruptedInstallerDialog.vala:132 +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#: src/ui/widgets/TagRow.vala:146 +msgid "Remove" +msgstr "Remover" + +#: src/data/Runnable.vala:659 src/ui/dialogs/CorruptedInstallerDialog.vala:128 +msgid "Backup" +msgstr "Cópia de Segurança" + +#: src/data/Runnable.vala:778 +#, c-format +msgid "%s: cannot detect main executable" +msgstr "%s: não consegue detetar o executável principal" + +#: src/data/Runnable.vala:779 +msgid "" +"Main executable file for this game cannot be detected automatically.\n" +"Please set main executable in game's properties." +msgstr "" + +#: src/data/Runnable.vala:908 +msgctxt "platform" +msgid "Emulated" +msgstr "Emulado" + +#: src/data/Game.vala:625 +msgctxt "status" +msgid "Running" +msgstr "Em execução" + +#: src/data/Game.vala:628 +msgctxt "status" +msgid "Installed" +msgstr "Instalado" + +#: src/data/Game.vala:629 +msgctxt "status" +msgid "Installing" +msgstr "A instalar" + +#: src/data/Game.vala:630 +msgctxt "status" +msgid "Verifying installer integrity" +msgstr "A verificar a integridade do instalador" + +#: src/data/Game.vala:631 +msgctxt "status" +msgid "Download started" +msgstr "Transferência iniciada" + +#: src/data/Game.vala:633 +msgctxt "status" +msgid "Not installed" +msgstr "Não instalado" + +#: src/data/Game.vala:643 +msgctxt "status_header" +msgid "Installed" +msgstr "Instalado" + +#: src/data/Game.vala:644 +msgctxt "status_header" +msgid "Installing" +msgstr "A instalar" + +#: src/data/Game.vala:646 +msgctxt "status_header" +msgid "Downloading" +msgstr "A transferir" + +#: src/data/Game.vala:648 +msgctxt "status_header" +msgid "Not installed" +msgstr "Não instalado" + +#: src/data/GameSource.vala:31 +#, c-format +msgid "%s games" +msgstr "%s jogos" + +#: src/data/sources/steam/Steam.vala:43 +msgid "Your SteamID will be read from Steam configuration file" +msgstr "A sua 'Id. do Steam' será lida do ficheiro de configuração do Steam" + +#: src/data/sources/steam/Steam.vala:46 +msgid "" +"Steam config file not found.\n" +"Login into your account in Steam client and return to GameHub" +msgstr "" + +#: src/data/sources/gog/GOGGame.vala:983 +#, c-format +msgid "DLC: %s" +msgstr "" + +#: src/data/sources/humble/HumbleGame.vala:343 +#, c-format +msgid "%s: no available installers" +msgstr "%s: sem instaladores disponíveis" + +#: src/data/sources/humble/HumbleGame.vala:344 +msgid "" +"Cannot get Trove download URL.\n" +"Make sure your Humble Monthly subscription is active." +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:192 +#, c-format +msgctxt "itch_dl_status" +msgid "%s left;" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:195 +#, c-format +msgctxt "itch_dl_status" +msgid "%d%%" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:198 +#, c-format +msgctxt "itch_dl_status" +msgid "(%1$s / %2$s)" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:201 +#, c-format +msgctxt "itch_dl_status" +msgid "[%s/s]" +msgstr "" + +#: src/data/sources/user/User.vala:30 +msgid "User games" +msgstr "Jogos do utilizador" + +#: src/data/db/tables/Tags.vala:225 +msgctxt "tag" +msgid "Favorites" +msgstr "Favoritos" + +#: src/data/db/tables/Tags.vala:226 +msgctxt "tag" +msgid "Not installed" +msgstr "Não instalado" + +#: src/data/db/tables/Tags.vala:227 +msgctxt "tag" +msgid "Installed" +msgstr "Instalado" + +#: src/data/db/tables/Tags.vala:228 +msgctxt "tag" +msgid "Hidden" +msgstr "Ocultado" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit script" +msgstr "Editar script" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit custom script" +msgstr "Editar script personalizado" + +#: src/data/compat/Innoextract.vala:55 +#, c-format +msgid "" +"Innoextract %1$s is not supported and may not be able to extract some " +"games correctly.\n" +"Install innoextract %2$s or newer." +msgstr "" + +#: src/data/compat/WineWrap.vala:61 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:242 +#: src/ui/dialogs/CompatRunDialog.vala:102 +#: src/ui/views/GamesView/GameContextMenu.vala:53 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:234 +msgid "Run" +msgstr "Executar" + +#: src/data/compat/WineWrap.vala:64 +msgid "Show WineWrap menu" +msgstr "Mostrar menu de WineWrap" + +#: src/data/compat/WineWrap.vala:67 src/data/compat/Proton.vala:122 +#: src/data/compat/Wine.vala:83 +msgid "Kill apps in prefix" +msgstr "" + +#: src/data/compat/Proton.vala:47 +msgid "Proton prefix" +msgstr "Prefixo do Proton" + +#: src/data/compat/Proton.vala:110 src/data/compat/Wine.vala:71 +msgid "Open prefix directory" +msgstr "Abrir diretoria de prefixos" + +#: src/data/compat/Proton.vala:113 src/data/compat/Wine.vala:74 +msgid "Run winecfg" +msgstr "Excecutar winecfg" + +#: src/data/compat/Proton.vala:116 src/data/compat/Wine.vala:77 +msgid "Run winetricks" +msgstr "Executar winetricks" + +#: src/data/compat/Proton.vala:119 src/data/compat/Wine.vala:80 +msgid "Run taskmgr" +msgstr "Executar taskmgr" + +#: src/data/compat/Wine.vala:53 +msgid "Wine prefix" +msgstr "Prefixo de Wine" + +#: src/data/compat/Wine.vala:55 +msgid "Environment variables" +msgstr "Variáveis de ambiente" + +#: src/data/compat/Wine.vala:60 +msgid "InnoSetup default options" +msgstr "" + +#: src/data/compat/RetroArch.vala:53 +msgid "Libretro core file" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:43 +msgid "Custom emulator" +msgstr "Emulador personalizado" + +#: src/data/compat/CustomEmulator.vala:48 +msgid "Emulator" +msgstr "Emulador" + +#: src/data/compat/CustomEmulator.vala:49 +msgid "Launch in game directory" +msgstr "Iniciar na diretoria de jogos" + +#: src/data/adapters/GamesAdapter.vala:440 +msgctxt "status_header" +msgid "Favorites" +msgstr "Favoritos" + +#: src/data/adapters/GamesAdapter.vala:445 +#, c-format +msgctxt "status_header" +msgid "%s: Favorites" +msgstr "%s: Favoritos" + +#: src/data/adapters/GamesAdapter.vala:491 +msgid "Merging games" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:504 +#, c-format +msgid "Merging games from %s" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:551 +#, c-format +msgid "Loading games from %s" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:678 +msgctxt "sort_mode" +msgid "By name" +msgstr "Por nome" + +#: src/data/adapters/GamesAdapter.vala:679 +msgctxt "sort_mode" +msgid "By last launch" +msgstr "Por última execução" + +#: src/data/adapters/GamesAdapter.vala:680 +msgctxt "sort_mode" +msgid "By playtime" +msgstr "Por hora de jogar" + +#: src/data/adapters/GamesAdapter.vala:705 +msgctxt "group_mode" +msgid "Do not group" +msgstr "Não agrupar" + +#: src/data/adapters/GamesAdapter.vala:706 +msgctxt "group_mode" +msgid "By status" +msgstr "Por estado" + +#: src/data/adapters/GamesAdapter.vala:707 +msgctxt "group_mode" +msgid "By source" +msgstr "Por fonte" + +#: src/data/providers/images/SteamGridDB.vala:151 +#: src/data/providers/data/IGDB.vala:431 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:217 +msgid "Default" +msgstr "Predefinição" + +#: src/data/providers/images/SteamGridDB.vala:158 +#: src/data/providers/data/IGDB.vala:438 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:225 +msgid "Restore default API key" +msgstr "Restaurar chave API predefinida" + +#: src/data/providers/images/SteamGridDB.vala:169 +#: src/data/providers/data/IGDB.vala:449 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:108 +msgid "API key" +msgstr "Chave API" + +#: src/data/providers/images/SteamGridDB.vala:177 +#: src/data/providers/data/IGDB.vala:457 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:53 +msgid "Generate key" +msgstr "Gerar chave" + +#: src/data/providers/images/SteamGridDB.vala:208 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Style" +msgstr "Estilo" + +#: src/data/providers/images/SteamGridDB.vala:209 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Score" +msgstr "Pontuação" + +#: src/data/providers/images/SteamGridDB.vala:213 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Author" +msgstr "Autor" + +#: src/data/providers/images/SteamGridDB.vala:225 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Alternate" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:226 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Blurred" +msgstr "" + +#. TRANSLATORS: Flat / Material Design image style. Probably should not be translated +#: src/data/providers/images/SteamGridDB.vala:228 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Material" +msgstr "Material" + +#: src/data/providers/images/SteamGridDB.vala:229 +msgctxt "imagesource_steamgriddb_image_style" +msgid "No logo" +msgstr "Sem logótipo" + +#: src/data/providers/images/SteamGridDB.vala:230 +msgctxt "imagesource_steamgriddb_image_style" +msgid "White logo" +msgstr "" + +#: src/data/providers/data/IGDB.vala:147 +msgid "" +"Monthly IGDB request quota has been reached. Set your own API key to use " +"IGDB data or disable IGDB." +msgstr "" + +#: src/data/providers/data/IGDB.vala:148 +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:40 +#: src/ui/views/WelcomeView.vala:53 src/ui/views/WelcomeView.vala:78 +#: src/ui/views/GamesView/GamesView.vala:230 +#: src/ui/views/GamesView/GamesView.vala:629 +msgid "Settings" +msgstr "Configurações" + +#: src/data/providers/data/IGDB.vala:356 +msgctxt "igdb_related_link" +msgid "Official website" +msgstr "Site da Web Oficial" + +#: src/data/providers/data/IGDB.vala:469 +msgctxt "igdb_preferred_description" +msgid "When game has description, show description" +msgstr "Quando o jogo tiver descrição, mostrar descrição" + +#: src/data/providers/data/IGDB.vala:476 +msgctxt "igdb_preferred_description" +msgid "of game" +msgstr "do jogo" + +#: src/data/providers/data/IGDB.vala:477 +msgctxt "igdb_preferred_description" +msgid "from IGDB" +msgstr "de IGDB" + +#: src/data/providers/data/IGDB.vala:478 +msgctxt "igdb_preferred_description" +msgid "both" +msgstr "ambos" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:65 +msgid "Some settings will be applied after application restart" +msgstr "Algumas configurações serão aplicadas depois de reiniciar a aplicação" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:71 +msgid "Games directory contains space. It may cause problems for some games" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:36 +msgid "Interface" +msgstr "Interface" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:37 +msgid "Appearance" +msgstr "Aparência" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:38 +msgid "General interface settings" +msgstr "Configurações da interface geral" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:48 +msgid "Dark theme" +msgstr "Tema escuro" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:53 +msgctxt "icon_style" +msgid "Theme-based" +msgstr "Baseado no tema" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:54 +msgctxt "icon_style" +msgid "Symbolic" +msgstr "Simbólico" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:55 +msgctxt "icon_style" +msgid "Colored" +msgstr "Colorido" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:57 +msgctxt "icon_style" +msgid "Icon style" +msgstr "Estilo do ícone" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:84 +msgid "Game card" +msgstr "Cartão do jogo" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:86 +msgid "Show platform icons" +msgstr "Mostrar ícones da plataforma" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:99 +msgctxt "grid_size" +msgid "Card size" +msgstr "Tamanho do cartão" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:117 +msgctxt "grid_size_preset" +msgid "Presets" +msgstr "Pré-ajustes" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:139 +msgid "Games list: installed" +msgstr "Lista de jogos: instalados" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:140 +msgid "Games list: not installed" +msgstr "Lista de jogos: não instalados" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:142 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:146 +msgctxt "list_style" +msgid "Show icon" +msgstr "Mostrar ícone" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:143 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:147 +msgctxt "list_style" +msgid "Bold title" +msgstr "Título a negrito" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:144 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:148 +msgctxt "list_style" +msgid "Show status" +msgstr "Mostrar estado" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:149 +msgctxt "list_style" +msgid "Dim" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:151 +msgid "Grid options" +msgstr "Opções de grelha" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:152 +msgid "List options" +msgstr "Opções de lista" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:31 +msgid "Behavior" +msgstr "Comportamento" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:32 +msgid "Behavior settings" +msgstr "Configurações de comportamento" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:42 +msgid "Run games with double click" +msgstr "Executar jogos com duplo clique" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:46 +msgid "Merge games from different sources" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:50 +msgid "Use imported tags" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:51 +msgid "General" +msgstr "Geral" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:52 +msgid "Collection" +msgstr "Coleção" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:53 +msgid "Empty" +msgstr "Vazia" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:65 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:85 +msgid "Collection directory" +msgstr "Diretoria das coleções" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:70 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:78 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:87 +msgid "Game directory" +msgstr "Diretoria dos jogos" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:71 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:79 +msgid "Installers" +msgstr "Instaladores" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:72 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:98 +msgid "DLC" +msgstr "DLC" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:73 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:197 +msgid "Bonus content" +msgstr "Conteúdo Bónus" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:84 +msgid "Variable syntax: $var or ${var}" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:86 +msgid "Game name" +msgstr "Nome do jogo" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:88 +#: src/ui/views/GamesView/FiltersPopover.vala:127 +msgid "Platform" +msgstr "Plataforma" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:36 +msgid "Controller" +msgstr "Controlador" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +msgid "Enabled" +msgstr "Ativado" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:53 +msgid "Focus GameHub window with Guide button" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:57 +msgid "Controllers" +msgstr "Controladores" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:89 +msgid "Move focus" +msgstr "Mover focos" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:91 +msgid "Exit" +msgstr "Sair" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:40 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:108 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:92 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:95 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:36 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:77 +msgid "Disabled" +msgstr "Desativado" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:47 +#: src/ui/dialogs/GameTweaksDialog.vala:53 +#: src/ui/views/GamesView/GameContextMenu.vala:183 +msgid "Tweaks" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:34 +msgid "Tweak launch options and apply them to games automatically" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:79 +msgid "" +"Tweaks are loaded from following directories in order\n" +"Last tweak overrides previous tweaks with same identifiers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:83 +msgid "Click to open" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:93 +#, c-format +msgid "Tweaks are loaded from %1$s and %2$d more directories (?)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:38 +msgid "Game sources" +msgstr "Fontes de jogo" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +msgid "Steam API keys have limited number of uses per day" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:63 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:57 +msgid "Installation directory" +msgstr "Diretoria de instalação" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:176 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:81 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:34 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:75 +msgid "Not installed" +msgstr "Não instalado" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:116 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:96 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:99 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:85 +msgid "Not authenticated" +msgstr "Não autenticado" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +#, c-format +msgid "Authenticated as %s" +msgstr "Autenticado como %s" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:103 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +msgid "Authenticated" +msgstr "Autenticado" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:183 +#: src/ui/dialogs/InstallDialog.vala:53 src/ui/dialogs/InstallDialog.vala:111 +#: src/ui/views/GamesView/GameContextMenu.vala:80 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:233 +#: src/ui/widgets/TweaksList.vala:95 +msgid "Install" +msgstr "Instalar" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:236 +msgid "Steam API key" +msgstr "Chave API do Steam" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:50 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:54 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:48 +msgid "Games directory" +msgstr "Diretoria de jogos" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:63 +msgid "Logout" +msgstr "Terminar sessão" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:50 +msgid "Load games from Humble Trove" +msgstr "Carregar jogos de Humble Trove" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:45 +msgid "Emulators" +msgstr "Emuladores" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:45 +msgid "Libretro core directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:46 +msgid "Libretro core info directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:50 +msgid "Ignored libretro cores" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:54 +msgid "Ignored game file extensions" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:66 +msgid "No cores found" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:70 +#, c-format +msgid "%u core found" +msgid_plural "%u cores found" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:46 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:168 +msgid "No custom emulators" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:164 +#, c-format +msgid "%u custom emulator" +msgid_plural "%u custom emulators" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:237 +msgid "Save" +msgstr "Guardar" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:250 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:312 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/dialogs/GamePropertiesDialog.vala:168 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +#: src/ui/views/GamesView/AddGamePopover.vala:67 +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Executable" +msgstr "Executável" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:251 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/views/GamesView/AddGamePopover.vala:68 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Installer" +msgstr "Instalador" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:256 +#: src/ui/dialogs/GamePropertiesDialog.vala:64 +#: src/ui/dialogs/GamePropertiesDialog.vala:69 +#: src/ui/views/GamesView/AddGamePopover.vala:73 +msgid "Name" +msgstr "Nome" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:272 +#: src/ui/dialogs/GamePropertiesDialog.vala:201 +#: src/ui/views/GamesView/AddGamePopover.vala:78 +msgid "Arguments" +msgstr "Argumentos" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:276 +msgid "Variables" +msgstr "Variáveis" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:277 +msgid "Game executable" +msgstr "Executável do jogo" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:278 +msgid "Game arguments" +msgstr "Argumentos de jogo" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:80 +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Directory" +msgstr "Diretoria" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +msgid "Select emulator directory" +msgstr "Selecionar diretoria do emulador" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:292 +#: src/ui/dialogs/GamePropertiesDialog.vala:219 +msgid "Force compatibility mode" +msgstr "Forçar modo de compatibilidade" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:307 +msgid "Game file patterns" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:315 +msgid "Image" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:318 +msgid "Icon" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:325 +msgid "" +"findutils-compatible glob patterns\n" +"\n" +" Multiple patterns can be separated with |\n" +" Start pattern with ./ to match relative path\n" +" $basename variable will be replaced with game's executable " +"name (without extension)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:38 +msgid "Data" +msgstr "Dados" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:39 +msgid "Providers" +msgstr "Provedores" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:40 +msgid "Third-party data providers" +msgstr "Provedores de dados terceiros" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:55 +msgid "Image providers" +msgstr "Provedores de imagem" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:68 +msgid "Metadata providers" +msgstr "Provedores de metadados" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:137 +msgid "Open website" +msgstr "Abrir sites da Web" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:36 +msgid "About" +msgstr "Sobre" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:71 +msgid "Copy application version and environment info" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:78 +#: src/ui/views/WelcomeView.vala:57 +msgid "All your games in one place" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:92 +msgctxt "about_link" +msgid "Website" +msgstr "Site da Web" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:96 +msgctxt "about_link" +msgid "Source code on GitHub" +msgstr "Código fonte no GitHub" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:103 +msgctxt "about_link" +msgid "Report a problem" +msgstr "Reportar um problema" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:104 +msgctxt "about_link" +msgid "Suggest translations" +msgstr "Sugerir traduções" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:110 +msgctxt "about_link" +msgid "Issues" +msgstr "Problemas" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:111 +msgctxt "about_link" +msgid "Contributors" +msgstr "Colaboradores" + +#. TRANSLATORS: Likely it should not be translated. GitHub Pulse is a page that shows recent repository activity: https://github.com/tkashkin/GameHub/pulse +#: src/ui/dialogs/SettingsDialog/pages/About.vala:114 +msgctxt "about_link" +msgid "Pulse" +msgstr "Pulse" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:115 +msgctxt "about_link" +msgid "Forks" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:109 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:129 +msgid "Import" +msgstr "Importar" + +#: src/ui/dialogs/InstallDialog.vala:110 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:153 +msgid "Download" +msgstr "Transferir" + +#: src/ui/dialogs/InstallDialog.vala:207 +msgid "Select installer" +msgstr "Selecionar instalador" + +#: src/ui/dialogs/InstallDialog.vala:216 +#, c-format +msgid "Installer size: %s" +msgstr "Tamanho do instalador: %s" + +#: src/ui/dialogs/InstallDialog.vala:348 +msgid "Unknown" +msgstr "Desconhecido" + +#: src/ui/dialogs/GamePropertiesDialog.vala:49 +#, c-format +msgid "%s: Properties" +msgstr "%s: Propriedades" + +#: src/ui/dialogs/GamePropertiesDialog.vala:84 +msgid "Images" +msgstr "Imagens" + +#: src/ui/dialogs/GamePropertiesDialog.vala:126 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:160 +#: src/ui/views/GameDetailsView/blocks/Artwork.vala:62 +msgid "Download images" +msgstr "Transferir imagens" + +#: src/ui/dialogs/GamePropertiesDialog.vala:144 +msgid "Image URL" +msgstr "URL da imagem" + +#: src/ui/dialogs/GamePropertiesDialog.vala:148 +msgid "Vertical image URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:157 +msgid "Icon URL" +msgstr "URL do ícone" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +#, fuzzy +msgid "Select working directory" +msgstr "Selecionar diretoria" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +#, fuzzy +msgid "Working directory" +msgstr "Abrir diretoria" + +#: src/ui/dialogs/GamePropertiesDialog.vala:214 +msgid "Compatibility" +msgstr "Compatibilidade" + +#: src/ui/dialogs/GamePropertiesDialog.vala:236 +msgid "Launch from terminal" +msgstr "Iniciar no terminal" + +#: src/ui/dialogs/GamePropertiesDialog.vala:252 +msgid "Copy to clipboard" +msgstr "Copiar para a área de transferência" + +#: src/ui/dialogs/GamePropertiesDialog.vala:254 +msgid "Add to Steam" +msgstr "Adicionar ao Steam" + +#: src/ui/dialogs/GamePropertiesDialog.vala:255 +msgid "Add to the Steam library" +msgstr "Adicionar à biblioteca do Steam" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:53 +#, c-format +msgid "%s: Overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "Overlays are disabled" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "" +"Enable overlays to manage DLCs and mods\n" +"\n" +"Enabling will move game to the “base“ overlay" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:77 +#: src/ui/views/GamesView/GameContextMenu.vala:175 +msgid "Overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:105 +msgid "Overlay ID (directory name)" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:110 +msgid "Overlay name (optional)" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:112 +msgid "Add" +msgstr "Adicionar" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:127 +msgid "Enable overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:182 +#, c-format +msgid "" +"Overlay usage at this path may be unsafe\n" +"Proceed at your own risk\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:187 +#, c-format +msgid "" +"Overlay usage at this path is not supported\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:266 +msgid "Open directory" +msgstr "Abrir diretoria" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:271 +msgid "Remove overlay" +msgstr "" + +#: src/ui/dialogs/CompatRunDialog.vala:48 +#: src/ui/views/GamesView/GameContextMenu.vala:46 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:235 +msgid "Run with compatibility layer" +msgstr "Executar camada de compatibilidade" + +#: src/ui/dialogs/CorruptedInstallerDialog.vala:71 +msgid "Corrupted installer: checksum mismatch in" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:57 +#: src/ui/views/GamesView/AddGamePopover.vala:105 +msgid "Import emulated games" +msgstr "Importar jogos emulados" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:75 +msgid "Select directory with emulated games" +msgstr "Selecionar diretoria com os jogos emulados" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:83 +msgid "Detected games" +msgstr "Jogos detetados" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:107 +msgid "Select all" +msgstr "Selecionar todos" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:115 +msgid "Select directory to import" +msgstr "Selecionar diretoria para importar" + +#: src/ui/dialogs/GameTweaksDialog.vala:40 +#, c-format +msgid "%s: Tweaks" +msgstr "" + +#: src/ui/views/WelcomeView.vala:52 +msgid "No enabled game sources" +msgstr "Sem fontes de jogo ativadas" + +#: src/ui/views/WelcomeView.vala:52 +msgid "Enable some game sources in settings" +msgstr "Ativar algumas fontes de jogo nas configurações" + +#: src/ui/views/WelcomeView.vala:57 +msgid "Let's get started" +msgstr "Vamos lá começar" + +#: src/ui/views/WelcomeView.vala:71 +msgid "Skip" +msgstr "Ignorar" + +#: src/ui/views/WelcomeView.vala:141 +msgid "Ready" +msgstr "Pronto" + +#: src/ui/views/WelcomeView.vala:147 +msgid "Authentication required" +msgstr "Autenticação obrigatória" + +#: src/ui/views/WelcomeView.vala:152 +#, fuzzy +msgid "Authenticating…" +msgstr "A autenticar..." + +#: src/ui/views/WelcomeView.vala:163 +#, c-format +msgid "Install %s" +msgstr "Instalar %s" + +#: src/ui/views/WelcomeView.vala:164 +msgid "Return to GameHub after installing" +msgstr "Voltar ao GameHub depois da instalação" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "No games" +msgstr "Sem jogos" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "Get some games or enable some game sources in settings" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:150 +msgid "Grid view" +msgstr "Ver grelha" + +#: src/ui/views/GamesView/GamesView.vala:151 +msgid "List view" +msgstr "Ver lista" + +#: src/ui/views/GamesView/GamesView.vala:159 +msgid "All games" +msgstr "Todos os jogos" + +#: src/ui/views/GamesView/GamesView.vala:182 +msgid "Downloads" +msgstr "Transferências" + +#: src/ui/views/GamesView/GamesView.vala:208 +msgid "Filters" +msgstr "Filtros" + +#: src/ui/views/GamesView/GamesView.vala:216 +#: src/ui/views/GamesView/AddGamePopover.vala:84 +msgid "Add game" +msgstr "Adicionar jogo" + +#: src/ui/views/GamesView/GamesView.vala:223 +msgid "Search" +msgstr "Pesquisar" + +#: src/ui/views/GamesView/GamesView.vala:328 +msgid "Menu" +msgstr "Menu" + +#: src/ui/views/GamesView/GamesView.vala:329 +#: src/ui/views/GameDetailsView/GameDetailsView.vala:104 +msgid "Back" +msgstr "Voltar" + +#: src/ui/views/GamesView/GamesView.vala:550 +#, c-format +msgid "%u game" +msgid_plural "%u games" +msgstr[0] "%u jogo" +msgstr[1] "%u jogos" + +#: src/ui/views/GamesView/GamesView.vala:553 +#, c-format +msgctxt "games_view_subtitle_filtered_games" +msgid "%1$u / %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:557 +#, c-format +msgctxt "games_view_subtitle" +msgid "%1$s: %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:568 +msgid "No user-added games" +msgstr "Sem jogos adicionados pelo utilizador" + +#: src/ui/views/GamesView/GamesView.vala:569 +msgid "Add some games using plus button" +msgstr "Adicionar alguns jogos utilizando o botão +" + +#: src/ui/views/GamesView/GamesView.vala:573 +#, c-format +msgid "No %s games" +msgstr "Sem %s jogos" + +#: src/ui/views/GamesView/GamesView.vala:574 +msgid "Get some Linux-compatible games" +msgstr "Obter alguns jogos compatíveis com o Linux" + +#: src/ui/views/GamesView/GamesView.vala:584 +#, c-format +msgid "No games matching “%s”" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:589 +#, c-format +msgid "No %1$s games matching “%2$s”" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:627 +msgid "" +"No games were loaded from Steam. Set your games list privacy to public or " +"use your own Steam API key in settings." +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:628 +msgid "Privacy" +msgstr "Privacidade" + +#: src/ui/views/GamesView/GamesView.vala:739 +msgid "Downloading images" +msgstr "A transferir as imagens" + +#: src/ui/views/GamesView/GamesView.vala:753 +#, c-format +msgid "Downloading image: %s" +msgstr "A transferir imagem: %s" + +#: src/ui/views/GamesView/DownloadProgressView.vala:131 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:162 +msgid "Pause download" +msgstr "Pausar transferência" + +#: src/ui/views/GamesView/DownloadProgressView.vala:137 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:168 +msgid "Resume download" +msgstr "Retomar transferência" + +#: src/ui/views/GamesView/DownloadProgressView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:174 +msgid "Cancel download" +msgstr "Cancelar transferência" + +#: src/ui/views/GamesView/FiltersPopover.vala:77 +msgid "Group" +msgstr "Agrupar" + +#: src/ui/views/GamesView/FiltersPopover.vala:102 +msgid "Sort" +msgstr "Ordenar" + +#: src/ui/views/GamesView/FiltersPopover.vala:234 +#: src/ui/widgets/GameTagsList.vala:58 +msgid "Tags" +msgstr "Etiquetas" + +#: src/ui/views/GamesView/FiltersPopover.vala:353 +msgid "All platforms" +msgstr "Todas as plataformas" + +#: src/ui/views/GamesView/AddGamePopover.vala:77 +msgid "Select game executable" +msgstr "Selecionar executável do jogo" + +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Select game directory" +msgstr "Selecionar diretoria do jogo" + +#: src/ui/views/GamesView/AddGamePopover.vala:111 +msgid "Download game images" +msgstr "Transferir imagens do jogo" + +#: src/ui/views/GamesView/GameContextMenu.vala:87 +msgid "Details" +msgstr "Detalhes" + +#: src/ui/views/GamesView/GameContextMenu.vala:117 +msgctxt "game_context_menu" +msgid "Favorite" +msgstr "Favorito" + +#: src/ui/views/GamesView/GameContextMenu.vala:121 +msgctxt "game_context_menu" +msgid "Hidden" +msgstr "Ocultado" + +#: src/ui/views/GamesView/GameContextMenu.vala:133 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:236 +msgid "Open installation directory" +msgstr "Abrir diretoria de instalação" + +#: src/ui/views/GamesView/GameContextMenu.vala:142 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:237 +msgid "Open installers collection directory" +msgstr "Abrir diretoria da coleção de instaladores" + +#: src/ui/views/GamesView/GameContextMenu.vala:151 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:238 +msgid "Open bonus collection directory" +msgstr "Abrir diretoria da coleção de bónus" + +#: src/ui/views/GamesView/GameContextMenu.vala:160 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:239 +msgid "Open screenshots directory" +msgstr "Abrir diretoria das capturas de ecrã" + +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +msgid "Uninstall" +msgstr "Desinstalar" + +#: src/ui/views/GamesView/GameContextMenu.vala:192 +msgid "Properties" +msgstr "Propriedades" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:100 +#, c-format +msgid "%d game selected" +msgid_plural "%d games selected" +msgstr[0] "%d jogo selecionado" +msgstr[1] "%d jogos selecionados" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:144 +#, c-format +msgid "%d game will be installed" +msgid_plural "%d games will be installed" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:154 +#, c-format +msgid "%d game will be downloaded" +msgid_plural "%d games will be downloaded" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:161 +#, c-format +msgid "Image for %d game will be searched" +msgid_plural "Images for %d games will be searched" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:168 +#, c-format +msgid "%d game will be uninstalled" +msgid_plural "%d games will be uninstalled" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:174 +msgid "Refresh" +msgstr "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:175 +#, c-format +msgid "" +"%d game will be removed from database. Restart GameHub to fetch new data" +msgid_plural "" +"%d games will be removed from database. Restart GameHub to fetch new data" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:240 +msgid "Open store page" +msgstr "Abrir página da loja" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:242 +msgid "Game properties" +msgstr "Propriedades do jogo" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:46 +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:60 +msgid "Playtime" +msgstr "Tempo de Jogo" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:52 +msgid "Playtime (local)" +msgstr "Tempo de Jogo (Local)" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:69 +msgid "Last launch" +msgstr "Última execução" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:46 +msgid "Achievements" +msgstr "Proezas" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:85 +#, c-format +msgid "Unlocked: %s" +msgstr "Desbloqueado: %s" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:90 +#, c-format +msgid "Global percentage: %g%%" +msgstr "Percentagem global: %g%%" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:77 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:103 +msgid "Language" +msgstr "Idioma" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:80 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:106 +msgid "Languages" +msgstr "idiomas" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:147 +#, fuzzy, c-format +msgid "%u DLCs cannot be installed" +msgstr "%s: instalador corrompido" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:71 +msgid "Category" +msgstr "Categoria" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:74 +msgid "Categories" +msgstr "Categorias" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:90 +msgid "Genre" +msgstr "Género" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:93 +msgid "Genres" +msgstr "Géneros" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:109 +msgctxt "igdb" +msgid "Popularity" +msgstr "Popularidade" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:115 +msgctxt "igdb" +msgid "Aggregated rating" +msgstr "Classificação global" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:116 +msgctxt "igdb" +msgid "IGDB user rating" +msgstr "Classificação do utilizador IGDB" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:117 +msgctxt "igdb" +msgid "Total rating" +msgstr "Classificação Total" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:126 +msgctxt "igdb" +msgid "Release date" +msgstr "Data de lançamento" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:133 +msgctxt "igdb" +msgid "Platforms" +msgstr "Plataformas" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:139 +msgctxt "igdb" +msgid "Genres" +msgstr "Géneros" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:145 +msgctxt "igdb" +msgid "Keywords" +msgstr "Palavras-chave" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:152 +msgctxt "igdb" +msgid "Links" +msgstr "Hiperligações" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:208 +#, c-format +msgid "Based on %d rating" +msgid_plural "Based on %d ratings" +msgstr[0] "Baseado em %d classificação" +msgstr[1] "Baseado em %d classificações" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:290 +msgctxt "igdb" +msgid "Summary" +msgstr "Resumo" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:301 +msgctxt "igdb" +msgid "Storyline" +msgstr "Enredo" + +#: src/ui/widgets/FileChooserEntry.vala:49 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select file" +msgstr "Selecionar ficheiro" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "No images" +msgstr "Sem imagens" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "" +"There are no images found for this game\n" +"Make sure game name is correct" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:94 +msgid "Search images:" +msgstr "Pesquisar por imagens:" + +#: src/ui/widgets/CompatToolPicker.vala:53 +msgid "Compatibility layer:" +msgstr "Camada de compatibilidade:" + +#: src/ui/widgets/CompatToolPicker.vala:92 +msgid "Configure" +msgstr "Configurar" + +#: src/ui/widgets/GameTagsList.vala:109 +msgid "Add tag" +msgstr "Adicionar etiqueta" + +#: src/ui/widgets/TweaksList.vala:86 +msgid "No description" +msgstr "" + +#: src/ui/widgets/TweaksList.vala:124 +#, fuzzy +msgid "Edit file" +msgstr "Selecionar ficheiro" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dh" +msgstr "%dh" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dm" +msgstr "%dm" + +#: src/utils/Utils.vala:464 +#, fuzzy, c-format +msgctxt "time" +msgid "%ds" +msgstr "%dh" + +#: src/settings/UI.vala:153 +msgctxt "grid_size_preset" +msgid "Steam" +msgstr "Steam" + +#: src/settings/UI.vala:154 +msgctxt "grid_size_preset" +msgid "Steam (vertical)" +msgstr "Steam (vertical)" + +#: src/settings/UI.vala:155 +msgctxt "grid_size_preset" +msgid "GOG" +msgstr "GOG" + +#: src/settings/UI.vala:156 +msgctxt "grid_size_preset" +msgid "GOG (vertical)" +msgstr "GOG (vertical)" + +#: src/settings/UI.vala:157 +msgctxt "grid_size_preset" +msgid "Square" +msgstr "Quadrado" + +#: src/settings/UI.vala:158 +msgctxt "grid_size_preset" +msgid "Custom" +msgstr "Personalizado" + +#: src/utils/downloader/Downloader.vala:200 +msgctxt "dl_status" +msgid "Queued" +msgstr "Em fila" + +#: src/utils/downloader/Downloader.vala:201 +msgctxt "dl_status" +msgid "Starting download" +msgstr "A iniciar a transferência" + +#: src/utils/downloader/Downloader.vala:202 +msgctxt "dl_status" +msgid "Download started" +msgstr "Transferência iniciada" + +#: src/utils/downloader/Downloader.vala:203 +msgctxt "dl_status" +msgid "Download finished" +msgstr "Transferência terminada" + +#: src/utils/downloader/Downloader.vala:204 +msgctxt "dl_status" +msgid "Download failed" +msgstr "Transferência falhou" + +#: src/utils/downloader/Downloader.vala:208 +#, fuzzy, c-format +msgctxt "dl_status" +msgid "Downloading: %s" +msgstr "A transferir" + +#: src/utils/downloader/Downloader.vala:210 +#, fuzzy +msgctxt "dl_status" +msgid "Downloading" +msgstr "A transferir" + +#: src/utils/downloader/Downloader.vala:214 +#, fuzzy, c-format +msgctxt "dl_status" +msgid "Paused: %s" +msgstr "Pausada: %d%% (%s / %s)" + +#: src/utils/downloader/Downloader.vala:216 +#, fuzzy +msgctxt "dl_status" +msgid "Paused" +msgstr "Pausar transferência" + +#: src/utils/downloader/Downloader.vala:218 +msgctxt "dl_status" +msgid "Download cancelled" +msgstr "Transferência cancelada" + +#. TRANSLATORS: Download progress template. %1$d - percentage, %2$s / %3$s - downloaded portion and total file size, %4$s - download speed +#: src/utils/downloader/Downloader.vala:262 +#, fuzzy, c-format +msgctxt "dl_status" +msgid "%1$d%% (%2$s / %3$s) [%4$s/s]" +msgstr "A transferir: %d%% (%s / %s) [%s/s]" + +#~ msgid "Disable esync" +#~ msgstr "Desativar esync" + +#~ msgid "Disable DirectX 11 compatibility layer" +#~ msgstr "Desativar camada de compatibilidade com DirectX 11" + +#~ msgid "Use WineD3D11 as DirectX 11 compatibility layer" +#~ msgstr "Utilizar WineD3D11 como camada de compatibilidade com DirectX 11" + +#, fuzzy +#~ msgid "Enable DirectX 9 compatibility layer" +#~ msgstr "Desativar camada de compatibilidade com DirectX 11" + +#~ msgid "No GUI" +#~ msgstr "Sem GUI" diff --git a/po/ru.po b/po/ru.po index eb696721..99a0aa4e 100644 --- a/po/ru.po +++ b/po/ru.po @@ -2,54 +2,1926 @@ # Copyright (C) 2018 THE com.github.tkashkin.gamehub'S COPYRIGHT HOLDER # This file is distributed under the same license as the com.github.tkashkin.gamehub package. # Automatically generated, 2018. -# +# Anatoliy Kashkin , 2018, 2019. msgid "" msgstr "" "Project-Id-Version: com.github.tkashkin.gamehub\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-05-27 03:39+0300\n" -"PO-Revision-Date: 2018-05-27 03:39+0300\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"POT-Creation-Date: 2020-01-26 06:40+0300\n" +"PO-Revision-Date: 2019-01-14 12:25+0000\n" +"Last-Translator: Anatoliy Kashkin \n" +"Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" -"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 3.4-dev\n" -#: data/com.github.tkashkin.gamehub.appdata.xml.in:9 -#: data/com.github.tkashkin.gamehub.desktop.in:5 -#: src/ui/views/WelcomeView.vala:16 -msgid "All your games in one place" -msgstr "Все игры в одном месте" +#: src/app.vala:91 +msgid "Show help" +msgstr "Показать справку" + +#: src/app.vala:92 +msgid "Show application version and exit" +msgstr "Показать версию приложения и выйти" + +#: src/app.vala:93 +msgid "Restart with GDB debugger attached" +msgstr "Перезапустить с подключенным отладчиком GDB" + +#: src/app.vala:94 +msgid "Show full GDB backtrace" +msgstr "Показывать полный стек вызовов в GDB" + +#: src/app.vala:95 +msgid "Treat fatal errors as criticals and crash application" +msgstr "Считать фатальные ошибки критическими и завершать приложение" + +#: src/app.vala:99 +msgid "Show main window" +msgstr "Показать главное окно" + +#: src/app.vala:100 +msgid "Show application settings dialog" +msgstr "Показать диалог настроек приложения" + +#: src/app.vala:101 +msgid "Show about dialog" +msgstr "Показать диалог информации о программе" + +#: src/app.vala:102 +msgid "Maximum number of background worker threads" +msgstr "Максимальное количество фоновых потоков" + +#: src/app.vala:106 +msgid "Run game" +msgstr "Запустить игру" + +#: src/app.vala:107 +msgid "Show compatibility options dialog" +msgstr "Показать диалог опций совместимости" + +#: src/app.vala:108 +msgid "Open game details" +msgstr "Открыть информацию об игре" + +#: src/app.vala:109 +msgid "Open game properties" +msgstr "Открыть свойства игры" + +#: src/app.vala:113 +msgid "Enable debug logging" +msgstr "Включить отладочные сообщения" + +#: src/app.vala:114 +msgid "" +"Log authentication process and sensitive information like authentication " +"tokens" +msgstr "" +"Выводить сообщения о процессе аутентификации и конфиденциальную информацию, " +"такую как токены аутентификации" + +#: src/app.vala:115 +msgid "Log download manager" +msgstr "Выводить сообщения менеджера загрузок" + +#: src/app.vala:116 +msgid "Log background workers start/stop" +msgstr "Выводить сообщения о запуске/остановке фоновых потоков" + +#: src/app.vala:117 +msgid "Disable log messages filtering" +msgstr "Отключить фильтрацию отладочных сообщений" + +#: src/app.vala:118 +msgid "Verbose logging" +msgstr "Подробные сообщения" + +#: src/app.vala:247 +msgid "Game Options:" +msgstr "Параметры игр:" + +#: src/app.vala:247 +msgid "Show game options help" +msgstr "Показать справку о параметрах игр" + +#: src/app.vala:255 +msgid "Logging Options:" +msgstr "Параметры журналирования:" + +#: src/app.vala:255 +msgid "Show logging options help" +msgstr "Показать справку о параметрах журналирования" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +msgid "Select executable" +msgstr "Выберите исполняемый файл" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:181 src/ui/views/GamesView/GamesView.vala:330 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select" +msgstr "Выбрать" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:180 src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Cancel" +msgstr "Отмена" -#: data/com.github.tkashkin.gamehub.appdata.xml.in:12 -msgid "Manage your Steam and GOG games in one place." -msgstr "Управляйте играми из Steam и GOG в одном месте" +#: src/data/Runnable.vala:166 src/ui/widgets/FileChooserEntry.vala:49 +msgid "Select directory" +msgstr "Выберите папку" -#: src/data/sources/steam/Steam.vala:13 +#: src/data/Runnable.vala:619 +#, c-format +msgid "Part %1$u of %2$u: %3$s" +msgstr "Часть %1$u из %2$u: %3$s" + +#: src/data/Runnable.vala:642 src/ui/dialogs/CorruptedInstallerDialog.vala:48 +#, c-format +msgid "%s: corrupted installer" +msgstr "%s: повреждённый установщик" + +#: src/data/Runnable.vala:643 +#, c-format +msgid "Checksum mismatch in %s" +msgstr "Несовпадение контрольной суммы в файле %s" + +#: src/data/Runnable.vala:657 src/ui/dialogs/CorruptedInstallerDialog.vala:126 +msgid "Show file" +msgstr "Показать файл" + +#: src/data/Runnable.vala:658 src/ui/dialogs/CorruptedInstallerDialog.vala:132 +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#: src/ui/widgets/TagRow.vala:146 +msgid "Remove" +msgstr "Удалить" + +#: src/data/Runnable.vala:659 src/ui/dialogs/CorruptedInstallerDialog.vala:128 +msgid "Backup" +msgstr "Сохранить" + +#: src/data/Runnable.vala:778 +#, c-format +msgid "%s: cannot detect main executable" +msgstr "%s: невозможно определить исполняемый файл игры" + +#: src/data/Runnable.vala:779 +msgid "" +"Main executable file for this game cannot be detected automatically.\n" +"Please set main executable in game's properties." +msgstr "" +"Исполняемый файл для этой игры невозможно определить автоматически.\n" +"Укажите исполняемый файл в свойствах игры." + +#: src/data/Runnable.vala:908 +msgctxt "platform" +msgid "Emulated" +msgstr "Эмулируемые" + +#: src/data/Game.vala:625 +msgctxt "status" +msgid "Running" +msgstr "Запущена" + +#: src/data/Game.vala:628 +msgctxt "status" +msgid "Installed" +msgstr "Установлена" + +#: src/data/Game.vala:629 +msgctxt "status" +msgid "Installing" +msgstr "Установка" + +#: src/data/Game.vala:630 +msgctxt "status" +msgid "Verifying installer integrity" +msgstr "Проверка целостности установщика" + +#: src/data/Game.vala:631 +msgctxt "status" +msgid "Download started" +msgstr "Загрузка начата" + +#: src/data/Game.vala:633 +msgctxt "status" +msgid "Not installed" +msgstr "Не установлена" + +#: src/data/Game.vala:643 +msgctxt "status_header" +msgid "Installed" +msgstr "Установленные" + +#: src/data/Game.vala:644 +msgctxt "status_header" +msgid "Installing" +msgstr "Установка" + +#: src/data/Game.vala:646 +msgctxt "status_header" +msgid "Downloading" +msgstr "Загрузка" + +#: src/data/Game.vala:648 +msgctxt "status_header" +msgid "Not installed" +msgstr "Не установленные" + +#: src/data/GameSource.vala:31 +#, c-format +msgid "%s games" +msgstr "Игры из %s" + +#: src/data/sources/steam/Steam.vala:43 msgid "Your SteamID will be read from Steam configuration file" msgstr "Ваш SteamID будет прочитан из файла конфигурации Steam" -#: src/ui/views/WelcomeView.vala:16 +#: src/data/sources/steam/Steam.vala:46 +msgid "" +"Steam config file not found.\n" +"Login into your account in Steam client and return to GameHub" +msgstr "" +"Файл конфигурации Steam не найден.\n" +"Войдите в ваш аккаунт в клиенте Steam и вернитесь в GameHub" + +#: src/data/sources/gog/GOGGame.vala:983 +#, c-format +msgid "DLC: %s" +msgstr "" + +#: src/data/sources/humble/HumbleGame.vala:343 +#, c-format +msgid "%s: no available installers" +msgstr "%s: нет доступных установщиков" + +#: src/data/sources/humble/HumbleGame.vala:344 +msgid "" +"Cannot get Trove download URL.\n" +"Make sure your Humble Monthly subscription is active." +msgstr "" +"Не удалось получить URL Trove.\n" +"Убедитесь, что подписка Humble Monthly активна." + +#: src/data/sources/itch/ItchDownloader.vala:192 +#, c-format +msgctxt "itch_dl_status" +msgid "%s left;" +msgstr "%s осталось;" + +#: src/data/sources/itch/ItchDownloader.vala:195 +#, c-format +msgctxt "itch_dl_status" +msgid "%d%%" +msgstr "%d%%" + +#: src/data/sources/itch/ItchDownloader.vala:198 +#, c-format +msgctxt "itch_dl_status" +msgid "(%1$s / %2$s)" +msgstr "(%1$s / %2$s)" + +#: src/data/sources/itch/ItchDownloader.vala:201 +#, c-format +msgctxt "itch_dl_status" +msgid "[%s/s]" +msgstr "[%s/с]" + +#: src/data/sources/user/User.vala:30 +msgid "User games" +msgstr "Пользовательские игры" + +#: src/data/db/tables/Tags.vala:225 +msgctxt "tag" +msgid "Favorites" +msgstr "Избранные" + +#: src/data/db/tables/Tags.vala:226 +msgctxt "tag" +msgid "Not installed" +msgstr "Не установленные" + +#: src/data/db/tables/Tags.vala:227 +msgctxt "tag" +msgid "Installed" +msgstr "Установленные" + +#: src/data/db/tables/Tags.vala:228 +msgctxt "tag" +msgid "Hidden" +msgstr "Скрытые" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit script" +msgstr "Редактировать скрипт" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit custom script" +msgstr "Редактировать пользовательский скрипт" + +#: src/data/compat/Innoextract.vala:55 +#, c-format +msgid "" +"Innoextract %1$s is not supported and may not be able to extract some " +"games correctly.\n" +"Install innoextract %2$s or newer." +msgstr "" +"Innoextract %1$s не поддерживается и может извлекать некоторые игры " +"некорректно.\n" +"Установите innoextract %2$s или более новый." + +#: src/data/compat/WineWrap.vala:61 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:242 +#: src/ui/dialogs/CompatRunDialog.vala:102 +#: src/ui/views/GamesView/GameContextMenu.vala:53 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:234 +msgid "Run" +msgstr "Запустить" + +#: src/data/compat/WineWrap.vala:64 +msgid "Show WineWrap menu" +msgstr "Показать меню WineWrap" + +#: src/data/compat/WineWrap.vala:67 src/data/compat/Proton.vala:122 +#: src/data/compat/Wine.vala:83 +msgid "Kill apps in prefix" +msgstr "Завершить приложения в префиксе" + +#: src/data/compat/Proton.vala:47 +msgid "Proton prefix" +msgstr "Префикс Proton" + +#: src/data/compat/Proton.vala:110 src/data/compat/Wine.vala:71 +msgid "Open prefix directory" +msgstr "Открыть директорию префикса" + +#: src/data/compat/Proton.vala:113 src/data/compat/Wine.vala:74 +msgid "Run winecfg" +msgstr "Запустить winecfg" + +#: src/data/compat/Proton.vala:116 src/data/compat/Wine.vala:77 +msgid "Run winetricks" +msgstr "Запустить winetricks" + +#: src/data/compat/Proton.vala:119 src/data/compat/Wine.vala:80 +msgid "Run taskmgr" +msgstr "Запустить taskmgr" + +#: src/data/compat/Wine.vala:53 +msgid "Wine prefix" +msgstr "Префикс Wine" + +#: src/data/compat/Wine.vala:55 +msgid "Environment variables" +msgstr "Переменные окружения" + +#: src/data/compat/Wine.vala:60 +msgid "InnoSetup default options" +msgstr "Опции по умолчанию для InnoSetup" + +#: src/data/compat/RetroArch.vala:53 +msgid "Libretro core file" +msgstr "Файл ядра libretro" + +#: src/data/compat/CustomEmulator.vala:43 +msgid "Custom emulator" +msgstr "Пользовательский эмулятор" + +#: src/data/compat/CustomEmulator.vala:48 +msgid "Emulator" +msgstr "Эмулятор" + +#: src/data/compat/CustomEmulator.vala:49 +msgid "Launch in game directory" +msgstr "Запускать в папке игры" + +#: src/data/adapters/GamesAdapter.vala:440 +msgctxt "status_header" +msgid "Favorites" +msgstr "Избранные" + +#: src/data/adapters/GamesAdapter.vala:445 +#, c-format +msgctxt "status_header" +msgid "%s: Favorites" +msgstr "%s: Избранные" + +#: src/data/adapters/GamesAdapter.vala:491 +msgid "Merging games" +msgstr "Объединение игр" + +#: src/data/adapters/GamesAdapter.vala:504 +#, c-format +msgid "Merging games from %s" +msgstr "Объединение игр из %s" + +#: src/data/adapters/GamesAdapter.vala:551 +#, c-format +msgid "Loading games from %s" +msgstr "Загрузка игр из %s" + +#: src/data/adapters/GamesAdapter.vala:678 +msgctxt "sort_mode" +msgid "By name" +msgstr "По названию" + +#: src/data/adapters/GamesAdapter.vala:679 +msgctxt "sort_mode" +msgid "By last launch" +msgstr "По времени последнего запуска" + +#: src/data/adapters/GamesAdapter.vala:680 +msgctxt "sort_mode" +msgid "By playtime" +msgstr "По времени игры" + +#: src/data/adapters/GamesAdapter.vala:705 +msgctxt "group_mode" +msgid "Do not group" +msgstr "Не группировать" + +#: src/data/adapters/GamesAdapter.vala:706 +msgctxt "group_mode" +msgid "By status" +msgstr "По статусу" + +#: src/data/adapters/GamesAdapter.vala:707 +msgctxt "group_mode" +msgid "By source" +msgstr "По источнику" + +#: src/data/providers/images/SteamGridDB.vala:151 +#: src/data/providers/data/IGDB.vala:431 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:217 +msgid "Default" +msgstr "По умолчанию" + +#: src/data/providers/images/SteamGridDB.vala:158 +#: src/data/providers/data/IGDB.vala:438 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:225 +msgid "Restore default API key" +msgstr "Восстановить API-ключ по умолчанию" + +#: src/data/providers/images/SteamGridDB.vala:169 +#: src/data/providers/data/IGDB.vala:449 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:108 +msgid "API key" +msgstr "API-ключ" + +#: src/data/providers/images/SteamGridDB.vala:177 +#: src/data/providers/data/IGDB.vala:457 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:53 +msgid "Generate key" +msgstr "Сгенерировать ключ" + +#: src/data/providers/images/SteamGridDB.vala:208 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Style" +msgstr "Стиль" + +#: src/data/providers/images/SteamGridDB.vala:209 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Score" +msgstr "Счёт" + +#: src/data/providers/images/SteamGridDB.vala:213 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Author" +msgstr "Автор" + +#: src/data/providers/images/SteamGridDB.vala:225 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Alternate" +msgstr "Альтернативное" + +#: src/data/providers/images/SteamGridDB.vala:226 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Blurred" +msgstr "Размытое" + +#. TRANSLATORS: Flat / Material Design image style. Probably should not be translated +#: src/data/providers/images/SteamGridDB.vala:228 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Material" +msgstr "Material" + +#: src/data/providers/images/SteamGridDB.vala:229 +msgctxt "imagesource_steamgriddb_image_style" +msgid "No logo" +msgstr "Без логотипа" + +#: src/data/providers/images/SteamGridDB.vala:230 +msgctxt "imagesource_steamgriddb_image_style" +msgid "White logo" +msgstr "Белый логотип" + +#: src/data/providers/data/IGDB.vala:147 +msgid "" +"Monthly IGDB request quota has been reached. Set your own API key to use " +"IGDB data or disable IGDB." +msgstr "" +"Месячный лимит на запросы к IGDB достигнут. Установите свой API-ключ, чтобы " +"использовать данные IGDB или отключите IGDB." + +#: src/data/providers/data/IGDB.vala:148 +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:40 +#: src/ui/views/WelcomeView.vala:53 src/ui/views/WelcomeView.vala:78 +#: src/ui/views/GamesView/GamesView.vala:230 +#: src/ui/views/GamesView/GamesView.vala:629 +msgid "Settings" +msgstr "Настройки" + +#: src/data/providers/data/IGDB.vala:356 +msgctxt "igdb_related_link" +msgid "Official website" +msgstr "Официальный веб-сайт" + +#: src/data/providers/data/IGDB.vala:469 +msgctxt "igdb_preferred_description" +msgid "When game has description, show description" +msgstr "Если игра имеет описание, показывать описание" + +#: src/data/providers/data/IGDB.vala:476 +msgctxt "igdb_preferred_description" +msgid "of game" +msgstr "игры" + +#: src/data/providers/data/IGDB.vala:477 +msgctxt "igdb_preferred_description" +msgid "from IGDB" +msgstr "с IGDB" + +#: src/data/providers/data/IGDB.vala:478 +msgctxt "igdb_preferred_description" +msgid "both" +msgstr "все" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:65 +msgid "Some settings will be applied after application restart" +msgstr "Некоторые настройки будут применены после перезапуска приложения" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:71 +msgid "Games directory contains space. It may cause problems for some games" +msgstr "" +"Папка игр содержит пробел. Это может вызвать проблемы для некоторых игр" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:36 +msgid "Interface" +msgstr "Интерфейс" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:37 +msgid "Appearance" +msgstr "Внешний вид" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:38 +msgid "General interface settings" +msgstr "Общие настройки интерфейса" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:48 +msgid "Dark theme" +msgstr "Тёмная тема" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:53 +msgctxt "icon_style" +msgid "Theme-based" +msgstr "В зависимости от темы" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:54 +msgctxt "icon_style" +msgid "Symbolic" +msgstr "Символьные" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:55 +msgctxt "icon_style" +msgid "Colored" +msgstr "Цветные" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:57 +msgctxt "icon_style" +msgid "Icon style" +msgstr "Стиль иконок" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:84 +msgid "Game card" +msgstr "Карточка игры" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:86 +msgid "Show platform icons" +msgstr "Показывать иконки платформ" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:99 +msgctxt "grid_size" +msgid "Card size" +msgstr "Размер карточки" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:117 +msgctxt "grid_size_preset" +msgid "Presets" +msgstr "Предустановки" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:139 +msgid "Games list: installed" +msgstr "Список игр: установленные" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:140 +msgid "Games list: not installed" +msgstr "Список игр: не установленные" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:142 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:146 +msgctxt "list_style" +msgid "Show icon" +msgstr "Показывать иконку" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:143 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:147 +msgctxt "list_style" +msgid "Bold title" +msgstr "Жирный заголовок" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:144 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:148 +msgctxt "list_style" +msgid "Show status" +msgstr "Показывать статус" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:149 +msgctxt "list_style" +msgid "Dim" +msgstr "Затемнять" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:151 +msgid "Grid options" +msgstr "Опции сетки" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:152 +msgid "List options" +msgstr "Опции списка" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:31 +msgid "Behavior" +msgstr "Поведение" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:32 +msgid "Behavior settings" +msgstr "Настройки поведения" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:42 +msgid "Run games with double click" +msgstr "Запускать игры двойным кликом" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:46 +msgid "Merge games from different sources" +msgstr "Объединять игры из разных источников" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:50 +msgid "Use imported tags" +msgstr "Использовать импортированные теги" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:51 +msgid "General" +msgstr "Общие" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:52 +msgid "Collection" +msgstr "Коллекция" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:53 +msgid "Empty" +msgstr "Пусто" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:65 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:85 +msgid "Collection directory" +msgstr "Папка коллекции" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:70 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:78 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:87 +msgid "Game directory" +msgstr "Папка игры" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:71 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:79 +msgid "Installers" +msgstr "Установщики" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:72 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:98 +msgid "DLC" +msgstr "DLC" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:73 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:197 +msgid "Bonus content" +msgstr "Бонусный контент" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:84 +msgid "Variable syntax: $var or ${var}" +msgstr "Синтаксис переменных: $var или ${var}" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:86 +msgid "Game name" +msgstr "Название игры" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:88 +#: src/ui/views/GamesView/FiltersPopover.vala:127 +msgid "Platform" +msgstr "Платформа" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:36 +msgid "Controller" +msgstr "Контроллер" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +msgid "Enabled" +msgstr "Включено" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:53 +msgid "Focus GameHub window with Guide button" +msgstr "Фокусировать окно GameHub при нажатии кнопки Guide" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:57 +msgid "Controllers" +msgstr "Контроллеры" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:89 +msgid "Move focus" +msgstr "Перемещение фокуса" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:91 +msgid "Exit" +msgstr "Выход" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:40 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:108 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:92 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:95 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:36 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:77 +msgid "Disabled" +msgstr "Отключено" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:47 +#: src/ui/dialogs/GameTweaksDialog.vala:53 +#: src/ui/views/GamesView/GameContextMenu.vala:183 +msgid "Tweaks" +msgstr "Твики" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:34 +msgid "Tweak launch options and apply them to games automatically" +msgstr "Настройте опции запуска и применяйте их к играм автоматически" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:79 +msgid "" +"Tweaks are loaded from following directories in order\n" +"Last tweak overrides previous tweaks with same identifiers" +msgstr "" +"Твики загружаются из следующих директорий по порядку\n" +"Последний твик перезаписывает предущие с одинаковым идентификатором" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:83 +msgid "Click to open" +msgstr "Кликните, чтобы открыть" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:93 +#, c-format +msgid "Tweaks are loaded from %1$s and %2$d more directories (?)" +msgstr "Твики загружаются из %1$s и ещё %2$d директорий (?)" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:38 +msgid "Game sources" +msgstr "Источники игр" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +msgid "Steam API keys have limited number of uses per day" +msgstr "API-ключи Steam имеют ограничение на количество использований в день" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:63 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:57 +msgid "Installation directory" +msgstr "Папка установки" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:176 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:81 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:34 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:75 +msgid "Not installed" +msgstr "Не установлен" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:116 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:96 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:99 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:85 +msgid "Not authenticated" +msgstr "Не авторизован" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +#, c-format +msgid "Authenticated as %s" +msgstr "Авторизован как %s" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:103 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +msgid "Authenticated" +msgstr "Авторизован" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:183 +#: src/ui/dialogs/InstallDialog.vala:53 src/ui/dialogs/InstallDialog.vala:111 +#: src/ui/views/GamesView/GameContextMenu.vala:80 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:233 +#: src/ui/widgets/TweaksList.vala:95 +msgid "Install" +msgstr "Установить" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:236 +msgid "Steam API key" +msgstr "API-ключ Steam" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:50 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:54 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:48 +msgid "Games directory" +msgstr "Папка игр" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:63 +msgid "Logout" +msgstr "Выйти" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:50 +msgid "Load games from Humble Trove" +msgstr "Загружать игры из Humble Trove" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:45 +msgid "Emulators" +msgstr "Эмуляторы" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:45 +msgid "Libretro core directory" +msgstr "Папка ядер libretro" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:46 +msgid "Libretro core info directory" +msgstr "Папка информации о ядрах libretro" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:50 +msgid "Ignored libretro cores" +msgstr "Игнорируемые ядра libretro" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:54 +msgid "Ignored game file extensions" +msgstr "Игнорируемые расширения файлов игр" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:66 +msgid "No cores found" +msgstr "Ядра не найдены" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:70 +#, c-format +msgid "%u core found" +msgid_plural "%u cores found" +msgstr[0] "Найдено %u ядро" +msgstr[1] "Найдено %u ядра" +msgstr[2] "Найдено %u ядер" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:46 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:168 +msgid "No custom emulators" +msgstr "Нет пользовательских эмуляторов" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:164 +#, c-format +msgid "%u custom emulator" +msgid_plural "%u custom emulators" +msgstr[0] "%u пользовательский эмулятор" +msgstr[1] "%u пользовательских эмулятора" +msgstr[2] "%u пользовательских эмуляторов" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:237 +msgid "Save" +msgstr "Сохранить" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:250 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:312 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/dialogs/GamePropertiesDialog.vala:168 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +#: src/ui/views/GamesView/AddGamePopover.vala:67 +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Executable" +msgstr "Исполняемый файл" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:251 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/views/GamesView/AddGamePopover.vala:68 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Installer" +msgstr "Установщик" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:256 +#: src/ui/dialogs/GamePropertiesDialog.vala:64 +#: src/ui/dialogs/GamePropertiesDialog.vala:69 +#: src/ui/views/GamesView/AddGamePopover.vala:73 +msgid "Name" +msgstr "Название" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:272 +#: src/ui/dialogs/GamePropertiesDialog.vala:201 +#: src/ui/views/GamesView/AddGamePopover.vala:78 +msgid "Arguments" +msgstr "Параметры" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:276 +msgid "Variables" +msgstr "Переменные" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:277 +msgid "Game executable" +msgstr "Исполняемый файл игры" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:278 +msgid "Game arguments" +msgstr "Параметры игры" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:80 +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Directory" +msgstr "Папка" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +msgid "Select emulator directory" +msgstr "Выберите папку эмулятора" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:292 +#: src/ui/dialogs/GamePropertiesDialog.vala:219 +msgid "Force compatibility mode" +msgstr "Использовать режим совместимости" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:307 +msgid "Game file patterns" +msgstr "Маски файлов игр" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:315 +msgid "Image" +msgstr "Изображение" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:318 +msgid "Icon" +msgstr "Иконка" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:325 +msgid "" +"findutils-compatible glob patterns\n" +"\n" +" Multiple patterns can be separated with |\n" +" Start pattern with ./ to match relative path\n" +" $basename variable will be replaced with game's executable " +"name (without extension)" +msgstr "" +"findutils-совместимые glob-маски\n" +"\n" +" Несколько масок могут быть разделены |\n" +" Начните маску с ./, чтобы использовать относительный путь\n" +" Переменная $basename будет заменена на имя исполняемого " +"файла игры (без расширения)" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:38 +msgid "Data" +msgstr "Данные" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:39 +msgid "Providers" +msgstr "Провайдеры" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:40 +msgid "Third-party data providers" +msgstr "Сторонние источники данных" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:55 +msgid "Image providers" +msgstr "Источники изображений" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:68 +msgid "Metadata providers" +msgstr "Источники метаданных" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:137 +msgid "Open website" +msgstr "Открыть веб-сайт" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:36 +msgid "About" +msgstr "О программе" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:71 +msgid "Copy application version and environment info" +msgstr "Копировать версию приложения и информацию об окружении" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:78 +#: src/ui/views/WelcomeView.vala:57 +msgid "All your games in one place" +msgstr "Все игры в одном месте" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:92 +msgctxt "about_link" +msgid "Website" +msgstr "Веб-сайт" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:96 +msgctxt "about_link" +msgid "Source code on GitHub" +msgstr "Исходный код на GitHub" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:103 +msgctxt "about_link" +msgid "Report a problem" +msgstr "Сообщить о проблеме" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:104 +msgctxt "about_link" +msgid "Suggest translations" +msgstr "Предложить переводы" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:110 +msgctxt "about_link" +msgid "Issues" +msgstr "Проблемы" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:111 +msgctxt "about_link" +msgid "Contributors" +msgstr "Авторы" + +#. TRANSLATORS: Likely it should not be translated. GitHub Pulse is a page that shows recent repository activity: https://github.com/tkashkin/GameHub/pulse +#: src/ui/dialogs/SettingsDialog/pages/About.vala:114 +msgctxt "about_link" +msgid "Pulse" +msgstr "Pulse" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:115 +msgctxt "about_link" +msgid "Forks" +msgstr "Форки" + +#: src/ui/dialogs/InstallDialog.vala:109 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:129 +msgid "Import" +msgstr "Импортировать" + +#: src/ui/dialogs/InstallDialog.vala:110 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:153 +msgid "Download" +msgstr "Загрузить" + +#: src/ui/dialogs/InstallDialog.vala:207 +msgid "Select installer" +msgstr "Выберите установщик" + +#: src/ui/dialogs/InstallDialog.vala:216 +#, c-format +msgid "Installer size: %s" +msgstr "Размер установщика: %s" + +#: src/ui/dialogs/InstallDialog.vala:348 +msgid "Unknown" +msgstr "Неизвестно" + +#: src/ui/dialogs/GamePropertiesDialog.vala:49 +#, c-format +msgid "%s: Properties" +msgstr "%s: Свойства" + +#: src/ui/dialogs/GamePropertiesDialog.vala:84 +msgid "Images" +msgstr "Изображения" + +#: src/ui/dialogs/GamePropertiesDialog.vala:126 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:160 +#: src/ui/views/GameDetailsView/blocks/Artwork.vala:62 +msgid "Download images" +msgstr "Загрузить изображения" + +#: src/ui/dialogs/GamePropertiesDialog.vala:144 +msgid "Image URL" +msgstr "URL изображения" + +#: src/ui/dialogs/GamePropertiesDialog.vala:148 +msgid "Vertical image URL" +msgstr "URL вертикального изображения" + +#: src/ui/dialogs/GamePropertiesDialog.vala:157 +msgid "Icon URL" +msgstr "URL иконки" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Select working directory" +msgstr "Выберите рабочую директорию" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Working directory" +msgstr "Рабочая директория" + +#: src/ui/dialogs/GamePropertiesDialog.vala:214 +msgid "Compatibility" +msgstr "Совместимость" + +#: src/ui/dialogs/GamePropertiesDialog.vala:236 +msgid "Launch from terminal" +msgstr "Запустить из терминала" + +#: src/ui/dialogs/GamePropertiesDialog.vala:252 +msgid "Copy to clipboard" +msgstr "Копировать в буфер обмена" + +#: src/ui/dialogs/GamePropertiesDialog.vala:254 +msgid "Add to Steam" +msgstr "Добавить в Steam" + +#: src/ui/dialogs/GamePropertiesDialog.vala:255 +msgid "Add to the Steam library" +msgstr "Добавить в библиотеку Steam" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:53 +#, c-format +msgid "%s: Overlays" +msgstr "%s: Оверлеи" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "Overlays are disabled" +msgstr "Оверлеи выключены" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "" +"Enable overlays to manage DLCs and mods\n" +"\n" +"Enabling will move game to the “base“ overlay" +msgstr "" +"Включите оверлеи для управления DLC и модификациями\n" +"\n" +"Включение приведёт к перемещению файлов игры в оверлей «base»" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:77 +#: src/ui/views/GamesView/GameContextMenu.vala:175 +msgid "Overlays" +msgstr "Оверлеи" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:105 +msgid "Overlay ID (directory name)" +msgstr "ID оверлея (название папки)" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:110 +msgid "Overlay name (optional)" +msgstr "Название оверлея (опционально)" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:112 +msgid "Add" +msgstr "Добавить" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:127 +msgid "Enable overlays" +msgstr "Включить оверлеи" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:182 +#, c-format +msgid "" +"Overlay usage at this path may be unsafe\n" +"Proceed at your own risk\n" +"\n" +"Path: %s" +msgstr "" +"Использование оверлеев в этой директории может быть небезопасно\n" +"Продолжайте на свой страх и риск\n" +"\n" +"Путь: %s" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:187 +#, c-format +msgid "" +"Overlay usage at this path is not supported\n" +"\n" +"Path: %s" +msgstr "" +"Использование оверлеев в этой директории не поддерживается\n" +"\n" +"Путь: %s" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:266 +msgid "Open directory" +msgstr "Открыть папку" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:271 +msgid "Remove overlay" +msgstr "Удалить оверлей" + +#: src/ui/dialogs/CompatRunDialog.vala:48 +#: src/ui/views/GamesView/GameContextMenu.vala:46 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:235 +msgid "Run with compatibility layer" +msgstr "Запустить, используя слой совместимости" + +#: src/ui/dialogs/CorruptedInstallerDialog.vala:71 +msgid "Corrupted installer: checksum mismatch in" +msgstr "повреждённый установщик: несовпадение контрольной суммы в файле" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:57 +#: src/ui/views/GamesView/AddGamePopover.vala:105 +msgid "Import emulated games" +msgstr "Импортировать эмулируемые игры" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:75 +msgid "Select directory with emulated games" +msgstr "Выберите папку с эмулируемыми играми" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:83 +msgid "Detected games" +msgstr "Обнаруженные игры" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:107 +msgid "Select all" +msgstr "Выделить всё" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:115 +msgid "Select directory to import" +msgstr "Выберите папку для импорта" + +#: src/ui/dialogs/GameTweaksDialog.vala:40 +#, c-format +msgid "%s: Tweaks" +msgstr "%s: Твики" + +#: src/ui/views/WelcomeView.vala:52 +msgid "No enabled game sources" +msgstr "Нет активных источников игр" + +#: src/ui/views/WelcomeView.vala:52 +msgid "Enable some game sources in settings" +msgstr "Включите источники в настройках" + +#: src/ui/views/WelcomeView.vala:57 msgid "Let's get started" msgstr "Давайте начнём" -#: src/ui/views/WelcomeView.vala:24 +#: src/ui/views/WelcomeView.vala:71 msgid "Skip" msgstr "Пропустить" -#: src/ui/views/WelcomeView.vala:60 -#, c-format -msgid "%d games loaded" -msgstr "Найдено %d игр" +#: src/ui/views/WelcomeView.vala:141 +msgid "Ready" +msgstr "Готово" -#: src/ui/views/WelcomeView.vala:65 +#: src/ui/views/WelcomeView.vala:147 msgid "Authentication required" msgstr "Требуется авторизация" -#: src/ui/views/WelcomeView.vala:70 +#: src/ui/views/WelcomeView.vala:152 +msgid "Authenticating…" +msgstr "Авторизация…" + +#: src/ui/views/WelcomeView.vala:163 #, c-format msgid "Install %s" msgstr "Установить %s" + +#: src/ui/views/WelcomeView.vala:164 +msgid "Return to GameHub after installing" +msgstr "Вернитесь в GameHub после установки" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "No games" +msgstr "Нет игр" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "Get some games or enable some game sources in settings" +msgstr "Получите игры или включите источники в настройках" + +#: src/ui/views/GamesView/GamesView.vala:150 +msgid "Grid view" +msgstr "Сетка" + +#: src/ui/views/GamesView/GamesView.vala:151 +msgid "List view" +msgstr "Список" + +#: src/ui/views/GamesView/GamesView.vala:159 +msgid "All games" +msgstr "Все игры" + +#: src/ui/views/GamesView/GamesView.vala:182 +msgid "Downloads" +msgstr "Загрузки" + +#: src/ui/views/GamesView/GamesView.vala:208 +msgid "Filters" +msgstr "Фильтры" + +#: src/ui/views/GamesView/GamesView.vala:216 +#: src/ui/views/GamesView/AddGamePopover.vala:84 +msgid "Add game" +msgstr "Добавить игру" + +#: src/ui/views/GamesView/GamesView.vala:223 +msgid "Search" +msgstr "Поиск" + +#: src/ui/views/GamesView/GamesView.vala:328 +msgid "Menu" +msgstr "Меню" + +#: src/ui/views/GamesView/GamesView.vala:329 +#: src/ui/views/GameDetailsView/GameDetailsView.vala:104 +msgid "Back" +msgstr "Назад" + +#: src/ui/views/GamesView/GamesView.vala:550 +#, c-format +msgid "%u game" +msgid_plural "%u games" +msgstr[0] "%u игра" +msgstr[1] "%u игры" +msgstr[2] "%u игр" + +#: src/ui/views/GamesView/GamesView.vala:553 +#, c-format +msgctxt "games_view_subtitle_filtered_games" +msgid "%1$u / %2$s" +msgstr "%1$u / %2$s" + +#: src/ui/views/GamesView/GamesView.vala:557 +#, c-format +msgctxt "games_view_subtitle" +msgid "%1$s: %2$s" +msgstr "%1$s: %2$s" + +#: src/ui/views/GamesView/GamesView.vala:568 +msgid "No user-added games" +msgstr "Нет пользовательских игр" + +#: src/ui/views/GamesView/GamesView.vala:569 +msgid "Add some games using plus button" +msgstr "Добавьте игры с помощью кнопки +" + +#: src/ui/views/GamesView/GamesView.vala:573 +#, c-format +msgid "No %s games" +msgstr "Нет игр из %s" + +#: src/ui/views/GamesView/GamesView.vala:574 +msgid "Get some Linux-compatible games" +msgstr "Получите игры, совместимые с Linux" + +#: src/ui/views/GamesView/GamesView.vala:584 +#, c-format +msgid "No games matching “%s”" +msgstr "Нет игр, соответствующих запросу «%s»" + +#: src/ui/views/GamesView/GamesView.vala:589 +#, c-format +msgid "No %1$s games matching “%2$s”" +msgstr "Нет игр из %1$s, соответствующих запросу «%2$s»" + +#: src/ui/views/GamesView/GamesView.vala:627 +msgid "" +"No games were loaded from Steam. Set your games list privacy to public or " +"use your own Steam API key in settings." +msgstr "" +"Нет игр, загруженных из Steam. Настройте список игр как публичный или " +"используйте свой API-ключ Steam в настройках." + +#: src/ui/views/GamesView/GamesView.vala:628 +msgid "Privacy" +msgstr "Приватность" + +#: src/ui/views/GamesView/GamesView.vala:739 +msgid "Downloading images" +msgstr "Загрузка изображений" + +#: src/ui/views/GamesView/GamesView.vala:753 +#, c-format +msgid "Downloading image: %s" +msgstr "Загрузка изображений: %s" + +#: src/ui/views/GamesView/DownloadProgressView.vala:131 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:162 +msgid "Pause download" +msgstr "Приостановить загрузку" + +#: src/ui/views/GamesView/DownloadProgressView.vala:137 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:168 +msgid "Resume download" +msgstr "Возобновить загрузку" + +#: src/ui/views/GamesView/DownloadProgressView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:174 +msgid "Cancel download" +msgstr "Отменить загрузку" + +#: src/ui/views/GamesView/FiltersPopover.vala:77 +msgid "Group" +msgstr "Группировка" + +#: src/ui/views/GamesView/FiltersPopover.vala:102 +msgid "Sort" +msgstr "Сортировка" + +#: src/ui/views/GamesView/FiltersPopover.vala:234 +#: src/ui/widgets/GameTagsList.vala:58 +msgid "Tags" +msgstr "Теги" + +#: src/ui/views/GamesView/FiltersPopover.vala:353 +msgid "All platforms" +msgstr "Все платформы" + +#: src/ui/views/GamesView/AddGamePopover.vala:77 +msgid "Select game executable" +msgstr "Выберите исполняемый файл игры" + +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Select game directory" +msgstr "Выберите папку игры" + +#: src/ui/views/GamesView/AddGamePopover.vala:111 +msgid "Download game images" +msgstr "Загрузить изображения игр" + +#: src/ui/views/GamesView/GameContextMenu.vala:87 +msgid "Details" +msgstr "Подробности" + +#: src/ui/views/GamesView/GameContextMenu.vala:117 +msgctxt "game_context_menu" +msgid "Favorite" +msgstr "Избранная" + +#: src/ui/views/GamesView/GameContextMenu.vala:121 +msgctxt "game_context_menu" +msgid "Hidden" +msgstr "Скрытая" + +#: src/ui/views/GamesView/GameContextMenu.vala:133 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:236 +msgid "Open installation directory" +msgstr "Открыть папку установки" + +#: src/ui/views/GamesView/GameContextMenu.vala:142 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:237 +msgid "Open installers collection directory" +msgstr "Открыть папку коллекции установщиков" + +#: src/ui/views/GamesView/GameContextMenu.vala:151 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:238 +msgid "Open bonus collection directory" +msgstr "Открыть папку коллекции бонусного контента" + +#: src/ui/views/GamesView/GameContextMenu.vala:160 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:239 +msgid "Open screenshots directory" +msgstr "Открыть папку скриншотов" + +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +msgid "Uninstall" +msgstr "Деинсталлировать" + +#: src/ui/views/GamesView/GameContextMenu.vala:192 +msgid "Properties" +msgstr "Свойства" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:100 +#, c-format +msgid "%d game selected" +msgid_plural "%d games selected" +msgstr[0] "Выделена %d игра" +msgstr[1] "Выделено %d игры" +msgstr[2] "Выделено %d игр" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:144 +#, c-format +msgid "%d game will be installed" +msgid_plural "%d games will be installed" +msgstr[0] "Будет установлена %d игра" +msgstr[1] "Будут установлены %d игры" +msgstr[2] "Будут установлены %d игр" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:154 +#, c-format +msgid "%d game will be downloaded" +msgid_plural "%d games will be downloaded" +msgstr[0] "Будет загружена %d игра" +msgstr[1] "Будут загружены %d игры" +msgstr[2] "Будут загружены %d игр" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:161 +#, c-format +msgid "Image for %d game will be searched" +msgid_plural "Images for %d games will be searched" +msgstr[0] "Будет найдено изображение для %d игры" +msgstr[1] "Будут найдены изображения для %d игр" +msgstr[2] "Будут найдены изображения для %d игр" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:168 +#, c-format +msgid "%d game will be uninstalled" +msgid_plural "%d games will be uninstalled" +msgstr[0] "Будет удалена %d игра" +msgstr[1] "Будут удалены %d игры" +msgstr[2] "Будут удалены %d игр" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:174 +msgid "Refresh" +msgstr "Обновить" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:175 +#, c-format +msgid "" +"%d game will be removed from database. Restart GameHub to fetch new data" +msgid_plural "" +"%d games will be removed from database. Restart GameHub to fetch new data" +msgstr[0] "" +"%d игра будет удалена из базы данных. Перезапустите GameHub, чтобы загрузить " +"новые данные" +msgstr[1] "" +"%d игры будут удалены из базы данных. Перезапустите GameHub, чтобы загрузить " +"новые данные" +msgstr[2] "" +"%d игр будут удалены из базы данных. Перезапустите GameHub, чтобы загрузить " +"новые данные" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:240 +msgid "Open store page" +msgstr "Открыть страницу в магазине" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:242 +msgid "Game properties" +msgstr "Свойства игры" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:46 +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:60 +msgid "Playtime" +msgstr "Время игры" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:52 +msgid "Playtime (local)" +msgstr "Время игры (локальное)" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:69 +msgid "Last launch" +msgstr "Последний запуск" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:46 +msgid "Achievements" +msgstr "Достижения" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:85 +#, c-format +msgid "Unlocked: %s" +msgstr "Открыто: %s" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:90 +#, c-format +msgid "Global percentage: %g%%" +msgstr "Глобальный процент: %g%%" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:77 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:103 +msgid "Language" +msgstr "Язык" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:80 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:106 +msgid "Languages" +msgstr "Языки" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:147 +#, c-format +msgid "%u DLCs cannot be installed" +msgstr "%u DLC не могут быть установлены" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:71 +msgid "Category" +msgstr "Категория" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:74 +msgid "Categories" +msgstr "Категории" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:90 +msgid "Genre" +msgstr "Жанр" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:93 +msgid "Genres" +msgstr "Жанры" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:109 +msgctxt "igdb" +msgid "Popularity" +msgstr "Популярность" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:115 +msgctxt "igdb" +msgid "Aggregated rating" +msgstr "Рейтинг критиков" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:116 +msgctxt "igdb" +msgid "IGDB user rating" +msgstr "Рейтинг пользователей IGDB" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:117 +msgctxt "igdb" +msgid "Total rating" +msgstr "Общий рейтинг" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:126 +msgctxt "igdb" +msgid "Release date" +msgstr "Дата выхода" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:133 +msgctxt "igdb" +msgid "Platforms" +msgstr "Платформы" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:139 +msgctxt "igdb" +msgid "Genres" +msgstr "Жанры" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:145 +msgctxt "igdb" +msgid "Keywords" +msgstr "Ключевые слова" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:152 +msgctxt "igdb" +msgid "Links" +msgstr "Ссылки" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:208 +#, c-format +msgid "Based on %d rating" +msgid_plural "Based on %d ratings" +msgstr[0] "На основе %d оценки" +msgstr[1] "На основе %d оценок" +msgstr[2] "На основе %d оценок" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:290 +msgctxt "igdb" +msgid "Summary" +msgstr "Описание" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:301 +msgctxt "igdb" +msgid "Storyline" +msgstr "Сюжет" + +#: src/ui/widgets/FileChooserEntry.vala:49 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select file" +msgstr "Выбрать файл" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "No images" +msgstr "Нет изображений" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "" +"There are no images found for this game\n" +"Make sure game name is correct" +msgstr "" +"Для этой игры нет подходящих изображений\n" +"Убедитесь в правильности названия игры" + +#: src/ui/widgets/ImagesDownloadPopover.vala:94 +msgid "Search images:" +msgstr "Поиск изображений:" + +#: src/ui/widgets/CompatToolPicker.vala:53 +msgid "Compatibility layer:" +msgstr "Слой совместимости:" + +#: src/ui/widgets/CompatToolPicker.vala:92 +msgid "Configure" +msgstr "Настроить" + +#: src/ui/widgets/GameTagsList.vala:109 +msgid "Add tag" +msgstr "Добавить тег" + +#: src/ui/widgets/TweaksList.vala:86 +msgid "No description" +msgstr "Нет описания" + +#: src/ui/widgets/TweaksList.vala:124 +msgid "Edit file" +msgstr "Редактировать файл" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dh" +msgstr "%dч" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dm" +msgstr "%dм" + +#: src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%ds" +msgstr "%dс" + +#: src/settings/UI.vala:153 +msgctxt "grid_size_preset" +msgid "Steam" +msgstr "Steam" + +#: src/settings/UI.vala:154 +msgctxt "grid_size_preset" +msgid "Steam (vertical)" +msgstr "Steam (вертикальный)" + +#: src/settings/UI.vala:155 +msgctxt "grid_size_preset" +msgid "GOG" +msgstr "GOG" + +#: src/settings/UI.vala:156 +msgctxt "grid_size_preset" +msgid "GOG (vertical)" +msgstr "GOG (вертикальный)" + +#: src/settings/UI.vala:157 +msgctxt "grid_size_preset" +msgid "Square" +msgstr "Квадрат" + +#: src/settings/UI.vala:158 +msgctxt "grid_size_preset" +msgid "Custom" +msgstr "Пользовательский" + +#: src/utils/downloader/Downloader.vala:200 +msgctxt "dl_status" +msgid "Queued" +msgstr "В очереди" + +#: src/utils/downloader/Downloader.vala:201 +msgctxt "dl_status" +msgid "Starting download" +msgstr "Начало загрузки" + +#: src/utils/downloader/Downloader.vala:202 +msgctxt "dl_status" +msgid "Download started" +msgstr "Загрузка начата" + +#: src/utils/downloader/Downloader.vala:203 +msgctxt "dl_status" +msgid "Download finished" +msgstr "Загрузка завершена" + +#: src/utils/downloader/Downloader.vala:204 +msgctxt "dl_status" +msgid "Download failed" +msgstr "Ошибка загрузки" + +#: src/utils/downloader/Downloader.vala:208 +#, c-format +msgctxt "dl_status" +msgid "Downloading: %s" +msgstr "Загрузка: %s" + +#: src/utils/downloader/Downloader.vala:210 +msgctxt "dl_status" +msgid "Downloading" +msgstr "Загрузка" + +#: src/utils/downloader/Downloader.vala:214 +#, c-format +msgctxt "dl_status" +msgid "Paused: %s" +msgstr "Приостановлено: %s" + +#: src/utils/downloader/Downloader.vala:216 +msgctxt "dl_status" +msgid "Paused" +msgstr "Приостановлено" + +#: src/utils/downloader/Downloader.vala:218 +msgctxt "dl_status" +msgid "Download cancelled" +msgstr "Загрузка отменена" + +#. TRANSLATORS: Download progress template. %1$d - percentage, %2$s / %3$s - downloaded portion and total file size, %4$s - download speed +#: src/utils/downloader/Downloader.vala:262 +#, c-format +msgctxt "dl_status" +msgid "%1$d%% (%2$s / %3$s) [%4$s/s]" +msgstr "%1$d%% (%2$s / %3$s) [%4$s/с]" + +#~ msgid "Disable esync" +#~ msgstr "Выключить esync" + +#~ msgid "Force LARGE_ADDRESS_AWARE flag" +#~ msgstr "Принудительно использовать флаг LARGE_ADDRESS_AWARE" + +#~ msgid "Disable DirectX 11 compatibility layer" +#~ msgstr "Выключить слой совместимости с DirectX 11" + +#~ msgid "Use WineD3D11 as DirectX 11 compatibility layer" +#~ msgstr "Использовать WineD3D11 как слой совместимости DirectX 11" + +#~ msgid "Show DXVK info overlay" +#~ msgstr "Показывать оверлей DXVK" + +#~ msgid "Enable DirectX 9 compatibility layer" +#~ msgstr "Выключить слой совместимости с DirectX 9" + +#~ msgid "Silent installation" +#~ msgstr "Тихая установка" + +#~ msgid "Very silent installation" +#~ msgstr "Очень тихая установка" + +#~ msgid "Suppress messages" +#~ msgstr "Подавить сообщения" + +#~ msgid "No GUI" +#~ msgstr "Без интерфейса" + +#~ msgctxt "igdb" +#~ msgid "%s on IGDB" +#~ msgstr "%s на IGDB" + +#~ msgid "Disable fullscreen" +#~ msgstr "Выключить полноэкранный режим" + +#~ msgid "Windowed" +#~ msgstr "Оконный режим" + +#~ msgid "Compact list" +#~ msgstr "Компактный список" + +#~ msgid "Show non-native games" +#~ msgstr "Показывать ненативные игры" + +#~ msgid "Use compatibility layers and consider Windows games compatible" +#~ msgstr "" +#~ "Использовать слои совместимости и считать игры для Windows совместимыми" + +#~ msgid "Glob patterns separated with |" +#~ msgstr "Glob-маски, разделённые |" + +#~ msgid "About GameHub" +#~ msgstr "О GameHub" + +#~ msgid "Use symbolic icons instead of colored icons" +#~ msgstr "Использовать символьные иконки вместо цветных" + +#~ msgid "Enable controller support" +#~ msgstr "Включить поддержку контроллера" + +#~ msgid "Reload" +#~ msgstr "Обновить" + +#~ msgid "Updating game info" +#~ msgstr "Обновление информации об играх" + +#~ msgid "Updating %s game info" +#~ msgstr "Обновление информации об играх из %s" + +#~ msgid "Merging %s (%s)" +#~ msgstr "Объединение %s (%s)" diff --git a/po/te.po b/po/te.po new file mode 100644 index 00000000..40a115fc --- /dev/null +++ b/po/te.po @@ -0,0 +1,1799 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the com.github.tkashkin.gamehub package. +# asher hrudai , 2019. +msgid "" +msgstr "" +"Project-Id-Version: com.github.tkashkin.gamehub\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-26 06:40+0300\n" +"PO-Revision-Date: 2019-08-11 08:23+0000\n" +"Last-Translator: asher hrudai \n" +"Language-Team: Telugu \n" +"Language: te\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 3.8-dev\n" + +#: src/app.vala:91 +msgid "Show help" +msgstr "Sahayam chupincu" + +#: src/app.vala:92 +msgid "Show application version and exit" +msgstr "" + +#: src/app.vala:93 +msgid "Restart with GDB debugger attached" +msgstr "" + +#: src/app.vala:94 +msgid "Show full GDB backtrace" +msgstr "" + +#: src/app.vala:95 +msgid "Treat fatal errors as criticals and crash application" +msgstr "" + +#: src/app.vala:99 +msgid "Show main window" +msgstr "" + +#: src/app.vala:100 +msgid "Show application settings dialog" +msgstr "" + +#: src/app.vala:101 +msgid "Show about dialog" +msgstr "" + +#: src/app.vala:102 +msgid "Maximum number of background worker threads" +msgstr "" + +#: src/app.vala:106 +msgid "Run game" +msgstr "" + +#: src/app.vala:107 +msgid "Show compatibility options dialog" +msgstr "" + +#: src/app.vala:108 +msgid "Open game details" +msgstr "" + +#: src/app.vala:109 +msgid "Open game properties" +msgstr "" + +#: src/app.vala:113 +msgid "Enable debug logging" +msgstr "" + +#: src/app.vala:114 +msgid "" +"Log authentication process and sensitive information like authentication " +"tokens" +msgstr "" + +#: src/app.vala:115 +msgid "Log download manager" +msgstr "" + +#: src/app.vala:116 +msgid "Log background workers start/stop" +msgstr "" + +#: src/app.vala:117 +msgid "Disable log messages filtering" +msgstr "" + +#: src/app.vala:118 +msgid "Verbose logging" +msgstr "" + +#: src/app.vala:247 +msgid "Game Options:" +msgstr "" + +#: src/app.vala:247 +msgid "Show game options help" +msgstr "" + +#: src/app.vala:255 +msgid "Logging Options:" +msgstr "" + +#: src/app.vala:255 +msgid "Show logging options help" +msgstr "" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +msgid "Select executable" +msgstr "" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:181 src/ui/views/GamesView/GamesView.vala:330 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select" +msgstr "" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:180 src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Cancel" +msgstr "" + +#: src/data/Runnable.vala:166 src/ui/widgets/FileChooserEntry.vala:49 +msgid "Select directory" +msgstr "" + +#: src/data/Runnable.vala:619 +#, c-format +msgid "Part %1$u of %2$u: %3$s" +msgstr "" + +#: src/data/Runnable.vala:642 src/ui/dialogs/CorruptedInstallerDialog.vala:48 +#, c-format +msgid "%s: corrupted installer" +msgstr "" + +#: src/data/Runnable.vala:643 +#, c-format +msgid "Checksum mismatch in %s" +msgstr "" + +#: src/data/Runnable.vala:657 src/ui/dialogs/CorruptedInstallerDialog.vala:126 +msgid "Show file" +msgstr "" + +#: src/data/Runnable.vala:658 src/ui/dialogs/CorruptedInstallerDialog.vala:132 +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#: src/ui/widgets/TagRow.vala:146 +msgid "Remove" +msgstr "" + +#: src/data/Runnable.vala:659 src/ui/dialogs/CorruptedInstallerDialog.vala:128 +msgid "Backup" +msgstr "" + +#: src/data/Runnable.vala:778 +#, c-format +msgid "%s: cannot detect main executable" +msgstr "" + +#: src/data/Runnable.vala:779 +msgid "" +"Main executable file for this game cannot be detected automatically.\n" +"Please set main executable in game's properties." +msgstr "" + +#: src/data/Runnable.vala:908 +msgctxt "platform" +msgid "Emulated" +msgstr "" + +#: src/data/Game.vala:625 +msgctxt "status" +msgid "Running" +msgstr "" + +#: src/data/Game.vala:628 +msgctxt "status" +msgid "Installed" +msgstr "" + +#: src/data/Game.vala:629 +msgctxt "status" +msgid "Installing" +msgstr "" + +#: src/data/Game.vala:630 +msgctxt "status" +msgid "Verifying installer integrity" +msgstr "" + +#: src/data/Game.vala:631 +msgctxt "status" +msgid "Download started" +msgstr "" + +#: src/data/Game.vala:633 +msgctxt "status" +msgid "Not installed" +msgstr "" + +#: src/data/Game.vala:643 +msgctxt "status_header" +msgid "Installed" +msgstr "" + +#: src/data/Game.vala:644 +msgctxt "status_header" +msgid "Installing" +msgstr "" + +#: src/data/Game.vala:646 +msgctxt "status_header" +msgid "Downloading" +msgstr "" + +#: src/data/Game.vala:648 +msgctxt "status_header" +msgid "Not installed" +msgstr "" + +#: src/data/GameSource.vala:31 +#, c-format +msgid "%s games" +msgstr "" + +#: src/data/sources/steam/Steam.vala:43 +msgid "Your SteamID will be read from Steam configuration file" +msgstr "" + +#: src/data/sources/steam/Steam.vala:46 +msgid "" +"Steam config file not found.\n" +"Login into your account in Steam client and return to GameHub" +msgstr "" + +#: src/data/sources/gog/GOGGame.vala:983 +#, c-format +msgid "DLC: %s" +msgstr "" + +#: src/data/sources/humble/HumbleGame.vala:343 +#, c-format +msgid "%s: no available installers" +msgstr "" + +#: src/data/sources/humble/HumbleGame.vala:344 +msgid "" +"Cannot get Trove download URL.\n" +"Make sure your Humble Monthly subscription is active." +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:192 +#, c-format +msgctxt "itch_dl_status" +msgid "%s left;" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:195 +#, c-format +msgctxt "itch_dl_status" +msgid "%d%%" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:198 +#, c-format +msgctxt "itch_dl_status" +msgid "(%1$s / %2$s)" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:201 +#, c-format +msgctxt "itch_dl_status" +msgid "[%s/s]" +msgstr "" + +#: src/data/sources/user/User.vala:30 +msgid "User games" +msgstr "" + +#: src/data/db/tables/Tags.vala:225 +msgctxt "tag" +msgid "Favorites" +msgstr "" + +#: src/data/db/tables/Tags.vala:226 +msgctxt "tag" +msgid "Not installed" +msgstr "" + +#: src/data/db/tables/Tags.vala:227 +msgctxt "tag" +msgid "Installed" +msgstr "" + +#: src/data/db/tables/Tags.vala:228 +msgctxt "tag" +msgid "Hidden" +msgstr "" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit script" +msgstr "" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit custom script" +msgstr "" + +#: src/data/compat/Innoextract.vala:55 +#, c-format +msgid "" +"Innoextract %1$s is not supported and may not be able to extract some " +"games correctly.\n" +"Install innoextract %2$s or newer." +msgstr "" + +#: src/data/compat/WineWrap.vala:61 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:242 +#: src/ui/dialogs/CompatRunDialog.vala:102 +#: src/ui/views/GamesView/GameContextMenu.vala:53 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:234 +msgid "Run" +msgstr "" + +#: src/data/compat/WineWrap.vala:64 +msgid "Show WineWrap menu" +msgstr "" + +#: src/data/compat/WineWrap.vala:67 src/data/compat/Proton.vala:122 +#: src/data/compat/Wine.vala:83 +msgid "Kill apps in prefix" +msgstr "" + +#: src/data/compat/Proton.vala:47 +msgid "Proton prefix" +msgstr "" + +#: src/data/compat/Proton.vala:110 src/data/compat/Wine.vala:71 +msgid "Open prefix directory" +msgstr "" + +#: src/data/compat/Proton.vala:113 src/data/compat/Wine.vala:74 +msgid "Run winecfg" +msgstr "" + +#: src/data/compat/Proton.vala:116 src/data/compat/Wine.vala:77 +msgid "Run winetricks" +msgstr "" + +#: src/data/compat/Proton.vala:119 src/data/compat/Wine.vala:80 +msgid "Run taskmgr" +msgstr "" + +#: src/data/compat/Wine.vala:53 +msgid "Wine prefix" +msgstr "" + +#: src/data/compat/Wine.vala:55 +msgid "Environment variables" +msgstr "" + +#: src/data/compat/Wine.vala:60 +msgid "InnoSetup default options" +msgstr "" + +#: src/data/compat/RetroArch.vala:53 +msgid "Libretro core file" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:43 +msgid "Custom emulator" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:48 +msgid "Emulator" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:49 +msgid "Launch in game directory" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:440 +msgctxt "status_header" +msgid "Favorites" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:445 +#, c-format +msgctxt "status_header" +msgid "%s: Favorites" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:491 +msgid "Merging games" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:504 +#, c-format +msgid "Merging games from %s" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:551 +#, c-format +msgid "Loading games from %s" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:678 +msgctxt "sort_mode" +msgid "By name" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:679 +msgctxt "sort_mode" +msgid "By last launch" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:680 +msgctxt "sort_mode" +msgid "By playtime" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:705 +msgctxt "group_mode" +msgid "Do not group" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:706 +msgctxt "group_mode" +msgid "By status" +msgstr "" + +#: src/data/adapters/GamesAdapter.vala:707 +msgctxt "group_mode" +msgid "By source" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:151 +#: src/data/providers/data/IGDB.vala:431 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:217 +msgid "Default" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:158 +#: src/data/providers/data/IGDB.vala:438 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:225 +msgid "Restore default API key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:169 +#: src/data/providers/data/IGDB.vala:449 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:108 +msgid "API key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:177 +#: src/data/providers/data/IGDB.vala:457 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:53 +msgid "Generate key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:208 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Style" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:209 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Score" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:213 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Author" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:225 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Alternate" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:226 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Blurred" +msgstr "" + +#. TRANSLATORS: Flat / Material Design image style. Probably should not be translated +#: src/data/providers/images/SteamGridDB.vala:228 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Material" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:229 +msgctxt "imagesource_steamgriddb_image_style" +msgid "No logo" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:230 +msgctxt "imagesource_steamgriddb_image_style" +msgid "White logo" +msgstr "" + +#: src/data/providers/data/IGDB.vala:147 +msgid "" +"Monthly IGDB request quota has been reached. Set your own API key to use " +"IGDB data or disable IGDB." +msgstr "" + +#: src/data/providers/data/IGDB.vala:148 +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:40 +#: src/ui/views/WelcomeView.vala:53 src/ui/views/WelcomeView.vala:78 +#: src/ui/views/GamesView/GamesView.vala:230 +#: src/ui/views/GamesView/GamesView.vala:629 +msgid "Settings" +msgstr "" + +#: src/data/providers/data/IGDB.vala:356 +msgctxt "igdb_related_link" +msgid "Official website" +msgstr "" + +#: src/data/providers/data/IGDB.vala:469 +msgctxt "igdb_preferred_description" +msgid "When game has description, show description" +msgstr "" + +#: src/data/providers/data/IGDB.vala:476 +msgctxt "igdb_preferred_description" +msgid "of game" +msgstr "" + +#: src/data/providers/data/IGDB.vala:477 +msgctxt "igdb_preferred_description" +msgid "from IGDB" +msgstr "" + +#: src/data/providers/data/IGDB.vala:478 +msgctxt "igdb_preferred_description" +msgid "both" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:65 +msgid "Some settings will be applied after application restart" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:71 +msgid "Games directory contains space. It may cause problems for some games" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:36 +msgid "Interface" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:37 +msgid "Appearance" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:38 +msgid "General interface settings" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:48 +msgid "Dark theme" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:53 +msgctxt "icon_style" +msgid "Theme-based" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:54 +msgctxt "icon_style" +msgid "Symbolic" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:55 +msgctxt "icon_style" +msgid "Colored" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:57 +msgctxt "icon_style" +msgid "Icon style" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:84 +msgid "Game card" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:86 +msgid "Show platform icons" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:99 +msgctxt "grid_size" +msgid "Card size" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:117 +msgctxt "grid_size_preset" +msgid "Presets" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:139 +msgid "Games list: installed" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:140 +msgid "Games list: not installed" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:142 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:146 +msgctxt "list_style" +msgid "Show icon" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:143 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:147 +msgctxt "list_style" +msgid "Bold title" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:144 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:148 +msgctxt "list_style" +msgid "Show status" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:149 +msgctxt "list_style" +msgid "Dim" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:151 +msgid "Grid options" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:152 +msgid "List options" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:31 +msgid "Behavior" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:32 +msgid "Behavior settings" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:42 +msgid "Run games with double click" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:46 +msgid "Merge games from different sources" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:50 +msgid "Use imported tags" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:51 +msgid "General" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:52 +msgid "Collection" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:53 +msgid "Empty" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:65 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:85 +msgid "Collection directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:70 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:78 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:87 +msgid "Game directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:71 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:79 +msgid "Installers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:72 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:98 +msgid "DLC" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:73 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:197 +msgid "Bonus content" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:84 +msgid "Variable syntax: $var or ${var}" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:86 +msgid "Game name" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:88 +#: src/ui/views/GamesView/FiltersPopover.vala:127 +msgid "Platform" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:36 +msgid "Controller" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +msgid "Enabled" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:53 +msgid "Focus GameHub window with Guide button" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:57 +msgid "Controllers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:89 +msgid "Move focus" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:91 +msgid "Exit" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:40 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:108 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:92 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:95 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:36 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:77 +msgid "Disabled" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:47 +#: src/ui/dialogs/GameTweaksDialog.vala:53 +#: src/ui/views/GamesView/GameContextMenu.vala:183 +msgid "Tweaks" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:34 +msgid "Tweak launch options and apply them to games automatically" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:79 +msgid "" +"Tweaks are loaded from following directories in order\n" +"Last tweak overrides previous tweaks with same identifiers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:83 +msgid "Click to open" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:93 +#, c-format +msgid "Tweaks are loaded from %1$s and %2$d more directories (?)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:38 +msgid "Game sources" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +msgid "Steam API keys have limited number of uses per day" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:63 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:57 +msgid "Installation directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:176 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:81 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:34 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:75 +msgid "Not installed" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:116 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:96 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:99 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:85 +msgid "Not authenticated" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +#, c-format +msgid "Authenticated as %s" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:103 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +msgid "Authenticated" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:183 +#: src/ui/dialogs/InstallDialog.vala:53 src/ui/dialogs/InstallDialog.vala:111 +#: src/ui/views/GamesView/GameContextMenu.vala:80 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:233 +#: src/ui/widgets/TweaksList.vala:95 +msgid "Install" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:236 +msgid "Steam API key" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:50 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:54 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:48 +msgid "Games directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:63 +msgid "Logout" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:50 +msgid "Load games from Humble Trove" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:45 +msgid "Emulators" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:45 +msgid "Libretro core directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:46 +msgid "Libretro core info directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:50 +msgid "Ignored libretro cores" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:54 +msgid "Ignored game file extensions" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:66 +msgid "No cores found" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:70 +#, c-format +msgid "%u core found" +msgid_plural "%u cores found" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:46 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:168 +msgid "No custom emulators" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:164 +#, c-format +msgid "%u custom emulator" +msgid_plural "%u custom emulators" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:237 +msgid "Save" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:250 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:312 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/dialogs/GamePropertiesDialog.vala:168 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +#: src/ui/views/GamesView/AddGamePopover.vala:67 +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Executable" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:251 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/views/GamesView/AddGamePopover.vala:68 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Installer" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:256 +#: src/ui/dialogs/GamePropertiesDialog.vala:64 +#: src/ui/dialogs/GamePropertiesDialog.vala:69 +#: src/ui/views/GamesView/AddGamePopover.vala:73 +msgid "Name" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:272 +#: src/ui/dialogs/GamePropertiesDialog.vala:201 +#: src/ui/views/GamesView/AddGamePopover.vala:78 +msgid "Arguments" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:276 +msgid "Variables" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:277 +msgid "Game executable" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:278 +msgid "Game arguments" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:80 +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +msgid "Select emulator directory" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:292 +#: src/ui/dialogs/GamePropertiesDialog.vala:219 +msgid "Force compatibility mode" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:307 +msgid "Game file patterns" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:315 +msgid "Image" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:318 +msgid "Icon" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:325 +msgid "" +"findutils-compatible glob patterns\n" +"\n" +" Multiple patterns can be separated with |\n" +" Start pattern with ./ to match relative path\n" +" $basename variable will be replaced with game's executable " +"name (without extension)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:38 +msgid "Data" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:39 +msgid "Providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:40 +msgid "Third-party data providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:55 +msgid "Image providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:68 +msgid "Metadata providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:137 +msgid "Open website" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:36 +msgid "About" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:71 +msgid "Copy application version and environment info" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:78 +#: src/ui/views/WelcomeView.vala:57 +msgid "All your games in one place" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:92 +msgctxt "about_link" +msgid "Website" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:96 +msgctxt "about_link" +msgid "Source code on GitHub" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:103 +msgctxt "about_link" +msgid "Report a problem" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:104 +msgctxt "about_link" +msgid "Suggest translations" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:110 +msgctxt "about_link" +msgid "Issues" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:111 +msgctxt "about_link" +msgid "Contributors" +msgstr "" + +#. TRANSLATORS: Likely it should not be translated. GitHub Pulse is a page that shows recent repository activity: https://github.com/tkashkin/GameHub/pulse +#: src/ui/dialogs/SettingsDialog/pages/About.vala:114 +msgctxt "about_link" +msgid "Pulse" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:115 +msgctxt "about_link" +msgid "Forks" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:109 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:129 +msgid "Import" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:110 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:153 +msgid "Download" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:207 +msgid "Select installer" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:216 +#, c-format +msgid "Installer size: %s" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:348 +msgid "Unknown" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:49 +#, c-format +msgid "%s: Properties" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:84 +msgid "Images" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:126 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:160 +#: src/ui/views/GameDetailsView/blocks/Artwork.vala:62 +msgid "Download images" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:144 +msgid "Image URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:148 +msgid "Vertical image URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:157 +msgid "Icon URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Select working directory" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Working directory" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:214 +msgid "Compatibility" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:236 +msgid "Launch from terminal" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:252 +msgid "Copy to clipboard" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:254 +msgid "Add to Steam" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:255 +msgid "Add to the Steam library" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:53 +#, c-format +msgid "%s: Overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "Overlays are disabled" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "" +"Enable overlays to manage DLCs and mods\n" +"\n" +"Enabling will move game to the “base“ overlay" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:77 +#: src/ui/views/GamesView/GameContextMenu.vala:175 +msgid "Overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:105 +msgid "Overlay ID (directory name)" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:110 +msgid "Overlay name (optional)" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:112 +msgid "Add" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:127 +msgid "Enable overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:182 +#, c-format +msgid "" +"Overlay usage at this path may be unsafe\n" +"Proceed at your own risk\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:187 +#, c-format +msgid "" +"Overlay usage at this path is not supported\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:266 +msgid "Open directory" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:271 +msgid "Remove overlay" +msgstr "" + +#: src/ui/dialogs/CompatRunDialog.vala:48 +#: src/ui/views/GamesView/GameContextMenu.vala:46 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:235 +msgid "Run with compatibility layer" +msgstr "" + +#: src/ui/dialogs/CorruptedInstallerDialog.vala:71 +msgid "Corrupted installer: checksum mismatch in" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:57 +#: src/ui/views/GamesView/AddGamePopover.vala:105 +msgid "Import emulated games" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:75 +msgid "Select directory with emulated games" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:83 +msgid "Detected games" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:107 +msgid "Select all" +msgstr "" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:115 +msgid "Select directory to import" +msgstr "" + +#: src/ui/dialogs/GameTweaksDialog.vala:40 +#, c-format +msgid "%s: Tweaks" +msgstr "" + +#: src/ui/views/WelcomeView.vala:52 +msgid "No enabled game sources" +msgstr "" + +#: src/ui/views/WelcomeView.vala:52 +msgid "Enable some game sources in settings" +msgstr "" + +#: src/ui/views/WelcomeView.vala:57 +msgid "Let's get started" +msgstr "" + +#: src/ui/views/WelcomeView.vala:71 +msgid "Skip" +msgstr "" + +#: src/ui/views/WelcomeView.vala:141 +msgid "Ready" +msgstr "" + +#: src/ui/views/WelcomeView.vala:147 +msgid "Authentication required" +msgstr "" + +#: src/ui/views/WelcomeView.vala:152 +msgid "Authenticating…" +msgstr "" + +#: src/ui/views/WelcomeView.vala:163 +#, c-format +msgid "Install %s" +msgstr "" + +#: src/ui/views/WelcomeView.vala:164 +msgid "Return to GameHub after installing" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "No games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "Get some games or enable some game sources in settings" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:150 +msgid "Grid view" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:151 +msgid "List view" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:159 +msgid "All games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:182 +msgid "Downloads" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:208 +msgid "Filters" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:216 +#: src/ui/views/GamesView/AddGamePopover.vala:84 +msgid "Add game" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:223 +msgid "Search" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:328 +msgid "Menu" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:329 +#: src/ui/views/GameDetailsView/GameDetailsView.vala:104 +msgid "Back" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:550 +#, c-format +msgid "%u game" +msgid_plural "%u games" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GamesView/GamesView.vala:553 +#, c-format +msgctxt "games_view_subtitle_filtered_games" +msgid "%1$u / %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:557 +#, c-format +msgctxt "games_view_subtitle" +msgid "%1$s: %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:568 +msgid "No user-added games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:569 +msgid "Add some games using plus button" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:573 +#, c-format +msgid "No %s games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:574 +msgid "Get some Linux-compatible games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:584 +#, c-format +msgid "No games matching “%s”" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:589 +#, c-format +msgid "No %1$s games matching “%2$s”" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:627 +msgid "" +"No games were loaded from Steam. Set your games list privacy to public or " +"use your own Steam API key in settings." +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:628 +msgid "Privacy" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:739 +msgid "Downloading images" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:753 +#, c-format +msgid "Downloading image: %s" +msgstr "" + +#: src/ui/views/GamesView/DownloadProgressView.vala:131 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:162 +msgid "Pause download" +msgstr "" + +#: src/ui/views/GamesView/DownloadProgressView.vala:137 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:168 +msgid "Resume download" +msgstr "" + +#: src/ui/views/GamesView/DownloadProgressView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:174 +msgid "Cancel download" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:77 +msgid "Group" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:102 +msgid "Sort" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:234 +#: src/ui/widgets/GameTagsList.vala:58 +msgid "Tags" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:353 +msgid "All platforms" +msgstr "" + +#: src/ui/views/GamesView/AddGamePopover.vala:77 +msgid "Select game executable" +msgstr "" + +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Select game directory" +msgstr "" + +#: src/ui/views/GamesView/AddGamePopover.vala:111 +msgid "Download game images" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:87 +msgid "Details" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:117 +msgctxt "game_context_menu" +msgid "Favorite" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:121 +msgctxt "game_context_menu" +msgid "Hidden" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:133 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:236 +msgid "Open installation directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:142 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:237 +msgid "Open installers collection directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:151 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:238 +msgid "Open bonus collection directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:160 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:239 +msgid "Open screenshots directory" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +msgid "Uninstall" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:192 +msgid "Properties" +msgstr "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:100 +#, c-format +msgid "%d game selected" +msgid_plural "%d games selected" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:144 +#, c-format +msgid "%d game will be installed" +msgid_plural "%d games will be installed" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:154 +#, c-format +msgid "%d game will be downloaded" +msgid_plural "%d games will be downloaded" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:161 +#, c-format +msgid "Image for %d game will be searched" +msgid_plural "Images for %d games will be searched" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:168 +#, c-format +msgid "%d game will be uninstalled" +msgid_plural "%d games will be uninstalled" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:174 +msgid "Refresh" +msgstr "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:175 +#, c-format +msgid "" +"%d game will be removed from database. Restart GameHub to fetch new data" +msgid_plural "" +"%d games will be removed from database. Restart GameHub to fetch new data" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:240 +msgid "Open store page" +msgstr "" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:242 +msgid "Game properties" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:46 +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:60 +msgid "Playtime" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:52 +msgid "Playtime (local)" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:69 +msgid "Last launch" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:46 +msgid "Achievements" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:85 +#, c-format +msgid "Unlocked: %s" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:90 +#, c-format +msgid "Global percentage: %g%%" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:77 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:103 +msgid "Language" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:80 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:106 +msgid "Languages" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:147 +#, c-format +msgid "%u DLCs cannot be installed" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:71 +msgid "Category" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:74 +msgid "Categories" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:90 +msgid "Genre" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:93 +msgid "Genres" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:109 +msgctxt "igdb" +msgid "Popularity" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:115 +msgctxt "igdb" +msgid "Aggregated rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:116 +msgctxt "igdb" +msgid "IGDB user rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:117 +msgctxt "igdb" +msgid "Total rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:126 +msgctxt "igdb" +msgid "Release date" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:133 +msgctxt "igdb" +msgid "Platforms" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:139 +msgctxt "igdb" +msgid "Genres" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:145 +msgctxt "igdb" +msgid "Keywords" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:152 +msgctxt "igdb" +msgid "Links" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:208 +#, c-format +msgid "Based on %d rating" +msgid_plural "Based on %d ratings" +msgstr[0] "" +msgstr[1] "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:290 +msgctxt "igdb" +msgid "Summary" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:301 +msgctxt "igdb" +msgid "Storyline" +msgstr "" + +#: src/ui/widgets/FileChooserEntry.vala:49 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select file" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "No images" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "" +"There are no images found for this game\n" +"Make sure game name is correct" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:94 +msgid "Search images:" +msgstr "" + +#: src/ui/widgets/CompatToolPicker.vala:53 +msgid "Compatibility layer:" +msgstr "" + +#: src/ui/widgets/CompatToolPicker.vala:92 +msgid "Configure" +msgstr "" + +#: src/ui/widgets/GameTagsList.vala:109 +msgid "Add tag" +msgstr "" + +#: src/ui/widgets/TweaksList.vala:86 +msgid "No description" +msgstr "" + +#: src/ui/widgets/TweaksList.vala:124 +msgid "Edit file" +msgstr "" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dh" +msgstr "" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dm" +msgstr "" + +#: src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%ds" +msgstr "" + +#: src/settings/UI.vala:153 +msgctxt "grid_size_preset" +msgid "Steam" +msgstr "" + +#: src/settings/UI.vala:154 +msgctxt "grid_size_preset" +msgid "Steam (vertical)" +msgstr "" + +#: src/settings/UI.vala:155 +msgctxt "grid_size_preset" +msgid "GOG" +msgstr "" + +#: src/settings/UI.vala:156 +msgctxt "grid_size_preset" +msgid "GOG (vertical)" +msgstr "" + +#: src/settings/UI.vala:157 +msgctxt "grid_size_preset" +msgid "Square" +msgstr "" + +#: src/settings/UI.vala:158 +msgctxt "grid_size_preset" +msgid "Custom" +msgstr "" + +#: src/utils/downloader/Downloader.vala:200 +msgctxt "dl_status" +msgid "Queued" +msgstr "" + +#: src/utils/downloader/Downloader.vala:201 +msgctxt "dl_status" +msgid "Starting download" +msgstr "" + +#: src/utils/downloader/Downloader.vala:202 +msgctxt "dl_status" +msgid "Download started" +msgstr "" + +#: src/utils/downloader/Downloader.vala:203 +msgctxt "dl_status" +msgid "Download finished" +msgstr "" + +#: src/utils/downloader/Downloader.vala:204 +msgctxt "dl_status" +msgid "Download failed" +msgstr "" + +#: src/utils/downloader/Downloader.vala:208 +#, c-format +msgctxt "dl_status" +msgid "Downloading: %s" +msgstr "" + +#: src/utils/downloader/Downloader.vala:210 +msgctxt "dl_status" +msgid "Downloading" +msgstr "" + +#: src/utils/downloader/Downloader.vala:214 +#, c-format +msgctxt "dl_status" +msgid "Paused: %s" +msgstr "" + +#: src/utils/downloader/Downloader.vala:216 +msgctxt "dl_status" +msgid "Paused" +msgstr "" + +#: src/utils/downloader/Downloader.vala:218 +msgctxt "dl_status" +msgid "Download cancelled" +msgstr "" + +#. TRANSLATORS: Download progress template. %1$d - percentage, %2$s / %3$s - downloaded portion and total file size, %4$s - download speed +#: src/utils/downloader/Downloader.vala:262 +#, c-format +msgctxt "dl_status" +msgid "%1$d%% (%2$s / %3$s) [%4$s/s]" +msgstr "" diff --git a/po/tr.po b/po/tr.po new file mode 100644 index 00000000..d5f8adcf --- /dev/null +++ b/po/tr.po @@ -0,0 +1,1872 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the com.github.tkashkin.gamehub package. +# Kemal Oktay Aktoğan , 2019. +# Güner Acet , 2019. +# Oğuz Ersen , 2019, 2020. +msgid "" +msgstr "" +"Project-Id-Version: com.github.tkashkin.gamehub\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-26 06:40+0300\n" +"PO-Revision-Date: 2020-04-15 12:11+0000\n" +"Last-Translator: Oğuz Ersen \n" +"Language-Team: Turkish \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.0-dev\n" + +#: src/app.vala:91 +msgid "Show help" +msgstr "Yardımı göster" + +#: src/app.vala:92 +msgid "Show application version and exit" +msgstr "Uygulama sürümünü göster ve çık" + +#: src/app.vala:93 +msgid "Restart with GDB debugger attached" +msgstr "GDB hata ayıklayıcısı ile birlikte yeniden başlat" + +#: src/app.vala:94 +msgid "Show full GDB backtrace" +msgstr "Tam GDB yığın geri izlemesini göster" + +#: src/app.vala:95 +msgid "Treat fatal errors as criticals and crash application" +msgstr "Ölümcül hataları kritik olarak kabul et ve uygulamayı çöktür" + +#: src/app.vala:99 +msgid "Show main window" +msgstr "Ana pencereyi göster" + +#: src/app.vala:100 +msgid "Show application settings dialog" +msgstr "Uygulama ayarları iletişim kutusunu göster" + +#: src/app.vala:101 +msgid "Show about dialog" +msgstr "Hakkında iletişim penceresini göster" + +#: src/app.vala:102 +msgid "Maximum number of background worker threads" +msgstr "Arka planda çalışan iş parçacık sayısının üst limiti" + +#: src/app.vala:106 +msgid "Run game" +msgstr "Oyunu çalıştır" + +#: src/app.vala:107 +msgid "Show compatibility options dialog" +msgstr "Uyumluluk ayarları iletişim kutusunu göster" + +#: src/app.vala:108 +msgid "Open game details" +msgstr "Oyun ayrıntılarını aç" + +#: src/app.vala:109 +msgid "Open game properties" +msgstr "Oyun özelliklerini aç" + +#: src/app.vala:113 +msgid "Enable debug logging" +msgstr "Hata ayıklama günlük kaydını etkinleştirin" + +#: src/app.vala:114 +msgid "" +"Log authentication process and sensitive information like authentication " +"tokens" +msgstr "" +"Kimlik doğrulama işlemi ve kimlik doğrulama belirteçleri gibi hassas bilgiler" + +#: src/app.vala:115 +msgid "Log download manager" +msgstr "Günlük kaydı indirme yöneticisi" + +#: src/app.vala:116 +msgid "Log background workers start/stop" +msgstr "Arka plan çalışma öbeklerinin günlük kaydını başlat/durdur" + +#: src/app.vala:117 +msgid "Disable log messages filtering" +msgstr "Log mesajları filtresini devre dışı bırak" + +#: src/app.vala:118 +msgid "Verbose logging" +msgstr "Ayrıntılı günlük kaydı" + +#: src/app.vala:247 +msgid "Game Options:" +msgstr "Oyun seçenekleri:" + +#: src/app.vala:247 +msgid "Show game options help" +msgstr "Oyun seçenekleri yardımını göster" + +#: src/app.vala:255 +msgid "Logging Options:" +msgstr "Günlüğe Kaydetme Seçenekleri:" + +#: src/app.vala:255 +msgid "Show logging options help" +msgstr "Günlüğe kaydetme seçenekleri yardımını göster" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +msgid "Select executable" +msgstr "Çalıştırma dosyasını seçiniz" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:181 src/ui/views/GamesView/GamesView.vala:330 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select" +msgstr "Seç" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:180 src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Cancel" +msgstr "İptal" + +#: src/data/Runnable.vala:166 src/ui/widgets/FileChooserEntry.vala:49 +msgid "Select directory" +msgstr "Dizin seç" + +#: src/data/Runnable.vala:619 +#, c-format +msgid "Part %1$u of %2$u: %3$s" +msgstr "Parça %1$u / %2$u: %3$s" + +#: src/data/Runnable.vala:642 src/ui/dialogs/CorruptedInstallerDialog.vala:48 +#, c-format +msgid "%s: corrupted installer" +msgstr "%s: bozuk kurucu" + +#: src/data/Runnable.vala:643 +#, c-format +msgid "Checksum mismatch in %s" +msgstr "%s içinde sağlama uyuşmazlığı" + +#: src/data/Runnable.vala:657 src/ui/dialogs/CorruptedInstallerDialog.vala:126 +msgid "Show file" +msgstr "Dosyayı göster" + +#: src/data/Runnable.vala:658 src/ui/dialogs/CorruptedInstallerDialog.vala:132 +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#: src/ui/widgets/TagRow.vala:146 +msgid "Remove" +msgstr "Kaldır" + +#: src/data/Runnable.vala:659 src/ui/dialogs/CorruptedInstallerDialog.vala:128 +msgid "Backup" +msgstr "Yedekleme" + +#: src/data/Runnable.vala:778 +#, c-format +msgid "%s: cannot detect main executable" +msgstr "%s: ana çalıştırılabilir dosya algılanamıyor" + +#: src/data/Runnable.vala:779 +msgid "" +"Main executable file for this game cannot be detected automatically.\n" +"Please set main executable in game's properties." +msgstr "" +"Bu oyun için ana çalıştırılabilir dosya otomatik olarak algılanamıyor.\n" +"Lütfen oyunun özelliklerinde çalıştırılabilir ana dosyayı ayarlayın." + +#: src/data/Runnable.vala:908 +msgctxt "platform" +msgid "Emulated" +msgstr "Emüle edilmiş" + +#: src/data/Game.vala:625 +msgctxt "status" +msgid "Running" +msgstr "Çalışıyor" + +#: src/data/Game.vala:628 +msgctxt "status" +msgid "Installed" +msgstr "Yüklendi" + +#: src/data/Game.vala:629 +msgctxt "status" +msgid "Installing" +msgstr "Yükleniyor" + +#: src/data/Game.vala:630 +msgctxt "status" +msgid "Verifying installer integrity" +msgstr "Kurucu bütünlüğü doğrulanıyor" + +#: src/data/Game.vala:631 +msgctxt "status" +msgid "Download started" +msgstr "İndirme başladı" + +#: src/data/Game.vala:633 +msgctxt "status" +msgid "Not installed" +msgstr "Yüklenmedi" + +#: src/data/Game.vala:643 +msgctxt "status_header" +msgid "Installed" +msgstr "Yüklendi" + +#: src/data/Game.vala:644 +msgctxt "status_header" +msgid "Installing" +msgstr "Yükleniyor" + +#: src/data/Game.vala:646 +msgctxt "status_header" +msgid "Downloading" +msgstr "İndiriliyor" + +#: src/data/Game.vala:648 +msgctxt "status_header" +msgid "Not installed" +msgstr "Yüklenmedi" + +#: src/data/GameSource.vala:31 +#, c-format +msgid "%s games" +msgstr "%s oyun" + +#: src/data/sources/steam/Steam.vala:43 +msgid "Your SteamID will be read from Steam configuration file" +msgstr "SteamID'niz Steam yapılandırma dosyasından okunacaktır" + +#: src/data/sources/steam/Steam.vala:46 +msgid "" +"Steam config file not found.\n" +"Login into your account in Steam client and return to GameHub" +msgstr "" +"Steam yapılandırma dosyası bulunamadı.\n" +"Steam istemcisinden hesabınıza giriş yapın ve GameHub'a geri dönün" + +#: src/data/sources/gog/GOGGame.vala:983 +#, c-format +msgid "DLC: %s" +msgstr "DLC: %s" + +#: src/data/sources/humble/HumbleGame.vala:343 +#, c-format +msgid "%s: no available installers" +msgstr "%s: kullanılabilir kurucu yok" + +#: src/data/sources/humble/HumbleGame.vala:344 +msgid "" +"Cannot get Trove download URL.\n" +"Make sure your Humble Monthly subscription is active." +msgstr "" +"Trove indirme URL’si alınamıyor.\n" +"Humble Monthly üyeliğinizin etkin olduğundan emin olun." + +#: src/data/sources/itch/ItchDownloader.vala:192 +#, c-format +msgctxt "itch_dl_status" +msgid "%s left;" +msgstr "%s kaldı;" + +#: src/data/sources/itch/ItchDownloader.vala:195 +#, c-format +msgctxt "itch_dl_status" +msgid "%d%%" +msgstr "%%%d" + +#: src/data/sources/itch/ItchDownloader.vala:198 +#, c-format +msgctxt "itch_dl_status" +msgid "(%1$s / %2$s)" +msgstr "(%1$s / %2$s)" + +#: src/data/sources/itch/ItchDownloader.vala:201 +#, c-format +msgctxt "itch_dl_status" +msgid "[%s/s]" +msgstr "[%s/s]" + +#: src/data/sources/user/User.vala:30 +msgid "User games" +msgstr "Kullanıcı oyunları" + +#: src/data/db/tables/Tags.vala:225 +msgctxt "tag" +msgid "Favorites" +msgstr "Sık kullanılanlar" + +#: src/data/db/tables/Tags.vala:226 +msgctxt "tag" +msgid "Not installed" +msgstr "Yüklü değil" + +#: src/data/db/tables/Tags.vala:227 +msgctxt "tag" +msgid "Installed" +msgstr "Yüklü" + +#: src/data/db/tables/Tags.vala:228 +msgctxt "tag" +msgid "Hidden" +msgstr "Gizli" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit script" +msgstr "Komut dosyasını düzenle" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit custom script" +msgstr "Özel komut dosyasını düzenle" + +#: src/data/compat/Innoextract.vala:55 +#, c-format +msgid "" +"Innoextract %1$s is not supported and may not be able to extract some " +"games correctly.\n" +"Install innoextract %2$s or newer." +msgstr "" +"Innoextract %1$s desteklenmemektedir ve bazı oyunları doğru şekilde " +"çıkaramayabilir.\n" +"Innoextract %2$s veya daha yeni bir sürümünü yükleyin." + +#: src/data/compat/WineWrap.vala:61 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:242 +#: src/ui/dialogs/CompatRunDialog.vala:102 +#: src/ui/views/GamesView/GameContextMenu.vala:53 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:234 +msgid "Run" +msgstr "Çalıştır" + +#: src/data/compat/WineWrap.vala:64 +msgid "Show WineWrap menu" +msgstr "WineWrap menüsünü göster" + +#: src/data/compat/WineWrap.vala:67 src/data/compat/Proton.vala:122 +#: src/data/compat/Wine.vala:83 +msgid "Kill apps in prefix" +msgstr "Önekteki uygulamaları sonlandır" + +#: src/data/compat/Proton.vala:47 +msgid "Proton prefix" +msgstr "Proton öneki" + +#: src/data/compat/Proton.vala:110 src/data/compat/Wine.vala:71 +msgid "Open prefix directory" +msgstr "Önek dizinini aç" + +#: src/data/compat/Proton.vala:113 src/data/compat/Wine.vala:74 +msgid "Run winecfg" +msgstr "winecfg'yi çalıştır" + +#: src/data/compat/Proton.vala:116 src/data/compat/Wine.vala:77 +msgid "Run winetricks" +msgstr "winetricks'i çalıştır" + +#: src/data/compat/Proton.vala:119 src/data/compat/Wine.vala:80 +msgid "Run taskmgr" +msgstr "Taskmgr'i çalıştır" + +#: src/data/compat/Wine.vala:53 +msgid "Wine prefix" +msgstr "Wine öneki" + +#: src/data/compat/Wine.vala:55 +msgid "Environment variables" +msgstr "Ortam değişkenleri" + +#: src/data/compat/Wine.vala:60 +msgid "InnoSetup default options" +msgstr "InnoSetup öntanımlı seçenekleri" + +#: src/data/compat/RetroArch.vala:53 +msgid "Libretro core file" +msgstr "Libretro çekirdek dosyası" + +#: src/data/compat/CustomEmulator.vala:43 +msgid "Custom emulator" +msgstr "Özel emülatör" + +#: src/data/compat/CustomEmulator.vala:48 +msgid "Emulator" +msgstr "Emülatör" + +#: src/data/compat/CustomEmulator.vala:49 +msgid "Launch in game directory" +msgstr "Oyun dizininde başlat" + +#: src/data/adapters/GamesAdapter.vala:440 +msgctxt "status_header" +msgid "Favorites" +msgstr "Sık kullanılanlar" + +#: src/data/adapters/GamesAdapter.vala:445 +#, c-format +msgctxt "status_header" +msgid "%s: Favorites" +msgstr "%s: Sık kullanılanlar" + +#: src/data/adapters/GamesAdapter.vala:491 +msgid "Merging games" +msgstr "Oyunlar birleştiriliyor" + +#: src/data/adapters/GamesAdapter.vala:504 +#, c-format +msgid "Merging games from %s" +msgstr "%s'den oyunlar birleştiriliyor" + +#: src/data/adapters/GamesAdapter.vala:551 +#, c-format +msgid "Loading games from %s" +msgstr "%s'den oyunlar yükleniyor" + +#: src/data/adapters/GamesAdapter.vala:678 +msgctxt "sort_mode" +msgid "By name" +msgstr "İsme göre" + +#: src/data/adapters/GamesAdapter.vala:679 +msgctxt "sort_mode" +msgid "By last launch" +msgstr "Son başlatmaya göre" + +#: src/data/adapters/GamesAdapter.vala:680 +msgctxt "sort_mode" +msgid "By playtime" +msgstr "Oynama zamanına göre" + +#: src/data/adapters/GamesAdapter.vala:705 +msgctxt "group_mode" +msgid "Do not group" +msgstr "Gruplandırma" + +#: src/data/adapters/GamesAdapter.vala:706 +msgctxt "group_mode" +msgid "By status" +msgstr "Duruma göre" + +#: src/data/adapters/GamesAdapter.vala:707 +msgctxt "group_mode" +msgid "By source" +msgstr "Kaynağa göre" + +#: src/data/providers/images/SteamGridDB.vala:151 +#: src/data/providers/data/IGDB.vala:431 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:217 +msgid "Default" +msgstr "Öntanımlı" + +#: src/data/providers/images/SteamGridDB.vala:158 +#: src/data/providers/data/IGDB.vala:438 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:225 +msgid "Restore default API key" +msgstr "Öntanımlı API anahtarını geri yükle" + +#: src/data/providers/images/SteamGridDB.vala:169 +#: src/data/providers/data/IGDB.vala:449 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:108 +msgid "API key" +msgstr "API anahtarı" + +#: src/data/providers/images/SteamGridDB.vala:177 +#: src/data/providers/data/IGDB.vala:457 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:53 +msgid "Generate key" +msgstr "Anahtar oluştur" + +#: src/data/providers/images/SteamGridDB.vala:208 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Style" +msgstr "Stil" + +#: src/data/providers/images/SteamGridDB.vala:209 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Score" +msgstr "Puan" + +#: src/data/providers/images/SteamGridDB.vala:213 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Author" +msgstr "Yazar" + +#: src/data/providers/images/SteamGridDB.vala:225 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Alternate" +msgstr "Alternatif" + +#: src/data/providers/images/SteamGridDB.vala:226 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Blurred" +msgstr "Bulanık" + +#. TRANSLATORS: Flat / Material Design image style. Probably should not be translated +#: src/data/providers/images/SteamGridDB.vala:228 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Material" +msgstr "Material" + +#: src/data/providers/images/SteamGridDB.vala:229 +msgctxt "imagesource_steamgriddb_image_style" +msgid "No logo" +msgstr "Logo yok" + +#: src/data/providers/images/SteamGridDB.vala:230 +msgctxt "imagesource_steamgriddb_image_style" +msgid "White logo" +msgstr "Beyaz logo" + +#: src/data/providers/data/IGDB.vala:147 +msgid "" +"Monthly IGDB request quota has been reached. Set your own API key to use " +"IGDB data or disable IGDB." +msgstr "" +"Aylık IGDB istek kotasına ulaşıldı. IGDB verilerini kullanmak için kendi API " +"anahtarınızı ayarlayın veya IGDB'yi devre dışı bırakın." + +#: src/data/providers/data/IGDB.vala:148 +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:40 +#: src/ui/views/WelcomeView.vala:53 src/ui/views/WelcomeView.vala:78 +#: src/ui/views/GamesView/GamesView.vala:230 +#: src/ui/views/GamesView/GamesView.vala:629 +msgid "Settings" +msgstr "Ayarlar" + +#: src/data/providers/data/IGDB.vala:356 +msgctxt "igdb_related_link" +msgid "Official website" +msgstr "Resmi web sitesi" + +#: src/data/providers/data/IGDB.vala:469 +msgctxt "igdb_preferred_description" +msgid "When game has description, show description" +msgstr "Oyunun açıklaması olduğunda açıklamayı göster" + +#: src/data/providers/data/IGDB.vala:476 +msgctxt "igdb_preferred_description" +msgid "of game" +msgstr "oyunun" + +#: src/data/providers/data/IGDB.vala:477 +msgctxt "igdb_preferred_description" +msgid "from IGDB" +msgstr "IGDB'den" + +#: src/data/providers/data/IGDB.vala:478 +msgctxt "igdb_preferred_description" +msgid "both" +msgstr "her ikisi de" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:65 +msgid "Some settings will be applied after application restart" +msgstr "Bazı ayarlar uygulama yeniden başlatıldıktan sonra uygulanacak" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:71 +msgid "Games directory contains space. It may cause problems for some games" +msgstr "" +"Oyunlar dizini boşluk içeriyor. Bu, bazı oyunlar için sorunlara neden " +"olabilir" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:36 +msgid "Interface" +msgstr "Arayüz" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:37 +msgid "Appearance" +msgstr "Görünüm" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:38 +msgid "General interface settings" +msgstr "Genel arayüz ayarları" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:48 +msgid "Dark theme" +msgstr "Karanlık tema" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:53 +msgctxt "icon_style" +msgid "Theme-based" +msgstr "Tema tabanlı" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:54 +msgctxt "icon_style" +msgid "Symbolic" +msgstr "Sembolik" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:55 +msgctxt "icon_style" +msgid "Colored" +msgstr "Renkli" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:57 +msgctxt "icon_style" +msgid "Icon style" +msgstr "Simge stili" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:84 +msgid "Game card" +msgstr "Oyun kartı" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:86 +msgid "Show platform icons" +msgstr "Platform simgelerini göster" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:99 +msgctxt "grid_size" +msgid "Card size" +msgstr "Kart boyutu" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:117 +msgctxt "grid_size_preset" +msgid "Presets" +msgstr "Hazır ayarlar" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:139 +msgid "Games list: installed" +msgstr "Oyun listesi: yüklü" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:140 +msgid "Games list: not installed" +msgstr "Oyun listesi: yüklü değil" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:142 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:146 +msgctxt "list_style" +msgid "Show icon" +msgstr "Simgeyi göster" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:143 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:147 +msgctxt "list_style" +msgid "Bold title" +msgstr "Kalın başlık" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:144 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:148 +msgctxt "list_style" +msgid "Show status" +msgstr "Durumu göster" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:149 +msgctxt "list_style" +msgid "Dim" +msgstr "Dim" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:151 +msgid "Grid options" +msgstr "Örgü seçenekleri" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:152 +msgid "List options" +msgstr "Seçenekleri listele" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:31 +msgid "Behavior" +msgstr "Davranış" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:32 +msgid "Behavior settings" +msgstr "Davranış ayarları" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:42 +msgid "Run games with double click" +msgstr "Oyunları çift tıklayarak çalıştır" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:46 +msgid "Merge games from different sources" +msgstr "Farklı kaynaklardan oyunları birleştir" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:50 +msgid "Use imported tags" +msgstr "İçe aktarılmış etiketler kullan" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:51 +msgid "General" +msgstr "Genel" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:52 +msgid "Collection" +msgstr "Koleksiyon" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:53 +msgid "Empty" +msgstr "Boş" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:65 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:85 +msgid "Collection directory" +msgstr "Koleksiyon dizini" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:70 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:78 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:87 +msgid "Game directory" +msgstr "Oyun dizini" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:71 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:79 +msgid "Installers" +msgstr "Kurucular" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:72 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:98 +msgid "DLC" +msgstr "DLC" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:73 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:197 +msgid "Bonus content" +msgstr "Bonus içerik" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:84 +msgid "Variable syntax: $var or ${var}" +msgstr "Değişken sözdizimi: $var veya ${var}" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:86 +msgid "Game name" +msgstr "Oyun adı" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:88 +#: src/ui/views/GamesView/FiltersPopover.vala:127 +msgid "Platform" +msgstr "Platform" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:36 +msgid "Controller" +msgstr "Denetleyici" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +msgid "Enabled" +msgstr "Etkin" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:53 +msgid "Focus GameHub window with Guide button" +msgstr "Rehber düğmesi ile GameHub penceresini odakla" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:57 +msgid "Controllers" +msgstr "Denetleyiciler" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:89 +msgid "Move focus" +msgstr "Odağı taşı" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:91 +msgid "Exit" +msgstr "Çıkış" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:40 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:108 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:92 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:95 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:36 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:77 +msgid "Disabled" +msgstr "Devre dışı" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:47 +#: src/ui/dialogs/GameTweaksDialog.vala:53 +#: src/ui/views/GamesView/GameContextMenu.vala:183 +msgid "Tweaks" +msgstr "İnce ayarlar" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:34 +msgid "Tweak launch options and apply them to games automatically" +msgstr "" +"Başlatma seçeneklerini değiştirin ve oyunlara otomatik olarak uygulayın" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:79 +msgid "" +"Tweaks are loaded from following directories in order\n" +"Last tweak overrides previous tweaks with same identifiers" +msgstr "" +"İnce ayarlar, aşağıdaki dizinlerden sırayla yüklenir\n" +"Son ayarlama, aynı tanımlayıcılara sahip önceki ayarlamaları geçersiz kılar" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:83 +msgid "Click to open" +msgstr "Açmak için tıklayın" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:93 +#, c-format +msgid "Tweaks are loaded from %1$s and %2$d more directories (?)" +msgstr "İnce ayarlar %1$s ve %2$d dizinden daha yüklenir (?)" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:38 +msgid "Game sources" +msgstr "Oyun kaynakları" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +msgid "Steam API keys have limited number of uses per day" +msgstr "Steam API anahtarlarının günlük kullanım sayısı sınırlıdır" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:63 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:57 +msgid "Installation directory" +msgstr "Kurulum dizini" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:176 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:81 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:34 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:75 +msgid "Not installed" +msgstr "Yüklü değil" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:116 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:96 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:99 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:85 +msgid "Not authenticated" +msgstr "Kimlik doğrulanmadı" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +#, c-format +msgid "Authenticated as %s" +msgstr "%s olarak kimlik doğrulandı" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:103 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +msgid "Authenticated" +msgstr "Kimlik doğrulandı" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:183 +#: src/ui/dialogs/InstallDialog.vala:53 src/ui/dialogs/InstallDialog.vala:111 +#: src/ui/views/GamesView/GameContextMenu.vala:80 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:233 +#: src/ui/widgets/TweaksList.vala:95 +msgid "Install" +msgstr "Yükle" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:236 +msgid "Steam API key" +msgstr "Steam API anahtarı" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:50 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:54 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:48 +msgid "Games directory" +msgstr "Oyun dizini" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:63 +msgid "Logout" +msgstr "Oturumu kapat" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:50 +msgid "Load games from Humble Trove" +msgstr "Humble Trove oyunlarını yükle" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:45 +msgid "Emulators" +msgstr "Emülatörler" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:45 +msgid "Libretro core directory" +msgstr "Libretro çekirdek dizini" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:46 +msgid "Libretro core info directory" +msgstr "Libretro çekirdek bilgi dizini" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:50 +msgid "Ignored libretro cores" +msgstr "Göz ardı edilen libretro çekirdekleri" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:54 +msgid "Ignored game file extensions" +msgstr "Göz ardı edilen oyun dosyası uzantıları" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:66 +msgid "No cores found" +msgstr "Çekirdek bulunamadı" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:70 +#, c-format +msgid "%u core found" +msgid_plural "%u cores found" +msgstr[0] "%u çekirdek bulundu" +msgstr[1] "%u çekirdek bulundu" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:46 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:168 +msgid "No custom emulators" +msgstr "Özel emülatör yok" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:164 +#, c-format +msgid "%u custom emulator" +msgid_plural "%u custom emulators" +msgstr[0] "%u özel emülatör" +msgstr[1] "%u özel emülatör" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:237 +msgid "Save" +msgstr "Kaydet" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:250 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:312 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/dialogs/GamePropertiesDialog.vala:168 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +#: src/ui/views/GamesView/AddGamePopover.vala:67 +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Executable" +msgstr "Çalıştırılabilir" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:251 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/views/GamesView/AddGamePopover.vala:68 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Installer" +msgstr "Kurucu" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:256 +#: src/ui/dialogs/GamePropertiesDialog.vala:64 +#: src/ui/dialogs/GamePropertiesDialog.vala:69 +#: src/ui/views/GamesView/AddGamePopover.vala:73 +msgid "Name" +msgstr "İsim" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:272 +#: src/ui/dialogs/GamePropertiesDialog.vala:201 +#: src/ui/views/GamesView/AddGamePopover.vala:78 +msgid "Arguments" +msgstr "Argümanlar" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:276 +msgid "Variables" +msgstr "Değişkenler" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:277 +msgid "Game executable" +msgstr "Oyunun çalıştırılabilir dosyası" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:278 +msgid "Game arguments" +msgstr "Oyun argümanları" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:80 +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Directory" +msgstr "Dizin" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +msgid "Select emulator directory" +msgstr "Emülatör dizinini seçin" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:292 +#: src/ui/dialogs/GamePropertiesDialog.vala:219 +msgid "Force compatibility mode" +msgstr "Uyumluluk modunu zorla" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:307 +msgid "Game file patterns" +msgstr "Oyun dosyası kalıpları" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:315 +msgid "Image" +msgstr "Görüntü" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:318 +msgid "Icon" +msgstr "Simge" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:325 +msgid "" +"findutils-compatible glob patterns\n" +"\n" +" Multiple patterns can be separated with |\n" +" Start pattern with ./ to match relative path\n" +" $basename variable will be replaced with game's executable " +"name (without extension)" +msgstr "" +"findutils ile uyumlu glob kalıpları\n" +"\n" +" Birden fazla kalıp | ile ayrılabilir\n" +" Göreceli yolu eşleştirmek için kalıbı ./ ile başlatın\n" +" $basename değişkeni, oyunun yürütülebilir dosyasının adıyla " +"(uzantı olmadan) değiştirilecektir" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:38 +msgid "Data" +msgstr "Veri" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:39 +msgid "Providers" +msgstr "Sağlayıcılar" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:40 +msgid "Third-party data providers" +msgstr "Üçüncü taraf veri sağlayıcıları" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:55 +msgid "Image providers" +msgstr "Görüntü sağlayıcıları" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:68 +msgid "Metadata providers" +msgstr "Üst veri sağlayıcıları" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:137 +msgid "Open website" +msgstr "Web sitesini aç" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:36 +msgid "About" +msgstr "Hakkında" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:71 +msgid "Copy application version and environment info" +msgstr "Uygulama sürümünü ve ortam bilgilerini kopyala" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:78 +#: src/ui/views/WelcomeView.vala:57 +msgid "All your games in one place" +msgstr "Tüm oyunlarınızı tek bir yerde" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:92 +msgctxt "about_link" +msgid "Website" +msgstr "Web sitesi" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:96 +msgctxt "about_link" +msgid "Source code on GitHub" +msgstr "Kaynak kodu GitHub'da" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:103 +msgctxt "about_link" +msgid "Report a problem" +msgstr "Sorun bildir" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:104 +msgctxt "about_link" +msgid "Suggest translations" +msgstr "Çeviri öner" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:110 +msgctxt "about_link" +msgid "Issues" +msgstr "Sorunlar" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:111 +msgctxt "about_link" +msgid "Contributors" +msgstr "Katkıda bulunanlar" + +#. TRANSLATORS: Likely it should not be translated. GitHub Pulse is a page that shows recent repository activity: https://github.com/tkashkin/GameHub/pulse +#: src/ui/dialogs/SettingsDialog/pages/About.vala:114 +msgctxt "about_link" +msgid "Pulse" +msgstr "Pulse" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:115 +msgctxt "about_link" +msgid "Forks" +msgstr "Forklar" + +#: src/ui/dialogs/InstallDialog.vala:109 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:129 +msgid "Import" +msgstr "İçe aktar" + +#: src/ui/dialogs/InstallDialog.vala:110 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:153 +msgid "Download" +msgstr "İndir" + +#: src/ui/dialogs/InstallDialog.vala:207 +msgid "Select installer" +msgstr "Kurucuyu seçin" + +#: src/ui/dialogs/InstallDialog.vala:216 +#, c-format +msgid "Installer size: %s" +msgstr "Kurucu boyutu: %s" + +#: src/ui/dialogs/InstallDialog.vala:348 +msgid "Unknown" +msgstr "Bilinmeyen" + +#: src/ui/dialogs/GamePropertiesDialog.vala:49 +#, c-format +msgid "%s: Properties" +msgstr "%s: Özellikler" + +#: src/ui/dialogs/GamePropertiesDialog.vala:84 +msgid "Images" +msgstr "Görüntüler" + +#: src/ui/dialogs/GamePropertiesDialog.vala:126 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:160 +#: src/ui/views/GameDetailsView/blocks/Artwork.vala:62 +msgid "Download images" +msgstr "Görüntüleri indirin" + +#: src/ui/dialogs/GamePropertiesDialog.vala:144 +msgid "Image URL" +msgstr "Resim URL'si" + +#: src/ui/dialogs/GamePropertiesDialog.vala:148 +msgid "Vertical image URL" +msgstr "Dikey resim URL'si" + +#: src/ui/dialogs/GamePropertiesDialog.vala:157 +msgid "Icon URL" +msgstr "Simge URL'si" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Select working directory" +msgstr "Çalışma dizinini seç" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Working directory" +msgstr "Çalışma dizini" + +#: src/ui/dialogs/GamePropertiesDialog.vala:214 +msgid "Compatibility" +msgstr "Uyumluluk" + +#: src/ui/dialogs/GamePropertiesDialog.vala:236 +msgid "Launch from terminal" +msgstr "Terminalden başlat" + +#: src/ui/dialogs/GamePropertiesDialog.vala:252 +msgid "Copy to clipboard" +msgstr "Panoya kopyala" + +#: src/ui/dialogs/GamePropertiesDialog.vala:254 +msgid "Add to Steam" +msgstr "Steam'e Ekle" + +#: src/ui/dialogs/GamePropertiesDialog.vala:255 +msgid "Add to the Steam library" +msgstr "Steam kütüphanesine ekle" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:53 +#, c-format +msgid "%s: Overlays" +msgstr "%s: Bindirmeler" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "Overlays are disabled" +msgstr "Bindirmeler devre dışı" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "" +"Enable overlays to manage DLCs and mods\n" +"\n" +"Enabling will move game to the “base“ overlay" +msgstr "" +"DLC'leri ve modları yönetmek için bindirmeleri etkinleştirin\n" +"\n" +"Etkinleştirme, oyunu “temel” bindirmeye taşıyacaktır" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:77 +#: src/ui/views/GamesView/GameContextMenu.vala:175 +msgid "Overlays" +msgstr "Bindirmeler" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:105 +msgid "Overlay ID (directory name)" +msgstr "Bindirme kimliği (dizin adı)" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:110 +msgid "Overlay name (optional)" +msgstr "Bindirme adı (isteğe bağlı)" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:112 +msgid "Add" +msgstr "Ekle" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:127 +msgid "Enable overlays" +msgstr "Bindirmeleri etkinleştir" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:182 +#, c-format +msgid "" +"Overlay usage at this path may be unsafe\n" +"Proceed at your own risk\n" +"\n" +"Path: %s" +msgstr "" +"Bu yoldaki bindirme kullanımı güvenli olmayabilir\n" +"Devam etmek kendi sorumluluğunuzdadır\n" +"\n" +"Yol: %s" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:187 +#, c-format +msgid "" +"Overlay usage at this path is not supported\n" +"\n" +"Path: %s" +msgstr "" +"Bu yoldaki bindirme kullanımı desteklenmemektedir\n" +"\n" +"Yol: %s" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:266 +msgid "Open directory" +msgstr "Dizini aç" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:271 +msgid "Remove overlay" +msgstr "Bindirmeyi kaldır" + +#: src/ui/dialogs/CompatRunDialog.vala:48 +#: src/ui/views/GamesView/GameContextMenu.vala:46 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:235 +msgid "Run with compatibility layer" +msgstr "Uyumluluk katmanıyla çalıştır" + +#: src/ui/dialogs/CorruptedInstallerDialog.vala:71 +msgid "Corrupted installer: checksum mismatch in" +msgstr "Bozuk kurucu: sağlama toplamı uyuşmazlığı" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:57 +#: src/ui/views/GamesView/AddGamePopover.vala:105 +msgid "Import emulated games" +msgstr "Emüle edilmiş oyunları içe aktar" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:75 +msgid "Select directory with emulated games" +msgstr "Emüle edilmiş oyunların olduğu dizini seç" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:83 +msgid "Detected games" +msgstr "Algılanan oyunlar" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:107 +msgid "Select all" +msgstr "Tümünü seç" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:115 +msgid "Select directory to import" +msgstr "İçe aktaracak dizini seç" + +#: src/ui/dialogs/GameTweaksDialog.vala:40 +#, c-format +msgid "%s: Tweaks" +msgstr "%s: İnce ayarlar" + +#: src/ui/views/WelcomeView.vala:52 +msgid "No enabled game sources" +msgstr "Etkinleştirilmiş oyun kaynağı yok" + +#: src/ui/views/WelcomeView.vala:52 +msgid "Enable some game sources in settings" +msgstr "Ayarlarda birkaç oyun kaynağını etkinleştirin" + +#: src/ui/views/WelcomeView.vala:57 +msgid "Let's get started" +msgstr "Başlayalım" + +#: src/ui/views/WelcomeView.vala:71 +msgid "Skip" +msgstr "Atla" + +#: src/ui/views/WelcomeView.vala:141 +msgid "Ready" +msgstr "Hazır" + +#: src/ui/views/WelcomeView.vala:147 +msgid "Authentication required" +msgstr "Kimlik doğrulama gerekli" + +#: src/ui/views/WelcomeView.vala:152 +msgid "Authenticating…" +msgstr "Kimlik doğrulanıyor…" + +#: src/ui/views/WelcomeView.vala:163 +#, c-format +msgid "Install %s" +msgstr "%s yükle" + +#: src/ui/views/WelcomeView.vala:164 +msgid "Return to GameHub after installing" +msgstr "Yüklemeden sonra GameHub'a dön" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "No games" +msgstr "Oyun yok" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "Get some games or enable some game sources in settings" +msgstr "Birkaç oyun edinin veya ayarlarda birkaç oyun kaynağını etkinleştirin" + +#: src/ui/views/GamesView/GamesView.vala:150 +msgid "Grid view" +msgstr "Izgara görünümü" + +#: src/ui/views/GamesView/GamesView.vala:151 +msgid "List view" +msgstr "Liste görünümü" + +#: src/ui/views/GamesView/GamesView.vala:159 +msgid "All games" +msgstr "Tüm oyunlar" + +#: src/ui/views/GamesView/GamesView.vala:182 +msgid "Downloads" +msgstr "İndirilenler" + +#: src/ui/views/GamesView/GamesView.vala:208 +msgid "Filters" +msgstr "Filtreler" + +#: src/ui/views/GamesView/GamesView.vala:216 +#: src/ui/views/GamesView/AddGamePopover.vala:84 +msgid "Add game" +msgstr "Oyun ekle" + +#: src/ui/views/GamesView/GamesView.vala:223 +msgid "Search" +msgstr "Arama" + +#: src/ui/views/GamesView/GamesView.vala:328 +msgid "Menu" +msgstr "Menü" + +#: src/ui/views/GamesView/GamesView.vala:329 +#: src/ui/views/GameDetailsView/GameDetailsView.vala:104 +msgid "Back" +msgstr "Geri" + +#: src/ui/views/GamesView/GamesView.vala:550 +#, c-format +msgid "%u game" +msgid_plural "%u games" +msgstr[0] "%u oyun" +msgstr[1] "%u oyun" + +#: src/ui/views/GamesView/GamesView.vala:553 +#, c-format +msgctxt "games_view_subtitle_filtered_games" +msgid "%1$u / %2$s" +msgstr "%1$u / %2$s" + +#: src/ui/views/GamesView/GamesView.vala:557 +#, c-format +msgctxt "games_view_subtitle" +msgid "%1$s: %2$s" +msgstr "%1$s: %2$s" + +#: src/ui/views/GamesView/GamesView.vala:568 +msgid "No user-added games" +msgstr "Kullanıcı tarafından eklenen oyun yok" + +#: src/ui/views/GamesView/GamesView.vala:569 +msgid "Add some games using plus button" +msgstr "Artı düğmesini kullanarak birkaç oyun ekleyin" + +#: src/ui/views/GamesView/GamesView.vala:573 +#, c-format +msgid "No %s games" +msgstr "%s oyunu yok" + +#: src/ui/views/GamesView/GamesView.vala:574 +msgid "Get some Linux-compatible games" +msgstr "Birkaç Linux uyumlu oyun edinin" + +#: src/ui/views/GamesView/GamesView.vala:584 +#, c-format +msgid "No games matching “%s”" +msgstr "\"%s\" ile eşleşen oyun yok" + +#: src/ui/views/GamesView/GamesView.vala:589 +#, c-format +msgid "No %1$s games matching “%2$s”" +msgstr "“%2$s” ile eşleşen %1$s oyun yok" + +#: src/ui/views/GamesView/GamesView.vala:627 +msgid "" +"No games were loaded from Steam. Set your games list privacy to public or " +"use your own Steam API key in settings." +msgstr "" +"Steam'den oyun yüklenmedi. Oyun listesi gizliliğinizi herkese açık olarak " +"ayarlayın veya ayarlarda kendi Steam API anahtarınızı kullanın." + +#: src/ui/views/GamesView/GamesView.vala:628 +msgid "Privacy" +msgstr "Gizlilik" + +#: src/ui/views/GamesView/GamesView.vala:739 +msgid "Downloading images" +msgstr "Görüntüler indiriliyor" + +#: src/ui/views/GamesView/GamesView.vala:753 +#, c-format +msgid "Downloading image: %s" +msgstr "Görüntü indiriliyor: %s" + +#: src/ui/views/GamesView/DownloadProgressView.vala:131 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:162 +msgid "Pause download" +msgstr "İndirmeyi duraklat" + +#: src/ui/views/GamesView/DownloadProgressView.vala:137 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:168 +msgid "Resume download" +msgstr "İndirmeye devam et" + +#: src/ui/views/GamesView/DownloadProgressView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:174 +msgid "Cancel download" +msgstr "İndirmeyi iptal et" + +#: src/ui/views/GamesView/FiltersPopover.vala:77 +msgid "Group" +msgstr "Grup" + +#: src/ui/views/GamesView/FiltersPopover.vala:102 +msgid "Sort" +msgstr "Sırala" + +#: src/ui/views/GamesView/FiltersPopover.vala:234 +#: src/ui/widgets/GameTagsList.vala:58 +msgid "Tags" +msgstr "Etiketler" + +#: src/ui/views/GamesView/FiltersPopover.vala:353 +msgid "All platforms" +msgstr "Tüm platformlar" + +#: src/ui/views/GamesView/AddGamePopover.vala:77 +msgid "Select game executable" +msgstr "Oyunun çalıştırılabilir dosyasını seç" + +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Select game directory" +msgstr "Oyun dizinini seç" + +#: src/ui/views/GamesView/AddGamePopover.vala:111 +msgid "Download game images" +msgstr "Oyun görüntüleri indir" + +#: src/ui/views/GamesView/GameContextMenu.vala:87 +msgid "Details" +msgstr "Detaylar" + +#: src/ui/views/GamesView/GameContextMenu.vala:117 +msgctxt "game_context_menu" +msgid "Favorite" +msgstr "Favori" + +#: src/ui/views/GamesView/GameContextMenu.vala:121 +msgctxt "game_context_menu" +msgid "Hidden" +msgstr "Gizli" + +#: src/ui/views/GamesView/GameContextMenu.vala:133 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:236 +msgid "Open installation directory" +msgstr "Kurulum dizinini aç" + +#: src/ui/views/GamesView/GameContextMenu.vala:142 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:237 +msgid "Open installers collection directory" +msgstr "Kurucu koleksiyon dizinini aç" + +#: src/ui/views/GamesView/GameContextMenu.vala:151 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:238 +msgid "Open bonus collection directory" +msgstr "Bonus koleksiyon dizinini aç" + +#: src/ui/views/GamesView/GameContextMenu.vala:160 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:239 +msgid "Open screenshots directory" +msgstr "Ekran görüntüleri dizinini aç" + +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +msgid "Uninstall" +msgstr "Kaldır" + +#: src/ui/views/GamesView/GameContextMenu.vala:192 +msgid "Properties" +msgstr "Özellikler" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:100 +#, c-format +msgid "%d game selected" +msgid_plural "%d games selected" +msgstr[0] "%d oyun seçildi" +msgstr[1] "%d oyun seçildi" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:144 +#, c-format +msgid "%d game will be installed" +msgid_plural "%d games will be installed" +msgstr[0] "%d oyun yüklenecek" +msgstr[1] "%d oyun yüklenecek" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:154 +#, c-format +msgid "%d game will be downloaded" +msgid_plural "%d games will be downloaded" +msgstr[0] "%d oyun indirilecek" +msgstr[1] "%d oyun indirilecek" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:161 +#, c-format +msgid "Image for %d game will be searched" +msgid_plural "Images for %d games will be searched" +msgstr[0] "%d oyun için görüntü aranacak" +msgstr[1] "%d oyun için görüntü aranacak" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:168 +#, c-format +msgid "%d game will be uninstalled" +msgid_plural "%d games will be uninstalled" +msgstr[0] "%d oyun kaldırılacak" +msgstr[1] "%d oyun kaldırılacak" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:174 +msgid "Refresh" +msgstr "Yenile" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:175 +#, c-format +msgid "" +"%d game will be removed from database. Restart GameHub to fetch new data" +msgid_plural "" +"%d games will be removed from database. Restart GameHub to fetch new data" +msgstr[0] "" +"%d oyun veritabanından kaldırılacak. Yeni veriler almak için GameHub'ı " +"yeniden başlatın" +msgstr[1] "" +"%d oyun veritabanından kaldırılacak. Yeni veriler almak için GameHub'ı " +"yeniden başlatın" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:240 +msgid "Open store page" +msgstr "Mağaza sayfasını aç" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:242 +msgid "Game properties" +msgstr "Oyun özellikleri" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:46 +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:60 +msgid "Playtime" +msgstr "Oynama zamanı" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:52 +msgid "Playtime (local)" +msgstr "Oynama zamanı (yerel)" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:69 +msgid "Last launch" +msgstr "Son başlatma" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:46 +msgid "Achievements" +msgstr "Başarılar" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:85 +#, c-format +msgid "Unlocked: %s" +msgstr "Kilidi açıldı: %s" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:90 +#, c-format +msgid "Global percentage: %g%%" +msgstr "Global yüzde: %%%g" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:77 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:103 +msgid "Language" +msgstr "Dil" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:80 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:106 +msgid "Languages" +msgstr "Diller" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:147 +#, c-format +msgid "%u DLCs cannot be installed" +msgstr "%u DLC yüklenemiyor" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:71 +msgid "Category" +msgstr "Kategori" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:74 +msgid "Categories" +msgstr "Kategoriler" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:90 +msgid "Genre" +msgstr "Tür" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:93 +msgid "Genres" +msgstr "Türler" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:109 +msgctxt "igdb" +msgid "Popularity" +msgstr "Popülerlik" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:115 +msgctxt "igdb" +msgid "Aggregated rating" +msgstr "Toplu derecelendirme" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:116 +msgctxt "igdb" +msgid "IGDB user rating" +msgstr "IGDB kullanıcı derecelendirmesi" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:117 +msgctxt "igdb" +msgid "Total rating" +msgstr "Toplam derecelendirme" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:126 +msgctxt "igdb" +msgid "Release date" +msgstr "Yayın tarihi" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:133 +msgctxt "igdb" +msgid "Platforms" +msgstr "Platformlar" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:139 +msgctxt "igdb" +msgid "Genres" +msgstr "Türler" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:145 +msgctxt "igdb" +msgid "Keywords" +msgstr "Anahtar kelimeler" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:152 +msgctxt "igdb" +msgid "Links" +msgstr "Linkler" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:208 +#, c-format +msgid "Based on %d rating" +msgid_plural "Based on %d ratings" +msgstr[0] "%d derecelendirmeye göre" +msgstr[1] "%d derecelendirmeye göre" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:290 +msgctxt "igdb" +msgid "Summary" +msgstr "Özet" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:301 +msgctxt "igdb" +msgid "Storyline" +msgstr "Hikayesi" + +#: src/ui/widgets/FileChooserEntry.vala:49 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select file" +msgstr "Dosya seç" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "No images" +msgstr "Görüntü yok" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "" +"There are no images found for this game\n" +"Make sure game name is correct" +msgstr "" +"Bu oyun için hiçbir resim bulunamadı\n" +"Oyun adının doğru olduğundan emin olun" + +#: src/ui/widgets/ImagesDownloadPopover.vala:94 +msgid "Search images:" +msgstr "Gürüntü ara:" + +#: src/ui/widgets/CompatToolPicker.vala:53 +msgid "Compatibility layer:" +msgstr "Uyumluluk katmanı:" + +#: src/ui/widgets/CompatToolPicker.vala:92 +msgid "Configure" +msgstr "Yapılandır" + +#: src/ui/widgets/GameTagsList.vala:109 +msgid "Add tag" +msgstr "Etiket ekle" + +#: src/ui/widgets/TweaksList.vala:86 +msgid "No description" +msgstr "Açıklama yok" + +#: src/ui/widgets/TweaksList.vala:124 +msgid "Edit file" +msgstr "Dosya düzenle" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dh" +msgstr "%dsaat" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dm" +msgstr "%ddk" + +#: src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%ds" +msgstr "%ds" + +#: src/settings/UI.vala:153 +msgctxt "grid_size_preset" +msgid "Steam" +msgstr "Steam" + +#: src/settings/UI.vala:154 +msgctxt "grid_size_preset" +msgid "Steam (vertical)" +msgstr "Steam (dikey)" + +#: src/settings/UI.vala:155 +msgctxt "grid_size_preset" +msgid "GOG" +msgstr "GOG" + +#: src/settings/UI.vala:156 +msgctxt "grid_size_preset" +msgid "GOG (vertical)" +msgstr "GOG (dikey)" + +#: src/settings/UI.vala:157 +msgctxt "grid_size_preset" +msgid "Square" +msgstr "Kare" + +#: src/settings/UI.vala:158 +msgctxt "grid_size_preset" +msgid "Custom" +msgstr "Özel" + +#: src/utils/downloader/Downloader.vala:200 +msgctxt "dl_status" +msgid "Queued" +msgstr "Sıraya konuldu" + +#: src/utils/downloader/Downloader.vala:201 +msgctxt "dl_status" +msgid "Starting download" +msgstr "İndirme başlatılıyor" + +#: src/utils/downloader/Downloader.vala:202 +msgctxt "dl_status" +msgid "Download started" +msgstr "İndirme başladı" + +#: src/utils/downloader/Downloader.vala:203 +msgctxt "dl_status" +msgid "Download finished" +msgstr "İndirme bitti" + +#: src/utils/downloader/Downloader.vala:204 +msgctxt "dl_status" +msgid "Download failed" +msgstr "İndirme başarısız oldu" + +#: src/utils/downloader/Downloader.vala:208 +#, c-format +msgctxt "dl_status" +msgid "Downloading: %s" +msgstr "İndiriliyor: %s" + +#: src/utils/downloader/Downloader.vala:210 +msgctxt "dl_status" +msgid "Downloading" +msgstr "İndiriliyor" + +#: src/utils/downloader/Downloader.vala:214 +#, c-format +msgctxt "dl_status" +msgid "Paused: %s" +msgstr "Duraklatıldı: %s" + +#: src/utils/downloader/Downloader.vala:216 +msgctxt "dl_status" +msgid "Paused" +msgstr "Duraklatıldı" + +#: src/utils/downloader/Downloader.vala:218 +msgctxt "dl_status" +msgid "Download cancelled" +msgstr "İndirme iptal edildi" + +#. TRANSLATORS: Download progress template. %1$d - percentage, %2$s / %3$s - downloaded portion and total file size, %4$s - download speed +#: src/utils/downloader/Downloader.vala:262 +#, c-format +msgctxt "dl_status" +msgid "%1$d%% (%2$s / %3$s) [%4$s/s]" +msgstr "%%%1$d (%2$s / %3$s) [%4$s/s]" + +#~ msgid "Disable esync" +#~ msgstr "Esync'i devre dışı bırak" + +#~ msgid "Force LARGE_ADDRESS_AWARE flag" +#~ msgstr "LARGE_ADDRESS_AWARE bayrağını zorla" + +#~ msgid "Disable DirectX 11 compatibility layer" +#~ msgstr "DirectX 11 uyumluluk katmanını devre dışı bırak" + +#~ msgid "Use WineD3D11 as DirectX 11 compatibility layer" +#~ msgstr "WineD3D11'i DirectX 11 uyumluluk katmanı olarak kullan" + +#~ msgid "Show DXVK info overlay" +#~ msgstr "DXVK bilgi paylaşımını göster" + +#~ msgid "Enable DirectX 9 compatibility layer" +#~ msgstr "DirectX 9 uyumluluk katmanını etkinleştir" + +#~ msgid "Silent installation" +#~ msgstr "Sessiz kurulum" + +#~ msgid "Very silent installation" +#~ msgstr "Çok sessiz kurulum" + +#~ msgid "Suppress messages" +#~ msgstr "Mesajları bastır" + +#~ msgid "No GUI" +#~ msgstr "GUI yok" diff --git a/po/zh_CN.po b/po/zh_CN.po new file mode 100644 index 00000000..0efde3da --- /dev/null +++ b/po/zh_CN.po @@ -0,0 +1,1849 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the com.github.tkashkin.gamehub package. +# wangling12 , 2019, 2020. +# Benjamin Zhao , 2020. +msgid "" +msgstr "" +"Project-Id-Version: com.github.tkashkin.gamehub\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-26 06:40+0300\n" +"PO-Revision-Date: 2020-02-09 07:50+0000\n" +"Last-Translator: Benjamin Zhao \n" +"Language-Team: Chinese (Simplified) \n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 3.11-dev\n" + +#: src/app.vala:91 +msgid "Show help" +msgstr "显示帮助" + +#: src/app.vala:92 +msgid "Show application version and exit" +msgstr "显示版本并退出" + +#: src/app.vala:93 +msgid "Restart with GDB debugger attached" +msgstr "重新启动附加的GDB调试器" + +#: src/app.vala:94 +msgid "Show full GDB backtrace" +msgstr "显示完整的GDB回溯" + +#: src/app.vala:95 +msgid "Treat fatal errors as criticals and crash application" +msgstr "将致命错误视为关键错误并关闭应用程序" + +#: src/app.vala:99 +msgid "Show main window" +msgstr "显示主窗口" + +#: src/app.vala:100 +msgid "Show application settings dialog" +msgstr "查看应用设置" + +#: src/app.vala:101 +msgid "Show about dialog" +msgstr "关于Gamehub" + +#: src/app.vala:102 +msgid "Maximum number of background worker threads" +msgstr "最大后台任务数" + +#: src/app.vala:106 +msgid "Run game" +msgstr "开始游戏" + +#: src/app.vala:107 +msgid "Show compatibility options dialog" +msgstr "显示兼容性选项窗口" + +#: src/app.vala:108 +msgid "Open game details" +msgstr "打开游戏详情" + +#: src/app.vala:109 +msgid "Open game properties" +msgstr "打开游戏属性" + +#: src/app.vala:113 +msgid "Enable debug logging" +msgstr "启用调试日志记录" + +#: src/app.vala:114 +msgid "" +"Log authentication process and sensitive information like authentication " +"tokens" +msgstr "记录身份验证过程和敏感信息,例如身份验证密钥" + +#: src/app.vala:115 +msgid "Log download manager" +msgstr "日志管理器" + +#: src/app.vala:116 +msgid "Log background workers start/stop" +msgstr "启动/停止日志后台工作" + +#: src/app.vala:117 +msgid "Disable log messages filtering" +msgstr "关闭日志信息过滤" + +#: src/app.vala:118 +msgid "Verbose logging" +msgstr "详细记录" + +#: src/app.vala:247 +msgid "Game Options:" +msgstr "游戏选项:" + +#: src/app.vala:247 +msgid "Show game options help" +msgstr "显示游戏选项帮助" + +#: src/app.vala:255 +msgid "Logging Options:" +msgstr "记录选项:" + +#: src/app.vala:255 +msgid "Show logging options help" +msgstr "显示日志选项帮助" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +msgid "Select executable" +msgstr "选择可执行文件" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:181 src/ui/views/GamesView/GamesView.vala:330 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select" +msgstr "选择" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:180 src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Cancel" +msgstr "取消" + +#: src/data/Runnable.vala:166 src/ui/widgets/FileChooserEntry.vala:49 +msgid "Select directory" +msgstr "选择文件夹" + +#: src/data/Runnable.vala:619 +#, c-format +msgid "Part %1$u of %2$u: %3$s" +msgstr "第%1$u部分(共%2$u部分):%3$s" + +#: src/data/Runnable.vala:642 src/ui/dialogs/CorruptedInstallerDialog.vala:48 +#, c-format +msgid "%s: corrupted installer" +msgstr "%s:安装程序损坏" + +#: src/data/Runnable.vala:643 +#, c-format +msgid "Checksum mismatch in %s" +msgstr "%s中的校验和不匹配" + +#: src/data/Runnable.vala:657 src/ui/dialogs/CorruptedInstallerDialog.vala:126 +msgid "Show file" +msgstr "显示文件" + +#: src/data/Runnable.vala:658 src/ui/dialogs/CorruptedInstallerDialog.vala:132 +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#: src/ui/widgets/TagRow.vala:146 +msgid "Remove" +msgstr "删除" + +#: src/data/Runnable.vala:659 src/ui/dialogs/CorruptedInstallerDialog.vala:128 +msgid "Backup" +msgstr "备份" + +#: src/data/Runnable.vala:778 +#, c-format +msgid "%s: cannot detect main executable" +msgstr "%s:无法检测到主要可执行文件" + +#: src/data/Runnable.vala:779 +msgid "" +"Main executable file for this game cannot be detected automatically.\n" +"Please set main executable in game's properties." +msgstr "" +"无法自动检测到此游戏的主可执行文件。\n" +"请在游戏的属性中设置主可执行文件。" + +#: src/data/Runnable.vala:908 +msgctxt "platform" +msgid "Emulated" +msgstr "模拟器" + +#: src/data/Game.vala:625 +msgctxt "status" +msgid "Running" +msgstr "正在运行" + +#: src/data/Game.vala:628 +msgctxt "status" +msgid "Installed" +msgstr "已安装" + +#: src/data/Game.vala:629 +msgctxt "status" +msgid "Installing" +msgstr "正在安装" + +#: src/data/Game.vala:630 +msgctxt "status" +msgid "Verifying installer integrity" +msgstr "验证安装程序的完整性" + +#: src/data/Game.vala:631 +msgctxt "status" +msgid "Download started" +msgstr "开始下载" + +#: src/data/Game.vala:633 +msgctxt "status" +msgid "Not installed" +msgstr "未安装" + +#: src/data/Game.vala:643 +msgctxt "status_header" +msgid "Installed" +msgstr "已安装" + +#: src/data/Game.vala:644 +msgctxt "status_header" +msgid "Installing" +msgstr "正在安装" + +#: src/data/Game.vala:646 +msgctxt "status_header" +msgid "Downloading" +msgstr "正在下载" + +#: src/data/Game.vala:648 +msgctxt "status_header" +msgid "Not installed" +msgstr "未安装" + +#: src/data/GameSource.vala:31 +#, c-format +msgid "%s games" +msgstr "%s个游戏" + +#: src/data/sources/steam/Steam.vala:43 +msgid "Your SteamID will be read from Steam configuration file" +msgstr "您的 SteamID 将从 Steam 配置文件中读取" + +#: src/data/sources/steam/Steam.vala:46 +msgid "" +"Steam config file not found.\n" +"Login into your account in Steam client and return to GameHub" +msgstr "" +"找不到Steam配置文件。\n" +"在Steam客户端中登录您的帐户并返回GameHub" + +#: src/data/sources/gog/GOGGame.vala:983 +#, c-format +msgid "DLC: %s" +msgstr "DLC: %s" + +#: src/data/sources/humble/HumbleGame.vala:343 +#, c-format +msgid "%s: no available installers" +msgstr "%s:没有可用的安装程序" + +#: src/data/sources/humble/HumbleGame.vala:344 +msgid "" +"Cannot get Trove download URL.\n" +"Make sure your Humble Monthly subscription is active." +msgstr "" +"无法获取Trove下载URL。\n" +"确保您的Humble Monthly订阅处于活动状态。" + +#: src/data/sources/itch/ItchDownloader.vala:192 +#, c-format +msgctxt "itch_dl_status" +msgid "%s left;" +msgstr "还剩%s;" + +#: src/data/sources/itch/ItchDownloader.vala:195 +#, c-format +msgctxt "itch_dl_status" +msgid "%d%%" +msgstr "%d%%" + +#: src/data/sources/itch/ItchDownloader.vala:198 +#, c-format +msgctxt "itch_dl_status" +msgid "(%1$s / %2$s)" +msgstr "(%1$s / %2$s)" + +#: src/data/sources/itch/ItchDownloader.vala:201 +#, c-format +msgctxt "itch_dl_status" +msgid "[%s/s]" +msgstr "[%s/s]" + +#: src/data/sources/user/User.vala:30 +msgid "User games" +msgstr "用户游戏" + +#: src/data/db/tables/Tags.vala:225 +msgctxt "tag" +msgid "Favorites" +msgstr "收藏 夹" + +#: src/data/db/tables/Tags.vala:226 +msgctxt "tag" +msgid "Not installed" +msgstr "未安装" + +#: src/data/db/tables/Tags.vala:227 +msgctxt "tag" +msgid "Installed" +msgstr "已安装" + +#: src/data/db/tables/Tags.vala:228 +msgctxt "tag" +msgid "Hidden" +msgstr "隐藏" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit script" +msgstr "编辑脚本" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit custom script" +msgstr "编辑自定义脚本" + +#: src/data/compat/Innoextract.vala:55 +#, c-format +msgid "" +"Innoextract %1$s is not supported and may not be able to extract some " +"games correctly.\n" +"Install innoextract %2$s or newer." +msgstr "" +"Innoextract %1$s 不受支持,可能无法正确提取某些游戏。\n" +"安装 innoextract %2$s 或更高版本。" + +#: src/data/compat/WineWrap.vala:61 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:242 +#: src/ui/dialogs/CompatRunDialog.vala:102 +#: src/ui/views/GamesView/GameContextMenu.vala:53 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:234 +msgid "Run" +msgstr "运行" + +#: src/data/compat/WineWrap.vala:64 +msgid "Show WineWrap menu" +msgstr "显示WineWrap菜单" + +#: src/data/compat/WineWrap.vala:67 src/data/compat/Proton.vala:122 +#: src/data/compat/Wine.vala:83 +msgid "Kill apps in prefix" +msgstr "杀死prefix中的应用" + +#: src/data/compat/Proton.vala:47 +msgid "Proton prefix" +msgstr "Proton prefix" + +#: src/data/compat/Proton.vala:110 src/data/compat/Wine.vala:71 +msgid "Open prefix directory" +msgstr "打开prefix目录" + +#: src/data/compat/Proton.vala:113 src/data/compat/Wine.vala:74 +msgid "Run winecfg" +msgstr "运行winecfg" + +#: src/data/compat/Proton.vala:116 src/data/compat/Wine.vala:77 +msgid "Run winetricks" +msgstr "运行winetricks" + +#: src/data/compat/Proton.vala:119 src/data/compat/Wine.vala:80 +msgid "Run taskmgr" +msgstr "运行taskmgr" + +#: src/data/compat/Wine.vala:53 +msgid "Wine prefix" +msgstr "Wine prefix" + +#: src/data/compat/Wine.vala:55 +msgid "Environment variables" +msgstr "环境变量" + +#: src/data/compat/Wine.vala:60 +msgid "InnoSetup default options" +msgstr "InnoSetup 默认选项" + +#: src/data/compat/RetroArch.vala:53 +msgid "Libretro core file" +msgstr "Libretro 核心文件" + +#: src/data/compat/CustomEmulator.vala:43 +msgid "Custom emulator" +msgstr "自定义模拟器" + +#: src/data/compat/CustomEmulator.vala:48 +msgid "Emulator" +msgstr "模拟器" + +#: src/data/compat/CustomEmulator.vala:49 +msgid "Launch in game directory" +msgstr "在游戏目录中启动" + +#: src/data/adapters/GamesAdapter.vala:440 +msgctxt "status_header" +msgid "Favorites" +msgstr "收藏 夹" + +#: src/data/adapters/GamesAdapter.vala:445 +#, c-format +msgctxt "status_header" +msgid "%s: Favorites" +msgstr "%s:收藏夹" + +#: src/data/adapters/GamesAdapter.vala:491 +msgid "Merging games" +msgstr "合并游戏" + +#: src/data/adapters/GamesAdapter.vala:504 +#, c-format +msgid "Merging games from %s" +msgstr "从 %s 合并游戏" + +#: src/data/adapters/GamesAdapter.vala:551 +#, c-format +msgid "Loading games from %s" +msgstr "从 %s 加载游戏" + +#: src/data/adapters/GamesAdapter.vala:678 +msgctxt "sort_mode" +msgid "By name" +msgstr "按名称" + +#: src/data/adapters/GamesAdapter.vala:679 +msgctxt "sort_mode" +msgid "By last launch" +msgstr "按最后一次运行" + +#: src/data/adapters/GamesAdapter.vala:680 +msgctxt "sort_mode" +msgid "By playtime" +msgstr "按游戏时间" + +#: src/data/adapters/GamesAdapter.vala:705 +msgctxt "group_mode" +msgid "Do not group" +msgstr "不分组" + +#: src/data/adapters/GamesAdapter.vala:706 +msgctxt "group_mode" +msgid "By status" +msgstr "按状态" + +#: src/data/adapters/GamesAdapter.vala:707 +msgctxt "group_mode" +msgid "By source" +msgstr "按来源" + +#: src/data/providers/images/SteamGridDB.vala:151 +#: src/data/providers/data/IGDB.vala:431 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:217 +msgid "Default" +msgstr "默认" + +#: src/data/providers/images/SteamGridDB.vala:158 +#: src/data/providers/data/IGDB.vala:438 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:225 +msgid "Restore default API key" +msgstr "恢复默认的API密钥" + +#: src/data/providers/images/SteamGridDB.vala:169 +#: src/data/providers/data/IGDB.vala:449 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:108 +msgid "API key" +msgstr "API 密钥" + +#: src/data/providers/images/SteamGridDB.vala:177 +#: src/data/providers/data/IGDB.vala:457 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:53 +msgid "Generate key" +msgstr "生成密钥" + +#: src/data/providers/images/SteamGridDB.vala:208 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Style" +msgstr "Style" + +#: src/data/providers/images/SteamGridDB.vala:209 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Score" +msgstr "Score" + +#: src/data/providers/images/SteamGridDB.vala:213 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Author" +msgstr "Author" + +#: src/data/providers/images/SteamGridDB.vala:225 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Alternate" +msgstr "Alternate" + +#: src/data/providers/images/SteamGridDB.vala:226 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Blurred" +msgstr "Blurred" + +#. TRANSLATORS: Flat / Material Design image style. Probably should not be translated +#: src/data/providers/images/SteamGridDB.vala:228 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Material" +msgstr "Material" + +#: src/data/providers/images/SteamGridDB.vala:229 +msgctxt "imagesource_steamgriddb_image_style" +msgid "No logo" +msgstr "No logo" + +#: src/data/providers/images/SteamGridDB.vala:230 +msgctxt "imagesource_steamgriddb_image_style" +msgid "White logo" +msgstr "White logo" + +#: src/data/providers/data/IGDB.vala:147 +msgid "" +"Monthly IGDB request quota has been reached. Set your own API key to use " +"IGDB data or disable IGDB." +msgstr "已达到每月IGDB请求配额。设置您自己的API密钥以使用IGDB数据或禁用IGDB。" + +#: src/data/providers/data/IGDB.vala:148 +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:40 +#: src/ui/views/WelcomeView.vala:53 src/ui/views/WelcomeView.vala:78 +#: src/ui/views/GamesView/GamesView.vala:230 +#: src/ui/views/GamesView/GamesView.vala:629 +msgid "Settings" +msgstr "设置" + +#: src/data/providers/data/IGDB.vala:356 +msgctxt "igdb_related_link" +msgid "Official website" +msgstr "官方网站" + +#: src/data/providers/data/IGDB.vala:469 +msgctxt "igdb_preferred_description" +msgid "When game has description, show description" +msgstr "当游戏有描述时,显示描述" + +#: src/data/providers/data/IGDB.vala:476 +msgctxt "igdb_preferred_description" +msgid "of game" +msgstr "游戏的" + +#: src/data/providers/data/IGDB.vala:477 +msgctxt "igdb_preferred_description" +msgid "from IGDB" +msgstr "来自IGDB" + +#: src/data/providers/data/IGDB.vala:478 +msgctxt "igdb_preferred_description" +msgid "both" +msgstr "都" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:65 +msgid "Some settings will be applied after application restart" +msgstr "某些设置将在应用程序重新启动后应用" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:71 +msgid "Games directory contains space. It may cause problems for some games" +msgstr "游戏目录包含空间。可能会导致某些游戏出现问题" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:36 +msgid "Interface" +msgstr "界面" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:37 +msgid "Appearance" +msgstr "外观" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:38 +msgid "General interface settings" +msgstr "常规界面设置" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:48 +msgid "Dark theme" +msgstr "暗色主题" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:53 +msgctxt "icon_style" +msgid "Theme-based" +msgstr "基于主题" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:54 +msgctxt "icon_style" +msgid "Symbolic" +msgstr "使其具有象征" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:55 +msgctxt "icon_style" +msgid "Colored" +msgstr "彩色" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:57 +msgctxt "icon_style" +msgid "Icon style" +msgstr "图标样式" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:84 +msgid "Game card" +msgstr "游戏卡牌" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:86 +msgid "Show platform icons" +msgstr "显示平台图标" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:99 +msgctxt "grid_size" +msgid "Card size" +msgstr "卡片大小" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:117 +msgctxt "grid_size_preset" +msgid "Presets" +msgstr "预设" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:139 +msgid "Games list: installed" +msgstr "游戏列表:已安装" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:140 +msgid "Games list: not installed" +msgstr "游戏列表:未安装" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:142 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:146 +msgctxt "list_style" +msgid "Show icon" +msgstr "显示图标" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:143 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:147 +msgctxt "list_style" +msgid "Bold title" +msgstr "标题加粗" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:144 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:148 +msgctxt "list_style" +msgid "Show status" +msgstr "显示状态" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:149 +msgctxt "list_style" +msgid "Dim" +msgstr "暗淡" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:151 +msgid "Grid options" +msgstr "网格选项" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:152 +msgid "List options" +msgstr "列表选项" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:31 +msgid "Behavior" +msgstr "行为" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:32 +msgid "Behavior settings" +msgstr "行为设置" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:42 +msgid "Run games with double click" +msgstr "双击运行游戏" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:46 +msgid "Merge games from different sources" +msgstr "合并来自不同来源的游戏" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:50 +msgid "Use imported tags" +msgstr "使用导入的标记" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:51 +msgid "General" +msgstr "通用" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:52 +msgid "Collection" +msgstr "游戏库" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:53 +msgid "Empty" +msgstr "空" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:65 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:85 +msgid "Collection directory" +msgstr "游戏库文件夹" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:70 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:78 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:87 +msgid "Game directory" +msgstr "游戏目录" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:71 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:79 +msgid "Installers" +msgstr "安装文件" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:72 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:98 +msgid "DLC" +msgstr "DLC" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:73 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:197 +msgid "Bonus content" +msgstr "奖励内容" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:84 +msgid "Variable syntax: $var or ${var}" +msgstr "变量语法:$var${var}" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:86 +msgid "Game name" +msgstr "游戏名称" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:88 +#: src/ui/views/GamesView/FiltersPopover.vala:127 +msgid "Platform" +msgstr "平台" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:36 +msgid "Controller" +msgstr "控制器" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +msgid "Enabled" +msgstr "启用" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:53 +msgid "Focus GameHub window with Guide button" +msgstr "使用Guide按钮将GameHub窗口置于最前" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:57 +msgid "Controllers" +msgstr "控制器" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:89 +msgid "Move focus" +msgstr "移动焦点" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:91 +msgid "Exit" +msgstr "退出" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:40 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:108 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:92 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:95 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:36 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:77 +msgid "Disabled" +msgstr "禁用" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:47 +#: src/ui/dialogs/GameTweaksDialog.vala:53 +#: src/ui/views/GamesView/GameContextMenu.vala:183 +msgid "Tweaks" +msgstr "调整" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:34 +msgid "Tweak launch options and apply them to games automatically" +msgstr "调整启动选项并将其自动应用于游戏" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:79 +msgid "" +"Tweaks are loaded from following directories in order\n" +"Last tweak overrides previous tweaks with same identifiers" +msgstr "" +"从以下目录按顺序加载调整项\n" +"相同条目的后续调整会覆盖之前的" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:83 +msgid "Click to open" +msgstr "点击打开" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:93 +#, c-format +msgid "Tweaks are loaded from %1$s and %2$d more directories (?)" +msgstr "从%1$s和另外%2$d个目录(?)加载调整" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:38 +msgid "Game sources" +msgstr "游戏源" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +msgid "Steam API keys have limited number of uses per day" +msgstr "Steam API密钥每天的使用次数有限制" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:63 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:57 +msgid "Installation directory" +msgstr "安装目录" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:176 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:81 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:34 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:75 +msgid "Not installed" +msgstr "未安装" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:116 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:96 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:99 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:85 +msgid "Not authenticated" +msgstr "未认证" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +#, c-format +msgid "Authenticated as %s" +msgstr "认证为%s " + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:103 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +msgid "Authenticated" +msgstr "已认证" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:183 +#: src/ui/dialogs/InstallDialog.vala:53 src/ui/dialogs/InstallDialog.vala:111 +#: src/ui/views/GamesView/GameContextMenu.vala:80 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:233 +#: src/ui/widgets/TweaksList.vala:95 +msgid "Install" +msgstr "安装" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:236 +msgid "Steam API key" +msgstr "Steam API密钥" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:50 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:54 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:48 +msgid "Games directory" +msgstr "游戏目录" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:63 +msgid "Logout" +msgstr "注销" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:50 +msgid "Load games from Humble Trove" +msgstr "从Humble Trove载入游戏" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:45 +msgid "Emulators" +msgstr "模拟器" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:45 +msgid "Libretro core directory" +msgstr "Libretro 核心目录" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:46 +msgid "Libretro core info directory" +msgstr "Libretro 核心信息目录" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:50 +msgid "Ignored libretro cores" +msgstr "忽略libretro核心" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:54 +msgid "Ignored game file extensions" +msgstr "忽略游戏文件扩展名" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:66 +msgid "No cores found" +msgstr "未找到内核" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:70 +#, c-format +msgid "%u core found" +msgid_plural "%u cores found" +msgstr[0] "找到 %u 个内核" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:46 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:168 +msgid "No custom emulators" +msgstr "没有自定义模拟器" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:164 +#, c-format +msgid "%u custom emulator" +msgid_plural "%u custom emulators" +msgstr[0] "%u个自定义模拟器" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:237 +msgid "Save" +msgstr "救" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:250 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:312 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/dialogs/GamePropertiesDialog.vala:168 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +#: src/ui/views/GamesView/AddGamePopover.vala:67 +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Executable" +msgstr "可执行文件" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:251 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/views/GamesView/AddGamePopover.vala:68 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +msgid "Installer" +msgstr "安装程序" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:256 +#: src/ui/dialogs/GamePropertiesDialog.vala:64 +#: src/ui/dialogs/GamePropertiesDialog.vala:69 +#: src/ui/views/GamesView/AddGamePopover.vala:73 +msgid "Name" +msgstr "名称" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:272 +#: src/ui/dialogs/GamePropertiesDialog.vala:201 +#: src/ui/views/GamesView/AddGamePopover.vala:78 +msgid "Arguments" +msgstr "参数" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:276 +msgid "Variables" +msgstr "变量" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:277 +msgid "Game executable" +msgstr "游戏可执行文件" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:278 +msgid "Game arguments" +msgstr "游戏参数" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:80 +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Directory" +msgstr "目录" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +msgid "Select emulator directory" +msgstr "选择模拟器目录" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:292 +#: src/ui/dialogs/GamePropertiesDialog.vala:219 +msgid "Force compatibility mode" +msgstr "强制兼容模式" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:307 +msgid "Game file patterns" +msgstr "游戏文件格式" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:315 +msgid "Image" +msgstr "图片" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:318 +msgid "Icon" +msgstr "图标" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:325 +msgid "" +"findutils-compatible glob patterns\n" +"\n" +" Multiple patterns can be separated with |\n" +" Start pattern with ./ to match relative path\n" +" $basename variable will be replaced with game's executable " +"name (without extension)" +msgstr "" +"findutils兼容的全局模式\n" +"\n" +"可以用|分隔多个模式\n" +" ./ 开头的模式以匹配相对路径\n" +" $basename变量将替换为游戏的可执行文件名称(不带扩展名)" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:38 +msgid "Data" +msgstr "数据" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:39 +msgid "Providers" +msgstr "提供者" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:40 +msgid "Third-party data providers" +msgstr "第三方数据提供者" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:55 +msgid "Image providers" +msgstr "图片提供者" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:68 +msgid "Metadata providers" +msgstr "元数据提供者" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:137 +msgid "Open website" +msgstr "打开网站" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:36 +msgid "About" +msgstr "关于" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:71 +msgid "Copy application version and environment info" +msgstr "复制应用程序版本和环境信息" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:78 +#: src/ui/views/WelcomeView.vala:57 +msgid "All your games in one place" +msgstr "将您所有的游戏都整合到同一个地方" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:92 +msgctxt "about_link" +msgid "Website" +msgstr "网站" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:96 +msgctxt "about_link" +msgid "Source code on GitHub" +msgstr "GitHub上的源码" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:103 +msgctxt "about_link" +msgid "Report a problem" +msgstr "报告问题" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:104 +msgctxt "about_link" +msgid "Suggest translations" +msgstr "提议翻译" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:110 +msgctxt "about_link" +msgid "Issues" +msgstr "问题" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:111 +msgctxt "about_link" +msgid "Contributors" +msgstr "贡献者" + +#. TRANSLATORS: Likely it should not be translated. GitHub Pulse is a page that shows recent repository activity: https://github.com/tkashkin/GameHub/pulse +#: src/ui/dialogs/SettingsDialog/pages/About.vala:114 +msgctxt "about_link" +msgid "Pulse" +msgstr "Pulse" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:115 +msgctxt "about_link" +msgid "Forks" +msgstr "Forks" + +#: src/ui/dialogs/InstallDialog.vala:109 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:129 +msgid "Import" +msgstr "导入" + +#: src/ui/dialogs/InstallDialog.vala:110 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:153 +msgid "Download" +msgstr "下载" + +#: src/ui/dialogs/InstallDialog.vala:207 +msgid "Select installer" +msgstr "选择安装程序" + +#: src/ui/dialogs/InstallDialog.vala:216 +#, c-format +msgid "Installer size: %s" +msgstr "安装程序大小: %s" + +#: src/ui/dialogs/InstallDialog.vala:348 +msgid "Unknown" +msgstr "未知" + +#: src/ui/dialogs/GamePropertiesDialog.vala:49 +#, c-format +msgid "%s: Properties" +msgstr "%s:属性" + +#: src/ui/dialogs/GamePropertiesDialog.vala:84 +msgid "Images" +msgstr "图像" + +#: src/ui/dialogs/GamePropertiesDialog.vala:126 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:160 +#: src/ui/views/GameDetailsView/blocks/Artwork.vala:62 +msgid "Download images" +msgstr "下载图片" + +#: src/ui/dialogs/GamePropertiesDialog.vala:144 +msgid "Image URL" +msgstr "图片网址" + +#: src/ui/dialogs/GamePropertiesDialog.vala:148 +msgid "Vertical image URL" +msgstr "垂直图片的网址" + +#: src/ui/dialogs/GamePropertiesDialog.vala:157 +msgid "Icon URL" +msgstr "图标网址" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Select working directory" +msgstr "选择工作目录" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +msgid "Working directory" +msgstr "工作目录" + +#: src/ui/dialogs/GamePropertiesDialog.vala:214 +msgid "Compatibility" +msgstr "兼容性" + +#: src/ui/dialogs/GamePropertiesDialog.vala:236 +msgid "Launch from terminal" +msgstr "从终端启动" + +#: src/ui/dialogs/GamePropertiesDialog.vala:252 +msgid "Copy to clipboard" +msgstr "复制到剪贴板" + +#: src/ui/dialogs/GamePropertiesDialog.vala:254 +msgid "Add to Steam" +msgstr "添加到Steam" + +#: src/ui/dialogs/GamePropertiesDialog.vala:255 +msgid "Add to the Steam library" +msgstr "添加到Steam库" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:53 +#, c-format +msgid "%s: Overlays" +msgstr "%s:覆盖" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "Overlays are disabled" +msgstr "叠加层已禁用" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "" +"Enable overlays to manage DLCs and mods\n" +"\n" +"Enabling will move game to the “base“ overlay" +msgstr "" +"启用叠加层以管理DLC和Mod\n" +"\n" +"启用该设置会将游戏移至“基本”叠加层" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:77 +#: src/ui/views/GamesView/GameContextMenu.vala:175 +msgid "Overlays" +msgstr "叠加层" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:105 +msgid "Overlay ID (directory name)" +msgstr "叠加ID(目录名称)" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:110 +msgid "Overlay name (optional)" +msgstr "叠加名称(可选)" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:112 +msgid "Add" +msgstr "添加" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:127 +msgid "Enable overlays" +msgstr "启用叠加层" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:182 +#, c-format +msgid "" +"Overlay usage at this path may be unsafe\n" +"Proceed at your own risk\n" +"\n" +"Path: %s" +msgstr "" +"此路径的叠加用法可能不安全\n" +"如果继续需要,自行承担风险\n" +"\n" +"路径:%s" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:187 +#, c-format +msgid "" +"Overlay usage at this path is not supported\n" +"\n" +"Path: %s" +msgstr "" +"不支持此路径的叠加用法\n" +"\n" +"路径:%s" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:266 +msgid "Open directory" +msgstr "打开目录" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:271 +msgid "Remove overlay" +msgstr "移除叠加层" + +#: src/ui/dialogs/CompatRunDialog.vala:48 +#: src/ui/views/GamesView/GameContextMenu.vala:46 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:235 +msgid "Run with compatibility layer" +msgstr "用兼容层运行" + +#: src/ui/dialogs/CorruptedInstallerDialog.vala:71 +msgid "Corrupted installer: checksum mismatch in" +msgstr "安装程序损坏:校验和不匹配" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:57 +#: src/ui/views/GamesView/AddGamePopover.vala:105 +msgid "Import emulated games" +msgstr "导入模拟游戏" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:75 +msgid "Select directory with emulated games" +msgstr "选择包含模拟游戏的目录" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:83 +msgid "Detected games" +msgstr "检测到的游戏" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:107 +msgid "Select all" +msgstr "全选" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:115 +msgid "Select directory to import" +msgstr "选择要导入的目录" + +#: src/ui/dialogs/GameTweaksDialog.vala:40 +#, c-format +msgid "%s: Tweaks" +msgstr "%s:覆盖" + +#: src/ui/views/WelcomeView.vala:52 +msgid "No enabled game sources" +msgstr "未启用的游戏源" + +#: src/ui/views/WelcomeView.vala:52 +msgid "Enable some game sources in settings" +msgstr "在设置中启用某些游戏源" + +#: src/ui/views/WelcomeView.vala:57 +msgid "Let's get started" +msgstr "让我们开始吧" + +#: src/ui/views/WelcomeView.vala:71 +msgid "Skip" +msgstr "跳过" + +#: src/ui/views/WelcomeView.vala:141 +msgid "Ready" +msgstr "准备就绪" + +#: src/ui/views/WelcomeView.vala:147 +msgid "Authentication required" +msgstr "需要身份验证" + +#: src/ui/views/WelcomeView.vala:152 +msgid "Authenticating…" +msgstr "正在验证…" + +#: src/ui/views/WelcomeView.vala:163 +#, c-format +msgid "Install %s" +msgstr "安装 %s" + +#: src/ui/views/WelcomeView.vala:164 +msgid "Return to GameHub after installing" +msgstr "安装后返回 GameHub" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "No games" +msgstr "没有游戏" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "Get some games or enable some game sources in settings" +msgstr "获取游戏或在设置中启用一些游戏源" + +#: src/ui/views/GamesView/GamesView.vala:150 +msgid "Grid view" +msgstr "网格视图" + +#: src/ui/views/GamesView/GamesView.vala:151 +msgid "List view" +msgstr "列表视图" + +#: src/ui/views/GamesView/GamesView.vala:159 +msgid "All games" +msgstr "所有游戏" + +#: src/ui/views/GamesView/GamesView.vala:182 +msgid "Downloads" +msgstr "下载" + +#: src/ui/views/GamesView/GamesView.vala:208 +msgid "Filters" +msgstr "过滤器" + +#: src/ui/views/GamesView/GamesView.vala:216 +#: src/ui/views/GamesView/AddGamePopover.vala:84 +msgid "Add game" +msgstr "添加游戏" + +#: src/ui/views/GamesView/GamesView.vala:223 +msgid "Search" +msgstr "搜索" + +#: src/ui/views/GamesView/GamesView.vala:328 +msgid "Menu" +msgstr "菜单" + +#: src/ui/views/GamesView/GamesView.vala:329 +#: src/ui/views/GameDetailsView/GameDetailsView.vala:104 +msgid "Back" +msgstr "返回" + +#: src/ui/views/GamesView/GamesView.vala:550 +#, c-format +msgid "%u game" +msgid_plural "%u games" +msgstr[0] "%u 个游戏" + +#: src/ui/views/GamesView/GamesView.vala:553 +#, fuzzy, c-format +msgctxt "games_view_subtitle_filtered_games" +msgid "%1$u / %2$s" +msgstr "(%1$s / %2$s)" + +#: src/ui/views/GamesView/GamesView.vala:557 +#, fuzzy, c-format +msgctxt "games_view_subtitle" +msgid "%1$s: %2$s" +msgstr "(%1$s / %2$s)" + +#: src/ui/views/GamesView/GamesView.vala:568 +msgid "No user-added games" +msgstr "无用户添加的游戏" + +#: src/ui/views/GamesView/GamesView.vala:569 +msgid "Add some games using plus button" +msgstr "使用加号按钮添加一些游戏" + +#: src/ui/views/GamesView/GamesView.vala:573 +#, c-format +msgid "No %s games" +msgstr "无 %s 游戏" + +#: src/ui/views/GamesView/GamesView.vala:574 +msgid "Get some Linux-compatible games" +msgstr "获取一些与 Linux 兼容的游戏" + +#: src/ui/views/GamesView/GamesView.vala:584 +#, c-format +msgid "No games matching “%s”" +msgstr "没有匹配\"%s\"的游戏" + +#: src/ui/views/GamesView/GamesView.vala:589 +#, c-format +msgid "No %1$s games matching “%2$s”" +msgstr "没有与\"%2$s\"匹配的%1$s 游戏" + +#: src/ui/views/GamesView/GamesView.vala:627 +msgid "" +"No games were loaded from Steam. Set your games list privacy to public or " +"use your own Steam API key in settings." +msgstr "" +"没有从Steam加载到任何游戏。将您的游戏列表隐私设置为公开或在设置中使用您自己的" +"Steam API密钥。" + +#: src/ui/views/GamesView/GamesView.vala:628 +msgid "Privacy" +msgstr "隐私" + +#: src/ui/views/GamesView/GamesView.vala:739 +msgid "Downloading images" +msgstr "下载图像" + +#: src/ui/views/GamesView/GamesView.vala:753 +#, c-format +msgid "Downloading image: %s" +msgstr "下载图片: %s" + +#: src/ui/views/GamesView/DownloadProgressView.vala:131 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:162 +msgid "Pause download" +msgstr "暂停下载" + +#: src/ui/views/GamesView/DownloadProgressView.vala:137 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:168 +msgid "Resume download" +msgstr "恢复下载" + +#: src/ui/views/GamesView/DownloadProgressView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:174 +msgid "Cancel download" +msgstr "取消下载" + +#: src/ui/views/GamesView/FiltersPopover.vala:77 +msgid "Group" +msgstr "组" + +#: src/ui/views/GamesView/FiltersPopover.vala:102 +msgid "Sort" +msgstr "排序" + +#: src/ui/views/GamesView/FiltersPopover.vala:234 +#: src/ui/widgets/GameTagsList.vala:58 +msgid "Tags" +msgstr "标签" + +#: src/ui/views/GamesView/FiltersPopover.vala:353 +msgid "All platforms" +msgstr "所有平台" + +#: src/ui/views/GamesView/AddGamePopover.vala:77 +msgid "Select game executable" +msgstr "选择游戏可执行文件" + +#: src/ui/views/GamesView/AddGamePopover.vala:82 +msgid "Select game directory" +msgstr "选择游戏目录" + +#: src/ui/views/GamesView/AddGamePopover.vala:111 +msgid "Download game images" +msgstr "下载游戏图片" + +#: src/ui/views/GamesView/GameContextMenu.vala:87 +msgid "Details" +msgstr "详细信息" + +#: src/ui/views/GamesView/GameContextMenu.vala:117 +msgctxt "game_context_menu" +msgid "Favorite" +msgstr "收藏 夹" + +#: src/ui/views/GamesView/GameContextMenu.vala:121 +msgctxt "game_context_menu" +msgid "Hidden" +msgstr "隐藏" + +#: src/ui/views/GamesView/GameContextMenu.vala:133 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:236 +msgid "Open installation directory" +msgstr "打开安装目录" + +#: src/ui/views/GamesView/GameContextMenu.vala:142 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:237 +msgid "Open installers collection directory" +msgstr "打开安装程序集合目录" + +#: src/ui/views/GamesView/GameContextMenu.vala:151 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:238 +msgid "Open bonus collection directory" +msgstr "打开奖励收集目录" + +#: src/ui/views/GamesView/GameContextMenu.vala:160 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:239 +msgid "Open screenshots directory" +msgstr "打开屏幕截图目录" + +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +msgid "Uninstall" +msgstr "卸载" + +#: src/ui/views/GamesView/GameContextMenu.vala:192 +msgid "Properties" +msgstr "属性" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:100 +#, c-format +msgid "%d game selected" +msgid_plural "%d games selected" +msgstr[0] "已选择 %d 个游戏" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:144 +#, c-format +msgid "%d game will be installed" +msgid_plural "%d games will be installed" +msgstr[0] "将安装 %d 个游戏" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:154 +#, c-format +msgid "%d game will be downloaded" +msgid_plural "%d games will be downloaded" +msgstr[0] "将下载 %d 个游戏" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:161 +#, c-format +msgid "Image for %d game will be searched" +msgid_plural "Images for %d games will be searched" +msgstr[0] "将搜索 %d 个游戏的图像" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:168 +#, c-format +msgid "%d game will be uninstalled" +msgid_plural "%d games will be uninstalled" +msgstr[0] "%d 个游戏将被卸载" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:174 +msgid "Refresh" +msgstr "刷新" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:175 +#, c-format +msgid "" +"%d game will be removed from database. Restart GameHub to fetch new data" +msgid_plural "" +"%d games will be removed from database. Restart GameHub to fetch new data" +msgstr[0] "%d 个游戏将从数据库中删除。重新启动 GameHub 以获取新数据" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:240 +msgid "Open store page" +msgstr "打开商店页面" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:242 +msgid "Game properties" +msgstr "游戏属性" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:46 +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:60 +msgid "Playtime" +msgstr "游戏时长" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:52 +msgid "Playtime (local)" +msgstr "游戏时长(本地)" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:69 +msgid "Last launch" +msgstr "最后启动" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:46 +msgid "Achievements" +msgstr "成就" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:85 +#, c-format +msgid "Unlocked: %s" +msgstr "解锁: %s" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:90 +#, c-format +msgid "Global percentage: %g%%" +msgstr "全球百分比:%g%%" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:77 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:103 +msgid "Language" +msgstr "语言" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:80 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:106 +msgid "Languages" +msgstr "语言" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:147 +#, c-format +msgid "%u DLCs cannot be installed" +msgstr "%u 安装程序已损坏,无法安装" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:71 +msgid "Category" +msgstr "类别" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:74 +msgid "Categories" +msgstr "类别" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:90 +msgid "Genre" +msgstr "体裁" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:93 +msgid "Genres" +msgstr "体裁" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:109 +msgctxt "igdb" +msgid "Popularity" +msgstr "人气度" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:115 +msgctxt "igdb" +msgid "Aggregated rating" +msgstr "综合评分" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:116 +msgctxt "igdb" +msgid "IGDB user rating" +msgstr "IGDB 用户评分" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:117 +msgctxt "igdb" +msgid "Total rating" +msgstr "总评分" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:126 +msgctxt "igdb" +msgid "Release date" +msgstr "发布日期" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:133 +msgctxt "igdb" +msgid "Platforms" +msgstr "平台" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:139 +msgctxt "igdb" +msgid "Genres" +msgstr "体裁" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:145 +msgctxt "igdb" +msgid "Keywords" +msgstr "关键字" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:152 +msgctxt "igdb" +msgid "Links" +msgstr "链接" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:208 +#, c-format +msgid "Based on %d rating" +msgid_plural "Based on %d ratings" +msgstr[0] "根据%d评分" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:290 +msgctxt "igdb" +msgid "Summary" +msgstr "摘要" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:301 +msgctxt "igdb" +msgid "Storyline" +msgstr "故事情节" + +#: src/ui/widgets/FileChooserEntry.vala:49 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select file" +msgstr "选择文件" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "No images" +msgstr "无图像" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "" +"There are no images found for this game\n" +"Make sure game name is correct" +msgstr "" +"没有找到这个游戏的图像\n" +"确保游戏名称正确" + +#: src/ui/widgets/ImagesDownloadPopover.vala:94 +msgid "Search images:" +msgstr "搜索图片:" + +#: src/ui/widgets/CompatToolPicker.vala:53 +msgid "Compatibility layer:" +msgstr "兼容层:" + +#: src/ui/widgets/CompatToolPicker.vala:92 +msgid "Configure" +msgstr "配置" + +#: src/ui/widgets/GameTagsList.vala:109 +msgid "Add tag" +msgstr "添加标记" + +#: src/ui/widgets/TweaksList.vala:86 +msgid "No description" +msgstr "没有说明" + +#: src/ui/widgets/TweaksList.vala:124 +msgid "Edit file" +msgstr "选择文件" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dh" +msgstr "%d小时" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dm" +msgstr "%d分钟" + +#: src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%ds" +msgstr "%d秒" + +#: src/settings/UI.vala:153 +msgctxt "grid_size_preset" +msgid "Steam" +msgstr "Steam" + +#: src/settings/UI.vala:154 +msgctxt "grid_size_preset" +msgid "Steam (vertical)" +msgstr "Steam (垂直)" + +#: src/settings/UI.vala:155 +msgctxt "grid_size_preset" +msgid "GOG" +msgstr "GOG" + +#: src/settings/UI.vala:156 +msgctxt "grid_size_preset" +msgid "GOG (vertical)" +msgstr "GOG (垂直)" + +#: src/settings/UI.vala:157 +msgctxt "grid_size_preset" +msgid "Square" +msgstr "队列" + +#: src/settings/UI.vala:158 +msgctxt "grid_size_preset" +msgid "Custom" +msgstr "自定义" + +#: src/utils/downloader/Downloader.vala:200 +msgctxt "dl_status" +msgid "Queued" +msgstr "在队列中" + +#: src/utils/downloader/Downloader.vala:201 +msgctxt "dl_status" +msgid "Starting download" +msgstr "正在开始下载" + +#: src/utils/downloader/Downloader.vala:202 +msgctxt "dl_status" +msgid "Download started" +msgstr "已开始下载" + +#: src/utils/downloader/Downloader.vala:203 +msgctxt "dl_status" +msgid "Download finished" +msgstr "下载完成" + +#: src/utils/downloader/Downloader.vala:204 +msgctxt "dl_status" +msgid "Download failed" +msgstr "下载失败" + +#: src/utils/downloader/Downloader.vala:208 +#, c-format +msgctxt "dl_status" +msgid "Downloading: %s" +msgstr "正在下载: %s" + +#: src/utils/downloader/Downloader.vala:210 +msgctxt "dl_status" +msgid "Downloading" +msgstr "正在下载" + +#: src/utils/downloader/Downloader.vala:214 +#, c-format +msgctxt "dl_status" +msgid "Paused: %s" +msgstr "已暂停: %s" + +#: src/utils/downloader/Downloader.vala:216 +msgctxt "dl_status" +msgid "Paused" +msgstr "暂停下载" + +#: src/utils/downloader/Downloader.vala:218 +msgctxt "dl_status" +msgid "Download cancelled" +msgstr "下载已取消" + +#. TRANSLATORS: Download progress template. %1$d - percentage, %2$s / %3$s - downloaded portion and total file size, %4$s - download speed +#: src/utils/downloader/Downloader.vala:262 +#, fuzzy, c-format +msgctxt "dl_status" +msgid "%1$d%% (%2$s / %3$s) [%4$s/s]" +msgstr "正在下载: %1$d%% (%2$s / %3$s) [%4$s/s]" + +#~ msgid "Disable esync" +#~ msgstr "禁止esync" + +#~ msgid "Force LARGE_ADDRESS_AWARE flag" +#~ msgstr "强制使用LARGE_ADDRESS_AWARE" + +#~ msgid "Disable DirectX 11 compatibility layer" +#~ msgstr "禁用 DirectX 11 兼容性层" + +#~ msgid "Use WineD3D11 as DirectX 11 compatibility layer" +#~ msgstr "使用 WineD3D11 作为 DirectX 11 兼容性层" + +#~ msgid "Show DXVK info overlay" +#~ msgstr "显示 DXVK 信息叠加" + +#~ msgid "Enable DirectX 9 compatibility layer" +#~ msgstr "禁用 DirectX 9兼容性层" + +#~ msgid "Silent installation" +#~ msgstr "静默安装" + +#~ msgid "Very silent installation" +#~ msgstr "非常静默的安装" + +#~ msgid "Suppress messages" +#~ msgstr "禁止显示消息" + +#~ msgid "No GUI" +#~ msgstr "没有 GUI" diff --git a/po/zh_HK.po b/po/zh_HK.po new file mode 100644 index 00000000..095f7592 --- /dev/null +++ b/po/zh_HK.po @@ -0,0 +1,1923 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the com.github.tkashkin.gamehub package. +# wenxiaobai , 2019. +# Anatoliy Kashkin , 2019. +# Elizabeth Sherrock , 2019. +# tofuHero , 2019. +# Allan Nordhøy , 2020. +msgid "" +msgstr "" +"Project-Id-Version: com.github.tkashkin.gamehub\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-26 06:40+0300\n" +"PO-Revision-Date: 2020-04-04 07:44+0000\n" +"Last-Translator: Allan Nordhøy \n" +"Language-Team: Chinese (Traditional, Hong Kong) \n" +"Language: zh_HK\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 4.0-dev\n" + +#: src/app.vala:91 +msgid "Show help" +msgstr "显示帮助" + +#: src/app.vala:92 +msgid "Show application version and exit" +msgstr "显示版本并退出" + +#: src/app.vala:93 +msgid "Restart with GDB debugger attached" +msgstr "重新启动附加的GDB调试器" + +#: src/app.vala:94 +msgid "Show full GDB backtrace" +msgstr "显示完整的GDB回溯" + +#: src/app.vala:95 +msgid "Treat fatal errors as criticals and crash application" +msgstr "将致命错误视为关键和崩溃应用程序" + +#: src/app.vala:99 +msgid "Show main window" +msgstr "显示主窗口" + +#: src/app.vala:100 +msgid "Show application settings dialog" +msgstr "显示应用设置对话框" + +#: src/app.vala:101 +msgid "Show about dialog" +msgstr "显示对话框" + +#: src/app.vala:102 +msgid "Maximum number of background worker threads" +msgstr "最大后台工作线程数" + +#: src/app.vala:106 +msgid "Run game" +msgstr "运行游戏" + +#: src/app.vala:107 +msgid "Show compatibility options dialog" +msgstr "显示兼容性选项对话框" + +#: src/app.vala:108 +msgid "Open game details" +msgstr "打开游戏细节" + +#: src/app.vala:109 +msgid "Open game properties" +msgstr "打开游戏属性" + +#: src/app.vala:113 +msgid "Enable debug logging" +msgstr "启用调试日志记录" + +#: src/app.vala:114 +msgid "" +"Log authentication process and sensitive information like authentication " +"tokens" +msgstr "记录身份验证过程和敏感信息,如身份验证令牌" + +#: src/app.vala:115 +msgid "Log download manager" +msgstr "日志管理器" + +#: src/app.vala:116 +msgid "Log background workers start/stop" +msgstr "日志后台工作开始/停止" + +#: src/app.vala:117 +msgid "Disable log messages filtering" +msgstr "关闭日志信息过滤" + +#: src/app.vala:118 +msgid "Verbose logging" +msgstr "详细记录" + +#: src/app.vala:247 +msgid "Game Options:" +msgstr "游戏选项:" + +#: src/app.vala:247 +msgid "Show game options help" +msgstr "显示游戏选项帮助" + +#: src/app.vala:255 +msgid "Logging Options:" +msgstr "记录选项:" + +#: src/app.vala:255 +msgid "Show logging options help" +msgstr "显示日志选项帮助" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +msgid "Select executable" +msgstr "选择可执行文件" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:181 src/ui/views/GamesView/GamesView.vala:330 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select" +msgstr "选择" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:180 src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Cancel" +msgstr "取消" + +#: src/data/Runnable.vala:166 src/ui/widgets/FileChooserEntry.vala:49 +msgid "Select directory" +msgstr "选择目录" + +#: src/data/Runnable.vala:619 +#, c-format +msgid "Part %1$u of %2$u: %3$s" +msgstr "" + +#: src/data/Runnable.vala:642 src/ui/dialogs/CorruptedInstallerDialog.vala:48 +#, c-format +msgid "%s: corrupted installer" +msgstr "%s: 安装程序损坏" + +#: src/data/Runnable.vala:643 +#, c-format +msgid "Checksum mismatch in %s" +msgstr "校验和不匹配 %s" + +#: src/data/Runnable.vala:657 src/ui/dialogs/CorruptedInstallerDialog.vala:126 +msgid "Show file" +msgstr "显示文件" + +#: src/data/Runnable.vala:658 src/ui/dialogs/CorruptedInstallerDialog.vala:132 +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#: src/ui/widgets/TagRow.vala:146 +msgid "Remove" +msgstr "删除" + +#: src/data/Runnable.vala:659 src/ui/dialogs/CorruptedInstallerDialog.vala:128 +msgid "Backup" +msgstr "备份" + +#: src/data/Runnable.vala:778 +#, c-format +msgid "%s: cannot detect main executable" +msgstr "%s: 无法检测主可执行文件" + +#: src/data/Runnable.vala:779 +msgid "" +"Main executable file for this game cannot be detected automatically.\n" +"Please set main executable in game's properties." +msgstr "" +"无法自动检测此游戏的主要可执行文件。\n" +"请在游戏属性中设置主要可执行文件。" + +#: src/data/Runnable.vala:908 +msgctxt "platform" +msgid "Emulated" +msgstr "模拟器" + +#: src/data/Game.vala:625 +msgctxt "status" +msgid "Running" +msgstr "正在运行" + +#: src/data/Game.vala:628 +msgctxt "status" +msgid "Installed" +msgstr "安装" + +#: src/data/Game.vala:629 +msgctxt "status" +msgid "Installing" +msgstr "安装" + +#: src/data/Game.vala:630 +msgctxt "status" +msgid "Verifying installer integrity" +msgstr "验证安装程序完整性" + +#: src/data/Game.vala:631 +msgctxt "status" +msgid "Download started" +msgstr "下载已开始" + +#: src/data/Game.vala:633 +msgctxt "status" +msgid "Not installed" +msgstr "未安装" + +#: src/data/Game.vala:643 +msgctxt "status_header" +msgid "Installed" +msgstr "安装" + +#: src/data/Game.vala:644 +msgctxt "status_header" +msgid "Installing" +msgstr "安装" + +#: src/data/Game.vala:646 +msgctxt "status_header" +msgid "Downloading" +msgstr "正在下载" + +#: src/data/Game.vala:648 +msgctxt "status_header" +msgid "Not installed" +msgstr "未安装" + +#: src/data/GameSource.vala:31 +#, c-format +msgid "%s games" +msgstr "%s 游戏" + +#: src/data/sources/steam/Steam.vala:43 +msgid "Your SteamID will be read from Steam configuration file" +msgstr "您的SteamID将从Steam配置文件中读取" + +#: src/data/sources/steam/Steam.vala:46 +msgid "" +"Steam config file not found.\n" +"Login into your account in Steam client and return to GameHub" +msgstr "" +"找不到Steam配置文件。\n" +"在Steam客户端登录您的帐户并返回GameHub" + +#: src/data/sources/gog/GOGGame.vala:983 +#, c-format +msgid "DLC: %s" +msgstr "" + +#: src/data/sources/humble/HumbleGame.vala:343 +#, c-format +msgid "%s: no available installers" +msgstr "%s: 没有可用的安装程序" + +#: src/data/sources/humble/HumbleGame.vala:344 +msgid "" +"Cannot get Trove download URL.\n" +"Make sure your Humble Monthly subscription is active." +msgstr "" +"无法获取Trove下载URL。\n" +"确保您的Humble Monthly订阅处于活动状态。" + +#: src/data/sources/itch/ItchDownloader.vala:192 +#, c-format +msgctxt "itch_dl_status" +msgid "%s left;" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:195 +#, c-format +msgctxt "itch_dl_status" +msgid "%d%%" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:198 +#, c-format +msgctxt "itch_dl_status" +msgid "(%1$s / %2$s)" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:201 +#, c-format +msgctxt "itch_dl_status" +msgid "[%s/s]" +msgstr "" + +#: src/data/sources/user/User.vala:30 +msgid "User games" +msgstr "用户游戏" + +#: src/data/db/tables/Tags.vala:225 +msgctxt "tag" +msgid "Favorites" +msgstr "收藏夹" + +#: src/data/db/tables/Tags.vala:226 +msgctxt "tag" +msgid "Not installed" +msgstr "未安装" + +#: src/data/db/tables/Tags.vala:227 +msgctxt "tag" +msgid "Installed" +msgstr "安装" + +#: src/data/db/tables/Tags.vala:228 +msgctxt "tag" +msgid "Hidden" +msgstr "隐藏的" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit script" +msgstr "编辑脚本" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit custom script" +msgstr "编辑自定义脚本" + +#: src/data/compat/Innoextract.vala:55 +#, c-format +msgid "" +"Innoextract %1$s is not supported and may not be able to extract some " +"games correctly.\n" +"Install innoextract %2$s or newer." +msgstr "" +"Innoextract %1$s 不受支持,可能无法正确提取某些游戏。\n" +"安装innoextract %2$s 或更新版本。" + +#: src/data/compat/WineWrap.vala:61 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:242 +#: src/ui/dialogs/CompatRunDialog.vala:102 +#: src/ui/views/GamesView/GameContextMenu.vala:53 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:234 +msgid "Run" +msgstr "运行" + +#: src/data/compat/WineWrap.vala:64 +msgid "Show WineWrap menu" +msgstr "显示WineWrap菜单" + +#: src/data/compat/WineWrap.vala:67 src/data/compat/Proton.vala:122 +#: src/data/compat/Wine.vala:83 +msgid "Kill apps in prefix" +msgstr "终止前缀中的应用程序" + +#: src/data/compat/Proton.vala:47 +msgid "Proton prefix" +msgstr "Proton 前缀" + +#: src/data/compat/Proton.vala:110 src/data/compat/Wine.vala:71 +msgid "Open prefix directory" +msgstr "打开前缀目录" + +#: src/data/compat/Proton.vala:113 src/data/compat/Wine.vala:74 +msgid "Run winecfg" +msgstr "运行winecfg" + +#: src/data/compat/Proton.vala:116 src/data/compat/Wine.vala:77 +msgid "Run winetricks" +msgstr "运行winetricks" + +#: src/data/compat/Proton.vala:119 src/data/compat/Wine.vala:80 +msgid "Run taskmgr" +msgstr "运行任务管理器" + +#: src/data/compat/Wine.vala:53 +#, fuzzy +msgid "Wine prefix" +msgstr "终止前缀中的应用程序" + +#: src/data/compat/Wine.vala:55 +msgid "Environment variables" +msgstr "环境变量" + +#: src/data/compat/Wine.vala:60 +msgid "InnoSetup default options" +msgstr "InnoSetup默认选项" + +#: src/data/compat/RetroArch.vala:53 +#, fuzzy +msgid "Libretro core file" +msgstr "打开前缀目录" + +#: src/data/compat/CustomEmulator.vala:43 +msgid "Custom emulator" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:48 +msgid "Emulator" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:49 +#, fuzzy +msgid "Launch in game directory" +msgstr "选择目录" + +#: src/data/adapters/GamesAdapter.vala:440 +msgctxt "status_header" +msgid "Favorites" +msgstr "收藏夹" + +#: src/data/adapters/GamesAdapter.vala:445 +#, fuzzy, c-format +msgctxt "status_header" +msgid "%s: Favorites" +msgstr "收藏夹" + +#: src/data/adapters/GamesAdapter.vala:491 +msgid "Merging games" +msgstr "合并游戏" + +#: src/data/adapters/GamesAdapter.vala:504 +#, c-format +msgid "Merging games from %s" +msgstr "正在合并来自%s的游戏" + +#: src/data/adapters/GamesAdapter.vala:551 +#, c-format +msgid "Loading games from %s" +msgstr "正在从%s加载游戏" + +#: src/data/adapters/GamesAdapter.vala:678 +msgctxt "sort_mode" +msgid "By name" +msgstr "游戏名" + +#: src/data/adapters/GamesAdapter.vala:679 +msgctxt "sort_mode" +msgid "By last launch" +msgstr "最后一次运行" + +#: src/data/adapters/GamesAdapter.vala:680 +msgctxt "sort_mode" +msgid "By playtime" +msgstr "游戏时间" + +#: src/data/adapters/GamesAdapter.vala:705 +msgctxt "group_mode" +msgid "Do not group" +msgstr "不分组" + +#: src/data/adapters/GamesAdapter.vala:706 +msgctxt "group_mode" +msgid "By status" +msgstr "按状态" + +#: src/data/adapters/GamesAdapter.vala:707 +msgctxt "group_mode" +msgid "By source" +msgstr "按来源" + +#: src/data/providers/images/SteamGridDB.vala:151 +#: src/data/providers/data/IGDB.vala:431 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:217 +msgid "Default" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:158 +#: src/data/providers/data/IGDB.vala:438 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:225 +msgid "Restore default API key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:169 +#: src/data/providers/data/IGDB.vala:449 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:108 +msgid "API key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:177 +#: src/data/providers/data/IGDB.vala:457 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:53 +msgid "Generate key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:208 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Style" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:209 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Score" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:213 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Author" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:225 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Alternate" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:226 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Blurred" +msgstr "" + +#. TRANSLATORS: Flat / Material Design image style. Probably should not be translated +#: src/data/providers/images/SteamGridDB.vala:228 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Material" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:229 +msgctxt "imagesource_steamgriddb_image_style" +msgid "No logo" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:230 +msgctxt "imagesource_steamgriddb_image_style" +msgid "White logo" +msgstr "" + +#: src/data/providers/data/IGDB.vala:147 +msgid "" +"Monthly IGDB request quota has been reached. Set your own API key to use " +"IGDB data or disable IGDB." +msgstr "" + +#: src/data/providers/data/IGDB.vala:148 +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:40 +#: src/ui/views/WelcomeView.vala:53 src/ui/views/WelcomeView.vala:78 +#: src/ui/views/GamesView/GamesView.vala:230 +#: src/ui/views/GamesView/GamesView.vala:629 +msgid "Settings" +msgstr "设置" + +#: src/data/providers/data/IGDB.vala:356 +msgctxt "igdb_related_link" +msgid "Official website" +msgstr "" + +#: src/data/providers/data/IGDB.vala:469 +msgctxt "igdb_preferred_description" +msgid "When game has description, show description" +msgstr "" + +#: src/data/providers/data/IGDB.vala:476 +#, fuzzy +msgctxt "igdb_preferred_description" +msgid "of game" +msgstr "运行游戏" + +#: src/data/providers/data/IGDB.vala:477 +msgctxt "igdb_preferred_description" +msgid "from IGDB" +msgstr "从IGDB" + +#: src/data/providers/data/IGDB.vala:478 +msgctxt "igdb_preferred_description" +msgid "both" +msgstr "都" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:65 +msgid "Some settings will be applied after application restart" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:71 +msgid "Games directory contains space. It may cause problems for some games" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:36 +msgid "Interface" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:37 +msgid "Appearance" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:38 +msgid "General interface settings" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:48 +msgid "Dark theme" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:53 +msgctxt "icon_style" +msgid "Theme-based" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:54 +msgctxt "icon_style" +msgid "Symbolic" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:55 +msgctxt "icon_style" +msgid "Colored" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:57 +msgctxt "icon_style" +msgid "Icon style" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:84 +#, fuzzy +msgid "Game card" +msgstr "游戏的名字" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:86 +#, fuzzy +msgid "Show platform icons" +msgstr "显示文件" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:99 +msgctxt "grid_size" +msgid "Card size" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:117 +msgctxt "grid_size_preset" +msgid "Presets" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:139 +#, fuzzy +msgid "Games list: installed" +msgstr "%s: 没有可用的安装程序" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:140 +#, fuzzy +msgid "Games list: not installed" +msgstr "%s: 没有可用的安装程序" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:142 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:146 +#, fuzzy +msgctxt "list_style" +msgid "Show icon" +msgstr "显示文件" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:143 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:147 +msgctxt "list_style" +msgid "Bold title" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:144 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:148 +msgctxt "list_style" +msgid "Show status" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:149 +msgctxt "list_style" +msgid "Dim" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:151 +#, fuzzy +msgid "Grid options" +msgstr "游戏选项:" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:152 +#, fuzzy +msgid "List options" +msgstr "记录选项:" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:31 +msgid "Behavior" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:32 +msgid "Behavior settings" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:42 +msgid "Run games with double click" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:46 +#, fuzzy +msgid "Merge games from different sources" +msgstr "正在合并来自%s的游戏" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:50 +msgid "Use imported tags" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:51 +msgid "General" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:52 +#, fuzzy +msgid "Collection" +msgstr "选择目录" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:53 +msgid "Empty" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:65 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:85 +#, fuzzy +msgid "Collection directory" +msgstr "选择目录" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:70 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:78 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:87 +#, fuzzy +msgid "Game directory" +msgstr "选择目录" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:71 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:79 +#, fuzzy +msgid "Installers" +msgstr "安装" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:72 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:98 +#, fuzzy +msgid "DLC" +msgstr "DLC" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:73 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:197 +msgid "Bonus content" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:84 +msgid "Variable syntax: $var or ${var}" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:86 +msgid "Game name" +msgstr "游戏的名字" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:88 +#: src/ui/views/GamesView/FiltersPopover.vala:127 +msgid "Platform" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:36 +#, fuzzy +msgid "Controller" +msgstr "安装" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +msgid "Enabled" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:53 +msgid "Focus GameHub window with Guide button" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:57 +#, fuzzy +msgid "Controllers" +msgstr "安装" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:89 +msgid "Move focus" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:91 +msgid "Exit" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:40 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:108 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:92 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:95 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:36 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:77 +msgid "Disabled" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:47 +#: src/ui/dialogs/GameTweaksDialog.vala:53 +#: src/ui/views/GamesView/GameContextMenu.vala:183 +msgid "Tweaks" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:34 +msgid "Tweak launch options and apply them to games automatically" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:79 +msgid "" +"Tweaks are loaded from following directories in order\n" +"Last tweak overrides previous tweaks with same identifiers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:83 +msgid "Click to open" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:93 +#, c-format +msgid "Tweaks are loaded from %1$s and %2$d more directories (?)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:38 +#, fuzzy +msgid "Game sources" +msgstr "打开游戏属性" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +msgid "Steam API keys have limited number of uses per day" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:63 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:57 +#, fuzzy +msgid "Installation directory" +msgstr "选择目录" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:176 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:81 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:34 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:75 +#, fuzzy +msgid "Not installed" +msgstr "未安装" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:116 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:96 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:99 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:85 +#, fuzzy +msgid "Not authenticated" +msgstr "未安装" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +#, c-format +msgid "Authenticated as %s" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:103 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +msgid "Authenticated" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:183 +#: src/ui/dialogs/InstallDialog.vala:53 src/ui/dialogs/InstallDialog.vala:111 +#: src/ui/views/GamesView/GameContextMenu.vala:80 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:233 +#: src/ui/widgets/TweaksList.vala:95 +#, fuzzy +msgid "Install" +msgstr "安装" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:236 +msgid "Steam API key" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:50 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:54 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:48 +#, fuzzy +msgid "Games directory" +msgstr "选择目录" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:63 +msgid "Logout" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:50 +#, fuzzy +msgid "Load games from Humble Trove" +msgstr "正在从%s加载游戏" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:45 +msgid "Emulators" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:45 +#, fuzzy +msgid "Libretro core directory" +msgstr "打开前缀目录" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:46 +#, fuzzy +msgid "Libretro core info directory" +msgstr "打开前缀目录" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:50 +msgid "Ignored libretro cores" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:54 +msgid "Ignored game file extensions" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:66 +msgid "No cores found" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:70 +#, c-format +msgid "%u core found" +msgid_plural "%u cores found" +msgstr[0] "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:46 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:168 +msgid "No custom emulators" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:164 +#, c-format +msgid "%u custom emulator" +msgid_plural "%u custom emulators" +msgstr[0] "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:237 +msgid "Save" +msgstr "保存" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:250 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:312 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/dialogs/GamePropertiesDialog.vala:168 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +#: src/ui/views/GamesView/AddGamePopover.vala:67 +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +#, fuzzy +msgid "Executable" +msgstr "选择可执行文件" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:251 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/views/GamesView/AddGamePopover.vala:68 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +#, fuzzy +msgid "Installer" +msgstr "安装" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:256 +#: src/ui/dialogs/GamePropertiesDialog.vala:64 +#: src/ui/dialogs/GamePropertiesDialog.vala:69 +#: src/ui/views/GamesView/AddGamePopover.vala:73 +msgid "Name" +msgstr "名字" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:272 +#: src/ui/dialogs/GamePropertiesDialog.vala:201 +#: src/ui/views/GamesView/AddGamePopover.vala:78 +#, fuzzy +msgid "Arguments" +msgstr "游戏的名字" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:276 +msgid "Variables" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:277 +#, fuzzy +msgid "Game executable" +msgstr "选择可执行文件" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:278 +#, fuzzy +msgid "Game arguments" +msgstr "游戏的名字" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:80 +#: src/ui/views/GamesView/AddGamePopover.vala:82 +#, fuzzy +msgid "Directory" +msgstr "选择目录" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#, fuzzy +msgid "Select emulator directory" +msgstr "选择目录" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:292 +#: src/ui/dialogs/GamePropertiesDialog.vala:219 +#, fuzzy +msgid "Force compatibility mode" +msgstr "显示兼容性选项对话框" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:307 +#, fuzzy +msgid "Game file patterns" +msgstr "选择可执行文件" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:315 +msgid "Image" +msgstr "图片" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:318 +msgid "Icon" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:325 +msgid "" +"findutils-compatible glob patterns\n" +"\n" +" Multiple patterns can be separated with |\n" +" Start pattern with ./ to match relative path\n" +" $basename variable will be replaced with game's executable " +"name (without extension)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:38 +msgid "Data" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:39 +msgid "Providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:40 +msgid "Third-party data providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:55 +#, fuzzy +msgid "Image providers" +msgstr "打开游戏属性" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:68 +msgid "Metadata providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:137 +msgid "Open website" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:36 +msgid "About" +msgstr "关于" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:71 +#, fuzzy +msgid "Copy application version and environment info" +msgstr "显示版本并退出" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:78 +#: src/ui/views/WelcomeView.vala:57 +msgid "All your games in one place" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:92 +msgctxt "about_link" +msgid "Website" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:96 +msgctxt "about_link" +msgid "Source code on GitHub" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:103 +msgctxt "about_link" +msgid "Report a problem" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:104 +#, fuzzy +msgctxt "about_link" +msgid "Suggest translations" +msgstr "静默安装" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:110 +msgctxt "about_link" +msgid "Issues" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:111 +msgctxt "about_link" +msgid "Contributors" +msgstr "" + +#. TRANSLATORS: Likely it should not be translated. GitHub Pulse is a page that shows recent repository activity: https://github.com/tkashkin/GameHub/pulse +#: src/ui/dialogs/SettingsDialog/pages/About.vala:114 +msgctxt "about_link" +msgid "Pulse" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:115 +msgctxt "about_link" +msgid "Forks" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:109 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:129 +msgid "Import" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:110 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:153 +msgid "Download" +msgstr "下载" + +#: src/ui/dialogs/InstallDialog.vala:207 +#, fuzzy +msgid "Select installer" +msgstr "选择" + +#: src/ui/dialogs/InstallDialog.vala:216 +#, fuzzy, c-format +msgid "Installer size: %s" +msgstr "安装" + +#: src/ui/dialogs/InstallDialog.vala:348 +msgid "Unknown" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:49 +#, fuzzy, c-format +msgid "%s: Properties" +msgstr "收藏夹" + +#: src/ui/dialogs/GamePropertiesDialog.vala:84 +msgid "Images" +msgstr "图片" + +#: src/ui/dialogs/GamePropertiesDialog.vala:126 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:160 +#: src/ui/views/GameDetailsView/blocks/Artwork.vala:62 +msgid "Download images" +msgstr "下载图片" + +#: src/ui/dialogs/GamePropertiesDialog.vala:144 +msgid "Image URL" +msgstr "图片的URL" + +#: src/ui/dialogs/GamePropertiesDialog.vala:148 +msgid "Vertical image URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:157 +msgid "Icon URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +#, fuzzy +msgid "Select working directory" +msgstr "选择目录" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +#, fuzzy +msgid "Working directory" +msgstr "打开前缀目录" + +#: src/ui/dialogs/GamePropertiesDialog.vala:214 +#, fuzzy +msgid "Compatibility" +msgstr "禁用DirectX 11兼容层" + +#: src/ui/dialogs/GamePropertiesDialog.vala:236 +msgid "Launch from terminal" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:252 +msgid "Copy to clipboard" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:254 +#, fuzzy +msgid "Add to Steam" +msgstr "加游戏" + +#: src/ui/dialogs/GamePropertiesDialog.vala:255 +#, fuzzy +msgid "Add to the Steam library" +msgstr "加游戏" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:53 +#, c-format +msgid "%s: Overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "Overlays are disabled" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "" +"Enable overlays to manage DLCs and mods\n" +"\n" +"Enabling will move game to the “base“ overlay" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:77 +#: src/ui/views/GamesView/GameContextMenu.vala:175 +#, fuzzy +msgid "Overlays" +msgstr "删除" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:105 +msgid "Overlay ID (directory name)" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:110 +msgid "Overlay name (optional)" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:112 +msgid "Add" +msgstr "加" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:127 +#, fuzzy +msgid "Enable overlays" +msgstr "删除" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:182 +#, c-format +msgid "" +"Overlay usage at this path may be unsafe\n" +"Proceed at your own risk\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:187 +#, c-format +msgid "" +"Overlay usage at this path is not supported\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:266 +#, fuzzy +msgid "Open directory" +msgstr "打开前缀目录" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:271 +#, fuzzy +msgid "Remove overlay" +msgstr "删除" + +#: src/ui/dialogs/CompatRunDialog.vala:48 +#: src/ui/views/GamesView/GameContextMenu.vala:46 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:235 +#, fuzzy +msgid "Run with compatibility layer" +msgstr "禁用DirectX 11兼容层" + +#: src/ui/dialogs/CorruptedInstallerDialog.vala:71 +#, fuzzy +msgid "Corrupted installer: checksum mismatch in" +msgstr "校验和不匹配 %s" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:57 +#: src/ui/views/GamesView/AddGamePopover.vala:105 +#, fuzzy +msgid "Import emulated games" +msgstr "选择目录" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:75 +#, fuzzy +msgid "Select directory with emulated games" +msgstr "选择目录" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:83 +#, fuzzy +msgid "Detected games" +msgstr "选择目录" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:107 +#, fuzzy +msgid "Select all" +msgstr "选择" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:115 +#, fuzzy +msgid "Select directory to import" +msgstr "选择目录" + +#: src/ui/dialogs/GameTweaksDialog.vala:40 +#, c-format +msgid "%s: Tweaks" +msgstr "" + +#: src/ui/views/WelcomeView.vala:52 +#, fuzzy +msgid "No enabled game sources" +msgstr "用户游戏" + +#: src/ui/views/WelcomeView.vala:52 +msgid "Enable some game sources in settings" +msgstr "" + +#: src/ui/views/WelcomeView.vala:57 +msgid "Let's get started" +msgstr "" + +#: src/ui/views/WelcomeView.vala:71 +msgid "Skip" +msgstr "" + +#: src/ui/views/WelcomeView.vala:141 +msgid "Ready" +msgstr "" + +#: src/ui/views/WelcomeView.vala:147 +msgid "Authentication required" +msgstr "" + +#: src/ui/views/WelcomeView.vala:152 +msgid "Authenticating…" +msgstr "" + +#: src/ui/views/WelcomeView.vala:163 +#, fuzzy, c-format +msgid "Install %s" +msgstr "安装" + +#: src/ui/views/WelcomeView.vala:164 +msgid "Return to GameHub after installing" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:136 +#, fuzzy +msgid "No games" +msgstr "运行游戏" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "Get some games or enable some game sources in settings" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:150 +msgid "Grid view" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:151 +msgid "List view" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:159 +#, fuzzy +msgid "All games" +msgstr "%s 游戏" + +#: src/ui/views/GamesView/GamesView.vala:182 +#, fuzzy +msgid "Downloads" +msgstr "下载" + +#: src/ui/views/GamesView/GamesView.vala:208 +msgid "Filters" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:216 +#: src/ui/views/GamesView/AddGamePopover.vala:84 +msgid "Add game" +msgstr "加游戏" + +#: src/ui/views/GamesView/GamesView.vala:223 +msgid "Search" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:328 +msgid "Menu" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:329 +#: src/ui/views/GameDetailsView/GameDetailsView.vala:104 +#, fuzzy +msgid "Back" +msgstr "备份" + +#: src/ui/views/GamesView/GamesView.vala:550 +#, c-format +msgid "%u game" +msgid_plural "%u games" +msgstr[0] "%u个游戏" + +#: src/ui/views/GamesView/GamesView.vala:553 +#, c-format +msgctxt "games_view_subtitle_filtered_games" +msgid "%1$u / %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:557 +#, c-format +msgctxt "games_view_subtitle" +msgid "%1$s: %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:568 +#, fuzzy +msgid "No user-added games" +msgstr "用户游戏" + +#: src/ui/views/GamesView/GamesView.vala:569 +msgid "Add some games using plus button" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:573 +#, fuzzy, c-format +msgid "No %s games" +msgstr "%s 游戏" + +#: src/ui/views/GamesView/GamesView.vala:574 +msgid "Get some Linux-compatible games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:584 +#, c-format +msgid "No games matching “%s”" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:589 +#, c-format +msgid "No %1$s games matching “%2$s”" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:627 +msgid "" +"No games were loaded from Steam. Set your games list privacy to public or " +"use your own Steam API key in settings." +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:628 +msgid "Privacy" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:739 +msgid "Downloading images" +msgstr "还在下载图片" + +#: src/ui/views/GamesView/GamesView.vala:753 +#, c-format +msgid "Downloading image: %s" +msgstr "还在下载图片:%s" + +#: src/ui/views/GamesView/DownloadProgressView.vala:131 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:162 +#, fuzzy +msgid "Pause download" +msgstr "开始下载" + +#: src/ui/views/GamesView/DownloadProgressView.vala:137 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:168 +#, fuzzy +msgid "Resume download" +msgstr "下载" + +#: src/ui/views/GamesView/DownloadProgressView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:174 +#, fuzzy +msgid "Cancel download" +msgstr "开始下载" + +#: src/ui/views/GamesView/FiltersPopover.vala:77 +msgid "Group" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:102 +msgid "Sort" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:234 +#: src/ui/widgets/GameTagsList.vala:58 +msgid "Tags" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:353 +#, fuzzy +msgid "All platforms" +msgstr "%s 游戏" + +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#, fuzzy +msgid "Select game executable" +msgstr "选择可执行文件" + +#: src/ui/views/GamesView/AddGamePopover.vala:82 +#, fuzzy +msgid "Select game directory" +msgstr "选择目录" + +#: src/ui/views/GamesView/AddGamePopover.vala:111 +msgid "Download game images" +msgstr "下载游戏的图片" + +#: src/ui/views/GamesView/GameContextMenu.vala:87 +msgid "Details" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:117 +#, fuzzy +msgctxt "game_context_menu" +msgid "Favorite" +msgstr "收藏夹" + +#: src/ui/views/GamesView/GameContextMenu.vala:121 +#, fuzzy +msgctxt "game_context_menu" +msgid "Hidden" +msgstr "隐藏的" + +#: src/ui/views/GamesView/GameContextMenu.vala:133 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:236 +#, fuzzy +msgid "Open installation directory" +msgstr "打开前缀目录" + +#: src/ui/views/GamesView/GameContextMenu.vala:142 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:237 +#, fuzzy +msgid "Open installers collection directory" +msgstr "打开前缀目录" + +#: src/ui/views/GamesView/GameContextMenu.vala:151 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:238 +#, fuzzy +msgid "Open bonus collection directory" +msgstr "打开前缀目录" + +#: src/ui/views/GamesView/GameContextMenu.vala:160 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:239 +#, fuzzy +msgid "Open screenshots directory" +msgstr "打开前缀目录" + +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#, fuzzy +msgid "Uninstall" +msgstr "安装" + +#: src/ui/views/GamesView/GameContextMenu.vala:192 +#, fuzzy +msgid "Properties" +msgstr "打开游戏属性" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:100 +#, fuzzy, c-format +msgid "%d game selected" +msgid_plural "%d games selected" +msgstr[0] "%s: 没有可用的安装程序" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:144 +#, fuzzy, c-format +msgid "%d game will be installed" +msgid_plural "%d games will be installed" +msgstr[0] "%s: 没有可用的安装程序" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:154 +#, fuzzy, c-format +msgid "%d game will be downloaded" +msgid_plural "%d games will be downloaded" +msgstr[0] "%s: 没有可用的安装程序" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:161 +#, fuzzy, c-format +msgid "Image for %d game will be searched" +msgid_plural "Images for %d games will be searched" +msgstr[0] "%s: 没有可用的安装程序" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:168 +#, fuzzy, c-format +msgid "%d game will be uninstalled" +msgid_plural "%d games will be uninstalled" +msgstr[0] "%s: 没有可用的安装程序" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:174 +msgid "Refresh" +msgstr "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:175 +#, c-format +msgid "" +"%d game will be removed from database. Restart GameHub to fetch new data" +msgid_plural "" +"%d games will be removed from database. Restart GameHub to fetch new data" +msgstr[0] "" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:240 +msgid "Open store page" +msgstr "" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:242 +#, fuzzy +msgid "Game properties" +msgstr "打开游戏属性" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:46 +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:60 +msgid "Playtime" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:52 +msgid "Playtime (local)" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:69 +msgid "Last launch" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:46 +msgid "Achievements" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:85 +#, c-format +msgid "Unlocked: %s" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:90 +#, c-format +msgid "Global percentage: %g%%" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:77 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:103 +msgid "Language" +msgstr "语言" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:80 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:106 +msgid "Languages" +msgstr "语言" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:147 +#, fuzzy, c-format +msgid "%u DLCs cannot be installed" +msgstr "%s: 安装程序损坏" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:71 +msgid "Category" +msgstr "类" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:74 +msgid "Categories" +msgstr "类" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:90 +msgid "Genre" +msgstr "类型" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:93 +msgid "Genres" +msgstr "类型" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:109 +msgctxt "igdb" +msgid "Popularity" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:115 +msgctxt "igdb" +msgid "Aggregated rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:116 +msgctxt "igdb" +msgid "IGDB user rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:117 +msgctxt "igdb" +msgid "Total rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:126 +msgctxt "igdb" +msgid "Release date" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:133 +#, fuzzy +msgctxt "igdb" +msgid "Platforms" +msgstr "%s 游戏" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:139 +msgctxt "igdb" +msgid "Genres" +msgstr "类型" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:145 +msgctxt "igdb" +msgid "Keywords" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:152 +msgctxt "igdb" +msgid "Links" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:208 +#, c-format +msgid "Based on %d rating" +msgid_plural "Based on %d ratings" +msgstr[0] "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:290 +msgctxt "igdb" +msgid "Summary" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:301 +msgctxt "igdb" +msgid "Storyline" +msgstr "" + +#: src/ui/widgets/FileChooserEntry.vala:49 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +#, fuzzy +msgid "Select file" +msgstr "选择" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +#, fuzzy +msgid "No images" +msgstr "下载图片" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "" +"There are no images found for this game\n" +"Make sure game name is correct" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:94 +#, fuzzy +msgid "Search images:" +msgstr "下载图片" + +#: src/ui/widgets/CompatToolPicker.vala:53 +#, fuzzy +msgid "Compatibility layer:" +msgstr "禁用DirectX 11兼容层" + +#: src/ui/widgets/CompatToolPicker.vala:92 +msgid "Configure" +msgstr "" + +#: src/ui/widgets/GameTagsList.vala:109 +#, fuzzy +msgid "Add tag" +msgstr "加游戏" + +#: src/ui/widgets/TweaksList.vala:86 +msgid "No description" +msgstr "" + +#: src/ui/widgets/TweaksList.vala:124 +#, fuzzy +msgid "Edit file" +msgstr "选择" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, fuzzy, c-format +msgctxt "time" +msgid "%dh" +msgstr "%d分" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dm" +msgstr "%d分" + +#: src/utils/Utils.vala:464 +#, fuzzy, c-format +msgctxt "time" +msgid "%ds" +msgstr "%d分" + +#: src/settings/UI.vala:153 +msgctxt "grid_size_preset" +msgid "Steam" +msgstr "" + +#: src/settings/UI.vala:154 +msgctxt "grid_size_preset" +msgid "Steam (vertical)" +msgstr "" + +#: src/settings/UI.vala:155 +msgctxt "grid_size_preset" +msgid "GOG" +msgstr "" + +#: src/settings/UI.vala:156 +msgctxt "grid_size_preset" +msgid "GOG (vertical)" +msgstr "" + +#: src/settings/UI.vala:157 +msgctxt "grid_size_preset" +msgid "Square" +msgstr "" + +#: src/settings/UI.vala:158 +msgctxt "grid_size_preset" +msgid "Custom" +msgstr "" + +#: src/utils/downloader/Downloader.vala:200 +msgctxt "dl_status" +msgid "Queued" +msgstr "" + +#: src/utils/downloader/Downloader.vala:201 +msgctxt "dl_status" +msgid "Starting download" +msgstr "开始下载" + +#: src/utils/downloader/Downloader.vala:202 +msgctxt "dl_status" +msgid "Download started" +msgstr "下载开始玩了" + +#: src/utils/downloader/Downloader.vala:203 +#, fuzzy +msgctxt "dl_status" +msgid "Download finished" +msgstr "下载开始玩了" + +#: src/utils/downloader/Downloader.vala:204 +#, fuzzy +msgctxt "dl_status" +msgid "Download failed" +msgstr "下载开始玩了" + +#: src/utils/downloader/Downloader.vala:208 +#, fuzzy, c-format +msgctxt "dl_status" +msgid "Downloading: %s" +msgstr "正在下载" + +#: src/utils/downloader/Downloader.vala:210 +#, fuzzy +msgctxt "dl_status" +msgid "Downloading" +msgstr "正在下载" + +#: src/utils/downloader/Downloader.vala:214 +#, c-format +msgctxt "dl_status" +msgid "Paused: %s" +msgstr "" + +#: src/utils/downloader/Downloader.vala:216 +#, fuzzy +msgctxt "dl_status" +msgid "Paused" +msgstr "开始下载" + +#: src/utils/downloader/Downloader.vala:218 +#, fuzzy +msgctxt "dl_status" +msgid "Download cancelled" +msgstr "下载开始玩了" + +#. TRANSLATORS: Download progress template. %1$d - percentage, %2$s / %3$s - downloaded portion and total file size, %4$s - download speed +#: src/utils/downloader/Downloader.vala:262 +#, c-format +msgctxt "dl_status" +msgid "%1$d%% (%2$s / %3$s) [%4$s/s]" +msgstr "" + +#, fuzzy +#~ msgid "Disable esync" +#~ msgstr "禁用esync" + +#~ msgid "Force LARGE_ADDRESS_AWARE flag" +#~ msgstr "强制使用 LARGE_ADDRESS_AWARE 标志" + +#~ msgid "Disable DirectX 11 compatibility layer" +#~ msgstr "禁用DirectX 11兼容层" + +#~ msgid "Use WineD3D11 as DirectX 11 compatibility layer" +#~ msgstr "使用wined3d11作为Directx11兼容层" + +#~ msgid "Show DXVK info overlay" +#~ msgstr "显示dxvk信息覆盖" + +#, fuzzy +#~ msgid "Enable DirectX 9 compatibility layer" +#~ msgstr "禁用DirectX 11兼容层" + +#~ msgid "Silent installation" +#~ msgstr "静默安装" + +#~ msgid "Very silent installation" +#~ msgstr "非常安静的安装" + +#~ msgid "Suppress messages" +#~ msgstr "禁止显示消息" + +#~ msgid "No GUI" +#~ msgstr "无图形用户界面" diff --git a/po/zh_TW.po b/po/zh_TW.po new file mode 100644 index 00000000..c34dc116 --- /dev/null +++ b/po/zh_TW.po @@ -0,0 +1,1923 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the com.github.tkashkin.gamehub package. +# wenxiaobai , 2019. +# Anatoliy Kashkin , 2019. +# Elizabeth Sherrock , 2019. +# tofuHero , 2019. +# Allan Nordhøy , 2020. +msgid "" +msgstr "" +"Project-Id-Version: com.github.tkashkin.gamehub\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-26 06:40+0300\n" +"PO-Revision-Date: 2020-04-04 07:44+0000\n" +"Last-Translator: Allan Nordhøy \n" +"Language-Team: Chinese (Traditional) \n" +"Language: zh_TW\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 4.0-dev\n" + +#: src/app.vala:91 +msgid "Show help" +msgstr "显示帮助" + +#: src/app.vala:92 +msgid "Show application version and exit" +msgstr "显示版本并退出" + +#: src/app.vala:93 +msgid "Restart with GDB debugger attached" +msgstr "重新启动附加的GDB调试器" + +#: src/app.vala:94 +msgid "Show full GDB backtrace" +msgstr "显示完整的GDB回溯" + +#: src/app.vala:95 +msgid "Treat fatal errors as criticals and crash application" +msgstr "将致命错误视为关键和崩溃应用程序" + +#: src/app.vala:99 +msgid "Show main window" +msgstr "显示主窗口" + +#: src/app.vala:100 +msgid "Show application settings dialog" +msgstr "显示应用设置对话框" + +#: src/app.vala:101 +msgid "Show about dialog" +msgstr "显示对话框" + +#: src/app.vala:102 +msgid "Maximum number of background worker threads" +msgstr "最大后台工作线程数" + +#: src/app.vala:106 +msgid "Run game" +msgstr "运行游戏" + +#: src/app.vala:107 +msgid "Show compatibility options dialog" +msgstr "显示兼容性选项对话框" + +#: src/app.vala:108 +msgid "Open game details" +msgstr "打开游戏细节" + +#: src/app.vala:109 +msgid "Open game properties" +msgstr "打开游戏属性" + +#: src/app.vala:113 +msgid "Enable debug logging" +msgstr "启用调试日志记录" + +#: src/app.vala:114 +msgid "" +"Log authentication process and sensitive information like authentication " +"tokens" +msgstr "记录身份验证过程和敏感信息,如身份验证令牌" + +#: src/app.vala:115 +msgid "Log download manager" +msgstr "日志管理器" + +#: src/app.vala:116 +msgid "Log background workers start/stop" +msgstr "日志后台工作开始/停止" + +#: src/app.vala:117 +msgid "Disable log messages filtering" +msgstr "关闭日志信息过滤" + +#: src/app.vala:118 +msgid "Verbose logging" +msgstr "详细记录" + +#: src/app.vala:247 +msgid "Game Options:" +msgstr "游戏选项:" + +#: src/app.vala:247 +msgid "Show game options help" +msgstr "显示游戏选项帮助" + +#: src/app.vala:255 +msgid "Logging Options:" +msgstr "记录选项:" + +#: src/app.vala:255 +msgid "Show logging options help" +msgstr "显示日志选项帮助" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +msgid "Select executable" +msgstr "选择可执行文件" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:181 src/ui/views/GamesView/GamesView.vala:330 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Select" +msgstr "选择" + +#: src/data/Runnable.vala:110 src/data/Runnable.vala:112 +#: src/data/Runnable.vala:180 src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +msgid "Cancel" +msgstr "取消" + +#: src/data/Runnable.vala:166 src/ui/widgets/FileChooserEntry.vala:49 +msgid "Select directory" +msgstr "选择目录" + +#: src/data/Runnable.vala:619 +#, c-format +msgid "Part %1$u of %2$u: %3$s" +msgstr "" + +#: src/data/Runnable.vala:642 src/ui/dialogs/CorruptedInstallerDialog.vala:48 +#, c-format +msgid "%s: corrupted installer" +msgstr "%s: 安装程序损坏" + +#: src/data/Runnable.vala:643 +#, c-format +msgid "Checksum mismatch in %s" +msgstr "校验和不匹配 %s" + +#: src/data/Runnable.vala:657 src/ui/dialogs/CorruptedInstallerDialog.vala:126 +msgid "Show file" +msgstr "显示文件" + +#: src/data/Runnable.vala:658 src/ui/dialogs/CorruptedInstallerDialog.vala:132 +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#: src/ui/widgets/TagRow.vala:146 +msgid "Remove" +msgstr "删除" + +#: src/data/Runnable.vala:659 src/ui/dialogs/CorruptedInstallerDialog.vala:128 +msgid "Backup" +msgstr "备份" + +#: src/data/Runnable.vala:778 +#, c-format +msgid "%s: cannot detect main executable" +msgstr "%s: 无法检测主可执行文件" + +#: src/data/Runnable.vala:779 +msgid "" +"Main executable file for this game cannot be detected automatically.\n" +"Please set main executable in game's properties." +msgstr "" +"无法自动检测此游戏的主要可执行文件。\n" +"请在游戏属性中设置主要可执行文件。" + +#: src/data/Runnable.vala:908 +msgctxt "platform" +msgid "Emulated" +msgstr "模拟器" + +#: src/data/Game.vala:625 +msgctxt "status" +msgid "Running" +msgstr "正在运行" + +#: src/data/Game.vala:628 +msgctxt "status" +msgid "Installed" +msgstr "安装" + +#: src/data/Game.vala:629 +msgctxt "status" +msgid "Installing" +msgstr "安装" + +#: src/data/Game.vala:630 +msgctxt "status" +msgid "Verifying installer integrity" +msgstr "验证安装程序完整性" + +#: src/data/Game.vala:631 +msgctxt "status" +msgid "Download started" +msgstr "下载已开始" + +#: src/data/Game.vala:633 +msgctxt "status" +msgid "Not installed" +msgstr "未安装" + +#: src/data/Game.vala:643 +msgctxt "status_header" +msgid "Installed" +msgstr "安装" + +#: src/data/Game.vala:644 +msgctxt "status_header" +msgid "Installing" +msgstr "安装" + +#: src/data/Game.vala:646 +msgctxt "status_header" +msgid "Downloading" +msgstr "正在下载" + +#: src/data/Game.vala:648 +msgctxt "status_header" +msgid "Not installed" +msgstr "未安装" + +#: src/data/GameSource.vala:31 +#, c-format +msgid "%s games" +msgstr "%s 游戏" + +#: src/data/sources/steam/Steam.vala:43 +msgid "Your SteamID will be read from Steam configuration file" +msgstr "您的SteamID将从Steam配置文件中读取" + +#: src/data/sources/steam/Steam.vala:46 +msgid "" +"Steam config file not found.\n" +"Login into your account in Steam client and return to GameHub" +msgstr "" +"找不到Steam配置文件。\n" +"在Steam客户端登录您的帐户并返回GameHub" + +#: src/data/sources/gog/GOGGame.vala:983 +#, c-format +msgid "DLC: %s" +msgstr "" + +#: src/data/sources/humble/HumbleGame.vala:343 +#, c-format +msgid "%s: no available installers" +msgstr "%s: 没有可用的安装程序" + +#: src/data/sources/humble/HumbleGame.vala:344 +msgid "" +"Cannot get Trove download URL.\n" +"Make sure your Humble Monthly subscription is active." +msgstr "" +"无法获取Trove下载URL。\n" +"确保您的Humble Monthly订阅处于活动状态。" + +#: src/data/sources/itch/ItchDownloader.vala:192 +#, c-format +msgctxt "itch_dl_status" +msgid "%s left;" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:195 +#, c-format +msgctxt "itch_dl_status" +msgid "%d%%" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:198 +#, c-format +msgctxt "itch_dl_status" +msgid "(%1$s / %2$s)" +msgstr "" + +#: src/data/sources/itch/ItchDownloader.vala:201 +#, c-format +msgctxt "itch_dl_status" +msgid "[%s/s]" +msgstr "" + +#: src/data/sources/user/User.vala:30 +msgid "User games" +msgstr "用户游戏" + +#: src/data/db/tables/Tags.vala:225 +msgctxt "tag" +msgid "Favorites" +msgstr "收藏夹" + +#: src/data/db/tables/Tags.vala:226 +msgctxt "tag" +msgid "Not installed" +msgstr "未安装" + +#: src/data/db/tables/Tags.vala:227 +msgctxt "tag" +msgid "Installed" +msgstr "安装" + +#: src/data/db/tables/Tags.vala:228 +msgctxt "tag" +msgid "Hidden" +msgstr "隐藏的" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit script" +msgstr "编辑脚本" + +#: src/data/compat/CustomScript.vala:60 +msgid "Edit custom script" +msgstr "编辑自定义脚本" + +#: src/data/compat/Innoextract.vala:55 +#, c-format +msgid "" +"Innoextract %1$s is not supported and may not be able to extract some " +"games correctly.\n" +"Install innoextract %2$s or newer." +msgstr "" +"Innoextract %1$s 不受支持,可能无法正确提取某些游戏。\n" +"安装innoextract %2$s 或更新版本。" + +#: src/data/compat/WineWrap.vala:61 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:242 +#: src/ui/dialogs/CompatRunDialog.vala:102 +#: src/ui/views/GamesView/GameContextMenu.vala:53 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:234 +msgid "Run" +msgstr "运行" + +#: src/data/compat/WineWrap.vala:64 +msgid "Show WineWrap menu" +msgstr "显示WineWrap菜单" + +#: src/data/compat/WineWrap.vala:67 src/data/compat/Proton.vala:122 +#: src/data/compat/Wine.vala:83 +msgid "Kill apps in prefix" +msgstr "终止前缀中的应用程序" + +#: src/data/compat/Proton.vala:47 +msgid "Proton prefix" +msgstr "Proton 前缀" + +#: src/data/compat/Proton.vala:110 src/data/compat/Wine.vala:71 +msgid "Open prefix directory" +msgstr "打开前缀目录" + +#: src/data/compat/Proton.vala:113 src/data/compat/Wine.vala:74 +msgid "Run winecfg" +msgstr "运行winecfg" + +#: src/data/compat/Proton.vala:116 src/data/compat/Wine.vala:77 +msgid "Run winetricks" +msgstr "运行winetricks" + +#: src/data/compat/Proton.vala:119 src/data/compat/Wine.vala:80 +msgid "Run taskmgr" +msgstr "运行任务管理器" + +#: src/data/compat/Wine.vala:53 +#, fuzzy +msgid "Wine prefix" +msgstr "终止前缀中的应用程序" + +#: src/data/compat/Wine.vala:55 +msgid "Environment variables" +msgstr "环境变量" + +#: src/data/compat/Wine.vala:60 +msgid "InnoSetup default options" +msgstr "InnoSetup默认选项" + +#: src/data/compat/RetroArch.vala:53 +#, fuzzy +msgid "Libretro core file" +msgstr "打开前缀目录" + +#: src/data/compat/CustomEmulator.vala:43 +msgid "Custom emulator" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:48 +msgid "Emulator" +msgstr "" + +#: src/data/compat/CustomEmulator.vala:49 +#, fuzzy +msgid "Launch in game directory" +msgstr "选择目录" + +#: src/data/adapters/GamesAdapter.vala:440 +msgctxt "status_header" +msgid "Favorites" +msgstr "收藏夹" + +#: src/data/adapters/GamesAdapter.vala:445 +#, fuzzy, c-format +msgctxt "status_header" +msgid "%s: Favorites" +msgstr "收藏夹" + +#: src/data/adapters/GamesAdapter.vala:491 +msgid "Merging games" +msgstr "合并游戏" + +#: src/data/adapters/GamesAdapter.vala:504 +#, c-format +msgid "Merging games from %s" +msgstr "正在合并来自%s的游戏" + +#: src/data/adapters/GamesAdapter.vala:551 +#, c-format +msgid "Loading games from %s" +msgstr "正在从%s加载游戏" + +#: src/data/adapters/GamesAdapter.vala:678 +msgctxt "sort_mode" +msgid "By name" +msgstr "游戏名" + +#: src/data/adapters/GamesAdapter.vala:679 +msgctxt "sort_mode" +msgid "By last launch" +msgstr "最后一次运行" + +#: src/data/adapters/GamesAdapter.vala:680 +msgctxt "sort_mode" +msgid "By playtime" +msgstr "游戏时间" + +#: src/data/adapters/GamesAdapter.vala:705 +msgctxt "group_mode" +msgid "Do not group" +msgstr "不分组" + +#: src/data/adapters/GamesAdapter.vala:706 +msgctxt "group_mode" +msgid "By status" +msgstr "按状态" + +#: src/data/adapters/GamesAdapter.vala:707 +msgctxt "group_mode" +msgid "By source" +msgstr "按来源" + +#: src/data/providers/images/SteamGridDB.vala:151 +#: src/data/providers/data/IGDB.vala:431 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:217 +msgid "Default" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:158 +#: src/data/providers/data/IGDB.vala:438 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:225 +msgid "Restore default API key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:169 +#: src/data/providers/data/IGDB.vala:449 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:108 +msgid "API key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:177 +#: src/data/providers/data/IGDB.vala:457 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:53 +msgid "Generate key" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:208 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Style" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:209 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Score" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:213 +msgctxt "imagesource_steamgriddb_image_property" +msgid "Author" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:225 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Alternate" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:226 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Blurred" +msgstr "" + +#. TRANSLATORS: Flat / Material Design image style. Probably should not be translated +#: src/data/providers/images/SteamGridDB.vala:228 +msgctxt "imagesource_steamgriddb_image_style" +msgid "Material" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:229 +msgctxt "imagesource_steamgriddb_image_style" +msgid "No logo" +msgstr "" + +#: src/data/providers/images/SteamGridDB.vala:230 +msgctxt "imagesource_steamgriddb_image_style" +msgid "White logo" +msgstr "" + +#: src/data/providers/data/IGDB.vala:147 +msgid "" +"Monthly IGDB request quota has been reached. Set your own API key to use " +"IGDB data or disable IGDB." +msgstr "" + +#: src/data/providers/data/IGDB.vala:148 +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:40 +#: src/ui/views/WelcomeView.vala:53 src/ui/views/WelcomeView.vala:78 +#: src/ui/views/GamesView/GamesView.vala:230 +#: src/ui/views/GamesView/GamesView.vala:629 +msgid "Settings" +msgstr "设置" + +#: src/data/providers/data/IGDB.vala:356 +msgctxt "igdb_related_link" +msgid "Official website" +msgstr "" + +#: src/data/providers/data/IGDB.vala:469 +msgctxt "igdb_preferred_description" +msgid "When game has description, show description" +msgstr "" + +#: src/data/providers/data/IGDB.vala:476 +#, fuzzy +msgctxt "igdb_preferred_description" +msgid "of game" +msgstr "运行游戏" + +#: src/data/providers/data/IGDB.vala:477 +msgctxt "igdb_preferred_description" +msgid "from IGDB" +msgstr "从IGDB" + +#: src/data/providers/data/IGDB.vala:478 +msgctxt "igdb_preferred_description" +msgid "both" +msgstr "都" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:65 +msgid "Some settings will be applied after application restart" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/SettingsDialog.vala:71 +msgid "Games directory contains space. It may cause problems for some games" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:36 +msgid "Interface" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:37 +msgid "Appearance" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:38 +msgid "General interface settings" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:48 +msgid "Dark theme" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:53 +msgctxt "icon_style" +msgid "Theme-based" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:54 +msgctxt "icon_style" +msgid "Symbolic" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:55 +msgctxt "icon_style" +msgid "Colored" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:57 +msgctxt "icon_style" +msgid "Icon style" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:84 +#, fuzzy +msgid "Game card" +msgstr "游戏的名字" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:86 +#, fuzzy +msgid "Show platform icons" +msgstr "显示文件" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:99 +msgctxt "grid_size" +msgid "Card size" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:117 +msgctxt "grid_size_preset" +msgid "Presets" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:139 +#, fuzzy +msgid "Games list: installed" +msgstr "%s: 没有可用的安装程序" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:140 +#, fuzzy +msgid "Games list: not installed" +msgstr "%s: 没有可用的安装程序" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:142 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:146 +#, fuzzy +msgctxt "list_style" +msgid "Show icon" +msgstr "显示文件" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:143 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:147 +msgctxt "list_style" +msgid "Bold title" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:144 +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:148 +msgctxt "list_style" +msgid "Show status" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:149 +msgctxt "list_style" +msgid "Dim" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:151 +#, fuzzy +msgid "Grid options" +msgstr "游戏选项:" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala:152 +#, fuzzy +msgid "List options" +msgstr "记录选项:" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:31 +msgid "Behavior" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:32 +msgid "Behavior settings" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:42 +msgid "Run games with double click" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:46 +#, fuzzy +msgid "Merge games from different sources" +msgstr "正在合并来自%s的游戏" + +#: src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala:50 +msgid "Use imported tags" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:51 +msgid "General" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:52 +#, fuzzy +msgid "Collection" +msgstr "选择目录" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:53 +msgid "Empty" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:65 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:85 +#, fuzzy +msgid "Collection directory" +msgstr "选择目录" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:70 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:78 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:87 +#, fuzzy +msgid "Game directory" +msgstr "选择目录" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:71 +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:79 +#, fuzzy +msgid "Installers" +msgstr "安装" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:72 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:98 +#, fuzzy +msgid "DLC" +msgstr "DLC" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:73 +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:197 +msgid "Bonus content" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:84 +msgid "Variable syntax: $var or ${var}" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:86 +msgid "Game name" +msgstr "游戏的名字" + +#: src/ui/dialogs/SettingsDialog/pages/general/Collection.vala:88 +#: src/ui/views/GamesView/FiltersPopover.vala:127 +msgid "Platform" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:36 +#, fuzzy +msgid "Controller" +msgstr "安装" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +msgid "Enabled" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:53 +msgid "Focus GameHub window with Guide button" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:57 +#, fuzzy +msgid "Controllers" +msgstr "安装" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:89 +msgid "Move focus" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:91 +msgid "Exit" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Controller.vala:106 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:40 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:108 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:92 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:37 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:95 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:36 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:77 +msgid "Disabled" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:47 +#: src/ui/dialogs/GameTweaksDialog.vala:53 +#: src/ui/views/GamesView/GameContextMenu.vala:183 +msgid "Tweaks" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:34 +msgid "Tweak launch options and apply them to games automatically" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:79 +msgid "" +"Tweaks are loaded from following directories in order\n" +"Last tweak overrides previous tweaks with same identifiers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:83 +msgid "Click to open" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala:93 +#, c-format +msgid "Tweaks are loaded from %1$s and %2$d more directories (?)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:38 +#, fuzzy +msgid "Game sources" +msgstr "打开游戏属性" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:59 +msgid "Steam API keys have limited number of uses per day" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:63 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:57 +#, fuzzy +msgid "Installation directory" +msgstr "选择目录" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:112 +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:176 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:81 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:34 +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:75 +#, fuzzy +msgid "Not installed" +msgstr "未安装" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:116 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:96 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:99 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:85 +#, fuzzy +msgid "Not authenticated" +msgstr "未安装" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +#, c-format +msgid "Authenticated as %s" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:120 +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:101 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:103 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:89 +msgid "Authenticated" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:183 +#: src/ui/dialogs/InstallDialog.vala:53 src/ui/dialogs/InstallDialog.vala:111 +#: src/ui/views/GamesView/GameContextMenu.vala:80 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:233 +#: src/ui/widgets/TweaksList.vala:95 +#, fuzzy +msgid "Install" +msgstr "安装" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala:236 +msgid "Steam API key" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:50 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:54 +#: src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala:48 +#, fuzzy +msgid "Games directory" +msgstr "选择目录" + +#: src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala:59 +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:63 +msgid "Logout" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala:50 +#, fuzzy +msgid "Load games from Humble Trove" +msgstr "正在从%s加载游戏" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:33 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:45 +msgid "Emulators" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:45 +#, fuzzy +msgid "Libretro core directory" +msgstr "打开前缀目录" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:46 +#, fuzzy +msgid "Libretro core info directory" +msgstr "打开前缀目录" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:50 +msgid "Ignored libretro cores" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:54 +msgid "Ignored game file extensions" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:66 +msgid "No cores found" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala:70 +#, c-format +msgid "%u core found" +msgid_plural "%u cores found" +msgstr[0] "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:46 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:168 +msgid "No custom emulators" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:164 +#, c-format +msgid "%u custom emulator" +msgid_plural "%u custom emulators" +msgstr[0] "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:237 +msgid "Save" +msgstr "保存" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:250 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:270 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:312 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/dialogs/GamePropertiesDialog.vala:168 +#: src/ui/dialogs/GamePropertiesDialog.vala:172 +#: src/ui/views/GamesView/AddGamePopover.vala:67 +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +#, fuzzy +msgid "Executable" +msgstr "选择可执行文件" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:251 +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:404 +#: src/ui/views/GamesView/AddGamePopover.vala:68 +#: src/ui/views/GamesView/AddGamePopover.vala:143 +#, fuzzy +msgid "Installer" +msgstr "安装" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:256 +#: src/ui/dialogs/GamePropertiesDialog.vala:64 +#: src/ui/dialogs/GamePropertiesDialog.vala:69 +#: src/ui/views/GamesView/AddGamePopover.vala:73 +msgid "Name" +msgstr "名字" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:272 +#: src/ui/dialogs/GamePropertiesDialog.vala:201 +#: src/ui/views/GamesView/AddGamePopover.vala:78 +#, fuzzy +msgid "Arguments" +msgstr "游戏的名字" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:276 +msgid "Variables" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:277 +#, fuzzy +msgid "Game executable" +msgstr "选择可执行文件" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:278 +#, fuzzy +msgid "Game arguments" +msgstr "游戏的名字" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:80 +#: src/ui/views/GamesView/AddGamePopover.vala:82 +#, fuzzy +msgid "Directory" +msgstr "选择目录" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:288 +#, fuzzy +msgid "Select emulator directory" +msgstr "选择目录" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:292 +#: src/ui/dialogs/GamePropertiesDialog.vala:219 +#, fuzzy +msgid "Force compatibility mode" +msgstr "显示兼容性选项对话框" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:307 +#, fuzzy +msgid "Game file patterns" +msgstr "选择可执行文件" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:315 +msgid "Image" +msgstr "图片" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:318 +msgid "Icon" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala:325 +msgid "" +"findutils-compatible glob patterns\n" +"\n" +" Multiple patterns can be separated with |\n" +" Start pattern with ./ to match relative path\n" +" $basename variable will be replaced with game's executable " +"name (without extension)" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:38 +msgid "Data" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:39 +msgid "Providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:40 +msgid "Third-party data providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:55 +#, fuzzy +msgid "Image providers" +msgstr "打开游戏属性" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:68 +msgid "Metadata providers" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala:137 +msgid "Open website" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:36 +msgid "About" +msgstr "关于" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:71 +#, fuzzy +msgid "Copy application version and environment info" +msgstr "显示版本并退出" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:78 +#: src/ui/views/WelcomeView.vala:57 +msgid "All your games in one place" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:92 +msgctxt "about_link" +msgid "Website" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:96 +msgctxt "about_link" +msgid "Source code on GitHub" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:103 +msgctxt "about_link" +msgid "Report a problem" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:104 +#, fuzzy +msgctxt "about_link" +msgid "Suggest translations" +msgstr "静默安装" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:110 +msgctxt "about_link" +msgid "Issues" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:111 +msgctxt "about_link" +msgid "Contributors" +msgstr "" + +#. TRANSLATORS: Likely it should not be translated. GitHub Pulse is a page that shows recent repository activity: https://github.com/tkashkin/GameHub/pulse +#: src/ui/dialogs/SettingsDialog/pages/About.vala:114 +msgctxt "about_link" +msgid "Pulse" +msgstr "" + +#: src/ui/dialogs/SettingsDialog/pages/About.vala:115 +msgctxt "about_link" +msgid "Forks" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:109 +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:129 +msgid "Import" +msgstr "" + +#: src/ui/dialogs/InstallDialog.vala:110 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:153 +msgid "Download" +msgstr "下载" + +#: src/ui/dialogs/InstallDialog.vala:207 +#, fuzzy +msgid "Select installer" +msgstr "选择" + +#: src/ui/dialogs/InstallDialog.vala:216 +#, fuzzy, c-format +msgid "Installer size: %s" +msgstr "安装" + +#: src/ui/dialogs/InstallDialog.vala:348 +msgid "Unknown" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:49 +#, fuzzy, c-format +msgid "%s: Properties" +msgstr "收藏夹" + +#: src/ui/dialogs/GamePropertiesDialog.vala:84 +msgid "Images" +msgstr "图片" + +#: src/ui/dialogs/GamePropertiesDialog.vala:126 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:160 +#: src/ui/views/GameDetailsView/blocks/Artwork.vala:62 +msgid "Download images" +msgstr "下载图片" + +#: src/ui/dialogs/GamePropertiesDialog.vala:144 +msgid "Image URL" +msgstr "图片的URL" + +#: src/ui/dialogs/GamePropertiesDialog.vala:148 +msgid "Vertical image URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:157 +msgid "Icon URL" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +#, fuzzy +msgid "Select working directory" +msgstr "选择目录" + +#: src/ui/dialogs/GamePropertiesDialog.vala:173 +#, fuzzy +msgid "Working directory" +msgstr "打开前缀目录" + +#: src/ui/dialogs/GamePropertiesDialog.vala:214 +#, fuzzy +msgid "Compatibility" +msgstr "禁用DirectX 11兼容层" + +#: src/ui/dialogs/GamePropertiesDialog.vala:236 +msgid "Launch from terminal" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:252 +msgid "Copy to clipboard" +msgstr "" + +#: src/ui/dialogs/GamePropertiesDialog.vala:254 +#, fuzzy +msgid "Add to Steam" +msgstr "加游戏" + +#: src/ui/dialogs/GamePropertiesDialog.vala:255 +#, fuzzy +msgid "Add to the Steam library" +msgstr "加游戏" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:53 +#, c-format +msgid "%s: Overlays" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "Overlays are disabled" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:71 +msgid "" +"Enable overlays to manage DLCs and mods\n" +"\n" +"Enabling will move game to the “base“ overlay" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:77 +#: src/ui/views/GamesView/GameContextMenu.vala:175 +#, fuzzy +msgid "Overlays" +msgstr "删除" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:105 +msgid "Overlay ID (directory name)" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:110 +msgid "Overlay name (optional)" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:112 +msgid "Add" +msgstr "加" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:127 +#, fuzzy +msgid "Enable overlays" +msgstr "删除" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:182 +#, c-format +msgid "" +"Overlay usage at this path may be unsafe\n" +"Proceed at your own risk\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:187 +#, c-format +msgid "" +"Overlay usage at this path is not supported\n" +"\n" +"Path: %s" +msgstr "" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:266 +#, fuzzy +msgid "Open directory" +msgstr "打开前缀目录" + +#: src/ui/dialogs/GameFSOverlaysDialog.vala:271 +#, fuzzy +msgid "Remove overlay" +msgstr "删除" + +#: src/ui/dialogs/CompatRunDialog.vala:48 +#: src/ui/views/GamesView/GameContextMenu.vala:46 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:235 +#, fuzzy +msgid "Run with compatibility layer" +msgstr "禁用DirectX 11兼容层" + +#: src/ui/dialogs/CorruptedInstallerDialog.vala:71 +#, fuzzy +msgid "Corrupted installer: checksum mismatch in" +msgstr "校验和不匹配 %s" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:57 +#: src/ui/views/GamesView/AddGamePopover.vala:105 +#, fuzzy +msgid "Import emulated games" +msgstr "选择目录" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:75 +#, fuzzy +msgid "Select directory with emulated games" +msgstr "选择目录" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:83 +#, fuzzy +msgid "Detected games" +msgstr "选择目录" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:107 +#, fuzzy +msgid "Select all" +msgstr "选择" + +#: src/ui/dialogs/ImportEmulatedGamesDialog.vala:115 +#, fuzzy +msgid "Select directory to import" +msgstr "选择目录" + +#: src/ui/dialogs/GameTweaksDialog.vala:40 +#, c-format +msgid "%s: Tweaks" +msgstr "" + +#: src/ui/views/WelcomeView.vala:52 +#, fuzzy +msgid "No enabled game sources" +msgstr "用户游戏" + +#: src/ui/views/WelcomeView.vala:52 +msgid "Enable some game sources in settings" +msgstr "" + +#: src/ui/views/WelcomeView.vala:57 +msgid "Let's get started" +msgstr "" + +#: src/ui/views/WelcomeView.vala:71 +msgid "Skip" +msgstr "" + +#: src/ui/views/WelcomeView.vala:141 +msgid "Ready" +msgstr "" + +#: src/ui/views/WelcomeView.vala:147 +msgid "Authentication required" +msgstr "" + +#: src/ui/views/WelcomeView.vala:152 +msgid "Authenticating…" +msgstr "" + +#: src/ui/views/WelcomeView.vala:163 +#, fuzzy, c-format +msgid "Install %s" +msgstr "安装" + +#: src/ui/views/WelcomeView.vala:164 +msgid "Return to GameHub after installing" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:136 +#, fuzzy +msgid "No games" +msgstr "运行游戏" + +#: src/ui/views/GamesView/GamesView.vala:136 +msgid "Get some games or enable some game sources in settings" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:150 +msgid "Grid view" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:151 +msgid "List view" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:159 +#, fuzzy +msgid "All games" +msgstr "%s 游戏" + +#: src/ui/views/GamesView/GamesView.vala:182 +#, fuzzy +msgid "Downloads" +msgstr "下载" + +#: src/ui/views/GamesView/GamesView.vala:208 +msgid "Filters" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:216 +#: src/ui/views/GamesView/AddGamePopover.vala:84 +msgid "Add game" +msgstr "加游戏" + +#: src/ui/views/GamesView/GamesView.vala:223 +msgid "Search" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:328 +msgid "Menu" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:329 +#: src/ui/views/GameDetailsView/GameDetailsView.vala:104 +#, fuzzy +msgid "Back" +msgstr "备份" + +#: src/ui/views/GamesView/GamesView.vala:550 +#, c-format +msgid "%u game" +msgid_plural "%u games" +msgstr[0] "%u个游戏" + +#: src/ui/views/GamesView/GamesView.vala:553 +#, c-format +msgctxt "games_view_subtitle_filtered_games" +msgid "%1$u / %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:557 +#, c-format +msgctxt "games_view_subtitle" +msgid "%1$s: %2$s" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:568 +#, fuzzy +msgid "No user-added games" +msgstr "用户游戏" + +#: src/ui/views/GamesView/GamesView.vala:569 +msgid "Add some games using plus button" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:573 +#, fuzzy, c-format +msgid "No %s games" +msgstr "%s 游戏" + +#: src/ui/views/GamesView/GamesView.vala:574 +msgid "Get some Linux-compatible games" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:584 +#, c-format +msgid "No games matching “%s”" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:589 +#, c-format +msgid "No %1$s games matching “%2$s”" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:627 +msgid "" +"No games were loaded from Steam. Set your games list privacy to public or " +"use your own Steam API key in settings." +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:628 +msgid "Privacy" +msgstr "" + +#: src/ui/views/GamesView/GamesView.vala:739 +msgid "Downloading images" +msgstr "还在下载图片" + +#: src/ui/views/GamesView/GamesView.vala:753 +#, c-format +msgid "Downloading image: %s" +msgstr "还在下载图片:%s" + +#: src/ui/views/GamesView/DownloadProgressView.vala:131 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:162 +#, fuzzy +msgid "Pause download" +msgstr "开始下载" + +#: src/ui/views/GamesView/DownloadProgressView.vala:137 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:168 +#, fuzzy +msgid "Resume download" +msgstr "下载" + +#: src/ui/views/GamesView/DownloadProgressView.vala:143 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:174 +#, fuzzy +msgid "Cancel download" +msgstr "开始下载" + +#: src/ui/views/GamesView/FiltersPopover.vala:77 +msgid "Group" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:102 +msgid "Sort" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:234 +#: src/ui/widgets/GameTagsList.vala:58 +msgid "Tags" +msgstr "" + +#: src/ui/views/GamesView/FiltersPopover.vala:353 +#, fuzzy +msgid "All platforms" +msgstr "%s 游戏" + +#: src/ui/views/GamesView/AddGamePopover.vala:77 +#, fuzzy +msgid "Select game executable" +msgstr "选择可执行文件" + +#: src/ui/views/GamesView/AddGamePopover.vala:82 +#, fuzzy +msgid "Select game directory" +msgstr "选择目录" + +#: src/ui/views/GamesView/AddGamePopover.vala:111 +msgid "Download game images" +msgstr "下载游戏的图片" + +#: src/ui/views/GamesView/GameContextMenu.vala:87 +msgid "Details" +msgstr "" + +#: src/ui/views/GamesView/GameContextMenu.vala:117 +#, fuzzy +msgctxt "game_context_menu" +msgid "Favorite" +msgstr "收藏夹" + +#: src/ui/views/GamesView/GameContextMenu.vala:121 +#, fuzzy +msgctxt "game_context_menu" +msgid "Hidden" +msgstr "隐藏的" + +#: src/ui/views/GamesView/GameContextMenu.vala:133 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:236 +#, fuzzy +msgid "Open installation directory" +msgstr "打开前缀目录" + +#: src/ui/views/GamesView/GameContextMenu.vala:142 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:237 +#, fuzzy +msgid "Open installers collection directory" +msgstr "打开前缀目录" + +#: src/ui/views/GamesView/GameContextMenu.vala:151 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:238 +#, fuzzy +msgid "Open bonus collection directory" +msgstr "打开前缀目录" + +#: src/ui/views/GamesView/GameContextMenu.vala:160 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:239 +#, fuzzy +msgid "Open screenshots directory" +msgstr "打开前缀目录" + +#: src/ui/views/GamesView/GameContextMenu.vala:167 +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:167 +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:241 +#, fuzzy +msgid "Uninstall" +msgstr "安装" + +#: src/ui/views/GamesView/GameContextMenu.vala:192 +#, fuzzy +msgid "Properties" +msgstr "打开游戏属性" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:100 +#, fuzzy, c-format +msgid "%d game selected" +msgid_plural "%d games selected" +msgstr[0] "%s: 没有可用的安装程序" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:144 +#, fuzzy, c-format +msgid "%d game will be installed" +msgid_plural "%d games will be installed" +msgstr[0] "%s: 没有可用的安装程序" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:154 +#, fuzzy, c-format +msgid "%d game will be downloaded" +msgid_plural "%d games will be downloaded" +msgstr[0] "%s: 没有可用的安装程序" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:161 +#, fuzzy, c-format +msgid "Image for %d game will be searched" +msgid_plural "Images for %d games will be searched" +msgstr[0] "%s: 没有可用的安装程序" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:168 +#, fuzzy, c-format +msgid "%d game will be uninstalled" +msgid_plural "%d games will be uninstalled" +msgstr[0] "%s: 没有可用的安装程序" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:174 +msgid "Refresh" +msgstr "" + +#: src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala:175 +#, c-format +msgid "" +"%d game will be removed from database. Restart GameHub to fetch new data" +msgid_plural "" +"%d games will be removed from database. Restart GameHub to fetch new data" +msgstr[0] "" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:240 +msgid "Open store page" +msgstr "" + +#: src/ui/views/GameDetailsView/GameDetailsPage.vala:242 +#, fuzzy +msgid "Game properties" +msgstr "打开游戏属性" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:46 +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:60 +msgid "Playtime" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:52 +msgid "Playtime (local)" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Playtime.vala:69 +msgid "Last launch" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:46 +msgid "Achievements" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:85 +#, c-format +msgid "Unlocked: %s" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/Achievements.vala:90 +#, c-format +msgid "Global percentage: %g%%" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:77 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:103 +msgid "Language" +msgstr "语言" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:80 +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:106 +msgid "Languages" +msgstr "语言" + +#: src/ui/views/GameDetailsView/blocks/GOGDetails.vala:147 +#, fuzzy, c-format +msgid "%u DLCs cannot be installed" +msgstr "%s: 安装程序损坏" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:71 +msgid "Category" +msgstr "类" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:74 +msgid "Categories" +msgstr "类" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:90 +msgid "Genre" +msgstr "类型" + +#: src/ui/views/GameDetailsView/blocks/SteamDetails.vala:93 +msgid "Genres" +msgstr "类型" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:109 +msgctxt "igdb" +msgid "Popularity" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:115 +msgctxt "igdb" +msgid "Aggregated rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:116 +msgctxt "igdb" +msgid "IGDB user rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:117 +msgctxt "igdb" +msgid "Total rating" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:126 +msgctxt "igdb" +msgid "Release date" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:133 +#, fuzzy +msgctxt "igdb" +msgid "Platforms" +msgstr "%s 游戏" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:139 +msgctxt "igdb" +msgid "Genres" +msgstr "类型" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:145 +msgctxt "igdb" +msgid "Keywords" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:152 +msgctxt "igdb" +msgid "Links" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:208 +#, c-format +msgid "Based on %d rating" +msgid_plural "Based on %d ratings" +msgstr[0] "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:290 +msgctxt "igdb" +msgid "Summary" +msgstr "" + +#: src/ui/views/GameDetailsView/blocks/IGDBInfo.vala:301 +msgctxt "igdb" +msgid "Storyline" +msgstr "" + +#: src/ui/widgets/FileChooserEntry.vala:49 +#: src/ui/widgets/FileChooserEntry.vala:55 +#: src/ui/widgets/FileChooserEntry.vala:57 +#, fuzzy +msgid "Select file" +msgstr "选择" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +#, fuzzy +msgid "No images" +msgstr "下载图片" + +#: src/ui/widgets/ImagesDownloadPopover.vala:74 +msgid "" +"There are no images found for this game\n" +"Make sure game name is correct" +msgstr "" + +#: src/ui/widgets/ImagesDownloadPopover.vala:94 +#, fuzzy +msgid "Search images:" +msgstr "下载图片" + +#: src/ui/widgets/CompatToolPicker.vala:53 +#, fuzzy +msgid "Compatibility layer:" +msgstr "禁用DirectX 11兼容层" + +#: src/ui/widgets/CompatToolPicker.vala:92 +msgid "Configure" +msgstr "" + +#: src/ui/widgets/GameTagsList.vala:109 +#, fuzzy +msgid "Add tag" +msgstr "加游戏" + +#: src/ui/widgets/TweaksList.vala:86 +msgid "No description" +msgstr "" + +#: src/ui/widgets/TweaksList.vala:124 +#, fuzzy +msgid "Edit file" +msgstr "选择" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, fuzzy, c-format +msgctxt "time" +msgid "%dh" +msgstr "%d分" + +#: src/utils/Utils.vala:456 src/utils/Utils.vala:464 +#, c-format +msgctxt "time" +msgid "%dm" +msgstr "%d分" + +#: src/utils/Utils.vala:464 +#, fuzzy, c-format +msgctxt "time" +msgid "%ds" +msgstr "%d分" + +#: src/settings/UI.vala:153 +msgctxt "grid_size_preset" +msgid "Steam" +msgstr "" + +#: src/settings/UI.vala:154 +msgctxt "grid_size_preset" +msgid "Steam (vertical)" +msgstr "" + +#: src/settings/UI.vala:155 +msgctxt "grid_size_preset" +msgid "GOG" +msgstr "" + +#: src/settings/UI.vala:156 +msgctxt "grid_size_preset" +msgid "GOG (vertical)" +msgstr "" + +#: src/settings/UI.vala:157 +msgctxt "grid_size_preset" +msgid "Square" +msgstr "" + +#: src/settings/UI.vala:158 +msgctxt "grid_size_preset" +msgid "Custom" +msgstr "" + +#: src/utils/downloader/Downloader.vala:200 +msgctxt "dl_status" +msgid "Queued" +msgstr "" + +#: src/utils/downloader/Downloader.vala:201 +msgctxt "dl_status" +msgid "Starting download" +msgstr "开始下载" + +#: src/utils/downloader/Downloader.vala:202 +msgctxt "dl_status" +msgid "Download started" +msgstr "下载开始玩了" + +#: src/utils/downloader/Downloader.vala:203 +#, fuzzy +msgctxt "dl_status" +msgid "Download finished" +msgstr "下载开始玩了" + +#: src/utils/downloader/Downloader.vala:204 +#, fuzzy +msgctxt "dl_status" +msgid "Download failed" +msgstr "下载开始玩了" + +#: src/utils/downloader/Downloader.vala:208 +#, fuzzy, c-format +msgctxt "dl_status" +msgid "Downloading: %s" +msgstr "正在下载" + +#: src/utils/downloader/Downloader.vala:210 +#, fuzzy +msgctxt "dl_status" +msgid "Downloading" +msgstr "正在下载" + +#: src/utils/downloader/Downloader.vala:214 +#, c-format +msgctxt "dl_status" +msgid "Paused: %s" +msgstr "" + +#: src/utils/downloader/Downloader.vala:216 +#, fuzzy +msgctxt "dl_status" +msgid "Paused" +msgstr "开始下载" + +#: src/utils/downloader/Downloader.vala:218 +#, fuzzy +msgctxt "dl_status" +msgid "Download cancelled" +msgstr "下载开始玩了" + +#. TRANSLATORS: Download progress template. %1$d - percentage, %2$s / %3$s - downloaded portion and total file size, %4$s - download speed +#: src/utils/downloader/Downloader.vala:262 +#, c-format +msgctxt "dl_status" +msgid "%1$d%% (%2$s / %3$s) [%4$s/s]" +msgstr "" + +#, fuzzy +#~ msgid "Disable esync" +#~ msgstr "禁用esync" + +#~ msgid "Force LARGE_ADDRESS_AWARE flag" +#~ msgstr "强制使用 LARGE_ADDRESS_AWARE 标志" + +#~ msgid "Disable DirectX 11 compatibility layer" +#~ msgstr "禁用DirectX 11兼容层" + +#~ msgid "Use WineD3D11 as DirectX 11 compatibility layer" +#~ msgstr "使用wined3d11作为Directx11兼容层" + +#~ msgid "Show DXVK info overlay" +#~ msgstr "显示dxvk信息覆盖" + +#, fuzzy +#~ msgid "Enable DirectX 9 compatibility layer" +#~ msgstr "禁用DirectX 11兼容层" + +#~ msgid "Silent installation" +#~ msgstr "静默安装" + +#~ msgid "Very silent installation" +#~ msgstr "非常安静的安装" + +#~ msgid "Suppress messages" +#~ msgstr "禁止显示消息" + +#~ msgid "No GUI" +#~ msgstr "无图形用户界面" diff --git a/scripts/AppRun b/scripts/AppRun new file mode 100755 index 00000000..ceed818e --- /dev/null +++ b/scripts/AppRun @@ -0,0 +1,19 @@ +#!/bin/bash + +echo "[AppRun ] GameHub AppImage" +echo "[AppRun ] AppDir: $APPDIR" + +export LD_LIBRARY_PATH="$APPDIR/usr/lib:$LD_LIBRARY_PATH" +export PATH="$APPDIR/usr/bin:$PATH" +export XDG_DATA_DIRS="$APPDIR/usr/share:$XDG_DATA_DIRS" + +export GSETTINGS_SCHEMA_DIR="$APPDIR/usr/share/glib-2.0/schemas/:$GSETTINGS_SCHEMA_DIR" + +export LD_LIBRARY_PATH="$APPDIR/usr/lib/x86_64-linux-gnu/webkit2gtk-4.0:$LD_LIBRARY_PATH" + +[ -e "$APPDIR/checkrt.sh" ] && . "$APPDIR/checkrt.sh" || echo "[AppRun ] Skipping CheckRT" + +echo "[AppRun ] Starting GameHub" + +cd "$APPDIR/usr" +"$APPDIR/usr/bin/com.github.tkashkin.gamehub" "$@" diff --git a/scripts/build.sh b/scripts/build.sh new file mode 100755 index 00000000..5aeed331 --- /dev/null +++ b/scripts/build.sh @@ -0,0 +1,366 @@ +#!/bin/bash + +_GH_RDNN="com.github.tkashkin.gamehub" +_GH_VERSION="0.16.0" + +_GH_BRANCH="${APPVEYOR_REPO_BRANCH:-$(git symbolic-ref --short -q HEAD)}" +_GH_COMMIT="$(git rev-parse HEAD)" +_GH_COMMIT_SHORT="$(git rev-parse --short HEAD)" + +_ROOT="`pwd`" +_SCRIPTROOT="$(dirname "$(readlink -f "$0")")" +_LINUXDEPLOYQT="linuxdeployqt-5-x86_64.AppImage" + +_SOURCE="${APPVEYOR_BUILD_VERSION:-$_GH_VERSION-$_GH_BRANCH-local}" +_VERSION="$_SOURCE-$_GH_COMMIT_SHORT" +_BUILD_VERSION="${APPVEYOR_BUILD_VERSION:-$_VERSION}" +_DEB_TARGET_DISTRO_ID="ubuntu" +_DEB_TARGET_DISTRO_NAMES=() +_DEB_TARGET_DISTRO_VERSIONS=() +_BUILD_IMAGE="local" +_GPG_BINARY="gpg1" +_GPG_PACKAGE="gnupg1" + +export CFLAGS="$CFLAGS -O0" +export DEB_BUILD_OPTIONS="noopt nostrip nocheck" + +if [[ "$APPVEYOR_BUILD_WORKER_IMAGE" = "Ubuntu1604" ]]; then + _DEB_TARGET_DISTRO_NAMES=("xenial") + _DEB_TARGET_DISTRO_VERSIONS=("16.04") + _BUILD_IMAGE="xenial" + _GPG_BINARY="gpg" + _GPG_PACKAGE="gnupg" +elif [[ "$APPVEYOR_BUILD_WORKER_IMAGE" = "Ubuntu1804" ]]; then + _DEB_TARGET_DISTRO_NAMES=("bionic" "disco" "eoan" "focal") + _DEB_TARGET_DISTRO_VERSIONS=("18.04" "19.04" "19.10" "20.04") + _BUILD_IMAGE="bionic" +else + source "/etc/os-release" + _DEB_TARGET_DISTRO_ID="$ID" + _DEB_TARGET_DISTRO_NAMES=("$VERSION_CODENAME") + _DEB_TARGET_DISTRO_VERSIONS=("$VERSION_ID") +fi + +BUILDROOT="$_ROOT/build/appimage" +BUILDDIR="$BUILDROOT/build" +APPDIR="$BUILDROOT/appdir" + +ACTION=${1:-build_local} +CHECKRT=${2:---checkrt} + +_usr_patch() +{ + set +e + file="$1" + echo "[scripts/build.sh] Patching $file" + sed -i -e 's#/usr#././#g' "$file" +} + +_mv_deps() +{ + set +e + lib="$1" + src="$2" + dest="$3" + recursive=${4:-true} + echo "[scripts/build.sh] Moving $lib" + [ -e "$src/$lib" ] && mv -f "$src/$lib" "$dest" + [ -e "$dest/$lib" ] && ldd "$dest/$lib" | awk '{print $1}' | while read dep; do + [ -e "$src/$dep" ] && echo "[scripts/build.sh] $dep <- $lib" + if [ "$recursive" = "true" ]; then + [ -e "$src/$dep" ] && _mv_deps "$dep" "$src" "$dest" "$recursive" + else + [ -e "$src/$dep" ] && mv -f "$src/$dep" "$dest" + fi + done +} + +import_keys() +{ + set +e + cd "$_ROOT" + if [[ -n "$keys_enc_secret" ]]; then + echo "[scripts/build.sh] Importing keys" + sudo apt install -y "$_GPG_PACKAGE" + curl -sflL "https://raw.githubusercontent.com/appveyor/secure-file/master/install.sh" | bash -e - + ./appveyor-tools/secure-file -decrypt "$_SCRIPTROOT/launchpad/key_pub.gpg.enc" -secret $keys_enc_secret + ./appveyor-tools/secure-file -decrypt "$_SCRIPTROOT/launchpad/key_sec.gpg.enc" -secret $keys_enc_secret + ./appveyor-tools/secure-file -decrypt "$_SCRIPTROOT/launchpad/passphrase.enc" -secret $keys_enc_secret + "$_GPG_BINARY" --no-use-agent --import "$_SCRIPTROOT/launchpad/key_pub.gpg" + "$_GPG_BINARY" --no-use-agent --allow-secret-key-import --import "$_SCRIPTROOT/launchpad/key_sec.gpg" + sudo apt-key add "$_SCRIPTROOT/launchpad/key_pub.gpg" + rm -f "$_SCRIPTROOT/launchpad/key_pub.gpg" "$_SCRIPTROOT/launchpad/key_sec.gpg" + fi +} + +deps() +{ + set +e + echo "[scripts/build.sh] Installing dependencies" + sudo DEBIAN_FRONTEND="noninteractive" add-apt-repository ppa:vala-team/next -y + sudo DEBIAN_FRONTEND="noninteractive" add-apt-repository ppa:savoury1/build-tools -y + sudo DEBIAN_FRONTEND="noninteractive" apt update -qq + sudo DEBIAN_FRONTEND="noninteractive" apt install -y meson valac checkinstall build-essential dput fakeroot moreutils git-buildpackage libgtk-3-dev libglib2.0-dev libwebkit2gtk-4.0-dev libjson-glib-dev libgee-0.8-dev libsoup2.4-dev libsqlite3-dev libxml2-dev libpolkit-gobject-1-dev + #sudo apt full-upgrade -y + if [[ "$APPVEYOR_BUILD_WORKER_IMAGE" = "Ubuntu1604" ]]; then + sudo DEBIAN_FRONTEND="noninteractive" dpkg -i "$_SCRIPTROOT/deps/xenial/"*.deb + else + sudo DEBIAN_FRONTEND="noninteractive" apt install -y libmanette-0.2-dev libxtst-dev libx11-dev + fi +} + +gen_changelogs() +{ + set +e + cd "$_ROOT" + echo "[scripts/build.sh] Generating changelogs" + + if [[ -z `git config user.name` ]]; then + git config user.email "ci@localhost" + git config user.name "CI" + fi + + git fetch --tags + + git tag -a $_BUILD_VERSION -m $_BUILD_VERSION + + > "debian/changelog.in" + > "data/$_GH_RDNN.changelog.xml" + + prevtag="initial" + git tag --sort v:refname | while read tag; do + if [[ "$prevtag" == "initial" ]]; then + prevtag="$tag" + continue + fi + + commitmsg=`git log --pretty=format:' * %s [%h]' $prevtag..$tag` + + ( + echo "$_GH_RDNN ($tag~\$VERSION_SUFFIX) \$DISTRO; urgency=low" + echo "${commitmsg:- * }" + git log -n1 --pretty='format:%n -- %aN <%aE> %aD%n%n' $tag^..$tag + ) | cat - "debian/changelog.in" | sponge "debian/changelog.in" + + xml_r_type="development" && [[ "$tag" == *"-master" ]] && xml_r_type="stable" + xml_r_date=`git log -n1 --date=short --pretty='format:date="%cd" timestamp="%ct"' $tag^..$tag` + xml_r_end=" />" && [[ -n "$commitmsg" ]] && xml_r_end=">" + xml_ver=`echo "$tag" | sed -E "s|-|.|g"` + + ( + echo -e "\t\t" + echo -e "\t\t\t\t
    " + + echo "$commitmsg" | sed -E "s|<|\<|g; s|>|\>|g; s| \* (.*)|\t\t\t\t\t
  • \1
  • |g" + + echo -e "\t\t\t\t
" + echo -e "\t\t\t" + echo -e "\t\t
" + fi + ) | cat - "data/$_GH_RDNN.changelog.xml" | sponge "data/$_GH_RDNN.changelog.xml" + + prevtag="$tag" + done + + git tag -d $_BUILD_VERSION +} + +build_deb() +{ + set -e + cd "$_ROOT" + sed "s/\$_GH_BRANCH/$_GH_BRANCH/g; s/\$_GH_COMMIT_SHORT/$_GH_COMMIT_SHORT/g; s/\$_GH_COMMIT/$_GH_COMMIT/g" "debian/rules.in" > "debian/rules" + if [[ "$APPVEYOR_BUILD_WORKER_IMAGE" = "Ubuntu1604" ]]; then + sed "s/libmanette-0.2-dev,//g" "debian/control.in" > "debian/control" + else + cp -f "debian/control.in" "debian/control" + fi + + for i in "${!_DEB_TARGET_DISTRO_NAMES[@]}"; do + _DEB_TARGET_DISTRO_NAME="${_DEB_TARGET_DISTRO_NAMES[$i]}" + _DEB_TARGET_DISTRO_VERSION="${_DEB_TARGET_DISTRO_VERSIONS[$i]}" + _DEB_VERSION_SUFFIX="${_DEB_TARGET_DISTRO_ID}${_DEB_TARGET_DISTRO_VERSION}" + _DEB_VERSION="${_BUILD_VERSION}~${_DEB_VERSION_SUFFIX}" + sed "s/\$DISTRO/${_DEB_TARGET_DISTRO_NAME}/g; s/\$VERSION_SUFFIX/${_DEB_VERSION_SUFFIX}/g" "debian/changelog.in" > "debian/changelog" + + if [[ $i = 0 ]]; then + echo "[scripts/build.sh] Building binary package for $_DEB_TARGET_DISTRO_ID $_DEB_TARGET_DISTRO_VERSION ($_DEB_TARGET_DISTRO_NAME)" + dpkg-buildpackage -F -sa -us -uc + mkdir -p "build/$_BUILD_IMAGE" + mv ../$_GH_RDNN*.deb "build/${_BUILD_IMAGE}/GameHub-${_BUILD_VERSION}-${_DEB_TARGET_DISTRO_NAME}-amd64.deb" + fi + + if [[ -e "$_SCRIPTROOT/launchpad/passphrase" && -n "$keys_enc_secret" ]]; then + set +e + echo "[scripts/build.sh] Building source package for $_DEB_TARGET_DISTRO_ID $_DEB_TARGET_DISTRO_VERSION ($_DEB_TARGET_DISTRO_NAME)" + dpkg-buildpackage -S -sa -us -uc + echo "[scripts/build.sh] Signing source package" + debsign -p"$_GPG_BINARY --no-use-agent --passphrase-file $_SCRIPTROOT/launchpad/passphrase --batch" -S -k2744E6BAF20BA10AAE92253F20442B9273408FF9 "../${_GH_RDNN}_${_DEB_VERSION}_source.changes" + echo "[scripts/build.sh] Uploading package to launchpad" + dput -u -c "$_SCRIPTROOT/launchpad/dput.cf" "gamehub_${_DEB_TARGET_DISTRO_NAME}" "../${_GH_RDNN}_${_DEB_VERSION}_source.changes" + rm "../${_GH_RDNN}_"* + set -e + fi + done + rm -f "$_SCRIPTROOT/launchpad/passphrase" + cd "$_ROOT" +} + +build() +{ + set -e + echo "[scripts/build.sh] Building" + cd "$_ROOT" + mkdir -p "$BUILDROOT" + meson "$BUILDDIR" --prefix=/usr --buildtype=debug -Dpackage=appimage -Dgit_branch=$_GH_BRANCH -Dgit_commit=$_GH_COMMIT -Dgit_commit_short=$_GH_COMMIT_SHORT + cd "$BUILDDIR" + ninja + DESTDIR="$APPDIR" ninja install + cd "$_ROOT" +} + +appimage() +{ + set -e + echo "[scripts/build.sh] Preparing AppImage" + cd "$BUILDROOT" + wget -c -nv "https://github.com/probonopd/linuxdeployqt/releases/download/5/$_LINUXDEPLOYQT" + chmod a+x "./$_LINUXDEPLOYQT" + unset QTDIR; unset QT_PLUGIN_PATH; unset LD_LIBRARY_PATH + export VERSION="${_BUILD_IMAGE}-${_VERSION}" + export LD_LIBRARY_PATH=$APPDIR/usr/lib:$LD_LIBRARY_PATH + "./$_LINUXDEPLOYQT" "$APPDIR/usr/share/applications/$_GH_RDNN.desktop" -appimage -no-plugins -no-copy-copyright-files +} + +appimage_tweak() +{ + set -e + echo "[scripts/build.sh] Tweaking AppImage" + cd "$BUILDROOT" + rm -f "$APPDIR/AppRun" + cp -f "$_SCRIPTROOT/AppRun" "$APPDIR/AppRun" + glib-compile-schemas "$APPDIR/usr/share/glib-2.0/schemas" +} + +appimage_bundle_libs() +{ + set +e + echo "[scripts/build.sh] Bundling additional libs" + cd "$BUILDROOT" + + mkdir -p "$APPDIR/usr/lib/x86_64-linux-gnu/webkit2gtk-4.0/" + cp -rf "/usr/lib/x86_64-linux-gnu/webkit2gtk-4.0/injected-bundle/" "$APPDIR/usr/lib/x86_64-linux-gnu/webkit2gtk-4.0/" + cp -f "/usr/lib/x86_64-linux-gnu/webkit2gtk-4.0/WebKitNetworkProcess" "$APPDIR/usr/lib/x86_64-linux-gnu/webkit2gtk-4.0/" + cp -f "/usr/lib/x86_64-linux-gnu/webkit2gtk-4.0/WebKitStorageProcess" "$APPDIR/usr/lib/x86_64-linux-gnu/webkit2gtk-4.0/" + cp -f "/usr/lib/x86_64-linux-gnu/webkit2gtk-4.0/WebKitWebProcess" "$APPDIR/usr/lib/x86_64-linux-gnu/webkit2gtk-4.0/" + find "$APPDIR/usr/lib/" -maxdepth 1 -type f -name "libwebkit2gtk-4.0.so.*" -print0 | while read -d $'\0' file; do + _usr_patch "$file" + done + find "$APPDIR/usr/lib/x86_64-linux-gnu/webkit2gtk-4.0/" -maxdepth 1 -type f -print0 | while read -d $'\0' file; do + _usr_patch "$file" + done +} + +appimage_checkrt() +{ + set +e + echo "[scripts/build.sh] Bundling checkrt libs" + cd "$BUILDROOT" + cp -f "$_SCRIPTROOT/checkrt.sh" "$APPDIR/checkrt.sh" + cp -rf "$_SCRIPTROOT/optlib" "$APPDIR/usr/" + + echo "[scripts/build.sh] Moving GTK and its dependencies" + mkdir -p "$APPDIR/usr/optlib/libgtk-3.so.0/" + _mv_deps "libgtk-3.so.0" "$APPDIR/usr/lib" "$APPDIR/usr/optlib/libgtk-3.so.0/" + + echo "[scripts/build.sh] Moving back non-GTK-specific dependencies" + find "$APPDIR/usr/lib/" -maxdepth 1 -type f -not -name "libwebkit2gtk-4.0.so.*" -print0 | while read -d $'\0' dep; do + _mv_deps "$(basename $dep)" "$APPDIR/usr/optlib/libgtk-3.so.0" "$APPDIR/usr/lib/" "false" + done + + if [[ "$APPVEYOR_BUILD_WORKER_IMAGE" = "Ubuntu1804" ]]; then + echo "[scripts/build.sh] Removing GTK and its dependencies" + rm -rf "$APPDIR/usr/optlib/libgtk-3.so.0" + fi + + for lib in 'libstdc++.so.6' 'libgcc_s.so.1'; do + echo "[scripts/build.sh] Bundling $lib" + mkdir -p "$APPDIR/usr/optlib/$lib" + for dir in "/lib" "/usr/lib"; do + libfile="$dir/x86_64-linux-gnu/$lib" + [ -e "$libfile" ] && cp "$libfile" "$APPDIR/usr/optlib/$lib/" + done + done +} + +appimage_pack() +{ + set -e + echo "[scripts/build.sh] Packing AppImage" + cd "$BUILDROOT" + unset QTDIR; unset QT_PLUGIN_PATH; unset LD_LIBRARY_PATH + export VERSION="${_BUILD_IMAGE}-${_VERSION}" + export LD_LIBRARY_PATH=$APPDIR/usr/lib:$LD_LIBRARY_PATH + "./$_LINUXDEPLOYQT" --appimage-extract + PATH=./squashfs-root/usr/bin:$PATH ./squashfs-root/usr/bin/appimagetool --no-appstream "$APPDIR" +} + +build_flatpak() +{ + set +e + echo "[scripts/build.sh] Building flatpak package" + cd "$_ROOT" + gen_changelogs + git add "debian/changelog" "data/$_GH_RDNN.changelog.xml" + git commit -m "Save generated changelog" + mkdir -p "$_ROOT/build/flatpak" + cd "$_ROOT/flatpak" + echo "[scripts/build.sh] Installing flatpak" + sudo DEBIAN_FRONTEND="noninteractive" apt install -y flatpak flatpak-builder + flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo + sed "s/\$BRANCH/$_GH_BRANCH/g; s/\$COMMIT_SHORT/$_GH_COMMIT_SHORT/g; s/\$COMMIT/$_GH_COMMIT/g" "$_GH_RDNN.json.in" > "$_GH_RDNN.json" + echo "[scripts/build.sh] Autoinstalling dependencies" + flatpak-builder -y --user --install-deps-from=flathub --install-deps-only "$_ROOT/build/flatpak/build" "$_GH_RDNN.json" + echo "[scripts/build.sh] Building" + flatpak-builder -y --user --repo="$_ROOT/build/flatpak/repo" --force-clean "$_ROOT/build/flatpak/build" "$_GH_RDNN.json" + echo "[scripts/build.sh] Building bundle" + flatpak build-bundle "$_ROOT/build/flatpak/repo" "$_ROOT/build/flatpak/GameHub-${_BUILD_IMAGE}-${_VERSION}.flatpak" "$_GH_RDNN" + echo "[scripts/build.sh] Removing flatpak build and repo directories" + rm -rf ".flatpak-builder" "$_ROOT/build/flatpak/build" "$_ROOT/build/flatpak/repo" + return 0 +} + +set +e +cd "$_ROOT" +git submodule update --init +mkdir -p "$BUILDROOT" + +if [[ "$ACTION" = "import_keys" ]]; then import_keys; fi + +if [[ "$ACTION" = "deps" ]]; then deps; fi + +if [[ "$ACTION" = "gen_changelogs" ]]; then gen_changelogs; fi + +if [[ "$ACTION" = "build_deb" ]]; then build_deb; fi + +if [[ "$ACTION" = "build" || "$ACTION" = "build_local" ]]; then build; fi + +if [[ "$ACTION" = "appimage" || "$ACTION" = "build_local" ]]; then appimage; fi +if [[ "$ACTION" = "appimage_tweak" || "$ACTION" = "build_local" ]]; then appimage_tweak; fi +if [[ "$ACTION" = "appimage_bundle_libs" || "$ACTION" = "build_local" ]]; then appimage_bundle_libs; fi +if [[ "$ACTION" = "appimage_checkrt" || ( "$ACTION" = "build_local" && "$CHECKRT" = "--checkrt" ) ]]; then appimage_checkrt; fi +if [[ "$ACTION" = "appimage_pack" || "$ACTION" = "build_local" ]]; then appimage_pack; fi + +if [[ "$ACTION" = "build_appimage" ]]; then + build + appimage + appimage_tweak + appimage_bundle_libs + appimage_checkrt + appimage_pack +fi + +if [[ "$ACTION" = "build_flatpak" && ! "$_BUILD_IMAGE" = "xenial" ]]; then build_flatpak; fi diff --git a/scripts/checkrt.sh b/scripts/checkrt.sh new file mode 100755 index 00000000..ecfdcfe5 --- /dev/null +++ b/scripts/checkrt.sh @@ -0,0 +1,55 @@ +#!/bin/bash + +_CRT_LIB_PATH="" + +echo "[CheckRT] Checking library versions" + +_CRT_LIBS=( + 'libstdc++.so.6':'^GLIBCXX_[0-9]\.[0-9]' + 'libgcc_s.so.1':'^GCC_[0-9]\.[0-9]' +) + +_CRT_LIBS_PREFER_SYSTEM=( + 'libgtk-3.so.0':'^gtk_scrolled_window_set_propagate_natural_width' # GTK 3.22+ +) + +for lib in ${_CRT_LIBS[@]}; do + lib_filename=$(echo "$lib" | cut -d: -f1) + version_prefix=$(echo "$lib" | cut -d: -f2) + lib_dir="$APPDIR/usr/optlib/$lib_filename" + lib_path="$lib_dir/$lib_filename" + if [ -e "$lib_path" ]; then + lib=$(PATH="/sbin:$PATH" ldconfig -p | grep "$lib_filename" | awk 'NR==1 {print $NF}') + sym_sys=$(tr '\0' '\n' < "$lib" | grep -e "$version_prefix" | tail -n1) + sym_app=$(tr '\0' '\n' < "$lib_path" | grep -e "$version_prefix" | tail -n1) + echo "[CheckRT] $lib_filename: sys: $sym_sys; app: $sym_app" + if [ z$(printf "$sym_sys\n$sym_app" | sort -V | tail -1) != z"$sym_sys" ]; then + _CRT_LIB_PATH="$lib_dir:$_CRT_LIB_PATH" + fi + fi +done + +for lib in ${_CRT_LIBS_PREFER_SYSTEM[@]}; do + lib_filename=$(echo "$lib" | cut -d: -f1) + version_prefix=$(echo "$lib" | cut -d: -f2) + lib_dir="$APPDIR/usr/optlib/$lib_filename" + lib_path="$lib_dir/$lib_filename" + if [ -e "$lib_path" ]; then + lib=$(PATH="/sbin:$PATH" ldconfig -p | grep "$lib_filename" | awk 'NR==1 {print $NF}') + sym_sys=$(tr '\0' '\n' < "$lib" | grep -e "$version_prefix" | tail -n1) + if [ -z "$sym_sys" ]; then + _CRT_LIB_PATH="$lib_dir:$_CRT_LIB_PATH" + else + echo "[CheckRT] Using system version of $lib_filename" + fi + fi +done + +export LD_LIBRARY_PATH="$_CRT_LIB_PATH:$LD_LIBRARY_PATH" + +if [ -e "$APPDIR/usr/optlib/exec.so" ]; then + export LD_PRELOAD="$APPDIR/usr/optlib/exec.so:$LD_PRELOAD" +fi + +echo "[CheckRT] LD_LIBRARY_PATH: $LD_LIBRARY_PATH" +echo "[CheckRT] LD_PRELOAD: $LD_PRELOAD" diff --git a/scripts/deps/xenial/gir1.2-soup-2.4_2.64.1-3_amd64.deb b/scripts/deps/xenial/gir1.2-soup-2.4_2.64.1-3_amd64.deb new file mode 100644 index 00000000..ef8d1e90 Binary files /dev/null and b/scripts/deps/xenial/gir1.2-soup-2.4_2.64.1-3_amd64.deb differ diff --git a/scripts/deps/xenial/gir1.2-soup-2.4_2.64.1-3_i386.deb b/scripts/deps/xenial/gir1.2-soup-2.4_2.64.1-3_i386.deb new file mode 100644 index 00000000..c1a1e4c4 Binary files /dev/null and b/scripts/deps/xenial/gir1.2-soup-2.4_2.64.1-3_i386.deb differ diff --git a/scripts/deps/xenial/libgssapi-krb5-2_1.16.1-1_amd64.deb b/scripts/deps/xenial/libgssapi-krb5-2_1.16.1-1_amd64.deb new file mode 100644 index 00000000..b5e6322b Binary files /dev/null and b/scripts/deps/xenial/libgssapi-krb5-2_1.16.1-1_amd64.deb differ diff --git a/scripts/deps/xenial/libgssapi-krb5-2_1.16.1-1_i386.deb b/scripts/deps/xenial/libgssapi-krb5-2_1.16.1-1_i386.deb new file mode 100644 index 00000000..f809672e Binary files /dev/null and b/scripts/deps/xenial/libgssapi-krb5-2_1.16.1-1_i386.deb differ diff --git a/scripts/deps/xenial/libk5crypto3_1.16.1-1_amd64.deb b/scripts/deps/xenial/libk5crypto3_1.16.1-1_amd64.deb new file mode 100644 index 00000000..fd6612cf Binary files /dev/null and b/scripts/deps/xenial/libk5crypto3_1.16.1-1_amd64.deb differ diff --git a/scripts/deps/xenial/libk5crypto3_1.16.1-1_i386.deb b/scripts/deps/xenial/libk5crypto3_1.16.1-1_i386.deb new file mode 100644 index 00000000..a8195271 Binary files /dev/null and b/scripts/deps/xenial/libk5crypto3_1.16.1-1_i386.deb differ diff --git a/scripts/deps/xenial/libkrb5-3_1.16.1-1_amd64.deb b/scripts/deps/xenial/libkrb5-3_1.16.1-1_amd64.deb new file mode 100644 index 00000000..3dd58819 Binary files /dev/null and b/scripts/deps/xenial/libkrb5-3_1.16.1-1_amd64.deb differ diff --git a/scripts/deps/xenial/libkrb5-3_1.16.1-1_i386.deb b/scripts/deps/xenial/libkrb5-3_1.16.1-1_i386.deb new file mode 100644 index 00000000..0993e99a Binary files /dev/null and b/scripts/deps/xenial/libkrb5-3_1.16.1-1_i386.deb differ diff --git a/scripts/deps/xenial/libkrb5support0_1.16.1-1_amd64.deb b/scripts/deps/xenial/libkrb5support0_1.16.1-1_amd64.deb new file mode 100644 index 00000000..5367889c Binary files /dev/null and b/scripts/deps/xenial/libkrb5support0_1.16.1-1_amd64.deb differ diff --git a/scripts/deps/xenial/libkrb5support0_1.16.1-1_i386.deb b/scripts/deps/xenial/libkrb5support0_1.16.1-1_i386.deb new file mode 100644 index 00000000..3d9cfb5a Binary files /dev/null and b/scripts/deps/xenial/libkrb5support0_1.16.1-1_i386.deb differ diff --git a/scripts/deps/xenial/libsoup2.4-1_2.64.1-3_amd64.deb b/scripts/deps/xenial/libsoup2.4-1_2.64.1-3_amd64.deb new file mode 100644 index 00000000..28051a61 Binary files /dev/null and b/scripts/deps/xenial/libsoup2.4-1_2.64.1-3_amd64.deb differ diff --git a/scripts/deps/xenial/libsoup2.4-1_2.64.1-3_i386.deb b/scripts/deps/xenial/libsoup2.4-1_2.64.1-3_i386.deb new file mode 100644 index 00000000..c4ea6afa Binary files /dev/null and b/scripts/deps/xenial/libsoup2.4-1_2.64.1-3_i386.deb differ diff --git a/scripts/deps/xenial/libsoup2.4-dev_2.64.1-3_amd64.deb b/scripts/deps/xenial/libsoup2.4-dev_2.64.1-3_amd64.deb new file mode 100644 index 00000000..a086e71d Binary files /dev/null and b/scripts/deps/xenial/libsoup2.4-dev_2.64.1-3_amd64.deb differ diff --git a/scripts/deps/xenial/libsoup2.4-dev_2.64.1-3_i386.deb b/scripts/deps/xenial/libsoup2.4-dev_2.64.1-3_i386.deb new file mode 100644 index 00000000..e7932329 Binary files /dev/null and b/scripts/deps/xenial/libsoup2.4-dev_2.64.1-3_i386.deb differ diff --git a/scripts/launchpad/dput.cf b/scripts/launchpad/dput.cf new file mode 100644 index 00000000..5f1e9d0d --- /dev/null +++ b/scripts/launchpad/dput.cf @@ -0,0 +1,41 @@ +[gamehub_bionic] +fqdn = ppa.launchpad.net +method = ftp +incoming = ~tkashkin/ubuntu/gamehub/bionic +login = anonymous +allow_unsigned_uploads = 1 + +[gamehub_xenial] +fqdn = ppa.launchpad.net +method = ftp +incoming = ~tkashkin/ubuntu/gamehub/xenial +login = anonymous +allow_unsigned_uploads = 1 + +[gamehub_cosmic] +fqdn = ppa.launchpad.net +method = ftp +incoming = ~tkashkin/ubuntu/gamehub/cosmic +login = anonymous +allow_unsigned_uploads = 1 + +[gamehub_disco] +fqdn = ppa.launchpad.net +method = ftp +incoming = ~tkashkin/ubuntu/gamehub/disco +login = anonymous +allow_unsigned_uploads = 1 + +[gamehub_eoan] +fqdn = ppa.launchpad.net +method = ftp +incoming = ~tkashkin/ubuntu/gamehub/eoan +login = anonymous +allow_unsigned_uploads = 1 + +[gamehub_focal] +fqdn = ppa.launchpad.net +method = ftp +incoming = ~tkashkin/ubuntu/gamehub/focal +login = anonymous +allow_unsigned_uploads = 1 diff --git a/scripts/launchpad/key_pub.gpg.enc b/scripts/launchpad/key_pub.gpg.enc new file mode 100644 index 00000000..ea8db355 Binary files /dev/null and b/scripts/launchpad/key_pub.gpg.enc differ diff --git a/scripts/launchpad/key_sec.gpg.enc b/scripts/launchpad/key_sec.gpg.enc new file mode 100644 index 00000000..6e6cc695 Binary files /dev/null and b/scripts/launchpad/key_sec.gpg.enc differ diff --git a/scripts/launchpad/passphrase.enc b/scripts/launchpad/passphrase.enc new file mode 100644 index 00000000..69f478e0 --- /dev/null +++ b/scripts/launchpad/passphrase.enc @@ -0,0 +1 @@ +ЀÂãB 9Bi \ No newline at end of file diff --git a/scripts/optlib/exec.so b/scripts/optlib/exec.so new file mode 100644 index 00000000..c8b4b408 Binary files /dev/null and b/scripts/optlib/exec.so differ diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml new file mode 100755 index 00000000..b4e768fd --- /dev/null +++ b/snap/snapcraft.yaml @@ -0,0 +1,64 @@ +name: gamehub +version: "0.6.0" +summary: Games manager written in Vala that supports GOG, Steam and Humble Bundle +description: | + Games manager/downloader/library written in Vala + Currently supported sources: Steam, GOG, Humble Bundle +icon: ../data/com.github.tkashkin.gamehub.svg +grade: stable +confinement: strict + +plugs: + gnome-3-26-1604: + interface: content + target: $SNAP/gnome-platform + default-provider: gnome-3-26-1604:gnome-3-26-1604 + gtk-3-themes: + interface: content + target: $SNAP/usr/share/themes + default-provider: gtk-common-themes:gtk-3-themes + icon-themes: + interface: content + target: $SNAP/usr/share/icons + default-provider: gtk-common-themes:icon-themes + sound-themes: + interface: content + target: $SNAP/usr/share/sounds + default-provider: gtk-common-themes:sounds-themes + +apps: + gamehub: + command: desktop-launch snapcraft-preload $SNAP/usr/bin/com.github.tkashkin.gamehub + desktop: usr/share/applications/com.github.tkashkin.gamehub.desktop + environment: + LD_LIBRARY_PATH: $SNAP/usr/lib/x86_64-linux-gnu/webkit2gtk-4.0/:$LD_LIBRARY_PATH + plugs: [network, network-observe, browser-support, gsettings, home, desktop, desktop-legacy, pulseaudio, opengl, x11, wayland, mir] + +parts: + gamehub: + source: .. + plugin: meson + meson-parameters: [--prefix=/usr, -Ddistro=generic, -Dsnap=true] + after: [desktop-gtk3, snapcraft-preload] + build-packages: + - build-essential + - meson + - libgtk-3-dev + - libglib2.0-dev + - libwebkit2gtk-4.0-dev + - libjson-glib-dev + - libgee-0.8-dev + - libsoup2.4-dev + - libsqlite3-dev + stage-packages: + - libgl1 + - binutils + - libwebkit2gtk-4.0-37 + - libcairo2 + - libgdk-pixbuf2.0-0 + - libglib2.0-0 + - libgstreamer1.0-0 + - libgtk-3-0 + - libjavascriptcoregtk-4.0-18 + - libpango-1.0-0 + - libsoup2.4-1 diff --git a/src/ProjectConfig.vala.in b/src/ProjectConfig.vala.in new file mode 100644 index 00000000..869e4025 --- /dev/null +++ b/src/ProjectConfig.vala.in @@ -0,0 +1,21 @@ +using Gtk; + +namespace GameHub.ProjectConfig +{ + public const string GETTEXT_PACKAGE = "@GETTEXT_PACKAGE@"; + public const string GETTEXT_DIR = "@GETTEXT_DIR@"; + + public const string PROJECT_NAME = "@PROJECT_NAME@"; + + public const string VERSION = "@VERSION@-@GIT_COMMIT_SHORT@-@GIT_BRANCH@"; + + public const string GIT_BRANCH = "@GIT_BRANCH@"; + public const string GIT_COMMIT_SHORT = "@GIT_COMMIT_SHORT@"; + public const string GIT_COMMIT = "@GIT_COMMIT@"; + + public const string PREFIX = "@PREFIX@"; + public const string DATADIR = "@DATADIR@"; + public const string BINDIR = "@BINDIR@"; + + public const string RUNTIME = "@RUNTIME@"; +} diff --git a/src/app.vala b/src/app.vala index dca176d4..9bb6a90d 100644 --- a/src/app.vala +++ b/src/app.vala @@ -1,50 +1,577 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + using Gtk; using Gdk; -using Granite; +using Gee; using GameHub.Data; +using GameHub.Data.DB; using GameHub.Data.Sources.Steam; using GameHub.Data.Sources.GOG; +using GameHub.Data.Sources.Humble; +using GameHub.Data.Sources.Itch; +using GameHub.Data.Sources.User; +using GameHub.Data.Tweaks; using GameHub.Utils; -[CCode(cname="GETTEXT_PACKAGE")] extern const string GETTEXT_PACKAGE; - namespace GameHub { - public class Application: Granite.Application + public class Application: Gtk.Application { + public static Application instance; + + public static bool log_auth = false; + public static bool log_downloader = false; + public static bool log_workers = false; + public static bool log_no_filters = false; + public static bool log_verbose = false; + + private static bool opt_help = false; + private static bool opt_debug_log = false; + private static bool opt_show_version = false; + + private static string? opt_run = null; + private static string? opt_game_details = null; + private static string? opt_game_properties = null; + + private static bool opt_show_compat = false; + private static bool opt_show = false; + private static bool opt_settings = false; + private static bool opt_about = false; + private static bool opt_gdb = false; + private static bool opt_gdb_bt_full = false; + private static bool opt_gdb_fatal_criticals = false; + + public static int worker_threads = -1; + + private GameHub.UI.Windows.MainWindow? main_window; + + public const string ACTION_PREFIX = "app."; + public const string ACTION_SETTINGS = "settings"; + public const string ACTION_ABOUT = "about"; + public const string ACTION_CORRUPTED_INSTALLER_PICK_ACTION = "corrupted-installer.pick-action"; + public const string ACTION_CORRUPTED_INSTALLER_SHOW = "corrupted-installer.show"; + public const string ACTION_CORRUPTED_INSTALLER_BACKUP = "corrupted-installer.backup"; + public const string ACTION_CORRUPTED_INSTALLER_REMOVE = "corrupted-installer.remove"; + public const string ACTION_GAME_RUN = "game.run"; + public const string ACTION_GAME_DETAILS = "game.details"; + public const string ACTION_GAME_PROPERTIES = "game.properties"; + + public const string ACCEL_SETTINGS = "S"; + + private const GLib.ActionEntry[] action_entries = { + { ACTION_SETTINGS, action_settings }, + { ACTION_ABOUT, action_about }, + { ACTION_CORRUPTED_INSTALLER_PICK_ACTION, action_corrupted_installer, "(ss)" }, + { ACTION_CORRUPTED_INSTALLER_SHOW, action_corrupted_installer, "(ss)" }, + { ACTION_CORRUPTED_INSTALLER_BACKUP, action_corrupted_installer, "(ss)" }, + { ACTION_CORRUPTED_INSTALLER_REMOVE, action_corrupted_installer, "(ss)" }, + { ACTION_GAME_RUN, action_game, "s" }, + { ACTION_GAME_DETAILS, action_game, "s" }, + { ACTION_GAME_PROPERTIES, action_game, "s" } + }; + + private const OptionEntry[] local_options = { + { "help", 'h', 0, OptionArg.NONE, out opt_help, N_("Show help"), null }, + { "version", 'v', 0, OptionArg.NONE, out opt_show_version, N_("Show application version and exit"), null }, + { "gdb", 0, 0, OptionArg.NONE, out opt_gdb, N_("Restart with GDB debugger attached"), null }, + { "gdb-bt-full", 0, 0, OptionArg.NONE, out opt_gdb_bt_full, N_("Show full GDB backtrace"), null }, + { "gdb-fatal-criticals", 0, 0, OptionArg.NONE, out opt_gdb_fatal_criticals, N_("Treat fatal errors as criticals and crash application"), null }, + { null } + }; + private const OptionEntry[] options = { + { "show", 's', 0, OptionArg.NONE, out opt_show, N_("Show main window"), null }, + { "settings", 0, 0, OptionArg.NONE, out opt_settings, N_("Show application settings dialog"), null }, + { "about", 0, 0, OptionArg.NONE, out opt_about, N_("Show about dialog"), null }, + { "worker-threads", 'j', 0, OptionArg.INT, out worker_threads, N_("Maximum number of background worker threads"), "THREADS" }, + { null } + }; + private const OptionEntry[] options_game = { + { "run", 'r', 0, OptionArg.STRING, out opt_run, N_("Run game"), "GAME" }, + { "show-compat", 'c', 0, OptionArg.NONE, out opt_show_compat, N_("Show compatibility options dialog"), null }, + { "details", 0, 0, OptionArg.STRING, out opt_game_details, N_("Open game details"), "GAME" }, + { "properties", 0, 0, OptionArg.STRING, out opt_game_properties, N_("Open game properties"), "GAME" }, + { null } + }; + private const OptionEntry[] options_log = { + { "debug", 'd', 0, OptionArg.NONE, out opt_debug_log, N_("Enable debug logging"), null }, + { "log-auth", 0, 0, OptionArg.NONE, out log_auth, N_("Log authentication process and sensitive information like authentication tokens"), null }, + { "log-downloader", 0, 0, OptionArg.NONE, out log_downloader, N_("Log download manager"), null }, + { "log-workers", 0, 0, OptionArg.NONE, out log_workers, N_("Log background workers start/stop"), null }, + { "log-no-filters", 0, 0, OptionArg.NONE, out log_no_filters, N_("Disable log messages filtering"), null }, + { "verbose", 0, 0, OptionArg.NONE, out log_verbose, N_("Verbose logging"), null }, + { null } + }; + construct { - application_id = "com.github.tkashkin.gamehub"; - flags = ApplicationFlags.FLAGS_NONE; - program_name = "GameHub"; + application_id = ProjectConfig.PROJECT_NAME; + flags = ApplicationFlags.HANDLES_COMMAND_LINE; + instance = this; + add_action_entries(action_entries, this); + set_accels_for_action(ACTION_PREFIX + ACTION_SETTINGS, { ACCEL_SETTINGS }); + } + + private const string[] THEME_SPECIFIC_STYLES = { "elementary" }; + private Screen screen; + private Gtk.Settings gtk_settings; + private HashMap theme_providers; + + private void init() + { + if(GameSources != null && CompatTools != null) return; + + FSUtils.make_dirs(); + ImageCache.init(); + Database.create(); + + GameSources = { new Steam(), new GOG(), new Humble(), new Trove(), new Itch(), new User() }; + + Providers.ImageProviders = { new Providers.Images.Steam(), new Providers.Images.SteamGridDB(), new Providers.Images.JinxSGVI() }; + Providers.DataProviders = { new Providers.Data.IGDB() }; + + var proton_latest = new Compat.Proton(Compat.Proton.LATEST); + + CompatTools = { new Compat.WineWrap(), new Compat.Innoextract(), new Compat.DOSBox(), new Compat.ScummVM(), proton_latest }; + + Compat.Proton.find_proton_versions(); + + CompatTool[] tools = CompatTools; + + string[] wine_binaries = { "wine"/*, "wine64", "wine32"*/ }; + string[] wine_arches = { "win64", "win32" }; + + foreach(var wine_binary in wine_binaries) + { + foreach(var wine_arch in wine_arches) + { + if(wine_binary == "wine32" && wine_arch == "win64") continue; + tools += new Compat.Wine(wine_binary, wine_arch); + } + } + + tools += new Compat.CustomEmulator(); + tools += new Compat.RetroArch(); + tools += new Compat.CustomScript(); + + CompatTools = tools; + + proton_latest.init(); + + IconTheme.get_default().add_resource_path("/com/github/tkashkin/gamehub/icons"); + + screen = Screen.get_default(); + + var app_provider = new CssProvider(); + app_provider.load_from_resource("/com/github/tkashkin/gamehub/css/app.css"); + StyleContext.add_provider_for_screen(screen, app_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); + + theme_providers = new HashMap(); + foreach(var theme in THEME_SPECIFIC_STYLES) + { + var provider = new CssProvider(); + provider.load_from_resource(@"/com/github/tkashkin/gamehub/css/themes/$(theme).css"); + theme_providers.set(theme, provider); + } + + gtk_settings = Gtk.Settings.get_for_screen(screen); + gtk_settings.notify["gtk-theme-name"].connect(gtk_theme_handler); + gtk_theme_handler(); + } + + private void gtk_theme_handler() + { + foreach(var provider in theme_providers.values) + { + StyleContext.remove_provider_for_screen(screen, provider); + } + if(theme_providers.has_key(gtk_settings.gtk_theme_name)) + { + StyleContext.add_provider_for_screen(screen, theme_providers.get(gtk_settings.gtk_theme_name), Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); + } } protected override void activate() { - weak IconTheme default_theme = IconTheme.get_default(); - default_theme.add_resource_path("/com/github/tkashkin/gamehub/icons"); - - var provider = new CssProvider(); - provider.load_from_resource("/com/github/tkashkin/gamehub/GameHub.css"); - StyleContext.add_provider_for_screen(Screen.get_default(), provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); - - new GameHub.UI.Windows.MainWindow(this).show_all(); + if(main_window == null) + { + print_version(false); + init(); + + #if MANETTE + GameHub.Utils.Gamepad.init(); + #endif + + main_window = new GameHub.UI.Windows.MainWindow(this); + main_window.show_all(); + } } public static int main(string[] args) { - Ivy.Stacktrace.register_handlers(); - - Intl.setlocale(LocaleCategory.ALL, ""); - Intl.textdomain(GETTEXT_PACKAGE); - - FSUtils.make_dirs(); - - GameSources = { new Steam(), new GOG() }; - + #if MANETTE + X.init_threads(); + #endif + var app = new Application(); + + Utils.Logger.init(); + + var lang = Environment.get_variable("LC_ALL") ?? ""; + Intl.setlocale(LocaleCategory.ALL, lang); + Intl.bindtextdomain(ProjectConfig.GETTEXT_PACKAGE, ProjectConfig.GETTEXT_DIR); + Intl.bind_textdomain_codeset(ProjectConfig.GETTEXT_PACKAGE, "UTF-8"); + Intl.textdomain(ProjectConfig.GETTEXT_PACKAGE); + return app.run(args); } + + private OptionGroup get_game_option_group() + { + var group = new OptionGroup("game", _("Game Options:"), _("Show game options help")); + group.add_entries(options_game); + group.set_translation_domain(ProjectConfig.GETTEXT_PACKAGE); + return group; + } + + private OptionGroup get_log_option_group() + { + var group = new OptionGroup("log", _("Logging Options:"), _("Show logging options help")); + group.add_entries(options_log); + group.set_translation_domain(ProjectConfig.GETTEXT_PACKAGE); + return group; + } + + public override bool local_command_line(ref weak string[] arguments, out int exit_status) + { + OptionContext local_option_context = new OptionContext(); + local_option_context.set_ignore_unknown_options(true); + local_option_context.set_help_enabled(false); + local_option_context.add_main_entries(local_options, ProjectConfig.GETTEXT_PACKAGE); + local_option_context.add_group(get_log_option_group()); + local_option_context.set_translation_domain(ProjectConfig.GETTEXT_PACKAGE); + + try + { + unowned string[] args = arguments; + local_option_context.parse(ref args); + } + catch(Error e) + { + warning(e.message); + } + + if(opt_show_version) + { + print_version(true); + exit_status = 0; + return true; + } + + if(opt_help) + { + OptionContext help_option_context = new OptionContext(); + help_option_context.set_help_enabled(false); + help_option_context.add_main_entries(local_options, ProjectConfig.GETTEXT_PACKAGE); + help_option_context.add_main_entries(options, ProjectConfig.GETTEXT_PACKAGE); + help_option_context.add_group(get_game_option_group()); + help_option_context.add_group(get_log_option_group()); + help_option_context.add_group(Gtk.get_option_group(true)); + help_option_context.set_translation_domain(ProjectConfig.GETTEXT_PACKAGE); + print(help_option_context.get_help(false, null)); + exit_status = 0; + return true; + } + + Logger.DisplayLevel = opt_debug_log ? Logger.LogLevel.DEBUG : Logger.LogLevel.INFO; + + if(opt_gdb || opt_gdb_bt_full || opt_gdb_fatal_criticals) + { + string[] current_args = arguments; + string[] cmd_args = {}; + for(int i = 1; i < current_args.length; i++) + { + var arg = current_args[i]; + if(arg != "--gdb" && arg != "--gdb-bt-full" && arg != "--gdb-fatal-criticals") + { + cmd_args += arg; + } + } + if(!("--debug" in cmd_args) && !("-d" in cmd_args)) + { + cmd_args += "--debug"; + } + string cmd_args_string = string.joinv(" ", cmd_args); + + string[] exec_cmd = { + "gdb", "-q", "--batch", + "-ex", @"set args $cmd_args_string", + "-ex", (opt_gdb_fatal_criticals ? "set env G_DEBUG = fatal-criticals" : "unset env G_DEBUG"), + "-ex", "set pagination off", + "-ex", "handle SIGHUP nostop pass", + "-ex", "handle SIGQUIT nostop pass", + "-ex", "handle SIGPIPE nostop pass", + "-ex", "handle SIGALRM nostop pass", + "-ex", "handle SIGTERM nostop pass", + "-ex", "handle SIGUSR1 nostop pass", + "-ex", "handle SIGUSR2 nostop pass", + "-ex", "handle SIGCHLD nostop pass", + "-ex", "set print thread-events off", + "-ex", "run", + "-ex", "thread apply all bt" + (opt_gdb_bt_full ? " full" : ""), + current_args[0] + }; + + info("Restarting with GDB"); + Utils.run(exec_cmd).dir(Environment.get_current_dir()).run_sync(); + exit_status = 0; + return true; + } + + return base.local_command_line(ref arguments, out exit_status); + } + + public override int command_line(ApplicationCommandLine cmd) + { + string[] oargs = cmd.get_arguments(); + unowned string[] args = oargs; + + var option_context = new OptionContext(); + option_context.add_main_entries(options, ProjectConfig.GETTEXT_PACKAGE); + option_context.add_group(get_game_option_group()); + option_context.add_group(get_log_option_group()); + option_context.add_group(Gtk.get_option_group(true)); + option_context.set_translation_domain(ProjectConfig.GETTEXT_PACKAGE); + + try + { + option_context.parse(ref args); + } + catch(Error e) + { + warning(e.message); + } + + Logger.DisplayLevel = opt_debug_log ? Logger.LogLevel.DEBUG : Logger.LogLevel.INFO; + + init(); + + if(opt_show || (opt_run == null && opt_game_details == null && opt_game_properties == null)) + { + activate(); + main_window.present(); + } + + if(opt_settings) + { + activate_action(ACTION_SETTINGS, null); + } + + if(opt_about) + { + activate_action(ACTION_ABOUT, null); + } + + if(opt_run != null) + { + activate_action(ACTION_GAME_RUN, new Variant.string(opt_run)); + } + + if(opt_game_details != null) + { + activate_action(ACTION_GAME_DETAILS, new Variant.string(opt_game_details)); + } + + if(opt_game_properties != null) + { + activate_action(ACTION_GAME_PROPERTIES, new Variant.string(opt_game_properties)); + } + + opt_run = null; + opt_game_details = null; + opt_game_properties = null; + + opt_show_compat = false; + opt_show = false; + opt_settings = false; + + return 0; + } + + [PrintfFormat] + private void println(bool plain, string format, ...) + { + var line = format.vprintf(va_list()); + if(plain) + { + print(line + "\n"); + } + else + { + info(line); + } + } + + private void print_version(bool plain) + { + println(plain, "- GameHub"); + println(plain, " Version: %s", ProjectConfig.VERSION); + println(plain, " Branch: %s", ProjectConfig.GIT_BRANCH); + if(ProjectConfig.GIT_COMMIT != null && ProjectConfig.GIT_COMMIT.length > 0) + { + println(plain, " Commit: %s", ProjectConfig.GIT_COMMIT); + } + + println(plain, "- Environment"); + #if OS_LINUX + println(plain, " Distro: %s", Utils.get_distro()); + println(plain, " DE: %s", Utils.get_desktop_environment() ?? "unknown"); + #else + println(plain, " OS: %s", Utils.get_distro()); + #endif + println(plain, " GTK: %u.%u.%u", Gtk.get_major_version(), Gtk.get_minor_version(), Gtk.get_micro_version()); + + var settings = Gtk.Settings.get_default(); + if(settings != null) + { + println(plain, " Themes: %s | %s", settings.gtk_theme_name, settings.gtk_icon_theme_name); + } + } + + private static void action_settings(SimpleAction action, Variant? args) + { + new GameHub.UI.Dialogs.SettingsDialog.SettingsDialog(); + } + + private static void action_about(SimpleAction action, Variant? args) + { + new GameHub.UI.Dialogs.SettingsDialog.SettingsDialog("about"); + } + + private static void action_corrupted_installer(SimpleAction action, Variant? args) + { + if(args == null) return; + + var args_iter = args.iterator(); + string? game_id = null; + string? path = null; + args_iter.next("s", &game_id); + args_iter.next("s", &path); + + if(game_id == null || path == null) return; + + var file = FSUtils.file(path); + if(file == null || !file.query_exists()) return; + try + { + switch(action.name) + { + case ACTION_CORRUPTED_INSTALLER_PICK_ACTION: + game_id = game_id.strip(); + if(game_id.length > 0 && ":" in game_id) + { + var id_parts = game_id.split(":"); + var game = GameHub.Data.DB.Tables.Games.get(id_parts[0], id_parts[1]); + if(game != null) + { + var loop = new MainLoop(); + var dlg = new UI.Dialogs.CorruptedInstallerDialog(game, file); + dlg.destroy.connect(() => { + loop.quit(); + }); + loop.run(); + } + } + break; + + case ACTION_CORRUPTED_INSTALLER_SHOW: + Utils.open_uri(file.get_parent().get_uri()); + break; + + case ACTION_CORRUPTED_INSTALLER_BACKUP: + file.move(FSUtils.file(path + ".backup"), FileCopyFlags.BACKUP); + break; + + case ACTION_CORRUPTED_INSTALLER_REMOVE: + file.delete(); + break; + } + } + catch(Error e) + { + warning("[app.installer_action] %s", e.message); + } + } + + private static void action_game(SimpleAction action, Variant? args) + { + if(args == null) return; + string? game_id = args.get_string(); + if(game_id == null) return; + + game_id = game_id.strip(); + if(game_id.length > 0 && ":" in game_id) + { + var id_parts = game_id.split(":"); + var game = GameHub.Data.DB.Tables.Games.get(id_parts[0], id_parts[1]); + if(game != null) + { + var loop = new MainLoop(); + game.update_game_info.begin((obj, res) => { + game.update_game_info.end(res); + switch(action.name) + { + case ACTION_GAME_RUN: + info("Starting `%s`", game.name); + game.run_or_install.begin(opt_show_compat, (obj, res) => { + game.run_or_install.end(res); + info("`%s` finished", game.name); + loop.quit(); + }); + break; + + case ACTION_GAME_DETAILS: + var dlg = new UI.Dialogs.GameDetailsDialog(game); + dlg.destroy.connect(() => { + loop.quit(); + }); + break; + + case ACTION_GAME_PROPERTIES: + var dlg = new UI.Dialogs.GamePropertiesDialog(game); + dlg.destroy.connect(() => { + loop.quit(); + }); + break; + } + }); + loop.run(); + } + else + { + error("Game with id `%s` from source `%s` is not found", id_parts[1], id_parts[0]); + } + } + else + { + error("`%s` is not a fully-qualified game id", opt_run); + } + } } } diff --git a/src/data/CompatTool.vala b/src/data/CompatTool.vala new file mode 100644 index 00000000..27d9e8b4 --- /dev/null +++ b/src/data/CompatTool.vala @@ -0,0 +1,166 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; + +using GameHub.Utils; + +namespace GameHub.Data +{ + public abstract class CompatTool: Object + { + public string id { get; protected set; default = "null"; } + public string name { get; protected set; default = ""; } + public string icon { get; protected set; default = "application-x-executable-symbolic"; } + public File? executable { get; protected set; default = null; } + public bool installed { get; protected set; default = false; } + + public Option[]? options = null; + public Option[]? install_options = null; + public Action[]? actions = null; + + public string[]? warnings = null; + + public virtual bool can_install(Runnable runnable) { return false; } + public virtual bool can_run(Runnable runnable) { return false; } + public virtual bool can_run_action(Runnable runnable, Runnable.RunnableAction action) { return false; } + + public virtual File get_install_root(Runnable runnable) { return runnable.install_dir; } + + public virtual async void install(Runnable runnable, File installer){} + public virtual async void run(Runnable game){} + public virtual async void run_action(Runnable runnable, Runnable.RunnableAction action){} + public virtual async void run_emulator(Emulator emu, Game? game, bool launch_in_game_dir=false){} + + protected string[] combine_cmd_with_args(string[] cmd, Runnable runnable, string[]? args_override=null) + { + string[] full_cmd = cmd; + + var args = args_override ?? Utils.parse_args(runnable.arguments); + if(args != null) + { + if("$command" in args || "${command}" in args) + { + full_cmd = {}; + } + + var variables = new HashMap(); + variables.set("game", runnable.name.replace(": ", " - ").replace(":", "")); + variables.set("game_dir", runnable.install_dir.get_path()); + + foreach(var arg in args) + { + if(arg == "$command" || arg == "${command}") + { + foreach(var a in cmd) + { + full_cmd += a; + } + } + else + { + if("$" in arg) + { + arg = FSUtils.expand(arg, null, variables); + } + full_cmd += arg; + } + } + } + + return full_cmd; + } + + public static CompatTool? by_id(string? id) + { + foreach(var tool in CompatTools) + { + if(tool.id == id) + { + return tool; + } + } + return null; + } + + public abstract class Option: Object + { + public string name { get; construct; } + public string description { get; construct; } + } + + public class BoolOption: Option + { + public bool enabled { get; construct set; } + public BoolOption(string name, string description, bool enabled) + { + Object(name: name, description: description, enabled: enabled); + } + } + + public class StringOption: Option + { + public string? value { get; construct set; } + public string? icon { get; set; default = null; } + public StringOption(string name, string description, string? value) + { + Object(name: name, description: description, value: value); + } + } + + public class FileOption: Option + { + public File? directory { get; construct set; } + public File? file { get; construct set; } + public Gtk.FileChooserAction mode { get; construct set; } + public string? icon { get; set; default = null; } + public FileOption(string name, string description, File? directory, File? file, Gtk.FileChooserAction mode=Gtk.FileChooserAction.OPEN) + { + Object(name: name, description: description, directory: directory, file: file, mode: mode); + } + } + + public class ComboOption: StringOption + { + public ArrayList options { get; construct set; } + public ComboOption(string name, string description, ArrayList options, string? value) + { + Object(name: name, description: description, options: options, value: value); + } + } + + public class Action: Object + { + public delegate void Delegate(Runnable runnable); + public string name { get; construct; } + public string description { get; construct; } + private Delegate action; + public Action(string name, string description, owned Delegate action) + { + Object(name: name, description: description); + this.action = (owned) action; + } + public void invoke(Runnable runnable) + { + action(runnable); + } + } + } + + public static CompatTool[] CompatTools; +} diff --git a/src/data/Emulator.vala b/src/data/Emulator.vala new file mode 100644 index 00000000..ac9dd38d --- /dev/null +++ b/src/data/Emulator.vala @@ -0,0 +1,255 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; +using GameHub.Data.DB; +using GameHub.Utils; + +namespace GameHub.Data +{ + public class Emulator: Runnable + { + private bool is_removed = false; + public signal void removed(); + + public override File? executable { owned get; set; } + public override File? work_dir { owned get; set; } + public Installer? installer; + + public string? game_executable_pattern { get; set; } + public string? game_image_pattern { get; set; } + public string? game_icon_pattern { get; set; } + + public Emulator.empty(){} + + public Emulator(string name, File dir, File exec, string args, string? compat=null) + { + this.name = name; + + install_dir = dir; + work_dir = dir; + + executable = exec; + arguments = args; + + compat_tool = compat; + force_compat = compat != null; + + update_status(); + } + + public Emulator.from_db(Sqlite.Statement s) + { + id = Tables.Emulators.ID.get(s); + name = Tables.Emulators.NAME.get(s); + install_dir = FSUtils.file(Tables.Emulators.INSTALL_PATH.get(s)); + work_dir = FSUtils.file(Tables.Emulators.WORK_DIR.get(s)); + executable = FSUtils.file(Tables.Emulators.EXECUTABLE.get(s)); + compat_tool = Tables.Emulators.COMPAT_TOOL.get(s); + compat_tool_settings = Tables.Emulators.COMPAT_TOOL_SETTINGS.get(s); + arguments = Tables.Emulators.ARGUMENTS.get(s); + game_executable_pattern = Tables.Emulators.GAME_EXECUTABLE_PATTERN.get(s); + game_image_pattern = Tables.Emulators.GAME_IMAGE_PATTERN.get(s); + game_icon_pattern = Tables.Emulators.GAME_ICON_PATTERN.get(s); + + update_status(); + } + + public void remove() + { + is_removed = true; + Tables.Emulators.remove(this); + removed(); + } + + public override void save() + { + update_status(); + + if(is_removed || name == null || executable == null) return; + + Tables.Emulators.add(this); + } + + public override void update_status() + { + if(is_removed || name == null || executable == null) return; + + id = Utils.md5(name); + + platforms.clear(); + platforms.add(Platform.LINUX); + } + + public override async void install(Runnable.Installer.InstallMode install_mode=Runnable.Installer.InstallMode.INTERACTIVE) + { + update_status(); + if(installer == null || install_dir == null) return; + var installers = new ArrayList(); + installers.add(installer); + new GameHub.UI.Dialogs.InstallDialog(this, installers, install_mode, install.callback); + yield; + } + + public string[] get_args(Game? game=null, File? exec=null) + { + string[] result_args = {}; + + if(exec != null) + { + result_args += exec.get_path(); + } + + if(arguments != null && arguments.length > 0) + { + var variables = new HashMap(); + variables.set("emu", name.replace(": ", " - ").replace(":", "")); + variables.set("emu_dir", install_dir.get_path()); + if(game != null) + { + variables.set("game", game.name.replace(": ", " - ").replace(":", "")); + variables.set("file", game.executable.get_path()); + variables.set("game_dir", game.install_dir.get_path()); + } + else + { + variables.set("game", ""); + variables.set("file", ""); + variables.set("game_dir", ""); + } + var args = Utils.parse_args(arguments); + if(args != null) + { + if(exec != null && ("$command" in args || "${command}" in args)) + { + result_args = {}; + variables.set("command", exec.get_path()); + } + foreach(var arg in args) + { + if(arg == "$game_args" || arg == "${game_args}") + { + if(game != null) + { + var game_args = Utils.parse_args(game.arguments); + if(game_args != null) + { + foreach(var game_arg in game_args) + { + result_args += game_arg; + } + } + } + continue; + } + if("$" in arg) + { + arg = FSUtils.expand(arg, null, variables); + } + result_args += arg; + } + } + } + + return result_args; + } + + public override async void run() + { + if(can_be_launched(true) && executable.query_exists()) + { + Runnable.IsLaunched = is_running = true; + + yield Utils.run(get_args(null, executable)).dir(work_dir.get_path()).override_runtime(true).run_sync_thread(); + + Timeout.add_seconds(1, () => { + Runnable.IsLaunched = is_running = false; + return Source.REMOVE; + }); + } + } + + public async void run_game(Game? game, bool launch_in_game_dir=false) + { + if(use_compat) + { + yield run_game_compat(game, launch_in_game_dir); + return; + } + + if(executable.query_exists()) + { + Runnable.IsLaunched = is_running = true; + + if(game != null) + { + game.is_running = true; + game.update_status(); + } + + var dir = game != null && launch_in_game_dir ? game.work_dir : work_dir; + + var task = Utils.run(get_args(game, executable)).dir(dir.get_path()).override_runtime(true); + if(game != null && game is TweakableGame) + { + task.tweaks(((TweakableGame) game).get_enabled_tweaks()); + } + yield task.run_sync_thread(); + + Timeout.add_seconds(1, () => { + Runnable.IsLaunched = is_running = false; + if(game != null) + { + game.is_running = false; + game.update_status(); + } + return Source.REMOVE; + }); + } + } + + public async void run_game_compat(Game? game, bool launch_in_game_dir=false) + { + new UI.Dialogs.CompatRunDialog(this, false, game, launch_in_game_dir); + } + + public static bool is_equal(Emulator first, Emulator second) + { + return first == second || first.id == second.id; + } + + public static uint hash(Emulator emu) + { + return str_hash(emu.id); + } + + public class Installer: Runnable.FileInstaller + { + private string emu_name; + public override string name { owned get { return emu_name; } } + + public Installer(Emulator emu, File installer) + { + emu_name = emu.name; + id = "installer"; + platform = installer.get_path().down().has_suffix(".exe") ? Platform.WINDOWS : Platform.LINUX; + file = installer; + } + } + } +} diff --git a/src/data/Game.vala b/src/data/Game.vala index 3ef5f2ab..b06f43eb 100644 --- a/src/data/Game.vala +++ b/src/data/Game.vala @@ -1,22 +1,694 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; using Gtk; +using GameHub.Utils; +using GameHub.Data.DB; +using GameHub.Data.Tweaks; + namespace GameHub.Data { - public abstract class Game + public abstract class Game: Runnable { public GameSource source { get; protected set; } - - public string id { get; protected set; } - public string name { get; protected set; } - - public string icon { get; protected set; } - public string image { get; protected set; } - - public string path { get; protected set; } - public string command { get; protected set; } - - public float playtime { get; protected set; default = 0; } - - public virtual async bool is_for_linux(){ return true; } + + public string description { get; protected set; } + + public string? icon { get; set; } + public string? image { get; set; } + public string? image_vertical { get; set; } + + public string? info { get; protected set; } + public string? info_detailed { get; protected set; } + + public string full_id { owned get { return source.id + ":" + id; } } + + public string? version { get; protected set; } + + public ArrayList tags { get; protected set; default = new ArrayList(Tables.Tags.Tag.is_equal); } + public bool has_tag(Tables.Tags.Tag tag) + { + return has_tag_id(tag.id); + } + public bool has_tag_id(string tag) + { + foreach(var t in tags) + { + if(t.id == tag) return true; + } + return false; + } + public void add_tag(Tables.Tags.Tag tag) + { + if(!tags.contains(tag)) + { + tags.add(tag); + } + if(!(tag in Tables.Tags.DYNAMIC_TAGS)) + { + save(); + status_change(_status); + tags_update(); + } + } + public void remove_tag(Tables.Tags.Tag tag) + { + if(tags.contains(tag)) + { + tags.remove(tag); + } + if(!(tag in Tables.Tags.DYNAMIC_TAGS)) + { + save(); + status_change(_status); + tags_update(); + } + } + public void toggle_tag(Tables.Tags.Tag tag) + { + if(tags.contains(tag)) + { + remove_tag(tag); + } + else + { + add_tag(tag); + } + } + + public override void save() + { + Tables.Games.add(this); + } + + public File? installers_dir { get; protected set; default = null; } + public bool is_installable { get; protected set; default = true; } + + public string? store_page { get; protected set; default = null; } + + public int64 last_launch { get; set; default = 0; } + + public abstract async void uninstall(); + + public override async void run() + { + if(can_be_launched(true) && executable.query_exists()) + { + Runnable.IsLaunched = is_running = true; + update_status(); + + string[] cmd = { executable.get_path() }; + + if(arguments != null && arguments.length > 0) + { + var variables = new HashMap(); + variables.set("game", name.replace(": ", " - ").replace(":", "")); + variables.set("game_dir", install_dir.get_path()); + var args = Utils.parse_args(arguments); + if(args != null) + { + if("$command" in args || "${command}" in args) + { + cmd = {}; + variables.set("command", executable.get_path()); + } + foreach(var arg in args) + { + if("$" in arg) + { + arg = FSUtils.expand(arg, null, variables); + } + cmd += arg; + } + } + } + + last_launch = get_real_time() / 1000000; + save(); + + var task = Utils.run(cmd).dir(work_dir.get_path()).override_runtime(true); + if(this is TweakableGame) + { + task.tweaks(((TweakableGame) this).get_enabled_tweaks()); + } + yield task.run_sync_thread(); + + playtime_tracked += ((get_real_time() / 1000000) - last_launch) / 60; + save(); + + Timeout.add_seconds(1, () => { + Runnable.IsLaunched = is_running = false; + update_status(); + return Source.REMOVE; + }); + } + } + + public async void run_or_install(bool show_compat=false) + { + if(status.state == Game.State.INSTALLED) + { + if(use_compat) + { + yield run_with_compat(show_compat); + } + else + { + yield run(); + } + } + else if(status.state == Game.State.UNINSTALLED) + { + yield install(); + } + } + + public virtual async void update_game_info(){} + + protected void update_version() + { + if(install_dir == null || !install_dir.query_exists()) return; + + var file = install_dir.get_child(FSUtils.GAMEHUB_DIR).get_child("version"); + if(file != null && file.query_exists()) + { + try + { + string ver; + FileUtils.get_contents(file.get_path(), out ver); + version = ver; + } + catch(Error e) + { + warning("[Game.update_version] Error while reading version: %s", e.message); + } + } + } + + public void save_version(string ver) + { + version = ver; + + if(install_dir == null || !install_dir.query_exists()) return; + + var file = install_dir.get_child(FSUtils.GAMEHUB_DIR).get_child("version"); + if(file != null) + { + try + { + FSUtils.mkdir(file.get_parent().get_path()); + FileUtils.set_contents(file.get_path(), ver); + } + catch(Error e) + { + warning("[Game.update_version] Error while reading version: %s", e.message); + } + } + } + + protected Game.Status _status = new Game.Status(Game.State.UNINSTALLED, null, null); + public signal void status_change(Game.Status status); + public signal void tags_update(); + + public Game.Status status + { + get { return _status; } + set { _status = value; status_change(_status); } + } + + public int64 playtime_source { get; set; default = 0; } + public int64 playtime_tracked { get; set; default = 0; } + + public int64 playtime { get { return playtime_source + playtime_tracked; } } + + public ArrayList overlays = new ArrayList(); + private FSOverlay? fs_overlay; + private string? fs_overlay_last_options; + + public File? get_file(string? p, bool from_all_overlays=true) + { + if(p == null || p.length == 0 || install_dir == null) return null; + var path = p; + if(!path.has_prefix("$game_dir/") && !path.has_prefix("/")) + { + path = "$game_dir/" + path; + } + File[] dirs = { install_dir }; + if(overlays_enabled) + { + if(from_all_overlays) + { + dirs = { + install_dir.get_child(FSUtils.GAMEHUB_DIR).get_child("_overlay").get_child("merged"), + install_dir.get_child(FSUtils.GAMEHUB_DIR).get_child(FSUtils.OVERLAYS_DIR).get_child(Overlay.BASE), + install_dir + }; + foreach(var overlay in overlays) + { + if(overlay.id == Overlay.BASE) continue; + dirs += install_dir.get_child(FSUtils.GAMEHUB_DIR).get_child(FSUtils.OVERLAYS_DIR).get_child(overlay.id); + } + } + mount_overlays.begin(); + } + var variables = new HashMap(); + foreach(var dir in dirs) + { + variables.set("game_dir", dir.get_path()); + var file = FSUtils.file(path, null, variables); + if(file != null && file.query_exists()) + { + return file; + } + } + return null; + } + + public string? executable_path; + public override File? executable + { + owned get + { + if(executable_path == null || executable_path.length == 0 || install_dir == null) return null; + return get_file(executable_path); + } + set + { + if(value != null && value.query_exists() && install_dir != null && install_dir.query_exists()) + { + File[] dirs = { install_dir }; + if(overlays_enabled) + { + dirs = { + install_dir.get_child(FSUtils.GAMEHUB_DIR).get_child("_overlay").get_child("merged"), + install_dir.get_child(FSUtils.GAMEHUB_DIR).get_child(FSUtils.OVERLAYS_DIR).get_child(Overlay.BASE), + install_dir + }; + } + foreach(var dir in dirs) + { + if(value.get_path().has_prefix(dir.get_path())) + { + executable_path = value.get_path().replace(dir.get_path(), "$game_dir"); + break; + } + } + } + else + { + executable_path = null; + } + save(); + } + } + + public string? work_dir_path; + public override File? work_dir + { + owned get + { + if(install_dir == null) return null; + if(work_dir_path == null || work_dir_path.length == 0) return install_dir; + return get_file(work_dir_path); + } + set + { + if(value != null && value.query_exists() && install_dir != null && install_dir.query_exists()) + { + File[] dirs = { install_dir }; + if(overlays_enabled) + { + dirs = { + install_dir.get_child(FSUtils.GAMEHUB_DIR).get_child("_overlay").get_child("merged"), + install_dir.get_child(FSUtils.GAMEHUB_DIR).get_child(FSUtils.OVERLAYS_DIR).get_child(Overlay.BASE), + install_dir + }; + } + foreach(var dir in dirs) + { + if(value.get_path().has_prefix(dir.get_path())) + { + work_dir_path = value.get_path().replace(dir.get_path(), "$game_dir/"); + break; + } + } + } + else + { + work_dir_path = null; + } + save(); + } + } + + public bool overlays_enabled + { + get + { + if(this is Sources.GOG.GOGGame.DLC && ((Sources.GOG.GOGGame.DLC) this).game != null) return ((Sources.GOG.GOGGame.DLC) this).game.overlays_enabled; + if(this is Sources.Steam.SteamGame) return false; + if(FSOverlay.RootPathSafety.for(install_dir) == FSOverlay.RootPathSafety.RESTRICTED) return false; + return install_dir != null && install_dir.query_exists() + && install_dir.get_child(FSUtils.GAMEHUB_DIR).get_child(FSUtils.OVERLAYS_DIR).get_child(FSUtils.OVERLAYS_LIST).query_exists(); + } + } + + public void enable_overlays() + { + if(this is Sources.GOG.GOGGame.DLC) + { + if(((Sources.GOG.GOGGame.DLC) this).game != null) ((Sources.GOG.GOGGame.DLC) this).game.enable_overlays(); + return; + } + + if(this is Sources.Steam.SteamGame || install_dir == null || !install_dir.query_exists() || overlays_enabled) return; + if(FSOverlay.RootPathSafety.for(install_dir) == FSOverlay.RootPathSafety.RESTRICTED) return; + + var base_overlay = new Overlay(this); + + try + { + FileInfo? finfo = null; + var enumerator = install_dir.enumerate_children("standard::*", FileQueryInfoFlags.NOFOLLOW_SYMLINKS); + while((finfo = enumerator.next_file()) != null) + { + var fname = finfo.get_name(); + if(fname == FSUtils.GAMEHUB_DIR) continue; + install_dir.get_child(fname).move(base_overlay.directory.get_child(fname), FileCopyFlags.OVERWRITE | FileCopyFlags.NOFOLLOW_SYMLINKS); + } + } + catch(Error e) + { + warning("[Game.enable_overlays] Error while moving game files to `base` overlay: %s", e.message); + } + + overlays.add(base_overlay); + save_overlays(); + save(); + } + + public void save_overlays() + { + if(this is Sources.GOG.GOGGame.DLC) + { + if(((Sources.GOG.GOGGame.DLC) this).game != null) ((Sources.GOG.GOGGame.DLC) this).game.save_overlays(); + return; + } + + if(install_dir == null || !install_dir.query_exists() || overlays == null) return; + if(FSOverlay.RootPathSafety.for(install_dir) == FSOverlay.RootPathSafety.RESTRICTED) return; + + var file = install_dir.get_child(FSUtils.GAMEHUB_DIR).get_child(FSUtils.OVERLAYS_DIR).get_child(FSUtils.OVERLAYS_LIST); + + if(file == null || !file.get_parent().query_exists()) return; + + var root_node = new Json.Node(Json.NodeType.OBJECT); + var root = new Json.Object(); + + var overlays_obj = new Json.Object(); + + foreach(var overlay in overlays) + { + if(overlay.id == Overlay.BASE) continue; + var obj = new Json.Object(); + obj.set_string_member("name", overlay.name); + obj.set_boolean_member("enabled", overlay.enabled); + overlays_obj.set_object_member(overlay.id, obj); + } + + root.set_object_member("overlays", overlays_obj); + root_node.set_object(root); + + var json = Json.to_string(root_node, true); + + try + { + FileUtils.set_contents(file.get_path(), json); + } + catch(Error e) + { + warning("[Game.save_overlays] %s", e.message); + } + + notify_property("overlays-enabled"); + } + + public void load_overlays() + { + if(this is Sources.GOG.GOGGame.DLC) + { + if(((Sources.GOG.GOGGame.DLC) this).game != null) ((Sources.GOG.GOGGame.DLC) this).game.load_overlays(); + return; + } + + if(!overlays_enabled) return; + overlays.clear(); + overlays.add(new Overlay(this)); + + var root_node = Parser.parse_json_file(install_dir.get_child(FSUtils.GAMEHUB_DIR).get_child(FSUtils.OVERLAYS_DIR).get_child(FSUtils.OVERLAYS_LIST).get_path()); + + var overlays_obj = Parser.json_object(root_node, {"overlays"}); + if(overlays_obj == null) return; + + foreach(var id in overlays_obj.get_members()) + { + var obj = overlays_obj.get_object_member(id); + overlays.add(new Overlay(this, id, obj.get_string_member("name"), obj.get_boolean_member("enabled"))); + } + } + + public async void mount_overlays(File? persist=null) + { + if(this is Sources.GOG.GOGGame.DLC) + { + if(((Sources.GOG.GOGGame.DLC) this).game != null) yield ((Sources.GOG.GOGGame.DLC) this).game.mount_overlays(persist); + return; + } + + if(!overlays_enabled) return; + load_overlays(); + + var overlay_dir = install_dir.get_child(FSUtils.GAMEHUB_DIR).get_child("_overlay"); + var merged_dir = overlay_dir.get_child("merged"); + var persist_dir = persist ?? overlay_dir.get_child("persist"); + var work_dir = overlay_dir.get_child("workdir"); + + var dirs = new ArrayList(); + + foreach(var overlay in overlays) + { + if(overlay.enabled) + { + dirs.add(overlay.directory); + } + } + + fs_overlay = new FSOverlay(merged_dir, dirs, persist_dir, work_dir); + if(fs_overlay.options != fs_overlay_last_options) + { + fs_overlay_last_options = fs_overlay.options; + yield fs_overlay.mount(); + } + } + + public async void umount_overlays() + { + if(this is Sources.GOG.GOGGame.DLC) + { + if(((Sources.GOG.GOGGame.DLC) this).game != null) yield ((Sources.GOG.GOGGame.DLC) this).game.umount_overlays(); + return; + } + + if(!overlays_enabled || fs_overlay == null) return; + yield fs_overlay.umount(); + } + + public ArrayList? achievements { get; protected set; default = null; } + public virtual async ArrayList? load_achievements() { return null; } + + public static bool is_equal(Game first, Game second) + { + return first == second || (first.source == second.source && first.id == second.id); + } + + public static uint hash(Game game) + { + return str_hash(game.full_id); + } + + public class Overlay: Object + { + public const string BASE = "base"; + + public Game game { get; construct; } + + public string id { get; construct; } + public string name { get; construct; } + public bool enabled { get; set; } + + public File? directory; + + public bool removable + { + get + { + if(id == BASE && game.overlays != null) + { + foreach(var overlay in game.overlays) + { + if(overlay.id != BASE) return false; + } + } + return true; + } + } + + public Overlay(Game game, string id=BASE, string? name=null, bool enabled=true) + { + Object(game: game, id: id, name: name ?? (id == BASE ? game.name : id)); + this.enabled = id == BASE || enabled; + } + + construct + { + if(game is Sources.Steam.SteamGame || game.install_dir == null || !game.install_dir.query_exists()) return; + + directory = FSUtils.mkdir(game.install_dir.get_child(FSUtils.GAMEHUB_DIR).get_child(FSUtils.OVERLAYS_DIR).get_child(id).get_path()); + } + + public void remove() + { + if(!removable) return; + + game.umount_overlays.begin((obj, res) => { + game.umount_overlays.end(res); + + if(id != BASE) + { + if(directory != null && directory.query_exists()) + { + FSUtils.rm(directory.get_path(), null, "-rf"); + } + game.overlays.remove(this); + game.save_overlays(); + } + else + { + try + { + FSUtils.mv_up(game.install_dir, @"$(FSUtils.GAMEHUB_DIR)/$(FSUtils.OVERLAYS_DIR)/$(BASE)"); + game.overlays.clear(); + game.install_dir.get_child(FSUtils.GAMEHUB_DIR).get_child(FSUtils.OVERLAYS_DIR).get_child(FSUtils.OVERLAYS_LIST).delete(); + game.install_dir.get_child(FSUtils.GAMEHUB_DIR).get_child(FSUtils.OVERLAYS_DIR).delete(); + game.notify_property("overlays-enabled"); + } + catch(Error e) + { + warning("[Game.Overlay.remove] %s", e.message); + } + } + }); + } + } + + public class Status + { + public Game.State state; + public Game? game; + public Downloader.Download? download; + + public Status(Game.State state, Game? game=null, Downloader.Download? download=null) + { + this.state = state; + this.game = game; + this.download = download; + } + + public string description + { + owned get + { + if(game != null && game.is_running) return C_("status", "Running"); + switch(state) + { + case Game.State.INSTALLED: return C_("status", "Installed") + (game != null && game.version != null ? @": $(game.version)" : ""); + case Game.State.INSTALLING: return C_("status", "Installing"); + case Game.State.VERIFYING_INSTALLER_INTEGRITY: return C_("status", "Verifying installer integrity"); + case Game.State.DOWNLOADING: return download != null && download.status != null && download.status.description != null ? download.status.description : C_("status", "Download started"); + } + return C_("status", "Not installed"); + } + } + + public string header + { + owned get + { + switch(state) + { + case Game.State.INSTALLED: return C_("status_header", "Installed"); + case Game.State.INSTALLING: return C_("status_header", "Installing"); + case Game.State.VERIFYING_INSTALLER_INTEGRITY: + case Game.State.DOWNLOADING: return C_("status_header", "Downloading"); + } + return C_("status_header", "Not installed"); + } + } + } + + public enum State + { + UNINSTALLED, INSTALLED, DOWNLOADING, VERIFYING_INSTALLER_INTEGRITY, INSTALLING; + } + + public abstract class Achievement + { + public string id { get; protected set; } + public string name { get; protected set; } + public string description { get; protected set; } + public bool unlocked { get; protected set; default = false; } + public DateTime? unlock_date { get; protected set; } + public string? unlock_time { get; protected set; } + public float global_percentage { get; protected set; default = 0; } + public string? image_locked { get; protected set; } + public string? image_unlocked { get; protected set; } + public string? image { get { return unlocked ? image_unlocked : image_locked; } } + } + } + + public interface TweakableGame: Game + { + public abstract string[]? tweaks { get; set; default = null; } + + public Tweak[] get_enabled_tweaks(CompatTool? tool=null) + { + Tweak[] enabled_tweaks = {}; + var all_tweaks = Tweak.load_tweaks(); + foreach(var tweak in all_tweaks.values) + { + if(tweak.is_enabled(this) && tweak.is_applicable_to(this, tool)) + { + enabled_tweaks += tweak; + } + } + return enabled_tweaks; + } } } diff --git a/src/data/GameSource.vala b/src/data/GameSource.vala index 0ca547db..25b51e4e 100644 --- a/src/data/GameSource.vala +++ b/src/data/GameSource.vala @@ -1,3 +1,21 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + using Gtk; using Gee; using GameHub.Utils; @@ -8,21 +26,46 @@ namespace GameHub.Data { public abstract class GameSource { + public virtual string id { get { return ""; } } public virtual string name { get { return ""; } } + public virtual string name_from { owned get { return _("%s games").printf(name); } } public virtual string icon { get { return ""; } } public virtual string auth_description { owned get { return ""; } } - + + public abstract bool enabled { get; set; } + public int games_count { get; protected set; } public abstract bool is_installed(bool refresh=false); - + public abstract async bool install(); - + public abstract async bool authenticate(); public abstract bool is_authenticated(); - - public abstract async ArrayList load_games(FutureResult? game_loaded = null); + public abstract bool can_authenticate_automatically(); + + public abstract ArrayList games { get; } + + public abstract async ArrayList load_games(Utils.FutureResult2? game_loaded=null, Utils.Future? cache_loaded=null); + + public static GameSource? by_id(string id) + { + foreach(var src in GameSources) + { + if(src.id == id) return src; + } + return null; + } + + public static GameSource? by_name(string name) + { + foreach(var src in GameSources) + { + if(src.name == name) return src; + } + return null; + } } - + public static GameSource[] GameSources; } diff --git a/src/data/Runnable.vala b/src/data/Runnable.vala new file mode 100644 index 00000000..20e3e694 --- /dev/null +++ b/src/data/Runnable.vala @@ -0,0 +1,925 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; +using Gtk; + +using GameHub.Utils; +using GameHub.Data.DB; + +namespace GameHub.Data +{ + public abstract class Runnable: Object + { + public string id { get; protected set; } + + private string _name; + public string escaped_name { get; set; } + public string normalized_name { get; set; } + + public string name + { + get + { + return _name; + } + set + { + _name = value; + escaped_name = Utils.strip_name(_name.replace(" ", "_"), "_.,"); + normalized_name = Utils.strip_name(_name, null, true); + } + } + + public string? compat_tool { get; set; } + public string? compat_tool_settings { get; set; } + + public string? arguments { get; set; } + + public bool is_running { get; set; default = false; } + + public ArrayList platforms { get; protected set; default = new ArrayList(); } + public virtual bool is_supported(Platform? platform=null, bool with_compat=true) + { + platform = platform ?? Platform.CURRENT; + if(platforms == null || platforms.size == 0 || platform in platforms) return true; + if(!with_compat) return false; + foreach(var tool in CompatTools) + { + if(tool.can_run(this)) return true; + } + return false; + } + + public abstract File? executable { owned get; set; } + public File? install_dir { get; set; } + public abstract File? work_dir { owned get; set; } + public virtual File? default_install_dir { owned get { return null; } } + + public ArrayList actions { get; protected set; default = new ArrayList(); } + + public abstract async void install(Runnable.Installer.InstallMode install_mode=Runnable.Installer.InstallMode.INTERACTIVE); + public abstract async void run(); + + public virtual bool can_be_launched(bool is_launch_attempt=false) + { + if(Runnable.IsLaunched || Sources.Steam.Steam.IsAnyAppRunning || is_running) return false; + if(is_launch_attempt) + { + lock(Runnable.LastLaunchAttempt) + { + var launch_attempt = Runnable.LastLaunchAttempt; + var now = get_real_time(); + Runnable.LastLaunchAttempt = now; + if(now - launch_attempt < 1000000) return false; + } + } + return true; + } + + public virtual async void run_with_compat(bool is_opened_from_menu=false) + { + if(can_be_launched(true)) + { + var dlg = new UI.Dialogs.CompatRunDialog(this, is_opened_from_menu); + dlg.destroy.connect(() => { + Idle.add(run_with_compat.callback); + }); + yield; + } + } + + public virtual FileChooser setup_executable_chooser() + { + #if GTK_3_22 + var chooser = new FileChooserNative(_("Select executable"), GameHub.UI.Windows.MainWindow.instance, FileChooserAction.OPEN, _("Select"), _("Cancel")); + #else + var chooser = new FileChooserDialog(_("Select executable"), GameHub.UI.Windows.MainWindow.instance, FileChooserAction.OPEN, _("Select"), ResponseType.ACCEPT, _("Cancel"), ResponseType.CANCEL); + #endif + + try + { + chooser.set_file(executable); + } + catch(Error e) + { + warning(e.message); + } + + return chooser; + } + + private int run_executable_chooser(FileChooser chooser) + { + #if GTK_3_22 + return (chooser as FileChooserNative).run(); + #else + return (chooser as FileChooserDialog).run(); + #endif + } + + public virtual void choose_executable(bool update=true) + { + var chooser = setup_executable_chooser(); + + if(run_executable_chooser(chooser) == ResponseType.ACCEPT) + { + set_chosen_executable(chooser.get_file(), update); + } + } + + public virtual void set_chosen_executable(File? file, bool update=true) + { + executable = file; + if(executable != null && executable.query_exists()) + { + Utils.run({"chmod", "+x", executable.get_path()}).run_sync(); + } + + if(update) + { + update_status(); + save(); + } + } + + public virtual void save(){} + public virtual void update_status(){} + + public virtual void import(bool update=true) + { + var chooser = new FileChooserDialog(_("Select directory"), GameHub.UI.Windows.MainWindow.instance, FileChooserAction.SELECT_FOLDER); + + var games_dir = ""; + if(this is Sources.GOG.GOGGame) + { + games_dir = FSUtils.Paths.GOG.Games; + } + else if(this is Sources.Humble.HumbleGame) + { + games_dir = FSUtils.Paths.Humble.Games; + } + + chooser.set_current_folder(games_dir); + + chooser.add_button(_("Cancel"), ResponseType.CANCEL); + var select_btn = chooser.add_button(_("Select"), ResponseType.ACCEPT); + + select_btn.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION); + select_btn.grab_default(); + + if(chooser.run() == ResponseType.ACCEPT) + { + install_dir = chooser.get_file(); + work_dir = install_dir; + executable = FSUtils.file(install_dir.get_path(), "start.sh"); + + if(!executable.query_exists()) + { + choose_executable(false); + } + + if(executable.query_exists()) + { + Utils.run({"chmod", "+x", executable.get_path()}).run_sync(); + } + + if(update) + { + update_status(); + save(); + } + } + + chooser.destroy(); + } + + public bool use_compat + { + get + { + return needs_compat || force_compat; + } + } + + public bool needs_compat + { + get + { + return (!is_supported(null, false) && is_supported(null, true)) || (executable != null && executable.get_basename().down().has_suffix(".exe")); + } + } + + public bool force_compat + { + get + { + if(this is Sources.Steam.SteamGame) return false; + if(get_compat_option_bool("force_compat") == true) return true; + return false; + } + set + { + if(this is Sources.Steam.SteamGame) return; + set_compat_option_bool("force_compat", value); + notify_property("use-compat"); + } + } + + public bool compat_options_saved + { + get + { + if(this is Sources.Steam.SteamGame) return false; + return get_compat_option_bool("compat_options_saved") == true; + } + set + { + if(this is Sources.Steam.SteamGame) return; + set_compat_option_bool("compat_options_saved", value); + } + } + + public Json.Object get_compat_settings(CompatTool tool) + { + if(compat_tool_settings != null && compat_tool_settings.length > 0) + { + var root = Parser.parse_json(compat_tool_settings); + var settings = Parser.json_object(root, { tool.id }); + if(settings != null) + { + return settings; + } + } + return new Json.Object(); + } + + public void set_compat_settings(CompatTool tool, Json.Object? settings) + { + var root_object = new Json.Object(); + if(compat_tool_settings != null && compat_tool_settings.length > 0) + { + var root = Parser.parse_json(compat_tool_settings); + if(root != null && root.get_node_type() == Json.NodeType.OBJECT) + { + root_object = root.get_object(); + } + } + + if(settings == null) + { + root_object.remove_member(tool.id); + } + else + { + root_object.set_object_member(tool.id, settings); + } + + var root_node = new Json.Node(Json.NodeType.OBJECT); + root_node.set_object(root_object); + compat_tool_settings = Json.to_string(root_node, false); + compat_options_saved = true; + save(); + } + + public bool? get_compat_option_bool(string key) + { + if(compat_tool_settings != null && compat_tool_settings.length > 0) + { + var root = Parser.parse_json(compat_tool_settings); + if(root != null && root.get_node_type() == Json.NodeType.OBJECT) + { + var obj = root.get_object(); + if(obj.has_member(key)) return obj.get_boolean_member(key); + } + } + return null; + } + + public void set_compat_option_bool(string key, bool? value) + { + var root_object = new Json.Object(); + if(compat_tool_settings != null && compat_tool_settings.length > 0) + { + var root = Parser.parse_json(compat_tool_settings); + if(root != null && root.get_node_type() == Json.NodeType.OBJECT) + { + root_object = root.get_object(); + } + } + if(value != null) + { + root_object.set_boolean_member(key, value); + } + else + { + root_object.remove_member(key); + } + var root_node = new Json.Node(Json.NodeType.OBJECT); + root_node.set_object(root_object); + compat_tool_settings = Json.to_string(root_node, false); + save(); + } + + public static bool IsLaunched = false; + public static int64 LastLaunchAttempt = 0; + + public abstract class Installer + { + public string id { get; protected set; } + public Platform platform { get; protected set; default = Platform.CURRENT; } + public int64 full_size { get; protected set; default = 0; } + public string? version { get; protected set; } + + public virtual string name { owned get { return id; } } + + public abstract async void install(Runnable runnable, CompatTool? tool=null); + + public static async InstallerType guess_type(File file, bool is_part=false) + { + var type = InstallerType.UNKNOWN; + if(file == null) return type; + + try + { + var finfo = yield file.query_info_async(FileAttribute.STANDARD_CONTENT_TYPE, FileQueryInfoFlags.NONE); + var mime = finfo.get_content_type(); + type = InstallerType.from_mime(mime); + + if(type != InstallerType.UNKNOWN) return type; + + var info = Utils.run({"file", "-bi", file.get_path()}).log(false).run_sync(true).output; + if(info != null && info.length > 0) + { + mime = info.split(";")[0]; + if(mime != null && mime.length > 0) + { + type = InstallerType.from_mime(mime); + } + } + + if(type != InstallerType.UNKNOWN) return type; + + string[] gog_part_ext = {"bin"}; + string[] exe_ext = {"sh", "elf", "bin", "run"}; + string[] win_exe_ext = {"exe", "msi"}; + string[] arc_ext = {"zip", "tar", "cpio", "bz2", "gz", "lz", "lzma", "7z", "rar"}; + + if(is_part) + { + foreach(var ext in gog_part_ext) + { + if(file.get_basename().down().has_suffix(@".$(ext)")) return InstallerType.GOG_PART; + } + } + + foreach(var ext in exe_ext) + { + if(file.get_basename().down().has_suffix(@".$(ext)")) return InstallerType.EXECUTABLE; + } + foreach(var ext in win_exe_ext) + { + if(file.get_basename().down().has_suffix(@".$(ext)")) return InstallerType.WINDOWS_EXECUTABLE; + } + foreach(var ext in arc_ext) + { + if(file.get_basename().down().has_suffix(@".$(ext)")) return InstallerType.ARCHIVE; + } + } + catch(Error e){} + + return type; + } + + public enum InstallerType + { + UNKNOWN, EXECUTABLE, WINDOWS_EXECUTABLE, GOG_PART, ARCHIVE, WINDOWS_NSIS_INSTALLER; + + public static InstallerType from_mime(string type) + { + switch(type.strip()) + { + case "application/x-executable": + case "application/x-elf": + case "application/x-sh": + case "application/x-shellscript": + return InstallerType.EXECUTABLE; + + case "application/x-dosexec": + case "application/x-ms-dos-executable": + case "application/dos-exe": + case "application/exe": + case "application/msdos-windows": + case "application/x-exe": + case "application/x-msdownload": + case "application/x-winexe": + case "application/x-msi": + return InstallerType.WINDOWS_EXECUTABLE; + + case "application/octet-stream": + return InstallerType.GOG_PART; + + case "application/zip": + case "application/x-tar": + case "application/x-gtar": + case "application/x-cpio": + case "application/x-bzip2": + case "application/gzip": + case "application/x-lzip": + case "application/x-lzma": + case "application/x-7z-compressed": + case "application/x-rar-compressed": + case "application/x-compressed-tar": + return InstallerType.ARCHIVE; + } + return InstallerType.UNKNOWN; + } + } + + public enum InstallMode + { + INTERACTIVE, AUTOMATIC, AUTOMATIC_DOWNLOAD + } + } + + public abstract class FileInstaller: Installer + { + private const string NSIS_INSTALLER_DESCRIPTION = "Nullsoft Installer"; + + public File? file { get; protected set; } + public int64 size { get; protected set; } + + public override async void install(Runnable runnable, CompatTool? tool=null) + { + yield install_file(file, false, runnable, tool); + } + + public static async void install_file(File? file, bool is_part, Runnable runnable, CompatTool? tool=null, out bool is_windows_installer=null, out bool is_nsis_installer=null) + { + is_windows_installer = false; + is_nsis_installer = false; + + if(file == null || !file.query_exists()) return; + + Game? game = null; + if(runnable is Game) + { + game = runnable as Game; + } + + var path = file.get_path(); + Utils.run({"chmod", "+x", path}).run_sync(); + + FSUtils.mkdir(runnable.install_dir.get_path()); + + var type = yield guess_type(file, is_part); + + if(type == InstallerType.WINDOWS_EXECUTABLE && tool is Compat.Innoextract) + { + var desc = Utils.run({"file", "-b", path}).log(false).run_sync(true).output; + if(desc != null && desc.length > 0 && NSIS_INSTALLER_DESCRIPTION in desc) + { + type = InstallerType.WINDOWS_NSIS_INSTALLER; + } + } + + string[]? cmd = null; + + switch(type) + { + case InstallerType.EXECUTABLE: + cmd = {path, "--", "--i-agree-to-all-licenses", + "--noreadme", "--nooptions", "--noprompt", + "--destination", runnable.install_dir.get_path().replace("'", "\\'")}; // probably mojosetup + break; + + case InstallerType.ARCHIVE: + case InstallerType.WINDOWS_NSIS_INSTALLER: + cmd = {"file-roller", path, "-e", runnable.install_dir.get_path()}; // extract with file-roller + break; + + case InstallerType.WINDOWS_EXECUTABLE: + case InstallerType.GOG_PART: + cmd = null; // use compattool later + break; + + default: + cmd = {"xdg-open", path}; // unknown type, just open + break; + } + + if(game != null) game.status = new Game.Status(Game.State.INSTALLING, game); + + if(cmd != null) + { + yield Utils.run(cmd).run_async(); + } + if(type == InstallerType.WINDOWS_EXECUTABLE) + { + is_windows_installer = true; + if(tool != null && tool.can_install(runnable)) + { + yield tool.install(runnable, file); + } + } + else if(type == InstallerType.WINDOWS_NSIS_INSTALLER) + { + is_nsis_installer = true; + } + } + } + + public abstract class DownloadableInstaller: Installer + { + public class Part: Object + { + public string id { get; construct set; } + public string url { get; construct set; } + public int64 size { get; construct set; } + public File? remote { get; construct set; } + public File? local { get; construct set; } + public string? checksum { get; construct set; } + public ChecksumType checksum_type { get; construct set; } + public Part(string id, string url, int64 size, File remote, File local, string? checksum=null, ChecksumType checksum_type=ChecksumType.MD5) + { + Object(id: id, url: url, size: size, remote: remote, local: local, checksum: checksum, checksum_type: checksum_type); + } + public string? checksum_type_string + { + get + { + if(checksum == null || checksum.length == 0) return null; + switch(checksum_type) + { + case ChecksumType.MD5: return "md5"; + case ChecksumType.SHA1: return "sha1"; + case ChecksumType.SHA256: return "sha256"; + case ChecksumType.SHA512: return "sha512"; + } + return null; + } + } + } + + public ArrayList parts { get; protected set; default = new ArrayList(); } + public virtual async void fetch_parts(){} + + public async ArrayList download(Runnable runnable) + { + var files = new ArrayList(); + try + { + Game? game = null; + if(runnable is Game) + { + game = runnable as Game; + } + + if(game != null) game.status = new Game.Status(Game.State.DOWNLOADING, game, null); + + var runnable_install_dir = runnable.install_dir ?? runnable.default_install_dir; + if(runnable_install_dir == null) return files; + runnable.install_dir = runnable_install_dir; + + uint p = 1; + foreach(var part in parts) + { + FSUtils.mkdir(part.local.get_parent().get_path()); + + var ds_id = Downloader.download_manager().file_download_started.connect(dl => { + if(dl.remote != part.remote) return; + if(game != null) + { + game.status = new Game.Status(Game.State.DOWNLOADING, game, dl); + dl.status_change.connect(s => { + game.status_change(game.status); + }); + } + }); + + var partDesc = part.id; + + if(parts.size > 1) + { + partDesc = _("Part %1$u of %2$u: %3$s").printf(p, parts.size, part.id); + } + + var info = new Downloader.DownloadInfo(runnable.name, partDesc, game != null ? game.icon : null, null, null, game != null ? game.source.icon : null); + var file = yield Downloader.download_file(part.remote, part.local, info); + if(file != null && file.query_exists()) + { + string? file_checksum = null; + if(part.checksum != null) + { + FileUtils.set_contents(file.get_path() + "." + part.checksum_type_string, part.checksum); + if(game != null) game.status = new Game.Status(Game.State.VERIFYING_INSTALLER_INTEGRITY, game); + file_checksum = yield Utils.compute_file_checksum(file, part.checksum_type); + if(game != null) game.status = new Game.Status(Game.State.DOWNLOADING, game, null); + } + + if(part.checksum == null || file_checksum == null || part.checksum == file_checksum) + { + files.add(file); + } + else + { + Utils.notify( + _("%s: corrupted installer").printf(runnable.name), + _("Checksum mismatch in %s").printf(file.get_basename()), + NotificationPriority.HIGH, + n => { + n.set_icon(new ThemedIcon("dialog-warning")); + if(game != null) + { + var icon = ImageCache.local_file(game.icon, @"games/$(game.source.id)/$(game.id)/icons/"); + if(icon != null && icon.query_exists()) + { + n.set_icon(new FileIcon(icon)); + } + } + var args = new Variant("(ss)", game != null ? game.full_id : runnable.id, file.get_path()); + n.set_default_action_and_target_value(Application.ACTION_PREFIX + Application.ACTION_CORRUPTED_INSTALLER_PICK_ACTION, args); + n.add_button_with_target_value(_("Show file"), Application.ACTION_PREFIX + Application.ACTION_CORRUPTED_INSTALLER_SHOW, args); + n.add_button_with_target_value(_("Remove"), Application.ACTION_PREFIX + Application.ACTION_CORRUPTED_INSTALLER_REMOVE, args); + n.add_button_with_target_value(_("Backup"), Application.ACTION_PREFIX + Application.ACTION_CORRUPTED_INSTALLER_BACKUP, args); + return n; + } + ); + + warning("Checksum mismatch in `%s`, skipping; expected: `%s`, actual: `%s`", file.get_basename(), part.checksum, file_checksum); + } + } + Downloader.download_manager().disconnect(ds_id); + + p++; + } + + if(game != null) game.status = new Game.Status(Game.State.UNINSTALLED, game); + runnable.update_status(); + } + catch(IOError.CANCELLED e){} + catch(Error e) + { + warning("[DownloadableInstaller.download] %s", e.message); + } + return files; + } + + public override async void install(Runnable runnable, CompatTool? tool=null) + { + try + { + var files = yield download(runnable); + + Game? game = null; + if(runnable is Game) + { + game = runnable as Game; + } + + if(game != null) game.status = new Game.Status(Game.State.UNINSTALLED, game); + runnable.update_status(); + + if(files.size == 0) return; + + uint f = 0; + bool windows_installer = false; + bool nsis_installer = false; + foreach(var file in files) + { + bool win; + bool nsis; + yield FileInstaller.install_file(file, f++ > 0, runnable, tool, out win, out nsis); + windows_installer = windows_installer || win; + nsis_installer = nsis_installer || nsis; + } + + try + { + if(nsis_installer) + { + FSUtils.rm(runnable.install_dir.get_path(), "\\$*DIR", "-rf"); // remove anything like $PLUGINSDIR + } + + int dircount = 0; + string? dirname = null; + FileInfo? finfo = null; + var enumerator = yield runnable.install_dir.enumerate_children_async("standard::*", FileQueryInfoFlags.NOFOLLOW_SYMLINKS); + while((finfo = enumerator.next_file()) != null) + { + if(finfo.get_file_type() == FileType.DIRECTORY && finfo.get_name() != FSUtils.GAMEHUB_DIR) + { + dircount++; + dirname = dirname == null && dircount == 1 ? finfo.get_name() : null; + } + else if(finfo.get_file_type() != FileType.DIRECTORY) + { + dirname = null; + break; + } + } + + if(dirname != null && !(runnable is GameHub.Data.Sources.GOG.GOGGame.DLC)) + { + FSUtils.mv_up(runnable.install_dir, dirname.replace(" ", "\\ ")); + } + + if(windows_installer || platform == Platform.WINDOWS) + { + runnable.force_compat = true; + } + } + catch(Error e){} + + runnable.update_status(); + + if(runnable is GameHub.Data.Sources.GOG.GOGGame && !(runnable is GameHub.Data.Sources.GOG.GOGGame.DLC) && (runnable.executable == null || !runnable.executable.query_exists())) + { + if(runnable.actions != null && runnable.actions.size > 0) + { + foreach(var action in runnable.actions) + { + if(action.is_primary) + { + if(action.file != null && action.file.query_exists()) + { + runnable.executable = action.file; + runnable.work_dir = action.workdir; + runnable.arguments = action.args; + break; + } + } + } + } + + runnable.update_status(); + } + + if((runnable.executable == null || !runnable.executable.query_exists()) && !(runnable is GameHub.Data.Sources.GOG.GOGGame.DLC)) + { + if(game != null) + { + Utils.notify( + _("%s: cannot detect main executable").printf(game.name), + _("Main executable file for this game cannot be detected automatically.\nPlease set main executable in game's properties."), + NotificationPriority.HIGH, + n => { + n.set_icon(new ThemedIcon("dialog-warning")); + if(game != null) + { + var icon = ImageCache.local_file(game.icon, @"games/$(game.source.id)/$(game.id)/icons/"); + if(icon != null && icon.query_exists()) + { + n.set_icon(new FileIcon(icon)); + } + } + n.set_default_action_and_target_value(Application.ACTION_PREFIX + Application.ACTION_GAME_PROPERTIES, new Variant.string(game.full_id)); + return n; + } + ); + } + else + { + runnable.choose_executable(); + } + } + + if(game != null && version != null) + { + game.save_version(version); + } + + var gh_marker = runnable.install_dir.get_child(".gamehub_" + runnable.id); + if(gh_marker != null) + { + FileUtils.set_contents(gh_marker.get_path(), ""); + } + } + catch(Error e) + { + warning("[DownloadableInstaller.install] %s", e.message); + } + runnable.update_status(); + } + } + + public abstract class RunnableAction + { + public Runnable runnable { get; protected set; } + + public bool is_primary { get; protected set; default = false; } + public bool is_hidden { get; protected set; default = false; } + public string name { get; protected set; } + public File? file { get; protected set; } + public File? workdir { get; protected set; } + public string? args { get; protected set; } + public Type?[] compat_tools { get; protected set; default = { null }; } + public string? uri { get; protected set; } + + public bool is_available(CompatTool? tool=null) + { + if(file == null && uri != null) + { + return true; + } + + if(tool == null) + { + return compat_tools.length == 0 || compat_tools[0] == null; + } + + var t = tool.get_type(); + + foreach(var type in compat_tools) + { + if(type != null && t.is_a(type)) + { + return true; + } + } + + return false; + } + + public async void invoke(CompatTool? tool=null) + { + if(file == null && uri != null) + { + Utils.open_uri(uri); + return; + } + + if(is_available(tool) && tool.can_run_action(runnable, this)) + { + yield tool.run_action(runnable, this); + } + } + } + } + + public enum Platform + { + LINUX, WINDOWS, MACOS, EMULATED; + + public const Platform[] PLATFORMS = { Platform.LINUX, Platform.WINDOWS, Platform.MACOS, Platform.EMULATED }; + + #if OS_LINUX + public const Platform CURRENT = Platform.LINUX; + #elif OS_WINDOWS + public const Platform CURRENT = Platform.WINDOWS; + #elif OS_MACOS + public const Platform CURRENT = Platform.MACOS; + #endif + + public string id() + { + switch(this) + { + case Platform.LINUX: return "linux"; + case Platform.WINDOWS: return "windows"; + case Platform.MACOS: return "mac"; + case Platform.EMULATED: return "emulated"; + } + assert_not_reached(); + } + + public string name() + { + switch(this) + { + case Platform.LINUX: return "Linux"; + case Platform.WINDOWS: return "Windows"; + case Platform.MACOS: return "macOS"; + case Platform.EMULATED: return C_("platform", "Emulated"); + } + assert_not_reached(); + } + + public string icon() + { + switch(this) + { + case Platform.LINUX: return "platform-linux-symbolic"; + case Platform.WINDOWS: return "platform-windows-symbolic"; + case Platform.MACOS: return "platform-macos-symbolic"; + case Platform.EMULATED: return "gamehub-symbolic"; + } + assert_not_reached(); + } + } +} diff --git a/src/data/adapters/GamesAdapter.vala b/src/data/adapters/GamesAdapter.vala new file mode 100644 index 00000000..2e61f740 --- /dev/null +++ b/src/data/adapters/GamesAdapter.vala @@ -0,0 +1,743 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gee; +using GameHub.Data.DB; +using GameHub.Utils; +using GameHub.Settings; + +using GameHub.UI.Widgets; +using GameHub.UI.Views.GamesView; +using GameHub.UI.Views.GamesView.List; +using GameHub.UI.Views.GamesView.Grid; + +namespace GameHub.Data.Adapters +{ + public class GamesAdapter: Object + { + public signal void cache_loaded(); + + private Settings.UI.Behavior settings; + public bool filter_settings_merge = true; + + public GameSource? filter_source { get; set; default = null; } + public ArrayList filter_tags; + public SortMode sort_mode = SortMode.NAME; + public GroupMode group_mode = GroupMode.STATUS; + public PlatformFilter filter_platform = PlatformFilter.ALL; + public string filter_search_query = ""; + + private ArrayList sources = new ArrayList(); + private ArrayList loading_sources = new ArrayList(); + + private ArrayList games = new ArrayList(); + + private bool new_games_added = false; + + public weak GamesGrid? grid; + public weak GamesList? list; + + private HashMap view_cache = new HashMap(); + + public string? status { get; private set; default = null; } + + #if UNITY + public Unity.LauncherEntry launcher_entry; + public Dbusmenu.Menuitem launcher_menu; + #endif + + public GamesAdapter() + { + foreach(var src in GameSources) + { + if(src.enabled && src.is_authenticated()) + { + sources.add(src); + } + } + + settings = Settings.UI.Behavior.instance; + filter_settings_merge = settings.merge_games; + + settings.notify["merge-games"].connect(() => invalidate()); + + #if UNITY + launcher_entry = Unity.LauncherEntry.get_for_desktop_id(ProjectConfig.PROJECT_NAME + ".desktop"); + setup_launcher_menu(); + #endif + } + + public void attach_grid(GamesGrid? grid) + { + this.grid = grid; + if(this.grid != null) + { + this.grid.set_filter_func(c => { + return filter((c as GameCard).game); + }); + this.grid.set_sort_func((c, c2) => { + return sort((c as GameCard).game, (c2 as GameCard).game); + }); + add_cached_views(false); + } + } + + public void attach_list(GamesList? list) + { + this.list = list; + if(this.list != null) + { + this.list.set_filter_func(r => { + return filter((r as GameListRow).game); + }); + this.list.set_sort_func((r, r2) => { + return sort((r as GameListRow).game, (r2 as GameListRow).game); + }); + this.list.set_header_func(list_header); + add_cached_views(false); + } + } + + public void invalidate(bool filter=true, bool sort=true, bool headers=true) + { + filter_settings_merge = settings.merge_games; + if(filter) + { + if(grid != null) grid.invalidate_filter(); + if(list != null) list.invalidate_filter(); + } + if(sort) + { + if(grid != null) grid.invalidate_sort(); + if(list != null) list.invalidate_sort(); + } + if(headers) + { + if(list != null) list.invalidate_headers(); + } + } + + public void load_games(Utils.FutureResult loaded_callback) + { + Utils.thread("GamesAdapterLoad", () => { + foreach(var src in sources) + { + loading_sources.add(src); + update_loading_status(); + src.load_games.begin(add, () => { add_cached_views(); }, (obj, res) => { + src.load_games.end(res); + loading_sources.remove(src); + update_loading_status(); + loaded_callback(src); + if(loading_sources.size == 0 && new_games_added) + { + if(new_games_added) + { + merge_games(); + } + else + { + status = null; + } + } + }); + } + }); + } + + public void add(Game game, bool is_cached=false) + { + games.add(game); + var holder = new ViewHolder(game, this); + lock(view_cache) + { + view_cache.set(game, holder); + } + if(!is_cached) + { + new_games_added = true; + Idle.add(() => { + add_views(game, holder); + return Source.REMOVE; + }, Priority.LOW); + } + if(game is Sources.User.UserGame) + { + ((Sources.User.UserGame) game).removed.connect(() => { + remove(game); + }); + } + + #if UNITY + add_game_to_launcher_favorites_menu(game); + #endif + } + + private void add_views(Game game, ViewHolder? holder=null) + { + holder = holder ?? view_cache.get(game); + if(holder != null) + { + holder.add_views(grid, list); + + if(grid != null && holder.grid_card != null) + { + holder.grid_card.show_all(); + if(grid.get_children().length() == 0) + { + holder.grid_card.grab_focus(); + } + } + + if(list != null && holder.list_row != null) + { + holder.list_row.show_all(); + if(list.get_selected_row() == null) + { + list.select_row(holder.list_row); + } + } + + if(!filter(game)) + { + if(holder.grid_card != null) holder.grid_card.changed(); + if(holder.list_row != null) holder.list_row.changed(); + } + } + } + + private void add_cached_views(bool invoke_cache_loaded_signal=true) + { + Idle.add(() => { + lock(view_cache) + { + foreach(var holder in view_cache.values) + { + add_views(holder.game, holder); + } + } + if(invoke_cache_loaded_signal) cache_loaded(); + return Source.REMOVE; + }, Priority.LOW); + } + + public void remove(Game game) + { + games.remove(game); + + ViewHolder? holder; + lock(view_cache) + { + view_cache.unset(game, out holder); + } + + if(holder != null) + { + holder.destroy(); + } + } + + public bool filter(Game? game) + { + if(game == null) return false; + + bool same_src = (filter_source == null || game == null || filter_source == game.source); + bool merged_src = false; + + ArrayList? merges = null; + + Platform[] platforms = {}; + + if(filter_platform != PlatformFilter.ALL) + { + foreach(var p in game.platforms) + { + if(!(p in platforms)) platforms += p; + } + } + + if(filter_settings_merge) + { + merges = Tables.Merges.get(game); + var primary = Tables.Merges.get_primary(game); + if(merges != null && merges.size > 0) + { + foreach(var g in merges) + { + if(g.source == filter_source) + { + merged_src = true; + if(filter_platform == PlatformFilter.ALL || filter_source != null) break; + } + + if(filter_platform != PlatformFilter.ALL && filter_source == null) + { + foreach(var p in g.platforms) + { + if(!(p in platforms)) platforms += p; + } + } + } + } + if(primary != null && filter_platform != PlatformFilter.ALL && filter_source == null) + { + foreach(var p in primary.platforms) + { + if(!(p in platforms)) platforms += p; + } + } + } + + if(filter_platform != PlatformFilter.ALL && !(filter_platform.platform() in platforms)) return false; + + bool tags_all_enabled = filter_tags == null || filter_tags.size == 0 || filter_tags.size == Tables.Tags.TAGS.size; + bool tags_all_except_hidden_enabled = filter_tags != null && filter_tags.size == Tables.Tags.TAGS.size - 1 && !(Tables.Tags.BUILTIN_HIDDEN in filter_tags); + bool tags_match = false; + bool tags_match_merged = false; + + if(!tags_all_enabled) + { + foreach(var tag in filter_tags) + { + tags_match = game.has_tag(tag); + if(tags_match) break; + } + if(!tags_match && merges != null && merges.size > 0) + { + foreach(var g in merges) + { + foreach(var tag in filter_tags) + { + tags_match_merged = g.has_tag(tag); + if(tags_match_merged) break; + } + } + } + } + + bool hidden = game.has_tag(Tables.Tags.BUILTIN_HIDDEN) && (filter_tags == null || filter_tags.size == 0 || !(Tables.Tags.BUILTIN_HIDDEN in filter_tags)); + + return (same_src || merged_src) && (tags_all_enabled || tags_all_except_hidden_enabled || tags_match || tags_match_merged) && !hidden && Utils.strip_name(filter_search_query).casefold() in Utils.strip_name(game.name).casefold(); + } + + public int sort(Game? game1, Game? game2) + { + if(game1 != null && game2 != null) + { + var s1 = game1.status.state; + var s2 = game2.status.state; + + var f1 = game1.has_tag(Tables.Tags.BUILTIN_FAVORITES); + var f2 = game2.has_tag(Tables.Tags.BUILTIN_FAVORITES); + + if(f1 && !f2) return -1; + if(f2 && !f1) return 1; + + switch(group_mode) + { + case GroupMode.STATUS: + if(s1 == Game.State.DOWNLOADING && s2 != Game.State.DOWNLOADING) return -1; + if(s1 != Game.State.DOWNLOADING && s2 == Game.State.DOWNLOADING) return 1; + if(s1 == Game.State.INSTALLING && s2 != Game.State.INSTALLING) return -1; + if(s1 != Game.State.INSTALLING && s2 == Game.State.INSTALLING) return 1; + if(s1 == Game.State.INSTALLED && s2 != Game.State.INSTALLED) return -1; + if(s1 != Game.State.INSTALLED && s2 == Game.State.INSTALLED) return 1; + break; + + case GroupMode.SOURCE: + if(game1.source != game2.source) + { + return game1.source.id.collate(game2.source.id); + } + break; + } + + switch(sort_mode) + { + case SortMode.LAST_LAUNCH: + if(game1.last_launch > game2.last_launch) return -1; + if(game1.last_launch < game2.last_launch) return 1; + break; + + case SortMode.PLAYTIME: + if(game1.playtime > game2.playtime) return -1; + if(game1.playtime < game2.playtime) return 1; + break; + } + + return game1.normalized_name.collate(game2.normalized_name); + } + return 0; + } + + private void list_header(ListBoxRow row, ListBoxRow? prev) + { + if(group_mode == GroupMode.NONE) + { + row.set_header(null); + return; + } + + var item = row as GameListRow; + var prev_item = prev as GameListRow; + var s = item.game.status.state; + var ps = prev_item != null ? prev_item.game.status.state : s; + var f = item.game.has_tag(Tables.Tags.BUILTIN_FAVORITES); + var pf = prev_item != null ? prev_item.game.has_tag(Tables.Tags.BUILTIN_FAVORITES) : f; + + if(group_mode == GroupMode.STATUS && prev_item != null && f == pf && (f || s == ps)) + { + row.set_header(null); + return; + } + + var src = item.game.source; + var psrc = prev_item != null ? prev_item.game.source : src; + + if(group_mode == GroupMode.SOURCE && prev_item != null && src == psrc && f == pf) + { + row.set_header(null); + return; + } + + var header = new Box(Orientation.HORIZONTAL, 6); + StyleClass.add(header, "games-list-header"); + if(prev_item == null) StyleClass.add(header, "first"); + header.hexpand = true; + + var label = Styled.H4Label(null); + label.hexpand = true; + label.xalign = 0; + label.ellipsize = Pango.EllipsizeMode.END; + + switch(group_mode) + { + case GroupMode.STATUS: + if(f) + { + var icon = new Image.from_icon_name("gh-game-favorite-symbolic", IconSize.MENU); + icon.valign = icon.valign = Align.CENTER; + icon.pixel_size = 12; + icon.margin = 2; + header.add(icon); + } + label.label = f ? C_("status_header", "Favorites") : item.game.status.header; + break; + + case GroupMode.SOURCE: + header.add(new Image.from_icon_name(src.icon, IconSize.MENU)); + label.label = f ? C_("status_header", "%s: Favorites").printf(src.name) : src.name; + break; + } + + header.add(label); + header.show_all(); + row.set_header(header); + } + + public int games_count + { + get + { + return games.size; + } + } + + public int filtered_games_count + { + get + { + var count = 0; + foreach(var game in games) + { + if(filter(game)) count++; + } + return count; + } + } + + public bool has_filtered_games + { + get + { + foreach(var game in games) + { + if(filter(game)) return true; + } + return false; + } + } + + private void merge_games() + { + if(!filter_settings_merge) return; + Utils.thread("GamesAdapterMerge", () => { + status = _("Merging games"); + foreach(var src in sources) + { + merge_games_from(src); + } + status = null; + }); + } + + private void merge_games_from(GameSource src) + { + if(!filter_settings_merge) return; + debug("[Merge] Merging %s games", src.name); + status = _("Merging games from %s").printf(src.name); + foreach(var game in src.games) + { + merge_game(game); + } + } + + private void merge_game(Game game) + { + if(!filter_settings_merge || game is Sources.GOG.GOGGame.DLC) return; + foreach(var src in sources) + { + foreach(var game2 in src.games) + { + merge_game_with_game(src, game, game2); + } + } + } + + private void merge_game_with_game(GameSource src, Game game, Game game2) + { + if(Game.is_equal(game, game2) || game2 is Sources.GOG.GOGGame.DLC) return; + + if(Tables.Merges.is_game_merged(game) || Tables.Merges.is_game_merged(game2) || Tables.Merges.is_game_merged_as_primary(game2)) return; + + bool name_match_exact = game.normalized_name.casefold() == game2.normalized_name.casefold(); + bool name_match_fuzzy_prefix = game.source != src + && (Utils.strip_name(game.name, ":", true).casefold().has_prefix(game2.normalized_name.casefold() + ":") + || Utils.strip_name(game2.name, ":", true).casefold().has_prefix(game.normalized_name.casefold() + ":")); + if(name_match_exact || name_match_fuzzy_prefix) + { + debug("[Merge] Merging '%s' (%s) with '%s' (%s)", game.name, game.full_id, game2.name, game2.full_id); + Tables.Merges.add(game, game2); + remove(game2); + game.update_status(); + } + } + + private void update_loading_status() + { + if(loading_sources.size > 0) + { + string[] src_names = {}; + foreach(var s in loading_sources) + { + src_names += s.name; + } + status = _("Loading games from %s").printf(string.joinv(", ", src_names)); + } + else + { + status = null; + } + } + + #if UNITY + private void setup_launcher_menu() + { + launcher_menu = new Dbusmenu.Menuitem(); + launcher_entry.quicklist = launcher_menu; + } + + private Dbusmenu.Menuitem launcher_menu_separator() + { + var separator = new Dbusmenu.Menuitem(); + separator.property_set(Dbusmenu.MENUITEM_PROP_TYPE, Dbusmenu.CLIENT_TYPES_SEPARATOR); + return separator; + } + + private void add_game_to_launcher_favorites_menu(Game game) + { + var added = false; + Dbusmenu.Menuitem? item = null; + + SourceFunc update = () => { + Idle.add(() => { + var favorite = game.has_tag(Tables.Tags.BUILTIN_FAVORITES); + if(!added && favorite) + { + if(item == null) + { + item = new Dbusmenu.Menuitem(); + item.property_set(Dbusmenu.MENUITEM_PROP_LABEL, game.name); + item.item_activated.connect(() => { game.run_or_install.begin(); }); + } + launcher_menu.child_append(item); + added = true; + } + else if(added && !favorite) + { + if(item != null) + { + launcher_menu.child_delete(item); + } + added = false; + } + return Source.REMOVE; + }, Priority.LOW); + return Source.REMOVE; + }; + + game.tags_update.connect(() => update()); + update(); + } + #endif + + private class ViewHolder + { + public GamesAdapter adapter; + public Game game; + public GameCard? grid_card = null; + public GameListRow? list_row = null; + + public ViewHolder(Game game, GamesAdapter adapter) + { + this.adapter = adapter; + this.game = game; + + this.game.tags_update.connect(() => { + Idle.add(() => { + if(grid_card != null) grid_card.changed(); + if(list_row != null) list_row.changed(); + return Source.REMOVE; + }, Priority.LOW); + }); + } + + public void init_views(bool init_card=true, bool init_row=true) + { + if(grid_card == null && init_card) grid_card = new GameCard(game, adapter); + if(list_row == null && init_row) list_row = new GameListRow(game, adapter); + } + + public void add_views(GamesGrid? grid, GamesList? list) + { + init_views(grid != null, list != null); + if(grid != null) + { + var old_parent = grid_card.parent; + if(old_parent != grid) + { + if(old_parent != null) old_parent.remove(grid_card); + grid.add(grid_card); + } + } + if(list != null) + { + var old_parent = list_row.parent; + if(old_parent != list) + { + if(old_parent != null) old_parent.remove(list_row); + list.add(list_row); + } + } + } + + public void destroy() + { + Idle.add(() => { + if(grid_card != null) grid_card.destroy(); + if(list_row != null) list_row.destroy(); + return Source.REMOVE; + }, Priority.LOW); + } + } + + public enum SortMode + { + NAME = 0, LAST_LAUNCH = 1, PLAYTIME = 2; + + public string name() + { + switch(this) + { + case SortMode.NAME: return C_("sort_mode", "By name"); + case SortMode.LAST_LAUNCH: return C_("sort_mode", "By last launch"); + case SortMode.PLAYTIME: return C_("sort_mode", "By playtime"); + } + assert_not_reached(); + } + + public string icon() + { + switch(this) + { + case SortMode.NAME: return "insert-text-symbolic"; + case SortMode.LAST_LAUNCH: return "document-open-recent-symbolic"; + case SortMode.PLAYTIME: return "preferences-system-time-symbolic"; + } + assert_not_reached(); + } + } + + public enum GroupMode + { + NONE = 0, STATUS = 1, SOURCE = 2; + + public string name() + { + switch(this) + { + case GroupMode.NONE: return C_("group_mode", "Do not group"); + case GroupMode.STATUS: return C_("group_mode", "By status"); + case GroupMode.SOURCE: return C_("group_mode", "By source"); + } + assert_not_reached(); + } + + public string icon() + { + switch(this) + { + case GroupMode.NONE: return "process-stop-symbolic"; + case GroupMode.STATUS: return "view-continuous-symbolic"; + case GroupMode.SOURCE: return "sources-all-symbolic"; + } + assert_not_reached(); + } + } + + public enum PlatformFilter + { + ALL = 0, LINUX = 1, WINDOWS = 2, MACOS = 3, EMULATED = 4; + + public const PlatformFilter[] FILTERS = { PlatformFilter.ALL, PlatformFilter.LINUX, PlatformFilter.WINDOWS, PlatformFilter.MACOS, PlatformFilter.EMULATED }; + + public Data.Platform platform() + { + switch(this) + { + case PlatformFilter.LINUX: return Data.Platform.LINUX; + case PlatformFilter.WINDOWS: return Data.Platform.WINDOWS; + case PlatformFilter.MACOS: return Data.Platform.MACOS; + case PlatformFilter.EMULATED: return Data.Platform.EMULATED; + } + assert_not_reached(); + } + } + } +} diff --git a/src/data/compat/CustomEmulator.vala b/src/data/compat/CustomEmulator.vala new file mode 100644 index 00000000..7ea16499 --- /dev/null +++ b/src/data/compat/CustomEmulator.vala @@ -0,0 +1,86 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; + +using GameHub.Data.DB; +using GameHub.Utils; + +namespace GameHub.Data.Compat +{ + public class CustomEmulator: CompatTool + { + public static CustomEmulator instance; + + private ArrayList emulator_names = new ArrayList(); + + private CompatTool.ComboOption emu_option; + private CompatTool.BoolOption game_dir_option; + + public CustomEmulator() + { + instance = this; + } + + construct + { + id = "emulator"; + name = _("Custom emulator"); + icon = "input-gaming-symbolic"; + + installed = true; + + emu_option = new CompatTool.ComboOption("emulator", _("Emulator"), emulator_names, null); + game_dir_option = new CompatTool.BoolOption("launch_in_game_dir", _("Launch in game directory"), false); + + update_emulators(); + + options = { emu_option, game_dir_option }; + } + + public void update_emulators() + { + emulator_names.clear(); + + var emulators = Tables.Emulators.get_all(); + + foreach(var emu in emulators) + { + emulator_names.add(emu.name); + } + + emu_option.options = emulator_names; + } + + public override bool can_run(Runnable runnable) + { + update_emulators(); + return installed && runnable is Game && emulator_names.size > 0; + } + + public override async void run(Runnable runnable) + { + if(!can_run(runnable)) return; + + var emu = Tables.Emulators.by_name(emu_option.value); + if(emu == null) return; + + yield emu.run_game(runnable as Game, game_dir_option.enabled); + } + } +} diff --git a/src/data/compat/CustomScript.vala b/src/data/compat/CustomScript.vala new file mode 100644 index 00000000..02560f84 --- /dev/null +++ b/src/data/compat/CustomScript.vala @@ -0,0 +1,155 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using GameHub.Utils; +using GameHub.Data.Tweaks; + +using GameHub.Data.Sources.Steam; + +namespace GameHub.Data.Compat +{ + public class CustomScript: CompatTool + { + public const string SCRIPT = "customscript.sh"; + private const string SCRIPT_TEMPLATE = """#!/bin/bash +GH_EXECUTABLE="$1" +GH_INSTALL_DIR="$2" +GH_GAME_ID="$3" +GH_GAME_ID_FULL="$4" +GH_GAME_NAME="$5" +GH_GAME_NAME_ESCAPED="$6" + +"""; + private const string EMU_SCRIPT_TEMPLATE = """#!/bin/bash +GH_EXECUTABLE="$1" +GH_INSTALL_DIR="$2" +GH_EMU_ID="$3" +GH_EMU_NAME="$4" +GH_GAME_EXECUTABLE="$5" +GH_GAME_INSTALL_DIR="$6" +GH_GAME_ID="$7" +GH_GAME_ID_FULL="$8" +GH_GAME_NAME="$9" +GH_GAME_NAME_ESCAPED="${10}" + +"""; + + construct + { + id = @"customscript"; + name = @"Custom script"; + icon = "application-x-executable-symbolic"; + installed = true; + + actions = { + new CompatTool.Action(_("Edit script"), _("Edit custom script"), edit_script) + }; + } + + public override bool can_run(Runnable runnable) + { + return true; + } + + public override async void run(Runnable runnable) + { + if(runnable.install_dir == null || !runnable.install_dir.query_exists()) return; + var gh_dir = FSUtils.mkdir(runnable.install_dir.get_path(), FSUtils.GAMEHUB_DIR); + var script = gh_dir.get_child(SCRIPT); + if(script.query_exists()) + { + Utils.run({"chmod", "+x", script.get_path()}).run_sync(); + var executable_path = runnable.executable != null ? runnable.executable.get_path() : "null"; + string[]? cmd = null; + if(runnable is Game) + { + var game = runnable as Game; + cmd = { script.get_path(), executable_path, game.work_dir.get_path(), game.id, game.full_id, game.name, game.escaped_name }; + } + else if(runnable is Emulator) + { + cmd = { script.get_path(), executable_path, runnable.id, runnable.name }; + } + + var task = Utils.run(cmd).dir(runnable.work_dir.get_path()); + if(runnable is TweakableGame) + { + task.tweaks(((TweakableGame) runnable).get_enabled_tweaks(this)); + } + yield task.run_sync_thread(); + } + else + { + edit_script(runnable); + } + } + + public override async void run_emulator(Emulator emu, Game? game, bool launch_in_game_dir=false) + { + if(emu.install_dir == null || !emu.install_dir.query_exists()) return; + var gh_dir = FSUtils.mkdir(emu.install_dir.get_path(), FSUtils.GAMEHUB_DIR); + var script = gh_dir.get_child(SCRIPT); + if(script.query_exists()) + { + Utils.run({"chmod", "+x", script.get_path()}).run_sync(); + var executable_path = emu.executable != null ? emu.executable.get_path() : "null"; + var game_executable_path = game != null && game.executable != null ? game.executable.get_path() : "null"; + string[] cmd = { script.get_path(), executable_path, emu.id, emu.name, game_executable_path, game.id, game.full_id, game.name, game.escaped_name }; + var dir = game != null && launch_in_game_dir ? game.work_dir : emu.work_dir; + + var task = Utils.run(cmd).dir(dir.get_path()); + if(game is TweakableGame) + { + task.tweaks(((TweakableGame) game).get_enabled_tweaks(this)); + } + yield task.run_sync_thread(); + } + else + { + edit_script(emu); + } + } + + public void edit_script(Runnable runnable) + { + if(runnable.install_dir == null || !runnable.install_dir.query_exists()) return; + var gh_dir = FSUtils.mkdir(runnable.install_dir.get_path(), FSUtils.GAMEHUB_DIR); + var script = gh_dir.get_child(SCRIPT); + if(!script.query_exists()) + { + try + { + if(runnable is Game) + { + FileUtils.set_contents(script.get_path(), SCRIPT_TEMPLATE, SCRIPT_TEMPLATE.length); + } + else if(runnable is Emulator) + { + FileUtils.set_contents(script.get_path(), EMU_SCRIPT_TEMPLATE, EMU_SCRIPT_TEMPLATE.length); + } + } + catch(Error e) + { + warning("[CustomScript.edit_script] %s", e.message); + } + } + Utils.run({"chmod", "+x", script.get_path()}).run_sync(); + Utils.open_uri(script.get_uri()); + } + } +} diff --git a/src/data/compat/DOSBox.vala b/src/data/compat/DOSBox.vala new file mode 100644 index 00000000..82fe4738 --- /dev/null +++ b/src/data/compat/DOSBox.vala @@ -0,0 +1,226 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; + +using GameHub.Utils; + +namespace GameHub.Data.Compat +{ + public class DOSBox: CompatTool + { + public string binary { get; construct; default = "dosbox"; } + + private HashMap additional_configs = new HashMap(); + + public DOSBox(string binary="dosbox") + { + Object(binary: binary); + } + + construct + { + id = @"dosbox"; + name = @"DOSBox"; + icon = "tool-dosbox-symbolic"; + + executable = Utils.find_executable(binary); + installed = executable != null && executable.query_exists(); + + init(); + } + + private void init() + { + CompatTool.Option[] options = {}; + additional_configs.clear(); + + foreach(var data_dir in FSUtils.get_data_dirs("compat/dosbox")) + { + if(GameHub.Application.log_verbose) + { + debug("[DOSBox.init] Config directory: '%s'", data_dir.get_path()); + } + + try + { + FileInfo? finfo = null; + var enumerator = data_dir.enumerate_children("standard::*", FileQueryInfoFlags.NOFOLLOW_SYMLINKS); + while((finfo = enumerator.next_file()) != null) + { + var fname = finfo.get_name(); + if(fname.down().has_suffix(".conf")) + { + var conf = data_dir.get_child(fname); + var description = fname; + bool enabled = false; + + string contents; + FileUtils.get_contents(conf.get_path(), out contents); + var lines = contents.split("\n"); + + foreach(var line in lines) + { + if(line.has_prefix("[")) break; + + if("description=" in line) + { + description = line.replace("description=", "").strip(); + } + else if("enabled=true" in line) + { + enabled = true; + } + } + + if(GameHub.Application.log_verbose) + { + debug("[DOSBox.init] Config: '%s'; description: '%s'; enabled: %s", conf.get_path(), description, enabled.to_string()); + } + + var opt = new CompatTool.BoolOption(conf.get_path(), description, enabled); + options += opt; + additional_configs.set(conf, opt); + } + } + } + catch(Error e) + { + warning("[DOSBox.init] %s", e.message); + } + this.options = options; + } + } + + private static ArrayList find_configs(File? dir) + { + var configs = new ArrayList(); + + if(dir == null || !dir.query_exists()) + { + return configs; + } + + try + { + FileInfo? finfo = null; + var enumerator = dir.enumerate_children("standard::*", FileQueryInfoFlags.NOFOLLOW_SYMLINKS); + while((finfo = enumerator.next_file()) != null) + { + var fname = finfo.get_name(); + if(fname.down().has_suffix(".conf")) + { + configs.add(dir.get_child(fname).get_path()); + } + } + } + catch(Error e) + { + warning("[DOSBox.find_configs] %s", e.message); + } + + return configs; + } + + private static bool is_dos_executable(File? file) + { + if(file == null || !file.query_exists()) return false; + var type = Utils.run({"file", "-b", file.get_path()}).log(false).run_sync(true).output; + if(type != null && type.length > 0) + { + return "DOS" in type; + } + return false; + } + + public override bool can_run(Runnable runnable) + { + return installed && runnable is Game && runnable.install_dir != null && runnable.install_dir.query_exists() + && (is_dos_executable(runnable.executable) || find_configs(runnable.install_dir).size > 0); + } + + public override async void run(Runnable runnable) + { + if(!can_run(runnable)) return; + + string[] cmd = { executable.get_path() }; + + var wdir = runnable.install_dir; + + var configs = find_configs(runnable.install_dir); + + if(configs.size > 2 && runnable is GameHub.Data.Sources.GOG.GOGGame) + { + foreach(var conf in configs) + { + if(conf.has_suffix("_single.conf")) + { + configs.clear(); + configs.add(conf.replace("_single.conf", ".conf")); + configs.add(conf); + break; + } + } + } + + if(configs.size > 0) + { + foreach(var conf in configs) + { + cmd += "-conf"; + cmd += conf; + } + } + else if(runnable.executable != null) + { + var dos_path = runnable.executable.get_path().replace(runnable.install_dir.get_path(), "").replace("/", "\\"); + var dos_cmdline = dos_path + ((runnable.arguments != null && runnable.arguments.length > 0) ? " " + runnable.arguments : ""); + cmd += "-c"; + cmd += "mount c ."; + cmd += "-c"; + cmd += "c:"; + cmd += "-c"; + cmd += "call " + dos_cmdline; + cmd += "-c"; + cmd += "exit"; + } + + foreach(var conf in additional_configs.entries) + { + if(conf.key.query_exists() && conf.value.enabled) + { + cmd += "-conf"; + cmd += conf.key.get_path(); + } + } + + var bundled_win_dosbox = FSUtils.find_case_insensitive(runnable.install_dir, "dosbox/dosbox.exe"); + if(bundled_win_dosbox != null && bundled_win_dosbox.query_exists()) + { + wdir = bundled_win_dosbox.get_parent(); + } + + var task = Utils.run(combine_cmd_with_args(cmd, runnable)).dir(wdir.get_path()); + if(runnable is TweakableGame) + { + task.tweaks(((TweakableGame) runnable).get_enabled_tweaks(this)); + } + yield task.run_sync_thread(); + } + } +} diff --git a/src/data/compat/Innoextract.vala b/src/data/compat/Innoextract.vala new file mode 100644 index 00000000..e7b30200 --- /dev/null +++ b/src/data/compat/Innoextract.vala @@ -0,0 +1,86 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using GameHub.Utils; + +using GameHub.Data.Sources.Steam; + +namespace GameHub.Data.Compat +{ + public class Innoextract: CompatTool + { + private const int[] MIN_SUPPORTED_VERSION = { 1, 8 }; + + public string binary { get; construct; default = "innoextract"; } + + public string? version { get; construct; default = null; } + + public Innoextract(string binary="innoextract") + { + Object(binary: binary); + } + + construct + { + id = "innoextract"; + name = "Innoextract"; + icon = "package-x-generic-symbolic"; + + executable = Utils.find_executable(binary); + installed = executable != null && executable.query_exists(); + + if(installed) + { + version = Utils.run({executable.get_path(), "-v", "-q", "-c", "0"}).log(false).run_sync(true).output.replace(id, "").strip(); + name = name + " (" + version + ")"; + + if(Utils.compare_versions(Utils.parse_version(version), Innoextract.MIN_SUPPORTED_VERSION) < 0) + { + warnings = { + _("Innoextract %1$s is not supported and may not be able to extract some games correctly.\nInstall innoextract %2$s or newer.") + .printf(version, Utils.format_version(Innoextract.MIN_SUPPORTED_VERSION)) + }; + } + } + } + + public override bool can_install(Runnable runnable) + { + return installed && runnable != null && Platform.WINDOWS in runnable.platforms; + } + + public override async void install(Runnable runnable, File installer) + { + if(!can_install(runnable) || (yield Runnable.Installer.guess_type(installer)) != Runnable.Installer.InstallerType.WINDOWS_EXECUTABLE) return; + + runnable.install_dir = runnable.install_dir ?? runnable.default_install_dir; + + string[] cmd = { executable.get_path(), "-e", "-m", "-d", runnable.install_dir.get_path() }; + if(runnable is Sources.GOG.GOGGame) cmd += "--gog"; + cmd += installer.get_path(); + yield Utils.run(cmd).dir(installer.get_parent().get_path()).run_sync_thread(); + + do + { + FSUtils.mv_up(runnable.install_dir, "__support"); + FSUtils.mv_up(runnable.install_dir, "app"); + } + while(runnable.install_dir.get_child("__support").query_exists()); + } + } +} diff --git a/src/data/compat/Proton.vala b/src/data/compat/Proton.vala new file mode 100644 index 00000000..2ae64052 --- /dev/null +++ b/src/data/compat/Proton.vala @@ -0,0 +1,342 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; + +using GameHub.Data.Sources.Steam; +using GameHub.Utils; + +namespace GameHub.Data.Compat +{ + public class Proton: Wine + { + public const string LATEST = "latest"; + + public string appid { get; construct set; } + public string? appname { get; construct set; } + + public bool is_latest { get; construct set; default = false; } + + public Proton(string appid, string? appname=null) + { + Object(appid: appid, appname: appname, is_latest: appid == LATEST, binary: "", arch: ""); + } + + construct + { + id = @"proton_$(appid)"; + name = appname ?? "Proton"; + icon = "source-steam-symbolic"; + installed = false; + + opt_prefix = new CompatTool.FileOption(Wine.OPT_PREFIX, _("Proton prefix"), null, null, Gtk.FileChooserAction.SELECT_FOLDER); + opt_prefix.icon = icon; + + options = { + opt_prefix, + opt_env + }; + + install_options = { + opt_prefix, + opt_env, + install_opt_innosetup_args + }; + + if(!is_latest) + { + init(); + } + } + + public void init() + { + if(is_latest) + { + name = "Proton (latest)"; + foreach(var tool in CompatTools) + { + if(tool is Proton) + { + var proton = tool as Proton; + if(proton.installed) + { + appid = proton.appid; + executable = proton.executable; + installed = true; + wine_binary = proton.wine_binary; + break; + } + } + } + } + else + { + File? proton_dir = null; + if(Steam.find_app_install_dir(appid, out proton_dir)) + { + if(proton_dir != null) + { + name = appname ?? proton_dir.get_basename(); + executable = proton_dir.get_child("proton"); + installed = executable.query_exists(); + wine_binary = proton_dir.get_child("dist/bin/wine"); + } + } + else + { + name = appname ?? "Proton"; + } + } + + if(installed) + { + actions = { + new CompatTool.Action("prefix", _("Open prefix directory"), r => { + Utils.open_uri(get_wineprefix(r).get_parent().get_uri()); + }), + new CompatTool.Action("winecfg", _("Run winecfg"), r => { + wineutil.begin(r, "winecfg"); + }), + new CompatTool.Action("winetricks", _("Run winetricks"), r => { + winetricks.begin(r); + }), + new CompatTool.Action("taskmgr", _("Run taskmgr"), r => { + wineutil.begin(r, "taskmgr"); + }), + new CompatTool.Action("kill", _("Kill apps in prefix"), r => { + wineboot.begin(r, {"-k"}); + }) + }; + } + } + + protected override async void exec(Runnable runnable, File file, File dir, string[]? args=null, bool parse_opts=true) + { + string[] cmd = { executable.get_path(), "run", file.get_path() }; + if(file.get_path().down().has_suffix(".msi")) + { + cmd = { executable.get_path(), "run", "msiexec", "/i", file.get_path() }; + } + var task = Utils.run(combine_cmd_with_args(cmd, runnable, args)).dir(dir.get_path()).env(prepare_env(runnable, parse_opts)); + if(runnable is TweakableGame) + { + task.tweaks(((TweakableGame) runnable).get_enabled_tweaks(this)); + } + yield task.run_sync_thread(); + } + + public override File get_default_wineprefix(Runnable runnable) + { + var install_dir = runnable.install_dir ?? runnable.default_install_dir; + + var prefix = FSUtils.mkdir(install_dir.get_path(), @"$(FSUtils.GAMEHUB_DIR)/$(FSUtils.COMPAT_DATA_DIR)/$(id)/pfx"); + var dosdevices = prefix.get_child("dosdevices"); + + if(FSUtils.file(install_dir.get_path(), @"$(FSUtils.GAMEHUB_DIR)/$(id)").query_exists()) + { + Utils.run({"bash", "-c", @"mv -f $(FSUtils.GAMEHUB_DIR)/$(id) $(FSUtils.GAMEHUB_DIR)/$(FSUtils.COMPAT_DATA_DIR)/$(id)"}).dir(install_dir.get_path()).run_sync(); + FSUtils.rm(dosdevices.get_child("d:").get_path()); + } + + return prefix; + } + + public override File get_wineprefix(Runnable runnable) + { + var prefix = get_default_wineprefix(runnable); + + if(opt_prefix.file != null && opt_prefix.file.query_exists()) + { + prefix = opt_prefix.file.get_child("pfx"); + } + + var dosdevices = prefix.get_child("dosdevices"); + + if(dosdevices.get_child("c:").query_exists() && dosdevices.get_path().has_prefix(runnable.install_dir.get_path())) + { + var has_symlink = false; + for(var letter = 'd'; letter <= 'y'; letter++) + { + if(is_symlink_and_correct(dosdevices.get_child(@"$(letter):"))) + { + has_symlink = true; + break; + } + } + + for(var letter = 'd'; has_symlink == false && letter <= 'y'; letter++) + { + if(!dosdevices.get_child(@"$(letter):").query_exists() && !dosdevices.get_child(@"$(letter)::").query_exists()) + { + Utils.run({"ln", "-nsf", "../../../../../", @"$(letter):"}).dir(dosdevices.get_path()).run_sync(); + break; + } + } + } + + return prefix; + } + + private bool is_symlink_and_correct(File symlink) + { + if(!symlink.query_exists()) + { + return false; + } + + try + { + var symlink_info = symlink.query_info("*", NONE); + if(symlink_info == null || !symlink_info.get_is_symlink() || symlink_info.get_symlink_target() != "../../../../../") + { + return false; + } + } + catch (Error e) + { + return false; + } + + return true; + } + + protected override string[] prepare_env(Runnable runnable, bool parse_opts=true) + { + var env = base.prepare_env(runnable, parse_opts); + + var dist = executable.get_parent().get_child("dist").get_path(); + env = Environ.set_variable(env, "WINEDLLPATH", @"$(dist)/lib64/wine:$(dist)/lib/wine"); + + var compatdata = get_wineprefix(runnable).get_parent(); + if(compatdata != null && compatdata.query_exists()) + { + env = Environ.set_variable(env, "STEAM_COMPAT_DATA_PATH", compatdata.get_path()); + env = Environ.set_variable(env, "WINEPREFIX", compatdata.get_child("pfx").get_path()); + } + + env = Environ.set_variable(env, "STEAM_COMPAT_CLIENT_INSTALL_PATH", FSUtils.expand(FSUtils.Paths.Steam.Home)); + env = Environ.set_variable(env, "PROTON_LOG", "1"); + + if(parse_opts) + { + foreach(var opt in options) + { + if(opt is CompatTool.BoolOption && ((CompatTool.BoolOption) opt).enabled) + { + env = Environ.set_variable(env, opt.name, "1"); + } + } + } + + return env; + } + + protected override async void wineboot(Runnable runnable, string[]? args=null) + { + if(args == null) + { + yield proton_init_prefix(runnable); + } + + yield wineutil(runnable, "wineboot", args); + } + + protected async void proton_init_prefix(Runnable runnable) + { + var prefix = get_wineprefix(runnable); + if(opt_prefix.file != null && opt_prefix.file.query_exists()) + { + prefix = opt_prefix.file.get_child("pfx"); + } + + var cmd = prefix.get_child("drive_c/windows/system32/cmd.exe"); + + if(!cmd.query_exists()) + { + yield Utils.run({executable.get_path(), "run", cmd.get_path(), "/c", "exit"}) + .dir(runnable.install_dir.get_path()) + .env(prepare_env(runnable)) + .run_sync_thread(true); + } + } + + public void install_app() + { + if(!is_latest && !installed) + { + Steam.install_app(appid); + } + } + + public static void find_proton_versions() + { + if(Steam.instance == null) return; + + Steam.instance.load_appinfo(); + + if(Steam.instance.appinfo == null) return; + + ArrayList versions = new ArrayList(); + + foreach(var app_node in Steam.instance.appinfo.nodes.values) + { + if(app_node != null && app_node is BinaryVDF.ListNode) + { + var app = (BinaryVDF.ListNode) app_node; + var common_node = app.get_nested({"appinfo", "common"}); + + if(common_node != null && common_node is BinaryVDF.ListNode) + { + var common = (BinaryVDF.ListNode) common_node; + + var name_node = common.get("name"); + var type_node = common.get("type"); + + if(name_node != null && name_node is BinaryVDF.StringNode && type_node != null && type_node is BinaryVDF.StringNode) + { + var name = ((BinaryVDF.StringNode) name_node).value; + var type = ((BinaryVDF.StringNode) type_node).value; + + if(type != null && type.down() == "tool" && name != null && name.down().has_prefix("proton ")) + { + versions.add(new Proton(app.key, name)); + } + } + } + } + } + + if(versions.size > 0) + { + versions.sort((first, second) => { + return int.parse(second.appid) - int.parse(first.appid); + }); + + CompatTool[] tools = CompatTools; + + foreach(var proton in versions) + { + tools += proton; + } + + CompatTools = tools; + } + } + } +} diff --git a/src/data/compat/RetroArch.vala b/src/data/compat/RetroArch.vala new file mode 100644 index 00000000..9b8fc7aa --- /dev/null +++ b/src/data/compat/RetroArch.vala @@ -0,0 +1,122 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; + +using GameHub.Utils; + +namespace GameHub.Data.Compat +{ + public class RetroArch: CompatTool + { + public const string LIBRETRO_CORE_SUFFIX = "_libretro.so"; + public const string LIBRETRO_CORE_INFO_SUFFIX = "_libretro.info"; + + public static RetroArch instance; + public ArrayList cores = new ArrayList(); + + public string binary { get; construct; default = "retroarch"; } + public bool has_cores { get; protected set; default = false; } + + private CompatTool.ComboOption core_option; + + public RetroArch(string binary="retroarch") + { + Object(binary: binary); + instance = this; + } + + construct + { + id = @"retroarch"; + name = @"RetroArch"; + icon = "emu-retroarch-symbolic"; + + executable = Utils.find_executable(binary); + installed = executable != null && executable.query_exists(); + + core_option = new CompatTool.ComboOption("core", _("Libretro core file"), cores, null); + + find_cores(); + + options = { core_option }; + } + + public bool find_cores() + { + cores.clear(); + has_cores = false; + core_option.options = cores; + + var dir = FSUtils.file(Settings.Compat.RetroArch.instance.core_dir); + + if(dir == null || !dir.query_exists()) + { + return has_cores; + } + + try + { + FileInfo? finfo = null; + var enumerator = dir.enumerate_children("standard::*", FileQueryInfoFlags.NOFOLLOW_SYMLINKS); + while((finfo = enumerator.next_file()) != null) + { + var fname = finfo.get_name(); + if(fname.has_suffix(LIBRETRO_CORE_SUFFIX)) + { + cores.add(fname.replace(LIBRETRO_CORE_SUFFIX, "")); + } + } + } + catch(Error e) + { + warning("[RetroArch.find_cores] %s", e.message); + } + + has_cores = cores.size > 0; + core_option.options = cores; + + return has_cores; + } + + public override bool can_run(Runnable runnable) + { + return installed && runnable is Game && has_cores; + } + + public override async void run(Runnable runnable) + { + if(!can_run(runnable)) return; + var core = core_option.value; + if(core == null) return; + + if(!core.has_prefix("/")) + { + core = FSUtils.expand(Settings.Compat.RetroArch.instance.core_dir, core); + } + if(!core.has_suffix(LIBRETRO_CORE_SUFFIX)) + { + core += LIBRETRO_CORE_SUFFIX; + } + + string[] cmd = { executable.get_path(), "-L", core, runnable.executable.get_path() }; + + yield Utils.run(combine_cmd_with_args(cmd, runnable)).dir(runnable.work_dir.get_path()).run_sync_thread(); + } + } +} diff --git a/src/data/compat/ScummVM.vala b/src/data/compat/ScummVM.vala new file mode 100644 index 00000000..1be0ca7c --- /dev/null +++ b/src/data/compat/ScummVM.vala @@ -0,0 +1,84 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; + +using GameHub.Utils; + +namespace GameHub.Data.Compat +{ + public class ScummVM: CompatTool + { + private static string SCUMMVM_NO_GAMES_WARNING = "WARNING: ScummVM could not find any game"; + + public string binary { get; construct; default = "scummvm"; } + + public ScummVM(string binary="scummvm") + { + Object(binary: binary); + } + + construct + { + id = "scummvm"; + name = "ScummVM"; + icon = "tool-scummvm-symbolic"; + + executable = Utils.find_executable(binary); + installed = executable != null && executable.query_exists(); + } + + private bool scummvm_detect(File? dir) + { + if(dir != null && dir.query_exists()) + { + var output = Utils.run({executable.get_path(), "--detect"}).dir(dir.get_path()).log(false).run_sync(true).output; + return !(SCUMMVM_NO_GAMES_WARNING in output); + } + return false; + } + + public override bool can_run(Runnable runnable) + { + return installed && runnable is Game + && (scummvm_detect(runnable.install_dir) || scummvm_detect(runnable.install_dir.get_child("data"))); + } + + public override async void run(Runnable runnable) + { + if(!can_run(runnable)) return; + + var dir = runnable.install_dir; + var data_dir = runnable.install_dir.get_child("data"); + + if(!scummvm_detect(dir) && scummvm_detect(data_dir)) + { + dir = data_dir; + } + + string[] cmd = { executable.get_path(), "--auto-detect" }; + + var task = Utils.run(combine_cmd_with_args(cmd, runnable)).dir(dir.get_path()); + if(runnable is TweakableGame) + { + task.tweaks(((TweakableGame) runnable).get_enabled_tweaks(this)); + } + yield task.run_sync_thread(); + } + } +} diff --git a/src/data/compat/Wine.vala b/src/data/compat/Wine.vala new file mode 100644 index 00000000..24880dc9 --- /dev/null +++ b/src/data/compat/Wine.vala @@ -0,0 +1,336 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using GameHub.Utils; + +using GameHub.Data.Sources.Steam; + +namespace GameHub.Data.Compat +{ + public class Wine: CompatTool + { + public const string OPT_PREFIX = "prefix"; + public const string OPT_ENV = "env"; + + public string binary { get; construct; default = "wine"; } + public string arch { get; construct; default = "win64"; } + public File? wine_binary { get; protected set; } + + public CompatTool.FileOption opt_prefix; + public CompatTool.StringOption opt_env; + + public CompatTool.BoolOption install_opt_innosetup_args; + + public Wine(string binary="wine", string arch="win64") + { + Object(binary: binary, arch: arch); + } + + construct + { + id = @"wine_$(binary)_$(arch)"; + name = @"Wine ($(binary)) [arch: $(arch)]"; + icon = "tool-wine-symbolic"; + + executable = wine_binary = Utils.find_executable(binary); + installed = executable != null && executable.query_exists(); + + opt_prefix = new CompatTool.FileOption(Wine.OPT_PREFIX, _("Wine prefix"), null, null, Gtk.FileChooserAction.SELECT_FOLDER); + opt_prefix.icon = icon; + opt_env = new CompatTool.StringOption(Wine.OPT_ENV, _("Environment variables"), null); + opt_env.icon = "utilities-terminal-symbolic"; + + options = { opt_prefix, opt_env }; + + install_opt_innosetup_args = new CompatTool.BoolOption("InnoSetup", _("InnoSetup default options"), true); + + install_options = { + opt_prefix, + opt_env, + install_opt_innosetup_args + }; + + if(installed) + { + actions = { + new CompatTool.Action("prefix", _("Open prefix directory"), r => { + Utils.open_uri(get_wineprefix(r).get_uri()); + }), + new CompatTool.Action("winecfg", _("Run winecfg"), r => { + wineutil.begin(r, "winecfg"); + }), + new CompatTool.Action("winetricks", _("Run winetricks"), r => { + winetricks.begin(r); + }), + new CompatTool.Action("taskmgr", _("Run taskmgr"), r => { + wineutil.begin(r, "taskmgr"); + }), + new CompatTool.Action("kill", _("Kill apps in prefix"), r => { + wineboot.begin(r, {"-k"}); + }) + }; + } + } + + public override bool can_install(Runnable runnable) + { + return can_run(runnable); + } + + public override bool can_run(Runnable runnable) + { + return installed && runnable != null && ((runnable is Game && (runnable is GameHub.Data.Sources.User.UserGame || Platform.WINDOWS in runnable.platforms)) || runnable is Emulator); + } + + public override bool can_run_action(Runnable runnable, Runnable.RunnableAction action) + { + return installed && runnable != null && action != null; + } + + protected virtual async string[] prepare_installer_args(Runnable runnable) + { + var tmp_root = (runnable is Game) ? "_gamehub_game_root" : "_gamehub_app_root"; + var win_path = yield convert_path(runnable, runnable.install_dir.get_child(tmp_root)); + var log_win_path = yield convert_path(runnable, runnable.install_dir.get_child("install.log")); + + string[] opts = {}; + + if(install_opt_innosetup_args.enabled) + { + opts = { "/SP-", "/NOCANCEL", "/NOGUI", "/NOICONS", @"/DIR=$(win_path)", @"/LOG=$(log_win_path)" }; + } + + foreach(var opt in install_options) + { + if(opt.name.has_prefix("/") && opt is CompatTool.BoolOption && ((CompatTool.BoolOption) opt).enabled) + { + opts += opt.name; + } + } + + return opts; + } + + public override async void install(Runnable runnable, File installer) + { + if(!can_install(runnable) || (yield Runnable.Installer.guess_type(installer)) != Runnable.Installer.InstallerType.WINDOWS_EXECUTABLE) return; + yield wineboot(runnable); + yield exec(runnable, installer, installer.get_parent(), yield prepare_installer_args(runnable)); + + var tmp_root = (runnable is Game) ? "_gamehub_game_root" : "_gamehub_app_root"; + if(runnable.install_dir != null && runnable.install_dir.get_child(tmp_root).query_exists()) + { + FSUtils.mv_up(runnable.install_dir, tmp_root); + } + } + + public override async void run(Runnable runnable) + { + if(!can_run(runnable)) return; + yield wineboot(runnable); + yield exec(runnable, runnable.executable, runnable.work_dir, Utils.parse_args(runnable.arguments)); + } + + public override async void run_action(Runnable runnable, Runnable.RunnableAction action) + { + if(!can_run_action(runnable, action)) return; + yield wineboot(runnable); + yield exec(runnable, action.file, action.workdir, Utils.parse_args(action.args)); + } + + public override async void run_emulator(Emulator emu, Game? game, bool launch_in_game_dir=false) + { + if(!can_run(emu)) return; + var dir = game != null && launch_in_game_dir ? game.work_dir : emu.work_dir; + yield exec(emu, emu.executable, dir, emu.get_args(game)); + } + + protected virtual async void exec(Runnable runnable, File file, File dir, string[]? args=null, bool parse_opts=true) + { + string[] cmd = { executable.get_path(), file.get_path() }; + if(file.get_path().down().has_suffix(".msi")) + { + cmd = { executable.get_path(), "msiexec", "/i", file.get_path() }; + } + var task = Utils.run(combine_cmd_with_args(cmd, runnable, args)).dir(dir.get_path()).env(prepare_env(runnable, parse_opts)); + if(runnable is TweakableGame) + { + task.tweaks(((TweakableGame) runnable).get_enabled_tweaks(this)); + } + yield task.run_sync_thread(); + } + + public virtual File get_default_wineprefix(Runnable runnable) + { + var install_dir = runnable.install_dir ?? runnable.default_install_dir; + + var prefix = FSUtils.mkdir(install_dir.get_path(), @"$(FSUtils.GAMEHUB_DIR)/$(FSUtils.COMPAT_DATA_DIR)/$(binary)_$(arch)"); + var dosdevices = prefix.get_child("dosdevices"); + + if(FSUtils.file(install_dir.get_path(), @"$(FSUtils.GAMEHUB_DIR)/$(binary)_$(arch)").query_exists()) + { + Utils.run({"bash", "-c", @"mv -f $(FSUtils.GAMEHUB_DIR)/$(binary)_$(arch) $(FSUtils.GAMEHUB_DIR)/$(FSUtils.COMPAT_DATA_DIR)/$(binary)_$(arch)"}).dir(install_dir.get_path()).run_sync(); + FSUtils.rm(dosdevices.get_child("d:").get_path()); + } + + return prefix; + } + + public virtual File get_wineprefix(Runnable runnable) + { + var prefix = get_default_wineprefix(runnable); + + if(opt_prefix.file != null && opt_prefix.file.query_exists()) + { + prefix = opt_prefix.file; + } + + var dosdevices = prefix.get_child("dosdevices"); + + if(dosdevices.get_child("c:").query_exists() && dosdevices.get_path().has_prefix(runnable.install_dir.get_path())) + { + var has_symlink = false; + for(var letter = 'd'; letter <= 'y'; letter++) + { + if(is_symlink_and_correct(dosdevices.get_child(@"$(letter):"))) + { + has_symlink = true; + break; + } + } + + for(var letter = 'd'; has_symlink == false && letter <= 'y'; letter++) + { + if(!dosdevices.get_child(@"$(letter):").query_exists() && !dosdevices.get_child(@"$(letter)::").query_exists()) + { + Utils.run({"ln", "-nsf", "../../../../", @"$(letter):"}).dir(dosdevices.get_path()).run_sync(); + break; + } + } + } + + return prefix; + } + + private bool is_symlink_and_correct(File symlink) + { + if(!symlink.query_exists()) + { + return false; + } + + try + { + var symlink_info = symlink.query_info("*", NONE); + if(symlink_info == null || !symlink_info.get_is_symlink() || symlink_info.get_symlink_target() != "../../../../") + { + return false; + } + } + catch (Error e) + { + return false; + } + + return true; + } + + public override File get_install_root(Runnable runnable) + { + return get_wineprefix(runnable).get_child("drive_c"); + } + + protected virtual string[] prepare_env(Runnable runnable, bool parse_opts=true) + { + var env = Environ.get(); + env = Environ.set_variable(env, "WINEDLLOVERRIDES", "mshtml=d;winemenubuilder.exe=d"); + + if(wine_binary != null && wine_binary.query_exists()) + { + env = Environ.set_variable(env, "WINE", wine_binary.get_path()); + env = Environ.set_variable(env, "WINELOADER", wine_binary.get_path()); + var wineserver_binary = wine_binary.get_parent().get_child("wineserver"); + if(wineserver_binary.query_exists()) + { + env = Environ.set_variable(env, "WINESERVER", wineserver_binary.get_path()); + } + } + + var prefix = get_wineprefix(runnable); + if(prefix != null && prefix.query_exists()) + { + env = Environ.set_variable(env, "WINEPREFIX", prefix.get_path()); + } + + if(arch != null && arch.length > 0) + { + env = Environ.set_variable(env, "WINEARCH", arch); + } + + if(parse_opts) + { + if(opt_env.value != null && opt_env.value.length > 0) + { + var evars = Utils.parse_args(opt_env.value); + if(evars != null) + { + foreach(var ev in evars) + { + var v = ev.split("="); + env = Environ.set_variable(env, v[0], v[1]); + } + } + } + } + + return env; + } + + protected virtual async void wineboot(Runnable runnable, string[]? args=null) + { + yield wineutil(runnable, "wineboot", args); + } + + protected async void wineutil(Runnable runnable, string util="winecfg", string[]? args=null) + { + string[] cmd = { wine_binary.get_path(), util }; + + if(args != null) + { + foreach(var arg in args) + { + cmd += arg; + } + } + + yield Utils.run(cmd).dir(runnable.install_dir.get_path()).env(prepare_env(runnable)).run_sync_thread(); + } + + protected async void winetricks(Runnable runnable) + { + yield Utils.run({"winetricks"}).dir(runnable.install_dir.get_path()).env(prepare_env(runnable)).run_sync_thread(); + } + + public async string convert_path(Runnable runnable, File path) + { + var win_path = (yield Utils.run({wine_binary.get_path(), "winepath", "-w", path.get_path()}).dir(runnable.install_dir.get_path()).env(prepare_env(runnable)).log(false).run_sync_thread(true)).output.strip(); + debug("[Wine.convert_path] '%s' -> '%s'", path.get_path(), win_path); + return win_path; + } + } +} diff --git a/src/data/compat/WineWrap.vala b/src/data/compat/WineWrap.vala new file mode 100644 index 00000000..12080e0b --- /dev/null +++ b/src/data/compat/WineWrap.vala @@ -0,0 +1,150 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; + +using GameHub.Utils; +using GameHub.Data.Sources.GOG; + +namespace GameHub.Data.Compat +{ + public class WineWrap: CompatTool + { + private const string WRAPPERS_INDEX_URL = "https://dropbox.com/s/dl/kw8t2b5x7b19guz/winewrap_index.json"; + + private HashMap wrappers = new HashMap(); + + public WineWrap() + { + id = "winewrap"; + name = "WineWrap (by adamhm)"; + icon = "tool-wine-symbolic"; + installed = true; + update_index.begin(); + } + + private async void update_index() + { + if(GameHub.Application.log_verbose) + { + debug("[WineWrap] Updating index"); + } + + var root_node = yield Parser.parse_remote_json_file_async(WRAPPERS_INDEX_URL); + if(root_node == null || root_node.get_node_type() != Json.NodeType.OBJECT) return; + var root = root_node.get_object(); + if(root == null) return; + + foreach(var id in root.get_members()) + { + wrappers.set(id, root.get_object_member(id).get_string_member("url")); + } + + if(wrappers.size > 0) + { + actions = { + new CompatTool.Action("play", _("Run"), r => { + action.begin(r, "play"); + }), + new CompatTool.Action("menu", _("Show WineWrap menu"), r => { + action.begin(r, "menu"); + }), + new CompatTool.Action("kill", _("Kill apps in prefix"), r => { + action.begin(r, "kill"); + }) + }; + } + else + { + installed = false; + } + + if(GameHub.Application.log_verbose) + { + debug("[WineWrap] Index updated"); + } + } + + public override bool can_install(Runnable runnable) + { + return installed && runnable != null && runnable is GOGGame && wrappers.has_key(runnable.id); + } + + public override async void install(Runnable runnable, File installer) + { + if(!can_install(runnable)) return; + + var wrapper_dir = FSUtils.mkdir(FSUtils.Paths.Cache.WineWrap, runnable.id); + + FSUtils.rm(wrapper_dir.get_path(), "*", "-rf"); + + var wrapper_remote = File.new_for_uri(wrappers.get(runnable.id)); + var wrapper_local = FSUtils.file(wrapper_dir.get_path(), @"/winewrap_$(runnable.id).tar.xz"); + + try + { + var wrapper = yield Downloader.download_file(wrapper_remote, wrapper_local); + + if(wrapper == null || !wrapper.query_exists()) return; + + string[] cmd = { "tar", "xf", wrapper.get_path(), "-C", wrapper_dir.get_path(), "--strip-components=1" }; + yield Utils.run(cmd).dir(wrapper_dir.get_path()).run_sync_thread(); + + var winewrap_env = Environ.get(); + winewrap_env = Environ.set_variable(winewrap_env, "WINEWRAP_RESPATH", installer.get_parent().get_path()); + winewrap_env = Environ.set_variable(winewrap_env, "WINEWRAP_BUILDPATH", runnable.install_dir.get_parent().get_path()); + winewrap_env = Environ.set_variable(winewrap_env, "WINEWRAP_SKIP_CHECKSUMS", "1"); + + FSUtils.rm(runnable.install_dir.get_path(), null, "-rf"); + + cmd = { "bash", "-c", "./*_wine.sh -dirname=" + (runnable as GOGGame).escaped_name }; + yield Utils.run(cmd).dir(wrapper_dir.get_path()).env(winewrap_env).run_sync_thread(); + + runnable.executable = runnable.install_dir.get_child("start.sh"); + } + catch(Error e) + { + warning("[WineWrap] %s", e.message); + } + } + + public override bool can_run(Runnable runnable) + { + return can_install(runnable) || runnable.compat_tool == id; + } + + public override async void run(Runnable runnable) + { + yield action(runnable, "play"); + } + + private async void action(Runnable runnable, string action) + { + if(!can_run(runnable)) return; + + string[] cmd = { runnable.install_dir.get_child("start.sh").get_path(), action }; + + var task = Utils.run(combine_cmd_with_args(cmd, runnable)).dir(runnable.work_dir.get_path()); + if(runnable is TweakableGame) + { + task.tweaks(((TweakableGame) runnable).get_enabled_tweaks(this)); + } + yield task.run_sync_thread(); + } + } +} diff --git a/src/data/db/Database.vala b/src/data/db/Database.vala new file mode 100644 index 00000000..45063ce8 --- /dev/null +++ b/src/data/db/Database.vala @@ -0,0 +1,123 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; +using Sqlite; + +using GameHub.Utils; + +using GameHub.Data.Sources.Steam; +using GameHub.Data.Sources.GOG; +using GameHub.Data.Sources.Humble; + +namespace GameHub.Data.DB +{ + public class Database + { + public const int VERSION = 11; + public static Table[] TABLES; + + public static Database instance; + + public Sqlite.Database? db = null; + + public Database() + { + instance = this; + + var path = FSUtils.expand(FSUtils.Paths.Cache.Database); + + var db_file = File.new_for_path(path); + var db_backup = db_file.get_parent().get_child(db_file.get_basename() + ".old"); + + bool err = false; + while(Sqlite.Database.open_v2(path, out db, Sqlite.OPEN_READWRITE | Sqlite.OPEN_CREATE) != Sqlite.OK) + { + warning("[Database] Can't open database (%d): %s", db.errcode(), db.errmsg()); + + if(err) + { + error("[Database] Can't recreate database. Remove '%s' manually and make sure GameHub can write into cache directory", path); + } + + err = true; + + try + { + db_file.move(db_backup, FileCopyFlags.BACKUP | FileCopyFlags.OVERWRITE); + } + catch(Error e) + { + error("[Database] Can't backup current database: %s", e.message); + } + } + + TABLES = { new Tables.Games(), new Tables.Tags(), new Tables.Merges(), new Tables.Emulators(), new Tables.IGDBData() }; + + migrate(); + init(); + } + + private void migrate() + { + Statement s; + + int version = 0; + int res = db.prepare_v2("PRAGMA user_version", -1, out s); + + if((res = s.step()) == Sqlite.ROW) + { + version = s.column_int(0); + + debug("[Database.migrate] Latest db version: %d, current: %d", VERSION, version); + + if(version < VERSION) + { + debug("[Database.migrate] Migrating database from version %d to %d", version, VERSION); + + foreach(var table in TABLES) + { + table.migrate(db, version); + } + + debug("[Database.migrate] Migration completed, new version: %d", VERSION); + + res = db.exec(@"PRAGMA user_version = $(VERSION)"); + + if(res != Sqlite.OK) + { + warning("[Database.migrate] Can't update version (%d): %s", db.errcode(), db.errmsg()); + } + } + } + } + + private void init() + { + foreach(var table in TABLES) + { + table.init(db); + } + } + + public static void create() + { + instance = new Database(); + } + } +} diff --git a/src/data/db/Table.vala b/src/data/db/Table.vala new file mode 100644 index 00000000..568e1510 --- /dev/null +++ b/src/data/db/Table.vala @@ -0,0 +1,95 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Sqlite; + +namespace GameHub.Data.DB +{ + public abstract class Table: Object + { + public class Field + { + public int column = 0; + public int column_for_bind = 0; + public Field(int col) + { + column = col; + column_for_bind = col + 1; + } + + public int bind(Statement s, string? str) + { + if(str == null) return bind_null(s); + return s.bind_text(column_for_bind, str); + } + public int bind_int(Statement s, int? i) + { + if(i == null) return bind_null(s); + return s.bind_int(column_for_bind, i); + } + public int bind_int64(Statement s, int64? i) + { + if(i == null) return bind_null(s); + return s.bind_int64(column_for_bind, i); + } + public int bind_bool(Statement s, bool? b) + { + if(b == null) return bind_null(s); + return s.bind_int(column_for_bind, b ? 1 : 0); + } + public int bind_value(Statement s, Sqlite.Value? v) + { + if(v == null) return bind_null(s); + return s.bind_value(column_for_bind, v); + } + public int bind_null(Statement s) + { + return s.bind_null(column_for_bind); + } + + public string? get(Statement s) + { + return s.column_text(column); + } + public int get_int(Statement s) + { + return s.column_int(column); + } + public bool get_bool(Statement s) + { + return get_int(s) == 0 ? false : true; + } + public int64 get_int64(Statement s) + { + return s.column_int64(column); + } + public unowned Sqlite.Value? get_value(Statement s) + { + return s.column_value(column); + } + } + + protected static Table.Field f(int col) + { + return new Table.Field(col); + } + + public abstract void migrate(Sqlite.Database db, int version); + public virtual void init(Sqlite.Database db){} + } +} diff --git a/src/data/db/tables/Emulators.vala b/src/data/db/tables/Emulators.vala new file mode 100644 index 00000000..c5a1ec1a --- /dev/null +++ b/src/data/db/tables/Emulators.vala @@ -0,0 +1,247 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; +using Sqlite; + +using GameHub.Utils; + +using GameHub.Data; + +namespace GameHub.Data.DB.Tables +{ + public class Emulators: Table + { + public static Emulators instance; + + public static Table.Field ID; + public static Table.Field NAME; + public static Table.Field INSTALL_PATH; + public static Table.Field EXECUTABLE; + public static Table.Field COMPAT_TOOL; + public static Table.Field COMPAT_TOOL_SETTINGS; + public static Table.Field ARGUMENTS; + public static Table.Field GAME_EXECUTABLE_PATTERN; + public static Table.Field GAME_IMAGE_PATTERN; + public static Table.Field GAME_ICON_PATTERN; + public static Table.Field WORK_DIR; + + public Emulators() + { + instance = this; + + ID = f(0); + NAME = f(1); + INSTALL_PATH = f(2); + EXECUTABLE = f(3); + COMPAT_TOOL = f(4); + COMPAT_TOOL_SETTINGS = f(5); + ARGUMENTS = f(6); + GAME_EXECUTABLE_PATTERN = f(7); + GAME_IMAGE_PATTERN = f(8); + GAME_ICON_PATTERN = f(9); + WORK_DIR = f(10); + } + + public override void migrate(Sqlite.Database db, int version) + { + for(int ver = version; ver < Database.VERSION; ver++) + { + switch(ver) + { + case 3: + db.exec("CREATE TABLE `emulators`( + `id` string not null, + `name` string not null, + `install_path` string, + `executable` string, + `compat_tool` string, + `compat_tool_settings` string, + `arguments` string, + PRIMARY KEY(`id`))"); + break; + + case 5: + db.exec("ALTER TABLE `emulators` ADD `game_executable_pattern` string"); + break; + + case 6: + db.exec("ALTER TABLE `emulators` ADD `game_image_pattern` string"); + db.exec("ALTER TABLE `emulators` ADD `game_icon_pattern` string"); + break; + + case 10: + db.exec("ALTER TABLE `emulators` ADD `work_dir` string"); + break; + } + } + } + + public static bool add(Emulator emu) + { + unowned Sqlite.Database? db = Database.instance.db; + if(db == null) return false; + + Statement s; + int res = db.prepare_v2("INSERT OR REPLACE INTO `emulators`( + `id`, + `name`, + `install_path`, + `executable`, + `compat_tool`, + `compat_tool_settings`, + `arguments`, + `game_executable_pattern`, + `game_image_pattern`, + `game_icon_pattern`, + `work_dir`) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", -1, out s); + + if(res != Sqlite.OK) + { + warning("[Database.Emulators.add] Can't prepare INSERT query (%d): %s", db.errcode(), db.errmsg()); + return false; + } + + ID.bind(s, emu.id); + NAME.bind(s, emu.name); + EXECUTABLE.bind(s, emu.executable == null || !emu.executable.query_exists() ? null : emu.executable.get_path()); + INSTALL_PATH.bind(s, emu.install_dir == null || !emu.install_dir.query_exists() ? null : emu.install_dir.get_path()); + COMPAT_TOOL.bind(s, emu.compat_tool); + COMPAT_TOOL_SETTINGS.bind(s, emu.compat_tool_settings); + ARGUMENTS.bind(s, emu.arguments); + GAME_EXECUTABLE_PATTERN.bind(s, emu.game_executable_pattern); + GAME_IMAGE_PATTERN.bind(s, emu.game_image_pattern); + GAME_ICON_PATTERN.bind(s, emu.game_icon_pattern); + WORK_DIR.bind(s, emu.work_dir == null || !emu.work_dir.query_exists() ? null : emu.work_dir.get_path()); + + res = s.step(); + + if(res != Sqlite.DONE) + { + warning("[Database.Emulators.add] Error (%d): %s", db.errcode(), db.errmsg()); + return false; + } + + return true; + } + + public static bool remove(Emulator emu) + { + unowned Sqlite.Database? db = Database.instance.db; + if(db == null) return false; + + Statement s; + int res = db.prepare_v2("DELETE FROM `emulators` WHERE `id` = ?", -1, out s); + + if(res != Sqlite.OK) + { + warning("[Database.Emulators.remove] Can't prepare DELETE query (%d): %s", db.errcode(), db.errmsg()); + return false; + } + + res = s.bind_text(1, emu.id); + + res = s.step(); + + if(res != Sqlite.DONE) + { + warning("[Database.Emulators.remove] Error (%d): %s", db.errcode(), db.errmsg()); + return false; + } + + return true; + } + + public static new Emulator? get(string id) + { + if(id == null) return null; + + unowned Sqlite.Database? db = Database.instance.db; + if(db == null) return null; + + Statement st; + int res = db.prepare_v2("SELECT * FROM `emulators` WHERE `id` = ?", -1, out st); + + if(res != Sqlite.OK) + { + warning("[Database.Emulators.get] Can't prepare SELECT query (%d): %s", db.errcode(), db.errmsg()); + return null; + } + + res = st.bind_text(1, id); + + if((res = st.step()) == Sqlite.ROW) + { + return new Emulator.from_db(st); + } + + return null; + } + + public static Emulator? by_name(string name) + { + if(name == null) return null; + + unowned Sqlite.Database? db = Database.instance.db; + if(db == null) return null; + + Statement st; + int res = db.prepare_v2("SELECT * FROM `emulators` WHERE `name` = ?", -1, out st); + + if(res != Sqlite.OK) + { + warning("[Database.Emulators.get] Can't prepare SELECT query (%d): %s", db.errcode(), db.errmsg()); + return null; + } + + res = st.bind_text(1, name); + + if((res = st.step()) == Sqlite.ROW) + { + return new Emulator.from_db(st); + } + + return null; + } + + public static ArrayList? get_all() + { + unowned Sqlite.Database? db = Database.instance.db; + if(db == null) return null; + + Statement st; + int res = db.prepare_v2("SELECT * FROM `emulators` ORDER BY `name` ASC", -1, out st); + + if(res != Sqlite.OK) + { + warning("[Database.Emulators.get_all] Can't prepare SELECT query (%d): %s", db.errcode(), db.errmsg()); + return null; + } + + var emus = new ArrayList(Emulator.is_equal); + + while((res = st.step()) == Sqlite.ROW) + { + emus.add(new Emulator.from_db(st)); + } + + return emus; + } + } +} diff --git a/src/data/db/tables/Games.vala b/src/data/db/tables/Games.vala new file mode 100644 index 00000000..c7fcbda5 --- /dev/null +++ b/src/data/db/tables/Games.vala @@ -0,0 +1,437 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; +using Sqlite; + +using GameHub.Utils; + +using GameHub.Data.Sources.Steam; +using GameHub.Data.Sources.GOG; +using GameHub.Data.Sources.Humble; +using GameHub.Data.Sources.Itch; +using GameHub.Data.Sources.User; + +namespace GameHub.Data.DB.Tables +{ + public class Games: Table + { + public static Games instance; + + private static HashMap cache; + + public static Table.Field SOURCE; + public static Table.Field ID; + public static Table.Field NAME; + public static Table.Field INFO; + public static Table.Field INFO_DETAILED; + public static Table.Field ICON; + public static Table.Field IMAGE; + public static Table.Field TAGS; + public static Table.Field INSTALL_PATH; + public static Table.Field EXECUTABLE; + public static Table.Field PLATFORMS; + public static Table.Field COMPAT_TOOL; + public static Table.Field COMPAT_TOOL_SETTINGS; + public static Table.Field ARGUMENTS; + public static Table.Field LAST_LAUNCH; + public static Table.Field PLAYTIME_SOURCE; + public static Table.Field PLAYTIME_TRACKED; + public static Table.Field IMAGE_VERTICAL; + public static Table.Field TWEAKS; + public static Table.Field WORK_DIR; + + public Games() + { + instance = this; + + cache = new HashMap(); + + SOURCE = f(0); + ID = f(1); + NAME = f(2); + INFO = f(3); + INFO_DETAILED = f(4); + ICON = f(5); + IMAGE = f(6); + TAGS = f(7); + INSTALL_PATH = f(8); + EXECUTABLE = f(9); + PLATFORMS = f(10); + COMPAT_TOOL = f(11); + COMPAT_TOOL_SETTINGS = f(12); + ARGUMENTS = f(13); + LAST_LAUNCH = f(14); + PLAYTIME_SOURCE = f(15); + PLAYTIME_TRACKED = f(16); + IMAGE_VERTICAL = f(17); + TWEAKS = f(18); + WORK_DIR = f(19); + } + + public override void migrate(Sqlite.Database db, int version) + { + for(int ver = version; ver < Database.VERSION; ver++) + { + switch(ver) + { + case 0: + db.exec("CREATE TABLE `games`( + `source` string not null, + `id` string not null, + `name` string not null, + `info` string, + `info_detailed` string, + `icon` string, + `image` string, + `tags` string, + `install_path` string, + `executable` string, + `platforms` string, + `compat_tool` string, + `compat_tool_settings` string, + PRIMARY KEY(`source`, `id`))"); + break; + + case 1: + db.exec("ALTER TABLE `games` ADD `arguments` string"); + break; + + case 2: + db.exec("ALTER TABLE `games` ADD `last_launch` integer not null default 0"); + break; + + case 4: + db.exec("ALTER TABLE `games` ADD `playtime_source` integer not null default 0"); + db.exec("ALTER TABLE `games` ADD `playtime_tracked` integer not null default 0"); + break; + + case 8: + db.exec("ALTER TABLE `games` ADD `image_vertical` string"); + break; + + case 9: + db.exec("ALTER TABLE `games` ADD `tweaks` string"); + break; + + case 10: + db.exec("ALTER TABLE `games` ADD `work_dir` string"); + break; + } + } + } + + public static bool add(Game game) + { + lock(cache) + { + if(!cache.has_key(game.full_id)) + { + cache.set(game.full_id, game); + } + } + + if(game is Sources.GOG.GOGGame.DLC) return false; + + unowned Sqlite.Database? db = Database.instance.db; + if(db == null) return false; + + Statement s; + int res = db.prepare_v2("INSERT OR REPLACE INTO `games`( + `source`, + `id`, + `name`, + `info`, + `info_detailed`, + `icon`, + `image`, + `tags`, + `install_path`, + `executable`, + `platforms`, + `compat_tool`, + `compat_tool_settings`, + `arguments`, + `last_launch`, + `playtime_source`, + `playtime_tracked`, + `image_vertical`, + `tweaks`, + `work_dir`) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", -1, out s); + + if(res != Sqlite.OK) + { + warning("[Database.Games.add] Can't prepare INSERT query (%d): %s", db.errcode(), db.errmsg()); + return false; + } + + var platforms = ""; + foreach(var p in game.platforms) + { + if(platforms.length > 0) platforms += ","; + platforms += p.id(); + } + + var tags = ""; + foreach(var t in game.tags) + { + if(tags.length > 0) tags += ","; + tags += t.id; + } + + string? tweaks = null; + if(game is TweakableGame && ((TweakableGame) game).tweaks != null) + { + tweaks = ""; + foreach(var t in ((TweakableGame) game).tweaks) + { + if(tweaks.length > 0) tweaks += ","; + tweaks += t; + } + } + + SOURCE.bind(s, game.source.id); + ID.bind(s, game.id); + NAME.bind(s, game.name); + INFO.bind(s, game.info); + INFO_DETAILED.bind(s, game.info_detailed); + ICON.bind(s, game.icon); + IMAGE.bind(s, game.image); + TAGS.bind(s, tags); + EXECUTABLE.bind(s, game.executable_path == null ? null : game.executable_path); + INSTALL_PATH.bind(s, game.install_dir == null ? null : game.install_dir.get_path()); + PLATFORMS.bind(s, platforms); + COMPAT_TOOL.bind(s, game.compat_tool); + COMPAT_TOOL_SETTINGS.bind(s, game.compat_tool_settings); + ARGUMENTS.bind(s, game.arguments); + LAST_LAUNCH.bind_int64(s, game.last_launch); + PLAYTIME_SOURCE.bind_int64(s, game.playtime_source); + PLAYTIME_TRACKED.bind_int64(s, game.playtime_tracked); + IMAGE_VERTICAL.bind(s, game.image_vertical); + TWEAKS.bind(s, tweaks); + WORK_DIR.bind(s, game.work_dir == null ? null : game.work_dir_path); + + res = s.step(); + + if(res != Sqlite.DONE) + { + warning("[Database.Games.add] Error (%d): %s", db.errcode(), db.errmsg()); + return false; + } + + return true; + } + + public static bool remove(Game game) + { + lock(cache) + { + if(cache.has_key(game.full_id)) + { + cache.unset(game.full_id); + } + } + + unowned Sqlite.Database? db = Database.instance.db; + if(db == null) return false; + + Statement s; + int res = db.prepare_v2("DELETE FROM `games` WHERE `source` = ? AND `id` = ?", -1, out s); + + if(res != Sqlite.OK) + { + warning("[Database.Games.remove] Can't prepare DELETE query (%d): %s", db.errcode(), db.errmsg()); + return false; + } + + res = s.bind_text(1, game.source.id); + res = s.bind_text(2, game.id); + + res = s.step(); + + if(res != Sqlite.DONE) + { + warning("[Database.Games.remove] Error (%d): %s", db.errcode(), db.errmsg()); + return false; + } + + return true; + } + + public static new Game? get(string src, string id) + { + if(src == null || id == null) return null; + + lock(cache) + { + if(cache.has_key(@"$(src):$(id)")) + { + return cache.get(@"$(src):$(id)"); + } + } + + unowned Sqlite.Database? db = Database.instance.db; + if(db == null) return null; + + Statement st; + int res; + + res = db.prepare_v2("SELECT * FROM `games` WHERE `source` = ? AND `id` = ?", -1, out st); + res = st.bind_text(1, src); + res = st.bind_text(2, id); + + if(res != Sqlite.OK) + { + warning("[Database.Games.get] Can't prepare SELECT query (%d): %s", db.errcode(), db.errmsg()); + return null; + } + + if((res = st.step()) == Sqlite.ROW) + { + var s = GameSource.by_id(SOURCE.get(st)); + Game? g = null; + + if(s is Steam) + { + g = new SteamGame.from_db((Steam) s, st); + } + else if(s is GOG) + { + g = new GOGGame.from_db((GOG) s, st); + } + else if(s is Trove) + { + g = new HumbleGame.from_db((Trove) s, st); + } + else if(s is Humble) + { + g = new HumbleGame.from_db((Humble) s, st); + } + else if(s is Itch) + { + g = new ItchGame.from_db((Itch) s, st); + } + else if(s is User) + { + g = new UserGame.from_db((User) s, st); + } + + if(g != null) + { + lock(cache) + { + cache.set(g.full_id, g); + } + } + + return g; + } + + return null; + } + + public static ArrayList? get_all(GameSource? src = null) + { + unowned Sqlite.Database? db = Database.instance.db; + if(db == null) return null; + + Statement st; + int res; + + if(src != null) + { + res = db.prepare_v2("SELECT * FROM `games` WHERE `source` = ? ORDER BY (CASE WHEN `tags` LIKE ? THEN 1 ELSE 2 END), `name` ASC", -1, out st); + res = st.bind_text(1, src.id); + res = st.bind_text(2, "%" + Tags.BUILTIN_INSTALLED.id + "%"); + } + else + { + res = db.prepare_v2("SELECT * FROM `games` ORDER BY (CASE WHEN `tags` LIKE ? THEN 1 ELSE 2 END), `name` ASC", -1, out st); + res = st.bind_text(1, "%" + Tags.BUILTIN_INSTALLED.id + "%"); + } + + if(res != Sqlite.OK) + { + warning("[Database.Games.get_all] Can't prepare SELECT query (%d): %s", db.errcode(), db.errmsg()); + return null; + } + + var games = new ArrayList(Game.is_equal); + + while((res = st.step()) == Sqlite.ROW) + { + var s = GameSource.by_id(SOURCE.get(st)); + + Game? g = null; + + var full_id = SOURCE.get(st) + ":" + ID.get(st); + + lock(cache) + { + if(cache.has_key(full_id)) + { + g = cache.get(full_id); + } + } + + if(g == null) + { + if(s is Steam) + { + g = new SteamGame.from_db((Steam) s, st); + } + else if(s is GOG) + { + g = new GOGGame.from_db((GOG) s, st); + } + else if(s is Trove) + { + g = new HumbleGame.from_db((Trove) s, st); + } + else if(s is Humble) + { + g = new HumbleGame.from_db((Humble) s, st); + } + else if(s is Itch) + { + g = new ItchGame.from_db((Itch) s, st); + } + else if(s is User) + { + g = new UserGame.from_db((User) s, st); + } + } + + if(g != null) + { + games.add(g); + lock(cache) + { + if(!cache.has_key(g.full_id)) + { + cache.set(g.full_id, g); + } + } + } + } + + return games; + } + } +} diff --git a/src/data/db/tables/IGDBData.vala b/src/data/db/tables/IGDBData.vala new file mode 100644 index 00000000..6c151437 --- /dev/null +++ b/src/data/db/tables/IGDBData.vala @@ -0,0 +1,203 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; +using Sqlite; + +using GameHub.Utils; + +using GameHub.Data.Sources.Steam; +using GameHub.Data.Sources.GOG; +using GameHub.Data.Sources.Humble; + +namespace GameHub.Data.DB.Tables +{ + public class IGDBData: Table + { + public static IGDBData instance; + + public static Table.Field GAME; + public static Table.Field DATA; + public static Table.Field INDEX; + + public IGDBData() + { + instance = this; + + GAME = f(0); + DATA = f(1); + INDEX = f(2); + } + + public override void migrate(Sqlite.Database db, int version) + { + for(int ver = version; ver < Database.VERSION; ver++) + { + switch(ver) + { + case 7: + db.exec("CREATE TABLE `igdb_data`( + `game` string not null, + `data` string, + PRIMARY KEY(`game`))"); + break; + + case 8: + db.exec("ALTER TABLE `igdb_data` ADD `index` integer not null default 0"); + break; + } + } + } + + public static bool add(Game game, string? data) + { + unowned Sqlite.Database? db = Database.instance.db; + if(db == null || data == null) return false; + + Statement s; + int res = db.prepare_v2("INSERT OR REPLACE INTO `igdb_data`( + `game`, + `data`) + VALUES (?, ?)", -1, out s); + + if(res != Sqlite.OK) + { + warning("[Database.IGDBData.add] Can't prepare INSERT query (%d): %s", db.errcode(), db.errmsg()); + return false; + } + + GAME.bind(s, game.full_id); + DATA.bind(s, data); + + res = s.step(); + + if(res != Sqlite.DONE) + { + warning("[Database.IGDBData.add] Error (%d): %s", db.errcode(), db.errmsg()); + return false; + } + + return true; + } + + public static bool set_index(Game game, int index) + { + unowned Sqlite.Database? db = Database.instance.db; + if(db == null) return false; + + Statement s; + int res = db.prepare_v2("UPDATE `igdb_data` SET `index` = ? WHERE `game` = ?", -1, out s); + + if(res != Sqlite.OK) + { + warning("[Database.IGDBData.set_index] Can't prepare UPDATE query (%d): %s", db.errcode(), db.errmsg()); + return false; + } + + s.bind_int(1, index); + s.bind_text(2, game.full_id); + + res = s.step(); + + if(res != Sqlite.DONE) + { + warning("[Database.IGDBData.set_index] Error (%d): %s", db.errcode(), db.errmsg()); + return false; + } + + return true; + } + + public static new string? get(Game game) + { + unowned Sqlite.Database? db = Database.instance.db; + if(db == null) return null; + + Statement s; + + int res = db.prepare_v2("SELECT * FROM `igdb_data` WHERE `game` = ? LIMIT 1", -1, out s); + + if(res != Sqlite.OK) + { + warning("[Database.IGDBData.get] Can't prepare SELECT query (%d): %s", db.errcode(), db.errmsg()); + return null; + } + + s.bind_text(1, game.full_id); + + if((res = s.step()) == Sqlite.ROW) + { + return DATA.get(s); + } + + return null; + } + + public static int get_index(Game game) + { + unowned Sqlite.Database? db = Database.instance.db; + if(db == null) return 0; + + Statement s; + + int res = db.prepare_v2("SELECT * FROM `igdb_data` WHERE `game` = ? LIMIT 1", -1, out s); + + if(res != Sqlite.OK) + { + warning("[Database.IGDBData.get_index] Can't prepare SELECT query (%d): %s", db.errcode(), db.errmsg()); + return 0; + } + + s.bind_text(1, game.full_id); + + if((res = s.step()) == Sqlite.ROW) + { + return INDEX.get_int(s); + } + + return 0; + } + + public static bool remove(Game game) + { + unowned Sqlite.Database? db = Database.instance.db; + if(db == null) return false; + + Statement s; + int res = db.prepare_v2("DELETE FROM `igdb_data` WHERE `game` = ?", -1, out s); + + if(res != Sqlite.OK) + { + warning("[Database.IGDBData.remove] Can't prepare DELETE query (%d): %s", db.errcode(), db.errmsg()); + return false; + } + + res = s.bind_text(1, game.full_id); + + res = s.step(); + + if(res != Sqlite.DONE) + { + warning("[Database.IGDBData.remove] Error (%d): %s", db.errcode(), db.errmsg()); + return false; + } + + return true; + } + } +} diff --git a/src/data/db/tables/Merges.vala b/src/data/db/tables/Merges.vala new file mode 100644 index 00000000..6e617f74 --- /dev/null +++ b/src/data/db/tables/Merges.vala @@ -0,0 +1,254 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; +using Sqlite; + +using GameHub.Utils; + +using GameHub.Data.Sources.Steam; +using GameHub.Data.Sources.GOG; +using GameHub.Data.Sources.Humble; + +namespace GameHub.Data.DB.Tables +{ + public class Merges: Table + { + public static Merges instance; + + public static Table.Field MERGE; + + public Merges() + { + instance = this; + + MERGE = f(0); + } + + public override void migrate(Sqlite.Database db, int version) + { + for(int ver = version; ver < Database.VERSION; ver++) + { + switch(ver) + { + case 0: + db.exec("CREATE TABLE `merges`( + `merge` string not null, + PRIMARY KEY(`merge`))"); + break; + } + } + } + + public static bool add(Game first, Game second) + { + if(first is Sources.GOG.GOGGame.DLC || second is Sources.GOG.GOGGame.DLC) return false; + + unowned Sqlite.Database? db = Database.instance.db; + if(db == null) return false; + + Statement s; + + int res = db.prepare_v2("SELECT rowid, * FROM `merges` WHERE `merge` LIKE ? OR `merge` LIKE ? OR `merge` LIKE ? OR `merge` LIKE ? OR `merge` LIKE ? OR `merge` LIKE ?", -1, out s); + + if(res != Sqlite.OK) + { + warning("[Database.Merges.add] Can't prepare SELECT query (%d): %s", db.errcode(), db.errmsg()); + return false; + } + + s.bind_text(1, @"$(first.full_id)|%"); + s.bind_text(2, @"%|$(first.full_id)|%"); + s.bind_text(3, @"%|$(first.full_id)"); + s.bind_text(4, @"$(second.full_id)|%"); + s.bind_text(5, @"%|$(second.full_id)|%"); + s.bind_text(6, @"%|$(second.full_id)"); + + int64? row = null; + int merge_var = 1; + + string old_merge = null; + + if((res = s.step()) == Sqlite.ROW) + { + row = s.column_int64(0); + old_merge = s.column_text(1); + merge_var = 2; + res = db.prepare_v2("INSERT OR REPLACE INTO `merges`(rowid, `merge`) VALUES (?, ?)", -1, out s); + } + else + { + res = db.prepare_v2("INSERT OR REPLACE INTO `merges`(`merge`) VALUES (?)", -1, out s); + } + + if(res != Sqlite.OK) + { + warning("[Database.Merges.add] Can't prepare INSERT query (%d): %s", db.errcode(), db.errmsg()); + return false; + } + + string[] games = {}; + if(old_merge != null) + { + foreach(var gameid in old_merge.split("|")) + { + if(!(gameid in games)) games += gameid; + } + } + + if(!(first.full_id in games)) games += first.full_id; + if(!(second.full_id in games)) games += second.full_id; + + var new_merge = string.joinv("|", games); + s.bind_text(merge_var, new_merge); + + res = s.step(); + + if(res != Sqlite.DONE) + { + warning("[Database.Merges.add] Error (%d): %s", db.errcode(), db.errmsg()); + return false; + } + + return true; + } + + public static new ArrayList? get(Game game) + { + unowned Sqlite.Database? db = Database.instance.db; + if(db == null) return null; + + Statement s; + + int res = db.prepare_v2("SELECT * FROM `merges` WHERE `merge` LIKE ?", -1, out s); + + if(res != Sqlite.OK) + { + warning("[Database.Merges.get] Can't prepare SELECT query (%d): %s", db.errcode(), db.errmsg()); + return null; + } + + s.bind_text(1, @"$(game.full_id)|%"); + + ArrayList? games = null; + while((res = s.step()) == Sqlite.ROW) + { + var merge = s.column_text(0); + if(merge != null) + { + if(games == null) games = new ArrayList(Game.is_equal); + + foreach(var gameid in merge.split("|")) + { + var gparts = gameid.split(":"); + var gsrc = gparts[0]; + var gid = gparts[1]; + + if(gsrc == null || gid == null) continue; + + var g = Games.get(gsrc, gid); + + if(g != null && !games.contains(g) && !Game.is_equal(game, g)) games.add(g); + } + } + } + return games; + } + + public static Game? get_primary(Game game) + { + unowned Sqlite.Database? db = Database.instance.db; + if(db == null) return null; + + Statement s; + + int res = db.prepare_v2("SELECT * FROM `merges` WHERE `merge` LIKE ? OR `merge` LIKE ? LIMIT 1", -1, out s); + + if(res != Sqlite.OK) + { + warning("[Database.Merges.is_game_merged] Can't prepare SELECT query (%d): %s", db.errcode(), db.errmsg()); + return null; + } + + s.bind_text(1, @"%|$(game.full_id)|%"); + s.bind_text(2, @"%|$(game.full_id)"); + + if((res = s.step()) == Sqlite.ROW) + { + var merge = s.column_text(0); + + if(merge != null) + { + foreach(var gameid in merge.split("|")) + { + var gparts = gameid.split(":"); + var gsrc = gparts[0]; + var gid = gparts[1]; + + if(gsrc == null || gid == null) continue; + + return Games.get(gsrc, gid); + } + } + } + + return null; + } + + public static bool is_game_merged(Game game) + { + unowned Sqlite.Database? db = Database.instance.db; + if(db == null) return false; + + Statement s; + + int res = db.prepare_v2("SELECT * FROM `merges` WHERE `merge` LIKE ? OR `merge` LIKE ? LIMIT 1", -1, out s); + + if(res != Sqlite.OK) + { + warning("[Database.Merges.is_game_merged] Can't prepare SELECT query (%d): %s", db.errcode(), db.errmsg()); + return false; + } + + s.bind_text(1, @"%|$(game.full_id)|%"); + s.bind_text(2, @"%|$(game.full_id)"); + + return s.step() == Sqlite.ROW; + } + + public static bool is_game_merged_as_primary(Game game) + { + unowned Sqlite.Database? db = Database.instance.db; + if(db == null) return false; + + Statement s; + + int res = db.prepare_v2("SELECT * FROM `merges` WHERE `merge` LIKE ? LIMIT 1", -1, out s); + + if(res != Sqlite.OK) + { + warning("[Database.Merges.is_game_merged_as_primary] Can't prepare SELECT query (%d): %s", db.errcode(), db.errmsg()); + return false; + } + + s.bind_text(1, @"$(game.full_id)|%"); + + return s.step() == Sqlite.ROW; + } + } +} diff --git a/src/data/db/tables/Tags.vala b/src/data/db/tables/Tags.vala new file mode 100644 index 00000000..dfcad4a0 --- /dev/null +++ b/src/data/db/tables/Tags.vala @@ -0,0 +1,281 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; +using Sqlite; + +using GameHub.Utils; + +using GameHub.Data.Sources.Steam; +using GameHub.Data.Sources.GOG; +using GameHub.Data.Sources.Humble; + +namespace GameHub.Data.DB.Tables +{ + public class Tags: Table + { + public static Tags instance; + + public static Table.Field ID; + public static Table.Field NAME; + public static Table.Field ICON; + public static Table.Field SELECTED; + + public static ArrayList TAGS; + public static ArrayList DYNAMIC_TAGS; + + public static Tag BUILTIN_FAVORITES; + public static Tag BUILTIN_UNINSTALLED; + public static Tag BUILTIN_INSTALLED; + public static Tag BUILTIN_HIDDEN; + + public signal void tags_updated(); + + public Tags() + { + instance = this; + + ID = f(0); + NAME = f(1); + ICON = f(2); + SELECTED = f(3); + + TAGS = new ArrayList(Tag.is_equal); + DYNAMIC_TAGS = new ArrayList(Tag.is_equal); + } + + public override void migrate(Sqlite.Database db, int version) + { + for(int ver = version; ver < Database.VERSION; ver++) + { + switch(ver) + { + case 0: + db.exec("CREATE TABLE `tags`( + `id` string, + `name` string, + `icon` string, + `selected` int, + PRIMARY KEY(`id`))"); + break; + } + } + } + + public override void init(Sqlite.Database db) + { + Statement s; + + int res = db.prepare_v2("SELECT * FROM `tags` ORDER BY SUBSTR(`id`, 1, 1) ASC, `name` ASC", -1, out s); + while((res = s.step()) == Sqlite.ROW) + { + var tag = new Tag.from_db(s); + if(!TAGS.contains(tag)) TAGS.add(tag); + + if(BUILTIN_FAVORITES == null && tag.id == Tag.BUILTIN_PREFIX + Tag.Builtin.FAVORITES.id()) BUILTIN_FAVORITES = tag; + if(BUILTIN_UNINSTALLED == null && tag.id == Tag.BUILTIN_PREFIX + Tag.Builtin.UNINSTALLED.id()) BUILTIN_UNINSTALLED = tag; + if(BUILTIN_INSTALLED == null && tag.id == Tag.BUILTIN_PREFIX + Tag.Builtin.INSTALLED.id()) BUILTIN_INSTALLED = tag; + if(BUILTIN_HIDDEN == null && tag.id == Tag.BUILTIN_PREFIX + Tag.Builtin.HIDDEN.id()) BUILTIN_HIDDEN = tag; + } + + Tag.Builtin[] builtin = { Tag.Builtin.FAVORITES, Tag.Builtin.UNINSTALLED, Tag.Builtin.INSTALLED, Tag.Builtin.HIDDEN }; + + foreach(var bt in builtin) + { + var tag = new Tag.from_builtin(bt); + Tags.add(tag); + + if(BUILTIN_FAVORITES == null && tag.id == Tag.BUILTIN_PREFIX + Tag.Builtin.FAVORITES.id()) BUILTIN_FAVORITES = tag; + if(BUILTIN_UNINSTALLED == null && tag.id == Tag.BUILTIN_PREFIX + Tag.Builtin.UNINSTALLED.id()) BUILTIN_UNINSTALLED = tag; + if(BUILTIN_INSTALLED == null && tag.id == Tag.BUILTIN_PREFIX + Tag.Builtin.INSTALLED.id()) BUILTIN_INSTALLED = tag; + if(BUILTIN_HIDDEN == null && tag.id == Tag.BUILTIN_PREFIX + Tag.Builtin.HIDDEN.id()) BUILTIN_HIDDEN = tag; + } + + DYNAMIC_TAGS.add(BUILTIN_UNINSTALLED); + DYNAMIC_TAGS.add(BUILTIN_INSTALLED); + + var settings = GameHub.Settings.UI.Behavior.instance; + settings.notify["import-tags"].connect(() => { + foreach(var tag in TAGS) + { + if(tag.id.has_prefix(Tag.IMPORTED_GOG_PREFIX)) + { + tag.enabled = settings.import_tags; + } + } + tags_updated(); + }); + settings.notify_property("import-tags"); + } + + public static bool add(Tag tag, bool replace=false) + { + unowned Sqlite.Database? db = Database.instance.db; + if(db == null) return false; + + Statement s; + int res = db.prepare_v2("INSERT OR " + (replace ? "REPLACE" : "IGNORE") + " INTO `tags` (`id`, `name`, `icon`, `selected`) VALUES (?, ?, ?, ?)", -1, out s); + + if(res != Sqlite.OK) + { + warning("[Database.Tags.add] Can't prepare INSERT query (%d): %s", db.errcode(), db.errmsg()); + return false; + } + + ID.bind(s, tag.id); + NAME.bind(s, tag.name); + ICON.bind(s, tag.icon); + SELECTED.bind_bool(s, tag.selected); + + res = s.step(); + + if(!TAGS.contains(tag)) + { + TAGS.add(tag); + if(tag.id.has_prefix(Tag.IMPORTED_GOG_PREFIX)) + { + tag.enabled = GameHub.Settings.UI.Behavior.instance.import_tags; + } + instance.tags_updated(); + } + + if(res != Sqlite.DONE) + { + warning("[Database.Tags.add] Error (%d): %s", db.errcode(), db.errmsg()); + return false; + } + + return true; + } + + public static bool remove(Tag tag) + { + unowned Sqlite.Database? db = Database.instance.db; + if(db == null) return false; + + Statement s; + int res = db.prepare_v2("DELETE FROM `tags` WHERE `id` = ?", -1, out s); + + if(res != Sqlite.OK) + { + warning("[Database.Tags.remove] Can't prepare DELETE query (%d): %s", db.errcode(), db.errmsg()); + return false; + } + + res = s.bind_text(1, tag.id); + + res = s.step(); + + if(res != Sqlite.DONE) + { + warning("[Database.Tags.remove] Error (%d): %s", db.errcode(), db.errmsg()); + return false; + } + + if(TAGS.contains(tag)) + { + TAGS.remove(tag); + instance.tags_updated(); + } + + return true; + } + + public class Tag: Object + { + public const string BUILTIN_PREFIX = "builtin:"; + public const string USER_PREFIX = "user:"; + public const string IMPORTED_GOG_PREFIX = "gog:"; + + public enum Builtin + { + FAVORITES, UNINSTALLED, INSTALLED, HIDDEN; + + public string id() + { + switch(this) + { + case Builtin.FAVORITES: return "favorites"; + case Builtin.UNINSTALLED: return "uninstalled"; + case Builtin.INSTALLED: return "installed"; + case Builtin.HIDDEN: return "hidden"; + } + assert_not_reached(); + } + + public string name() + { + switch(this) + { + case Builtin.FAVORITES: return C_("tag", "Favorites"); + case Builtin.UNINSTALLED: return C_("tag", "Not installed"); + case Builtin.INSTALLED: return C_("tag", "Installed"); + case Builtin.HIDDEN: return C_("tag", "Hidden"); + } + assert_not_reached(); + } + + public string icon() + { + switch(this) + { + case Builtin.FAVORITES: return "gh-tag-favorites-symbolic"; + case Builtin.UNINSTALLED: return "gh-tag-symbolic"; + case Builtin.INSTALLED: return "gh-tag-symbolic"; + case Builtin.HIDDEN: return "gh-tag-hidden-symbolic"; + } + assert_not_reached(); + } + } + + public string? id { get; construct set; } + public string? name { get; construct set; } + public string icon { get; construct set; } + public bool selected { get; construct set; default = true; } + public bool enabled { get; construct set; default = true; } + public bool removable { get { return id != null && id.has_prefix(USER_PREFIX); } } + + public Tag(string? id, string? name, string icon="gh-tag-symbolic", bool selected=true) + { + Object(id: id, name: name, icon: icon, selected: selected); + } + public Tag.from_db(Statement s) + { + this(ID.get(s), NAME.get(s), ICON.get(s), SELECTED.get_bool(s)); + } + public Tag.from_builtin(Builtin t) + { + this(BUILTIN_PREFIX + t.id(), t.name(), t.icon(), true); + } + public Tag.from_name(string name) + { + this(USER_PREFIX + Utils.md5(name), name); + } + + public bool remove() + { + return Tags.remove(this); + } + + public static bool is_equal(Tag first, Tag second) + { + return first == second || first.id == second.id; + } + } + } +} diff --git a/src/data/providers/DataProvider.vala b/src/data/providers/DataProvider.vala new file mode 100644 index 00000000..927dfd7a --- /dev/null +++ b/src/data/providers/DataProvider.vala @@ -0,0 +1,32 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; +using GameHub.Utils; + +namespace GameHub.Data.Providers +{ + public abstract class DataProvider: Provider + { + public override string icon { get { return "text-x-generic-symbolic"; } } + + public abstract async T data(Game game); + } + + public static DataProvider[] DataProviders; +} diff --git a/src/data/providers/ImagesProvider.vala b/src/data/providers/ImagesProvider.vala new file mode 100644 index 00000000..5f2f591e --- /dev/null +++ b/src/data/providers/ImagesProvider.vala @@ -0,0 +1,63 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; +using GameHub.Utils; + +namespace GameHub.Data.Providers +{ + public abstract class ImagesProvider: Provider + { + public override string icon { get { return "image-x-generic"; } } + + public abstract async ArrayList images(Game game); + + public class Result: Object + { + public string? name { get; set; default = null; } + public string? url { get; set; default = null; } + public ArrayList? images { get; set; default = null; } + public ImageSize image_size { get; set; default = ImageSize(460, 215); } + } + + public class Image: Object + { + public string url { get; protected construct set; } + public string? description { get; protected construct set; default = null; } + + public Image(string url, string? description=null) + { + Object(url: url, description: description); + } + } + + public struct ImageSize + { + public int width; + public int height; + + public ImageSize(int w, int h) + { + width = w; + height = h; + } + } + } + + public static ImagesProvider[] ImageProviders; +} diff --git a/src/data/providers/Provider.vala b/src/data/providers/Provider.vala new file mode 100644 index 00000000..4ed46c0d --- /dev/null +++ b/src/data/providers/Provider.vala @@ -0,0 +1,35 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; +using GameHub.Utils; + +namespace GameHub.Data.Providers +{ + public abstract class Provider + { + public virtual string id { get { return ""; } } + public virtual string name { get { return ""; } } + public virtual string url { get { return ""; } } + public virtual string icon { get { return "text-x-generic"; } } + + public abstract bool enabled { get; set; } + + public virtual Gtk.Widget? settings_widget { owned get { return null; } } + } +} diff --git a/src/data/providers/data/IGDB.vala b/src/data/providers/data/IGDB.vala new file mode 100644 index 00000000..73cf5843 --- /dev/null +++ b/src/data/providers/data/IGDB.vala @@ -0,0 +1,497 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; +using GameHub.Utils; + +namespace GameHub.Data.Providers.Data +{ + public class IGDB: DataProvider?> + { + private const string SCHEME = "https://"; + private const string DOMAIN = "igdb.com"; + private const string API_SUBDOMAIN = "api-v3."; + private const string API_BASE_URL = SCHEME + API_SUBDOMAIN + DOMAIN; + private const string API_KEY_PAGE = "https://api.igdb.com/admin/applications"; + + public override string id { get { return "igdb"; } } + public override string name { get { return "IGDB"; } } + public override string url { get { return SCHEME + DOMAIN; } } + public override string icon { get { return "provider-data-igdb"; } } + + public override bool enabled + { + get { return Settings.Providers.Data.IGDB.instance.enabled; } + set { Settings.Providers.Data.IGDB.instance.enabled = value; } + } + + public static IGDB instance; + private bool request_quota_reached; + + public IGDB() + { + instance = this; + request_quota_reached = false; + } + + public override async ArrayList? data(Game game) + { + var cached = DB.Tables.IGDBData.get(game); + + bool error = false; + uint status = 0; + string? err_msg = null; + + if(cached != null && cached.length > 0) + { + var res = yield parse(game, cached, out error, out status, out err_msg); + if(error || res == null) + { + DB.Tables.IGDBData.remove(game); + } + if(res != null) return res; + } + + if(request_quota_reached) return null; + + var headers = new HashMap(); + headers.set("user-key", Settings.Providers.Data.IGDB.instance.api_key); + + var endpoint = "/games?search=%s&fields=%s".printf(Uri.escape_string(game.name), string.joinv(",", Fields.REQUEST_FIELDS)); + var json = yield Parser.load_remote_file_async(API_BASE_URL + endpoint, "GET", null, headers, null, out status); + + var res = yield parse(game, json, out error, out status, out err_msg); + + if(!error) + { + DB.Tables.IGDBData.add(game, json); + } + else + { + show_error(status, err_msg); + } + + return res; + } + + private async ArrayList? parse(Game game, string json, out bool error, out uint status, out string? err_msg) + { + error = false; + status = 0; + err_msg = null; + + var json_root = Parser.parse_json(json); + if(json_root == null || json_root.get_node_type() != Json.NodeType.ARRAY) return null; + var json_array = json_root.get_array(); + if(json_array == null || json_array.get_length() < 1) return null; + + var results = new ArrayList(); + + foreach(var node in json_array.get_elements()) + { + var obj = node.get_object(); + + if(is_error(obj, out status, out err_msg)) + { + error = true; + return null; + } + + results.add(new Result(obj)); + } + + return results; + } + + private bool is_error(Json.Object? obj, out uint status, out string? err_msg) + { + status = 0; + err_msg = null; + + if(obj == null) return true; + + err_msg = obj.has_member("cause") ? obj.get_string_member("cause") : null; + + if(err_msg != null) + { + status = obj.has_member("status") ? (uint) obj.get_int_member("status") : 0; + warning(@"[IGDB] Error $(status): $(err_msg)"); + return true; + } + return false; + } + + private void show_error(uint status, string? err_msg) + { + if(request_quota_reached) return; + if(status == Soup.Status.FORBIDDEN && err_msg != null && "request limit" in err_msg) + { + request_quota_reached = true; + if(UI.Views.GamesView.GamesView.instance == null) return; + Idle.add(() => { + var msg = UI.Views.GamesView.GamesView.instance.add_message(_("Monthly IGDB request quota has been reached. Set your own API key to use IGDB data or disable IGDB."), Gtk.MessageType.WARNING); + msg.add_button(_("Settings"), 1); + + msg.close.connect(() => { + #if GTK_3_22 + msg.revealed = false; + #endif + Timeout.add(250, () => { msg.destroy(); return Source.REMOVE; }); + }); + + msg.response.connect(r => { + switch(r) + { + case 1: + new UI.Dialogs.SettingsDialog.SettingsDialog("providers/providers"); + break; + + case Gtk.ResponseType.CLOSE: + msg.close(); + break; + } + }); + return Source.REMOVE; + }); + } + } + + public class Result + { + public int? id = null; + public string? name = null; + public string? url = null; + public int64? release_date = null; + public Website[]? websites = null; + + public Link[]? platforms = null; + + public string? summary = null; + public string? storyline = null; + + public Link[]? genres = null; + public Link[]? keywords = null; + + public double? popularity = null; + + public double? aggregated_rating = null; + public int? aggregated_rating_count = null; + public double? igdb_rating = null; + public int? igdb_rating_count = null; + public double? total_rating = null; + public int? total_rating_count = null; + + public Result(Json.Object obj) + { + if(obj.has_member(Fields.ID)) + id = (int) obj.get_int_member(Fields.ID); + if(obj.has_member(Fields.NAME)) + name = obj.get_string_member(Fields.NAME); + if(obj.has_member(Fields.URL)) + url = obj.get_string_member(Fields.URL); + if(obj.has_member(Fields.RELEASE_DATE)) + release_date = obj.get_int_member(Fields.RELEASE_DATE); + + if(obj.has_member(Fields.SUMMARY)) + summary = obj.get_string_member(Fields.SUMMARY); + if(obj.has_member(Fields.STORYLINE)) + storyline = obj.get_string_member(Fields.STORYLINE); + + if(obj.has_member(Fields.POPULARITY)) + popularity = obj.get_double_member(Fields.POPULARITY); + + if(obj.has_member(Fields.AGGREGATED_RATING)) + aggregated_rating = obj.get_double_member(Fields.AGGREGATED_RATING); + if(obj.has_member(Fields.AGGREGATED_RATING_COUNT)) + aggregated_rating_count = (int) obj.get_int_member(Fields.AGGREGATED_RATING_COUNT); + if(obj.has_member(Fields.IGDB_RATING)) + igdb_rating = obj.get_double_member(Fields.IGDB_RATING); + if(obj.has_member(Fields.IGDB_RATING_COUNT)) + igdb_rating_count = (int) obj.get_int_member(Fields.IGDB_RATING_COUNT); + if(obj.has_member(Fields.TOTAL_RATING)) + total_rating = obj.get_double_member(Fields.TOTAL_RATING); + if(obj.has_member(Fields.TOTAL_RATING_COUNT)) + total_rating_count = (int) obj.get_int_member(Fields.TOTAL_RATING_COUNT); + + if(obj.has_member(Fields.WEBSITES) && obj.get_member(Fields.WEBSITES).get_node_type() == Json.NodeType.ARRAY) + { + var websites_array = obj.get_array_member(Fields.WEBSITES); + if(websites_array.get_length() > 0) + { + Website[] websites = {}; + foreach(var node in websites_array.get_elements()) + { + websites += new Website(node.get_object()); + } + this.websites = websites; + } + } + + if(obj.has_member(Fields.PLATFORMS) && obj.get_member(Fields.PLATFORMS).get_node_type() == Json.NodeType.ARRAY) + { + var platforms_array = obj.get_array_member(Fields.PLATFORMS); + if(platforms_array.get_length() > 0) + { + Link[] platforms = {}; + foreach(var node in platforms_array.get_elements()) + { + platforms += new Link(node.get_object()); + } + this.platforms = platforms; + } + } + + if(obj.has_member(Fields.GENRES) && obj.get_member(Fields.GENRES).get_node_type() == Json.NodeType.ARRAY) + { + var genres_array = obj.get_array_member(Fields.GENRES); + if(genres_array.get_length() > 0) + { + Link[] genres = {}; + foreach(var node in genres_array.get_elements()) + { + genres += new Link(node.get_object()); + } + this.genres = genres; + } + } + + if(obj.has_member(Fields.KEYWORDS) && obj.get_member(Fields.KEYWORDS).get_node_type() == Json.NodeType.ARRAY) + { + var keywords_array = obj.get_array_member(Fields.KEYWORDS); + if(keywords_array.get_length() > 0) + { + Link[] keywords = {}; + foreach(var node in keywords_array.get_elements()) + { + keywords += new Link(node.get_object()); + } + this.keywords = keywords; + } + } + } + + public class Link + { + public string name; + public string url; + + public Link(Json.Object obj) + { + name = obj.get_string_member("name"); + url = obj.get_string_member("url"); + } + } + + public class Website + { + public string url; + public Category category; + + public Website(Json.Object obj) + { + url = obj.get_string_member("url"); + category = Category.from_id((int) obj.get_int_member("category")); + } + + public enum Category + { + UNKNOWN = 0, OFFICIAL = 1, WIKIA = 2, WIKIPEDIA = 3, FACEBOOK = 4, TWITTER = 5, TWITCH = 6, + INSTAGRAM = 8, YOUTUBE = 9, IPHONE = 10, IPAD = 11, ANDROID = 12, STEAM = 13, REDDIT = 14, + DISCORD = 15, GOOGLE_PLUS = 16, TUMBLR = 17, LINKEDIN = 18, PINTEREST = 19, SOUNDCLOUD = 20; + + public static Category from_id(int id) + { + return (Category) id; + } + + public int id() + { + return (int) this; + } + + public string icon() + { + switch(this) + { + case WIKIPEDIA: return "related-link-wikipedia-symbolic"; + case FACEBOOK: return "related-link-facebook-symbolic"; + case TWITTER: return "related-link-twitter-symbolic"; + case TWITCH: return "related-link-twitch-symbolic"; + case INSTAGRAM: return "related-link-instagram-symbolic"; + case YOUTUBE: return "related-link-youtube-symbolic"; + case IPHONE: return "related-link-app-iphone-symbolic"; + case IPAD: return "related-link-app-ipad-symbolic"; + case ANDROID: return "related-link-app-android-symbolic"; + case STEAM: return "source-steam-symbolic"; + case REDDIT: return "related-link-reddit-symbolic"; + case DISCORD: return "related-link-discord-symbolic"; + case GOOGLE_PLUS: return "related-link-google-plus-symbolic"; + case TUMBLR: return "related-link-tumblr-symbolic"; + case LINKEDIN: return "related-link-linkedin-symbolic"; + case PINTEREST: return "related-link-pinterest-symbolic"; + case SOUNDCLOUD: return "related-link-soundcloud-symbolic"; + } + return "web-browser-symbolic"; + } + + public string? description() + { + switch(this) + { + case OFFICIAL: return C_("igdb_related_link", "Official website"); + case WIKIA: return "Wikia"; + case WIKIPEDIA: return "Wikipedia"; + case FACEBOOK: return "Facebook"; + case TWITTER: return "Twitter"; + case TWITCH: return "Twitch"; + case INSTAGRAM: return "Instagram"; + case YOUTUBE: return "YouTube"; + case IPHONE: return "iPhone"; + case IPAD: return "iPad"; + case ANDROID: return "Android"; + case STEAM: return "Steam"; + case REDDIT: return "Reddit"; + case DISCORD: return "Discord"; + case GOOGLE_PLUS: return "Google+"; + case TUMBLR: return "Tumblr"; + case LINKEDIN: return "LinkedIn"; + case PINTEREST: return "Pinterest"; + case SOUNDCLOUD: return "SoundCloud"; + } + return null; + } + } + } + } + + private class Fields + { + public const string[] REQUEST_FIELDS = { + ID, NAME, URL, RELEASE_DATE, WEBSITES + _EXPAND, + PLATFORMS + _EXPAND, + SUMMARY, STORYLINE, + GENRES + _EXPAND, KEYWORDS + _EXPAND, + POPULARITY, + AGGREGATED_RATING, AGGREGATED_RATING_COUNT, IGDB_RATING, IGDB_RATING_COUNT, TOTAL_RATING, TOTAL_RATING_COUNT + }; + + public const string _EXPAND = ".*"; + public const string _COUNT = "_count"; + + public const string ID = "id"; + public const string NAME = "name"; + public const string URL = "url"; + public const string RELEASE_DATE = "first_release_date"; + public const string WEBSITES = "websites"; + + public const string PLATFORMS = "platforms"; + + public const string SUMMARY = "summary"; + public const string STORYLINE = "storyline"; + + public const string GENRES = "genres"; + public const string KEYWORDS = "keywords"; + + public const string POPULARITY = "popularity"; + + public const string AGGREGATED_RATING = "aggregated_rating"; + public const string AGGREGATED_RATING_COUNT = AGGREGATED_RATING + _COUNT; + public const string IGDB_RATING = "rating"; + public const string IGDB_RATING_COUNT = IGDB_RATING + _COUNT; + public const string TOTAL_RATING = "total_rating"; + public const string TOTAL_RATING_COUNT = TOTAL_RATING + _COUNT; + } + + public override Gtk.Widget? settings_widget + { + owned get + { + var settings = Settings.Providers.Data.IGDB.instance; + + var grid = new Gtk.Grid(); + grid.column_spacing = 12; + grid.row_spacing = 4; + + var entry = new Gtk.Entry(); + entry.placeholder_text = _("Default"); + entry.max_length = 32; + if(settings.api_key != settings.schema.get_default_value("api-key").get_string()) + { + entry.text = settings.api_key; + } + entry.secondary_icon_name = "edit-delete-symbolic"; + entry.secondary_icon_tooltip_text = _("Restore default API key"); + entry.set_size_request(250, -1); + + entry.notify["text"].connect(() => { settings.api_key = entry.text; }); + entry.icon_press.connect((pos, e) => { + if(pos == Gtk.EntryIconPosition.SECONDARY) + { + entry.text = ""; + } + }); + + var label = new Gtk.Label(_("API key")); + label.halign = Gtk.Align.START; + label.valign = Gtk.Align.CENTER; + label.hexpand = true; + + var entry_wrapper = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0); + entry_wrapper.get_style_context().add_class(Gtk.STYLE_CLASS_LINKED); + + var link = new Gtk.Button.with_label(_("Generate key")); + link.tooltip_text = API_KEY_PAGE; + + link.clicked.connect(() => { + Utils.open_uri(API_KEY_PAGE); + }); + + entry_wrapper.add(entry); + entry_wrapper.add(link); + + var desc_src_wrapper = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 12); + + var desc_src_label = new Gtk.Label(C_("igdb_preferred_description", "When game has description, show description")); + desc_src_label.halign = Gtk.Align.START; + desc_src_label.valign = Gtk.Align.CENTER; + desc_src_label.hexpand = true; + + var desc_src = new GameHub.UI.Widgets.ModeButton(); + desc_src.homogeneous = false; + desc_src.append_text(C_("igdb_preferred_description", "of game")); + desc_src.append_text(C_("igdb_preferred_description", "from IGDB")); + desc_src.append_text(C_("igdb_preferred_description", "both")); + + desc_src.selected = settings.preferred_description; + + desc_src.mode_changed.connect(() => { + settings.preferred_description = (Settings.Providers.Data.IGDB.PreferredDescription) desc_src.selected; + }); + + desc_src_wrapper.add(desc_src_label); + desc_src_wrapper.add(desc_src); + + grid.attach(label, 0, 0); + grid.attach(entry_wrapper, 1, 0); + grid.attach(desc_src_wrapper, 0, 1, 2, 1); + + return grid; + } + } + } +} diff --git a/src/data/providers/images/JinxSGVI.vala b/src/data/providers/images/JinxSGVI.vala new file mode 100644 index 00000000..18c9d8f1 --- /dev/null +++ b/src/data/providers/images/JinxSGVI.vala @@ -0,0 +1,92 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; +using GameHub.Utils; + +namespace GameHub.Data.Providers.Images +{ + public class JinxSGVI: ImagesProvider + { + private const string BASE_URL = "https://steam.cryotank.net"; + + public override string id { get { return "jinx_sgvi"; } } + public override string name { get { return "Jinx's Steam Grid View Images"; } } + public override string url { get { return BASE_URL; } } + + public override bool enabled + { + get { return Settings.Providers.Images.JinxSGVI.instance.enabled; } + set { Settings.Providers.Images.JinxSGVI.instance.enabled = value; } + } + + public override async ArrayList images(Game game) + { + var result = new ImagesProvider.Result(); + result.name = "%s: %s".printf(name, game.name); + result.url = BASE_URL + "/?s=" + Uri.escape_string(game.name); + result.images = new ArrayList(); + + yield parse_page(result.url, result); + + var results = new ArrayList(); + results.add(result); + return results; + } + + private async void parse_page(string url, ImagesProvider.Result result) + { + var html = yield Parser.parse_remote_html_file_async(url, "GET"); + if(html == null) return; + + var xpath = new Xml.XPath.Context(html); + + var galleries = xpath.eval("//div[contains(@class,'ngg-galleryoverview')]")->nodesetval; + if(galleries != null && galleries->length() > 0) + { + for(int g = 0; g < galleries->length(); g++) + { + var gallery = galleries->item(g); + xpath.node = gallery; + + var images = xpath.eval("div/div[@class='ngg-gallery-thumbnail']/a")->nodesetval; + if(images != null && images->length() > 0) + { + for(int i = 0; i < images->length(); i++) + { + var img = images->item(i); + if(img == null) continue; + result.images.add(new ImagesProvider.Image(img->get_prop("data-src"), img->get_prop("data-title"))); + } + } + + var next_page = xpath.eval("div[@class='ngg-navigation']/a[@class='next']")->nodesetval; + if(next_page != null && next_page->length() > 0) + { + var next_page_url = next_page->item(0)->get_prop("href").strip(); + if(next_page_url != null) + { + yield parse_page(next_page_url, result); + } + } + } + } + delete html; + } + } +} diff --git a/src/data/providers/images/Steam.vala b/src/data/providers/images/Steam.vala new file mode 100644 index 00000000..45a05873 --- /dev/null +++ b/src/data/providers/images/Steam.vala @@ -0,0 +1,229 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; +using GameHub.Utils; + +namespace GameHub.Data.Providers.Images +{ + public class Steam: ImagesProvider + { + private const string DOMAIN = "https://store.steampowered.com/"; + private const string CDN_BASE_URL = "http://cdn.akamai.steamstatic.com/steam/apps/"; + private const string API_KEY_PAGE = "https://steamcommunity.com/dev/apikey"; + private const string API_BASE_URL = "https://api.steampowered.com/"; + + private const string APPLIST_CACHE_FILE = "applist.json"; + private ImagesProvider.ImageSize?[] SIZES = { ImageSize(460, 215), ImageSize(600, 900) }; + + public override string id { get { return "steam"; } } + public override string name { get { return "Steam"; } } + public override string url { get { return DOMAIN; } } + public override string icon { get { return "source-steam-symbolic"; } } + + public override bool enabled + { + get { return Settings.Providers.Images.Steam.instance.enabled; } + set { Settings.Providers.Images.Steam.instance.enabled = value; } + } + + public override async ArrayList images(Game game) + { + var results = new ArrayList(); + string? appid = null; + + if(game is GameHub.Data.Sources.Steam.SteamGame) + { + appid = game.id; + } + else + { + appid = yield GameHub.Data.Sources.Steam.Steam.get_appid_from_name(game.name); + + // also contains unowned games: + if(appid == null) appid = yield get_appid_from_name(game.name); + } + + if(appid != null) + { + debug("[Provider.Images.Steam] Found appid %s for game %s", appid, game.name); + foreach(var size in SIZES) + { + var result = new ImagesProvider.Result(); + result.images = new ArrayList(); + result.image_size = size ?? ImageSize(460, 215); + result.name = "%s: %s (%d × %d)".printf(name, game.name, result.image_size.width, result.image_size.height); + result.url = "%sapp/%s".printf(DOMAIN, appid); + + string? remote_result = null; + string? local_result = null; + switch (size.width) { + case 460: + // Always enforced by steam, exists for everything + local_result = yield search_local(appid); + remote_result = yield search_remote(appid, "header.jpg", false); + break; + // case 920: + // Higher resolution of the one above at the same location + // break; + case 600: + // Enforced since 2019, possibly not available + local_result = yield search_local(appid, "p"); + remote_result = yield search_remote(appid, "library_600x900_2x.jpg"); + break; + } + + if(local_result != null) + { + result.images.add(new Image(local_result, "Local custom steam grid image")); + } + + if(remote_result != null) + { + result.images.add(new Image(remote_result, "Remote download")); + } + + if(result.images.size > 0) + { + results.add(result); + } + } + } + + return results; + } + + private async string? search_local(string appid, string format="") + { + string[] extensions = { ".png", ".jpg" }; + File? griddir = Sources.Steam.Steam.get_userdata_dir().get_child("config").get_child("grid"); + + foreach(var extension in extensions) + { + if(griddir.get_child(appid + format + extension).query_exists()) + { + return "file://" + griddir.get_child(appid + format + extension).get_path(); + } + } + + return null; + } + + private async string? search_remote(string appid, string format, bool needs_check=true) + { + var exists = !needs_check; + var endpoint = "%s/%s".printf(appid, format); + + if(needs_check) + { + exists = yield image_exists("%s%s".printf(CDN_BASE_URL, endpoint)); + } + + if(exists) + { + return "%s%s".printf(CDN_BASE_URL, endpoint); + } + + return null; + } + + private async bool image_exists(string url) + { + uint status; + yield Parser.load_remote_file_async(url, "GET", null, null, null, out status); + if(status == 200) + { + return true; + } + return false; + } + + private async string? get_appid_from_name(string game_name) + { + var applist_cache_path = @"$(FSUtils.Paths.Cache.Providers)/steam/"; + var cache_file = FSUtils.file(applist_cache_path, APPLIST_CACHE_FILE); + DateTime? modification_date = null; + + if(cache_file.query_exists()) + { + try + { + // Get modification time so we refresh only once a day + #if GLIB_2_62 + modification_date = cache_file.query_info("*", FileQueryInfoFlags.NONE).get_modification_date_time(); + #else + modification_date = new DateTime.from_timeval_utc(cache_file.query_info("*", FileQueryInfoFlags.NONE).get_modification_time()); + #endif + } + catch(Error e) + { + debug("[Provider.Images.Steam] %s", e.message); + return null; + } + } + + if(!cache_file.query_exists() || modification_date == null || modification_date.compare(new DateTime.now_utc().add_days(-1)) < 0) + { + var url = @"$(API_BASE_URL)ISteamApps/GetAppList/v0002/"; + + FSUtils.mkdir(applist_cache_path); + cache_file = FSUtils.file(applist_cache_path, APPLIST_CACHE_FILE); + + try + { + var json_string = yield Parser.load_remote_file_async(url); + var tmp = Parser.parse_json(json_string); + if(tmp != null && tmp.get_node_type() == Json.NodeType.OBJECT && tmp.get_object().get_object_member("applist").get_array_member("apps").get_length() > 0) + { + var dos = new DataOutputStream(cache_file.replace(null, false, FileCreateFlags.NONE)); + dos.put_string(json_string); + debug("[Provider.Images.Steam] Refreshed steam applist"); + } + else + { + debug("[Provider.Images.Steam] Downloaded applist is empty"); + } + } + catch(Error e) + { + warning("[Provider.Images.Steam] %s", e.message); + return null; + } + } + + var json = Parser.parse_json_file(applist_cache_path, APPLIST_CACHE_FILE); + if(json == null || json.get_node_type() != Json.NodeType.OBJECT) + { + debug("[Provider.Images.Steam] Error reading steam applist"); + return null; + } + + var apps = json.get_object().get_object_member("applist").get_array_member("apps").get_elements(); + foreach(var app in apps) + { + if(app.get_object().get_string_member("name").down() == game_name.down()) + { + var appid = app.get_object().get_int_member("appid").to_string(); + return appid; + } + } + + return null; + } + } +} diff --git a/src/data/providers/images/SteamGridDB.vala b/src/data/providers/images/SteamGridDB.vala new file mode 100644 index 00000000..fffd7a0f --- /dev/null +++ b/src/data/providers/images/SteamGridDB.vala @@ -0,0 +1,250 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; +using GameHub.Utils; + +namespace GameHub.Data.Providers.Images +{ + public class SteamGridDB: ImagesProvider + { + private const string DOMAIN = "https://steamgriddb.com"; + private const string BASE_URL = DOMAIN + "/api/v2"; + private const string API_KEY_PAGE = DOMAIN + "/profile/preferences"; + + private ImagesProvider.ImageSize?[] SIZES = { null, ImageSize(460, 215), ImageSize(920, 430), ImageSize(600, 900), ImageSize(342, 482) }; + + public override string id { get { return "steamgriddb"; } } + public override string name { get { return "SteamGridDB"; } } + public override string url { get { return DOMAIN; } } + public override string icon { get { return "provider-images-steamgriddb"; } } + + public override bool enabled + { + get { return Settings.Providers.Images.SteamGridDB.instance.enabled; } + set { Settings.Providers.Images.SteamGridDB.instance.enabled = value; } + } + + public override async ArrayList images(Game game) + { + var results = new ArrayList(); + + ArrayList? games; + if(game is GameHub.Data.Sources.Steam.SteamGame) + { + games = yield games_by_steam_appid(game.id); + } + else + { + games = yield games_by_name(game.name); + } + + if(games != null && games.size > 0) + { + foreach(var g in games) + { + foreach(var size in SIZES) + { + var result = new ImagesProvider.Result(); + result.image_size = size ?? ImageSize(460, 215); + result.name = "%s: %s (%d × %d)".printf(name, g.name, result.image_size.width, result.image_size.height); + result.url = "%s/game/%s".printf(DOMAIN, g.id); + + var dimensions = size != null ? "?dimensions=%dx%d".printf(size.width, size.height) : ""; + + var endpoint = "/grids/game/%s%s".printf(g.id, dimensions); + //if(game is GameHub.Data.Sources.Steam.SteamGame) endpoint = "/grids/steam/%s%s".printf(game.id, dimensions); + + var root = yield Parser.parse_remote_json_file_async(BASE_URL + endpoint, "GET", Settings.Providers.Images.SteamGridDB.instance.api_key); + if(root == null || root.get_node_type() != Json.NodeType.OBJECT) continue; + var obj = root.get_object(); + var data = obj.has_member("data") ? obj.get_array_member("data") : null; + if(data == null || data.get_length() < 1) continue; + + result.images = new ArrayList(); + foreach(var img_node in data.get_elements()) + { + var img = img_node != null && img_node.get_node_type() == Json.NodeType.OBJECT ? img_node.get_object() : null; + if(img == null || !img.has_member("url")) continue; + result.images.add(new Image(img)); + } + + if(result.images.size > 0) + { + results.add(result); + } + } + } + } + + return results; + } + + private async ArrayList? games_by_name(string name) + { + var root = yield Parser.parse_remote_json_file_async(BASE_URL + "/search/autocomplete/" + Uri.escape_string(name), "GET", Settings.Providers.Images.SteamGridDB.instance.api_key); + if(root == null || root.get_node_type() != Json.NodeType.OBJECT) return null; + var obj = root.get_object(); + var data = obj.has_member("data") ? obj.get_array_member("data") : null; + if(data == null || data.get_length() < 1) return null; + + var games = new ArrayList(); + foreach(var item_node in data.get_elements()) + { + var item = item_node != null && item_node.get_node_type() == Json.NodeType.OBJECT ? item_node.get_object() : null; + if(item == null || !item.has_member("id") || !item.has_member("name")) continue; + games.add(new SGDBGame(item)); + } + return games; + } + + private async ArrayList? games_by_steam_appid(string appid) + { + var root = yield Parser.parse_remote_json_file_async(BASE_URL + "/games/steam/" + appid, "GET", Settings.Providers.Images.SteamGridDB.instance.api_key); + if(root == null || root.get_node_type() != Json.NodeType.OBJECT) return null; + var obj = root.get_object(); + var data = obj.has_member("data") ? obj.get_object_member("data") : null; + if(data == null || !data.has_member("id") || !data.has_member("name")) return null; + + var games = new ArrayList(); + games.add(new SGDBGame(data)); + return games; + } + + private class SGDBGame + { + public string id; + public string name; + public SGDBGame(Json.Object game) + { + id = game.get_int_member("id").to_string(); + name = game.get_string_member("name"); + } + } + + public override Gtk.Widget? settings_widget + { + owned get + { + var settings = Settings.Providers.Images.SteamGridDB.instance; + + var grid = new Gtk.Grid(); + grid.column_spacing = 12; + grid.row_spacing = 4; + + var entry = new Gtk.Entry(); + entry.placeholder_text = _("Default"); + entry.max_length = 32; + if(settings.api_key != settings.schema.get_default_value("api-key").get_string()) + { + entry.text = settings.api_key; + } + entry.secondary_icon_name = "edit-delete-symbolic"; + entry.secondary_icon_tooltip_text = _("Restore default API key"); + entry.set_size_request(250, -1); + + entry.notify["text"].connect(() => { settings.api_key = entry.text; }); + entry.icon_press.connect((pos, e) => { + if(pos == Gtk.EntryIconPosition.SECONDARY) + { + entry.text = ""; + } + }); + + var label = new Gtk.Label(_("API key")); + label.halign = Gtk.Align.START; + label.valign = Gtk.Align.CENTER; + label.hexpand = true; + + var entry_wrapper = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0); + entry_wrapper.get_style_context().add_class(Gtk.STYLE_CLASS_LINKED); + + var link = new Gtk.Button.with_label(_("Generate key")); + link.tooltip_text = API_KEY_PAGE; + + link.clicked.connect(() => { + Utils.open_uri(API_KEY_PAGE); + }); + + entry_wrapper.add(entry); + entry_wrapper.add(link); + + grid.attach(label, 0, 0); + grid.attach(entry_wrapper, 1, 0); + + return grid; + } + } + + public class Image: ImagesProvider.Image + { + public string raw_style { get; protected construct set; } + public Style? style { get; protected construct set; default = null; } + public int score { get; protected construct set; default = 0; } + public string? author { get; protected construct set; default = null; } + + public Image(Json.Object obj) + { + Object(url: obj.get_string_member("url"), raw_style: obj.get_string_member("style")); + style = Style.from_string(raw_style); + author = obj.has_member("author") ? obj.get_object_member("author").get_string_member("name") : null; + score = obj.has_member("score") ? (int) obj.get_int_member("score") : 0; + + description = """%s: %s""".printf(C_("imagesource_steamgriddb_image_property", "Style"), style == null ? raw_style : style.name()) + "\n" + + """%s: %d""".printf(C_("imagesource_steamgriddb_image_property", "Score"), score); + + if(author != null) + { + description += "\n" + """%s: %s""".printf(C_("imagesource_steamgriddb_image_property", "Author"), author); + } + } + + public enum Style + { + ALTERNATE, BLURRED, MATERIAL, NO_LOGO, WHITE_LOGO; + + public string name() + { + switch(this) + { + case Style.ALTERNATE: return C_("imagesource_steamgriddb_image_style", "Alternate"); + case Style.BLURRED: return C_("imagesource_steamgriddb_image_style", "Blurred"); + // TRANSLATORS: Flat / Material Design image style. Probably should not be translated + case Style.MATERIAL: return C_("imagesource_steamgriddb_image_style", "Material"); + case Style.NO_LOGO: return C_("imagesource_steamgriddb_image_style", "No logo"); + case Style.WHITE_LOGO: return C_("imagesource_steamgriddb_image_style", "White logo"); + } + assert_not_reached(); + } + + public static Style? from_string(string style) + { + switch(style) + { + case "alternate": return Style.ALTERNATE; + case "blurred": return Style.BLURRED; + case "material": return Style.MATERIAL; + case "no_logo": return Style.NO_LOGO; + case "white_logo": return Style.WHITE_LOGO; + } + return null; + } + } + } + } +} diff --git a/src/data/sources/gog/GOG.vala b/src/data/sources/gog/GOG.vala index 83ea0b8e..b3cd06e2 100644 --- a/src/data/sources/gog/GOG.vala +++ b/src/data/sources/gog/GOG.vala @@ -1,5 +1,23 @@ -using Gtk; +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + using Gee; +using GameHub.Data.DB; using GameHub.Utils; namespace GameHub.Data.Sources.GOG @@ -9,16 +27,45 @@ namespace GameHub.Data.Sources.GOG private const string CLIENT_ID = "46899977096215655"; private const string CLIENT_SECRET = "9d85c43b1482497dbbce61f6e4aa173a433796eeae2ca8c5f6129f2dc4de46d9"; private const string REDIRECT = "https%3A%2F%2Fembed.gog.com%2Fon_login_success%3Forigin%3Dclient"; - + + private const string[] GAMES_BLACKLIST = {"1424856371" /* Hotline Miami 2: Wrong Number - Digital Comics */}; + + public static GOG instance; + + public override string id { get { return "gog"; } } public override string name { get { return "GOG"; } } - public override string icon { get { return "gog"; } } - + public override string icon { get { return "source-gog-symbolic"; } } + + public override bool enabled + { + get { return settings.enabled; } + set { settings.enabled = value; } + } + public string? user_id { get; protected set; } public string? user_name { get; protected set; } - + private string? user_auth_code = null; - private string? user_token = null; + public string? user_token = null; private string? user_refresh_token = null; + private bool token_needs_refresh = false; + + private Settings.Auth.GOG settings; + + public GOG() + { + instance = this; + + settings = Settings.Auth.GOG.instance; + var access_token = settings.access_token; + var refresh_token = settings.refresh_token; + if(access_token.length > 0 && refresh_token.length > 0) + { + user_token = access_token; + user_refresh_token = refresh_token; + token_needs_refresh = true; + } + } public override bool is_installed(bool refresh) { @@ -29,106 +76,328 @@ namespace GameHub.Data.Sources.GOG { return true; } - + public override async bool authenticate() { + settings.authenticated = true; + + if(token_needs_refresh && user_refresh_token != null) + { + return (yield refresh_token()); + } + return (yield get_auth_code()) && (yield get_token()); } - + public override bool is_authenticated() { - return user_token != null; + return !token_needs_refresh && user_token != null; + } + + public override bool can_authenticate_automatically() + { + return user_refresh_token != null && settings.authenticated; } - + private async bool get_auth_code() { if(user_auth_code != null) { return true; } - + var wnd = new GameHub.UI.Windows.WebAuthWindow(this.name, @"https://auth.gog.com/auth?client_id=$(CLIENT_ID)&redirect_uri=$(REDIRECT)&response_type=code&layout=client2", "https://embed.gog.com/on_login_success?origin=client&code="); - + wnd.finished.connect(code => { user_auth_code = code; + if(GameHub.Application.log_auth) + { + debug("[Auth] GOG auth code: %s", code); + } Idle.add(get_auth_code.callback); }); - + wnd.canceled.connect(() => Idle.add(get_auth_code.callback)); - - wnd.set_size_request(550, 680); + + wnd.set_size_request(550, 680); wnd.show_all(); wnd.present(); - + yield; - + return user_auth_code != null; } - + private async bool get_token() { if(user_token != null) { return true; } - - print("Fetching access token...\n"); - + var url = @"https://auth.gog.com/token?client_id=$(CLIENT_ID)&client_secret=$(CLIENT_SECRET)&grant_type=authorization_code&redirect_uri=$(REDIRECT)&code=$(user_auth_code)"; - var root = yield Parser.parse_remote_json_file_async(url); + var root = (yield Parser.parse_remote_json_file_async(url)).get_object(); user_token = root.get_string_member("access_token"); user_refresh_token = root.get_string_member("refresh_token"); user_id = root.get_string_member("user_id"); - + + settings.access_token = user_token ?? ""; + settings.refresh_token = user_refresh_token ?? ""; + + if(GameHub.Application.log_auth) + { + debug("[Auth] GOG access token: %s", user_token); + debug("[Auth] GOG refresh token: %s", user_refresh_token); + debug("[Auth] GOG user id: %s", user_id); + } + return user_token != null; } - - private async bool refresh_token() + + public async bool refresh_token() { - if(user_token == null) + if(user_refresh_token == null) { - return true; + return false; + } + + if(GameHub.Application.log_auth) + { + debug("[Auth] Refreshing GOG access token with refresh token: %s", user_refresh_token); } - + var url = @"https://auth.gog.com/token?client_id=$(CLIENT_ID)&client_secret=$(CLIENT_SECRET)&grant_type=refresh_token&refresh_token=$(user_refresh_token)"; - var root = yield Parser.parse_remote_json_file_async(url); + var root_node = yield Parser.parse_remote_json_file_async(url); + var root = root_node != null && root_node.get_node_type() == Json.NodeType.OBJECT ? root_node.get_object() : null; + + if(root == null) + { + token_needs_refresh = false; + return false; + } + user_token = root.get_string_member("access_token"); user_refresh_token = root.get_string_member("refresh_token"); user_id = root.get_string_member("user_id"); - + + settings.access_token = user_token ?? ""; + settings.refresh_token = user_refresh_token ?? ""; + + if(GameHub.Application.log_auth) + { + debug("[Auth] GOG access token: %s", user_token); + debug("[Auth] GOG refresh token: %s", user_refresh_token); + debug("[Auth] GOG user id: %s", user_id); + } + + token_needs_refresh = false; + return user_token != null; } - private ArrayList games = new ArrayList(); - public override async ArrayList load_games(FutureResult? game_loaded = null) + private HashMap load_player_stats() { - if(user_id == null || user_token == null || games.size > 0) + var player_stats = new HashMap(); + + if(user_name == null) + { + var userdata_node = Parser.parse_remote_json_file(@"https://embed.gog.com/userData.json", "GET", user_token); + var userdata = userdata_node != null && userdata_node.get_node_type() == Json.NodeType.OBJECT ? userdata_node.get_object() : null; + user_name = userdata != null && userdata.has_member("username") ? userdata.get_string_member("username") : null; + } + + if(user_name == null) return player_stats; + + var page = 1; + var pages = 1; + + while(page <= pages) { - return games; + var url = @"https://embed.gog.com/u/$(user_name)/games/stats?sort=total_playtime&order=desc&page=$(page)"; + var root_node = Parser.parse_remote_json_file(url, "GET", user_token); + var root = root_node != null && root_node.get_node_type() == Json.NodeType.OBJECT ? root_node.get_object() : null; + + if(root == null) break; + + page = (int) root.get_int_member("page"); + pages = (int) root.get_int_member("pages"); + + debug("[GOG] Loading player stats: page %d of %d", page, pages); + + var items = root.get_object_member("_embedded").get_array_member("items"); + + foreach(var i in items.get_elements()) + { + var game = Parser.json_object(i, {"game"}); + var stats = Parser.json_object(i, {"stats", user_id}); + if(game == null || !game.has_member("id")) continue; + var id = game.get_string_member("id"); + var image = game.has_member("image") ? game.get_string_member("image") : null; + var playtime = stats != null && stats.has_member("playtime") ? stats.get_int_member("playtime") : 0; + int64 last_launch = 0; + + #if GLIB_2_56 + if(stats != null && stats.has_member("lastSession")) + { + last_launch = new DateTime.from_iso8601(stats.get_string_member("lastSession"), new TimeZone.utc()).to_unix(); + } + #endif + + player_stats.set(id, new PlayerStatItem(id, playtime, last_launch, image)); + } + + page++; } - - var url = @"https://embed.gog.com/account/getFilteredProducts?mediaType=1"; - var root = yield Parser.parse_remote_json_file_async(url, "GET", user_token); - - var products = root.get_array_member("products"); - - games.clear(); - - foreach(var g in products.get_elements()) + + return player_stats; + } + + private ArrayList _games = new ArrayList(Game.is_equal); + + public override ArrayList games { get { return _games; } } + + public override async ArrayList load_games(Utils.FutureResult2? game_loaded=null, Utils.Future? cache_loaded=null) + { + if(((user_id == null || user_token == null) && token_needs_refresh) || _games.size > 0) { - var game = new GOGGame(this, g.get_object()); - if(yield game.is_for_linux()) + return _games; + } + + Utils.thread("GOGLoading", () => { + _games.clear(); + + var stats = load_player_stats(); + + var cached = Tables.Games.get_all(this); + games_count = 0; + if(cached.size > 0) + { + foreach(var g in cached) + { + if(!(g.id in GAMES_BLACKLIST)) + { + if(stats.has_key(g.id)) + { + var s = stats.get(g.id); + g.last_launch = int64.max(g.last_launch, s.last_launch); + g.playtime_source = s.playtime; + } + if(!Settings.UI.Behavior.instance.merge_games || !Tables.Merges.is_game_merged(g)) + { + _games.add(g); + if(game_loaded != null) + { + game_loaded(g, true); + } + } + } + games_count++; + } + } + + if(cache_loaded != null) + { + cache_loaded(); + } + + var page = 1; + var pages = 1; + + while(page <= pages) { - games.add(game); - games_count = games.size; - if(game_loaded != null) game_loaded(game); + var url = @"https://embed.gog.com/account/getFilteredProducts?mediaType=1&page=$(page)"; + var root_node = Parser.parse_remote_json_file(url, "GET", user_token); + var root = root_node != null && root_node.get_node_type() == Json.NodeType.OBJECT ? root_node.get_object() : null; + + if(root == null) break; + + page = (int) root.get_int_member("page"); + pages = (int) root.get_int_member("totalPages"); + + debug("[GOG] Loading games: page %d of %d", page, pages); + + if(page == 1) + { + var tags = root.has_member("tags") ? root.get_array_member("tags") : null; + if(tags != null) + { + foreach(var t in tags.get_elements()) + { + var id = t.get_object().get_string_member("id"); + var name = t.get_object().get_string_member("name"); + Tables.Tags.add(new Tables.Tags.Tag("gog:" + id, name, icon)); + if(GameHub.Application.log_verbose) + { + debug("[GOG] Imported tag: %s (%s)", name, id); + } + } + } + } + + var products = root.get_array_member("products"); + + foreach(var g in products.get_elements()) + { + var game = new GOGGame(this, g); + bool is_new_game = !(game.id in GAMES_BLACKLIST) && !_games.contains(game); + if(is_new_game) + { + if(stats.has_key(game.id)) + { + var s = stats.get(game.id); + game.last_launch = int64.max(game.last_launch, s.last_launch); + game.playtime_source = s.playtime; + } + if(!Settings.UI.Behavior.instance.merge_games || !Tables.Merges.is_game_merged(game)) + { + _games.add(game); + if(game_loaded != null) + { + game_loaded(game, false); + } + } + } + + var g_index = _games.index_of(game); + if(g_index >= 0 && g_index < _games.size) + { + var go = g.get_object(); + ((GOGGame) _games.get(g_index)).has_updates = go.has_member("updates") && go.get_int_member("updates") > 0; + } + + if(is_new_game) + { + games_count++; + game.save(); + } + } + + page++; } + + Idle.add(load_games.callback); + }); + + yield; + + return _games; + } + + private class PlayerStatItem + { + public string id; + public int64 playtime; + public int64 last_launch; + public string image; + + public PlayerStatItem(string id, int64 playtime, int64 last_launch, string image) + { + this.id = id; + this.playtime = playtime; + this.last_launch = last_launch; + this.image = image; } - - games_count = games.size; - - return games; } } } diff --git a/src/data/sources/gog/GOGGame.vala b/src/data/sources/gog/GOGGame.vala index 1bba7707..f975ad3d 100644 --- a/src/data/sources/gog/GOGGame.vala +++ b/src/data/sources/gog/GOGGame.vala @@ -1,28 +1,1019 @@ -using Gtk; +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; +using GameHub.Data.DB; using GameHub.Utils; namespace GameHub.Data.Sources.GOG { - public class GOGGame: Game + public class GOGGame: Game, TweakableGame { - private bool? _is_for_linux = null; - - public GOGGame(GOG src, Json.Object json) - { - this.source = src; - - this.id = json.get_int_member("id").to_string(); - this.name = json.get_string_member("title"); - - this.image = "https:" + json.get_string_member("image") + "_392.jpg"; - this.icon = this.image; - - this._is_for_linux = json.get_object_member("worksOn").get_boolean_member("Linux"); - } - - public async bool is_for_linux() - { - return (!) _is_for_linux; + public string[]? tweaks { get; set; default = null; } + + public ArrayList? installers { get; protected set; default = new ArrayList(); } + public ArrayList? bonus_content { get; protected set; default = new ArrayList(); } + public ArrayList? dlc { get; protected set; default = new ArrayList(); } + + public File? bonus_content_dir { get; protected set; default = null; } + + public bool has_updates { get; set; default = false; } + + public override File? default_install_dir + { + owned get + { + return FSUtils.file(FSUtils.Paths.GOG.Games, escaped_name); + } + } + + private bool game_info_updating = false; + private bool game_info_updated = false; + + public GOGGame.default(){} + + public GOGGame(GOG src, Json.Node json_node) + { + source = src; + + var json_obj = json_node.get_object(); + + id = json_obj.get_int_member("id").to_string(); + name = json_obj.get_string_member("title"); + icon = ""; + + if(json_obj.has_member("image")) + { + image = "https:" + json_obj.get_string_member("image") + "_392.jpg"; + } + + info = Json.to_string(json_node, false); + + var worksOn = json_obj != null && json_obj.has_member("worksOn") ? json_obj.get_object_member("worksOn") : null; + if(worksOn != null && worksOn.get_boolean_member("Linux")) platforms.add(Platform.LINUX); + if(worksOn != null && worksOn.get_boolean_member("Windows")) platforms.add(Platform.WINDOWS); + if(worksOn != null && worksOn.get_boolean_member("Mac")) platforms.add(Platform.MACOS); + + var tags_json = !json_obj.has_member("tags") ? null : json_obj.get_array_member("tags"); + if(tags_json != null) + { + foreach(var tag_json in tags_json.get_elements()) + { + var tid = source.id + ":" + tag_json.get_string(); + foreach(var t in Tables.Tags.TAGS) + { + if(tid == t.id) + { + if(!tags.contains(t)) tags.add(t); + break; + } + } + } + } + + has_updates = json_obj.has_member("updates") && json_obj.get_int_member("updates") > 0; + + install_dir = null; + executable_path = "$game_dir/start.sh"; + work_dir_path = "$game_dir"; + + mount_overlays.begin(); + update_status(); + } + + public GOGGame.from_db(GOG src, Sqlite.Statement s) + { + source = src; + id = Tables.Games.ID.get(s); + name = Tables.Games.NAME.get(s); + info = Tables.Games.INFO.get(s); + info_detailed = Tables.Games.INFO_DETAILED.get(s); + icon = Tables.Games.ICON.get(s); + image = Tables.Games.IMAGE.get(s); + install_dir = Tables.Games.INSTALL_PATH.get(s) != null ? FSUtils.file(Tables.Games.INSTALL_PATH.get(s)) : null; + executable_path = Tables.Games.EXECUTABLE.get(s); + work_dir_path = Tables.Games.WORK_DIR.get(s); + compat_tool = Tables.Games.COMPAT_TOOL.get(s); + compat_tool_settings = Tables.Games.COMPAT_TOOL_SETTINGS.get(s); + arguments = Tables.Games.ARGUMENTS.get(s); + last_launch = Tables.Games.LAST_LAUNCH.get_int64(s); + playtime_source = Tables.Games.PLAYTIME_SOURCE.get_int64(s); + playtime_tracked = Tables.Games.PLAYTIME_TRACKED.get_int64(s); + image_vertical = Tables.Games.IMAGE_VERTICAL.get(s); + + platforms.clear(); + var pls = Tables.Games.PLATFORMS.get(s).split(","); + foreach(var pl in pls) + { + foreach(var p in Platform.PLATFORMS) + { + if(pl == p.id()) + { + platforms.add(p); + break; + } + } + } + + tags.clear(); + var tag_ids = (Tables.Games.TAGS.get(s) ?? "").split(","); + foreach(var tid in tag_ids) + { + foreach(var t in Tables.Tags.TAGS) + { + if(tid == t.id) + { + if(!tags.contains(t)) tags.add(t); + break; + } + } + } + + var tweaks_string = Tables.Games.TWEAKS.get(s); + if(tweaks_string != null) + { + tweaks = tweaks_string.split(","); + } + + mount_overlays.begin(); + update_status(); + } + + public override async void update_game_info() + { + if(game_info_updating) return; + game_info_updating = true; + + yield mount_overlays(); + update_status(); + + if(info_detailed == null || info_detailed.length == 0) + { + var lang = Intl.setlocale(LocaleCategory.ALL, null).down().substring(0, 2); + var url = @"https://api.gog.com/products/$(id)?expand=downloads,description,expanded_dlcs" + (lang != null && lang.length > 0 ? "&locale=" + lang : ""); + + while(true) + { + uint status = 0; + var json = (yield Parser.load_remote_file_async(url, "GET", ((GOG) source).user_token, null, null, out status)); + + if(status == Soup.Status.OK && json != null && json.length > 0) + { + info_detailed = json; + break; + } + else if(status == Soup.Status.UNAUTHORIZED) + { + yield ((GOG) source).refresh_token(); + } + else break; + } + } + + var root = Parser.parse_json(info_detailed); + + var images = Parser.json_object(root, {"images"}); + var desc = Parser.json_object(root, {"description"}); + var links = Parser.json_object(root, {"links"}); + + if(image == null || image == "") + { + var i = Parser.parse_json(info).get_object(); + image = "https:" + i.get_string_member("image") + "_392.jpg"; + } + + if((icon == null || icon == "") && (images != null && images.has_member("icon"))) + { + icon = images.get_string_member("icon"); + if(icon != null) icon = "https:" + icon; + else icon = image; + } + + is_installable = root != null && root.get_node_type() == Json.NodeType.OBJECT + && root.get_object().has_member("is_installable") && root.get_object().get_boolean_member("is_installable"); + + if(desc != null) + { + description = desc.get_string_member("full"); + var cool = desc.get_string_member("whats_cool_about_it"); + if(cool != null && cool.length > 0) + { + description += "
    "; + var cool_parts = cool.split("\n"); + foreach(var part in cool_parts) + { + part = part.strip(); + if(part.length > 0) + { + description += "
  • " + part + "
  • "; + } + } + description += "
"; + } + } + + if(links != null) + { + store_page = links.get_string_member("product_card"); + } + + var downloads = Parser.json_object(root, {"downloads"}); + + var installers_json = downloads == null || !downloads.has_member("installers") ? null : downloads.get_array_member("installers"); + if(installers_json != null && installers.size == 0) + { + foreach(var installer_json in installers_json.get_elements()) + { + var installer = new Installer(this, installer_json.get_object()); + installers.add(installer); + } + } + + if(installers.size == 0) + { + is_installable = false; + } + + var bonuses_json = downloads == null || !downloads.has_member("bonus_content") ? null : downloads.get_array_member("bonus_content"); + if(bonuses_json != null && bonus_content.size == 0) + { + Json.Object? bonus_map = null; + + if(bonus_content_dir != null && bonus_content_dir.query_exists()) + { + var map_file = bonus_content_dir.get_child(BonusContent.FILEMAP_NAME); + if(map_file != null && map_file.query_exists()) + { + var map_root_node = Parser.parse_json_file(map_file.get_path()); + bonus_map = map_root_node != null && map_root_node.get_node_type() == Json.NodeType.OBJECT ? map_root_node.get_object() : null; + } + } + + foreach(var bonus_json in bonuses_json.get_elements()) + { + bonus_content.add(new BonusContent(this, bonus_json.get_object(), bonus_map)); + } + } + + var dlcs_json = root == null || root.get_node_type() != Json.NodeType.OBJECT || !root.get_object().has_member("expanded_dlcs") ? null : root.get_object().get_array_member("expanded_dlcs"); + if(dlcs_json != null && dlc.size == 0) + { + foreach(var dlc_json in dlcs_json.get_elements()) + { + var d = new GOGGame.DLC(this, dlc_json); + dlc.add(d); + yield d.update_downloads_info(); + } + } + + root = Parser.parse_json(info); + + var tags_json = root == null || root.get_node_type() != Json.NodeType.OBJECT || !root.get_object().has_member("tags") ? null : root.get_object().get_array_member("tags"); + + if(tags_json != null) + { + foreach(var tag_json in tags_json.get_elements()) + { + var tid = source.id + ":" + tag_json.get_string(); + foreach(var t in Tables.Tags.TAGS) + { + if(tid == t.id) + { + if(!tags.contains(t)) tags.add(t); + break; + } + } + } + } + + save(); + + update_status(); + + game_info_updated = true; + game_info_updating = false; + } + + public override async void install(Runnable.Installer.InstallMode install_mode=Runnable.Installer.InstallMode.INTERACTIVE) + { + yield update_game_info(); + if(installers == null || installers.size < 1) return; + new GameHub.UI.Dialogs.InstallDialog(this, installers, install_mode, install.callback); + yield; + } + + public override async void uninstall() + { + if(install_dir != null && install_dir.query_exists()) + { + string? uninstaller = null; + try + { + FileInfo? finfo = null; + var enumerator = yield install_dir.enumerate_children_async("standard::*", FileQueryInfoFlags.NONE); + while((finfo = enumerator.next_file()) != null) + { + if(finfo.get_name().has_prefix("uninstall-")) + { + uninstaller = finfo.get_name(); + break; + } + } + } + catch(Error e){} + + yield umount_overlays(); + + if(uninstaller != null) + { + uninstaller = FSUtils.expand(install_dir.get_path(), uninstaller); + debug("[GOGGame] Running uninstaller '%s'...", uninstaller); + yield Utils.run({uninstaller, "--noprompt", "--force"}).override_runtime(true).run_sync_thread(); + } + else + { + FSUtils.rm(install_dir.get_path(), "", "-rf"); + } + update_status(); + } + if((install_dir == null || !install_dir.query_exists()) && (executable == null || !executable.query_exists())) + { + install_dir = null; + executable = null; + save(); + update_status(); + } + } + + public override void update_status() + { + if(status.state == Game.State.DOWNLOADING && status.download.status.state != Downloader.Download.State.CANCELLED) return; + + var state = Game.State.UNINSTALLED; + + var gameinfo = get_file("gameinfo", false); + var goggame = get_file(@"goggame-$(id).info"); + var gh_marker = get_file(@".gamehub_$(id)"); + + var files = new ArrayList(); + + files.add(goggame); + files.add(gh_marker); + + if(!(this is DLC)) + { + files.add(executable); + files.add(gameinfo); + } + + foreach(var file in files) + { + if(file != null && file.query_exists()) + { + state = Game.State.INSTALLED; + break; + } + } + + status = new Game.Status(state, this); + if(state == Game.State.INSTALLED) + { + remove_tag(Tables.Tags.BUILTIN_UNINSTALLED); + add_tag(Tables.Tags.BUILTIN_INSTALLED); + } + else + { + add_tag(Tables.Tags.BUILTIN_UNINSTALLED); + remove_tag(Tables.Tags.BUILTIN_INSTALLED); + } + + if(gameinfo != null && gameinfo.query_exists()) + { + try + { + string info; + FileUtils.get_contents(gameinfo.get_path(), out info); + var lines = info.split("\n"); + if(lines.length >= 2) + { + version = lines[1]; + } + } + catch(Error e) + { + warning("[GOGGame.update_status] Error while reading gameinfo: %s", e.message); + } + } + else + { + update_version(); + } + + actions.clear(); + if(goggame != null && goggame.query_exists()) + { + var goggame_node = Parser.parse_json_file(goggame.get_path()); + if(goggame_node != null && goggame_node.get_node_type() == Json.NodeType.OBJECT) + { + var goggame_obj = goggame_node.get_object(); + var tasks = goggame_obj.has_member("playTasks") ? goggame_obj.get_array_member("playTasks") : null; + if(tasks != null) + { + foreach(var task_node in tasks.get_elements()) + { + if(task_node == null || task_node.get_node_type() != Json.NodeType.OBJECT) continue; + var action = new RunnableAction(this, task_node.get_object()); + if(!action.is_hidden) + { + actions.add(action); + } + } + } + } + } + + string g = name; + string? d = null; + if(this is DLC) + { + g = (this as DLC).game.name; + d = name; + } + installers_dir = FSUtils.file(FSUtils.Paths.Collection.GOG.expand_installers(g, d)); + bonus_content_dir = FSUtils.file(FSUtils.Paths.Collection.GOG.expand_bonus(g, d)); + } + + private bool loading_achievements = false; + public override async ArrayList? load_achievements() + { + if(achievements != null || loading_achievements || source == null || ((GOG) source).user_id == null) + { + return achievements; + } + + loading_achievements = true; + + Json.Node? root = null; + Json.Object? root_obj = null; + + while(true) + { + var url = "https://gameplay.gog.com/clients/%s/users/%s/achievements".printf(id, ((GOG) source).user_id); + uint status = 0; + + root = (yield Parser.parse_remote_json_file_async(url, "GET", ((GOG) source).user_token, null, null, out status)); + root_obj = root != null && root.get_node_type() == Json.NodeType.OBJECT ? root.get_object() : null; + + if(status == Soup.Status.UNAUTHORIZED) + { + yield ((GOG) source).refresh_token(); + } + else break; + } + + if(root_obj == null || !root_obj.has_member("items")) + { + loading_achievements = false; + return null; + } + + var achievements_array = root_obj.get_array_member("items"); + + var _achievements = new ArrayList(); + + foreach(var a_node in achievements_array.get_elements()) + { + var a_obj = a_node != null && a_node.get_node_type() == Json.NodeType.OBJECT + ? a_node.get_object() : null; + + if(a_obj == null || !a_obj.has_member("achievement_key")) continue; + + var a_id = a_obj.get_string_member("achievement_key"); + var a_name = a_obj.has_member("name") ? a_obj.get_string_member("name") : a_id; + var a_desc = a_obj.has_member("description") ? a_obj.get_string_member("description") : ""; + var a_image_unlocked = a_obj.has_member("image_url_unlocked") ? a_obj.get_string_member("image_url_unlocked") : null; + var a_image_locked = a_obj.has_member("image_url_locked") ? a_obj.get_string_member("image_url_locked") : null; + string? a_unlock_date = null; + + if(a_obj.has_member("date_unlocked")) + { + var date = a_obj.get_member("date_unlocked"); + if(date.get_node_type() == Json.NodeType.VALUE) + { + a_unlock_date = date.get_string(); + } + } + + bool a_unlocked = a_unlock_date != null; + float a_global_percentage = a_obj.has_member("rarity") ? (float) a_obj.get_double_member("rarity") : 0; + + _achievements.add(new Achievement(a_id, a_name, a_desc, a_image_locked, a_image_unlocked, + a_unlocked, a_unlock_date, a_global_percentage)); + } + + _achievements.sort((first, second) => { + var a1 = first as Achievement; + var a2 = second as Achievement; + + if(a1.unlock_date != null || a2.unlock_date != null) + { + return (a2.unlock_date ?? new DateTime.from_unix_utc(0)).compare(a1.unlock_date ?? new DateTime.from_unix_utc(0)); + } + + if(a1.global_percentage < a2.global_percentage) return 1; + if(a1.global_percentage > a2.global_percentage) return -1; + return 0; + }); + + achievements = _achievements; + loading_achievements = false; + return achievements; + } + + public class Achievement: Game.Achievement + { + public Achievement(string id, string name, string desc, string? image_locked, string? image_unlocked, + bool unlocked, string? unlock_date, float global_percentage) + { + this.id = id; + this.name = name; + this.description = desc; + this.image_locked = image_locked; + this.image_unlocked = image_unlocked; + this.unlocked = unlocked; + this.global_percentage = global_percentage; + + #if GLIB_2_56 + if(unlock_date != null) + { + this.unlock_date = new DateTime.from_iso8601(unlock_date, new TimeZone.utc()); + this.unlock_time = Utils.get_relative_datetime(this.unlock_date); + } + #endif + } + } + + public class Installer: Runnable.DownloadableInstaller + { + private GOGGame game; + private Json.Object json; + private bool fetched = false; + private File? installers_dir; + + public string lang; + public string lang_full; + + public override string name { owned get { return lang_full + (version != null ? ": " + version : ""); } } + + public Installer(GOGGame game, Json.Object json) + { + this.game = game; + this.json = json; + + id = json.get_string_member("id"); + lang = json.get_string_member("language"); + lang_full = json.get_string_member("language_full"); + + var os = json.get_string_member("os"); + platform = Platform.CURRENT; + foreach(var p in Platform.PLATFORMS) + { + if(os == p.id()) + { + platform = p; + break; + } + } + + string g = game.name; + string? d = null; + if(game is DLC) + { + g = (game as DLC).game.name; + d = game.name; + } + installers_dir = FSUtils.file(FSUtils.Paths.Collection.GOG.expand_installers(g, d, platform)) ?? game.installers_dir; + + full_size = json.get_int_member("total_size"); + version = json.get_string_member("version"); + } + + public override async void fetch_parts() + { + if(fetched || installers_dir == null || !json.has_member("files") || json.get_member("files").get_node_type() != Json.NodeType.ARRAY) return; + + int loading_count = 0; + + foreach(var file_node in json.get_array_member("files").get_elements()) + { + var file = file_node != null && file_node.get_node_type() == Json.NodeType.OBJECT ? file_node.get_object() : null; + if(file != null) + { + var id = file.get_string_member("id"); + var size = file.get_int_member("size"); + var downlink_url = file.get_string_member("downlink"); + + Utils.thread("GOGGame.Installer.fetch_part", () => { + loading_count++; + + var root_node = Parser.parse_remote_json_file(downlink_url, "GET", ((GOG) game.source).user_token); + if(root_node != null && root_node.get_node_type() == Json.NodeType.OBJECT) + { + var root = root_node.get_object(); + if(root != null && root.has_member("downlink")) + { + var url = root.get_string_member("downlink"); + var checksum_url = root.get_string_member("checksum"); + var remote = File.new_for_uri(url); + + string? local_filename = null; + + string? hash = null; + var hash_type = ChecksumType.MD5; + + var checksum_root = Parser.parse_remote_xml_file(checksum_url, "GET", ((GOG) game.source).user_token); + if(checksum_root != null) + { + var checksum_file_node = checksum_root->get_root_element(); + if(checksum_file_node != null) + { + hash = checksum_file_node->get_prop("md5"); + local_filename = checksum_file_node->get_prop("name"); + } + + delete checksum_root; + } + + if(local_filename == null && "/namespaces/website/download?path=" in url) + { + var remote_path_encoded = url.split("/namespaces/website/download?path=")[1].split("&")[0]; + var remote_path = Uri.unescape_string(remote_path_encoded); + local_filename = File.new_for_path(remote_path).get_basename(); + } + + var local = installers_dir.get_child(local_filename ?? "gog_" + game.id + "_" + this.id + "_" + id); + + parts.add(new Runnable.DownloadableInstaller.Part(id, url, size, remote, local, hash, hash_type)); + } + } + + loading_count--; + if(loading_count == 0) + { + Idle.add(fetch_parts.callback); + } + }); + } + } + + yield; + fetched = true; + } + } + + public class RunnableAction: Runnable.RunnableAction + { + public RunnableAction(GOGGame game, Json.Object json) + { + runnable = game; + is_primary = json.has_member("isPrimary") && json.get_boolean_member("isPrimary"); + is_hidden = json.has_member("isHidden") && json.get_boolean_member("isHidden"); + name = json.has_member("name") ? json.get_string_member("name") : game.name; + + var type = json.has_member("type") ? json.get_string_member("type") : "filetask"; + + if(type.down() == "filetask") + { + file = find_file(json.get_string_member("path")); + if(file != null && file.query_exists()) + { + if(file.get_basename().down().has_suffix(".exe")) + { + workdir = find_file(json.has_member("workingDir") ? json.get_string_member("workingDir") : ""); + args = json.has_member("arguments") ? json.get_string_member("arguments").replace("\\", "/").strip() : null; + compat_tools = { typeof(GameHub.Data.Compat.Wine) }; + } + else + { + uri = file.get_uri(); + file = null; + } + } + } + else if(type.down() == "urltask") + { + uri = json.has_member("link") ? json.get_string_member("link") : null; + } + } + + private File? find_file(string path) + { + if(runnable.install_dir == null || !runnable.install_dir.query_exists()) return null; + var dir = (runnable is Game && ((Game) runnable).overlays_enabled) + ? runnable.install_dir.get_child(FSUtils.GAMEHUB_DIR).get_child("_overlay").get_child("merged") + : runnable.install_dir; + if(dir == null || !dir.query_exists()) return null; + var p = path.replace("//", "/").replace("\\", "/").strip(); + if(p.length == 0) return dir; + return FSUtils.find_case_insensitive(dir, p); + } + } + + public class BonusContent + { + public const string FILEMAP_NAME = ".bonusmap.json"; + + public GOGGame game; + + public string id; + public string name; + public string type; + public int64 count; + public string file; + public int64 size; + + public string filename; + + protected BonusContent.Status _status = new BonusContent.Status(); + public signal void status_change(BonusContent.Status status); + + public BonusContent.Status status + { + get { return _status; } + set { _status = value; status_change(_status); } + } + + public Downloader.DownloadInfo dl_info; + + public File? downloaded_file; + + public string text { owned get { return count > 1 ? @"$(count) $(name)" : name; } } + + public string icon + { + get + { + switch(type) + { + case "wallpapers": + case "images": + case "avatars": + case "artworks": + return "folder-pictures-symbolic"; + + case "audio": + case "soundtrack": + return "folder-music-symbolic"; + + case "video": + return "folder-videos-symbolic"; + + default: return "folder-documents-symbolic"; + } + } + } + + public BonusContent(GOGGame game, Json.Object json, Json.Object? bonus_map=null) + { + this.game = game; + id = json.get_int_member("id").to_string(); + name = json.get_string_member("name"); + type = json.get_string_member("type"); + count = json.get_int_member("count"); + file = json.get_array_member("files").get_object_element(0).get_string_member("downlink"); + size = json.get_int_member("total_size"); + dl_info = new Downloader.DownloadInfo(text, game.name, game.icon, null, null, icon); + + filename = @"gog_$(game.id)_bonus_$(id)"; + if(bonus_map != null && bonus_map.has_member(id)) + { + filename = bonus_map.get_string_member(id); + downloaded_file = game.bonus_content_dir.get_child(filename); + status = new BonusContent.Status(downloaded_file != null && downloaded_file.query_exists() ? BonusContent.State.DOWNLOADED : BonusContent.State.NOT_DOWNLOADED); + } + } + + public async File? download() + { + if(game.bonus_content_dir == null) return null; + + Json.Node? root_node = null; + + while(true) + { + uint status = 0; + + root_node = yield Parser.parse_remote_json_file_async(file, "GET", ((GOG) game.source).user_token, null, null, out status); + + if(status == Soup.Status.UNAUTHORIZED) + { + yield ((GOG) game.source).refresh_token(); + } + else break; + } + + if(root_node == null || root_node.get_node_type() != Json.NodeType.OBJECT) return null; + var root = root_node.get_object(); + if(root == null || !root.has_member("downlink")) return null; + + var url = root.get_string_member("downlink"); + var checksum_url = root.get_string_member("checksum"); + var remote = File.new_for_uri(url); + + if(filename == @"gog_$(game.id)_bonus_$(id)" && "/namespaces/website/download?path=" in url) + { + var remote_path_encoded = url.split("/namespaces/website/download?path=")[1].split("&")[0]; + var remote_path = Uri.unescape_string(remote_path_encoded); + filename = File.new_for_path(remote_path).get_basename(); + } + + warning("[filename] %s", filename); + + FSUtils.mkdir(FSUtils.Paths.GOG.Games); + FSUtils.mkdir(game.bonus_content_dir.get_path()); + + var local = game.bonus_content_dir.get_child(filename); + + status = new BonusContent.Status(BonusContent.State.DOWNLOADING, null); + var ds_id = Downloader.download_manager().file_download_started.connect(dl => { + if(dl.remote != remote) return; + status = new BonusContent.Status(BonusContent.State.DOWNLOADING, dl); + dl.status_change.connect(s => { + status_change(status); + }); + }); + + var start_date = new DateTime.now_local(); + + try + { + downloaded_file = yield Downloader.download_file(remote, local, dl_info, true, false); + } + catch(Error e){} + + Downloader.download_manager().disconnect(ds_id); + + save_filename(); + + status = new BonusContent.Status(downloaded_file != null && downloaded_file.query_exists() ? BonusContent.State.DOWNLOADED : BonusContent.State.NOT_DOWNLOADED); + + var elapsed = new DateTime.now_local().difference(start_date); + + if(elapsed <= 10 * TimeSpan.SECOND) open(); + + return downloaded_file; + } + + public void open() + { + if(downloaded_file != null && downloaded_file.query_exists()) + { + Idle.add(() => { + Utils.open_uri(downloaded_file.get_uri()); + return Source.REMOVE; + }); + } + } + + private void save_filename() + { + if(game.bonus_content_dir == null || downloaded_file == null || !downloaded_file.query_exists()) return; + + filename = downloaded_file.get_basename(); + + var file = game.bonus_content_dir.get_child(BonusContent.FILEMAP_NAME); + + Json.Node? root_node = null; + Json.Object? root = null; + + if(file != null && file.query_exists()) + { + root_node = Parser.parse_json_file(file.get_path()); + } + + if(root_node == null || root_node.get_node_type() != Json.NodeType.OBJECT) + { + root_node = new Json.Node(Json.NodeType.OBJECT); + root = new Json.Object(); + } + else + { + root = root_node.get_object(); + } + + root.set_string_member(id, filename); + root_node.set_object(root); + + var json = Json.to_string(root_node, true); + + try + { + FileUtils.set_contents(file.get_path(), json); + } + catch(Error e) + { + warning("[GOGGame.BonusContent.save_filename] %s", e.message); + } + } + + public class Status + { + public BonusContent.State state; + + public Downloader.Download? download; + + public Status(BonusContent.State state=BonusContent.State.NOT_DOWNLOADED, Downloader.Download? download=null) + { + this.state = state; + this.download = download; + } + } + + public enum State + { + NOT_DOWNLOADED, DOWNLOADING, DOWNLOADED; + } + } + + public class DLC: GOGGame + { + public GOGGame game; + + public override File? default_install_dir + { + owned get + { + return game.default_install_dir; + } + } + + public DLC(GOGGame game, Json.Node json_node) + { + base(game.source as GOG, json_node); + + icon = game.icon; + image = game.image; + + install_dir = game.install_dir; + work_dir = game.work_dir; + executable = game.executable; + + platforms = game.platforms; + + this.game = game; + update_status(); + } + + // hack to parse installers/downloads fast, but allow next updates to fetch less important data + public async void update_downloads_info() + { + info_detailed = info; + yield update_game_info(); + info_detailed = null; + } + + public override void update_status() + { + if(game == null) return; + + base.update_status(); + } + + public override async void install(Runnable.Installer.InstallMode install_mode=Runnable.Installer.InstallMode.INTERACTIVE) + { + if(game.install_dir == null || !game.install_dir.query_exists()) return; + + yield game.umount_overlays(); + game.enable_overlays(); + var overlay = new Game.Overlay(game, "dlc_" + id, _("DLC: %s").printf(name), true); + + yield game.mount_overlays(overlay.directory); + + install_dir = game.install_dir.get_child(FSUtils.GAMEHUB_DIR).get_child("_overlay").get_child("merged"); + + yield base.install(install_mode); + + yield game.umount_overlays(); + + game.overlays.add(overlay); + game.save_overlays(); + yield game.mount_overlays(); + } } } } diff --git a/src/data/sources/humble/Humble.vala b/src/data/sources/humble/Humble.vala new file mode 100644 index 00000000..80bdf3d0 --- /dev/null +++ b/src/data/sources/humble/Humble.vala @@ -0,0 +1,240 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; +using GameHub.Data.DB; +using GameHub.Utils; + +namespace GameHub.Data.Sources.Humble +{ + public class Humble: GameSource + { + public const string AUTH_COOKIE = "_simpleauth_sess"; + + public static Humble instance; + + public override string id { get { return "humble"; } } + public override string name { get { return "Humble Bundle"; } } + public override string icon { get { return "source-humble-symbolic"; } } + + public override bool enabled + { + get { return settings.enabled; } + set { settings.enabled = value; } + } + + public string? user_token = null; + + public static string? escaped_cookie(string? token) + { + if(token == null) + { + return null; + } + var escaped = "%s=\"%s\";".printf(AUTH_COOKIE, token.replace("=", "\\075")); + + if(GameHub.Application.log_auth && GameHub.Application.log_verbose) + { + debug("[Humble.escaped_cookie] Unescaped: %s", token); + debug("[Humble.escaped_cookie] Escaped: %s", escaped); + } + + return escaped; + } + + private Settings.Auth.Humble settings; + + public Humble() + { + instance = this; + + settings = Settings.Auth.Humble.instance; + var access_token = settings.access_token; + if(access_token.length > 0) + { + user_token = access_token; + } + } + + public override bool is_installed(bool refresh) + { + return true; + } + + public override async bool install() + { + return true; + } + + public override async bool authenticate() + { + settings.authenticated = true; + + return yield get_token(); + } + + public override bool is_authenticated() + { + return user_token != null; + } + + public override bool can_authenticate_automatically() + { + return user_token != null && settings.authenticated; + } + + private async bool get_token() + { + if(user_token != null) + { + return true; + } + + var wnd = new GameHub.UI.Windows.WebAuthWindow(this.name, "https://www.humblebundle.com/login?goto=home", "https://www.humblebundle.com/home/library", AUTH_COOKIE); + + wnd.finished.connect(token => + { + user_token = token.replace("\"", "").replace("\\\\075", "=").replace("\\075", "="); + settings.access_token = user_token ?? ""; + if(GameHub.Application.log_auth) + { + debug("[Auth] Humble access token: %s", user_token); + } + Idle.add(get_token.callback); + }); + + wnd.canceled.connect(() => Idle.add(get_token.callback)); + + wnd.show_all(); + wnd.present(); + + yield; + + return user_token != null; + } + + private ArrayList _games = new ArrayList(Game.is_equal); + + public override ArrayList games { get { return _games; } } + + public override async ArrayList load_games(Utils.FutureResult2? game_loaded=null, Utils.Future? cache_loaded=null) + { + if(user_token == null || _games.size > 0) + { + return _games; + } + + Utils.thread("HumbleLoading", () => { + _games.clear(); + + var cached = Tables.Games.get_all(this); + games_count = 0; + if(cached.size > 0) + { + foreach(var g in cached) + { + if(g.platforms.size == 0) continue; + if(!Settings.UI.Behavior.instance.merge_games || !Tables.Merges.is_game_merged(g)) + { + _games.add(g); + if(game_loaded != null) + { + game_loaded(g, true); + } + } + games_count++; + } + } + + if(cache_loaded != null) + { + cache_loaded(); + } + + var headers = new HashMap(); + headers["Cookie"] = escaped_cookie(user_token); + + var orders_json = Parser.load_remote_file("https://www.humblebundle.com/api/v1/user/order?ajax=true", "GET", null, headers); + var orders_md5 = Utils.md5(orders_json); + + try + { + string? cached_orders_md5 = null; + FileUtils.get_contents(FSUtils.expand(FSUtils.Paths.Humble.LoadedOrdersMD5), out cached_orders_md5); + if(orders_md5 == cached_orders_md5) + { + Idle.add(load_games.callback); + return; + } + } + catch(Error e){} + + try + { + FileUtils.set_contents(FSUtils.expand(FSUtils.Paths.Humble.LoadedOrdersMD5), orders_md5); + } + catch(Error e){} + + var orders = Parser.parse_json(orders_json).get_array(); + + foreach(var order in orders.get_elements()) + { + var key = order.get_object().get_string_member("gamekey"); + + var root_node = Parser.parse_remote_json_file(@"https://www.humblebundle.com/api/v1/order/$(key)?ajax=true", "GET", null, headers); + + if(root_node == null || root_node.get_node_type() != Json.NodeType.OBJECT) continue; + + var root = root_node.get_object(); + + if(root == null) continue; + + var products = root.get_array_member("subproducts"); + + if(products == null) continue; + + foreach(var product in products.get_elements()) + { + var game = new HumbleGame(this, key, product); + if(game.platforms.size == 0) continue; + bool is_new_game = !_games.contains(game); + if(is_new_game && (!Settings.UI.Behavior.instance.merge_games || !Tables.Merges.is_game_merged(game))) + { + _games.add(game); + if(game_loaded != null) + { + game_loaded(game, false); + } + } + if(is_new_game) + { + games_count++; + game.save(); + } + } + } + + Idle.add(load_games.callback); + }); + + yield; + + return _games; + } + } +} diff --git a/src/data/sources/humble/HumbleGame.vala b/src/data/sources/humble/HumbleGame.vala new file mode 100644 index 00000000..edda76de --- /dev/null +++ b/src/data/sources/humble/HumbleGame.vala @@ -0,0 +1,502 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; +using GameHub.Data.DB; +using GameHub.Utils; + +namespace GameHub.Data.Sources.Humble +{ + public class HumbleGame: Game, TweakableGame + { + public string[]? tweaks { get; set; default = null; } + + public string order_id; + + private bool game_info_updating = false; + private bool game_info_updated = false; + private bool game_info_refreshed = false; + + public ArrayList? installers { get; protected set; default = new ArrayList(); } + + public override File? default_install_dir + { + owned get + { + return FSUtils.file(FSUtils.Paths.Humble.Games, escaped_name); + } + } + + public HumbleGame(Humble src, string order, Json.Node json_node) + { + source = src; + + var json_obj = json_node.get_object(); + + id = json_obj.get_string_member("machine_name"); + name = json_obj.has_member("human_name") ? json_obj.get_string_member("human_name") : json_obj.get_string_member("human-name"); + image = json_obj.has_member("image") ? json_obj.get_string_member("image") : json_obj.get_string_member("icon"); + icon = json_obj.has_member("icon") ? json_obj.get_string_member("icon") : image; + order_id = order; + + info = Json.to_string(json_node, false); + + platforms.clear(); + + if(json_obj.has_member("downloads")) + { + var downloads_node = json_obj.get_member("downloads"); + switch(downloads_node.get_node_type()) + { + case Json.NodeType.ARRAY: + foreach(var dl in downloads_node.get_array().get_elements()) + { + var dl_platform = dl.get_object().get_string_member("platform"); + foreach(var p in Platform.PLATFORMS) + { + if(dl_platform == p.id()) + { + platforms.add(p); + } + } + } + break; + + case Json.NodeType.OBJECT: + foreach(var dl_platform in downloads_node.get_object().get_members()) + { + foreach(var p in Platform.PLATFORMS) + { + if(dl_platform == p.id()) + { + platforms.add(p); + } + } + } + break; + } + } + + install_dir = null; + executable_path = "$game_dir/start.sh"; + work_dir_path = "$game_dir"; + info_detailed = @"{\"order\":\"$(order_id)\"}"; + + mount_overlays.begin(); + update_status(); + } + + public HumbleGame.from_db(Humble src, Sqlite.Statement s) + { + source = src; + id = Tables.Games.ID.get(s); + name = Tables.Games.NAME.get(s); + info = Tables.Games.INFO.get(s); + info_detailed = Tables.Games.INFO_DETAILED.get(s); + icon = Tables.Games.ICON.get(s); + image = Tables.Games.IMAGE.get(s); + install_dir = Tables.Games.INSTALL_PATH.get(s) != null ? FSUtils.file(Tables.Games.INSTALL_PATH.get(s)) : null; + executable_path = Tables.Games.EXECUTABLE.get(s); + work_dir_path = Tables.Games.WORK_DIR.get(s); + compat_tool = Tables.Games.COMPAT_TOOL.get(s); + compat_tool_settings = Tables.Games.COMPAT_TOOL_SETTINGS.get(s); + arguments = Tables.Games.ARGUMENTS.get(s); + last_launch = Tables.Games.LAST_LAUNCH.get_int64(s); + playtime_source = Tables.Games.PLAYTIME_SOURCE.get_int64(s); + playtime_tracked = Tables.Games.PLAYTIME_TRACKED.get_int64(s); + image_vertical = Tables.Games.IMAGE_VERTICAL.get(s); + + platforms.clear(); + var pls = Tables.Games.PLATFORMS.get(s).split(","); + foreach(var pl in pls) + { + foreach(var p in Platform.PLATFORMS) + { + if(pl == p.id()) + { + platforms.add(p); + break; + } + } + } + + tags.clear(); + var tag_ids = (Tables.Games.TAGS.get(s) ?? "").split(","); + foreach(var tid in tag_ids) + { + foreach(var t in Tables.Tags.TAGS) + { + if(tid == t.id) + { + if(!tags.contains(t)) tags.add(t); + break; + } + } + } + + var json_node = Parser.parse_json(info_detailed); + if(json_node != null && json_node.get_node_type() == Json.NodeType.OBJECT) + { + var json = json_node.get_object(); + if(json.has_member("order")) + { + order_id = json.get_string_member("order"); + } + } + + var tweaks_string = Tables.Games.TWEAKS.get(s); + if(tweaks_string != null) + { + tweaks = tweaks_string.split(","); + } + + mount_overlays.begin(); + update_status(); + } + + public override void update_status() + { + if(status.state == Game.State.DOWNLOADING && status.download.status.state != Downloader.Download.State.CANCELLED) return; + + status = new Game.Status(executable != null && executable.query_exists() ? Game.State.INSTALLED : Game.State.UNINSTALLED, this); + if(status.state == Game.State.INSTALLED) + { + remove_tag(Tables.Tags.BUILTIN_UNINSTALLED); + add_tag(Tables.Tags.BUILTIN_INSTALLED); + } + else + { + add_tag(Tables.Tags.BUILTIN_UNINSTALLED); + remove_tag(Tables.Tags.BUILTIN_INSTALLED); + } + + installers_dir = FSUtils.file(FSUtils.Paths.Collection.Humble.expand_installers(name)); + + update_version(); + } + + public override async void update_game_info() + { + if(game_info_updating) return; + game_info_updating = true; + + yield mount_overlays(); + update_status(); + + if((icon == null || icon == "") && (info != null && info.length > 0)) + { + var i = Parser.parse_json(info).get_object(); + icon = i.get_string_member("icon"); + } + + if(image == null || image == "") + { + image = icon; + } + + if(game_info_updated) + { + game_info_updating = false; + return; + } + + if(info == null || info.length == 0) + { + var token = ((Humble) source).user_token; + + var headers = new HashMap(); + headers["Cookie"] = @"$(Humble.AUTH_COOKIE)=\"$(token)\";"; + + var root_node = yield Parser.parse_remote_json_file_async(@"https://www.humblebundle.com/api/v1/order/$(order_id)?ajax=true", "GET", null, headers); + if(root_node == null || root_node.get_node_type() != Json.NodeType.OBJECT) + { + game_info_updating = false; + return; + } + var root = root_node.get_object(); + if(root == null) + { + game_info_updating = false; + return; + } + var products = root.get_array_member("subproducts"); + if(products == null) + { + game_info_updating = false; + return; + } + foreach(var product_node in products.get_elements()) + { + if(product_node.get_object().get_string_member("machine_name") != id) continue; + info = Json.to_string(product_node, false); + break; + } + } + + var product_node = Parser.parse_json(info); + if(product_node == null || product_node.get_node_type() != Json.NodeType.OBJECT) + { + game_info_updating = false; + return; + } + + var product = product_node.get_object(); + if(product == null) + { + game_info_updating = false; + return; + } + + if(product.has_member("description-text")) + { + description = product.get_string_member("description-text"); + } + else if(product.has_member("_gamehub_description")) + { + description = product.get_string_member("_gamehub_description"); + } + + save(); + + update_status(); + + game_info_updated = true; + game_info_updating = false; + } + + private async void update_installers() + { + if(installers.size > 0) return; + + var product_node = Parser.parse_json(info); + if(product_node == null || product_node.get_node_type() != Json.NodeType.OBJECT) return; + + var product = product_node.get_object(); + if(product == null) return; + + if(product.has_member("downloads")) + { + bool refresh = false; + + var downloads_node = product.get_member("downloads"); + switch(downloads_node.get_node_type()) + { + case Json.NodeType.ARRAY: + foreach(var dl_node in downloads_node.get_array().get_elements()) + { + var dl = dl_node.get_object(); + var id = dl.get_string_member("machine_name"); + var dl_id = dl.has_member("download_identifier") ? dl.get_string_member("download_identifier") : null; + var os = dl.get_string_member("platform"); + if(dl.has_member("download_struct") && dl.get_member("download_struct").get_node_type() == Json.NodeType.ARRAY) + { + foreach(var dls_node in dl.get_array_member("download_struct").get_elements()) + { + refresh = process_download(id, dl_id, os, dls_node.get_object()); + } + } + } + break; + + case Json.NodeType.OBJECT: + foreach(var os in downloads_node.get_object().get_members()) + { + var dl = downloads_node.get_object().get_object_member(os); + var id = dl.get_string_member("machine_name"); + var dl_id = dl.has_member("download_identifier") ? dl.get_string_member("download_identifier") : null; + refresh = process_download(id, dl_id, os, dl); + } + break; + } + + if(refresh && !game_info_refreshed) + { + game_info_refreshed = true; + game_info_updated = false; + installers.clear(); + yield update_game_info(); + yield update_installers(); + return; + } + } + + is_installable = installers.size > 0; + + if(installers.size == 0 && source is Trove) + { + Utils.notify( + _("%s: no available installers").printf(name), + _("Cannot get Trove download URL.\nMake sure your Humble Monthly subscription is active."), + NotificationPriority.HIGH, + n => { + n.set_icon(new ThemedIcon("dialog-warning")); + var cached_icon = ImageCache.local_file(icon, @"$(source.id)/$(id)/icons/"); + if(cached_icon != null && cached_icon.query_exists()) + { + n.set_icon(new FileIcon(cached_icon)); + } + return n; + } + ); + } + } + + private bool process_download(string id, string? dl_id, string os, Json.Object dl_struct) + { + var platform = Platform.CURRENT; + foreach(var p in Platform.PLATFORMS) + { + if(os == p.id()) + { + platform = p; + break; + } + } + + bool refresh = false; + + var installer = new Installer(this, id, dl_id, platform, dl_struct); + if(installer.is_url_update_required()) + { + if(source is Trove) + { + var old_url = installer.part.url; + var new_url = installer.update_url(this); + if(new_url != null) + { + var url_field = "\"%s\""; + info = info.replace(url_field.printf(old_url), url_field.printf(new_url)); + } + refresh = true; + } + else + { + info = null; + refresh = true; + } + } + if(!refresh) installers.add(installer); + + return refresh; + } + + public override async void install(Runnable.Installer.InstallMode install_mode=Runnable.Installer.InstallMode.INTERACTIVE) + { + yield update_installers(); + if(installers.size < 1) return; + new GameHub.UI.Dialogs.InstallDialog(this, installers, install_mode, install.callback); + yield; + } + + public override async void uninstall() + { + if(install_dir != null && install_dir.query_exists()) + { + yield umount_overlays(); + FSUtils.rm(install_dir.get_path(), "", "-rf"); + update_status(); + if((install_dir == null || !install_dir.query_exists()) && (executable == null || !executable.query_exists())) + { + install_dir = null; + executable = null; + save(); + update_status(); + } + } + } + + public class Installer: Runnable.DownloadableInstaller + { + private File? installers_dir; + + public string dl_name; + public string? dl_id; + public Runnable.DownloadableInstaller.Part part; + + public override string name { owned get { return dl_name; } } + + public Installer(HumbleGame game, string machine_name, string? download_identifier, Platform platform, Json.Object download) + { + id = machine_name; + this.platform = platform; + dl_id = download_identifier; + dl_name = download.has_member("name") ? download.get_string_member("name") : ""; + var url_obj = download.has_member("url") ? download.get_object_member("url") : null; + var url = url_obj != null && url_obj.has_member("web") ? url_obj.get_string_member("web") : ""; + full_size = download.has_member("file_size") ? download.get_int_member("file_size") : 0; + + installers_dir = FSUtils.file(FSUtils.Paths.Collection.Humble.expand_installers(game.name, platform)) ?? game.installers_dir; + + if(installers_dir == null) return; + + var remote = File.new_for_uri(url); + var local = installers_dir.get_child("humble_" + game.id + "_" + id); + + string? hash = null; + ChecksumType hash_type = ChecksumType.MD5; + + if(download.has_member("md5")) + { + hash = download.get_string_member("md5"); + hash_type = ChecksumType.MD5; + } + else if(download.has_member("sha1")) + { + hash = download.get_string_member("sha1"); + hash_type = ChecksumType.SHA1; + } + else if(download.has_member("sha256")) + { + hash = download.get_string_member("sha256"); + hash_type = ChecksumType.SHA256; + } + + part = new Runnable.DownloadableInstaller.Part(id, url, full_size, remote, local, hash, hash_type); + parts.add(part); + } + + public bool is_url_update_required() + { + if(part.url == null || part.url.length == 0 || part.url.has_prefix("humble-trove-unsigned://")) return true; + if(!part.url.contains("&ttl=")) return false; + var ttl_string = part.url.split("&ttl=")[1].split("&")[0]; + var ttl = new DateTime.from_unix_utc(int64.parse(ttl_string)); + var now = new DateTime.now_utc(); + var res = ttl.compare(now); + return res != 1; + } + + public string? update_url(HumbleGame game) + { + if(!(game.source is Trove) || !is_url_update_required()) return null; + + var new_url = Trove.sign_url(id, dl_id, ((Humble) game.source).user_token); + + if(GameHub.Application.log_verbose) + { + debug("[HumbleGame.Installer.update_url] Old URL: '%s'; (%s)", part.url, game.full_id); + debug("[HumbleGame.Installer.update_url] New URL: '%s'; (%s)", new_url, game.full_id); + } + + if(new_url != null) part.url = new_url; + + return new_url; + } + } + } +} diff --git a/src/data/sources/humble/Trove.vala b/src/data/sources/humble/Trove.vala new file mode 100644 index 00000000..38a216dc --- /dev/null +++ b/src/data/sources/humble/Trove.vala @@ -0,0 +1,170 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; +using GameHub.Data.DB; +using GameHub.Utils; + +namespace GameHub.Data.Sources.Humble +{ + public class Trove: Humble + { + public const string PAGE_URL = "https://www.humblebundle.com/monthly/trove"; + public const string SIGN_URL = "https://www.humblebundle.com/api/v1/user/download/sign"; + public const string FAKE_ORDER = "humble-trove"; + public const string TROVE_INTRO_ID = "trove_intro"; + + public override string id { get { return "humble-trove"; } } + public override string name { get { return "Humble Trove"; } } + public override string icon { get { return "source-humble-trove-symbolic"; } } + + public override bool enabled + { + get { return Settings.Auth.Humble.instance.enabled && Settings.Auth.Humble.instance.load_trove_games; } + set { Settings.Auth.Humble.instance.load_trove_games = value; } + } + + private ArrayList _games = new ArrayList(Game.is_equal); + + public override ArrayList games { get { return _games; } } + + public override async ArrayList load_games(Utils.FutureResult2? game_loaded=null, Utils.Future? cache_loaded=null) + { + if(user_token == null || _games.size > 0) + { + return _games; + } + + Utils.thread("HumbleTroveLoading", () => { + _games.clear(); + + var cached = Tables.Games.get_all(this); + games_count = 0; + if(cached.size > 0) + { + foreach(var g in cached) + { + if(g.platforms.size == 0) continue; + if(!Settings.UI.Behavior.instance.merge_games || !Tables.Merges.is_game_merged(g)) + { + _games.add(g); + if(game_loaded != null) + { + game_loaded(g, true); + } + } + games_count++; + } + } + + if(cache_loaded != null) + { + cache_loaded(); + } + + var headers = new HashMap(); + headers["Cookie"] = escaped_cookie(user_token); + + var html = Parser.parse_remote_html_file(Trove.PAGE_URL, "GET", null, headers); + + if(html != null) + { + var xpath = new Xml.XPath.Context(html); + + var trove_json = xpath.eval("//script[@id='webpack-monthly-trove-data']/text()")->nodesetval->item(0)->content.strip(); + + if(trove_json != null) + { + var trove_root_node = Parser.parse_json(trove_json); + if(trove_root_node.get_node_type() == Json.NodeType.OBJECT) + { + var trove_root = trove_root_node.get_object(); + if(trove_root != null) + { + var products = trove_root.has_member("standardProducts") ? trove_root.get_array_member("standardProducts") : null; + if(products != null) + { + products.foreach_element((array, index, node) => { + var obj = node.get_object(); + var key = obj.get_string_member("machine_name"); + + if(key == TROVE_INTRO_ID) return; + + var downloads = obj.get_object_member("downloads"); + + downloads.foreach_member((downloads_obj, dl_os, dl_node) => { + var dl_obj = dl_node.get_object(); + var dl_name = dl_obj.get_string_member("machine_name"); + var dl_id = dl_obj.get_object_member("url").get_string_member("web"); + dl_obj.set_string_member("download_identifier", dl_id); + dl_obj.get_object_member("url").set_string_member("web", "humble-trove-unsigned://" + dl_name + "/_gh_dl_/" + dl_id); + }); + + var game = new HumbleGame(this, Trove.FAKE_ORDER, node); + + if(game.platforms.size == 0) return; + bool is_new_game = !_games.contains(game); + if(is_new_game && (!Settings.UI.Behavior.instance.merge_games || !Tables.Merges.is_game_merged(game))) + { + _games.add(game); + if(game_loaded != null) + { + game_loaded(game, false); + } + } + if(is_new_game) games_count++; + }); + } + } + } + } + + delete html; + } + + Idle.add(load_games.callback); + }); + + yield; + + return _games; + } + + public static string? sign_url(string machine_name, string filename, string humble_token) + { + var headers = new HashMap(); + headers["Cookie"] = escaped_cookie(humble_token); + + var data = new HashMap(); + data["machine_name"] = machine_name; + data["filename"] = filename; + + var signed_node = Parser.parse_remote_json_file(Trove.SIGN_URL, "POST", null, headers, data); + var signed = signed_node != null && signed_node.get_node_type() == Json.NodeType.OBJECT ? signed_node.get_object() : null; + + var signed_url = signed != null && signed.has_member("signed_url") ? signed.get_string_member("signed_url") : null; + + if(GameHub.Application.log_verbose) + { + debug("[Trove.sign_url] '%s':'%s' -> '%s'", machine_name, filename, signed_url); + } + + return signed_url; + } + } +} diff --git a/src/data/sources/itch/ButlerClient.vala b/src/data/sources/itch/ButlerClient.vala new file mode 100644 index 00000000..8bbd1859 --- /dev/null +++ b/src/data/sources/itch/ButlerClient.vala @@ -0,0 +1,277 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin +Copyright (C) 2019 Yaohan Chen + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; +using GameHub.Utils; + +namespace GameHub.Data.Sources.Itch +{ + /** + * JSON-RPC 2.0 client compatible with butler daemon + * We have to make our own because jsonrpc-glib-1.0 prefixes messages + * with Content-Length headers, while butler daemon expects one message + * per line, deliminated by LF + */ + public class ButlerClient: Object, ServerMessageListener, ServerMessageRelay + { + private SocketConnection socket_connection; + private int message_id = 0; + private Sender sender; + private Receiver receiver; + + public ButlerClient(SocketConnection socket_connection) + { + this.socket_connection = socket_connection; + sender = new Sender(socket_connection.output_stream); + receiver = new Receiver(socket_connection.input_stream, sender); + relay_messages(receiver); + } + + public async Json.Object? call(string method, Json.Node? params=null, out Json.Object? error = null) + { + message_id++; + sender.send(message_id, method, params); + return (yield receiver.get_reply(message_id, out error)); + } + + private class Sender + { + private DataOutputStream stream; + + public Sender(OutputStream output_stream) + { + this.stream = new DataOutputStream(output_stream); + } + + public void send(int message_id, string method, Json.Node? params=null) + { + var request = Parser.json(j => j + .set_member_name("jsonrpc").add_string_value("2.0") + .set_member_name("id").add_int_value(message_id) + .set_member_name("method").add_string_value(method) + .set_member_name("params").add_value(params ?? Parser.json()) + ); + + try + { + var json = Json.to_string(request, false); + stream.put_string(json + "\n"); + + if(Application.log_verbose) + { + debug("[ButlerClient: req %d] %s", message_id, json); + } + } + catch(Error e) + { + warning("[ButlerClient: req %d] Error while sending request: %s", message_id, e.message); + } + } + + public void respond(int message_id, Json.Node? result=null) + { + var request = Parser.json(j => j + .set_member_name("jsonrpc").add_string_value("2.0") + .set_member_name("id").add_int_value(message_id) + .set_member_name("result").add_value(result ?? Parser.json()) + ); + + try + { + var json = Json.to_string(request, false); + stream.put_string(json + "\n"); + + if(Application.log_verbose) + { + debug("[ButlerClient: srs %d] %s", message_id, json); + } + } + catch(Error e) + { + warning("[ButlerClient: srs %d] Error while responding to server request: %s", message_id, e.message); + } + } + } + + private class Receiver: Object, ServerMessageListener + { + private DataInputStream stream; + private Sender sender; + private HashMap responses; + + public Receiver(InputStream input_stream, Sender sender) + { + stream = new DataInputStream(input_stream); + stream.set_newline_type(DataStreamNewlineType.LF); + responses = new HashMap(); + this.sender = sender; + Utils.thread("ItchButlerClientReceiver", () => { + handle_messages.begin(); + }, false); + } + + private async void handle_messages() + { + while(true) + { + try + { + var json = yield stream.read_line_async(); + var root = Parser.parse_json(json); + if(root == null || root.get_node_type() != Json.NodeType.OBJECT) continue; + + var obj = root.get_object(); + if(obj == null) continue; + + const int NO_ID = -1; + var error_info = obj.has_member("error") ? obj.get_object_member("error") : null; + var message_id = obj.has_member("id") ? (int) obj.get_int_member("id") : NO_ID; + var result = obj.has_member("result") ? obj.get_object_member("result") : null; + var params = obj.has_member("params") ? obj.get_object_member("params") : null; + var method = obj.has_member("method") ? obj.get_string_member("method") : null; + + if(error_info != null && message_id != NO_ID) + { + // failure response + warning("[ButlerClient: err %d] %s", message_id, json); + responses.set(message_id, {error_info, false}); + } + else if(result != null && message_id != NO_ID) + { + // success response + if(Application.log_verbose) + { + debug("[ButlerClient: res %d] %s", message_id, json); + } + responses.set(message_id, {result, true}); + } + else if(message_id != NO_ID) + { + // server request + debug("[ButlerClient: srv %d] %s", message_id, json); + server_call(method, params, new ServerMessageResponder(result => sender.respond(message_id, result))); + } + else if(params != null && method != null) + { + // notification + notification(method, params); + + switch(method.down()) + { + case "log": + var log_level = params.has_member("level") ? params.get_string_member("level") : "info"; + var log_message = "[ButlerClient: log] " + params.get_string_member("message"); + switch(log_level.down()) + { + case "info": + info(log_message); + break; + + case "debug": + if(Application.log_verbose) + { + debug(log_message); + } + break; + + case "warning": + case "error": + warning(log_message); + break; + } + break; + + default: + if(Application.log_verbose) + { + debug("[ButlerClient: ntf] %s", json); + } + break; + } + } + else + { + warning("[ButlerClient: ???] %s", json); + } + } + catch(Error e) + { + warning("[ButlerClient] Error while handling messages: %s", e.message); + } + } + } + + public async Json.Object? get_reply(int message_id, out Json.Object? error=null) + { + error = null; + while(!responses.has_key(message_id)) + { + yield Utils.sleep_async(50); + } + Response response; + responses.unset(message_id, out response); + + if(response.successful) + { + return response.content; + } + else + { + error = response.content; + return null; + } + } + + struct Response + { + Json.Object content; + bool successful; + } + } + } + + public class ServerMessageResponder + { + public delegate void Delegate(Json.Node? result=null); + private Delegate responder; + public ServerMessageResponder(owned Delegate responder) + { + this.responder = (owned) responder; + } + public void respond(Json.Node? result=null) + { + responder(result); + } + } + + public interface ServerMessageListener: Object + { + public signal void notification(string method, Json.Object? args); + public signal void server_call(string method, Json.Object? args, ServerMessageResponder responder); + } + + public interface ServerMessageRelay: ServerMessageListener + { + public void relay_messages(ServerMessageListener source) + { + source.notification.connect((method, args) => notification(method, args)); + source.server_call.connect((method, args, responder) => server_call(method, args, responder)); + } + } +} diff --git a/src/data/sources/itch/ButlerConnection.vala b/src/data/sources/itch/ButlerConnection.vala new file mode 100644 index 00000000..38dde111 --- /dev/null +++ b/src/data/sources/itch/ButlerConnection.vala @@ -0,0 +1,235 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin +Copyright (C) 2019 Yaohan Chen + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; +using GameHub.Utils; + +namespace GameHub.Data.Sources.Itch +{ + public class ButlerConnection: Object, ServerMessageListener, ServerMessageRelay + { + private ButlerClient client; + + public async bool init(string address, string secret) + { + try + { + client = new ButlerClient(yield (new SocketClient().connect_to_host_async(address, 0, null))); + relay_messages(client); + + var res = yield client.call("Meta.Authenticate", Parser.json(j => j.set_member_name("secret").add_string_value(secret))); + return res != null && res.has_member("ok") && res.get_boolean_member("ok"); + } + catch(Error e) + { + warning("[ButlerConnection.connect] Error: %s", e.message); + } + return false; + } + + public async bool authenticate(string api_key, out string? user_name, out int? user_id) + { + user_name = null; + user_id = null; + var res = yield client.call("Profile.LoginWithAPIKey", Parser.json(j => j.set_member_name("apiKey").add_string_value(api_key))); + var user = Parser.json_nested_object(res, {"profile", "user"}); + + if(user == null) return false; + if(user.has_member("username")) + user_name = user.get_string_member("username"); + if(user.has_member("id")) + user_id = (int) user.get_int_member("id"); + return true; + } + + public async ArrayList get_owned_keys(int profile_id, bool fresh) + { + var res = yield client.call("Fetch.ProfileOwnedKeys", Parser.json(j => j + .set_member_name("profileId").add_int_value(profile_id) + .set_member_name("fresh").add_boolean_value(fresh) + )); + + ArrayList items = new ArrayList(); + + var arr = res.has_member("items") ? res.get_array_member("items") : null; + if(arr != null) + { + arr.foreach_element((array, index, node) => { + items.add(node.get_object().get_member("game")); + }); + // next page + } + + return items; + } + + public async HashMap> get_caves(int? game_id=null, out ArrayList installed_games=null) + { + var result = yield client.call("Fetch.Caves", Parser.json(j => { + if(game_id != null) + { + j.set_member_name("filters").begin_object() + .set_member_name("gameId").add_int_value(game_id) + .end_object(); + } + })); + var caves = new HashMap>(); + var installed = new ArrayList(); + + var arr = result.has_member("items") ? result.get_array_member("items") : null; + if(arr != null) + { + arr.foreach_element((array, index, node) => { + var cave = node.get_object(); + var cave_id = cave.get_string_member("id"); + var game = cave.get_member("game"); + var cave_game_id = (int) game.get_object().get_int_member("id"); + + var install_info = cave.has_member("installInfo") ? cave.get_object_member("installInfo") : null; + var install_dir = install_info != null && install_info.has_member("installFolder") ? install_info.get_string_member("installFolder") : null; + + installed.add(game); + + ArrayList caves_for_game; + if(caves.has_key(cave_game_id)) + { + caves_for_game = caves.get(cave_game_id); + } + else + { + caves_for_game = new ArrayList(); + caves.set(cave_game_id, caves_for_game); + } + caves_for_game.add(new Cave(cave_id, install_dir)); + }); + } + + installed_games = installed; + return caves; + } + + public async Cave? get_cave(string cave_id) + { + var result = yield client.call("Fetch.Cave", Parser.json(j => j + .set_member_name("caveId").add_string_value(cave_id) + )); + var install_info = Parser.json_nested_object(result, {"cave", "installInfo"}); + var install_dir = install_info != null && install_info.has_member("installFolder") ? install_info.get_string_member("installFolder") : null; + return install_dir != null ? new Cave(cave_id, install_dir) : null; + } + + public async ArrayList? get_game_uploads(int game_id) + { + var result = yield client.call("Game.FindUploads", Parser.json(j => j + .set_member_name("game").begin_object() + .set_member_name("id").add_int_value(game_id) + .end_object() + )); + var uploads = new ArrayList(); + var arr = result.has_member("uploads") ? result.get_array_member("uploads") : null; + if(arr != null) + { + arr.foreach_element((array, index, node) => { + uploads.add(node.get_object()); + }); + } + return uploads; + } + + public async void install(int game_id, int upload_id, string install_id) + { + var install_dir = FSUtils.mkdir(FSUtils.Paths.Itch.Games); + var install_dir_is_added = false; + string? install_location_id = null; + + var install_locations_list = (yield client.call("Install.Locations.List")).get_array_member("installLocations"); + + foreach(var location_node in install_locations_list.get_elements()) + { + var location_obj = location_node.get_object(); + if(location_obj != null && location_obj.get_string_member("path") == install_dir.get_path()) + { + install_dir_is_added = true; + install_location_id = location_obj.get_string_member("id"); + break; + } + } + + if(!install_dir_is_added) + { + var add_install_location_result = yield client.call("Install.Locations.Add", Parser.json(j => j + .set_member_name("path").add_string_value(install_dir.get_path()) + )); + install_location_id = add_install_location_result.get_object_member("installLocation").get_string_member("id"); + } + + var install_queue_result = yield client.call("Install.Queue", Parser.json(j => j + .set_member_name("game").begin_object() + .set_member_name("id").add_int_value(game_id) + .end_object() + .set_member_name("upload").begin_object() + .set_member_name("id").add_int_value(upload_id) + .end_object() + .set_member_name("installLocationId").add_string_value(install_location_id) + .set_member_name("queueDownload").add_boolean_value(true) + )); + + var staging_folder = install_queue_result.get_string_member("stagingFolder"); + yield client.call("Install.Perform", Parser.json(j => j + .set_member_name("id").add_string_value(install_id) + .set_member_name("stagingFolder").add_string_value(staging_folder) + )); + } + + public async bool cancel_install(string id) + { + var result = yield client.call("Install.Cancel", Parser.json(j => j + .set_member_name("id").add_string_value(id) + )); + return result.get_boolean_member("didCancel"); + } + + public async void uninstall(string cave_id) + { + yield client.call("Uninstall.Perform", Parser.json(j => j + .set_member_name("caveId").add_string_value(cave_id) + )); + } + + public async void run(string cave_id) + { + var prereqs_dir = FSUtils.expand(FSUtils.Paths.Itch.Games, ".prereqs"); + yield client.call("Launch", Parser.json(j => j + .set_member_name("caveId").add_string_value(cave_id) + .set_member_name("prereqsDir").add_string_value(prereqs_dir) + )); + } + } + + public class Cave + { + public string id; + public string? install_dir; + public Cave(string id, string? install_dir) + { + this.id = id; + this.install_dir = install_dir; + } + } +} diff --git a/src/data/sources/itch/ButlerDaemon.vala b/src/data/sources/itch/ButlerDaemon.vala new file mode 100644 index 00000000..15478af8 --- /dev/null +++ b/src/data/sources/itch/ButlerDaemon.vala @@ -0,0 +1,111 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin +Copyright (C) 2019 Yaohan Chen + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; +using GameHub.Utils; + +namespace GameHub.Data.Sources.Itch +{ + public class ButlerDaemon + { + private File? butler_executable = null; + private DataInputStream stdout_stream; + private string address; + private string secret; + + public ButlerDaemon(File? executable) + { + butler_executable = executable; + start_daemon(); + } + + public async ButlerConnection create_connection() + { + if(address == null || secret == null) + { + yield get_credentials(); + } + + var connection = new ButlerConnection(); + yield connection.init(address, secret); + return connection; + } + + private void start_daemon() + { + if(butler_executable == null || !butler_executable.query_exists()) + { + warning("[ButlerDaemon.start_daemon] butler executable is not found"); + return; + } + + var butler_path = butler_executable.get_path(); + var db_path = FSUtils.expand(FSUtils.Paths.Itch.Home, FSUtils.Paths.Itch.Database); + + var pid = ((int) Posix.getpid()).to_string(); + + string[] cmd = { butler_path, "daemon", "--json", "--transport", "tcp", "--keep-alive", "--dbpath", db_path, "--destiny-pid", pid }; + int stdout_fd; + + try + { + if(Application.log_verbose) + { + debug("[ButlerDaemon.start_daemon] Starting butler daemon ('%s') with dbpath='%s'", butler_path, db_path); + } + Process.spawn_async_with_pipes(null, cmd, null, SpawnFlags.SEARCH_PATH, null, null, null, out stdout_fd, null); + stdout_stream = new DataInputStream(new UnixInputStream(stdout_fd, false)); + } + catch(Error e) + { + warning("[ButlerDaemon.start_daemon] Error while running butler: %s", e.message); + } + } + + private async void get_credentials() + { + address = null; + secret = null; + while(stdout_stream != null) + { + try + { + var line = yield stdout_stream.read_line_async(); + + var json_node = Parser.parse_json(line); + if(json_node != null && json_node.get_node_type() == Json.NodeType.OBJECT) + { + var json_object = json_node.get_object(); + + if(json_object.get_string_member("type") == "butlerd/listen-notification") + { + address = json_object.get_object_member("tcp").get_string_member("address"); + secret = json_object.get_string_member("secret"); + return; + } + } + } + catch(Error e) + { + warning("[ButlerDaemon.get_credentials] Error: %s", e.message); + } + } + } + } +} diff --git a/src/data/sources/itch/Itch.vala b/src/data/sources/itch/Itch.vala new file mode 100644 index 00000000..27462c53 --- /dev/null +++ b/src/data/sources/itch/Itch.vala @@ -0,0 +1,271 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin +Copyright (C) 2019 Yaohan Chen + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; +using GameHub.Utils; +using GameHub.Data; +using GameHub.Data.DB; + +namespace GameHub.Data.Sources.Itch +{ + public class Itch: GameSource + { + public static Itch instance; + + public File? butler_executable = null; + private ButlerDaemon? butler_daemon = null; + private ButlerConnection? butler_connection = null; + + public Itch() + { + instance = this; + } + + public override string id { get { return "itch"; } } + public override string name { get { return "itch.io"; } } + public override string icon { get { return "source-itch-symbolic"; } } + public override string auth_description + { + owned get + { + return ""; + } + } + public override bool enabled + { + get { return Settings.Auth.Itch.instance.enabled; } + set { Settings.Auth.Itch.instance.enabled = value; } + } + + public int? user_id { get; protected set; } + public string? user_name { get; protected set; } + + private bool? installed = null; + + public override bool is_installed(bool refresh) + { + if(installed != null && !refresh) + { + return (!) installed; + } + + var butler = Utils.find_executable("butler"); + + if(butler == null || !butler.query_exists()) + { + var version_file = FSUtils.file(FSUtils.Paths.Itch.Home, FSUtils.Paths.Itch.ButlerCurrentVersion); + if(version_file != null && version_file.query_exists()) + { + try + { + string version; + FileUtils.get_contents(version_file.get_path(), out version); + butler = FSUtils.file(FSUtils.Paths.Itch.Home, FSUtils.Paths.Itch.ButlerExecutable.printf(version)); + } + catch(Error e) + { + warning("[Itch.is_installed] Error while reading butler version: %s", e.message); + } + } + } + + butler_executable = butler; + + installed = butler_executable != null && butler_executable.query_exists(); + + return (!) installed; + } + + public override async bool install() + { + return true; + } + + public override async bool authenticate() + { + yield butler_connect(); + + Settings.Auth.Itch.instance.authenticated = true; + if(is_authenticated()) return true; + + var api_key = Settings.Auth.Itch.instance.api_key; + + string? user_name; + int? user_id; + var success = yield butler_connection.authenticate(api_key, out user_name, out user_id); + this.user_name = user_name; + this.user_id = user_id; + return success; + } + + public override bool is_authenticated() + { + return user_id != null; + } + + public override bool can_authenticate_automatically() + { + return Settings.Auth.Itch.instance.authenticated && Settings.Auth.Itch.instance.api_key != null && Settings.Auth.Itch.instance.api_key.length > 0; + } + + private ArrayList _games = new ArrayList(Game.is_equal); + + public override ArrayList games { get { return _games; } } + + public override async ArrayList load_games(Utils.FutureResult2? game_loaded=null, Utils.Future? cache_loaded=null) + { + if(!is_authenticated() || _games.size > 0) + { + return _games; + } + + Utils.thread("ItchLoading", () => { + _games.clear(); + + var cached = Tables.Games.get_all(this); + games_count = 0; + if(cached.size > 0) + { + foreach(var g in cached) + { + if(!Settings.UI.Behavior.instance.merge_games || !Tables.Merges.is_game_merged(g)) + { + _games.add(g); + if(game_loaded != null) + { + game_loaded(g, true); + } + } + games_count++; + } + } + + if(cache_loaded != null) + { + cache_loaded(); + } + + load_games_from_butler.begin(game_loaded, (obj, res) => { + load_games_from_butler.end(res); + Idle.add(load_games.callback); + }); + }); + + yield; + + return _games; + } + + private async void load_games_from_butler(Utils.FutureResult2? game_loaded=null) + { + ArrayList owned_games = yield butler_connection.get_owned_keys(user_id, true); + ArrayList installed_games; + + var caves = yield butler_connection.get_caves(null, out installed_games); + + ArrayList[] game_arrays = { owned_games, installed_games }; + foreach(var arr in game_arrays) + { + foreach(var node in arr) + { + var game = new ItchGame(this, node); + bool is_new_game = !_games.contains(game); + if(is_new_game && (!Settings.UI.Behavior.instance.merge_games || !Tables.Merges.is_game_merged(game))) + { + _games.add(game); + if(game_loaded != null) + { + game_loaded(game, false); + } + } + if(is_new_game) + { + games_count++; + game.save(); + } + } + } + + foreach(var g in _games) + { + yield update_game_state((ItchGame) g, caves); + } + } + + public async ArrayList? get_game_uploads(ItchGame game) + { + return yield butler_connection.get_game_uploads(game.int_id); + } + + public async void install_game(ItchGame.Installer installer) + { + yield ItchDownloader.get_instance().download(installer, butler_daemon); + yield update_game_state(installer.game); + } + + public async void uninstall_game(ItchGame game) + { + yield butler_connection.uninstall(game.cave_id); + yield update_game_state(game); + } + + public async void update_game_state(ItchGame game, HashMap>? caves_map=null) + { + caves_map = caves_map ?? yield butler_connection.get_caves(game.int_id); + game.update_caves(caves_map); + } + + public async void run_game(ItchGame game) + { + var connection = yield butler_daemon.create_connection(); + connection.server_call.connect((method, args, responder) => { + File? file = null; + switch(method) + { + case "ShellLaunch": + file = FSUtils.file(args.get_string_member("itemPath")); + break; + + case "HTMLLaunch": + file = FSUtils.file(args.get_string_member("rootFolder"), args.get_string_member("indexPath")); + break; + + case "URLLaunch": + file = File.new_for_uri(args.get_string_member("url")); + break; + } + if(file != null) + { + Utils.open_uri(file.get_uri()); + } + responder.respond(); + }); + yield connection.run(game.cave_id); + } + + private async void butler_connect() + { + if(butler_daemon == null && butler_executable != null || butler_executable.query_exists()) + { + butler_daemon = new ButlerDaemon(butler_executable); + butler_connection = yield butler_daemon.create_connection(); + } + } + } +} diff --git a/src/data/sources/itch/ItchDownloader.vala b/src/data/sources/itch/ItchDownloader.vala new file mode 100644 index 00000000..c58b72bf --- /dev/null +++ b/src/data/sources/itch/ItchDownloader.vala @@ -0,0 +1,208 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; + +using GameHub.Data.DB; +using GameHub.Utils; + +using GameHub.Utils.Downloader; + +namespace GameHub.Data.Sources.Itch +{ + public class ItchDownloader: GameHub.Utils.Downloader.Downloader + { + private static ItchDownloader? instance; + + private HashTable downloads; + private HashTable dl_info; + + public static ItchDownloader get_instance() + { + if(instance == null) + { + instance = new ItchDownloader(); + } + return instance; + } + + public ItchDownloader() + { + downloads = new HashTable(str_hash, str_equal); + dl_info = new HashTable(str_hash, str_equal); + download_manager().add_downloader(this); + } + + public override Download? get_download(string id) + { + lock(downloads) + { + return downloads.get(id); + } + } + + public ItchDownload? get_game_download(ItchGame? game) + { + if(game == null) return null; + lock(downloads) + { + return (ItchDownload?) downloads.get(game.full_id); + } + } + + public async void download(ItchGame.Installer? installer, ButlerDaemon butler_daemon) + { + if(installer == null) return; + var game = installer.game; + + var download = get_game_download(game); + if(game == null || download != null) return; + + var connection = yield butler_daemon.create_connection(); + var install_id = Uuid.string_random(); + + download = new ItchDownload(connection, install_id); + + lock(downloads) downloads.set(game.full_id, download); + download_started(download); + + download.status_change.connect(s => game.status_change(game.status)); + + var info = new DownloadInfo(game.name, null, game.icon, null, null, game.source.icon); + info.download = download; + + lock(dl_info) dl_info.set(game.full_id, info); + dl_started(info); + + if(GameHub.Application.log_downloader) + { + debug("[ItchDownloader] Installing '%s'...", game.full_id); + } + + game.status = new Game.Status(Game.State.DOWNLOADING, game, download); + + yield connection.install(game.int_id, installer.int_id, install_id); + + lock(downloads) downloads.remove(game.full_id); + lock(dl_info) dl_info.remove(game.full_id); + + download_finished(download); + dl_ended(info); + + game.update_status(); + } + } + + /* + TODO: Implement pause and resume + */ + public class ItchDownload: Download//, PausableDownload + { + private ButlerConnection butler_connection; + private int64 bytes_total = -1; + + public ItchDownload(ButlerConnection butler_connection, string install_id) + { + base(install_id); + this.butler_connection = butler_connection; + + status = new Status(Download.State.STARTING); + + butler_connection.notification.connect((s, method, @params) => { + switch(method) + { + case "TaskStarted": + bytes_total = params.get_int_member("totalSize"); + status = new Status(Download.State.STARTED); + break; + + case "Progress": + var progress = params.get_double_member("progress"); + var speed = params.get_double_member("bps"); + var eta = params.get_double_member("eta"); + status = new Status(Download.State.DOWNLOADING, bytes_total, progress, (int64) speed, (int64) eta); + break; + + case "TaskSucceeded": + status = new Status(Download.State.FINISHED); + break; + } + }); + } + + /* + TODO: Implement pause and resume + public void pause(){} + public void resume(){} + */ + + public override void cancel() + { + butler_connection.cancel_install.begin(id, (obj, result) => { + var cancelled = butler_connection.cancel_install.end(result); + if(cancelled) { + status = new Status(Download.State.CANCELLED); + } + }); + } + + public class Status: Download.Status + { + public int64 bytes_total = -1; + public double dl_progress = -1; + public int64 dl_speed = -1; + public int64 eta = -1; + + public Status(Download.State state=Download.State.STARTING, int64 total=-1, double progress=-1, int64 speed=-1, int64 eta=-1) + { + base(state); + this.bytes_total = total; + this.dl_progress = progress; + this.dl_speed = speed; + this.eta = eta; + } + + public override double progress + { + get { return (double) dl_progress; } + } + + public override string? progress_string + { + owned get + { + string[] result = {}; + + if(eta >= 0) + result += C_("itch_dl_status", "%s left;").printf(Utils.seconds_to_string(eta)); + + if(dl_progress >= 0) + result += C_("itch_dl_status", "%d%%").printf((int) (dl_progress * 100)); + + if(bytes_total >= 0) + result += C_("itch_dl_status", "(%1$s / %2$s)").printf(format_size((int) (dl_progress * bytes_total)), format_size(bytes_total)); + + if(dl_speed >= 0) + result += C_("itch_dl_status", "[%s/s]").printf(format_size(dl_speed)); + + return string.joinv(" ", result); + } + } + } + } +} diff --git a/src/data/sources/itch/ItchGame.vala b/src/data/sources/itch/ItchGame.vala new file mode 100644 index 00000000..d706ac95 --- /dev/null +++ b/src/data/sources/itch/ItchGame.vala @@ -0,0 +1,314 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; + +using GameHub.Data.DB; +using GameHub.Utils; + +namespace GameHub.Data.Sources.Itch +{ + public class ItchGame: Game + { + public int int_id { get { return int.parse(id); } } + + public ItchGame(Itch src, Json.Node json_node) + { + source = src; + + var json_obj = json_node.get_object(); + + id = json_obj.get_int_member("id").to_string(); + name = json_obj.get_string_member("title"); + icon = json_obj.has_member("stillCoverUrl") ? json_obj.get_string_member("stillCoverUrl") : json_obj.get_string_member("coverUrl"); + description = json_obj.get_string_member("shortText"); + store_page = json_obj.get_string_member("url"); + + image = icon; + + var platforms_obj = json_obj.get_object_member("platforms"); + if(platforms_obj.has_member("windows")) + { + platforms.add(Platform.WINDOWS); + } + if(platforms_obj.has_member("linux")) + { + platforms.add(Platform.LINUX); + } + if(platforms_obj.has_member("osx")) + { + platforms.add(Platform.MACOS); + } + + + info = Json.to_string(json_node, false); + + update_status(); + } + + public ItchGame.from_db(Itch src, Sqlite.Statement s) + { + source = src; + id = Tables.Games.ID.get(s); + name = Tables.Games.NAME.get(s); + info = Tables.Games.INFO.get(s); + info_detailed = Tables.Games.INFO_DETAILED.get(s); + icon = Tables.Games.ICON.get(s); + image = Tables.Games.IMAGE.get(s); + install_dir = Tables.Games.INSTALL_PATH.get(s) != null ? FSUtils.file(Tables.Games.INSTALL_PATH.get(s)) : null; + executable_path = Tables.Games.EXECUTABLE.get(s); + work_dir_path = Tables.Games.WORK_DIR.get(s); + compat_tool = Tables.Games.COMPAT_TOOL.get(s); + compat_tool_settings = Tables.Games.COMPAT_TOOL_SETTINGS.get(s); + arguments = Tables.Games.ARGUMENTS.get(s); + last_launch = Tables.Games.LAST_LAUNCH.get_int64(s); + playtime_source = Tables.Games.PLAYTIME_SOURCE.get_int64(s); + playtime_tracked = Tables.Games.PLAYTIME_TRACKED.get_int64(s); + + platforms.clear(); + var pls = Tables.Games.PLATFORMS.get(s).split(","); + foreach(var pl in pls) + { + foreach(var p in Platform.PLATFORMS) + { + if(pl == p.id()) + { + platforms.add(p); + break; + } + } + } + + tags.clear(); + var tag_ids = (Tables.Games.TAGS.get(s) ?? "").split(","); + foreach(var tid in tag_ids) + { + foreach(var t in Tables.Tags.TAGS) + { + if(tid == t.id) + { + if(!tags.contains(t)) tags.add(t); + break; + } + } + } + + var info_root = Parser.parse_json(info); + if(info_root != null && info_root.get_node_type() == Json.NodeType.OBJECT) + { + var info_root_obj = info_root.get_object(); + description = info_root_obj.get_string_member("shortText"); + store_page = info_root_obj.get_string_member("url"); + } + + update_status(); + } + + public override async void update_game_info() + { + update_status(); + } + + private ArrayList caves = new ArrayList(); + public void update_caves(HashMap> caves_map) + { + if(caves_map.has_key(int_id)) + { + caves = caves_map.get(int_id); + } + else + { + caves.clear(); + } + + var cave = this.cave; + if(cave != null) + { + install_dir = FSUtils.file(cave.install_dir); + } + + update_status(); + } + + public Cave? cave + { + owned get + { + if(caves.size > 0) + { + return caves.first(); + } + return null; + } + } + + public string? cave_id + { + get + { + var cave = this.cave; + return cave != null ? cave.id : null; + } + } + + public override void update_status() + { + if(status.state == Game.State.DOWNLOADING && status.download != null + && status.download.status != null && status.download.status.state != Downloader.Download.State.CANCELLED + && status.download.status.state != Downloader.Download.State.FINISHED) return; + + if(caves.size > 0) + { + status = new Game.Status(Game.State.INSTALLED, this); + } + else + { + status = new Game.Status(Game.State.UNINSTALLED, this); + } + + if(status.state == Game.State.INSTALLED) + { + remove_tag(Tables.Tags.BUILTIN_UNINSTALLED); + add_tag(Tables.Tags.BUILTIN_INSTALLED); + } + else + { + add_tag(Tables.Tags.BUILTIN_UNINSTALLED); + remove_tag(Tables.Tags.BUILTIN_INSTALLED); + } + } + + public override async void install(Runnable.Installer.InstallMode install_mode=Runnable.Installer.InstallMode.INTERACTIVE) + { + var uploads = yield ((Itch) source).get_game_uploads(this); + + if(uploads == null || uploads.size == 0) + { + is_installable = false; + return; + } + + var installers = new ArrayList(); + + foreach(var upload in uploads) + { + var platforms = new ArrayList(); + var platforms_obj = upload.get_object_member("platforms"); + if(platforms_obj.has_member("windows")) + { + platforms.add(Platform.WINDOWS); + } + if(platforms_obj.has_member("linux")) + { + platforms.add(Platform.LINUX); + } + if(platforms_obj.has_member("osx")) + { + platforms.add(Platform.MACOS); + } + + if(platforms.size == 0) platforms.add(Platform.CURRENT); + + foreach(var platform in platforms) + { + installers.add(new Installer(this, upload, platform)); + } + } + + new GameHub.UI.Dialogs.InstallDialog(this, installers, install_mode, install.callback); + yield; + } + + public override async void run() + { + if(can_be_launched(true)) + { + Runnable.IsLaunched = is_running = true; + update_status(); + + last_launch = get_real_time() / 1000000; + save(); + + yield ((Itch) source).run_game(this); + + playtime_tracked += ((get_real_time() / 1000000) - last_launch) / 60; + save(); + + Timeout.add_seconds(1, () => { + Runnable.IsLaunched = is_running = false; + update_status(); + return Source.REMOVE; + }); + } + } + + public override async void run_with_compat(bool is_opened_from_menu=false) + { + } + + public override async void uninstall() + { + ((Itch) source).uninstall_game.begin(this); + } + + public class Installer: Runnable.Installer + { + public int int_id { get { return int.parse(id); } } + + public ItchGame game; + private Json.Object json; + + public string? display_name; + public string? file_name; + + private string _name; + public override string name { owned get { return _name; } } + + public Installer(ItchGame game, Json.Object json, Platform platform) + { + this.game = game; + this.json = json; + + id = json.get_int_member("id").to_string(); + this.platform = platform; + + file_name = json.has_member("filename") ? json.get_string_member("filename") : null; + display_name = json.has_member("displayName") ? json.get_string_member("displayName") : null; + + if(file_name.length == 0) file_name = null; + if(display_name.length == 0) display_name = null; + + _name = display_name ?? file_name ?? game.name; + + var build_obj = json.has_member("build") ? json.get_object_member("build") : null; + if(build_obj != null) + { + version = build_obj.has_member("userVersion") ? build_obj.get_string_member("userVersion") : null; + _name += @" ($(version))"; + } + + full_size = json.get_int_member("size"); + } + + public override async void install(Runnable runnable, CompatTool? tool=null) + { + yield ((Itch) game.source).install_game(this); + } + } + } +} diff --git a/src/data/sources/steam/Steam.vala b/src/data/sources/steam/Steam.vala index 562cfaea..ce3b43c7 100644 --- a/src/data/sources/steam/Steam.vala +++ b/src/data/sources/steam/Steam.vala @@ -1,99 +1,552 @@ -using Gtk; +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + using Gee; +using GameHub.Data.DB; using GameHub.Utils; +using ZLib.Utility; namespace GameHub.Data.Sources.Steam { public class Steam: GameSource { - private const string API_KEY = "8B10B604CAC6AC90F57AACE025DD904C"; - + public static Steam instance; + + public Steam() + { + instance = this; + } + + public string api_key; + + public override string id { get { return "steam"; } } public override string name { get { return "Steam"; } } - public override string icon { get { return "steam-symbolic"; } } - public override string auth_description { owned get { return ".\n%s".printf(_("Your SteamID will be read from Steam configuration file")); } } - + public override string icon { get { return "source-steam-symbolic"; } } + public override string auth_description + { + owned get + { + var text = _("Your SteamID will be read from Steam configuration file"); + if(!is_authenticated_in_steam_client) + { + text = _("Steam config file not found.\nLogin into your account in Steam client and return to GameHub"); + } + return ".\n%s".printf(text); + } + } + + public override bool enabled + { + get { return Settings.Auth.Steam.instance.enabled; } + set { Settings.Auth.Steam.instance.enabled = value; } + } + public string? user_id { get; protected set; } public string? user_name { get; protected set; } private bool? installed = null; + public BinaryVDF.ListNode? appinfo; + public BinaryVDF.ListNode? packageinfo; + + public bool is_authenticated_in_steam_client + { + get + { + var loginusers = FSUtils.find_case_insensitive(FSUtils.file(FSUtils.Paths.Steam.Home), FSUtils.Paths.Steam.LoginUsersVDF); + return loginusers != null && loginusers.query_exists(); + } + } + public override bool is_installed(bool refresh) { if(installed != null && !refresh) { return (!) installed; } - - installed = Utils.is_package_installed("steam"); + + var distro = Utils.get_distro().down(); + if("ubuntu" in distro || "elementary" in distro || "pop!_os" in distro) + { + installed = Utils.is_package_installed("steam") + || Utils.is_package_installed("steam64") + || Utils.is_package_installed("steam-launcher") + || Utils.is_package_installed("steam-installer") + || FSUtils.file(FSUtils.Paths.Steam.Home).query_exists(); + } + else + { + installed = FSUtils.file(FSUtils.Paths.Steam.Home).query_exists(); + } + return (!) installed; } + public static bool find_app_install_dir(string app, out File? install_dir) + { + install_dir = null; + foreach(var dir in Steam.LibraryFolders) + { + var acf = FSUtils.find_case_insensitive(FSUtils.file(dir), @"appmanifest_$(app).acf"); + if(acf != null && acf.query_exists()) + { + var root = Parser.parse_vdf_file(acf.get_path()).get_object(); + var d = FSUtils.find_case_insensitive(FSUtils.file(dir), "common/" + root.get_object_member("AppState").get_string_member("installdir")); + install_dir = d; + return d != null && d.query_exists(); + } + } + return false; + } + + public static bool is_app_installed(string app) + { + return find_app_install_dir(app, null); + } + public override async bool install() { - Utils.open_uri("appstream://steam.desktop"); + var distro = Utils.get_distro().down(); + if("elementary" in distro || "pop!_os" in distro) + { + Utils.open_uri("appstream://steam.desktop"); + } return true; } public override async bool authenticate() { + Settings.Auth.Steam.instance.authenticated = true; + if(is_authenticated()) return true; - + var result = false; - - new Thread("steam-loginusers-thread", () => { - Json.Object config = Parser.parse_vdf_file(FSUtils.Paths.Steam.LoginUsersVDF); - var users = config.get_object_member("users"); - + + if(!is_authenticated_in_steam_client) + { + Utils.open_uri("steam://"); + return false; + } + + Utils.thread("Steam-loginusers", () => { + var loginusers = FSUtils.find_case_insensitive(FSUtils.file(FSUtils.Paths.Steam.Home), FSUtils.Paths.Steam.LoginUsersVDF); + + if(loginusers == null || !loginusers.query_exists()) + { + result = false; + Idle.add(authenticate.callback); + return; + } + + var config = Parser.parse_vdf_file(loginusers.get_path()); + var users = Parser.json_object(config, {"users"}); + + if(users == null) + { + result = false; + Idle.add(authenticate.callback); + return; + } + foreach(var uid in users.get_members()) { + var user = users.get_object_member(uid); + user_id = uid; - user_name = users.get_object_member(uid).get_string_member("PersonaName"); - - result = true; - break; + user_name = user.get_string_member("PersonaName"); + + var last = !user.has_member("mostrecent") || user.get_string_member("mostrecent") == "1"; + + if(GameHub.Application.log_auth) + { + debug(@"[Auth] SteamID: $(user_id), PersonaName: $(user_name), last: $(last)"); + } + + if(last) + { + result = true; + break; + } } - + Idle.add(authenticate.callback); - return null; }); - + yield; return result; } - + public override bool is_authenticated() { return user_id != null; } - private ArrayList games = new ArrayList(); - public override async ArrayList load_games(FutureResult? game_loaded = null) + public override bool can_authenticate_automatically() + { + return Settings.Auth.Steam.instance.authenticated && is_authenticated_in_steam_client; + } + + public void load_appinfo() + { + if(appinfo == null) + { + appinfo = new AppInfoVDF(FSUtils.find_case_insensitive(FSUtils.file(FSUtils.Paths.Steam.Home), FSUtils.Paths.Steam.AppInfoVDF)).read(); + } + if(packageinfo == null) + { + packageinfo = new PackageInfoVDF(FSUtils.find_case_insensitive(FSUtils.file(FSUtils.Paths.Steam.Home), FSUtils.Paths.Steam.PackageInfoVDF)).read(); + } + } + + private ArrayList _games = new ArrayList(Game.is_equal); + + public override ArrayList games { get { return _games; } } + + public override async ArrayList load_games(Utils.FutureResult2? game_loaded=null, Utils.Future? cache_loaded=null) + { + api_key = Settings.Auth.Steam.instance.api_key; + + if(!is_authenticated() || _games.size > 0) + { + return _games; + } + + Utils.thread("SteamLoading", () => { + _games.clear(); + + load_appinfo(); + + var cached = Tables.Games.get_all(this); + games_count = 0; + if(cached.size > 0) + { + foreach(var g in cached) + { + if(!Settings.UI.Behavior.instance.merge_games || !Tables.Merges.is_game_merged(g)) + { + _games.add(g); + if(game_loaded != null) + { + game_loaded(g, true); + } + } + games_count++; + } + } + + if(cache_loaded != null) + { + cache_loaded(); + } + + var url = @"https://api.steampowered.com/IPlayerService/GetOwnedGames/v0001/?key=$(api_key)&steamid=$(user_id)&format=json&include_appinfo=1&include_played_free_games=1"; + + var root = Parser.parse_remote_json_file(url); + var response = Parser.json_object(root, {"response"}); + var json_games = response != null && response.has_member("games") ? response.get_array_member("games") : null; + + if(json_games != null) + { + foreach(var g in json_games.get_elements()) + { + var game = new SteamGame(this, g); + bool is_new_game = !_games.contains(game); + if(is_new_game && (!Settings.UI.Behavior.instance.merge_games || !Tables.Merges.is_game_merged(game))) + { + _games.add(game); + if(game_loaded != null) + { + game_loaded(game, false); + } + } + if(is_new_game) + { + games_count++; + game.save(); + } + else if(g != null && g.get_node_type() == Json.NodeType.OBJECT) + { + _games.get(_games.index_of(game)).playtime_source = g.get_object().get_int_member("playtime_forever"); + } + } + } + + Idle.add(load_games.callback); + }); + + yield; + + watch_client_registry(); + + return _games; + } + + public static BinaryVDF.ListNode? get_appinfo(string appid) { - if(!is_authenticated() || games.size > 0) + if(instance.appinfo != null) { - return games; + return (BinaryVDF.ListNode?) instance.appinfo.get(appid); } - - var url = @"https://api.steampowered.com/IPlayerService/GetOwnedGames/v0001/?key=$(Steam.API_KEY)&steamid=$(this.user_id)&format=json&include_appinfo=1"; - - var root = yield Parser.parse_remote_json_file_async(url); - var json_games = root.get_object_member("response").get_array_member("games"); - - games.clear(); - - foreach(var g in json_games.get_elements()) + return null; + } + + public static string[]? get_packages_for_app(string appid) + { + if(instance.packageinfo == null) return null; + string[] pkgs = {}; + foreach(var pkg in instance.packageinfo.nodes.values) + { + if(appid in ((PackageInfoVDF.PackageNode) pkg).appids) + { + pkgs += ((PackageInfoVDF.PackageNode) pkg).id; + } + } + return pkgs; + } + + public static async string? get_appid_from_name(string game_name) + { + if(instance == null) return null; + + instance.load_appinfo(); + + if(instance.appinfo == null) return null; + + foreach(var app_node in instance.appinfo.nodes.values) { - var game = new SteamGame(this, g.get_object()); - if(yield game.is_for_linux()) + if(app_node != null && app_node is BinaryVDF.ListNode) { - games.add(game); - games_count = games.size; - if(game_loaded != null) game_loaded(game); + var app = (BinaryVDF.ListNode) app_node; + var common_node = app.get_nested({"appinfo", "common"}); + + if(common_node != null && common_node is BinaryVDF.ListNode) + { + var common = (BinaryVDF.ListNode) common_node; + + var name_node = common.get("name"); + var type_node = common.get("type"); + + if(name_node != null && name_node is BinaryVDF.StringNode && type_node != null && type_node is BinaryVDF.StringNode) + { + var name = ((BinaryVDF.StringNode) name_node).value; + var type = ((BinaryVDF.StringNode) type_node).value; + + if(type != null && type.down() == "game" && name != null && name.down() == game_name.down()) + { + return app.key; + } + } + } } } - - - return games; + + return null; } + + public static void install_app(string appid) + { + Utils.open_uri(@"steam://install/$(appid)"); + } + + public static void install_multiple_apps(string[] appids) + { + if(instance.packageinfo == null) return; + var packages = ""; + foreach(var appid in appids) + { + var pkgs = get_packages_for_app(appid); + foreach(var pkg in pkgs) + { + packages += "/" + pkg; + } + } + if(packages.length > 0) + { + Utils.open_uri("steam://subscriptioninstall" + packages); + } + } + + private void watch_client_registry() + { + var regfile = FSUtils.find_case_insensitive(FSUtils.file(FSUtils.Paths.Steam.Home), FSUtils.Paths.Steam.RegistryVDF); + if(regfile == null || !regfile.query_exists()) return; + + Timeout.add_seconds(5, () => { + Utils.thread("SteamClientRegistryUpdate", () => { + client_registry_update(regfile); + }, false); + return Source.CONTINUE; + }, Priority.LOW); + } + + private void client_registry_update(File? regfile) + { + if(regfile == null || !regfile.query_exists()) return; + + var reg = Parser.parse_vdf_file(regfile.get_path()); + var steam = Parser.json_object(reg, {"Registry", "HKCU", "Software", "Valve", "Steam"}); + + if(steam == null) return; + + var running_appid = steam.has_member("RunningAppID") ? steam.get_string_member("RunningAppID") : "0"; + IsAnyAppRunning = running_appid != "0"; + + var apps = steam.has_member("Apps") ? steam.get_member("Apps") : null; + + foreach(var g in _games) + { + var game = g as SteamGame; + + var appinfo = Parser.json_object(apps, {game.id}); + var running = game.id == running_appid || (appinfo != null && appinfo.has_member("Running") && appinfo.get_string_member("Running") == "1"); + var updating = appinfo != null && appinfo.has_member("Updating") && appinfo.get_string_member("Updating") == "1"; + + if(game.is_running != running || game.is_updating != updating) + { + game.is_running = running; + game.is_updating = updating; + game.update_status(); + } + } + } + + public static ArrayList? folders = null; + public static ArrayList LibraryFolders + { + get + { + if(folders != null) return folders; + folders = new ArrayList(); + + var steamapps = FSUtils.find_case_insensitive(FSUtils.file(FSUtils.Paths.Steam.Home), FSUtils.Paths.Steam.SteamApps); + + if(steamapps == null || !steamapps.query_exists()) return folders; + + folders.add(steamapps.get_path()); + + var libraryfolders = FSUtils.find_case_insensitive(steamapps, FSUtils.Paths.Steam.LibraryFoldersVDF); + + if(libraryfolders == null || !libraryfolders.query_exists()) return folders; + + var root = Parser.parse_vdf_file(libraryfolders.get_path()); + var lf = Parser.json_object(root, {"LibraryFolders"}); + + if(lf != null) + { + foreach(var key in lf.get_members()) + { + var libdir = FSUtils.file(lf.get_string_member(key)); + if(libdir != null && libdir.query_exists()) + { + var dir = FSUtils.find_case_insensitive(libdir, "steamapps"); + if(dir != null && dir.query_exists()) folders.add(dir.get_path()); + } + } + } + + return folders; + } + } + + public static uint64 communityid_to_steamid3(uint64 id) + { + return id - 76561197960265728; + } + + public static File? get_userdata_dir() + { + uint64 communityid = uint64.parse(instance.user_id); + uint64 steamid3 = communityid_to_steamid3(communityid); + return FSUtils.find_case_insensitive(FSUtils.file(FSUtils.Paths.Steam.Home), @"steam/userdata/$(steamid3)"); + } + + public static void add_game_shortcut(Game game) + { + var config_dir = FSUtils.find_case_insensitive(get_userdata_dir(), "config"); + if(config_dir == null || !config_dir.query_exists()) return; + + var shortcuts = FSUtils.find_case_insensitive(config_dir, "shortcuts.vdf") ?? FSUtils.file(config_dir.get_path(), "shortcuts.vdf"); + + var vdf = new BinaryVDF(shortcuts); + + var root_node = vdf.read() as BinaryVDF.ListNode; + + if(root_node.get("shortcuts") == null) + { + root_node = new BinaryVDF.ListNode.node("shortcuts"); + } + else + { + root_node = root_node.get("shortcuts") as BinaryVDF.ListNode; + } + + var game_node = new BinaryVDF.ListNode.node(root_node.nodes.size.to_string()); + + game_node.add_node(new BinaryVDF.StringNode.node("AppName", game.name)); + game_node.add_node(new BinaryVDF.StringNode.node("exe", ProjectConfig.PROJECT_NAME)); + game_node.add_node(new BinaryVDF.StringNode.node("LaunchOptions", "--run " + game.full_id)); + game_node.add_node(new BinaryVDF.StringNode.node("ShortcutPath", ProjectConfig.DATADIR + "/applications/" + ProjectConfig.PROJECT_NAME + ".desktop")); + game_node.add_node(new BinaryVDF.StringNode.node("StartDir", ".")); + game_node.add_node(new BinaryVDF.IntNode.node("IsHidden", 0)); + game_node.add_node(new BinaryVDF.IntNode.node("OpenVR", 0)); + game_node.add_node(new BinaryVDF.IntNode.node("AllowOverlay", 1)); + game_node.add_node(new BinaryVDF.IntNode.node("AllowDesktopConfig", 1)); + game_node.add_node(new BinaryVDF.IntNode.node("LastPlayTime", 1)); + + if(game.image != null) + { + var cached = ImageCache.local_file(game.image, @"games/$(game.source.id)/$(game.id)/images/"); + game_node.add_node(new BinaryVDF.StringNode.node("icon", cached.get_path())); + } + + if(game.image_vertical != null) + { + try + { + var cached = ImageCache.local_file(game.image_vertical, @"games/$(game.source.id)/$(game.id)/images/"); + // https://github.com/boppreh/steamgrid/blob/master/games.go#L120 + uint64 id = crc32(0, (ProjectConfig.PROJECT_NAME + game.name).data) | 0x80000000; + var dest = FSUtils.file(get_userdata_dir().get_child("config").get_child("grid").get_path(), id.to_string() + "p.png"); + cached.copy(dest, NONE); + } + catch (Error e) {} + } + + var tags_node = new BinaryVDF.ListNode.node("tags"); + tags_node.add_node(new BinaryVDF.StringNode.node("0", "GameHub")); + + foreach(var tag in game.tags) + { + if(tag.removable) + { + tags_node.add_node(new BinaryVDF.StringNode.node((game.tags.index_of(tag) + 1).to_string(), tag.name)); + } + } + + game_node.add_node(tags_node); + + root_node.add_node(game_node); + + root_node.show(); + + BinaryVDF.write(shortcuts, root_node); + } + + public static bool IsAnyAppRunning = false; } } diff --git a/src/data/sources/steam/SteamGame.vala b/src/data/sources/steam/SteamGame.vala index 8ea62d17..f6de7359 100644 --- a/src/data/sources/steam/SteamGame.vala +++ b/src/data/sources/steam/SteamGame.vala @@ -1,60 +1,420 @@ -using Gtk; +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; + +using GameHub.Data.DB; using GameHub.Utils; namespace GameHub.Data.Sources.Steam { public class SteamGame: Game { - private bool? _is_for_linux = null; private int metadata_tries = 0; - - public SteamGame(Steam src, Json.Object json) - { - this.source = src; - - this.id = json.get_int_member("appid").to_string(); - this.name = json.get_string_member("name"); - - var icon_hash = json.get_string_member("img_icon_url"); - var image_hash = json.get_string_member("img_logo_url"); - - this.icon = @"https://media.steampowered.com/steamcommunity/public/images/apps/$(this.id)/$(icon_hash).jpg"; - this.image = @"https://cdn.akamai.steamstatic.com/steam/apps/$(this.id)/header.jpg"; - - this.command = @"xdg-open steam://rungameid/$(this.id)"; - - this.playtime = ((float) json.get_int_member("playtime_forever")) / 60.0f; - } - - public override async bool is_for_linux() - { - if(_is_for_linux != null) return _is_for_linux; - + + private bool game_info_updating = false; + private bool game_info_updated = false; + + public bool is_updating { get; set; default = false; } + + public File? screenshots_dir { get; protected set; default = null; } + + public SteamGame(Steam src, Json.Node json_node) + { + source = src; + + var json_obj = json_node.get_object(); + + id = json_obj.get_int_member("appid").to_string(); + name = json_obj.get_string_member("name"); + + var icon_hash = json_obj.get_string_member("img_icon_url"); + + icon = @"http://media.steampowered.com/steamcommunity/public/images/apps/$(id)/$(icon_hash).jpg"; + image = @"http://cdn.akamai.steamstatic.com/steam/apps/$(id)/header.jpg"; + image_vertical = @"http://cdn.akamai.steamstatic.com/steam/apps/$(id)/library_600x900_2x.jpg"; + + info = Json.to_string(json_node, false); + + store_page = @"steam://store/$(id)"; + + update_status(); + } + + public SteamGame.from_db(Steam src, Sqlite.Statement s) + { + source = src; + id = Tables.Games.ID.get(s); + name = Tables.Games.NAME.get(s); + info = Tables.Games.INFO.get(s); + info_detailed = Tables.Games.INFO_DETAILED.get(s); + info = Tables.Games.INFO.get(s); + info_detailed = Tables.Games.INFO_DETAILED.get(s); + compat_tool = Tables.Games.COMPAT_TOOL.get(s); + compat_tool_settings = Tables.Games.COMPAT_TOOL_SETTINGS.get(s); + arguments = Tables.Games.ARGUMENTS.get(s); + last_launch = Tables.Games.LAST_LAUNCH.get_int64(s); + playtime_source = Tables.Games.PLAYTIME_SOURCE.get_int64(s); + playtime_tracked = Tables.Games.PLAYTIME_TRACKED.get_int64(s); + + icon = Tables.Games.ICON.get(s); + image = Tables.Games.IMAGE.get(s); + image_vertical = Tables.Games.IMAGE_VERTICAL.get(s); + + if(image == null || image == "") + { + image = @"http://cdn.akamai.steamstatic.com/steam/apps/$(id)/header.jpg"; + } + + if(image_vertical == null || image_vertical == "") + { + image_vertical = @"http://cdn.akamai.steamstatic.com/steam/apps/$(id)/library_600x900_2x.jpg"; + } + + platforms.clear(); + var pls = Tables.Games.PLATFORMS.get(s).split(","); + foreach(var pl in pls) + { + foreach(var p in Platform.PLATFORMS) + { + if(pl == p.id()) + { + platforms.add(p); + break; + } + } + } + + tags.clear(); + var tag_ids = (Tables.Games.TAGS.get(s) ?? "").split(","); + foreach(var tid in tag_ids) + { + foreach(var t in Tables.Tags.TAGS) + { + if(tid == t.id) + { + if(!tags.contains(t)) tags.add(t); + break; + } + } + } + + store_page = @"steam://store/$(id)"; + + update_status(); + } + + public override async void update_game_info() + { + if(game_info_updating) return; + game_info_updating = true; + + update_status(); + + if((info != null && info.length > 0)) + { + var i = Parser.parse_json(info).get_object(); + if((icon == null || icon == "")) + { + var icon_hash = i.get_string_member("img_icon_url"); + icon = @"http://media.steampowered.com/steamcommunity/public/images/apps/$(id)/$(icon_hash).jpg"; + } + if(playtime_source == 0) + { + playtime_source = i.get_int_member("playtime_forever"); + } + } + + File? dir; + Steam.find_app_install_dir(id, out dir); + install_dir = dir; + work_dir = dir; + + var appinfo = Steam.get_appinfo(id); + if(appinfo != null) + { + //appinfo.show(); + } + + screenshots_dir = FSUtils.find_case_insensitive(Steam.get_userdata_dir(), @"760/remote/$(id)/screenshots"); + + if(game_info_updated) + { + game_info_updating = false; + return; + } + + if(info_detailed == null || info_detailed.length == 0) + { + if(GameHub.Application.log_verbose) + { + debug("[SteamGame] %s: no cached app data for '%s', fetching...", id, name); + } + var lang = Utils.get_language_name().down(); + var url = @"https://store.steampowered.com/api/appdetails?appids=$(id)" + (lang != null && lang.length > 0 ? "&l=" + lang : ""); + info_detailed = (yield Parser.load_remote_file_async(url)); + } + + var root = Parser.parse_json(info_detailed); + + var app = Parser.json_object(root, {id}); + + if(app == null) + { + if(GameHub.Application.log_verbose) + { + debug("[SteamGame] %s: no app data for '%s', store page does not exist", id, name); + } + game_info_updated = true; + game_info_updating = false; + return; + } + + var data = Parser.json_object(root, {id, "data"}); + + if(data == null) + { + bool success = app.has_member("success") && app.get_boolean_member("success"); + if(GameHub.Application.log_verbose) + { + debug("[SteamGame] %s: no app data for '%s', success: %s, store page does not exist", id, name, success.to_string()); + } + if(metadata_tries > 0) + { + game_info_updated = true; + game_info_updating = false; + return; + } + } + + description = data != null && data.has_member("detailed_description") ? data.get_string_member("detailed_description") : ""; + metadata_tries++; - - print("[Steam app %s] Checking for linux compatibility [%d]...\n", this.id, metadata_tries); - - var url = @"https://store.steampowered.com/api/appdetails?appids=$(this.id)"; - var root = yield Parser.parse_remote_json_file_async(url); - var platforms = Parser.json_object(root, {this.id, "data", "platforms"}); - - if(platforms == null) - { - if(metadata_tries > 2) - { - print("[Steam app %s] No data, %d tries failed, assuming no linux support\n", this.id, metadata_tries); - _is_for_linux = false; - return _is_for_linux; - } - - print("[Steam app %s] No data, sleeping for 2.5s\n", this.id); - yield Utils.sleep_async(2500); - return yield is_for_linux(); - } - - _is_for_linux = platforms.get_boolean_member("linux"); - - return _is_for_linux; + + var platforms_json = Parser.json_object(root, {id, "data", "platforms"}); + + platforms.clear(); + if(platforms_json == null) + { + if(GameHub.Application.log_verbose) + { + debug("[SteamGame] %s: No platform support data, %d tries failed, assuming Windows support", id, metadata_tries); + } + platforms.add(Platform.WINDOWS); + save(); + game_info_updated = true; + game_info_updating = false; + return; + } + + foreach(var p in Platform.PLATFORMS) + { + if(platforms_json.has_member(p.id()) && platforms_json.get_boolean_member(p.id())) + { + platforms.add(p); + } + } + + save(); + + update_status(); + + game_info_updated = true; + game_info_updating = false; + } + + public override void update_status() + { + var state = Game.State.UNINSTALLED; + if(is_updating) + { + state = Game.State.INSTALLING; + } + else if(Steam.is_app_installed(id)) + { + state = Game.State.INSTALLED; + remove_tag(Tables.Tags.BUILTIN_UNINSTALLED); + add_tag(Tables.Tags.BUILTIN_INSTALLED); + } + else + { + add_tag(Tables.Tags.BUILTIN_UNINSTALLED); + remove_tag(Tables.Tags.BUILTIN_INSTALLED); + } + status = new Game.Status(state, this); + } + + public override async void install(Runnable.Installer.InstallMode install_mode=Runnable.Installer.InstallMode.INTERACTIVE) + { + Steam.install_app(id); + update_status(); + } + + public override async void run() + { + if(!can_be_launched(true)) return; + last_launch = get_real_time() / 1000000; + save(); + Utils.open_uri(@"steam://rungameid/$(id)"); + update_status(); + } + + public override async void run_with_compat(bool is_opened_from_menu=false) + { + yield run(); + } + + public override async void uninstall() + { + Utils.open_uri(@"steam://uninstall/$(id)"); + update_status(); + } + + private bool loading_achievements = false; + public override async ArrayList? load_achievements() + { + if(achievements != null || loading_achievements) + { + return achievements; + } + + loading_achievements = true; + + var lang = Utils.get_language_name().down(); + lang = (lang != null && lang.length > 0 ? "&l=" + lang : ""); + + var schema_url = @"https://api.steampowered.com/ISteamUserStats/GetSchemaForGame/v2/?key=$(Steam.instance.api_key)&format=json&appid=$(id)$(lang)"; + var achievements_url = @"https://api.steampowered.com/ISteamUserStats/GetPlayerAchievements/v1/?key=$(Steam.instance.api_key)&steamid=$(Steam.instance.user_id)&format=json&appid=$(id)$(lang)"; + var global_percentages_url = @"https://api.steampowered.com/ISteamUserStats/GetGlobalAchievementPercentagesForApp/v2/?key=$(Steam.instance.api_key)&format=json&gameid=$(id)"; + + var schema_root = (yield Parser.parse_remote_json_file_async(schema_url)); + var achievements_root = (yield Parser.parse_remote_json_file_async(achievements_url)); + var global_percentages_root = (yield Parser.parse_remote_json_file_async(global_percentages_url)); + + var schema_achievements_obj = Parser.json_object(schema_root, {"game", "availableGameStats"}); + if(schema_achievements_obj == null || !schema_achievements_obj.has_member("achievements")) + { + loading_achievements = false; + return null; + } + var schema_achievements = schema_achievements_obj.get_array_member("achievements"); + + var achievements_obj = Parser.json_object(achievements_root, {"playerstats"}); + if(achievements_obj == null || !achievements_obj.has_member("achievements")) + { + loading_achievements = false; + return null; + } + var player_achievements = achievements_obj.get_array_member("achievements"); + + var global_percentages_obj = Parser.json_object(global_percentages_root, {"achievementpercentages"}); + if(global_percentages_obj == null || !global_percentages_obj.has_member("achievements")) + { + loading_achievements = false; + return null; + } + var global_percentages = global_percentages_obj.get_array_member("achievements"); + + var _achievements = new ArrayList(); + + foreach(var s_achievement_node in schema_achievements.get_elements()) + { + var s_achievement = s_achievement_node != null && s_achievement_node.get_node_type() == Json.NodeType.OBJECT + ? s_achievement_node.get_object() : null; + + if(s_achievement == null || !s_achievement.has_member("name")) continue; + + var a_id = s_achievement.get_string_member("name"); + var a_name = s_achievement.has_member("displayName") ? s_achievement.get_string_member("displayName") : a_id; + var a_desc = s_achievement.has_member("description") ? s_achievement.get_string_member("description") : ""; + var a_image_unlocked = s_achievement.has_member("icon") ? s_achievement.get_string_member("icon") : null; + var a_image_locked = s_achievement.has_member("icongray") ? s_achievement.get_string_member("icongray") : null; + bool a_unlocked = false; + int64 a_unlock_time = 0; + float a_global_percentage = 0; + + foreach(var p_achievement_node in player_achievements.get_elements()) + { + var p_achievement = p_achievement_node != null && p_achievement_node.get_node_type() == Json.NodeType.OBJECT + ? p_achievement_node.get_object() : null; + + if(p_achievement == null || !p_achievement.has_member("apiname") + || p_achievement.get_string_member("apiname") != a_id) continue; + + a_unlocked = p_achievement.has_member("achieved") && p_achievement.get_int_member("achieved") > 0; + a_unlock_time = p_achievement.has_member("unlocktime") ? p_achievement.get_int_member("unlocktime") : 0; + } + + foreach(var gp_achievement_node in global_percentages.get_elements()) + { + var gp_achievement = gp_achievement_node != null && gp_achievement_node.get_node_type() == Json.NodeType.OBJECT + ? gp_achievement_node.get_object() : null; + + if(gp_achievement == null || !gp_achievement.has_member("name") + || gp_achievement.get_string_member("name") != a_id) continue; + + a_global_percentage = (float) (gp_achievement.has_member("percent") ? gp_achievement.get_double_member("percent") : 0); + } + + _achievements.add(new Achievement(a_id, a_name, a_desc, a_image_locked, a_image_unlocked, + a_unlocked, a_unlock_time, a_global_percentage)); + } + + _achievements.sort((first, second) => { + var a1 = first as Achievement; + var a2 = second as Achievement; + + if(a1.unlock_timestamp > 0 || a2.unlock_timestamp > 0) + { + return (int) (a2.unlock_timestamp - a1.unlock_timestamp); + } + + if(a1.global_percentage < a2.global_percentage) return 1; + if(a1.global_percentage > a2.global_percentage) return -1; + return 0; + }); + + achievements = _achievements; + loading_achievements = false; + return achievements; + } + + public override void import(bool update=true){} + public override void choose_executable(bool update=true){} + + public class Achievement: Game.Achievement + { + public int64 unlock_timestamp; + + public Achievement(string id, string name, string desc, string? image_locked, string? image_unlocked, + bool unlocked, int64 unlock_time, float global_percentage) + { + this.id = id; + this.name = name; + this.description = desc; + this.image_locked = image_locked; + this.image_unlocked = image_unlocked; + this.unlocked = unlocked; + this.global_percentage = global_percentage; + this.unlock_timestamp = unlock_time; + this.unlock_date = new DateTime.from_unix_utc(unlock_time); + this.unlock_time = Utils.get_relative_datetime(this.unlock_date); + } } } } diff --git a/src/data/sources/user/User.vala b/src/data/sources/user/User.vala new file mode 100644 index 00000000..4b112275 --- /dev/null +++ b/src/data/sources/user/User.vala @@ -0,0 +1,133 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; +using GameHub.Data.DB; +using GameHub.Utils; + +namespace GameHub.Data.Sources.User +{ + public class User: GameSource + { + public static User instance; + + public override string id { get { return "user"; } } + public override string name { get { return _("User games"); } } + public override string name_from { owned get { return name; } } + public override string icon { get { return "avatar-default-symbolic"; } } + + public User() + { + instance = this; + } + + public override bool enabled + { + get { return true; } + set {} + } + + public override bool is_installed(bool refresh) + { + return true; + } + + public override async bool install() + { + return true; + } + + public override async bool authenticate() + { + return true; + } + + public override bool is_authenticated() + { + return true; + } + + public override bool can_authenticate_automatically() + { + return true; + } + + private ArrayList _games = new ArrayList(Game.is_equal); + + public override ArrayList games { get { return _games; } } + + public override async ArrayList load_games(Utils.FutureResult2? game_loaded=null, Utils.Future? cache_loaded=null) + { + if(_games.size > 0) + { + return _games; + } + + Utils.thread("UserGamesLoading", () => { + _games.clear(); + + var cached = Tables.Games.get_all(this); + games_count = 0; + if(cached.size > 0) + { + foreach(var g in cached) + { + if(!Settings.UI.Behavior.instance.merge_games || !Tables.Merges.is_game_merged(g)) + { + g.update_game_info.begin(); + _games.add(g); + if(game_loaded != null) + { + /*Idle.add(() => { */game_loaded(g, true); /*return Source.REMOVE; });*/ + } + ((UserGame) g).removed.connect(() => { + _games.remove(g); + }); + } + games_count++; + } + } + + if(cache_loaded != null) + { + cache_loaded(); + } + + Idle.add(load_games.callback); + }); + + yield; + + return _games; + } + + public void add_game(UserGame game) + { + if(_games.contains(game)) return; + _games.add(game); + games_count++; + } + + public void remove_game(UserGame game) + { + _games.remove(game); + games_count--; + Tables.Games.remove(game); + } + } +} diff --git a/src/data/sources/user/UserGame.vala b/src/data/sources/user/UserGame.vala new file mode 100644 index 00000000..7a68d6c2 --- /dev/null +++ b/src/data/sources/user/UserGame.vala @@ -0,0 +1,205 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; +using GameHub.Data.DB; +using GameHub.Utils; + +namespace GameHub.Data.Sources.User +{ + public class UserGame: Game, TweakableGame + { + public string[]? tweaks { get; set; default = null; } + + private bool is_removed = false; + public signal void removed(); + + private Installer? installer; + + public UserGame(string name, File dir, File exec, string args, bool is_installer) + { + source = User.instance; + + this.id = Utils.md5(name + Random.next_int().to_string()); + this.name = name; + + platforms.clear(); + + var path = exec.get_path().down(); + platforms.add(path.has_suffix(".exe") || path.has_suffix(".bat") || path.has_suffix(".com") ? Platform.WINDOWS : Platform.LINUX); + + install_dir = dir; + work_dir = dir; + + arguments = args; + + if(!is_installer) + { + executable = exec; + } + else + { + installer = new Installer(this, exec); + var root_object = new Json.Object(); + root_object.set_string_member("installer", exec.get_path()); + var root_node = new Json.Node(Json.NodeType.OBJECT); + root_node.set_object(root_object); + info = Json.to_string(root_node, false); + save(); + } + + ((User) source).add_game(this); + + mount_overlays.begin(); + update_status(); + } + + public UserGame.from_db(User src, Sqlite.Statement s) + { + source = src; + id = Tables.Games.ID.get(s); + name = Tables.Games.NAME.get(s); + info = Tables.Games.INFO.get(s); + info_detailed = Tables.Games.INFO_DETAILED.get(s); + icon = Tables.Games.ICON.get(s); + image = Tables.Games.IMAGE.get(s); + install_dir = Tables.Games.INSTALL_PATH.get(s) != null ? FSUtils.file(Tables.Games.INSTALL_PATH.get(s)) : null; + executable_path = Tables.Games.EXECUTABLE.get(s); + work_dir_path = Tables.Games.WORK_DIR.get(s); + compat_tool = Tables.Games.COMPAT_TOOL.get(s); + compat_tool_settings = Tables.Games.COMPAT_TOOL_SETTINGS.get(s); + arguments = Tables.Games.ARGUMENTS.get(s); + last_launch = Tables.Games.LAST_LAUNCH.get_int64(s); + playtime_source = Tables.Games.PLAYTIME_SOURCE.get_int64(s); + playtime_tracked = Tables.Games.PLAYTIME_TRACKED.get_int64(s); + image_vertical = Tables.Games.IMAGE_VERTICAL.get(s); + + platforms.clear(); + var pls = Tables.Games.PLATFORMS.get(s).split(","); + foreach(var pl in pls) + { + foreach(var p in Platform.PLATFORMS) + { + if(pl == p.id()) + { + platforms.add(p); + break; + } + } + } + + tags.clear(); + var tag_ids = (Tables.Games.TAGS.get(s) ?? "").split(","); + foreach(var tid in tag_ids) + { + foreach(var t in Tables.Tags.TAGS) + { + if(tid == t.id) + { + if(!tags.contains(t)) tags.add(t); + break; + } + } + } + + var tweaks_string = Tables.Games.TWEAKS.get(s); + if(tweaks_string != null) + { + tweaks = tweaks_string.split(","); + } + + mount_overlays.begin(); + update_status(); + } + + public override async void update_game_info() + { + yield mount_overlays(); + update_status(); + + if(installer == null && info != null && info.length > 0) + { + var i = Parser.parse_json(info).get_object(); + installer = new Installer(this, File.new_for_path(i.get_string_member("installer"))); + } + + save(); + } + + public override async void install(Runnable.Installer.InstallMode install_mode=Runnable.Installer.InstallMode.INTERACTIVE) + { + yield update_game_info(); + if(installer == null) return; + var installers = new ArrayList(); + installers.add(installer); + new GameHub.UI.Dialogs.InstallDialog(this, installers, install_mode, install.callback); + yield; + } + + public override async void uninstall() + { + yield umount_overlays(); + remove(); + } + + public void remove() + { + is_removed = true; + ((User) source).remove_game(this); + removed(); + } + + public override void save() + { + if(!is_removed) + { + base.save(); + } + } + + public override void update_status() + { + var exec = executable; + status = new Game.Status(exec != null && exec.query_exists() ? Game.State.INSTALLED : Game.State.UNINSTALLED, this); + if(status.state == Game.State.INSTALLED) + { + remove_tag(Tables.Tags.BUILTIN_UNINSTALLED); + add_tag(Tables.Tags.BUILTIN_INSTALLED); + } + else + { + add_tag(Tables.Tags.BUILTIN_UNINSTALLED); + remove_tag(Tables.Tags.BUILTIN_INSTALLED); + } + } + + public class Installer: Runnable.FileInstaller + { + private string game_name; + public override string name { owned get { return game_name; } } + + public Installer(UserGame game, File installer) + { + game_name = game.name; + id = "installer"; + platform = installer.get_path().down().has_suffix(".exe") ? Platform.WINDOWS : Platform.LINUX; + file = installer; + } + } + } +} diff --git a/src/data/tweaks/Tweak.vala b/src/data/tweaks/Tweak.vala new file mode 100644 index 00000000..a417194c --- /dev/null +++ b/src/data/tweaks/Tweak.vala @@ -0,0 +1,446 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gee; + +using GameHub.Utils; + +namespace GameHub.Data.Tweaks +{ + public class Tweak: Object + { + public string id { get; protected set; } + public string? name { get; protected set; default = null; } + public string? description { get; protected set; default = null; } + public string? url { get; protected set; default = null; } + + public ApplicabilityOptions? applicability_options { get; protected set; default = null; } + + public HashMap? env { get; protected set; default = null; } + public string? command { get; protected set; default = null; } + public File? file { get; protected set; default = null; } + + public Tweak(string id, string? name, string? description, string? url, ApplicabilityOptions? applicability_options, HashMap? env, string? command, File? file) + { + Object(id: id, name: name, description: description, url: url, applicability_options: applicability_options, env: env, command: command, file: file); + } + + public Tweak.from_json_object(Json.Object obj, File? file, string? default_id=null) + { + string id = default_id ?? "tweak"; + string? name = null; + string? description = null; + string? url = null; + ApplicabilityOptions? applicability_options = null; + HashMap? env = null; + string? command = null; + + if(obj.has_member("id")) id = obj.get_string_member("id"); + if(obj.has_member("name")) name = obj.get_string_member("name"); + if(obj.has_member("description")) description = obj.get_string_member("description"); + if(obj.has_member("url")) url = obj.get_string_member("url"); + + if(obj.has_member("applicable_to")) + applicability_options = new ApplicabilityOptions.from_json(obj.get_member("applicable_to")); + + if(obj.has_member("env")) + { + env = new HashMap(); + var env_object = obj.get_object_member("env"); + foreach(var env_var in env_object.get_members()) + { + var env_value = env_object.get_member(env_var); + if(env_value.get_node_type() == Json.NodeType.VALUE) + { + env.set(env_var, env_value.get_string()); + } + else + { + env.set(env_var, null); + } + } + } + + if(obj.has_member("command")) command = obj.get_string_member("command"); + + Object(id: id, name: name, description: description, url: url, applicability_options: applicability_options, env: env, command: command, file: file); + } + + public static ArrayList load_from_file(File file) + { + var loaded_tweaks = new ArrayList(); + string id = file.get_basename().replace(".json", ""); + + var node = Parser.parse_json_file(file.get_path()); + switch(node.get_node_type()) + { + case Json.NodeType.OBJECT: + loaded_tweaks.add(new Tweak.from_json_object(node.get_object(), file, id)); + break; + + case Json.NodeType.ARRAY: + int i = 0; + foreach(var tweak_node in node.get_array().get_elements()) + { + if(tweak_node.get_node_type() == Json.NodeType.OBJECT) + { + loaded_tweaks.add(new Tweak.from_json_object(tweak_node.get_object(), file, @"$(id)[$(i++)]")); + } + } + break; + } + + return loaded_tweaks; + } + + public bool is_applicable_to(TweakableGame game, CompatTool? compat_tool=null) + { + if(applicability_options == null) return true; + return applicability_options.is_applicable_to(game, compat_tool); + } + + public bool is_enabled(TweakableGame? game=null) + { + if(game == null || game.tweaks == null) + { + return id in Settings.Tweaks.instance.global; + } + else + { + return id in game.tweaks; + } + } + + public void set_enabled(bool enabled, TweakableGame? game=null) + { + if(game == null) + { + var global = Settings.Tweaks.instance.global; + if(!enabled && id in global) + { + string[] new_global = {}; + foreach(var t in global) + { + if(t != id) new_global += t; + } + Settings.Tweaks.instance.global = new_global; + } + else if(enabled && !(id in global)) + { + global += id; + Settings.Tweaks.instance.global = global; + } + } + else + { + var game_tweaks = game.tweaks ?? Settings.Tweaks.instance.global; + if(!enabled && id in game_tweaks) + { + string[] new_game_tweaks = {}; + foreach(var t in game_tweaks) + { + if(t != id) new_game_tweaks += t; + } + game.tweaks = new_game_tweaks; + game.save(); + } + else if(enabled && !(id in game_tweaks)) + { + game_tweaks += id; + game.tweaks = game_tweaks; + game.save(); + } + } + } + + public string icon + { + owned get + { + var icon = "system-run-symbolic"; + if(applicability_options != null) + { + if(applicability_options.platforms != null && applicability_options.platforms.size > 0) + { + icon = applicability_options.platforms.first().icon(); + } + + if(applicability_options.compat_tool_ids != null && applicability_options.compat_tool_ids.size > 0) + { + var tool_id = applicability_options.compat_tool_ids.first(); + foreach(var tool in CompatTools) + { + if(tool.id == tool_id || tool.id.has_prefix(@"$(tool_id)_")) + { + icon = tool.icon; + break; + } + } + } + } + return icon; + } + } + + private static HashMap? tweaks = null; + public static HashMap load_tweaks(bool refresh=false) + { + if(tweaks != null && tweaks.size > 0 && !refresh) + { + return tweaks; + } + + tweaks = new HashMap(); + + foreach(var data_dir in FSUtils.get_data_dirs("tweaks")) + { + if(GameHub.Application.log_verbose) + { + debug("[Tweak.load_tweaks] Directory: '%s'", data_dir.get_path()); + } + + try + { + FileInfo? finfo = null; + var enumerator = data_dir.enumerate_children("standard::*", FileQueryInfoFlags.NOFOLLOW_SYMLINKS); + while((finfo = enumerator.next_file()) != null) + { + var fname = finfo.get_name(); + if(fname.down().has_suffix(".json")) + { + var file = data_dir.get_child(fname); + var loaded_tweaks = load_from_file(file); + + if(GameHub.Application.log_verbose) + { + debug("[Tweak.load_tweaks] File: '%s'; %d tweak(s):", file.get_path(), loaded_tweaks.size); + } + + foreach(var tweak in loaded_tweaks) + { + tweaks.set(tweak.id, tweak); + + if(GameHub.Application.log_verbose) + { + debug("[Tweak.load_tweaks] %s", Json.to_string(new Json.Node(Json.NodeType.OBJECT).init_object(tweak.to_json()), false)); + } + } + } + } + } + catch(Error e) + { + warning("[Tweak.load_tweaks] %s", e.message); + } + } + + return tweaks; + } + + public Json.Object to_json() + { + var obj = new Json.Object(); + + obj.set_string_member("id", id); + if(name != null) obj.set_string_member("name", name); + if(description != null) obj.set_string_member("description", description); + if(url != null) obj.set_string_member("url", url); + + if(applicability_options != null) + { + var options = applicability_options.to_json(); + if(options != null) obj.set_member("applicable_to", options); + } + + if(env != null && env.size > 0) + { + var env_obj = new Json.Object(); + foreach(var env_var in env.entries) + { + if(env_var.value != null) + { + env_obj.set_string_member(env_var.key, env_var.value); + } + else + { + env_obj.set_null_member(env_var.key); + } + } + obj.set_object_member("env", env_obj); + } + + if(command != null) obj.set_string_member("command", command); + + return obj; + } + + public class ApplicabilityOptions: Object + { + public ArrayList? platforms { get; protected set; default = null; } + public ArrayList? compat_tool_ids { get; protected set; default = null; } + + public ApplicabilityOptions(ArrayList? platforms, ArrayList? compat_tool_ids) + { + Object(platforms: platforms, compat_tool_ids: compat_tool_ids); + } + + public ApplicabilityOptions.from_json(Json.Node? json) + { + ArrayList? platforms = null; + ArrayList? compat_tool_ids = null; + + if(json != null && json.get_node_type() == Json.NodeType.OBJECT) + { + var obj = json.get_object(); + + if(obj.has_member("platforms")) + { + var platforms_array = obj.get_array_member("platforms"); + if(platforms_array.get_length() > 0) + { + platforms = new ArrayList(); + foreach(var platform_node in platforms_array.get_elements()) + { + if(platform_node.get_node_type() == Json.NodeType.VALUE) + { + var platform_id = platform_node.get_string(); + if(platform_id != null) + { + foreach(var p in Platform.PLATFORMS) + { + if(platform_id == p.id() && !(p in platforms)) + { + platforms.add(p); + break; + } + } + } + } + } + } + } + + if(obj.has_member("compat")) + { + var tools_array = obj.get_array_member("compat"); + if(tools_array.get_length() > 0) + { + compat_tool_ids = new ArrayList(); + foreach(var tool_node in tools_array.get_elements()) + { + if(tool_node.get_node_type() == Json.NodeType.VALUE) + { + var tool_id = tool_node.get_string(); + if(tool_id != null && !(tool_id in compat_tool_ids)) + { + compat_tool_ids.add(tool_id); + } + } + } + } + } + } + + Object(platforms: platforms, compat_tool_ids: compat_tool_ids); + } + + public bool is_applicable_to(TweakableGame game, CompatTool? compat_tool=null) + { + if(platforms != null) + { + var has_platform = false; + foreach(var platform in platforms) + { + if(platform in game.platforms) + { + has_platform = true; + break; + } + } + if(!has_platform) return false; + } + + string? compat_tool_id = null; + if(compat_tool != null) + { + compat_tool_id = compat_tool.id; + } + else + { + if(game.use_compat) + { + compat_tool_id = game.compat_tool; + } + } + + if(compat_tool_ids != null) + { + var has_tool = false; + if(compat_tool_id != null) + { + foreach(var id in compat_tool_ids) + { + if(compat_tool_id == id || compat_tool_id.has_prefix(@"$(id)_")) + { + has_tool = true; + break; + } + } + } + if(!has_tool) return false; + } + + return true; + } + + public Json.Node? to_json() + { + if((platforms == null || platforms.size == 0) && (compat_tool_ids == null || compat_tool_ids.size == 0)) + { + return null; + } + + var node = new Json.Node(Json.NodeType.OBJECT); + var obj = new Json.Object(); + + if(platforms != null && platforms.size > 0) + { + var platforms_array = new Json.Array.sized(platforms.size); + foreach(var platform in platforms) + { + platforms_array.add_string_element(platform.id()); + } + obj.set_array_member("platforms", platforms_array); + } + + if(compat_tool_ids != null && compat_tool_ids.size > 0) + { + var tools_array = new Json.Array.sized(compat_tool_ids.size); + foreach(var tool_id in compat_tool_ids) + { + tools_array.add_string_element(tool_id); + } + obj.set_array_member("compat", tools_array); + } + + node.set_object(obj); + return node; + } + } + } +} diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 00000000..2acdeac9 --- /dev/null +++ b/src/meson.build @@ -0,0 +1,278 @@ +project_config = vcs_tag( + input: vcs_tag( + input: vcs_tag( + input: configure_file( + input: 'ProjectConfig.vala.in', + output: 'ProjectConfig.vala.in.in.in', + configuration: conf_data + ), + output: 'ProjectConfig.vala.in.in', + command: ['git', 'rev-parse', '--short', 'HEAD'], + replace_string: '@GIT_COMMIT_SHORT@', + fallback: '' + ), + output: 'ProjectConfig.vala.in', + command: ['git', 'rev-parse', 'HEAD'], + replace_string: '@GIT_COMMIT@', + fallback: '' + ), + output: 'ProjectConfig.vala', + command: ['git', 'symbolic-ref', '--short', '-q', 'HEAD'], + replace_string: '@GIT_BRANCH@', + fallback: '' +) + +deps = [ + dependency('gdk-3.0'), + dependency('json-glib-1.0'), + dependency('gee-0.8'), + dependency('sqlite3'), + dependency('libxml-2.0'), + dependency('gio-unix-2.0'), + dependency('zlib'), + meson.get_compiler('vala').find_library('posix'), + meson.get_compiler('vala').find_library('linux') +] + +sources = [ + 'app.vala', + + 'data/Runnable.vala', + 'data/Game.vala', + 'data/GameSource.vala', + 'data/Emulator.vala', + + 'data/sources/steam/Steam.vala', + 'data/sources/steam/SteamGame.vala', + + 'data/sources/gog/GOG.vala', + 'data/sources/gog/GOGGame.vala', + + 'data/sources/humble/Humble.vala', + 'data/sources/humble/HumbleGame.vala', + 'data/sources/humble/Trove.vala', + + 'data/sources/itch/Itch.vala', + 'data/sources/itch/ItchGame.vala', + 'data/sources/itch/ItchDownloader.vala', + 'data/sources/itch/ButlerDaemon.vala', + 'data/sources/itch/ButlerConnection.vala', + 'data/sources/itch/ButlerClient.vala', + + 'data/sources/user/User.vala', + 'data/sources/user/UserGame.vala', + + 'data/db/Database.vala', + 'data/db/Table.vala', + 'data/db/tables/Games.vala', + 'data/db/tables/Tags.vala', + 'data/db/tables/Merges.vala', + 'data/db/tables/Emulators.vala', + 'data/db/tables/IGDBData.vala', + + 'data/CompatTool.vala', + 'data/compat/CustomScript.vala', + 'data/compat/Innoextract.vala', + 'data/compat/WineWrap.vala', + 'data/compat/Proton.vala', + 'data/compat/Wine.vala', + 'data/compat/DOSBox.vala', + 'data/compat/ScummVM.vala', + 'data/compat/RetroArch.vala', + 'data/compat/CustomEmulator.vala', + + 'data/adapters/GamesAdapter.vala', + + 'data/providers/Provider.vala', + 'data/providers/ImagesProvider.vala', + 'data/providers/DataProvider.vala', + 'data/providers/images/Steam.vala', + 'data/providers/images/SteamGridDB.vala', + 'data/providers/images/JinxSGVI.vala', + 'data/providers/data/IGDB.vala', + + 'data/tweaks/Tweak.vala', + + 'ui/windows/MainWindow.vala', + 'ui/windows/WebAuthWindow.vala', + + 'ui/dialogs/SettingsDialog/SettingsDialog.vala', + 'ui/dialogs/SettingsDialog/SettingsDialogPage.vala', + + 'ui/dialogs/SettingsDialog/pages/ui/Appearance.vala', + 'ui/dialogs/SettingsDialog/pages/ui/Behavior.vala', + 'ui/dialogs/SettingsDialog/pages/general/Collection.vala', + 'ui/dialogs/SettingsDialog/pages/general/Tweaks.vala', + 'ui/dialogs/SettingsDialog/pages/sources/Steam.vala', + 'ui/dialogs/SettingsDialog/pages/sources/GOG.vala', + 'ui/dialogs/SettingsDialog/pages/sources/Humble.vala', + 'ui/dialogs/SettingsDialog/pages/sources/Itch.vala', + 'ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala', + 'ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala', + 'ui/dialogs/SettingsDialog/pages/providers/Providers.vala', + 'ui/dialogs/SettingsDialog/pages/About.vala', + + 'ui/dialogs/InstallDialog.vala', + + 'ui/dialogs/GameDetailsDialog.vala', + 'ui/dialogs/GamePropertiesDialog.vala', + 'ui/dialogs/GameFSOverlaysDialog.vala', + 'ui/dialogs/CompatRunDialog.vala', + 'ui/dialogs/CorruptedInstallerDialog.vala', + 'ui/dialogs/ImportEmulatedGamesDialog.vala', + 'ui/dialogs/GameTweaksDialog.vala', + + 'ui/views/BaseView.vala', + 'ui/views/WelcomeView.vala', + + 'ui/views/GamesView/GamesView.vala', + + 'ui/views/GamesView/grid/GamesGrid.vala', + 'ui/views/GamesView/grid/GameCard.vala', + + 'ui/views/GamesView/list/GamesList.vala', + 'ui/views/GamesView/list/GameListRow.vala', + + 'ui/views/GamesView/DownloadProgressView.vala', + 'ui/views/GamesView/FiltersPopover.vala', + 'ui/views/GamesView/AddGamePopover.vala', + 'ui/views/GamesView/GameContextMenu.vala', + + 'ui/views/GameDetailsView/GameDetailsView.vala', + 'ui/views/GameDetailsView/MultipleGamesDetailsView.vala', + 'ui/views/GameDetailsView/GameDetailsPage.vala', + + 'ui/views/GameDetailsView/GameDetailsBlock.vala', + 'ui/views/GameDetailsView/blocks/Artwork.vala', + 'ui/views/GameDetailsView/blocks/Playtime.vala', + 'ui/views/GameDetailsView/blocks/Achievements.vala', + 'ui/views/GameDetailsView/blocks/Description.vala', + 'ui/views/GameDetailsView/blocks/GOGDetails.vala', + 'ui/views/GameDetailsView/blocks/SteamDetails.vala', + 'ui/views/GameDetailsView/blocks/IGDBInfo.vala', + + 'ui/widgets/AutoSizeImage.vala', + 'ui/widgets/ActionButton.vala', + 'ui/widgets/FileChooserEntry.vala', + 'ui/widgets/ExtendedStackSwitcher.vala', + 'ui/widgets/ImagesDownloadPopover.vala', + 'ui/widgets/CompatToolOptions.vala', + 'ui/widgets/CompatToolPicker.vala', + 'ui/widgets/GameTagsList.vala', + 'ui/widgets/TagRow.vala', + 'ui/widgets/Styles.vala', + 'ui/widgets/AlertView.vala', + 'ui/widgets/ModeButton.vala', + 'ui/widgets/OverlayBar.vala', + 'ui/widgets/Welcome.vala', + 'ui/widgets/SettingsSidebar.vala', + 'ui/widgets/TweaksList.vala', + + 'utils/Utils.vala', + 'utils/ImageCache.vala', + 'utils/FSUtils.vala', + 'utils/FSOverlay.vala', + 'utils/Parser.vala', + 'utils/BinaryVDF.vala', + 'utils/SignalRateLimiter.vala', + + 'settings/Settings.vala', + 'settings/UI.vala', + 'settings/SavedState.vala', + 'settings/Auth.vala', + 'settings/Compat.vala', + 'settings/Providers.vala', + 'settings/Controller.vala', + 'settings/Tweaks.vala', + + 'utils/downloader/Downloader.vala', + 'utils/downloader/SoupDownloader.vala' +] + +if get_option('os') == 'linux' + add_global_arguments('-D', 'OS_LINUX', language: 'vala') +elif get_option('os') == 'windows' + add_global_arguments('-D', 'OS_WINDOWS', language: 'vala') + deps += meson.get_compiler('c').find_library('ntdll') +elif get_option('os') == 'macos' + add_global_arguments('-D', 'OS_MACOS', language: 'vala') +endif + +glib262 = dependency('glib-2.0', version: '>=2.62', required: false) +if glib262.found() + add_global_arguments('-D', 'GLIB_2_62', '-D', 'GLIB_2_56', language: 'vala') + deps += glib262 +else + glib256 = dependency('glib-2.0', version: '>=2.56', required: false) + if glib256.found() + add_global_arguments('-D', 'GLIB_2_56', language: 'vala') + deps += glib256 + else + deps += dependency('glib-2.0') + endif +endif + +gtk322 = dependency('gtk+-3.0', version: '>=3.22', required: false) +if gtk322.found() + add_global_arguments('-D', 'GTK_3_22', language: 'vala') + deps += gtk322 +else + deps += dependency('gtk+-3.0') +endif + +# not sure which version fixed Message.response_headers.get_content_range(), 2.60+ should work +soup260 = dependency('libsoup-2.4', version: '>=2.60', required: false) +if soup260.found() + add_global_arguments('-D', 'SOUP_2_60', language: 'vala') + deps += soup260 +else + deps += dependency('libsoup-2.4') +endif + +webkit2gtk = dependency('webkit2gtk-4.0', required: false) +if webkit2gtk.found() + add_global_arguments('-D', 'WEBKIT2GTK', language: 'vala') + deps += webkit2gtk +endif + +if get_option('os') == 'linux' and get_option('feature_overlayfs') + add_global_arguments('-D', 'OVERLAYFS', language: 'vala') + polkit = dependency('polkit-gobject-1', required: false) + if polkit.found() + add_global_arguments('-D', 'POLKIT', language: 'vala') + deps += polkit + endif +endif + +if get_option('use_libunity') + unity = dependency('unity', required: false) + if unity.found() + add_global_arguments('-D', 'UNITY', language: 'vala') + deps += unity + endif +endif + +manette = dependency('manette-0.2', required: false) +if manette.found() + add_global_arguments('-D', 'MANETTE', language: 'vala') + deps += manette + deps += dependency('x11') + deps += dependency('gdk-x11-3.0') + deps += dependency('xtst') + sources += 'utils/Gamepad.vala' + sources += 'ui/dialogs/SettingsDialog/pages/general/Controller.vala' +endif + +executable( + meson.project_name(), + project_config, + + sources, + + icons_gresource, + css_gresource, + + dependencies: deps, + install: true, + gui_app: true +) diff --git a/src/settings/Auth.vala b/src/settings/Auth.vala new file mode 100644 index 00000000..fa0b91cf --- /dev/null +++ b/src/settings/Auth.vala @@ -0,0 +1,136 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +namespace GameHub.Settings.Auth +{ + public class Steam: SettingsSchema + { + public bool enabled { get; set; } + public bool authenticated { get; set; } + public string api_key { get; set; } + + public Steam() + { + base(ProjectConfig.PROJECT_NAME + ".auth.steam"); + } + + protected override void verify(string key) + { + switch(key) + { + case "api-key": + if(api_key.length != 32) + { + schema.reset("api-key"); + } + break; + } + } + + private static Steam? _instance; + public static unowned Steam instance + { + get + { + if(_instance == null) + { + _instance = new Steam(); + } + return _instance; + } + } + } + + public class GOG: SettingsSchema + { + public bool enabled { get; set; } + public bool authenticated { get; set; } + public string access_token { get; set; } + public string refresh_token { get; set; } + + public GOG() + { + base(ProjectConfig.PROJECT_NAME + ".auth.gog"); + } + + private static GOG? _instance; + public static unowned GOG instance + { + get + { + if(_instance == null) + { + _instance = new GOG(); + } + return _instance; + } + } + } + + public class Humble: SettingsSchema + { + public bool enabled { get; set; } + public bool authenticated { get; set; } + public string access_token { get; set; } + + public bool load_trove_games { get; set; } + + public Humble() + { + base(ProjectConfig.PROJECT_NAME + ".auth.humble"); + } + + private static Humble? _instance; + public static unowned Humble instance + { + get + { + if(_instance == null) + { + _instance = new Humble(); + } + return _instance; + } + } + } + + public class Itch: SettingsSchema + { + public bool enabled { get; set; } + public bool authenticated { get; set; } + public string api_key { get; set; } + + public Itch() + { + base(ProjectConfig.PROJECT_NAME + ".auth.itch"); + } + + private static Itch? _instance; + public static unowned Itch instance + { + get + { + if(_instance == null) + { + _instance = new Itch(); + } + return _instance; + } + } + } +} diff --git a/src/settings/Compat.vala b/src/settings/Compat.vala new file mode 100644 index 00000000..1e0d78db --- /dev/null +++ b/src/settings/Compat.vala @@ -0,0 +1,49 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + + + +namespace GameHub.Settings.Compat +{ + public class RetroArch: SettingsSchema + { + public string core_dir { get; set; } + public string core_info_dir { get; set; } + + public string cores_blacklist { get; set; } + public string game_executable_extensions_blacklist { get; set; } + + public RetroArch() + { + base(ProjectConfig.PROJECT_NAME + ".compat.retroarch"); + } + + private static RetroArch? _instance; + public static unowned RetroArch instance + { + get + { + if(_instance == null) + { + _instance = new RetroArch(); + } + return _instance; + } + } + } +} diff --git a/src/settings/Controller.vala b/src/settings/Controller.vala new file mode 100644 index 00000000..5a9c92e6 --- /dev/null +++ b/src/settings/Controller.vala @@ -0,0 +1,49 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + + + +namespace GameHub.Settings +{ + public class Controller: SettingsSchema + { + public bool enabled { get; set; } + public bool focus_window { get; set; } + + public string[] known_controllers { get; set; } + public string[] ignored_controllers { get; set; } + + public Controller() + { + base(ProjectConfig.PROJECT_NAME + ".controller"); + } + + private static Controller? _instance; + public static unowned Controller instance + { + get + { + if(_instance == null) + { + _instance = new Controller(); + } + return _instance; + } + } + } +} diff --git a/src/settings/Providers.vala b/src/settings/Providers.vala new file mode 100644 index 00000000..76d05f92 --- /dev/null +++ b/src/settings/Providers.vala @@ -0,0 +1,154 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + + + +namespace GameHub.Settings.Providers +{ + namespace Images + { + public class SteamGridDB: SettingsSchema + { + public bool enabled { get; set; } + public string api_key { get; set; } + + public SteamGridDB() + { + base(ProjectConfig.PROJECT_NAME + ".providers.images.steamgriddb"); + } + + protected override void verify(string key) + { + switch(key) + { + case "api-key": + if(api_key.length != 32) + { + schema.reset("api-key"); + } + break; + } + } + + private static SteamGridDB? _instance; + public static unowned SteamGridDB instance + { + get + { + if(_instance == null) + { + _instance = new SteamGridDB(); + } + return _instance; + } + } + } + + public class JinxSGVI: SettingsSchema + { + public bool enabled { get; set; } + + public JinxSGVI() + { + base(ProjectConfig.PROJECT_NAME + ".providers.images.jinx-sgvi"); + } + + private static JinxSGVI? _instance; + public static unowned JinxSGVI instance + { + get + { + if(_instance == null) + { + _instance = new JinxSGVI(); + } + return _instance; + } + } + } + + public class Steam: SettingsSchema + { + public bool enabled { get; set; } + + public Steam() + { + base(ProjectConfig.PROJECT_NAME + ".providers.images.steam"); + } + + private static Steam? _instance; + public static unowned Steam instance + { + get + { + if(_instance == null) + { + _instance = new Steam(); + } + return _instance; + } + } + } + } + + namespace Data + { + public class IGDB: SettingsSchema + { + public bool enabled { get; set; } + public string api_key { get; set; } + public PreferredDescription preferred_description { get; set; } + + public IGDB() + { + base(ProjectConfig.PROJECT_NAME + ".providers.data.igdb"); + } + + protected override void verify(string key) + { + switch(key) + { + case "api-key": + if(api_key.length != 32) + { + schema.reset("api-key"); + } + break; + } + } + + private static IGDB? _instance; + public static unowned IGDB instance + { + get + { + if(_instance == null) + { + _instance = new IGDB(); + } + return _instance; + } + } + + public enum PreferredDescription + { + GAME = 0, IGDB = 1, BOTH = 2 + } + } + } +} diff --git a/src/settings/SavedState.vala b/src/settings/SavedState.vala new file mode 100644 index 00000000..0d80f2ae --- /dev/null +++ b/src/settings/SavedState.vala @@ -0,0 +1,86 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using GameHub.Data.Adapters; + +namespace GameHub.Settings.SavedState +{ + public class Window: SettingsSchema + { + public int width { get; set; } + public int height { get; set; } + public Window.State state { get; set; } + public int x { get; set; } + public int y { get; set; } + + public Window() + { + base(ProjectConfig.PROJECT_NAME + ".saved-state.window"); + } + + private static Window? _instance; + public static unowned Window instance + { + get + { + if(_instance == null) + { + _instance = new Window(); + } + return _instance; + } + } + + public enum State + { + NORMAL = 0, MAXIMIZED = 1, FULLSCREEN = 2 + } + } + + public class GamesView: SettingsSchema + { + public GamesView.Style style { get; set; } + public GamesAdapter.SortMode sort_mode { get; set; } + public GamesAdapter.GroupMode group_mode { get; set; } + public string filter_source { get; set; } + public GamesAdapter.PlatformFilter filter_platform { get; set; } + + public GamesView() + { + base(ProjectConfig.PROJECT_NAME + ".saved-state.games-view"); + } + + private static GamesView? _instance; + public static unowned GamesView instance + { + get + { + if(_instance == null) + { + _instance = new GamesView(); + } + return _instance; + } + } + + public enum Style + { + GRID = 0, LIST = 1 + } + } +} diff --git a/src/settings/Settings.vala b/src/settings/Settings.vala new file mode 100644 index 00000000..0ad3e538 --- /dev/null +++ b/src/settings/Settings.vala @@ -0,0 +1,228 @@ +/* +This file is part of GameHub. +Copyright(C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +/* Based on Granite.Services.Settings */ + +namespace GameHub.Settings +{ + public abstract class SettingsSchema: Object + { + bool saving_key; + [Signal(no_recurse = true, run = "first", action = true, no_hooks = true, detailed = true)] + public signal void changed(); + + public GLib.Settings schema { get; construct; } + + protected SettingsSchema(string schema) + { + Object(schema: new GLib.Settings(schema)); + } + + construct + { + debug("Loading settings from schema '%s'", schema.schema_id); + + var obj_class = (ObjectClass) get_type().class_ref(); + var properties = obj_class.list_properties(); + foreach(var prop in properties) + load_key(prop.name); + + start_monitor(); + } + + ~SettingsSchema() + { + stop_monitor(); + } + + private void stop_monitor() + { + schema.changed.disconnect(load_key); + } + + private void start_monitor() + { + schema.changed.connect(load_key); + } + + void handle_notify(Object sender, ParamSpec property) + { + notify.disconnect(handle_notify); + call_verify(property.name); + notify.connect(handle_notify); + save_key(property.name); + } + + void handle_verify_notify(Object sender, ParamSpec property) + { + warning("Key '%s' failed verification in schema '%s', changing value", property.name, schema.schema_id); + } + + private void call_verify(string key) + { + notify.connect(handle_verify_notify); + verify(key); + changed[key](); + notify.disconnect(handle_verify_notify); + } + + protected virtual void verify(string key){} + + private void load_key(string key) + { + if(key == "schema") return; + + var obj_class = (ObjectClass) get_type().class_ref(); + var prop = obj_class.find_property(key); + + if(prop == null) + return; + + notify.disconnect(handle_notify); + + var type = prop.value_type; + var val = Value(type); + this.get_property(prop.name, ref val); + + if(val.type() == prop.value_type) + { + if(type == typeof(int)) + set_property(prop.name, schema.get_int(key)); + else if(type == typeof(uint)) + set_property(prop.name, schema.get_uint(key)); + else if(type == typeof(double)) + set_property(prop.name, schema.get_double(key)); + else if(type == typeof(string)) + set_property(prop.name, schema.get_string(key)); + else if(type == typeof(string[])) + set_property(prop.name, schema.get_strv(key)); + else if(type == typeof(bool)) + set_property(prop.name, schema.get_boolean(key)); + else if(type == typeof(int64)) + set_property(prop.name, schema.get_value(key).get_int64()); + else if(type == typeof(uint64)) + set_property(prop.name, schema.get_value(key).get_uint64()); + else if(type.is_enum()) + set_property(prop.name, schema.get_enum(key)); + } + else + { + debug("Unsupported settings type '%s' for key '%s' in schema '%s'", type.name(), key, schema.schema_id); + notify.connect(handle_notify); + return; + } + + call_verify(key); + notify.connect(handle_notify); + } + + void save_key(string key) + { + if(key == "schema" || saving_key) return; + + var obj_class = (ObjectClass) get_type().class_ref(); + var prop = obj_class.find_property(key); + + if(prop == null) return; + + bool success = true; + + saving_key = true; + notify.disconnect(handle_notify); + + var type = prop.value_type; + var val = Value(type); + this.get_property(prop.name, ref val); + + if(val.type() == prop.value_type) + { + if(type == typeof(int)) + { + if(val.get_int() != schema.get_int(key)) + { + success = schema.set_int(key, val.get_int()); + } + } + else if(type == typeof(uint)) + { + if(val.get_uint() != schema.get_uint(key)) + { + success = schema.set_uint(key, val.get_uint()); + } + } + else if(type == typeof(int64)) + { + if(val.get_int64() != schema.get_value(key).get_int64()) + { + success = schema.set_value(key, new Variant.int64(val.get_int64())); + } + } + else if(type == typeof(uint64)) + { + if(val.get_uint64() != schema.get_value(key).get_uint64()) + { + success = schema.set_value(key, new Variant.uint64(val.get_uint64())); + } + } + else if(type == typeof(double)) + { + if(val.get_double() != schema.get_double(key)) + { + success = schema.set_double(key, val.get_double()); + } + } + else if(type == typeof(string)) + { + if(val.get_string() != schema.get_string(key)) + { + success = schema.set_string(key, val.get_string()); + } + } + else if(type == typeof(string[])) + { + string[] strings = null; + this.get(key, &strings); + if(strings != schema.get_strv(key)) + { + success = schema.set_strv(key, strings); + } + } + else if(type == typeof(bool)) + { + if(val.get_boolean() != schema.get_boolean(key)) + { + success = schema.set_boolean(key, val.get_boolean()); + } + } + else if(type.is_enum()) + { + if(val.get_enum() != schema.get_enum(key)) + { + success = schema.set_enum(key, val.get_enum()); + } + } + } + else debug("Unsupported settings type '%s' for key '%s' in schema '%s'", type.name(), key, schema.schema_id); + + if(!success) warning("Key '%s' could not be written to.", key); + + notify.connect(handle_notify); + saving_key = false; + } + } +} diff --git a/src/settings/Tweaks.vala b/src/settings/Tweaks.vala new file mode 100644 index 00000000..3aafa1f7 --- /dev/null +++ b/src/settings/Tweaks.vala @@ -0,0 +1,45 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + + + +namespace GameHub.Settings +{ + public class Tweaks: SettingsSchema + { + public string[] global { get; set; } + + public Tweaks() + { + base(ProjectConfig.PROJECT_NAME + ".tweaks"); + } + + private static Tweaks? _instance; + public static unowned Tweaks instance + { + get + { + if(_instance == null) + { + _instance = new Tweaks(); + } + return _instance; + } + } + } +} diff --git a/src/settings/UI.vala b/src/settings/UI.vala new file mode 100644 index 00000000..44604792 --- /dev/null +++ b/src/settings/UI.vala @@ -0,0 +1,223 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; + + +namespace GameHub.Settings.UI +{ + public class Appearance: SettingsSchema + { + public const string[] COLORED_ICONS_THEMES = { "elementary" }; + + public bool dark_theme { get; set; } + public Appearance.IconStyle icon_style { get; set; } + + public bool grid_platform_icons { get; set; } + + public int grid_card_width { get; set; } + public int grid_card_height { get; set; } + + public string[] list_style_cache; + public string[] list_style { get; set; } + public signal void list_style_updated(string[] style); + + public static string symbolic_icon_suffix + { + owned get + { + return instance.icon_style.icon_suffix(); + } + } + + public static IconSize headerbar_icon_size + { + get + { + return instance.icon_style.headerbar_icon_size(); + } + } + + public Appearance() + { + base(ProjectConfig.PROJECT_NAME + ".ui.appearance"); + list_style_cache = list_style; + } + + public void update_list_style(string[] new_style) + { + list_style_cache = new_style; + list_style_updated(list_style_cache); + list_style = list_style_cache; + } + + public static Gtk.Settings gtk_settings; + private static Appearance? _instance; + public static unowned Appearance instance + { + get + { + if(_instance == null) + { + _instance = new Appearance(); + gtk_settings = Gtk.Settings.get_default(); + gtk_settings.gtk_application_prefer_dark_theme = _instance.dark_theme; + _instance.notify["dark-theme"].connect(() => { + gtk_settings.gtk_application_prefer_dark_theme = _instance.dark_theme; + }); + gtk_settings.notify["gtk-theme-name"].connect(() => { + _instance.notify_property("icon-style"); + }); + } + return _instance; + } + } + + public enum IconStyle + { + THEME = 0, SYMBOLIC = 1, COLORED = 2; + + public bool is_symbolic() + { + if(this == IconStyle.THEME) + { + return !(gtk_settings.gtk_theme_name in COLORED_ICONS_THEMES); + } + return this == IconStyle.SYMBOLIC; + } + + public string icon_suffix() + { + return is_symbolic() ? "-symbolic" : ""; + } + + public IconSize headerbar_icon_size() + { + return is_symbolic() ? IconSize.SMALL_TOOLBAR : IconSize.LARGE_TOOLBAR; + } + } + + public enum GameGridSizePreset + { + STEAM = 0, STEAM_VERTICAL = 1, GOG = 2, GOG_VERTICAL = 3, SQUARE = 4, CUSTOM = 5; + + public const GameGridSizePreset[] PRESETS = { STEAM, STEAM_VERTICAL, GOG, GOG_VERTICAL, SQUARE, CUSTOM }; + + public int width() + { + switch(this) + { + case STEAM: return 460; + case STEAM_VERTICAL: return 300; + case GOG: return 392; + case GOG_VERTICAL: return 342; + case SQUARE: return 320; + case CUSTOM: return -1; + } + assert_not_reached(); + } + + public int height() + { + switch(this) + { + case STEAM: return 215; + case STEAM_VERTICAL: return 450; + case GOG: return 220; + case GOG_VERTICAL: return 482; + case SQUARE: return 320; + case CUSTOM: return -1; + } + assert_not_reached(); + } + + public string name() + { + switch(this) + { + case STEAM: return C_("grid_size_preset", "Steam"); + case STEAM_VERTICAL: return C_("grid_size_preset", "Steam (vertical)"); + case GOG: return C_("grid_size_preset", "GOG"); + case GOG_VERTICAL: return C_("grid_size_preset", "GOG (vertical)"); + case SQUARE: return C_("grid_size_preset", "Square"); + case CUSTOM: return C_("grid_size_preset", "Custom"); + } + assert_not_reached(); + } + + public string icon() + { + switch(this) + { + case STEAM, STEAM_VERTICAL: return "source-steam-symbolic"; + case GOG, GOG_VERTICAL: return "source-gog-symbolic"; + case SQUARE: return "image-x-generic-symbolic"; + case CUSTOM: return "document-properties-symbolic"; + } + assert_not_reached(); + } + + public string? description() + { + var desc = name(); + if(this != CUSTOM) + { + desc += "\n" + """%d × %d""".printf(width(), height()); + } + return desc; + } + + public static GameGridSizePreset from_size(int? w, int? h) + { + foreach(var preset in PRESETS) + { + if(w == preset.width() && h == preset.height()) + { + return preset; + } + } + return CUSTOM; + } + } + } + + public class Behavior: SettingsSchema + { + public bool grid_doubleclick { get; set; } + public bool merge_games { get; set; } + public bool import_tags { get; set; } + + public Behavior() + { + base(ProjectConfig.PROJECT_NAME + ".ui.behavior"); + } + + private static Behavior? _instance; + public static unowned Behavior instance + { + get + { + if(_instance == null) + { + _instance = new Behavior(); + } + return _instance; + } + } + } +} diff --git a/src/ui/dialogs/CompatRunDialog.vala b/src/ui/dialogs/CompatRunDialog.vala new file mode 100644 index 00000000..ae9b90b9 --- /dev/null +++ b/src/ui/dialogs/CompatRunDialog.vala @@ -0,0 +1,165 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; + +using GLib; +using Gee; +using GameHub.Utils; +using GameHub.UI.Widgets; + +using GameHub.Data; +using GameHub.Data.Sources.Steam; + +namespace GameHub.UI.Dialogs +{ + public class CompatRunDialog: Dialog + { + public bool is_opened_from_menu { get; construct; default = false; } + + public Runnable game { get; construct; } + public Game? emulated_game { get; construct; } + public bool launch_in_game_dir { get; construct; } + + private Box content; + private Label title_label; + private CompatToolOptions opts_list; + + private CompatToolPicker compat_tool_picker; + + public CompatRunDialog(Runnable game, bool is_opened_from_menu=false, Game? emulated_game=null, bool launch_in_game_dir=false) + { + Object(game: game, emulated_game: emulated_game, launch_in_game_dir: launch_in_game_dir, transient_for: Windows.MainWindow.instance, resizable: false, title: _("Run with compatibility layer"), is_opened_from_menu: is_opened_from_menu); + } + + construct + { + get_style_context().add_class("rounded"); + get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + + modal = true; + + var hbox = new Box(Orientation.HORIZONTAL, 8); + hbox.margin_start = hbox.margin_end = 5; + + content = new Box(Orientation.VERTICAL, 0); + + title_label = Styled.H2Label(game.name); + title_label.margin_start = 4; + title_label.halign = Align.START; + title_label.valign = Align.START; + title_label.hexpand = true; + content.add(title_label); + + compat_tool_picker = new CompatToolPicker(game, false); + content.add(compat_tool_picker); + + opts_list = new CompatToolOptions(game, compat_tool_picker, false); + + content.add(opts_list); + + if(game is Game && ((Game) game).icon != null) + { + var g = (Game) game; + var icon = new AutoSizeImage(); + icon.valign = Align.START; + icon.set_constraint(48, 48, 1); + icon.set_size_request(48, 48); + title_label.margin_start = 8; + compat_tool_picker.margin_start = 4; + icon.load(g.icon, null, @"$(g.source.id)/$(g.id)/icons/"); + hbox.add(icon); + } + + hbox.add(content); + + response.connect((source, response_id) => { + switch(response_id) + { + case ResponseType.ACCEPT: + run_with_compat(); + hide(); + break; + } + }); + + var run_btn = add_button(_("Run"), ResponseType.ACCEPT); + run_btn.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION); + run_btn.grab_default(); + + get_content_area().add(hbox); + get_content_area().set_size_request(340, 96); + + var tool = game.compat_tool; + + if(!is_opened_from_menu && tool != null && compat_tool_picker.selected != null && compat_tool_picker.selected.id == tool && game.compat_options_saved) + { + Idle.add(() => { + run_with_compat(); + hide(); + return Source.REMOVE; + }); + return; + } + + show_all(); + } + + private void run_with_compat() + { + if(compat_tool_picker == null || compat_tool_picker.selected == null) return; + + Runnable.IsLaunched = game.is_running = true; + + if(game is Emulator) + { + emulated_game.is_running = true; + emulated_game.update_status(); + compat_tool_picker.selected.run_emulator.begin(game as Emulator, emulated_game, launch_in_game_dir, (obj, res) => { + compat_tool_picker.selected.run_emulator.end(res); + Timeout.add_seconds(1, () => { + Runnable.IsLaunched = game.is_running = emulated_game.is_running = false; + emulated_game.update_status(); + return Source.REMOVE; + }); + destroy(); + }); + } + else + { + game.update_status(); + (game as Game).last_launch = get_real_time() / 1000000; + game.save(); + compat_tool_picker.selected.run.begin(game, (obj, res) => { + compat_tool_picker.selected.run.end(res); + Timeout.add_seconds(1, () => { + Runnable.IsLaunched = game.is_running = false; + game.update_status(); + return Source.REMOVE; + }); + (game as Game).playtime_tracked += ((get_real_time() / 1000000) - (game as Game).last_launch) / 60; + game.save(); + destroy(); + }); + } + + opts_list.save_options(); + } + } +} diff --git a/src/ui/dialogs/CorruptedInstallerDialog.vala b/src/ui/dialogs/CorruptedInstallerDialog.vala new file mode 100644 index 00000000..93afdadc --- /dev/null +++ b/src/ui/dialogs/CorruptedInstallerDialog.vala @@ -0,0 +1,148 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; + +using GLib; +using Gee; +using GameHub.Utils; +using GameHub.UI.Widgets; + +using GameHub.Data; +using GameHub.Data.Sources.Steam; + +namespace GameHub.UI.Dialogs +{ + public class CorruptedInstallerDialog: Dialog + { + private const int RESPONSE_SHOW = 10; + private const int RESPONSE_BACKUP = 11; + private const int RESPONSE_REMOVE = 12; + + public Runnable game { get; construct; } + public File installer { get; construct; } + + private Box content; + private Label title_label; + private Label subtitle_label; + private Label message_label; + + public CorruptedInstallerDialog(Runnable game, File installer) + { + Object(game: game, installer: installer, transient_for: Windows.MainWindow.instance, resizable: false, title: _("%s: corrupted installer").printf(game.name)); + } + + construct + { + get_style_context().add_class("rounded"); + get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + + modal = true; + + var hbox = new Box(Orientation.HORIZONTAL, 8); + hbox.margin_start = hbox.margin_end = 5; + + content = new Box(Orientation.VERTICAL, 0); + content.margin_bottom = 8; + + title_label = Styled.H2Label(game.name); + title_label.margin_start = 8; + title_label.halign = Align.START; + title_label.valign = Align.START; + title_label.hexpand = true; + content.add(title_label); + + subtitle_label = new Label(_("Corrupted installer: checksum mismatch in")); + subtitle_label.margin_start = 8; + subtitle_label.halign = Align.START; + subtitle_label.valign = Align.START; + subtitle_label.hexpand = true; + content.add(subtitle_label); + + message_label = new Label(installer.get_basename()); + message_label.margin_start = 8; + message_label.halign = Align.START; + message_label.valign = Align.START; + message_label.hexpand = true; + message_label.get_style_context().add_class("category-label"); + content.add(message_label); + + if(game is Game && ((Game) game).icon != null) + { + var g = (Game) game; + var icon = new AutoSizeImage(); + icon.valign = Align.START; + icon.set_constraint(48, 48, 1); + icon.set_size_request(48, 48); + icon.load(g.icon, null, @"$(g.source.id)/$(g.id)/icons/"); + hbox.add(icon); + } + + hbox.add(content); + + response.connect((source, response_id) => { + var action = Application.ACTION_CORRUPTED_INSTALLER_SHOW; + switch(response_id) + { + case CorruptedInstallerDialog.RESPONSE_SHOW: + action = Application.ACTION_CORRUPTED_INSTALLER_SHOW; + break; + + case CorruptedInstallerDialog.RESPONSE_BACKUP: + action = Application.ACTION_CORRUPTED_INSTALLER_BACKUP; + break; + + case CorruptedInstallerDialog.RESPONSE_REMOVE: + action = Application.ACTION_CORRUPTED_INSTALLER_REMOVE; + break; + + default: + return; + } + string id = (game is Game) ? (game as Game).full_id : game.id; + Application.instance.activate_action(action, new Variant("(ss)", id, installer.get_path())); + if(action != Application.ACTION_CORRUPTED_INSTALLER_SHOW) + { + destroy(); + } + }); + + var show_btn = add_button(_("Show file"), CorruptedInstallerDialog.RESPONSE_SHOW); + + var backup_btn = add_button(_("Backup"), CorruptedInstallerDialog.RESPONSE_BACKUP); + backup_btn.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION); + backup_btn.grab_default(); + + var remove_btn = add_button(_("Remove"), CorruptedInstallerDialog.RESPONSE_REMOVE); + remove_btn.get_style_context().add_class(Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION); + + var bbox = show_btn.get_parent() as ButtonBox; + if(bbox != null) + { + bbox.set_child_secondary(show_btn, true); + bbox.set_child_non_homogeneous(show_btn, true); + } + + get_content_area().add(hbox); + get_content_area().set_size_request(340, 96); + + show_all(); + } + } +} diff --git a/src/ui/dialogs/GameDetailsDialog.vala b/src/ui/dialogs/GameDetailsDialog.vala new file mode 100644 index 00000000..7ec2fab1 --- /dev/null +++ b/src/ui/dialogs/GameDetailsDialog.vala @@ -0,0 +1,74 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gee; + +using GameHub.Data; +using GameHub.Utils; + +namespace GameHub.UI.Dialogs +{ + public class GameDetailsDialog: Dialog + { + public Game? game { get; construct; } + + public GameDetailsDialog(Game? game) + { + Object(transient_for: Windows.MainWindow.instance, resizable: false, title: game.name, game: game); + } + + construct + { + get_style_context().add_class("rounded"); + get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + + gravity = Gdk.Gravity.CENTER; + + var content = get_content_area(); + content.set_size_request(560, -1); + + var details_view = new GameHub.UI.Views.GameDetailsView.GameDetailsView(game); + details_view.preferred_source = game.source; + + content.add(details_view); + + response.connect((source, response_id) => { + switch(response_id) + { + case ResponseType.CLOSE: + destroy(); + break; + } + }); + + get_style_context().add_class("gameinfo-background"); + var ui_settings = GameHub.Settings.UI.Appearance.instance; + ui_settings.notify["dark-theme"].connect(() => { + get_style_context().remove_class("dark"); + if(ui_settings.dark_theme) get_style_context().add_class("dark"); + }); + ui_settings.notify_property("dark-theme"); + + get_action_area().no_show_all = true; + get_action_area().visible = false; + + show_all(); + } + } +} diff --git a/src/ui/dialogs/GameFSOverlaysDialog.vala b/src/ui/dialogs/GameFSOverlaysDialog.vala new file mode 100644 index 00000000..1261d1db --- /dev/null +++ b/src/ui/dialogs/GameFSOverlaysDialog.vala @@ -0,0 +1,304 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; +using Gee; + + +using GameHub.Data; +using GameHub.Data.DB; +using GameHub.Utils; +using GameHub.UI.Widgets; + +namespace GameHub.UI.Dialogs +{ + public class GameFSOverlaysDialog: Dialog + { + private const int RESPONSE_ENABLE_OVERLAYS = 1; + + public Game? game { get; construct; } + + private Stack stack; + + private Box disabled_box; + private AlertView disabled_alert; + private Button enable_btn; + + private Box content; + private ListBox overlays_list; + private ScrolledWindow overlays_scrolled; + + private Entry id_entry; + private Entry name_entry; + private Button add_btn; + + public GameFSOverlaysDialog(Game? game) + { + Object(transient_for: Windows.MainWindow.instance, resizable: false, title: _("%s: Overlays").printf(game.name), game: game); + } + + construct + { + get_style_context().add_class("rounded"); + get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + + gravity = Gdk.Gravity.NORTH; + + stack = new Stack(); + stack.transition_type = StackTransitionType.CROSSFADE; + + content = new Box(Orientation.VERTICAL, 0); + content.margin_start = content.margin_end = 6; + + disabled_box = new Box(Orientation.VERTICAL, 0); + + disabled_alert = new AlertView(_("Overlays are disabled"), _("Enable overlays to manage DLCs and mods\n\nEnabling will move game to the “base“ overlay"), "dialog-information"); + disabled_alert.get_style_context().remove_class(Gtk.STYLE_CLASS_VIEW); + disabled_alert.halign = Align.START; + + disabled_box.add(disabled_alert); + + var overlays_header = Styled.H4Label(_("Overlays")); + overlays_header.xpad = 8; + content.add(overlays_header); + + overlays_list = new ListBox(); + overlays_list.get_style_context().add_class("overlays-list"); + overlays_list.selection_mode = SelectionMode.NONE; + + overlays_scrolled = new ScrolledWindow(null, null); + overlays_scrolled.vexpand = true; + #if GTK_3_22 + overlays_scrolled.propagate_natural_width = true; + overlays_scrolled.propagate_natural_height = true; + overlays_scrolled.max_content_height = 320; + #endif + overlays_scrolled.add(overlays_list); + + content.add(overlays_scrolled); + + var separator = new Separator(Orientation.HORIZONTAL); + separator.margin_bottom = 8; + content.add(separator); + + var add_box = new Box(Orientation.HORIZONTAL, 0); + add_box.get_style_context().add_class(Gtk.STYLE_CLASS_LINKED); + + id_entry = new Entry(); + id_entry.hexpand = true; + id_entry.placeholder_text = _("Overlay ID (directory name)"); + id_entry.primary_icon_name = "list-add-symbolic"; + + name_entry = new Entry(); + name_entry.hexpand = true; + name_entry.placeholder_text = _("Overlay name (optional)"); + + add_btn = new Button.with_label(_("Add")); + add_btn.sensitive = false; + + add_box.add(id_entry); + add_box.add(name_entry); + add_box.add(add_btn); + + content.add(add_box); + + stack.add(disabled_box); + stack.add(content); + + get_content_area().add(stack); + get_content_area().set_size_request(480, 240); + + enable_btn = add_button(_("Enable overlays"), RESPONSE_ENABLE_OVERLAYS) as Button; + enable_btn.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION); + enable_btn.grab_default(); + + response.connect((source, response_id) => { + switch(response_id) + { + case RESPONSE_ENABLE_OVERLAYS: + game.enable_overlays(); + break; + } + }); + + destroy.connect(() => { + game.save_overlays(); + game.mount_overlays.begin(); + }); + + show_all(); + + game.notify["overlays-enabled"].connect(update); + + add_btn.clicked.connect(add_overlay); + + id_entry.activate.connect(() => name_entry.grab_focus()); + name_entry.activate.connect(add_overlay); + + id_entry.changed.connect(() => add_btn.sensitive = id_entry.text.strip().length > 0); + + Idle.add(() => { + update(); + return Source.REMOVE; + }); + } + + private void update() + { + game.load_overlays(); + + if(!game.overlays_enabled) + { + disabled_box.foreach(w => { + if(w != disabled_alert) + { + w.destroy(); + } + }); + + if(game.install_dir != null && game.install_dir.query_exists()) + { + var safety = FSOverlay.RootPathSafety.for(game.install_dir); + + if(safety != FSOverlay.RootPathSafety.SAFE) + { + var message_type = MessageType.WARNING; + var message = _("Overlay usage at this path may be unsafe\nProceed at your own risk\n\nPath: %s"); + + if(safety == FSOverlay.RootPathSafety.RESTRICTED) + { + message_type = MessageType.ERROR; + message = _("Overlay usage at this path is not supported\n\nPath: %s"); + } + + var label = new Label(message.printf(game.install_dir.get_path())); + label.use_markup = true; + + var msg = new InfoBar(); + msg.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME); + msg.get_content_area().add(label); + msg.message_type = message_type; + msg.show_all(); + disabled_box.add(msg); + } + + enable_btn.sensitive = safety != FSOverlay.RootPathSafety.RESTRICTED; + } + else + { + enable_btn.sensitive = false; + } + + stack.visible_child = disabled_box; + enable_btn.visible = true; + } + else + { + stack.visible_child = content; + enable_btn.visible = false; + enable_btn.sensitive = false; + + overlays_list.foreach(w => w.destroy()); + + foreach(var overlay in game.overlays) + { + overlays_list.add(new OverlayRow(overlay)); + } + + overlays_list.show_all(); + } + } + + private void add_overlay() + { + var id = id_entry.text.strip(); + var name = name_entry.text.strip(); + if(name.length == 0) name = id; + if(id.length == 0) return; + game.overlays.add(new Game.Overlay(game, id, name, true)); + game.save_overlays(); + id_entry.text = name_entry.text = ""; + id_entry.grab_focus(); + } + + private class OverlayRow: ListBoxRow + { + public Game.Overlay overlay { get; construct; } + + public OverlayRow(Game.Overlay overlay) + { + Object(overlay: overlay); + } + + construct + { + var grid = new Grid(); + grid.margin_start = grid.margin_end = 8; + grid.margin_top = grid.margin_bottom = 6; + grid.column_spacing = 8; + + var name = new Label(overlay.name); + name.get_style_context().add_class("category-label"); + name.hexpand = true; + name.xalign = 0; + + var id = new Label(overlay.id); + id.hexpand = true; + id.xalign = 0; + + var open = new Button.from_icon_name("folder-symbolic", IconSize.SMALL_TOOLBAR); + open.tooltip_text = _("Open directory"); + open.valign = Align.CENTER; + open.get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + + var remove = new Button.from_icon_name("edit-delete-symbolic", IconSize.SMALL_TOOLBAR); + remove.tooltip_text = _("Remove overlay"); + remove.sensitive = overlay.removable; + remove.valign = Align.CENTER; + remove.get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + + var enabled = new Switch(); + enabled.active = overlay.enabled; + enabled.sensitive = overlay.id != Game.Overlay.BASE; + enabled.valign = Align.CENTER; + + grid.attach(name, 0, 0); + grid.attach(id, 0, 1); + grid.attach(open, 1, 0, 1, 2); + grid.attach(remove, 2, 0, 1, 2); + grid.attach(enabled, 3, 0, 1, 2); + + child = grid; + + open.clicked.connect(() => { + Utils.open_uri(overlay.directory.get_uri()); + }); + + remove.clicked.connect(() => { + overlay.remove(); + }); + + enabled.notify["active"].connect(() => { + overlay.enabled = enabled.active; + overlay.game.save_overlays(); + }); + } + } + } +} diff --git a/src/ui/dialogs/GamePropertiesDialog.vala b/src/ui/dialogs/GamePropertiesDialog.vala new file mode 100644 index 00000000..2dbb8dab --- /dev/null +++ b/src/ui/dialogs/GamePropertiesDialog.vala @@ -0,0 +1,409 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; +using Gee; + + +using GameHub.Data; +using GameHub.Data.DB; +using GameHub.Utils; +using GameHub.UI.Widgets; + +namespace GameHub.UI.Dialogs +{ + public class GamePropertiesDialog: Dialog + { + public Game? game { get; construct; } + + private Box content; + + private Entry name_entry; + private AutoSizeImage image_view; + private AutoSizeImage image_vertical_view; + private AutoSizeImage icon_view; + private FileChooserEntry image_entry; + private FileChooserEntry image_vertical_entry; + private FileChooserEntry icon_entry; + + private Box properties_box; + + public GamePropertiesDialog(Game? game) + { + Object(transient_for: Windows.MainWindow.instance, resizable: false, title: _("%s: Properties").printf(game.name), game: game); + } + + construct + { + get_style_context().add_class("rounded"); + get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + + gravity = Gdk.Gravity.NORTH; + + content = new Box(Orientation.HORIZONTAL, 8); + content.margin_start = content.margin_end = 6; + + properties_box = new Box(Orientation.VERTICAL, 0); + + var name_header = Styled.H4Label(_("Name")); + name_header.xpad = 8; + properties_box.add(name_header); + + name_entry = new Entry(); + name_entry.placeholder_text = name_entry.primary_icon_tooltip_text = _("Name"); + name_entry.primary_icon_name = "insert-text-symbolic"; + name_entry.primary_icon_activatable = false; + name_entry.margin = 4; + name_entry.margin_top = 0; + properties_box.add(name_entry); + + name_entry.text = game.name; + name_entry.changed.connect(() => { + game.name = name_entry.text.strip(); + game.update_status(); + game.save(); + DB.Tables.IGDBData.remove(game); + }); + + var images_header = Styled.H4Label(_("Images")); + images_header.xpad = 8; + properties_box.add(images_header); + + var images_hbox = new Box(Orientation.HORIZONTAL, 0); + + var images_card = Styled.Card("gamecard", "static"); + images_card.margin = 4; + + icon_view = new AutoSizeImage(); + icon_view.margin = 4; + icon_view.set_constraint(48, 48, 1); + icon_view.halign = Align.START; + icon_view.valign = Align.END; + + image_view = new AutoSizeImage(); + image_view.expand = false; + + var actions = new Box(Orientation.VERTICAL, 0); + actions.get_style_context().add_class("actions"); + actions.hexpand = true; + actions.vexpand = false; + + var images_overlay = new Overlay(); + images_overlay.add(image_view); + images_overlay.add_overlay(actions); + images_overlay.add_overlay(icon_view); + + images_card.add(images_overlay); + + var image_vertical_card = Styled.Card("gamecard", "static"); + image_vertical_card.margin = 4; + + image_vertical_view = new AutoSizeImage(); + image_vertical_view.expand = false; + + var images_download_btn = new MenuButton(); + images_download_btn.get_style_context().add_class("images-download-button"); + images_download_btn.margin = 8; + images_download_btn.halign = Align.END; + images_download_btn.valign = Align.START; + images_download_btn.image = new Image.from_icon_name("folder-download-symbolic", IconSize.BUTTON); + images_download_btn.tooltip_text = _("Download images"); + + var actions_vertical = new Box(Orientation.VERTICAL, 0); + actions_vertical.get_style_context().add_class("actions"); + actions_vertical.expand = true; + + var image_vertical_overlay = new Overlay(); + image_vertical_overlay.add(image_vertical_view); + image_vertical_overlay.add_overlay(actions_vertical); + image_vertical_overlay.add_overlay(images_download_btn); + + image_vertical_card.add(image_vertical_overlay); + + images_hbox.add(images_card); + images_hbox.add(image_vertical_card); + + properties_box.add(images_hbox); + + image_entry = add_image_entry(_("Image URL"), "image-x-generic"); + image_entry.hexpand = true; + image_entry.margin = 4; + + image_vertical_entry = add_image_entry(_("Vertical image URL"), "image-x-generic"); + image_vertical_entry.hexpand = true; + image_vertical_entry.margin_top = 0; + + var images_download_popover = new ImagesDownloadPopover(game, images_download_btn); + + properties_box.add(image_entry); + properties_box.add(image_vertical_entry); + + icon_entry = add_image_entry(_("Icon URL"), "image-x-generic-symbolic"); + icon_entry.margin_top = 0; + + properties_box.add(icon_entry); + + var space = new Box(Orientation.VERTICAL, 0); + space.vexpand = true; + properties_box.add(space); + + if(!(game is Data.Sources.Steam.SteamGame) && game.install_dir != null && game.install_dir.query_exists()) + { + var executable_header = Styled.H4Label(_("Executable")); + executable_header.xpad = 8; + properties_box.add(executable_header); + + var executable_picker = new FileChooserEntry(_("Select executable"), FileChooserAction.OPEN, "application-x-executable", _("Executable"), false, true); + var work_dir_picker = new FileChooserEntry(_("Select working directory"), FileChooserAction.SELECT_FOLDER, "folder", _("Working directory")); + try + { + executable_picker.set_default_directory(game.install_dir); + executable_picker.select_file(game.executable); + work_dir_picker.set_default_directory(game.install_dir); + work_dir_picker.select_file(game.work_dir); + } + catch(Error e) + { + warning(e.message); + } + executable_picker.margin_start = executable_picker.margin_end = 4; + work_dir_picker.margin_start = work_dir_picker.margin_end = work_dir_picker.margin_top = 4; + properties_box.add(executable_picker); + properties_box.add(work_dir_picker); + + executable_picker.file_set.connect(() => { + game.set_chosen_executable(executable_picker.file); + }); + + work_dir_picker.file_set.connect(() => { + game.work_dir = work_dir_picker.file; + game.save(); + }); + + var args_entry = new Entry(); + args_entry.text = game.arguments ?? ""; + args_entry.placeholder_text = args_entry.primary_icon_tooltip_text = _("Arguments"); + args_entry.primary_icon_name = "utilities-terminal-symbolic"; + args_entry.primary_icon_activatable = false; + args_entry.margin = 4; + + args_entry.changed.connect(() => { + game.arguments = args_entry.text.strip(); + game.update_status(); + game.save(); + }); + + properties_box.add(args_entry); + + var compat_header = Styled.H4Label(_("Compatibility")); + compat_header.no_show_all = true; + compat_header.xpad = 8; + properties_box.add(compat_header); + + var compat_force_switch = add_switch(_("Force compatibility mode"), game.force_compat, f => { game.force_compat = f; }); + compat_force_switch.no_show_all = true; + + var compat_tool = new CompatToolPicker(game, false, true); + compat_tool.no_show_all = true; + compat_tool.margin_start = compat_tool.margin_end = 4; + properties_box.add(compat_tool); + + game.notify["use-compat"].connect(() => { + compat_force_switch.visible = !game.needs_compat; + compat_tool.visible = game.use_compat; + compat_header.visible = compat_force_switch.visible || compat_tool.visible; + game.update_status(); + }); + game.notify_property("use-compat"); + } + + var gh_run_args_header = Styled.H4Label(_("Launch from terminal")); + gh_run_args_header.xpad = 8; + properties_box.add(gh_run_args_header); + + var gh_run_args_box = new Box(Orientation.HORIZONTAL, 0); + gh_run_args_box.get_style_context().add_class(Gtk.STYLE_CLASS_LINKED); + gh_run_args_box.margin_start = gh_run_args_box.margin_end = gh_run_args_box.margin_bottom = 4; + + var gh_run_args_entry = new Entry(); + gh_run_args_entry.hexpand = true; + gh_run_args_entry.text = ProjectConfig.PROJECT_NAME + " --run " + game.full_id; + gh_run_args_entry.editable = false; + gh_run_args_entry.primary_icon_name = "utilities-terminal-symbolic"; + gh_run_args_entry.primary_icon_activatable = false; + gh_run_args_entry.secondary_icon_name = "edit-copy-symbolic"; + gh_run_args_entry.secondary_icon_activatable = true; + gh_run_args_entry.secondary_icon_tooltip_text = _("Copy to clipboard"); + + var gh_add_to_steam_btn = new Button.with_label(_("Add to Steam")); + gh_add_to_steam_btn.tooltip_text = _("Add to the Steam library"); + + gh_add_to_steam_btn.clicked.connect(() => { + Data.Sources.Steam.Steam.add_game_shortcut(game); + }); + + gh_run_args_box.add(gh_run_args_entry); + gh_run_args_box.add(gh_add_to_steam_btn); + + properties_box.add(gh_run_args_box); + + gh_run_args_entry.icon_press.connect((icon, event) => { + if(icon == EntryIconPosition.SECONDARY && ((EventButton) event).button == 1) + { + gh_run_args_entry.select_region(0, -1); + gh_run_args_entry.copy_clipboard(); + } + }); + + content.add(new GameTagsList(game)); + content.add(new Separator(Orientation.VERTICAL)); + content.add(properties_box); + + get_content_area().add(content); + get_content_area().set_size_request(640, 480); + + delete_event.connect(() => { + image_entry.activate(); + icon_entry.activate(); + set_image_url(true); + set_image_vertical_url(true); + set_icon_url(true); + game.save(); + destroy(); + }); + + update_image_constraints(); + + game.notify["image"].connect(load_images); + game.notify["image-vertical"].connect(load_images); + load_images(); + + show_all(); + } + + private void set_image_url(bool replace=false) + { + var url = image_entry.uri; + if(url == null || url.length == 0) url = game.image; + if(replace) + { + game.image = url; + } + else + { + image_view.load(url, null, @"games/$(game.source.id)/$(game.id)/images/"); + } + } + + private void set_image_vertical_url(bool replace=false) + { + var url = image_vertical_entry.uri; + if(url == null || url.length == 0) url = game.image_vertical; + if(replace) + { + game.image_vertical = url; + } + else + { + image_vertical_view.load(null, url, @"games/$(game.source.id)/$(game.id)/images/"); + } + } + + private void set_icon_url(bool replace=false) + { + var url = icon_entry.uri; + if(url == null || url.length == 0) url = game.icon; + if(replace) + { + game.icon = url; + } + else + { + icon_view.load(url, null, @"games/$(game.source.id)/$(game.id)/icons/"); + } + } + + private void load_images() + { + image_entry.reset(); + image_vertical_entry.reset(); + + image_view.load(game.image, null, @"games/$(game.source.id)/$(game.id)/images/"); + image_vertical_view.load(null, game.image_vertical, @"games/$(game.source.id)/$(game.id)/images/"); + icon_view.load(game.icon, null, @"games/$(game.source.id)/$(game.id)/icons/"); + } + + private void update_image_constraints() + { + set_image_constraints(image_view, 460, 215); + set_image_constraints(image_vertical_view, 143, 215); + } + + private void set_image_constraints(AutoSizeImage iv, int w, int h) + { + var ratio = (float) h / w; + iv.set_constraint(w, w * 2, ratio); + } + + private FileChooserEntry add_image_entry(string text, string icon) + { + var entry = new FileChooserEntry(text, FileChooserAction.OPEN, icon, text, true); + entry.margin = 4; + + var filter = new FileFilter(); + filter.add_mime_type("image/*"); + entry.chooser.set_filter(filter); + + entry.uri_set.connect(() => { set_image_url(false); set_image_vertical_url(false); set_icon_url(false); }); + + return entry; + } + + private Box add_row(string text, Widget widget) + { + widget.halign = Align.END; + + var label = new Label(text); + label.halign = Align.START; + label.hexpand = true; + + var hbox = new Box(Orientation.HORIZONTAL, 12); + hbox.margin = 4; + hbox.margin_start = 8; + + hbox.add(label); + hbox.add(widget); + + hbox.show_all(); + + properties_box.add(hbox); + return hbox; + } + + private Box add_switch(string text, bool enabled, owned SwitchAction action) + { + var sw = new Switch(); + sw.active = enabled; + sw.notify["active"].connect(() => { action(sw.active); }); + return add_row(text, sw); + } + + protected delegate void SwitchAction(bool active); + } +} diff --git a/src/ui/dialogs/GameTweaksDialog.vala b/src/ui/dialogs/GameTweaksDialog.vala new file mode 100644 index 00000000..5486ebc7 --- /dev/null +++ b/src/ui/dialogs/GameTweaksDialog.vala @@ -0,0 +1,80 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; +using Gee; + +using GameHub.Data; +using GameHub.Data.DB; +using GameHub.Utils; +using GameHub.UI.Widgets; + +namespace GameHub.UI.Dialogs +{ + public class GameTweaksDialog: Dialog + { + public TweakableGame? game { get; construct; } + + private Box content; + private TweaksList tweaks_list; + private ScrolledWindow tweaks_list_scroll; + + public GameTweaksDialog(TweakableGame? game) + { + Object(transient_for: Windows.MainWindow.instance, resizable: false, title: _("%s: Tweaks").printf(game.name), game: game); + } + + construct + { + get_style_context().add_class("rounded"); + get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + + gravity = Gdk.Gravity.NORTH; + + content = new Box(Orientation.VERTICAL, 0); + content.margin_start = content.margin_end = 6; + + var tweaks_header = Styled.H4Label(_("Tweaks")); + tweaks_header.xpad = 8; + content.add(tweaks_header); + + tweaks_list = new TweaksList(game); + tweaks_list.get_style_context().add_class("separated-list"); + tweaks_list.hexpand = false; + + tweaks_list_scroll = new ScrolledWindow(null, null); + tweaks_list_scroll.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME); + tweaks_list_scroll.hscrollbar_policy = PolicyType.NEVER; + tweaks_list_scroll.vexpand = true; + #if GTK_3_22 + tweaks_list_scroll.propagate_natural_width = true; + tweaks_list_scroll.propagate_natural_height = true; + tweaks_list_scroll.max_content_height = 520; + #endif + tweaks_list_scroll.add(tweaks_list); + + content.add(tweaks_list_scroll); + + get_content_area().add(content); + get_content_area().set_size_request(480, -1); + + show_all(); + } + } +} diff --git a/src/ui/dialogs/ImportEmulatedGamesDialog.vala b/src/ui/dialogs/ImportEmulatedGamesDialog.vala new file mode 100644 index 00000000..517fe8aa --- /dev/null +++ b/src/ui/dialogs/ImportEmulatedGamesDialog.vala @@ -0,0 +1,650 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; + +using GLib; +using Gee; +using GameHub.Utils; +using GameHub.UI.Widgets; + +using GameHub.Data; +using GameHub.Data.DB; +using GameHub.Data.Compat; +using GameHub.Data.Sources.User; + +namespace GameHub.UI.Dialogs +{ + public class ImportEmulatedGamesDialog: Dialog + { + private const int RESPONSE_IMPORT = 10; + + public signal void game_added(UserGame game); + + private HashMap detected_games; + + private Box content; + + private FileChooserEntry dir_chooser; + + private Label status_label; + private Spinner status_spinner; + + private ScrolledWindow found_list_scroll; + private ListBox found_list; + + private CheckButton select_all; + private Button import_btn; + + public ImportEmulatedGamesDialog() + { + Object(transient_for: Windows.MainWindow.instance, resizable: false, title: _("Import emulated games")); + } + + construct + { + get_style_context().add_class("rounded"); + get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + get_style_context().add_class("import-emulated-games-dialog"); + + modal = true; + + content = new Box(Orientation.VERTICAL, 4); + content.set_size_request(640, 480); + content.margin = 4; + + var dir_hbox = new Box(Orientation.HORIZONTAL, 12); + dir_hbox.margin_start = dir_hbox.margin_end = 8; + + dir_chooser = new FileChooserEntry(_("Select directory with emulated games"), FileChooserAction.SELECT_FOLDER); + dir_chooser.hexpand = true; + + dir_chooser.file_set.connect(start_search); + + dir_hbox.add(Styled.H4Label(_("Directory"))); + dir_hbox.add(dir_chooser); + + var header_label = Styled.H4Label(_("Detected games")); + header_label.margin_start = header_label.margin_end = 8; + header_label.xalign = 0; + header_label.hexpand = true; + + found_list_scroll = new ScrolledWindow(null, null); + found_list_scroll.expand = true; + found_list_scroll.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME); + + found_list = new ListBox(); + found_list.selection_mode = SelectionMode.NONE; + found_list.sensitive = false; + + found_list.set_sort_func((row, row2) => ((EmulatedGameRow) row).sort((EmulatedGameRow) row2)); + found_list.set_header_func((row, prev) => ((EmulatedGameRow) row).header((EmulatedGameRow) prev)); + + found_list_scroll.add(found_list); + + content.add(dir_hbox); + content.add(header_label); + content.add(found_list_scroll); + + var status_hbox = new Box(Orientation.HORIZONTAL, 10); + + select_all = new CheckButton.with_label(_("Select all")); + select_all.get_style_context().add_class("select-all"); + select_all.active = true; + select_all.no_show_all = true; + select_all.visible = false; + select_all.xalign = 0.5f; + select_all.toggled.connect(select_all_toggled); + + status_label = new Label(_("Select directory to import")); + status_label.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL); + status_label.xalign = 0; + status_label.hexpand = true; + + status_spinner = new Spinner(); + status_spinner.halign = Align.END; + status_spinner.no_show_all = true; + status_spinner.visible = false; + + status_hbox.add(select_all); + status_hbox.add(status_spinner); + status_hbox.add(status_label); + + import_btn = (Button) add_button(_("Import"), RESPONSE_IMPORT); + import_btn.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION); + import_btn.sensitive = false; + + var bbox = (ButtonBox) import_btn.get_parent(); + bbox.add(status_hbox); + bbox.set_child_secondary(status_hbox, true); + bbox.set_child_non_homogeneous(status_hbox, true); + + response.connect((source, response_id) => { + switch(response_id) + { + case RESPONSE_IMPORT: + found_list.foreach(r => { + var row = (EmulatedGameRow) r; + row.import_as_usergame(); + }); + destroy(); + break; + } + }); + + delete_event.connect(() => { + destroy(); + }); + + get_content_area().add(content); + + show_all(); + } + + private bool is_toggling_selection = false; + private bool is_updating_selection = false; + private void select_all_toggled() + { + if(is_toggling_selection || is_updating_selection) return; + is_toggling_selection = true; + + select_all.inconsistent = false; + found_list.foreach(r => { + var row = (EmulatedGameRow) r; + row.import.active = select_all.active; + }); + + is_toggling_selection = false; + + update_selection(); + } + + private void update_selection() + { + if(is_updating_selection || is_toggling_selection) return; + is_updating_selection = true; + + bool all_selected = true; + bool none_selected = true; + + found_list.foreach(r => { + var row = (EmulatedGameRow) r; + all_selected = all_selected && row.import.active; + none_selected = none_selected && !row.import.active; + }); + + select_all.active = all_selected; + select_all.inconsistent = !all_selected && !none_selected; + + import_btn.sensitive = !none_selected; + + is_updating_selection = false; + } + + private void add_row(EmulatedGameRow row) + { + found_list.add(row); + row.game_added.connect(g => game_added(g)); + row.import.toggled.connect(update_selection); + } + + private void start_search() + { + if(!dir_chooser.sensitive || dir_chooser.file == null) return; + + dir_chooser.sensitive = false; + select_all.visible = false; + found_list.sensitive = false; + status_spinner.visible = true; + status_spinner.start(); + + detected_games = new HashMap(); + + found_list.foreach(r => r.destroy()); + + Utils.thread("ImportEmulatedGamesDialogSearch", () => { + debug("[ImportEmulatedGamesDialog] Starting search in '%s'", dir_chooser.file.get_path()); + + search_emulators(); + search_retroarch(); + + Idle.add(() => { + select_all.visible = true; + found_list.sensitive = true; + status_spinner.visible = false; + status_spinner.stop(); + status_label.label = null; + + foreach(var game in detected_games.values) + { + add_row(new EmulatedGameRow(game)); + } + + update_selection(); + return Source.REMOVE; + }); + }); + } + + private void search_emulators() + { + var root = dir_chooser.file; + + var emulators = Tables.Emulators.get_all(); + foreach(var emu in emulators) + { + var pattern = emu.game_executable_pattern; + if(pattern != null) pattern = pattern.strip(); + + if(pattern.length > 0) + { + var subpatterns = pattern.split("|"); + foreach(var sp in subpatterns) + { + sp = sp.strip(); + bool is_dir_based = sp.has_prefix("./"); + + if(is_dir_based) + { + if(sp == "./") continue; + sp = sp.substring(sp.index_of_nth_char(2)); + } + + var files_list = Utils.run({"find", root.get_path(), "-path", "*/" + sp, "-type", "f"}).log(false).run_sync(true).output; + var files = files_list.split("\n"); + + foreach(var file_path in files) + { + var file = FSUtils.file(file_path); + + var dir = file.get_parent(); + var name = file.get_basename(); + + if(is_dir_based) + { + if("/" in sp) + { + var sp_parts = sp.split("/"); + for(int i = 0; i < sp_parts.length - 1; i++) + { + dir = dir.get_parent(); + } + } + name = dir.get_basename(); + } + else + { + var ext_index = name.last_index_of_char('.'); + if(ext_index > 0) + { + name = name.substring(0, ext_index); + } + } + + debug("[search_emulators: %s] '%s': %s [%s]", emu.name, name, file.get_path(), dir.get_path()); + + var tool = new EmulatedGame.Tool(emu); + var game = detected_games.has_key(file_path) ? detected_games.get(file_path) : new EmulatedGame(name, file, dir, is_dir_based ? dir.get_parent() : dir); + game.tools.add(tool); + detected_games.set(file_path, game); + } + } + } + } + } + + private void search_retroarch() + { + var root = dir_chooser.file; + + var retroarch = RetroArch.instance; + if(!retroarch.installed) + { + warning("[search_retroarch] RetroArch is not installed"); + return; + } + if(!retroarch.has_cores) + { + warning("[search_retroarch] No libretro cores found"); + return; + } + + var core_info_dir = FSUtils.file(Settings.Compat.RetroArch.instance.core_info_dir); + + if(core_info_dir == null || !core_info_dir.query_exists()) + { + warning("[search_retroarch] libretro core info dir does not exist"); + return; + } + + var ignored_cores = Settings.Compat.RetroArch.instance.cores_blacklist.split("|"); + var ignored_extensions = Settings.Compat.RetroArch.instance.game_executable_extensions_blacklist.split("|"); + + foreach(var core in retroarch.cores) + { + if(core in ignored_cores) continue; + + var info = core_info_dir.get_child(core + RetroArch.LIBRETRO_CORE_INFO_SUFFIX); + + if(info == null || !info.query_exists()) continue; + + status_label.label = "RetroArch: " + core; + + try + { + string full_info; + FileUtils.get_contents(info.get_path(), out full_info); + + if(!("supported_extensions = \"" in full_info)) continue; + + string? core_name = null; + string? display_name = null; + string? supported_extensions = null; + + var lines = full_info.split("\n"); + foreach(var line in lines) + { + if("corename = \"" in line) + { + core_name = line.replace("corename = \"", "").replace("\"", "").strip(); + } + else if("display_name = \"" in line) + { + display_name = line.replace("display_name = \"", "").replace("\"", "").strip(); + status_label.label = "RetroArch: " + display_name; + } + else if("supported_extensions = \"" in line) + { + supported_extensions = line.replace("supported_extensions = \"", "").replace("\"", "").strip(); + } + } + + if(supported_extensions != null && supported_extensions.length > 0) + { + var exts = supported_extensions.split("|"); + foreach(var ext in exts) + { + ext = ext.strip(); + if(ext in ignored_extensions) continue; + + var files_list = Utils.run({"find", root.get_path(), "-path", "*/*." + ext, "-type", "f"}).log(false).run_sync(true).output; + var files = files_list.split("\n"); + + foreach(var file_path in files) + { + var file = FSUtils.file(file_path); + + var dir = file.get_parent(); + var name = file.get_basename(); + + var ext_index = name.last_index_of_char('.'); + if(ext_index > 0) + { + name = name.substring(0, ext_index); + } + + debug("[search_retroarch: %s] '%s': %s [%s]", core, name, file.get_path(), dir.get_path()); + + var tool = new EmulatedGame.Tool.libretro(core, core_name, display_name); + var game = detected_games.has_key(file_path) ? detected_games.get(file_path) : new EmulatedGame(name, file, dir, dir); + game.tools.add(tool); + detected_games.set(file_path, game); + } + } + } + } + catch(Error e) + { + warning("[search_retroarch] Error while reading core info: %s", e.message); + } + } + } + + private class EmulatedGame: Object + { + public string name; + public File file; + public File directory; + public File parent_directory; + public ArrayList tools; + + public EmulatedGame(string name, File file, File directory, File parent_directory) + { + this.name = name; + this.file = file; + this.directory = directory; + this.parent_directory = parent_directory; + this.tools = new ArrayList(); + } + + public class Tool: Object + { + public string short_name; + public string name; + public Emulator? emulator = null; + public string? libretro_core = null; + public bool uses_libretro = false; + + public Tool(Emulator emulator) + { + this.short_name = this.name = emulator.name; + this.emulator = emulator; + this.uses_libretro = false; + } + + public Tool.libretro(string core, string? core_name, string? display_name) + { + this.short_name = "RetroArch: " + (core_name != null ? core_name : core); + this.name = "RetroArch: " + (display_name != null ? display_name : (core_name != null ? core_name : core)); + this.libretro_core = core; + this.uses_libretro = true; + } + } + } + + private class EmulatedGameRow: ListBoxRow + { + public signal void game_added(UserGame game); + + public EmulatedGame game; + public CheckButton import; + public Entry title; + + private Gtk.ListStore tools_model; + private int tools_model_size = 0; + private Gtk.TreeIter tools_iter; + public ComboBox tools; + + public EmulatedGame.Tool selected_tool; + + public EmulatedGameRow(EmulatedGame game) + { + this.game = game; + + var grid = new Grid(); + grid.column_spacing = 8; + grid.margin_start = grid.margin_end = 8; + grid.margin_top = grid.margin_bottom = 4; + + import = new CheckButton(); + import.active = true; + + var title_hbox = new Box(Orientation.HORIZONTAL, 0); + title_hbox.expand = true; + title_hbox.get_style_context().add_class(Gtk.STYLE_CLASS_LINKED); + + title = new Entry(); + title.expand = true; + title.xalign = 0; + + title_hbox.add(title); + + tools_model = new Gtk.ListStore(2, typeof(string), typeof(EmulatedGame.Tool)); + foreach(var tool in game.tools) + { + tools_model.append(out tools_iter); + tools_model.set(tools_iter, 0, tool.short_name); + tools_model.set(tools_iter, 1, tool); + tools_model_size++; + } + + tools = new ComboBox.with_model(tools_model); + tools.set_size_request(128, -1); + tools.popup_fixed_width = false; + + CellRendererText r_name = new CellRendererText(); + r_name.ellipsize = Pango.EllipsizeMode.END; + r_name.width_chars = r_name.max_width_chars = 20; + r_name.xpad = 4; + tools.pack_start(r_name, true); + tools.add_attribute(r_name, "text", 0); + + tools.changed.connect(() => { + if(tools_model_size == 0) return; + Value v; + tools.get_active_iter(out tools_iter); + tools_model.get_value(tools_iter, 1, out v); + selected_tool = v as EmulatedGame.Tool; + tools.tooltip_text = selected_tool.name; + }); + + tools.active = 0; + tools.sensitive = tools_model_size > 1; + + title_hbox.add(tools); + + title.text = game.name; + tooltip_text = game.file.get_path(); + + import.toggled.connect(() => { + title_hbox.sensitive = import.active; + }); + + grid.attach(import, 0, 0); + grid.attach(title_hbox, 1, 0); + + child = grid; + show_all(); + } + + public int sort(EmulatedGameRow other) + { + var dir = game.parent_directory.get_path(); + var other_dir = other.game.parent_directory.get_path(); + return strcmp(dir.collate_key_for_filename(), other_dir.collate_key_for_filename()); + } + + public void header(EmulatedGameRow? prev) + { + if(prev == null || prev.game.parent_directory.get_path() != game.parent_directory.get_path()) + { + var header = Styled.H4Label(game.parent_directory.get_path()); + header.margin_end = 8; + header.ellipsize = Pango.EllipsizeMode.START; + header.tooltip_text = header.label; + header.expand = false; + header.show_all(); + set_header(header); + } + else + { + set_header(null); + } + } + + public void import_as_usergame() + { + if(!import.active) return; + + var g = new UserGame(title.text.strip(), game.directory, game.file, "", false); + + if(selected_tool.uses_libretro) + { + g.compat_tool = "retroarch"; + g.compat_tool_settings = "{\"compat_options_saved\":true,\"force_compat\":true,\"retroarch\":{\"options\":{\"core\":\"" + selected_tool.libretro_core + "\"}}}"; + } + else + { + g.compat_tool = "emulator"; + g.compat_tool_settings = "{\"compat_options_saved\":true,\"force_compat\":true,\"emulator\":{\"options\":{\"emulator\":\"" + selected_tool.emulator.name + "\"}}}"; + + var basename = game.file.get_basename(); + var ext_index = basename.last_index_of_char('.'); + if(ext_index > 0) + { + basename = basename.substring(0, ext_index); + } + + var image = find_by_pattern(selected_tool.emulator.game_image_pattern, game.directory, basename); + var icon = find_by_pattern(selected_tool.emulator.game_icon_pattern, game.directory, basename); + + if(image != null) + { + g.image = image.get_uri(); + } + if(icon != null) + { + g.icon = icon.get_uri(); + } + } + + g.platforms.clear(); + g.platforms.add(Platform.EMULATED); + + g.save(); + User.instance.add_game(g); + game_added(g); + } + + private File? find_by_pattern(string? pattern, File directory, string basename) + { + if(pattern != null) + { + var subpatterns = pattern.split("|"); + foreach(var sp in subpatterns) + { + sp = sp.strip(); + + if(sp.has_prefix("./")) + { + if(sp == "./") continue; + sp = sp.substring(sp.index_of_nth_char(2)); + } + + sp = sp.replace("${basename}", basename).replace("$basename", basename); + + var files_list = Utils.run({"find", directory.get_path(), "-path", "*/" + sp}).log(false).run_sync(true).output; + var files = files_list.split("\n"); + + foreach(var file_path in files) + { + var file = FSUtils.file(file_path); + if(file != null && file.query_exists()) + { + return file; + } + } + } + } + + return null; + } + } + } +} diff --git a/src/ui/dialogs/InstallDialog.vala b/src/ui/dialogs/InstallDialog.vala new file mode 100644 index 00000000..03cc0f7a --- /dev/null +++ b/src/ui/dialogs/InstallDialog.vala @@ -0,0 +1,387 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; +using GLib; +using Gee; +using GameHub.Utils; +using GameHub.UI.Widgets; + +using GameHub.Data; +using GameHub.Data.Sources.GOG; +using GameHub.Data.Sources.Humble; + +namespace GameHub.UI.Dialogs +{ + public class InstallDialog: Dialog + { + private const int RESPONSE_IMPORT = 10; + private const int RESPONSE_DOWNLOAD = 11; + + private Box content; + private Label title_label; + private Label subtitle_label; + + private ModeButton platforms_list; + private ListBox installers_list; + + private CompatToolPicker compat_tool_picker; + private CompatToolOptions opts_list; + + public Runnable runnable { get; construct; } + public Runnable.Installer.InstallMode install_mode { get; construct; } + private SourceFunc? callback = null; + + public InstallDialog(Runnable runnable, ArrayList installers, Runnable.Installer.InstallMode install_mode=Runnable.Installer.InstallMode.INTERACTIVE, owned SourceFunc? callback=null) + { + Object(transient_for: Windows.MainWindow.instance, resizable: false, title: _("Install"), runnable: runnable, install_mode: install_mode); + this.callback = (owned) callback; + + Game? game = null; + + if(runnable is Game) + { + game = runnable as Game; + } + + get_style_context().add_class("rounded"); + get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + + modal = true; + + var hbox = new Box(Orientation.HORIZONTAL, 8); + hbox.margin_start = hbox.margin_end = 5; + + content = new Box(Orientation.VERTICAL, 0); + + title_label = Styled.H2Label(null); + title_label.margin_start = title_label.margin_end = 4; + title_label.halign = Align.START; + title_label.xalign = 0; + title_label.wrap = true; + title_label.max_width_chars = 36; + + var subtitle_hbox = new Box(Orientation.HORIZONTAL, 8); + + subtitle_label = new Label(null); + subtitle_label.margin_start = subtitle_label.margin_end = 4; + subtitle_label.halign = Align.START; + subtitle_label.valign = Align.CENTER; + subtitle_label.hexpand = true; + + if(game != null && game.icon != null) + { + var icon = new AutoSizeImage(); + icon.valign = Align.START; + icon.set_constraint(48, 48, 1); + icon.set_size_request(48, 48); + icon.load(game.icon, null, @"games/$(game.source.id)/$(game.id)/icons/"); + hbox.add(icon); + title_label.margin_start = title_label.margin_end = 8; + subtitle_label.margin_start = subtitle_label.margin_end = 8; + } + + hbox.add(content); + + subtitle_hbox.add(subtitle_label); + + content.add(title_label); + content.add(subtitle_hbox); + + title_label.label = runnable.name; + + var import_btn = add_button(_("Import"), InstallDialog.RESPONSE_IMPORT); + var dl_btn = add_button(_("Download"), InstallDialog.RESPONSE_DOWNLOAD); + var install_btn = add_button(_("Install"), ResponseType.ACCEPT); + install_btn.get_style_context().add_class(STYLE_CLASS_SUGGESTED_ACTION); + install_btn.grab_default(); + + var bbox = import_btn.get_parent() as ButtonBox; + if(bbox != null) + { + bbox.set_child_secondary(import_btn, true); + bbox.set_child_non_homogeneous(import_btn, true); + } + + platforms_list = new ModeButton(); + platforms_list.get_style_context().add_class("installer-platforms-list"); + platforms_list.halign = Align.END; + platforms_list.valign = Align.CENTER; + + installers_list = new ListBox(); + installers_list.get_style_context().add_class("installers-list"); + installers_list.margin_top = 4; + + installers_list.set_sort_func((row1, row2) => { + var item1 = row1 as InstallerRow; + var item2 = row2 as InstallerRow; + if(item1 != null && item2 != null) + { + var i1 = item1.installer; + var i2 = item2.installer; + + if(i1.platform.id() == Platform.CURRENT.id() && i2.platform.id() != Platform.CURRENT.id()) return -1; + if(i1.platform.id() != Platform.CURRENT.id() && i2.platform.id() == Platform.CURRENT.id()) return 1; + + return i1.name.collate(i2.name); + } + return 0; + }); + + var sys_langs = Intl.get_language_names(); + + var compatible_platforms = new ArrayList(); + + foreach(var installer in installers) + { + var row = new InstallerRow(runnable, installer); + installers_list.add(row); + + if(!(installer.platform in compatible_platforms)) + { + compatible_platforms.add(installer.platform); + } + + if(installer is GOGGame.Installer && (installer as GOGGame.Installer).lang in sys_langs) + { + installers_list.select_row(row); + } + else if(installers_list.get_selected_row() == null && installer.platform.id() == Platform.CURRENT.id()) + { + installers_list.select_row(row); + } + } + + installers_list.set_filter_func(installers_filter); + + platforms_list.mode_changed.connect(() => { + installers_list.invalidate_filter(); + foreach(var r in installers_list.get_children()) + { + var row = r as InstallerRow; + var selected_row = installers_list.get_selected_row() as InstallerRow; + if(selected_row == null || !installers_filter(selected_row)) + { + if(installers_filter(row) && (!(row.installer is GOGGame.Installer) || (row.installer as GOGGame.Installer).lang in sys_langs)) + { + installers_list.select_row(row); + break; + } + } + } + install_btn.sensitive = platforms_list.selected >= 0 && platforms_list.selected < Platform.PLATFORMS.length && Platform.PLATFORMS[platforms_list.selected] != Platform.MACOS; + }); + + platforms_list.selected = -1; + for(int i = 0; i < Platform.PLATFORMS.length; i++) + { + var icon = new Image.from_icon_name(Platform.PLATFORMS[i].icon(), IconSize.BUTTON); + icon.tooltip_text = Platform.PLATFORMS[i].name(); + platforms_list.append(icon); + var is_compatible = Platform.PLATFORMS[i] in compatible_platforms; + platforms_list.set_item_visible(i, is_compatible); + if(is_compatible && platforms_list.selected < 0) + { + platforms_list.selected = i; + } + } + + if(installers.size > 1) + { + subtitle_label.label = _("Select installer"); + content.add(installers_list); + if(compatible_platforms.size > 1) + { + subtitle_hbox.add(platforms_list); + } + } + else + { + subtitle_label.label = _("Installer size: %s").printf(fsize(installers[0].full_size)); + } + + Revealer? compat_tool_revealer = new Revealer(); + + var compat_tool_box = new Box(Orientation.VERTICAL, 4); + + compat_tool_picker = new CompatToolPicker(runnable, true); + compat_tool_picker.margin_start = game != null && game.icon != null ? 4 : 0; + compat_tool_picker.margin_top = 8; + + compat_tool_box.add(compat_tool_picker); + compat_tool_revealer.add(compat_tool_box); + + if(installers.size > 1) + { + compat_tool_revealer.reveal_child = false; + + installers_list.row_selected.connect(r => { + var row = r as InstallerRow; + if(row == null) + { + compat_tool_revealer.reveal_child = false; + } + else + { + var installer = row.installer; + compat_tool_revealer.reveal_child = installer.platform == Platform.WINDOWS; + dl_btn.sensitive = installer is Runnable.DownloadableInstaller; + } + }); + } + else + { + compat_tool_revealer.reveal_child = installers[0].platform == Platform.WINDOWS; + dl_btn.sensitive = installers[0] is Runnable.DownloadableInstaller; + } + + content.add(compat_tool_revealer); + + opts_list = new CompatToolOptions(runnable, compat_tool_picker, true); + compat_tool_box.add(opts_list); + + if(game is GameHub.Data.Sources.User.UserGame || runnable is GameHub.Data.Emulator) + { + subtitle_label.no_show_all = true; + subtitle_label.visible = false; + dl_btn.no_show_all = true; + dl_btn.visible = false; + import_btn.no_show_all = true; + import_btn.visible = false; + compat_tool_revealer.reveal_child = true; + } + + response.connect((source, response_id) => { + switch(response_id) + { + case ResponseType.CLOSE: + destroy(); + if(callback != null) callback(); + break; + + case InstallDialog.RESPONSE_IMPORT: + runnable.import(); + destroy(); + if(callback != null) callback(); + break; + + case ResponseType.ACCEPT: + case InstallDialog.RESPONSE_DOWNLOAD: + var installer = installers[0]; + if(installers.size > 1) + { + var row = installers_list.get_selected_row() as InstallerRow; + if(row != null) installer = row.installer; + } + if(opts_list != null) + { + opts_list.save_options(); + } + install_or_download.begin(response_id, installer, compat_tool_picker != null ? compat_tool_picker.selected : null); + destroy(); + break; + } + }); + + get_content_area().add(hbox); + get_content_area().set_size_request(380, 96); + + if(install_mode != Runnable.Installer.InstallMode.INTERACTIVE) + { + Idle.add(() => { + response(install_mode == Runnable.Installer.InstallMode.AUTOMATIC ? ResponseType.ACCEPT : InstallDialog.RESPONSE_DOWNLOAD); + hide(); + return Source.REMOVE; + }); + return; + } + + if(install_mode == Runnable.Installer.InstallMode.INTERACTIVE) + { + show_all(); + present(); + } + } + + private async void install_or_download(int response_id, Runnable.Installer installer, CompatTool? tool=null) + { + if(installer is Runnable.DownloadableInstaller) + { + var dl_installer = (Runnable.DownloadableInstaller) installer; + + yield dl_installer.fetch_parts(); + + if(response_id == InstallDialog.RESPONSE_DOWNLOAD) + { + yield dl_installer.download(runnable); + } + } + if(response_id == ResponseType.ACCEPT) + { + yield installer.install(runnable, tool); + } + if(callback != null) callback(); + } + + public static string fsize(int64 size) + { + if(size > 0) + { + return format_size(size); + } + return _("Unknown"); + } + + private bool installers_filter(ListBoxRow row) + { + var item = row as InstallerRow; + return item != null && platforms_list.selected >= 0 && platforms_list.selected < Platform.PLATFORMS.length && item.installer.platform == Platform.PLATFORMS[platforms_list.selected]; + } + + private class InstallerRow: ListBoxRow + { + public Runnable runnable; + public Runnable.Installer installer; + + public InstallerRow(Runnable runnable, Runnable.Installer installer) + { + this.runnable = runnable; + this.installer = installer; + + var box = new Box(Orientation.HORIZONTAL, 8); + box.margin_start = box.margin_end = 8; + box.margin_top = box.margin_bottom = 4; + + var icon = new Image.from_icon_name(installer.platform.icon(), IconSize.BUTTON); + + var name = new Label(installer.name); + name.hexpand = true; + name.halign = Align.START; + + var size = new Label(fsize(installer.full_size)); + size.halign = Align.END; + + box.add(icon); + box.add(name); + box.add(size); + child = box; + } + } + } +} diff --git a/src/ui/dialogs/SettingsDialog/SettingsDialog.vala b/src/ui/dialogs/SettingsDialog/SettingsDialog.vala new file mode 100644 index 00000000..2c15973f --- /dev/null +++ b/src/ui/dialogs/SettingsDialog/SettingsDialog.vala @@ -0,0 +1,168 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using GameHub.UI.Widgets; + +using GameHub.Utils; + +namespace GameHub.UI.Dialogs.SettingsDialog +{ + public class SettingsDialog: Dialog + { + private static bool restart_msg_shown = false; + private static bool games_dir_space_msg_shown = false; + + private InfoBar restart_msg; + private InfoBar games_dir_space_msg; + + private Stack pages; + + private string default_page; + + public SettingsDialog(string page="ui/appearance") + { + Object(transient_for: Windows.MainWindow.instance, resizable: false, title: _("Settings")); + default_page = page; + } + + construct + { + get_style_context().add_class("settings-dialog"); + get_style_context().add_class("rounded"); + get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + + var ui_settings = GameHub.Settings.UI.Appearance.instance; + ui_settings.notify["dark-theme"].connect(() => { + get_style_context().remove_class("dark"); + if(ui_settings.dark_theme) get_style_context().add_class("dark"); + }); + ui_settings.notify_property("dark-theme"); + + gravity = Gdk.Gravity.NORTH; + modal = true; + + var content = get_content_area(); + content.set_size_request(860, 540); + + restart_msg = new InfoBar(); + restart_msg.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME); + restart_msg.get_content_area().add(new Label(_("Some settings will be applied after application restart"))); + restart_msg.message_type = MessageType.INFO; + restart_msg.show_all(); + + games_dir_space_msg = new InfoBar(); + games_dir_space_msg.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME); + games_dir_space_msg.get_content_area().add(new Label(_("Games directory contains space. It may cause problems for some games"))); + games_dir_space_msg.message_type = MessageType.WARNING; + games_dir_space_msg.show_all(); + games_dir_space_msg.margin_bottom = 8; + + update_messages(); + + pages = new Stack(); + pages.homogeneous = false; + pages.interpolate_size = true; + + add_page("ui/appearance", new Pages.UI.Appearance(this)); + add_page("ui/behavior", new Pages.UI.Behavior(this)); + + add_page("general/collection", new Pages.General.Collection(this)); + add_page("general/tweaks", new Pages.General.Tweaks(this)); + #if MANETTE + add_page("general/controller", new Pages.General.Controller(this)); + #endif + + add_page("sources/steam", new Pages.Sources.Steam(this)); + add_page("sources/gog", new Pages.Sources.GOG(this)); + add_page("sources/humble", new Pages.Sources.Humble(this)); + add_page("sources/itch", new Pages.Sources.Itch(this)); + + add_page("emulators/retroarch", new Pages.Emulators.RetroArch(this)); + add_page("emulators/custom", new Pages.Emulators.Emulators(this)); + + add_page("providers/providers", new Pages.Providers.Providers(this)); + + add_page("about", new Pages.About(this)); + + var sidebar = new SettingsSidebar(pages); + sidebar.get_style_context().add_class("settings-pages-sidebar"); + + var content_hbox = new Box(Orientation.HORIZONTAL, 1); + var content_root = new Box(Orientation.VERTICAL, 0); + + content_root.add(restart_msg); + content_root.add(games_dir_space_msg); + content_root.add(pages); + + content_hbox.add(sidebar); + content_hbox.add(content_root); + + content.add(content_hbox); + + response.connect((source, response_id) => { + switch(response_id) + { + case ResponseType.CLOSE: + destroy(); + break; + } + }); + + show_all(); + + get_action_area().visible = false; + + Idle.add(() => { + pages.visible_child_name = default_page; + sidebar.visible_child_name = default_page; + return Source.REMOVE; + }); + } + + private void add_page(string id, SettingsSidebar.SettingsPage page) + { + pages.add_named(page, id); + } + + public void show_restart_message() + { + restart_msg_shown = true; + update_messages(); + } + + public void update_games_dir_space_message() + { + var paths = FSUtils.Paths.Settings.instance; + games_dir_space_msg_shown = " " in paths.gog_games || " " in paths.humble_games; + update_messages(); + } + + private void update_messages() + { + restart_msg.visible = restart_msg_shown; + restart_msg.no_show_all = !restart_msg_shown; + games_dir_space_msg.visible = games_dir_space_msg_shown; + games_dir_space_msg.no_show_all = !games_dir_space_msg_shown; + #if GTK_3_22 + restart_msg.revealed = restart_msg_shown; + games_dir_space_msg.revealed = games_dir_space_msg_shown; + #endif + } + } +} diff --git a/src/ui/dialogs/SettingsDialog/SettingsDialogPage.vala b/src/ui/dialogs/SettingsDialog/SettingsDialogPage.vala new file mode 100644 index 00000000..128ddadf --- /dev/null +++ b/src/ui/dialogs/SettingsDialog/SettingsDialogPage.vala @@ -0,0 +1,209 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using GameHub.UI.Widgets; + +using GameHub.Utils; + +namespace GameHub.UI.Dialogs.SettingsDialog +{ + public abstract class SettingsDialogPage: SettingsSidebar.SimpleSettingsPage + { + public SettingsDialog dialog { construct; protected get; } + + public bool restart_requested = false; + + protected Grid root_grid; + protected Grid header_grid; + + construct + { + content_area.orientation = Orientation.VERTICAL; + content_area.row_spacing = 0; + + root_grid = content_area.get_parent() as Grid; + header_grid = root_grid.get_child_at(0, 0) as Grid; + + header_grid.row_spacing = 0; + + var description_label = header_grid.get_child_at(1, 1) as Label; + if(description_label != null) + { + description_label.use_markup = true; + } + } + + protected void request_restart() + { + status_type = StatusType.WARNING; + dialog.show_restart_message(); + restart_requested = true; + } + + protected Box add_switch(string text, bool enabled, owned SwitchAction action) + { + var sw = new Switch(); + sw.active = enabled; + sw.halign = Align.END; + sw.notify["active"].connect(() => { action(sw.active); }); + + var label = new Label(text); + label.halign = Align.START; + label.hexpand = true; + + var hbox = new Box(Orientation.HORIZONTAL, 12); + hbox.add(label); + hbox.add(sw); + return add_widget(hbox); + } + + protected Box add_entry(string? text, string val, owned EntryAction action, string? icon=null) + { + var entry = new Entry(); + entry.text = val; + entry.notify["text"].connect(() => { action(entry.text); }); + entry.set_size_request(280, -1); + + entry.primary_icon_name = icon; + + var hbox = new Box(Orientation.HORIZONTAL, 12); + + if(text != null) + { + var label = new Label(text); + label.halign = Align.START; + label.hexpand = true; + hbox.add(label); + } + else + { + entry.hexpand = true; + } + + hbox.add(entry); + return add_widget(hbox); + } + + protected Box add_file_chooser(string text, FileChooserAction mode, string val, owned EntryAction action, bool create=true, string? icon=null, bool allow_url=false, bool allow_executable=false) + { + var chooser = new FileChooserEntry(text, mode, icon, null, allow_url, allow_executable); + chooser.chooser.create_folders = create; + chooser.chooser.show_hidden = true; + chooser.select_file(FSUtils.file(val)); + chooser.tooltip_text = chooser.file.get_path(); + chooser.file_set.connect(() => { chooser.tooltip_text = chooser.file != null ? chooser.file.get_path() : null; action(chooser.tooltip_text); }); + chooser.set_size_request(280, -1); + + var label = new Label(text); + label.halign = Align.START; + label.hexpand = true; + + var hbox = new Box(Orientation.HORIZONTAL, 12); + hbox.add(label); + hbox.add(chooser); + return add_widget(hbox); + } + + protected Label add_label(string text, bool use_markup=false) + { + var label = new Label(text); + label.halign = Align.START; + label.hexpand = true; + label.use_markup = use_markup; + return add_widget(label); + } + + protected Box add_labels(string text, string text2, bool use_markup=false) + { + var label = new Label(text); + label.max_width_chars = 52; + label.xalign = 0; + label.wrap = true; + label.halign = Align.START; + label.hexpand = true; + label.use_markup = use_markup; + + var label2 = new Label(text2); + label2.xalign = 0; + label2.wrap = true; + label2.use_markup = use_markup; + label2.set_size_request(280, -1); + + var hbox = new Box(Orientation.HORIZONTAL, 12); + hbox.add(label); + hbox.add(label2); + return add_widget(hbox); + } + + protected Label add_header(string text) + { + var label = Styled.H4Label(text); + label.xpad = 4; + label.halign = Align.START; + label.hexpand = true; + return add_widget(label); + } + + protected LinkButton add_link(string text, string uri) + { + var link = new LinkButton.with_label(uri, text); + link.halign = Align.START; + link.hexpand = true; + return add_widget(link); + } + + protected Box add_labeled_link(string label_text, string text, string uri) + { + var label = new Label(label_text); + label.max_width_chars = 52; + label.xalign = 0; + label.wrap = true; + label.halign = Align.START; + label.hexpand = true; + + var link = new LinkButton.with_label(uri, text); + link.halign = Align.END; + + var hbox = new Box(Orientation.HORIZONTAL, 12); + hbox.add(label); + hbox.add(link); + return add_widget(hbox); + } + + protected Separator add_separator() + { + return add_widget(new Separator(Orientation.HORIZONTAL)); + } + + protected T add_widget(T widget) + { + if(!((widget as Widget).get_style_context().has_class(StyleClass.Label.H4))) + { + (widget as Widget).margin = 4; + (widget as Widget).margin_end = 0; + } + content_area.add(widget as Widget); + return widget; + } + + public delegate void SwitchAction(bool active); + public delegate void EntryAction(string val); + public delegate void ButtonAction(); + } +} diff --git a/src/ui/dialogs/SettingsDialog/pages/About.vala b/src/ui/dialogs/SettingsDialog/pages/About.vala new file mode 100644 index 00000000..67d3f26b --- /dev/null +++ b/src/ui/dialogs/SettingsDialog/pages/About.vala @@ -0,0 +1,174 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using GameHub.UI.Widgets; + +using GameHub.Utils; + +namespace GameHub.UI.Dialogs.SettingsDialog.Pages +{ + public class About: SettingsSidebar.SettingsPage + { + private Settings.UI.Appearance ui_settings; + + private Box links_view; + private Box small_links_view; + + public About(SettingsDialog dlg) + { + Object( + header: _("About"), + title: "GameHub", + status: ProjectConfig.VERSION, + icon_name: ProjectConfig.PROJECT_NAME + ); + } + + construct + { + ui_settings = Settings.UI.Appearance.instance; + + var content_vbox = new Box(Orientation.VERTICAL, 8); + content_vbox.expand = true; + + var content_hbox = new Box(Orientation.HORIZONTAL, 0); + content_hbox.margin = 12; + + var logo = new Image.from_icon_name(ProjectConfig.PROJECT_NAME, IconSize.DIALOG); + logo.valign = Align.START; + + var appinfo_grid = new Grid(); + appinfo_grid.margin_start = 12; + appinfo_grid.row_spacing = 0; + appinfo_grid.column_spacing = 8; + + var app_title = Styled.H2Label("GameHub"); + app_title.hexpand = true; + app_title.xalign = 0; + + var app_version = new Label(ProjectConfig.VERSION); + app_version.hexpand = true; + app_version.xalign = 0; + app_version.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL); + + var app_info_copy = new Button.from_icon_name("edit-copy-symbolic", IconSize.BUTTON); + app_info_copy.tooltip_text = _("Copy application version and environment info"); + app_info_copy.get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + app_info_copy.set_size_request(36, 36); + app_info_copy.halign = app_info_copy.valign = Align.CENTER; + + app_info_copy.clicked.connect(copy_app_info); + + var app_subtitle = Styled.H3Label(_("All your games in one place")); + app_subtitle.margin_top = 4; + app_subtitle.hexpand = true; + app_subtitle.xalign = 0; + + appinfo_grid.attach(app_title, 0, 0); + appinfo_grid.attach(app_version, 0, 1); + appinfo_grid.attach(app_info_copy, 1, 0, 1, 2); + appinfo_grid.attach(app_subtitle, 0, 2); + + links_view = new Box(Orientation.VERTICAL, 2); + links_view.expand = true; + links_view.margin = 4; + + add_link(C_("about_link", "Website"), "https://tkashkin.tk/projects/gamehub", "web-browser-symbolic"); + + var source_mirrors = new Box(Orientation.HORIZONTAL, 0); + + add_link(C_("about_link", "Source code on GitHub"), "https://github.com/tkashkin/GameHub", "about-link-github-symbolic", source_mirrors).hexpand = true; + add_link(null, "https://codeberg.org/tkashkin/GameHub", "about-link-codeberg.org", source_mirrors).hexpand = false; + add_link(null, "https://repo.or.cz/GameHub.git", "about-link-git-symbolic", source_mirrors).hexpand = false; + add_link(null, "https://git.froggi.es/tkashkin/gamehub", "about-link-git.froggi.es", source_mirrors).hexpand = false; + + links_view.add(source_mirrors); + + add_link(C_("about_link", "Report a problem"), "https://github.com/tkashkin/GameHub/issues/new/choose", "dialog-warning-symbolic"); + add_link(C_("about_link", "Suggest translations"), "https://hosted.weblate.org/engage/gamehub", "preferences-desktop-locale-symbolic"); + + small_links_view = new Box(Orientation.HORIZONTAL, 8); + small_links_view.margin = 8; + small_links_view.halign = Align.END; + + add_small_link(C_("about_link", "Issues"), "https://github.com/tkashkin/GameHub/issues"); + add_small_link(C_("about_link", "Contributors"), "https://github.com/tkashkin/GameHub/graphs/contributors"); + + // TRANSLATORS: Likely it should not be translated. GitHub Pulse is a page that shows recent repository activity: https://github.com/tkashkin/GameHub/pulse + add_small_link(C_("about_link", "Pulse"), "https://github.com/tkashkin/GameHub/pulse"); + add_small_link(C_("about_link", "Forks"), "https://github.com/tkashkin/GameHub/network"); + + content_hbox.add(logo); + content_hbox.add(appinfo_grid); + + content_vbox.add(content_hbox); + content_vbox.add(links_view); + content_vbox.add(small_links_view); + + add(content_vbox); + } + + private void copy_app_info() + { + var info = "- GameHub\n" + + " Version: %s\n".printf(ProjectConfig.VERSION) + + " Branch: %s\n".printf(ProjectConfig.GIT_BRANCH); + + if(ProjectConfig.GIT_COMMIT != null && ProjectConfig.GIT_COMMIT.length > 0) + { + info += " Commit: %s\n".printf(ProjectConfig.GIT_COMMIT); + } + + info += "- Environment\n"; + #if OS_LINUX + info += " Distro: %s\n".printf(Utils.get_distro()); + info += " DE: %s\n".printf(Utils.get_desktop_environment() ?? "unknown"); + #else + info += " OS: %s\n".printf(Utils.get_distro()); + #endif + info += " GTK: %u.%u.%u\n".printf(Gtk.get_major_version(), Gtk.get_minor_version(), Gtk.get_micro_version()); + + var settings = Gtk.Settings.get_default(); + if(settings != null) + { + info += " Themes: %s | %s".printf(settings.gtk_theme_name, settings.gtk_icon_theme_name); + } + + Clipboard.get_default(Gdk.Display.get_default()).set_text(info, info.length); + } + + private GameHub.UI.Widgets.ActionButton add_link(string? title, string url, string icon="web-browser", Container? parent=null) + { + var button = new GameHub.UI.Widgets.ActionButton(icon, null, title ?? url, title != null, true); + button.tooltip_text = url; + + button.clicked.connect(() => { + Utils.open_uri(url); + }); + + (parent ?? links_view).add(button); + return button; + } + + private void add_small_link(string title, string url) + { + small_links_view.add(new LinkButton.with_label(url, title)); + } + } +} diff --git a/src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala b/src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala new file mode 100644 index 00000000..ff3b271b --- /dev/null +++ b/src/ui/dialogs/SettingsDialog/pages/emulators/Emulators.vala @@ -0,0 +1,522 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; + + +using GameHub.Data; +using GameHub.Utils; + +using GameHub.UI.Widgets; + +using GameHub.Data.DB; + +namespace GameHub.UI.Dialogs.SettingsDialog.Pages.Emulators +{ + public class Emulators: SettingsSidebar.SettingsPage + { + public SettingsDialog dialog { construct; protected get; } + + private Stack stack; + private Button add_btn; + private Button remove_btn; + + private EmulatorPage? previous_page; + + public Emulators(SettingsDialog dlg) + { + Object( + dialog: dlg, + title: _("Emulators"), + status: _("No custom emulators"), + icon_name: "application-x-executable-symbolic" + ); + } + + construct + { + var paths = FSUtils.Paths.Settings.instance; + + var content_hbox = new Box(Orientation.HORIZONTAL, 0); + + stack = new Stack(); + stack.expand = true; + + var sidebar_box = new Box(Orientation.VERTICAL, 0); + sidebar_box.vexpand = true; + + var sidebar = new StackSidebar(); + sidebar.stack = stack; + sidebar.get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + sidebar.vexpand = true; + sidebar.set_size_request(128, -1); + + var actionbar = new ActionBar(); + actionbar.vexpand = false; + + add_btn = new Button.from_icon_name("list-add-symbolic", IconSize.MENU); + add_btn.get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + + remove_btn = new Button.from_icon_name("list-remove-symbolic", IconSize.MENU); + remove_btn.get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + + var actions = new Box(Orientation.HORIZONTAL, 0); + actions.get_style_context().add_class(Gtk.STYLE_CLASS_LINKED); + + actions.add(add_btn); + actions.add(remove_btn); + + actionbar.pack_start(actions); + + sidebar_box.add(sidebar); + sidebar_box.add(actionbar); + + content_hbox.add(sidebar_box); + content_hbox.add(new Separator(Orientation.VERTICAL)); + content_hbox.add(stack); + + add(content_hbox); + + stack.notify["visible-child"].connect(() => { + var page = stack.visible_child as EmulatorPage; + if(previous_page != null && previous_page != page) + { + previous_page.save(); + } + previous_page = page; + }); + + dialog.destroy.connect(() => { + if(previous_page != null) + { + previous_page.save(); + } + }); + + add_btn.clicked.connect(() => { + add_emu_page(); + }); + + remove_btn.clicked.connect(() => { + remove_emu_page(); + }); + + var emulators = Tables.Emulators.get_all(); + foreach(var emu in emulators) + { + add_emu_page(emu); + } + + Idle.add(() => { + update(); + return Source.REMOVE; + }); + } + + private void add_emu_page(Emulator? emulator=null) + { + var page = new EmulatorPage(stack, emulator); + var id = emulator != null ? "emu/" + emulator.id : stack.get_children().length().to_string(); + stack.add_titled(page, id, emulator != null ? emulator.name : ""); + page.show_all(); + if(emulator == null) + { + stack.set_visible_child(page); + } + page.emulator.removed.connect(() => { + stack.remove(page); + update(); + }); + update(); + } + + private void remove_emu_page() + { + var page = stack.visible_child as EmulatorPage; + if(page != null) + { + page.remove(); + update(); + } + } + + private void update() + { + var count = stack.get_children().length(); + remove_btn.sensitive = count > 0; + if(count > 0) + { + status = ngettext("%u custom emulator", "%u custom emulators", count).printf(count); + } + else + { + status = _("No custom emulators"); + } + } + + private class EmulatorPage: Box + { + private string _title; + public string title + { + get + { + return _title; + } + set + { + _title = value.strip(); + if(parent == stack) + { + stack.child_set(this, title: _title); + } + } + } + public Stack stack { get; construct; } + public Emulator emulator { get; construct set; } + + private Grid grid; + private int rows = 0; + + private ModeButton mode; + + private new Entry name; + private FileChooserEntry emudir; + private FileChooserEntry executable; + private Label executable_label; + private Entry arguments; + private Label arguments_label; + + private Entry game_executable_pattern; + private Label game_executable_pattern_label; + private Entry game_image_pattern; + private Label game_image_pattern_label; + private Entry game_icon_pattern; + private Label game_icon_pattern_label; + + private Button run_btn; + private Button save_btn; + + public EmulatorPage(Stack stack, Emulator? emulator=null) + { + Object(orientation: Orientation.VERTICAL, stack: stack, emulator: emulator ?? new Emulator.empty()); + } + + construct + { + grid = new Grid(); + grid.margin = 6; + grid.expand = true; + grid.row_spacing = 4; + grid.column_spacing = 8; + + var grid_scroll = new ScrolledWindow(null, null); + grid_scroll.get_style_context().add_class(Gtk.STYLE_CLASS_VIEW); + grid_scroll.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME); + grid_scroll.margin_start = grid_scroll.margin_end = 1; + grid_scroll.expand = true; + + grid_scroll.add(grid); + add(grid_scroll); + + save_btn = new Button.with_label(_("Save")); + save_btn.halign = Align.END; + save_btn.valign = Align.END; + save_btn.sensitive = false; + + run_btn = new Button.with_label(_("Run")); + run_btn.halign = Align.START; + run_btn.valign = Align.END; + run_btn.sensitive = false; + + mode = new ModeButton(); + mode.margin_bottom = 8; + mode.halign = Align.CENTER; + mode.append_text(_("Executable")); + mode.append_text(_("Installer")); + mode.selected = 0; + grid.attach(mode, 0, rows, 2, 1); + rows++; + + name = add_entry(_("Name"), "insert-text-symbolic", true); + + name.text = emulator.name ?? ""; + + name.changed.connect(() => { + title = name.text.strip(); + Tables.Emulators.remove(emulator); + emulator.name = title; + }); + + name.changed(); + + add_separator(); + + executable = add_filechooser(_("Executable"), _("Select executable"), FileChooserAction.OPEN, true, out executable_label); + + arguments = add_entry(_("Arguments"), "utilities-terminal-symbolic", false, out arguments_label); + arguments.text = emulator.arguments ?? "$file $game_args"; + + arguments.tooltip_markup = + """%s""".printf(_("Variables")) + "\n\n" + + """$file - %s""".printf(_("Game executable")) + "\n" + + """$game_args - %s""".printf(_("Game arguments")); + + arguments.changed.connect(() => { + emulator.arguments = arguments.text.strip(); + }); + + arguments.changed(); + + add_separator(); + + emudir = add_filechooser(_("Directory"), _("Select emulator directory"), FileChooserAction.SELECT_FOLDER, true); + + add_separator(); + + var compat_force_switch = add_switch(_("Force compatibility mode"), emulator.force_compat, f => { emulator.force_compat = f; }); + compat_force_switch.no_show_all = true; + + var compat_tool = new CompatToolPicker(emulator, false, true); + compat_tool.no_show_all = true; + grid.attach(compat_tool, 0, rows, 2, 1); + rows++; + + emulator.notify["use-compat"].connect(() => { + compat_force_switch.visible = !emulator.needs_compat; + compat_tool.visible = emulator.use_compat; + }); + + add_separator(); + + var patterns_header = Styled.H4Label(_("Game file patterns")); + patterns_header.margin_start = patterns_header.margin_end = 4; + grid.attach(patterns_header, 0, rows, 2, 1); + rows++; + + game_executable_pattern = add_entry(_("Executable"), "application-x-executable", false, out game_executable_pattern_label); + game_executable_pattern.placeholder_text = "*.bin|*.rom|./code/*.rpx"; + + game_image_pattern = add_entry(_("Image"), "image-x-generic", false, out game_image_pattern_label); + game_image_pattern.placeholder_text = "./cover.png|./meta/bootTvTex.tga"; + + game_icon_pattern = add_entry(_("Icon"), "image-x-generic-symbolic", false, out game_icon_pattern_label); + game_icon_pattern.placeholder_text = "./icon.png|./meta/iconTex.tga"; + + game_executable_pattern.text = emulator.game_executable_pattern ?? ""; + game_image_pattern.text = emulator.game_image_pattern ?? ""; + game_icon_pattern.text = emulator.game_icon_pattern ?? ""; + + var patterns_syntax = new Label(_("findutils-compatible glob patterns\n\n Multiple patterns can be separated with |\n Start pattern with ./ to match relative path\n $basename variable will be replaced with game's executable name (without extension)")); + patterns_syntax.wrap = true; + patterns_syntax.use_markup = true; + patterns_syntax.xalign = 0; + + var patterns_syntax_info = new InfoBar(); + patterns_syntax_info.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME); + patterns_syntax_info.get_style_context().add_class("settings-info"); + patterns_syntax_info.message_type = MessageType.INFO; + patterns_syntax_info.get_content_area().add(patterns_syntax); + + grid.attach(patterns_syntax_info, 0, rows, 2, 1); + rows++; + + var btn_box = new Box(Orientation.HORIZONTAL, 0); + btn_box.margin_start = btn_box.margin_end = 8; + btn_box.margin_top = btn_box.margin_bottom = 4; + + btn_box.pack_start(run_btn); + btn_box.pack_end(save_btn); + + add(btn_box); + + run_btn.clicked.connect(run); + save_btn.clicked.connect(save); + + mode.mode_changed.connect(update); + + executable.file_set.connect(() => { + emulator.executable = executable.file; + if(name.text.strip().length == 0 && executable.file != null) + { + name.text = executable.file.get_basename(); + } + update(); + }); + + if(emulator.install_dir != null && emulator.install_dir.query_exists()) + { + try + { + emudir.select_file(emulator.install_dir); + } + catch(Error e) + { + warning(e.message); + } + } + + if(emulator.executable != null && emulator.executable.query_exists()) + { + try + { + executable.select_file(emulator.executable); + } + catch(Error e) + { + warning(e.message); + } + } + + update(); + } + + private void update() + { + if(mode.selected == 0 && executable.file != null && emudir.file == null) + { + emudir.select_file(executable.file.get_parent()); + } + + emulator.name = title; + emulator.arguments = arguments.text.strip(); + emulator.game_executable_pattern = game_executable_pattern.text.strip(); + emulator.game_image_pattern = game_image_pattern.text.strip(); + emulator.game_icon_pattern = game_icon_pattern.text.strip(); + + emulator.install_dir = emudir.file; + + executable_label.label = mode.selected == 0 ? _("Executable") : _("Installer"); + arguments.sensitive = arguments_label.sensitive = mode.selected == 0; + + run_btn.sensitive = emulator.name.length > 0 && executable.file != null && mode.selected == 0 && emudir.file != null; + save_btn.sensitive = emulator.name.length > 0 && executable.file != null && ((mode.selected == 0 && emudir.file != null) || mode.selected == 1); + + emulator.notify_property("use-compat"); + } + + public void save() + { + update(); + + if(mode.selected == 1 && executable.file != null && emudir.file != null) + { + sensitive = false; + + emulator.installer = new Emulator.Installer(emulator, emulator.executable); + + emulator.executable = null; + emulator.install.begin(Runnable.Installer.InstallMode.INTERACTIVE, (obj, res) => { + emulator.install.end(res); + sensitive = true; + mode.selected = 0; + executable.select_file(emulator.executable); + emulator.save(); + }); + + return; + } + + emulator.save(); + } + + public void run() + { + save(); + emulator.run_game.begin(null); + } + + public new void remove() + { + emulator.remove(); + } + + private Entry add_entry(string text, string icon, bool required=true, out Label label=null) + { + label = new Label(text); + label.halign = Align.START; + label.xalign = 1; + label.margin = 4; + label.hexpand = true; + if(required) + { + label.get_style_context().add_class("category-label"); + } + var entry = new Entry(); + entry.primary_icon_name = icon; + entry.primary_icon_activatable = false; + entry.set_size_request(280, -1); + grid.attach(label, 0, rows); + grid.attach(entry, 1, rows); + rows++; + return entry; + } + + private FileChooserEntry add_filechooser(string text, string title, FileChooserAction action=FileChooserAction.OPEN, bool required=true, out Label label=null) + { + label = new Label(text); + label.halign = Align.START; + label.xalign = 1; + label.margin = 4; + label.hexpand = true; + if(required) + { + label.get_style_context().add_class("category-label"); + } + var entry = new FileChooserEntry(title, action, null, null, false, action == FileChooserAction.OPEN); + entry.set_size_request(280, -1); + grid.attach(label, 0, rows); + grid.attach(entry, 1, rows); + rows++; + return entry; + } + + private void add_separator() + { + var separator = new Separator(Orientation.HORIZONTAL); + separator.margin_top = separator.margin_bottom = 2; + grid.attach(separator, 0, rows, 2, 1); + rows++; + } + + private Box add_switch(string text, bool enabled, owned SettingsDialogPage.SwitchAction action) + { + var sw = new Switch(); + sw.active = enabled; + sw.halign = Align.END; + sw.notify["active"].connect(() => { action(sw.active); }); + + var label = new Label(text); + label.halign = Align.START; + label.hexpand = true; + + var hbox = new Box(Orientation.HORIZONTAL, 12); + hbox.margin_start = 4; + + hbox.add(label); + hbox.add(sw); + + hbox.show_all(); + + grid.attach(hbox, 0, rows, 2, 1); + rows++; + return hbox; + } + } + } +} diff --git a/src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala b/src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala new file mode 100644 index 00000000..334ecf2f --- /dev/null +++ b/src/ui/dialogs/SettingsDialog/pages/emulators/RetroArch.vala @@ -0,0 +1,79 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; + +using GameHub.Utils; + +namespace GameHub.UI.Dialogs.SettingsDialog.Pages.Emulators +{ + public class RetroArch: SettingsDialogPage + { + private Settings.Compat.RetroArch settings; + + public RetroArch(SettingsDialog dlg) + { + Object( + dialog: dlg, + header: _("Emulators"), + description: _("Not installed"), + title: "RetroArch", + icon_name: "emu-retroarch-symbolic" + ); + status = description; + } + + construct + { + settings = Settings.Compat.RetroArch.instance; + + add_file_chooser(_("Libretro core directory"), FileChooserAction.SELECT_FOLDER, settings.core_dir, v => { settings.core_dir = v; update(); request_restart(); }); + add_file_chooser(_("Libretro core info directory"), FileChooserAction.SELECT_FOLDER, settings.core_info_dir, v => { settings.core_info_dir = v; request_restart(); }); + + add_separator(); + + add_header(_("Ignored libretro cores")); + var cores_blacklist = add_entry(null, settings.cores_blacklist, v => { settings.cores_blacklist = v; update(); }, "application-x-executable-symbolic").get_children().last().data as Entry; + cores_blacklist.placeholder_text = settings.schema.get_default_value("cores-blacklist").get_string(); + + add_header(_("Ignored game file extensions")); + var game_executable_extensions_blacklist = add_entry(null, settings.game_executable_extensions_blacklist, v => { settings.game_executable_extensions_blacklist = v; update(); }, "package-x-generic-symbolic").get_children().last().data as Entry; + game_executable_extensions_blacklist.placeholder_text = settings.schema.get_default_value("game-executable-extensions-blacklist").get_string(); + + update(); + } + + private void update() + { + var retroarch = GameHub.Data.Compat.RetroArch.instance; + if(retroarch.installed) + { + status = description = _("No cores found"); + if(retroarch.has_cores) + { + var cores = retroarch.cores.size; + status = description = ngettext("%u core found", "%u cores found", cores).printf(cores); + } + } + else + { + status = description = _("Not installed"); + } + } + } +} diff --git a/src/ui/dialogs/SettingsDialog/pages/general/Collection.vala b/src/ui/dialogs/SettingsDialog/pages/general/Collection.vala new file mode 100644 index 00000000..24ee90a4 --- /dev/null +++ b/src/ui/dialogs/SettingsDialog/pages/general/Collection.vala @@ -0,0 +1,148 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; + + +using GameHub.Data; +using GameHub.Utils; +using GameHub.UI.Widgets; + +namespace GameHub.UI.Dialogs.SettingsDialog.Pages.General +{ + public class Collection: SettingsDialogPage + { + private FSUtils.Paths.Collection collection; + private FSUtils.Paths.Collection.GOG gog; + private FSUtils.Paths.Collection.Humble humble; + + private FileChooserEntry collection_root; + + private Entry gog_game_dir; + private Entry gog_installers; + private Entry gog_dlc; + private Entry gog_bonus; + + private Entry humble_game_dir; + private Entry humble_installers; + + private int syntax_info_grid_rows = 0; + private Grid syntax_info_grid; + + public Collection(SettingsDialog dlg) + { + Object( + dialog: dlg, + header: _("General"), + title: _("Collection"), + description: _("Empty"), + icon_name: "folder-download" + ); + status = description; + } + + construct + { + collection = FSUtils.Paths.Collection.instance; + gog = FSUtils.Paths.Collection.GOG.instance; + humble = FSUtils.Paths.Collection.Humble.instance; + + collection_root = add_file_chooser(_("Collection directory"), FileChooserAction.SELECT_FOLDER, collection.root, v => { collection.root = v; update(); }).get_children().last().data as FileChooserEntry; + + add_separator(); + + add_header("GOG"); + gog_game_dir = add_entry(_("Game directory") + " ($game_dir)", gog.game_dir, v => { gog.game_dir = v; update(); }, "source-gog-symbolic").get_children().last().data as Entry; + gog_installers = add_entry(_("Installers"), gog.installers, v => { gog.installers = v; update(); }, "source-gog-symbolic").get_children().last().data as Entry; + gog_dlc = add_entry(_("DLC"), gog.dlc, v => { gog.dlc = v; update(); }, "folder-download-symbolic").get_children().last().data as Entry; + gog_bonus = add_entry(_("Bonus content"), gog.bonus, v => { gog.bonus = v; update(); }, "folder-music-symbolic").get_children().last().data as Entry; + + add_separator(); + + add_header("Humble Bundle"); + humble_game_dir = add_entry(_("Game directory") + " ($game_dir)", humble.game_dir, v => { humble.game_dir = v; update(); }, "source-humble-symbolic").get_children().last().data as Entry; + humble_installers = add_entry(_("Installers"), humble.installers, v => { humble.installers = v; update(); }, "source-humble-symbolic").get_children().last().data as Entry; + + syntax_info_grid = new Grid(); + syntax_info_grid.column_spacing = 72; + + syntax_info_label(_("Variable syntax: $var or ${var}")); + syntax_info_label(" $root", _("Collection directory")); + syntax_info_label(" $game", _("Game name")); + syntax_info_label(" $game_dir", _("Game directory")); + syntax_info_label(" $platform, $platform_name", _("Platform")); + + var syntax_info = new InfoBar(); + syntax_info.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME); + syntax_info.get_style_context().add_class("settings-info"); + syntax_info.message_type = MessageType.INFO; + syntax_info.get_content_area().add(syntax_info_grid); + + add_widget(syntax_info); + syntax_info.margin = 0; + + update(); + } + + private void update() + { + var game = "Game"; + + gog_game_dir.tooltip_text = FSUtils.Paths.Collection.GOG.expand_game_dir(game); + gog_installers.tooltip_text = FSUtils.Paths.Collection.GOG.expand_installers(game, null, Platform.CURRENT); + gog_dlc.tooltip_text = FSUtils.Paths.Collection.GOG.expand_dlc(game); + gog_bonus.tooltip_text = FSUtils.Paths.Collection.GOG.expand_bonus(game); + + humble_game_dir.tooltip_text = FSUtils.Paths.Collection.Humble.expand_game_dir(game); + humble_installers.tooltip_text = FSUtils.Paths.Collection.Humble.expand_installers(game); + + Utils.thread("CollectionDiskUsage", () => { + try + { + FileMeasureProgressCallback callback = (reporting, size, dirs, files) => { + Idle.add(() => { + status = description = format_size(size); + return Source.REMOVE; + }); + }; + uint64 size, dirs, files; + FSUtils.file(collection.root).measure_disk_usage(FileMeasureFlags.NONE, null, callback, out size, out dirs, out files); + callback(true, size, dirs, files); + } + catch(Error e){} + }); + } + + private void syntax_info_label(string variable, string? description=null) + { + var var_label = new Label(variable); + var_label.xalign = 0; + var_label.use_markup = true; + syntax_info_grid.attach(var_label, 0, syntax_info_grid_rows, description == null ? 2 : 1, 1); + + if(description != null) + { + var desc_label = new Label(description); + desc_label.xalign = 0; + syntax_info_grid.attach(desc_label, 1, syntax_info_grid_rows); + } + + syntax_info_grid_rows++; + } + } +} diff --git a/src/ui/dialogs/SettingsDialog/pages/general/Controller.vala b/src/ui/dialogs/SettingsDialog/pages/general/Controller.vala new file mode 100644 index 00000000..d3067220 --- /dev/null +++ b/src/ui/dialogs/SettingsDialog/pages/general/Controller.vala @@ -0,0 +1,215 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; + +using GameHub.Utils; +using GameHub.UI.Widgets; + +namespace GameHub.UI.Dialogs.SettingsDialog.Pages.General +{ + public class Controller: SettingsDialogPage + { + private Settings.Controller settings; + private ListBox controllers; + private Grid shortcuts_grid; + + public Controller(SettingsDialog dlg) + { + Object( + dialog: dlg, + title: _("Controller"), + description: _("Enabled"), + icon_name: "gamehub-symbolic", + activatable: true + ); + status = description; + } + + construct + { + root_grid.margin = 0; + header_grid.margin = 12; + header_grid.margin_bottom = 0; + content_area.margin = 0; + + settings = Settings.Controller.instance; + + var focus_switch = add_switch(_("Focus GameHub window with Guide button"), settings.focus_window, v => { settings.focus_window = v; update(); request_restart(); }); + focus_switch.margin_start = 16; + focus_switch.margin_end = 12; + + var controllers_header = add_header(_("Controllers")); + controllers_header.margin_start = controllers_header.margin_end = 12; + + var controllers_scroll = add_widget(new ScrolledWindow(null, null)); + controllers_scroll.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME); + controllers_scroll.hscrollbar_policy = PolicyType.NEVER; + + controllers_scroll.margin_start = 7; + controllers_scroll.margin_end = 3; + controllers_scroll.margin_top = 0; + controllers_scroll.margin_bottom = 6; + + controllers = new ListBox(); + controllers.selection_mode = SelectionMode.NONE; + controllers.get_style_context().add_class("separated-list"); + + controllers_scroll.add(controllers); + + shortcuts_grid = add_widget(new Grid()); + shortcuts_grid.valign = Align.END; + shortcuts_grid.column_spacing = 12; + shortcuts_grid.margin_start = 16; + shortcuts_grid.margin_end = 12; + + #if GTK_3_22 + controllers_scroll.propagate_natural_width = true; + controllers_scroll.propagate_natural_height = true; + shortcuts_grid.expand = true; + #else + controllers_scroll.expand = true; + #endif + + add_shortcut(0, 0, _("Move focus"), "trigger-left", "/", "trigger-right"); + shortcuts_grid.add(new Separator(Orientation.VERTICAL)); + add_shortcut(2, 0, _("Exit"), "guide", "+", "b"); + + status_switch.active = settings.enabled; + status_switch.notify["active"].connect(() => { + settings.enabled = status_switch.active; + update(); + request_restart(); + }); + + update(); + } + + private void update() + { + content_area.sensitive = settings.enabled; + status = description = settings.enabled ? _("Enabled") : _("Disabled"); + + controllers.foreach(r => { + if(r != null) r.destroy(); + }); + + foreach(var controller in settings.known_controllers) + { + controllers.add(new ControllerRow(controller, !(controller in settings.ignored_controllers), this)); + } + } + + private class ControllerRow: ListBoxRow + { + public string controller { get; construct; } + public bool enabled { get; construct set; } + + public Controller page { get; construct; } + + public ControllerRow(string controller, bool enabled, Controller page) + { + Object(controller: controller, enabled: enabled, page: page); + } + + construct + { + var settings = Settings.Controller.instance; + + var hbox = new Box(Orientation.HORIZONTAL, 8); + hbox.margin_start = hbox.margin_end = 8; + hbox.margin_top = hbox.margin_bottom = 4; + + var icon = new Image.from_icon_name("gamehub-symbolic", IconSize.SMALL_TOOLBAR); + icon.valign = Align.CENTER; + + var name = new Label(controller); + name.get_style_context().add_class("category-label"); + name.hexpand = true; + name.ellipsize = Pango.EllipsizeMode.END; + name.xalign = 0; + name.valign = Align.CENTER; + + var enabled_switch = new Switch(); + enabled_switch.active = enabled; + enabled_switch.valign = Align.CENTER; + + hbox.add(icon); + hbox.add(name); + hbox.add(enabled_switch); + + child = hbox; + + enabled_switch.notify["active"].connect(() => { + enabled = enabled_switch.active; + }); + + notify["enabled"].connect(() => { + var ignored = settings.ignored_controllers; + if(enabled && controller in ignored) + { + string[] new_controllers = {}; + foreach(var c in ignored) + { + if(c != controller) new_controllers += c; + } + settings.ignored_controllers = new_controllers; + page.request_restart(); + } + else if(!enabled && !(controller in ignored)) + { + ignored += controller; + settings.ignored_controllers = ignored; + page.request_restart(); + } + }); + } + } + + private void add_shortcut(int x, int y, string action, ...) + { + var buttons = va_list(); + + var label = new Label(action); + label.halign = Align.START; + label.hexpand = true; + + var bbox = new Box(Orientation.HORIZONTAL, 8); + bbox.halign = Align.END; + + for(string? btn = buttons.arg(); btn != null; btn = buttons.arg()) + { + if(btn == "+" || btn == "/" || btn == ",") + { + bbox.add(new Label(btn)); + } + else + { + var image = new Image.from_icon_name("controller-button-" + btn, IconSize.LARGE_TOOLBAR); + bbox.add(image); + } + } + + var hbox = new Box(Orientation.HORIZONTAL, 12); + hbox.add(label); + hbox.add(bbox); + + shortcuts_grid.attach(hbox, x, y); + } + } +} diff --git a/src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala b/src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala new file mode 100644 index 00000000..01654f7a --- /dev/null +++ b/src/ui/dialogs/SettingsDialog/pages/general/Tweaks.vala @@ -0,0 +1,105 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; + +using GameHub.Data; +using GameHub.Utils; +using GameHub.UI.Widgets; + +namespace GameHub.UI.Dialogs.SettingsDialog.Pages.General +{ + public class Tweaks: SettingsDialogPage + { + public Tweaks(SettingsDialog dlg) + { + Object( + dialog: dlg, + title: _("Tweaks"), + description: _("Tweak launch options and apply them to games automatically"), + icon_name: "system-run" + ); + status = description; + } + + construct + { + root_grid.margin = 0; + header_grid.margin = 12; + header_grid.margin_bottom = 0; + content_area.margin = 0; + + var header = add_header(_("Tweaks")); + header.margin_start = header.margin_end = 12; + + var tweaks_list_scroll = add_widget(new ScrolledWindow(null, null)); + tweaks_list_scroll.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME); + tweaks_list_scroll.hscrollbar_policy = PolicyType.NEVER; + + tweaks_list_scroll.margin_start = 7; + tweaks_list_scroll.margin_end = 3; + tweaks_list_scroll.margin_top = 0; + tweaks_list_scroll.margin_bottom = 6; + + var tweaks_list = new TweaksList(); + tweaks_list.get_style_context().add_class("separated-list"); + + tweaks_list_scroll.add(tweaks_list); + + #if GTK_3_22 + tweaks_list_scroll.propagate_natural_width = true; + tweaks_list_scroll.propagate_natural_height = true; + #else + tweaks_list_scroll.expand = true; + #endif + + add_dirs_info(); + } + + private void add_dirs_info() + { + var dirs = FSUtils.get_data_dirs("tweaks", true); + var last_dir = dirs.last(); + + var dirs_tooltip = """%s""".printf(_("Tweaks are loaded from following directories in order\nLast tweak overrides previous tweaks with same identifiers")) + "\n"; + foreach(var dir in dirs) + { + if(dir == last_dir) + dirs_tooltip += "\n• %s (%s)".printf(dir.get_path(), _("Click to open")); + else + dirs_tooltip += "\n• %s".printf(dir.get_path()); + } + + var dirs_btn = new Button(); + dirs_btn.hexpand = true; + dirs_btn.tooltip_markup = dirs_tooltip; + StyleClass.add(dirs_btn, Gtk.STYLE_CLASS_FLAT); + + var dirs_btn_label = new Label(_("Tweaks are loaded from %1$s and %2$d more directories (?)").printf(last_dir.get_path(), dirs.size - 1)); + dirs_btn_label.wrap = true; + dirs_btn_label.xalign = 0; + dirs_btn_label.use_markup = true; + + dirs_btn.add(dirs_btn_label); + + dirs_btn.clicked.connect(() => { Utils.open_uri(last_dir.get_uri()); }); + + add_widget(dirs_btn); + } + } +} diff --git a/src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala b/src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala new file mode 100644 index 00000000..428c0eea --- /dev/null +++ b/src/ui/dialogs/SettingsDialog/pages/providers/Providers.vala @@ -0,0 +1,189 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; + +using GameHub.Utils; +using GameHub.UI.Widgets; +using GameHub.Data.Providers; + +namespace GameHub.UI.Dialogs.SettingsDialog.Pages.Providers +{ + public class Providers: SettingsDialogPage + { + private Settings.Providers.Data.IGDB igdb; + + private ListBox image_providers; + private ListBox data_providers; + + public Providers(SettingsDialog dlg) + { + Object( + dialog: dlg, + header: _("Data"), + title: _("Providers"), + description: _("Third-party data providers"), + icon_name: "web-browser" + ); + status = description; + } + + construct + { + root_grid.margin = 0; + header_grid.margin = 12; + header_grid.margin_bottom = 0; + content_area.margin = 0; + + igdb = Settings.Providers.Data.IGDB.instance; + + var image_providers_header = add_header(_("Image providers")); + image_providers_header.margin_start = image_providers_header.margin_end = 12; + + image_providers = add_widget(new ListBox()); + image_providers.selection_mode = SelectionMode.NONE; + image_providers.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME); + image_providers.get_style_context().add_class("flat-list"); + + image_providers.margin_start = 7; + image_providers.margin_end = 3; + image_providers.margin_top = 0; + image_providers.margin_bottom = 6; + + var data_providers_header = add_header(_("Metadata providers")); + data_providers_header.margin_start = data_providers_header.margin_end = 12; + + data_providers = add_widget(new ListBox()); + data_providers.selection_mode = SelectionMode.NONE; + data_providers.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME); + data_providers.get_style_context().add_class("flat-list"); + + data_providers.margin_start = 7; + data_providers.margin_end = 3; + data_providers.margin_top = 0; + data_providers.margin_bottom = 6; + + update(); + } + + private void update() + { + image_providers.foreach(r => { + if(r != null) r.destroy(); + }); + + foreach(var src in ImageProviders) + { + image_providers.add(new ProviderRow(src)); + } + + foreach(var src in DataProviders) + { + data_providers.add(new ProviderRow(src)); + } + } + + private class ProviderRow: ListBoxRow + { + public Provider provider { get; construct; } + + public ProviderRow(Provider provider) + { + Object(provider: provider); + } + + construct + { + var root_vbox = new Box(Orientation.VERTICAL, 0); + + var grid = new Grid(); + grid.column_spacing = 12; + grid.margin_start = grid.margin_end = 8; + grid.margin_top = grid.margin_bottom = 4; + + var icon = new Image.from_icon_name(provider.icon, IconSize.LARGE_TOOLBAR); + icon.valign = Align.CENTER; + + var name = new Label(provider.name); + name.get_style_context().add_class("category-label"); + name.hexpand = true; + name.xalign = 0; + name.valign = Align.CENTER; + + var url = new Label(provider.url); + url.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL); + url.hexpand = true; + url.xalign = 0; + url.valign = Align.CENTER; + + var open = new Button.from_icon_name("web-browser-symbolic", IconSize.SMALL_TOOLBAR); + open.get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + open.valign = Align.CENTER; + open.tooltip_text = _("Open website"); + + var enabled_switch = new Switch(); + enabled_switch.active = provider.enabled; + enabled_switch.valign = Align.CENTER; + + grid.attach(icon, 0, 0, 1, 2); + grid.attach(name, 1, 0); + grid.attach(url, 1, 1); + grid.attach(open, 2, 0, 1, 2); + grid.attach(enabled_switch, 3, 0, 1, 2); + + root_vbox.add(grid); + + Revealer? provider_settings_revealer = null; + var provider_settings = provider.settings_widget; + if(provider_settings != null) + { + provider_settings_revealer = new Revealer(); + provider_settings_revealer.transition_type = RevealerTransitionType.SLIDE_DOWN; + provider_settings_revealer.reveal_child = provider.enabled; + + var provider_settings_wrapper = new Box(Orientation.VERTICAL, 0); + provider_settings_wrapper.get_style_context().add_class("provider-settings"); + + provider_settings.margin_top = provider_settings.margin_bottom = 4; + provider_settings.margin_start = 44; + provider_settings.margin_end = 8; + + provider_settings_wrapper.add(provider_settings); + provider_settings_wrapper.show_all(); + + provider_settings_revealer.add(provider_settings_wrapper); + root_vbox.add(provider_settings_revealer); + } + + child = root_vbox; + + enabled_switch.notify["active"].connect(() => { + provider.enabled = enabled_switch.active; + if(provider_settings_revealer != null) + { + provider_settings_revealer.reveal_child = provider.enabled; + } + }); + + open.clicked.connect(() => { + Utils.open_uri(provider.url); + }); + } + } + } +} diff --git a/src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala b/src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala new file mode 100644 index 00000000..d4f461f1 --- /dev/null +++ b/src/ui/dialogs/SettingsDialog/pages/sources/GOG.vala @@ -0,0 +1,106 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; + +using GameHub.Utils; +using GameHub.UI.Widgets; + +namespace GameHub.UI.Dialogs.SettingsDialog.Pages.Sources +{ + public class GOG: SettingsDialogPage + { + private Settings.Auth.GOG gog_auth; + private Button logout_btn; + private FileChooserEntry games_dir_chooser; + + public GOG(SettingsDialog dlg) + { + Object( + dialog: dlg, + title: "GOG", + description: _("Disabled"), + icon_name: "source-gog-symbolic", + activatable: true + ); + status = description; + } + + construct + { + var paths = FSUtils.Paths.Settings.instance; + + gog_auth = Settings.Auth.GOG.instance; + + games_dir_chooser = add_file_chooser(_("Games directory"), FileChooserAction.SELECT_FOLDER, paths.gog_games, v => { paths.gog_games = v; request_restart(); update(); }).get_children().last().data as FileChooserEntry; + + status_switch.active = gog_auth.enabled; + status_switch.notify["active"].connect(() => { + gog_auth.enabled = status_switch.active; + request_restart(); + update(); + }); + + logout_btn = new Button.with_label(_("Logout")); + action_area.add(logout_btn); + + logout_btn.clicked.connect(() => { + gog_auth.authenticated = false; + gog_auth.access_token = ""; + gog_auth.refresh_token = ""; + request_restart(); + update(); + }); + + update(); + } + + private void update() + { + content_area.sensitive = gog_auth.enabled; + logout_btn.sensitive = gog_auth.authenticated && gog_auth.access_token.length > 0; + + if(" " in FSUtils.Paths.Settings.instance.gog_games) + { + games_dir_chooser.get_style_context().add_class(Gtk.STYLE_CLASS_ERROR); + status_type = StatusType.ERROR; + } + else + { + games_dir_chooser.get_style_context().remove_class(Gtk.STYLE_CLASS_ERROR); + status_type = restart_requested ? StatusType.WARNING : StatusType.NONE; + } + dialog.update_games_dir_space_message(); + + if(!gog_auth.enabled) + { + status = description = _("Disabled"); + } + else if(!gog_auth.authenticated || gog_auth.access_token.length == 0) + { + status = description = _("Not authenticated"); + } + else + { + var user_name = GameHub.Data.Sources.GOG.GOG.instance.user_name; + status = description = user_name != null ? _("Authenticated as %s").printf(user_name) : _("Authenticated"); + } + } + + } +} diff --git a/src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala b/src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala new file mode 100644 index 00000000..02e4a87b --- /dev/null +++ b/src/ui/dialogs/SettingsDialog/pages/sources/Humble.vala @@ -0,0 +1,108 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; + +using GameHub.Utils; +using GameHub.UI.Widgets; + +namespace GameHub.UI.Dialogs.SettingsDialog.Pages.Sources +{ + public class Humble: SettingsDialogPage + { + private Settings.Auth.Humble humble_auth; + private Button logout_btn; + private FileChooserEntry games_dir_chooser; + + public Humble(SettingsDialog dlg) + { + Object( + dialog: dlg, + title: "Humble Bundle", + description: _("Disabled"), + icon_name: "source-humble-symbolic", + activatable: true + ); + status = description; + } + + construct + { + var paths = FSUtils.Paths.Settings.instance; + + humble_auth = Settings.Auth.Humble.instance; + + add_switch(_("Load games from Humble Trove"), humble_auth.load_trove_games, v => { humble_auth.load_trove_games = v; update(); request_restart(); }); + + add_separator(); + + games_dir_chooser = add_file_chooser(_("Games directory"), FileChooserAction.SELECT_FOLDER, paths.humble_games, v => { paths.humble_games = v; update(); request_restart(); }).get_children().last().data as FileChooserEntry; + + status_switch.active = humble_auth.enabled; + status_switch.notify["active"].connect(() => { + humble_auth.enabled = status_switch.active; + request_restart(); + update(); + }); + + logout_btn = new Button.with_label(_("Logout")); + action_area.add(logout_btn); + + logout_btn.clicked.connect(() => { + humble_auth.authenticated = false; + humble_auth.access_token = ""; + request_restart(); + update(); + }); + + update(); + } + + private void update() + { + content_area.sensitive = humble_auth.enabled; + logout_btn.sensitive = humble_auth.authenticated && humble_auth.access_token.length > 0; + + if(" " in FSUtils.Paths.Settings.instance.humble_games) + { + games_dir_chooser.get_style_context().add_class(Gtk.STYLE_CLASS_ERROR); + status_type = StatusType.ERROR; + } + else + { + games_dir_chooser.get_style_context().remove_class(Gtk.STYLE_CLASS_ERROR); + status_type = restart_requested ? StatusType.WARNING : StatusType.NONE; + } + dialog.update_games_dir_space_message(); + + if(!humble_auth.enabled) + { + status = description = _("Disabled"); + } + else if(!humble_auth.authenticated || humble_auth.access_token.length == 0) + { + status = description = _("Not authenticated"); + } + else + { + status = description = _("Authenticated"); + } + } + + } +} diff --git a/src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala b/src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala new file mode 100644 index 00000000..a6348d5f --- /dev/null +++ b/src/ui/dialogs/SettingsDialog/pages/sources/Itch.vala @@ -0,0 +1,118 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; + +using GameHub.Utils; +using GameHub.UI.Widgets; + +namespace GameHub.UI.Dialogs.SettingsDialog.Pages.Sources +{ + public class Itch: SettingsDialogPage + { + private Settings.Auth.Itch itch_auth; + private FileChooserEntry games_dir_chooser; + + public Itch(SettingsDialog dlg) + { + Object( + dialog: dlg, + title: "itch.io", + description: _("Disabled"), + icon_name: "source-itch-symbolic", + activatable: true + ); + status = description; + } + + construct + { + var paths = FSUtils.Paths.Settings.instance; + itch_auth = Settings.Auth.Itch.instance; + + games_dir_chooser = add_file_chooser(_("Games directory"), FileChooserAction.SELECT_FOLDER, paths.itch_games, v => { paths.itch_games = v; request_restart(); update(); }).get_children().last().data as FileChooserEntry; + + add_separator(); + + add_apikey_entry(); + add_link(_("Generate key"), "https://itch.io/api-keys"); + + add_separator(); + + add_file_chooser(_("Installation directory"), FileChooserAction.SELECT_FOLDER, paths.itch_home, v => { paths.itch_home = v; request_restart(); }, false); + + status_switch.active = itch_auth.enabled; + status_switch.notify["active"].connect(() => { + itch_auth.enabled = status_switch.active; + update(); + request_restart(); + }); + + update(); + } + + private void update() + { + var itch = GameHub.Data.Sources.Itch.Itch.instance; + + content_area.sensitive = itch.enabled; + + if(!itch.enabled) + { + status = description = _("Disabled"); + } + else if(!itch.is_installed()) + { + status = description = _("Not installed"); + } + else if(!itch.is_authenticated()) + { + status = description = _("Not authenticated"); + } + else + { + status = description = itch.user_name != null ? _("Authenticated as %s").printf(itch.user_name) : _("Authenticated"); + } + } + + protected void add_apikey_entry() + { + var itch_auth = Settings.Auth.Itch.instance; + + var entry = new Entry(); + entry.max_length = 40; + if(itch_auth.api_key != itch_auth.schema.get_default_value("api-key").get_string()) + { + entry.text = itch_auth.api_key; + } + entry.primary_icon_name = "source-itch-symbolic"; + entry.set_size_request(280, -1); + + entry.notify["text"].connect(() => { itch_auth.api_key = entry.text; request_restart(); }); + + var label = new Label(_("API key")); + label.halign = Align.START; + label.hexpand = true; + + var hbox = new Box(Orientation.HORIZONTAL, 12); + hbox.add(label); + hbox.add(entry); + add_widget(hbox); + } + } +} diff --git a/src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala b/src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala new file mode 100644 index 00000000..7ae98127 --- /dev/null +++ b/src/ui/dialogs/SettingsDialog/pages/sources/Steam.vala @@ -0,0 +1,256 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; + +using GameHub.Data; +using GameHub.Data.Compat; + +using GameHub.Utils; + +namespace GameHub.UI.Dialogs.SettingsDialog.Pages.Sources +{ + public class Steam: SettingsDialogPage + { + private Settings.Auth.Steam steam_auth; + + private ListBox proton; + + public Steam(SettingsDialog dlg) + { + Object( + dialog: dlg, + header: _("Game sources"), + title: "Steam", + description: _("Disabled"), + icon_name: "source-steam-symbolic", + activatable: true + ); + status = description; + } + + construct + { + root_grid.margin = 0; + header_grid.margin = 12; + header_grid.margin_bottom = 0; + content_area.margin = 0; + + var paths = FSUtils.Paths.Settings.instance; + + steam_auth = Settings.Auth.Steam.instance; + + add_steam_apikey_entry(); + adjust_margins(add_labeled_link(_("Steam API keys have limited number of uses per day"), _("Generate key"), "steam://openurl/https://steamcommunity.com/dev/apikey")); + + adjust_margins(add_separator()); + + adjust_margins(add_file_chooser(_("Installation directory"), FileChooserAction.SELECT_FOLDER, paths.steam_home, v => { paths.steam_home = v; request_restart(); }, false)); + + var proton_header = add_header("Proton"); + proton_header.margin_start = proton_header.margin_end = 12; + + var proton_scroll = add_widget(new ScrolledWindow(null, null)); + proton_scroll.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME); + proton_scroll.hscrollbar_policy = PolicyType.NEVER; + + proton_scroll.margin_start = 7; + proton_scroll.margin_end = 3; + proton_scroll.margin_top = 0; + proton_scroll.margin_bottom = 6; + + proton = new ListBox(); + proton.selection_mode = SelectionMode.NONE; + proton.get_style_context().add_class("separated-list"); + + proton_scroll.add(proton); + + #if GTK_3_22 + proton_scroll.propagate_natural_width = true; + proton_scroll.propagate_natural_height = true; + #else + proton_scroll.expand = true; + #endif + + status_switch.active = steam_auth.enabled; + status_switch.notify["active"].connect(() => { + steam_auth.enabled = status_switch.active; + update(); + request_restart(); + }); + + update(); + } + + private void update() + { + var steam = GameHub.Data.Sources.Steam.Steam.instance; + + content_area.sensitive = steam.enabled; + + if(!steam.enabled) + { + status = description = _("Disabled"); + } + else if(!steam.is_installed()) + { + status = description = _("Not installed"); + } + else if(!steam.is_authenticated_in_steam_client) + { + status = description = _("Not authenticated"); + } + else + { + status = description = steam.user_name != null ? _("Authenticated as %s").printf(steam.user_name) : _("Authenticated"); + } + + proton.foreach(r => { + if(r != null) r.destroy(); + }); + + foreach(var tool in CompatTools) + { + if(tool is Proton) + { + var p = tool as Proton; + if(p != null && !p.is_latest) + { + proton.add(new ProtonRow(p, this)); + } + } + } + + proton.show_all(); + } + + private class ProtonRow: ListBoxRow + { + public Proton proton { get; construct; } + + public Steam page { private get; construct; } + + public ProtonRow(Proton proton, Steam page) + { + Object(proton: proton, page: page); + } + + construct + { + var grid = new Grid(); + grid.column_spacing = 12; + grid.margin_start = grid.margin_end = 8; + grid.margin_top = grid.margin_bottom = 4; + + var icon = new Image.from_icon_name("source-steam-symbolic", IconSize.LARGE_TOOLBAR); + icon.valign = Align.CENTER; + + var name = new Label(proton.name); + name.get_style_context().add_class("category-label"); + name.set_size_request(96, -1); + name.hexpand = false; + name.xalign = 0; + name.valign = Align.CENTER; + + var appid = new Label(proton.appid); + appid.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL); + appid.hexpand = true; + appid.xalign = 0; + appid.valign = Align.CENTER; + + var status = new Label(_("Not installed")); + status.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL); + status.hexpand = true; + status.ellipsize = Pango.EllipsizeMode.MIDDLE; + status.xalign = 0; + status.valign = Align.CENTER; + + var install = new Button.with_label(_("Install")); + install.valign = Align.CENTER; + install.sensitive = false; + + grid.attach(icon, 0, 0, 1, 2); + grid.attach(name, 1, 0); + grid.attach(appid, 2, 0); + grid.attach(status, 1, 1, 2, 1); + + if(proton.installed && proton.executable != null) + { + status.label = status.tooltip_text = proton.executable.get_path(); + } + else + { + install.sensitive = true; + grid.attach(install, 3, 0, 1, 2); + + install.clicked.connect(() => { + install.sensitive = false; + page.request_restart(); + proton.install_app(); + }); + } + + child = grid; + } + } + + protected Box add_steam_apikey_entry() + { + var steam_auth = Settings.Auth.Steam.instance; + + var entry = new Entry(); + entry.placeholder_text = _("Default"); + entry.max_length = 32; + if(steam_auth.api_key != steam_auth.schema.get_default_value("api-key").get_string()) + { + entry.text = steam_auth.api_key; + } + entry.primary_icon_name = "source-steam-symbolic"; + entry.secondary_icon_name = "edit-delete-symbolic"; + entry.secondary_icon_tooltip_text = _("Restore default API key"); + entry.set_size_request(280, -1); + + entry.notify["text"].connect(() => { steam_auth.api_key = entry.text; request_restart(); }); + entry.icon_press.connect((pos, e) => { + if(pos == EntryIconPosition.SECONDARY) + { + entry.text = ""; + } + }); + + var label = new Label(_("Steam API key")); + label.halign = Align.START; + label.hexpand = true; + + var hbox = new Box(Orientation.HORIZONTAL, 12); + hbox.add(label); + hbox.add(entry); + add_widget(hbox); + + adjust_margins(hbox); + + return hbox; + } + + private void adjust_margins(Widget w) + { + w.margin_start = 16; + w.margin_end = 12; + } + } +} diff --git a/src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala b/src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala new file mode 100644 index 00000000..1473dea3 --- /dev/null +++ b/src/ui/dialogs/SettingsDialog/pages/ui/Appearance.vala @@ -0,0 +1,213 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using GameHub.UI.Widgets; + +using GameHub.Utils; + +namespace GameHub.UI.Dialogs.SettingsDialog.Pages.UI +{ + public class Appearance: SettingsDialogPage + { + private Settings.UI.Appearance settings; + + private ModeButton grid_size_presets; + + public Appearance(SettingsDialog dlg) + { + Object( + dialog: dlg, + header: _("Interface"), + title: _("Appearance"), + description: _("General interface settings"), + icon_name: "preferences-desktop" + ); + status = description; + } + + construct + { + settings = Settings.UI.Appearance.instance; + + add_switch(_("Dark theme"), settings.dark_theme, v => { settings.dark_theme = v; }); + + var icon_style = new ModeButton(); + icon_style.homogeneous = false; + icon_style.halign = Align.END; + icon_style.append_text(C_("icon_style", "Theme-based")); + icon_style.append_text(C_("icon_style", "Symbolic")); + icon_style.append_text(C_("icon_style", "Colored")); + + var icon_style_label = new Label(C_("icon_style", "Icon style")); + icon_style_label.halign = Align.START; + icon_style_label.hexpand = true; + + var icon_style_hbox = new Box(Orientation.HORIZONTAL, 12); + icon_style_hbox.add(icon_style_label); + icon_style_hbox.add(icon_style); + add_widget(icon_style_hbox); + + icon_style.selected = settings.icon_style; + icon_style.mode_changed.connect(() => { + settings.icon_style = (Settings.UI.Appearance.IconStyle) icon_style.selected; + }); + + add_separator(); + + var tabs_switcher = add_widget(new StackSwitcher()); + tabs_switcher.halign = Align.CENTER; + + var tabs_stack = add_widget(new Stack()); + tabs_stack.margin = 0; + + tabs_switcher.stack = tabs_stack; + + var tab_grid = new Box(Orientation.VERTICAL, 4); + tab_grid.margin = 4; + + tab_grid.add(Styled.H4Label(_("Game card"))); + + add_checkbox(_("Show platform icons"), settings.grid_platform_icons, v => { settings.grid_platform_icons = v; }, tab_grid); + + var grid_size_separator = new Separator(Orientation.HORIZONTAL); + grid_size_separator.margin_top = grid_size_separator.margin_bottom = 4; + tab_grid.add(grid_size_separator); + + var grid_size_wrap_hbox = new Box(Orientation.HORIZONTAL, 12); + var grid_size_hbox = new Box(Orientation.HORIZONTAL, 8); + + var grid_width_spinbutton = add_spinbutton(settings.grid_card_width, v => { settings.grid_card_width = v; update_grid_size_presets(); }, grid_size_hbox); + grid_size_hbox.add(new Label("×")); + var grid_height_spinbutton = add_spinbutton(settings.grid_card_height, v => { settings.grid_card_height = v; update_grid_size_presets(); }, grid_size_hbox); + + var grid_size_label = new Label(C_("grid_size", "Card size")); + grid_size_label.halign = Align.START; + grid_size_label.hexpand = true; + + grid_size_wrap_hbox.add(grid_size_label); + grid_size_wrap_hbox.add(grid_size_hbox); + + tab_grid.add(grid_size_wrap_hbox); + + grid_size_presets = new ModeButton(); + StyleClass.add(grid_size_presets, "icons-modebutton"); + grid_size_presets.halign = Align.END; + + foreach(var preset in Settings.UI.Appearance.GameGridSizePreset.PRESETS) + { + grid_size_presets.append_icon(preset.icon(), IconSize.BUTTON, preset.description(), true); + } + + var grid_size_presets_label = new Label(C_("grid_size_preset", "Presets")); + grid_size_presets_label.halign = Align.START; + grid_size_presets_label.hexpand = true; + + var grid_size_presets_hbox = new Box(Orientation.HORIZONTAL, 12); + grid_size_presets_hbox.add(grid_size_presets_label); + grid_size_presets_hbox.add(grid_size_presets); + tab_grid.add(grid_size_presets_hbox); + + var tab_list = new Box(Orientation.HORIZONTAL, 8); + tab_list.margin = 4; + + var list_installed = new Box(Orientation.VERTICAL, 4); + list_installed.hexpand = true; + + var list_uninstalled = new Box(Orientation.VERTICAL, 4); + list_uninstalled.hexpand = true; + + tab_list.add(list_installed); + tab_list.add(new Separator(Orientation.VERTICAL)); + tab_list.add(list_uninstalled); + + list_installed.add(Styled.H4Label(_("Games list: installed"))); + list_uninstalled.add(Styled.H4Label(_("Games list: not installed"))); + + add_list_style_checkbox(C_("list_style", "Show icon"), "installed-icon", list_installed); + add_list_style_checkbox(C_("list_style", "Bold title"), "installed-title-bold", list_installed); + add_list_style_checkbox(C_("list_style", "Show status"), "installed-status", list_installed); + + add_list_style_checkbox(C_("list_style", "Show icon"), "uninstalled-icon", list_uninstalled); + add_list_style_checkbox(C_("list_style", "Bold title"), "uninstalled-title-bold", list_uninstalled); + add_list_style_checkbox(C_("list_style", "Show status"), "uninstalled-status", list_uninstalled); + add_list_style_checkbox(C_("list_style", "Dim"), "uninstalled-dim", list_uninstalled); + + tabs_stack.add_titled(tab_grid, "grid", _("Grid options")); + tabs_stack.add_titled(tab_list, "list", _("List options")); + + grid_size_presets.mode_changed.connect(() => { + var preset = Settings.UI.Appearance.GameGridSizePreset.PRESETS[grid_size_presets.selected]; + if(preset != Settings.UI.Appearance.GameGridSizePreset.CUSTOM) + { + grid_width_spinbutton.value = preset.width(); + grid_height_spinbutton.value = preset.height(); + } + }); + + update_grid_size_presets(); + } + + private void update_grid_size_presets() + { + grid_size_presets.selected = (int) Settings.UI.Appearance.GameGridSizePreset.from_size(settings.grid_card_width, settings.grid_card_height); + } + + private CheckButton add_checkbox(string label, bool active, owned SettingsDialogPage.SwitchAction action, Box parent) + { + var check = new CheckButton.with_label(label); + StyleClass.add(check, "default-padding"); + parent.add(check); + check.active = active; + check.toggled.connect(() => { action(check.active); }); + return check; + } + + private CheckButton add_list_style_checkbox(string label, string style, Box parent) + { + return add_checkbox(label, style in settings.list_style, active => { + if(!active && style in settings.list_style) + { + string[] new_style = {}; + foreach(var s in settings.list_style) + { + if(s != style) new_style += s; + } + settings.update_list_style(new_style); + } + else if(active && !(style in settings.list_style)) + { + string[] new_style = settings.list_style; + new_style += style; + settings.update_list_style(new_style); + } + }, parent); + } + + private SpinButton add_spinbutton(int value, owned SpinButtonAction action, Box parent) + { + var button = new SpinButton.with_range(100, 1000, 10); + button.value = value; + button.value_changed.connect(() => { action((int) button.value); }); + parent.add(button); + return button; + } + + delegate void SpinButtonAction(int value); + } +} diff --git a/src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala b/src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala new file mode 100644 index 00000000..53f3d000 --- /dev/null +++ b/src/ui/dialogs/SettingsDialog/pages/ui/Behavior.vala @@ -0,0 +1,53 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; + +using GameHub.Utils; + +namespace GameHub.UI.Dialogs.SettingsDialog.Pages.UI +{ + public class Behavior: SettingsDialogPage + { + public Behavior(SettingsDialog dlg) + { + Object( + dialog: dlg, + title: _("Behavior"), + description: _("Behavior settings"), + icon_name: "preferences-system" + ); + status = description; + } + + construct + { + var settings = Settings.UI.Behavior.instance; + + add_switch(_("Run games with double click"), settings.grid_doubleclick, v => { settings.grid_doubleclick = v; }); + + add_separator(); + + add_switch(_("Merge games from different sources"), settings.merge_games, v => { settings.merge_games = v; request_restart(); }); + + add_separator(); + + add_switch(_("Use imported tags"), settings.import_tags, v => { settings.import_tags = v; }); + } + } +} diff --git a/src/ui/views/BaseView.vala b/src/ui/views/BaseView.vala index 2ba5b6cb..ef66c455 100644 --- a/src/ui/views/BaseView.vala +++ b/src/ui/views/BaseView.vala @@ -1,36 +1,54 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + using Gtk; -using Granite; + using GameHub.UI.Windows; namespace GameHub.UI.Views { - public abstract class BaseView: Gtk.Grid + public abstract class BaseView: Grid { protected MainWindow window; protected HeaderBar titlebar; - + construct { titlebar = new HeaderBar(); titlebar.title = "GameHub"; titlebar.show_close_button = true; } - + public virtual void attach_to_window(MainWindow wnd) { window = wnd; show(); } - + public virtual void on_show() { titlebar.show_all(); window.set_titlebar(titlebar); } - + public virtual void on_window_focus() { - + } } } diff --git a/src/ui/views/GameDetailsView/GameDetailsBlock.vala b/src/ui/views/GameDetailsView/GameDetailsBlock.vala new file mode 100644 index 00000000..01754475 --- /dev/null +++ b/src/ui/views/GameDetailsView/GameDetailsBlock.vala @@ -0,0 +1,63 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using GameHub.UI.Widgets; + +using Gdk; +using Gee; + +using GameHub.Data; + +namespace GameHub.UI.Views.GameDetailsView +{ + public abstract class GameDetailsBlock: Box + { + public Game game { get; construct; } + + public int text_max_width { get; construct; } + + public abstract bool supports_game { get; } + + protected Box? add_info_label(string title, string? text, bool multiline=true, bool markup=false, Container? parent=null) + { + if(text == null || text == "") return null; + + var title_label = Styled.H4Label(title); + title_label.set_size_request(multiline ? -1 : 128, -1); + title_label.valign = Align.START; + + var text_label = new Label(text); + text_label.get_style_context().add_class(multiline ? "gameinfo-multiline-value" : "gameinfo-singleline-value"); + text_label.halign = Align.START; + text_label.hexpand = false; + text_label.wrap = true; + text_label.xalign = 0; + text_label.max_width_chars = text_max_width; + text_label.use_markup = markup; + + var box = new Box(multiline ? Orientation.VERTICAL : Orientation.HORIZONTAL, multiline ? 0 : 16); + box.margin_start = box.margin_end = 8; + box.add(title_label); + box.add(text_label); + (parent ?? this).add(box); + + return box; + } + } +} diff --git a/src/ui/views/GameDetailsView/GameDetailsPage.vala b/src/ui/views/GameDetailsView/GameDetailsPage.vala new file mode 100644 index 00000000..52234cff --- /dev/null +++ b/src/ui/views/GameDetailsView/GameDetailsPage.vala @@ -0,0 +1,530 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; +using Gee; + +using GameHub.Data; +using GameHub.Utils; +using GameHub.UI.Widgets; +using GameHub.UI.Views.GamesView; + +namespace GameHub.UI.Views.GameDetailsView +{ + public class GameDetailsPage: Gtk.Grid + { + public Game game { get; construct; } + + public GameDetailsView details_view { get; construct; } + + public GameDetailsPage(Game game, GameDetailsView parent) + { + Object(game: game, details_view: parent); + } + + private bool is_dialog = false; + private bool is_updated = false; + + private Stack stack; + private Spinner spinner; + + private ScrolledWindow content_scrolled; + public Box content; + private Box actions; + + private Label title; + private Label status; + private ProgressBar download_progress; + private AutoSizeImage icon; + private Image no_icon_indicator; + private Image src_icon; + + private Box platform_icons; + + private Downloader.Download? download; + + private Button action_pause; + private Button action_resume; + private Button action_cancel; + + private ActionButton action_install; + private ActionButton action_run; + private ActionButton action_run_with_compat; + private ActionButton action_properties; + private ActionButton action_open_directory; + private ActionButton action_open_installer_collection_directory; + private ActionButton action_open_bonus_collection_directory; + private ActionButton action_open_screenshots_directory; + private ActionButton action_open_store_page; + private ActionButton action_uninstall; + + private Box blocks; + private Box sidebar; + + construct + { + stack = new Stack(); + stack.transition_type = StackTransitionType.NONE; + stack.vexpand = true; + + spinner = new Spinner(); + spinner.active = true; + spinner.set_size_request(36, 36); + spinner.halign = Align.CENTER; + spinner.valign = Align.CENTER; + + content_scrolled = new ScrolledWindow(null, null); + #if GTK_3_22 + content_scrolled.propagate_natural_width = true; + content_scrolled.propagate_natural_height = true; + #endif + + content = new Box(Orientation.VERTICAL, 0); + content.margin_start = content.margin_end = 8; + + var title_hbox_eventbox = new EventBox(); + + var title_overlay = new Overlay(); + title_overlay.margin_start = title_overlay.margin_end = 7; + + var title_icons = new Box(Orientation.HORIZONTAL, 15); + title_icons.valign = Align.START; + title_icons.halign = Align.END; + + var title_hbox = new Box(Orientation.HORIZONTAL, 15); + + var icon_overlay = new Overlay(); + icon_overlay.set_size_request(48, 48); + icon_overlay.valign = Align.START; + + no_icon_indicator = new Image.from_icon_name("gamehub-symbolic", IconSize.DND); + no_icon_indicator.get_style_context().add_class("no-icon-indicator"); + no_icon_indicator.halign = Align.CENTER; + no_icon_indicator.valign = Align.CENTER; + no_icon_indicator.opacity = 0.8; + + icon = new AutoSizeImage(); + icon.halign = Align.CENTER; + icon.valign = Align.CENTER; + icon.set_constraint(48, 48, 1); + + icon_overlay.add(no_icon_indicator); + icon_overlay.add_overlay(icon); + + title = Styled.H2Label(null); + title.halign = Align.START; + title.wrap = true; + title.xalign = 0; + title.hexpand = true; + + status = new Label(null); + status.halign = Align.START; + status.hexpand = true; + + download_progress = new ProgressBar(); + download_progress.hexpand = true; + download_progress.fraction = 0d; + download_progress.hide(); + + src_icon = new Image(); + src_icon.icon_size = IconSize.DIALOG; + src_icon.opacity = 0.1; + + platform_icons = new Box(Orientation.HORIZONTAL, 15); + + var title_vbox = new Box(Orientation.VERTICAL, 0); + var vbox_labels = new Box(Orientation.VERTICAL, 0); + vbox_labels.hexpand = true; + + var hbox_inner = new Box(Orientation.HORIZONTAL, 8); + var hbox_actions = new Box(Orientation.HORIZONTAL, 0); + hbox_actions.vexpand = false; + hbox_actions.valign = Align.CENTER; + + action_pause = new Button.from_icon_name("media-playback-pause-symbolic"); + action_pause.set_size_request(36, 36); + action_pause.tooltip_text = _("Pause download"); + action_pause.get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + action_pause.visible = false; + + action_resume = new Button.from_icon_name("media-playback-start-symbolic"); + action_resume.set_size_request(36, 36); + action_resume.tooltip_text = _("Resume download"); + action_resume.get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + action_resume.visible = false; + + action_cancel = new Button.from_icon_name("process-stop-symbolic"); + action_cancel.set_size_request(36, 36); + action_cancel.tooltip_text = _("Cancel download"); + action_cancel.get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + action_cancel.visible = false; + + vbox_labels.add(title); + vbox_labels.add(status); + + hbox_inner.add(vbox_labels); + hbox_inner.add(hbox_actions); + + hbox_actions.add(action_pause); + hbox_actions.add(action_resume); + hbox_actions.add(action_cancel); + + title_vbox.add(hbox_inner); + title_vbox.add(download_progress); + + title_hbox.add(icon_overlay); + title_hbox.add(title_vbox); + + title_icons.add(platform_icons); + title_icons.add(src_icon); + + title_overlay.add(title_hbox); + title_overlay.add_overlay(title_icons); + title_overlay.set_overlay_pass_through(title_icons, true); + + title_hbox_eventbox.add(title_overlay); + + content.add(title_hbox_eventbox); + + actions = new Box(Orientation.HORIZONTAL, 0); + actions.margin_top = actions.margin_bottom = 16; + + content.add(actions); + + var blocks_hbox = new Box(Orientation.HORIZONTAL, 8); + + blocks = new Box(Orientation.VERTICAL, 0); + blocks.hexpand = true; + + sidebar = new Box(Orientation.VERTICAL, 6); + sidebar.hexpand = false; + sidebar.halign = Align.END; + + blocks_hbox.add(blocks); + blocks_hbox.add(sidebar); + + content.add(blocks_hbox); + + content_scrolled.add(content); + + stack.add(spinner); + stack.add(content_scrolled); + + add(stack); + + stack.visible_child = spinner; + + action_install = add_action("go-down", null, _("Install"), install_game, true); + action_run = add_action("media-playback-start", null, _("Run"), run_game, true); + action_run_with_compat = add_action("media-playback-start", "platform-windows-symbolic", _("Run with compatibility layer"), run_game_with_compat, true); + action_open_directory = add_action("folder", null, _("Open installation directory"), open_game_directory); + action_open_installer_collection_directory = add_action("folder-download", null, _("Open installers collection directory"), open_installer_collection_directory); + action_open_bonus_collection_directory = add_action("folder-documents", null, _("Open bonus collection directory"), open_bonus_collection_directory); + action_open_screenshots_directory = add_action("folder-pictures", null, _("Open screenshots directory"), open_screenshots_directory); + action_open_store_page = add_action("web-browser", null, _("Open store page"), open_game_store_page); + action_uninstall = add_action("edit-delete", null, (game is Sources.User.UserGame) ? _("Remove") : _("Uninstall"), uninstall_game); + action_properties = add_action("system-run", null, _("Game properties"), game_properties); + + action_cancel.clicked.connect(() => { + if(download != null) download.cancel(); + }); + + action_pause.clicked.connect(() => { + if(download != null && download is Downloader.PausableDownload) + { + ((Downloader.PausableDownload) download).pause(); + } + }); + + action_resume.clicked.connect(() => { + if(download != null && download is Downloader.PausableDownload) + { + ((Downloader.PausableDownload) download).resume(); + } + }); + + title_hbox_eventbox.add_events(EventMask.BUTTON_RELEASE_MASK); + title_hbox_eventbox.button_release_event.connect(e => { + switch(e.button) + { + case 3: + open_context_menu(e, true); + break; + } + return true; + }); + } + + private void set_visible_widgets(Game.Status s) + { + status.label = s.description; + download_progress.hide(); + if(s.state == Game.State.DOWNLOADING && s.download != null && s.download.status != null) + { + download = s.download; + var ds = download.status.state; + + download_progress.show(); + download_progress.fraction = download.status.progress; + + action_cancel.visible = true; + action_cancel.sensitive = ds == Downloader.Download.State.DOWNLOADING || ds == Downloader.Download.State.QUEUED || ds == Downloader.Download.State.PAUSED; + action_pause.visible = download is Downloader.PausableDownload && ds != Downloader.Download.State.PAUSED && ds != Downloader.Download.State.QUEUED; + action_resume.visible = download is Downloader.PausableDownload && ds == Downloader.Download.State.PAUSED && ds != Downloader.Download.State.QUEUED; + } + else + { + action_cancel.visible = false; + action_pause.visible = false; + action_resume.visible = false; + } + action_install.visible = s.state != Game.State.INSTALLED; + action_install.sensitive = s.state == Game.State.UNINSTALLED && game.is_installable; + action_run_with_compat.visible = s.state == Game.State.INSTALLED && game.use_compat; + action_run_with_compat.sensitive = game.can_be_launched(); + action_run.visible = s.state == Game.State.INSTALLED && !action_run_with_compat.visible; + action_run.sensitive = game.can_be_launched(); + action_open_directory.visible = s.state == Game.State.INSTALLED && game.install_dir != null && game.install_dir.query_exists(); + action_open_installer_collection_directory.visible = game.installers_dir != null && game.installers_dir.query_exists(); + action_open_bonus_collection_directory.visible = game is GameHub.Data.Sources.GOG.GOGGame && (game as GameHub.Data.Sources.GOG.GOGGame).bonus_content_dir != null && (game as GameHub.Data.Sources.GOG.GOGGame).bonus_content_dir.query_exists(); + action_open_screenshots_directory.visible = game is GameHub.Data.Sources.Steam.SteamGame && (game as GameHub.Data.Sources.Steam.SteamGame).screenshots_dir != null && (game as GameHub.Data.Sources.Steam.SteamGame).screenshots_dir.query_exists(); + action_open_store_page.visible = game.store_page != null; + action_uninstall.visible = s.state == Game.State.INSTALLED && !(game is GameHub.Data.Sources.GOG.GOGGame.DLC); + action_properties.visible = !(game is GameHub.Data.Sources.GOG.GOGGame.DLC); + + if(action_run_with_compat.visible && game.compat_tool != null) + { + foreach(var tool in CompatTools) + { + if(tool.id == game.compat_tool) + { + action_run_with_compat.icon_overlay = tool.icon; + break; + } + } + } + } + + public void update() + { + Utils.thread("GameDetailsPageUpdate", () => { + update_game.begin(); + }); + } + + private async void update_game() + { + is_dialog = !(get_toplevel() is GameHub.UI.Windows.MainWindow); + + title.max_width_chars = is_dialog ? 36 : -1; + + #if GTK_3_22 + content_scrolled.max_content_height = is_dialog ? 640 : -1; + #endif + + if(is_updated) return; + + if(spinner.parent == stack) + { + stack.visible_child = spinner; + } + + if(game == null) return; + + yield game.update_game_info(); + + is_updated = true; + + title.label = game.name; + src_icon.icon_name = game.source.icon; + + platform_icons.foreach(w => platform_icons.remove(w)); + foreach(var p in game.platforms) + { + var icon = new Image(); + icon.icon_name = p.icon(); + icon.icon_size = IconSize.DIALOG; + icon.opacity = 0.1; + platform_icons.add(icon); + } + platform_icons.show_all(); + + blocks.foreach(b => b.destroy()); + sidebar.foreach(b => b.destroy()); + + var desc = new Blocks.Description(game, is_dialog); + var igdb = new Blocks.IGDBInfo(game, desc, is_dialog); + + GameDetailsBlock[] blk = { + new Blocks.Achievements(game, is_dialog), + igdb.description, + desc + }; + GameDetailsBlock[] sidebar_blk = { + new Blocks.Artwork(game, details_view), + new Blocks.Playtime(game), + igdb, + new Blocks.SteamDetails(game), + new Blocks.GOGDetails(game, this) + }; + + foreach(var b in blk) + { + if(b.supports_game) + { + blocks.add(b); + } + } + foreach(var b in sidebar_blk) + { + if(b.supports_game) + { + sidebar.add(b); + } + } + + game.status_change.connect(s => { + Idle.add(() => { + set_visible_widgets(s); + return Source.REMOVE; + }); + }); + set_visible_widgets(game.status); + + icon.load(game.icon, null, @"games/$(game.source.id)/$(game.id)/icons/"); + no_icon_indicator.visible = game.icon == null || icon.source == null; + + if(content_scrolled.parent == stack) + { + stack.visible_child = content_scrolled; + } + } + + private void install_game() + { + if(_game != null && game.status.state == Game.State.UNINSTALLED) + { + game.install.begin(); + } + } + + private void game_properties() + { + if(_game != null) + { + new Dialogs.GamePropertiesDialog(game).show_all(); + } + } + + private void open_game_directory() + { + if(_game != null && game.status.state == Game.State.INSTALLED && game.install_dir != null && game.install_dir.query_exists()) + { + Utils.open_uri(game.install_dir.get_uri()); + } + } + + private void open_installer_collection_directory() + { + if(_game != null && game.installers_dir != null && game.installers_dir.query_exists()) + { + Utils.open_uri(game.installers_dir.get_uri()); + } + } + + private void open_bonus_collection_directory() + { + if(_game != null && game is GameHub.Data.Sources.GOG.GOGGame) + { + var gog_game = game as GameHub.Data.Sources.GOG.GOGGame; + if(gog_game != null && gog_game.bonus_content_dir != null && gog_game.bonus_content_dir.query_exists()) + { + Utils.open_uri(gog_game.bonus_content_dir.get_uri()); + } + } + } + + private void open_screenshots_directory() + { + if(_game != null && game is GameHub.Data.Sources.Steam.SteamGame) + { + var steam_game = game as GameHub.Data.Sources.Steam.SteamGame; + if(steam_game != null && steam_game.screenshots_dir != null && steam_game.screenshots_dir.query_exists()) + { + Utils.open_uri(steam_game.screenshots_dir.get_uri()); + } + } + } + + private void open_game_store_page() + { + if(_game != null && game.store_page != null) + { + Utils.open_uri(game.store_page); + } + } + + private void run_game() + { + if(_game != null && game.status.state == Game.State.INSTALLED) + { + game.run.begin(); + } + } + + private void run_game_with_compat() + { + if(_game != null && game.status.state == Game.State.INSTALLED) + { + game.run_with_compat.begin(false); + } + } + + private void uninstall_game() + { + if(_game != null && game.status.state == Game.State.INSTALLED) + { + game.uninstall.begin(); + } + } + + private void open_context_menu(Event e, bool at_pointer=true) + { + if(_game != null) + { + new GameContextMenu(game, this).open(e, at_pointer); + } + } + + private delegate void Action(); + private ActionButton add_action(string icon, string? icon_overlay, string title, Action action, bool primary=false) + { + var ui_settings = Settings.UI.Appearance.instance; + var button = new ActionButton(icon + Settings.UI.Appearance.symbolic_icon_suffix, icon_overlay, title, primary, ui_settings.icon_style.is_symbolic()); + button.hexpand = primary; + actions.add(button); + button.clicked.connect(() => action()); + ui_settings.notify["icon-style"].connect(() => { + button.icon = icon + Settings.UI.Appearance.symbolic_icon_suffix; + button.compact = ui_settings.icon_style.is_symbolic(); + }); + return button; + } + } +} diff --git a/src/ui/views/GameDetailsView/GameDetailsView.vala b/src/ui/views/GameDetailsView/GameDetailsView.vala new file mode 100644 index 00000000..560779af --- /dev/null +++ b/src/ui/views/GameDetailsView/GameDetailsView.vala @@ -0,0 +1,278 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; +using Gee; + +using GameHub.Data; +using GameHub.Data.DB; +using GameHub.Utils; +using GameHub.UI.Widgets; + +namespace GameHub.UI.Views.GameDetailsView +{ + public class GameDetailsView: BaseView + { + private Game? _game; + private ArrayList? _selected_games; + + public GameSource? preferred_source { get; set; } + + public int content_margin = 8; + + public Game? game + { + get { return _game; } + set + { + _game = value; + _selected_games = null; + navigation.clear(); + navigation.add(game); + Idle.add(() => { + update(); + return Source.REMOVE; + }); + } + } + + public ArrayList? selected_games + { + get { return _selected_games; } + set + { + _selected_games = value; + _game = null; + Idle.add(() => { + update_selected_games(); + return Source.REMOVE; + }); + } + } + + public GameDetailsView(Game? game=null) + { + Object(game: game); + } + + private Stack root_stack; + public MultipleGamesDetailsView selected_games_view; + private Box game_box; + + private Stack stack; + + private Button back_button; + private ExtendedStackSwitcher stack_tabs; + + private Revealer actions; + + private ArrayList navigation = new ArrayList(Game.is_equal); + + construct + { + root_stack = new Stack(); + root_stack.transition_type = StackTransitionType.NONE; + root_stack.expand = true; + + stack = new Stack(); + stack.transition_type = StackTransitionType.SLIDE_LEFT_RIGHT; + stack.expand = true; + + stack_tabs = new ExtendedStackSwitcher(stack); + stack_tabs.valign = Align.CENTER; + stack_tabs.halign = Align.CENTER; + stack_tabs.expand = false; + stack_tabs.visible = false; + + back_button = new Button.with_label(""); + back_button.tooltip_text = _("Back"); + back_button.valign = Align.CENTER; + back_button.expand = false; + back_button.visible = false; + back_button.margin_top = back_button.margin_bottom = 6; + StyleClass.add(back_button, StyleClass.BACK_BUTTON); + + back_button.clicked.connect(() => { + if(navigation.size > 1) + { + navigation.remove_at(navigation.size - 1); + } + Idle.add(() => { + update(); + return Source.REMOVE; + }); + }); + + game_box = new Box(Orientation.VERTICAL, 0); + + actions = new Revealer(); + actions.transition_type = RevealerTransitionType.SLIDE_DOWN; + actions.reveal_child = false; + + var actionbar = new ActionBar(); + actionbar.get_style_context().add_class("gameinfo-toolbar"); + actionbar.pack_start(back_button); + actionbar.set_center_widget(stack_tabs); + + actions.add(actionbar); + + game_box.add(actions); + game_box.add(stack); + + selected_games_view = new MultipleGamesDetailsView(); + + root_stack.add(game_box); + root_stack.add(selected_games_view); + + root_stack.visible_child = game_box; + + add(root_stack); + + stack.notify["visible-child"].connect(() => { + var page = stack.visible_child as GameDetailsPage; + if(page != null) + { + Idle.add(() => { + page.update(); + return Source.REMOVE; + }); + } + }); + + get_style_context().add_class("gameinfo-background"); + var ui_settings = GameHub.Settings.UI.Appearance.instance; + ui_settings.notify["dark-theme"].connect(() => { + get_style_context().remove_class("dark"); + if(ui_settings.dark_theme) get_style_context().add_class("dark"); + }); + ui_settings.notify_property("dark-theme"); + + notify["preferred-source"].connect(() => { + if(preferred_source != null) + { + var id = preferred_source.id; + foreach(var page in stack.get_children()) + { + var page_id = Value(typeof(string)); + stack.child_get_property(page, "name", ref page_id); + if(page_id.holds(typeof(string)) && page_id.get_string().has_prefix(@"$(id):")) + { + stack.set_visible_child_full(page_id.get_string(), StackTransitionType.NONE); + } + } + } + }); + + Idle.add(() => { + update(); + return Source.REMOVE; + }); + } + + public void navigate(Game g) + { + navigation.add(g); + + Idle.add(() => { + update(); + return Source.REMOVE; + }); + } + + private void update() + { + root_stack.visible_child = game_box; + + stack_tabs.clear(); + + back_button.visible = false; + if(navigation.size > 1) + { + back_button.visible = true; + back_button.label = navigation.get(navigation.size - 2).name; + } + + var g = navigation.get(navigation.size - 1); + + if(g == null) return; + + var primary = Settings.UI.Behavior.instance.merge_games ? Tables.Merges.get_primary(g) : null; + var merges = Settings.UI.Behavior.instance.merge_games ? Tables.Merges.get(g) : null; + bool merged = merges != null && merges.size > 0; + + stack_tabs.visible = merged || primary != null; + + add_page(g); + + if(primary != null) + { + if(!Game.is_equal(g, primary)) + { + add_page(primary); + } + merges = Tables.Merges.get(primary); + merged = merges != null && merges.size > 0; + } + + if(merged) + { + foreach(var m in merges) + { + if(Game.is_equal(g, m) + || !m.is_supported(null) + || (g is Sources.GOG.GOGGame.DLC && Game.is_equal((g as Sources.GOG.GOGGame.DLC).game, m))) + { + continue; + } + + add_page(m); + } + } + + stack_tabs.visible = stack.get_children().length() > 1; + + actions.reveal_child = back_button.visible || stack_tabs.visible; + + stack.show_all(); + + Idle.add(() => { + notify_property("preferred-source"); + return Source.REMOVE; + }); + } + + private void add_page(Game g) + { + if(stack.get_child_by_name(g.full_id) != null) return; + + var label = """%s%s""".printf(g.source.name, "\n" + g.name.replace("&", "&").replace("&", "&")); + + var page = new GameDetailsPage(g, this); + page.content.margin = content_margin; + stack_tabs.add_tab(page, g.full_id, label, true, g.source.icon); + } + + private void update_selected_games() + { + if(selected_games == null) return; + selected_games_view.games = selected_games; + root_stack.visible_child = selected_games_view; + } + } +} diff --git a/src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala b/src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala new file mode 100644 index 00000000..33d3379b --- /dev/null +++ b/src/ui/views/GameDetailsView/MultipleGamesDetailsView.vala @@ -0,0 +1,279 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; +using Gee; + +using GameHub.Data; +using GameHub.Data.DB; +using GameHub.Utils; +using GameHub.UI.Widgets; + +namespace GameHub.UI.Views.GameDetailsView +{ + public class MultipleGamesDetailsView: Grid + { + public signal void download_images(ArrayList games); + + private ArrayList? _games; + public ArrayList? games + { + get { return _games; } + set + { + _games = value; + Idle.add(() => { + update(); + return Source.REMOVE; + }); + } + } + + private Label header; + private Box actions; + private GameTagsList tags; + + private ArrayList? installable; + private ArrayList? downloadable; + private ArrayList? no_images; + private ArrayList? uninstallable; + private ArrayList? refreshable; + + public MultipleGamesDetailsView(ArrayList? games=null) + { + Object(games: games); + } + + construct + { + header = Styled.H2Label(null); + header.halign = Align.START; + header.wrap = true; + header.xalign = 0; + header.hexpand = true; + header.margin = 24; + + var actions_wrapper = new Box(Orientation.VERTICAL, 0); + actions_wrapper.expand = true; + + actions = new Box(Orientation.VERTICAL, 0); + actions.margin = 16; + actions.margin_top = 0; + + actions_wrapper.add(actions); + + tags = new GameTagsList(); + tags.get_style_context().add_class(Gtk.STYLE_CLASS_VIEW); + tags.width_request = 200; + tags.hexpand = false; + + attach(header, 0, 0); + attach(actions_wrapper, 0, 1); + attach(new Separator(Orientation.VERTICAL), 1, 0, 1, 2); + attach(tags, 2, 0, 1, 2); + + show_all(); + } + + private void update() + { + if(games == null) return; + + tags.games = games; + + header.label = ngettext("%d game selected", "%d games selected", games.size).printf(games.size); + + actions.foreach(w => w.destroy()); + + installable = new ArrayList(); + downloadable = new ArrayList(); + no_images = new ArrayList(); + uninstallable = new ArrayList(); + refreshable = new ArrayList(); + + foreach(var g in games) + { + if(g.status.state == Game.State.INSTALLED) + { + uninstallable.add(g); + } + else + { + if(!(g is Sources.User.UserGame)) + { + refreshable.add(g); + if(g.is_installable) + { + if(g.status.state == Game.State.UNINSTALLED) + { + installable.add(g); + } + if(!(g is Sources.Steam.SteamGame)) + { + downloadable.add(g); + } + } + } + } + if(g.image == null) + { + no_images.add(g); + } + } + + if(installable.size > 0) + { + add_action_separator(); + var action_install = add_action("go-down", null, _("Install"), install_games); + action_install.text += "\n" + """%s""".printf(ngettext("%d game will be installed", "%d games will be installed", installable.size).printf(installable.size)); + } + + if(downloadable.size > 0) + { + if(installable.size == 0) + { + add_action_separator(); + } + var action_download = add_action("folder-download", null, _("Download"), download_games); + action_download.text += "\n" + """%s""".printf(ngettext("%d game will be downloaded", "%d games will be downloaded", downloadable.size).printf(downloadable.size)); + } + + if(no_images.size > 0) + { + add_action_separator(); + var action_download_images = add_action("image-x-generic", null, _("Download images"), download_game_images); + action_download_images.text += "\n" + """%s""".printf(ngettext("Image for %d game will be searched", "Images for %d games will be searched", no_images.size).printf(no_images.size)); + } + + if(uninstallable.size > 0) + { + add_action_separator(); + var action_uninstall = add_action("edit-delete", null, _("Uninstall"), uninstall_games); + action_uninstall.text += "\n" + """%s""".printf(ngettext("%d game will be uninstalled", "%d games will be uninstalled", uninstallable.size).printf(uninstallable.size)); + } + + if(refreshable.size > 0) + { + add_action_separator(); + var action_refresh = add_action("view-refresh", null, _("Refresh"), refresh_games); + action_refresh.text += "\n" + """%s""".printf(ngettext("%d game will be removed from database. Restart GameHub to fetch new data", "%d games will be removed from database. Restart GameHub to fetch new data", refreshable.size).printf(refreshable.size)); + } + + actions.show_all(); + } + + private void install_games() + { + if(installable == null || installable.size == 0) return; + + if(Sources.Steam.Steam.instance.enabled) + { + string[] steam_apps = {}; + foreach(var game in installable) + { + if(game is Sources.Steam.SteamGame) + { + steam_apps += game.id; + } + } + if(steam_apps.length > 0) + { + Sources.Steam.Steam.install_multiple_apps(steam_apps); + } + } + + foreach(var game in installable) + { + if(!(game is Sources.Steam.SteamGame)) + { + game.install.begin(Runnable.Installer.InstallMode.AUTOMATIC); + } + } + update(); + } + + private void download_games() + { + if(downloadable == null || downloadable.size == 0) return; + foreach(var game in downloadable) + { + if(!(game is Sources.Steam.SteamGame)) + { + game.install.begin(Runnable.Installer.InstallMode.AUTOMATIC_DOWNLOAD); + } + } + update(); + } + + private void download_game_images() + { + if(no_images == null || no_images.size == 0) return; + download_images(no_images); + update(); + } + + private void uninstall_games() + { + if(uninstallable == null || uninstallable.size == 0) return; + uninstall_games_async.begin(uninstallable); + } + + private void refresh_games() + { + if(refreshable == null || refreshable.size == 0) return; + foreach(var game in refreshable) + { + Tables.Games.remove(game); + } + update(); + } + + private async void uninstall_games_async(ArrayList games) + { + foreach(var game in games) + { + yield game.uninstall(); + } + update(); + } + + private void add_action_separator() + { + if(actions.get_children().length() == 0) return; + var separator = new Separator(Orientation.HORIZONTAL); + separator.margin = 4; + actions.add(separator); + } + + private delegate void Action(); + private ActionButton add_action(string icon, string? icon_overlay, string title, Action action) + { + var ui_settings = Settings.UI.Appearance.instance; + var button = new ActionButton(icon + Settings.UI.Appearance.symbolic_icon_suffix, icon_overlay, title, true, ui_settings.icon_style.is_symbolic()); + button.hexpand = true; + actions.add(button); + button.clicked.connect(() => action()); + ui_settings.notify["icon-style"].connect(() => { + button.icon = icon + Settings.UI.Appearance.symbolic_icon_suffix; + button.compact = ui_settings.icon_style.is_symbolic(); + }); + return button; + } + } +} diff --git a/src/ui/views/GameDetailsView/blocks/Achievements.vala b/src/ui/views/GameDetailsView/blocks/Achievements.vala new file mode 100644 index 00000000..c8875f5d --- /dev/null +++ b/src/ui/views/GameDetailsView/blocks/Achievements.vala @@ -0,0 +1,110 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; +using Gee; + +using GameHub.Data; +using GameHub.Data.Sources.Steam; +using GameHub.Data.Sources.GOG; + +using GameHub.Utils; + +using GameHub.UI.Widgets; + +namespace GameHub.UI.Views.GameDetailsView.Blocks +{ + public class Achievements: GameDetailsBlock + { + private const int IMAGE_SIZE = 32; + + public Achievements(Game game, bool is_dialog) + { + Object(game: game, orientation: Orientation.VERTICAL, text_max_width: is_dialog ? 80 : -1); + } + + construct + { + if(!supports_game) return; + + var header = Styled.H4Label(_("Achievements"), "description-header"); + header.margin_start = header.margin_end = 7; + + var achievements_scrolled = new ScrolledWindow(null, null); + achievements_scrolled.hscrollbar_policy = PolicyType.AUTOMATIC; + achievements_scrolled.vscrollbar_policy = PolicyType.NEVER; + + var achievements_box = new Box(Orientation.HORIZONTAL, 4); + achievements_box.margin_top = 8; + achievements_box.margin_start = achievements_box.margin_end = 7; + achievements_box.margin_bottom = 12; + + achievements_scrolled.add(achievements_box); + + game.load_achievements.begin((obj, res) => { + game.load_achievements.end(res); + + if(game.achievements == null || game.achievements.size < 1) return; + + achievements_box.foreach(a => a.destroy()); + + foreach(var achievement in game.achievements) + { + var image = new AutoSizeImage(); + image.valign = Align.CENTER; + image.corner_radius = IMAGE_SIZE / 2; + image.set_constraint(IMAGE_SIZE, IMAGE_SIZE, 1); + image.set_size_request(IMAGE_SIZE, IMAGE_SIZE); + image.opacity = achievement.unlocked ? 1 : 0.2; + + image.tooltip_markup = """%s""".printf(achievement.name.replace("&", "&").replace("&", "&")) + "\n"; + + if(achievement.description.length > 0) + { + image.tooltip_markup += """%s""".printf(achievement.description.replace("&", "&").replace("&", "&")) + "\n"; + } + + if(achievement.unlocked) + { + image.tooltip_markup += "\n" + """%s""".printf(_("Unlocked: %s").printf(achievement.unlock_time)); + } + + if(achievement.global_percentage > 0) + { + image.tooltip_markup += "\n" + """%s""".printf(_("Global percentage: %g%%").printf(achievement.global_percentage)); + } + + image.load(achievement.image, null, @"games/$(game.source.id)/$(game.id)/achievements/$(achievement.id)/"); + achievements_box.add(image); + } + achievements_box.show_all(); + + Idle.add(() => { + add(header); + add(achievements_scrolled); + show_all(); + if(parent != null) parent.queue_draw(); + return Source.REMOVE; + }); + }); + } + + public override bool supports_game { get { return game is SteamGame || game is GOGGame; } } + } +} diff --git a/src/ui/views/GameDetailsView/blocks/Artwork.vala b/src/ui/views/GameDetailsView/blocks/Artwork.vala new file mode 100644 index 00000000..76777b3a --- /dev/null +++ b/src/ui/views/GameDetailsView/blocks/Artwork.vala @@ -0,0 +1,102 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; +using Gee; + +using GameHub.Data; +using GameHub.Utils; +using GameHub.UI.Widgets; + +namespace GameHub.UI.Views.GameDetailsView.Blocks +{ + public class Artwork: GameDetailsBlock + { + private AutoSizeImage image_view; + + public GameDetailsView details_view { get; construct; } + + public Artwork(Game game, GameDetailsView details_view) + { + Object(game: game, orientation: Orientation.VERTICAL, text_max_width: 48, details_view: details_view); + } + + construct + { + var card = Styled.Card("gamecard", "static"); + + image_view = new AutoSizeImage(); + image_view.hexpand = false; + + var actions = new Box(Orientation.VERTICAL, 0); + actions.get_style_context().add_class("actions"); + actions.hexpand = true; + actions.vexpand = false; + + var image_overlay = new Overlay(); + image_overlay.add(image_view); + image_overlay.add_overlay(actions); + + var images_download_btn = new MenuButton(); + images_download_btn.get_style_context().add_class("images-download-button"); + images_download_btn.margin = 8; + images_download_btn.halign = Align.END; + images_download_btn.valign = Align.START; + images_download_btn.image = new Image.from_icon_name("folder-download-symbolic", IconSize.BUTTON); + images_download_btn.tooltip_text = _("Download images"); + + image_overlay.add_overlay(images_download_btn); + + card.add(image_overlay); + add(card); + + Allocation alloc; + details_view.get_allocation(out alloc); + + var images_download_popover = new ImagesDownloadPopover(game, images_download_btn, alloc.width - 200, alloc.height - 200); + + Settings.UI.Appearance.instance.notify["grid-card-width"].connect(update_image_constraints); + Settings.UI.Appearance.instance.notify["grid-card-height"].connect(update_image_constraints); + update_image_constraints(); + + game.notify["image"].connect(load_image); + game.notify["image-vertical"].connect(load_image); + load_image(); + + show_all(); + if(parent != null) parent.queue_draw(); + } + + private void load_image() + { + image_view.load(game.image, game.image_vertical, @"games/$(game.source.id)/$(game.id)/images/"); + } + + private void update_image_constraints() + { + var w = Settings.UI.Appearance.instance.grid_card_width; + var h = Settings.UI.Appearance.instance.grid_card_height; + var ratio = (float) h / w; + image_view.set_constraint(360, 360, ratio); + if(parent != null) parent.queue_draw(); + } + + public override bool supports_game { get { return true; } } + } +} diff --git a/src/ui/views/GameDetailsView/blocks/Description.vala b/src/ui/views/GameDetailsView/blocks/Description.vala new file mode 100644 index 00000000..1a7a4464 --- /dev/null +++ b/src/ui/views/GameDetailsView/blocks/Description.vala @@ -0,0 +1,98 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using GameHub.UI.Widgets; + +using Gdk; +using Gee; + +#if WEBKIT2GTK +using WebKit; +#endif + +using GameHub.Data; +using GameHub.Data.Sources.Humble; + +namespace GameHub.UI.Views.GameDetailsView.Blocks +{ + public class Description: GameDetailsBlock + { + #if WEBKIT2GTK + private WebView description; + #endif + + private const string CSS = "body{overflow: hidden; font-size: 0.8em; margin: 7px; line-height: 1.4; %s} h1,h2,h3{line-height: 1.2;} ul{padding: 4px 0 4px 16px;} img{max-width: 100%; display: block;}"; + private const string CSS_COLORS = "background: %s; color: %s;"; + private const string WRAPPER_HTML = "
%s
"; + private string? current_colors; + + public Description(Game game, bool is_dialog) + { + Object(game: game, orientation: Orientation.VERTICAL, text_max_width: is_dialog ? 80 : -1); + } + + construct + { + if(!supports_game) return; + + get_style_context().add_class(Gtk.STYLE_CLASS_BACKGROUND); + + #if WEBKIT2GTK + description = new WebView(); + description.hexpand = true; + description.vexpand = true; + description.sensitive = false; + description.get_settings().hardware_acceleration_policy = HardwareAccelerationPolicy.NEVER; + + update_colors(); + state_flags_changed.connect(() => update_colors()); + GameHub.Settings.UI.Appearance.instance.notify["dark-theme"].connect(() => update_colors()); + + description.set_size_request(-1, -1); + var desc = WRAPPER_HTML.printf(game.description); + description.load_html(desc, null); + description.notify["title"].connect(e => { + description.set_size_request(-1, -1); + var height = int.parse(description.title); + description.set_size_request(-1, height + 8); + }); + + add(description); + #endif + + show_all(); + if(parent != null) parent.queue_draw(); + } + + private void update_colors() + { + #if WEBKIT2GTK + var colors = CSS_COLORS.printf(get_style_context().get_background_color(get_state_flags()).to_string(), get_style_context().get_color(get_state_flags()).to_string()); + if(colors != current_colors) + { + description.user_content_manager.remove_all_style_sheets(); + description.user_content_manager.add_style_sheet(new UserStyleSheet(CSS.printf(colors), UserContentInjectedFrames.TOP_FRAME, UserStyleLevel.USER, null, null)); + current_colors = colors; + } + #endif + } + + public override bool supports_game { get { return game.description != null; } } + } +} diff --git a/src/ui/views/GameDetailsView/blocks/GOGDetails.vala b/src/ui/views/GameDetailsView/blocks/GOGDetails.vala new file mode 100644 index 00000000..60288818 --- /dev/null +++ b/src/ui/views/GameDetailsView/blocks/GOGDetails.vala @@ -0,0 +1,393 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; +using Gee; + +using GameHub.Data; +using GameHub.Data.Sources.GOG; + +using GameHub.UI.Widgets; +using GameHub.UI.Views.GamesView; + +using GameHub.Utils; + +namespace GameHub.UI.Views.GameDetailsView.Blocks +{ + public class GOGDetails: GameDetailsBlock + { + public GameDetailsPage details_page { get; construct; } + + public GOGDetails(Game game, GameDetailsPage page) + { + Object(game: game, orientation: Orientation.VERTICAL, details_page: page, text_max_width: 48); + } + + construct + { + if(!supports_game) return; + + var gog_game = game as GOGGame; + + var root = Parser.parse_json(game.info_detailed); + + if(root == null || gog_game == null) return; + + get_style_context().add_class("gameinfo-sidebar-block"); + + var link = new ActionButton(game.source.icon, null, "GOG", true, true); + if(game.store_page != null) + { + link.tooltip_text = game.store_page; + link.clicked.connect(() => { + Utils.open_uri(game.store_page); + }); + } + + add(link); + add(new Separator(Orientation.HORIZONTAL)); + + var langs = Parser.json_object(root, {"languages"}); + if(langs != null) + { + var sys_langs = Intl.get_language_names(); + var langs_string = ""; + foreach(var l in langs.get_members()) + { + var lang = langs.get_string_member(l); + if(l in sys_langs) lang = @"$(lang)"; + langs_string += (langs_string.length > 0 ? ", " : "") + lang; + } + var langs_label = _("Language"); + if(langs_string.contains(",")) + { + langs_label = _("Languages"); + } + add_info_label(langs_label, langs_string, langs_string.contains(","), true); + } + + if(gog_game.dlc != null && gog_game.dlc.size > 0) + { + add(new Separator(Orientation.HORIZONTAL)); + + var installable = new ArrayList(); + var not_installable = new ArrayList(); + + foreach(var dlc in gog_game.dlc) + { + (dlc.is_installable ? installable : not_installable).add(dlc); + } + + var dlcbox = new Box(Orientation.VERTICAL, 0); + var header = Styled.H4Label(_("DLC")); + header.margin_start = header.margin_end = 8; + dlcbox.add(header); + + if(installable.size > 0 || not_installable.size <= 3) + { + var dlclist = new ListBox(); + dlclist.selection_mode = SelectionMode.NONE; + dlclist.get_style_context().add_class("gameinfo-content-list"); + + foreach(var dlc in installable) + { + dlclist.add(new DLCRow(dlc, details_page)); + } + + if(not_installable.size <= 3) + { + foreach(var dlc in not_installable) + { + dlclist.add(new DLCRow(dlc, details_page)); + } + } + + dlcbox.add(dlclist); + } + + if(not_installable.size > 3) + { + var dlclist_scrolled = new ScrolledWindow(null, null); + dlclist_scrolled.hscrollbar_policy = PolicyType.NEVER; + dlclist_scrolled.set_size_request(420, 64); + + #if GTK_3_22 + dlclist_scrolled.propagate_natural_width = true; + dlclist_scrolled.propagate_natural_height = true; + dlclist_scrolled.max_content_height = 720; + #endif + + var dlclist = new ListBox(); + dlclist.selection_mode = SelectionMode.NONE; + dlclist.get_style_context().add_class("gameinfo-content-list"); + + foreach(var dlc in not_installable) + { + dlclist.add(new DLCRow(dlc, details_page, false)); + } + + dlclist_scrolled.add(dlclist); + + var dlc_popover_button = new Button.with_label(_("%u DLCs cannot be installed").printf(not_installable.size)); + dlc_popover_button.get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + dlc_popover_button.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL); + + var dlc_popover = new Popover(dlc_popover_button); + dlc_popover.position = PositionType.LEFT; + + dlc_popover.add(dlclist_scrolled); + dlclist_scrolled.show_all(); + + dlc_popover_button.clicked.connect(() => { + #if GTK_3_22 + dlc_popover.popup(); + #else + dlc_popover.show(); + #endif + }); + + dlcbox.add(new Separator(Orientation.HORIZONTAL)); + dlcbox.add(dlc_popover_button); + } + + add(dlcbox); + } + + if(gog_game.bonus_content != null && gog_game.bonus_content.size > 0) + { + add(new Separator(Orientation.HORIZONTAL)); + + var bonuslist_scrolled = new ScrolledWindow(null, null); + bonuslist_scrolled.hscrollbar_policy = PolicyType.NEVER; + bonuslist_scrolled.set_size_request(420, 64); + + #if GTK_3_22 + bonuslist_scrolled.propagate_natural_width = true; + bonuslist_scrolled.propagate_natural_height = true; + bonuslist_scrolled.max_content_height = 720; + #endif + + var bonuslist = new ListBox(); + bonuslist.selection_mode = SelectionMode.NONE; + bonuslist.get_style_context().add_class("gameinfo-content-list"); + + foreach(var bonus in gog_game.bonus_content) + { + bonuslist.add(new BonusContentRow(bonus)); + } + + bonuslist_scrolled.add(bonuslist); + + var bonus_popover_button = new ActionButton("folder-download-symbolic", null, _("Bonus content"), true, true); + + var bonus_popover = new Popover(bonus_popover_button); + bonus_popover.position = PositionType.LEFT; + + bonus_popover.add(bonuslist_scrolled); + bonuslist_scrolled.show_all(); + + bonus_popover_button.clicked.connect(() => { + #if GTK_3_22 + bonus_popover.popup(); + #else + bonus_popover.show(); + #endif + }); + + add(bonus_popover_button); + } + + show_all(); + if(parent != null) parent.queue_draw(); + } + + public override bool supports_game { get { return (game is GOGGame) && game.info_detailed != null && game.info_detailed.length > 0; } } + + public class BonusContentRow: ListBoxRow + { + public GOGGame.BonusContent bonus; + + public BonusContentRow(GOGGame.BonusContent bonus) + { + this.bonus = bonus; + + var content = new Overlay(); + + var progress_bar = new Frame(null); + progress_bar.halign = Align.START; + progress_bar.vexpand = true; + progress_bar.get_style_context().add_class("progress"); + + var box = new Box(Orientation.HORIZONTAL, 8); + box.margin_start = box.margin_end = 8; + box.margin_top = box.margin_bottom = 8; + + var icon = new Image.from_icon_name(bonus.icon, IconSize.BUTTON); + + var name = new Label(bonus.text); + name.ellipsize = Pango.EllipsizeMode.END; + name.hexpand = true; + name.halign = Align.START; + name.xalign = 0; + + var desc_label = new Label(format_size(bonus.size)); + desc_label.halign = Align.END; + + var status_icon = new Image.from_icon_name("folder-download-symbolic", IconSize.BUTTON); + status_icon.halign = Align.END; + + box.add(icon); + box.add(name); + box.add(desc_label); + box.add(status_icon); + + var event_box = new Box(Orientation.VERTICAL, 0); + event_box.expand = true; + + content.add(box); + content.add_overlay(progress_bar); + content.add_overlay(event_box); + + bonus.status_change.connect(s => { + if(s.state == GOGGame.BonusContent.State.DOWNLOADING) + { + Allocation alloc; + content.get_allocation(out alloc); + if(s.download != null && s.download.status != null) + { + progress_bar.get_style_context().add_class("downloading"); + progress_bar.set_size_request((int) (s.download.status.progress * alloc.width), alloc.height); + desc_label.label = s.download.status.description; + desc_label.get_style_context().remove_class(Gtk.STYLE_CLASS_DIM_LABEL); + desc_label.ellipsize = Pango.EllipsizeMode.NONE; + status_icon.icon_name = "folder-download-symbolic"; + } + return; + } + + progress_bar.get_style_context().remove_class("downloading"); + progress_bar.set_size_request(0, 0); + + if(s.state == GOGGame.BonusContent.State.DOWNLOADED && (bonus.downloaded_file == null || !bonus.downloaded_file.query_exists())) + { + s.state = GOGGame.BonusContent.State.NOT_DOWNLOADED; + } + + if(s.state == GOGGame.BonusContent.State.DOWNLOADED) + { + desc_label.label = bonus.filename; + desc_label.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL); + desc_label.ellipsize = Pango.EllipsizeMode.MIDDLE; + status_icon.icon_name = "document-open-symbolic"; + } + else + { + desc_label.label = format_size(bonus.size); + desc_label.get_style_context().remove_class(Gtk.STYLE_CLASS_DIM_LABEL); + desc_label.ellipsize = Pango.EllipsizeMode.NONE; + status_icon.icon_name = "folder-download-symbolic"; + } + }); + bonus.status_change(bonus.status); + + content.add_events(EventMask.ALL_EVENTS_MASK); + content.button_release_event.connect(e => { + if(e.button == 1) + { + if(bonus.status.state == GOGGame.BonusContent.State.NOT_DOWNLOADED || (bonus.status.state == GOGGame.BonusContent.State.DOWNLOADED && (bonus.downloaded_file == null || !bonus.downloaded_file.query_exists()))) + { + bonus.download.begin(); + } + else if(bonus.status.state == GOGGame.BonusContent.State.DOWNLOADED) + { + bonus.open(); + } + } + return true; + }); + + child = content; + } + } + + public class DLCRow: ListBoxRow + { + public GOGGame.DLC dlc; + + public DLCRow(GOGGame.DLC dlc, GameDetailsPage details_page, bool limit_name_width=true) + { + this.dlc = dlc; + + var ebox = new EventBox(); + ebox.margin_start = ebox.margin_end = 8; + ebox.margin_top = ebox.margin_bottom = 6; + + var box = new Box(Orientation.HORIZONTAL, 8); + + var name = new Label(dlc.name); + name.ellipsize = Pango.EllipsizeMode.END; + name.hexpand = true; + name.halign = Align.START; + name.xalign = 0; + + if(limit_name_width) + { + name.max_width_chars = 42; + name.tooltip_text = dlc.name; + } + + var status_icon = new Image.from_icon_name(dlc.status.state == Game.State.INSTALLED ? "process-completed-symbolic" : "folder-download-symbolic", IconSize.BUTTON); + status_icon.opacity = dlc.is_installable ? 1 : 0.6; + status_icon.halign = Align.END; + + ebox.add_events(EventMask.BUTTON_RELEASE_MASK); + ebox.button_release_event.connect(e => { + switch(e.button) + { + case 1: + details_page.details_view.navigate(dlc); + break; + + case 3: + new GameContextMenu(dlc, this).open(e, true); + break; + } + return true; + }); + + dlc.status_change.connect(() => { + Idle.add(() => { + status_icon.icon_name = dlc.status.state == Game.State.INSTALLED ? "process-completed-symbolic" : "folder-download-symbolic"; + status_icon.opacity = dlc.is_installable ? 1 : 0.6; + return Source.REMOVE; + }); + }); + + dlc.update_game_info.begin(); + + box.add(name); + box.add(status_icon); + + ebox.add(box); + + child = ebox; + } + } + } +} diff --git a/src/ui/views/GameDetailsView/blocks/IGDBInfo.vala b/src/ui/views/GameDetailsView/blocks/IGDBInfo.vala new file mode 100644 index 00000000..7556c4c5 --- /dev/null +++ b/src/ui/views/GameDetailsView/blocks/IGDBInfo.vala @@ -0,0 +1,324 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; +using Gee; + +using GameHub.Data; +using GameHub.Utils; +using GameHub.UI.Widgets; + +namespace GameHub.UI.Views.GameDetailsView.Blocks +{ + public class IGDBInfo: GameDetailsBlock + { + public Description description_block { private get; construct; } + public IGDBDescription description { get; construct; } + + private ArrayList? results; + private int result_index = 0; + + public IGDBInfo(Game game, Description desc, bool is_dialog) + { + Object(game: game, orientation: Orientation.VERTICAL, description_block: desc, text_max_width: 48, description: new IGDBDescription(game, desc, is_dialog)); + } + + construct + { + if(!supports_game) return; + + get_style_context().add_class("igdb-data-container"); + + Providers.Data.IGDB.instance.data.begin(game, (obj, res) => { + results = Providers.Data.IGDB.instance.data.end(res); + if(results == null || results.size == 0) return; + set_result_index(DB.Tables.IGDBData.get_index(game)); + }); + } + + private void set_result(Providers.Data.IGDB.Result result) + { + this.foreach(w => w.destroy()); + + var igdb_link_hbox = new Box(Orientation.HORIZONTAL, 0); + StyleClass.add(igdb_link_hbox, Gtk.STYLE_CLASS_LINKED); + + var igdb_link = new ActionButton(Providers.Data.IGDB.instance.icon, null, "IGDB", true, true); + igdb_link.hexpand = true; + if(result.url != null) + { + igdb_link.tooltip_text = result.url; + igdb_link.clicked.connect(() => { + Utils.open_uri(result.url); + }); + } + else + { + igdb_link.sensitive = false; + } + + igdb_link_hbox.add(igdb_link); + + if(results.size > 1) + { + var menu = new Gtk.Menu(); + menu.halign = Align.END; + + for(int i = 0; i < results.size; i++) + { + var index = i; + var item = new CheckMenuItem.with_label(results[index].name); + item.draw_as_radio = true; + item.active = index == result_index; + item.activate.connect(() => { + set_result_index(index); + }); + menu.add(item); + } + + menu.show_all(); + + var menu_btn = new MenuButton(); + StyleClass.add(menu_btn, Gtk.STYLE_CLASS_FLAT); + menu_btn.popup = menu; + + igdb_link_hbox.add(menu_btn); + } + + add(igdb_link_hbox); + + if(result.popularity != null) + { + add(new Separator(Orientation.HORIZONTAL)); + add_label(C_("igdb", "Popularity"), "%.1f".printf(result.popularity), false, true); + } + + if((result.aggregated_rating_count != null && result.aggregated_rating_count > 0) || (result.igdb_rating_count != null && result.igdb_rating_count > 0) || (result.total_rating_count != null && result.total_rating_count > 0)) + { + add(new Separator(Orientation.HORIZONTAL)); + add_rating(C_("igdb", "Aggregated rating"), result.aggregated_rating, result.aggregated_rating_count); + add_rating(C_("igdb", "IGDB user rating"), result.igdb_rating, result.igdb_rating_count); + add_rating(C_("igdb", "Total rating"), result.total_rating, result.total_rating_count); + } + + if(result.release_date != null) + { + var date = new DateTime.from_unix_utc(result.release_date); + if(date != null) + { + add(new Separator(Orientation.HORIZONTAL)); + add_label(C_("igdb", "Release date"), date.format("%x"), false, true); + } + } + + if(result.platforms != null) + { + add(new Separator(Orientation.HORIZONTAL)); + add_link_list(C_("igdb", "Platforms"), result.platforms); + } + + if(result.genres != null) + { + add(new Separator(Orientation.HORIZONTAL)); + add_link_list(C_("igdb", "Genres"), result.genres); + } + + if(result.keywords != null) + { + add(new Separator(Orientation.HORIZONTAL)); + add_link_list(C_("igdb", "Keywords"), result.keywords); + } + + if(result.websites != null) + { + add(new Separator(Orientation.HORIZONTAL)); + + var links_label = Styled.H4Label(C_("igdb", "Links")); + links_label.margin_start = links_label.margin_end = 7; + links_label.get_style_context().add_class("igdb-data-container-scrollable-header"); + links_label.valign = Align.START; + add(links_label); + + var links_scroll = new ScrolledWindow(null, null); + links_scroll.get_style_context().add_class("igdb-data-container-scrollable-value"); + links_scroll.vscrollbar_policy = PolicyType.NEVER; + links_scroll.hexpand = true; + + var links_box = new Box(Orientation.HORIZONTAL, 0); + links_box.get_style_context().add_class("gameinfo-multiline-value"); + links_box.margin_start = links_box.margin_end = 3; + + foreach(var site in result.websites) + { + var category_desc = site.category.description(); + var desc = """%s""".printf(site.url); + if(category_desc != null) + { + desc = "%s\n%s".printf("""%s""".printf(category_desc), desc); + } + var link = new ActionButton(site.category.icon(), null, desc, false, true); + link.clicked.connect(() => { + Utils.open_uri(site.url); + }); + links_box.add(link); + } + + links_scroll.add(links_box); + add(links_scroll); + } + + description.result = result; + + show_all(); + parent.queue_draw(); + } + + private void set_result_index(int index) + { + if(results.size > index) + { + result_index = index; + DB.Tables.IGDBData.set_index(game, index); + set_result(results[index]); + } + } + + public override bool supports_game { get { return Providers.Data.IGDB.instance.enabled; } } + + private void add_rating(string label, double? rating, int? count, Box? parent=null) + { + if(rating == null || count == null || count < 1) return; + var box = add_label(label, "%.1f / 100".printf(rating), false, true, parent); + box.tooltip_markup = ngettext("Based on %d rating", "Based on %d ratings", count).printf(count); + } + + private Box? add_label(string title, string? text, bool multiline=true, bool markup=false, Container? parent=null) + { + var box = add_info_label(title, text, multiline, markup, parent); + if(box != null) + { + box.margin_start -= 1; + box.margin_end -= 1; + } + return box; + } + + private Box? add_link_list(string title, Providers.Data.IGDB.Result.Link[] links, Container? parent=null) + { + var title_label = Styled.H4Label(title); + title_label.margin_start = title_label.margin_end = 7; + title_label.get_style_context().add_class("igdb-data-container-scrollable-header"); + title_label.set_size_request(128, -1); + title_label.valign = Align.CENTER; + + var links_scroll = new ScrolledWindow(null, null); + links_scroll.get_style_context().add_class("igdb-data-container-scrollable-value"); + links_scroll.vscrollbar_policy = PolicyType.NEVER; + links_scroll.hexpand = true; + + var links_box = new Box(Orientation.HORIZONTAL, 0); + links_box.margin_start = links_box.margin_end = 7; + links_box.get_style_context().add_class("gameinfo-multiline-value"); + links_box.hexpand = false; + + foreach(var link in links) + { + var button = new LinkButton.with_label(link.url, link.name); + button.hexpand = false; + if(links_box.get_children().length() > 0) + { + links_box.add(new Label(", ")); + } + links_box.add(button); + } + + links_scroll.add(links_box); + + var box = new Box(Orientation.VERTICAL, 0); + box.add(title_label); + box.add(links_scroll); + (parent ?? this).add(box); + + return box; + } + + public class IGDBDescription: GameDetailsBlock + { + public Description description_block { private get; construct; } + public Providers.Data.IGDB.Result? result { get; set; } + + public IGDBDescription(Game game, Description desc, bool is_dialog) + { + Object(game: game, orientation: Orientation.VERTICAL, description_block: desc, text_max_width: is_dialog ? 80 : -1); + } + + construct + { + if(!supports_game) return; + + get_style_context().add_class("igdb-data-container"); + + notify["result"].connect(() => { + this.hide(); + this.foreach(w => w.destroy()); + + if(result == null) return; + + var preferred_desc = Settings.Providers.Data.IGDB.instance.preferred_description; + var game_has_desc = description_block.supports_game && game.description != null; + + if(preferred_desc != Settings.Providers.Data.IGDB.PreferredDescription.GAME || !game_has_desc) + { + if(result.summary != null) + { + add_label(C_("igdb", "Summary"), result.summary, true, false); + + if(preferred_desc == Settings.Providers.Data.IGDB.PreferredDescription.IGDB) + { + description_block.destroy(); + } + } + + if(result.storyline != null) + { + if(result.summary != null) add(new Separator(Orientation.HORIZONTAL)); + add_label(C_("igdb", "Storyline"), result.storyline, true, false); + } + + show_all(); + if(parent != null) parent.queue_draw(); + } + }); + } + + public override bool supports_game { get { return Providers.Data.IGDB.instance.enabled; } } + + private Box? add_label(string title, string? text, bool multiline=true, bool markup=false, Container? parent=null) + { + var box = add_info_label(title, text, multiline, markup, parent); + if(box != null) + { + box.margin_start -= 1; + box.margin_end -= 1; + } + return box; + } + } + } +} diff --git a/src/ui/views/GameDetailsView/blocks/Playtime.vala b/src/ui/views/GameDetailsView/blocks/Playtime.vala new file mode 100644 index 00000000..b148c3c6 --- /dev/null +++ b/src/ui/views/GameDetailsView/blocks/Playtime.vala @@ -0,0 +1,79 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; +using Gee; + +using GameHub.Data; +using GameHub.Data.Sources.Steam; +using GameHub.Data.Sources.GOG; + +using GameHub.Utils; + +using GameHub.UI.Widgets; + +namespace GameHub.UI.Views.GameDetailsView.Blocks +{ + public class Playtime: GameDetailsBlock + { + public Playtime(Game game) + { + Object(game: game, orientation: Orientation.VERTICAL, text_max_width: 48); + } + + construct + { + if(!supports_game) return; + + get_style_context().add_class("gameinfo-sidebar-block"); + + var header = Styled.H4Label(_("Playtime")); + + var add_separator = false; + + if(game.playtime_tracked > 0) + { + add_info_label(_("Playtime (local)"), Utils.minutes_to_string(game.playtime_tracked), false, false); + add_separator = true; + } + + if(game.playtime_source > 0) + { + if(add_separator) add(new Separator(Orientation.HORIZONTAL)); + add_separator = true; + add_info_label(_("Playtime"), Utils.minutes_to_string(game.playtime_source), false, false); + } + + if(game.last_launch > 0) + { + var date = new GLib.DateTime.from_unix_local(game.last_launch); + if(date != null) + { + if(add_separator) add(new Separator(Orientation.HORIZONTAL)); + add_info_label(_("Last launch"), Utils.get_relative_datetime(date), false, false); + } + } + + show_all(); + if(parent != null) parent.queue_draw(); + } + + public override bool supports_game { get { return game.playtime_source > 0 || game.playtime_tracked > 0 || game.last_launch > 0; } } + } +} diff --git a/src/ui/views/GameDetailsView/blocks/SteamDetails.vala b/src/ui/views/GameDetailsView/blocks/SteamDetails.vala new file mode 100644 index 00000000..85117493 --- /dev/null +++ b/src/ui/views/GameDetailsView/blocks/SteamDetails.vala @@ -0,0 +1,118 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; +using Gee; + +using GameHub.Data; +using GameHub.Data.Sources.Steam; + +using GameHub.Utils; + +using GameHub.UI.Widgets; + +namespace GameHub.UI.Views.GameDetailsView.Blocks +{ + public class SteamDetails: GameDetailsBlock + { + public SteamDetails(Game game) + { + Object(game: game, orientation: Orientation.VERTICAL, text_max_width: 48); + } + + construct + { + if(!supports_game) return; + + var root = Parser.parse_json(game.info_detailed).get_object(); + var app = root.has_member(game.id) ? root.get_object_member(game.id) : null; + var data = app != null && app.has_member("data") ? app.get_object_member("data") : null; + if(data == null) return; + + get_style_context().add_class("gameinfo-sidebar-block"); + + var link = new ActionButton(game.source.icon, null, "Steam", true, true); + if(game.store_page != null) + { + link.tooltip_text = game.store_page; + link.clicked.connect(() => { + Utils.open_uri(game.store_page); + }); + } + + add(link); + + var categories = data.has_member("categories") ? data.get_array_member("categories") : null; + if(categories != null) + { + var categories_string = ""; + foreach(var c in categories.get_elements()) + { + var cat = c.get_object().get_string_member("description"); + categories_string += (categories_string.length > 0 ? ", " : "") + cat; + } + + var categories_label = _("Category"); + if(categories_string.contains(",")) + { + categories_label = _("Categories"); + } + add(new Separator(Orientation.HORIZONTAL)); + add_info_label(categories_label, categories_string, categories_string.contains(","), true); + } + + var genres = data.has_member("genres") ? data.get_array_member("genres") : null; + if(genres != null) + { + var genres_string = ""; + foreach(var g in genres.get_elements()) + { + var genre = g.get_object().get_string_member("description"); + genres_string += (genres_string.length > 0 ? ", " : "") + genre; + } + + var genres_label = _("Genre"); + if(genres_string.contains(",")) + { + genres_label = _("Genres"); + } + add(new Separator(Orientation.HORIZONTAL)); + add_info_label(genres_label, genres_string, genres_string.contains(","), true); + } + + var langs = data.has_member("supported_languages") ? data.get_string_member("supported_languages") : null; + if(langs != null) + { + langs = langs.split("
*")[0].replace("strong>", "b>"); + var langs_label = _("Language"); + if(langs.contains(",")) + { + langs_label = _("Languages"); + } + add(new Separator(Orientation.HORIZONTAL)); + add_info_label(langs_label, langs, langs.contains(","), true); + } + + show_all(); + if(parent != null) parent.queue_draw(); + } + + public override bool supports_game { get { return (game is SteamGame) && game.info_detailed != null && game.info_detailed.length > 0; } } + } +} diff --git a/src/ui/views/GamesGridView/GameCard.vala b/src/ui/views/GamesGridView/GameCard.vala deleted file mode 100644 index 2a130cab..00000000 --- a/src/ui/views/GamesGridView/GameCard.vala +++ /dev/null @@ -1,98 +0,0 @@ -using Gtk; -using Granite; -using GameHub.Data; -using GameHub.Utils; - -namespace GameHub.UI.Views -{ - public class GameCard: FlowBoxChild - { - public Game game; - - private Overlay content; - private AsyncImage image; - private Image src_icon; - private Label label; - - construct - { - var wrapper = new Box(Orientation.HORIZONTAL, 0); - wrapper.halign = Align.CENTER; - wrapper.valign = Align.CENTER; - - var card = new Box(Orientation.VERTICAL, 0); - card.get_style_context().add_class(Granite.STYLE_CLASS_CARD); - card.get_style_context().add_class("gamecard"); - - card.margin = 4; - card.halign = Align.CENTER; - card.valign = Align.CENTER; - - wrapper.add(card); - - child = wrapper; - - content = new Overlay(); - - image = new AsyncImage(); - - src_icon = new Image(); - src_icon.valign = Align.START; - src_icon.halign = Align.START; - src_icon.margin = 8; - src_icon.opacity = 0.5; - - label = new Label(""); - label.xpad = 8; - label.ypad = 8; - label.hexpand = true; - label.valign = Align.END; - label.justify = Justification.CENTER; - label.lines = 3; - label.set_line_wrap(true); - - content.add(image); - content.add_overlay(label); - content.add_overlay(src_icon); - - card.add(content); - - show_all(); - } - - public GameCard(Game game) - { - this.game = game; - - label.label = game.name; - - src_icon.pixbuf = FSUtils.get_icon(game.source.icon + "-white", 24); - - load_image.begin(); - } - - private async void load_image() - { - var hash = Checksum.compute_for_string(ChecksumType.MD5, game.image, game.image.length); - var remote = File.new_for_uri(game.image); - var cached = FSUtils.file(FSUtils.Paths.Cache.Images, hash + ".jpg"); - try - { - if(!cached.query_exists()) - { - image.set_from_file_async.begin(remote, 306, 143, false); - remote.copy_async.begin(cached, FileCopyFlags.NONE); - } - else - { - image.set_from_file_async.begin(cached, 306, 143, false); - } - } - catch(Error e) - { - error(e.message); - image.set_from_file_async.begin(remote, -1, -1, true); - } - } - } -} diff --git a/src/ui/views/GamesGridView/GamesGridView.vala b/src/ui/views/GamesGridView/GamesGridView.vala deleted file mode 100644 index 9e286e4f..00000000 --- a/src/ui/views/GamesGridView/GamesGridView.vala +++ /dev/null @@ -1,111 +0,0 @@ -using Gtk; -using Gee; -using Granite; -using GameHub.Data; -using GameHub.Utils; - -namespace GameHub.UI.Views -{ - public class GamesGridFlowBox: Gtk.FlowBox - { - - } - - public class GamesGridView: BaseView - { - private ArrayList sources = new ArrayList(); - - private GamesGridFlowBox games_list; - - private Granite.Widgets.ModeButton filter; - private SearchEntry search; - - private Spinner spinner; - private int loading_sources = 0; - - construct - { - foreach(var src in GameSources) - { - if(src.is_authenticated()) sources.add(src); - } - - games_list = new GamesGridFlowBox(); - games_list.margin = 4; - - games_list.activate_on_single_click = false; - games_list.homogeneous = true; - games_list.min_children_per_line = 3; - games_list.selection_mode = SelectionMode.NONE; - games_list.valign = Align.START; - - var scrolled = new ScrolledWindow(null, null); - scrolled.expand = true; - scrolled.hscrollbar_policy = PolicyType.NEVER; - scrolled.add(games_list); - add(scrolled); - - filter = new Granite.Widgets.ModeButton(); - filter.append_icon("view-filter-symbolic", IconSize.SMALL_TOOLBAR); - foreach(var src in sources) filter.append_pixbuf(FSUtils.get_icon(src.icon, 16)); - filter.set_active(sources.size > 1 ? 0 : 1); - - search = new SearchEntry(); - - if(sources.size > 1) titlebar.pack_start(filter); - titlebar.pack_end(search); - - games_list.set_sort_func((child1, child2) => { - var item1 = child1 as GameCard; - var item2 = child2 as GameCard; - if(item1 != null && item2 != null) - { - return item1.game.name.collate(item2.game.name); - } - return 0; - }); - - games_list.set_filter_func(child => { - var item = child as GameCard; - var f = filter.selected; - - GameSource? src = null; - if(f > 0) src = sources[f - 1]; - - var games = src == null ? games_list.get_children().length() : src.games_count; - titlebar.title = "GameHub" + (src == null ? "" : ": " + src.name); - titlebar.subtitle = @"$(games) games"; - - return (src == null || item == null || src == item.game.source) && (item == null || search.text.casefold() in item.game.name.casefold()); - }); - - filter.mode_changed.connect(games_list.invalidate_filter); - search.search_changed.connect(games_list.invalidate_filter); - - spinner = new Spinner(); - titlebar.pack_end(spinner); - - show_all(); - scrolled.show_all(); - games_list.show_all(); - - load_games.begin(); - } - - private async void load_games() - { - foreach(var src in sources) - { - loading_sources++; - spinner.active = loading_sources > 0; - src.load_games.begin(g => { - games_list.add(new GameCard(g)); - games_list.show_all(); - }, (obj, res) => { - loading_sources--; - spinner.active = loading_sources > 0; - }); - } - } - } -} diff --git a/src/ui/views/GamesView/AddGamePopover.vala b/src/ui/views/GamesView/AddGamePopover.vala new file mode 100644 index 00000000..8b851d3b --- /dev/null +++ b/src/ui/views/GamesView/AddGamePopover.vala @@ -0,0 +1,239 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; +using Gee; + +using GameHub.Data; +using GameHub.Data.DB; +using GameHub.Utils; +using GameHub.UI.Widgets; + +using GameHub.Data.Sources.User; + +namespace GameHub.UI.Views.GamesView +{ + public class AddGamePopover: Popover + { + public signal void game_added(UserGame game); + public signal void download_images(); + + private Gtk.Grid grid; + private int rows = 0; + + private bool suppress_updates = false; + + private ModeButton mode; + + private new Entry name; + private FileChooserEntry gamedir; + private FileChooserEntry executable; + private Label executable_label; + private Entry arguments; + private Label arguments_label; + private new Button add; + + public AddGamePopover(Widget? relative_to) + { + Object(relative_to: relative_to); + } + + construct + { + grid = new Gtk.Grid(); + grid.row_spacing = 4; + grid.column_spacing = 4; + grid.set_size_request(270, -1); + + mode = new ModeButton(); + mode.margin_bottom = 8; + mode.halign = Align.CENTER; + mode.append_text(_("Executable")); + mode.append_text(_("Installer")); + mode.selected = 0; + grid.attach(mode, 0, rows, 2, 1); + rows++; + + name = add_entry(_("Name"), "insert-text-symbolic", true); + + add_separator(); + + executable = add_filechooser(_("Executable"), _("Select game executable"), FileChooserAction.OPEN, true, out executable_label); + arguments = add_entry(_("Arguments"), "utilities-terminal-symbolic", false, out arguments_label); + + add_separator(); + + gamedir = add_filechooser(_("Directory"), _("Select game directory"), FileChooserAction.SELECT_FOLDER, true); + + add = new Button.with_label(_("Add game")); + add.margin_top = 8; + add.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION); + add.sensitive = false; + + grid.attach(add, 0, rows, 2, 1); + + mode.mode_changed.connect(update); + name.changed.connect(update); + executable.file_set.connect(update); + gamedir.file_set.connect(update); + arguments.changed.connect(update); + + update(); + + add.clicked.connect(add_game); + + var import_vbox = new Box(Orientation.VERTICAL, 4); + import_vbox.valign = Align.CENTER; + import_vbox.set_size_request(270, -1); + + var emu_import_btn = new ActionButton("list-add-symbolic", "application-x-executable-symbolic", _("Import emulated games"), true); + import_vbox.add(emu_import_btn); + emu_import_btn.clicked.connect(import_emulated_games); + + import_vbox.add(new Separator(Orientation.HORIZONTAL)); + + var images_import_btn = new ActionButton("image-x-generic-symbolic", "folder-download-symbolic", _("Download game images"), true, true); + import_vbox.add(images_import_btn); + images_import_btn.clicked.connect(start_images_download); + + var hbox = new Box(Orientation.HORIZONTAL, 8); + hbox.margin = 8; + + hbox.add(grid); + hbox.add(new Separator(Orientation.VERTICAL)); + hbox.add(import_vbox); + + child = hbox; + hbox.show_all(); + + name.grab_focus(); + } + + private void update() + { + if(suppress_updates) return; + + if(mode.selected == 0 && executable.file != null && gamedir.file == null) + { + suppress_updates = true; + gamedir.select_file(executable.file.get_parent()); + suppress_updates = false; + } + + add.sensitive = name.text.strip().length > 0 + && executable.file != null && executable.file.query_exists() + && gamedir.file != null && gamedir.file.query_exists(); + + executable_label.label = mode.selected == 0 ? _("Executable") : _("Installer"); + arguments.sensitive = arguments_label.sensitive = mode.selected == 0; + } + + private void add_game() + { + var game = new UserGame(name.text.strip(), gamedir.file, executable.file, arguments.text.strip(), mode.selected != 0); + name.text = ""; + executable.reset(); + gamedir.reset(); + arguments.text = ""; + update(); + game.save(); + game_added(game); + #if GTK_3_22 + popdown(); + #else + hide(); + #endif + executable.reset(); + gamedir.reset(); + if(mode.selected != 0) + { + game.install.begin(); + } + } + + private void import_emulated_games() + { + #if GTK_3_22 + popdown(); + #else + hide(); + #endif + var dlg = new UI.Dialogs.ImportEmulatedGamesDialog(); + dlg.game_added.connect(g => game_added(g)); + } + + private void start_images_download() + { + #if GTK_3_22 + popdown(); + #else + hide(); + #endif + download_images(); + } + + private Entry add_entry(string text, string icon, bool required=true, out Label label=null) + { + label = new Label(text); + label.set_size_request(72, -1); + label.hexpand = true; + label.xalign = 1; + label.margin = 4; + if(required) + { + label.get_style_context().add_class("category-label"); + } + var entry = new Entry(); + entry.primary_icon_name = icon; + entry.primary_icon_activatable = false; + entry.set_size_request(180, -1); + grid.attach(label, 0, rows); + grid.attach(entry, 1, rows); + rows++; + return entry; + } + + private FileChooserEntry add_filechooser(string text, string title, FileChooserAction action=FileChooserAction.OPEN, bool required=true, out Label label=null) + { + label = new Label(text); + label.set_size_request(72, -1); + label.hexpand = true; + label.xalign = 1; + label.margin = 4; + if(required) + { + label.get_style_context().add_class("category-label"); + } + var entry = new FileChooserEntry(title, action, null, null, false, action == FileChooserAction.OPEN); + entry.set_size_request(180, -1); + grid.attach(label, 0, rows); + grid.attach(entry, 1, rows); + rows++; + return entry; + } + + private void add_separator() + { + var separator = new Separator(Orientation.HORIZONTAL); + separator.margin_top = separator.margin_bottom = 4; + grid.attach(separator, 0, rows, 2, 1); + rows++; + } + } +} diff --git a/src/ui/views/GamesView/DownloadProgressView.vala b/src/ui/views/GamesView/DownloadProgressView.vala new file mode 100644 index 00000000..7bc7a680 --- /dev/null +++ b/src/ui/views/GamesView/DownloadProgressView.vala @@ -0,0 +1,206 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; + +using GameHub.Data; +using GameHub.Utils; +using GameHub.UI.Widgets; + +namespace GameHub.UI.Views.GamesView +{ + public class DownloadProgressView: ListBoxRow + { + public Downloader.DownloadInfo dl_info; + + private Image? icon; + private AutoSizeImage? image; + + private Image? type_icon; + private AutoSizeImage? type_image; + + private Overlay image_overlay; + + private ProgressBar progress_bar; + + private Button action_pause; + private Button action_resume; + private Button action_cancel; + + public DownloadProgressView(Downloader.DownloadInfo info) + { + dl_info = info; + + selectable = false; + + var hbox = new Box(Orientation.HORIZONTAL, 8); + hbox.margin = 8; + var hbox_inner = new Box(Orientation.HORIZONTAL, 8); + var hbox_actions = new Box(Orientation.HORIZONTAL, 0); + hbox_actions.get_style_context().add_class(Gtk.STYLE_CLASS_LINKED); + hbox_actions.vexpand = false; + hbox_actions.valign = Align.CENTER; + + var vbox = new Box(Orientation.VERTICAL, 0); + var vbox_labels = new Box(Orientation.VERTICAL, 0); + vbox_labels.hexpand = true; + + image_overlay = new Overlay(); + image_overlay.valign = Align.START; + image_overlay.set_size_request(48, 48); + + if(dl_info.icon != null) + { + image = new AutoSizeImage(); + image.valign = Align.START; + image.set_constraint(48, 48, 1); + image.set_size_request(48, 48); + image.load(dl_info.icon, null, "images/icons/"); + image_overlay.add(image); + } + else if(dl_info.icon_name != null) + { + icon = new Image.from_icon_name(dl_info.icon_name, IconSize.DIALOG); + icon.set_size_request(48, 48); + image_overlay.add(icon); + } + + if(dl_info.type_icon != null) + { + type_image = new AutoSizeImage(); + type_image.set_constraint(16, 16, 1); + type_image.set_size_request(16, 16); + type_image.halign = Align.END; + type_image.valign = Align.END; + type_image.get_style_context().add_class("dl-progress-type-icon"); + type_image.load(dl_info.type_icon, null, "images/icons/"); + image_overlay.add_overlay(type_image); + } + else if(dl_info.type_icon_name != null) + { + type_icon = new Image.from_icon_name(dl_info.type_icon_name, IconSize.SMALL_TOOLBAR); + type_icon.set_size_request(16, 16); + type_icon.halign = Align.END; + type_icon.valign = Align.END; + type_icon.get_style_context().add_class("dl-progress-type-icon"); + image_overlay.add_overlay(type_icon); + } + + hbox.add(image_overlay); + + var label = new Label(dl_info.name); + label.halign = Align.START; + label.get_style_context().add_class("category-label"); + label.ypad = 2; + vbox_labels.add(label); + + if(dl_info.description != null) + { + var desc_label = new Label(dl_info.description); + desc_label.halign = Align.START; + desc_label.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL); + desc_label.ypad = 2; + vbox_labels.add(desc_label); + } + + var state_label = new Label(null); + state_label.halign = Align.START; + vbox_labels.add(state_label); + + progress_bar = new ProgressBar(); + progress_bar.hexpand = true; + progress_bar.fraction = 0d; + + action_pause = new Button.from_icon_name("media-playback-pause-symbolic"); + action_pause.tooltip_text = _("Pause download"); + action_pause.get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + action_pause.no_show_all = true; + action_pause.visible = false; + + action_resume = new Button.from_icon_name("media-playback-start-symbolic"); + action_resume.tooltip_text = _("Resume download"); + action_resume.get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + action_resume.no_show_all = true; + action_resume.visible = false; + + action_cancel = new Button.from_icon_name("process-stop-symbolic"); + action_cancel.tooltip_text = _("Cancel download"); + action_cancel.get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + action_cancel.no_show_all = true; + action_cancel.visible = false; + + hbox_inner.add(vbox_labels); + hbox_inner.add(hbox_actions); + + hbox_actions.add(action_pause); + hbox_actions.add(action_resume); + hbox_actions.add(action_cancel); + + vbox.add(hbox_inner); + vbox.add(progress_bar); + + hbox.add(vbox); + + child = hbox; + + dl_info.download.status_change.connect(s => { + Idle.add(() => { + state_label.label = s.description; + var ds = s.state; + + progress_bar.fraction = s.progress; + + action_cancel.visible = true; + action_cancel.sensitive = ds == Downloader.Download.State.DOWNLOADING || ds == Downloader.Download.State.QUEUED || ds == Downloader.Download.State.PAUSED; + action_pause.visible = dl_info.download is Downloader.PausableDownload && ds != Downloader.Download.State.PAUSED && ds != Downloader.Download.State.QUEUED; + action_resume.visible = dl_info.download is Downloader.PausableDownload && ds == Downloader.Download.State.PAUSED && ds != Downloader.Download.State.QUEUED; + + return Source.REMOVE; + }); + }); + + action_cancel.clicked.connect(() => { + dl_info.download.cancel(); + }); + + action_pause.clicked.connect(() => { + if(dl_info.download is Downloader.PausableDownload) + { + ((Downloader.PausableDownload) dl_info.download).pause(); + } + }); + + action_resume.clicked.connect(() => { + if(dl_info.download is Downloader.PausableDownload) + { + ((Downloader.PausableDownload) dl_info.download).resume(); + } + }); + + Downloader.download_manager().dl_ended.connect(dl => { + Idle.add(() => { + if(dl == dl_info) destroy(); + return Source.REMOVE; + }); + }); + + show_all(); + } + } +} diff --git a/src/ui/views/GamesView/FiltersPopover.vala b/src/ui/views/GamesView/FiltersPopover.vala new file mode 100644 index 00000000..955242f4 --- /dev/null +++ b/src/ui/views/GamesView/FiltersPopover.vala @@ -0,0 +1,357 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; +using Gee; + +using GameHub.Data; +using GameHub.Data.Adapters; +using GameHub.Data.DB; +using GameHub.Utils; +using GameHub.UI.Widgets; +using GameHub.Settings; + +namespace GameHub.UI.Views.GamesView +{ + public class FiltersPopover: Popover + { + public ArrayList selected_tags { get; private set; } + public signal void filters_changed(ArrayList selected_tags); + + public GamesAdapter.SortMode sort_mode { get; private set; default = GamesAdapter.SortMode.NAME; } + public signal void sort_mode_changed(Adapters.GamesAdapter.SortMode sort_mode); + + public GamesAdapter.GroupMode group_mode { get; private set; default = GamesAdapter.GroupMode.STATUS; } + public signal void group_mode_changed(Adapters.GamesAdapter.GroupMode group_mode); + + public GamesAdapter.PlatformFilter filter_platform { get; private set; default = GamesAdapter.PlatformFilter.ALL; } + public signal void filter_platform_changed(Adapters.GamesAdapter.PlatformFilter filter_platform); + + private ModeButton group_mode_button; + private ModeButton sort_mode_button; + private ModeButton platform_button; + + private CheckButton tags_header_check; + private ListBox tags_list; + + private bool is_toggling_all = false; + private bool is_updating = false; + + public FiltersPopover(Widget? relative_to) + { + Object(relative_to: relative_to); + } + + construct + { + selected_tags = new ArrayList(Tables.Tags.Tag.is_equal); + + set_size_request(220, -1); + + var vbox = new Box(Orientation.VERTICAL, 0); + + var group_hbox = new Box(Orientation.HORIZONTAL, 6); + group_hbox.margin_start = group_hbox.margin_end = 8; + group_hbox.margin_top = 4; + group_hbox.margin_bottom = 2; + + var group_image = new Image.from_icon_name("view-continuous-symbolic", IconSize.BUTTON); + group_hbox.add(group_image); + + var group_label = Styled.H4Label(_("Group")); + group_label.margin_end = 2; + group_label.xpad = 0; + group_label.halign = Align.START; + group_label.xalign = 0; + group_label.hexpand = true; + group_hbox.add(group_label); + + group_mode_button = new ModeButton(); + group_mode_button.get_style_context().add_class("icons-modebutton"); + group_mode_button.halign = Align.END; + group_mode_button.valign = Align.CENTER; + group_mode_button.can_focus = true; + add_group_mode(GamesAdapter.GroupMode.NONE); + add_group_mode(GamesAdapter.GroupMode.STATUS); + add_group_mode(GamesAdapter.GroupMode.SOURCE); + group_hbox.add(group_mode_button); + + var sort_hbox = new Box(Orientation.HORIZONTAL, 6); + sort_hbox.margin_start = sort_hbox.margin_end = 8; + sort_hbox.margin_top = sort_hbox.margin_bottom = 2; + + var sort_image = new Image.from_icon_name("view-sort-descending-symbolic", IconSize.BUTTON); + sort_hbox.add(sort_image); + + var sort_label = Styled.H4Label(_("Sort")); + sort_label.margin_end = 2; + sort_label.xpad = 0; + sort_label.halign = Align.START; + sort_label.xalign = 0; + sort_label.hexpand = true; + sort_hbox.add(sort_label); + + sort_mode_button = new ModeButton(); + sort_mode_button.get_style_context().add_class("icons-modebutton"); + sort_mode_button.halign = Align.END; + sort_mode_button.valign = Align.CENTER; + sort_mode_button.can_focus = true; + add_sort_mode(GamesAdapter.SortMode.NAME); + add_sort_mode(GamesAdapter.SortMode.LAST_LAUNCH); + add_sort_mode(GamesAdapter.SortMode.PLAYTIME); + sort_hbox.add(sort_mode_button); + + var platform_hbox = new Box(Orientation.HORIZONTAL, 6); + platform_hbox.margin_start = platform_hbox.margin_end = 8; + platform_hbox.margin_top = platform_hbox.margin_bottom = 2; + + var platform_image = new Image.from_icon_name("application-x-executable-symbolic", IconSize.BUTTON); + platform_hbox.add(platform_image); + + var platform_label = Styled.H4Label(_("Platform")); + platform_label.margin_end = 2; + platform_label.xpad = 0; + platform_label.halign = Align.START; + platform_label.xalign = 0; + platform_label.hexpand = true; + platform_hbox.add(platform_label); + + platform_button = new ModeButton(); + platform_button.get_style_context().add_class("icons-modebutton"); + platform_button.halign = Align.END; + platform_button.valign = Align.CENTER; + platform_button.can_focus = true; + + foreach(var p in GamesAdapter.PlatformFilter.FILTERS) + { + add_platform(p); + } + + platform_hbox.add(platform_button); + + var saved_state = SavedState.GamesView.instance; + + group_mode_button.set_active((int) saved_state.group_mode); + group_mode = saved_state.group_mode; + group_mode_button.mode_changed.connect(() => { + saved_state.group_mode = (GamesAdapter.GroupMode) group_mode_button.selected; + group_mode = saved_state.group_mode; + group_mode_changed(group_mode); + }); + + sort_mode_button.set_active((int) saved_state.sort_mode); + sort_mode = saved_state.sort_mode; + sort_mode_button.mode_changed.connect(() => { + saved_state.sort_mode = (GamesAdapter.SortMode) sort_mode_button.selected; + sort_mode = saved_state.sort_mode; + sort_mode_changed(sort_mode); + }); + + platform_button.set_active((int) saved_state.filter_platform); + filter_platform = saved_state.filter_platform; + platform_button.mode_changed.connect(() => { + saved_state.filter_platform = (GamesAdapter.PlatformFilter) platform_button.selected; + filter_platform = saved_state.filter_platform; + filter_platform_changed(filter_platform); + }); + + vbox.add(group_hbox); + vbox.add(new Separator(Orientation.HORIZONTAL)); + vbox.add(sort_hbox); + vbox.add(new Separator(Orientation.HORIZONTAL)); + vbox.add(platform_hbox); + vbox.add(new Separator(Orientation.HORIZONTAL)); + + tags_list = new ListBox(); + tags_list.get_style_context().add_class("tags-list"); + tags_list.get_style_context().add_class("not-rounded"); + tags_list.selection_mode = SelectionMode.NONE; + + tags_list.set_sort_func((row1, row2) => { + var item1 = row1 as TagRow; + var item2 = row2 as TagRow; + + if(row1 != null && row2 != null) + { + var t1 = item1.tag.id; + var t2 = item2.tag.id; + + var b1 = t1.has_prefix(Tables.Tags.Tag.BUILTIN_PREFIX); + var b2 = t2.has_prefix(Tables.Tags.Tag.BUILTIN_PREFIX); + if(b1 && !b2) return -1; + if(!b1 && b2) return 1; + + var u1 = t1.has_prefix(Tables.Tags.Tag.USER_PREFIX); + var u2 = t2.has_prefix(Tables.Tags.Tag.USER_PREFIX); + if(u1 && !u2) return -1; + if(!u1 && u2) return 1; + + return item1.tag.name.collate(item1.tag.name); + } + + return 0; + }); + + var tags_scrolled = new ScrolledWindow(null, null); + #if GTK_3_22 + tags_scrolled.propagate_natural_width = true; + tags_scrolled.propagate_natural_height = true; + tags_scrolled.max_content_height = 440; + #else + tags_scrolled.min_content_height = 320; + #endif + tags_scrolled.add(tags_list); + tags_scrolled.show_all(); + + var tebox = new EventBox(); + tebox.get_style_context().add_class("tags-list-header"); + tebox.above_child = true; + tebox.can_focus = true; + + var tbox = new Box(Orientation.HORIZONTAL, 8); + tbox.margin_start = tbox.margin_end = 8; + tbox.margin_top = tbox.margin_bottom = 6; + + tags_header_check = new CheckButton(); + tags_header_check.can_focus = false; + + var header = Styled.H4Label(_("Tags")); + header.halign = Align.START; + header.xalign = 0; + header.hexpand = true; + + tbox.add(tags_header_check); + tbox.add(header); + + tebox.add_events(EventMask.ALL_EVENTS_MASK); + tebox.enter_notify_event.connect(e => { tebox.get_style_context().add_class("hover"); }); + tebox.leave_notify_event.connect(e => { tebox.get_style_context().remove_class("hover"); }); + tebox.button_release_event.connect(e => { + if(e.button == 1) + { + toggle_all_tags(); + } + return true; + }); + tebox.key_release_event.connect(e => { + switch(((EventKey) e).keyval) + { + case Key.Return: + case Key.space: + case Key.KP_Space: + toggle_all_tags(); + return true; + } + return false; + }); + + tebox.add(tbox); + + vbox.add(tebox); + vbox.add(new Separator(Orientation.HORIZONTAL)); + vbox.add(tags_scrolled); + + child = vbox; + + load_tags(); + + Tables.Tags.instance.tags_updated.connect(load_tags); + + vbox.show_all(); + } + + private void toggle_all_tags() + { + tags_header_check.inconsistent = false; + tags_header_check.active = !tags_header_check.active; + + is_toggling_all = true; + foreach(var tag in Tables.Tags.TAGS) + { + tag.selected = tags_header_check.active; + } + is_toggling_all = false; + update(); + } + + private void load_tags() + { + tags_list.foreach(w => w.destroy()); + + foreach(var tag in Tables.Tags.TAGS) + { + if(!tag.enabled) continue; + tags_list.add(new TagRow(tag)); + tag.notify["selected"].connect(update); + } + + tags_list.show_all(); + + update(); + } + + private void update() + { + if(is_toggling_all || is_updating) return; + is_updating = true; + + selected_tags.clear(); + + foreach(var tag in Tables.Tags.TAGS) + { + if(tag.selected) selected_tags.add(tag); + Tables.Tags.add(tag, true); + } + + tags_header_check.inconsistent = selected_tags.size != 0 && selected_tags.size != Tables.Tags.TAGS.size; + tags_header_check.active = selected_tags.size > 0; + + filters_changed(selected_tags); + + is_updating = false; + } + + private void add_sort_mode(GamesAdapter.SortMode mode) + { + var image = new Image.from_icon_name(mode.icon(), IconSize.MENU); + image.tooltip_text = mode.name(); + sort_mode_button.append(image); + } + + private void add_group_mode(GamesAdapter.GroupMode mode) + { + var image = new Image.from_icon_name(mode.icon(), IconSize.MENU); + image.tooltip_text = mode.name(); + group_mode_button.append(image); + } + + private void add_platform(GamesAdapter.PlatformFilter p) + { + Platform? platform = null; + if(p != GamesAdapter.PlatformFilter.ALL) + { + platform = p.platform(); + } + + var image = new Image.from_icon_name(platform == null ? "application-x-executable-symbolic" : platform.icon(), IconSize.MENU); + image.tooltip_text = platform == null ? _("All platforms") : platform.name(); + platform_button.append(image); + } + } +} diff --git a/src/ui/views/GamesView/GameContextMenu.vala b/src/ui/views/GamesView/GameContextMenu.vala new file mode 100644 index 00000000..c12d892e --- /dev/null +++ b/src/ui/views/GamesView/GameContextMenu.vala @@ -0,0 +1,265 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; + +using GameHub.Data; +using GameHub.Data.DB; +using GameHub.Utils; +using GameHub.UI.Widgets; + +namespace GameHub.UI.Views.GamesView +{ + public class GameContextMenu: Gtk.Menu + { + public Game game { get; construct; } + public Widget? target { get; construct; default = null; } + public bool is_merge_submenu { private get; construct; default = false; } + + public GameContextMenu(Game game, Widget? target=null, bool is_merge_submenu=false) + { + Object(game: game, target: target, is_merge_submenu: is_merge_submenu); + } + + construct + { + if(game.status.state == Game.State.INSTALLED && !(game is Sources.GOG.GOGGame.DLC)) + { + if(game.use_compat) + { + var run_with_compat = new Gtk.MenuItem.with_label(_("Run with compatibility layer")); + run_with_compat.sensitive = game.can_be_launched(); + run_with_compat.activate.connect(() => game.run_with_compat.begin(true)); + add(run_with_compat); + } + else + { + var run = new Gtk.MenuItem.with_label(_("Run")); + run.sensitive = game.can_be_launched(); + run.activate.connect(() => game.run.begin()); + add(run); + } + add(new Gtk.SeparatorMenuItem()); + + if(game.actions != null && game.actions.size > 0) + { + var compat_tool = CompatTool.by_id(game.compat_tool); + foreach(var action in game.actions) + { + var action_item = new Gtk.MenuItem.with_label(action.name); + action_item.get_style_context().add_class("menuitem-game-action"); + if(action.is_primary) + { + action_item.get_style_context().add_class("primary"); + } + action_item.sensitive = action.is_available(compat_tool); + action_item.activate.connect(() => action.invoke.begin(compat_tool)); + add(action_item); + } + add(new Gtk.SeparatorMenuItem()); + } + } + else if(game.status.state == Game.State.UNINSTALLED) + { + var install = new Gtk.MenuItem.with_label(_("Install")); + install.sensitive = game.is_installable; + install.activate.connect(() => game.install.begin()); + add(install); + add(new Gtk.SeparatorMenuItem()); + } + + var details = new Gtk.MenuItem.with_label(_("Details")); + details.activate.connect(() => new Dialogs.GameDetailsDialog(game).show_all()); + add(details); + + if(!(game is Sources.GOG.GOGGame.DLC)) + { + if(Settings.UI.Behavior.instance.merge_games && !is_merge_submenu) + { + var merges = DB.Tables.Merges.get(game); + var primary = DB.Tables.Merges.get_primary(game); + if(primary != null || (merges != null && merges.size > 0)) + { + add(new Gtk.SeparatorMenuItem()); + if(primary != null) + { + add_merged_game_submenu(primary); + merges = DB.Tables.Merges.get(primary); + } + if(merges != null) + { + foreach(var g in merges) + { + if(g == game) continue; + add_merged_game_submenu(g); + } + } + } + } + + add(new Gtk.SeparatorMenuItem()); + var favorite = new Gtk.CheckMenuItem.with_label(C_("game_context_menu", "Favorite")); + favorite.active = game.has_tag(Tables.Tags.BUILTIN_FAVORITES); + favorite.toggled.connect(() => game.toggle_tag(Tables.Tags.BUILTIN_FAVORITES)); + add(favorite); + var hidden = new Gtk.CheckMenuItem.with_label(C_("game_context_menu", "Hidden")); + hidden.active = game.has_tag(Tables.Tags.BUILTIN_HIDDEN); + hidden.toggled.connect(() => game.toggle_tag(Tables.Tags.BUILTIN_HIDDEN)); + add(hidden); + } + + bool add_dirs_separator = true; + + if(game.status.state == Game.State.INSTALLED && game.install_dir != null && game.install_dir.query_exists()) + { + if(add_dirs_separator) add(new Gtk.SeparatorMenuItem()); + add_dirs_separator = false; + var open_dir = new Gtk.MenuItem.with_label(_("Open installation directory")); + open_dir.activate.connect(open_game_directory); + add(open_dir); + } + + if(game.installers_dir != null && game.installers_dir.query_exists()) + { + if(add_dirs_separator) add(new Gtk.SeparatorMenuItem()); + add_dirs_separator = false; + var open_installers_dir = new Gtk.MenuItem.with_label(_("Open installers collection directory")); + open_installers_dir.activate.connect(open_installer_collection_directory); + add(open_installers_dir); + } + + if(game is GameHub.Data.Sources.GOG.GOGGame && (game as GameHub.Data.Sources.GOG.GOGGame).bonus_content_dir != null && (game as GameHub.Data.Sources.GOG.GOGGame).bonus_content_dir.query_exists()) + { + if(add_dirs_separator) add(new Gtk.SeparatorMenuItem()); + add_dirs_separator = false; + var open_bonuses_dir = new Gtk.MenuItem.with_label(_("Open bonus collection directory")); + open_bonuses_dir.activate.connect(open_bonus_collection_directory); + add(open_bonuses_dir); + } + + if(game is GameHub.Data.Sources.Steam.SteamGame && (game as GameHub.Data.Sources.Steam.SteamGame).screenshots_dir != null && (game as GameHub.Data.Sources.Steam.SteamGame).screenshots_dir.query_exists()) + { + if(add_dirs_separator) add(new Gtk.SeparatorMenuItem()); + add_dirs_separator = false; + var open_screenshots_dir = new Gtk.MenuItem.with_label(_("Open screenshots directory")); + open_screenshots_dir.activate.connect(open_screenshots_directory); + add(open_screenshots_dir); + } + + if((game.status.state == Game.State.INSTALLED || game is Sources.User.UserGame) && !(game is Sources.GOG.GOGGame.DLC)) + { + var uninstall = new Gtk.MenuItem.with_label((game is Sources.User.UserGame) ? _("Remove") : _("Uninstall")); + uninstall.activate.connect(() => game.uninstall.begin()); + add(new Gtk.SeparatorMenuItem()); + add(uninstall); + + if(!(game is Sources.Steam.SteamGame)) + { + add(new Gtk.SeparatorMenuItem()); + var fs_overlays = new Gtk.MenuItem.with_label(_("Overlays")); + fs_overlays.activate.connect(() => new Dialogs.GameFSOverlaysDialog(game).show_all()); + add(fs_overlays); + } + + if(game is TweakableGame) + { + add(new Gtk.SeparatorMenuItem()); + var tweaks = new Gtk.MenuItem.with_label(_("Tweaks")); + tweaks.activate.connect(() => new Dialogs.GameTweaksDialog((TweakableGame) game).show_all()); + add(tweaks); + } + } + + if(!(game is Sources.GOG.GOGGame.DLC)) + { + add(new Gtk.SeparatorMenuItem()); + var properties = new Gtk.MenuItem.with_label(_("Properties")); + properties.activate.connect(() => new Dialogs.GamePropertiesDialog(game).show_all()); + add(properties); + } + + show_all(); + } + + public void open(Event e, bool at_pointer=true) + { + #if GTK_3_22 + if(at_pointer) + { + popup_at_pointer(e); + } + else + { + popup_at_widget(target, Gravity.SOUTH, Gravity.NORTH, e); + } + #else + popup(null, null, null, 0, ((EventButton) e).time); + #endif + } + + private void open_game_directory() + { + if(game != null && game.status.state == Game.State.INSTALLED && game.install_dir != null && game.install_dir.query_exists()) + { + Utils.open_uri(game.install_dir.get_uri()); + } + } + + private void open_installer_collection_directory() + { + if(game != null && game.installers_dir != null && game.installers_dir.query_exists()) + { + Utils.open_uri(game.installers_dir.get_uri()); + } + } + + private void open_bonus_collection_directory() + { + if(game != null && game is GameHub.Data.Sources.GOG.GOGGame) + { + var gog_game = game as GameHub.Data.Sources.GOG.GOGGame; + if(gog_game != null && gog_game.bonus_content_dir != null && gog_game.bonus_content_dir.query_exists()) + { + Utils.open_uri(gog_game.bonus_content_dir.get_uri()); + } + } + } + + private void open_screenshots_directory() + { + if(game != null && game is GameHub.Data.Sources.Steam.SteamGame) + { + var steam_game = game as GameHub.Data.Sources.Steam.SteamGame; + if(steam_game != null && steam_game.screenshots_dir != null && steam_game.screenshots_dir.query_exists()) + { + Utils.open_uri(steam_game.screenshots_dir.get_uri()); + } + } + } + + private void add_merged_game_submenu(Game g) + { + var item = new Gtk.MenuItem.with_label("""%s%s""".printf(g.source.name, "\n" + g.name.replace("&", "&").replace("&", "&"))); + ((Label) item.get_child()).use_markup = true; + item.get_style_context().add_class("menuitem-merged-game"); + item.submenu = new GameContextMenu(g, null, true); + add(item); + } + } +} diff --git a/src/ui/views/GamesView/GamesView.vala b/src/ui/views/GamesView/GamesView.vala new file mode 100644 index 00000000..a52c9f8e --- /dev/null +++ b/src/ui/views/GamesView/GamesView.vala @@ -0,0 +1,956 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; +using GLib; +using Gee; + +using GameHub.Data; +using GameHub.Data.Adapters; +using GameHub.Data.DB; +using GameHub.Utils; +using GameHub.UI.Widgets; +using GameHub.UI.Windows; +using GameHub.Settings; + +using GameHub.UI.Views.GamesView.List; +using GameHub.UI.Views.GamesView.Grid; + +namespace GameHub.UI.Views.GamesView +{ + public class GamesView: BaseView + { + public static GamesView instance; + + private ArrayList sources = new ArrayList(); + + private GamesAdapter games_adapter; + + private Box messages; + + private Stack stack; + + private AlertView empty_alert; + + private GamesGrid games_grid; + + private Paned games_list_paned; + private GamesList games_list; + private GameDetailsView.GameDetailsView games_list_details; + + private ModeButton view; + + private ModeButton filter; + private SearchEntry search; + + private OverlayBar status_overlay; + + private Button settings; + + private MenuButton downloads; + private Popover downloads_popover; + private ListBox downloads_list; + private int downloads_count = 0; + + private MenuButton filters; + private FiltersPopover filters_popover; + + private MenuButton add_game_button; + private AddGamePopover add_game_popover; + + private Settings.UI.Appearance ui_settings; + private Settings.SavedState.GamesView saved_state; + + #if MANETTE + private Manette.Monitor manette_monitor = new Manette.Monitor(); + private ArrayList connected_gamepads = new ArrayList(); + private bool gamepad_axes_to_keys_thread_running = false; + private ArrayList gamepad_mode_visible_widgets = new ArrayList(); + private ArrayList gamepad_mode_hidden_widgets = new ArrayList(); + private Settings.Controller controller_settings; + #endif + + public const string ACTION_PREFIX = "win."; + public const string ACTION_SOURCE_PREV = "source.previous"; + public const string ACTION_SOURCE_NEXT = "source.next"; + public const string ACTION_SEARCH = "search"; + public const string ACTION_FILTERS = "filters"; + public const string ACTION_DOWNLOADS = "downloads"; + public const string ACTION_SELECT_RANDOM_GAME = "select-random-game"; + public const string ACTION_ADD_GAME = "add-game"; + public const string ACTION_EXIT = "exit"; + + public const string ACCEL_SOURCE_PREV = "F1"; // LB + public const string ACCEL_SOURCE_NEXT = "F2"; // RB + public const string ACCEL_SEARCH = "F"; + public const string ACCEL_FILTERS = "F"; + public const string ACCEL_DOWNLOADS = "D"; + public const string ACCEL_SELECT_RANDOM_GAME = "R"; + public const string ACCEL_ADD_GAME = "N"; + public const string ACCEL_EXIT = "Escape"; // Guide + Escape + + private const GLib.ActionEntry[] action_entries = { + { ACTION_SOURCE_PREV, window_action_handler }, + { ACTION_SOURCE_NEXT, window_action_handler }, + { ACTION_SEARCH, window_action_handler }, + { ACTION_FILTERS, window_action_handler }, + { ACTION_DOWNLOADS, window_action_handler }, + { ACTION_SELECT_RANDOM_GAME, window_action_handler }, + { ACTION_ADD_GAME, window_action_handler }, + { ACTION_EXIT, window_action_handler } + }; + + construct + { + instance = this; + + ui_settings = Settings.UI.Appearance.instance; + saved_state = Settings.SavedState.GamesView.instance; + + foreach(var src in GameSources) + { + if(src.enabled && src.is_authenticated()) sources.add(src); + } + + var overlay = new Overlay(); + + stack = new Stack(); + stack.transition_type = StackTransitionType.CROSSFADE; + + empty_alert = new AlertView(_("No games"), _("Get some games or enable some game sources in settings"), "dialog-warning"); + stack.add(empty_alert); + + overlay.add(stack); + + messages = new Box(Orientation.VERTICAL, 0); + + attach(messages, 0, 0); + attach(overlay, 0, 1); + + view = new ModeButton(); + view.halign = Align.CENTER; + view.valign = Align.CENTER; + + add_view_button("view-grid-symbolic", _("Grid view")); + add_view_button("view-list-symbolic", _("List view")); + + view.mode_changed.connect(update_view); + + filter = new ModeButton(); + filter.halign = Align.CENTER; + filter.valign = Align.CENTER; + + add_filter_button("sources-all-symbolic", _("All games")); + + foreach(var src in sources) + { + add_filter_button(src.icon, src.name_from); + } + + filter.set_active(sources.size > 1 ? 0 : 1); + + if(saved_state.filter_source.length > 0) + { + for(int i = 0; i < sources.size; i++) + { + if(sources[i].id == saved_state.filter_source) + { + filter.set_active(i + 1); + break; + } + } + } + + downloads = new MenuButton(); + downloads.valign = Align.CENTER; + Utils.set_accel_tooltip(downloads, _("Downloads"), ACCEL_DOWNLOADS); + downloads.image = new Image.from_icon_name("folder-download" + Settings.UI.Appearance.symbolic_icon_suffix, Settings.UI.Appearance.headerbar_icon_size); + + downloads_popover = new Popover(downloads); + downloads_list = new ListBox(); + downloads_list.get_style_context().add_class("downloads-list"); + + var downloads_scrolled = new ScrolledWindow(null, null); + #if GTK_3_22 + downloads_scrolled.propagate_natural_width = true; + downloads_scrolled.propagate_natural_height = true; + downloads_scrolled.max_content_height = 440; + #else + downloads_scrolled.min_content_height = 440; + #endif + downloads_scrolled.add(downloads_list); + downloads_scrolled.show_all(); + + downloads_popover.add(downloads_scrolled); + downloads_popover.position = PositionType.BOTTOM; + downloads_popover.set_size_request(500, -1); + downloads.popover = downloads_popover; + downloads.sensitive = false; + + filters = new MenuButton(); + filters.valign = Align.CENTER; + Utils.set_accel_tooltip(filters, _("Filters"), ACCEL_FILTERS); + filters.image = new Image.from_icon_name("tag" + Settings.UI.Appearance.symbolic_icon_suffix, Settings.UI.Appearance.headerbar_icon_size); + filters_popover = new FiltersPopover(filters); + filters_popover.position = PositionType.BOTTOM; + filters.popover = filters_popover; + + add_game_button = new MenuButton(); + add_game_button.valign = Align.CENTER; + Utils.set_accel_tooltip(add_game_button, _("Add game"), ACCEL_ADD_GAME); + add_game_button.image = new Image.from_icon_name("list-add" + Settings.UI.Appearance.symbolic_icon_suffix, Settings.UI.Appearance.headerbar_icon_size); + add_game_popover = new AddGamePopover(add_game_button); + add_game_popover.position = PositionType.BOTTOM; + add_game_button.popover = add_game_popover; + + search = new SearchEntry(); + search.placeholder_text = _("Search"); + Utils.set_accel_tooltip(search, search.placeholder_text, ACCEL_SEARCH); + search.halign = Align.CENTER; + search.valign = Align.CENTER; + + settings = new Button(); + settings.valign = Align.CENTER; + Utils.set_accel_tooltip(settings, _("Settings"), Application.ACCEL_SETTINGS); + settings.image = new Image.from_icon_name("open-menu" + Settings.UI.Appearance.symbolic_icon_suffix, Settings.UI.Appearance.headerbar_icon_size); + settings.action_name = Application.ACTION_PREFIX + Application.ACTION_SETTINGS; + + games_adapter = new GamesAdapter(); + games_adapter.cache_loaded.connect(update_view); + + filter.mode_changed.connect(update_view); + search.search_changed.connect(() => { + games_adapter.filter_search_query = search.text; + games_adapter.invalidate(true, false, true); + update_view(); + }); + search.activate.connect(search_run_first_matching_game); + + ui_settings.notify["icon-style"].connect(() => { + (filters.image as Image).icon_name = "tag" + Settings.UI.Appearance.symbolic_icon_suffix; + (add_game_button.image as Image).icon_name = "list-add" + Settings.UI.Appearance.symbolic_icon_suffix; + (downloads.image as Image).icon_name = "folder-download" + Settings.UI.Appearance.symbolic_icon_suffix; + (settings.image as Image).icon_name = "open-menu" + Settings.UI.Appearance.symbolic_icon_suffix; + (filters.image as Image).icon_size = (add_game_button.image as Image).icon_size = (downloads.image as Image).icon_size = (settings.image as Image).icon_size = Settings.UI.Appearance.headerbar_icon_size; + }); + + filters_popover.filters_changed.connect(() => { + games_adapter.filter_tags = filters_popover.selected_tags; + games_adapter.invalidate(true, false, true); + }); + filters_popover.filter_platform_changed.connect(() => { + games_adapter.filter_platform = filters_popover.filter_platform; + games_adapter.invalidate(true, false, true); + }); + filters_popover.sort_mode_changed.connect(() => { + games_adapter.sort_mode = filters_popover.sort_mode; + games_adapter.invalidate(false, true, false); + }); + filters_popover.group_mode_changed.connect(() => { + games_adapter.group_mode = filters_popover.group_mode; + games_adapter.invalidate(true, true, true); + }); + + add_game_popover.game_added.connect(g => { + games_adapter.add(g); + update_view(); + }); + add_game_popover.download_images.connect(() => { + download_images_async.begin(null); + }); + + titlebar.pack_start(view); + + if(sources.size > 1) + { + #if MANETTE + titlebar.pack_start(gamepad_image("bumper-left")); + #endif + + titlebar.pack_start(filter); + + #if MANETTE + titlebar.pack_start(gamepad_image("bumper-right")); + #endif + } + + #if MANETTE + var gamepad_filters_separator = new Separator(Orientation.VERTICAL); + gamepad_filters_separator.no_show_all = true; + gamepad_mode_visible_widgets.add(gamepad_filters_separator); + titlebar.pack_start(gamepad_filters_separator); + #endif + + titlebar.pack_start(filters); + + #if MANETTE + titlebar.pack_start(gamepad_image("y")); + #endif + + var settings_overlay = new Overlay(); + settings_overlay.add(settings); + + #if MANETTE + var settings_gamepad_shortcut = gamepad_image("select"); + settings_gamepad_shortcut.halign = Align.CENTER; + settings_gamepad_shortcut.valign = Align.END; + settings_overlay.add_overlay(settings_gamepad_shortcut); + settings_overlay.set_overlay_pass_through(settings_gamepad_shortcut, true); + #endif + + titlebar.pack_end(settings_overlay); + + titlebar.pack_end(downloads); + titlebar.pack_end(search); + titlebar.pack_end(add_game_button); + + #if MANETTE + var gamepad_shortcuts_separator = new Separator(Orientation.VERTICAL); + gamepad_shortcuts_separator.no_show_all = true; + gamepad_mode_visible_widgets.add(gamepad_shortcuts_separator); + titlebar.pack_end(gamepad_shortcuts_separator); + titlebar.pack_end(gamepad_image("x", _("Menu"))); + titlebar.pack_end(gamepad_image("b", _("Back"))); + titlebar.pack_end(gamepad_image("a", _("Select"))); + #endif + + status_overlay = new OverlayBar(overlay); + games_adapter.notify["status"].connect(() => { + update_status(games_adapter.status); + }); + + show_all(); + + stack.set_visible_child(empty_alert); + + view.opacity = 0; + view.sensitive = false; + filter.opacity = 0; + filter.sensitive = false; + search.opacity = 0; + search.sensitive = false; + downloads.opacity = 0; + filters.opacity = 0; + filters.sensitive = false; + add_game_button.opacity = 0; + add_game_button.sensitive = false; + + Downloader.download_manager().dl_started.connect(dl => { + Idle.add(() => { + downloads_list.add(new DownloadProgressView(dl)); + downloads.sensitive = true; + downloads_count++; + + #if UNITY + dl.download.status_change.connect(s => { + Idle.add(() => { + update_downloads_progress(); + return Source.REMOVE; + }, Priority.LOW); + }); + #endif + return Source.REMOVE; + }, Priority.LOW); + }); + Downloader.download_manager().dl_ended.connect(dl => { + Idle.add(() => { + downloads_count--; + if(downloads_count < 0) downloads_count = 0; + downloads.sensitive = downloads_count > 0; + if(downloads_count == 0) + { + #if GTK_3_22 + downloads_popover.popdown(); + #else + downloads_popover.hide(); + #endif + } + #if UNITY + update_downloads_progress(); + #endif + return Source.REMOVE; + }, Priority.LOW); + }); + + #if MANETTE + controller_settings = Settings.Controller.instance; + gamepad_mode_hidden_widgets.add(view); + gamepad_mode_hidden_widgets.add(downloads); + gamepad_mode_hidden_widgets.add(search); + gamepad_mode_hidden_widgets.add(add_game_button); + + if(controller_settings.enabled) + { + var manette_iterator = manette_monitor.iterate(); + Manette.Device manette_device = null; + while(manette_iterator.next(out manette_device)) + { + on_gamepad_connected(manette_device); + } + manette_monitor.device_connected.connect(on_gamepad_connected); + manette_monitor.device_disconnected.connect(on_gamepad_disconnected); + } + #endif + + games_adapter.filter_tags = filters_popover.selected_tags; + games_adapter.filter_platform = filters_popover.filter_platform; + games_adapter.sort_mode = filters_popover.sort_mode; + games_adapter.group_mode = filters_popover.group_mode; + + load_games(); + } + + public override void attach_to_window(MainWindow wnd) + { + base.attach_to_window(wnd); + + window.add_action_entries(action_entries, this); + Application.instance.set_accels_for_action(ACTION_PREFIX + ACTION_SOURCE_PREV, { ACCEL_SOURCE_PREV }); + Application.instance.set_accels_for_action(ACTION_PREFIX + ACTION_SOURCE_NEXT, { ACCEL_SOURCE_NEXT }); + Application.instance.set_accels_for_action(ACTION_PREFIX + ACTION_SEARCH, { ACCEL_SEARCH }); + Application.instance.set_accels_for_action(ACTION_PREFIX + ACTION_FILTERS, { ACCEL_FILTERS }); + Application.instance.set_accels_for_action(ACTION_PREFIX + ACTION_DOWNLOADS, { ACCEL_DOWNLOADS }); + Application.instance.set_accels_for_action(ACTION_PREFIX + ACTION_SELECT_RANDOM_GAME, { ACCEL_SELECT_RANDOM_GAME }); + Application.instance.set_accels_for_action(ACTION_PREFIX + ACTION_ADD_GAME, { ACCEL_ADD_GAME }); + Application.instance.set_accels_for_action(ACTION_PREFIX + ACTION_EXIT, { ACCEL_EXIT }); + Application.instance.set_accels_for_action(Application.ACTION_PREFIX + Application.ACTION_SETTINGS, { "F5" }); // Select + } + + private void window_action_handler(SimpleAction action, Variant? args) + { + switch(action.name) + { + case ACTION_SOURCE_PREV: + case ACTION_SOURCE_NEXT: + var tab = filter.selected + (action.name == ACTION_SOURCE_PREV ? -1 : 1); + if(tab < 0) tab = (int) filter.n_items - 1; + else if(tab >= filter.n_items) tab = 0; + filter.selected = tab; + break; + + case ACTION_SEARCH: + search.grab_focus(); + break; + + case ACTION_FILTERS: + filters.clicked(); + break; + + case ACTION_DOWNLOADS: + if(downloads.sensitive) + { + downloads.clicked(); + } + break; + + case ACTION_SELECT_RANDOM_GAME: + int index = Random.int_range(0, (int32) games_grid.get_children().length()); + games_grid.select(index, view.selected == 0); + games_list.select(index, view.selected == 1); + break; + + case ACTION_ADD_GAME: + add_game_button.clicked(); + break; + + case ACTION_EXIT: + #if MANETTE + Gamepad.reset(); + #endif + window.destroy(); + break; + } + } + + private void init_grid() + { + if(games_grid != null) return; + + games_grid = new GamesGrid(); + stack.add(games_grid.wrapped()); + games_grid.attach(games_adapter); + } + + private void init_list() + { + if(games_list != null) return; + + games_list_paned = new Paned(Orientation.HORIZONTAL); + games_list = new GamesList(); + games_list_details = new GameDetailsView.GameDetailsView(null); + games_list_details.content_margin = 16; + games_list_paned.pack1(games_list.wrapped(), false, false); + games_list_paned.pack2(games_list_details, true, true); + stack.add(games_list_paned); + games_list_paned.show_all(); + + games_list.game_selected.connect(game => { games_list_details.game = game; }); + games_list.multiple_games_selected.connect(games => { games_list_details.selected_games = games; }); + games_list_details.selected_games_view.download_images.connect(games => { + download_images_async.begin(games); + }); + games_list.attach(games_adapter); + } + + private void init_and_show_view(Settings.SavedState.GamesView.Style view) + { + switch(view) + { + case Settings.SavedState.GamesView.Style.GRID: + init_grid(); + if(games_grid != null && games_grid.scrolled != null) + stack.set_visible_child(games_grid.scrolled); + break; + + case Settings.SavedState.GamesView.Style.LIST: + init_list(); + if(games_list != null && games_list_paned != null) + stack.set_visible_child(games_list_paned); + break; + } + } + + private void update_view() + { + show_games(); + + var f = filter.selected; + GameSource? src = null; + if(f > 0) src = sources[f - 1]; + + if(games_adapter.filter_source != src) + { + games_adapter.filter_source = src; + games_adapter.invalidate(true, false, true); + } + + if(games_list_details != null) games_list_details.preferred_source = src; + + saved_state.filter_source = src == null ? "" : src.id; + + var games = src == null ? games_adapter.games_count : src.games_count; + var filtered_games = games_adapter.filtered_games_count; + + var games_count = ngettext("%u game", "%u games", games).printf(games); + if(filtered_games != games) + { + games_count = C_("games_view_subtitle_filtered_games", "%1$u / %2$s").printf(filtered_games, games_count); + } + if(src != null) + { + titlebar.subtitle = C_("games_view_subtitle", "%1$s: %2$s").printf(src.name, games_count); + } + else + { + titlebar.subtitle = games_count; + } + + if(src != null && src.games_count == 0) + { + if(src is GameHub.Data.Sources.User.User) + { + empty_alert.title = _("No user-added games"); + empty_alert.description = _("Add some games using plus button"); + } + else + { + empty_alert.title = _("No %s games").printf(src.name); + empty_alert.description = _("Get some Linux-compatible games"); + } + empty_alert.icon_name = src.icon; + stack.set_visible_child(empty_alert); + return; + } + else if(search.text.strip().length > 0) + { + if(!games_adapter.has_filtered_games) + { + empty_alert.title = _("No games matching “%s”").printf(search.text.strip()); + empty_alert.description = null; + empty_alert.icon_name = null; + if(src != null) + { + empty_alert.title = _("No %1$s games matching “%2$s”").printf(src.name, search.text.strip()); + } + stack.set_visible_child(empty_alert); + return; + } + } + + saved_state.style = (Settings.SavedState.GamesView.Style) view.selected; + init_and_show_view(saved_state.style); + } + + private void show_games() + { + if(view.opacity != 0 || stack.visible_child != empty_alert) return; + + view.set_active((int) saved_state.style); + init_and_show_view(saved_state.style); + + view.opacity = 1; + view.sensitive = true; + filter.opacity = 1; + filter.sensitive = true; + search.opacity = 1; + search.sensitive = true; + downloads.opacity = 1; + filters.opacity = 1; + filters.sensitive = true; + add_game_button.opacity = 1; + add_game_button.sensitive = true; + } + + private void load_games() + { + messages.get_children().foreach(c => messages.remove(c)); + + games_adapter.load_games(src => { + if(src.games_count == 0 && src is GameHub.Data.Sources.Steam.Steam) + { + var msg = add_message(_("No games were loaded from Steam. Set your games list privacy to public or use your own Steam API key in settings."), MessageType.WARNING); + msg.add_button(_("Privacy"), 1); + msg.add_button(_("Settings"), 2); + + msg.close.connect(() => { + #if GTK_3_22 + msg.revealed = false; + #endif + Timeout.add(250, () => { messages.remove(msg); return Source.REMOVE; }); + }); + + msg.response.connect(r => { + switch(r) + { + case 1: + Utils.open_uri("steam://openurl/https://steamcommunity.com/my/edit/settings"); + break; + + case 2: + settings.clicked(); + break; + + case ResponseType.CLOSE: + msg.close(); + break; + } + }); + } + }); + } + + private void add_view_button(string icon, string tooltip) + { + var image = new Image.from_icon_name(icon, IconSize.MENU); + image.tooltip_text = tooltip; + view.append(image); + } + + private void add_filter_button(string icon, string tooltip) + { + var image = new Image.from_icon_name(icon, IconSize.MENU); + image.tooltip_text = tooltip; + filter.append(image); + } + + private void search_run_first_matching_game() + { + if(search.text.strip().length == 0 || !search.has_focus) return; + + if(view.selected == 0) + { + #if GTK_3_22 + var card = games_grid.get_child_at_pos(0, 0) as GameCard?; + if(card != null) + { + card.game.run_or_install.begin(); + } + #endif + } + else + { + var row = games_list.get_row_at_y(32) as GameListRow?; + if(row != null) + { + row.game.run_or_install.begin(); + } + } + } + + public InfoBar add_message(string text, MessageType type=MessageType.OTHER) + { + var bar = new InfoBar(); + bar.message_type = type; + + #if GTK_3_22 + bar.revealed = false; + #endif + + bar.show_close_button = true; + bar.get_content_area().add(new Label(text)); + + messages.add(bar); + + bar.show_all(); + + #if GTK_3_22 + bar.revealed = true; + #endif + + return bar; + } + + private void update_status(string? status) + { + Idle.add(() => { + if(status != null && status.length > 0) + { + status_overlay.label = status; + status_overlay.active = true; + status_overlay.show(); + } + else + { + status_overlay.active = false; + status_overlay.hide(); + } + return Source.REMOVE; + }, Priority.LOW); + } + + private async void download_images_async(ArrayList? games=null) + { + update_status(_("Downloading images")); + var _games = games ?? DB.Tables.Games.get_all(); + foreach(var game in _games) + { + if(game.image == null || game.image_vertical == null) + { + yield download_game_images(game); + } + } + update_status(null); + } + + private async void download_game_images(Game game) + { + update_status(_("Downloading image: %s").printf(game.name)); + + string? image = game.image; + string? image_vertical = game.image_vertical; + + if(image != null && image_vertical != null) return; + + foreach(var src in Data.Providers.ImageProviders) + { + if(!src.enabled) continue; + + var results = yield src.images(game); + if(results == null || results.size < 1) continue; + foreach(var result in results) + { + if(result.images != null && result.images.size > 0) + { + if(image == null && result.image_size.width >= result.image_size.height) + { + image = result.images.get(0).url; + } + else if(image_vertical == null && result.image_size.width < result.image_size.height) + { + image_vertical = result.images.get(0).url; + } + } + + if(image != null && image_vertical != null) break; + } + } + + game.image = image; + game.image_vertical = image_vertical; + game.save(); + } + + #if UNITY + private void update_downloads_progress() + { + games_adapter.launcher_entry.progress_visible = downloads_count > 0; + double progress = 0; + int count = 0; + downloads_list.foreach(row => { + var dl_row = row as DownloadProgressView; + if(dl_row != null) + { + progress += dl_row.dl_info.download.status.progress; + count++; + } + }); + games_adapter.launcher_entry.progress = progress / count; + games_adapter.launcher_entry.count_visible = count > 0; + games_adapter.launcher_entry.count = count; + } + #endif + + #if MANETTE + private void ui_update_gamepad_mode() + { + Idle.add(() => { + var is_gamepad_connected = connected_gamepads.size > 0 && Gamepad.ButtonPressed; + var widgets_to_show = is_gamepad_connected ? gamepad_mode_visible_widgets : gamepad_mode_hidden_widgets; + var widgets_to_hide = is_gamepad_connected ? gamepad_mode_hidden_widgets : gamepad_mode_visible_widgets; + foreach(var w in widgets_to_show) w.show(); + foreach(var w in widgets_to_hide) w.hide(); + if(is_gamepad_connected) + { + view.selected = 0; + games_grid.grab_focus(); + } + return Source.REMOVE; + }); + } + + private void on_gamepad_connected(Manette.Device device) + { + var known = controller_settings.known_controllers; + var ignored = controller_settings.ignored_controllers; + + if(!(device.get_name() in known)) + { + known += device.get_name(); + controller_settings.known_controllers = known; + } + + if(device.get_name() in ignored) + { + debug("[Gamepad] '%s' connected [ignored]", device.get_name()); + return; + } + + debug("[Gamepad] '%s' connected", device.get_name()); + + device.button_press_event.connect(on_gamepad_button_press_event); + device.button_release_event.connect(on_gamepad_button_release_event); + device.absolute_axis_event.connect(on_gamepad_absolute_axis_event); + connected_gamepads.add(device); + gamepad_axes_to_keys_thread(); + ui_update_gamepad_mode(); + } + + private void on_gamepad_disconnected(Manette.Device device) + { + debug("[Gamepad] '%s' disconnected", device.get_name()); + connected_gamepads.remove(device); + ui_update_gamepad_mode(); + } + + private void on_gamepad_button_press_event(Manette.Device device, Manette.Event e) + { + uint16 btn; + if(!e.get_button(out btn)) return; + on_gamepad_button(btn, true); + } + + private void on_gamepad_button_release_event(Manette.Event e) + { + uint16 btn; + if(!e.get_button(out btn)) return; + on_gamepad_button(btn, false); + } + + private void on_gamepad_button(uint16 btn, bool press) + { + if(Gamepad.Buttons.has_key(btn)) + { + var b = Gamepad.Buttons.get(btn); + b.emit_key_event(press); + + if(GameHub.Application.log_verbose && !Runnable.IsLaunched && !Sources.Steam.Steam.IsAnyAppRunning) + { + debug("[Gamepad] Button %s: %s (%s) [%d]", (press ? "pressed" : "released"), b.name, b.long_name, btn); + } + + ui_update_gamepad_mode(); + + if(controller_settings.focus_window && !press && b == Gamepad.BTN_GUIDE && !window.has_focus && !Runnable.IsLaunched && !Sources.Steam.Steam.IsAnyAppRunning) + { + window.get_window().focus(Gdk.CURRENT_TIME); + } + } + } + + private void on_gamepad_absolute_axis_event(Manette.Event e) + { + uint16 axis; + double value; + if(!e.get_absolute(out axis, out value)) return; + + if(Gamepad.Axes.has_key(axis)) + { + Gamepad.Axes.get(axis).value = value; + } + } + + private void gamepad_axes_to_keys_thread() + { + if(gamepad_axes_to_keys_thread_running) return; + Utils.thread("GamepadAxesToKeysThread", () => { + gamepad_axes_to_keys_thread_running = true; + while(connected_gamepads.size > 0) + { + foreach(var axis in Gamepad.Axes.values) + { + axis.emit_key_event(); + } + Thread.usleep(Gamepad.KEY_EVENT_EMIT_INTERVAL); + ui_update_gamepad_mode(); + } + Gamepad.reset(); + gamepad_axes_to_keys_thread_running = false; + }); + } + + private Widget gamepad_image(string icon, string? text=null) + { + Widget widget; + + var image = new Image.from_icon_name("controller-button-" + icon, IconSize.LARGE_TOOLBAR); + + if(text != null) + { + var label = Styled.H4Label(text); + var box = new Box(Orientation.HORIZONTAL, 8); + box.margin_start = box.margin_end = 4; + box.add(image); + box.add(label); + box.show_all(); + widget = box; + } + else + { + widget = image; + } + + widget.visible = false; + widget.no_show_all = true; + + gamepad_mode_visible_widgets.add(widget); + return widget; + } + #endif + } +} diff --git a/src/ui/views/GamesView/grid/GameCard.vala b/src/ui/views/GamesView/grid/GameCard.vala new file mode 100644 index 00000000..5a1c21bc --- /dev/null +++ b/src/ui/views/GamesView/grid/GameCard.vala @@ -0,0 +1,488 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; +using Gee; + +using GameHub.Data; +using GameHub.Data.Adapters; +using GameHub.Data.DB; +using GameHub.Utils; +using GameHub.UI.Widgets; + +namespace GameHub.UI.Views.GamesView.Grid +{ + public class GameCard: FlowBoxChild + { + public GamesAdapter? adapter { private get; construct; default = null; } + private ArrayList? merges = null; + + private Game? _game = null; + private Game? _visible_game = null; + public Game? game + { + get + { + return _visible_game; + } + construct set + { + update_game(value); + } + } + + public signal void update_tags(); + + private Frame card; + private Overlay content; + private AutoSizeImage image; + private Label label; + private Label status_label; + + private Box src_icons; + private Image src_icon; + + private Image favorite_icon; + private Image updated_icon; + + private Box platform_icons; + + private Box actions; + + private Frame progress_bar; + + private Image no_image_indicator; + private Image running_indicator; + + private bool _image_is_visible = false; + public bool image_is_visible + { + get + { + return _image_is_visible; + } + set + { + if(_image_is_visible != value) + { + _image_is_visible = value; + update_image(); + } + } + } + + public GameCard(Game? game=null, GamesAdapter? adapter=null) + { + Object(game: game, adapter: adapter); + } + + construct + { + margin = 0; + + card = Styled.Card("gamecard"); + card.margin = 4; + + child = card; + + content = new Overlay(); + + image = new AutoSizeImage(); + + src_icons = new Box(Orientation.HORIZONTAL, 4); + src_icons.valign = Align.START; + src_icons.halign = Align.START; + src_icons.margin = 8; + src_icons.set_events(0); + + platform_icons = new Box(Orientation.HORIZONTAL, 4); + platform_icons.valign = Align.START; + platform_icons.halign = Align.END; + platform_icons.margin = 8; + platform_icons.set_events(0); + + src_icon = new Image(); + src_icon.icon_size = IconSize.LARGE_TOOLBAR; + + label = new Label(""); + label.xpad = 8; + label.ypad = 4; + label.hexpand = true; + label.justify = Justification.CENTER; + label.lines = 3; + label.ellipsize = Pango.EllipsizeMode.END; + label.set_line_wrap(true); + + favorite_icon = new Image.from_icon_name("gh-game-favorite-symbolic", IconSize.BUTTON); + favorite_icon.valign = Align.END; + favorite_icon.halign = Align.START; + favorite_icon.margin = 6; + + updated_icon = new Image.from_icon_name("gh-game-updated-symbolic", IconSize.BUTTON); + updated_icon.valign = Align.END; + updated_icon.halign = Align.END; + updated_icon.margin = 6; + + favorite_icon.pixel_size = updated_icon.pixel_size = 12; + + status_label = new Label(""); + status_label.get_style_context().add_class("status"); + status_label.xpad = 8; + status_label.ypad = 2; + status_label.hexpand = true; + status_label.justify = Justification.CENTER; + status_label.lines = 1; + + var info = new Box(Orientation.VERTICAL, 0); + info.get_style_context().add_class("info"); + info.add(label); + info.add(status_label); + info.valign = Align.END; + + actions = new Box(Orientation.VERTICAL, 0); + actions.get_style_context().add_class("actions"); + actions.hexpand = true; + actions.vexpand = true; + + progress_bar = new Frame(null); + progress_bar.halign = Align.START; + progress_bar.valign = Align.END; + progress_bar.get_style_context().add_class("progress"); + + no_image_indicator = new Image.from_icon_name("gamehub-symbolic", IconSize.DIALOG); + no_image_indicator.get_style_context().add_class("no-image-indicator"); + no_image_indicator.halign = Align.CENTER; + no_image_indicator.valign = Align.CENTER; + no_image_indicator.opacity = 0; + + running_indicator = new Image.from_icon_name("system-run-symbolic", IconSize.DIALOG); + running_indicator.get_style_context().add_class("running-indicator"); + running_indicator.halign = Align.CENTER; + running_indicator.valign = Align.CENTER; + running_indicator.opacity = 0; + + content.add(image); + content.add_overlay(actions); + content.add_overlay(info); + content.add_overlay(platform_icons); + content.add_overlay(src_icons); + content.add_overlay(favorite_icon); + content.add_overlay(updated_icon); + content.add_overlay(progress_bar); + content.add_overlay(no_image_indicator); + content.add_overlay(running_indicator); + + card.add(content); + + content.add_events(EventMask.ALL_EVENTS_MASK); + content.enter_notify_event.connect(e => { card.get_style_context().add_class("hover"); }); + content.leave_notify_event.connect(e => { card.get_style_context().remove_class("hover"); }); + content.button_press_event.connect(e => { + switch(e.button) + { + case 1: + if(!Settings.UI.Behavior.instance.grid_doubleclick || (Settings.UI.Behavior.instance.grid_doubleclick && e.type == EventType.2BUTTON_PRESS)) + { + game.run_or_install.begin(); + } + break; + + case 3: + open_context_menu(e, true); + break; + } + ((FlowBox) parent).select_child(this); + grab_focus(); + return true; + }); + key_release_event.connect(e => { + switch(((EventKey) e).keyval) + { + case Key.Return: + case Key.space: + case Key.KP_Space: + game.run_or_install.begin(); + return true; + + case Key.Menu: + open_context_menu(e, false); + return true; + } + return false; + }); + + Settings.UI.Appearance.instance.notify["grid-platform-icons"].connect(update_grid_icons); + update_grid_icons(); + + Settings.UI.Appearance.instance.notify["grid-card-width"].connect(update_image_constraints); + Settings.UI.Appearance.instance.notify["grid-card-height"].connect(update_image_constraints); + update_image_constraints(); + } + + private ulong status_handler_id; + private ulong image_handler_id; + private ulong image_vertical_handler_id; + private ulong updates_handler_id; + + private void update_game(Game? new_game) + { + if(new_game == _game || new_game == null) return; + + if(_game != null) + { + _game.disconnect(status_handler_id); + _game.disconnect(image_handler_id); + _game.disconnect(image_vertical_handler_id); + _game.disconnect(updates_handler_id); + } + + _game = new_game; + + if(Settings.UI.Behavior.instance.merge_games) + { + merges = Tables.Merges.get(_game); + } + + if(adapter != null) + { + adapter.notify["filter-source"].connect(() => { + update_source(adapter.filter_source); + }); + update_source(adapter.filter_source); + } + else + { + update_source(null); + } + } + + private void update_source(GameSource? source=null) + { + if(!Settings.UI.Behavior.instance.merge_games || merges == null || merges.size == 0) + { + update(_game); + return; + } + + var vg = _game; + + if(merges != null && merges.size > 0) + { + foreach(var g in merges) + { + if(vg is Sources.User.UserGame) break; + if(source == null) + { + if(g.status.state > vg.status.state || g is Sources.User.UserGame) + { + vg = g; + } + } + else if(g.source == source) + { + vg = g; + break; + } + } + } + + update(vg); + } + + private void update(Game? vg) + { + _visible_game = vg; + + Idle.add(() => { + label.label = game.name; + src_icon.icon_name = game.source.icon; + + src_icons.foreach(w => w.destroy()); + src_icons.add(src_icon); + + if(game != _game) + { + add_src_icon(_game.source.icon); + } + if(Settings.UI.Behavior.instance.merge_games && merges != null && merges.size > 0) + { + foreach(var g in merges) + { + if(g == game) continue; + add_src_icon(g.source.icon); + } + } + src_icons.show_all(); + + platform_icons.foreach(w => w.destroy()); + Platform[] platforms = {}; + foreach(var p in game.platforms) + { + if(!(p in platforms)) + { + platforms += p; + } + } + if(Settings.UI.Behavior.instance.merge_games && adapter.filter_source == null && merges != null && merges.size > 0) + { + foreach(var g in merges) + { + if(g == game) continue; + foreach(var p in g.platforms) + { + if(!(p in platforms)) + { + platforms += p; + } + } + } + } + foreach(var p in platforms) + { + var icon = new Image(); + icon.icon_name = p.icon(); + icon.icon_size = IconSize.LARGE_TOOLBAR; + platform_icons.add(icon); + } + platform_icons.show_all(); + + return Source.REMOVE; + }); + + status_handler_id = game.status_change.connect(status_handler); + status_handler(game.status); + + image_handler_id = game.notify["image"].connect(update_image); + image_vertical_handler_id = game.notify["image-vertical"].connect(update_image); + update_image(); + + updates_handler_id = game.notify["has-updates"].connect(updates_handler); + updates_handler(); + } + + private void add_src_icon(string icon_name) + { + var icon = new Image(); + icon.icon_name = icon_name; + icon.icon_size = IconSize.LARGE_TOOLBAR; + src_icons.add(icon); + } + + private void status_handler(Game.Status s) + { + Idle.add(() => { + label.label = game.name; + status_label.label = s.description; + favorite_icon.visible = game.has_tag(Tables.Tags.BUILTIN_FAVORITES); + switch(s.state) + { + case Game.State.UNINSTALLED: + card.get_style_context().remove_class("installed"); + card.get_style_context().remove_class("downloading"); + card.get_style_context().remove_class("installing"); + break; + + case Game.State.INSTALLED: + card.get_style_context().add_class("installed"); + card.get_style_context().remove_class("downloading"); + card.get_style_context().remove_class("installing"); + break; + + case Game.State.DOWNLOADING: + card.get_style_context().remove_class("installed"); + card.get_style_context().add_class("downloading"); + card.get_style_context().remove_class("installing"); + Allocation alloc; + card.get_allocation(out alloc); + if(s.download != null && s.download.status != null && s.download.status.progress >= 0) + { + progress_bar.set_size_request((int) (s.download.status.progress * alloc.width), 8); + } + break; + + case Game.State.INSTALLING: + card.get_style_context().remove_class("installed"); + card.get_style_context().remove_class("downloading"); + card.get_style_context().add_class("installing"); + break; + } + if(game.is_running) + { + card.get_style_context().add_class("running"); + running_indicator.opacity = 1; + no_image_indicator.opacity = 0; + } + else + { + card.get_style_context().remove_class("running"); + running_indicator.opacity = 0; + no_image_indicator.opacity = game.image == null && game.image_vertical == null ? 1 : 0; + } + return Source.REMOVE; + }, Priority.LOW); + } + + private void update_image() + { + if(image == null) return; + if(image_is_visible) + { + image.load(game.image, game.image_vertical, @"games/$(game.source.id)/$(game.id)/images/"); + no_image_indicator.opacity = game.image == null && game.image_vertical == null && !game.is_running ? 1 : 0; + } + else + { + #if PERF_GAMECARD_UNLOAD_IMAGES + image.unload(); + #endif + } + } + + private void updates_handler() + { + Idle.add(() => { + updated_icon.visible = game is GameHub.Data.Sources.GOG.GOGGame && (game as GameHub.Data.Sources.GOG.GOGGame).has_updates; + return Source.REMOVE; + }, Priority.LOW); + } + + private void update_grid_icons() + { + Idle.add(() => { + src_icons.visible = platform_icons.visible = Settings.UI.Appearance.instance.grid_platform_icons; + return Source.REMOVE; + }, Priority.LOW); + } + + private void update_image_constraints() + { + var w = Settings.UI.Appearance.instance.grid_card_width; + var h = Settings.UI.Appearance.instance.grid_card_height; + var ratio = (float) h / w; + var min = (int) (w / 1.5f); + var max = (int) (w * 1.5f); + image.set_constraint(min, max, ratio); + } + + private void open_context_menu(Event e, bool at_pointer=true) + { + new GameContextMenu(game, this).open(e, at_pointer); + } + } +} diff --git a/src/ui/views/GamesView/grid/GamesGrid.vala b/src/ui/views/GamesView/grid/GamesGrid.vala new file mode 100644 index 00000000..5398952f --- /dev/null +++ b/src/ui/views/GamesView/grid/GamesGrid.vala @@ -0,0 +1,119 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; +using Gee; + +using GameHub.Data; +using GameHub.Data.Adapters; +using GameHub.Data.DB; +using GameHub.Utils; +using GameHub.UI.Widgets; + +namespace GameHub.UI.Views.GamesView.Grid +{ + public class GamesGrid: FlowBox + { + public signal void game_selected(Game? game); + + private GamesAdapter? adapter = null; + public ScrolledWindow scrolled; + + public GamesGrid() + { + Object(selection_mode: SelectionMode.SINGLE); + } + + construct + { + get_style_context().add_class("games-grid"); + margin = 4; + activate_on_single_click = false; + homogeneous = true; + min_children_per_line = 2; + max_children_per_line = 32; + selection_mode = SelectionMode.BROWSE; + valign = Align.START; + } + + public void attach(GamesAdapter adapter) + { + this.adapter = adapter; + adapter.attach_grid(this); + } + + public void select(int index, bool grab_focus=false) + { + var card = get_child_at_index(index); + if(card != null) + { + select_child(card); + if(grab_focus) card.grab_focus(); + } + } + + private void update_scroll() + { + var scroll = scrolled.vadjustment.value; + var height = scrolled.vadjustment.page_size; + + var viewport_top = scroll; + var viewport_bottom = scroll + height; + + this.foreach(w => { + var card = (GameCard) w; + + if(!card.visible) return; + + Allocation alloc; + card.get_allocation(out alloc); + + if(alloc.x < 0 || alloc.y < 0 || alloc.width < 1 || alloc.height < 1) return; + + var card_top = alloc.y; + var card_bottom = alloc.y + alloc.height; + + var is_before_viewport = card_bottom < viewport_top; + var is_after_viewport = card_top > viewport_bottom; + + card.image_is_visible = !is_before_viewport && !is_after_viewport; + }); + } + + public ScrolledWindow wrapped() + { + scrolled = new ScrolledWindow(null, null); + scrolled.expand = true; + scrolled.hscrollbar_policy = PolicyType.NEVER; + scrolled.add(this); + setup_scroll_events(); + scrolled.show_all(); + show_all(); + return scrolled; + } + + private void setup_scroll_events() + { + var limiter = new SignalRateLimiter(100); + scrolled.vadjustment.value_changed.connect(() => limiter.update()); + scrolled.size_allocate.connect(() => limiter.update()); + limiter.signaled.connect(update_scroll); + } + } +} diff --git a/src/ui/views/GamesView/list/GameListRow.vala b/src/ui/views/GamesView/list/GameListRow.vala new file mode 100644 index 00000000..6b794e42 --- /dev/null +++ b/src/ui/views/GamesView/list/GameListRow.vala @@ -0,0 +1,344 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; +using Gee; + +using GameHub.Data; +using GameHub.Data.Adapters; +using GameHub.Data.DB; +using GameHub.Utils; +using GameHub.UI.Widgets; + +namespace GameHub.UI.Views.GamesView.List +{ + public class GameListRow: ListBoxRow + { + public GamesAdapter? adapter { private get; construct; default = null; } + private ArrayList? merges = null; + + private Game? _game = null; + private Game? _visible_game = null; + public Game? game + { + get + { + return _visible_game; + } + construct set + { + update_game(value); + } + } + + public signal void update_tags(); + + private Overlay icon_overlay; + private AutoSizeImage icon; + private Image no_icon_indicator; + + private Label label; + private Label status_label; + private Image favorite_icon; + private Image updated_icon; + + private bool _icon_is_visible = false; + public bool icon_is_visible + { + get + { + return _icon_is_visible; + } + set + { + if(_icon_is_visible != value) + { + _icon_is_visible = value; + update_icon(); + } + } + } + + private GameHub.Settings.UI.Appearance ui_settings; + + public GameListRow(Game? game=null, GamesAdapter? adapter=null) + { + Object(game: game, adapter: adapter, activatable: true, selectable: true); + } + + construct + { + get_style_context().add_class("game-list-row"); + + var hbox = new Box(Orientation.HORIZONTAL, 4); + hbox.margin = 4; + var vbox = new Box(Orientation.VERTICAL, 0); + vbox.margin_start = 4; + vbox.valign = Align.CENTER; + + icon_overlay = new Overlay(); + icon_overlay.no_show_all = true; + + no_icon_indicator = new Image.from_icon_name("gamehub-symbolic", IconSize.BUTTON); + no_icon_indicator.get_style_context().add_class("no-icon-indicator"); + no_icon_indicator.halign = Align.CENTER; + no_icon_indicator.valign = Align.CENTER; + no_icon_indicator.opacity = 0.8; + + icon = new AutoSizeImage(); + icon.halign = Align.CENTER; + icon.valign = Align.CENTER; + icon.scale = true; + + icon_overlay.add(no_icon_indicator); + icon_overlay.add_overlay(icon); + + no_icon_indicator.show_all(); + icon.show_all(); + + hbox.add(icon_overlay); + + var label_hbox = new Box(Orientation.HORIZONTAL, 4); + + favorite_icon = new Image.from_icon_name("gh-game-favorite-symbolic", IconSize.BUTTON); + updated_icon = new Image.from_icon_name("gh-game-updated-symbolic", IconSize.BUTTON); + favorite_icon.no_show_all = updated_icon.no_show_all = true; + favorite_icon.margin_top = updated_icon.margin_top = 2; + favorite_icon.valign = updated_icon.valign = Align.CENTER; + favorite_icon.pixel_size = updated_icon.pixel_size = 8; + + label = Styled.Label(null, "title"); + label.hexpand = true; + label.xalign = 0; + label.ellipsize = Pango.EllipsizeMode.END; + + label_hbox.add(label); + label_hbox.add(favorite_icon); + label_hbox.add(updated_icon); + + status_label = Styled.Label(null, "status"); + status_label.halign = Align.START; + status_label.xalign = 0; + status_label.ellipsize = Pango.EllipsizeMode.END; + status_label.no_show_all = true; + + vbox.add(label_hbox); + vbox.add(status_label); + + hbox.add(vbox); + + notify["is-selected"].connect(update_icon); + + ui_settings = GameHub.Settings.UI.Appearance.instance; + ui_settings.list_style_updated.connect(update_style); + update_style(ui_settings.list_style_cache); + + var ebox = new EventBox(); + ebox.add(hbox); + + child = ebox; + + ebox.add_events(EventMask.ALL_EVENTS_MASK); + ebox.button_press_event.connect(e => { + switch(e.button) + { + case 1: + var list = (ListBox) parent; + + if(ModifierType.CONTROL_MASK in e.state) + { + if(is_selected()) + { + list.unselect_row(this); + } + else + { + list.select_row(this); + } + } + else + { + list.unselect_all(); + activate(); + + if(e.type == EventType.2BUTTON_PRESS) + { + game.run_or_install.begin(); + } + } + break; + + case 3: + new GameContextMenu(game, icon).open(e, true); + break; + } + return true; + }); + } + + private ulong status_handler_id; + private ulong updates_handler_id; + + private void update_game(Game? new_game) + { + if(new_game == _game || new_game == null) return; + + if(_game != null) + { + _game.disconnect(status_handler_id); + _game.disconnect(updates_handler_id); + } + + _game = new_game; + if(Settings.UI.Behavior.instance.merge_games) + { + merges = Tables.Merges.get(_game); + } + + if(adapter != null) + { + adapter.notify["filter-source"].connect(() => { + update_source(adapter.filter_source); + }); + update_source(adapter.filter_source); + } + else + { + update_source(null); + } + } + + private void update_source(GameSource? source=null) + { + if(!Settings.UI.Behavior.instance.merge_games || merges == null || merges.size == 0) + { + update(_game); + return; + } + + var vg = _game; + + if(merges != null && merges.size > 0) + { + foreach(var g in merges) + { + if(vg is Sources.User.UserGame) break; + if(source == null) + { + if(g.status.state > vg.status.state || g is Sources.User.UserGame) + { + vg = g; + } + } + else if(g.source == source) + { + vg = g; + break; + } + } + } + + update(vg); + } + + private void update(Game? vg) + { + _visible_game = vg; + + status_handler_id = game.status_change.connect(status_handler); + status_handler(game.status); + + updates_handler_id = game.notify["has-updates"].connect(updates_handler); + updates_handler(); + } + + private void status_handler(Game.Status s) + { + Idle.add(() => { + label.label = game.name; + status_label.label = s.description; + tooltip_markup = """%s""".printf(game.name.replace("&", "&").replace("&", "&")) + "\n" + """%s""".printf(s.description.replace("&", "&").replace("&", "&")); + update_style(ui_settings.list_style_cache); + favorite_icon.visible = game.has_tag(Tables.Tags.BUILTIN_FAVORITES); + update_icon(); + changed(); + return Source.REMOVE; + }, Priority.LOW); + } + + private void updates_handler() + { + Idle.add(() => { + updated_icon.visible = game is GameHub.Data.Sources.GOG.GOGGame && (game as GameHub.Data.Sources.GOG.GOGGame).has_updates; + return Source.REMOVE; + }, Priority.LOW); + } + + public void update_style(string[] style) + { + var is_gog_game = game is GameHub.Data.Sources.GOG.GOGGame; + var is_installed = game != null && game.status != null && game.status.state != Game.State.UNINSTALLED; + + var style_prefix = is_installed ? "installed" : "uninstalled"; + + var show_status = @"$(style_prefix)-status" in style; + + // GOG icons are rounded, make them bigger to compensate visual difference + var image_size = !show_status ? (is_gog_game ? 18 : 16) : (is_gog_game ? 38 : 32); + var overlay_size = !show_status ? 18 : 38; + + icon.set_constraint(image_size, image_size, 1); + icon_overlay.set_size_request(overlay_size, overlay_size); + + status_label.visible = show_status; + + icon_overlay.visible = @"$(style_prefix)-icon" in style; + + if(@"$(style_prefix)-title-bold" in style) + { + StyleClass.add(label, "bold"); + } + else + { + StyleClass.remove(label, "bold"); + } + + if(@"$(style_prefix)-dim" in style) + { + StyleClass.add(this, "dim"); + } + else + { + StyleClass.remove(this, "dim"); + } + } + + private void update_icon() + { + if(icon_is_visible) + { + icon.load(game.icon, null, @"games/$(game.source.id)/$(game.id)/icons/"); + } + else + { + icon.unload(); + } + } + } +} diff --git a/src/ui/views/GamesView/list/GamesList.vala b/src/ui/views/GamesView/list/GamesList.vala new file mode 100644 index 00000000..1c3e4ebf --- /dev/null +++ b/src/ui/views/GamesView/list/GamesList.vala @@ -0,0 +1,123 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; +using Gee; + +using GameHub.Data; +using GameHub.Data.Adapters; +using GameHub.Data.DB; +using GameHub.Utils; +using GameHub.UI.Widgets; + +namespace GameHub.UI.Views.GamesView.List +{ + public class GamesList: ListBox + { + public signal void game_selected(Game? game); + public signal void multiple_games_selected(ArrayList games); + + private GamesAdapter? adapter = null; + public ScrolledWindow scrolled; + + public GamesList() + { + Object(selection_mode: SelectionMode.MULTIPLE); + } + + construct + { + selected_rows_changed.connect(() => { + var rows = get_selected_rows(); + if(rows.length() == 1) + { + game_selected(((GameListRow) rows.data).game); + } + else if(rows.length() > 1) + { + var selected = new ArrayList(); + foreach(var row in rows) + { + var game = ((GameListRow) row).game; + if(game != null) selected.add(game); + } + multiple_games_selected(selected); + } + }); + } + + public void attach(GamesAdapter adapter) + { + this.adapter = adapter; + adapter.attach_list(this); + } + + public void select(int index, bool grab_focus=false) + { + unselect_all(); + var row = get_row_at_index(index); + if(row != null) + { + select_row(row); + if(grab_focus) row.grab_focus(); + } + } + + private void update_scroll() + { + var scroll = scrolled.vadjustment.value; + var height = scrolled.vadjustment.page_size; + + var viewport_top = scroll; + var viewport_bottom = scroll + height; + + this.foreach(w => { + var row = (GameListRow) w; + + if(!row.visible) return; + + Allocation alloc; + row.get_allocation(out alloc); + + if(alloc.x < 0 || alloc.y < 0 || alloc.width < 1 || alloc.height < 1) return; + + var row_top = alloc.y; + var row_bottom = alloc.y + alloc.height; + + var is_before_viewport = row_bottom < viewport_top; + var is_after_viewport = row_top > viewport_bottom; + + row.icon_is_visible = !is_before_viewport && !is_after_viewport; + }); + } + + public ScrolledWindow wrapped() + { + scrolled = new ScrolledWindow(null, null); + scrolled.hscrollbar_policy = PolicyType.NEVER; + scrolled.set_size_request(220, -1); + scrolled.add(this); + scrolled.vadjustment.value_changed.connect(update_scroll); + scrolled.size_allocate.connect(update_scroll); + scrolled.show_all(); + show_all(); + return scrolled; + } + } +} diff --git a/src/ui/views/WelcomeView.vala b/src/ui/views/WelcomeView.vala index f73880f5..1029a4ab 100644 --- a/src/ui/views/WelcomeView.vala +++ b/src/ui/views/WelcomeView.vala @@ -1,100 +1,204 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + using Gtk; -using Granite; +using GameHub.UI.Widgets; + using GameHub.Data; using GameHub.Utils; namespace GameHub.UI.Views { public class WelcomeView: BaseView - { - private Granite.Widgets.Welcome welcome; - + { + private Stack stack; + private AlertView empty_alert; + private Welcome welcome; + private Button skip_btn; - + private Button settings; + + private bool is_updating = false; + construct { - welcome = new Granite.Widgets.Welcome(_("All your games in one place"), _("Let's get started")); - + var ui_settings = GameHub.Settings.UI.Appearance.instance; + + stack = new Stack(); + stack.transition_type = StackTransitionType.CROSSFADE; + + var spinner = new Spinner(); + spinner.active = true; + spinner.set_size_request(36, 36); + spinner.halign = Align.CENTER; + spinner.valign = Align.CENTER; + stack.add(spinner); + + empty_alert = new AlertView(_("No enabled game sources"), _("Enable some game sources in settings"), "dialog-warning"); + empty_alert.show_action(_("Settings")); + + stack.add(empty_alert); + + welcome = new Welcome(_("All your games in one place"), _("Let's get started")); + welcome.activated.connect(index => { on_entry_clicked.begin(index); }); - - add(welcome); - + + stack.add(welcome); + + add(stack); + + titlebar.get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + welcome.get_style_context().remove_class(Gtk.STYLE_CLASS_VIEW); + empty_alert.get_style_context().remove_class(Gtk.STYLE_CLASS_VIEW); + skip_btn = new Button.with_label(_("Skip")); - skip_btn.clicked.connect(open_games_grid); - skip_btn.set_sensitive(false); - + skip_btn.clicked.connect(open_games_view); + skip_btn.halign = Align.CENTER; + skip_btn.valign = Align.CENTER; + + settings = new Button(); + settings.valign = Align.CENTER; + Utils.set_accel_tooltip(settings, _("Settings"), Application.ACCEL_SETTINGS); + settings.image = new Image.from_icon_name("open-menu" + Settings.UI.Appearance.symbolic_icon_suffix, Settings.UI.Appearance.headerbar_icon_size); + settings.action_name = Application.ACTION_PREFIX + Application.ACTION_SETTINGS; + + ui_settings.notify["symbolic-icons"].connect(() => { + (settings.image as Image).icon_name = "open-menu" + Settings.UI.Appearance.symbolic_icon_suffix; + (settings.image as Image).icon_size = Settings.UI.Appearance.headerbar_icon_size; + }); + + empty_alert.action_activated.connect(() => settings.clicked()); + + titlebar.pack_end(settings); titlebar.pack_end(skip_btn); - + + settings.opacity = 0; + settings.sensitive = false; + skip_btn.opacity = 0; + skip_btn.sensitive = false; + foreach(var src in GameSources) { - var image = FSUtils.get_icon(src.icon); - welcome.append_with_pixbuf(image, src.name, ""); + welcome.append(src.icon, src.name, ""); } + update_entries.begin(); } - + public override void on_window_focus() { update_entries.begin(); } - - private void open_games_grid() + + private void open_games_view() { - window.add_view(new GamesGridView()); + window.add_view(new GamesView.GamesView()); } - + private async void update_entries() { - skip_btn.set_sensitive(false); + if(is_updating) return; + is_updating = true; + + skip_btn.sensitive = false; var all_authenticated = true; - + int enabled_sources = 0; + for(int index = 0; index < GameSources.length; index++) { var src = GameSources[index]; - + var btn = welcome.get_button_from_index(index); - + + welcome.set_item_visible(index, !(src is Sources.Humble.Trove) && !(src is Sources.User.User) && src.enabled); + + if(src is Sources.Humble.Trove || !src.enabled) continue; + enabled_sources++; + if(src.is_installed(true)) { btn.title = src.name; - + if(src.is_authenticated()) { btn.description = _("Ready"); welcome.set_item_sensitivity(index, false); - skip_btn.set_sensitive(true); + skip_btn.sensitive = true; } else { btn.description = _("Authentication required") + src.auth_description; all_authenticated = false; + + if(src.can_authenticate_automatically()) + { + btn.description = _("Authenticating…"); + welcome.set_item_sensitivity(index, false); + yield src.authenticate(); + is_updating = false; + update_entries.begin(); + return; + } } } else { btn.title = _("Install %s").printf(src.name); - btn.description = "Return to GameHub after installing"; + btn.description = _("Return to GameHub after installing"); all_authenticated = false; } } - - if(all_authenticated) + + if(enabled_sources > 0 && all_authenticated) + { + Idle.add(() => { open_games_view(); return false; }); + return; + } + + if(enabled_sources == 0) + { + settings.opacity = 0; + settings.sensitive = false; + skip_btn.opacity = 0; + stack.set_visible_child(empty_alert); + empty_alert.show_all(); + } + else { - open_games_grid(); + settings.opacity = 1; + settings.sensitive = true; + skip_btn.opacity = 1; + stack.set_visible_child(welcome); + welcome.show_all(); } - - welcome.show_all(); + + is_updating = false; } - + private async void on_entry_clicked(int index) { welcome.set_item_sensitivity(index, false); - + GameSource src = GameSources[index]; var installed = src.is_installed(); - + if(installed) { if(!src.is_authenticated()) diff --git a/src/ui/widgets/ActionButton.vala b/src/ui/widgets/ActionButton.vala new file mode 100644 index 00000000..caecae09 --- /dev/null +++ b/src/ui/widgets/ActionButton.vala @@ -0,0 +1,106 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; + +namespace GameHub.UI.Widgets +{ + class ActionButton: Gtk.Button + { + public string icon { get; construct set; } + public string? icon_overlay { get; construct set; } + public string text { get; construct set; } + public bool show_text { get; construct; default = true; } + public bool compact { get; construct set; default = false; } + + public ActionButton(string icon, string? icon_overlay, string text, bool show_text=true, bool compact=false) + { + Object(icon: icon, icon_overlay: icon_overlay, text: text, show_text: show_text, compact: compact); + } + + construct + { + get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + + var box = new Box(Orientation.HORIZONTAL, 8); + + var overlay = new Overlay(); + overlay.valign = Align.CENTER; + overlay.set_size_request(48, 48); + + var image = new Image.from_icon_name(icon, IconSize.DIALOG); + image.valign = Align.CENTER; + overlay.add(image); + + notify["icon"].connect(() => { + image.icon_name = compact ? icon_overlay ?? icon : icon; + }); + + Image? overlay_image = null; + + if(icon_overlay != null) + { + overlay_image = new Image.from_icon_name(icon_overlay, IconSize.LARGE_TOOLBAR); + overlay_image.set_size_request(24, 24); + overlay_image.halign = Align.END; + overlay_image.valign = Align.END; + overlay.add_overlay(overlay_image); + overlay.set_overlay_pass_through(overlay_image, true); + notify["icon-overlay"].connect(() => { + overlay_image.icon_name = icon_overlay; + image.icon_name = compact ? icon_overlay ?? icon : icon; + }); + } + + box.add(overlay); + + if(show_text) + { + var label = Styled.H3Label(text.replace("&", "&").replace("&", "&")); + label.halign = Align.START; + label.valign = Align.CENTER; + label.xalign = 0; + label.ellipsize = Pango.EllipsizeMode.END; + label.use_markup = true; + box.add(label); + notify["text"].connect(() => { + label.label = text.replace("&", "&").replace("&", "&"); + }); + } + + tooltip_markup = text.replace("&", "&").replace("&", "&"); + notify["text"].connect(() => { + tooltip_markup = text.replace("&", "&").replace("&", "&"); + }); + + notify["compact"].connect(() => { + if(overlay_image != null) + { + overlay_image.no_show_all = compact; + overlay_image.visible = !compact; + image.icon_name = compact ? icon_overlay : icon; + } + image.icon_size = compact ? IconSize.LARGE_TOOLBAR : IconSize.DIALOG; + overlay.set_size_request(compact && !show_text ? -1 : 48, compact ? 32 : 48); + }); + notify_property("compact"); + + child = box; + } + } +} diff --git a/src/ui/widgets/AlertView.vala b/src/ui/widgets/AlertView.vala new file mode 100644 index 00000000..a32f4b54 --- /dev/null +++ b/src/ui/widgets/AlertView.vala @@ -0,0 +1,153 @@ +/* +This file is part of GameHub. +Copyright(C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +/* Based on Granite.Widgets.AlertView */ + +using Gtk; + +namespace GameHub.UI.Widgets +{ + public class AlertView: Grid + { + public signal void action_activated(); + + public string title + { + get + { + return title_label.label; + } + set + { + title_label.label = value; + } + } + + public string description + { + get + { + return description_label.label; + } + set + { + description_label.label = value; + } + } + + public string icon_name + { + owned get + { + return image.icon_name ?? ""; + } + set + { + if(value != null && value != "") + { + image.set_from_icon_name(value, IconSize.DIALOG); + image.no_show_all = false; + image.show(); + } + else + { + image.no_show_all = true; + image.hide(); + } + } + } + + private Label title_label; + private Label description_label; + private Image image; + private Button action_button; + private Revealer action_revealer; + + public AlertView(string title, string description, string icon_name) + { + Object(title: title, description: description, icon_name: icon_name); + } + + construct + { + get_style_context().add_class(Gtk.STYLE_CLASS_VIEW); + + title_label = Styled.H2Label(null); + title_label.hexpand = true; + title_label.max_width_chars = 75; + title_label.wrap = true; + title_label.wrap_mode = Pango.WrapMode.WORD_CHAR; + title_label.use_markup = true; + title_label.xalign = 0; + + description_label = new Label(null); + description_label.hexpand = true; + description_label.max_width_chars = 75; + description_label.wrap = true; + description_label.use_markup = true; + description_label.xalign = 0; + description_label.valign = Align.START; + + action_button = new Button(); + action_button.margin_top = 24; + + action_revealer = new Revealer(); + action_revealer.add(action_button); + action_revealer.halign = Align.END; + action_revealer.transition_type = RevealerTransitionType.SLIDE_UP; + + image = new Image(); + image.margin_top = 6; + image.valign = Align.START; + + var layout = new Grid(); + layout.column_spacing = 12; + layout.row_spacing = 6; + layout.halign = Align.CENTER; + layout.valign = Align.CENTER; + layout.vexpand = true; + layout.margin = 24; + + layout.attach(image, 1, 1, 1, 2); + layout.attach(title_label, 2, 1, 1, 1); + layout.attach(description_label, 2, 2, 1, 1); + layout.attach(action_revealer, 2, 3, 1, 1); + + add(layout); + + action_button.clicked.connect(() => {action_activated();}); + } + + public void show_action(string? label=null) + { + if(label != null) + action_button.label = label; + + if(action_button.label == null) + return; + + action_revealer.set_reveal_child(true); + action_revealer.show_all(); + } + + public void hide_action() + { + action_revealer.set_reveal_child(false); + } + } +} diff --git a/src/ui/widgets/AutoSizeImage.vala b/src/ui/widgets/AutoSizeImage.vala new file mode 100644 index 00000000..3bc93669 --- /dev/null +++ b/src/ui/widgets/AutoSizeImage.vala @@ -0,0 +1,261 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; +using GameHub.Utils; + +namespace GameHub.UI.Widgets +{ + public class AutoSizeImage: DrawingArea + { + private string? url; + private string? url_vertical; + private Pixbuf? src; + private Pixbuf? src_vertical; + private Pixbuf? scaled; + private Pixbuf? scaled_vertical; + private string cache_prefix = ImageCache.DEFAULT_CACHED_FILE_PREFIX; + + private int cmin = 0; + private int cmax = 0; + private float ratio = 1; + private Orientation constraint = Orientation.HORIZONTAL; + + public bool? scale = null; + private bool _scale = true; + private bool _scale_vertical = true; + + public int corner_radius = 4; + + public Pixbuf? source + { + get + { + return src; + } + set + { + src = value; + scaled = src; + if(src != null && src.width > 0 && src.height > 0) + { + _scale = scale ?? (src.width > cmin || src.height > cmin || src.width != src.height); + } + queue_draw(); + } + } + + public Pixbuf? source_vertical + { + get + { + return src_vertical; + } + set + { + src_vertical = value; + scaled_vertical = src_vertical; + if(src_vertical != null && src_vertical.width > 0 && src_vertical.height > 0) + { + _scale_vertical = scale ?? (src_vertical.width > cmin || src_vertical.height > cmin || src_vertical.width != src_vertical.height); + } + queue_draw(); + } + } + + public void set_constraint(int min, int max, float ratio = 1, Orientation orientation = Orientation.HORIZONTAL) + { + this.constraint = orientation; + this.ratio = ratio; + this.cmin = min; + this.cmax = max; + switch(constraint) + { + case Orientation.HORIZONTAL: + set_size_request(cmin, (int) (cmin * ratio)); + break; + + case Orientation.VERTICAL: + set_size_request((int) (cmin / ratio), cmin); + break; + } + load_image(is_vertical); + } + + private bool is_vertical + { + get { return ratio > 1; } + } + + public void load(string? url, string? url_vertical, string cache_prefix=ImageCache.DEFAULT_CACHED_FILE_PREFIX) + { + if(url == this.url && url_vertical == this.url_vertical) return; + unload(); + this.url = url; + this.url_vertical = url_vertical; + this.cache_prefix = cache_prefix; + load_image(is_vertical); + } + + private void load_image(bool vertical=false) + { + if(vertical && url_vertical != null && url_vertical != "") + { + if(src_vertical == null) + { + ImageCache.load.begin(url_vertical, cache_prefix, (obj, res) => { + source_vertical = ImageCache.load.end(res); + if(src_vertical == null) + { + load_image(false); + } + }); + } + } + else if(url != null && url != "") + { + if(src == null) + { + ImageCache.load.begin(url, cache_prefix, (obj, res) => { + source = ImageCache.load.end(res); + }); + } + } + } + + public void unload() + { + url = null; + url_vertical = null; + cache_prefix = ImageCache.DEFAULT_CACHED_FILE_PREFIX; + source = null; + source_vertical = null; + } + + public override SizeRequestMode get_request_mode() + { + switch(constraint) + { + case Orientation.HORIZONTAL: return SizeRequestMode.HEIGHT_FOR_WIDTH; + case Orientation.VERTICAL: return SizeRequestMode.WIDTH_FOR_HEIGHT; + default: return SizeRequestMode.CONSTANT_SIZE; + } + } + + public override void get_preferred_width_for_height(int height, out int minimum_width, out int natural_width) + { + if(constraint == Orientation.VERTICAL) + { + minimum_width = natural_width = (int) (height / ratio); + } + else + { + base.get_preferred_width_for_height(height, out minimum_width, out natural_width); + } + } + + public override void get_preferred_height_for_width(int width, out int minimum_height, out int natural_height) + { + if(constraint == Orientation.HORIZONTAL) + { + minimum_height = natural_height = (int) (width * ratio); + } + else + { + base.get_preferred_height_for_width(width, out minimum_height, out natural_height); + } + } + + public override bool draw(Cairo.Context ctx) + { + ctx.scale(1.0 / scale_factor, 1.0 / scale_factor); + + var width = get_allocated_width() * scale_factor; + var height = get_allocated_height() * scale_factor; + + var img = src; + var scaled_img = scaled; + var _scale_img = _scale; + + if(is_vertical && src_vertical != null) + { + img = src_vertical; + scaled_img = scaled_vertical; + _scale_img = _scale_vertical; + } + + if(img != null && img.width > 0 && img.height > 0) + { + if(_scale_img) + { + var ratio = float.min((float) width / img.width, (float) height / img.height); + var new_width = (int) (img.width * ratio); + var new_height = (int) (img.height * ratio); + + if(new_width < width) + { + new_height = (int) ((float) new_height / (float) new_width * (float) width); + new_width = width; + } + + if(new_height < height) + { + new_width = (int) ((float) new_width / (float) new_height * (float) height); + new_height = height; + } + + if(scaled_img.width != new_width || scaled_img.height != new_height) + { + scaled_img = img.scale_simple(new_width, new_height, InterpType.HYPER); + + if(is_vertical && src_vertical != null) + { + this.scaled_vertical = scaled_img; + } + else + { + this.scaled = scaled_img; + } + } + } + + var x = (width - scaled_img.width) / 2; + var y = (height - scaled_img.height) / 2; + + cairo_rounded_rectangle(ctx, int.max(x, 0), int.max(y, 0), int.min(scaled_img.width, width), int.min(scaled_img.height, height), corner_radius * scale_factor); + cairo_set_source_pixbuf(ctx, scaled_img, x, y); + + ctx.clip(); + ctx.paint(); + } + + return false; + } + + private static void cairo_rounded_rectangle(Cairo.Context cr, double x, double y, double width, double height, double radius) + { + cr.move_to(x + radius, y); + cr.arc(x + width - radius, y + radius, radius, Math.PI * 1.5, Math.PI * 2); + cr.arc(x + width - radius, y + height - radius, radius, 0, Math.PI * 0.5); + cr.arc(x + radius, y + height - radius, radius, Math.PI * 0.5, Math.PI); + cr.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 1.5); + cr.close_path(); + } + } +} diff --git a/src/ui/widgets/CompatToolOptions.vala b/src/ui/widgets/CompatToolOptions.vala new file mode 100644 index 00000000..5b6a6fb8 --- /dev/null +++ b/src/ui/widgets/CompatToolOptions.vala @@ -0,0 +1,305 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; + + +using GameHub.Data; +using GameHub.Utils; + +namespace GameHub.UI.Widgets +{ + public class CompatToolOptions: ListBox + { + private CompatToolPicker compat_tool_picker; + private Runnable runnable; + private bool install; + private string settings_key; + + public CompatToolOptions(Runnable runnable, CompatToolPicker picker, bool install = false) + { + this.runnable = runnable; + this.compat_tool_picker = picker; + this.install = install; + this.settings_key = install ? "install_options" : "options"; + visible = false; + get_style_context().add_class("tags-list"); + selection_mode = SelectionMode.NONE; + update_options(); + compat_tool_picker.notify["selected"].connect(update_options); + } + + public void update_options() + { + this.foreach(r => r.destroy()); + visible = false; + + if(compat_tool_picker == null || compat_tool_picker.selected == null) return; + var options = install ? compat_tool_picker.selected.install_options : compat_tool_picker.selected.options; + if(options == null) return; + + var tool_settings = runnable.get_compat_settings(compat_tool_picker.selected); + var ts_options = tool_settings.has_member(settings_key) ? tool_settings.get_object_member(settings_key) : new Json.Object(); + + foreach(var opt in options) + { + if(ts_options != null && ts_options.has_member(opt.name)) + { + if(opt is CompatTool.BoolOption) + { + ((CompatTool.BoolOption) opt).enabled = ts_options.get_boolean_member(opt.name); + } + else if(opt is CompatTool.FileOption) + { + ((CompatTool.FileOption) opt).file = FSUtils.file(ts_options.get_string_member(opt.name)); + } + else if(opt is CompatTool.ComboOption) + { + var val = ts_options.get_string_member(opt.name); + if(val == null || val in ((CompatTool.ComboOption) opt).options) + { + ((CompatTool.ComboOption) opt).value = val; + } + } + else if(opt is CompatTool.StringOption) + { + ((CompatTool.StringOption) opt).value = ts_options.get_string_member(opt.name); + } + } + else + { + switch(opt.name) + { + case Compat.Wine.OPT_PREFIX: + var prefix = (compat_tool_picker.selected as Compat.Wine).get_default_wineprefix(runnable); + if(compat_tool_picker.selected is Compat.Proton) + { + prefix = prefix.get_parent(); + } + ((CompatTool.FileOption) opt).file = prefix; + break; + } + } + add(new OptionRow(opt)); + } + + show_all(); + } + + public void save_options() + { + runnable.compat_options_saved = true; + + if(compat_tool_picker == null || compat_tool_picker.selected == null) return; + var options = install ? compat_tool_picker.selected.install_options : compat_tool_picker.selected.options; + if(options == null) return; + + var tool_settings = runnable.get_compat_settings(compat_tool_picker.selected); + var ts_options = tool_settings.has_member(settings_key) ? tool_settings.get_object_member(settings_key) : new Json.Object(); + + foreach(var opt in options) + { + if(opt is CompatTool.BoolOption) + { + ts_options.set_boolean_member(opt.name, ((CompatTool.BoolOption) opt).enabled); + } + else if(opt is CompatTool.FileOption) + { + var file = ((CompatTool.FileOption) opt).file; + if(file != null && file.query_exists()) + { + ts_options.set_string_member(opt.name, file.get_path()); + } + else + { + ts_options.remove_member(opt.name); + } + } + else if(opt is CompatTool.ComboOption) + { + var val = ((CompatTool.ComboOption) opt).value; + if(val != null && val in ((CompatTool.ComboOption) opt).options) + { + ts_options.set_string_member(opt.name, val); + } + else + { + ts_options.remove_member(opt.name); + } + } + else if(opt is CompatTool.StringOption) + { + var val = ((CompatTool.StringOption) opt).value; + if(val != null) + { + ts_options.set_string_member(opt.name, val); + } + else + { + ts_options.remove_member(opt.name); + } + } + } + tool_settings.set_object_member(settings_key, ts_options); + runnable.set_compat_settings(compat_tool_picker.selected, tool_settings); + } + + public class OptionRow: ListBoxRow + { + public CompatTool.Option option { get; construct; } + + public OptionRow(CompatTool.Option option) + { + Object(option: option); + } + + construct + { + var ebox = new EventBox(); + ebox.above_child = true; + + var box = new Box(Orientation.HORIZONTAL, 6); + box.margin_start = box.margin_end = 8; + box.margin_top = box.margin_bottom = 6; + + var name = new Label(option.description); + name.halign = Align.START; + name.xalign = 0; + name.hexpand = true; + + ebox.tooltip_text = option.name; + + Widget? option_widget = null; + + if(option is CompatTool.BoolOption) + { + var bool_option = (CompatTool.BoolOption) option; + + var check = new CheckButton(); + check.margin_end = 2; + check.active = bool_option.enabled; + box.add(check); + + ebox.add_events(EventMask.ALL_EVENTS_MASK); + ebox.button_release_event.connect(e => { + if(e.button == 1) + { + check.active = !check.active; + bool_option.enabled = check.active; + } + return true; + }); + } + else if(option is CompatTool.FileOption) + { + var file_option = (CompatTool.FileOption) option; + + var icon = new Image.from_icon_name(file_option.icon ?? "document-open-symbolic", IconSize.MENU); + box.add(icon); + + ebox.above_child = false; + box.margin_top = box.margin_bottom = 2; + box.margin_end = 0; + + var entry = new FileChooserEntry(file_option.description, file_option.mode); + entry.set_size_request(220, -1); + + if(file_option.file != null || file_option.directory != null) + { + try + { + entry.select_file(file_option.file ?? file_option.directory); + } + catch(Error e) + { + warning(e.message); + } + } + entry.file_set.connect(() => { + file_option.file = entry.file; + }); + option_widget = entry; + } + else if(option is CompatTool.ComboOption) + { + var combo_option = (CompatTool.ComboOption) option; + + var icon = new Image.from_icon_name(combo_option.icon ?? "view-sort-descending-symbolic", IconSize.MENU); + box.add(icon); + + ebox.above_child = false; + box.margin_top = box.margin_bottom = 2; + box.margin_end = 0; + + var model = new Gtk.ListStore(1, typeof(string)); + Gtk.TreeIter iter; + + foreach(var opt in combo_option.options) + { + model.append(out iter); + model.set(iter, 0, opt); + } + + var combo = new ComboBox.with_model(model); + combo.set_size_request(220, -1); + + var renderer = new CellRendererText(); + combo.pack_start(renderer, true); + combo.add_attribute(renderer, "text", 0); + combo.changed.connect(() => { + Value v; + combo.get_active_iter(out iter); + model.get_value(iter, 0, out v); + combo_option.value = v as string; + }); + combo.active = combo_option.value in combo_option.options ? combo_option.options.index_of(combo_option.value) : 0; + option_widget = combo; + } + else if(option is CompatTool.StringOption) + { + var string_option = (CompatTool.StringOption) option; + + var icon = new Image.from_icon_name(string_option.icon ?? "insert-text-symbolic", IconSize.MENU); + box.add(icon); + + ebox.above_child = false; + box.margin_top = box.margin_bottom = 2; + box.margin_end = 0; + + var entry = new Entry(); + entry.set_size_request(220, -1); + if(string_option.value != null) + { + entry.text = string_option.value; + } + entry.notify["text"].connect(() => { string_option.value = entry.text; }); + option_widget = entry; + } + + box.add(name); + + if(option_widget != null) box.add(option_widget); + + ebox.add(box); + + child = ebox; + } + } + } +} diff --git a/src/ui/widgets/CompatToolPicker.vala b/src/ui/widgets/CompatToolPicker.vala new file mode 100644 index 00000000..93fe46a4 --- /dev/null +++ b/src/ui/widgets/CompatToolPicker.vala @@ -0,0 +1,210 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; + + +using GameHub.Data; +using GameHub.Data.DB; + +namespace GameHub.UI.Widgets +{ + public class CompatToolPicker: Box + { + public CompatTool? selected { get; private set; default = null; } + + public Runnable runnable { get; construct; } + public bool install_mode { get; construct; } + public bool show_compat_config { get; construct; } + + private Gtk.ListStore model; + private int model_size = 0; + private Gtk.TreeIter iter; + private ComboBox combo; + + private Box actions; + private Box warnings; + + public CompatToolPicker(Runnable runnable, bool install_mode, bool show_compat_config=false) + { + Object(orientation: Orientation.VERTICAL, spacing: 4, runnable: runnable, install_mode: install_mode, show_compat_config: show_compat_config); + } + + construct + { + margin_bottom = 4; + + var label = new Label(_("Compatibility layer:")); + label.hexpand = true; + label.xalign = 0; + label.margin_start = label.margin_end = 4; + + model = new Gtk.ListStore(3, typeof(string), typeof(string), typeof(CompatTool)); + + foreach(var tool in CompatTools) + { + if(tool.installed && ((install_mode && tool.can_install(runnable)) || (!install_mode && tool.can_run(runnable)))) + { + model.append(out iter); + model.set(iter, 0, tool.icon); + model.set(iter, 1, tool.name); + model.set(iter, 2, tool); + model_size++; + } + } + + combo = new ComboBox.with_model(model); + combo.halign = Align.END; + + CellRendererPixbuf r_icon = new CellRendererPixbuf(); + combo.pack_start(r_icon, false); + combo.add_attribute(r_icon, "icon-name", 0); + + CellRendererText r_name = new CellRendererText(); + r_name.xpad = 8; + combo.pack_start(r_name, true); + combo.add_attribute(r_name, "text", 1); + + var tool_box = new Box(Orientation.HORIZONTAL, 8); + + var combo_wrapper = new Box(Orientation.HORIZONTAL, 0); + combo_wrapper.get_style_context().add_class(Gtk.STYLE_CLASS_LINKED); + + combo_wrapper.add(combo); + + var compat_config = new Button.from_icon_name("open-menu-symbolic"); + compat_config.tooltip_text = _("Configure"); + compat_config.sensitive = false; + compat_config.clicked.connect(() => { + runnable.run_with_compat.begin(true); + }); + if(show_compat_config) + { + combo_wrapper.add(compat_config); + } + + tool_box.add(label); + tool_box.add(combo_wrapper); + + warnings = new Box(Orientation.VERTICAL, 0); + + actions = new Box(Orientation.HORIZONTAL, 0); + actions.get_style_context().add_class(Gtk.STYLE_CLASS_LINKED); + + combo.changed.connect(() => { + if(model_size == 0) return; + + Value v; + combo.get_active_iter(out iter); + model.get_value(iter, 2, out v); + selected = v as CompatTool; + + compat_config.sensitive = false; + + if(selected == null) return; + + combo.tooltip_text = selected.executable != null ? selected.executable.get_path() : null; + + if(selected.can_run(runnable)) + { + runnable.compat_tool = selected.id; + runnable.save(); + runnable.update_status(); + } + + actions.foreach(w => w.destroy()); + actions.hide(); + + if(selected.actions != null) + { + foreach(var action in selected.actions) + { + add_action(action); + } + actions.show_all(); + } + + compat_config.sensitive = selected.options != null && selected.options.length > 0; + + warnings.foreach(w => w.destroy()); + warnings.hide(); + + if(selected.warnings != null && selected.warnings.length > 0) + { + foreach(var warning in selected.warnings) + { + add_warning(warning); + } + warnings.show_all(); + } + }); + + int index = 0; + if(runnable.compat_tool != null && runnable.compat_tool.length > 0) + { + model.foreach((m, p, i) => { + if(model_size == 0) return false; + + Value v; + m.get_value(i, 2, out v); + var tool = v as CompatTool; + if(runnable.compat_tool == tool.id) + { + return true; + } + index++; + return false; + }); + } + if(model_size > 0) + { + combo.active = index < model_size ? index : 0; + } + + add(tool_box); + add(warnings); + add(actions); + + show_all(); + } + + private void add_action(CompatTool.Action action) + { + var btn = new Button.with_label(action.name); + btn.tooltip_text = action.description; + btn.hexpand = true; + btn.clicked.connect(() => action.invoke(runnable)); + actions.add(btn); + } + + private void add_warning(string warning) + { + var infobar = new InfoBar(); + infobar.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME); + infobar.get_style_context().add_class("compat-tool-warning"); + infobar.message_type = MessageType.WARNING; + var label = new Label(warning); + label.use_markup = true; + label.wrap = true; + label.xalign = 0; + infobar.get_content_area().add(label); + warnings.add(infobar); + } + } +} diff --git a/src/ui/widgets/ExtendedStackSwitcher.vala b/src/ui/widgets/ExtendedStackSwitcher.vala new file mode 100644 index 00000000..d24347a4 --- /dev/null +++ b/src/ui/widgets/ExtendedStackSwitcher.vala @@ -0,0 +1,90 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gee; + + +namespace GameHub.UI.Widgets +{ + public class ExtendedStackSwitcher: ModeButton + { + public Stack stack { get; construct; } + + private ArrayList tab_names = new ArrayList(); + + public ExtendedStackSwitcher(Stack stack) + { + Object(stack: stack, homogeneous: false); + + stack.notify["visible-child-name"].connect(() => { + set_active(tab_names.index_of(stack.visible_child_name)); + }); + + notify["selected"].connect(() => { + if(selected > -1 && selected < tab_names.size) + { + stack.visible_child_name = tab_names[selected]; + } + }); + } + + public void add_tab(Widget tab, string name, string? text=null, bool text_markup=true, string? icon=null, string? tooltip=null, bool tooltip_markup=true) + { + stack.add_named(tab, name); + tab_names.add(name); + + var tab_hbox = new Box(Orientation.HORIZONTAL, 2); + + if(icon != null) + { + tab_hbox.add(new Image.from_icon_name(icon, IconSize.LARGE_TOOLBAR)); + } + + if(text != null) + { + var label = new Label(text); + label.use_markup = text_markup; + tab_hbox.add(label); + } + + if(tooltip != null) + { + if(tooltip_markup) + { + tab_hbox.tooltip_markup = tooltip; + } + else + { + tab_hbox.tooltip_text = tooltip; + } + } + + tab_hbox.show_all(); + append(tab_hbox); + } + + public void clear() + { + set_active(-1); + tab_names.clear(); + clear_children(); + stack.foreach(t => t.destroy()); + } + } +} diff --git a/src/ui/widgets/FileChooserEntry.vala b/src/ui/widgets/FileChooserEntry.vala new file mode 100644 index 00000000..e689c7ab --- /dev/null +++ b/src/ui/widgets/FileChooserEntry.vala @@ -0,0 +1,204 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; + +using GameHub.Utils; + +namespace GameHub.UI.Widgets +{ + public class FileChooserEntry: Entry + { + public signal void file_set(); + public signal void uri_set(); + + public File? file { get; protected set; } + public string? uri { get; protected set; } + + public string? title { get; construct; } + public FileChooserAction action { get; construct; } + public bool allow_url { get; construct; } + public bool allow_executable { get; construct; } + + public FileChooser chooser { get; protected set; } + + public FileChooserEntry(string? title, FileChooserAction action, string? icon=null, string? hint=null, bool allow_url=false, bool allow_executable=false) + { + Object(title: title, action: action, allow_url: allow_url, allow_executable: allow_executable); + placeholder_text = primary_icon_tooltip_text = hint; + primary_icon_name = icon ?? (directory_mode ? "folder" : "application-x-executable"); + primary_icon_activatable = false; + secondary_icon_name = "folder-symbolic"; + secondary_icon_activatable = true; + secondary_icon_tooltip_text = directory_mode ? _("Select directory") : _("Select file"); + } + + construct + { + #if GTK_3_22 + chooser = new FileChooserNative(title ?? _("Select file"), GameHub.UI.Windows.MainWindow.instance, action, _("Select"), _("Cancel")); + #else + chooser = new FileChooserDialog(title ?? _("Select file"), GameHub.UI.Windows.MainWindow.instance, action, _("Select"), ResponseType.ACCEPT, _("Cancel"), ResponseType.CANCEL); + #endif + + activate.connect(() => { + select_file_path(text); + }); + focus_out_event.connect(() => { + select_file_path(text); + return false; + }); + + icon_press.connect((icon, event) => { + if(icon == EntryIconPosition.SECONDARY && ((EventButton) event).button == 1) + { + if(run_chooser() == ResponseType.ACCEPT) + { + select_file(chooser.get_file()); + } + } + }); + } + + public void select_file_path(string? path_or_uri) + { + if(path_or_uri == null || path_or_uri.strip().length == 0) + { + text = ""; + chooser.unselect_all(); + file = null; + uri = null; + file_set(); + uri_set(); + return; + } + + var path = path_or_uri.strip(); + + if(allow_url && (path.has_prefix("file://") || path.has_prefix("https://") || path.has_prefix("http://") || path.has_prefix("ftp://"))) + { + uri = path; + if(text.has_prefix("file://")) + { + file = File.new_for_uri(uri); + } + } + else if(path.has_prefix("/") || path.has_prefix("~")) + { + file = FSUtils.file(path); + uri = file.get_uri(); + } + else if(allow_executable && path.length > 0) + { + var executable = Utils.find_executable(path); + if(executable != null && executable.query_exists()) + { + file = executable; + } + else + { + file = FSUtils.file("/usr/bin", text); + } + uri = file.get_uri(); + } + + text = ""; + + if(file != null) + { + if(file.query_exists()) + { + try + { + chooser.select_file(file); + } + catch(Error e) + { + warning("[FileChooserEntry.select_file_path] %s", e.message); + } + } + else + { + chooser.unselect_all(); + } + text = file.get_path(); + } + + if(allow_url) + { + text = uri ?? ""; + } + + scroll_to_end(); + + file_set(); + uri_set(); + } + + public void select_file(File? f) + { + select_file_path(f != null ? f.get_path() : null); + } + + public void set_default_directory(File? directory) + { + if(directory != null && directory.query_exists()) + { + try + { + chooser.set_current_folder_file(directory); + } + catch(Error e) + { + warning("[FileChooserEntry.set_default_directory] %s", e.message); + } + } + } + + public void reset() + { + select_file_path(null); + } + + private int run_chooser() + { + #if GTK_3_22 + return (chooser as FileChooserNative).run(); + #else + return (chooser as FileChooserDialog).run(); + #endif + } + + private void scroll_to_end() + { + if(cursor_position < text.length) + { + move_cursor(MovementStep.BUFFER_ENDS, 1, false); + } + } + + private bool directory_mode + { + get + { + return action == FileChooserAction.SELECT_FOLDER || action == FileChooserAction.CREATE_FOLDER; + } + } + } +} diff --git a/src/ui/widgets/GameTagsList.vala b/src/ui/widgets/GameTagsList.vala new file mode 100644 index 00000000..8ba2ccf2 --- /dev/null +++ b/src/ui/widgets/GameTagsList.vala @@ -0,0 +1,156 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; +using Gee; + +using GameHub.Data; +using GameHub.Data.DB; + +namespace GameHub.UI.Widgets +{ + public class GameTagsList: Box + { + private ArrayList _games; + public ArrayList games + { + get { return _games; } + set + { + _games = value; + update(); + } + } + + private ListBox list; + private ScrolledWindow scrolled; + private Entry new_entry; + + public GameTagsList(Game? game=null, ArrayList? games=null) + { + Object(orientation: Orientation.VERTICAL, spacing: 0); + _games = games ?? new ArrayList(); + if(game != null && !(game in _games)) + { + _games.add(game); + } + update(); + } + + construct + { + var header = Styled.H4Label(_("Tags")); + header.xpad = 8; + add(header); + + list = new ListBox(); + list.get_style_context().add_class("tags-list"); + list.selection_mode = SelectionMode.NONE; + + list.set_sort_func((row1, row2) => { + var item1 = row1 as TagRow; + var item2 = row2 as TagRow; + + if(row1 != null && row2 != null) + { + var tag1 = item1.tag; + var tag2 = item2.tag; + + if(tag1 == null || tag2 == null) return 0; + + var t1 = tag1.id; + var t2 = tag2.id; + + var b1 = t1.has_prefix(Tables.Tags.Tag.BUILTIN_PREFIX); + var b2 = t2.has_prefix(Tables.Tags.Tag.BUILTIN_PREFIX); + if(b1 && !b2) return -1; + if(!b1 && b2) return 1; + + var u1 = t1.has_prefix(Tables.Tags.Tag.USER_PREFIX); + var u2 = t2.has_prefix(Tables.Tags.Tag.USER_PREFIX); + if(u1 && !u2) return -1; + if(!u1 && u2) return 1; + + if(tag1.name == null || tag1.name.length == 0 || tag2.name == null || tag2.name.length == 0) return 0; + return tag1.name.collate(tag2.name); + } + + return 0; + }); + + scrolled = new ScrolledWindow(null, null); + scrolled.vexpand = true; + #if GTK_3_22 + scrolled.propagate_natural_width = true; + scrolled.propagate_natural_height = true; + scrolled.max_content_height = 320; + #endif + scrolled.add(list); + + add(scrolled); + + new_entry = new Entry(); + new_entry.placeholder_text = _("Add tag"); + new_entry.primary_icon_name = "gh-tag-add-symbolic"; + new_entry.primary_icon_activatable = false; + new_entry.secondary_icon_name = "list-add-symbolic"; + new_entry.secondary_icon_activatable = true; + new_entry.margin = 4; + + new_entry.icon_press.connect((icon, event) => { + if(icon == EntryIconPosition.SECONDARY && ((EventButton) event).button == 1) + { + add_tag(); + } + }); + new_entry.activate.connect(add_tag); + + add(new_entry); + + Tables.Tags.instance.tags_updated.connect(update); + + show_all(); + } + + private void update() + { + list.foreach(w => w.destroy()); + foreach(var tag in Tables.Tags.TAGS) + { + if(tag in Tables.Tags.DYNAMIC_TAGS || !tag.enabled) continue; + list.add(new TagRow(tag, games)); + } + list.show_all(); + } + + private void add_tag() + { + var name = new_entry.text.strip(); + if(name.length == 0) return; + new_entry.text = ""; + var tag = new Tables.Tags.Tag.from_name(name); + Tables.Tags.add(tag); + foreach(var game in games) + { + game.add_tag(tag); + } + update(); + } + } +} diff --git a/src/ui/widgets/ImagesDownloadPopover.vala b/src/ui/widgets/ImagesDownloadPopover.vala new file mode 100644 index 00000000..08a4bb09 --- /dev/null +++ b/src/ui/widgets/ImagesDownloadPopover.vala @@ -0,0 +1,267 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; + + +using GameHub.Data; +using GameHub.Data.Providers; + +namespace GameHub.UI.Widgets +{ + class ImagesDownloadPopover: Popover + { + public Game game { get; construct; } + + private Box vbox; + private Box search_links; + + private Stack stack; + private Spinner spinner; + private AlertView no_images_alert; + private ScrolledWindow images_scroll; + private Box images; + + private bool images_load_started = false; + + public ImagesDownloadPopover(Game game, MenuButton button, int r_width=520, int r_height=400) + { + Object(game: game, relative_to: button); + button.popover = this; + position = PositionType.LEFT; + + images_scroll.set_size_request(int.max(r_width, 520), int.max(r_height, 400)); + + button.clicked.connect(load_images); + + game.notify["name"].connect(() => { + images.foreach(i => i.destroy()); + images_load_started = false; + stack.visible_child = spinner; + }); + } + + construct + { + vbox = new Box(Orientation.VERTICAL, 0); + + stack = new Stack(); + stack.transition_type = StackTransitionType.CROSSFADE; + stack.interpolate_size = true; + stack.no_show_all = true; + + spinner = new Spinner(); + spinner.halign = spinner.valign = Align.CENTER; + spinner.set_size_request(32, 32); + spinner.margin = 16; + spinner.start(); + + no_images_alert = new AlertView(_("No images"), _("There are no images found for this game\nMake sure game name is correct"), "dialog-information"); + no_images_alert.get_style_context().remove_class(Gtk.STYLE_CLASS_VIEW); + + images_scroll = new ScrolledWindow(null, null); + + images = new Box(Orientation.VERTICAL, 0); + images.margin = 4; + + images_scroll.add(images); + + stack.add(spinner); + stack.add(no_images_alert); + stack.add(images_scroll); + + spinner.show(); + stack.visible_child = spinner; + + search_links = new Box(Orientation.HORIZONTAL, 8); + search_links.margin = 8; + + var search_links_label = new Label(_("Search images:")); + search_links_label.halign = Align.START; + search_links_label.xalign = 0; + search_links_label.hexpand = true; + search_links.add(search_links_label); + + add_search_link("SteamGridDB", "https://steamgriddb.com/game/%s"); + add_search_link("Jinx's SGVI", "https://steam.cryotank.net/?s=%s"); + add_search_link("Google", "https://google.com/search?tbm=isch&tbs=isz:ex,iszw:460,iszh:215&q=%s"); + + vbox.add(stack); + vbox.add(new Separator(Orientation.HORIZONTAL)); + vbox.add(search_links); + + child = vbox; + + vbox.show_all(); + stack.show(); + } + + private void load_images() + { + if(images_load_started) return; + images_load_started = true; + + load_images_async.begin(); + } + + private async void load_images_async() + { + foreach(var src in ImageProviders) + { + if(!src.enabled) continue; + + var results = yield src.images(game); + if(results == null || results.size < 1) continue; + foreach(var result in results) + { + if(result != null && result.images != null && result.images.size > 0) + { + if(images.get_children().length() > 0) + { + var separator = new Separator(Orientation.HORIZONTAL); + separator.margin = 4; + separator.margin_bottom = 0; + images.add(separator); + } + + var header_hbox = new Box(Orientation.HORIZONTAL, 8); + header_hbox.margin_start = header_hbox.margin_end = 4; + + var header = Styled.H4Label(result.name); + header.hexpand = true; + + header_hbox.add(header); + + if(result.url != null) + { + var link = new Button.from_icon_name("web-browser-symbolic"); + link.get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + link.tooltip_text = result.url; + link.clicked.connect(() => { + Utils.open_uri(result.url); + }); + header_hbox.add(link); + } + + images.add(header_hbox); + + var flow = new FlowBox(); + flow.activate_on_single_click = true; + flow.homogeneous = true; + flow.min_children_per_line = 1; + flow.selection_mode = SelectionMode.SINGLE; + + flow.child_activated.connect(i => { + var item = (ImageItem) i; + + if(item.size.width >= item.size.height) + { + game.image = item.image.url; + } + else + { + game.image_vertical = item.image.url; + } + game.save(); + + #if GTK_3_22 + popdown(); + #else + hide(); + #endif + }); + + foreach(var img in result.images) + { + var item = new ImageItem(img, result.image_size, src, game); + flow.add(item); + if(img.url == game.image) + { + flow.select_child(item); + item.grab_focus(); + } + } + + images.add(flow); + } + } + } + + if(images.get_children().length() > 0) + { + images_scroll.show_all(); + stack.visible_child = images_scroll; + } + else + { + no_images_alert.show_all(); + stack.visible_child = no_images_alert; + } + } + + private void add_search_link(string text, string url) + { + var link = new LinkButton.with_label(url.printf(Uri.escape_string(game.name)), text); + link.halign = Align.START; + link.margin = 0; + search_links.add(link); + } + + private class ImageItem: FlowBoxChild + { + public ImagesProvider.Image image { get; construct; } + public ImagesProvider.ImageSize size { get; construct; } + + public ImagesProvider provider { get; construct; } + public Game game { get; construct; } + + public ImageItem(ImagesProvider.Image image, ImagesProvider.ImageSize size, ImagesProvider provider, Game game) + { + Object(image: image, size: size, provider: provider, game: game); + } + + construct + { + margin = 0; + + var card = Styled.Card("gamecard", "static"); + card.sensitive = false; + card.margin = 4; + + card.tooltip_markup = image.description; + + var img = new AutoSizeImage(); + img.load(image.url, null, @"games/$(game.source.id)/$(game.id)/images/providers/$(provider.id)/"); + + card.add(img); + + child = card; + + var ratio = (float) size.height / size.width; + + var w_1x = size.width > 500 ? size.width / 2 : size.width; + + var min = int.max((int) (w_1x / 2f), 100); + var max = int.min(w_1x, 460); + img.set_constraint(min, max, ratio); + + show_all(); + } + } + } +} diff --git a/src/ui/widgets/ModeButton.vala b/src/ui/widgets/ModeButton.vala new file mode 100644 index 00000000..d8668a6c --- /dev/null +++ b/src/ui/widgets/ModeButton.vala @@ -0,0 +1,246 @@ +/* +This file is part of GameHub. +Copyright(C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +/* Based on Granite.Widgets.ModeButton */ + +using Gtk; +using Gee; + +namespace GameHub.UI.Widgets +{ + public class ModeButton: Box + { + private class Item: ToggleButton + { + public int index { get; construct; } + public Item(int index) + { + Object(index: index); + can_focus = false; + add_events(Gdk.EventMask.SCROLL_MASK); + } + } + + public signal void mode_added(int index, Widget widget); + public signal void mode_removed(int index, Widget widget); + public signal void mode_changed(Widget widget); + + public int selected + { + get { return _selected; } + set { set_active(value); } + } + + public uint n_items { get { return item_map.size; } } + + private int _selected = -1; + private HashMap item_map; + + public ModeButton(){} + + construct + { + homogeneous = true; + spacing = 0; + can_focus = false; + item_map = new HashMap(); + StyleClass.add(this, Gtk.STYLE_CLASS_LINKED, "raised"); + } + + public int append_pixbuf(Gdk.Pixbuf pixbuf, string? tooltip=null, bool tooltip_markup=false) + { + return append(new Image.from_pixbuf(pixbuf), tooltip, tooltip_markup); + } + + public int append_text(string text, string? tooltip=null, bool tooltip_markup=false) + { + return append(new Label(text), tooltip, tooltip_markup); + } + + public int append_icon(string icon_name, IconSize size, string? tooltip=null, bool tooltip_markup=false) + { + return append(new Image.from_icon_name(icon_name, size), tooltip, tooltip_markup); + } + + public int append(Widget w, string? tooltip=null, bool tooltip_markup=false) + { + int index; + for(index = item_map.size; item_map.has_key(index); index++); + assert(item_map[index] == null); + + var item = new Item(index); + item.scroll_event.connect(on_scroll_event); + item.add(w); + + item.toggled.connect(() => { + if(item.active) + { + selected = item.index; + } + else if(selected == item.index) + { + item.active = true; + } + }); + + item_map[index] = item; + + add(item); + item.show_all(); + + mode_added(index, w); + + if(tooltip != null) + { + if(tooltip_markup) + w.tooltip_markup = tooltip; + else + w.tooltip_text = tooltip; + } + + return index; + } + + private void clear_selected() + { + _selected = -1; + foreach(var item in item_map.values) + { + if(item != null && item.active) + { + item.set_active(false); + } + } + } + + public void set_active(int new_active_index) + { + if(new_active_index <= -1) + { + clear_selected(); + return; + } + + return_if_fail(item_map.has_key(new_active_index)); + var new_item = item_map[new_active_index] as Item; + + if(new_item != null) + { + assert(new_item.index == new_active_index); + new_item.set_active(true); + + if(_selected == new_active_index) return; + + var old_item = item_map[_selected] as Item; + + _selected = new_active_index; + + if(old_item != null) + { + old_item.set_active(false); + } + + mode_changed(new_item.get_child()); + } + } + + public void set_item_visible(int index, bool val) + { + return_if_fail(item_map.has_key(index)); + var item = item_map[index] as Item; + + if(item != null) + { + assert(item.index == index); + item.no_show_all = !val; + item.visible = val; + } + } + + public new void remove(int index) + { + return_if_fail(item_map.has_key(index)); + var item = item_map[index] as Item; + + if(item != null) + { + assert(item.index == index); + item_map.unset(index); + mode_removed(index, item.get_child()); + item.destroy(); + } + } + + public void clear_children() + { + foreach(weak Widget button in get_children()) + { + button.hide(); + if(button.get_parent() != null) + { + base.remove(button); + } + } + + item_map.clear(); + _selected = -1; + } + + private bool on_scroll_event(Widget widget, Gdk.EventScroll ev) + { + int offset; + switch(ev.direction) + { + case Gdk.ScrollDirection.DOWN: + case Gdk.ScrollDirection.RIGHT: + offset = 1; + break; + case Gdk.ScrollDirection.UP: + case Gdk.ScrollDirection.LEFT: + offset = -1; + break; + default: + return false; + } + + var children = get_children(); + uint n_children = children.length(); + + var selected_item = item_map[selected]; + if(selected_item == null) return false; + + int new_item = children.index(selected_item); + if(new_item < 0) return false; + + do + { + new_item += offset; + var item = children.nth_data(new_item) as Item; + + if(item != null && item.visible && item.sensitive) + { + selected = item.index; + break; + } + } + while(new_item >= 0 && new_item < n_children); + + return false; + } + } +} diff --git a/src/ui/widgets/OverlayBar.vala b/src/ui/widgets/OverlayBar.vala new file mode 100644 index 00000000..75a72fbb --- /dev/null +++ b/src/ui/widgets/OverlayBar.vala @@ -0,0 +1,126 @@ +/* +This file is part of GameHub. +Copyright(C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +/* Based on Granite.Widgets.OverlayBar */ + +using Gtk; + +namespace GameHub.UI.Widgets +{ + public class OverlayBar: EventBox + { + private Label status_label; + private Revealer revealer; + private Spinner spinner; + + public string label + { + get + { + return status_label.label; + } + set + { + status_label.label = value; + } + } + + public bool active + { + get + { + return spinner.active; + } + set + { + spinner.active = value; + revealer.reveal_child = value; + } + } + + public OverlayBar(Overlay? overlay=null) + { + if(overlay != null) + { + overlay.add_events(Gdk.EventMask.ENTER_NOTIFY_MASK); + overlay.add_overlay(this); + } + } + + construct + { + status_label = new Label(""); + status_label.set_ellipsize(Pango.EllipsizeMode.END); + + spinner = new Spinner(); + + revealer = new Revealer(); + revealer.reveal_child = false; + revealer.transition_type = RevealerTransitionType.SLIDE_LEFT; + revealer.add(spinner); + + var grid = new Grid(); + StyleClass.add(grid, "overlay-bar"); + grid.add(status_label); + grid.add(revealer); + + add(grid); + + set_halign(Align.END); + set_valign(Align.END); + + var ctx = grid.get_style_context(); + var state = ctx.get_state(); + + var padding = ctx.get_padding(state); + status_label.margin_top = padding.top; + status_label.margin_bottom = padding.bottom; + status_label.margin_start = padding.left; + status_label.margin_end = padding.right; + spinner.margin_end = padding.right; + + var margin = ctx.get_margin(state); + grid.margin_top = margin.top; + grid.margin_bottom = margin.bottom; + grid.margin_start = margin.left; + grid.margin_end = margin.right; + } + + public override void parent_set(Widget? old_parent) + { + Widget parent = get_parent(); + + if(old_parent != null) + old_parent.enter_notify_event.disconnect(enter_notify_callback); + if(parent != null) + parent.enter_notify_event.connect(enter_notify_callback); + } + + private bool enter_notify_callback(Gdk.EventCrossing event) + { + if(get_halign() == Align.START) + set_halign(Align.END); + else + set_halign(Align.START); + + queue_resize(); + + return false; + } + } +} diff --git a/src/ui/widgets/SettingsSidebar.vala b/src/ui/widgets/SettingsSidebar.vala new file mode 100644 index 00000000..7e2a187a --- /dev/null +++ b/src/ui/widgets/SettingsSidebar.vala @@ -0,0 +1,412 @@ +/* +This file is part of GameHub. +Copyright(C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +/* Based on Granite.SettingsSidebar */ + +using Gtk; + +namespace GameHub.UI.Widgets +{ + public class SettingsSidebar: ScrolledWindow + { + private ListBox listbox; + public Stack stack { get; construct; } + + public string? visible_child_name + { + get + { + var selected_row = listbox.get_selected_row(); + if(selected_row == null) + { + return null; + } + else + { + return ((Row) selected_row).name; + } + } + set + { + foreach(unowned Widget listbox_child in listbox.get_children()) + { + if(((Row) listbox_child).name == value) + { + listbox.select_row((ListBoxRow) listbox_child); + } + } + } + } + + public SettingsSidebar(Stack stack) + { + Object(stack: stack); + } + + construct + { + hscrollbar_policy = PolicyType.NEVER; + width_request = 200; + listbox = new ListBox(); + listbox.activate_on_single_click = true; + listbox.selection_mode = SelectionMode.SINGLE; + + add(listbox); + + on_sidebar_changed(); + stack.add.connect(on_sidebar_changed); + stack.remove.connect(on_sidebar_changed); + + listbox.row_selected.connect((row) => { + stack.visible_child = ((Row) row).page; + }); + + listbox.set_header_func((row, before) => { + var header = ((Row) row).header; + if(header != null) + { + row.set_header(Styled.H4Label(header)); + } + }); + } + + private void on_sidebar_changed() + { + listbox.get_children().foreach((listbox_child) => { + listbox_child.destroy(); + }); + + stack.get_children().foreach((child) => { + if(child is SettingsSidebar.SettingsPage) + { + var row = new Row((SettingsPage) child); + listbox.add(row); + } + }); + + listbox.show_all(); + } + + public abstract class SettingsPage: ScrolledWindow + { + protected string _icon_name; + protected string _title; + + public enum StatusType { ERROR, WARNING, NONE } + + public StatusType status_type { get; set; default = StatusType.NONE; } + public Widget? display_widget { get; construct; } + public string? header { get; construct; } + public string status { get; set; } + + public string? icon_name + { + get + { + return _icon_name; + } + construct set + { + _icon_name = value; + } + } + + public string title + { + get + { + return _title; + } + construct set + { + _title = value; + } + } + } + + public abstract class SimpleSettingsPage: SettingsPage + { + private Image header_icon; + private Label description_label; + private Label title_label; + private string _description; + + public ButtonBox action_area { get; construct; } + public Grid content_area { get; construct; } + public Switch? status_switch { get; construct; } + public bool activatable { get; construct; } + + public string description + { + get + { + return _description; + } + construct set + { + if(description_label != null) + { + description_label.label = value; + } + _description = value; + } + } + + public new string icon_name + { + get + { + return _icon_name; + } + construct set + { + if(header_icon != null) + { + header_icon.icon_name = value; + } + _icon_name = value; + } + } + + construct + { + header_icon = new Image.from_icon_name(icon_name, IconSize.DIALOG); + header_icon.pixel_size = 48; + header_icon.valign = Align.START; + + title_label = Styled.H2Label(title); + title_label.ellipsize = Pango.EllipsizeMode.END; + title_label.xalign = 0; + + var header_area = new Grid(); + header_area.column_spacing = 12; + header_area.row_spacing = 3; + + header_area.attach(title_label, 1, 0); + + if(description != null) + { + description_label = new Label(description); + description_label.xalign = 0; + description_label.wrap = true; + + header_area.attach(header_icon, 0, 0, 1, 2); + header_area.attach(description_label, 1, 1); + } + else + { + header_area.attach(header_icon, 0, 0); + } + + if(activatable) + { + status_switch = new Switch(); + status_switch.hexpand = true; + status_switch.halign = Align.END; + status_switch.valign = Align.CENTER; + header_area.attach(status_switch, 2, 0); + } + + content_area = new Grid(); + content_area.column_spacing = 12; + content_area.row_spacing = 12; + content_area.vexpand = true; + + action_area = new ButtonBox(Orientation.HORIZONTAL); + action_area.set_layout(ButtonBoxStyle.END); + action_area.spacing = 6; + + var grid = new Grid(); + grid.margin = 12; + grid.orientation = Orientation.VERTICAL; + grid.row_spacing = 24; + grid.add(header_area); + grid.add(content_area); + grid.add(action_area); + + add(grid); + + set_action_area_visibility(); + + action_area.add.connect(set_action_area_visibility); + action_area.remove.connect(set_action_area_visibility); + + notify["icon-name"].connect(() => { + if(header_icon != null) + { + header_icon.icon_name = icon_name; + } + }); + + notify["title"].connect(() => { + if(title_label != null) + { + title_label.label = title; + } + }); + } + + private void set_action_area_visibility() + { + if(action_area.get_children() != null) + { + action_area.no_show_all = false; + action_area.show(); + } + else + { + action_area.no_show_all = true; + action_area.hide(); + } + } + } + + private class Row: ListBoxRow + { + public SettingsPage.StatusType status_type + { + set + { + switch(value) + { + case SettingsPage.StatusType.ERROR: + status_icon.icon_name = "dialog-error-symbolic"; + break; + case SettingsPage.StatusType.WARNING: + status_icon.icon_name = "dialog-warning-symbolic"; + break; + } + } + } + + public Widget display_widget { get; construct; } + + public string? header { get; set; } + + public unowned SettingsPage page { get; construct; } + + public string icon_name + { + get + { + return _icon_name; + } + set + { + _icon_name = value; + if(display_widget is Image) + { + ((Image) display_widget).icon_name = value; + ((Image) display_widget).pixel_size = 32; + } + } + } + + public string status + { + set + { + status_label.label = "%s".printf(value); + status_label.no_show_all = false; + status_label.show(); + } + } + + public string title + { + get + { + return _title; + } + set + { + _title = value; + title_label.label = value; + } + } + + private Image status_icon; + private Label status_label; + private Label title_label; + private string _icon_name; + private string _title; + + public Row(SettingsPage page) + { + Object(page: page); + } + + construct + { + title_label = Styled.H3Label(page.title); + title_label.ellipsize = Pango.EllipsizeMode.END; + title_label.xalign = 0; + + status_icon = new Image(); + status_icon.halign = Align.END; + status_icon.valign = Align.END; + + status_label = new Label(null); + status_label.no_show_all = true; + status_label.use_markup = true; + status_label.ellipsize = Pango.EllipsizeMode.END; + status_label.xalign = 0; + + if(page.icon_name != null) + { + display_widget = new Image(); + icon_name = page.icon_name; + } + else + { + display_widget = page.display_widget; + } + + var overlay = new Overlay(); + overlay.width_request = 38; + overlay.add(display_widget); + overlay.add_overlay(status_icon); + + var grid = new Grid(); + grid.margin = 6; + grid.column_spacing = 6; + grid.attach(overlay, 0, 0, 1, 2); + grid.attach(title_label, 1, 0, 1, 1); + grid.attach(status_label, 1, 1, 1, 1); + + add(grid); + + header = page.header; + page.bind_property("icon-name", this, "icon-name", BindingFlags.DEFAULT); + page.bind_property("status", this, "status", BindingFlags.DEFAULT); + page.bind_property("status-type", this, "status-type", BindingFlags.DEFAULT); + page.bind_property("title", this, "title", BindingFlags.DEFAULT); + + if(page.status != null) + { + status = page.status; + } + + if(page.status_type != SettingsPage.StatusType.NONE) + { + status_type = page.status_type; + } + } + } + } +} diff --git a/src/ui/widgets/Styles.vala b/src/ui/widgets/Styles.vala new file mode 100644 index 00000000..244ad283 --- /dev/null +++ b/src/ui/widgets/Styles.vala @@ -0,0 +1,114 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; + +namespace GameHub.UI.Widgets +{ + namespace StyleClass + { + namespace Label + { + public const string H1 = "h1"; + public const string H2 = "h2"; + public const string H3 = "h3"; + public const string H4 = "h4"; + } + + public const string CARD = "card"; + public const string BACK_BUTTON = "back-button"; + + public void add(Widget widget, ...) + { + add_va(widget, va_list()); + } + + public void remove(Widget widget, ...) + { + remove_va(widget, va_list()); + } + + public void add_va(Widget widget, va_list classes) + { + var ctx = widget.get_style_context(); + for(string? class = classes.arg(); class != null; class = classes.arg()) + { + ctx.add_class(class); + } + } + + public void remove_va(Widget widget, va_list classes) + { + var ctx = widget.get_style_context(); + for(string? class = classes.arg(); class != null; class = classes.arg()) + { + ctx.remove_class(class); + } + } + } + + namespace Styled + { + private Label label(string? text, string main_class, va_list classes) + { + var label = new Gtk.Label(text); + StyleClass.add(label, main_class); + StyleClass.add_va(label, classes); + return label; + } + + public Label Label(string? text, string main_class, ...) + { + return label(text, main_class, va_list()); + } + + public Label H1Label(string? text, ...) + { + return label(text, StyleClass.Label.H1, va_list()); + } + public Label H2Label(string? text, ...) + { + return label(text, StyleClass.Label.H2, va_list()); + } + public Label H3Label(string? text, ...) + { + return label(text, StyleClass.Label.H3, va_list()); + } + public Label H4Label(string? text, ...) + { + var label = label(text, StyleClass.Label.H4, va_list()); + label.halign = Gtk.Align.START; + label.xalign = 0; + return label; + } + public Label DimLabel(string? text, ...) + { + return label(text, Gtk.STYLE_CLASS_DIM_LABEL, va_list()); + } + + public Frame Card(string main_class, ...) + { + var card = new Frame(null); + card.shadow_type = ShadowType.NONE; + StyleClass.add(card, StyleClass.CARD); + StyleClass.add(card, main_class); + StyleClass.add_va(card, va_list()); + return card; + } + } +} diff --git a/src/ui/widgets/TagRow.vala b/src/ui/widgets/TagRow.vala new file mode 100644 index 00000000..0359d601 --- /dev/null +++ b/src/ui/widgets/TagRow.vala @@ -0,0 +1,168 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; +using Gee; + + +using GameHub.Data; +using GameHub.Data.DB; + +namespace GameHub.UI.Widgets +{ + public class TagRow: ListBoxRow + { + public ArrayList? games; + public Tables.Tags.Tag tag; + public bool toggles_tag_for_games; + private CheckButton check; + + public TagRow(Tables.Tags.Tag tag, ArrayList? games=null) + { + this.games = games; + this.tag = tag; + this.toggles_tag_for_games = games != null; + + can_focus = true; + + var ebox = new EventBox(); + ebox.above_child = true; + + var box = new Box(Orientation.HORIZONTAL, 8); + box.margin_start = box.margin_end = 8; + box.margin_top = box.margin_bottom = 6; + + check = new CheckButton(); + check.can_focus = false; + + if(toggles_tag_for_games) + { + var have_tag = 0; + foreach(var game in games) + { + if(game.has_tag(tag)) have_tag++; + } + check.active = have_tag > 0; + check.inconsistent = have_tag != 0 && have_tag != games.size; + } + else + { + check.active = tag.selected; + tag.notify["selected"].connect(() => { + check.active = tag.selected; + }); + } + + var name = new Label(tag.name); + name.halign = Align.START; + name.xalign = 0; + name.hexpand = true; + + var icon = new Image.from_icon_name(tag.icon, IconSize.BUTTON); + + box.add(check); + box.add(name); + box.add(icon); + + ebox.add_events(EventMask.BUTTON_PRESS_MASK); + ebox.button_press_event.connect(e => { + switch(e.button) + { + case 1: + toggle(); + break; + + case 3: + show_context_menu(e, true); + break; + } + return true; + }); + + add_events(EventMask.KEY_RELEASE_MASK); + key_release_event.connect(e => { + switch(((EventKey) e).keyval) + { + case Key.Return: + case Key.space: + case Key.KP_Space: + toggle(); + return true; + } + return false; + }); + + ebox.add(box); + + child = ebox; + } + + private void toggle() + { + if(toggles_tag_for_games) + { + check.active = !check.active; + check.inconsistent = false; + + foreach(var game in games) + { + if(check.active && !game.has_tag(tag)) + { + game.add_tag(tag); + } + else if(!check.active && game.has_tag(tag)) + { + game.remove_tag(tag); + } + } + } + else + { + check.active = !check.active; + tag.selected = check.active; + } + } + + private void show_context_menu(Event e, bool at_pointer=true) + { + var menu = new Gtk.Menu(); + + var remove = new Gtk.MenuItem.with_label(_("Remove")); + remove.sensitive = tag.removable; + remove.activate.connect(() => tag.remove()); + + menu.add(remove); + + menu.show_all(); + + #if GTK_3_22 + if(at_pointer) + { + menu.popup_at_pointer(e); + } + else + { + menu.popup_at_widget(this, Gravity.SOUTH, Gravity.NORTH, e); + } + #else + menu.popup(null, null, null, 0, ((EventButton) e).time); + #endif + } + } +} diff --git a/src/ui/widgets/TweaksList.vala b/src/ui/widgets/TweaksList.vala new file mode 100644 index 00000000..80770767 --- /dev/null +++ b/src/ui/widgets/TweaksList.vala @@ -0,0 +1,145 @@ +/* +This file is part of GameHub. +Copyright (C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +using Gtk; +using Gdk; +using Gee; + +using GameHub.Data; +using GameHub.Data.Tweaks; + +namespace GameHub.UI.Widgets +{ + public class TweaksList: ListBox + { + public TweakableGame? game { get; construct; default = null; } + + public TweaksList(TweakableGame? game=null) + { + Object(game: game, selection_mode: SelectionMode.NONE); + } + + construct + { + update(); + } + + public void update(CompatTool? compat_tool=null) + { + this.foreach(w => w.destroy()); + + var tweaks = Tweak.load_tweaks(game == null); + + foreach(var tweak in tweaks.values) + { + if(game == null || tweak.is_applicable_to(game, compat_tool)) + { + add(new TweakRow(tweak, game)); + } + } + } + + private class TweakRow: ListBoxRow + { + public Tweak tweak { get; construct; } + public TweakableGame? game { get; construct; default = null; } + + public TweakRow(Tweak tweak, TweakableGame? game=null) + { + Object(tweak: tweak, game: game); + } + + construct + { + var grid = new Grid(); + grid.column_spacing = 12; + grid.margin_start = grid.margin_end = 8; + grid.margin_top = grid.margin_bottom = 4; + + var icon = new Image.from_icon_name(tweak.icon, IconSize.LARGE_TOOLBAR); + icon.valign = Align.CENTER; + + var name = new Label(tweak.name ?? tweak.id); + name.get_style_context().add_class("category-label"); + name.set_size_request(96, -1); + name.hexpand = true; + name.ellipsize = Pango.EllipsizeMode.END; + name.max_width_chars = 60; + name.xalign = 0; + name.valign = Align.CENTER; + + var description = new Label(tweak.description ?? _("No description")); + description.tooltip_text = tweak.description; + description.get_style_context().add_class(Gtk.STYLE_CLASS_DIM_LABEL); + description.hexpand = true; + description.ellipsize = Pango.EllipsizeMode.END; + description.max_width_chars = 60; + description.xalign = 0; + description.valign = Align.CENTER; + + var install = new Button.with_label(_("Install")); + install.valign = Align.CENTER; + install.sensitive = false; + + var enabled = new Switch(); + enabled.active = tweak.is_enabled(game); + enabled.valign = Align.CENTER; + + grid.attach(icon, 0, 0, 1, 2); + grid.attach(name, 1, 0); + grid.attach(description, 1, 1); + + if(tweak.url != null) + { + var url = new Button.from_icon_name("web-browser-symbolic", IconSize.SMALL_TOOLBAR); + url.tooltip_text = tweak.url; + url.valign = Align.CENTER; + url.get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + + url.clicked.connect(() => { + Utils.open_uri(tweak.url); + }); + + grid.attach(url, 2, 0, 1, 2); + } + + if(tweak.file != null && tweak.file.query_exists()) + { + var edit = new Button.from_icon_name("accessories-text-editor-symbolic", IconSize.SMALL_TOOLBAR); + edit.tooltip_text = _("Edit file"); + edit.valign = Align.CENTER; + edit.get_style_context().add_class(Gtk.STYLE_CLASS_FLAT); + + edit.clicked.connect(() => { + Utils.open_uri(tweak.file.get_uri()); + }); + + grid.attach(edit, 3, 0, 1, 2); + } + + grid.attach(enabled, 4, 0, 1, 2); + + enabled.notify["active"].connect(() => { + tweak.set_enabled(enabled.active, game); + }); + + child = grid; + } + } + } +} diff --git a/src/ui/widgets/Welcome.vala b/src/ui/widgets/Welcome.vala new file mode 100644 index 00000000..d6bc2f88 --- /dev/null +++ b/src/ui/widgets/Welcome.vala @@ -0,0 +1,224 @@ +/* +This file is part of GameHub. +Copyright(C) 2018-2019 Anatoliy Kashkin + +GameHub 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. + +GameHub 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 GameHub. If not, see . +*/ + +/* Based on Granite.Widgets.Welcome */ + +using Gtk; + +namespace GameHub.UI.Widgets +{ + public class Welcome: EventBox + { + public signal void activated(int index); + protected new GLib.List