photofilmstrip-3.7.2/0000755000232200023220000000000013560357432015164 5ustar debalancedebalancephotofilmstrip-3.7.2/scripts/0000755000232200023220000000000013560357432016653 5ustar debalancedebalancephotofilmstrip-3.7.2/scripts/photofilmstrip-cli0000644000232200023220000000027013560357352022426 0ustar debalancedebalance#!python # -*- coding: UTF-8 -*- __copyright__ = "Copyright © 2012 Jens Göpfert" __author__ = "Jens Göpfert " from photofilmstrip.CLI import main main() photofilmstrip-3.7.2/scripts/photofilmstrip0000644000232200023220000000027013560357352021661 0ustar debalancedebalance#!python # -*- coding: UTF-8 -*- __copyright__ = "Copyright © 2012 Jens Göpfert" __author__ = "Jens Göpfert " from photofilmstrip.GUI import main main() photofilmstrip-3.7.2/LICENSE0000644000232200023220000000135013560357351016170 0ustar debalancedebalancePhotoFilmStrip is Copyright (C) 2008-2018 by Jens Göpfert 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA photofilmstrip-3.7.2/CHANGES0000644000232200023220000002537513560357351016173 0ustar debalancedebalance * 2014/10/13 (Version 2.1.0) added: - new video rendering backend python-gstreamer changed: - compatible to wxPython 3 * 2013/11/20 (Version 2.0.0) added: - thumbnails are stored in project database - lazy loading of pictures - acceleration algorithm for dynamic path movement - tool button to swap the motion rectangles - movement (linear, accelerated) can be adjusted for each picture - new option to centralize motion rectangles path for still image animation - new movement type 'delayed' - toolbutton to unlock the image dimension restrictions - multiselect of images - russian translation - greek translation changed: - long running tasks implemented as jobs - a lot of internal refactoring bugfix: - application icon not only for GNOME;XFCE (enabled for all) - MANIFEST.in updated to create valid source dist - default value for videonorm in settings file is PAL - fixed #29: film strip scrambled with >185 slides loaded - GUI freeze while loading a project - unexpected error occured when removing an image which is hovered - automatic path calculation after inserting images fixed - videonorm must be one of PAL or NTSC * 2011/11/28 (Version 1.5.0) added: - rendering uses affine transformation for speed up and smoother image movement * 2010/12/20 (Version 1.4.0) added: - italian translation bugfix: - py2exe and PIL workaround * 2010/11/12 (Version 1.3.99 BETA) changed: - internal optimizations bugfix: - a few * 2010/10/31 (Version 1.3.98 ALPHA) changed: - better audio support - simplified render settings - UI optimizations - keyboard shortcuts - settings file saved in app dir (if possible) - portable version bugfix: - working CLI - order of recently used projects fixed * 2010/07/18 (Version 1.3.97 ALPHA) added: - MJPEG-Renderer - Direct input for motion positions - Copy and paste for motion positions (keyboard only) bugfix: - minimal size of mainframe specified - property dialog could not open if no pics were added to the project - ticket id 2890912: drop position determined correctly * 2010/07/04 (Version 1.3.96 ALPHA) added: - Flash-Video Renderer - additional transition (roll) bugfix: - fixed frame count due float precision - removing audio file in project properties works - Workaround: audio/video sync (mencoder calculates strange movie length in NTSC) - progress bar has correct max progress - RemoveObserver raises ValueError: list.remove(x): x not in list - OutputProfile raises AttributeError no attribute OutputProfile.__resNtsc * 2010/06/12 (Version 1.3.95 ALPHA) added: - Transition type and duration customizable - Option for draft-mode (replaces UseResample option) - sample music files (thanks to my dad) - Portuguese translation started - Req-ID 3006759 (4:3 Support) - Req-ID 3002271 (Option for no transition) changed: - Handling of Aspect-Ratio data (internal) - menu entry to change language - aspect ratio for SVCD and DVD considered - user interface simplified - multi project capable - aspect ratio, total duration and audiofile are now saved within project bugfixes: - Bug-ID 3003534 (Subtitles out of sync) - Rendering with only 1 image does not fail anymore * 2010/03/14 (Version 1.3.5) added: - Czech translation (thanks to Tomas) * 2010/02/14 (Version 1.3.4) added: - french translation (thanks to Teza) * 2010/01/24 (Version 1.3.3) bugfixes: - select wx-version for multiple wx installations - check for mencoder - incomplete portuguese translation removed * 2009/11/10 (Version 1.3.2) bugfixes: - UnicodeEncodeError when generating subtitle (srt-file) - preparation for customizable aspect ratio * 2009/11/08 (Version 1.3.1) bugfixes: - register picture in ImageCache after browsing for a single pic - UnicodeEncodeError fixed when batch job is created - cli arg for audio duration accepts float values - HitTest for PhotoFilmStrip-list recognizes gap between pictures * 2009/11/01 (Version 1.3) changed: - pictures stored low-res in memory, hi-res is created delayed in background - automatic motion path (random) - quick start deactivated because of some keyboard issues - output format simplified - no dependency to mjpegtools anymore bugfixes: - picture selection by keyboard scroll photofilmstrip - resolution for SVCD fixed - UnicodeEncode errors - some minor bugs * 2009/09/18 (Version 1.2) changed: - quick start for importing images to a new PhotoFilmStrip bugfixes: - GUI behavior - UnicodeEncode errors - wxPython assertions - no section errors - lots of minor bugs * 2009/02/18 (Version 1.1) changed: - memory consumption optimized. PhotoFilmStrip is now ready for large projects ;-) bugfix: - unexpected error when dropping images from an external application - leaving move operation correctly when stopping DragNDrop outside the window * 2009/02/16 (Version 1.1-BETA) added: - new control for the image list (real photofilmstrip) changed: - invisible parts of the images are a kind of grayed out bugfix: - a lot of bugfixes sent by the bug-report feature (many thanks to all users) * 2008/12/03 (Version 1.0) added: - new mouse cursors for resizing the sections changed: - program description and properties moved to Setting module - DummyPicture implementation optimized bugfix: - unexpected error (cannot identify image) - select/deselect of images in list works properly - mouse capturing (mainly for windows) - position of thumbnails in imagelist is working properly under windows too - settings file is saved in temp folder if no environment variable HOME is set under windows * 2008/11/27 added: - information about selected rectange are shown changed: - core runs without wxPython ->CLI can be used without X-Server - bugreport sends platform infos - Resizing Borders has landed, Corners are next target bugfix: - mutual vowels in pathnames - pictures in portrait-format are processed properly - effects with PIL - progress bar more precisely * 2008/11/22 added: - windows release works properly - help system - creation of batch jobs - Export and Import feature for Projects implemented - display renderers whose dependencies are fulfilled, missing dependencies are shown in RendererChoice - bug report error dialog added - renderer checks for his dependencies changed: - PIL used instead of imagemagick, rendering works completely in RAM now - Icon for dummy pictures - image size is saved in project file - handling of section editing improved - py2exe build script optimized - GUI optimizations bugfix: - PyData works correctly - minor bugfixes * 2008/11/04 added: - Makefile (make deb) prepares everything for dpkg-buildpackage - py2exe build script changed: - GUI optimizations * 2008/11/04 added: - audio file support in CLI (CLI cannot determine length of audio yet) - audio file is processed in MPEG2Renderer now - new CLI option for total length of photofilmstrip - question dialog for selection of an alternative folder in case image files has moved - Renderer gets audiofile name to mux into video stream - MPEG4 Renderer process audio file - ResampleFilter editable via property - audio file is supported now (CLI cannot determine length of audio yet) - total length adjustable in dialog - specified total length applied when rendering a filmstrip - drag and drop accepts images and project files - GUI opens project from command line argument changed: - logfiles of mpeg2enc renamed - yuvscaler in MPEG2Renderer not needed anymore - exitcode are evaluated in calls of other command line tools - Internationalization bugfix: - abortion of rendering works correctly - VCD and SVCD arguments in mpeg2enc fixed - CLI uses stored bitrate property from ini file if given, otherwise the default bitrate from profile definition - quoted file paths in calls of other command line tools - compatibility with MS Windows - determination of length of an audio clip works under windows - command line tools (ppmtoy4m, mencoder) sends output to logfiles, because pipe buffer is limited - aborting processed correctly * 2008/10/31 added: - subtitles are generated now - MovieRenderer splitted up into Renderer for MPEG2 and MPEG4 - method factory in renderers to process abort signal - each renderer gets his own value dictionary and it is saved in ini file - output profiles in settings module configurable - MPEG4 output for HD movies changed: - RenderEngine implements render logic - Renderer classes only process instructions from RenderEnging - using pipes to feed the mpegencoder - mencoder reads data from pipe; no yuv file needed anymore - Renderer dynamically loaded into render dialog bugfix: - progressbar improved - typo - CLI works again - renderer properties saved correctly - encoded output for VCD, SVCD and DVD corrected * 2008/10/22 added: - command line interface bugfix: - wrong parameter for mpegencoder * 2008/10/20 added: - effect parameter in renderer added - black and white effect works - dummy pictured inserted for pictures that do not exist anymore - effect, comment alignment are saved in project now - database field for image date prepared - picture object marked changes if there are really changes changed: - parameters for mpegencoder changed for better quality bugfix: - image resource file supports deprecated methods of older wxPython Versions * 2008/10/17 added: - subimage counter for progressbar - new shellscript renderer - resample option for MPEG-renderer to improve quality - image sections can now edited with cursor keys changed: - default duration for pictures is now 7 seconds - filedialogs reminds last selection - resource file for images is now compatible with older wxPython version bugfix: - framerate and imagemode are correctly sent to encoder - encoding for german po-file fixed - statusbar update when starting new project * 2008/10/11 initial release photofilmstrip-3.7.2/PKG-INFO0000644000232200023220000000075413560357432016267 0ustar debalancedebalanceMetadata-Version: 1.0 Name: photofilmstrip Version: 3.7.2 Summary: PhotoFilmStrip - Creates movies out of your pictures. Home-page: http://www.photofilmstrip.org Author: Jens Göpfert Author-email: info@photofilmstrip.org License: GPLv2 Description: PhotoFilmStrip creates movies out of your pictures in just 3 steps. First select your photos, customize the motion path and render the video. There are several output possibilities for VCD, SVCD, DVD up to FULL-HD. Platform: UNKNOWN photofilmstrip-3.7.2/MANIFEST.in0000644000232200023220000000037013560357351016722 0ustar debalancedebalancerecursive-include data * recursive-include po * recursive-include docs * include windows/photofilmstrip.bat include windows/photofilmstrip-cli.bat include CHANGES include COPYING include LICENSE include Makefile include MANIFEST.in include README photofilmstrip-3.7.2/COPYING0000644000232200023220000004310313560357351016220 0ustar debalancedebalance 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. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 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. , 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. photofilmstrip-3.7.2/po/0000755000232200023220000000000013560357432015602 5ustar debalancedebalancephotofilmstrip-3.7.2/po/en.po0000644000232200023220000005376513560357351016564 0ustar debalancedebalance# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR ORGANIZATION # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PhotoFilmStrip\n" "POT-Creation-Date: 2018-11-07 22:03+CET\n" "PO-Revision-Date: 2011-07-10 13:32+0100\n" "Last-Translator: Jens Göpfert \n" "Language-Team: Jens Göpfert \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: pygettext.py 1.5\n" "X-Poedit-Language: English\n" "X-Poedit-Country: UNITED STATES\n" "X-Poedit-SourceCharset: utf-8\n" #: photofilmstrip/action/ActionAutoPath.py:23 #: photofilmstrip/gui/PnlPfsProject.py:115 msgid "Random motion" msgstr "" #: photofilmstrip/action/ActionCenterPath.py:21 msgid "Centralize motion" msgstr "" #: photofilmstrip/action/ActionI18N.py:24 #: photofilmstrip/gui/ActionManager.py:170 msgid "Language" msgstr "" #: photofilmstrip/action/ActionOpenFolder.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:28 msgid "Open folder" msgstr "" #: photofilmstrip/action/ActionPlayVideo.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:22 msgid "Play video" msgstr "" #: photofilmstrip/action/ActionRender.py:37 msgid "Start" msgstr "" #: photofilmstrip/cli/Main.py:46 photofilmstrip/cli/Main.py:196 msgid "all done" msgstr "" #: photofilmstrip/cli/Main.py:64 msgid "processing project" msgstr "" #: photofilmstrip/cli/Main.py:65 msgid "using renderer" msgstr "" #: photofilmstrip/cli/Main.py:66 msgid "output format" msgstr "" #: photofilmstrip/cli/Main.py:69 msgid "framerate" msgstr "" #: photofilmstrip/cli/Main.py:103 msgid "specifies the project file" msgstr "" #: photofilmstrip/cli/Main.py:104 msgid "The path where to save the output files. Use - for stdout." msgstr "" #: photofilmstrip/cli/Main.py:106 photofilmstrip/cli/Main.py:129 msgid "Option videonorm is deprecated, use an appropriate profile!" msgstr "" #: photofilmstrip/cli/Main.py:108 msgid "enable draft mode" msgstr "" #: photofilmstrip/cli/Main.py:108 photofilmstrip/gui/DlgRender.py:167 msgid "" "Activate this option to generate a preview of your PhotoFilmStrip. The " "rendering process will speed up dramatically, but results in lower quality." msgstr "" #: photofilmstrip/cli/Main.py:120 msgid "project file does not exist: %s" msgstr "" #: photofilmstrip/cli/Main.py:124 msgid "no project file specified!" msgstr "" #: photofilmstrip/cli/Main.py:134 msgid "invalid format specified: %s" msgstr "" #: photofilmstrip/cli/Main.py:140 msgid "invalid profile specified: %s" msgstr "" #: photofilmstrip/cli/Main.py:146 msgid "cannot load project" msgstr "" #: photofilmstrip/cli/Main.py:159 msgid "cannot create output path: %s" msgstr "" #: photofilmstrip/cli/Main.py:169 photofilmstrip/gui/DlgConfigureAudio.py:231 #: photofilmstrip/gui/DlgConfigureAudio.py:253 msgid "Audio file '%s' does not exist!" msgstr "" #: photofilmstrip/cli/Main.py:190 msgid "...aborted!" msgstr "" #: photofilmstrip/core/BaseRenderer.py:50 msgid "Unknown property: %s" msgstr "" #: photofilmstrip/core/BaseRenderer.py:58 msgid "" msgstr "" #: photofilmstrip/core/BaseRenderer.py:73 msgid "no" msgstr "" #: photofilmstrip/core/ProjectFile.py:222 msgid "Saving '%s' ..." msgstr "" #: photofilmstrip/core/ProjectFile.py:276 msgid "Loading '%s' ..." msgstr "" #: photofilmstrip/core/RenderEngine.py:113 #: photofilmstrip/core/RenderEngine.py:201 msgid "processing transition %d/%d" msgstr "" #: photofilmstrip/core/RenderEngine.py:124 #: photofilmstrip/core/RenderEngine.py:210 msgid "processing image %d/%d" msgstr "" #: photofilmstrip/core/renderer/CairoRenderer.py:35 msgid "Preview" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:50 msgid "GStreamer (python-gst-1.0) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:287 msgid "Bitrate must be a number!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:455 #: photofilmstrip/core/renderer/GStreamerRenderer.py:531 #: photofilmstrip/core/renderer/GStreamerRenderer.py:601 #: photofilmstrip/core/renderer/GStreamerRenderer.py:690 #: photofilmstrip/core/renderer/GStreamerRenderer.py:730 #: photofilmstrip/core/renderer/GStreamerRenderer.py:779 msgid "libav (gstreamer1.0-libav) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:459 #: photofilmstrip/core/renderer/GStreamerRenderer.py:535 #: photofilmstrip/core/renderer/GStreamerRenderer.py:605 msgid "x264-Codec (gstreamer1.0-plugins-ugly) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:463 #: photofilmstrip/core/renderer/GStreamerRenderer.py:609 msgid "MKV-Muxer (gstreamer1.0-plugins-good) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:539 msgid "MP4-Muxer (gstreamer1.0-plugins-good) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:647 msgid "Theora-Codec (gstreamer1.0-plugins-base) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:651 msgid "Vorbis-Codec (gstreamer1.0-plugins-base) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:655 msgid "OGV-Muxer (gstreamer1.0-plugins-base) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:686 #: photofilmstrip/core/renderer/GStreamerRenderer.py:726 #: photofilmstrip/core/renderer/GStreamerRenderer.py:775 msgid "MPEG-1/2-Codec (gstreamer1.0-plugins-bad) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:694 #: photofilmstrip/core/renderer/GStreamerRenderer.py:734 #: photofilmstrip/core/renderer/GStreamerRenderer.py:783 msgid "MPEG-Muxer (gstreamer1.0-plugins-bad) required!" msgstr "" #: photofilmstrip/core/renderer/SingleFileRenderer.py:21 msgid "Single pictures" msgstr "" #: photofilmstrip/core/tasks.py:48 msgid "generating subtitle" msgstr "" #: photofilmstrip/gui/ActionManager.py:60 #: photofilmstrip/gui/ActionManager.py:190 msgid "&File" msgstr "" #: photofilmstrip/gui/ActionManager.py:61 #: photofilmstrip/gui/ActionManager.py:191 msgid "&Edit" msgstr "" #: photofilmstrip/gui/ActionManager.py:62 #: photofilmstrip/gui/ActionManager.py:154 photofilmstrip/gui/DlgRender.py:141 #: photofilmstrip/gui/DlgRendererProps.py:86 msgid "&Help" msgstr "" #: photofilmstrip/gui/ActionManager.py:76 msgid "New Slideshow" msgstr "" #: photofilmstrip/gui/ActionManager.py:81 msgid "Open" msgstr "" #: photofilmstrip/gui/ActionManager.py:87 msgid "Save" msgstr "" #: photofilmstrip/gui/ActionManager.py:97 #: photofilmstrip/gui/ActionManager.py:98 msgid "Show job queue" msgstr "" #: photofilmstrip/gui/ActionManager.py:108 #: photofilmstrip/gui/PnlSlideshow.py:25 msgid "Slideshow" msgstr "" #: photofilmstrip/gui/ActionManager.py:110 #: photofilmstrip/gui/PnlTimelapse.py:18 msgid "Timelapse" msgstr "" #: photofilmstrip/gui/ActionManager.py:116 msgid "New" msgstr "" #: photofilmstrip/gui/ActionManager.py:118 msgid "&Open" msgstr "" #: photofilmstrip/gui/ActionManager.py:123 msgid "&Save" msgstr "" #: photofilmstrip/gui/ActionManager.py:136 msgid "&Close" msgstr "" #: photofilmstrip/gui/ActionManager.py:141 msgid "E&xit" msgstr "" #: photofilmstrip/gui/ActionManager.py:173 msgid "&About" msgstr "" #: photofilmstrip/gui/DlgBugReport.py:41 msgid "An unexpected error occured" msgstr "" #: photofilmstrip/gui/DlgBugReport.py:44 msgid "" "An unexpected error occured. Do you want to send this bug report to the " "developers of %s?" msgstr "" #: photofilmstrip/gui/DlgBugReport.py:99 msgid "Bug-Report send. Thank you for your support." msgstr "" #: photofilmstrip/gui/DlgBugReport.py:100 photofilmstrip/gui/FrmMain.py:290 msgid "Information" msgstr "" #: photofilmstrip/gui/DlgBugReport.py:106 msgid "Sorry, this function is temporary not available.." msgstr "" #: photofilmstrip/gui/DlgBugReport.py:107 #: photofilmstrip/gui/DlgConfigureAudio.py:232 #: photofilmstrip/gui/DlgConfigureAudio.py:244 #: photofilmstrip/gui/DlgConfigureAudio.py:254 #: photofilmstrip/gui/DlgNewProject.py:156 #: photofilmstrip/gui/DlgNewProject.py:167 #: photofilmstrip/gui/DlgPicDurationByAudio.py:208 #: photofilmstrip/gui/DlgPicDurationByAudio.py:216 #: photofilmstrip/gui/FrmMain.py:376 photofilmstrip/gui/PnlPfsProject.py:468 #: photofilmstrip/gui/PnlTimelapse.py:113 msgid "Error" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:55 msgid "Configure your audio files that are used as a background music." msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:90 msgid "Set the duration of your slideshow to fit your audio files" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:92 #: photofilmstrip/gui/DlgDuration.py:70 photofilmstrip/gui/DlgNewProject.py:84 #: photofilmstrip/gui/DlgPicDurationByAudio.py:50 #: photofilmstrip/gui/DlgPositionInput.py:238 #: photofilmstrip/gui/DlgRender.py:147 #: photofilmstrip/gui/DlgRendererProps.py:92 #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:97 msgid "&Cancel" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:97 #: photofilmstrip/gui/DlgDuration.py:72 photofilmstrip/gui/DlgNewProject.py:86 #: photofilmstrip/gui/DlgPicDurationByAudio.py:51 #: photofilmstrip/gui/DlgPositionInput.py:244 #: photofilmstrip/gui/DlgRendererProps.py:97 msgid "&Ok" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:104 #: photofilmstrip/gui/DlgConfigureAudio.py:109 #: photofilmstrip/gui/PnlSlideshow.py:47 photofilmstrip/gui/PnlSlideshow.py:48 #: photofilmstrip/gui/PnlTimelapse.py:33 photofilmstrip/gui/PnlTimelapse.py:34 msgid "Configure music" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:138 msgid "Select music" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:140 msgid "Audio files" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:243 msgid "Audio file not supported!" msgstr "" #: photofilmstrip/gui/DlgDuration.py:48 msgid "Total length:" msgstr "" #: photofilmstrip/gui/DlgDuration.py:50 msgid "" "Overrides the duration of single pictures and gives the project this total " "length." msgstr "" #: photofilmstrip/gui/DlgDuration.py:54 msgid "User defined:" msgstr "" #: photofilmstrip/gui/DlgDuration.py:65 msgid "Fit to audio files" msgstr "" #: photofilmstrip/gui/DlgDuration.py:80 msgid "Slideshow duration" msgstr "" #: photofilmstrip/gui/DlgDuration.py:84 msgid "Configure duration of slideshow" msgstr "" #: photofilmstrip/gui/DlgNewProject.py:61 msgid "Project name:" msgstr "" #: photofilmstrip/gui/DlgNewProject.py:66 msgid "Folder:" msgstr "" #: photofilmstrip/gui/DlgNewProject.py:78 msgid "Aspect ratio:" msgstr "" #: photofilmstrip/gui/DlgNewProject.py:110 msgid "Unnamed project" msgstr "" #: photofilmstrip/gui/DlgNewProject.py:116 msgid "My PhotoFilmStrips" msgstr "" #: photofilmstrip/gui/DlgNewProject.py:126 msgid "Browse for folder" msgstr "" #: photofilmstrip/gui/DlgNewProject.py:145 msgid "Folder does not exists! Do you want %s to create it?" msgstr "" #: photofilmstrip/gui/DlgNewProject.py:146 #: photofilmstrip/gui/PnlEditorPage.py:29 #: photofilmstrip/gui/PnlEditorPage.py:49 #: photofilmstrip/gui/PnlEditorPage.py:88 #: photofilmstrip/gui/WxProjectFile.py:101 #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:224 msgid "Question" msgstr "" #: photofilmstrip/gui/DlgNewProject.py:155 msgid "Cannot create folder: %s" msgstr "" #: photofilmstrip/gui/DlgNewProject.py:166 msgid "Cannot write into folder!" msgstr "" #: photofilmstrip/gui/DlgNewProject.py:180 msgid "The project name must be filled." msgstr "" #: photofilmstrip/gui/DlgNewProject.py:186 msgid "The project name contains invalid characters." msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:23 #: photofilmstrip/gui/PnlSlideshow.py:54 photofilmstrip/gui/PnlSlideshow.py:55 msgid "Adjust picture durations" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:26 msgid "Adjust picture durations to audio file" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:30 msgid "" "Find your picture duration by playing the audio file of your project and\n" "pressing the hit button to apply the current playing time." msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:43 #: photofilmstrip/gui/DlgPicDurationByAudio.py:153 msgid "Play" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:46 msgid "Hit" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:100 msgid "Stop" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:179 msgid "Playing time" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:207 msgid "Your project does not have an audio file configured." msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:215 msgid "" "Your project uses more than one audio file. Currently the durations can be " "adjusted only for one audio file." msgstr "" #: photofilmstrip/gui/DlgPositionInput.py:140 msgid "Motion positions" msgstr "" #: photofilmstrip/gui/DlgPositionInput.py:147 msgid "Start position" msgstr "" #: photofilmstrip/gui/DlgPositionInput.py:155 #: photofilmstrip/gui/DlgPositionInput.py:199 msgid "Location:" msgstr "" #: photofilmstrip/gui/DlgPositionInput.py:173 #: photofilmstrip/gui/DlgPositionInput.py:215 msgid "Size:" msgstr "" #: photofilmstrip/gui/DlgPositionInput.py:191 msgid "End position" msgstr "" #: photofilmstrip/gui/DlgPositionInput.py:233 msgid "Reset" msgstr "" #: photofilmstrip/gui/DlgPositionInput.py:252 msgid "Adjust motion positions directly" msgstr "" #: photofilmstrip/gui/DlgRender.py:96 msgid "Render project" msgstr "" #: photofilmstrip/gui/DlgRender.py:107 msgid "Format:" msgstr "" #: photofilmstrip/gui/DlgRender.py:122 msgid "Properties" msgstr "" #: photofilmstrip/gui/DlgRender.py:127 msgid "Profile:" msgstr "" #: photofilmstrip/gui/DlgRender.py:136 msgid "Draft" msgstr "" #: photofilmstrip/gui/DlgRender.py:152 msgid "&Start" msgstr "" #: photofilmstrip/gui/DlgRender.py:164 msgid "Configure output and start render process" msgstr "" #: photofilmstrip/gui/DlgRendererProps.py:50 msgid "Property" msgstr "" #: photofilmstrip/gui/DlgRendererProps.py:52 msgid "Value" msgstr "" #: photofilmstrip/gui/DlgRendererProps.py:71 msgid "Output properties" msgstr "" #: photofilmstrip/gui/DlgRendererProps.py:113 msgid "Edit extended output properties" msgstr "" #: photofilmstrip/gui/DlgRendererProps.py:147 msgid "Edit property" msgstr "" #: photofilmstrip/gui/FrmMain.py:83 msgid "Welcome" msgstr "" #: photofilmstrip/gui/FrmMain.py:85 msgid "Job queue" msgstr "" #: photofilmstrip/gui/FrmMain.py:141 msgid "Rendering in progress..." msgstr "" #: photofilmstrip/gui/FrmMain.py:234 photofilmstrip/gui/PnlWelcome.py:57 msgid "Create new slideshow" msgstr "" #: photofilmstrip/gui/FrmMain.py:241 msgid "Create new timelapse" msgstr "" #: photofilmstrip/gui/FrmMain.py:249 msgid "Select %s-Project" msgstr "" #: photofilmstrip/gui/FrmMain.py:251 msgid "Files" msgstr "" #: photofilmstrip/gui/FrmMain.py:289 msgid "You must restart %s for your new language setting to take effect." msgstr "" #: photofilmstrip/gui/FrmMain.py:300 msgid "" "PhotoFilmStrip creates movies out of your pictures in just 3 steps. First " "select your photos, customize the motion path and render the video. There " "are several output possibilities for VCD, SVCD, DVD up to FULL-HD." msgstr "" #: photofilmstrip/gui/FrmMain.py:303 msgid "online" msgstr "" #: photofilmstrip/gui/FrmMain.py:374 msgid "Invalid %(app)s-Project: %(file)s" msgstr "" #: photofilmstrip/gui/PnlAddPics.py:50 photofilmstrip/gui/PnlWelcome.py:30 msgid "Welcome to PhotoFilmStrip" msgstr "" #: photofilmstrip/gui/PnlAddPics.py:52 msgid "" "Drag some pictures onto this text or\n" "click the button below\n" "to add pictures to your new PhotoFilmStrip." msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:142 msgid "Settings" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:146 msgid "Rotation:" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:166 msgid "Effect:" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:180 msgid "Process" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:184 msgid "Movement:" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:196 #: photofilmstrip/gui/PnlEditPicture.py:212 #: photofilmstrip/gui/PnlEditPicture.py:359 msgid "sec" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:200 msgid "Transition:" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:220 msgid "Subtitle" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:240 msgid "Linear" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:241 msgid "Accelerated" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:242 msgid "Delayed" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:250 msgid "No effect" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:251 msgid "Black and White" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:252 msgid "Sepia tone" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:258 msgid "None" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:259 msgid "Fade" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:260 msgid "Roll" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:354 msgid "fpp" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:355 msgid "frames per picture - the number of frames each picture will be shown" msgstr "" #: photofilmstrip/gui/PnlEditorPage.py:26 msgid "Could not save the file '%(file)s': %(errMsg)s" msgstr "" #: photofilmstrip/gui/PnlEditorPage.py:45 msgid "New file" msgstr "" #: photofilmstrip/gui/PnlEditorPage.py:48 msgid "'%s' has been modified. Save changes?" msgstr "" #: photofilmstrip/gui/PnlEditorPage.py:74 msgid "Save %s" msgstr "" #: photofilmstrip/gui/PnlEditorPage.py:77 msgid "File" msgstr "" #: photofilmstrip/gui/PnlEditorPage.py:87 msgid "Overwrite existing file '%s'?" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:118 #: photofilmstrip/gui/PnlPfsProject.py:120 msgid "Set motion start to end" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:122 #: photofilmstrip/gui/PnlPfsProject.py:124 msgid "Set motion end to start" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:126 #: photofilmstrip/gui/PnlPfsProject.py:128 msgid "Swap motion" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:131 #: photofilmstrip/gui/PnlPfsProject.py:133 msgid "Adjust motion manual" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:136 #: photofilmstrip/gui/PnlPfsProject.py:138 msgid "Preserve image dimension" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:294 msgid "&Import Pictures" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:299 msgid "Move picture &left" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:303 msgid "Move picture &right" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:308 msgid "R&emove Picture" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:313 msgid "Rotate &clockwise" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:317 msgid "Rotate counter clock&wise" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:322 msgid "Random &motion" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:326 msgid "Centralize m&otion" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:384 msgid "Export slideshow" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:387 #: photofilmstrip/gui/PnlPfsProject.py:400 msgid "Portable slideshow" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:398 msgid "Import Slideshow" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:409 msgid "Import images" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:411 msgid "Image files" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:654 msgid "Audio file '%s' does not exist! Continue anyway?" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:655 msgid "Warning" msgstr "" #: photofilmstrip/gui/PnlSlideshow.py:30 msgid "&Properties" msgstr "" #: photofilmstrip/gui/PnlSlideshow.py:39 photofilmstrip/gui/PnlSlideshow.py:40 #: photofilmstrip/gui/PnlTimelapse.py:25 photofilmstrip/gui/PnlTimelapse.py:26 msgid "Import Pictures" msgstr "" #: photofilmstrip/gui/PnlSlideshow.py:62 photofilmstrip/gui/PnlSlideshow.py:63 #: photofilmstrip/gui/PnlTimelapse.py:41 photofilmstrip/gui/PnlTimelapse.py:42 msgid "Render filmstrip" msgstr "" #: photofilmstrip/gui/PnlSlideshow.py:89 photofilmstrip/gui/PnlTimelapse.py:66 msgid "Images" msgstr "" #: photofilmstrip/gui/PnlSlideshow.py:94 msgid "Duration" msgstr "" #: photofilmstrip/gui/PnlTimelapse.py:69 msgid "Frames" msgstr "" #: photofilmstrip/gui/PnlTimelapse.py:92 msgid "The picture counter is not increasing: %s" msgstr "" #: photofilmstrip/gui/PnlTimelapse.py:110 msgid "" "Filename '%s' does not match a number pattern which is necessary for a time " "lapse slide show!" msgstr "" #: photofilmstrip/gui/PnlWelcome.py:37 photofilmstrip/gui/PnlWelcome.py:103 msgid "Recent projects" msgstr "" #: photofilmstrip/gui/PnlWelcome.py:62 msgid "Open existing project" msgstr "" #: photofilmstrip/gui/PnlWelcome.py:106 msgid "How to start..." msgstr "" #: photofilmstrip/gui/PnlWelcome.py:107 msgid "Create a new project or load an existing one." msgstr "" #: photofilmstrip/gui/PnlWelcome.py:138 msgid "Update available" msgstr "" #: photofilmstrip/gui/PnlWelcome.py:141 msgid "The following changes has been made:" msgstr "" #: photofilmstrip/gui/WxProjectFile.py:59 msgid "Loading project %s" msgstr "" #: photofilmstrip/gui/WxProjectFile.py:75 msgid "Saving project %s" msgstr "" #: photofilmstrip/gui/WxProjectFile.py:100 msgid "" "Some images does not exist in the folder '%s' anymore. If the files has " "moved you can select the new path. Do you want to select a new path?" msgstr "" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:73 msgid "Elapsed time" msgstr "" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:85 msgid "Remaining time" msgstr "" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:203 msgid "Unknown" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobManager.py:50 msgid "&Clear list" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:127 msgid "Abort" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:133 msgid "Remove from list" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:223 msgid "Abort selected process?" msgstr "" #: photofilmstrip/lib/jobimpl/VisualJob.py:29 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:25 msgid "Waiting..." msgstr "" #: photofilmstrip/lib/jobimpl/VisualJob.py:68 #: photofilmstrip/lib/jobimpl/VisualJob.py:85 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:60 msgid "Aborted" msgstr "" #: photofilmstrip/lib/jobimpl/VisualJob.py:70 msgid "Done" msgstr "" #: photofilmstrip/lib/jobimpl/VisualJob.py:79 msgid "Aborting..." msgstr "" #: photofilmstrip/uwp/UwpService.py:76 msgid "Slideshow created!" msgstr "" photofilmstrip-3.7.2/po/cs.po0000644000232200023220000007761013560357351016562 0ustar debalancedebalance# Copyright (C) YEAR ORGANIZATION # # Pavel Fric , 2019. msgid "" msgstr "" "Project-Id-Version: PhotoFilmStrip\n" "POT-Creation-Date: 2019-02-19 17:47+CET\n" "PO-Revision-Date: 2019-02-19 17:48+0100\n" "Last-Translator: Pavel Fric \n" "Language-Team: Czech \n" "Language: cs_CZ\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: pygettext.py 1.5\n" "X-Poedit-SourceCharset: utf-8\n" "X-Generator: Poedit 2.1.1\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" #: photofilmstrip/action/ActionAutoPath.py:23 #: photofilmstrip/gui/PnlPfsProject.py:115 msgid "Random motion" msgstr "Náhodný pohyb" #: photofilmstrip/action/ActionCenterPath.py:21 msgid "Centralize motion" msgstr "Vystředit výběr" #: photofilmstrip/action/ActionI18N.py:24 #: photofilmstrip/gui/ActionManager.py:170 msgid "Language" msgstr "Jazyk" #: photofilmstrip/action/ActionOpenFolder.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:28 msgid "Open folder" msgstr "Otevřít složku" #: photofilmstrip/action/ActionPlayVideo.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:22 photofilmstrip/ux/gnome.py:42 msgid "Play video" msgstr "Přehrát obrazový záznam" #: photofilmstrip/action/ActionRender.py:37 msgid "Start" msgstr "Spustit" #: photofilmstrip/cli/Main.py:46 photofilmstrip/cli/Main.py:196 msgid "all done" msgstr "Vše dokončeno" #: photofilmstrip/cli/Main.py:64 msgid "processing project" msgstr "Zpracovává se projekt" #: photofilmstrip/cli/Main.py:65 msgid "using renderer" msgstr "Používá se zpracovávač" #: photofilmstrip/cli/Main.py:66 msgid "output format" msgstr "Výstupní formát" #: photofilmstrip/cli/Main.py:69 msgid "framerate" msgstr "Snímkování" #: photofilmstrip/cli/Main.py:103 msgid "specifies the project file" msgstr "Určuje projektový soubor" #: photofilmstrip/cli/Main.py:104 msgid "The path where to save the output files. Use - for stdout." msgstr "Cesta, kam ukládat výstupní soubory. Použít pro standardní výstup." #: photofilmstrip/cli/Main.py:106 photofilmstrip/cli/Main.py:129 msgid "Option videonorm is deprecated, use an appropriate profile!" msgstr "" "Volba videonorm se už nepoužívá (zastaralá). Použijte odpovídající profil!" #: photofilmstrip/cli/Main.py:108 msgid "enable draft mode" msgstr "Povolit návrhový režim" #: photofilmstrip/cli/Main.py:108 photofilmstrip/gui/DlgRender.py:167 msgid "" "Activate this option to generate a preview of your PhotoFilmStrip. The " "rendering process will speed up dramatically, but results in lower quality." msgstr "" "Zapněte tuto volbu pro vytvoření náhledu vašeho filmového pásu. postup " "zpracování se podstatně zrychlí, ale vede k nižší jakosti." #: photofilmstrip/cli/Main.py:120 msgid "project file does not exist: %s" msgstr "Projektový soubor neexistuje: %s" #: photofilmstrip/cli/Main.py:124 msgid "no project file specified!" msgstr "Není stanoven projektový soubor!" #: photofilmstrip/cli/Main.py:134 msgid "invalid format specified: %s" msgstr "Stanoven špatný formát: %s" #: photofilmstrip/cli/Main.py:140 msgid "invalid profile specified: %s" msgstr "Stanoven špatný profil: %s" #: photofilmstrip/cli/Main.py:146 msgid "cannot load project" msgstr "Nelze nahrát projekt" #: photofilmstrip/cli/Main.py:159 msgid "cannot create output path: %s" msgstr "Nelze vytvořit výstupní cestu: %s" #: photofilmstrip/cli/Main.py:169 photofilmstrip/gui/DlgConfigureAudio.py:231 #: photofilmstrip/gui/DlgConfigureAudio.py:253 msgid "Audio file '%s' does not exist!" msgstr "Zvukový soubor '%s' neexistuje!" #: photofilmstrip/cli/Main.py:190 msgid "...aborted!" msgstr "Přerušeno!" #: photofilmstrip/core/BaseRenderer.py:50 msgid "Unknown property: %s" msgstr "Neznámá vlastnost: %s" #: photofilmstrip/core/BaseRenderer.py:58 msgid "" msgstr "" #: photofilmstrip/core/BaseRenderer.py:73 msgid "no" msgstr "Ne" #: photofilmstrip/core/ProjectFile.py:222 msgid "Saving '%s' ..." msgstr "Ukládá se '%s' ..." #: photofilmstrip/core/ProjectFile.py:276 msgid "Loading '%s' ..." msgstr "Nahrává se '%s' ..." #: photofilmstrip/core/RenderEngine.py:113 #: photofilmstrip/core/RenderEngine.py:201 msgid "processing transition %d/%d" msgstr "Zpracovává se přechod %d/%d" #: photofilmstrip/core/RenderEngine.py:124 #: photofilmstrip/core/RenderEngine.py:210 msgid "processing image %d/%d" msgstr "Zpracovává se obraz %d/%d" #: photofilmstrip/core/renderer/CairoRenderer.py:35 msgid "Preview" msgstr "Náhled" #: photofilmstrip/core/renderer/GStreamerRenderer.py:50 msgid "GStreamer (python-gst-1.0) required!" msgstr "Požadován GStreamer (python-gst-1.0)!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:287 msgid "Bitrate must be a number!" msgstr "Datový tok musí být číslo!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:455 #: photofilmstrip/core/renderer/GStreamerRenderer.py:531 #: photofilmstrip/core/renderer/GStreamerRenderer.py:601 #: photofilmstrip/core/renderer/GStreamerRenderer.py:690 #: photofilmstrip/core/renderer/GStreamerRenderer.py:730 #: photofilmstrip/core/renderer/GStreamerRenderer.py:779 msgid "libav (gstreamer1.0-libav) required!" msgstr "Požadován libav (gstreamer1.0-libav)!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:459 #: photofilmstrip/core/renderer/GStreamerRenderer.py:535 #: photofilmstrip/core/renderer/GStreamerRenderer.py:605 msgid "x264-Codec (gstreamer1.0-plugins-ugly) required!" msgstr "Požadován kodek x264 (gstreamer1.0-plugins-ugly)!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:463 #: photofilmstrip/core/renderer/GStreamerRenderer.py:609 msgid "MKV-Muxer (gstreamer1.0-plugins-good) required!" msgstr "Požadován MKV-Muxer (gstreamer1.0-plugins-good)!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:539 msgid "MP4-Muxer (gstreamer1.0-plugins-good) required!" msgstr "Požadován MP4-Muxer (gstreamer1.0-plugins-good)!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:647 msgid "Theora-Codec (gstreamer1.0-plugins-base) required!" msgstr "Požadován kodek Theora (gstreamer1.0-plugins-base)!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:651 msgid "Vorbis-Codec (gstreamer1.0-plugins-base) required!" msgstr "Požadován kodek Vorbis (gstreamer1.0-plugins-base)!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:655 msgid "OGV-Muxer (gstreamer1.0-plugins-base) required!" msgstr "Požadován OGV-Muxer (gstreamer1.0-plugins-base)!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:686 #: photofilmstrip/core/renderer/GStreamerRenderer.py:726 #: photofilmstrip/core/renderer/GStreamerRenderer.py:775 msgid "MPEG-1/2-Codec (gstreamer1.0-plugins-bad) required!" msgstr "Požadován kodek MPEG-1/2 (gstreamer1.0-plugins-bad)!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:694 #: photofilmstrip/core/renderer/GStreamerRenderer.py:734 #: photofilmstrip/core/renderer/GStreamerRenderer.py:783 msgid "MPEG-Muxer (gstreamer1.0-plugins-bad) required!" msgstr "Požadován MPEG-Muxer (gstreamer1.0-plugins-bad)!" #: photofilmstrip/core/renderer/SingleFileRenderer.py:21 msgid "Single pictures" msgstr "Samostatné obrázky" #: photofilmstrip/core/tasks.py:48 msgid "generating subtitle" msgstr "Vytváří se titulky" #: photofilmstrip/gui/ActionManager.py:60 #: photofilmstrip/gui/ActionManager.py:190 msgid "&File" msgstr "&Soubor" #: photofilmstrip/gui/ActionManager.py:61 #: photofilmstrip/gui/ActionManager.py:191 msgid "&Edit" msgstr "Úp&ravy" #: photofilmstrip/gui/ActionManager.py:62 #: photofilmstrip/gui/ActionManager.py:154 photofilmstrip/gui/DlgRender.py:141 #: photofilmstrip/gui/DlgRendererProps.py:86 msgid "&Help" msgstr "&Nápověda" #: photofilmstrip/gui/ActionManager.py:76 msgid "New Slideshow" msgstr "Nové promítání" #: photofilmstrip/gui/ActionManager.py:81 msgid "Open" msgstr "Otevřít" #: photofilmstrip/gui/ActionManager.py:87 msgid "Save" msgstr "Uložit" #: photofilmstrip/gui/ActionManager.py:97 #: photofilmstrip/gui/ActionManager.py:98 msgid "Show job queue" msgstr "Ukázat řadu úloh" #: photofilmstrip/gui/ActionManager.py:108 #: photofilmstrip/gui/PnlSlideshow.py:25 msgid "Slideshow" msgstr "Promítání" #: photofilmstrip/gui/ActionManager.py:110 #: photofilmstrip/gui/PnlTimelapse.py:18 msgid "Timelapse" msgstr "Časový úsek" #: photofilmstrip/gui/ActionManager.py:116 msgid "New" msgstr "Nový" #: photofilmstrip/gui/ActionManager.py:118 msgid "&Open" msgstr "&Otevřít" #: photofilmstrip/gui/ActionManager.py:123 msgid "&Save" msgstr "&Uložit" #: photofilmstrip/gui/ActionManager.py:136 msgid "&Close" msgstr "&Zavřít" #: photofilmstrip/gui/ActionManager.py:141 msgid "E&xit" msgstr "&Ukončit" #: photofilmstrip/gui/ActionManager.py:173 msgid "&About" msgstr "&O programu" #: photofilmstrip/gui/DlgBugReport.py:41 msgid "An unexpected error occured" msgstr "Nastala neočekávaná chyba" #: photofilmstrip/gui/DlgBugReport.py:44 msgid "" "An unexpected error occured. Do you want to send this bug report to the " "developers of %s?" msgstr "Nastala neočekávaná chyba. Chcete poslat zprávu o chybě vývojářům %s?" #: photofilmstrip/gui/DlgBugReport.py:99 msgid "Bug-Report send. Thank you for your support." msgstr "Zpráva o chybě odeslána. Děkujeme za podporu." #: photofilmstrip/gui/DlgBugReport.py:100 photofilmstrip/gui/FrmMain.py:290 msgid "Information" msgstr "Informace" #: photofilmstrip/gui/DlgBugReport.py:106 msgid "Sorry, this function is temporary not available.." msgstr "Omlouváme se, tato funkce je dočasně nedostupná." #: photofilmstrip/gui/DlgBugReport.py:107 #: photofilmstrip/gui/DlgConfigureAudio.py:232 #: photofilmstrip/gui/DlgConfigureAudio.py:244 #: photofilmstrip/gui/DlgConfigureAudio.py:254 #: photofilmstrip/gui/DlgNewProject.py:156 #: photofilmstrip/gui/DlgNewProject.py:167 #: photofilmstrip/gui/DlgPicDurationByAudio.py:208 #: photofilmstrip/gui/DlgPicDurationByAudio.py:216 #: photofilmstrip/gui/FrmMain.py:376 photofilmstrip/gui/PnlPfsProject.py:468 #: photofilmstrip/gui/PnlTimelapse.py:113 msgid "Error" msgstr "Chyba" #: photofilmstrip/gui/DlgConfigureAudio.py:55 msgid "Configure your audio files that are used as a background music." msgstr "Nastavit zvukové soubory používané jako hudba na pozadí." #: photofilmstrip/gui/DlgConfigureAudio.py:90 msgid "Set the duration of your slideshow to fit your audio files" msgstr "Nastavit dobu trvání promítání, aby se shodovala se zvukovými soubory" #: photofilmstrip/gui/DlgConfigureAudio.py:92 #: photofilmstrip/gui/DlgDuration.py:70 photofilmstrip/gui/DlgNewProject.py:84 #: photofilmstrip/gui/DlgPicDurationByAudio.py:50 #: photofilmstrip/gui/DlgPositionInput.py:238 #: photofilmstrip/gui/DlgRender.py:147 #: photofilmstrip/gui/DlgRendererProps.py:92 #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:97 msgid "&Cancel" msgstr "&Zrušit" #: photofilmstrip/gui/DlgConfigureAudio.py:97 #: photofilmstrip/gui/DlgDuration.py:72 photofilmstrip/gui/DlgNewProject.py:86 #: photofilmstrip/gui/DlgPicDurationByAudio.py:51 #: photofilmstrip/gui/DlgPositionInput.py:244 #: photofilmstrip/gui/DlgRendererProps.py:97 msgid "&Ok" msgstr "&OK" #: photofilmstrip/gui/DlgConfigureAudio.py:104 #: photofilmstrip/gui/DlgConfigureAudio.py:109 #: photofilmstrip/gui/PnlSlideshow.py:47 photofilmstrip/gui/PnlSlideshow.py:48 #: photofilmstrip/gui/PnlTimelapse.py:33 photofilmstrip/gui/PnlTimelapse.py:34 msgid "Configure music" msgstr "Nastavit hudbu" #: photofilmstrip/gui/DlgConfigureAudio.py:138 msgid "Select music" msgstr "Vybrat hudbu" #: photofilmstrip/gui/DlgConfigureAudio.py:140 msgid "Audio files" msgstr "Zvukové soubory" #: photofilmstrip/gui/DlgConfigureAudio.py:243 msgid "Audio file not supported!" msgstr "Zvukový soubor nepodporován!" #: photofilmstrip/gui/DlgDuration.py:48 msgid "Total length:" msgstr "Celková délka:" #: photofilmstrip/gui/DlgDuration.py:50 msgid "" "Overrides the duration of single pictures and gives the project this total " "length." msgstr "" "Potlačí dobu trvání jednotlivých obrázků a nastaví obrazovému záznamu tuto " "celkovou délku." #: photofilmstrip/gui/DlgDuration.py:54 msgid "User defined:" msgstr "Uživatelsky stanovené:" #: photofilmstrip/gui/DlgDuration.py:65 msgid "Fit to audio files" msgstr "Přizpůsobit zvukovým souborům" #: photofilmstrip/gui/DlgDuration.py:80 msgid "Slideshow duration" msgstr "Doba trvání promítání" #: photofilmstrip/gui/DlgDuration.py:84 msgid "Configure duration of slideshow" msgstr "Nastavit dobu trvání promítání" #: photofilmstrip/gui/DlgNewProject.py:61 msgid "Project name:" msgstr "Název projektu:" #: photofilmstrip/gui/DlgNewProject.py:66 msgid "Folder:" msgstr "Složka:" #: photofilmstrip/gui/DlgNewProject.py:78 msgid "Aspect ratio:" msgstr "Poměr stran:" #: photofilmstrip/gui/DlgNewProject.py:110 msgid "Unnamed project" msgstr "Nepojmenovaný projekt" #: photofilmstrip/gui/DlgNewProject.py:116 msgid "My PhotoFilmStrips" msgstr "Moje filmové pásy" #: photofilmstrip/gui/DlgNewProject.py:126 msgid "Browse for folder" msgstr "Vybrat složku" #: photofilmstrip/gui/DlgNewProject.py:145 msgid "Folder does not exists! Do you want %s to create it?" msgstr "Složka neexistuje! Chcete, aby ji %s vytvořil?" #: photofilmstrip/gui/DlgNewProject.py:146 #: photofilmstrip/gui/PnlEditorPage.py:29 #: photofilmstrip/gui/PnlEditorPage.py:49 #: photofilmstrip/gui/PnlEditorPage.py:88 #: photofilmstrip/gui/WxProjectFile.py:101 #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:224 msgid "Question" msgstr "Otázka" #: photofilmstrip/gui/DlgNewProject.py:155 msgid "Cannot create folder: %s" msgstr "Nelze vytvořit složku: %s" #: photofilmstrip/gui/DlgNewProject.py:166 msgid "Cannot write into folder!" msgstr "Nelze zapisovat do složky!" #: photofilmstrip/gui/DlgNewProject.py:180 msgid "The project name must be filled." msgstr "Název projektu musí být zadán." #: photofilmstrip/gui/DlgNewProject.py:186 msgid "The project name contains invalid characters." msgstr "Název projektu obsahuje neplatné znaky." #: photofilmstrip/gui/DlgPicDurationByAudio.py:23 #: photofilmstrip/gui/PnlSlideshow.py:54 photofilmstrip/gui/PnlSlideshow.py:55 msgid "Adjust picture durations" msgstr "Přizpůsobit doby trvání obrázků" #: photofilmstrip/gui/DlgPicDurationByAudio.py:26 msgid "Adjust picture durations to audio file" msgstr "Přizpůsobit doby trvání obrázků zvukovému souboru" #: photofilmstrip/gui/DlgPicDurationByAudio.py:30 msgid "" "Find your picture duration by playing the audio file of your project and\n" "pressing the hit button to apply the current playing time." msgstr "" "Najít dobu trvání obrázku přehráváním zvukového souboru projektu a \n" "stisknutím tlačítka pro udeření pro použití nynější doby přehrávání." #: photofilmstrip/gui/DlgPicDurationByAudio.py:43 #: photofilmstrip/gui/DlgPicDurationByAudio.py:153 msgid "Play" msgstr "Přehrát" #: photofilmstrip/gui/DlgPicDurationByAudio.py:46 msgid "Hit" msgstr "Udeřit" #: photofilmstrip/gui/DlgPicDurationByAudio.py:100 msgid "Stop" msgstr "Zastavit" #: photofilmstrip/gui/DlgPicDurationByAudio.py:179 msgid "Playing time" msgstr "Čas přehrávání" #: photofilmstrip/gui/DlgPicDurationByAudio.py:207 msgid "Your project does not have an audio file configured." msgstr "Váš projekt nemá nastaven zvukový soubor." #: photofilmstrip/gui/DlgPicDurationByAudio.py:215 msgid "" "Your project uses more than one audio file. Currently the durations can be " "adjusted only for one audio file." msgstr "" "Váš projekt používá více než jeden zvukový soubor. V současnosti mohou být " "doby trvání přizpůsobeny jen pro jeden zvukový soubor." #: photofilmstrip/gui/DlgPositionInput.py:140 msgid "Motion positions" msgstr "Polohy pohybů" #: photofilmstrip/gui/DlgPositionInput.py:147 msgid "Start position" msgstr "Poloha začátku" #: photofilmstrip/gui/DlgPositionInput.py:155 #: photofilmstrip/gui/DlgPositionInput.py:199 msgid "Location:" msgstr "Umístění:" #: photofilmstrip/gui/DlgPositionInput.py:173 #: photofilmstrip/gui/DlgPositionInput.py:215 msgid "Size:" msgstr "Velikost:" #: photofilmstrip/gui/DlgPositionInput.py:191 msgid "End position" msgstr "Poloha konce" #: photofilmstrip/gui/DlgPositionInput.py:233 msgid "Reset" msgstr "Obnovit výchozí" #: photofilmstrip/gui/DlgPositionInput.py:252 msgid "Adjust motion positions directly" msgstr "Přizpůsobit cestu pohybu ručně" #: photofilmstrip/gui/DlgRender.py:96 msgid "Render project" msgstr "Zpracovat projekt" #: photofilmstrip/gui/DlgRender.py:107 msgid "Format:" msgstr "Formát:" #: photofilmstrip/gui/DlgRender.py:122 msgid "Properties" msgstr "Vlastnosti" #: photofilmstrip/gui/DlgRender.py:127 msgid "Profile:" msgstr "Profil:" #: photofilmstrip/gui/DlgRender.py:136 msgid "Draft" msgstr "Návrh" #: photofilmstrip/gui/DlgRender.py:152 msgid "&Start" msgstr "&Spustit" #: photofilmstrip/gui/DlgRender.py:164 msgid "Configure output and start render process" msgstr "Nastavit výstup a zahájit postup zpracování" #: photofilmstrip/gui/DlgRendererProps.py:50 msgid "Property" msgstr "Vlastnost" #: photofilmstrip/gui/DlgRendererProps.py:52 msgid "Value" msgstr "Hodnota" #: photofilmstrip/gui/DlgRendererProps.py:71 msgid "Output properties" msgstr "Výstupní vlastnosti" #: photofilmstrip/gui/DlgRendererProps.py:113 msgid "Edit extended output properties" msgstr "Upravit rozšířené vlastnosti výstupu" #: photofilmstrip/gui/DlgRendererProps.py:147 msgid "Edit property" msgstr "Upravit vlastnost" #: photofilmstrip/gui/FrmMain.py:83 msgid "Welcome" msgstr "Vítejte" #: photofilmstrip/gui/FrmMain.py:85 msgid "Job queue" msgstr "Řada úloh" #: photofilmstrip/gui/FrmMain.py:141 msgid "Rendering in progress..." msgstr "Probíhá zpracování..." #: photofilmstrip/gui/FrmMain.py:234 photofilmstrip/gui/PnlWelcome.py:57 msgid "Create new slideshow" msgstr "Vytvořit nové promítání" #: photofilmstrip/gui/FrmMain.py:241 msgid "Create new timelapse" msgstr "Vytvořit nový časový úsek" #: photofilmstrip/gui/FrmMain.py:249 msgid "Select %s-Project" msgstr "Vybrat %s-Projekt" #: photofilmstrip/gui/FrmMain.py:251 msgid "Files" msgstr "Soubory" #: photofilmstrip/gui/FrmMain.py:289 msgid "You must restart %s for your new language setting to take effect." msgstr "Musíte %s spustit znovu, aby se nové jazykové nastavení projevilo." #: photofilmstrip/gui/FrmMain.py:300 msgid "" "PhotoFilmStrip creates movies out of your pictures in just 3 steps. First " "select your photos, customize the motion path and render the video. There " "are several output possibilities for VCD, SVCD, DVD up to FULL-HD." msgstr "" "PhotoFilmStrip vytváří filmy z vašich fotek v pouhých 3 krocích. Nejprve " "vyberte vaše fotky, upravte cesty pohybu a zpracujte obrazový záznam. Lze " "použít mnoho výstupních možností pro VCD, SVCD, DVD, až po FULL-HD." #: photofilmstrip/gui/FrmMain.py:303 msgid "online" msgstr "Připojen" #: photofilmstrip/gui/FrmMain.py:374 msgid "Invalid %(app)s-Project: %(file)s" msgstr "Špatný %(app)s-Projekt: %(file)s" #: photofilmstrip/gui/PnlAddPics.py:50 photofilmstrip/gui/PnlWelcome.py:30 msgid "Welcome to PhotoFilmStrip" msgstr "Vítejte ve PhotoFilmStrip" #: photofilmstrip/gui/PnlAddPics.py:52 msgid "" "Drag some pictures onto this text or\n" "click the button below\n" "to add pictures to your new PhotoFilmStrip." msgstr "" "Na tento text přetáhněte obrázky nebo\n" "stiskněte tlačítko níže\n" "pro vytvoření nového filmového pásu." #: photofilmstrip/gui/PnlEditPicture.py:142 msgid "Settings" msgstr "Nastavení" #: photofilmstrip/gui/PnlEditPicture.py:146 msgid "Rotation:" msgstr "Otočení:" #: photofilmstrip/gui/PnlEditPicture.py:166 msgid "Effect:" msgstr "Efekt:" #: photofilmstrip/gui/PnlEditPicture.py:180 msgid "Process" msgstr "Průběh obrazu" #: photofilmstrip/gui/PnlEditPicture.py:184 msgid "Movement:" msgstr "Pohyb:" #: photofilmstrip/gui/PnlEditPicture.py:196 #: photofilmstrip/gui/PnlEditPicture.py:212 #: photofilmstrip/gui/PnlEditPicture.py:359 msgid "sec" msgstr "s" #: photofilmstrip/gui/PnlEditPicture.py:200 msgid "Transition:" msgstr "Přechod:" #: photofilmstrip/gui/PnlEditPicture.py:220 msgid "Subtitle" msgstr "Titulky" #: photofilmstrip/gui/PnlEditPicture.py:240 msgid "Linear" msgstr "Lineární" #: photofilmstrip/gui/PnlEditPicture.py:241 msgid "Accelerated" msgstr "Zrychlený" #: photofilmstrip/gui/PnlEditPicture.py:242 msgid "Delayed" msgstr "Zpožděný" #: photofilmstrip/gui/PnlEditPicture.py:250 msgid "No effect" msgstr "Bez efektu" #: photofilmstrip/gui/PnlEditPicture.py:251 msgid "Black and White" msgstr "Černobílé" #: photofilmstrip/gui/PnlEditPicture.py:252 msgid "Sepia tone" msgstr "Sépiové tónování" #: photofilmstrip/gui/PnlEditPicture.py:258 msgid "None" msgstr "Žádný" #: photofilmstrip/gui/PnlEditPicture.py:259 msgid "Fade" msgstr "Prolínání" #: photofilmstrip/gui/PnlEditPicture.py:260 msgid "Roll" msgstr "Svinout" #: photofilmstrip/gui/PnlEditPicture.py:354 msgid "fpp" msgstr "SNO" #: photofilmstrip/gui/PnlEditPicture.py:355 msgid "frames per picture - the number of frames each picture will be shown" msgstr "" "snímků na obrázek - počet jednotlivých snímků, kterými bude každý obrázek " "ukazován" #: photofilmstrip/gui/PnlEditorPage.py:26 msgid "Could not save the file '%(file)s': %(errMsg)s" msgstr "Nepodařilo se uložit soubor '%(file)s': %(errMsg)s" #: photofilmstrip/gui/PnlEditorPage.py:45 msgid "New file" msgstr "Nový soubor" #: photofilmstrip/gui/PnlEditorPage.py:48 msgid "'%s' has been modified. Save changes?" msgstr "'%s' byl změněn. Uložit změny?" #: photofilmstrip/gui/PnlEditorPage.py:74 msgid "Save %s" msgstr "Uložit %s" #: photofilmstrip/gui/PnlEditorPage.py:77 msgid "File" msgstr "Soubor" #: photofilmstrip/gui/PnlEditorPage.py:87 msgid "Overwrite existing file '%s'?" msgstr "Přepsat stávající soubor '%s'?" #: photofilmstrip/gui/PnlPfsProject.py:118 #: photofilmstrip/gui/PnlPfsProject.py:120 msgid "Set motion start to end" msgstr "Nastavit začátek pohybu po konec" #: photofilmstrip/gui/PnlPfsProject.py:122 #: photofilmstrip/gui/PnlPfsProject.py:124 msgid "Set motion end to start" msgstr "Nastavit konec pohybu po začátek" #: photofilmstrip/gui/PnlPfsProject.py:126 #: photofilmstrip/gui/PnlPfsProject.py:128 msgid "Swap motion" msgstr "Vyměnit výběr začátku a cíle" #: photofilmstrip/gui/PnlPfsProject.py:131 #: photofilmstrip/gui/PnlPfsProject.py:133 msgid "Adjust motion manual" msgstr "Zadat pohyb ručně" #: photofilmstrip/gui/PnlPfsProject.py:136 #: photofilmstrip/gui/PnlPfsProject.py:138 msgid "Preserve image dimension" msgstr "Zachovat rozměry obrázku" #: photofilmstrip/gui/PnlPfsProject.py:294 msgid "&Import Pictures" msgstr "&Zavést obrázky" #: photofilmstrip/gui/PnlPfsProject.py:299 msgid "Move picture &left" msgstr "Posunout obrázek do&leva" #: photofilmstrip/gui/PnlPfsProject.py:303 msgid "Move picture &right" msgstr "Posunout obrázek do&prava" #: photofilmstrip/gui/PnlPfsProject.py:308 msgid "R&emove Picture" msgstr "O&dstranit obrázek" #: photofilmstrip/gui/PnlPfsProject.py:313 msgid "Rotate &clockwise" msgstr "&Otočit obrázek vpravo" #: photofilmstrip/gui/PnlPfsProject.py:317 msgid "Rotate counter clock&wise" msgstr "O&točit obrázek vlevo" #: photofilmstrip/gui/PnlPfsProject.py:322 msgid "Random &motion" msgstr "Náhodný &pohyb" #: photofilmstrip/gui/PnlPfsProject.py:326 msgid "Centralize m&otion" msgstr "Vystředit &výběr" #: photofilmstrip/gui/PnlPfsProject.py:384 msgid "Export slideshow" msgstr "Vyvést promítání" #: photofilmstrip/gui/PnlPfsProject.py:387 #: photofilmstrip/gui/PnlPfsProject.py:400 msgid "Portable slideshow" msgstr "Přenositelné promítání" #: photofilmstrip/gui/PnlPfsProject.py:398 msgid "Import Slideshow" msgstr "Zavést promítání" #: photofilmstrip/gui/PnlPfsProject.py:409 msgid "Import images" msgstr "Zavést obrázky" #: photofilmstrip/gui/PnlPfsProject.py:411 msgid "Image files" msgstr "Soubory s obrázky" #: photofilmstrip/gui/PnlPfsProject.py:654 msgid "Audio file '%s' does not exist! Continue anyway?" msgstr "Zvukový soubor '%s' neexistuje! Přesto pokračovat?" #: photofilmstrip/gui/PnlPfsProject.py:655 msgid "Warning" msgstr "Varování" #: photofilmstrip/gui/PnlSlideshow.py:30 msgid "&Properties" msgstr "&Vlastnosti" #: photofilmstrip/gui/PnlSlideshow.py:39 photofilmstrip/gui/PnlSlideshow.py:40 #: photofilmstrip/gui/PnlTimelapse.py:25 photofilmstrip/gui/PnlTimelapse.py:26 msgid "Import Pictures" msgstr "Zavést obrázky" #: photofilmstrip/gui/PnlSlideshow.py:62 photofilmstrip/gui/PnlSlideshow.py:63 #: photofilmstrip/gui/PnlTimelapse.py:41 photofilmstrip/gui/PnlTimelapse.py:42 msgid "Render filmstrip" msgstr "Zpracovat filmový pás" #: photofilmstrip/gui/PnlSlideshow.py:89 photofilmstrip/gui/PnlTimelapse.py:66 msgid "Images" msgstr "Obrázky" #: photofilmstrip/gui/PnlSlideshow.py:94 msgid "Duration" msgstr "Doba trvání" #: photofilmstrip/gui/PnlTimelapse.py:69 msgid "Frames" msgstr "Snímky" #: photofilmstrip/gui/PnlTimelapse.py:92 msgid "The picture counter is not increasing: %s" msgstr "Počítadlo obrázků neroste: %s" #: photofilmstrip/gui/PnlTimelapse.py:110 msgid "" "Filename '%s' does not match a number pattern which is necessary for a time " "lapse slide show!" msgstr "" "Název souboru '%s' neodpovídá číselnému vzoru, který je nezbytný pro " "promítaní časových úseků!" #: photofilmstrip/gui/PnlWelcome.py:37 photofilmstrip/gui/PnlWelcome.py:103 msgid "Recent projects" msgstr "Nedávné projekty" #: photofilmstrip/gui/PnlWelcome.py:62 msgid "Open existing project" msgstr "Otevřít stávající projekt" #: photofilmstrip/gui/PnlWelcome.py:106 msgid "How to start..." msgstr "Jak začít..." #: photofilmstrip/gui/PnlWelcome.py:107 msgid "Create a new project or load an existing one." msgstr "Vytvořit nový projekt nebo nahrát stávající." #: photofilmstrip/gui/PnlWelcome.py:138 msgid "Update available" msgstr "Dostupná aktualizace" #: photofilmstrip/gui/PnlWelcome.py:141 msgid "The following changes has been made:" msgstr "Byly provedeny následující změny:" #: photofilmstrip/gui/WxProjectFile.py:59 msgid "Loading project %s" msgstr "Nahrává se projekt %s" #: photofilmstrip/gui/WxProjectFile.py:75 msgid "Saving project %s" msgstr "Uložit projekt %s" #: photofilmstrip/gui/WxProjectFile.py:100 msgid "" "Some images does not exist in the folder '%s' anymore. If the files has " "moved you can select the new path. Do you want to select a new path?" msgstr "" "Některé obrázky v adresáři '%s' již neexistují. Pokud byly přesunuty, můžete " "vybrat novou cestu. Chcete vybrat novou cestu?" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:73 msgid "Elapsed time" msgstr "Uplynulý čas" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:85 msgid "Remaining time" msgstr "Zbývající čas" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:203 msgid "Unknown" msgstr "Neznámý" #: photofilmstrip/lib/jobimpl/PnlJobManager.py:50 msgid "&Clear list" msgstr "&Vyprázdnit seznam" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:127 msgid "Abort" msgstr "Přerušit" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:133 msgid "Remove from list" msgstr "Odstranit ze seznamu" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:223 msgid "Abort selected process?" msgstr "Odstranit vybraný proces?" #: photofilmstrip/lib/jobimpl/VisualJob.py:29 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:25 msgid "Waiting..." msgstr "Čeká se..." #: photofilmstrip/lib/jobimpl/VisualJob.py:68 #: photofilmstrip/lib/jobimpl/VisualJob.py:85 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:60 msgid "Aborted" msgstr "Přerušeno" #: photofilmstrip/lib/jobimpl/VisualJob.py:70 msgid "Done" msgstr "Hotovo" #: photofilmstrip/lib/jobimpl/VisualJob.py:79 msgid "Aborting..." msgstr "Přerušuje se..." #: photofilmstrip/ux/gnome.py:50 photofilmstrip/ux/uwp.py:66 msgid "Slideshow created!" msgstr "Promítání vytvořeno!" #~ msgid "FLV-Muxer (gstreamer1.0-plugins-good) required!" #~ msgstr "Požadován FLV-Muxer (gstreamer1.0-plugins-good)!" #, fuzzy #~ msgid "Audio files:" #~ msgstr "Zvukové soubory" #, fuzzy #~ msgid "Project properties" #~ msgstr "Parametr" #, fuzzy #~ msgid "PhotoFilmStrip project" #~ msgstr "Nepojmenované video" #~ msgid "Unnamed PhotoFilmStrip" #~ msgstr "Nepojmenované video" #~ msgid "Project" #~ msgstr "Projekt" #~ msgid "invalid videonorm specified: %s" #~ msgstr "specifikována špatná video norma: %s" #~ msgid "Error: %s" #~ msgstr "Chyba: %s" #~ msgid "Please wait..." #~ msgstr "Prosím čekejte..." #~ msgid "initialize renderer" #~ msgstr "Iniciuji renderer" #~ msgid "creating output..." #~ msgstr "vytvářím výstup..." #~ msgid "mencoder (mencoder) required!" #~ msgstr "mencoder (mencoder) vyžadován!" #~ msgid "MPEG(1/2)-Video (MPG)" #~ msgstr "MPEG(1/2)-Video (MPG)" #~ msgid "MPEG4-XVid/AC3 (AVI)" #~ msgstr "MPEG4-XVid/AC3 (AVI)" #, fuzzy #~ msgid "mencoder with MP3 support (mp3lame) required!" #~ msgstr "mencoder (mencoder) vyžadován!" #~ msgid "MPEG4-XVid/MP3 (AVI)" #~ msgstr "MPEG4-XVid/MP3 (AVI)" #~ msgid "&Tools" #~ msgstr "&Nástroje" #~ msgid "New Project" #~ msgstr "Nový projekt" #~ msgid "Save Project" #~ msgstr "Uložit projekt" #~ msgid "&New Project" #~ msgstr "&Nový projekt" #~ msgid "&Open Project" #~ msgstr "&Otevřít projekt" #~ msgid "&Save Project" #~ msgstr "&Uložit projekt" #, fuzzy #~ msgid "&Close Project" #~ msgstr "&Nový projekt" #~ msgid "&Render filmstrip" #~ msgstr "&Renderovat video" #~ msgid "Audio file:" #~ msgstr "Zvukový soubor:" #~ msgid "Type:" #~ msgstr "Typ:" #~ msgid "&Batch Job" #~ msgstr "&Dávka" #~ msgid "" #~ "Project not saved yet. Please save the project first to create a batch " #~ "job!" #~ msgstr "" #~ "Projekt není ještě uložen. Prosím uložte nejprve projekt pro vytvoření " #~ "dávkové úlohy." #~ msgid "Batch file" #~ msgstr "Dávkový soubor" #~ msgid "Shell script" #~ msgstr "Skript" #~ msgid "Select batch file" #~ msgstr "Vybrat dávkový soubor" #~ msgid "Export %s-Project" #~ msgstr "Exportovat %s-Projekt" #~ msgid "Import %s-Project" #~ msgstr "Importovat %s-Projekt" #, fuzzy #~ msgid "Duration:" #~ msgstr "Trvání" #~ msgid "Browse" #~ msgstr "Prohlížet" #~ msgid "Import image" #~ msgstr "Importovat obrázek" #~ msgid "Please wait" #~ msgstr "Prosím čekejte" #~ msgid "Loading pictures..." #~ msgstr "Nahrávám obrázky..." #~ msgid "Invalid audio file!" #~ msgstr "Špatný zvukový soubor!" #~ msgid "processing audiofile..." #~ msgstr "zpracovávám zvukový soubor..." #, fuzzy #~ msgid "Video clip (AVI)" #~ msgstr "Vide klip" #~ msgid "total length of the PhotoFilmStrip (seconds)" #~ msgstr "celková délka videa (v sekundách)" #~ msgid "use audiofile as audiotrack (use --length to limit the movie length)" #~ msgstr "" #~ "použít audio soubor jako zvukovou stopu (použijte parametr --length k " #~ "omezení délky videa)" #~ msgid "no outputpath specified!" #~ msgstr "není specifikovaná výstupní cesta!" #~ msgid "audio file does not exist: %s" #~ msgstr "zvukový soubor neexistuje: %s" #, fuzzy #~ msgid "Directory:" #~ msgstr "Výstupní adresář:" #, fuzzy #~ msgid "Select a directory" #~ msgstr "Výstupní adresář:" #~ msgid "No media support found on this platform!" #~ msgstr "Nenalezena mediální podpora na této platformě!" #~ msgid "Output" #~ msgstr "Výstup" #~ msgid "Translators" #~ msgstr "Překladatelé" #~ msgid "Open &recent" #~ msgstr "Otevřít &nedávné" #~ msgid "Save Project &as" #~ msgstr "Uložit projekt &jako" #~ msgid "&Import Project" #~ msgstr "&Importovat projekt" #~ msgid "&Export Project" #~ msgstr "&Exportovat projekt" #~ msgid "Sec." #~ msgstr "Sekund." #~ msgid "Output path is not empty! Use it anyway?" #~ msgstr "Výstupní cesta není prázdná! Přesto použít?" #~ msgid "New version available" #~ msgstr "Dostupná nová verze" #~ msgid "Close" #~ msgstr "Zavřít" #~ msgid "Goto download site" #~ msgstr "Přejít na stránku ke stažení" #~ msgid "Duration (sec):" #~ msgstr "Trvání (sekund):" #~ msgid "ppmtoy4m (mjpegtools) required!" #~ msgstr "ppmtoy4m (mjpegtools) vyžadován!" #~ msgid "mpeg2enc (mjpegtools) required!" #~ msgstr "mpeg2enc (mjpegtools) vyžadován!" photofilmstrip-3.7.2/po/pt_BR.po0000644000232200023220000007200513560357351017154 0ustar debalancedebalance# Brazilian Portuguese translation for photofilmstrip # Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 # This file is distributed under the same license as the photofilmstrip package. # FIRST AUTHOR , 2012. # msgid "" msgstr "" "Project-Id-Version: PhotoFilmStrip\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2018-11-07 22:03+CET\n" "PO-Revision-Date: 2012-12-05 23:10+0100\n" "Last-Translator: Jens Göpfert \n" "Language-Team: Brazilian Portuguese \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2012-12-05 22:00+0000\n" "X-Generator: Launchpad (build 16341)\n" #: photofilmstrip/action/ActionAutoPath.py:23 #: photofilmstrip/gui/PnlPfsProject.py:115 msgid "Random motion" msgstr "Movimento aleatório" #: photofilmstrip/action/ActionCenterPath.py:21 msgid "Centralize motion" msgstr "" #: photofilmstrip/action/ActionI18N.py:24 #: photofilmstrip/gui/ActionManager.py:170 msgid "Language" msgstr "Idioma" #: photofilmstrip/action/ActionOpenFolder.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:28 msgid "Open folder" msgstr "Abrir pasta" #: photofilmstrip/action/ActionPlayVideo.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:22 msgid "Play video" msgstr "Reproduzir vídeo" #: photofilmstrip/action/ActionRender.py:37 #, fuzzy msgid "Start" msgstr "&Iniciar" #: photofilmstrip/cli/Main.py:46 photofilmstrip/cli/Main.py:196 msgid "all done" msgstr "tudo pronto" #: photofilmstrip/cli/Main.py:64 msgid "processing project" msgstr "processando o projeto" #: photofilmstrip/cli/Main.py:65 msgid "using renderer" msgstr "usando o renderizador" #: photofilmstrip/cli/Main.py:66 msgid "output format" msgstr "formato de saída" #: photofilmstrip/cli/Main.py:69 msgid "framerate" msgstr "taxa de quadros" #: photofilmstrip/cli/Main.py:103 msgid "specifies the project file" msgstr "especifica o arquivo de projeto" #: photofilmstrip/cli/Main.py:104 msgid "The path where to save the output files. Use - for stdout." msgstr "O caminho onde salvar os arquivos de saída. Utilize - para stdout." #: photofilmstrip/cli/Main.py:106 photofilmstrip/cli/Main.py:129 msgid "Option videonorm is deprecated, use an appropriate profile!" msgstr "" #: photofilmstrip/cli/Main.py:108 msgid "enable draft mode" msgstr "habiltar modo rascunho" #: photofilmstrip/cli/Main.py:108 photofilmstrip/gui/DlgRender.py:167 msgid "" "Activate this option to generate a preview of your PhotoFilmStrip. The " "rendering process will speed up dramatically, but results in lower quality." msgstr "" "Ative essa opção para gerar uma pré-visualização do seu PhotoFilmStrip. O " "processo de renderização irá acelerar drasticamente, mas resulta em menor " "qualidade." #: photofilmstrip/cli/Main.py:120 msgid "project file does not exist: %s" msgstr "o arquivo de projeto não existe: %s" #: photofilmstrip/cli/Main.py:124 msgid "no project file specified!" msgstr "nenhum arquivo de projeto espeficado!" #: photofilmstrip/cli/Main.py:134 msgid "invalid format specified: %s" msgstr "formato especificado inválido: %s" #: photofilmstrip/cli/Main.py:140 msgid "invalid profile specified: %s" msgstr "perfil especificado inválido: %s" #: photofilmstrip/cli/Main.py:146 #, fuzzy msgid "cannot load project" msgstr "não foi possível carregar o photofilmstrip" #: photofilmstrip/cli/Main.py:159 msgid "cannot create output path: %s" msgstr "não foi possível criar o caminho de saída: %s" #: photofilmstrip/cli/Main.py:169 photofilmstrip/gui/DlgConfigureAudio.py:231 #: photofilmstrip/gui/DlgConfigureAudio.py:253 msgid "Audio file '%s' does not exist!" msgstr "O arquivo de áudio '%s' não existe!" #: photofilmstrip/cli/Main.py:190 msgid "...aborted!" msgstr "... abortado!" #: photofilmstrip/core/BaseRenderer.py:50 msgid "Unknown property: %s" msgstr "Propriedade desconhecida: %s" #: photofilmstrip/core/BaseRenderer.py:58 msgid "" msgstr "" #: photofilmstrip/core/BaseRenderer.py:73 msgid "no" msgstr "não" #: photofilmstrip/core/ProjectFile.py:222 #, fuzzy msgid "Saving '%s' ..." msgstr "Carregando '%s' ..." #: photofilmstrip/core/ProjectFile.py:276 msgid "Loading '%s' ..." msgstr "Carregando '%s' ..." #: photofilmstrip/core/RenderEngine.py:113 #: photofilmstrip/core/RenderEngine.py:201 msgid "processing transition %d/%d" msgstr "processando transição %d/%d" #: photofilmstrip/core/RenderEngine.py:124 #: photofilmstrip/core/RenderEngine.py:210 msgid "processing image %d/%d" msgstr "processando imagem %d/%d" #: photofilmstrip/core/renderer/CairoRenderer.py:35 msgid "Preview" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:50 msgid "GStreamer (python-gst-1.0) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:287 msgid "Bitrate must be a number!" msgstr "A taxa de bits deve ser um número!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:455 #: photofilmstrip/core/renderer/GStreamerRenderer.py:531 #: photofilmstrip/core/renderer/GStreamerRenderer.py:601 #: photofilmstrip/core/renderer/GStreamerRenderer.py:690 #: photofilmstrip/core/renderer/GStreamerRenderer.py:730 #: photofilmstrip/core/renderer/GStreamerRenderer.py:779 msgid "libav (gstreamer1.0-libav) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:459 #: photofilmstrip/core/renderer/GStreamerRenderer.py:535 #: photofilmstrip/core/renderer/GStreamerRenderer.py:605 msgid "x264-Codec (gstreamer1.0-plugins-ugly) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:463 #: photofilmstrip/core/renderer/GStreamerRenderer.py:609 msgid "MKV-Muxer (gstreamer1.0-plugins-good) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:539 msgid "MP4-Muxer (gstreamer1.0-plugins-good) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:647 msgid "Theora-Codec (gstreamer1.0-plugins-base) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:651 msgid "Vorbis-Codec (gstreamer1.0-plugins-base) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:655 msgid "OGV-Muxer (gstreamer1.0-plugins-base) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:686 #: photofilmstrip/core/renderer/GStreamerRenderer.py:726 #: photofilmstrip/core/renderer/GStreamerRenderer.py:775 msgid "MPEG-1/2-Codec (gstreamer1.0-plugins-bad) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:694 #: photofilmstrip/core/renderer/GStreamerRenderer.py:734 #: photofilmstrip/core/renderer/GStreamerRenderer.py:783 msgid "MPEG-Muxer (gstreamer1.0-plugins-bad) required!" msgstr "" #: photofilmstrip/core/renderer/SingleFileRenderer.py:21 msgid "Single pictures" msgstr "Imagens simples" #: photofilmstrip/core/tasks.py:48 msgid "generating subtitle" msgstr "gerando legenda" #: photofilmstrip/gui/ActionManager.py:60 #: photofilmstrip/gui/ActionManager.py:190 msgid "&File" msgstr "&Arquivo" #: photofilmstrip/gui/ActionManager.py:61 #: photofilmstrip/gui/ActionManager.py:191 msgid "&Edit" msgstr "&Editar" #: photofilmstrip/gui/ActionManager.py:62 #: photofilmstrip/gui/ActionManager.py:154 photofilmstrip/gui/DlgRender.py:141 #: photofilmstrip/gui/DlgRendererProps.py:86 msgid "&Help" msgstr "A&juda" #: photofilmstrip/gui/ActionManager.py:76 msgid "New Slideshow" msgstr "" #: photofilmstrip/gui/ActionManager.py:81 msgid "Open" msgstr "" #: photofilmstrip/gui/ActionManager.py:87 msgid "Save" msgstr "" #: photofilmstrip/gui/ActionManager.py:97 #: photofilmstrip/gui/ActionManager.py:98 msgid "Show job queue" msgstr "" #: photofilmstrip/gui/ActionManager.py:108 #: photofilmstrip/gui/PnlSlideshow.py:25 msgid "Slideshow" msgstr "" #: photofilmstrip/gui/ActionManager.py:110 #: photofilmstrip/gui/PnlTimelapse.py:18 msgid "Timelapse" msgstr "" #: photofilmstrip/gui/ActionManager.py:116 msgid "New" msgstr "" #: photofilmstrip/gui/ActionManager.py:118 msgid "&Open" msgstr "" #: photofilmstrip/gui/ActionManager.py:123 msgid "&Save" msgstr "" #: photofilmstrip/gui/ActionManager.py:136 msgid "&Close" msgstr "&Fechar" #: photofilmstrip/gui/ActionManager.py:141 msgid "E&xit" msgstr "Sai&r" #: photofilmstrip/gui/ActionManager.py:173 msgid "&About" msgstr "&Sobre" #: photofilmstrip/gui/DlgBugReport.py:41 msgid "An unexpected error occured" msgstr "Ocorreu um erro inesperado" #: photofilmstrip/gui/DlgBugReport.py:44 msgid "" "An unexpected error occured. Do you want to send this bug report to the " "developers of %s?" msgstr "" "Ocorreu um erro inesperado. Você deseja enviar este relatório de bug para os " "desenvolvedores de %s?" #: photofilmstrip/gui/DlgBugReport.py:99 msgid "Bug-Report send. Thank you for your support." msgstr "" #: photofilmstrip/gui/DlgBugReport.py:100 photofilmstrip/gui/FrmMain.py:290 msgid "Information" msgstr "Informações" #: photofilmstrip/gui/DlgBugReport.py:106 msgid "Sorry, this function is temporary not available.." msgstr "Desculpe, esta função não está temporariamente disponível..." #: photofilmstrip/gui/DlgBugReport.py:107 #: photofilmstrip/gui/DlgConfigureAudio.py:232 #: photofilmstrip/gui/DlgConfigureAudio.py:244 #: photofilmstrip/gui/DlgConfigureAudio.py:254 #: photofilmstrip/gui/DlgNewProject.py:156 #: photofilmstrip/gui/DlgNewProject.py:167 #: photofilmstrip/gui/DlgPicDurationByAudio.py:208 #: photofilmstrip/gui/DlgPicDurationByAudio.py:216 #: photofilmstrip/gui/FrmMain.py:376 photofilmstrip/gui/PnlPfsProject.py:468 #: photofilmstrip/gui/PnlTimelapse.py:113 msgid "Error" msgstr "Erro" #: photofilmstrip/gui/DlgConfigureAudio.py:55 msgid "Configure your audio files that are used as a background music." msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:90 msgid "Set the duration of your slideshow to fit your audio files" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:92 #: photofilmstrip/gui/DlgDuration.py:70 photofilmstrip/gui/DlgNewProject.py:84 #: photofilmstrip/gui/DlgPicDurationByAudio.py:50 #: photofilmstrip/gui/DlgPositionInput.py:238 #: photofilmstrip/gui/DlgRender.py:147 #: photofilmstrip/gui/DlgRendererProps.py:92 #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:97 msgid "&Cancel" msgstr "&Cancelar" #: photofilmstrip/gui/DlgConfigureAudio.py:97 #: photofilmstrip/gui/DlgDuration.py:72 photofilmstrip/gui/DlgNewProject.py:86 #: photofilmstrip/gui/DlgPicDurationByAudio.py:51 #: photofilmstrip/gui/DlgPositionInput.py:244 #: photofilmstrip/gui/DlgRendererProps.py:97 msgid "&Ok" msgstr "&OK" #: photofilmstrip/gui/DlgConfigureAudio.py:104 #: photofilmstrip/gui/DlgConfigureAudio.py:109 #: photofilmstrip/gui/PnlSlideshow.py:47 photofilmstrip/gui/PnlSlideshow.py:48 #: photofilmstrip/gui/PnlTimelapse.py:33 photofilmstrip/gui/PnlTimelapse.py:34 msgid "Configure music" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:138 msgid "Select music" msgstr "Selecionar música" #: photofilmstrip/gui/DlgConfigureAudio.py:140 msgid "Audio files" msgstr "Arquivos de áudio" #: photofilmstrip/gui/DlgConfigureAudio.py:243 msgid "Audio file not supported!" msgstr "Arquivo de áudio não suportado!" #: photofilmstrip/gui/DlgDuration.py:48 msgid "Total length:" msgstr "Comprimento total:" #: photofilmstrip/gui/DlgDuration.py:50 msgid "" "Overrides the duration of single pictures and gives the project this total " "length." msgstr "" "Substitui a duração de imagens simples e dá ao projeto este comprimento " "total." #: photofilmstrip/gui/DlgDuration.py:54 msgid "User defined:" msgstr "Definido pelo usuário:" #: photofilmstrip/gui/DlgDuration.py:65 #, fuzzy msgid "Fit to audio files" msgstr "Arquivos de áudio" #: photofilmstrip/gui/DlgDuration.py:80 msgid "Slideshow duration" msgstr "" #: photofilmstrip/gui/DlgDuration.py:84 msgid "Configure duration of slideshow" msgstr "" #: photofilmstrip/gui/DlgNewProject.py:61 msgid "Project name:" msgstr "Nome do projeto:" #: photofilmstrip/gui/DlgNewProject.py:66 msgid "Folder:" msgstr "Pasta:" #: photofilmstrip/gui/DlgNewProject.py:78 msgid "Aspect ratio:" msgstr "Taxa de proporção:" #: photofilmstrip/gui/DlgNewProject.py:110 #, fuzzy msgid "Unnamed project" msgstr "não foi possível carregar o photofilmstrip" #: photofilmstrip/gui/DlgNewProject.py:116 msgid "My PhotoFilmStrips" msgstr "Meu PhotoFilmStrips" #: photofilmstrip/gui/DlgNewProject.py:126 msgid "Browse for folder" msgstr "Navegar por pasta" #: photofilmstrip/gui/DlgNewProject.py:145 msgid "Folder does not exists! Do you want %s to create it?" msgstr "A pasta não existe! Você deseja criar %s?" #: photofilmstrip/gui/DlgNewProject.py:146 #: photofilmstrip/gui/PnlEditorPage.py:29 #: photofilmstrip/gui/PnlEditorPage.py:49 #: photofilmstrip/gui/PnlEditorPage.py:88 #: photofilmstrip/gui/WxProjectFile.py:101 #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:224 msgid "Question" msgstr "Pergunta" #: photofilmstrip/gui/DlgNewProject.py:155 msgid "Cannot create folder: %s" msgstr "Não foi possível criar pasta: %s" #: photofilmstrip/gui/DlgNewProject.py:166 msgid "Cannot write into folder!" msgstr "Não foi possível escreve na pasta!" #: photofilmstrip/gui/DlgNewProject.py:180 msgid "The project name must be filled." msgstr "O nome do projeto deve ser preenchido." #: photofilmstrip/gui/DlgNewProject.py:186 msgid "The project name contains invalid characters." msgstr "O nome do projeto contém caracteres inválidos." #: photofilmstrip/gui/DlgPicDurationByAudio.py:23 #: photofilmstrip/gui/PnlSlideshow.py:54 photofilmstrip/gui/PnlSlideshow.py:55 msgid "Adjust picture durations" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:26 msgid "Adjust picture durations to audio file" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:30 msgid "" "Find your picture duration by playing the audio file of your project and\n" "pressing the hit button to apply the current playing time." msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:43 #: photofilmstrip/gui/DlgPicDurationByAudio.py:153 msgid "Play" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:46 msgid "Hit" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:100 msgid "Stop" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:179 #, fuzzy msgid "Playing time" msgstr "Reproduzir vídeo" #: photofilmstrip/gui/DlgPicDurationByAudio.py:207 msgid "Your project does not have an audio file configured." msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:215 msgid "" "Your project uses more than one audio file. Currently the durations can be " "adjusted only for one audio file." msgstr "" #: photofilmstrip/gui/DlgPositionInput.py:140 msgid "Motion positions" msgstr "Posições de movimentos" #: photofilmstrip/gui/DlgPositionInput.py:147 msgid "Start position" msgstr "Posição inicial" #: photofilmstrip/gui/DlgPositionInput.py:155 #: photofilmstrip/gui/DlgPositionInput.py:199 msgid "Location:" msgstr "Localização:" #: photofilmstrip/gui/DlgPositionInput.py:173 #: photofilmstrip/gui/DlgPositionInput.py:215 msgid "Size:" msgstr "Tamanho:" #: photofilmstrip/gui/DlgPositionInput.py:191 msgid "End position" msgstr "Posição final" #: photofilmstrip/gui/DlgPositionInput.py:233 msgid "Reset" msgstr "Reiniciar" #: photofilmstrip/gui/DlgPositionInput.py:252 msgid "Adjust motion positions directly" msgstr "Ajustar diretamente as posições de movimento" #: photofilmstrip/gui/DlgRender.py:96 #, fuzzy msgid "Render project" msgstr "Projetos recentes" #: photofilmstrip/gui/DlgRender.py:107 msgid "Format:" msgstr "Formato:" #: photofilmstrip/gui/DlgRender.py:122 msgid "Properties" msgstr "Propriedades" #: photofilmstrip/gui/DlgRender.py:127 msgid "Profile:" msgstr "Perfil:" #: photofilmstrip/gui/DlgRender.py:136 msgid "Draft" msgstr "Rascunho" #: photofilmstrip/gui/DlgRender.py:152 msgid "&Start" msgstr "&Iniciar" #: photofilmstrip/gui/DlgRender.py:164 msgid "Configure output and start render process" msgstr "Configurar saída e início do processo de renderização" #: photofilmstrip/gui/DlgRendererProps.py:50 msgid "Property" msgstr "Propriedade" #: photofilmstrip/gui/DlgRendererProps.py:52 msgid "Value" msgstr "Valor" #: photofilmstrip/gui/DlgRendererProps.py:71 msgid "Output properties" msgstr "Propriedades de saída" #: photofilmstrip/gui/DlgRendererProps.py:113 msgid "Edit extended output properties" msgstr "Editar propriedades de saída estendida" #: photofilmstrip/gui/DlgRendererProps.py:147 msgid "Edit property" msgstr "Editar proprietário" #: photofilmstrip/gui/FrmMain.py:83 msgid "Welcome" msgstr "Bem-vindo(a)" #: photofilmstrip/gui/FrmMain.py:85 msgid "Job queue" msgstr "" #: photofilmstrip/gui/FrmMain.py:141 msgid "Rendering in progress..." msgstr "" #: photofilmstrip/gui/FrmMain.py:234 photofilmstrip/gui/PnlWelcome.py:57 #, fuzzy msgid "Create new slideshow" msgstr "Portátil" #: photofilmstrip/gui/FrmMain.py:241 #, fuzzy msgid "Create new timelapse" msgstr "Criar um novo projeto" #: photofilmstrip/gui/FrmMain.py:249 msgid "Select %s-Project" msgstr "Selecionar Projeto-%s" #: photofilmstrip/gui/FrmMain.py:251 #, fuzzy msgid "Files" msgstr "&Arquivo" #: photofilmstrip/gui/FrmMain.py:289 msgid "You must restart %s for your new language setting to take effect." msgstr "" "Você deve reiniciar %s para sua nova configuração de idioma fazer efeito." #: photofilmstrip/gui/FrmMain.py:300 msgid "" "PhotoFilmStrip creates movies out of your pictures in just 3 steps. First " "select your photos, customize the motion path and render the video. There " "are several output possibilities for VCD, SVCD, DVD up to FULL-HD." msgstr "" "O PhotoFilmStrip cria filmes das suas imagens em apenas três passos. " "Primeiro, selecione suas fotos, personalize o caminho do movimento e " "renderize o vídeo. Há várias possibilidades de saída para VCD, SVCD, DVD até " "FULL-HD." #: photofilmstrip/gui/FrmMain.py:303 msgid "online" msgstr "on-line" #: photofilmstrip/gui/FrmMain.py:374 msgid "Invalid %(app)s-Project: %(file)s" msgstr "" #: photofilmstrip/gui/PnlAddPics.py:50 photofilmstrip/gui/PnlWelcome.py:30 msgid "Welcome to PhotoFilmStrip" msgstr "Bem-vindo ao PhotoFilmStrip" #: photofilmstrip/gui/PnlAddPics.py:52 msgid "" "Drag some pictures onto this text or\n" "click the button below\n" "to add pictures to your new PhotoFilmStrip." msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:142 msgid "Settings" msgstr "Configurações" #: photofilmstrip/gui/PnlEditPicture.py:146 msgid "Rotation:" msgstr "Rotação:" #: photofilmstrip/gui/PnlEditPicture.py:166 msgid "Effect:" msgstr "Efeito:" #: photofilmstrip/gui/PnlEditPicture.py:180 msgid "Process" msgstr "Processo" #: photofilmstrip/gui/PnlEditPicture.py:184 msgid "Movement:" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:196 #: photofilmstrip/gui/PnlEditPicture.py:212 #: photofilmstrip/gui/PnlEditPicture.py:359 msgid "sec" msgstr "seg" #: photofilmstrip/gui/PnlEditPicture.py:200 msgid "Transition:" msgstr "Transição:" #: photofilmstrip/gui/PnlEditPicture.py:220 msgid "Subtitle" msgstr "Legenda" #: photofilmstrip/gui/PnlEditPicture.py:240 msgid "Linear" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:241 msgid "Accelerated" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:242 msgid "Delayed" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:250 msgid "No effect" msgstr "Sem efeito" #: photofilmstrip/gui/PnlEditPicture.py:251 msgid "Black and White" msgstr "Preto e branco" #: photofilmstrip/gui/PnlEditPicture.py:252 msgid "Sepia tone" msgstr "Tom sépia" #: photofilmstrip/gui/PnlEditPicture.py:258 msgid "None" msgstr "Nenhum" #: photofilmstrip/gui/PnlEditPicture.py:259 msgid "Fade" msgstr "Esmaecer" #: photofilmstrip/gui/PnlEditPicture.py:260 msgid "Roll" msgstr "Rolagem" #: photofilmstrip/gui/PnlEditPicture.py:354 msgid "fpp" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:355 msgid "frames per picture - the number of frames each picture will be shown" msgstr "" #: photofilmstrip/gui/PnlEditorPage.py:26 msgid "Could not save the file '%(file)s': %(errMsg)s" msgstr "Não foi possível salvar o arquivo '%(file)s': %(errMsg)s" #: photofilmstrip/gui/PnlEditorPage.py:45 msgid "New file" msgstr "" #: photofilmstrip/gui/PnlEditorPage.py:48 msgid "'%s' has been modified. Save changes?" msgstr "'%s' foi modificado. Salvar alterações?" #: photofilmstrip/gui/PnlEditorPage.py:74 #, fuzzy msgid "Save %s" msgstr "Salvar Projeto-%s" #: photofilmstrip/gui/PnlEditorPage.py:77 #, fuzzy msgid "File" msgstr "&Arquivo" #: photofilmstrip/gui/PnlEditorPage.py:87 msgid "Overwrite existing file '%s'?" msgstr "Sobrescrever o arquivo '%s' existente?" #: photofilmstrip/gui/PnlPfsProject.py:118 #: photofilmstrip/gui/PnlPfsProject.py:120 msgid "Set motion start to end" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:122 #: photofilmstrip/gui/PnlPfsProject.py:124 msgid "Set motion end to start" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:126 #: photofilmstrip/gui/PnlPfsProject.py:128 #, fuzzy msgid "Swap motion" msgstr "Movimento aleatório" #: photofilmstrip/gui/PnlPfsProject.py:131 #: photofilmstrip/gui/PnlPfsProject.py:133 msgid "Adjust motion manual" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:136 #: photofilmstrip/gui/PnlPfsProject.py:138 msgid "Preserve image dimension" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:294 msgid "&Import Pictures" msgstr "&Importar imagens" #: photofilmstrip/gui/PnlPfsProject.py:299 msgid "Move picture &left" msgstr "Mover imagem para &esquerda" #: photofilmstrip/gui/PnlPfsProject.py:303 msgid "Move picture &right" msgstr "Mover imagem para &direita" #: photofilmstrip/gui/PnlPfsProject.py:308 #, fuzzy msgid "R&emove Picture" msgstr "&Remover imagem" #: photofilmstrip/gui/PnlPfsProject.py:313 msgid "Rotate &clockwise" msgstr "Girar no sentido &horário" #: photofilmstrip/gui/PnlPfsProject.py:317 msgid "Rotate counter clock&wise" msgstr "Girar no sentido &anti-horário" #: photofilmstrip/gui/PnlPfsProject.py:322 #, fuzzy msgid "Random &motion" msgstr "Movimento aleatório" #: photofilmstrip/gui/PnlPfsProject.py:326 msgid "Centralize m&otion" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:384 msgid "Export slideshow" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:387 #: photofilmstrip/gui/PnlPfsProject.py:400 #, fuzzy msgid "Portable slideshow" msgstr "Portátil" #: photofilmstrip/gui/PnlPfsProject.py:398 #, fuzzy msgid "Import Slideshow" msgstr "Importar imagens" #: photofilmstrip/gui/PnlPfsProject.py:409 msgid "Import images" msgstr "Importar imagens" #: photofilmstrip/gui/PnlPfsProject.py:411 #, fuzzy msgid "Image files" msgstr "Arquivos de Imagem" #: photofilmstrip/gui/PnlPfsProject.py:654 msgid "Audio file '%s' does not exist! Continue anyway?" msgstr "O arquivo de áudio '%s' não existe! Continua mesmo assim?" #: photofilmstrip/gui/PnlPfsProject.py:655 msgid "Warning" msgstr "Aviso" #: photofilmstrip/gui/PnlSlideshow.py:30 msgid "&Properties" msgstr "&Propriedades" #: photofilmstrip/gui/PnlSlideshow.py:39 photofilmstrip/gui/PnlSlideshow.py:40 #: photofilmstrip/gui/PnlTimelapse.py:25 photofilmstrip/gui/PnlTimelapse.py:26 msgid "Import Pictures" msgstr "Importar imagens" #: photofilmstrip/gui/PnlSlideshow.py:62 photofilmstrip/gui/PnlSlideshow.py:63 #: photofilmstrip/gui/PnlTimelapse.py:41 photofilmstrip/gui/PnlTimelapse.py:42 msgid "Render filmstrip" msgstr "" #: photofilmstrip/gui/PnlSlideshow.py:89 photofilmstrip/gui/PnlTimelapse.py:66 msgid "Images" msgstr "Imagens" #: photofilmstrip/gui/PnlSlideshow.py:94 msgid "Duration" msgstr "Duração" #: photofilmstrip/gui/PnlTimelapse.py:69 msgid "Frames" msgstr "" #: photofilmstrip/gui/PnlTimelapse.py:92 msgid "The picture counter is not increasing: %s" msgstr "" #: photofilmstrip/gui/PnlTimelapse.py:110 msgid "" "Filename '%s' does not match a number pattern which is necessary for a time " "lapse slide show!" msgstr "" #: photofilmstrip/gui/PnlWelcome.py:37 photofilmstrip/gui/PnlWelcome.py:103 msgid "Recent projects" msgstr "Projetos recentes" #: photofilmstrip/gui/PnlWelcome.py:62 msgid "Open existing project" msgstr "Abrir um projeto existente" #: photofilmstrip/gui/PnlWelcome.py:106 msgid "How to start..." msgstr "Como iniciar..." #: photofilmstrip/gui/PnlWelcome.py:107 msgid "Create a new project or load an existing one." msgstr "Criar um novo projeto ou carregar um existente." #: photofilmstrip/gui/PnlWelcome.py:138 msgid "Update available" msgstr "Atualização disponível" #: photofilmstrip/gui/PnlWelcome.py:141 msgid "The following changes has been made:" msgstr "As seguintes alterações foram feitas:" #: photofilmstrip/gui/WxProjectFile.py:59 #, fuzzy msgid "Loading project %s" msgstr "Carregar projeto" #: photofilmstrip/gui/WxProjectFile.py:75 msgid "Saving project %s" msgstr "Salvar projeto %s" #: photofilmstrip/gui/WxProjectFile.py:100 msgid "" "Some images does not exist in the folder '%s' anymore. If the files has " "moved you can select the new path. Do you want to select a new path?" msgstr "" "Algumas imagens não existem mais na pasta '%s'. Se os arquivos foram movidos " "você pode selecionar um novo caminho. Deseja selecionar um novo caminho?" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:73 msgid "Elapsed time" msgstr "" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:85 msgid "Remaining time" msgstr "" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:203 msgid "Unknown" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobManager.py:50 msgid "&Clear list" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:127 msgid "Abort" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:133 msgid "Remove from list" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:223 msgid "Abort selected process?" msgstr "Abortar o processo atual?" #: photofilmstrip/lib/jobimpl/VisualJob.py:29 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:25 msgid "Waiting..." msgstr "" #: photofilmstrip/lib/jobimpl/VisualJob.py:68 #: photofilmstrip/lib/jobimpl/VisualJob.py:85 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:60 msgid "Aborted" msgstr "abortado" #: photofilmstrip/lib/jobimpl/VisualJob.py:70 msgid "Done" msgstr "" #: photofilmstrip/lib/jobimpl/VisualJob.py:79 msgid "Aborting..." msgstr "abortando..." #: photofilmstrip/uwp/UwpService.py:76 msgid "Slideshow created!" msgstr "" #, fuzzy #~ msgid "Audio files:" #~ msgstr "Arquivos de áudio" #~ msgid "Project properties" #~ msgstr "Propriedades do projeto" #~ msgid "PhotoFilmStrip project" #~ msgstr "Projeto do PhotoFilmStrip" #~ msgid "Unnamed PhotoFilmStrip" #~ msgstr "PhotoFilmStrip - Sem nome" #~ msgid "Project" #~ msgstr "Projeto" #~ msgid "Please wait..." #~ msgstr "Aguarde por favor..." #~ msgid "aborting..." #~ msgstr "abortando..." #~ msgid "mencoder (mencoder) required!" #~ msgstr "o mencoder (mencoder) é requerido!" #~ msgid "MPEG(1/2)-Video (MPG)" #~ msgstr "MPEG(1/2)-Video (MPG)" #~ msgid "MPEG format supports only VCD, SVCD and DVD profile!" #~ msgstr "O formato MPEG suporta somente os perfis VCD, SVCD e DVD!" #~ msgid "MPEG4-XVid/AC3 (AVI)" #~ msgstr "MPEG4-XVid/AC3 (AVI)" #~ msgid "mencoder with MP3 support (mp3lame) required!" #~ msgstr "mencoder com suporte a MP3 (mp3lame) é requerido!" #~ msgid "MPEG4-XVid/MP3 (AVI)" #~ msgstr "MPEG4-XVid/MP3 (AVI)" #~ msgid "Flash-Video (FLV)" #~ msgstr "Flash-Video (FLV)" #~ msgid "Motion-JPEG (AVI)" #~ msgstr "Motion-JPEG (AVI)" #~ msgid "&Tools" #~ msgstr "&Ferramentas" #~ msgid "New Project" #~ msgstr "Novo projeto" #~ msgid "Load Project" #~ msgstr "Carregar projeto" #~ msgid "Save Project" #~ msgstr "Salvar projeto" #~ msgid "&New Project" #~ msgstr "&Novo projeto" #~ msgid "&Open Project" #~ msgstr "&Abrir projeto" #~ msgid "&Save Project" #~ msgstr "&Salvar projeto" #~ msgid "&Close Project" #~ msgstr "&Fechar projeto" #~ msgid "Audio file:" #~ msgstr "Arquivo de áudio:" #~ msgid "Type:" #~ msgstr "Tipo:" #~ msgid "Export %s-Project" #~ msgstr "Exportar Projeto-%s" #~ msgid "Import %s-Project" #~ msgstr "Importar Projeto-%s" #~ msgid "Duration:" #~ msgstr "Duração:" #~ msgid "Error: %s" #~ msgstr "Erro: %s" #~ msgid "initialize renderer" #~ msgstr "inicializar o renderizador" #~ msgid "creating output..." #~ msgstr "criando saída..." #~ msgid "Finalizing" #~ msgstr "Finalizando" #~ msgid "Choose your next action:" #~ msgstr "Escolha a próxima ação:" #~ msgid "Delete unfinished result" #~ msgstr "Apagar resultado não finalizado" #~ msgid "Do nothing" #~ msgstr "Não fazer nada" #~ msgid "Show error again and send to developer." #~ msgstr "Mostrar o erro novamente e enviar para o desenvolvedor." #~ msgid "The rendering process was aborted." #~ msgstr "O processo de renderização foi abortado." #~ msgid "The rendering process was interrupted." #~ msgstr "O processo de renderização foi interropido." #~ msgid "The rendering process has been finished." #~ msgstr "O processo de renderização foi finalizado." #~ msgid "&Batch Job" #~ msgstr "&Trabalho em lote" #~ msgid "" #~ "Project not saved yet. Please save the project first to create a batch " #~ "job!" #~ msgstr "" #~ "O projeto não foi salvo ainda. Por favor, salve primeiro projeto para " #~ "criar um trabalho em lotes!" #~ msgid "Batch file" #~ msgstr "Arquivo de lote" #~ msgid "Shell script" #~ msgstr "Script shell" #~ msgid "Select batch file" #~ msgstr "Selecionar arquivo de lote" #~ msgid "Browse" #~ msgstr "Navegar" #~ msgid "Import image" #~ msgstr "Importar imagem" #~ msgid "Please wait" #~ msgstr "Por favor, aguarde" #~ msgid "Loading pictures..." #~ msgstr "Carregando imagens..." photofilmstrip-3.7.2/po/ru.po0000644000232200023220000007575713560357351016615 0ustar debalancedebalance# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR ORGANIZATION # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PhotoFilmStrip\n" "POT-Creation-Date: 2018-11-07 22:03+CET\n" "PO-Revision-Date: 2012-01-24 20:49+0100\n" "Last-Translator: Jens Göpfert \n" "Language-Team: \n" "Language: Russian\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: pygettext.py 1.5\n" "X-Poedit-Language: Russian\n" "X-Poedit-Country: RUSSIAN FEDERATION\n" "X-Poedit-SourceCharset: utf-8\n" #: photofilmstrip/action/ActionAutoPath.py:23 #: photofilmstrip/gui/PnlPfsProject.py:115 msgid "Random motion" msgstr "Случайное движение" #: photofilmstrip/action/ActionCenterPath.py:21 msgid "Centralize motion" msgstr "" #: photofilmstrip/action/ActionI18N.py:24 #: photofilmstrip/gui/ActionManager.py:170 msgid "Language" msgstr "Язык" #: photofilmstrip/action/ActionOpenFolder.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:28 msgid "Open folder" msgstr "Открыть папку" #: photofilmstrip/action/ActionPlayVideo.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:22 msgid "Play video" msgstr "Воспроизвести видео" #: photofilmstrip/action/ActionRender.py:37 msgid "Start" msgstr "Старт" #: photofilmstrip/cli/Main.py:46 photofilmstrip/cli/Main.py:196 msgid "all done" msgstr "готово" #: photofilmstrip/cli/Main.py:64 msgid "processing project" msgstr "обработка проекта" #: photofilmstrip/cli/Main.py:65 msgid "using renderer" msgstr "использование создания видео" #: photofilmstrip/cli/Main.py:66 msgid "output format" msgstr "выходной формат" #: photofilmstrip/cli/Main.py:69 msgid "framerate" msgstr "частота кадров" #: photofilmstrip/cli/Main.py:103 msgid "specifies the project file" msgstr "укажите файл проекта" #: photofilmstrip/cli/Main.py:104 msgid "The path where to save the output files. Use - for stdout." msgstr "Путь для сохранения выходных файлов. Используйте - для stdout." #: photofilmstrip/cli/Main.py:106 photofilmstrip/cli/Main.py:129 msgid "Option videonorm is deprecated, use an appropriate profile!" msgstr "" #: photofilmstrip/cli/Main.py:108 msgid "enable draft mode" msgstr "включить черновой режим" #: photofilmstrip/cli/Main.py:108 photofilmstrip/gui/DlgRender.py:167 msgid "" "Activate this option to generate a preview of your PhotoFilmStrip. The " "rendering process will speed up dramatically, but results in lower quality." msgstr "" "Активируйте эту опцию для предпросмотра вашего PhotoFilmStrip. Процесс " "создания видео резко ускорится, но результат будет низкого качества." #: photofilmstrip/cli/Main.py:120 msgid "project file does not exist: %s" msgstr "файл проекта не существует: %s" #: photofilmstrip/cli/Main.py:124 msgid "no project file specified!" msgstr "не указан файл проекта!" #: photofilmstrip/cli/Main.py:134 msgid "invalid format specified: %s" msgstr "казан не верный формат: %s" #: photofilmstrip/cli/Main.py:140 msgid "invalid profile specified: %s" msgstr "указан не верный профиль: %s" #: photofilmstrip/cli/Main.py:146 #, fuzzy msgid "cannot load project" msgstr "невозможно загрузить photofilmstrip" #: photofilmstrip/cli/Main.py:159 msgid "cannot create output path: %s" msgstr "невозможно создать выходной путь: %s" #: photofilmstrip/cli/Main.py:169 photofilmstrip/gui/DlgConfigureAudio.py:231 #: photofilmstrip/gui/DlgConfigureAudio.py:253 msgid "Audio file '%s' does not exist!" msgstr "Аудио файл '%s' не существует!" #: photofilmstrip/cli/Main.py:190 msgid "...aborted!" msgstr "...прерван!" #: photofilmstrip/core/BaseRenderer.py:50 msgid "Unknown property: %s" msgstr "Неизвестное свойство: %s" #: photofilmstrip/core/BaseRenderer.py:58 msgid "" msgstr "" #: photofilmstrip/core/BaseRenderer.py:73 msgid "no" msgstr "нет" #: photofilmstrip/core/ProjectFile.py:222 msgid "Saving '%s' ..." msgstr "Загрузка '%s' ..." #: photofilmstrip/core/ProjectFile.py:276 msgid "Loading '%s' ..." msgstr "Загрузка '%s' ..." #: photofilmstrip/core/RenderEngine.py:113 #: photofilmstrip/core/RenderEngine.py:201 msgid "processing transition %d/%d" msgstr "обработка перехода %d/%d" #: photofilmstrip/core/RenderEngine.py:124 #: photofilmstrip/core/RenderEngine.py:210 msgid "processing image %d/%d" msgstr "обработка изображения %d/%d" #: photofilmstrip/core/renderer/CairoRenderer.py:35 msgid "Preview" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:50 msgid "GStreamer (python-gst-1.0) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:287 msgid "Bitrate must be a number!" msgstr "Битрейт должен быть числом!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:455 #: photofilmstrip/core/renderer/GStreamerRenderer.py:531 #: photofilmstrip/core/renderer/GStreamerRenderer.py:601 #: photofilmstrip/core/renderer/GStreamerRenderer.py:690 #: photofilmstrip/core/renderer/GStreamerRenderer.py:730 #: photofilmstrip/core/renderer/GStreamerRenderer.py:779 msgid "libav (gstreamer1.0-libav) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:459 #: photofilmstrip/core/renderer/GStreamerRenderer.py:535 #: photofilmstrip/core/renderer/GStreamerRenderer.py:605 msgid "x264-Codec (gstreamer1.0-plugins-ugly) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:463 #: photofilmstrip/core/renderer/GStreamerRenderer.py:609 msgid "MKV-Muxer (gstreamer1.0-plugins-good) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:539 msgid "MP4-Muxer (gstreamer1.0-plugins-good) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:647 msgid "Theora-Codec (gstreamer1.0-plugins-base) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:651 msgid "Vorbis-Codec (gstreamer1.0-plugins-base) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:655 msgid "OGV-Muxer (gstreamer1.0-plugins-base) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:686 #: photofilmstrip/core/renderer/GStreamerRenderer.py:726 #: photofilmstrip/core/renderer/GStreamerRenderer.py:775 msgid "MPEG-1/2-Codec (gstreamer1.0-plugins-bad) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:694 #: photofilmstrip/core/renderer/GStreamerRenderer.py:734 #: photofilmstrip/core/renderer/GStreamerRenderer.py:783 msgid "MPEG-Muxer (gstreamer1.0-plugins-bad) required!" msgstr "" #: photofilmstrip/core/renderer/SingleFileRenderer.py:21 msgid "Single pictures" msgstr "Одиночные изображения" #: photofilmstrip/core/tasks.py:48 msgid "generating subtitle" msgstr "создание субтитров" #: photofilmstrip/gui/ActionManager.py:60 #: photofilmstrip/gui/ActionManager.py:190 msgid "&File" msgstr "Файл" #: photofilmstrip/gui/ActionManager.py:61 #: photofilmstrip/gui/ActionManager.py:191 msgid "&Edit" msgstr "Правка" #: photofilmstrip/gui/ActionManager.py:62 #: photofilmstrip/gui/ActionManager.py:154 photofilmstrip/gui/DlgRender.py:141 #: photofilmstrip/gui/DlgRendererProps.py:86 msgid "&Help" msgstr "Помощь" #: photofilmstrip/gui/ActionManager.py:76 msgid "New Slideshow" msgstr "" #: photofilmstrip/gui/ActionManager.py:81 msgid "Open" msgstr "" #: photofilmstrip/gui/ActionManager.py:87 msgid "Save" msgstr "" #: photofilmstrip/gui/ActionManager.py:97 #: photofilmstrip/gui/ActionManager.py:98 #, fuzzy msgid "Show job queue" msgstr "Очередь заданий" #: photofilmstrip/gui/ActionManager.py:108 #: photofilmstrip/gui/PnlSlideshow.py:25 msgid "Slideshow" msgstr "" #: photofilmstrip/gui/ActionManager.py:110 #: photofilmstrip/gui/PnlTimelapse.py:18 msgid "Timelapse" msgstr "" #: photofilmstrip/gui/ActionManager.py:116 msgid "New" msgstr "" #: photofilmstrip/gui/ActionManager.py:118 msgid "&Open" msgstr "" #: photofilmstrip/gui/ActionManager.py:123 msgid "&Save" msgstr "" #: photofilmstrip/gui/ActionManager.py:136 #, fuzzy msgid "&Close" msgstr "Закрыть проект" #: photofilmstrip/gui/ActionManager.py:141 msgid "E&xit" msgstr "Выход" #: photofilmstrip/gui/ActionManager.py:173 msgid "&About" msgstr "О программе" #: photofilmstrip/gui/DlgBugReport.py:41 msgid "An unexpected error occured" msgstr "Произошла непредвиденная ошибка" #: photofilmstrip/gui/DlgBugReport.py:44 msgid "" "An unexpected error occured. Do you want to send this bug report to the " "developers of %s?" msgstr "" "Произошла непредвиденная ошибка. Вы хотите отправить информацию об ошибке " "разработчикам %s?" #: photofilmstrip/gui/DlgBugReport.py:99 msgid "Bug-Report send. Thank you for your support." msgstr "Сообщение об ошибке отправлено. Спасибо за вашу помощь." #: photofilmstrip/gui/DlgBugReport.py:100 photofilmstrip/gui/FrmMain.py:290 msgid "Information" msgstr "Информация" #: photofilmstrip/gui/DlgBugReport.py:106 msgid "Sorry, this function is temporary not available.." msgstr "Извините, эта функция временно не доступна..." #: photofilmstrip/gui/DlgBugReport.py:107 #: photofilmstrip/gui/DlgConfigureAudio.py:232 #: photofilmstrip/gui/DlgConfigureAudio.py:244 #: photofilmstrip/gui/DlgConfigureAudio.py:254 #: photofilmstrip/gui/DlgNewProject.py:156 #: photofilmstrip/gui/DlgNewProject.py:167 #: photofilmstrip/gui/DlgPicDurationByAudio.py:208 #: photofilmstrip/gui/DlgPicDurationByAudio.py:216 #: photofilmstrip/gui/FrmMain.py:376 photofilmstrip/gui/PnlPfsProject.py:468 #: photofilmstrip/gui/PnlTimelapse.py:113 msgid "Error" msgstr "Ошибка" #: photofilmstrip/gui/DlgConfigureAudio.py:55 msgid "Configure your audio files that are used as a background music." msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:90 msgid "Set the duration of your slideshow to fit your audio files" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:92 #: photofilmstrip/gui/DlgDuration.py:70 photofilmstrip/gui/DlgNewProject.py:84 #: photofilmstrip/gui/DlgPicDurationByAudio.py:50 #: photofilmstrip/gui/DlgPositionInput.py:238 #: photofilmstrip/gui/DlgRender.py:147 #: photofilmstrip/gui/DlgRendererProps.py:92 #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:97 msgid "&Cancel" msgstr "Отмена" #: photofilmstrip/gui/DlgConfigureAudio.py:97 #: photofilmstrip/gui/DlgDuration.py:72 photofilmstrip/gui/DlgNewProject.py:86 #: photofilmstrip/gui/DlgPicDurationByAudio.py:51 #: photofilmstrip/gui/DlgPositionInput.py:244 #: photofilmstrip/gui/DlgRendererProps.py:97 msgid "&Ok" msgstr "Ок" #: photofilmstrip/gui/DlgConfigureAudio.py:104 #: photofilmstrip/gui/DlgConfigureAudio.py:109 #: photofilmstrip/gui/PnlSlideshow.py:47 photofilmstrip/gui/PnlSlideshow.py:48 #: photofilmstrip/gui/PnlTimelapse.py:33 photofilmstrip/gui/PnlTimelapse.py:34 msgid "Configure music" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:138 msgid "Select music" msgstr "Выбор музыки" #: photofilmstrip/gui/DlgConfigureAudio.py:140 msgid "Audio files" msgstr "Аудио файлы" #: photofilmstrip/gui/DlgConfigureAudio.py:243 msgid "Audio file not supported!" msgstr "Аудио файл не поддерживается!" #: photofilmstrip/gui/DlgDuration.py:48 msgid "Total length:" msgstr "Общая длительность:" #: photofilmstrip/gui/DlgDuration.py:50 msgid "" "Overrides the duration of single pictures and gives the project this total " "length." msgstr "" "Переопределяет продолжительность отдельных изображений и задает проекту " "общую длину." #: photofilmstrip/gui/DlgDuration.py:54 msgid "User defined:" msgstr "Определено пользователем:" #: photofilmstrip/gui/DlgDuration.py:65 #, fuzzy msgid "Fit to audio files" msgstr "Аудио файлы" #: photofilmstrip/gui/DlgDuration.py:80 msgid "Slideshow duration" msgstr "" #: photofilmstrip/gui/DlgDuration.py:84 msgid "Configure duration of slideshow" msgstr "" #: photofilmstrip/gui/DlgNewProject.py:61 msgid "Project name:" msgstr "Имя проекта:" #: photofilmstrip/gui/DlgNewProject.py:66 msgid "Folder:" msgstr "Папка:" #: photofilmstrip/gui/DlgNewProject.py:78 msgid "Aspect ratio:" msgstr "Соотношение сторон:" #: photofilmstrip/gui/DlgNewProject.py:110 #, fuzzy msgid "Unnamed project" msgstr "невозможно загрузить photofilmstrip" #: photofilmstrip/gui/DlgNewProject.py:116 msgid "My PhotoFilmStrips" msgstr "Мой PhotoFilmStrips" #: photofilmstrip/gui/DlgNewProject.py:126 msgid "Browse for folder" msgstr "Обзор папок" #: photofilmstrip/gui/DlgNewProject.py:145 msgid "Folder does not exists! Do you want %s to create it?" msgstr "Папка не существует! Вы хотите чтобы %s создал её?" #: photofilmstrip/gui/DlgNewProject.py:146 #: photofilmstrip/gui/PnlEditorPage.py:29 #: photofilmstrip/gui/PnlEditorPage.py:49 #: photofilmstrip/gui/PnlEditorPage.py:88 #: photofilmstrip/gui/WxProjectFile.py:101 #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:224 msgid "Question" msgstr "Вопрос" #: photofilmstrip/gui/DlgNewProject.py:155 msgid "Cannot create folder: %s" msgstr "Невозможно создать папку: %s" #: photofilmstrip/gui/DlgNewProject.py:166 msgid "Cannot write into folder!" msgstr "Не могу записать в папку!" #: photofilmstrip/gui/DlgNewProject.py:180 msgid "The project name must be filled." msgstr "Имя проекта должно быть заполнено." #: photofilmstrip/gui/DlgNewProject.py:186 msgid "The project name contains invalid characters." msgstr "Имя проекта содержит недопустимые символы." #: photofilmstrip/gui/DlgPicDurationByAudio.py:23 #: photofilmstrip/gui/PnlSlideshow.py:54 photofilmstrip/gui/PnlSlideshow.py:55 msgid "Adjust picture durations" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:26 msgid "Adjust picture durations to audio file" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:30 msgid "" "Find your picture duration by playing the audio file of your project and\n" "pressing the hit button to apply the current playing time." msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:43 #: photofilmstrip/gui/DlgPicDurationByAudio.py:153 msgid "Play" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:46 msgid "Hit" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:100 msgid "Stop" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:179 #, fuzzy msgid "Playing time" msgstr "Ожидаемое время" #: photofilmstrip/gui/DlgPicDurationByAudio.py:207 msgid "Your project does not have an audio file configured." msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:215 msgid "" "Your project uses more than one audio file. Currently the durations can be " "adjusted only for one audio file." msgstr "" #: photofilmstrip/gui/DlgPositionInput.py:140 msgid "Motion positions" msgstr "Позиции движения" #: photofilmstrip/gui/DlgPositionInput.py:147 msgid "Start position" msgstr "Начальная позиция" #: photofilmstrip/gui/DlgPositionInput.py:155 #: photofilmstrip/gui/DlgPositionInput.py:199 msgid "Location:" msgstr "Положение:" #: photofilmstrip/gui/DlgPositionInput.py:173 #: photofilmstrip/gui/DlgPositionInput.py:215 msgid "Size:" msgstr "Размер:" #: photofilmstrip/gui/DlgPositionInput.py:191 msgid "End position" msgstr "Конечная позиция" #: photofilmstrip/gui/DlgPositionInput.py:233 msgid "Reset" msgstr "Сброс" #: photofilmstrip/gui/DlgPositionInput.py:252 msgid "Adjust motion positions directly" msgstr "Настроить позиции движения напрямую" #: photofilmstrip/gui/DlgRender.py:96 #, fuzzy msgid "Render project" msgstr "Последние проекты" #: photofilmstrip/gui/DlgRender.py:107 msgid "Format:" msgstr "Формат:" #: photofilmstrip/gui/DlgRender.py:122 msgid "Properties" msgstr "Свойства" #: photofilmstrip/gui/DlgRender.py:127 msgid "Profile:" msgstr "Профиль:" #: photofilmstrip/gui/DlgRender.py:136 msgid "Draft" msgstr "Черновик" #: photofilmstrip/gui/DlgRender.py:152 msgid "&Start" msgstr "Старт" #: photofilmstrip/gui/DlgRender.py:164 msgid "Configure output and start render process" msgstr "Сконфигурировать выходной формат и начать процесс создания видео" #: photofilmstrip/gui/DlgRendererProps.py:50 msgid "Property" msgstr "Свойство" #: photofilmstrip/gui/DlgRendererProps.py:52 msgid "Value" msgstr "Значение" #: photofilmstrip/gui/DlgRendererProps.py:71 msgid "Output properties" msgstr "Свойства выходного файла" #: photofilmstrip/gui/DlgRendererProps.py:113 msgid "Edit extended output properties" msgstr "Редактировать расширенные свойства выходного файла" #: photofilmstrip/gui/DlgRendererProps.py:147 msgid "Edit property" msgstr "Редактировать свойство" #: photofilmstrip/gui/FrmMain.py:83 msgid "Welcome" msgstr "Добро пожаловать" #: photofilmstrip/gui/FrmMain.py:85 msgid "Job queue" msgstr "Очередь заданий" #: photofilmstrip/gui/FrmMain.py:141 msgid "Rendering in progress..." msgstr "" #: photofilmstrip/gui/FrmMain.py:234 photofilmstrip/gui/PnlWelcome.py:57 #, fuzzy msgid "Create new slideshow" msgstr "Портативный" #: photofilmstrip/gui/FrmMain.py:241 #, fuzzy msgid "Create new timelapse" msgstr "Создать новый проект" #: photofilmstrip/gui/FrmMain.py:249 msgid "Select %s-Project" msgstr "Выбрать %s-Проект" #: photofilmstrip/gui/FrmMain.py:251 #, fuzzy msgid "Files" msgstr "Файл" #: photofilmstrip/gui/FrmMain.py:289 msgid "You must restart %s for your new language setting to take effect." msgstr "" "Вы должны перезапустить %s чтобы новые языковые настройки вступили в силу." #: photofilmstrip/gui/FrmMain.py:300 msgid "" "PhotoFilmStrip creates movies out of your pictures in just 3 steps. First " "select your photos, customize the motion path and render the video. There " "are several output possibilities for VCD, SVCD, DVD up to FULL-HD." msgstr "" "PhotoFilmStrip создает фильмы из фотографий всего за 3 шага. Сначала " "выберите фотографии, настройте траекторию движения и сделайте видео. Есть " "несколько возможностей вывода видео от VCD, SVCD, DVD до Full-HD." #: photofilmstrip/gui/FrmMain.py:303 msgid "online" msgstr "в интернет" #: photofilmstrip/gui/FrmMain.py:374 msgid "Invalid %(app)s-Project: %(file)s" msgstr "Неправильный %(app)s-Проект: %(file)s" #: photofilmstrip/gui/PnlAddPics.py:50 photofilmstrip/gui/PnlWelcome.py:30 msgid "Welcome to PhotoFilmStrip" msgstr "Добро пожаловать в PhotoFilmStrip" #: photofilmstrip/gui/PnlAddPics.py:52 msgid "" "Drag some pictures onto this text or\n" "click the button below\n" "to add pictures to your new PhotoFilmStrip." msgstr "" "Перетащите изображения на этот текст или\n" "нажмите на кнопку ниже\n" "чтобы добавить изображения в ваш новый PhotoFilmStrip." #: photofilmstrip/gui/PnlEditPicture.py:142 msgid "Settings" msgstr "Настройки" #: photofilmstrip/gui/PnlEditPicture.py:146 msgid "Rotation:" msgstr "Вращение:" #: photofilmstrip/gui/PnlEditPicture.py:166 msgid "Effect:" msgstr "Эффект:" #: photofilmstrip/gui/PnlEditPicture.py:180 msgid "Process" msgstr "Показ" #: photofilmstrip/gui/PnlEditPicture.py:184 msgid "Movement:" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:196 #: photofilmstrip/gui/PnlEditPicture.py:212 #: photofilmstrip/gui/PnlEditPicture.py:359 msgid "sec" msgstr "сек" #: photofilmstrip/gui/PnlEditPicture.py:200 msgid "Transition:" msgstr "Переход:" #: photofilmstrip/gui/PnlEditPicture.py:220 msgid "Subtitle" msgstr "Субтитры" #: photofilmstrip/gui/PnlEditPicture.py:240 msgid "Linear" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:241 msgid "Accelerated" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:242 msgid "Delayed" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:250 msgid "No effect" msgstr "Без эффектов" #: photofilmstrip/gui/PnlEditPicture.py:251 msgid "Black and White" msgstr "Черно-белое" #: photofilmstrip/gui/PnlEditPicture.py:252 msgid "Sepia tone" msgstr "Сепия" #: photofilmstrip/gui/PnlEditPicture.py:258 msgid "None" msgstr "Ничего" #: photofilmstrip/gui/PnlEditPicture.py:259 msgid "Fade" msgstr "Затухание" #: photofilmstrip/gui/PnlEditPicture.py:260 msgid "Roll" msgstr "Сдвиг" #: photofilmstrip/gui/PnlEditPicture.py:354 msgid "fpp" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:355 msgid "frames per picture - the number of frames each picture will be shown" msgstr "" #: photofilmstrip/gui/PnlEditorPage.py:26 msgid "Could not save the file '%(file)s': %(errMsg)s" msgstr "Невозможно сохранить файл '%(file)s': %(errMsg)s" #: photofilmstrip/gui/PnlEditorPage.py:45 msgid "New file" msgstr "" #: photofilmstrip/gui/PnlEditorPage.py:48 msgid "'%s' has been modified. Save changes?" msgstr "'%s' был изменен. Сохранить изменения?" #: photofilmstrip/gui/PnlEditorPage.py:74 #, fuzzy msgid "Save %s" msgstr "Сохранить %s-Проект" #: photofilmstrip/gui/PnlEditorPage.py:77 #, fuzzy msgid "File" msgstr "Файл" #: photofilmstrip/gui/PnlEditorPage.py:87 msgid "Overwrite existing file '%s'?" msgstr "Перезаписать существующий файл '%s'?" #: photofilmstrip/gui/PnlPfsProject.py:118 #: photofilmstrip/gui/PnlPfsProject.py:120 msgid "Set motion start to end" msgstr "Установить позицию начала в позицию конца" #: photofilmstrip/gui/PnlPfsProject.py:122 #: photofilmstrip/gui/PnlPfsProject.py:124 msgid "Set motion end to start" msgstr "Установить позицию конца в позицию начала" #: photofilmstrip/gui/PnlPfsProject.py:126 #: photofilmstrip/gui/PnlPfsProject.py:128 #, fuzzy msgid "Swap motion" msgstr "Случайное движение" #: photofilmstrip/gui/PnlPfsProject.py:131 #: photofilmstrip/gui/PnlPfsProject.py:133 msgid "Adjust motion manual" msgstr "Настроить движение вручную" #: photofilmstrip/gui/PnlPfsProject.py:136 #: photofilmstrip/gui/PnlPfsProject.py:138 msgid "Preserve image dimension" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:294 msgid "&Import Pictures" msgstr "Импорт изображений" #: photofilmstrip/gui/PnlPfsProject.py:299 msgid "Move picture &left" msgstr "Переместить изображение влево" #: photofilmstrip/gui/PnlPfsProject.py:303 msgid "Move picture &right" msgstr "Переместить изображение вправо" #: photofilmstrip/gui/PnlPfsProject.py:308 #, fuzzy msgid "R&emove Picture" msgstr "Удалить изображение" #: photofilmstrip/gui/PnlPfsProject.py:313 msgid "Rotate &clockwise" msgstr "Вращать по часовой стрелке" #: photofilmstrip/gui/PnlPfsProject.py:317 msgid "Rotate counter clock&wise" msgstr "Вращать против часовой стрелки" #: photofilmstrip/gui/PnlPfsProject.py:322 #, fuzzy msgid "Random &motion" msgstr "Случайное движение" #: photofilmstrip/gui/PnlPfsProject.py:326 msgid "Centralize m&otion" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:384 msgid "Export slideshow" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:387 #: photofilmstrip/gui/PnlPfsProject.py:400 #, fuzzy msgid "Portable slideshow" msgstr "Портативный" #: photofilmstrip/gui/PnlPfsProject.py:398 #, fuzzy msgid "Import Slideshow" msgstr "Импорт изображений" #: photofilmstrip/gui/PnlPfsProject.py:409 msgid "Import images" msgstr "Импорт изображений" #: photofilmstrip/gui/PnlPfsProject.py:411 #, fuzzy msgid "Image files" msgstr "Файлы изображений" #: photofilmstrip/gui/PnlPfsProject.py:654 msgid "Audio file '%s' does not exist! Continue anyway?" msgstr "Аудио файл '%s' не существует! Все равно продолжить?" #: photofilmstrip/gui/PnlPfsProject.py:655 msgid "Warning" msgstr "Внимание" #: photofilmstrip/gui/PnlSlideshow.py:30 msgid "&Properties" msgstr "Свойства" #: photofilmstrip/gui/PnlSlideshow.py:39 photofilmstrip/gui/PnlSlideshow.py:40 #: photofilmstrip/gui/PnlTimelapse.py:25 photofilmstrip/gui/PnlTimelapse.py:26 msgid "Import Pictures" msgstr "Импорт изображений" #: photofilmstrip/gui/PnlSlideshow.py:62 photofilmstrip/gui/PnlSlideshow.py:63 #: photofilmstrip/gui/PnlTimelapse.py:41 photofilmstrip/gui/PnlTimelapse.py:42 msgid "Render filmstrip" msgstr "Создать видео" #: photofilmstrip/gui/PnlSlideshow.py:89 photofilmstrip/gui/PnlTimelapse.py:66 msgid "Images" msgstr "Изображения" #: photofilmstrip/gui/PnlSlideshow.py:94 msgid "Duration" msgstr "Длительность" #: photofilmstrip/gui/PnlTimelapse.py:69 msgid "Frames" msgstr "" #: photofilmstrip/gui/PnlTimelapse.py:92 msgid "The picture counter is not increasing: %s" msgstr "" #: photofilmstrip/gui/PnlTimelapse.py:110 msgid "" "Filename '%s' does not match a number pattern which is necessary for a time " "lapse slide show!" msgstr "" #: photofilmstrip/gui/PnlWelcome.py:37 photofilmstrip/gui/PnlWelcome.py:103 msgid "Recent projects" msgstr "Последние проекты" #: photofilmstrip/gui/PnlWelcome.py:62 msgid "Open existing project" msgstr "Открыть существующий проект" #: photofilmstrip/gui/PnlWelcome.py:106 msgid "How to start..." msgstr "С чего начать..." #: photofilmstrip/gui/PnlWelcome.py:107 msgid "Create a new project or load an existing one." msgstr "Создать новый проект или загрузить существующий" #: photofilmstrip/gui/PnlWelcome.py:138 msgid "Update available" msgstr "Доступно обновление" #: photofilmstrip/gui/PnlWelcome.py:141 msgid "The following changes has been made:" msgstr "Были сделаны следующие изменения:" #: photofilmstrip/gui/WxProjectFile.py:59 msgid "Loading project %s" msgstr "Загрузить проект %s" #: photofilmstrip/gui/WxProjectFile.py:75 msgid "Saving project %s" msgstr "Сохранить проект %s" #: photofilmstrip/gui/WxProjectFile.py:100 msgid "" "Some images does not exist in the folder '%s' anymore. If the files has " "moved you can select the new path. Do you want to select a new path?" msgstr "" "Некоторые изображения больше не существуют в каталоге '%s'. Если файлы были " "перемещены вы можете выбрать новый путь. Вы хотите выбрать новый путь к " "файлам?" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:73 msgid "Elapsed time" msgstr "Прошедшее время" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:85 msgid "Remaining time" msgstr "Ожидаемое время" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:203 msgid "Unknown" msgstr "Неизвестно" #: photofilmstrip/lib/jobimpl/PnlJobManager.py:50 msgid "&Clear list" msgstr "Очистить список" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:127 msgid "Abort" msgstr "Прервать" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:133 msgid "Remove from list" msgstr "Удалить из списка" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:223 msgid "Abort selected process?" msgstr "Прервать текущий процесс?" #: photofilmstrip/lib/jobimpl/VisualJob.py:29 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:25 msgid "Waiting..." msgstr "прерывание..." #: photofilmstrip/lib/jobimpl/VisualJob.py:68 #: photofilmstrip/lib/jobimpl/VisualJob.py:85 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:60 msgid "Aborted" msgstr "...прерван!" #: photofilmstrip/lib/jobimpl/VisualJob.py:70 msgid "Done" msgstr "Завершено" #: photofilmstrip/lib/jobimpl/VisualJob.py:79 msgid "Aborting..." msgstr "Прерывание..." #: photofilmstrip/uwp/UwpService.py:76 msgid "Slideshow created!" msgstr "" #, fuzzy #~ msgid "Audio files:" #~ msgstr "Аудио файлы" #~ msgid "Project properties" #~ msgstr "Свойства проекта" #~ msgid "PhotoFilmStrip project" #~ msgstr "PhotoFilmStrip проект" #~ msgid "Unnamed PhotoFilmStrip" #~ msgstr "Безымянный PhotoFilmStrip" #~ msgid "Project" #~ msgstr "Проект" #~ msgid "invalid videonorm specified: %s" #~ msgstr "указан не верный videonorm: %s" #~ msgid "Please wait..." #~ msgstr "Пожалуйста подождите..." #~ msgid "aborting..." #~ msgstr "прерывание..." #~ msgid "mencoder (mencoder) required!" #~ msgstr "требуется mencoder (mencoder)!" #~ msgid "MPEG(1/2)-Video (MPG)" #~ msgstr "MPEG(1/2)-Video (MPG" #~ msgid "MPEG format supports only VCD, SVCD and DVD profile!" #~ msgstr "Формат MPEG поддерживает только профили VCD, SVCD и DVD!" #~ msgid "MPEG4-XVid/AC3 (AVI)" #~ msgstr "MPEG4-XVid/AC3 (AVI)" #~ msgid "mencoder with MP3 support (mp3lame) required!" #~ msgstr "требуется mencoder с поддержкой MP3 (mp3lame)!" #~ msgid "MPEG4-XVid/MP3 (AVI)" #~ msgstr "MPEG4-XVid/MP3 (AVI)" #~ msgid "Flash-Video (FLV)" #~ msgstr "Flash-Video (FLV)" #~ msgid "Motion-JPEG (AVI)" #~ msgstr "Motion-JPEG (AVI)" #~ msgid "&Tools" #~ msgstr "Инструменты" #~ msgid "New Project" #~ msgstr "Новый проект" #~ msgid "Load Project" #~ msgstr "Загрузить проект" #~ msgid "Save Project" #~ msgstr "Сохранить проект" #~ msgid "&New Project" #~ msgstr "Новый проект" #~ msgid "&Open Project" #~ msgstr "Открыть проект" #~ msgid "&Save Project" #~ msgstr "Сохранить проект" #~ msgid "&Render filmstrip" #~ msgstr "Создать видео" #~ msgid "Audio file:" #~ msgstr "Аудио файл:" #~ msgid "Type:" #~ msgstr "Тип:" #~ msgid "Export %s-Project" #~ msgstr "Экспорт %s-Проект" #~ msgid "Import %s-Project" #~ msgstr "Импорт %s-Проект" #~ msgid "Duration:" #~ msgstr "Длительность:" #~ msgid "Browse" #~ msgstr "Обзор" #~ msgid "Import image" #~ msgstr "Импорт изображения" photofilmstrip-3.7.2/po/el.po0000644000232200023220000010637613560357351016557 0ustar debalancedebalancemsgid "" msgstr "" "Project-Id-Version: PhotoFilmStrip v3.0.2\n" "POT-Creation-Date: 2018-11-07 22:03+CET\n" "PO-Revision-Date: 2018-10-04 23:46+0200\n" "Last-Translator: geogeo.gr \n" "Language-Team: geogeo.gr \n" "Language: el_GR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: pygettext.py 1.5\n" "X-Poedit-SourceCharset: utf-8\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 2.0.6\n" #: photofilmstrip/action/ActionAutoPath.py:23 #: photofilmstrip/gui/PnlPfsProject.py:115 msgid "Random motion" msgstr "Τυχαία κίνηση" #: photofilmstrip/action/ActionCenterPath.py:21 msgid "Centralize motion" msgstr "&Συγκεντρωτική κίνηση" #: photofilmstrip/action/ActionI18N.py:24 #: photofilmstrip/gui/ActionManager.py:170 msgid "Language" msgstr "Γλώσσα / Language" #: photofilmstrip/action/ActionOpenFolder.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:28 msgid "Open folder" msgstr "Άνοιγμα φακέλου" #: photofilmstrip/action/ActionPlayVideo.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:22 msgid "Play video" msgstr "Αναπαραγωγή βίντεο" #: photofilmstrip/action/ActionRender.py:37 msgid "Start" msgstr "Έναρξη" #: photofilmstrip/cli/Main.py:46 photofilmstrip/cli/Main.py:196 msgid "all done" msgstr "Ολοκλήρωση όλων" #: photofilmstrip/cli/Main.py:64 msgid "processing project" msgstr "Επεξεργασία έργου" #: photofilmstrip/cli/Main.py:65 msgid "using renderer" msgstr "Χρήση απόδοσης" #: photofilmstrip/cli/Main.py:66 msgid "output format" msgstr "μορφή εξόδου" #: photofilmstrip/cli/Main.py:69 msgid "framerate" msgstr "Ρυθμός καρέ" #: photofilmstrip/cli/Main.py:103 msgid "specifies the project file" msgstr "Καθορίζει το αρχείο έργου" #: photofilmstrip/cli/Main.py:104 msgid "The path where to save the output files. Use - for stdout." msgstr "" "Η διαδρομή όπου θα αποθηκευθούν τα εξαγόμενα αρχεία. Χρήση - για stdout." #: photofilmstrip/cli/Main.py:106 photofilmstrip/cli/Main.py:129 msgid "Option videonorm is deprecated, use an appropriate profile!" msgstr "" #: photofilmstrip/cli/Main.py:108 msgid "enable draft mode" msgstr "Ενεργοποίηση λειτουργίας προσχεδίου" #: photofilmstrip/cli/Main.py:108 photofilmstrip/gui/DlgRender.py:167 msgid "" "Activate this option to generate a preview of your PhotoFilmStrip. The " "rendering process will speed up dramatically, but results in lower quality." msgstr "" "Ενεργοποιήστε αυτή την επιλογή για να δημιουργήσετε μια προεπισκόπηση του " "PhotoFilmStrip σας. \n" "Η διαδικασία απόδοσης θα επιταχυνθεί δραστικά, αλλά με αποτέλεσμα τη " "χαμηλότερη ποιότητα." #: photofilmstrip/cli/Main.py:120 msgid "project file does not exist: %s" msgstr "Το αρχείο έργου δεν υπάρχει: %s" #: photofilmstrip/cli/Main.py:124 msgid "no project file specified!" msgstr "Δεν καθορίστηκε αρχείο έργου!" #: photofilmstrip/cli/Main.py:134 msgid "invalid format specified: %s" msgstr "Καθορίστηκε μη έγκυρη μορφή: %s" #: photofilmstrip/cli/Main.py:140 msgid "invalid profile specified: %s" msgstr "Καθορίστηκε μη έγκυρo προφιλ: %s" #: photofilmstrip/cli/Main.py:146 #, fuzzy msgid "cannot load project" msgstr "Αδυναμία φόρτωσης της ταινίας" #: photofilmstrip/cli/Main.py:159 msgid "cannot create output path: %s" msgstr "Δεν είναι δυνατή η δημιουργία του φακέλου εξόδου: %s" #: photofilmstrip/cli/Main.py:169 photofilmstrip/gui/DlgConfigureAudio.py:231 #: photofilmstrip/gui/DlgConfigureAudio.py:253 msgid "Audio file '%s' does not exist!" msgstr "Το αρχείο ήχου '%s' δεν υπάρχει!" #: photofilmstrip/cli/Main.py:190 msgid "...aborted!" msgstr "...ματαιώθηκε!" #: photofilmstrip/core/BaseRenderer.py:50 msgid "Unknown property: %s" msgstr "Άγνωστη ιδιότητα: %s" #: photofilmstrip/core/BaseRenderer.py:58 msgid "" msgstr "<προεπιλογή>" #: photofilmstrip/core/BaseRenderer.py:73 msgid "no" msgstr "όχι" #: photofilmstrip/core/ProjectFile.py:222 #, fuzzy msgid "Saving '%s' ..." msgstr "Φόρτωση '%s' ..." #: photofilmstrip/core/ProjectFile.py:276 msgid "Loading '%s' ..." msgstr "Φόρτωση '%s' ..." #: photofilmstrip/core/RenderEngine.py:113 #: photofilmstrip/core/RenderEngine.py:201 msgid "processing transition %d/%d" msgstr "Επεξεργασία μετάβασης %d/%d" #: photofilmstrip/core/RenderEngine.py:124 #: photofilmstrip/core/RenderEngine.py:210 msgid "processing image %d/%d" msgstr "Επεξεργασία εικόνας %d/%d" #: photofilmstrip/core/renderer/CairoRenderer.py:35 msgid "Preview" msgstr "Προεπισκόπηση" #: photofilmstrip/core/renderer/GStreamerRenderer.py:50 msgid "GStreamer (python-gst-1.0) required!" msgstr "Απαιτείται GStreamer (python-gst-1.0)!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:287 msgid "Bitrate must be a number!" msgstr "Το bitrate πρέπει να είναι ένας αριθμός!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:455 #: photofilmstrip/core/renderer/GStreamerRenderer.py:531 #: photofilmstrip/core/renderer/GStreamerRenderer.py:601 #: photofilmstrip/core/renderer/GStreamerRenderer.py:690 #: photofilmstrip/core/renderer/GStreamerRenderer.py:730 #: photofilmstrip/core/renderer/GStreamerRenderer.py:779 msgid "libav (gstreamer1.0-libav) required!" msgstr "Απαιτείται libav (gstreamer1.0-libav)!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:459 #: photofilmstrip/core/renderer/GStreamerRenderer.py:535 #: photofilmstrip/core/renderer/GStreamerRenderer.py:605 msgid "x264-Codec (gstreamer1.0-plugins-ugly) required!" msgstr "Απαιτείται x264-Codec (gstreamer1.0-plugins-ugly)!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:463 #: photofilmstrip/core/renderer/GStreamerRenderer.py:609 msgid "MKV-Muxer (gstreamer1.0-plugins-good) required!" msgstr "Απαιτείται MKV-Muxer (gstreamer1.0-plugins-good)!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:539 msgid "MP4-Muxer (gstreamer1.0-plugins-good) required!" msgstr "Απαιτείται MP4-Muxer (gstreamer1.0-plugins-good)!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:647 msgid "Theora-Codec (gstreamer1.0-plugins-base) required!" msgstr "Απαιτείται Theora-Codec (gstreamer1.0-plugins-base)!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:651 msgid "Vorbis-Codec (gstreamer1.0-plugins-base) required!" msgstr "Απαιτείται Vorbis-Codec (gstreamer1.0-plugins-base)!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:655 msgid "OGV-Muxer (gstreamer1.0-plugins-base) required!" msgstr "Απαιτείται OGV-Muxer (gstreamer1.0-plugins-base)!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:686 #: photofilmstrip/core/renderer/GStreamerRenderer.py:726 #: photofilmstrip/core/renderer/GStreamerRenderer.py:775 msgid "MPEG-1/2-Codec (gstreamer1.0-plugins-bad) required!" msgstr "Απαιτείται MPEG-1/2-Codec (gstreamer1.0-plugins-bad)!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:694 #: photofilmstrip/core/renderer/GStreamerRenderer.py:734 #: photofilmstrip/core/renderer/GStreamerRenderer.py:783 msgid "MPEG-Muxer (gstreamer1.0-plugins-bad) required!" msgstr "Απαιτείται MPEG-Muxer (gstreamer1.0-plugins-bad)!" #: photofilmstrip/core/renderer/SingleFileRenderer.py:21 msgid "Single pictures" msgstr "Μεμονωμένες εικόνες" #: photofilmstrip/core/tasks.py:48 msgid "generating subtitle" msgstr "Δημιουργία υπότιτλου" #: photofilmstrip/gui/ActionManager.py:60 #: photofilmstrip/gui/ActionManager.py:190 msgid "&File" msgstr "&Αρχείο" #: photofilmstrip/gui/ActionManager.py:61 #: photofilmstrip/gui/ActionManager.py:191 msgid "&Edit" msgstr "&Επεξεργασία" #: photofilmstrip/gui/ActionManager.py:62 #: photofilmstrip/gui/ActionManager.py:154 photofilmstrip/gui/DlgRender.py:141 #: photofilmstrip/gui/DlgRendererProps.py:86 msgid "&Help" msgstr "&Βοήθεια" #: photofilmstrip/gui/ActionManager.py:76 msgid "New Slideshow" msgstr "" #: photofilmstrip/gui/ActionManager.py:81 msgid "Open" msgstr "" #: photofilmstrip/gui/ActionManager.py:87 msgid "Save" msgstr "" #: photofilmstrip/gui/ActionManager.py:97 #: photofilmstrip/gui/ActionManager.py:98 msgid "Show job queue" msgstr "Εμφάνιση ουράς εργασιών" #: photofilmstrip/gui/ActionManager.py:108 #: photofilmstrip/gui/PnlSlideshow.py:25 msgid "Slideshow" msgstr "" #: photofilmstrip/gui/ActionManager.py:110 #: photofilmstrip/gui/PnlTimelapse.py:18 msgid "Timelapse" msgstr "Παρέλευση χρόνου" #: photofilmstrip/gui/ActionManager.py:116 msgid "New" msgstr "" #: photofilmstrip/gui/ActionManager.py:118 msgid "&Open" msgstr "" #: photofilmstrip/gui/ActionManager.py:123 msgid "&Save" msgstr "" #: photofilmstrip/gui/ActionManager.py:136 msgid "&Close" msgstr "&Κλείσιμο" #: photofilmstrip/gui/ActionManager.py:141 msgid "E&xit" msgstr "Έ&ξοδος" #: photofilmstrip/gui/ActionManager.py:173 msgid "&About" msgstr "&Περί" #: photofilmstrip/gui/DlgBugReport.py:41 msgid "An unexpected error occured" msgstr "Παρουσιάστηκε μη αναμενόμενο σφάλμα" #: photofilmstrip/gui/DlgBugReport.py:44 msgid "" "An unexpected error occured. Do you want to send this bug report to the " "developers of %s?" msgstr "" "Παρουσιάστηκε μη αναμενόμενο σφάλμα. \n" "Θέλετε να στείλετε αυτή την αναφορά σφάλματος στους δημιουργούς του %s;" #: photofilmstrip/gui/DlgBugReport.py:99 msgid "Bug-Report send. Thank you for your support." msgstr "Αποστολή αναφοράς σφάλματος. Ευχαριστούμε για την υποστήριξή σας." #: photofilmstrip/gui/DlgBugReport.py:100 photofilmstrip/gui/FrmMain.py:290 msgid "Information" msgstr "Πληροφορίες" #: photofilmstrip/gui/DlgBugReport.py:106 msgid "Sorry, this function is temporary not available.." msgstr "Συγνώμη, αυτή η λειτουργία προσωρινά δεν είναι διαθέσιμη." #: photofilmstrip/gui/DlgBugReport.py:107 #: photofilmstrip/gui/DlgConfigureAudio.py:232 #: photofilmstrip/gui/DlgConfigureAudio.py:244 #: photofilmstrip/gui/DlgConfigureAudio.py:254 #: photofilmstrip/gui/DlgNewProject.py:156 #: photofilmstrip/gui/DlgNewProject.py:167 #: photofilmstrip/gui/DlgPicDurationByAudio.py:208 #: photofilmstrip/gui/DlgPicDurationByAudio.py:216 #: photofilmstrip/gui/FrmMain.py:376 photofilmstrip/gui/PnlPfsProject.py:468 #: photofilmstrip/gui/PnlTimelapse.py:113 msgid "Error" msgstr "Σφάλμα" #: photofilmstrip/gui/DlgConfigureAudio.py:55 msgid "Configure your audio files that are used as a background music." msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:90 msgid "Set the duration of your slideshow to fit your audio files" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:92 #: photofilmstrip/gui/DlgDuration.py:70 photofilmstrip/gui/DlgNewProject.py:84 #: photofilmstrip/gui/DlgPicDurationByAudio.py:50 #: photofilmstrip/gui/DlgPositionInput.py:238 #: photofilmstrip/gui/DlgRender.py:147 #: photofilmstrip/gui/DlgRendererProps.py:92 #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:97 msgid "&Cancel" msgstr "Ά&κυρο" #: photofilmstrip/gui/DlgConfigureAudio.py:97 #: photofilmstrip/gui/DlgDuration.py:72 photofilmstrip/gui/DlgNewProject.py:86 #: photofilmstrip/gui/DlgPicDurationByAudio.py:51 #: photofilmstrip/gui/DlgPositionInput.py:244 #: photofilmstrip/gui/DlgRendererProps.py:97 msgid "&Ok" msgstr "&Εντάξει" #: photofilmstrip/gui/DlgConfigureAudio.py:104 #: photofilmstrip/gui/DlgConfigureAudio.py:109 #: photofilmstrip/gui/PnlSlideshow.py:47 photofilmstrip/gui/PnlSlideshow.py:48 #: photofilmstrip/gui/PnlTimelapse.py:33 photofilmstrip/gui/PnlTimelapse.py:34 msgid "Configure music" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:138 msgid "Select music" msgstr "Επιλέξτε μουσική" #: photofilmstrip/gui/DlgConfigureAudio.py:140 msgid "Audio files" msgstr "Αρχεία ήχου" #: photofilmstrip/gui/DlgConfigureAudio.py:243 msgid "Audio file not supported!" msgstr "Το αρχείο ήχου δεν υποστηρίζεται!" #: photofilmstrip/gui/DlgDuration.py:48 msgid "Total length:" msgstr "Συνολικό μήκος:" #: photofilmstrip/gui/DlgDuration.py:50 msgid "" "Overrides the duration of single pictures and gives the project this total " "length." msgstr "" "Παρακάμπτει τη διάρκεια των μεμονωμένων εικόνων και δίνει στο έργο, το " "παρακάτω συνολικό μήκος." #: photofilmstrip/gui/DlgDuration.py:54 msgid "User defined:" msgstr "Οριζόμενο από χρήστη:" #: photofilmstrip/gui/DlgDuration.py:65 msgid "Fit to audio files" msgstr "Προσαρμογή στα αρχεία ήχου" #: photofilmstrip/gui/DlgDuration.py:80 msgid "Slideshow duration" msgstr "" #: photofilmstrip/gui/DlgDuration.py:84 msgid "Configure duration of slideshow" msgstr "" #: photofilmstrip/gui/DlgNewProject.py:61 msgid "Project name:" msgstr "Όνομα έργου:" #: photofilmstrip/gui/DlgNewProject.py:66 msgid "Folder:" msgstr "Φάκελος:" #: photofilmstrip/gui/DlgNewProject.py:78 msgid "Aspect ratio:" msgstr "Αναλογία πλευρών:" #: photofilmstrip/gui/DlgNewProject.py:110 #, fuzzy msgid "Unnamed project" msgstr "Αδυναμία φόρτωσης της ταινίας" #: photofilmstrip/gui/DlgNewProject.py:116 msgid "My PhotoFilmStrips" msgstr "Οι ταινίες μου" #: photofilmstrip/gui/DlgNewProject.py:126 msgid "Browse for folder" msgstr "Αναζήτηση για φάκελο" #: photofilmstrip/gui/DlgNewProject.py:145 msgid "Folder does not exists! Do you want %s to create it?" msgstr "Ο φάκελος δεν υπάρχει. Θέλετε το %s να τον δημιουργήσει;" #: photofilmstrip/gui/DlgNewProject.py:146 #: photofilmstrip/gui/PnlEditorPage.py:29 #: photofilmstrip/gui/PnlEditorPage.py:49 #: photofilmstrip/gui/PnlEditorPage.py:88 #: photofilmstrip/gui/WxProjectFile.py:101 #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:224 msgid "Question" msgstr "Ερώτηση" #: photofilmstrip/gui/DlgNewProject.py:155 msgid "Cannot create folder: %s" msgstr "Δεν είναι δυνατή η δημιουργία του φακέλου: %s" #: photofilmstrip/gui/DlgNewProject.py:166 msgid "Cannot write into folder!" msgstr "Δεν είναι δυνατή η εγγραφή στο φάκελο!" #: photofilmstrip/gui/DlgNewProject.py:180 msgid "The project name must be filled." msgstr "Πρέπει να συμπληρωθεί ένα όνομα για το έργο." #: photofilmstrip/gui/DlgNewProject.py:186 msgid "The project name contains invalid characters." msgstr "Το όνομα του έργου περιέχει μη έγκυρους χαρακτήρες." #: photofilmstrip/gui/DlgPicDurationByAudio.py:23 #: photofilmstrip/gui/PnlSlideshow.py:54 photofilmstrip/gui/PnlSlideshow.py:55 msgid "Adjust picture durations" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:26 msgid "Adjust picture durations to audio file" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:30 msgid "" "Find your picture duration by playing the audio file of your project and\n" "pressing the hit button to apply the current playing time." msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:43 #: photofilmstrip/gui/DlgPicDurationByAudio.py:153 msgid "Play" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:46 msgid "Hit" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:100 msgid "Stop" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:179 #, fuzzy msgid "Playing time" msgstr "Χρόνος που απομένει" #: photofilmstrip/gui/DlgPicDurationByAudio.py:207 msgid "Your project does not have an audio file configured." msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:215 msgid "" "Your project uses more than one audio file. Currently the durations can be " "adjusted only for one audio file." msgstr "" #: photofilmstrip/gui/DlgPositionInput.py:140 msgid "Motion positions" msgstr "Θέσεις κίνησης" #: photofilmstrip/gui/DlgPositionInput.py:147 msgid "Start position" msgstr "Αρχική θέση" #: photofilmstrip/gui/DlgPositionInput.py:155 #: photofilmstrip/gui/DlgPositionInput.py:199 msgid "Location:" msgstr "Θέση:" #: photofilmstrip/gui/DlgPositionInput.py:173 #: photofilmstrip/gui/DlgPositionInput.py:215 msgid "Size:" msgstr "Μέγεθος:" #: photofilmstrip/gui/DlgPositionInput.py:191 msgid "End position" msgstr "Τελική θέση" #: photofilmstrip/gui/DlgPositionInput.py:233 msgid "Reset" msgstr "Επαναφορά" #: photofilmstrip/gui/DlgPositionInput.py:252 msgid "Adjust motion positions directly" msgstr "Άμεση ρύθμιση της θέσης κίνησης" #: photofilmstrip/gui/DlgRender.py:96 #, fuzzy msgid "Render project" msgstr "Πρόσφατα έργα" #: photofilmstrip/gui/DlgRender.py:107 msgid "Format:" msgstr "Μορφή:" #: photofilmstrip/gui/DlgRender.py:122 msgid "Properties" msgstr "Ιδιότητες" #: photofilmstrip/gui/DlgRender.py:127 msgid "Profile:" msgstr "Προφίλ:" #: photofilmstrip/gui/DlgRender.py:136 msgid "Draft" msgstr "Προσχέδιο" #: photofilmstrip/gui/DlgRender.py:152 msgid "&Start" msgstr "Έ&ναρξη" #: photofilmstrip/gui/DlgRender.py:164 msgid "Configure output and start render process" msgstr "Διαμόρφωση εξόδου και έναρξη διαδικασίας απόδοσης" #: photofilmstrip/gui/DlgRendererProps.py:50 msgid "Property" msgstr "Ιδιότητα" #: photofilmstrip/gui/DlgRendererProps.py:52 msgid "Value" msgstr "Τιμή" #: photofilmstrip/gui/DlgRendererProps.py:71 msgid "Output properties" msgstr "Ιδιότητες εξόδου" #: photofilmstrip/gui/DlgRendererProps.py:113 msgid "Edit extended output properties" msgstr "Επεξεργασία εκτεταμένων ιδιοτήτων εξόδου" #: photofilmstrip/gui/DlgRendererProps.py:147 msgid "Edit property" msgstr "Επεξεργασία ιδιότητας" #: photofilmstrip/gui/FrmMain.py:83 msgid "Welcome" msgstr "Καλώς ήλθατε" #: photofilmstrip/gui/FrmMain.py:85 msgid "Job queue" msgstr "Ουρά εργασιών" #: photofilmstrip/gui/FrmMain.py:141 msgid "Rendering in progress..." msgstr "Απόδοση σε εξέλιξη..." #: photofilmstrip/gui/FrmMain.py:234 photofilmstrip/gui/PnlWelcome.py:57 #, fuzzy msgid "Create new slideshow" msgstr "Φορητό" #: photofilmstrip/gui/FrmMain.py:241 #, fuzzy msgid "Create new timelapse" msgstr "Δημιουργία νέου έργου" #: photofilmstrip/gui/FrmMain.py:249 msgid "Select %s-Project" msgstr "Επιλέξτε έργο %s" #: photofilmstrip/gui/FrmMain.py:251 #, fuzzy msgid "Files" msgstr "&Αρχείο" #: photofilmstrip/gui/FrmMain.py:289 msgid "You must restart %s for your new language setting to take effect." msgstr "" "Πρέπει να κάνετε επανεκκίνηση του %s για να εφαρμοστεί η αλλαγή γλώσσας." #: photofilmstrip/gui/FrmMain.py:300 msgid "" "PhotoFilmStrip creates movies out of your pictures in just 3 steps. First " "select your photos, customize the motion path and render the video. There " "are several output possibilities for VCD, SVCD, DVD up to FULL-HD." msgstr "" "Το PhotoFilmStrip δημιουργεί ταινίες από τις εικόνες σας, σε 3 απλά βήματα. " "Πρώτα επιλέγετε τις φωτογραφίες σας, μετά προσαρμόζετε τη διαδρομή κίνησης " "και τέλος την απόδοση του βίντεο. Υπάρχουν πολλές δυνατότητες εξόδου για " "VCD, SVCD, DVD, μέχρι FULL-HD. " #: photofilmstrip/gui/FrmMain.py:303 msgid "online" msgstr "Σε σύνδεση" #: photofilmstrip/gui/FrmMain.py:374 msgid "Invalid %(app)s-Project: %(file)s" msgstr "Μη έγκυρο έργο του %(app)s: %(file)s" #: photofilmstrip/gui/PnlAddPics.py:50 photofilmstrip/gui/PnlWelcome.py:30 msgid "Welcome to PhotoFilmStrip" msgstr "Καλώς ήλθατε στο PhotoFilmStrip" #: photofilmstrip/gui/PnlAddPics.py:52 msgid "" "Drag some pictures onto this text or\n" "click the button below\n" "to add pictures to your new PhotoFilmStrip." msgstr "" "Μεταφέρετε μερικές εικόνες πάνω σ΄αυτό το κείμενο\n" "ή κάντε κλικ στο κουμπί παρακάτω\n" "για να προσθέσετε εικόνες στον νέο σας PhotoFilmStrip." #: photofilmstrip/gui/PnlEditPicture.py:142 msgid "Settings" msgstr "Ρυθμίσεις" #: photofilmstrip/gui/PnlEditPicture.py:146 msgid "Rotation:" msgstr "Περιστροφή:" #: photofilmstrip/gui/PnlEditPicture.py:166 msgid "Effect:" msgstr "Εφέ:" #: photofilmstrip/gui/PnlEditPicture.py:180 msgid "Process" msgstr "Διαδικασία" #: photofilmstrip/gui/PnlEditPicture.py:184 msgid "Movement:" msgstr "Κίνηση:" #: photofilmstrip/gui/PnlEditPicture.py:196 #: photofilmstrip/gui/PnlEditPicture.py:212 #: photofilmstrip/gui/PnlEditPicture.py:359 msgid "sec" msgstr "δευτ." #: photofilmstrip/gui/PnlEditPicture.py:200 msgid "Transition:" msgstr "Μετάβαση:" #: photofilmstrip/gui/PnlEditPicture.py:220 msgid "Subtitle" msgstr "Υπότιτλος " #: photofilmstrip/gui/PnlEditPicture.py:240 msgid "Linear" msgstr "Γραμμική" #: photofilmstrip/gui/PnlEditPicture.py:241 msgid "Accelerated" msgstr "Επιταχυνόμενη" #: photofilmstrip/gui/PnlEditPicture.py:242 msgid "Delayed" msgstr "Επιβραδυνόμενη" #: photofilmstrip/gui/PnlEditPicture.py:250 msgid "No effect" msgstr "Χωρίς εφέ" #: photofilmstrip/gui/PnlEditPicture.py:251 msgid "Black and White" msgstr "Ασπρόμαυρα" #: photofilmstrip/gui/PnlEditPicture.py:252 msgid "Sepia tone" msgstr "Τόνος σκουριάς" #: photofilmstrip/gui/PnlEditPicture.py:258 msgid "None" msgstr "Καμία" #: photofilmstrip/gui/PnlEditPicture.py:259 msgid "Fade" msgstr "Σβήσιμο" #: photofilmstrip/gui/PnlEditPicture.py:260 msgid "Roll" msgstr "Κύλιση" #: photofilmstrip/gui/PnlEditPicture.py:354 msgid "fpp" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:355 msgid "frames per picture - the number of frames each picture will be shown" msgstr "" #: photofilmstrip/gui/PnlEditorPage.py:26 msgid "Could not save the file '%(file)s': %(errMsg)s" msgstr "Δεν ήταν δυνατή η αποθήκευση του αρχείου '%(file)s': %(errMsg)s" #: photofilmstrip/gui/PnlEditorPage.py:45 msgid "New file" msgstr "" #: photofilmstrip/gui/PnlEditorPage.py:48 msgid "'%s' has been modified. Save changes?" msgstr "" "Το «%s» έχει τροποποιηθεί. \n" "Να αποθηκευτούν οι αλλαγές;" #: photofilmstrip/gui/PnlEditorPage.py:74 #, fuzzy msgid "Save %s" msgstr "Αποθήκευση του έργου %s" #: photofilmstrip/gui/PnlEditorPage.py:77 #, fuzzy msgid "File" msgstr "&Αρχείο" #: photofilmstrip/gui/PnlEditorPage.py:87 msgid "Overwrite existing file '%s'?" msgstr "Αντικατάσταση του υπάρχοντος αρχείου '%s';" #: photofilmstrip/gui/PnlPfsProject.py:118 #: photofilmstrip/gui/PnlPfsProject.py:120 msgid "Set motion start to end" msgstr "Κίνηση από αρχή προς τέρμα" #: photofilmstrip/gui/PnlPfsProject.py:122 #: photofilmstrip/gui/PnlPfsProject.py:124 msgid "Set motion end to start" msgstr "Κίνηση από τέρμα προς αρχή" #: photofilmstrip/gui/PnlPfsProject.py:126 #: photofilmstrip/gui/PnlPfsProject.py:128 msgid "Swap motion" msgstr "Ανταλλαγή κίνησης" #: photofilmstrip/gui/PnlPfsProject.py:131 #: photofilmstrip/gui/PnlPfsProject.py:133 msgid "Adjust motion manual" msgstr "Ρύθμιση κίνησης χειροκίνητα" #: photofilmstrip/gui/PnlPfsProject.py:136 #: photofilmstrip/gui/PnlPfsProject.py:138 msgid "Preserve image dimension" msgstr "Διατήρηση διάστασης εικόνας" #: photofilmstrip/gui/PnlPfsProject.py:294 msgid "&Import Pictures" msgstr "&Εισαγωγή εικόνων" #: photofilmstrip/gui/PnlPfsProject.py:299 msgid "Move picture &left" msgstr "Μετακίνηση εικόνας &αριστερά" #: photofilmstrip/gui/PnlPfsProject.py:303 msgid "Move picture &right" msgstr "Μετακίνηση εικόνας &δεξιά" #: photofilmstrip/gui/PnlPfsProject.py:308 msgid "R&emove Picture" msgstr "Α&φαίρεση εικόνας" #: photofilmstrip/gui/PnlPfsProject.py:313 msgid "Rotate &clockwise" msgstr "Περιστροφή δε&ξιόστροφα" #: photofilmstrip/gui/PnlPfsProject.py:317 msgid "Rotate counter clock&wise" msgstr "Περιστροφή α&ριστερόστροφα" #: photofilmstrip/gui/PnlPfsProject.py:322 msgid "Random &motion" msgstr "Τυ&χαία κίνηση" #: photofilmstrip/gui/PnlPfsProject.py:326 msgid "Centralize m&otion" msgstr "Συγκεντρωτική κίνηση" #: photofilmstrip/gui/PnlPfsProject.py:384 msgid "Export slideshow" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:387 #: photofilmstrip/gui/PnlPfsProject.py:400 #, fuzzy msgid "Portable slideshow" msgstr "Φορητό" #: photofilmstrip/gui/PnlPfsProject.py:398 #, fuzzy msgid "Import Slideshow" msgstr "Εισαγωγή εικόνων" #: photofilmstrip/gui/PnlPfsProject.py:409 msgid "Import images" msgstr "Εισαγωγή εικόνων" #: photofilmstrip/gui/PnlPfsProject.py:411 #, fuzzy msgid "Image files" msgstr "Αρχεία εικόνων" #: photofilmstrip/gui/PnlPfsProject.py:654 msgid "Audio file '%s' does not exist! Continue anyway?" msgstr "Το αρχείο ήχου '%s' δεν υπάρχει! Θέλετε να συνεχίσετε οπωσδήποτε;" #: photofilmstrip/gui/PnlPfsProject.py:655 msgid "Warning" msgstr "Προειδοποίηση" #: photofilmstrip/gui/PnlSlideshow.py:30 msgid "&Properties" msgstr "Ιδιότητες" #: photofilmstrip/gui/PnlSlideshow.py:39 photofilmstrip/gui/PnlSlideshow.py:40 #: photofilmstrip/gui/PnlTimelapse.py:25 photofilmstrip/gui/PnlTimelapse.py:26 msgid "Import Pictures" msgstr "Εισαγωγή φωτογραφιών" #: photofilmstrip/gui/PnlSlideshow.py:62 photofilmstrip/gui/PnlSlideshow.py:63 #: photofilmstrip/gui/PnlTimelapse.py:41 photofilmstrip/gui/PnlTimelapse.py:42 msgid "Render filmstrip" msgstr "Απόδοση ταινίας" #: photofilmstrip/gui/PnlSlideshow.py:89 photofilmstrip/gui/PnlTimelapse.py:66 msgid "Images" msgstr "Εικόνες" #: photofilmstrip/gui/PnlSlideshow.py:94 msgid "Duration" msgstr "Διάρκεια" #: photofilmstrip/gui/PnlTimelapse.py:69 msgid "Frames" msgstr "" #: photofilmstrip/gui/PnlTimelapse.py:92 msgid "The picture counter is not increasing: %s" msgstr "" #: photofilmstrip/gui/PnlTimelapse.py:110 msgid "" "Filename '%s' does not match a number pattern which is necessary for a time " "lapse slide show!" msgstr "" #: photofilmstrip/gui/PnlWelcome.py:37 photofilmstrip/gui/PnlWelcome.py:103 msgid "Recent projects" msgstr "Πρόσφατα έργα" #: photofilmstrip/gui/PnlWelcome.py:62 msgid "Open existing project" msgstr "Άνοιγμα υπάρχοντος έργου" #: photofilmstrip/gui/PnlWelcome.py:106 msgid "How to start..." msgstr "Πως να ξεκινήσετε..." #: photofilmstrip/gui/PnlWelcome.py:107 msgid "Create a new project or load an existing one." msgstr "Δημιουργήστε ένα νέο έργο ή φορτώστε ένα υπάρχον." #: photofilmstrip/gui/PnlWelcome.py:138 msgid "Update available" msgstr "Υπάρχει διαθέσιμη ενημέρωση" #: photofilmstrip/gui/PnlWelcome.py:141 msgid "The following changes has been made:" msgstr "Έχουν γίνει οι ακόλουθες αλλαγές:" #: photofilmstrip/gui/WxProjectFile.py:59 #, fuzzy msgid "Loading project %s" msgstr "Αποθήκευση του έργου %s" #: photofilmstrip/gui/WxProjectFile.py:75 msgid "Saving project %s" msgstr "Αποθήκευση του έργου %s" #: photofilmstrip/gui/WxProjectFile.py:100 msgid "" "Some images does not exist in the folder '%s' anymore. If the files has " "moved you can select the new path. Do you want to select a new path?" msgstr "" "Κάποιες εικόνες δεν υπάρχουν πλέον στο φάκελο '%s'. Εάν τα αρχεία έχουν " "μετακινηθεί, μπορείτε να επιλέξετε τη νέα διαδρομή. Θέλετε να επιλέξετε μια " "νέα διαδρομή;" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:73 msgid "Elapsed time" msgstr "Χρόνος που πέρασε" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:85 msgid "Remaining time" msgstr "Χρόνος που απομένει" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:203 msgid "Unknown" msgstr "Άγνωστο" #: photofilmstrip/lib/jobimpl/PnlJobManager.py:50 msgid "&Clear list" msgstr "Ε&κκαθάριση λίστας" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:127 msgid "Abort" msgstr "Ματαίωση" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:133 msgid "Remove from list" msgstr "Αφαίρεση από τη λίστα" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:223 msgid "Abort selected process?" msgstr "Ματαίωση της επιλεγμένης διαδικασίας;" #: photofilmstrip/lib/jobimpl/VisualJob.py:29 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:25 msgid "Waiting..." msgstr "Αναμονή..." #: photofilmstrip/lib/jobimpl/VisualJob.py:68 #: photofilmstrip/lib/jobimpl/VisualJob.py:85 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:60 msgid "Aborted" msgstr "Ματαιώθηκε" #: photofilmstrip/lib/jobimpl/VisualJob.py:70 msgid "Done" msgstr "Ολοκληρώθηκε" #: photofilmstrip/lib/jobimpl/VisualJob.py:79 msgid "Aborting..." msgstr "Ματαίωση..." #: photofilmstrip/uwp/UwpService.py:76 msgid "Slideshow created!" msgstr "" #~ msgid "Audio files:" #~ msgstr "Αρχεία ήχου:" #~ msgid "Project properties" #~ msgstr "Ιδιότητες έργου" #~ msgid "PhotoFilmStrip project" #~ msgstr "Έργο του PhotoFilmStrip" #~ msgid "Unnamed PhotoFilmStrip" #~ msgstr "Ανώνυμο PhotoFilmStrip" #~ msgid "Project" #~ msgstr "Έργο" #~ msgid "&Batch Job" #~ msgstr "&Εργασία δέσμης" #~ msgid "&Close Project" #~ msgstr "&Κλείσιμο έργου" #~ msgid "&New Project" #~ msgstr "Νέ&ο έργο" #~ msgid "&Open Project" #~ msgstr "Ά&νοιγμα έργου" #~ msgid "&Render filmstrip" #~ msgstr "&Απόδοση ταινίας" #~ msgid "&Save Project" #~ msgstr "&Αποθήκευση έργου" #~ msgid "&Show job queue" #~ msgstr "Εμ&φάνιση ουράς εργασιών" #~ msgid "&Tools" #~ msgstr "Εργα&λεία" #~ msgid "Abort current process?" #~ msgstr "Ματαίωση της τρέχουσας διαδικασίας;" #~ msgid "Audio file:" #~ msgstr "Αρχείο ήχου:" #~ msgid "Automatic" #~ msgstr "Αυτόματα" #~ msgid "Batch file" #~ msgstr "Αρχείο δέσμης" #~ msgid "Browse" #~ msgstr "Εύρεση" #~ msgid "Cancel" #~ msgstr "Άκυρο" #~ msgid "Choose your next action:" #~ msgstr "Επιλέξτε την επόμενη ενέργειά σας:" #~ msgid "Delete unfinished result" #~ msgstr "Διαγραφή ανολοκλήρωτου αποτελέσματος" #~ msgid "Do nothing" #~ msgstr "Καμία ενέργεια" #~ msgid "Duration:" #~ msgstr "Διάρκεια:" #~ msgid "Error: %s" #~ msgstr "Σφάλμα: %s" #~ msgid "Errors occurred" #~ msgstr "Παρουσιάστηκαν σφάλματα" #~ msgid "Export %s-Project" #~ msgstr "Εξαγωγή του έργου %s" #~ msgid "Finalizing" #~ msgstr "Οριστικοποίηση" #~ msgid "Flash-Video (FLV)" #~ msgstr "Flash-Video (FLV)" #~ msgid "Import %s-Project" #~ msgstr "Εισαγωγή του έργου %s" #~ msgid "Import image" #~ msgstr "Εισαγωγή εικόνας" #~ msgid "Load Project" #~ msgstr "Φόρτωση έργου" #~ msgid "Loading pictures..." #~ msgstr "Φόρτωση φωτογραφιών..." #~ msgid "MP3-Codec (gstreamer0.10-plugins-ugly-multiverse) required!" #~ msgstr "Απαιτείται MP3-Codec (gstreamer0.10-plugins-ugly-multiverse)!" #~ msgid "Medium" #~ msgstr "Μέσο" #~ msgid "MPEG format supports only VCD, SVCD and DVD profile!" #~ msgstr "Η μορφή MPEG υποστηρίζει μόνο προφίλ VCD, SVCD και DVD!" #~ msgid "MPEG(1/2)-Video (MPG)" #~ msgstr "MPEG(1/2)-Βίντεο (MPG)" #~ msgid "MPEG4-XVid/AC3 (AVI)" #~ msgstr "MPEG4-XVid/AC3 (AVI)" #~ msgid "MPEG4-XVid/MP3 (AVI)" #~ msgstr "MPEG4-XVid/MP3 (AVI)" #~ msgid "Motion-JPEG (AVI)" #~ msgstr "Κίνηση-JPEG (AVI)" #~ msgid "New Project" #~ msgstr "Νέο έργο" #~ msgid "Open-CV (python-opencv) required!" #~ msgstr "Απαιτείται Open-CV (python-opencv)!" #~ msgid "OK" #~ msgstr "Εντάξει" #~ msgid "Please wait" #~ msgstr "Παρακαλώ περιμένετε" #~ msgid "Please wait..." #~ msgstr "Παρακαλώ περιμένετε..." #~ msgid "" #~ "Project not saved yet. Please save the project first to create a batch " #~ "job!" #~ msgstr "" #~ "Το έργο δεν έχει ακόμη αποθηκευτεί. Παρακαλώ αποθηκεύστε πρώτα το έργο, " #~ "για να δημιουργήσετε μια δέσμη εργασιών!" #~ msgid "RenderSubtitle" #~ msgstr "Απόδοση υπότιτλων" #~ msgid "Resolution:" #~ msgstr "Ανάλυση:" #~ msgid "Save Project" #~ msgstr "Αποθήκευση έργου" #~ msgid "See the logfile '%s' for details" #~ msgstr "Δείτε το αρχείο καταγραφής '%s' για λεπτομέρειες" #~ msgid "Select batch file" #~ msgstr "Επιλέξτε αρχείο δέσμης" #~ msgid "Shell script" #~ msgstr "Δέσμη ενεργειών κελύφους" #~ msgid "Show error again and send to developer." #~ msgstr "Εμφάνιση του σφάλματος ξανά και αποστολή στο δημιουργό." #~ msgid "The rendering process has been finished." #~ msgstr "Η διαδικασία απόδοσης έχει τελειώσει." #~ msgid "The rendering process was aborted." #~ msgstr "Η διαδικασία απόδοσης ματαιώθηκε." #~ msgid "The rendering process was interrupted." #~ msgstr "Η διαδικασία απόδοσης διακόπηκε." #~ msgid "Type:" #~ msgstr "Τύπος:" #~ msgid "aborting..." #~ msgstr "ματαίωση..." #~ msgid "creating output..." #~ msgstr "δημιουργία εξόδου ..." #~ msgid "false" #~ msgstr "ψευδής" #~ msgid "initialize renderer" #~ msgstr "Προετοιμασία απόδοσης" #~ msgid "invalid videonorm specified: %s" #~ msgstr "Καθορίστηκε μη έγκυρο πρότυπο βίντεο: %s" #~ msgid "mencoder (mencoder) required!" #~ msgstr "Απαιτείται mencoder (mencoder)!" #~ msgid "mencoder with MP3 support (mp3lame) required!" #~ msgstr "Απαιτείται mencoder με υποστήριξη MP3 (mp3lame)!" photofilmstrip-3.7.2/po/de.po0000644000232200023220000010527613560357351016545 0ustar debalancedebalance# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR ORGANIZATION # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PhotoFilmStrip\n" "POT-Creation-Date: 2018-11-07 22:03+CET\n" "PO-Revision-Date: 2018-11-07 21:21+0000\n" "Last-Translator: jensgoe \n" "Language-Team: Jens \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 3.2.2\n" "Generated-By: pygettext.py 1.5\n" "X-Poedit-SourceCharset: UTF-8\n" #: photofilmstrip/action/ActionAutoPath.py:23 #: photofilmstrip/gui/PnlPfsProject.py:115 msgid "Random motion" msgstr "Zufällige Bewegung" #: photofilmstrip/action/ActionCenterPath.py:21 msgid "Centralize motion" msgstr "Auswahl zentrieren" #: photofilmstrip/action/ActionI18N.py:24 #: photofilmstrip/gui/ActionManager.py:170 msgid "Language" msgstr "Sprache" #: photofilmstrip/action/ActionOpenFolder.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:28 msgid "Open folder" msgstr "Ordner öffnen" #: photofilmstrip/action/ActionPlayVideo.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:22 msgid "Play video" msgstr "Video abspielen" #: photofilmstrip/action/ActionRender.py:37 msgid "Start" msgstr "Start" #: photofilmstrip/cli/Main.py:46 photofilmstrip/cli/Main.py:196 msgid "all done" msgstr "Fertig" #: photofilmstrip/cli/Main.py:64 msgid "processing project" msgstr "Verarbeite Projekt" #: photofilmstrip/cli/Main.py:65 msgid "using renderer" msgstr "Verwende Renderer" #: photofilmstrip/cli/Main.py:66 msgid "output format" msgstr "Ausgabeformat" #: photofilmstrip/cli/Main.py:69 msgid "framerate" msgstr "Bildrate" #: photofilmstrip/cli/Main.py:103 msgid "specifies the project file" msgstr "Angabe der Projektdatei" #: photofilmstrip/cli/Main.py:104 msgid "The path where to save the output files. Use - for stdout." msgstr "Pfad, in dem die Ausgabe gespeichert wird. Verwende - für stdout." #: photofilmstrip/cli/Main.py:106 photofilmstrip/cli/Main.py:129 msgid "Option videonorm is deprecated, use an appropriate profile!" msgstr "" "Option Videonorm wird nicht mehr unterstützt. Verwende ein entsprechendes " "Profil!" #: photofilmstrip/cli/Main.py:108 msgid "enable draft mode" msgstr "Entwurfsmodus aktivieren" #: photofilmstrip/cli/Main.py:108 photofilmstrip/gui/DlgRender.py:167 msgid "" "Activate this option to generate a preview of your PhotoFilmStrip. The " "rendering process will speed up dramatically, but results in lower quality." msgstr "" "Aktivieren Sie diese Option, um eine Vorschau zu erstellen. Die Erstellung " "geht zu Lasten der Bildqualität wesentlich schneller." #: photofilmstrip/cli/Main.py:120 msgid "project file does not exist: %s" msgstr "Projektdatei nicht vorhanden: %s" #: photofilmstrip/cli/Main.py:124 msgid "no project file specified!" msgstr "Keine Projektdatei angegeben!" #: photofilmstrip/cli/Main.py:134 msgid "invalid format specified: %s" msgstr "Ungültiges Format: %s" #: photofilmstrip/cli/Main.py:140 msgid "invalid profile specified: %s" msgstr "Ungültiges Profil: %s" #: photofilmstrip/cli/Main.py:146 msgid "cannot load project" msgstr "Projekt kann nicht geladen werden" #: photofilmstrip/cli/Main.py:159 msgid "cannot create output path: %s" msgstr "Ausgabe-Verzeichnis kann nicht erstellt werden: %s" #: photofilmstrip/cli/Main.py:169 photofilmstrip/gui/DlgConfigureAudio.py:231 #: photofilmstrip/gui/DlgConfigureAudio.py:253 msgid "Audio file '%s' does not exist!" msgstr "Audio-Datei '%s' nicht vorhanden!" #: photofilmstrip/cli/Main.py:190 msgid "...aborted!" msgstr "...abgebrochen!" #: photofilmstrip/core/BaseRenderer.py:50 msgid "Unknown property: %s" msgstr "Unbekannte Eigenschaft: %s" #: photofilmstrip/core/BaseRenderer.py:58 msgid "" msgstr "" #: photofilmstrip/core/BaseRenderer.py:73 msgid "no" msgstr "nein" #: photofilmstrip/core/ProjectFile.py:222 msgid "Saving '%s' ..." msgstr "Speicher '%s' ..." #: photofilmstrip/core/ProjectFile.py:276 msgid "Loading '%s' ..." msgstr "Lade '%s' ..." #: photofilmstrip/core/RenderEngine.py:113 #: photofilmstrip/core/RenderEngine.py:201 msgid "processing transition %d/%d" msgstr "Berechne Bildübergang %d/%d" #: photofilmstrip/core/RenderEngine.py:124 #: photofilmstrip/core/RenderEngine.py:210 msgid "processing image %d/%d" msgstr "Verarbeite Bild %d/%d" #: photofilmstrip/core/renderer/CairoRenderer.py:35 msgid "Preview" msgstr "Vorschau" #: photofilmstrip/core/renderer/GStreamerRenderer.py:50 msgid "GStreamer (python-gst-1.0) required!" msgstr "GStreamer (python-gst-1.0) nicht gefunden!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:287 msgid "Bitrate must be a number!" msgstr "Bitrate muss eine Zahl sein!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:455 #: photofilmstrip/core/renderer/GStreamerRenderer.py:531 #: photofilmstrip/core/renderer/GStreamerRenderer.py:601 #: photofilmstrip/core/renderer/GStreamerRenderer.py:690 #: photofilmstrip/core/renderer/GStreamerRenderer.py:730 #: photofilmstrip/core/renderer/GStreamerRenderer.py:779 msgid "libav (gstreamer1.0-libav) required!" msgstr "libav (gstreamer1.0-libav) nicht gefunden!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:459 #: photofilmstrip/core/renderer/GStreamerRenderer.py:535 #: photofilmstrip/core/renderer/GStreamerRenderer.py:605 msgid "x264-Codec (gstreamer1.0-plugins-ugly) required!" msgstr "x264-Codec (gstreamer1.0-plugins-ugly) nicht gefunden!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:463 #: photofilmstrip/core/renderer/GStreamerRenderer.py:609 msgid "MKV-Muxer (gstreamer1.0-plugins-good) required!" msgstr "MKV-Muxer (gstreamer1.0-plugins-good) nicht gefunden!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:539 msgid "MP4-Muxer (gstreamer1.0-plugins-good) required!" msgstr "MP4-Muxer (gstreamer1.0-plugins-good) nicht gefunden!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:647 msgid "Theora-Codec (gstreamer1.0-plugins-base) required!" msgstr "Theora-Codec (gstreamer1.0-plugins-base) nicht gefunden!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:651 msgid "Vorbis-Codec (gstreamer1.0-plugins-base) required!" msgstr "Vorbis-Codec (gstreamer1.0-plugins-base) nicht gefunden!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:655 msgid "OGV-Muxer (gstreamer1.0-plugins-base) required!" msgstr "OGV-Muxer (gstreamer1.0-plugins-base) nicht gefunden!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:686 #: photofilmstrip/core/renderer/GStreamerRenderer.py:726 #: photofilmstrip/core/renderer/GStreamerRenderer.py:775 msgid "MPEG-1/2-Codec (gstreamer1.0-plugins-bad) required!" msgstr "MPEG-1/2-Codec (gstreamer1.0-plugins-bad) nicht gefunden!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:694 #: photofilmstrip/core/renderer/GStreamerRenderer.py:734 #: photofilmstrip/core/renderer/GStreamerRenderer.py:783 msgid "MPEG-Muxer (gstreamer1.0-plugins-bad) required!" msgstr "MPEG-Muxer (gstreamer1.0-plugins-bad) nicht gefunden!" #: photofilmstrip/core/renderer/SingleFileRenderer.py:21 msgid "Single pictures" msgstr "Einzelbilder" #: photofilmstrip/core/tasks.py:48 msgid "generating subtitle" msgstr "generiere Untertitel" #: photofilmstrip/gui/ActionManager.py:60 #: photofilmstrip/gui/ActionManager.py:190 msgid "&File" msgstr "&Datei" #: photofilmstrip/gui/ActionManager.py:61 #: photofilmstrip/gui/ActionManager.py:191 msgid "&Edit" msgstr "&Bearbeiten" #: photofilmstrip/gui/ActionManager.py:62 #: photofilmstrip/gui/ActionManager.py:154 photofilmstrip/gui/DlgRender.py:141 #: photofilmstrip/gui/DlgRendererProps.py:86 msgid "&Help" msgstr "&Hilfe" #: photofilmstrip/gui/ActionManager.py:76 msgid "New Slideshow" msgstr "Neue Slideshow" #: photofilmstrip/gui/ActionManager.py:81 msgid "Open" msgstr "Öffnen" #: photofilmstrip/gui/ActionManager.py:87 msgid "Save" msgstr "Speichern" #: photofilmstrip/gui/ActionManager.py:97 #: photofilmstrip/gui/ActionManager.py:98 msgid "Show job queue" msgstr "Auftragsliste zeigen" #: photofilmstrip/gui/ActionManager.py:108 #: photofilmstrip/gui/PnlSlideshow.py:25 msgid "Slideshow" msgstr "Slideshow" #: photofilmstrip/gui/ActionManager.py:110 #: photofilmstrip/gui/PnlTimelapse.py:18 msgid "Timelapse" msgstr "Zeitraffer" #: photofilmstrip/gui/ActionManager.py:116 msgid "New" msgstr "Neu" #: photofilmstrip/gui/ActionManager.py:118 msgid "&Open" msgstr "Ö&ffnen" #: photofilmstrip/gui/ActionManager.py:123 msgid "&Save" msgstr "&Speichern" #: photofilmstrip/gui/ActionManager.py:136 msgid "&Close" msgstr "S&chließen" #: photofilmstrip/gui/ActionManager.py:141 msgid "E&xit" msgstr "B&eenden" #: photofilmstrip/gui/ActionManager.py:173 msgid "&About" msgstr "&Info" #: photofilmstrip/gui/DlgBugReport.py:41 msgid "An unexpected error occured" msgstr "Ein unerwarteter Fehler ist aufgetretetn" #: photofilmstrip/gui/DlgBugReport.py:44 msgid "" "An unexpected error occured. Do you want to send this bug report to the " "developers of %s?" msgstr "" "Ein unerwarteter Fehler ist aufgetreten. Wollen Sie einen Fehlerbericht an " "die Entwickler von %s senden?" #: photofilmstrip/gui/DlgBugReport.py:99 msgid "Bug-Report send. Thank you for your support." msgstr "Fehlerbericht gesendet. Vielen Dank für die Unterstützung." #: photofilmstrip/gui/DlgBugReport.py:100 photofilmstrip/gui/FrmMain.py:290 msgid "Information" msgstr "Information" #: photofilmstrip/gui/DlgBugReport.py:106 msgid "Sorry, this function is temporary not available.." msgstr "Entschuldigung, diese Funktion ist zur Zeit nicht verfügbar." #: photofilmstrip/gui/DlgBugReport.py:107 #: photofilmstrip/gui/DlgConfigureAudio.py:232 #: photofilmstrip/gui/DlgConfigureAudio.py:244 #: photofilmstrip/gui/DlgConfigureAudio.py:254 #: photofilmstrip/gui/DlgNewProject.py:156 #: photofilmstrip/gui/DlgNewProject.py:167 #: photofilmstrip/gui/DlgPicDurationByAudio.py:208 #: photofilmstrip/gui/DlgPicDurationByAudio.py:216 #: photofilmstrip/gui/FrmMain.py:376 photofilmstrip/gui/PnlPfsProject.py:468 #: photofilmstrip/gui/PnlTimelapse.py:113 msgid "Error" msgstr "Fehler" #: photofilmstrip/gui/DlgConfigureAudio.py:55 msgid "Configure your audio files that are used as a background music." msgstr "" "Konfigurieren Sie Audio Dateien, die als Hintergrundmusik verwendet werden." #: photofilmstrip/gui/DlgConfigureAudio.py:90 msgid "Set the duration of your slideshow to fit your audio files" msgstr "Länge der Slideshow den Audio Dateien angleichen" #: photofilmstrip/gui/DlgConfigureAudio.py:92 #: photofilmstrip/gui/DlgDuration.py:70 photofilmstrip/gui/DlgNewProject.py:84 #: photofilmstrip/gui/DlgPicDurationByAudio.py:50 #: photofilmstrip/gui/DlgPositionInput.py:238 #: photofilmstrip/gui/DlgRender.py:147 #: photofilmstrip/gui/DlgRendererProps.py:92 #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:97 msgid "&Cancel" msgstr "&Abbrechen" #: photofilmstrip/gui/DlgConfigureAudio.py:97 #: photofilmstrip/gui/DlgDuration.py:72 photofilmstrip/gui/DlgNewProject.py:86 #: photofilmstrip/gui/DlgPicDurationByAudio.py:51 #: photofilmstrip/gui/DlgPositionInput.py:244 #: photofilmstrip/gui/DlgRendererProps.py:97 msgid "&Ok" msgstr "&Ok" #: photofilmstrip/gui/DlgConfigureAudio.py:104 #: photofilmstrip/gui/DlgConfigureAudio.py:109 #: photofilmstrip/gui/PnlSlideshow.py:47 photofilmstrip/gui/PnlSlideshow.py:48 #: photofilmstrip/gui/PnlTimelapse.py:33 photofilmstrip/gui/PnlTimelapse.py:34 msgid "Configure music" msgstr "Hintergrundmusik konfigurieren" #: photofilmstrip/gui/DlgConfigureAudio.py:138 msgid "Select music" msgstr "Audiodatei auswählen" #: photofilmstrip/gui/DlgConfigureAudio.py:140 msgid "Audio files" msgstr "Audiodateien" #: photofilmstrip/gui/DlgConfigureAudio.py:243 msgid "Audio file not supported!" msgstr "Audio-Datei nicht unterstützt!" #: photofilmstrip/gui/DlgDuration.py:48 msgid "Total length:" msgstr "Gesamtlänge:" #: photofilmstrip/gui/DlgDuration.py:50 msgid "" "Overrides the duration of single pictures and gives the project this total " "length." msgstr "Dauer der Einzelbilder durch diese Gesamtlänge überschreiben." #: photofilmstrip/gui/DlgDuration.py:54 msgid "User defined:" msgstr "Manuell:" #: photofilmstrip/gui/DlgDuration.py:65 msgid "Fit to audio files" msgstr "An Audiodateien angleichen" #: photofilmstrip/gui/DlgDuration.py:80 msgid "Slideshow duration" msgstr "Länge der Slideshow" #: photofilmstrip/gui/DlgDuration.py:84 msgid "Configure duration of slideshow" msgstr "Länge der Slideshow konfigurieren" #: photofilmstrip/gui/DlgNewProject.py:61 msgid "Project name:" msgstr "Projektname:" #: photofilmstrip/gui/DlgNewProject.py:66 msgid "Folder:" msgstr "Ordner:" #: photofilmstrip/gui/DlgNewProject.py:78 msgid "Aspect ratio:" msgstr "Seitenverhältnis:" #: photofilmstrip/gui/DlgNewProject.py:110 msgid "Unnamed project" msgstr "Unbenanntes Projekt" #: photofilmstrip/gui/DlgNewProject.py:116 msgid "My PhotoFilmStrips" msgstr "Eigene PhotoFilmStrips" #: photofilmstrip/gui/DlgNewProject.py:126 msgid "Browse for folder" msgstr "Ordner auswählen" #: photofilmstrip/gui/DlgNewProject.py:145 msgid "Folder does not exists! Do you want %s to create it?" msgstr "Ordner existiert nicht. Soll %s ihn erstellen?" #: photofilmstrip/gui/DlgNewProject.py:146 #: photofilmstrip/gui/PnlEditorPage.py:29 #: photofilmstrip/gui/PnlEditorPage.py:49 #: photofilmstrip/gui/PnlEditorPage.py:88 #: photofilmstrip/gui/WxProjectFile.py:101 #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:224 msgid "Question" msgstr "Frage" #: photofilmstrip/gui/DlgNewProject.py:155 msgid "Cannot create folder: %s" msgstr "Ordner kann nicht erstellt werden: %s" #: photofilmstrip/gui/DlgNewProject.py:166 msgid "Cannot write into folder!" msgstr "Ordner nicht beschreibbar!" #: photofilmstrip/gui/DlgNewProject.py:180 msgid "The project name must be filled." msgstr "Bitte einen Projektnamen angeben." #: photofilmstrip/gui/DlgNewProject.py:186 msgid "The project name contains invalid characters." msgstr "Der Projektname enthält ungültige Zeichen." #: photofilmstrip/gui/DlgPicDurationByAudio.py:23 #: photofilmstrip/gui/PnlSlideshow.py:54 photofilmstrip/gui/PnlSlideshow.py:55 msgid "Adjust picture durations" msgstr "Anzeigedauer für Bilder einstellen" #: photofilmstrip/gui/DlgPicDurationByAudio.py:26 msgid "Adjust picture durations to audio file" msgstr "Anzeigedauer der Bilder an Musik anpassen" #: photofilmstrip/gui/DlgPicDurationByAudio.py:30 msgid "" "Find your picture duration by playing the audio file of your project and\n" "pressing the hit button to apply the current playing time." msgstr "" "In diesem Dialog können sie die Anzeigedauer der Bilder an die Musik " "anpassen.\n" "Drücken sie 'Abspielen' und anschließend für jedes Bild die Hit-" "Schaltfläche, wenn\n" "eine markante Stelle im Lied ertönt. Die aktuelle Position wird in die " "Anzeigedauer\n" "automatisch umgerechnet und nach Klicken auf Ok übernommen." #: photofilmstrip/gui/DlgPicDurationByAudio.py:43 #: photofilmstrip/gui/DlgPicDurationByAudio.py:153 msgid "Play" msgstr "Abspielen" #: photofilmstrip/gui/DlgPicDurationByAudio.py:46 msgid "Hit" msgstr "Hit" #: photofilmstrip/gui/DlgPicDurationByAudio.py:100 msgid "Stop" msgstr "Stop" #: photofilmstrip/gui/DlgPicDurationByAudio.py:179 msgid "Playing time" msgstr "Position" #: photofilmstrip/gui/DlgPicDurationByAudio.py:207 msgid "Your project does not have an audio file configured." msgstr "In ihrem Projekt ist keine Musik eingestellt." #: photofilmstrip/gui/DlgPicDurationByAudio.py:215 msgid "" "Your project uses more than one audio file. Currently the durations can be " "adjusted only for one audio file." msgstr "" "Ihr Projekt verwendet mehr als ein Musiktitel. Die Anzeigedauer kann nur für " "einen Titel eingestellt werden." #: photofilmstrip/gui/DlgPositionInput.py:140 msgid "Motion positions" msgstr "Bewegungspfad" #: photofilmstrip/gui/DlgPositionInput.py:147 msgid "Start position" msgstr "Startposition" #: photofilmstrip/gui/DlgPositionInput.py:155 #: photofilmstrip/gui/DlgPositionInput.py:199 msgid "Location:" msgstr "Position:" #: photofilmstrip/gui/DlgPositionInput.py:173 #: photofilmstrip/gui/DlgPositionInput.py:215 msgid "Size:" msgstr "Größe:" #: photofilmstrip/gui/DlgPositionInput.py:191 msgid "End position" msgstr "Zielposition" #: photofilmstrip/gui/DlgPositionInput.py:233 msgid "Reset" msgstr "Zurücksetzen" #: photofilmstrip/gui/DlgPositionInput.py:252 msgid "Adjust motion positions directly" msgstr "Bewegungspfad manuell anpassen" #: photofilmstrip/gui/DlgRender.py:96 msgid "Render project" msgstr "Video erstellen" #: photofilmstrip/gui/DlgRender.py:107 msgid "Format:" msgstr "Format:" #: photofilmstrip/gui/DlgRender.py:122 msgid "Properties" msgstr "Eigenschaften" #: photofilmstrip/gui/DlgRender.py:127 msgid "Profile:" msgstr "Profil:" #: photofilmstrip/gui/DlgRender.py:136 msgid "Draft" msgstr "Entwurf" #: photofilmstrip/gui/DlgRender.py:152 msgid "&Start" msgstr "&Start" #: photofilmstrip/gui/DlgRender.py:164 msgid "Configure output and start render process" msgstr "Ausgabe konfigurieren und erzeugen" #: photofilmstrip/gui/DlgRendererProps.py:50 msgid "Property" msgstr "Eigenschaft" #: photofilmstrip/gui/DlgRendererProps.py:52 msgid "Value" msgstr "Wert" #: photofilmstrip/gui/DlgRendererProps.py:71 msgid "Output properties" msgstr "Videoeigenschaften" #: photofilmstrip/gui/DlgRendererProps.py:113 msgid "Edit extended output properties" msgstr "Erweiterte Videoeigenschaften bearbeiten" #: photofilmstrip/gui/DlgRendererProps.py:147 msgid "Edit property" msgstr "Eigenschaft bearbeiten" #: photofilmstrip/gui/FrmMain.py:83 msgid "Welcome" msgstr "Willkommen" #: photofilmstrip/gui/FrmMain.py:85 msgid "Job queue" msgstr "Aufträge" #: photofilmstrip/gui/FrmMain.py:141 msgid "Rendering in progress..." msgstr "Wird erstellt..." #: photofilmstrip/gui/FrmMain.py:234 photofilmstrip/gui/PnlWelcome.py:57 msgid "Create new slideshow" msgstr "Neue Slideshow erstellen" #: photofilmstrip/gui/FrmMain.py:241 msgid "Create new timelapse" msgstr "Neuen Zeitraffer erstellen" #: photofilmstrip/gui/FrmMain.py:249 msgid "Select %s-Project" msgstr "%s-Projekt auswählen" #: photofilmstrip/gui/FrmMain.py:251 msgid "Files" msgstr "Dateien" #: photofilmstrip/gui/FrmMain.py:289 msgid "You must restart %s for your new language setting to take effect." msgstr "" "Starten Sie %s neu, damit die neuen Spracheinstellungen wirksam werden." #: photofilmstrip/gui/FrmMain.py:300 msgid "" "PhotoFilmStrip creates movies out of your pictures in just 3 steps. First " "select your photos, customize the motion path and render the video. There " "are several output possibilities for VCD, SVCD, DVD up to FULL-HD." msgstr "" "PhotoFilmStrip erstellt Videoclips aus Digitalfotos in nur 3 Schritten. " "Fotos auswählen, Bewegung anpassen und Video erstellen lassen. Verfügbar " "sind Formate für VCD, SVCD, DVD bis hin zu FULL-HD." #: photofilmstrip/gui/FrmMain.py:303 msgid "online" msgstr "Online" #: photofilmstrip/gui/FrmMain.py:374 msgid "Invalid %(app)s-Project: %(file)s" msgstr "Kein gültiges %(app)s-Projekt: %(file)s" #: photofilmstrip/gui/PnlAddPics.py:50 photofilmstrip/gui/PnlWelcome.py:30 msgid "Welcome to PhotoFilmStrip" msgstr "Willkommen zu PhotoFilmStrip" #: photofilmstrip/gui/PnlAddPics.py:52 msgid "" "Drag some pictures onto this text or\n" "click the button below\n" "to add pictures to your new PhotoFilmStrip." msgstr "" "Ziehen Sie Bilder auf diesen Text oder\n" "benutzen Sie die Schaltfläche unten, um\n" "Bilder zu Ihrem neuen PhotoFilmStrip hinzuzufügen." #: photofilmstrip/gui/PnlEditPicture.py:142 msgid "Settings" msgstr "Einstellungen" #: photofilmstrip/gui/PnlEditPicture.py:146 msgid "Rotation:" msgstr "Drehung:" #: photofilmstrip/gui/PnlEditPicture.py:166 msgid "Effect:" msgstr "Effekt:" #: photofilmstrip/gui/PnlEditPicture.py:180 msgid "Process" msgstr "Bildablauf" #: photofilmstrip/gui/PnlEditPicture.py:184 msgid "Movement:" msgstr "Bewegung:" #: photofilmstrip/gui/PnlEditPicture.py:196 #: photofilmstrip/gui/PnlEditPicture.py:212 #: photofilmstrip/gui/PnlEditPicture.py:359 msgid "sec" msgstr "Sek" #: photofilmstrip/gui/PnlEditPicture.py:200 msgid "Transition:" msgstr "Bildübergang:" #: photofilmstrip/gui/PnlEditPicture.py:220 msgid "Subtitle" msgstr "Untertitel" #: photofilmstrip/gui/PnlEditPicture.py:240 msgid "Linear" msgstr "Gleichförmig" #: photofilmstrip/gui/PnlEditPicture.py:241 msgid "Accelerated" msgstr "Beschleunigen" #: photofilmstrip/gui/PnlEditPicture.py:242 msgid "Delayed" msgstr "Verzögern" #: photofilmstrip/gui/PnlEditPicture.py:250 msgid "No effect" msgstr "Kein Effekt" #: photofilmstrip/gui/PnlEditPicture.py:251 msgid "Black and White" msgstr "Schwarz-Weiss" #: photofilmstrip/gui/PnlEditPicture.py:252 msgid "Sepia tone" msgstr "Sephia-Effekt" #: photofilmstrip/gui/PnlEditPicture.py:258 msgid "None" msgstr "Keiner" #: photofilmstrip/gui/PnlEditPicture.py:259 msgid "Fade" msgstr "Überblenden" #: photofilmstrip/gui/PnlEditPicture.py:260 msgid "Roll" msgstr "Rollen" #: photofilmstrip/gui/PnlEditPicture.py:354 msgid "fpp" msgstr "fpp" #: photofilmstrip/gui/PnlEditPicture.py:355 msgid "frames per picture - the number of frames each picture will be shown" msgstr "" "frames per picture - Die Anzahl der Einzelbilder im Video für jedes Bild" #: photofilmstrip/gui/PnlEditorPage.py:26 msgid "Could not save the file '%(file)s': %(errMsg)s" msgstr "Konnte Datei '%(file)s' nicht speichern: %(errMsg)s" #: photofilmstrip/gui/PnlEditorPage.py:45 msgid "New file" msgstr "Neue Datei" #: photofilmstrip/gui/PnlEditorPage.py:48 msgid "'%s' has been modified. Save changes?" msgstr "'%s' wurde geändert. Änderungen speichern?" #: photofilmstrip/gui/PnlEditorPage.py:74 msgid "Save %s" msgstr "Speicher %s" #: photofilmstrip/gui/PnlEditorPage.py:77 msgid "File" msgstr "Datei" #: photofilmstrip/gui/PnlEditorPage.py:87 msgid "Overwrite existing file '%s'?" msgstr "Bestehende Datei '%s' überschreiben?" #: photofilmstrip/gui/PnlPfsProject.py:118 #: photofilmstrip/gui/PnlPfsProject.py:120 msgid "Set motion start to end" msgstr "Startauswahl zu Endauswahl" #: photofilmstrip/gui/PnlPfsProject.py:122 #: photofilmstrip/gui/PnlPfsProject.py:124 msgid "Set motion end to start" msgstr "Endauswahl zu Startauswahl" #: photofilmstrip/gui/PnlPfsProject.py:126 #: photofilmstrip/gui/PnlPfsProject.py:128 msgid "Swap motion" msgstr "Start- und Zielauswahl tauschen" #: photofilmstrip/gui/PnlPfsProject.py:131 #: photofilmstrip/gui/PnlPfsProject.py:133 msgid "Adjust motion manual" msgstr "Bewegung manuell eingeben" #: photofilmstrip/gui/PnlPfsProject.py:136 #: photofilmstrip/gui/PnlPfsProject.py:138 msgid "Preserve image dimension" msgstr "Bildgrößenbeschränkung aufheben" #: photofilmstrip/gui/PnlPfsProject.py:294 msgid "&Import Pictures" msgstr "Bilder &importieren" #: photofilmstrip/gui/PnlPfsProject.py:299 msgid "Move picture &left" msgstr "Bild nach &links" #: photofilmstrip/gui/PnlPfsProject.py:303 msgid "Move picture &right" msgstr "Bild nach re&chts" #: photofilmstrip/gui/PnlPfsProject.py:308 msgid "R&emove Picture" msgstr "Bild &entfernen" #: photofilmstrip/gui/PnlPfsProject.py:313 msgid "Rotate &clockwise" msgstr "Im Uhrzeigersinn d&rehen" #: photofilmstrip/gui/PnlPfsProject.py:317 msgid "Rotate counter clock&wise" msgstr "&Gegen Uhrzeigersinn drehen" #: photofilmstrip/gui/PnlPfsProject.py:322 msgid "Random &motion" msgstr "Zufällige Bewegung" #: photofilmstrip/gui/PnlPfsProject.py:326 msgid "Centralize m&otion" msgstr "Auswahl &zentrieren" #: photofilmstrip/gui/PnlPfsProject.py:384 msgid "Export slideshow" msgstr "Slideshow exportieren" #: photofilmstrip/gui/PnlPfsProject.py:387 #: photofilmstrip/gui/PnlPfsProject.py:400 msgid "Portable slideshow" msgstr "Transportable Slideshow" #: photofilmstrip/gui/PnlPfsProject.py:398 msgid "Import Slideshow" msgstr "Slideshow importieren" #: photofilmstrip/gui/PnlPfsProject.py:409 msgid "Import images" msgstr "Bilder importieren" #: photofilmstrip/gui/PnlPfsProject.py:411 msgid "Image files" msgstr "Bilddateien" #: photofilmstrip/gui/PnlPfsProject.py:654 msgid "Audio file '%s' does not exist! Continue anyway?" msgstr "Audio-Datei '%s' nicht vorhanden! Dennoch fortsetzen?" #: photofilmstrip/gui/PnlPfsProject.py:655 msgid "Warning" msgstr "Warnung" #: photofilmstrip/gui/PnlSlideshow.py:30 msgid "&Properties" msgstr "&Eigenschaften" #: photofilmstrip/gui/PnlSlideshow.py:39 photofilmstrip/gui/PnlSlideshow.py:40 #: photofilmstrip/gui/PnlTimelapse.py:25 photofilmstrip/gui/PnlTimelapse.py:26 msgid "Import Pictures" msgstr "Bilder importieren" #: photofilmstrip/gui/PnlSlideshow.py:62 photofilmstrip/gui/PnlSlideshow.py:63 #: photofilmstrip/gui/PnlTimelapse.py:41 photofilmstrip/gui/PnlTimelapse.py:42 msgid "Render filmstrip" msgstr "Filmstreifen erstellen" #: photofilmstrip/gui/PnlSlideshow.py:89 photofilmstrip/gui/PnlTimelapse.py:66 msgid "Images" msgstr "Bilder" #: photofilmstrip/gui/PnlSlideshow.py:94 msgid "Duration" msgstr "Dauer" #: photofilmstrip/gui/PnlTimelapse.py:69 msgid "Frames" msgstr "Einzelbilder" #: photofilmstrip/gui/PnlTimelapse.py:92 msgid "The picture counter is not increasing: %s" msgstr "Die Dateinummerierung ist nicht fortlaufend: %s" #: photofilmstrip/gui/PnlTimelapse.py:110 msgid "" "Filename '%s' does not match a number pattern which is necessary for a time " "lapse slide show!" msgstr "" "Datei '%s' enthält kein Zahlenmuster, das aber für Zeitraffer-Slideshows " "erforderlich ist!" #: photofilmstrip/gui/PnlWelcome.py:37 photofilmstrip/gui/PnlWelcome.py:103 msgid "Recent projects" msgstr "Letzte Projekte" #: photofilmstrip/gui/PnlWelcome.py:62 msgid "Open existing project" msgstr "Ein bestehendes Projekt laden" #: photofilmstrip/gui/PnlWelcome.py:106 msgid "How to start..." msgstr "Der Anfang..." #: photofilmstrip/gui/PnlWelcome.py:107 msgid "Create a new project or load an existing one." msgstr "" "Erstellen Sie ein neues Projekt oder laden Sie ein bereits existierendes." #: photofilmstrip/gui/PnlWelcome.py:138 msgid "Update available" msgstr "Neue Version verfügbar" #: photofilmstrip/gui/PnlWelcome.py:141 msgid "The following changes has been made:" msgstr "Die folgenden Änderungen wurden vorgenommen:" #: photofilmstrip/gui/WxProjectFile.py:59 msgid "Loading project %s" msgstr "Projekt %s laden" #: photofilmstrip/gui/WxProjectFile.py:75 msgid "Saving project %s" msgstr "Projekt %s speichern" #: photofilmstrip/gui/WxProjectFile.py:100 msgid "" "Some images does not exist in the folder '%s' anymore. If the files has " "moved you can select the new path. Do you want to select a new path?" msgstr "" "Einige Bilder aus dem Ordner '%s' existieren nicht mehr. Falls die Dateien " "verschoben wurden, kann jetzt der neue Pfad ausgewählt werden. Soll ein " "neuer Pfad gewählt werden?" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:73 msgid "Elapsed time" msgstr "Verstrichene Zeit" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:85 msgid "Remaining time" msgstr "Verbleibende Zeit" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:203 msgid "Unknown" msgstr "Unbekannt" #: photofilmstrip/lib/jobimpl/PnlJobManager.py:50 msgid "&Clear list" msgstr "Liste &leeren" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:127 msgid "Abort" msgstr "Abbrechen" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:133 msgid "Remove from list" msgstr "Von Liste entfernen" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:223 msgid "Abort selected process?" msgstr "Aktuellen Vorgang abbrechen?" #: photofilmstrip/lib/jobimpl/VisualJob.py:29 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:25 msgid "Waiting..." msgstr "Warte..." #: photofilmstrip/lib/jobimpl/VisualJob.py:68 #: photofilmstrip/lib/jobimpl/VisualJob.py:85 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:60 msgid "Aborted" msgstr "Abgebrochen" #: photofilmstrip/lib/jobimpl/VisualJob.py:70 msgid "Done" msgstr "Fertig" #: photofilmstrip/lib/jobimpl/VisualJob.py:79 msgid "Aborting..." msgstr "Breche ab..." #: photofilmstrip/uwp/UwpService.py:76 msgid "Slideshow created!" msgstr "Slideshow erstellt!" #~ msgid "Audio files:" #~ msgstr "Audiodateien:" #~ msgid "Project properties" #~ msgstr "Projekteigenschaften" #~ msgid "PhotoFilmStrip project" #~ msgstr "PhotoFilmStrip-Projekt" #~ msgid "Unnamed PhotoFilmStrip" #~ msgstr "Unbenannter PhotoFilmStrip" #~ msgid "Project" #~ msgstr "Projekt" #~ msgid "invalid videonorm specified: %s" #~ msgstr "Videonorm ungültig: %s" #~ msgid "&Tools" #~ msgstr "&Extras" #~ msgid "New Project" #~ msgstr "Neues Projekt" #~ msgid "Load Project" #~ msgstr "Projekt laden" #~ msgid "Save Project" #~ msgstr "Projekt speichern" #~ msgid "&New Project" #~ msgstr "&Neues Projekt" #~ msgid "&Open Project" #~ msgstr "Pr&ojekt öffnen" #~ msgid "&Save Project" #~ msgstr "Projekt &speichern" #~ msgid "&Close Project" #~ msgstr "Projekt s&chließen" #~ msgid "&Render filmstrip" #~ msgstr "&Filmstreifen erstellen" #~ msgid "&Show job queue" #~ msgstr "Auftragsliste &zeigen" #~ msgid "Resolution:" #~ msgstr "Auflösung:" #~ msgid "Type:" #~ msgstr "Typ:" #~ msgid "Automatic" #~ msgstr "Automatisch" #~ msgid "Export %s-Project" #~ msgstr "%s-Projekt exportieren" #~ msgid "Portable" #~ msgstr "Mitnehm" #~ msgid "Import %s-Project" #~ msgstr "%s-Projekt importieren" #~ msgid "MP3-Codec (gstreamer0.10-plugins-ugly-multiverse) required!" #~ msgstr "MP3-Codec (gstreamer0.10-plugins-ugly-multiverse) nicht gefunden!" #~ msgid "mencoder (mencoder) required!" #~ msgstr "mencoder (mencoder) nicht gefunden!" #~ msgid "MPEG format supports only VCD, SVCD and DVD profile!" #~ msgstr "MPEG-Format unterstützt nur die Profile VCD, SVCD und DVD!" #~ msgid "MPEG4-XVid/AC3 (AVI)" #~ msgstr "MPEG4-XVid/AC3 (AVI)" #~ msgid "mencoder with MP3 support (mp3lame) required!" #~ msgstr "mencoder mit MP3-Unterstützung (mp3lame) erforderlich!" #~ msgid "MPEG4-XVid/MP3 (AVI)" #~ msgstr "MPEG4-XVid/MP3 (AVI)" #~ msgid "Flash-Video (FLV)" #~ msgstr "Flash-Video (FLV)" #~ msgid "Motion-JPEG (AVI)" #~ msgstr "Motion-JPEG (AVI)" #~ msgid "Open-CV (python-opencv) required!" #~ msgstr "Open-CV (python-opencv) nicht gefunden!" #~ msgid "Audio file:" #~ msgstr "Audiodatei:" #~ msgid "Please wait..." #~ msgstr "Bitte warten" #~ msgid "aborting..." #~ msgstr "abbrechen..." #~ msgid "MPEG(1/2)-Video (MPG)" #~ msgstr "MPEG(1/2)-Video (MPG)" #~ msgid "Error: %s" #~ msgstr "Fehler: %s" #~ msgid "initialize renderer" #~ msgstr "Initialisiere" #~ msgid "creating output..." #~ msgstr "Ausgabe erstellen..." #~ msgid "Finalizing" #~ msgstr "Abschließen" #~ msgid "Choose your next action:" #~ msgstr "Was möchten Sie tun:" #~ msgid "Delete unfinished result" #~ msgstr "Unfertige Dateien löschen" #~ msgid "Do nothing" #~ msgstr "Nichts" #~ msgid "Show error again and send to developer." #~ msgstr "Fehler erneut zeigen und zum Entwickler senden." #~ msgid "The rendering process was aborted." #~ msgstr "Der Erstellungsprozess wurde abgebrochen." #~ msgid "The rendering process was interrupted." #~ msgstr "Der Erstellungsprozess wurde unterbrochen." #~ msgid "The rendering process has been finished." #~ msgstr "Der Erstellungsprozess wurde abgeschlossen." #~ msgid "&Batch Job" #~ msgstr "&Batch Auftrag" #~ msgid "" #~ "Project not saved yet. Please save the project first to create a batch " #~ "job!" #~ msgstr "" #~ "Projekt wurde noch nicht gespeichert. Zum Erstellen von Batch-Aufträgen " #~ "bitte erst das Projekt speichern." #~ msgid "Batch file" #~ msgstr "Stapel-Datei" #~ msgid "Shell script" #~ msgstr "Shell-Script" #~ msgid "Select batch file" #~ msgstr "Stapelverarbeitungsdatei wählen" #~ msgid "Duration:" #~ msgstr "Dauer:" #~ msgid "Browse" #~ msgstr "Durchsuchen" #~ msgid "Import image" #~ msgstr "Bild importieren" #~ msgid "Please wait" #~ msgstr "Bitte warten" #~ msgid "Loading pictures..." #~ msgstr "Bilder laden..." #~ msgid "Invalid audio file!" #~ msgstr "Ungültige Audio-Datei" #~ msgid "processing audiofile..." #~ msgstr "Verarbeite Audio-Datei..." #~ msgid "Video clip (AVI)" #~ msgstr "Videodatei (AVI)" #, fuzzy #~ msgid "Audio file does not exist: %s" #~ msgstr "Audio-Datei nicht vorhanden: %s" #~ msgid "" #~ "The path where to save the output files. If single file renderer is used, " #~ "this option can be omitted to use stdout." #~ msgstr "" #~ "Pfad, in dem die Ausgabe gespeichert wird. Wenn Einzelbild-Ausgabe " #~ "verwendet wird, kann die Option weggelassen werden und die Ausgabe wird " #~ "nach stdout umgeleitet." #~ msgid "total length of the PhotoFilmStrip (seconds)" #~ msgstr "Gesamtlänge vom PhotoFilmStrip in Sekunden" #~ msgid "use audiofile as audiotrack (use --length to limit the movie length)" #~ msgstr "" #~ "Verwende eine Audio-Datei als Tonspur (Video-Länge mit --length Option " #~ "einschränken)" #~ msgid "no outputpath specified!" #~ msgstr "Ausgabepfad erforderlich!" #~ msgid "Directory:" #~ msgstr "Ordner:" #~ msgid "Select a directory" #~ msgstr "Ordner auswählen" #, fuzzy #~ msgid "Cancel" #~ msgstr "&Abbrechen" #, fuzzy #~ msgid "Ok" #~ msgstr "&Ok" #~ msgid "No media support found on this platform!" #~ msgstr "Video-Unterstützung auf dieser Plattform nicht verfügbar!" #~ msgid "Adjust motion" #~ msgstr "Bewegung anpassen" #~ msgid "Output" #~ msgstr "Ausgabe" #~ msgid "Mode:" #~ msgstr "Modus:" #~ msgid "Standard" #~ msgstr "Normal" #~ msgid "Advanced" #~ msgstr "Erweitert" #~ msgid "Translators" #~ msgstr "Übersetzer" #~ msgid "Duration (sec):" #~ msgstr "Dauer (Sek):" #~ msgid "English" #~ msgstr "English" #~ msgid "French" #~ msgstr "Francais" #~ msgid "German" #~ msgstr "Deutsch" #~ msgid "Czech" #~ msgstr "Český" #~ msgid "Open &recent" #~ msgstr "Zuletzt &verwendet" #~ msgid "Save Project &as" #~ msgstr "Projekt speichern &unter" #~ msgid "&Import Project" #~ msgstr "Projekt &importieren" #~ msgid "&Export Project" #~ msgstr "Projekt &exportieren" #~ msgid "Sec." #~ msgstr "Sek." #~ msgid "Output path is not empty! Use it anyway?" #~ msgstr "Ausgabeordner nicht leer. Dennoch verwenden?" #~ msgid "New version available" #~ msgstr "Neue Version verfügbar" #~ msgid "Close" #~ msgstr "S&chließen" #~ msgid "Goto download site" #~ msgstr "Gehe zur Download-Seite" #~ msgid "ppmtoy4m (mjpegtools) required!" #~ msgstr "ppmtoy4m (mjpegtools) nicht gefunden!" #~ msgid "prepare" #~ msgstr "vorbereiten" #~ msgid "crop and resize" #~ msgstr "Zuschneiden und Größe ändern" #~ msgid "Single pictures (shellscript)" #~ msgstr "Einzelbilder (Shellscript)" #~ msgid "convert (imagemagick) required!" #~ msgstr "convert (imagemagick) nicht gefunden!" #~ msgid "composite (imagemagick) required!" #~ msgstr "composite (imagemagick) nicht gefunden!" #~ msgid "Help will be available soon." #~ msgstr "Hilfe bald verfügbar." #~ msgid "one of: VCD, SVCD, DVD, Medium, HD, FULL-HD" #~ msgstr "VCD, SVCD, DVD, Medium, HD oder FULL-HD" #~ msgid "" #~ "0=Single pictures, 1=Shellscript, 2=MPEG-Video (fast), 3=MPEG-Video (HQ)" #~ msgstr "" #~ "0=Einzelbilder, 1=Shellscript, 2=MPEG-Video (schnell), 3=MPEG-Video (HQ)" #~ msgid "MPEG-Video (fast)" #~ msgstr "MPEG-Video (schnell)" #~ msgid "MPEG-Video (HQ; slow)" #~ msgstr "MPEG-Video (HQ; langsam)" #~ msgid "Render Story" #~ msgstr "Slideshow erstellen" #~ msgid "&Import Pictures\tCtrl+I" #~ msgstr "Bilder &importieren\tCtrl+I" photofilmstrip-3.7.2/po/it.po0000644000232200023220000007376613560357351016601 0ustar debalancedebalance# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR ORGANIZATION # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PhotoFilmStrip\n" "POT-Creation-Date: 2018-11-07 22:03+CET\n" "PO-Revision-Date: 2018-10-24 10:00+0100\n" "Last-Translator: Giacomo Zanobini \n" "Language-Team: Giacomo Zanobini \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: pygettext.py 1.5\n" "X-Poedit-Language: Italian\n" "X-Poedit-Country: ITALY\n" "X-Poedit-SourceCharset: utf-8\n" #: photofilmstrip/action/ActionAutoPath.py:23 #: photofilmstrip/gui/PnlPfsProject.py:115 msgid "Random motion" msgstr "Movimento casuale" #: photofilmstrip/action/ActionCenterPath.py:21 msgid "Centralize motion" msgstr "Movimento al centro" #: photofilmstrip/action/ActionI18N.py:24 #: photofilmstrip/gui/ActionManager.py:170 msgid "Language" msgstr "Lingua" #: photofilmstrip/action/ActionOpenFolder.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:28 msgid "Open folder" msgstr "Apri cartella" #: photofilmstrip/action/ActionPlayVideo.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:22 msgid "Play video" msgstr "Riproduci il video" #: photofilmstrip/action/ActionRender.py:37 #, fuzzy msgid "Start" msgstr "Inizia" #: photofilmstrip/cli/Main.py:46 photofilmstrip/cli/Main.py:196 msgid "all done" msgstr "finito tutto" #: photofilmstrip/cli/Main.py:64 msgid "processing project" msgstr "eleborazione in corso" #: photofilmstrip/cli/Main.py:65 msgid "using renderer" msgstr "" #: photofilmstrip/cli/Main.py:66 msgid "output format" msgstr "formato di output" #: photofilmstrip/cli/Main.py:69 msgid "framerate" msgstr "frame al secondo" #: photofilmstrip/cli/Main.py:103 msgid "specifies the project file" msgstr "selezionare il file di progetto" #: photofilmstrip/cli/Main.py:104 msgid "The path where to save the output files. Use - for stdout." msgstr "Il percorso dove salvare i file in output. Usa - per stdout" #: photofilmstrip/cli/Main.py:106 photofilmstrip/cli/Main.py:129 msgid "Option videonorm is deprecated, use an appropriate profile!" msgstr "L'opzione videonorm è deprecata, usa un profilo appropriato!" #: photofilmstrip/cli/Main.py:108 msgid "enable draft mode" msgstr "abilita modalità bozza" #: photofilmstrip/cli/Main.py:108 photofilmstrip/gui/DlgRender.py:167 msgid "" "Activate this option to generate a preview of your PhotoFilmStrip. The " "rendering process will speed up dramatically, but results in lower quality." msgstr "" "Attiva questa opzione per generare un'anteprima del tuo PhotoFilmStrip. Il " "processo di rendering si velocizzerà notevolmente, ma i risultati saranno di " "minor qualita'" #: photofilmstrip/cli/Main.py:120 msgid "project file does not exist: %s" msgstr "il file di progetto non esiste: %s" #: photofilmstrip/cli/Main.py:124 msgid "no project file specified!" msgstr "nessun file di progetto è stato specificato" #: photofilmstrip/cli/Main.py:134 msgid "invalid format specified: %s" msgstr "formato specificato non valido: %s" #: photofilmstrip/cli/Main.py:140 msgid "invalid profile specified: %s" msgstr "profilo specificato non valido: %s" #: photofilmstrip/cli/Main.py:146 #, fuzzy msgid "cannot load project" msgstr "impossibile caricare photofilmstrip" #: photofilmstrip/cli/Main.py:159 msgid "cannot create output path: %s" msgstr "impossibile creare il percorso per l'output: %s" #: photofilmstrip/cli/Main.py:169 photofilmstrip/gui/DlgConfigureAudio.py:231 #: photofilmstrip/gui/DlgConfigureAudio.py:253 msgid "Audio file '%s' does not exist!" msgstr "Il file audio '%s' non esiste!" #: photofilmstrip/cli/Main.py:190 msgid "...aborted!" msgstr "...annullato!" #: photofilmstrip/core/BaseRenderer.py:50 msgid "Unknown property: %s" msgstr "Proprieta' sconosciuta: %s" #: photofilmstrip/core/BaseRenderer.py:58 msgid "" msgstr "" #: photofilmstrip/core/BaseRenderer.py:73 msgid "no" msgstr "no" #: photofilmstrip/core/ProjectFile.py:222 #, fuzzy msgid "Saving '%s' ..." msgstr "Salvataggio in corso '%s' ..." #: photofilmstrip/core/ProjectFile.py:276 msgid "Loading '%s' ..." msgstr "Caricamento in corso '%s' ..." #: photofilmstrip/core/RenderEngine.py:113 #: photofilmstrip/core/RenderEngine.py:201 msgid "processing transition %d/%d" msgstr "elaborazione transizione %d/%d" #: photofilmstrip/core/RenderEngine.py:124 #: photofilmstrip/core/RenderEngine.py:210 msgid "processing image %d/%d" msgstr "elaborazione immagine %d/%d" #: photofilmstrip/core/renderer/CairoRenderer.py:35 msgid "Preview" msgstr "Anteprima" #: photofilmstrip/core/renderer/GStreamerRenderer.py:50 msgid "GStreamer (python-gst-1.0) required!" msgstr "GStreamer (python-gst-1.0) è richiesto!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:287 msgid "Bitrate must be a number!" msgstr "Bitrate deve essere un numero!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:455 #: photofilmstrip/core/renderer/GStreamerRenderer.py:531 #: photofilmstrip/core/renderer/GStreamerRenderer.py:601 #: photofilmstrip/core/renderer/GStreamerRenderer.py:690 #: photofilmstrip/core/renderer/GStreamerRenderer.py:730 #: photofilmstrip/core/renderer/GStreamerRenderer.py:779 msgid "libav (gstreamer1.0-libav) required!" msgstr "libav (gstreamer1.0-libav) è richiesto" #: photofilmstrip/core/renderer/GStreamerRenderer.py:459 #: photofilmstrip/core/renderer/GStreamerRenderer.py:535 #: photofilmstrip/core/renderer/GStreamerRenderer.py:605 msgid "x264-Codec (gstreamer1.0-plugins-ugly) required!" msgstr "x264-Codec (gstreamer1.0-plugins-ugly) è richiesto" #: photofilmstrip/core/renderer/GStreamerRenderer.py:463 #: photofilmstrip/core/renderer/GStreamerRenderer.py:609 msgid "MKV-Muxer (gstreamer1.0-plugins-good) required!" msgstr "MKV-Muxer (gstreamer1.0-plugins-good) è richiesto!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:539 msgid "MP4-Muxer (gstreamer1.0-plugins-good) required!" msgstr "MP4-Muxer (gstreamer1.0-plugins-good) è richiesto!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:647 msgid "Theora-Codec (gstreamer1.0-plugins-base) required!" msgstr "Theora-Codec (gstreamer1.0-plugins-base) è richiesto!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:651 msgid "Vorbis-Codec (gstreamer1.0-plugins-base) required!" msgstr "Vorbis-Codec (gstreamer1.0-plugins-base) è richiesto!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:655 msgid "OGV-Muxer (gstreamer1.0-plugins-base) required!" msgstr "OGV-Muxer (gstreamer1.0-plugins-base) è richiesto!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:686 #: photofilmstrip/core/renderer/GStreamerRenderer.py:726 #: photofilmstrip/core/renderer/GStreamerRenderer.py:775 msgid "MPEG-1/2-Codec (gstreamer1.0-plugins-bad) required!" msgstr "MPEG-1/2-Codec (gstreamer1.0-plugins-bad) è richiesto!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:694 #: photofilmstrip/core/renderer/GStreamerRenderer.py:734 #: photofilmstrip/core/renderer/GStreamerRenderer.py:783 msgid "MPEG-Muxer (gstreamer1.0-plugins-bad) required!" msgstr "MPEG-Muxer (gstreamer1.0-plugins-bad) è richiesto!" #: photofilmstrip/core/renderer/SingleFileRenderer.py:21 msgid "Single pictures" msgstr "Immagini singole" #: photofilmstrip/core/tasks.py:48 msgid "generating subtitle" msgstr "generazione in corso del sottotitolo" #: photofilmstrip/gui/ActionManager.py:60 #: photofilmstrip/gui/ActionManager.py:190 msgid "&File" msgstr "&File" #: photofilmstrip/gui/ActionManager.py:61 #: photofilmstrip/gui/ActionManager.py:191 msgid "&Edit" msgstr "&Edit" #: photofilmstrip/gui/ActionManager.py:62 #: photofilmstrip/gui/ActionManager.py:154 photofilmstrip/gui/DlgRender.py:141 #: photofilmstrip/gui/DlgRendererProps.py:86 msgid "&Help" msgstr "&Help" #: photofilmstrip/gui/ActionManager.py:76 msgid "New Slideshow" msgstr "Nuova Presentazione" #: photofilmstrip/gui/ActionManager.py:81 msgid "Open" msgstr "Apri" #: photofilmstrip/gui/ActionManager.py:87 msgid "Save" msgstr "Salva" #: photofilmstrip/gui/ActionManager.py:97 #: photofilmstrip/gui/ActionManager.py:98 msgid "Show job queue" msgstr "Mostra la coda dei lavori" #: photofilmstrip/gui/ActionManager.py:108 #: photofilmstrip/gui/PnlSlideshow.py:25 msgid "Slideshow" msgstr "Presentazione" #: photofilmstrip/gui/ActionManager.py:110 #: photofilmstrip/gui/PnlTimelapse.py:18 msgid "Timelapse" msgstr "" #: photofilmstrip/gui/ActionManager.py:116 msgid "New" msgstr "Nuovo" #: photofilmstrip/gui/ActionManager.py:118 msgid "&Open" msgstr "&Apri" #: photofilmstrip/gui/ActionManager.py:123 msgid "&Save" msgstr "" #: photofilmstrip/gui/ActionManager.py:136 msgid "&Close" msgstr "&Chiudi" #: photofilmstrip/gui/ActionManager.py:141 msgid "E&xit" msgstr "E&xit" #: photofilmstrip/gui/ActionManager.py:173 msgid "&About" msgstr "&About" #: photofilmstrip/gui/DlgBugReport.py:41 msgid "An unexpected error occured" msgstr "Si è verificato un errore imprevisto" #: photofilmstrip/gui/DlgBugReport.py:44 msgid "" "An unexpected error occured. Do you want to send this bug report to the " "developers of %s?" msgstr "" "Si e' verificato un errore imprevisto. Vuoi inviare un rapporto agli " "sviluppatori di %s?" #: photofilmstrip/gui/DlgBugReport.py:99 msgid "Bug-Report send. Thank you for your support." msgstr "Bug-Report inviato. Grazie per il tuo supporto." #: photofilmstrip/gui/DlgBugReport.py:100 photofilmstrip/gui/FrmMain.py:290 msgid "Information" msgstr "Informazioni" #: photofilmstrip/gui/DlgBugReport.py:106 msgid "Sorry, this function is temporary not available.." msgstr "Spiacenti, questa funzione non è al momento disponibile." #: photofilmstrip/gui/DlgBugReport.py:107 #: photofilmstrip/gui/DlgConfigureAudio.py:232 #: photofilmstrip/gui/DlgConfigureAudio.py:244 #: photofilmstrip/gui/DlgConfigureAudio.py:254 #: photofilmstrip/gui/DlgNewProject.py:156 #: photofilmstrip/gui/DlgNewProject.py:167 #: photofilmstrip/gui/DlgPicDurationByAudio.py:208 #: photofilmstrip/gui/DlgPicDurationByAudio.py:216 #: photofilmstrip/gui/FrmMain.py:376 photofilmstrip/gui/PnlPfsProject.py:468 #: photofilmstrip/gui/PnlTimelapse.py:113 msgid "Error" msgstr "Errore" #: photofilmstrip/gui/DlgConfigureAudio.py:55 msgid "Configure your audio files that are used as a background music." msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:90 msgid "Set the duration of your slideshow to fit your audio files" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:92 #: photofilmstrip/gui/DlgDuration.py:70 photofilmstrip/gui/DlgNewProject.py:84 #: photofilmstrip/gui/DlgPicDurationByAudio.py:50 #: photofilmstrip/gui/DlgPositionInput.py:238 #: photofilmstrip/gui/DlgRender.py:147 #: photofilmstrip/gui/DlgRendererProps.py:92 #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:97 msgid "&Cancel" msgstr "Annulla" #: photofilmstrip/gui/DlgConfigureAudio.py:97 #: photofilmstrip/gui/DlgDuration.py:72 photofilmstrip/gui/DlgNewProject.py:86 #: photofilmstrip/gui/DlgPicDurationByAudio.py:51 #: photofilmstrip/gui/DlgPositionInput.py:244 #: photofilmstrip/gui/DlgRendererProps.py:97 msgid "&Ok" msgstr "&Ok" #: photofilmstrip/gui/DlgConfigureAudio.py:104 #: photofilmstrip/gui/DlgConfigureAudio.py:109 #: photofilmstrip/gui/PnlSlideshow.py:47 photofilmstrip/gui/PnlSlideshow.py:48 #: photofilmstrip/gui/PnlTimelapse.py:33 photofilmstrip/gui/PnlTimelapse.py:34 msgid "Configure music" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:138 msgid "Select music" msgstr "Seleziona la musica" #: photofilmstrip/gui/DlgConfigureAudio.py:140 msgid "Audio files" msgstr "File audio" #: photofilmstrip/gui/DlgConfigureAudio.py:243 #, fuzzy msgid "Audio file not supported!" msgstr "Il file audio non è supportato!" #: photofilmstrip/gui/DlgDuration.py:48 msgid "Total length:" msgstr "Durata totale:" #: photofilmstrip/gui/DlgDuration.py:50 msgid "" "Overrides the duration of single pictures and gives the project this total " "length." msgstr "" "Ignora la durata impostata per i singoli fotogrammi e dai al progetto questa " "durata totale." #: photofilmstrip/gui/DlgDuration.py:54 msgid "User defined:" msgstr "Definito dall'utente:" #: photofilmstrip/gui/DlgDuration.py:65 #, fuzzy msgid "Fit to audio files" msgstr "Come il file audio" #: photofilmstrip/gui/DlgDuration.py:80 #, fuzzy msgid "Slideshow duration" msgstr "Presentazione creata!" #: photofilmstrip/gui/DlgDuration.py:84 msgid "Configure duration of slideshow" msgstr "" #: photofilmstrip/gui/DlgNewProject.py:61 msgid "Project name:" msgstr "Nome del progetto:" #: photofilmstrip/gui/DlgNewProject.py:66 msgid "Folder:" msgstr "Cartella:" #: photofilmstrip/gui/DlgNewProject.py:78 msgid "Aspect ratio:" msgstr "Rapporto altezza/larghezza" #: photofilmstrip/gui/DlgNewProject.py:110 #, fuzzy msgid "Unnamed project" msgstr "impossibile caricare photofilmstrip" #: photofilmstrip/gui/DlgNewProject.py:116 msgid "My PhotoFilmStrips" msgstr "I miei PhotoFilmStrips" #: photofilmstrip/gui/DlgNewProject.py:126 msgid "Browse for folder" msgstr "Sfoglia cartelle" #: photofilmstrip/gui/DlgNewProject.py:145 msgid "Folder does not exists! Do you want %s to create it?" msgstr "Cartella inesistente! Vuoi che %s la crei?" #: photofilmstrip/gui/DlgNewProject.py:146 #: photofilmstrip/gui/PnlEditorPage.py:29 #: photofilmstrip/gui/PnlEditorPage.py:49 #: photofilmstrip/gui/PnlEditorPage.py:88 #: photofilmstrip/gui/WxProjectFile.py:101 #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:224 msgid "Question" msgstr "Domanda" #: photofilmstrip/gui/DlgNewProject.py:155 msgid "Cannot create folder: %s" msgstr "Impossibile creare la cartella: %s" #: photofilmstrip/gui/DlgNewProject.py:166 msgid "Cannot write into folder!" msgstr "Impossibile scrivere nella cartella!" #: photofilmstrip/gui/DlgNewProject.py:180 msgid "The project name must be filled." msgstr "Il nome del progetto deve essere specificato." #: photofilmstrip/gui/DlgNewProject.py:186 msgid "The project name contains invalid characters." msgstr "Il nome del progetto contiene caratteri non validi" #: photofilmstrip/gui/DlgPicDurationByAudio.py:23 #: photofilmstrip/gui/PnlSlideshow.py:54 photofilmstrip/gui/PnlSlideshow.py:55 msgid "Adjust picture durations" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:26 msgid "Adjust picture durations to audio file" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:30 msgid "" "Find your picture duration by playing the audio file of your project and\n" "pressing the hit button to apply the current playing time." msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:43 #: photofilmstrip/gui/DlgPicDurationByAudio.py:153 msgid "Play" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:46 msgid "Hit" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:100 msgid "Stop" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:179 #, fuzzy msgid "Playing time" msgstr "Tempo rimanente" #: photofilmstrip/gui/DlgPicDurationByAudio.py:207 msgid "Your project does not have an audio file configured." msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:215 msgid "" "Your project uses more than one audio file. Currently the durations can be " "adjusted only for one audio file." msgstr "" #: photofilmstrip/gui/DlgPositionInput.py:140 msgid "Motion positions" msgstr "Posizioni di movimento" #: photofilmstrip/gui/DlgPositionInput.py:147 msgid "Start position" msgstr "Posizione iniziale" #: photofilmstrip/gui/DlgPositionInput.py:155 #: photofilmstrip/gui/DlgPositionInput.py:199 msgid "Location:" msgstr "Posizione:" #: photofilmstrip/gui/DlgPositionInput.py:173 #: photofilmstrip/gui/DlgPositionInput.py:215 msgid "Size:" msgstr "Dimensione:" #: photofilmstrip/gui/DlgPositionInput.py:191 msgid "End position" msgstr "Posizione finale" #: photofilmstrip/gui/DlgPositionInput.py:233 msgid "Reset" msgstr "Reset" #: photofilmstrip/gui/DlgPositionInput.py:252 msgid "Adjust motion positions directly" msgstr "Imposta manualmente le posizioni" #: photofilmstrip/gui/DlgRender.py:96 #, fuzzy msgid "Render project" msgstr "Progetti recenti" #: photofilmstrip/gui/DlgRender.py:107 msgid "Format:" msgstr "Formato:" #: photofilmstrip/gui/DlgRender.py:122 msgid "Properties" msgstr "Proprieta'" #: photofilmstrip/gui/DlgRender.py:127 msgid "Profile:" msgstr "Profilo:" #: photofilmstrip/gui/DlgRender.py:136 msgid "Draft" msgstr "Bozza" #: photofilmstrip/gui/DlgRender.py:152 msgid "&Start" msgstr "Inizia" #: photofilmstrip/gui/DlgRender.py:164 msgid "Configure output and start render process" msgstr "Configura l'output e avvia il processo di rendering" #: photofilmstrip/gui/DlgRendererProps.py:50 msgid "Property" msgstr "Proprieta'" #: photofilmstrip/gui/DlgRendererProps.py:52 msgid "Value" msgstr "Valore" #: photofilmstrip/gui/DlgRendererProps.py:71 msgid "Output properties" msgstr "Proprieta' dell'output" #: photofilmstrip/gui/DlgRendererProps.py:113 msgid "Edit extended output properties" msgstr "Modifica proprieta' estese dell'output" #: photofilmstrip/gui/DlgRendererProps.py:147 msgid "Edit property" msgstr "Modifica impostazioni" #: photofilmstrip/gui/FrmMain.py:83 msgid "Welcome" msgstr "Benvenuto" #: photofilmstrip/gui/FrmMain.py:85 msgid "Job queue" msgstr "Coda dei lavori" #: photofilmstrip/gui/FrmMain.py:141 msgid "Rendering in progress..." msgstr "" #: photofilmstrip/gui/FrmMain.py:234 photofilmstrip/gui/PnlWelcome.py:57 #, fuzzy msgid "Create new slideshow" msgstr "Presentazione portabile" #: photofilmstrip/gui/FrmMain.py:241 #, fuzzy msgid "Create new timelapse" msgstr "Crea nuovo progetto" #: photofilmstrip/gui/FrmMain.py:249 msgid "Select %s-Project" msgstr "Seleziona il progetto %s" #: photofilmstrip/gui/FrmMain.py:251 #, fuzzy msgid "Files" msgstr "&File" #: photofilmstrip/gui/FrmMain.py:289 msgid "You must restart %s for your new language setting to take effect." msgstr "" "Devi riavviare %s affinché le nuove impostazioni di lingua abbiano effetto" #: photofilmstrip/gui/FrmMain.py:300 msgid "" "PhotoFilmStrip creates movies out of your pictures in just 3 steps. First " "select your photos, customize the motion path and render the video. There " "are several output possibilities for VCD, SVCD, DVD up to FULL-HD." msgstr "" "PhotoFilmStrip crea filmati partendo da immagini in soli 3 passi. Frimo " "seleziona le tue foto, personalizza il percorso del movimento e effettua il " "render del video. Ci sono svariate alternative per l'output per VCD, SVCD, " "DVD fino a FULL-HD." #: photofilmstrip/gui/FrmMain.py:303 msgid "online" msgstr "online" #: photofilmstrip/gui/FrmMain.py:374 msgid "Invalid %(app)s-Project: %(file)s" msgstr "Progetto di %(app)s non valido: %(file)s" #: photofilmstrip/gui/PnlAddPics.py:50 photofilmstrip/gui/PnlWelcome.py:30 msgid "Welcome to PhotoFilmStrip" msgstr "Benvenuto in PhotoFilmStrip" #: photofilmstrip/gui/PnlAddPics.py:52 msgid "" "Drag some pictures onto this text or\n" "click the button below\n" "to add pictures to your new PhotoFilmStrip." msgstr "" "Trascina qualche immagine qui o\n" "premi il pulsante sotto\n" "per aggiungere immagini al tuo nuovo PhotoFilmStrip." #: photofilmstrip/gui/PnlEditPicture.py:142 msgid "Settings" msgstr "Impostazioni" #: photofilmstrip/gui/PnlEditPicture.py:146 msgid "Rotation:" msgstr "Rotazione:" #: photofilmstrip/gui/PnlEditPicture.py:166 msgid "Effect:" msgstr "Effetto:" #: photofilmstrip/gui/PnlEditPicture.py:180 msgid "Process" msgstr "Processo" #: photofilmstrip/gui/PnlEditPicture.py:184 msgid "Movement:" msgstr "Movimento:" #: photofilmstrip/gui/PnlEditPicture.py:196 #: photofilmstrip/gui/PnlEditPicture.py:212 #: photofilmstrip/gui/PnlEditPicture.py:359 msgid "sec" msgstr "sec" #: photofilmstrip/gui/PnlEditPicture.py:200 msgid "Transition:" msgstr "Transizione:" #: photofilmstrip/gui/PnlEditPicture.py:220 msgid "Subtitle" msgstr "Sottotitolo" #: photofilmstrip/gui/PnlEditPicture.py:240 msgid "Linear" msgstr "Lineare" #: photofilmstrip/gui/PnlEditPicture.py:241 msgid "Accelerated" msgstr "Accelerato" #: photofilmstrip/gui/PnlEditPicture.py:242 msgid "Delayed" msgstr "Ritardato" #: photofilmstrip/gui/PnlEditPicture.py:250 msgid "No effect" msgstr "Nessun effetto" #: photofilmstrip/gui/PnlEditPicture.py:251 msgid "Black and White" msgstr "Bianco e nero" #: photofilmstrip/gui/PnlEditPicture.py:252 msgid "Sepia tone" msgstr "Toni seppia" #: photofilmstrip/gui/PnlEditPicture.py:258 msgid "None" msgstr "Nessuno" #: photofilmstrip/gui/PnlEditPicture.py:259 msgid "Fade" msgstr "Dissolvenza" #: photofilmstrip/gui/PnlEditPicture.py:260 msgid "Roll" msgstr "Roll" #: photofilmstrip/gui/PnlEditPicture.py:354 msgid "fpp" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:355 msgid "frames per picture - the number of frames each picture will be shown" msgstr "" #: photofilmstrip/gui/PnlEditorPage.py:26 msgid "Could not save the file '%(file)s': %(errMsg)s" msgstr "impossibile salvare il file '%(file)s': %(errMsg)s" #: photofilmstrip/gui/PnlEditorPage.py:45 msgid "New file" msgstr "Nuovo file" #: photofilmstrip/gui/PnlEditorPage.py:48 msgid "'%s' has been modified. Save changes?" msgstr "'%s' e' stato modificato. Salvare le modifiche?" #: photofilmstrip/gui/PnlEditorPage.py:74 #, fuzzy msgid "Save %s" msgstr "Salva %s" #: photofilmstrip/gui/PnlEditorPage.py:77 #, fuzzy msgid "File" msgstr "&File" #: photofilmstrip/gui/PnlEditorPage.py:87 msgid "Overwrite existing file '%s'?" msgstr "Sovrascrivere il file esistente '%s'?" #: photofilmstrip/gui/PnlPfsProject.py:118 #: photofilmstrip/gui/PnlPfsProject.py:120 msgid "Set motion start to end" msgstr "Imposta posizione iniziale come finale" #: photofilmstrip/gui/PnlPfsProject.py:122 #: photofilmstrip/gui/PnlPfsProject.py:124 msgid "Set motion end to start" msgstr "Imposta posizione finale come iniziale" #: photofilmstrip/gui/PnlPfsProject.py:126 #: photofilmstrip/gui/PnlPfsProject.py:128 #, fuzzy msgid "Swap motion" msgstr "Inverti movimento" #: photofilmstrip/gui/PnlPfsProject.py:131 #: photofilmstrip/gui/PnlPfsProject.py:133 msgid "Adjust motion manual" msgstr "agguista movimento manualmente" #: photofilmstrip/gui/PnlPfsProject.py:136 #: photofilmstrip/gui/PnlPfsProject.py:138 msgid "Preserve image dimension" msgstr "Mantieni le dimensioni dell'immagine" #: photofilmstrip/gui/PnlPfsProject.py:294 msgid "&Import Pictures" msgstr "&Importa immagini" #: photofilmstrip/gui/PnlPfsProject.py:299 msgid "Move picture &left" msgstr "Sposta immagine a sinistra" #: photofilmstrip/gui/PnlPfsProject.py:303 msgid "Move picture &right" msgstr "Sposta immagine a destra" #: photofilmstrip/gui/PnlPfsProject.py:308 #, fuzzy msgid "R&emove Picture" msgstr "&Rimuovi immagine" #: photofilmstrip/gui/PnlPfsProject.py:313 msgid "Rotate &clockwise" msgstr "Ruota in senso orario" #: photofilmstrip/gui/PnlPfsProject.py:317 msgid "Rotate counter clock&wise" msgstr "Ruota in senso antiorario" #: photofilmstrip/gui/PnlPfsProject.py:322 #, fuzzy msgid "Random &motion" msgstr "Movimento casuale" #: photofilmstrip/gui/PnlPfsProject.py:326 msgid "Centralize m&otion" msgstr "Posiziona al centro" #: photofilmstrip/gui/PnlPfsProject.py:384 msgid "Export slideshow" msgstr "Esporta presentazione" #: photofilmstrip/gui/PnlPfsProject.py:387 #: photofilmstrip/gui/PnlPfsProject.py:400 #, fuzzy msgid "Portable slideshow" msgstr "Presentazione portabile" #: photofilmstrip/gui/PnlPfsProject.py:398 #, fuzzy msgid "Import Slideshow" msgstr "Importa immagini" #: photofilmstrip/gui/PnlPfsProject.py:409 msgid "Import images" msgstr "Importa immagini" #: photofilmstrip/gui/PnlPfsProject.py:411 #, fuzzy msgid "Image files" msgstr "File con immagini" #: photofilmstrip/gui/PnlPfsProject.py:654 msgid "Audio file '%s' does not exist! Continue anyway?" msgstr "Il file audio '%s' non esiste! Continuare comunque?" #: photofilmstrip/gui/PnlPfsProject.py:655 msgid "Warning" msgstr "Attenzione" #: photofilmstrip/gui/PnlSlideshow.py:30 msgid "&Properties" msgstr "&Proprietà" #: photofilmstrip/gui/PnlSlideshow.py:39 photofilmstrip/gui/PnlSlideshow.py:40 #: photofilmstrip/gui/PnlTimelapse.py:25 photofilmstrip/gui/PnlTimelapse.py:26 msgid "Import Pictures" msgstr "Importa immagini" #: photofilmstrip/gui/PnlSlideshow.py:62 photofilmstrip/gui/PnlSlideshow.py:63 #: photofilmstrip/gui/PnlTimelapse.py:41 photofilmstrip/gui/PnlTimelapse.py:42 msgid "Render filmstrip" msgstr "Esegui il render del film" #: photofilmstrip/gui/PnlSlideshow.py:89 photofilmstrip/gui/PnlTimelapse.py:66 msgid "Images" msgstr "Immagini" #: photofilmstrip/gui/PnlSlideshow.py:94 msgid "Duration" msgstr "Durata" #: photofilmstrip/gui/PnlTimelapse.py:69 msgid "Frames" msgstr "" #: photofilmstrip/gui/PnlTimelapse.py:92 msgid "The picture counter is not increasing: %s" msgstr "" #: photofilmstrip/gui/PnlTimelapse.py:110 msgid "" "Filename '%s' does not match a number pattern which is necessary for a time " "lapse slide show!" msgstr "" #: photofilmstrip/gui/PnlWelcome.py:37 photofilmstrip/gui/PnlWelcome.py:103 msgid "Recent projects" msgstr "Progetti recenti" #: photofilmstrip/gui/PnlWelcome.py:62 msgid "Open existing project" msgstr "Apri progetto esistente" #: photofilmstrip/gui/PnlWelcome.py:106 msgid "How to start..." msgstr "Come iniziare..." #: photofilmstrip/gui/PnlWelcome.py:107 msgid "Create a new project or load an existing one." msgstr "Creare un nuovo progetto o caricarne uno esistente." #: photofilmstrip/gui/PnlWelcome.py:138 msgid "Update available" msgstr "Aggiornamento disponibile" #: photofilmstrip/gui/PnlWelcome.py:141 msgid "The following changes has been made:" msgstr "Sono stati apportati i seguenti cambiamenti:" #: photofilmstrip/gui/WxProjectFile.py:59 #, fuzzy msgid "Loading project %s" msgstr "Sto caricando il progetto %s" #: photofilmstrip/gui/WxProjectFile.py:75 #, fuzzy msgid "Saving project %s" msgstr "Salvataggio in corso del progetto %s" #: photofilmstrip/gui/WxProjectFile.py:100 msgid "" "Some images does not exist in the folder '%s' anymore. If the files has " "moved you can select the new path. Do you want to select a new path?" msgstr "" "Alcune immagini non esistono piu' nella cartella '%s'. Se i file sono stati " "spostati, puoi indicare il nuovo percorso. Vuoi indicare il nuovo percorso?" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:73 msgid "Elapsed time" msgstr "Tempo trascorso" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:85 msgid "Remaining time" msgstr "Tempo rimanente" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:203 msgid "Unknown" msgstr "Sconosciuto" #: photofilmstrip/lib/jobimpl/PnlJobManager.py:50 msgid "&Clear list" msgstr "Cancella elenco" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:127 msgid "Abort" msgstr "Annulla" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:133 msgid "Remove from list" msgstr "Rimuovi dall'elenco" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:223 #, fuzzy msgid "Abort selected process?" msgstr "Interrompere il processo selezionato?" #: photofilmstrip/lib/jobimpl/VisualJob.py:29 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:25 #, fuzzy msgid "Waiting..." msgstr "In attesa..." #: photofilmstrip/lib/jobimpl/VisualJob.py:68 #: photofilmstrip/lib/jobimpl/VisualJob.py:85 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:60 #, fuzzy msgid "Aborted" msgstr "Annullato" #: photofilmstrip/lib/jobimpl/VisualJob.py:70 msgid "Done" msgstr "Fatto" #: photofilmstrip/lib/jobimpl/VisualJob.py:79 #, fuzzy msgid "Aborting..." msgstr "annullamento in corso..." #: photofilmstrip/uwp/UwpService.py:76 msgid "Slideshow created!" msgstr "Presentazione creata!" #, fuzzy #~ msgid "Audio files:" #~ msgstr "File audio" #~ msgid "Project properties" #~ msgstr "Impostazioni del progetto" #~ msgid "PhotoFilmStrip project" #~ msgstr "progetto di PhotofilmStrip" #~ msgid "Unnamed PhotoFilmStrip" #~ msgstr "progetto PhotoFilmStrip senza nome" #~ msgid "Project" #~ msgstr "Progetto" #~ msgid "Error: %s" #~ msgstr "Errore: %s" #~ msgid "Please wait..." #~ msgstr "Attendere prego..." #~ msgid "initialize renderer" #~ msgstr "inizializzazione del renderer" #~ msgid "creating output..." #~ msgstr "creazione output in corso..." #~ msgid "mencoder (mencoder) required!" #~ msgstr "mencoder (mencoder) richiesto!" #~ msgid "MPEG(1/2)-Video (MPG)" #~ msgstr "MPEG(1/2)-Video (MPG)" #~ msgid "MPEG4-XVid/AC3 (AVI)" #~ msgstr "MPEG4-XVid/AC3 (AVI)" #, fuzzy #~ msgid "mencoder with MP3 support (mp3lame) required!" #~ msgstr "mencoder con supporto MP3 (mp3lame) richiesto!" #~ msgid "MPEG4-XVid/MP3 (AVI)" #~ msgstr "MPEG4-XVid/MP3 (AVI)" #~ msgid "Flash-Video (FLV)" #~ msgstr "video in Flash(FLV)" #~ msgid "Motion-JPEG (AVI)" #~ msgstr "Motion-JPEG (AVI)" #~ msgid "&Tools" #~ msgstr "Strumenti" #~ msgid "New Project" #~ msgstr "Nuovo progetto" #~ msgid "&New Project" #~ msgstr "&Nuovo progetto" #~ msgid "&Open Project" #~ msgstr "Apri progetto" #~ msgid "&Save Project" #~ msgstr "&Salva progetto" #~ msgid "&Close Project" #~ msgstr "&Chiudi progetto" #~ msgid "Finalizing" #~ msgstr "Finalizzazione in corso..." #~ msgid "Choose your next action:" #~ msgstr "Scegli la tua prossima azione:" #~ msgid "Delete unfinished result" #~ msgstr "Rimuovi risultati non completati" #~ msgid "Show error again and send to developer." #~ msgstr "Mostra l'errore di nuovo e invialo allo sviluppatore" #~ msgid "The rendering process was aborted." #~ msgstr "Il processo di rendering e' stato annullato" #~ msgid "The rendering process was interrupted." #~ msgstr "Il processo di rendering e' stato interrotto" #~ msgid "The rendering process has been finished." #~ msgstr "Il processo di rendering e' terminato" #~ msgid "Audio file:" #~ msgstr "File audio:" #~ msgid "Type:" #~ msgstr "Tipo:" #~ msgid "&Batch Job" #~ msgstr "Lavoro &Batch" #~ msgid "" #~ "Project not saved yet. Please save the project first to create a batch " #~ "job!" #~ msgstr "" #~ "Progetto non ancora salvato. Salva il progetto prima di creare il lavoro " #~ "batch!" #~ msgid "Batch file" #~ msgstr "File batch" #~ msgid "Shell script" #~ msgstr "Script di shell" #~ msgid "Select batch file" #~ msgstr "Seleziona il file batch" #~ msgid "Export %s-Project" #~ msgstr "Esporta progetto %s" #~ msgid "Import %s-Project" #~ msgstr "Importa progetto %s" #~ msgid "Duration:" #~ msgstr "Durata:" #~ msgid "Browse" #~ msgstr "Sfoglia" #~ msgid "Import image" #~ msgstr "Importa immagine" #~ msgid "Please wait" #~ msgstr "Attendere prego" #~ msgid "Loading pictures..." #~ msgstr "Caricamento immagini..." #~ msgid "Invalid audio file!" #~ msgstr "File audio non valido!" #~ msgid "processing audiofile..." #~ msgstr "elaborazione file audio in corso..." photofilmstrip-3.7.2/po/es.po0000644000232200023220000006703013560357351016557 0ustar debalancedebalance# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR ORGANIZATION # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PhotoFilmStrip\n" "POT-Creation-Date: 2018-11-07 22:03+CET\n" "PO-Revision-Date: 2019-09-26 19:07-0300\n" "Last-Translator: Iván A. Werbach\n" "Language-Team: Iván A. Werbach\n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: pygettext.py 1.5\n" "X-Poedit-SourceCharset: UTF-8\n" "X-Generator: Poedit 2.0.6\n" #: photofilmstrip/action/ActionAutoPath.py:23 #: photofilmstrip/gui/PnlPfsProject.py:115 msgid "Random motion" msgstr "Zoom aleatorio" #: photofilmstrip/action/ActionCenterPath.py:21 msgid "Centralize motion" msgstr "Zoom al centro" #: photofilmstrip/action/ActionI18N.py:24 #: photofilmstrip/gui/ActionManager.py:170 msgid "Language" msgstr "Idioma" #: photofilmstrip/action/ActionOpenFolder.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:28 msgid "Open folder" msgstr "Abrir carpeta" #: photofilmstrip/action/ActionPlayVideo.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:22 msgid "Play video" msgstr "Reproducir video" #: photofilmstrip/action/ActionRender.py:37 msgid "Start" msgstr "Inicio" #: photofilmstrip/cli/Main.py:46 photofilmstrip/cli/Main.py:196 msgid "all done" msgstr "hecho" #: photofilmstrip/cli/Main.py:64 msgid "processing project" msgstr "procesando proyecto" #: photofilmstrip/cli/Main.py:65 msgid "using renderer" msgstr "usar motor de renderizado" #: photofilmstrip/cli/Main.py:66 msgid "output format" msgstr "formato de salida" #: photofilmstrip/cli/Main.py:69 msgid "framerate" msgstr "vel. de fotogramas" #: photofilmstrip/cli/Main.py:103 msgid "specifies the project file" msgstr "especificar el archivo de proyecto" #: photofilmstrip/cli/Main.py:104 msgid "The path where to save the output files. Use - for stdout." msgstr "" "El directorio donde guardar los archivos de salida. Use - para stdout." #: photofilmstrip/cli/Main.py:106 photofilmstrip/cli/Main.py:129 msgid "Option videonorm is deprecated, use an appropriate profile!" msgstr "La opción videonorm está en desuso, usar un perfil apropiado!" #: photofilmstrip/cli/Main.py:108 msgid "enable draft mode" msgstr "activar modo borrador" #: photofilmstrip/cli/Main.py:108 photofilmstrip/gui/DlgRender.py:167 msgid "" "Activate this option to generate a preview of your PhotoFilmStrip. The " "rendering process will speed up dramatically, but results in lower quality." msgstr "" "Active esta opción para generar una vista previa de su PhotoFilmStrip. El " "proceso de renderizado se acelerará, pero resultará de menor calidad." #: photofilmstrip/cli/Main.py:120 msgid "project file does not exist: %s" msgstr "el archivo %s del proyecto no existe" #: photofilmstrip/cli/Main.py:124 msgid "no project file specified!" msgstr "¡No se especificó un archivo del proyecto!" #: photofilmstrip/cli/Main.py:134 msgid "invalid format specified: %s" msgstr "formato inválido: %s" #: photofilmstrip/cli/Main.py:140 msgid "invalid profile specified: %s" msgstr "perfil inválido: %s" #: photofilmstrip/cli/Main.py:146 msgid "cannot load project" msgstr "no se puede abrir el proyecto" #: photofilmstrip/cli/Main.py:159 msgid "cannot create output path: %s" msgstr "no se puede crear el directorio de salida: %s" #: photofilmstrip/cli/Main.py:169 photofilmstrip/gui/DlgConfigureAudio.py:231 #: photofilmstrip/gui/DlgConfigureAudio.py:253 msgid "Audio file '%s' does not exist!" msgstr "¡El archivo %s de audio no existe!" #: photofilmstrip/cli/Main.py:190 msgid "...aborted!" msgstr "...¡abortado!" #: photofilmstrip/core/BaseRenderer.py:50 msgid "Unknown property: %s" msgstr "Propiedad desconocida: %s" #: photofilmstrip/core/BaseRenderer.py:58 msgid "" msgstr "" #: photofilmstrip/core/BaseRenderer.py:73 msgid "no" msgstr "no" #: photofilmstrip/core/ProjectFile.py:222 msgid "Saving '%s' ..." msgstr "Guardando '%s' ..." #: photofilmstrip/core/ProjectFile.py:276 msgid "Loading '%s' ..." msgstr "Cargando '%s' ..." #: photofilmstrip/core/RenderEngine.py:113 #: photofilmstrip/core/RenderEngine.py:201 msgid "processing transition %d/%d" msgstr "procesando transición %d/%d" #: photofilmstrip/core/RenderEngine.py:124 #: photofilmstrip/core/RenderEngine.py:210 msgid "processing image %d/%d" msgstr "procesando imagen %d/%d" #: photofilmstrip/core/renderer/CairoRenderer.py:35 msgid "Preview" msgstr "Vista previa" #: photofilmstrip/core/renderer/GStreamerRenderer.py:50 msgid "GStreamer (python-gst-1.0) required!" msgstr "¡GStreamer (python-gst-1.0) requerido!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:287 msgid "Bitrate must be a number!" msgstr "¡La tasa de bits debe ser un número!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:455 #: photofilmstrip/core/renderer/GStreamerRenderer.py:531 #: photofilmstrip/core/renderer/GStreamerRenderer.py:601 #: photofilmstrip/core/renderer/GStreamerRenderer.py:690 #: photofilmstrip/core/renderer/GStreamerRenderer.py:730 #: photofilmstrip/core/renderer/GStreamerRenderer.py:779 msgid "libav (gstreamer1.0-libav) required!" msgstr "¡libav (gstreamer1.0-libav) requerido!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:459 #: photofilmstrip/core/renderer/GStreamerRenderer.py:535 #: photofilmstrip/core/renderer/GStreamerRenderer.py:605 msgid "x264-Codec (gstreamer1.0-plugins-ugly) required!" msgstr "¡x264-Codec (gstreamer1.0-plugins-ugly) requerido!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:463 #: photofilmstrip/core/renderer/GStreamerRenderer.py:609 msgid "MKV-Muxer (gstreamer1.0-plugins-good) required!" msgstr "¡MKV-Muxer (gstreamer1.0-plugins-good) requerido!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:539 msgid "MP4-Muxer (gstreamer1.0-plugins-good) required!" msgstr "¡MP4-Muxer (gstreamer1.0-plugins-good) requerido!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:647 msgid "Theora-Codec (gstreamer1.0-plugins-base) required!" msgstr "¡Theora-Codec (gstreamer1.0-plugins-base) requerido!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:651 msgid "Vorbis-Codec (gstreamer1.0-plugins-base) required!" msgstr "¡Vorbis-Codec (gstreamer1.0-plugins-base) requerido!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:655 msgid "OGV-Muxer (gstreamer1.0-plugins-base) required!" msgstr "¡OGV-Muxer (gstreamer1.0-plugins-base) requerido!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:686 #: photofilmstrip/core/renderer/GStreamerRenderer.py:726 #: photofilmstrip/core/renderer/GStreamerRenderer.py:775 msgid "MPEG-1/2-Codec (gstreamer1.0-plugins-bad) required!" msgstr "¡MPEG-1/2-Codec (gstreamer1.0-plugins-bad) requerido!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:694 #: photofilmstrip/core/renderer/GStreamerRenderer.py:734 #: photofilmstrip/core/renderer/GStreamerRenderer.py:783 msgid "MPEG-Muxer (gstreamer1.0-plugins-bad) required!" msgstr "¡MPEG-Muxer (gstreamer1.0-plugins-bad) requerido!" #: photofilmstrip/core/renderer/SingleFileRenderer.py:21 msgid "Single pictures" msgstr "Imágenes individuales" #: photofilmstrip/core/tasks.py:48 msgid "generating subtitle" msgstr "generando subtítulos" #: photofilmstrip/gui/ActionManager.py:60 #: photofilmstrip/gui/ActionManager.py:190 msgid "&File" msgstr "&Archivo" #: photofilmstrip/gui/ActionManager.py:61 #: photofilmstrip/gui/ActionManager.py:191 msgid "&Edit" msgstr "&Editar" #: photofilmstrip/gui/ActionManager.py:62 #: photofilmstrip/gui/ActionManager.py:154 photofilmstrip/gui/DlgRender.py:141 #: photofilmstrip/gui/DlgRendererProps.py:86 msgid "&Help" msgstr "A&yuda" #: photofilmstrip/gui/ActionManager.py:76 msgid "New Slideshow" msgstr "Nueva presentación" #: photofilmstrip/gui/ActionManager.py:81 msgid "Open" msgstr "Abrir" #: photofilmstrip/gui/ActionManager.py:87 msgid "Save" msgstr "Guardar" #: photofilmstrip/gui/ActionManager.py:97 #: photofilmstrip/gui/ActionManager.py:98 msgid "Show job queue" msgstr "Mostrar cola de trabajos" #: photofilmstrip/gui/ActionManager.py:108 #: photofilmstrip/gui/PnlSlideshow.py:25 msgid "Slideshow" msgstr "Presentación" #: photofilmstrip/gui/ActionManager.py:110 #: photofilmstrip/gui/PnlTimelapse.py:18 msgid "Timelapse" msgstr "Línea de tiempo" #: photofilmstrip/gui/ActionManager.py:116 msgid "New" msgstr "Nuevo" #: photofilmstrip/gui/ActionManager.py:118 msgid "&Open" msgstr "A&brir" #: photofilmstrip/gui/ActionManager.py:123 msgid "&Save" msgstr "&Guardar" #: photofilmstrip/gui/ActionManager.py:136 msgid "&Close" msgstr "Ce&rrar" #: photofilmstrip/gui/ActionManager.py:141 msgid "E&xit" msgstr "&Salir" #: photofilmstrip/gui/ActionManager.py:173 msgid "&About" msgstr "&Sobre" #: photofilmstrip/gui/DlgBugReport.py:41 msgid "An unexpected error occured" msgstr "Un error ha ocurrido" #: photofilmstrip/gui/DlgBugReport.py:44 msgid "" "An unexpected error occured. Do you want to send this bug report to the " "developers of %s?" msgstr "" "Un error ha ocurrido. ¿Quiere enviar el reporte a los desarrolladores de %s?" #: photofilmstrip/gui/DlgBugReport.py:99 msgid "Bug-Report send. Thank you for your support." msgstr "Reporte enviado. Gracias por el soporte." #: photofilmstrip/gui/DlgBugReport.py:100 photofilmstrip/gui/FrmMain.py:290 msgid "Information" msgstr "Información" #: photofilmstrip/gui/DlgBugReport.py:106 msgid "Sorry, this function is temporary not available.." msgstr "Lo lamentamos, esta función no está disponible temporalmente." #: photofilmstrip/gui/DlgBugReport.py:107 #: photofilmstrip/gui/DlgConfigureAudio.py:232 #: photofilmstrip/gui/DlgConfigureAudio.py:244 #: photofilmstrip/gui/DlgConfigureAudio.py:254 #: photofilmstrip/gui/DlgNewProject.py:156 #: photofilmstrip/gui/DlgNewProject.py:167 #: photofilmstrip/gui/DlgPicDurationByAudio.py:208 #: photofilmstrip/gui/DlgPicDurationByAudio.py:216 #: photofilmstrip/gui/FrmMain.py:376 photofilmstrip/gui/PnlPfsProject.py:468 #: photofilmstrip/gui/PnlTimelapse.py:113 msgid "Error" msgstr "Error" #: photofilmstrip/gui/DlgConfigureAudio.py:55 msgid "Configure your audio files that are used as a background music." msgstr "Configure los archivos de audio que se utilizan como música de fondo." #: photofilmstrip/gui/DlgConfigureAudio.py:90 msgid "Set the duration of your slideshow to fit your audio files" msgstr "" "Ajustar la duración de la presentación para que se ajuste al archivo de " "audio" #: photofilmstrip/gui/DlgConfigureAudio.py:92 #: photofilmstrip/gui/DlgDuration.py:70 photofilmstrip/gui/DlgNewProject.py:84 #: photofilmstrip/gui/DlgPicDurationByAudio.py:50 #: photofilmstrip/gui/DlgPositionInput.py:238 #: photofilmstrip/gui/DlgRender.py:147 #: photofilmstrip/gui/DlgRendererProps.py:92 #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:97 msgid "&Cancel" msgstr "&Cancelar" #: photofilmstrip/gui/DlgConfigureAudio.py:97 #: photofilmstrip/gui/DlgDuration.py:72 photofilmstrip/gui/DlgNewProject.py:86 #: photofilmstrip/gui/DlgPicDurationByAudio.py:51 #: photofilmstrip/gui/DlgPositionInput.py:244 #: photofilmstrip/gui/DlgRendererProps.py:97 msgid "&Ok" msgstr "&Listo" #: photofilmstrip/gui/DlgConfigureAudio.py:104 #: photofilmstrip/gui/DlgConfigureAudio.py:109 #: photofilmstrip/gui/PnlSlideshow.py:47 photofilmstrip/gui/PnlSlideshow.py:48 #: photofilmstrip/gui/PnlTimelapse.py:33 photofilmstrip/gui/PnlTimelapse.py:34 msgid "Configure music" msgstr "Configurar música" #: photofilmstrip/gui/DlgConfigureAudio.py:138 msgid "Select music" msgstr "Seleccionar música" #: photofilmstrip/gui/DlgConfigureAudio.py:140 msgid "Audio files" msgstr "Archivos de audio" #: photofilmstrip/gui/DlgConfigureAudio.py:243 msgid "Audio file not supported!" msgstr "¡Archivo de audio no soportado!" #: photofilmstrip/gui/DlgDuration.py:48 msgid "Total length:" msgstr "Duración total:" #: photofilmstrip/gui/DlgDuration.py:50 msgid "" "Overrides the duration of single pictures and gives the project this total " "length." msgstr "" "Reemplazar la duración de las imágenes para darle al proyecto el tamaño " "total." #: photofilmstrip/gui/DlgDuration.py:54 msgid "User defined:" msgstr "Definido por el usuario:" #: photofilmstrip/gui/DlgDuration.py:65 msgid "Fit to audio files" msgstr "Ajustar al archivo de audio" #: photofilmstrip/gui/DlgDuration.py:80 msgid "Slideshow duration" msgstr "Duración de la presentación" #: photofilmstrip/gui/DlgDuration.py:84 msgid "Configure duration of slideshow" msgstr "Configurar la duración de la presentación" #: photofilmstrip/gui/DlgNewProject.py:61 msgid "Project name:" msgstr "Nombre del proyecto:" #: photofilmstrip/gui/DlgNewProject.py:66 msgid "Folder:" msgstr "Carpeta:" #: photofilmstrip/gui/DlgNewProject.py:78 msgid "Aspect ratio:" msgstr "Relación de aspecto:" #: photofilmstrip/gui/DlgNewProject.py:110 msgid "Unnamed project" msgstr "Proyecto sin nombre" #: photofilmstrip/gui/DlgNewProject.py:116 msgid "My PhotoFilmStrips" msgstr "Mis presentaciones PhotoFilmStrip" #: photofilmstrip/gui/DlgNewProject.py:126 msgid "Browse for folder" msgstr "Buscar por carpeta" #: photofilmstrip/gui/DlgNewProject.py:145 msgid "Folder does not exists! Do you want %s to create it?" msgstr "¡La carpeta no existe! ¿Quiere que %s la cree?" #: photofilmstrip/gui/DlgNewProject.py:146 #: photofilmstrip/gui/PnlEditorPage.py:29 #: photofilmstrip/gui/PnlEditorPage.py:49 #: photofilmstrip/gui/PnlEditorPage.py:88 #: photofilmstrip/gui/WxProjectFile.py:101 #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:224 msgid "Question" msgstr "Pregunta" #: photofilmstrip/gui/DlgNewProject.py:155 msgid "Cannot create folder: %s" msgstr "No se puede crear la carpeta: %s" #: photofilmstrip/gui/DlgNewProject.py:166 msgid "Cannot write into folder!" msgstr "¡No se puede escribir en la carpeta!" #: photofilmstrip/gui/DlgNewProject.py:180 msgid "The project name must be filled." msgstr "El nombre del proyecto debe estar definido." #: photofilmstrip/gui/DlgNewProject.py:186 msgid "The project name contains invalid characters." msgstr "El nombre del proyecto contiene caracteres inválidos." #: photofilmstrip/gui/DlgPicDurationByAudio.py:23 #: photofilmstrip/gui/PnlSlideshow.py:54 photofilmstrip/gui/PnlSlideshow.py:55 msgid "Adjust picture durations" msgstr "Ajustar duración de la imagen" #: photofilmstrip/gui/DlgPicDurationByAudio.py:26 msgid "Adjust picture durations to audio file" msgstr "Ajustar duración de las imágenes al archivo de audio" #: photofilmstrip/gui/DlgPicDurationByAudio.py:30 msgid "" "Find your picture duration by playing the audio file of your project and\n" "pressing the hit button to apply the current playing time." msgstr "" "Encuentre la duración de la imagen reproduciendo el archivo de audio del " "proyecto\n" "y luego presionando el botón para ajustarla a ese momento." #: photofilmstrip/gui/DlgPicDurationByAudio.py:43 #: photofilmstrip/gui/DlgPicDurationByAudio.py:153 msgid "Play" msgstr "Reproducir" #: photofilmstrip/gui/DlgPicDurationByAudio.py:46 msgid "Hit" msgstr "Punto" #: photofilmstrip/gui/DlgPicDurationByAudio.py:100 msgid "Stop" msgstr "Detener" #: photofilmstrip/gui/DlgPicDurationByAudio.py:179 msgid "Playing time" msgstr "Tiempo de rep." #: photofilmstrip/gui/DlgPicDurationByAudio.py:207 msgid "Your project does not have an audio file configured." msgstr "Su proyecto no tiene un archivo de audio configurado." #: photofilmstrip/gui/DlgPicDurationByAudio.py:215 msgid "" "Your project uses more than one audio file. Currently the durations can be " "adjusted only for one audio file." msgstr "" "Su proyecto usa más de un archivo de audio. Por el momento, las duraciones " "pueden ajustarse sólo para un solo archivo." #: photofilmstrip/gui/DlgPositionInput.py:140 msgid "Motion positions" msgstr "Posición del movimiento" #: photofilmstrip/gui/DlgPositionInput.py:147 msgid "Start position" msgstr "Posición de inicio" #: photofilmstrip/gui/DlgPositionInput.py:155 #: photofilmstrip/gui/DlgPositionInput.py:199 msgid "Location:" msgstr "Ubicación:" #: photofilmstrip/gui/DlgPositionInput.py:173 #: photofilmstrip/gui/DlgPositionInput.py:215 msgid "Size:" msgstr "Tamaño:" #: photofilmstrip/gui/DlgPositionInput.py:191 msgid "End position" msgstr "Posición final" #: photofilmstrip/gui/DlgPositionInput.py:233 msgid "Reset" msgstr "Restablecer" #: photofilmstrip/gui/DlgPositionInput.py:252 msgid "Adjust motion positions directly" msgstr "Ajustar posiciones de movimiento directamente" #: photofilmstrip/gui/DlgRender.py:96 msgid "Render project" msgstr "Procesar proyecto" #: photofilmstrip/gui/DlgRender.py:107 msgid "Format:" msgstr "Formato:" #: photofilmstrip/gui/DlgRender.py:122 msgid "Properties" msgstr "Propiedades" #: photofilmstrip/gui/DlgRender.py:127 msgid "Profile:" msgstr "Perfil:" #: photofilmstrip/gui/DlgRender.py:136 msgid "Draft" msgstr "Borrador" #: photofilmstrip/gui/DlgRender.py:152 msgid "&Start" msgstr "&Inicio" #: photofilmstrip/gui/DlgRender.py:164 msgid "Configure output and start render process" msgstr "Configurar la salida y comenzar el procesado" #: photofilmstrip/gui/DlgRendererProps.py:50 msgid "Property" msgstr "Propiedad" #: photofilmstrip/gui/DlgRendererProps.py:52 msgid "Value" msgstr "Valor" #: photofilmstrip/gui/DlgRendererProps.py:71 msgid "Output properties" msgstr "Propiedades de salida" #: photofilmstrip/gui/DlgRendererProps.py:113 msgid "Edit extended output properties" msgstr "Editar propiedades extendidas de la salida" #: photofilmstrip/gui/DlgRendererProps.py:147 msgid "Edit property" msgstr "Editar propiedad" #: photofilmstrip/gui/FrmMain.py:83 msgid "Welcome" msgstr "Bienvenido/a" #: photofilmstrip/gui/FrmMain.py:85 msgid "Job queue" msgstr "Cola de trabajo" #: photofilmstrip/gui/FrmMain.py:141 msgid "Rendering in progress..." msgstr "Proceso en progreso..." #: photofilmstrip/gui/FrmMain.py:234 photofilmstrip/gui/PnlWelcome.py:57 msgid "Create new slideshow" msgstr "Crear nueva presentación" #: photofilmstrip/gui/FrmMain.py:241 msgid "Create new timelapse" msgstr "Crear nueva secuencia" #: photofilmstrip/gui/FrmMain.py:249 msgid "Select %s-Project" msgstr "Seleccionar %s-Proyecto" #: photofilmstrip/gui/FrmMain.py:251 msgid "Files" msgstr "Archivos" #: photofilmstrip/gui/FrmMain.py:289 msgid "You must restart %s for your new language setting to take effect." msgstr "Debe reiniciar %s para que se apliquen los cambios." #: photofilmstrip/gui/FrmMain.py:300 msgid "" "PhotoFilmStrip creates movies out of your pictures in just 3 steps. First " "select your photos, customize the motion path and render the video. There " "are several output possibilities for VCD, SVCD, DVD up to FULL-HD." msgstr "" "PhotoFilmStrip crea películas a partir de sus imágenes en sólo 3 pasos. " "Primero seleccione sus fotos, ajuste los movimientos y genere el video. Hay " "varios tipos de salidas como VCD, SVCD y DVD hasta en FULL-HD." #: photofilmstrip/gui/FrmMain.py:303 msgid "online" msgstr "en línea" #: photofilmstrip/gui/FrmMain.py:374 #, fuzzy msgid "Invalid %(app)s-Project: %(file)s" msgstr "%(app)s-Project inválido: %(file)s" #: photofilmstrip/gui/PnlAddPics.py:50 photofilmstrip/gui/PnlWelcome.py:30 msgid "Welcome to PhotoFilmStrip" msgstr "Bienvenido/a a PhotoFilmStrip" #: photofilmstrip/gui/PnlAddPics.py:52 msgid "" "Drag some pictures onto this text or\n" "click the button below\n" "to add pictures to your new PhotoFilmStrip." msgstr "" "Arrastre algunas imágenes hacia este texto\n" "o haga clic en el botón de abajo\n" "para agregar imágenes a su presentación." #: photofilmstrip/gui/PnlEditPicture.py:142 msgid "Settings" msgstr "Ajustes" #: photofilmstrip/gui/PnlEditPicture.py:146 msgid "Rotation:" msgstr "Rotación:" #: photofilmstrip/gui/PnlEditPicture.py:166 msgid "Effect:" msgstr "Efecto:" #: photofilmstrip/gui/PnlEditPicture.py:180 msgid "Process" msgstr "Proceso" #: photofilmstrip/gui/PnlEditPicture.py:184 msgid "Movement:" msgstr "Movimiento:" #: photofilmstrip/gui/PnlEditPicture.py:196 #: photofilmstrip/gui/PnlEditPicture.py:212 #: photofilmstrip/gui/PnlEditPicture.py:359 msgid "sec" msgstr "seg" #: photofilmstrip/gui/PnlEditPicture.py:200 msgid "Transition:" msgstr "Transición:" #: photofilmstrip/gui/PnlEditPicture.py:220 msgid "Subtitle" msgstr "Subtítulo" #: photofilmstrip/gui/PnlEditPicture.py:240 msgid "Linear" msgstr "Lineal" #: photofilmstrip/gui/PnlEditPicture.py:241 msgid "Accelerated" msgstr "Acelerada" #: photofilmstrip/gui/PnlEditPicture.py:242 msgid "Delayed" msgstr "Retrasada" #: photofilmstrip/gui/PnlEditPicture.py:250 msgid "No effect" msgstr "Sin efectos" #: photofilmstrip/gui/PnlEditPicture.py:251 msgid "Black and White" msgstr "Blanco y negro" #: photofilmstrip/gui/PnlEditPicture.py:252 msgid "Sepia tone" msgstr "Tono sepia" #: photofilmstrip/gui/PnlEditPicture.py:258 msgid "None" msgstr "Ninguno" #: photofilmstrip/gui/PnlEditPicture.py:259 msgid "Fade" msgstr "Difuminado" #: photofilmstrip/gui/PnlEditPicture.py:260 msgid "Roll" msgstr "Empujar" #: photofilmstrip/gui/PnlEditPicture.py:354 msgid "fpp" msgstr "cps" #: photofilmstrip/gui/PnlEditPicture.py:355 msgid "frames per picture - the number of frames each picture will be shown" msgstr "" "cuadros por segundo - el número de cuadros que se mostrará de cada imagen" #: photofilmstrip/gui/PnlEditorPage.py:26 #, fuzzy msgid "Could not save the file '%(file)s': %(errMsg)s" msgstr "No se puede guardar el archivo '%(file)s': %(errMsg)s" #: photofilmstrip/gui/PnlEditorPage.py:45 msgid "New file" msgstr "Archivo nuevo" #: photofilmstrip/gui/PnlEditorPage.py:48 msgid "'%s' has been modified. Save changes?" msgstr "'%s' fue modificado. ¿Guardar cambios?" #: photofilmstrip/gui/PnlEditorPage.py:74 msgid "Save %s" msgstr "Guardando %s" #: photofilmstrip/gui/PnlEditorPage.py:77 msgid "File" msgstr "Archivo" #: photofilmstrip/gui/PnlEditorPage.py:87 msgid "Overwrite existing file '%s'?" msgstr "¿Reemplazar archivo existente '%s'?" #: photofilmstrip/gui/PnlPfsProject.py:118 #: photofilmstrip/gui/PnlPfsProject.py:120 msgid "Set motion start to end" msgstr "Establecer posición final igual a la de inicio" #: photofilmstrip/gui/PnlPfsProject.py:122 #: photofilmstrip/gui/PnlPfsProject.py:124 msgid "Set motion end to start" msgstr "Establecer posición de inicio igual a la del final" #: photofilmstrip/gui/PnlPfsProject.py:126 #: photofilmstrip/gui/PnlPfsProject.py:128 msgid "Swap motion" msgstr "Intercambiar posiciones" #: photofilmstrip/gui/PnlPfsProject.py:131 #: photofilmstrip/gui/PnlPfsProject.py:133 msgid "Adjust motion manual" msgstr "Ajuste manual del movimiento" #: photofilmstrip/gui/PnlPfsProject.py:136 #: photofilmstrip/gui/PnlPfsProject.py:138 msgid "Preserve image dimension" msgstr "Preservar dimensiones de la imagen" #: photofilmstrip/gui/PnlPfsProject.py:294 msgid "&Import Pictures" msgstr "I&mportar imágenes" #: photofilmstrip/gui/PnlPfsProject.py:299 msgid "Move picture &left" msgstr "Mover imagen a la &derecha" #: photofilmstrip/gui/PnlPfsProject.py:303 msgid "Move picture &right" msgstr "Mover imagen a la i&zquierda" #: photofilmstrip/gui/PnlPfsProject.py:308 msgid "R&emove Picture" msgstr "E&liminar imagen" #: photofilmstrip/gui/PnlPfsProject.py:313 msgid "Rotate &clockwise" msgstr "Rotar en sentido h&orario" #: photofilmstrip/gui/PnlPfsProject.py:317 msgid "Rotate counter clock&wise" msgstr "Rotar en sentido a&ntihorario" #: photofilmstrip/gui/PnlPfsProject.py:322 msgid "Random &motion" msgstr "Movimiento a&leatorio" #: photofilmstrip/gui/PnlPfsProject.py:326 msgid "Centralize m&otion" msgstr "Mov. al cen&tro" #: photofilmstrip/gui/PnlPfsProject.py:384 msgid "Export slideshow" msgstr "Exportar presentación" #: photofilmstrip/gui/PnlPfsProject.py:387 #: photofilmstrip/gui/PnlPfsProject.py:400 msgid "Portable slideshow" msgstr "Presentación portable" #: photofilmstrip/gui/PnlPfsProject.py:398 msgid "Import Slideshow" msgstr "Importar presentación" #: photofilmstrip/gui/PnlPfsProject.py:409 msgid "Import images" msgstr "Importar imágenes" #: photofilmstrip/gui/PnlPfsProject.py:411 msgid "Image files" msgstr "Archivos de imagen" #: photofilmstrip/gui/PnlPfsProject.py:654 msgid "Audio file '%s' does not exist! Continue anyway?" msgstr "¡El archivo de audio '%s' no existe! ¿Continuar?" #: photofilmstrip/gui/PnlPfsProject.py:655 msgid "Warning" msgstr "Advertencia" #: photofilmstrip/gui/PnlSlideshow.py:30 msgid "&Properties" msgstr "&Propiedades" #: photofilmstrip/gui/PnlSlideshow.py:39 photofilmstrip/gui/PnlSlideshow.py:40 #: photofilmstrip/gui/PnlTimelapse.py:25 photofilmstrip/gui/PnlTimelapse.py:26 msgid "Import Pictures" msgstr "Importar imágenes" #: photofilmstrip/gui/PnlSlideshow.py:62 photofilmstrip/gui/PnlSlideshow.py:63 #: photofilmstrip/gui/PnlTimelapse.py:41 photofilmstrip/gui/PnlTimelapse.py:42 msgid "Render filmstrip" msgstr "Procesar presentación" #: photofilmstrip/gui/PnlSlideshow.py:89 photofilmstrip/gui/PnlTimelapse.py:66 msgid "Images" msgstr "Imágenes" #: photofilmstrip/gui/PnlSlideshow.py:94 msgid "Duration" msgstr "Duración" #: photofilmstrip/gui/PnlTimelapse.py:69 msgid "Frames" msgstr "Cuadros" #: photofilmstrip/gui/PnlTimelapse.py:92 msgid "The picture counter is not increasing: %s" msgstr "El contador de imágenes no aumenta: %s" #: photofilmstrip/gui/PnlTimelapse.py:110 msgid "" "Filename '%s' does not match a number pattern which is necessary for a time " "lapse slide show!" msgstr "" "¡El nombre de archivo '%s' no contiene un patrón numérico que es necesario " "para una secuencia de imágenes!" #: photofilmstrip/gui/PnlWelcome.py:37 photofilmstrip/gui/PnlWelcome.py:103 msgid "Recent projects" msgstr "Proyectos recientes" #: photofilmstrip/gui/PnlWelcome.py:62 msgid "Open existing project" msgstr "Abrir proyecto existente" #: photofilmstrip/gui/PnlWelcome.py:106 msgid "How to start..." msgstr "Cómo comenzar..." #: photofilmstrip/gui/PnlWelcome.py:107 msgid "Create a new project or load an existing one." msgstr "Crear un proyecto nuevo o abrir uno existente." #: photofilmstrip/gui/PnlWelcome.py:138 msgid "Update available" msgstr "Actualización disponible" #: photofilmstrip/gui/PnlWelcome.py:141 msgid "The following changes has been made:" msgstr "Se realizaron los siguientes cambios:" #: photofilmstrip/gui/WxProjectFile.py:59 msgid "Loading project %s" msgstr "Abriendo proyecto %s" #: photofilmstrip/gui/WxProjectFile.py:75 msgid "Saving project %s" msgstr "Guardando proyecto %s" #: photofilmstrip/gui/WxProjectFile.py:100 msgid "" "Some images does not exist in the folder '%s' anymore. If the files has " "moved you can select the new path. Do you want to select a new path?" msgstr "" "Algunas imágenes ya no existen en la carpeta '%s' . Si los archivos fueron " "movidos, puede seleccionar la nueva ruta. ¿Quiere seleccionar una nueva " "ruta?" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:73 msgid "Elapsed time" msgstr "Tiempo transcurrido" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:85 msgid "Remaining time" msgstr "Tiempo restante" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:203 msgid "Unknown" msgstr "Desconocido" #: photofilmstrip/lib/jobimpl/PnlJobManager.py:50 msgid "&Clear list" msgstr "&Limpiar lista" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:127 msgid "Abort" msgstr "Abortar" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:133 msgid "Remove from list" msgstr "Remover de la lista" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:223 msgid "Abort selected process?" msgstr "¿Abortar proceso seleccionado?" #: photofilmstrip/lib/jobimpl/VisualJob.py:29 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:25 msgid "Waiting..." msgstr "Esperando..." #: photofilmstrip/lib/jobimpl/VisualJob.py:68 #: photofilmstrip/lib/jobimpl/VisualJob.py:85 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:60 msgid "Aborted" msgstr "Abortado" #: photofilmstrip/lib/jobimpl/VisualJob.py:70 msgid "Done" msgstr "Hecho" #: photofilmstrip/lib/jobimpl/VisualJob.py:79 msgid "Aborting..." msgstr "Abortando..." #: photofilmstrip/uwp/UwpService.py:76 msgid "Slideshow created!" msgstr "¡Presentación creada!" photofilmstrip-3.7.2/po/ko.po0000644000232200023220000007301313560357351016557 0ustar debalancedebalancemsgid "" msgstr "" "Project-Id-Version: PhotoFilmStrip\n" "POT-Creation-Date: 2018-11-07 22:03+CET\n" "PO-Revision-Date: 2011-07-10 13:36+0100\n" "Last-Translator: Jens Göpfert \n" "Language-Team: Choi Youn-Soo \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: pygettext.py 1.5\n" "X-Poedit-Language: Korean\n" "X-Poedit-Country: KOREA, REPUBLIC OF\n" "X-Poedit-SourceCharset: utf-8\n" #: photofilmstrip/action/ActionAutoPath.py:23 #: photofilmstrip/gui/PnlPfsProject.py:115 msgid "Random motion" msgstr "무작위 모션" #: photofilmstrip/action/ActionCenterPath.py:21 msgid "Centralize motion" msgstr "" #: photofilmstrip/action/ActionI18N.py:24 #: photofilmstrip/gui/ActionManager.py:170 msgid "Language" msgstr "언어" #: photofilmstrip/action/ActionOpenFolder.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:28 msgid "Open folder" msgstr "폴더 열기" #: photofilmstrip/action/ActionPlayVideo.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:22 msgid "Play video" msgstr "비디오 재생" #: photofilmstrip/action/ActionRender.py:37 #, fuzzy msgid "Start" msgstr "시작(&S)" #: photofilmstrip/cli/Main.py:46 photofilmstrip/cli/Main.py:196 msgid "all done" msgstr "모두 완성" #: photofilmstrip/cli/Main.py:64 msgid "processing project" msgstr "프로젝트 처리" #: photofilmstrip/cli/Main.py:65 msgid "using renderer" msgstr "렌더러 사용" #: photofilmstrip/cli/Main.py:66 msgid "output format" msgstr "출력 포맷" #: photofilmstrip/cli/Main.py:69 msgid "framerate" msgstr "프레임율" #: photofilmstrip/cli/Main.py:103 msgid "specifies the project file" msgstr "프로젝트 파일 지정" #: photofilmstrip/cli/Main.py:104 msgid "The path where to save the output files. Use - for stdout." msgstr "출력 파일을 저장할 경로입니다. 표준 출력 사용." #: photofilmstrip/cli/Main.py:106 photofilmstrip/cli/Main.py:129 msgid "Option videonorm is deprecated, use an appropriate profile!" msgstr "" #: photofilmstrip/cli/Main.py:108 msgid "enable draft mode" msgstr "초안 모드 사용" #: photofilmstrip/cli/Main.py:108 photofilmstrip/gui/DlgRender.py:167 msgid "" "Activate this option to generate a preview of your PhotoFilmStrip. The " "rendering process will speed up dramatically, but results in lower quality." msgstr "" "PhotoFilmStrip의 미리보기를 위해 이 옵션을 활성화하십시오. 렌더링 결과는 낮" "은 품질이지만, 속도는 매우 빠릅니다." #: photofilmstrip/cli/Main.py:120 msgid "project file does not exist: %s" msgstr "프로젝트 파일이 존재하지 않습니다: %s" #: photofilmstrip/cli/Main.py:124 msgid "no project file specified!" msgstr "프로젝트 파일이 지정되지 않았습니다!" #: photofilmstrip/cli/Main.py:134 msgid "invalid format specified: %s" msgstr "잘못된 포맷 지정: %s" #: photofilmstrip/cli/Main.py:140 msgid "invalid profile specified: %s" msgstr "잘못된 프로필 지정: %s" #: photofilmstrip/cli/Main.py:146 #, fuzzy msgid "cannot load project" msgstr "PhotoFilmStrip를 불러올 수 없습니다." #: photofilmstrip/cli/Main.py:159 msgid "cannot create output path: %s" msgstr "출력 경로를 만들 수 없습니다: %s" #: photofilmstrip/cli/Main.py:169 photofilmstrip/gui/DlgConfigureAudio.py:231 #: photofilmstrip/gui/DlgConfigureAudio.py:253 msgid "Audio file '%s' does not exist!" msgstr "'%s' 오디오 파일은 존재하지 않습니다!" #: photofilmstrip/cli/Main.py:190 msgid "...aborted!" msgstr "...중지되었습니다!" #: photofilmstrip/core/BaseRenderer.py:50 msgid "Unknown property: %s" msgstr "알 수없는 속성: %s" #: photofilmstrip/core/BaseRenderer.py:58 msgid "" msgstr "<기본값>" #: photofilmstrip/core/BaseRenderer.py:73 msgid "no" msgstr "아니오" #: photofilmstrip/core/ProjectFile.py:222 #, fuzzy msgid "Saving '%s' ..." msgstr "'%s' 불러오기..." #: photofilmstrip/core/ProjectFile.py:276 msgid "Loading '%s' ..." msgstr "'%s' 불러오기..." #: photofilmstrip/core/RenderEngine.py:113 #: photofilmstrip/core/RenderEngine.py:201 msgid "processing transition %d/%d" msgstr "전환 처리 %d/%d" #: photofilmstrip/core/RenderEngine.py:124 #: photofilmstrip/core/RenderEngine.py:210 msgid "processing image %d/%d" msgstr "이미지 처리 %d/%d" #: photofilmstrip/core/renderer/CairoRenderer.py:35 msgid "Preview" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:50 msgid "GStreamer (python-gst-1.0) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:287 msgid "Bitrate must be a number!" msgstr "비트 전송률은 숫자여야 합니다!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:455 #: photofilmstrip/core/renderer/GStreamerRenderer.py:531 #: photofilmstrip/core/renderer/GStreamerRenderer.py:601 #: photofilmstrip/core/renderer/GStreamerRenderer.py:690 #: photofilmstrip/core/renderer/GStreamerRenderer.py:730 #: photofilmstrip/core/renderer/GStreamerRenderer.py:779 msgid "libav (gstreamer1.0-libav) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:459 #: photofilmstrip/core/renderer/GStreamerRenderer.py:535 #: photofilmstrip/core/renderer/GStreamerRenderer.py:605 msgid "x264-Codec (gstreamer1.0-plugins-ugly) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:463 #: photofilmstrip/core/renderer/GStreamerRenderer.py:609 msgid "MKV-Muxer (gstreamer1.0-plugins-good) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:539 msgid "MP4-Muxer (gstreamer1.0-plugins-good) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:647 msgid "Theora-Codec (gstreamer1.0-plugins-base) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:651 msgid "Vorbis-Codec (gstreamer1.0-plugins-base) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:655 msgid "OGV-Muxer (gstreamer1.0-plugins-base) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:686 #: photofilmstrip/core/renderer/GStreamerRenderer.py:726 #: photofilmstrip/core/renderer/GStreamerRenderer.py:775 msgid "MPEG-1/2-Codec (gstreamer1.0-plugins-bad) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:694 #: photofilmstrip/core/renderer/GStreamerRenderer.py:734 #: photofilmstrip/core/renderer/GStreamerRenderer.py:783 msgid "MPEG-Muxer (gstreamer1.0-plugins-bad) required!" msgstr "" #: photofilmstrip/core/renderer/SingleFileRenderer.py:21 msgid "Single pictures" msgstr "단일 사진" #: photofilmstrip/core/tasks.py:48 msgid "generating subtitle" msgstr "자막 만들기" #: photofilmstrip/gui/ActionManager.py:60 #: photofilmstrip/gui/ActionManager.py:190 msgid "&File" msgstr "파일(&E)" #: photofilmstrip/gui/ActionManager.py:61 #: photofilmstrip/gui/ActionManager.py:191 msgid "&Edit" msgstr "편집(&E)" #: photofilmstrip/gui/ActionManager.py:62 #: photofilmstrip/gui/ActionManager.py:154 photofilmstrip/gui/DlgRender.py:141 #: photofilmstrip/gui/DlgRendererProps.py:86 msgid "&Help" msgstr "도움말(&H)" #: photofilmstrip/gui/ActionManager.py:76 msgid "New Slideshow" msgstr "" #: photofilmstrip/gui/ActionManager.py:81 msgid "Open" msgstr "" #: photofilmstrip/gui/ActionManager.py:87 msgid "Save" msgstr "" #: photofilmstrip/gui/ActionManager.py:97 #: photofilmstrip/gui/ActionManager.py:98 msgid "Show job queue" msgstr "" #: photofilmstrip/gui/ActionManager.py:108 #: photofilmstrip/gui/PnlSlideshow.py:25 msgid "Slideshow" msgstr "" #: photofilmstrip/gui/ActionManager.py:110 #: photofilmstrip/gui/PnlTimelapse.py:18 msgid "Timelapse" msgstr "" #: photofilmstrip/gui/ActionManager.py:116 msgid "New" msgstr "" #: photofilmstrip/gui/ActionManager.py:118 msgid "&Open" msgstr "" #: photofilmstrip/gui/ActionManager.py:123 msgid "&Save" msgstr "" #: photofilmstrip/gui/ActionManager.py:136 msgid "&Close" msgstr "닫기(&C)" #: photofilmstrip/gui/ActionManager.py:141 msgid "E&xit" msgstr "종료(&x)" #: photofilmstrip/gui/ActionManager.py:173 msgid "&About" msgstr "정보(&A)" #: photofilmstrip/gui/DlgBugReport.py:41 msgid "An unexpected error occured" msgstr "예기치 않은 오류가 발생했습니다." #: photofilmstrip/gui/DlgBugReport.py:44 msgid "" "An unexpected error occured. Do you want to send this bug report to the " "developers of %s?" msgstr "" "예기치 않은 오류가 발생했습니다. 이 버그 리포트를 %s의 개발자에게 보내시겠습" "니까?" #: photofilmstrip/gui/DlgBugReport.py:99 msgid "Bug-Report send. Thank you for your support." msgstr "버그 리포트를 보냅니다. 당신의 지원에 감사합니다." #: photofilmstrip/gui/DlgBugReport.py:100 photofilmstrip/gui/FrmMain.py:290 msgid "Information" msgstr "정보" #: photofilmstrip/gui/DlgBugReport.py:106 msgid "Sorry, this function is temporary not available.." msgstr "죄송합니다. 이 기능은 일시적으로 사용할 수 없습니다.." #: photofilmstrip/gui/DlgBugReport.py:107 #: photofilmstrip/gui/DlgConfigureAudio.py:232 #: photofilmstrip/gui/DlgConfigureAudio.py:244 #: photofilmstrip/gui/DlgConfigureAudio.py:254 #: photofilmstrip/gui/DlgNewProject.py:156 #: photofilmstrip/gui/DlgNewProject.py:167 #: photofilmstrip/gui/DlgPicDurationByAudio.py:208 #: photofilmstrip/gui/DlgPicDurationByAudio.py:216 #: photofilmstrip/gui/FrmMain.py:376 photofilmstrip/gui/PnlPfsProject.py:468 #: photofilmstrip/gui/PnlTimelapse.py:113 msgid "Error" msgstr "오류" #: photofilmstrip/gui/DlgConfigureAudio.py:55 msgid "Configure your audio files that are used as a background music." msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:90 msgid "Set the duration of your slideshow to fit your audio files" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:92 #: photofilmstrip/gui/DlgDuration.py:70 photofilmstrip/gui/DlgNewProject.py:84 #: photofilmstrip/gui/DlgPicDurationByAudio.py:50 #: photofilmstrip/gui/DlgPositionInput.py:238 #: photofilmstrip/gui/DlgRender.py:147 #: photofilmstrip/gui/DlgRendererProps.py:92 #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:97 msgid "&Cancel" msgstr "취소(&C)" #: photofilmstrip/gui/DlgConfigureAudio.py:97 #: photofilmstrip/gui/DlgDuration.py:72 photofilmstrip/gui/DlgNewProject.py:86 #: photofilmstrip/gui/DlgPicDurationByAudio.py:51 #: photofilmstrip/gui/DlgPositionInput.py:244 #: photofilmstrip/gui/DlgRendererProps.py:97 msgid "&Ok" msgstr "확인(&O)" #: photofilmstrip/gui/DlgConfigureAudio.py:104 #: photofilmstrip/gui/DlgConfigureAudio.py:109 #: photofilmstrip/gui/PnlSlideshow.py:47 photofilmstrip/gui/PnlSlideshow.py:48 #: photofilmstrip/gui/PnlTimelapse.py:33 photofilmstrip/gui/PnlTimelapse.py:34 msgid "Configure music" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:138 msgid "Select music" msgstr "음악 선택" #: photofilmstrip/gui/DlgConfigureAudio.py:140 msgid "Audio files" msgstr "오디오 파일" #: photofilmstrip/gui/DlgConfigureAudio.py:243 #, fuzzy msgid "Audio file not supported!" msgstr "'%s' 오디오 파일은 존재하지 않습니다!" #: photofilmstrip/gui/DlgDuration.py:48 msgid "Total length:" msgstr "총 길이:" #: photofilmstrip/gui/DlgDuration.py:50 msgid "" "Overrides the duration of single pictures and gives the project this total " "length." msgstr "총 길이는 단일 사진의 지속기간과 프로젝트에 우선합니다." #: photofilmstrip/gui/DlgDuration.py:54 msgid "User defined:" msgstr "사용자 정의:" #: photofilmstrip/gui/DlgDuration.py:65 #, fuzzy msgid "Fit to audio files" msgstr "오디오 파일" #: photofilmstrip/gui/DlgDuration.py:80 msgid "Slideshow duration" msgstr "" #: photofilmstrip/gui/DlgDuration.py:84 msgid "Configure duration of slideshow" msgstr "" #: photofilmstrip/gui/DlgNewProject.py:61 msgid "Project name:" msgstr "프로젝트명:" #: photofilmstrip/gui/DlgNewProject.py:66 msgid "Folder:" msgstr "폴더:" #: photofilmstrip/gui/DlgNewProject.py:78 msgid "Aspect ratio:" msgstr "화면 비율:" #: photofilmstrip/gui/DlgNewProject.py:110 #, fuzzy msgid "Unnamed project" msgstr "PhotoFilmStrip를 불러올 수 없습니다." #: photofilmstrip/gui/DlgNewProject.py:116 msgid "My PhotoFilmStrips" msgstr "내 PhotoFilmStrips" #: photofilmstrip/gui/DlgNewProject.py:126 msgid "Browse for folder" msgstr "폴더 찾기" #: photofilmstrip/gui/DlgNewProject.py:145 msgid "Folder does not exists! Do you want %s to create it?" msgstr "폴더가 존재하지 않습니다! %s 폴더를 만드시겠습니까?" #: photofilmstrip/gui/DlgNewProject.py:146 #: photofilmstrip/gui/PnlEditorPage.py:29 #: photofilmstrip/gui/PnlEditorPage.py:49 #: photofilmstrip/gui/PnlEditorPage.py:88 #: photofilmstrip/gui/WxProjectFile.py:101 #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:224 msgid "Question" msgstr "질문" #: photofilmstrip/gui/DlgNewProject.py:155 msgid "Cannot create folder: %s" msgstr "폴더를 만들 수 없습니다: %s" #: photofilmstrip/gui/DlgNewProject.py:166 msgid "Cannot write into folder!" msgstr "폴더에 쓰기 권한이 없습니다!" #: photofilmstrip/gui/DlgNewProject.py:180 msgid "The project name must be filled." msgstr "프로젝트명을 입력해야 합니다." #: photofilmstrip/gui/DlgNewProject.py:186 msgid "The project name contains invalid characters." msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:23 #: photofilmstrip/gui/PnlSlideshow.py:54 photofilmstrip/gui/PnlSlideshow.py:55 msgid "Adjust picture durations" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:26 msgid "Adjust picture durations to audio file" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:30 msgid "" "Find your picture duration by playing the audio file of your project and\n" "pressing the hit button to apply the current playing time." msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:43 #: photofilmstrip/gui/DlgPicDurationByAudio.py:153 msgid "Play" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:46 msgid "Hit" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:100 msgid "Stop" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:179 #, fuzzy msgid "Playing time" msgstr "비디오 재생" #: photofilmstrip/gui/DlgPicDurationByAudio.py:207 msgid "Your project does not have an audio file configured." msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:215 msgid "" "Your project uses more than one audio file. Currently the durations can be " "adjusted only for one audio file." msgstr "" #: photofilmstrip/gui/DlgPositionInput.py:140 msgid "Motion positions" msgstr "모션 위치" #: photofilmstrip/gui/DlgPositionInput.py:147 msgid "Start position" msgstr "시작 위치" #: photofilmstrip/gui/DlgPositionInput.py:155 #: photofilmstrip/gui/DlgPositionInput.py:199 msgid "Location:" msgstr "위치:" #: photofilmstrip/gui/DlgPositionInput.py:173 #: photofilmstrip/gui/DlgPositionInput.py:215 msgid "Size:" msgstr "크기:" #: photofilmstrip/gui/DlgPositionInput.py:191 msgid "End position" msgstr "끝 위치" #: photofilmstrip/gui/DlgPositionInput.py:233 msgid "Reset" msgstr "재설정" #: photofilmstrip/gui/DlgPositionInput.py:252 msgid "Adjust motion positions directly" msgstr "직접 모션 위치 조정" #: photofilmstrip/gui/DlgRender.py:96 #, fuzzy msgid "Render project" msgstr "최근 프로젝트" #: photofilmstrip/gui/DlgRender.py:107 msgid "Format:" msgstr "포맷:" #: photofilmstrip/gui/DlgRender.py:122 msgid "Properties" msgstr "속성" #: photofilmstrip/gui/DlgRender.py:127 msgid "Profile:" msgstr "프로필:" #: photofilmstrip/gui/DlgRender.py:136 msgid "Draft" msgstr "초안" #: photofilmstrip/gui/DlgRender.py:152 msgid "&Start" msgstr "시작(&S)" #: photofilmstrip/gui/DlgRender.py:164 msgid "Configure output and start render process" msgstr "구성 출력 및 렌더링 과정 시작" #: photofilmstrip/gui/DlgRendererProps.py:50 msgid "Property" msgstr "속성" #: photofilmstrip/gui/DlgRendererProps.py:52 msgid "Value" msgstr "값" #: photofilmstrip/gui/DlgRendererProps.py:71 msgid "Output properties" msgstr "출력 속성" #: photofilmstrip/gui/DlgRendererProps.py:113 msgid "Edit extended output properties" msgstr "확장 출력 속성 편집" #: photofilmstrip/gui/DlgRendererProps.py:147 msgid "Edit property" msgstr "속성 편집" #: photofilmstrip/gui/FrmMain.py:83 msgid "Welcome" msgstr "환영" #: photofilmstrip/gui/FrmMain.py:85 msgid "Job queue" msgstr "" #: photofilmstrip/gui/FrmMain.py:141 msgid "Rendering in progress..." msgstr "" #: photofilmstrip/gui/FrmMain.py:234 photofilmstrip/gui/PnlWelcome.py:57 #, fuzzy msgid "Create new slideshow" msgstr "포터블" #: photofilmstrip/gui/FrmMain.py:241 #, fuzzy msgid "Create new timelapse" msgstr "새 프로젝트 만들기" #: photofilmstrip/gui/FrmMain.py:249 msgid "Select %s-Project" msgstr "%s-프로젝트 선택" #: photofilmstrip/gui/FrmMain.py:251 #, fuzzy msgid "Files" msgstr "파일(&E)" #: photofilmstrip/gui/FrmMain.py:289 msgid "You must restart %s for your new language setting to take effect." msgstr "새 언어 설정을 적용하려면 %s 을 다시 시작해야 합니다." #: photofilmstrip/gui/FrmMain.py:300 msgid "" "PhotoFilmStrip creates movies out of your pictures in just 3 steps. First " "select your photos, customize the motion path and render the video. There " "are several output possibilities for VCD, SVCD, DVD up to FULL-HD." msgstr "" "PhotoFilmStrip은 3단계로 사진을 영화로 만들 수 있습니다. 처음으로 사진을 선택" "하고, 사용자 모션 경로를 정의하고 비디오를 렌더합니다. VCD, SVCD, DVD, 풀 HD " "등 출력 가능한 몇 가지가 있습니다." #: photofilmstrip/gui/FrmMain.py:303 msgid "online" msgstr "온라인" #: photofilmstrip/gui/FrmMain.py:374 msgid "Invalid %(app)s-Project: %(file)s" msgstr "잘못된 %(app)s-프로젝트 %(file)s" #: photofilmstrip/gui/PnlAddPics.py:50 photofilmstrip/gui/PnlWelcome.py:30 msgid "Welcome to PhotoFilmStrip" msgstr "PhotoFilmStrip에 오신 것을 환영합니다" #: photofilmstrip/gui/PnlAddPics.py:52 msgid "" "Drag some pictures onto this text or\n" "click the button below\n" "to add pictures to your new PhotoFilmStrip." msgstr "" "이 텍스트 위에 여러 사진을 드래그하거나\n" "아래 버튼을 클릭하여\n" "PhotoFilmStrip에 새 사진을 추가할 수 있습니다." #: photofilmstrip/gui/PnlEditPicture.py:142 msgid "Settings" msgstr "설정" #: photofilmstrip/gui/PnlEditPicture.py:146 msgid "Rotation:" msgstr "회전:" #: photofilmstrip/gui/PnlEditPicture.py:166 msgid "Effect:" msgstr "효과:" #: photofilmstrip/gui/PnlEditPicture.py:180 msgid "Process" msgstr "과정" #: photofilmstrip/gui/PnlEditPicture.py:184 msgid "Movement:" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:196 #: photofilmstrip/gui/PnlEditPicture.py:212 #: photofilmstrip/gui/PnlEditPicture.py:359 msgid "sec" msgstr "초" #: photofilmstrip/gui/PnlEditPicture.py:200 msgid "Transition:" msgstr "전환:" #: photofilmstrip/gui/PnlEditPicture.py:220 msgid "Subtitle" msgstr "자막" #: photofilmstrip/gui/PnlEditPicture.py:240 msgid "Linear" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:241 msgid "Accelerated" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:242 msgid "Delayed" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:250 msgid "No effect" msgstr "효과 없음" #: photofilmstrip/gui/PnlEditPicture.py:251 msgid "Black and White" msgstr "흑백" #: photofilmstrip/gui/PnlEditPicture.py:252 msgid "Sepia tone" msgstr "암갈색 톤" #: photofilmstrip/gui/PnlEditPicture.py:258 msgid "None" msgstr "없음" #: photofilmstrip/gui/PnlEditPicture.py:259 msgid "Fade" msgstr "투명하게" #: photofilmstrip/gui/PnlEditPicture.py:260 msgid "Roll" msgstr "이동" #: photofilmstrip/gui/PnlEditPicture.py:354 msgid "fpp" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:355 msgid "frames per picture - the number of frames each picture will be shown" msgstr "" #: photofilmstrip/gui/PnlEditorPage.py:26 msgid "Could not save the file '%(file)s': %(errMsg)s" msgstr "'%(file)s' 파일을 저장할 수 없습니다: %(errMsg)s" #: photofilmstrip/gui/PnlEditorPage.py:45 msgid "New file" msgstr "" #: photofilmstrip/gui/PnlEditorPage.py:48 msgid "'%s' has been modified. Save changes?" msgstr "'%s' 파일이 수정되었습니다. 저장하시겠습니까?" #: photofilmstrip/gui/PnlEditorPage.py:74 #, fuzzy msgid "Save %s" msgstr "%s-프로젝트 저장" #: photofilmstrip/gui/PnlEditorPage.py:77 #, fuzzy msgid "File" msgstr "파일(&E)" #: photofilmstrip/gui/PnlEditorPage.py:87 msgid "Overwrite existing file '%s'?" msgstr "기존의 '%s' 파일을 덮어 쓰시겠습니까?" #: photofilmstrip/gui/PnlPfsProject.py:118 #: photofilmstrip/gui/PnlPfsProject.py:120 msgid "Set motion start to end" msgstr "끝 모션을 시작에 설정" #: photofilmstrip/gui/PnlPfsProject.py:122 #: photofilmstrip/gui/PnlPfsProject.py:124 msgid "Set motion end to start" msgstr "시작 모션을 끝에 설정" #: photofilmstrip/gui/PnlPfsProject.py:126 #: photofilmstrip/gui/PnlPfsProject.py:128 #, fuzzy msgid "Swap motion" msgstr "무작위 모션" #: photofilmstrip/gui/PnlPfsProject.py:131 #: photofilmstrip/gui/PnlPfsProject.py:133 msgid "Adjust motion manual" msgstr "모션 수동 조정" #: photofilmstrip/gui/PnlPfsProject.py:136 #: photofilmstrip/gui/PnlPfsProject.py:138 msgid "Preserve image dimension" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:294 msgid "&Import Pictures" msgstr "이미지 수입(&I)" #: photofilmstrip/gui/PnlPfsProject.py:299 msgid "Move picture &left" msgstr "왼쪽으로 사진 이동(&l)" #: photofilmstrip/gui/PnlPfsProject.py:303 msgid "Move picture &right" msgstr "오른쪽으로 사진 이동(&r)" #: photofilmstrip/gui/PnlPfsProject.py:308 #, fuzzy msgid "R&emove Picture" msgstr "이미지 제거(&R)" #: photofilmstrip/gui/PnlPfsProject.py:313 msgid "Rotate &clockwise" msgstr "오른쪽으로 회전(&c)" #: photofilmstrip/gui/PnlPfsProject.py:317 msgid "Rotate counter clock&wise" msgstr "왼쪽으로 회전(&w)" #: photofilmstrip/gui/PnlPfsProject.py:322 #, fuzzy msgid "Random &motion" msgstr "무작위 모션" #: photofilmstrip/gui/PnlPfsProject.py:326 msgid "Centralize m&otion" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:384 msgid "Export slideshow" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:387 #: photofilmstrip/gui/PnlPfsProject.py:400 #, fuzzy msgid "Portable slideshow" msgstr "포터블" #: photofilmstrip/gui/PnlPfsProject.py:398 #, fuzzy msgid "Import Slideshow" msgstr "이미지 수입" #: photofilmstrip/gui/PnlPfsProject.py:409 msgid "Import images" msgstr "이미지 수입" #: photofilmstrip/gui/PnlPfsProject.py:411 #, fuzzy msgid "Image files" msgstr "이미지 파일" #: photofilmstrip/gui/PnlPfsProject.py:654 msgid "Audio file '%s' does not exist! Continue anyway?" msgstr "'%s' 오디오 파일이 존재하지 않습니다! 계속하시겠습니까?" #: photofilmstrip/gui/PnlPfsProject.py:655 msgid "Warning" msgstr "경고" #: photofilmstrip/gui/PnlSlideshow.py:30 msgid "&Properties" msgstr "환경 설정(&P)" #: photofilmstrip/gui/PnlSlideshow.py:39 photofilmstrip/gui/PnlSlideshow.py:40 #: photofilmstrip/gui/PnlTimelapse.py:25 photofilmstrip/gui/PnlTimelapse.py:26 msgid "Import Pictures" msgstr "사진 수입" #: photofilmstrip/gui/PnlSlideshow.py:62 photofilmstrip/gui/PnlSlideshow.py:63 #: photofilmstrip/gui/PnlTimelapse.py:41 photofilmstrip/gui/PnlTimelapse.py:42 msgid "Render filmstrip" msgstr "Filmstrip 렌더" #: photofilmstrip/gui/PnlSlideshow.py:89 photofilmstrip/gui/PnlTimelapse.py:66 msgid "Images" msgstr "이미지" #: photofilmstrip/gui/PnlSlideshow.py:94 msgid "Duration" msgstr "지속기간" #: photofilmstrip/gui/PnlTimelapse.py:69 msgid "Frames" msgstr "" #: photofilmstrip/gui/PnlTimelapse.py:92 msgid "The picture counter is not increasing: %s" msgstr "" #: photofilmstrip/gui/PnlTimelapse.py:110 msgid "" "Filename '%s' does not match a number pattern which is necessary for a time " "lapse slide show!" msgstr "" #: photofilmstrip/gui/PnlWelcome.py:37 photofilmstrip/gui/PnlWelcome.py:103 msgid "Recent projects" msgstr "최근 프로젝트" #: photofilmstrip/gui/PnlWelcome.py:62 msgid "Open existing project" msgstr "기존 프로젝트 열기" #: photofilmstrip/gui/PnlWelcome.py:106 msgid "How to start..." msgstr "시작 방법..." #: photofilmstrip/gui/PnlWelcome.py:107 msgid "Create a new project or load an existing one." msgstr "새 프로젝트를 만들거나 기존의 프로젝트를 불러오십시오." #: photofilmstrip/gui/PnlWelcome.py:138 msgid "Update available" msgstr "사용 가능한 업데이트" #: photofilmstrip/gui/PnlWelcome.py:141 msgid "The following changes has been made:" msgstr "다음과 같이 변경되습니다:" #: photofilmstrip/gui/WxProjectFile.py:59 #, fuzzy msgid "Loading project %s" msgstr "프로젝트 불러오기" #: photofilmstrip/gui/WxProjectFile.py:75 #, fuzzy msgid "Saving project %s" msgstr "프로젝트 저장" #: photofilmstrip/gui/WxProjectFile.py:100 msgid "" "Some images does not exist in the folder '%s' anymore. If the files has " "moved you can select the new path. Do you want to select a new path?" msgstr "" "일부 이미지는 '%s' 폴더에 더 이상 존재하지 않습니다. 만약 파일이 이동되었다" "면 새 경로를 선택할 수 있습니다. 새 경로를 선택하시겠습니까?" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:73 msgid "Elapsed time" msgstr "" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:85 msgid "Remaining time" msgstr "" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:203 msgid "Unknown" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobManager.py:50 msgid "&Clear list" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:127 msgid "Abort" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:133 msgid "Remove from list" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:223 #, fuzzy msgid "Abort selected process?" msgstr "현재 과정을 중지시키겠습니까?" #: photofilmstrip/lib/jobimpl/VisualJob.py:29 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:25 #, fuzzy msgid "Waiting..." msgstr "중지..." #: photofilmstrip/lib/jobimpl/VisualJob.py:68 #: photofilmstrip/lib/jobimpl/VisualJob.py:85 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:60 #, fuzzy msgid "Aborted" msgstr "...중지되었습니다!" #: photofilmstrip/lib/jobimpl/VisualJob.py:70 msgid "Done" msgstr "" #: photofilmstrip/lib/jobimpl/VisualJob.py:79 #, fuzzy msgid "Aborting..." msgstr "중지..." #: photofilmstrip/uwp/UwpService.py:76 msgid "Slideshow created!" msgstr "" #, fuzzy #~ msgid "Audio files:" #~ msgstr "오디오 파일" #~ msgid "Project properties" #~ msgstr "프로젝트 속성" #~ msgid "PhotoFilmStrip project" #~ msgstr "PhotoFilmStrip 프로젝트" #~ msgid "Unnamed PhotoFilmStrip" #~ msgstr "Unnamed PhotoFilmStrip" #~ msgid "Project" #~ msgstr "프로젝트" #~ msgid "invalid videonorm specified: %s" #~ msgstr "잘못된 비디오 표준이 지정되었습니다.: %s" #~ msgid "Error: %s" #~ msgstr "오류: %s" #~ msgid "Please wait..." #~ msgstr "기다려주십시오..." #~ msgid "initialize renderer" #~ msgstr "렌더러 초기화" #~ msgid "creating output..." #~ msgstr "출력 만들기..." #~ msgid "mencoder (mencoder) required!" #~ msgstr "mencoder (mencoder) 가 필요합니다!" #~ msgid "MPEG(1/2)-Video (MPG)" #~ msgstr "MPEG(1/2)-비디오 (MPG)" #~ msgid "MPEG format supports only VCD, SVCD and DVD profile!" #~ msgstr "MPEG 포맷은 VCD, SVCD와 DVD 프로필만 지원합니다!" #~ msgid "MPEG4-XVid/AC3 (AVI)" #~ msgstr "MPEG4-XVid/AC3 (AVI)" #, fuzzy #~ msgid "mencoder with MP3 support (mp3lame) required!" #~ msgstr "mencoder (mencoder) 가 필요합니다!" #~ msgid "MPEG4-XVid/MP3 (AVI)" #~ msgstr "MPEG4-XVid/MP3 (AVI)" #~ msgid "Flash-Video (FLV)" #~ msgstr "플래시 비디오 (FLV)" #~ msgid "Motion-JPEG (AVI)" #~ msgstr "모션-JPEG (AVI)" #~ msgid "&Tools" #~ msgstr "도구(&T)" #~ msgid "New Project" #~ msgstr "새 프로젝트" #~ msgid "&New Project" #~ msgstr "새 프로젝트(&N)" #~ msgid "&Open Project" #~ msgstr "프로젝트 열기(&O)" #~ msgid "&Save Project" #~ msgstr "프로젝트 저장(&S)" #~ msgid "&Close Project" #~ msgstr "프로젝트 닫기(&C)" #~ msgid "&Render filmstrip" #~ msgstr "Filmstrip 렌더(&R)" #~ msgid "Finalizing" #~ msgstr "완성" #~ msgid "Choose your next action:" #~ msgstr "다음 작업을 선택하십시오:" #~ msgid "Delete unfinished result" #~ msgstr "미완성 결과 지우기" #~ msgid "Do nothing" #~ msgstr "아무것도 하지 않음" #~ msgid "Show error again and send to developer." #~ msgstr "오류가 다시 보이면 개발자에게 보내십시오." #~ msgid "The rendering process was aborted." #~ msgstr "렌더링 과정이 정지되었습니다." #~ msgid "The rendering process was interrupted." #~ msgstr "렌더링 과정이 일시 정지되었습니다." #~ msgid "The rendering process has been finished." #~ msgstr "렌더링 과정이 끝났습니다." #~ msgid "Audio file:" #~ msgstr "오디오 파일:" #~ msgid "Type:" #~ msgstr "종류:" #~ msgid "&Batch Job" #~ msgstr "일괄 작업(&B)" #~ msgid "" #~ "Project not saved yet. Please save the project first to create a batch " #~ "job!" #~ msgstr "" #~ "프로젝트가 저장되지 않았습니다. 일괄 작업을 만들 프로젝트를 처음으로 저장" #~ "하십시오!" #~ msgid "Batch file" #~ msgstr "배치 파일" #~ msgid "Shell script" #~ msgstr "쉘 스크립트" #~ msgid "Select batch file" #~ msgstr "배치 파일 선택" #~ msgid "Export %s-Project" #~ msgstr "%s-프로젝트 수출" #~ msgid "Import %s-Project" #~ msgstr "%s-프로젝트 수입" #~ msgid "Duration:" #~ msgstr "지속기간:" #~ msgid "Browse" #~ msgstr "찾아보기" #~ msgid "Import image" #~ msgstr "이미지 수입" #~ msgid "Please wait" #~ msgstr "기다려주십시오" #~ msgid "Loading pictures..." #~ msgstr "사진 불러오기..." #~ msgid "Invalid audio file!" #~ msgstr "잘못된 오디오 파일입니다!" photofilmstrip-3.7.2/po/ta.po0000644000232200023220000011467013560357351016557 0ustar debalancedebalance# Tamil translation for photofilmstrip # Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 # This file is distributed under the same license as the photofilmstrip package. # FIRST AUTHOR , 2012. # msgid "" msgstr "" "Project-Id-Version: photofilmstrip\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2018-11-07 22:03+CET\n" "PO-Revision-Date: 2012-12-05 23:21+0100\n" "Last-Translator: Jens Göpfert \n" "Language-Team: Tamil \n" "Language: ta\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2012-12-05 22:12+0000\n" "X-Generator: Launchpad (build 16341)\n" #: photofilmstrip/action/ActionAutoPath.py:23 #: photofilmstrip/gui/PnlPfsProject.py:115 msgid "Random motion" msgstr "சீரற்ற நகர்ச்சி" #: photofilmstrip/action/ActionCenterPath.py:21 msgid "Centralize motion" msgstr "" #: photofilmstrip/action/ActionI18N.py:24 #: photofilmstrip/gui/ActionManager.py:170 msgid "Language" msgstr "மொழி" #: photofilmstrip/action/ActionOpenFolder.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:28 msgid "Open folder" msgstr "அடைவைத் திற" #: photofilmstrip/action/ActionPlayVideo.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:22 msgid "Play video" msgstr "நிகழ்படத்தை ஓட்டு" #: photofilmstrip/action/ActionRender.py:37 #, fuzzy msgid "Start" msgstr "&தொடங்கு" #: photofilmstrip/cli/Main.py:46 photofilmstrip/cli/Main.py:196 msgid "all done" msgstr "எல்லாம் முடிந்தது" #: photofilmstrip/cli/Main.py:64 msgid "processing project" msgstr "திட்டப்பணி செயலாக்கப்படுகிறது" #: photofilmstrip/cli/Main.py:65 msgid "using renderer" msgstr "நிகழ்பட வழங்கி பயன்படுத்தப்படுகிறது" #: photofilmstrip/cli/Main.py:66 msgid "output format" msgstr "வெளிப்பாட்டு வடிவம்" #: photofilmstrip/cli/Main.py:69 msgid "framerate" msgstr "சட்டத் திறன்" #: photofilmstrip/cli/Main.py:103 msgid "specifies the project file" msgstr "திட்டப்பணிக் கோப்பை குறிப்பிடுகிறது" #: photofilmstrip/cli/Main.py:104 msgid "The path where to save the output files. Use - for stdout." msgstr "" "வெளிப்பாட்டுக் கோப்புகளை சேமிக்க வேண்டிய இடம். திட்ட வெளிப்பாட்டுக்கு '-' பயன்படுத்தவும்." #: photofilmstrip/cli/Main.py:106 photofilmstrip/cli/Main.py:129 msgid "Option videonorm is deprecated, use an appropriate profile!" msgstr "" #: photofilmstrip/cli/Main.py:108 msgid "enable draft mode" msgstr "வரைவு நிலையை செயல்படுத்து" #: photofilmstrip/cli/Main.py:108 photofilmstrip/gui/DlgRender.py:167 msgid "" "Activate this option to generate a preview of your PhotoFilmStrip. The " "rendering process will speed up dramatically, but results in lower quality." msgstr "" "உங்கள் போடோபிலம்ஸ்டிரிப்பின் மூன்னோட்டத்தை உருவாக்க இந்த தேர்வை செயல்படுத்தவும். செயலாக்க " "வேகம் வியப்பூட்டும் அளவுக்கு கூடும், ஆனால் தரம் குறையும்." #: photofilmstrip/cli/Main.py:120 msgid "project file does not exist: %s" msgstr "திட்டப்பணி கோப்பு இல்லை: %s" #: photofilmstrip/cli/Main.py:124 msgid "no project file specified!" msgstr "திட்டப்பணி கோப்பு குறிப்பிடப்படவில்லை!" #: photofilmstrip/cli/Main.py:134 msgid "invalid format specified: %s" msgstr "தவறான வடிவம் குறிப்பிடப்பட்டுள்ளது: %s" #: photofilmstrip/cli/Main.py:140 msgid "invalid profile specified: %s" msgstr "குறிப்பிடப்பட்ட தன்விவரம் ஏற்றுக்கொள்ளத்தக்கது இல்லை: %s" #: photofilmstrip/cli/Main.py:146 #, fuzzy msgid "cannot load project" msgstr "போடோபில்ம்ஸ்டிரிப்பை ஏற்ற முடியவில்லை" #: photofilmstrip/cli/Main.py:159 msgid "cannot create output path: %s" msgstr "வெளிப்பாட்டு பாதையை உருவாக்க முடியவில்லை: %s" #: photofilmstrip/cli/Main.py:169 photofilmstrip/gui/DlgConfigureAudio.py:231 #: photofilmstrip/gui/DlgConfigureAudio.py:253 msgid "Audio file '%s' does not exist!" msgstr "ஒலிக் கோப்பு '%s' கோப்பமைப்பில் இல்லை!" #: photofilmstrip/cli/Main.py:190 msgid "...aborted!" msgstr "...நிறுத்தப்பட்டது!" #: photofilmstrip/core/BaseRenderer.py:50 msgid "Unknown property: %s" msgstr "தெரியாத பண்பு: %s" #: photofilmstrip/core/BaseRenderer.py:58 msgid "" msgstr "<இயல்பிருப்பு>" #: photofilmstrip/core/BaseRenderer.py:73 msgid "no" msgstr "இல்லை" #: photofilmstrip/core/ProjectFile.py:222 #, fuzzy msgid "Saving '%s' ..." msgstr "'%s' ஏற்றப்படுகிறது..." #: photofilmstrip/core/ProjectFile.py:276 msgid "Loading '%s' ..." msgstr "'%s' ஏற்றப்படுகிறது..." #: photofilmstrip/core/RenderEngine.py:113 #: photofilmstrip/core/RenderEngine.py:201 msgid "processing transition %d/%d" msgstr "சீர்மாற்றம் %d/%d செயலாக்கப்படுகிறது" #: photofilmstrip/core/RenderEngine.py:124 #: photofilmstrip/core/RenderEngine.py:210 msgid "processing image %d/%d" msgstr "நிழற்படம் %d/%d செயலாக்கப்படுகிறது" #: photofilmstrip/core/renderer/CairoRenderer.py:35 msgid "Preview" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:50 msgid "GStreamer (python-gst-1.0) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:287 msgid "Bitrate must be a number!" msgstr "நுண்மி விகிதம் எண்ணாக இருக்க வேண்டும்!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:455 #: photofilmstrip/core/renderer/GStreamerRenderer.py:531 #: photofilmstrip/core/renderer/GStreamerRenderer.py:601 #: photofilmstrip/core/renderer/GStreamerRenderer.py:690 #: photofilmstrip/core/renderer/GStreamerRenderer.py:730 #: photofilmstrip/core/renderer/GStreamerRenderer.py:779 msgid "libav (gstreamer1.0-libav) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:459 #: photofilmstrip/core/renderer/GStreamerRenderer.py:535 #: photofilmstrip/core/renderer/GStreamerRenderer.py:605 msgid "x264-Codec (gstreamer1.0-plugins-ugly) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:463 #: photofilmstrip/core/renderer/GStreamerRenderer.py:609 msgid "MKV-Muxer (gstreamer1.0-plugins-good) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:539 msgid "MP4-Muxer (gstreamer1.0-plugins-good) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:647 msgid "Theora-Codec (gstreamer1.0-plugins-base) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:651 msgid "Vorbis-Codec (gstreamer1.0-plugins-base) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:655 msgid "OGV-Muxer (gstreamer1.0-plugins-base) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:686 #: photofilmstrip/core/renderer/GStreamerRenderer.py:726 #: photofilmstrip/core/renderer/GStreamerRenderer.py:775 msgid "MPEG-1/2-Codec (gstreamer1.0-plugins-bad) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:694 #: photofilmstrip/core/renderer/GStreamerRenderer.py:734 #: photofilmstrip/core/renderer/GStreamerRenderer.py:783 msgid "MPEG-Muxer (gstreamer1.0-plugins-bad) required!" msgstr "" #: photofilmstrip/core/renderer/SingleFileRenderer.py:21 msgid "Single pictures" msgstr "ஒற்றைப் படங்கள்" #: photofilmstrip/core/tasks.py:48 msgid "generating subtitle" msgstr "துனை உரை உருவாக்கப்படுகிறது" #: photofilmstrip/gui/ActionManager.py:60 #: photofilmstrip/gui/ActionManager.py:190 msgid "&File" msgstr "&கோப்பு" #: photofilmstrip/gui/ActionManager.py:61 #: photofilmstrip/gui/ActionManager.py:191 msgid "&Edit" msgstr "&திருத்து" #: photofilmstrip/gui/ActionManager.py:62 #: photofilmstrip/gui/ActionManager.py:154 photofilmstrip/gui/DlgRender.py:141 #: photofilmstrip/gui/DlgRendererProps.py:86 msgid "&Help" msgstr "&உதவி" #: photofilmstrip/gui/ActionManager.py:76 msgid "New Slideshow" msgstr "" #: photofilmstrip/gui/ActionManager.py:81 msgid "Open" msgstr "" #: photofilmstrip/gui/ActionManager.py:87 msgid "Save" msgstr "" #: photofilmstrip/gui/ActionManager.py:97 #: photofilmstrip/gui/ActionManager.py:98 msgid "Show job queue" msgstr "" #: photofilmstrip/gui/ActionManager.py:108 #: photofilmstrip/gui/PnlSlideshow.py:25 msgid "Slideshow" msgstr "" #: photofilmstrip/gui/ActionManager.py:110 #: photofilmstrip/gui/PnlTimelapse.py:18 msgid "Timelapse" msgstr "" #: photofilmstrip/gui/ActionManager.py:116 msgid "New" msgstr "" #: photofilmstrip/gui/ActionManager.py:118 msgid "&Open" msgstr "" #: photofilmstrip/gui/ActionManager.py:123 msgid "&Save" msgstr "" #: photofilmstrip/gui/ActionManager.py:136 msgid "&Close" msgstr "&மூடு" #: photofilmstrip/gui/ActionManager.py:141 msgid "E&xit" msgstr "&வெளியேறு" #: photofilmstrip/gui/ActionManager.py:173 msgid "&About" msgstr "&பற்றி" #: photofilmstrip/gui/DlgBugReport.py:41 msgid "An unexpected error occured" msgstr "எதிர்பார்க்காத பிழை ஏற்பட்டுள்ளது" #: photofilmstrip/gui/DlgBugReport.py:44 msgid "" "An unexpected error occured. Do you want to send this bug report to the " "developers of %s?" msgstr "" "எதிர்பார்க்காத பிழை ஏற்பட்டுள்ளது. இப்பிழையின் அறிக்கையை %s இன் உருவாக்குநர்களுக்கு அனுப்ப " "விரும்புகிறீர்களா?" #: photofilmstrip/gui/DlgBugReport.py:99 msgid "Bug-Report send. Thank you for your support." msgstr "வழு அறிக்கை அனுப்பப்பட்டது. உங்கள் ஆதரவுக்கு நன்றி." #: photofilmstrip/gui/DlgBugReport.py:100 photofilmstrip/gui/FrmMain.py:290 msgid "Information" msgstr "தகவல்" #: photofilmstrip/gui/DlgBugReport.py:106 msgid "Sorry, this function is temporary not available.." msgstr "மன்னிக்கவும், இச்செயல்பாட்டை தற்காலிகமாக பயன்படுத்தமுடியாது." #: photofilmstrip/gui/DlgBugReport.py:107 #: photofilmstrip/gui/DlgConfigureAudio.py:232 #: photofilmstrip/gui/DlgConfigureAudio.py:244 #: photofilmstrip/gui/DlgConfigureAudio.py:254 #: photofilmstrip/gui/DlgNewProject.py:156 #: photofilmstrip/gui/DlgNewProject.py:167 #: photofilmstrip/gui/DlgPicDurationByAudio.py:208 #: photofilmstrip/gui/DlgPicDurationByAudio.py:216 #: photofilmstrip/gui/FrmMain.py:376 photofilmstrip/gui/PnlPfsProject.py:468 #: photofilmstrip/gui/PnlTimelapse.py:113 msgid "Error" msgstr "பிழை" #: photofilmstrip/gui/DlgConfigureAudio.py:55 msgid "Configure your audio files that are used as a background music." msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:90 msgid "Set the duration of your slideshow to fit your audio files" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:92 #: photofilmstrip/gui/DlgDuration.py:70 photofilmstrip/gui/DlgNewProject.py:84 #: photofilmstrip/gui/DlgPicDurationByAudio.py:50 #: photofilmstrip/gui/DlgPositionInput.py:238 #: photofilmstrip/gui/DlgRender.py:147 #: photofilmstrip/gui/DlgRendererProps.py:92 #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:97 msgid "&Cancel" msgstr "&இரத்து" #: photofilmstrip/gui/DlgConfigureAudio.py:97 #: photofilmstrip/gui/DlgDuration.py:72 photofilmstrip/gui/DlgNewProject.py:86 #: photofilmstrip/gui/DlgPicDurationByAudio.py:51 #: photofilmstrip/gui/DlgPositionInput.py:244 #: photofilmstrip/gui/DlgRendererProps.py:97 msgid "&Ok" msgstr "&சரி" #: photofilmstrip/gui/DlgConfigureAudio.py:104 #: photofilmstrip/gui/DlgConfigureAudio.py:109 #: photofilmstrip/gui/PnlSlideshow.py:47 photofilmstrip/gui/PnlSlideshow.py:48 #: photofilmstrip/gui/PnlTimelapse.py:33 photofilmstrip/gui/PnlTimelapse.py:34 msgid "Configure music" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:138 msgid "Select music" msgstr "இசையை தேர்ந்தெடு" #: photofilmstrip/gui/DlgConfigureAudio.py:140 msgid "Audio files" msgstr "ஒலி கோப்புகள்" #: photofilmstrip/gui/DlgConfigureAudio.py:243 msgid "Audio file not supported!" msgstr "ஒலிக் கோப்பு ஆதரிக்கப்படவில்லை!" #: photofilmstrip/gui/DlgDuration.py:48 msgid "Total length:" msgstr "மொத்த நீளம்:" #: photofilmstrip/gui/DlgDuration.py:50 msgid "" "Overrides the duration of single pictures and gives the project this total " "length." msgstr "தனிப் படங்களின் நேரங்களை புறக்கணித்து திட்டப்பணிக்கு இந்த மொத்த நீளத்தை கொடுக்கிறது." #: photofilmstrip/gui/DlgDuration.py:54 msgid "User defined:" msgstr "பயனர் வரையறுத்தது:" #: photofilmstrip/gui/DlgDuration.py:65 #, fuzzy msgid "Fit to audio files" msgstr "ஒலி கோப்புகள்" #: photofilmstrip/gui/DlgDuration.py:80 msgid "Slideshow duration" msgstr "" #: photofilmstrip/gui/DlgDuration.py:84 msgid "Configure duration of slideshow" msgstr "" #: photofilmstrip/gui/DlgNewProject.py:61 msgid "Project name:" msgstr "திட்டப்பணியின் பெயர்" #: photofilmstrip/gui/DlgNewProject.py:66 msgid "Folder:" msgstr "அடைவு:" #: photofilmstrip/gui/DlgNewProject.py:78 msgid "Aspect ratio:" msgstr "உருவ விகிதம்:" #: photofilmstrip/gui/DlgNewProject.py:110 #, fuzzy msgid "Unnamed project" msgstr "போடோபில்ம்ஸ்டிரிப்பை ஏற்ற முடியவில்லை" #: photofilmstrip/gui/DlgNewProject.py:116 msgid "My PhotoFilmStrips" msgstr "எனது நிழற்படத்தொடர்கள்" #: photofilmstrip/gui/DlgNewProject.py:126 msgid "Browse for folder" msgstr "அடைவுக்கு உலாவவும்" #: photofilmstrip/gui/DlgNewProject.py:145 msgid "Folder does not exists! Do you want %s to create it?" msgstr "அடைவை காணமுடியவில்லை! அடைவை %s உருவாக்க விரும்புகிறீர்களா?" #: photofilmstrip/gui/DlgNewProject.py:146 #: photofilmstrip/gui/PnlEditorPage.py:29 #: photofilmstrip/gui/PnlEditorPage.py:49 #: photofilmstrip/gui/PnlEditorPage.py:88 #: photofilmstrip/gui/WxProjectFile.py:101 #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:224 msgid "Question" msgstr "வினா" #: photofilmstrip/gui/DlgNewProject.py:155 msgid "Cannot create folder: %s" msgstr "அடைவை உருவாக்க முடியவில்லை: %s" #: photofilmstrip/gui/DlgNewProject.py:166 msgid "Cannot write into folder!" msgstr "அடைவில் எழுத முடியவில்லை!" #: photofilmstrip/gui/DlgNewProject.py:180 msgid "The project name must be filled." msgstr "திட்டப்பணியின் பெயர் நிரப்பப்பட வேண்டும்" #: photofilmstrip/gui/DlgNewProject.py:186 msgid "The project name contains invalid characters." msgstr "திட்டப்பணிப் பெயரில் ஏற்கமுடியாத எழுத்துக்கள் உள்ளன." #: photofilmstrip/gui/DlgPicDurationByAudio.py:23 #: photofilmstrip/gui/PnlSlideshow.py:54 photofilmstrip/gui/PnlSlideshow.py:55 msgid "Adjust picture durations" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:26 msgid "Adjust picture durations to audio file" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:30 msgid "" "Find your picture duration by playing the audio file of your project and\n" "pressing the hit button to apply the current playing time." msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:43 #: photofilmstrip/gui/DlgPicDurationByAudio.py:153 msgid "Play" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:46 msgid "Hit" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:100 msgid "Stop" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:179 #, fuzzy msgid "Playing time" msgstr "நிகழ்படத்தை ஓட்டு" #: photofilmstrip/gui/DlgPicDurationByAudio.py:207 msgid "Your project does not have an audio file configured." msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:215 msgid "" "Your project uses more than one audio file. Currently the durations can be " "adjusted only for one audio file." msgstr "" #: photofilmstrip/gui/DlgPositionInput.py:140 msgid "Motion positions" msgstr "நகர் நிலைகள்" #: photofilmstrip/gui/DlgPositionInput.py:147 msgid "Start position" msgstr "தொடக்க நிலை" #: photofilmstrip/gui/DlgPositionInput.py:155 #: photofilmstrip/gui/DlgPositionInput.py:199 msgid "Location:" msgstr "இருப்பிடம்:" #: photofilmstrip/gui/DlgPositionInput.py:173 #: photofilmstrip/gui/DlgPositionInput.py:215 msgid "Size:" msgstr "அளவு :" #: photofilmstrip/gui/DlgPositionInput.py:191 msgid "End position" msgstr "இறுதி நிலை" #: photofilmstrip/gui/DlgPositionInput.py:233 msgid "Reset" msgstr "மீளமை" #: photofilmstrip/gui/DlgPositionInput.py:252 msgid "Adjust motion positions directly" msgstr "நகர் நிலைகளை நேராக சரிசெய்யவும்" #: photofilmstrip/gui/DlgRender.py:96 #, fuzzy msgid "Render project" msgstr "அண்மைய திட்டப்பணிகள்" #: photofilmstrip/gui/DlgRender.py:107 msgid "Format:" msgstr "வடிவம்:" #: photofilmstrip/gui/DlgRender.py:122 msgid "Properties" msgstr "பண்புகள்" #: photofilmstrip/gui/DlgRender.py:127 msgid "Profile:" msgstr "விவரகுறிப்பு:" #: photofilmstrip/gui/DlgRender.py:136 msgid "Draft" msgstr "வரைவு" #: photofilmstrip/gui/DlgRender.py:152 msgid "&Start" msgstr "&தொடங்கு" #: photofilmstrip/gui/DlgRender.py:164 msgid "Configure output and start render process" msgstr "வெளிப்பாட்டை உருவமைத்து உருவாக்கச் செயலைத் தொடங்கு" #: photofilmstrip/gui/DlgRendererProps.py:50 msgid "Property" msgstr "பண்பு" #: photofilmstrip/gui/DlgRendererProps.py:52 msgid "Value" msgstr "மதிப்பு" #: photofilmstrip/gui/DlgRendererProps.py:71 msgid "Output properties" msgstr "வெளிப்பாட்டு பண்புகள்" #: photofilmstrip/gui/DlgRendererProps.py:113 msgid "Edit extended output properties" msgstr "நீட்டித்த வெளிப்பாட்டு பண்புகளை திருத்து" #: photofilmstrip/gui/DlgRendererProps.py:147 msgid "Edit property" msgstr "பண்பை திருத்து" #: photofilmstrip/gui/FrmMain.py:83 msgid "Welcome" msgstr "நல்வரவு" #: photofilmstrip/gui/FrmMain.py:85 msgid "Job queue" msgstr "" #: photofilmstrip/gui/FrmMain.py:141 msgid "Rendering in progress..." msgstr "" #: photofilmstrip/gui/FrmMain.py:234 photofilmstrip/gui/PnlWelcome.py:57 #, fuzzy msgid "Create new slideshow" msgstr "கையடக்கமான" #: photofilmstrip/gui/FrmMain.py:241 #, fuzzy msgid "Create new timelapse" msgstr "புதிய திட்டப்பணியை உருவாக்கு" #: photofilmstrip/gui/FrmMain.py:249 msgid "Select %s-Project" msgstr "%s-திட்டப்பணியை தேர்ந்தெடு" #: photofilmstrip/gui/FrmMain.py:251 #, fuzzy msgid "Files" msgstr "&கோப்பு" #: photofilmstrip/gui/FrmMain.py:289 msgid "You must restart %s for your new language setting to take effect." msgstr "உங்கள் புதிய மொழி அமைப்பு செயல்பட %s ஐ மறுதுவக்க வேண்டும்." #: photofilmstrip/gui/FrmMain.py:300 msgid "" "PhotoFilmStrip creates movies out of your pictures in just 3 steps. First " "select your photos, customize the motion path and render the video. There " "are several output possibilities for VCD, SVCD, DVD up to FULL-HD." msgstr "" "நிழற்படத்தொடர் உங்கள் படங்களிலிருந்து மூன்றே செய்படிகளில் நிகழ்படங்களை உருவாக்குகிறது. " "முதலில் படங்களை தேர்வுசெய்யவும். பிறகு நகர்ச்சிகளை தக்கபடி மாற்றிக்கொண்டு நிகழ்படத்தை " "உருவாக்கவும். விசிடி, எஸ்விசிடி, டிவிடி என்று முழு எச்டி வரை பல வெளிப்பாட்டு உள்ளன." #: photofilmstrip/gui/FrmMain.py:303 msgid "online" msgstr "இணைப்பில்" #: photofilmstrip/gui/FrmMain.py:374 msgid "Invalid %(app)s-Project: %(file)s" msgstr "பிழையுற்ற %(app)s-திட்டப்பணி: %(file)s" #: photofilmstrip/gui/PnlAddPics.py:50 photofilmstrip/gui/PnlWelcome.py:30 msgid "Welcome to PhotoFilmStrip" msgstr "நிழற்படத்தொடருக்கு நல்வரவு" #: photofilmstrip/gui/PnlAddPics.py:52 msgid "" "Drag some pictures onto this text or\n" "click the button below\n" "to add pictures to your new PhotoFilmStrip." msgstr "" "இவ்வுரைக்கு சில படங்களை இழுக்கவும் அல்லது \n" "கீழேயுள்ள விசையை அழுத்தி உங்கள் புதிய நிழற்படதொடரில் படங்களை சேர்க்கவும்." #: photofilmstrip/gui/PnlEditPicture.py:142 msgid "Settings" msgstr "அமைப்புகள்" #: photofilmstrip/gui/PnlEditPicture.py:146 msgid "Rotation:" msgstr "சுழற்சி:" #: photofilmstrip/gui/PnlEditPicture.py:166 msgid "Effect:" msgstr "விளைவு:" #: photofilmstrip/gui/PnlEditPicture.py:180 msgid "Process" msgstr "செயல்பாடு" #: photofilmstrip/gui/PnlEditPicture.py:184 msgid "Movement:" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:196 #: photofilmstrip/gui/PnlEditPicture.py:212 #: photofilmstrip/gui/PnlEditPicture.py:359 msgid "sec" msgstr "நொடி" #: photofilmstrip/gui/PnlEditPicture.py:200 msgid "Transition:" msgstr "சீர்மாற்றம்:" #: photofilmstrip/gui/PnlEditPicture.py:220 msgid "Subtitle" msgstr "துணை உரை" #: photofilmstrip/gui/PnlEditPicture.py:240 msgid "Linear" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:241 msgid "Accelerated" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:242 msgid "Delayed" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:250 msgid "No effect" msgstr "எந்த விளைவுமில்லை" #: photofilmstrip/gui/PnlEditPicture.py:251 msgid "Black and White" msgstr "கருப்பு வெள்ளை" #: photofilmstrip/gui/PnlEditPicture.py:252 msgid "Sepia tone" msgstr "பழுப்பு கலப்பு" #: photofilmstrip/gui/PnlEditPicture.py:258 msgid "None" msgstr "எதுவுமில்லை" #: photofilmstrip/gui/PnlEditPicture.py:259 msgid "Fade" msgstr "மங்கு" #: photofilmstrip/gui/PnlEditPicture.py:260 msgid "Roll" msgstr "உருட்டு" #: photofilmstrip/gui/PnlEditPicture.py:354 msgid "fpp" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:355 msgid "frames per picture - the number of frames each picture will be shown" msgstr "" #: photofilmstrip/gui/PnlEditorPage.py:26 msgid "Could not save the file '%(file)s': %(errMsg)s" msgstr "கோப்பு '%(file)s' ஐ சேமிக்க முடியவில்லை: %(errMsg)s" #: photofilmstrip/gui/PnlEditorPage.py:45 msgid "New file" msgstr "" #: photofilmstrip/gui/PnlEditorPage.py:48 msgid "'%s' has been modified. Save changes?" msgstr "'%s' மாற்றப்பட்டுள்ளது. மாற்றங்களை சேமிக்க வேண்டுமா?" #: photofilmstrip/gui/PnlEditorPage.py:74 #, fuzzy msgid "Save %s" msgstr "%s-திட்டப்பணியை சேமி" #: photofilmstrip/gui/PnlEditorPage.py:77 #, fuzzy msgid "File" msgstr "&கோப்பு" #: photofilmstrip/gui/PnlEditorPage.py:87 msgid "Overwrite existing file '%s'?" msgstr "ஏற்கனவே உள்ள '%s' கோப்பை மேலெழுத வேண்டுமா?" #: photofilmstrip/gui/PnlPfsProject.py:118 #: photofilmstrip/gui/PnlPfsProject.py:120 msgid "Set motion start to end" msgstr "நகர்ச்சி தொடக்கத்தை முடிவாக அமை" #: photofilmstrip/gui/PnlPfsProject.py:122 #: photofilmstrip/gui/PnlPfsProject.py:124 msgid "Set motion end to start" msgstr "நகர்ச்சி முடிவை தொடக்கமாக அமை" #: photofilmstrip/gui/PnlPfsProject.py:126 #: photofilmstrip/gui/PnlPfsProject.py:128 #, fuzzy msgid "Swap motion" msgstr "சீரற்ற நகர்ச்சி" #: photofilmstrip/gui/PnlPfsProject.py:131 #: photofilmstrip/gui/PnlPfsProject.py:133 msgid "Adjust motion manual" msgstr "நகர்ச்சியை கைமுறையாக சரிசெய்" #: photofilmstrip/gui/PnlPfsProject.py:136 #: photofilmstrip/gui/PnlPfsProject.py:138 msgid "Preserve image dimension" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:294 msgid "&Import Pictures" msgstr "&படங்களை இறக்குமதி செய்" #: photofilmstrip/gui/PnlPfsProject.py:299 msgid "Move picture &left" msgstr "படத்தை &இடதுபுறமாக நகர்த்து" #: photofilmstrip/gui/PnlPfsProject.py:303 msgid "Move picture &right" msgstr "படத்தை வ&லதுபுறமாக நகர்த்து" #: photofilmstrip/gui/PnlPfsProject.py:308 #, fuzzy msgid "R&emove Picture" msgstr "படத்தை &நீக்கு" #: photofilmstrip/gui/PnlPfsProject.py:313 msgid "Rotate &clockwise" msgstr "வல&ஞ்சுழியாக சுழற்று" #: photofilmstrip/gui/PnlPfsProject.py:317 msgid "Rotate counter clock&wise" msgstr "இ&டஞ்சுழியாக சுழற்று" #: photofilmstrip/gui/PnlPfsProject.py:322 #, fuzzy msgid "Random &motion" msgstr "சீரற்ற நகர்ச்சி" #: photofilmstrip/gui/PnlPfsProject.py:326 msgid "Centralize m&otion" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:384 msgid "Export slideshow" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:387 #: photofilmstrip/gui/PnlPfsProject.py:400 #, fuzzy msgid "Portable slideshow" msgstr "கையடக்கமான" #: photofilmstrip/gui/PnlPfsProject.py:398 #, fuzzy msgid "Import Slideshow" msgstr "படங்களை இறக்குமதி செய்" #: photofilmstrip/gui/PnlPfsProject.py:409 msgid "Import images" msgstr "படங்களை இறக்குமதி செய்" #: photofilmstrip/gui/PnlPfsProject.py:411 #, fuzzy msgid "Image files" msgstr "படக்கோப்புகள்" #: photofilmstrip/gui/PnlPfsProject.py:654 msgid "Audio file '%s' does not exist! Continue anyway?" msgstr "ஒலிக் கோப்பு '%s' காணப்படவில்லை! எப்படியும் தொடர வேண்டுமா?" #: photofilmstrip/gui/PnlPfsProject.py:655 msgid "Warning" msgstr "எச்சரிக்கை" #: photofilmstrip/gui/PnlSlideshow.py:30 msgid "&Properties" msgstr "&பண்புகள்" #: photofilmstrip/gui/PnlSlideshow.py:39 photofilmstrip/gui/PnlSlideshow.py:40 #: photofilmstrip/gui/PnlTimelapse.py:25 photofilmstrip/gui/PnlTimelapse.py:26 msgid "Import Pictures" msgstr "படங்களை இறக்குமதி செய்" #: photofilmstrip/gui/PnlSlideshow.py:62 photofilmstrip/gui/PnlSlideshow.py:63 #: photofilmstrip/gui/PnlTimelapse.py:41 photofilmstrip/gui/PnlTimelapse.py:42 msgid "Render filmstrip" msgstr "படத்தொடரை காட்டு" #: photofilmstrip/gui/PnlSlideshow.py:89 photofilmstrip/gui/PnlTimelapse.py:66 msgid "Images" msgstr "படங்கள்" #: photofilmstrip/gui/PnlSlideshow.py:94 msgid "Duration" msgstr "நேர அளவு" #: photofilmstrip/gui/PnlTimelapse.py:69 msgid "Frames" msgstr "" #: photofilmstrip/gui/PnlTimelapse.py:92 msgid "The picture counter is not increasing: %s" msgstr "" #: photofilmstrip/gui/PnlTimelapse.py:110 msgid "" "Filename '%s' does not match a number pattern which is necessary for a time " "lapse slide show!" msgstr "" #: photofilmstrip/gui/PnlWelcome.py:37 photofilmstrip/gui/PnlWelcome.py:103 msgid "Recent projects" msgstr "அண்மைய திட்டப்பணிகள்" #: photofilmstrip/gui/PnlWelcome.py:62 msgid "Open existing project" msgstr "இருக்கும் திட்டப்பணியை திற" #: photofilmstrip/gui/PnlWelcome.py:106 msgid "How to start..." msgstr "தொடங்குவது எப்படி..." #: photofilmstrip/gui/PnlWelcome.py:107 msgid "Create a new project or load an existing one." msgstr "புதிய திட்டப்பணியை உருவாக்கு அல்லது இருக்கும் ஒன்றை ஏற்று." #: photofilmstrip/gui/PnlWelcome.py:138 msgid "Update available" msgstr "மேம்பாடு இருக்கிறது" #: photofilmstrip/gui/PnlWelcome.py:141 msgid "The following changes has been made:" msgstr "பின்வரும் மாற்றங்கள் செய்யப்பட்டுள்ளன:" #: photofilmstrip/gui/WxProjectFile.py:59 #, fuzzy msgid "Loading project %s" msgstr "திட்டப்பணியை ஏற்று" #: photofilmstrip/gui/WxProjectFile.py:75 #, fuzzy msgid "Saving project %s" msgstr "திட்டப்பணியை சேமி" #: photofilmstrip/gui/WxProjectFile.py:100 msgid "" "Some images does not exist in the folder '%s' anymore. If the files has " "moved you can select the new path. Do you want to select a new path?" msgstr "" "சில படங்கள் '%s' அடைவில் இனியும் காணப்படவில்லை. படங்கள் நகர்த்தப்பட்டிருந்தால் புதிய " "இருப்பிடத்தை தேர்ந்தெடுக்கவும். புதிய அடைவின் பாதையை தேரந்தெடுக்க விரும்புகிறீர்களா?" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:73 msgid "Elapsed time" msgstr "" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:85 msgid "Remaining time" msgstr "" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:203 msgid "Unknown" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobManager.py:50 msgid "&Clear list" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:127 msgid "Abort" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:133 msgid "Remove from list" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:223 #, fuzzy msgid "Abort selected process?" msgstr "தற்போதைய செயலை நிறுத்த வேண்டுமா?" #: photofilmstrip/lib/jobimpl/VisualJob.py:29 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:25 #, fuzzy msgid "Waiting..." msgstr "நிறுத்துகிறது..." #: photofilmstrip/lib/jobimpl/VisualJob.py:68 #: photofilmstrip/lib/jobimpl/VisualJob.py:85 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:60 msgid "Aborted" msgstr "நிறுத்தப்பட்டது" #: photofilmstrip/lib/jobimpl/VisualJob.py:70 msgid "Done" msgstr "" #: photofilmstrip/lib/jobimpl/VisualJob.py:79 msgid "Aborting..." msgstr "நிறுத்துகிறது..." #: photofilmstrip/uwp/UwpService.py:76 msgid "Slideshow created!" msgstr "" #, fuzzy #~ msgid "Audio files:" #~ msgstr "ஒலி கோப்புகள்" #~ msgid "Project properties" #~ msgstr "திட்டப்பணியின் பண்புகள்" #~ msgid "PhotoFilmStrip project" #~ msgstr "நிழற்படத்தொடர் திட்டப்பணி" #~ msgid "Unnamed PhotoFilmStrip" #~ msgstr "பெயரளிக்கப்படாத நிழற்படத்தொடர்" #~ msgid "Project" #~ msgstr "திட்டப்பணி" #~ msgid "invalid videonorm specified: %s" #~ msgstr "தவறான நிகழ்பட வடிவம் குறிப்பிடப்பட்டுள்ளது: %s" #~ msgid "Please wait..." #~ msgstr "தயவு செய்து காத்திருக்கவும்..." #~ msgid "aborting..." #~ msgstr "நிறுத்துகிறது..." #~ msgid "mencoder (mencoder) required!" #~ msgstr "மென்கோடர் (mencoder) தேவை!" #~ msgid "MPEG(1/2)-Video (MPG)" #~ msgstr "எம்.பி.இ.ஜி (1/2)-நிகழ்படம் (MPG)" #~ msgid "MPEG format supports only VCD, SVCD and DVD profile!" #~ msgstr "" #~ "எம்.பி.இ.ஜி வடிவம் விசிடி, சூப்பர் விசிடி, டிவிடி தன்விவரங்களை மட்டுமே ஆதரிக்கும்" #~ msgid "MPEG4-XVid/AC3 (AVI)" #~ msgstr "எம்.பி.இ.ஜி 4-XVid/AC3 (AVI)" #~ msgid "mencoder with MP3 support (mp3lame) required!" #~ msgstr "MP3 ஆதரவுள்ள மென்கோடர் (mp3lame) தேவை!" #~ msgid "MPEG4-XVid/MP3 (AVI)" #~ msgstr "எம்.பி.இ.ஜி 4-XVid/MP3 (AVI)" #~ msgid "Flash-Video (FLV)" #~ msgstr "பிளாஷ்-நிகழ்படம் (FLV)" #~ msgid "Motion-JPEG (AVI)" #~ msgstr "நகர்-JPEG (AVI)" #~ msgid "&Tools" #~ msgstr "&கருவிகள்" #~ msgid "New Project" #~ msgstr "புதிய திட்டப்பணி" #~ msgid "Load Project" #~ msgstr "திட்டப்பணியை ஏற்று" #~ msgid "Save Project" #~ msgstr "திட்டப்பணியை சேமி" #~ msgid "&New Project" #~ msgstr "&புதிய திட்டப்பணி" #~ msgid "&Open Project" #~ msgstr "திட்டப்பணியை &திற" #~ msgid "&Save Project" #~ msgstr "திட்டப்பணியை &சேமி" #~ msgid "&Close Project" #~ msgstr "திட்டப்பணியை &மூடு" #~ msgid "&Render filmstrip" #~ msgstr "படத்தொடரை &உருவாக்கு" #~ msgid "Audio file:" #~ msgstr "ஒலிக் கோப்பு:" #~ msgid "Type:" #~ msgstr "வகை:" #~ msgid "Export %s-Project" #~ msgstr "%s-திட்டப்பணியை ஏற்றுமதி செய்" #~ msgid "Import %s-Project" #~ msgstr "%s-திட்டப்பணியை இறக்குமதி செய்" #~ msgid "Duration:" #~ msgstr "கால அளவு:" #~ msgid "Error: %s" #~ msgstr "பிழை: %s" #~ msgid "initialize renderer" #~ msgstr "நிகழ்பட வழங்கியை தொடங்கு" #~ msgid "creating output..." #~ msgstr "வெளிப்பாடு உருவாக்கப்படுகிறது..." #~ msgid "Finalizing" #~ msgstr "இறுதிப்படுத்துகிறது" #~ msgid "Choose your next action:" #~ msgstr "உங்கள் அடுத்த நடவடிக்கையை தேர்ந்தெடுக்கவும்:" #~ msgid "Delete unfinished result" #~ msgstr "முழுமையாகாத முடிவை அழிக்கவும்" #~ msgid "Do nothing" #~ msgstr "எதுவும் செய்யாதே" #~ msgid "Show error again and send to developer." #~ msgstr "பிழையை மீண்டும் காட்டி உருவாக்குநருக்கு அனுப்பு" #~ msgid "The rendering process was aborted." #~ msgstr "படத்தொடரை உருவாக்கும் செயல் நிறுத்தப்பட்டது" #~ msgid "The rendering process was interrupted." #~ msgstr "படத்தொடரை உருவாக்கும் செயல் தடைபட்டது" #~ msgid "The rendering process has been finished." #~ msgstr "படத்தொடரை உருவாக்கும் செயல் முடிவுற்றது." #~ msgid "&Batch Job" #~ msgstr "&தொகுதிச் செயல்" #~ msgid "" #~ "Project not saved yet. Please save the project first to create a batch " #~ "job!" #~ msgstr "" #~ "திட்டப்பணி இன்னும் சேமிக்கப்படவில்லை. தொகுதிச் செயலை உருவாக்க திட்டப்பணியை முதலில் " #~ "சேமிக்கவும்!" #~ msgid "Batch file" #~ msgstr "தொகுதிக் கோப்பு" #~ msgid "Shell script" #~ msgstr "ஷெல் குறுநிரல்" #~ msgid "Select batch file" #~ msgstr "தொகுதிக் கோப்பை தேர்ந்தெடு" #~ msgid "Browse" #~ msgstr "உலாவு" #~ msgid "Import image" #~ msgstr "படத்தை இறக்குமதி செய்" #~ msgid "Please wait" #~ msgstr "தயவுசெய்து காத்திருக்கவும்" #~ msgid "Loading pictures..." #~ msgstr "படங்கள் ஏற்றப்படுகின்றன..." photofilmstrip-3.7.2/po/uk.po0000644000232200023220000010057313560357351016567 0ustar debalancedebalance# Ukrainian translation for photofilmstrip # Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 # This file is distributed under the same license as the photofilmstrip package. # FIRST AUTHOR , 2012. # msgid "" msgstr "" "Project-Id-Version: photofilmstrip\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2018-11-07 22:03+CET\n" "PO-Revision-Date: 2012-12-05 23:20+0100\n" "Last-Translator: Jens Göpfert \n" "Language-Team: Ukrainian \n" "Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2012-12-05 22:16+0000\n" "X-Generator: Launchpad (build 16341)\n" "X-Poedit-Country: UKRAINE\n" "X-Poedit-Language: Ukrainian\n" #: photofilmstrip/action/ActionAutoPath.py:23 #: photofilmstrip/gui/PnlPfsProject.py:115 msgid "Random motion" msgstr "Випадковий рух" #: photofilmstrip/action/ActionCenterPath.py:21 msgid "Centralize motion" msgstr "" #: photofilmstrip/action/ActionI18N.py:24 #: photofilmstrip/gui/ActionManager.py:170 msgid "Language" msgstr "Мова" #: photofilmstrip/action/ActionOpenFolder.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:28 msgid "Open folder" msgstr "Відкрити теку" #: photofilmstrip/action/ActionPlayVideo.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:22 msgid "Play video" msgstr "Відтворити відео" #: photofilmstrip/action/ActionRender.py:37 #, fuzzy msgid "Start" msgstr "&Почати" #: photofilmstrip/cli/Main.py:46 photofilmstrip/cli/Main.py:196 msgid "all done" msgstr "завершено" #: photofilmstrip/cli/Main.py:64 msgid "processing project" msgstr "обробка проекту" #: photofilmstrip/cli/Main.py:65 msgid "using renderer" msgstr "з використанням обробника" #: photofilmstrip/cli/Main.py:66 msgid "output format" msgstr "формат виводу" #: photofilmstrip/cli/Main.py:69 msgid "framerate" msgstr "частота кадрів" #: photofilmstrip/cli/Main.py:103 msgid "specifies the project file" msgstr "вказує файл проекту" #: photofilmstrip/cli/Main.py:104 msgid "The path where to save the output files. Use - for stdout." msgstr "Шлях для збереження вихідних файлів. Використайте - для stdout." #: photofilmstrip/cli/Main.py:106 photofilmstrip/cli/Main.py:129 msgid "Option videonorm is deprecated, use an appropriate profile!" msgstr "" #: photofilmstrip/cli/Main.py:108 msgid "enable draft mode" msgstr "увімкнути чернетковий режим" #: photofilmstrip/cli/Main.py:108 photofilmstrip/gui/DlgRender.py:167 msgid "" "Activate this option to generate a preview of your PhotoFilmStrip. The " "rendering process will speed up dramatically, but results in lower quality." msgstr "" "Виберіть цей параметр, щоб створити попередній перегляд фільму. Обробка " "значно прискориться, але знизиться якість." #: photofilmstrip/cli/Main.py:120 msgid "project file does not exist: %s" msgstr "файла проекту %s не існує." #: photofilmstrip/cli/Main.py:124 msgid "no project file specified!" msgstr "не вказаний файл проекту!" #: photofilmstrip/cli/Main.py:134 msgid "invalid format specified: %s" msgstr "вказано неправильний формат: %s" #: photofilmstrip/cli/Main.py:140 msgid "invalid profile specified: %s" msgstr "вказано неправильний профіль: %s" #: photofilmstrip/cli/Main.py:146 #, fuzzy msgid "cannot load project" msgstr "неможливо завантажити програму" #: photofilmstrip/cli/Main.py:159 msgid "cannot create output path: %s" msgstr "неможливо створити вихідний шлях %s" #: photofilmstrip/cli/Main.py:169 photofilmstrip/gui/DlgConfigureAudio.py:231 #: photofilmstrip/gui/DlgConfigureAudio.py:253 msgid "Audio file '%s' does not exist!" msgstr "Звукового файла '%s' не існує!" #: photofilmstrip/cli/Main.py:190 msgid "...aborted!" msgstr "...припинено!" #: photofilmstrip/core/BaseRenderer.py:50 msgid "Unknown property: %s" msgstr "Невідома властивість: %s" #: photofilmstrip/core/BaseRenderer.py:58 msgid "" msgstr "<типово>" #: photofilmstrip/core/BaseRenderer.py:73 msgid "no" msgstr "ні" #: photofilmstrip/core/ProjectFile.py:222 #, fuzzy msgid "Saving '%s' ..." msgstr "Завантаження '%s' ..." #: photofilmstrip/core/ProjectFile.py:276 msgid "Loading '%s' ..." msgstr "Завантаження '%s' ..." #: photofilmstrip/core/RenderEngine.py:113 #: photofilmstrip/core/RenderEngine.py:201 msgid "processing transition %d/%d" msgstr "обробка переміщення %d/%d" #: photofilmstrip/core/RenderEngine.py:124 #: photofilmstrip/core/RenderEngine.py:210 msgid "processing image %d/%d" msgstr "обробка зображення %d/%d" #: photofilmstrip/core/renderer/CairoRenderer.py:35 msgid "Preview" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:50 msgid "GStreamer (python-gst-1.0) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:287 msgid "Bitrate must be a number!" msgstr "Швидкість потоку має бути числом!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:455 #: photofilmstrip/core/renderer/GStreamerRenderer.py:531 #: photofilmstrip/core/renderer/GStreamerRenderer.py:601 #: photofilmstrip/core/renderer/GStreamerRenderer.py:690 #: photofilmstrip/core/renderer/GStreamerRenderer.py:730 #: photofilmstrip/core/renderer/GStreamerRenderer.py:779 msgid "libav (gstreamer1.0-libav) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:459 #: photofilmstrip/core/renderer/GStreamerRenderer.py:535 #: photofilmstrip/core/renderer/GStreamerRenderer.py:605 msgid "x264-Codec (gstreamer1.0-plugins-ugly) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:463 #: photofilmstrip/core/renderer/GStreamerRenderer.py:609 msgid "MKV-Muxer (gstreamer1.0-plugins-good) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:539 msgid "MP4-Muxer (gstreamer1.0-plugins-good) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:647 msgid "Theora-Codec (gstreamer1.0-plugins-base) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:651 msgid "Vorbis-Codec (gstreamer1.0-plugins-base) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:655 msgid "OGV-Muxer (gstreamer1.0-plugins-base) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:686 #: photofilmstrip/core/renderer/GStreamerRenderer.py:726 #: photofilmstrip/core/renderer/GStreamerRenderer.py:775 msgid "MPEG-1/2-Codec (gstreamer1.0-plugins-bad) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:694 #: photofilmstrip/core/renderer/GStreamerRenderer.py:734 #: photofilmstrip/core/renderer/GStreamerRenderer.py:783 msgid "MPEG-Muxer (gstreamer1.0-plugins-bad) required!" msgstr "" #: photofilmstrip/core/renderer/SingleFileRenderer.py:21 msgid "Single pictures" msgstr "Окремі зображення" #: photofilmstrip/core/tasks.py:48 msgid "generating subtitle" msgstr "створення субтитрів" #: photofilmstrip/gui/ActionManager.py:60 #: photofilmstrip/gui/ActionManager.py:190 msgid "&File" msgstr "&Файл" #: photofilmstrip/gui/ActionManager.py:61 #: photofilmstrip/gui/ActionManager.py:191 msgid "&Edit" msgstr "З&міни" #: photofilmstrip/gui/ActionManager.py:62 #: photofilmstrip/gui/ActionManager.py:154 photofilmstrip/gui/DlgRender.py:141 #: photofilmstrip/gui/DlgRendererProps.py:86 msgid "&Help" msgstr "До&помога" #: photofilmstrip/gui/ActionManager.py:76 msgid "New Slideshow" msgstr "" #: photofilmstrip/gui/ActionManager.py:81 msgid "Open" msgstr "" #: photofilmstrip/gui/ActionManager.py:87 msgid "Save" msgstr "" #: photofilmstrip/gui/ActionManager.py:97 #: photofilmstrip/gui/ActionManager.py:98 msgid "Show job queue" msgstr "" #: photofilmstrip/gui/ActionManager.py:108 #: photofilmstrip/gui/PnlSlideshow.py:25 msgid "Slideshow" msgstr "" #: photofilmstrip/gui/ActionManager.py:110 #: photofilmstrip/gui/PnlTimelapse.py:18 msgid "Timelapse" msgstr "" #: photofilmstrip/gui/ActionManager.py:116 msgid "New" msgstr "" #: photofilmstrip/gui/ActionManager.py:118 msgid "&Open" msgstr "" #: photofilmstrip/gui/ActionManager.py:123 msgid "&Save" msgstr "" #: photofilmstrip/gui/ActionManager.py:136 msgid "&Close" msgstr "&Закрити" #: photofilmstrip/gui/ActionManager.py:141 msgid "E&xit" msgstr "В&ихід" #: photofilmstrip/gui/ActionManager.py:173 msgid "&About" msgstr "&Про..." #: photofilmstrip/gui/DlgBugReport.py:41 msgid "An unexpected error occured" msgstr "Виникла несподівана помилка" #: photofilmstrip/gui/DlgBugReport.py:44 msgid "" "An unexpected error occured. Do you want to send this bug report to the " "developers of %s?" msgstr "" "Трапилась помилка. Чи бажаєте ви надіслати звіт про помилку розробникам %s?" #: photofilmstrip/gui/DlgBugReport.py:99 msgid "Bug-Report send. Thank you for your support." msgstr "Повідомлення про помилку надіслане. Дякуємо за підтримку." #: photofilmstrip/gui/DlgBugReport.py:100 photofilmstrip/gui/FrmMain.py:290 msgid "Information" msgstr "Інформація" #: photofilmstrip/gui/DlgBugReport.py:106 msgid "Sorry, this function is temporary not available.." msgstr "Вибачте, ця функція тимчасово недоступна." #: photofilmstrip/gui/DlgBugReport.py:107 #: photofilmstrip/gui/DlgConfigureAudio.py:232 #: photofilmstrip/gui/DlgConfigureAudio.py:244 #: photofilmstrip/gui/DlgConfigureAudio.py:254 #: photofilmstrip/gui/DlgNewProject.py:156 #: photofilmstrip/gui/DlgNewProject.py:167 #: photofilmstrip/gui/DlgPicDurationByAudio.py:208 #: photofilmstrip/gui/DlgPicDurationByAudio.py:216 #: photofilmstrip/gui/FrmMain.py:376 photofilmstrip/gui/PnlPfsProject.py:468 #: photofilmstrip/gui/PnlTimelapse.py:113 msgid "Error" msgstr "Помилка" #: photofilmstrip/gui/DlgConfigureAudio.py:55 msgid "Configure your audio files that are used as a background music." msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:90 msgid "Set the duration of your slideshow to fit your audio files" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:92 #: photofilmstrip/gui/DlgDuration.py:70 photofilmstrip/gui/DlgNewProject.py:84 #: photofilmstrip/gui/DlgPicDurationByAudio.py:50 #: photofilmstrip/gui/DlgPositionInput.py:238 #: photofilmstrip/gui/DlgRender.py:147 #: photofilmstrip/gui/DlgRendererProps.py:92 #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:97 msgid "&Cancel" msgstr "&Скасувати" #: photofilmstrip/gui/DlgConfigureAudio.py:97 #: photofilmstrip/gui/DlgDuration.py:72 photofilmstrip/gui/DlgNewProject.py:86 #: photofilmstrip/gui/DlgPicDurationByAudio.py:51 #: photofilmstrip/gui/DlgPositionInput.py:244 #: photofilmstrip/gui/DlgRendererProps.py:97 msgid "&Ok" msgstr "&Гаразд" #: photofilmstrip/gui/DlgConfigureAudio.py:104 #: photofilmstrip/gui/DlgConfigureAudio.py:109 #: photofilmstrip/gui/PnlSlideshow.py:47 photofilmstrip/gui/PnlSlideshow.py:48 #: photofilmstrip/gui/PnlTimelapse.py:33 photofilmstrip/gui/PnlTimelapse.py:34 msgid "Configure music" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:138 msgid "Select music" msgstr "Вибрати музику" #: photofilmstrip/gui/DlgConfigureAudio.py:140 msgid "Audio files" msgstr "Звукові файли" #: photofilmstrip/gui/DlgConfigureAudio.py:243 msgid "Audio file not supported!" msgstr "Звуковий файл не підтримується!" #: photofilmstrip/gui/DlgDuration.py:48 msgid "Total length:" msgstr "Загальна тривалість:" #: photofilmstrip/gui/DlgDuration.py:50 msgid "" "Overrides the duration of single pictures and gives the project this total " "length." msgstr "" "Скасовує значення тривалості окремих зображень і задає загальну тривалість " "проекту." #: photofilmstrip/gui/DlgDuration.py:54 msgid "User defined:" msgstr "Вказати:" #: photofilmstrip/gui/DlgDuration.py:65 #, fuzzy msgid "Fit to audio files" msgstr "Звукові файли" #: photofilmstrip/gui/DlgDuration.py:80 msgid "Slideshow duration" msgstr "" #: photofilmstrip/gui/DlgDuration.py:84 msgid "Configure duration of slideshow" msgstr "" #: photofilmstrip/gui/DlgNewProject.py:61 msgid "Project name:" msgstr "Назва проекту:" #: photofilmstrip/gui/DlgNewProject.py:66 msgid "Folder:" msgstr "Тека:" #: photofilmstrip/gui/DlgNewProject.py:78 msgid "Aspect ratio:" msgstr "Співвідношення розмірів:" #: photofilmstrip/gui/DlgNewProject.py:110 #, fuzzy msgid "Unnamed project" msgstr "неможливо завантажити програму" #: photofilmstrip/gui/DlgNewProject.py:116 msgid "My PhotoFilmStrips" msgstr "Мої фільми" #: photofilmstrip/gui/DlgNewProject.py:126 msgid "Browse for folder" msgstr "Вибрати теку" #: photofilmstrip/gui/DlgNewProject.py:145 msgid "Folder does not exists! Do you want %s to create it?" msgstr "Тека не існує! Чи бажаєте, щоб %s створив її?" #: photofilmstrip/gui/DlgNewProject.py:146 #: photofilmstrip/gui/PnlEditorPage.py:29 #: photofilmstrip/gui/PnlEditorPage.py:49 #: photofilmstrip/gui/PnlEditorPage.py:88 #: photofilmstrip/gui/WxProjectFile.py:101 #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:224 msgid "Question" msgstr "Запитання" #: photofilmstrip/gui/DlgNewProject.py:155 msgid "Cannot create folder: %s" msgstr "Не вдається створити теку: %s" #: photofilmstrip/gui/DlgNewProject.py:166 msgid "Cannot write into folder!" msgstr "Не вдається записати до теки!" #: photofilmstrip/gui/DlgNewProject.py:180 msgid "The project name must be filled." msgstr "Слід вказати назву проекту." #: photofilmstrip/gui/DlgNewProject.py:186 msgid "The project name contains invalid characters." msgstr "Назва проекту містить недопустимі символи." #: photofilmstrip/gui/DlgPicDurationByAudio.py:23 #: photofilmstrip/gui/PnlSlideshow.py:54 photofilmstrip/gui/PnlSlideshow.py:55 msgid "Adjust picture durations" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:26 msgid "Adjust picture durations to audio file" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:30 msgid "" "Find your picture duration by playing the audio file of your project and\n" "pressing the hit button to apply the current playing time." msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:43 #: photofilmstrip/gui/DlgPicDurationByAudio.py:153 msgid "Play" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:46 msgid "Hit" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:100 msgid "Stop" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:179 #, fuzzy msgid "Playing time" msgstr "Відтворити відео" #: photofilmstrip/gui/DlgPicDurationByAudio.py:207 msgid "Your project does not have an audio file configured." msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:215 msgid "" "Your project uses more than one audio file. Currently the durations can be " "adjusted only for one audio file." msgstr "" #: photofilmstrip/gui/DlgPositionInput.py:140 msgid "Motion positions" msgstr "Позиції руху" #: photofilmstrip/gui/DlgPositionInput.py:147 msgid "Start position" msgstr "Початок" #: photofilmstrip/gui/DlgPositionInput.py:155 #: photofilmstrip/gui/DlgPositionInput.py:199 msgid "Location:" msgstr "Розташування:" #: photofilmstrip/gui/DlgPositionInput.py:173 #: photofilmstrip/gui/DlgPositionInput.py:215 msgid "Size:" msgstr "Розмір:" #: photofilmstrip/gui/DlgPositionInput.py:191 msgid "End position" msgstr "Кінець" #: photofilmstrip/gui/DlgPositionInput.py:233 msgid "Reset" msgstr "Скинути" #: photofilmstrip/gui/DlgPositionInput.py:252 msgid "Adjust motion positions directly" msgstr "Налаштуйте рух безпосередньо" #: photofilmstrip/gui/DlgRender.py:96 #, fuzzy msgid "Render project" msgstr "Останні проекти" #: photofilmstrip/gui/DlgRender.py:107 msgid "Format:" msgstr "Формат:" #: photofilmstrip/gui/DlgRender.py:122 msgid "Properties" msgstr "Параметри" #: photofilmstrip/gui/DlgRender.py:127 msgid "Profile:" msgstr "Профіль:" #: photofilmstrip/gui/DlgRender.py:136 msgid "Draft" msgstr "Чернетка" #: photofilmstrip/gui/DlgRender.py:152 msgid "&Start" msgstr "&Почати" #: photofilmstrip/gui/DlgRender.py:164 msgid "Configure output and start render process" msgstr "Налаштувати вихід і розпочати обробку" #: photofilmstrip/gui/DlgRendererProps.py:50 msgid "Property" msgstr "Параметр" #: photofilmstrip/gui/DlgRendererProps.py:52 msgid "Value" msgstr "Значення" #: photofilmstrip/gui/DlgRendererProps.py:71 msgid "Output properties" msgstr "Параметри виведення" #: photofilmstrip/gui/DlgRendererProps.py:113 msgid "Edit extended output properties" msgstr "Змінити розширені параметри виведення" #: photofilmstrip/gui/DlgRendererProps.py:147 msgid "Edit property" msgstr "Змінити параметр" #: photofilmstrip/gui/FrmMain.py:83 msgid "Welcome" msgstr "Вітаємо!" #: photofilmstrip/gui/FrmMain.py:85 msgid "Job queue" msgstr "" #: photofilmstrip/gui/FrmMain.py:141 msgid "Rendering in progress..." msgstr "" #: photofilmstrip/gui/FrmMain.py:234 photofilmstrip/gui/PnlWelcome.py:57 #, fuzzy msgid "Create new slideshow" msgstr "Портабельний" #: photofilmstrip/gui/FrmMain.py:241 #, fuzzy msgid "Create new timelapse" msgstr "Створити новий проект" #: photofilmstrip/gui/FrmMain.py:249 msgid "Select %s-Project" msgstr "Вибрати проект %s" #: photofilmstrip/gui/FrmMain.py:251 #, fuzzy msgid "Files" msgstr "&Файл" #: photofilmstrip/gui/FrmMain.py:289 msgid "You must restart %s for your new language setting to take effect." msgstr "Потрібно перезапустити %s щоб активувати нові мовні параметри." #: photofilmstrip/gui/FrmMain.py:300 msgid "" "PhotoFilmStrip creates movies out of your pictures in just 3 steps. First " "select your photos, customize the motion path and render the video. There " "are several output possibilities for VCD, SVCD, DVD up to FULL-HD." msgstr "" "PhotoFilmStrip створює фільм з ваших зображень за 3 кроки. Спочатку виберіть " "фотографії, налаштуйте шляхи переміщення і обробіть відео. Є можливість " "виводити у форматах VCD, SVCD, DVD аж до FULL-HD." #: photofilmstrip/gui/FrmMain.py:303 msgid "online" msgstr "онлайн" #: photofilmstrip/gui/FrmMain.py:374 msgid "Invalid %(app)s-Project: %(file)s" msgstr "Неправильний %(app)s-Проект: %(file)s" #: photofilmstrip/gui/PnlAddPics.py:50 photofilmstrip/gui/PnlWelcome.py:30 msgid "Welcome to PhotoFilmStrip" msgstr "Ласкаво просимо до PhotoFilmStrip!" #: photofilmstrip/gui/PnlAddPics.py:52 msgid "" "Drag some pictures onto this text or\n" "click the button below\n" "to add pictures to your new PhotoFilmStrip." msgstr "" "Перетягніть зображення на цей текст або\n" "клацніть кнопку внизу,\n" "щоб додати зображення до нового проекту." #: photofilmstrip/gui/PnlEditPicture.py:142 msgid "Settings" msgstr "Налаштування" #: photofilmstrip/gui/PnlEditPicture.py:146 msgid "Rotation:" msgstr "Обертання:" #: photofilmstrip/gui/PnlEditPicture.py:166 msgid "Effect:" msgstr "Ефект:" #: photofilmstrip/gui/PnlEditPicture.py:180 msgid "Process" msgstr "Обробка" #: photofilmstrip/gui/PnlEditPicture.py:184 msgid "Movement:" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:196 #: photofilmstrip/gui/PnlEditPicture.py:212 #: photofilmstrip/gui/PnlEditPicture.py:359 msgid "sec" msgstr "сек" #: photofilmstrip/gui/PnlEditPicture.py:200 msgid "Transition:" msgstr "Переміщення:" #: photofilmstrip/gui/PnlEditPicture.py:220 msgid "Subtitle" msgstr "Субтитри" #: photofilmstrip/gui/PnlEditPicture.py:240 msgid "Linear" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:241 msgid "Accelerated" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:242 msgid "Delayed" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:250 msgid "No effect" msgstr "Без ефекту" #: photofilmstrip/gui/PnlEditPicture.py:251 msgid "Black and White" msgstr "Чорно-біле" #: photofilmstrip/gui/PnlEditPicture.py:252 msgid "Sepia tone" msgstr "Сепія" #: photofilmstrip/gui/PnlEditPicture.py:258 msgid "None" msgstr "Немає" #: photofilmstrip/gui/PnlEditPicture.py:259 msgid "Fade" msgstr "Згасання" #: photofilmstrip/gui/PnlEditPicture.py:260 msgid "Roll" msgstr "Прокручування" #: photofilmstrip/gui/PnlEditPicture.py:354 msgid "fpp" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:355 msgid "frames per picture - the number of frames each picture will be shown" msgstr "" #: photofilmstrip/gui/PnlEditorPage.py:26 msgid "Could not save the file '%(file)s': %(errMsg)s" msgstr "Неможливо записати файл '%(file)s': %(errMsg)s" #: photofilmstrip/gui/PnlEditorPage.py:45 msgid "New file" msgstr "" #: photofilmstrip/gui/PnlEditorPage.py:48 msgid "'%s' has been modified. Save changes?" msgstr "'%s' змінено. Зберегти зміни?" #: photofilmstrip/gui/PnlEditorPage.py:74 #, fuzzy msgid "Save %s" msgstr "Зберегти проект %s" #: photofilmstrip/gui/PnlEditorPage.py:77 #, fuzzy msgid "File" msgstr "&Файл" #: photofilmstrip/gui/PnlEditorPage.py:87 msgid "Overwrite existing file '%s'?" msgstr "Переписати наявний файл '%s'?" #: photofilmstrip/gui/PnlPfsProject.py:118 #: photofilmstrip/gui/PnlPfsProject.py:120 msgid "Set motion start to end" msgstr "Зробити початкове положення кінцевим" #: photofilmstrip/gui/PnlPfsProject.py:122 #: photofilmstrip/gui/PnlPfsProject.py:124 msgid "Set motion end to start" msgstr "Зробити кінцеве положення початковим" #: photofilmstrip/gui/PnlPfsProject.py:126 #: photofilmstrip/gui/PnlPfsProject.py:128 #, fuzzy msgid "Swap motion" msgstr "Випадковий рух" #: photofilmstrip/gui/PnlPfsProject.py:131 #: photofilmstrip/gui/PnlPfsProject.py:133 msgid "Adjust motion manual" msgstr "Налаштувати рух вручну" #: photofilmstrip/gui/PnlPfsProject.py:136 #: photofilmstrip/gui/PnlPfsProject.py:138 msgid "Preserve image dimension" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:294 msgid "&Import Pictures" msgstr "&Імпортувати зображення" #: photofilmstrip/gui/PnlPfsProject.py:299 msgid "Move picture &left" msgstr "Пересунути зображення &ліворуч" #: photofilmstrip/gui/PnlPfsProject.py:303 msgid "Move picture &right" msgstr "Пересунути зображення п&раворуч" #: photofilmstrip/gui/PnlPfsProject.py:308 #, fuzzy msgid "R&emove Picture" msgstr "В&илучити зображення" #: photofilmstrip/gui/PnlPfsProject.py:313 msgid "Rotate &clockwise" msgstr "Повернути &за годинниковою стрілкою" #: photofilmstrip/gui/PnlPfsProject.py:317 msgid "Rotate counter clock&wise" msgstr "Повернути п&роти годинникової стрілки" #: photofilmstrip/gui/PnlPfsProject.py:322 #, fuzzy msgid "Random &motion" msgstr "Випадковий рух" #: photofilmstrip/gui/PnlPfsProject.py:326 msgid "Centralize m&otion" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:384 msgid "Export slideshow" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:387 #: photofilmstrip/gui/PnlPfsProject.py:400 #, fuzzy msgid "Portable slideshow" msgstr "Портабельний" #: photofilmstrip/gui/PnlPfsProject.py:398 #, fuzzy msgid "Import Slideshow" msgstr "Імпорт зображень" #: photofilmstrip/gui/PnlPfsProject.py:409 msgid "Import images" msgstr "Імпорт зображень" #: photofilmstrip/gui/PnlPfsProject.py:411 #, fuzzy msgid "Image files" msgstr "Файли зображень" #: photofilmstrip/gui/PnlPfsProject.py:654 msgid "Audio file '%s' does not exist! Continue anyway?" msgstr "Звукового файлу '%s' не існує! Все одно продовжити?" #: photofilmstrip/gui/PnlPfsProject.py:655 msgid "Warning" msgstr "Застереження" #: photofilmstrip/gui/PnlSlideshow.py:30 msgid "&Properties" msgstr "В&ластивості" #: photofilmstrip/gui/PnlSlideshow.py:39 photofilmstrip/gui/PnlSlideshow.py:40 #: photofilmstrip/gui/PnlTimelapse.py:25 photofilmstrip/gui/PnlTimelapse.py:26 msgid "Import Pictures" msgstr "Імпортувати зображення" #: photofilmstrip/gui/PnlSlideshow.py:62 photofilmstrip/gui/PnlSlideshow.py:63 #: photofilmstrip/gui/PnlTimelapse.py:41 photofilmstrip/gui/PnlTimelapse.py:42 msgid "Render filmstrip" msgstr "Обробити фільм" #: photofilmstrip/gui/PnlSlideshow.py:89 photofilmstrip/gui/PnlTimelapse.py:66 msgid "Images" msgstr "Зображень" #: photofilmstrip/gui/PnlSlideshow.py:94 msgid "Duration" msgstr "Тривалість" #: photofilmstrip/gui/PnlTimelapse.py:69 msgid "Frames" msgstr "" #: photofilmstrip/gui/PnlTimelapse.py:92 msgid "The picture counter is not increasing: %s" msgstr "" #: photofilmstrip/gui/PnlTimelapse.py:110 msgid "" "Filename '%s' does not match a number pattern which is necessary for a time " "lapse slide show!" msgstr "" #: photofilmstrip/gui/PnlWelcome.py:37 photofilmstrip/gui/PnlWelcome.py:103 msgid "Recent projects" msgstr "Останні проекти" #: photofilmstrip/gui/PnlWelcome.py:62 msgid "Open existing project" msgstr "Відкрити наявний проект" #: photofilmstrip/gui/PnlWelcome.py:106 msgid "How to start..." msgstr "Як розпочати..." #: photofilmstrip/gui/PnlWelcome.py:107 msgid "Create a new project or load an existing one." msgstr "Створіть новий проект або відкрийте наявний." #: photofilmstrip/gui/PnlWelcome.py:138 msgid "Update available" msgstr "Доступне оновлення" #: photofilmstrip/gui/PnlWelcome.py:141 msgid "The following changes has been made:" msgstr "Внесено такі зміни:" #: photofilmstrip/gui/WxProjectFile.py:59 #, fuzzy msgid "Loading project %s" msgstr "Відкрити проект" #: photofilmstrip/gui/WxProjectFile.py:75 #, fuzzy msgid "Saving project %s" msgstr "Зберегти проект" #: photofilmstrip/gui/WxProjectFile.py:100 msgid "" "Some images does not exist in the folder '%s' anymore. If the files has " "moved you can select the new path. Do you want to select a new path?" msgstr "" "Деяких зображень вже немає у теці '%s'. Якщо вони переміщені, ви можете " "вказати новий шлях. Чи бажаєте ви вказати новий шлях?" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:73 msgid "Elapsed time" msgstr "" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:85 msgid "Remaining time" msgstr "" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:203 msgid "Unknown" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobManager.py:50 msgid "&Clear list" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:127 msgid "Abort" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:133 msgid "Remove from list" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:223 #, fuzzy msgid "Abort selected process?" msgstr "Припинити поточний процес?" #: photofilmstrip/lib/jobimpl/VisualJob.py:29 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:25 #, fuzzy msgid "Waiting..." msgstr "припинення..." #: photofilmstrip/lib/jobimpl/VisualJob.py:68 #: photofilmstrip/lib/jobimpl/VisualJob.py:85 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:60 msgid "Aborted" msgstr "припинено" #: photofilmstrip/lib/jobimpl/VisualJob.py:70 msgid "Done" msgstr "" #: photofilmstrip/lib/jobimpl/VisualJob.py:79 msgid "Aborting..." msgstr "припинення..." #: photofilmstrip/uwp/UwpService.py:76 msgid "Slideshow created!" msgstr "" #, fuzzy #~ msgid "Audio files:" #~ msgstr "Звукові файли" #~ msgid "Project properties" #~ msgstr "Параметри проекту" #~ msgid "PhotoFilmStrip project" #~ msgstr "Проект PhotoFilmStrip" #~ msgid "Unnamed PhotoFilmStrip" #~ msgstr "PhotoFilmStrip без назви" #~ msgid "Project" #~ msgstr "Проект" #~ msgid "invalid videonorm specified: %s" #~ msgstr "вказано неправильний відеостандарт: %s" #~ msgid "Please wait..." #~ msgstr "Зачекайте, будь ласка..." #~ msgid "aborting..." #~ msgstr "припинення..." #~ msgid "mencoder (mencoder) required!" #~ msgstr "потрібний MEncoder!" #~ msgid "MPEG(1/2)-Video (MPG)" #~ msgstr "MPEG(1/2)-відео (MPG)" #~ msgid "MPEG format supports only VCD, SVCD and DVD profile!" #~ msgstr "Формат MPEG підтримує лише профілі VCD, SVCD та DVD!" #~ msgid "MPEG4-XVid/AC3 (AVI)" #~ msgstr "MPEG4-XVid/AC3 (AVI)" #~ msgid "mencoder with MP3 support (mp3lame) required!" #~ msgstr "потрібен MEncoder з підтримкою MP3 (mp3lame)!" #~ msgid "MPEG4-XVid/MP3 (AVI)" #~ msgstr "MPEG4-XVid/MP3 (AVI)" #~ msgid "Flash-Video (FLV)" #~ msgstr "Флеш-відео (FLV)" #~ msgid "Motion-JPEG (AVI)" #~ msgstr "Рухомий-JPEG (AVI)" #~ msgid "&Tools" #~ msgstr "&Інструменти" #~ msgid "New Project" #~ msgstr "Новий проект" #~ msgid "Load Project" #~ msgstr "Відкрити проект" #~ msgid "Save Project" #~ msgstr "Зберегти проект" #~ msgid "&New Project" #~ msgstr "&Новий проект" #~ msgid "&Open Project" #~ msgstr "&Відкрити проект" #~ msgid "&Save Project" #~ msgstr "&Зберегти проект" #~ msgid "&Close Project" #~ msgstr "За&крити проект" #~ msgid "&Render filmstrip" #~ msgstr "&Обробити фільм" #~ msgid "Audio file:" #~ msgstr "Звуковий файл:" #~ msgid "Type:" #~ msgstr "Тип:" #~ msgid "Export %s-Project" #~ msgstr "Експортувати проект %s" #~ msgid "Import %s-Project" #~ msgstr "Імпортувати проект %s" #~ msgid "Duration:" #~ msgstr "Тривалість:" #~ msgid "Error: %s" #~ msgstr "Помилка: %s" #~ msgid "initialize renderer" #~ msgstr "ініціалізація обробника" #~ msgid "creating output..." #~ msgstr "створення виведення..." #~ msgid "Finalizing" #~ msgstr "Завершення" #~ msgid "Choose your next action:" #~ msgstr "Виберіть наступну дію:" #~ msgid "Delete unfinished result" #~ msgstr "Вилучити незавершені результати" #~ msgid "Do nothing" #~ msgstr "Не робити нічого" #~ msgid "Show error again and send to developer." #~ msgstr "Показати помилку знову і надіслати розробнику." #~ msgid "The rendering process was aborted." #~ msgstr "Обробку було перервано." #~ msgid "The rendering process was interrupted." #~ msgstr "Обробку було зупинено." #~ msgid "The rendering process has been finished." #~ msgstr "Обробку завершено." #~ msgid "&Batch Job" #~ msgstr "&Пакетна обробка" #~ msgid "" #~ "Project not saved yet. Please save the project first to create a batch " #~ "job!" #~ msgstr "" #~ "Проект ще не збережено. Збережіть проект перед початком пакетної обробки!" #~ msgid "Batch file" #~ msgstr "Пакет" #~ msgid "Shell script" #~ msgstr "Сценарій оболонки" #~ msgid "Select batch file" #~ msgstr "Вибрати пакет" #~ msgid "Browse" #~ msgstr "Огляд" #~ msgid "Import image" #~ msgstr "Імпорт зображення" #~ msgid "Please wait" #~ msgstr "Будь ласка, зачекайте" #~ msgid "Loading pictures..." #~ msgstr "Завантаження зображень..." photofilmstrip-3.7.2/po/tr.po0000644000232200023220000007104713560357351016600 0ustar debalancedebalance# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR ORGANIZATION # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PhotoFilmStrip\n" "POT-Creation-Date: 2018-11-07 22:03+CET\n" "PO-Revision-Date: 2011-09-04 03:13+0200\n" "Last-Translator: Alattin \n" "Language-Team: Jens Göpfert \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: pygettext.py 1.5\n" "X-Poedit-Language: English\n" "X-Poedit-Country: UNITED STATES\n" "X-Poedit-SourceCharset: utf-8\n" #: photofilmstrip/action/ActionAutoPath.py:23 #: photofilmstrip/gui/PnlPfsProject.py:115 msgid "Random motion" msgstr "Rastgele hareket" #: photofilmstrip/action/ActionCenterPath.py:21 msgid "Centralize motion" msgstr "" #: photofilmstrip/action/ActionI18N.py:24 #: photofilmstrip/gui/ActionManager.py:170 msgid "Language" msgstr "Dil" #: photofilmstrip/action/ActionOpenFolder.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:28 msgid "Open folder" msgstr "Dosya aç" #: photofilmstrip/action/ActionPlayVideo.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:22 msgid "Play video" msgstr "Videoyu oynat" #: photofilmstrip/action/ActionRender.py:37 #, fuzzy msgid "Start" msgstr "&Başlat" #: photofilmstrip/cli/Main.py:46 photofilmstrip/cli/Main.py:196 msgid "all done" msgstr "Bitti" #: photofilmstrip/cli/Main.py:64 msgid "processing project" msgstr "proje işleniyor" #: photofilmstrip/cli/Main.py:65 msgid "using renderer" msgstr "çevirici kullanılıyor" #: photofilmstrip/cli/Main.py:66 msgid "output format" msgstr "Çıkış formatı" #: photofilmstrip/cli/Main.py:69 msgid "framerate" msgstr "framerate" #: photofilmstrip/cli/Main.py:103 msgid "specifies the project file" msgstr "Belirtilen proje dosyası" #: photofilmstrip/cli/Main.py:104 msgid "The path where to save the output files. Use - for stdout." msgstr "Çıktı dosyalarını kaydetmek için yol.Stdout için - kullanın." #: photofilmstrip/cli/Main.py:106 photofilmstrip/cli/Main.py:129 msgid "Option videonorm is deprecated, use an appropriate profile!" msgstr "" #: photofilmstrip/cli/Main.py:108 msgid "enable draft mode" msgstr "taslak mod seç" #: photofilmstrip/cli/Main.py:108 photofilmstrip/gui/DlgRender.py:167 msgid "" "Activate this option to generate a preview of your PhotoFilmStrip. The " "rendering process will speed up dramatically, but results in lower quality." msgstr "" "PhotoFilmStrip'te bir önizleme oluşturmak için bu seçeneği etkinleştirin." "Oluşturma sürecini önemli ölçüde hızlandırır, ancak sonuçlar daha düşük " "kalitede olur . " #: photofilmstrip/cli/Main.py:120 msgid "project file does not exist: %s" msgstr "proje dosyası yok: %s" #: photofilmstrip/cli/Main.py:124 msgid "no project file specified!" msgstr "Belirtilen proje dosyası yok!" #: photofilmstrip/cli/Main.py:134 msgid "invalid format specified: %s" msgstr "Hatalı format belirtilmiş: %s" #: photofilmstrip/cli/Main.py:140 msgid "invalid profile specified: %s" msgstr "Hatalı profil belirtilmiş: %s" #: photofilmstrip/cli/Main.py:146 #, fuzzy msgid "cannot load project" msgstr "photofilmstrip yüklenemedi" #: photofilmstrip/cli/Main.py:159 msgid "cannot create output path: %s" msgstr "Çıkış yolu yaratılamıyor: %s" #: photofilmstrip/cli/Main.py:169 photofilmstrip/gui/DlgConfigureAudio.py:231 #: photofilmstrip/gui/DlgConfigureAudio.py:253 msgid "Audio file '%s' does not exist!" msgstr "Ses dosyası '%s' yok!" #: photofilmstrip/cli/Main.py:190 msgid "...aborted!" msgstr "...iptal edildi!" #: photofilmstrip/core/BaseRenderer.py:50 msgid "Unknown property: %s" msgstr "Bilinmeyen özellik: %s" #: photofilmstrip/core/BaseRenderer.py:58 msgid "" msgstr "<ön tanımlı>" #: photofilmstrip/core/BaseRenderer.py:73 msgid "no" msgstr "hayır" #: photofilmstrip/core/ProjectFile.py:222 #, fuzzy msgid "Saving '%s' ..." msgstr "Yükleniyor '%s' ..." #: photofilmstrip/core/ProjectFile.py:276 msgid "Loading '%s' ..." msgstr "Yükleniyor '%s' ..." #: photofilmstrip/core/RenderEngine.py:113 #: photofilmstrip/core/RenderEngine.py:201 msgid "processing transition %d/%d" msgstr "İşlenen geçiş %d/%d" #: photofilmstrip/core/RenderEngine.py:124 #: photofilmstrip/core/RenderEngine.py:210 msgid "processing image %d/%d" msgstr "İşlenen resim %d/%d" #: photofilmstrip/core/renderer/CairoRenderer.py:35 msgid "Preview" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:50 msgid "GStreamer (python-gst-1.0) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:287 msgid "Bitrate must be a number!" msgstr "Bitrate bir sayı olmalıdır!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:455 #: photofilmstrip/core/renderer/GStreamerRenderer.py:531 #: photofilmstrip/core/renderer/GStreamerRenderer.py:601 #: photofilmstrip/core/renderer/GStreamerRenderer.py:690 #: photofilmstrip/core/renderer/GStreamerRenderer.py:730 #: photofilmstrip/core/renderer/GStreamerRenderer.py:779 msgid "libav (gstreamer1.0-libav) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:459 #: photofilmstrip/core/renderer/GStreamerRenderer.py:535 #: photofilmstrip/core/renderer/GStreamerRenderer.py:605 msgid "x264-Codec (gstreamer1.0-plugins-ugly) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:463 #: photofilmstrip/core/renderer/GStreamerRenderer.py:609 msgid "MKV-Muxer (gstreamer1.0-plugins-good) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:539 msgid "MP4-Muxer (gstreamer1.0-plugins-good) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:647 msgid "Theora-Codec (gstreamer1.0-plugins-base) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:651 msgid "Vorbis-Codec (gstreamer1.0-plugins-base) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:655 msgid "OGV-Muxer (gstreamer1.0-plugins-base) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:686 #: photofilmstrip/core/renderer/GStreamerRenderer.py:726 #: photofilmstrip/core/renderer/GStreamerRenderer.py:775 msgid "MPEG-1/2-Codec (gstreamer1.0-plugins-bad) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:694 #: photofilmstrip/core/renderer/GStreamerRenderer.py:734 #: photofilmstrip/core/renderer/GStreamerRenderer.py:783 msgid "MPEG-Muxer (gstreamer1.0-plugins-bad) required!" msgstr "" #: photofilmstrip/core/renderer/SingleFileRenderer.py:21 msgid "Single pictures" msgstr "Ufak resimler" #: photofilmstrip/core/tasks.py:48 msgid "generating subtitle" msgstr "Altyazı hazırlanıyor" #: photofilmstrip/gui/ActionManager.py:60 #: photofilmstrip/gui/ActionManager.py:190 msgid "&File" msgstr "&Dosya" #: photofilmstrip/gui/ActionManager.py:61 #: photofilmstrip/gui/ActionManager.py:191 msgid "&Edit" msgstr "&Düzenle" #: photofilmstrip/gui/ActionManager.py:62 #: photofilmstrip/gui/ActionManager.py:154 photofilmstrip/gui/DlgRender.py:141 #: photofilmstrip/gui/DlgRendererProps.py:86 msgid "&Help" msgstr "&Yardım" #: photofilmstrip/gui/ActionManager.py:76 msgid "New Slideshow" msgstr "" #: photofilmstrip/gui/ActionManager.py:81 msgid "Open" msgstr "" #: photofilmstrip/gui/ActionManager.py:87 msgid "Save" msgstr "" #: photofilmstrip/gui/ActionManager.py:97 #: photofilmstrip/gui/ActionManager.py:98 msgid "Show job queue" msgstr "" #: photofilmstrip/gui/ActionManager.py:108 #: photofilmstrip/gui/PnlSlideshow.py:25 msgid "Slideshow" msgstr "" #: photofilmstrip/gui/ActionManager.py:110 #: photofilmstrip/gui/PnlTimelapse.py:18 msgid "Timelapse" msgstr "" #: photofilmstrip/gui/ActionManager.py:116 msgid "New" msgstr "" #: photofilmstrip/gui/ActionManager.py:118 msgid "&Open" msgstr "" #: photofilmstrip/gui/ActionManager.py:123 msgid "&Save" msgstr "" #: photofilmstrip/gui/ActionManager.py:136 msgid "&Close" msgstr "&Kapat" #: photofilmstrip/gui/ActionManager.py:141 msgid "E&xit" msgstr "Ç&kış" #: photofilmstrip/gui/ActionManager.py:173 msgid "&About" msgstr "&Hakkında" #: photofilmstrip/gui/DlgBugReport.py:41 msgid "An unexpected error occured" msgstr "Beklenmeyen hata oluştu" #: photofilmstrip/gui/DlgBugReport.py:44 msgid "" "An unexpected error occured. Do you want to send this bug report to the " "developers of %s?" msgstr "" "Beklenmeyen hata oluştu.Bu hatayı %s geliştiricilerine göndermek " "istermisiniz?" #: photofilmstrip/gui/DlgBugReport.py:99 msgid "Bug-Report send. Thank you for your support." msgstr "Hata gönderildi. Desteğiniz için teşekkür ederiz." #: photofilmstrip/gui/DlgBugReport.py:100 photofilmstrip/gui/FrmMain.py:290 msgid "Information" msgstr "Bilgi" #: photofilmstrip/gui/DlgBugReport.py:106 msgid "Sorry, this function is temporary not available.." msgstr "Üzgünüm,bu fonksiyona ulaşılamıyor.." #: photofilmstrip/gui/DlgBugReport.py:107 #: photofilmstrip/gui/DlgConfigureAudio.py:232 #: photofilmstrip/gui/DlgConfigureAudio.py:244 #: photofilmstrip/gui/DlgConfigureAudio.py:254 #: photofilmstrip/gui/DlgNewProject.py:156 #: photofilmstrip/gui/DlgNewProject.py:167 #: photofilmstrip/gui/DlgPicDurationByAudio.py:208 #: photofilmstrip/gui/DlgPicDurationByAudio.py:216 #: photofilmstrip/gui/FrmMain.py:376 photofilmstrip/gui/PnlPfsProject.py:468 #: photofilmstrip/gui/PnlTimelapse.py:113 msgid "Error" msgstr "Hata" #: photofilmstrip/gui/DlgConfigureAudio.py:55 msgid "Configure your audio files that are used as a background music." msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:90 msgid "Set the duration of your slideshow to fit your audio files" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:92 #: photofilmstrip/gui/DlgDuration.py:70 photofilmstrip/gui/DlgNewProject.py:84 #: photofilmstrip/gui/DlgPicDurationByAudio.py:50 #: photofilmstrip/gui/DlgPositionInput.py:238 #: photofilmstrip/gui/DlgRender.py:147 #: photofilmstrip/gui/DlgRendererProps.py:92 #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:97 msgid "&Cancel" msgstr "&Vazgeç" #: photofilmstrip/gui/DlgConfigureAudio.py:97 #: photofilmstrip/gui/DlgDuration.py:72 photofilmstrip/gui/DlgNewProject.py:86 #: photofilmstrip/gui/DlgPicDurationByAudio.py:51 #: photofilmstrip/gui/DlgPositionInput.py:244 #: photofilmstrip/gui/DlgRendererProps.py:97 msgid "&Ok" msgstr "&Tamam" #: photofilmstrip/gui/DlgConfigureAudio.py:104 #: photofilmstrip/gui/DlgConfigureAudio.py:109 #: photofilmstrip/gui/PnlSlideshow.py:47 photofilmstrip/gui/PnlSlideshow.py:48 #: photofilmstrip/gui/PnlTimelapse.py:33 photofilmstrip/gui/PnlTimelapse.py:34 msgid "Configure music" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:138 msgid "Select music" msgstr "Müzik seçin" #: photofilmstrip/gui/DlgConfigureAudio.py:140 msgid "Audio files" msgstr "Ses dosyaları" #: photofilmstrip/gui/DlgConfigureAudio.py:243 msgid "Audio file not supported!" msgstr "Ses dosyası desteklenmiyor!" #: photofilmstrip/gui/DlgDuration.py:48 msgid "Total length:" msgstr "Toplam uzunluk:" #: photofilmstrip/gui/DlgDuration.py:50 msgid "" "Overrides the duration of single pictures and gives the project this total " "length." msgstr "Tek resim süresini geçersiz kılar ve projenin toplam uzunluğunu verir." #: photofilmstrip/gui/DlgDuration.py:54 msgid "User defined:" msgstr "Kullanıcı tanımlı:" #: photofilmstrip/gui/DlgDuration.py:65 #, fuzzy msgid "Fit to audio files" msgstr "Ses dosyaları" #: photofilmstrip/gui/DlgDuration.py:80 msgid "Slideshow duration" msgstr "" #: photofilmstrip/gui/DlgDuration.py:84 msgid "Configure duration of slideshow" msgstr "" #: photofilmstrip/gui/DlgNewProject.py:61 msgid "Project name:" msgstr "Proje ismi:" #: photofilmstrip/gui/DlgNewProject.py:66 msgid "Folder:" msgstr "Dosya:" #: photofilmstrip/gui/DlgNewProject.py:78 msgid "Aspect ratio:" msgstr "En-boy oranı:" #: photofilmstrip/gui/DlgNewProject.py:110 #, fuzzy msgid "Unnamed project" msgstr "photofilmstrip yüklenemedi" #: photofilmstrip/gui/DlgNewProject.py:116 msgid "My PhotoFilmStrips" msgstr "PhotoFilmStrips" #: photofilmstrip/gui/DlgNewProject.py:126 msgid "Browse for folder" msgstr "Dosya için gözat" #: photofilmstrip/gui/DlgNewProject.py:145 msgid "Folder does not exists! Do you want %s to create it?" msgstr "Klasör yok! %s klasörü yaratılsın mı?" #: photofilmstrip/gui/DlgNewProject.py:146 #: photofilmstrip/gui/PnlEditorPage.py:29 #: photofilmstrip/gui/PnlEditorPage.py:49 #: photofilmstrip/gui/PnlEditorPage.py:88 #: photofilmstrip/gui/WxProjectFile.py:101 #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:224 msgid "Question" msgstr "Soru" #: photofilmstrip/gui/DlgNewProject.py:155 msgid "Cannot create folder: %s" msgstr "Dosya yaratılamadı: %s" #: photofilmstrip/gui/DlgNewProject.py:166 msgid "Cannot write into folder!" msgstr "Dosya içine yazılamadı!" #: photofilmstrip/gui/DlgNewProject.py:180 msgid "The project name must be filled." msgstr "Proje adı doldurulması zorunludur." #: photofilmstrip/gui/DlgNewProject.py:186 msgid "The project name contains invalid characters." msgstr "Proje isminde hatalı karakterler var." #: photofilmstrip/gui/DlgPicDurationByAudio.py:23 #: photofilmstrip/gui/PnlSlideshow.py:54 photofilmstrip/gui/PnlSlideshow.py:55 msgid "Adjust picture durations" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:26 msgid "Adjust picture durations to audio file" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:30 msgid "" "Find your picture duration by playing the audio file of your project and\n" "pressing the hit button to apply the current playing time." msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:43 #: photofilmstrip/gui/DlgPicDurationByAudio.py:153 msgid "Play" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:46 msgid "Hit" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:100 msgid "Stop" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:179 #, fuzzy msgid "Playing time" msgstr "Videoyu oynat" #: photofilmstrip/gui/DlgPicDurationByAudio.py:207 msgid "Your project does not have an audio file configured." msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:215 msgid "" "Your project uses more than one audio file. Currently the durations can be " "adjusted only for one audio file." msgstr "" #: photofilmstrip/gui/DlgPositionInput.py:140 msgid "Motion positions" msgstr "Hareket pozisyonları" #: photofilmstrip/gui/DlgPositionInput.py:147 msgid "Start position" msgstr "İlk pozisyon" #: photofilmstrip/gui/DlgPositionInput.py:155 #: photofilmstrip/gui/DlgPositionInput.py:199 msgid "Location:" msgstr "Yer:" #: photofilmstrip/gui/DlgPositionInput.py:173 #: photofilmstrip/gui/DlgPositionInput.py:215 msgid "Size:" msgstr "Boyut:" #: photofilmstrip/gui/DlgPositionInput.py:191 msgid "End position" msgstr "Son pozisyon" #: photofilmstrip/gui/DlgPositionInput.py:233 msgid "Reset" msgstr "Sıfırla" #: photofilmstrip/gui/DlgPositionInput.py:252 msgid "Adjust motion positions directly" msgstr "Hareket pozisyonunu ayarlama" #: photofilmstrip/gui/DlgRender.py:96 #, fuzzy msgid "Render project" msgstr "Proje geçmişi" #: photofilmstrip/gui/DlgRender.py:107 msgid "Format:" msgstr "Format:" #: photofilmstrip/gui/DlgRender.py:122 msgid "Properties" msgstr "Özellikler" #: photofilmstrip/gui/DlgRender.py:127 msgid "Profile:" msgstr "Profil:" #: photofilmstrip/gui/DlgRender.py:136 msgid "Draft" msgstr "Taslak" #: photofilmstrip/gui/DlgRender.py:152 msgid "&Start" msgstr "&Başlat" #: photofilmstrip/gui/DlgRender.py:164 msgid "Configure output and start render process" msgstr "Düzenlemeleri yapın ve başlat tıklayın." #: photofilmstrip/gui/DlgRendererProps.py:50 msgid "Property" msgstr "Özellik" #: photofilmstrip/gui/DlgRendererProps.py:52 msgid "Value" msgstr "Değer" #: photofilmstrip/gui/DlgRendererProps.py:71 msgid "Output properties" msgstr "Çıkış özellikleri" #: photofilmstrip/gui/DlgRendererProps.py:113 msgid "Edit extended output properties" msgstr "Geniş çıkış özelliklerini ayarla" #: photofilmstrip/gui/DlgRendererProps.py:147 msgid "Edit property" msgstr "Özellikleri düzenle" #: photofilmstrip/gui/FrmMain.py:83 msgid "Welcome" msgstr "Hoşgeldin" #: photofilmstrip/gui/FrmMain.py:85 msgid "Job queue" msgstr "" #: photofilmstrip/gui/FrmMain.py:141 msgid "Rendering in progress..." msgstr "" #: photofilmstrip/gui/FrmMain.py:234 photofilmstrip/gui/PnlWelcome.py:57 #, fuzzy msgid "Create new slideshow" msgstr "Portatif" #: photofilmstrip/gui/FrmMain.py:241 #, fuzzy msgid "Create new timelapse" msgstr "Yeni proje yarat" #: photofilmstrip/gui/FrmMain.py:249 msgid "Select %s-Project" msgstr "%s-Projesini seçin" #: photofilmstrip/gui/FrmMain.py:251 #, fuzzy msgid "Files" msgstr "&Dosya" #: photofilmstrip/gui/FrmMain.py:289 msgid "You must restart %s for your new language setting to take effect." msgstr "Yeni dilin aktif olması için %s programını tekrar başlatın." #: photofilmstrip/gui/FrmMain.py:300 msgid "" "PhotoFilmStrip creates movies out of your pictures in just 3 steps. First " "select your photos, customize the motion path and render the video. There " "are several output possibilities for VCD, SVCD, DVD up to FULL-HD." msgstr "" "PhotoFilmStrip ile sadece 3 adımda resimlerinizden film yaratın.Önce " "resimleri seçin,dosyanızı ayarlayın ve filminizi yaratın.VCD, SVCD, DVD ve " "FULL-HD için birçok seçenek mevcuttur." #: photofilmstrip/gui/FrmMain.py:303 msgid "online" msgstr "Bağlı" #: photofilmstrip/gui/FrmMain.py:374 msgid "Invalid %(app)s-Project: %(file)s" msgstr "Hatalı %(app)s-Proje: %(file)s" #: photofilmstrip/gui/PnlAddPics.py:50 photofilmstrip/gui/PnlWelcome.py:30 msgid "Welcome to PhotoFilmStrip" msgstr "PhotoFilmStrip'e hoşgeldiniz" #: photofilmstrip/gui/PnlAddPics.py:52 msgid "" "Drag some pictures onto this text or\n" "click the button below\n" "to add pictures to your new PhotoFilmStrip." msgstr "" "Resimleri bu yazıya taşıyın veya\n" "butona tıklayıp resimleri ekleyin." #: photofilmstrip/gui/PnlEditPicture.py:142 msgid "Settings" msgstr "Ayarlar" #: photofilmstrip/gui/PnlEditPicture.py:146 msgid "Rotation:" msgstr "Rotasyon:" #: photofilmstrip/gui/PnlEditPicture.py:166 msgid "Effect:" msgstr "Efekt:" #: photofilmstrip/gui/PnlEditPicture.py:180 msgid "Process" msgstr "İşlem" #: photofilmstrip/gui/PnlEditPicture.py:184 msgid "Movement:" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:196 #: photofilmstrip/gui/PnlEditPicture.py:212 #: photofilmstrip/gui/PnlEditPicture.py:359 msgid "sec" msgstr "san." #: photofilmstrip/gui/PnlEditPicture.py:200 msgid "Transition:" msgstr "Dönüşüm:" #: photofilmstrip/gui/PnlEditPicture.py:220 msgid "Subtitle" msgstr "Altyazı" #: photofilmstrip/gui/PnlEditPicture.py:240 msgid "Linear" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:241 msgid "Accelerated" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:242 msgid "Delayed" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:250 msgid "No effect" msgstr "Efekt yok" #: photofilmstrip/gui/PnlEditPicture.py:251 msgid "Black and White" msgstr "Siyah ve beyaz" #: photofilmstrip/gui/PnlEditPicture.py:252 msgid "Sepia tone" msgstr "Sepya tonu" #: photofilmstrip/gui/PnlEditPicture.py:258 msgid "None" msgstr "Yok" #: photofilmstrip/gui/PnlEditPicture.py:259 msgid "Fade" msgstr "Fade" #: photofilmstrip/gui/PnlEditPicture.py:260 msgid "Roll" msgstr "Roll" #: photofilmstrip/gui/PnlEditPicture.py:354 msgid "fpp" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:355 msgid "frames per picture - the number of frames each picture will be shown" msgstr "" #: photofilmstrip/gui/PnlEditorPage.py:26 msgid "Could not save the file '%(file)s': %(errMsg)s" msgstr "'%(file)' dosyası kaydedilmedi: %(errMsg)s" #: photofilmstrip/gui/PnlEditorPage.py:45 msgid "New file" msgstr "" #: photofilmstrip/gui/PnlEditorPage.py:48 msgid "'%s' has been modified. Save changes?" msgstr "'%s' modifiye edildi. Değişiklikler kaydedilsinmi?" #: photofilmstrip/gui/PnlEditorPage.py:74 #, fuzzy msgid "Save %s" msgstr "%s-Projesini kaydet" #: photofilmstrip/gui/PnlEditorPage.py:77 #, fuzzy msgid "File" msgstr "&Dosya" #: photofilmstrip/gui/PnlEditorPage.py:87 msgid "Overwrite existing file '%s'?" msgstr "Var olan '%s' üzerine yazılsın mı?" #: photofilmstrip/gui/PnlPfsProject.py:118 #: photofilmstrip/gui/PnlPfsProject.py:120 msgid "Set motion start to end" msgstr "Hareketi baştan sona ayarla" #: photofilmstrip/gui/PnlPfsProject.py:122 #: photofilmstrip/gui/PnlPfsProject.py:124 msgid "Set motion end to start" msgstr "Hareketi sondan başa ayarla" #: photofilmstrip/gui/PnlPfsProject.py:126 #: photofilmstrip/gui/PnlPfsProject.py:128 #, fuzzy msgid "Swap motion" msgstr "Rastgele hareket" #: photofilmstrip/gui/PnlPfsProject.py:131 #: photofilmstrip/gui/PnlPfsProject.py:133 msgid "Adjust motion manual" msgstr "Hareket pozisyonu elle ayarlama" #: photofilmstrip/gui/PnlPfsProject.py:136 #: photofilmstrip/gui/PnlPfsProject.py:138 msgid "Preserve image dimension" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:294 msgid "&Import Pictures" msgstr "&Resimleri al" #: photofilmstrip/gui/PnlPfsProject.py:299 msgid "Move picture &left" msgstr "Resmi &sola taşı" #: photofilmstrip/gui/PnlPfsProject.py:303 msgid "Move picture &right" msgstr "Resmi &sağa taşı" #: photofilmstrip/gui/PnlPfsProject.py:308 #, fuzzy msgid "R&emove Picture" msgstr "&Resmi sil" #: photofilmstrip/gui/PnlPfsProject.py:313 msgid "Rotate &clockwise" msgstr "Saat yönüne &çevir" #: photofilmstrip/gui/PnlPfsProject.py:317 msgid "Rotate counter clock&wise" msgstr "Saat&yönü tersine çevir" #: photofilmstrip/gui/PnlPfsProject.py:322 #, fuzzy msgid "Random &motion" msgstr "Rastgele hareket" #: photofilmstrip/gui/PnlPfsProject.py:326 msgid "Centralize m&otion" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:384 msgid "Export slideshow" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:387 #: photofilmstrip/gui/PnlPfsProject.py:400 #, fuzzy msgid "Portable slideshow" msgstr "Portatif" #: photofilmstrip/gui/PnlPfsProject.py:398 #, fuzzy msgid "Import Slideshow" msgstr "Resimleri al" #: photofilmstrip/gui/PnlPfsProject.py:409 msgid "Import images" msgstr "Resimleri al" #: photofilmstrip/gui/PnlPfsProject.py:411 #, fuzzy msgid "Image files" msgstr "Resim dosyaları" #: photofilmstrip/gui/PnlPfsProject.py:654 msgid "Audio file '%s' does not exist! Continue anyway?" msgstr "Ses dosyası '%s' yok! Devam etmek istermisin?" #: photofilmstrip/gui/PnlPfsProject.py:655 msgid "Warning" msgstr "Dikkat" #: photofilmstrip/gui/PnlSlideshow.py:30 msgid "&Properties" msgstr "&Özellikler" #: photofilmstrip/gui/PnlSlideshow.py:39 photofilmstrip/gui/PnlSlideshow.py:40 #: photofilmstrip/gui/PnlTimelapse.py:25 photofilmstrip/gui/PnlTimelapse.py:26 msgid "Import Pictures" msgstr "Resimleri al" #: photofilmstrip/gui/PnlSlideshow.py:62 photofilmstrip/gui/PnlSlideshow.py:63 #: photofilmstrip/gui/PnlTimelapse.py:41 photofilmstrip/gui/PnlTimelapse.py:42 msgid "Render filmstrip" msgstr "Film yap" #: photofilmstrip/gui/PnlSlideshow.py:89 photofilmstrip/gui/PnlTimelapse.py:66 msgid "Images" msgstr "Resimler" #: photofilmstrip/gui/PnlSlideshow.py:94 msgid "Duration" msgstr "Süre" #: photofilmstrip/gui/PnlTimelapse.py:69 msgid "Frames" msgstr "" #: photofilmstrip/gui/PnlTimelapse.py:92 msgid "The picture counter is not increasing: %s" msgstr "" #: photofilmstrip/gui/PnlTimelapse.py:110 msgid "" "Filename '%s' does not match a number pattern which is necessary for a time " "lapse slide show!" msgstr "" #: photofilmstrip/gui/PnlWelcome.py:37 photofilmstrip/gui/PnlWelcome.py:103 msgid "Recent projects" msgstr "Proje geçmişi" #: photofilmstrip/gui/PnlWelcome.py:62 msgid "Open existing project" msgstr "Önceki projeyi aç" #: photofilmstrip/gui/PnlWelcome.py:106 msgid "How to start..." msgstr "Nasıl başlar..." #: photofilmstrip/gui/PnlWelcome.py:107 msgid "Create a new project or load an existing one." msgstr "Yeni proje yarat veya önceki projeyi aç tıklayın." #: photofilmstrip/gui/PnlWelcome.py:138 msgid "Update available" msgstr "Yükseltme bulundu" #: photofilmstrip/gui/PnlWelcome.py:141 msgid "The following changes has been made:" msgstr "Yapılan değişiklikler :" #: photofilmstrip/gui/WxProjectFile.py:59 #, fuzzy msgid "Loading project %s" msgstr "Projeyi yükle" #: photofilmstrip/gui/WxProjectFile.py:75 #, fuzzy msgid "Saving project %s" msgstr "Projeyi kaydet" #: photofilmstrip/gui/WxProjectFile.py:100 msgid "" "Some images does not exist in the folder '%s' anymore. If the files has " "moved you can select the new path. Do you want to select a new path?" msgstr "" "Bazı görüntüler artık '% s' klasöründe yok.Eğer dosyalar taşındıysa yeni " "bir yol seçebilirsiniz. Yeni bir yol seçmek istiyor musunuz?" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:73 msgid "Elapsed time" msgstr "" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:85 msgid "Remaining time" msgstr "" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:203 msgid "Unknown" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobManager.py:50 msgid "&Clear list" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:127 msgid "Abort" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:133 msgid "Remove from list" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:223 #, fuzzy msgid "Abort selected process?" msgstr "Proje iptal edilsin mi?" #: photofilmstrip/lib/jobimpl/VisualJob.py:29 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:25 #, fuzzy msgid "Waiting..." msgstr "vazgeçildi..." #: photofilmstrip/lib/jobimpl/VisualJob.py:68 #: photofilmstrip/lib/jobimpl/VisualJob.py:85 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:60 #, fuzzy msgid "Aborted" msgstr "...iptal edildi!" #: photofilmstrip/lib/jobimpl/VisualJob.py:70 msgid "Done" msgstr "" #: photofilmstrip/lib/jobimpl/VisualJob.py:79 #, fuzzy msgid "Aborting..." msgstr "vazgeçildi..." #: photofilmstrip/uwp/UwpService.py:76 msgid "Slideshow created!" msgstr "" #, fuzzy #~ msgid "Audio files:" #~ msgstr "Ses dosyaları" #~ msgid "Project properties" #~ msgstr "Proje özellikleri" #~ msgid "PhotoFilmStrip project" #~ msgstr "PhotoFilmStrip proje" #~ msgid "Unnamed PhotoFilmStrip" #~ msgstr "PhotoFilmStrip için bir isim verin" #~ msgid "Project" #~ msgstr "Proje" #~ msgid "invalid videonorm specified: %s" #~ msgstr "Hatalı vidyonorm belirtilmiş: %s" #~ msgid "Error: %s" #~ msgstr "Hata: %s" #~ msgid "Please wait..." #~ msgstr "Lütfen bekleyin..." #~ msgid "initialize renderer" #~ msgstr "çeviriciyi başlat" #~ msgid "creating output..." #~ msgstr "çıkış yaratılıyor..." #~ msgid "mencoder (mencoder) required!" #~ msgstr "mencoder (mencoder) gerekli!" #~ msgid "MPEG(1/2)-Video (MPG)" #~ msgstr "MPEG(1/2)-Video (MPG)" #~ msgid "MPEG format supports only VCD, SVCD and DVD profile!" #~ msgstr "MPEG format sadece VCD, SVCD ve DVD profilini destekler!" #~ msgid "MPEG4-XVid/AC3 (AVI)" #~ msgstr "MPEG4-XVid/AC3 (AVI)" #~ msgid "mencoder with MP3 support (mp3lame) required!" #~ msgstr "mencoder ile MP3 destekler (mp3lame gerekli)!" #~ msgid "MPEG4-XVid/MP3 (AVI)" #~ msgstr "MPEG4-XVid/MP3 (AVI)" #~ msgid "Flash-Video (FLV)" #~ msgstr "Flash-Video (FLV)" #~ msgid "Motion-JPEG (AVI)" #~ msgstr "Motion-JPEG (AVI)" #~ msgid "&Tools" #~ msgstr "&Araçlar" #~ msgid "New Project" #~ msgstr "Yeni proje" #~ msgid "&New Project" #~ msgstr "&Yeni proje" #~ msgid "&Open Project" #~ msgstr "&Proje aç" #~ msgid "&Save Project" #~ msgstr "&Projeyi kaydet" #~ msgid "&Close Project" #~ msgstr "&Projeyi kapat" #~ msgid "&Render filmstrip" #~ msgstr "&Film yap" #~ msgid "Finalizing" #~ msgstr "Final" #~ msgid "Choose your next action:" #~ msgstr "Diğer adımı seçin:" #~ msgid "Delete unfinished result" #~ msgstr "Bitmemiş sonuçları silin" #~ msgid "Do nothing" #~ msgstr "Birşey yapma" #~ msgid "Show error again and send to developer." #~ msgstr "Hatayı tekrar göster ve geliştiricilere gönder." #~ msgid "The rendering process was aborted." #~ msgstr "Çevrilme işinden vazgeçildi." #~ msgid "The rendering process was interrupted." #~ msgstr "Çevirme işlemi kesildi." #~ msgid "The rendering process has been finished." #~ msgstr "Çevrilme işi bitti." #~ msgid "Audio file:" #~ msgstr "Ses dosyası:" #~ msgid "Type:" #~ msgstr "Tip:" #~ msgid "&Batch Job" #~ msgstr "&İş yığını" #~ msgid "" #~ "Project not saved yet. Please save the project first to create a batch " #~ "job!" #~ msgstr "" #~ "Proje henüz kaydedilmedi.İş yığınını kaydetmek için önce projeyi kaydedin!" #~ msgid "Batch file" #~ msgstr "Yığın dosyası" #~ msgid "Shell script" #~ msgstr "kabuk betiği " #~ msgid "Select batch file" #~ msgstr "Yığın dosyası seç" #~ msgid "Export %s-Project" #~ msgstr "%s-Projesini dışa aktar" #~ msgid "Import %s-Project" #~ msgstr "%s-Projesini içe aktar" #~ msgid "Duration:" #~ msgstr "Süre:" #~ msgid "Browse" #~ msgstr "Gözat" #~ msgid "Import image" #~ msgstr "Resim al" #~ msgid "Please wait" #~ msgstr "Lütfen bekleyin" #~ msgid "Loading pictures..." #~ msgstr "Resimler yükleniyor..." photofilmstrip-3.7.2/po/PhotoFilmStrip.pot0000644000232200023220000005471513560357351021265 0ustar debalancedebalance# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR ORGANIZATION # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2018-11-07 22:03+CET\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: ENCODING\n" "Generated-By: pygettext.py 1.5\n" #: ./photofilmstrip/action/ActionAutoPath.py:23 #: ./photofilmstrip/gui/PnlPfsProject.py:115 msgid "Random motion" msgstr "" #: ./photofilmstrip/action/ActionCenterPath.py:21 msgid "Centralize motion" msgstr "" #: ./photofilmstrip/action/ActionI18N.py:24 #: ./photofilmstrip/gui/ActionManager.py:170 msgid "Language" msgstr "" #: ./photofilmstrip/action/ActionOpenFolder.py:20 #: ./photofilmstrip/gui/PnlRenderJobVisual.py:28 msgid "Open folder" msgstr "" #: ./photofilmstrip/action/ActionPlayVideo.py:20 #: ./photofilmstrip/gui/PnlRenderJobVisual.py:22 msgid "Play video" msgstr "" #: ./photofilmstrip/action/ActionRender.py:37 msgid "Start" msgstr "" #: ./photofilmstrip/cli/Main.py:46 ./photofilmstrip/cli/Main.py:196 msgid "all done" msgstr "" #: ./photofilmstrip/cli/Main.py:64 msgid "processing project" msgstr "" #: ./photofilmstrip/cli/Main.py:65 msgid "using renderer" msgstr "" #: ./photofilmstrip/cli/Main.py:66 msgid "output format" msgstr "" #: ./photofilmstrip/cli/Main.py:69 msgid "framerate" msgstr "" #: ./photofilmstrip/cli/Main.py:103 msgid "specifies the project file" msgstr "" #: ./photofilmstrip/cli/Main.py:104 msgid "The path where to save the output files. Use - for stdout." msgstr "" #: ./photofilmstrip/cli/Main.py:106 ./photofilmstrip/cli/Main.py:129 msgid "Option videonorm is deprecated, use an appropriate profile!" msgstr "" #: ./photofilmstrip/cli/Main.py:108 msgid "enable draft mode" msgstr "" #: ./photofilmstrip/cli/Main.py:108 ./photofilmstrip/gui/DlgRender.py:167 msgid "Activate this option to generate a preview of your PhotoFilmStrip. The rendering process will speed up dramatically, but results in lower quality." msgstr "" #: ./photofilmstrip/cli/Main.py:120 msgid "project file does not exist: %s" msgstr "" #: ./photofilmstrip/cli/Main.py:124 msgid "no project file specified!" msgstr "" #: ./photofilmstrip/cli/Main.py:134 msgid "invalid format specified: %s" msgstr "" #: ./photofilmstrip/cli/Main.py:140 msgid "invalid profile specified: %s" msgstr "" #: ./photofilmstrip/cli/Main.py:146 msgid "cannot load project" msgstr "" #: ./photofilmstrip/cli/Main.py:159 msgid "cannot create output path: %s" msgstr "" #: ./photofilmstrip/cli/Main.py:169 #: ./photofilmstrip/gui/DlgConfigureAudio.py:231 #: ./photofilmstrip/gui/DlgConfigureAudio.py:253 msgid "Audio file '%s' does not exist!" msgstr "" #: ./photofilmstrip/cli/Main.py:190 msgid "...aborted!" msgstr "" #: ./photofilmstrip/core/BaseRenderer.py:50 msgid "Unknown property: %s" msgstr "" #: ./photofilmstrip/core/BaseRenderer.py:58 msgid "" msgstr "" #: ./photofilmstrip/core/BaseRenderer.py:73 msgid "no" msgstr "" #: ./photofilmstrip/core/ProjectFile.py:222 msgid "Saving '%s' ..." msgstr "" #: ./photofilmstrip/core/ProjectFile.py:276 msgid "Loading '%s' ..." msgstr "" #: ./photofilmstrip/core/RenderEngine.py:113 #: ./photofilmstrip/core/RenderEngine.py:201 msgid "processing transition %d/%d" msgstr "" #: ./photofilmstrip/core/RenderEngine.py:124 #: ./photofilmstrip/core/RenderEngine.py:210 msgid "processing image %d/%d" msgstr "" #: ./photofilmstrip/core/renderer/CairoRenderer.py:35 msgid "Preview" msgstr "" #: ./photofilmstrip/core/renderer/GStreamerRenderer.py:50 msgid "GStreamer (python-gst-1.0) required!" msgstr "" #: ./photofilmstrip/core/renderer/GStreamerRenderer.py:287 msgid "Bitrate must be a number!" msgstr "" #: ./photofilmstrip/core/renderer/GStreamerRenderer.py:455 #: ./photofilmstrip/core/renderer/GStreamerRenderer.py:531 #: ./photofilmstrip/core/renderer/GStreamerRenderer.py:601 #: ./photofilmstrip/core/renderer/GStreamerRenderer.py:690 #: ./photofilmstrip/core/renderer/GStreamerRenderer.py:730 #: ./photofilmstrip/core/renderer/GStreamerRenderer.py:779 msgid "libav (gstreamer1.0-libav) required!" msgstr "" #: ./photofilmstrip/core/renderer/GStreamerRenderer.py:459 #: ./photofilmstrip/core/renderer/GStreamerRenderer.py:535 #: ./photofilmstrip/core/renderer/GStreamerRenderer.py:605 msgid "x264-Codec (gstreamer1.0-plugins-ugly) required!" msgstr "" #: ./photofilmstrip/core/renderer/GStreamerRenderer.py:463 #: ./photofilmstrip/core/renderer/GStreamerRenderer.py:609 msgid "MKV-Muxer (gstreamer1.0-plugins-good) required!" msgstr "" #: ./photofilmstrip/core/renderer/GStreamerRenderer.py:539 msgid "MP4-Muxer (gstreamer1.0-plugins-good) required!" msgstr "" #: ./photofilmstrip/core/renderer/GStreamerRenderer.py:647 msgid "Theora-Codec (gstreamer1.0-plugins-base) required!" msgstr "" #: ./photofilmstrip/core/renderer/GStreamerRenderer.py:651 msgid "Vorbis-Codec (gstreamer1.0-plugins-base) required!" msgstr "" #: ./photofilmstrip/core/renderer/GStreamerRenderer.py:655 msgid "OGV-Muxer (gstreamer1.0-plugins-base) required!" msgstr "" #: ./photofilmstrip/core/renderer/GStreamerRenderer.py:686 #: ./photofilmstrip/core/renderer/GStreamerRenderer.py:726 #: ./photofilmstrip/core/renderer/GStreamerRenderer.py:775 msgid "MPEG-1/2-Codec (gstreamer1.0-plugins-bad) required!" msgstr "" #: ./photofilmstrip/core/renderer/GStreamerRenderer.py:694 #: ./photofilmstrip/core/renderer/GStreamerRenderer.py:734 #: ./photofilmstrip/core/renderer/GStreamerRenderer.py:783 msgid "MPEG-Muxer (gstreamer1.0-plugins-bad) required!" msgstr "" #: ./photofilmstrip/core/renderer/SingleFileRenderer.py:21 msgid "Single pictures" msgstr "" #: ./photofilmstrip/core/tasks.py:48 msgid "generating subtitle" msgstr "" #: ./photofilmstrip/gui/ActionManager.py:60 #: ./photofilmstrip/gui/ActionManager.py:190 msgid "&File" msgstr "" #: ./photofilmstrip/gui/ActionManager.py:61 #: ./photofilmstrip/gui/ActionManager.py:191 msgid "&Edit" msgstr "" #: ./photofilmstrip/gui/ActionManager.py:62 #: ./photofilmstrip/gui/ActionManager.py:154 #: ./photofilmstrip/gui/DlgRender.py:141 #: ./photofilmstrip/gui/DlgRendererProps.py:86 msgid "&Help" msgstr "" #: ./photofilmstrip/gui/ActionManager.py:76 msgid "New Slideshow" msgstr "" #: ./photofilmstrip/gui/ActionManager.py:81 msgid "Open" msgstr "" #: ./photofilmstrip/gui/ActionManager.py:87 msgid "Save" msgstr "" #: ./photofilmstrip/gui/ActionManager.py:97 #: ./photofilmstrip/gui/ActionManager.py:98 msgid "Show job queue" msgstr "" #: ./photofilmstrip/gui/ActionManager.py:108 #: ./photofilmstrip/gui/PnlSlideshow.py:25 msgid "Slideshow" msgstr "" #: ./photofilmstrip/gui/ActionManager.py:110 #: ./photofilmstrip/gui/PnlTimelapse.py:18 msgid "Timelapse" msgstr "" #: ./photofilmstrip/gui/ActionManager.py:116 msgid "New" msgstr "" #: ./photofilmstrip/gui/ActionManager.py:118 msgid "&Open" msgstr "" #: ./photofilmstrip/gui/ActionManager.py:123 msgid "&Save" msgstr "" #: ./photofilmstrip/gui/ActionManager.py:136 msgid "&Close" msgstr "" #: ./photofilmstrip/gui/ActionManager.py:141 msgid "E&xit" msgstr "" #: ./photofilmstrip/gui/ActionManager.py:173 msgid "&About" msgstr "" #: ./photofilmstrip/gui/DlgBugReport.py:41 msgid "An unexpected error occured" msgstr "" #: ./photofilmstrip/gui/DlgBugReport.py:44 msgid "An unexpected error occured. Do you want to send this bug report to the developers of %s?" msgstr "" #: ./photofilmstrip/gui/DlgBugReport.py:99 msgid "Bug-Report send. Thank you for your support." msgstr "" #: ./photofilmstrip/gui/DlgBugReport.py:100 #: ./photofilmstrip/gui/FrmMain.py:290 msgid "Information" msgstr "" #: ./photofilmstrip/gui/DlgBugReport.py:106 msgid "Sorry, this function is temporary not available.." msgstr "" #: ./photofilmstrip/gui/DlgBugReport.py:107 #: ./photofilmstrip/gui/DlgConfigureAudio.py:232 #: ./photofilmstrip/gui/DlgConfigureAudio.py:244 #: ./photofilmstrip/gui/DlgConfigureAudio.py:254 #: ./photofilmstrip/gui/DlgNewProject.py:156 #: ./photofilmstrip/gui/DlgNewProject.py:167 #: ./photofilmstrip/gui/DlgPicDurationByAudio.py:208 #: ./photofilmstrip/gui/DlgPicDurationByAudio.py:216 #: ./photofilmstrip/gui/FrmMain.py:376 #: ./photofilmstrip/gui/PnlPfsProject.py:468 #: ./photofilmstrip/gui/PnlTimelapse.py:113 msgid "Error" msgstr "" #: ./photofilmstrip/gui/DlgConfigureAudio.py:55 msgid "Configure your audio files that are used as a background music." msgstr "" #: ./photofilmstrip/gui/DlgConfigureAudio.py:90 msgid "Set the duration of your slideshow to fit your audio files" msgstr "" #: ./photofilmstrip/gui/DlgConfigureAudio.py:92 #: ./photofilmstrip/gui/DlgDuration.py:70 #: ./photofilmstrip/gui/DlgNewProject.py:84 #: ./photofilmstrip/gui/DlgPicDurationByAudio.py:50 #: ./photofilmstrip/gui/DlgPositionInput.py:238 #: ./photofilmstrip/gui/DlgRender.py:147 #: ./photofilmstrip/gui/DlgRendererProps.py:92 #: ./photofilmstrip/lib/jobimpl/DlgJobVisual.py:97 msgid "&Cancel" msgstr "" #: ./photofilmstrip/gui/DlgConfigureAudio.py:97 #: ./photofilmstrip/gui/DlgDuration.py:72 #: ./photofilmstrip/gui/DlgNewProject.py:86 #: ./photofilmstrip/gui/DlgPicDurationByAudio.py:51 #: ./photofilmstrip/gui/DlgPositionInput.py:244 #: ./photofilmstrip/gui/DlgRendererProps.py:97 msgid "&Ok" msgstr "" #: ./photofilmstrip/gui/DlgConfigureAudio.py:104 #: ./photofilmstrip/gui/DlgConfigureAudio.py:109 #: ./photofilmstrip/gui/PnlSlideshow.py:47 #: ./photofilmstrip/gui/PnlSlideshow.py:48 #: ./photofilmstrip/gui/PnlTimelapse.py:33 #: ./photofilmstrip/gui/PnlTimelapse.py:34 msgid "Configure music" msgstr "" #: ./photofilmstrip/gui/DlgConfigureAudio.py:138 msgid "Select music" msgstr "" #: ./photofilmstrip/gui/DlgConfigureAudio.py:140 msgid "Audio files" msgstr "" #: ./photofilmstrip/gui/DlgConfigureAudio.py:243 msgid "Audio file not supported!" msgstr "" #: ./photofilmstrip/gui/DlgDuration.py:48 msgid "Total length:" msgstr "" #: ./photofilmstrip/gui/DlgDuration.py:50 msgid "Overrides the duration of single pictures and gives the project this total length." msgstr "" #: ./photofilmstrip/gui/DlgDuration.py:54 msgid "User defined:" msgstr "" #: ./photofilmstrip/gui/DlgDuration.py:65 msgid "Fit to audio files" msgstr "" #: ./photofilmstrip/gui/DlgDuration.py:80 msgid "Slideshow duration" msgstr "" #: ./photofilmstrip/gui/DlgDuration.py:84 msgid "Configure duration of slideshow" msgstr "" #: ./photofilmstrip/gui/DlgNewProject.py:61 msgid "Project name:" msgstr "" #: ./photofilmstrip/gui/DlgNewProject.py:66 msgid "Folder:" msgstr "" #: ./photofilmstrip/gui/DlgNewProject.py:78 msgid "Aspect ratio:" msgstr "" #: ./photofilmstrip/gui/DlgNewProject.py:110 msgid "Unnamed project" msgstr "" #: ./photofilmstrip/gui/DlgNewProject.py:116 msgid "My PhotoFilmStrips" msgstr "" #: ./photofilmstrip/gui/DlgNewProject.py:126 msgid "Browse for folder" msgstr "" #: ./photofilmstrip/gui/DlgNewProject.py:145 msgid "Folder does not exists! Do you want %s to create it?" msgstr "" #: ./photofilmstrip/gui/DlgNewProject.py:146 #: ./photofilmstrip/gui/PnlEditorPage.py:29 #: ./photofilmstrip/gui/PnlEditorPage.py:49 #: ./photofilmstrip/gui/PnlEditorPage.py:88 #: ./photofilmstrip/gui/WxProjectFile.py:101 #: ./photofilmstrip/lib/jobimpl/PnlJobVisual.py:224 msgid "Question" msgstr "" #: ./photofilmstrip/gui/DlgNewProject.py:155 msgid "Cannot create folder: %s" msgstr "" #: ./photofilmstrip/gui/DlgNewProject.py:166 msgid "Cannot write into folder!" msgstr "" #: ./photofilmstrip/gui/DlgNewProject.py:180 msgid "The project name must be filled." msgstr "" #: ./photofilmstrip/gui/DlgNewProject.py:186 msgid "The project name contains invalid characters." msgstr "" #: ./photofilmstrip/gui/DlgPicDurationByAudio.py:23 #: ./photofilmstrip/gui/PnlSlideshow.py:54 #: ./photofilmstrip/gui/PnlSlideshow.py:55 msgid "Adjust picture durations" msgstr "" #: ./photofilmstrip/gui/DlgPicDurationByAudio.py:26 msgid "Adjust picture durations to audio file" msgstr "" #: ./photofilmstrip/gui/DlgPicDurationByAudio.py:30 msgid "" "Find your picture duration by playing the audio file of your project and\n" "pressing the hit button to apply the current playing time." msgstr "" #: ./photofilmstrip/gui/DlgPicDurationByAudio.py:43 #: ./photofilmstrip/gui/DlgPicDurationByAudio.py:153 msgid "Play" msgstr "" #: ./photofilmstrip/gui/DlgPicDurationByAudio.py:46 msgid "Hit" msgstr "" #: ./photofilmstrip/gui/DlgPicDurationByAudio.py:100 msgid "Stop" msgstr "" #: ./photofilmstrip/gui/DlgPicDurationByAudio.py:179 msgid "Playing time" msgstr "" #: ./photofilmstrip/gui/DlgPicDurationByAudio.py:207 msgid "Your project does not have an audio file configured." msgstr "" #: ./photofilmstrip/gui/DlgPicDurationByAudio.py:215 msgid "Your project uses more than one audio file. Currently the durations can be adjusted only for one audio file." msgstr "" #: ./photofilmstrip/gui/DlgPositionInput.py:140 msgid "Motion positions" msgstr "" #: ./photofilmstrip/gui/DlgPositionInput.py:147 msgid "Start position" msgstr "" #: ./photofilmstrip/gui/DlgPositionInput.py:155 #: ./photofilmstrip/gui/DlgPositionInput.py:199 msgid "Location:" msgstr "" #: ./photofilmstrip/gui/DlgPositionInput.py:173 #: ./photofilmstrip/gui/DlgPositionInput.py:215 msgid "Size:" msgstr "" #: ./photofilmstrip/gui/DlgPositionInput.py:191 msgid "End position" msgstr "" #: ./photofilmstrip/gui/DlgPositionInput.py:233 msgid "Reset" msgstr "" #: ./photofilmstrip/gui/DlgPositionInput.py:252 msgid "Adjust motion positions directly" msgstr "" #: ./photofilmstrip/gui/DlgRender.py:96 msgid "Render project" msgstr "" #: ./photofilmstrip/gui/DlgRender.py:107 msgid "Format:" msgstr "" #: ./photofilmstrip/gui/DlgRender.py:122 msgid "Properties" msgstr "" #: ./photofilmstrip/gui/DlgRender.py:127 msgid "Profile:" msgstr "" #: ./photofilmstrip/gui/DlgRender.py:136 msgid "Draft" msgstr "" #: ./photofilmstrip/gui/DlgRender.py:152 msgid "&Start" msgstr "" #: ./photofilmstrip/gui/DlgRender.py:164 msgid "Configure output and start render process" msgstr "" #: ./photofilmstrip/gui/DlgRendererProps.py:50 msgid "Property" msgstr "" #: ./photofilmstrip/gui/DlgRendererProps.py:52 msgid "Value" msgstr "" #: ./photofilmstrip/gui/DlgRendererProps.py:71 msgid "Output properties" msgstr "" #: ./photofilmstrip/gui/DlgRendererProps.py:113 msgid "Edit extended output properties" msgstr "" #: ./photofilmstrip/gui/DlgRendererProps.py:147 msgid "Edit property" msgstr "" #: ./photofilmstrip/gui/FrmMain.py:83 msgid "Welcome" msgstr "" #: ./photofilmstrip/gui/FrmMain.py:85 msgid "Job queue" msgstr "" #: ./photofilmstrip/gui/FrmMain.py:141 msgid "Rendering in progress..." msgstr "" #: ./photofilmstrip/gui/FrmMain.py:234 ./photofilmstrip/gui/PnlWelcome.py:57 msgid "Create new slideshow" msgstr "" #: ./photofilmstrip/gui/FrmMain.py:241 msgid "Create new timelapse" msgstr "" #: ./photofilmstrip/gui/FrmMain.py:249 msgid "Select %s-Project" msgstr "" #: ./photofilmstrip/gui/FrmMain.py:251 msgid "Files" msgstr "" #: ./photofilmstrip/gui/FrmMain.py:289 msgid "You must restart %s for your new language setting to take effect." msgstr "" #: ./photofilmstrip/gui/FrmMain.py:300 msgid "PhotoFilmStrip creates movies out of your pictures in just 3 steps. First select your photos, customize the motion path and render the video. There are several output possibilities for VCD, SVCD, DVD up to FULL-HD." msgstr "" #: ./photofilmstrip/gui/FrmMain.py:303 msgid "online" msgstr "" #: ./photofilmstrip/gui/FrmMain.py:374 msgid "Invalid %(app)s-Project: %(file)s" msgstr "" #: ./photofilmstrip/gui/PnlAddPics.py:50 ./photofilmstrip/gui/PnlWelcome.py:30 msgid "Welcome to PhotoFilmStrip" msgstr "" #: ./photofilmstrip/gui/PnlAddPics.py:52 msgid "" "Drag some pictures onto this text or\n" "click the button below\n" "to add pictures to your new PhotoFilmStrip." msgstr "" #: ./photofilmstrip/gui/PnlEditPicture.py:142 msgid "Settings" msgstr "" #: ./photofilmstrip/gui/PnlEditPicture.py:146 msgid "Rotation:" msgstr "" #: ./photofilmstrip/gui/PnlEditPicture.py:166 msgid "Effect:" msgstr "" #: ./photofilmstrip/gui/PnlEditPicture.py:180 msgid "Process" msgstr "" #: ./photofilmstrip/gui/PnlEditPicture.py:184 msgid "Movement:" msgstr "" #: ./photofilmstrip/gui/PnlEditPicture.py:196 #: ./photofilmstrip/gui/PnlEditPicture.py:212 #: ./photofilmstrip/gui/PnlEditPicture.py:359 msgid "sec" msgstr "" #: ./photofilmstrip/gui/PnlEditPicture.py:200 msgid "Transition:" msgstr "" #: ./photofilmstrip/gui/PnlEditPicture.py:220 msgid "Subtitle" msgstr "" #: ./photofilmstrip/gui/PnlEditPicture.py:240 msgid "Linear" msgstr "" #: ./photofilmstrip/gui/PnlEditPicture.py:241 msgid "Accelerated" msgstr "" #: ./photofilmstrip/gui/PnlEditPicture.py:242 msgid "Delayed" msgstr "" #: ./photofilmstrip/gui/PnlEditPicture.py:250 msgid "No effect" msgstr "" #: ./photofilmstrip/gui/PnlEditPicture.py:251 msgid "Black and White" msgstr "" #: ./photofilmstrip/gui/PnlEditPicture.py:252 msgid "Sepia tone" msgstr "" #: ./photofilmstrip/gui/PnlEditPicture.py:258 msgid "None" msgstr "" #: ./photofilmstrip/gui/PnlEditPicture.py:259 msgid "Fade" msgstr "" #: ./photofilmstrip/gui/PnlEditPicture.py:260 msgid "Roll" msgstr "" #: ./photofilmstrip/gui/PnlEditPicture.py:354 msgid "fpp" msgstr "" #: ./photofilmstrip/gui/PnlEditPicture.py:355 msgid "frames per picture - the number of frames each picture will be shown" msgstr "" #: ./photofilmstrip/gui/PnlEditorPage.py:26 msgid "Could not save the file '%(file)s': %(errMsg)s" msgstr "" #: ./photofilmstrip/gui/PnlEditorPage.py:45 msgid "New file" msgstr "" #: ./photofilmstrip/gui/PnlEditorPage.py:48 msgid "'%s' has been modified. Save changes?" msgstr "" #: ./photofilmstrip/gui/PnlEditorPage.py:74 msgid "Save %s" msgstr "" #: ./photofilmstrip/gui/PnlEditorPage.py:77 msgid "File" msgstr "" #: ./photofilmstrip/gui/PnlEditorPage.py:87 msgid "Overwrite existing file '%s'?" msgstr "" #: ./photofilmstrip/gui/PnlPfsProject.py:118 #: ./photofilmstrip/gui/PnlPfsProject.py:120 msgid "Set motion start to end" msgstr "" #: ./photofilmstrip/gui/PnlPfsProject.py:122 #: ./photofilmstrip/gui/PnlPfsProject.py:124 msgid "Set motion end to start" msgstr "" #: ./photofilmstrip/gui/PnlPfsProject.py:126 #: ./photofilmstrip/gui/PnlPfsProject.py:128 msgid "Swap motion" msgstr "" #: ./photofilmstrip/gui/PnlPfsProject.py:131 #: ./photofilmstrip/gui/PnlPfsProject.py:133 msgid "Adjust motion manual" msgstr "" #: ./photofilmstrip/gui/PnlPfsProject.py:136 #: ./photofilmstrip/gui/PnlPfsProject.py:138 msgid "Preserve image dimension" msgstr "" #: ./photofilmstrip/gui/PnlPfsProject.py:294 msgid "&Import Pictures" msgstr "" #: ./photofilmstrip/gui/PnlPfsProject.py:299 msgid "Move picture &left" msgstr "" #: ./photofilmstrip/gui/PnlPfsProject.py:303 msgid "Move picture &right" msgstr "" #: ./photofilmstrip/gui/PnlPfsProject.py:308 msgid "R&emove Picture" msgstr "" #: ./photofilmstrip/gui/PnlPfsProject.py:313 msgid "Rotate &clockwise" msgstr "" #: ./photofilmstrip/gui/PnlPfsProject.py:317 msgid "Rotate counter clock&wise" msgstr "" #: ./photofilmstrip/gui/PnlPfsProject.py:322 msgid "Random &motion" msgstr "" #: ./photofilmstrip/gui/PnlPfsProject.py:326 msgid "Centralize m&otion" msgstr "" #: ./photofilmstrip/gui/PnlPfsProject.py:384 msgid "Export slideshow" msgstr "" #: ./photofilmstrip/gui/PnlPfsProject.py:387 #: ./photofilmstrip/gui/PnlPfsProject.py:400 msgid "Portable slideshow" msgstr "" #: ./photofilmstrip/gui/PnlPfsProject.py:398 msgid "Import Slideshow" msgstr "" #: ./photofilmstrip/gui/PnlPfsProject.py:409 msgid "Import images" msgstr "" #: ./photofilmstrip/gui/PnlPfsProject.py:411 msgid "Image files" msgstr "" #: ./photofilmstrip/gui/PnlPfsProject.py:654 msgid "Audio file '%s' does not exist! Continue anyway?" msgstr "" #: ./photofilmstrip/gui/PnlPfsProject.py:655 msgid "Warning" msgstr "" #: ./photofilmstrip/gui/PnlSlideshow.py:30 msgid "&Properties" msgstr "" #: ./photofilmstrip/gui/PnlSlideshow.py:39 #: ./photofilmstrip/gui/PnlSlideshow.py:40 #: ./photofilmstrip/gui/PnlTimelapse.py:25 #: ./photofilmstrip/gui/PnlTimelapse.py:26 msgid "Import Pictures" msgstr "" #: ./photofilmstrip/gui/PnlSlideshow.py:62 #: ./photofilmstrip/gui/PnlSlideshow.py:63 #: ./photofilmstrip/gui/PnlTimelapse.py:41 #: ./photofilmstrip/gui/PnlTimelapse.py:42 msgid "Render filmstrip" msgstr "" #: ./photofilmstrip/gui/PnlSlideshow.py:89 #: ./photofilmstrip/gui/PnlTimelapse.py:66 msgid "Images" msgstr "" #: ./photofilmstrip/gui/PnlSlideshow.py:94 msgid "Duration" msgstr "" #: ./photofilmstrip/gui/PnlTimelapse.py:69 msgid "Frames" msgstr "" #: ./photofilmstrip/gui/PnlTimelapse.py:92 msgid "The picture counter is not increasing: %s" msgstr "" #: ./photofilmstrip/gui/PnlTimelapse.py:110 msgid "Filename '%s' does not match a number pattern which is necessary for a time lapse slide show!" msgstr "" #: ./photofilmstrip/gui/PnlWelcome.py:37 #: ./photofilmstrip/gui/PnlWelcome.py:103 msgid "Recent projects" msgstr "" #: ./photofilmstrip/gui/PnlWelcome.py:62 msgid "Open existing project" msgstr "" #: ./photofilmstrip/gui/PnlWelcome.py:106 msgid "How to start..." msgstr "" #: ./photofilmstrip/gui/PnlWelcome.py:107 msgid "Create a new project or load an existing one." msgstr "" #: ./photofilmstrip/gui/PnlWelcome.py:138 msgid "Update available" msgstr "" #: ./photofilmstrip/gui/PnlWelcome.py:141 msgid "The following changes has been made:" msgstr "" #: ./photofilmstrip/gui/WxProjectFile.py:59 msgid "Loading project %s" msgstr "" #: ./photofilmstrip/gui/WxProjectFile.py:75 msgid "Saving project %s" msgstr "" #: ./photofilmstrip/gui/WxProjectFile.py:100 msgid "Some images does not exist in the folder '%s' anymore. If the files has moved you can select the new path. Do you want to select a new path?" msgstr "" #: ./photofilmstrip/lib/jobimpl/DlgJobVisual.py:73 msgid "Elapsed time" msgstr "" #: ./photofilmstrip/lib/jobimpl/DlgJobVisual.py:85 msgid "Remaining time" msgstr "" #: ./photofilmstrip/lib/jobimpl/DlgJobVisual.py:203 msgid "Unknown" msgstr "" #: ./photofilmstrip/lib/jobimpl/PnlJobManager.py:50 msgid "&Clear list" msgstr "" #: ./photofilmstrip/lib/jobimpl/PnlJobVisual.py:127 msgid "Abort" msgstr "" #: ./photofilmstrip/lib/jobimpl/PnlJobVisual.py:133 msgid "Remove from list" msgstr "" #: ./photofilmstrip/lib/jobimpl/PnlJobVisual.py:223 msgid "Abort selected process?" msgstr "" #: ./photofilmstrip/lib/jobimpl/VisualJob.py:29 #: ./photofilmstrip/lib/jobimpl/VisualJobMixin.py:25 msgid "Waiting..." msgstr "" #: ./photofilmstrip/lib/jobimpl/VisualJob.py:68 #: ./photofilmstrip/lib/jobimpl/VisualJob.py:85 #: ./photofilmstrip/lib/jobimpl/VisualJobMixin.py:60 msgid "Aborted" msgstr "" #: ./photofilmstrip/lib/jobimpl/VisualJob.py:70 msgid "Done" msgstr "" #: ./photofilmstrip/lib/jobimpl/VisualJob.py:79 msgid "Aborting..." msgstr "" #: ./photofilmstrip/uwp/UwpService.py:76 msgid "Slideshow created!" msgstr "" photofilmstrip-3.7.2/po/nl.po0000644000232200023220000007164413560357351016567 0ustar debalancedebalance# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR ORGANIZATION # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PhotoFilmStrip\n" "POT-Creation-Date: 2018-11-07 22:03+CET\n" "PO-Revision-Date: 2011-07-10 13:36+0100\n" "Last-Translator: Jens Göpfert \n" "Language-Team: Jens Göpfert \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: pygettext.py 1.5\n" "X-Poedit-Language: English\n" "X-Poedit-Country: UNITED STATES\n" "X-Poedit-SourceCharset: utf-8\n" #: photofilmstrip/action/ActionAutoPath.py:23 #: photofilmstrip/gui/PnlPfsProject.py:115 msgid "Random motion" msgstr "Willekeurige bewegingen" #: photofilmstrip/action/ActionCenterPath.py:21 msgid "Centralize motion" msgstr "" #: photofilmstrip/action/ActionI18N.py:24 #: photofilmstrip/gui/ActionManager.py:170 msgid "Language" msgstr "Taal" #: photofilmstrip/action/ActionOpenFolder.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:28 msgid "Open folder" msgstr "Map openen" #: photofilmstrip/action/ActionPlayVideo.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:22 msgid "Play video" msgstr "Video afspelen" #: photofilmstrip/action/ActionRender.py:37 #, fuzzy msgid "Start" msgstr "&Start" #: photofilmstrip/cli/Main.py:46 photofilmstrip/cli/Main.py:196 msgid "all done" msgstr "alles verwerkt" #: photofilmstrip/cli/Main.py:64 msgid "processing project" msgstr "bewerken project" #: photofilmstrip/cli/Main.py:65 msgid "using renderer" msgstr "gebruik renderer" #: photofilmstrip/cli/Main.py:66 msgid "output format" msgstr "uitvoer formaat" #: photofilmstrip/cli/Main.py:69 msgid "framerate" msgstr "aantal beelden p/s" #: photofilmstrip/cli/Main.py:103 msgid "specifies the project file" msgstr "specificeert het project bestand" #: photofilmstrip/cli/Main.py:104 msgid "The path where to save the output files. Use - for stdout." msgstr "" "Het pad waar de uitvoer bestanden worden opgeslagen. In gebruik - voor " "standaard uitvoer." #: photofilmstrip/cli/Main.py:106 photofilmstrip/cli/Main.py:129 msgid "Option videonorm is deprecated, use an appropriate profile!" msgstr "" #: photofilmstrip/cli/Main.py:108 msgid "enable draft mode" msgstr "ontwerp-modus toestaan" #: photofilmstrip/cli/Main.py:108 photofilmstrip/gui/DlgRender.py:167 msgid "" "Activate this option to generate a preview of your PhotoFilmStrip. The " "rendering process will speed up dramatically, but results in lower quality." msgstr "" "Activeer deze optie om een voorbeeld van je PhotoFilmStrip te genereren. Het " "renderen zal drastisch versnellen, maar resulteert in een lagere kwaliteit." #: photofilmstrip/cli/Main.py:120 msgid "project file does not exist: %s" msgstr "project file bestaat niet: %s" #: photofilmstrip/cli/Main.py:124 msgid "no project file specified!" msgstr "geen projec tbestand gespecificeerd!" #: photofilmstrip/cli/Main.py:134 msgid "invalid format specified: %s" msgstr "ongeldig formaat opgegeven: %s" #: photofilmstrip/cli/Main.py:140 msgid "invalid profile specified: %s" msgstr "ongeldig profiel opgegeven: %s" #: photofilmstrip/cli/Main.py:146 #, fuzzy msgid "cannot load project" msgstr "kan fotofilmstrip niet laden" #: photofilmstrip/cli/Main.py:159 msgid "cannot create output path: %s" msgstr "kan uitvoer niet opslaan in: %s" #: photofilmstrip/cli/Main.py:169 photofilmstrip/gui/DlgConfigureAudio.py:231 #: photofilmstrip/gui/DlgConfigureAudio.py:253 msgid "Audio file '%s' does not exist!" msgstr "Geluidsbestand '%s' bestaat niet!" #: photofilmstrip/cli/Main.py:190 msgid "...aborted!" msgstr "...onderbroken!" #: photofilmstrip/core/BaseRenderer.py:50 msgid "Unknown property: %s" msgstr "Onbekende eigenschap: %s" #: photofilmstrip/core/BaseRenderer.py:58 msgid "" msgstr "" #: photofilmstrip/core/BaseRenderer.py:73 msgid "no" msgstr "nee" #: photofilmstrip/core/ProjectFile.py:222 #, fuzzy msgid "Saving '%s' ..." msgstr "Aan het laden '%s' ..." #: photofilmstrip/core/ProjectFile.py:276 msgid "Loading '%s' ..." msgstr "Aan het laden '%s' ..." #: photofilmstrip/core/RenderEngine.py:113 #: photofilmstrip/core/RenderEngine.py:201 msgid "processing transition %d/%d" msgstr "overgang verwerking %d/%d" #: photofilmstrip/core/RenderEngine.py:124 #: photofilmstrip/core/RenderEngine.py:210 msgid "processing image %d/%d" msgstr "bewerk foto %d/%d" #: photofilmstrip/core/renderer/CairoRenderer.py:35 msgid "Preview" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:50 msgid "GStreamer (python-gst-1.0) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:287 msgid "Bitrate must be a number!" msgstr "Bitrate moet een getal zijn!" #: photofilmstrip/core/renderer/GStreamerRenderer.py:455 #: photofilmstrip/core/renderer/GStreamerRenderer.py:531 #: photofilmstrip/core/renderer/GStreamerRenderer.py:601 #: photofilmstrip/core/renderer/GStreamerRenderer.py:690 #: photofilmstrip/core/renderer/GStreamerRenderer.py:730 #: photofilmstrip/core/renderer/GStreamerRenderer.py:779 msgid "libav (gstreamer1.0-libav) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:459 #: photofilmstrip/core/renderer/GStreamerRenderer.py:535 #: photofilmstrip/core/renderer/GStreamerRenderer.py:605 msgid "x264-Codec (gstreamer1.0-plugins-ugly) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:463 #: photofilmstrip/core/renderer/GStreamerRenderer.py:609 msgid "MKV-Muxer (gstreamer1.0-plugins-good) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:539 msgid "MP4-Muxer (gstreamer1.0-plugins-good) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:647 msgid "Theora-Codec (gstreamer1.0-plugins-base) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:651 msgid "Vorbis-Codec (gstreamer1.0-plugins-base) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:655 msgid "OGV-Muxer (gstreamer1.0-plugins-base) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:686 #: photofilmstrip/core/renderer/GStreamerRenderer.py:726 #: photofilmstrip/core/renderer/GStreamerRenderer.py:775 msgid "MPEG-1/2-Codec (gstreamer1.0-plugins-bad) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:694 #: photofilmstrip/core/renderer/GStreamerRenderer.py:734 #: photofilmstrip/core/renderer/GStreamerRenderer.py:783 msgid "MPEG-Muxer (gstreamer1.0-plugins-bad) required!" msgstr "" #: photofilmstrip/core/renderer/SingleFileRenderer.py:21 msgid "Single pictures" msgstr "per stuk foto's" #: photofilmstrip/core/tasks.py:48 msgid "generating subtitle" msgstr "genereren ondertiteling" #: photofilmstrip/gui/ActionManager.py:60 #: photofilmstrip/gui/ActionManager.py:190 msgid "&File" msgstr "&Bestand" #: photofilmstrip/gui/ActionManager.py:61 #: photofilmstrip/gui/ActionManager.py:191 msgid "&Edit" msgstr "&Wijzig" #: photofilmstrip/gui/ActionManager.py:62 #: photofilmstrip/gui/ActionManager.py:154 photofilmstrip/gui/DlgRender.py:141 #: photofilmstrip/gui/DlgRendererProps.py:86 msgid "&Help" msgstr "&Help" #: photofilmstrip/gui/ActionManager.py:76 msgid "New Slideshow" msgstr "" #: photofilmstrip/gui/ActionManager.py:81 msgid "Open" msgstr "" #: photofilmstrip/gui/ActionManager.py:87 msgid "Save" msgstr "" #: photofilmstrip/gui/ActionManager.py:97 #: photofilmstrip/gui/ActionManager.py:98 msgid "Show job queue" msgstr "" #: photofilmstrip/gui/ActionManager.py:108 #: photofilmstrip/gui/PnlSlideshow.py:25 msgid "Slideshow" msgstr "" #: photofilmstrip/gui/ActionManager.py:110 #: photofilmstrip/gui/PnlTimelapse.py:18 msgid "Timelapse" msgstr "" #: photofilmstrip/gui/ActionManager.py:116 msgid "New" msgstr "" #: photofilmstrip/gui/ActionManager.py:118 msgid "&Open" msgstr "" #: photofilmstrip/gui/ActionManager.py:123 msgid "&Save" msgstr "" #: photofilmstrip/gui/ActionManager.py:136 msgid "&Close" msgstr "&Afsluiten" #: photofilmstrip/gui/ActionManager.py:141 msgid "E&xit" msgstr "&Afsluiten" #: photofilmstrip/gui/ActionManager.py:173 msgid "&About" msgstr "&Over" #: photofilmstrip/gui/DlgBugReport.py:41 msgid "An unexpected error occured" msgstr "Er is een onverwachte fout opgetreden" #: photofilmstrip/gui/DlgBugReport.py:44 msgid "" "An unexpected error occured. Do you want to send this bug report to the " "developers of %s?" msgstr "" "Er is een onverwachte fout opgetreden. Wilt u dit foutrapport versturen naar " "de ontwikkelaars van %s?" #: photofilmstrip/gui/DlgBugReport.py:99 msgid "Bug-Report send. Thank you for your support." msgstr "Foutreport verstuurd. Dank voor uw steun." #: photofilmstrip/gui/DlgBugReport.py:100 photofilmstrip/gui/FrmMain.py:290 msgid "Information" msgstr "Informatie" #: photofilmstrip/gui/DlgBugReport.py:106 msgid "Sorry, this function is temporary not available.." msgstr "Sorry, deze functie is tijdelijk niet beschikbaar ..." #: photofilmstrip/gui/DlgBugReport.py:107 #: photofilmstrip/gui/DlgConfigureAudio.py:232 #: photofilmstrip/gui/DlgConfigureAudio.py:244 #: photofilmstrip/gui/DlgConfigureAudio.py:254 #: photofilmstrip/gui/DlgNewProject.py:156 #: photofilmstrip/gui/DlgNewProject.py:167 #: photofilmstrip/gui/DlgPicDurationByAudio.py:208 #: photofilmstrip/gui/DlgPicDurationByAudio.py:216 #: photofilmstrip/gui/FrmMain.py:376 photofilmstrip/gui/PnlPfsProject.py:468 #: photofilmstrip/gui/PnlTimelapse.py:113 msgid "Error" msgstr "Fout" #: photofilmstrip/gui/DlgConfigureAudio.py:55 msgid "Configure your audio files that are used as a background music." msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:90 msgid "Set the duration of your slideshow to fit your audio files" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:92 #: photofilmstrip/gui/DlgDuration.py:70 photofilmstrip/gui/DlgNewProject.py:84 #: photofilmstrip/gui/DlgPicDurationByAudio.py:50 #: photofilmstrip/gui/DlgPositionInput.py:238 #: photofilmstrip/gui/DlgRender.py:147 #: photofilmstrip/gui/DlgRendererProps.py:92 #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:97 msgid "&Cancel" msgstr "&Onderbreek" #: photofilmstrip/gui/DlgConfigureAudio.py:97 #: photofilmstrip/gui/DlgDuration.py:72 photofilmstrip/gui/DlgNewProject.py:86 #: photofilmstrip/gui/DlgPicDurationByAudio.py:51 #: photofilmstrip/gui/DlgPositionInput.py:244 #: photofilmstrip/gui/DlgRendererProps.py:97 msgid "&Ok" msgstr "&Ok" #: photofilmstrip/gui/DlgConfigureAudio.py:104 #: photofilmstrip/gui/DlgConfigureAudio.py:109 #: photofilmstrip/gui/PnlSlideshow.py:47 photofilmstrip/gui/PnlSlideshow.py:48 #: photofilmstrip/gui/PnlTimelapse.py:33 photofilmstrip/gui/PnlTimelapse.py:34 msgid "Configure music" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:138 msgid "Select music" msgstr "Selecteer muziek" #: photofilmstrip/gui/DlgConfigureAudio.py:140 msgid "Audio files" msgstr "Audio bestanden" #: photofilmstrip/gui/DlgConfigureAudio.py:243 #, fuzzy msgid "Audio file not supported!" msgstr "Geluidsbestand bestaat niet!" #: photofilmstrip/gui/DlgDuration.py:48 msgid "Total length:" msgstr "Totale lengte:" #: photofilmstrip/gui/DlgDuration.py:50 msgid "" "Overrides the duration of single pictures and gives the project this total " "length." msgstr "" "Overschrijft de duur van enkele foto's en geeft het project dit totale " "lengte." #: photofilmstrip/gui/DlgDuration.py:54 msgid "User defined:" msgstr "Door gebruiker gedefinieerd:" #: photofilmstrip/gui/DlgDuration.py:65 #, fuzzy msgid "Fit to audio files" msgstr "Audio bestanden" #: photofilmstrip/gui/DlgDuration.py:80 msgid "Slideshow duration" msgstr "" #: photofilmstrip/gui/DlgDuration.py:84 msgid "Configure duration of slideshow" msgstr "" #: photofilmstrip/gui/DlgNewProject.py:61 msgid "Project name:" msgstr "Project naam:" #: photofilmstrip/gui/DlgNewProject.py:66 msgid "Folder:" msgstr "Map:" #: photofilmstrip/gui/DlgNewProject.py:78 msgid "Aspect ratio:" msgstr "Aspect ratio:" #: photofilmstrip/gui/DlgNewProject.py:110 #, fuzzy msgid "Unnamed project" msgstr "kan fotofilmstrip niet laden" #: photofilmstrip/gui/DlgNewProject.py:116 msgid "My PhotoFilmStrips" msgstr "Mijn Fotofilmstrip" #: photofilmstrip/gui/DlgNewProject.py:126 msgid "Browse for folder" msgstr "Blader naar de map" #: photofilmstrip/gui/DlgNewProject.py:145 msgid "Folder does not exists! Do you want %s to create it?" msgstr "Map bestaat niet! Wilt u %s deze aanmaken?" #: photofilmstrip/gui/DlgNewProject.py:146 #: photofilmstrip/gui/PnlEditorPage.py:29 #: photofilmstrip/gui/PnlEditorPage.py:49 #: photofilmstrip/gui/PnlEditorPage.py:88 #: photofilmstrip/gui/WxProjectFile.py:101 #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:224 msgid "Question" msgstr "Vraag" #: photofilmstrip/gui/DlgNewProject.py:155 msgid "Cannot create folder: %s" msgstr "Kan map '%s' niet maken" #: photofilmstrip/gui/DlgNewProject.py:166 msgid "Cannot write into folder!" msgstr "Kan niet opslaan in de map!" #: photofilmstrip/gui/DlgNewProject.py:180 msgid "The project name must be filled." msgstr "De naam van het project moet worden ingevuld." #: photofilmstrip/gui/DlgNewProject.py:186 msgid "The project name contains invalid characters." msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:23 #: photofilmstrip/gui/PnlSlideshow.py:54 photofilmstrip/gui/PnlSlideshow.py:55 msgid "Adjust picture durations" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:26 msgid "Adjust picture durations to audio file" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:30 msgid "" "Find your picture duration by playing the audio file of your project and\n" "pressing the hit button to apply the current playing time." msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:43 #: photofilmstrip/gui/DlgPicDurationByAudio.py:153 msgid "Play" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:46 msgid "Hit" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:100 msgid "Stop" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:179 #, fuzzy msgid "Playing time" msgstr "Video afspelen" #: photofilmstrip/gui/DlgPicDurationByAudio.py:207 msgid "Your project does not have an audio file configured." msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:215 msgid "" "Your project uses more than one audio file. Currently the durations can be " "adjusted only for one audio file." msgstr "" #: photofilmstrip/gui/DlgPositionInput.py:140 msgid "Motion positions" msgstr "Bewegingsposities" #: photofilmstrip/gui/DlgPositionInput.py:147 msgid "Start position" msgstr "Start positie" #: photofilmstrip/gui/DlgPositionInput.py:155 #: photofilmstrip/gui/DlgPositionInput.py:199 msgid "Location:" msgstr "Locatie:" #: photofilmstrip/gui/DlgPositionInput.py:173 #: photofilmstrip/gui/DlgPositionInput.py:215 msgid "Size:" msgstr "Maat:" #: photofilmstrip/gui/DlgPositionInput.py:191 msgid "End position" msgstr "Eind positie" #: photofilmstrip/gui/DlgPositionInput.py:233 msgid "Reset" msgstr "Hertsel" #: photofilmstrip/gui/DlgPositionInput.py:252 msgid "Adjust motion positions directly" msgstr "Pas beweging posities direct aan" #: photofilmstrip/gui/DlgRender.py:96 #, fuzzy msgid "Render project" msgstr "Recente projecten" #: photofilmstrip/gui/DlgRender.py:107 msgid "Format:" msgstr "Formaat:" #: photofilmstrip/gui/DlgRender.py:122 msgid "Properties" msgstr "Eigenschappen" #: photofilmstrip/gui/DlgRender.py:127 msgid "Profile:" msgstr "Profiel:" #: photofilmstrip/gui/DlgRender.py:136 msgid "Draft" msgstr "Voorbeeld" #: photofilmstrip/gui/DlgRender.py:152 msgid "&Start" msgstr "&Start" #: photofilmstrip/gui/DlgRender.py:164 msgid "Configure output and start render process" msgstr "Configureer uitvoer en start bewerkingsproces" #: photofilmstrip/gui/DlgRendererProps.py:50 msgid "Property" msgstr "Eigenschap" #: photofilmstrip/gui/DlgRendererProps.py:52 msgid "Value" msgstr "Waarde" #: photofilmstrip/gui/DlgRendererProps.py:71 msgid "Output properties" msgstr "Uitvoer eigenschappen" #: photofilmstrip/gui/DlgRendererProps.py:113 msgid "Edit extended output properties" msgstr "Wijzig uitgebreide uitvoer eigenschappen" #: photofilmstrip/gui/DlgRendererProps.py:147 msgid "Edit property" msgstr "Wijzig eigenschap" #: photofilmstrip/gui/FrmMain.py:83 msgid "Welcome" msgstr "Welkom" #: photofilmstrip/gui/FrmMain.py:85 msgid "Job queue" msgstr "" #: photofilmstrip/gui/FrmMain.py:141 msgid "Rendering in progress..." msgstr "" #: photofilmstrip/gui/FrmMain.py:234 photofilmstrip/gui/PnlWelcome.py:57 #, fuzzy msgid "Create new slideshow" msgstr "Portable" #: photofilmstrip/gui/FrmMain.py:241 #, fuzzy msgid "Create new timelapse" msgstr "Maak een nieuw project" #: photofilmstrip/gui/FrmMain.py:249 msgid "Select %s-Project" msgstr "Selecteer %s-Project" #: photofilmstrip/gui/FrmMain.py:251 #, fuzzy msgid "Files" msgstr "&Bestand" #: photofilmstrip/gui/FrmMain.py:289 msgid "You must restart %s for your new language setting to take effect." msgstr "" "U moet opnieuw starten %s voor de nieuwe taalinstelling van kracht wordt." #: photofilmstrip/gui/FrmMain.py:300 msgid "" "PhotoFilmStrip creates movies out of your pictures in just 3 steps. First " "select your photos, customize the motion path and render the video. There " "are several output possibilities for VCD, SVCD, DVD up to FULL-HD." msgstr "" "Fotofilmstrip creëert films van uw foto's in slechts 3 stappen. Selecteer " "eerst uw foto's, aanpassen van de beweging pad en maak de video. Er zijn " "verschillende output mogelijkheden voor VCD, SVCD, DVD tot FULL-HD." #: photofilmstrip/gui/FrmMain.py:303 msgid "online" msgstr "online" #: photofilmstrip/gui/FrmMain.py:374 msgid "Invalid %(app)s-Project: %(file)s" msgstr "Ongeldige %(app)s-Project: %(file)s" #: photofilmstrip/gui/PnlAddPics.py:50 photofilmstrip/gui/PnlWelcome.py:30 msgid "Welcome to PhotoFilmStrip" msgstr "Welkom bij Fotofilmstrip " #: photofilmstrip/gui/PnlAddPics.py:52 msgid "" "Drag some pictures onto this text or\n" "click the button below\n" "to add pictures to your new PhotoFilmStrip." msgstr "" "Sleep een paar foto's op deze tekst of \n" "Klik op de onderstaande knop \n" "om foto's toe te voegen aan uw nieuwe Fotofilmstrip " #: photofilmstrip/gui/PnlEditPicture.py:142 msgid "Settings" msgstr "Instellingen" #: photofilmstrip/gui/PnlEditPicture.py:146 msgid "Rotation:" msgstr "Rotatie:" #: photofilmstrip/gui/PnlEditPicture.py:166 msgid "Effect:" msgstr "Effect:" #: photofilmstrip/gui/PnlEditPicture.py:180 msgid "Process" msgstr "Proces" #: photofilmstrip/gui/PnlEditPicture.py:184 msgid "Movement:" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:196 #: photofilmstrip/gui/PnlEditPicture.py:212 #: photofilmstrip/gui/PnlEditPicture.py:359 msgid "sec" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:200 msgid "Transition:" msgstr "Overgang:" #: photofilmstrip/gui/PnlEditPicture.py:220 msgid "Subtitle" msgstr "Ondertiteling" #: photofilmstrip/gui/PnlEditPicture.py:240 msgid "Linear" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:241 msgid "Accelerated" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:242 msgid "Delayed" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:250 msgid "No effect" msgstr "Geen effect" #: photofilmstrip/gui/PnlEditPicture.py:251 msgid "Black and White" msgstr "Zwart en Wit" #: photofilmstrip/gui/PnlEditPicture.py:252 msgid "Sepia tone" msgstr "Sepia kleur" #: photofilmstrip/gui/PnlEditPicture.py:258 msgid "None" msgstr "Geen" #: photofilmstrip/gui/PnlEditPicture.py:259 msgid "Fade" msgstr "Vervagen" #: photofilmstrip/gui/PnlEditPicture.py:260 msgid "Roll" msgstr "Rollen" #: photofilmstrip/gui/PnlEditPicture.py:354 msgid "fpp" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:355 msgid "frames per picture - the number of frames each picture will be shown" msgstr "" #: photofilmstrip/gui/PnlEditorPage.py:26 msgid "Could not save the file '%(file)s': %(errMsg)s" msgstr "Kon bestand '%(file)s' niet opslaan: %(errMsg)s" #: photofilmstrip/gui/PnlEditorPage.py:45 msgid "New file" msgstr "" #: photofilmstrip/gui/PnlEditorPage.py:48 msgid "'%s' has been modified. Save changes?" msgstr "'%s' is gewijzigd. Wijzigingen opslaan?" #: photofilmstrip/gui/PnlEditorPage.py:74 #, fuzzy msgid "Save %s" msgstr "Opslaan '%s'-Project" #: photofilmstrip/gui/PnlEditorPage.py:77 #, fuzzy msgid "File" msgstr "&Bestand" #: photofilmstrip/gui/PnlEditorPage.py:87 msgid "Overwrite existing file '%s'?" msgstr "Overschrijf bestaand bestand '%s'?" #: photofilmstrip/gui/PnlPfsProject.py:118 #: photofilmstrip/gui/PnlPfsProject.py:120 msgid "Set motion start to end" msgstr "Zet begin beweging aan het eind" #: photofilmstrip/gui/PnlPfsProject.py:122 #: photofilmstrip/gui/PnlPfsProject.py:124 msgid "Set motion end to start" msgstr "Zet eind beweging aan het begin" #: photofilmstrip/gui/PnlPfsProject.py:126 #: photofilmstrip/gui/PnlPfsProject.py:128 #, fuzzy msgid "Swap motion" msgstr "Willekeurige bewegingen" #: photofilmstrip/gui/PnlPfsProject.py:131 #: photofilmstrip/gui/PnlPfsProject.py:133 msgid "Adjust motion manual" msgstr "Beweging handmatig instellen" #: photofilmstrip/gui/PnlPfsProject.py:136 #: photofilmstrip/gui/PnlPfsProject.py:138 msgid "Preserve image dimension" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:294 msgid "&Import Pictures" msgstr "&Importeer foto's" #: photofilmstrip/gui/PnlPfsProject.py:299 msgid "Move picture &left" msgstr "Verplaats foto & links" #: photofilmstrip/gui/PnlPfsProject.py:303 msgid "Move picture &right" msgstr "Verplaats foto &rechts" #: photofilmstrip/gui/PnlPfsProject.py:308 #, fuzzy msgid "R&emove Picture" msgstr "&Verwijder foto" #: photofilmstrip/gui/PnlPfsProject.py:313 msgid "Rotate &clockwise" msgstr "Roteer &Rechtsom" #: photofilmstrip/gui/PnlPfsProject.py:317 msgid "Rotate counter clock&wise" msgstr "Roteer &Linksom" #: photofilmstrip/gui/PnlPfsProject.py:322 #, fuzzy msgid "Random &motion" msgstr "Willekeurige bewegingen" #: photofilmstrip/gui/PnlPfsProject.py:326 msgid "Centralize m&otion" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:384 msgid "Export slideshow" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:387 #: photofilmstrip/gui/PnlPfsProject.py:400 #, fuzzy msgid "Portable slideshow" msgstr "Portable" #: photofilmstrip/gui/PnlPfsProject.py:398 #, fuzzy msgid "Import Slideshow" msgstr "Importeer foto's" #: photofilmstrip/gui/PnlPfsProject.py:409 msgid "Import images" msgstr "Importeer foto's" #: photofilmstrip/gui/PnlPfsProject.py:411 #, fuzzy msgid "Image files" msgstr "Afbeeldings bestanden" #: photofilmstrip/gui/PnlPfsProject.py:654 msgid "Audio file '%s' does not exist! Continue anyway?" msgstr "Geluid-bestand '%s' bestaat niet! Toch doorgaan?" #: photofilmstrip/gui/PnlPfsProject.py:655 msgid "Warning" msgstr "Waarschuwing" #: photofilmstrip/gui/PnlSlideshow.py:30 msgid "&Properties" msgstr "&Eigenschappen" #: photofilmstrip/gui/PnlSlideshow.py:39 photofilmstrip/gui/PnlSlideshow.py:40 #: photofilmstrip/gui/PnlTimelapse.py:25 photofilmstrip/gui/PnlTimelapse.py:26 msgid "Import Pictures" msgstr "Importeer Foto's" #: photofilmstrip/gui/PnlSlideshow.py:62 photofilmstrip/gui/PnlSlideshow.py:63 #: photofilmstrip/gui/PnlTimelapse.py:41 photofilmstrip/gui/PnlTimelapse.py:42 msgid "Render filmstrip" msgstr "Render filmstrip" #: photofilmstrip/gui/PnlSlideshow.py:89 photofilmstrip/gui/PnlTimelapse.py:66 msgid "Images" msgstr "Foto's" #: photofilmstrip/gui/PnlSlideshow.py:94 msgid "Duration" msgstr "Tijdsduur" #: photofilmstrip/gui/PnlTimelapse.py:69 msgid "Frames" msgstr "" #: photofilmstrip/gui/PnlTimelapse.py:92 msgid "The picture counter is not increasing: %s" msgstr "" #: photofilmstrip/gui/PnlTimelapse.py:110 msgid "" "Filename '%s' does not match a number pattern which is necessary for a time " "lapse slide show!" msgstr "" #: photofilmstrip/gui/PnlWelcome.py:37 photofilmstrip/gui/PnlWelcome.py:103 msgid "Recent projects" msgstr "Recente projecten" #: photofilmstrip/gui/PnlWelcome.py:62 msgid "Open existing project" msgstr "Open bestaand project" #: photofilmstrip/gui/PnlWelcome.py:106 msgid "How to start..." msgstr "Hoe te beginnen" #: photofilmstrip/gui/PnlWelcome.py:107 msgid "Create a new project or load an existing one." msgstr "Maak een nieuw project of laad een bestaand project" #: photofilmstrip/gui/PnlWelcome.py:138 msgid "Update available" msgstr "Update beschikbaar" #: photofilmstrip/gui/PnlWelcome.py:141 msgid "The following changes has been made:" msgstr "De volgende wijzigingen zijn gemaakt" #: photofilmstrip/gui/WxProjectFile.py:59 #, fuzzy msgid "Loading project %s" msgstr "Laad Project" #: photofilmstrip/gui/WxProjectFile.py:75 #, fuzzy msgid "Saving project %s" msgstr "Bewaar Project" #: photofilmstrip/gui/WxProjectFile.py:100 msgid "" "Some images does not exist in the folder '%s' anymore. If the files has " "moved you can select the new path. Do you want to select a new path?" msgstr "" "Sommige afbeeldingen bestaat niet meer in de map '%s' . Als de bestanden " "zijn verplaatst kunt u nu het nieuwe pad. Wilt u een nieuw pad te kiezen?" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:73 msgid "Elapsed time" msgstr "" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:85 msgid "Remaining time" msgstr "" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:203 msgid "Unknown" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobManager.py:50 msgid "&Clear list" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:127 msgid "Abort" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:133 msgid "Remove from list" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:223 #, fuzzy msgid "Abort selected process?" msgstr "Onderbreek huidige bewerking?" #: photofilmstrip/lib/jobimpl/VisualJob.py:29 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:25 #, fuzzy msgid "Waiting..." msgstr "afbreken ..." #: photofilmstrip/lib/jobimpl/VisualJob.py:68 #: photofilmstrip/lib/jobimpl/VisualJob.py:85 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:60 #, fuzzy msgid "Aborted" msgstr "...onderbroken!" #: photofilmstrip/lib/jobimpl/VisualJob.py:70 msgid "Done" msgstr "" #: photofilmstrip/lib/jobimpl/VisualJob.py:79 #, fuzzy msgid "Aborting..." msgstr "afbreken ..." #: photofilmstrip/uwp/UwpService.py:76 msgid "Slideshow created!" msgstr "" #, fuzzy #~ msgid "Audio files:" #~ msgstr "Audio bestanden" #~ msgid "Project properties" #~ msgstr "Project eigenschappen" #~ msgid "PhotoFilmStrip project" #~ msgstr "Fotofilmstrip project" #~ msgid "Unnamed PhotoFilmStrip" #~ msgstr "Naamloos Fotofilmstrip" #~ msgid "Project" #~ msgstr "Project" #~ msgid "invalid videonorm specified: %s" #~ msgstr "ongeldige video-norm opgegeven: %s" #~ msgid "Error: %s" #~ msgstr "Fout: %s" #~ msgid "Please wait..." #~ msgstr "Een ogenblik ..." #~ msgid "initialize renderer" #~ msgstr "initialiseer renderer" #~ msgid "creating output..." #~ msgstr "uitvoer opslaan ..." #~ msgid "mencoder (mencoder) required!" #~ msgstr "mencoder (mencoder) verplicht!" #~ msgid "MPEG(1/2)-Video (MPG)" #~ msgstr "MPEG(1/2)-Video (MPG)" #~ msgid "MPEG format supports only VCD, SVCD and DVD profile!" #~ msgstr "MPEG-formaat ondersteunt alleen VCD, SVCD en DVD profiel!" #~ msgid "MPEG4-XVid/AC3 (AVI)" #~ msgstr "MPEG4-XVid/AC3 (AVI)" #, fuzzy #~ msgid "mencoder with MP3 support (mp3lame) required!" #~ msgstr "mencoder (mencoder) verplicht!" #~ msgid "MPEG4-XVid/MP3 (AVI)" #~ msgstr "MPEG4-XVid/MP3 (AVI)" #~ msgid "Flash-Video (FLV)" #~ msgstr "Flash-Video (FLV)" #~ msgid "Motion-JPEG (AVI)" #~ msgstr "Motion-JPEG (AVI)" #~ msgid "&Tools" #~ msgstr "&Hulpmiddelen" #~ msgid "New Project" #~ msgstr "Nieuw Project" #~ msgid "&New Project" #~ msgstr "&Nieuw Project" #~ msgid "&Open Project" #~ msgstr "&Open Project" #~ msgid "&Save Project" #~ msgstr "&Project opslaan" #~ msgid "&Close Project" #~ msgstr "$Sluit Project" #~ msgid "&Render filmstrip" #~ msgstr "&Render filmstrip" #~ msgid "Finalizing" #~ msgstr "Afwerken" #~ msgid "Choose your next action:" #~ msgstr "Kies uw volgende actie:" #~ msgid "Delete unfinished result" #~ msgstr "Verwijder onvoltooide resultaat" #~ msgid "Do nothing" #~ msgstr "Doe niets" #~ msgid "Show error again and send to developer." #~ msgstr "Toon fout opnieuw en stuur het naar de ontwikkelaar." #~ msgid "The rendering process was aborted." #~ msgstr "Het rendering proces werd afgebroken." #~ msgid "The rendering process was interrupted." #~ msgstr "rendering proces werd onderbroken." #~ msgid "The rendering process has been finished." #~ msgstr "Het rendering proces is voltooid." #~ msgid "Audio file:" #~ msgstr "Geluidsbestand" #~ msgid "Type:" #~ msgstr "Type:" #~ msgid "&Batch Job" #~ msgstr "&Partij verwerking" #~ msgid "" #~ "Project not saved yet. Please save the project first to create a batch " #~ "job!" #~ msgstr "" #~ "Project is nog niet opgeslagen. Bewaar eerst het project voor partij " #~ "verwerking op te starten!" #~ msgid "Batch file" #~ msgstr "Partij verwerkingsbestand" #~ msgid "Shell script" #~ msgstr "Shell script" #~ msgid "Select batch file" #~ msgstr "Kies partijverwerkings-bestand" #~ msgid "Export %s-Project" #~ msgstr "Exporteer '%s'-Project" #~ msgid "Import %s-Project" #~ msgstr "Importeer '%s'-Project" #~ msgid "Duration:" #~ msgstr "Tijdsduur:" #~ msgid "Browse" #~ msgstr "Verken" #~ msgid "Import image" #~ msgstr "Importeer afbeelding" #~ msgid "Please wait" #~ msgstr "Moment a.u.b." #~ msgid "Loading pictures..." #~ msgstr "Afbeedling laden" #~ msgid "Invalid audio file!" #~ msgstr "Ongeldige geluids bestand!" photofilmstrip-3.7.2/po/fr.po0000644000232200023220000007306213560357351016561 0ustar debalancedebalance# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR ORGANIZATION # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PhotoFilmStrip\n" "POT-Creation-Date: 2018-11-07 22:03+CET\n" "PO-Revision-Date: 2011-07-10 13:34+0100\n" "Last-Translator: Jens Göpfert \n" "Language-Team: Jens Göpfert \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: pygettext.py 1.5\n" "X-Poedit-Language: English\n" "X-Poedit-Country: UNITED STATES\n" "X-Poedit-SourceCharset: utf-8\n" #: photofilmstrip/action/ActionAutoPath.py:23 #: photofilmstrip/gui/PnlPfsProject.py:115 msgid "Random motion" msgstr "" #: photofilmstrip/action/ActionCenterPath.py:21 msgid "Centralize motion" msgstr "" #: photofilmstrip/action/ActionI18N.py:24 #: photofilmstrip/gui/ActionManager.py:170 msgid "Language" msgstr "" #: photofilmstrip/action/ActionOpenFolder.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:28 msgid "Open folder" msgstr "" #: photofilmstrip/action/ActionPlayVideo.py:20 #: photofilmstrip/gui/PnlRenderJobVisual.py:22 msgid "Play video" msgstr "" #: photofilmstrip/action/ActionRender.py:37 #, fuzzy msgid "Start" msgstr "&Démarrer " #: photofilmstrip/cli/Main.py:46 photofilmstrip/cli/Main.py:196 msgid "all done" msgstr "Terminer " #: photofilmstrip/cli/Main.py:64 msgid "processing project" msgstr "Traitement du projet " #: photofilmstrip/cli/Main.py:65 msgid "using renderer" msgstr "utilisation du moteur de rendu " #: photofilmstrip/cli/Main.py:66 msgid "output format" msgstr "Format de sortie" #: photofilmstrip/cli/Main.py:69 msgid "framerate" msgstr "Images par seconde " #: photofilmstrip/cli/Main.py:103 msgid "specifies the project file" msgstr "spécifie le fichier projet " #: photofilmstrip/cli/Main.py:104 #, fuzzy msgid "The path where to save the output files. Use - for stdout." msgstr "" "Le chemin où sauvegarder les fichiers de production. Si l'outil de " "restitution de fichier seul est utilisé, cette option peut être omise pour " "utiliser stdout." #: photofilmstrip/cli/Main.py:106 photofilmstrip/cli/Main.py:129 msgid "Option videonorm is deprecated, use an appropriate profile!" msgstr "" #: photofilmstrip/cli/Main.py:108 msgid "enable draft mode" msgstr "" #: photofilmstrip/cli/Main.py:108 photofilmstrip/gui/DlgRender.py:167 msgid "" "Activate this option to generate a preview of your PhotoFilmStrip. The " "rendering process will speed up dramatically, but results in lower quality." msgstr "" #: photofilmstrip/cli/Main.py:120 #, fuzzy msgid "project file does not exist: %s" msgstr "Le fichier de projet n'existe pas: %s " #: photofilmstrip/cli/Main.py:124 #, fuzzy msgid "no project file specified!" msgstr "pas de fichier projet définit!" #: photofilmstrip/cli/Main.py:134 msgid "invalid format specified: %s" msgstr "Format invalide spécifié: %s " #: photofilmstrip/cli/Main.py:140 msgid "invalid profile specified: %s" msgstr "Profil spécifié invalide: %s" #: photofilmstrip/cli/Main.py:146 #, fuzzy msgid "cannot load project" msgstr "ne peux charger PhotoFilmStrip " #: photofilmstrip/cli/Main.py:159 #, fuzzy msgid "cannot create output path: %s" msgstr "ne peux créer le chemin de sortie: %s " #: photofilmstrip/cli/Main.py:169 photofilmstrip/gui/DlgConfigureAudio.py:231 #: photofilmstrip/gui/DlgConfigureAudio.py:253 #, fuzzy msgid "Audio file '%s' does not exist!" msgstr "Le fichier audio n'existe pas!" #: photofilmstrip/cli/Main.py:190 msgid "...aborted!" msgstr "...abandonner! " #: photofilmstrip/core/BaseRenderer.py:50 msgid "Unknown property: %s" msgstr "Propriété inconnue: %s" #: photofilmstrip/core/BaseRenderer.py:58 msgid "" msgstr "" #: photofilmstrip/core/BaseRenderer.py:73 msgid "no" msgstr "" #: photofilmstrip/core/ProjectFile.py:222 #, fuzzy msgid "Saving '%s' ..." msgstr "Chargement '%s'" #: photofilmstrip/core/ProjectFile.py:276 msgid "Loading '%s' ..." msgstr "Chargement '%s'" #: photofilmstrip/core/RenderEngine.py:113 #: photofilmstrip/core/RenderEngine.py:201 msgid "processing transition %d/%d" msgstr "Traitement transition %d/%d" #: photofilmstrip/core/RenderEngine.py:124 #: photofilmstrip/core/RenderEngine.py:210 msgid "processing image %d/%d" msgstr "Traitement image %d/%d" #: photofilmstrip/core/renderer/CairoRenderer.py:35 msgid "Preview" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:50 msgid "GStreamer (python-gst-1.0) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:287 msgid "Bitrate must be a number!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:455 #: photofilmstrip/core/renderer/GStreamerRenderer.py:531 #: photofilmstrip/core/renderer/GStreamerRenderer.py:601 #: photofilmstrip/core/renderer/GStreamerRenderer.py:690 #: photofilmstrip/core/renderer/GStreamerRenderer.py:730 #: photofilmstrip/core/renderer/GStreamerRenderer.py:779 msgid "libav (gstreamer1.0-libav) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:459 #: photofilmstrip/core/renderer/GStreamerRenderer.py:535 #: photofilmstrip/core/renderer/GStreamerRenderer.py:605 msgid "x264-Codec (gstreamer1.0-plugins-ugly) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:463 #: photofilmstrip/core/renderer/GStreamerRenderer.py:609 msgid "MKV-Muxer (gstreamer1.0-plugins-good) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:539 msgid "MP4-Muxer (gstreamer1.0-plugins-good) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:647 msgid "Theora-Codec (gstreamer1.0-plugins-base) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:651 msgid "Vorbis-Codec (gstreamer1.0-plugins-base) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:655 msgid "OGV-Muxer (gstreamer1.0-plugins-base) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:686 #: photofilmstrip/core/renderer/GStreamerRenderer.py:726 #: photofilmstrip/core/renderer/GStreamerRenderer.py:775 msgid "MPEG-1/2-Codec (gstreamer1.0-plugins-bad) required!" msgstr "" #: photofilmstrip/core/renderer/GStreamerRenderer.py:694 #: photofilmstrip/core/renderer/GStreamerRenderer.py:734 #: photofilmstrip/core/renderer/GStreamerRenderer.py:783 msgid "MPEG-Muxer (gstreamer1.0-plugins-bad) required!" msgstr "" #: photofilmstrip/core/renderer/SingleFileRenderer.py:21 msgid "Single pictures" msgstr "Images fixes" #: photofilmstrip/core/tasks.py:48 msgid "generating subtitle" msgstr "Création des sous-titres " #: photofilmstrip/gui/ActionManager.py:60 #: photofilmstrip/gui/ActionManager.py:190 msgid "&File" msgstr "&Fichier" #: photofilmstrip/gui/ActionManager.py:61 #: photofilmstrip/gui/ActionManager.py:191 msgid "&Edit" msgstr "&Editer" #: photofilmstrip/gui/ActionManager.py:62 #: photofilmstrip/gui/ActionManager.py:154 photofilmstrip/gui/DlgRender.py:141 #: photofilmstrip/gui/DlgRendererProps.py:86 msgid "&Help" msgstr "&Aide" #: photofilmstrip/gui/ActionManager.py:76 msgid "New Slideshow" msgstr "" #: photofilmstrip/gui/ActionManager.py:81 msgid "Open" msgstr "" #: photofilmstrip/gui/ActionManager.py:87 msgid "Save" msgstr "" #: photofilmstrip/gui/ActionManager.py:97 #: photofilmstrip/gui/ActionManager.py:98 msgid "Show job queue" msgstr "" #: photofilmstrip/gui/ActionManager.py:108 #: photofilmstrip/gui/PnlSlideshow.py:25 msgid "Slideshow" msgstr "" #: photofilmstrip/gui/ActionManager.py:110 #: photofilmstrip/gui/PnlTimelapse.py:18 msgid "Timelapse" msgstr "" #: photofilmstrip/gui/ActionManager.py:116 msgid "New" msgstr "" #: photofilmstrip/gui/ActionManager.py:118 msgid "&Open" msgstr "" #: photofilmstrip/gui/ActionManager.py:123 msgid "&Save" msgstr "" #: photofilmstrip/gui/ActionManager.py:136 msgid "&Close" msgstr "&Fermer" #: photofilmstrip/gui/ActionManager.py:141 msgid "E&xit" msgstr "Q&uitter" #: photofilmstrip/gui/ActionManager.py:173 msgid "&About" msgstr "&A propos" #: photofilmstrip/gui/DlgBugReport.py:41 msgid "An unexpected error occured" msgstr "Une erreur imprévue est survenue" #: photofilmstrip/gui/DlgBugReport.py:44 msgid "" "An unexpected error occured. Do you want to send this bug report to the " "developers of %s?" msgstr "" "Une erreur imprévue est survenue. Vous vous envoyer le rapport d'incident au " "développeur %s?" #: photofilmstrip/gui/DlgBugReport.py:99 msgid "Bug-Report send. Thank you for your support." msgstr "Rapport de bug envoyé. Merci de votre soutien." #: photofilmstrip/gui/DlgBugReport.py:100 photofilmstrip/gui/FrmMain.py:290 msgid "Information" msgstr "Information" #: photofilmstrip/gui/DlgBugReport.py:106 msgid "Sorry, this function is temporary not available.." msgstr "Désolé cette fonction est temporairement indisponible.." #: photofilmstrip/gui/DlgBugReport.py:107 #: photofilmstrip/gui/DlgConfigureAudio.py:232 #: photofilmstrip/gui/DlgConfigureAudio.py:244 #: photofilmstrip/gui/DlgConfigureAudio.py:254 #: photofilmstrip/gui/DlgNewProject.py:156 #: photofilmstrip/gui/DlgNewProject.py:167 #: photofilmstrip/gui/DlgPicDurationByAudio.py:208 #: photofilmstrip/gui/DlgPicDurationByAudio.py:216 #: photofilmstrip/gui/FrmMain.py:376 photofilmstrip/gui/PnlPfsProject.py:468 #: photofilmstrip/gui/PnlTimelapse.py:113 msgid "Error" msgstr "Erreur" #: photofilmstrip/gui/DlgConfigureAudio.py:55 msgid "Configure your audio files that are used as a background music." msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:90 msgid "Set the duration of your slideshow to fit your audio files" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:92 #: photofilmstrip/gui/DlgDuration.py:70 photofilmstrip/gui/DlgNewProject.py:84 #: photofilmstrip/gui/DlgPicDurationByAudio.py:50 #: photofilmstrip/gui/DlgPositionInput.py:238 #: photofilmstrip/gui/DlgRender.py:147 #: photofilmstrip/gui/DlgRendererProps.py:92 #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:97 msgid "&Cancel" msgstr "&Annulé" #: photofilmstrip/gui/DlgConfigureAudio.py:97 #: photofilmstrip/gui/DlgDuration.py:72 photofilmstrip/gui/DlgNewProject.py:86 #: photofilmstrip/gui/DlgPicDurationByAudio.py:51 #: photofilmstrip/gui/DlgPositionInput.py:244 #: photofilmstrip/gui/DlgRendererProps.py:97 msgid "&Ok" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:104 #: photofilmstrip/gui/DlgConfigureAudio.py:109 #: photofilmstrip/gui/PnlSlideshow.py:47 photofilmstrip/gui/PnlSlideshow.py:48 #: photofilmstrip/gui/PnlTimelapse.py:33 photofilmstrip/gui/PnlTimelapse.py:34 msgid "Configure music" msgstr "" #: photofilmstrip/gui/DlgConfigureAudio.py:138 msgid "Select music" msgstr "Sélectionner la musique" #: photofilmstrip/gui/DlgConfigureAudio.py:140 #, fuzzy msgid "Audio files" msgstr "Fichiers audio" #: photofilmstrip/gui/DlgConfigureAudio.py:243 #, fuzzy msgid "Audio file not supported!" msgstr "Le fichier audio n'existe pas!" #: photofilmstrip/gui/DlgDuration.py:48 msgid "Total length:" msgstr "Longueur total:" #: photofilmstrip/gui/DlgDuration.py:50 #, fuzzy msgid "" "Overrides the duration of single pictures and gives the project this total " "length." msgstr "" "Dépasser la durée des images fixes donne cette longueur totale au " "photofilmstrip " #: photofilmstrip/gui/DlgDuration.py:54 msgid "User defined:" msgstr "Défini par l'utilisateur:" #: photofilmstrip/gui/DlgDuration.py:65 #, fuzzy msgid "Fit to audio files" msgstr "Fichier audio" #: photofilmstrip/gui/DlgDuration.py:80 msgid "Slideshow duration" msgstr "" #: photofilmstrip/gui/DlgDuration.py:84 msgid "Configure duration of slideshow" msgstr "" #: photofilmstrip/gui/DlgNewProject.py:61 #, fuzzy msgid "Project name:" msgstr "Projet " #: photofilmstrip/gui/DlgNewProject.py:66 msgid "Folder:" msgstr "" #: photofilmstrip/gui/DlgNewProject.py:78 msgid "Aspect ratio:" msgstr "" #: photofilmstrip/gui/DlgNewProject.py:110 #, fuzzy msgid "Unnamed project" msgstr "ne peux charger PhotoFilmStrip " #: photofilmstrip/gui/DlgNewProject.py:116 #, fuzzy msgid "My PhotoFilmStrips" msgstr "PhotoFilmStrip sans nom " #: photofilmstrip/gui/DlgNewProject.py:126 msgid "Browse for folder" msgstr "" #: photofilmstrip/gui/DlgNewProject.py:145 #, fuzzy msgid "Folder does not exists! Do you want %s to create it?" msgstr "Le chemin de destination n'existe pas! Voulez vous %s le créer?" #: photofilmstrip/gui/DlgNewProject.py:146 #: photofilmstrip/gui/PnlEditorPage.py:29 #: photofilmstrip/gui/PnlEditorPage.py:49 #: photofilmstrip/gui/PnlEditorPage.py:88 #: photofilmstrip/gui/WxProjectFile.py:101 #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:224 msgid "Question" msgstr "Question" #: photofilmstrip/gui/DlgNewProject.py:155 msgid "Cannot create folder: %s" msgstr "Ne peux créer le dossier: %s" #: photofilmstrip/gui/DlgNewProject.py:166 #, fuzzy msgid "Cannot write into folder!" msgstr "Ne peux écrire dans le dossier: %s" #: photofilmstrip/gui/DlgNewProject.py:180 msgid "The project name must be filled." msgstr "" #: photofilmstrip/gui/DlgNewProject.py:186 msgid "The project name contains invalid characters." msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:23 #: photofilmstrip/gui/PnlSlideshow.py:54 photofilmstrip/gui/PnlSlideshow.py:55 msgid "Adjust picture durations" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:26 msgid "Adjust picture durations to audio file" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:30 msgid "" "Find your picture duration by playing the audio file of your project and\n" "pressing the hit button to apply the current playing time." msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:43 #: photofilmstrip/gui/DlgPicDurationByAudio.py:153 msgid "Play" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:46 msgid "Hit" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:100 msgid "Stop" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:179 msgid "Playing time" msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:207 msgid "Your project does not have an audio file configured." msgstr "" #: photofilmstrip/gui/DlgPicDurationByAudio.py:215 msgid "" "Your project uses more than one audio file. Currently the durations can be " "adjusted only for one audio file." msgstr "" #: photofilmstrip/gui/DlgPositionInput.py:140 msgid "Motion positions" msgstr "" #: photofilmstrip/gui/DlgPositionInput.py:147 msgid "Start position" msgstr "" #: photofilmstrip/gui/DlgPositionInput.py:155 #: photofilmstrip/gui/DlgPositionInput.py:199 #, fuzzy msgid "Location:" msgstr "Rotation:" #: photofilmstrip/gui/DlgPositionInput.py:173 #: photofilmstrip/gui/DlgPositionInput.py:215 msgid "Size:" msgstr "" #: photofilmstrip/gui/DlgPositionInput.py:191 #, fuzzy msgid "End position" msgstr "Vitesse de transition:" #: photofilmstrip/gui/DlgPositionInput.py:233 msgid "Reset" msgstr "" #: photofilmstrip/gui/DlgPositionInput.py:252 msgid "Adjust motion positions directly" msgstr "" #: photofilmstrip/gui/DlgRender.py:96 #, fuzzy msgid "Render project" msgstr "Traitement du projet " #: photofilmstrip/gui/DlgRender.py:107 msgid "Format:" msgstr "Format:" #: photofilmstrip/gui/DlgRender.py:122 #, fuzzy msgid "Properties" msgstr "Propriété" #: photofilmstrip/gui/DlgRender.py:127 msgid "Profile:" msgstr "Profil:" #: photofilmstrip/gui/DlgRender.py:136 #, fuzzy msgid "Draft" msgstr "Durée " #: photofilmstrip/gui/DlgRender.py:152 msgid "&Start" msgstr "&Démarrer " #: photofilmstrip/gui/DlgRender.py:164 msgid "Configure output and start render process" msgstr "" #: photofilmstrip/gui/DlgRendererProps.py:50 msgid "Property" msgstr "Propriété" #: photofilmstrip/gui/DlgRendererProps.py:52 msgid "Value" msgstr "Valeur " #: photofilmstrip/gui/DlgRendererProps.py:71 #, fuzzy msgid "Output properties" msgstr "Propriété" #: photofilmstrip/gui/DlgRendererProps.py:113 msgid "Edit extended output properties" msgstr "" #: photofilmstrip/gui/DlgRendererProps.py:147 msgid "Edit property" msgstr "Éditer propriétés" #: photofilmstrip/gui/FrmMain.py:83 msgid "Welcome" msgstr "" #: photofilmstrip/gui/FrmMain.py:85 msgid "Job queue" msgstr "" #: photofilmstrip/gui/FrmMain.py:141 msgid "Rendering in progress..." msgstr "" #: photofilmstrip/gui/FrmMain.py:234 photofilmstrip/gui/PnlWelcome.py:57 #, fuzzy msgid "Create new slideshow" msgstr "Portable" #: photofilmstrip/gui/FrmMain.py:241 #, fuzzy msgid "Create new timelapse" msgstr "Nouveau projet " #: photofilmstrip/gui/FrmMain.py:249 msgid "Select %s-Project" msgstr "Sélectionner %s-Projet" #: photofilmstrip/gui/FrmMain.py:251 #, fuzzy msgid "Files" msgstr "&Fichier" #: photofilmstrip/gui/FrmMain.py:289 msgid "You must restart %s for your new language setting to take effect." msgstr "" #: photofilmstrip/gui/FrmMain.py:300 msgid "" "PhotoFilmStrip creates movies out of your pictures in just 3 steps. First " "select your photos, customize the motion path and render the video. There " "are several output possibilities for VCD, SVCD, DVD up to FULL-HD." msgstr "" "PhotoFilmStrip réalise des films a partir des vos images en juste trois " "étapes. Premièrement sélectionnez vos photos, vos effets et le rendu vidéo. " "Il y a plusieurs possibilités de formats, VCD, SVCD, DVD, jusqu'au FULL-HD." #: photofilmstrip/gui/FrmMain.py:303 msgid "online" msgstr "en ligne " #: photofilmstrip/gui/FrmMain.py:374 msgid "Invalid %(app)s-Project: %(file)s" msgstr "Projet %(app)s-invalide: %(file)s" #: photofilmstrip/gui/PnlAddPics.py:50 photofilmstrip/gui/PnlWelcome.py:30 msgid "Welcome to PhotoFilmStrip" msgstr "Bienvenue dans PhotoFilmStrip" #: photofilmstrip/gui/PnlAddPics.py:52 msgid "" "Drag some pictures onto this text or\n" "click the button below\n" "to add pictures to your new PhotoFilmStrip." msgstr "" "Glissez des images sur ce texte ou\n" "cliquez sur le bouton ci-dessous" #: photofilmstrip/gui/PnlEditPicture.py:142 msgid "Settings" msgstr "Configuration" #: photofilmstrip/gui/PnlEditPicture.py:146 msgid "Rotation:" msgstr "Rotation:" #: photofilmstrip/gui/PnlEditPicture.py:166 msgid "Effect:" msgstr "Effets:" #: photofilmstrip/gui/PnlEditPicture.py:180 msgid "Process" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:184 msgid "Movement:" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:196 #: photofilmstrip/gui/PnlEditPicture.py:212 #: photofilmstrip/gui/PnlEditPicture.py:359 msgid "sec" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:200 #, fuzzy msgid "Transition:" msgstr "Vitesse de transition:" #: photofilmstrip/gui/PnlEditPicture.py:220 msgid "Subtitle" msgstr "Sous-titres" #: photofilmstrip/gui/PnlEditPicture.py:240 msgid "Linear" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:241 msgid "Accelerated" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:242 msgid "Delayed" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:250 msgid "No effect" msgstr "Pas d'effets" #: photofilmstrip/gui/PnlEditPicture.py:251 msgid "Black and White" msgstr "Noir et blanc " #: photofilmstrip/gui/PnlEditPicture.py:252 msgid "Sepia tone" msgstr "Ton sépia" #: photofilmstrip/gui/PnlEditPicture.py:258 #, fuzzy msgid "None" msgstr "en ligne " #: photofilmstrip/gui/PnlEditPicture.py:259 msgid "Fade" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:260 msgid "Roll" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:354 msgid "fpp" msgstr "" #: photofilmstrip/gui/PnlEditPicture.py:355 msgid "frames per picture - the number of frames each picture will be shown" msgstr "" #: photofilmstrip/gui/PnlEditorPage.py:26 msgid "Could not save the file '%(file)s': %(errMsg)s" msgstr "Ne peux enregistrer le fichier '%(file)s': %(errMsg)s" #: photofilmstrip/gui/PnlEditorPage.py:45 msgid "New file" msgstr "" #: photofilmstrip/gui/PnlEditorPage.py:48 msgid "'%s' has been modified. Save changes?" msgstr "'%s' a été modifié. Enregistrer les changements?" #: photofilmstrip/gui/PnlEditorPage.py:74 #, fuzzy msgid "Save %s" msgstr "Enregistrer %s-projet " #: photofilmstrip/gui/PnlEditorPage.py:77 #, fuzzy msgid "File" msgstr "&Fichier" #: photofilmstrip/gui/PnlEditorPage.py:87 msgid "Overwrite existing file '%s'?" msgstr "Écraser le fichier existant '%s'? " #: photofilmstrip/gui/PnlPfsProject.py:118 #: photofilmstrip/gui/PnlPfsProject.py:120 msgid "Set motion start to end" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:122 #: photofilmstrip/gui/PnlPfsProject.py:124 msgid "Set motion end to start" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:126 #: photofilmstrip/gui/PnlPfsProject.py:128 msgid "Swap motion" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:131 #: photofilmstrip/gui/PnlPfsProject.py:133 msgid "Adjust motion manual" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:136 #: photofilmstrip/gui/PnlPfsProject.py:138 msgid "Preserve image dimension" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:294 msgid "&Import Pictures" msgstr "&Importer des images " #: photofilmstrip/gui/PnlPfsProject.py:299 msgid "Move picture &left" msgstr "Bouger l'image à&gauche " #: photofilmstrip/gui/PnlPfsProject.py:303 msgid "Move picture &right" msgstr "Bouger l'image à&droite " #: photofilmstrip/gui/PnlPfsProject.py:308 #, fuzzy msgid "R&emove Picture" msgstr "&Retirer image" #: photofilmstrip/gui/PnlPfsProject.py:313 msgid "Rotate &clockwise" msgstr "Rotation &horaire " #: photofilmstrip/gui/PnlPfsProject.py:317 msgid "Rotate counter clock&wise" msgstr "Rotation sens anti&horaire " #: photofilmstrip/gui/PnlPfsProject.py:322 #, fuzzy msgid "Random &motion" msgstr "Vitesse de transition:" #: photofilmstrip/gui/PnlPfsProject.py:326 msgid "Centralize m&otion" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:384 msgid "Export slideshow" msgstr "" #: photofilmstrip/gui/PnlPfsProject.py:387 #: photofilmstrip/gui/PnlPfsProject.py:400 #, fuzzy msgid "Portable slideshow" msgstr "Portable" #: photofilmstrip/gui/PnlPfsProject.py:398 #, fuzzy msgid "Import Slideshow" msgstr "Importer des images " #: photofilmstrip/gui/PnlPfsProject.py:409 msgid "Import images" msgstr "Importer des images " #: photofilmstrip/gui/PnlPfsProject.py:411 #, fuzzy msgid "Image files" msgstr "Fichiers image " #: photofilmstrip/gui/PnlPfsProject.py:654 #, fuzzy msgid "Audio file '%s' does not exist! Continue anyway?" msgstr "Le fichier audio n'existe pas!" #: photofilmstrip/gui/PnlPfsProject.py:655 msgid "Warning" msgstr "" #: photofilmstrip/gui/PnlSlideshow.py:30 #, fuzzy msgid "&Properties" msgstr "Propriété" #: photofilmstrip/gui/PnlSlideshow.py:39 photofilmstrip/gui/PnlSlideshow.py:40 #: photofilmstrip/gui/PnlTimelapse.py:25 photofilmstrip/gui/PnlTimelapse.py:26 msgid "Import Pictures" msgstr "Importer des images" #: photofilmstrip/gui/PnlSlideshow.py:62 photofilmstrip/gui/PnlSlideshow.py:63 #: photofilmstrip/gui/PnlTimelapse.py:41 photofilmstrip/gui/PnlTimelapse.py:42 msgid "Render filmstrip" msgstr "Rendu filmstrip " #: photofilmstrip/gui/PnlSlideshow.py:89 photofilmstrip/gui/PnlTimelapse.py:66 msgid "Images" msgstr "Images" #: photofilmstrip/gui/PnlSlideshow.py:94 msgid "Duration" msgstr "Durée " #: photofilmstrip/gui/PnlTimelapse.py:69 msgid "Frames" msgstr "" #: photofilmstrip/gui/PnlTimelapse.py:92 msgid "The picture counter is not increasing: %s" msgstr "" #: photofilmstrip/gui/PnlTimelapse.py:110 msgid "" "Filename '%s' does not match a number pattern which is necessary for a time " "lapse slide show!" msgstr "" #: photofilmstrip/gui/PnlWelcome.py:37 photofilmstrip/gui/PnlWelcome.py:103 #, fuzzy msgid "Recent projects" msgstr "Traitement du projet " #: photofilmstrip/gui/PnlWelcome.py:62 #, fuzzy msgid "Open existing project" msgstr "Traitement du projet " #: photofilmstrip/gui/PnlWelcome.py:106 msgid "How to start..." msgstr "" #: photofilmstrip/gui/PnlWelcome.py:107 msgid "Create a new project or load an existing one." msgstr "" #: photofilmstrip/gui/PnlWelcome.py:138 msgid "Update available" msgstr "" #: photofilmstrip/gui/PnlWelcome.py:141 #, fuzzy msgid "The following changes has been made:" msgstr "" "Une nouvelle version est disponible en ligne. Les changements suivants on " "été fait: " #: photofilmstrip/gui/WxProjectFile.py:59 #, fuzzy msgid "Loading project %s" msgstr "Charger projet" #: photofilmstrip/gui/WxProjectFile.py:75 #, fuzzy msgid "Saving project %s" msgstr "Enregistrer le projet sous " #: photofilmstrip/gui/WxProjectFile.py:100 msgid "" "Some images does not exist in the folder '%s' anymore. If the files has " "moved you can select the new path. Do you want to select a new path?" msgstr "" "Certaines images dans ce dossier n'existent '%s' plus. Si ces fichiers ont " "été déplacés vous pouvez sélectionner un nouveau chemin. Voulez vous " "sélectionner un nouveau chemin?" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:73 msgid "Elapsed time" msgstr "" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:85 msgid "Remaining time" msgstr "" #: photofilmstrip/lib/jobimpl/DlgJobVisual.py:203 msgid "Unknown" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobManager.py:50 msgid "&Clear list" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:127 msgid "Abort" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:133 msgid "Remove from list" msgstr "" #: photofilmstrip/lib/jobimpl/PnlJobVisual.py:223 #, fuzzy msgid "Abort selected process?" msgstr "Abandonner le processus en cour? " #: photofilmstrip/lib/jobimpl/VisualJob.py:29 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:25 #, fuzzy msgid "Waiting..." msgstr "abandon..." #: photofilmstrip/lib/jobimpl/VisualJob.py:68 #: photofilmstrip/lib/jobimpl/VisualJob.py:85 #: photofilmstrip/lib/jobimpl/VisualJobMixin.py:60 #, fuzzy msgid "Aborted" msgstr "...abandonner! " #: photofilmstrip/lib/jobimpl/VisualJob.py:70 msgid "Done" msgstr "" #: photofilmstrip/lib/jobimpl/VisualJob.py:79 #, fuzzy msgid "Aborting..." msgstr "abandon..." #: photofilmstrip/uwp/UwpService.py:76 msgid "Slideshow created!" msgstr "" #, fuzzy #~ msgid "Audio files:" #~ msgstr "Fichiers audio" #, fuzzy #~ msgid "Project properties" #~ msgstr "Propriété" #, fuzzy #~ msgid "PhotoFilmStrip project" #~ msgstr "PhotoFilmStrip sans nom " #~ msgid "Unnamed PhotoFilmStrip" #~ msgstr "PhotoFilmStrip sans nom " #~ msgid "Project" #~ msgstr "Projet " #~ msgid "invalid videonorm specified: %s" #~ msgstr "Norme vidéo spécifié invalide: %s " #~ msgid "Error: %s" #~ msgstr "Erreur: %s" #~ msgid "Please wait..." #~ msgstr "Attendez s.v.p... " #~ msgid "initialize renderer" #~ msgstr "Initialiser rendu " #~ msgid "creating output..." #~ msgstr "création sortie..." #~ msgid "mencoder (mencoder) required!" #~ msgstr "mencoder (mencoder) requis!" #~ msgid "MPEG(1/2)-Video (MPG)" #~ msgstr "Vidéo-MPEG1/2 (MPG)" #~ msgid "MPEG4-XVid/AC3 (AVI)" #~ msgstr "MPEG4-XVid/AC3 (AVI)" #, fuzzy #~ msgid "mencoder with MP3 support (mp3lame) required!" #~ msgstr "mencoder (mencoder) requis!" #~ msgid "MPEG4-XVid/MP3 (AVI)" #~ msgstr "MPEG4-XVid/MP3 (AVI)" #~ msgid "&Tools" #~ msgstr "&Outils" #~ msgid "New Project" #~ msgstr "Nouveau projet " #~ msgid "Save Project" #~ msgstr "Enregistrer le projet " #~ msgid "&New Project" #~ msgstr "&Nouveau projet " #~ msgid "&Open Project" #~ msgstr "&Ouvrir Projet" #~ msgid "&Save Project" #~ msgstr "&Enregistrer le projet " #, fuzzy #~ msgid "&Close Project" #~ msgstr "&Nouveau projet " #~ msgid "&Render filmstrip" #~ msgstr "&Rendu filmstrip " #~ msgid "Audio file:" #~ msgstr "Fichier audio:" #~ msgid "Type:" #~ msgstr "Type:" #~ msgid "&Batch Job" #~ msgstr "&Traitement par lots" #~ msgid "" #~ "Project not saved yet. Please save the project first to create a batch " #~ "job!" #~ msgstr "" #~ "Le projet n'est pas encore sauvegardé. S.v.p sauvegardez le projet afin " #~ "de créer un traitement par lot!" #~ msgid "Batch file" #~ msgstr "Fichier batch " #~ msgid "Shell script" #~ msgstr "Script shell " #~ msgid "Select batch file" #~ msgstr "Sélectionner fichier batch " #~ msgid "Export %s-Project" #~ msgstr "Exporter %s-Projet" #~ msgid "Import %s-Project" #~ msgstr "Importer %s-Projet" #~ msgid "Duration:" #~ msgstr "Durée:" #~ msgid "Browse" #~ msgstr "Chercher " #~ msgid "Import image" #~ msgstr "Importer une image " #~ msgid "Please wait" #~ msgstr "Attendez svp" #~ msgid "Loading pictures..." #~ msgstr "Chargement des images... " #~ msgid "Invalid audio file!" #~ msgstr "Fichier audio invalide! " #~ msgid "processing audiofile..." #~ msgstr "Traitement fichier audio..." #, fuzzy #~ msgid "Video clip (AVI)" #~ msgstr "Vidéo clip" #~ msgid "total length of the PhotoFilmStrip (seconds)" #~ msgstr "Longueur totale du PhotoFilmStrip (secondes) " #~ msgid "use audiofile as audiotrack (use --length to limit the movie length)" #~ msgstr "" #~ "Utiliser un fichier audio comme piste son (utiliser --lenght pour limiter " #~ "la longueur du film) " #~ msgid "no outputpath specified!" #~ msgstr "pas de chemin de destination spécifié!" #~ msgid "audio file does not exist: %s" #~ msgstr "Le fichier audio n'existe pas: %s" #, fuzzy #~ msgid "Directory:" #~ msgstr "Dossier de destination: " #, fuzzy #~ msgid "Select a directory" #~ msgstr "Dossier de destination: " #~ msgid "No media support found on this platform!" #~ msgstr "Aucun média trouver sur ce système " #~ msgid "Output" #~ msgstr "Sortie " #~ msgid "Translators" #~ msgstr "Traducteurs" #~ msgid "Open &recent" #~ msgstr "Ouvrir &récent " #~ msgid "Save Project &as" #~ msgstr "Enregistrer le projet &sous " #~ msgid "&Import Project" #~ msgstr "&Importer Projet " #~ msgid "&Export Project" #~ msgstr "&Exporter le projet " #~ msgid "Sec." #~ msgstr "Sec." #~ msgid "Output path is not empty! Use it anyway?" #~ msgstr "Le chemin de destination n'est pas vide! Utiliser quand même?" #~ msgid "New version available" #~ msgstr "Nouvelle version disponible " #~ msgid "Close" #~ msgstr "Fermer " #~ msgid "Goto download site" #~ msgstr "Aller au site de téléchargement " #~ msgid "Duration (sec):" #~ msgstr "Durée (sec):" #~ msgid "French:" #~ msgstr "Français:" #~ msgid "ppmtoy4m (mjpegtools) required!" #~ msgstr "ppmtoy4m (mjpegtools) est requis!" #~ msgid "mpeg2enc (mjpegtools) required!" #~ msgstr "mpeg2enc (mjpegtools) est requis!" photofilmstrip-3.7.2/Makefile0000644000232200023220000000125513560357351016627 0ustar debalancedebalance# # Makefile for PhotoFilmStrip # displayname = PhotoFilmStrip srcdir = . pkgdir = photofilmstrip all: clean test compile test: pylint --rcfile=.pylintrc --disable=W,R,C $(pkgdir) compile: python3 setup.py build sdist clean: if [ -e ./dist ] ; then rm -r ./dist ; fi find . -name "*.pyc" -exec rm {} ';' find . -name "*.pyo" -exec rm {} ';' find . -name "_scmInfo.py*" -exec rm {} ';' python3 setup.py clean update-po: pygettext -o "po/$(displayname).pot" -v "$(srcdir)/$(pkgdir)" find po/ -name "*.po" -exec msgmerge --backup=none --update {} "po/$(displayname).pot" ';' versioninfo: python3 -c "from photofilmstrip import Constants;print(Constants.APP_VERSION)"; \ photofilmstrip-3.7.2/setup.py0000644000232200023220000006406713560357352016714 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2011 Jens Goepfert # import glob import sys, os import sqlite3 import zipfile from distutils import log from distutils.command.build import build from distutils.command.clean import clean from distutils.command.sdist import sdist from distutils.core import setup from distutils.core import Command from distutils.dir_util import remove_tree from distutils.sysconfig import get_python_lib try: from sphinx.application import Sphinx except ImportError: Sphinx = None try: import py2exe import py2exe.dllfinder orig_determine_dll_type = py2exe.dllfinder.DllFinder.determine_dll_type def determine_dll_type(self, imagename): if imagename.lower().find("msvcr100.dll") != -1 or imagename.lower().find("msvcp100.dll") != -1: return "DLL" else: return orig_determine_dll_type(self, imagename) py2exe.dllfinder.DllFinder.determine_dll_type = determine_dll_type except ImportError: py2exe = None from photofilmstrip import Constants if os.getenv("ProgramFiles(x86)"): PROGRAMFILES = os.path.expandvars("%ProgramFiles(x86)%") else: PROGRAMFILES = os.path.expandvars("%ProgramFiles%") WORKDIR = os.path.dirname(os.path.abspath(sys.argv[0])) INNO = os.path.join(PROGRAMFILES, "Inno Setup 5", "ISCC.exe") MSGFMT = os.path.join(getattr(sys, "real_prefix", os.path.dirname(sys.executable)), "Tools", "i18n", "msgfmt.py") if os.path.isfile(MSGFMT): MSGFMT = [sys.executable, MSGFMT] else: MSGFMT = ["msgfmt"] class pfs_clean(clean): def run(self): clean.run(self) for directory in (os.path.join(WORKDIR, "build"), ): if os.path.exists(directory): remove_tree(directory, 1) for fname in (os.path.join(WORKDIR, "version.info"), os.path.join(WORKDIR, "MANIFEST"), ): if os.path.exists(fname): os.remove(fname) class pfs_scm_info(Command): description = "generates _scmInfo.py in source folder" user_options = [] sub_commands = [] def initialize_options(self): pass def finalize_options(self): pass def run(self): scmRev = os.getenv("SCM_REV") if not scmRev: # if not set in environment it hopefully was generated earlier # building deb with fakeroot has no SCM_REV var anymore try: import photofilmstrip._scmInfo scmRev = photofilmstrip._scmInfo.SCM_REV except ImportError: scmRev = "src" for target in getattr(self.distribution, "windows", []) + \ getattr(self.distribution, "console", []): target.Update(scmRev) if scmRev != "src": fd = open(os.path.join("photofilmstrip", "_scmInfo.py"), "w") fd.write("SCM_REV = \"%s\"\n" % scmRev) fd.close() class pfs_sdist(sdist): sub_commands = [ ('scm_info', lambda x: True), ] + sdist.sub_commands class pfs_docs(Command): description = "generates sphinx docs" user_options = [ ('config-dir=', 'c', 'Location of the configuration directory'), ('project=', None, 'The documented project\'s name'), ('version=', None, 'The short X.Y version'), ('release=', None, 'The full version, including alpha/beta/rc tags'), ('builder=', 'b', 'The builder (or builders) to use.') ] sub_commands = [] def initialize_options(self): self.config_dir = None self.project = '' self.version = '' self.release = '' self.builder = ['html'] def finalize_options(self): pass def run(self): build = self.get_finalized_command('build') build_dir = os.path.join(os.path.abspath(build.build_base), 'sphinx') doctree_dir = os.path.join(build_dir, 'doctrees') self.mkpath(build_dir) self.mkpath(doctree_dir) confoverrides = {} if self.project: confoverrides['project'] = self.project if self.version: confoverrides['version'] = self.version if self.release: confoverrides['release'] = self.release for builder in self.builder: builder_target_dir = os.path.join(build_dir, builder) self.mkpath(builder_target_dir) app = Sphinx(self.config_dir, self.config_dir, builder_target_dir, doctree_dir, builder, confoverrides) app.build() self.distribution.data_files.extend([ (os.path.join("share", "doc", "photofilmstrip"), glob.glob("docs/*.*")), (os.path.join("share", "doc", "photofilmstrip", "html"), glob.glob("build/sphinx/html/*.*")), (os.path.join("share", "doc", "photofilmstrip", "html", "_sources"), glob.glob("build/sphinx/html/_sources/*.*")), (os.path.join("share", "doc", "photofilmstrip", "html", "_static"), glob.glob("build/sphinx/html/_static/*.*")) ]) class pfs_build(build): sub_commands = [ ('scm_info', lambda x: True), ('build_sphinx', lambda x: True if Sphinx else False), ] + build.sub_commands def run(self): self._make_resources() self._make_locale() build.run(self) def _make_resources(self): try: from wx.tools.img2py import img2py except ImportError: log.warn("Cannot update image resources! Using images.py from source") return if sys.platform.startswith("linux") and os.getenv("DISPLAY") is None: log.warn("Cannot update image resources! img2py needs X") return imgDir = os.path.abspath(os.path.join("res", "icons")) if not os.path.exists(imgDir): return target = os.path.join("photofilmstrip", "res", "images.py") target_mtime = os.path.getmtime(target) imgResources = ( ("ICON_16", "photofilmstrip_16.png"), ("ICON_24", "photofilmstrip_24.png"), ("ICON_32", "photofilmstrip_32.png"), ("ICON_48", "photofilmstrip_48.png"), ("ICON_64", "photofilmstrip_64.png"), ("ICON_128", "photofilmstrip_128.png"), ("PROJECT_NEW_16", "project_new_16.png"), ("PROJECT_NEW_24", "project_new_24.png"), ("PROJECT_NEW_64", "project_new_64.png"), ("PROJECT_OPEN_16", "project_open_16.png"), ("PROJECT_OPEN_24", "project_open_24.png"), ("PROJECT_OPEN_64", "project_open_64.png"), ("PROJECT_SAVE_16", "project_save_16.png"), ("PROJECT_SAVE_D_16", "project_save_d_16.png"), ("PROJECT_SAVE_24", "project_save_24.png"), ("PROJECT_SAVE_D_24", "project_save_d_24.png"), ("PROJECT_CLOSE_16", "project_close_16.png"), ("PROJECT_CLOSE_D_16", "project_close_d_16.png"), ("FOLDER_OPEN_16", "folder_open_16.png"), ("FOLDER_OPEN_24", "folder_open_24.png"), ("MOTION_START_TO_END_24", "motion_start_to_end_24.png"), ("MOTION_END_TO_START_24", "motion_end_to_start_24.png"), ("MOTION_SWAP_24", "motion_swap_24.png"), ("MOTION_MANUAL_24", "motion_manual_24.png"), ("MOTION_MANUAL_32", "motion_manual_32.png"), ("MOTION_RANDOM_16", "motion_random_16.png"), ("MOTION_RANDOM_D_16", "motion_random_d_16.png"), ("MOTION_RANDOM_24", "motion_random_24.png"), ("MOTION_CENTER_16", "motion_center_16.png"), ("MOTION_CENTER_D_16", "motion_center_d_16.png"), ("LOCK_24", "lock_24.png"), ("UNLOCK_24", "unlock_24.png"), ("MENU_24", "menu_24.png"), ("ABORT_16", "abort_16.png"), ("ABORT_24", "abort_24.png"), ("LIST_REMOVE_16", "list_remove_16.png"), ("LIST_REMOVE_24", "list_remove_24.png"), ("RENDER_16", "render_16.png"), ("RENDER_D_16", "render_d_16.png"), ("RENDER_24", "render_24.png"), ("RENDER_D_24", "render_d_24.png"), ("RENDER_32", "render_32.png"), ("IMPORT_PICTURES_16", "import_pictures_16.png"), ("IMPORT_PICTURES_D_16", "import_pictures_d_16.png"), ("IMPORT_PICTURES_24", "import_pictures_24.png"), ("IMPORT_PICTURES_D_24", "import_pictures_d_24.png"), ("IMPORT_PICTURES_32", "import_pictures_32.png"), ("JOB_QUEUE_16", "job_queue_16.png"), ("JOB_QUEUE_D_16", "job_queue_d_16.png"), ("JOB_QUEUE_24", "job_queue_24.png"), ("JOB_QUEUE_D_24", "job_queue_d_24.png"), ("IMAGE_ROTATION_LEFT_16", "image_rotation_left_16.png"), ("IMAGE_ROTATION_LEFT_D_16", "image_rotation_left_d_16.png"), ("IMAGE_ROTATION_RIGHT_16", "image_rotation_right_16.png"), ("IMAGE_ROTATION_RIGHT_D_16", "image_rotation_right_d_16.png"), ("IMAGE_MOVING_LEFT_16", "image_moving_left_16.png"), ("IMAGE_MOVING_LEFT_D_16", "image_moving_left_d_16.png"), ("IMAGE_MOVING_LEFT_32", "image_moving_left_32.png"), ("IMAGE_MOVING_LEFT_D_32", "image_moving_left_d_32.png"), ("IMAGE_MOVING_RIGHT_16", "image_moving_right_16.png"), ("IMAGE_MOVING_RIGHT_D_16", "image_moving_right_d_16.png"), ("IMAGE_MOVING_RIGHT_32", "image_moving_right_32.png"), ("IMAGE_MOVING_RIGHT_D_32", "image_moving_right_d_32.png"), ("IMAGE_REMOVE_16", "image_remove_16.png"), ("IMAGE_REMOVE_D_16", "image_remove_d_16.png"), ("IMAGE_REMOVE_32", "image_remove_32.png"), ("IMAGE_REMOVE_D_32", "image_remove_d_32.png"), ("MUSIC_16", "music_16.png"), ("MUSIC_24", "music_24.png"), ("MUSIC_32", "music_32.png"), ("MUSIC_DURATION_24", "music_duration_24.png"), ("MUSIC_DURATION_32", "music_duration_32.png"), ("PLAY_16", "play_16.png"), ("PLAY_24", "play_24.png"), ("PLAY_PAUSE_16", "play_pause_16.png"), ("PLAY_PAUSE_d_16", "play_pause_d_16.png"), ("ARROW_UP_16", "arrow_up_16.png"), ("ARROW_UP_D_16", "arrow_up_d_16.png"), ("ARROW_DOWN_16", "arrow_down_16.png"), ("ARROW_DOWN_D_16", "arrow_down_d_16.png"), ("REMOVE_16", "remove_16.png"), ("REMOVE_D_16", "remove_d_16.png"), ("VIDEO_FORMAT_16", "video_format_16.png"), ("VIDEO_FORMAT_32", "video_format_32.png"), ("ALERT_16", "alert_16.png"), ("PROPERTIES_16", "properties_16.png"), ("EXIT_16", "exit_16.png"), ("HELP_16", "help_16.png"), ("ABOUT_16", "about_16.png"), ("FILMSTRIP", "filmstrip.png"), ("DIA", "dia.png"), ("DIA_S", "dia_s.png"), ) for idx, (imgName, imgFile) in enumerate(imgResources): img2py(os.path.join(imgDir, imgFile), target, append=idx > 0, imgName=imgName, icon=True, compressed=True, catalog=True) def _make_locale(self): for filename in os.listdir("po"): lang, ext = os.path.splitext(filename) if ext.lower() == ".po": moDir = os.path.join("build", "mo", lang, "LC_MESSAGES") moFile = os.path.join(moDir, "%s.mo" % Constants.APP_NAME) if not os.path.exists(moDir): os.makedirs(moDir) self.spawn(MSGFMT + ["-o", moFile, os.path.join("po", filename)]) targetPath = os.path.join("share", "locale", lang, "LC_MESSAGES") self.distribution.data_files.append( (targetPath, (moFile,)) ) class pfs_exe(Command): description = "create an executable dist for MS Windows (py2exe)" user_options = [ ('target-dir=', 't', 'target directory'), ] sub_commands = [('py2exe', lambda x: True if py2exe else False) ] def initialize_options(self): self.target_dir = os.path.join("build", "dist") def finalize_options(self): self.mkpath(self.target_dir) def run(self): py2exe = self.get_finalized_command('py2exe') py2exe.dist_dir = self.target_dir self.distribution.windows = [ Target(script=os.path.join("photofilmstrip", "GUI.py"), dest_base=Constants.APP_NAME ), ] self.distribution.console = [ Target(script=os.path.join("photofilmstrip", "CLI.py"), dest_base=Constants.APP_NAME + "-cli" ) ] self.distribution.zipfile = "modules" # Run all sub-commands (at least those that need to be run) for cmdName in self.get_sub_commands(): self.run_command(cmdName) site_packages = get_python_lib() targetDir = self.target_dir dllDirGnome = os.path.join(site_packages, "gnome") for dll in glob.glob(os.path.join(dllDirGnome, "*.dll")): self.copy_file(os.path.join(dllDirGnome, dll), os.path.join(targetDir, os.path.basename(dll))) targetDir = os.path.join(self.target_dir, "etc", "fonts") self.copy_tree(os.path.join(dllDirGnome, "etc", "fonts"), targetDir) targetDir = os.path.join(self.target_dir, "lib", "gstreamer-1.0") self.copy_tree(os.path.join(dllDirGnome, "lib", "gstreamer-1.0"), targetDir) targetDir = os.path.join(self.target_dir, "lib", "girepository-1.0") self.mkpath(targetDir) for giTypeLib in ["GLib-2.0.typelib", "GModule-2.0.typelib", "GObject-2.0.typelib", "Gst-1.0.typelib"]: self.copy_file(os.path.join(dllDirGnome, "lib", "girepository-1.0", giTypeLib), os.path.join(targetDir, giTypeLib)) class pfs_win_setup(Command): description = "create an executable installer for MS Windows (InnoSetup)" user_options = [] sub_commands = [('bdist_win', lambda x: True), ] def initialize_options(self): pass def finalize_options(self): pass def run(self): # Run all sub-commands (at least those that need to be run) for cmdName in self.get_sub_commands(): self.run_command(cmdName) ver = Constants.APP_VERSION open(os.path.join(WORKDIR, "version.info"), "w").write(ver) is64Bit = sys.maxsize > 2 ** 32 if is64Bit: bitSuffix = "win64" else: bitSuffix = "win32" log.info("building installer...") self.spawn([INNO, "/Q", "/F%s-%s-%s" % ("setup_photofilmstrip", ver, bitSuffix), os.path.join("windows", "photofilmstrip_%s.iss" % bitSuffix)]) log.info(" done.") class pfs_win_portable(Command): description = "create a portable executable for MS Windows" user_options = [] sub_commands = [('bdist_win', lambda x: True), ] def initialize_options(self): pass def finalize_options(self): pass def run(self): # Run all sub-commands (at least those that need to be run) for cmdName in self.get_sub_commands(): self.run_command(cmdName) ver = Constants.APP_VERSION is64Bit = sys.maxsize > 2 ** 32 if is64Bit: bitSuffix = "win64" else: bitSuffix = "win32" log.info("building portable zip...") if not os.path.exists("release"): os.makedirs("release") Zip(os.path.join("dist", "photofilmstrip-{0}-{1}.zip".format(ver, bitSuffix)), "build/dist", # virtualFolder="PhotoFilmStrip-%s" % ver, stripFolders=2) log.info(" done.") class Target: def __init__(self, **kw): self.__dict__.update(kw) self.product_version = "%s-%s" % (Constants.APP_VERSION, "src") self.version = "%s.%s" % (Constants.APP_VERSION, 0) self.company_name = "" self.copyright = "(c) 2017" self.name = "%s %s" % (Constants.APP_NAME, Constants.APP_VERSION) self.description = self.name # self.other_resources = [(RT_MANIFEST, 1, MANIFEST % dict(prog=Constants.APP_NAME))] logo = os.path.join("res", "icon", "photofilmstrip.ico") self.icon_resources = [(1, logo)] def Update(self, scmRev): self.product_version = "%s-%s" % (Constants.APP_VERSION, scmRev) def Zip(zipFile, srcDir, stripFolders=0, virtualFolder=None): log.info("zip %s to %s" % (srcDir, zipFile)) if not os.path.isdir(os.path.dirname(zipFile)): os.makedirs(os.path.dirname(zipFile)) zf = zipfile.ZipFile(zipFile, "w", zipfile.ZIP_DEFLATED) for dirpath, dirnames, filenames in os.walk(srcDir): fldr = dirpath if stripFolders > 0: fldrs = os.path.normpath(fldr).split(os.sep)[stripFolders:] if fldrs: fldr = os.path.join(*fldrs) else: fldr = "" for fname in filenames: if virtualFolder is None: zipTarget = os.path.join(fldr, fname) else: zipTarget = os.path.join(virtualFolder, fldr, fname) log.info(" deflate %s" % zipTarget) zf.write(os.path.join(dirpath, fname), zipTarget) zf.close() def Unzip(zipFile, targetDir, stripFolders=0): log.info("unzip %s to %s" % (zipFile, targetDir)) if not os.path.isdir(targetDir): os.makedirs(targetDir) zf = zipfile.ZipFile(zipFile, "r") for ele in zf.namelist(): eleInfo = zf.getinfo(ele) if eleInfo.file_size == 0: continue log.info(" inflate %s (%s)" % (ele, eleInfo.file_size)) fldr, fname = os.path.split(ele) if stripFolders > 0: fldrs = os.path.normpath(fldr).split(os.sep)[stripFolders:] if fldrs: fldr = os.path.join(*fldrs) else: fldr = "" eleFldr = os.path.join(targetDir, fldr) if not os.path.isdir(eleFldr): os.makedirs(eleFldr) data = zf.read(ele) fd = open(os.path.join(eleFldr, fname), "wb") fd.write(data) fd.close() platform_scripts = [] platform_data = [] if os.name == "nt": platform_scripts.append(os.path.join("windows", "photofilmstrip.bat")) platform_scripts.append(os.path.join("windows", "photofilmstrip-cli.bat")) else: platform_data.append(("share/applications", ["data/photofilmstrip.desktop"])) platform_data.append(("share/pixmaps", ["data/photofilmstrip.xpm"])) for size in glob.glob(os.path.join("data/icons", "*")): for category in glob.glob(os.path.join(size, "*")): icons = [] for icon in glob.glob(os.path.join(category, "*")): icons.append(icon) platform_data.append(("share/icons/hicolor/%s/%s" % \ (os.path.basename(size), \ os.path.basename(category)), \ icons)) setup( cmdclass={ "clean" : pfs_clean, "sdist" : pfs_sdist, "build" : pfs_build, "bdist_win" : pfs_exe, "bdist_wininst" : pfs_win_setup, "bdist_winport" : pfs_win_portable, "scm_info" : pfs_scm_info, 'build_sphinx' : pfs_docs, }, verbose=False, options={"py2exe": {"compressed": 2, # "bundle_files":1, "optimize": 2, "dll_excludes": ["libcairo-gobject-2.dll", "libffi-6.dll", "libfontconfig-1.dll", "libfreetype-6.dll", "libgio-2.0-0.dll", "libgirepository-1.0-1.dll", "libglib-2.0-0.dll", "libgmodule-2.0-0.dll", "libgobject-2.0-0.dll", "libintl-8.dll", "libpng16-16.dll", "libwinpthread-1.dll", "libzzz.dll]"], "packages": ["gi", "photofilmstrip.ux"], "includes": ["gi", "PIL.Image", "PIL.BmpImagePlugin", "PIL.BufrStubImagePlugin", "PIL.CurImagePlugin", "PIL.DcxImagePlugin", "PIL.EpsImagePlugin", "PIL.FitsStubImagePlugin", "PIL.FliImagePlugin", "PIL.FpxImagePlugin", "PIL.GbrImagePlugin", "PIL.GifImagePlugin", "PIL.GribStubImagePlugin", "PIL.Hdf5StubImagePlugin", "PIL.IcnsImagePlugin", "PIL.IcoImagePlugin", "PIL.ImImagePlugin", "PIL.ImtImagePlugin", "PIL.IptcImagePlugin", "PIL.JpegImagePlugin", "PIL.McIdasImagePlugin", "PIL.MicImagePlugin", "PIL.MpegImagePlugin", "PIL.MspImagePlugin", "PIL.PalmImagePlugin", "PIL.PcdImagePlugin", "PIL.PcxImagePlugin", "PIL.PdfImagePlugin", "PIL.PixarImagePlugin", "PIL.PngImagePlugin", "PIL.PpmImagePlugin", "PIL.PsdImagePlugin", "PIL.SgiImagePlugin", "PIL.SpiderImagePlugin", "PIL.SunImagePlugin", "PIL.TgaImagePlugin", "PIL.TiffImagePlugin", "PIL.WmfImagePlugin", "PIL.XbmImagePlugin", "PIL.XpmImagePlugin", "PIL.XVThumbImagePlugin" ], "excludes": ["Tkconstants", "tkinter", "tcl", "PIL._imagingtk", "PIL.ImageTk", "_ssl", "numpy"] }, "sdist": {"formats": ["gztar"]}, 'build_sphinx': {"project": Constants.APP_NAME, "release": Constants.APP_VERSION, "config_dir": 'docs/help', "builder": ["html"]} }, data_files=[ (os.path.join("share", "doc", "photofilmstrip"), glob.glob("docs/*.*")), # (os.path.join("share", "photofilmstrip", "audio"), glob.glob("data/audio/*.mp3")), ] + platform_data, scripts=[ "scripts/photofilmstrip", "scripts/photofilmstrip-cli", ] + platform_scripts, name=Constants.APP_NAME.lower(), version=Constants.APP_VERSION, license="GPLv2", description=Constants.APP_SLOGAN, long_description=Constants.APP_DESCRIPTION, author=Constants.DEVELOPERS[0], author_email="info@photofilmstrip.org", url=Constants.APP_URL, packages=['photofilmstrip', 'photofilmstrip.action', 'photofilmstrip.cli', 'photofilmstrip.core', 'photofilmstrip.core.renderer', 'photofilmstrip.gui', 'photofilmstrip.gui.ctrls', 'photofilmstrip.gui.util', 'photofilmstrip.lib', 'photofilmstrip.lib.common', 'photofilmstrip.lib.jobimpl', 'photofilmstrip.res', 'photofilmstrip.ux'], ) photofilmstrip-3.7.2/README0000644000232200023220000000000013560357351016032 0ustar debalancedebalancephotofilmstrip-3.7.2/data/0000755000232200023220000000000013560357432016075 5ustar debalancedebalancephotofilmstrip-3.7.2/data/photofilmstrip.desktop0000644000232200023220000000076113560357351022557 0ustar debalancedebalance[Desktop Entry] Version=3.4.1 Name=PhotoFilmStrip GenericName=Slideshow Creator GenericName[de]=Erstellung von Diashows Comment=Create animated slideshows Comment[de]=Erstelle animierte Diashows Keywords=album;gallery;image;images;photo;photographs;photos;picture;pictures;photography;video; Keywords[de]=Album;Gallerie;Bild;Bilder;Foto;Fotos;Fotografie;Fotografien;Dia;Dias;Video; Exec=photofilmstrip Icon=photofilmstrip Terminal=false Type=Application StartupNotify=false Categories=AudioVideo; photofilmstrip-3.7.2/data/icons/0000755000232200023220000000000013560357432017210 5ustar debalancedebalancephotofilmstrip-3.7.2/data/icons/64x64/0000755000232200023220000000000013560357432020003 5ustar debalancedebalancephotofilmstrip-3.7.2/data/icons/64x64/apps/0000755000232200023220000000000013560357432020746 5ustar debalancedebalancephotofilmstrip-3.7.2/data/icons/64x64/apps/photofilmstrip.png0000644000232200023220000000505213560357351024541 0ustar debalancedebalancePNG  IHDR@@iqsBIT|d pHYstEXtSoftwarewww.inkscape.org< IDATx[{PTݽww^B@.>b+H u )ݩJS!8ht0#uщt+c;&H6hhXG+".]p @o{{~/<Fl6n\v ՂBχ\.G}}=}l6DEEpmmmpBɓy.f vZǁ}Wf̘߾}e"""|sss}b T@<2lTvb0CV|},|:;;,X+zjkҏ"T*G|쥥={.V ,j5n~0`޽</␟8:d2SEff&˲Oj'sLF{Eh4N#A7n=yH$ݶm(;;h޼yeXHV aaafl':_ч~Xrr2Ԑb=٧Itt8pEEE Z^G<ϓR9sܼy3 *eddз~K)))']322裏>zj@[l۷\.lt9&]{=R*L&#FC8*((2  ĥ'S.>\ 'DӧOf͚E%T,K&;FVꋋi̙cBŋ`0lr ,YBV?ONT*) Ӵ`oعs'dQPHHYV:uH(iii4m4Z#. qqqŲe`2xP\\<Z?FHH4 è}3g, 0<` wWP(tǎd0($$BCCiʔ)cF$锐@ Z(>>***H*~,LK,]vQ@@L&bFY&99V+ҦM(++˛@1 nݺ!Lx'aYV +WPhh(-_t:]D *é֮]K111>BBӫJ)))A&MRvv6%''?D"E)!!g;T}r8E| m߾] =QTjhii޽{UXѣGQ]]$%%H8cqf|d٨ ݸq饗^ki4|--uU}-¬Yp ?ZDT Z Á1Vkk+Z[[}asa؝;wp]|D{{;l6#00p̮NJ,-ѳ,rI3@qoJ"&&[nKPU? Щpt?Ny S'oSL$&&"""nw_0/^Dzz:"##GLonT MmO~ g]rL7gY?irt _r9t:PUUBtRaÆ ~ ĥxu + '*x3'!uD`X%~[:] F.]&^gL3Gp' f  [% TU8t:H$455yu& ~'}X_WNJ5ƅqo@(eQSSI&fϞm 5 VbzL ~w$`l%('ᔸu;~QPD,p0gnT*\|. N+VD_t:JSgaF&,'om՘.s6 VHNJ¼tvEÇhnn(//Gll,_444qؾ8ܕ?nёQ3PK8}*j߂yj},pt{W-mHYJPXboJ܌F[H444yl6c8~8ܯ [,9r. vuuu8u_w, h]y`Bn{*p255@{{;B!p,..i`nnffff`rr~5dppPnIH(]f@NNNKّd}}])HD Ð`0(.pXEEQ$H00p8,)h&@Driraj$! kjjFdp\l6V+6HT*E4fUfiZvuuE6%Lr( r9..."}}}VbX,&Ͻ*]S[[[ $ (Rnp8p\X, YU@V+irxxHXHQ|p87BrJSS (:UUKEJM:|>߭j?~yaC_WKP,Ks(?d&ϳ&yJUEihh,?=q%|#? %+KOcyފx<222"iV`===ƒyGo^B0P꜃GǟeJ9??쬪ytHͯOSÝOeT-QMv at]4"U% V4MtzazN'/Seccd2*te,xx%K`Ĉ@c̘16ð)g...TTTDDD3i&"RSS_9>ydkb111ŋ<<`JOO'oooJHH ԺukZbm]ڶm6H&ODDDRaÆQBB}g^x= ЬY3 Z^zPHiiit9jذ!)Jj׮-m=AÆ 6ݺu6mJ TRRB]ty2 }ԩS E;vLoڵkG"ԤI['تopp0O?DA$lO:;;SƍFAYYYt%rssubXA4hP0N}&͌WIҥKm^HL,' sΤRѣG԰aC@SNݲe ui2-h?w\""zl^PL,#zJ]wh͚55'|BC !GwGQ۶mm8&fPXnJDDիWW!寵Ќ3j@hrJ &www[' eȐ!SN=HΝ;_EiiiQ|>mڴ.\@/2ЁGIpp0yzzt;իW) ӓEԿ:u*]RRRӧOSiiQ|>mݺ(33Νkcb={͔7oOxB 6iÆ M$ oDDHׯ!v%^RQm^xLLޠat}"":ux<"JiܸqGB|>yzzr?)FGGsOZ 9ANNe`bIOOi֭DZufViAǏ7R>!wޡ*--1c*bHDիpB6n)wwwȨٳgs=G{oժm߾rssi$H ùҥKkQ+СC:4=ɤҥK:pk5jDK,KRIIYƇI$Zx1ٳidE+}7DD~J+pvvdN>mdR{9r$ZJ5 ԨQ#>-Zd5t:{IT5H'O?-[:t@&L RIԬY3HR:<C y2|oT{{h"z(77,#;wL'N-ZX2m/4eu}7Կ*,,Zsrrjab{YnWyӑ#Gݝ~w;vz"##iLa|"777l*--#F,((k[f sj[\^y1coߞ=jTKD"UVѲeˬyZmڴK.Qpp0,?b [@H$]v4LJrrr(##|6>rss^^^E~)/tnXls-%Ç".㺺"66ڵJQF!11;6`aذa n9OeeeR)z_~P0CϞ=0CeXt)z`p-=4o͚5HVTϝ8q" :OsɤI[n]iuI&|rԩS nHxZst![,yb͍&OL'Nxj޼u4Gx֭?L]mrB!uЁЅ hĈvZ̅0au涛S[WUx<ׯٳM6ܹ&M޽{5Pzz:ڵ֙bT\\L[l9>tPzgcgϞ9[7&Mŋ/5jDW^ׯZb9r3,B/_;C(11Fv֭.O GLNNN:ڵkQc]pĈOo%JUe WEkٳϏG}dsE,GRŋ|> 9j~駟Z@o@("**ҹGENNT*,fԄ6h4=z4&O-[Fz~̙hѢfWk~x饗),, 2͚59p>| "\z\&3 j777JHHӧOQJJbhݺu6MVȇ~HN:>}:;s (ⷱ 21B|>EDDpuPkȔ)S*zEf͚ՙr:B!eff ӱcGx"_^,X`9tAgݻw)""¢ڷoO999$˭|ʓ+cf޵kWkg[X{.) /iڵFZJgϞVG<ӪUܹC3z(/^RtΈRGڵә$x͛7iDD4m4@gΜ!TJM6y@ ٳg֯_oT^"жm۞AqΝ8ǥӢE|/'''ʲ"f QRR͛7cǎ֭ 55?:t`p< cƌan1rH:u J; WWW\.GRyMuD,:(-- &MBFp|WHIIA #==݂ZK.PTXx1wP>, ڵ1U_9QQQzjھ}Q{=M(77ϟOt]""޽;7>?^ '''<3hԯ_ߺ!^2rJJHRDDD@,CPpssCϞ=j/NNNUjҤ @,CXBQW6[|NNN3k|-ćD"l3t>WZQFn߾ V |("صk |Yk GVS"foK @8{,.\8y$wVUV7X8ZMERA&q[Q `ǎUݼvqfo___sǮ]HIIAhh(bccVu-[r4h`Y휑#^_D"!sKиqc( ֞(J\~-Z@^7@M+O03wz44Jy<>sK pU&MpMO:wGi Z?K!IRٹUW5\r/_ֹq *Q аaC p-8 hgn+umaBzW'B{s7FC]5J,AYYY^ߊ ĭ7|pb1E68~h-n^ތkGB)Ҫ"?{W|dTx_JʘXsÜ+|ت>tD8p D", !-1}W>evZ8Keh9dX~<Xwc@VMWnx|! d-J%Ǝ _йsg(J`„ Xve"_zzB5((RֽR 2W~OJ$ȸZz xz{{׎P齆/pF^^{X\e˖<ڳbT 4gΜdI3͎7N߄]Q7wVb3 <s[|R)ȼ17X_dp}}t|1cܻw8 .]@ȑ#ڵe mۆtg䢪2e=Ŷ*a2 6n2X@ @5^WR&Zf` F~U:>b(JH$͛Qdm۶3V\ɵuOwi A6=ZZG0ukXrׯyL__cˇo p%dee}HMMiT,sݻ EFFj5ׯB֭[8xb,/ K^FYXA35> סk.A|paMQa+;c a0))){.իMxw}'Nqz!88R+"##CgZx3ЪUKaiJYg>Ǒ_"* ڠ_֐.4ʇT5+fgo Ӽy=ܻwO͍ +w^tb#CSA ;#xyp4o; $ D(+0I_,#.}I oeI.^/ԪS<?7g`A|~MkՄ`֬Ybу`YHlx:+H5 ?O"_ŗ[_h.Np7?xJcw*:j|0ۨEBBBp)4n\D޽O8~&6ifoU\|>TbIPPǝ;wd1;Me߁|)'NmQD{ BdvEno3k9j@PǏq,T6mXDquuT33uF@_dM*D.C!E2ú"/įCYoIoXT*Bp]iZuz6+ d2nt]OgqYB|!&`ʇIo6טw rXZe`A*୷iALLް'N3g΄E5U^At`r|8yy~ܼ<' dFvr_1aLjS{sA.#$$k߾};\ ya!fkn0͛7lj5^v">>{e+P^ЏP${qp^n˓d2ܸq׮]CZZnܸ<pOk+XtEW JKK{nƾ _r w 5k;vwǡCУG%@o؀oe6<Y8%YY8I Ot<[P(bbI433ˤj$%%!$$DYf8|0 1j(m۶O SS+'OMFǰ/ѵnq@@[7E2~줾}|kEBCC իW9]|ù}9r-N>Mh…ty ={zH/l#.iƓ 33iiiPTh׮y;w Cg:tnDwM]䋮}ct|ۭք})L.J=OGŭ[[oݻ7ܹlYf_5t綕غVAeJA{A$/k``xְI z9akXzS]_8p -[VB.]Rp9Xf_=zw1`ڀWO-Nk ui 0@g &M~ wܱvb-\ѓNշm׌n~/{Wa]`رUnΝ;Wfծ0f B;}W^͚.H{Numci233QTTTxFFPNaaJdii)=&Ɵ_oj #K?{}L:|Xz8uZ;v ͛7EY+nnص=AZ  \WIX6Kw#< ]fCo)4,2'82"[ S.H[f*jA0ZFo]~}APTymP`  IՔ 03"k^6Fb>X[pu xB];qwCk4hCѣ{GttvUVOk^vW&~׾19puus>4 *C) ӳBSVvk_5":sM oGjsp .PvQX,>42C*xW+hiMwi*o"`-닠 4moo/:uⅳk^M9i [аA sC0`84 sC0`84 sC0`84 sC0`84 sC0`84 sC0`84 sC0`84 sCTE:u[\\ BLL|ܾ}$!!! PRR\L\\@ @ǎѼysB.CRrro߆L&3Z z???bARA&rPF`ea=.P(H7oޤ'FF7~"-[#!!Fƍ3IǵkjѴiSgeaT X,~Y h!dQ, Ô^^^&T`/:L8;;d!H$^5򉕅aO@՚d!Y~_>KF>0 S&hz^6q{aifuk<! J$c tCE)WrR1^5򉕅aOb7Oii[7XYea7=jC>YC)e밇4u{HC]C8Pƍ VcBJ{L&3iRkL۸qcU(1z84+ 1,*9Ha 9áaph0 9áaph0 g5~%7IENDB`photofilmstrip-3.7.2/data/icons/512x512/0000755000232200023220000000000013560357432020137 5ustar debalancedebalancephotofilmstrip-3.7.2/data/icons/512x512/apps/0000755000232200023220000000000013560357432021102 5ustar debalancedebalancephotofilmstrip-3.7.2/data/icons/512x512/apps/photofilmstrip.png0000644000232200023220000007750313560357351024707 0ustar debalancedebalancePNG  IHDRxsBIT|d pHYs%%IR$tEXtSoftwarewww.inkscape.org< IDATxwX6zPbƆ{WHGMQ1vM5F%% kI{AEuywGƲ,p>};g3g{ (W6   (P@A  BAAC(  rAQ  !AD9 (P@A  BAAC(  rAQ  !AD9 (P@A  BAAC(  rAQ  !AD9 (P@ARhڴ)4j*VPbEP**55222 ##233!##'??4gW `~w4$@~(~SjUxXYYZDfkT `~( Di@~` ?0 KCUÎR@~` ?0 "氣A~` ?0 9(u `~H @~`T?P`$@~` ?0XٙÎR@~` ?0 "2v: @~`T?9i@~` ?0XlD"1@~` ?0, @~` ?0 z`$@~` ?0XlUiXx$ ?0 RP@.ÎR@~` ?0 "氣A~` ?0 #!?0 RP //v: @~`T?P `~H @~`T?+#!?0 RP ''v: @~`T?P`$@~` ?0X(0@~` ?0, @~` ?0 "氣A~` ?0 z@~` ?0 KFB~` ?0 #!?0 R@ `~H @~`T?,#!?0 R@=FB~` ?0 #!?0 R@ `~H @~`T?P`$@~` ?0XDBAADR  J?AD9 (P@A  BAAC(  rAQ  !AD9D@&Eȑ#W_T* PF ttMhSXZl֭[XND"H-LHH@DU} &%%?#A"H$ +޾}>}jp=oooY[yp1^ 9r 46mu(긺¹s`ҤI4PQGj0## }<2"H$p3f \Cv/:;;kdDDo?R aܷo_T*<ѣЎ!H$ Ĝn Ɣ5jL&wޡRD___ϣH> ''[j%sH$Tx%YP(^z駟kw%y k@.]d A$D*!;شim޽ly`` e0;;k׮-y nyܹs(9_ǏKpI$d^y{{cjj*{Doool߾=[[H$ׯ_q ~HQV099ĠඑH$|ڳg?g`^ ܸq-4֟5kD"ϣIp?f7nSRR8±cP& n'D"Lݻshoozl޽ nz '`Fzq-[PtG"HeLc~ĈӧOqqqIFIp0::CBBM6˹(ϟ/$T$HJŏoܸbkժֿ-C8p o۶- 4D"H\ > "Ըqcti+رc")E*ZjժaRR>x;vh2Cb1 "3)Sp.BAH$I,Yk׮m CD9lڴ 1*Z* cǎd,mժU$==4h H$bfܻwvhӜ9s8u\`}6 noT+EDD "˗/Mnݻ1==W.\,XreH"H5k={C4h{ի蕬qݸeQQQ{8̕+WNh'H$iɒ%rJ(,LOMMEm+g܀"vڼgGH$ѧ~ݺu܎*8m4*܀"sμQ/.D"VPP?!!mllʴ ~111j6'Nȋ & H$eo߾ͻw0^~_z4mD1矸sNϵȴ :88`zz:N:loݺsa˖-v(D"4h弇ŋys###z֭g|،3?R"7:tPZΦ-^zs1z抒Hr-KءCTTJ˗ڔJ~zNQQQ*p _֭[vkp5@"ʭ,-+>{_ł5rhѸ|O0322… f=ޠ]vY\L"H%!K{a54~3g۷_ ~P=#N:ƍ]`~%H%e߿O,KNNN58{l@gFDFFN!1$$DpI$,J$ѣG5>+Vk׮" mV۷oƍxE|D"ʚƏ%z ky۳ԨT*@GGGը A@vv6?ϟ?u H$RZK!Y^%?8b3g̜9$ [c9r$DGG"8M4'N l߾Ǝ ТE 8}4XYY/0a%0 p=T*sAf4n?rt֭Dm*/8::?TZ|}}bŊ2 ё38;;ڵk{,qZ]pp0'D||<6oGŋH/$d*թS7o\W*(oʋܰ^zصkW1bΞ=ׯ_7brr2݀<<<ȑ#/ظqcOZhr͛9 [6H$)4o<ܽ{w3007 ?C/5kpΜ9&]k׮`bgΜrɓ-n`G6m033ck||<8f4"{(4D*y&%v)ID"lҤ Ν;_zAK ,*NLuB޽{fݺuJ"HEz?ܬqpp'O+WNc#G sJ,c޽ɓEbbbJ[y*v7n܈o05K ,,7A"H$SÃu٬Zh塿?vޝwCT*O!{{{Çs~)1b6Qow#b 4H;K=8$ vUpI$ڷo޿̙D(,'O_kbb"~Wh![[[3g\wZj }gi]ZM^^>d'NX8QL ,@B{* 6mE 8q -ZfD*,u6okk x9D(yXD8d8eoժ&$$h|ڵ"9sL6D"Gر,ϝ;#G{cVV(((ϝ;9 6mE<$8zuV`/n}ZDD"ޣf͚ekԨ999~Ls@ܹsJ8{l  )D$)S4NKJJ~ɠ CJ"Hj5jԈ?}&o^=8^xa"tɓ29AJ`!!!KC5''(#pʕzӧO n'D"'S3 AD֭Kkޔ g8c e*U_5v +Vu?///{T*3g]"7A-zD"ʯMLSGx5E___twwLvZiL~5j}=**ʢֱ)!6mw^/FR)^ZuΝhcc#CR):2D"._LLaqlٷ~f oQӦM9+*Jttt.de2;8ׯ3ˋ/иHu"[xEA)SH$ O8[n5Y999~+++|{܋#ggg:u*""6 4 .Ĭ,΃3//7o>۴i ̚R޽{Z,^D"o1YꥅWX :q~̕vYYY n@2pռ_^bTV oܸ{ȦbǎsNj8oa?.G"ʹM ]ʕ1++ ӓ-a}&ML6l Vrʸh"|{|qioo1_@~~>~g9aÆ?& "H"ʩyl67oތ .dԳd2M8uTLKKׯ_c ɂU޽{ڵkؼysvX,+Vh|.\P۷\vy=<<I$R9"">|$խ[ yPl߾ 4ڶm+ykSV؁ݣ״%<}صk`3õ.#m6}F"ʟڶmxADDٲ`I_~G9s7VLYӧo!"s] .Y} CTԧODD9rdjժ""sō3={f T1>>oݺդʸ7b_n[Y%Ԕŋk ޾}ނD" 2ٳg1<:t`PÇ#"ŋ5neUզ}bff&zj^|Kp-L @TbDD/Ȭ0j[|}}˗s="+W 7oԸ}xϏTruuŪU nGAM:J^^~U%&L&k  #˱SNf%88]cˮ^ M6s hYL;w4hOOO8j IDAT4iYlٹs'\S#F0񈲋T*e648uԮ]M:0OOO}lٮ] $$?.e !L-T5YPa=zd6;d2–LE*?x"ҔB %PkԨseDD6F@@I*?^:g7B'Oܮ2FPaϞ=z6r>x[fooQQQ/0"r>kӧ 0S#ggg2 ޿۷/D"L<` BB͚5 99uK.زG `РA{nլY|||fNj/ << [ְaCXdَI-r9糦zPn]^A,T*xTZ5jז~|`QƍÙ3g{nLL 4i?.e|}}apyz*>}zmc) |8̝;W>}cǚ˗s^ID"۬%J?/^|X[[Ç{ 0!JO~QU±caر0l0ڴr4iԨQx<|0.ZvTTcll999f3wɓ*SӦM\3III}~Wܿmn޼N6/96l'#kkk|2"2}ᇂDb%Zոqc\~=2##ۇ (:С%<|+Vhsô4q'N(I;J*qY|9nݺ67męQ0|DD~wcx"ٙ|BCC9K\fgg~&Y1??svؑϼyp…]vgϞ˗/9˨nذ 'Mk׮i˅ 066VpJ1##/_N-SP$mكrËRJx%^pH$f=_p$^'1i$aÆa~x |~ CD8q߾}+?HC#Gݻ nI7(ŋݻw իW8k֬"-舧O+W42 ϝ;9ԩS+25k,ε1gܤIDd^*XH$Hp%{{{=z4޽{eee?{OMx!^`e|+WIIIrrrN:dyjڴ)ڼqAZnSҥ [fNW ZJ@˗#"b5 D*7djٲ%,77#""Ko]+++͝}P(]vޕxJ^'yyyheeet{VӧOs=z!!!ZM>[n-OH$RT2;wzuԁuցB/>|K.J*i (N%K/0ͧN糟5jSL1҉Bwﲟ5_PVfζ6I(A~T޽{0zhӧCrr2L4 =zK. *hT*aС"֮] C 1s΅'N{_َGNnݺi_CQT;NtVkaA e2P;Xx1T^u ߿{eb1l޼>cةR`РALV-[ 87ont[JRk訵D١LjJ%9r>ɓ'CǎaʕW&~L"; 44,6yم_5j3f0˱҉:@TӢE 26PQ| J&(O>11 Y4h HN:EZ`5WZbT<cп8}4[&Jaǎпsٲep`zEDDh|UAX&bUf HRh֬Qm)JHIIGGG묧R >>:.A=Y {WeRo 2 ɏCYfABBYfrʌ}  hal ڵ+gD"HHKK0<<~7ٳɏ ?~<TP/^lcUVoool0`*xe!!!ZB[@rr2;PW\[[" CubBB^v 6lkd`llժYlP/۪RqƂix5DQoMnOjժU3iӦmp HV`ѪX";wqhmm}g5BDfy@ښ] ĉAأG_~={Mlڴ#G`~p޽3aM:| D*7emm޽m۶qnĉEf*UO &ѣGCHH&sex]'77.]`NF;99<]۷:רQW^$(} aÆ(N,]FœOpIт qĉz2e "b*,ŋy] jGk۷۷o;D2?N<ɹdee+Wpƍ8rH[.>,_\pHQzʕ+zCD4HF9sAu V=v"k HR!md ƙ3g~RTh-B...x!=zG2._>>>z-Ҵ}jP@cM`ݺuT*2DpHװa̚mۆ2L~>>>Zf͚8>>>!"QtӬY32( HLLUVavP"}fUq N*Dؽ{wߥKDD?~<== )) G+cҷEܹs5k={H$Nq 7oӦM>}۷oT$\~=vYﯝ*Xg*R|/@DķoꜪ'133SJš5k=ӧ58f7x^%KpʕD"iݻ͛ݻw޽õk4J&L&ej̘1g}sSw bȸ7B@WWWNy:uvnݪT*?S֭$H:ee2v7n܈o߾5(éSЎ1ԩ0r3&dKv}´ݹsGﱾ[DD 㔷hтmG״=z "eD2J%s T;vĈ|@@PC?FkkkdsB"Y>sAF+޽{ZիX BD 6pʻuƶiZ .DDoFpHP(p 5jx{{CPPL>= _/H[ngxZ իWR暅T֭]o'>s0@* >u{xxc P`Іu E(VZ8a{ .M$}vDDl߾m#fΟ?_g0}tu% Mpʔ)lY??unѣ$ nA!C^~ ,ʕ+ noQTJ}6{ .TڵCDݻ9ϵ^v[8)) oѢEl}JΝ;1::gֹ̘pD2HPd5h׮]˹F.={M6j\]]̙39ٳԏs(]v5~HHzsM7k֌H$;F.c ֭[clʕ6x͛H$A舣Gƛ7oj^~?R, hoo/]m۶o>PW?_·] L&TbE`pN;;;vzUbbb"| w@" D-[m۶annƛ۷oqѢE+$Hp͚5gϞEggg"M&%%+VݻwyۧOnPkտkDEEq׮]SYf춂T$&;N2?7CB֭[ n.͜9]Cի.M$%pذajz)֭[ZN|AN}4?deeT*$h nY$SNxo/_p 8k}Utpp&R="muaT*rɒ%~'N QPiZHD"X&FRǡo߾Pzu;w.xOӦMa׮]C8qάgBsN@ƍa׮] J6(Amooo Yfedd3m:88pqtt|nذ!\zՠaR)O?dqpڵT*RkT̯X,fHٳ5ϏVVVCNb@DѣG dl& СC+V@jj*&O sN ѣiӦ`cc#9D 'N`?PMj,OOOgd*USGf͚xOe"x"pĈxN>-[NRՈ#k2&&-[.w@ ۷/gc\?f4h oH$R$f͚͛1;;wSNH*\2Z,8n̘1 B}g?Mo̚5ly5 D*7_}^~w3|2ӇR/^{ϟ?GDnsuu՚8aDUvms4d$H:%B6668p@fW=Cd[i޼ʶzy(~5uT "u_R%^zm۶![& D*7ԩjժ8uTADf޽{VZF*rpp ۿ?g3;= ƍٮСCءC,;;[pH\M4O<%K@FfϞ p-8qeL8{,W^~NKKcǎꥥl7''G} H$zaPPL}>0=(IfUxK)֒Lr'(  E=ښ-^77|+7n`„ 0uT#CP| L-kt6.qoP|߾}}`޼yrM o6ԃ 10 KUVPѝy( 10p(qeZ3 N(  ֭]hxB> #o+#W AT6Ǭ8::Ÿ篘@_6! ' }|;wclCTBRRmT* ID8pQDIrBaF > J. RJ yfSAX `ZC=޼dĉAV nV7As^"?t`HMAX AAAߚ7nhW{i-ZX3raz޼yR>"xIAX { VXyk6.A DOu#_@ٿ50Ο? ], &B8V4:aqi珈j*?Zeee) OXߎШ?hAX5krG'i{M Zݹs޼y J;MJ? (<.??_˞L8ΠA]1"##ٿ J/ׇ߷yVAfR8З뼲(ڤ 777pssӿ#A&XiRF g]=}~lgimP/A՝ڳCCRipN5kjÈ$A9 7C{} AAXnnnpi8q"DGGL\bEFz4=n ۶m3fkkk^mYYYC޾د,GC<R@{r9oN^^T{giw…  [8\04l^xbË£#灭0fRz0nXP3Ֆ i5@Hܹ˗/g?.,pP 88ɉfVV} x9\zvrrrZRAV-P7}gСCK먪U‘C{ Ler-X`APݽ3sv5_B[k.? n !//2Sʕ,L q`Zk|9jH.^8 u}@~ 9::r>wؑYS=xzQ+/_kЅ=L<N9 9esd]n W u)!+޽)'믋,? "B/޽ʕ+kV8UBll,h[.xxx||HL͛76-a`m]ܜ!71U9oYN^-[j1bTvK׆ $IA" !#C%;;;'ODe0ȼ *ed}pIv` ~ͬݠJ*0o^__Iv^D@+pV@&`aƎ nnncQ"HgFdgg}L|ХKy0O툭}`Pr2п 2ř3gd2# ;w4 Zp1XbښDVZ`wpVZlwb <| [}fcbrA$&HL qV_<4CXBy W4@(Sܹs.]QQQrMI~̅r>}:TV-r iJ:ҨTlNP#ZOQa+ٌ~RQ: Azz:+@iݺ5`k{/w<}>Mk#];uƨլ`32( "4oޜاںlXbBCC2R NSLmDիܸ7th&_*Hs A6l<=x;NF?}r4eVvlzuЮC'Ӝl~ !%a  c =nݺqO< F%>"J'2 "֭MFChimLZ1]j>A">} b+HOOsAH;OܠcxOZmalhӪ\-C)i߾ ggP\$&HAATaaa%`cc\PUVVGDAQrstk-3p-{8(Br_à;P5gϞBg/xci߾=tl}>)ډm?WDJ*pYXdIhŤ,Gx"b;vlHC:uҿ{sW9+aC2\\- canH$hhx-cz@||<(CTXN8^"=ה. 9Գ>S=DGO ι믠TϏ5yBPessW z¿g]tTyiʶ"QD}v;]*`[)Shܧm۶Aff&899Aj+Q̜>"~ڻ U jT^6k4>ƍcLpm3aAý{EYG*ؿ?\|Rm6@D8{,ܼyS>{7oٖйsg , +++رm=R2y- TJ~k&;NISjUf$V@bb" .] ~~~еk"'6lD"xzzBHH9rX` իWl_p!dggC@@Q6=;Z*{xSq3?k{o8v( YВt.`|@˖-F E3_(p^/^e4,&J*TvA @.cK0,s6zVNhh(TMW67ajkæM8e AXI C,+,--͠A_~%?.\6l(q OՄL&wwnlӦMy /^\3'okeYiC̃ߏKƍAH&Ьq-^l*H2ַn <"^D,kS֭[r ‚x)xzz¢E8PR%vտ¨T*x!g> F{6;;;K{zzVY[.oLJ \]6; 0;J>}{ֳ^=5K2 BBB zW%7pu'kb*;MA ꁕò%ӡc;琣{3:| ҥKfM4={ӵݼy3'pvA>}Z\|<|RJpqԉIZ^"\Uz^hS@ `ՠTnT}Xh(sPfǃ`Jo 3 W~=@h4%R+ر 0!Cxt nbWk׮ԬY6nh6z jՂٳgCJ /^{ΝѣtRhܸ1kwZjc!?,X֣D( [ 7o,vjww41H 9$3dgd @(i]lGMzz:Ο?/쉀֯_?8;;CÆ y"^v-[5Qpvvy9?H z Om[Bx ~έ) Jnnnlw.nܸ-[d_;bm-<؁jՂ?ia뚕 ˿&Ȁ KEMh;7N{DШQ#1ڻ >$!P (Mi""b!#(* *b]QEETJGT@ )L?lԙL徟{O^C;sN&OG}ԺZ嶝G`YYI 'N5#22* fss1&Mf4M6`1~xM^͐M1Y6Qr5kD h(JBQs._P=,04f P.rgP~r 툈%KKHH@IkwW}ㆠN:Oa~FC0@6`2F&|_md9e@,#++h"\:tf|,#zm4(-HAQ^]y+N8<3r`nzdLc)jǭ-K.]QQQfDD7l||INƾ骽,C*>҂O)Ԛ@dPZZ,|/3=<^ y+ $$${I0uT6bq ojM wUj`A> ֵnݺ ? o&$xHـ஻_Vf)Z\S[sk [0Fem{WgpҥK+,6Rtrt K3ms(FG`'YwӶm[6& 4wssǡZ-ۃ5F]-0}T!DMi_߁GhBQ눁?fXtO`@,Z T@PPZlg/oiժU_0o.>עJo00o<4o N+l>Kbqlc[ƛXvm?}yI,|vgU冢 @n."jb޽6'**^{5$%%9T{~[pЁ*e²e0|߿s|}+X$l='m{xSY,|~X Q\8pKg6m3޽{z=>C 䘐jN=ݻ9oFʵJ:щ*턇a?tO7 "psвeK 2U@L0h Ao_s6Axx8}Yhz$IO ,˘vH#@I3 vx<=t;vfU7%R8%K0qDHGVŋyĸ} 4Ulo{cÇYӀ\+''pMS@];פoXfۋA]\b@GH61GOǽ]cƍnZ+E" ..1111b`׮]Ug9Oaر.k_zpYj3Y{qqq{]_QIKCg~[l ܹsR#֬ ?GS# Z\St dF3̚ߋ͛=ضc@,ue˖! .\_K+.]}jճ8y$wY[~TݓTi/M=Uy`MF<ǬCG_CFЯ_̟?V"r+WcȑUk:wlms/hw+,Z #GbNR2ӱ҉R#11:܅-"*"!Ї!88;o*J f()1FQ Ky9iWq\RS/ -- .\3gnYD>?O?mmذaXreT*As,Cŷ~#GM6 .I&!سgO>شiEիW Cq[w1-}GAkgST֑2$!4vׯn[/t:0iٍ'Ѹqcwgd2l6Wx ;; 6D /X/ܬĎk 45wmz߾}֡P ɵ222evaX f ''HIIy\vMo NwޞSkYS"+k.={lm.\'-[fE+VT{ x'ύF#~g@==.ύ70lpx:[S_z#WS&OFDxeUj ]ݲ?ܶW][xydd$"##iӦj/-N8a3KСC˖:un_/~y<~x>|ѬY3ƍrhhhӧOڿx CyC,[?i4|וNU]͛UhQF]˿b:T=<7߸q#;feef͚U,ш)/zƏ?mD%X&7vYow PZZVSMҘ2e|#?Wprr}96̴T9&&|x#22M>]VUuVYeyƍ՞SN6ܣeܹs(w,'}Ye,7lȲ,L&9 nڵ+f:,)su1W|n)EW7+{}f|0a<5jeeeUDDDT… fx^en5`({s`EbbbФIm_|IЯ_?իWQRRJUn"r=o9.~ٜ_cy &Q^zau׸!:wꀗ&Mp?fjU"V*_j*ݻFܕk)n*"eDq㬓Y Y#=.9Et:nM+|8s&!Axy$q`-It:|hDbb"lR*+RRR]µ{ڵ ;v˺< xs"Ҹ 6lzNjc褞Hb%gQhR,kV  88!!!FhhdBii)Ұ1} WxNju,Np&N7g冖I=cgl6HLLtAa̘1߰a>K.ؼy3z-tҥ¹ ȵ\^t:HOoDB# n$ YfH(P  ħ F2F>'ţp)}Gp#Cqd:.._QF!++ ϟǸq|Z788_طo|VX$3UU>.ѸqcO7nڵ+Zn 8vk*8qC_ ** qqqNPWк V#lт[f 6mO?ݧ.X|O Gq ylV}5,٣bǺePwS>||"3km]v|ݾ}{{nݻ'N&"1c" *]=OF݀tn==sGFFbOpxx+7" dm@ѵJO& 2HFuvhZ<ٳlj_jtsozs  שL92t8;vɒ% n6t=]RHr>Gk5);6AP$zsI&nk VM! G>}VZUEL&k!,, | vQ1b~8k!5 $۞q/Sku뢠HK|:ޓ'N $Haܱcԏ7HpD'@M֯l&"hT_???e@Z]@8dxm7gVh 6[£N 8gϖ!cѣ`;-`PXUk71/\ cѹ_("z]t[{.CTE7ֽCFGOUb%&&b׮]P8qD&:r֯_iӦAO-ɣ,99v llrH#a*> LMei s[ޕ_^Q{2=iiiG׮](((pX @b^` fB2 W5$H;fšh{XLDC^N:HKKCPP+V8|ѣGc0a,XVQY:ϜA#rsKn7^?U;1gϞ:… 1p@̞=<3GDP?߇ȞąFmۆvr6nHsh իzLr^'tnݺ9=׮]?D3zuWs}ӎ'IV\~}FTTӎKQ\\LFx梤жm[g6\g e z=" 5tnm]i4 U>Sj;c;tVE|8y$:$vߟCPDOHw>t{e]Zlw'Jtqy&OOCiYM""JKK1c WjB&:$ ܹJfAJO?\0 .^X,#ѰaCg5\g Çm{7) YH3 qqM/8cՐ4YIJV_X̃"vK[ xdt| D}㧟~bbb0m0@%-ի3{űcбX,jXb?KIg|~yF`CV'"ϛ3gbccQnwHYᜅE38O7kR(R}HC*x:/Nsj HwScJoUnU aßA׮]hT.lfy$af fuShh(ڷo.]6msz֙} r39˲#"񉩀kKRᩧ¬\f~hv =zO_\*\EaA!I:ct<5r[DDD-w "f9Z^F`DoHPO7-4woٌ֛_oA|Сx %8~DDD" L6 m:> $u2VnN}ٳ'Z&.3Ͼ"塨Tpͱnno *,\I&ᮻa.@pk&GPd_v1cb 7;@Νn:<Je;v"""AT' %=qNNl&9L!=={6RSS=$""B,n2 ̎1dFa`ڵtȋZΟ!:,M 70,=$ Ṥ $y2肶`P>CDeO7R& ?lI/vh עmڳ7Ο?_7cPXݶy=[*-4w~hԡZh`M$; Y-%""/Q5WW^H<&)cxҭN¥LH*3`┩|'"RT#,, s> W6sK?S~#30:NHJf)Tbgܥ~]SӰFa}QZ1ǁ!ԁw#/d$cO PwfZ'F/]{kS ,P^=]tAP̦| 0a6@6l$ E#( Oyy>\R@ w{ԝ?"X8FABB5jX4jPШՐT*dffԩSشiSK6ls=dğ1jL>DD<, ""R DDD HX) """b@DD@, ""R DDD HX) """b@DD@, ""R DDD HX) """b@DD@, ""R DDD HX) """b@DD@, ""R DDD HX) """b@DD@, ""R DDD HX) """b@DD@, ""R DDD HX) """b@DD@, ""R DDD HX) """b@DD@, ""R DDD HX) """b@DD@, ""R DDD HX) """b@DD@, ""R DDD HX) """8F;]vBDD"dB^^ 77Gnn.󑟟[_SZZꜟ  09Ad{ SSSeWqMx0s`'5ָqc$''Cٳ]$Irٱ9A`so{ڶmW09A`s9]4n9A`s xkvhas 0[svE;|s 09ޚ 19A`s9ps 09ޚ@``+s 09A.Z+s 09A.T*.0 09A``wj+s 09AX89A`só 09A``w|aw`s 0[s0 has 0[s(--uE;|s 09ޚ 19A`s9]>9A`só=bs 0[s` 09A`s5^ps 09ޚ@QQ+s 09AX89A`só 09AX89A`soƍhas 0[s` 09AX89A`só 09AX89A`só 09A8 AA`s xkps 09ޚ 19A`s9ps 09ޚ 19A`s9ps 09ޚ@t#Ƚ """HX) """b@DD@, ""R DDD HX) """b@DD@, ""R DDD HX) """b@DD@, ""R DDD HX) """{ mIENDB`photofilmstrip-3.7.2/data/icons/32x32/0000755000232200023220000000000013560357432017771 5ustar debalancedebalancephotofilmstrip-3.7.2/data/icons/32x32/apps/0000755000232200023220000000000013560357432020734 5ustar debalancedebalancephotofilmstrip-3.7.2/data/icons/32x32/apps/photofilmstrip.png0000644000232200023220000000231513560357351024526 0ustar debalancedebalancePNG  IHDR szzsBIT|d pHYsbb_'StEXtSoftwarewww.inkscape.org<JIDATXWMHg~Ǚfv?3İA]\et." CC %(9R@[,rŞ8 (|E4M)L"yxhhhɓ'a۶#ǁ$I]8~?A'ZE' ^YNMMy|zz333d6I0  IҶmdqr]P(Iǡi^m3yxx bmi$ à8(TU###8LEGUUAMӨ:݈iY~ikkk4 Grip8 I\.JAaXQQ/FY"Ϝ9CIh&-W( BWΚH$-'_ĉiL&e'4. )?Jvǎs(r3 ]]](HX[[+یa_?R)^pedY.: F_Wp]@p]P5akk p;B>GMM |>R cz1{wX@ve}xptb{{@ur~[Ӡ|uϨ뀰Ohl( vvvJݺ#eG_/dz[X_/E)h9LOO7n>?%Sx1w6~/O$o~9AO}7ϗX,nC&=נK-!6 E/YQ__y: |S_?M@p/]Nj/t Ν;GZ|E)9~<ȡY룘w?)y></nFx8%oFO2l pIENDB`photofilmstrip-3.7.2/data/icons/scalable/0000755000232200023220000000000013560357432020756 5ustar debalancedebalancephotofilmstrip-3.7.2/data/icons/scalable/apps/0000755000232200023220000000000013560357432021721 5ustar debalancedebalancephotofilmstrip-3.7.2/data/icons/scalable/apps/photofilmstrip.svg0000644000232200023220000006164113560357351025535 0ustar debalancedebalance Created by potrace 1.14, written by Peter Selinger 2001-2017 image/svg+xml photofilmstrip-3.7.2/data/icons/256x256/0000755000232200023220000000000013560357432020151 5ustar debalancedebalancephotofilmstrip-3.7.2/data/icons/256x256/apps/0000755000232200023220000000000013560357432021114 5ustar debalancedebalancephotofilmstrip-3.7.2/data/icons/256x256/apps/photofilmstrip.png0000644000232200023220000003201213560357351024703 0ustar debalancedebalancePNG  IHDR\rfsBIT|d pHYs  tEXtSoftwarewww.inkscape.org< IDATxyXTYUDTpE4]s$ܭLsink[J!+fh h!"c~fFf`s]%s{sg"a, 0 c:80a, cp` X0Ƃ0 `80a, cp` Fm N_ppp@zz:r9233 ŋ8z( j=`|Ik׮%}?|"؃q=h}ֶ`=׃PJAkpuu5IJ {`Tk`{0@P$=`\{`Z\.7IJ {`؃{؃{ v{0 ;;`')-=z؃{؃{؃{ v{0.`8`+ QddA σʩ@xV``80a, c:ԯ_.]š5k`kkkHO Si/R!וR-N0faӧO@`*~'U.?4? *݁2.^(//2ƍGDD1999{'{wi˖-&A?ÃΝ;'?L}A,Vf͚N>${{{ںuA3O *[VVV4p@""PH$(\LDDcǎ;BC 'NhrZTL֯_O-ZH""ڰa/*7 8]FΝ;G啸왜9s~7rqq""3g/RAsuuǏQϞ=ADD4k,_Ҽcʕti2֭[.%''BaÆX,}7o۶mDDNY #kkk_ҼQFsFk֬n߾=Pvv6mb ꫯ W݉H.SVL~mq2~HPǏb1H>t=""ڵkɯ -E(""<<_~Zb :=n5pvvJr-ZdcǪV>XEoҙ3g>n*͛ݻL& 5kAe˖QnnpΞ=K^^^e>|@ B%,X_yjڴi{niР>}֭[GDDZRU-^)22Lu% iƍ¯vrrA*A&OLř6mʾӦҰGv/Rc8@[z͟?\+i&ˣ7nP߾}}NÇ(//>2|̙jA5IQeѣG뜾{tR5j4\UV7Rnn.СCXta]vmϟ_n/ <$)77:tSz+++:<҅ ȸ~D"1)99ƌSa9s4r Qሩ[&*j֬IDsԩSiԢE ""::888_5%'j޼9XƌC5k$Ԯ]; 665jT&#-ۊe"PzzNUV[n=mڴ kFd"R7a+n h۶mTPP@QQQ4i$SEGGѳgϨ{6"H 3fɿ@ʭaÆɓ'uJqF4iRff&رèޤR)`lJ)m۶Q^^|8Fi @&MmVVVpԩSG.;;5i&tgΜAZZڴicǎڒޔKׯSNHJJR^ Yqqq9r$k׮mVz 0n8@BB|Xe߶m~ZLsb///ѣ6???z)) :;;S\\W.FSV(''祕s!@D3-ZD 0rPѣ*ۮ^>} ;;֭äIt>^cͲZR)N&7Q4k,_CiDoVh„ 믿{'A-M`@~)}4i$j۶ZqTQ9sF"keՁZHի\ڷoOsZ}]fJ%PNN8'&&4M2ªRv-… t i ŋl2ѣI}]ʢX,dڵj^6\ƍ_-[L?aÆ!//OTVM@WË/9c*LTp:yYrXn:""a[ ۷WA~z[CIe2y @-Z`ĉڵ Ŕ̡CӧO޽[ ܽ{W\X(F½6UHMm$nݺ[nFW^/лwo4lQQQ~X5NNNx77̔;Ç!}{[1> Bnn.;XsB|c2332e e0`̋;`ɧا*r\1>[ 44>ҤSoooaopNNs;\ikB+ryfD˖-!aaa(((|B ''Gk~}[ntS[4 ѷA2hѢRSS?++KiͯVZB5kزyo?4kY.5]ܿ\] )_9ElذAe||#F4Ν3Sҡ! +Yaee JvQ碭P(^aÆ5ʔ;ժU믺n$9fCڵ!JBlٲc8Lcgg_{ur0+ׯ-Vt5кuk@ll,Dc`o̊zZ$1`Ba_bHoybGݺu=R^ pqqAZвYP4Ç7_ƸHR U(М@|9 UVń 0<~^}U%MaggrF$IK$aws4̄˗/cÆ ؼy C @6m@pǎjb4h@̓}oB]uJ/W[@tv}i:XjETuP(D*<6k@ü\Q}5e=]t4^PB"/,ׯ_*~ƌ% X LҮĖ{Q]YRQ*)ĐȜP<ָ`W?>|Aλ~ 伈-Hs HJJEkkTP(x& n*ni((ȁH,ڝaH}_}\>hժU۴iX?pqG`0h 9 eeѣ(>X"2 }vh-C~3 Zt\H";;iG?bMEtt4ڶmW/ˀ(} 7[,e˖ƍR+իWq'O… cѨQ#\c/F><xLo<=j!)פ|5?uC@YzM9M:Ry3^32BƼy`ccE'ڵk777DFFbhР iB3h@o^2YhU<7.Hlg`0[EHӳ L^}5E$^-;@}nm<{ J\~G|'zes!жm[ 88آ& Y'X3b>M&L,}{w 4ƃ`L_өS'ېJj}n޼Ϟ=Ӛy _ YbB#D"aX(K/!5a&|e',';- xy_QHrW^x}hzzZZ*&O5d_s[jߕkkkDeA!+b( Rѳ{VdhLB;e=W^R׃ʿ䊩0ݻ?3e7ߢco߾ @>}XYYJH鉌 i֮]khp_Re#0Q]]brWWW_|y 2iD"G>~ @$bd"Sv`*k׮ŤI8q:w޽{ׁ'L,w^CժU:XǶ-0Il?;-jD5jDM)y H *Nbz i0_̐&M#x{IDAT5x뭷zj֭=?n "Ν>52c:rss}E@aBܹs(߿_oooHROƠA?;v4ޅ#}@K_H|8~0Uۆ> P( 맟)ϟ?Ǿ}EWMKKCbb")))?O|X/^M܇$2Q7oΕG>ccqeڢUVڹ=nArr2#|ăW^oRLDs6mgςTuSpIt jBTTfϞ]>UI8v׭k ϟIR ?_D XzPD{aVd85s&=?KtH+3XaÆ*U>Ϙ14>=x@fm R8s?Kb4h@tN’%Kݻw4i"##^ju5Oѻr˪Pj"ן;A:8ժa/!ܵƇْ/gQ6( r."/ q9 7Byz/]Y&jԨ/Ĵ...Qe/_Da4`VVrrr`eeeLL9wHII$UYlnlm(O㦘>lH<؊B{ ߴ mRiWf߿0ˇM/&&???,ZHH`_8rTݖFuRT{^SURwVo,9!*Hś`ȠFUl۶ : ڱ\@Y)իW -[e|*'$qJE6ttA^a+/=x~=(;~[zt`< "a(DѧOeʝRw\6c6f5 #Iu_+t 4mك?N,CN 4y-|8xlqu"jժPڵ<-2L8;;`X*}6xW ~tkN2dۇ!H@&t:4!b=fnIDGGW^f :v2k0Sy(Хϟ# p ddQ/[@ieط{=Bwa7Xd"͙C$g hٲadٳbZҸʔ)Wb 2%X*Uybd>T "I/1sp,[x8=֞IvE3Qք34y&~,^Xk;v`…/y9*`9mmmqzTs~Rɗ1.Af~U4o7ҍ2} Ν;kMSF \&LցJf/ΆQGM<"=?5hoyƌ^{#aK,FBZɶxt'e ~ߐdZ[ ±c m1"F诿 0 "ܬigg7/B./ */[3''O<10fGx`O)8ta%bHmQc98+JZĉf1(J, booۗ~>mrE.@½%&mᇶRd ? ͛ær]Yسed8Iͬ;U޸Cӱ"Y]!777qeQ+ݸqmq#~P%N ["]RQ=N A`.6l c*L2;j( r!c#56/Š4qCb}d䋃bL}|4r㬇&|`%]fs0Le(#~Km:#S't? YYjbGcsy')-jν'Q}Zƽ}ƇƏ gG> r^LT}fsU P?^ga[!xS5" "~Iӗtva*`(D&?fu^2cw8Voi=>~v 78Ø360 c|*T0 `80a, cp` X0Ƃ0 `80a, cp` X0Ƃ0 `80a, cp` X0Ƃ0 `80a, cp` X0Ƃ0 `80a, cp` X0Ƃ0 `80#նSN믿888 ==r@FF =z5{0Ҥkג>̟?_c>e{`x{{kUnAkRNRZ{`5$=`\ZT~`=׃P( v{0=X@.$=`\\`=p`=h ;Iia=׃m؃q=p`=p`=p`=h YYY;Iia={`{`Zt(22 {`A@ X <+0X0Ƃ0 `80a, cp` X0Ƃ0 `80bDdIENDB`photofilmstrip-3.7.2/data/icons/16x16/0000755000232200023220000000000013560357432017775 5ustar debalancedebalancephotofilmstrip-3.7.2/data/icons/16x16/apps/0000755000232200023220000000000013560357432020740 5ustar debalancedebalancephotofilmstrip-3.7.2/data/icons/16x16/apps/photofilmstrip.png0000644000232200023220000000117713560357351024537 0ustar debalancedebalancePNG  IHDRasBIT|d pHYs-ItEXtSoftwarewww.inkscape.org<IDAT8œka?{wyå#b@B:e[.vB:!" n.dE݄": n u+nm{r(\_Ua!szzJRZR Z<#MS*'''A GGZ-:FeMGA Z},u]hREdYFnjc1Zzysxd2AEI)olkk c fff$ib@1Hە(Jv^]RFf,H3)Z3;[Geɤ,*xLq6xؿ֚g"㘢(J3ܺ/Oy7y(v\]Rl6e}}])ٻ\kԔ/(@>; 9o>|'DIk7@.]gr0}IӔJW39C1|{B>hIENDB`photofilmstrip-3.7.2/data/icons/128x128/0000755000232200023220000000000013560357432020145 5ustar debalancedebalancephotofilmstrip-3.7.2/data/icons/128x128/apps/0000755000232200023220000000000013560357432021110 5ustar debalancedebalancephotofilmstrip-3.7.2/data/icons/128x128/apps/photofilmstrip.png0000644000232200023220000001340113560357351024700 0ustar debalancedebalancePNG  IHDR>asBIT|d pHYsmhtEXtSoftwarewww.inkscape.org<~IDATx]kXSW~p p AP#@Q@AE Z/kh:#ukV{uJ^kP#)` X"akB>t7?1ˡ%Fӭº`zZPݪ[9%nUsÇUiwsLρ9hN:*TXEE;nH`e"V^MYZvv6͜9vIhҤIF+@RܹsXv-vڅ}ΡšO>do2*F WQGΝ#[[[# ё***(44h :˖-xf?OY[[w蓑A{?-ѣGy J ?f?Oy{{w蓘HMMM4h #GڴiyzzAhXLQQQdggGm=P(l|O R١3mܸcϧ'NЃuɓqFl7L&|JOORJf?iO >coѺYLFKƆ D111lٲ KKKڿ?9s>ՕJJJ=5:}&ٙf͚B[nQyy9./)22)<J#F mNFEE1Ѹ.l$?Ss7\PR3(..Fjj*Ǝs0|Y28owq)))RSSLJr9h b1%&&Ҿ}ԩS4cƌ ڀ(;;۠Y.cZ||#GPBB jjj"gggŴeڱcPTT͚5mw;{xxЪU~njĭBCCi׮]$˩wG/&MD+Wm?cLOWz7:CXTTD6oL饗^;vbܺADss3rrr+Wbڴiqj10s //r޽{3ܔJ%R)\]]Ϝ0B!Pbb"YYY]ٿ :z(=I>}>C:yyڴ6W_8B C aZ7[ =>$#hȐ!ׯߏl`vjBL&(n#,yvMIM@,c۶m娪Ç%#pi35yyXN6 RB(Å  h@DǃY=S'> z?~aaaxήؘgOӳ'ǃ4-I ,J­[())ɓѿ3Ah65lVU2|;xb޽{ Omjbڅt-؊Jp;uZD6I͛7ϕ L'''1[PQQWWW07Wu5Pk3H$Rl_]$VuUjv())5"##1|p[W1O2nnnz_d*NOg(7cFg&*kؙ~rƄ}ߐ 鏎Fyy9L66+mȥa%1M]r\| of9rWEj~.g6m|ƢE޽[7::@KK`Ǿ/Gl4o4ZjqR _`AHIHc GsƎ@`` ֯_o2<˽%Ru#uBֿ0}xȗƲ RCsF Tݻy_9sc&w-&8퍴4ܿ&8ib>Z; .Z_aZ‚`Aw waDSS;%Ŷ...'No`!A<{V_j9F.BSSK.h[E"T*GNNVSb 0z¢Q<5-cns3χL&CDD3es!yu*—k5Ǭnkaai4ܾ}_^_???띝?aӆu؜ ۫2  [|5DNYeFa؈7vXnܰ<9: 'wqծ8<xo!vf:YM7 !!!۷/9r_ii)bbbPhG+K1ӗPxXx` ] U*VX, bzuuu&LÇ(Ҳ2G+B#k7l9 RԨUA=~}'g _o!fJ|~ٳgcܸq1c ++ [nq͛HOOGMM  -[֣kmllPvJ=Ęޕ~^J́:deehi^l߾y˦\.޽{Ǐ1XhXlv3gG|m-BEMspvvƝ;wpi椞={hhhj5T*]`f-AO᳌M~' Ny"/=V^TVV"fQqBqN5x<lmmQ^^WTOy1 ŋs򘙿7n@T#88XgXOXn jGsM^aAA0="';޽.\00qqqسgbPTyAP^Ñ#GLƚmn"53_ϷbX/H¨Fm}sqޟC P(|VUUDb梬 uuu(,,4/sMqa2x";C_%pvrjK"C<<O}q㥸XO ܵ_ :… L#cY_~#^IwttĖdUՐH॰@}*_䁀Q vLaÆĥKP(Vl?|LwiW Eڋpjuﮘ44m={ab(//78?XklヒqIӞ %!kQ=5id_ X{[hP;/hl)ЫW/&ٳօ??];5rCt <?) w^>({EBΟ?۷uU? 0j`W3x x<>U+m*L?hǧ~5Sp1Х5b1ؙo;6huMSU1T Hv|[B>dxTZ~c_L_ׯqqq8-Y9]eUpv]?KVf!gOpY;1-%KC`e&aD`kx!-s3}1.z0Yla`s5K8' rp`98XN,' rp`98XN,' rhmJBmm-Ν^LH$&X`A8%xzzֺirGP*z_R]mr &q0=n rh m/i9h )w#,8% BwsLAK*sLˁ9hN:wwt faH`,`98XN,'lЯIENDB`photofilmstrip-3.7.2/data/icons/48x48/0000755000232200023220000000000013560357432020007 5ustar debalancedebalancephotofilmstrip-3.7.2/data/icons/48x48/apps/0000755000232200023220000000000013560357432020752 5ustar debalancedebalancephotofilmstrip-3.7.2/data/icons/48x48/apps/photofilmstrip.png0000644000232200023220000000374413560357351024553 0ustar debalancedebalancePNG  IHDR00WsBIT|d pHYsDtEXtSoftwarewww.inkscape.org<aIDAThYmLT~{a^uљNgR-?1aJɖ]X1tMkZ\w6kXSStK]#YٴlChlȇ dvlf Or{s{{{~ @Caa! #p@ ʼ$I(++dBoot:x^XVܺu D3U(zp8xB)..F @ M6aP(t`0q'F[l.V"QIFIIIjF#_s H/0d2ڵ$IZtu}}=d"eֹ\.r\2aQ(!p8ȑ#17 9N*))^cMǎ{EVdyYFyl6JƖZ$jii bE`0N'l6B0 Cv, ד(j.serssj\ u:=zx'IEVKF֭[GԩSVI&t2`+**t:6OMM먬˗RXql@OO2220>>"Ҝ(^0O,0k"ҥKظq#]&6sATBR֭[܌VyԈ.fs\nt9;wжm>d0s?Y1`br7`Y~5~uYWrp[r΢vIENDB`photofilmstrip-3.7.2/data/photofilmstrip.xpm0000644000232200023220000001066313560357351021714 0ustar debalancedebalance/* XPM */ static char *p[] = { /* columns rows colors chars-per-pixel */ "32 32 144 2 ", " c black", ". c #010101", "X c #020202", "o c gray1", "O c #040404", "+ c gray2", "@ c #060606", "# c #070706", "$ c #070707", "% c gray3", "& c #090909", "* c gray4", "= c #0B0B0B", "- c #0C0C0B", "; c gray5", ": c #0E0E0E", "> c gray6", ", c #10100F", "< c #11110F", "1 c #101010", "2 c gray7", "3 c #131313", "4 c gray8", "5 c #161616", "6 c gray9", "7 c #181716", "8 c #191919", "9 c gray10", "0 c #1B1B1B", "q c gray11", "w c #1D1D1D", "e c #1E1E1E", "r c #202020", "t c gray13", "y c #232323", "u c gray14", "i c #252525", "p c gray15", "a c #272727", "s c #2B2925", "d c gray16", "f c #2A2A2A", "g c #2C2C2C", "h c gray18", "j c #35332D", "k c gray19", "l c #323232", "z c gray20", "x c #343434", "c c #353535", "v c gray21", "b c #373737", "n c #3A3830", "m c #3E3C33", "M c gray22", "N c #3A3A3A", "B c #3F3F3F", "V c #413F36", "C c gray25", "Z c #434241", "A c #474540", "S c #444444", "D c #464646", "F c gray29", "G c #4B4B4B", "H c gray30", "J c #56544B", "K c #58564B", "L c #5C594C", "P c #5D5A4C", "I c #505050", "U c gray32", "Y c #555555", "T c #565656", "R c gray34", "E c #585858", "W c #595858", "Q c gray35", "! c gray36", "~ c #5F5F5F", "^ c #646050", "/ c #726E5B", "( c gray38", ") c #646464", "_ c #676664", "` c #686868", "' c #6A6A6A", "] c #6D6D6D", "[ c #6F6F6F", "{ c #777363", "} c gray44", "| c gray45", " . c #767676", ".. c #777777", "X. c gray47", "o. c #8D8775", "O. c #A69E7E", "+. c #848484", "@. c gray54", "#. c gray56", "$. c #9A9480", "%. c #909090", "&. c gray59", "*. c gray60", "=. c #9F9F9F", "-. c #AFAFAF", ";. c #B9B4A3", ":. c gray71", ">. c #B6B6B6", ",. c #C6BC9C", "<. c #C8BF9D", "1. c #DECD87", "2. c #DFCD88", "3. c #DFCE8A", "4. c #DFCF8C", "5. c #DECF8D", "6. c #DFCF8E", "7. c #CCC29D", "8. c #D0C596", "9. c #D3C796", "0. c #D5C996", "q. c #DBCE97", "w. c #DDCF94", "e. c #DFCF95", "r. c #DECF96", "t. c #D0C69E", "y. c #DBCE98", "u. c #DBCF9E", "i. c #DED095", "p. c #DDD098", "a. c #DED09B", "s. c #DACDA0", "d. c gray81", "f. c gray84", "g. c #D8D4D2", "h. c #DAD6D3", "j. c #E3DEDB", "k. c gray91", "l. c #EFEFEF", "z. c #F1F1F1", "x. c gray96", "c. c #F6F6F6", "v. c #F9F9F9", "b. c white", /* pixels */ " ", "% z 1 X l 5 h w a y t d 0 k 4 z o : z * ", "b b.I 6 b.} c.#. f.-. >.d. &.l. ..b.1 R b.k ", "v b.I 5 b.} x.#. f.-. >.d. &.l. .b.1 T b.k ", "* v 2 o z 5 k w f y y d w k 5 x o 1 z * ", "@ $ ! . X X H $ ", "1 & : H o Q 6 = ", "p F T Y 8 3 ! 9 = > 3 ", " p ) + ] w X o 4 B o = 5 6 ", " X > X.2 R X g p 2 X + : a ", " % 8 E & h X & D t d X ", "M N 5 ; U O : > i ( e = ", " r c q X 8 % S *.=.: ", " X X M ' k.O O $ L ", " u ` z.e n m q.", " $ @.v.G : ^ 8.O.7 # 0.y.", " : +.b.Q o , 6.1.w.9.3.4./ ", " y | b.~ h.;.i.1.1.p.P ", " Z - g H :.%.& g.j._ V s ", " $.r.,.. $ W <.{ w C [ O ", " O t.1.u.s.5.1.a.- O g > ", " o.e.1.2.7.A J O ", " < K j ", " ", " ", " ", " ", "% z 1 X l 5 h w a y t d 0 k 4 z o : z * ", "b b.I 6 b.} c.#. f.-. >.d. &.l. ..b.1 R b.k ", "v b.I 5 b.} x.#. f.-. >.d. &.l. .b.1 T b.k ", "* z 1 o z 5 k w f y y d w k 5 z o 1 z * ", " " }; photofilmstrip-3.7.2/windows/0000755000232200023220000000000013560357432016656 5ustar debalancedebalancephotofilmstrip-3.7.2/windows/photofilmstrip.bat0000644000232200023220000000005313560357352022430 0ustar debalancedebalance@"%~dp0..\python" "%~dp0photofilmstrip" %* photofilmstrip-3.7.2/windows/photofilmstrip-cli.bat0000755000232200023220000000006013560357352023176 0ustar debalancedebalance@"%~dp0..\python" "%~dp0photofilmstrip-cli" %* photofilmstrip-3.7.2/docs/0000755000232200023220000000000013560357432016114 5ustar debalancedebalancephotofilmstrip-3.7.2/docs/help/0000755000232200023220000000000013560357432017044 5ustar debalancedebalancephotofilmstrip-3.7.2/docs/help/more.rst0000644000232200023220000000016413560357351020541 0ustar debalancedebalanceMore functions ============== - Export and Import of PhotoFilmStrips - Command line interface (photofilmstrip-cli) photofilmstrip-3.7.2/docs/help/_static/0000755000232200023220000000000013560357432020472 5ustar debalancedebalancephotofilmstrip-3.7.2/docs/help/_static/logo.png0000644000232200023220000000505213560357351022142 0ustar debalancedebalancePNG  IHDR@@iqsBIT|d pHYstEXtSoftwarewww.inkscape.org< IDATx[{PTݽww^B@.>b+H u )ݩJS!8ht0#uщt+c;&H6hhXG+".]p @o{{~/<Fl6n\v ՂBχ\.G}}=}l6DEEpmmmpBɓy.f vZǁ}Wf̘߾}e"""|sss}b T@<2lTvb0CV|},|:;;,X+zjkҏ"T*G|쥥={.V ,j5n~0`޽</␟8:d2SEff&˲Oj'sLF{Eh4N#A7n=yH$ݶm(;;h޼yeXHV aaafl':_ч~Xrr2Ԑb=٧Itt8pEEE Z^G<ϓR9sܼy3 *eddз~K)))']322裏>zj@[l۷\.lt9&]{=R*L&#FC8*((2  ĥ'S.>\ 'DӧOf͚E%T,K&;FVꋋi̙cBŋ`0lr ,YBV?ONT*) Ӵ`oعs'dQPHHYV:uH(iii4m4Z#. qqqŲe`2xP\\<Z?FHH4 è}3g, 0<` wWP(tǎd0($$BCCiʔ)cF$锐@ Z(>>***H*~,LK,]vQ@@L&bFY&99V+ҦM(++˛@1 nݺ!Lx'aYV +WPhh(-_t:]D *é֮]K111>BBӫJ)))A&MRvv6%''?D"E)!!g;T}r8E| m߾] =QTjhii޽{UXѣGQ]]$%%H8cqf|d٨ ݸq饗^ki4|--uU}-¬Yp ?ZDT Z Á1Vkk+Z[[}asa؝;wp]|D{{;l6#00p̮NJ,-ѳ,rI3@qoJ"&&[nKPU? Щpt?Ny S'oSL$&&"""nw_0/^Dzz:"##GLonT MmO~ g]rL7gY?irt _r9t:PUUBtRaÆ ~ ĥxu + '*x3'!uD`X%~[:] F.]&^gL3Gp' f  [% TU8t:H$455yu& ~'}X_WNJ5ƅqo@(eQSSI&fϞm 5 VbzL ~w$`l%('ᔸu;~QPD,p0gnT*\|. N+VD_t:JSgaF&,'om՘.s6 VHNJ¼tvEÇhnn(//Gll,_444qؾ8ܕ?nёQ3PK8}*j߂yj},pt{W-mHYJPXboJ܌F[H444yl6c8~8ܯ [,9r. vuuu8u_w, hNUL 2>NUL if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.installed, then set the SPHINXBUILD environment variable to point echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.http://sphinx-doc.org/ exit /b 1 ) %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% goto end :help %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% :end popd photofilmstrip-3.7.2/docs/help/renderpfs.rst0000644000232200023220000001043613560357351021572 0ustar debalancedebalanceRender a slideshow ================== If you are done designing your PhotoFilmStrip you can create a movie file. The possibilities to set up the movie are described here. .. _render_settings: Settings -------- .. _output: Output ------ .. _output_format: Format ~~~~~~ This option allows you to specify the desired output format. The following table shows which formats are available with their default properties. Single pictures ``````````````` The output is rendered as single picture files to the output folder. Notice, with the videonorm NTSC (~30 fps) and a PhotoFilmStrip with a total length of 10 seconds results to 300 pictures. Each with a size of approximatally 2 MB results to 600 MB. Properties '''''''''' - ResampleFilter (Nearest, Bilinear, Bicubic, Antialias) VCD (MPG) ````````` Creates movie files for Video-CDs. Properties '''''''''' - Bitrate (overrides profile specific) - RenderSubtitle (true, false) - SubtitleSettings SVCD, DVD (MPG) ``````````````` Creates MPEG-2 conform movie files. Properties '''''''''' - Bitrate (overrides profile specific) - RenderSubtitle (true, false) - SubtitleSettings Theora/Vorbis (OGV) ``````````````````` Creates OGV movie files. Properties '''''''''' - Bitrate (overrides profile specific) - RenderSubtitle (true, false) - SubtitleSettings x264 (MKV, MP4) ``````````````` Creates H.264 or MPEG-4 part 10 video files. Properties '''''''''' - Bitrate (overrides profile specific) - RenderSubtitle (true, false) - SubtitleSettings - SpeedPreset: default is medium (6) - Profile (main, **high**, baseline, constrained-baseline) x265 (MKV) `````````` Creates H.265 or MPEG-H part 2 video files. Properties '''''''''' - Bitrate (overrides profile specific) - RenderSubtitle (true, false) - SubtitleSettings - SpeedPreset: default is medium (6) Common properties ~~~~~~~~~~~~~~~~~ - SpeedPreset: - (0): None - (1): ultrafast - (2): superfast - (3): veryfast - (4): faster - (5): fast - (6): medium - (7): slow - (8): slower - (9): veryslow - (10): placebo - SubtitleSettings: Use several settings splitted via semicolon. Some useful settings are: - shaded-background=1 - valignment=bottom|top - font-desc= (font-desc=Arial 12) - color=0xAARRGGBB (color=0xff00ff00 for green without transparancy) A full list of properties can be found `here `_. The following value shows a green subtitle at the top of the screen: ``shaded-background=1;valignment=top;font-desc=Arial 12;color=0xff00ff00`` .. _render_profile: Profile ~~~~~~~ The profile field allows you to select the desired video type. The following table shows which types are available with their default properties. +---------+---------------------+--------------+-------------+ | Name | Resolution | Bitrate | Compression | +=========+=====================+==============+=============+ | VCD | 352x288 (PAL) | 1150 kBit/s | MPEG-1 | | | 352x240 (NTSC) | | | +---------+---------------------+--------------+-------------+ | SVCD | 576x480 (PAL) | 2500 kBit/s | MPEG-2 | | | 480x480 (NTSC) | | | +---------+---------------------+--------------+-------------+ | DVD | 720x576 (PAL) | 8000 kBit/s | MPEG-2 | | | 720x480 (NTSC) | | | +---------+---------------------+--------------+-------------+ | Medium | 640x360 (360p) | 1000 kBit/s | various | +---------+---------------------+--------------+-------------+ | Medium | 854x480 (480p) | 2500 kBit/s | various | +---------+---------------------+--------------+-------------+ | HD | 1280x720 (720p) | 7500 kBit/s | various | +---------+---------------------+--------------+-------------+ | Full-HD | 1920x1080 (1080p) | 12000 kBit/s | various | +---------+---------------------+--------------+-------------+ | UHD | 3840x2160 (2160p) | 50000 kBit/s | various | +---------+---------------------+--------------+-------------+ | UHD-2 | 7600x4320 (4320p) | 60000 kBit/s | various | +---------+---------------------+--------------+-------------+ photofilmstrip-3.7.2/docs/help/Makefile0000644000232200023220000000114313560357351020503 0ustar debalancedebalance# Minimal makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build SPHINXPROJ = PhotoFilmStrip SOURCEDIR = . BUILDDIR = _build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)photofilmstrip-3.7.2/docs/help/conf.py0000644000232200023220000001235413560357351020350 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip documentation build configuration file, created by # sphinx-quickstart on Sat Nov 18 15:56:31 2017. # # This file is execfile()d with the current directory set to its # containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # # import os # import sys # sys.path.insert(0, os.path.abspath('.')) import time # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. # # needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # # source_suffix = ['.rst', '.md'] source_suffix = '.rst' # The master toctree document. master_doc = 'index' # General information about the project. project = u'PhotoFilmStrip' copyright = u'%s, Jens Göpfert' % time.strftime('%Y') author = u'Jens Göpfert' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = u'src' # The full version, including alpha/beta/rc tags. release = u'src' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. language = None # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This patterns also effect to html_static_path and html_extra_path exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = False # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # html_theme = 'agogo' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. # html_theme_options = { 'headerbg': '#222 url(bgtop.png) top left repeat-x', 'bgcolor': '#000000', 'linkcolor': '#337ab7', } # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # Custom sidebar templates, must be a dictionary that maps document names # to template names. # # This is required for the alabaster theme # refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars html_sidebars = { '**': [ 'relations.html', # needs 'show_related': True theme option to display 'searchbox.html', ] } html_show_sourcelink = False #html_use_index = False html_logo = '_static/logo.png' # -- Options for HTMLHelp output ------------------------------------------ # Output file base name for HTML help builder. htmlhelp_basename = 'photofilmstrip' # -- Options for LaTeX output --------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # # 'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). # # 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. # # 'preamble': '', # Latex figure (float) alignment # # 'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ (master_doc, 'PhotoFilmStrip.tex', u'PhotoFilmStrip Documentation', u'Jens Göpfert', 'manual'), ] # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ (master_doc, 'photofilmstrip', u'PhotoFilmStrip Documentation', [author], 1) ] # -- Options for Texinfo output ------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ (master_doc, 'PhotoFilmStrip', u'PhotoFilmStrip Documentation', author, 'PhotoFilmStrip', 'One line description of project.', 'Miscellaneous'), ] photofilmstrip-3.7.2/docs/help/copyright.rst0000644000232200023220000010557313560357351021621 0ustar debalancedebalanceCopyright ========= GNU GENERAL PUBLIC LICENSE -------------------------- Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. https://fsf.org/ Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble ~~~~~~~~ The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS ~~~~~~~~~~~~~~~~~~~~ 0. Definitions. ^^^^^^^^^^^^^^^ "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. ^^^^^^^^^^^^^^^ The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. ^^^^^^^^^^^^^^^^^^^^^ All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: - a) The work must carry prominent notices stating that you modified it, and giving a relevant date. - b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". - c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. - d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: - a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. - b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. - c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. - d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. - e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. ^^^^^^^^^^^^^^^^^^^^ "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: - a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or - b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or - c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or - d) Limiting the use for publicity purposes of names of licensors or authors of the material; or - e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or - f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. ^^^^^^^^^^^^^^^ You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. ^^^^^^^^^^^^ A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. ^^^^^^^^^^^^^^^^^^^^^^^^^^^ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. :: Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: :: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands \`show w' and \`show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see https://www.gnu.org/licenses/. The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read https://www.gnu.org/licenses/why-not-lgpl.html. photofilmstrip-3.7.2/docs/help/index.rst0000644000232200023220000000067513560357351020715 0ustar debalancedebalance.. PhotoFilmStrip documentation master file, created by sphinx-quickstart on Sat Nov 18 15:56:31 2017. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. PhotoFilmStrip documentation ============================ .. toctree:: :maxdepth: 2 copyright introduction createpfs renderpfs more Miscellaneous ============= * :ref:`genindex` * :ref:`search` photofilmstrip-3.7.2/docs/help/createpfs.rst0000644000232200023220000000376713560357351021567 0ustar debalancedebalanceCreating a new PhotoFilmStrip ============================= Project properties ------------------ Total length ~~~~~~~~~~~~ If this option is activated you can override the duration of the single pictures and setup the total movie length.. This is useful if you want to integrate the PhotoFilmStrip in another video project. Notice, the duration of the single pictures is multiplied with a factor, a ratio to the desired total length.. A PhotoFilmStrip containing two pictures with the durations of 2 and 4 seconds results to durations of. 3.3 and 6.7 seconds in a PhotoFilmStrip with a total length of 10 seconds. The ratio is 1.67 (10.0 / 6.0). You have two options to specify the total length. - Manual, to set the total length for yourself. - Audio file, to set the total length to the length of an audio file. .. _add_pics: Add pictures ------------ To add pictures to your PhotoFilmStrip you can use the entry in the main menu (Tools -> Import pictures), the toolbutton in the toolbar or by dropping some file in the imagelist at the bottom of the main window. .. _motion_control: Motion control -------------- After selecting a picture you see it once on the left hand side and once on the right hand side. Now you can move a rectange on both pictures. To zoom the rectangle simply use the mousewheel. Move it by dragging it with the mouse. The rectangle on the left picture defines where the animated path of the picture starts. The ending point is defined with the rectangle on the right picture. .. _settings: Settings -------- Below the two images you can see a panel to adjust some settings for the selected picture. It is possible to rotate it clockwise and counter clockwise. You have the choice between some nice effects like black and white etc. Furthermore you can type in a comment to the picture. These comments will be generated into a subtitle file. This allows you to easily turn on/off the comments while playing your PhotoFilmStrip on a DVD-Player or with your favorite software player. photofilmstrip-3.7.2/docs/manpage/0000755000232200023220000000000013560357432017524 5ustar debalancedebalancephotofilmstrip-3.7.2/docs/manpage/photofilmstrip.10000644000232200023220000000042513560357351022672 0ustar debalancedebalance.TH USAGE: "1" "October 2014" "Usage: photofilmstrip [options]" "User Commands" .SH NAME photofilmstrip \- Slideshow creator with Ken Burns effect .SH SYNOPSIS .B photofilmstrip .SH "SEE ALSO" .BR photofilmstrip-cli (1). .SH AUTHOR photofilmstrip was written by Jens Goepfert. photofilmstrip-3.7.2/docs/manpage/photofilmstrip-cli.10000644000232200023220000000312713560357351023441 0ustar debalancedebalance.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.2. .TH PHOTOFILMSTRIP-CLI "1" "October 2014" "photofilmstrip-cli 2.1.0-trunk" "User Commands" .SH NAME photofilmstrip-cli \- Command Line Interface for PhotoFilmStrip a slideshow creator with Ken Burns effect .SH SYNOPSIS .B photofilmstrip-cli [\fI\,options\/\fR] .SH OPTIONS .TP \fB\-\-version\fR show program's version number and exit .TP \fB\-h\fR, \fB\-\-help\fR show this help message and exit .TP \fB\-p\fR PROJECT, \fB\-\-project\fR=\fI\,PROJECT\/\fR specifies the project file .TP \fB\-o\fR PATH, \fB\-\-outputpath\fR=\fI\,PATH\/\fR The path where to save the output files. Use \- for stdout. .TP \fB\-t\fR PROFILE, \fB\-\-profile\fR=\fI\,PROFILE\/\fR 0=Medium, 1=HD, 2=FULL\-HD [default: 0] .TP \fB\-n\fR VIDEONORM, \fB\-\-videonorm\fR=\fI\,VIDEONORM\/\fR n=NTSC, p=PAL [default: p] .TP \fB\-f\fR FORMAT, \fB\-\-format\fR=\fI\,FORMAT\/\fR 0=Single pictures, 1=VCD (MPG), 2=SVCD (MPG), 3=DVD (MPG), 4=Theora/Vorbis (OGV), 5=x264/MP3 (MKV), 6=Preview [default: 4] .TP \fB\-a\fR, \fB\-\-draft\fR enable draft mode \- Activate this option to generate a preview of your PhotoFilmStrip. The rendering process will speed up dramatically, but results in lower quality. .TP \fB\-d\fR, \fB\-\-debug\fR enable debug logging .SH "SEE ALSO" The full documentation for .B photofilmstrip-cli is maintained as a Texinfo manual. If the .B info and .B photofilmstrip-cli programs are properly installed at your site, the command .IP .B info photofilmstrip-cli .PP should give you access to the complete manual. .SH AUTHOR photofilmstrip was written by Jens Goepfert. photofilmstrip-3.7.2/photofilmstrip/0000755000232200023220000000000013560357432020247 5ustar debalancedebalancephotofilmstrip-3.7.2/photofilmstrip/_scmInfo.py0000644000232200023220000000002413560357431022351 0ustar debalancedebalanceSCM_REV = "5a61cd0" photofilmstrip-3.7.2/photofilmstrip/ux/0000755000232200023220000000000013560357432020703 5ustar debalancedebalancephotofilmstrip-3.7.2/photofilmstrip/ux/Ux.py0000644000232200023220000000436113560357351021655 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2018 Jens Goepfert # import logging from photofilmstrip.lib.DestructionManager import Destroyable import importlib class UxService(Destroyable): __instance = None @classmethod def GetInstance(cls): if cls.__instance is None: cls.__instance = UxService() return cls.__instance def __init__(self): Destroyable.__init__(self) self.uxAdapters = [] for modname in ("gnome", "uwp"): try: ux_module = importlib.import_module("photofilmstrip.ux." + modname) except: logging.getLogger('UxService').debug( "importing UxAdapter '%s' failed", modname, exc_info=1) continue if hasattr(ux_module, "ux_init"): try: uxAdapter = getattr(ux_module, "ux_init")() if isinstance(uxAdapter, UxAdapter): self.uxAdapters.append(uxAdapter) except: logging.getLogger('UxService').error( "initializing UxAdapter '%s' failed", ux_module, exc_info=1) def Initialize(self): for uxAdapter in self.uxAdapters: uxAdapter.OnInit() def Start(self): for uxAdapter in self.uxAdapters: uxAdapter.OnStart() def Destroy(self): for uxAdapter in self.uxAdapters: uxAdapter.OnDestroy() class UxAdapter: def OnInit(self): ''' Triggers on right before GUI is started. ''' raise NotImplementedError() def OnStart(self): ''' Triggers right after the process has started. Raise PreventStartupSignal if startup may be prevented ''' pass def OnDestroy(self): ''' Triggers on shut down to clean up stuff. ''' pass class Ux: ''' Entity for user experience information ''' def __init__(self): self.uxEvents = [] def AddUxEvent(self, uxEvent): self.uxEvents.append(uxEvent) def GetUxEvents(self): return self.uxEvents class UxPreventStartupSignal(Exception): pass photofilmstrip-3.7.2/photofilmstrip/ux/__init__.py0000644000232200023220000000000013560357351023002 0ustar debalancedebalancephotofilmstrip-3.7.2/photofilmstrip/ux/uwp.py0000644000232200023220000000542413560357351022075 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2018 Jens Goepfert # import logging import optparse import os import subprocess import sys from photofilmstrip.lib.jobimpl.IVisualJobManager import IVisualJobManager from photofilmstrip.lib.jobimpl.JobManager import JobManager from photofilmstrip.ux.Ux import UxAdapter, Ux, UxPreventStartupSignal class UwpAdapter(UxAdapter, IVisualJobManager): def __init__(self, svcClientPath): self.svcClientPath = svcClientPath self.svcClient = None def OnInit(self): startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW self.svcClient = subprocess.Popen( [self.svcClientPath], stdin=subprocess.PIPE, startupinfo=startupinfo) JobManager().AddVisual(self) def __SendLines(self, lines): if self.svcClient is None: return logging.getLogger('UwpService').debug("Current Exit-Code %s", self.svcClient.poll()) for line in lines: self.svcClient.stdin.write(line.encode("utf-8")) self.svcClient.stdin.write("\r\n".encode("utf-8")) self.svcClient.stdin.flush() def OnDestroy(self): lines = ["exit"] self.__SendLines(lines) def ShowToast(self, title, msg, image, launch): lines = ["notify", title, msg, image, "--uwp-open \"" + launch + "\"", "process"] self.__SendLines(lines) def LogEvent(self, eventName): lines = ['event', eventName, "process"] self.__SendLines(lines) def RegisterJob(self, job): if isinstance(job, Ux): for uxEvent in job.GetUxEvents(): self.LogEvent(uxEvent) def RemoveJob(self, job): if job.GetGroupId() != "render": return if not job.IsAborted(): self.ShowToast(_("Slideshow created!"), job.GetName(), job.GetOutputFile(), job.GetOutputFile()) def OnStart(self): parser = optparse.OptionParser(usage=optparse.SUPPRESS_USAGE) parser.error = lambda msg: None parser.add_option("-u", "--uwp-open", help="opens a folder from uwp-bridge") options = parser.parse_args()[0] if options.uwp_open: from photofilmstrip.action.ActionOpenFolder import ActionOpenFolder ActionOpenFolder(options.uwp_open).Execute() raise UxPreventStartupSignal() def ux_init(): pfsPath = os.path.dirname(sys.argv[0]) svcClientPath = os.path.join(pfsPath, "..", "Tools", "UwpBridge.exe") logging.getLogger('UwpAdapter').debug( "trying UwpBridge.exe in '%s'", svcClientPath) if os.path.isfile(svcClientPath): return UwpAdapter(svcClientPath) photofilmstrip-3.7.2/photofilmstrip/ux/gnome.py0000644000232200023220000000273013560357351022364 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2018 Jens Goepfert # import gi gi.require_version('Notify', '0.7') gi.require_version('GdkPixbuf', '2.0') from gi.repository import GdkPixbuf, Gio, GLib, Notify from photofilmstrip import Constants from photofilmstrip.lib.jobimpl.IVisualJobManager import IVisualJobManager from photofilmstrip.lib.jobimpl.JobManager import JobManager from photofilmstrip.res.images import ICON_16 from photofilmstrip.ux.Ux import UxAdapter class UxGnome(UxAdapter, IVisualJobManager): def __init__(self): JobManager().AddVisual(self) def OnInit(self): Notify.init(Constants.APP_NAME) def RegisterJob(self, job): pass def ShowNotification(self, title, info, path): data = ICON_16.GetData() data_bytes = GLib.Bytes.new(list(data)) data_stream = Gio.MemoryInputStream.new_from_bytes(data_bytes) icon = GdkPixbuf.Pixbuf.new_from_stream(data_stream) notification = Notify.Notification.new(title, info) notification.set_image_from_pixbuf(icon) notification.add_action("action", _(u'Play video'), lambda: None) notification.show() def RemoveJob(self, job): if job.GetGroupId() != "render": return if not job.IsAborted(): self.ShowNotification( _("Slideshow created!"), job.GetName(), job.GetOutputFile()) def ux_init(): return UxGnome() photofilmstrip-3.7.2/photofilmstrip/__init__.py0000644000232200023220000000017113560357351022357 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2011 Jens Goepfert # photofilmstrip-3.7.2/photofilmstrip/action/0000755000232200023220000000000013560357432021524 5ustar debalancedebalancephotofilmstrip-3.7.2/photofilmstrip/action/ActionI18N.py0000644000232200023220000000214613560357351023716 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2011 Jens Goepfert # import gettext import os from photofilmstrip.action.IAction import IAction from photofilmstrip import Constants from photofilmstrip.lib.Settings import Settings class ActionI18N(IAction): def __init__(self, lang=None): self.__lang = lang def GetName(self): return _("Language") def Execute(self): curLang = Settings().GetLanguage() localeDir = None for localeDir in (os.path.join(Constants.APP_DIR, "share", "locale"), os.path.join(Constants.APP_DIR, "locale"),): if os.path.isdir(localeDir): break if localeDir is None: gettext.install(Constants.APP_NAME) return try: lang = gettext.translation(Constants.APP_NAME, localeDir, languages=[curLang, "en"]) lang.install(True) except IOError: gettext.install(Constants.APP_NAME) photofilmstrip-3.7.2/photofilmstrip/action/WxAbstractAction.py0000644000232200023220000000165213560357351025322 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2011 Jens Goepfert # import wx from photofilmstrip.action.IAction import IAction class WxAbstractAction(IAction): def __init__(self): pass def GetBitmap(self, art=None): raise NotImplementedError() def ToMenu(self, evtHandler, menu, ident=None): if ident is None: ident = wx.NewId() mitm = wx.MenuItem(menu, ident, self.GetName()) try: bmp = self.GetBitmap(wx.ART_MENU) except NotImplementedError: bmp = None if bmp: mitm.SetBitmap(bmp) menu.Append(mitm) evtHandler.Bind(wx.EVT_MENU, self.__OnExecute, id=ident) return mitm def Bind(self, evtHandler, evt): evtHandler.Bind(evt, self.__OnExecute) def __OnExecute(self, event): self.Execute() event.Skip() photofilmstrip-3.7.2/photofilmstrip/action/ActionPlayVideo.py0000644000232200023220000000074513560357351025136 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2011 Jens Goepfert # import os from photofilmstrip.action.IAction import IAction from photofilmstrip.lib.util import StartFile class ActionPlayVideo(IAction): def __init__(self, outFile): self.outFile = outFile def GetName(self): return _(u'Play video') def Execute(self): if os.path.isfile(self.outFile): StartFile(self.outFile) photofilmstrip-3.7.2/photofilmstrip/action/ActionCenterPath.py0000644000232200023220000000227013560357351025272 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2013 Jens Goepfert # from photofilmstrip.action.IAction import IAction from photofilmstrip.core.Aspect import Aspect from photofilmstrip.core import PILBackend class ActionCenterPath(IAction): def __init__(self, picture, aspect): self.__picture = picture self.__aspect = aspect def GetName(self): return _(u'Centralize motion') def Execute(self): try: width, height = PILBackend.GetImageSize( self.__picture.GetFilename()) except: return ratio = Aspect.ToFloat(self.__aspect) picRatio = width / height if picRatio > ratio: scaledWidth = height * ratio scaledHeight = height else: scaledWidth = width scaledHeight = width / ratio centerRect = (int(round((width - scaledWidth) / 2.0)), int(round((height - scaledHeight) / 2.0)), int(round(scaledWidth)), int(round(scaledHeight))) self.__picture.SetStartRect(centerRect) self.__picture.SetTargetRect(centerRect) photofilmstrip-3.7.2/photofilmstrip/action/__init__.py0000644000232200023220000000017113560357351023634 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2011 Jens Goepfert # photofilmstrip-3.7.2/photofilmstrip/action/ActionOpenFolder.py0000644000232200023220000000135413560357351025274 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2011 Jens Goepfert # import os import subprocess from photofilmstrip.action.IAction import IAction class ActionOpenFolder(IAction): def __init__(self, outFile): self.outFile = outFile def GetName(self): return _(u'Open folder') def GetBitmap(self): import wx return wx.ArtProvider.GetBitmap('PFS_FOLDER_OPEN_16') def Execute(self): outDir = os.path.dirname(self.outFile) if not os.path.isdir(outDir): return if os.name == "nt": os.startfile(outDir) # pylint: disable=no-member else: subprocess.Popen(["xdg-open", outDir]) photofilmstrip-3.7.2/photofilmstrip/action/ActionAutoPath.py0000644000232200023220000000365113560357351024766 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2011 Jens Goepfert # import random from photofilmstrip.action.IAction import IAction from photofilmstrip.core.Aspect import Aspect from photofilmstrip.core import PILBackend class ActionAutoPath(IAction): def __init__(self, picture, aspect): self.__picture = picture self.__aspect = aspect def GetName(self): return _(u'Random motion') def Execute(self): try: width, height = PILBackend.GetImageSize( self.__picture.GetFilename()) except: return if self.__picture.GetWidth() == -1: # FIXME: stupid if self.__picture.SetWidth(width) self.__picture.SetHeight(height) ratio = Aspect.ToFloat(self.__aspect) if width < height: # portrait startRect = (0, 0, width, width / ratio) targetRect = (0, height - (width / ratio), width, width / ratio) else: scaledWidth = width * 0.75 startRect = (0, 0, width, width / ratio) d = random.randint(0, 3) if d == 0: targetRect = (0, 0, scaledWidth, scaledWidth / ratio) elif d == 1: targetRect = (0, height - (scaledWidth / ratio), scaledWidth, scaledWidth / ratio) elif d == 2: targetRect = (width - scaledWidth, 0, scaledWidth, scaledWidth / ratio) elif d == 3: targetRect = (width - scaledWidth, height - (scaledWidth / ratio), scaledWidth, scaledWidth / ratio) if random.randint(0, 1): targetRect, startRect = startRect, targetRect self.__picture.SetStartRect(startRect) self.__picture.SetTargetRect(targetRect) photofilmstrip-3.7.2/photofilmstrip/action/IAction.py0000644000232200023220000000040213560357351023420 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2011 Jens Goepfert # class IAction: def GetName(self): raise NotImplementedError() def Execute(self): raise NotImplementedError() photofilmstrip-3.7.2/photofilmstrip/action/WxAction.py0000644000232200023220000000134513560357351023635 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2011 Jens Goepfert # from photofilmstrip.action.WxAbstractAction import WxAbstractAction class WxAction(WxAbstractAction): def __init__(self, name, target, args=None, bmp=None): WxAbstractAction.__init__(self) self.name = name self.target = target if args is None: args = () self.args = args self.bmp = bmp def GetName(self): return self.name def Execute(self): return self.target(*self.args) def GetBitmap(self, art=None): if isinstance(self.bmp, dict): return self.bmp.get(art) else: return self.bmp photofilmstrip-3.7.2/photofilmstrip/action/ActionRender.py0000644000232200023220000000766613560357351024472 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2011 Jens Goepfert # import logging import os from photofilmstrip.action.IAction import IAction from photofilmstrip.lib.Settings import Settings from photofilmstrip.lib.util import CheckFile from photofilmstrip.core.Renderer import RENDERERS from photofilmstrip.core.RenderEngine import RenderEngineSlideshow, \ RenderEngineTimelapse from photofilmstrip.core.RenderJob import RenderJob from photofilmstrip.core.GPlayer import GPlayer class ActionRender(IAction): def __init__(self, photoFilmStrip, profile, rendererClass, draftMode, outpath=None): self.__photoFilmStrip = photoFilmStrip self.__profile = profile self.__rendererClass = rendererClass self.__draftMode = draftMode self.__outpath = outpath self.__renderJob = None def GetName(self): return _(u'Start') def _CheckAndGetOutFile(self): if self.__outpath == "-": return projFile = self.__photoFilmStrip.GetFilename() baseDir = os.path.dirname(projFile) baseDir = os.path.join(baseDir, self.__profile.GetName()) if not os.path.isdir(baseDir): os.makedirs(baseDir) outFile = os.path.join(baseDir, os.path.basename(os.path.splitext(projFile)[0])) return outFile def _SaveSettings(self): settings = Settings() settings.SetLastProfile(self.__profile.GetName()) try: idxRenderer = RENDERERS.index(self.__rendererClass) except ValueError: return settings.SetUsedRenderer(idxRenderer) def Execute(self): audioFiles = [] audioLength = 0 for audioFile in self.__photoFilmStrip.GetAudioFiles(): if CheckFile(audioFile): length = GPlayer(audioFile).GetLength() audioFiles.append(audioFile) logging.debug("Using audiofile '%s' with length: %s", audioFile, length) audioLength += length else: logging.warning("Missing audiofile '%s'!", audioFile) outFile = self._CheckAndGetOutFile() self._SaveSettings() savedProps = Settings().GetRenderProperties(self.__rendererClass.__name__) for prop in self.__rendererClass.GetProperties(): value = savedProps.get(prop.lower(), self.__rendererClass.GetProperty(prop)) self.__rendererClass.SetProperty(prop, value) totalLength = self.__photoFilmStrip.GetDuration(False) if totalLength == -1: totalLength = int(round((audioLength + 500) / 1000.0)) renderer = self.__rendererClass() renderer.Init(self.__profile, self.__photoFilmStrip.GetAspect(), outFile) renderer.SetAudioFiles(audioFiles) if self.__photoFilmStrip.GetTimelapse(): uxEvent = "RenderTimeLapse" renderEngine = RenderEngineTimelapse(self.__profile, self.__photoFilmStrip.GetPictures(), self.__draftMode) else: uxEvent = "RenderSlideshow" renderEngine = RenderEngineSlideshow(self.__profile, self.__photoFilmStrip.GetPictures(), self.__draftMode, totalLength) name = "%s (%s)" % (self.__photoFilmStrip.GetName(), self.__profile.GetName()) self.__renderJob = RenderJob(name, renderer, renderEngine.GetTasks()) self.__renderJob.AddUxEvent(uxEvent) self.__renderJob.AddUxEvent(self.__profile.GetName()) def GetRenderJob(self): return self.__renderJob photofilmstrip-3.7.2/photofilmstrip/res/0000755000232200023220000000000013560357432021040 5ustar debalancedebalancephotofilmstrip-3.7.2/photofilmstrip/res/__init__.py0000644000232200023220000000017113560357351023150 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # photofilmstrip-3.7.2/photofilmstrip/res/license.py0000644000232200023220000000146313560357351023040 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # licenseText = """This package 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 package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this package; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ photofilmstrip-3.7.2/photofilmstrip/res/images.py0000644000232200023220000043226313560357351022671 0ustar debalancedebalance#---------------------------------------------------------------------- # This file was generated by setup.py # from wx.lib.embeddedimage import PyEmbeddedImage catalog = {} index = [] ICON_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAAsQAAALEBxi1JjQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAH8SURBVDiNxZO/axNhGMc/73t3ecOlx9Ejsa2HhWLwQEI6ZYpb1y4OdggOQv0HOhQhIgpu' b'LoJk00XdhCIIOgoObs4JdSuG0m5t6a/L3XuPg3IorRVc/MIDDx8enl/wVWEYyuHhIb7vc3p6' b'SqVSwVqLUgqlFNZaPM8jTVOq1SonJyf4vs/R0RFBEOAMBoNHm5ubrK2tsbe3R6/XwxjD0tIS' b'8/PztFotOp0OjUaD5eVlrLWsrq6yvb1Nv99HBUEgtVqN/f19sizDdV2stWitEREAlFIURYHr' b'umRZRhzHjMdjjDG4tVqNer0OwM7ODnmec5EWFxcZDod4nsdkMkEfHx8TRRFJkpwpjqIIrfVv' b'bGtrC2MM1tofw2ZmZiQIAmm322KMEUAAMcZIt9uVKIpKdl7o3d1dlFKMRqPyZoAsy0iShJWV' b'lTObKaXQWjM7W0cDHBwckGUZk8mkLCqKgvF4TLvdxnGcks/NNnjYv4vWmo3XD9Bn2v8iz/OI' b'45iiKEr26sUz7ty6ztcvT/n0eQg3uh15+fyxKKXkdu+mXF24Ut7XbDZlfX1dHMcp2bu3G5Jc' b'a8rUlC+AKEA+vh+wEDsgOW8+fOPe/SflRN/3SdMUa+0fNxVALs9dkunp8MKPnxfqZ/LPcsMw' b'5P+ayfd9SdOUSqXyVzM5jkOe56UPjDF8B3tCED73aAe+AAAAAElFTkSuQmCC') index.append('ICON_16') catalog['ICON_16'] = ICON_16 #---------------------------------------------------------------------- ICON_24 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAABCgAAAQoBFqS8ywAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAOBSURBVEiJzZVfSKt1GMc/7x/2bnNDx0TdP/ZuXg38N/EEhggaKwgP5E0XZRwC8Q/d5EVg' b'hJxzEwrWzYlKLCpC6WKEIJWgFxMhsJsgTBAsEVYTHDplymxuPl3oGax5YAhCD/xunu/zvt/v' b'83u+z/sqgHCPofb29jI1NQVAe3s7s7OzAIRCIebn5wFwu90sLi6iaRq6rrOwsIDb7QZgbm6O' b'5uZmAGZmZujs7ARgcnKS/v5+GBsbk7W1NQFkcHBQtra2BJDu7m5Jp9MCSCgUEhERXdfFZrOJ' b'iIjf7xdATk5OpKurSwDZ2dmRgYEBAWR9fV2Gh4cFp9MpkUhEALHb7aUHDcOQYDAogOi6LuFw' b'WBRFEUVRJBwOi67rAkgwGBTDMASQcDgstbW1AojH4xGn0ylomiaBQKBEcpejaZoAEovFxOVy' b'lWFqJBIhn8/j9/vp6Oi40yBramqIRqPs7++TyWRwuVzYbDasVivq9vY2kUiEVCpFNBrFZrPd' b'7gZVxWazoWlaBXZ1dUU2myWZTOJyuSgUCuRyOS4uLgAQi8UifX190tbWVhrYf4/FYpFYLCb1' b'9fXPvSq3212RU1tbWwkEAiQSCQqFAsfHxyiKUqbQbrfjcDhwuVxYLJYK/FkcHR1V5BRArFYr' b'pmlyeHhIsVjk9PS0vEhR8Pl8jI6O4nA4mJiYuJWg4uU3QqpySlNTkwwNDcnm5qYoivLcOlVV' b'Sxb+8tP3Ra1Kyk37FouFuro6fD7frWo/nn6X7755gmEYvP3WQ/pf9KNXS1AsFktzKBaLFfgb' b'rz9k8OUmFM3K1s+zqJLj2+9/uybweb38nUpVRZTP52loaODg4KAsPz39EQcHf3GW+ZWr4iWf' b'fPEjyz+sAyC/rH8lK0tPBZCWlhb5/OljefWV3or79Xg8MjIyIqZpVmA9PT3ywoMHFXkFkEdv' b'vsbj915CMFDlH+TqnIOMm0ejH/LHn/tlShsbGzk/P+fs7KyqjnnG5HTWSOKnz+T3za/lyQfv' b'iMPhEE9Tw52/T2UdVC3lDlG1Tf+/BHa7Ha/XC4BhGAQCAQB0Xcc0zesiVSUUCpVW3zRNdP16' b'hQKBAIZhAOD1erHb7cC1GZxOJ4yPj9/rL1Pd3d1lY2MDgGQyyerqKgDpdJrl5WUAstks8Xgc' b'EeHy8pJ4PE4ulwNgaWmJTCYDwMrKCqmbhU0kEuzt7XHvLvoXplrYSr+a8ZYAAAAASUVORK5C' b'YII=') index.append('ICON_24') catalog['ICON_24'] = ICON_24 #---------------------------------------------------------------------- ICON_32 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAABYgAAAWIBXyfQUwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AARKSURBVFiF7VdNSBxnGH7mx5md3WZ2sj8zxLBBXVx/0GV0rC4iibYgpakgAauCh9rYQ0PD' b'CiUYKLQ59NBS2kBbLISWnnLJxZ48tIWWUkIbCkKgNrGQHqSuBptV6yradZ4eFgdWd6ORlPSQ' b'B15mnpn3+77n/fk++AQAxBOE6PP54DgODMMofBBFtLa2wjRNzymZTCIWi3m8rq4O8Xjc49XV' b'1WhoaPD4yZMnYdu2xyORCBzHgSRJAABd1+E4Dvx+P9DR0UGS7O/vJwBalkWSHB8fJwrZ4cbG' b'Bq9everx2dlZTk1NeXx6epozMzMen5ycZDab9fjExARJ0jAMAuDg4CBJ0rZtimRxBfbyct8e' b'BQ9dw+/3s729naFQiAAoSRIdx6Fpml4Etm0zFot5vLGxkfF43OPxeJwNDQ0ej8VitG3b46Zp' b'sq2tjZIkEQANw6DjOPT7/YSiKFRVlSMjIxQEwRv0OEwURe/Z19dHVVX3+xmGQU3TqOs6+/r6' b'HquA3YiHh4dpWRYDgcB+kaZpoqenB2tra9A0DQMDA0eocmmYpolwOAxJkrC0tIRcLofKykoE' b'AgEEg0GEw2EAABOJBMfGxlhRUcGLFy8W1fugFO9GWcoikQjPnDlDSZIYCARomiYty9rrV5go' b'GAzy8uXLDIVCHBwc9OpXzpqamphIJLzmLSewoqKCuq6zrq6unF/hxefz8cSJExwaGqKmaUwm' b'k2Un1TSNvb29rK6uLur+hwkp+z+VSrGzs9PbdseOHeO5c+coy3LJAbquMxgMsra2lqOjozx1' b'6lTJ5jqsCbtpqKqqQjQaRSaTwcLCAizLQiaTKdlcPp8PXV1dGBgYgKIoSKfTWFtbK9uMB2Ff' b'ug6qPwCmUileuHCBi4uLZbO112RZLjoLRoZforhXjeu6cF33QNXLy8twXReapqGysvJQkba3' b'NWFrawsAcLrLwTuXzkI+1MgSmJ+fR01NDXw+H5qbm7GyslK2DGOv9OON13oxe3cR9/5YQHZl' b'BZ99eB6AcHQBqqpie3sbiqJA13XkcrmSfoYRxFvp06C7io4WE998dQXPqOuAsIFPvpzBvhIc' b'FtFoFNlsFgCgKAp2dnZK+t26+SPm/owCkg7B/RsBZRWuqOPtD77HRx9fL2Tg+ed68POtW1hf' b'Lx1FKWiahrm5OUxPT6OlpQU3btzA5ubmPj/XJRobU3j3vfcxd/c27t/P4tfffi/y4bVPr/De' b'zCRvfvs5BUGgqqocHhriT999wYk3z5ft6lgsxu7ubqbT6UPvhL0moLA98MsP16CrS9gRLdAV' b'IYt/Ae42IEWQ7Bovmx1ZllFfX4/5+Xmsrq4eOoO7EAEgn8/D7nwVU18/gIxNyMhAcP/Bg5yJ' b'1y9dx4svdJedIJ/P486dO0dafBdFKTl+PMihl8/yWaf5yMfro5h3FD8pHHkbPhXw2AQ8vRn9' b'L25GjuN46v6rm5HjOCVvRk/8HPgXwjL+bIyBC3AAAAAASUVORK5CYII=') index.append('ICON_32') catalog['ICON_32'] = ICON_32 #---------------------------------------------------------------------- ICON_48 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAACEwAAAhMBmtPiRAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAdhSURBVGiB7VltTFTZGX7u3HvnzhfcYZbpsF51ho/RmQ6CTmdSvqwDkS0/7LgxYYtKirXJ' b'll1YMcF0TWtaXHe30TZr7IdYU1PTdEuDXSNZ2bS0xcZsQ+JolJjAbPwAhciHDZYBZAZ25u0P' b'9OJshgVmGYkJT3KSe59znnvue973nvOeexgAhBcYiuV+ga8KFkBDYWEh8vLyEAwG8ejRI7nS' b'4XDA4/FAEAQMDg7KvCRJKCsrg8lkQm9vr8zrdDp4vV5YrVbcunULRDPOVSgU8Hq9cDgcePDg' b'AUKhkKwpLi6G2+1GIBBAIBCQ+U2bNmHz5s1QKBQYHh6W+fT0dJSWlsJgMOD+/fsAALpx4wYR' b'ER08eJAwE1IEgM6ePUtERE1NTVH8/v37iYiou7s7ivd4PPQUKpVK5vV6vczn5eVFaXp7e4mI' b'qLq6Ooq/cOECERE1NjZG8Q0NDURE1NHRQQBIAQAcx8V0T6L5pXiWAgCmp6djNk40vxTPYgCQ' b'2+2GKIq4fft2VEzb7XZIkoShoSHcvHlT5levXg2bzYaJiQl0dHTIvCiKcLvdAID29nZEIhEA' b'M99ASUkJAMDn82F0dFTWFBQUQKPRwO/3o7+/X+Y3bNgAk8mE/v5++P1+mbdYLMjKysLo6Ch8' b'Ph+AJ7GVlpZGW7ZsiYq35S6rVq0iURRJo9HM2UYBAElJSRgcHITVaoXL5YrhuOcDjUYjX3Mc' b'h4qKCkiShMnJyS/VEcMwZDKZCADt2rWLJElalhHX6XTydX19PeXl5ZHJZCKWZefWuVwucrlc' b'MmG32+n06dNR0+DzKBqNhhiGIQDkcDjoyJEjMdvxPE9ms5l4nqe1a9cSANDu3bupsrJSbrRj' b'xw5qamqKGpFEl5ycHHoaDcePHye9Xh9Vb7PZKD8/n3ie/6IWxLIslZeX04EDB0ipVBIA2rNn' b'D9XW1j43A7KzswkAOZ1OKikpifKMXq+X62OU2Ru3203Hjh176hqqq6ujzMzMRb+MVqul5ORk' b'eRZZiEYQBOJ5nmw2mxxKFouFioqK5tPOxpZaraakpCRqaWmhjIwMYhiG6urqiOO4RRlgMBio' b'rKyMnE4npaWlxRWKFouFbDbbQtrO3jAMQ3a7nSwWC9XX15MoiqTVasnr9S6qc5ZlqaamhnJz' b'c8lqtcblxQUP2lwNdTodHT16lHieJ0mS5h1FrVZLRqOR1q1bRwDo1KlTpFarSavVJnQyYCsq' b'KhqysrLgdDrBsqycNk9NTeH69euorKzE5cuXo1LgWJiengbHcRgZGYHZbIbD4UBPTw8yMjIw' b'Pj4OIvrSnCheME8sATCTa+fm5iIcDuPSpUsYHx8Hz/PYuHEjrl27Juc2c0GpVEKlUqG0tBQF' b'BQXo7OzE1q1b0dzcjNbWVnl/sNSIGcMul4vMZnNcbtXr9XTu3Dmqrq6mO3fu0LZt2xISPjzP' b'U8wtZTgcxtWrV3Hv3r24RmTNmjV4+PAh/H4/BEGQM9R4oRIEpKSkRHEcx6HpD4cx907jKyA7' b'OxudnZ0IBAJQKpWQJAmCIMz7Hc2FYCiE4Be0J4/XI8eekphN/fnz53HlyhV4PB4AwPr16yEI' b'wqKf89JLKfjow/fxr4sfwGhMlfk3X38NpUWpiBAS4wGVSoWenh6cOXMGOp0OIyMjKCwsRFdX' b'14LCkmVZfNz8c3w9k0PgsRqlrx6CWjWTahuNqXi9ygOKjGJ8ghJjQCgUgtFoxMTEBFQqFURR' b'hMFgQF9f34L0Z393CDZLGJFwGDohhE/+ehj+2/9FgTMVoElQJABGoUTD0ebEhJBCoYAgCAiH' b'w2AYBna7HS0tLWBZdl7tt1/Zii5/PxgFL3Mp2jHk5wqg8Bgo8jkUnA5vv/t3XPzk34kxIBKJ' b'QBRFdHd3A5jZK6ekpCxoITvdeBJvVP8I/+yYwuikCIaZfUWGUWBkPAllr32A5o/aADzzZ662' b'5s0lMyAYDMJqtSIQCKCtrQ19fX3Yu3cveJ6fVzsVmgKjUKCsrBy+mwTv987gvV/78NNfforS' b'8pNwbamF/7O7URoCQOebTtCJXxyknd99lZJ02qgF443qH1JOzoZFLTImk4kyMzNp+/bt5Pf7' b'aefOnZSamjqvTqfT0Z//9Ed6953D9M1ndopzFTmV+MfFRmS+/D8AwKPHL8P1re+DiJCcnAxJ' b'knDk0A/gzDZg4OHn+E752xh55hdkLKSnp2NsbAyiKKKqqgqtra3w+XzzpiOLhWyAWq3GjU9/' b'Cx5DAICJaRMGhibxNaMOyerHAI0CT3KZtv9MonrfOwvqgOM4FBcXo729HWazGXfv3p1fFI8B' b'wMzs8bcLJ5C1ehKgcIzWLEJhE+zuKvzsJ/tw+L1fzduBIAhQq9UQBAHDw8NLntBFrQORSASv' b'eN9CUf438PvfvAUlBmYrWQN+/H4ruj+bWYi6/LcW1EEoFIo7hVgIojwQVcEw2FdTheQkLQYG' b'hvHhXz7GZDCYsBeJF3Ma8KLghT+hWTFgubFiwHLjhTdg5Zj1WX7lmDUOfuWYdbmPWVdyoeXG' b'/wFwW3LOouF28QAAAABJRU5ErkJggg==') index.append('ICON_48') catalog['ICON_48'] = ICON_48 #---------------------------------------------------------------------- ICON_64 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAACxQAAAsUBidZ/7wAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAmnSURBVHic7Vt7UFTnFf/dvXd3ufteQkAW3OWhLj4QsmKVgCtIC3UcCSndqUpTIThodDAj' b'dZLRiYnJdBQrraNjO4wm9Y9IiLY2aB+OjQKt4/uxwaZonFhHKyKCLq9dHrtw+gfDys0KskC4' b'zshv5szce873nXvO736v+/gYAIQXGBKxAxAbLzwBHAAYjUbYbDa43W5cu3YN1dXVgkIBAQHI' b'z8+HXC5HfX09ysvLfRzZbDZERUXB4XCgvLwcbW1tAvv8+fOxcOFCtLW14eTJk7h586bALmYM' b'tHbtWurHgQMHCH3jgldmzJjhtd++fdvHDoAaGhq8ZSIiInzshw4d8tpzc3N97GLFIAEAqVTq' b'w+ZAPMsOADKZbFR2sWKQAADDMENWfJZ9LHyIFYMEADo7O4es+Cz7WPgQKwYOAKqqqrB69WoA' b'8BmcAKCurs5r/+7A0o+ioiKoVCoAwKNHj3zspaWlqKysBACcPXvWxy5WDAwGLITUajXcbvew' b'2H6eERAQMOwcBOuA4OBg7N69GzzPfy+BjQfi4uKQn58Po9E47DpkMpm8U0VmZiaVlJQQy7JP' b'nWqeJ9Hr9YJzmUxGe/bsoUWLFvnjp+/AaDSSTqcjABQREUEbN24UPcGhhOd5kkgkAt22bdso' b'OzubgoKCaN68ecPzZbFYSK1WC5RhYWG0Zs0astlsoic6FAEDzxMTE6msrMx/XxzH0YcffujD' b'WHJyMtXU1JDFYhE92adJdHS095jjOLpw4QJFRUUNWl6n0xHP8xQXF0c8z5NSqaQ5c+YQ+tnc' b'vHkz5eXlCSplZGTQt99+SykpKaIn/F0Z2M8zMjLoo48+emq5mJgYysnJGYqcvgODwUBbtmyh' b'7du3k1wu9xaw2Wx07tw5n/4mtqSmphLQ113fe+89UiqVArtMJiONRkOZmZnP8vXkhOM4Kigo' b'oLKyMgoODvbqCwoKqKioaMyC7ydTLpf7BD5cCQ8PJwCUlJRE06dPF9hmzZpF6enpw/UlVLAs' b'SyaTiY4dO0arVq3y6ouLi2nmzJljQsDixYvJYDCQ2WwWEO2vyOVyCgwMFOiWLFlCVqvVHz9P' b'TlQqFSkUCtLr9aTT6ej06dO0YMECb+vYuXMnyWSyURPwwQcfUEhICFmtVpo6deqoSBgoaWlp' b'NG3aNP9aIwagvb0dLpcLGo0GcXFxyM3NxbJly2AymeDxeFBcXIy8vDyMFlqtFo8fP0ZISAg0' b'Gg0MBsOofQLAmTNnnvoc8SwMyg7DMMTzPJWWlpLBYCAAFBsb63dXUCgUgul0x44dZDAYKCQk' b'hEJDQ2nKlClj0gJGJOnp6ZSQkEAcxw1aKD4+nioqKkgqlRIAn373LImLixNMpUuWLKFdu3ZR' b'QEAAmUwmYhhGvFkmOTmZrFYrFRYW0qZNmygrK8ub6EAxGAy0bt26IYkaTHieJ4ZhCABZrVYK' b'CgqiK1euUGhoKC1fvpx0Ol3/okQMESrCw8OpoKCA1q5dSzExMT6J5OTkkEKh8PtC/YPTq6++' b'SikpKdTR0UGTJk2igwcPUnZ2NiUnJz8fBPSLRCKhRYsW0fLlyykhIcGrZxjGOwePVN5//31y' b'OByUlZVF33zzDW3fvl2s5InDIOjt7fW+PVGpVNBqtWhpaQER4d69e4NVGxZYlsXRo0dRXV2N' b'gIAAJCUljcrfSLE4YwGAcWZ88uTJZLPZqKmpiRQKBd24cYO6u7vppZdeGvNraTQaioyMfKot' b'LXUeVf199+At4PvCrFmzcOPGDZw/fx5arRZEBKlUCrVaDYfDgd7e3jG7VmtrK1pbW330HMdh' b'769z4elhxv/T2J07d3D37l18+eWXyMzMRHt7OwDAbDYjMDBwzK7zTtFKLLMt9tGzLIu//akY' b'ckkzQIRxbwG1tbUAgMrKSpSWliImJgYAEB0djVu3bqGzs9NLir9Qq1XY+PYbmD/XDLkM0Knl' b'cLR048Q/TnnLFL61DFMnuwEA3e6e8W8BU6ZMAQAkJiYiIiICbndfMBcvXkR6ejoiIyNH5Nfy' b'ykzY/7UTb7xuxFSTDI1NbYhPfgtnz10EAMjlckwON+BnWT/w1mlydAtfi48H5HI5dDodwsLC' b'UFVVBYVCAY7jsHTpUqSlpWHDhg1++wwKCsSlk78C9bR4dQwrh722Cycq7XgzJwUhug4QGBB1' b'A0RgWCV+kls6/l2gq6sLRqMRly5d8iYPABaLBfv374der4fD4fDLZ+xMMximR3AnqacL8WYg' b'3vwKgBYMHFslnAobtlTA/lWtOP8H6HQ6SCQSNDU1eXUmkwn19fV+J3/g431YX7gBG7ceA4bx' b'/bBXoseKNX/AF8f6xoVxbwFA3xcolmVRU1ODSZMmAQBmz57tbQ3+IDXFClbCYnpMCX67dwcW' b'JMZg7mwV0NslKCfhlLjydTt+UVAEp9P1RN9/wLIs8t8c/bP+cDBnzhy43W6oVCpcvnwZLpcL' b'TqcTK1asgETiX6N0uToAAEqFAu+8sxXVZ+5hRuIm7Cy9ivK/3MMnh2/h3W3VmJH4LrJzNguS' b'BwAWwFYASE5Kwry5FnR2tON/9+6PRZ6D4uHDh2hubgbP8ygvL0dsbCyuX7+Onp4eNDQ0oLGx' b'cdi+vqg4htyVPwcDBm63B9GRUfi07DOcu1CDyupLOH3mKmqv34Lb7XlqfcEscLvmE3R7AFeH' b'FC1t3UhZvEpQWKvVYtdvStDc3IyKo39GW5sT9q+ujYiEyMhINDQ0gOd5lJSUwGw2Y//+/Th+' b'/DgePHgwIp8jgaDTNTgkCFY/gJYHtLwEX1/4FPFJefB4+tjjOA7rCtcjPMyAE38sBHq7QOx6' b'7Nh7Evs+/tyvC1ssFhw5cgQulwt2ux11dXU4deqUX3d/LCBoARqNGvZ/7gHT++QOPHa+jIv2' b'u6g6fRUb1/0UgVoPWKYF6O1+4oQLRGzSL0e8glMqlVi5ciX27duH2NhY2O32kWfkJwQjTmtr' b'GxJS30ZLZ4hXF6hsxI+TeezYlISXNfVgqVGQPMDg9wcuoL29HdOmRvkdgF6vh9PpxP379+Hx' b'eHDz5s1h/Q80VvAZch3NrXgl6U0c+usDgNUOWbmHCcWlWhlKdh8Ax3GoOPw7vwPon/fPnz8P' b'AHA6nd7l8XhgyKWwTCbDkc92YmZUF0A9A2pJ8Z//ypG7eit+9MM0fH7oMKRSKXQ6LRobmwZz' b'91xiWM8Cr7+WjuzXUuFodqLu/kPU/Ps6jp84PQ7hff8Y94eh5w0v/L/CEwSIHYDYmCBA7ADE' b'xgQBYgcgNiYIEDsAsTGxZwiY2DM0sWdoYs/QxJ6hiT1DLyxe+HXAC0/A/wG6tmR1QUeBBwAA' b'AABJRU5ErkJggg==') index.append('ICON_64') catalog['ICON_64'] = ICON_64 #---------------------------------------------------------------------- ICON_128 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAFiQAABYkBbWid+gAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'ABZ+SURBVHic7V1rWFNXun6TkHAJkHALQVAjigKKQI9RQLwUQUWKIIgWWi+tnrEda/Vox9E6' b'I3WsFh1rhVYHe7R1itDBSrVeaxVQEY6tI63VKWCr1gtYFRXkIgSS7/zgYWuaAAFCou79Ps/3' b'PMna31rrzd5v1lr7W2uvzQNA4MBa8M1NgIN5wQmA5eAEwHJwAmA5OAGwHJwAWA6Lx7+kpKQg' b'ISGB+a5SqVBbW4u5c+fi3LlzHRbm4+ODzMxMSCQSJq26uhqFhYVYsGCBQYQ4DqbloCWAhIQE' b'eHp66hTm4OBgEGmlUonAwECd9OrqaoPycxxMz0GrC7CzszOYoD50Nz/HwfQcuDEAy6ElAI1G' b'063Cupuf42B6DloCUKvV3aq0ubm5W/k5DqbnoCWAhoaGblXa3fwcB9Nz0BLAw4cPu1Vpd/Nz' b'HEzPgRMAyzloxQFOnTqFqqoqHaf79+8bVFhFRQWOHTumk25I4ILjYB4OPHALQlgNLg7AcrQr' b'AKVSiX79+pmKC4d2MHToUIhEIqOX264Apk6diuLiYoSEhBi9Yg6Gw8XFBSkpKczEztSpU41a' b'PrVlIpGIVq9eTb/99hsFBAS06cdZz1p2djbNnDmTdu7cSQBo0qRJRiu73RZApVLh3LlzWLt2' b'LXbt2oW+ffu2586hExCLxQb5xcXFoU+fPpDJZPjmm28AAIcOHTIqF0YNq1ev1lGIg4MDvfji' b'ixQXF0fnzp0jW1tbs/8jngULCQnp0MfR0ZEqKiooNDSUgoODic/n9wQX3cTo6GgSCoU66cuW' b'LaOcnBzi8XhmP4FPu1lbW3fok5GRQXv27KEBAwaQv78/AS1/yNGjR/esAJ5//nkKDw/XShMK' b'hcTj8ejzzz+nv/71r2Y/gU+zeXt7d+iTmJhITU1NNGjQIIqLi6ORI0cSANq0aRN5enoaj4+9' b'vb1B/2ixWExRUVFkZ2dHxcXFFB0dbfYT+bTawIED2z2uUCioqqqKtmzZ0vN8+vfvTwcOHCCl' b'Utmhs7OzM23cuJGCg4Pp8uXL5OPjY/aT+awZn8+nEydO0IMHD8jV1dUUdYLc3Nzo5MmTtHHj' b'RrK0tGw3g0wmo/z8fEpPT6fS0lKSSqVmP2lPmw0fPrzNY2+88QYRkdG6WZlMRuHh4eTr60sA' b'yMbGhgYNGkQxMTG0bNmyFgEAIEtLS9q/fz+dOXOmwz7G1dWVSkpKiIjo4MGDPTU6fSbN2dmZ' b'Zs2apfeYQqGgW7duUXl5OYnF4i6VL5fLKTIykgDQ4MGDKTw8nGQyWXt5Hn3x9PSk7Oxsqqqq' b'ori4uHYr6tWrF126dImIiNatW0eOjo5mP7lPg40fP77NQM7ixYvp6tWrNGfOnE6X6+/vT9u3' b'b6fk5GSSSCSdyaubGBMTQ5WVlZScnNzuANHT05MqKiqIiOjnn382+8l9Guytt97SexcQERFB' b'CxcupOLi4k61qHK5nDIyMmjr1q3k5ubWFU7aCVZWVqRUKsnLy4uKiopo165dZGNj02YBfn5+' b'dPfuXSIiioiIMPsJftItLS1NZ5wlEoloyZIltG/fvk7d4ysUCiopKaHAwMAu89EJBTc0NKC+' b'vh7JyckoLCxEY2MjCgoK4OHh8XtXAMD58+cRFRWF2tpapKamwtraWq8fhxbU1dWhsbFRK23O' b'nDk4c+YM6uvrcfLkyQ7LkMlkUCgUuHr1KqKjo/H99993i1O7zYu/vz+tWrWKbty40e6tYkRE' b'BDU0NND7779v9n/Zk2zz58/X+m5vb09Lly6l5cuXk7u7e4f5X375ZVq8eLExo7HtOwwdOpTS' b'09Npzpw5VFNTQ9OnT2/TNykpiZqbm40dqjSK2dnZ6aR5enrSkCFDTMrj9/3//PnzSSqVdjjb' b'6uDgQBkZGTRjxgxjc+rYydbWllxcXOjFF18klUpF77zzDjk6OuodrKSkpNClS5f0nnBz2oIF' b'C5jPgYGBxOfzafLkyfTcc8+ZjZO9vT1NnTq1Qz9fX18qLCykUaNG9QSPzmWIi4sjlUpFpaWl' b'tHPnTp2miM/n08GDB2n79u1mv+iP244dO5j7YaVSScOHD6fZs2fTgAEDzMbJwcGhw6Y8Ojqa' b'8vLyqHfv3j3Fo/OZYmNjSaVSERHpbbokEgmVlJTQlClTzH7hW2337t0UERFBvXr1IktLS4qN' b'jaVXX32Vhg4dyvg8abGMpKQk+vTTTw2aOeyqtbsgZMSIEXB3d4eTkxOioqIglUoBAHv37sWE' b'CRNw8+ZNrFq1Cny+djHV1dWIjY3F+vXr4ebm1l4VJsPt27fh7++Pfv36obGxEYcOHQKfz4dS' b'qYSlpSUAYNiwYWZm+QhRUVFwdHTEK6+8YpTnDNqDQUpxdXWlt956i959912m35TJZFRUVESp' b'qal680RHR9OhQ4eeiPUDr7/+OmVlZZFcLicAdPDgQZo9ezZNnjyZhg0bRgB6YoDVZVMoFKaq' b'q3MZhEIhTZs2jZYsWUKDBw8mOzs7KigoaHPyIiUlRWsAZi577rnnqKysTCstOjqavLy8mIHY' b'7Nmzzc7TDNb1zK19pq2tLRUVFdHChQt1fCwsLOjw4cPk5eVlsh+lb8Dk7OxMarWa7O3tmbSg' b'oCDi8/nMvIchI/Jn0LpfiIuLC02ZMoVKS0tp3rx5Osfd3NwoPT29R3/I40GqY8eO6RwXCATU' b'3NxMSUlJTFrrHYCTkxMBYFbdsMyMU5BMJqOMjAxSq9U0ceJEneMBAQHMnHRP2KJFi5ixxt69' b'e/X63Lx5k+rr60kgEBAAZtasNRjUms4qi4+Pp9zcXFqzZg1FRkZqNZGdNaFQSJs3b6YbN250' b'eT67qxYaGkojRowgAG1Op0ZFRRERMdG41i5swYIFJBKJGD9Tczen8a9cuQKhUIjS0lKMGTMG' b'+fn5KC4uRmpqKsaOHatzi9cempqaMH/+fKxZswaZmZmwsrIyOG93cerUKTx48AAAkJGRoXUs' b'IiICAFBTUwMAmDBhAgBgyJAhkEgkcHZ2hqOjIwBg5MiR8Pf3NxXtJwI6qnB3d6d58+bR/v37' b'6eLFi7RhwwZmWbKhFhYWRnv27HkilowVFhaSWCwmiURCzc3NlJeXR0BLXD4pKYlSU1PJx8eH' b'5HI5xcbG9mjg5Qm09h3EYjElJibSvn376NSpUzRjxowO1w222oABAyg7O9ugWS5jWnx8vNb3' b'I0eOUEJCAgGgiooKampqImdnZxKLxbRlyxbasWMHhYSEUFRUFM2aNYttdwOGO3t4eNCqVavo' b'hx9+oJSUFIOCFRKJhLZu3WrSFcStF7vVQkNDadeuXSSXy6kVrXcDR48epS+//JImTZpEK1eu' b'pMDAwA6XbT9j1vlMFhYWFB8fT4cPH6bMzMwOV6QIBAJ68803zTpDWFRUROHh4YwANm/eTACo' b'pKSE8vPz6aWXXqIdO3aY+2KY3Lq0QURzczNycnIQGRmJlStXYtq0acjIyMC4ceP0+qvVaqSl' b'pTGDMHMgLy8PcrkcBQUFAIDevXsz3JRKJaRSKVxdXc3Gz5wwipKEQiHFxMRQYmIiWVlZmV3Z' b'v7egoCA6evQojR49moiIiUmcPn2aiIg+/PBDOnnypNl5mtq0NonqDpqamvDVV18ZqzijQiAQ' b'oKGhAUOGDGHSWjdbqqurAwC88MILPT7r9iThow+W4dr1u+zYI2jIkCHo168f9u/fj+zsbABg' b'duBqFYBCoYBMJgPwKG7wpCMs7Hm8t3ZNl/K6u0nRy03KDgEEBARALBZj27ZtkMvlqKqqwsOH' b'D+Ht7a21JaujoyOsrKxw+vRpM7I1HHl5+Vj+9opO5/vuxDYEDOTDylLIDgH4+vpCKBTiu+++' b'w4ULF5gLrNFoQESMH4/Hg5eXl1kHqz2N6VMnwsX+PojUEAoF7BDAgAEDmIt65swZHD9+HGFh' b'Ybh48aLOrtoDBw4EANjY2JicZ0/D07Mf1ifHgzQtG0kLBCwRgEqlwq1btwAAlZWVKCkpweTJ' b'k9G/f38QETMOAIBBgwYBaOk2njVs++h/oFZVMt/5fB47BLB48WLm/v/evXuoqamBh4cHwsLC' b'IBKJtLZPbRXAr7/+ag6qHWL5n+bh2oV0nC3YioT4iQblkUql+L5wOxSudVrpRBoY7TbwScbN' b'mzeZz5WVlaipqYGNjQ2mTJkCJycn+Pn5McdbBVBRUQFXV1em5TA3klf8EbMS/AB1Na7cUKGP' b'azP+/pcISCRSbPvkX+3mXZP8GiRWt3XSG1VqdrQAj+PAgQMoKSmBtbU1IiMjMXz4cK3nGVtX' b'MU+ZMgVubm56X7xkKsROjsBPZ7ajKDcd02MC8Oe/7cGDRmeMmfgmKmvssfaj09iZtReffrKt' b'3XLGhOjf7bWqqp59Avjtt9+QnJzc5iCvtemPjo5GeXk5kpKSTMjuETau+xM2rZ4EK/5tyKX3' b'YSW4izGjnoOdTctdi3L0XHy8/QsM6O+J+W+82WY5clcXiEX672rKfi5nhwA2bdrEfPb29sai' b'RYsYAezevVvLNzo6GkBLSxAQEGDymACfz8e+L95HbIQTNM3ab/2YNFoCAWrg7PTo1XEX/vMT' b'6uvrtfykUgmiXwjHYN9BSPv7ApCmSacegUiCvfuPsWMM8NFHH8Hb2xulpaW4c+cOvvnmG/j6' b'+gIAxo4dq+UbERGBnJwcAEBgYCDWr19vMp48Hg+H96bCy722JVKvBxp1I/IPvId1Hx5C1r8O' b'MLexffp44MiX78DGshmapgcgUkPNc4QFr0avAArOVOPu3bvseV/AnDlzsGPHDibyd+vWLSb0' b'+zjKysrg7e2NtLQ03L9/H8nJySbjOGliGD5aOx4gwy6JWtAbmV8UYVrMf8HCgmBBdwzKd6/e' b'GcFhf0RTUxM7ugCgJbDz+BrFtsYALi4uAIATJ07g22+/BWC6uYEhvv1BPHuD/QXq65gZ1xtW' b'gtsGX/yHajnGRi5CU1NLq8CKLgBo6VtFIhHq6urA4/HaFIBUKgWfz0dOTg7zmlZTjQPEYhuo' b'yQoWMPwVs53BvXoZwqIWorb2UTyANS0Aj8djHgK1trZuc7Uzn8+HTCZDREQEM2Xc03MDr7/2' b'B8THxSF5dSqCwpfg9gOpkWvgoeyaNYKen8esnG4FawTA5/NhYdHS4Gk0Gty+fRtff/21Xl8/' b'Pz+T/eudnZzw9tI/YdOGddicugn37t3H26sywOcb5+0gAgtbfPblNUROWaT3ZZKsEYBGo2EE' b'0NjYiK+//prpB3/vN3bsWJPNCG7csI75PDk6CoUn8pB3vAjr/nEWD9WuOP+LADy+sPMF83io' b'b5YhdmY63lmzpU031gigqakJISEh6Nu3L4gI5eXlGDlypI5faWkpYmJi4O7ujsjIyB7npVBo' b'R+n69O6NKxdLkZv/HQYPfxUx05eiuARQkRN4AssOy+PxhdBYeGDD1gvwC5qL78/9p11/1gwC' b'VSoVVqxYwSwLCwoKYp4Gehx1dXWwtraGlZUVJkyYgMOHD/cor9KyMvTr20crzcJCgNwjh5G1' b'azf+vGw54pPeAgAMGtgff/vLHPTxkMLKUgihhQUam9SorVWh6kE9yn6+iZx9J/Htt2cMrl9v' b'HMDGxgaZGZ+Bz+chZkp8937hE4LZs2dj3LhxmDFjBgAgKysLGo0GW7duxf79+3HlyhUEBATg' b'5s2bSE9PR01NDRQKBZYtW9ajawVtbGxQdqHtF0rW1T3EmPCIHpuU0tsF7N6VjaF+g/Hf817v' b'kUrNgbq6OmRlZYHH4wFoaeqvXr2KgoICbN++nXnLplwux969exEXF4fjx4/3+LYx9fX1WJG8' b'qs1onFhsjaIT+fD29u6R+vV2ATNnvwJHBwd8tm0thEIRxkXO7JHKTYlz587h8uXLcHZ2xp07' b'd3D69GnmpJ49exaurq5oaGiAlZUV1Go1VCoVrl27huDgYGYtQU/hs4ydqKiowObUTah+8AAn' b'C07h+vUbqK55gMLCIvz8yy89VrdeAVRWViL/0GaIBZdRcc8B48JCcftONXg8HmxtbVFeXo6r' b'V68aVAGPx8NP58/BysoSuXnHMfcP84z6AwzFxYsXAQAeHh64c+cO8vLymJm/GzduQKlU4scf' b'f8Tw4cMREhKC9evXIzg4WGfJWE/hWG4eBg0ZapK6HkebcwGlxf+CiK78ztsCAB9NvF4YFJjY' b'YeHBQUH4MPUDHD2Wi6O5uaisrISvtxciJ4Ti2vU7yN69HxcuXDDCzzAccXFx2LNnj9ZiUKlU' b'innz5kGhUOC1117DkSNHEB8fj8zMTMTGxpqUn6nR5m3g//37mm4iNQOkghC38J8zX8DPz7fd' b'wp2cnfBi0stYvuIvyMvLB0iD95aPwqiARrwUbY99GXNx6Ycd2PDen7v9QwyFUCjEBx98oJVW' b'VVUFiUSC4uJi5ObmoqysDHV1dSgsLDQZL3OhTQH8cWEyeCL9O4RD8xDW/F/w1c4lcHZyarPw' b'AwcO4pdLlwAAIpEIQ/38oNI8FubUPARPfRNx46W4WPxPDPUb3LVf0Qnk5eXh+PHjOumtArC2' b'tsbChQsBtEwjt+6N+Kyi3eng8RHPY+uG6aDmtt9ZX9fcG34jXtZJd3R0xJbUZKhV1ZC5SOCl' b'sIWmqRJA230qX+SBgFELmKd2TIlhw4bhxx9/xKVLl6BQKKBWq+Hg4IDs7GyMHz/e5HxMhQ7X' b'A7yUGId3l44Faera9LlX6wzwRZDai3Dpah3+mXUA766YBjTfATT1beb7Peqae2Fi3NsoLy83' b'OI+xkZaWho8//lhrbOLj44OSkhKzcepJCAC8057D+Qsl+OmXB4iOHAW0IQJrUT2shTXgaarg' b'ZF+PsJEegLoaIN1Ye1toUDvDL2iOzmyVKdCrVy8m9n/lyhWEhobi7NmzzPHWhaKPPz/wrMCg' b'uYCjuYXwD12IOzVyQ7N0CjyeCJs/KdQamQsEAvzjw3eNXpc+9OnzKBR78eJFnYdCzp8/j9u3' b'dZdVPwsw+GrW1NRgxNhXkJ75M3gC4w2MeDwRvj5Vi/T/1d7ZK23jKkwaP8Zo9bSHx6d+NRrN' b'U/NwqDHQpTWBtmIxvtiZAm8FtTs2aA91Tb2RlVMEVbMA73/wodYxqVSK7wq+gKVIiL6Dxnap' b'fA6GoVuLQhWKPvjs42R4uFQBGpWBFVrgfmNfxExfguvXr+v1cXFxwf3795E4LQYZWTldpcfB' b'ABhlVXDitBewdvkEkKa2XT++yANLVmYhZ0/LFOtwpRLZWTsxLfElnPn3v7tLg0MXYLRl4ZMm' b'hmHpokS4y+1gwWsAeMDZH+8hLf1z/DN9MS7/eh8Rk98wWWydg2FgzXMBHPSDNUvCOOgHJwCW' b'gxMAy8EJgOXgBMBycAJgOTgBsBycAFgOTgAsBycAloMTAMvBCYDl4ATAcnACYDk4AbAcnABY' b'Dk4ALAcnAJaDEwDLwQmA5eAEwHJobRGTkpKChIQE5rtKpUJtbS3mzp2r9V6dtuDj44PMzExI' b'JBImrbq6GoWFhViwYIFBhDgOpuWgJYCEhAR4enrqFNa6aXJHUCqVel+xUl1t+ObHHAfTctDq' b'Auzs7AwmqA/dzc9xMD0HbgzAcmgJoLuPbRnjsS+Og2k5aAng8RcpdwX6tiPvLDgOpuWgJYCG' b'hoa2/AxCd/NzHEzPQUsA3d0U2RibKnMcTMuBEwDLOWjFAU6dOqV3j77Wd+d0hIqKCmbX7cdh' b'SOCC42AeDtz+ACwHFwdgOTgBsBycAFgOTgAsBycAloMTAMvx/5ISbNCvp42CAAAAAElFTkSu' b'QmCC') index.append('ICON_128') catalog['ICON_128'] = ICON_128 #---------------------------------------------------------------------- PROJECT_NEW_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AADYSURBVDiNxZG9DsFgFIbf03aR1j1wDSLRGxDp3sbg5x7MBo0raW1MliJ2hpaVjWugjUmP' b'QSslxNdBvNP3nZ/nnJwX+LcIAEzTlA9hoc7MWppg4LSdjxZCgGqjPWSi/pusHXju4DvA6I6Z' b'2cyxeQhCK/DcqZSjKSsNTE0AEAYEM5eIaJL+iSDnAnySIjI5ffueYwH3mwkD0mLfc6yK0elJ' b'oBoz60S0FgJk3Uman9wSvkFitf4aV5Ix+zybAEDM2D0AJe1iHyN1FcfXosg2kiSfy2q03IgU' b'/1w3lwVNl0cM9gQAAAAASUVORK5CYII=') index.append('PROJECT_NEW_16') catalog['PROJECT_NEW_16'] = PROJECT_NEW_16 #---------------------------------------------------------------------- PROJECT_NEW_24 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAC2SURBVEiJY2AYBQMNGGEMY/d4bwam/zMZGRikcahsPLNtUQOpFjDDGNJq+vsYGRhk8Kh1' b'kFLTZ3x2++IBUiyA+8DEM+4/qa7DAZ4wMDCkndm+aDsDAwMDE5UMRQYyDAwMM2EcWljAwMDA' b'IEsVC85sX8R4ZvsiRnxqaOUD+lnAQqoGbEGCLIaeGgefD5BdCHM5vjw0AiMZGRBTvCD74Akl' b'lqGBx9gsSKOSJY8ZGZnSqGDOKKASAAAvnCjJd55JwAAAAABJRU5ErkJggg==') index.append('PROJECT_NEW_24') catalog['PROJECT_NEW_24'] = PROJECT_NEW_24 #---------------------------------------------------------------------- PROJECT_NEW_64 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAk6QAAJOkBUCTn+AAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAJKSURBVHic7Zo9axRRFIbfM7vENHYGQQvRYDrZSHYkdmIh7oDlCiruRsgvsBYSOxsL/4HZ' b'FJEliCBJFBGsLHT8CEgaP7BKpRBDmiTsHFvBMzu7m7lzltzzlPfemfPuszP33tkdwDAMwzAM' b'w/AT6mVMGM1UGMkpTnhk0EIMbH98sfhy0ONd0VVAtdaoMfCIgLM5Vbsfr7bmczlXTpTSOqpX' b'mzdAWCbgWI71Lp2YqNDm1/U3OZ7zQIgCztfujAWUvAIw6qDmUEkIpMYydW4COOqsKmOuGjXm' b'nZ2/D0QBCWjSeWXGXFhrPHBeJwNxEgyjZpuZ60WHyZE9AD+Jub0/Wnr4+dnjrbSB4hVwCBgB' b'MMFE98q7SXzhyu3TaQMPq4B/GU9K9LRer4sTvg8CAGDyx86Ra1KHLwJACC5L7d4IYMZxqd0b' b'AUFA4ornjYA0ytoBsojXWv99c3nuU7y/AkyAdgBtTIB2AG1MgHYAbdT3AdI6n8X71YXr3fr7' b'2Sd4fwWYAO0A2ngvQH0SDKNmu1u/NOFNRY27AWg67RhmvthrfXUBgzzVBaBpexrMCROgHUAb' b'E6AdQBvvBagvg1lI+4R+1vkshl6A63+pvb8FRAHMvFN0ENcwsC21ywKAT27jaJCIn0m+Bcr7' b'SwD+uIxTMFvBLj2ROkQBH54v/QIwC6DjMlVBdEA0++5167fUmfqe4Oa39Y2T45W3IIQAxpzF' b'cwiDNgKmW/HawkramJ5+kJyKZs4RkjMHeVW2SCigPRB/j1cWv2hnMQzDMAzDMIaVvyYdlwhv' b'9dW2AAAAAElFTkSuQmCC') index.append('PROJECT_NEW_64') catalog['PROJECT_NEW_64'] = PROJECT_NEW_64 #---------------------------------------------------------------------- PROJECT_OPEN_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAEFSURBVDiNxZKxSkNBEEXP7EsjJmDhBwTxB1SEdFpIfNhvZ9DGv7Aw2Nv4AZGkU7CMT7AR' b'RAIaQbCwEBT8AEESRMnuWMToCsJbC/FWw1zumZ1l4L8lANba5L43VlXV4shQeL7KWsdRgPm0' b'tq0imz+49ct2cysfsLK2r6o28tVOlMZF1twAKASkjlfdiSEIuFFtvrry2M1aBwkyyAN4SObS' b'mp1dXp0uhEYlXS8PxB/KcLNcGWHRhA0nWo1KDtV/YqLzDYCw9AvA6d3R7uvnCqregCxEx1VO' b'IPxEmAEmo/MmBKjegkzFD+e62967gY87KBdf6g/98XPvXSkvbMC9Oc4AjR34t3oHnFtQJ7uM' b'K6EAAAAASUVORK5CYII=') index.append('PROJECT_OPEN_16') catalog['PROJECT_OPEN_16'] = PROJECT_OPEN_16 #---------------------------------------------------------------------- PROJECT_OPEN_24 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAEUSURBVEiJ7ZG7SgNREIa/WQ1ELW3EpDFF2oC3xmZRQcR3iCkkz7E+Rtq1TO+CBrEI2Cze' b'WtslhWCneIFkLGQ1JCfCOgs2+ZozDMP/nTkHpvw3khZre4cHeNoSKE2YPI5PwyCrYCYtStXa' b'hUD5l1l/uVqT3sPdZRbB9wbr+3XNejsHCdCMozBKG14OocOUgdZwY3Z0Io5CGe1ZyHuDMcY2' b'APD9RvF5bvAEzBuy9aOvS84NXoq6ZQwHuL0/O3l0P5Gnu8ZwQM9hwh+oYheIdpyCzZ36IrBq' b'jH8rLLx3nYJ+Qbdd/UwI3at2+9UpELE/jyqdtHbd1C7wxClIvg6pGPN71xsrNy5B80fyZxLg' b'iCAYGHOm5MgnJQRAyyN2E8cAAAAASUVORK5CYII=') index.append('PROJECT_OPEN_24') catalog['PROJECT_OPEN_24'] = PROJECT_OPEN_24 #---------------------------------------------------------------------- PROJECT_OPEN_64 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAk6QAAJOkBUCTn+AAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAM1SURBVHic7ZrLaxNRFMa/M4lpUUQEhSIFpWI3UmsfsQoFn0gS1120QhrBP6A7l213XYnS' b'naAtESlod8UmtdUWFz7IQ9RFF4oIBamgQmspiM09rqJ9TJLJzJ2bTLy/1eTeM/d8+TjnzmQy' b'gEaj0Wg0Go3m/4SsxAQjsVaGOMyCA3YTMbCaTd6fsXu+WxQ1oDMcDTNwm4BjkrINp6fjQ1LW' b'koSv0ERnqL8XhEkCDkjMd+5Qcyt9+fB2QeKajjA1oC187aBBYhZAvQs5q8oEw2zQT7k+AHtd' b'y8oY7IxEh1xbvwxMDRCgk65nZgwGw9ER1/OUwHQTDEb6HzJzj2oxElgGYV4IjGST8XdWTjCt' b'AA/TAEavQUh1RKJ9Vk6oNQPyBIgx1h6KnigVWKsGAEDAR7hRKqiWDQADF0rF+K0uRsArwXzT' b'mSS1EBGXirFsAIiWMon4I0eKqpCabgEraAMqLaDSWN8DCnAqFD2TAzfKEKMKw/D9TE2PJwEJ' b'BgjCOIGanctSB7OYBJAEHLZAV/hqIwBPfXkAINBs/tiRATn4LjuXUwEM39zfQ0cLES45FqMY' b'Bj6nHt/7lP/sxAAC47wETUohwpYHs7YNCEZirQAaHCtSzr/+B5xUALPnyh9AblfOP795wEEL' b'eNEAzr6cuftj84gtA4739AQY6JYjSiVbyx+waUDdWn03gD2O9SiGDcxtH7NlALH3Ln8A1lfE' b'vhfbB23dCpMHr/9gfv4xOfpr+3DZFdBypW8/QO1yVKmDaWf5AzYMqBP+iyjyn2K1wrxzAwTs' b'7AFeLH/Q12wy/t5spnwDPLgBMsQcANMHpGUZcDoUOwLgqARNSjHYvP+BMg3IEXvz56/wPy00' b'VV4LeLL/sZh6MrZUaNLyfQCzMAA6K0eTOojYdPfPU04FtEHu6zJKYGEULH+ggAHMvLZzlJrk' b'SFLKho82FooFmBsAvHFFjnqevU48WC0WYN4C/t8TAFbcUKSYW6UCTA3ITE18A3AdQE62IoWM' b'phPxRKmggptgOhGfJIEQgEWpstznOxEG0l1NA1aCrbwqi45IrIUgmpy8KqsCZl6mwO5MZurO' b'eqW1aDQajUaj0WiqnT/yqMjSmxhvqAAAAABJRU5ErkJggg==') index.append('PROJECT_OPEN_64') catalog['PROJECT_OPEN_64'] = PROJECT_OPEN_64 #---------------------------------------------------------------------- PROJECT_SAVE_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AADWSURBVDiNxZJBDsFAGIXfP0PiCG7Bopv2BK1DlLiBSBzCQmJPFxWbOkDdAAmXsZGgnk0r' b'g7ahC14yyf9n3nz/m8wA/5ZkhdXpzkD2AOgS/0YjcXfx8vgO8PwriCnBbe4kkSgPUjM8muD2' b'sF6s8gCW52elnUCvATgAoErilsnOCjMBRCQyJn2kqgk+BmzSVQXAwT4OnX0cOhQMvwZo3IJH' b'c27MvwZcbtJ6mOqndpHPfIUExi9USkWW2x1TUUgZAcSL9xlAIBCgb0CaEE6E6e7TYRZe6fe6' b'AyKdQQ5+P1IOAAAAAElFTkSuQmCC') index.append('PROJECT_SAVE_16') catalog['PROJECT_SAVE_16'] = PROJECT_SAVE_16 #---------------------------------------------------------------------- PROJECT_SAVE_D_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAArElEQVR42mNkoBAwUs2ASZMm' b'zQFSCUDMjEf9cSD2yMvL+4TNgD9AaiIQn8CheRU2Q5AN+A+kwoASq7HphsrDXQJUZ0WJAQxA' b'dYzYDCAa0M2A41DakhwDCoGKJkDlioBUL6kG8MOiCijHD6Q+kGTA////7fLz8w9D5eyB1AFC' b'BoASEnIqfAHEXVA1ZUAsjiT3F2gAC7oBs4BUEgP+pAzWDMRzgQakoxhALqDYAADNVlkROfKn' b'qAAAAABJRU5ErkJggg==') index.append('PROJECT_SAVE_D_16') catalog['PROJECT_SAVE_D_16'] = PROJECT_SAVE_D_16 #---------------------------------------------------------------------- PROJECT_SAVE_24 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAESSURBVEiJ7ZS/bsIwEMa/cywegrC2a5GAnbHhHcjIK5CpAqbAI7A1eQeyVeykQ+eOVH0I' b'ZOwOEMlyDPmnTPS33ec7f/addMA/BZAeDF+nE0W0JcCteMsy3UUL25GjB92n/gcBvaqvBDDu' b'Pr/Q7/fXPu+tMfR8BQBpEpGZaCPL1y5bH5Io0DVW+a13UMB85PlhawaZSasGJtwmmr1tQus/' b'eByDE6DmZ8Hds+CuAoKLVox1yCYKePtM4o0mrQeeDwLCm0VXyv1AyihXSOy9TGkpAyk7udXB' b'mXRsubUMGBdTUzsJ5DQbpWZAwGrg+ZCCx5khAcs6Bj+wr+sOAaHDReFQARz1wGzR7GpSlyMR' b'mzWof0T+AB1zQEAqbAbfAAAAAElFTkSuQmCC') index.append('PROJECT_SAVE_24') catalog['PROJECT_SAVE_24'] = PROJECT_SAVE_24 #---------------------------------------------------------------------- PROJECT_SAVE_D_24 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAvklEQVR42mNkoDFgHF4WTJo0' b'yQtIzQJiaRLNaczLy2sgxoLHQEqGTMditQTdgv8gGqiQqKCDqUcCnUC9FbS0AMMSWliAon9g' b'LKAUjFpAEwt+AXEtEC+B8mOBuAmI2ahlQQVQUyea2nIg1UEVC/7//y+Vn5//HE2tBJB6ThUL' b'gEAaqOkZmlpQgfiElkEEKg7aqWUBKJLrgHgxlE92JFNSXMPAY6AFcrgs8GSAVDjkWgJyYBrQ' b'gh1YLaAFGPoWAACwQnwZ7O4euAAAAABJRU5ErkJggg==') index.append('PROJECT_SAVE_D_24') catalog['PROJECT_SAVE_D_24'] = PROJECT_SAVE_D_24 #---------------------------------------------------------------------- PROJECT_CLOSE_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAD4SURBVDiNxZGhTsNQFIb/09aQjAcAv9kKUoEHstXfZILRd8BgJtrUoHiI4orCtKNuYslE' b'WTK/BIHAkwoM+zEb65rbtAuCI88933f+nAv8d0m1cTa4uRPgXjtN+PkkCsotszrzsVrOTrr2' b'lwAXTbBWoJXUwLWCreS0ZwsE0zzVw8DmBkop8604uiLZ2SXG52Ly+FIH7gmc/iikyFjzGuRJ' b'5DcLXC8mqZq2laqA4DpPomerZJqvyYc2tCFyS8oQwE4AkffXNHpqI3BcT8nmA4wDYuvT/FVg' b'AQDJAsCl43pxG4jkOYDsV2B8M1ybQgDHLRdnFo3w8Lya+gEzTVbi59ZlJwAAAABJRU5ErkJg' b'gg==') index.append('PROJECT_CLOSE_16') catalog['PROJECT_CLOSE_16'] = PROJECT_CLOSE_16 #---------------------------------------------------------------------- PROJECT_CLOSE_D_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAArUlEQVR42mNkoBAwUt2ASZMm' b'lQOpDhzqG/Ly8hoJugCHIRia8XoBzRCsmgmGAdCQBhAN1NyANwymTp3K/PfvXzcgkwcm8f//' b'/0/5+fk7iQpEoE3NQKoGi3wjPtuRDVgFpEIJ2YYEvgBxDNDwjcgGyAJxH5EGFAHxA6ABkcgG' b'gAIrjBjdyOoHjwHzgJQrEB8nMgwsgXgX0IBkmAGKDJBo5CXSgM9A3Aw04AHFuREA8YJTEbpb' b'QPsAAAAASUVORK5CYII=') index.append('PROJECT_CLOSE_D_16') catalog['PROJECT_CLOSE_D_16'] = PROJECT_CLOSE_D_16 #---------------------------------------------------------------------- FOLDER_OPEN_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAEFSURBVDiNxZKxSkNBEEXP7EsjJmDhBwTxB1SEdFpIfNhvZ9DGv7Aw2Nv4AZGkU7CMT7AR' b'RAIaQbCwEBT8AEESRMnuWMToCsJbC/FWw1zumZ1l4L8lANba5L43VlXV4shQeL7KWsdRgPm0' b'tq0imz+49ct2cysfsLK2r6o28tVOlMZF1twAKASkjlfdiSEIuFFtvrry2M1aBwkyyAN4SObS' b'mp1dXp0uhEYlXS8PxB/KcLNcGWHRhA0nWo1KDtV/YqLzDYCw9AvA6d3R7uvnCqregCxEx1VO' b'IPxEmAEmo/MmBKjegkzFD+e62967gY87KBdf6g/98XPvXSkvbMC9Oc4AjR34t3oHnFtQJ7uM' b'K6EAAAAASUVORK5CYII=') index.append('FOLDER_OPEN_16') catalog['FOLDER_OPEN_16'] = FOLDER_OPEN_16 #---------------------------------------------------------------------- FOLDER_OPEN_24 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAEUSURBVEiJ7ZG7SgNREIa/WQ1ELW3EpDFF2oC3xmZRQcR3iCkkz7E+Rtq1TO+CBrEI2Cze' b'WtslhWCneIFkLGQ1JCfCOgs2+ZozDMP/nTkHpvw3khZre4cHeNoSKE2YPI5PwyCrYCYtStXa' b'hUD5l1l/uVqT3sPdZRbB9wbr+3XNejsHCdCMozBKG14OocOUgdZwY3Z0Io5CGe1ZyHuDMcY2' b'APD9RvF5bvAEzBuy9aOvS84NXoq6ZQwHuL0/O3l0P5Gnu8ZwQM9hwh+oYheIdpyCzZ36IrBq' b'jH8rLLx3nYJ+Qbdd/UwI3at2+9UpELE/jyqdtHbd1C7wxClIvg6pGPN71xsrNy5B80fyZxLg' b'iCAYGHOm5MgnJQRAyyN2E8cAAAAASUVORK5CYII=') index.append('FOLDER_OPEN_24') catalog['FOLDER_OPEN_24'] = FOLDER_OPEN_24 #---------------------------------------------------------------------- MOTION_START_TO_END_24 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AADSSURBVEiJ7ZTBEcIgEEUfjF0Yq1BrcDL2EG9pQY/JzRLMlSLEHqQL7cEjXqIT0SRAzEn/' b'jZ3lv1k+AH/1SDQX89VmjbSVgGmk3xXIjVb6UZAvNGkPA8wBEqBqFiYfGjBaCSK0SDMLzJo1' b'2dL7NQUDlmm2HxVgYRsCiTqiEIgb8pvq4NognLXade0fFLLPJINvkbXcxgNYCnNSZVdLbwbu' b'o3tm4mEOsRN4mscBBKWveRTAHFUR0j/6X+SGfAWStsflqUtz4U6Q15BocyFkPmD/L+oOI24+' b'Er15FBIAAAAASUVORK5CYII=') index.append('MOTION_START_TO_END_24') catalog['MOTION_START_TO_END_24'] = MOTION_START_TO_END_24 #---------------------------------------------------------------------- MOTION_END_TO_START_24 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AADXSURBVEiJ7ZPNEYIwEEZfMnahVgE9OGAPeKMGb+JNOpBrijBNQBXSg8d4QSfiTyCRk363' b'3dl8Lzu7C385JOwgWm3WSFMJmHv6tUBea6VvCflAk+YYYA6wACo7MXtRQK2VwENxkhlgaefk' b'm9qvaRQgTrNiMkCcZgWG3SQAX3N4HrLTvBvkXa6F+NhByM8HAYzhEmLuBDRalQa2IQDnDBqt' b'yijJEHCA8Uc4aItCOhl8B41WJYL9ZACA+qSKSQE+6g+5BRb9Yxqpsx30O8g7iLe5EDIPeP+L' b'ugLqLTw21wMy1wAAAABJRU5ErkJggg==') index.append('MOTION_END_TO_START_24') catalog['MOTION_END_TO_START_24'] = MOTION_END_TO_START_24 #---------------------------------------------------------------------- MOTION_SWAP_24 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAEpSURBVEiJ7ZRBTsMwEEX/GN+CNguuELNGFQsUVb2CK3WRa1S9Bd2gKBwBIXfXbaWGK6Co' b'9BhVhk0NIXESkxaxgL+b0fg9j2QZ+E9HqFyEd9MxBC8JuOzJ2wOIM5Ma2xBfbILvT4ADwADA' b'styQjgFkJiX0iIo0AxiWe6Jh9mzxEoQTHahoqm2tIj27Hs+uziIIJzqgA69B/AkkBFwc1j6S' b'VsEHHOQCeUkaBTU4Y64izSrSDMbcV+IUdNy8mlbJ77yil6d0x5JGAL96MHYk5Gj7/OCcbdyg' b'JiEsMpNSZlICYeEDbxU4Jd+4uZfASiRf3FLBue1RwblkcdMFB+p/kTObVZIDSGy9XT0mTbPV' b'/Pgrqm6wBzA4/op981YuqhvER0lvOJGITzj/F/MOEHR7/G1z6tAAAAAASUVORK5CYII=') index.append('MOTION_SWAP_24') catalog['MOTION_SWAP_24'] = MOTION_SWAP_24 #---------------------------------------------------------------------- MOTION_MANUAL_24 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AADrSURBVEiJ7ZVLisJAEEBfNbPzBh5BzU4FT+DnDgacG7lyJ6hnEI8giLrwc4W5Rbpmk9Zo' b'IpqOoKBvFarSr7qqOwS+3EHcQ7PXr1uVMVBLxnOiwMEaGWznkw2AcZlYHhSQE68NjNWxC5hE' b'slpAfE0tq4DJeNGXk+snlVJmIvz5WFUpI/STsVQBA6PVYrr0KdDshC3LZYFnjiWT9Ihi6t1Q' b'84jWi2nm7XtdB7d2lJf3PoNHuvyewV2SHVjAREij0Q5LPrIIqQjqXKkCRyAQ0aF6DieWo8Le' b'xc7/AyMDYAfk+oKvUGBHZH8LOD6Nf3rBO2ntq8pUAAAAAElFTkSuQmCC') index.append('MOTION_MANUAL_24') catalog['MOTION_MANUAL_24'] = MOTION_MANUAL_24 #---------------------------------------------------------------------- MOTION_MANUAL_32 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAASdAAAEnQB3mYfeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAE+SURBVFiF7ZWxS8NAFMZ/L60IHWxXXRV0FNquzkYc1c3GXfxr6ixaNzvLObs2Dg6iQnHT' b'uXUItEOfU0psqyEk4Sr2N717d9z38b6DgwX/HYkuqq63Ljo6R2QHKGWsFaB6L4Wl087txduU' b'gQ33bLlC/xHYzFj4O8JLT8vbXdMcADhhv6z9eu7iAMpWhc9auHQiO6u5i4dKOlqbYcAO1g0U' b'ZzUFrjqmdZKlUN1tXCp4k33rE7BuYGYEUWpuo51GwDetw1QGgIM0BuKY/wh805K4M2mY/wlU' b'd49/fUSTPNxdJ3q0sQZE5CbJhUx88XHMfwSqemTVQNJMk2I9AusGxhGIOB+gACh4Nbcx9XWm' b'QSO1U9D3cR0WPVZ84DVL0R94DkoDf8pA1zQH4hT3AAMEOQgHgBGnuP/Ubg9zuH/BH+ULaclM' b'X5CXfNQAAAAASUVORK5CYII=') index.append('MOTION_MANUAL_32') catalog['MOTION_MANUAL_32'] = MOTION_MANUAL_32 #---------------------------------------------------------------------- MOTION_RANDOM_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAEkSURBVDiNpZI/S8NQFMXPfX8yuAgOGRxCxk4ZGoQuDlleOzg7NRD8HI5+Dgno5K5WB10L' b'JQU3JwkdnKQfIP9eB2kwaRJTeqb3uPd3z71wgANFfz/ueDqEka8AAAm3opf75X91URln5Ctk' b'cvH7Ts927Brq7NATqhsk3CqdE24B+HGUb0rwk+g1/GyqEzo0mgR2RvkDQFkBfb18vnur97Se' b'UMIMV7KQFwx046pg0GvAaBLYKRXvmsiQmfGdiuQU0CJFvq737pywhQmwAUATPkjrRGh+OZ+F' b'cb1fdMEAAI1jobk3n4VxZw6aYA3EUjOvdG7LQS+4RcJRvtkbbsqBq4IB8SICcLSP81YEAMPx' b'9Jwx9gRgTUx4i8fbrz5wRa4KBo7yzX25DQydl2pgAjkjAAAAAElFTkSuQmCC') index.append('MOTION_RANDOM_16') catalog['MOTION_RANDOM_16'] = MOTION_RANDOM_16 #---------------------------------------------------------------------- MOTION_RANDOM_D_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA1klEQVR42mNkoBAwInMmTpxo' b'xMjI+AjE/v//v1x+fv45QvIoBkyaNEkESJ2Gck3z8vLeEJKnrgHYnAgUEwOKCQEV3yDoBXQA' b'tFEBSK0C4j9AXAM0ZB/eQMShOQmInwHxFhAb5BKCBkA17wfij0DsBMRSQDwP6GwfoLNf4TUA' b'SbMCVOgiEP8C4jCg7Q/wegGLZhAAaXIEacYbiIQ0441GYjTjNAAazycJaQYBrF4AmqoB5J8F' b'Yi58mnEBRqjJtkCTtwGZ76Ca7xGjGSUWQC4BOusdejwTAgCVuZwRQ2i1dAAAAABJRU5ErkJg' b'gg==') index.append('MOTION_RANDOM_D_16') catalog['MOTION_RANDOM_D_16'] = MOTION_RANDOM_D_16 #---------------------------------------------------------------------- MOTION_RANDOM_24 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAGWSURBVEiJ3ZQxSBthGIaf79fBreDoHnAQFO5Sl0wqMaeTRtqh9RI6idBFBHc3F0FcMome' b'OEoRJBcCZuoWI3Tr4KyTuwje1+VSRHL/JTnr0Hf8eb/n/f53+OC/VN6rbH9c/DoN4BSrk/mS' b'vzmsf7TXgJqooZhO3vN/KlFBjTq2AJtfkrfyrxTmBFrtMJi3Bdj8ppfZXV6fUigItBQK7vL6' b'lA1u8/cMIGIBo047DOYx6hCxYF3f4k+sKEn5pWpJNToDCa7Dky1Abf7eP7DDzwU9AP3sliqH' b'aUv2HdCFA9/b4emuPps5RFddr7KfOSCG/xB07zoMjgA6zePfgtZA/UwBXTgwpsiGU6xOArie' b'/02RHRHzxTZv7e8l/MXzvaC1GF5u148bQwU4XqUo6MUreFdPkVC+qQeXNjgkVDQofKBblFBL' b'V48iZuXmVS1936J+4Emdp96iLPDUW5QFDqTfItfzH4DxoeApiiuS4F/AAUYA7m5/NSdy0+PA' b'bPz+FAlrnfpJPQv8b0Ac0pjIzXwAciLm01vA30V/AFm8+QgTQy8lAAAAAElFTkSuQmCC') index.append('MOTION_RANDOM_24') catalog['MOTION_RANDOM_24'] = MOTION_RANDOM_24 #---------------------------------------------------------------------- MOTION_CENTER_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AADbSURBVDiNtZNNagJBEIW/6layEAZyFX9xk50kxiMIeolANmY3B1HBI8QJeAGFxKsEXNtT' b'blRmtDvOIHm7rn7vq6Kahv9Q+2XULVIDMD5jKnxd1lNh1XodP/0JyIQjT7Oaqi4vIWfAjXAQ' b'YkqEvRAJuTr9YbTHfoigVl28SRY7n68SAjixE1HeUHAYBd59vqtXKKvgBFZdfOzMQ7Uah3wC' b'UB+MGzbVlcLj6eI7mef20+yPNHPcpZjnbTJdG4Dt5+zHGekJ/BaY+hyGzA4KQnLhHKAA5Coc' b'VJnPdLcODA5ijErR8qcAAAAASUVORK5CYII=') index.append('MOTION_CENTER_16') catalog['MOTION_CENTER_16'] = MOTION_CENTER_16 #---------------------------------------------------------------------- MOTION_CENTER_D_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAt0lEQVR42mNkoBAwYhOcNGmS' b'ZV5e3nFCYlgNACkEUjuAivnRxL8AKS+g+CGcBsA0AzEfUCG63H8g9RXdEEZsmkF8HAYwoBvC' b'iE0zAQNQDMEaiFANIMNqgRiksQWo+BPRsQA1oAtIlUK5XUADyuluAMgL1WBFjIwtubm5n3Ea' b'AFRsDKR2A7EgkYEICg93oJoTyNGIYggeA+CaMbyAbAgOA1A0Yw0DmCFARUJo4h/RNeMMRIoy' b'E6kAAKLscxEHiPl/AAAAAElFTkSuQmCC') index.append('MOTION_CENTER_D_16') catalog['MOTION_CENTER_D_16'] = MOTION_CENTER_D_16 #---------------------------------------------------------------------- LOCK_24 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAFWSURBVEiJzZS7TgJBFIa/s4NU+gICCY21iWB8BZeYWBvjlqutNhgLa7SwsoFKQZ9AdGNj' b'awxS0NuBl2cwzI7FSkLA7C4LJvzJJJMz5/zfmUsG/lkSJ6lYcrYxHALFIGJaAhctr3EXVaui' b'EtZtpwJcAnkgHQzJg+wsr6ymP946T2H1VlTnBsrAN5iy7qcyup/KGDgOYpyslZytMI9UaPvB' b'sWDgtO01zodWzgq2g0DF8jkCmol2ABQA8P36WKFY1wDI4F6SARYB2o83n6MLrYerr9/p0jSA' b'qTX2TIubeyUjUhPITOjVA9xXr+4NB8d3IFJNYA6QBaqjwb+OKJvAfKBcHMBMNUcA4X5BkVXo' b'HOBF5k8KUEYfPDfr7y/ebU+02p85IKnC/6IhaVRtw951fZ0WY/VrMX/6+ADA1qguShPXHObq' b'Fc0Q0JvCrxsH4CaEdEUsN0HdnOsHtElTop3yxk0AAAAASUVORK5CYII=') index.append('LOCK_24') catalog['LOCK_24'] = LOCK_24 #---------------------------------------------------------------------- UNLOCK_24 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAFNSURBVEiJzZSxSgNBEIa/2Y15CJNAGmvBO/ER5KJgLcLZnbbaRCyso4WVhUlngk9g5Dpb' b'kWhhb5fEh5DsrcURCEbuLpcE8sM2s/P//8zssLBkSJYkt+YfYDkD3DhiewK3vbDzlMbVaQnb' b'nt8A7oAqUIyPVEEO1zc2i99fny9JfJVWuYU68AO2bkaFkhkVShYu4hiXWzV/P0mjkFh+PBYs' b'XH2EnZuJm2vH8xFoqIhzoJurA8ABIIraU0RRDwDI+F2WANfzrev5NiknrYO5MbWmzu7xHso2' b'BUozag2A4D1sh5PBqQ5E2fsc4gBloPk3+N+IyjnEx6hkMVgoVshAeF7TlDWmAoSp+bMaaGtO' b'X7vt4Vv4OBCjTxZukBfJf9EEDLq14x0FkSmKVaNWxp8+uwHgGXQfbcgqDiu1RQs0GMyh189i' b'EOQ06YuoIAdvxfELb7xSIP/N950AAAAASUVORK5CYII=') index.append('UNLOCK_24') catalog['UNLOCK_24'] = UNLOCK_24 #---------------------------------------------------------------------- MENU_24 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AABmSURBVEiJ7ZJBDYBADASntQEuEMEDEfxOE/fFxJnAxeGjOCCFQIDQee9m9zEQPI14g10/' b'DqhlAQPSUubi6an7idok0AAtkL0998BZjgwkYAWqiKab/ryQsOjSgbBon7DIw08t+j4b1DYk' b'HJtnLRoAAAAASUVORK5CYII=') index.append('MENU_24') catalog['MENU_24'] = MENU_24 #---------------------------------------------------------------------- ABORT_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAGOSURBVDiNpZI9SyNhFIWfOzNiOv+Apeu3jRux0c4mEdROMIx2FmIhprS2FNMsiJUagrVN' b'ImJpI0waFYkfZf6AVgbzzt1i3okTHVxYb3cP9xzOOVz44UgaOJ0rjIbiLYYwCODAo6Pts+ta' b'5f5bgd9z633S0zoAXU4RV4HT8D2zUb88fPkiEJHfroDxf7i+dTEz17XKq3VnlXpaBwlyM4UY' b'YxNG3D8x6MSZrW2ApnqZIZBSImkpwqyIUpic90c6AgZ3KRGnX9qt3aB2vI3oPqL7Qe14W9qt' b'XaA/VhQjiwCeBQa63epWNu9rUC0XAbJ5fw/VreSFCL+6OvjfiR08d8NSCqonxWze3wMIquVi' b'Nrcm8OFClSewuadzhVGDe2f3pnqZoShzTJCSer070n57IOohVOOM1S+OGp0/mMqtVhRW7Nrk' b'ozC+YEo5OD9ZhUQH4XtmA7i162dyErtxxWzGYEegfnn44mJmFK0AmiIQopRdzGz8hZ0OPs/k' b'vD8ioSwgMhxZ1gbGOatfHDXS7n80fwEqbI9NTan9sgAAAABJRU5ErkJggg==') index.append('ABORT_16') catalog['ABORT_16'] = ABORT_16 #---------------------------------------------------------------------- ABORT_24 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAJZSURBVEiJ1ZXNS5RRFMZ/5xo2YxOthMgWaQXCGFQzbVoEKUoqZGovCGHNPqKg7ONPsGYT' b'7VoNDoEwlRmYkiTRMmdcpKELkRZi0WyCBgcK72nhDL4fo6m06Vnd95xzn+d8XM4L/ztkK2fU' b'caprCuFuRS6BngIOl1zLCDOijK5GiiOfM5lfOxaIt1+9DDoI0rB1jrokysD0RPrltgQcx6n6' b'UqgZVPT21sQ+GUg2RIr3M5nMmtu+xx+4G/JSpneWCmGAAZ99A/GOa72oPt8puYdQtdfdLlM+' b'RB2nGtVBX1oLqDkPfKvAlbdoCzDrNqqR5LH2G3sDAjWFcDdw1B1sVa9nJ1LvMdoK5N3kGG2e' b'GU9PWfSWR1apP6A/LgYE1p+iFwYZjnUkTmTH0nO6Zs6VKsmrmJbsWHou1pZoNMizQG1CV0AA' b'9HSwC9SK2nfxzv6m3NvUAkZbMdqce5OajXf2N0mV/QAcDPJLvHx2v6JDFQQAarEyFetItGTH' b'UrMAsbZEI9ZOArWb3KmrUME/ha0ksLJJcN7dFk+7vIN342tQQMhVIncPFCuTpXb5B++FMB0Q' b'EGXUH2fRvgoD9Qzeolf899Tq6w2tEqKOUx0uhOZ9y23OojcNMkxwoHmL9hnkMdDksi8WI8Vo' b'ecN6VsWZC/09KvIiUPIOYJSejxNDI+XvKrdzZfHTfN3xk/uBs7tiFx5Njw898Qj6Y45EVu8p' b'JHfKrZCs31d8ENTcBKV2PcS3nypg0Sh33W3ZlgCsDz70M9SF0CUiMbT0yxSWVTUnyCv9HhrN' b'5Z7+/ksS/zH+AJly9UDPAIpxAAAAAElFTkSuQmCC') index.append('ABORT_24') catalog['ABORT_24'] = ABORT_24 #---------------------------------------------------------------------- LIST_REMOVE_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AADtSURBVDiN7ZAxSgNhEIW/+c1abZdrCCnUxT5FYCVgo1WMZ9DCLqAXSO6wNuKUgmwhWlis' b'BANa5AaCR/glxYyNhYGsW6Sx8Gvfe8N7A/8IwG5+cuPuh3Umdz+alVe6SmsBiPnE8JUGgJZY' b'VavVCRvI+7QsaoNLBzzIqThLE1xEgSrrDtu2yUWSxvNKNWa9QcckHLyUxSV8/+A3dvaPtzB5' b'BN6CMzLhFniNacznqgsB2M6HZwHZ+xk0/Hl2V4wBst6gYyHcA23gIUljv1KNAKGpQRNrT2hs' b'ED7lA7hO0tiflkUVzLo4T3PVxbrt/whfVVpeFIrDr/sAAAAASUVORK5CYII=') index.append('LIST_REMOVE_16') catalog['LIST_REMOVE_16'] = LIST_REMOVE_16 #---------------------------------------------------------------------- LIST_REMOVE_24 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AADwSURBVEiJ7VOxCsIwFLzXzHYT/AgdxEoHJwWH9BcKRb/I0bEi9BM0izrpUBQ66OAnCN10' b'DrokUupgo9TF3hSOl/fu3SVAhQrfgvTB4cHd5OJBzOl9FWCZKvo/FM4g5zm53K/FIrpma1zu' b'27GIbgCevT7JgDo8mEhicdcbNTTZ5uO6BNs6XjDNCi/0EvIqJdgOQBPASYINAIBBbjTHIHt6' b'O+MBWm22oaKfAxMRpi8bGGagh6wBtFSnM8Hq75ezS7au9H/wO4uKwjRkY4tiEV0JWIBwJrKG' b'iQjTRISpGnQEaKX+wlcgl/t2nlTcR7ZXKA8PCIFhMNuUM9wAAAAASUVORK5CYII=') index.append('LIST_REMOVE_24') catalog['LIST_REMOVE_24'] = LIST_REMOVE_24 #---------------------------------------------------------------------- RENDER_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAEKSURBVDiNzZM9SkNRFIS/uQa0dAHWthbG3x28tJJYGRfhDgSLIJjGSrCI6RTsDCL2EUIs' b'bNxAFhALm6B3LHxPXvDlITY6cOGewzlzZxiuyGG91lx+j14BUAhx8hZvn+66r5Sgki+iOZS0' b'C4DNfGAHuC4jEMBqsncg1ALmCmbGMXj78ab7PFNBUNiwXbQMsBiiztdq+6Mptfhh2Ls4CSXq' b'RpKussL2ku16et8KaBNgJoGk/qDXaaQLbdttgEGv05DUn7JQBNv1atJ0SnaZ9atJ07bJ1JVZ' b'+BH+N0E+hX56Mu9fkf59CpV0OJZYAXHs6EG+FfxpIyXgVJKl738h2mMmC0fD+7OX0kd+iw+H' b'DX6VW9DlbAAAAABJRU5ErkJggg==') index.append('RENDER_16') catalog['RENDER_16'] = RENDER_16 #---------------------------------------------------------------------- RENDER_D_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAqUlEQVR42mNkQAKTJk1SA1L6' b'UO6/////78jPz//KgAcwohmwAkiFIwkF5+XlrSNoAFBjMZDqBGJmLGo+ALEV0KDr+AxYBaRC' b'8Vh0HIifoImdABrah8+AJ1CNoVAaBCyBeDWUPg40IAyfAatBCoBy/4HsMKjYKqAYI1Q9AyED' b'CIHVI8CAIRYL6HkAHXQD8Wl0LwINOA4zwAZIZTPgzgulQMUfsZnMyEAhAAB4bG8RCLGU3wAA' b'AABJRU5ErkJggg==') index.append('RENDER_D_16') catalog['RENDER_D_16'] = RENDER_D_16 #---------------------------------------------------------------------- RENDER_24 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AACoSURBVEiJ7ZXBDcIwDEWfEUKMA6JD0CHoEj1y55QpsoSXiATrkAtcShVVjeIieqF9p+TL' b'9rdlRYGZkTGxqps7cBjIj6D+ONVgk9GHxXNakX6C0/lyE5EW2BVyIuCC+qvFoJ/AWJwuprUU' b'h2SCqm5e1iQLQb1Afgc/w2wQ1MunK8t9ssG3LGgHq8ECDNaHNhvb5Byx/QcAz6B+bwlMJ3Cd' b'SYkI4oyN/AFvXnk5eAGTlBwAAAAASUVORK5CYII=') index.append('RENDER_24') catalog['RENDER_24'] = RENDER_24 #---------------------------------------------------------------------- RENDER_D_24 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAg0lEQVR42mNkoDFgxCY4adKk' b'80DKAE34Ql5eniG1LPiPTRxoASMDiQCuAWhoG5AqBmI2Anp+AXEP0LJqUi34SYThMPATaAEH' b'qRb8J0YDsQAWnIPHApgGmDpi+YPHgqEfB6MWjAALRjMaXSygeX3QCqRKiLAEVKN1Ay2oIckC' b'WgGaWwAAEdiLGVc80bIAAAAASUVORK5CYII=') index.append('RENDER_D_24') catalog['RENDER_D_24'] = RENDER_D_24 #---------------------------------------------------------------------- RENDER_32 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAASdAAAEnQB3mYfeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAGNSURBVFiF7Za/ThRRFMZ/36zQgJWtz0CzaBYNVsQsFnS7hclCJCGhJCS+hAXyBuoaG7c0' b'AUmoKGDR3dpeKHgACv7szGdBduMqAzM7hGnmK+c7957fnHNu7oWcpTjj+cLyw/PL8J3Eo389' b'4x4hm52d5o+sAA/ijMuL3hxi1Y4JKAHwOitAEGeEOBYOQOhGP6mGWjA9v/QevAJMpNgjlLQP' b'qv/c+niSFmBQgafVxRnwWsrkACXbs46it2mTw18zEOLHip/JWyXxrFxt1BIlVXRwuP3leAgg' b'qwwVSV+TxPYc1IEW3DCE96XRKmA2jNsA/b8WtCN7AyCQ1g0VANv1K18VxPqdABi3u98/twCm' b'5xevPkpH3e1mC+DJq6UadgWgH1euNrhuxnJvwQCpXG3Ukg5RVtmu9yuTewUKgAKgAMgdoLgL' b'cm9BcRfc2ZMMOJZ0kCQwIjj6D0DSaZbslnY7W5/epF03aMFF6D3g14j5zwL4MMrCoXMx9bIx' b'MV7SC9uTSTcIIIzG1Ol+a/4eBaDQHzSwnCzjZ+iqAAAAAElFTkSuQmCC') index.append('RENDER_32') catalog['RENDER_32'] = RENDER_32 #---------------------------------------------------------------------- IMPORT_PICTURES_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAFFSURBVDiNxZIxS4JRFIafcz+1wU9/QtRa4BCYW2NpW5OGlUP/oqk/0BbtSi0RgYsiDX5L' b'RJhjRZsI1RREZVl+3tuQSsqn6dQ7Hc55n/feAwf+WwKwGN9a00IOsMfk3hA2rgq5vALQQnIC' b'GMDGSApAAYiImgDmh8HqBfzt5hRoeY2GBZwATQAMZfu9nhRkZ7wAQ9n+qK+LSAZ4MEanHcdx' b'K8XsHob8yAAD91/apBzHcSuF7LHlby1US4eP3bFqsQ3UfzO+/lV5mvKp/ehqBgDtQrfuPADG' b'PAPT/QFa3yECEDHGRLx2HZQ23PYCZkLN3VojeK51OzQOrJT1OhtsnFXpXOKgoiuZeS16rg8y' b'6qZSyl4Pen2DDYBPo2sBJQfAUqd1ocSNe3k9fwAQWd4MBiwpAH6LdvyyePQyzDtUsUQ6HEuk' b'w6M8328PaIbPBK3lAAAAAElFTkSuQmCC') index.append('IMPORT_PICTURES_16') catalog['IMPORT_PICTURES_16'] = IMPORT_PICTURES_16 #---------------------------------------------------------------------- IMPORT_PICTURES_D_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA/0lEQVR42mNkoBAwUsWASZMm' b'BQKpRUDMQ6S+L0Ack5eXtxFmwAogFU6i5SuABkTCDFgFpEJJNGA10IAwYg1YB8S+QMxKrAFr' b'gNgHiDmAeP+/f//cmJiYCoDsbmIMgGkIArL7////b5Kfn/+8oaGBUUhIaD1QzB+fAU+BGoyA' b'Gl5BxcWBil7CrJw4caIwIyPjOSBTDpcBl4D4JoHAUwdiPXQDmoFUDYmx0AQ0oB5swNSpU5n/' b'/v3rCmTyEqn5MzMz8+7s7Oy/WJMy0EXaQEoLTfga0Mar6GqxGgAMLG5gYG0DMu2gQseB2ANo' b'wCeiDEAzhBWXZrwGQL3CB6JxaQYBACO6bhEIM2UOAAAAAElFTkSuQmCC') index.append('IMPORT_PICTURES_D_16') catalog['IMPORT_PICTURES_D_16'] = IMPORT_PICTURES_D_16 #---------------------------------------------------------------------- IMPORT_PICTURES_24 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAFgSURBVEiJ7ZG/S0JRFMe/52ZT9Qf0C1pqdTDoHwhCmkJoaLBBcHKPttraWhMk/BEI3THq' b'PXNqCEF9RYFNLaHk0pg80XynyTK5r/fMVzj0ne4959zPh3sv8B+HUHcRWNteh+A4AbNDMmsA' b'omUtrQGA+DAJPvIADgBzAOLdjehreJV5leBXMrKCV2beBNAYWkCA0VdiIooYekYSc2xIAeUX' b'Js0VELKfeByWLlKnAFDSM0kmSv5U8MS+1paUsjM+YUZAKAIomFPmbu9Q+82KMehhUEHTEhQy' b'zrIvAFCQ0uy0fRtsWaGKlK3ewfvLTENYsP0PtYA5dnOe+vL2t/njZyN3UleNl3Kpit1/+JQC' b'osRyMJxQ9mzCNvXeG9QGATqkqhJEPZJUiUTUA86IhJwGAsHwDgEHyiZjr6yn9787P+YkqD/e' b'XU8v+psErA4KdyVQSlzCXQu6kpklP4FwVdbcwf8k73FigUuDDyceAAAAAElFTkSuQmCC') index.append('IMPORT_PICTURES_24') catalog['IMPORT_PICTURES_24'] = IMPORT_PICTURES_24 #---------------------------------------------------------------------- IMPORT_PICTURES_D_24 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAABCElEQVR42mNkoDFgHD4WTJo0' b'yRtIzQRiaQrNfALEaXl5edvRLXgMpGSo5PDHQAvk0C34T82gAVrAOLIt+ALESUA8H4i5KbXg' b'LBAbI/FB6iKABqwC6kmAWkK2BbuZmZk9//79uxjIjoSK9QE1FyPpA1mQQI4FD4HYBKjwDVCO' b'E8g+AMR/////75Cfn/8LpmjixIncjIyMp4BMLVIs+AHENkBFZ5HkpYCG/wca/hzdtUA5bSB1' b'Ejk+CFmQAlQwl4EEgB4fA5JMaV5UeAKpWVSwBORQUGG3A8UCWoGBtwAYdOVAqgOHdAMwKBop' b'9gEOSwgaTlIQoVlClOEkWQC1pAFEAw1vIFYPzSMZADaqhhlDHKEVAAAAAElFTkSuQmCC') index.append('IMPORT_PICTURES_D_24') catalog['IMPORT_PICTURES_D_24'] = IMPORT_PICTURES_D_24 #---------------------------------------------------------------------- IMPORT_PICTURES_32 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAASdAAAEnQB3mYfeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAISSURBVFiF7Za/T1NRFMc/570mWlOJ4J/gqA6Kgl2MG1UTBw0DMUCMiYMDg3Hxj9BBNhel' b'Fga7GJQ2VYcmxsQCrVFk0ThYjcb4g9gAJbbvHqciFPr6Wl5rIn6388457/t5756be+G/trtk' b'bXD01PBxg94U5QBg++zlAHPGmJFcKvZ0A0C472JXySq9A/b4bLxOAgsrVnnf3NTEAoBVSZSs' b'Um+rzQEUOneYwLFKvAqgqqFWm2/mZbkVtkP/HMDXvwkwqQGOAN9aCCBfaiTe2DiD2QfRvBEu' b'ANoKgEk1ziEgX/V8CUvPZZLjBYBcIvpQ4bqvAApvtbRzKJuKfbaMOQMs/snK5dmpu6/X1u8u' b'5q8Bz/wCWBJLz2af3PoJMJ2KvVTMIGCA0dnkWLS6IZ1Ol8WxB/AwD3UBVLhU/YXZZOy+iAwU' b'Q8WrtfpmHt3+4GUe6gGMZhPRiU0NEmP35uPxX27NXuYh4JL7IUimOzLYXwfSXcILlO/A3kYB' b'uhSNiYhLiQfV2ZCrSyBifdqak3fZyMcNAKHi+wzCdBv8M7tW8jOVYN3/3X+iPxQMBkdADor4' b'eyNSxRHh1fLy8uh8Or5Yv2O7yPOI95483+FI4IZAh1udQsHW8pXK2eAbAMDh08PdttHHCp01' b'SgoGqy+XvPPc6zsb3uQuEA2bNwVQA6Ip86YBqiDsZs23rJ7IULgnMhRuu7Gf+g23rdCkMz7M' b'KwAAAABJRU5ErkJggg==') index.append('IMPORT_PICTURES_32') catalog['IMPORT_PICTURES_32'] = IMPORT_PICTURES_32 #---------------------------------------------------------------------- JOB_QUEUE_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AADGSURBVDiNxZG9DcJADIU/k4zBGEQKI4QeSiIKFmAQNgAEZegRG4DEGqwBjwIiHReHnwbc' b'3J393rP9Dv4dVl96xXgBlEDyhnMxsTrtN1OATlD4hAyQyJjUjzQsPM6zmR08pqQ+0A0bpTHI' b'zA6n3XrkCWSDspI0DHMNAUnDXjFWywSNXHMCOF6luSfQMZsJ8qecB/wmmitAbmaVB/b28kzc' b'xiZ65rVPIPWzQVnFOY8cC1y4/2+3rVuEBQITBcuw8JqsxQe4H8UNzexBrvi09KgAAAAASUVO' b'RK5CYII=') index.append('JOB_QUEUE_16') catalog['JOB_QUEUE_16'] = JOB_QUEUE_16 #---------------------------------------------------------------------- JOB_QUEUE_D_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAiklEQVR42mNkoBAwUs2ASZMm' b'zQVS8UDMTEDPXyCen5eXl4puwB8iNMMNARrAgm7AfyjzCRAfx6HREohlQAygAYy4DFgNlAzD' b'phuoZhWQCiVkAFEAnwEngLgPh74iILaguQEUewEjEJEDjxgDsEUjPPrwGUBxQpoFpJKIMASU' b'lOcCDUhHMYBcQLEBADPRSBFbV1sbAAAAAElFTkSuQmCC') index.append('JOB_QUEUE_D_16') catalog['JOB_QUEUE_D_16'] = JOB_QUEUE_D_16 #---------------------------------------------------------------------- JOB_QUEUE_24 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AACFSURBVEiJY2AYBQQAIzLH2D3em4Hp/0xGBgZpMs17wsDAkHZm+6LtMAEmFNuY/s+gwHAG' b'BgYGGQYGhpnIAkxYFFAKZPFZQHXAgk/yzPZFjPjkYcDEM+4/LrmB9QE+lxELRuOAIBjBcUCs' b'70bjgGQLnlDBzMf4LEij0JLHjIxMaRToH4kAAGiVH8B1T57tAAAAAElFTkSuQmCC') index.append('JOB_QUEUE_24') catalog['JOB_QUEUE_24'] = JOB_QUEUE_24 #---------------------------------------------------------------------- JOB_QUEUE_D_24 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAdklEQVR42mNkoDFgHF4WTJo0' b'yRtIzQRiaTLNewLEaXl5edtxWfAYSMlQ6OjHQAvkcFnwnxrBArQAbu7AWoCsEB/Ap29gLaB5' b'ENHcgtE4GHgL8AURPscMHgtoHkS0sIDmxbUnkJpFgSUgB4IqnB1YLaAFGPoWAADtt2YZzccp' b'JAAAAABJRU5ErkJggg==') index.append('JOB_QUEUE_D_24') catalog['JOB_QUEUE_D_24'] = JOB_QUEUE_D_24 #---------------------------------------------------------------------- IMAGE_ROTATION_LEFT_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAITSURBVDiNjZFPSJNxGMc/z/vu1bmpUyQkIyxoFkklzgIvVgjF1EBEPYjMW3rp1rVDXesQ' b'jIJJO+SlwzQIbcNDtLp4KA/9EYSEQOwgVDpazndz79PFLZNt9Fx/z+fz+z7PI1So7oHQsVye' b'BUWqBH0ljkTeLT5dOdgjlQQFSTbPa4FmYAeY3cZ3ey0RtisKTgVvVTeSigBguO6Rd5ocy/7K' b'njUtQl3Gm+lficWyRjm4gdRzhQmFCXX2wltS93F5/tn3usz6KMqO57f7fskEBRjoO/QU38Y3' b'tJYI2+f6xxqrHdcXceSy+Z8wgN+N3enx98ytxqPpo/4OL0J3MUH7yEhVTdozC3qj3F72Iy96' b'M8ZgukYDKvqomOBEa1cUGC0BbBlKrxr6RpDPil7JWZzP1GYiVs7acAWC44O7tXacdOkfFRoc' b'y/1heX56KdAXGhOVVkfk7UoslgVeuATjrvdXzeZP8U02kDryz/zCKopqdqcl0Be6JMoMsJjS' b'+qlCiyGiSQeurSXC9ja+ISBeFDg8fJ+YOSumUYQLlyi0mC1tFzZAHjedbn+yGo+mPf6eOTd2' b'J+BX9FNLW0dzOXh/R9AVDIVRjtfurg8nk8m9v+fUMyCt5eCiYB94iZBSMzdp5KpPYho/HM3f' b'AUhp/VQpuCg4IHkADAMehc0qk6tLCzPfSt/nkKBQF69PtGM6N1WlF8hZJgOVJH8A8YzipTpp' b'yrkAAAAASUVORK5CYII=') index.append('IMAGE_ROTATION_LEFT_16') catalog['IMAGE_ROTATION_LEFT_16'] = IMAGE_ROTATION_LEFT_16 #---------------------------------------------------------------------- IMAGE_ROTATION_LEFT_D_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABaUlEQVR42o2SPUjDQBiGe0Eq' b'iAri4CAigoqgm+Aq4qRVKdJJB3GpXfIzuDrUxcUhiTi0k9hVnbTQQTq4C4KC4KCLg4MWl4I/' b'JD4pSYhtkvbg4ct3vfc57noiETNM0xymXEISrqGgKMpDcI1ItBmupApDUIcz2EX0FSsg2O3s' b'6Lb7MAjPUIQ+27ZTqqp+i5jwBSy7U2VYd3bVdb1LkqRz+hd6VXQQTjRLDMMYEEI80c+LDsMt' b'Etbm+e73BViTWJ0LWm1zrxVIwywc+wKMJ5StkEANUjAOE7AJN1xilg2XBME0TZmmGCGw+a1X' b'luU6azfoT6HEMbYbfyOTd9Qc3Iac/9ERMNaQzLnhincPnsCgfjCRD7nEHPOFwM7/wp5ghlpl' b'l0keRq1JcgD3UeGGwL3AI8qIZVkZTdN+A5IpGI0KBwVO4Ao+YQfG4B32AkdpCfuCgOQQMtAD' b'b7BA8DXuUYQ95WlKFhbhB1biJH9Z/5/CudBE8gAAAABJRU5ErkJggg==') index.append('IMAGE_ROTATION_LEFT_D_16') catalog['IMAGE_ROTATION_LEFT_D_16'] = IMAGE_ROTATION_LEFT_D_16 #---------------------------------------------------------------------- IMAGE_ROTATION_RIGHT_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAIGSURBVDiNhZI9aFNRGIaf7yRNTFtJqoNDh4JEEKogGIcuEnEIiQEhEHAxLYjWJYODo10c' b'3HSIoNZFgy5eKBVKo0LtZlGriFgpUhFRB4fa/PTHpLn3c+kN8ZrWdzocvufhPT+CJ7FTZw/h' b'yAVFTgra6PKRnpsq/vDOuRF3EU3mg2GpXBclA3Qr/Az4OLET3BJEk/lgH5VpRVdMQ0a1y+zH' b'Z5ZxmmMAK4RHl0qFeieBAeijckOVWu/GtzOvZorLK7L7vTrNgsKwwnCEykQ0mQ92bHA0NXJY' b'1HneDJoD7ybvlaPJfDBCZQJIeWany4Qz3iZG1DkvaOE/MECqUxMDxG18zwaz2UCEqrUN3JL0' b'UXkcj4/sagkUZ6zeu/a2ezU0Ds6gql5DuYiw2MmgkKh1662W4E3pweSCZTW2rmQAIx/mnxTv' b'tDG/OokGs9lALJU7/dc/2Dp/QoWc35jXJrT23a6FjjjCizZ2ukw4E6EaA71p3N2lUqFeJpwB' b'nopSbDrOsTnL2nCMRr3wUqlQFzSB6KzgibeJUQ4qXGmHhxLn9myazU8+7OP/CLwS0K8giy4c' b'j8f9q6GBCeDzfOn+pY4CVxKW6m0AI76r2M5ep6v+RZqBu0DPRu96esGyGtsK3Aylc/0Nm1mB' b'fcC6iD5a7/l92X25HQVD6Vz/ps0U4FeY8WOPvyw9/Ng+8wffL+Zav9jy/AAAAABJRU5ErkJg' b'gg==') index.append('IMAGE_ROTATION_RIGHT_16') catalog['IMAGE_ROTATION_RIGHT_16'] = IMAGE_ROTATION_RIGHT_16 #---------------------------------------------------------------------- IMAGE_ROTATION_RIGHT_D_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABYUlEQVR42n2STygFQRzHd7ZX' b'CicOiptSDpSDKyUH0VOvlyPKxbvtroMjh+eubZP0XF4OiuSkVw64uSgHB6QkxUH5dxIv7fpM' b'zdMaszP16TezM99P82eFo7Uoivoo8zAKdch7nvfoZDSRCjZRVqEIzfAEI7bwr0CFa/CWJElJ' b'CNFN/wWW1boSoi+bYJ3SGcfxVBAE30q4DxNqnZQXTRLB4n7qMfSw4N0QdmwSKYioz0yULeFM' b'iRRcyFvn7OecfY/+pGNvh1BA8tkQFAjXCFcYD8EO3EMAvRmSKoI5/RmrlGmYZXKb8ZUSvEKb' b'LlCvNa7/B/L8Y1ICZ/AAA3Cq3wMMwppIa3WJ2skM/S39Evlept8qtK2ZdiKPsaSF5ZFuYPif' b'wCCRF3rdCIdhmHNdV87dMl4wClKSDTVcgXa4g01o4RLzvu/XMwUpURflBDrgA3YJL8rwn2e0' b'hA8gB0dQYduX6TU/ZXOiv6ytZKAAAAAASUVORK5CYII=') index.append('IMAGE_ROTATION_RIGHT_D_16') catalog['IMAGE_ROTATION_RIGHT_D_16'] = IMAGE_ROTATION_RIGHT_D_16 #---------------------------------------------------------------------- IMAGE_MOVING_LEFT_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAECSURBVDiNxZIxSgNRFEXP+xlwBHeglUuQUQubVILTxVaYWLiAlKbRaUSsXICNBCsXYLRK' b'G8GxcgcquoCBVPOvjUwizIyBIJ7q8/479/Phwn9jVcN2+zDMQ+0Kv9QkOx+Mg6qLfFnnoJ5V' b'55eoVby52UEUJymAGauN5pS1MiCKkxRxOqdY4haRAdwiMoCTmPyy48uTGAlOfgRkw8GF4LhG' b'zj1uB3gBPiV/kG2vnyHdlwEAdSEGR8/D67H3vuNxnezh5oM09YUFieD9e2dKFCfp090g3Yy7' b't5I2BFd1/zJjC7Ff2ZRor3sJ6tXJM7xWNnFlYv08ZNRUZTOTFa3HOR75Y74AfnxbCh9D2xsA' b'AAAASUVORK5CYII=') index.append('IMAGE_MOVING_LEFT_16') catalog['IMAGE_MOVING_LEFT_16'] = IMAGE_MOVING_LEFT_16 #---------------------------------------------------------------------- IMAGE_MOVING_LEFT_D_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAsklEQVR42mNkoBAw0sSASZMm' b'cQApNyBmJ6D/BC4D+oFUAREOeMKIprEhLy+vAUivAnJDSfICSDOQqgcawEiyATDNIDbJBiBr' b'JteAciDdgceAf0DMBGXvh+ImdC/ADUEz4AsQuwLxbCAW+f//vxELC8vLv3//bgXyPdADEWwI' b'mgERQP7KiRMnqjAyMooA2SegakWB1HkglsYXjUZQm3EBMyAOojQhPaYkKf8H4pO0yUykAAC1' b'i1qQz5ZMvwAAAABJRU5ErkJggg==') index.append('IMAGE_MOVING_LEFT_D_16') catalog['IMAGE_MOVING_LEFT_D_16'] = IMAGE_MOVING_LEFT_D_16 #---------------------------------------------------------------------- IMAGE_MOVING_LEFT_32 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAASdAAAEnQB3mYfeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAHSSURBVFiF7Za/a9RwGIefN7mh0h/uVaj4HxROFNylDbh0UKjt0aFQcOmi0M0OLgUnrYtQ' b'IakgGLdypP4BFbHJILR0qO3mJqiId601eR2k1cslMddc75b7bN83b77PM7wkL/TSS5cjrTRf' b'G5u59Et0XoQLRaCqhCq6edBfX84tcHX8zlCIuQMMF4E3RGTFyNsbYl5vKxxA9VamQNmqLP7t' b'1YG2wv9kMFWgbFUWUR6cAbQhiQKdgicKdBLeJNBpeINAN+AnAt2CAxjdhAMYqtTP6nKFXVRn' b'MwUCz1lSWCjIqiXUfoihE/766gqwnCoAUEhCeAFyAziMPbjrV1e3AL5y/p5AkCpwWgkVPqjZ' b'N+d79oYqcydo0ce+ZzvH54/ek8MIuQ18SxVoVULgiyGliWDtWQ0gWHdshUcC72r9B/fj/YFn' b'7wFN89D0JcwpEUWRTG9Wn+//W7w8UF+ISkc3t133Z9JLvue8JjYPif+C/0ko8jB4Y1fjddd1' b'w2Dt5ecs8/g8lNIaA89ZKluVcykKlfL49FQWKEtBkaHjU+6N6Io1M6YaeaeDpuZ77o3I0KO3' b'Cp/aihd51dJSOmpNjpiY84JxsQhXlRDlfX2w9rTIPb300pb8Bkt9tPNSsvOcAAAAAElFTkSu' b'QmCC') index.append('IMAGE_MOVING_LEFT_32') catalog['IMAGE_MOVING_LEFT_32'] = IMAGE_MOVING_LEFT_32 #---------------------------------------------------------------------- IMAGE_MOVING_LEFT_D_32 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABiElEQVR42mNkGGDAOOqAUQeQ' b'onjSpEkKQCofiKUptPcvEJ/+////FKIdALScD0hdB2IpKgbAXFIc4AmktlHRchD4jNcBQEsb' b'8vLyGqDsUCC1isoOwJ0GQJYDqXqgAxjp7gCY5SA23R2AbDndHYBuOV0dgM1yujkAl+V0cQA+' b'y+nlgHIg3UEjB9wG4k4gnoPTAVDDcTqCSAd8A2IuNLGvQGwB1H8FqHcykJ2D0wH4HEGEA5YA' b'8Qwg3gvE7Eji8UC9i6B6QeJHgdgYpwNwOYKAAy4yMjJa5ebmfgPKxwP5C2BGAfXlo5mtDKTO' b'AjE/TgdgcwQeB7wHYhOg/D0kvd1AygZYzdrn5+f/wmJ2CJBajdcB6I7A4YB/QOwHlNuKrG/q' b'1KnMf//+FQSKv2HAAdDTA77KCOwIHA5oAorjzLr4AHp6ILc6fgANBXIBqHEjQtABaI7xAFLb' b'KbAUG/hMapPsGgPl7UFkQHyTDAQmTpwoD8x2oOwlQ6HFoEbpKWBumTq0muWjDhiWDgAAO0PF' b'1wqSFgAAAAAASUVORK5CYII=') index.append('IMAGE_MOVING_LEFT_D_32') catalog['IMAGE_MOVING_LEFT_D_32'] = IMAGE_MOVING_LEFT_D_32 #---------------------------------------------------------------------- IMAGE_MOVING_RIGHT_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAEOSURBVDiNxZC9SgNREIW/ubs2IvgAiq0PECSQBxBSWIiI3VZ5AhFsky5N8BV0bewDJgpC' b'KgO6eYQ0wcJGsBDM396x2GzcbNj1p8mBC8OdOd+ce2HVksKBt8NEi7lDmNHGUO47ncthuucy' b'5VFEtvL3KB/r9gI4TXeMwA/meYptgL2yV18A/Ma8mIXzJOTPgDTE/Q8gAVlKYL8H9AzhKRei' b'fCYBXVHZB8YgN73WdUMdjoG3jAjVoO3XYsCrWnv03L56UOzJOLQVgF7THyi2EiVeNsPsDxS6' b'GOMVyh4Aaw67cT1Tf14JtaAVmWPAi8Ah0cl+L7YJENz61eS9K6FTUicsqqpkmQUzemfzLm/B' b'6vQFM/Vb/jMIvyYAAAAASUVORK5CYII=') index.append('IMAGE_MOVING_RIGHT_16') catalog['IMAGE_MOVING_RIGHT_16'] = IMAGE_MOVING_RIGHT_16 #---------------------------------------------------------------------- IMAGE_MOVING_RIGHT_D_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA0ElEQVR42mNkoBAwUmzApEmT' b'5IC0OQF1P4F4V15e3g9sBjwB0tJEWNYPNKAImwH/iXTtaqABYUD1HUC6ghIDQOo7YYaQawAD' b'zBBKDAAbgm7APyBmgrJLgDgMiM3wGNCAbMBxIK4F4m1AvA6oOBIaxeeAWBiLAQ1AfiPMgBf/' b'//83ys/Pfw7kBwDZu4HsryBVID7IQCBeg2QAWDNyIK4H4pN4/J8CxOehBoA0NyBH42MgLUNE' b'IOJMSLIMkKSML1+AkvJOoAE/MQwgMgpxAooNAADYLXyEpVe9PgAAAABJRU5ErkJggg==') index.append('IMAGE_MOVING_RIGHT_D_16') catalog['IMAGE_MOVING_RIGHT_D_16'] = IMAGE_MOVING_RIGHT_D_16 #---------------------------------------------------------------------- IMAGE_MOVING_RIGHT_32 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAASdAAAEnQB3mYfeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAHaSURBVFiF7Za/axNhGMc/z3vXNoV066SbW9WxBcG/IIugmK2mdCzWWXBKyCK4ZFYo+YE6' b'OFmwF6vgFGh7VwotnRz8QSvYQZBSg2nuXodQSeLd5bikqUO+08vd87yfD8fD8cAoo1xw5Fo6' b'PZ44mVwWLXMiGP1cpjWHrpwWdtZefIksMJvKrACL/YA7JOAwMWbO1FZXjqPUKyA9KDiAwOVG' b'07sZtV4ByUEKAHieO3V2nktlHvcSONdoeBgmce4CvSSGIhAmMTSBIImhCvhJDF2gW8K8CIE2' b'iVhfwBVkHvjWt4SmHibwK6DtkW2VnmvFPODGp5N1quVckMBX5errwF5X02vHqjwB2H5T/oAm' b'3w8c/Ifwt2h1d2u98snU6pbAUauHj7qZWGgdW3FuXMmDvIsL9xUQ9AO7WrQBNqrFzxq5A/xQ' b'ntzefv/0Z0dxNus1XC/6PHTB/xHQIkXbqjxrf+ZYpZoxdnrVflva97tzd71yFGkefODdArsY' b'E/f9ejdXX34Pu7vnPATAofM/cEma9b3Z1L0wVggDJX4vhJxj+cPPBI6BKWAaZDoWHWiHK2X8' b'3YactXI2rE8Br+JCA3Iwbqpa1GKznqwvJU4m9weylOIdaEMKUffBUUb5L/IH3W26DRZa1FkA' b'AAAASUVORK5CYII=') index.append('IMAGE_MOVING_RIGHT_32') catalog['IMAGE_MOVING_RIGHT_32'] = IMAGE_MOVING_RIGHT_32 #---------------------------------------------------------------------- IMAGE_MOVING_RIGHT_D_32 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABnUlEQVR42u2WsUvDQBTGLxUc' b'RNcKTl0VHDuIKDo4OLq4ig5OJhl189y0UxPIJIq7U50E/wJxEAQnJ0s7CBJQoeAQ4vdKW0xy' b'J9ck5Abz4ONeL+/e9zsSemcwzWGUACWA4ziThmEcIK9DExn7dcMwbNq2/aoM4LruJcbdHDfV' b'xYbmTdP8UgWgwukcASg2Lcu6VQUIczan2AbANSXof4r8SCcA9T+TQRQFwGQQRQIIIYoGSEDo' b'AIhA6AIYQegE6EOkAQigHagBzWUE4H8B9KApwfwhmjewbh35HROfHyoAHDUnMoA2tAa1oMVf' b'8y3f97c45+Gg+TE1SgHQN6dEBPANraDgAc9qyO+hKvQC1TH/MSz0PK8SBAH952+MATAylwHs' b'o+B8+APPlzHcQKuYf45vBcd5FaffI4t+DzKAiLkI4AoFiaMZNbOYf5O8Syb4HkQACfM4wBN2' b'soRzvMdSROx7iAMIzeMA79BnGvNBVKCaAIDMuWwRAZDpTAZjUYx1IbnAuJejeQevckH5Spbz' b'pbQDNbH7tuoC/dfyEuDfA/wAnmX8lAqs+aIAAAAASUVORK5CYII=') index.append('IMAGE_MOVING_RIGHT_D_32') catalog['IMAGE_MOVING_RIGHT_D_32'] = IMAGE_MOVING_RIGHT_D_32 #---------------------------------------------------------------------- IMAGE_REMOVE_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAFGSURBVDiNvZA/S0JxFIaf8/Oa4VS49hFqUcvdGryJSyCS4nWqdre+QFu4BEVLkEVDo6QR' b'4RqRNERbEA1NJTSFpN57mpQg/FNB7/Zyznl43wP/oahdcBYWnVDfJ5yNSGo9CGCNOo7ZuRkX' b'3XUDPERSq0vS8W8iFHFbAuzJOAnCdj5ukArQAkKIlhrVchHAjAO4rZXrInIGhICm+rpbvdlY' b'gGjC2VbVtIicAkFc/2XvJxbAXDI7HVB/XD3vG1CMWigFREs31cNi2M7HjUrFm5AkcCgAEdvZ' b'F1gbGEG9bOP86KRnY3Zu5rp2/NyvYESmhlVQpPvV9477gL9oGOD15wDhTOANuGq7Ogv6+BPA' b'fburGVWz4veRvrsovxghA3wMA1gAquoB7wHLHIDS9YT55QIKKNo04A5NoMoO8DRgp9qZ9NVH' b'Vfm1PgFPlm4X5nAV2gAAAABJRU5ErkJggg==') index.append('IMAGE_REMOVE_16') catalog['IMAGE_REMOVE_16'] = IMAGE_REMOVE_16 #---------------------------------------------------------------------- IMAGE_REMOVE_D_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABBklEQVR42mNkoBAwEqNo0qRJ' b'cf///9+an5//FspPZ2RkXJybm/uNoAFAxTJA6iYQ3wZiFyCuBOIiIM7My8ubQawLnIDUZiD+' b'DsTCQNwP1FxEtBeghqwCUqFA/AaINYEGvCElDHqhzl4NxN4g7wDDxBkUJmADJk6cKAgMFJAz' b'mbDoZwHiyUC8CORsJO+AwmARI9SGWUAqFY8jooCKlyMHLJD/BO4FJP/hAmFADauxSdDUgNdA' b'LEqqAVuB2AqIbwBDOQAYsMeBbCViDdAEarIAajIFRRNQw1OguAmQfQSIYwkZsAJIKQDxIyxq' b'QC4C6s9bh88AGyCVw4A9HXwA4jKgAR9wGkAJAABWGnIRb3GQzgAAAABJRU5ErkJggg==') index.append('IMAGE_REMOVE_D_16') catalog['IMAGE_REMOVE_D_16'] = IMAGE_REMOVE_D_16 #---------------------------------------------------------------------- IMAGE_REMOVE_32 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAASdAAAEnQB3mYfeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAKxSURBVFiF7ZbPS1RRFMc/5z0dWrQMgimChigyomycxiCEFtKM9ItI0UwLyUKiRes2bxH9' b'BUY/EEGtjCSCKNMoJSrMZhTsh2iKuxSDaFOL5sc7LZwZnjpCMz6LwLM759x7v5973rn3Plg1' b'Fy0Yrt24ZNKyjOLyBu/CsOGWeEm4viGJOeEPnzqWJS2BwalmsyA5HAzXFs1LuCIeqqtG5A5z' b'G4qhUhntaXsEgGUZgbdTN1U4mxo+XWiyd+Bx+xdwqQKmJ9GvyFjK9SDalaqEBAanmh3iAD0D' b'Jb6ZtONKBQCKyxu8ZkGiD9iWCsUE+hUOZsSUlkip7zyWZbsOABA8UrM+Eff0CVqUJd0aDfoa' b'neKuAwDsO1S/IZ5kDFjrEOmNBH0VC8XBxVOQ1kokuewUB1A44B+cPJJtgumatGUZgTWbbqlw' b'3hH9AXgAU5Dj3i27309Pjow7p7lVgWzd3qq2vVWR0ZTvPB3uAgRC9U0KTRkapSUa9DUO9d6e' b'sRNmOZDetUcwOp035rwmDFScrkL1KCKFuQDY2OOGGrsUPUyWbnecju2KXBh62nZ9EYC/4sxO' b'UXtkIdSfmopeMWyZiZT6bmTr9uLyBq9pxsuiPR33nPGMWEm4/gTQlY84gIh0RbrbqnKdl+kB' b'VXX9TsgJ4F/ZKsD/ByAir4DpvwQgs05P4YtREKsU9CSQXFEAhQkjpjsQnqdCcZTqwUeds5Gn' b'HS9VxVpJgJ9i6PF3L9q//ZJEFfAZ0UtDPe2v0wOGSjdfBZ6tCIAK56JPOj4CfHhy97tZGC+L' b'dndcmzfIsuxYUutYZj8ULA7JMLYd94fqKtORRAz8obql1ngAXFw+gGh87mnQPSJyP+eVVOP5' b'AGQ+gU3hG4Gv+SwC2AoP85k47wHyH65ZR8Lcj+b2P2CoMRrpbfuUD8Cq/QavlPR7ZeZ/5gAA' b'AABJRU5ErkJggg==') index.append('IMAGE_REMOVE_32') catalog['IMAGE_REMOVE_32'] = IMAGE_REMOVE_32 #---------------------------------------------------------------------- IMAGE_REMOVE_D_32 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACDElEQVR42u2Xz0sCQRTHd5Nu' b'XZLSsG4R/YDoEERBdYgoCKKItMJbFGFL/gUehDp0VZAKwlsSGfTjEkE/DnXoVAQmRdd+4MVT' b'QRRm38lRntt6WJ0tEge+vN19s/M+83wzO8rSHze5qAD8fn+d2+1+0PIFAoGyRCJRA/+TIQAI' b'Ps3iQFMIskt9Xq9XNpvNzDcG9cEfFQqA4JMwG1AZ9A7ZEWSfzHwNlzO8O8tAB/yPIgGsMCdQ' b'C3/EICbi8fgen7mLdA+aTKZZRVE+hQFwCBuHaCQQp9Ag6baO4HPp4EIBcmSCtqyZGwLAIWph' b'bqEK8vgQwYfUwYUDkGp3qVzfNaFeHUIBNKqdtReSiazVIRQgx8yDyWTSI8vykaRaHTQTopbh' b'vJTahNItU+0aq+MNakjvmLJqIAfMCFSuk+EOaoOGJY1qJ6ujGVIQfOVHBtCpFea6gKwsQc8I' b'vqpV7TwTvQi+SZ9TgHGYcAG/RBiDO/S+RAHsMFslgBLAfwA4g+oh228AxCAruWenmHaoCTqG' b'TEYC3GMv78JezjaOfuhDSp3nznl/D8yiUQCvUCcGjPh8vkpAXLAuuM/s9/zrd4DLASMAnBgs' b'RHxW3MfULwPOArgrKVUPwgAuoWUdY/RACyIARmF29A5AWggAzkIAqmEikCWP4Ozrxw4a23kD' b'cIgqmG5J/3kgiuA3eYAX2Z/TfNoXuRn2Ich80EsAAAAASUVORK5CYII=') index.append('IMAGE_REMOVE_D_32') catalog['IMAGE_REMOVE_D_32'] = IMAGE_REMOVE_D_32 #---------------------------------------------------------------------- MUSIC_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAErSURBVDiNxY8xS0JhGIWf81lpBUa/IYggCOLi1OIUCYkROF4QWmpp6pc0Cg3aFg0RmfQH' b'gkwbmmqJxsYsgyC8b0NZ16uWm2f6Du/5nvc9MGppmNDSqj897rTsHJ4FeMhW6tXDOYCxaDif' b'z8ceX6YWzOFJgWcmD0gBE2adlb97ewAPr4lNOTsCMPsJvmNcItWExQ12BgJC3UoYtXZMV3qK' b'3zYaxQ8Ab83PS/ofcF0tFwbNwnLDhP7SwAvCSqcLiVYiKCJywFtfQCrjZ00uBzaLdQNak+1d' b'kP9tkz2AVMbPGjrFIj87kpuPzFqdhwP42tyldtgE2EnYm3TcBSCw+wigHjY35+UzC7SOdGDY' b'XtOS210VnjWzP0tz0WADuFOgrWiLxkWpAlT6dxylPgETllziqjxp4wAAAABJRU5ErkJggg==') index.append('MUSIC_16') catalog['MUSIC_16'] = MUSIC_16 #---------------------------------------------------------------------- MUSIC_24 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAFoSURBVEiJ7ZQ7SwNBFEbPnV1TKCKW2kbQIohxtUqt4KNNaQoLO/+CUf+HhaZMaTTaK8GY' b'iJYigTSSzkICwddei7BhI3nsRguLnGq4c/d+ZxhmYUgf5LcD5le3xkaMxI3BURcH0UQpn4l6' b'+3aYYclk0qq+js6pwRFxHVVxgGUgourptjv3DIivbE/b9oejIo4qTrVOQo1OAqgGO3zPAMv+' b'fFYEtOmlndveEe5RboDdUAFdqCmUgSuU68h4o1zIZhsAS2upwQIETSNW0f6yioXLo5cwNoEC' b'bvOZwzBD/ZhBP/w3AYNccovF9dSmUd0DiQGVPw1oDufU97BifQOCGHkYJR1EpBUQ1MjHbJf6' b'W5tIWCMfjx2rwkPHgKBGHq5w0LHb1ba6PyCQkcfd+UlOXdlEKAJ1hCKqG6WLzLm/r3UH6sq+' b'GM31M/JTvjw+A8667QNY3qJWeXiaii6UxDADTDT/kLrz02jIn/MN9/546OsNyWwAAAAASUVO' b'RK5CYII=') index.append('MUSIC_24') catalog['MUSIC_24'] = MUSIC_24 #---------------------------------------------------------------------- MUSIC_32 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAATrwAAE68BY+aOwwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAJOSURBVFiF7ZZNSFRRFMd/587zKxMqScNokUVERiBvmjBpaUzh9i2GUKFF21q0j4jWRdCm' b'TeNHRMyqEDSXpZDpbJQorcDdRAsXKpnz8U6LMkbevJn3bGrT/Hfv3f8953fOve/woKb/XfI3' b'g5+5ONBcZ6TbGGx1sRHtnZ8YPVbssaqVzHGcyMranpNqsEVcW1Vs4CxQr8qvUr317hqgu+9q' b'h2XlbBWxVbFXNuhVo/sBVIM3NhBAqVZCvlMR0J916e7qCAbQYJnHquqUa6WPciCLoAeBI6UM' b'JmikgMoojCPcFpc+tRr3zU8M2yLyxm/Dn1zCNWBRYBp0ZqvA7MLU6NewQUIDiDJgLDM7O578' b'GHZvVQDmJkfGqpF4W9W+AzWA0KraKN5WT//g4WyBWwL9QCuwrGjzPwGIXR48kSvIK0Hbi16f' b'LjcmSwJ0OU5943pTTAytmjdLQQetqyTZmbyiPADR+FBCNvS+Cm0oSMRFlVylQOcuXTlVgJ4w' b'yT0A0fhQAtEn6h32dZUCFdQ6jlTslMfw+yvocpx6hHvs8idF0dUAtowvQON6Uyzs+RXre8vm' b'W+BLOY/Ac18AQQ4EyJP1W3iXSmUFbuB/YzOu697xBYhI/lMAgKVyi3MTI88EEng7Ma3IhfTL' b'Mc8R7DjvaHxwBuG8XwJVuZ6eHH5QidK2r9VJ21YMpVVdWU5PJT/4eXd8Ba66Q0bMa+BQCe+L' b'zpZvD9OVsgPp9KMcMBPASqT4IfN5YbX9qP3URNy9QAfQALxXlbudLZs3U6lUIUjQmmoKox9z' b'gr6vGG9NAgAAAABJRU5ErkJggg==') index.append('MUSIC_32') catalog['MUSIC_32'] = MUSIC_32 #---------------------------------------------------------------------- MUSIC_DURATION_24 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAAWQAAAFkBqp2phgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAAQdEVYdFRpdGxlAG11c2ljIGljb24/SYESAAADTElEQVRIic2VbUiUWRTH/+c+4+gzOm7m' b'TKTSRoZbNqTSvLCgLbu1FGbWWhkI6cgwFdHrl2JjP0jLfuhjtcG6u0SWQhAURVFRW/lBwTTL' b'CisieqEXsRnzbUZn9Hnu6UPNtM2aqxNB/4/3nv/5nXPufZ4LfGZRvEbb9+UppkT1W12IwI3z' b'dS0fizNMNKF96boMIcgBUCEDRQCcDBgFyT0AJg9wLnXbpMB3gCwkUBGAmTzRaiYCYMHnCPg6' b'ZopBAq5JUBOAZgJvjhvwTl1E1ARwM4GbTUPPOhobG7XIpmNZVfWnAUi62841XPq/JONJfIr5' b'iwBM+JqOKckNUhHd44XE3YG92D2bCFkk+UdnceV6Z4kne6y4SXdgL62wkJbwB8CrTSZTaOqU' b'1NDrvoGk4NBwkqvEfUIXI5vazxzzfxRgKy83GvvMFkD7z2/EXlphMXBia0aGZXr12lJasWSh' b'SkQqM6P9zn38tv/w8m6f32EvrXBGINERFa7wmB3LqmrVgNqvGLQXAGbEAoxQ/86cbs2sP/Cr' b'ermpFddudgIAiAiOvFw0HNiTlDnNkmUk9a+IRwCA3b4hIaxp/4CxEUBSZFPqCEWrL3bPHtW0' b'lb9s9SSmJKvY4a3AwcPHoes6AODR0xd4+rwLP2+pTtA0vcy1pHJWdERkDa8BwxVTsE9juvG+' b'Erko1ZyqL5g/xwAA2TOzUGD7BrX1JzEcCqOj8wF2bqqEIz8XX5mT9b7+wUUADom3LcIck3yQ' b'QetuX6wPRldIWKyWKSB6fzRFrgLUHT8Lc0oyjuyrQf68HBARrOlpREJMi3bQi9QjadQ/iyUX' b'EIlOhelgy4W6J/8mSrDP5+8DM0chzvxc1O7djQJbDhRFAQAwM3w9vcxSvooCHp7/PQxgd+yh' b'fiCmqwOBgKH9zn048nIBAIqiwJ4394Ow67fuoX8wqAiJK+PmG0uFP3lPrfLuGhkMDPFYGggE' b'ucy7c3Rh2frTEc+kvuSQHvR2dftfVm2rGWm7dRfMb58gZkZbx124t9eMdr96/TI8EPZEPJN+' b'k12Lq9JJFX/qulyVYlJHrOlpmq+n1xAYGjYqijjJw3Jj6+WjPXEDInKWeLJZH/2BiSzE7BcS' b'V1ov1j+ON1/cegMv4EeC+eo6VAAAAABJRU5ErkJggg==') index.append('MUSIC_DURATION_24') catalog['MUSIC_DURATION_24'] = MUSIC_DURATION_24 #---------------------------------------------------------------------- MUSIC_DURATION_32 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAAQdEVYdFRpdGxlAG11c2ljIGljb24/SYESAAAELklEQVRYhe2Xf0yVZRTHP+d9L94fRoj9' b'ABEMp5JKOIV7rUS3tBXeu+Vc283pMnA4nKnNNduqpf1YW1o626T5Yzgo7I+8G/85tOHaCl0K' b'NCnFGkstEVATAZmS99739IdwB9xrEl5rq86f5znnfD/n2Xmf533gv24SjyJ+v9881+2aikG+' b'qs5FNL++unLScHJtIxHMe67ERbA3FyEfmHu2hzkYOhboa2n4fQ0LwOMrSkXDHpB8hbmEet0I' b'9hGw/3UAt3f5V6rWU3fqSuGCQC2QDuTHDQBk3G0kz6ByRERqsThSf+jTU33AW0DiCQBAL3BM' b'VL9RkaMadBxtqNnTNVyRuwdQDtUf/GxxPASHmnEviv4P8I8CiHJMYetw40d0Ev6Z1R2srAKq' b'/naAPF9RjkF4pao8DWT2uc8p1IihZfUHKk/eE4DJ3nX2ZLq2q1qrFDHuv2/0zYy0FAvgfGv7' b'lO6e69lYsta9sHDXjcTrr54KBG7GDWCyd519jHZVqzB/2pTM8KoXn+dJ94xRhtw6ti1VGhpP' b's6P8CzndfG6Nq8c5Ldvv9w6EiBrCxxctTXH7XnrH4yv82u1dfhzIuB3AGLo/RpjvW5DP+6+t' b'Njdt3c2Vjs7IuiGCZ+Z09m7baHgXzEFhgbPHuW1gjUEA7oWFi8LBhGaUt1V1HogHcMUSz/MV' b'5YCWPPboJDauL2ZCeiq5OVMpLQ9ExSbYbGxav5LpWRNB5GVPQWF2FECut+gJRKuAxKgKBtei' b'fGoVA8aaFX5sNhOA9SuXUlN7nB9+/DkS1tJ2idLy/ZimwdoVL4CqoaZVHAVgYG0GzFjdiqWH' b'h/pM01w4dkwSuTlTI77xqQ+xbHEB23bvo6Ozi08qAixZ/SaXr3Ryo/d38mZMIzkpkQQzwRcF' b'AOTFEgdqMxN7K6N3QDMeSU+lf+D6beniZzn10xkKlr1CXWMTuza/wbsbSnA5HRgiTBifStiy' b'InMV+QoEjigUDG6dKrvNVhQIBMKxyFQ1yuew23kgOQmAnR+8jtNhH5IDMgA6AmAFHUvE1lsC' b'5GDQLpYRqKuuqIslDCBitPx6oT3LUh20Cy6ng6qyDxGRKHFLlfOt7ZiG0RIF0PeD8dHtBIda' b'KByq7ujszmpoPI1n5vRBay6nI2ZO/YkmrnZdA9ED/b4RX0ZiaBkiVmnFfoKh0B3jg6EQpeX7' b'QcQy1Srr98ec+uFYa/P3l9ImzXz4csfV2a0Xf2Pe7FkYRux+gqEQ720v49vvTiKiO45X74sM' b'9YgBAJJnZdWMCibkN589P/FofaOmp6XIuJQHI0NmqVJ3oom3tuy8JW7IYeuio7CtrcHqr3HX' b'L6Nsv39U3/G6GjCTEkeHMzPSTIBfWtqszu4eAxFLsEqti84NDQ17ggPz4/I0A/AUFGaraRWj' b'8gwDrmOUL00J7z1W/XlTvLT+XfYH4rV7TnItBFkAAAAASUVORK5CYII=') index.append('MUSIC_DURATION_32') catalog['MUSIC_DURATION_32'] = MUSIC_DURATION_32 #---------------------------------------------------------------------- PLAY_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAC0SURBVDiNY2AYnsDUK97OwcGBhRi1TDjEc75wyp019oo1J9cABgYGBj3G/4zHTDxjZ1r7' b'JfGSYwBUnjHtx+8/1409YwLIMYCBgYGBgZGBQZqRgWm9qVf8Kj23WDGSDYCB////q7OwMsmS' b'Y8APBkaGxu88303PbV14FlmCYFQxMjIe/veHMe3srgU3sMnjM+ADIwNj+eltC2czMDD8x6UI' b'qwH/Gf5tZmb9k3ty0/KXhFw4DAAAy24ur2eu4uQAAAAASUVORK5CYII=') index.append('PLAY_16') catalog['PLAY_16'] = PLAY_16 #---------------------------------------------------------------------- PLAY_24 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAENSURBVEiJ7ZOxSsNQFIa/E7rY3VVw8AG0zeaQzabg6Giqg63gKKKPIL6Cglid7G7ara41' b'qIgO7eTu4GChGWyOgzgIprkpzSDkW+//3+8eOBdycspV76S0Xi9O27cSE8qBjMPnlcrmWjaC' b'b8miJdK2q7XrZXd7fvaCH4/qRoFx33ZrdUBMOomhsutpjK5riTR6N83BpH6qCX4jTqQ8llzv' b'0HGcQgYCAOYEjj+KC4Fd2bKzEAAgypKiq3+dxY6Wgls0agTtq/5MBQLvIEd3/sUpELMIUwpE' b'pPWp1t6Df/6WlE0lUHhV1d17v9kx7ZgKItCzcBTuv3RbwzSPMhE8EbETdC57aS42ZtInyvkf' b'fAFjgU5Rd7miLwAAAABJRU5ErkJggg==') index.append('PLAY_24') catalog['PLAY_24'] = PLAY_24 #---------------------------------------------------------------------- PLAY_PAUSE_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AADMSURBVDiN3Y47DgFhFIXP/b06pc4mjAmtzvzqqcg/RGIBNkAsRDGhGbVHpyXsQqfUkXBU' b'kzCIoeNU99zHdw/wP7JqpvKsX3CaZVt7gaVNFwBs7QW29oJwrsJCLljYVdOIAoTnPElXQcoA' b'QNIl6T4AAKQp8Iva9D9JriJeQPSKjhlaVif1DSBUS3LHacmpZ78FxNYrwJD7TG09Hx/eAZIR' b'TwgG25nfj5vgFnASor2Z+6O4x3cAKlS3U38ZXaAkdko4uYArABCRyScPfkBX/1A7r5UA2DMA' b'AAAASUVORK5CYII=') index.append('PLAY_PAUSE_16') catalog['PLAY_PAUSE_16'] = PLAY_PAUSE_16 #---------------------------------------------------------------------- PLAY_PAUSE_d_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAfklEQVR42mNkoBAwDh4DJk2a' b'5JiXl7cfXQFQ3AJIFQHxCaB8H5C/CiQOZIehG/ATSCUDJZagGRAKpECaVoM0Afn/oQYwohsA' b'kgDhJqBkA7kGwMD8////p+fn5/8m1wAQ2A3EIUDsPiAGzAN6IYMcL1AUiBRHI2UJiVww8AYA' b'ADGljhFAyvuxAAAAAElFTkSuQmCC') index.append('PLAY_PAUSE_d_16') catalog['PLAY_PAUSE_d_16'] = PLAY_PAUSE_d_16 #---------------------------------------------------------------------- ARROW_UP_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAB6SURBVDiNY2AY1EA7NJRNOzSUDZ8aJnyaOb9wrub8zLHRwSGBA5c6RnyaGRgY/BgYGBgY' b'/v/fwfODOfDAgQU/CBqAoRkGcBjCSJRmPIYwEq0ZhyFYw4CBgYHBxDPuPzL/zPZFWNXijAVi' b'wTAwgAWXxP///8MoNZw+AAB5qTZGwoz1IgAAAABJRU5ErkJggg==') index.append('ARROW_UP_16') catalog['ARROW_UP_16'] = ARROW_UP_16 #---------------------------------------------------------------------- ARROW_UP_D_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAZUlEQVR42mNkoBAw0tSAiRMn' b'soHo/Pz8XyQbANLMyMi4GsgEGRKYl5f3g2gDkDT7QYV24DKEkQjNDPgMYSRSM05DGEnQjNUQ' b'nIE4adKk/8h8oAasakcNwG9AKJoBq0kygFhAsQEAvBQ5EU8K8roAAAAASUVORK5CYII=') index.append('ARROW_UP_D_16') catalog['ARROW_UP_D_16'] = ARROW_UP_D_16 #---------------------------------------------------------------------- ARROW_DOWN_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AACISURBVDiNY2AYaMCIS8LYIzYUmX92x+LV2NSx4DSZkXEVMZYx4XEdUWAYGAAPGO3QUDbO' b'z5yrGBgZ/Ano2c7znSnowIEFPxgYGBiYYaKvr137K2ioto71J6seAyODBjGaUQwgwhAMzRgG' b'4DEEq2YGBjwpESlM2HBpJgi0Q0PZtEND2UjWSFcAAA/vNvugThMHAAAAAElFTkSuQmCC') index.append('ARROW_DOWN_16') catalog['ARROW_DOWN_16'] = ARROW_DOWN_16 #---------------------------------------------------------------------- ARROW_DOWN_D_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAaUlEQVR42mNkoBAw0syASZMm' b'hSLz8/LyVpNqwH80AxhHDSBgwMSJE9kYGRlXAZn+DPjBdiAOAhr4A8MFRBiCohmrF/AYgqEZ' b'ZxhgMQSrZryBiGQIGy7NeA2AGQKi8/Pzf+FSQ7vMRCwAAFJWORHb+TzcAAAAAElFTkSuQmCC') index.append('ARROW_DOWN_D_16') catalog['ARROW_DOWN_D_16'] = ARROW_DOWN_D_16 #---------------------------------------------------------------------- REMOVE_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAEHSURBVDiNxZCxTgJBFEXP3R1JNGG/QPwFC6OJDYU2W9FZqpWtifZW9P4AaKEFiZQ0/IGJ' b'yRb6CcZGExpKdOZZIGSzLAIVt5r35sx99w2sW8oXB+nZoce2BQnSLZD8XQ0xuzYYxujjpf/w' b'PHnj8gYW6UrGScmgBKktwKQuMDVQkdxLT8sMpsr6j9187YqApKf/DIpDowXwQs0x0GcIoQ68' b'mXgNIdQFX2XkzApjWTVWXAludAwQh8quYdUVErBlsmbW6wyyXmdgsiawuUIC3s19N/bT8yOA' b'4EYN/WxkwM6yBrXIuxuTXQBE3rUMassm8EBspstJI3f2RXjmDwzuy8Bxz+7mJF6jfgEfLE/B' b'MgWxkwAAAABJRU5ErkJggg==') index.append('REMOVE_16') catalog['REMOVE_16'] = REMOVE_16 #---------------------------------------------------------------------- REMOVE_D_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAw0lEQVR42mNkoBAwUtWASZMm' b'WQIpGSDmA+I+KA0Cn4C4CEo/ycvLO47LgFVAKpSApauBBoTh9ALQELwGADWvxhsGQAP+EzCA' b'kS4GvPz//38oIyPjFCAbyPyfC2SvAbLFiDXgGxD7AfFFqLA+EG8GYk5SvHD83bt31iCGkJDQ' b'USBlSYoXHgGxMdRmBqhLzgKxHLEGgPBkIE6FCs8G4lyQemIM+AOkmHFEwl+gASyEDJgFpJKw' b'GPIXiOcCDUjHawCpgGIDAPaBUBFQre+bAAAAAElFTkSuQmCC') index.append('REMOVE_D_16') catalog['REMOVE_D_16'] = REMOVE_D_16 #---------------------------------------------------------------------- VIDEO_FORMAT_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AACSSURBVDiNY2AYBYwwholX3D2G/wyKeNT+YvrP4HBqx6LjZh5xlqd2LDrOwMDAwASXxq+Z' b'gYGBge0vw38ZM484y3+MDDtggkz4dGA6l9ECqpkPJsZCigEMjAxF6EIkuQAbINELDJ2MDAzv' b'yTbg3///Z/8yMboiG4IwgJHhPgH9v5gZGJ+c27rwLON/Bm9SLB7uAAAucyMEvcgZegAAAABJ' b'RU5ErkJggg==') index.append('VIDEO_FORMAT_16') catalog['VIDEO_FORMAT_16'] = VIDEO_FORMAT_16 #---------------------------------------------------------------------- VIDEO_FORMAT_32 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAASdAAAEnQB3mYfeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AADhSURBVFiF7ZI9CsJAEEbfupbiaQS9gSZgLyjowcRCCdY2Ri1tRLDyKP40wjpWYoiRFZIl' b'oPvKYWa+x86Cx+P5d1S60AiHY0RGgM6x94JicFhOF8liM+jX93F0StYqb6P5wwFqiOqlww16' b'lW6sZgznDQdAqdeeZtCv39FroJXue3+BgnmGS0a4cwFbOGSfoBhEnjf/GO5UQKD9TZ/zP+AF' b'yhSIgW1pAkqpy81IaJNweoLjZna1STj/AzaJLAFTRLDIa89xM7tqTBfYWQUEJgVInBHmycI+' b'jk4a08m51+Px/CAP3CJJ5X55UlcAAAAASUVORK5CYII=') index.append('VIDEO_FORMAT_32') catalog['VIDEO_FORMAT_32'] = VIDEO_FORMAT_32 #---------------------------------------------------------------------- ALERT_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAE6SURBVDiNtZC9SgNBFIW/2WxMtjEIAUsJQkRCLIxE7GKRRQykcgWFqI0oVuoTaK9E8RXE' b'wl4tBFsbu3RBwQcQVNYmqHMtsob8TFYscstzzznz3YFBTt6tpPJuJRXmscOW2lZHiAiw1M+j' b'+i1ypbV5pblrurT7cH1+a/JZJtHzvIjSnLQEsaqFQsFIayx49p0tYKpNyvjO2KbJ23NCtrQ6' b'EtN2HUgC94E8B7w0rK907eriNZQgpu3DIIyIVEWkGqyScYkchJ4wXapMAtsm1Gah2sktbmTb' b'tY6PsbR1ChJt3afUXleHrUSOAbeHYGZhvQxS7Pd6G0ex6Q0eAch43pDz4dSAdCeyLAckl10t' b'T28kMo83Zw0LIO47+93h36AhDDCe4H0XQM2WV0a/P6N1YPhv/I7xReuJf2YGMD+zk1NTit/4' b'+AAAAABJRU5ErkJggg==') index.append('ALERT_16') catalog['ALERT_16'] = ALERT_16 #---------------------------------------------------------------------- PROPERTIES_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAGASURBVDiNpZO9SwNBEMV/szmxCNjY2GmRwj4X1BBBG7lYqJhSPIOdhZXgf2FlYSGInFgq' b'Vl46BRG/zl6wSWljI1gELjsWnmeiFxGdandn3rx5jx34Z0ivRLHqrxuRSQCrenEfBttZdU7v' b'zrqsSglAhGEgs0E6wbhXH4mlvYbqnkVGjMgRkE/Sr1a1ZtAmIquO5nauG/vNrgliY7dQWURk' b'03wnyhuRxgdfbGwBqKUTuF59CrFnX0AWuErOZb76pWY6auyfGwC1PCk8doKtMB+FQSUKgwoq' b'C4CmWHhUy1OXB2PVpYE2uedE1mUUBpVOQtfzLxHKQJyjPXgTHr4ApHJb/X0Z0rOjs9YAFGfq' b'o07L3vFpatn1VuZS9ll/HmEiuTpOy94VZ+qjfADEMAQUOkgE0RPX868S0RN0m1hIMA/pozvr' b'H6Es/kqDcBydBrV0AgDHmo1Y7ANqg58/kvEda3Y/e/UIt7p8C1JKqm6j02Asq67nLihyYESa' b'8L5Mv5L2l3gDAC2ETODWK80AAAAASUVORK5CYII=') index.append('PROPERTIES_16') catalog['PROPERTIES_16'] = PROPERTIES_16 #---------------------------------------------------------------------- EXIT_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAEZSURBVDiNxZK/SsNgFMV/1/gIHX0Fp6SYR0gCnUShSJJBnAtdnISKi4OLD1DFiBR0LDR5' b'hEqTzUdwkj6Ag+F2kITYJK2Tnun+Pfccvg/+G1IElhuMgRAwtuzkotwvkugMYLfSCFFuFZ1v' b'vii2CgOgRmAoOs+Sx5eicOCe7L3GT+9VAtPxEWRY5Dttl8xev5NjvFleMNqkqCRI40iq17Pp' b'ZAkMUS66bnDdRlBa6Hrhc9OAqn4onFte8JnOopqaVgu/RalgMXs4Xm9ajn+KyCHKKI2jyyaC' b'UoHlBmo6/lGRm71+B5EbhKs0aV7+QbCObDpZGuT7Tb4bLQC5ILbp+GXhS7/fvQpBbCCvESjc' b'iTCofpIW5KDjLTN/iBX3XlWagRr2qAAAAABJRU5ErkJggg==') index.append('EXIT_16') catalog['EXIT_16'] = EXIT_16 #---------------------------------------------------------------------- HELP_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAGHSURBVDiNrZIxa1RREIW/M/cZQYP5AbZGNIqiIW5lIaRZBGMpLpYGIgEL/0fQQtMIissq' b'qdTAotglWGjhFkngKfoTrGKxW+y9Y5F969vdFxs93Zw5c+6Zy8A/QlVkrd6YS8qWEpwGIPk3' b'D/62027mfzWYX1ye0VRvHedWhbk7/jIj3fv8rrU/YTC/uDyjI72PwPkBteuupwCS3y3xO4F4' b'tTCxodNUb708PN21K2baDh63pru2AOwNeheiwuORBLV6Yy4S9oraXfeDx61k1jn4Ai4F45o7' b'D4t1kvm5TruZZwCRcLO8juSPkobh0sGEDPkfSdQSkBeqUxwCoRWP2U+XPxjhxSxAdtjgABvH' b'u3rx61j/k5yTVYIiwY/K193f7x/tL8i5ON5z5/vQIJm/BnxCJD0zs+0K70SyN0ODTruZC15N' b'yJw1nLUKvvXlw/Ov5RUw4gqwW7XKGHaC4mpRjJxrrd440ceeCN0e7wEJpxUUVytPuYzL1++c' b'VdINpDMA8pR7DJtF7P+K37sKku4pcjReAAAAAElFTkSuQmCC') index.append('HELP_16') catalog['HELP_16'] = HELP_16 #---------------------------------------------------------------------- ABOUT_16 = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'AAFHSURBVDiNpZK/S8JBGMY/7/fM1T+g2lLKkiAHEWprkSCbIpBWQehvcQuHlsIkaCkCiZqD' b'ctDBAqPcW5qcXO7eFn93GuEDt9zd83mf972DOSW+zVQmF3cSyjqIAQTwYcXdNqrl1kxAcjcf' b'kXC3hHLkgavAVYAt1O4rnV+A5G4+IgvdJ2Djj9SvBrvdhwQDUrhb8pife2tUCSvmdCxBKpOL' b'W8zbZGxVPQQQkevJdlyg641quRUCsJgDT88+4/DIShZo9VtY8V5TiihFP4EoQGhKhZ5fXwDE' b'99oiCsMhtmeBvHCn7QHABXoD6D/8DhfcAhiAr8/m92J0MwYkxlPKkoikgeXx8lzWHy7OYGQG' b'AbZgMYkJSNpTvWnEngx9PdXuKx2D3Va0MqUdh1I22B3vVx7V1t7xmjjZR2QVQNS11Jq7+uP5' b'u+/+XPoBXM1s1TkhatwAAAAASUVORK5CYII=') index.append('ABOUT_16') catalog['ABOUT_16'] = ABOUT_16 #---------------------------------------------------------------------- FILMSTRIP = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAAZcAAAHtCAYAAADV3zOqAAAABGdBTUEAALGPC/xhBQAAAAlw' b'SFlzAAAOwgAADsIBFShKgAAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMK0KCsAA' b'AG6USURBVHhe7b0HcBzXveZLCyBAkcrBkrPX9r22ZUu+PPvuq9p617W7b2u3dvfV7toKlkSJ' b'CpYokZREKlCJpJhzzhSzSDHnTIpJzDmJOYM555z1+jucf/s/zTMAiOlpzAy+r+pXAE7o7mkA' b'/69P6HPKURRFURRFURRFURRFUUXoB7GvkP6eoiiKokokaya5ubkV/6//5xUD8vPzH7A5NBqK' b'oiiqpMrLy3tYjEXIycm5N5ZNg6EoiqKKJTGMHwRNReOZzt1SLvaVoiiKopyyRlGxYsU8l6EE' b'QTlbiwZDURRFJZA1iJycnPtcRpIIr0ou6lEURVGUU7m5uY+5DKQovKpsuVAURVG+xBTucpnG' b'nRA7Dk2GoiiqjMsaAQbmXWZREuxRaTAURVFlW56xPOgyiWSIHZoGQ1EUVYbkB32XMYRBbm7u' b'o7FT0GAoiqLKgCTYl3eZQpjk5+c/GDsXDYaiKCqLZYN8+fLl73GZQSrgW/wURVFlQOiucplA' b'KuFb/BRFUdknCeiFLuOSavgWP0VRVPbIBvIKFSrkuwJ+1HiXkoProSiKojJX1lhycnLudwX6' b'0kKui6Ioisos+cHbFdzTgdjl0WQoiqIyRBKwc1xBPZ2IXScNhqIoKs1lA3VeXp6/W2S6Y6+a' b'BkNRFJXe8ozlIVcQT1dyc3MfiV06DYaiKCqN5AdlV/DOBLgXP0VRVHrJBuNKlSqlfBmXVOO1' b'YO6xn4gGQ1EUVaqyQRhLq7iCdSai3uKnKIqiSkve0/4PXUE6k8HHuvXpKIqiqKgkXUZJ7xaZ' b'zsQ+I7vHKIqiIpANtvn5+RVcATmb8D5meXxWiqIoKgJhVpUrGGcjsY/M1gtFUVQK5AdXVwDO' b'ZmIfm6IoigpZYiy5ruCb7cQ+O0VRFBWirLHk5uZWcgXesoC9C+wWoyiKCld5eXmPuIJuWeCB' b'f/pFpdhtoLlQFEUlowEDBkggLdXdIkubu3/24wdj94GiKIpKRseOHRNjyXMF3LLCvb/4EffZ' b'pyiKCkOLFi2ygfT111+/zxVwywo/fOQR2f6YxkJRFFVSLV261A+iR44ff/zGzZtm2/btplPn' b'zpVdwTdbuedXv3g8dhsgGgtFUVRJtXfvXhtEu3frlnP2woV/9/3335sTJ0+aCxcvGnwPjhw7' b'ZoYOG2aeeeYZZ1DOBu755S/vszeEpkJRFJWcPOOwgXT1hg13nz179vcwkoOHDlX2wFezd98+' b'c+DgQXPm7FnfaGA6M2fOMjVq1HAG6Uzk4X/6pzx7Q2gsFEVR4WjHjt0PeYbxL5cuXzb7Dx6s' b'fOjwYXP4yJE4YDT79u+3HD9xwjcasGr1atOwUSNn0M4EvFsghkJjoSiKKqk8Q/CD6JEjR34C' b'g0A3mNdCqRw0FRdiNGjVHDl61Fy5etU3ml0FBaZHjx7OIJ5u3PPrX8qWxhRFUVQyEmOZOmVB' b'+XMXzv8GhuC1VCqj68tlJMUBdWE0aPHocRq0cEaNGm1eeOEFZ3AvTR74zW/4YiRFUVQYEmNZ' b'v37dPecvnP8jZoRhfMXVDVZSYDRo1ew/cMCcPnPGNxp0uX07d66pVauWM9hHyf1P/Uk2AKOx' b'UBRFhaG9ew8+evHSpcrnL1wodjdYSQmO08DMxGzWrVtnmjVv7gz+qSR2GyAaC0VRVElVUFBg' b'g2j16tXvOnfu3C8Q2I8eO2ZbGC5DSBWFjdPs2bvX9OnTx2kGYVHpn375gL0hFEVRVHLyArc1' b'lsWLFuWfvXDhdwjkGF9BoHcZQJTIOA2+njt/3jeaU6dOmfETJpiqVas6TaIk3PfH31SwN4St' b'FYqiqHC0defO+y9euvTU1WvXMA4S6vhKWEirBuM0Jz1zEaNB62bhokXmozp1nKZRHH75n/7T' b'XbFbQWOhKIpKQn4QPXf27I88YzHHjh9H8E7p+EpY6HEaXLcep9m4cbNp06aN00SClP/x4z+M' b'3QaKoigqSVljqVSpUu70mTN/LUH56vXrdkBdgnY6dIsVB1wnWjMyzRkzzuQzoTutX79+TmPJ' b'+eVP77V3g60ViqKopGUDaW5ubkUdaGvWqGFmzZpl0IKRwIwpwhK0ox7YTwY9TqO7z+rWresv' b'rlnpiZ+Xt3eDxkJRFBWO8vLyHtbGEuTZZ581w4YNs4tQSmDGS49oFWSS0eBa0V125ty5uBWb' b'Y7cBorFQFEUlIQmiJdotsmuXLmb7jh2+0Vy7ft1OE0bwTsfuM1wPDBDXum79et9Y8h955KHY' b'faAoiqKSlDWWihUrhrJbZL369c2yFSvMzZjRAHQ9pcs4DUxFFszsP2CAbyyP/eafKtq7wdYK' b'RVFU0rKBNCcnJyW7RVar9paZNn26Oa/ePzl77lzcmIfLAFIFzO1ybDD/jb//3b/O3/7137hb' b'JEVRVJjKzc19TBtCKhk0eLAdlxGjwawtPU6TylYNjAXnPHL8OMdXKIqiUiAJonfpIBs17Tp0' b'MFu2bvWNBuM0WE4m7HEaHEcM7dt583xjue+hh+6P3QeaCkVRVJKygTQvL+9uHehLm08++8ws' b'WbLEXL9xwzebMMZp9IrKLVu3/sf4yq9+lW/vBo2FoigqHHnG8qAO7OnGa6+9ZiZPmhS3zP7Z' b'8+fveJwGpgSzunbzetzxq1atKoZCY6EoikpCfhDVQTZTGDBggG2BiNHocRqkB1s1+FnK7ywo' b'8FsrFSpUeDR2GyiKoqgkJcZSXgfsTKVV69Zmw8aNvtHgBcjYemc+GLdB3sixY31jefjhh++J' b'3Qe2ViiKopLRhg0bbCDNzc29RwfobOHDDz4w8xcsMFeuXfuH2cTGbD6sU8c3lieeeILLuFAU' b'RYWpnJycR3VAzlaqVKliJk6caA4fO+abCojdBojGQlEUVVLt37/fBtH+tfuXaBmXbMEz1Qft' b'DaEoiqKS0/ex3SLnzZ+bf/Xatd9eu3HdzJ07t3Lt2rWdAThbuffee++2N4StFYqiqHC0adOm' b'+89fuPAUXkg8cfJkZb1B1rr1603zFi2cATlb+MlPfsLdIimKopLVokWL/CB68ODBxzG4jfdD' b'Dhw8aLchxuwpTNnFCsXY6leMZs/evaZP377OAJ2JeB//sVt3wYrGQlEUVVJJN1ifPn1yzp0/' b'/yuYBkwk0dvs+iVEr7xvNKdOnzYTJkw0r7ziDtzpjncL7sN98ERToSiKSkZiLMuWLat47sKF' b'J2ASnqlULu4yKSiHVg1eNtQ7MaI7zWsNmToff+wM5OmGdwvycB880VgoiqLCUEFBwUMXL136' b'F7yx7pmE7QZzGUlRiNGgVYMXEvX6Xhs3bzZt2rZ1BvbSxrsFYig0FoqiqJLKC/Z+MD169OhP' b'Efyx6VVx19oqDjAatGZgNDArGJcYDc7z1cCBzkAfJd7nf/jWbaAoiqKSkhjL1ClTyp+7ePGf' b'EOy94F85TGNxocdpsMmXGM057/spU6eaN95802kAqcK7BdwtkqIoKgyJsazbvPne8xcuPonp' b'xRhfKWk3WEmR7jOgx2lwPUuXLTOf163rNISw8G5BLu6DJxoLRVFUGDpw4MAPL12+XBmzvLxW' b'RGVX8I8SPU6DhSIxEUDMZuu2baZTp05OgygpsdsA0VgoiqJKqj//+c82iNaoUeOus2fP/hJB' b'G9OMU90NVlL0OM2Fixd9o0HekCFDzNPPPOM0jaLwboHsFklRFEUlo//+3/+7NRYvOFc4efr0' b'79DthNlgaC0Eg3o6osdpzpw96xsNTGfGjBmmevXqTiMJ4t0C7hZJURQVpv6///N/Hjh69Oif' b'YoG58sVLl/wNshC0M8Vo9DgNZraJ0YBVq1aZz+vVS2QsXMaFoigqBPlBNBho27Vrb7Zs2eoH' b'ZYxv4H0UGA2CdqYZDa778NGjBoaJz3PpyhV/mfy7uFskRVFUaBJjydWm4uLjTz4xi5csMVfV' b'ADpmbknrIBOMBi0vjB/h2keMGuUbS05+Be4WSVEUFZJsIM3Nza2kTaQ4vPrqq3aDrNNqXCM2' b'm8zvPnMF99IEBnghtq7ZJ5995hvLAz+9n7tFUhRFham8vLxHtGmUlP79+tlZW2I0eLseLQQY' b'DdJLu1WD68B1nb94kbtFUhRFpUASRFO2W2SLli3N+g0bfKPBjDOM05RG9xnOhVYUrmPV2rW+' b'sVR66CHuFklRFBWSrLFUqFAhT5tBKnn//Q/M/PnzzdUrV3yzwZ4vaM2k2mhwDnmbv1ffvr6x' b'PPSLX3C3SIqiqJBkA2lOTs59OvhHyYtVqpix48bFLd+SqnEaGNflmKFVfe01/xqe+q//Ncfe' b'DRoLRVFUUvKDaG5u7uM62Jc2PXv1Mrv37PGNBrtVyjhNMq0aGfs5dOTIP2aDVarA3SIpiqJC' b'kgTRHB3U05HGTZuaNd995xvNTQ+8+Hgn4zTS8kH9mbNn+cZy/+MPcbdIiqKokGQDaV5e3t06' b'iGcC77zzjpk9e7a5dOkf+7nIOE2i7jPkyXIvTZo3843lR7/+NXeLpCiKClOesTykg3Ym8uxz' b'z5kRw0fa2WZiNFgnTJajkYkBmJF27dq1uLrNmjUTQ6GxUBRFlVSbN2/2g6gOstlE127dzM5d' b'u3yjueoZCr5u3b7db63cff/9j8RuA0VRFJWMDh8+LMZSXgfjbKZuvXpmy9atZvTYsb6xPPrj' b'H1eK3Qe2ViiKopLRokWLbCBt2LDhPTr4ljV+/tRT3C2SoigqTB08evTRm99/X/ng4cNm0KCv' b'/Sf5skLsNkA0FoqiqJKqoKDABtHq1avfdf7cuV9g3AGD3mfPnfPHI/CC4tSpU82bb77pDMjZ' b'QLm8/AfsDaEoiqKSk2cc1lgWL1qUf+bs2d/BSA4dPmx3iwTyboh+Ex6zqZYvW2bq1q3rDNKZ' b'SLn8/Ar2hrC1QlEUFY527Nhx/4WLF5/CbKn9Bw5UxtTc4LsfYjSYsnv02DG70ZeYzbbt202n' b'Tp2cQTsT8G4Bd4ukKIpKVgsXLvSD6JEjR34Eo8CLhQcOHqwcNJVEyEuIMCK8KyJGA+MZMnSo' b'eeaZZ5yBPJ0ol5/7w9htoCiKopKRZwDWWKZMmZJ7/tyFX8MQYBDJLPSIuvK2u97wC6YzY+ZM' b'U6NGDWdwL03KVci5194QtlYoiqKSkxjL6tWrK547f/4PMICDhw7Z8RWXaZQEPU6D9bzEaMCq' b'1atNw4YNncE+SspVqsTdIimKosLUnj17Hr546dK/eNxRN1hJ0OM0WKEYKxWL0ewqKDDdu3d3' b'Bv9UErsNEI2FoiiqpPICuQTRHxw5duxnCOxoUSTTDVZSdPeZHqfB9YwaNcq88MILTkMIg3Ll' b'8x6K3QeKoigqGYmxzFq6NM9rqfwzAjmmGZeGsQTBNaBVg4kBmEwgRnP58lXz7dy5platWk6T' b'KAnl8vIq2hvC1gpFUVRyqlq1qg2kW7duve/8+fNPXr9xw46vuKYZlzbBcRq8RyNms27dOqxI' b'7DSN4uDdAu4WSVEUFYL8IHrq3LnHsC/JiZMnEbhTOr4SFoWN0+zZu9f07t3HaSIuYrcBorFQ' b'FEUlIRtEH3rooZwhQ4b8UoIykA2yELgRwF2BPR3R4zRYgkY+zynv84wZO9a8+orDVPJz7rd3' b'g6ZCURSVtGwgLV++fNxukc8//7wZPWaMbb1IYD5/4UJc0HYF9XREWjUHPPCypnyejl26+Itr' b'lqtQId/eDRoLRVFUOMrLy3tQG4uLHj17moLdu/3AjG4ndD/BaDKlVbPXu07sFHnpypW4z+bd' b'AjEUGgtFUVQS8oOoDrLFpVHjxmbtmjW+0dz0wIA6TCYdjQbXg649XOv2Xbv81kr5SpW4WyRF' b'UVRIEmMJZbfImjVrmlmzZhu8XClmI+M06dB9hvNLV9jI0aN9Y3n48ce5WyRFUVRIsoG0fPny' b'Kdkt8tlnnzXDhg+3e7qI0eClR0xjLg2jQStKXrp8/6OPfGP52R/+wN0iKYqiwlRubu6j2hBS' b'SecuXcz2HTt8o8EqylGN0+AcOOeZ8+fjdsSM3QaIxkJRFJWEJIj+QAfZqKlXr75ZsXKlHZ8R' b's4m9RxOq0eA4AMdftnKlbyyVHnrowdh9oCiKopKUNZYKFSrk60Bf2lSrVs1Mmz7dTm0Wo8HW' b'yMlOc8Y4j+x82a1nj3+Mr/zqx9wtkqIoKkzl5+ffrwN7OjJo0CA7LiNGc+ny5bhxmuK0atD6' b'wY6YqP/iyy/5x/6///pX7hZJURQVgvwgqgN4ptCuQwezZetW32gwToPZXoWN08g0430HD/qt' b'ldx7Kj4Wuw0QjYWiKCoJSRDN0QE7U/nkk0/M4iVLDBbPFLNBt5eM0+zzTAXmgvSp06f7xvLA' b'jx7hbpEURVFhqG/fvjaQ5uXlVdQBOlt47bXXzMRJk+zYjBiNrILcoFEj31h++pvf5NkbQmOh' b'KIoKTQ/pgJzN9B8wwBz0Wi46rdbOnWIoNBaKoqiSyntqt0H0/3jB9L/8t//2Ux1oyxI59979' b'sL0hFEVRVHISY5kzb175Kzdu/BO6h1atXl25YaNGzgCcrVR67EHuFklRFBWGxFg2bdp077nz' b'55/E2MOx48cr6w2ysIJx9x49nAE5W3jowQe5jAtFUVSYOnDo0A+xWCQ2wtp/4IDdhlgvFqlf' b'UMSb8KNGjzYvvPiiM0hnIrHbANFYKIqiSqqCggIbRGvWrHnX2fPn7W6RWKcr0dvsB710TNeF' b'4WCVYjGay1eumLnz5platWs7g3a6Uy4/X3aLpCiKopKRZwrWWFauXFnhwoULv4NJeC2VysVd' b'jwvl5N0Q7LsiU3jBuvXrTfPmzZ2BPN3AcgP2hrC1QlEUFY62FxQ8cOHixT9dvnrV7wZzGUlR' b'wGj2eyaD7jO0fPQ4DXZq7NO3rzOwlzbeLeAyLhRFUclq+bJlfhA9dOTIj2/cuGlOnT6NbrDK' b'LtMoKehWk3EajN+I0eBc4ydMMFVfdgf7qCiXm/to7DZQFEVRycgL7tZYBk+ZknvxwoVfI9ij' b'pZJofCUspPsM4zSyujDA+l6LFi0yderUcRpAqvCM5R57Q9haoSiKSk5iLOvWrat07ty5PyC4' b'e0G/2OMrYSFGg1YNdpa8ptb32rh5k2nTpq3TEMKi3D33lLc3hMZCURQVjnbvLnjk4qVLlTHV' b'GMZS0vGVsIDRHIhNc8a1YEl8MRrMSvtq4ECnQZSU2G2AaCwURVEl1Z///GcJoj84euLEzxC0' b'0VpIdTdYSdHjNHohSYzZTJk61bz+xhtO0yiKcuXzuFskRVFUGPqf//N/WmPxgnPe6TNnfosg' b'jdlg6WosQaT7DOhxGkx3Xrpsmfn888+dRhKkXF7e3faGsLVCURSVnN59910bSP/9v//3923b' b'vv3JWGCujB0Vi9ogKx3R4zS4fkwEELPxPp9p29Y9TuPdghzcB080FoqiqCTkB9G77rrrcR1o' b'69arZ5atWGFuxoIy0BtkZYrRAOk+wziN6j7z914pf/fd3C2SoigqJEkQLXK3yDffrGamTpsW' b't04YgrQe83AF9XQC1whzwbVPnjbVN5YfVKx4X+w+0FQoiqKSlA2keXl5d2sTKS4DBw6yLRcx' b'GszaQuC2RnPgQNq1avC+zJmzZ+21NmnWzDeW+3/0I+4WSVEUFaY8Ywllt8h27dqZzVu2+EaD' b'8Q3MMEuXcZq9+/fZQX0sL6Ovu3mzZmIoNBaKoqgk5AdRHWTD5ONPPjGLFy82V9UAemmN0+Bc' b'6ArDNWzdts1vrdx9//2PxG4DRVEUlaTEWMprM0glr776qpkwcWLcMvt4/ySKcRocG7PEcM4h' b'w4b5xvLoj39cKXYf2FqhKIpKUjaQli9f/h4d/KOmb79+duxDjEaP0yA9rFYNWkgXL16y53in' b'Vi3fWH75L//C3SIpiqLCVG5u7qM60Jc2LVq0NOs3bPCNJrY9ctLdZ3sP7LPHO3X6tG8qIHYb' b'IBoLRVFUEpIgepcOsunI+x98YObNn2/wwqaYDbrS0JoprtGgzKFDt6YZL1q61DeWex555IHY' b'faAoiqKSlDWWfE86iGcCVapUMWPGjDEnT570jQbv1hQ2TgMTwp4vKNuxS9d/jK/87GcV7N1g' b'a4WiKCoceb7ygA7amUrPXr1Mwe7dvtFgOjF2rZRxGrRsrsVaPM8+/ze/3v/7n/8zd4ukKIpK' b'Vps3b/aDqA7O2UTjpk3Nmu++843memz//d179/qtldx7Kv4wdhsoiqKoZHTw4EExllwdjLOZ' b'mjVrmqVLl5op30z3jeXBnzx6b+w+sLVCURSVjHbv3m0DaY8ePSrp4FvWePDnP+dukRRFUWHK' b'a7k8/P333/8L1s6aNGlS5VdeedUZgLOV2G2AaCwURVEllWckEkR/cDy2W6T3NW6DLKzvtWjx' b'YvPxxx87A3I2UK58+Ydi94GiKIpKRmIsc+bMybt46dI/w0gOHT5sd4vEux6YPYWZVHghUW+Q' b'hYUlE22QlYmUy8uraG8IWysURVHJSYxl69at952/dOnJ6zdumIMHDlTGEirBdz9gNPJuCPKx' b'1IoYDfKwZL4raGcC3i3gbpEURVHJaunSpX4Q3Xfw4GMwirNnz8I8KgdNJRH6JUS1E6NdSBKb' b'gL3x5pvOQJ5OlMvPfTx2GyAaC0VRVEm1d+9eG0TbtGmTc+7s+X8HQzhy7JjzTfXiIt1nQI/T' b'YH2v5StWmLp16zqDe2lSLj//fntDaCoURVHJyQv4NpAuX7fubq+F8XsYgGcMlWEOLtMoCWI0' b'aNVgiXo9TrNt+3bTqXNnZ7CPknIVKuTbG0JjoSiKCkcFBQUPXrh48U9XrlzBcifO8ZUwwZIq' b'Mk7jndc3miNe3tChQ83TzzzjNIBU4d0CMRQaC0VRVEnlBXI/iB4+evQnN73AfuLkyTsaXwkL' b'PU4j+88DmM7MWbNMjRo1nIYQBuVyc7lbJEVRVBgSY5k5c0b5ixcv/gaBXKYZu4J/lOhxGrxT' b'I0YDVq1ebRo2bOg0iZJQLrc8d4ukKIoKQ1WrVrWBdO3aTfecv3Dhjze8oB32+EpY6HEarFCM' b'lYrFaHYVFJjuPXo4TaM4lLuvHHeLpCiKClMXL19+9MzZs5Uxg8sL3pF3g5UU6T4LjtOghTNq' b'9GjzwgsvOI0kSOw2QDQWiqKoJGSD6O9///sftG3b9ucSlAHeP9FjHq6gno7gWtGqwcQA7CYp' b'nwfv5syeM8fUql37dlPJz3/Q3g2KoigqaVljce0W2bdvXxugdWDWG2SlY1eZCz1Og5/l8wwe' b'PtRfJr9c+fLcLZKiKCpM5eTk3K9NxUXzFi3MuvXr/cCMFx2xbpgE7UwwGlzn5StXDMaRnn7u' b'Of+zlfvxT7hbJEVRVAjyg6g2kOLy/vvvm7nz5tlALWaDrifZ7jcdjQbXhuvcf/DgP3aLrFjx' b'sdhtgGgsFEVRSUiCaI42jJLyYpUqZvSYMfYdGDGa8xcupM04jT3/0aP2uqZO/8dukQ/86BHu' b'FklRFBWSbCDNy8urqA0iTL7s1csU7N7tGw2mB8s4TdStGrRW5KXLLxo29I3l57/9bZ69GzQW' b'iqKocOQZy8PaDFJJ48aNzeo1a3yjwVv+mBYcxTjNXu/4OCcmIehr+uvgwWIoNBaKoqgk5AdT' b'HWSjpuY775hZs2ebi5cu+WYj4zRhdp/BsHAsHH/Tpk1+a+Xu++9/OHYfKIqiqCRljaVixYp5' b'OtCXNs8995wZMXy4ORYbCwF46REvPyZjNKgnS8J8NXiQbyyP/exn3C2SoigqJNlAmpOTc68O' b'7OlI1y5dzPYdO3yjwXL7dzpOg3KXYq2iajXe9o/963/9Vy7jQlEUFaZyc3N/qIN4JvBF/fpm' b'xcqVdnxGzOb4qZOFjtPsi00zPn7ypN9aAbHbANFYKIqikpAE0bt0kM1UqlWrZr6ZPt1ObRaj' b'OXPunO3+ErM55JkN0uctWOAby32PPiq7RVIURVFJyhpLfn5+BR2gs4nBgwfbcRkxmps3b9qv' b'7Tp28I3lh7/4BXeLpCiKClOesTygg3E2075dO7us/jNqpeO//vWvXMaFoigqBPlBVAfessYP' b'8vMfjd0GiqIoKkmJseS6Am5ZoeIj998Tuw9srVAURSUpG0jLly9fyRVwywrl7rmnvL0bNBaK' b'oqhwlJub+4gr4JYVYrcBorFQFEUlIQmipbqMS2lTrvxd3C2SoigqJFljqVChwm27RZYlyuXl' b'3W3vBlsrFEVRScsG0uLsFpnN4BbgPniisVAURSUhP4jm5uY+7gq4ZQHvw3O3SIqiqJAkQTSU' b'3SIzFa+5dl/sPtBUKIqikpQNpHl5eXe7Am5ZAbcA98ETjYWiKCoMecbykCvglhW8WyCGQmOh' b'KIpKQn4QdQXbskK58nncLZKiKCokWWOpVKlSeVfALSuUy82tZO8GWysURVFJywbS3Nzce1wB' b't6yAW4D74InGQlEUFYYycbfIMIndBojGQlEUlYQkiGbFbpElpVxOzgOx+0BRFEUlKWss2bxb' b'ZHEol1+ugr0bbK1QFEWFo7K0W6QL7xZwt0iKoqgQ5AdRV7AtK5TLzf1h7DZQFEVRSUqMpUzv' b'FlkuJ+fe2H1ga4WiKCpJ2UCam5tbtneLLFeOu0VSFEWFqby8vIddAbesELsNEI2FoigqCUkQ' b'Leu7RT4Uuw8URVFUkrLGUrFixTxXwC0reM21ivZusLVCURSVtGwgzcnJuc8VcMsKuAW4D55o' b'LBRFUUnID6K5ubmPuQJuWcD78I/HbgNEY6EoikpCEkTL+m6R98fuA02FoigqSdlAWuZ3i6xQ' b'Lt/eDRoLRVFUOPKM5UFXwC0reLdADIXGQlEUlYT8IOoKtmWFcrm5j8RuA0VRFJWkxFjK+G6R' b'5blbJEVRVEiygbR8+fLcLfKWaCwURVFhKDc391FXwC0rxG4DRGOhKIpKQhJEy/Zukfk5D8bu' b'A0VRFJWkrLHke3IF3LJCubw87hZJURQVpjxfud8VcMsK3i3gbpEURVEhyA+irmBbVigXv1sk' b'jYWiKCoJSRAt68u4cLdIiqKokGQDaV5eXkVXwC0r4BbgPniisVAURYUh7hbpGwqNhaIoKgn5' b'wdQVbMsK5crnPRy7DxRFUVSSssaSaLfIFq3bmm5f9jHde/YOjY5dupvP6n5x27lKE6+5xt0i' b'KYqiQpINpDk5OfcGg+3zL1Qx4ydNN/2++tr07NPf9OzdLzR69R1gvvp6qBk1fpKp36Bx3HlL' b'A+8WcBkXiqKoEOQH0dzc3B+6Au6IMeNN5249bSujU9ceoYPjdujczXw9dKTXMup92/mjInYb' b'IBoLRVFUEpIgmnAZl6efec4MHzXOGkCX7l+mlI6ewfTpP8gMHjbSeS2pQu0WSVEURSUpayz5' b'+fkVXAFXeO31N8yQ4aNty8JlCGHTyWshdf+yj20tvf5GNec1hQluAe6DJ7ZWKIqiwpBnLA+4' b'Aq7mlVdf98xlVGTmAtBVhm644aPHmUZNmjmvKwy8W8BlXCiKokKQH0RdwdZFaZiLgK64gUNG' b'mB69+zmvraSUy819NHYbKIqiqCQlxpLrCriJKE1zATCY3v2+stfgur47pVxu+Xti94GtFYqi' b'qCRlA2n58uUruQJuYZS2uQB0k3Xr2duMGD3BvFW9pvM6iwNuAe6DJxoLRVFUGMrNzX3EFXCL' b'Ih3MRcA4zLCRY03T5q2c11oYsdsA0VgoiqKSkATRpJZxuVNzQQsDs7169Oprv7rKJIMdhxk8' b'zL586breIOXuuuuh2H2gKIqikpQ1lgoVKiS9W+SdmEt3z1DaduximrZsYxo3a2Wat2rrTy12' b'lS8pMg4zdMRo5zUL5Srk34378Ne//pWtFYqiqCRlA2lOTk4ou0UWx1zQWunqfW3UuJlp27aD' b'GTp0uJk4aYoZOmy4ada8lWnWsm3oBoNxmK49epmRYyaYGu+8d9t1T58xp/LOHXt+NXz4cLuc' b'y5EjR2gwFEVRJZAfPHNzcx8PBtuSUpS5wFg6e4H+s8/rm35ea2LR4mVm8+at5sDBQ+bSpUvm' b'7Nlzpk+ffqaJZzKp6iYbOnKMadG6nX/NrTwz69Cpm5k6faZZvHT5EwsXLrD73e/fv58GQ1EU' b'dQeSoBn6bpFFmQtaD2ixdO/R24wcNdZMmzrDLFu+wmzavMXs2bvXXL12zXz//femfYfOpl3H' b'LtaMXMdJBlwbxmF69u7vX/eHH9Yxrdt2rDx56jdm9ZrvnlqzZv19uEE7duygwVAURRVXeXl5' b'd2tTCIvCzAUtEbQYBg4abG7cuGnWb9ho5s1faBYvWWo2bfFaLwcOmtOnT1tzWbP2O9OgSfOU' b'tF4AWjBf9ulv+gwYZKp614xrr/3+h6ZN+06VJ0yY6l3bJrNt6w6+PElRFFVc5efnPxg0hbAo' b'zFywZH4Dr9UyZ84cayDCiRMnzfbtO8ylS5fN9es3bNrhw4dMQ68sZpEFjxMWmKrc1WtBfeW1' b'Yj757HN7/TXfec+091pMYydMNPv2HvQM79DPYret3IoVK9iKoSiKSqCU7hhZVMulafPWZvSo' b'MdZADh08ZNZ5rZdVq9eYzZu3mSNHjppz587bvK3btpkGjZraGWXB44QNTKbfwMGmVdv25tln' b'nzfV3qpu2nXsbMaMnVT52NFj5uiR47/ZvHlzDm7enj17aDAURVEuuUwhLIoac8FU4yZNmpux' b'4ybYMZcJE6eYJUuX2TGX3bv3+ObSt98AL9h3SMmYiwsYDKYrd/XO98Yb1cwbf69mx3zGjptY' b'ef/+Q+bI0RNP7N+/3w70e9dHg6EoilKyQdFlCmFRlLnALNp16Gzq1PnUDPPKLV22wo697N6z' b'15y/cMtYJk2cbL5o2CRl4y2JgMHgnDCZjz76xLzxZjXTxjO4ceMnVd63d785febMn06dOmkH' b'+tevX0+DoSiKitM995R3GUMYFGUuAOMo7Tp1NV80aGx69e5rZsyYZZYvX2nmz5tvunfr4RlL' b'08haLEFujcP08gxmkGnktbDefqumadm6HVpYlQsKdttxoatXr3Kgn6IoyqkQ3sZ3URxzAfZ9' b'F+9rsxatTcNGTe34CkyldbuOkbdYXMBkevUbYNp6raxatd83zb3rnDBpitm5Y6dtXd38/nt/' b'oJ/dZBRFUbd0KxiWz6voMohkKK65CBiwR0sGYDZZabVYXMBgevTqZ7//5NO6pmmzlmb8xMlm' b'566CyjAYj99cvnzZvtFPg6EoirqlW8GwQs69LpMoKXdqLukODAaG1713X/vyZ5OmLcy48ZPN' b'rl27xWCeuHHjBgf6KYqilG4Fw2JsX1xcss1cNGjFtGrdzjRt0dqMGTvBbN+2UwzmTxcuXLgf' b't3LDhg00GIqiKE+3gmH5vBLt3xIkm80FYDwIkxGat2xjhgwdYdat21AZ66Fdu3Yda6P90N5L' b'iqIoyirWgsl9zGUYd0K2mwtANxne12neuq3p13+gWb5shTl06LAd6D9y5Kg/0L98+TK2YiiK' b'KvOygdBlGHdCWTAXIBMPWrftYCcjfDt3viko2F0ZL4F6RvObffsu2IF+vtFPURQVgsGUFXMR' b'8E4MpitjG4Gp02aaLVu2VD554hTWJHvi4MEDHOinKIqKKSmDKWvmAmAw+LwdOnXF2/zmu3Ub' b'Ku/Zu9/s2bPvT7v37+dAP0VRlFKJFrgsi+YCYDDY7RKtmKHDR5rlK1ZV3rJlq9m5c5fZvXsf' b'B/opiqKU7ngzsbJqLgBbN+O9GCx42f+rr838BYvMmjXfmT17D5rvvlunlu5fzlYMRVFlXPeU' b'u6N1yMqyuWjad+pqNyObOWM21k2rvHHTFrNy5ZrfLF68xQ70cwtliqLKsm4FwPz8Yq9DRnP5' b'B+29e9C1ey8zafIUs2Dh4sqr16wzK1aueWL9+nXco5+iqDKvWwEwr3jrkNFc4sF2yh279DAj' b'R48zs+fMr7xo0RKzaNGyP61atdYO9G/ZsoUGQ1FUmdWtAJhT9DpkNJfbwUA/7sfXg4eZGd/M' b'rDxj5hwzf8Fis3Tpcg70UxRV5iVdZIXuv09zcdO5e0/TvlN307f/QDNx0lTLwkVLzfRps7hH' b'P0VRZV63gl8h65DRXAoH9wVv9I8aPQ6LX1aeMnWGmTJ5+m+WLVtmB/oPHDhAg6Eoqkwq1oLJ' b'fZzmUjLQTYavQ4aNNMNHjK48YeIUM37SlCdmzJt3N24tDYaiqLIqG/xoLiUHBgMGDBxsBg0Z' b'XnnoyDFmzJiJf5o8fZYd6F+yZAkNhqKoMimnwdBc7gzMJuvVd4D56quvK/cb8LX5eugIM2LU' b'GD3Qj/tcZvgf/+N//ABrsYUNjus6Xxjwmv8BrzkeueaDgXMmSyqvuZikXPYkNJfkQAsG+8Tg' b'vo0dP8nMXbjUrFq33h/opyiKKqu6S8ylKs3ljoG59Ok/0Lzy2t99ky7LeE9mvwiLa1ev2q+1' b'atX6hetcYRE8bzJcu3bNfn377bcz7ppfeeWVzLnmGzfs12effTbl13xTnTcZrseu+S9/+UtK' b'r7kwcnJy7o3F/Wj0H/7Df7AGU+WVV2kudwjMpe+AQeaLRk2cv8yyRKfOnfHPaC5fuWK8f6Sk' b'uHL1qj3WqdOnnecKi169e4d2zTgGjnXkyDHnucJi4KBBoV/z/n0HnOcKi5EjR4R+zTt27XKe' b'KywmTJgQ+jVv2rTJea4o8Qzmvljoj6SLzKpz9y//3cDBwxAwK7sCKXGDBS+HjRzr/EWWJbx/' b'nsqHjxypfODgwaQ56IHjuc4TJjjHocOHnddwpxw8dCiya3advyTg95WJ1+y1JiK55v0HDjiv' b'4U7AMY4eO1bZM5mUX3NxiYX81JvLp59+ak8ybOSYnw0YNATBsljmgh0dMd6Adz/w1VUm08Fn' b'xJL8rjwBrZehI0Y7f4llha1bt9rWhvfPZLx//qTYt38//rFNt27dnOcKi50FBfaJMsxrbtu+' b'vfNcYYHzXLx0KdRrbtqsmfNcYXHk6FFz/sKFUK+5br16znOFxclTp8zZc+eM98DgvI47Qa75' b'o48+cp6rNLCBPwpz6devnz3JV4OG/rz/wMFFmguMpNuXfe3y9M1btjFNm7cyzVu38+rdynPV' b'ySTENNEiwQrJHTrfGrSX7ZGDlHVzadiwof3nwT+R65/rTkAAQvDEP7XrXGHRokWLUK/50uXL' b'Zs/evc5zhUXHjh1DvWY8DOzcscN5rrDo0aNHqNd87fp1s3nTFue5wmLAV1+Fds1eq8XcuHnT' b'rFm71nmu0sIG/ijMpW/fvvYkgwYPK9JcEGBbt+1o6n/RyLRu09707z/QjBg52gz8apBp0rSZ' b'ad6qXUYbDK69bYcupn6DxqaFZ5ydunQzbdu2N180bGJat+vo/Gxl3Vzwj3js+HHnP9edAlPB' b'8VznCROc48ixY85ruFOivGbX+UsKr9kNzhFGiwWg1RbFNd8pNvCnk7l09QJr0xatzSCvzKTJ' b'U83QYSPNggWLsTWw5/IHzO49e03HTl5rplXbjDQYXHMLzzDxGbZu3WZu3Lhuvr/5vTl79pzd' b'OKxDx86mmff5g5+tLJvLshUrzA3vnwdPaK5/rjsBT4r4Rxw6bJjzXGGx5rvv7NNkmNc8YMAA' b'57nCYuOmTfapPcxr7tGzp/NcYbHdaxWF3VXasVMn57nCYo8Xwy6F3FXaqmVL57lKExv408Vc' b'0GJBF1G7Dp3sDcM/58yZs83UaTPMqjVrzObNW20f5elTp02jRk1Mp2494+qnO/h87Tp2NW3a' b'dfBM5ab9jFeuXDPHjh03+/btN3s9tnifsW2bDqZN+05xXWRl1Vxq1nzH3qcwAh6eFM+cPWvO' b'nT3vPFdYoN8b14x/fNd13Am4ZvzNo3/eda6wwPhCWNeMoInxjyPe965zhUXTJk1CvWZ0leLv' b'zHWusGjbtm2o14zxvILdu53nKm1s4E8Xc+neu49p3KylWTB/of0FCBs2bjJr1q4zu3YVmEOH' b'Dtq00aPGmkZNW5ievfvFHSOdwbXWb9jErF2z1n6Gq94TF4CxbN223az20lesXG3GT5hkGjZu' b'Zrr36uvXLavmctV7kj5x8mQoXQgIHLjvL774ovNcYYFzhHXNB2LX7DpPmOAcmdjteDQDux3R' b'jeW6hjvlkEcU11xSbOBPG3P5so9p1rKNmTBhog24O3bu8p7qj3lPQEfNjh27zKlTJ82ZM2fs' b'DV2ydJmp5wXqTDKXbp5ZYJzl2NFj9jOcP3/emsuhQ4fN8hUrzZw5883kKdPNiJFjTcNGTePq' b'lkVzmTZ9ur1PYbRaxFhmzJjpPFdYfDt3bmjXvDfW5TFx4kTnucJi8ZIloV2zdNOMHDnSea6w' b'WLVqVejdjl8PGuw8V1is37Ah9G7HPn36OM+VDtjAn27dYgisg4eMwJLzZvacud4f0hrbT4lA' b'fO3aNXtT586dZxp4T/eZZC6YTl3PM5f93h/G1evXfANdv36j94R60GzZts1+3mEjx5hGZdxc' b'nv/b30ILeHgqRUsCL5q5zhUWr7z6aqjXjJc70e3hOldYvPXWW6FeM7od0SXmOldY1K79vr3m' b'MLqWcM3odkz1i7SfffppaNcs3Y5HvZam61zpgg386TSgj9ZLw8ZNzegx473WyXKzYuUqs3nz' b'NrN79x47NoFfEGjXvqOdpqzHJdIdGCFmhM2ePceOuWzfvsNs3LTZLFi4yGzZus3/bKdOnTbN' b'W7Q2XdS7L2XNXM54//AIVPjnd/2D3QkInLiv77z7rvNcYXHh0iXbsg7zmt98803nucICg+EI' b'rGFec9WqVZ3nCgu0WMLuKn322Wed5woLnAPdjmFcM46B47nOk07YwJ9O5nJr0LuLada8pVm4' b'aInZu3e/OXr0mLl06bK9oWDI4KGmUZPmGTdbDJ8Nqxw3adzc7Nyx0xzYf8isWr3GfPvtPDN2' b'3ETbPYbP963XemnoldGfryyZy5ChQ+19COMpD8EDwWjFihXOc4XF2DFjQr1mHGvBwoXOc4XF' b'lClT7HlwPtd13AlyzbNmz3aeKyxmzpoV3jV7vysca8rUqc5zhcX8BQtCu2bpDhs7bpzzXOmE' b'DfzpZC6gmxdUW7fr5AXhZmbYsBFm6dJlZt269XbmWAvvib5h4xa2jKtuuoPrbtO2o2narIX5' b'ZvoMs2jRMu8f8lsz6OuhdiB/8uSptnWjWy2gLJkL/nnCeMIDGLPD8VznCZPQrtk7Bp5wU33N' b'zzzzjD1HGAEPnxstCZi461xhUeWll0K9ZrTY0HJznSss3njjjXCv2WsZY1ab61zphg386WYu' b'AE/5XhnTpHkrG2wxEN6gUVPTvnM374k+c8ZZXKBFgs+BMaNmzVvYFykbed9/4X3Gpt73rqVg' b'yoq54B8o7KVHGjZq5DxXWKDvG33gYZiLXDP66F3nCgsE1rCXHqn9/vvOc4UF7nHYXaXVq1d3' b'nisssKpC2N2Or772mvNc6YYN/OloLgICcY/e/SwYs8ikMZbCwOfAAD++R1cZvha2flpZMJfO' b'XbrYf54wupZgTngq3bZtu/NcYdG7T5/QrhnBA7OJMKvIda6w+Dq24nFY14wWy6rVq53nCgvM' b'PgvzmnEszJJznSssZMXjMK957rx5znOlIzbwp7O5lAWKWrQSlAVzwT+P6x+rpOB4rvOESZjX' b'HNUyHjhHGE/SAO+ZZNo1R9HtCHAOmILrGu4EfG50O0ZxzWFiAz/NJf3JdnPZsnWruXrtWqjd' b'Yd26d3eeKyx2pWDF43bt2jnPFRYIdmF3OzZL8YrHOBe6xMK85nopXvEYZnDu/PlQDFGu+aM6' b'dZznSlds4Ke5pD/ZbC4NUrDi8aHDh53nCouwVzy+ePmynRnpOldYdEjBisep3kyrR4+eoV0z' b'jPXWisep3UwLa8CFec3odky3FY+Lgw386WwuGJvAOES2jLUEKe7ny2ZzwT8ilx6J5ppd5y8p' b'vGY3OEdYXXjpuuJxcbCBPx3NBQG3c49edgHHlm3am7YdOnsBGHu8ZIfJiKG07djFtGp364VQ' b'jL0kmmKdreaydNky+88TRt80nhRxrGGpXvF4zRr7NBnmNWN/D9e5wmLj5lsrHofZtdSzVy/n' b'ucIiFSsed0r5isd7wl/xuHVr57nSHRv4081cEHhbtm5nmjVvZbp362n69f/KdOve09Rv0Mi0' b'atvB5rvqZQq4/lZtOtip1V26djdf9upjOnbsbJo0aW5ae59PZpFpstFcatasaf95wgjSeFK8' b'teLxWee5woIrHsdWPPZaba5zhUUqVjze5/2duc4VFm3K0IrHxcEG/nQyFzzNN2nW0nTs1NXM' b'nj3XbNy42a67dc77J8T6Yu07dDLNWmbmXi4A1439arp06R5b5fmw2bp1u1m6dIV9Sx8GA9MJ' b'ziDLRnPJxBWPb3rnCPuaXecJE5wj05YewTnK8orHUV1zKrGBP13MpWuPPqZFq7b2pcLhXiCd' b'OXOOWb58pdm8ebNd5BE3GwtXYt0tLHCZaeMwthusQ2fTunV7c90LrBcvXjQ7duw0a9euM3Pn' b'LTAjR40zU6fNNKPHjLMvj2oDzTZzmTYtBSsez8ycFY+ly2Pi5MnOc4VFKlY8HjVqlPNcYbEy' b'BSseDxqc4hWP15etFY+Lgw386WAuCLzYSKt7jy+9p6wTZumy5V4AmmnmzV9kNm3cYvbu3WdO' b'nLg1P33N6jV2deFMWhEZ4Hrretf93drv7Oc4ePCQ2em1XtauW+99zoVm9eq15vLlKzYPO1Li' b'LX4x0Gwyl+cyccXjV249mYZ1zXhrO/UrHlcP9ZqjWfG4tr3mMLqWcM12c0HvXrvOFRaffBb+' b'isfHvZam61yZhA386WAueEq3e7lMnGx/UcLxY8ftRlrnzp33Wi3XbRpWDf6iYdOMW18MXV3Y' b'4OyS12LB57hw4ZL9w8eKyAf233r6FoYOG2G3Q5bWSzaZC/7hw17G471Ur3js/c7CvuY3q1Vz' b'nissrnjmxRWPueJxaWEDf7qYS4vW7cyIkaPtzb148ZIda9m0eYsFy+0jGCPv6JGjpt4XjZ0D' b'3+kMWiFY7RhGic+BZffxObfv2Gl3oFywYJGZN2+h3d+lc5fupp3q+ssWc0nJiscrVzrPFRaj' b'M3DF48mxFY/DvObZs791nissQl3xOHbNU6dNc54rLBakYMXjMRmw4nFxsIE/SnMZMmzkzwcM' b'GuIcc0EAbeUZDMYfxk+YbMaOm2AWLlxsNm3abPdzkW4xtG4aYsn93pnVcrm1n0szs3jxYvs5' b'zp49Z/Z7LRa0zLAh2oxZc8z4cZPtZAYs1pmNYy743GE84QEuPeImFSseYyKD61xhUaVKlVCv' b'mSselz428EdpLu07dv354GEjneZix106dDafflbPDBs6yu7ngsFuDHofP37C/iIxcPZZ3S+K' b'tR5XOuJ9btOoSTN/gsLZ8+fs95u3bDXffbfee9Kabho1bmIXs5RWC7hlLmOcv8RMAf9AYS89' b'0ijFKx7DDMJeeuSzzz93nissUrHi8fspXvH47PnzoXc7Vq9Rw3musEjFisevZciKx8XBBv4o' b'zGXgwIH2JH/+j//x50NGjkHAvM1cALq68EJhk6bNzOAhw8ySJcvMli1bzNYt28y4sePM5/W+' b'MB29QKsDbyZhDdT7fPW+aGime0ay3zOWvXv3mu/WrTejRo81jRs3ty+OYr99XQ+mNHhYamfp' b'pJKUrHi8PcUrHvfuHdo1I3hEseLxwAxc8XhEClY8XrJ0qfNcYTE+BSsez8ugFY+Lgw38UZiL' b'J3sSnPTjTz83o8ZOqIwgiyfyIF28ANyhcze72yT208eTPoIx3v/oHAu2rnqZglx//dg+Nfh8' b'DRo1sZ8Pn7tLd+xl84/y7b37hHGqNh1S+3ZxKsE/j+sfq6TgeK7zhEmmXnMYT9Ig07odcYwo' b'uh1BmNeMbscorjlqbNSP2lxAy9YdKo8aN8n0HTDYfNlngB2P0PTqO8D06T/I9O73lfnSfj/Q' b'KzvIK9v/trKZCD4TPk9v73P19D4/Pmcf72d87rhy3ucdNGSkGTF6/G2/vEwhFSsed0/1isc7' b'd5rLIS890q5DB+e5wgJPwFzx+HtTr35957nCAmaAbryDIV5znQxb8bg42KgfpblU8qQvoGmL' b'Vrabq3P3nqZzV49uMZAmeE/xcd9LmYwm+Jn0z14+7oV3Tzp16W67AvU9yyQaNGhg/3kQ+PDP' b'VNI3mFEPASiSFY9btrTXjH98OXfweoqDXPOly1fM3n37nOcKiw6ecYV5zVGseNyz55ehXnMU' b'Kx731yse43qTuGbpdvxu3TrnuTKZ/Pz8B2zUj8hcfLkuhmQn127cMPu9f/w9e/eGAv6xXecJ' b'kxux4OE6/52yb38014xz7A3tmm89TbvOEyY4h+v8JUHGLVznCZMwrxmGGMU1lwaxUB+54GQ/' b'cF0QyS6On7g1wy9MRo1J7Yw5zLJynTcZBqd46RG86e86bzL06dvXea6wwNRm13mToVu3bs5z' b'hYXrnMnStm1qN4crDbz4fpeN9KUg20z68Y9//LDrwkj20KRJE1O9enXzzjvvmBrv1CgxNfG1' b'Rg3z8ccfO88TJk2ahnvNUfSlN23aNJxr9q4X14yVn13nCZOmzZqat99+O5xrrlnDfPjhh87z' b'hAn+Nt56+61QrhnHSPX07tLCRvmou8NisifNycl51HVhhBBCMhcb5UvTXO697z6aCyGEZBk2' b'ypemuTx8//00F0IIyTJslC9Nc3ns8cdoLoQQkmXYKF+a5vKzn/yM5kIIIVmGjfKlaS6//Okv' b'aS6EEJJl2ChfGubyl7/8xZ70V7/6Fc2FEEKyDB3nI9X//t//2570n//5n2kuhBCSZeg4H6nk' b'pL/73e9oLoQQkmXoOB+paC6EEJK96DgfqeSkv/3tb2kuhBCSZeg4H6nkpE888QTNhRBCsgwd' b'5yOVnPSpp56iuRBCSJah43ykkpM++eSTNBdCCMkydJyPVDQXQgjJXnScj1Rhmctnn31mpk2b' b'ZsaNG2fGjx9vxo4da8H32JypcePGxaqnGT16tOnbt2+x9ll4/vnnzfDhw813331ndu/ebXbs' b'2GFmzJhh92lwlRdQZsKECfZ8cr1Dhw41nTt3Ni+88IKzTmE899xz5ptvvjGTJ09OuFnSM888' b'Y8vg3F98kXjL5F69epmVK1eaPXv2mF27dpmFCxeaRo0aOcsSQogLHecjVVjmciC2rWlRvPXW' b'W3H19se2cC2KCxcuxNXTbNy40VlHgNG46nXs2NFZXrN9+3Zn3USMGDEirr6rzJAhQ/z89u3b' b'35Y/ffr0uGMEKexeEEKIRsf5SBWWuejgt2bNGrNq1Sqzdu1as2nTprg8kKje1q1bzZYtW2xA' b'x/dogSD95s2b9uuSJUvi6gbrg+XLl9uWyLp16+LST5w4cVvduXPn+vloHeD4GzZsMAUFBXF1' b'z549e1vdRMjnPX/+vP06cODA28rgHHLsYN7x48f9PLB582YzceJEs2jRorh0EKxLCCFBdJyP' b'VGGby8WLFxPmi0kE0wurV6tWLb9Morpg27ZtcXngxRdfjCvToUOHuHwxAKDThWvXrvn57doV' b'b29tKX/9+nX/+8LK6HQYq+Rdvnw5Lk84c+aMXwaG4ypDCCGCjvORKgxzadasmR/w0GpxlUFX' b'jpSRtFatWhVZD0gZXXfkyJF+2qlTp+LKazp16uSXQ0tI50k60OkC9pyX/ERda0H0MYWGDRs6' b'y+jPjD3HdR1dXhM0TFcZQggRdJyPVGGYy5w5c/xg5xq4r1evnjMgzps3z09DGV1HwAC9lEF3' b'laRLGqhSpUpcnSBS7urVq37ae++956fv3LkzrrxGyly5csWZr9Emu2zZMnPjxg37Pbq6pIw2' b'rJ49e/rpe/fu9dMxmUDSXUg54MonhBBBx/lIFYa5YExCgl2DBg1sWs2aNU2dOnXM1KlTbbp0' b'iQ0aNMivd/r0ab/epEmTbLdV//797YD3zJkz47qlwN///ndb79133/XTDh8+7B8vEVIWx5M0' b'3fLBLDNdXiNlcP2ufM23337rl8fPGHeSn+Xa9TjPq6++6teVNCBpiZB7WZyyhJCyjY7zkSoM' b'c9GBsTAw2F2SehiP0VOKYVCSh2nD+phBYHJS9siRI346pvZKOloxuo4AQ5AyMEJXGY02S/ys' b'W0eYUuwqEyznGjsKImX1MQghxIWO85EqWXOR4K2fpjXoisLMr6ZNm8bVq1Gjhl8GA+tff/21' b'neWFWV1IQ5dS0IwEvB8idVu0aOEsI+jWBFpRki5pQJfX6CnDixcvdpbRSNlDhw7dlgbws3SV' b'Yeq2lMFnkDLoYpR0F7ospnG7yhBCiKDjfKRK1lzwgqQEO7yE6CrjQtdDENd5+p0ZvJSo8wBe' b'upT8Ll263JavkXJAxmbwcqSkwdiCdQRd96OPPnKWEXQLCS9iSnrv3r39dHwuMWFdBuNUUgZT' b'qSXdBVpxUrZt27bOMoQQIug4H6mSNRfMopJgh2nDrjIudL1g4H722Wf9PKDzAIKq5OlWQhB0' b'MUk5vC8i6XhxUdIxqUDXERYsWOCXKc57Luiek/Iff/xxXJ6kA2m56DJFfV4BhlSccoQQIug4' b'H6mSNZeSBrui6mnzcc2e0vVnz559W76uD3QeXpaU9OA0YYAusER1n376afP222/fNk6DFz9d' b'5YEM4mPGWaIyukWCFzqD+bNmzfLzQbVq1W4rQwghQXScj1RhmcudLklSVL3q1av7ZYIvGwL9' b'/oqAKcUYtA+mo2Wg6547d86mo4sKrRIMsuM6grPTQHBtMteAPJC0S5cuxaXrfDEX17TmqlWr' b'+scQ9u3bFzdFWeD6YoSQ4qLjfKRKxlywtIkEPKzv5SrjQtdLNGgPpAzo06fPbfktW7aMKxME' b'Cz0G6wBX2SCJust0GUl78803/TRMXtDlhWPHjvllEs0Iw9RkvJkv5YLc6TpnhBCi43ykSsZc' b'3njjDfviIF4MDLYOCqO49RBs8ZSOcniD3VUG1K9f34waNcquRIyFI4t6socpYTVidInhK8AY' b'CN6fKWol5NatW9vjB1s0mMWF68TqzDpdg/yiygBcB2bP4fNgkgQH7gkhJUXH+UiVjLkQQghJ' b'b3Scj1Q0F0IIyV50nI9UNBdCCMledJyPVMmYyyuv3NoBkqQPGDN6+eWX7VdXPiFFgZW38Tfk' b'yiOlC343rlhcGDrOR6qSmstrr73mnNFECCEkdbjicWHoOB+pkmm5YI93vG9CSp+uXbvamWiy' b'CvWYMWPsjDyku8oTEgR/K5hBKduGY0sIzI7ES8yu8iR6XNuiF4WO85EqGXMh6Ye0KF15hBQH' b'eQ/NlUcyDx3nIxXNJbv49NNPbWDg8jCkpMgadq48knnoOB+paC7ZBRYBRWCQzckIuVPw4i7N' b'JXvQcT5S0VyyC5oLSRaaS3ah43ykorlkF9lqLs8884wznYRPKswFSz5hSw4sbeQCU59d9Vxg' b'kVdsiY7tyYcNG2YnHbjKaV566SVTu3btIvdl0mAvKamTyX9/Os5HKppLdlFSc8E6ZqhXXDAb' b'LXiMYJlgvgYLfEo5DCAH8zFzSR8LK0RLHt6v0nlFoY9LiiYV5hL8nSQCO8e66gPMfsSq4656' b'YMOGDc56QJcr7qriZ86c8evg79FVJhPQcT5S0Vyyi5Kai2xiVlywTbWuv2jRIpuuty3Q+UGk' b'DMDLYTrvm2++icv/6quv4vKx+yjSE22tHUTXJUWTKnPB1hn695IItEaC9VeuXHlbOezsip1k' b'g+nBugDp8vfiyndRkjrpiI7zkSpKc8EcevzhTJo0yf4Bo2lb3NWUpS5msqA5jK2BXeUAVizG' b'nHA0l1u1apWQHj16xNXDfP6OHTsW2szGE0y3bt3M66+/7qdh+2TULex8WIkZ9fSxUkFJzUW2' b'k8ZmaPg6ffp0exwgWxdI18Df/vY3+1VAl4eUBfIPWadOnbhyGl1ep+vdQ0FwUzawYsUKP18C' b'0Z2syk0KJ2xzQYtDfl+JtqSQcwI86Og8vbkfwP+Szg++0L1+/fq4fL03VHF2lQV4E17qBK8n' b'09BxPlJFYS54GUt+US4Ka86uWbPGWUfA0vTBOq5yiZA6WN5fp7uCGs4l+fXq1fPTdRdPUejj' b'pYKSmksQeZEOfP75584yguyiiX9CmKzUc/1uAB4MpIzu7tJ72aBLQtfR6CdgGLurDCk5YZuL' b'7MQKsB24qwyQMvrc8vcswEh0HSFoMDpv8ODBfvqcOXPi8hKhu2VXr17tLJMp6DgfqVJtLvqp' b'ASaCwTg8HePpd8aMGX7eyZMn4+qhZSB5YMuWLbZl8MEHH9gWD3aOlLxgt4mkowwCGeq1adPG' b'Bz9jjxQcS+rIi2N4ssFXV3DDTpdybJ0uaQDHxd4urvMV1toKi7DMRX8mV76gDVeeKOXntWvX' b'3lYeYFvqRHUAtpkO1tHosq58khxhm4vuugq2egXdFXrq1Ck/HXFB0gszJqC3Edfveen/W6xi' b'oeskAoYidaLocUglOs5HqlSbCwZ+5ZeEmRfBfOxEiT3jsT2xTpc6AM1qnecqI2noPpO0cePG' b'xZUvDPTf6uMBbEKmy0g6jE7SdPN58+bNceVLgzDMBQFAPhNwlRGkzNGjR29LS7SFtd4qeunS' b'pf736E4LPmQEwe9EyqKlM3LkSDsZAcveTJkyxX5FtyseXLp37+48BimcsM1Ffr9Agj56Ct5+' b'+207uI5uLF0GD2euupKWiEOHDvll9eaCd3IMQY9BFrWBYLqj43ykSrW56GAPEnWVaBYsWOCX' b'xxiLq0wiZGAZ1K1b11nGhdTZvXu3v8e+3use0yiljH6SGTBggJ/ev39/P720CMNcZMAcJGp9' b'gEQtOTx5utIFyUtE0NQ1MhZUnMFhmI3rGKRwwjQX9A7gWMUdzNe9EBirlPR169bFHdeFPg7M' b'C2noNtXpwTqJKEmddEXH+UiVanMBspiiBq0V9M+7yutyrvzC0HULY/78+X4d3a/7/vvvx40J' b'yBTEmTNn+mlSD2DMQNILQz/Zp5IwzEXPzEnUJaAfGoLdfbqLI7hEeM2aNW06ZpXJwP+OHTvi' b'uteArqM5duyYXwYtxXnz5tnWD7rSMPALMAEB3Rp8N6ZkhGkuuucCBoMeAj3FFy0E9F40aNDg' b'trpyHQAt1GC+BhM6pCyQdP2g9N1338XVSYT+20accpXJJHScj1RRmIuAAHLixAn/FydgPSxd' b'TtKDXWVFgbEcqYs/WjS38XS9fft2H3Rp7d27185wknp67EfS5GdJO3z4sP3+6tWrfplgOQyC' b'63PJ+dAaKm5fb7KEYS66SyDRgLnkgyFDhtj+8AkTJph+/fqZgoICP093cQDM9EO6PMnq8RX9' b'DkOiFqvkA1c+SZ4wzUU/fH3yySd+uh5TxQODriNMnDjRL4O/G1cZYfny5X5Z3cpZoWYWfvnl' b'l3F1EjFr1iy/zogRI5xlMgkd5yNVlOYioE8fT5zyCwQ6X9L2798fl67BexbBp2L88UhdbAeg' b'8wpDZjtp48ATuxwLs11ksBDXLWXQypEyOr00CcNc5DMBVz5edNNlXIhBodWq68JopUzwHxcz' b'9CQP6DyAPnrJK+6UUnLnhGku8vtyHa9v375+Hh7EgvlYXl7yC2v54w1/lJGWMN7GlzzdHZdo' b'plkQ3a2L/3FXmUxCx/lIlSpzQfCXXxDGUFxl8AcjfxA6XeoF0wU9A02X0U/MunxRSJ3g28H6' b'CV7Q4zi6+yeZYB4myZoLuifkM6GFF8zHbD/JB+hCQwsRYzN4YsTP6OaQfJiJrq/r6nQBQUby' b'8fvUeYMGDfLz+vTpE5dHwiMsc8GSLvL7wv+Sq4zkA9ffLNIlRmBKcTAfrSF9DPxP6nydp9ML' b'oyR10hkd5yNVKlsu+peEfkydp59agtN+dXMYM4vwxCp5aJFIHtAz0PAz/hCLeqrVsz8wTViO' b'9dlnn8WVa9q0qU1Hy0bePNf5Mm0ZFPa+RaLpl6kgWXOZNm2a/5lc/dx6pldhT3VSRgcVvIkv' b'6UCX10g9fNVdKehilLoYV0HrEl1y6G7VwITuZKYgiScsc9Gtfzx0uMrg9ydlXOMbo0eP9vMB' b'uqfRRQbQs6Hz8E6crivbT6DXAb0S6F1YtmyZvRZ0owGM1+GhSMYW8QK21MHfIB6MXXUwftO7' b'd++486UrOs5HqlSaC97Q1r98F8ePH3fWXbVqlbO8gGmu+i15maJaXKSeHgOSNI1uVmPqq6Tj' b'jXZJLw5RtWySNRfdWtPvAQF0Y0nerl274vKC6HcOJE3eJQKubhBBT57Q9XVacdDHJMUnLHNB' b'z4T8LgrrppYyQE8hFvCgoMu4wMNqsF5RL2BrsKIH6gS76wsDM0WD50xHdJyPVKk0FwGtA3Q5' b'ISBhkB5PoHg3IRi8gmDQHe8soDzqISAlqoeWEc6BfExXRV9/EOThyRxPtlIP6QhmiQYMMS8f' b'A3woowfl33zzTfuHWNT58BWfQR8zlSRrLmiNISi4Wn8wdAy+FvUuCsA9wYMDXqCTlifuIfqz' b'UR/L7ATraPD7PnjwoDUpedES5o53GfD0iq94cg2Crjzk6dmA5M4Iy1zkfSOMWbryBXRxojsL' b'b88n+rvAzD9MGEEMwd8P/jbQiihs219MMsH/Lv4H8X+P/0cNpqrjGvFSr9TB6wTFqYMy+lzp' b'jI7zkSoKcyHREcaAPinbhDmgT0ofHecjFc0lu6C5kGShuWQXOs5HKppLdkFzIclCc8kudJyP' b'VDSX7ILmQpKF5pJd6DgfqWgu2QXNhSQLzSW70HE+UtFcsguaC0kWmkt2oeN8pKK5ZBc0F5Is' b'NJfsQsf5SEVzyS5oLiRZaC7ZhY7zkYrmkl3QXEiy0FyyCx3nIxXNJbuguZBkoblkFzrORyqa' b'S3ZBcyHJQnPJLnScj1Q0l+yC5kKSheaSXeg4H6loLtkFzYUkC80lu9BxPlLRXLILmgtJFppL' b'dqHjfKSiuWQXNBeSLDSX7ELH+UhFc8kuaC4kWWgu2YWO85GK5pJd0FxIstBcsgsd5yMVzSW7' b'oLmQZKG5ZBc6zkcqmkt2QXMhyUJzyS50nI9UNJfsguZCkoXmkl3oOB+paC7ZBc2FJAvNJbvQ' b'cT5S0VyyC5oLSRaaS3ah43ykorlkFzQXkiw0l+xCx/lIRXPJLmguJFloLtmFjvORiuaSXdBc' b'SLLQXLILHecjFc0lu6C5kGShuWQXOs5HKppLdkFzIclCc8kudJyPVDSX7ILmQpKF5pJd6Dgf' b'qWgu2QXNhSQLzSW70HE+UtFcsguaC0kWmkt2oeN8pKK5ZBeffvqpDQzVqlVz5hNSFOPHj6e5' b'ZBE6zkcqmkt28cYbbzAwkKT4+uuv+TeUReg4H6mSMZe6deuaDz74wHz44YeklPnkk0/Ma6+9' b'ZgYNGmQDw5dffmnefPNN8/HHHzvLk+wHv3v8XbjyXKBs1apVzZIlS+zfUL169UzNmjVNnTp1' b'nOVJdEicxVdXLC4MHecjVUnNBYEMf4CEEEKiwxWPC0PH+UiVTMulZcuWpkGDBiSNaNSokWnS' b'pIn96son2Q9+9++9957ZvXu3DUYNGzY0n3/+ebH/Jho3bsy/oTQEv8f69es7Y3Fh6DgfqZIx' b'F0JI+iLdW648UnbQcT5S0VwIyU7WrVtHcyE0F0JIuKxdu5bmQmguhJBwCctcMEOpV69e9v2X' b'MWPGmK5du97Re1SY5YT6EyZMMKNGjTKdOnUyL774orOsgPe1MMaAcV1XPsBMNowLNWvWzDz9' b'9NNxeUhD/dq1a8ela5o3b27HlzDrVadjXEPGNzBWhXzw/vvvm2eeeSaubCag43ykorkQkp0k' b'ay4YREb9RFy5csUGeFddsGDBAmc94dSpU3bWqauuLufKB7pMrVq1/HR5CVTQdQSYjuTv2LEj' b'Lk/XTQQMUtdJZ3Scj1RRmMurr77q/AUJx48fN926dXPWdSGzYATXUic6vziUpF7v3r3jzklI' b'OpGMubz88sv+3/mlS5dsMIWRvPvuu/7yMMILL7wQVxeBXufj/3vAgAF2BlqXLl3Mvn374vLf' b'fvvtuPpoKUneoUOH4vI0+hg6/fDhwzbt3Llz9uvKlSvj8sHEiRP9ulgySdLRYkHazZs3zbFj' b'x0yPHj3M4MGD7YulixYt8uuAkSNHxh0zXdFxPlJFYS74BelfSiKCTxAu5GkKv/xr167Z71u3' b'bh1X5pVXojGX4D8VIelEMuYybdo0/++8Xbt2t+UjsEr+N99846eje0rSQd++fePqCTq4A503' b'Y8YMPx3daDpP6N69u19m9erVcXmSrgl2Z50+fdrP0+mLFy/209H9p/NA8P2+YH46ouN8pIrC' b'XOSPHHz11Vd++rPPPmt/gUiHWeDr8OHD4+oGkePoOtOnT7+tHFozVapUMc8995x5/vnnzY0b' b'N/x6MlccT2cvvfSSLYOf5akF4OkKacjHcQT0FeNrouY8IelCMuYycOBAWxf/Y2gBfPbZZ85y' b'QU6ePOn/DyUyBkHKAZ2OlpKkYzkjnSds377dL9OiRQs/HWMkkn7mzBn/e5TX9SUdrRxXOvjb' b'3/4Wlyds3brVL+My3nRDx/lIFYW56F+YKx/LTBRVBsyePdsvg9aQNHv37NnjLK+ResCVD2bN' b'muWXGTFihLMMIZlCsmMuZ8+e9f8fAB7QZs6caZcVcpXX3d/Xr193ltFoE0FdSZc0oMtrEpWZ' b'O3eun46Hx40bN/o/16hRw5ZBT4ekDRkyxK+Lh11JB5IeZP78+X6ZRC2zdELH+UiVDuYCiiqj' b'+4C3bdtm08RcEtURMCtEyhUUFDjLAAwwSjn8obnKEJIpJGsuoGPHjubo0aP+/4Vw8eJF29LX' b'ZXVXGbq9dJ4LfTxJw9iOpG3atCmuvACTkDLnz5+Py4OpSR5+1t1YGPtB2tKlS/00bWoYQ5X0' b'ZcuW+elB9Jhv27ZtnWXSCR3nI1WqzQVTBeUXsXPnTmcZcPnyZb+c68lIN3ElDSYTTHOhWyTD' b'hg1zlgFSBsyZM8f+g6D/F33KAN1v+Bl5rvqEpBNhmIsGXdowFf1/gmnGkq8HvIvqLsLCqlIW' b'D3WSvn79ej+9c+fOcXWEyZMn+2UmTZoUlyfp+iFSTyDAYp4y4A90XW0aiFs6TyNlgvXTFR3n' b'I1WqzUV3ZQ0dOtRZBuhfGMY0dF6fPn38PD3INnXqVD8daynpOhptTNI0DoKZMMjXTz6F4ToG' b'IelEScylevXqZsqUKfaBLDhRRtD/0/oJXwd9PITpOkGkHMBqzJIu46hAl9fo8VOMiUq6jN8C' b'vFcj6Sgj6UDO8d133/llgC6j0zUbNmzwy2DsxVUm3dBxPlKl2lz0rIzC5sRLGZAob+HChXHp' b'eKlJ8grr+5QywJUP0KKRMuhuwz8NnqLwBwiwlMaaNWtsH26HDh2cxyAknSiJueDlQ/k/QCvF' b'VUbP5tJjk8FZmliqX9cDmGijzWHevHlx+dpc8CKlzgOjR4/28w8ePBiXpwfag7PD0MWGdJxb' b'HiB1lxYeTqUuWjC6rrB8+XK/DHCVSUd0nI9UqTaX4vwy+vXr55eBGem8zZs3+3kYrOvfv799' b'QsK+JTAbyUvUR6r/aHTzO8iuXbv8crqpT0imUtJuMd31he/RHYzxFPzfYdxC8lzHRvexzkdX' b'OGaN4cXGAwcOxOWh5yFYX4+5AEwzhoHh3HomGgjWlXQYVDBP8rW56Dx0ryENeRhjGjdunO3+' b'RlcfPoMcGwRjVLqj43ykSqW5vPPOO/4vJDjwptG/ON0UR3NZ5xVGol84/jClTGFNdX0sVz4h' b'mUYyYy56RpQLvH3vqgfwP3z16lVnPYCuJdeLzwImEbjqCa5zY6q05Ae7uwQYlT6OztPpicA4' b'TqtWreLqZQI6zkeqVJoL3lmRX0yiqb36aURmcwiSDvD0gJcsMV9d0NMMga4rYJqy5AdntwiY' b'zy5lgk1tQjKVMAb0MZsK62q1adPGvsCc6L0TF3i/DHUxuI8B8tdff91ZLhEYe0V9mFVxzo1r' b'RdecK0/ATpvBMV2AY8t7bHg5Wt6PC5bLRHScj1SpNBfdnMQgIJ4u2rdvb2eBBJvPQNeVZirQ' b'bwAHkb7UYH1B8hLlA4yhIB9N4r1799qpyxgQxLs0GrwVjC68O/kHI6S0CMNcSOaj43ykSqW5' b'6MBeGBgs1/UQvHW+zguipxnj6UrnoeldnOPogcDi8MUXXziPQ0g6QXMhQMf5SJUqc8FLiJh1' b'tX//frv4HL6iVQAwG2PVqlV23rxrCWv0jZ44ccIOrGH2SjBfg64udKehfHDGGJaFwCA+5rUX' b'1vpBC+vIkSP2GtEtJtepQfcavqKc6xiEpBs0FwJ0nI9UqWy5EEJKD5oLATrORyqaCyHZCc2F' b'AB3nIxXNhZDshOZCgI7zkYrmQkh2QnMhQMf5SEVzISQ7obkQoON8pKK5EJKdYIo/zYXoOB+p' b'aC6EZCey0KIrj5QddJyPVDQXQrIHLGWE5UvwvbwcHCxDyhY6zkeqkppLcEvQ4oDVSq9cuWIX' b'tQsbHLe4e7EkA85z7do15zWUFBwviuvH/cembKkCn8V13rDA/blw4ULKwLa7OEcqwGq8WGEY' b'a+lhkdWwwcvC2LcIC8Tis+gViF3/v6TsoON8pGLLhZDsZPHixTQXQnMhhIQLlp6nuRAd5yMV' b'zYWQ7IRTkQnQcT5S0VwIyU5oLgToOB+paC6EZCc0FwJ0nI9UNBdCshOaCwE6zkcqmgsh2QnN' b'hQAd5yNVVObSp08f06VLF7vFMbYV7tixo/3aqVMn07JlS/Pyyy8762HL4W7dusXVC9Yt7t7c' b'2Hhs3LhxZtGiRWbhwoVm1KhR5tNPP3WWFbDrJLY4Dp6/bdu25v3333fWuVNwrClTptipo99+' b'+60ZMGCA3Q/cVTbI22+/bfr372/mzJljlixZYmbMmGG6du3qLEvKFjQXAnScj1RRmEvjxo3t' b'H3lRYEfJYF1XORd4AS5YV8DOlq46mgYNGjjrusoGgSG46hbFli1bnMcTsPulqx6A2eHFPFc9' b'Abt9uuqSsgHNhQAd5yNVFOYyf/58P+Dh6RyBHK0OPLHjqRvGIPn4h5B6NWrUsGl4sxxbJqPl' b'069fPwu2NMYTPt5OlrrYhlif97333vPzAN5aRlCuXbu2qV+/vlmxYkVcPlpJuj6W0kA6gjje' b'QMe2ye3atbPXPnLkyLjgHjx3YXz88cd+PYC3trHlM+4LPiO2d5Y8l2lu3rw5rv7kyZPN559/' b'bltSuJ86D/ctWJ+UDWguBOg4H6miMBcsfyHB7umnn74t/6233vLzsUSGpI8fP95PRwDVdTRS' b'BiRKR9DVeUL37t3jyuk8dOVJOgxS5wl6yZPPPvvMWSaIlAcDBw50ltH3DN1wkr5y5Uo//ezZ' b's3F1NNqwe/Xq5SxDshuaCwE6zkeqKMxFglyiP3S0AiR/48aNfrpulTz//PNxdYRBgwb5ZbCm' b'kqTrtZWmTp0aVyeIDuRvvPGGn15QUOCnN2rUKK6OoK+9ON1j6OqS8hj3cZUR0HJ77rnn/J/f' b'eecdvy7QZYNgfEjK7dy501mGZDc0FwJ0nI9UqTYXdPNIkNNdXgCBfPbs2X4+eOWVf+TrdHT7' b'VKtWzXYpIdCjxYGgqctIywEBWafL8RJx+PBhv+xHH33kpxfnGJhsIGUwtuMqoynOMRMB45W6' b'PXv2dJYRPvjgA7/soUOHnGVIdkNzIUDH+UiVanPZtGmT/QPHuIkEu0Q0adLEryeTAHSrIhFo' b'peApX+pidpfkYWaYpCdCHwvjLEjD+IWkYcXZYB0Bs7yk3MyZM51lhDp16vhlYWiuMoUhdYEr' b'X6NbdOhKc5Uh2Q3NhQAd5yNVqs1FAhzAoPfu3bvtV3QPYWAaU2jbt29/Wz1Mq5V66D5CYMaA' b'ujarNWvW3FYPTJgwwa+baKxFwDGlLI4p6RjjkXSM/eg6GiyXL+Xq1q3rLCM0bNjQL1ucVk4Q' b'qQtc+Ro9FpSoS49kNzQXAnScj1SpNBd0e0mAwz4TrjKJkHqufw75pwGYvRXMx8wryV+xYsVt' b'+RopB9q0aeOnY5aVpNeqVSuujjBmzBi/jDamROjW0IkTJ5xlAK4Z50e3H7oVJV3qAl0+iJ4I' b'AfNzlSHZD82FAB3nI1UqzQUvKUqQK6rLSPPMM8/49RL9cxQnX7ri0GJwlcFsKzkGWkQ6T9KB' b'TheGDh0aV6ZKlSrOckF0HQy6B/MHDx4cV0bPrtNjLokG6fU9B4kmQpDsh+ZCgI7zkSqV5qIH' b'ytGt5SrjQg+SJxovGD58uF8Gs7qC+bpVAbZv324NAcj2rwL2Gtd1ZbwHXUuYGo1zoasNBul6' b'IRNTqXV9mJZ0S+l00Lt377i6uC6Mj6C1oc0OvPbaa7fV1/lg+vTptqWGawvmvfnmm7fVJ2UH' b'mgsBOs5HqlSaiw50rvxE6Hc0XOMxgj6+q3usdevWhb7Fvn//fvPJJ5/cVk9PY04EjGDEiBG3' b'1ZUXP4GeGq3BZ9LHCoLxJlc9QTaBSsTEiROd9UjZguZCgI7zkSqV5lK9enX79K2nFxcHTDnG' b'emH46soX0H2G42Nsp7BuKZy/VatWds0tvJBYVCsK5/773/9u1/fC8bHumYBzuupocN2uVkcQ' b'XDfGeXBdMEe8x+IqlwhMvcaYDOpj3bSqVas6y5GyCc2FAB3nI1UqzYUQUnrQXAjQcT5S0VwI' b'yU5oLgToOB+paC6EZCc0FwJ0nI9UNBdCshOaCwE6zkcqmgsh2QnNhQAd5yMVzYWQ7ESmrLvy' b'SNlBx/lIRXMhJDvBmnw0F6LjfKRKxlyOHDlilyHZtWsXISRNwOKw69evt8YCtm3bZnbs2OEs' b'SzIDxFn8Xjds2OCMxYWh43ykKqm5yBbAhBBCosMVjwtDx/lIlUzLhRBCSHqj43ykorkQQkj2' b'ouN8pKK5EEJI9qLjfKSiuRBCSPai43ykorkQQkj2ouN8pKK5EEJI9qLjfKSiuRBCSPai43yk' b'orkkBzYie/vtt4u1OVgYPPfcc/Z82IjNlU8IIRod5yNVqs1l06ZNzheBhI0bN9pg6arbuXNn' b'vxzeTpX0WrVqxR0jEXir9fnnn487JnCVTUS/fv1uq9+gQQO7RbKr/L59+5x717vKFoaui10x' b'C9vaePTo0XHlNWfOnHHW0Vy+fNkMGTLEWZ8QktnoOB+pUm0urmDmonfv3rfVlVVdAbbylfRR' b'o0bF1S0KfUzgKpOIZ599Nq4uTC5YRu/5L2ALYqnTrVu32/ILY9myZX7dmTNn3pZ/8uRJc+XK' b'lbi0RPv16zJFMXnyZOcxCCGZi47zkSoqc7l69epteb169YoLblhSRufrPL13/YEDB/z0+vXr' b'x9URDh06ZG7evGnLDBo0yE9v3bq1X3fLli1xdYri9OnTft1r166ZTz/9NC5/xIgRfj7QeRq0' b'pqTMjRs3nGXAypUr447XqFGjuPyXXnrJtjokP/h5dAsP68DpPAGmLWWAqwwhJHPRcT5SpdJc' b'unTp4getVatWOcvMnTvXLzN79uy4PEkHxUnX4ClcyowbN85PX758uZ/evn37uDqFMXbsWL8e' b'jMVVBhw7dsyWgbElGhdp2bKlfyy0zlxlmjVr5pcBrjJConLjx4/306dNmxaXp0lUnxCS+eg4' b'H6lSaS5YwVOCVocOHZxl6tat65dBa0PSO3bs6KevW7fOT3/vvff8dIxvSLoGYxTIR6sAX3Xr' b'RlozoFq1anH1CkPqAFyDq0xxweeRY8GAXWX0dbZo0cJZRtAtKrRWJP348eN++gsvvBBXR1i6' b'dKlf5ty5c84yhJDMRcf5SJVKc5GgBVz5AGMTUgbBUNITjbfoFgS6xzCege6oqVOnmm+//dbs' b'3bvXzwdYalzqAp1XFFIH3V+ShvEVfbySoM/x9NNP35aPGWiS7+pODCKtJfD+++/76ZIGxowZ' b'Y/r06WMmTJhgZsyYcVuXG3jjjTfijksIyXx0nI9UqTIXDITrwOUqA/S4y+bNm/10XVePt2Ds' b'QOcl4vz586Zv375+PYBuMFdZF4sWLfLrDRgwwE+HgeljlgR9Hlc+rlvy58yZ4yyj0ccTs/r4' b'44/tz7oF5AL5mImm7zEhJHvQcT5Spcpc9EBxovEWoJ+6xQxefPFFPw3o8jodLYrXX3/djk9c' b'vHjRT//iiy/i6girV6/2y6DF4yrjAlN9pR5aSa4yxaVTp07+sRDUXWXQupAyAwcOdJYR2rVr' b'55fFDDJJnzRpkp8Oo8Rkidq1a5tZs2bZNJhKsFVHCMk+dJyPVKkyF7y/IsFNd2tp2rRp45cB' b'kt6jRw8/bc2aNX66nv104sQJP12QPBDMK05+IvT1wKBcZcDhw4fteyWYrvzJJ584y+hxqETj' b'LbqlVJgxAykH9AQFTFeW9ODYElpDkjd8+PC4PEJIdqHjfKRKlblI8AKufD2QD2A0kqe3aNUT' b'ASZOnOinY4xF0gU85Uv+9u3bb8uXPJcxFYa0pKSLqUqVKreV0a0NEMwXilNGuhTlfGhxuMrp' b'AXuMP+k8SQc63ZWPt/5dZQghmY+O85EqFeYiwRFTdhEg8YSOt+3RAhg8eLB9c14Ht6FDh8bV' b'R5oEVp2O2WRSp06dOnF5guQDPUAtrSRc08GDB+31fP311/YdGA1aDej6evfdd+OOiy4kfWwM' b'kKNbDsfR1wVc5iPocq58QU+ZBmhtYGUAMH369Li8oFl+8MEHft7Ro0fj8gRtxAUFBc4yhJDM' b'R8f5SJUKc9FjFIWBoIhAqOu+9dZbcWV0XqJ0DYzKVQ5dVjq9KNCy0scF27Ztc5YVEMgLGxhH' b'F5SUxbFcZTS6+yoReJclWE+PLcGIgvmCPk7Tpk2dZQghmY2O85EqFebSvXt3O3CMFxnRfYXu' b'LAww42kfLYPmzZs764F33nnHzshCUOzZs6efjtbQ/PnzbfrIkSPj6gTBy5hTpkwxS5Ys8dPw' b'8zfffGOvR64pESinj6epWbOmvYatW7fa9cWwdhoCPNJd5TVyX7Cki54yXBj43FjuBl2FOB9a' b'fXjxFCsNuMoDGCymG+M+FNaKQpcjPiuuybWGGiEk89FxPlKlwlwIIYSkBzrORyqaCyGEZC86' b'zkcqmgshhGQvOs5HKpoLIYRkLzrORyqaCyGEZC86zkcqmgshhGQvOs5HqpKaC9aq0u9JEEII' b'ST2ueFwYOs5HqmRaLlh+BOto7dmzhxBCSIpAnMV2Inrl+OKi43ykSsZcCCGEpDc6zkcqmgsh' b'hGQvOs5HKpoLIYRkLzrORyqaCyGEZC86zkeqVJoLFlAMLkcPsAhjjRo1nHWCYIVf7Ft/9uzZ' b'ImdKYFfG69ev2w27sM1xovJYfh970+OYUk5vqIVFNiUf58YOj/gqXL582Vy4cMHW05uH4RhI' b'Qz3sjKnroQ7SMSiHxTGlTmGsXbvW1i3OZ8e2BsX57B07drzts7/22mvOsgC7g6I8Nh+7ceOG' b'adSokbOcgK0ScFxsbeDKB9jyAPcGx3PlE0LCQ8f5SJUKc9E7KRZGcB+XIL17976tTqItjAE2' b'CAuWf/nll28rFywDispPxFdffeXXGzdunLNMIvQ5g7ju4eeff+4sCzCbJFj++eefv61csAwI' b'lhGqVq16W9l58+Y5ywIYjy6LXTdd5SQfhuXKJ4SEh47zkSpsc8ES7jrAfPnll3H5n332WVz+' b'xx9/HJcv6H308dSPp3J8j1aFqzyQ8thXBU/b+D64xS9aA0hHywJP+fgeWzLrMnIcoNOLAvvT' b'SL1Em5nhqR1P7CgD83SVeeWVf1wDWi5oBeB7bFngKg+kvP7swRaJbD2Nzy6toUT7+AM5Jloj' b'+B3g+2PHjjnLAuzVjzJolcg1v/DCC3FlsFWAHLd///5xeYSQ8NFxPlKFaS4IqBI4AAzCVQ5B' b'BQEO+5MkCrCyEyXAzxKQUSdYFmDXSSmPvUkQ4PC9Ni99fdgTRsxF7/GPbiMpg2Ap6cVB6gFX' b'PsCTv5TBjpeuMpIPQ9U/Y757sCx4++23/TJo8Yi56D1j0OqRMvjs586ds9/rbaQ1eqtpGAT2' b'8pefXeWB5GvQotJlxNxBor8PQkh46DgfqcI0l9OnT/uBA1sGu8oUBzxNy3H+/ve/2zQJhiBY' b'HiBQS75ePaBFixZ+GUnDOAm2KJaf9XHk6R5gX3ykYQMzBPDq1atbsFvmhx9+GFcP2w9LvXXr' b'1sXlCdgSWcoA11gHupIkH91SSJNWAwiWB2PHjvXz9Wdv3LixX0bSsH2ybj3q4wjY1Ezyhw0b' b'ZtOwwZmkoWUVrIMdOCV/xYoVcZ9Dj69JGtD1CSGpQcf5SBWmuYQRONCKkGNgMFnSEbAk/bnn' b'nourA44cOWLz0O2En6Us9u3Hz9jFUtLwM3ZzxPdo4cgxdL3ioOtJlxBaXGhlHThwwHYh4Xpk' b'4Fzj2vkR1yr5ehfONWvW+Om6vCDdcfv27bM/S9lOnTrZn7Ejp64v14rWoxxDwM6XUlZ3F2Ky' b'hKR369Ytrg5A96fkw7yQJj+jhYifdVennghBCEkdOs5HqrDMBS0MCRynTp1ylimKp59+2j9G' b'cEYVWiCSh0Cn84DkYWtl/bNsqSw/Y8tg/TNMRo6BloSkSx4C89KlS83ixYstCMz4edq0aX49' b'fbzCWLBggenTp09cPUG3ONAS0Xl6nKJly5ZxeUDyZD99+VlmdsnPgwcPjvsZrRE5hiBjJcHu' b'LCD1YPTBvB07dvj5kgaDlTR8Pvwu5GfX5yCEhI+O85FKTvrUU08lZS46MKN7zFVGwJMtulGC' b'6TJWANDnv3LlSjsDDE+5mMIreQjSul79+vX9vE8++cSmyc8wE6zHIz8jr3bt2v7PegYWZq9J' b'Ovbcl/Si0KYYnF6LCQiSN3DgwLg8jYwpAXSryWfHWAdaJJI3Z86cuHp6htYHH3xg0+Tn4cOH' b'm23btvk/I0+POwUnHeCcSJeWF8wUpoHfxaZNm/x66KbT9YDk6c//0ksv+en4/bkMiBCSWnSc' b'j1T/63/9L3vSP/zhD4+4LuxOkMBRWPCQgXbw7bff+ukYC9D1CwMznfQxg11eQGaXaaS7Rg8q' b'S3kgXWsgOMupMHSXEAJ0MF8/wbdv3/62fD1YXhTB6bswAMmTND0ZQpAxIj1QL+UBrkuXLwpd' b'F2Mqkh40fn0+Ad2EugwhJDU88cQTP0Z8LxVzee+998Rc7ndd3J2gB+IxhRaD4JKHgXCMQUi+' b'jI2AVq1a+em7du3y04MkGtSXAW89hiDjELgOfMWTt+TJMQ4fPuynSboEZp1eFLp1IN1wGrxv' b'IvnBY7dt29ZPx3F0nkZe2gzWl24s3VqUiRVyXxDgJU+OIeMzwXSAlpjOE7SRYZKDpGOKtKTX' b'q1cvrg5AOq4Tvx98fyetQkJIyUGjAfH9L3/5S/TmIvIcLt91cXcK3rOQQJMIjFlIebzkqPP0' b'sYLoGUgfffSRTdPvhCD4SVn9zgmQdD1TavTo0X66Hg8oDlu2bPHr6nRJC6KvXYwuOMYTrKPR' b'XXu1atWyaa+//rqfpluBMsVakHS8gCpp6DKTdF1WT18Ools3+n0jXV+XF5YtWxZXRrrvCCGp' b'5cknn6wUC/GlZy6Q6+JKAgbfEQz1FFp0OeGJNdjdhBlJMAK0IlxPvRq8k4HWD8rLTCi0ejCB' b'AHvLYHqxlMVgNc4J8O6KpH/99de2LJCpvgBTmXFcjA2gGwtP9i4KCgqsgUqAx0uaaFGhTvBl' b'TA3GmHBOlJMWFrrDcE5co752F1jeBZ8d3WLStYaJDfjsOIaeGo2JCPLZ0TKSdEwrxjWgvHx2' b'mAy6qbBMT3AiQRA8CKAurkO/qY+WEn5/mNWmy2twz3D/8NWVTwgJn5/+9Kd3xcJ76ejpp5+2' b'rua53A9dF0gIISTzQFz/61//WrqtFujXv/51jusCCSGEZBZ//OMf82KhvXT1zjvvWHf73e9+' b'95DrQgkhhGQGv/3tbx9DPK9Zs2bpt1oguRDXxRJCCMkMdDxPJ9FgCCEkQ/nXf/3X0h3EL46e' b'fPLJH7sunhBCSPrxb//2b2nXWkkozJN2fQhCCCHpwR/+8If7YiE7Y+S7oHfxFf/4xz+yJUMI' b'IWmAF49/8qc//emeWIiGMqfVkkh//vOff+CZTQ4hhJDo8Awl5/e//73LRDLbWORlS4qiKKp0' b'FYvHjMkURVFUaatcuf8fa0AIMA81SxkAAAAASUVORK5CYII=') index.append('FILMSTRIP') catalog['FILMSTRIP'] = FILMSTRIP #---------------------------------------------------------------------- DIA = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAAJYAAACKCAYAAABIFbMCAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAEAAAABAABGSOaawAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'ABD3SURBVHic7ZpLjBzHecd/X1X3PHaGuytS5kOUJUqUuZRpWZYoiaSl2Gs7EBkptoMItJEE' b'iX1IEF8SIICRADkEMpBTHqf4kAD2xQGcwHnAsPyinIMcOLYpibFiWxQpKhRJKXxz36+Z6a4v' b'h1kud3anZ5omm7Tp7wfMofur/tfX1f/pqq4qec8DD6qKkFQ3IKGJXxjjMmlpGI0q+NYMrjlJ' b'WllLcBXiudOoL5NUbudmEDXGkWSOVnUDoinRwkXSqEYoDxPNn0NCSqt2R+b1Lm3gGuOE0hpC' b'VOtV1SQQsmSAoW4BCS2i+fOEqEZaHiaav4CEJq3a5ry3mAsBVAOIA1VEBL2O+tHcOdCUpHYH' b'EhL8wsWlWFoaRKMBXDKHb4yTloYJca3tDYmIOpRUEU2Xn7iGtNpaKlHPUi6ZAxGCryKaIGkT' b'9aW+110b7dxEszyzRFfj/FygAd8YR50nLQ3hG+OIpiTl28AV0Xad3hC0pzuuWwYumVuRR8A3' b'pwhxjVAaRJFV10jaQNJG+3oE15wiRDVcY5K0su56pXZL4kIDNAViANLK2vbbI50ndWtubnJA' b'lMZ1QPCtGVQDIRpYenOsRJJ5vEtWq6jiG+NdK3CtGUQTkvJqo6hESEhQcaiLUXGgKbLag13x' b'yRyXeyoXmkhjHELaWaY5CQhpaRA0xTenQBwhGoCQ4hvjhLiOujhfpVeBpI12u2iXNrtGVBX1' b'JSAsvuXLS+evFyGuA9p+huhimyW4sNobLjSQloIqCEQhroMG4rkzS+Mm35rpaiyXzAPzq86L' b'COmK8Zaq4pvjhHiQEA90TVwEcI72cEURDYSoAq1Wrht3rekrWqGFhMvXXXGmJHPt49IgogGX' b'zC2OfW7Dtabbb1VfgSKMpQmSXH9TAagrL94bEMf45gQSWqSl4etWR4jb48949jTqIpLqelxr' b'FprdXzqyzBvXpStUWPrHLFUEpNHGrl3glescirRLiCdEA7jmDOqv/0O+5XB+abigCCFe025r' b'cTc5sTaFjZDbL+Q+fZoIaXntlWvi+uUhg5GD5X9aFX8TM1lNtrFEEMIXVXgeiTZqVN8CgFPR' b'NOwUwuO0+7A8nBf4K1U51VEFRIr+CsJn6OvCJV5TX/4GuI6WVKFKaH7cpc1NOXVQiX6c+oGX' b'HO7lVOXSstCgSvh9QXbn1UL5Ck6/RnBNJBrQqP4gQBDd5JOFZ9A0718mgH5e4QeirnPA6PRe' b'lD8F1na/dBUzqvo3gju8QkcIPIzwJ0App1YT+DN1UaJR/V6V6Dgq51C/GV/5DOnCyPLCMrJr' b'r6KKb06Ai0njOi6ZQ9Pm1468cvDjWbVsf+QDf6+++od5MhKRZ4788Nv/nhUf2bX3X4Fn8mhF' b'jne9+oMDb3SPjkbvfqj5NiIb2h8l4FvTgJDG9fYUQ2sGfIngq+P1pHTnoUPPzXVTunfnrw7F' b'kTsDUs2R1qGjBw88Ssb8zMj73v9xJ+GroTRIv/+PwJeOHDzwqaz4tl17f1fgSzlyQuCzRw4e' b'+Nus+MiufX8N+tl+Or45Cc798eFD3/+7rDI7Ht5zREPaNpeLcKIpQiCUBglRtT335Mv40uA/' b'96zMlf6zPRfU/+dVjvTSkpAey6UVQjPbVAAvJCGuvnz5PkRTQjSwdF/Q7m7VlZCQvp1lKoDj' b'h/5jEg2n8+QF6Rv0mPSr+8Y3Na4jGvpqaUiP9WorvBzJ2+5I6/Xe7Z68nkcnxHVCPPhcL600' b'WvN8KA0u+miAKJo727VgiGoPA/+UJaSNyYejdPUXYteypTV3AYez4r41uUeSPFrS97XtGuMP' b'uS5ftKsLxlv7FYkXLr6T0P+rTn350X5SWe28kuAG9vSKu/mx+6JW5v+hg9RXHwQyDSGtycd8' b'rnYH9WvWAyey4r45tluShSt55lI1jKvEjGUUghnLKAQzllEIUVoa7BoQ8ae6BpauLJ9Kc86Q' b'u9SP9YqnrnJcSvEH++kI9B1Jqx84lfpK9p6ZK2oX+pUIcW1cVTf0VRJ/old8cnIyjQfX908J' b'UNybPXOKBi6kOXd+OO/f7lkgqp5Icy5lJUTTveLBlY9TKi19xEQh7r4SLnC6l1AaDZzOO6cZ' b'nEz2LFCqnQp5Fk+VtF+RNK6dzjnTeqlfgTSqTwD9jQU9H+DQ0FCYiXLuOFB6/qFDVL0krtyr' b'yJWyjp6fouoqb6vP+QyDzvSMx7VTy/2Q3RVq70976RPvKBu7nmWDhnxagmf//p5rFw7ytbrk' b'mnHOpaV9yrVa63K3Fa5fu6f5tfo8o9Cnro56Y9+vbEcbZBpLRT+R9RBHR0cjFT6ZNylC+O2s' b'0I7R0TrIx3IqRdtPTn8iK3j/+5+6W+HxXErK9vt37304K7xt174ngLtz5vWhHY8+tTEr2Kzy' b'Ozl1QPU3du78aPftIIBTMtuyi9gn4dmuz3jnzp0xyv68Sj7NfoZb3jc6jMrTy8+1l3QykeOC' b'Hl+VLmwF7smb1CI/FjjfoSMIygNAvgFIm6Doiw7peDVre91zJ3A1u9wWBF6kvQ62XKsCPEb+' b'dTSACeBHQmd3rcIQyiPkXwsFOCPw6sqTATYJ7LgKHYBjAidXnlRhG8pdV6n1isDF5ScWn+GD' b'QMe+qT7GMoyfjazPi2Mq8n0Jmm8dwvilRJ1sRPVxgftWxroYS/9yU7X5uRdeeKGYrY/GLcXo' b'6Gh0eqH8OVH+fPn5jq5Q4TuvHzzw5I1Pz/gFR0Z27/0Oykcun+j4YhAlc8+UYfRAVaXDOx3G' b'UpHes+2Gkc2J5Qe2VmgUghnLKAQzllEIZiyjEMxYRiGYsYxCMGMZhWDGMgrBjGUUghnLKAQz' b'llEIZiyjEMxYRiGYsYxCMGMZhWDGMgrBjGUUghnLKAQzllEIZiyjEMxYRiGYsYxCMGMZhWDG' b'MgrBjGUUghnLKAQzllEIZiyjEMxYRiGYsYxCMGMZhWDGMgrBjGUUghnLKAQzllEIZiyjEMxY' b'RiGYsYxCMGMZhWDGMgrBjGUUghnLKAQzllEIZiyjEMxYRiGYsYxCMGMZhWDGMgrBjGUUghnL' b'KAQzllEIZiyjEMxYRiGYsYxCMGMZhWDGMgrBjGUUghnLKAQzllEIZiyjEMxYRiGYsYxCMGMZ' b'hWDGMgrBjGUUghnLKAQzllEIZiyjEMxYRiGYsYxCMGMZhWDGMgrBjGUUghnLKAQzllEIZiyj' b'EMxYRiGYsYxCMGMZhWDGMgrBjGUUghnLKAQzllEIZiyjEMxYRiGYsYxCWGEsXXdz0jB+4VG9' b'fflhh7EEPnRjszFuGaTTOyu7wk9t27XvqRuYjnEL8K7H9j4t8HvLz8nIrr26olwA/bKKfFeC' b'TN7A/IxfMNTpsMAoym8BsjzWzViGcc3YV6FRCFGP2DjoFxC5tPykBLw6Pozykauo5wTwjwiz' b'HWeVEvAM8OBVaB1C5KugrU4trYN8GrjzKrQOCPJdFQ2dUrxD4A+AwZw6isqXcfqTlQFRtip8' b'Gohzai0IfFGFtzpzUhHkEdrtlZeLgnxBRSdWpBuJypMKH7gKrWMi8mVF5zuUglYQ2S+wY/n5' b'zK5QRZ96/YfPf6t7Hc+6kV0/PAj6SI6EgvP+3te+/82T3YIjj39sDUnjOHB7t/gKztST0n2H' b'Dj0311XrkX0jeD2SQwfge0cPHvgA0PX+t+/e95uq+m/5pPQfjh58/jNZ0W279v6FwOfyKIny' b'R0dePPD5rPjI7r1fQdmfS8u50SM/+NZ3uwb37/fbTk39z0pDZNB0CVteO3TgTLfgA088fVuz' b'lZxg2R/RCUq3nwvpi9n1PBtEw6Gsa5f/VMOFLFMBHP2vr00DR/JpcTjLVABHX/72UVQn8mg5' b'xyEyTAUQJDqYR0dQnMjL2W0FEngxr1bq9KVeWk70pbxaM9Szn+G//Esq8N95dED/L8tUAD/5' b'3jfGQd9Yfk0UzZ7uXro8OAxc6h6EqDH2OOlCrzZYbAnf900UzZ9/QEKrXzHUld7XV2vuzJBk' b'+2WJ1JWf6K1zdr3Lc39AiGt7gC9kxX1r4iGXzGaFV1Rc3w4czArLwuQTvpVPq1S+VALms+JR' b'4+IeSRr9hcT3HV5E8+dHJCRLxzZ4NwrBjGUUghnLKAQzllEIUfCVrgHnomavC9VFl5Tu1y5H' b'xPUdHaqLJ1X8UF8x5yb6FVFfaSla6p9YnPlhAiCVaiPkG7uDRGM9c4LJrHZeXdhP967LX8qr' b'VV1TT3vFA/GYeOlVpI1zmR8Al1EpzaiPapePo7TSfaeMOHp+eqSloZ8qfLB/VvQ1Q1oafhOR' b'u3JovdFXq7J2Bljbr5zCqsnM5SRRZYLKQI6UADjcs67y4BshZ+egQd7qFU9Kgz8VzbcK16CR' b'9IqH8tCrwGN9c4Lz/cqk1dtOoWy4fJx5twuivWblUXrHl9G/nLh8WpJDK099gPQpFy3kvj9U' b'8L3iAZ9by/W5Rwn586r1b4vr0lYAEjrLZBrLJ7IvK3bnnv1VkA8BJM0Fzp98jdnJS8xNjXHu' b'zcMkrY7eb/32XU/uzNLatufXN4O+t1/iACgPb33/k+sztXbte4IVyzCtxjznT7zG3NQYs5MX' b'OffmYdKkCeiHd+zYn9llpj76tVw5AaLsY8Xq/ooCubUQzWx3eNbheDKvVDJfytTaMTpaJ/+S' b'zjvf/ejezBn6kceevEeF+5ef67W7IQG+rkjHa1DQCOWDCFuXTqpy5n9/wqb73svc1CWaC/MM' b'r++YU5tW+DrI9AqtKrAXyDRLF86oyPMoHe4VdAj4KLCq/1INnD3+Kpu2PsDMxAVC0mLw9jsA' b'jiL6PVWXrtDaCDwNvd9EHQgvifJKQDraUzSMIJJnyLCULsh3tL2+ukxHHcKjXN26ahN4Tlmx' b'3ovGtDd1brkKrQmEb6rKTKdWGADZx4olORnZtVddMg+62LbiCNEAkjaQ0ALxhKiaWVvSXGDs' b'zAkGBtfhvGf60hnWbt5KXMo5WM2Ba82ytPriPMFXcekChARcTPBlXKt9vxpVUbnih1ZjnvGz' b'J6kN3w4IM2NnWbf5PqJSOVfdzYU5SuUqiJA0F3BRjHOe5sIcznuiuEyr0R7b+ijG5e/1Vtzj' b'Yv6+AhqQ0AQRQlRbigGoi1HfmbtoiiTtHEJc5/LzVBejLmofAyEaALm2iQBJm4u5LfokWUD0' b'8lBOCHF7/B4BSGsGF5pLiYdoAJfM45JZ1Jd7GisqVVh/9/al44HB7uPmsTMnaMxNkyYt1m2+' b'l7HTJxAn3HFf/z+ga00ji8YPvgK+irRmcelC++Z8Cd9s70lMXYT6K8aKy9WO/GpD+bf1T4+d' b'4+Jbr1OpD7Pujnt4+/Uf4X3M3e/Zzeljr+C8586RnUyPnWPq4mlu23AXMxPnWX/XdibOv8U7' b'7hrJXZdvTgFKWvEQUnxzEhVPiGpL9waQRrXVxgqtpTIa13DJLJI2CFGNEA8sxXo9x7xIaOCb' b'U6hEhGgAn84tmRpxS8a6YfNYc1OXWLtpCyFNaM7PMjC0lpAkkPML52YwO3GBTVvfi2pgfmaC' b'dZu3UqmtIWk1GF5/Jxvuvh/nIyq1QXzU3hWTNBtceOsYzYXMtfJfCm6YsWpDtzN+9iQhTajU' b'BpmfGsPHJZAc8yg3Cec8IaTtrk4cmiY0F+YQcagqjfl2F1WqDCCu3ZRJq4mLIuTn+L5uBDfM' b'WKoBDe39dBoCIaSEtOf83U1naMM7GTt9nLUbt1AffgdzU2MMDK7FRzGlap2F2XYXM3b2JKpK' b'VKqwYcv9bNhyP9U1fafSbml+tpHmz8DaTfd0HG/e9hByjQPJoilX69y5/cpexjvedWXXTm1o' b'3dJ4bX2XsdRtG/PM99663LQn+/NuKuPa+H98kabPnwayCwAAAABJRU5ErkJggg==') index.append('DIA') catalog['DIA'] = DIA #---------------------------------------------------------------------- DIA_S = PyEmbeddedImage( b'iVBORw0KGgoAAAANSUhEUgAAAJYAAACKCAYAAABIFbMCAAAABHNCSVQICAgIfAhkiAAAAAlw' b'SFlzAAAEAAAABAABGSOaawAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA' b'ABICSURBVHic7Zv9bxzHece/M7t777w7kcfjm8QXiTYl2Xq3LMe27LiJo7qI4RptmiCp0yBo' b'gKJN0SSN3bg1XCBo674EyA99R1E0/QMKuGkCt/YPTezGsvUu6oWkKImkKPOdR/JI3sve7kx/' b'OPLEJW9vV5ZGku3nAxDQ7cw+OzP72d1nZ1bswV17pGQMVrgJTJjQChmsYgeSkHoIWmkJ3FyA' b'HaqH4CEYuTFILQgrlMLdQC/OgVk5lMJNYNKGXpiBrUchgkno+UkwYaMUbXXdn9tF8OIcRKAO' b'Qo/WOtQCAOEWBkCiWgETJej5KQg9CjuYhJ6fBhMmStE2v130BQMgpQAYB6QEYwzyNsbXc5OA' b'tGFFW8GEBa0wUymzA3FIPQJu5aAV52AHkhBGtOwG06E7IkkJJu21G26hWeVYkuk1a3ErBzAG' b'oYXBpAVmm5BawHO/W6PcNibdnKlQVZx7AimgFecguQY7kIBWnAOTNqzgJoCrGDunGwyyph23' b'rQXcyq1rh4BmZiGMKEQgDgm2YR9mF8HsYnl/MHAzC6FHwYsLsEMNt6tpH0u4KALSBmAAAOxQ' b'ffnuYedh87q72zgAum3EADBopSVIKSD0SOXOsR5m5aFxa2MUKaEV56oegJeWwKQFK7hRFMl0' b'MGFBMg7JDUjGAWmDbXSwKpqVw+qTigsTrDgHCNtZx1wAwGAH4oC0oZlZgHEIPQIIG1pxDsKI' b'QXLD30FvAmYXy+Miq4zZLSKlhNQCAMTKXT5Y2X67EEYMgCyfQ8iVMbPAxUY3uCiClSQgJcAA' b'XRgxQAoYufFK3qSVlqqKxa08gPyG7Ywx2OvyLSklNHMOwohDGJGqDWcMAOcopysSTAoIPQSU' b'Sr46zkuLN2KJEphY3e+GmczKlX8H4mBSgFu5ldxnE3hpsXxX1UKACrGkBWbdfqkAQPLgSt8A' b'GAY0cx5MlGAHkrftGMIo55/G8hgk12GF0+ClZcCsftNha9y4LY9CCVSumMqBANh6c9VH4I39' b'OCRYuQbTIPQIuLkEqd3+k/yxg2uVdEGCQRh15bFm/C43rIyyDLl8Q/Z4pjEGO1h/Yx8jtpoy' b'ED5Ye9FKpt3FlmzEXSzGcPjwYfngnn3IzmUwMzUJAJAQGLl6mV0Z7Pd9kHhdHZ555ohsqK93' b'bBdCYGBgED97+23mNzdobWnBngeelNJ25lKmWcDZE++xbGbSd7s2t3ehq2OL7OzuQTQWr2wv' b'5Av42TvvsKtXh3zHOvjQAbl/3x5omo6SWcTo0BUAwMJ8Bqfe+zkT1sbHRzU4Z/ilp56S3d1d' b'4OtkmZqZxhtvvMmWl5d9xQoGg/jlI0/Lttb1Uy8SwyOjePOtt5hl2VX3XY+m6/jCl74gdQZM' b'T4yjsbkFdYlNWJibxc/f+gmbHL3qqL8iFisnZit5hmQcux46LL/+299wO9vy33/0I/a/7xz1' b'lWb/1gtfkQcO7Ksa65FDB5FdzOLkqdO+Yv3B7/+eaGpqrFpmffXr8rvf+iZfzGZvNHTl5QQA' b'wDhsIwZoAUQiEbzy6p+KQCBQNdaBg/vlt7/9Ijd95HsdHe343d/5hmRr3zoee7Tyz1OPPib/' b'7oc/4OX7eO1ufurQI/I3v/xF16tsUyKJf/nXf/M1Vr/63LPymSNPV4318MGHIITAf//Pm56x' b'hBHFF1/4mvzs05+tGuvpz31O/slL32ETY9fLsbgOzqQNBgERiEPo4fLckxbEocc/XfNgPdt3' b'rMwFef81NzfXvB01N6d9xdE1BjepAEDXNXR0b5er/WDShtAjlX4BZdEkD6AhGYebVAAQDYeR' b'SNT561865ZRqHXv27IM0YmBSeMZKN9WedG5paZa+x73GWAFAa1OjrzjCiGHv/odrnsMdex8u' b'OxSIQ+gR6HpuomrF4SuXcOjQw66Bhq8MwG3f9czNTqGtrcW1fKjvrM9Y3hfq9cFzzE+s2dFF' b'zzqLY4PQSwXPetcGzjLUmE22bdv3WA319QLPft61fGriA9+xRkeuYN/eva7lVy9d9B0rO59B' b'qqHetXyo74xj3O+NVwjiYweJRSiBxCKUQGIRStDtQLxqQSrdVHPHVLoZbvuuJxKN1SxvaG5D' b'/6VBzzice08CJtNtcm4x55nlJ+vTnrHCyTQWFuY969U3ba75xsQY8z1WDU21P62pSyR9x6pv' b'qP1WmGpu9R0rFKr5eRFSzW1yaORaZdx1YVRfCU9sqv11QWJTA9z2XU84Ulus+nSrr1hc914o' b'SKSaIa55v+lEErUHHQCC8RREznsCMZly//YLADjnvseqPt1cszwai/uOFU+6v8UBwKb6lO9Y' b'wXCodqxG5zl0fRR6zcj6nbEFAMuuXbdk+Vt0FkJAeHxDZftc9LVs73pWyV8sr/ZbN7EQ7TVW' b'ts+xKtf1GHePY63F2wdnH13FOnb8hOtJFELg/WPHfTfqvfffd300FYtFnDl91tdMshACx46d' b'dK07M5vB4OWrvmKNj09geOSaa/mlwcuYzWRcy9fS3z/A5heyruVH33Pv/3pOnTrNzCpfD9yI' b'ddx3rPePHYcQ1Z/Stm3j2PGTfkPhaI1zuJzLobe311HOeg4dcc0PGhsbkU41bCifnJ5hMzMz' b'1XZxZcvmNsTr6hyxJCSuXx9j2UXvycpVOGfo7OxEOBh0xLKEwMjICCsUir5jGYaBrV2d0DXN' b'EcssldjQ8PBN3ZUjkQja27dIbd0MfK6QZ8PD127qO6lEMoHNLS0bdphbWGBjY+O+4wBAUzqN' b'VEP9hljjU1MsM+vvwlmlvX0L6qLRDefw2uh1trTkXL+sKRZBfFiqZsNN6TS2dXfLZMLfGwPx' b'yWR+IYvLlwfZ1NT0hrINYj37+V+Rzz/3rOScprgIb4QQ8j9e/zH76U/fcOQADnt27twhf+35' b'50gqwjecc/z688/JnTt6HCmVw6CD+/fd2VYRHwsYYzhw4IBjm0Os+gb6L1fEhyO1zh165hFK' b'ILEIJZBYhBJILEIJJBahBBKLUAKJRSiBxCKUQGIRSiCxCCWQWIQSSCxCCSQWoQQSi1ACiUUo' b'gcQilEBiEUogsQglkFiEEkgsQgkkFqEEEotQAolFKIHEIpRAYhFKILEIJZBYhBJILEIJJBah' b'BBKLUAKJRSiBxCKUQGIRSiCxCCWQWIQSSCxCCSQWoQQSi1ACiUUogcQilEBiEUogsQglkFiE' b'EkgsQgkkFqEEEotQAolFKIHEIpRAYhFKILEIJZBYhBJILEIJJBahBBKLUAKJRSiBxCKUQGIR' b'SiCxCCWQWIQSSCxCCSQWoQQSi1ACiUUogcQilEBiEUogsQglkFiEEkgsQgkkFqEEEotQAolF' b'KIHEIpRAYhFKILEIJZBYhBJILEIJJBahBBKLUAKJRSiBxCKUQGIRSiCxCCWQWIQSSCxCCSQW' b'oQQSi1CCQ6ylpaW71Q7iI87i0qLjt0Osvv6BO9oY4uNDX98lx2+HWO8ePcrO9p5nd7RFxEee' b'M2fPsaPvHXV4w3oOHZFrN3DOcOjhg3L79h6EQ+E720LiI0Uun0N//wDeP3aCSenQaKNYBHE7' b'oLdCQgm6W0EkEsEThx+XsbqoY7sUEn19fbjYN+A7F0s1NODRRx+RgWDAsd2ybJw8eYqNjl73' b'3eCOjnbs379PaprzmigWivjFL95lmbl537EefGCn3N7Ts+HyWswu4e133mH5fMFXHMbK6cPm' b'LW0byqYnZ/B/777LbNv2FcswDDzx+GNyU8Mmx3YpgeGhYZw8ddr3uMdiUTz5xGEZjjhTGiEE' b'Lpy/yAYuDfoNhaZ0Go986pA0DKcyJbOE4ydOsrGxccd210fhd771Tbl7166qZUJIfP/PX+PD' b'wyOeDeKc4a//8i9EqqG+anm+UMSLf/QyX1pa9oyVSCbwN6/9mQgEAlXLx8cn8fIrr/q6C9/X' b'vQ1//L0XBWPVz9PJk6fZ3/7DP/k6iZ9+8gn5ta9+xTWleP3HP2Gv/+d/+Yr1wpe/JD/zmadc' b'Y/39P/4zO37ilK9Y33vpD8X2nvurlgkp8Mqr3+frhaiGrmv4wV+9JpLJRNXy5VwO333pZb72' b'QuQMEtX+urq6XDvHOUNne7t023ftXywWhZtUABAOBdHS3OQZh0GitaVZukkFAC0tTQiHQ75i' b'dXZ2SjepAKBrW5ev/jFIdHV2uMYBgK1dnb7iMEh0dHXUzHm7urp8x9q6tcs1DmccHR3+zmEy' b'mYSbVAAQjUTQ2Jhy7KPry2NVK+eXl1EXi7kGG+o7xdz2XUuhYHjWmbjSC315wbPe+GCRAag5' b'8NbsEHQpPGNduXCCAb/hGmtxPgM//QOAqwPn8OQTj7uWjw5d9h1r8voourdudS2/cvGM71hW' b'qYSA4T7+Ixf9ncNFc9azzuzwBej5GxPslLwTSiCxCCWQWIQSSCxCCbrQQlULNMN1igsAEK1L' b'SKGFPF97A8Hq8dcSiiaQyxd91It71uHBKKxSybNetC5Z8yVANwJwG5v1RGLub0wAEI5EfMcK' b'eiyjRerivmNpmuYRy985DIaiXlUQiNShYFqV37odaqgezEOIlo77cfGq9xtFMJH0rFPfuhXT' b'S94TiKnN3Z7LT3q8BcVl7zmx1s7q8zurRGIxuI3NhlhbOmuWp5vbfMeqTzXVPlZHN+zQaV+x' b'OK/9QGruuB+Xr894xomkGj3rJFu6MFe4cTzXI9ui9iu7V/kqQngLI25rLH8z3MKufUxh+WsT' b'UJ5srIUt/C/HCmHVLvc5g1+O5dHH2zRWwMbxchXr3Dn3z2fMUgl9/f0MACyzgKmRPiwvzCKX' b'zWBy6CKs0o3HWnZxEcPD11wblJmfx+h1f0s6wyOjbGFx0bX80uBlrF+GKRXzmBruQy6bwfLC' b'DCaHLsK2TPT19zHLch/Y3hr931C39zzWr+6v5ey5835DoffCRdfjCiFx4cIF/7Fq9KFYLGLg' b'0qCvPmYyc/jgA/cZ+umZGYxNTDi2uS7pcM6xd89uWVfnzGuEsDEwMMCmptfcQqXE+JVzaOne' b'jVx2FmYhj2R6c6U4FApiz+5dMhSKOGKVSkWcP3+RZWvIsp5EMoEHdj4gDd2ZA+bzOZw528tM' b'09ywj5QCE1cvoGXbLizNT0NYJcRTrWhubsJ993VLzpy5yMLCPHp7zzOvO9Fauro60L65XWLd' b'bP7ExPhNrckxxrBz5w6Zakg5+yAEhkaGb2pdVdc17Nm9W8ZidY7ttm2hv3+Azcx6T3yuEolE' b'sHvXAzIYdOaAplnAufMX2PolOdZz6IjkVh6QK1cv4xB6BMwugokSwDQI3T2htMwCMuPDiMQb' b'wDUNi7PjqG/bBiPgL8H0Ay8tozLhzjUILQxuFwBhAdyA0ILgpfKsr9TDkGtEKRXzmJsYQTSZ' b'AsCwlJlAQ1s39EDQ17HNQg6BYBhgDJZZANcNcK7BLOTANQ26EUSpmAcAaLoBrtV+6XHv40r7' b'tRAgBZgwAcYg9GilDAAkNyA1Z9uZtMGschuEEcPq+ZTcgOR6+TcAoUcAdmsTAcw2V9q24olV' b'AJOrj28GYZQTfR0AWGkJXJiVhgs9Am7lwa1lSC1YUyw9EEK6Y3vldyRefV0wMz6MYm4RtlVC' b'Q9tWZMaGwThDa/cez87w0iLYivhCCwFaGKy0DG4Xyp3TAtDM8pKQzXXINW9DRjDsaF804S+J' b'BoDFzCRmRi8hFEuiobUL1y+dhqYZ6HjwEYwNngHXNGzuOYDFzCSyM2PY1NSOpfkppNu3Y35q' b'FI3tPb6PpZlZABJ2SAOEDc1cgGQahB6t9A0AbD26USxRqtSRRhTcWgazixB6FMKIVMpqnUe/' b'MFGEZmYhmQ6hR6DZuYrUYLwi1h2bx8plZ1Hf0glhWzDzy4gk6iEsq/w9yD3K8vw0WrbthpQC' b'+aV5NLRtQyhaB6tURDK9GU0dO8A1HaFoHJpeXpOzzCKmRwdhFnJ3ufV3lzsmVjSRwtzECIRt' b'IRSNI5/NQDMCWJ+T3EtwrkEIu/yoYxzStmAWcmCMQ0qJ4sqiayAUAVt5tbdKJriuo9aXE58E' b'7phYUgrIlddfKQSEsG/q1flukGjagszYVdQ3dyKWbEQum0EkXg9NNxAIx1BY+SIjMzECKSX0' b'QAhNnTvQ1LkD4Tr3T4U+CXy4TPNDUN/i/Dao7f59YLeYSKomGI5h8/aHKr9b79tb+Xc00VDJ' b'19JVcqlNze3qG3gPc9fO7L0uFXFr/D8BY3BAvZ9bbQAAAABJRU5ErkJggg==') index.append('DIA_S') catalog['DIA_S'] = DIA_S photofilmstrip-3.7.2/photofilmstrip/res/cursors.py0000644000232200023220000000514313560357351023115 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # import wx DATA = [[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], [2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 2, 0, 0, 0, 0], [2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 2, 0, 1, 1, 0], [2, 2, 2, 2, 2, 2, 2, 0, 1, 1, 0, 2, 0, 1, 1, 0], [2, 2, 2, 2, 2, 2, 0, 1, 1, 1, 0, 2, 0, 1, 1, 0], [2, 2, 2, 2, 2, 0, 1, 1, 1, 1, 0, 2, 0, 1, 1, 0], [2, 2, 2, 2, 0, 1, 1, 1, 1, 1, 0, 2, 0, 1, 1, 0], [2, 2, 2, 0, 1, 1, 1, 1, 1, 1, 0, 2, 0, 1, 1, 0], [2, 2, 0, 1, 1, 1, 1, 1, 1, 1, 0, 2, 0, 1, 1, 0], [2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 0, 1, 1, 0], [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 1, 0], [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 1, 0], [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0], [2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0], [2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0], [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] __CURSORS = {} def __MakeCursor(data): img = wx.Image(16, 16) img.SetMaskColour(255, 0, 0) for px in range(len(data)): for py in range(len(data[px])): val = data[px][py] if val == 2: img.SetRGB(px, py, 255, 0, 0) elif val == 1: img.SetRGB(px, py, 0, 0, 0) elif val == 0: img.SetRGB(px, py, 255, 255, 255) img.SetOption(wx.IMAGE_OPTION_CUR_HOTSPOT_X, 8) img.SetOption(wx.IMAGE_OPTION_CUR_HOTSPOT_Y, 8) return wx.Cursor(img) def GetNW(): if 'NW' in __CURSORS: return __CURSORS['NW'] result = [] for line in DATA: tmp = [] for value in line: tmp.insert(0, value) result.insert(0, tmp) cursor = __MakeCursor(result) __CURSORS['NW'] = cursor return cursor def GetSE(): if 'SE' in __CURSORS: return __CURSORS['SE'] cursor = __MakeCursor(DATA) __CURSORS['SE'] = cursor return cursor def GetSW(): if 'SW' in __CURSORS: return __CURSORS['SW'] result = [] for line in DATA: tmp = [] for value in line: tmp.append(value) result.insert(0, tmp) cursor = __MakeCursor(result) __CURSORS['SW'] = cursor return cursor def GetNE(): if 'NE' in __CURSORS: return __CURSORS['NE'] result = [] for line in DATA: tmp = [] for value in line: tmp.insert(0, value) result.append(tmp) cursor = __MakeCursor(result) __CURSORS['NE'] = cursor return cursor photofilmstrip-3.7.2/photofilmstrip/lib/0000755000232200023220000000000013560357432021015 5ustar debalancedebalancephotofilmstrip-3.7.2/photofilmstrip/lib/common/0000755000232200023220000000000013560357432022305 5ustar debalancedebalancephotofilmstrip-3.7.2/photofilmstrip/lib/common/__init__.py0000644000232200023220000000017113560357351024415 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # photofilmstrip-3.7.2/photofilmstrip/lib/common/ObserverPattern.py0000644000232200023220000000132713560357351026007 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # class Observable: def __init__(self): self.__observers = [] def AddObserver(self, observer): if isinstance(observer, Observer): if observer not in self.__observers: self.__observers.append(observer) else: raise RuntimeError() def RemoveObserver(self, observer): self.__observers.remove(observer) def Notify(self, arg=None): for observer in self.__observers: observer.ObservableUpdate(self, arg) class Observer: def ObservableUpdate(self, obj, arg): raise NotImplementedError() photofilmstrip-3.7.2/photofilmstrip/lib/common/Singleton.py0000644000232200023220000000071313560357351024622 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # class SingletonType(type): def __init__(self, name, bases, dict): type.__init__(self, name, bases, dict) self.instance = None def __call__(self): if self.instance is None: self.instance = type.__call__(self) return self.instance class Singleton(metaclass=SingletonType): pass photofilmstrip-3.7.2/photofilmstrip/lib/__init__.py0000644000232200023220000000017113560357351023125 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # photofilmstrip-3.7.2/photofilmstrip/lib/jobimpl/0000755000232200023220000000000013560357432022451 5ustar debalancedebalancephotofilmstrip-3.7.2/photofilmstrip/lib/jobimpl/VisualJobMixin.py0000644000232200023220000000612213560357351025727 0ustar debalancedebalance# -*- coding: utf-8 -*- # # Copyright (C) 2018 Jens Goepfert # from .IVisualJob import IVisualJob from .IVisualJobHandler import IVisualJobHandler from .LogVisualJobHandler import LogVisualJobHandler class VisualJobMixin(IVisualJob): def __init__(self, name, maxProgress=-1, visualJobHandler=None): IVisualJob.__init__(self) self.__defaultVisualJobHdl = LogVisualJobHandler() self.__visualJobHandler = [] if visualJobHandler is not None: self.AddVisualJobHandler(visualJobHandler) self.__name = name self.__maxProgress = maxProgress self.__progress = 0 self.__info = _(u"Waiting...") def __NotifyHandler(self, funcName, args=None): if args is None: args = () for hdl in self.__visualJobHandler: if hdl: func = getattr(hdl, funcName) func(self, *args) def AddVisualJobHandler(self, visualJobHandler): assert isinstance(visualJobHandler, IVisualJobHandler) if self.__defaultVisualJobHdl in self.__visualJobHandler: self.__visualJobHandler.remove(self.__defaultVisualJobHdl) self.__visualJobHandler.append(visualJobHandler) # if a new visual is added, notify it about all fields possible # for an inital update visualJobHandler.OnHandleJobUpdate(self, ("name", "maxProgress", "info", "progress"),) def RemoveVisualJobHandler(self, visualJobHandler): if visualJobHandler in self.__visualJobHandler: self.__visualJobHandler.remove(visualJobHandler) if len(self.__visualJobHandler) == 0: self.__visualJobHandler.append(self.__defaultVisualJobHdl) def _VJMBegin(self): self.__NotifyHandler("OnHandleJobBegin") def _VJMDone(self): self.__NotifyHandler("OnHandleJobDone") def _VJMAbort(self): self.SetInfo(_(u"Aborted")) def GetName(self): return self.__name def SetName(self, name): self.__name = name self.__NotifyHandler("OnHandleJobUpdate", (("name",),)) def GetMaxProgress(self): return self.__maxProgress def SetMaxProgress(self, maxProgress): self.__maxProgress = maxProgress self.__NotifyHandler("OnHandleJobUpdate", (("maxProgress",),)) def StepProgress(self, info=None, progress=1): notifyFields = ("progress",) self.__progress += progress if info is not None: self.__info = info notifyFields = ("progress", "info") self.__NotifyHandler("OnHandleJobUpdate", (notifyFields,)) def GetInfo(self): return self.__info def SetInfo(self, info): self.__info = info self.__NotifyHandler("OnHandleJobUpdate", (("info",),)) def GetProgress(self): return self.__progress def SetProgress(self, progress): self.__progress = progress self.__NotifyHandler("OnHandleJobUpdate", (("progress",),)) photofilmstrip-3.7.2/photofilmstrip/lib/jobimpl/JobManager.py0000644000232200023220000002341313560357351025033 0ustar debalancedebalance# -*- coding: utf-8 -*- # # Copyright (C) 2018 Jens Goepfert # import logging import multiprocessing import queue import threading from photofilmstrip.lib.common.Singleton import Singleton from photofilmstrip.lib.DestructionManager import Destroyable from .IVisualJobManager import IVisualJobManager from .LogVisualJobManager import LogVisualJobManager from .Worker import Worker, WorkerAbortSignal from .JobAbortedException import JobAbortedException class _JobCtxGroup: ''' Handles the processing state of a JobContext and manages a queue with JobContexts that are waiting to be processed. ''' def __init__(self, workers): self.__idleQueue = queue.Queue() # holds the JobContext that is currently active self.__active = None # counts how many workers has finished working on the active JobContext self.__doneCount = 0 # if set the acitve JobContext has finshed self.__doneEvent = threading.Event() # a list with workers working for this context group self.__workers = workers self.__lock = threading.Lock() def Put(self, jobContext): ''' Adds a JobContext to the queue :param jobContext: ''' self.__idleQueue.put(jobContext) def Get(self): ''' Returns a JobContext from the queue. Blocks if no JobContext is waiting. ''' return self.__idleQueue.get() def __enter__(self): self.__lock.acquire() return self def __exit__(self, typ, value, traceback): self.__lock.release() def Active(self): ''' Return the currently active JobContext. ''' return self.__active def SetActive(self, jobContext): ''' Sets the given JobContext as active. Resets the counter of finished workers and the doneEvent. :param jobContext: ''' self.__active = jobContext if jobContext is not None: self.__doneCount = 0 self.__doneEvent.clear() def DoneCount(self): ''' Returns the number of finished workers for the active JobContext. Only used for logging purposes. ''' return self.__doneCount def CheckBusy(self): ''' Returns True if workers are still busy with the active JobContext. ''' return self.__doneCount < len(self.__workers) def IncDoneCount(self): ''' Must be called when a worker finished the last workload of the active JobContext. ''' self.__doneCount += 1 def SetDoneEvent(self): ''' Must be called when the last worker finished the last workload of the active JobContext. ''' self.__doneEvent.set() def WaitDoneEvent(self): ''' Must be called to block a finished worker until the last worker has finished. ''' self.__doneEvent.wait() def Workers(self): return self.__workers class JobManager(Singleton, Destroyable): DEFAULT_CTXGROUP_ID = "general" def __init__(self): Destroyable.__init__(self) self.__defaultVisual = LogVisualJobManager() self.__visuals = [self.__defaultVisual] self.__destroying = False self.__jobCtxGroups = {} self.__logger = logging.getLogger("JobManager") def AddVisual(self, visual): assert isinstance(visual, IVisualJobManager) if self.__defaultVisual in self.__visuals: self.__visuals.remove(self.__defaultVisual) if visual not in self.__visuals: self.__visuals.append(visual) def RemoveVisual(self, visual): if visual in self.__visuals: self.__visuals.remove(visual) if len(self.__visuals) == 0: self.__visuals.append(self.__defaultVisual) def Init(self, workerCtxGroup=None, workerCount=None): if workerCtxGroup is None: workerCtxGroup = JobManager.DEFAULT_CTXGROUP_ID if workerCount is None: workerCount = multiprocessing.cpu_count() if workerCtxGroup in self.__jobCtxGroups: raise RuntimeError("group already initialized") workers = [] i = 0 while i < workerCount: self.__logger.debug("creating worker for group %s", workerCtxGroup) worker = Worker(self, workerCtxGroup, i) workers.append(worker) i += 1 jcGroup = _JobCtxGroup(workers) self.__jobCtxGroups[workerCtxGroup] = jcGroup for worker in workers: worker.start() def EnqueueContext(self, jobContext): if jobContext.GetGroupId() not in self.__jobCtxGroups: raise RuntimeError("job group %s not available" % jobContext.GetGroupId()) self.__logger.debug("%s: register job", jobContext) jcGroup = self.__jobCtxGroups[jobContext.GetGroupId()] jcGroup.Put(jobContext) for visual in self.__visuals: try: visual.RegisterJob(jobContext) except Exception: self.__logger.error("RegisterJob for visual <%s> failed", # IGNORE:W0702 visual, exc_info=1) def _GetWorkLoad(self, workerCtxGroup): ''' Retrieves a workload of the given context group. :param workerCtxGroup: ''' jcGroup = self.__jobCtxGroups[workerCtxGroup] try: with jcGroup: while jcGroup.Active() is None: jcIdle = jcGroup.Get() if jcIdle is None: raise WorkerAbortSignal() if self.__StartCtx(jcIdle): jcGroup.SetActive(jcIdle) if self.__destroying: # if in destroying state raise Queue.Empty() to enter # the except section and get FinishCtx() called raise queue.Empty() jobCtxActive = jcGroup.Active() workLoad = jobCtxActive.GetWorkLoad() return jobCtxActive, workLoad # FIXME: no tuple except queue.Empty: # no more workloads, job done, only __FinishCtx() needs to be done # wait for all workers to be done with jcGroup: jcGroup.IncDoneCount() if jcGroup.CheckBusy(): self.__logger.debug("<%s> block until ready... %s", threading.currentThread().getName(), jcGroup.DoneCount()) jcGroup.WaitDoneEvent() self.__logger.debug("<%s> block released continuing... %s", threading.currentThread().getName(), jcGroup.DoneCount()) else: with jcGroup: jobCtxActive = jcGroup.Active() if jobCtxActive is not None: jcGroup.SetActive(None) self.__FinishCtx(jobCtxActive) self.__logger.debug("<%s> set done... %s", threading.currentThread().getName(), jcGroup.DoneCount()) jcGroup.SetDoneEvent() if self.__destroying: raise WorkerAbortSignal() else: raise queue.Empty() def __StartCtx(self, ctx): self.__logger.debug("<%s> starting %s...", threading.currentThread().getName(), ctx.GetName()) try: ctx._Begin() # pylint: disable=protected-access except JobAbortedException: return False except Exception as exc: self.__logger.error("<%s> not started %s", # IGNORE:W0702 threading.currentThread().getName(), ctx.GetName(), exc_info=1) try: ctx.Abort("Error: %s" % exc) except: self.__logger.error("<%s> error while aborting faulty started %s", # IGNORE:W0702 threading.currentThread().getName(), ctx.GetName(), exc_info=1) return False self.__logger.debug("<%s> started %s", threading.currentThread().getName(), ctx.GetName()) return True def __FinishCtx(self, ctx): self.__logger.debug("<%s> finalizing %s...", threading.currentThread().getName(), ctx.GetName()) try: ctx._Done() # pylint: disable=protected-access except: self.__logger.error("<%s> error %s", # IGNORE:W0702 threading.currentThread().getName(), ctx.GetName(), exc_info=1) finally: self.__logger.debug("<%s> finished %s", threading.currentThread().getName(), ctx.GetName()) for visual in self.__visuals: try: visual.RemoveJob(ctx) except Exception: self.__logger.error("RemoveJob for visual <%s> failed", # IGNORE:W0702 visual, exc_info=1) def Destroy(self): self.__logger.debug("start destroying") self.__destroying = True for jcGroup in self.__jobCtxGroups.values(): for worker in jcGroup.Workers(): # put invalid jobs in idle queue to release the blocking state jcGroup.Put(None) for worker in jcGroup.Workers(): self.__logger.debug("<%s> joining...", worker.getName()) worker.join(3) if worker.isAlive(): self.__logger.warning("<%s> join failed", worker.getName()) else: self.__logger.debug("<%s> joined!", worker.getName()) self.__logger.debug("destroyed") photofilmstrip-3.7.2/photofilmstrip/lib/jobimpl/LogVisualJobHandler.py0000644000232200023220000000102313560357351026655 0ustar debalancedebalance# -*- coding: utf-8 -*- # # Copyright (C) 2018 Jens Goepfert # from .IVisualJobHandler import IVisualJobHandler from .LogVisualJobManager import LOGGER class LogVisualJobHandler(IVisualJobHandler): def OnHandleJobBegin(self, jobContext): LOGGER.debug("OnHandleJobBegin %s", jobContext) def OnHandleJobDone(self, jobContext): LOGGER.debug("OnHandleJobDone %s", jobContext) def OnHandleJobUpdate(self, jobContext, fields=None): LOGGER.debug("OnHandleJobUpdate %s -> %s", jobContext, fields) photofilmstrip-3.7.2/photofilmstrip/lib/jobimpl/VisualJob.py0000644000232200023220000000770513560357351024732 0ustar debalancedebalance# -*- coding: utf-8 -*- # # Copyright (C) 2018 Jens Goepfert # from .IVisualJob import IVisualJob from .IVisualJobHandler import IVisualJobHandler from .Job import Job from .LogVisualJobHandler import LogVisualJobHandler class VisualJob(Job, IVisualJob): def __init__(self, name, target=None, args=None, kwargs=None, maxProgress=-1, visualJobHandler=None, groupId="general"): Job.__init__(self, target, args, kwargs, groupId) IVisualJob.__init__(self) self.__defaultVisualJobHdl = LogVisualJobHandler() self.__visualJobHandler = [] if visualJobHandler is not None: self.AddVisualJobHandler(visualJobHandler) self.__name = name self.__maxProgress = maxProgress self.__progress = 0 self.__info = _(u"Waiting...") def __NotifyHandler(self, funcName, args=None): if args is None: args = () for hdl in self.__visualJobHandler: if hdl: func = getattr(hdl, funcName) func(self, *args) def _Interact(self, evtClass): for hdl in self.__visualJobHandler: if not hdl.OnHandleJobInteraction(self, evtClass): return def AddVisualJobHandler(self, visualJobHandler): assert isinstance(visualJobHandler, IVisualJobHandler) if self.__defaultVisualJobHdl in self.__visualJobHandler: self.__visualJobHandler.remove(self.__defaultVisualJobHdl) self.__visualJobHandler.append(visualJobHandler) # if a new visual is added, notify it about all fields possible # for an inital update visualJobHandler.OnHandleJobUpdate(self, ("name", "maxProgress", "info", "progress")) def RemoveVisualJobHandler(self, visualJobHandler): if visualJobHandler in self.__visualJobHandler: self.__visualJobHandler.remove(visualJobHandler) if len(self.__visualJobHandler) == 0: self.__visualJobHandler.append(self.__defaultVisualJobHdl) def _Begin(self): self.__NotifyHandler("OnHandleJobBegin") Job._Begin(self) def _Done(self): if self.IsAborted(): self.SetInfo(_(u"Aborted")) else: self.SetInfo(_(u"Done")) try: Job._Done(self) finally: self.__NotifyHandler("OnHandleJobDone") def Abort(self, msg=None): if Job.Abort(self, msg): if msg is None: msg = _(u"Aborting...") self.SetInfo(msg) return True else: if self.IsDone() and self.IsAborted(): if msg is None: msg = _(u"Aborted") self.SetInfo(msg) return False def GetName(self): return self.__name def SetName(self, name): self.__name = name self.__NotifyHandler("OnHandleJobUpdate", (("name",),)) def GetMaxProgress(self): return self.__maxProgress def SetMaxProgress(self, maxProgress): self.__maxProgress = maxProgress self.__NotifyHandler("OnHandleJobUpdate", (("maxProgress",),)) def StepProgress(self, info=None, progress=1): notifyFields = ("progress",) self.__progress += progress if info is not None: self.__info = info notifyFields = ("progress", "info") self.__NotifyHandler("OnHandleJobUpdate", (notifyFields,)) def GetInfo(self): return self.__info def SetInfo(self, info): self.__info = info self.__NotifyHandler("OnHandleJobUpdate", (("info",),)) def GetProgress(self): return self.__progress def SetProgress(self, progress): self.__progress = progress self.__NotifyHandler("OnHandleJobUpdate", (("progress",),)) photofilmstrip-3.7.2/photofilmstrip/lib/jobimpl/IVisualJobManager.py0000644000232200023220000000034213560357351026324 0ustar debalancedebalance# -*- coding: utf-8 -*- # # Copyright (C) 2018 Jens Goepfert # class IVisualJobManager: def RegisterJob(self, job): raise NotImplementedError() def RemoveJob(self, job): raise NotImplementedError() photofilmstrip-3.7.2/photofilmstrip/lib/jobimpl/__init__.py0000644000232200023220000000007713560357351024566 0ustar debalancedebalance# -*- coding: utf-8 -*- # # Copyright (C) 2018 Jens Goepfert # photofilmstrip-3.7.2/photofilmstrip/lib/jobimpl/PnlJobVisual.py0000644000232200023220000002052113560357351025373 0ustar debalancedebalance# Boa:FramePanel:PnlJobVisual # -*- coding: utf-8 -*- # # Copyright (C) 2018 Jens Goepfert # import wx from photofilmstrip.action.WxAction import WxAction from photofilmstrip.lib.jobimpl.WxVisualJobHandler import ( WxVisualJobHandler, EVT_JOB_UPDATE) [wxID_PNLJOBVISUAL, wxID_PNLJOBVISUALBMPJOB, wxID_PNLJOBVISUALCMDACTION, wxID_PNLJOBVISUALCMDMENU, wxID_PNLJOBVISUALGAUGEPROGRESS, wxID_PNLJOBVISUALSTATICLINE, wxID_PNLJOBVISUALSTJOBINFO, wxID_PNLJOBVISUALSTJOBNAME, ] = [wx.NewId() for _init_ctrls in range(8)] class PnlJobVisual(wx.Panel, WxVisualJobHandler): def _init_coll_szMain_Items(self, parent): # generated method, don't edit parent.Add(self.szTop, 0, border=4, flag=wx.EXPAND | wx.RIGHT | wx.LEFT) parent.Add(self.staticLine, 0, border=0, flag=wx.EXPAND) def _init_coll_szMiddle_Items(self, parent): # generated method, don't edit parent.Add(self.stJobName, 0, border=4, flag=wx.EXPAND | wx.TOP | wx.BOTTOM) parent.Add(self.gaugeProgress, 0, border=0, flag=wx.EXPAND) parent.Add(self.stJobInfo, 0, border=4, flag=wx.EXPAND | wx.TOP | wx.BOTTOM) def _init_coll_szTop_Items(self, parent): # generated method, don't edit parent.Add(self.bmpJob, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) parent.AddSpacer(4) parent.Add(self.szMiddle, 1, border=0, flag=0) parent.AddSpacer(4) parent.Add(self.cmdAction, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) parent.AddSpacer(4) parent.Add(self.cmdMenu, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) parent.AddSpacer(4) def _init_sizers(self): # generated method, don't edit self.szMain = wx.BoxSizer(orient=wx.VERTICAL) self.szMiddle = wx.BoxSizer(orient=wx.VERTICAL) self.szTop = wx.BoxSizer(orient=wx.HORIZONTAL) self._init_coll_szMain_Items(self.szMain) self._init_coll_szMiddle_Items(self.szMiddle) self._init_coll_szTop_Items(self.szTop) self.SetSizer(self.szMain) def _init_ctrls(self, prnt): # generated method, don't edit wx.Panel.__init__(self, id=wxID_PNLJOBVISUAL, name=u'PnlJobVisual', parent=prnt, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL) self.SetBackgroundColour(wx.Colour(255, 255, 255)) self.bmpJob = wx.StaticBitmap( bitmap=wx.ArtProvider.GetBitmap('PFS_RENDER_24'), id=wxID_PNLJOBVISUALBMPJOB, name=u'bmpJob', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.stJobName = wx.StaticText(id=wxID_PNLJOBVISUALSTJOBNAME, label=u'job name', name=u'stJobName', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.gaugeProgress = wx.Gauge(id=wxID_PNLJOBVISUALGAUGEPROGRESS, name=u'gaugeProgress', parent=self, pos=wx.Point(-1, -1), range=100, size=wx.Size(-1, -1), style=wx.GA_HORIZONTAL) self.stJobInfo = wx.StaticText(id=wxID_PNLJOBVISUALSTJOBINFO, label=u'job info', name=u'stJobInfo', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.cmdAction = wx.StaticBitmap( bitmap=wx.ArtProvider.GetBitmap('PFS_FOLDER_OPEN_24'), id=wxID_PNLJOBVISUALCMDACTION, name=u'cmdAction', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.cmdAction.Bind(wx.EVT_LEFT_DOWN, self.OnCmdActionLeftDown) self.cmdMenu = wx.StaticBitmap( bitmap=wx.ArtProvider.GetBitmap('PFS_MENU_24'), id=wxID_PNLJOBVISUALCMDMENU, name=u'cmdMenu', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.cmdMenu.Bind(wx.EVT_LEFT_DOWN, self.OnCmdMenuLeftDown) self.staticLine = wx.StaticLine(id=wxID_PNLJOBVISUALSTATICLINE, name=u'staticLine', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self._init_sizers() def __init__(self, parent, pnlJobManager, jobContext): self._init_ctrls(parent) WxVisualJobHandler.__init__(self) self.pnlJobManager = pnlJobManager for ctrl in (self, self.stJobName, self.stJobInfo, self.gaugeProgress): ctrl.Bind(wx.EVT_LEFT_DOWN, self.__OnLeftDown) font = self.stJobName.GetFont() font.SetWeight(wx.FONTWEIGHT_BOLD) self.stJobName.SetFont(font) self.stJobName.SetLabel(jobContext.GetName()) self.gaugeProgress.SetRange(jobContext.GetMaxProgress()) self.jobContext = jobContext self._actAbort = WxAction( _(u"Abort"), self._Abort, bmp={wx.ART_MENU: wx.ArtProvider.GetBitmap('PFS_ABORT_16'), wx.ART_TOOLBAR: wx.ArtProvider.GetBitmap('PFS_ABORT_24')} ) self._actRemove = WxAction( _("Remove from list"), self._Remove, bmp={wx.ART_MENU: wx.ArtProvider.GetBitmap('PFS_LIST_REMOVE_16'), wx.ART_TOOLBAR: wx.ArtProvider.GetBitmap('PFS_LIST_REMOVE_24')} ) self.curAction = None self.jobContext.AddVisualJobHandler(self) self.Bind(EVT_JOB_UPDATE, self.OnJobUpdate) def OnJobUpdate(self, event): fields = event.GetFields() if "progress" in fields: self.gaugeProgress.SetValue(self.jobContext.GetProgress()) if "info" in fields: self.stJobInfo.SetLabel(self.jobContext.GetInfo()) if "maxProgress" in fields: self.gaugeProgress.SetRange(self.jobContext.GetMaxProgress()) if "name" in fields: self.stJobName.SetLabel(self.jobContext.GetName()) self._SetupAction() def __OnLeftDown(self, event): evt = wx.ListEvent(wx.EVT_LIST_ITEM_SELECTED.typeId, self.GetId()) evt.SetEventObject(self) self.GetEventHandler().ProcessEvent(evt) def Select(self, value): if value: if self.IsShownOnScreen(): self.SetFocus() bgCol = wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHT) txtCol = wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT) else: bgCol = wx.WHITE txtCol = wx.SystemSettings.GetColour(wx.SYS_COLOUR_LISTBOXTEXT) self.SetBackgroundColour(bgCol) self.stJobName.SetForegroundColour(txtCol) self.stJobInfo.SetForegroundColour(txtCol) self.Refresh() def OnCmdActionLeftDown(self, event): self.curAction.Execute() event.Skip() def OnCmdMenuLeftDown(self, event): menu = wx.Menu() mitm = self._actAbort.ToMenu(self, menu) menu.Enable(mitm.GetId(), self.jobContext.IsIdle() or not self.jobContext.IsDone()) mitm = self._actRemove.ToMenu(self, menu) menu.Enable(mitm.GetId(), self.jobContext.IsDone()) menu.AppendSeparator() self._OnMenuActions(menu) self.cmdMenu.PopupMenu(menu) def _OnMenuActions(self, menu): pass def _SetupAction(self): if self.jobContext.IsIdle() or not self.jobContext.IsDone(): self.curAction = self._actAbort elif self.jobContext.IsAborted() or self.jobContext.IsDone(): self.curAction = self._actRemove else: self.curAction = None self._OnSetupAction() curTip = self.cmdAction.GetToolTip() if curTip: curTip = curTip.GetTip() if self.curAction and curTip != self.curAction.GetName(): self.cmdAction.SetBitmap(self.curAction.GetBitmap(wx.ART_TOOLBAR)) self.cmdAction.SetToolTip(self.curAction.GetName()) def _OnSetupAction(self): pass def _Abort(self): dlg = wx.MessageDialog(self, _(u"Abort selected process?"), _(u"Question"), wx.YES_NO | wx.ICON_EXCLAMATION) try: if dlg.ShowModal() == wx.ID_YES: self.jobContext.Abort() finally: dlg.Destroy() def _Remove(self): wx.CallAfter(self.pnlJobManager.RemovePnlJobVisual, self, True) # self.pnlJobManager.RemovePnlJobVisual(self, True) photofilmstrip-3.7.2/photofilmstrip/lib/jobimpl/WorkLoad.py0000644000232200023220000000062213560357351024545 0ustar debalancedebalance# -*- coding: utf-8 -*- # # Copyright (C) 2018 Jens Goepfert # from .IWorkLoad import IWorkLoad class WorkLoad(IWorkLoad): def __init__(self): pass def _Execute(self, jobContext): """ internal - called by the framework """ try: return self.Run(jobContext) finally: self._Finish() def _Finish(self): pass photofilmstrip-3.7.2/photofilmstrip/lib/jobimpl/Worker.py0000644000232200023220000000565513560357351024307 0ustar debalancedebalance# -*- coding: utf-8 -*- # # Copyright (C) 2018 Jens Goepfert # import logging import queue import sys import threading import traceback from .IJobContext import IWorker from .IWorkLoad import IWorkLoad from .ResultObject import ResultObject from .JobAbortedException import JobAbortedException class Worker(threading.Thread, IWorker): ''' A worker thread that processes workloads of a JobContext. The worker belongs to a specific group id that decides which JobContexts are executed. ''' def __init__(self, jobManager, ctxGroupId, num): threading.Thread.__init__(self, name="{0}-{1}".format(ctxGroupId, num)) self.__jobManager = jobManager self.__ctxGroupId = ctxGroupId self.__logger = logging.getLogger("Worker") def GetContextGroupId(self): return self.__ctxGroupId def run(self): self.__logger.debug("<%s> Started...", self.getName()) while 1: self.__logger.log(logging.NOTSET, "<%s> Worker alive", self.getName()) jobContext = None workLoad = None # jobContext = self.__jobManager._GetJobContext(self.GetContextGroupId()) try: self.__logger.debug("<%s> waiting for job", self.getName()) jobContext, workLoad = self.__jobManager._GetWorkLoad(self.GetContextGroupId()) except queue.Empty: continue except WorkerAbortSignal: break if not isinstance(workLoad, IWorkLoad): self.__logger.debug("<%s> Retrieved invalid job object '%s' from Queue: %s", self.getName(), jobContext, workLoad) continue self.__ProcessWorkLoad(jobContext, workLoad) self.__logger.debug("<%s> Worker gone...", self.getName()) def __ProcessWorkLoad(self, jobContext, workLoad): ro = ResultObject(workLoad) try: self.__logger.debug("<%s> processing work load %s", self.getName(), workLoad) ro.result = workLoad._Execute(jobContext) # IGNORE:W0212 self.__logger.debug("<%s> execution done, result = %s", self.getName(), ro.result) except Exception as inst: # IGNORE:R0703 self.__logger.error("<%s> job exception: %s", self.getName(), inst, exc_info=1) ro.exception = inst ro.traceback = "Traceback (within worker):\n" + "".join(traceback.format_tb(sys.exc_info()[2])) if jobContext.IsAborted(): ro.exception = JobAbortedException() try: self.__logger.debug("<%s> pushing result %s", self.getName(), workLoad) jobContext.PushResult(ro) self.__logger.debug("<%s> result pushed %s", self.getName(), workLoad) except Exception as inst: # IGNORE:R0703 self.__logger.error("<%s> push result exception: %s", self.getName(), inst, exc_info=1) class WorkerAbortSignal(Exception): pass photofilmstrip-3.7.2/photofilmstrip/lib/jobimpl/WxVisualJobManager.py0000644000232200023220000000242313560357351026534 0ustar debalancedebalance# -*- coding: utf-8 -*- # # Copyright (C) 2018 Jens Goepfert # import wx from photofilmstrip.lib.jobimpl.IVisualJobManager import IVisualJobManager from photofilmstrip.lib.jobimpl.JobManager import JobManager from photofilmstrip.lib.jobimpl.Job import Job _EVT_REGISTER_JOB_TYPE = wx.NewEventType() EVT_REGISTER_JOB = wx.PyEventBinder(_EVT_REGISTER_JOB_TYPE, 1) _EVT_REMOVE_JOB_TYPE = wx.NewEventType() EVT_REMOVE_JOB = wx.PyEventBinder(_EVT_REMOVE_JOB_TYPE, 1) class WxVisualJobManager(IVisualJobManager): def __init__(self, win=None): self.__id = wx.NewId() if win is None: win = self assert isinstance(win, wx.EvtHandler) self.__win = win JobManager().AddVisual(self) def GetId(self): return self.__id def RegisterJob(self, job): evt = JobEvent(self.__win.GetId(), job, _EVT_REGISTER_JOB_TYPE) wx.PostEvent(self.__win, evt) def RemoveJob(self, job): evt = JobEvent(self.__win.GetId(), job, _EVT_REMOVE_JOB_TYPE) wx.PostEvent(self.__win, evt) class JobEvent(wx.PyEvent): def __init__(self, ident, job, evtType): wx.PyEvent.__init__(self, ident, evtType) assert isinstance(job, Job) self.__job = job def GetJob(self): return self.__job photofilmstrip-3.7.2/photofilmstrip/lib/jobimpl/IVisualJobHandler.py0000644000232200023220000000053213560357351026330 0ustar debalancedebalance# -*- coding: utf-8 -*- # # Copyright (C) 2018 Jens Goepfert # class IVisualJobHandler: def OnHandleJobBegin(self, jobContext): raise NotImplementedError() def OnHandleJobDone(self, jobContext): raise NotImplementedError() def OnHandleJobUpdate(self, jobContext, fields=None): raise NotImplementedError() photofilmstrip-3.7.2/photofilmstrip/lib/jobimpl/LogVisualJobManager.py0000644000232200023220000000061313560357351026656 0ustar debalancedebalance# -*- coding: utf-8 -*- # # Copyright (C) 2018 Jens Goepfert # import logging from .IVisualJobManager import IVisualJobManager LOGGER = logging.getLogger("VisualJobManager") class LogVisualJobManager(IVisualJobManager): def RegisterJob(self, job): LOGGER.debug("RegisterJob %s", job.GetName()) def RemoveJob(self, job): LOGGER.debug("RemoveJob %s", job.GetName()) photofilmstrip-3.7.2/photofilmstrip/lib/jobimpl/Job.py0000644000232200023220000000677313560357351023552 0ustar debalancedebalance# -*- coding: utf-8 -*- # # Copyright (C) 2018 Jens Goepfert # import logging import queue from .IJobContext import IJobContext from .WorkLoad import WorkLoad from .IWorkLoad import IWorkLoad from .ResultObject import NoResultObject from .JobAbortedException import JobAbortedException class Job(IJobContext): ''' A Job implements the JobContext interface and handles the smaller workloads in a queue. ''' def __init__(self, target=None, args=None, kwargs=None, groupId="general"): IJobContext.__init__(self) self.__groupId = groupId self.__logger = logging.getLogger("Job<%s> %s" % (groupId, self)) self.__workQueue = queue.Queue() self.__resultObject = NoResultObject(WorkLoad()) self.__done = False self.__aborted = False self.__idle = True if target: self.AddWorkLoad(SingleWorkLoad(self, target, args, kwargs)) def GetGroupId(self): return self.__groupId def AddWorkLoad(self, workLoad): assert isinstance(workLoad, IWorkLoad) self.__workQueue.put(workLoad) def GetWorkLoad(self): if self.__aborted: while 1: self.__logger.debug("emptying task queue") try: self.__workQueue.get(False) finally: self.__logger.debug("task queue empty") else: return self.__workQueue.get(False) def PushResult(self, resultObject): self.__resultObject = resultObject def _Begin(self): if self.__aborted: self.__done = True raise JobAbortedException() self.Begin() self.__idle = False def Begin(self): pass def IsIdle(self): return self.__idle def _Done(self): try: self.Done() finally: self.__done = True def Done(self): pass def IsDone(self): return self.__done def IsAborted(self): return self.__aborted def Abort(self, msg=None): if self.__aborted: return False if self.__done: self.__logger.debug("cannot abort finished job!") return False else: self.__aborted = True if self.__idle: # Abort() got called while job is idle # Begin() was not called yet so Done wont get called self.__idle = False self.__done = True return False self.__logger.debug("aborting... (%s)", msg) return True def GetResultObject(self): # , block=True): return self.__resultObject class SingleWorkLoad(WorkLoad): ''' A helper class to wrap a simple method call as a Workload. ''' def __init__(self, job, target, args=None, kwargs=None): WorkLoad.__init__(self) if args is None: args = [] if kwargs is None: kwargs = {} assert callable(target), "target must be callable" assert isinstance(args, list) or isinstance(args, tuple), \ "args must be of type list or tuple" assert isinstance(kwargs, dict), \ "kwargs must be of type dict" self.__job = job self.__target = target self.__args = args self.__kwargs = kwargs def Run(self, jobContext): return self.__target(*self.__args, job=jobContext, **self.__kwargs) def GetJob(self): return self.__job photofilmstrip-3.7.2/photofilmstrip/lib/jobimpl/PnlJobManager.py0000644000232200023220000001164413560357351025510 0ustar debalancedebalance# Boa:FramePanel:PnlJobManager # -*- coding: utf-8 -*- # # Copyright (C) 2018 Jens Goepfert # import wx import wx.lib.scrolledpanel from photofilmstrip.lib.jobimpl.WxVisualJobManager import WxVisualJobManager, EVT_REGISTER_JOB from photofilmstrip.lib.jobimpl.JobManager import JobManager from photofilmstrip.lib.jobimpl.PnlJobVisual import PnlJobVisual [wxID_PNLJOBMANAGER, wxID_PNLJOBMANAGERCMDCLEAR, wxID_PNLJOBMANAGERPNLJOBS, ] = [wx.NewId() for _init_ctrls in range(3)] class PnlJobManager(wx.Panel, WxVisualJobManager): def _init_coll_szMain_Items(self, parent): # generated method, don't edit parent.Add(self.pnlJobs, 1, border=0, flag=wx.EXPAND) parent.Add(self.cmdClear, 0, border=4, flag=wx.ALL) def _init_sizers(self): # generated method, don't edit self.szMain = wx.BoxSizer(orient=wx.VERTICAL) self.szJobs = wx.BoxSizer(orient=wx.VERTICAL) self._init_coll_szMain_Items(self.szMain) self.SetSizer(self.szMain) self.pnlJobs.SetSizer(self.szJobs) def _init_ctrls(self, prnt): # generated method, don't edit wx.Panel.__init__(self, id=wxID_PNLJOBMANAGER, name=u'PnlJobManager', parent=prnt, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL) self.SetClientSize(wx.Size(400, 250)) self.pnlJobs = wx.lib.scrolledpanel.ScrolledPanel(id=wxID_PNLJOBMANAGERPNLJOBS, name=u'pnlJobs', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.SUNKEN_BORDER) self.cmdClear = wx.Button(id=wxID_PNLJOBMANAGERCMDCLEAR, label=_(u'&Clear list'), name=u'cmdClear', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.cmdClear.Bind(wx.EVT_BUTTON, self.OnCmdClearButton, id=wxID_PNLJOBMANAGERCMDCLEAR) self._init_sizers() def __init__(self, parent, pnlJobClass=PnlJobVisual): self._init_ctrls(parent) WxVisualJobManager.__init__(self) self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnSelectItem) self.pnlJobs.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.pnlJobs.SetupScrolling(scroll_x=False) self.parentFrame = None if isinstance(parent, wx.Frame): self.parentFrame = parent self._selected = None self.pnlJobVisuals = [] self.pnlJobClass = pnlJobClass self.Bind(EVT_REGISTER_JOB, self.OnRegisterJob) JobManager().AddVisual(self) def OnRegisterJob(self, event): jobContext = event.GetJob() if jobContext.GetGroupId() != "render": return pjv = self.pnlJobClass(self.pnlJobs, self, jobContext) pjv.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.szJobs.Add(pjv, 0, wx.EXPAND) self.szJobs.Layout() self.pnlJobs.SetupScrolling(scroll_x=False) self.pnlJobVisuals.append(pjv) if self._selected is None: pjv.Select(True) self._selected = pjv if self.parentFrame: self.parentFrame.Show() def OnSelectItem(self, event): pnl = event.GetEventObject() if pnl != self._selected: if self._selected is not None: self._selected.Select(False) self._selected = pnl self._selected.Select(True) def OnKeyDown(self, event): key = event.GetKeyCode() try: idx = self.pnlJobVisuals.index(self._selected) except ValueError: idx = -1 if key == wx.WXK_DOWN: if self._selected is not None and len(self.pnlJobVisuals) > idx + 1: self._selected.Select(False) self._selected = self.pnlJobVisuals[idx + 1] self._selected.Select(True) elif key == wx.WXK_UP: if self._selected is not None and idx > 0: self._selected.Select(False) self._selected = self.pnlJobVisuals[idx - 1] self._selected.Select(True) else: event.Skip() def RemovePnlJobVisual(self, pnlJobVisual, layout=False): if pnlJobVisual.jobContext.IsDone(): if pnlJobVisual is self._selected: self._selected = None self.pnlJobVisuals.remove(pnlJobVisual) self.szJobs.Detach(pnlJobVisual) pnlJobVisual.Destroy() if layout: self.szJobs.Layout() self.pnlJobs.SetupScrolling(scroll_x=False) return True else: return False def OnCmdClearButton(self, event): removedOne = False idx = 0 while idx < len(self.pnlJobVisuals): pnlJobVis = self.pnlJobVisuals[idx] if self.RemovePnlJobVisual(pnlJobVis): removedOne = True else: idx += 1 if removedOne: self.szJobs.Layout() self.pnlJobs.SetupScrolling(scroll_x=False) photofilmstrip-3.7.2/photofilmstrip/lib/jobimpl/WxVisualJobHandler.py0000644000232200023220000000642713560357351026547 0ustar debalancedebalance# -*- coding: utf-8 -*- # # Copyright (C) 2018 Jens Goepfert # import threading import wx from .IVisualJobHandler import IVisualJobHandler from .ResultObject import ResultObject _EVT_JOB_RESULT_TYPE = wx.NewEventType() EVT_JOB_RESULT = wx.PyEventBinder(_EVT_JOB_RESULT_TYPE, 1) _EVT_JOB_UPDATE_TYPE = wx.NewEventType() EVT_JOB_UPDATE = wx.PyEventBinder(_EVT_JOB_UPDATE_TYPE, 1) _EVT_JOB_UIINTERACT_TYPE = wx.NewEventType() EVT_JOB_UIINTERACT = wx.PyEventBinder(_EVT_JOB_UIINTERACT_TYPE, 1) class WxVisualJobHandler(IVisualJobHandler): def __init__(self, win=None): self.__id = wx.NewId() if win is None: win = self assert isinstance(win, wx.EvtHandler) self.__win = win self.__win.Bind(EVT_JOB_UIINTERACT, self.__OnInteract) def GetId(self): return self.__id def OnHandleJobBegin(self, jobContext): evt = UpdateEvent(self.__win.GetId(), None, UpdateEvent.KIND_BEGIN) wx.PostEvent(self.__win, evt) def OnHandleJobDone(self, jobContext): evt = ResultEvent(self.__win.GetId(), jobContext.GetResultObject()) wx.PostEvent(self.__win, evt) evt = UpdateEvent(self.__win.GetId(), None, UpdateEvent.KIND_DONE) wx.PostEvent(self.__win, evt) def OnHandleJobUpdate(self, jobContext, fields=None): evt = UpdateEvent(self.__win.GetId(), fields, UpdateEvent.KIND_UPDATE) wx.PostEvent(self.__win, evt) def OnHandleJobInteraction(self, jobContext, evt): assert isinstance(evt, WxInteractionEvent) evt._threadEvt = threading.Event() # pylint: disable=protected-access evt._job = jobContext # pylint: disable=protected-access wx.PostEvent(self.__win, evt) evt._threadEvt.wait() # pylint: disable=protected-access return evt.GetSkipped() def __OnInteract(self, event): assert wx.IsMainThread() try: event.OnProcess(self.__win) finally: event._threadEvt.set() # pylint: disable=protected-access class ResultEvent(wx.PyEvent): def __init__(self, ident, resultObj): wx.PyEvent.__init__(self, ident, _EVT_JOB_RESULT_TYPE) assert isinstance(resultObj, ResultObject) self.__resultObj = resultObj def GetResult(self, printTraceback=True): return self.__resultObj.GetResult(printTraceback) def GetSource(self): return self.__resultObj.GetSource() class UpdateEvent(wx.PyEvent): KIND_UPDATE = 1 KIND_BEGIN = 2 KIND_DONE = 4 def __init__(self, ident, fields, kind): wx.PyEvent.__init__(self, ident, _EVT_JOB_UPDATE_TYPE) if fields is None: fields = [] self.__fields = fields self.__kind = kind def GetFields(self): return self.__fields def IsBegin(self): return self.__kind == UpdateEvent.KIND_BEGIN def IsDone(self): return self.__kind == UpdateEvent.KIND_DONE def IsUpdate(self): return self.__kind == UpdateEvent.KIND_UPDATE class WxInteractionEvent(wx.PyEvent): def __init__(self): wx.PyEvent.__init__(self, eventType=_EVT_JOB_UIINTERACT_TYPE) self._threadEvt = None self._job = None def GetJob(self): return self._job def OnProcess(self, wxParent): raise NotImplementedError() photofilmstrip-3.7.2/photofilmstrip/lib/jobimpl/JobAbortedException.py0000644000232200023220000000016013560357351026712 0ustar debalancedebalance# -*- coding: utf-8 -*- # # Copyright (C) 2018 Jens Goepfert # class JobAbortedException(Exception): pass photofilmstrip-3.7.2/photofilmstrip/lib/jobimpl/IVisualJob.py0000644000232200023220000000127413560357351025036 0ustar debalancedebalance# -*- coding: utf-8 -*- # # Copyright (C) 2018 Jens Goepfert # class IVisualJob: def GetName(self): raise NotImplementedError() def SetName(self, value): raise NotImplementedError() def GetInfo(self): raise NotImplementedError() def SetInfo(self, info): raise NotImplementedError() def GetMaxProgress(self): raise NotImplementedError() def SetMaxProgress(self, value): raise NotImplementedError() def GetProgress(self): raise NotImplementedError() def SetProgress(self, value): raise NotImplementedError() def StepProgress(self, info=None, progress=1): raise NotImplementedError() photofilmstrip-3.7.2/photofilmstrip/lib/jobimpl/IWorkLoad.py0000644000232200023220000000043313560357351024656 0ustar debalancedebalance# -*- coding: utf-8 -*- # # Copyright (C) 2018 Jens Goepfert # class IWorkLoad: def _Execute(self, jobContext): raise NotImplementedError() def _Finish(self): raise NotImplementedError() def Run(self, jobContext): raise NotImplementedError() photofilmstrip-3.7.2/photofilmstrip/lib/jobimpl/IJobContext.py0000644000232200023220000000241313560357351025213 0ustar debalancedebalance# -*- coding: utf-8 -*- # # Copyright (C) 2018 Jens Goepfert # class IJobContext: ''' The JobContext interface handles the processing of a long running job. A Job can contain of multiple tasks (smaller workloads) that may processed on different worker threads. The JobContext belongs to a group that decides on which workers the workloads are processed. ''' def GetGroupId(self): raise NotImplementedError def GetWorkLoad(self): raise NotImplementedError() def PushResult(self, resultObject): raise NotImplementedError() def _Begin(self): """ internal - called from the framework """ raise NotImplementedError() def Begin(self): raise NotImplementedError() def _Done(self): """ internal - called from the framework """ raise NotImplementedError() def Done(self): raise NotImplementedError() def IsDone(self): raise NotImplementedError() def IsAborted(self): raise NotImplementedError() def Abort(self, msg=None): raise NotImplementedError() def IsIdle(self): raise NotImplementedError() class IWorker: def GetContextGroupId(self): raise NotImplementedError() photofilmstrip-3.7.2/photofilmstrip/lib/jobimpl/ResultObject.py0000644000232200023220000000135613560357351025435 0ustar debalancedebalance# -*- coding: utf-8 -*- # # Copyright (C) 2018 Jens Goepfert # import sys from .IWorkLoad import IWorkLoad class ResultObject(object): def __init__(self, source): assert isinstance(source, IWorkLoad) self.__source = source self.result = None self.exception = None self.traceback = None def GetSource(self): return self.__source def GetResult(self, printTraceback=True): if self.exception: if printTraceback and self.traceback is not None: print(self.traceback, end=' ', file=sys.stderr) raise self.exception # pylint: disable=raising-bad-type else: return self.result class NoResultObject(ResultObject): pass photofilmstrip-3.7.2/photofilmstrip/lib/jobimpl/DlgJobVisual.py0000644000232200023220000002213413560357351025352 0ustar debalancedebalance# Boa:Dialog:DlgJobVisual # -*- coding: utf-8 -*- # # Copyright (C) 2018 Jens Goepfert # import time import wx from .WxVisualJobHandler import WxVisualJobHandler, EVT_JOB_UPDATE [wxID_DLGJOBVISUAL, wxID_DLGJOBVISUALCMDABORT, wxID_DLGJOBVISUALGAUGE, wxID_DLGJOBVISUALSTELAPSEDDIV, wxID_DLGJOBVISUALSTELAPSEDLABEL, wxID_DLGJOBVISUALSTELAPSEDVALUE, wxID_DLGJOBVISUALSTINFO, wxID_DLGJOBVISUALSTREMAININGDIV, wxID_DLGJOBVISUALSTREMAININGLABEL, wxID_DLGJOBVISUALSTREMAININGVALUE, ] = [wx.NewId() for _init_ctrls in range(10)] class DlgJobVisual(wx.Dialog, WxVisualJobHandler): def _init_coll_szMain_Items(self, parent): # generated method, don't edit parent.Add(self.stInfo, 0, border=8, flag=wx.ALL) parent.Add(self.gauge, 0, border=8, flag=wx.EXPAND | wx.ALL) parent.Add(self.szTiming, 0, border=8, flag=wx.EXPAND | wx.ALL) parent.Add(self.cmdAbort, 0, border=8, flag=wx.ALL | wx.ALIGN_CENTER_HORIZONTAL) def _init_coll_szTiming_Items(self, parent): # generated method, don't edit parent.Add(self.stElapsedLabel, 0, border=0, flag=wx.ALIGN_RIGHT) parent.Add(self.stElapsedDiv, 0, border=4, flag=wx.RIGHT | wx.LEFT) parent.Add(self.stElapsedValue, 0, border=8, flag=wx.LEFT) parent.Add(self.stRemainingLabel, 0, border=0, flag=wx.ALIGN_RIGHT) parent.Add(self.stRemainingDiv, 0, border=4, flag=wx.RIGHT | wx.LEFT) parent.Add(self.stRemainingValue, 0, border=8, flag=wx.LEFT) def _init_sizers(self): # generated method, don't edit self.szMain = wx.BoxSizer(orient=wx.VERTICAL) self.szTiming = wx.FlexGridSizer(cols=3, hgap=0, rows=2, vgap=8) self._init_coll_szMain_Items(self.szMain) self._init_coll_szTiming_Items(self.szTiming) self.SetSizer(self.szMain) def _init_ctrls(self, prnt): # generated method, don't edit wx.Dialog.__init__(self, id=wxID_DLGJOBVISUAL, name=u'DlgJobVisual', parent=prnt, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.DEFAULT_DIALOG_STYLE, title='') self.SetClientSize(wx.Size(400, 250)) self.SetSizeHints(350, -1, -1, -1) self.stInfo = wx.StaticText(id=wxID_DLGJOBVISUALSTINFO, label=u'Info', name=u'stInfo', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.gauge = wx.Gauge(id=wxID_DLGJOBVISUALGAUGE, name=u'gauge', parent=self, pos=wx.Point(-1, -1), range=100, size=wx.Size(-1, -1), style=wx.GA_HORIZONTAL) self.stElapsedLabel = wx.StaticText(id=wxID_DLGJOBVISUALSTELAPSEDLABEL, label=_(u'Elapsed time'), name=u'stElapsedLabel', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.ALIGN_RIGHT) self.stElapsedDiv = wx.StaticText(id=wxID_DLGJOBVISUALSTELAPSEDDIV, label=u':', name=u'stElapsedDiv', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.stElapsedValue = wx.StaticText(id=wxID_DLGJOBVISUALSTELAPSEDVALUE, label=u'0:00:00', name=u'stElapsedValue', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.stRemainingLabel = wx.StaticText(id=wxID_DLGJOBVISUALSTREMAININGLABEL, label=_(u'Remaining time'), name=u'stRemainingLabel', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.stRemainingDiv = wx.StaticText(id=wxID_DLGJOBVISUALSTREMAININGDIV, label=u':', name=u'stRemainingDiv', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.stRemainingValue = wx.StaticText(id=wxID_DLGJOBVISUALSTREMAININGVALUE, label=u'0:00:00', name=u'stRemainingValue', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.cmdAbort = wx.Button(id=wxID_DLGJOBVISUALCMDABORT, label=_(u'&Cancel'), name=u'cmdAbort', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.cmdAbort.Show(False) self.cmdAbort.Bind(wx.EVT_BUTTON, self.__OnCancel, id=wxID_DLGJOBVISUALCMDABORT) self._init_sizers() def __init__(self, parent, job): self._init_ctrls(parent) WxVisualJobHandler.__init__(self) self.SetTitle(job.GetName()) if self.cmdAbort.IsShown(): self.__state = "Continue" else: self.__state = "Uncancelable" self.__job = job self.__delay = 3 self.__maximum = 100 self.__display_estimated = 0 self.__last_timeupdate = 0 self.__ctdelay = 0 self.__timeStart = time.time() self.Bind(wx.EVT_CLOSE, self.__OnClose) self.Bind(EVT_JOB_UPDATE, self.__OnJobUpdate) def __OnCancel(self, event): if self.__state == "Finished": event.Skip() else: self.__state = "Canceled" # self.DisableAbort() # self.DisableSkip() self.__timeStop = time.time() def __OnClose(self, event): if self.__state == "Uncancelable": event.Veto() elif self.__state == "Finished": event.Skip() else: self.__state = "Canceled" # self.DisableAbort() # self.DisableSkip() self.__timeStop = time.time() def __Pulse(self, newmsg): self.gauge.Pulse() self.__UpdateMessage(newmsg) if 1: # self.__elapsed or self.__remaining or self.__estimated: elapsed = time.time() - self.__timeStart self.__SetTimeLabel(elapsed, self.stElapsedValue) # self.__SetTimeLabel(-1, self.stEstimated) self.__SetTimeLabel(-1, self.stRemainingValue) def __Update(self, value, msg): if value <= self.__maximum: self.gauge.SetValue(value) self.__UpdateMessage(msg) # if (self.__elapsed or self.__remaining or self.__estimated) and (value != 0): if value != 0: elapsed = time.time() - self.__timeStart if self.__last_timeupdate < elapsed or value == self.__maximum: self.__last_timeupdate = elapsed estimated = (elapsed * self.__maximum) / value if estimated > self.__display_estimated and self.__ctdelay >= 0: self.__ctdelay += 1 elif estimated < self.__display_estimated and self.__ctdelay <= 0: self.__ctdelay -= 1 else: self.__ctdelay = 0 if self.__ctdelay >= self.__delay \ or self.__ctdelay <= (self.__delay * -1) \ or value == self.__maximum \ or elapsed > self.__display_estimated \ or (elapsed > 0 and elapsed < 4): self.__display_estimated = estimated self.__ctdelay = 0 display_remaining = self.__display_estimated - elapsed if display_remaining < 0: display_remaining = 0; self.__SetTimeLabel(elapsed, self.stElapsedValue) # self.__SetTimeLabel(m_display_estimated, self.stEstimated) self.__SetTimeLabel(display_remaining, self.stRemainingValue) def __UpdateMessage(self, newmsg): if newmsg and newmsg != self.stInfo.GetLabel(): self.stInfo.SetLabel(newmsg) def __SetTimeLabel(self, val, staticText): if val != -1: hours = val // 3600 minutes = (val % 3600) // 60 seconds = val % 60 s = "%d:%02d:%02d" % (hours, minutes, seconds) else: s = _("Unknown") if s != staticText.GetLabel(): staticText.SetLabel(s) def __OnJobUpdate(self, event): if event.IsBegin(): self.__timeStart = time.time() # self.__dlg = wx.ProgressDialog(self.__job.GetName(), # self.__job.GetInfo(), # maximum=self.__job.GetMaxProgress(), # parent=self, # style = wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME | wx.PD_REMAINING_TIME)# | wx.PD_AUTO_HIDE) self.SetInitialSize(self.GetEffectiveMinSize()) self.CenterOnParent() self.ShowModal() if event.IsDone(): self.__state = "Finished" self.Close() if event.IsUpdate(): if "name" in event.GetFields(): self.SetTitle(self.__job.GetName()) # if "info" in event.GetFields(): # self.stInfo.SetLabel(self.__job.GetInfo()) # if "progress" in event.GetFields(): # self.gauge.SetValue(self.__job.GetProgress()) if "maxProgress" in event.GetFields(): maximum = self.__job.GetMaxProgress() if maximum > 0: self.__maximum = maximum self.gauge.SetRange(maximum) self.__Update(self.__job.GetProgress(), self.__job.GetInfo()) photofilmstrip-3.7.2/photofilmstrip/lib/UpdateChecker.py0000644000232200023220000000304013560357351024073 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # import threading import urllib.request import re class UpdateChecker(threading.Thread): URL = "http://www.photofilmstrip.org/update.txt" def __init__(self): threading.Thread.__init__(self, name="UpdateCheck") self._onlineVersion = None self._changes = [] self._checkDone = False self._isOk = False self.start() def run(self): try: fd = urllib.request.urlopen(self.URL) # fd = open('/home/jens/Projects/Python/PhotoFilmStrip/res/update.txt', 'r') data = fd.read() except IOError: self._checkDone = True return lines = data.decode("utf-8").split('\n') ovMatch = re.match(r"(\d+).(\d+).(\d+)?(.+)?", lines.pop(0)) if ovMatch: self._onlineVersion = ".".join(ovMatch.groups()[:3]) else: return self._changes = lines self._checkDone = True self._isOk = True def IsDone(self): return self._checkDone def IsOk(self): return self._isOk def IsNewer(self, currentVersion): if self.IsDone() and self.IsOk(): curTup = currentVersion.split(".") newTup = self._onlineVersion.split(".") return newTup > curTup return False def GetChanges(self): return "\n".join(self._changes) def GetVersion(self): return self._onlineVersion photofilmstrip-3.7.2/photofilmstrip/lib/util.py0000644000232200023220000000150413560357351022344 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # import logging import os import subprocess def IsPathWritable(path): _path = path try: fd = open(os.path.join(_path, 'test'), 'w') fd.write(" ") fd.close() os.remove(os.path.join(_path, 'test')) return True except Exception as err: logging.debug("IsPathWritable(%s): %s", path, err) return False def CheckFile(filename): if filename and not os.path.exists(filename): return False else: return True def StartFile(filename): if os.name == "nt": try: os.startfile(filename) # pylint: disable=no-member except: pass else: subprocess.Popen(["xdg-open", filename]) photofilmstrip-3.7.2/photofilmstrip/lib/DestructionManager.py0000644000232200023220000000221013560357351025160 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # import logging from photofilmstrip.lib.common.Singleton import Singleton class DestructionManager(Singleton): def __init__(self): self.__destroyables = [] def AddDestroyable(self, destroyable): assert isinstance(destroyable, IDestroyable) self.__destroyables.append(destroyable) def Destroy(self): while self.__destroyables: dest = self.__destroyables.pop(0) logging.getLogger('DestructionManager').debug("destroying '%s'", dest) try: dest.Destroy() logging.getLogger('DestructionManager').debug("destroyed '%s'", dest) except BaseException as exc: logging.debug("could not destroy '%s': %s", dest, exc, exc_info=True) logging.getLogger('DestructionManager').debug("everything destroyed") class IDestroyable: def Destroy(self): raise NotImplementedError() class Destroyable(IDestroyable): def __init__(self): DestructionManager().AddDestroyable(self) photofilmstrip-3.7.2/photofilmstrip/lib/Settings.py0000644000232200023220000001214213560357351023167 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2011 Jens Goepfert # import locale import logging import os import tempfile from configparser import ConfigParser from photofilmstrip.lib.common.Singleton import Singleton from photofilmstrip.lib.util import IsPathWritable from photofilmstrip import Constants class Settings(Singleton): def __init__(self): self.cp = None if IsPathWritable(Constants.APP_DIR): setPath = Constants.APP_DIR else: userpath = os.path.expanduser("~") if userpath == "~": userpath = tempfile.gettempdir() setPath = userpath self.filename = os.path.join(setPath, '.%s' % Constants.APP_NAME) logging.debug("settings file: %s", self.filename) self.Load() def Load(self): if self.cp is None: self.cp = ConfigParser() if os.path.isfile(self.filename): self.cp.read(self.filename, "utf-8") if not self.cp.has_section("General"): self.cp.add_section("General") if not self.cp.has_section("History"): self.cp.add_section("History") if not self.cp.has_section("Profiles"): self.cp.add_section("Profiles") def Save(self): try: fd = open(self.filename, 'w', encoding='utf-8') self.cp.write(fd) fd.close() except IOError: pass def SetLanguage(self, lang): self.Load() self.cp.set("General", "Language", lang) self.Save() def GetLanguage(self): self.Load() if self.cp.has_option("General", "Language"): return self.cp.get("General", "Language") defLang = locale.getdefaultlocale()[0] if defLang is None: defLang = "" return defLang def SetFileHistory(self, fileList): self.Load() self.cp.remove_section("History") self.cp.add_section("History") for idx, filename in enumerate(fileList): if idx < 10 and os.path.exists(filename): self.cp.set("History", "%d" % idx, os.path.abspath(filename)) self.Save() def GetFileHistory(self): self.Load() fileList = [] for idx in range(10): if self.cp.has_option("History", str(idx)): filename = self.cp.get("History", str(idx)) if os.path.exists(filename) and filename not in fileList: fileList.append(filename) return fileList def SetProjectPath(self, path): self.Load() self.cp.set("General", "ProjectPath", path) self.Save() def GetProjectPath(self): self.Load() if self.cp.has_option("General", "ProjectPath"): return self.cp.get("General", "ProjectPath") return u"" def SetImagePath(self, path): self.Load() self.cp.set("General", "ImagePath", path) self.Save() def GetImagePath(self): self.Load() if self.cp.has_option("General", "ImagePath"): return self.cp.get("General", "ImagePath") return u"" def SetAudioPath(self, path): self.Load() self.cp.set("General", "AudioPath", path) self.Save() def GetAudioPath(self): self.Load() if self.cp.has_option("General", "AudioPath"): return self.cp.get("General", "AudioPath") return u"" def SetLastProfile(self, profile): self.Load() self.cp.set("General", "LastProfile", str(profile)) self.Save() def GetLastProfile(self): self.Load() if self.cp.has_option("General", "LastProfile"): try: return self.cp.get("General", "LastProfile") except: pass return None def SetUsedRenderer(self, renderer): self.Load() self.cp.set("General", "Renderer", str(renderer)) self.Save() def GetUsedRenderer(self): self.Load() if self.cp.has_option("General", "Renderer"): try: return self.cp.getint("General", "Renderer") except: pass return None def SetLastKnownVersion(self, version): self.Load() self.cp.set("General", "LastKnownVersion", version) self.Save() def GetLastKnownVersion(self): self.Load() if self.cp.has_option("General", "LastKnownVersion"): return self.cp.get("General", "LastKnownVersion") return "0.0.0" def SetRenderProperties(self, renderer, props): self.Load() if self.cp.has_section(renderer): self.cp.remove_section(renderer) self.cp.add_section(renderer) for prop, value in props.items(): self.cp.set(renderer, prop, value) self.Save() def GetRenderProperties(self, renderer): self.Load() result = {} if not self.cp.has_section(renderer): return result for prop, value in self.cp.items(renderer): result[prop] = value return result photofilmstrip-3.7.2/photofilmstrip/AppMixin.py0000644000232200023220000000271113560357351022347 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2011 Jens Goepfert # import logging import sys from photofilmstrip.lib.DestructionManager import DestructionManager class AppMixin: def __init__(self): self.InitLogging() def InitLogging(self): if "-d" in sys.argv: lvl = logging.DEBUG else: lvl = logging.WARNING logging.basicConfig(level=lvl, format=self._GetLogFormat(), datefmt='%d.%m.%Y %H:%M:%S', filename=self._GetLogFilename()) def InitI18N(self): from photofilmstrip.action.ActionI18N import ActionI18N ActionI18N().Execute() def InitGStreamer(self): import gi gi.require_version('Gst', '1.0') from gi.repository import Gst Gst.init(None) def Start(self): self.InitI18N() self.InitGStreamer() DestructionManager() from photofilmstrip.lib.jobimpl.JobManager import JobManager JobManager().Init(workerCount=2) JobManager().Init("render") try: return self._OnStart() finally: DestructionManager().Destroy() def _GetLogFormat(self): return '%(asctime)s (%(levelname)s) %(name)s: %(message)s' def _GetLogFilename(self): return None def _OnStart(self): raise NotImplementedError() photofilmstrip-3.7.2/photofilmstrip/GUI.py0000644000232200023220000000212013560357351021240 0ustar debalancedebalance#!/usr/bin/python # -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # import os import tempfile import sys from photofilmstrip.AppMixin import AppMixin from photofilmstrip.ux.Ux import UxService, UxPreventStartupSignal from photofilmstrip import Constants class GuiApp(AppMixin): def _OnStart(self): import wx assert wx.VERSION[0] == 4 from photofilmstrip.ux.Ux import UxService UxService.GetInstance().Initialize() from photofilmstrip.gui.PhotoFilmStripApp import PhotoFilmStripApp app = PhotoFilmStripApp(0) app.MainLoop() def _GetLogFilename(self): if getattr(sys, 'frozen', None) == "windows_exe": sys.stderr = sys.stdout return os.path.join(tempfile.gettempdir(), Constants.APP_NAME + ".log") else: return None def main(): guiApp = GuiApp() try: UxService.GetInstance().Start() except UxPreventStartupSignal: return guiApp.Start() if __name__ == "__main__": main() photofilmstrip-3.7.2/photofilmstrip/cli/0000755000232200023220000000000013560357432021016 5ustar debalancedebalancephotofilmstrip-3.7.2/photofilmstrip/cli/__init__.py0000644000232200023220000000017113560357351023126 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # photofilmstrip-3.7.2/photofilmstrip/cli/Main.py0000644000232200023220000001475513560357351022270 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2010 Jens Goepfert # import os, time, logging from optparse import OptionParser from photofilmstrip import Constants from photofilmstrip.lib.util import CheckFile from photofilmstrip.core.OutputProfile import ( GetOutputProfiles, GetMPEGProfiles) from photofilmstrip.core.ProjectFile import ProjectFile from photofilmstrip.core.Renderer import RENDERERS from photofilmstrip.core.renderer.StreamRenderer import StreamRenderer from photofilmstrip.action.ActionRender import ActionRender from photofilmstrip.lib.jobimpl.JobManager import JobManager from photofilmstrip.lib.jobimpl.IVisualJobHandler import IVisualJobHandler class CliGui(IVisualJobHandler): def __init__(self): self._maxProgress = 100 self._curProgress = 0 self._info = u"" def __Output(self): percent = float(self._curProgress) / self._maxProgress width = 37 chars = u"=" * int(width * percent) chars = chars[:width] line = u"|%-3d%%%-37s| %s" % (int(percent * 100), chars, self._info) line = line[:80] print(u"%-80s\r" % (line), end=' ') def OnHandleJobBegin(self, jobContext): pass def OnHandleJobDone(self, jobContext): self._info = _(u"all done") self.__Output() def OnHandleJobUpdate(self, jobContext, fields=None): if 'maxProgress' in fields: self._maxProgress = jobContext.GetMaxProgress() if 'progress' in fields: self._curProgress = jobContext.GetProgress() if 'info' in fields: self._info = jobContext.GetInfo() self.__Output() def Info(self, project, rendererClass, profile): print() print(Constants.APP_NAME, Constants.APP_VERSION_EX) print(u"(C) 2010 Jens G\xf6pfert") print(Constants.APP_URL) print() print(u"%-20s: %s" % (_(u"processing project"), project)) print(u"%-20s: %s" % (_(u"using renderer"), rendererClass.GetName())) print(u"%-20s: %s" % (_(u"output format"), profile.GetName( withRes=True))) print(u"%-20s: %1.f" % ( _(u"framerate"), profile.GetFrameRate().AsFloat())) print() def Write(self, text): print(text) class DummyGui(IVisualJobHandler): def Info(self, project, rendererClass, profile): pass def OnHandleJobBegin(self, jobContext): pass def OnHandleJobDone(self, jobContext): pass def OnHandleJobUpdate(self, jobContext, fields=None): pass def main(showHelp=False): parser = OptionParser(prog="%s-cli" % Constants.APP_NAME.lower(), version="%%prog %s" % Constants.APP_VERSION_EX) profiles = GetOutputProfiles() + GetMPEGProfiles() profStr = ", ".join(["%d=%s" % ( idx, prof.GetName()) for idx, prof in enumerate(profiles)]) formatStr = ", ".join(["%d=%s" % (idx, rdr.GetName()) for idx, rdr in enumerate(RENDERERS)]) parser.add_option("-p", "--project", help=_(u"specifies the project file")) parser.add_option("-o", "--outputpath", help=_(u"The path where to save the output files. Use - for stdout."), metavar="PATH") parser.add_option("-t", "--profile", help=profStr + " [default: %default]", default=0, type="int") parser.add_option("-n", "--videonorm", help=_(u"Option videonorm is deprecated, use an appropriate profile!")) parser.add_option("-f", "--format", help=formatStr + " [default: %default]", default=4, type="int") parser.add_option("-a", "--draft", action="store_true", default=False, help=u"%s - %s" % (_(u"enable draft mode"), _(u"Activate this option to generate a preview of your PhotoFilmStrip. The rendering process will speed up dramatically, but results in lower quality."))) parser.add_option("-d", "--debug", action="store_true", default=False, help=u"enable debug logging") if showHelp: parser.print_help() return 0 options = parser.parse_args()[0] if options.project: options.project = os.path.abspath(options.project) if not os.path.isfile(options.project): logging.error(_(u"project file does not exist: %s"), options.project) return 1 else: parser.print_help() logging.error(_(u"no project file specified!")) return 2 if options.videonorm: parser.print_help() logging.error(_(u"Option videonorm is deprecated, use an appropriate profile!")) return 4 if options.format not in range(len(RENDERERS)): parser.print_help() logging.error(_(u"invalid format specified: %s"), options.format) return 5 rendererClass = RENDERERS[options.format] if options.profile >= len(profiles): parser.print_help() logging.error(_(u"invalid profile specified: %s"), options.profile) return 3 profile = profiles[options.profile] prjFile = ProjectFile(filename=options.project) if not prjFile.Load(): logging.error(_(u"cannot load project")) return 6 if options.outputpath: if options.outputpath == "-": outpath = "-" rendererClass = StreamRenderer else: outpath = os.path.abspath(options.outputpath) if not os.path.exists(outpath): try: os.makedirs(outpath) except Exception as err: logging.error(_(u"cannot create output path: %s"), err) return 7 else: outpath = None project = prjFile.GetProject() ar = ActionRender(project, profile, rendererClass, False, outpath) audioFile = project.GetAudioFile() if not CheckFile(audioFile): logging.error(_(u"Audio file '%s' does not exist!"), audioFile) return 8 if rendererClass is StreamRenderer: cliGui = DummyGui() else: cliGui = CliGui() cliGui.Info(options.project, rendererClass, profile) ar.Execute() renderJob = ar.GetRenderJob() renderJob.AddVisualJobHandler(cliGui) JobManager().EnqueueContext(renderJob) try: while not renderJob.IsDone(): time.sleep(0.1) except KeyboardInterrupt: renderJob.Abort() cliGui.Write("\n" + _(u"...aborted!")) return 10 resultObj = renderJob.GetResultObject() result = resultObj.GetResult() if result: cliGui.Write(_(u"all done")) # else: # logging.error(_(u"Error: %s"), renderEngine.GetErrorMessage()) photofilmstrip-3.7.2/photofilmstrip/CLI.py0000644000232200023220000000175213560357351021235 0ustar debalancedebalance#!/usr/bin/python # -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2010 Jens Goepfert # import sys from photofilmstrip.AppMixin import AppMixin class CliApp(AppMixin): def _GetLogFormat(self): return '\n%(levelname)s: %(message)s' def _OnStart(self): showHelp = False for helpOption in ("-h", "--help"): if helpOption in sys.argv: showHelp = True sys.argv.remove(helpOption) from photofilmstrip.cli.Main import main return main(showHelp) def main(): cliApp = CliApp() # import hotshot # prof = hotshot.Profile("pfs.prof") # exitCode = prof.runcall(cliApp.Start) # prof.close() # import hotshot.stats # stats = hotshot.stats.load("pfs.prof") # stats.strip_dirs() # stats.sort_stats('time', 'calls') # stats.print_stats(50) exitCode = cliApp.Start() sys.exit(exitCode) if __name__ == "__main__": main() photofilmstrip-3.7.2/photofilmstrip/Constants.py0000644000232200023220000000175113560357351022601 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2011 Jens Goepfert # import os import sys try: from photofilmstrip._scmInfo import SCM_REV # IGNORE:F0401 except ImportError: SCM_REV = "src" if getattr(sys, "frozen", False): APP_DIR = os.path.dirname(os.path.abspath(sys.argv[0])) else: APP_DIR = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])), "..") APP_NAME = "PhotoFilmStrip" APP_VERSION = "3.7.2" APP_VERSION_EX = "%s-%s" % (APP_VERSION, SCM_REV) APP_SLOGAN = "PhotoFilmStrip - Creates movies out of your pictures." APP_DESCRIPTION = """\ PhotoFilmStrip creates movies out of your pictures in just 3 steps. First select your photos, customize the motion path and render the video. There are several output possibilities for VCD, SVCD, DVD up to FULL-HD. """ APP_URL = "http://www.photofilmstrip.org" DEVELOPERS = [u"Jens Göpfert"] TRANSLATORS = ["Teza Lprod - http://lprod.org", "geogeo - http://www.geogeo.gr"] photofilmstrip-3.7.2/photofilmstrip/gui/0000755000232200023220000000000013560357432021033 5ustar debalancedebalancephotofilmstrip-3.7.2/photofilmstrip/gui/ctrls/0000755000232200023220000000000013560357432022162 5ustar debalancedebalancephotofilmstrip-3.7.2/photofilmstrip/gui/ctrls/__init__.py0000644000232200023220000000017113560357351024272 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # photofilmstrip-3.7.2/photofilmstrip/gui/ctrls/PyListView.py0000644000232200023220000000257613560357351024625 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # import wx class PyListView(wx.ListView): def __init__(self, parent, id, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.LC_ICON, validator=wx.DefaultValidator, name=wx.ListCtrlNameStr): wx.ListView.__init__(self, parent, id, pos, size, style, validator, name) self.__data = {} self.__key = 0 def DeleteAllItems(self): self.__data.clear() wx.ListView.DeleteAllItems(self) def DeleteItem(self, item): key = self.GetItemData(item) del self.__data[key] wx.ListView.DeleteItem(self, item) def SetPyData(self, item, data): key = self.GetItemData(item) if key == 0: self.__key += 1 key = self.__key self.SetItemData(item, key) self.__data[key] = data def GetPyData(self, item): key = self.GetItemData(item) return self.__data.get(key) def GetPyDataList(self): result = [] for item in range(self.GetItemCount()): result.append(self.GetPyData(item)) return result def FindItemPyData(self, data): for key, pydata in self.__data.items(): if data is pydata: return self.FindItemData(-1, key) photofilmstrip-3.7.2/photofilmstrip/gui/ctrls/PnlFloatSpinCtrl.py0000644000232200023220000000723113560357351025735 0ustar debalancedebalance# Boa:FramePanel:PnlFloatSpinCtrl # -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2010 Jens Goepfert # import wx from photofilmstrip.gui.util.FloatValidator import FloatValidator [wxID_PNLFLOATSPINCTRL, wxID_PNLFLOATSPINCTRLSPINBUTTONVALUE, wxID_PNLFLOATSPINCTRLTCVALUE, ] = [wx.NewId() for _init_ctrls in range(3)] class PnlFloatSpinCtrl(wx.Panel): def _init_coll_szMain_Items(self, parent): # generated method, don't edit parent.Add(self.tcValue, 1, border=0, flag=0) parent.Add(self.spinButtonValue, 0, border=0, flag=0) def _init_sizers(self): # generated method, don't edit self.szMain = wx.BoxSizer(orient=wx.HORIZONTAL) self._init_coll_szMain_Items(self.szMain) self.SetSizer(self.szMain) def _init_ctrls(self, prnt): # generated method, don't edit wx.Panel.__init__(self, id=wxID_PNLFLOATSPINCTRL, name=u'PnlFloatSpinCtrl', parent=prnt, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL) self.SetClientSize(wx.Size(169, 31)) self.tcValue = wx.TextCtrl(id=wxID_PNLFLOATSPINCTRLTCVALUE, name=u'tcValue', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0, value=u'5.0') self.tcValue.Bind(wx.EVT_KILL_FOCUS, self.OnTextCtrlValueKillFocus, id=wxID_PNLFLOATSPINCTRLTCVALUE) self.tcValue.Bind(wx.EVT_TEXT, self.OnTextCtrlValueText, id=wxID_PNLFLOATSPINCTRLTCVALUE) self.spinButtonValue = wx.SpinButton(id=wxID_PNLFLOATSPINCTRLSPINBUTTONVALUE, name=u'spinButtonValue', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.SP_VERTICAL) self.spinButtonValue.Bind(wx.EVT_SPIN, self.OnSpinButtonValueSpin, id=wxID_PNLFLOATSPINCTRLSPINBUTTONVALUE) self._init_sizers() def __init__(self, parent, id, pos, size, style, name): self._init_ctrls(parent) self.tcValue.SetValidator(FloatValidator()) self.spinButtonValue.SetMinSize(wx.Size(-1, self.tcValue.GetSize()[1])) def __SendValueChangedEvent(self, value): evt = ValueChangedEvent(self.GetId(), value) evt.SetEventObject(self) self.GetEventHandler().ProcessEvent(evt) def SetRange(self, minVal, maxVal): self.spinButtonValue.SetRange(minVal, maxVal) def OnSpinButtonValueSpin(self, event): value = event.GetPosition() / 10.0 self.tcValue.ChangeValue("%.1f" % value) self.__SendValueChangedEvent(value) event.Skip() def __GetValue(self): val = self.tcValue.GetValue() try: floatVal = max(float(val), 1.0) except ValueError: floatVal = 1.0 return min(floatVal, 600.0) def SetValue(self, value): self.tcValue.ChangeValue("%.1f" % value) self.spinButtonValue.SetValue(int(value * 10)) def OnTextCtrlValueKillFocus(self, event): value = self.__GetValue() self.spinButtonValue.SetValue(int(value * 10)) self.tcValue.ChangeValue("%.1f" % value) self.__SendValueChangedEvent(value) event.Skip() def OnTextCtrlValueText(self, event): value = self.__GetValue() self.__SendValueChangedEvent(value) event.Skip() _EVT_VALUE_CHANGED_TYPE = wx.NewEventType() EVT_VALUE_CHANGED = wx.PyEventBinder(_EVT_VALUE_CHANGED_TYPE, 1) class ValueChangedEvent(wx.PyCommandEvent): def __init__(self, wxId, value): wx.PyCommandEvent.__init__(self, _EVT_VALUE_CHANGED_TYPE, wxId) self.__value = value def GetValue(self): return self.__value photofilmstrip-3.7.2/photofilmstrip/gui/ctrls/IconLabelLink.py0000644000232200023220000000427413560357351025211 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2010 Jens Goepfert # import wx from photofilmstrip.gui.helper import ChopText class IconLabelLink(wx.Panel): def __init__(self, parent, size=wx.DefaultSize, label="label", bmp=None, descr="descr"): wx.Panel.__init__(self, parent, -1, wx.DefaultPosition, (150, 150), 0, "IconLabelLink") self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM) self.bmpDia = wx.ArtProvider.GetBitmap('PFS_DIA') self.bmpDiaSelected = wx.ArtProvider.GetBitmap('PFS_DIA_S') self.bmpThumb = bmp self.label = label self.mouseOver = False self.SetToolTip(u'{0}\n{1}'.format(label, descr)) self.Bind(wx.EVT_PAINT, self.OnPaint) self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseEvents) self.SetCursor(wx.Cursor(wx.CURSOR_HAND)) def OnMouseEvents(self, event): if event.LeftDown(): self.OnClick() if event.Entering(): self.mouseOver = True self.Refresh() if event.Leaving(): self.mouseOver = False self.Refresh() # event.Skip() def OnPaint(self, event): # pylint: disable=unused-argument dc = wx.AutoBufferedPaintDC(self) dc.SetBackground(wx.Brush(self.GetParent().GetBackgroundColour())) sz = self.GetSize() dc.Clear() if self.mouseOver: dc.DrawBitmap(self.bmpDiaSelected, 0, 0) else: dc.DrawBitmap(self.bmpDia, 0, 0) thumbSz = self.bmpThumb.GetSize() thumbRect = wx.Rect(sz[0] // 2 - thumbSz[0] // 2, sz[1] // 2 - thumbSz[1] // 2 - 15, thumbSz[0], thumbSz[1]) dc.DrawBitmap(self.bmpThumb, thumbRect.GetTopLeft()) thumbRect.Inflate(1, 1) dc.SetBrush(wx.TRANSPARENT_BRUSH) dc.DrawRectangle(thumbRect) label, width = ChopText(dc, self.label, 138) dc.DrawText(label, sz[0] // 2 - width // 2, 97) def OnClick(self): raise NotImplementedError("OnClick") photofilmstrip-3.7.2/photofilmstrip/gui/ctrls/PnlDlgHeader.py0000644000232200023220000000743513560357351025036 0ustar debalancedebalance# Boa:FramePanel:PnlDlgHeader # -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2010 Jens Goepfert # import wx from wx.lib.wordwrap import wordwrap [wxID_PNLDLGHEADER, wxID_PNLDLGHEADERBMPLOGO, wxID_PNLDLGHEADERPNLHEADER, wxID_PNLDLGHEADERSLHDR, wxID_PNLDLGHEADERSTERRMSG, wxID_PNLDLGHEADERSTHEADER, ] = [wx.NewId() for _init_ctrls in range(6)] class PnlDlgHeader(wx.Panel): def _init_coll_szHeaderText_Items(self, parent): # generated method, don't edit parent.Add(self.stHeader, 0, border=0, flag=0) parent.Add(self.stErrMsg, 0, border=4, flag=wx.TOP) def _init_coll_szMain_Items(self, parent): # generated method, don't edit parent.Add(self.pnlHeader, 0, border=0, flag=wx.EXPAND) parent.Add(self.slHdr, 0, border=0, flag=wx.EXPAND) def _init_coll_szHeader_Items(self, parent): # generated method, don't edit parent.Add(self.bmpLogo, 0, border=8, flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL) parent.Add(self.szHeaderText, 0, border=8, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL) def _init_sizers(self): # generated method, don't edit self.szMain = wx.BoxSizer(orient=wx.VERTICAL) self.szHeader = wx.BoxSizer(orient=wx.HORIZONTAL) self.szHeaderText = wx.BoxSizer(orient=wx.VERTICAL) self._init_coll_szMain_Items(self.szMain) self._init_coll_szHeader_Items(self.szHeader) self._init_coll_szHeaderText_Items(self.szHeaderText) self.SetSizer(self.szMain) self.pnlHeader.SetSizer(self.szHeader) def _init_ctrls(self, prnt): # generated method, don't edit wx.Panel.__init__(self, id=wxID_PNLDLGHEADER, name=u'PnlDlgHeader', parent=prnt, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL) self.pnlHeader = wx.Panel(id=wxID_PNLDLGHEADERPNLHEADER, name=u'pnlHeader', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL) self.pnlHeader.SetBackgroundColour(wx.Colour(255, 255, 255)) self.bmpLogo = wx.StaticBitmap(bitmap=wx.ArtProvider.GetBitmap('wxART_GO_HOME', wx.ART_TOOLBAR, (32, 32)), id=wxID_PNLDLGHEADERBMPLOGO, name=u'bmpLogo', parent=self.pnlHeader, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.stHeader = wx.StaticText(id=wxID_PNLDLGHEADERSTHEADER, label=u'', name=u'stHeader', parent=self.pnlHeader, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.stErrMsg = wx.StaticText(id=wxID_PNLDLGHEADERSTERRMSG, label=u'', name=u'stErrMsg', parent=self.pnlHeader, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.stErrMsg.Show(False) self.stErrMsg.SetForegroundColour(wx.Colour(255, 0, 0)) self.slHdr = wx.StaticLine(id=wxID_PNLDLGHEADERSLHDR, name=u'slHdr', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self._init_sizers() def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.TAB_TRAVERSAL, name=u'PnlDlgHeader'): self._init_ctrls(parent) font = self.stHeader.GetFont() font.SetWeight(wx.FONTWEIGHT_BOLD) self.stHeader.SetFont(font) def SetErrorMessage(self, msg): if msg: msg = wordwrap(msg, 350, wx.ClientDC(self.stErrMsg)) self.stErrMsg.SetLabel(msg) self.stErrMsg.Show(True) else: self.stErrMsg.Show(False) self.pnlHeader.Layout() def SetTitle(self, title): self.stHeader.SetLabel(title) def SetBitmap(self, bmp): self.bmpLogo.SetBitmap(bmp) photofilmstrip-3.7.2/photofilmstrip/gui/PnlRenderJobVisual.py0000644000232200023220000000321113560357351025112 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # import wx from photofilmstrip.action.WxAction import WxAction from photofilmstrip.action.ActionPlayVideo import ActionPlayVideo from photofilmstrip.action.ActionOpenFolder import ActionOpenFolder from photofilmstrip.lib.jobimpl.PnlJobVisual import PnlJobVisual class PnlRenderJobVisual(PnlJobVisual): def __init__(self, parent, pnlJobManager, jobContext): PnlJobVisual.__init__(self, parent, pnlJobManager, jobContext) self._actPlay = WxAction( _(u"Play video"), self._PlayVideo, bmp={wx.ART_MENU: wx.ArtProvider.GetBitmap('PFS_PLAY_16'), wx.ART_TOOLBAR: wx.ArtProvider.GetBitmap('PFS_PLAY_24')} ) self._actOpenFldr = WxAction( _(u"Open folder"), self._OpenFolder, bmp={wx.ART_MENU: wx.ArtProvider.GetBitmap('PFS_FOLDER_OPEN_16'), wx.ART_TOOLBAR: wx.ArtProvider.GetBitmap('PFS_FOLDER_OPEN_24')} ) def _OnMenuActions(self, menu): mitm = self._actPlay.ToMenu(self, menu) menu.Enable(mitm.GetId(), self.jobContext.IsDone()) mitm = self._actOpenFldr.ToMenu(self, menu) menu.Enable(mitm.GetId(), not self.jobContext.IsIdle()) def _OnSetupAction(self): if self.jobContext.IsDone(): self.curAction = self._actPlay def _PlayVideo(self): ActionPlayVideo(self.jobContext.GetOutputFile()).Execute() def _OpenFolder(self): ActionOpenFolder(self.jobContext.GetOutputFile()).Execute() photofilmstrip-3.7.2/photofilmstrip/gui/PnlTimelapse.py0000644000232200023220000001154713560357351024012 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # import wx from photofilmstrip.core.PicturePattern import PicturePattern from photofilmstrip.gui.ImageSectionEditor import ImageProxy from photofilmstrip.gui.PnlPfsProject import ( PnlPfsProject, ID_PIC_IMPORT, ID_MUSIC, ID_RENDER_FILMSTRIP) class PnlTimelapse(PnlPfsProject): def _GetEditorName(self): return _(u"Timelapse") def AddToolBarActions(self, toolBar): toolBar.AddTool(ID_PIC_IMPORT, '', wx.ArtProvider.GetBitmap('PFS_IMPORT_PICTURES_24'), wx.ArtProvider.GetBitmap('PFS_IMPORT_PICTURES_D_24'), wx.ITEM_NORMAL, _(u'Import Pictures'), _(u'Import Pictures'), None) toolBar.AddSeparator() toolBar.AddTool(ID_MUSIC, '', wx.ArtProvider.GetBitmap('PFS_MUSIC_24'), wx.NullBitmap, wx.ITEM_NORMAL, _(u'Configure music'), _(u'Configure music'), None) toolBar.AddSeparator() toolBar.AddTool(ID_RENDER_FILMSTRIP, '', wx.ArtProvider.GetBitmap('PFS_RENDER_24'), wx.ArtProvider.GetBitmap('PFS_RENDER_D_24'), wx.ITEM_NORMAL, _(u'Render filmstrip'), _(u'Render filmstrip'), None) def GetStatusText(self, index): project = self.GetProject() try: imgCount, frameCount = self.__CalcDuration() except ValueError as err: if index == 0: return str(err) else: return "" totalTime = project.GetDuration(False) if totalTime == -1: # TODO: calc from audio files totalTime = 0 elif totalTime is None: pass # totalTime = project.GetDuration(True) else: assert True, "totalTime is invalid" if index == 0: return u"%s: %d" % (_(u"Images"), imgCount) elif index == 1: return u"%s: %d" % (_(u"Frames"), frameCount) else: return u"" def __CalcDuration(self): pics = self.GetProject().GetPictures() idxPic = 0 imgCount = 0 frameCount = 0 while idxPic < len(pics) - 1: pic = pics[idxPic] picPattern = PicturePattern.Create(pic.GetFilename()) assert picPattern.IsOk() picNum = picPattern.num # get number from next pic nextPic = pics[idxPic + 1] nextPicPattern = PicturePattern.Create(nextPic.GetFilename()) assert nextPicPattern.IsOk() picCount = nextPicPattern.num - picNum if picCount < 0: raise ValueError(_(u"The picture counter is not " u"increasing: %s") % nextPic.GetFilename()) picDur = int(pic.GetDuration()) transDur = int(pic.GetTransitionDuration()) imgCount += picCount frameCount += (picCount * (picDur + transDur)) idxPic += 1 return imgCount, frameCount def _CheckImportedPic(self, path): picPattern = PicturePattern.Create(path) if not picPattern.IsOk(): dlgErr = wx.MessageDialog( self, _(u"Filename '%s' does not match a number pattern " u"which is necessary for a time lapse slide " u"show!") % path, _(u"Error"), wx.OK | wx.ICON_ERROR) dlgErr.ShowModal() dlgErr.Destroy() return False else: return True def _InitImageProxy(self): self.imgProxyLeft = ImageProxy() self.imgProxyLeft.AddObserver(self.bitmapLeft) self.imgProxyRight = ImageProxy() self.imgProxyRight.AddObserver(self.bitmapRight) self.bitmapLeft.SetImgProxy(self.imgProxyLeft) self.bitmapRight.SetImgProxy(self.imgProxyRight) def _OnPicsSelectionChanged(self, selItems, selPics): if selItems: selIdx = selItems[0] selPic = self.lvPics.GetPicture(selIdx) nextPic = self.lvPics.GetPicture(selIdx + 1) self._CheckAndSetLock(selPic) self.imgProxyLeft.SetPicture(selPic) self.bitmapLeft.SetSection(wx.Rect(*selPic.GetStartRect())) if nextPic: self.imgProxyRight.SetPicture(nextPic) self.bitmapRight.SetSection(wx.Rect(*nextPic.GetStartRect())) self.bitmapRight.Enable(True) else: self.bitmapRight.Enable(False) photofilmstrip-3.7.2/photofilmstrip/gui/DlgNewProject.py0000644000232200023220000001647713560357351024133 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2010 Jens Goepfert # import os import wx from photofilmstrip import Constants from photofilmstrip.lib.Settings import Settings from photofilmstrip.lib.util import IsPathWritable from photofilmstrip.core.Aspect import Aspect from photofilmstrip.core.Project import Project from photofilmstrip.gui.ctrls.PnlDlgHeader import PnlDlgHeader class DlgNewProject(wx.Dialog): def _InitSizers(self): szMain = wx.BoxSizer(orient=wx.VERTICAL) szCtrls = wx.GridBagSizer(hgap=8, vgap=8) szCmds = wx.BoxSizer(orient=wx.HORIZONTAL) szMain.Add(self.pnlHdr, 0, border=0, flag=wx.EXPAND) szMain.Add(szCtrls, 0, border=8, flag=wx.ALL | wx.EXPAND) szMain.Add(self.staticLine, 0, border=0, flag=wx.EXPAND) szMain.Add(szCmds, 0, border=8, flag=wx.ALL | wx.ALIGN_RIGHT) szCtrls.Add(self.stProject, (0, 0), border=0, flag=wx.ALIGN_CENTER_VERTICAL, span=(1, 1)) szCtrls.Add(self.tcProject, (0, 1), border=0, flag=wx.EXPAND, span=(1, 1)) szCtrls.Add(self.stFolder, (1, 0), border=0, flag=wx.ALIGN_CENTER_VERTICAL, span=(1, 1)) szCtrls.Add(self.tcFolder, (1, 1), border=0, flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, span=(1, 1)) szCtrls.Add(self.cmdBrowseFolder, (1, 2), border=0, flag=0, span=(1, 1)) szCtrls.Add(self.stAspect, (2, 0), border=0, flag=wx.ALIGN_CENTER_VERTICAL, span=(1, 1)) szCtrls.Add(self.choiceAspect, (2, 1), border=0, flag=wx.EXPAND, span=(1, 1)) szCtrls.AddGrowableCol(1) szCmds.Add(self.cmdCancel, 0, border=0, flag=0) szCmds.AddSpacer(8) szCmds.Add(self.cmdOk, 0, border=0, flag=0) self.SetSizer(szMain) def _InitCtrls(self): self.pnlHdr = PnlDlgHeader(self) self.stProject = wx.StaticText(self, label=_(u'Project name:'), name=u'stProject') self.tcProject = wx.TextCtrl(self, name=u'tcProject', value=u'') self.stFolder = wx.StaticText(self, label=_(u'Folder:'), name=u'stFolder') self.tcFolder = wx.TextCtrl(self, name=u'tcFolder', style=wx.TE_READONLY, value=u'') self.cmdBrowseFolder = wx.BitmapButton(self, bitmap=wx.ArtProvider.GetBitmap('PFS_FOLDER_OPEN_16'), name=u'cmdBrowseFolder', style=wx.BU_AUTODRAW) self.cmdBrowseFolder.Bind(wx.EVT_BUTTON, self.OnCmdBrowseFolderButton) self.stAspect = wx.StaticText(self, label=_(u'Aspect ratio:'), name=u'stAspect') self.choiceAspect = wx.Choice(self, choices=[], name=u'choiceAspect') self.staticLine = wx.StaticLine(self) self.cmdCancel = wx.Button(self, id=wx.ID_CANCEL, label=_(u'&Cancel'), name=u'cmdCancel') self.cmdOk = wx.Button(self, id=wx.ID_OK, label=_(u'&Ok'), name=u'cmdOk') self.cmdOk.Bind(wx.EVT_BUTTON, self.OnCmdOkButton, id=wx.ID_OK) def __init__(self, parent, title): wx.Dialog.__init__(self, parent, name=u'DlgNewProject', style=wx.DEFAULT_DIALOG_STYLE, title=title) self._InitCtrls() self._InitSizers() self.pnlHdr.SetTitle(title) self.pnlHdr.SetBitmap(wx.ArtProvider.GetBitmap('PFS_ICON_32')) self.choiceAspect.Append(Aspect.ASPECT_16_9) self.choiceAspect.Append(Aspect.ASPECT_4_3) self.choiceAspect.Append(Aspect.ASPECT_3_2) self.choiceAspect.Select(0) self.tcProject.SetMinSize(wx.Size(300, -1)) self.tcFolder.SetMinSize(wx.Size(300, -1)) self.choiceAspect.SetMinSize(wx.Size(300, -1)) self.tcProject.SetValue(_(u"Unnamed project")) self.tcProject.SelectAll() self.tcProject.SetFocus() projPath = Settings().GetProjectPath() if not projPath: projPath = os.path.join(wx.GetHomeDir(), _(u"My PhotoFilmStrips")) Settings().SetProjectPath(projPath) self.tcFolder.SetValue(projPath) self.Fit() self.CenterOnParent() self.SetFocus() def OnCmdBrowseFolderButton(self, event): dlg = wx.DirDialog(self, _(u"Browse for folder"), defaultPath=self.tcFolder.GetValue()) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() if self.__ValidateOutDir(path): self.tcFolder.SetValue(path) Settings().SetProjectPath(path) dlg.Destroy() def OnCmdOkButton(self, event): if self.__ValidateOutDir() and self.__ValidateProjName(): event.Skip() def __ValidateOutDir(self, path=None): if path is None: path = self.tcFolder.GetValue().strip() if not os.path.isdir(path): dlg = wx.MessageDialog(self, _(u"Folder does not exists! Do you want %s to create it?") % Constants.APP_NAME, _(u"Question"), wx.YES_NO | wx.ICON_QUESTION) resp = dlg.ShowModal() dlg.Destroy() if resp == wx.ID_YES: try: os.makedirs(path) except Exception as err: dlg = wx.MessageDialog(self, _(u"Cannot create folder: %s") % str(err), _(u"Error"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return False else: return False else: if not IsPathWritable(path): dlg = wx.MessageDialog(self, _(u"Cannot write into folder!"), _(u"Error"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return False return True def __ValidateProjName(self): projName = self.tcProject.GetValue().strip() projName = projName.strip(u".") projPath = os.path.join(self.tcFolder.GetValue().strip(), projName) if not projName: self.pnlHdr.SetErrorMessage(_(u"The project name must be filled.")) return False elif not os.path.exists(projPath): try: os.makedirs(projPath) except Exception: self.pnlHdr.SetErrorMessage(_(u"The project name contains invalid characters.")) return False os.removedirs(projPath) return True else: self.pnlHdr.SetErrorMessage(u"") return True def __GetProjectPath(self): projName = self.tcProject.GetValue().strip() projName = projName.strip(u".") filepath = os.path.join(self.tcFolder.GetValue().strip(), projName, "%s.pfs" % projName) return filepath def GetProject(self): project = Project(self.__GetProjectPath()) project.SetTimelapse(False) project.SetAspect(self.choiceAspect.GetStringSelection()) return project photofilmstrip-3.7.2/photofilmstrip/gui/__init__.py0000644000232200023220000000017113560357351023143 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # photofilmstrip-3.7.2/photofilmstrip/gui/PnlEditorPage.py0000644000232200023220000001047613560357351024112 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2017 Jens Goepfert # import os import wx from photofilmstrip.lib.Settings import Settings class PnlEditorPage(wx.Panel): def __init__(self, parent, id=wx.ID_ANY, name=wx.PanelNameStr): wx.Panel.__init__(self, parent, id, name=name) self.__hasChanged = False def __Save(self, filepath): try: return self._Save(filepath) except Exception as err: dlg = wx.MessageDialog(self.GetParent(), _(u"Could not save the file '%(file)s': %(errMsg)s") % \ {'file': filepath, 'errMsg': str(err)}, _(u"Question"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return False def SetChanged(self, changed=True): self.__hasChanged = changed def HasChanged(self): return self.__hasChanged def CheckAndAskSaving(self): if self.HasChanged(): filepath = self.GetSaveFilePath() if filepath is None: filepath = _(u"New file") dlg = wx.MessageDialog(self.GetParent(), _(u"'%s' has been modified. Save changes?") % filepath, _(u"Question"), wx.YES_NO | wx.CANCEL | wx.ICON_EXCLAMATION) response = dlg.ShowModal() dlg.Destroy() if response == wx.ID_CANCEL: return False elif response == wx.ID_YES and not self.OnSave(): return False return True def OnSave(self): curFilePath = self.GetSaveFilePath() if curFilePath is None: return self.OnSaveAs() elif self.__Save(curFilePath): self.SetChanged(False) return True else: return False def OnSaveAs(self): curFilePath = self.GetSaveFilePath() if curFilePath is None: curFilePath = "{0}{1}".format(self._GetEditorName(), self.GetFileExtension()) dlg = wx.FileDialog(self.GetParent(), _(u"Save %s") % self._GetEditorName(), self._GetDefaultSaveFolder(), curFilePath, self._GetEditorName() + u'-' + _(u"File") + " (*{0})|*{0}".format(self.GetFileExtension()), wx.FD_SAVE) try: if dlg.ShowModal() == wx.ID_OK: filepath = dlg.GetPath() if os.path.splitext(filepath)[1].lower() != self.GetFileExtension(): filepath += self.GetFileExtension() if os.path.isfile(filepath): dlg2 = wx.MessageDialog(self.GetParent(), _(u"Overwrite existing file '%s'?") % filepath, _(u"Question"), wx.YES_NO | wx.ICON_QUESTION) try: if dlg2.ShowModal() == wx.ID_NO: return False finally: dlg2.Destroy() if self.__Save(filepath): self.SetChanged(False) return True else: return False finally: dlg.Destroy() def _GetDefaultSaveFolder(self): return Settings().GetProjectPath() def _GetEditorName(self): raise NotImplementedError() def _Save(self, filepath): raise NotImplementedError() def GetProject(self): raise NotImplementedError() def GetFileExtension(self): raise NotImplementedError() def GetStatusText(self, index): raise NotImplementedError() def GetSaveFilePath(self): raise NotImplementedError() def AddMenuFileActions(self, menu): pass def AddMenuEditActions(self, menu): pass def AddToolBarActions(self, toolBar): pass def ConnectEvents(self, evtHandler): pass def DisconnEvents(self, evtHandler): pass def OnStatusBarClick(self, index): pass photofilmstrip-3.7.2/photofilmstrip/gui/util/0000755000232200023220000000000013560357432022010 5ustar debalancedebalancephotofilmstrip-3.7.2/photofilmstrip/gui/util/FloatValidator.py0000644000232200023220000000253613560357351025303 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # import wx import string class FloatValidator(wx.Validator): def __init__(self): wx.Validator.__init__(self) self.Bind(wx.EVT_CHAR, self.OnChar) def Clone(self): return FloatValidator() def Validate(self, win): tc = self.GetWindow() val = tc.GetValue() for x in val: if x not in (string.digits + ".-"): return False return True def OnChar(self, event): key = event.GetKeyCode() if key < wx.WXK_SPACE or key == wx.WXK_DELETE or key > 255: event.Skip() return if chr(key) in string.digits: event.Skip() return if chr(key) == '-' and '-' not in self.GetWindow().GetValue(): self.GetWindow().SetInsertionPoint(0) self.GetWindow().WriteText("-") self.GetWindow().SetInsertionPointEnd() return if chr(key) in [',', '.'] and "." not in self.GetWindow().GetValue(): self.GetWindow().WriteText(".") return if not wx.Validator.IsSilent(): wx.Bell() # Returning without calling even.Skip eats the event before it # gets to the text control return photofilmstrip-3.7.2/photofilmstrip/gui/util/__init__.py0000644000232200023220000000017113560357351024120 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # photofilmstrip-3.7.2/photofilmstrip/gui/util/ImageCache.py0000644000232200023220000000733413560357351024337 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2011 Jens Goepfert # import threading import time import wx from photofilmstrip.lib.common.Singleton import Singleton from photofilmstrip.lib.common.ObserverPattern import Observer from photofilmstrip.core import PILBackend from photofilmstrip.lib.DestructionManager import Destroyable class ImageCache(Singleton, Observer): SIZE = 400 THUMB_SIZE = 100 def __init__(self): self._picRegistry = {} self._wxImgCache = {} self._wxBmpCache = {} self._pilCache = {} self._inScalingQueue = object() self.scaleThread = ScaleThread(self) self.scaleThread.start() self.win = None self.thumb = None def RegisterWin(self, win): self.win = win def ObservableUpdate(self, obj, arg): if arg == 'bitmap': self.UpdatePicture(obj) def ClearCache(self): self._wxImgCache.clear() self._wxBmpCache.clear() def RegisterPicture(self, picture, pilThumb=None): # if pilThumb is None: # pilThumb = PILBackend.GetThumbnail(picture, height=120) key = picture.GetKey() self._picRegistry[key] = picture self._pilCache[key] = pilThumb picture.AddObserver(self) def UpdatePicture(self, picture): key = picture.GetKey() if key in self._wxImgCache: del self._wxImgCache[key] if key in self._wxBmpCache: del self._wxBmpCache[key] if key in self._pilCache: del self._pilCache[key] self.RegisterPicture(picture) def GetImage(self, picture): key = picture.GetKey() if key not in self._wxImgCache: pilImg = PILBackend.GetThumbnail(picture, width=ImageCache.SIZE) wxImg = wx.Image(PILBackend.ImageToStream(pilImg), wx.BITMAP_TYPE_JPEG) self._wxImgCache[key] = wxImg return self._wxImgCache[key] def GetThumbBmp(self, picture): key = picture.GetKey() if key not in self._wxBmpCache: pilImg = self._pilCache.get(key) if pilImg is None: self._pilCache[key] = self._inScalingQueue self.scaleThread.queue.append(picture) return self.thumb elif pilImg is self._inScalingQueue: return self.thumb else: # pilImg = self._pilCache[key] wxImg = wx.Image(PILBackend.ImageToStream(pilImg), wx.BITMAP_TYPE_JPEG) self._wxBmpCache[key] = wxImg.ConvertToBitmap() return self._wxBmpCache[key] class ScaleThread(threading.Thread, Destroyable): def __init__(self, imgCache): threading.Thread.__init__(self, name="ScaleThread") Destroyable.__init__(self) self.imgCache = imgCache self.active = True self.queue = [] def Destroy(self): self.active = False def run(self): while self.active: pic = None try: pic = self.queue.pop(0) except IndexError: time.sleep(0.1) continue pilImg = PILBackend.GetThumbnail(pic, height=ImageCache.THUMB_SIZE) self.imgCache.RegisterPicture(pic, pilImg) if self.imgCache.win: evt = ThumbnailReadyEvent(pic) wx.PostEvent(self.imgCache.win, evt) _EVT_THUMB_READY_TYPE = wx.NewEventType() EVT_THUMB_READY = wx.PyEventBinder(_EVT_THUMB_READY_TYPE, 1) class ThumbnailReadyEvent(wx.PyEvent): def __init__(self, pic): wx.PyEvent.__init__(self, eventType=_EVT_THUMB_READY_TYPE) self.__pic = pic def GetPicture(self): return self.__pic photofilmstrip-3.7.2/photofilmstrip/gui/PhotoFilmStripApp.py0000644000232200023220000000146213560357351024774 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # import os import sys import wx from photofilmstrip.gui.ArtProvider import ArtProvider from photofilmstrip.gui.FrmMain import FrmMain from photofilmstrip.gui.DlgBugReport import DlgBugReport class PhotoFilmStripApp(wx.App): def OnInit(self): # self.SetAssertMode(wx.PYAPP_ASSERT_SUPPRESS) # loc = wx.Locale(wx.LANGUAGE_GERMAN) ArtProvider.Init() frame = FrmMain() frame.Show() frame.Maximize() self.SetTopWindow(frame) DlgBugReport.Initialize(frame) if len(sys.argv) > 1: for arg in sys.argv[1:]: if os.path.isfile(arg): frame.LoadProject(arg) return True photofilmstrip-3.7.2/photofilmstrip/gui/FrmMain.py0000644000232200023220000003556513560357351022754 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # import os import wx import wx.aui import wx.adv from wx.lib.wordwrap import wordwrap from photofilmstrip import Constants from photofilmstrip.action.ActionI18N import ActionI18N from photofilmstrip.core.RenderJob import RenderJob from photofilmstrip.lib.common.ObserverPattern import Observer from photofilmstrip.lib.Settings import Settings from photofilmstrip.lib.jobimpl.WxVisualJobManager import ( WxVisualJobManager, EVT_REGISTER_JOB, EVT_REMOVE_JOB) from photofilmstrip.lib.jobimpl.JobManager import JobManager from photofilmstrip.lib.jobimpl.PnlJobManager import PnlJobManager from photofilmstrip.gui.ActionManager import ActionManager from photofilmstrip.gui.PnlWelcome import PnlWelcome from photofilmstrip.gui.HelpViewer import HelpViewer from photofilmstrip.gui.DlgNewProject import DlgNewProject from photofilmstrip.gui.WxProjectFile import WxProjectFile from photofilmstrip.gui.PnlRenderJobVisual import PnlRenderJobVisual from photofilmstrip.gui.PnlEditorPage import PnlEditorPage from photofilmstrip.res.license import licenseText from photofilmstrip.gui.PnlTimelapse import PnlTimelapse from photofilmstrip.gui.PnlSlideshow import PnlSlideshow ID_PAGE_UP = wx.NewId() ID_PAGE_DOWN = wx.NewId() class FrmMain(wx.Frame, Observer, WxVisualJobManager): def __init__(self): wx.Frame.__init__(self, None, -1, name=u'FrmMain', pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL) WxVisualJobManager.__init__(self) self.SetTitle(Constants.APP_NAME) iconBundle = wx.IconBundle() iconBundle.AddIcon(wx.ArtProvider.GetIcon("PFS_ICON_16", wx.ART_OTHER)) iconBundle.AddIcon(wx.ArtProvider.GetIcon("PFS_ICON_24", wx.ART_OTHER)) iconBundle.AddIcon(wx.ArtProvider.GetIcon("PFS_ICON_32", wx.ART_OTHER)) iconBundle.AddIcon(wx.ArtProvider.GetIcon("PFS_ICON_48", wx.ART_OTHER)) iconBundle.AddIcon(wx.ArtProvider.GetIcon("PFS_ICON_64", wx.ART_OTHER)) iconBundle.AddIcon(wx.ArtProvider.GetIcon("PFS_ICON_128", wx.ART_OTHER)) self.SetIcons(iconBundle) self.statusBar = wx.StatusBar(self) self.statusBar.SetFieldsCount(4) self.statusBar.Bind(wx.EVT_LEFT_DOWN, self.OnStatusBarLeftDown) self.SetStatusBar(self.statusBar) self.menuBar = wx.MenuBar() self.SetMenuBar(self.menuBar) self.toolBar = wx.ToolBar(self) self.SetToolBar(self.toolBar) self._actionMgr = ActionManager(self, self.menuBar, self.toolBar) self.notebook = wx.aui.AuiNotebook(self, -1, style=wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB) self.notebook.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED, self.OnPageChanged) self.notebook.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE, self.OnPageClose) self.pnlWelcome = PnlWelcome(self.notebook, self) self.pnlWelcome.SetDropTarget(ProjectDropTarget(self)) self.notebook.AddPage(self.pnlWelcome, _(u"Welcome"), True) self.frmJobManager = wx.Frame(self, -1, _(u"Job queue"), size=wx.Size(600, 400), style=wx.DEFAULT_FRAME_STYLE | wx.STAY_ON_TOP) self.frmJobManager.SetIcon(wx.ArtProvider.GetIcon("PFS_JOB_QUEUE_16", wx.ART_OTHER)) self.frmJobManager.Bind(wx.EVT_CLOSE, self.OnCloseFrameJobManager) PnlJobManager(self.frmJobManager, pnlJobClass=PnlRenderJobVisual) self.Bind(wx.EVT_CLOSE, self.OnClose) self.Bind(wx.EVT_MENU, self.OnSlideshow, id=ActionManager.ID_SLIDESHOW) self.Bind(wx.EVT_MENU, self.OnTimelapse, id=ActionManager.ID_TIMELAPSE) self.Bind(wx.EVT_MENU, self.OnProjectLoad, id=wx.ID_OPEN) self.Bind(wx.EVT_MENU, self.OnProjectSave, id=wx.ID_SAVE) self.Bind(wx.EVT_MENU, self.OnProjectSaveAs, id=wx.ID_SAVEAS) self.Bind(wx.EVT_MENU, self.OnProjectClose, id=ActionManager.ID_PROJECT_CLOSE) self.Bind(wx.EVT_MENU, self.OnExit, id=wx.ID_EXIT) self.Bind(wx.EVT_MENU, self.OnAbout, id=wx.ID_ABOUT) self.Bind(wx.EVT_MENU, self.OnHelpIndex, id=wx.ID_HELP) for wxId in ActionManager.LANG_MAP.keys(): self.Bind(wx.EVT_MENU, self.OnChangeLanguage, id=wxId) self.Bind(wx.EVT_MENU, self.OnShowFrameJobManager, id=ActionManager.ID_JOB_QUEUE) self.Bind(wx.EVT_UPDATE_UI, self.OnCheckProjectChanged, id=wx.ID_SAVE) self.Bind(wx.EVT_UPDATE_UI, self.OnCheckProjectActive, id=wx.ID_SAVEAS) self.Bind(wx.EVT_UPDATE_UI, self.OnCheckProjectActive, id=ActionManager.ID_PROJECT_CLOSE) self.Bind(wx.EVT_MENU, self.OnHelpContent, id=wx.ID_HELP_CONTENTS) self.Bind(wx.EVT_MENU, self.OnPageNext, id=ID_PAGE_DOWN) self.Bind(wx.EVT_MENU, self.OnPagePrev, id=ID_PAGE_UP) self.SetInitialSize((720, 680)) at = wx.AcceleratorTable([(wx.ACCEL_NORMAL, wx.WXK_F1, wx.ID_HELP_CONTENTS), (wx.ACCEL_CTRL, wx.WXK_PAGEDOWN, ID_PAGE_DOWN), (wx.ACCEL_CTRL, wx.WXK_PAGEUP, ID_PAGE_UP)]) self.SetAcceleratorTable(at) JobManager().AddVisual(self) self.Bind(EVT_REGISTER_JOB, self.OnRegisterJob) self.Bind(EVT_REMOVE_JOB, self.OnRemoveJob) def ObservableUpdate(self, obj, arg): if obj is self.__GetCurrentProject(): self.UpdateStatusText() #### Event-Handler - Begin ##################################################### # Jobs def OnRegisterJob(self, event): job = event.GetJob() if isinstance(job, RenderJob): self.statusBar.SetStatusText(_(u"Rendering in progress..."), 3) def OnRemoveJob(self, event): self.statusBar.SetStatusText("", 3) def OnCloseFrameJobManager(self, event): self.frmJobManager.Show(False) def OnShowFrameJobManager(self, event): self.frmJobManager.Show() # Pages def OnPageChanged(self, event): sel = event.GetSelection() page = None if sel == 0: self.notebook.SetWindowStyleFlag(0) self.SetTitle(Constants.APP_NAME) else: page = self.notebook.GetPage(sel) self.notebook.SetWindowStyleFlag(wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB) filepath = page.GetProject().GetFilename() self.SetTitle(Constants.APP_NAME + u' - ' + filepath) self._actionMgr.UpdateActions(page) self.UpdateStatusText() def OnPageNext(self, event): idx = self.notebook.GetSelection() idx += 1 if idx < self.notebook.GetPageCount(): self.notebook.SetSelection(idx) def OnPagePrev(self, event): idx = self.notebook.GetSelection() idx -= 1 if idx >= 0: self.notebook.SetSelection(idx) def OnPageClose(self, event): sel = event.GetSelection() if sel == 0: event.Veto() return else: if self.ClosePage(sel): event.Skip() else: event.Veto() # UpdateUI def OnCheckProjectActive(self, event): pnl = self.__GetCurrentPnlEditor() event.Enable(pnl is not None) def OnCheckProjectChanged(self, event): pnl = self.__GetCurrentPnlEditor() if pnl: event.Enable(pnl.HasChanged()) else: event.Enable(False) # Misc def OnStatusBarLeftDown(self, event): mpos = event.GetPosition() if self.statusBar.GetFieldRect(3).Contains(mpos) \ and self.statusBar.GetStatusText(3) != "": self.frmJobManager.Show() return pnlEditor = self.__GetCurrentPnlEditor() if pnlEditor: for idx in range(self.statusBar.GetFieldsCount()): if self.statusBar.GetFieldRect(idx).Contains(mpos): pnlEditor.OnStatusBarClick(idx - 1) return def OnClose(self, event): while self.notebook.GetPageCount() > 1: idx = 1 self.notebook.SetSelection(idx) if self.ClosePage(idx): self.notebook.DeletePage(idx) else: return JobManager().RemoveVisual(self) self.frmJobManager.Destroy() event.Skip() # Menu def OnSlideshow(self, event): dlg = DlgNewProject(self, _("Create new slideshow")) if dlg.ShowModal() == wx.ID_OK: photoFilmStrip = dlg.GetProject() self._NewSlideshow(photoFilmStrip) dlg.Destroy() def OnTimelapse(self, event): dlg = DlgNewProject(self, _("Create new timelapse")) if dlg.ShowModal() == wx.ID_OK: photoFilmStrip = dlg.GetProject() photoFilmStrip.SetTimelapse(True) self._NewTimelapse(photoFilmStrip) dlg.Destroy() def OnProjectLoad(self, event): dlg = wx.FileDialog(self, _(u"Select %s-Project") % Constants.APP_NAME, Settings().GetProjectPath(), "", Constants.APP_NAME + u'-' + _(u"Files") + " (*.pfs;*.pfsprod)|*.pfs;*.pfsprod", wx.FD_OPEN) if dlg.ShowModal() == wx.ID_OK: self.LoadProject(dlg.GetPath()) def OnProjectSave(self, event): pnlEditor = self.__GetCurrentPnlEditor() if pnlEditor: if pnlEditor.OnSave(): self.AddFileToHistory(pnlEditor.GetSaveFilePath()) def OnProjectSaveAs(self, event): pnlEditor = self.__GetCurrentPnlEditor() if pnlEditor: if pnlEditor.OnSaveAs(): self.AddFileToHistory(pnlEditor.GetSaveFilePath()) def OnProjectClose(self, event): sel = self.notebook.GetSelection() if self.ClosePage(sel): self.notebook.DeletePage(sel) def OnExit(self, event): self.Close() def OnHelpIndex(self, event): HelpViewer().DisplayID(HelpViewer.ID_INDEX) event.Skip() def OnHelpContent(self, event): HelpViewer().DisplayID(HelpViewer.ID_CREATE_PFS) event.Skip() def OnChangeLanguage(self, event): lang = ActionManager.LANG_MAP.get(event.GetId(), "en") Settings().SetLanguage(lang) ActionI18N().Execute() dlg = wx.MessageDialog(self, _(u"You must restart %s for your new language setting to take effect.") % Constants.APP_NAME, _(u"Information"), wx.ICON_INFORMATION | wx.OK) dlg.ShowModal() dlg.Destroy() def OnAbout(self, event): info = wx.adv.AboutDialogInfo() info.Name = Constants.APP_NAME info.Version = Constants.APP_VERSION_EX info.Copyright = u"(C) 2018 %s" % Constants.DEVELOPERS[0] info.Description = wordwrap(_("PhotoFilmStrip creates movies out of your pictures in just 3 steps. First select your photos, customize the motion path and render the video. There are several output possibilities for VCD, SVCD, DVD up to FULL-HD."), 350, wx.ClientDC(self)) info.WebSite = (Constants.APP_URL, "%s %s" % (Constants.APP_NAME, _(u"online"))) info.Developers = Constants.DEVELOPERS info.Translators = Constants.TRANSLATORS info.License = wordwrap(licenseText, 500, wx.ClientDC(self)) wx.adv.AboutBox(info) #### Event-Handler - END ####################################################### def __GetCurrentPnlEditor(self): sel = self.notebook.GetSelection() page = self.notebook.GetPage(sel) if isinstance(page, PnlEditorPage): return page def __GetCurrentProject(self): page = self.__GetCurrentPnlEditor() if page: return page.GetProject() return None def AddFileToHistory(self, filename): fileList = Settings().GetFileHistory() if filename in fileList: fileList.remove(filename) fileList.insert(0, filename) Settings().SetFileHistory(fileList) def UpdateStatusText(self): page = self.__GetCurrentPnlEditor() if page is None: self.statusBar.SetStatusText(Constants.APP_URL, 1) self.statusBar.SetStatusText("%s %s" % (Constants.APP_NAME, Constants.APP_VERSION), 2) else: self.statusBar.SetStatusText(page.GetStatusText(0), 1) self.statusBar.SetStatusText(page.GetStatusText(1), 2) def ClosePage(self, idx): page = self.notebook.GetPage(idx) if page.CheckAndAskSaving(): page.Close() return True else: return False def _NewSlideshow(self, project): pnl = PnlSlideshow(self.notebook, project) project.AddObserver(self) filepath = os.path.basename(project.GetFilename()) self.notebook.AddPage(pnl, os.path.basename(filepath), True) return pnl def _NewTimelapse(self, project): pnl = PnlTimelapse(self.notebook, project) project.AddObserver(self) filepath = os.path.basename(project.GetFilename()) self.notebook.AddPage(pnl, os.path.basename(filepath), True) return pnl def LoadProject(self, filepath, skipHistory=False): for idx in range(1, self.notebook.GetPageCount()): page = self.notebook.GetPage(idx) if page.GetProject().GetFilename() == filepath: self.notebook.SetSelection(idx) return prjFile = WxProjectFile(self, filename=filepath) result = prjFile.Load() if not result: dlg = wx.MessageDialog(self, _(u"Invalid %(app)s-Project: %(file)s") % {"app": Constants.APP_NAME, "file": filepath}, _(u"Error"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return project = prjFile.GetProject() pics = project.GetPictures() if project.GetTimelapse(): pnl = self._NewTimelapse(project) else: pnl = self._NewSlideshow(project) pnl.InsertPictures(pics) pnl.SetChanged(False) if not skipHistory: self.AddFileToHistory(filepath) # self.pnlWelcome.RefreshPage() # crashes on unix wx.CallAfter(self.pnlWelcome.RefreshPage) class ProjectDropTarget(wx.FileDropTarget): def __init__(self, frmMain): wx.FileDropTarget.__init__(self) self.frmMain = frmMain def OnDropFiles(self, x, y, filenames): if len(filenames) == 1: path = filenames[0] ext = os.path.splitext(path)[1].lower() if ext == '.pfs': self.frmMain.LoadProject(path) return True return False photofilmstrip-3.7.2/photofilmstrip/gui/ArtProvider.py0000644000232200023220000000100113560357351023636 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # import wx from wx.lib.art import img2pyartprov import photofilmstrip.res.images class ArtProvider: provider = None @classmethod def Init(cls): if cls.provider is None: cls.provider = img2pyartprov.Img2PyArtProvider( photofilmstrip.res.images, artIdPrefix='PFS_' ) wx.ArtProvider.Push(cls.provider) photofilmstrip-3.7.2/photofilmstrip/gui/PnlPfsProject.py0000644000232200023220000007437313560357351024154 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2017 Jens Goepfert # import os import logging import wx from photofilmstrip.action.ActionAutoPath import ActionAutoPath from photofilmstrip.action.ActionCenterPath import ActionCenterPath from photofilmstrip.action.ActionRender import ActionRender from photofilmstrip.core.Picture import Picture from photofilmstrip.core.Project import Project from photofilmstrip.lib.Settings import Settings from photofilmstrip.lib.common.ObserverPattern import Observer from photofilmstrip.lib.jobimpl.JobManager import JobManager from photofilmstrip.lib.util import CheckFile from photofilmstrip.gui.helper import CreateMenuItem from photofilmstrip.gui.ImageSectionEditor import ( ImageSectionEditor, EVT_RECT_CHANGED) from photofilmstrip.gui.PhotoFilmStripList import ( PhotoFilmStripList, EVT_CHANGED) from photofilmstrip.gui.util.ImageCache import ImageCache from photofilmstrip.gui.PnlEditorPage import PnlEditorPage from photofilmstrip.gui.PnlEditPicture import PnlEditPicture from photofilmstrip.gui.PnlAddPics import PnlAddPics from photofilmstrip.gui.DlgConfigureAudio import DlgConfigureAudio from photofilmstrip.gui.DlgPositionInput import DlgPositionInput from photofilmstrip.gui.DlgRender import DlgRender from photofilmstrip.gui.WxProjectFile import WxProjectFile from photofilmstrip.core.exceptions import RenderException [wxID_PNLPFSPROJECT, wxID_PNLPFSPROJECTBITMAPLEFT, wxID_PNLPFSPROJECTBITMAPRIGHT, wxID_PNLPFSPROJECTCMDMOVELEFT, wxID_PNLPFSPROJECTCMDMOVERIGHT, wxID_PNLPFSPROJECTCMDREMOVE, wxID_PNLPFSPROJECTLVPICS, wxID_PNLPFSPROJECTPANELTOP, wxID_PNLPFSPROJECTPNLADDPICS, wxID_PNLPFSPROJECTPNLEDITPICTURE, wxID_PNLPFSPROJECTTOOLBARIMGSECT, ] = [wx.NewId() for _init_ctrls in range(11)] [wxID_PNLPFSPROJECTTOOLBARIMGSECTADJUST, wxID_PNLPFSPROJECTTOOLBARIMGSECTFTTORIGHT, wxID_PNLPFSPROJECTTOOLBARIMGSECTGHTTOLEFT, wxID_PNLPFSPROJECTTOOLBARIMGSECTUNLOCK, wxID_PNLPFSPROJECTTOOLBARIMGSECTSWAP, wxID_PNLPFSPROJECTTOOLBARIMGSECTTOPATH, ] = [wx.NewId() for _init_coll_toolBarImgSect_Tools in range(6)] [ID_PIC_MOVE_LEFT, ID_PIC_MOVE_RIGHT, ID_PIC_REMOVE, ID_PIC_ROTATE_CW, ID_PIC_ROTATE_CCW, ID_PIC_MOTION_RANDOM, ID_PIC_MOTION_CENTER, ID_PIC_IMPORT, ID_MUSIC, ID_RENDER_FILMSTRIP, ID_EXPORT, ID_IMPORT, ] = [wx.NewId() for __ in range(12)] class PnlPfsProject(PnlEditorPage, Observer): _custom_classes = {"wx.Panel": ["PnlEditorPage", "ImageSectionEditor", "PnlEditPicture", "PnlAddPics"], "wx.ListView": ["PhotoFilmStripList"]} def _init_coll_sizerPictures_Items(self, parent): # generated method, don't edit parent.Add(self.lvPics, 1, border=0, flag=wx.EXPAND) parent.Add(self.sizerPictureCtrls, 0, border=0, flag=wx.EXPAND) def _init_coll_sizerPictureCtrls_Items(self, parent): # generated method, don't edit parent.Add(self.cmdMoveLeft, 0, border=2, flag=wx.ALL) parent.AddStretchSpacer(1) parent.Add(self.cmdMoveRight, 0, border=2, flag=wx.ALL) parent.AddStretchSpacer(1) parent.Add(self.cmdRemove, 0, border=2, flag=wx.ALL) def _init_coll_sizerMain_Items(self, parent): # generated method, don't edit parent.Add(self.panelTop, 1, border=0, flag=wx.EXPAND) parent.Add(self.pnlAddPics, 1, border=0, flag=wx.ALIGN_CENTER_HORIZONTAL) parent.Add(self.pnlEditPicture, 0, border=0, flag=wx.EXPAND) parent.Add(self.sizerPictures, 0, border=0, flag=wx.EXPAND) def _init_coll_sizerPnlTop_Items(self, parent): # generated method, don't edit parent.Add(self.bitmapLeft, 1, border=0, flag=wx.EXPAND | wx.ALL) parent.Add(self.toolBarImgSect, 0, border=0, flag=wx.EXPAND) parent.Add(self.bitmapRight, 1, border=0, flag=wx.ALL | wx.EXPAND) def _init_coll_toolBarImgSect_Tools(self, parent): # generated method, don't edit parent.AddTool(wxID_PNLPFSPROJECTTOOLBARIMGSECTTOPATH, "", wx.ArtProvider.GetBitmap('PFS_MOTION_RANDOM_24'), _(u'Random motion')) parent.AddSeparator() parent.AddTool(wxID_PNLPFSPROJECTTOOLBARIMGSECTFTTORIGHT, _(u'Set motion start to end'), wx.ArtProvider.GetBitmap('PFS_MOTION_START_TO_END_24'), _(u'Set motion start to end')) parent.AddTool(wxID_PNLPFSPROJECTTOOLBARIMGSECTGHTTOLEFT, _(u'Set motion end to start'), wx.ArtProvider.GetBitmap('PFS_MOTION_END_TO_START_24'), _(u'Set motion end to start')) parent.AddTool(wxID_PNLPFSPROJECTTOOLBARIMGSECTSWAP, _(u'Swap motion'), wx.ArtProvider.GetBitmap('PFS_MOTION_SWAP_24'), _(u'Swap motion')) parent.AddSeparator() parent.AddTool(wxID_PNLPFSPROJECTTOOLBARIMGSECTADJUST, _(u'Adjust motion manual'), wx.ArtProvider.GetBitmap('PFS_MOTION_MANUAL_24'), _(u'Adjust motion manual')) parent.AddSeparator() parent.AddCheckTool(wxID_PNLPFSPROJECTTOOLBARIMGSECTUNLOCK, _(u'Preserve image dimension'), wx.ArtProvider.GetBitmap('PFS_LOCK_24'), shortHelp=_(u'Preserve image dimension')) self.Bind(wx.EVT_TOOL, self.OnToolBarImgSectToolAutoPath, id=wxID_PNLPFSPROJECTTOOLBARIMGSECTTOPATH) self.Bind(wx.EVT_TOOL, self.OnToolBarImgSectToolLeftToRight, id=wxID_PNLPFSPROJECTTOOLBARIMGSECTFTTORIGHT) self.Bind(wx.EVT_TOOL, self.OnToolBarImgSectToolRightToLeft, id=wxID_PNLPFSPROJECTTOOLBARIMGSECTGHTTOLEFT) self.Bind(wx.EVT_TOOL, self.OnToolBarImgSectToolAdjust, id=wxID_PNLPFSPROJECTTOOLBARIMGSECTADJUST) self.Bind(wx.EVT_TOOL, self.OnToolBarImgSectSwap, id=wxID_PNLPFSPROJECTTOOLBARIMGSECTSWAP) self.Bind(wx.EVT_TOOL, self.OnToolBarImgSectUnlockTool, id=wxID_PNLPFSPROJECTTOOLBARIMGSECTUNLOCK) parent.Realize() def _init_sizers(self): # generated method, don't edit sizerPnlTop = wx.BoxSizer(orient=wx.HORIZONTAL) sizerMain = wx.BoxSizer(orient=wx.VERTICAL) self.sizerPictures = wx.BoxSizer(orient=wx.HORIZONTAL) self.sizerPictureCtrls = wx.BoxSizer(orient=wx.VERTICAL) self._init_coll_sizerPnlTop_Items(sizerPnlTop) self._init_coll_sizerMain_Items(sizerMain) self._init_coll_sizerPictures_Items(self.sizerPictures) self._init_coll_sizerPictureCtrls_Items(self.sizerPictureCtrls) self.SetSizer(sizerMain) self.panelTop.SetSizer(sizerPnlTop) def _InitCtrls(self): self.panelTop = wx.Panel(id=wxID_PNLPFSPROJECTPANELTOP, name=u'panelTop', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL) self.bitmapLeft = ImageSectionEditor(id=wxID_PNLPFSPROJECTBITMAPLEFT, name=u'bitmapLeft', parent=self.panelTop, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.toolBarImgSect = wx.ToolBar(id=wxID_PNLPFSPROJECTTOOLBARIMGSECT, name=u'toolBarImgSect', parent=self.panelTop, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.TB_VERTICAL | wx.NO_BORDER | wx.TB_NODIVIDER) self.bitmapRight = ImageSectionEditor(id=wxID_PNLPFSPROJECTBITMAPRIGHT, name=u'bitmapRight', parent=self.panelTop, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.pnlAddPics = PnlAddPics(id=wxID_PNLPFSPROJECTPNLADDPICS, name=u'pnlAddPics', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL) self.pnlEditPicture = PnlEditPicture(id=wxID_PNLPFSPROJECTPNLEDITPICTURE, name=u'pnlEditPicture', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL) self.lvPics = PhotoFilmStripList(id=wxID_PNLPFSPROJECTLVPICS, name=u'lvPics', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.HSCROLL) # | wx.ALWAYS_SHOW_SB) self.lvPics.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnLvPicsSelectionChanged, id=wxID_PNLPFSPROJECTLVPICS) self.cmdMoveLeft = wx.BitmapButton(bitmap=wx.ArtProvider.GetBitmap('PFS_IMAGE_MOVING_LEFT_32'), id=wxID_PNLPFSPROJECTCMDMOVELEFT, name=u'cmdMoveLeft', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.BU_AUTODRAW) self.cmdMoveLeft.SetBitmapDisabled(wx.ArtProvider.GetBitmap('PFS_IMAGE_MOVING_LEFT_D_32')) self.cmdMoveLeft.Bind(wx.EVT_BUTTON, self.OnCmdMoveLeftButton, id=wxID_PNLPFSPROJECTCMDMOVELEFT) self.cmdMoveRight = wx.BitmapButton(bitmap=wx.ArtProvider.GetBitmap('PFS_IMAGE_MOVING_RIGHT_32'), id=wxID_PNLPFSPROJECTCMDMOVERIGHT, name=u'cmdMoveRight', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.BU_AUTODRAW) self.cmdMoveRight.SetBitmapDisabled(wx.ArtProvider.GetBitmap('PFS_IMAGE_MOVING_RIGHT_D_32')) self.cmdMoveRight.Bind(wx.EVT_BUTTON, self.OnCmdMoveRightButton, id=wxID_PNLPFSPROJECTCMDMOVERIGHT) self.cmdRemove = wx.BitmapButton(bitmap=wx.ArtProvider.GetBitmap('PFS_IMAGE_REMOVE_32'), id=wxID_PNLPFSPROJECTCMDREMOVE, name=u'cmdRemove', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.BU_AUTODRAW) self.cmdRemove.SetBitmapDisabled(wx.ArtProvider.GetBitmap('PFS_IMAGE_REMOVE_D_32')) self.cmdRemove.Bind(wx.EVT_BUTTON, self.OnCmdRemoveButton, id=wxID_PNLPFSPROJECTCMDREMOVE) self._init_coll_toolBarImgSect_Tools(self.toolBarImgSect) self._init_sizers() def __init__(self, parent, project): PnlEditorPage.__init__(self, parent, id=wxID_PNLPFSPROJECT, name=u'PnlPfsProject') self.SetClientSize(wx.Size(400, 250)) self._InitCtrls() Observer.__init__(self) self.lvPics.SetDropTarget(ImageDropTarget(self)) self.imgProxyLeft = None self.imgProxyRight = None self.__project = project self.__usedAltPath = False self._InitImageProxy() self.bitmapLeft.SetAspect(project.GetAspect()) self.bitmapRight.SetAspect(project.GetAspect()) self.pnlAddPics.GetButton().Bind(wx.EVT_BUTTON, self.OnImportPics) self.pnlAddPics.stInfo.SetDropTarget(ImageDropTarget(self)) self.cmdMoveLeft.Enable(False) self.cmdMoveRight.Enable(False) self.cmdRemove.Enable(False) self.panelTop.Show(False) self.Bind(EVT_RECT_CHANGED, self.OnRectChanged, id=self.bitmapLeft.GetId()) self.Bind(EVT_RECT_CHANGED, self.OnRectChanged, id=self.bitmapRight.GetId()) self.Bind(EVT_CHANGED, self.OnPhotoFilmStripListChanged, id=self.lvPics.GetId()) project.AddObserver(self) self.pnlEditPicture.SetupModeByProject(project) self.SetInitialSize(self.GetEffectiveMinSize()) self.SetChanged(False) def _InitImageProxy(self): raise NotImplementedError() def GetFileExtension(self): return ".pfs" def GetSaveFilePath(self): return self.__project.GetFilename() def _Save(self, filepath): prjFile = WxProjectFile(self, self.__project, filepath) prjFile.Save(False) return True def AddMenuFileActions(self, menu): # CreateMenuItem(menu, self.ID_IMPORT, _(u"&Import Project")) # CreateMenuItem(menu, self.ID_EXPORT, _(u"&Export Project")) # menu.AppendSeparator() pass def AddMenuEditActions(self, menu): CreateMenuItem(menu, ID_PIC_IMPORT, _(u'&Import Pictures') + '\tCtrl+I', wx.ArtProvider.GetBitmap('PFS_IMPORT_PICTURES_16'), wx.ArtProvider.GetBitmap('PFS_IMPORT_PICTURES_D_16')) menu.AppendSeparator() CreateMenuItem(menu, ID_PIC_MOVE_LEFT, _(u'Move picture &left'), wx.ArtProvider.GetBitmap('PFS_IMAGE_MOVING_LEFT_16'), wx.ArtProvider.GetBitmap('PFS_IMAGE_MOVING_LEFT_D_16')) CreateMenuItem(menu, ID_PIC_MOVE_RIGHT, _(u'Move picture &right'), wx.ArtProvider.GetBitmap('PFS_IMAGE_MOVING_RIGHT_16'), wx.ArtProvider.GetBitmap('PFS_IMAGE_MOVING_RIGHT_D_16')) menu.AppendSeparator() CreateMenuItem(menu, ID_PIC_REMOVE, _(u'R&emove Picture') + '\tCtrl+Del', wx.ArtProvider.GetBitmap('PFS_IMAGE_REMOVE_16'), wx.ArtProvider.GetBitmap('PFS_IMAGE_REMOVE_D_16')) menu.AppendSeparator() CreateMenuItem(menu, ID_PIC_ROTATE_CW, _(u'Rotate &clockwise') + '\tCtrl+r', wx.ArtProvider.GetBitmap('PFS_IMAGE_ROTATION_RIGHT_16'), wx.ArtProvider.GetBitmap('PFS_IMAGE_ROTATION_RIGHT_D_16')) CreateMenuItem(menu, ID_PIC_ROTATE_CCW, _(u'Rotate counter clock&wise') + '\tCtrl+l', wx.ArtProvider.GetBitmap('PFS_IMAGE_ROTATION_LEFT_16'), wx.ArtProvider.GetBitmap('PFS_IMAGE_ROTATION_LEFT_D_16')) menu.AppendSeparator() CreateMenuItem(menu, ID_PIC_MOTION_RANDOM, _(u'Random &motion') + '\tCtrl+d', wx.ArtProvider.GetBitmap('PFS_MOTION_RANDOM_16'), wx.ArtProvider.GetBitmap('PFS_MOTION_RANDOM_D_16')) CreateMenuItem(menu, ID_PIC_MOTION_CENTER, _(u'Centralize m&otion') + '\tCtrl+f', wx.ArtProvider.GetBitmap('PFS_MOTION_CENTER_16'), wx.ArtProvider.GetBitmap('PFS_MOTION_CENTER_D_16')) def ConnectEvents(self, evtHandler): evtHandler.Bind(wx.EVT_MENU, self.OnProjectExport, id=ID_EXPORT) evtHandler.Bind(wx.EVT_MENU, self.OnProjectImport, id=ID_IMPORT) evtHandler.Bind(wx.EVT_MENU, self.OnCmdMoveLeftButton, id=ID_PIC_MOVE_LEFT) evtHandler.Bind(wx.EVT_MENU, self.OnCmdMoveRightButton, id=ID_PIC_MOVE_RIGHT) evtHandler.Bind(wx.EVT_MENU, self.OnCmdRemoveButton, id=ID_PIC_REMOVE) evtHandler.Bind(wx.EVT_MENU, self.OnCmdRotateLeftButton, id=ID_PIC_ROTATE_CCW) evtHandler.Bind(wx.EVT_MENU, self.OnCmdRotateRightButton, id=ID_PIC_ROTATE_CW) evtHandler.Bind(wx.EVT_MENU, self.OnCmdMotionRandom, id=ID_PIC_MOTION_RANDOM) evtHandler.Bind(wx.EVT_MENU, self.OnCmdMotionCenter, id=ID_PIC_MOTION_CENTER) evtHandler.Bind(wx.EVT_MENU, self.OnImportPics, id=ID_PIC_IMPORT) evtHandler.Bind(wx.EVT_MENU, self.OnConfigureMusic, id=ID_MUSIC) evtHandler.Bind(wx.EVT_MENU, self.OnRenderFilmstrip, id=ID_RENDER_FILMSTRIP) evtHandler.Bind(wx.EVT_UPDATE_UI, self.OnCheckImageSelected, id=ID_PIC_REMOVE) evtHandler.Bind(wx.EVT_UPDATE_UI, self.OnCheckImageSelected, id=ID_PIC_ROTATE_CCW) evtHandler.Bind(wx.EVT_UPDATE_UI, self.OnCheckImageSelected, id=ID_PIC_ROTATE_CW) evtHandler.Bind(wx.EVT_UPDATE_UI, self.OnCheckImageSelected, id=ID_PIC_MOVE_LEFT) evtHandler.Bind(wx.EVT_UPDATE_UI, self.OnCheckImageSelected, id=ID_PIC_MOVE_RIGHT) evtHandler.Bind(wx.EVT_UPDATE_UI, self.OnCheckImageSelected, id=ID_PIC_MOTION_RANDOM) evtHandler.Bind(wx.EVT_UPDATE_UI, self.OnCheckImageSelected, id=ID_PIC_MOTION_CENTER) evtHandler.Bind(wx.EVT_UPDATE_UI, self.OnCheckProjectReady, id=ID_RENDER_FILMSTRIP) def DisconnEvents(self, evtHandler): for wId in [ID_PIC_MOVE_LEFT, ID_PIC_MOVE_RIGHT, ID_PIC_REMOVE, ID_PIC_ROTATE_CCW, ID_PIC_ROTATE_CW, ID_PIC_MOTION_RANDOM, ID_PIC_MOTION_CENTER, ID_PIC_IMPORT, ID_MUSIC, ID_RENDER_FILMSTRIP]: evtHandler.Disconnect(wId) def GetSelectedImageState(self): items = self.lvPics.GetSelected() if len(items) == 0: kind = 'none' elif items[0] == 0: if self.lvPics.GetItemCount() == 1: kind = 'none' # to disable move buttons else: kind = 'first' elif items[0] == self.lvPics.GetItemCount() - 1: kind = 'last' else: kind = 'any' # if len(items) > 1: # kind = 'multi' return kind def OnProjectExport(self, event): prj = self.__project curFilePath = prj.GetFilename() dlg = wx.FileDialog(self, _(u"Export slideshow"), Settings().GetProjectPath(), curFilePath, u"%s %s" % (_(u"Portable slideshow"), "(*.ppfs)|*.ppfs"), wx.FD_SAVE) if dlg.ShowModal() == wx.ID_OK: filepath = dlg.GetPath() if os.path.splitext(filepath)[1].lower() != ".ppfs": filepath += ".ppfs" prjFile = WxProjectFile(self, self.__project, filepath) prjFile.Save(True) def OnProjectImport(self, event): dlg = wx.FileDialog(self, _(u"Import Slideshow"), Settings().GetProjectPath(), "", u"%s %s" % (_(u"Portable slideshow"), "(*.ppfs)|*.ppfs"), wx.FD_OPEN) if dlg.ShowModal() == wx.ID_OK: filepath = dlg.GetPath() prjFile = WxProjectFile(self, filename=filepath) prjFile.Load() def OnImportPics(self, event): dlg = wx.FileDialog(self, _(u"Import images"), Settings().GetImagePath(), "", _(u"Image files") + " (*.*)|*.*", wx.FD_OPEN | wx.FD_MULTIPLE | wx.FD_PREVIEW) if dlg.ShowModal() == wx.ID_OK: pics = [] for path in dlg.GetPaths(): if not self._CheckImportedPic(path): continue pic = Picture(path) pics.append(pic) ImageCache().RegisterPicture(pic) selItms = self.lvPics.GetSelected() self.InsertPictures(pics, selItms[0] + 1 if selItms else None, autopath=True) Settings().SetImagePath(os.path.dirname(path)) selPics = self.lvPics.GetSelectedPictures() self.pnlEditPicture.SetPictures(selPics) dlg.Destroy() def _CheckImportedPic(self, path): # pylint: disable=unused-argument return True def OnConfigureMusic(self, event): dlg = DlgConfigureAudio(self, self.GetProject()) dlg.ShowModal() dlg.Destroy() def OnRenderFilmstrip(self, event): self.PrepareRendering() project = self.__project dlg = DlgRender(self, project.GetAspect()) try: if dlg.ShowModal() != wx.ID_OK: return profile = dlg.GetProfile() draftMode = dlg.GetDraftMode() rendererClass = dlg.GetRendererClass() finally: dlg.Destroy() ar = ActionRender(project, profile, rendererClass, draftMode) try: ar.Execute() renderJob = ar.GetRenderJob() JobManager().EnqueueContext(renderJob) except RenderException as exc: dlg = wx.MessageDialog(self, exc.GetMessage(), _(u"Error"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() def OnCheckImageSelected(self, event): value = self.IsPictureSelected() kind = self.GetSelectedImageState() if event.GetId() == ID_PIC_MOVE_LEFT: # FIXME: does not work with multiselect value = kind not in ['first', 'none'] and value elif event.GetId() == ID_PIC_MOVE_RIGHT: # FIXME: does not work with multiselect value = kind not in ['last', 'none'] and value event.Enable(value) def OnCheckProjectReady(self, event): event.Enable(self.IsReady()) def OnLvPicsSelectionChanged(self, event): selItems = self.lvPics.GetSelected() self.cmdMoveLeft.Enable(selItems.count(0) == 0) self.cmdMoveRight.Enable(selItems.count(self.lvPics.GetItemCount() - 1) == 0) self.cmdRemove.Enable(len(selItems) > 0) selPics = self.lvPics.GetSelectedPictures() self.pnlEditPicture.SetPictures(selPics) self.panelTop.Enable(len(selPics) == 1) self.bitmapRight.Enable(len(selPics) == 1) self.bitmapLeft.Enable(len(selPics) == 1) self._OnPicsSelectionChanged(selItems, selPics) if event: event.Skip() def _OnPicsSelectionChanged(self, selItems, selPics): raise NotImplementedError() def OnRectChanged(self, event): selItem = self.lvPics.GetSelected() pic = None if selItem: pic = self.lvPics.GetPicture(selItem[0]) if pic is None: return if self.__project.GetTimelapse(): self.__OnRectChangedTimelapse(event, pic, selItem[0]) else: self.__OnRectChangedDefault(event, pic) if event.CheckImageDimensionLock(): self._CheckAndSetLock(pic) def __OnRectChangedDefault(self, event, pic): if event.GetEventObject() is self.bitmapLeft: pic.SetStartRect(tuple(self.bitmapLeft.GetSection())) else: pic.SetTargetRect(tuple(self.bitmapRight.GetSection())) def __OnRectChangedTimelapse(self, event, pic, selIdx): if event.GetEventObject() is self.bitmapLeft: pic.SetStartRect(tuple(self.bitmapLeft.GetSection())) prevPic = self.lvPics.GetPicture(selIdx - 1) if prevPic: prevPic.SetTargetRect(tuple(self.bitmapLeft.GetSection())) else: pic.SetTargetRect(tuple(self.bitmapRight.GetSection())) nextPic = self.lvPics.GetPicture(selIdx + 1) if nextPic: nextPic.SetStartRect(tuple(self.bitmapRight.GetSection())) def OnCmdMoveLeftButton(self, event): selItems = self.lvPics.GetSelected() selItems.sort() for selItem in selItems: self.lvPics.SwapPictures(selItem, selItem - 1) self.SetChanged(True) def OnCmdMoveRightButton(self, event): selItems = self.lvPics.GetSelected() selItems.sort(reverse=True) for selItem in selItems: self.lvPics.SwapPictures(selItem, selItem + 1) self.SetChanged(True) def OnCmdRemoveButton(self, event): selItems = self.lvPics.GetSelected() # remove pics starting at the end selItems.sort(reverse=True) for selItem in selItems: self.lvPics.DeleteItem(selItem) if self.lvPics.GetItemCount() == 0: self.imgProxyLeft.SetPicture(None) self.imgProxyRight.SetPicture(None) self.pnlEditPicture.SetPictures(None) self.pnlEditPicture.Enable(False) self.cmdMoveLeft.Enable(False) self.cmdMoveRight.Enable(False) self.pnlAddPics.Show(True) self.panelTop.Show(False) self.cmdRemove.Enable(self.lvPics.GetItemCount() > 0) self.Layout() def OnCmdRotateLeftButton(self, event): self.pnlEditPicture.OnCmdRotateLeftButton(event) def OnCmdRotateRightButton(self, event): self.pnlEditPicture.OnCmdRotateRightButton(event) def OnCmdMotionRandom(self, event): self.OnMotionRandom() def OnCmdMotionCenter(self, event): self.OnMotionCenter() def OnPhotoFilmStripListChanged(self, event): self.__project.SetPictures(self.lvPics.GetPictures()) self.SetChanged(True) def OnToolBarImgSectToolAutoPath(self, event): self.OnMotionRandom() def OnToolBarImgSectToolLeftToRight(self, event): selItem = self.lvPics.GetSelected() pic = self.lvPics.GetPicture(selItem[0]) if pic is None: return pic.SetTargetRect(pic.GetStartRect()) def OnToolBarImgSectToolRightToLeft(self, event): selItem = self.lvPics.GetSelected() pic = self.lvPics.GetPicture(selItem[0]) if pic is None: return pic.SetStartRect(pic.GetTargetRect()) def OnToolBarImgSectSwap(self, event): selItem = self.lvPics.GetSelected() pic = self.lvPics.GetPicture(selItem[0]) if pic is None: return target = pic.GetTargetRect() pic.SetTargetRect(pic.GetStartRect()) pic.SetStartRect(target) def OnToolBarImgSectToolAdjust(self, event): selItem = self.lvPics.GetSelected() selPic = self.lvPics.GetPicture(selItem[0]) dlg = DlgPositionInput(self, selPic, self.__project.GetAspect()) dlg.ShowModal() dlg.Destroy() def OnMotionRandom(self): for pic in self.lvPics.GetSelectedPictures(): actAp = ActionAutoPath(pic, self.__project.GetAspect()) actAp.Execute() def OnMotionCenter(self): for pic in self.lvPics.GetSelectedPictures(): actCp = ActionCenterPath(pic, self.__project.GetAspect()) actCp.Execute() def Close(self): self.imgProxyLeft.RemoveObserver(self.bitmapLeft) self.imgProxyRight.RemoveObserver(self.bitmapRight) self.imgProxyLeft.Destroy() self.imgProxyRight.Destroy() def GetProject(self): return self.__project def PrepareRendering(self): for audioFile in self.__project.GetAudioFiles(): if not CheckFile(audioFile): dlg = wx.MessageDialog(self, _(u"Audio file '%s' does not exist! Continue anyway?") % audioFile, _(u"Warning"), wx.YES_NO | wx.ICON_WARNING) dlgResult = dlg.ShowModal() dlg.Destroy() if dlgResult == wx.ID_NO: return else: break def InsertPictures(self, pics, position=None, autopath=False): logging.debug("InsertPictures(pos=%s)", position) if position is None: position = self.lvPics.GetItemCount() self.lvPics.Freeze() for pic in pics: if autopath: actAp = ActionAutoPath(pic, self.__project.GetAspect()) actAp.Execute() self.lvPics.InsertPicture(position, pic) position += 1 pic.AddObserver(self) self.lvPics.Thaw() if len(self.lvPics.GetSelected()) == 0: self.lvPics.Select(0) self.SetChanged(True) self.pnlAddPics.Show(self.lvPics.GetItemCount() == 0) self.panelTop.Show(self.lvPics.GetItemCount() != 0) self.Layout() self.lvPics.SetFocus() def ObservableUpdate(self, obj, arg): if isinstance(obj, Picture): if arg == 'bitmap': if self.bitmapLeft._imgProxy._picture is obj: self.imgProxyLeft.SetPicture(obj) elif self.bitmapRight._imgProxy._picture is obj: self.imgProxyRight.SetPicture(obj) self.lvPics.Refresh() if arg == 'duration': self.__project.Notify("duration") if arg == 'start' and self.bitmapLeft._imgProxy._picture is obj: self.bitmapLeft.SetSection(wx.Rect(*obj.GetStartRect())) if arg == 'target' and self.bitmapLeft._imgProxy._picture is obj: self.bitmapRight.SetSection(wx.Rect(*obj.GetTargetRect())) self.SetChanged(True) elif isinstance(obj, Project): if arg == 'duration': self.pnlEditPicture.SetupModeByProject(self.__project) self.SetChanged(True) def IsReady(self): return self.lvPics.GetItemCount() > 0 def IsPictureSelected(self): return len(self.lvPics.GetSelected()) > 0 def _CheckAndSetLock(self, pic): unlocked = False for rect in (pic.GetStartRect(), pic.GetTargetRect()): if rect[0] < 0 or rect[1] < 0 \ or rect[2] > pic.GetWidth() or rect[3] > pic.GetHeight() \ or rect[0] + rect[2] > pic.GetWidth() \ or rect[1] + rect[3] > pic.GetHeight(): unlocked = True break self.toolBarImgSect.ToggleTool(wxID_PNLPFSPROJECTTOOLBARIMGSECTUNLOCK, unlocked) if unlocked: resName = 'PFS_UNLOCK_24' else: resName = 'PFS_LOCK_24' self.toolBarImgSect.SetToolNormalBitmap( wxID_PNLPFSPROJECTTOOLBARIMGSECTUNLOCK, wx.ArtProvider.GetBitmap(resName, wx.ART_TOOLBAR, wx.DefaultSize)) self.bitmapLeft.SetLock(not unlocked) self.bitmapRight.SetLock(not unlocked) def OnToolBarImgSectUnlockTool(self, event): if event.IsChecked(): resName = 'PFS_UNLOCK_24' else: resName = 'PFS_LOCK_24' self.toolBarImgSect.SetToolNormalBitmap( wxID_PNLPFSPROJECTTOOLBARIMGSECTUNLOCK, wx.ArtProvider.GetBitmap(resName, wx.ART_TOOLBAR, wx.DefaultSize)) self.bitmapLeft.SetLock(not event.IsChecked()) self.bitmapRight.SetLock(not event.IsChecked()) class ImageDropTarget(wx.FileDropTarget): def __init__(self, pnlPfs): wx.FileDropTarget.__init__(self) self.pnlPfs = pnlPfs def OnDropFiles(self, x, y, filenames): itm = self.pnlPfs.lvPics.HitTest((x, y)) logging.debug("OnDropFiles(%d, %d, %s): %s", x, y, filenames, itm) pics = [] for path in filenames: ext = os.path.splitext(path)[1].lower() if ext in ['.jpg', '.jpeg', '.png', '.bmp']: pic = Picture(path) pics.append(pic) if pics: self.pnlPfs.InsertPictures(pics, itm + 1 if itm != wx.NOT_FOUND else None, True) return True return False photofilmstrip-3.7.2/photofilmstrip/gui/WxProjectFile.py0000644000232200023220000000724113560357351024136 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # import time import wx from photofilmstrip.lib.Settings import Settings from photofilmstrip.core.ProjectFile import ProjectFile from photofilmstrip.lib.jobimpl.VisualJob import VisualJob from photofilmstrip.lib.jobimpl.WxVisualJobHandler import EVT_JOB_RESULT, WxInteractionEvent from photofilmstrip.lib.jobimpl.JobManager import JobManager from photofilmstrip.lib.jobimpl.DlgJobVisual import DlgJobVisual class WxProjectFile(ProjectFile): def __init__(self, wxParent, project=None, filename=None): ProjectFile.__init__(self, project, filename) self.__wxParent = wxParent self.__wxvJob = None self.__result = None def __WaitUntilJobDone(self): while self.__result is None: if wx.IsMainThread(): wx.Yield() time.sleep(0.05) self.__wxvJob = None try: return self.__result finally: self.__result = None def __OnJobDone(self, event): self.__result = event.GetResult() def __Load(self, importPath, job=None): return ProjectFile.Load(self, importPath) def __Save(self, includePics, job=None): ProjectFile.Save(self, includePics) return True def _SelectAlternatePath(self, imgPath): sapEvent = SelectAlternatePathEvent(imgPath) self.__wxvJob._Interact(sapEvent) def _StepProgress(self, msg): self.__wxvJob.StepProgress(msg) def Load(self, importPath=None): wxvJob = VisualJob(_("Loading project %s") % self._filename, self.__Load, args=(importPath,)) wxvJob.SetAltPath = self.SetAltPath dlg = DlgJobVisual(self.__wxParent, wxvJob) dlg.Bind(EVT_JOB_RESULT, self.__OnJobDone) wxvJob.AddVisualJobHandler(dlg) self.__wxvJob = wxvJob JobManager().EnqueueContext(wxvJob) try: return self.__WaitUntilJobDone() finally: dlg.Destroy() def Save(self, includePics=False): wxvJob = VisualJob(_("Saving project %s") % self._filename, self.__Save, args=(includePics,), maxProgress=len(self._project.GetPictures())) dlg = DlgJobVisual(self.__wxParent, wxvJob) dlg.Bind(EVT_JOB_RESULT, self.__OnJobDone) wxvJob.AddVisualJobHandler(dlg) self.__wxvJob = wxvJob JobManager().EnqueueContext(wxvJob) try: return self.__WaitUntilJobDone() finally: dlg.Destroy() class SelectAlternatePathEvent(WxInteractionEvent): def __init__(self, imgPath): WxInteractionEvent.__init__(self) self.__imgPath = imgPath def OnProcess(self, wxParent): dlg = wx.MessageDialog(wxParent, _(u"Some images does not exist in the folder '%s' anymore. If the files has moved you can select the new path. Do you want to select a new path?") % self.__imgPath, _(u"Question"), wx.YES_NO | wx.ICON_QUESTION) try: if dlg.ShowModal() == wx.ID_NO: self.GetJob().SetAltPath(self.__imgPath, self.__imgPath) return finally: dlg.Destroy() dlg = wx.DirDialog(wxParent, defaultPath=Settings().GetImagePath()) try: if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() self.GetJob().SetAltPath(self.__imgPath, path) return else: self.Skip() finally: dlg.Destroy() photofilmstrip-3.7.2/photofilmstrip/gui/HelpViewer.py0000644000232200023220000000205713560357351023463 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # import os import sys from photofilmstrip.lib.util import StartFile class HelpViewer: ID_INDEX = "index.html" ID_CREATE_PFS = "createpfs.html" ID_RENDER = "renderpfs.html" def __init__(self): basedir = os.path.dirname(os.path.abspath(sys.argv[0])) docDir = None for docDir in (os.path.join("..", "share", "doc", "photofilmstrip", "html"), # linux os.path.join("share", "doc", "photofilmstrip", "html"), # win os.path.join("..", "build", "sphinx", "html")): # source docDir = os.path.join(basedir, docDir) if os.path.isdir(docDir): break else: raise RuntimeError("helpdir not found!") self.docDir = os.path.abspath(docDir) def DisplayID(self, ident): StartFile(os.path.join(self.docDir, ident)) def Show(self): StartFile(os.path.join(self.docDir, self.ID_INDEX)) photofilmstrip-3.7.2/photofilmstrip/gui/DlgRender.py0000644000232200023220000003202013560357351023250 0ustar debalancedebalance# Boa:Dialog:DlgRender # -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # import wx import wx.adv from photofilmstrip.core.OutputProfile import ( GetOutputProfiles, GetMPEGProfiles) from photofilmstrip.core.Renderer import RENDERERS from photofilmstrip.lib.Settings import Settings from photofilmstrip.gui.ctrls.PnlDlgHeader import PnlDlgHeader from photofilmstrip.gui.HelpViewer import HelpViewer from photofilmstrip.gui.DlgRendererProps import DlgRendererProps [wxID_DLGRENDER, wxID_DLGRENDERCBDRAFT, wxID_DLGRENDERCHOICEFORMAT, wxID_DLGRENDERCHOICEPROFILE, wxID_DLGRENDERCMDCANCEL, wxID_DLGRENDERCMDHELP, wxID_DLGRENDERCMDRENDERERPROPS, wxID_DLGRENDERCMDSTART, wxID_DLGRENDERPNLHDR, wxID_DLGRENDERPNLSETTINGS, wxID_DLGRENDERSTFORMAT, wxID_DLGRENDERSTPROFILE, ] = [wx.NewId() for _init_ctrls in range(12)] class DlgRender(wx.Dialog): _custom_classes = {"wx.Choice": ["FormatComboBox"], "wx.Panel": ["PnlDlgHeader"]} DEFAULT_FORMAT = u"x264/AC3 (MKV)" DEFAULT_PROFILE = u"HD 720p@25.00 fps" def _init_coll_sizerMain_Items(self, parent): # generated method, don't edit parent.Add(self.pnlHdr, 0, border=0, flag=wx.EXPAND) parent.Add(self.pnlSettings, 0, border=4, flag=wx.ALL) parent.AddSpacer(8) parent.Add(self.sizerCmd, 0, border=4, flag=wx.EXPAND | wx.ALL) def _init_coll_sizerCmd_Items(self, parent): # generated method, don't edit parent.Add(self.cmdHelp, 0, border=0, flag=0) parent.AddStretchSpacer(1) parent.Add(self.cmdCancel, 0, border=0, flag=0) parent.AddSpacer(8) parent.Add(self.cmdStart, 0, border=0, flag=0) def _init_coll_sizerSettings_Items(self, parent): # generated method, don't edit parent.Add(self.stFormat, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) parent.Add(self.choiceFormat, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) parent.Add(self.cmdRendererProps, 0, border=0, flag=0) parent.Add(self.stProfile, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) parent.Add(self.choiceProfile, 0, border=0, flag=wx.EXPAND) parent.AddSpacer(8) parent.AddSpacer(8) parent.Add(self.cbDraft, 0, border=0, flag=0) def _init_coll_sizerSettings_Growables(self, parent): # generated method, don't edit parent.AddGrowableCol(2) def _init_sizers(self): # generated method, don't edit self.sizerMain = wx.BoxSizer(orient=wx.VERTICAL) self.sizerCmd = wx.BoxSizer(orient=wx.HORIZONTAL) self.sizerSettings = wx.FlexGridSizer(cols=3, hgap=8, rows=5, vgap=8) self.sizerSettings.SetFlexibleDirection(wx.BOTH) self._init_coll_sizerMain_Items(self.sizerMain) self._init_coll_sizerCmd_Items(self.sizerCmd) self._init_coll_sizerSettings_Items(self.sizerSettings) self._init_coll_sizerSettings_Growables(self.sizerSettings) self.SetSizer(self.sizerMain) self.pnlSettings.SetSizer(self.sizerSettings) def _init_ctrls(self, prnt): # generated method, don't edit wx.Dialog.__init__(self, id=wxID_DLGRENDER, name=u'DlgRender', parent=prnt, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.DEFAULT_DIALOG_STYLE, title=_(u'Render project')) self.pnlHdr = PnlDlgHeader(id=wxID_DLGRENDERPNLHDR, name=u'pnlHdr', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL) self.pnlSettings = wx.Panel(id=wxID_DLGRENDERPNLSETTINGS, name=u'pnlSettings', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL) self.stFormat = wx.StaticText(id=wxID_DLGRENDERSTFORMAT, label=_(u'Format:'), name=u'stFormat', parent=self.pnlSettings, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.choiceFormat = FormatComboBox(choices=[], id=wxID_DLGRENDERCHOICEFORMAT, name=u'choiceFormat', parent=self.pnlSettings, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.CB_READONLY) self.choiceFormat.SetSizeHints(400, -1) self.choiceFormat.Bind(wx.EVT_COMBOBOX, self.OnChoiceFormat, id=wxID_DLGRENDERCHOICEFORMAT) self.cmdRendererProps = wx.BitmapButton(bitmap=wx.ArtProvider.GetBitmap('PFS_VIDEO_FORMAT_16'), id=wxID_DLGRENDERCMDRENDERERPROPS, name=u'cmdRendererProps', parent=self.pnlSettings, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.BU_AUTODRAW) self.cmdRendererProps.SetToolTip(_(u"Properties")) self.cmdRendererProps.Bind(wx.EVT_BUTTON, self.OnCmdRendererPropsButton, id=wxID_DLGRENDERCMDRENDERERPROPS) self.stProfile = wx.StaticText(id=wxID_DLGRENDERSTPROFILE, label=_(u'Profile:'), name=u'stProfile', parent=self.pnlSettings, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.choiceProfile = wx.Choice(choices=[], id=wxID_DLGRENDERCHOICEPROFILE, name=u'choiceProfile', parent=self.pnlSettings, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.choiceProfile.SetSizeHints(400, -1) self.cbDraft = wx.CheckBox(id=wxID_DLGRENDERCBDRAFT, label=_(u'Draft'), name=u'cbDraft', parent=self.pnlSettings, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.cbDraft.SetValue(False) self.cmdHelp = wx.Button(id=wx.ID_HELP, label=_(u'&Help'), name=u'cmdHelp', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.cmdHelp.Bind(wx.EVT_BUTTON, self.OnCmdHelpButton, id=wx.ID_HELP) self.cmdCancel = wx.Button(id=wxID_DLGRENDERCMDCANCEL, label=_(u'&Cancel'), name=u'cmdCancel', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.cmdCancel.Bind(wx.EVT_BUTTON, self.OnCmdCancelButton, id=wxID_DLGRENDERCMDCANCEL) self.cmdStart = wx.Button(id=wxID_DLGRENDERCMDSTART, label=_(u'&Start'), name=u'cmdStart', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.cmdStart.Bind(wx.EVT_BUTTON, self.OnCmdStartButton, id=wxID_DLGRENDERCMDSTART) self._init_sizers() def __init__(self, parent, aspectRatio): self._init_ctrls(parent) self.Bind(wx.EVT_CLOSE, self.OnCmdCancelButton) self.pnlHdr.SetTitle(_('Configure output and start render process')) self.pnlHdr.SetBitmap(wx.ArtProvider.GetBitmap('PFS_RENDER_32')) self.cbDraft.SetToolTip(_(u"Activate this option to generate a preview of your PhotoFilmStrip. The rendering process will speed up dramatically, but results in lower quality.")) self.aspectRatio = aspectRatio self.__InitProfiles() settings = Settings() if settings.GetUsedRenderer() is None: self.choiceFormat.SetStringSelection(self.DEFAULT_FORMAT) else: self.choiceFormat.SetSelection(settings.GetUsedRenderer()) self.OnChoiceFormat(None) self.__SelectProfileByName(settings.GetLastProfile()) self.SetEscapeId(wxID_DLGRENDERCMDCANCEL) self.Fit() self.CentreOnParent() self.SetFocus() self.profile = None self.draftMode = False self.rendererClass = None def __GetChoiceDataSelected(self, choice): return choice.GetClientData(choice.GetSelection()) def __SelectProfileByName(self, profName): if profName is None: profName = self.DEFAULT_PROFILE choice = self.choiceProfile for idx in range(choice.GetCount()): prof = choice.GetClientData(idx) if prof and prof.GetName() == profName: choice.Select(idx) return choice.Select(0) def __InitProfiles(self, filtr=None, profiles=None): if profiles is None: profiles = [] profs = GetOutputProfiles(self.aspectRatio) for prof in profs: if prof.GetFriendlyName(): profiles.append(prof) profiles.append("-") profiles.extend(profs) selection = self.choiceFormat.GetStringSelection() self.choiceProfile.Clear() useFriendlyName = True for profile in profiles: if profile == "-": self.choiceProfile.Append(u"----------") useFriendlyName = False continue if filtr and not profile.GetName().startswith(filtr): continue if useFriendlyName: profName = profile.GetFriendlyName() else: profName = profile.GetName() self.choiceProfile.Append(u"%s (%sx%s)" % (profName, profile.GetResolution()[0], profile.GetResolution()[1]), profile) self.choiceProfile.SetStringSelection(selection) def OnChoiceFormat(self, event): if event is None: formatData = self.__GetChoiceDataSelected(self.choiceFormat) else: formatData = event.GetClientData() if isinstance(formatData, FormatData): self.cmdStart.Enable(formatData.IsOk()) if formatData.IsMPEG(): self.__InitProfiles(formatData.GetRendererClass().GetName().split(" ")[0], GetMPEGProfiles()) else: self.__InitProfiles() self.__SelectProfileByName(Settings().GetLastProfile()) def OnCmdStartButton(self, event): formatData = self.__GetChoiceDataSelected(self.choiceFormat) self.rendererClass = formatData.GetRendererClass() profile = self.__GetChoiceDataSelected(self.choiceProfile) if profile is None: return self.profile = profile self.draftMode = self.cbDraft.GetValue() self.EndModal(wx.ID_OK) def OnCmdCancelButton(self, event): self.EndModal(wx.ID_CANCEL) def OnCmdRendererPropsButton(self, event): data = self.__GetChoiceDataSelected(self.choiceFormat) if data is None: return rendererClass = data.GetRendererClass() dlg = DlgRendererProps(self, rendererClass) dlg.ShowModal() dlg.Destroy() def OnCmdHelpButton(self, event): HelpViewer().DisplayID(HelpViewer.ID_RENDER) event.Skip() def GetProfile(self): return self.profile def GetDraftMode(self): return self.draftMode def GetRendererClass(self): return self.rendererClass class FormatComboBox(wx.adv.OwnerDrawnComboBox): def __init__(self, *args, **kwargs): wx.adv.OwnerDrawnComboBox.__init__(self, *args, **kwargs) for rend in RENDERERS: self.AddRenderer(rend) def AddRenderer(self, rend, altName=None): msgList = [] rend.CheckDependencies(msgList) self.Append(altName or rend.GetName(), FormatData(rend, msgList)) def SetSelection(self, index): if index >= self.GetCount(): index = 0 wx.adv.OwnerDrawnComboBox.SetSelection(self, index) def OnDrawItem(self, dc, rect, item, flags): if item == wx.NOT_FOUND: return data = self.GetClientData(item) rect2 = wx.Rect(*rect) rect2.Deflate(5, 0) if data.GetMessages(): bmp = wx.ArtProvider.GetBitmap('PFS_ALERT_16') dc.SetTextForeground(wx.SystemSettings.GetColour(wx.SYS_COLOUR_GRAYTEXT)) else: bmp = wx.NullBitmap if flags & wx.adv.ODCB_PAINTING_SELECTED: dc.SetTextForeground(wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT)) else: dc.SetTextForeground(wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT)) if flags & wx.adv.ODCB_PAINTING_CONTROL: dc.DrawLabel(self.GetString(item), rect2, wx.ALIGN_CENTER_VERTICAL) else: dc.DrawLabel("\n".join([self.GetString(item)] + data.GetMessages()), bmp, rect2, wx.ALIGN_CENTER_VERTICAL) def OnMeasureItem(self, item): data = self.GetClientData(item) height = self.GetTextExtent(self.GetString(item))[1] * (len(data.GetMessages()) + 1) return height + 8 class FormatData: MPEG_PROFILES = ("VCD", "SVCD", "DVD") def __init__(self, rendClass, msgList): self._rendererClass = rendClass self._msgList = msgList def IsOk(self): return len(self._msgList) == 0 def IsMPEG(self): for mpegProf in FormatData.MPEG_PROFILES: if self._rendererClass.GetName().startswith(mpegProf): return True return False def GetRendererClass(self): return self._rendererClass def GetMessages(self): return self._msgList photofilmstrip-3.7.2/photofilmstrip/gui/PnlAddPics.py0000644000232200023220000000351413560357351023371 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2010 Jens Goepfert # import wx class PnlAddPics(wx.Panel): def _InitSizers(self): szCentered = wx.BoxSizer(wx.VERTICAL) szCentered.Add(self.stTitle, 0, border=4, flag=wx.EXPAND | wx.ALL) szCentered.AddSpacer(8) szCentered.Add(self.stInfo, 0, border=4, flag=wx.EXPAND | wx.ALL) szCentered.AddSpacer(8) szCentered.Add(self.cmdBrowse, 0, border=4, flag=wx.ALIGN_CENTER_HORIZONTAL | wx.ALL) szMain = wx.BoxSizer(wx.HORIZONTAL) szMain.Add(szCentered, flag=wx.ALIGN_CENTER_VERTICAL) self.SetSizer(szMain) def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0, name='PnlAddPics'): wx.Panel.__init__(self, id=id, name=name, parent=parent, pos=pos, size=size, style=style) self.SetClientSize(wx.Size(400, 250)) self.stTitle = wx.StaticText( self, wx.ID_ANY, name=u'stTitle', style=wx.ALIGN_CENTRE) self.stInfo = wx.StaticText( self, wx.ID_ANY, name=u'stInfo', style=wx.ALIGN_CENTRE) self.cmdBrowse = wx.BitmapButton( self, wx.ID_ANY, name=u'cmdBrowse', bitmap=wx.ArtProvider.GetBitmap('PFS_IMPORT_PICTURES_32')) font = self.stTitle.GetFont() font.SetWeight(wx.BOLD) self.stTitle.SetFont(font) self.stTitle.SetLabel(_(u"Welcome to PhotoFilmStrip")) self.stInfo.SetLabel( _(u"Drag some pictures onto this text or\n" u"click the button below\n" u"to add pictures to your new PhotoFilmStrip.")) self._InitSizers() def GetButton(self): return self.cmdBrowse photofilmstrip-3.7.2/photofilmstrip/gui/ActionManager.py0000644000232200023220000001634413560357351024125 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2017 Jens Goepfert # import wx from photofilmstrip.lib.Settings import Settings from photofilmstrip.gui.helper import CreateMenuItem class ActionManager: ID_JOB_QUEUE = wx.NewId() ID_PROJECT_CLOSE = wx.NewId() ID_SLIDESHOW = wx.NewId() ID_TIMELAPSE = wx.NewId() ID_LANG_EN = wx.NewId() ID_LANG_FR = wx.NewId() ID_LANG_DE = wx.NewId() ID_LANG_PT_BR = wx.NewId() ID_LANG_CS = wx.NewId() ID_LANG_IT = wx.NewId() ID_LANG_KO = wx.NewId() ID_LANG_NL = wx.NewId() ID_LANG_RU = wx.NewId() ID_LANG_TA = wx.NewId() ID_LANG_UK = wx.NewId() ID_LANG_EL = wx.NewId() ID_LANG_ES = wx.NewId() LANG_MAP = { ID_LANG_EN: "en", ID_LANG_FR: "fr", ID_LANG_DE: "de", ID_LANG_CS: "cs", ID_LANG_IT: "it", ID_LANG_KO: "ko", ID_LANG_NL: "nl", ID_LANG_RU: "ru", ID_LANG_PT_BR: "pt_BR", ID_LANG_TA: "ta", ID_LANG_UK: "uk", ID_LANG_EL: "el", ID_LANG_ES: 'es' } def __init__(self, frame, menuBar, toolBar): self._frame = frame self._menuBar = menuBar self._toolBar = toolBar self._prevEditor = None self._toolFix = 0 menuFile = self.__CreateMenuFile() menuEdit = self.__CreateMenuEdit() menuHelp = self.__CreateMenuHelp() self._menuBar.Append(menuFile, _(u'&File')) self._menuBar.Append(menuEdit, _(u'&Edit')) self._menuBar.Append(menuHelp, _(u'&Help')) self.__MakeToolBar(toolBar) self.__SelectLanguage(Settings().GetLanguage()) def __SelectLanguage(self, lang): for ident, l in self.LANG_MAP.items(): if l == lang: self._menuBar.Check(ident, True) def __MakeToolBar(self, toolBar): toolBar.AddTool(ActionManager.ID_SLIDESHOW, "", wx.ArtProvider.GetBitmap('PFS_PROJECT_NEW_24'), kind=wx.ITEM_DROPDOWN, shortHelp=_(u'New Slideshow')) toolBar.Bind(wx.EVT_TOOL_DROPDOWN, self.OnDropDownNew) toolBar.AddTool(wx.ID_OPEN, "", wx.ArtProvider.GetBitmap('PFS_PROJECT_OPEN_24'), _(u'Open'),) toolBar.AddTool(wx.ID_SAVE, "", wx.ArtProvider.GetBitmap('PFS_PROJECT_SAVE_24'), wx.ArtProvider.GetBitmap('PFS_PROJECT_SAVE_D_24'), wx.ITEM_NORMAL, shortHelp=_(u'Save')) # toolBar.AddSimpleTool(wx.ID_SAVEAS, # wx.ArtProvider.GetBitmap('PFS_PROJECT_SAVEAS_16'), # _(u'Save Project as'), _(u'Save Project as')) toolBar.AddSeparator() toolBar.AddTool(self.ID_JOB_QUEUE, '', wx.ArtProvider.GetBitmap('PFS_JOB_QUEUE_24'), wx.ArtProvider.GetBitmap('PFS_JOB_QUEUE_D_24'), wx.ITEM_NORMAL, _(u'Show job queue'), _(u'Show job queue'), None) toolBar.AddSeparator() self._toolFix = toolBar.GetToolsCount() toolBar.Realize() def __CreateMenuNew(self): menu = wx.Menu() CreateMenuItem(menu, ActionManager.ID_SLIDESHOW, _(u'Slideshow') + '\tCtrl+N', wx.ArtProvider.GetBitmap('PFS_PROJECT_NEW_16')) CreateMenuItem(menu, ActionManager.ID_TIMELAPSE, _(u'Timelapse'), wx.ArtProvider.GetBitmap('PFS_PROJECT_NEW_16')) return menu def __CreateMenuFile(self, editor=None): menu = wx.Menu() menu.Append(wx.ID_ANY, _(u'New'), self.__CreateMenuNew()) CreateMenuItem(menu, wx.ID_OPEN, _(u'&Open') + '\tCtrl+O', wx.ArtProvider.GetBitmap('PFS_PROJECT_OPEN_16')) menu.AppendSeparator() CreateMenuItem(menu, wx.ID_SAVE, _(u'&Save') + '\tCtrl+S', wx.ArtProvider.GetBitmap('PFS_PROJECT_SAVE_16'), wx.ArtProvider.GetBitmap('PFS_PROJECT_SAVE_D_16')) # CreateMenuItem(menu, wx.ID_SAVEAS, # _(u'Save Project &as'), # wx.ArtProvider.GetBitmap('PFS_PROJECT_SAVEAS_16')) menu.AppendSeparator() if editor: if editor.AddMenuFileActions(menu): menu.AppendSeparator() CreateMenuItem(menu, ActionManager.ID_PROJECT_CLOSE, _(u'&Close') + '\tCtrl+W', wx.ArtProvider.GetBitmap('PFS_PROJECT_CLOSE_16'), wx.ArtProvider.GetBitmap('PFS_PROJECT_CLOSE_D_16')) menu.AppendSeparator() CreateMenuItem(menu, wx.ID_EXIT, _(u'E&xit') + '\tCtrl+Q', wx.ArtProvider.GetBitmap('PFS_EXIT_16')) return menu def __CreateMenuEdit(self, editor=None): menu = wx.Menu() if editor: editor.AddMenuEditActions(menu) return menu def __CreateMenuHelp(self): menu = wx.Menu() CreateMenuItem(menu, wx.ID_HELP, _(u'&Help') + '\tF1', wx.ArtProvider.GetBitmap('PFS_HELP_16')) menu.AppendSeparator() langMenu = wx.Menu() langMenu.AppendRadioItem(self.ID_LANG_EN, u"English") langMenu.AppendRadioItem(self.ID_LANG_FR, u"Français") langMenu.AppendRadioItem(self.ID_LANG_DE, u"Deutsch") langMenu.AppendRadioItem(self.ID_LANG_NL, u"Nederlands") langMenu.AppendRadioItem(self.ID_LANG_PT_BR, u"Português (Brasil)") langMenu.AppendRadioItem(self.ID_LANG_CS, u"Český") langMenu.AppendRadioItem(self.ID_LANG_IT, u"Italiano") langMenu.AppendRadioItem(self.ID_LANG_KO, u"한국어") langMenu.AppendRadioItem(self.ID_LANG_RU, u"русский") langMenu.AppendRadioItem(self.ID_LANG_TA, u"தமிழ்") langMenu.AppendRadioItem(self.ID_LANG_UK, u"Український") langMenu.AppendRadioItem(self.ID_LANG_EL, u"ελληνικά") langMenu.AppendRadioItem(self.ID_LANG_ES, u"Español") menu.Append(wx.NewId(), _("Language"), langMenu) menu.AppendSeparator() CreateMenuItem(menu, wx.ID_ABOUT, _(u'&About'), wx.ArtProvider.GetBitmap('PFS_ABOUT_16')) return menu def OnDropDownNew(self, event): # pylint: disable=unused-argument menu = self.__CreateMenuNew() self._frame.PopupMenu(menu) def UpdateActions(self, newEditor): while self._toolFix < self._toolBar.GetToolsCount(): self._toolBar.DeleteToolByPos(self._toolFix) if self._prevEditor: self._prevEditor.DisconnEvents(self._frame) menuFile = self.__CreateMenuFile(newEditor) menuEdit = self.__CreateMenuEdit(newEditor) self._menuBar.Replace(0, menuFile, _(u'&File')).Destroy() self._menuBar.Replace(1, menuEdit, _(u'&Edit')).Destroy() if newEditor: newEditor.AddToolBarActions(self._toolBar) newEditor.ConnectEvents(self._frame) self._prevEditor = newEditor self._toolBar.Realize() photofilmstrip-3.7.2/photofilmstrip/gui/DlgRendererProps.py0000644000232200023220000001426013560357351024631 0ustar debalancedebalance# Boa:Dialog:DlgRendererProps # -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2010 Jens Goepfert # import wx from photofilmstrip.lib.Settings import Settings from photofilmstrip.gui.HelpViewer import HelpViewer from photofilmstrip.gui.ctrls.PnlDlgHeader import PnlDlgHeader [wxID_DLGRENDERERPROPS, wxID_DLGRENDERERPROPSCMDCANCEL, wxID_DLGRENDERERPROPSCMDHELP, wxID_DLGRENDERERPROPSCMDOK, wxID_DLGRENDERERPROPSLCPROPS, wxID_DLGRENDERERPROPSPNLHDR, wxID_DLGRENDERERPROPSSTATICLINE, ] = [wx.NewId() for _init_ctrls in range(7)] class DlgRendererProps(wx.Dialog): _custom_classes = {"wx.Choice": ["FormatComboBox"], "wx.Panel": ["PnlDlgHeader"]} def _init_coll_sizerCmd_Items(self, parent): # generated method, don't edit parent.Add(self.cmdHelp, 0, border=0, flag=0) parent.AddStretchSpacer(1) parent.Add(self.cmdCancel, 0, border=0, flag=0) parent.AddSpacer(8) parent.Add(self.cmdOk, 0, border=0, flag=0) def _init_coll_sizerMain_Items(self, parent): # generated method, don't edit parent.Add(self.pnlHdr, 0, border=0, flag=wx.EXPAND) parent.Add(self.lcProps, 1, border=0, flag=wx.EXPAND) parent.Add(self.staticLine, 0, border=8, flag=wx.TOP | wx.BOTTOM | wx.EXPAND) parent.Add(self.sizerCmd, 0, border=4, flag=wx.EXPAND | wx.ALL) def _init_coll_lcProps_Columns(self, parent): # generated method, don't edit parent.InsertColumn(col=0, format=wx.LIST_FORMAT_LEFT, heading=_(u'Property'), width=200) parent.InsertColumn(col=1, format=wx.LIST_FORMAT_LEFT, heading=_(u'Value'), width=200) def _init_sizers(self): # generated method, don't edit self.sizerMain = wx.BoxSizer(orient=wx.VERTICAL) self.sizerCmd = wx.BoxSizer(orient=wx.HORIZONTAL) self._init_coll_sizerMain_Items(self.sizerMain) self._init_coll_sizerCmd_Items(self.sizerCmd) self.SetSizer(self.sizerMain) def _init_ctrls(self, prnt): # generated method, don't edit wx.Dialog.__init__(self, id=wxID_DLGRENDERERPROPS, name=u'DlgRendererProps', parent=prnt, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, title=_(u'Output properties')) self.SetClientSize(wx.Size(400, 250)) self.pnlHdr = PnlDlgHeader(id=wxID_DLGRENDERERPROPSPNLHDR, name=u'pnlHdr', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL) self.lcProps = wx.ListCtrl(id=wxID_DLGRENDERERPROPSLCPROPS, name=u'lcProps', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.LC_REPORT | wx.SUNKEN_BORDER) self.lcProps.SetMinSize(wx.Size(500, 120)) self._init_coll_lcProps_Columns(self.lcProps) self.lcProps.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnActivateProperty, id=wxID_DLGRENDERERPROPSLCPROPS) self.cmdHelp = wx.Button(id=wx.ID_HELP, label=_(u'&Help'), name=u'cmdHelp', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.cmdHelp.Bind(wx.EVT_BUTTON, self.OnCmdHelpButton, id=wx.ID_HELP) self.cmdCancel = wx.Button(id=wxID_DLGRENDERERPROPSCMDCANCEL, label=_(u'&Cancel'), name=u'cmdCancel', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.cmdCancel.Bind(wx.EVT_BUTTON, self.OnCmdCancelButton, id=wxID_DLGRENDERERPROPSCMDCANCEL) self.cmdOk = wx.Button(id=wxID_DLGRENDERERPROPSCMDOK, label=_(u'&Ok'), name=u'cmdOk', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.cmdOk.Bind(wx.EVT_BUTTON, self.OnCmdOkButton, id=wxID_DLGRENDERERPROPSCMDOK) self.staticLine = wx.StaticLine(id=wxID_DLGRENDERERPROPSSTATICLINE, name=u'staticLine', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self._init_sizers() def __init__(self, parent, rendererClass): self._init_ctrls(parent) self.Bind(wx.EVT_CLOSE, self.OnCmdCancelButton) self.pnlHdr.SetTitle(_(u'Edit extended output properties')) self.pnlHdr.SetBitmap(wx.ArtProvider.GetBitmap('PFS_VIDEO_FORMAT_32')) self.rendererClass = rendererClass self.lcProps.DeleteAllItems() savedProps = Settings().GetRenderProperties(rendererClass.__name__) for prop in rendererClass.GetProperties(): value = savedProps.get(prop.lower(), rendererClass.GetProperty(prop)) self.lcProps.Append([prop, value]) rendererClass.SetProperty(prop, value) self.SetAffirmativeId(wxID_DLGRENDERERPROPSCMDOK) self.SetEscapeId(wxID_DLGRENDERERPROPSCMDCANCEL) self.SetInitialSize(self.GetEffectiveMinSize()) self.CentreOnParent() self.SetFocus() def OnCmdCancelButton(self, event): self.EndModal(wx.ID_CANCEL) def OnCmdOkButton(self, event): propDict = {} for prop in self.rendererClass.GetProperties(): if self.rendererClass.GetProperty(prop) != self.rendererClass.GetDefaultProperty(prop): propDict[prop] = self.rendererClass.GetProperty(prop) Settings().SetRenderProperties(self.rendererClass.__name__, propDict) self.EndModal(wx.ID_OK) def OnActivateProperty(self, event): idx = event.GetIndex() prop = self.lcProps.GetItemText(idx) dlg = wx.TextEntryDialog(self, _(u"Edit property"), prop, str(self.rendererClass.GetProperty(prop))) if dlg.ShowModal() == wx.ID_OK: value = dlg.GetValue() if len(value) == 0: value = self.rendererClass.GetDefaultProperty(prop) self.rendererClass.SetProperty(prop, value) self.lcProps.SetItem(idx, 1, str(value)) dlg.Destroy() def OnCmdHelpButton(self, event): HelpViewer().DisplayID(HelpViewer.ID_RENDER) event.Skip() photofilmstrip-3.7.2/photofilmstrip/gui/PnlWelcome.py0000644000232200023220000002071413560357351023456 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2010 Jens Goepfert # import os import wx import wx.html import wx.lib.wxpTag # import needed to initialize html tag 'wxp'; pylint: disable=unused-import import wx.adv from photofilmstrip import Constants from photofilmstrip.lib.Settings import Settings from photofilmstrip.lib.UpdateChecker import UpdateChecker from photofilmstrip.core.ProjectFile import ProjectFile from photofilmstrip.core import PILBackend from photofilmstrip.gui.ctrls.IconLabelLink import IconLabelLink class PnlWelcome(wx.Panel): def __init__(self, parent, frmMain): wx.Panel.__init__(self, parent) self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM) self.title = _(u"Welcome to PhotoFilmStrip") self.Bind(wx.EVT_PAINT, self.OnPaint) self.Bind(wx.EVT_SIZE, self.OnSize) self.__frmMain = frmMain self.htmlTitle = _(u"Recent projects") self.htmlText = u"" self.htmlRecentProjects = u"" self.htmlUpdate = u"" self.pnlHtmlBackground = wx.Panel(self) self.pnlHtmlBackground.SetBackgroundColour(wx.Colour(52, 73, 94)) self.htmlWin = wx.html.HtmlWindow(self.pnlHtmlBackground, -1, style=wx.NO_BORDER) self.htmlWin.SetBackgroundStyle(wx.BG_STYLE_SYSTEM) self.htmlWin.Bind(EVT_LINK, self.OnLinkClicked) self.htmlWin.SetSizeHints(650, -1, 650, -1) sizerHtmlBackground = wx.BoxSizer(wx.HORIZONTAL) sizerHtmlBackground.Add(self.htmlWin, 1, wx.EXPAND | wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 8) self.bmpFilmstrip = wx.ArtProvider.GetBitmap('PFS_FILMSTRIP') self.cmdNew = wx.BitmapButton(self, -1, wx.ArtProvider.GetBitmap('PFS_PROJECT_NEW_64')) self.cmdNew.SetToolTip(_(u"Create new slideshow")) self.cmdNew.Bind(wx.EVT_BUTTON, self.__frmMain.OnSlideshow) self.cmdOpen = wx.BitmapButton(self, -1, wx.ArtProvider.GetBitmap('PFS_PROJECT_OPEN_64')) self.cmdOpen.SetToolTip(_(u"Open existing project")) self.cmdOpen.Bind(wx.EVT_BUTTON, self.__frmMain.OnProjectLoad) sizerCmd = wx.BoxSizer(wx.HORIZONTAL) sizerCmd.Add(self.cmdNew, 0, wx.ALL, 30) sizerCmd.AddStretchSpacer(1) sizerCmd.Add(self.cmdOpen, 0, wx.ALL, 30) sizerMain = wx.BoxSizer(wx.VERTICAL) sizerMain.AddStretchSpacer(1) sizerMain.Add(sizerCmd, 0, wx.ALIGN_CENTER_HORIZONTAL, 8) sizerMain.Add(self.pnlHtmlBackground, 3, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 8) sizerMain.AddStretchSpacer(1) self.pnlHtmlBackground.SetSizer(sizerHtmlBackground) self.SetSizer(sizerMain) self.Layout() self.RefreshPage() self.__updateChecker = UpdateChecker() wx.CallLater(500, self.__NotifyUpdate) def RefreshPage(self, withHistory=True): if withHistory: htmlParts = [] fileHistory = Settings().GetFileHistory() for recentFile in fileHistory: if ProjectFile(filename=recentFile).IsOk(): htmlPart = """ """ % recentFile htmlParts.append(htmlPart) breakAt = 4 for idx in range((len(htmlParts) - 1) // breakAt): htmlParts.insert(idx + ((idx + 1) * breakAt), "") if htmlParts: self.htmlTitle = _(u"Recent projects") self.htmlText = "" else: self.htmlTitle = _(u"How to start...") self.htmlText = _(u"Create a new project or load an existing one.") self.htmlRecentProjects = "".join(htmlParts) html = HTML_TEMPLATE % {'title': self.htmlTitle, 'text': self.htmlText, 'htmlRecentProjects': self.htmlRecentProjects, 'htmlUpdate': self.htmlUpdate} self.htmlWin.SetPage(html) def __NotifyUpdate(self): if not self.__updateChecker.IsDone(): wx.CallLater(100, self.__NotifyUpdate) return if not self.__updateChecker.IsOk(): return # if not self.__updateChecker.IsNewer(Settings().GetLastKnownVersion()): # return if not self.__updateChecker.IsNewer(Constants.APP_VERSION): return Settings().SetLastKnownVersion(self.__updateChecker.GetVersion()) html = """

%(title)s

%(msg)s

%(changes)s
""" % {"title": _("Update available"), "appname": Constants.APP_NAME, "version": self.__updateChecker.GetVersion(), "msg": _(u'The following changes has been made:'), "changes": self.__updateChecker.GetChanges(), "url": Constants.APP_URL} self.htmlUpdate = html self.RefreshPage(withHistory=False) def OnSize(self, event): self.Refresh() event.Skip() def OnPaint(self, event): dc = wx.BufferedPaintDC(self) sz = self.GetSize() dc.SetBackground(wx.Brush(wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE))) dc.Clear() rect = wx.Rect(0, 180, sz[0], sz[1]) dc.GradientFillLinear(rect, wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE), wx.Colour(52, 73, 94), wx.SOUTH) font = wx.Font(28, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, 'Tahoma') dc.SetFont(font) dc.SetTextForeground(wx.Colour(99, 102, 106)) dc.DrawLabel(self.title, wx.Rect(0, 10, sz[0], 75), wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL) dc.DrawBitmap(self.bmpFilmstrip, 10, sz[1] - self.bmpFilmstrip.GetSize()[1] - 30) def OnLinkClicked(self, event): filename = event.GetFilename() self.__frmMain.LoadProject(filename) class LinkOpenPfs(IconLabelLink): BMP_MAP = {} def __init__(self, parent, size=wx.DefaultSize, filename=None): self.filename = filename if filename not in LinkOpenPfs.BMP_MAP: prjFile = ProjectFile(filename=filename) imgCount = prjFile.GetPicCount() img = prjFile.GetPreviewThumb() if img is not None: wxImg = wx.Image(PILBackend.ImageToStream(img), wx.BITMAP_TYPE_JPEG) bmp = wxImg.ConvertToBitmap() else: bmp = wx.ArtProvider.GetBitmap("PFS_ICON_48", wx.ART_OTHER) descr = "%d images" % imgCount LinkOpenPfs.BMP_MAP[filename] = (bmp, descr) bmp, descr = LinkOpenPfs.BMP_MAP[filename] IconLabelLink.__init__(self, parent, size, os.path.splitext(os.path.basename(filename))[0], bmp, descr) def OnClick(self): evt = LinkClickedEvent(self.GetParent().GetId(), self.filename) self.GetEventHandler().ProcessEvent(evt) EVT_LINK_TYPE = wx.NewEventType() EVT_LINK = wx.PyEventBinder(EVT_LINK_TYPE, 1) class LinkClickedEvent(wx.PyCommandEvent): def __init__(self, wxId, filename): wx.PyCommandEvent.__init__(self, EVT_LINK_TYPE, wxId) self._filename = filename def GetFilename(self): return self._filename class PfsHyperlink(wx.adv.HyperlinkCtrl): def __init__(self, parent, size=wx.DefaultSize, label=""): wx.adv.HyperlinkCtrl.__init__(self, parent, -1, label, size=size) self.SetBackgroundColour(parent.GetBackgroundColour()) self.SetURL(Constants.APP_URL) HTML_TEMPLATE = """

%(title)s

%(htmlRecentProjects)s
%(text)s
%(htmlUpdate)s
""" photofilmstrip-3.7.2/photofilmstrip/gui/DlgConfigureAudio.py0000644000232200023220000002324113560357351024741 0ustar debalancedebalance# encoding: UTF-8 # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2018 Jens Goepfert # import os import wx from photofilmstrip.lib.Settings import Settings from photofilmstrip.core.AudioPlayer import AudioPlayer from photofilmstrip.gui.ctrls.PnlDlgHeader import PnlDlgHeader class DlgConfigureAudio(wx.Dialog): def _InitSizers(self): szMain = wx.BoxSizer(orient=wx.VERTICAL) szCtrls = wx.BoxSizer(orient=wx.HORIZONTAL) szAudioCmds = wx.BoxSizer(orient=wx.VERTICAL) szCmds = wx.BoxSizer(orient=wx.HORIZONTAL) szMain.Add(self.pnlHdr, 0, border=0, flag=wx.EXPAND) szMain.Add(self.szMsg, 0, border=8, flag=wx.ALL | wx.EXPAND) szMain.Add(szCtrls, 0, border=8, flag=wx.ALL | wx.EXPAND) szMain.Add(self.cbAudio, 0, border=8, flag=wx.ALL | wx.EXPAND) szMain.Add(szCmds, 0, border=8, flag=wx.ALL | wx.ALIGN_RIGHT) szCtrls.Add(self.lvAudio, 1, flag=wx.EXPAND | wx.RIGHT, border=4) szCtrls.Add(szAudioCmds) szAudioCmds.Add(self.cmdBrowseAudio, border=2, flag=wx.BOTTOM) szAudioCmds.Add(self.cmdAudioPreview, border=2, flag=wx.BOTTOM) szAudioCmds.Add(self.cmdAudioMoveUp, border=2, flag=wx.BOTTOM) szAudioCmds.Add(self.cmdAudioMoveDown, border=2, flag=wx.BOTTOM) szAudioCmds.Add(self.cmdAudioDel, border=2, flag=wx.BOTTOM) szCmds.Add(self.cmdCancel, 0, border=0, flag=0) szCmds.AddSpacer(8) szCmds.Add(self.cmdOk, 0, border=0, flag=0) self.SetSizer(szMain) def _InitCtrls(self): self.pnlHdr = PnlDlgHeader(self) self.szMsg = self.CreateTextSizer( _("Configure your audio files that are used as a background music.")) self.lvAudio = wx.ListBox(self, style=wx.LB_SINGLE) self.lvAudio.Bind(wx.EVT_LISTBOX, self.OnControlStatusAudio) self.cmdBrowseAudio = wx.BitmapButton(self, bitmap=wx.ArtProvider.GetBitmap('PFS_MUSIC_16'), name=u'cmdBrowseAudio', style=wx.BU_AUTODRAW) self.cmdBrowseAudio.Bind(wx.EVT_BUTTON, self.OnCmdBrowseAudioButton) self.cmdAudioPreview = wx.BitmapButton(self, bitmap=wx.ArtProvider.GetBitmap('PFS_PLAY_PAUSE_16'), name=u'cmdAudioPreview', style=wx.BU_AUTODRAW) self.cmdAudioPreview.SetBitmapDisabled(wx.ArtProvider.GetBitmap('PFS_PLAY_PAUSE_D_16')) self.cmdAudioPreview.Bind(wx.EVT_BUTTON, self.OnCmdAudioPreviewButton) self.cmdAudioMoveUp = wx.BitmapButton(self, bitmap=wx.ArtProvider.GetBitmap('PFS_ARROW_UP_16'), name=u'cmdAudioMoveUp', style=wx.BU_AUTODRAW) self.cmdAudioMoveUp.SetBitmapDisabled(wx.ArtProvider.GetBitmap('PFS_ARROW_UP_D_16')) self.cmdAudioMoveUp.Bind(wx.EVT_BUTTON, self.OnCmdAudioMove) self.cmdAudioMoveDown = wx.BitmapButton(self, bitmap=wx.ArtProvider.GetBitmap('PFS_ARROW_DOWN_16'), name=u'cmdAudioMoveDown', style=wx.BU_AUTODRAW) self.cmdAudioMoveDown.SetBitmapDisabled(wx.ArtProvider.GetBitmap('PFS_ARROW_DOWN_D_16')) self.cmdAudioMoveDown.Bind(wx.EVT_BUTTON, self.OnCmdAudioMove) self.cmdAudioDel = wx.BitmapButton(self, bitmap=wx.ArtProvider.GetBitmap('PFS_REMOVE_16'), name=u'cmdAudioDel', style=wx.BU_AUTODRAW) self.cmdAudioDel.SetBitmapDisabled(wx.ArtProvider.GetBitmap('PFS_REMOVE_D_16')) self.cmdAudioDel.Bind(wx.EVT_BUTTON, self.OnCmdAudioDel) self.cbAudio = wx.CheckBox(self, wx.ID_ANY, label=_(u'Set the duration of your slideshow to fit your audio files')) self.cmdCancel = wx.Button(self, id=wx.ID_CANCEL, label=_(u'&Cancel'), name=u'cmdCancel') self.cmdCancel.Bind(wx.EVT_BUTTON, self.OnCmdCancelButton, id=wx.ID_CANCEL) self.cmdOk = wx.Button(self, id=wx.ID_OK, label=_(u'&Ok'), name=u'cmdOk') self.cmdOk.Bind(wx.EVT_BUTTON, self.OnCmdOkButton, id=wx.ID_OK) def __init__(self, parent, project): wx.Dialog.__init__(self, parent, name=u'DlgConfigureAudio', style=wx.DEFAULT_DIALOG_STYLE, title=_(u'Configure music')) self.Bind(wx.EVT_CLOSE, self.OnClose) self._InitCtrls() self.pnlHdr.SetTitle(_(u'Configure music')) self.pnlHdr.SetBitmap(wx.ArtProvider.GetBitmap('PFS_MUSIC_32')) self.lvAudio.SetMinSize(wx.Size(300, -1)) self.__project = project self.__mediaCtrl = None if project.GetTimelapse(): self.cbAudio.SetValue(False) self.cbAudio.Show(False) else: duration = project.GetDuration(False) self.cbAudio.SetValue(duration == -1) for audioFile in project.GetAudioFiles(): idx = self.lvAudio.Append(audioFile) self.lvAudio.Select(idx) self.__ControlStatusAudio() self._InitSizers() self.Fit() self.CenterOnParent() def OnControlStatusAudio(self, event): # pylint: disable=unused-argument self.__ControlStatusAudio() def OnCmdBrowseAudioButton(self, event): # pylint: disable=unused-argument dlg = wx.FileDialog(self, _(u"Select music"), Settings().GetAudioPath(), "", _(u"Audio files") + " (*.*)|*.*", wx.FD_OPEN | wx.FD_MULTIPLE) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() Settings().SetAudioPath(os.path.dirname(path)) for path in dlg.GetPaths(): self.lvAudio.Append(path) dlg.Destroy() def OnCmdAudioPreviewButton(self, event): # pylint: disable=unused-argument selIdx = self.lvAudio.GetSelection() if selIdx == wx.NOT_FOUND: return filename = self.lvAudio.GetString(selIdx) if self.__mediaCtrl and self.__mediaCtrl.GetFilename() == filename: if self.__mediaCtrl.IsPlaying(): self.__mediaCtrl.Stop() else: self.__mediaCtrl.Play() else: self.__LoadAudioFile(filename) def OnCmdAudioMove(self, event): selIdx = self.lvAudio.GetSelection() if selIdx == wx.NOT_FOUND: return selAudio = self.lvAudio.GetString(selIdx) evtObj = event.GetEventObject() if evtObj is self.cmdAudioMoveUp: if selIdx > 0: prevAudio = self.lvAudio.GetString(selIdx - 1) self.lvAudio.SetString(selIdx, prevAudio) self.lvAudio.SetString(selIdx - 1, selAudio) self.lvAudio.SetSelection(selIdx - 1) elif evtObj is self.cmdAudioMoveDown: if selIdx < self.lvAudio.GetCount() - 1: nextAudio = self.lvAudio.GetString(selIdx + 1) self.lvAudio.SetString(selIdx, nextAudio) self.lvAudio.SetString(selIdx + 1, selAudio) self.lvAudio.SetSelection(selIdx + 1) self.__ControlStatusAudio() def OnCmdAudioDel(self, event): # pylint: disable=unused-argument selIdx = self.lvAudio.GetSelection() if selIdx != wx.NOT_FOUND: self.lvAudio.Delete(selIdx) self.lvAudio.Select(min(selIdx, self.lvAudio.GetCount() - 1)) self.__ControlStatusAudio() def OnClose(self, event): self.__CloseMediaCtrl() event.Skip() def OnCmdCancelButton(self, event): self.__CloseMediaCtrl() event.Skip() def OnCmdOkButton(self, event): self.__CloseMediaCtrl() if self.__ValidateAudioFile(): self.__project.SetAudioFiles(self.lvAudio.GetItems()) if self.cbAudio.GetValue(): self.__project.SetDuration(-1) elif self.__project.GetDuration(False) == -1: # was previously set, so reset the duration self.__project.SetDuration(None) event.Skip() def __ControlStatusAudio(self): selected = self.lvAudio.GetSelection() self.cmdAudioPreview.Enable(selected != wx.NOT_FOUND) self.cmdAudioDel.Enable(selected != wx.NOT_FOUND) self.cmdAudioMoveUp.Enable(selected > 0) self.cmdAudioMoveDown.Enable(selected < (self.lvAudio.GetCount() - 1)) def __LoadAudioFile(self, path): self.__CloseMediaCtrl() if not os.path.exists(path): dlg = wx.MessageDialog(self, _(u"Audio file '%s' does not exist!") % path, _(u"Error"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() mediaCtrl = AudioPlayer(path) if mediaCtrl.IsOk(): self.__mediaCtrl = mediaCtrl self.__mediaCtrl.Play() else: dlg = wx.MessageDialog(self, _(u"Audio file not supported!"), _(u"Error"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() def __ValidateAudioFile(self): for path in self.lvAudio.GetItems(): if not os.path.exists(path): dlg = wx.MessageDialog(self, _(u"Audio file '%s' does not exist!") % path, _(u"Error"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return False return True def __CloseMediaCtrl(self): if self.__mediaCtrl is not None: try: self.__mediaCtrl.Close() except: pass self.__mediaCtrl = None photofilmstrip-3.7.2/photofilmstrip/gui/PnlSlideshow.py0000644000232200023220000001144013560357351024020 0ustar debalancedebalance# encoding: UTF-8 # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2018 Jens Goepfert # import wx from photofilmstrip.gui.PnlPfsProject import ( PnlPfsProject, ID_PIC_IMPORT, ID_MUSIC, ID_RENDER_FILMSTRIP) from photofilmstrip.gui.DlgDuration import DlgDuration from photofilmstrip.gui.DlgPicDurationByAudio import DlgPicDurationByAudio from photofilmstrip.gui.helper import CreateMenuItem from photofilmstrip.gui.ImageSectionEditor import ImageProxy [ID_PROJECT_PROPS, ID_PIC_DURATION_BY_AUDIO, ] = [wx.NewId() for __ in range(2)] class PnlSlideshow(PnlPfsProject): def _GetEditorName(self): return _(u"Slideshow") def AddMenuFileActions(self, menu): PnlPfsProject.AddMenuFileActions(self, menu) CreateMenuItem(menu, ID_PROJECT_PROPS, _(u"&Properties"), wx.ArtProvider.GetBitmap('PFS_PROPERTIES_16')) return True def AddToolBarActions(self, toolBar): toolBar.AddTool(ID_PIC_IMPORT, '', wx.ArtProvider.GetBitmap('PFS_IMPORT_PICTURES_24'), wx.ArtProvider.GetBitmap('PFS_IMPORT_PICTURES_D_24'), wx.ITEM_NORMAL, _(u'Import Pictures'), _(u'Import Pictures'), None) toolBar.AddSeparator() toolBar.AddTool(ID_MUSIC, '', wx.ArtProvider.GetBitmap('PFS_MUSIC_24'), wx.NullBitmap, wx.ITEM_NORMAL, _(u'Configure music'), _(u'Configure music'), None) toolBar.AddTool(ID_PIC_DURATION_BY_AUDIO, '', wx.ArtProvider.GetBitmap('PFS_MUSIC_DURATION_24'), wx.NullBitmap, wx.ITEM_NORMAL, _(u'Adjust picture durations'), _(u'Adjust picture durations'), None) toolBar.AddSeparator() toolBar.AddTool(ID_RENDER_FILMSTRIP, '', wx.ArtProvider.GetBitmap('PFS_RENDER_24'), wx.ArtProvider.GetBitmap('PFS_RENDER_D_24'), wx.ITEM_NORMAL, _(u'Render filmstrip'), _(u'Render filmstrip'), None) def ConnectEvents(self, evtHandler): PnlPfsProject.ConnectEvents(self, evtHandler) evtHandler.Bind(wx.EVT_MENU, self.OnProperties, id=ID_PROJECT_PROPS) evtHandler.Bind(wx.EVT_MENU, self.OnPicDurationByAudio, id=ID_PIC_DURATION_BY_AUDIO) evtHandler.Bind(wx.EVT_UPDATE_UI, self.OnCheckProjectReady, id=ID_PIC_DURATION_BY_AUDIO) def DisconnEvents(self, evtHandler): PnlPfsProject.DisconnEvents(self, evtHandler) for wId in [ID_PIC_DURATION_BY_AUDIO]: evtHandler.Disconnect(wId) def GetStatusText(self, index): project = self.GetProject() imgCount = len(project.GetPictures()) totalTime = project.GetDuration(False) if totalTime == -1: # TODO: calc from audio files totalTime = 0 elif totalTime is None: totalTime = project.GetDuration(True) if index == 0: return u"%s: %d" % (_(u"Images"), imgCount) elif index == 1: minutes = totalTime // 60 seconds = totalTime % 60 return u"%s: %02d:%02d" % (_(u"Duration"), minutes, seconds) else: return u"" def OnStatusBarClick(self, index): if index == 1: self.OnProperties(None) def OnProperties(self, event): # pylint: disable=unused-argument dlg = DlgDuration(self, self.GetProject()) dlg.ShowModal() dlg.Destroy() def OnPicDurationByAudio(self, event): # pylint: disable=unused-argument DlgPicDurationByAudio.Interact(self, self.GetProject()) def _InitImageProxy(self): self.imgProxyLeft = self.imgProxyRight = ImageProxy() self.imgProxyLeft.AddObserver(self.bitmapLeft) self.imgProxyRight.AddObserver(self.bitmapRight) self.bitmapLeft.SetImgProxy(self.imgProxyLeft) self.bitmapRight.SetImgProxy(self.imgProxyRight) def _OnPicsSelectionChanged(self, selItems, selPics): if selPics: # assert self.imgProxyLeft is self.imgProxyRight self.imgProxyLeft.SetPicture(selPics[0]) self.imgProxyRight.SetPicture(selPics[0]) self._CheckAndSetLock(selPics[0]) self.bitmapLeft.SetSection(wx.Rect(*selPics[0].GetStartRect())) self.bitmapRight.SetSection(wx.Rect(*selPics[0].GetTargetRect())) photofilmstrip-3.7.2/photofilmstrip/gui/helper.py0000644000232200023220000000230613560357351022665 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2017 Jens Goepfert # import wx def CreateMenuItem(menu, ident, text="", bmp=None, disabledBitmap=None): if text: item = wx.MenuItem(menu, ident, text) item.SetHelp(text.replace('&', '').split('\t')[0]) else: item = wx.MenuItem(menu, ident) if bmp is not None: item.SetBitmap(bmp) if disabledBitmap is not None: item.SetDisabledBitmap(disabledBitmap) menu.Append(item) def ChopText(dc, text, maxSize): """ Chops the input `text` if its size does not fit in `maxSize`, by cutting the text and adding ellipsis at the end. :param `dc`: a `wx.DC` device context; :param `text`: the text to chop; :param `maxSize`: the maximum size in which the text should fit. """ # first check if the text fits with no problems width, __ = dc.GetTextExtent(text) if width <= maxSize: return text, width for i in range(len(text), -1, -1): s = '%s ... %s' % (text[:i * 33 // 100], text[-i * 67 // 100:]) width, __ = dc.GetTextExtent(s) if width <= maxSize: break return s, width photofilmstrip-3.7.2/photofilmstrip/gui/PhotoFilmStripList.py0000644000232200023220000004312013560357351025164 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # import os import wx from photofilmstrip.gui.util.ImageCache import ImageCache, EVT_THUMB_READY from photofilmstrip.gui.helper import ChopText EVT_CHANGED_TYPE = wx.NewEventType() EVT_CHANGED = wx.PyEventBinder(EVT_CHANGED_TYPE, 1) class ChangedEvent(wx.PyCommandEvent): def __init__(self, wxId): wx.PyCommandEvent.__init__(self, EVT_CHANGED_TYPE, wxId) class PhotoFilmStripList(wx.ScrolledWindow): GAP = 10 BORDER = 45 THUMB_HEIGHT = 120 HOLE_WIDTH = 11 HOLE_HEIGHT = 16 HOLE_PADDING = 13 # distance between holes HOLE_MARGIN = 6 # distance to thumb LABEL_MARGIN = 8 STRIP_HEIGHT = THUMB_HEIGHT + 2 * BORDER def __init__(self, parent, id=-1, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.HSCROLL | wx.VSCROLL, name='PhotoFilmStripList'): wx.ScrolledWindow.__init__(self, parent, id, pos, size, style, name) self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM) self.SetBackgroundColour(wx.BLACK) clientSize = wx.Size(-1, self.STRIP_HEIGHT + wx.SystemSettings.GetMetric(wx.SYS_HSCROLL_Y)) self.SetSizeHints(clientSize, clientSize) self.__frozen = False self.__pictures = [] self.__selIdxs = [] self.__hvrIdx = -1 self.__dragIdx = -1 self.__dropIdx = -1 self.__dragBmp = None self.__dragBmpIdx = -1 self.__dragX = 0 self.__dragOffX = 0 self.__UpdateVirtualSize() self.SetScrollRate(1, 0) self.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel) self.Bind(wx.EVT_PAINT, self.OnPaint) self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseEvent) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_MOUSE_CAPTURE_LOST, self.OnCaptureLost) ImageCache().RegisterWin(self) ImageCache().thumb = wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE, wx.ART_TOOLBAR, (120, 120)) self.Bind(EVT_THUMB_READY, self.__OnThumbReady) def Freeze(self, *args): self.__frozen = True def Thaw(self, *args): self.__frozen = False self.__UpdateVirtualSize() def IsFrozen(self, *args): return self.__frozen def __OnThumbReady(self, event): self.__UpdateVirtualSize() def OnPaint(self, event): pdc = wx.BufferedPaintDC(self) try: dc = wx.GCDC(pdc) except Exception: dc = pdc dc.SetBackground(wx.BLACK_BRUSH) dc.Clear() vx = self.GetViewStart()[0] clientWidth = self.GetClientSize()[0] diaRect = wx.Rect(-vx, 0, 0, self.STRIP_HEIGHT) for idx, pic in enumerate(self.__pictures): bmp = ImageCache().GetThumbBmp(pic) # if the picture cannot be loaded GetWidth may return -1 bmpWidth = bmp.GetWidth() diaRect.SetWidth(bmpWidth + self.GAP) if idx == self.__dropIdx and self.__dragIdx > idx: diaRect.Offset(self.__dragBmp.GetWidth(), 0) if diaRect.right + 1 >= 0 and idx != self.__dragIdx: if diaRect.left <= clientWidth: label = os.path.splitext(os.path.basename(pic.GetFilename()))[0] diaNo = idx + 1 if idx >= self.__dropIdx and idx < self.__dragIdx: diaNo += 1 if idx <= self.__dropIdx and idx > self.__dragIdx: diaNo -= 1 self.__DrawDia(dc, diaRect, diaRect.x + vx, bmp, str(diaNo), label, idx in self.__selIdxs, idx == self.__hvrIdx) else: break if idx != self.__dragIdx or self.__dragIdx == self.__dropIdx: diaRect.Offset(diaRect.width, 0) if idx == self.__dropIdx and self.__dragIdx < idx: diaRect.Offset(self.__dragBmp.GetWidth(), 0) if self.__dragIdx != -1: dc.DrawBitmap(self.__dragBmp, self.__dragX - self.__dragOffX - vx, 0, True) def __CreateDiaBmp(self, picIdx, selected=False, highlighted=False, dropIdx=None): pic = self.__pictures[picIdx] thumbBmp = ImageCache().GetThumbBmp(pic) diaRect = self.GetDiaRect(picIdx) holeOffset = diaRect.x bmp = wx.Bitmap(diaRect.width, diaRect.height) diaNo = str(picIdx + 1) label = os.path.splitext(os.path.basename(pic.GetFilename()))[0] dc = wx.MemoryDC(bmp) try: dc = wx.GCDC(dc) except Exception: pass if dropIdx is not None: diaNo = str(dropIdx + 1) dropRect = self.GetDiaRect(dropIdx) if dropIdx > picIdx: holeOffset = dropRect.right + 1 - diaRect.width diaRect.SetX(0) self.__DrawDia(dc, diaRect, holeOffset, thumbBmp, diaNo, label, selected, highlighted) return bmp def __DrawDia(self, dc, rect, holeOffset, thumbBmp, diaNo, label, selected=False, highlighted=False): font = wx.SystemSettings.GetFont(wx.SYS_ANSI_FIXED_FONT) font.SetPointSize(9) dc.SetFont(font) colour = wx.Colour(235, 235, 235) bmpX = rect.x + self.GAP // 2 bmpY = (rect.height - thumbBmp.GetHeight()) // 2 holeX = rect.x + self.GAP // 2 - (holeOffset % (self.HOLE_WIDTH + self.HOLE_PADDING)) dc.SetClippingRegion(rect.GetX(), rect.GetY(), rect.GetWidth(), rect.GetHeight()) if selected: dc.SetBackground(wx.Brush(wx.Colour(38, 54, 70))) dc.Clear() dc.SetPen(wx.Pen(wx.Colour(237, 156, 0))) dc.SetBrush(wx.Brush(wx.Colour(237, 156, 0))) dc.DrawRectangle(rect.x, 0, rect.right + 1, 3) dc.DrawRectangle(rect.x, rect.bottom - 2, rect.right + 1, rect.bottom) else: dc.SetBackground(wx.BLACK_BRUSH) dc.Clear() dc.SetTextForeground(wx.Colour(237, 156, 0)) dc.SetBrush(wx.Brush(colour)) dc.SetPen(wx.Pen(colour)) diaNoWidth, textHeight = dc.GetTextExtent(diaNo) label, labelWidth = ChopText(dc, label, thumbBmp.GetWidth()) dc.DrawBitmap(thumbBmp, bmpX, bmpY, True) dc.DrawText(diaNo, rect.x + (rect.width - diaNoWidth) // 2, self.LABEL_MARGIN - 3) dc.DrawText(label, rect.x + (rect.width - labelWidth) // 2, rect.height - self.LABEL_MARGIN - textHeight) while holeX <= rect.right + 1: dc.DrawRoundedRectangle(holeX, self.BORDER - self.HOLE_MARGIN - self.HOLE_HEIGHT, self.HOLE_WIDTH, self.HOLE_HEIGHT, 2) dc.DrawRoundedRectangle(holeX, self.BORDER + self.THUMB_HEIGHT + self.HOLE_MARGIN, self.HOLE_WIDTH, self.HOLE_HEIGHT, 2) holeX += self.HOLE_WIDTH + self.HOLE_PADDING if highlighted: dc.SetPen(wx.TRANSPARENT_PEN) dc.SetBrush(wx.Brush(wx.Colour(77, 136, 196, 80))) dc.DrawRectangle(rect) dc.DestroyClippingRegion() def _SendChangedEvent(self): evt = ChangedEvent(self.GetId()) evt.SetEventObject(self) self.GetEventHandler().ProcessEvent(evt) def __Scroll(self, value): sp = self.GetScrollPos(wx.HORIZONTAL) self.Scroll(sp + value, -1) def OnMouseWheel(self, event): rot = event.GetWheelRotation() linesPer = 40 # event.GetLinesPerAction() if rot > 0: self.__Scroll(-linesPer) else: self.__Scroll(linesPer) def OnMouseEvent(self, event): mPos = event.GetPosition() unscrolledPos = self.CalcUnscrolledPosition(mPos) idx = self.HitTest(mPos) if event.Moving(): if idx != self.__hvrIdx: self.__hvrIdx = idx self.Refresh() if event.Dragging(): if idx != -1: self.__dropIdx = idx if mPos.x < 10: self.__Scroll(-40) elif mPos.x > self.GetClientSize()[0] - 10: self.__Scroll(40) self.__dragX = unscrolledPos.x if self.__dragIdx == -1: if idx != -1: self.__dragIdx = idx self.__dragBmp = self.__CreateDiaBmp(idx, True, True) self.__dragBmpIdx = idx rect = self.GetDiaRect(idx) self.__dragOffX = self.__dragX - rect.GetLeft() self.CaptureMouse() elif self.__dragBmpIdx != self.__dropIdx: self.__dragBmpIdx = self.__dropIdx self.__dragBmp = self.__CreateDiaBmp(self.__dragIdx, True, True, self.__dropIdx) self.Refresh() if event.Leaving(): self.__hvrIdx = -1 self.Refresh() if event.LeftDown() and not event.Dragging(): if idx != -1: if event.ControlDown(): self.Select(idx, idx not in self.__selIdxs, False) elif event.ShiftDown(): if not self.__selIdxs: # nothing selected self.Select(idx) else: step = 1 if idx > self.__selIdxs[0] else -1 for ct, _idx in enumerate(range(self.__selIdxs[0], idx + step, step)): self.Select(_idx, deselectOthers=ct == 0) else: self.Select(idx) if event.LeftUp() and self.__dragIdx != -1: self.__FinishDnD() event.Skip() def OnCaptureLost(self, event): self.__dragIdx = -1 self.__dropIdx = -1 self.Refresh() event.Skip() def OnKeyDown(self, event): if event.HasModifiers(): event.Skip() return key = event.GetKeyCode() if self.__selIdxs: if event.ShiftDown(): # if add to selection use last selected item as reference sel = self.__selIdxs[-1] else: sel = self.__selIdxs[0] else: sel = -1 if key == wx.WXK_LEFT: if sel > 0: self.Select(sel - 1, deselectOthers=not event.ShiftDown()) self.EnsureVisible(sel - 1) elif key == wx.WXK_RIGHT: if sel < self.GetItemCount() - 1: self.Select(sel + 1, deselectOthers=not event.ShiftDown()) self.EnsureVisible(sel + 1) elif key == wx.WXK_END: self.Select(self.GetItemCount() - 1) self.EnsureVisible(self.GetItemCount() - 1) elif key == wx.WXK_HOME: self.Select(0) self.EnsureVisible(0) elif key == wx.WXK_ESCAPE: if self.__dragIdx != -1: self.__FinishDnD(abort=True) else: event.Skip() def __FinishDnD(self, abort=False): if self.__dragIdx != -1: if self.HasCapture(): self.ReleaseMouse() idx = self.__dragIdx if not abort: self.MovePicture(self.__dragIdx, self.__dropIdx) self.Select(self.__dropIdx) idx = self.__dropIdx self.__dragIdx = -1 self.__dropIdx = -1 self.Refresh() self.EnsureVisible(idx) def EnsureVisible(self, idx): rect = self.GetDiaRect(idx) left = rect.GetLeft() vs = self.GetViewStart()[0] ch = self.GetClientSize()[0] if left < vs: self.Scroll(left, 0) elif left > vs + ch: self.Scroll(rect.GetRight() - ch, 0) def __UpdateVirtualSize(self): width = 0 for pic in self.__pictures: bmp = ImageCache().GetThumbBmp(pic) # if the picture cannot be loaded GetWidth may return -1 width += bmp.GetWidth() + self.GAP self.SetVirtualSize((width, self.STRIP_HEIGHT)) self.Refresh() def GetThumbSize(self, pic): aspect = pic.GetWidth() / pic.GetHeight() thumbHeight = self.THUMB_HEIGHT thumbWidth = int(round(thumbHeight * aspect)) return thumbWidth, thumbHeight def GetDiaRect(self, idx): sx = 0 for picIdx, pic in enumerate(self.__pictures): thumbWidth = ImageCache().GetThumbBmp(pic).GetWidth() if idx == picIdx: rect = wx.Rect(sx, 0, thumbWidth + self.GAP, self.STRIP_HEIGHT) return rect sx += thumbWidth + self.GAP def HitTest(self, pos): pos = self.CalcUnscrolledPosition(pos) sx = 0 for idx, pic in enumerate(self.__pictures): thumbWidth = ImageCache().GetThumbBmp(pic).GetWidth() rect = wx.Rect(sx, 0, thumbWidth + self.GAP, self.STRIP_HEIGHT) if rect.Contains(pos): return idx sx += thumbWidth + self.GAP return -1 # def AddPicture(self, pic): # self.__pictures.append(pic) # self.__UpdateVirtualSize() # self._SendChangedEvent() def InsertPicture(self, idx, pic): self.__pictures.insert(idx, pic) for i in range(len(self.__selIdxs)): if self.__selIdxs[i] >= idx \ and self.__selIdxs[i] + 1 not in self.__selIdxs: self.__selIdxs[i] += 1 if not self.IsFrozen(): self.__UpdateVirtualSize() self._SendChangedEvent() def DeleteItem(self, idx): self.__pictures.pop(idx) firstSel = 0 if self.__selIdxs: firstSel = self.__selIdxs[0] if firstSel >= len(self.__pictures): firstSel = len(self.__pictures) - 1 if idx in self.__selIdxs: self.__selIdxs.remove(idx) if firstSel != idx \ and firstSel not in self.__selIdxs: self.__selIdxs.insert(0, firstSel) if len(self.__selIdxs) == 0: self.__selIdxs.append(firstSel) for i in range(len(self.__selIdxs)): if self.__selIdxs[i] > idx \ and self.__selIdxs[i] - 1 not in self.__selIdxs: self.__selIdxs[i] -= 1 if len(self.__pictures) == 0: self.__selIdxs = [] if self.__hvrIdx >= len(self.__pictures): self.__hvrIdx = -1 self.__UpdateVirtualSize() self._SendChangedEvent() evt = wx.ListEvent(wx.EVT_LIST_ITEM_SELECTED.typeId, self.GetId()) self.GetEventHandler().ProcessEvent(evt) def DeleteAllItems(self): self.__selIdxs = [] self.__pictures = [] self.__UpdateVirtualSize() self._SendChangedEvent() def GetItemCount(self): return len(self.__pictures) def GetPicture(self, idx): try: return self.__pictures[idx] except IndexError: return None def SetPicture(self, idx, pic): if idx in range(len(self.__pictures)): self.__pictures[idx] = pic self.Refresh() def GetPictures(self): return self.__pictures[:] def GetSelected(self): return self.__selIdxs[:] def GetSelectedPictures(self): selPics = [] for idx in self.__selIdxs: pic = self.GetPicture(idx) if pic is not None: selPics.append(pic) return selPics def Select(self, idx, on=True, deselectOthers=True): if idx in range(len(self.__pictures)): if deselectOthers: newSel = [] else: newSel = self.__selIdxs[:] if on and idx not in newSel: newSel.append(idx) elif not on and idx in newSel and len(newSel) > 1: # must have more than one selected item to make sure # there is at least one selected newSel.remove(idx) evt = None if newSel != self.__selIdxs: evt = wx.ListEvent(wx.EVT_LIST_ITEM_SELECTED.typeId, self.GetId()) # evt.m_itemIndex = newSelIdx # evt.m_oldItemIndex = self.__selIdx self.__selIdxs = newSel self.Refresh() if evt: self.GetEventHandler().ProcessEvent(evt) return True else: return False def SwapPictures(self, idxFrom, idxTo): picFrom = self.__pictures[idxFrom] picTo = self.__pictures[idxTo] self.__pictures[idxFrom] = picTo self.__pictures[idxTo] = picFrom evt = None try: p = self.__selIdxs.index(idxFrom) self.__selIdxs[p] = idxTo evt = wx.ListEvent(wx.EVT_LIST_ITEM_SELECTED.typeId, self.GetId()) evt.m_itemIndex = idxTo evt.m_oldItemIndex = idxFrom except ValueError: pass self.Refresh() self._SendChangedEvent() if evt: self.GetEventHandler().ProcessEvent(evt) def MovePicture(self, idxFrom, idxTo): pic = self.__pictures.pop(idxFrom) self.__pictures.insert(idxTo, pic) evt = None try: p = self.__selIdxs.index(idxFrom) self.__selIdxs[p] = idxTo evt = wx.ListEvent(wx.EVT_LIST_ITEM_SELECTED.typeId, self.GetId()) evt.m_itemIndex = idxTo evt.m_oldItemIndex = idxFrom except ValueError: pass self.Refresh() if idxFrom != idxTo: self._SendChangedEvent() if evt: self.GetEventHandler().ProcessEvent(evt) # FIXME: should be fixed height ImageCache.THUMB_SIZE = PhotoFilmStripList.THUMB_HEIGHT photofilmstrip-3.7.2/photofilmstrip/gui/DlgPositionInput.py0000644000232200023220000003615613560357351024673 0ustar debalancedebalance# Boa:Dialog:DlgPositionInput # -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2010 Jens Goepfert # import wx from photofilmstrip.core.Aspect import Aspect from photofilmstrip.gui.ctrls.PnlDlgHeader import PnlDlgHeader [wxID_DLGPOSITIONINPUT, wxID_DLGPOSITIONINPUTCMDCANCEL, wxID_DLGPOSITIONINPUTCMDOK, wxID_DLGPOSITIONINPUTCMDRESET, wxID_DLGPOSITIONINPUTPNLHDR, wxID_DLGPOSITIONINPUTSLENDPOS, wxID_DLGPOSITIONINPUTSLSTARTPOS, wxID_DLGPOSITIONINPUTSPINENDHEIGHT, wxID_DLGPOSITIONINPUTSPINENDWIDTH, wxID_DLGPOSITIONINPUTSPINENDX, wxID_DLGPOSITIONINPUTSPINENDY, wxID_DLGPOSITIONINPUTSPINSTARTHEIGHT, wxID_DLGPOSITIONINPUTSPINSTARTWIDTH, wxID_DLGPOSITIONINPUTSPINSTARTX, wxID_DLGPOSITIONINPUTSPINSTARTY, wxID_DLGPOSITIONINPUTSTENDLOCATION, wxID_DLGPOSITIONINPUTSTENDPOS, wxID_DLGPOSITIONINPUTSTENDSIZE, wxID_DLGPOSITIONINPUTSTSTARTLOCATION, wxID_DLGPOSITIONINPUTSTSTARTPOS, wxID_DLGPOSITIONINPUTSTSTARTSIZE, ] = [wx.NewId() for _init_ctrls in range(21)] class DlgPositionInput(wx.Dialog): _custom_classes = {"wx.Panel": ["PnlDlgHeader"]} def _init_coll_szStart_Items(self, parent): # generated method, don't edit parent.Add(self.stStartLocation, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) parent.Add(self.spinStartX, 0, border=0, flag=0) parent.Add(self.spinStartY, 0, border=0, flag=0) parent.Add(self.stStartSize, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) parent.Add(self.spinStartWidth, 0, border=0, flag=0) parent.Add(self.spinStartHeight, 0, border=0, flag=0) def _init_coll_szStartHdr_Items(self, parent): # generated method, don't edit parent.Add(self.stStartPos, 0, border=0, flag=0) parent.AddSpacer(8) parent.Add(self.slStartPos, 1, border=0, flag=wx.ALIGN_CENTER_VERTICAL) def _init_coll_szEndCtrls_Items(self, parent): # generated method, don't edit parent.AddSpacer(16) parent.Add(self.szEnd, 1, border=0, flag=0) def _init_coll_szEnd_Items(self, parent): # generated method, don't edit parent.Add(self.stEndLocation, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) parent.Add(self.spinEndX, 0, border=0, flag=0) parent.Add(self.spinEndY, 0, border=0, flag=0) parent.Add(self.stEndSize, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) parent.Add(self.spinEndWidth, 0, border=0, flag=0) parent.Add(self.spinEndHeight, 0, border=0, flag=0) def _init_coll_szCmds_Items(self, parent): # generated method, don't edit parent.Add(self.cmdReset, 0, border=0, flag=0) parent.AddSpacer(8) parent.Add(self.cmdCancel, 0, border=0, flag=0) parent.AddSpacer(8) parent.Add(self.cmdOk, 0, border=0, flag=0) def _init_coll_szMain_Items(self, parent): # generated method, don't edit parent.Add(self.pnlHdr, 0, border=0, flag=wx.EXPAND) parent.Add(self.szStartHdr, 0, border=4, flag=wx.ALL | wx.EXPAND) parent.Add(self.szStartCtrls, 0, border=4, flag=wx.EXPAND | wx.ALL) parent.AddSpacer(16) parent.Add(self.szEndHdr, 0, border=4, flag=wx.ALL | wx.EXPAND) parent.Add(self.szEndCtrls, 0, border=4, flag=wx.EXPAND | wx.ALL) parent.AddSpacer(16) parent.Add(self.szCmds, 0, border=4, flag=wx.ALL | wx.ALIGN_RIGHT) def _init_coll_szStartCtrls_Items(self, parent): # generated method, don't edit parent.AddSpacer(8) parent.Add(self.szStart, 1, border=0, flag=0) def _init_coll_szEndHdr_Items(self, parent): # generated method, don't edit parent.Add(self.stEndPos, 0, border=0, flag=0) parent.AddSpacer(8) parent.Add(self.slEndPos, 1, border=0, flag=wx.ALIGN_CENTER_VERTICAL) def _init_sizers(self): # generated method, don't edit self.szMain = wx.BoxSizer(orient=wx.VERTICAL) self.szStart = wx.FlexGridSizer(cols=3, hgap=4, rows=2, vgap=8) self.szStartHdr = wx.BoxSizer(orient=wx.HORIZONTAL) self.szEndHdr = wx.BoxSizer(orient=wx.HORIZONTAL) self.szStartCtrls = wx.BoxSizer(orient=wx.HORIZONTAL) self.szEnd = wx.FlexGridSizer(cols=3, hgap=4, rows=2, vgap=8) self.szEndCtrls = wx.BoxSizer(orient=wx.HORIZONTAL) self.szCmds = wx.BoxSizer(orient=wx.HORIZONTAL) self._init_coll_szMain_Items(self.szMain) self._init_coll_szStart_Items(self.szStart) self._init_coll_szStartHdr_Items(self.szStartHdr) self._init_coll_szEndHdr_Items(self.szEndHdr) self._init_coll_szStartCtrls_Items(self.szStartCtrls) self._init_coll_szEnd_Items(self.szEnd) self._init_coll_szEndCtrls_Items(self.szEndCtrls) self._init_coll_szCmds_Items(self.szCmds) self.SetSizer(self.szMain) def _init_ctrls(self, prnt): # generated method, don't edit wx.Dialog.__init__(self, id=wxID_DLGPOSITIONINPUT, name=u'DlgPositionInput', parent=prnt, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.DEFAULT_DIALOG_STYLE, title=_(u'Motion positions')) self.pnlHdr = PnlDlgHeader(id=wxID_DLGPOSITIONINPUTPNLHDR, name=u'pnlHdr', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL) self.stStartPos = wx.StaticText(id=wxID_DLGPOSITIONINPUTSTSTARTPOS, label=_(u'Start position'), name=u'stStartPos', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.slStartPos = wx.StaticLine(id=wxID_DLGPOSITIONINPUTSLSTARTPOS, name=u'slStartPos', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.stStartLocation = wx.StaticText(id=wxID_DLGPOSITIONINPUTSTSTARTLOCATION, label=_(u'Location:'), name=u'stStartLocation', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.spinStartX = wx.SpinCtrl(id=wxID_DLGPOSITIONINPUTSPINSTARTX, initial=0, max=100, min=0, name=u'spinStartX', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.SP_ARROW_KEYS) self.spinStartX.Bind(wx.EVT_TEXT, self.OnSpinChange, id=wxID_DLGPOSITIONINPUTSPINSTARTX) self.spinStartY = wx.SpinCtrl(id=wxID_DLGPOSITIONINPUTSPINSTARTY, initial=0, max=100, min=0, name=u'spinStartY', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.SP_ARROW_KEYS) self.spinStartY.Bind(wx.EVT_TEXT, self.OnSpinChange, id=wxID_DLGPOSITIONINPUTSPINSTARTY) self.stStartSize = wx.StaticText(id=wxID_DLGPOSITIONINPUTSTSTARTSIZE, label=_(u'Size:'), name=u'stStartSize', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.spinStartWidth = wx.SpinCtrl(id=wxID_DLGPOSITIONINPUTSPINSTARTWIDTH, initial=0, max=100, min=0, name=u'spinStartWidth', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.SP_ARROW_KEYS) self.spinStartWidth.Bind(wx.EVT_TEXT, self.OnSpinChange, id=wxID_DLGPOSITIONINPUTSPINSTARTWIDTH) self.spinStartHeight = wx.SpinCtrl(id=wxID_DLGPOSITIONINPUTSPINSTARTHEIGHT, initial=0, max=100, min=0, name=u'spinStartHeight', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.SP_ARROW_KEYS) self.spinStartHeight.Bind(wx.EVT_TEXT, self.OnSpinChange, id=wxID_DLGPOSITIONINPUTSPINSTARTHEIGHT) self.stEndPos = wx.StaticText(id=wxID_DLGPOSITIONINPUTSTENDPOS, label=_(u'End position'), name=u'stEndPos', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.slEndPos = wx.StaticLine(id=wxID_DLGPOSITIONINPUTSLENDPOS, name=u'slEndPos', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.stEndLocation = wx.StaticText(id=wxID_DLGPOSITIONINPUTSTENDLOCATION, label=_(u'Location:'), name=u'stEndLocation', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.spinEndX = wx.SpinCtrl(id=wxID_DLGPOSITIONINPUTSPINENDX, initial=0, max=100, min=0, name=u'spinEndX', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.SP_ARROW_KEYS) self.spinEndX.Bind(wx.EVT_TEXT, self.OnSpinChange, id=wxID_DLGPOSITIONINPUTSPINENDX) self.spinEndY = wx.SpinCtrl(id=wxID_DLGPOSITIONINPUTSPINENDY, initial=0, max=100, min=0, name=u'spinEndY', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.SP_ARROW_KEYS) self.spinEndY.Bind(wx.EVT_TEXT, self.OnSpinChange, id=wxID_DLGPOSITIONINPUTSPINENDY) self.stEndSize = wx.StaticText(id=wxID_DLGPOSITIONINPUTSTENDSIZE, label=_(u'Size:'), name=u'stEndSize', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.spinEndWidth = wx.SpinCtrl(id=wxID_DLGPOSITIONINPUTSPINENDWIDTH, initial=0, max=100, min=0, name=u'spinEndWidth', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.SP_ARROW_KEYS) self.spinEndWidth.Bind(wx.EVT_TEXT, self.OnSpinChange, id=wxID_DLGPOSITIONINPUTSPINENDWIDTH) self.spinEndHeight = wx.SpinCtrl(id=wxID_DLGPOSITIONINPUTSPINENDHEIGHT, initial=0, max=100, min=0, name=u'spinEndHeight', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.SP_ARROW_KEYS) self.spinEndHeight.Bind(wx.EVT_TEXT, self.OnSpinChange, id=wxID_DLGPOSITIONINPUTSPINENDHEIGHT) self.cmdReset = wx.Button(id=wxID_DLGPOSITIONINPUTCMDRESET, label=_(u'Reset'), name=u'cmdReset', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.cmdReset.Bind(wx.EVT_BUTTON, self.OnCmdResetButton, id=wxID_DLGPOSITIONINPUTCMDRESET) self.cmdCancel = wx.Button(id=wx.ID_CANCEL, label=_(u'&Cancel'), name=u'cmdCancel', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.cmdCancel.Bind(wx.EVT_BUTTON, self.OnCmdCancelButton, id=wx.ID_CANCEL) self.cmdOk = wx.Button(id=wx.ID_OK, label=_(u'&Ok'), name=u'cmdOk', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self._init_sizers() def __init__(self, parent, pic, aspect): self._init_ctrls(parent) self.pnlHdr.SetTitle(_(u'Adjust motion positions directly')) self.pnlHdr.SetBitmap(wx.ArtProvider.GetBitmap('PFS_MOTION_MANUAL_32')) self.__pic = pic self.__ratio = Aspect.ToFloat(aspect) self.__doOnChange = True self.__backupStart = self.__pic.GetStartRect() self.__backupEnd = self.__pic.GetTargetRect() font = self.stStartPos.GetFont() font.SetWeight(wx.FONTWEIGHT_BOLD) self.stStartPos.SetFont(font) self.stEndPos.SetFont(font) self._InitValues() self.SetInitialSize(self.GetEffectiveMinSize()) self.CenterOnParent() self.SetFocus() def _InitValues(self): self.__doOnChange = False # Init ranges with max values self.spinStartX.SetRange(0, self.__pic.GetWidth()) self.spinStartY.SetRange(0, self.__pic.GetHeight()) self.spinStartWidth.SetRange(0, min(int(round(self.__pic.GetHeight() * self.__ratio)), self.__pic.GetWidth())) self.spinStartHeight.SetRange(0, min(int(round(self.__pic.GetWidth() / self.__ratio)), self.__pic.GetHeight())) self.spinEndX.SetRange(0, self.__pic.GetWidth()) self.spinEndY.SetRange(0, self.__pic.GetHeight()) self.spinEndWidth.SetRange(0, min(int(round(self.__pic.GetHeight() * self.__ratio)), self.__pic.GetWidth())) self.spinEndHeight.SetRange(0, min(int(round(self.__pic.GetWidth() / self.__ratio)), self.__pic.GetHeight())) # Init values self.spinStartX.SetValue(self.__pic.GetStartRect()[0]) self.spinStartY.SetValue(self.__pic.GetStartRect()[1]) self.spinStartWidth.SetValue(self.__pic.GetStartRect()[2]) self.spinStartHeight.SetValue(self.__pic.GetStartRect()[3]) self.spinEndX.SetValue(self.__pic.GetTargetRect()[0]) self.spinEndY.SetValue(self.__pic.GetTargetRect()[1]) self.spinEndWidth.SetValue(self.__pic.GetTargetRect()[2]) self.spinEndHeight.SetValue(self.__pic.GetTargetRect()[3]) self.__doOnChange = True self._SetupRanges() def _SetupRanges(self): ''' Limit the location ranges to the current adjusted size ''' self.spinStartX.SetRange(0, self.__pic.GetWidth() - self.spinStartWidth.GetValue()) self.spinStartY.SetRange(0, self.__pic.GetHeight() - self.spinStartHeight.GetValue()) self.spinEndX.SetRange(0, self.__pic.GetWidth() - self.spinEndWidth.GetValue()) self.spinEndY.SetRange(0, self.__pic.GetHeight() - self.spinEndHeight.GetValue()) def _PreserveAspect(self, wxId): self.__doOnChange = False if wxId == wxID_DLGPOSITIONINPUTSPINSTARTWIDTH: self.spinStartHeight.SetValue(int(round(self.spinStartWidth.GetValue() / self.__ratio))) if wxId == wxID_DLGPOSITIONINPUTSPINSTARTHEIGHT: self.spinStartWidth.SetValue(int(round(self.spinStartHeight.GetValue() * self.__ratio))) if wxId == wxID_DLGPOSITIONINPUTSPINENDWIDTH: self.spinEndHeight.SetValue(int(round(self.spinEndWidth.GetValue() / self.__ratio))) if wxId == wxID_DLGPOSITIONINPUTSPINENDHEIGHT: self.spinEndWidth.SetValue(int(round(self.spinEndHeight.GetValue() * self.__ratio))) self.__doOnChange = True def OnSpinChange(self, event): if not self.__doOnChange: return self._PreserveAspect(event.GetId()) startRect = (self.spinStartX.GetValue(), self.spinStartY.GetValue(), self.spinStartWidth.GetValue(), self.spinStartHeight.GetValue()) endRect = (self.spinEndX.GetValue(), self.spinEndY.GetValue(), self.spinEndWidth.GetValue(), self.spinEndHeight.GetValue()) if event.GetId() in (wxID_DLGPOSITIONINPUTSPINENDWIDTH, wxID_DLGPOSITIONINPUTSPINENDHEIGHT, wxID_DLGPOSITIONINPUTSPINSTARTWIDTH, wxID_DLGPOSITIONINPUTSPINSTARTHEIGHT): self._SetupRanges() self.__pic.SetStartRect(startRect) self.__pic.SetTargetRect(endRect) event.Skip() def OnCmdResetButton(self, event): self.__pic.SetStartRect(self.__backupStart) self.__pic.SetTargetRect(self.__backupEnd) self._InitValues() event.Skip() def OnCmdCancelButton(self, event): self.__pic.SetStartRect(self.__backupStart) self.__pic.SetTargetRect(self.__backupEnd) event.Skip() photofilmstrip-3.7.2/photofilmstrip/gui/DlgDuration.py0000644000232200023220000001271613560357351023630 0ustar debalancedebalance# encoding: UTF-8 # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2010 Jens Goepfert # import wx import wx.lib.masked.timectrl from photofilmstrip.gui.ctrls.PnlDlgHeader import PnlDlgHeader class DlgDuration(wx.Dialog): def _InitSizers(self): szManual = wx.BoxSizer(wx.HORIZONTAL) szManual.Add(self.rbManual, flag=wx.ALIGN_CENTER_VERTICAL) szManual.AddSpacer(8) szManual.Add(self.timeCtrlTotalLength, 1) szCtrls = wx.BoxSizer(orient=wx.VERTICAL) szCtrls.AddSpacer(8) szCtrls.Add(self.cbTotalLength, border=8, flag=wx.LEFT) szCtrls.AddSpacer(8) szCtrls.Add(self.rbAudio, border=32, flag=wx.LEFT | wx.EXPAND) szCtrls.AddSpacer(8) szCtrls.Add(szManual, border=32, flag=wx.LEFT | wx.EXPAND) szCmds = wx.BoxSizer(orient=wx.HORIZONTAL) szCmds.Add(self.cmdCancel, 0, border=0, flag=0) szCmds.AddSpacer(8) szCmds.Add(self.cmdOk, 0, border=0, flag=0) szMain = wx.BoxSizer(orient=wx.VERTICAL) szMain.Add(self.pnlHdr, 0, border=0, flag=wx.EXPAND) szMain.Add(szCtrls, 0, border=8, flag=wx.ALL | wx.EXPAND) szMain.Add(self.staticLine, 0, border=0, flag=wx.EXPAND) szMain.Add(szCmds, 0, border=8, flag=wx.ALL | wx.ALIGN_RIGHT) self.SetSizer(szMain) def _InitCtrls(self): self.pnlHdr = PnlDlgHeader(self) self.cbTotalLength = wx.CheckBox(self, label=_(u'Total length:'), name=u'cbTotalLength') self.cbTotalLength.SetValue(False) self.cbTotalLength.SetToolTip(_(u'Overrides the duration of single pictures and gives the project this total length.')) self.cbTotalLength.Bind(wx.EVT_CHECKBOX, self.OnControlStatusTotalLength) self.rbManual = wx.RadioButton(self, label=_(u'User defined:'), name=u'rbManual') self.rbManual.Bind(wx.EVT_RADIOBUTTON, self.OnControlStatusTotalLength) self.timeCtrlTotalLength = wx.lib.masked.timectrl.TimeCtrl(self, display_seconds=True, fmt24hr=True, name=u'timeCtrlTotalLength', oob_color=wx.YELLOW, style=0, useFixedWidthFont=True, value='12:00:00 AM', size=wx.Size(300, -1)) self.timeCtrlTotalLength.Enable(False) self.rbAudio = wx.RadioButton(self, label=_(u'Fit to audio files'), name=u'rbAudio') self.rbAudio.Bind(wx.EVT_RADIOBUTTON, self.OnControlStatusTotalLength) self.staticLine = wx.StaticLine(self) self.cmdCancel = wx.Button(self, id=wx.ID_CANCEL, label=_(u'&Cancel'), name=u'cmdCancel') self.cmdOk = wx.Button(self, id=wx.ID_OK, label=_(u'&Ok'), name=u'cmdOk') self.cmdOk.Bind(wx.EVT_BUTTON, self.OnCmdOkButton, id=wx.ID_OK) self.cmdOk.SetDefault() def __init__(self, parent, project=None): wx.Dialog.__init__(self, parent, name=u'DlgDuration', style=wx.DEFAULT_DIALOG_STYLE, title=_(u'Slideshow duration')) self._InitCtrls() self.pnlHdr.SetTitle(_(u'Configure duration of slideshow')) self.pnlHdr.SetBitmap(wx.ArtProvider.GetBitmap('PFS_ICON_32')) defTime = wx.DateTime.Now() defTime.SetHMS(0, 0, 30) minTime = wx.DateTime.Now() minTime.SetHMS(0, 0, 1) maxTime = wx.DateTime.Now() maxTime.SetHMS(1, 59, 59) self.timeCtrlTotalLength.SetValue(defTime) self.timeCtrlTotalLength.SetMin(minTime) self.timeCtrlTotalLength.SetMax(maxTime) self.timeCtrlTotalLength.SetLimited(True) self.__project = project pfsDur = project.GetDuration(calc=True) duration = project.GetDuration(calc=False) if duration is None: self.cbTotalLength.SetValue(False) elif duration <= 0: self.cbTotalLength.SetValue(True) self.rbAudio.SetValue(True) else: self.cbTotalLength.SetValue(True) self.rbManual.SetValue(True) pfsDur = duration pfsDur = int(round(pfsDur)) dur = wx.DateTime.Now() dur.SetHMS(pfsDur // 3600, (pfsDur % 3600) // 60, pfsDur % 60) try: self.timeCtrlTotalLength.SetWxDateTime(dur) except ValueError: # duration is invalid if there are no photos pass self.__ControlStatusTotalLength() self._InitSizers() self.Fit() self.CenterOnParent() self.SetFocus() def OnControlStatusTotalLength(self, event): self.__ControlStatusTotalLength() event.Skip() def OnCmdOkButton(self, event): self.__project.SetDuration(self.__GetTotalLength()) event.Skip() def __ControlStatusTotalLength(self): active = self.cbTotalLength.GetValue() manual = self.rbManual.GetValue() self.rbAudio.Enable(active) self.rbManual.Enable(active) self.timeCtrlTotalLength.Enable(active and manual) def __GetTotalLength(self): totalLength = None if self.cbTotalLength.GetValue(): if self.rbManual.GetValue(): totalLength = 0 dateTime = self.timeCtrlTotalLength.GetValue(as_wxDateTime=True) totalLength += dateTime.GetHour() * 3600 totalLength += dateTime.GetMinute() * 60 totalLength += dateTime.GetSecond() elif self.rbAudio.GetValue(): totalLength = -1 return totalLength photofilmstrip-3.7.2/photofilmstrip/gui/PnlEditPicture.py0000644000232200023220000003630113560357351024303 0ustar debalancedebalance# Boa:FramePanel:PnlEditPicture # -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # import wx from photofilmstrip.core.Picture import Picture from photofilmstrip.gui.ctrls.PnlFloatSpinCtrl import ( PnlFloatSpinCtrl, EVT_VALUE_CHANGED) [wxID_PNLEDITPICTURE, wxID_PNLEDITPICTURECHOICEEFFECT, wxID_PNLEDITPICTURECHOICEMOVEMENT, wxID_PNLEDITPICTURECHOICETRANS, wxID_PNLEDITPICTURECMDROTATELEFT, wxID_PNLEDITPICTURECMDROTATERIGHT, wxID_PNLEDITPICTUREPNLIMGDURATION, wxID_PNLEDITPICTUREPNLTRANSDURATION, wxID_PNLEDITPICTURESTATICLINE1, wxID_PNLEDITPICTURESTATICLINE2, wxID_PNLEDITPICTURESTDURATIONUNIT, wxID_PNLEDITPICTURESTEFFECT, wxID_PNLEDITPICTURESTMOVEMENT, wxID_PNLEDITPICTURESTPROCESS, wxID_PNLEDITPICTURESTROTATION, wxID_PNLEDITPICTURESTSETTINGS, wxID_PNLEDITPICTURESTSUBTITLE, wxID_PNLEDITPICTURESTTRANS, wxID_PNLEDITPICTURESTTRANSUNIT, wxID_PNLEDITPICTURETCCOMMENT, ] = [wx.NewId() for _init_ctrls in range(20)] class PnlEditPicture(wx.Panel): _custom_classes = {"wx.Panel": ["PnlFloatSpinCtrl"]} def _init_coll_sizerMain_Items(self, parent): # generated method, don't edit parent.Add(self.szSettings, 0, border=4, flag=wx.ALL) parent.AddSpacer(8) parent.Add(self.staticLine1, 0, border=4, flag=wx.ALL | wx.EXPAND) parent.AddSpacer(8) parent.Add(self.szTimes, 0, border=4, flag=wx.ALL) parent.AddSpacer(8) parent.Add(self.staticLine2, 0, border=4, flag=wx.EXPAND | wx.ALL) parent.AddSpacer(8) parent.Add(self.szSubtitle, 1, border=4, flag=wx.ALL | wx.EXPAND) def _init_coll_szTimes_Items(self, parent): # generated method, don't edit parent.Add(self.stProcess, 0, border=0, flag=0) parent.Add(self.sizerTimesCtrls, 0, border=16, flag=wx.LEFT) def _init_coll_szSubtitle_Items(self, parent): # generated method, don't edit parent.Add(self.stSubtitle, 0, border=0, flag=0) parent.Add(self.tcComment, 1, border=16, flag=wx.LEFT | wx.EXPAND) def _init_coll_sizerTimesCtrls_Items(self, parent): # generated method, don't edit parent.Add(self.stMovement, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) parent.Add(self.choiceMovement, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND) parent.Add(self.pnlImgDuration, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) parent.Add(self.stDurationUnit, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) parent.Add(self.stTrans, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) parent.Add(self.choiceTrans, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND) parent.Add(self.pnlTransDuration, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) parent.Add(self.stTransUnit, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) def _init_coll_szSettings_Items(self, parent): # generated method, don't edit parent.Add(self.stSettings, 0, border=0, flag=0) parent.Add(self.szSettingsCtrls, 0, border=16, flag=wx.LEFT) def _init_coll_szSettingsCtrls_Growables(self, parent): # generated method, don't edit parent.AddGrowableCol(1) #!!! def _init_coll_szSettingsCtrls_Items(self, parent): # generated method, don't edit parent.Add(self.stRotation, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) parent.Add(self.sizerRotationTools, 0, border=0, flag=wx.EXPAND) parent.Add(self.stEffect, 0, border=0, flag=wx.ALIGN_CENTER_VERTICAL) parent.Add(self.choiceEffect, 0, border=0, flag=wx.EXPAND) def _init_coll_sizerRotationTools_Items(self, parent): # generated method, don't edit parent.Add(self.cmdRotateLeft, 0, border=0, flag=0) parent.AddStretchSpacer(1) parent.Add(self.cmdRotateRight, 0, border=0, flag=0) def _init_sizers(self): # generated method, don't edit self.sizerMain = wx.BoxSizer(orient=wx.HORIZONTAL) self.szSettingsCtrls = wx.FlexGridSizer(cols=2, hgap=8, rows=2, vgap=8) self.szSubtitle = wx.BoxSizer(orient=wx.VERTICAL) self.sizerRotationTools = wx.BoxSizer(orient=wx.HORIZONTAL) self.sizerTimesCtrls = wx.FlexGridSizer(cols=4, hgap=8, rows=2, vgap=8) self.szTimes = wx.BoxSizer(orient=wx.VERTICAL) self.szSettings = wx.BoxSizer(orient=wx.VERTICAL) self._init_coll_sizerMain_Items(self.sizerMain) self._init_coll_szSettingsCtrls_Items(self.szSettingsCtrls) self._init_coll_szSettingsCtrls_Growables(self.szSettingsCtrls) self._init_coll_szSubtitle_Items(self.szSubtitle) self._init_coll_sizerRotationTools_Items(self.sizerRotationTools) self._init_coll_sizerTimesCtrls_Items(self.sizerTimesCtrls) self._init_coll_szTimes_Items(self.szTimes) self._init_coll_szSettings_Items(self.szSettings) self.SetSizer(self.sizerMain) def _init_ctrls(self, prnt): # generated method, don't edit wx.Panel.__init__(self, id=wxID_PNLEDITPICTURE, name=u'PnlEditPicture', parent=prnt, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL) self.SetClientSize(wx.Size(827, 137)) self.stSettings = wx.StaticText(id=wxID_PNLEDITPICTURESTSETTINGS, label=_(u'Settings'), name=u'stSettings', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.stRotation = wx.StaticText(id=wxID_PNLEDITPICTURESTROTATION, label=_(u'Rotation:'), name=u'stRotation', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.cmdRotateLeft = wx.BitmapButton(bitmap=wx.ArtProvider.GetBitmap('PFS_IMAGE_ROTATION_LEFT_16'), id=wxID_PNLEDITPICTURECMDROTATELEFT, name=u'cmdRotateLeft', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.BU_AUTODRAW) self.cmdRotateLeft.SetBitmapDisabled(wx.ArtProvider.GetBitmap('PFS_IMAGE_ROTATION_LEFT_D_16')) self.cmdRotateLeft.Bind(wx.EVT_BUTTON, self.OnCmdRotateLeftButton, id=wxID_PNLEDITPICTURECMDROTATELEFT) self.cmdRotateRight = wx.BitmapButton(bitmap=wx.ArtProvider.GetBitmap('PFS_IMAGE_ROTATION_RIGHT_16'), id=wxID_PNLEDITPICTURECMDROTATERIGHT, name=u'cmdRotateRight', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.BU_AUTODRAW) self.cmdRotateRight.SetBitmapDisabled(wx.ArtProvider.GetBitmap('PFS_IMAGE_ROTATION_RIGHT_D_16')) self.cmdRotateRight.Bind(wx.EVT_BUTTON, self.OnCmdRotateRightButton, id=wxID_PNLEDITPICTURECMDROTATERIGHT) self.stEffect = wx.StaticText(id=wxID_PNLEDITPICTURESTEFFECT, label=_(u'Effect:'), name=u'stEffect', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.choiceEffect = wx.Choice(choices=[], id=wxID_PNLEDITPICTURECHOICEEFFECT, name=u'choiceEffect', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.choiceEffect.Bind(wx.EVT_CHOICE, self.OnChoiceEffectChoice, id=wxID_PNLEDITPICTURECHOICEEFFECT) self.staticLine1 = wx.StaticLine(id=wxID_PNLEDITPICTURESTATICLINE1, name='staticLine1', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.LI_VERTICAL) self.stProcess = wx.StaticText(id=wxID_PNLEDITPICTURESTPROCESS, label=_(u'Process'), name=u'stProcess', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.stMovement = wx.StaticText(id=wxID_PNLEDITPICTURESTMOVEMENT, label=_(u'Movement:'), name=u'stMovement', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.choiceMovement = wx.Choice(choices=[], id=wxID_PNLEDITPICTURECHOICEMOVEMENT, name=u'choiceMovement', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.pnlImgDuration = PnlFloatSpinCtrl(id=wxID_PNLEDITPICTUREPNLIMGDURATION, name=u'pnlImgDuration', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL) self.stDurationUnit = wx.StaticText(id=wxID_PNLEDITPICTURESTDURATIONUNIT, label=_(u'sec'), name=u'stDurationUnit', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.stTrans = wx.StaticText(id=wxID_PNLEDITPICTURESTTRANS, label=_(u'Transition:'), name=u'stTrans', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.choiceTrans = wx.Choice(choices=[], id=wxID_PNLEDITPICTURECHOICETRANS, name=u'choiceTrans', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.pnlTransDuration = PnlFloatSpinCtrl(id=wxID_PNLEDITPICTUREPNLTRANSDURATION, name=u'pnlTransDuration', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL) self.stTransUnit = wx.StaticText(id=wxID_PNLEDITPICTURESTTRANSUNIT, label=_(u'sec'), name=u'stTransUnit', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.staticLine2 = wx.StaticLine(id=wxID_PNLEDITPICTURESTATICLINE2, name='staticLine2', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.LI_VERTICAL) self.stSubtitle = wx.StaticText(id=wxID_PNLEDITPICTURESTSUBTITLE, label=_(u'Subtitle'), name=u'stSubtitle', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=0) self.tcComment = wx.TextCtrl(id=wxID_PNLEDITPICTURETCCOMMENT, name=u'tcComment', parent=self, pos=wx.Point(-1, -1), size=wx.Size(-1, -1), style=wx.TE_MULTILINE, value='') self.tcComment.Bind(wx.EVT_TEXT, self.OnTextCtrlCommentText, id=wxID_PNLEDITPICTURETCCOMMENT) self._init_sizers() def __init__(self, parent, id, pos, size, style, name): self._init_ctrls(parent) font = self.stSettings.GetFont() font.SetWeight(wx.FONTWEIGHT_BOLD) self.stSettings.SetFont(font) self.stProcess.SetFont(font) self.stSubtitle.SetFont(font) self.choiceMovement.Append(_(u"Linear"), Picture.MOVE_LINEAR) self.choiceMovement.Append(_(u"Accelerated"), Picture.MOVE_ACCEL) self.choiceMovement.Append(_(u"Delayed"), Picture.MOVE_DELAYED) self.choiceMovement.SetSelection(1) self.choiceMovement.Bind(wx.EVT_CHOICE, self.OnChoiceMvmntChoice) self.pnlImgDuration.SetRange(1, 6000) self.pnlImgDuration.SetValue(7) self.pnlImgDuration.Bind(EVT_VALUE_CHANGED, self.OnImgDurationChanged) self.choiceEffect.Append(_(u"No effect"), Picture.EFFECT_NONE) self.choiceEffect.Append(_(u"Black and White"), Picture.EFFECT_BLACK_WHITE) self.choiceEffect.Append(_(u"Sepia tone"), Picture.EFFECT_SEPIA) self.choiceEffect.SetSelection(0) self.pnlTransDuration.SetRange(5, 200) self.pnlTransDuration.SetValue(1) self.pnlTransDuration.Bind(EVT_VALUE_CHANGED, self.OnTransDurationChanged) self.choiceTrans.Append(_(u"None"), Picture.TRANS_NONE) self.choiceTrans.Append(_(u"Fade"), Picture.TRANS_FADE) self.choiceTrans.Append(_(u"Roll"), Picture.TRANS_ROLL) self.choiceTrans.SetSelection(1) self.choiceTrans.Bind(wx.EVT_CHOICE, self.OnChoiceTransChoice) self._pictures = [] self.SetPictures(None) def __FindChoiceIdxByData(self, choice, data): for idx in range(choice.GetCount()): if choice.GetClientData(idx) == data: return idx return wx.NOT_FOUND def __GetChoiceDataBySelection(self, choice): selIdx = choice.GetSelection() if selIdx != wx.NOT_FOUND: return choice.GetClientData(selIdx) else: return None def __SetChoiceSelectionByData(self, choice, data): idx = self.__FindChoiceIdxByData(choice, data) if idx != wx.NOT_FOUND: choice.Select(idx) def OnCmdRotateLeftButton(self, event): for pic in self._pictures: pic.Rotate(False) def OnCmdRotateRightButton(self, event): for pic in self._pictures: pic.Rotate(True) def OnChoiceEffectChoice(self, event): for pic in self._pictures: pic.SetEffect(event.GetClientData()) event.Skip() def OnChoiceMvmntChoice(self, event): mvmnt = event.GetClientData() for pic in self._pictures: pic.SetMovement(mvmnt) event.Skip() def OnChoiceTransChoice(self, event): trans = event.GetClientData() for pic in self._pictures: pic.SetTransition(trans) self.pnlTransDuration.Enable(trans != Picture.TRANS_NONE) event.Skip() def OnTransDurationChanged(self, event): duration = event.GetValue() for pic in self._pictures: pic.SetTransitionDuration(duration) def OnImgDurationChanged(self, event): duration = event.GetValue() for pic in self._pictures: pic.SetDuration(duration) def OnTextCtrlCommentText(self, event): for pic in self._pictures: pic.SetComment(self.tcComment.GetValue()) event.Skip() def SetPictures(self, pictures): if pictures is None: pictures = [] self.Enable(len(pictures) > 0) self._pictures = pictures if self._pictures: pic = self._pictures[0] self.tcComment.ChangeValue(pic.GetComment()) self.pnlImgDuration.SetValue(pic.GetDuration()) self.__SetChoiceSelectionByData(self.choiceMovement, pic.GetMovement()) self.__SetChoiceSelectionByData(self.choiceEffect, pic.GetEffect()) self.__SetChoiceSelectionByData(self.choiceTrans, pic.GetTransition()) self.pnlTransDuration.SetValue(pic.GetTransitionDuration(rawValue=True)) self.pnlTransDuration.Enable(pic.GetTransition() != Picture.TRANS_NONE) def SetupModeByProject(self, project): if project.GetTimelapse(): selTrans = self.choiceTrans.GetSelection() rollIdx = self.__FindChoiceIdxByData( self.choiceTrans, Picture.TRANS_ROLL) if rollIdx != wx.NOT_FOUND: self.choiceTrans.Delete(rollIdx) if rollIdx == selTrans: self.choiceTrans.Select(0) unit = _("fpp") tooltip = _("frames per picture - the number of frames each picture will be shown") else: projDuration = project.GetDuration(calc=False) if projDuration is None: unit = _('sec') else: # project duration is set to a fixed value (or by music), so # the units are not seconds but kind of ratio time unit = "-" tooltip = "" self.stDurationUnit.SetLabel(unit) self.stTransUnit.SetLabel(unit) self.stDurationUnit.SetToolTip(tooltip) self.stTransUnit.SetToolTip(tooltip) photofilmstrip-3.7.2/photofilmstrip/gui/DlgPicDurationByAudio.py0000644000232200023220000002017613560357351025540 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2018 Jens Goepfert # import wx from photofilmstrip.core.GPlayer import GPlayer from photofilmstrip.gui.ctrls.PnlDlgHeader import PnlDlgHeader class DlgPicDurationByAudio(wx.Dialog): def __init__(self, parent, audioFile, expectedSteps): ''' :type parent: wx.Window :type audioFile: str :type expectedSteps: int ''' wx.Dialog.__init__(self, parent, style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER) self.SetTitle(_(u'Adjust picture durations')) self.pnlHdr = PnlDlgHeader(self) self.pnlHdr.SetTitle(_(u'Adjust picture durations to audio file')) self.pnlHdr.SetBitmap(wx.ArtProvider.GetBitmap('PFS_MUSIC_DURATION_32')) szMsg = self.CreateTextSizer( _("Find your picture duration by playing the audio file of your project and\n" "pressing the hit button to apply the current playing time.")) self.stAudio = wx.StaticText(self, wx.ID_ANY, style=wx.ST_NO_AUTORESIZE) font = self.stAudio.GetFont() font.SetPointSize(16) self.stAudio.SetFont(font) self.listbox = wx.ListBox(self, wx.ID_ANY) self.listbox.SetSizeHints(wx.Size(-1, 200)) self.listbox.Bind(wx.EVT_KEY_DOWN, self.__OnStepListKeyDown) self.listbox.Bind(wx.EVT_LISTBOX_DCLICK, self.__OnStepListDClickDown) self.btnPlay = wx.Button(self, wx.ID_ANY, _("Play")) self.btnPlay.Bind(wx.EVT_BUTTON, self.__OnPlay) self.btnHit = wx.Button(self, wx.ID_ANY, _("Hit")) self.btnHit.Disable() self.btnHit.Bind(wx.EVT_BUTTON, self.__OnHit) self.btnCancel = wx.Button(self, wx.ID_CANCEL, _('&Cancel')) self.btnOk = wx.Button(self, wx.ID_OK, _('&Ok')) szButtons = wx.BoxSizer(wx.HORIZONTAL) szButtons.Add(self.btnPlay, flag=wx.RIGHT, border=8) szButtons.Add(self.btnHit, flag=wx.RIGHT, border=8) szButtons.AddStretchSpacer() szButtons.Add(self.btnCancel, flag=wx.RIGHT, border=8) szButtons.Add(self.btnOk) sz = wx.BoxSizer(wx.VERTICAL) sz.Add(self.pnlHdr, flag=wx.EXPAND) sz.Add(szMsg, flag=wx.EXPAND | wx.ALL, border=8) sz.Add(self.stAudio, flag=wx.EXPAND | wx.ALL, border=8) sz.Add(self.listbox, 1, wx.EXPAND | wx.ALL, border=8) sz.Add(szButtons, flag=wx.ALL | wx.ALIGN_RIGHT, border=8) self.SetSizerAndFit(sz) self.__audioFile = audioFile self.__player = None self.__timer = None self.__duration = None self.__expectedSteps = expectedSteps self.__stepIdx = 0 self.__lastTime = None self.__InitStepList() self.stAudio.SetLabel(self.__CreateAudioInfoText(None)) self.SetEscapeId(wx.ID_CANCEL) self.Bind(wx.EVT_TIMER, self.__OnTimer) self.Bind(wx.EVT_CLOSE, self.__OnClose) self.Bind(wx.EVT_BUTTON, self.__OnClose, id=wx.ID_OK) self.Bind(wx.EVT_BUTTON, self.__OnClose, id=wx.ID_CANCEL) def __OnTimer(self, event): # pylint: disable=unused-argument if self.__player: if self.__player.IsPlaying(): posMiliSecs = self.__player.GetPosition() if posMiliSecs: self.stAudio.SetLabel( self.__CreateAudioInfoText(posMiliSecs)) else: self.__ProcessStop() def __OnPlay(self, event): # pylint: disable=unused-argument if self.__player is None or not self.__player.IsPlaying(): self.btnPlay.SetLabel(_("Stop")) self.btnHit.Enable() self.__InitStepList() self.__timer = wx.Timer(self) self.__timer.Start(50) self.__player = GPlayer(self.__audioFile) self.__lastTime = 0 self.__duration = self.__player.GetLength() self.__player.Play() # self.__player.SetPosition(5000) self.btnHit.SetFocus() else: self.__ProcessStop() def __OnHit(self, event): # pylint: disable=unused-argument milliSecs = self.__player.GetPosition() if self.__stepIdx < self.__expectedSteps - 1: milliSecs -= 50 # time to react self.__NextStepDuration(milliSecs - self.__lastTime) self.__lastTime = milliSecs if self.__stepIdx >= self.__expectedSteps - 1: self.__NextStepDuration(self.__duration - self.__lastTime) self.__ProcessStop() def __OnClose(self, event): if self.__timer: self.__timer.Stop() if self.__player and self.__player.IsPlaying(): self.__player.Stop() event.Skip() def __OnStepListKeyDown(self, event): if event.GetKeyCode() == wx.WXK_DELETE: sel = self.listbox.GetSelection() if sel != wx.NOT_FOUND: self.listbox.SetString(self.__CreateDurationText(sel, None)) self.listbox.Delete(sel) def __OnStepListDClickDown(self, event): event.Skip() def __InitStepList(self): self.__stepIdx = 0 self.listbox.Clear() for ctr in range(self.__expectedSteps): self.listbox.Append(self.__CreateDurationText(ctr, None)) self.listbox.Select(0) def __ProcessStop(self): self.btnPlay.SetLabel(_("Play")) self.btnHit.Disable() self.__timer.Stop() self.__player.Stop() self.__player = None def __NextStepDuration(self, duration): value = self.__CreateDurationText(self.__stepIdx, duration) self.listbox.SetString(self.__stepIdx, value) self.listbox.SetClientData(self.__stepIdx, duration) self.__stepIdx += 1 if self.__stepIdx < self.listbox.GetCount(): self.listbox.Select(self.__stepIdx) def __TimeToStr(self, milliSecs): if milliSecs is None: return "--:--:--,--" else: secs = milliSecs // 1000.0 hours = int(secs / 3600.0) minutes = int(secs / 60.0) % 60 seconds = int(secs) % 60 frac = ((milliSecs / 1000.0) % 1) * 1000 return "%02d:%02d:%02d,%03d" % (hours, minutes, seconds, frac) def __CreateAudioInfoText(self, posMiliSecs): return "{}: {}".format(_("Playing time"), self.__TimeToStr(posMiliSecs)) def __CreateDurationText(self, idx, value): return "{}: {}".format(idx + 1, self.__TimeToStr(value)) def GetDurations(self): result = [] if self.listbox.HasClientData(): for idx in range(self.__expectedSteps): duration = self.listbox.GetClientData(idx) if duration is not None: result.append(duration) else: break return result @staticmethod def Interact(parent, project): ''' :type parent: wx.Window :type project: photofilmstrip.core.Project.Project ''' pics = project.GetPictures() if len(pics) == 0: return if len(project.GetAudioFiles()) == 0: dlg = wx.MessageDialog(parent, _(u"Your project does not have an audio file configured."), _(u"Error"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return if len(project.GetAudioFiles()) > 1: dlg = wx.MessageDialog(parent, _(u"Your project uses more than one audio file. Currently the durations can be adjusted only for one audio file."), _(u"Error"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return dlg = DlgPicDurationByAudio(parent, project.GetAudioFile(), len(pics)) if dlg.ShowModal() == wx.ID_OK: for idx, duration in enumerate(dlg.GetDurations()): try: pics[idx].SetDuration(duration / 1000.0) except IndexError: break dlg.Destroy() photofilmstrip-3.7.2/photofilmstrip/gui/DlgBugReport.py0000644000232200023220000000740313560357351023751 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # import io import sys import traceback import urllib.parse import urllib.request import wx from wx.lib.wordwrap import wordwrap from photofilmstrip import Constants class DlgBugReport(wx.Dialog): PARENT = None @classmethod def Initialize(cls, parent): cls.PARENT = parent def excepthook(etype, value, tb): if not getattr(sys, 'frozen', False): traceback.print_exception(etype, value, tb) output = io.StringIO() traceback.print_exception(etype, value, tb, file=output) dlg = DlgBugReport(cls.PARENT, output.getvalue()) dlg.ShowModal() dlg.Destroy() sys.excepthook = excepthook def __init__(self, parent, msg): wx.Dialog.__init__(self, parent, -1, _(u"An unexpected error occured"), name=u'DlgBugReport') text = _(u"An unexpected error occured. Do you want to send this bug report to the developers of %s?") % Constants.APP_NAME stBmp = wx.StaticBitmap( self, -1, wx.ArtProvider.GetBitmap(wx.ART_ERROR, wx.ART_OTHER, (32, 32))) stMsg = wx.StaticText(self, -1, wordwrap(text, 300, wx.ClientDC(self))) szTop = wx.BoxSizer(wx.HORIZONTAL) szTop.Add(stBmp, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 8) szTop.Add(stMsg, 0, wx.ALL, 8) self.tcMsg = wx.TextCtrl( self, -1, msg, style=wx.TE_MULTILINE | wx.TE_READONLY | wx.TE_DONTWRAP) szCmd = self.CreateSeparatedButtonSizer(wx.YES | wx.NO) szMain = wx.BoxSizer(wx.VERTICAL) szMain.Add(szTop, 0) szMain.Add(self.tcMsg, 1, wx.EXPAND | wx.ALL, 4) szMain.Add(szCmd, 0, wx.EXPAND | wx.ALL, 4) self.SetSizer(szMain) self.Bind(wx.EVT_BUTTON, self.OnNo, id=wx.ID_NO) self.Bind(wx.EVT_BUTTON, self.OnYes, id=wx.ID_YES) self.SetAffirmativeId(wx.ID_YES) self.SetEscapeId(wx.ID_NO) self.SetInitialSize(self.GetEffectiveMinSize()) self.CenterOnParent() self.SetFocus() def OnYes(self, event): # pylint: disable=unused-argument info = "\n".join([sys.platform, sys.getdefaultencoding(), sys.getfilesystemencoding(), str(getattr(sys, 'frozen', False))]) params = urllib.parse.urlencode( {'bugreport': "%s-%s\n\n%s\n%s\n" % (Constants.APP_NAME, Constants.APP_VERSION_EX, self.tcMsg.GetValue(), info)}) params = params.encode('utf_8') try: fd = urllib.request.urlopen( "http://www.photofilmstrip.org/bugreport.php", params) result = fd.read() result = result.decode("utf-8") except IOError: result = None if result and result.find("Result 1") != -1: dlg = wx.MessageDialog( self, _(u"Bug-Report send. Thank you for your support."), _(u"Information"), wx.OK | wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy() else: dlg = wx.MessageDialog(self, _(u"Sorry, this function is temporary not available.."), _(u"Error"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() self.EndModal(wx.ID_YES) def OnNo(self, event): self.EndModal(wx.ID_NO) event.Skip() photofilmstrip-3.7.2/photofilmstrip/gui/ImageSectionEditor.py0000644000232200023220000005525413560357351025136 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # import re import threading import time import wx import photofilmstrip.res.cursors as cursors from photofilmstrip.lib.common.ObserverPattern import Observable, Observer from photofilmstrip.core.Aspect import Aspect from photofilmstrip.core import PILBackend from photofilmstrip.gui.util.ImageCache import ImageCache EVT_RECT_CHANGED_TYPE = wx.NewEventType() EVT_RECT_CHANGED = wx.PyEventBinder(EVT_RECT_CHANGED_TYPE, 1) class RectChangedEvent(wx.PyCommandEvent): def __init__(self, wxId, rect): wx.PyCommandEvent.__init__(self, EVT_RECT_CHANGED_TYPE, wxId) self._rect = rect self._checkImageDimensionLock = False def GetRect(self): return self._rect def SetCheckImageDimensionLock(self, value): self._checkImageDimensionLock = value def CheckImageDimensionLock(self): return self._checkImageDimensionLock class ImageSectionEditor(wx.Panel, Observer): BORDER_TOLERANCE = 20 POSITION_INSIDE = 0x01 POSITION_TOP = 0x10 POSITION_BOTTOM = 0x20 POSITION_LEFT = 0x40 POSITION_RIGHT = 0x80 INFO_TIME_OUT = 2.0 def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0, name='panel'): wx.Panel.__init__(self, parent, id, pos, size, style, name) Observer.__init__(self) self.SetSizeHints(200, 150) self.SetCursor(wx.Cursor(wx.CURSOR_ARROW)) self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM) self.RATIO = 16.0 / 9.0 self._imgProxy = None self._sectRect = wx.Rect(0, 0, 1280, 720) self._zoom = 1 self._infoTimer = wx.Timer(self) self._lastRectUpdate = 0 self._action = None self._startX = None self._startY = None self._startRect = None self._lock = True self.Bind(wx.EVT_PAINT, self.OnPaint) self.Bind(wx.EVT_MOTION, self.OnMotion) self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown) self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp) self.Bind(wx.EVT_SIZE, self.OnResize) self.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_TIMER, self.OnInfoTimer) self.Bind(wx.EVT_MOUSE_CAPTURE_LOST, self.OnCaptureLost) def ObservableUpdate(self, obj, arg): self.__Scale() self.__KeepRectInImage() self.Refresh() def SetAspect(self, aspect): self.RATIO = Aspect.ToFloat(aspect) self.__KeepRectInImage() self.Refresh() def SetImgProxy(self, imgProxy): self._imgProxy = imgProxy def __Scale(self): if not self._imgProxy.IsOk(): return cw, ch = self.GetClientSize().Get() iw, ih = self._imgProxy.GetSize() rx = cw / iw ry = ch / ih newWidth = cw newHeight = ih * rx self._zoom = rx if newHeight > ch: newHeight = ch newWidth = iw * ry self._zoom = ry self._imgProxy.Scale(newWidth, newHeight) def __DrawBitmap(self, dc): if self._imgProxy.IsOk(): left, top = self.__GetBmpTopLeft() dc.DrawBitmap(self._imgProxy.GetBitmap(), left, top) def __GetBmpTopLeft(self): if not self._imgProxy.IsOk(): return 0, 0 cw, ch = self.GetClientSize().Get() iw, ih = self._imgProxy.GetCurrentSize() left = (cw - iw) / 2.0 top = (ch - ih) / 2.0 return int(round(left)), int(round(top)) def __SectRectToClientRect(self): left, top = self.__GetBmpTopLeft() sectRect = wx.Rect(left + (self._sectRect.GetLeft() * self._zoom), top + (self._sectRect.GetTop() * self._zoom), self._sectRect.GetWidth() * self._zoom, self._sectRect.GetHeight() * self._zoom) return sectRect def __DrawSection(self, dc): if not self._imgProxy.IsOk(): return sectRect = self.__SectRectToClientRect() dc.SetBrush(wx.TRANSPARENT_BRUSH) iRect = wx.Rect(sectRect.GetPosition(), sectRect.GetSize()) dc.SetPen(wx.WHITE_PEN) iRect.Inflate(1, 1) dc.DrawRectangle(iRect) # draw background color = wx.Colour(0, 0, 0, 153) dc.SetBrush(wx.Brush(color)) dc.SetPen(wx.TRANSPARENT_PEN) # wx.Pen(color)) # left left, top = self.__GetBmpTopLeft() bmpWidth, bmpHeight = self._imgProxy.GetCurrentSize() dc.DrawRectangle(left, top, iRect.x - left, bmpHeight) lWidth = left + bmpWidth - iRect.GetWidth() - iRect.x left = iRect.x + iRect.GetWidth() dc.DrawRectangle(left, top, lWidth, bmpHeight) dc.DrawRectangle(iRect.x, top, iRect.GetWidth(), iRect.y - top) dc.DrawRectangle(iRect.x, iRect.y + iRect.GetHeight(), iRect.GetWidth(), top + bmpHeight - iRect.GetHeight() - iRect.y) now = time.time() alpha = 255 if now - self._lastRectUpdate > self.INFO_TIME_OUT // 2: alpha = (1 - ((now - self._lastRectUpdate) - (self.INFO_TIME_OUT // 2)) / (self.INFO_TIME_OUT // 2)) * 255 alpha = int(round(alpha)) if alpha < 0: alpha = 0 dc.SetTextForeground(wx.Colour(255, 255, 255, alpha)) font = wx.SystemSettings.GetFont(wx.SYS_SYSTEM_FONT) font.SetPointSize(16) font.SetWeight(wx.BOLD) dc.SetFont(font) dc.SetPen(wx.WHITE_PEN) dc.SetBrush(wx.TRANSPARENT_BRUSH) dc.DrawRectangle(sectRect) dc.DrawLabel("%d, %d - %d x %d" % tuple(self._sectRect), sectRect, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL) def OnPaint(self, event): sz = self.GetClientSize() pdc = wx.BufferedPaintDC(self) try: dc = wx.GCDC(pdc) except Exception: dc = pdc isModalDialogShown = False for win in wx.GetTopLevelWindows(): if isinstance(win, wx.Dialog) and win.IsModal(): isModalDialogShown = True break dc.SetBrush(wx.BLACK_BRUSH) dc.DrawRectangle(0, 0, sz[0], sz[1]) if not self.IsEnabled() and not isModalDialogShown: # a modal dialog set this window to disabled (not enabled), but # this windows is set to disabled if no selection can # be made (multiple selected images) # this rectangle should only be drawn if this windows is set to # disabled programmatically and not when a modal dialog is shown dc.SetBrush(wx.Brush(wx.Colour(90, 90, 90, 255), wx.HORIZONTAL_HATCH)) dc.DrawRectangle(0, 0, sz[0], sz[1]) elif self._imgProxy is not None: self.__DrawBitmap(dc) self.__DrawSection(dc) event.Skip() def __UpdateSectRect(self): self._lastRectUpdate = time.time() if not self._infoTimer.IsRunning(): self._infoTimer.Start(50) self.Refresh() def OnInfoTimer(self, event): if (time.time() - self._lastRectUpdate) > self.INFO_TIME_OUT: self._infoTimer.Stop() # iRect = self.__SectRectToClientRect() # iRect.Inflate((220 - iRect.GetWidth()) / 2, (50 - iRect.GetHeight()) / 2) # self.RefreshRect(iRect) self.Refresh() event.Skip() def __ClientToImage(self, px, py): bmpLeft, bmpTop = self.__GetBmpTopLeft() nx = (px - bmpLeft) / self._zoom ny = (py - bmpTop) / self._zoom return nx, ny def __FindPosition(self, cpx, cpy): tlx, tly = self._sectRect.GetTopLeft().Get() brx, bry = self._sectRect.GetBottomRight().Get() # first Check the Corners # topleft if abs(cpx - tlx) < self.BORDER_TOLERANCE and abs(cpy - tly) < self.BORDER_TOLERANCE: return self.POSITION_TOP | self.POSITION_LEFT # topright elif abs(cpx - brx) < self.BORDER_TOLERANCE and abs(cpy - tly) < self.BORDER_TOLERANCE: return self.POSITION_TOP | self.POSITION_RIGHT # bottom left elif abs(cpx - tlx) < self.BORDER_TOLERANCE and abs(cpy - bry) < self.BORDER_TOLERANCE: return self.POSITION_BOTTOM | self.POSITION_LEFT # bottom right elif abs(cpx - brx) < self.BORDER_TOLERANCE and abs(cpy - bry) < self.BORDER_TOLERANCE: return self.POSITION_BOTTOM | self.POSITION_RIGHT # then the Borders # left elif abs(cpx - tlx) < self.BORDER_TOLERANCE and (tly < cpy < bry): return self.POSITION_LEFT # right elif abs(cpx - brx) < self.BORDER_TOLERANCE and (tly < cpy < bry): return self.POSITION_RIGHT # top elif abs(cpy - tly) < self.BORDER_TOLERANCE and (tlx < cpx < brx): return self.POSITION_TOP # bottom elif abs(cpy - bry) < self.BORDER_TOLERANCE and (tlx < cpx < brx): return self.POSITION_BOTTOM elif self._sectRect.Contains(cpx, cpy): return self.POSITION_INSIDE else: return None def __SelectCursor(self, position): # the cornsers if position == self.POSITION_TOP | self.POSITION_LEFT: self.SetCursor(cursors.GetNW()) elif position == self.POSITION_BOTTOM | self.POSITION_RIGHT: self.SetCursor(cursors.GetSE()) elif position == self.POSITION_BOTTOM | self.POSITION_LEFT: self.SetCursor(cursors.GetSW()) elif position == self.POSITION_TOP | self.POSITION_RIGHT: self.SetCursor(cursors.GetNE()) # the Borders elif position in [self.POSITION_LEFT, self.POSITION_RIGHT]: self.SetCursor(wx.Cursor(wx.CURSOR_SIZEWE)) elif position in [self.POSITION_TOP, self.POSITION_BOTTOM]: self.SetCursor(wx.Cursor(wx.CURSOR_SIZENS)) elif position == self.POSITION_INSIDE: self.SetCursor(wx.Cursor(wx.CURSOR_SIZING)) else: self.SetCursor(wx.Cursor(wx.CURSOR_ARROW)) def OnCaptureLost(self, event): # pylint: disable=unused-argument if self._action is not None: self.__SelectCursor(None) self._action = None self._startX = None self._startY = None def OnLeftDown(self, event): if not self._imgProxy.IsOk(): return px, py = event.GetPosition().Get() cpx, cpy = self.__ClientToImage(px, py) self._action = self.__FindPosition(cpx, cpy) if self._action is not None: self.CaptureMouse() self._startX = cpx self._startY = cpy self._startRect = wx.Rect(*self._sectRect.Get()) event.Skip() def OnMotion(self, event): if not self._imgProxy.IsOk(): return px, py = event.GetPosition().Get() cpx, cpy = self.__ClientToImage(px, py) if self._action is None: position = self.__FindPosition(cpx, cpy) self.__SelectCursor(position) else: if self._action == self.POSITION_INSIDE: deltaX = cpx - self._startX deltaY = cpy - self._startY self._sectRect.SetX(self._startRect.GetX() + deltaX) self._sectRect.SetY(self._startRect.GetY() + deltaY) else: # calculate dx aka delta x if self._action & self.POSITION_LEFT: dx = self._startX - cpx elif self._action & self.POSITION_RIGHT: dx = cpx - self._startX else: dx = None # calculate dy aka delta y if self._action & self.POSITION_TOP: dy = self._startY - cpy elif self._action & self.POSITION_BOTTOM: dy = cpy - self._startY else: dy = None # choose which one to use if dy is None or (dx is not None and dx > dy * self.RATIO): width = self._startRect.GetWidth() + dx height = width / self.RATIO dy = dx / self.RATIO else: height = self._startRect.GetHeight() + dy width = height * self.RATIO dx = dy * self.RATIO # check size recalcDelta = False if width < 100: width = 100 height = width / self.RATIO recalcDelta = True else: if width > self._imgProxy.GetWidth() and self._lock: width = self._imgProxy.GetWidth() height = width / self.RATIO recalcDelta = True if height > self._imgProxy.GetHeight() and self._lock: height = self._imgProxy.GetHeight() width = height * self.RATIO recalcDelta = True if recalcDelta: dx = width - self._startRect.GetWidth() dy = height - self._startRect.GetHeight() # now that we have the width and height, find out the position sx = self._startRect.GetX() sy = self._startRect.GetY() # we need an algorithm for this if self._action == self.POSITION_TOP | self.POSITION_LEFT: nx = sx - dx ny = sy - dy elif self._action == self.POSITION_TOP | self.POSITION_RIGHT: nx = sx ny = sy - dy elif self._action == self.POSITION_BOTTOM | self.POSITION_RIGHT: nx = sx ny = sy elif self._action == self.POSITION_BOTTOM | self.POSITION_LEFT: nx = sx - dx ny = sy elif self._action == self.POSITION_LEFT: nx = sx - dx ny = sy - dy / 2 elif self._action == self.POSITION_RIGHT: nx = sx ny = sy - dy / 2 elif self._action == self.POSITION_TOP: nx = sx - dx / 2 ny = sy - dy elif self._action == self.POSITION_BOTTOM: nx = sx - dx / 2 ny = sy # check pos if self._lock: if nx < 0: nx = 0 elif nx + width > self._imgProxy.GetWidth(): nx = self._imgProxy.GetWidth() - width if ny < 0: ny = 0 elif ny + height > self._imgProxy.GetHeight(): ny = self._imgProxy.GetHeight() # everything should be ok now self._sectRect.SetX(nx) self._sectRect.SetY(ny) self._sectRect.SetWidth(width) self._sectRect.SetHeight(height) # self._SendRectChangedEvent() self.__UpdateSectRect() def OnLeftUp(self, event): if self._action is not None: px, py = event.GetPosition().Get() cpx, cpy = self.__ClientToImage(px, py) position = self.__FindPosition(cpx, cpy) self.__SelectCursor(position) if self.HasCapture(): self.ReleaseMouse() self._action = None self._startX = None self._startY = None event.Skip() def _SendRectChangedEvent(self, checkImageDimensionLock=False): if not self._imgProxy.IsOk(): return self.__KeepRectInImage() evt = RectChangedEvent(self.GetId(), self._sectRect) evt.SetCheckImageDimensionLock(checkImageDimensionLock) evt.SetEventObject(self) self.GetEventHandler().ProcessEvent(evt) def OnMouseWheel(self, event): rotation = event.GetWheelRotation() step = 20 if rotation > 0: self._sectRect.Inflate(step, int(round(step / self.RATIO))) else: self._sectRect.Inflate(-step, -int(round(step / self.RATIO))) self._SendRectChangedEvent() self.__UpdateSectRect() def OnResize(self, event): if self._imgProxy is not None: self.__Scale() self.Refresh() event.Skip() def OnKeyDown(self, event): key = event.GetKeyCode() step = 20 if key == wx.WXK_NUMPAD_ADD: self._sectRect.Inflate(step, int(round(step / self.RATIO))) elif key == wx.WXK_NUMPAD_SUBTRACT: self._sectRect.Inflate(-step, -int(round(step / self.RATIO))) elif key == wx.WXK_NUMPAD_DIVIDE: width = 1280 self._sectRect.SetWidth(width) self._sectRect.SetHeight(int(round(width / self.RATIO))) elif key == wx.WXK_NUMPAD_MULTIPLY: self._sectRect = wx.Rect(0, 0, self._imgProxy.GetWidth(), int(round(self._imgProxy.GetWidth() / self.RATIO))) elif key == wx.WXK_LEFT: if event.ShiftDown(): self._sectRect.Offset(-50, 0) else: self._sectRect.Offset(-10, 0) elif key == wx.WXK_UP: if event.ShiftDown(): self._sectRect.Offset(0, -50) else: self._sectRect.Offset(0, -10) elif key == wx.WXK_RIGHT: if event.ShiftDown(): self._sectRect.Offset(50, 0) else: self._sectRect.Offset(10, 0) elif key == wx.WXK_DOWN: if event.ShiftDown(): self._sectRect.Offset(0, 50) else: self._sectRect.Offset(0, 10) elif event.GetModifiers() == wx.MOD_CONTROL and key == ord('C'): self.OnCopy(event) elif event.GetModifiers() == wx.MOD_CONTROL and key == ord('V'): self.OnPaste(event) else: event.Skip() return self._SendRectChangedEvent() self.__UpdateSectRect() def __KeepRectInImage(self): if not self._imgProxy.IsOk(): return left = self._sectRect.GetLeft() top = self._sectRect.GetTop() width = self._sectRect.GetWidth() height = self._sectRect.GetHeight() if self._lock: if width > self._imgProxy.GetWidth(): width = self._imgProxy.GetWidth() height = int(round(width / self.RATIO)) if height > self._imgProxy.GetHeight(): height = self._imgProxy.GetHeight() width = int(round(height * self.RATIO)) if left < 0: left = 0 if left + width > self._imgProxy.GetWidth(): left = self._imgProxy.GetWidth() - width if top < 0: top = 0 if top + height > self._imgProxy.GetHeight(): top = self._imgProxy.GetHeight() - height self._sectRect = wx.Rect(left, top, width, height) def OnCopy(self, event): data = "%d, %d - %d x %d" % tuple(self._sectRect) if wx.TheClipboard.Open(): try: do = wx.TextDataObject() do.SetText(data) wx.TheClipboard.SetData(do) finally: wx.TheClipboard.Close() def OnPaste(self, event): if wx.TheClipboard.Open(): try: do = wx.TextDataObject() data = None if wx.TheClipboard.GetData(do): data = do.GetText() sectData = re.findall(r"([-]?\d+), ([-]?\d+) - (\d+) x (\d+)", data) if sectData: sectData = sectData[0] try: rect = wx.Rect(int(sectData[0]), int(sectData[1]), int(sectData[2]), int(sectData[3])) self._lock = False self.SetSection(rect) self._SendRectChangedEvent(checkImageDimensionLock=True) except ValueError: pass finally: wx.TheClipboard.Close() # ============================ def GetSection(self): return self._sectRect def SetSection(self, rect): self._sectRect = wx.Rect(rect.GetPosition(), rect.GetSize()) self.Refresh() def SetLock(self, lock): self._lock = lock class ScaleThread(threading.Thread): def __init__(self, picture, callbackOnDone): threading.Thread.__init__(self, name="reload %s" % picture.GetFilename()) self._picture = picture self._abort = False self._callbackOnDone = callbackOnDone def Abort(self): self._abort = True def run(self): self._abort = False for __ in range(20): time.sleep(0.1) if self._abort: return pilImg = PILBackend.GetImage(self._picture) wxImg = wx.Image(PILBackend.ImageToStream(pilImg), wx.BITMAP_TYPE_JPEG) if not self._abort: self._callbackOnDone(wxImg) class ImageProxy(Observable): def __init__(self): Observable.__init__(self) self._curThread = None self._picture = None self._wxImg = None self._wxBmp = None self._curSize = -1, -1 def Destroy(self): if self._curThread: self._curThread.Abort() self._curThread.join() def IsOk(self): return self._picture is not None def OnThreadDone(self, img): self._wxImg = img wx.CallAfter(self.Notify) def SetPicture(self, picture): self._picture = picture if self._picture is not None: self._wxImg = ImageCache().GetImage(picture) if self._curThread is not None: self._curThread.Abort() self._curThread = ScaleThread(picture, self.OnThreadDone) self._curThread.start() self.Notify() def GetWidth(self): return self._picture.GetWidth() def GetHeight(self): return self._picture.GetHeight() def GetSize(self): return self.GetWidth(), self.GetHeight() def Scale(self, width, height): if not (width > 0 and height > 0): return img = self._wxImg.Scale(width, height) self._wxBmp = img.ConvertToBitmap() self._curSize = width, height def GetCurrentSize(self): return self._curSize def GetBitmap(self): return self._wxBmp photofilmstrip-3.7.2/photofilmstrip/core/0000755000232200023220000000000013560357432021177 5ustar debalancedebalancephotofilmstrip-3.7.2/photofilmstrip/core/RenderJob.py0000644000232200023220000001371013560357351023425 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2017 Jens Goepfert # import logging import threading from photofilmstrip.ux.Ux import Ux from photofilmstrip.lib.jobimpl.VisualJob import VisualJob from photofilmstrip.lib.jobimpl.Worker import JobAbortedException from photofilmstrip.lib.jobimpl.WorkLoad import WorkLoad class RenderJob(VisualJob, Ux): def __init__(self, name, renderer, tasks): VisualJob.__init__(self, name, groupId="render") Ux.__init__(self) self.renderer = renderer self.tasks = tasks self.SetMaxProgress(len(tasks)) self.resultsForRendererLock = threading.Lock() self.resultForRendererIdx = 0 self.resultsForRendererCache = {} self.taskResultCache = {} self.finalizeHandler = self.renderer.GetFinalizeHandler() self.__logger = logging.getLogger("RenderJob") def GetOutputFile(self): return self.renderer.GetOutputFile() def Done(self): if self.IsAborted(): self.renderer.ProcessAbort() self.renderer.Finalize() self.__logger.debug("task cache: %s; result cache: %s", len(self.taskResultCache), len(self.resultsForRendererCache)) def Begin(self): # prepare task queue self.__logger.debug("%s: prepare task queue", self.GetName()) for idx, task in enumerate(self.tasks): for subTask in task.IterSubTasks(): self._RegisterTaskResult(subTask, True) self._RegisterTaskResult(task, False) prt = RendererResultTask(idx, task) self.AddWorkLoad(prt) # prepare the renderer, creates the sink pipe self.renderer.Prepare() def _RegisterTaskResult(self, task, isSubTask): if isSubTask: # no finalize for subtasks finalizeHandler = None else: finalizeHandler = self.finalizeHandler # make sure that a real sub task is not processed from FinalizeHandler # so generate a special key for subtasks key = "{0}{1}".format(task.GetKey(), isSubTask) if key in self.taskResultCache: trce = self.taskResultCache[key] isNew = False else: trce = TaskResultCacheEntry(task, self, finalizeHandler) self.taskResultCache[key] = trce isNew = True trce.refCount += 1 return isNew def GetWorkLoad(self): task = VisualJob.GetWorkLoad(self) self.SetInfo(task.GetInfo()) self.__logger.debug("%s: %s: %s - start", threading.current_thread().getName(), self.GetName(), task.GetKey()) return task def PushResult(self, resultObject): ''' overrides IJobContext.PushResult ''' task = resultObject.GetSource() self.__logger.debug("%s: %s: %s - done", threading.current_thread().getName(), self.GetName(), task.GetKey()) try: result = resultObject.GetResult() self.resultsForRendererCache[task.idx] = result except JobAbortedException: pass with self.resultsForRendererLock: while self.resultForRendererIdx in self.resultsForRendererCache: idx = self.resultForRendererIdx self.__logger.debug("%s: %s: resultToFetch: %s", threading.current_thread().getName(), self.GetName(), idx) imgData = self.resultsForRendererCache[idx] if imgData: self.renderer.ToSink(imgData) del self.resultsForRendererCache[idx] self.resultForRendererIdx += 1 self.StepProgress() def ProcessSubTask(self, task, isSubTask=True): key = "{0}{1}".format(task.GetKey(), isSubTask) trce = self.taskResultCache[key] result = trce.GetResult() if trce.refCount == 0: self.__logger.debug("%s: %s: clear cached result %s", threading.current_thread().getName(), self.GetName(), key) del self.taskResultCache[key] else: self.__logger.debug("%s: %s: result ref count %s %s", threading.current_thread().getName(), self.GetName(), trce.refCount, key) return result class RendererResultTask(WorkLoad): ''' its more like a dummy task just to assure the correct reference counting of task results especially concerning sub tasks. ''' def __init__(self, idx, task): WorkLoad.__init__(self) self.idx = idx self.task = task def GetKey(self): return self.idx def Run(self, jobContext): # self.task is not really a sub task, but is processed as a sub task to # use the result cache return jobContext.ProcessSubTask(self.task, False) def GetInfo(self): return self.task.GetInfo() class TaskResultCacheEntry: NO_RESULT = object() def __init__(self, task, renderJob, finalizeHandler): self.task = task self.renderJob = renderJob self.finalizeHandler = finalizeHandler self.refCount = 0 self.result = TaskResultCacheEntry.NO_RESULT self.lock = threading.Lock() def SetResult(self, result): assert self.result is TaskResultCacheEntry.NO_RESULT self.result = result def GetResult(self): with self.lock: if self.result is TaskResultCacheEntry.NO_RESULT: self.result = self.task.Run(self.renderJob) if self.finalizeHandler and self.result: self.result = self.finalizeHandler.ProcessFinalize(self.result) self.refCount -= 1 return self.result photofilmstrip-3.7.2/photofilmstrip/core/__init__.py0000644000232200023220000000017113560357351023307 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # photofilmstrip-3.7.2/photofilmstrip/core/Aspect.py0000644000232200023220000000071113560357351022767 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2010 Jens Goepfert # class Aspect: ASPECT_4_3 = "4:3" ASPECT_3_2 = "3:2" ASPECT_16_9 = "16:9" @classmethod def ToFloat(cls, aspect): if aspect == cls.ASPECT_16_9: return 16.0 / 9.0 if aspect == cls.ASPECT_4_3: return 4.0 / 3.0 if aspect == cls.ASPECT_3_2: return 3.0 / 2.0 photofilmstrip-3.7.2/photofilmstrip/core/GPlayer.py0000644000232200023220000001052313560357351023115 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2014 Jens Goepfert # import logging import threading import time from gi.repository import Gst from gi.repository import GObject class GPlayer: def __init__(self, filename): self.__filename = filename self.__pipeline = None self.__length = None self.__gtkMainloop = None self.__position = None self.__Identify() def __Identify(self): pipeline = Gst.Pipeline() fileSrc = Gst.ElementFactory.make("filesrc") fileSrc.set_property("location", self.__filename) audioDec = Gst.ElementFactory.make("decodebin") audioConv = Gst.ElementFactory.make("audioconvert") audioSink = Gst.ElementFactory.make("fakesink") pipeline.add(fileSrc) pipeline.add(audioDec) pipeline.add(audioConv) pipeline.add(audioSink) fileSrc.link(audioDec) audioConv.link(audioSink) audioDec.connect("pad-added", self._GstPadAdded, audioConv) pipeline.set_state(Gst.State.PLAYING) hasResult = False while not hasResult: msg = pipeline.get_bus().pop() if msg is None: time.sleep(0.001) continue hasResult, duration = pipeline.query_duration(Gst.Format.TIME) pipeline.set_state(Gst.State.NULL) self.__length = duration // Gst.MSECOND def GetFilename(self): return self.__filename def IsOk(self): return self.__length is not None def IsPlaying(self): return self.__pipeline is not None def Play(self): if self.__pipeline is None: pipeline = Gst.Pipeline() fileSrc = Gst.ElementFactory.make("filesrc") fileSrc.set_property("location", self.__filename) audioDec = Gst.ElementFactory.make("decodebin") audioConv = Gst.ElementFactory.make("audioconvert") audioSink = Gst.ElementFactory.make("autoaudiosink") pipeline.add(fileSrc) pipeline.add(audioDec) pipeline.add(audioConv) pipeline.add(audioSink) fileSrc.link(audioDec) audioConv.link(audioSink) audioDec.connect("pad-added", self._GstPadAdded, audioConv) self.__pipeline = pipeline self.__pipeline.set_state(Gst.State.PLAYING) bus = self.__pipeline.get_bus() bus.add_signal_watch() bus.connect("message", self._GstOnMessage) gtkMainloopThread = threading.Thread(name="gtkMainLoop", target=self._GtkMainloop) gtkMainloopThread.start() def Stop(self): self.Close() def Close(self): self.__pipeline.send_event(Gst.Event.new_eos()) def GetLength(self): return self.__length def GetPosition(self): if self.__pipeline: hasResult, position = self.__pipeline.query_position(Gst.Format.TIME) if hasResult: return position // Gst.MSECOND def SetPosition(self, start): if self.__pipeline: nanoSecs = start * Gst.MSECOND self.__pipeline.seek(1.0, Gst.Format.TIME, Gst.SeekFlags.FLUSH, Gst.SeekType.SET, nanoSecs, Gst.SeekType.NONE, 0) def _GstOnMessage(self, bus, msg): # pylint: disable=unused-argument logging.debug('_GstOnMessage: %s', msg.type) if msg.type == Gst.MessageType.ERROR: err, debug = msg.parse_error() logging.error("Error received from element %s: %s", msg.src.get_name(), err) logging.debug("Debugging information: %s", debug) elif msg.type == Gst.MessageType.EOS: self.__pipeline.set_state(Gst.State.NULL) self.__gtkMainloop.quit() self.__pipeline = None self.__gtkMainloop = None def _GstPadAdded(self, decodebin, pad, audioConv): # pylint: disable=unused-argument caps = pad.get_current_caps() compatible_pad = audioConv.get_compatible_pad(pad, caps) pad.link(compatible_pad) def _GtkMainloop(self): GObject.threads_init() self.__gtkMainloop = GObject.MainLoop() self.__gtkMainloop.run() photofilmstrip-3.7.2/photofilmstrip/core/Project.py0000644000232200023220000000450113560357351023157 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # import os from photofilmstrip.lib.common.ObserverPattern import Observable from photofilmstrip.core.Aspect import Aspect class Project(Observable): def __init__(self, filename=None): Observable.__init__(self) self.__pictures = [] self.__filename = filename self.__audioFiles = [] self.__aspect = Aspect.ASPECT_16_9 self.__duration = None self.__timelapse = False def GetName(self): if self.__filename is None: return u"" fname = os.path.splitext(self.__filename)[0] return os.path.basename(fname) def GetFilename(self): return self.__filename def SetFilename(self, filename): self.__filename = filename def GetPictures(self): return self.__pictures def SetPictures(self, picList): oldDuration = self.GetDuration() self.__pictures = picList self.Notify("pictures") if self.GetDuration() != oldDuration: self.Notify("duration") def SetAudioFiles(self, audioFiles): self.__audioFiles = audioFiles self.Notify("audiofile") def GetAudioFile(self): ''' compatibility ''' if self.__audioFiles: return self.__audioFiles[0] else: return None def GetAudioFiles(self): return self.__audioFiles def SetAspect(self, aspect): if aspect == self.__aspect: return self.__aspect = aspect self.Notify("aspect") def GetAspect(self): return self.__aspect def SetDuration(self, duration): if duration == self.__duration: return self.__duration = duration self.Notify("duration") def GetDuration(self, calc=True): if calc: totalTime = 0 for pic in self.__pictures: totalTime += pic.GetDuration() + pic.GetTransitionDuration() else: totalTime = self.__duration return totalTime def SetTimelapse(self, value): if value == self.__timelapse: return self.__timelapse = value self.Notify("timelapse") def GetTimelapse(self): return self.__timelapse photofilmstrip-3.7.2/photofilmstrip/core/OutputProfile.py0000644000232200023220000002130213560357351024370 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2010 Jens Goepfert # from photofilmstrip.core.Aspect import Aspect class FrameRate: def __init__(self, numValue, strValue): self.num = numValue self.str = strValue def __str__(self, *args, **kwargs): return u"%.2f fps" % self.num def AsFloat(self): return self.num def AsStr(self): return self.str class OutputProfile: PAL = 1 NTSC = 2 def __init__(self, name, resolution, frameRate, bitrate, videoNorm=None): self.__name = name self.__resolution = resolution self.__frameRate = frameRate self.__bitrate = bitrate self.__videoNorm = videoNorm self.__friendlyName = None def GetName(self, withRes=False): if self.__videoNorm: simple = self.__name else: simple = "{0}@{1}".format(self.__name, self.__frameRate) if withRes: return "%s (%dx%d)" % (simple, self.GetResolution()[0], self.GetResolution()[1]) else: return simple def GetBitrate(self): return self.__bitrate def GetResolution(self): return self.__resolution def GetFrameRate(self): return self.__frameRate def GetVideoNorm(self): return self.__videoNorm def IsMPEGProfile(self): for mpegProf in ("VCD", "SVCD", "DVD"): if self.__name.startswith(mpegProf): return True return False def SetFriendlyName(self, value): self.__friendlyName = value def GetFriendlyName(self): return self.__friendlyName FPS15 = FrameRate(15.0, "15/1") FPS23996 = FrameRate(24000.0 / 1001.0, "24000/1001") FPS24 = FrameRate(24.0, "24/1") FPS25 = FrameRate(25.0, "25/1") FPS29997 = FrameRate(30000.0 / 1001.0, "30000/1001") FPS30 = FrameRate(30.0, "30/1") FPS50 = FrameRate(50.0, "50/1") FPS59994 = FrameRate(60000.0 / 1001.0, "60000/1001") FPS60 = FrameRate(60.0, "60/1") def __CreateMPEGProfiles(): vcd_pal = OutputProfile("VCD-PAL", (352, 288), FPS25, 1150, OutputProfile.PAL) vcd_ntsc = OutputProfile("VCD-NTSC", (352, 240), FPS29997, 1150, OutputProfile.NTSC) svcd_pal = OutputProfile("SVCD-PAL", (480, 576), FPS25, 2500, OutputProfile.PAL) svcd_ntsc = OutputProfile("SVCD-NTSC", (480, 576), FPS29997, 2500, OutputProfile.NTSC) dvd_pal = OutputProfile("DVD-PAL", (720, 576), FPS25, 8000, OutputProfile.PAL) dvd_ntsc = OutputProfile("DVD-NTSC", (720, 480), FPS29997, 8000, OutputProfile.NTSC) result = [vcd_pal, vcd_ntsc, svcd_pal, svcd_ntsc, dvd_pal, dvd_ntsc] for prof in result: prof.SetFriendlyName(prof.GetName()) return result def __Create16_9Profiles(): profs = [] # 360p for fps in [FPS23996, FPS25]: prof = OutputProfile("360p", (640, 360), fps, 1000) if fps is FPS25: prof.SetFriendlyName("Medium") profs.append(prof) for fps in [FPS29997, FPS30, FPS50, FPS59994, FPS60]: prof = OutputProfile("360p", (640, 360), fps, 1500) profs.append(prof) # 480p for fps in [FPS24, FPS30]: prof = OutputProfile("480p", (854, 480), fps, 2500) profs.append(prof) for fps in [FPS50, FPS60]: prof = OutputProfile("480p", (854, 480), fps, 4000) profs.append(prof) # 720p for fps in [FPS23996, FPS24, FPS25]: prof = OutputProfile("HD 720p", (1280, 720), fps, 5000) if fps is FPS25: prof.SetFriendlyName("HD") profs.append(prof) for fps in [FPS29997, FPS30, FPS50, FPS59994, FPS60]: prof = OutputProfile("HD 720p", (1280, 720), fps, 7500) profs.append(prof) # 1080p for fps in [FPS23996, FPS24, FPS25]: prof = OutputProfile("HD 1080p", (1920, 1080), fps, 8000) if fps is FPS25: prof.SetFriendlyName("FULL-HD") profs.append(prof) for fps in [FPS29997, FPS30, FPS50, FPS60]: prof = OutputProfile("HD 1080p", (1920, 1080), fps, 12000) profs.append(prof) # 2160p for fps in [FPS23996, FPS24, FPS25]: prof = OutputProfile("UHD-1 2160p", (3840, 2160), fps, 25000) if fps is FPS25: prof.SetFriendlyName("UHD") profs.append(prof) for fps in [FPS29997, FPS30, FPS50, FPS60]: prof = OutputProfile("UHD-1 2160p", (3840, 2160), fps, 50000) profs.append(prof) # 4320p for fps in [FPS25, FPS30, FPS50, FPS60]: prof = OutputProfile("UHD-2 4320p", (7680, 4320), fps, 60000) profs.append(prof) return profs def __Create4_3Profiles(): profs = [] # 360p for fps in [FPS23996, FPS25]: prof = OutputProfile("360p", (480, 360), fps, 1000) if fps is FPS25: prof.SetFriendlyName("Medium") profs.append(prof) for fps in [FPS29997, FPS30, FPS50, FPS59994, FPS60]: prof = OutputProfile("360p", (480, 360), fps, 1500) profs.append(prof) # 480p for fps in [FPS24, FPS30]: prof = OutputProfile("480p", (640, 480), fps, 2500) profs.append(prof) for fps in [FPS50, FPS60]: prof = OutputProfile("480p", (640, 480), fps, 4000) profs.append(prof) # 720p for fps in [FPS23996, FPS24, FPS25]: prof = OutputProfile("HD 720p", (960, 720), fps, 5000) if fps is FPS25: prof.SetFriendlyName("HD") profs.append(prof) for fps in [FPS29997, FPS30, FPS50, FPS59994, FPS60]: prof = OutputProfile("HD 720p", (960, 720), fps, 7500) profs.append(prof) # 1080p for fps in [FPS23996, FPS24, FPS25]: prof = OutputProfile("HD 1080p", (1440, 1080), fps, 8000) if fps is FPS25: prof.SetFriendlyName("FULL-HD") profs.append(prof) for fps in [FPS29997, FPS30, FPS50, FPS60]: prof = OutputProfile("HD 1080p", (1440, 1080), fps, 12000) profs.append(prof) # 2160p for fps in [FPS23996, FPS24, FPS25]: prof = OutputProfile("UHD-1 2160p", (2880, 2160), fps, 25000) if fps is FPS25: prof.SetFriendlyName("UHD") profs.append(prof) for fps in [FPS29997, FPS30, FPS50, FPS60]: prof = OutputProfile("UHD-1 2160p", (2880, 2160), fps, 50000) profs.append(prof) # 4320p for fps in [FPS25, FPS30, FPS50, FPS60]: prof = OutputProfile("UHD-2 4320p", (5760, 4320), fps, 60000) profs.append(prof) return profs def __Create3_2Profiles(): profs = [] # 360p for fps in [FPS23996, FPS25]: prof = OutputProfile("360p", (540, 360), fps, 1000) if fps is FPS25: prof.SetFriendlyName("Medium") profs.append(prof) for fps in [FPS29997, FPS30, FPS50, FPS59994, FPS60]: prof = OutputProfile("360p", (540, 360), fps, 1500) profs.append(prof) # 480p for fps in [FPS24, FPS30]: prof = OutputProfile("480p", (720, 480), fps, 2500) profs.append(prof) for fps in [FPS50, FPS60]: prof = OutputProfile("480p", (720, 480), fps, 4000) profs.append(prof) # 720p for fps in [FPS23996, FPS24, FPS25]: prof = OutputProfile("HD 720p", (1080, 720), fps, 5000) if fps is FPS25: prof.SetFriendlyName("HD") profs.append(prof) for fps in [FPS29997, FPS30, FPS50, FPS59994, FPS60]: prof = OutputProfile("HD 720p", (1080, 720), fps, 7500) profs.append(prof) # 1080p for fps in [FPS23996, FPS24, FPS25]: prof = OutputProfile("HD 1080p", (1620, 1080), fps, 8000) if fps is FPS25: prof.SetFriendlyName("FULL-HD") profs.append(prof) for fps in [FPS29997, FPS30, FPS50, FPS60]: prof = OutputProfile("HD 1080p", (1620, 1080), fps, 12000) profs.append(prof) # 2160p for fps in [FPS23996, FPS24, FPS25]: prof = OutputProfile("UHD-1 2160p", (3240, 2160), fps, 25000) if fps is FPS25: prof.SetFriendlyName("UHD") profs.append(prof) for fps in [FPS29997, FPS30, FPS50, FPS60]: prof = OutputProfile("UHD-1 2160p", (3240, 2160), fps, 50000) profs.append(prof) # 4320p for fps in [FPS25, FPS30, FPS50, FPS60]: prof = OutputProfile("UHD-2 4320p", (6480, 4320), fps, 60000) profs.append(prof) return profs def GetOutputProfiles(aspect=Aspect.ASPECT_16_9): if aspect == Aspect.ASPECT_4_3: return __Create4_3Profiles() elif aspect == Aspect.ASPECT_3_2: return __Create3_2Profiles() else: return __Create16_9Profiles() def GetMPEGProfiles(): return __CreateMPEGProfiles() photofilmstrip-3.7.2/photofilmstrip/core/AudioPlayer.py0000644000232200023220000000030013560357351023760 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2014 Jens Goepfert # from photofilmstrip.core.GPlayer import GPlayer AudioPlayer = GPlayer photofilmstrip-3.7.2/photofilmstrip/core/RenderEngine.py0000644000232200023220000002474413560357351024131 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2011 Jens Goepfert # import os from photofilmstrip.core.tasks import TaskCropResize, TaskTrans, TaskSubtitle from photofilmstrip.core.Picture import Picture from photofilmstrip.core.PicturePattern import PicturePattern from photofilmstrip.core.exceptions import RenderException class RenderEngine: def __init__(self, profile, pics, draftMode): self._profile = profile self._pics = pics self._draftMode = draftMode self._tasks = [] def _PrepareTasks(self, pics): raise NotImplementedError() def GetTasks(self): self._PrepareTasks(self._pics) return self._tasks class RenderEngineSlideshow(RenderEngine): def __init__(self, profile, pics, draftMode, totalLength): RenderEngine.__init__(self, profile, pics, draftMode) self.__targetLengthSecs = totalLength self.__picCountFactor = None def __GetPicCountFactor(self, pics): if self.__targetLengthSecs is None: result = 1.0 else: # targetLength should be at least 1sec for each pic targetLengthSecs = max(self.__targetLengthSecs, len(pics)) totalSecs = 0 for idxPic, pic in enumerate(pics): totalSecs += pic.GetDuration() if idxPic < (len(pics) - 1): totalSecs += pic.GetTransitionDuration() result = targetLengthSecs / totalSecs return result def __GetPicCount(self, pic): """ returns the number of pictures """ fr = self._profile.GetFrameRate().AsFloat() return int(round(pic.GetDuration() * \ fr * \ self.__picCountFactor)) def __GetTransCount(self, pic): """ returns the number of pictures needed for the transition """ fr = self._profile.GetFrameRate().AsFloat() return int(round(pic.GetTransitionDuration() * \ fr * \ self.__picCountFactor)) def __TransAndFinal(self, infoText, trans, picFrom, picTo, pathRectsFrom, pathRectsTo): if len(pathRectsFrom) != len(pathRectsTo): raise RuntimeError() count = len(pathRectsFrom) for idx in range(count): task = TaskTrans(trans, idx / count, picFrom.Copy(), pathRectsFrom[idx], picTo.Copy(), pathRectsTo[idx], self._profile.GetResolution()) task.SetInfo(infoText) task.SetDraft(self._draftMode) self._tasks.append(task) return True def _PrepareTasks(self, pics): self.__picCountFactor = self.__GetPicCountFactor(pics) taskSub = TaskSubtitle(self.__picCountFactor, pics) self._tasks.append(taskSub) pathRectsBefore = [] picBefore = None transCountBefore = 0 for idxPic, pic in enumerate(pics): picCount = self.__GetPicCount(pic) transCount = 0 if idxPic < (len(pics) - 1): # last pic has no transition transCount = self.__GetTransCount(pic) cp = ComputePath(pic, picCount + transCount + transCountBefore) pathRects = cp.GetPathRects() if idxPic > 0 and idxPic < len(pics): # first and last pic has no transition infoText = _(u"processing transition %d/%d") % (idxPic + 1, len(pics)) if transCountBefore > 0: phase2a = pathRectsBefore[-transCountBefore:] phase2b = pathRects[:transCountBefore] if not self.__TransAndFinal(infoText, pics[idxPic - 1].GetTransition(), picBefore, pic, phase2a, phase2b): break infoText = _(u"processing image %d/%d") % (idxPic + 1, len(pics)) if transCount > 0: # transition needs pictures, subtract them from movement _pathRects = pathRects[transCountBefore:-transCount] else: # transition needs no pictures, use them all for movement _pathRects = pathRects[transCountBefore:] for rect in _pathRects: task = TaskCropResize(pic.Copy(), rect, self._profile.GetResolution()) task.SetInfo(infoText) task.SetDraft(self._draftMode) self._tasks.append(task) picBefore = pic pathRectsBefore = pathRects transCountBefore = transCount class RenderEngineTimelapse(RenderEngine): def _PrepareTasks(self, pics): picBefore = None picNum = None idxPic = 0 while idxPic < len(pics) - 1: pic = pics[idxPic] picPattern = PicturePattern.Create(pic.GetFilename()) if not picPattern.IsOk(): raise RenderException( (u"Filename '%s' does not match a number pattern " u"which is necessary for a time lapse " u"slide show!") % pic.GetFilename()) picNum = picPattern.num picDur = int(pic.GetDuration()) transDur = int(pic.GetTransitionDuration()) # get number from next pic nextPic = pics[idxPic + 1] nextPicPattern = PicturePattern.Create(nextPic.GetFilename()) if not nextPicPattern.IsOk(): idxPic += 1 continue picCount = nextPicPattern.num - picNum if picCount < 0: raise RenderException( (u"The picture counter is not " u"increasing: %s") % nextPic.GetFilename()) if idxPic + 1 == len(pics) - 1: # next pic is the last one so incluse the last pic cp = ComputePath(pic, (picDur * (picCount + 1)) + (transDur * picCount)) else: cp = ComputePath(pic, (picDur + transDur) * picCount) pathRects = cp.GetPathRects() picDir = os.path.dirname(pic.GetFilename()) idxRect = 0 while idxRect < len(pathRects): picCopy = pic.Copy() picCopy._filename = os.path.join( picDir, "{0}{1}{2}".format(picPattern.prefix, ("%%0%dd" % picPattern.digits) % picNum, picPattern.postfix)) if transDur > 0 and picBefore: for idxTrans in range(transDur): task = TaskTrans(pic.GetTransition(), (idxTrans + 1) / (transDur + 1), picBefore.Copy(), pathRects[idxRect], picCopy.Copy(), pathRects[idxRect], self._profile.GetResolution()) task.SetInfo(_(u"processing transition %d/%d") % (picNum, idxTrans + 1)) task.SetDraft(self._draftMode) self._tasks.append(task) idxRect += 1 if idxRect < len(pathRects): for __ in range(picDur): task = TaskCropResize(picCopy.Copy(), pathRects[idxRect], self._profile.GetResolution()) task.SetInfo(_(u"processing image %d/%d") % (picNum, __ + 1)) task.SetDraft(self._draftMode) self._tasks.append(task) idxRect += 1 picNum += 1 picBefore = picCopy picBefore = None idxPic += 1 class ComputePath: def __init__(self, pic, picCount): px1, py1 = pic.GetStartRect()[:2] w1, h1 = pic.GetStartRect()[2:] px2, py2 = pic.GetTargetRect()[:2] w2, h2 = pic.GetTargetRect()[2:] cx1 = (w1 / 2.0) + px1 cy1 = (h1 / 2.0) + py1 cx2 = (w2 / 2.0) + px2 cy2 = (h2 / 2.0) + py2 if pic.GetMovement() == Picture.MOVE_LINEAR: clazz = LinearMovement elif pic.GetMovement() == Picture.MOVE_DELAYED: clazz = DelayedMovement else: clazz = AccelMovement mX = clazz(cx2 - cx1, picCount, cx1) mY = clazz(cy2 - cy1, picCount, cy1) mW = clazz(w2 - w1, picCount, w1) mH = clazz(h2 - h1, picCount, h1) pathRects = [] for step in range(picCount): px = mX.Get(step) py = mY.Get(step) width = mW.Get(step) height = mH.Get(step) rect = (px - width / 2.0, py - height / 2.0, width, height) pathRects.append(rect) self.pathRects = pathRects def GetPathRects(self): return self.pathRects class LinearMovement: def __init__(self, s, t, s0): self._s = float(s) self._t = float(t) self._s0 = float(s0) if t > 1: self._v = self._s / (self._t - 1) else: self._v = 0 def Get(self, t): # s = v *t + s0 t = float(t) return self._v * t + self._s0 class AccelMovement: def __init__(self, s, t, s0): self._s = float(s) self._t = float(t) self._s0 = float(s0) # gesucht: Polynom 3ten Grades # s = a*t^3 + b*t^2 + c*t + d # RB 1: f'(t) = 0 # RB 2: f'(0) = 0 --> c = 0 # RB 3: f''(t/2) = 0 --> b = -3 * a * t # RB 4: f(t) = s --> a = (s - b*t^2) / t^3 self._a = -2.0 * self._s / (self._t ** 3) self._b = -3 * self._a * (self._t / 2.0) self._c = 0 self._d = float(s0) def Get(self, t): return self._a * t ** 3 + self._b * t ** 2 + self._c * t + self._d class DelayedMovement(AccelMovement): def __init__(self, s, t, s0): AccelMovement.__init__(self, s, t / 2, s0) self._t4th = t / 4 self._sAccel = None def Get(self, t): if t < self._t4th: self._sAccel = self._s0 elif t < (self._t * 2) - self._t4th: self._sAccel = AccelMovement.Get(self, t - self._t4th) return self._sAccel photofilmstrip-3.7.2/photofilmstrip/core/tasks.py0000644000232200023220000000745013560357351022704 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2017 Jens Goepfert # import os from photofilmstrip.core.Subtitle import SubtitleSrt from photofilmstrip.core import PILBackend class Task: def __init__(self): self.info = u"" self.subTasks = [] def __str__(self): return "%s: %s" % (self.__class__.__name__, self.info) def IterSubTasks(self): for subTask in self.subTasks: for subSubTask in subTask.IterSubTasks(): yield subSubTask yield subTask def GetInfo(self): return self.info def SetInfo(self, info): self.info = info def GetKey(self): raise NotImplementedError() def Run(self, jobContext): raise NotImplementedError() class TaskSubtitle(Task): def __init__(self, picCountFactor, pics): Task.__init__(self) self.__picCountFactor = picCountFactor self.__pics = pics self.SetInfo(_(u"generating subtitle")) def __HasComments(self): for pic in self.__pics: if pic.GetComment(): return True return False def GetKey(self): return "subtitle" def Run(self, jobContext): if self.__HasComments(): outFile = jobContext.GetOutputFile() baseFile = os.path.splitext(outFile)[0] st = SubtitleSrt(baseFile, self.__picCountFactor) st.Start(self.__pics) class TaskLoadPic(Task): def __init__(self, picture): Task.__init__(self) self.picture = picture def GetKey(self): return 'LoadPic_{}'.format( self.picture.GetKey()) def Run(self, jobContext): return PILBackend.GetImage(self.picture) class TaskImaging(Task): def __init__(self, resolution): Task.__init__(self) self.resolution = resolution self.draft = False def SetDraft(self, value): self.draft = value class TaskCropResize(TaskImaging): def __init__(self, picture, rect, resolution): TaskImaging.__init__(self, resolution) self.picture = picture self.rect = rect self.taskLoadPic = TaskLoadPic(picture) self.subTasks.append(self.taskLoadPic) def GetKey(self): return 'CropAndResize_{}_{}_{}'.format( self.taskLoadPic.GetKey(), self.rect, self.resolution) def Run(self, jobContext): image = jobContext.ProcessSubTask(self.taskLoadPic) img = PILBackend.CropAndResize(image, self.rect, self.resolution, self.draft) return img class TaskTrans(TaskImaging): def __init__(self, kind, percentage, pic1, rect1, pic2, rect2, resolution): TaskImaging.__init__(self, resolution) self.kind = kind self.percentage = percentage self.taskPic1 = TaskCropResize(pic1, rect1, resolution) self.taskPic2 = TaskCropResize(pic2, rect2, resolution) self.subTasks.append(self.taskPic1) self.subTasks.append(self.taskPic2) def SetDraft(self, value): TaskImaging.SetDraft(self, value) self.taskPic1.SetDraft(self.draft) self.taskPic2.SetDraft(self.draft) def GetKey(self): return 'TaskTrans_{}_{}_{}_{}'.format( self.kind, self.percentage, self.taskPic1.GetKey(), self.taskPic2.GetKey()) def Run(self, jobContext): image1 = jobContext.ProcessSubTask(self.taskPic1) image2 = jobContext.ProcessSubTask(self.taskPic2) img = PILBackend.Transition(self.kind, image1, image2, self.percentage) return img photofilmstrip-3.7.2/photofilmstrip/core/PILBackend.py0000644000232200023220000001531013560357351023445 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2010 Jens Goepfert # import logging import io from PIL import Image, ImageDraw from photofilmstrip.core.Picture import Picture def ImageToStream(pilImg, imgFormat="JPEG"): fd = io.BytesIO() pilImg.save(fd, imgFormat) fd.seek(0) return fd def ImageFromBuffer(size, buffr): pilImg = Image.frombuffer("RGB", size, buffr, 'raw', "RGB", 0, 1) return pilImg def RotateExif(pilImg): exifOrient = 274 rotation = 0 try: exif = pilImg._getexif() # pylint: disable=protected-access if isinstance(exif, dict) and exifOrient in exif: rotation = exif[exifOrient] except AttributeError: pass except Exception as err: logging.debug("PILBackend.RotateExif(): %s", err, exc_info=1) if rotation == 2: # flip horizontal return pilImg.transpose(Image.FLIP_LEFT_RIGHT) elif rotation == 3: # rotate 180 return pilImg.rotate(-180) elif rotation == 4: # flip vertical return pilImg.transpose(Image.FLIP_TOP_BOTTOM) elif rotation == 5: # transpose pilImg = pilImg.rotate(-90, expand=1) return pilImg.transpose(Image.FLIP_LEFT_RIGHT) elif rotation == 6: # rotate 90 return pilImg.rotate(-90, expand=1) elif rotation == 7: # transverse pilImg = pilImg.rotate(-90, expand=1) return pilImg.transpose(Image.FLIP_TOP_BOTTOM) elif rotation == 8: # rotate 270 return pilImg.rotate(-270, expand=1) return pilImg def CropAndResize(pilImg, rect, size, draft=False): if draft: filtr = Image.NEAREST else: filtr = Image.BILINEAR img = pilImg.transform(size, Image.AFFINE, [rect[2] / size[0], 0, rect[0], 0, rect[3] / size[1], rect[1]], filtr) return img def Transition(kind, pilImg1, pilImg2, percentage): if kind == Picture.TRANS_FADE: img = Image.blend(pilImg1, pilImg2, percentage) elif kind == Picture.TRANS_ROLL: xsize, ysize = pilImg1.size delta = int(xsize * percentage) part1 = pilImg2.crop((0, 0, delta, ysize)) part2 = pilImg1.crop((delta, 0, xsize, ysize)) image = pilImg2.copy() image.paste(part2, (0, 0, xsize - delta, ysize)) image.paste(part1, (xsize - delta, 0, xsize, ysize)) img = image return img def __CreateDummyImage(message): width = 400 height = 300 img = Image.new("RGB", (width, height), (255, 255, 255)) draw = ImageDraw.Draw(img) textWidth, textHeight = draw.textsize(message) x = (width - textWidth) // 2 y = (height - textHeight * 2) draw.text((x, y), message, fill=(0, 0, 0)) sz = width // 2 draw.ellipse(((width - sz) // 2, (height - sz) // 2, (width + sz) // 2, (height + sz) // 2), fill=(255, 0, 0)) sz = width // 7 draw.line((width // 2 - sz, height // 2 - sz, width // 2 + sz, height // 2 + sz), fill=(255, 255, 255), width=20) draw.line((width // 2 + sz, height // 2 - sz, width // 2 - sz, height // 2 + sz), fill=(255, 255, 255), width=20) del draw return img def __GetImage(picture): try: img = Image.open(picture.GetFilename()) # open does not validate the image data, because it is not loaded yet # use thumbnail() instead of load, it checks image data much faster img.thumbnail((10, 10)) # discard the thumbnail img = Image.open(picture.GetFilename()) picture.SetDummy(False) except Exception as err: logging.debug("PILBackend.GetImage(%s): %s", picture.GetFilename(), err, exc_info=1) img = __CreateDummyImage(str(err)) picture.SetDummy(True) return img def __ProcessImage(img, picture): if not picture.IsDummy(): img = RotateExif(img) rotation = picture.GetRotation() * -90 if rotation != 0: img = img.rotate(rotation) if picture.GetEffect() == picture.EFFECT_BLACK_WHITE: img = img.convert("L") elif picture.GetEffect() == picture.EFFECT_SEPIA: def make_linear_ramp(white): # putpalette expects [r,g,b,r,g,b,...] ramp = [] r, g, b = white for i in range(255): ramp.extend((r * i // 255, g * i // 255, b * i // 255)) return ramp # make sepia ramp (tweak color as necessary) sepia = make_linear_ramp((255, 240, 192)) img = img.convert("L") img.putpalette(sepia) return img.convert("RGB") def GetImage(picture): pilImg = __GetImage(picture) pilImg = __ProcessImage(pilImg, picture) picture.SetWidth(pilImg.size[0]) picture.SetHeight(pilImg.size[1]) return pilImg def GetExifRotation(pilImg): exifOrient = 274 rotation = 0 try: exif = pilImg._getexif() # pylint: disable=protected-access if isinstance(exif, dict) and exifOrient in exif: rotation = exif[exifOrient] except AttributeError: pass except Exception as err: logging.debug("PILBackend.RotateExif(): %s", err, exc_info=1) if rotation == 3: # rotate 180 return 2 elif rotation == 5: # transpose return 1 elif rotation == 6: # rotate 90 return 1 elif rotation == 7: # transverse return 1 elif rotation == 8: # rotate 270 return 3 else: return 0 def GetImageSize(filename): pilImg = Image.open(filename) width, height = pilImg.size rotation = GetExifRotation(pilImg) while rotation > 0: width, height = height, width rotation -= 1 return width, height def GetThumbnail(picture, width=None, height=None): img = __GetImage(picture) aspect = img.size[0] / img.size[1] if width is not None and height is not None: thumbWidth = width thumbHeight = height elif width is not None: thumbWidth = width thumbHeight = int(round(thumbWidth / aspect)) elif height is not None: thumbHeight = height thumbWidth = int(round(thumbHeight * aspect)) # prescale image to speed up processing img.thumbnail((max(thumbWidth, thumbHeight), max(thumbWidth, thumbHeight)), Image.NEAREST) img = __ProcessImage(img, picture) # make the real thumbnail img.thumbnail((thumbWidth, thumbHeight), Image.NEAREST) # newImg = Image.new("RGB", (thumbWidth, thumbHeight), 0) # newImg.paste(img, (abs(thumbWidth - img.size[0]) / 2, # abs(thumbHeight - img.size[1]) / 2)) # img = newImg return img photofilmstrip-3.7.2/photofilmstrip/core/renderer/0000755000232200023220000000000013560357432023005 5ustar debalancedebalancephotofilmstrip-3.7.2/photofilmstrip/core/renderer/SingleFileRenderer.py0000644000232200023220000000215013560357351027065 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2011 Jens Goepfert # import os from photofilmstrip.core.BaseRenderer import BaseRenderer class SingleFileRenderer(BaseRenderer): def __init__(self): BaseRenderer.__init__(self) self._counter = 0 @staticmethod def GetName(): return _(u"Single pictures") @staticmethod def GetProperties(): return ["ResampleFilter"] @staticmethod def GetDefaultProperty(prop): if prop == "ResampleFilter": return "Antialias" else: return BaseRenderer.GetDefaultProperty(prop) def Prepare(self): pass def ToSink(self, data): self._counter += 1 outputPath = os.path.dirname(self._outFile) newFilename = os.path.join(outputPath, '%09d.%s' % (self._counter, "jpg")) with open(newFilename, "wb") as fd: fd.write(data) def Finalize(self): pass def ProcessAbort(self): pass photofilmstrip-3.7.2/photofilmstrip/core/renderer/__init__.py0000644000232200023220000000017113560357351025115 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2014 Jens Goepfert # photofilmstrip-3.7.2/photofilmstrip/core/renderer/StreamRenderer.py0000644000232200023220000000207313560357351026303 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2011 Jens Goepfert # import sys from photofilmstrip.core.renderer.SingleFileRenderer import SingleFileRenderer from photofilmstrip.core.BaseRenderer import ImageDataFinalizeHandler class StreamRenderer(SingleFileRenderer): def __init__(self): SingleFileRenderer.__init__(self) @staticmethod def GetName(): return u"Stream output" @staticmethod def GetProperties(): return SingleFileRenderer.GetProperties() + ["Format"] @staticmethod def GetDefaultProperty(prop): if prop == "Format": return "PPM" else: return SingleFileRenderer.GetDefaultProperty(prop) def GetFinalizeHandler(self): imgFormat = self.GetProperty("Format") if imgFormat in ["JPEG", "PPM"]: return ImageDataFinalizeHandler(imgFormat) else: raise RuntimeError("unsupported format: %s" % imgFormat) def ToSink(self, data): sys.stdout.buffer.write(data) photofilmstrip-3.7.2/photofilmstrip/core/renderer/GStreamerRenderer.py0000644000232200023220000006532213560357351026747 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2014 Jens Goepfert # import logging import os import threading import queue from gi.repository import Gst from gi.repository import GObject from photofilmstrip.core.Aspect import Aspect from photofilmstrip.core.OutputProfile import OutputProfile from photofilmstrip.core.BaseRenderer import BaseRenderer from photofilmstrip.core.Subtitle import SrtParser from photofilmstrip.core.exceptions import RendererException class _GStreamerRenderer(BaseRenderer): def __init__(self): BaseRenderer.__init__(self) self._Log = _GStreamerRenderer.Log self.resQueue = queue.Queue(20) self.active = None self.finished = None self.ready = None self.pipeline = None self.idxFrame = 0 self.idxAudioFile = 0 self.imgDuration = None self.finalTime = None self.gtkMainloop = None self.textoverlay = None self.srtParse = None self.concat = None self.ptsOffset = 0 self.ptsLast = -1 @staticmethod def CheckDependencies(msgList): if Gst is None or GObject is None: _GStreamerRenderer.Log(logging.DEBUG, "checking for gstreamer failed!") msgList.append(_(u"GStreamer (python-gst-1.0) required!")) else: to = Gst.ElementFactory.find("textoverlay") if to is None: _GStreamerRenderer.Log(logging.WARN, "GStreamer element textoverlay not found! Subtitles cannot rendered into video file.") @staticmethod def GetProperties(): return ["Bitrate", "RenderSubtitle", "SubtitleSettings"] @staticmethod def GetDefaultProperty(prop): if prop == "RenderSubtitle": return "false" if prop == "SubtitleSettings": return "" return BaseRenderer.GetDefaultProperty(prop) def ToSink(self, data): self.resQueue.put(data) def GetOutputFile(self): outFile = '{0}.{1}'.format(self._outFile, self._GetExtension()) return outFile def __CleanUp(self): ''' Waits until the ready event is set and finished the GTK-Mainloop. The ready event is set within _GstOnMessage if the end-of-stream event was handled. ''' if self.ready is None: return self._Log(logging.DEBUG, "waiting for ready event") self.ready.wait() self.gtkMainloop.quit() self.active = None self.finished = None self.ready = None self.pipeline = None self.idxFrame = 0 self.idxAudioFile = 0 self.imgDuration = None self.finalTime = None self.gtkMainloop = None self.textoverlay = None self.srtParse = None self.concat = None self.ptsOffset = 0 self.ptsLast = -1 if self.GetTypedProperty("RenderSubtitle", bool): # delete subtitle file, if subtitle is rendered in video srtPath = self._outFile + ".srt" if os.path.exists(srtPath): os.remove(srtPath) def ProcessAbort(self): ''' Called if the user aborts the rendering. Sets the active flag to false and waits until everything is cleaned up. ''' if self.active: self.active = False self.__CleanUp() def Prepare(self): ''' Build the gstreamer pipeline and all necessary objects and bindings. ''' GObject.threads_init() self.ready = threading.Event() self.ready.set() self.active = True self.finished = False frameRate = self.GetProfile().GetFrameRate() # 1000ms / fps == x msec/frame self.imgDuration = int(round(1000 * Gst.MSECOND / frameRate.AsFloat())) self._Log(logging.DEBUG, "set imgDuration=%s", self.imgDuration) self.pipeline = Gst.Pipeline() caps = Gst.caps_from_string( "image/jpeg,framerate={0}".format(frameRate.AsStr())) videoSrc = Gst.ElementFactory.make("appsrc") videoSrc.set_property("block", True) videoSrc.set_property("caps", caps) videoSrc.connect("need-data", self._GstNeedData) self.pipeline.add(videoSrc) queueVideo = Gst.ElementFactory.make("queue") self.pipeline.add(queueVideo) jpegDecoder = Gst.ElementFactory.make("jpegdec") self.pipeline.add(jpegDecoder) colorConverter = Gst.ElementFactory.make("videoconvert") self.pipeline.add(colorConverter) videoEnc = self._GetVideoEncoder() self.pipeline.add(videoEnc) if self.GetTypedProperty("RenderSubtitle", bool) and Gst.ElementFactory.find("textoverlay"): self.textoverlay = Gst.ElementFactory.make("textoverlay") self.textoverlay.set_property("text", "") self._SetupTextOverlay() self.pipeline.add(self.textoverlay) # link elements for video stream videoSrc.link(jpegDecoder) jpegDecoder.link(colorConverter) if self.textoverlay: colorConverter.link(self.textoverlay) self.textoverlay.link(queueVideo) else: colorConverter.link(queueVideo) queueVideo.link(videoEnc) audioEnc = None if self.GetAudioFiles(): self.concat = Gst.ElementFactory.make("concat") self.pipeline.add(self.concat) srcpad = self.concat.get_static_pad("src") srcpad.add_probe(Gst.PadProbeType.BUFFER, # | Gst.PadProbeType.EVENT_DOWNSTREAM, self._GstProbeBuffer) self._GstAddAudioFile(self.GetAudioFiles()[self.idxAudioFile]) audioConv = Gst.ElementFactory.make("audioconvert") self.pipeline.add(audioConv) audiorate = Gst.ElementFactory.make("audioresample") self.pipeline.add(audiorate) audioQueue = Gst.ElementFactory.make("queue") self.pipeline.add(audioQueue) audioEnc = self._GetAudioEncoder() self.pipeline.add(audioEnc) self.concat.link(audioConv) audioConv.link(audiorate) audiorate.link(audioQueue) audioQueue.link(audioEnc) if self.GetProfile().IsMPEGProfile(): vp = Gst.ElementFactory.make("mpegvideoparse") self.pipeline.add(vp) videoEnc.link(vp) videoEnc = vp if audioEnc: ap = Gst.ElementFactory.make("mpegaudioparse") self.pipeline.add(ap) audioEnc.link(ap) audioEnc = ap elif isinstance(self, MkvX265AC3): vp = Gst.ElementFactory.make("h265parse") self.pipeline.add(vp) videoEnc.link(vp) videoEnc = vp mux = self._GetMux() self.pipeline.add(mux) videoQueue2 = Gst.ElementFactory.make("queue") self.pipeline.add(videoQueue2) videoEncCaps = self._GetVideoEncoderCaps() # pylint: disable=assignment-from-none if videoEncCaps: videoEnc.link_filtered(videoQueue2, videoEncCaps) else: videoEnc.link(videoQueue2) videoQueue2.link(mux) if audioEnc: audioQueue2 = Gst.ElementFactory.make("queue") self.pipeline.add(audioQueue2) audioEnc.link(audioQueue2) audioQueue2.link(mux) sink = Gst.ElementFactory.make("filesink") sink.set_property("location", self.GetOutputFile()) self.pipeline.add(sink) mux.link(sink) bus = self.pipeline.get_bus() bus.add_signal_watch() bus.connect("message", self._GstOnMessage) self.pipeline.set_state(Gst.State.PLAYING) self.gtkMainloop = GObject.MainLoop() gtkMainloopThread = threading.Thread(name="gtkMainLoop", target=self._GtkMainloop) gtkMainloopThread.start() self.ready.clear() def _GtkMainloop(self): self._Log(logging.DEBUG, "GTK mainloop starting...") self.gtkMainloop.run() self._Log(logging.DEBUG, "GTK mainloop finished") def _GstAddAudioFile(self, audioFile): ''' Inserts new elements to refer a new audio file in the gstreamer pipeline. :param audioFile: the full path to the audio file ''' audioSrc = Gst.ElementFactory.make("filesrc") audioSrc.set_property("location", audioFile) self.pipeline.add(audioSrc) audioDec = Gst.ElementFactory.make("decodebin") audioDec.connect("pad-added", self._GstPadAddedAudio) audioDec.connect("no-more-pads", self._GstNoMorePadsAudio) self.pipeline.add(audioDec) audioSrc.link(audioDec) def Finalize(self): if not self.finished: self.finished = True self.__CleanUp() def _GetBitrate(self): bitrate = self.GetTypedProperty("Bitrate", int, self.GetProfile().GetBitrate()) if bitrate is None: raise RendererException(_(u"Bitrate must be a number!")) return bitrate def _GstOnMessage(self, bus, msg): # pylint: disable=unused-argument ''' Gstreamer message handler for messages in gstreamer event bus. :param bus: :param msg: ''' self._Log(logging.DEBUG, '_GstOnMessage: %s', msg.type) if msg.type == Gst.MessageType.ERROR: err, debug = msg.parse_error() self._Log(logging.ERROR, "Error received from element %s: %s", msg.src.get_name(), err) self._Log(logging.DEBUG, "Debugging information: %s", debug) elif msg.type == Gst.MessageType.LATENCY: self.pipeline.recalculate_latency() elif msg.type == Gst.MessageType.EOS: self.pipeline.set_state(Gst.State.NULL) self.ready.set() # return Gst.BusSyncReply.PASS def _GstNeedData(self, src, need_bytes): # pylint: disable=unused-argument ''' Gstreamer need-data probe callback to feed the appsrc with image data. The image data comes from a queue that is filled from other worker threads. If the queue is empty and the finish flag is set send end-of-stream to the appsrc so the pipeline can finish its processing. If the textoverlay element is available the current text for the rendered subtitle will be set. :param src: GstElement appsrc :param need_bytes: unused size ''' self._Log(logging.DEBUG, '_GstNeedData: %s', self.idxFrame) pts = self.idxFrame * self.imgDuration while self.active: result = None try: result = self.resQueue.get(True, 0.25) break except queue.Empty: self._Log(logging.DEBUG, '_GstNeedData: Queue.Empty') if self.finished: self._Log(logging.DEBUG, '_GstNeedData: finished, emitting end-of-stream (finalTime %s)', pts) self.finalTime = pts src.emit("end-of-stream") return else: continue else: self._Log(logging.DEBUG, '_GstNeedData: not active anymore, emitting end-of-stream (finalTime %s)', pts) self.finalTime = pts src.emit("end-of-stream") return self._Log(logging.DEBUG, '_GstNeedData: push to buffer (%s)', len(result)) buf = Gst.Buffer.new_wrapped(result) buf.pts = pts buf.duration = self.imgDuration ret = src.emit("push-buffer", buf) if ret != Gst.FlowReturn.OK: return if self.textoverlay: # self.textoverlay.set_property("text", "Frame: %s" % self.idxFrame) if self.srtParse is None: srtPath = self._outFile + ".srt" self.srtParse = SrtParser( srtPath, self.GetProfile().GetFrameRate().AsFloat()) subtitle = self.srtParse.Get(self.idxFrame) self.textoverlay.set_property("text", subtitle) self.idxFrame += 1 def _GstPadAddedAudio(self, decodebin, pad): ''' Gstreamer pad-added probe callback to attach a new audio file to the pipeline. :param decodebin: GstElement decodebin (decoder for audio data) :param pad: GstPad object ''' self._Log(logging.DEBUG, "_GstPadAddedAudio: %s - %s", decodebin, pad) caps = pad.get_current_caps() compatible_pad = self.concat.get_compatible_pad(pad, caps) pad.link(compatible_pad) def _GstNoMorePadsAudio(self, decodebin): self._Log(logging.DEBUG, "_GstNoMorePadsAudio: %s", decodebin) self.idxAudioFile += 1 if self.idxAudioFile < len(self.GetAudioFiles()): # self.pipeline.set_state(Gst.State.PAUSED) self._GstAddAudioFile(self.GetAudioFiles()[self.idxAudioFile]) # self.pipeline.set_state(Gst.State.PLAYING) def _GstProbeBuffer(self, srcPad, probeInfo): # pylint: disable=unused-argument ''' Gstreamer pad probe callback to check if the current stream time has reached the final time (usually the length of the overall audio stream). If final time has reached send eos event (end of stream) to finish the pipeline :param srcPad: src pad of the muxer :param probeInfo: GstPadProbeInfo object ''' buf = probeInfo.get_buffer() self._Log(logging.DEBUG, "_GstProbeBuffer: buffer %s", (buf, buf.pts // Gst.MSECOND, self.ptsOffset // Gst.MSECOND, self.finalTime)) if buf.pts < self.ptsLast: self.ptsOffset += self.ptsLast self.ptsLast = buf.pts if self.finalTime is None: return Gst.PadProbeReturn.PASS elif self.ptsOffset + buf.pts >= self.finalTime: return Gst.PadProbeReturn.DROP else: return Gst.PadProbeReturn.PASS def _SetupTextOverlay(self): settings = self.GetProperty("SubtitleSettings") for singleSetting in settings.split(";"): settingAndProp = singleSetting.split("=") if len(settingAndProp) == 2: prop, value = settingAndProp try: # try number as int value = int(value) except: # pylint: disable-msg=bare-except try: # try numbers as hex value = int(value, 16) except: # pylint: disable-msg=bare-except pass self.textoverlay.set_property(prop, value) def _GetExtension(self): raise NotImplementedError() def _GetMux(self): raise NotImplementedError() def _GetAudioEncoder(self): raise NotImplementedError() def _GetVideoEncoder(self): raise NotImplementedError() def _GetVideoEncoderCaps(self): return None class MkvX264AC3(_GStreamerRenderer): @staticmethod def GetName(): return "x264/AC3 (MKV)" @staticmethod def CheckDependencies(msgList): _GStreamerRenderer.CheckDependencies(msgList) if not msgList: aEnc = Gst.ElementFactory.find("avenc_ac3") if aEnc is None: msgList.append(_(u"libav (gstreamer1.0-libav) required!")) vEnc = Gst.ElementFactory.find("x264enc") if vEnc is None: msgList.append(_(u"x264-Codec (gstreamer1.0-plugins-ugly) required!")) mux = Gst.ElementFactory.find("matroskamux") if mux is None: msgList.append(_(u"MKV-Muxer (gstreamer1.0-plugins-good) required!")) @staticmethod def GetDefaultProperty(prop): if prop == "Profile": return "high" elif prop == "HardwareEncoding": return "false" else: return _GStreamerRenderer.GetDefaultProperty(prop) @staticmethod def GetProperties(): return _GStreamerRenderer.GetProperties() + [ "SpeedPreset", "Profile", "HardwareEncoding"] def _GetExtension(self): return "mkv" def _GetMux(self): mux = Gst.ElementFactory.make("matroskamux") return mux def _GetAudioEncoder(self): # audioEnc = Gst.ElementFactory.make("lamemp3enc") audioEnc = Gst.ElementFactory.make("avenc_ac3") # audioEnc = Gst.ElementFactory.make("lame") # audioEnc.set_property("target", "bitrate") # audioEnc.set_property("bitrate", 192) return audioEnc def _GetVideoEncoder(self): if self.GetTypedProperty("HardwareEncoding", bool) and Gst.ElementFactory.find("vaapih264enc"): videoEnc = Gst.ElementFactory.make("vaapih264enc") else: videoEnc = Gst.ElementFactory.make("x264enc") videoEnc.set_property("bitrate", self._GetBitrate()) speedPreset = self.GetTypedProperty("SpeedPreset", int) if speedPreset is not None: videoEnc.set_property("speed-preset", speedPreset) return videoEnc def _GetVideoEncoderCaps(self): profile = self.GetTypedProperty("Profile", str) if profile in ("main", "high", "baseline", "constrained-baseline"): caps = Gst.caps_from_string("video/x-h264,profile={}".format(profile)) return caps elif profile: self._Log(logging.WARN, "value '%s' for profile not supported!", profile) return None class Mp4X264AAC(_GStreamerRenderer): @staticmethod def GetName(): return "x264/AAC (MP4)" @staticmethod def CheckDependencies(msgList): _GStreamerRenderer.CheckDependencies(msgList) if not msgList: aEnc = Gst.ElementFactory.find("avenc_aac") if aEnc is None: msgList.append(_(u"libav (gstreamer1.0-libav) required!")) vEnc = Gst.ElementFactory.find("x264enc") if vEnc is None: msgList.append(_(u"x264-Codec (gstreamer1.0-plugins-ugly) required!")) mux = Gst.ElementFactory.find("mp4mux") if mux is None: msgList.append(_(u"MP4-Muxer (gstreamer1.0-plugins-good) required!")) @staticmethod def GetDefaultProperty(prop): if prop == "Profile": return "high" elif prop == "HardwareEncoding": return "false" else: return _GStreamerRenderer.GetDefaultProperty(prop) @staticmethod def GetProperties(): return _GStreamerRenderer.GetProperties() + [ "SpeedPreset", "Profile", "HardwareEncoding"] def _GetExtension(self): return "mp4" def _GetMux(self): mux = Gst.ElementFactory.make("mp4mux") return mux def _GetAudioEncoder(self): audioEnc = Gst.ElementFactory.make("avenc_aac") return audioEnc def _GetVideoEncoder(self): if self.GetTypedProperty("HardwareEncoding", bool) and Gst.ElementFactory.find("vaapih264enc"): videoEnc = Gst.ElementFactory.make("vaapih264enc") else: videoEnc = Gst.ElementFactory.make("x264enc") videoEnc.set_property("bitrate", self._GetBitrate()) speedPreset = self.GetTypedProperty("SpeedPreset", int) if speedPreset is not None: videoEnc.set_property("speed-preset", speedPreset) return videoEnc def _GetVideoEncoderCaps(self): profile = self.GetTypedProperty("Profile", str) if profile in ("main", "high", "baseline", "constrained-baseline"): caps = Gst.caps_from_string("video/x-h264,profile={}".format(profile)) return caps elif profile: self._Log(logging.WARN, "value '%s' for profile not supported!", profile) return None class MkvX265AC3(_GStreamerRenderer): @staticmethod def GetName(): return "x265/AC3 (MKV)" @staticmethod def CheckDependencies(msgList): _GStreamerRenderer.CheckDependencies(msgList) if not msgList: aEnc = Gst.ElementFactory.find("avenc_ac3") if aEnc is None: msgList.append(_(u"libav (gstreamer1.0-libav) required!")) vEnc = Gst.ElementFactory.find("x265enc") if vEnc is None: msgList.append(_(u"x264-Codec (gstreamer1.0-plugins-ugly) required!")) mux = Gst.ElementFactory.find("matroskamux") if mux is None: msgList.append(_(u"MKV-Muxer (gstreamer1.0-plugins-good) required!")) @staticmethod def GetProperties(): return _GStreamerRenderer.GetProperties() + ["SpeedPreset"] def _GetExtension(self): return "mkv" def _GetMux(self): mux = Gst.ElementFactory.make("matroskamux") return mux def _GetAudioEncoder(self): audioEnc = Gst.ElementFactory.make("avenc_ac3") return audioEnc def _GetVideoEncoder(self): videoEnc = Gst.ElementFactory.make("x265enc") videoEnc.set_property("bitrate", self._GetBitrate()) speedPreset = self.GetTypedProperty("SpeedPreset", int) if speedPreset is not None: videoEnc.set_property("speed-preset", speedPreset) return videoEnc class OggTheoraVorbis(_GStreamerRenderer): @staticmethod def GetName(): return "Theora/Vorbis (OGV)" @staticmethod def CheckDependencies(msgList): _GStreamerRenderer.CheckDependencies(msgList) if not msgList: aEnc = Gst.ElementFactory.find("theoraenc") if aEnc is None: msgList.append(_(u"Theora-Codec (gstreamer1.0-plugins-base) required!")) vEnc = Gst.ElementFactory.find("vorbisenc") if vEnc is None: msgList.append(_(u"Vorbis-Codec (gstreamer1.0-plugins-base) required!")) mux = Gst.ElementFactory.find("oggmux") if mux is None: msgList.append(_(u"OGV-Muxer (gstreamer1.0-plugins-base) required!")) def _GetExtension(self): return "ogv" def _GetMux(self): mux = Gst.ElementFactory.make("oggmux") return mux def _GetAudioEncoder(self): audioEnc = Gst.ElementFactory.make("vorbisenc") return audioEnc def _GetVideoEncoder(self): videoEnc = Gst.ElementFactory.make("theoraenc") videoEnc.set_property("bitrate", self._GetBitrate()) return videoEnc class VCDFormat(_GStreamerRenderer): @staticmethod def GetName(): return "VCD (MPG)" @staticmethod def CheckDependencies(msgList): _GStreamerRenderer.CheckDependencies(msgList) if not msgList: vEnc = Gst.ElementFactory.find("mpeg2enc") if vEnc is None: msgList.append(_(u"MPEG-1/2-Codec (gstreamer1.0-plugins-bad) required!")) aEnc = Gst.ElementFactory.find("avenc_mp2") if aEnc is None: msgList.append(_(u"libav (gstreamer1.0-libav) required!")) mux = Gst.ElementFactory.find("mpegtsmux") if mux is None: msgList.append(_(u"MPEG-Muxer (gstreamer1.0-plugins-bad) required!")) def _GetExtension(self): return "mpg" def _GetMux(self): mux = Gst.ElementFactory.make("mpegtsmux") return mux def _GetAudioEncoder(self): audioEnc = Gst.ElementFactory.make("avenc_mp2") return audioEnc def _GetVideoEncoder(self): videoEnc = Gst.ElementFactory.make("mpeg2enc") videoEnc.set_property("format", 1) videoEnc.set_property("norm", "p" if self.GetProfile().GetVideoNorm() == OutputProfile.PAL else "n") return videoEnc class SVCDFormat(_GStreamerRenderer): @staticmethod def GetName(): return "SVCD (MPG)" @staticmethod def CheckDependencies(msgList): _GStreamerRenderer.CheckDependencies(msgList) if not msgList: vEnc = Gst.ElementFactory.find("mpeg2enc") if vEnc is None: msgList.append(_(u"MPEG-1/2-Codec (gstreamer1.0-plugins-bad) required!")) aEnc = Gst.ElementFactory.find("avenc_mp2") if aEnc is None: msgList.append(_(u"libav (gstreamer1.0-libav) required!")) mux = Gst.ElementFactory.find("mpegtsmux") if mux is None: msgList.append(_(u"MPEG-Muxer (gstreamer1.0-plugins-bad) required!")) def _GetExtension(self): return "mpg" def _GetMux(self): mux = Gst.ElementFactory.make("mpegtsmux") return mux def _GetAudioEncoder(self): audioEnc = Gst.ElementFactory.make("avenc_mp2") return audioEnc def _GetVideoEncoder(self): videoEnc = Gst.ElementFactory.make("mpeg2enc") videoEnc.set_property("format", 4) videoEnc.set_property("norm", "p" if self.GetProfile().GetVideoNorm() == OutputProfile.PAL else "n") if self._aspect == Aspect.ASPECT_16_9: gstAspect = 3 elif self._aspect == Aspect.ASPECT_4_3: gstAspect = 2 else: gstAspect = 0 videoEnc.set_property("aspect", gstAspect) videoEnc.set_property("dummy-svcd-sof", 0) videoEnc.set_property("bitrate", self._GetBitrate()) return videoEnc class DVDFormat(_GStreamerRenderer): @staticmethod def GetName(): return "DVD (MPG)" @staticmethod def CheckDependencies(msgList): _GStreamerRenderer.CheckDependencies(msgList) if not msgList: vEnc = Gst.ElementFactory.find("mpeg2enc") if vEnc is None: msgList.append(_(u"MPEG-1/2-Codec (gstreamer1.0-plugins-bad) required!")) aEnc = Gst.ElementFactory.find("avenc_mp2") if aEnc is None: msgList.append(_(u"libav (gstreamer1.0-libav) required!")) mux = Gst.ElementFactory.find("mpegtsmux") if mux is None: msgList.append(_(u"MPEG-Muxer (gstreamer1.0-plugins-bad) required!")) def _GetExtension(self): return "mpg" def _GetMux(self): mux = Gst.ElementFactory.make("mpegtsmux") return mux def _GetAudioEncoder(self): audioEnc = Gst.ElementFactory.make("avenc_mp2") return audioEnc def _GetVideoEncoder(self): videoEnc = Gst.ElementFactory.make("mpeg2enc") videoEnc.set_property("format", 8) videoEnc.set_property("norm", "p" if self.GetProfile().GetVideoNorm() == OutputProfile.PAL else "n") if self._aspect == Aspect.ASPECT_16_9: gstAspect = 3 elif self._aspect == Aspect.ASPECT_4_3: gstAspect = 2 else: gstAspect = 0 videoEnc.set_property("aspect", gstAspect) videoEnc.set_property("bitrate", self._GetBitrate()) return videoEnc photofilmstrip-3.7.2/photofilmstrip/core/renderer/CairoRenderer.py0000644000232200023220000000625513560357351026113 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2011 Jens Goepfert # import array import time try: import wx import cairo except (ImportError, RuntimeError): cairo = None from photofilmstrip.core.BaseRenderer import BaseRenderer, FinalizeHandler class CairoRenderer(BaseRenderer): def __init__(self): BaseRenderer.__init__(self) self._ctx = None self._mainClock = Clock() self._framerate = None self._screen = wx.Frame(wx.GetApp().GetTopWindow(), style=wx.DEFAULT_FRAME_STYLE | wx.RESIZE_BORDER) self._screen.Bind(wx.EVT_PAINT, self.OnPaint) self._screen.Show() @staticmethod def GetName(): return _(u"Preview") @staticmethod def CheckDependencies(msgList): BaseRenderer.CheckDependencies(msgList) if cairo is None: msgList.append("cairo not installed!") def GetFinalizeHandler(self): ''' :rtype: FinalizeHandler ''' return PilToCairoFinalizeHandler() def ToSink(self, data): self._ctx = data self._mainClock.tick(self._framerate) wx.CallAfter(self._screen.Refresh) def ProcessAbort(self): wx.CallAfter(self._screen.Destroy) def Prepare(self): self._screen.SetClientSize(*self.GetProfile().GetResolution()) self._framerate = self.GetProfile().GetFrameRate().AsFloat() self._mainClock.reset() def OnPaint(self, event): dc = wx.BufferedPaintDC(self._screen) # dc.SetBackground(wx.Brush('black')) # dc.Clear() if self._ctx: w = self._ctx.get_width() h = self._ctx.get_height() data = self._ctx.get_data() wxbmp = wx.Bitmap.FromBufferRGBA(w, h, data) dc.DrawBitmap(wxbmp, 0, 0) event.Skip() def Finalize(self): wx.CallAfter(self._screen.Destroy) class PilToCairoFinalizeHandler(FinalizeHandler): def ProcessFinalize(self, pilImg): pilImg = pilImg.copy() w, h = pilImg.size data = pilImg.convert('RGBA').tobytes() buff = array.array('B', data) cairoImage = cairo.ImageSurface.create_for_data(# pylint: disable=no-member buff, cairo.FORMAT_ARGB32, w, h) # pylint: disable=no-member # cairoImage = cairo.ImageSurface.create_for_data(buff, cairo.FORMAT_RGB24, w, h) return cairoImage class Clock: def __init__(self): self.fps = 0.0 self.fps_count = 0 self.start = 0 def reset(self): self.start = time.time() def tick(self, framerate): nowtime = time.time() self.fps_count += 1 timepassed = nowtime - self.start self.fps = 1.0 / (timepassed / self.fps_count) endtime = (1.0 / framerate) * self.fps_count delay = endtime - timepassed if delay < 0: delay = 0 time.sleep(delay) def get_fps(self): return self.fps def get_fps(clock, value): fps = clock.get_fps() tol = 0.1 # print fps, abs(fps - value), abs(fps * tol) return not (fps > 1 and abs(fps - value) <= abs(fps * tol)) photofilmstrip-3.7.2/photofilmstrip/core/ProjectFile.py0000644000232200023220000003007313560357351023762 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2017 Jens Goepfert # import logging import os import random import sqlite3 from photofilmstrip.core import PILBackend from photofilmstrip.core.Aspect import Aspect from photofilmstrip.core.Picture import Picture from photofilmstrip.gui.util.ImageCache import ImageCache # FIXME: no gui import here from photofilmstrip.core.Project import Project SCHEMA_REV = 4 """ 4: - added column movement to table picture 3: - added thumbnail table 2: - added property table 1: - initial """ SCHEMA = """ CREATE TABLE `picture` ( picture_id INTEGER PRIMARY KEY AUTOINCREMENT, filename TEXT, width INTEGER, height INTEGER, start_left INTEGER, start_top INTEGER, start_width INTEGER, start_height INTEGER, target_left INTEGER, target_top INTEGER, target_width INTEGER, target_height INTEGER, rotation INTEGER, duration DOUBLE, movement INTEGER, comment TEXT, effect INTEGER, transition INTEGER, transition_duration DOUBLE, data BLOB ); CREATE TABLE `property` ( property_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, value TEXT ); CREATE TABLE `thumbnail` ( thumbnail_id INTEGER PRIMARY KEY AUTOINCREMENT, picture_id INTEGER, width INTEGER, height INTEGER, data BLOB, FOREIGN KEY(picture_id) REFERENCES picture(picture_id) ON DELETE CASCADE ); """ class ProjectFile: def __init__(self, project=None, filename=None): self._project = project self._filename = filename # project.GetFilename() self.__conn = None self.__altPaths = {} self.__fileRev = 1 def __del__(self): if self.__conn is not None: logging.debug("database not closed properly: %s", self._filename) self.__conn.close() def GetProject(self): return self._project def __Connect(self): if self.__conn is None: self.__conn = sqlite3.connect(self._filename, detect_types=sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES) cur = self.__GetCursor() try: # at the beginning we had no property table cur.execute("SELECT value FROM `property` WHERE name=?", ("rev",)) result = cur.fetchone() if result: self.__fileRev = int(result[0]) except sqlite3.DatabaseError: pass def __Close(self, commit=False): if self.__conn is None: raise RuntimeError("not connected") if commit: self.__conn.commit() self.__conn.close() self.__conn = None def __GetCursor(self): if self.__conn is None: raise RuntimeError("not connected") cur = self.__conn.cursor() cur.row_factory = sqlite3.Row return cur def GetPicCount(self): self.IsOk() self.__Connect() try: try: cur = self.__GetCursor() cur.execute("SELECT COUNT(*) FROM `picture`") return cur.fetchone()[0] except sqlite3.DatabaseError: return 0 finally: self.__Close() return -1 def GetPreviewThumb(self): if not self.Load(): return None img = None pics = self._project.GetPictures() imgCount = len(pics) if imgCount > 0: picIdx = random.randint(0, imgCount - 1) pic = pics[picIdx] if os.path.exists(pic.GetFilename()): img = PILBackend.GetThumbnail(pic, width=136, height=70) if pic.IsDummy(): img = None return img def IsOk(self): self.__Connect() try: try: cur = self.__GetCursor() cur.execute("SELECT * FROM `picture`") return True except BaseException as err: logging.debug("IsOk(%s): %s", self._filename, err) return False finally: self.__Close() # save methods def __PicToQuery(self, pic, includePics): if includePics: fd = open(pic.GetFilename(), 'rb') picData = fd.read() fd.close() else: picData = None query = "INSERT INTO `picture` (" \ "filename, width, height, " \ "start_left, start_top, start_width, start_height, " \ "target_left, target_top, target_width, target_height, " \ "rotation, duration, movement, comment, effect, " \ "transition, transition_duration, data" \ ") VALUES (" \ "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?" \ ");" values = (pic.GetFilename(), pic.GetWidth(), pic.GetHeight(), pic.GetStartRect()[0], pic.GetStartRect()[1], pic.GetStartRect()[2], pic.GetStartRect()[3], pic.GetTargetRect()[0], pic.GetTargetRect()[1], pic.GetTargetRect()[2], pic.GetTargetRect()[3], pic.GetRotation(), pic.GetDuration(), pic.GetMovement(), pic.GetComment(), pic.GetEffect(), pic.GetTransition(), pic.GetTransitionDuration(rawValue=True), picData) return query, values def __ThumbToQuery(self, picId, pic): pilThumb = PILBackend.GetThumbnail(pic, height=120) thumbWidth, thumbHeight = pilThumb.size thumbData = pilThumb.tobytes() query = "INSERT INTO `thumbnail` (" \ "picture_id, width, height, data" \ ") VALUES (" \ "?, ?, ?, ?" \ ");" values = (picId, thumbWidth, thumbHeight, thumbData) return query, values def _StepProgress(self, msg): pass def Save(self, includePics=False): dirname = os.path.dirname(self._filename) if not os.path.exists(dirname): os.makedirs(dirname) if os.path.exists(self._filename): os.remove(self._filename) self.__Connect() cur = self.__GetCursor() cur.executescript(SCHEMA) cur = self.__GetCursor() for pic in self._project.GetPictures(): self._StepProgress(_(u"Saving '%s' ...") % pic.GetFilename()) query, values = self.__PicToQuery(pic, includePics) cur.execute(query, values) query, values = self.__ThumbToQuery(cur.lastrowid, pic) cur.execute(query, values) query = "INSERT INTO `property` (name, value) VALUES (?, ?);" for name, value in [('rev', SCHEMA_REV), ('aspect', self._project.GetAspect()), ('duration', self._project.GetDuration(False)), ('timelapse', int(self._project.GetTimelapse()))]: if value is not None: cur.execute(query, (name, value)) for audioFile in self._project.GetAudioFiles(): cur.execute(query, ('audiofile', audioFile)) self.__Close(commit=True) self._project.SetFilename(self._filename) # load methods def _SelectAlternatePath(self, imgPath): pass def Load(self, importPath=None): filename = self._filename if not os.path.isfile(filename): return False self.__Connect() cur = self.__GetCursor() fileRev = 1 try: # at the beginning we had no property table cur.execute("SELECT value FROM `property` WHERE name=?", ("rev",)) result = cur.fetchone() if result: fileRev = int(result[0]) except sqlite3.DatabaseError: pass try: cur.execute("SELECT * FROM `picture`") except sqlite3.DatabaseError: self.__Close() return False picList = [] for row in cur: imgFile = row["filename"] imgPath = os.path.dirname(imgFile) self._StepProgress(_(u"Loading '%s' ...") % (os.path.basename(imgFile))) picData = self.__LoadSafe(row, 'data', None) if picData is None: if not (os.path.exists(imgPath) and os.path.isfile(imgFile)): if imgPath not in self.__altPaths: self._SelectAlternatePath(imgPath) imgFile = os.path.join(self.__altPaths.get(imgPath, imgPath), os.path.basename(imgFile)) pic = Picture(imgFile) else: if importPath is None: importPath = os.path.dirname(filename) tmpImg = os.path.join(importPath, os.path.basename(imgFile)) if os.path.isfile(tmpImg): logging.debug('overwrite existing file: %s', tmpImg) if not os.path.isdir(importPath): os.makedirs(importPath) fd = open(tmpImg, 'wb') fd.write(picData) fd.close() pic = Picture(tmpImg) pic.SetWidth(self.__LoadSafe(row, 'width', -1)) pic.SetHeight(self.__LoadSafe(row, 'height', -1)) rect = (row["start_left"], row["start_top"], row["start_width"], row["start_height"]) pic.SetStartRect(rect) rect = (row["target_left"], row["target_top"], row["target_width"], row["target_height"]) pic.SetTargetRect(rect) pic.SetDuration(row["duration"]) pic.SetMovement(self.__LoadSafe(row, "movement", Picture.MOVE_LINEAR)) pic.SetComment(row["comment"]) pic.SetRotation(row['rotation']) pic.SetEffect(self.__LoadSafe(row, 'effect', Picture.EFFECT_NONE)) pic.SetTransition(self.__LoadSafe(row, 'transition', Picture.TRANS_FADE)) pic.SetTransitionDuration(self.__LoadSafe(row, 'transition_duration', 1.0)) self.__LoadThumbnail(pic, row["picture_id"]) picList.append(pic) project = Project(self._filename) project.SetPictures(picList) if fileRev >= 2: project.SetAudioFiles(self.__LoadProperties(cur, "audiofile", str)) project.SetDuration(self.__LoadProperty(cur, "duration", float)) project.SetAspect(self.__LoadProperty(cur, "aspect", str, Aspect.ASPECT_16_9)) project.SetTimelapse(self.__LoadProperty(cur, "timelapse", int, False)) self.__Close() self._project = project return True def __LoadThumbnail(self, pic, picId): ImageCache().RegisterPicture(pic) return thumbNail = None if self.__fileRev >= 3: cur = self.__GetCursor() cur.execute("SELECT * FROM `thumbnail` WHERE picture_id=?", (picId,)) row = cur.fetchone() if row: thumbWidth = row["width"] thumbHeight = row["height"] thumbData = row["data"] thumbNail = PILBackend.ImageFromBuffer((thumbWidth, thumbHeight), thumbData) if thumbNail is None: thumbNail = PILBackend.GetThumbnail(pic, height=120) ImageCache().RegisterPicture(pic, thumbNail) def __LoadSafe(self, row, colName, default): try: return row[colName] except IndexError: return default def __LoadProperty(self, cur, propName, typ, default=None): cur.execute("SELECT value FROM `property` WHERE name=?", (propName,)) result = cur.fetchone() if result: return typ(result[0]) else: return default def __LoadProperties(self, cur, propName, typ): cur.execute("SELECT value " "FROM `property` " "WHERE name=? " "ORDER BY property_id ASC", (propName,)) result = [] for row in cur: if row: result.append(typ(row[0])) return result def SetAltPath(self, imgPath, path): self.__altPaths[imgPath] = path photofilmstrip-3.7.2/photofilmstrip/core/Renderer.py0000644000232200023220000000111013560357351023310 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2011 Jens Goepfert # import photofilmstrip.core.renderer.SingleFileRenderer as SFR import photofilmstrip.core.renderer.GStreamerRenderer as GSR import photofilmstrip.core.renderer.CairoRenderer as CR RENDERERS = [SFR.SingleFileRenderer] RENDERERS.extend([ GSR.VCDFormat, GSR.SVCDFormat, GSR.DVDFormat, GSR.OggTheoraVorbis, GSR.MkvX264AC3, GSR.Mp4X264AAC, GSR.MkvX265AC3]) RENDERERS.extend([ CR.CairoRenderer]) photofilmstrip-3.7.2/photofilmstrip/core/BaseRenderer.py0000644000232200023220000000706013560357351024115 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2011 Jens Goepfert # import io import logging class MetaBaseRenderer(type): def __new__(cls, name, bases, dic): newBaseRendererClass = type.__new__(cls, name, bases, dic) newBaseRendererClass.PROP_VALUES = {} return newBaseRendererClass class BaseRenderer(metaclass=MetaBaseRenderer): def __init__(self): self._outFile = None self._profile = None self._audioFiles = [] self._aspect = None def Init(self, profile, aspect, outFile): self._outFile = outFile self._profile = profile self._aspect = aspect @staticmethod def CheckDependencies(msgList): pass @staticmethod def GetName(): raise NotImplementedError() @staticmethod def GetProperties(): return [] @classmethod def SetProperty(cls, prop, value): if prop in cls.GetProperties(): cls.PROP_VALUES[prop] = value # pylint: disable=no-member else: logging.getLogger(cls.GetName()).warning(_(u"Unknown property: %s"), prop) @classmethod def GetProperty(cls, prop): return cls.PROP_VALUES.get(prop, cls.GetDefaultProperty(prop)) # pylint: disable=no-member @staticmethod def GetDefaultProperty(prop): # pylint: disable=unused-argument return _(u"") @classmethod def Log(cls, level, *args, **kwargs): logging.getLogger(cls.__name__).log(level, *args, **kwargs) def GetTypedProperty(self, prop, pyType, default=None): value = self.__class__.GetProperty(prop) warn = True if value == self.__class__.GetDefaultProperty(prop): if default is not None: value = default warn = False if pyType is bool: if value.lower() in ["0", _(u"no"), "false"]: value = False else: value = True else: try: value = pyType(value) except: if warn: self.__class__.Log( logging.WARN, "{0} must be of type {1}".format(prop, pyType)) value = None return value def SetAudioFiles(self, audioFiles): self._audioFiles = audioFiles def GetAudioFile(self): ''' compatibility ''' if self._audioFiles: return self._audioFiles[0] else: return None def GetAudioFiles(self): return self._audioFiles def GetOutputFile(self): return self._outFile def GetProfile(self): return self._profile def GetFinalizeHandler(self): ''' :rtype: ImageDataFinalizeHandler ''' return ImageDataFinalizeHandler('JPEG', 95) def Finalize(self): raise NotImplementedError() def ToSink(self, data): raise NotImplementedError() def ProcessAbort(self): raise NotImplementedError() class FinalizeHandler(object): def ProcessFinalize(self, pilImg): raise NotImplementedError() class ImageDataFinalizeHandler(FinalizeHandler): def __init__(self, formt, quality=None): self._format = formt self._quality = quality def ProcessFinalize(self, pilImg): res = io.BytesIO() if self._quality: pilImg.save(res, self._format, quality=self._quality) else: pilImg.save(res, self._format) return res.getvalue() photofilmstrip-3.7.2/photofilmstrip/core/exceptions.py0000644000232200023220000000056613560357351023741 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2017 Jens Goepfert # class RenderException(Exception): def __init__(self, msg): Exception.__init__(self) self.message = msg self.msg = msg def GetMessage(self): return self.msg class RendererException(RenderException): pass photofilmstrip-3.7.2/photofilmstrip/core/Subtitle.py0000644000232200023220000000744313560357351023354 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2010 Jens Goepfert # import codecs import os class SubtitleSrt(object): def __init__(self, outFile, factor=1.0): self.__outFile = outFile self.__index = 0 self.__curTime = 0.0 self.__factor = factor def __FormatTime(self, totalSecs): hours = int(totalSecs / 3600.0) minutes = int(totalSecs / 60.0) % 60 seconds = int(totalSecs) % 60 frac = int((totalSecs - int(totalSecs)) * 1000.0) return "%02d:%02d:%02d,%03d" % (hours, minutes, seconds, frac) def __GetPicDuration(self, pic): return pic.GetDuration() * self.__factor def __ProcessPic(self, pic): start = self.__FormatTime(self.__curTime) end = self.__FormatTime(self.__curTime + self.__GetPicDuration(pic)) result = u"%(idx)d\n" \ u"%(start)s --> %(end)s\n" \ u"%(text)s\n" \ u"\n" % {'idx': self.__index, 'start': start, 'end': end, 'text': pic.GetComment().strip()} return result def Start(self, pics): if self.__outFile is None: return fd = codecs.open(self.__outFile + ".srt", 'w', "utf-8", "replace") fd.write(codecs.BOM_UTF8.decode("utf-8")) for pic in pics: self.__index += 1 data = self.__ProcessPic(pic) fd.write(data) self.__curTime += self.__GetPicDuration(pic) + \ (pic.GetTransitionDuration() * self.__factor) fd.close() class SrtParser(object): def __init__(self, path, framerate): self.__path = path self.__framerate = framerate self.__data = [] if os.path.exists(self.__path): self.Parse() def Parse(self): fd = codecs.open(self.__path, 'r', "utf-8") fd.read(len(codecs.BOM_UTF8.decode("utf-8"))) try: while 1: lineIdx = fd.readline() try: _idx = int(lineIdx.strip()) except: break lineTime = fd.readline() start = self.__ParseTime(lineTime[:12]) end = self.__ParseTime(lineTime[17:]) lineTxt = [] while 1: _line = fd.readline().rstrip() if _line: lineTxt.append(_line) else: break self.__data.append((start, end, "\n".join(lineTxt))) finally: fd.close() def __ParseTime(self, text): hours = int(text[:2]) minutes = int(text[3:5]) seconds = float(text[6:].replace(",", ".")) millis = ((((hours * 60) + minutes) * 60) + seconds * 1000.0) return millis def Get(self, pic): msec = pic * (1.0 / self.__framerate) * 1000.0 for start, end, text in self.__data: if msec >= start and msec <= end: return text return "" def testWrite(): from photofilmstrip.core.Picture import Picture p1 = Picture(None) p1.SetComment("this is my first picture") p1.SetDuration(25) p2 = Picture(None) p2.SetComment("this is my second picture") p2.SetDuration(10) p3 = Picture(None) p3.SetComment("this is my third picture") p3.SetDuration(20) p4 = Picture(None) p4.SetComment("this is my third picture") p4.SetDuration(3740) s = SubtitleSrt("output") s.Start([p1, p2, p3, p4]) def testRead(): stp = SrtParser('output.srt', 25.0) for f in range(800): print(f, stp.Get(f)) if __name__ == "__main__": testWrite() testRead() photofilmstrip-3.7.2/photofilmstrip/core/Picture.py0000644000232200023220000001134413560357351023167 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2008 Jens Goepfert # import logging from photofilmstrip.lib.common.ObserverPattern import Observable class Picture(Observable): EFFECT_NONE = 0 EFFECT_BLACK_WHITE = 1 EFFECT_SEPIA = 2 TRANS_NONE = 0 TRANS_FADE = 1 TRANS_ROLL = 2 MOVE_LINEAR = 0 MOVE_ACCEL = 1 MOVE_DELAYED = 2 def __init__(self, filename): Observable.__init__(self) self._filename = filename self._startRect = (0, 0, 1280, 720) self._targetRect = (0, 0, 1280, 720) self._isDummy = False self._duration = 7.0 self._movement = Picture.MOVE_ACCEL self._rotation = 0 self._comment = u"" self._effect = Picture.EFFECT_NONE self._width = -1 self._height = -1 self._trans = Picture.TRANS_FADE self._transDur = 1.0 def Copy(self): clone = Picture(self._filename) clone.SetStartRect(self._startRect[:]) clone.SetTargetRect(self._targetRect[:]) clone.SetDummy(self._isDummy) clone.SetDuration(self._duration) clone.SetRotation(self._rotation) clone.SetComment(self._comment) clone.SetEffect(self._effect) clone.SetWidth(self._width) clone.SetHeight(self._height) clone.SetTransition(self._trans) clone.SetTransitionDuration(self._transDur) return clone def GetFilename(self): return self._filename def SetStartRect(self, rect): if rect == self._startRect or self._isDummy: return self._startRect = rect self.Notify("start") def GetStartRect(self): return self._startRect def SetTargetRect(self, rect): if rect == self._targetRect or self._isDummy: return self._targetRect = rect self.Notify("target") def GetTargetRect(self): return self._targetRect def SetDummy(self, isDummy): self._isDummy = isDummy def IsDummy(self): return self._isDummy def SetDuration(self, duration): if duration == self._duration: return self._duration = duration self.Notify("duration") def GetDuration(self): return self._duration def SetMovement(self, movement): if movement == self._movement: return self._movement = movement self.Notify("movement") def GetMovement(self): return self._movement def SetComment(self, comment): if comment == self._comment: return self._comment = comment self.Notify('comment') def GetComment(self): return self._comment def SetEffect(self, effect): if effect == self._effect: return self._effect = effect self.Notify('effect') self.Notify("bitmap") def GetEffect(self): return self._effect def SetRotation(self, rotation): for __ in range(abs(rotation)): self.__Rotate(rotation > 0) self.Notify("rotation") def GetRotation(self): return self._rotation def SetWidth(self, width): self._width = width def GetWidth(self): if self._width == -1: logging.debug("width not set yet!") return self._width def SetHeight(self, height): self._height = height def GetHeight(self): if self._height == -1: logging.debug("height not set yet!") return self._height def SetTransition(self, transition): if transition == self._trans: return self._trans = transition self.Notify('transition') self.Notify('duration') # if set to no transition def GetTransition(self): return self._trans def SetTransitionDuration(self, transDur): if transDur == self._transDur: return self._transDur = transDur self.Notify('duration') def GetTransitionDuration(self, rawValue=False): if not rawValue and self._trans == Picture.TRANS_NONE: return 0.0 return self._transDur def __Rotate(self, clockwise=True): if clockwise: self._rotation += 1 else: self._rotation -= 1 if self._rotation > 3: self._rotation = 0 if self._rotation < -3: self._rotation = 0 self._width, self._height = self._height, self._width def Rotate(self, clockwise=True): self.__Rotate(clockwise) self.Notify("bitmap") def GetKey(self): key = "%s:%s:%s" % (self.GetFilename(), self.GetRotation(), self.GetEffect()) return key photofilmstrip-3.7.2/photofilmstrip/core/PicturePattern.py0000644000232200023220000000161313560357351024523 0ustar debalancedebalance# -*- coding: utf-8 -*- # # PhotoFilmStrip - Creates movies out of your pictures. # # Copyright (C) 2017 Jens Goepfert # import os import re class PicturePattern: @staticmethod def Create(path): result = None getnum = re.compile(r"(.*?)(\d+)([.].*)") match = getnum.match(os.path.basename(path)) if match is None: result = PicturePattern() else: prefix = match.groups()[0] num = int(match.groups()[1]) postfix = match.groups()[2] digits = len(match.groups()[1]) result = PicturePattern(prefix, num, postfix, digits) return result def __init__(self, prefix=None, num=None, postfix=None, digits=None): self.prefix = prefix self.num = num self.postfix = postfix self.digits = digits def IsOk(self): return self.num is not None