Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:16.0:FactoryCandidates
sushi
sushi-46.0.obscpio
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File sushi-46.0.obscpio of Package sushi
07070100000000000081A4000000000000000000000001660EE2C800000011000000000000000000000000000000000000001600000000sushi-46.0/.gitignore.flatpak-builder/07070100000001000081A4000000000000000000000001660EE2C80000029F000000000000000000000000000000000000001A00000000sushi-46.0/.gitlab-ci.ymlinclude: "https://gitlab.gnome.org/GNOME/citemplates/raw/master/flatpak/flatpak_ci_initiative.yml" .flatpak-vars: variables: MANIFEST_PATH: "flatpak/org.gnome.NautilusPreviewer.json" FLATPAK_MODULE: "sushi" APP_ID: "org.gnome.NautilusPreviewerDevel" RUNTIME_REPO: "https://nightly.gnome.org/gnome-nightly.flatpakrepo" BUNDLE: "sushi-dev.flatpak" flatpak@x86_64: extends: - ".flatpak@x86_64" - ".flatpak-vars" flatpak@aarch64: extends: - ".flatpak@aarch64" - ".flatpak-vars" nightly@x86_64: extends: ".publish_nightly" needs: ["flatpak@x86_64"] nightly@aarch64: extends: ".publish_nightly" needs: ["flatpak@aarch64"] 07070100000002000081A4000000000000000000000001660EE2C800000022000000000000000000000000000000000000001300000000sushi-46.0/AUTHORSCosimo Cecchi <cosimoc@gnome.org> 07070100000003000081A4000000000000000000000001660EE2C80000499A000000000000000000000000000000000000001300000000sushi-46.0/COPYINGThe source code of Sushi is licensed to you under the GNU General Public License version 2, or (at your option) any later version. This GPL license have a exception clause added, see at the bottom of file for details. ======================================================================== GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) 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 this service 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 make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. 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. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), 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 distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the 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 a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE 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. 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 convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. <one line to give the program's name and a brief idea of what it does.> Copyright (C) <year> <name of author> 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 2 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision 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, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. <signature of Ty Coon>, 1 April 1989 Ty Coon, President of Vice This 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. The Sushi project hereby grants permission for non-GPL compatible GStreamer plugins to be used and distributed together with GStreamer and Sushi. This permission is above and beyond the permissions granted by the GPL license by which Sushi is covered. If you modify this code, you may extend this exception to your version of the code, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. 07070100000004000081A4000000000000000000000001660EE2C8000028CE000000000000000000000000000000000000001000000000sushi-46.0/NEWS46.0 ==== - Make webkit2gtk optional (Yaakov Selkowitz) - Fix freeze when libreoffice is missing (Corey Berla) - Fix tick position for fullscreen video (Balló György) - Misc cleanup (Corey Berla) - Translation updates 45.0 ==== - Translation updates 45.alpha.2 - Fix build (Corey Berla) 45.alpha.1 ==== - Fix translatable filename (Piotr Drąg) 45.alpha ==== - Fix window size with custom scale factor in x11 (Nelson Ben) - Don't show window before renderer is ready (Nelson Ben) - Allow keyboard copy shortcuts for evince and text viewers (Corey Berla) - Fix crash when switching between audio files (Corey Berla) - Fix coverart download (Corey Berla) - Add ParentHandle dbus property (Corey Berla) - Add development profile (Corey Berla) 44.2 ==== - Fix loading certain documents in evince (Frank Dana) - Translation updates 43.0 ==== - Another stable Sushi release 43.rc ===== - Make Webkit-4.1 a hard dependency 42.0 ==== - Enable web process (webkit) sandbox - Use EvinceView.JobLoadGFile for loading documents - Check for mimeTypes when populating list of viewers - Allow right-clicks to show context menu for GtkSourceView - Translation updates 41.0 ==== - Drop libmusicbrainz dependency (use libsoup directly) - Account for scale-factor when estimating window size - Build against webkit2gtk-4.1 (!23, Javier Jardón) - Disable webkit sandboxing (!18, Joel Ong) - Translation updates 3.38.0 ====== - Fix build when Wayland is disabled (Ting-Wei Lan) - Make X11 and Wayland configurable at build time (!12, David Heidelberg) - Sync font-widget with gnome-font-viewer - Fix various meson build issues - Sandbox webkitgtk - Fix crash caused by the lack of getters for viewers' properties 3.34.0 ====== - Add support for moving Nautilus selection with arrow keys (#5) - Add support for parenting the window on Wayland (#1) - Use builder-dark style for text/source viewer (#24) - Add localization for appdata file (!11, Piotr Drąg) 3.33.90 ====== - Add a command line launcher (#758253) - Fix viewer mimetype matching (#20, Joel Ong) - Load viewers from home directory (#19, Joel Ong) - Translation updates 3.33.4 ====== - Add a native LibreofficeKit renderer - Fix translation infrastructure regression (#18) - Fix loading album cover art from Amazon - Fix several glitches on HiDpi and fractional scaling displays - Respect placement of close button preference (#14) - Fix audio metadata tags retrieval (#13) - Only load a single GstTagList copy (#654500) - Fix displaying audio tag content with markup characters (#700589) - Add an appdata file (#761038) - Properly letterbox album cover art - Add a way to report loading errors in the main view - Scale window size with display resolution (#7) 3.33.3 ====== - Rewrite to use GTK directly, drop Clutter dependency - Use GtkSourceView 4 (Joel Ong, Martin Blanchard) 3.32.0 ====== - Update DOAP file for GitLab move (Andre Klapper) - Explicitly hide minimize and maximize (#3, Will Thompson) 3.31.2 ====== - Port to meson build system (Rasmus Thomsen, Will Thompson) - Replace some deprecated API (Martin Blanchard) 3.30.0 ====== - Fix miscellaneous warnings - Rename service file to match owned bus name 3.28.3 ====== - Fix another LibreOffice to PDF conversion regression (hopefully for good this time) 3.28.2 ====== - Fix another LibreOffice to PDF conversion regression 3.28.1 ====== - Fix LibreOffice to PDF conversion regression (Robert McQueen) - Add support for docx/pptx/xlsx MIME types (Robert McQueen) 3.28.0 ====== - Add support for GIF animations (Princeton Ferro) - Use LibreOffice directly instead of unoconv (Robert McQueen) - Prefer LibreOffice from flatpak when installed (Robert McQueen) 3.24.0 ====== - Translation updates 3.23.91 ======= - Use correct icon when fullscreen - Use upstream format.js code - Specify GdkX11 import version - Translation updates 3.21.91 ======= - Make sushi work under Wayland - Fix builddir != srcdir builds - Translation updates 3.20.0 ====== - Link directly with harfbuzz (Andreas Henriksson) - Translation updates 3.19.90 - "Hardcore Chilling" ============================= - Port to ClutterGst 3.0 (Lionel Landwerlin) - Don't assume X (Matthias Clasen) - Don't use deprecated style classes (Matthias Clasen) - Port to GTask - Fix toolbar spacing - Resync font renderer from gnome-font-viewer 3.18.0 - "Symbiosis" ==================== - Translation updates 3.17.4 - "Dark Wave" ==================== - Apply embedded orientation to images - Fix encoding problems when loading non utf-8 text files - Do not crash when right clicking text previews - Add a way to easily run under gdb - Use regular GTK client side decorations - Use GResource for auxiliary data - Fix theming glitches after GTK update (Trinh Anh Ngoc) 3.16.0 ====== - Translation updates 3.15.90 - "Mexican Bus" ======================= - Fix deadlock with recent clutter/clutter-gtk - Don't require a parent window - Port HTML viewer to WebKit2 (Marcos Chavarría Teijeiro) - Fix margins in RTL (Yosef Or Boczko) - Fix toolbar icons for RTL (Yosef Or Boczko) 3.12.0 - "Hippie Hill" ====================== - Translation updates 3.11.90 - "Bandoliers" ====================== - Fix compatibility with js24-based GJS - Update for E4X removal (Dominique Leuenberger, Tim Lunn) - Update FSF address (Daniel Mustieles) 3.10.0 ====== - Make translations appear - Some fixes for right-to-left languages 3.8.1 - "Merchandise" ===================== - Fix a crash while loading PDF documents (Philippe Coval) 3.8.0 - "Bla" ============= - Translation updates 3.7.91 - "Asleep" ================= - Call gtk_render_background when drawing SushiFontWidget - Translation updates 3.7.5 - "It's a New Day" ======================== - Use a better padding for the font preview - Remove custom CSS styling for SushiFontWidget - Fix the build with automake 1.13 (Nuno Araujo) 3.7.4 - "Wilderness" ==================== - Use PackageKit to install unoconv if not detected at runtime - Drop gjs-dbus dependency (Rico Tzschichholz) - Translation updates 3.7.3 - "Invisible" =================== - Use the single-include header for GtkSourceView (Ryan Lortie) - Add some convenience functions to SushiFontWidget - Use a better error message in SushiFontLoader - Translation updates 3.6.0 - "Laughing" ================== - Fix regression where double spacebar was required to activate preview from Nautilus - Translation updates 3.5.92 - "Drop the Leash" ========================= - Translation updates 3.5.91 - "Evacuation" ===================== - Port to libmusicbrainz5 (Jon Dowland) 3.5.90 - "Spritz" ================= - Port to GStreamer 1.0 (Tim-Philipp Müller) - Fix OSD toolbar positioning for the audio viewer 0.5.5 - "Red Wine Liberation Front" =================================== - Port to GDBus (Jasper St. Pierre) - Port to GtkApplication (Jasper St. Pierre) 0.5.4 - "Nowhere Land" ====================== - Unify folder and fallback file viewers - Remove more of our custom theming - Use a higher limit when querying the MusicBrainz service (Jon Dowland) - Don't hardcode /bin/bash in the launcher scripts (Antoine Jacoutot) 0.5.2 - "No-one Needs To Know" ============================== - Fall back to C locale when constructing the sample string before picking an entirely random-glyph string in the font widget - Flip font widget orientation for RTL locales - Always pick a valid size for fixed-size fonts in the font widget 0.5.1 - "Let It Go" =================== - Use libmusicbrainz v4 API - Add a preference to turn off client window decorations - Fix vertical interline spacing in the font viewer - Enable fullscreen for the font viewer - Use OSD style class for toolbars - Use GEdit GtkSourceView color scheme if available (Vadim Rutkovsky) - Don't install the private library in the system libdir (Michael Biebl) - Use mime type list provided by Totem for gst and audio viewers (Bastien Nocera) 0.4.1 - "Marmot" ================ - Fix a crash when fetching album cover art - Move the window to the current desktop workspace when shown - Avoid maximization and window snapping - Plug some memory leaks 0.4.0 - "Walking Donut" ======================= - Translation updates 0.3.92 - "Teasing Owl" ===================== - Properly center the window title in the allocated space - Clear signal handlers when switching between viewers - Translation updates 0.3.91 - "Estathé" ================== - Ellipsize title for long filenames (Vadim Rutkovsky) - Use F11 as a keybinding for Fullscreen (Vadim Rutkovsky) - Initialize X11 threads (Gert Michael Kulyk) - Translation updates 0.3.0 - "Casa Gori" =================== - Quote the file path before passing it to unoconv (Vincent Untz) - Build with latest clutter-gtk - Translation updates 0.2.1 - "Here and now" ====================== - Fix OSD toolbar not appearing for text files previews - Make sure the decoration title is centered with the close button - Translation updates 0.2.0 - "Fuuuuuuuu" =================== - First stable release - Tons of translation updates! 0.1.92 - "Indie Rural Foo" ========================== - Implement cache for cover art - Improve documentation - Tons of translation updates! 0.1.90 - "Nonno Nanni" ====================== - Add a Close() remote method 0.0.5 - "Coop" ============== - Use "document-open-symbolic" for run/open toolbar buttons - Require latest clutter-gtk to fix underallocations with GTK+ 3.1 - Use g_format_size() instead of g_format_size_for_display() - Use the GTK+ dark theme - UTF8-validate the text before inserting it into the buffer (Ignacio Casal Quinteiro) 0.0.4 - "Bianca" ================ - Relicense to GPLv2 with an exception clause to allow use non-free GStreamer plugins. - Fix some compilation warnings (Vincent Untz) 0.0.3 - "Last Night" ==================== - Add HTML viewer - Add text viewer - Add font viewer - Update to latest 3.1.3 platform changes - Too many fixes and improvements to be listed here [ 0.0.2 never actually happened ] 0.0.2 - "Crab Conspiration" =========================== Minor/bugfix release. - Load pixbufs asynchronously - Quit with 'Q' - Fix fullscreen scale mismatch in the image plugin 0.0.1 - "Weapons of Mass Ave Destruction" ========================================= Initial release. Support for the following content types: - PDF documents - Video files - Music - Pictures - Folders/Files 07070100000005000081A4000000000000000000000001660EE2C8000003A8000000000000000000000000000000000000001500000000sushi-46.0/README.md# Sushi This is Sushi, a quick previewer for Files (nautilus), the GNOME desktop file manager. ## Using Sushi Sushi is a DBus-activated service. For Sushi to popup, applications will have to call the `ShowFile` method on the `org.gnome.NautilusPreviewer2` interface. If you want to debug Sushi without a calling application, you can use the `sushi <filename>` command. ## Reporting issues Before filing an issue here, confirm that it has not been fixed on the latest nightly build. The easiest way to do this is by installing the nightly flatpak. ``` flatpak remote-add --if-not-exists gnome-nightly https://nightly.gnome.org/gnome-nightly.flatpakrepo flatpak install gnome-nightly org.gnome.NautilusPreviewerDevel ``` After installing the nightly flatpak, you can launch Sushi via the below command, or by initiating a preview from the NautilusDevel nightly flatpak. `flatpak run org.gnome.NautilusPreviewerDevel <filename>` 07070100000006000081A4000000000000000000000001660EE2C800000211000000000000000000000000000000000000001000000000sushi-46.0/TODOBugs: - shouldn't probably steal focus from the nautilus window when open ? - error handling from plugins should be catched and a fail-whale of some sort be displayed - album arts not square should be canvased into a square shape Low-priority bugs: - videos over remote mounts should have some some sort of buffering Ideas (to be validated): - make preview window resizable, and save per-file preview size in gvfs metadata - save/share cover art with Rhythmbox/Banshee? - add a zoom-in/zoom-out effect when opening/closing 07070100000007000041ED000000000000000000000002660EE2C800000000000000000000000000000000000000000000001000000000sushi-46.0/data07070100000008000081A4000000000000000000000001660EE2C800002808000000000000000000000000000000000000002E00000000sushi-46.0/data/builder-dark.style-scheme.xml<?xml version="1.0" encoding="UTF-8"?> <!-- This file is part of GtkSourceView Copyright (C) 2007 GtkSourceView team Author: Paolo Borelli <pborelli@gnome.org> GtkSourceView is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. GtkSourceView 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA --> <style-scheme id="builder-dark" name="Builder Dark" version="1.0"> <author>Paolo Borelli, Christian Hergert</author> <description>Dark color scheme for Builder using the Tango color palette</description> <!-- Tango Palette --> <color name="butter1" value="#fce94f"/> <color name="butter2" value="#edd400"/> <color name="butter3" value="#c4a000"/> <color name="chameleon1" value="#8ae234"/> <color name="chameleon2" value="#73d216"/> <color name="chameleon3" value="#4e9a06"/> <color name="orange1" value="#fcaf3e"/> <color name="orange2" value="#f57900"/> <color name="orange3" value="#ce5c00"/> <color name="skyblue1" value="#729fcf"/> <color name="skyblue2" value="#3465a4"/> <color name="skyblue3" value="#204a87"/> <color name="plum1" value="#ad7fa8"/> <color name="plum2" value="#75507b"/> <color name="plum3" value="#5c3566"/> <color name="chocolate1" value="#e9b96e"/> <color name="chocolate2" value="#c17d11"/> <color name="chocolate3" value="#8f5902"/> <color name="scarletred1" value="#ef2929"/> <color name="scarletred2" value="#cc0000"/> <color name="scarletred3" value="#a40000"/> <color name="aluminium1" value="#eeeeec"/> <color name="aluminium2" value="#d3d7cf"/> <color name="aluminium3" value="#babdb6"/> <color name="aluminium4" value="#888a85"/> <color name="aluminium5" value="#555753"/> <color name="aluminium6" value="#2e3436"/> <color name="white" value="#ffffff"/> <color name="pink1" value="#dd4a68"/> <color name="red1" value="#ff0000"/> <color name="dark1" value="#1e1e1e"/> <color name="dark2" value="#303030"/> <!-- Global Settings --> <style name="text" foreground="aluminium3" background="dark1"/> <style name="selection" foreground="aluminium1" background="aluminium4"/> <style name="cursor" foreground="aluminium2"/> <style name="current-line" background="dark2"/> <style name="current-line-number" background="dark2"/> <style name="line-numbers" foreground="aluminium5" background="dark1"/> <style name="draw-spaces" foreground="aluminium5"/> <style name="background-pattern" background="#202020"/> <style name="map-overlay" background="#rgba(136,138,133,0.25)"/> <!-- Diagnostics Underlining --> <style name="diagnostician::deprecated" underline="error" underline-color="aluminium3"/> <style name="diagnostician::error" underline="error" underline-color="red1"/> <style name="diagnostician::note" underline="error" underline-color="skyblue1"/> <style name="diagnostician::warning" underline="error" underline-color="orange1"/> <!-- Snippets --> <style name="snippet::tab-stop" background="orange3" foreground="aluminium6"/> <style name="snippet::area" background="#rgba(86,114,151,.5)"/> <!-- Debugger --> <style name="debugger::current-breakpoint" foreground="#2e3436" background="#fcaf3e"/> <style name="debugger::breakpoint" foreground="#ffffff" background="#204a87"/> <!-- Hover links --> <style name="action::hover-definition" background="#41464c" underline="true"/> <!-- Bracket Matching --> <style name="bracket-match" foreground="chocolate2" bold="true"/> <style name="bracket-mismatch" foreground="aluminium1" background="scarletred2" bold="true"/> <!-- Right Margin --> <style name="right-margin" foreground="#484749" background="#484749"/> <!-- Search Matching --> <style name="search-match" foreground="aluminium1" background="chameleon3"/> <style name="quick-highlight-match" background="#rgba(78,154,6,.25)"/> <!-- Search Shadow --> <style name="search-shadow" background="#rgba(0,0,0,0.4)"/> <!-- Spellchecker Matching --> <style name="misspelled-match" foreground="#000000" background="#b3d4fc"/> <!-- Comments --> <style name="def:comment" foreground="aluminium4"/> <style name="def:shebang" foreground="aluminium4" bold="true"/> <style name="def:doc-comment-element" italic="true"/> <!-- Constants --> <style name="def:constant" foreground="butter2"/> <style name="def:string" foreground="#0077aa"/> <style name="def:special-char" foreground="#dd4a68"/> <style name="def:special-constant" foreground="plum1"/> <style name="def:floating-point" foreground="orange3"/> <style name="def:function" foreground="#4186A8"/> <!-- Identifiers --> <style name="def:identifier" foreground="skyblue1"/> <!-- Statements --> <style name="def:statement" foreground="white" bold="true"/> <!-- Types --> <style name="def:type" foreground="chameleon1" bold="true"/> <!-- Others --> <style name="def:preprocessor" foreground="#dd4a68"/> <style name="def:error" foreground="aluminium1" background="scarletred2" bold="true"/> <style name="def:warning" foreground="aluminium1" background="plum1"/> <style name="def:note" background="butter1" foreground="aluminium4" bold="true"/> <style name="def:underlined" italic="true" underline="true"/> <!-- Heading styles, uncomment to enable --> <!-- <style name="def:heading0" scale="5.0"/> <style name="def:heading1" scale="2.5"/> <style name="def:heading2" scale="2.0"/> <style name="def:heading3" scale="1.7"/> <style name="def:heading4" scale="1.5"/> <style name="def:heading5" scale="1.3"/> <style name="def:heading6" scale="1.2"/> --> <!-- Language specific --> <style name="c:comment" foreground="#8b9eab"/> <style name="c:preprocessor" foreground="#8194a6" bold="false"/> <style name="c:boolean" foreground="#0077aa"/> <style name="c:keyword" foreground="#0077aa" bold="true"/> <style name="c:string" foreground="#669900"/> <style name="c:included-file" foreground="orange3"/> <style name="c:storage-class" foreground="orange3" bold="true"/> <style name="c:type" foreground="#669900" bold="true"/> <style name="c:macro-name" foreground="#677685" bold="false"/> <style name="c:enum-name" foreground="#dd4a68" bold="false"/> <style name="diff:added-line" foreground="chameleon2"/> <style name="diff:removed-line" foreground="plum1"/> <style name="diff:changed-line" foreground="blue1"/> <style name="diff:diff-file" foreground="chameleon1" bold="true"/> <style name="diff:location" foreground="chameleon1"/> <style name="diff:special-case" foreground="white" bold="true"/> <style name="gutter:added-line" foreground="chameleon2"/> <style name="gutter:changed-line" foreground="butter3"/> <style name="gutter:removed-line" foreground="scarletred3"/> <style name="js:object" foreground="chameleon3" bold="true"/> <style name="js:constructors" foreground="pink1"/> <style name="js:keyword" foreground="#2b85aa"/> <style name="js:string" foreground="#669900"/> <style name="js:function" foreground="pink1"/> <style name="latex:command" foreground="chameleon1" bold="true"/> <style name="latex:include" use-style="def:preprocessor"/> <style name="xml:comment" foreground="#8b9eab"/> <style name="xml:attribute-name" foreground="#orange3" bold="false"/> <style name="xml:attribute-value" foreground="#669900"/> <style name="xml:tag-match" background="#rgba(114,159,207,.20)"/> <!-- Symbol-tree xml-pack coloring --> <style name="symboltree::label" foreground="#000000" background="#D5E7FC"/> <style name="symboltree::id" foreground="#000000" background="#D9E7BD"/> <style name="symboltree::style-class" foreground="#000000" background="#DFCD9B"/> <style name="symboltree::type" foreground="#000000" background="#F4DAC3"/> <style name="symboltree::parent" foreground="#000000" background="#DEBECF"/> <style name="symboltree::class" foreground="#000000" background="#FFEF98"/> <style name="symboltree::attribute" foreground="#000000" background="#F0E68C"/> </style-scheme> 07070100000009000081A4000000000000000000000001660EE2C8000002AD000000000000000000000000000000000000001C00000000sushi-46.0/data/meson.buildconf = configuration_data() conf.set('libexecdir', libexecdir) conf.set('app_id', app_id) configure_file( input: 'org.gnome.NautilusPreviewer.service.in', output: '@0@.service'.format(app_id), configuration: conf, install_dir: join_paths(datadir, 'dbus-1', 'services'), ) i18n.merge_file( input: configure_file( input: 'org.gnome.NautilusPreviewer.appdata.xml.in.in', output: '@BASENAME@', configuration: conf ), output: '@0@.appdata.xml'.format(app_id), po_dir: '../po', install: true, install_dir: join_paths(datadir, 'metainfo') ) install_data( 'builder-dark.style-scheme.xml', install_dir: join_paths(pkgdatadir, 'gtksourceview-4/styles') ) 0707010000000A000081A4000000000000000000000001660EE2C80000049E000000000000000000000000000000000000003E00000000sushi-46.0/data/org.gnome.NautilusPreviewer.appdata.xml.in.in<?xml version="1.0" encoding="UTF-8"?> <!-- Copyright 2015 Jiri Eischmann <eischmann@redhat.com> --> <component type="addon"> <id>@app_id@</id> <extends>org.gnome.Nautilus.desktop</extends> <metadata_license>CC0-1.0</metadata_license> <project_license>GPL-2.0+</project_license> <name>Sushi</name> <summary>Provide a facility for quickly viewing different kinds of files</summary> <description> <p> Sushi is a file previewer for the GNOME desktop environment. It is an independent component that integrates with GNOME Files (Nautilus). </p> </description> <keywords> <keyword>nautilus</keyword> <keyword>sushi</keyword> <keyword>view</keyword> <keyword>previewer</keyword> <keyword>preview</keyword> </keywords> <releases> <release version="46.0" date="2024-04-04"/> </releases> <translation type="gettext">sushi</translation> <url type="translate">https://wiki.gnome.org/TranslationProject</url> <url type="homepage">https://gitlab.gnome.org/GNOME/sushi</url> <url type="bugtracker">https://gitlab.gnome.org/GNOME/sushi/issues</url> <update_contact>eischmann_at_redhat.com</update_contact> </component> 0707010000000B000081A4000000000000000000000001660EE2C800000039000000000000000000000000000000000000003700000000sushi-46.0/data/org.gnome.NautilusPreviewer.service.in[D-BUS Service] Name=@app_id@ Exec=@libexecdir@/@app_id@ 0707010000000C000041ED000000000000000000000002660EE2C800000000000000000000000000000000000000000000001300000000sushi-46.0/flatpak0707010000000D000081A4000000000000000000000001660EE2C800000DC5000000000000000000000000000000000000003400000000sushi-46.0/flatpak/org.gnome.NautilusPreviewer.json{ "app-id": "org.gnome.NautilusPreviewerDevel", "runtime": "org.gnome.Platform", "runtime-version": "master", "sdk": "org.gnome.Sdk", "command": "sushi", "cleanup": [ "/include", "/lib/pkgconfig", "*.a" ], "finish-args": [ "--socket=pulseaudio", "--socket=x11", "--socket=wayland", "--share=ipc", "--share=network", "--device=dri", "--talk-name=org.freedesktop.FileManager1", "--filesystem=home:ro" ], "modules": [ { "name": "popplerdata", "no-autogen": true, "make-install-args": [ "prefix=/app" ], "sources": [ { "type": "archive", "url": "https://poppler.freedesktop.org/poppler-data-0.4.11.tar.gz", "sha256": "2cec05cd1bb03af98a8b06a1e22f6e6e1a65b1e2f3816cb3069bb0874825f08c" } ] }, { "name": "poppler", "buildsystem": "cmake-ninja", "config-opts": [ "-DCMAKE_INSTALL_LIBDIR=/app/lib", "-DCMAKE_INSTALL_INCLUDEDIR=/app/include", "-DENABLE_LIBOPENJPEG=none", "-DENABLE_BOOST=OFF", "-DENABLE_CPP=OFF", "-DBUILD_GTK_TESTS=OFF", "-DBUILD_CPP_TESTS=OFF" ], "cleanup": [ "/bin" ], "sources": [ { "type": "archive", "url": "https://poppler.freedesktop.org/poppler-23.01.0.tar.xz", "sha256": "fae9b88d3d5033117d38477b79220cfd0d8e252c278ec870ab1832501741fd94" } ] }, { "name": "evince", "buildsystem": "meson", "cleanup": [ "/share/GConf", "/share/help" ], "config-opts": [ "-Dnautilus=false", "-Dgtk_doc=false", "-Dviewer=false", "-Dpreviewer=false", "-Ddbus=false", "-Dintrospection=true", "-Dcomics=disabled", "-Dgspell=disabled" ], "sources": [ { "type": "archive", "url": "https://download.gnome.org/sources/evince/43/evince-43.1.tar.xz", "sha256": "6d75ca62b73bfbb600f718a098103dc6b813f9050b9594be929e29b4589d2335" } ] }, { "name": "sourceview-4", "buildsystem": "meson", "config-opts": [ "-Dinstall_tests=false", "-Dgtk_doc=false", "-Dvapi=false" ], "sources": [ { "type": "archive", "url": "https://download.gnome.org/sources/gtksourceview/4.8/gtksourceview-4.8.4.tar.xz", "sha256": "7ec9d18fb283d1f84a3a3eff3b7a72b09a10c9c006597b3fbabbb5958420a87d" } ] }, { "name": "sushi", "buildsystem": "meson", "config-opts": [ "-Dprofile=development" ], "sources": [ { "type": "dir", "path": ".." } ] } ] } 0707010000000E000081A4000000000000000000000001660EE2C800000729000000000000000000000000000000000000001700000000sushi-46.0/meson.buildproject( 'sushi', 'c', version: '46.0', meson_version: '>=0.58.0' ) epoxy_dep = dependency('epoxy') evince_document_dep = dependency('evince-document-3.0') evince_view_dep = dependency('evince-view-3.0') freetype_dep = dependency('freetype2') gdk_pixbuf_dep = dependency('gdk-pixbuf-2.0', version: '>=2.23.0') gio_unix_dep = dependency('gio-unix-2.0', version: '>=2.29.14') glib_dep = dependency('glib-2.0', version: '>=2.29.14') gstreamer_dep = dependency('gstreamer-1.0') gstreamer_audio_dep = dependency('gstreamer-audio-1.0') gstreamer_tag_dep = dependency('gstreamer-tag-1.0') gstreamer_video_dep = dependency('gstreamer-video-1.0') gtk_dep = dependency('gtk+-3.0', version: '>=3.13.2') gtk_x11_dep = dependency('gtk+-x11-3.0', required: get_option('X11')) gtk_wayland_dep = dependency('gtk+-wayland-3.0', version: '>= 3.21.5', required: get_option('wayland')) gtksourceview_dep = dependency('gtksourceview-4', version: '>=4.0.3') harfbuzz_dep = dependency('harfbuzz', version: '>=0.9.9') webkit_dep = dependency('webkit2gtk-4.1', required: false) bindir = join_paths(get_option('prefix'), get_option('bindir')) datadir = join_paths(get_option('prefix'), get_option('datadir')) libdir = join_paths(get_option('prefix'), get_option('libdir')) libexecdir = join_paths(get_option('prefix'), get_option('libexecdir')) pkgdatadir = join_paths(datadir, meson.project_name()) pkglibdir = join_paths(libdir, meson.project_name()) gjs = find_program('gjs', 'gjs-console') add_project_arguments( '-DGETTEXT_PACKAGE="' + meson.project_name() + '"', language: 'c', ) if get_option('profile') == 'default' app_id = 'org.gnome.NautilusPreviewer' else app_id = 'org.gnome.NautilusPreviewerDevel' endif object_path = '/@0@'.format(app_id.replace('.', '/')) i18n = import('i18n') subdir('data') subdir('po') subdir('src') 0707010000000F000081A4000000000000000000000001660EE2C800000157000000000000000000000000000000000000001D00000000sushi-46.0/meson_options.txtoption('wayland', type: 'feature', value: 'auto', description: 'Build with Wayland support.') option('X11', type: 'feature', value: 'auto', description: 'Build with legacy X11 support.') option('profile', type: 'combo', choices: ['default', 'development'], value: 'default', description: 'Build with default or development App Id.') 07070100000010000041ED000000000000000000000002660EE2C800000000000000000000000000000000000000000000000E00000000sushi-46.0/po07070100000011000081A4000000000000000000000001660EE2C80000013D000000000000000000000000000000000000001600000000sushi-46.0/po/LINGUAS# Keep this list sorted alphabetically ab af an ar as ast be bg bn_IN bs ca ca@valencia ckb cs da de el en_GB eo es et eu fa fi fr fur gd gl gu he hi hr hu id ie is it ja ka kab kk kn ko lt lv mjw ml mr ms nb ne nl oc or pa pl pt pt_BR ro ru sl sk sr sr@latin sv ta te tg th tr uk uz@cyrillic vi zh_CN zh_HK zh_TW ug 07070100000012000081A4000000000000000000000001660EE2C8000000F5000000000000000000000000000000000000001A00000000sushi-46.0/po/POTFILES.in# List of source files containing translatable strings. # Please keep this file sorted alphabetically. data/org.gnome.NautilusPreviewer.appdata.xml.in.in src/ui/fallbackRenderer.js src/ui/mainWindow.js src/viewers/audio.js src/viewers/evince.js 07070100000013000081A4000000000000000000000001660EE2C800000A50000000000000000000000000000000000000001400000000sushi-46.0/po/ab.po# Abkhazian translation for sushi. # Copyright (C) 2022 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # Нанба Наала <naala-nanba@rambler.ru>, 2022. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2021-09-21 13:26+0000\n" "PO-Revision-Date: 2021-09-21 13:26+0000\n" "Last-Translator: Нанба Наала <naala-nanba@rambler.ru>\n" "Language-Team: Abkhazian <ab@li.org>\n" "Language: ab\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-DamnedLies-Scope: partial\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Ишәнаҭоит алшара иаарццакны хкы рацәала афаилқәа рыхәаԥшра" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "Sushi- ишәнаҭоит алшара иаарццакны аусуратә ишәа шәахәаԥшырц." "Уи ихьыԥшым хәҭаҵас афаил иалалоит." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Ахкы" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d Хәҭак" msgstr[1] "%d Ахәҭақәа" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Иҭацәу ақьаадҭра " #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Ашәага" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Ианыԥсахыз арыцхә" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Арбара залшом %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Аԥшьы %s аҟны аартра" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Аартра" #: src/viewers/audio.js:375 msgid "from" msgstr "аҟынтә" #: src/viewers/audio.js:380 msgid "by" msgstr "ила" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d аҟынтә %d" 07070100000014000081A4000000000000000000000001660EE2C80000067F000000000000000000000000000000000000001400000000sushi-46.0/po/af.po# Afrikaans translation for sushi. # Copyright (C) 2017 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # pieter <pieter@sonbesie.co.za>, 2017. # Pieter Schoeman <pieter@sonbesie.co.za>, 2017. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?" "product=sushi&keywords=I18N+L10N&component=general\n" "POT-Creation-Date: 2017-10-05 12:34+0000\n" "PO-Revision-Date: 2017-11-24 15:10+0200\n" "Last-Translator: Pieter Schoeman <pieter@sonbesie.co.za>\n" "Language-Team: Afrikaans <pieter@sonbesie.co.za>\n" "Language: af\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: Gtranslator 2.91.7\n" #: ../src/js/ui/fallbackRenderer.js:119 msgid "Type" msgstr "Tipe" #: ../src/js/ui/fallbackRenderer.js:120 ../src/js/ui/fallbackRenderer.js:129 #: ../src/js/ui/fallbackRenderer.js:135 ../src/js/ui/spinnerBox.js:56 msgid "Loading…" msgstr "Laai tans…" #: ../src/js/ui/fallbackRenderer.js:128 msgid "Size" msgstr "Grootte" #: ../src/js/ui/fallbackRenderer.js:134 msgid "Modified" msgstr "Verander" #: ../src/js/viewers/audio.js:172 msgid "from" msgstr "van" #: ../src/js/viewers/audio.js:174 msgid "by" msgstr "deur" #: ../src/js/viewers/evince.js:77 #, javascript-format msgid "%d of %d" msgstr "%d of %d" #: ../src/libsushi/sushi-file-loader.c:639 #, c-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d item" msgstr[1] "%d items" #: ../src/libsushi/sushi-file-loader.c:651 msgid "Empty Folder" msgstr "Leë gids" 07070100000015000081A4000000000000000000000001660EE2C800000755000000000000000000000000000000000000001400000000sushi-46.0/po/an.po# Aragonese translation for sushi. # Copyright (C) 2012 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # Daniel Martinez <entaltoaragon@gmail.com>, 2012. # msgid "" msgstr "" "Project-Id-Version: sushi gnome-3-4\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" "product=sushi&keywords=I18N+L10N&component=general\n" "POT-Creation-Date: 2012-09-25 23:26+0000\n" "PO-Revision-Date: 2012-09-29 11:48+0200\n" "Last-Translator: Daniel Martinez <entaltoaragon@gmail.com>\n" "Language-Team: Aragonés <softaragones@googlegroups.com>\n" "Language: an\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bits\n" "Plural-Forms: nplurals=2; plural=(n!=1);\n" #: ../data/org.gnome.sushi.gschema.xml.in.h:1 msgid "Client decoration" msgstr "Decoración d'o client" #: ../data/org.gnome.sushi.gschema.xml.in.h:2 msgid "Whether the window draws WM decorations itself" msgstr "Dice si la finestra debuxa decoracions WM por si mesma" #: ../src/js/ui/fallbackRenderer.js:120 msgid "Type" msgstr "Tipo" #: ../src/js/ui/fallbackRenderer.js:121 ../src/js/ui/fallbackRenderer.js:130 #: ../src/js/ui/fallbackRenderer.js:136 ../src/js/ui/spinnerBox.js:57 msgid "Loading…" msgstr "Cargando…" #: ../src/js/ui/fallbackRenderer.js:129 msgid "Size" msgstr "Tamanyo" #: ../src/js/ui/fallbackRenderer.js:135 msgid "Modified" msgstr "Modificada" #: ../src/js/viewers/audio.js:172 msgid "from" msgstr "dende" #: ../src/js/viewers/audio.js:174 msgid "by" msgstr "por" #: ../src/js/viewers/evince.js:79 #, c-format msgid "%d of %d" msgstr "%d de %d" #: ../src/libsushi/sushi-file-loader.c:639 #, c-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d elemento" msgstr[1] "%d elementos" #: ../src/libsushi/sushi-file-loader.c:651 msgid "Empty Folder" msgstr "Vaciar carpeta" 07070100000016000081A4000000000000000000000001660EE2C8000007CD000000000000000000000000000000000000001400000000sushi-46.0/po/ar.po# Arabic translation for sushi. # Copyright (C) 2011 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # Abdalrahim G. Fakhouri <abdilra7eem@yahoo.com>, 2011. msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" "product=sushi&keywords=I18N+L10N&component=general\n" "POT-Creation-Date: 2011-09-02 20:34+0000\n" "PO-Revision-Date: 2011-09-03 00:26+0300\n" "Last-Translator: Abdalrahim G. Fakhouri <abdilra7eem@yahoo.com>\n" "Language-Team: Arabic <doc@arabeyes.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ar\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: Virtaal 0.7.0\n" "X-Project-Style: gnome\n" #: ../src/libsushi/sushi-file-loader.c:641 #, c-format msgid "%d item" msgid_plural "%d items" msgstr[0] "لا عناصر" msgstr[1] "عنصر واحد" msgstr[2] "عنصران" msgstr[3] "%d عناصر" msgstr[4] "%d عنصراً" msgstr[5] "%d عنصر" #: ../src/libsushi/sushi-file-loader.c:653 msgid "Empty Folder" msgstr "مجلد فارغ" #: ../src/js/ui/fallbackRenderer.js:120 msgid "Type" msgstr "النّوع" #: ../src/js/ui/fallbackRenderer.js:121 ../src/js/ui/fallbackRenderer.js:126 #: ../src/js/ui/fallbackRenderer.js:131 ../src/js/ui/spinnerBox.js:54 #: ../src/js/viewers/folder.js:127 ../src/js/viewers/folder.js:132 msgid "Loading…" msgstr "يُحمّل…" #: ../src/js/ui/fallbackRenderer.js:125 ../src/js/viewers/folder.js:126 msgid "Size" msgstr "الحجم" #: ../src/js/ui/fallbackRenderer.js:130 ../src/js/viewers/folder.js:131 msgid "Modified" msgstr "مُعدَّل" #: ../src/js/viewers/audio.js:163 msgid "from" msgstr "مِن" #: ../src/js/viewers/audio.js:165 msgid "by" msgstr "أداء" #: ../src/js/viewers/evince.js:75 #, c-format msgid "%d of %d" msgstr "%d من %d" 07070100000017000081A4000000000000000000000001660EE2C8000008D2000000000000000000000000000000000000001400000000sushi-46.0/po/as.po# Assamese translation for sushi. # Copyright (C) 2011 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # # ngoswami <ngoswami@redhat.com>, 2011. # Nilamdyuti Goswami <ngoswami@redhat.com>, 2011, 2012. msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug." "cgi?product=sushi&keywords=I18N+L10N&component=general\n" "POT-Creation-Date: 2012-04-12 19:27+0000\n" "PO-Revision-Date: 2012-08-13 21:21+0530\n" "Last-Translator: Nilamdyuti Goswami <ngoswami@redhat.com>\n" "Language-Team: as_IN <kde-i18n-doc@kde.org>\n" "Language: as\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: Lokalize 1.0\n" #: ../data/org.gnome.sushi.gschema.xml.in.h:1 msgid "Client decoration" msgstr "ক্লাএন্ট সাজ্-সজ্জা" #: ../data/org.gnome.sushi.gschema.xml.in.h:2 msgid "Whether the window draws WM decorations itself" msgstr "উইন্ডোয় WM সাজ্-সজ্জাসমূহ নিজে কৰে নে" #: ../src/js/ui/fallbackRenderer.js:117 msgid "Type" msgstr "ধৰণ" #: ../src/js/ui/fallbackRenderer.js:118 ../src/js/ui/fallbackRenderer.js:123 #: ../src/js/ui/fallbackRenderer.js:128 ../src/js/ui/spinnerBox.js:57 #: ../src/js/viewers/folder.js:124 ../src/js/viewers/folder.js:129 msgid "Loading…" msgstr "ল'ড কৰা হৈছে…" #: ../src/js/ui/fallbackRenderer.js:122 ../src/js/viewers/folder.js:123 msgid "Size" msgstr "আকাৰ" #: ../src/js/ui/fallbackRenderer.js:127 ../src/js/viewers/folder.js:128 msgid "Modified" msgstr "পৰিবৰ্তিত" #: ../src/js/viewers/audio.js:171 msgid "from" msgstr "পৰা" #: ../src/js/viewers/audio.js:173 msgid "by" msgstr "দ্বাৰা" #: ../src/js/viewers/evince.js:79 #, c-format msgid "%d of %d" msgstr "%d ৰ %d" #: ../src/libsushi/sushi-file-loader.c:640 #, c-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d বস্তু" msgstr[1] "%d বস্তুবোৰ" #: ../src/libsushi/sushi-file-loader.c:652 msgid "Empty Folder" msgstr "ফোল্ডাৰ খালি কৰক" 07070100000018000081A4000000000000000000000001660EE2C80000071C000000000000000000000000000000000000001500000000sushi-46.0/po/ast.po# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Xandru Armesto <xandru@softastur.org>, 2011. msgid "" msgstr "" "Project-Id-Version: Sushi master\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=sushi&" "keywords=I18N+L10N&component=general\n" "POT-Creation-Date: 2011-09-09 20:30+0000\n" "PO-Revision-Date: 2011-09-10 09:07+0200\n" "Last-Translator: Xandru Armesto <xandru@softastur.org>\n" "Language-Team: Softastur <alministradores@softastur.org>\n" "Language: ast\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: Virtaal 0.5.2\n" "X-Poedit-Language: Asturian\n" "X-Poedit-SourceCharset: utf-8\n" #: ../src/libsushi/sushi-file-loader.c:641 #, c-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d elementu" msgstr[1] "%d elementos" #: ../src/libsushi/sushi-file-loader.c:653 msgid "Empty Folder" msgstr "Vaciar carpeta" #: ../src/js/ui/fallbackRenderer.js:120 msgid "Type" msgstr "Tipu" #: ../src/js/ui/fallbackRenderer.js:121 ../src/js/ui/fallbackRenderer.js:126 #: ../src/js/ui/fallbackRenderer.js:131 ../src/js/ui/spinnerBox.js:54 #: ../src/js/viewers/folder.js:127 ../src/js/viewers/folder.js:132 msgid "Loading…" msgstr "Cargando…" #: ../src/js/ui/fallbackRenderer.js:125 ../src/js/viewers/folder.js:126 msgid "Size" msgstr "Tamañu" #: ../src/js/ui/fallbackRenderer.js:130 ../src/js/viewers/folder.js:131 msgid "Modified" msgstr "Modificada" #: ../src/js/viewers/audio.js:163 msgid "from" msgstr "dende" #: ../src/js/viewers/audio.js:165 msgid "by" msgstr "por" #: ../src/js/viewers/evince.js:75 #, c-format msgid "%d of %d" msgstr "%d de %d" 07070100000019000081A4000000000000000000000001660EE2C800000A3D000000000000000000000000000000000000001400000000sushi-46.0/po/be.po# Ihar Hrachyshka <ihar.hrachyshka@gmail.com>, 2011. # msgid "" msgstr "" "Project-Id-Version: sushi.master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2022-07-24 06:37+0000\n" "PO-Revision-Date: 2022-12-01 05:41+0300\n" "Last-Translator: Launchpad translators\n" "Language-Team: Belarusian <i18n-bel-gnome@googlegroups.com>\n" "Language: be\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" "X-Generator: Poedit 3.2\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Забяспечвае магчымасць хуткага прагляду для розных тыпаў файлаў" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi - праграма папярэдняга прагляду файлаў для працоўнага асяроддзя " "GNOME. Гэта незалежны кампанент, які інтэграваны ў «Файлы» GNOME " "(Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Тып" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d элемент" msgstr[1] "%d элементы" msgstr[2] "%d элементаў" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Пустая папка" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Памер" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Дата змянення" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Не ўдалося паказаць %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Адкрыць праз %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Адкрыць" #: src/viewers/audio.js:375 msgid "from" msgstr "альбом: " #: src/viewers/audio.js:380 msgid "by" msgstr "выканаўца: " #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d з %d" 0707010000001A000081A4000000000000000000000001660EE2C800000A70000000000000000000000000000000000000001400000000sushi-46.0/po/bg.po# Bulgarian translation of sushi po-file. # Copyright (C) 2011 Free Software Foundation, Inc. # Copyright (C) 2022 Alexander Shopov <ash@kambanaria.org>. # This file is distributed under the same license as the sushi package. # Ivaylo Valkov <ivaylo@e-valkov.org>, 2011. # Alexander Shopov <ash@kambanaria.org>, 2012, 2022. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2022-02-03 20:58+0000\n" "PO-Revision-Date: 2022-03-28 23:03+0200\n" "Last-Translator: Alexander Shopov <ash@kambanaria.org>\n" "Language-Team: Bulgarian <dict@fsa-bg.org>\n" "Language: bg\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" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Програма за бърз преглед на файлове" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi е програма за преглед на файлове за графичната среда GNOME. Тя е " "компонент, който се интегрира с програмата за управление на файлове " "(Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Вид" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d обект" msgstr[1] "%d обекта" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Празна папка" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Размер" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Променен" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "„%s“ не може да се покаже" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Отваряне с %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Отваряне" #: src/viewers/audio.js:375 msgid "from" msgstr "от" #: src/viewers/audio.js:380 msgid "by" msgstr "на" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d от %d" 0707010000001B000081A4000000000000000000000001660EE2C80000083E000000000000000000000000000000000000001700000000sushi-46.0/po/bn_IN.po# Bengali (India) translation for sushi. # Copyright (C) 2012 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # # Sayak Sarkar <sayak.bugsmith@gmail.com>, 2012. msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" "product=sushi&keywords=I18N+L10N&component=general\n" "POT-Creation-Date: 2012-07-19 02:30+0000\n" "PO-Revision-Date: 2012-07-23 01:54+0530\n" "Last-Translator: Sayak Sarkar <sayak.bugsmith@gmail.com>\n" "Language-Team: Bengali (India) <anubad@lists.ankur.org.in>\n" "Language: bn_IN\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: Lokalize 1.4\n" #: ../data/org.gnome.sushi.gschema.xml.in.h:1 msgid "Client decoration" msgstr "ক্লায়েন্ট অলঙ্কার" #: ../data/org.gnome.sushi.gschema.xml.in.h:2 msgid "Whether the window draws WM decorations itself" msgstr "উইন্ডোটি WM অলঙ্কারাদি নিজেই আঁকে কিনা" #: ../src/js/ui/fallbackRenderer.js:120 msgid "Type" msgstr "প্রকার" #: ../src/js/ui/fallbackRenderer.js:121 ../src/js/ui/fallbackRenderer.js:130 #: ../src/js/ui/fallbackRenderer.js:136 ../src/js/ui/spinnerBox.js:57 msgid "Loading…" msgstr "লোড হচ্ছে …" #: ../src/js/ui/fallbackRenderer.js:129 msgid "Size" msgstr "মাপ" #: ../src/js/ui/fallbackRenderer.js:135 msgid "Modified" msgstr "পরিবর্তিত" #: ../src/js/viewers/audio.js:172 msgid "from" msgstr "থেকে" #: ../src/js/viewers/audio.js:174 msgid "by" msgstr "কর্তৃক" #: ../src/js/viewers/evince.js:79 #, c-format msgid "%d of %d" msgstr "% d এর % d" #: ../src/libsushi/sushi-file-loader.c:639 #, c-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d বস্তু" msgstr[1] "%d বস্তুসমূহ" #: ../src/libsushi/sushi-file-loader.c:651 msgid "Empty Folder" msgstr "খালি ফোল্ডার" 0707010000001C000081A4000000000000000000000001660EE2C800000813000000000000000000000000000000000000001400000000sushi-46.0/po/bs.po# Bosnian translation for bosnianuniversetranslation # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the bosnianuniversetranslation package. # FIRST AUTHOR <EMAIL@ADDRESS>, 2013. # msgid "" msgstr "" "Project-Id-Version: bosnianuniversetranslation\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" "product=sushi&keywords=I18N+L10N&component=general\n" "POT-Creation-Date: 2015-02-26 23:59+0000\n" "PO-Revision-Date: 2013-11-11 10:50+0000\n" "Last-Translator: Josip Juricevic <juricevic@live.com>\n" "Language-Team: Bosnian <bs@li.org>\n" "Language: bs\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" "X-Launchpad-Export-Date: 2014-10-23 07:09+0000\n" "X-Generator: Launchpad (build 17203)\n" #: ../data/org.gnome.sushi.gschema.xml.in.h:1 msgid "Client decoration" msgstr "Klijentskio ukrašavanje" #: ../data/org.gnome.sushi.gschema.xml.in.h:2 msgid "Whether the window draws WM decorations itself" msgstr "Kad prozor ispiše WM ukrasi ga sam" #: ../src/js/ui/fallbackRenderer.js:121 msgid "Type" msgstr "Vrsta" #: ../src/js/ui/fallbackRenderer.js:122 ../src/js/ui/fallbackRenderer.js:131 #: ../src/js/ui/fallbackRenderer.js:137 ../src/js/ui/spinnerBox.js:58 msgid "Loading…" msgstr "Učitavanje…" #: ../src/js/ui/fallbackRenderer.js:130 msgid "Size" msgstr "Veličina" #: ../src/js/ui/fallbackRenderer.js:136 msgid "Modified" msgstr "Izmijenjen" #: ../src/js/viewers/audio.js:173 msgid "from" msgstr "od" #: ../src/js/viewers/audio.js:175 msgid "by" msgstr "sa" #: ../src/js/viewers/evince.js:79 msgid "%d of %d" msgstr "%d od %d" #: ../src/libsushi/sushi-file-loader.c:639 #, c-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d stavka" msgstr[1] "%d stavke" msgstr[2] "%d stavki" #: ../src/libsushi/sushi-file-loader.c:651 msgid "Empty Folder" msgstr "Prazan direktorij" 0707010000001D000081A4000000000000000000000001660EE2C80000098D000000000000000000000000000000000000001400000000sushi-46.0/po/ca.po# Catalan translation for sushi. # Copyright (C) 2011 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # Pau Iranzo <paugnu@gmail.com>, 2011. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 14:15+0000\n" "PO-Revision-Date: 2020-12-19 16:18+0100\n" "Last-Translator: Miquel-Àngel Burgos i Fradeja <miquel.angel." "burgos@gmail.com>\n" "Language-Team: Catalan <tradgnome@softcatala.org>\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: Poedit 2.4.1\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "" "Proporciona la capacitat de veure ràpidament diferents tipus de fitxers" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "El Sushi és un previsualitzador de fitxers per a l'entorn d'escriptori " "GNOME. Es tracta d'un component independent que s'integra amb el " "Fitxers del GNOME (Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Tipus" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d element" msgstr[1] "%d elements" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Carpeta buida" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Mida" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Modificat" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "No s'ha pogut mostrar %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Obre amb %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Obre" #: src/viewers/audio.js:359 msgid "from" msgstr "des de" #: src/viewers/audio.js:364 msgid "by" msgstr "per" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d de %d" 0707010000001E000081A4000000000000000000000001660EE2C800000711000000000000000000000000000000000000001D00000000sushi-46.0/po/ca@valencia.po# Catalan translation for sushi. # Copyright (C) 2011 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # Pau Iranzo <paugnu@gmail.com>, 2011. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?" "product=sushi&keywords=I18N+L10N&component=general\n" "POT-Creation-Date: 2017-04-08 16:24+0000\n" "PO-Revision-Date: 2011-09-15 21:47+0100\n" "Last-Translator: Xavi Ivars <xavi.ivars@gmail.com>\n" "Language-Team: Catalan <tradgnome@softcatala.org>\n" "Language: ca-valencia\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bits\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" #: ../src/js/ui/fallbackRenderer.js:119 msgid "Type" msgstr "Tipus" #: ../src/js/ui/fallbackRenderer.js:120 ../src/js/ui/fallbackRenderer.js:129 #: ../src/js/ui/fallbackRenderer.js:135 ../src/js/ui/spinnerBox.js:56 msgid "Loading…" msgstr "S'està carregant…" #: ../src/js/ui/fallbackRenderer.js:128 msgid "Size" msgstr "Mida" #: ../src/js/ui/fallbackRenderer.js:134 msgid "Modified" msgstr "Modificat" #: ../src/js/viewers/audio.js:172 msgid "from" msgstr "des de" #: ../src/js/viewers/audio.js:174 msgid "by" msgstr "per" #: ../src/js/viewers/evince.js:77 #, javascript-format msgid "%d of %d" msgstr "%d de %d" #: ../src/libsushi/sushi-file-loader.c:639 #, c-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d element" msgstr[1] "%d elements" #: ../src/libsushi/sushi-file-loader.c:651 msgid "Empty Folder" msgstr "Carpeta buida" #~ msgid "Client decoration" #~ msgstr "Decoració del client" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "" #~ "Si la mateixa finestra dibuixa les decoracions del gestor de finestres" 0707010000001F000081A4000000000000000000000001660EE2C800000844000000000000000000000000000000000000001500000000sushi-46.0/po/ckb.po# Kurdish (Sorani) translation for gnome-sushi # Copyright (c) 2020 Rosetta Contributors and Canonical Ltd 2020 # This file is distributed under the same license as the gnome-sushi package. # FIRST AUTHOR <EMAIL@ADDRESS>, 2020. # msgid "" msgstr "" "Project-Id-Version: gnome-sushi\n" "Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" "POT-Creation-Date: 2020-04-16 02:06+0000\n" "PO-Revision-Date: 2020-05-05 00:49+0300\n" "Last-Translator: Jwtiyar Nariman <jwtiyar@gmail.com>\n" "Language-Team: Kurdish (Sorani) <ckb@li.org>\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-Launchpad-Export-Date: 2020-05-04 21:40+0000\n" "X-Generator: Poedit 2.3\n" "Language: ckb\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "سوشی" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "" #: src/ui/fallbackRenderer.js:233 msgid "Type" msgstr "جۆر" #: src/ui/fallbackRenderer.js:243 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d بڕگە" msgstr[1] "%d بڕگە" #: src/ui/fallbackRenderer.js:248 msgid "Empty Folder" msgstr "بوخچەی بەتاڵ" #: src/ui/fallbackRenderer.js:251 msgid "Size" msgstr "قەبارە" #: src/ui/fallbackRenderer.js:256 msgid "Modified" msgstr "دەستکاریکراوە" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "ناتوانرێت %s پیشانبدرێت" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "بیکەرەوە لەڕێگەی %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "کردنەوە" #: src/viewers/audio.js:352 msgid "from" msgstr "لە" #: src/viewers/audio.js:357 msgid "by" msgstr "لەلایەن" #: src/viewers/evince.js:86 #, javascript-format msgid "%d of %d" msgstr "%d لە %d" 07070100000020000081A4000000000000000000000001660EE2C8000009EC000000000000000000000000000000000000001400000000sushi-46.0/po/cs.po# Czech translation for sushi. # Copyright (C) 2011 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # # PW <petr.wudi@gmail.com>, 2011. # Marek Černocký <marek@manet.cz>, 2011, 2012, 2019, 2020. # msgid "" msgstr "" "Project-Id-Version: sushi\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 14:15+0000\n" "PO-Revision-Date: 2020-10-26 19:33+0200\n" "Last-Translator: Marek Černocký <marek@manet.cz>\n" "Language-Team: čeština <gnome-cs-list@gnome.org>\n" "Language: cs\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>=2 && n<=4) ? 1 : 2;\n" "X-Generator: Gtranslator 2.91.7\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Poskytuje příslušenství pro rychlé náhledy různých druhů souborů" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi slouží k zobrazení náhledů souborů v uživatelském prostředí GNOME. " "Jedná se o nezávislou komponentu, která se začleňuje do aplikace Soubory " "GNOME (Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Typ" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d položka" msgstr[1] "%d položky" msgstr[2] "%d položek" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Prázdná složka" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Velikost" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Změněno" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Nelze zobrazit %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Otevřít pomocí %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Otevřít" #: src/viewers/audio.js:359 msgid "from" msgstr "z" #: src/viewers/audio.js:364 msgid "by" msgstr "od" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d z %d" 07070100000021000081A4000000000000000000000001660EE2C8000009B4000000000000000000000000000000000000001400000000sushi-46.0/po/da.po# Danish translation for sushi. # Copyright (C) 2011, 2019 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # Joe Hansen <joedalton2@yahoo.dk>, 2011. # Aputsiaq Niels Janussen <aj@isit.gl>, 2011. # Ask Hjorth Larsen <asklarsen@gmail.com>, 2019. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-23 08:16+0000\n" "PO-Revision-Date: 2021-02-20 00:00+0000\n" "Last-Translator: scootergrisen\n" "Language-Team: Danish <dansk@dansk-gruppen.dk>\n" "Language: da\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" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "En funktion til hurtigt at vise forskellige typer fil" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi er en filforhåndsviser til GNOME-skrivebordsmiljøet. Det er en " "uafhængig komponent som integrerer med GNOME Filer (Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Type" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d element" msgstr[1] "%d elementer" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Tom mappe" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Størrelse" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Ændret" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Kan ikke vise %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Åbn med %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Åbn" #: src/viewers/audio.js:359 msgid "from" msgstr "fra" #: src/viewers/audio.js:364 msgid "by" msgstr "af" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d af %d" 07070100000022000081A4000000000000000000000001660EE2C800000B02000000000000000000000000000000000000001400000000sushi-46.0/po/de.po# German translation for sushi. # Copyright (C) 2011 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # Mario Blättermann <mario.blaettermann@gmail.com>, 2011, 2012. # Gabor Karsay <gabor.karsay@gmx.at>, 2011. # Tim Sabsch <tim@sabsch.com>, 2019. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 14:35+0000\n" "PO-Revision-Date: 2020-10-27 10:51+0100\n" "Last-Translator: Christian Kirbach <christian.kirbach@gmail.com>\n" "Language-Team: German <gnome-de@gnome.org>\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: Poedit 2.4.1\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Verschiedene Arten von Dateien schnell ansehen" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi ist eine Dateivorschau für die GNOME-Arbeitsumgebung. Sie ist eine " "unabhängige Komponente, die sich nahtlos in GNOME Dateien (Nautilus) " "integriert." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Typ" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d Objekt" msgstr[1] "%d Objekte" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Leerer Ordner" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Größe" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Geändert" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "%s kann nicht angezeigt werden" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Mit %s öffnen" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Öffnen" # Kontext: from albumName #: src/viewers/audio.js:359 msgid "from" msgstr "aus" # Kontext: by artistName #: src/viewers/audio.js:364 msgid "by" msgstr "von" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d von %d" #~ msgid "Client decoration" #~ msgstr "Client-seitige Dekoration" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "" #~ "Legt fest, ob das Fenster die Fenstermanager-Dekorationen selbst zeichnet" #~ msgid "Loading…" #~ msgstr "Ladevorgang …" 07070100000023000081A4000000000000000000000001660EE2C800000C39000000000000000000000000000000000000001400000000sushi-46.0/po/el.po# Greek translation for sushi. # Copyright (C) 2012 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # apo <apo.apostolakis.apo@gmail.com>, 2012. # Efstathios Iosifidis <iosifidis@opensuse.org>, 2019. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 14:15+0000\n" "PO-Revision-Date: 2021-04-23 15:15+0300\n" "Last-Translator: Efstathios Iosifidis <eiosifidis@gnome.org>\n" "Language-Team: Greek, Modern (1453-) <gnome-el-list@gnome.org>\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" "X-Generator: Poedit 2.3\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Μια δυνατότητα γρήγορης προβολής διαφόρων ειδών αρχείων" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Το Sushi είναι ένα πρόγραμμα προεπισκόπησης αρχείων για το περιβάλλον " "επιφάνειας εργασίας GNOME. Είναι ένα ανεξάρτητο στοιχείο που ενσωματώνεται " "στο πρόγραμμα Αρχεία GNOME (Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Τύπος" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d αντικείμενο" msgstr[1] "%d αντικείμενα" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Άδειασμα του φακέλου" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Μέγεθος" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Τροποποιήθηκε" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Αδυναμία εμφάνισης %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Άνοιγμα με %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Άνοιγμα" #: src/viewers/audio.js:359 msgid "from" msgstr "του" #: src/viewers/audio.js:364 msgid "by" msgstr "από" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d από %d" #~ msgid "Client decoration" #~ msgstr "Διακόσμηση πελάτη" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "Αν το παράθυρο θα σχεδιάζει διακοσμήσεις του διαχειριστή παραθύρων" #~ msgid "Loading…" #~ msgstr "Φορτώνει…" 07070100000024000081A4000000000000000000000001660EE2C800000A56000000000000000000000000000000000000001700000000sushi-46.0/po/en_GB.po# British English translation of sushu. # Copyright (C) 2011 sushi'S COPYRIGHT HOLDER # This file is distributed under the same licence as the sushi package. # Bruce Cowan <bruce@bcowan.me.uk>, 2011, 2012. # Zander Brown <zbrown@gnome.org>, 2019-2021. # msgid "" msgstr "" "Project-Id-Version: sushi\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-23 08:16+0000\n" "PO-Revision-Date: 2021-02-16 22:24+0000\n" "Last-Translator: Zander Brown <zbrown@gnome.org>\n" "Language-Team: English - United Kingdom <en_GB@li.org>\n" "Language: en_GB\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: Gtranslator 3.38.0\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Provide a facility for quickly viewing different kinds of files" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Type" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d item" msgstr[1] "%d items" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Empty Folder" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Size" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Modified" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Unable to display %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Open With %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Open" #: src/viewers/audio.js:359 msgid "from" msgstr "from" #: src/viewers/audio.js:364 msgid "by" msgstr "by" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d of %d" #~ msgid "Client decoration" #~ msgstr "Client decoration" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "Whether the window draws WM decorations itself" #~ msgid "Loading…" #~ msgstr "Loading…" 07070100000025000081A4000000000000000000000001660EE2C8000009B9000000000000000000000000000000000000001400000000sushi-46.0/po/eo.po# Esperanto translation for sushi. # Copyright (C) 2011 Free Software Foundation, Inc. # This file is distributed under the same license as the sushi package. # Kristjan SCHMIDT <kristjan.schmidt@googlemail.com>, 2011. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2023-06-29 22:30+0000\n" "PO-Revision-Date: 2023-09-20 22:55+0200\n" "Last-Translator: Kristjan SCHMIDT <kristjan.schmidt@googlemail.com>\n" "Language-Team: Esperanto <gnome-eo-list@gnome.org>\n" "Language: eo\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: Poedit 3.2.2\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Suŝio" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "" "Provizi instalaĵon por rapide vidi malsamajn specojn de dosieroj" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Suŝio estas dosiero-antaŭrigardilo por la labortabla medio GNOME. Ĝi " "estas sendependa komponanto, kiu integriĝas kun GNOME-dosieroj " "(Nautilo)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Tipo" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d elemento" msgstr[1] "%d elementoj" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Malplena dosierujo" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Grando" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Modifite" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Ne eblas montri %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:358 #, javascript-format msgid "Open With %s" msgstr "Malfermi per %s" #: src/ui/mainWindow.js:364 msgid "Open" msgstr "Malfermi" #: src/viewers/audio.js:375 msgid "from" msgstr "de" #: src/viewers/audio.js:380 msgid "by" msgstr "de" #: src/viewers/evince.js:103 #, javascript-format msgid "%d of %d" msgstr "%d de %d" #~ msgid "Loading…" #~ msgstr "Ŝargante…" 07070100000026000081A4000000000000000000000001660EE2C800000A91000000000000000000000000000000000000001400000000sushi-46.0/po/es.po# Spanish translation for sushi. # Copyright (C) 2011 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # Daniel Mustieles <daniel.mustieles@gmail.com>, 2011-2020. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 14:15+0000\n" "PO-Revision-Date: 2020-12-02 13:00+0100\n" "Last-Translator: Daniel Mustieles <daniel.mustieles@gmail.com>\n" "Language-Team: Spanish - Spain <gnome-es-list@gnome.org>\n" "Language: es_ES\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: Gtranslator 3.38.0\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "" "Proporciona la posibilidad de ver rápidamente diferentes tipos de archivos" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi es un previsualizador de archivos para el entorno de escritorio GNOME. " "Es un componente independiente que se integra con Archivos de GNOME " "(Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Tipo" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d elemento" msgstr[1] "%d elementos" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Vaciar carpeta" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Tamaño" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Modificada" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "No se puede mostrar %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Abrir con %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Abrir" #: src/viewers/audio.js:359 msgid "from" msgstr "desde" #: src/viewers/audio.js:364 msgid "by" msgstr "por" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d de %d" #~ msgid "Client decoration" #~ msgstr "Decoración del cliente" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "Indica si la ventana dibuja decoraciones WM por sí misma" #~ msgid "Loading…" #~ msgstr "Cargando…" 07070100000027000081A4000000000000000000000001660EE2C80000052A000000000000000000000000000000000000001400000000sushi-46.0/po/et.po# Sushi eesti keele tõlge. # Estonian translation for sushi. # # Copyright (C) 2011 The GNOME Project. # This file is distributed under the same license as the sushi package. # Mattias Põldaru <mahfiaz@gmail.com>, 2011, 2012. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" "product=sushi&keywords=I18N+L10N&component=general\n" "POT-Creation-Date: 2012-09-22 15:45+0000\n" "PO-Revision-Date: 2012-08-21 09:19+0300\n" "Last-Translator: Mattias Põldaru <mahfiaz@gmail.com>\n" "Language-Team: Estonian <gnome-et@linux.ee>\n" "Language: et\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" msgid "Client decoration" msgstr "Kliendi dekoratsioonid" msgid "Whether the window draws WM decorations itself" msgstr "Kas aken joonistab aknahalduri dekoratsioonid ise" msgid "Type" msgstr "Liik" msgid "Loading…" msgstr "Laadimine…" msgid "Size" msgstr "Suurus" msgid "Modified" msgstr "Muudeti" msgid "from" msgstr "album" msgid "by" msgstr "esitaja" #, c-format msgid "%d of %d" msgstr "%d / %d" #, c-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d element" msgstr[1] "%d elementi" msgid "Empty Folder" msgstr "Tühi kaust" 07070100000028000081A4000000000000000000000001660EE2C800000AEF000000000000000000000000000000000000001400000000sushi-46.0/po/eu.po# Basque translation for sushi. # Copyright (C) 2011 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # Julen Ruiz Aizpuru <julenx@gmail.com>, 2011, 2013. # Iñaki Larrañaga Murgoitio <dooteo@zundan.com>, 2013, 2014. # Asier Sarasua Garmendia <asier.sarasua@gmail.com>, 2019. # msgid "" msgstr "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 14:35+0000\n" "PO-Revision-Date: 2020-10-29 10:00+0100\n" "Last-Translator: Asier Sarasua Garmendia <asiersarasua@ni.eus>\n" "Language-Team: Basque <librezale@librezale.eus>\n" "Language: eu\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-Project-Style: gnome\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Fitxategi mota desberdinak azkar bistaratzeko tresna bat" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "Sushi fitxategien aurrebistak ikusteko aplikazio bat da, GNOME mahaigain-ingurunerako sortua. Osagai independentea da, GNOME Fitxategiak (Nautilus) aplikazioan integratzen dena." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Mota" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "Elementu %d" msgstr[1] "%d elementu" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Karpeta hutsa" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Tamaina" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Aldatze-data" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Ezin da %s erakutsi" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Ireki honekin: %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Ireki" #: src/viewers/audio.js:359 msgid "from" msgstr "diskoa:" #: src/viewers/audio.js:364 msgid "by" msgstr "egilea:" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d / %d" #~ msgid "Client decoration" #~ msgstr "Bezeroaren dekorazioa" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "Leihoak leiho-kudeatzailearen dekorazioak marraztuko dituen edo ez" #~ msgid "Loading…" #~ msgstr "Kargatzen…" 07070100000029000081A4000000000000000000000001660EE2C800000B48000000000000000000000000000000000000001400000000sushi-46.0/po/fa.po# Persian translation for sushi. # Copyright (C) 2011 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # Arash Mousavi <mousavi.arash@gmail.com>, 2012. # Danial Behzadi <dani.behzi@ubuntu.com>, 2013-2021. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 14:15+0000\n" "PO-Revision-Date: 2021-01-22 13:59+0000\n" "Last-Translator: Danial Behzadi <dani.behzi@ubuntu.com>\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=1; plural=0;\n" "X-Poedit-SourceCharset: utf-8\n" "X-Generator: Poedit 2.4.2\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "سوشی" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "امکانی برای دیدن سریع گونههای مختلف پروندهها فراهم میکند" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "سوشی یک پیشنمای پرونده برای محیط میزکار گنوم است. مولّفهای مستقل که با " "پروندههای گنوم (ناتیلوس) یکپارچه میشود." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "گونه" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%Id مورد" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "شاخهٔ خالی" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "اندازه" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "تغییر یافته" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "ناتوان در نمایش %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "گشودن با %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "گشودن" #: src/viewers/audio.js:359 msgid "from" msgstr "از" #: src/viewers/audio.js:364 msgid "by" msgstr "با" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%Id از %Id" #~ msgid "Client decoration" #~ msgstr "آرایش کارگیر" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "اینکه آیا پنجره آریشهای WM را خودش میکشد یا خیر" #~ msgid "Loading…" #~ msgstr "در حال بارگیری" 0707010000002A000081A4000000000000000000000001660EE2C800000AC5000000000000000000000000000000000000001400000000sushi-46.0/po/fi.po# Finnish translation for sushi. # Copyright (C) 2012 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # # Gnome 2012-03 Finnish translation sprint participants: # Niklas Laxström # artnay <jiri.gronroos@iki.fi>, 2012. msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 14:35+0000\n" "PO-Revision-Date: 2020-12-13 10:38+0200\n" "Last-Translator: Jiri Grönroos <jiri.gronroos+l10n@iki.fi>\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: Poedit 2.4.2\n" "X-POT-Import-Date: 2012-02-19 15:25:28+0000\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Tarjoaa mahdollisuuden katsella nopeasti erilaisia tiedostoja" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi on tiedostojen esikatselukseen tarkoitettu sovellus Gnome-" "työpöydälle. Se on itsenäinen komponentti, joka integroituu osaksi " "Gnomen tiedostonhallintaa (Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Tyyppi" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d kohde" msgstr[1] "%d kohdetta" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Tyhjä kansio" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Koko" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Muokattu" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Ei voitu näyttää %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Avaa sovelluksella %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Avaa" #: src/viewers/audio.js:359 msgid "from" msgstr "albumilta" #: src/viewers/audio.js:364 msgid "by" msgstr "esittää" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d/%d" #~ msgid "Client decoration" #~ msgstr "Ikkunan reunukset" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "Piirtääkö ikkuna ikkunanhallinan reunukset itse" #~ msgid "Loading…" #~ msgstr "Ladataan…" 0707010000002B000081A4000000000000000000000001660EE2C800000AEF000000000000000000000000000000000000001400000000sushi-46.0/po/fr.po# French translation for sushi. # Copyright (C) 2011-2019 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # Alexandre Franke <alexandre.franke@gmail.com>, 2011. # Charles Monzat <charles.monzat@free.fr>, 2019. # Julien Humbert <julroy67@gmail.com>, 2019. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 14:35+0000\n" "PO-Revision-Date: 2020-10-22 23:30+0200\n" "Last-Translator: Guillaume Bernard <associations@guillaume-bernard.fr>\n" "Language-Team: GNOME French Team <gnomefr@traduc.org>\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: Poedit 2.4.1\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Fournit un moyen pour voir rapidement différents types de fichiers" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi est un outil de prévisualisation pour l’environnement de bureau " "GNOME. C’est un composant indépendant qui s’intègre avec Fichiers de " "GNOME (Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Type" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d élément" msgstr[1] "%d éléments" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Dossier vide" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Taille" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Modifié" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Impossible d’afficher %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Ouvrir avec %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Ouvrir" #: src/viewers/audio.js:359 msgid "from" msgstr "de" #: src/viewers/audio.js:364 msgid "by" msgstr "par" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d sur %d" #~ msgid "Client decoration" #~ msgstr "Décoration du client" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "Indique si la fenêtre dessine les décorations du WM elle-même" #~ msgid "Loading…" #~ msgstr "Chargement…" 0707010000002C000081A4000000000000000000000001660EE2C800000A4B000000000000000000000000000000000000001500000000sushi-46.0/po/fur.po# Friulian translation for sushi. # Copyright (C) 2012 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # TmTFx <f.t.public@gmail.com>, 2012. # msgid "" msgstr "" "Project-Id-Version: sushi gnome-3-6\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-23 08:16+0000\n" "PO-Revision-Date: 2020-11-19 04:26+0100\n" "Last-Translator: Fabio Tomat <f.t.public@gmail.com>\n" "Language-Team: Friulian <fur@li.org>\n" "Language: fur\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: Poedit 2.4.1\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Furnìs une funzion par viodi subite diferents gjenars di files" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi al è un program pal ambient di scritori GNOME, che al mostre " "une anteprime dai file. Al è un component indipendent che si integre " "cun GNOME Files (Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Gjenar" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d element" msgstr[1] "%d elements" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Cartele Vueide" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Dimension" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Modificât" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Impussibil mostrâ %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Vierç cun %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Vierç" #: src/viewers/audio.js:359 msgid "from" msgstr "di" #: src/viewers/audio.js:364 msgid "by" msgstr "di" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d di %d" #~ msgid "Client decoration" #~ msgstr "Decorazion Client" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "Se il barcon al disegne di besôl lis decorazions dal WM" #~ msgid "Loading…" #~ msgstr "Cjariament…" 0707010000002D000081A4000000000000000000000001660EE2C8000006D7000000000000000000000000000000000000001400000000sushi-46.0/po/gd.po# Scottish Gaelic translation for sushi. # Copyright (C) 2015 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # GunChleoc <fios@foramnagaidhlig.net>, 2015, 2018. msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=sushi" "&keywords=I18N+L10N&component=general\n" "POT-Creation-Date: 2017-04-08 16:24+0000\n" "PO-Revision-Date: 2018-02-23 17:35+0100\n" "Last-Translator: GunChleoc <fios@foramnagaidhlig.net>\n" "Language-Team: Fòram na Gàidhlig\n" "Language: gd\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : " "(n > 2 && n < 20) ? 2 : 3;\n" "X-Generator: Virtaal 0.7.1\n" "X-Project-Style: gnome\n" #: ../src/js/ui/fallbackRenderer.js:119 msgid "Type" msgstr "Seòrsa" #: ../src/js/ui/fallbackRenderer.js:120 ../src/js/ui/fallbackRenderer.js:129 #: ../src/js/ui/fallbackRenderer.js:135 ../src/js/ui/spinnerBox.js:56 msgid "Loading…" msgstr "’Ga luchdadh…" #: ../src/js/ui/fallbackRenderer.js:128 msgid "Size" msgstr "Meud" #: ../src/js/ui/fallbackRenderer.js:134 msgid "Modified" msgstr "Air atharrachadh" #: ../src/js/viewers/audio.js:172 msgid "from" msgstr "o" #: ../src/js/viewers/audio.js:174 msgid "by" msgstr "le" #: ../src/js/viewers/evince.js:77 #, javascript-format msgid "%d of %d" msgstr "%d à %d" #: ../src/libsushi/sushi-file-loader.c:639 #, c-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d nì" msgstr[1] "%d nì" msgstr[2] "%d nithean" msgstr[3] "%d nì" #: ../src/libsushi/sushi-file-loader.c:651 msgid "Empty Folder" msgstr "Pasgan falamh" 0707010000002E000081A4000000000000000000000001660EE2C800000ADF000000000000000000000000000000000000001400000000sushi-46.0/po/gl.po# Galician translations for PACKAGE package. # Copyright (C) 2011 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # fran <frandieguez@gnome.org>, 2011. # Fran Diéguez <frandieguez@gnome.org>, 2011. # Fran Dieguez <frandieguez@gnome.org>, 2011-2021. # msgid "" msgstr "" "Project-Id-Version: sushi\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2021-02-22 07:58+0000\n" "PO-Revision-Date: 2021-01-25 20:26+0100\n" "Last-Translator: Fran Dieguez <frandieguez@gnome.org>\n" "Language-Team: Proxecto Trasno <proxecto@trasno.gal>\n" "Language: gl\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: Gtranslator 3.38.0\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "" "Fornece a capacidade de ver de forma rápida diferentes tipos de ficheiros" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi é un previsualizador de ficheiros para o ambiente de escritorio de " "GNOME. É un compoñente independente que se integra con Ficheiros de GNOME " "(Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Tipo" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d elemento" msgstr[1] "%d elementos" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Cartafol baleiro" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Tamaño" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Modificada" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Non foi posíbel mostrar %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Abrir con %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Abrir" #: src/viewers/audio.js:359 msgid "from" msgstr "desde" #: src/viewers/audio.js:364 msgid "by" msgstr "por" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d de %d" #~ msgid "Client decoration" #~ msgstr "Decoración do cliente" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "Indica se a xanela debuxa decoracións WM por si mesma" #~ msgid "Loading…" #~ msgstr "Cargando…" 0707010000002F000081A4000000000000000000000001660EE2C8000007DF000000000000000000000000000000000000001400000000sushi-46.0/po/gu.po# Gujarati translation for sushi. # Copyright (C) 2012 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # # , 2012. msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug." "cgi?product=sushi&keywords=I18N+L10N&component=general\n" "POT-Creation-Date: 2012-07-19 02:30+0000\n" "PO-Revision-Date: 2012-07-27 14:44+0530\n" "Last-Translator: \n" "Language-Team: gu_IN <kde-i18n-doc@kde.org>\n" "Language: gu\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: Lokalize 1.0\n" #: ../data/org.gnome.sushi.gschema.xml.in.h:1 msgid "Client decoration" msgstr "ક્લાયન્ટ સજાવટ" #: ../data/org.gnome.sushi.gschema.xml.in.h:2 msgid "Whether the window draws WM decorations itself" msgstr "શું વિન્ડો પોતાની જાતે WM સજાવટને દોરે છે" #: ../src/js/ui/fallbackRenderer.js:120 msgid "Type" msgstr "પ્રકાર" #: ../src/js/ui/fallbackRenderer.js:121 ../src/js/ui/fallbackRenderer.js:130 #: ../src/js/ui/fallbackRenderer.js:136 ../src/js/ui/spinnerBox.js:57 msgid "Loading…" msgstr "લાવી રહ્યા છે…" #: ../src/js/ui/fallbackRenderer.js:129 msgid "Size" msgstr "માપ" #: ../src/js/ui/fallbackRenderer.js:135 msgid "Modified" msgstr "ફેરફાર કરેલું" #: ../src/js/viewers/audio.js:172 msgid "from" msgstr "માંથી" #: ../src/js/viewers/audio.js:174 msgid "by" msgstr "દ્દારા" #: ../src/js/viewers/evince.js:79 #, c-format msgid "%d of %d" msgstr "%d નું %d" #: ../src/libsushi/sushi-file-loader.c:639 #, c-format msgid "%d item" msgid_plural "%d items" msgstr[0] "૧ વસ્તુ" msgstr[1] "%d વસ્તુઓ" #: ../src/libsushi/sushi-file-loader.c:651 msgid "Empty Folder" msgstr "ખાલી ફોલ્ડર" 07070100000030000081A4000000000000000000000001660EE2C800000B8E000000000000000000000000000000000000001400000000sushi-46.0/po/he.po# Hebrew translations for PACKAGE package. # Copyright (C) 2011 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Yaron Shahrabani <sh.yaron@gmail.com>, 2011. # Yosef Or Boczko <yoseforb@gmail.com>, 2020-2021. # msgid "" msgstr "" "Project-Id-Version: Sushi\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-23 08:16+0000\n" "PO-Revision-Date: 2021-03-29 02:32+0300\n" "Last-Translator: Yosef Or Boczko <yoseforb@gmail.com>\n" "Language-Team: Hebrew <yoseforb@gmail.com>\n" "Language: he\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>2||n==0) ? 1 : 2\n" "X-Poedit-Language: Hebrew\n" "X-Poedit-Country: ISRAEL\n" "X-Poedit-SourceCharset: UTF-8\n" "X-Generator: Gtranslator 3.38.0\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "מספק אמצעי להצגה מהירה של מגוון קבצים" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi הוא מציג תצוגה מקדימה של קבצים עבור שולחן העבודה GNOME. זהו רכיב עצמאי " "שמשתלב עם יישום הקבצים של GNOME (Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "סוג" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "פריט אחד" msgstr[1] "%d פריטים" msgstr[2] "%d פריטים" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "תיקייה ריקה" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "גודל" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "מועד השינוי" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "לא נתן להציג את %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "פתיחה באמצעות %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "פתיחה" #: src/viewers/audio.js:359 msgid "from" msgstr "מאת" #: src/viewers/audio.js:364 msgid "by" msgstr "על ידי" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d מתוך %d" #~ msgid "Client decoration" #~ msgstr "Client decoration" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "Whether the window draws WM decorations itself" #~ msgid "Loading…" #~ msgstr "בטעינה…" 07070100000031000081A4000000000000000000000001660EE2C800000BD8000000000000000000000000000000000000001400000000sushi-46.0/po/hi.po# Hindi translation for sushi. # Copyright (C) 2011-2020 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # Panwar108 <caspian7pena@gmail.com>, 2020. # Hemish <hemish04082005@gmail.com>, 2022. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 14:15+0000\n" "PO-Revision-Date: 2022-12-07 08:34+0530\n" "Last-Translator: Hemish <hemish04082005@gmail.com>\n" "Language-Team: Hindi <indlinux-hindi@lists.sourceforge.net https://indlinux." "org/hindi>\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" "X-Generator: Gtranslator 42.0\n" "X-Language: hi_IN\n" "X-Source-Language: en\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "सुशी" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "यह विभिन्न प्रकार की फाइलें शीघ्रता से देखने हेतु साधन प्रदान करता है।" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "सुशी गनोम डेस्कटॉप वातावरण के लिए एक फ़ाइल पूर्वावलोकनकर्ता है। यह एक स्वतंत्र घटक है जो " "गनोम फाइल (नॉटिलस) के साथ एकीकृत हो जाता है।" #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "प्रकार" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d वस्तु" msgstr[1] "%d वस्तुएँ" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "रिक्त फोल्डर" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "आकार" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "परिवर्तित" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "%s प्रदर्शित करने में विफल" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "%s द्वारा खोलें" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "खोलें" #: src/viewers/audio.js:359 msgid "from" msgstr "से" #: src/viewers/audio.js:364 msgid "by" msgstr "द्वारा" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d का %d" 07070100000032000081A4000000000000000000000001660EE2C8000009B1000000000000000000000000000000000000001400000000sushi-46.0/po/hr.po# Croatian translation for sushi. # Copyright (C) 2017 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 14:35+0000\n" "PO-Revision-Date: 2020-10-30 11:29+0100\n" "Last-Translator: gogo <trebelnik2@gmail.com>\n" "Language-Team: Croatian <hr@li.org>\n" "Language: hr\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" "X-Generator: Poedit 2.3\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Omogućuje brz pregled različitih vrsta datoteka" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi je brzi preglednik za GNOME radno okruženje. On je jedinstvena " "komponenta koja je integrirana u GNOME Datoteke (Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Vrsta" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d stavka" msgstr[1] "%d stavke" msgstr[2] "%d stavaka" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Prazna mapa" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Veličina" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Promijenjeno" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Nemoguće je prikazati %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Otvori s(a) %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Otvori" #: src/viewers/audio.js:359 msgid "from" msgstr "iz" #: src/viewers/audio.js:364 msgid "by" msgstr "od" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d od %d" #~ msgid "Loading…" #~ msgstr "Učitavanje..." 07070100000033000081A4000000000000000000000001660EE2C800000A13000000000000000000000000000000000000001400000000sushi-46.0/po/hu.po# Hungarian translation for sushi. # Copyright (C) 2011, 2012, 2019, 2021 Free Software Foundation, Inc. # This file is distributed under the same license as the sushi package. # # Gabor Kelemen <kelemeng at gnome dot hu>, 2011, 2012. # Balázs Úr <ur.balazs at fsf dot hu>, 2019, 2021. # Balázs Meskó <mesko.balazs at fsf dot hu>, 2021. msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 14:15+0000\n" "PO-Revision-Date: 2021-02-14 01:22+0100\n" "Last-Translator: Balázs Meskó <mesko.balazs at fsf dot hu>\n" "Language-Team: Hungarian <gnome-hu-list at gnome dot org>\n" "Language: hu\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: Lokalize 19.12.3\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Lehetőség biztosítása különféle típusú fájlok gyors megtekintéséhez" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "A Sushi egy fájlelőnézet-készítő a GNOME asztali környezethez. Egy " "független összetevő, amely a GNOME Fájlokba (Nautilusba) épül be." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Típus" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d elem" msgstr[1] "%d elem" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Üres mappa" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Méret" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Módosítva" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Nem jeleníthető meg: %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Megnyitás ezzel: %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Megnyitás" #: src/viewers/audio.js:359 msgid "from" msgstr "ettől:" #: src/viewers/audio.js:364 msgid "by" msgstr "–" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d / %d" 07070100000034000081A4000000000000000000000001660EE2C80000099D000000000000000000000000000000000000001400000000sushi-46.0/po/id.po# Indonesian translation for sushi. # Copyright (C) 2011 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # # Andika Triwidada <andika@gmail.com>, 2011, 2012. # Dirgita <dirgitadevina@yahoo.co.id>, 2012. # Kukuh Syafaat <kukuhsyafaat@gnome.org>, 2019. msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 14:35+0000\n" "PO-Revision-Date: 2020-11-08 21:06+0700\n" "Last-Translator: Kukuh Syafaat <kukuhsyafaat@gnome.org>\n" "Language-Team: Indonesian <gnome@i15n.org>\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: Poedit 2.4.1\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Menyediakan fasilitas untuk melihat berbagai jenis berkas dengan cepat" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi adalah pratinjau berkas untuk lingkungan desktop GNOME. Ini adalah " "komponen independen yang terintegrasi dengan GNOME Berkas (Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Jenis" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d butir" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Folder Kosong" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Ukuran" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Diubah" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Tidak dapat menampilkan %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Buka Dengan %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Buka" #: src/viewers/audio.js:359 msgid "from" msgstr "dari" #: src/viewers/audio.js:364 msgid "by" msgstr "oleh" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d dari %d" 07070100000035000081A4000000000000000000000001660EE2C800000913000000000000000000000000000000000000001400000000sushi-46.0/po/ie.po# Interlingue translation for sushi. # Copyright (C) 2022 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # Olga Smirnova <mistresssilvara@hotmail.com>, 2022. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2022-09-18 08:19+0000\n" "PO-Revision-Date: 2022-12-10 03:44+0700\n" "Last-Translator: \n" "Language-Team: Interlingue <ie@li.org>\n" "Language: ie\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: Poedit 3.1.1\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Provide rapid prevision por different tipes de files" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi es un visor de files por li ambientie GNOME. It es un " "índependent componente quel integra con Files GNOME (Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Tip" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d element" msgstr[1] "%d elementes" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Vacui fólder" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Grandore" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Modificat" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Ne successat monstrar %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Aperter per %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Aperter" #: src/viewers/audio.js:375 msgid "from" msgstr "de" #: src/viewers/audio.js:380 msgid "by" msgstr "de" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d ex %d" 07070100000036000081A4000000000000000000000001660EE2C80000073C000000000000000000000000000000000000001400000000sushi-46.0/po/is.po# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Sveinn í Felli <sv1@fellsnet.is>, 2015. msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" "product=sushi&keywords=I18N+L10N&component=general\n" "POT-Creation-Date: 2015-03-25 12:12+0000\n" "PO-Revision-Date: 2015-04-09 17:50+0000\n" "Last-Translator: Sveinn í Felli <sv1@fellsnet.is>\n" "Language-Team: Icelandic <translation-team-is@lists.sourceforge.net>\n" "Language: is\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: Lokalize 1.5\n" #: ../data/org.gnome.sushi.gschema.xml.in.h:1 msgid "Client decoration" msgstr "Skreyting biðlara" #: ../data/org.gnome.sushi.gschema.xml.in.h:2 msgid "Whether the window draws WM decorations itself" msgstr "Hvort glugginn teikni WM gluggaskreytingar sjálfur" #: ../src/js/ui/fallbackRenderer.js:121 msgid "Type" msgstr "Gerð" #: ../src/js/ui/fallbackRenderer.js:122 ../src/js/ui/fallbackRenderer.js:131 #: ../src/js/ui/fallbackRenderer.js:137 ../src/js/ui/spinnerBox.js:58 msgid "Loading…" msgstr "Hleð inn…" #: ../src/js/ui/fallbackRenderer.js:130 msgid "Size" msgstr "Stærð" #: ../src/js/ui/fallbackRenderer.js:136 msgid "Modified" msgstr "Breytt" #: ../src/js/viewers/audio.js:173 msgid "from" msgstr "frá" #: ../src/js/viewers/audio.js:175 msgid "by" msgstr "um" #: ../src/js/viewers/evince.js:79 #, javascript-format msgid "%d of %d" msgstr "%d af %d" #: ../src/libsushi/sushi-file-loader.c:639 #, c-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d atriði" msgstr[1] "%d atriði" #: ../src/libsushi/sushi-file-loader.c:651 msgid "Empty Folder" msgstr "Tóm mappa" 07070100000037000081A4000000000000000000000001660EE2C8000009A9000000000000000000000000000000000000001400000000sushi-46.0/po/it.po# Italian translation for sushi # Copyright (C) 2011, 2012, 2019, 2020 Free Software Foundation, Inc # This file is distributed under the same license as the sushi package. # Luca Ferretti <lferrett@gnome.org>, 2011. # Milo Casagrande <milo@milo.name>, 2012, 2019, 2020. # msgid "" msgstr "" "Project-Id-Version: sushi\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 14:35+0000\n" "PO-Revision-Date: 2020-11-16 09:44+0100\n" "Last-Translator: Milo Casagrande <milo@milo.name>\n" "Language-Team: Italian <tp@lists.linux.it>\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: Poedit 2.4.1\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Fornisce un sistema per visualizzare velocemente file diversi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi è un'applicazione per la visualizzazione di anteprime di file per " "l'ambiente GNOME. È un componente indipendente che si integra con File di " "GNOME (Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Tipo" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d oggetto" msgstr[1] "%d oggetti" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Cartella vuota" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Dimensione" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Ultima modifica" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Impossibile visualizzare %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Apri con %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Apri" #: src/viewers/audio.js:359 msgid "from" msgstr "da" #: src/viewers/audio.js:364 msgid "by" msgstr "di" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d di %d" 07070100000038000081A4000000000000000000000001660EE2C800000B43000000000000000000000000000000000000001400000000sushi-46.0/po/ja.po# sushi ja.po. # Copyright (C) 2011-2019 Free Software Foundation, Inc. # This file is distributed under the same license as the sushi package. # Takeshi AIHANA <takeshi.aihana@gmail.com>, 2011. # Jiro Matsuzawa <jmatsuzawa@src.gnome.org>, 2012. # Takayuki KUSANO <AE5T-KSN@asahi-net.or.jp>, 2012. # sicklylife <translation@sicklylife.jp>, 2019. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-23 08:16+0000\n" "PO-Revision-Date: 2020-12-19 15:30+0900\n" "Last-Translator: sicklylife <translation@sicklylife.jp>\n" "Language-Team: Japanese <gnome-translation@gnome.gr.jp>\n" "Language: ja\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" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "さまざまな種類のファイルを素早く表示できるようにします" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi は GNOME デスクトップ環境向けのファイルプレビューアーで、GNOME " "のファイルマネージャー (Nautilus) の機能を補う独自コンポーネントです。" #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "種類" # sushi #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d 個のアイテム" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "空のフォルダー" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "サイズ" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "更新日時" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "%s を表示できません" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "%s で開く" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "開く" #: src/viewers/audio.js:359 msgid "from" msgstr "(アルバム)" #: src/viewers/audio.js:364 msgid "by" msgstr "(アーティスト)" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d / %d" #~ msgid "Client decoration" #~ msgstr "クライアントで装飾" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "ウインドウが自分自身で WM 装飾を描画するかどうか" #~ msgid "Loading…" #~ msgstr "読み込み中…" 07070100000039000081A4000000000000000000000001660EE2C800000ADE000000000000000000000000000000000000001400000000sushi-46.0/po/ka.po# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2022-05-06 10:02+0000\n" "PO-Revision-Date: 2022-06-30 15:15+0200\n" "Last-Translator: Temuri Doghonadze <temuri.doghonadze@gmail.com>\n" "Language-Team: \n" "Language: ka\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: Poedit 3.1\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "სხვადასხვა ტიპის ფაილების ნახვა" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi არის ფაილის წინასწარი გადამხედველი GNOME სამუშაო გარემოსთვის. " "ეს არის დამოუკიდებელი კომპონენტი, რომელიც ინტეგრირდება GNOME " "ფაილებთან (Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "ტიპი" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d ელემენტი" msgstr[1] "%d ელემენტი" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "ცარიელი საქაღალდე" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "ზომა" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "შეცვლილია" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "%s-ის ჩვენების შეცდომა" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "%s-ით გახსნა" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "გახსნა" #: src/viewers/audio.js:375 msgid "from" msgstr "-დან" #: src/viewers/audio.js:380 msgid "by" msgstr "-ის მიერ" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d-დან %d" 0707010000003A000081A4000000000000000000000001660EE2C8000009BA000000000000000000000000000000000000001500000000sushi-46.0/po/kab.po# Kabyle translation for sushi. # Copyright (C) 2024 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # ButterflyOfFire <ButterflyOfFire@protonmail.com>, 2024. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues/\n" "POT-Creation-Date: 2024-03-23 15:15+0000\n" "PO-Revision-Date: 2024-03-29 10:33+0100\n" "Last-Translator: sa\n" "Language-Team: Kabyle <>\n" "Language: kab\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-DL-Team: kab\n" "X-DL-Module: sushi\n" "X-DL-Branch: master\n" "X-DL-Domain: po\n" "X-DL-State: Translating\n" "X-Generator: Poedit 3.4.2\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "" "Amuddu n tmahilt yessirigen timeẓriwt tuzribt n wanawen yemgaraden n " "yifuyla" #: data/org.gnome.NautilusPreviewer.appdata.xml.in.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi d ameskan n yifuyla i temnaḍt n tnarit n GNOME. D isger ilelli " "iselɣen ɣef yifuyla n GNOME (Nautilus)." #: src/ui/fallbackRenderer.js:244 msgid "Type" msgstr "Anaw" #: src/ui/fallbackRenderer.js:254 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d uferdis" msgstr[1] "%d yiferdisen" #: src/ui/fallbackRenderer.js:259 msgid "Empty Folder" msgstr "Akaram d ilem" #: src/ui/fallbackRenderer.js:263 msgid "Size" msgstr "Teɣzi" #: src/ui/fallbackRenderer.js:269 msgid "Modified" msgstr "Yettubeddel" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "D awezɣi ad yettwaskan %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:358 #, javascript-format msgid "Open With %s" msgstr "Ldi s %s" #: src/ui/mainWindow.js:364 msgid "Open" msgstr "Ldi" #: src/viewers/audio.js:401 msgid "from" msgstr "sɣur" #: src/viewers/audio.js:406 msgid "by" msgstr "s" #: src/viewers/evince.js:111 #, javascript-format msgid "%d of %d" msgstr "%d ɣef %d" 0707010000003B000081A4000000000000000000000001660EE2C800000B44000000000000000000000000000000000000001400000000sushi-46.0/po/kk.po# Kazakh translation for sushi. # Copyright (C) 2014 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # Baurzhan Muftakhidinov <baurthefirst@gmail.com>, 2014-2021. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2021-04-23 12:16+0000\n" "PO-Revision-Date: 2021-08-30 13:33+0500\n" "Last-Translator: Baurzhan Muftakhidinov <baurthefirst@gmail.com>\n" "Language-Team: Kazakh <kk@li.org>\n" "Language: kk\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: Poedit 3.0\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Суши" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Әр түрлі файлдарды жылдам карауды қамтамасыз ету" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi — GNOME жұмыс үстелі ортасына арналған файлды алдын ала қарау " "құралы. Ол GNOME файлдарымен (Nautilus) интеграцияланатын дербес " "компонент." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Түрі" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d нәрсе" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Бос бума" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Өлшемі" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Өзгертілген" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "%s көрсету мүмкін емес" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "%s көмегімен ашу" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Ашу" #: src/viewers/audio.js:359 msgid "from" msgstr "альбомнан" #: src/viewers/audio.js:364 msgid "by" msgstr "орындайтын" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d, барлығы %d" #~ msgid "Client decoration" #~ msgstr "Клиент безендіруі" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "Терезе ТБ безендіруін өздігінен салу керек пе" #~ msgid "Loading…" #~ msgstr "Жүктеу…" 0707010000003C000081A4000000000000000000000001660EE2C80000083E000000000000000000000000000000000000001400000000sushi-46.0/po/kn.po# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Shankar Prasad <svenkate@redhat.com>, 2012. msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=" "sushi&keywords=I18N+L10N&component=general\n" "POT-Creation-Date: 2012-12-07 15:01+0000\n" "PO-Revision-Date: 2012-12-10 12:21-0500\n" "Last-Translator: Shankar Prasad <svenkate@redhat.com>\n" "Language-Team: Kannada <kde-i18n-doc@kde.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: kn\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Zanata 3.2.3\n" #: ../data/org.gnome.sushi.gschema.xml.in.h:1 msgid "Client decoration" msgstr "ಕ್ಲೈಂಟ್ ಅಲಂಕರಣ" #: ../data/org.gnome.sushi.gschema.xml.in.h:2 msgid "Whether the window draws WM decorations itself" msgstr "ಕಿಟಕಿಯು ತಾನಾಗಿಯೆ WM ಅಲಂಕಾರಗಳನ್ನು ರಚಿಸಿಕೊಳ್ಳುತ್ತದೆಯೆ" #: ../src/js/ui/fallbackRenderer.js:120 msgid "Type" msgstr "ಬಗೆ" #: ../src/js/ui/fallbackRenderer.js:121 #: ../src/js/ui/fallbackRenderer.js:130 #: ../src/js/ui/fallbackRenderer.js:136 #: ../src/js/ui/spinnerBox.js:57 msgid "Loading…" msgstr "ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ…" #: ../src/js/ui/fallbackRenderer.js:129 msgid "Size" msgstr "ಗಾತ್ರ" #: ../src/js/ui/fallbackRenderer.js:135 msgid "Modified" msgstr "ಮಾರ್ಪಡಿಸಲಾಗಿದ್ದು" #: ../src/js/viewers/audio.js:172 msgid "from" msgstr "ಇಂದ" #: ../src/js/viewers/audio.js:174 msgid "by" msgstr "ಯಲ್ಲಿ" #: ../src/js/viewers/evince.js:78 #, c-format msgid "%d of %d" msgstr "%d, %d ರಲ್ಲಿ" #: ../src/libsushi/sushi-file-loader.c:639 #, c-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d ಅಂಶ" msgstr[1] "%d ಅಂಶಗಳು" #: ../src/libsushi/sushi-file-loader.c:651 msgid "Empty Folder" msgstr "ಖಾಲಿ ಕಡತಕೋಶ" 0707010000003D000081A4000000000000000000000001660EE2C800000A7D000000000000000000000000000000000000001400000000sushi-46.0/po/ko.po# Korean translation for sushi. # This file is distributed under the same license as the sushi package. # # Seong-ho Cho <darkcircle.0426@gmail.com>, 2011. # Changwoo Ryu <cwryu@debian.org>, 2012, 2019, 2021. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 14:15+0000\n" "PO-Revision-Date: 2021-09-13 09:35+0900\n" "Last-Translator: Changwoo Ryu <cwryu@debian.org>\n" "Language-Team: Korean <gnome-kr@googlegroups.com>\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" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "스시" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "여러가지 종류의 파일을 빠르게 보는 기능을 제공합니다" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "스시는 그놈 데스크톱 환경을 위한 파일 미리 보기 프로그램입니다. 스시는 그놈 파일(노틸러스)과 연동해 동작하는 독립적인 구성 요소입니다." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "유형" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "항목 %d개" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "빈 폴더" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "크기" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "수정됨" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "%s 파일을 표시할 수 없습니다" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "%s 프로그램으로 열기" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "열기" #: src/viewers/audio.js:359 msgid "from" msgstr "앨범" #: src/viewers/audio.js:364 msgid "by" msgstr "만든 이" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d (전체 %d)" #~ msgid "Client decoration" #~ msgstr "클라이언트 장식" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "창에서 창관리자 장식을 직접 그릴지 여부" #~ msgid "Loading…" #~ msgstr "불러오는 중…" 0707010000003E000081A4000000000000000000000001660EE2C800000AF9000000000000000000000000000000000000001400000000sushi-46.0/po/lt.po# Lithuanian translation for sushi. # Copyright (C) 2011 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # Žygimantas Beručka <zygis@gnome.org>, 2012. # Aurimas Černius <aurisc4@gmail.com>, 2011-2020. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 14:35+0000\n" "PO-Revision-Date: 2020-10-24 21:22+0300\n" "Last-Translator: Aurimas Černius <aurisc4@gmail.com>\n" "Language-Team: Lietuvių <gnome-lt@lists.akl.lt>\n" "Language: lt\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" "%100<10 || n%100>=20) ? 1 : 2)\n" "X-Generator: Gtranslator 3.36.0\n" "X-Project-Style: gnome\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Suši" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Pateikia galimybę greitai parodyti įvairius failus" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi yra failų peržiūros priemonė GNOME darbalaukio aplinkai. Tai yra " "nepriklausomas komponentas, kuris integruojasi su GNOME Failais (Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Tipas" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d elementas" msgstr[1] "%d elementai" msgstr[2] "%d elementų" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Tuščias aplankas" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Dydis" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Pakeista" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Nepavyko parodyti %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Atverti su %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Atverti" #: src/viewers/audio.js:359 msgid "from" msgstr "iš" #: src/viewers/audio.js:364 msgid "by" msgstr "atlieka" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d iš %d" #~ msgid "Client decoration" #~ msgstr "Kliento apipavidalinimas" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "Ar langas pats piešia valdyklės apipavidalinimą" #~ msgid "Loading…" #~ msgstr "Įkeliama…" 0707010000003F000081A4000000000000000000000001660EE2C800000A61000000000000000000000000000000000000001400000000sushi-46.0/po/lv.po# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Rūdofls Mazurs <rudolfs.mazurs@gmail.com>, 2011, 2012, 2019, 2021. msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 14:15+0000\n" "PO-Revision-Date: 2021-03-07 21:00+0200\n" "Last-Translator: Rūdolfs Mazurs <rudolfs.mazurs@gmail.com>\n" "Language-Team: Latvian <lata-l10n@googlegroups.com>\n" "Language: lv\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 != 0 ? 1 :" " 2);\n" "X-Generator: Lokalize 19.12.3\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Suši" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Nodrošina veidu, kā ātri apskatīt dažādas datnes" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi ir datņu priekšskatīšanas programma GNOME darbvirsmas videi. Tā ir" " neatkarīga komponente, kas integrējas ar GNOME Datnēm (Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Tips" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d vienums" msgstr[1] "%d vienumi" msgstr[2] "%d vienumu" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Tukša mape" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Izmērs" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Mainīts" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Nevarēja attēlot %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Atvērt ar %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Atvērt" #: src/viewers/audio.js:359 msgid "from" msgstr "no" #: src/viewers/audio.js:364 msgid "by" msgstr "izpilda" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d no %d" #~ msgid "Client decoration" #~ msgstr "Klienta apdare" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "Vai logs pats zīmē pats savu LP apdari" #~ msgid "Loading…" #~ msgstr "Ielādē…" 07070100000040000081A4000000000000000000000001660EE2C80000003A000000000000000000000000000000000000001A00000000sushi-46.0/po/meson.buildi18n.gettext( meson.project_name(), preset: 'glib', ) 07070100000041000081A4000000000000000000000001660EE2C80000069E000000000000000000000000000000000000001500000000sushi-46.0/po/mjw.po# Karbi translation for sushi. # Copyright (C) 2019 sushi's Free Software Foundation, Inc. # This file is distributed under the same license as the sushi package. # Jor Teron <jor.teron@gmail.com>, 2019. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2019-08-03 12:16+0000\n" "PO-Revision-Date: 2019-08-03 21:49+0530\n" "Last-Translator: Jor Teron <jor.teron@gmail.com>\n" "Language-Team: Karbi <karbi.translation@gmail.com>\n" "Language: mjw\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: gedit 3.28.1\n" #: src/ui/fallbackRenderer.js:233 msgid "Type" msgstr "" #: src/ui/fallbackRenderer.js:243 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "Son %d" msgstr[1] "Son %d" #: src/ui/fallbackRenderer.js:248 msgid "Empty Folder" msgstr "Angse Folder" #: src/ui/fallbackRenderer.js:251 msgid "Size" msgstr "" #: src/ui/fallbackRenderer.js:256 msgid "Modified" msgstr "" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:327 #, javascript-format msgid "Open With %s" msgstr "%s pen kangpu" #: src/ui/mainWindow.js:333 msgid "Open" msgstr "Kangpu" #: src/viewers/audio.js:352 msgid "from" msgstr "" #: src/viewers/audio.js:357 msgid "by" msgstr "" #: src/viewers/evince.js:86 #, javascript-format msgid "%d of %d" msgstr "%d do %d longpen" 07070100000042000081A4000000000000000000000001660EE2C8000008E5000000000000000000000000000000000000001400000000sushi-46.0/po/ml.po# Malayalam translation for sushi. # Copyright (C) 2012 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # jishnu7 <jishnu7@gmail.com>, 2012. # Ani Peter <apeter@redhat.com>, 2012. # Anish A <aneesh.nl@gmail.com>, 2012. msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" "product=sushi&keywords=I18N+L10N&component=general\n" "POT-Creation-Date: 2012-09-21 06:27+0000\n" "PO-Revision-Date: 2012-09-22 10:55+0530\n" "Last-Translator: Anish A <aneesh.nl@gmail.com>\n" "Language-Team: Swatantra Malayalam Computing\n" "Language: ml\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: Virtaal 0.6.1\n" #: ../data/org.gnome.sushi.gschema.xml.in.h:1 msgid "Client decoration" msgstr "ക്ലയന്റ് ഒരുക്കം" #: ../data/org.gnome.sushi.gschema.xml.in.h:2 msgid "Whether the window draws WM decorations itself" msgstr "ജാലകപരിപാലകന് ഒരുക്കങ്ങള് ജാലകം തനിയ ചെയ്യുമോ എന്ന്" #: ../src/js/ui/fallbackRenderer.js:120 msgid "Type" msgstr "തരം" #: ../src/js/ui/fallbackRenderer.js:121 ../src/js/ui/fallbackRenderer.js:130 #: ../src/js/ui/fallbackRenderer.js:136 ../src/js/ui/spinnerBox.js:57 msgid "Loading…" msgstr "എടുത്തുകൊണ്ടിരിക്കുന്നു…" #: ../src/js/ui/fallbackRenderer.js:129 msgid "Size" msgstr "വലിപ്പം" #: ../src/js/ui/fallbackRenderer.js:135 msgid "Modified" msgstr "പരിഷ്കരിച്ചത്" #: ../src/js/viewers/audio.js:172 msgid "from" msgstr "ചിത്രം/ആല്ബം" #: ../src/js/viewers/audio.js:174 msgid "by" msgstr "പാടിയത്" #: ../src/js/viewers/evince.js:79 #, c-format msgid "%d of %d" msgstr "താള് %d/%d" #: ../src/libsushi/sushi-file-loader.c:639 #, c-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d വസ്തു" msgstr[1] "%d വസ്തുക്കള്" #: ../src/libsushi/sushi-file-loader.c:651 msgid "Empty Folder" msgstr "ഒഴിഞ്ഞ അറ" 07070100000043000081A4000000000000000000000001660EE2C800000809000000000000000000000000000000000000001400000000sushi-46.0/po/mr.po# Marathi translation for sushi. # Copyright (C) 2012 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # # Sandeep Shedmake <sshedmak@redhat.com>, 2012. msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" "product=sushi&keywords=I18N+L10N&component=general\n" "POT-Creation-Date: 2012-08-10 13:38+0000\n" "PO-Revision-Date: 2012-08-10 22:16+0530\n" "Last-Translator: Sandeep Shedmake <sshedmak@redhat.com>\n" "Language-Team: Marathi <maajhe-sanganak@freelists.org>\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: Lokalize 1.4\n" #: ../data/org.gnome.sushi.gschema.xml.in.h:1 msgid "Client decoration" msgstr "क्लाएंट सजावट" #: ../data/org.gnome.sushi.gschema.xml.in.h:2 msgid "Whether the window draws WM decorations itself" msgstr "पटल स्वतःहून WM सजावट रेखाटते" #: ../src/js/ui/fallbackRenderer.js:120 msgid "Type" msgstr "प्रकार" #: ../src/js/ui/fallbackRenderer.js:121 ../src/js/ui/fallbackRenderer.js:130 #: ../src/js/ui/fallbackRenderer.js:136 ../src/js/ui/spinnerBox.js:57 msgid "Loading…" msgstr "लोड करत आहे…" #: ../src/js/ui/fallbackRenderer.js:129 msgid "Size" msgstr "आकार" #: ../src/js/ui/fallbackRenderer.js:135 msgid "Modified" msgstr "संपादित केले" #: ../src/js/viewers/audio.js:172 msgid "from" msgstr "पासून" #: ../src/js/viewers/audio.js:174 msgid "by" msgstr "तर्फे" #: ../src/js/viewers/evince.js:79 #, c-format msgid "%d of %d" msgstr "%d, %d पैकी" #: ../src/libsushi/sushi-file-loader.c:639 #, c-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d घटक" msgstr[1] "%d घटके" #: ../src/libsushi/sushi-file-loader.c:651 msgid "Empty Folder" msgstr "रिकामे फोल्डर" 07070100000044000081A4000000000000000000000001660EE2C8000007B1000000000000000000000000000000000000001400000000sushi-46.0/po/ms.po# Malay translation for sushi. # Copyright (C) 2019 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # abuyop <abuyop@gmail.com>, 2019. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2019-12-02 00:29+0000\n" "PO-Revision-Date: 2019-12-29 16:49+0800\n" "Language-Team: Malay <ms@li.org>\n" "Language: ms\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" "Last-Translator: abuyop <abuyop@gmail.com>\n" "X-Generator: Poedit 2.0.6\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Sediakan satu kemudahan untuk melihat jenis-jenis fail berbeza secara pantas" #: src/ui/fallbackRenderer.js:233 msgid "Type" msgstr "Jenis" #: src/ui/fallbackRenderer.js:243 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d item" #: src/ui/fallbackRenderer.js:248 msgid "Empty Folder" msgstr "Folder Kosong" #: src/ui/fallbackRenderer.js:251 msgid "Size" msgstr "Saiz" #: src/ui/fallbackRenderer.js:256 msgid "Modified" msgstr "Diubah suai" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Tidak boleh paparkan %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Buka Dengan %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Buka" #: src/viewers/audio.js:352 msgid "from" msgstr "daripada" #: src/viewers/audio.js:357 msgid "by" msgstr "oleh" #: src/viewers/evince.js:86 #, javascript-format msgid "%d of %d" msgstr "%d dari %d" 07070100000045000081A4000000000000000000000001660EE2C80000093D000000000000000000000000000000000000001400000000sushi-46.0/po/nb.po# Norwegian bokmål translation of sushi. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Kjartan Maraas <kmaraas@gnome.org>, 2011-2020. # msgid "" msgstr "" "Project-Id-Version: sushi 3.38.x\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 14:35+0000\n" "PO-Revision-Date: 2021-01-13 15:09+0100\n" "Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n" "Language-Team: Norwegian bokmål <i18n-nb@lister.ping.uio.no>\n" "Language: nb\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" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Gir mulighet for å vise forskjellige typer filer raskt" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "Sushi gjør forhåndsvisning av filer for GNOME skrivebordsmiljøet. Det er en uavhengig komponent som integrerer med GNOME file (Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Type" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d oppføring" msgstr[1] "%d oppføringer" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Tom mappe" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Størrelse" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Endret" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Kan ikke vise %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Åpne med %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Åpne" #: src/viewers/audio.js:359 msgid "from" msgstr "fra" #: src/viewers/audio.js:364 msgid "by" msgstr "av" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d av %d" 07070100000046000081A4000000000000000000000001660EE2C800000BA7000000000000000000000000000000000000001400000000sushi-46.0/po/ne.po# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # msgid "" msgstr "" "Project-Id-Version: Gnome Nepali Translation Project\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 14:15+0000\n" "PO-Revision-Date: 2021-04-21 08:32+0545\n" "Last-Translator: Pawan Chitrakar <chautari@gmail.com>\n" "Language-Team: Nepali Translation Team <chautari@gmail.com>\n" "Language: ne\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: Poedit 2.4.2\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "सुशी" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "विभिन्न प्रकारका फाइलहरू छिटो हेर्नको लागि सुविधा प्रदान गर्नुहोस्" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "सुशी जिनोम डेस्कटप परिवेशका लागि फाइल पूर्वावलोकनकर्ता हो । यो एउटा स्वतन्त्र " "अवयव हो जसले जिनोम फाइल (नटलस) सँग एकीकृत गर्दछ।" #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "प्रकार" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d सामाग्री" msgstr[1] "%d सामाग्रीहरू" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "खालीफोल्डर" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "साइज" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "परिमार्जित" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "%s प्रदर्शन गर्न असमर्थ" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "%s संग खोल्नुहोस्" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "खुला" #: src/viewers/audio.js:359 msgid "from" msgstr "बाट" #: src/viewers/audio.js:364 msgid "by" msgstr "देखि" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d मा %d" #~ msgid "Loading…" #~ msgstr "लोड गर्दै…" 07070100000047000081A4000000000000000000000001660EE2C800000A60000000000000000000000000000000000000001400000000sushi-46.0/po/nl.po# Dutch translation for Sushi # # This file is distributed under the same license as the sushi package. # # Wouter Bolsterlee <wbolster@gnome.org>, 2011‒2013. # Nathan Follens <nthn@unseen.is>, 2019, 2021. # msgid "" msgstr "" "Project-Id-Version: Sushi\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-23 08:16+0000\n" "PO-Revision-Date: 2021-04-01 20:27+0200\n" "Last-Translator: Nathan Follens <nthn@unseen.is>\n" "Language-Team: Dutch <gnome-nl-list@gnome.org>\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: Poedit 2.4.2\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "" "Biedt de mogelijkheid om verschillende soorten bestanden in een oogopslag te " "bekijken" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi is een voorbeeldweergavetoepassing voor de Gnome-bureaubladomgeving. " "Het is een onafhankelijk onderdeel dat integreert met Gnome Bestanden " "(Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Type" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d item" msgstr[1] "%d items" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Lege map" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Grootte" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Gewijzigd" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Kan %s niet weergeven" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Openen met %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Openen" #: src/viewers/audio.js:359 msgid "from" msgstr "van" #: src/viewers/audio.js:364 msgid "by" msgstr "door" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d van %d" #~ msgid "Client decoration" #~ msgstr "Vensterdecoratie" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "Geeft aan of het venster de eigen vensterdecoratie moet tekenen" #~ msgid "Loading…" #~ msgstr "Laden…" 07070100000048000081A4000000000000000000000001660EE2C800000AB4000000000000000000000000000000000000001400000000sushi-46.0/po/oc.po# Occitan translation for sushi. # Copyright (C) 2011 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # Cédric Valmary <cvalmary@yahoo.fr>, 2015. # Cédric Valmary (Tot en òc) <cvalmary@yahoo.fr>, 2015. # Cédric Valmary (totenoc.eu) <cvalmary@yahoo.fr>, 2016. msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 14:15+0000\n" "PO-Revision-Date: 2021-05-11 19:45+0200\n" "Last-Translator: Quentin PAGÈS\n" "Language-Team: Tot En Òc\n" "Language: oc\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: Poedit 2.4.3\n" "X-Project-Style: gnome\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Ofrís un biais facil per visualizar diferents tipes de fichièrs" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi es un previsualizaire de fichièrs per l’environament de burèu GNOME. " "Es un compausant independent que s’intègra a GNOME Files (Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Tipe" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d element" msgstr[1] "%d elements" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Dorsièr void" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Talha" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Modificat" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Impossible d'afichar %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Dobrir amb %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Dobrir" #: src/viewers/audio.js:359 msgid "from" msgstr "de" #: src/viewers/audio.js:364 msgid "by" msgstr "per" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d sus %d" #~ msgid "Loading…" #~ msgstr "Cargament…" #~ msgid "Client decoration" #~ msgstr "Decoracion del client" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "Indica se la fenèstra dessenha las decoracions del WM ela-meteissa" 07070100000049000081A4000000000000000000000001660EE2C800000823000000000000000000000000000000000000001400000000sushi-46.0/po/or.po# Oriya translation for sushi. # Copyright (C) 2011 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # # Manoj Kumar Giri <mgiri@redhat.com>, 2011, 2012. msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" "product=sushi&keywords=I18N+L10N&component=general\n" "POT-Creation-Date: 2012-09-25 23:14+0000\n" "PO-Revision-Date: 2012-11-28 17:53+0530\n" "Last-Translator: Manoj Kumar Giri <mgiri@redhat.com>\n" "Language-Team: Oriya <oriya-it@googlegroups.com>\n" "Language: or\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: Lokalize 1.5\n" #: ../data/org.gnome.sushi.gschema.xml.in.h:1 msgid "Client decoration" msgstr "କ୍ଲାଏଣ୍ଟ ଆଭୁଷଣ" #: ../data/org.gnome.sushi.gschema.xml.in.h:2 msgid "Whether the window draws WM decorations itself" msgstr "ୱିଣ୍ଡୋ WM ଆଭୁଷଣକୁ ନିଜେ ଅଙ୍କନ କରିଥାଏ କି" #: ../src/js/ui/fallbackRenderer.js:120 msgid "Type" msgstr "ପ୍ରକାର" #: ../src/js/ui/fallbackRenderer.js:121 ../src/js/ui/fallbackRenderer.js:130 #: ../src/js/ui/fallbackRenderer.js:136 ../src/js/ui/spinnerBox.js:57 msgid "Loading…" msgstr "ଧାରଣ କରୁଅଛି…" #: ../src/js/ui/fallbackRenderer.js:129 msgid "Size" msgstr "ଆକାର" #: ../src/js/ui/fallbackRenderer.js:135 msgid "Modified" msgstr "ପରିବର୍ତ୍ତିତ" #: ../src/js/viewers/audio.js:172 msgid "from" msgstr "ଠାରୁ" #: ../src/js/viewers/audio.js:174 msgid "by" msgstr "ଦ୍ବାରା" #: ../src/js/viewers/evince.js:79 #, c-format msgid "%d of %d" msgstr "%d ର %d" #: ../src/libsushi/sushi-file-loader.c:639 #, c-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d ବସ୍ତୁ" msgstr[1] "%d ବସ୍ତୁଗୁଡ଼ିକ" #: ../src/libsushi/sushi-file-loader.c:651 msgid "Empty Folder" msgstr "ଖାଲି ଫୋଲଡର" 0707010000004A000081A4000000000000000000000001660EE2C800000816000000000000000000000000000000000000001400000000sushi-46.0/po/pa.po# Punjabi translation for sushi. # Copyright (C) 2011 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # # A S Alam <aalam@users.sf.net>, 2011, 2012, 2014. msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" "product=sushi&keywords=I18N+L10N&component=general\n" "POT-Creation-Date: 2014-09-21 10:28+0000\n" "PO-Revision-Date: 2014-09-21 08:45-0500\n" "Last-Translator: A S Alam <aalam@users.sf.net>\n" "Language-Team: Punjabi/Panjabi <punjabi-users@lists.sf.net>\n" "Language: pa\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: Lokalize 1.5\n" #: ../data/org.gnome.sushi.gschema.xml.in.h:1 msgid "Client decoration" msgstr "ਕਲਾਇਟ ਸਜਾਵਟ" #: ../data/org.gnome.sushi.gschema.xml.in.h:2 msgid "Whether the window draws WM decorations itself" msgstr "ਕੀ ਵਿੰਡੋ ਖੁਦ WM ਸਜਾਵਟ ਕਰੇ" #: ../src/js/ui/fallbackRenderer.js:121 msgid "Type" msgstr "ਕਿਸਮ" #: ../src/js/ui/fallbackRenderer.js:122 ../src/js/ui/fallbackRenderer.js:131 #: ../src/js/ui/fallbackRenderer.js:137 ../src/js/ui/spinnerBox.js:58 msgid "Loading…" msgstr "ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…" #: ../src/js/ui/fallbackRenderer.js:130 msgid "Size" msgstr "ਅਕਾਰ" #: ../src/js/ui/fallbackRenderer.js:136 msgid "Modified" msgstr "ਸੋਧ ਕੀਤੀ" #: ../src/js/viewers/audio.js:173 msgid "from" msgstr "ਵਿੱਚੋਂ" #: ../src/js/viewers/audio.js:175 msgid "by" msgstr "ਵਲੋਂ" #: ../src/js/viewers/evince.js:79 #, javascript-format #| msgid "%d of %d" msgid "%d of %d" msgstr "%d, %d ਵਿੱਚੋ" #: ../src/libsushi/sushi-file-loader.c:639 #, c-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d ਆਈਟਮ" msgstr[1] "%d ਆਈਟਮਾਂ" #: ../src/libsushi/sushi-file-loader.c:651 msgid "Empty Folder" msgstr "ਖਾਲੀ ਫੋਲਡਰ" 0707010000004B000081A4000000000000000000000001660EE2C8000009DA000000000000000000000000000000000000001400000000sushi-46.0/po/pl.po# Polish translation for sushi. # Copyright © 2011-2020 the sushi authors. # This file is distributed under the same license as the sushi package. # Piotr Drąg <piotrdrag@gmail.com>, 2011-2020. # Aviary.pl <community-poland@mozilla.org>, 2011-2020. # msgid "" msgstr "" "Project-Id-Version: sushi\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 14:35+0000\n" "PO-Revision-Date: 2020-10-24 12:58+0200\n" "Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n" "Language-Team: Polish <community-poland@mozilla.org>\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" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Dodaje funkcję szybkiego podglądu różnych rodzajów plików" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi to program do podglądu plików dla środowiska GNOME. Jest niezależnym " "składnikiem integrującym się z Menedżerem plików GNOME (Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Typ" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d element" msgstr[1] "%d elementy" msgstr[2] "%d elementów" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Pusty katalog" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Rozmiar" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Modyfikacja" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Nie można wyświetlić pliku %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Otwórz za pomocą „%s”" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Otwórz" #: src/viewers/audio.js:359 msgid "from" msgstr "z" #: src/viewers/audio.js:364 msgid "by" msgstr " " #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d z %d" 0707010000004C000081A4000000000000000000000001660EE2C800000ABC000000000000000000000000000000000000001400000000sushi-46.0/po/pt.po# sushi's Portuguese translation. # Copyright © 2011, 2012, 2013 sushi # This file is distributed under the same license as the sushi package. # # Duarte Loreto <happyguy_pt@hotmail.com>, 2011, 2012, 2013. # Juliano de Souza Camargo <julianosc@protonmail.com>, 2020. # msgid "" msgstr "" "Project-Id-Version: 3.8\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 19:38+0000\n" "PO-Revision-Date: 2020-12-07 06:11-0300\n" "Last-Translator: Juliano de Souza Camargo <julianosc@protonmail.com>\n" "Language-Team: Portuguese <>\n" "Language: 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: Gtranslator 3.38.0\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "" "Forneça um recurso para visualizar rapidamente diferentes tipos de ficheiros" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "O Sushi é um pré-visualizador de ficheiros para o ambiente de trabalho " "GNOME. É um componente independente que se integra com o Ficheiros do GNOME " "(Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Tipo" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d item" msgstr[1] "%d itens" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Pasta vazia" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Tamanho" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Modificado" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Não é possível mostrar %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Abrir com %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Abrir" #: src/viewers/audio.js:359 msgid "from" msgstr "de" #: src/viewers/audio.js:364 msgid "by" msgstr "por" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d de %d" #~ msgid "Loading…" #~ msgstr "A carregar…" #~ msgid "Client decoration" #~ msgstr "Decoração do cliente" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "" #~ "Se a própria janela desenha ou não as decorações de Gestor de janelas" 0707010000004D000081A4000000000000000000000001660EE2C800000A22000000000000000000000000000000000000001700000000sushi-46.0/po/pt_BR.po# Brazilian Portuguese translation for sushi. # Copyright (C) 2019 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # Djavan Fagundes <djavan@comum.org>, 2011. # Og Maciel <ogmaciel@gnome.org>, 2011. # Rafael Fontenelle <rafaelff@gnome.org>, 2012-2019. # Enrico Nicoletto <enriconlto@src.gnome.org>, 2019, 2020. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 14:35+0000\n" "PO-Revision-Date: 2020-11-10 08:14-0300\n" "Last-Translator: Enrico Nicoletto <liverig@gmail.com>\n" "Language-Team: Brazilian Portuguese <gnome-pt_br-list@gnome.org>\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: Poedit 2.4.1\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "" "Oferece uma facilidade para visualizar rapidamente diferentes tipos de " "arquivos" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi é um visualizador de arquivos para a área de trabalho do GNOME. É um " "componente independente que se integra com o Arquivos do GNOME (Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Tipo" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d item" msgstr[1] "%d itens" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Pasta vazia" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Tamanho" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Modificado" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Não foi possível exibir %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Abrir com %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Abrir" #: src/viewers/audio.js:359 msgid "from" msgstr "de" #: src/viewers/audio.js:364 msgid "by" msgstr "por" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d de %d"0707010000004E000081A4000000000000000000000001660EE2C800000A76000000000000000000000000000000000000001400000000sushi-46.0/po/ro.po# Romanian translation for sushi. # Copyright (C) 2015 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # Adriannho <raziel_theripper@yahoo.com>, 2015. # Daniel Șerbănescu <daniel [at] serbanescu [dot] dk>, 2015. msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 14:15+0000\n" "PO-Revision-Date: 2020-12-12 20:47+0200\n" "Last-Translator: Florentina Mușat <florentina.musat.28@gmail.com>\n" "Language-Team: Gnome Romanian Translation Team\n" "Language: ro\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==0 || (n%100 > 0 && n%100 < " "20)) ? 1 : 2);\n" "X-Generator: Poedit 2.4.2\n" "X-Project-Style: gnome\n" "X-Poedit-SourceCharset: UTF-8\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Oferă o facilitate de a vizualiza rapid tipuri diferite de fișiere" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi este un previzualizator de fișiere pentru mediul de desktop GNOME. " "Este o componentă independentă care se integrează cu Fișiere GNOME " "(Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Tip" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d element" msgstr[1] "%d elemente" msgstr[2] "%d de elemente" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Dosar gol" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Mărime" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Modificat" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Nu s-a putut afișa %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Deschide cu %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Deschide" #: src/viewers/audio.js:359 msgid "from" msgstr "din" #: src/viewers/audio.js:364 msgid "by" msgstr "de către" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d din %d" #~ msgid "Loading…" #~ msgstr "Se încarcă…" 0707010000004F000081A4000000000000000000000001660EE2C800000C36000000000000000000000000000000000000001400000000sushi-46.0/po/ru.po# Russian translation for sushi. # Copyright (C) 2011 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # Yuri Myasoedov <omerta13@yandex.ru>, 2011, 2012. # Stas Solovey <whats_up@tut.by>, 2011-2019. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-23 08:16+0000\n" "PO-Revision-Date: 2021-01-06 15:57+0200\n" "Last-Translator: Alexey Rubtsov <rushills@gmail.com>\n" "Language-Team: русский <gnome-cyr@gnome.org>\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" "X-Generator: Poedit 2.4.2\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Предоставляет возможность быстрого просмотра различных типов файлов" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi - программа быстрого просмотра для рабочего стола GNOME. Она " "является независимым компонентом и интегрируется в Файлы (Nautilus)" #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Тип" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d элемент" msgstr[1] "%d элемента" msgstr[2] "%d элементов" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Пустая папка" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Размер" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Дата изменения" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Невозможно отобразить %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Открыть в приложении %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Открыть" #: src/viewers/audio.js:359 msgid "from" msgstr "из" #: src/viewers/audio.js:364 msgid "by" msgstr "в исполнении" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d из %d" #~ msgid "Client decoration" #~ msgstr "Декорация клиента" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "Должно ли окно самостоятельно рисовать декорации" #~ msgid "Loading…" #~ msgstr "Загрузка…" 07070100000050000081A4000000000000000000000001660EE2C800000AB9000000000000000000000000000000000000001400000000sushi-46.0/po/sk.po# Slovak translation for sushi. # Copyright (C) 2012 Free Software Foundation, Inc. # This file is distributed under the same license as the sushi package. # Stanislav Kubík <stanislavkubik.hody@gmail.com>, 2012. # msgid "" msgstr "" "Project-Id-Version: sushi\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 19:38+0000\n" "PO-Revision-Date: 2020-10-25 15:17+0100\n" "Last-Translator: Dušan Kazik <prescott66@gmail.com>\n" "Language-Team: Slovak <gnome-sk-list@gnome.org>\n" "Language: sk\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) ? 1 : (n>=2 && n<=4) ? 2 : 0;\n" "X-Generator: Poedit 2.4.1\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Poskytuje prostriedky na rýchle zobrazenie rôznych druhov súborov" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi je zobrazovač náhľadov pre pracovné prostredie GNOME. Je " "nezávislou súčasťou, ktorá je integrovaná do aplikácie Súbory " "prostredia GNOME (Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Typ" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d položiek" msgstr[1] "%d položka" msgstr[2] "%d položky" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Prázdny priečinok" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Veľkosť" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Upravené" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Nie je možné zobraziť %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Otvoriť pomocou aplikácie %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Otvoriť" #: src/viewers/audio.js:359 msgid "from" msgstr "z" #: src/viewers/audio.js:364 msgid "by" msgstr "od" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d. z %d" #~ msgid "Client decoration" #~ msgstr "Dekorácia klienta" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "Či vykresliť dekoráciu okna namiesto správcu okien" #~ msgid "Loading…" #~ msgstr "Načítava sa…" 07070100000051000081A4000000000000000000000001660EE2C800000B1F000000000000000000000000000000000000001400000000sushi-46.0/po/sl.po# Slovenian translation for sushi. # Copyright (C) 2011 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # # Mira Metljak <miraov@gmail.com>, 2011. # Matej Urbančič <mateju@svn.gnome.org>, + 2019–2021. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2021-01-13 14:10+0000\n" "PO-Revision-Date: 2021-01-13 21:43+0100\n" "Last-Translator: Matej Urbančič <mateju@svn.gnome.org>\n" "Language-Team: Slovenian GNOME Translation Team <gnome-si@googlegroups.com>\n" "Language: sl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n" "%100==4 ? 3 : 0);\n" "X-Poedit-SourceCharset: utf-8\n" "X-Generator: Poedit 2.4.1\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Program za hitro pregledovanje različnih vrst datotek" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi je program za predogled datotek za namizje GNOME. Program je neodvisen " "od sistemskih knjižnic in razširja zmožnosti Datotek GNOME (Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Vrsta" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d predmetov" msgstr[1] "%d predmet" msgstr[2] "%d predmeta" msgstr[3] "%d predmeti" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Prazna mapa" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Velikost" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Spremenjeno" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Datoteke %s ni mogoče prikazati." #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Odpri s programom %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Odpri" #: src/viewers/audio.js:359 msgid "from" msgstr "od" #: src/viewers/audio.js:364 msgid "by" msgstr "od" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d od %d" #~ msgid "Client decoration" #~ msgstr "Oblikovanje odjemalca" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "Ali naj okno izriše oblikovanje WM" #~ msgid "Loading..." #~ msgstr "Nalaganje ..." 07070100000052000081A4000000000000000000000001660EE2C800000C37000000000000000000000000000000000000001400000000sushi-46.0/po/sr.po# Serbian translation for sushi. # Copyright (C) 2011 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # Мирослав Николић <miroslavnikolic@rocketmail.com>, 2011, 2012. msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 14:35+0000\n" "PO-Revision-Date: 2020-10-25 05:39+0100\n" "Last-Translator: Марко М. Костић <marko.m.kostic@gmail.com>\n" "Language-Team: Serbian <gnom@prevod.org>\n" "Language: sr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : n" "%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Project-Style: gnome\n" "X-Generator: Poedit 2.4.1\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Суши" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Пружа могућност брзог прегледа различитих врста датотека" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Суши је претпрегледач датотека за Гномову радну површ. Ово је " "независан део који се уграђује унутар Гномових Датотека (Наутилус)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Врста" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d ставка" msgstr[1] "%d ставке" msgstr[2] "%d ставки" msgstr[3] "Једна ставка" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Празна фасцикла" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Величина" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Измењенo" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Не могу да прикажем %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Отвори програмом %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Отвори" #: src/viewers/audio.js:359 msgid "from" msgstr "од" #: src/viewers/audio.js:364 msgid "by" msgstr "од" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d од %d" #~ msgid "Client decoration" #~ msgstr "Украс клијента" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "Да ли прозор сам исцртава украсе управника прозора" #~ msgid "Loading…" #~ msgstr "Учитавам…" 07070100000053000081A4000000000000000000000001660EE2C80000086E000000000000000000000000000000000000001A00000000sushi-46.0/po/sr@latin.po# Serbian translation for sushi. # Copyright (C) 2011 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # Miroslav Nikolić <miroslavnikolic@rocketmail.com>, 2011, 2012. msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=sushi&" "keywords=I18N+L10N&component=general\n" "POT-Creation-Date: 2012-04-12 19:27+0000\n" "PO-Revision-Date: 2012-08-01 10:03+0200\n" "Last-Translator: Miroslav Nikolić <miroslavnikolic@rocketmail.com>\n" "Language-Team: Serbian <gnom@prevod.org>\n" "Language: sr@latin\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : " "n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Project-Style: gnome\n" #: ../data/org.gnome.sushi.gschema.xml.in.h:1 msgid "Client decoration" msgstr "Ukras klijenta" #: ../data/org.gnome.sushi.gschema.xml.in.h:2 msgid "Whether the window draws WM decorations itself" msgstr "Da li prozor sam iscrtava ukrase upravnika prozora" #: ../src/js/ui/fallbackRenderer.js:117 msgid "Type" msgstr "Vrsta" #: ../src/js/ui/fallbackRenderer.js:118 ../src/js/ui/fallbackRenderer.js:123 #: ../src/js/ui/fallbackRenderer.js:128 ../src/js/ui/spinnerBox.js:57 #: ../src/js/viewers/folder.js:124 ../src/js/viewers/folder.js:129 msgid "Loading…" msgstr "Učitavam…" #: ../src/js/ui/fallbackRenderer.js:122 ../src/js/viewers/folder.js:123 msgid "Size" msgstr "Veličina" #: ../src/js/ui/fallbackRenderer.js:127 ../src/js/viewers/folder.js:128 msgid "Modified" msgstr "Izmenjena" #: ../src/js/viewers/audio.js:171 msgid "from" msgstr "od" #: ../src/js/viewers/audio.js:173 msgid "by" msgstr "od" #: ../src/js/viewers/evince.js:79 #, c-format msgid "%d of %d" msgstr "%d od %d" #: ../src/libsushi/sushi-file-loader.c:640 #, c-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d stavka" msgstr[1] "%d stavke" msgstr[2] "%d stavki" msgstr[3] "Jedna stavka" #: ../src/libsushi/sushi-file-loader.c:652 msgid "Empty Folder" msgstr "Prazna fascikla" 07070100000054000081A4000000000000000000000001660EE2C800000A9C000000000000000000000000000000000000001400000000sushi-46.0/po/sv.po# Swedish translation for sushi. # Copyright © 2011-2020 Free Software Foundation, Inc. # This file is distributed under the same license as the sushi package. # Daniel Nylander <po@danielnylander.se>, 2011, 2012. # Anders Jonsson <anders.jonsson@norsjovallen.se>, 2016, 2019, 2020. # msgid "" msgstr "" "Project-Id-Version: sushi\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 14:35+0000\n" "PO-Revision-Date: 2020-10-23 18:51+0200\n" "Last-Translator: Anders Jonsson <anders.jonsson@norsjovallen.se>\n" "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n" "Language: sv\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: Poedit 2.4.1\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Tillhandahåll ett verktyg för att snabbt visa olika typer av filer" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi är en filförhandsvisare för skrivbordsmiljön GNOME. Det är en " "oberoende komponent som integrerar med GNOME Filer (Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Typ" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d objekt" msgstr[1] "%d objekt" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Tom mapp" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Storlek" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Ändrad" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Kunde inte visa %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Öppna med %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Öppna" #: src/viewers/audio.js:359 msgid "from" msgstr "från" #: src/viewers/audio.js:364 msgid "by" msgstr "av" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d av %d" #~ msgid "Loading…" #~ msgstr "Läser in…" #~ msgid "Client decoration" #~ msgstr "Klientdekoration" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "" #~ "Huruvida fönstret ritar ut dekorationer från fönsterhanteraren själv" 07070100000055000081A4000000000000000000000001660EE2C800000CEC000000000000000000000000000000000000001400000000sushi-46.0/po/ta.po# Tamil translation for sushi. # Copyright (C) 2011 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # # Dr.T.Vasudevan <agnihot3@gmail.com>, 2011, 2012. msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 14:15+0000\n" "PO-Revision-Date: 2012-09-02 14:59+0530\n" "Last-Translator: Dr.T.Vasudevan <agnihot3@gmail.com>\n" "Language-Team: Tamil <ta@li.org>\n" "Language: ta\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: Lokalize 1.1\n" "X-Language: ta\n" "X-Source-Language: C\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "சூஷி" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "பல்வேறு வகையான கோப்புகளை விரைவாக காணும் வசதியை வழங்கும்" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "சூஷி என்பது க்னோம் டெஸ்க்டாப்பிறகான கோப்பு முன்னோட்டம். இது க்னோம் " "கோப்புகளுடன் (நாட்டிலஸ்) ஒருங்கிணையும் ஒரு சுயாதீனமான கூறு ஆகும்." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "வகை" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d உருப்படி" msgstr[1] "%d உருப்படிகள்" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "காலி அடைவு" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "அளவு" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "மாற்றப்பட்ட" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "%s ஐ காட்ட முடியவில்லை" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "%s வுடன் திறக்கவும்" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "திற" #: src/viewers/audio.js:359 msgid "from" msgstr "இல் இருந்து" #: src/viewers/audio.js:364 msgid "by" msgstr "ஆல்" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d இன் %d" #~ msgid "Client decoration" #~ msgstr "சார்ந்தோன் அலங்காரம்" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "டபிள்யூஎம் அலங்காரங்களை சாரளமே செய்து கொள்ளுமா" #~ msgid "Loading…" #~ msgstr "ஏற்றுகிறது…" 07070100000056000081A4000000000000000000000001660EE2C8000008D9000000000000000000000000000000000000001400000000sushi-46.0/po/te.po# Telugu translation for sushi. # Copyright (C) 2012 Swecha Telugu Localisation Team <localization@swecha.net> # This file is distributed under the same license as the sushi package. # # Praveen Illa <mail2ipn@gmail.com>, 2011, 2012. # Sasi Bhushan Boddepalli <sasi@swecha.net>, 2012 msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" "product=sushi&keywords=I18N+L10N&component=general\n" "POT-Creation-Date: 2012-04-12 19:27+0000\n" "PO-Revision-Date: 2012-04-17 13:51+0530\n" "Last-Translator: Sasi Bhushan Boddepalli <sasi@swecha.net>\n" "Language-Team: Telugu <indlinux-telugu@lists.sourceforge.net>\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" #: ../data/org.gnome.sushi.gschema.xml.in.h:1 msgid "Client decoration" msgstr "క్లయింట్ అలంకరణ " #: ../data/org.gnome.sushi.gschema.xml.in.h:2 msgid "Whether the window draws WM decorations itself" msgstr "విండో WM అలంకరణలు కూడా చూపించారో లేదో" #: ../src/js/ui/fallbackRenderer.js:117 msgid "Type" msgstr "రకం" #: ../src/js/ui/fallbackRenderer.js:118 ../src/js/ui/fallbackRenderer.js:123 #: ../src/js/ui/fallbackRenderer.js:128 ../src/js/ui/spinnerBox.js:57 #: ../src/js/viewers/folder.js:124 ../src/js/viewers/folder.js:129 msgid "Loading…" msgstr "నింపుతున్నది…" #: ../src/js/ui/fallbackRenderer.js:122 ../src/js/viewers/folder.js:123 msgid "Size" msgstr "పరిమాణం" #: ../src/js/ui/fallbackRenderer.js:127 ../src/js/viewers/folder.js:128 msgid "Modified" msgstr "మార్చబడినది" #: ../src/js/viewers/audio.js:171 msgid "from" msgstr "నుండి" #: ../src/js/viewers/audio.js:173 msgid "by" msgstr "చే" #: ../src/js/viewers/evince.js:79 #, c-format msgid "%d of %d" msgstr "%d of %d" #: ../src/libsushi/sushi-file-loader.c:640 #, c-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d అంశం" msgstr[1] "%d అంశాలు" #: ../src/libsushi/sushi-file-loader.c:652 msgid "Empty Folder" msgstr "ఖాళీ సంచయం" 07070100000057000081A4000000000000000000000001660EE2C800000781000000000000000000000000000000000000001400000000sushi-46.0/po/tg.po# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Victor Ibragimov <victor.ibragimov@gmail.com>, 2013. # msgid "" msgstr "" "Project-Id-Version: Tajik Gnome\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" "product=sushi&keywords=I18N+L10N&component=general\n" "POT-Creation-Date: 2013-07-21 16:21+0000\n" "PO-Revision-Date: 2013-10-10 13:01+0500\n" "Last-Translator: Victor Ibragimov <victor.ibragimov@gmail.com>\n" "Language-Team: \n" "Language: tg\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: Poedit 1.5.7\n" #: ../data/org.gnome.sushi.gschema.xml.in.h:1 msgid "Client decoration" msgstr "Ороиши муштарӣ" #: ../data/org.gnome.sushi.gschema.xml.in.h:2 msgid "Whether the window draws WM decorations itself" msgstr "Интихоби ороиши худкор барои равзана" #: ../src/js/ui/fallbackRenderer.js:120 msgid "Type" msgstr "Намуд" #: ../src/js/ui/fallbackRenderer.js:121 ../src/js/ui/fallbackRenderer.js:130 #: ../src/js/ui/fallbackRenderer.js:136 ../src/js/ui/spinnerBox.js:57 msgid "Loading…" msgstr "Бор шуда истодааст…" #: ../src/js/ui/fallbackRenderer.js:129 msgid "Size" msgstr "Андоза" #: ../src/js/ui/fallbackRenderer.js:135 msgid "Modified" msgstr "Тағйирёфта" #: ../src/js/viewers/audio.js:172 msgid "from" msgstr "аз" #: ../src/js/viewers/audio.js:174 msgid "by" msgstr "бо" #: ../src/js/viewers/evince.js:78 #, c-format msgid "%d of %d" msgstr "%d аз %d" #: ../src/libsushi/sushi-file-loader.c:641 #, c-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d объект" #: ../src/libsushi/sushi-file-loader.c:653 msgid "Empty Folder" msgstr "Ҷузвдони холӣ" 07070100000058000081A4000000000000000000000001660EE2C800000CDC000000000000000000000000000000000000001400000000sushi-46.0/po/th.po# Thai translation for sushi. # Copyright (C) 2011-2012 Free Software Foundation, Inc. # This file is distributed under the same license as the sushi package. # Unticha Pramgoed <unticha@gmail.com>, 2011-2012. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2023-06-29 22:30+0000\n" "PO-Revision-Date: 2024-02-23 00:11+0700\n" "Last-Translator: Unticha Pramgoed <unticha@gmail.com>\n" "Language-Team: Thai <thai-l10n@googlegroups.com>\n" "Language: th\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: Poedit 3.4.2\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "เครื่องมืออำนวยความสะดวกสำหรับดูไฟล์ประเภทต่างๆ ได้อย่างรวดเร็ว" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi เป็นโปรแกรมแสดงตัวอย่างไฟล์สำหรับสภาพแวดล้อมเดสก์ท็อป GNOME " "และเป็นองค์ประกอบแยกต่างหากซึ่งทำงานร่วมกับโปรแกรมจัดการไฟล์ของ GNOME " "(Nautilus)" #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "ชนิด" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d รายการ" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "โฟลเดอร์ว่างเปล่า" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "ขนาด" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "แก้ไขเมื่อ" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "ไม่สามารถแสดง %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:358 #, javascript-format msgid "Open With %s" msgstr "เปิดด้วย %s" #: src/ui/mainWindow.js:364 msgid "Open" msgstr "เปิด" #: src/viewers/audio.js:375 msgid "from" msgstr "จาก" #: src/viewers/audio.js:380 msgid "by" msgstr "โดย" #: src/viewers/evince.js:103 #, javascript-format msgid "%d of %d" msgstr "%d จาก %d" #~ msgid "Client decoration" #~ msgstr "ตกแต่งโปรแกรมลูกข่าย" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "กำหนดว่าหน้าต่างจะวาดตกแต่งด้วยโปรแกรมจัดการหน้าต่างหรือไม่" #~ msgid "Loading…" #~ msgstr "กำลังโหลด…" 07070100000059000081A4000000000000000000000001660EE2C8000009E1000000000000000000000000000000000000001400000000sushi-46.0/po/tr.po# Turkish translation for sushi. # Copyright (C) 2011-2023 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # # Muhammet Kara <muhammet.k@gmail.com>, 2011. # Necdet Yücel <necdetyucel@gmail.com>, 2014. # Sabri Ünal <libreajans@gmail.com>, 2019. # Emin Tufan Çetin <etcetin@gmail.com>, 2021. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2023-07-02 13:36+0000\n" "PO-Revision-Date: 2021-02-22 10:56+0300\n" "Last-Translator: Emin Tufan Çetin <etcetin@gmail.com>\n" "Language-Team: Turkish <takim@gnome.org.tr>\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=1; plural=0;\n" "X-Generator: Poedit 2.4.2\n" "X-POOTLE-MTIME: 1415555003.000000\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Değişik türdeki dosyaları hızlıca görüntülemeyi sağlar" #: data/org.gnome.NautilusPreviewer.appdata.xml.in.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi, GNOME masaüstü ortamı için dosya ön izleyicidir. GNOME Dosyalar " "(Nautilus) ile tümleşen bağımsız bileşendir." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Tür" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d öge" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Boş Klasör" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Boyut" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Değiştirilme" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "%s gösterilemiyor" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:358 #, javascript-format msgid "Open With %s" msgstr "%s İle Aç" #: src/ui/mainWindow.js:364 msgid "Open" msgstr "Aç" #: src/viewers/audio.js:401 msgid "from" msgstr "Albüm:" #: src/viewers/audio.js:406 msgid "by" msgstr "Sanatçı:" #: src/viewers/evince.js:103 #, javascript-format msgid "%d of %d" msgstr "%d / %d" 0707010000005A000081A4000000000000000000000001660EE2C80000077A000000000000000000000000000000000000001400000000sushi-46.0/po/ug.po# Uyghur translation for sushi. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Sahran <sahran.ug@gmail.com>, 2011. # msgid "" msgstr "" "Project-Id-Version: sushi\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=sushi&keywords=I18N+L10N&component=general\n" "POT-Creation-Date: 2012-12-07 14:53+0000\n" "PO-Revision-Date: 2013-01-27 13:34+0900\n" "Last-Translator: Gheyret Kenji <gheyret@gmail.com>\n" "Language-Team: Uyghur Computer Science Association <UKIJ@yahoogroups.com>\n" "Language: ug\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" #: ../data/org.gnome.sushi.gschema.xml.in.h:1 msgid "Client decoration" msgstr "خېرىدار بېزىكى" #: ../data/org.gnome.sushi.gschema.xml.in.h:2 msgid "Whether the window draws WM decorations itself" msgstr "WM بېزەكلىرىنى كۆزنەك ئۆزى سىزامدۇ" #: ../src/js/ui/fallbackRenderer.js:120 msgid "Type" msgstr "تىپى" #: ../src/js/ui/fallbackRenderer.js:121 ../src/js/ui/fallbackRenderer.js:130 #: ../src/js/ui/fallbackRenderer.js:136 ../src/js/ui/spinnerBox.js:57 msgid "Loading…" msgstr "ئوقۇۋاتىدۇ…" #: ../src/js/ui/fallbackRenderer.js:129 msgid "Size" msgstr "چوڭلۇقى" #: ../src/js/ui/fallbackRenderer.js:135 msgid "Modified" msgstr "ئۆزگەرتىلدى" #: ../src/js/viewers/audio.js:172 msgid "from" msgstr "ئەۋەتكۈچى" #: ../src/js/viewers/audio.js:174 msgid "by" msgstr "ئارىلىق" #: ../src/js/viewers/evince.js:79 #, c-format msgid "%d of %d" msgstr "%d / %d" #: ../src/libsushi/sushi-file-loader.c:639 #, c-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d تۈر" #: ../src/libsushi/sushi-file-loader.c:651 msgid "Empty Folder" msgstr "بوش قىسقۇچ" 0707010000005B000081A4000000000000000000000001660EE2C800000C5B000000000000000000000000000000000000001400000000sushi-46.0/po/uk.po# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Korostil Daniel <ted.korostiled@gmail.com>, 2011. # Re. <ted.korostiled@gmail.com>, 2012. # Yuri Chornoivan <yurchor@ukr.net>, 2020. msgid "" msgstr "" "Project-Id-Version: 1.0\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2020-10-22 14:15+0000\n" "PO-Revision-Date: 2020-10-22 17:18+0300\n" "Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n" "Language-Team: Ukrainian <kde-i18n-uk@kde.org>\n" "Language: uk\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" "X-Generator: Lokalize 20.11.70\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Надає можливість швидко переглядати вміст файлів різних типів" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi — засіб попереднього перегляду вмісту файлів для стільничного" " середовища GNOME. Це незалежний компонент, який інтегрується із «Файлами»" " GNOME (Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Тип" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d об'єкт" msgstr[1] "%d об'єкти" msgstr[2] "%d об'єктів" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Порожня тека" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Розмір" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Змінено" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Не вдалося обробити вміст %s для показу" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Відкрити за допомогою %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Відкрити" #: src/viewers/audio.js:359 msgid "from" msgstr "з" #: src/viewers/audio.js:364 msgid "by" msgstr " " #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d з %d" #~ msgid "Client decoration" #~ msgstr "Клієнт декорацій" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "Чи вікно вимальовує декорації самого віконного менеджера" #~ msgid "Loading…" #~ msgstr "Завантаження…" 0707010000005C000081A4000000000000000000000001660EE2C8000007A8000000000000000000000000000000000000001D00000000sushi-46.0/po/uz@cyrillic.po# SUSHI - UZBEK TRANSLATION. # Copyright (C) 2012 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # # Bahodir Mansurov <6ahodir@gmail.com>, 2012. msgid "" msgstr "" "Project-Id-Version: sushi\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" "product=sushi&keywords=I18N+L10N&component=general\n" "POT-Creation-Date: 2012-10-12 20:23+0000\n" "PO-Revision-Date: 2012-10-14 19:15-0500\n" "Last-Translator: Bahodir Mansurov <6ahodir@gmail.com>\n" "Language-Team: Uzbek\n" "Language: uz@cyrillic\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-Poedit-Bookmarks: -1,1,-1,-1,-1,-1,-1,-1,-1,-1\n" #: ../data/org.gnome.sushi.gschema.xml.in.h:1 msgid "Client decoration" msgstr "Мижоз безаги" #: ../data/org.gnome.sushi.gschema.xml.in.h:2 msgid "Whether the window draws WM decorations itself" msgstr "Дераза Бошқарувчи (ДБ) безакларини деразанинг ўзи чизиши" #: ../src/js/ui/fallbackRenderer.js:120 msgid "Type" msgstr "Тури" #: ../src/js/ui/fallbackRenderer.js:121 ../src/js/ui/fallbackRenderer.js:130 #: ../src/js/ui/fallbackRenderer.js:136 ../src/js/ui/spinnerBox.js:57 msgid "Loading…" msgstr "Юкланяпти…" #: ../src/js/ui/fallbackRenderer.js:129 msgid "Size" msgstr "Ҳажми" #: ../src/js/ui/fallbackRenderer.js:135 msgid "Modified" msgstr "Ўзгартирилган" #: ../src/js/viewers/audio.js:172 msgid "from" msgstr "дан" #: ../src/js/viewers/audio.js:174 msgid "by" msgstr "билан" #: ../src/js/viewers/evince.js:79 #, c-format msgid "%d of %d" msgstr "%dдан %dтаси" #: ../src/libsushi/sushi-file-loader.c:639 #, c-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%dта элемент" #: ../src/libsushi/sushi-file-loader.c:651 msgid "Empty Folder" msgstr "Бўш жилд" 0707010000005D000081A4000000000000000000000001660EE2C800000A38000000000000000000000000000000000000001400000000sushi-46.0/po/vi.po# Vietnamese translation for sushi. # Copyright (C) 2011 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # Nguyễn Thái Ngọc Duy <pclouds@gmail.com>, 2011. # Antoine Đỗ <do.antoine@disroot.org>, 2021. # Trần Ngọc Quân <vnwildman@gmail.com>, 2021. # msgid "" msgstr "" "Project-Id-Version: sushi gnome master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2021-03-28 23:33+0000\n" "PO-Revision-Date: 2021-04-01 07:21+0700\n" "Last-Translator: Trần Ngọc Quân <vnwildman@gmail.com>\n" "Language-Team: Vietnamese <gnome-vi-list@gnome.org>\n" "Language: vi\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: Gtranslator 2.91.7\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "Cung cấp phương tiện để xem nhanh các kiểu tập tin khác nhau" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi là một trình xem trước tập tin cho môi trường máy tính để bàn " "GNOME. Đây là một thành phần độc lập tích hợp với Tập tin GNOME " "(Nautilus)." #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "Kiểu" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d mục" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "Thư mục rỗng" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "Kích thước" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "Sửa đổi" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "Không thể hiển thị %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "Mở bằng %s" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "Mở" #: src/viewers/audio.js:359 msgid "from" msgstr "từ" #: src/viewers/audio.js:364 msgid "by" msgstr "bởi" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d trên %d" #~ msgid "Loading…" #~ msgstr "Đang nạp…" 0707010000005E000081A4000000000000000000000001660EE2C800000A3F000000000000000000000000000000000000001700000000sushi-46.0/po/zh_CN.po# Simplified Chinese translation of sushi. # Copyright (C) 2011-2019 Free Software Foundation, Inc. # This file is distributed under the same license as the sushi package. # Kuang Chen <kuangchen@ucla.edu>, 2011. # YunQiang Su <wzssyqa@gmail.com>, 2011. # Dingzhong Chen <wsxy162@gmail.com>, 2019. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2021-01-25 19:28+0000\n" "PO-Revision-Date: 2021-01-28 13:46+0800\n" "Last-Translator: mars <gzhqyz@gmail.com>\n" "Language-Team: Chinese (China) <i18n-zh@googlegroups.com>\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: Poedit 2.4.1\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "提供快速查看不同类型文件的功能" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi 是 GNOME 桌面的文件预览工具,作为独立组件集成到文件(Nautilus)。" #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "类型" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d 个条目" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "空文件夹" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "大小" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "已修改" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "无法显示 %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "使用 %s 打开" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "打开" #: src/viewers/audio.js:359 msgid "from" msgstr "从" #: src/viewers/audio.js:364 msgid "by" msgstr "由" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "第 %d 页, 共 %d 页" #~ msgid "Client decoration" #~ msgstr "客户端装饰" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "是否由窗口自绘窗口管理器装饰" #~ msgid "Loading…" #~ msgstr "正在载入…" 0707010000005F000081A4000000000000000000000001660EE2C8000006DC000000000000000000000000000000000000001700000000sushi-46.0/po/zh_HK.po# Chinese (Hong Kong) translation for sushi. # Copyright (C) 2011 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # Cheng-Chia Tseng <pswo10680@gmail.com>, 2012. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2012-07-17 15:29+0800\n" "PO-Revision-Date: 2012-07-17 15:29+0800\n" "Last-Translator: Chao-Hsiung Liao <j_h_liau@yahoo.com.tw>\n" "Language-Team: Chinese (Hong Kong) <community@linuxhall.org>\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" #: ../data/org.gnome.sushi.gschema.xml.in.h:1 msgid "Client decoration" msgstr "客戶端裝飾" #: ../data/org.gnome.sushi.gschema.xml.in.h:2 msgid "Whether the window draws WM decorations itself" msgstr "視窗要是否描繪自身的視窗管理裝飾" #: ../src/js/ui/fallbackRenderer.js:120 msgid "Type" msgstr "類型" #: ../src/js/ui/fallbackRenderer.js:121 ../src/js/ui/fallbackRenderer.js:130 #: ../src/js/ui/fallbackRenderer.js:136 ../src/js/ui/spinnerBox.js:57 msgid "Loading…" msgstr "正在載入…" #: ../src/js/ui/fallbackRenderer.js:129 msgid "Size" msgstr "大小" #: ../src/js/ui/fallbackRenderer.js:135 msgid "Modified" msgstr "已修改" #: ../src/js/viewers/audio.js:172 msgid "from" msgstr "專輯" #: ../src/js/viewers/audio.js:174 msgid "by" msgstr "來自" #: ../src/js/viewers/evince.js:79 #, c-format msgid "%d of %d" msgstr "%d / %d" #: ../src/libsushi/sushi-file-loader.c:639 #, c-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d 個項目" #: ../src/libsushi/sushi-file-loader.c:651 msgid "Empty Folder" msgstr "空資料夾" 07070100000060000081A4000000000000000000000001660EE2C800000A66000000000000000000000000000000000000001700000000sushi-46.0/po/zh_TW.po# Chinese (Taiwan) translation for sushi. # Copyright (C) 2011 sushi's COPYRIGHT HOLDER # This file is distributed under the same license as the sushi package. # # Cheng-Chia Tseng <pswo10680@gmail.com>, 2012. # pan93412 <pan93412@gmail.com>, 2019. # Freddy Cheng <freddy4212@gmail.com>, 2022. # msgid "" msgstr "" "Project-Id-Version: sushi master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/sushi/issues\n" "POT-Creation-Date: 2022-05-06 10:02+0000\n" "PO-Revision-Date: 2022-09-10 17:24+0800\n" "Last-Translator: Cheng-Chia Tseng <pswo10680@gmail.com>\n" "Language-Team: Chinese - Taiwan <chinese-l10n@googlegroups.com>\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: Poedit 3.1.1\n" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:9 msgid "Sushi" msgstr "Sushi" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:10 msgid "Provide a facility for quickly viewing different kinds of files" msgstr "一個能夠快速檢視不同種類檔案的工具" #: data/org.gnome.NautilusPreviewer.appdata.xml.in:12 msgid "" "Sushi is a file previewer for the GNOME desktop environment. It is an " "independent component that integrates with GNOME Files (Nautilus)." msgstr "" "Sushi 是 GNOME 桌面環境的檔案預覽程式。它是整合於 GNOME 檔案 " "(Nautilus) 的獨立元件。" #: src/ui/fallbackRenderer.js:241 msgid "Type" msgstr "類型" #: src/ui/fallbackRenderer.js:251 #, javascript-format msgid "%d item" msgid_plural "%d items" msgstr[0] "%d 個項目" #: src/ui/fallbackRenderer.js:256 msgid "Empty Folder" msgstr "空資料夾" #: src/ui/fallbackRenderer.js:259 msgid "Size" msgstr "大小" #: src/ui/fallbackRenderer.js:264 msgid "Modified" msgstr "修改時間" #. TRANSLATORS: This is a filename, e.g. "image.jpg" #: src/ui/mainWindow.js:90 #, javascript-format msgid "Unable to display %s" msgstr "無法顯示 %s" #. TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" #: src/ui/mainWindow.js:342 #, javascript-format msgid "Open With %s" msgstr "用「%s」開啟" #: src/ui/mainWindow.js:348 msgid "Open" msgstr "開啟" #: src/viewers/audio.js:375 msgid "from" msgstr "專輯" #: src/viewers/audio.js:380 msgid "by" msgstr "來自" #: src/viewers/evince.js:94 #, javascript-format msgid "%d of %d" msgstr "%d/%d" #~ msgid "Client decoration" #~ msgstr "客戶端裝飾" #~ msgid "Whether the window draws WM decorations itself" #~ msgstr "視窗要是否描繪自身的視窗管理裝飾" #~ msgid "Loading…" #~ msgstr "正在載入…" 07070100000061000041ED000000000000000000000002660EE2C800000000000000000000000000000000000000000000000F00000000sushi-46.0/src07070100000062000041ED000000000000000000000002660EE2C800000000000000000000000000000000000000000000001800000000sushi-46.0/src/libsushi07070100000063000081A4000000000000000000000001660EE2C800004E01000000000000000000000000000000000000002900000000sushi-46.0/src/libsushi/SushiMediaBin.ui<?xml version="1.0" encoding="UTF-8"?> <!-- Generated with glade 3.20.0 --> <interface> <requires lib="gtk+" version="3.20"/> <object class="GtkImage" id="audio_playback_image"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="icon_name">media-playback-start-symbolic</property> </object> <object class="GtkImage" id="fullscreen_image"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="icon_size">1</property> <property name="icon_name">view-fullscreen-symbolic</property> </object> <object class="GtkAdjustment" id="playback_adjustment"> <property name="upper">128</property> <property name="step_increment">60</property> <property name="page_increment">300</property> <signal name="value-changed" handler="on_playback_adjustment_value_changed" swapped="no"/> </object> <object class="GtkImage" id="playback_image"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="icon_size">1</property> <property name="icon_name">media-playback-start-symbolic</property> </object> <object class="GtkAdjustment" id="volume_adjustment"> <property name="upper">1</property> <property name="value">1</property> <property name="step_increment">0.040000000000000001</property> <property name="page_increment">0.10000000000000001</property> </object> <template class="SushiMediaBin" parent="GtkBox"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="orientation">vertical</property> <signal name="realize" handler="on_sushi_media_bin_realize" swapped="no"/> <child> <object class="GtkStack" id="stack"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="hexpand">True</property> <property name="vexpand">True</property> <property name="hhomogeneous">False</property> <property name="vhomogeneous">False</property> <child> <object class="GtkOverlay" id="overlay"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property> <property name="no_show_all">True</property> <signal name="button-press-event" handler="on_overlay_button_press_event" swapped="no"/> <signal name="button-release-event" handler="on_overlay_button_release_event" swapped="no"/> <signal name="motion-notify-event" handler="on_overlay_motion_notify_event" swapped="no"/> <child> <placeholder/> </child> <child type="overlay"> <object class="GtkRevealer" id="top_revealer"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_STRUCTURE_MASK</property> <property name="valign">start</property> <signal name="leave-notify-event" handler="on_revealer_leave_notify_event" swapped="no"/> <signal name="motion-notify-event" handler="on_revealer_motion_notify_event" swapped="no"/> <child> <object class="GtkBox"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="orientation">vertical</property> <child> <object class="GtkLabel" id="title_label"> <property name="can_focus">False</property> <property name="halign">start</property> <style> <class name="title"/> </style> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkBox" id="info_box"> <property name="can_focus">False</property> <child> <placeholder/> </child> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">1</property> </packing> </child> <style> <class name="overlay-bar"/> <class name="top"/> </style> </object> </child> </object> <packing> <property name="index">1</property> </packing> </child> <child type="overlay"> <object class="GtkRevealer" id="bottom_revealer"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_STRUCTURE_MASK</property> <property name="valign">end</property> <property name="transition_type">crossfade</property> <signal name="leave-notify-event" handler="on_revealer_leave_notify_event" swapped="no"/> <signal name="motion-notify-event" handler="on_revealer_motion_notify_event" swapped="no"/> <child> <object class="GtkBox" id="bottom_box"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="valign">end</property> <property name="orientation">horizontal</property> <property name="margin-start">32</property> <property name="margin-end">32</property> <property name="margin-bottom">32</property> <child> <object class="GtkButton" id="playback_button"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="image">playback_image</property> <property name="relief">none</property> <signal name="clicked" handler="sushi_media_bin_toggle_playback" swapped="yes"/> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkLabel" id="progress_position_label"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="valign">center</property> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">1</property> </packing> </child> <child> <object class="GtkScale" id="progress_scale"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="adjustment">playback_adjustment</property> <property name="round_digits">2</property> <property name="draw_value">False</property> <signal name="format-value" handler="on_progress_scale_format_value" swapped="no"/> </object> <packing> <property name="expand">True</property> <property name="fill">True</property> <property name="position">2</property> </packing> </child> <child> <object class="GtkLabel" id="progress_duration_label"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="valign">center</property> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">3</property> </packing> </child> <child> <object class="GtkButton" id="fullscreen_button"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="image">fullscreen_image</property> <property name="relief">none</property> <signal name="clicked" handler="sushi_media_bin_toggle_fullscreen" swapped="yes"/> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="pack_type">end</property> <property name="position">4</property> </packing> </child> <child> <object class="GtkVolumeButton" id="volume_button"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="focus_on_click">False</property> <property name="receives_default">False</property> <property name="relief">none</property> <property name="orientation">vertical</property> <property name="value">1</property> <property name="size">menu</property> <property name="adjustment">volume_adjustment</property> <child internal-child="plus_button"> <object class="GtkButton"> <property name="can_focus">True</property> <property name="receives_default">True</property> <property name="halign">center</property> <property name="valign">center</property> <property name="relief">none</property> </object> </child> <child internal-child="minus_button"> <object class="GtkButton"> <property name="can_focus">True</property> <property name="receives_default">True</property> <property name="halign">center</property> <property name="valign">center</property> <property name="relief">none</property> </object> </child> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="pack_type">end</property> <property name="position">5</property> </packing> </child> <child> <placeholder/> </child> <style> <class name="osd"/> <class name="overlay-bar"/> <class name="bottom"/> </style> </object> </child> </object> <packing> <property name="index">2</property> </packing> </child> <child type="overlay"> <object class="GtkBox" id="play_box"> <property name="visible">False</property> <property name="can_focus">False</property> <property name="halign">center</property> <property name="valign">center</property> <child> <object class="GtkImage" id="play_image"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="pixel_size">32</property> <property name="icon_name">media-playback-start-symbolic</property> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkLabel" id="duration_label"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="halign">start</property> </object> <packing> <property name="expand">True</property> <property name="fill">True</property> <property name="position">1</property> </packing> </child> </object> <packing> <property name="pass_through">True</property> <property name="index">2</property> </packing> </child> </object> </child> <child> <object class="GtkBox" id="audio_box"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="spacing">2</property> <child> <object class="GtkButton" id="audio_playback_button"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">False</property> <property name="image">audio_playback_image</property> <property name="relief">none</property> <signal name="clicked" handler="sushi_media_bin_toggle_playback" swapped="yes"/> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkLabel" id="audio_position_label"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="width_chars">4</property> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">1</property> </packing> </child> <child> <object class="GtkScale" id="audio_progress_scale"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="adjustment">playback_adjustment</property> <property name="draw_value">False</property> </object> <packing> <property name="expand">True</property> <property name="fill">True</property> <property name="position">2</property> </packing> </child> <child> <object class="GtkLabel" id="audio_duration_label"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="width_chars">4</property> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="pack_type">end</property> <property name="position">4</property> </packing> </child> <child> <object class="GtkVolumeButton" id="audio_volume_button"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="focus_on_click">False</property> <property name="receives_default">False</property> <property name="relief">none</property> <property name="orientation">vertical</property> <property name="value">1</property> <property name="size">menu</property> <property name="adjustment">volume_adjustment</property> <child internal-child="plus_button"> <object class="GtkButton"> <property name="can_focus">True</property> <property name="receives_default">True</property> <property name="halign">center</property> <property name="valign">center</property> <property name="relief">none</property> </object> </child> <child internal-child="minus_button"> <object class="GtkButton"> <property name="can_focus">True</property> <property name="receives_default">True</property> <property name="halign">center</property> <property name="valign">center</property> <property name="relief">none</property> </object> </child> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="pack_type">end</property> <property name="position">3</property> </packing> </child> <style> <class name="bottom"/> <class name="audio"/> </style> </object> <packing> <property name="position">1</property> </packing> </child> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">0</property> </packing> </child> </template> </interface> 07070100000064000081A4000000000000000000000001660EE2C800000CE9000000000000000000000000000000000000003100000000sushi-46.0/src/libsushi/externalwindow-wayland.c/* * Copyright © 2016 Red Hat, Inc * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see <http://www.gnu.org/licenses/>. * * Authors: * Jonas Ådahl <jadahl@redhat.com> */ #include "config.h" #include <gdk/gdk.h> #include <gdk/gdkwayland.h> #include "externalwindow-wayland.h" static GdkDisplay *wayland_display; struct _ExternalWindowWayland { ExternalWindow parent; char *handle_str; }; struct _ExternalWindowWaylandClass { ExternalWindowClass parent_class; }; G_DEFINE_TYPE (ExternalWindowWayland, external_window_wayland, EXTERNAL_TYPE_WINDOW) static GdkDisplay * get_wayland_display (void) { if (wayland_display) return wayland_display; gdk_set_allowed_backends ("wayland"); wayland_display = gdk_display_open (NULL); gdk_set_allowed_backends (NULL); if (!wayland_display) g_warning ("Failed to open Wayland display"); return wayland_display; } ExternalWindowWayland * external_window_wayland_new (const char *handle_str) { ExternalWindowWayland *external_window_wayland; GdkDisplay *display; display = get_wayland_display (); if (!display) { g_warning ("No Wayland display connection, ignoring Wayland parent"); return NULL; } external_window_wayland = g_object_new (EXTERNAL_TYPE_WINDOW_WAYLAND, "display", display, NULL); external_window_wayland->handle_str = g_strdup (handle_str); return external_window_wayland; } static void external_window_wayland_set_parent_of (ExternalWindow *external_window, GdkWindow *child_window) { ExternalWindowWayland *external_window_wayland = EXTERNAL_WINDOW_WAYLAND (external_window); char *handle_str = external_window_wayland->handle_str; if (!gdk_wayland_window_set_transient_for_exported (child_window, handle_str)) g_warning ("Failed to set portal window transient for external parent"); } static void external_window_wayland_dispose (GObject *object) { ExternalWindowWayland *external_window_wayland = EXTERNAL_WINDOW_WAYLAND (object); g_free (external_window_wayland->handle_str); G_OBJECT_CLASS (external_window_wayland_parent_class)->dispose (object); } static void external_window_wayland_init (ExternalWindowWayland *external_window_wayland) { } static void external_window_wayland_class_init (ExternalWindowWaylandClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); ExternalWindowClass *external_window_class = EXTERNAL_WINDOW_CLASS (klass); object_class->dispose = external_window_wayland_dispose; external_window_class->set_parent_of = external_window_wayland_set_parent_of; } 07070100000065000081A4000000000000000000000001660EE2C800000515000000000000000000000000000000000000003100000000sushi-46.0/src/libsushi/externalwindow-wayland.h/* * Copyright © 2016 Red Hat, Inc * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see <http://www.gnu.org/licenses/>. * * Authors: * Jonas Ådahl <jadahl@redhat.com> */ #pragma once #include <glib-object.h> #include "externalwindow.h" #define EXTERNAL_TYPE_WINDOW_WAYLAND (external_window_wayland_get_type ()) #define EXTERNAL_WINDOW_WAYLAND(object) (G_TYPE_CHECK_INSTANCE_CAST (object, EXTERNAL_TYPE_WINDOW_WAYLAND, ExternalWindowWayland)) typedef struct _ExternalWindowWayland ExternalWindowWayland; typedef struct _ExternalWindowWaylandClass ExternalWindowWaylandClass; GType external_window_wayland_get_type (void); ExternalWindowWayland *external_window_wayland_new (const char *handle_str); 07070100000066000081A4000000000000000000000001660EE2C800000DCD000000000000000000000000000000000000002D00000000sushi-46.0/src/libsushi/externalwindow-x11.c/* * Copyright © 2016 Red Hat, Inc * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see <http://www.gnu.org/licenses/>. * * Authors: * Jonas Ådahl <jadahl@redhat.com> */ #include "config.h" #include <errno.h> #include <gdk/gdkx.h> #include <gdk/gdk.h> #include <stdlib.h> #include "externalwindow-x11.h" static GdkDisplay *x11_display; struct _ExternalWindowX11 { ExternalWindow parent; GdkWindow *foreign_gdk_window; }; struct _ExternalWindowX11Class { ExternalWindowClass parent_class; }; G_DEFINE_TYPE (ExternalWindowX11, external_window_x11, EXTERNAL_TYPE_WINDOW) static GdkDisplay * get_x11_display (void) { if (x11_display) return x11_display; gdk_set_allowed_backends ("x11"); x11_display = gdk_display_open (NULL); gdk_set_allowed_backends (NULL); if (!x11_display) g_warning ("Failed to open X11 display"); return x11_display; } ExternalWindowX11 * external_window_x11_new (const char *handle_str) { ExternalWindowX11 *external_window_x11; GdkDisplay *display; int xid; GdkWindow *foreign_gdk_window; display = get_x11_display (); if (!display) { g_warning ("No X display connection, ignoring X11 parent"); return NULL; } errno = 0; xid = strtol (handle_str, NULL, 16); if (errno != 0) { g_warning ("Failed to reference external X11 window, invalid XID %s", handle_str); return NULL; } foreign_gdk_window = gdk_x11_window_foreign_new_for_display (display, xid); if (!foreign_gdk_window) { g_warning ("Failed to create foreign window for XID %d", xid); return NULL; } external_window_x11 = g_object_new (EXTERNAL_TYPE_WINDOW_X11, "display", display, NULL); external_window_x11->foreign_gdk_window = foreign_gdk_window; return external_window_x11; } static void external_window_x11_set_parent_of (ExternalWindow *external_window, GdkWindow *child_window) { ExternalWindowX11 *external_window_x11 = EXTERNAL_WINDOW_X11 (external_window); gdk_window_set_transient_for (child_window, external_window_x11->foreign_gdk_window); } static void external_window_x11_dispose (GObject *object) { ExternalWindowX11 *external_window_x11 = EXTERNAL_WINDOW_X11 (object); g_clear_object (&external_window_x11->foreign_gdk_window); G_OBJECT_CLASS (external_window_x11_parent_class)->dispose (object); } static void external_window_x11_init (ExternalWindowX11 *external_window_x11) { } static void external_window_x11_class_init (ExternalWindowX11Class *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); ExternalWindowClass *external_window_class = EXTERNAL_WINDOW_CLASS (klass); object_class->dispose = external_window_x11_dispose; external_window_class->set_parent_of = external_window_x11_set_parent_of; } 07070100000067000081A4000000000000000000000001660EE2C8000004E2000000000000000000000000000000000000002D00000000sushi-46.0/src/libsushi/externalwindow-x11.h/* * Copyright © 2016 Red Hat, Inc * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see <http://www.gnu.org/licenses/>. * * Authors: * Jonas Ådahl <jadahl@redhat.com> */ #pragma once #include <glib-object.h> #include "externalwindow.h" #define EXTERNAL_TYPE_WINDOW_X11 (external_window_x11_get_type ()) #define EXTERNAL_WINDOW_X11(object) (G_TYPE_CHECK_INSTANCE_CAST (object, EXTERNAL_TYPE_WINDOW_X11, ExternalWindowX11)) typedef struct _ExternalWindowX11 ExternalWindowX11; typedef struct _ExternalWindowX11Class ExternalWindowX11Class; GType external_window_get_type (void); ExternalWindowX11 *external_window_x11_new (const char *handle_str); 07070100000068000081A4000000000000000000000001660EE2C8000012C2000000000000000000000000000000000000002900000000sushi-46.0/src/libsushi/externalwindow.c/* * Copyright © 2016 Red Hat, Inc * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see <http://www.gnu.org/licenses/>. * * Authors: * Jonas Ådahl <jadahl@redhat.com> */ #include "config.h" #include <string.h> #include "externalwindow.h" #ifdef HAVE_GTK_X11 #include "externalwindow-x11.h" #endif #ifdef HAVE_GTK_WAYLAND #include "externalwindow-wayland.h" #endif enum { PROP_0, PROP_DISPLAY, }; typedef struct _ExternalWindowPrivate { GdkDisplay *display; } ExternalWindowPrivate; G_DEFINE_TYPE_WITH_PRIVATE (ExternalWindow, external_window, G_TYPE_OBJECT) ExternalWindow * create_external_window_from_handle (const char *handle_str) { #ifdef HAVE_GTK_X11 { const char x11_prefix[] = "x11:"; if (g_str_has_prefix (handle_str, x11_prefix)) { ExternalWindowX11 *external_window_x11; const char *x11_handle_str = handle_str + strlen (x11_prefix); external_window_x11 = external_window_x11_new (x11_handle_str); return EXTERNAL_WINDOW (external_window_x11); } } #endif #ifdef HAVE_GTK_WAYLAND { const char wayland_prefix[] = "wayland:"; if (g_str_has_prefix (handle_str, wayland_prefix)) { ExternalWindowWayland *external_window_wayland; const char *wayland_handle_str = handle_str + strlen (wayland_prefix); external_window_wayland = external_window_wayland_new (wayland_handle_str); return EXTERNAL_WINDOW (external_window_wayland); } } #endif g_warning ("Unhandled parent window type %s\n", handle_str); return NULL; } void external_window_set_parent_of (ExternalWindow *external_window, GdkWindow *child_window) { EXTERNAL_WINDOW_GET_CLASS (external_window)->set_parent_of (external_window, child_window); } GdkDisplay * external_window_get_display (ExternalWindow *external_window) { ExternalWindowPrivate *priv = external_window_get_instance_private (external_window); return priv->display; } static void external_window_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { ExternalWindow *external_window = EXTERNAL_WINDOW (object); ExternalWindowPrivate *priv = external_window_get_instance_private (external_window); switch (prop_id) { case PROP_DISPLAY: g_set_object (&priv->display, g_value_get_object (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void external_window_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { ExternalWindow *external_window = EXTERNAL_WINDOW (object); ExternalWindowPrivate *priv = external_window_get_instance_private (external_window); switch (prop_id) { case PROP_DISPLAY: g_value_set_object (value, priv->display); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } } static void external_window_init (ExternalWindow *external_window) { } static void external_window_class_init (ExternalWindowClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->get_property = external_window_get_property; object_class->set_property = external_window_set_property; g_object_class_install_property (object_class, PROP_DISPLAY, g_param_spec_object ("display", "GdkDisplay", "The GdkDisplay instance", GDK_TYPE_DISPLAY, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); } 07070100000069000081A4000000000000000000000001660EE2C80000076C000000000000000000000000000000000000002900000000sushi-46.0/src/libsushi/externalwindow.h/* * Copyright © 2016 Red Hat, Inc * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see <http://www.gnu.org/licenses/>. * * Authors: * Jonas Ådahl <jadahl@redhat.com> */ #pragma once #include <glib-object.h> #include <gtk/gtk.h> #define EXTERNAL_TYPE_WINDOW (external_window_get_type ()) #define EXTERNAL_WINDOW(object) (G_TYPE_CHECK_INSTANCE_CAST (object, EXTERNAL_TYPE_WINDOW, ExternalWindow)) #define EXTERNAL_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST (klass, EXTERNAL_TYPE_WINDOW, ExternalWindowClass)) #define EXTERNAL_WINDOW_GET_CLASS(klass) (G_TYPE_INSTANCE_GET_CLASS (klass, EXTERNAL_TYPE_WINDOW, ExternalWindowClass)) typedef struct _ExternalWindow ExternalWindow; typedef struct _ExternalWindowClass ExternalWindowClass; struct _ExternalWindow { GObject parent_instance; }; struct _ExternalWindowClass { GObjectClass parent_class; void (*set_parent_of) (ExternalWindow *external_window, GdkWindow *child_window); }; GType external_window_get_type (void); ExternalWindow *create_external_window_from_handle (const char *handle_str); void external_window_set_parent_of (ExternalWindow *external_window, GdkWindow *child_window); GdkDisplay *external_window_get_display (ExternalWindow *external_window); 0707010000006A000081A4000000000000000000000001660EE2C8000006ED000000000000000000000000000000000000002400000000sushi-46.0/src/libsushi/meson.buildconfig_data = configuration_data() if gtk_x11_dep.found() config_data.set('HAVE_GTK_X11', 1) endif if gtk_wayland_dep.found() config_data.set('HAVE_GTK_WAYLAND', 1) endif configure_file(output: 'config.h', configuration: config_data) externalwindow_sources = [ 'externalwindow.c', 'externalwindow.h', ] if gtk_x11_dep.found() externalwindow_sources += [ 'externalwindow-x11.c', 'externalwindow-x11.h', ] endif if gtk_wayland_dep.found() externalwindow_sources += [ 'externalwindow-wayland.c', 'externalwindow-wayland.h', ] endif libsushi_deps = [ epoxy_dep, evince_document_dep, evince_view_dep, freetype_dep, gdk_pixbuf_dep, glib_dep, gstreamer_dep, gstreamer_audio_dep, gstreamer_tag_dep, gstreamer_video_dep, gtk_dep, harfbuzz_dep, ] libsushi_sources = [ 'sushi-font-loader.c', 'sushi-font-loader.h', 'sushi-font-widget.c', 'sushi-font-widget.h', 'sushi-media-bin.c', 'sushi-media-bin.h', 'sushi-utils.c', 'sushi-utils.h', ] libsushi_resource = gnome.compile_resources( 'sushi-lib-resources', 'org.gnome.Libsushi.gresource.xml', c_name: 'sushi' ) libsushi = shared_library( 'sushi-1.0', dependencies: libsushi_deps, sources: [ externalwindow_sources, libsushi_sources, libsushi_resource ], install: true, install_dir: pkglibdir ) gnome.generate_gir( libsushi, sources: [ libsushi_sources, ], nsversion: '1.0', namespace: 'Sushi', symbol_prefix: 'sushi', identifier_prefix: 'Sushi', includes: [ 'GstTag-1.0', 'GdkPixbuf-2.0', 'Gtk-3.0', 'EvinceDocument-3.0', 'EvinceView-3.0', ], install: true, install_dir_gir: join_paths(pkgdatadir, 'gir-1.0'), install_dir_typelib: join_paths(pkglibdir, 'girepository-1.0'), ) 0707010000006B000081A4000000000000000000000001660EE2C8000000C9000000000000000000000000000000000000003900000000sushi-46.0/src/libsushi/org.gnome.Libsushi.gresource.xml<?xml version="1.0" encoding="UTF-8"?> <gresources> <gresource prefix="/org/gnome/Sushi/libsushi"> <file>SushiMediaBin.ui</file> <file>sushi-media-bin.css</file> </gresource> </gresources> 0707010000006C000081A4000000000000000000000001660EE2C800001667000000000000000000000000000000000000002C00000000sushi-46.0/src/libsushi/sushi-font-loader.c/* * Copyright (C) 2011 Red Hat, Inc. * * 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 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. * * The Sushi project hereby grant permission for non-gpl compatible GStreamer * plugins to be used and distributed together with GStreamer and Sushi. This * permission is above and beyond the permissions granted by the GPL license * Sushi is covered by. * * Authors: Cosimo Cecchi <cosimoc@redhat.com> * */ #include "sushi-font-loader.h" #include <stdlib.h> #include <ft2build.h> #include FT_FREETYPE_H #include <gio/gio.h> typedef struct { FT_Library library; FT_Long face_index; GFile *file; gchar *face_contents; gsize face_length; } FontLoadJob; static FontLoadJob * font_load_job_new (FT_Library library, const gchar *uri, gint face_index, GAsyncReadyCallback callback, gpointer user_data) { FontLoadJob *job = g_slice_new0 (FontLoadJob); job->library = library; job->face_index = (FT_Long) face_index; job->file = g_file_new_for_uri (uri); return job; } static void font_load_job_free (FontLoadJob *job) { g_clear_object (&job->file); g_free (job->face_contents); g_slice_free (FontLoadJob, job); } G_DEFINE_AUTOPTR_CLEANUP_FUNC (FontLoadJob, font_load_job_free) static void face_data_finalizer (void *object) { FT_Face face = object; g_clear_object (&face->generic.data); } static FT_Face create_face_from_contents (FontLoadJob *job, gchar **contents, GError **error) { FT_Error ft_error; FT_Face retval; ft_error = FT_New_Memory_Face (job->library, (const FT_Byte *) job->face_contents, (FT_Long) job->face_length, job->face_index, &retval); if (ft_error != 0) { g_autofree gchar *uri = g_file_get_uri (job->file); g_set_error (error, G_IO_ERROR, 0, "Unable to read the font face file '%s'", uri); return NULL; } retval->generic.data = g_object_ref (job->file); retval->generic.finalizer = face_data_finalizer; *contents = g_steal_pointer (&job->face_contents); return retval; } static gboolean font_load_job_do_load (FontLoadJob *job, GError **error) { return g_file_load_contents (job->file, NULL, &job->face_contents, &job->face_length, NULL, error); } static void font_load_job (GTask *task, gpointer source_object, gpointer user_data, GCancellable *cancellable) { FontLoadJob *job = user_data; g_autoptr(GError) error = NULL; font_load_job_do_load (job, &error); if (error != NULL) g_task_return_error (task, g_steal_pointer (&error)); else g_task_return_boolean (task, TRUE); } /** * sushi_new_ft_face_from_uri: (skip) * */ FT_Face sushi_new_ft_face_from_uri (FT_Library library, const gchar *uri, gint face_index, gchar **contents, GError **error) { g_autoptr(FontLoadJob) job = font_load_job_new (library, uri, face_index, NULL, NULL); if (!font_load_job_do_load (job, error)) return NULL; return create_face_from_contents (job, contents, error); } /** * sushi_new_ft_face_from_uri_async: (skip) * */ void sushi_new_ft_face_from_uri_async (FT_Library library, const gchar *uri, gint face_index, GAsyncReadyCallback callback, gpointer user_data) { FontLoadJob *job = font_load_job_new (library, uri, face_index, callback, user_data); g_autoptr(GTask) task = g_task_new (NULL, NULL, callback, user_data); g_task_set_task_data (task, job, (GDestroyNotify) font_load_job_free); g_task_run_in_thread (task, font_load_job); } /** * sushi_new_ft_face_from_uri_finish: (skip) * */ FT_Face sushi_new_ft_face_from_uri_finish (GAsyncResult *result, gchar **contents, GError **error) { FontLoadJob *job; if (!g_task_propagate_boolean (G_TASK (result), error)) return NULL; job = g_task_get_task_data (G_TASK (result)); return create_face_from_contents (job, contents, error); } /** * sushi_get_font_name: (skip) * */ gchar * sushi_get_font_name (FT_Face face, gboolean short_form) { const char *style_name = face->style_name; const char *family_name = face->family_name; if (family_name == NULL) { /* Try to get the basename of the file this was loaded from */ GFile *file = face->generic.data; if (G_IS_FILE (file)) return g_file_get_basename (file); /* Use an empty string as the last fallback */ return g_strdup (""); } if (style_name == NULL || (short_form && g_strcmp0 (style_name, "Regular") == 0)) return g_strdup (family_name); return g_strconcat (family_name, ", ", style_name, NULL); } 0707010000006D000081A4000000000000000000000001660EE2C8000007ED000000000000000000000000000000000000002C00000000sushi-46.0/src/libsushi/sushi-font-loader.h/* * Copyright (C) 2011 Red Hat, Inc. * * 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 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. * * The Sushi project hereby grant permission for non-gpl compatible GStreamer * plugins to be used and distributed together with GStreamer and Sushi. This * permission is above and beyond the permissions granted by the GPL license * Sushi is covered by. * * Authors: Cosimo Cecchi <cosimoc@redhat.com> * */ #ifndef __SUSHI_FONT_LOADER_H__ #define __SUSHI_FONT_LOADER_H__ #include <ft2build.h> #include FT_FREETYPE_H #include <gio/gio.h> FT_Face sushi_new_ft_face_from_uri (FT_Library library, const gchar *uri, gint face_index, gchar **contents, GError **error); void sushi_new_ft_face_from_uri_async (FT_Library library, const gchar *uri, gint face_index, GAsyncReadyCallback callback, gpointer user_data); FT_Face sushi_new_ft_face_from_uri_finish (GAsyncResult *result, gchar **contents, GError **error); gchar * sushi_get_font_name (FT_Face face, gboolean short_form); #endif /* __SUSHI_FONT_LOADER_H__ */ 0707010000006E000081A4000000000000000000000001660EE2C800005BE0000000000000000000000000000000000000002C00000000sushi-46.0/src/libsushi/sushi-font-widget.c/* * Copyright (C) 2011 Red Hat, Inc. * Copyright (C) 2014 Khaled Hosny <khaledhosny@eglug.org>. * * 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 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. * * The Sushi project hereby grant permission for non-gpl compatible GStreamer * plugins to be used and distributed together with GStreamer and Sushi. This * permission is above and beyond the permissions granted by the GPL license * Sushi is covered by. * * Authors: Cosimo Cecchi <cosimoc@redhat.com> * */ #include "sushi-font-widget.h" #include "sushi-font-loader.h" #include <hb-glib.h> #include <math.h> enum { PROP_URI = 1, PROP_FACE_INDEX, NUM_PROPERTIES }; enum { LOADED, ERROR, NUM_SIGNALS }; struct _SushiFontWidget { GtkDrawingArea parent_instance; gchar *uri; gint face_index; FT_Library library; FT_Face face; gchar *face_contents; const gchar *lowercase_text; const gchar *uppercase_text; const gchar *punctuation_text; gchar *sample_string; gchar *font_name; }; static GParamSpec *properties[NUM_PROPERTIES] = { NULL, }; static guint signals[NUM_SIGNALS] = { 0, }; G_DEFINE_TYPE (SushiFontWidget, sushi_font_widget, GTK_TYPE_DRAWING_AREA) #define SURFACE_SIZE 4 #define SECTION_SPACING 16 #define LINE_SPACING 2 static const gchar lowercase_text_stock[] = "abcdefghijklmnopqrstuvwxyz"; static const gchar uppercase_text_stock[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; static const gchar punctuation_text_stock[] = "0123456789.:,;(*!?')"; static void text_to_glyphs (cairo_t *cr, const gchar *text, cairo_glyph_t **glyphs, int *num_glyphs) { PangoAttribute *fallback_attr; PangoAttrList *attr_list; PangoContext *context; PangoDirection base_dir; GList *items; GList *visual_items; FT_Face ft_face; hb_font_t *hb_font; gdouble x = 0, y = 0; gint i; gdouble x_scale, y_scale; *num_glyphs = 0; *glyphs = NULL; base_dir = pango_find_base_dir (text, -1); cairo_scaled_font_t *cr_font = cairo_get_scaled_font (cr); ft_face = cairo_ft_scaled_font_lock_face (cr_font); hb_font = hb_ft_font_create (ft_face, NULL); cairo_surface_t *target = cairo_get_target (cr); cairo_surface_get_device_scale (target, &x_scale, &y_scale); /* We abuse pango itemazation to split text into script and direction * runs, since we use our fonts directly no through pango, we don't * bother changing the default font, but we disable font fallback as * pango will split runs at font change */ context = pango_cairo_create_context (cr); attr_list = pango_attr_list_new (); fallback_attr = pango_attr_fallback_new (FALSE); pango_attr_list_insert (attr_list, fallback_attr); items = pango_itemize_with_base_dir (context, base_dir, text, 0, strlen (text), attr_list, NULL); g_object_unref (context); pango_attr_list_unref (attr_list); /* reorder the items in the visual order */ visual_items = pango_reorder_items (items); while (visual_items) { PangoItem *item; PangoAnalysis analysis; hb_buffer_t *hb_buffer; hb_glyph_info_t *hb_glyphs; hb_glyph_position_t *hb_positions; gint n; item = visual_items->data; analysis = item->analysis; hb_buffer = hb_buffer_create (); hb_buffer_add_utf8 (hb_buffer, text, -1, item->offset, item->length); hb_buffer_set_script (hb_buffer, hb_glib_script_to_script (analysis.script)); hb_buffer_set_language (hb_buffer, hb_language_from_string (pango_language_to_string (analysis.language), -1)); hb_buffer_set_direction (hb_buffer, analysis.level % 2 ? HB_DIRECTION_RTL : HB_DIRECTION_LTR); hb_shape (hb_font, hb_buffer, NULL, 0); n = hb_buffer_get_length (hb_buffer); hb_glyphs = hb_buffer_get_glyph_infos (hb_buffer, NULL); hb_positions = hb_buffer_get_glyph_positions (hb_buffer, NULL); *glyphs = g_renew (cairo_glyph_t, *glyphs, *num_glyphs + n); for (i = 0; i < n; i++) { (*glyphs)[*num_glyphs + i].index = hb_glyphs[i].codepoint; (*glyphs)[*num_glyphs + i].x = x + (hb_positions[i].x_offset / (64. * x_scale)); (*glyphs)[*num_glyphs + i].y = y - (hb_positions[i].y_offset / (64. * y_scale)); x += (hb_positions[i].x_advance / (64. * x_scale)); y -= (hb_positions[i].y_advance / (64. * y_scale)); } *num_glyphs += n; hb_buffer_destroy (hb_buffer); visual_items = visual_items->next; } g_list_free_full (visual_items, (GDestroyNotify) pango_item_free); g_list_free_full (items, (GDestroyNotify) pango_item_free); hb_font_destroy (hb_font); cairo_ft_scaled_font_unlock_face (cr_font); } static void text_extents (cairo_t *cr, const char *text, cairo_text_extents_t *extents) { g_autofree cairo_glyph_t *glyphs = NULL; gint num_glyphs; text_to_glyphs (cr, text, &glyphs, &num_glyphs); cairo_glyph_extents (cr, glyphs, num_glyphs, extents); } /* adapted from gnome-utils:font-viewer/font-view.c * * Copyright (C) 2002-2003 James Henstridge <james@daa.com.au> * Copyright (C) 2010 Cosimo Cecchi <cosimoc@gnome.org> * * License: GPLv2+ */ static void draw_string (SushiFontWidget *self, cairo_t *cr, GtkBorder padding, const gchar *text, gint *pos_y) { g_autofree cairo_glyph_t *glyphs = NULL; cairo_font_extents_t font_extents; cairo_text_extents_t extents; GtkTextDirection text_dir; gint pos_x; gint num_glyphs; gint i; text_dir = gtk_widget_get_direction (GTK_WIDGET (self)); text_to_glyphs (cr, text, &glyphs, &num_glyphs); cairo_font_extents (cr, &font_extents); cairo_glyph_extents (cr, glyphs, num_glyphs, &extents); if (pos_y != NULL) *pos_y += font_extents.ascent + font_extents.descent + extents.y_advance + LINE_SPACING / 2; if (text_dir == GTK_TEXT_DIR_LTR) pos_x = padding.left; else { pos_x = gtk_widget_get_allocated_width (GTK_WIDGET (self)) - extents.x_advance - padding.right; } for (i = 0; i < num_glyphs; i++) { glyphs[i].x += pos_x; glyphs[i].y += *pos_y; } cairo_move_to (cr, pos_x, *pos_y); cairo_show_glyphs (cr, glyphs, num_glyphs); *pos_y += LINE_SPACING / 2; } static gboolean check_font_contain_text (FT_Face face, const gchar *text) { g_autofree gunichar *string = NULL; glong len, idx; string = g_utf8_to_ucs4_fast (text, -1, &len); for (idx = 0; idx < len; idx++) { gunichar c = string[idx]; if (!FT_Get_Char_Index (face, c)) return FALSE; } return TRUE; } static gchar * build_charlist_for_face (FT_Face face, gint *length) { g_autoptr(GString) string = NULL; gulong c; guint glyph; gint total_chars = 0; string = g_string_new (NULL); c = FT_Get_First_Char (face, &glyph); while (glyph != 0) { g_string_append_unichar (string, (gunichar) c); c = FT_Get_Next_Char (face, c, &glyph); total_chars++; } if (length) *length = total_chars; return g_strdup (string->str); } static gchar * random_string_from_available_chars (FT_Face face, gint n_chars) { g_autofree gchar *chars = NULL; g_autoptr(GString) retval = NULL; gint idx, rand, total_chars; gchar *ptr, *end; idx = 0; chars = build_charlist_for_face (face, &total_chars); if (total_chars == 0) return NULL; if (total_chars <= n_chars) return g_steal_pointer (&chars); retval = g_string_new (NULL); while (idx < n_chars) { rand = g_random_int_range (0, total_chars); ptr = g_utf8_offset_to_pointer (chars, rand); end = g_utf8_find_next_char (ptr, NULL); g_string_append_len (retval, ptr, end - ptr); idx++; } return g_strdup (retval->str); } static gboolean set_pango_sample_string (SushiFontWidget *self) { const gchar *sample_string; gboolean retval = FALSE; sample_string = pango_language_get_sample_string (pango_language_from_string (NULL)); if (check_font_contain_text (self->face, sample_string)) retval = TRUE; if (!retval) { sample_string = pango_language_get_sample_string (pango_language_from_string ("C")); if (check_font_contain_text (self->face, sample_string)) retval = TRUE; } g_clear_pointer (&self->sample_string, g_free); if (retval) self->sample_string = g_strdup (sample_string); return retval; } static void select_best_charmap (SushiFontWidget *self) { gchar *chars; gint idx, n_chars; if (FT_Select_Charmap (self->face, FT_ENCODING_UNICODE) == 0) return; for (idx = 0; idx < self->face->num_charmaps; idx++) { if (FT_Set_Charmap (self->face, self->face->charmaps[idx]) != 0) continue; chars = build_charlist_for_face (self->face, &n_chars); g_free (chars); if (n_chars > 0) break; } } static void build_strings_for_face (SushiFontWidget *self) { select_best_charmap (self); /* if we don't have lowercase/uppercase/punctuation text in the face, * we omit it directly, and render a random text below. */ if (check_font_contain_text (self->face, lowercase_text_stock)) self->lowercase_text = lowercase_text_stock; else self->lowercase_text = NULL; if (check_font_contain_text (self->face, uppercase_text_stock)) self->uppercase_text = uppercase_text_stock; else self->uppercase_text = NULL; if (check_font_contain_text (self->face, punctuation_text_stock)) self->punctuation_text = punctuation_text_stock; else self->punctuation_text = NULL; if (!set_pango_sample_string (self)) self->sample_string = random_string_from_available_chars (self->face, 36); g_free (self->font_name); self->font_name = sushi_get_font_name (self->face, FALSE); } static gint * build_sizes_table (FT_Face face, gint *n_sizes, gint *alpha_size, gint *title_size) { gint *sizes = NULL; gint i; /* work out what sizes to render */ if (FT_IS_SCALABLE (face)) { *n_sizes = 14; sizes = g_new (gint, *n_sizes); sizes[0] = 8; sizes[1] = 10; sizes[2] = 12; sizes[3] = 18; sizes[4] = 24; sizes[5] = 36; sizes[6] = 48; sizes[7] = 72; sizes[8] = 96; sizes[9] = 120; sizes[10] = 144; sizes[11] = 168; sizes[12] = 192; sizes[13] = 216; *alpha_size = 24; *title_size = 48; } else { gint alpha_diff = G_MAXINT; gint title_diff = G_MAXINT; /* use fixed sizes */ *n_sizes = face->num_fixed_sizes; sizes = g_new (gint, *n_sizes); *alpha_size = 0; for (i = 0; i < face->num_fixed_sizes; i++) { sizes[i] = face->available_sizes[i].height; if ((gint) (abs (sizes[i] - 24)) < alpha_diff) { alpha_diff = (gint) abs (sizes[i] - 24); *alpha_size = sizes[i]; } if ((gint) (abs (sizes[i] - 24)) < title_diff) { title_diff = (gint) abs (sizes[i] - 24); *title_size = sizes[i]; } } } return sizes; } static void sushi_font_widget_size_request (GtkWidget *drawing_area, gint *width, gint *height, gint *min_height) { SushiFontWidget *self = SUSHI_FONT_WIDGET (drawing_area); gint i, pixmap_width, pixmap_height; cairo_text_extents_t extents; cairo_font_extents_t font_extents; cairo_font_face_t *font; g_autofree gint *sizes = NULL; gint n_sizes, alpha_size, title_size; cairo_t *cr; cairo_surface_t *surface; FT_Face face = self->face; GtkStyleContext *context; GtkStateFlags state; GtkBorder padding; if (face == NULL) { if (width != NULL) *width = 1; if (height != NULL) *height = 1; if (min_height != NULL) *min_height = 1; return; } if (min_height != NULL) *min_height = -1; surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, SURFACE_SIZE, SURFACE_SIZE); cr = cairo_create (surface); context = gtk_widget_get_style_context (drawing_area); state = gtk_style_context_get_state (context); gtk_style_context_get_padding (context, state, &padding); sizes = build_sizes_table (face, &n_sizes, &alpha_size, &title_size); /* calculate size of pixmap to use */ pixmap_width = padding.left + padding.right; pixmap_height = padding.top + padding.bottom; font = cairo_ft_font_face_create_for_ft_face (face, 0); if (check_font_contain_text (face, self->font_name)) cairo_set_font_face (cr, font); else cairo_set_font_face (cr, NULL); cairo_set_font_size (cr, title_size); cairo_font_extents (cr, &font_extents); text_extents (cr, self->font_name, &extents); pixmap_height += font_extents.ascent + font_extents.descent + extents.y_advance + LINE_SPACING; pixmap_width = MAX (pixmap_width, extents.width + padding.left + padding.right); pixmap_height += SECTION_SPACING / 2; cairo_set_font_face (cr, font); cairo_set_font_size (cr, alpha_size); cairo_font_extents (cr, &font_extents); if (self->lowercase_text != NULL) { text_extents (cr, self->lowercase_text, &extents); pixmap_height += font_extents.ascent + font_extents.descent + extents.y_advance + LINE_SPACING; pixmap_width = MAX (pixmap_width, extents.width + padding.left + padding.right); } if (self->uppercase_text != NULL) { text_extents (cr, self->uppercase_text, &extents); pixmap_height += font_extents.ascent + font_extents.descent + extents.y_advance + LINE_SPACING; pixmap_width = MAX (pixmap_width, extents.width + padding.left + padding.right); } if (self->punctuation_text != NULL) { text_extents (cr, self->punctuation_text, &extents); pixmap_height += font_extents.ascent + font_extents.descent + extents.y_advance + LINE_SPACING; pixmap_width = MAX (pixmap_width, extents.width + padding.left + padding.right); } if (self->sample_string != NULL) { pixmap_height += SECTION_SPACING; for (i = 0; i < n_sizes; i++) { cairo_set_font_size (cr, sizes[i]); cairo_font_extents (cr, &font_extents); text_extents (cr, self->sample_string, &extents); pixmap_height += font_extents.ascent + font_extents.descent + extents.y_advance + LINE_SPACING; pixmap_width = MAX (pixmap_width, extents.width + padding.left + padding.right); if ((i == 7) && (min_height != NULL)) *min_height = pixmap_height; } } pixmap_height += padding.bottom + SECTION_SPACING; if (min_height != NULL && *min_height == -1) *min_height = pixmap_height; if (width != NULL) *width = pixmap_width; if (height != NULL) *height = pixmap_height; cairo_destroy (cr); cairo_font_face_destroy (font); cairo_surface_destroy (surface); } static void sushi_font_widget_get_preferred_width (GtkWidget *drawing_area, gint *minimum_width, gint *natural_width) { gint width; sushi_font_widget_size_request (drawing_area, &width, NULL, NULL); *minimum_width = 0; *natural_width = width; } static void sushi_font_widget_get_preferred_height (GtkWidget *drawing_area, gint *minimum_height, gint *natural_height) { gint height, min_height; sushi_font_widget_size_request (drawing_area, NULL, &height, &min_height); *minimum_height = min_height; *natural_height = height; } static gboolean sushi_font_widget_draw (GtkWidget *drawing_area, cairo_t *cr) { SushiFontWidget *self = SUSHI_FONT_WIDGET (drawing_area); g_autofree gint *sizes = NULL; gint n_sizes, alpha_size, title_size, pos_y = 0, i; cairo_font_face_t *font = NULL; FT_Face face = self->face; GtkStyleContext *context; GdkRGBA color; GtkBorder padding; GtkStateFlags state; gint allocated_width, allocated_height; if (face == NULL) return FALSE; context = gtk_widget_get_style_context (drawing_area); state = gtk_style_context_get_state (context); allocated_width = gtk_widget_get_allocated_width (drawing_area); allocated_height = gtk_widget_get_allocated_height (drawing_area); gtk_render_background (context, cr, 0, 0, allocated_width, allocated_height); gtk_style_context_get_color (context, state, &color); gtk_style_context_get_padding (context, state, &padding); gdk_cairo_set_source_rgba (cr, &color); sizes = build_sizes_table (face, &n_sizes, &alpha_size, &title_size); font = cairo_ft_font_face_create_for_ft_face (face, 0); /* draw text */ if (check_font_contain_text (face, self->font_name)) cairo_set_font_face (cr, font); else cairo_set_font_face (cr, NULL); cairo_set_font_size (cr, title_size); draw_string (self, cr, padding, self->font_name, &pos_y); if (pos_y > allocated_height) goto end; pos_y += SECTION_SPACING / 2; cairo_set_font_face (cr, font); cairo_set_font_size (cr, alpha_size); if (self->lowercase_text != NULL) draw_string (self, cr, padding, self->lowercase_text, &pos_y); if (pos_y > allocated_height) goto end; if (self->uppercase_text != NULL) draw_string (self, cr, padding, self->uppercase_text, &pos_y); if (pos_y > allocated_height) goto end; if (self->punctuation_text != NULL) draw_string (self, cr, padding, self->punctuation_text, &pos_y); if (pos_y > allocated_height) goto end; pos_y += SECTION_SPACING; for (i = 0; i < n_sizes; i++) { cairo_set_font_size (cr, sizes[i]); if (self->sample_string != NULL) draw_string (self, cr, padding, self->sample_string, &pos_y); if (pos_y > allocated_height) break; } end: cairo_font_face_destroy (font); return FALSE; } static void font_face_async_ready_cb (GObject *object, GAsyncResult *result, gpointer user_data) { SushiFontWidget *self = user_data; g_autoptr(GError) error = NULL; self->face = sushi_new_ft_face_from_uri_finish (result, &self->face_contents, &error); if (error != NULL) { g_signal_emit (self, signals[ERROR], 0, error); g_print ("Can't load the font face: %s\n", error->message); return; } build_strings_for_face (self); gtk_widget_queue_resize (GTK_WIDGET (self)); g_signal_emit (self, signals[LOADED], 0); } void sushi_font_widget_load (SushiFontWidget *self) { sushi_new_ft_face_from_uri_async (self->library, self->uri, self->face_index, font_face_async_ready_cb, self); } static void sushi_font_widget_init (SushiFontWidget *self) { FT_Error err = FT_Init_FreeType (&self->library); if (err != FT_Err_Ok) g_error ("Unable to initialize FreeType"); gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (self)), GTK_STYLE_CLASS_VIEW); } static void sushi_font_widget_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { SushiFontWidget *self = SUSHI_FONT_WIDGET (object); switch (prop_id) { case PROP_URI: g_value_set_string (value, self->uri); break; case PROP_FACE_INDEX: g_value_set_int (value, self->face_index); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void sushi_font_widget_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { SushiFontWidget *self = SUSHI_FONT_WIDGET (object); switch (prop_id) { case PROP_URI: self->uri = g_value_dup_string (value); break; case PROP_FACE_INDEX: self->face_index = g_value_get_int (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void sushi_font_widget_finalize (GObject *object) { SushiFontWidget *self = SUSHI_FONT_WIDGET (object); g_free (self->uri); if (self->face != NULL) { FT_Done_Face (self->face); self->face = NULL; } g_free (self->font_name); g_free (self->sample_string); g_free (self->face_contents); if (self->library != NULL) { FT_Done_FreeType (self->library); self->library = NULL; } G_OBJECT_CLASS (sushi_font_widget_parent_class)->finalize (object); } static void sushi_font_widget_constructed (GObject *object) { SushiFontWidget *self = SUSHI_FONT_WIDGET (object); sushi_font_widget_load (self); G_OBJECT_CLASS (sushi_font_widget_parent_class)->constructed (object); } static void sushi_font_widget_class_init (SushiFontWidgetClass *klass) { GObjectClass *oclass = G_OBJECT_CLASS (klass); GtkWidgetClass *wclass = GTK_WIDGET_CLASS (klass); oclass->finalize = sushi_font_widget_finalize; oclass->set_property = sushi_font_widget_set_property; oclass->get_property = sushi_font_widget_get_property; oclass->constructed = sushi_font_widget_constructed; wclass->draw = sushi_font_widget_draw; wclass->get_preferred_width = sushi_font_widget_get_preferred_width; wclass->get_preferred_height = sushi_font_widget_get_preferred_height; properties[PROP_URI] = g_param_spec_string ("uri", "Uri", "Uri", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT); properties[PROP_FACE_INDEX] = g_param_spec_int ("face-index", "Face index", "Face index", 0, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT); signals[LOADED] = g_signal_new ("loaded", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); signals[ERROR] = g_signal_new ("error", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_ERROR); g_object_class_install_properties (oclass, NUM_PROPERTIES, properties); } SushiFontWidget * sushi_font_widget_new (const gchar *uri, gint face_index) { return g_object_new (SUSHI_TYPE_FONT_WIDGET, "uri", uri, "face-index", face_index, NULL); } /** * sushi_font_widget_get_ft_face: (skip) * */ FT_Face sushi_font_widget_get_ft_face (SushiFontWidget *self) { return self->face; } const gchar * sushi_font_widget_get_uri (SushiFontWidget *self) { return self->uri; } 0707010000006F000081A4000000000000000000000001660EE2C80000069C000000000000000000000000000000000000002C00000000sushi-46.0/src/libsushi/sushi-font-widget.h/* * Copyright (C) 2011 Red Hat, Inc. * * 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 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. * * The Sushi project hereby grant permission for non-gpl compatible GStreamer * plugins to be used and distributed together with GStreamer and Sushi. This * permission is above and beyond the permissions granted by the GPL license * Sushi is covered by. * * Authors: Cosimo Cecchi <cosimoc@redhat.com> * */ #ifndef __SUSHI_FONT_WIDGET_H__ #define __SUSHI_FONT_WIDGET_H__ #include <glib-object.h> #include <gtk/gtk.h> #include <cairo/cairo-ft.h> #include <hb-ft.h> G_BEGIN_DECLS #define SUSHI_TYPE_FONT_WIDGET (sushi_font_widget_get_type ()) G_DECLARE_FINAL_TYPE (SushiFontWidget, sushi_font_widget, SUSHI, FONT_WIDGET, GtkDrawingArea) SushiFontWidget *sushi_font_widget_new (const gchar *uri, gint face_index); FT_Face sushi_font_widget_get_ft_face (SushiFontWidget *self); const gchar *sushi_font_widget_get_uri (SushiFontWidget *self); void sushi_font_widget_load (SushiFontWidget *self); G_END_DECLS #endif /* __SUSHI_FONT_WIDGET_H__ */ 07070100000070000081A4000000000000000000000001660EE2C800011147000000000000000000000000000000000000002A00000000sushi-46.0/src/libsushi/sushi-media-bin.c/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ /* * sushi-media-bin.c * Based on ekn-media-bin.c from: * https://github.com/endlessm/eos-knowledge-lib/tree/master/lib/eosknowledgeprivate * * Copyright (C) 2016 Endless Mobile, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Author: Juan Pablo Ugarte <ugarte@endlessm.com> * */ #include "sushi-media-bin.h" #include <gst/gst.h> #include <gst/video/gstvideosink.h> #include <gst/audio/gstaudiobasesink.h> #include <epoxy/gl.h> #ifdef DEBUG #include <unistd.h> #include <sys/types.h> #include <sys/syscall.h> #define WARN_IF_NOT_MAIN_THREAD if (getpid () != syscall (SYS_gettid)) g_warning ("%s %d not in main thread", __func__, __LINE__); #endif #define AUTOHIDE_TIMEOUT_DEFAULT 2 /* Controls autohide timeout in seconds */ #define INFO_N_COLUMNS 6 /* Number of info columns labels */ #define FPS_WINDOW_SIZE 2 /* Window size in seconds to calculate fps */ #define SMB_ICON_SIZE GTK_ICON_SIZE_BUTTON #define SMB_ICON_NAME_PLAY "media-playback-start-symbolic" #define SMB_ICON_NAME_PAUSE "media-playback-pause-symbolic" #define SMB_ICON_NAME_FULLSCREEN "view-fullscreen-symbolic" #define SMB_ICON_NAME_RESTORE "view-restore-symbolic" #define SMB_INITIAL_STATE GST_STATE_PAUSED GST_DEBUG_CATEGORY_STATIC (sushi_media_bin_debug); #define GST_CAT_DEFAULT sushi_media_bin_debug struct _SushiMediaBin { GtkBox parent; }; typedef struct { /* Properties */ gchar *uri; gint autohide_timeout; gchar *title; gchar *description; /* Boolean properties */ gboolean fullscreen:1; gboolean show_stream_info:1; gboolean audio_mode:1; /* We place extra flags here so the get squashed with the boolean properties */ gboolean title_user_set:1; /* True if the user set title property */ gboolean description_user_set:1; /* True if the user set description property */ gboolean dump_dot_file:1; /* True if GST_DEBUG_DUMP_DOT_DIR is set */ gboolean ignore_adjustment_changes:1; /* Internal Widgets */ GtkStack *stack; GtkImage *playback_image; GtkImage *fullscreen_image; GtkAdjustment *playback_adjustment; GtkAdjustment *volume_adjustment; /* Internal Video Widgets */ GtkWidget *overlay; GtkWidget *play_box; GtkScaleButton *volume_button; GtkWidget *info_box; GtkLabel *title_label; GtkLabel *info_column_label[INFO_N_COLUMNS]; GtkLabel *duration_label; GtkLabel *progress_duration_label; GtkLabel *progress_position_label; /* Thanks to GSK all the blitting will be done in GL */ GtkRevealer *top_revealer; GtkRevealer *bottom_revealer; /* Internal Audio Widgets */ GtkWidget *audio_box; GtkScaleButton *audio_volume_button; GtkLabel *audio_duration_label; GtkLabel *audio_position_label; GtkImage *audio_playback_image; /* Support Objects */ GtkWidget *video_widget; /* Created at runtime from sink */ GtkWindow *fullscreen_window; GdkCursor *blank_cursor; GtkWidget *tmp_image; /* FIXME: remove this once we can derive from GtkBin in Glade */ /* Internal variables */ guint timeout_id; /* Autohide timeout source id */ gint timeout_count; /* Autohide timeout count since last move event */ guint tick_id; /* Widget frame clock tick callback (used to update UI) */ gint64 tick_start; gint64 frames_window_start; guint frames_window; /* Frames "rendered" in the last FPS_WINDOW_SIZE seconds window */ guint frames_rendered; /* Total frames "rendered" */ GdkEventType pressed_button_type; gint video_width; gint video_height; /* Gst support */ GstElement *play; /* playbin element */ GstElement *video_sink; /* The video sink element used (glsinkbin or gtksink) */ GstElement *vis_plugin; /* The visualization plugin */ GstBus *bus; /* playbin bus */ GstBuffer *last_buffer; GstTagList *audio_tags; GstTagList *video_tags; GstTagList *text_tags; GstQuery *position_query; /* Used to query position more quicker */ GstState state; /* The desired state of the pipeline */ gint64 duration; /* Stream duration */ guint position; /* Stream position in seconds */ } SushiMediaBinPrivate; enum { PROP_0, PROP_URI, PROP_VOLUME, PROP_AUTOHIDE_TIMEOUT, PROP_FULLSCREEN, PROP_SHOW_STREAM_INFO, PROP_AUDIO_MODE, PROP_TITLE, PROP_DESCRIPTION, N_PROPERTIES }; enum { ERROR, SIZE_CHANGE, TAGS_CHANGE, LAST_SIGNAL }; static GParamSpec *properties[N_PROPERTIES]; static guint sushi_media_bin_signals[LAST_SIGNAL] = { 0 }; G_DEFINE_TYPE_WITH_PRIVATE (SushiMediaBin, sushi_media_bin, GTK_TYPE_BOX); #define SMB_PRIVATE(d) ((SushiMediaBinPrivate *) sushi_media_bin_get_instance_private(d)) static void sushi_media_bin_init_playbin (SushiMediaBin *self); static void sushi_media_bin_set_tick_enabled (SushiMediaBin *self, gboolean enabled); static GtkWindow *sushi_media_bin_window_new (SushiMediaBin *self); static const gchar *format_time (gint time); static inline gint64 sushi_media_bin_get_position (SushiMediaBin *self) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); gint64 position; if (!priv->play || !gst_element_query (priv->play, priv->position_query)) return 0; gst_query_parse_position (priv->position_query, NULL, &position); return position; } static GstStateChangeReturn sushi_media_bin_set_state (SushiMediaBin *self, GstState state) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); priv->state = state; return gst_element_set_state (priv->play, state); } /* Action handlers */ static void sushi_media_bin_toggle_playback (SushiMediaBin *self) { if (SMB_PRIVATE (self)->state == GST_STATE_PLAYING) sushi_media_bin_pause (self); else sushi_media_bin_play (self); } static void sushi_media_bin_toggle_fullscreen (SushiMediaBin *self) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); /* Do nothing in audio mode */ if (priv->audio_mode) return; sushi_media_bin_set_fullscreen (self, !priv->fullscreen); } static void sushi_media_bin_reveal_controls (SushiMediaBin *self) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); gdk_window_set_cursor (gtk_widget_get_window (priv->overlay), NULL); /* We only show the top bar if there is something in the info labels */ if (!g_str_equal (gtk_label_get_label (priv->title_label), "") || !g_str_equal (gtk_label_get_label (priv->info_column_label[0]), "") || !g_str_equal (gtk_label_get_label (priv->info_column_label[2]), "") || !g_str_equal (gtk_label_get_label (priv->info_column_label[4]), "")) gtk_revealer_set_reveal_child (priv->top_revealer, TRUE); gtk_revealer_set_reveal_child (priv->bottom_revealer, TRUE); } static gboolean revealer_timeout (gpointer data) { SushiMediaBinPrivate *priv = SMB_PRIVATE (data); GdkWindow *window; if (++priv->timeout_count < priv->autohide_timeout) return G_SOURCE_CONTINUE; window = gtk_widget_get_window (priv->overlay); if (window != NULL) gdk_window_set_cursor (window, priv->blank_cursor); gtk_revealer_set_reveal_child (priv->top_revealer, FALSE); gtk_revealer_set_reveal_child (priv->bottom_revealer, FALSE); priv->timeout_id = 0; return G_SOURCE_REMOVE; } static inline void ensure_no_timeout(SushiMediaBinPrivate *priv) { if (!priv->timeout_id) return; g_source_remove (priv->timeout_id); priv->timeout_id = 0; } static void sushi_media_bin_revealer_timeout (SushiMediaBin *self, gboolean activate) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); if (activate) { /* Reset counter */ priv->timeout_count = 0; if (!priv->timeout_id) priv->timeout_id = g_timeout_add_seconds (1, revealer_timeout, self); } else { GdkWindow *window = gtk_widget_get_window (priv->overlay); ensure_no_timeout (priv); if (window) gdk_window_set_cursor (window, NULL); } } static void sushi_media_bin_action_toggle (SushiMediaBin *self, const gchar *action) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); g_return_if_fail (action != NULL); if (g_str_equal (action, "playback")) sushi_media_bin_toggle_playback (self); else if (g_str_equal (action, "fullscreen")) sushi_media_bin_toggle_fullscreen (self); else if (g_str_equal (action, "show-stream-info")) { sushi_media_bin_set_show_stream_info (self, !priv->show_stream_info); sushi_media_bin_reveal_controls (self); } else g_warning ("Ignoring unknown toggle action %s", action); } static void sushi_media_bin_action_seek (SushiMediaBin *self, gint seconds) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); gint64 position = sushi_media_bin_get_position (self) + (seconds * GST_SECOND); gst_element_seek_simple (priv->play, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, seconds ? CLAMP (position, 0, priv->duration) : 0); } /* Signals handlers */ static gboolean on_overlay_button_press_event (GtkWidget *widget, GdkEvent *event, SushiMediaBin *self) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); if (event->button.button != GDK_BUTTON_PRIMARY) return FALSE; priv->pressed_button_type = event->type; return TRUE; } static gboolean on_overlay_button_release_event (GtkWidget *widget, GdkEvent *event, SushiMediaBin *self) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); if (event->button.button != GDK_BUTTON_PRIMARY) return FALSE; if (priv->pressed_button_type == GDK_BUTTON_PRESS) { sushi_media_bin_toggle_playback (self); } else if (priv->pressed_button_type == GDK_2BUTTON_PRESS) { sushi_media_bin_toggle_fullscreen (self); sushi_media_bin_toggle_playback (self); } /* Reset state, since some widgets like GtkButton do not consume * the last button press release event */ priv->pressed_button_type = GDK_NOTHING; return TRUE; } static gboolean on_revealer_leave_notify_event (GtkWidget *widget, GdkEvent *event, SushiMediaBin *self) { sushi_media_bin_revealer_timeout (self, TRUE); return FALSE; } static gboolean on_revealer_motion_notify_event (GtkWidget *widget, GdkEvent *event, SushiMediaBin *self) { /* Do not hide controls and restore pointer */ sushi_media_bin_revealer_timeout (self, FALSE); return TRUE; } static gboolean on_overlay_motion_notify_event (GtkWidget *widget, GdkEvent *event, SushiMediaBin *self) { sushi_media_bin_reveal_controls (self); sushi_media_bin_revealer_timeout (self, TRUE); return FALSE; } static void on_playback_adjustment_value_changed (GtkAdjustment *adjustment, SushiMediaBin *self) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); if (priv->ignore_adjustment_changes) return; priv->position = gtk_adjustment_get_value (adjustment); gst_element_seek_simple (priv->play, GST_FORMAT_TIME, GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_FLUSH, priv->position * GST_SECOND); } static gchar * on_progress_scale_format_value (GtkScale *scale, gdouble value, SushiMediaBin *self) { /* FIXME: CSS padding does not work as expected, add some padding here */ return g_strdup_printf (" %s ", format_time (value)); } static void on_volume_popup_show (GtkWidget *popup, SushiMediaBin *self) { /* Do not hide controls */ sushi_media_bin_revealer_timeout (self, FALSE); } static void on_volume_popup_hide (GtkWidget *popup, SushiMediaBin *self) { sushi_media_bin_revealer_timeout (self, TRUE); } static inline void sushi_media_bin_update_state (SushiMediaBin *self) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); if (priv->uri && priv->video_sink) { g_object_set (priv->play, "uri", priv->uri, NULL); gst_element_set_state (priv->play, priv->state); } } static GdkPixbuf * sushi_media_bin_video_pixbuf_new (SushiMediaBin *self) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); gint width, height, video_width, video_height, dx, dy; cairo_surface_t *surface; gdouble scale = 1.0; GdkPixbuf *pixbuf; cairo_t *cr; width = gtk_widget_get_allocated_width (GTK_WIDGET (self)); height = gtk_widget_get_allocated_height (GTK_WIDGET (self)); video_width = gtk_widget_get_allocated_width (priv->video_widget); video_height = gtk_widget_get_allocated_height (priv->video_widget); if ((width != video_width || height != video_height) && priv->video_width && priv->video_height) { scale = MIN (width/(gdouble)priv->video_width, height/(gdouble)priv->video_height); dx = ABS (video_width - priv->video_width) * scale; dy = ABS (video_height - priv->video_height) * scale; width = video_width * scale; height = video_height * scale; } else dx = dy = 0; surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height); cr = cairo_create (surface); if (scale != 1.0) cairo_scale (cr, scale, scale); gtk_widget_draw (priv->video_widget, cr); pixbuf = gdk_pixbuf_get_from_surface (surface, dx/2, dy/2, width-dx, height-dy); cairo_destroy (cr); cairo_surface_destroy (surface); return pixbuf; } static inline gboolean sushi_media_bin_gl_check (GtkWidget *widget) { static gsize gl_works = 0; if (g_once_init_enter (&gl_works)) { GError *error = NULL; gsize works = 1; GdkGLContext *context; GdkWindow *window; if ((window = gtk_widget_get_window (widget)) && (context = gdk_window_create_gl_context (window, &error))) { const gchar *vendor, *renderer; gdk_gl_context_make_current (context); vendor = (const gchar *) glGetString (GL_VENDOR); renderer = (const gchar *) glGetString (GL_RENDERER); GST_INFO ("GL Vendor: %s, renderer: %s", vendor, renderer); if (g_str_equal (vendor, "nouveau")) GST_WARNING ("nouveau is blacklisted, since sharing gl contexts in " "multiple threads is not supported " "and will eventually make it crash."); else if (g_strstr_len (renderer, -1, "Gallium") && g_strstr_len (renderer, -1, "llvmpipe")) GST_INFO ("Detected software GL rasterizer, falling back to gtksink"); else works = 2; gdk_gl_context_clear_current (); } if (error) { GST_WARNING ("Could not window to create GL context, %s", error->message); g_error_free (error); } g_once_init_leave (&gl_works, works); } return (gl_works > 1); } static inline void sushi_media_bin_init_video_sink (SushiMediaBin *self) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); GtkWidget *video_widget = NULL; GstElement *video_sink = NULL; if (priv->video_sink) return; if (priv->audio_mode) { video_sink = gst_element_factory_make ("fakesink", "SushiMediaBinNullSink"); g_object_set (video_sink, "sync", TRUE, NULL); g_object_set (priv->play, "video-sink", video_sink, NULL); priv->video_sink = gst_object_ref_sink (video_sink); return; } if (sushi_media_bin_gl_check (GTK_WIDGET (self))) { video_sink = gst_element_factory_make ("glsinkbin", "SushiMediaBinGLVideoSink"); if (video_sink) { GstElement *gtkglsink = gst_element_factory_make ("gtkglsink", NULL); if (gtkglsink) { GST_INFO ("Using gtkglsink"); g_object_set (video_sink, "sink", gtkglsink, NULL); g_object_get (gtkglsink, "widget", &video_widget, NULL); } else { GST_WARNING ("Could not create gtkglsink"); gst_object_replace ((GstObject**)&video_sink, NULL); } } else { GST_WARNING ("Could not create glsinkbin"); } } /* Fallback to gtksink */ if (!video_sink) { GST_INFO ("Falling back to gtksink"); video_sink = gst_element_factory_make ("gtksink", NULL); g_object_get (video_sink, "widget", &video_widget, NULL); } /* We use a null sink as a last resort */ if (video_sink && video_widget) { g_object_set (video_widget, "expand", TRUE, NULL); /* And pack it where we want the video to show up */ gtk_container_add (GTK_CONTAINER (priv->overlay), video_widget); gtk_widget_show (video_widget); /* g_object_get() returns a new reference */ priv->video_widget = video_widget; } else { GtkWidget *img = gtk_image_new_from_icon_name ("image-missing", GTK_ICON_SIZE_DIALOG); GST_WARNING ("Could not get video widget from gtkglsink/gtksink, falling back to fakesink"); g_object_unref (video_widget); gst_object_unref (video_sink); video_sink = gst_element_factory_make ("fakesink", "SushiMediaBinFakeSink"); g_object_set (video_sink, "sync", TRUE, NULL); gtk_container_add (GTK_CONTAINER (priv->overlay), img); gtk_widget_show (img); /* FIXME: the overlay does not get motion and press events with this code path */ } /* Setup playbin video sink */ if (video_sink) { g_object_set (priv->play, "video-sink", video_sink, NULL); priv->video_sink = gst_object_ref_sink (video_sink); } } static inline void sushi_media_bin_deinit_video_sink (SushiMediaBin *self) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); /* Stop Playback to give gst a chance to cleanup its mess */ if (priv->play) gst_element_set_state (priv->play, GST_STATE_NULL); /* Stop bus watch */ if (priv->bus) { gst_bus_set_flushing (priv->bus, TRUE); gst_bus_remove_watch (priv->bus); gst_object_replace ((GstObject**)&priv->bus, NULL); } /* Unref video sink */ gst_object_replace ((GstObject**)&priv->video_sink, NULL); /* Destroy video widget */ g_clear_pointer (&priv->video_widget, gtk_widget_destroy); /* Unref playbin */ gst_object_replace ((GstObject**)&priv->play, NULL); } static void sushi_media_bin_fullscreen_apply (SushiMediaBin *self, gboolean fullscreen) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); gint64 position = -1; if ((fullscreen && priv->fullscreen_window) || (!fullscreen && !priv->fullscreen_window)) return; /* * To avoid flickering, this will make the widget pack an image with the last * frame in the container before reparenting the video widget in the * fullscreen window */ if (!priv->tmp_image) { GdkPixbuf *pixbuf = sushi_media_bin_video_pixbuf_new (self); priv->tmp_image = gtk_image_new_from_pixbuf (pixbuf); g_object_set (priv->tmp_image, "expand", TRUE, NULL); g_object_unref (pixbuf); } /* * FIXME: GtkGstGLWidget does not support reparenting to a different toplevel * because the gl context is different and the pipeline does not know it * changes, so as a temporary workaround we simply reconstruct the whole * pipeline. * * See bug https://bugzilla.gnome.org/show_bug.cgi?id=775045 */ if ((priv->state == GST_STATE_PAUSED || priv->state == GST_STATE_PLAYING) && g_strcmp0 (G_OBJECT_TYPE_NAME (priv->video_sink), "GstGLSinkBin") == 0) { /* NOTE: here we could set tmp_image to the content of the current sample * but it wont be updated until the main window is show at which point * we will see the old frame anyways. */ position = sushi_media_bin_get_position (self); gtk_container_remove (GTK_CONTAINER (priv->overlay), priv->video_widget); sushi_media_bin_deinit_video_sink (self); } g_object_ref (priv->overlay); if (fullscreen) { priv->fullscreen_window = g_object_ref (sushi_media_bin_window_new (self)); /* Reparent video widget in a fullscreen window */ gtk_container_remove (GTK_CONTAINER (priv->stack), priv->overlay); /* Pack an image with the last frame inside the bin */ gtk_container_add (GTK_CONTAINER (priv->stack), priv->tmp_image); gtk_widget_show (priv->tmp_image); gtk_stack_set_visible_child (GTK_STACK (priv->stack), priv->tmp_image); /* Pack video in the fullscreen window */ gtk_container_add (GTK_CONTAINER (priv->fullscreen_window), priv->overlay); gtk_window_fullscreen (priv->fullscreen_window); gtk_window_present (priv->fullscreen_window); /* Hide cursor if controls are hidden */ if (!gtk_revealer_get_reveal_child (priv->bottom_revealer)) gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (priv->fullscreen_window)), priv->blank_cursor); gtk_image_set_from_icon_name (priv->fullscreen_image, SMB_ICON_NAME_RESTORE, SMB_ICON_SIZE); } else { gtk_container_remove (GTK_CONTAINER (priv->stack), priv->tmp_image); priv->tmp_image = NULL; /* Reparent video widget back into ourselves */ gtk_container_remove (GTK_CONTAINER (priv->fullscreen_window), priv->overlay); gtk_container_add (GTK_CONTAINER (priv->stack), priv->overlay); gtk_stack_set_visible_child (GTK_STACK (priv->stack), priv->overlay); gtk_widget_destroy (GTK_WIDGET (priv->fullscreen_window)); g_clear_object (&priv->fullscreen_window); gtk_image_set_from_icon_name (priv->fullscreen_image, SMB_ICON_NAME_FULLSCREEN, SMB_ICON_SIZE); gtk_widget_grab_focus (GTK_WIDGET (self)); } /* * FIXME: See bug https://bugzilla.gnome.org/show_bug.cgi?id=775045 */ if (priv->play == NULL) { sushi_media_bin_init_playbin (self); sushi_media_bin_init_video_sink (self); g_object_set (priv->play, "uri", priv->uri, NULL); /* Init new pipeline */ gst_element_set_state (priv->play, GST_STATE_PAUSED); gst_element_get_state (priv->play, NULL, NULL, GST_CLOCK_TIME_NONE); /* Seek to position */ gst_element_seek_simple (priv->play, GST_FORMAT_TIME, GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_FLUSH, position); gst_message_unref (gst_bus_pop_filtered (priv->bus, GST_MESSAGE_ASYNC_DONE)); /* Resume playback */ if (priv->state == GST_STATE_PLAYING) { gst_element_set_state (priv->play, GST_STATE_PLAYING); gst_element_get_state (priv->play, NULL, NULL, GST_CLOCK_TIME_NONE); } } g_object_unref (priv->overlay); } static void on_sushi_media_bin_realize (GtkWidget *widget, SushiMediaBin *self) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); /* Create a blank_cursor */ priv->blank_cursor = gdk_cursor_new_from_name (gtk_widget_get_display (widget), "none"); /* Create video sink */ sushi_media_bin_init_video_sink (self); if (priv->fullscreen) sushi_media_bin_fullscreen_apply (self, TRUE); /* Make playbin show the first video frame if there is an URI */ sushi_media_bin_update_state (self); /* Disconnect after initialization */ g_signal_handlers_disconnect_by_func (widget, on_sushi_media_bin_realize, self); } static void on_sushi_media_bin_unrealize (GtkWidget *widget, SushiMediaBin *self) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); /* Remove controls timeout */ ensure_no_timeout (priv); /* Disconnect after completion */ g_signal_handlers_disconnect_by_func (widget, on_sushi_media_bin_unrealize, self); } static gboolean sushi_media_bin_error (SushiMediaBin *self, GError *error) { /* TODO: properly present errors to the user */ g_warning ("%s", error->message); return TRUE; } static void sushi_media_bin_init_volume_button (SushiMediaBin *self, GtkScaleButton *button, gboolean stop_timeout) { GtkWidget *popup = gtk_scale_button_get_popup (button); if (stop_timeout) { g_signal_connect (popup, "show", G_CALLBACK (on_volume_popup_show), self); g_signal_connect (popup, "hide", G_CALLBACK (on_volume_popup_hide), self); } gtk_style_context_add_class (gtk_widget_get_style_context (popup), "sushi-media-bin"); } static void sushi_media_bin_init_style (SushiMediaBin *self) { static gsize style_initialized = 0; if (g_once_init_enter (&style_initialized)) { GtkCssProvider *css_provider = gtk_css_provider_new (); gtk_css_provider_load_from_resource (css_provider, "/org/gnome/Sushi/libsushi/sushi-media-bin.css"); gtk_style_context_add_provider_for_screen (gdk_screen_get_default (), GTK_STYLE_PROVIDER (css_provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION-10); g_object_unref (css_provider); g_once_init_leave (&style_initialized, 1); } } static void sushi_media_bin_init (SushiMediaBin *self) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); gint i; gtk_widget_init_template (GTK_WIDGET (self)); sushi_media_bin_init_style (self); priv->state = SMB_INITIAL_STATE; priv->autohide_timeout = AUTOHIDE_TIMEOUT_DEFAULT; priv->pressed_button_type = GDK_NOTHING; priv->dump_dot_file = (g_getenv ("GST_DEBUG_DUMP_DOT_DIR") != NULL); sushi_media_bin_init_playbin (self); /* Create info box column labels */ for (i = 0; i < INFO_N_COLUMNS; i++) { GtkWidget *label = gtk_label_new (""); priv->info_column_label[i] = GTK_LABEL (label); gtk_container_add (GTK_CONTAINER (priv->info_box), label); gtk_widget_set_valign (label, GTK_ALIGN_START); gtk_widget_show (label); } /* Cache position query */ priv->position_query = gst_query_new_position (GST_FORMAT_TIME); /* Make both buttons look the same */ g_object_bind_property (priv->playback_image, "icon-name", priv->audio_playback_image, "icon-name", G_BINDING_SYNC_CREATE); sushi_media_bin_init_volume_button (self, priv->volume_button, TRUE); sushi_media_bin_init_volume_button (self, priv->audio_volume_button, FALSE); } static void sushi_media_bin_dispose (GObject *object) { SushiMediaBin *self = SUSHI_MEDIA_BIN (object); SushiMediaBinPrivate *priv = SMB_PRIVATE (self); /* Remove controls timeout */ ensure_no_timeout (priv); /* Finalize gstreamer related objects */ sushi_media_bin_deinit_video_sink (self); /* Destroy fullscreen window */ if (priv->fullscreen_window) { gtk_widget_destroy (GTK_WIDGET (priv->fullscreen_window)); g_clear_object (&priv->fullscreen_window); } /* Unref cursor */ g_clear_object (&priv->blank_cursor); G_OBJECT_CLASS (sushi_media_bin_parent_class)->dispose (object); } static void sushi_media_bin_finalize (GObject *object) { SushiMediaBin *self = SUSHI_MEDIA_BIN (object); SushiMediaBinPrivate *priv = SMB_PRIVATE (self); ensure_no_timeout(priv); /* Clear position query */ g_clear_pointer (&priv->position_query, gst_query_unref); /* Remove frame clock tick callback */ sushi_media_bin_set_tick_enabled (self, FALSE); /* Clear tag lists */ g_clear_pointer (&priv->audio_tags, gst_tag_list_unref); g_clear_pointer (&priv->video_tags, gst_tag_list_unref); g_clear_pointer (&priv->text_tags, gst_tag_list_unref); /* Free properties */ g_clear_pointer (&priv->uri, g_free); g_clear_pointer (&priv->title, g_free); g_clear_pointer (&priv->description, g_free); G_OBJECT_CLASS (sushi_media_bin_parent_class)->finalize (object); } static inline void sushi_media_bin_set_audio_mode (SushiMediaBin *self, gboolean audio_mode) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); priv->audio_mode = audio_mode; if (audio_mode) gtk_stack_set_visible_child (GTK_STACK (priv->stack), priv->audio_box); } static void sushi_media_bin_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { g_return_if_fail (SUSHI_IS_MEDIA_BIN (object)); switch (prop_id) { case PROP_URI: sushi_media_bin_set_uri (SUSHI_MEDIA_BIN (object), g_value_get_string (value)); break; case PROP_VOLUME: sushi_media_bin_set_volume (SUSHI_MEDIA_BIN (object), g_value_get_double (value)); break; case PROP_AUTOHIDE_TIMEOUT: sushi_media_bin_set_autohide_timeout (SUSHI_MEDIA_BIN (object), g_value_get_int (value)); break; case PROP_FULLSCREEN: sushi_media_bin_set_fullscreen (SUSHI_MEDIA_BIN (object), g_value_get_boolean (value)); break; case PROP_SHOW_STREAM_INFO: sushi_media_bin_set_show_stream_info (SUSHI_MEDIA_BIN (object), g_value_get_boolean (value)); break; case PROP_AUDIO_MODE: sushi_media_bin_set_audio_mode (SUSHI_MEDIA_BIN (object), g_value_get_boolean (value)); break; case PROP_TITLE: sushi_media_bin_set_title (SUSHI_MEDIA_BIN (object), g_value_get_string (value)); break; case PROP_DESCRIPTION: sushi_media_bin_set_description (SUSHI_MEDIA_BIN (object), g_value_get_string (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void sushi_media_bin_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { SushiMediaBinPrivate *priv; g_return_if_fail (SUSHI_IS_MEDIA_BIN (object)); priv = SMB_PRIVATE (SUSHI_MEDIA_BIN (object)); switch (prop_id) { case PROP_URI: g_value_set_string (value, priv->uri); break; case PROP_VOLUME: g_value_set_double (value, gtk_adjustment_get_value (priv->volume_adjustment)); break; case PROP_AUTOHIDE_TIMEOUT: g_value_set_int (value, priv->autohide_timeout); break; case PROP_FULLSCREEN: g_value_set_boolean (value, priv->fullscreen); break; case PROP_SHOW_STREAM_INFO: g_value_set_boolean (value, priv->show_stream_info); break; case PROP_AUDIO_MODE: g_value_set_boolean (value, priv->audio_mode); break; case PROP_TITLE: g_value_set_string (value, priv->title); break; case PROP_DESCRIPTION: g_value_set_string (value, priv->description); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static GtkSizeRequestMode sushi_media_bin_get_request_mode (GtkWidget *self) { return GTK_SIZE_REQUEST_CONSTANT_SIZE; } static void sushi_media_bin_get_preferred_width (GtkWidget *self, gint *minimum_width, gint *natural_width) { SushiMediaBinPrivate *priv = SMB_PRIVATE (SUSHI_MEDIA_BIN (self)); if (priv->audio_mode) { GTK_WIDGET_CLASS (sushi_media_bin_parent_class)->get_preferred_width (self, minimum_width, natural_width); } else { *minimum_width = priv->video_width ? 320 : 0; *natural_width = priv->video_width ? priv->video_width : 0; } } static void sushi_media_bin_get_preferred_height (GtkWidget *self, gint *minimum_height, gint *natural_height) { SushiMediaBinPrivate *priv = SMB_PRIVATE (SUSHI_MEDIA_BIN (self)); if (priv->audio_mode) { GTK_WIDGET_CLASS (sushi_media_bin_parent_class)->get_preferred_height (self, minimum_height, natural_height); } else { *minimum_height = priv->video_height ? 240 : 0; *natural_height = priv->video_height ? priv->video_height : 0; } } #define SMB_DEFINE_ACTION_SIGNAL(klass, name, handler,...) \ g_signal_new_class_handler (name, \ G_TYPE_FROM_CLASS (klass), \ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, \ G_CALLBACK (handler), \ NULL, NULL, NULL, \ G_TYPE_NONE, __VA_ARGS__) static void sushi_media_bin_class_init (SushiMediaBinClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); object_class->dispose = sushi_media_bin_dispose; object_class->finalize = sushi_media_bin_finalize; object_class->set_property = sushi_media_bin_set_property; object_class->get_property = sushi_media_bin_get_property; widget_class->get_request_mode = sushi_media_bin_get_request_mode; widget_class->get_preferred_width = sushi_media_bin_get_preferred_width; widget_class->get_preferred_height = sushi_media_bin_get_preferred_height; /* Properties */ properties[PROP_URI] = g_param_spec_string ("uri", "URI", "The Media URI to playback", NULL, G_PARAM_READWRITE); properties[PROP_VOLUME] = g_param_spec_double ("volume", "Volume", "Stream volume", 0.0, 1.0, 1.0, G_PARAM_READWRITE); properties[PROP_AUTOHIDE_TIMEOUT] = g_param_spec_int ("autohide-timeout", "Auto hide timeout", "Controls auto hide timeout in seconds", 0, G_MAXINT, AUTOHIDE_TIMEOUT_DEFAULT, G_PARAM_READWRITE); properties[PROP_FULLSCREEN] = g_param_spec_boolean ("fullscreen", "Fullscreen", "Whether to show the video in fullscreen or not", FALSE, G_PARAM_READWRITE); properties[PROP_SHOW_STREAM_INFO] = g_param_spec_boolean ("show-stream-info", "Show stream info", "Whether to show stream information or not", FALSE, G_PARAM_READWRITE); properties[PROP_AUDIO_MODE] = g_param_spec_boolean ("audio-mode", "Audio Mode", "Wheter to show controls suitable for audio files only", FALSE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); properties[PROP_TITLE] = g_param_spec_string ("title", "Title", "The title to display", NULL, G_PARAM_READWRITE); properties[PROP_DESCRIPTION] = g_param_spec_string ("description", "Description", "Audio/Video description", NULL, G_PARAM_READWRITE); g_object_class_install_properties (object_class, N_PROPERTIES, properties); /** * SushiMediaBin::error: * @self: the #SushiMediaBin which received the signal. * @error: the #GError */ sushi_media_bin_signals[ERROR] = g_signal_new_class_handler ("error", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, G_CALLBACK (sushi_media_bin_error), g_signal_accumulator_true_handled, NULL, NULL, G_TYPE_BOOLEAN, 1, G_TYPE_ERROR); /** * SushiMediaBin::size-change: * @self: the #SushiMediaBin which received the signal. */ sushi_media_bin_signals[SIZE_CHANGE] = g_signal_new ("size-change", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); /** * SushiMediaBin::tags-change: * @self: the #SushiMediaBin which received the signal. */ sushi_media_bin_signals[TAGS_CHANGE] = g_signal_new ("tags-change", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); /* Action signals for key bindings */ SMB_DEFINE_ACTION_SIGNAL (object_class, "toggle", sushi_media_bin_action_toggle, 1, G_TYPE_STRING); SMB_DEFINE_ACTION_SIGNAL (object_class, "seek", sushi_media_bin_action_seek, 1, G_TYPE_INT); /* Template */ gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/Sushi/libsushi/SushiMediaBin.ui"); gtk_widget_class_bind_template_child_private (widget_class, SushiMediaBin, stack); gtk_widget_class_bind_template_child_private (widget_class, SushiMediaBin, playback_adjustment); gtk_widget_class_bind_template_child_private (widget_class, SushiMediaBin, volume_adjustment); gtk_widget_class_bind_template_child_private (widget_class, SushiMediaBin, playback_image); gtk_widget_class_bind_template_child_private (widget_class, SushiMediaBin, fullscreen_image); gtk_widget_class_bind_template_child_private (widget_class, SushiMediaBin, overlay); gtk_widget_class_bind_template_child_private (widget_class, SushiMediaBin, play_box); gtk_widget_class_bind_template_child_private (widget_class, SushiMediaBin, volume_button); gtk_widget_class_bind_template_child_private (widget_class, SushiMediaBin, title_label); gtk_widget_class_bind_template_child_private (widget_class, SushiMediaBin, info_box); gtk_widget_class_bind_template_child_private (widget_class, SushiMediaBin, duration_label); gtk_widget_class_bind_template_child_private (widget_class, SushiMediaBin, progress_duration_label); gtk_widget_class_bind_template_child_private (widget_class, SushiMediaBin, progress_position_label); gtk_widget_class_bind_template_child_private (widget_class, SushiMediaBin, top_revealer); gtk_widget_class_bind_template_child_private (widget_class, SushiMediaBin, bottom_revealer); gtk_widget_class_bind_template_child_private (widget_class, SushiMediaBin, audio_box); gtk_widget_class_bind_template_child_private (widget_class, SushiMediaBin, audio_duration_label); gtk_widget_class_bind_template_child_private (widget_class, SushiMediaBin, audio_volume_button); gtk_widget_class_bind_template_child_private (widget_class, SushiMediaBin, audio_position_label); gtk_widget_class_bind_template_child_private (widget_class, SushiMediaBin, audio_playback_image); gtk_widget_class_bind_template_callback (widget_class, on_sushi_media_bin_realize); gtk_widget_class_bind_template_callback (widget_class, on_sushi_media_bin_unrealize); gtk_widget_class_bind_template_callback (widget_class, on_overlay_motion_notify_event); gtk_widget_class_bind_template_callback (widget_class, on_overlay_button_press_event); gtk_widget_class_bind_template_callback (widget_class, on_overlay_button_release_event); gtk_widget_class_bind_template_callback (widget_class, on_revealer_motion_notify_event); gtk_widget_class_bind_template_callback (widget_class, on_revealer_leave_notify_event); gtk_widget_class_bind_template_callback (widget_class, on_progress_scale_format_value); gtk_widget_class_bind_template_callback (widget_class, on_playback_adjustment_value_changed); gtk_widget_class_bind_template_callback (widget_class, sushi_media_bin_toggle_playback); gtk_widget_class_bind_template_callback (widget_class, sushi_media_bin_toggle_fullscreen); /* Setup CSS */ gtk_widget_class_set_css_name (widget_class, "sushi-media-bin"); /* Init GStreamer */ gst_init_check (NULL, NULL, NULL); GST_DEBUG_CATEGORY_INIT (sushi_media_bin_debug, "SushiMediaBin", 0, "SushiMediaBin audio/video widget"); } /*************************** Fullscreen Window Type ***************************/ G_DECLARE_FINAL_TYPE (SushiMediaBinWindow, sushi_media_bin_window, SUSHI, MEDIA_BIN_WINDOW, GtkWindow) struct _SushiMediaBinWindow { GtkWindow parent; }; G_DEFINE_TYPE (SushiMediaBinWindow, sushi_media_bin_window, GTK_TYPE_WINDOW); static void sushi_media_bin_window_init (SushiMediaBinWindow *self) { gtk_window_set_decorated (GTK_WINDOW (self), FALSE); } static void sushi_media_bin_window_class_init (SushiMediaBinWindowClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (klass), "sushi-media-bin"); SMB_DEFINE_ACTION_SIGNAL (object_class, "toggle", NULL, 1, G_TYPE_STRING); SMB_DEFINE_ACTION_SIGNAL (object_class, "seek", NULL, 1, G_TYPE_INT); } static GtkWindow * sushi_media_bin_window_new (SushiMediaBin *bin) { GObject *window = g_object_new (sushi_media_bin_window_get_type (), NULL); g_signal_connect_swapped (window, "delete-event", G_CALLBACK (sushi_media_bin_toggle_fullscreen), bin); g_signal_connect_swapped (window, "toggle", G_CALLBACK (sushi_media_bin_action_toggle), bin); g_signal_connect_swapped (window, "seek", G_CALLBACK (sushi_media_bin_action_seek), bin); return (GtkWindow *) window; } /*********************************** Utils ************************************/ #define TIME_HOURS(t) (t / 3600) #define TIME_MINUTES(t) ((t % 3600) / 60) #define TIME_SECONDS(t) (t % 60) static const gchar * format_time (gint time) { static gchar buffer[16]; gint hours = TIME_HOURS (time); if (hours) g_snprintf (buffer, sizeof (buffer), "%d:%02d:%02d", hours, TIME_MINUTES (time), TIME_SECONDS (time)); else g_snprintf (buffer, sizeof (buffer), "%d:%02d", TIME_MINUTES (time), TIME_SECONDS (time)); return (const gchar *) buffer; } static void on_widget_style_updated (GtkWidget *widget, gpointer data) { gboolean visible = GPOINTER_TO_INT (data); gdouble opacity; gtk_style_context_get (gtk_widget_get_style_context (widget), gtk_widget_get_state_flags (widget), "opacity", &opacity, NULL); if ((visible && opacity >= 1.0) || (!visible && opacity == 0.0)) { gtk_widget_set_visible (widget, visible); g_signal_handlers_disconnect_by_func (widget, on_widget_style_updated, data); } } static void widget_set_visible (GtkWidget *widget, gboolean visible) { GtkStyleContext *context = gtk_widget_get_style_context (widget); g_signal_handlers_disconnect_by_func (widget, on_widget_style_updated, GINT_TO_POINTER (TRUE)); g_signal_handlers_disconnect_by_func (widget, on_widget_style_updated, GINT_TO_POINTER (FALSE)); gtk_style_context_remove_class (context, visible ? "hide" : "show"); gtk_style_context_add_class (context, visible ? "show" : "hide"); if (visible) gtk_widget_show (widget); g_signal_connect (widget, "style-updated", G_CALLBACK (on_widget_style_updated), GINT_TO_POINTER (visible)); } /* The following macros are used to define generic getters and setters */ #define SMB_DEFINE_GETTER_FULL(type, prop, retval, retstmt) \ type \ sushi_media_bin_get_##prop (SushiMediaBin *self) \ { \ g_return_val_if_fail (SUSHI_IS_MEDIA_BIN (self), retval); \ retstmt \ } #define SMB_DEFINE_GETTER(type, prop, retval) \ SMB_DEFINE_GETTER_FULL (type, prop, retval, return SMB_PRIVATE (self)->prop;) #define SMB_DEFINE_SETTER_FULL(type, prop, PROP, setup, cmp, assign, code) \ void \ sushi_media_bin_set_##prop (SushiMediaBin *self, type prop) \ { \ SushiMediaBinPrivate *priv; \ g_return_if_fail (SUSHI_IS_MEDIA_BIN (self)); \ priv = SMB_PRIVATE (self); \ setup; \ if (cmp) \ { \ assign; \ code; \ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_##PROP]); \ } \ } /* The last argument is for custom code that will be added just before calling * g_object_notify_by_pspec() */ #define SMB_DEFINE_SETTER(type, prop, PROP, code) \ SMB_DEFINE_SETTER_FULL(type, prop, PROP, \ , \ priv->prop != prop, \ priv->prop = prop, \ code) #define SMB_DEFINE_SETTER_BOOLEAN(prop, PROP, code) \ SMB_DEFINE_SETTER_FULL(gboolean, prop, PROP, \ prop = (prop) ? TRUE : FALSE, \ priv->prop != prop, \ priv->prop = prop, \ code) #define SMB_DEFINE_SETTER_STRING(prop, PROP, code) \ SMB_DEFINE_SETTER_FULL(const gchar *, prop, PROP, \ , \ g_strcmp0 (priv->prop, prop), \ g_free (priv->prop); priv->prop = g_strdup (prop), \ code) /******************************** GST Support *********************************/ static inline gboolean sushi_media_bin_handle_msg_error (SushiMediaBin *self, GstMessage *msg) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); GError *error = NULL; gboolean handled; gst_message_parse_error (msg, &error, NULL); if (priv->play) gst_element_set_state (priv->play, GST_STATE_NULL); g_signal_emit (self, sushi_media_bin_signals[ERROR], 0, error, &handled); g_error_free (error); return handled; } static inline void sushi_media_bin_update_duration (SushiMediaBin *self) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); gint64 duration; if (!gst_element_query_duration (priv->play, GST_FORMAT_TIME, &duration) || priv->duration == duration) return; priv->duration = duration; duration = GST_TIME_AS_SECONDS (duration); gtk_label_set_label (priv->audio_duration_label, format_time (duration)); gtk_label_set_label (priv->duration_label, format_time (duration)); gtk_label_set_label (priv->progress_duration_label, format_time (duration)); gtk_adjustment_set_upper (priv->playback_adjustment, duration); } static inline void sushi_media_bin_update_position (SushiMediaBin *self) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); gint position = GST_TIME_AS_SECONDS (sushi_media_bin_get_position (self)); if (priv->position == position) return; priv->position = position; priv->ignore_adjustment_changes = TRUE; gtk_adjustment_set_value (priv->playback_adjustment, position); priv->ignore_adjustment_changes = FALSE; gtk_label_set_label (priv->progress_position_label, format_time (position)); gtk_label_set_label (priv->audio_position_label, format_time (position)); } static inline void log_fps (SushiMediaBin *self, GdkFrameClock *frame_clock) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); gint64 frame_time, time; GstSample *sample; /* Get current buffer and return if its the same as last tick */ g_object_get (priv->play, "sample", &sample, NULL); if (sample) { GstBuffer *buffer = gst_sample_get_buffer (sample); gst_sample_unref (sample); if (priv->last_buffer == buffer) return; priv->last_buffer = buffer; } else return; frame_time = gdk_frame_clock_get_frame_time (frame_clock); /* Initialize state variables */ if (priv->tick_start == 0) { priv->tick_start = frame_time; priv->frames_window_start = frame_time; priv->frames_window = 0; priv->frames_rendered = 0; } else if (priv->frames_window == 0) priv->frames_window_start = frame_time; priv->frames_window++; /* We only print FPS once every FPS_WINDOW_SIZE seconds */ time = frame_time - priv->frames_window_start; if (time < FPS_WINDOW_SIZE * 1000000) return; priv->frames_rendered += priv->frames_window; GST_INFO ("FPS: %lf average: %lf", priv->frames_window / (time / 1000000.0), priv->frames_rendered / ((frame_time - priv->tick_start) / 1000000.0)); priv->frames_window = 0; } static gboolean sushi_media_bin_tick_callback (GtkWidget *widget, GdkFrameClock *frame_clock, gpointer user_data) { static GstDebugLevel level; sushi_media_bin_update_position ((SushiMediaBin *)user_data); if (level == 0) level = gst_debug_category_get_threshold (sushi_media_bin_debug); if (level >= GST_LEVEL_INFO) log_fps ((SushiMediaBin *)user_data, frame_clock); return G_SOURCE_CONTINUE; } static void sushi_media_bin_set_tick_enabled (SushiMediaBin *self, gboolean enabled) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); if (priv->tick_id) { gtk_widget_remove_tick_callback (GTK_WIDGET (self), priv->tick_id); priv->tick_id = priv->tick_start = 0; } if (enabled) priv->tick_id = gtk_widget_add_tick_callback (priv->overlay, sushi_media_bin_tick_callback, self, NULL); } static inline void sushi_media_bin_dump_dot (SushiMediaBin *self, GstState old, GstState new) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); gchar *filename; filename = g_strdup_printf ("%s_%s_%s", g_get_prgname (), gst_element_state_get_name (old), gst_element_state_get_name (new)); gst_debug_bin_to_dot_file_with_ts (GST_BIN (priv->play), GST_DEBUG_GRAPH_SHOW_ALL, filename); g_free (filename); } static inline void sushi_media_bin_handle_msg_state_changed (SushiMediaBin *self, GstMessage *msg) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); GstState old_state, new_state; gst_message_parse_state_changed (msg, &old_state, &new_state, NULL); if (old_state == new_state || GST_MESSAGE_SRC (msg) != GST_OBJECT (priv->play)) return; GST_DEBUG ("State changed from %s to %s", gst_element_state_get_name (old_state), gst_element_state_get_name (new_state)); if (priv->dump_dot_file) sushi_media_bin_dump_dot (self, old_state, new_state); /* Update UI */ if (old_state == GST_STATE_READY && new_state == GST_STATE_PAUSED) { gtk_image_set_from_icon_name (priv->playback_image, SMB_ICON_NAME_PLAY, SMB_ICON_SIZE); widget_set_visible (priv->play_box, FALSE); sushi_media_bin_update_duration (self); } else if (new_state == GST_STATE_PLAYING) { widget_set_visible (priv->play_box, FALSE); gtk_image_set_from_icon_name (priv->playback_image, SMB_ICON_NAME_PAUSE, SMB_ICON_SIZE); sushi_media_bin_set_tick_enabled (self, TRUE); } else { gtk_image_set_from_icon_name (priv->playback_image, SMB_ICON_NAME_PLAY, SMB_ICON_SIZE); widget_set_visible (priv->play_box, FALSE); priv->position = 0; sushi_media_bin_set_tick_enabled (self, FALSE); } } typedef struct { GString *tag; GString *val; } MetaDataStrings; static void print_tag (const GstTagList *list, const gchar *tag, gpointer data) { MetaDataStrings *metadata = data; gint i, n; for (i = 0, n = gst_tag_list_get_tag_size (list, tag); i < n; ++i) { const GValue *val = gst_tag_list_get_value_index (list, tag, i); GValue str = {0, }; g_value_init (&str, G_TYPE_STRING); g_value_transform (val, &str); g_string_append_printf (metadata->tag, "\n %s", tag); g_string_append_printf (metadata->val, "\n: %s", g_value_get_string (&str)); g_value_unset (&str); } } static inline void meta_data_strings_set_title (MetaDataStrings *metadata, const gchar *title) { g_string_assign (metadata->tag, title); g_string_assign (metadata->val, ""); } static inline void meta_data_strings_set_info (MetaDataStrings *metadata, GtkLabel *left, GtkLabel *right, GstTagList *tags) { if (tags) { gst_tag_list_foreach (tags, print_tag, metadata); gtk_label_set_label (left, metadata->tag->str); gtk_label_set_label (right, metadata->val->str); } else { gtk_label_set_label (left, ""); gtk_label_set_label (right, ""); } } static inline void sushi_media_bin_update_stream_info (SushiMediaBin *self) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); MetaDataStrings metadata = { g_string_new (""), g_string_new ("") }; meta_data_strings_set_title (&metadata, "Audio:"); meta_data_strings_set_info (&metadata, priv->info_column_label[0], priv->info_column_label[1], priv->audio_tags); meta_data_strings_set_title (&metadata, "Video:"); if (priv->video_width && priv->video_height) { g_string_append_printf (metadata.tag, "\n video-resolution"); g_string_append_printf (metadata.val, "\n: %dx%d", priv->video_width, priv->video_height); } meta_data_strings_set_info (&metadata, priv->info_column_label[2], priv->info_column_label[3], priv->video_tags); meta_data_strings_set_title (&metadata, "Text:"); meta_data_strings_set_info (&metadata, priv->info_column_label[4], priv->info_column_label[5], priv->text_tags); g_string_free (metadata.tag, TRUE); g_string_free (metadata.val, TRUE); } static inline void sushi_media_bin_handle_msg_application (SushiMediaBin *self, GstMessage *msg) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); const GstStructure *structure; const gchar *name; structure = gst_message_get_structure (msg); name = gst_structure_get_name (structure); g_return_if_fail (name != NULL); if (priv->show_stream_info) sushi_media_bin_update_stream_info (self); /* TODO: handle audio and text tags */ if (g_str_equal (name, "video-tags-changed")) { gchar *value = NULL; if (!priv->title_user_set) { if (priv->video_tags) gst_tag_list_get_string_index (priv->video_tags, GST_TAG_TITLE, 0, &value); sushi_media_bin_set_title (self, value); priv->title_user_set = FALSE; g_clear_pointer (&value, g_free); } if (!priv->description_user_set) { /* Get description from comment or description tags */ if (priv->video_tags) { /* We try comment tag first and then description */ if (!gst_tag_list_get_string_index (priv->video_tags, GST_TAG_COMMENT, 0, &value)) gst_tag_list_get_string_index (priv->video_tags, GST_TAG_DESCRIPTION, 0, &value); } sushi_media_bin_set_description (self, value); priv->description_user_set = FALSE; g_clear_pointer (&value, g_free); } } } static inline void sushi_media_bin_handle_msg_eos (SushiMediaBin *self, GstMessage *msg) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); GST_DEBUG ("Got EOS"); gst_element_set_state (priv->play, GST_STATE_NULL); sushi_media_bin_set_state (self, SMB_INITIAL_STATE); sushi_media_bin_update_position (self); } static inline void sushi_media_bin_post_message_application (SushiMediaBin *self, const gchar *name) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); GstStructure *data = gst_structure_new (name, NULL, NULL); /* Post message on the bus for the main thread to pick it up */ gst_element_post_message (priv->play, gst_message_new_application (GST_OBJECT (priv->play), data)); } static inline void sushi_media_bin_handle_msg_tag (SushiMediaBin *self, GstMessage *msg) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); GstObject *src = GST_MESSAGE_SRC (msg); GstTagList *tags = NULL, *old_tags = NULL; const gchar *type = NULL; gst_message_parse_tag (msg, &tags); if (g_type_is_a (G_OBJECT_TYPE (src), GST_TYPE_VIDEO_SINK)) { old_tags = priv->video_tags; if (!old_tags || (old_tags && !gst_tag_list_is_equal (old_tags, tags))) { type = "video-tags-changed"; priv->video_tags = gst_tag_list_merge (old_tags, tags, GST_TAG_MERGE_REPLACE); } } else if (g_type_is_a (G_OBJECT_TYPE (src), GST_TYPE_AUDIO_BASE_SINK)) { old_tags = priv->audio_tags; if (!old_tags || (old_tags && !gst_tag_list_is_equal (old_tags, tags))) { type = "audio-tags-changed"; priv->audio_tags = gst_tag_list_merge (old_tags, tags, GST_TAG_MERGE_REPLACE); } } /* Post message on the bus for the main thread to pick it up */ if (type) { sushi_media_bin_post_message_application (self, type); g_signal_emit (self, sushi_media_bin_signals[TAGS_CHANGE], 0); g_clear_pointer (&old_tags, gst_tag_list_unref); } gst_tag_list_unref (tags); } static inline void sushi_media_bin_handle_streams_selected (SushiMediaBin *self, GstMessage *msg) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); GstStreamCollection *collection = NULL; GstStream *stream = NULL; GstStructure *caps_struct; GstCaps *caps; gint i, n, w, h; gst_message_parse_streams_selected (msg, &collection); n = gst_stream_collection_get_size (collection); for (i = 0; i < n; i++) { stream = gst_stream_collection_get_stream (collection, i); if (gst_stream_get_stream_type (stream) == GST_STREAM_TYPE_VIDEO) break; } if (!stream) return; caps = gst_stream_get_caps (stream); caps_struct = gst_caps_get_structure (caps, 0); if (gst_structure_get_int (caps_struct, "width", &w) && gst_structure_get_int (caps_struct, "height", &h)) { if (priv->video_width != w || priv->video_height != h) { priv->video_width = w; priv->video_height = h; gtk_widget_queue_resize (GTK_WIDGET (self)); } } else priv->video_width = priv->video_height = 0; g_signal_emit (self, sushi_media_bin_signals[SIZE_CHANGE], 0); gst_caps_unref (caps); gst_object_unref (collection); } static gboolean sushi_media_bin_bus_watch (GstBus *bus, GstMessage *msg, gpointer data) { SushiMediaBin *self = data; switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_APPLICATION: sushi_media_bin_handle_msg_application (self, msg); break; case GST_MESSAGE_DURATION_CHANGED: sushi_media_bin_update_duration (self); break; case GST_MESSAGE_EOS: sushi_media_bin_handle_msg_eos (self, msg); break; case GST_MESSAGE_ERROR: return sushi_media_bin_handle_msg_error (self, msg); case GST_MESSAGE_STATE_CHANGED: sushi_media_bin_handle_msg_state_changed (self, msg); break; case GST_MESSAGE_STREAMS_SELECTED: sushi_media_bin_handle_streams_selected (self, msg); break; case GST_MESSAGE_TAG: sushi_media_bin_handle_msg_tag (self, msg); break; default: break; } return G_SOURCE_CONTINUE; } static void sushi_media_bin_init_playbin (SushiMediaBin *self) { SushiMediaBinPrivate *priv = SMB_PRIVATE (self); priv->play = gst_element_factory_make ("playbin3", "SushiMediaBinPlayBin"); gst_object_ref_sink (priv->play); /* Setup volume */ /* NOTE: Bidirectional binding makes the app crash on X11 */ g_object_bind_property (priv->volume_adjustment, "value", priv->play, "volume", G_BINDING_SYNC_CREATE); /* Watch bus */ priv->bus = gst_pipeline_get_bus (GST_PIPELINE (priv->play)); gst_bus_add_watch (priv->bus, sushi_media_bin_bus_watch, self); } /********************************* Public API *********************************/ /** * sushi_media_bin_new: * @audio_mode: * * Returns a new #SushiMediaBin * */ GtkWidget * sushi_media_bin_new (gboolean audio_mode) { return (GtkWidget*) g_object_new (SUSHI_TYPE_MEDIA_BIN, "audio-mode", audio_mode, NULL); } /** * sushi_media_bin_get_uri: * @self: a #SushiMediaBin * * Return the media URI */ SMB_DEFINE_GETTER (const gchar *, uri, NULL) /** * sushi_media_bin_set_uri: * @self: a #SushiMediaBin * @uri: * * Sets the media URI to play */ SMB_DEFINE_SETTER_STRING (uri, URI, /* Make playbin show the first video frame if there is an URI * and the widget is realized. */ sushi_media_bin_update_state (self); /* Clear tag lists */ if (priv->audio_tags) { g_clear_pointer (&priv->audio_tags, gst_tag_list_unref); sushi_media_bin_post_message_application (self, "audio-tags-changed"); } if (priv->video_tags) { g_clear_pointer (&priv->video_tags, gst_tag_list_unref); sushi_media_bin_post_message_application (self, "video-tags-changed"); } if (priv->text_tags) { g_clear_pointer (&priv->text_tags, gst_tag_list_unref); sushi_media_bin_post_message_application (self, "text-tags-changed"); } ) /** * sushi_media_bin_get_autohide_timeout: * @self: a #SushiMediaBin * * Returns control's auto hide timeout in seconds. */ SMB_DEFINE_GETTER (gint, autohide_timeout, 0) /** * sushi_media_bin_set_autohide_timeout: * @self: a #SushiMediaBin * @autohide_timeout: A timeout in seconds * * Sets the timeout to auto hide controls */ SMB_DEFINE_SETTER (gint, autohide_timeout, AUTOHIDE_TIMEOUT,) /** * sushi_media_bin_get_fullscreen: * @self: a #SushiMediaBin * * Returns whether video is fullscreen or not */ SMB_DEFINE_GETTER (gboolean, fullscreen, FALSE) /** * sushi_media_bin_set_fullscreen: * @self: a #SushiMediaBin * @fullscreen: * * Sets whether to show the video in fullscreen mode or not */ SMB_DEFINE_SETTER_BOOLEAN (fullscreen, FULLSCREEN, /* If there is no video sink, delay fullscreen until realize event */ if (priv->video_sink) sushi_media_bin_fullscreen_apply (self, fullscreen); ) /** * sushi_media_bin_get_show_stream_info: * @self: a #SushiMediaBin * * Returns whether streams information are show or not */ SMB_DEFINE_GETTER (gboolean, show_stream_info, FALSE) /** * sushi_media_bin_set_show_stream_info: * @self: a #SushiMediaBin * @show_stream_info: * * Sets whether to show stream information or not */ SMB_DEFINE_SETTER_BOOLEAN (show_stream_info, SHOW_STREAM_INFO, if (show_stream_info) { sushi_media_bin_update_stream_info (self); gtk_widget_show (priv->info_box); } else { gint i; gtk_widget_hide (priv->info_box); for (i = 0; i < INFO_N_COLUMNS; i++) gtk_label_set_label (priv->info_column_label[i], ""); } ) /** * sushi_media_bin_get_title: * @self: a #SushiMediaBin * * Returns the media title if any */ SMB_DEFINE_GETTER (const gchar *, title, NULL) /** * sushi_media_bin_set_title: * @self: a #SushiMediaBin * @title: * * Sets the media title. * By default SushiMediaBin will use the title from the media metadata */ SMB_DEFINE_SETTER_STRING (title, TITLE, gtk_label_set_label (priv->title_label, title); gtk_widget_set_visible (GTK_WIDGET (priv->title_label), title != NULL); priv->title_user_set = TRUE; ) /** * sushi_media_bin_get_description: * @self: a #SushiMediaBin * * Returns the media description if any */ SMB_DEFINE_GETTER (const gchar *, description, NULL) /** * sushi_media_bin_set_description: * @self: a #SushiMediaBin * @description: * * Sets the media description. * By default SushiMediaBin will use the description from the media metadata */ SMB_DEFINE_SETTER_STRING (description, DESCRIPTION, priv->description_user_set = TRUE; ) /** * sushi_media_bin_get_volume: * @self: a #SushiMediaBin * * Returns audio volume from 0.0 to 1.0 */ SMB_DEFINE_GETTER_FULL (gdouble, volume, 1.0, return gtk_adjustment_get_value (SMB_PRIVATE (self)->volume_adjustment); ) /** * sushi_media_bin_set_volume: * @self: a #SushiMediaBin * @volume: from 0.0 to 1.0 * * Sets the audio volume */ SMB_DEFINE_SETTER_FULL (gdouble, volume, VOLUME, volume = CLAMP (volume, 0.0, 1.0), gtk_adjustment_get_value (priv->volume_adjustment) != volume, gtk_adjustment_set_value (priv->volume_adjustment, volume), ) /** * sushi_media_bin_get_audio_tags: * @self: a #SushiMediaBin * * Returns a #GstTagList with the audio tags for the played media */ SMB_DEFINE_GETTER_FULL (GstTagList *, audio_tags, NULL, return (gst_tag_list_ref (SMB_PRIVATE (self)->audio_tags)); ) /** * sushi_media_bin_get_video_tags: * @self: a #SushiMediaBin * * Returns a #GstTagList with the video tags for the played media */ SMB_DEFINE_GETTER_FULL (GstTagList *, video_tags, NULL, return (gst_tag_list_ref (SMB_PRIVATE (self)->video_tags)); ) /** * sushi_media_bin_play: * @self: a #SushiMediaBin * * Start media playback */ void sushi_media_bin_play (SushiMediaBin *self) { SushiMediaBinPrivate *priv; g_return_if_fail (SUSHI_IS_MEDIA_BIN (self)); priv = SMB_PRIVATE (self); g_object_set (priv->play, "uri", priv->uri, NULL); sushi_media_bin_set_state (self, GST_STATE_PLAYING); } /** * sushi_media_bin_pause: * @self: a #SushiMediaBin * * Pause media playback */ void sushi_media_bin_pause (SushiMediaBin *self) { g_return_if_fail (SUSHI_IS_MEDIA_BIN (self)); sushi_media_bin_set_state (self, GST_STATE_PAUSED); } /** * sushi_media_bin_stop: * @self: a #SushiMediaBin * * Stop media playback */ void sushi_media_bin_stop (SushiMediaBin *self) { g_return_if_fail (SUSHI_IS_MEDIA_BIN (self)); sushi_media_bin_set_state (self, GST_STATE_NULL); } static void sushi_media_bin_free_pixbuf (guchar *pixels, gpointer data) { gst_sample_unref (GST_SAMPLE (data)); } /** * sushi_media_bin_screenshot: * @self: a #SushiMediaBin * @width: desired screenshot width or -1 for original size * @height: desired screenshot height or -1 for original size * * Takes a screenshot of the current frame. * * Returns: (transfer full): a new #GdkPixbuf */ GdkPixbuf * sushi_media_bin_screenshot (SushiMediaBin *self, gint width, gint height) { SushiMediaBinPrivate *priv; GdkPixbuf *retval = NULL; GstSample *sample; GstCaps *caps; GstBuffer *buffer; GstMemory *memory = NULL; GstMapInfo info; g_return_val_if_fail (SUSHI_IS_MEDIA_BIN (self), NULL); priv = SMB_PRIVATE (self); /* Create a caps object with the desired format */ caps = gst_caps_new_simple ("video/x-raw", "format", G_TYPE_STRING, "RGB", "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1, NULL); if (width >= 0 && width >= 0) gst_caps_set_simple (caps, "width", G_TYPE_INT, width, "height", G_TYPE_INT, height, NULL); /* Get current sample in RGB */ g_signal_emit_by_name (priv->play, "convert-sample", caps, &sample); gst_caps_unref (caps); if (sample) { GstStructure *caps_struct; if (!(caps = gst_sample_get_caps (sample))) return NULL; caps_struct = gst_caps_get_structure (caps, 0); if (!(gst_structure_get_int (caps_struct, "width", &width) && gst_structure_get_int (caps_struct, "height", &height))) return NULL; } else { /* FIXME: gst does not suport converting from video/x-raw(memory:GLMemory) */ g_warning ("Could not get video sample"); return NULL; } /* The buffer remains valid as long as sample is valid */ if ((buffer = gst_sample_get_buffer (sample)) && (memory = gst_buffer_get_memory (buffer, 0)) && gst_memory_map (memory, &info, GST_MAP_READ)) { /* Create pixbuf from data with custom destroy function to free sample */ retval = gdk_pixbuf_new_from_data (info.data, GDK_COLORSPACE_RGB, FALSE, 8, width, height, GST_ROUND_UP_4 (width * 3), sushi_media_bin_free_pixbuf, sample); gst_memory_unmap (memory, &info); } else { g_warning ("Could not map memory from sample"); gst_sample_unref (sample); } gst_memory_unref (memory); return retval; } 07070100000071000081A4000000000000000000000001660EE2C800000964000000000000000000000000000000000000002C00000000sushi-46.0/src/libsushi/sushi-media-bin.css/* * sushi-media-bin.css * Based on ekn-media-bin.css from: * https://github.com/endlessm/eos-knowledge-lib/tree/master/lib/eosknowledgeprivate * * Copyright (C) 2016 Endless Mobile, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Author: Juan Pablo Ugarte <ugarte@endlessm.com> * */ @define-color audio-bg-color #4c4c4c; sushi-media-bin { background: black; } sushi-media-bin box.overlay-bar.top { padding: 12px; } sushi-media-bin label.title { font: 18px Sans; } /* Controls */ sushi-media-bin box.overlay-bar.bottom { padding: 13px; border-radius: 5px; } sushi-media-bin box.overlay-bar.bottom label { margin: 0px 6px; } /* Audio nodes */ sushi-media-bin box.audio > box { background: @audio-bg-color; } sushi-media-bin box.audio > scale { margin: 0; padding: 1px 0px; background-image: linear-gradient(to top, @audio-bg-color 3px, transparent 3px); } sushi-media-bin box.audio > scale trough { padding: 1px 0px; background: #707070; } /* Setup key bindings */ @binding-set smb-binding-set { bind "space" { "toggle" ("playback") }; bind "f" { "toggle" ("fullscreen") }; bind "i" { "toggle" ("show-stream-info") }; bind "Right" { "seek" (5) }; bind "Left" { "seek" (-5) }; bind "Up" { "seek" (60) }; bind "Down" { "seek" (-60) }; bind "Page_Up" { "seek" (300) }; bind "Page_Down" { "seek" (-300) }; bind "Home" { "seek" (0) }; } @binding-set smb-fullscreen-binding-set { bind "Escape" { "toggle" ("fullscreen") }; } sushi-media-bin { -gtk-key-bindings: smb-binding-set; } sushi-media-bin.fullscreen { -gtk-key-bindings: smb-binding-set, smb-fullscreen-binding-set; } 07070100000072000081A4000000000000000000000001660EE2C800000DEB000000000000000000000000000000000000002A00000000sushi-46.0/src/libsushi/sushi-media-bin.h/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ /* * sushi-media-bin.h * Based on ekn-media-bin.h from: * https://github.com/endlessm/eos-knowledge-lib/tree/master/lib/eosknowledgeprivate * * Copyright (C) 2016 Endless Mobile, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Author: Juan Pablo Ugarte <ugarte@endlessm.com> * */ #pragma once #include <gst/gst.h> #include <gtk/gtk.h> G_BEGIN_DECLS #define SUSHI_TYPE_MEDIA_BIN (sushi_media_bin_get_type ()) G_DECLARE_FINAL_TYPE (SushiMediaBin, sushi_media_bin, SUSHI, MEDIA_BIN, GtkBox) GtkWidget *sushi_media_bin_new (gboolean audio_mode); const gchar *sushi_media_bin_get_uri (SushiMediaBin *self); void sushi_media_bin_set_uri (SushiMediaBin *self, const gchar *uri); gdouble sushi_media_bin_get_volume (SushiMediaBin *self); void sushi_media_bin_set_volume (SushiMediaBin *self, gdouble volume); gint sushi_media_bin_get_autohide_timeout (SushiMediaBin *self); void sushi_media_bin_set_autohide_timeout (SushiMediaBin *self, gint autohide_timeout); gboolean sushi_media_bin_get_fullscreen (SushiMediaBin *self); void sushi_media_bin_set_fullscreen (SushiMediaBin *self, gboolean fullscreen); gboolean sushi_media_bin_get_show_stream_info (SushiMediaBin *self); void sushi_media_bin_set_show_stream_info (SushiMediaBin *self, gboolean show_stream_info); const gchar *sushi_media_bin_get_title (SushiMediaBin *self); void sushi_media_bin_set_title (SushiMediaBin *self, const gchar *title); const gchar *sushi_media_bin_get_description (SushiMediaBin *self); void sushi_media_bin_set_description (SushiMediaBin *self, const gchar *description); GstTagList *sushi_media_bin_get_audio_tags (SushiMediaBin *self); GstTagList *sushi_media_bin_get_video_tags (SushiMediaBin *self); void sushi_media_bin_play (SushiMediaBin *self); void sushi_media_bin_pause (SushiMediaBin *self); void sushi_media_bin_stop (SushiMediaBin *self); GdkPixbuf *sushi_media_bin_screenshot (SushiMediaBin *self, gint width, gint height); G_END_DECLS 07070100000073000081A4000000000000000000000001660EE2C800002C83000000000000000000000000000000000000002600000000sushi-46.0/src/libsushi/sushi-utils.c/* * Copyright (C) 2011 Red Hat, Inc. * * 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 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. * * The Sushi project hereby grant permission for non-gpl compatible GStreamer * plugins to be used and distributed together with GStreamer and Sushi. This * permission is above and beyond the permissions granted by the GPL license * Sushi is covered by. * * Authors: Cosimo Cecchi <cosimoc@redhat.com> * */ #include "sushi-utils.h" #include <glib/gstdio.h> #include <gtk/gtk.h> #ifdef GDK_WINDOWING_X11 #include <gdk/gdkx.h> #endif #ifdef GDK_WINDOWING_WAYLAND #include <gdk/gdkwayland.h> #endif #include "externalwindow.h" void sushi_window_set_child_of_external (GtkWindow *window, const char *handle) { ExternalWindow *external_window; gtk_widget_realize (GTK_WIDGET (window)); external_window = create_external_window_from_handle (handle); if (!external_window) return; external_window_set_parent_of (external_window, gtk_widget_get_window (GTK_WIDGET (window))); g_object_unref (external_window); } /** * sushi_get_evince_document_from_job: * @job: * @error: * * Returns: (transfer none): */ EvDocument * sushi_get_evince_document_from_job (EvJob *job, GError **error) { if (job->failed) { g_propagate_error (error, job->error); return NULL; } return job->document; } /** * sushi_query_supported_document_types: * * Returns: (transfer full): */ gchar ** sushi_query_supported_document_types (void) { GList *infos, *l; gchar **retval = NULL; GPtrArray *array; EvTypeInfo *info; gint idx; infos = ev_backends_manager_get_all_types_info (); if (infos == NULL) return NULL; array = g_ptr_array_new (); for (l = infos; l != NULL; l = l->next) { info = l->data; for (idx = 0; info->mime_types[idx] != NULL; idx++) g_ptr_array_add (array, g_strdup (info->mime_types[idx])); } g_ptr_array_add (array, NULL); retval = (gchar **) g_ptr_array_free (array, FALSE); return retval; } static void load_libreoffice (GTask *task); typedef struct { GFile *file; gchar *pdf_path; gboolean checked_libreoffice_flatpak; gboolean have_libreoffice_flatpak; GPid libreoffice_pid; } TaskData; static void task_data_free (TaskData *data) { if (data->pdf_path) { g_unlink (data->pdf_path); g_free (data->pdf_path); } if (data->libreoffice_pid != -1) { kill (data->libreoffice_pid, SIGKILL); data->libreoffice_pid = -1; } g_clear_object (&data->file); g_free (data); } static void libreoffice_missing_ready_cb (GObject *source, GAsyncResult *res, gpointer user_data) { g_autoptr(GTask) task = user_data; g_autoptr(GError) error = NULL; g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), res, &error); if (error != NULL) { /* can't install libreoffice with packagekit - nothing else we can do */ g_task_return_error (task, g_steal_pointer (&error)); return; } /* now that we have libreoffice installed, try again loading the document */ load_libreoffice (task); } static void libreoffice_missing (GTask *task) { GApplication *app = g_application_get_default (); GDBusConnection *connection = g_application_get_dbus_connection (app); const gchar *libreoffice_path[2]; libreoffice_path[0] = "/usr/bin/libreoffice"; libreoffice_path[1] = NULL; g_dbus_connection_call (connection, "org.freedesktop.PackageKit", "/org/freedesktop/PackageKit", "org.freedesktop.PackageKit.Modify2", "InstallProvideFiles", g_variant_new ("(^asssa{sv})", libreoffice_path, "hide-confirm-deps", "org.gnome.NautilusPreviewer"), NULL, G_DBUS_CALL_FLAGS_NONE, G_MAXINT, NULL, libreoffice_missing_ready_cb, g_object_ref (task)); } static void libreoffice_child_watch_cb (GPid pid, gint status, gpointer user_data) { g_autoptr(GTask) task = user_data; TaskData *data = g_task_get_task_data (task); g_spawn_close_pid (pid); data->libreoffice_pid = -1; g_task_return_pointer (task, g_file_new_for_path (data->pdf_path), g_object_unref); } #define LIBREOFFICE_FLATPAK "org.libreoffice.LibreOffice" static gboolean check_libreoffice_flatpak (GTask *task, const gchar *flatpak_path) { const gchar *check_argv[] = { flatpak_path, "info", LIBREOFFICE_FLATPAK, NULL }; g_autoptr(GError) error = NULL; gboolean ret; gint exit_status = -1; TaskData *data = g_task_get_task_data (task); if (data->checked_libreoffice_flatpak) return data->have_libreoffice_flatpak; data->checked_libreoffice_flatpak = TRUE; ret = g_spawn_sync (NULL, (gchar **) check_argv, NULL, G_SPAWN_DEFAULT | G_SPAWN_STDERR_TO_DEV_NULL | G_SPAWN_STDOUT_TO_DEV_NULL, NULL, NULL, NULL, NULL, &exit_status, &error); if (ret) { g_autoptr(GError) child_error = NULL; if (g_spawn_check_exit_status (exit_status, &child_error)) { g_debug ("Found LibreOffice flatpak!"); data->have_libreoffice_flatpak = TRUE; } else { g_debug ("LibreOffice flatpak not found, flatpak info returned %i (%s)", exit_status, child_error->message); } } else { g_warning ("Error while checking for LibreOffice flatpak: %s", error->message); } return data->have_libreoffice_flatpak; } static void load_libreoffice (GTask *task) { g_autofree gchar *flatpak_path = NULL, *libreoffice_path = NULL; g_autofree gchar *doc_path = NULL, *doc_name = NULL, *tmp_name = NULL; g_autofree gchar *command = NULL, *pdf_dir = NULL; g_auto(GStrv) argv = NULL; g_autoptr(GError) error = NULL; gboolean use_flatpak = FALSE; gboolean res; GPid pid; TaskData *data = g_task_get_task_data (task); flatpak_path = g_find_program_in_path ("flatpak"); if (flatpak_path != NULL) use_flatpak = check_libreoffice_flatpak (task, flatpak_path); if (!use_flatpak) { libreoffice_path = g_find_program_in_path ("libreoffice"); if (libreoffice_path == NULL) { libreoffice_missing (task); return; } } doc_path = g_file_get_path (data->file); doc_name = g_file_get_basename (data->file); /* libreoffice --convert-to replaces the extension with .pdf */ tmp_name = g_strrstr (doc_name, "."); if (tmp_name) *tmp_name = '\0'; tmp_name = g_strdup_printf ("%s.pdf", doc_name); pdf_dir = g_build_filename (g_get_user_cache_dir (), "sushi", NULL); data->pdf_path = g_build_filename (pdf_dir, tmp_name, NULL); g_mkdir_with_parents (pdf_dir, 0700); if (use_flatpak) { g_autofree gchar *flatpak_doc = g_strdup_printf ("--filesystem=%s:ro", doc_path); g_autofree gchar *flatpak_dir = g_strdup_printf ("--filesystem=%s", pdf_dir); const gchar *flatpak_argv[] = { NULL, /* to be replaced with flatpak binary */ "run", "--command=/app/libreoffice/program/soffice", "--nofilesystem=host", NULL, /* to be replaced with filesystem permissions to read document */ NULL, /* to be replaced with filesystem permissions to write output */ LIBREOFFICE_FLATPAK, "--convert-to", "pdf", "--outdir", NULL, /* to be replaced with output dir */ NULL, /* to be replaced with input file */ NULL }; flatpak_argv[0] = flatpak_path; flatpak_argv[4] = flatpak_doc; flatpak_argv[5] = flatpak_dir; flatpak_argv[10] = pdf_dir; flatpak_argv[11] = doc_path; argv = g_strdupv ((gchar **) flatpak_argv); } else { const gchar *libreoffice_argv[] = { NULL, /* to be replaced with binary */ "--convert-to", "pdf", "--outdir", NULL, /* to be replaced with output dir */ NULL, /* to be replaced with input file */ NULL }; libreoffice_argv[0] = libreoffice_path; libreoffice_argv[4] = pdf_dir; libreoffice_argv[5] = doc_path; argv = g_strdupv ((gchar **) libreoffice_argv); } command = g_strjoinv (" ", (gchar **) argv); g_debug ("Executing LibreOffice command: %s", command); res = g_spawn_async (NULL, (gchar **) argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, &error); if (!res) { g_warning ("Error while spawning libreoffice: %s", error->message); return; } g_child_watch_add (pid, libreoffice_child_watch_cb, g_object_ref (task)); data->libreoffice_pid = pid; } void sushi_convert_libreoffice (GFile *file, GAsyncReadyCallback callback, gpointer user_data) { GTask *task = g_task_new (NULL, NULL, callback, user_data); TaskData *data = g_new0 (TaskData, 1); data->libreoffice_pid = -1; data->file = g_object_ref (file); g_task_set_task_data (task, data, (GDestroyNotify) task_data_free); load_libreoffice (task); } /** * sushi_convert_libreoffice_finish: * @result: * @error: * * Returns: (transfer full): */ GFile * sushi_convert_libreoffice_finish (GAsyncResult *result, GError **error) { return g_task_propagate_pointer (G_TASK (result), error); } /** * sushi_pixbuf_from_gst_sample: * @sample: * @error: * * Returns: (transfer full): */ GdkPixbuf * sushi_pixbuf_from_gst_sample (GstSample *sample, GError **error) { g_autoptr(GdkPixbufLoader) loader = NULL; GstBuffer *buffer = gst_sample_get_buffer (sample); GdkPixbuf *pixbuf = NULL; GstMapInfo info; if (!gst_buffer_map (buffer, &info, GST_MAP_READ)) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to map GstBuffer"); return NULL; } loader = gdk_pixbuf_loader_new (); if (!gdk_pixbuf_loader_write (loader, info.data, info.size, error) || !gdk_pixbuf_loader_close (loader, error)) return NULL; pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); if (pixbuf) g_object_ref (pixbuf); gst_buffer_unmap (buffer, &info); return pixbuf; } /** * sushi_running_under_wayland: * * Returns: Whether we are running under Wayland backend. */ gboolean sushi_running_under_wayland (GdkDisplay *display) { #ifdef GDK_WINDOWING_WAYLAND return GDK_IS_WAYLAND_DISPLAY (display); #endif return FALSE; } 07070100000074000081A4000000000000000000000001660EE2C8000009B8000000000000000000000000000000000000002600000000sushi-46.0/src/libsushi/sushi-utils.h/* * Copyright (C) 2011 Red Hat, Inc. * * 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 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. * * The Sushi project hereby grant permission for non-gpl compatible GStreamer * plugins to be used and distributed together with GStreamer and Sushi. This * permission is above and beyond the permissions granted by the GPL license * Sushi is covered by. * * Authors: Cosimo Cecchi <cosimoc@redhat.com> * */ #ifndef __SUSHI_UTILS_H__ #define __SUSHI_UTILS_H__ #include <evince-document.h> #include <evince-view.h> #include <gdk/gdk.h> #include <gio/gio.h> #include <gst/gst.h> G_BEGIN_DECLS gchar ** sushi_query_supported_document_types (void); EvDocument * sushi_get_evince_document_from_job (EvJob *job, GError **error); void sushi_convert_libreoffice (GFile *file, GAsyncReadyCallback callback, gpointer user_data); GFile * sushi_convert_libreoffice_finish (GAsyncResult *result, GError **error); void sushi_get_asin_for_track (const gchar *artist, const gchar *album, GAsyncReadyCallback callback, gpointer user_data); gchar * sushi_get_asin_for_track_finish (GAsyncResult *result, GError **error); GdkPixbuf * sushi_pixbuf_from_gst_sample (GstSample *sample, GError **error); void sushi_window_set_child_of_external (GtkWindow *window, const char *handle); gboolean sushi_running_under_wayland (GdkDisplay *display); G_END_DECLS #endif /* __SUSHI_UTILS_H__ */ 07070100000075000081A4000000000000000000000001660EE2C800000586000000000000000000000000000000000000001B00000000sushi-46.0/src/meson.buildgnome = import('gnome') # Compile libsushi and its introspection data subdir('libsushi') conf_src = configuration_data() conf_src.set('object_path', object_path) sushi_src_resources = gnome.compile_resources( '@0@.src'.format(app_id), configure_file( input: 'org.gnome.NautilusPreviewer.src.gresource.xml.in', output: '@BASENAME@', configuration: conf_src ), gresource_bundle: true, install: true, install_dir: pkgdatadir, ) sushi_data_resources = gnome.compile_resources( '@0@.data'.format(app_id), 'org.gnome.NautilusPreviewer.data.gresource.xml', gresource_bundle: true, install: true, install_dir: pkgdatadir, ) conf = configuration_data() conf.set('GJS', gjs.full_path()) conf.set('PACKAGE_NAME', meson.project_name()) conf.set('PACKAGE_VERSION', meson.project_version()) conf.set('prefix', get_option('prefix')) conf.set('libdir', libdir) conf.set('pkgdatadir', pkgdatadir) conf.set('app_id', app_id) conf.set('object_path', object_path) nautilus_previewer_bin = configure_file( input: 'org.gnome.NautilusPreviewer.in', output: app_id, configuration: conf, ) install_data( nautilus_previewer_bin, install_mode: 'rwxr-xr-x', install_dir: libexecdir, ) sushi_bin = configure_file( input: 'sushi.in', output: 'sushi', configuration: conf, ) install_data( sushi_bin, install_mode: 'rwxr-xr-x', install_dir: bindir, ) 07070100000076000081A4000000000000000000000001660EE2C8000000E8000000000000000000000000000000000000003E00000000sushi-46.0/src/org.gnome.NautilusPreviewer.data.gresource.xml<?xml version="1.0" encoding="UTF-8"?> <gresources> <gresource prefix="/org/gnome/NautilusPreviewer"> <file>org.gnome.NautilusPreviewer.xml</file> <file>org.gnome.NautilusPreviewer2.xml</file> </gresource> </gresources> 07070100000077000081A4000000000000000000000001660EE2C8000000B8000000000000000000000000000000000000002E00000000sushi-46.0/src/org.gnome.NautilusPreviewer.in#!@GJS@ imports.package.init({ name: '@PACKAGE_NAME@', version: '@PACKAGE_VERSION@', prefix: '@prefix@', libdir: '@libdir@', }); imports.package.run(imports.ui.main); 07070100000078000081A4000000000000000000000001660EE2C8000002BF000000000000000000000000000000000000004000000000sushi-46.0/src/org.gnome.NautilusPreviewer.src.gresource.xml.in<?xml version="1.0" encoding="UTF-8"?> <gresources> <gresource prefix="@object_path@/js"> <file>ui/application.js</file> <file>ui/fallbackRenderer.js</file> <file>ui/main.js</file> <file>ui/mainWindow.js</file> <file>ui/mimeHandler.js</file> <file>ui/renderer.js</file> <file>ui/utils.js</file> <file>util/constants.js</file> <file>util/totemMimeTypes.js</file> <file>viewers/audio.js</file> <file>viewers/evince.js</file> <file>viewers/font.js</file> <file>viewers/gst.js</file> <file>viewers/html.js</file> <file>viewers/image.js</file> <file>viewers/libreoffice.js</file> <file>viewers/text.js</file> </gresource> </gresources> 07070100000079000081A4000000000000000000000001660EE2C800000145000000000000000000000000000000000000002F00000000sushi-46.0/src/org.gnome.NautilusPreviewer.xml<node> <interface name="org.gnome.NautilusPreviewer"> <method name="ShowFile"> <arg type="s" direction="in" name="uri" /> <arg type="i" direction="in" name="xid" /> <arg type="b" direction="in" name="closeIfAlreadyShown" /> </method> <method name="Close"> </method> </interface> </node> 0707010000007A000081A4000000000000000000000001660EE2C800000239000000000000000000000000000000000000003000000000sushi-46.0/src/org.gnome.NautilusPreviewer2.xml<node> <interface name="org.gnome.NautilusPreviewer2"> <method name="ShowFile"> <arg type="s" direction="in" name="uri" /> <arg type="s" direction="in" name="windowHandle" /> <arg type="b" direction="in" name="closeIfAlreadyShown" /> </method> <method name="Close"> </method> <!-- Since version 45 --> <property name="ParentHandle" type="s" access="read" /> <property name="Visible" type="b" access="read" /> <signal name="SelectionEvent"> <arg type="q" name="direction" /> </signal> </interface> </node> 0707010000007B000081A4000000000000000000000001660EE2C8000004FE000000000000000000000000000000000000001800000000sushi-46.0/src/sushi.in#!@GJS@ const {Gio, GLib, GObject} = imports.gi; const ByteArray = imports.byteArray; const System = imports.system; GLib.set_prgname('sushi'); function help() { print(`Usage: sushi FILE Opens FILE in a NautilusPreviewer window.`); } if (ARGV.includes('-h') || ARGV.includes('--help')) { help(); System.exit(0); } if (ARGV.length != 1) { printerr('The launcher takes exactly one argument\n'); help(); System.exit(1); } let file = Gio.File.new_for_commandline_arg(ARGV[0]); if (!file.query_exists(null)) { printerr(`The file at ${file.get_uri()} does not exist.`); System.exit(1); } try { let dataResource = Gio.Resource.load('@pkgdatadir@/@app_id@.data.gresource'); dataResource._register(); } catch(e) { logError(e, 'Unable to load data resource'); System.exit(1); } let bytes = Gio.resources_lookup_data( '/org/gnome/NautilusPreviewer/org.gnome.NautilusPreviewer.xml', 0); let wrapper = Gio.DBusProxy.makeProxyWrapper(ByteArray.toString(bytes.toArray())); let proxy; try { proxy = new wrapper( Gio.DBus.session, '@app_id@', '@object_path@'); } catch(e) { logError(e, 'Unable to create DBus proxy for NautilusPreviewer'); System.exit(1); } proxy.ShowFileSync(file.get_uri(), 0, false); 0707010000007C000041ED000000000000000000000002660EE2C800000000000000000000000000000000000000000000001200000000sushi-46.0/src/ui0707010000007D000081A4000000000000000000000001660EE2C8000013B8000000000000000000000000000000000000002100000000sushi-46.0/src/ui/application.js/* * Copyright (C) 2011 Red Hat, Inc. * * 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 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. * * The Sushi project hereby grant permission for non-gpl compatible GStreamer * plugins to be used and distributed together with GStreamer and Sushi. This * permission is above and beyond the permissions granted by the GPL license * Sushi is covered by. * * Authors: Cosimo Cecchi <cosimoc@redhat.com> * */ const {Gio, GLib, GObject, Gtk} = imports.gi; const ByteArray = imports.byteArray; const MainWindow = imports.ui.mainWindow; var NautilusPreviewerSkeleton = class { constructor(application, resource) { this.application = application; let bytes = Gio.resources_lookup_data(resource, 0); this._skeleton = Gio.DBusExportedObject.wrapJSObject( ByteArray.toString(bytes.toArray()), this); } get impl() { return this._skeleton; } export(connection, path) { try { this._skeleton.export(connection, path); } catch (e) { logError(e, 'Failed to export NautilusPreviewer DBus interface'); } } unexport(connection) { if (this._skeleton && this._skeleton.has_connection(connection)) this._skeleton.unexport_from_connection(connection); } Close() { this.application.close(); } } var NautilusPreviewer1Skeleton = class extends NautilusPreviewerSkeleton { constructor(application) { super(application, '/org/gnome/NautilusPreviewer/org.gnome.NautilusPreviewer.xml'); } ShowFile(uri, xid, closeIfAlreadyShown) { let handle = 'x11:%d'.format(xid); this.application.showFile(uri, handle, closeIfAlreadyShown); } } var NautilusPreviewer2Skeleton = class extends NautilusPreviewerSkeleton { constructor(application) { super(application, '/org/gnome/NautilusPreviewer/org.gnome.NautilusPreviewer2.xml'); } ShowFile(uri, windowHandle, closeIfAlreadyShown) { this.application.showFile(uri, windowHandle, closeIfAlreadyShown); } } var Application = GObject.registerClass(class Application extends Gtk.Application { vfunc_startup() { super.vfunc_startup(); this._defineStyleAndThemes(); } vfunc_dbus_register(connection, path) { let actualPath = `/org/gnome/${pkg.name.split('.').at(-1)}`; this._skeleton = new NautilusPreviewer1Skeleton(this); this._skeleton2 = new NautilusPreviewer2Skeleton(this); this._skeleton.export(connection, actualPath); this._skeleton2.export(connection, actualPath); return super.vfunc_dbus_register(connection, path); } vfunc_dbus_unregister(connection, path) { this._skeleton.unexport(connection); this._skeleton2.unexport(connection); return super.vfunc_dbus_unregister(connection, path); } vfunc_activate() { } _ensureMainWindow() { if (this._mainWindow) return; this._mainWindow = new MainWindow.MainWindow(this); if (pkg.name.endsWith('Devel')) this._mainWindow.get_style_context().add_class('devel'); this._skeleton2.impl.emit_property_changed( 'Visible', new GLib.Variant('b', true)); this._mainWindow.connect('destroy', () => { this._mainWindow = null; this._skeleton2.impl.emit_property_changed( 'Visible', new GLib.Variant('b', false)); }); } _defineStyleAndThemes() { let settings = Gtk.Settings.get_default(); settings.gtk_application_prefer_dark_theme = true; } close() { if (this._mainWindow) this._mainWindow.destroy(); } emitSelectionEvent(direction) { this._skeleton2.impl.emit_signal( 'SelectionEvent', new GLib.Variant('(u)', [direction])); } updateParentHandle(handle) { this._skeleton2.impl.emit_property_changed( 'ParentHandle', new GLib.Variant('s', handle)); } showFile(uri, windowHandle, closeIfAlreadyShown) { this._ensureMainWindow(); let file = Gio.file_new_for_uri(uri); if (closeIfAlreadyShown && this._mainWindow.file && this._mainWindow.file.equal(file)) { this._mainWindow.destroy(); } else { this._mainWindow.setParent(windowHandle); this._mainWindow.setFile(file); } } }); 0707010000007E000081A4000000000000000000000001660EE2C80000287D000000000000000000000000000000000000002600000000sushi-46.0/src/ui/fallbackRenderer.js/* * Copyright (C) 2011 Red Hat, Inc. * * 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 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. * * The Sushi project hereby grant permission for non-gpl compatible GStreamer * plugins to be used and distributed together with GStreamer and Sushi. This * permission is above and beyond the permissions granted by the GPL license * Sushi is covered by. * * Authors: Cosimo Cecchi <cosimoc@redhat.com> * */ const {Gio, GLib, GObject, Gtk, Pango} = imports.gi; const Gettext = imports.gettext; const Renderer = imports.ui.renderer; function _getDeepCountAttrs() { return [ Gio.FILE_ATTRIBUTE_STANDARD_SIZE, Gio.FILE_ATTRIBUTE_STANDARD_TYPE, Gio.FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, Gio.FILE_ATTRIBUTE_STANDARD_NAME, Gio.FILE_ATTRIBUTE_UNIX_INODE ].join(','); } const loadFile = function(_fileToLoad, _fileInfo, _cancellable, _updateCallback) { let _seenInodes = new Set(); let _subDirectories = []; let _enumerator = null; let _file = null; let _state = { fileInfo: _fileInfo, directoryItems: 0, fileItems: 0, loading: true, totalItems: 0, totalSize: 0, unreadableItems: 0 } let _timeoutId = 0; function _cleanup() { if (_enumerator && !_enumerator.is_closed()) _enumerator.close_async(0, null, null); } function _deepCountLoad() { _file.enumerate_children_async( _getDeepCountAttrs(), Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, GLib.PRIORITY_LOW, _cancellable, (f, res) => { try { _enumerator = _file.enumerate_children_finish(res); } catch(e) { _state.unreadableItems++; if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) _deepCountNext(); return; } _enumerator.next_files_async( 100, GLib.PRIORITY_LOW, _cancellable, _deepCountMoreFiles); }); } function _deepCountMoreFiles(en, res) { let files = []; try { files = _enumerator.next_files_finish(res); } catch (e) { if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) return; } files.forEach(_deepCountOne); if (files.length) { _enumerator.next_files_async( 100, GLib.PRIORITY_LOW, _cancellable, _deepCountMoreFiles); } else { _cleanup(); _deepCountNext(); } } function _deepCountNext() { _file = _subDirectories.shift(); if (_file) { _deepCountLoad(); } else { _cleanup(); _state.loading = false; } _queueUpdate(); } function _deepCountOne(info) { let inode = info.get_attribute_uint64(Gio.FILE_ATTRIBUTE_UNIX_INODE); let isSeen = false; if (inode) { isSeen = _seenInodes.has(inode); if (!isSeen) _seenInodes.add(inode); } let fileType = info.get_file_type(); if (fileType == Gio.FileType.DIRECTORY) { _state.directoryItems++; _subDirectories.unshift(_file.get_child(info.get_name())); } else { _state.fileItems++; } if (!isSeen && info.has_attribute(Gio.FILE_ATTRIBUTE_STANDARD_SIZE)) _state.totalSize += info.get_size(); } function _queueUpdate() { if (_timeoutId != 0) return; _timeoutId = GLib.timeout_add(0, 300, () => { _timeoutId = 0; _sendUpdate(); return false; }); } function _unqueueUpdate() { if (_timeoutId != 0) GLib.source_remove(_timeoutId); } function _sendUpdate() { _updateCallback(_state); } _cancellable.connect(_unqueueUpdate); _file = _fileToLoad; let fileType = _fileInfo.get_file_type(); if (fileType == Gio.FileType.DIRECTORY) _deepCountLoad(); else _state.loading = false; _sendUpdate(); }; var FallbackRenderer = GObject.registerClass({ Implements: [Renderer.Renderer], Properties: { fullscreen: GObject.ParamSpec.boolean('fullscreen', '', '', GObject.ParamFlags.READABLE, false), ready: GObject.ParamSpec.boolean('ready', '', '', GObject.ParamFlags.READABLE, false) }, }, class FallbackRenderer extends Gtk.Box { get ready() { return !!this._ready; } get fullscreen() { return !!this._fullscreen; } _init(file, fileInfo) { super._init({ orientation: Gtk.Orientation.HORIZONTAL, spacing: 6 }); this._image = new Gtk.Image(); this.pack_start(this._image, false, false, 0); this._updateIcon(new Gio.ThemedIcon({ name: 'text-x-generic' })); let vbox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL, spacing: 1, margin_top: 48, margin_start: 12, margin_end: 12 }); this.pack_start(vbox, false, false, 0); let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL, spacing: 6 }); vbox.pack_start(hbox, false, false, 0); this._titleLabel = new Gtk.Label({ max_width_chars: 48, ellipsize: Pango.EllipsizeMode.MIDDLE }); this._titleLabel.set_halign(Gtk.Align.START); hbox.pack_start(this._titleLabel, false, false, 0); this._spinner = new Gtk.Spinner(); hbox.pack_start(this._spinner, false, false, 0); this._spinner.start(); this._spinner.show(); this._typeLabel = new Gtk.Label({ no_show_all: true }); this._typeLabel.set_halign(Gtk.Align.START); vbox.pack_start(this._typeLabel, false, false, 0); this._sizeLabel = new Gtk.Label(); this._sizeLabel.set_halign(Gtk.Align.START); vbox.pack_start(this._sizeLabel, false, false, 0); this._dateLabel = new Gtk.Label(); this._dateLabel.set_halign(Gtk.Align.START); vbox.pack_start(this._dateLabel, false, false, 0); this._cancellable = new Gio.Cancellable(); loadFile(file, fileInfo, this._cancellable, this._onFileInfoUpdated.bind(this)); this.connect('destroy', this._onDestroy.bind(this)); this.isReady(); } _applyLabels(state) { let fileName = state.fileInfo.get_display_name(); fileName = GLib.markup_escape_text(fileName, -1); let titleStr = `<b><big>${fileName}</big></b>`; this._titleLabel.set_markup(titleStr); if (state.fileInfo.get_file_type() != Gio.FileType.DIRECTORY) { let contentType = state.fileInfo.get_content_type(); let typeDescr = Gio.content_type_get_description(contentType); typeDescr = GLib.markup_escape_text(typeDescr, -1); let typeStr = '<small><b>' + _("Type") + ' </b>' + typeDescr + '</small>'; this._typeLabel.set_markup(typeStr); this._typeLabel.show(); } let sizeFormatted; if (state.fileInfo.get_file_type() != Gio.FileType.DIRECTORY) { sizeFormatted = GLib.format_size(state.fileInfo.get_size()); } else if (state.totalSize > 0) { let itemsStr = Gettext.ngettext( "%d item", "%d items", state.fileItems + state.directoryItems). format(state.fileItems + state.directoryItems); sizeFormatted = `${GLib.format_size(state.totalSize)}, ${itemsStr}`; } else { sizeFormatted = _("Empty Folder"); } sizeFormatted = GLib.markup_escape_text(sizeFormatted, -1); let sizeStr = '<small><b>' + _("Size") + ' </b>' + sizeFormatted + '</small>'; this._sizeLabel.set_markup(sizeStr); let date = GLib.DateTime.new_from_timeval_local(state.fileInfo.get_modification_time()); let dateFormatted = date.format('%x %X'); dateFormatted = GLib.markup_escape_text(dateFormatted, -1); let dateStr = '<small><b>' + _("Modified") + ' </b>' + dateFormatted + '</small>'; this._dateLabel.set_markup(dateStr); } _applyIcon(state) { let icon = state.fileInfo.get_icon(); this._updateIcon(icon); } _updateIcon(icon) { let iconTheme = Gtk.IconTheme.get_default(); let iconInfo = iconTheme.lookup_by_gicon_for_scale(icon, 256, this._image.scale_factor, 0); if (!iconInfo) return; try { let surface = iconInfo.load_surface(this._image.get_window()); this._image.surface = surface; } catch (e) { logError(e, `Error loading surface for icon ${icon.to_string()}`); } } _onFileInfoUpdated(state) { if (!state.loading) { this._spinner.stop(); this._spinner.hide(); } this._applyIcon(state); this._applyLabels(state); } _onDestroy() { this._cancellable.cancel(); } get hasToolbar() { return false; } get resizable() { return false; } get resizePolicy() { return Renderer.ResizePolicy.NAT_SIZE; } }); 0707010000007F000081A4000000000000000000000001660EE2C8000006F3000000000000000000000000000000000000001A00000000sushi-46.0/src/ui/main.js/* * Copyright (C) 2011 Red Hat, Inc. * * 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 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. * * The Sushi project hereby grant permission for non-gpl compatible GStreamer * plugins to be used and distributed together with GStreamer and Sushi. This * permission is above and beyond the permissions granted by the GPL license * Sushi is covered by. * * Authors: Cosimo Cecchi <cosimoc@redhat.com> * */ pkg.initGettext(); pkg.initFormat(); pkg.require({ EvinceDocument: '3.0', EvinceView: '3.0', Gdk: '3.0', GdkPixbuf: '2.0', Gio: '2.0', GLib: '2.0', GObject: '2.0', Gst: '1.0', GstTag: '1.0', Gtk: '3.0', GtkSource: '4', Pango: '1.0', Soup: '3.0', Sushi: '1.0', }); const {Gio, GLib} = imports.gi; const Application = imports.ui.application; function main(argv) { let application = new Application.Application({ application_id: pkg.name, flags: Gio.ApplicationFlags.IS_SERVICE, inactivity_timeout: 12000 }); if (GLib.getenv('SUSHI_PERSIST')) application.hold(); return application.run(argv); } 07070100000080000081A4000000000000000000000001660EE2C800003AEB000000000000000000000000000000000000002000000000sushi-46.0/src/ui/mainWindow.js/* * Copyright (C) 2011 Red Hat, Inc. * * 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 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. * * The Sushi project hereby grant permission for non-gpl compatible GStreamer * plugins to be used and distributed together with GStreamer and Sushi. This * permission is above and beyond the permissions granted by the GPL license * Sushi is covered by. * * Authors: Cosimo Cecchi <cosimoc@redhat.com> * */ const {Gdk, Gio, GLib, GObject, Gtk, Sushi} = imports.gi; const Constants = imports.util.constants; const MimeHandler = imports.ui.mimeHandler; const Renderer = imports.ui.renderer; const Utils = imports.ui.utils; const WINDOW_MAX_W = 800; const WINDOW_MAX_H = 600; const WINDOW_MAX_W_BASE = 1368; const WINDOW_MAX_H_BASE = 768; const Embed = GObject.registerClass(class Embed extends Gtk.Overlay { vfunc_get_request_mode() { return Gtk.SizeRequestMode.HEIGHT_FOR_WIDTH; } vfunc_get_preferred_width() { let [min, nat] = super.vfunc_get_preferred_width(); min = Math.max(min, Constants.VIEW_MIN); nat = Math.max(nat, Constants.VIEW_MIN); return [min, nat]; } vfunc_get_preferred_height_for_width(forWidth) { let [min, nat] = super.vfunc_get_preferred_height_for_width(forWidth); if (forWidth <= Constants.VIEW_MIN) { min = Math.max(min, Constants.VIEW_MIN); nat = Math.max(nat, Constants.VIEW_MIN); } return [min, nat]; } }); const ErrorBox = GObject.registerClass({ Implements: [Renderer.Renderer], Properties: { fullscreen: GObject.ParamSpec.boolean('fullscreen', '', '', GObject.ParamFlags.READABLE, false), ready: GObject.ParamSpec.boolean('ready', '', '', GObject.ParamFlags.READABLE, false) }, }, class ErrorBox extends Gtk.Grid { _init(file, error) { super._init({ orientation: Gtk.Orientation.VERTICAL, row_spacing: 12, hexpand: true, vexpand: true, halign: Gtk.Align.CENTER, valign: Gtk.Align.CENTER }); let image = new Gtk.Image({ pixel_size: 128, icon_name: 'face-uncertain-symbolic', halign: Gtk.Align.CENTER, valign: Gtk.Align.CENTER }); this.add(image); // TRANSLATORS: This is a filename, e.g. "image.jpg" let primary = _("Unable to display %s").format(file.get_basename()); let primaryMarkup = '<big><b>%s</b></big>'.format(GLib.markup_escape_text(primary, -1)); let primaryLabel = new Gtk.Label({ label: primaryMarkup, use_markup: true, halign: Gtk.Align.CENTER, valign: Gtk.Align.CENTER }); this.add(primaryLabel); let secondaryLabel = new Gtk.Label({ label: error.message, wrap: true, halign: Gtk.Align.CENTER, valign: Gtk.Align.CENTER }); this.add(secondaryLabel); this.show_all(); } }); function _getDecorationLayout() { function _isSupported(name) { // We don't support maximize and minimize return ['menu', 'close'].includes(name); } let settings = Gtk.Settings.get_default(); let decorationLayout = settings.gtk_decoration_layout; let [lhs, rhs] = decorationLayout.split(':'); let leftGroup = lhs.split(',').filter(_isSupported); let rightGroup = rhs ? rhs.split(',').filter(_isSupported) : []; return [leftGroup.join(','), rightGroup.join(',')].join(':'); }; var MainWindow = GObject.registerClass(class MainWindow extends Gtk.ApplicationWindow { _init(application) { this._renderer = null; this._lastWindowSize = [0, 0]; this.file = null; super._init({ type: Gtk.WindowType.TOPLEVEL, skipPagerHint: true, skipTaskbarHint: true, windowPosition: Gtk.WindowPosition.CENTER, gravity: Gdk.Gravity.CENTER, application: application }); this._titlebar = new Gtk.HeaderBar({ show_close_button: true, decoration_layout: _getDecorationLayout() }); this.set_titlebar(this._titlebar); this._openButton = new Gtk.Button(); this._openButton.connect('clicked', this._onFileOpenClicked.bind(this)); this._titlebar.pack_end(this._openButton); this.connect('motion-notify-event', this._onMotionNotifyEvent.bind(this)); this.connect('realize', this._onRealize.bind(this)); let eventBox = new Gtk.EventBox({ visible_window: false }); eventBox.connect('button-press-event', this._onButtonPressEvent.bind(this)); this.add(eventBox); this._embed = new Embed(); eventBox.add(this._embed); // call show_all() early when there's still no child Renderer, because show_all() later // when the Renderer is a child may have unexpected results, see comments in !49 this.show_all(); // but leave MainWindow not visible, because we want it to be firstly shown/mapped // when it has its final dimemnsions i.e. when the Renderer has emmitted the 'ready' // signal, i.e. on the _onRendererReady() handler. this.hide(); this._defineActions(); } _onRealize() { // don't support maximize and minimize this.get_window().set_functions(Gdk.WMFunction.MOVE | Gdk.WMFunction.RESIZE | Gdk.WMFunction.CLOSE); } _defineActions() { let quit = new Gio.SimpleAction({ name: 'quit' }); quit.connect('activate', () => { this.destroy(); }); this.application.set_accels_for_action('win.quit', ['q', 'Escape', 'space']); this.add_action(quit); let fullscreen = new Gio.SimpleAction({ name: 'fullscreen' }); fullscreen.connect('activate', () => { this._renderer.toggleFullscreen(); }); this.application.set_accels_for_action('win.fullscreen', ['f', 'F11']); this.add_action(fullscreen); var _addSelectAction = ((name, accel, direction) => { let action = new Gio.SimpleAction({ name: name }); action.connect('activate', () => { this.application.emitSelectionEvent(direction); }); this.application.set_accels_for_action(`win.${name}`, [accel]); this.add_action(action); }); _addSelectAction('select-left', 'Left', Gtk.DirectionType.LEFT); _addSelectAction('select-right', 'Right', Gtk.DirectionType.RIGHT); _addSelectAction('select-up', 'Up', Gtk.DirectionType.UP); _addSelectAction('select-down', 'Down', Gtk.DirectionType.DOWN); } _onButtonPressEvent(window, event) { if (!this._renderer.moveOnClick) return false; let [, rootX, rootY] = event.get_root_coords(); let [, button] = event.get_button(); this.begin_move_drag(button, rootX, rootY, event.get_time()); return false; } _onMotionNotifyEvent() { if (this._renderer.toolbar) this._renderer.toolbar.resetTimeout(); return false; } _reportError(error) { let renderer = new ErrorBox(this.file, error); this._embedRenderer(renderer); } _onRendererFullscreen() { if (this._renderer.fullscreen) this.fullscreen(); else this.unfullscreen(); } _onRendererReady() { if (this._renderer.ready) { this._resizeWindow(); this.queue_resize(); this.show(); } } _getMaxSize() { let gdkWin = this.get_window(); let display = this.get_display(); let underWayland = Sushi.running_under_wayland(display); let monitor = display.get_monitor_at_window(gdkWin); let geometry = monitor.get_geometry(); // Scale our maximum with the actual monitor geometry let scaleW = 1.0; let scaleH = 1.0; // FIXME: We can only trust GTK >= 3.24.9 to report the right // monitor geometry under Wayland when fractional scaling is enabled. // Disable the scaling logic for older GTK versions. // See https://gitlab.gnome.org/GNOME/gtk/issues/1828 let versionCheck = Gtk.check_version(3, 24, 9); if (!versionCheck) { scaleW = (geometry.width / WINDOW_MAX_W_BASE); scaleH = (geometry.height / WINDOW_MAX_H_BASE); } // reduce by scale factor only under Wayland, otherwise // X11 HiDPI windows are shown too small -- Issue #91 if (underWayland) { scaleW = scaleW / this.get_scale_factor (); scaleH = scaleH / this.get_scale_factor (); } return [Math.floor(scaleW * WINDOW_MAX_W), Math.floor(scaleH * WINDOW_MAX_H)]; } _resizeWindow() { if (!this._renderer) return; if (this._renderer.fullscreen) return; let maxSize = this._getMaxSize(); let rendererSize = [this._renderer.get_preferred_width(), this._renderer.get_preferred_height()]; let natSize = [rendererSize[0][1], rendererSize[1][1]]; let windowSize; let resizePolicy = this._renderer.resizePolicy; if (resizePolicy == Renderer.ResizePolicy.MAX_SIZE) windowSize = maxSize; else if (resizePolicy == Renderer.ResizePolicy.NAT_SIZE) windowSize = natSize; else if (resizePolicy == Renderer.ResizePolicy.SCALED) windowSize = Utils.getScaledSize(natSize, maxSize, false); else if (resizePolicy == Renderer.ResizePolicy.STRETCHED) windowSize = Utils.getScaledSize(natSize, maxSize, true); if ((windowSize[0] > 0 && windowSize[0] != this._lastWindowSize[0]) || (windowSize[1] > 0 && windowSize[1] != this._lastWindowSize[1])) { this._lastWindowSize = windowSize; this.resize(windowSize[0], windowSize[1]); } } _createRenderer() { this.file.query_info_async( [Gio.FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, Gio.FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, Gio.FILE_ATTRIBUTE_STANDARD_ICON, Gio.FILE_ATTRIBUTE_STANDARD_SIZE, Gio.FILE_ATTRIBUTE_STANDARD_TYPE, Gio.FILE_ATTRIBUTE_TIME_MODIFIED].join(','), Gio.FileQueryInfoFlags.NONE, GLib.PRIORITY_DEFAULT, null, (obj, res) => { try { let fileInfo = obj.query_info_finish(res); this._createView(fileInfo); } catch(e) { this._reportError(e); } }); } _embedRenderer(renderer) { if (this._renderer) { this._renderer.destroy() this._renderer = null; } this._renderer = renderer; this._renderer.show_all(); this._renderer.expand = true; this._embed.add(this._renderer); if (this._renderer.toolbar) this._embed.add_overlay(this._renderer.toolbar); } _createView(fileInfo) { let klass = MimeHandler.getKlass(fileInfo.get_content_type()); let renderer = new klass(this.file, fileInfo); this._embedRenderer(renderer); renderer.connect('error', (r, err) => { this._reportError(err); }); renderer.connect('notify::fullscreen', this._onRendererFullscreen.bind(this)); renderer.connect('notify::ready', this._onRendererReady.bind(this)); this._onRendererReady(); this.set_resizable(this._renderer.resizable); this.set_title(fileInfo.get_display_name()); } _updateTitlebar() { try { let appInfo = this.file.query_default_handler(null); // TRANSLATORS: This is the display name of an application, e.g. "Open With Image Viewer" this._openButton.set_label(_("Open With %s").format(appInfo.get_display_name())); } catch (e) { // This happens when running under flatpak, since we don't have direct access // to the other applications if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_SUPPORTED)) logError(e, `Failed to query default handler for ${this.file.get_uri()}`); this._openButton.set_label(_("Open")); } } _onFileOpenClicked() { let ctx = this.get_display().get_app_launch_context(); ctx.set_timestamp(Gtk.get_current_event_time()); ctx.set_screen(this.get_screen()); // Ideally we would use gtk_show_uri_on_window() here, since it properly // parents dialogs that may come from a flatpak portal over the window. // // Unfortunately we need to wait until the result of the launch before // destroying our window, which gtk_show_uri_on_window() doesn't allow, // so we use GIO directly. Gio.AppInfo.launch_default_for_uri_async(this.file.get_uri(), ctx, null, (obj, result) => { try { Gio.AppInfo.launch_default_for_uri_finish(result); this.destroy(); } catch (e) { logError(e, `Failed to launch default handler for ${this.file.get_uri()}`); } }); } /************************************************************************** ************************ public methods ********************************** **************************************************************************/ setParent(handle) { Sushi.window_set_child_of_external(this, handle); this.application.updateParentHandle(handle); } setFile(file) { this.file = file; this._updateTitlebar(); this._createRenderer(); } }); 07070100000081000081A4000000000000000000000001660EE2C80000082B000000000000000000000000000000000000002100000000sushi-46.0/src/ui/mimeHandler.js/* * Copyright (C) 2011 Red Hat, Inc. * * 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 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. * * The Sushi project hereby grant permission for non-gpl compatible GStreamer * plugins to be used and distributed together with GStreamer and Sushi. This * permission is above and beyond the permissions granted by the GPL license * Sushi is covered by. * * Authors: Cosimo Cecchi <cosimoc@redhat.com> * */ const {Gio, GLib} = imports.gi; const FallbackRenderer = imports.ui.fallbackRenderer; var renderers = []; //Patch import path let localPath = GLib.build_filenamev([GLib.get_user_data_dir(), 'sushi']); imports.searchPath.push(localPath); for (let i in imports.viewers) { if (imports.viewers[i].hasOwnProperty('mimeTypes')) { renderers.push(imports.viewers[i]); } } var getKlass = function(mime) { let renderer = renderers.find((r) => { // first, try a direct match with the mimetype itself if (r.mimeTypes.includes(mime)) return true; return false; }); if (!renderer) { renderer = renderers.find((r) => { // if this fails, try to see if we have any handlers // registered for a parent type if (r.mimeTypes.some((rm) => Gio.content_type_is_a(mime, rm))) return true; return false; }); } if (renderer) return renderer.Klass; // finally, resort to the fallback renderer return FallbackRenderer.FallbackRenderer; } 07070100000082000081A4000000000000000000000001660EE2C800000EBB000000000000000000000000000000000000001E00000000sushi-46.0/src/ui/renderer.jsconst {GLib, GObject, Gtk} = imports.gi; const Constants = imports.util.constants; const Utils = imports.ui.utils; var ResizePolicy = { MAX_SIZE: 0, NAT_SIZE: 1, SCALED: 2, STRETCHED: 3 }; var Renderer = GObject.registerClass({ Requires: [Gtk.Widget], Properties: { fullscreen: GObject.ParamSpec.boolean('fullscreen', '', '', GObject.ParamFlags.READABLE, false), ready: GObject.ParamSpec.boolean('ready', '', '', GObject.ParamFlags.READABLE, false) }, Signals: { 'error': { param_types: [GLib.Error.$gtype] } } }, class Renderer extends GObject.Interface { isReady() { this._ready = true; this.notify('ready'); } populateToolbar() { // do nothing, this is optional } toggleFullscreen() { if (!this.canFullscreen) return; this._fullscreen = !this.fullscreen; this.notify('fullscreen'); } get canFullscreen() { // by default, we can fullscreen if we're resizable return this.resizable; } get fullscreen() { return !!this._fullscreen; } get hasToolbar() { return true; } get moveOnClick() { return true; } get ready() { return !!this._ready; } get resizable() { return true; } get resizePolicy() { return ResizePolicy.MAX_SIZE; } get toolbar() { if (!this.hasToolbar) return null; if (!this._toolbar) { this._toolbar = new RendererToolbar(); this.connect('destroy', () => { this._toolbar.destroy(); }); this.populateToolbar(this._toolbar.box); if (this.canFullscreen) { if (this._toolbar.box.get_children().length > 0) this._toolbar.box.add(new Gtk.Separator({ orientation: Gtk.Orientation.VERTICAL })); this._toolbar.box.add(Utils.createFullscreenButton(this)); } } return this._toolbar; } }); var RendererToolbarBox = GObject.registerClass({ CssName: 'toolbar', }, class RendererToolbarBox extends Gtk.Box { _init() { super._init({ halign: Gtk.Align.CENTER, hexpand: true }); this.get_style_context().add_class('osd'); } }); var RendererToolbar = GObject.registerClass(class RendererToolbar extends Gtk.Revealer { _init() { this._revealTimeoutId = 0; super._init({ valign: Gtk.Align.END, hexpand: true, margin_bottom: Constants.TOOLBAR_SPACING, margin_start: Constants.TOOLBAR_SPACING, margin_end: Constants.TOOLBAR_SPACING, transition_type: Gtk.RevealerTransitionType.CROSSFADE }); this.box = new RendererToolbarBox(); this.add(this.box); this.connect('destroy', this._onDestroy.bind(this)); } resetTimeout() { if (this._revealTimeoutId == 0) this.reveal_child = true; this._removeRevealTimeout(); this._revealTimeoutId = GLib.timeout_add( GLib.PRIORITY_DEFAULT, 1500, this._onRevealTimeout.bind(this)); } _onDestroy() { this._removeRevealTimeout(); } _onRevealTimeout() { this._revealTimeoutId = 0; this.reveal_child = false; return false; } _removeRevealTimeout() { if (this._revealTimeoutId != 0) { GLib.source_remove(this._revealTimeoutId); this._revealTimeoutId = 0; } } }); 07070100000083000081A4000000000000000000000001660EE2C800000A2E000000000000000000000000000000000000001B00000000sushi-46.0/src/ui/utils.js/* * Copyright (C) 2011 Red Hat, Inc. * * 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 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. * * The Sushi project hereby grant permission for non-gpl compatible GStreamer * plugins to be used and distributed together with GStreamer and Sushi. This * permission is above and beyond the permissions granted by the GPL license * Sushi is covered by. * * Authors: Cosimo Cecchi <cosimoc@redhat.com> * */ const {Gtk} = imports.gi; function getScaledSize(baseSize, allocSize, upscale) { let allocW = allocSize[0]; let allocH = allocSize[1]; let width = baseSize[0]; let height = baseSize[1]; let scale = 1.0; if (((width <= allocW && height <= allocH) && upscale) || (width > allocW && height > allocH)) { /* up/downscale both directions */ let allocRatio = allocW / allocH; let baseRatio = width / height; if (baseRatio > allocRatio) scale = allocW / width; else scale = allocH / height; } else if (width > allocW && height <= allocH) { /* downscale x */ scale = allocW / width; } else if (width <= allocW && height > allocH) { /* downscale y */ scale = allocH / height; } width *= scale; height *= scale; return [ Math.floor(width), Math.floor(height) ]; } function createToolButton(renderer, iconName, callback) { let button = Gtk.Button.new_from_icon_name(iconName, Gtk.IconSize.MENU); button.set_relief(Gtk.ReliefStyle.NONE); button.connect('clicked', () => { renderer.toolbar.resetTimeout(); callback(button); }); return button; } function createFullscreenButton(renderer) { return createToolButton(renderer, 'view-fullscreen-symbolic', (button) => { renderer.toggleFullscreen(); if (renderer.fullscreen) button.image.icon_name = 'view-restore-symbolic'; else button.image.icon_name = 'view-fullscreen-symbolic'; }); } 07070100000084000041ED000000000000000000000002660EE2C800000000000000000000000000000000000000000000001400000000sushi-46.0/src/util07070100000085000081A4000000000000000000000001660EE2C80000041B000000000000000000000000000000000000002100000000sushi-46.0/src/util/constants.js/* * Copyright (C) 2011 Red Hat, Inc. * * 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 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. * * The Sushi project hereby grant permission for non-gpl compatible GStreamer * plugins to be used and distributed together with GStreamer and Sushi. This * permission is above and beyond the permissions granted by the GPL license * Sushi is covered by. * * Authors: Cosimo Cecchi <cosimoc@redhat.com> * */ var VIEW_MIN = 400; var TOOLBAR_SPACING = 32; 07070100000086000081A4000000000000000000000001660EE2C8000009E4000000000000000000000000000000000000002600000000sushi-46.0/src/util/totemMimeTypes.js/* generated with mime-type-imports.sh in the totem module, don't edit or commit in the sushi module without filing a bug against totem */ var audioTypes = [ "audio/3gpp", "audio/ac3", "audio/AMR", "audio/AMR-WB", "audio/basic", "audio/flac", "audio/midi", "audio/mp2", "audio/mp4", "audio/mpeg", "audio/ogg", "audio/prs.sid", "audio/vnd.rn-realaudio", "audio/x-aiff", "audio/x-ape", "audio/x-flac", "audio/x-gsm", "audio/x-it", "audio/x-m4a", "audio/x-matroska", "audio/x-mod", "audio/x-mp3", "audio/x-mpeg", "audio/x-ms-asf", "audio/x-ms-asx", "audio/x-ms-wax", "audio/x-ms-wma", "audio/x-musepack", "audio/x-pn-aiff", "audio/x-pn-au", "audio/x-pn-wav", "audio/x-pn-windows-acm", "audio/x-realaudio", "audio/x-real-audio", "audio/x-s3m", "audio/x-sbc", "audio/x-speex", "audio/x-stm", "audio/x-tta", "audio/x-wav", "audio/x-wavpack", "audio/x-vorbis", "audio/x-vorbis+ogg", "audio/x-xm", "application/x-flac", ]; var videoTypes = [ "application/mxf", "application/ogg", "application/ram", "application/sdp", "application/vnd.apple.mpegurl", "application/vnd.ms-wpl", "application/vnd.rn-realmedia", "application/x-extension-m4a", "application/x-extension-mp4", "application/x-flash-video", "application/x-matroska", "application/x-netshow-channel", "application/x-ogg", "application/x-quicktimeplayer", "application/x-shorten", "image/vnd.rn-realpix", "image/x-pict", "misc/ultravox", "text/x-google-video-pointer", "video/3gp", "video/3gpp", "video/dv", "video/divx", "video/fli", "video/flv", "video/mp2t", "video/mp4", "video/mp4v-es", "video/mpeg", "video/msvideo", "video/ogg", "video/quicktime", "video/vivo", "video/vnd.divx", "video/vnd.mpegurl", "video/vnd.rn-realvideo", "video/vnd.vivo", "video/webm", "video/x-anim", "video/x-avi", "video/x-flc", "video/x-fli", "video/x-flic", "video/x-flv", "video/x-m4v", "video/x-matroska", "video/x-mpeg", "video/x-mpeg2", "video/x-ms-asf", "video/x-ms-asx", "video/x-msvideo", "video/x-ms-wm", "video/x-ms-wmv", "video/x-ms-wmx", "video/x-ms-wvx", "video/x-nsv", "video/x-ogm+ogg", "video/x-theora+ogg", "video/x-totem-stream", "audio/x-pn-realaudio", ]; 07070100000087000041ED000000000000000000000002660EE2C800000000000000000000000000000000000000000000001700000000sushi-46.0/src/viewers07070100000088000081A4000000000000000000000001660EE2C800003746000000000000000000000000000000000000002000000000sushi-46.0/src/viewers/audio.js/* * Copyright (C) 2011 Red Hat, Inc. * * 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 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. * * The Sushi project hereby grant permission for non-gpl compatible GStreamer * plugins to be used and distributed together with GStreamer and Sushi. This * permission is above and beyond the permissions granted by the GPL license * Sushi is covered by. * * Authors: Cosimo Cecchi <cosimoc@redhat.com> * */ const {Gdk, GdkPixbuf, Gio, GLib, GObject, Gst, GstTag, Gtk, Soup, Sushi} = imports.gi; const Constants = imports.util.constants; const Renderer = imports.ui.renderer; const TotemMimeTypes = imports.util.totemMimeTypes; function _formatTimeString(timeVal) { let hours = Math.floor(timeVal / 3600); timeVal -= hours * 3600; let minutes = Math.floor(timeVal / 60); timeVal -= minutes * 60; let seconds = Math.floor(timeVal); let str = ('%02d:%02d').format(minutes, seconds); if (hours > 0) { str = ('%d').format(hours) + ':' + str; } return str; } const COVER_ART_ARCHIVE_URL = "https://coverartarchive.org/release/%s"; const MUSIC_BRAINZ_ASIN_FORMAT = "https://musicbrainz.org/ws/2/release/?query=release:\"%s\"AND artist:\"%s\"&limit=1&fmt=json"; const fetchCoverArt = function(_tagList, _cancellable, _callback) { function _fetchFromTags() { let coverSample = null; let idx = 0; while (true) { let [res, sample] = _tagList.get_sample_index(Gst.TAG_IMAGE, idx); if (!res) break; idx++; let caps = sample.get_caps(); let capsStruct = caps.get_structure(0); let [r, type] = capsStruct.get_enum('image-type', GstTag.TagImageType.$gtype); if (type == GstTag.TagImageType.UNDEFINED) { coverSample = sample; } else if (type == GstTag.TagImageType.FRONT_COVER) { coverSample = sample; break; } } // Fallback to preview if (!coverSample) coverSample = _tagList.get_sample_index(Gst.TAG_PREVIEW_IMAGE, 0)[1]; if (coverSample) { try { return Sushi.pixbuf_from_gst_sample(coverSample) } catch (e) { logError(e, 'Unable to fetch cover art from GstSample'); } } return null; } function _getCacheFile(mbid) { let cachePath = GLib.build_filenamev([GLib.get_user_cache_dir(), 'sushi']); return Gio.File.new_for_path(GLib.build_filenamev([cachePath, `${mbid}.jpg`])); } function _fetchFromStream(stream, done) { GdkPixbuf.Pixbuf.new_from_stream_async(stream, _cancellable, (o, res) => { let cover; try { cover = GdkPixbuf.Pixbuf.new_from_stream_finish(res); } catch (e) { done(e, null); return; } done(null, cover); }); } function _fetchFromCache(mbid, done) { let file = _getCacheFile(mbid); file.query_info_async(Gio.FILE_ATTRIBUTE_STANDARD_TYPE, 0, 0, _cancellable, (f, res) => { try { file.query_info_finish(res); } catch (e) { done(e, null); return; } file.read_async(0, _cancellable, (f, res) => { let stream; try { stream = file.read_finish(res); } catch (e) { done(e, null); return; } _fetchFromStream(stream, done); }); }); } function _saveToCache(mbid, stream, done) { let cacheFile = _getCacheFile(mbid); let cachePath = cacheFile.get_parent().get_path(); GLib.mkdir_with_parents(cachePath, 448); cacheFile.replace_async(null, false, Gio.FileCreateFlags.PRIVATE, 0, _cancellable, (f, res) => { let outStream; try { outStream = cacheFile.replace_finish(res); } catch (e) { done(e); return; } outStream.splice_async( stream, Gio.OutputStreamSpliceFlags.CLOSE_SOURCE | Gio.OutputStreamSpliceFlags.CLOSE_TARGET, 0, _cancellable, (s, res) => { try { outStream.splice_finish(res); } catch (e) { done(e); return; } done(); }); }); } function decode(buffer) { let decoder = new TextDecoder('utf8'); return decoder.decode(buffer); } function _fetchCoverArtArchiveImage(uri, mbid, done) { let session = new Soup.Session(); let message = Soup.Message.new('GET', uri); message.request_headers.append('User-Agent', 'gnome-sushi'); session.send_async(message, 0, _cancellable, (r, res) => { let stream; try { stream = session.send_finish(res); } catch (e) { done(e, null); return; } _saveToCache(mbid, stream, (err) => { if (err) logError(err, 'Unable to save cover to cache'); _fetchFromCache(mbid, done); }); }); } function _fetchCoverArtArchiveMetadata(mbid, done) { let uri = COVER_ART_ARCHIVE_URL.format(mbid); let session = new Soup.Session(); let message = Soup.Message.new('GET', uri); message.request_headers.append('User-Agent', 'gnome-sushi'); session.send_and_read_async(message, 0, _cancellable, (r, res) => { try { let data = decode(session.send_and_read_finish(res).get_data()); if (message.get_status() !== Soup.Status.OK) return; let json_data = JSON.parse (data); let uri = json_data['images'][0]['thumbnails']['small']; _fetchCoverArtArchiveImage(uri, mbid, done); return; } catch (e) { done(e, null); } }); } function _fetchFromMusicBrainz(done) { let artist = _tagList.get_string('artist')[1]; let album = _tagList.get_string('album')[1]; let uri = MUSIC_BRAINZ_ASIN_FORMAT.format(album, artist); let session = new Soup.Session(); let message = Soup.Message.new('GET', uri); message.request_headers.append('User-Agent', 'gnome-sushi'); session.send_and_read_async(message, 0, _cancellable, (r, res) => { let mbid = null; try { let data = decode(session.send_and_read_finish(res).get_data()); if (message.get_status() !== Soup.Status.OK) return; let json_response = JSON.parse(data); if (!('releases' in json_response) || json_response['releases'].length === 0) return; mbid = json_response['releases'][0]['id']; } catch (e) { done (e, null); return; } _fetchFromCache(mbid, (err, cover) => { if (cover) done(null, cover); else _fetchCoverArtArchiveMetadata(mbid, done); }); }); } let cover = _fetchFromTags(); if (cover) { _callback(null, cover); return; } _fetchFromMusicBrainz(_callback); } const AudioPlayer = GObject.registerClass({ CssName: 'toolbar', }, class AudioPlayer extends Sushi.MediaBin { _init(file) { super._init({ audio_mode: true, uri: file.get_uri(), margin_bottom: Constants.TOOLBAR_SPACING, margin_start: Constants.TOOLBAR_SPACING, margin_end: Constants.TOOLBAR_SPACING, valign: Gtk.Align.END }); this.get_style_context().add_class('osd'); } }); const COVER_SIZE = 256; var Klass = GObject.registerClass({ Implements: [Renderer.Renderer], Properties: { fullscreen: GObject.ParamSpec.boolean('fullscreen', '', '', GObject.ParamFlags.READABLE, false), ready: GObject.ParamSpec.boolean('ready', '', '', GObject.ParamFlags.READABLE, false) }, }, class AudioRenderer extends Gtk.Overlay { get ready() { return !!this._ready; } get fullscreen() { return !!this._fullscreen; } _init(file) { super._init(); this._coverFetched = false; let box = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL, spacing: 6 }); this.add(box); this._player = new AudioPlayer(file); this._player.connect('tags-change', (p) => { this._updateFromTags(this._player.get_audio_tags()); }); this._player.connect('error', (p, error) => { this.emit('error', error); return false; }); this.add_overlay(this._player); this._autoplayId = GLib.idle_add(0, () => { this._autoplayId = 0; this._player.play(); return false; }); let frame = new Gtk.Frame({ height_request: COVER_SIZE, width_request: COVER_SIZE, shadow_type: Gtk.ShadowType.NONE }); box.pack_start(frame, false, false, 0); this._image = new Gtk.Image({ icon_name: 'media-optical-symbolic', pixel_size: COVER_SIZE }); frame.add(this._image); let vbox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL, spacing: 1, margin_top: 48, margin_start: 12, margin_end: 12 }); box.pack_start(vbox, false, false, 0); this._titleLabel = new Gtk.Label(); this._titleLabel.set_halign(Gtk.Align.START); vbox.pack_start(this._titleLabel, false, false, 0); this._authorLabel = new Gtk.Label(); this._authorLabel.set_halign(Gtk.Align.START); vbox.pack_start(this._authorLabel, false, false, 0); this._albumLabel = new Gtk.Label(); this._albumLabel.set_halign(Gtk.Align.START); vbox.pack_start(this._albumLabel, false, false, 0); this.connect('destroy', this._onDestroy.bind(this)); this._cancellable = new Gio.Cancellable(); this.isReady(); } _onDestroy() { if (this._autoplayId > 0) { GLib.source_remove(this._autoplayId); this._autoplayId = 0; } this._cancellable.cancel(); } _setCover(cover) { let scaleFactor = this.get_scale_factor(); let size = COVER_SIZE * scaleFactor; let width = cover.get_width(); let height = cover.get_height(); let targetWidth = size; let targetHeight = size; if (width > height) targetHeight = height * size / width; else targetWidth = width * size / height; let coverArt = cover.scale_simple(targetWidth, targetHeight, GdkPixbuf.InterpType.BILINEAR); let surface = Gdk.cairo_surface_create_from_pixbuf(coverArt, scaleFactor, this.get_window()); this._image.set_from_surface(surface); } _onCoverArtFetched(err, cover) { if (err) { if (!err.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND) && !err.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) logError(err, 'Unable to fetch cover art'); return; } this._setCover(cover); } _updateFromTags(tags) { let albumName = tags.get_string('album')[1]; let artistName = tags.get_string('artist')[1]; let titleName = tags.get_string('title')[1]; if (!titleName) { let file = Gio.file_new_for_uri(this._player.uri); titleName = file.get_basename(); } if (albumName) { let escaped = GLib.markup_escape_text(albumName, -1); this._albumLabel.set_markup('<small><i>' + _("from") + ' </i>' + escaped + '</small>'); } if (artistName) { let escaped = GLib.markup_escape_text(artistName, -1); this._authorLabel.set_markup('<small><i>' + _("by") + ' </i><b>' + escaped + '</b></small>'); } let escaped = GLib.markup_escape_text(titleName, -1); this._titleLabel.set_markup('<b>' + escaped + '</b>'); if (artistName && albumName && !this._coverFetched) { fetchCoverArt(tags, this._cancellable, this._onCoverArtFetched.bind(this)); this._coverFetched = true; } } get hasToolbar() { // SushiMediaBin uses its own toolbar return false; } get resizable() { return false; } get resizePolicy() { return Renderer.ResizePolicy.NAT_SIZE; } }); var mimeTypes = TotemMimeTypes.audioTypes; 07070100000089000081A4000000000000000000000001660EE2C80000165B000000000000000000000000000000000000002100000000sushi-46.0/src/viewers/evince.js/* * Copyright (C) 2011 Red Hat, Inc. * * 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 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. * * The Sushi project hereby grant permission for non-gpl compatible GStreamer * plugins to be used and distributed together with GStreamer and Sushi. This * permission is above and beyond the permissions granted by the GPL license * Sushi is covered by. * * Authors: Cosimo Cecchi <cosimoc@redhat.com> * */ const {EvinceDocument, EvinceView, Gio, GObject, Gtk, Sushi} = imports.gi; const Constants = imports.util.constants; const Renderer = imports.ui.renderer; const Utils = imports.ui.utils; const Libreoffice = imports.viewers.libreoffice; var Klass = GObject.registerClass({ Implements: [Renderer.Renderer], Properties: { fullscreen: GObject.ParamSpec.boolean('fullscreen', '', '', GObject.ParamFlags.READABLE, false), ready: GObject.ParamSpec.boolean('ready', '', '', GObject.ParamFlags.READABLE, false) }, }, class EvinceRenderer extends Gtk.ScrolledWindow { get ready() { return !!this._ready; } get fullscreen() { return !!this._fullscreen; } _init(file, fileInfo) { super._init({ visible: true, min_content_height: Constants.VIEW_MIN, min_content_width: Constants.VIEW_MIN }); if (evinceTypes.includes(fileInfo.get_content_type())) { this._loadFile(file); } else { Sushi.convert_libreoffice(file, (o, res) => { let convertedFile; try { convertedFile = Sushi.convert_libreoffice_finish(res); } catch (e) { this.emit('error', e); return; } this._loadFile(convertedFile); }); } this._defineActions(); this._view = EvinceView.View.new(); this._view.show(); this.add(this._view); this.connect('destroy', this._onDestroy.bind(this)); this.isReady(); } _onDestroy() { if(this._job) this._job.disconnect(this._jobHandlerId); if(this._model) this._model.disconnect(this._modelHandlerId); } _loadFile(file) { if (file.has_uri_scheme("file")) { this._job = EvinceView.JobLoad.new(file.get_uri()); } else { this._job = EvinceView.JobLoadGFile.new( file, EvinceDocument.DocumentLoadFlags.NONE); } this._jobHandlerId = this._job.connect('finished', this._onLoadJobFinished.bind(this)); this._job.scheduler_push_job(EvinceView.JobPriority.PRIORITY_NONE); } _updatePageLabel() { let curPage = this._model.get_page(); let totPages = this._model.document.get_n_pages(); this._toolbarBack.set_sensitive(curPage > 0); this._toolbarForward.set_sensitive(curPage < totPages - 1); this._pageLabel.set_text(_("%d of %d").format(curPage + 1, totPages)); } _onLoadJobFinished(job) { let document; try { document = Sushi.get_evince_document_from_job(job); } catch (e) { this.emit('error', e); return; } this._model = EvinceView.DocumentModel.new_with_document(document); this._model.set_sizing_mode(EvinceView.SizingMode.FIT_WIDTH); this._model.set_continuous(true); this._modelHandlerId = this._model.connect('page-changed', this._updatePageLabel.bind(this)); this._updatePageLabel(); this._view.set_model(this._model); } _defineActions() { let application = Gio.Application.get_default (); let copyAction = new Gio.SimpleAction({ name: 'copy' }); copyAction.connect ('activate', () => { this._view.copy(); }); application.set_accels_for_action ('evince.copy', ['<control>c']); let actionGroup = new Gio.SimpleActionGroup(); actionGroup.add_action(copyAction); this.insert_action_group ('evince', actionGroup); } get moveOnClick() { return false; } populateToolbar(toolbar) { this._toolbarBack = Utils.createToolButton(this, 'go-previous-symbolic', () => { this._view.previous_page(); }); toolbar.add(this._toolbarBack); this._pageLabel = new Gtk.Label({ hexpand: true, margin_start: 10, margin_end: 10 }); toolbar.add(this._pageLabel); this._toolbarForward = Utils.createToolButton(this, 'go-next-symbolic', () => { this._view.next_page(); }); toolbar.add(this._toolbarForward); } }); EvinceDocument.init(); var evinceTypes = Sushi.query_supported_document_types(); var mimeTypes = evinceTypes; if (!Libreoffice.isAvailable()) mimeTypes = mimeTypes.concat(Libreoffice.officeTypes); 0707010000008A000081A4000000000000000000000001660EE2C8000007DB000000000000000000000000000000000000001F00000000sushi-46.0/src/viewers/font.js/* * Copyright (C) 2011 Red Hat, Inc. * * 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 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. * * The Sushi project hereby grant permission for non-gpl compatible GStreamer * plugins to be used and distributed together with GStreamer and Sushi. This * permission is above and beyond the permissions granted by the GPL license * Sushi is covered by. * * Authors: Cosimo Cecchi <cosimoc@redhat.com> * */ const {GLib, GObject, Gtk, Sushi} = imports.gi; const Renderer = imports.ui.renderer; var Klass = GObject.registerClass({ Implements: [Renderer.Renderer], Properties: { fullscreen: GObject.ParamSpec.boolean('fullscreen', '', '', GObject.ParamFlags.READABLE, false), ready: GObject.ParamSpec.boolean('ready', '', '', GObject.ParamFlags.READABLE, false) }, }, class FontRenderer extends Sushi.FontWidget { get ready() { return !!this._ready; } get fullscreen() { return !!this._fullscreen; } _init(file) { super._init({ uri: file.get_uri(), visible: true }) this.isReady(); } }); var mimeTypes = [ 'application/x-font-ttf', 'application/x-font-otf', 'application/x-font-pcf', 'application/x-font-type1' ]; 0707010000008B000081A4000000000000000000000001660EE2C800000A38000000000000000000000000000000000000001E00000000sushi-46.0/src/viewers/gst.js/* * Copyright (C) 2011 Red Hat, Inc. * * 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 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. * * The Sushi project hereby grant permission for non-gpl compatible GStreamer * plugins to be used and distributed together with GStreamer and Sushi. This * permission is above and beyond the permissions granted by the GPL license * Sushi is covered by. * * Authors: Cosimo Cecchi <cosimoc@redhat.com> * */ const {GLib, GObject, Sushi} = imports.gi; const Renderer = imports.ui.renderer; const TotemMimeTypes = imports.util.totemMimeTypes; var Klass = GObject.registerClass({ Implements: [Renderer.Renderer], Properties: { fullscreen: GObject.ParamSpec.boolean('fullscreen', '', '', GObject.ParamFlags.READABLE, false), ready: GObject.ParamSpec.boolean('ready', '', '', GObject.ParamFlags.READABLE, false) }, }, class GstRenderer extends Sushi.MediaBin { get ready() { return !!this._ready; } get fullscreen() { return !!this._fullscreen; } _init(file) { super._init({ uri: file.get_uri() }); this._autoplayId = GLib.idle_add(0, () => { this._autoplayId = 0; this.play(); return false; }); this.connect('destroy', this._onDestroy.bind(this)); this.connect('size-change', this.isReady.bind(this)); } _onDestroy() { if (this._autoplayId > 0) { GLib.source_remove(this._autoplayId); this._autoplayId = 0; } } get canFullscreen() { // fullscreen is handled internally by the widget return false; } get hasToolbar() { // SushiMediaBin uses its own toolbar return false; } get resizePolicy() { return Renderer.ResizePolicy.STRETCHED; } }); var mimeTypes = TotemMimeTypes.videoTypes; 0707010000008C000081A4000000000000000000000001660EE2C8000009F4000000000000000000000000000000000000001F00000000sushi-46.0/src/viewers/html.js/* * Copyright (C) 2011 Red Hat, Inc. * * 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 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. * * The Sushi project hereby grant permission for non-gpl compatible GStreamer * plugins to be used and distributed together with GStreamer and Sushi. This * permission is above and beyond the permissions granted by the GPL license * Sushi is covered by. * * Authors: Cosimo Cecchi <cosimoc@redhat.com> * */ const {Gtk, GLib, GObject, Sushi} = imports.gi; var WebKit2; try { imports.gi.versions.WebKit2 = '4.1'; WebKit2 = imports.gi.WebKit2; } catch(e) { } function _isAvailable() { return WebKit2 !== undefined; } const Renderer = imports.ui.renderer; var Klass = _isAvailable() ? GObject.registerClass({ Implements: [Renderer.Renderer], Properties: { fullscreen: GObject.ParamSpec.boolean('fullscreen', '', '', GObject.ParamFlags.READABLE, false), ready: GObject.ParamSpec.boolean('ready', '', '', GObject.ParamFlags.READABLE, false) }, }, class HTMLRenderer extends WebKit2.WebView { get ready() { return !!this._ready; } get fullscreen() { return !!this._fullscreen; } _init(file) { super._init(); /* disable the default context menu of the web view */ this.connect('context-menu', function() {return true;}); this.load_uri(file.get_uri()); this.connect('load-failed', (view, loadEvent, uri, error) => { this.emit('error', error); }); this.isReady(); } static { WebKit2.WebContext.get_default().set_sandbox_enabled(true); } get moveOnClick() { return false; } }) : undefined; var mimeTypes = []; if (_isAvailable()) mimeTypes = [ 'text/html' ]; 0707010000008D000081A4000000000000000000000001660EE2C8000019D6000000000000000000000000000000000000002000000000sushi-46.0/src/viewers/image.js/* * Copyright (C) 2011 Red Hat, Inc. * * 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 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. * * The Sushi project hereby grant permission for non-gpl compatible GStreamer * plugins to be used and distributed together with GStreamer and Sushi. This * permission is above and beyond the permissions granted by the GPL license * Sushi is covered by. * * Authors: Cosimo Cecchi <cosimoc@redhat.com> * */ const {Gdk, GdkPixbuf, Gio, GLib, GObject, Gtk} = imports.gi; const Renderer = imports.ui.renderer; var Klass = GObject.registerClass({ Implements: [Renderer.Renderer], Properties: { fullscreen: GObject.ParamSpec.boolean('fullscreen', '', '', GObject.ParamFlags.READABLE, false), ready: GObject.ParamSpec.boolean('ready', '', '', GObject.ParamFlags.READABLE, false) }, }, class ImageRenderer extends Gtk.DrawingArea { get ready() { return !!this._ready; } get fullscreen() { return !!this._fullscreen; } _init(file) { super._init(); this._cancellable = new Gio.Cancellable(); this._pix = null; this._scaledSurface = null; this._timeoutId = 0; this._createImageTexture(file); this.connect('destroy', this._onDestroy.bind(this)); } vfunc_get_preferred_width() { return [1, this._pix ? this._pix.get_width() : 1]; } vfunc_get_preferred_height() { return [1, this._pix ? this._pix.get_height() : 1]; } vfunc_size_allocate(allocation) { super.vfunc_size_allocate(allocation); this._ensureScaledPix(); } vfunc_draw(context) { if (!this._scaledSurface) return false; let width = this.get_allocated_width(); let height = this.get_allocated_height(); let scaleFactor = this.get_scale_factor(); let offsetX = (width - this._scaledSurface.getWidth() / scaleFactor) / 2; let offsetY = (height - this._scaledSurface.getHeight() / scaleFactor) / 2; context.setSourceSurface(this._scaledSurface, offsetX, offsetY); context.paint(); return false; } _createImageTexture(file) { file.read_async(GLib.PRIORITY_DEFAULT, this._cancellable, (obj, res) => { try { let stream = obj.read_finish(res); this._textureFromStream(stream); } catch (e) { this.emit('error', e); } }); } _ensureScaledPix() { if (!this._pix) return; let scaleFactor = this.get_scale_factor(); let width = this.get_allocated_width() * scaleFactor; let height = this.get_allocated_height() * scaleFactor; // Scale original to fit, if necessary let origWidth = this._pix.get_width(); let origHeight = this._pix.get_height(); let scaleX = width / origWidth; let scaleY = height / origHeight; let scale = Math.min(scaleX, scaleY); // Do not upscale unless we're fullscreen if (!this.fullscreen) scale = Math.min(scale, 1.0 * scaleFactor); let newWidth = Math.floor(origWidth * scale); let newHeight = Math.floor(origHeight * scale); let scaledWidth = this._scaledSurface ? this._scaledSurface.getWidth() : 0; let scaledHeight = this._scaledSurface ? this._scaledSurface.getHeight() : 0; if (newWidth == scaledWidth && newHeight == scaledHeight) return; // Avoid blur if we're upscaling a lot, e.g. when fullscreening // a small image. We use nearest neighbor interpolation for that case. let interpType = GdkPixbuf.InterpType.BILINEAR; if (scale >= 3.0 * scaleFactor) interpType = GdkPixbuf.InterpType.NEAREST; let scaledPixbuf = this._pix.scale_simple(newWidth, newHeight, interpType); this._scaledSurface = Gdk.cairo_surface_create_from_pixbuf(scaledPixbuf, scaleFactor, this.get_window()); } _setPix(pix) { this._pix = pix; this._scaledSurface = null; this.queue_resize(); this.isReady(); } _textureFromStream(stream) { GdkPixbuf.PixbufAnimation.new_from_stream_async(stream, this._cancellable, (obj, res) => { let anim; try { anim = GdkPixbuf.PixbufAnimation.new_from_stream_finish(res); } catch (e) { this.emit('error', e); return; } this._iter = anim.get_iter(null); this._update(); stream.close_async(GLib.PRIORITY_DEFAULT, this._cancellable, (obj, res) => { try { obj.close_finish(res); } catch (e) { logError(e, 'Unable to close the stream'); } }); }); } _update() { this._setPix(this._iter.get_pixbuf().apply_embedded_orientation()); let delay = this._iter.get_delay_time(); if (delay == -1) return; this._timeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, delay, () => { this._timeoutId = 0; if (this._iter.advance(null)) this._update(); return false; }); } get resizePolicy() { return Renderer.ResizePolicy.SCALED; } _onDestroy() { if (this._timeoutId) { GLib.source_remove(this._timeoutId); this._timeoutId = 0; } this._cancellable.cancel(); } }); var mimeTypes = []; let formats = GdkPixbuf.Pixbuf.get_formats(); for (let idx in formats) mimeTypes = mimeTypes.concat(formats[idx].get_mime_types()); 0707010000008E000081A4000000000000000000000001660EE2C800000E19000000000000000000000000000000000000002600000000sushi-46.0/src/viewers/libreoffice.jsconst {GLib, GObject, Gtk} = imports.gi; var LOKDocView; try { LOKDocView = imports.gi.LOKDocView; } catch(e) { } var isAvailable = function() { return LOKDocView !== undefined; }; const Constants = imports.util.constants; const Renderer = imports.ui.renderer; var Klass = GObject.registerClass({ Implements: [Renderer.Renderer], Properties: { fullscreen: GObject.ParamSpec.boolean('fullscreen', '', '', GObject.ParamFlags.READABLE, false), ready: GObject.ParamSpec.boolean('ready', '', '', GObject.ParamFlags.READABLE, false) }, }, class LibreofficeRenderer extends Gtk.ScrolledWindow { get ready() { return !!this._ready; } get fullscreen() { return !!this._fullscreen; } _init(file) { super._init({ hexpand: true, visible: true, min_content_height: Constants.VIEW_MIN, min_content_width: Constants.VIEW_MIN }); this._lastAllocWidth = 0; this._tickCallbackId = 0; this._view = LOKDocView.View.new(null, null); this._view.set_edit(false); this._view.show(); this.add(this._view); this._view.open_document(file.get_uri(), '{}', null, null); this.isReady(); } vfunc_size_allocate(allocation) { super.vfunc_size_allocate(allocation); if (this._view.width_request == -1) return; if (this._tickCallbackId != 0) this.remove_tick_callback(this._tickCallbackId); this._tickCallbackId = this.add_tick_callback(this._resizeView.bind(this)); } _resizeView() { this._tickCallbackId = 0; let allocWidth = this.get_allocated_width(); if (this._lastAllocWidth == allocWidth) return; // Match the Evince renderer behavior and resize the document upon // receiving a new allocation. // We rely on the fact that LOKDocView always sets its size using // gtk_widget_set_size_request(), so we can know how much it will // scale to after we set a new zoom level. let zoomLevel = this._view.zoom_level; if (this._view.width_request < allocWidth) { while ((this._view.width_request < allocWidth) && this._view.can_zoom_in) { zoomLevel = this._view.zoom_level; this._view.zoom_level += 0.1; } } else if (this._view.width_request > allocWidth) { while ((this._view.width_request >= allocWidth) && this._view.can_zoom_out) { this._view.zoom_level -= 0.1; zoomLevel = this._view.zoom_level; } } this._view.zoom_level = zoomLevel; this._lastAllocWidth = allocWidth; } get moveOnClick() { return false; } }); var officeTypes = [ 'application/vnd.oasis.opendocument.text', 'application/vnd.oasis.opendocument.presentation', 'application/vnd.oasis.opendocument.spreadsheet', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/msword', 'application/vnd.ms-excel', 'application/vnd.ms-powerpoint', 'application/rtf' ]; var mimeTypes = []; if (isAvailable()) mimeTypes = officeTypes; 0707010000008F000081A4000000000000000000000001660EE2C800000F43000000000000000000000000000000000000001F00000000sushi-46.0/src/viewers/text.js/* * Copyright (C) 2011 Red Hat, Inc. * * 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 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. * * The Sushi project hereby grant permission for non-gpl compatible GStreamer * plugins to be used and distributed together with GStreamer and Sushi. This * permission is above and beyond the permissions granted by the GPL license * Sushi is covered by. * * Authors: Cosimo Cecchi <cosimoc@redhat.com> * */ const {Gdk, Gio, GLib, GObject, Gtk, GtkSource} = imports.gi; const Renderer = imports.ui.renderer; var Klass = GObject.registerClass({ Implements: [Renderer.Renderer], Properties: { fullscreen: GObject.ParamSpec.boolean('fullscreen', '', '', GObject.ParamFlags.READABLE, false), ready: GObject.ParamSpec.boolean('ready', '', '', GObject.ParamFlags.READABLE, false) }, }, class TextRenderer extends Gtk.ScrolledWindow { get ready() { return !!this._ready; } get fullscreen() { return !!this._fullscreen; } _init(file, fileInfo) { super._init(); this._cancellable = new Gio.Cancellable(); let buffer = this._createBuffer(file, fileInfo); this._view = new GtkSource.View({ buffer: buffer, editable: false, cursor_visible: false, monospace: true, show_line_numbers: !!buffer.language }); this.add(this._view); this.isReady(); this.connect('destroy', this._onDestroy.bind(this)); } _onDestroy() { this._cancellable.cancel(); } _createBuffer(file, fileInfo) { let buffer = new GtkSource.Buffer(); let styleManager = GtkSource.StyleSchemeManager.get_default(); let stylePath = GLib.build_filenamev([pkg.pkgdatadir, 'gtksourceview-4', 'styles']); styleManager.prepend_search_path(stylePath); let scheme = styleManager.get_scheme('builder-dark'); buffer.set_style_scheme(scheme); let langManager = GtkSource.LanguageManager.get_default(); let language = langManager.guess_language(file.get_basename(), fileInfo.get_content_type()); if (language) buffer.set_language(language); let sourceFile = new GtkSource.File({ location: file }); let loader = new GtkSource.FileLoader({ buffer: buffer, file: sourceFile }); loader.load_async(0, this._cancellable, null, (loader, result) => { try { loader.load_finish(result); } catch (e) { if(!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) this.emit('error', e); } }); return buffer; } get moveOnClick() { return false; } }); // register for text/plain and let the mime handler call us for child types var mimeTypes = [ 'text/plain' ]; 07070100000090000081A4000000000000000000000001660EE2C8000005DD000000000000000000000000000000000000001600000000sushi-46.0/sushi.doap<?xml version="1.0" encoding="UTF-8"?> <Project xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:foaf="http://xmlns.com/foaf/0.1/" xmlns:gnome="http://api.gnome.org/doap-extensions#" xmlns="http://usefulinc.com/ns/doap#"> <name xml:lang="en">Sushi</name> <shortdesc xml:lang="en">A quick previewer for Nautilus</shortdesc> <description>Sushi is a quick previewer for the file manager.</description> <download-page rdf:resource="http://download.gnome.org/sources/sushi/" /> <bug-database rdf:resource="https://gitlab.gnome.org/GNOME/sushi/issues/" /> <category rdf:resource="http://api.gnome.org/doap-extensions#core" /> <programming-language>JavaScript</programming-language> <programming-language>C</programming-language> <author> <foaf:Person> <foaf:name>Cosimo Cecchi</foaf:name> <foaf:mbox rdf:resource="mailto:cosimoc@gnome.org" /> <gnome:userid>cosimoc</gnome:userid> </foaf:Person> </author> <maintainer> <foaf:Person> <foaf:name>Felipe Borges</foaf:name> <foaf:mbox rdf:resource="mailto:felipeborges@gnome.org" /> <gnome:userid>felipeborges</gnome:userid> </foaf:Person> </maintainer> <maintainer> <foaf:Person> <foaf:name>Corey Berla</foaf:name> <foaf:mbox rdf:resource="mailto:coreyberla@gnome.org" /> <gnome:userid>coreyberla</gnome:userid> </foaf:Person> </maintainer> </Project> 07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!1003 blocks
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor