pax_global_header00006660000000000000000000000064134732355740014527gustar00rootroot0000000000000052 comment=8a705702303c6de6aadbd57c83cba6cdf4e9e0ad qwinff-master/000077500000000000000000000000001347323557400136565ustar00rootroot00000000000000qwinff-master/.gitignore000066400000000000000000000001001347323557400156350ustar00rootroot00000000000000/src/qwinff.pro.user /src/Makefile /bin/ /build/ *.o *.qm qwinff-master/.travis.yml000066400000000000000000000006101347323557400157640ustar00rootroot00000000000000language: cpp before_install: - sudo apt-get update - sudo apt-get install libqt4-dev - if [ "$USE_LIBNOTIFY" == 1 ]; then sudo apt-get install libnotify-dev; fi - export DISPLAY=:99.0 - sh -e /etc/init.d/xvfb start - sleep 3 # give xvfb some time to start env: matrix: - USE_LIBNOTIFY=0 - USE_LIBNOTIFY=1 script: - make USE_LIBNOTIFY=$USE_LIBNOTIFY - make check qwinff-master/CHANGELOG.txt000066400000000000000000000064261347323557400157160ustar00rootroot00000000000000Version 0.2.1 ------------- (2015-08-22) - Support building with Qt5 (still compatible with Qt4). - Added Portuguese translation. - MediaPlayerWidget: scoll to seek and click to toggle play/pause. Version 0.2.0 ------------- (2014-02-09) - Use avconv if ffmpeg is not available (experimental) - Added a video-cutting dialog with embedded mplayer. - Use embedded mplayer to preview video-cutting. - Recursively add files when a folder is dragged in. - Fixed default presets for AVI - Added application icon for OS/2 Warp. - Switched to Tango icon theme. Version 0.1.9 ------------- (2013-09-10) - Added output formats: asf, swf, aiff, flac, au, mp2 - Added more output path options. - Added update checker. - Automatically start conversion after adding files (off by default) - Several program parameters can be set in constants.xml. - Minor UI improvements - Can now set version-specific ffmpeg parameters in presets.xml. - Compatible with newer ffmpeg versions ("-sameq" doesn't work since ffmpeg 1.2). - (Windows) Dialog buttons are now also translated. - (Linux) User can now change ffmpeg and sox executable paths in the Options dialog. - (Packaging) Support older Qt versions down to 4.4.3. - (Packaging) Added file "constants.xml". - (Packaging) (Windows) Place Qt translation files in "translations" folder - (Packaging) (Windows) QWinFF now depends on QtNetwork4.dll (for update checker). - (Packaging) (Windows) merge "ffmpeg" and "sox" folder into "tools" folder Version 0.1.8 ------------- (2013-02-13) - Improved video/audio cutting interface. - Fixed some bugs when working with newer ffmpeg versions. Version 0.1.7 ------------- (2012-09-17) - Drag&Drop reordering tasks - Fixed progress-displaying of wav input files. Version 0.1.6 ------------- (2012-08-26) - New Feature: Adjust video speed (requires sox to be installed). - Added Czech translation. - Rearranged toolbar actions. - Fixed: Auto presets got messed up when being edited. - Removed "Auto bitrate" option - Many UI improvements. Version 0.1.5 ------------- (2012-08-17) - New Feature: Shutdown computer when all tasks are done. - Added Italian translation. - Added several ffmpeg presets that don't give extra arguments. Version 0.1.4 ------------- (2012-06-21) - Some minor gui improvements - Include desktop file and application icon in installation. Version 0.1.3 ------------- - Enable users to select the range of the media file to encode. - Fixed video encoding error on some systems due to ffmpeg multithread options. - Removed "-aq 60" option in OGG Vorbis to prevent inflating the output file. Version 0.1.2 ------------- (2012-02-11) - Use notify-send by default. - Made libnotify optional and disabled by default. - Explicit link with gtk+-2.0. (libnotify can be used with either gtk2 or gtk3) - Fixed compilation error with older libnotify versions. Version 0.1.1 ------------- (2012-02-07) - Use libnotify for desktop notification. - Separate preset file for each user. - Save program settings and the user preset file in ~/.qwinff/ - Added Japanese translation. Version 0.1.0 ------------- (2011-11-05) - Disable the auto adjust bitrate option by default as it causes problems sometimes. (2011-11-03) - First stable release. qwinff-master/COPYING.txt000066400000000000000000001045131347323557400155330ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 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 . 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 . qwinff-master/INSTALL.txt000066400000000000000000000066421347323557400155350ustar00rootroot00000000000000Building and Installing QWinFF ============================== QWinFF uses the Qt Toolkit as its graphical interface. You must install QtSDK 4.4.3 or greater to build QWinFF. Currently supported platforms are GNU/Linux and Microsoft Windows. QWinFF depends on several external programs at runtime. Currently these programs are: - ffmpeg (required) - ffprobe (required) - ffplay (optional, for previewing audio/video cutting) - sox (optional, for adjusting audio speed) Building on GNU/Linux --------------------- The build dependencies of QWinFF are listed as follows: - QtSDK 4.4.3 or later - libnotify (only when compiling with `USE_LIBNOTIFY=1`) Decompress the source code; open a terminal and enter the directory. Type `make`. If everything is ok, you may type "make install" to install it. This will install QWinFF in `/usr/`. If `make` fails, it's probably because the Qt3 toolchain is used instead of the Qt4 one. Try to type something like this (just examples): make QMAKE=qmake-qt4 LRELEASE=lrelease-qt4 or make QMAKE=/usr/share/qt4/bin/qmake LRELEASE=/usr/share/qt4/bin/lrelease ### Changing Installation Path By default, QWinFF will be installed to `/usr/`. You can change it by setting `PREFIX`. For example, the following command will install QWinFF in `/usr/local/`: make PREFIX=/usr/local make PREFIX=/usr/local install Please make sure that `PREFIX` in `make` and `make install` are the same. ### Compiling with libnotify *libnotify* is a library that sends desktop notifications. Most GNU/Linux distributions include it by default, and many applications make use of it to notify the user of some events. To compile QWinFF with libnotify, set `USE_LIBNOTIFY=1` when invoking `make` like `make USE_LIBNOTIFY=1`. QWinFF will use libnotify to send notifications if it has been built like this. If libnotify is not used at compile-time, QWinFF will try to use *notify-send*, which is a command-line interface to libnotify. If notify-send is available on the system, it will be used to send notifications. Otherwise, QWinFF will fallback to using Qt MessageBox. Note that libnotify 0.7+ is not compatible with its older versions (0.5.x, 0.6.x). QWinFF will compile with both APIs, but if you compile it with libnotify 0.7, it will only work with libnotify runtime 0.7, and vice versa. Building on Windows ------------------- The following packages are required to build QWinFF on Windows. - Qt4 SDK with MinGW - cygwin First, install *Qt4 SDK* and *cygwin*, and add the paths containing executables of Qt tools and cygwin executables to `PATH`. Extract the source code to a directory and switch to it. Click on `windows_build.bat` to build. (or `windows_build_portable.bat` which will build QWinFF as a portable application) If the build was successful, the output files will be copied to `windows_release\`. (or `windows_release_portable\` for portable version) Copy necessary Qt DLLs to `windows_release\` If you are using the official QtSDK, the DLLs are probably `QtCore4.dll`, `QtGui4.dll`, `QtNetwork4.dll` `libgcc_s_dw2-1.dll`, `libstdc++-6.dll` and `mingwm10.dll`. These files can be found in `\Desktop\Qt\4.x.x\mingw\bin`. Download runtime dependencies (`ffmpeg.exe`, `ffprobe.exe`, etc.) and placed them in `windows_release\tools`. Now you can execute QWinFF by clicking on the executable file. The NSIS script `qwinff.nsi` in `windows_release\` can be used to create an installer. (see http://nsis.sourceforge.net) qwinff-master/Makefile000066400000000000000000000051131347323557400153160ustar00rootroot00000000000000 # Build Parameters # You can change these parameters to customize the build. # Installation Prefix PREFIX?=/usr # Version ID String (displayed after the version string in the about dialog) VIDSTR= ############################### # Variables here are not meant to be changed. # Paths PROJECT_ROOT=$(shell pwd) SRC_DIR=$(PROJECT_ROOT)/src BUILD_DIR=$(PROJECT_ROOT)/build BIN_DIR=$(PROJECT_ROOT)/bin DATA_PATH=$(PREFIX)/share/qwinff TRANSLATION_PATH=$(DATA_PATH)/translations ifeq ($(PROJECT_ROOT),) $(error "PROJECT_ROOT is not set properly") endif # Tools QMAKE=qmake LRELEASE=lrelease # Settings QMAKE_DEFS= DESTDIR=$(BIN_DIR) \ OBJECTS_DIR=$(BUILD_DIR)/obj \ MOC_DIR=$(BUILD_DIR)/moc \ RCC_DIR=$(BUILD_DIR)/rcc \ UI_DIR=$(BUILD_DIR)/ui \ DEFINES+=QT_NO_DEBUG_OUTPUT DEFS= DATA_PATH=\\\"$(DATA_PATH)\\\" \ VERSION_ID_STRING=\\\"$(VIDSTR)\\\" USE_LIBNOTIFY=0 ifneq ($(USE_LIBNOTIFY),0) QMAKE_DEFS += CONFIG+=libnotify endif all: release release: +cd $(SRC_DIR) && $(QMAKE) $(QMAKE_DEFS) qwinff.pro && $(DEFS) $(MAKE) -cd src && $(LRELEASE) qwinff.pro check: cd $(SRC_DIR)/tests && sh run-tests.sh clean: test -n "$(PROJECT_ROOT)" # ensure we don't accidentally remove /bin if $(PROJECT_ROOT) is empty rm -rf $(BIN_DIR) rm -rf $(BUILD_DIR) -cd $(SRC_DIR) && $(MAKE) clean && rm Makefile install: -install -d $(DESTDIR)$(PREFIX)/bin/ install -m 755 bin/qwinff $(DESTDIR)$(PREFIX)/bin/ -install -d $(DESTDIR)$(DATA_PATH) install -m 644 src/presets.xml $(DESTDIR)$(DATA_PATH) install -m 644 src/constants.xml $(DESTDIR)$(DATA_PATH) -install -d $(DESTDIR)$(TRANSLATION_PATH) -install -m 644 src/translations/*.qm $(DESTDIR)$(TRANSLATION_PATH) -install -d $(DESTDIR)$(PREFIX)/share/man/man1 install -m 644 man/qwinff.1 $(DESTDIR)$(PREFIX)/share/man/man1/ -install -d $(DESTDIR)$(PREFIX)/share/applications install -m 644 qwinff.desktop $(DESTDIR)$(PREFIX)/share/applications/ -install -d $(DESTDIR)$(PREFIX)/share/pixmaps install -m 644 src/icons/qwinff_256x256.png $(DESTDIR)$(PREFIX)/share/pixmaps/qwinff.png gzip -9 -f $(DESTDIR)$(PREFIX)/share/man/man1/qwinff.1 uninstall: -rm -f $(DESTDIR)$(PREFIX)/bin/qwinff -rm -f $(DESTDIR)$(DATA_PATH)/presets.xml -rm -f $(DESTDIR)$(DATA_PATH)/constants.xml -rm -f $(DESTDIR)$(TRANSLATION_PATH)/*.qm -rmdir $(DESTDIR)$(TRANSLATION_PATH) -rmdir $(DESTDIR)$(DATA_PATH) -rm -f $(DESTDIR)$(PREFIX)/share/applications/qwinff.desktop -rm -f $(DESTDIR)$(PREFIX)/share/pixmaps/qwinff.png -rm -f $(DESTDIR)$(PREFIX)/share/man/man1/qwinff.1.gz .PHONY: all release check clean install uninstall qwinff-master/README.md000066400000000000000000000041641347323557400151420ustar00rootroot00000000000000QWinFF, FFmpeg GUI front-end based on Qt4 ========================================= Introduction ------------ QWinFF is a GUI for [FFmpeg](http://ffmpeg.org), a powerful media converter. FFmpeg can read audio and video files in various formats and convert them into other formats. QWinFF features an intuitive graphical interface and a rich set of presets to help you convert media files within a few clicks. Advanced users can also adjust conversion parameters in detail. For compiling and installing QWinFF, please refer to INSTALL.txt. License ------- Copyright (C) 2011 Timothy Lin 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. Acknowledgements ---------------- Icons located in src/icons are taken from [GNOME Project](http://www.gnome.org/)(GPL/LGPL), [Tango Project](http://tango.freedesktop.org/)(Public Domain), and [GNOME Colors](http://code.google.com/p/gnome-colors/)(GPL). This program uses Qt, you can find more information about Qt on [its website](http://qt-project.org/). This program relies on [FFmpeg](ffmpeg.org) to do conversion. License: LGPL/GPL Some audio-processing functionalities depends on [SoX](http://sox.sourceforge.net), the Swiss Army knife of sound processing programs. License: LGPL/GPL Other free software projects that influenced the development of QWinFF: - [WinFF](http://winff.org) - Presets, Ideas - [Sinthgunt](http://code.google.com/p/sinthgunt) - Presets, Parsing FFmpeg Output - [SMPlayer](http://smplayer.sourceforge.net) - Qt Skills, Project Structure - [Clementine](http://www.clementine-player.org) - Qt Skills Proprietary software that influenced the development of QWinFF - [FormatFactory](http://www.formatoz.com) - Ideas, Appearance qwinff-master/man/000077500000000000000000000000001347323557400144315ustar00rootroot00000000000000qwinff-master/man/qwinff.1000066400000000000000000000023011347323557400160010ustar00rootroot00000000000000.TH qwinff 1 "October 2011" "QWinFF" "QWinFF" .SH NAME QWinFF \- A media converter GUI .SH SYNOPSIS .B qwinff [file1 [file2]] ... .SH DESCRIPTION QWinFF is a GUI for FFmpeg [#ffmpeg]_, a command line media converter. FFmpeg can read audio and video files in various formats and convert them into other formats. For example, you can convert video downloaded from the Internet into audio files for your mobile phone. QWinFF comes with a set of predefined presets to help you quickly convert media files without having to know the details. These presets defines what arguments should be passed to *ffmpeg* for each output format. In case you want to adjust the details (bitrate, audio volume, etc.), QWinFF lets you edit conversion parameters for each individual task. .SH OPTIONS .TP .B [file1 [file2]] ... Input files separated by spaces. These files can be any kind of media files that FFmpeg can decode. .SH SEE ALSO \fBffmpeg\fR(1), \fBffprobe\fR(1), \fBsox\fR(1) .SH AUTHOR .TP The author of QWinFF is Timothy Lin .TP The QWinFF logo was designed by kuanyui .SH BUGS Please submit bugs to \fBhttps://github.com/qwinff/qwinff/issues\fR or \fBlzh9102@gmail.com\fR qwinff-master/qwinff.desktop000066400000000000000000000027261347323557400165520ustar00rootroot00000000000000[Desktop Entry] Categories=AudioVideo;AudioVideoEditing; Comment=Convert between media file formats Comment[zh_TW]=轉換影音檔案格式 Comment[zh_CN]=转换影音文件格式 Comment[cs]=Převést mezi formáty souborů Comment[es]=Convertir entre formados de archivos Comment[it]=Converte file multimediali in vari formati Comment[fr]=Convertit entre formats de fichier multimédia Comment[ja]=音声とビデオファイルの変換 Comment[ro]=Converteşte formatele de fișiere media Comment[ru]=Преобразование между медиа-форматами Comment[tr]=Çokluortam dosya biçimleri arasında dönüştürme Comment[ar]=تحويل بين صيغ ملفات الوسائط Comment[hu]=Média fájlformátumok átalakítása Comment[pl]=Konwersja plików multimedialnych, pomiędzy różnymi formatami Name=QWinFF GenericName=Media Converter GenericName[zh_TW]=影音轉檔器 GenericName[zh_CN]=影音转换器 GenericName[cs]=Převodník médií GenericName[es]=Convertidor de Medios GenericName[it]=Convertitore di file multimediali GenericName[fr]=Convertisseur de fichier multimédia GenericName[ja]=メディア変換 GenericName[ro]=Media Converter GenericName[ru]=Медиа-конвертер GenericName[tr]=Çokluortam Dönüştürücü GenericName[ar]=محول الوسائط GenericName[hu]=Média átalakító GenericName[pl]=Konwerter mediów Exec=qwinff %U Icon=qwinff Type=Application Terminal=false X-KDE-StartupNotify=true X-SuSE-translate=true qwinff-master/qwinff.nsi.in000066400000000000000000000104061347323557400162710ustar00rootroot00000000000000!include "MUI.nsh" !define APPNAME "QWinFF" !define VERSION "@QWINFF_VERSION@" !define DESCRIPTION "A cross platform media converter GUI" !define UNINSTALLER "uninstall.exe" !define LICENSE "license.txt" !define CHANGELOG "changelog.txt" Name "${APPNAME}" OutFile "qwinff_${VERSION}-setup.exe" InstallDir $PROGRAMFILES\QWinFF RequestExecutionLevel admin var StartMenuFolder !insertmacro MUI_PAGE_WELCOME !insertmacro MUI_PAGE_DIRECTORY !define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKLM" !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\QWinFF" !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder" !define MUI_FINISHPAGE_RUN !define MUI_FINISHPAGE_RUN_NOTCHECKED !define MUI_FINISHPAGE_RUN_FUNCTION "LaunchProgram" !define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED !define MUI_FINISHPAGE_SHOWREADME $INSTDIR\${CHANGELOG} !insertmacro MUI_PAGE_STARTMENU Application $StartMenuFolder !insertmacro MUI_PAGE_INSTFILES !insertmacro MUI_PAGE_FINISH !insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_UNPAGE_INSTFILES !insertmacro MUI_UNPAGE_FINISH ;Languages !insertmacro MUI_LANGUAGE "English" !insertmacro MUI_LANGUAGE "TradChinese" !insertmacro MUI_LANGUAGE "Japanese" !insertmacro MUI_LANGUAGE "Italian" !insertmacro MUI_LANGUAGE "Czech" !insertmacro MUI_LANGUAGE "French" !insertmacro MUI_LANGUAGE "German" !insertmacro MUI_LANGUAGE "Spanish" !insertmacro MUI_LANGUAGE "SpanishInternational" !insertmacro MUI_LANGUAGE "SimpChinese" !insertmacro MUI_LANGUAGE "Korean" !insertmacro MUI_LANGUAGE "Dutch" !insertmacro MUI_LANGUAGE "Danish" !insertmacro MUI_LANGUAGE "Swedish" !insertmacro MUI_LANGUAGE "Norwegian" !insertmacro MUI_LANGUAGE "NorwegianNynorsk" !insertmacro MUI_LANGUAGE "Finnish" !insertmacro MUI_LANGUAGE "Greek" !insertmacro MUI_LANGUAGE "Russian" !insertmacro MUI_LANGUAGE "Portuguese" !insertmacro MUI_LANGUAGE "PortugueseBR" !insertmacro MUI_LANGUAGE "Polish" !insertmacro MUI_LANGUAGE "Ukrainian" !insertmacro MUI_LANGUAGE "Slovak" !insertmacro MUI_LANGUAGE "Croatian" !insertmacro MUI_LANGUAGE "Bulgarian" !insertmacro MUI_LANGUAGE "Hungarian" !insertmacro MUI_LANGUAGE "Thai" !insertmacro MUI_LANGUAGE "Romanian" !insertmacro MUI_LANGUAGE "Latvian" !insertmacro MUI_LANGUAGE "Macedonian" !insertmacro MUI_LANGUAGE "Estonian" !insertmacro MUI_LANGUAGE "Turkish" !insertmacro MUI_LANGUAGE "Lithuanian" !insertmacro MUI_LANGUAGE "Slovenian" !insertmacro MUI_LANGUAGE "Serbian" !insertmacro MUI_LANGUAGE "SerbianLatin" !insertmacro MUI_LANGUAGE "Arabic" !insertmacro MUI_LANGUAGE "Farsi" !insertmacro MUI_LANGUAGE "Hebrew" !insertmacro MUI_LANGUAGE "Indonesian" !insertmacro MUI_LANGUAGE "Mongolian" !insertmacro MUI_LANGUAGE "Luxembourgish" !insertmacro MUI_LANGUAGE "Albanian" !insertmacro MUI_LANGUAGE "Breton" !insertmacro MUI_LANGUAGE "Belarusian" !insertmacro MUI_LANGUAGE "Icelandic" Section SetOutPath $INSTDIR # Program Files File qwinff.exe File presets.xml File constants.xml File *.dll File ${LICENSE} file ${CHANGELOG} CreateDirectory translations CreateDirectory tools SetOutPath $INSTDIR\translations File translations\*.qm SetOutPath $INSTDIR\tools File tools\* # Create Uninstaller WriteUninstaller "$INSTDIR\${UNINSTALLER}" # Create Desktop Shortcut CreateShortcut "$DESKTOP\QWinFF.lnk" "$INSTDIR\qwinff.exe" !insertmacro MUI_STARTMENU_WRITE_BEGIN Application # Start Menu Shortcuts CreateDirectory "$SMPROGRAMS\$StartMenuFolder" CreateShortcut "$SMPROGRAMS\$StartMenuFolder\QWinFF.lnk" "$INSTDIR\qwinff.exe" CreateShortcut "$SMPROGRAMS\$StartMenuFolder\Uninstall QWinFF.lnk" "$INSTDIR\${UNINSTALLER}" !insertmacro MUI_STARTMENU_WRITE_END SectionEnd Function LaunchProgram ExecShell "" "$INSTDIR\qwinff.exe" FunctionEnd # Uninstaller Section "un.Uninstaller" Delete $INSTDIR\${UNINSTALLER} Delete $INSTDIR\qwinff.exe Delete $INSTDIR\presets.xml Delete $INSTDIR\constants.xml Delete $INSTDIR\*.dll Delete $INSTDIR\${LICENSE} Delete $INSTDIR\${CHANGELOG} Delete $INSTDIR\tools\* RmDir $INSTDIR\tools Delete $INSTDIR\translations\* RmDir $INSTDIR\translations RmDir $INSTDIR # Remove the installation directory if it's empty. Delete "$DESKTOP\QWinFF.lnk" !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuFolder Delete "$SMPROGRAMS\$StartMenuFolder\*.lnk" RmDir "$SMPROGRAMS\$StartMenuFolder" DeleteRegKey /ifempty HKLM "Software\QWinFF" SectionEnd qwinff-master/src/000077500000000000000000000000001347323557400144455ustar00rootroot00000000000000qwinff-master/src/appicon.rc000066400000000000000000000000561347323557400164250ustar00rootroot00000000000000IDI_ICON1 ICON DISCARDABLE "icons/appicon.ico"qwinff-master/src/appicon_os2.rc000066400000000000000000000000361347323557400172060ustar00rootroot00000000000000ICON 1 "icons/appicon_os2.ico"qwinff-master/src/constants.xml000066400000000000000000000123751347323557400172130ustar00rootroot00000000000000 false avi vfw divx mpg mpeg m1v m2v mpv dv 3gp mov mp4 m4v mqv dat vcd ogg ogm ogv asf wmv bin iso vob mkv nsv ram flv rm swf ts rmvb dvr-ms m2t m2ts rec mts webm mp3 ogg wav wma ac3 ra ape flac http://qwinff.github.io/latest.xml false false qwinff_output 30 AddFiles StartConversion StopConversion Retry RetryAll | RemoveSelectedItems RemoveCompletedItems | OpenOutputFolder Poweroff 5 4096 #C8DCFF
#96C8DC
#6496A0 #000000 #FFFFFF5F
3.0 #D2D2D2 #EBEBEB #828282 #FAFAFA #D8F4A6 #A8E854 #008A00 #DAFAA7 50 QSlider::groove:horizontal { border: 0px solid #999999; height: 8px; background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #B1B1B1, stop:1 #c4c4c4); margin: -1px; padding:0 6px; } QSlider::handle:horizontal { background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #ffffff stop:1 #aaaaaa); border: 1px solid #939393; width: 16px; margin: -5px; border-radius: 8px; } QSlider::handle:horizontal:hover { background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #ffffff stop:1 #cccccc); border: 1px solid #aaaaaa; box-shadow:0px 0px 3px #ffffff; } QSlider::add-page:horizontal { background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #d2d2d2, stop:1 #ebebeb); border: 1px solid #939393; border-radius: 2px; margin: 0px; } QSlider::sub-page:horizontal { background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #54aae8, stop:1#b6d3e8 ); border: 1px solid #2f82be; border-radius: 2px; margin: 0px; }
qwinff-master/src/converter/000077500000000000000000000000001347323557400164545ustar00rootroot00000000000000qwinff-master/src/converter/audiofilter.cpp000066400000000000000000000066571347323557400215050ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "audiofilter.h" #include "conversionparameters.h" #include "exepath.h" #include "ffmpeginterface.h" #include #include #include #ifdef OPERATION_TIMEOUT # define TIMEOUT OPERATION_TIMEOUT #else # define TIMEOUT 3000 #endif /* SoX provides much more audio-processing options than ffmpeg, yet it doesn't accept as many formats as ffmpeg does. In this pipeline, format conversion is done by ffmpeg and audio processing is done by SoX. The audio-filtering pipeline consists of two stages: 1. Audio Extraction command: ffmpeg -i -vn -f - input: infile output: stdout Extract the audio stream from the input file, convert it into sox format, and pipe it to stdout. 2. Audio Filtering command: sox -t - -t - input: stdin output: stdout Process the audio stream using SoX. The output is piped to stdout. */ AudioFilter::AudioFilter(QObject *parent) : QObject(parent), m_extractAudioProc(new QProcess(this)), m_soxProc(new QProcess(this)) { QSet muxing, demuxing; FFmpegInterface::getSupportedMuxingFormats(muxing); FFmpegInterface::getSupportedDemuxingFormats(demuxing); m_useSoxFormat = muxing.contains("sox") && demuxing.contains("sox"); } bool AudioFilter::start(ConversionParameters& params, QProcess *dest) { QStringList ffmpeg_param; QStringList sox_param; const char *fmt = m_useSoxFormat ? "sox" : "flac"; if (m_soxProc->state() != QProcess::NotRunning) { m_soxProc->kill(); m_soxProc->waitForFinished(TIMEOUT); } if (m_extractAudioProc->state() != QProcess::NotRunning) { m_extractAudioProc->kill(); m_extractAudioProc->waitForFinished(TIMEOUT); } // ffmpeg process settings ffmpeg_param << "-i" << params.source << "-vn" << "-f" << fmt << "-"; m_extractAudioProc->setStandardOutputProcess(m_soxProc); // sox process settings sox_param << "-t" << fmt << "-" << "-t" << fmt << "-"; if (params.speed_scaling) { sox_param << "tempo" << QString::number(params.speed_scaling_factor); } m_soxProc->setStandardOutputProcess(dest); qDebug() << "ffmpeg" << ffmpeg_param; qDebug() << "sox" << sox_param; // start the two processes m_extractAudioProc->start(ExePath::getPath("ffmpeg"), ffmpeg_param); m_soxProc->start(ExePath::getPath("sox"), sox_param); return m_extractAudioProc->waitForStarted(TIMEOUT) && m_soxProc->waitForStarted(TIMEOUT); } bool AudioFilter::available() { QProcess sox_process; sox_process.start(ExePath::getPath("sox"), QStringList()); return sox_process.waitForStarted(TIMEOUT); } qwinff-master/src/converter/audiofilter.h000066400000000000000000000027761347323557400211500ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef AUDIOFILTER_H #define AUDIOFILTER_H #include class QProcess; class ConversionParameters; class AudioFilter : public QObject { Q_OBJECT public: explicit AudioFilter(QObject *parent = 0); /** * Start the audio-filtering process pipeline. * @param param the conversion parameter * @param dest the process to receive the output from stdin */ bool start(ConversionParameters& param, QProcess *dest); /** * Check if execution conditions are met. * @return true if AudioFilter works, false otherwise. */ static bool available(); signals: public slots: private slots: private: QProcess *m_extractAudioProc; QProcess *m_soxProc; bool m_useSoxFormat; }; #endif // AUDIOFILTER_H qwinff-master/src/converter/conversionparameters.cpp000066400000000000000000000124721347323557400234370ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "conversionparameters.h" #include "mediaprobe.h" #include #include #include #define TIMEOUT 3000 namespace { int parseFFmpegArguments(QStringList& args, int index, ConversionParameters& result) { int used_arg_count = 0; try { QString& arg = args[index]; /* BEGIN MACRO DEFINITIONS */ #define CHECK_OPTION_BEGIN if (false) do { } while (0) #define CHECK_OPTION(argument) else if (arg == argument) // absorb options like "-option" with no parameter // set result.property to value #define CHECK_OPTION_1(argument, property, value) \ else if (arg == argument) do { result.property = value; used_arg_count = 1; } while (0) // absorb options like "-option str" where "str" is a string. // set result.property to the next token #define CHECK_OPTION_2(argument, property) \ else if (arg == argument) do { \ result.property = args[index+1]; \ used_arg_count = 2; } while (0) // absorb options like "-option value" where "value" has numeric meaning // convertmethod is the corresponding conversion method of QString // set result.property to the converted value of the next token #define CHECK_OPTION_2_METHOD(argument, property, convertmethod) \ else if (arg == argument) do { \ QString nextarg = args[index+1]; \ nextarg.replace(QRegExp("[a-z]"), ""); /* remove units */ \ result.property = nextarg.convertmethod(); \ used_arg_count = 2; } while (0) #define CHECK_OPTION_2_FUNCTION(argument, property, convertfunction) \ else if (arg == argument) do { \ QString nextarg = args[index+1]; \ nextarg.replace(QRegExp("[a-z]"), ""); /* remove units */ \ result.property = convertfunction(nextarg); \ used_arg_count = 2; } while (0) #define CHECK_OPTION_END do { } while (0) /* END MACRO DEFINITIONS */ if (arg[0] == '-') { CHECK_OPTION_BEGIN; // Threads CHECK_OPTION_2_METHOD("-threads", threads, toInt); // Audio Options CHECK_OPTION_1("-an", disable_audio, true); CHECK_OPTION_2_METHOD("-ab", audio_bitrate, toInt); CHECK_OPTION_2_METHOD("-ar", audio_sample_rate, toInt); CHECK_OPTION_2_METHOD("-ac", audio_channels, toInt); CHECK_OPTION_2_METHOD("-vol", audio_volume, toInt); // Video Options CHECK_OPTION_1("-vn", disable_video, true); CHECK_OPTION_1("-sameq", video_same_quality, true); CHECK_OPTION_1("-deinterlace", video_deinterlace, true); CHECK_OPTION_2_METHOD("-b", video_bitrate, toInt); CHECK_OPTION_2_METHOD("-croptop", video_crop_top, toInt); CHECK_OPTION_2_METHOD("-cropbottom", video_crop_bottom, toInt); CHECK_OPTION_2_METHOD("-cropleft", video_crop_left, toInt); CHECK_OPTION_2_METHOD("-cropright", video_crop_right, toInt); /* TODO: add begin time and duration */ // width and height are in the same parameter (for example: "-s 800x600") CHECK_OPTION("-s") { QRegExp pattern("([0-9]+)x([0-9]+)"); if (pattern.indexIn(args[index+1]) != -1) { result.video_width = pattern.cap(1).toInt(); result.video_height = pattern.cap(2).toInt(); used_arg_count = 2; } } CHECK_OPTION_END; } } catch (...) { return 0; } return used_arg_count; #undef CHECK_OPTION_BEGIN #undef CHECK_OPTION_1 #undef CHECK_OPTION_2 #undef CHECK_OPTION_2_METHOD #undef CHECK_OPTION_2_FUNCTION #undef CHECK_OPTION_END } } void ConversionParameters::copyConfigurationFrom(const ConversionParameters &src) { QString orig_src = source; QString orig_dest = destination; *this = src; source = orig_src; destination = orig_dest; } ConversionParameters ConversionParameters::fromFFmpegParameters(const QString ¶ms_str) { ConversionParameters result; QStringList args = params_str.split(" ", QString::SkipEmptyParts); for (int i=0; i * * 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 . */ #ifndef CONVERSIONPARAMETERS_H #define CONVERSIONPARAMETERS_H #include #include class ConversionParameters { public: /* Generic Options */ QString source; ///< name of source file QString destination; ///< name of destination file int threads; ///< how many threads to use in conversion bool disable_audio; bool copy_audio; int audio_bitrate; int audio_sample_rate; bool audio_keep_sample_rate; ///< whether to keep original audio sample rate int audio_channels; int audio_volume; ///< output volume in binary percent (256 is normal, 512 is double) bool disable_video; bool copy_video; bool video_same_quality; ///< whether to keep all video quality (-sameq option in ffmpeg) bool video_deinterlace; int video_bitrate; int video_width; int video_height; int video_crop_top, video_crop_bottom, video_crop_left, video_crop_right; unsigned int time_begin, time_end; /* FFmpeg Specific Options */ /*! Additional options passed to the ffmpeg transcoder. These options will be overriden by other specific options. */ QString ffmpeg_options; /* MEncoder Specific Options */ //QString mencoder_oac; // output audio codec //QString mencoder_ovc; // output video codec //QString mencoder_of; // output format /* Speed (FFmpeg + SoX) */ /*! Turn on/off speed scaling. If speed scaling is on, speed_scaling_factor will be used to change the speed of the video and audio stream. */ bool speed_scaling; /*! Speed scaling factor. 1.0 is normal speed; less than 1.0, slow down; greater than 1.0, speed up. This parameter is only used when speed_scaling is true. */ double speed_scaling_factor; /*! Copy all fields except source, destination files from src * @param src the source to copy from */ void copyConfigurationFrom(const ConversionParameters& src); /*! Generate a ConversionParameters from ffmpeg command line options. This function ignores input and output file options. */ static ConversionParameters fromFFmpegParameters(const QString& params_str); static ConversionParameters fromFFmpegParameters(const char *params_str); ConversionParameters() : threads(0), disable_audio(false), copy_audio(false), audio_bitrate(0), audio_sample_rate(0), audio_keep_sample_rate(false), audio_channels(0), audio_volume(0), disable_video(false), copy_video(false), video_same_quality(false), video_deinterlace(false), video_bitrate(0), video_width(0), video_height(0), video_crop_top(0), video_crop_bottom(0), video_crop_left(0), video_crop_right(0), time_begin(0), time_end(0), speed_scaling(false), speed_scaling_factor(1.0) { } }; #endif // CONVERSIONPARAMETERS_H qwinff-master/src/converter/converterinterface.cpp000066400000000000000000000016761347323557400230620ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "converterinterface.h" ConverterInterface::ConverterInterface(QObject *parent) : QObject(parent) { } QString ConverterInterface::errorMessage() const { return QString(); } qwinff-master/src/converter/converterinterface.h000066400000000000000000000045121347323557400225170ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef CONVERTERINTERFACE_H #define CONVERTERINTERFACE_H #include #include #include #include "conversionparameters.h" /** Abstract Converter Interface Derived class must implement the virtual functions to provide converter details. */ class ConverterInterface : public QObject { Q_OBJECT public: explicit ConverterInterface(QObject *parent = 0); virtual QString executableName() const = 0; virtual void reset() = 0; virtual QProcess::ProcessChannel processReadChannel() const = 0; /*! Fill parameter list and determine whether the configuration needs * additional audio filtering. This function must be called before * starting the process. Implementations of this function should * do necessary setup, such as obtaining stream duration for calculating * progress. * @param param [in] the conversion parameter * @param list [out] the command-line parameter list * @param needs_audio_filter [out] whether AudioFilter should be used. The return value is true * implies that the parameter list makes the conversion process * wait for data input from stdin. */ virtual void fillParameterList(const ConversionParameters& param, QStringList& list , bool *needs_audio_filter) = 0; virtual void parseProcessOutput(const QString& line) = 0; virtual double progress() const = 0; virtual QString errorMessage() const; signals: void progressRefreshed(double percentage); public slots: }; #endif // CONVERTERINTERFACE_H qwinff-master/src/converter/exepath.cpp000066400000000000000000000046641347323557400206300ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "exepath.h" #include #include #include #ifdef OPERATION_TIMEOUT #define TIMEOUT OPERATION_TIMEOUT #else #define TIMEOUT 30000 #endif namespace { typedef QMap Map; Map program_path; } void ExePath::setPath(QString program, QString path) { program_path.insert(program, path); } QString ExePath::getPath(QString program) { if (program_path.contains(program)) return program_path[program]; else Q_ASSERT_X(false, "ExePath::getPath" , QString("Program path of '%1' has not been set.") .arg(program).toStdString().c_str()); return ""; } bool ExePath::checkProgramAvailability(QString program) { if (!program_path.contains(program)) // the program is not set return false; QProcess proc; QStringList param; // try to run the program proc.start(ExePath::getPath(program), param); if (!proc.waitForStarted(TIMEOUT)) return false; // failed to start the program // successfully started the program, kill it immediately proc.kill(); proc.waitForFinished(TIMEOUT); return true; } void ExePath::saveSettings() { QSettings settings; foreach (QString name, program_path.keys()) { QString path = program_path[name]; settings.setValue("exepath/" + name, path); } } void ExePath::loadSettings() { QSettings settings; foreach (QString name, program_path.keys()) { QString path = settings.value("exepath/" + name , program_path[name]).toString(); program_path[name] = path; } } QList ExePath::getPrograms() { return program_path.keys(); } qwinff-master/src/converter/exepath.h000066400000000000000000000025761347323557400202750ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef EXEPATH_H #define EXEPATH_H #include #include class ExePath { public: static void setPath(QString program, QString path); static QString getPath(QString program); /** * @brief Check whether the program can be executed. * @param program the program to test */ static bool checkProgramAvailability(QString program); /** * Save the paths using QSettings */ static void saveSettings(); /** * Load the paths using QSettings */ static void loadSettings(); static QList getPrograms(); private: ExePath(); }; #endif // EXEPATH_H qwinff-master/src/converter/ffmpeginterface.cpp000066400000000000000000000525331347323557400223150ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "ffmpeginterface.h" #include "mediaprobe.h" #include "exepath.h" #include #include #include #include #include // timeout before force-terminating ffmpeg #ifdef OPERATION_TIMEOUT # define TIMEOUT OPERATION_TIMEOUT #else # define TIMEOUT 3000 #endif namespace { namespace patterns { const char progress[] = "size=\\s*([0-9]+)kB\\s+time=\\s*([0-9]+\\.[0-9]+)\\s+bitrate=\\s*([0-9]+\\.[0-9]+)kbits/s"; enum Progress_1_Fields { PROG_1_TIME = 2 }; const char progress2[] // another possible format where time is represented as hh:mm:ss = "size=\\s*([0-9]+)kB\\s+time=\\s*([0-9][0-9]):([0-9][0-9]):([0-9][0-9](\\.[0-9][0-9]?)?)\\s+" "bitrate=\\s*([0-9]+\\.[0-9]+)kbits/s"; enum Progress_2_Fields { PROG_2_HR = 2, PROG_2_MIN, PROG_2_SEC }; const char duration[] = "Duration:\\s+([0-9][0-9]):([0-9][0-9]):([0-9][0-9](\\.[0-9][0-9]?)?)"; } // namespace patterns namespace info { QAtomicInt is_encoders_read(false); volatile bool ffmpeg_exist = false; QString ffmpeg_version; QString ffmpeg_codec_info; QString ffmpeg_format_info; QList audio_encoders; QList video_encoders; QList subtitle_encoders; QList muxing_formats; QList demuxing_formats; namespace inner { /** * @brief Extract encoder information from codec description. * @param target Extracted encoder names will be pushed into @a target * @param s the codec description string * @return number of encoders found */ int find_encoders_in_desc(QStringList& target, const QString& s) { const char *keyword_begin = "(encoders:"; const char *keyword_end = ")"; int begin = s.indexOf(keyword_begin); if (begin < 0) return 0; // encoder name not found in description begin += strlen(keyword_begin); int end = s.indexOf(keyword_end, begin); if (end < 0) return 0; // error, mission ')' int length = end - begin; // encoder_str contains encoder names separated by spaces, and // may contain leading and trailing spaces. QString encoders_str = s.mid(begin, length); // split encoder_str into encoder names and skip whitespaces QStringList encoders = encoders_str.split(' ', QString::SkipEmptyParts); foreach (QString s, encoders) { target.push_back(s); // fill codec names into the list } return encoders.size(); } bool read_ffmpeg_codecs(const char *flag) { QProcess ffmpeg_process; QStringList parameters; parameters.push_back(QString(flag)); ffmpeg_process.setReadChannel(QProcess::StandardOutput); //qDebug() << ExePath::getPath("ffmpeg") << parameters.join(" "); ffmpeg_process.start(ExePath::getPath("ffmpeg"), parameters); // Wait until ffmpeg has started. if (!ffmpeg_process.waitForStarted(TIMEOUT)) { return false; } // Wait until ffmpeg has finished. if (!ffmpeg_process.waitForFinished(TIMEOUT)) { return false; } if (ffmpeg_process.exitCode() != 0) { return false; // error } // Find all available encoders QRegExp pattern("[ D]E([ VAS])...\\s+([^ ]+)\\s*(.*)$"); QStringList encoder_list; // temporary storage of encoder names const int AV_INDEX = 1; const int CODEC_NAME_INDEX = 2; const int CODEC_DESC = 3; ffmpeg_codec_info.clear(); while (ffmpeg_process.canReadLine()) { QString line(ffmpeg_process.readLine()); ffmpeg_codec_info.append(line); if (pattern.indexIn(line) != -1) { QString av = pattern.cap(AV_INDEX); QString codec = pattern.cap(CODEC_NAME_INDEX); QString desc = pattern.cap(CODEC_DESC); // extract codec names encoder_list.clear(); if (!find_encoders_in_desc(encoder_list, desc)) encoder_list.push_back(codec); foreach (QString codec_name, encoder_list) { if (av == "A") { // audio encoder //qDebug() << "Audio Codec: " + codec_name; audio_encoders.push_back(codec_name); } else if (av == "V") { // video encoder //qDebug() << "Video Codec: " + codec_name; video_encoders.push_back(codec_name); } else if (av == "S") { // subtitle encoder //qDebug() << "Subtitle Codec: " + codec_name; subtitle_encoders.push_back(codec_name); } } } } return true; } bool read_ffmpeg_version() { QProcess ffmpeg_process; QStringList parameters; parameters.push_back(QString("-version")); //qDebug() << ExePath::getPath("ffmpeg") << parameters.join(" "); ffmpeg_process.start(ExePath::getPath("ffmpeg"), parameters); ffmpeg_process.waitForStarted(TIMEOUT); ffmpeg_process.waitForFinished(TIMEOUT); ffmpeg_version = QString(ffmpeg_process.readAll()); return true; } bool read_ffmpeg_formats() { QProcess ffmpeg_process; QStringList parameters; parameters << "-formats"; ffmpeg_process.start(ExePath::getPath("ffmpeg"), parameters); ffmpeg_process.waitForStarted(TIMEOUT); ffmpeg_process.waitForFinished(TIMEOUT); if (ffmpeg_process.exitCode() != 0) return false; muxing_formats.clear(); demuxing_formats.clear(); ffmpeg_format_info.clear(); QRegExp pattern("^ ([ D])([ E]) ([^ ]+)\\s+(.*)$"); const int INDEX_DEMUX = 1; const int INDEX_MUX = 2; const int INDEX_NAME = 3; //const int INDEX_DETAIL = 4; while (ffmpeg_process.canReadLine()) { QString line(ffmpeg_process.readLine()); ffmpeg_format_info.append(line); if (pattern.indexIn(line) != -1) { QString name = pattern.cap(INDEX_NAME); if (pattern.cap(INDEX_DEMUX) == "D") demuxing_formats.append(name); if (pattern.cap(INDEX_MUX) == "E") muxing_formats.append(name); } } return true; } } // namespace inner /* Read FFmpeg information. * (1) Check available encoder from "ffmpeg -codecs" and "ffmpeg -formats". * (2) Read ffmpeg version information by "ffmpeg -version" command. * Once the information is correctly read, it never * execute ffmpeg to acquire the information again. */ void read_ffmpeg_info() { if (!is_encoders_read.testAndSetAcquire(false, true)) return; // Skip the operation if the information was already read. qDebug() << "Read FFmpeg Information"; /* Older versions of ffmpeg has no "-codecs" flag and report all * supported codecs by "-formats". Recent versions report codecs * by "-codecs" flag, so we check "-codecs" first. If ffmpeg * returns an error, retry with flag "-formats". */ if (!inner::read_ffmpeg_codecs("-codecs") && !inner::read_ffmpeg_codecs("-formats")) { is_encoders_read = false; // allow retry when failed return; } if (!inner::read_ffmpeg_version()) return; if (!inner::read_ffmpeg_formats()) return; ffmpeg_exist = true; } } // namespace info // extract error message from the line QString extract_errmsg(const QString& line) { QRegExp pattern("^[^:]*:(.*)$"); const int INDEX_MESSAGE = 1; if (pattern.indexIn(line) != -1) return pattern.cap(INDEX_MESSAGE).trimmed(); else return ""; } // scale sec with speed_factor if scale == true double scale_time(unsigned int sec, bool scale, double speed_factor) { if (!sec) return 0; else if (scale) return sec / speed_factor; // (speed *= 2) means (time /= 2) else return sec; } } // anonymous namespace struct FFmpegInterface::Private { double duration; double progress; QString stringBuffer; QRegExp progress_pattern; QRegExp progress_pattern_2; QRegExp duration_pattern; bool encoders_read; QList audio_encoders; QList video_encoders; QList subtitle_encoders; QString errmsg; Private() : duration(0), progress(0) , progress_pattern(patterns::progress) , progress_pattern_2(patterns::progress2) , duration_pattern(patterns::duration) , encoders_read(false) { } bool check_progress(const QString&); QStringList getOptionList(const ConversionParameters&, bool*, bool*); }; /*! Check whether the output line is a progress line. If it is, update p->progress and return true. Otherwise, keep the value of p->progress and return false. */ bool FFmpegInterface::Private::check_progress(const QString& line) { QRegExp& pattern = progress_pattern; int index = pattern.indexIn(line); if (index != -1) { const double t = pattern.cap(patterns::PROG_1_TIME).toDouble(); // calculate progress progress = (t / duration) * 100; return true; } else { // try another pattern QRegExp& alternate_pattern = progress_pattern_2; if (alternate_pattern.indexIn(line) != -1) { const int hour = alternate_pattern.cap(patterns::PROG_2_HR).toInt(); const int min = alternate_pattern.cap(patterns::PROG_2_MIN).toInt(); const double sec = alternate_pattern.cap(patterns::PROG_2_SEC).toDouble(); const double t = hour*3600 + min*60 + sec; progress = (t / duration) * 100; return true; } } errmsg = line; // save the last output line return false; } /** * Convert a ConversionParameters object into ffmpeg command-line option list. * @param o the parameter object * @return a QStringList containing command-line options * @note This function is time-consuming because it calls ffprobe to obtain * media information. */ QStringList FFmpegInterface::Private::getOptionList(const ConversionParameters &o , bool *needs_audio_filter , bool *success) { MediaProbe probe; bool bNeedsAudioFilter; if (!probe.run(o.source, TIMEOUT)) { if (success) *success = false; return QStringList(); } bNeedsAudioFilter = o.speed_scaling && !o.disable_audio && probe.hasAudio(); QStringList list; // overwrite if file exists list.append("-y"); if (!bNeedsAudioFilter) { /* in this configuration, input is read from file arguments: -i */ list << "-i" << o.source; } else { /* In this configuration, video (if any) is read from file and audio is read from stdin if source file contains video: arguments: -i -i - -map 0: -map 1 if source file has no video stream: arguments: -i - */ if (probe.hasVideo() && !o.disable_video) list << "-i" << o.source << "-i" << "-" << "-map" << QString("0:%1").arg(probe.videoStreamIndex()) << "-map" << "1"; else list << "-i" << "-"; } // enable experimental codecs by default list << "-strict" << "experimental"; /* ==== Additional Options ==== */ if (!o.ffmpeg_options.isEmpty()) { QList additional_options = o.ffmpeg_options.split(" ", QString::SkipEmptyParts); foreach (QString opt, additional_options) list.append(opt); } if (o.threads >= 2) { list.append("-threads"); list.append(QString::number(o.threads)); } /* ==== Audio/Video Options ==== */ // Audio Options if (o.disable_audio) { list.append("-an"); // no audio } else if (o.copy_audio) { // copy audio data (no re-encode) list.append("-acodec"); list.append("copy"); } else { // audio enabled // audio bitrate in kb/s if (o.audio_bitrate > 0) { list.append("-ab"); list.append(QString("%1k").arg(o.audio_bitrate)); } // audio sample rate in hz if (o.audio_sample_rate > 0) { list.append("-ar"); int sample_rate = o.audio_sample_rate; if (o.audio_keep_sample_rate && !probe.error() && probe.audioSampleRate() != 0) { sample_rate = probe.audioSampleRate(); qDebug() << "Apply probed sample rate: " + QString::number(sample_rate); } list.append(QString("%1").arg(sample_rate)); } // audio channels if (o.audio_channels > 0) { list.append("-ac"); list.append(QString("%1").arg(o.audio_channels)); } // volume // 256 is normal volume if (o.audio_volume > 0 && o.audio_volume != 256) { list.append("-vol"); list.append(QString("%1").arg(o.audio_volume)); } } // Video Options if (o.disable_video || !probe.hasVideo()) { list.append("-vn"); // no video } else if (o.copy_video) { // copy video data (no re-encode) list.append("-vcodec"); list.append("copy"); } else { // video enabled // same video quality as source if (o.video_same_quality) { list.append("-sameq"); } // deinterlace if (o.video_deinterlace) { list.append("-deinterlace"); } // video bitrate if (o.video_bitrate > 0) { list.append("-b"); list.append(QString("%1k").arg(o.video_bitrate)); } // video dimensions if (o.video_width > 0 && o.video_height > 0) { list.append("-s"); list.append(QString("%1x%2").arg(o.video_width).arg(o.video_height)); } if (o.video_crop_top > 0) { list.append("-croptop"); list.append(QString("%1").arg(o.video_crop_top)); } if (o.video_crop_bottom > 0) { list.append("-cropbottom"); list.append(QString("%1").arg(o.video_crop_bottom)); } if (o.video_crop_left > 0) { list.append("-cropleft"); list.append(QString("%1").arg(o.video_crop_left)); } if (o.video_crop_right > 0) { list.append("-cropright"); list.append(QString("%1").arg(o.video_crop_right)); } /* -vf "setpts=<1/rate>*PTS": video filter to change video speed <1/rate> is the reciprocal of the scaling factor (1.0 is original speed) */ if (o.speed_scaling) list << "-vf" << QString("setpts=%1*PTS").arg(1/o.speed_scaling_factor); } // Time Options /* Scale begin time and end time if speed_scaling is on. * scaled_time_begin and scaled_time_end are doubles, so never compare time * (ex. time == 0) by them. Compare using o.time_begin and o.time_end instead. */ double scaled_time_begin = scale_time(o.time_begin, o.speed_scaling, o.speed_scaling_factor); double scaled_time_end = scale_time(o.time_end, o.speed_scaling, o.speed_scaling_factor); /* -ss time_begin When used as an output option, ffmpeg decodes but discards input until timestamp reaches time_begin */ if (o.time_begin > 0) { list.append("-ss"); list.append(QString("%1").arg(scaled_time_begin)); } /* -t time_duration Stop writing the output after its duration reaches time_duration */ if (o.time_end > 0) { Q_ASSERT(o.time_end >= o.time_begin); double scaled_duration = scaled_time_end - scaled_time_begin; list.append("-t"); list.append(QString("%1").arg(scaled_duration)); } // destination file list.append(o.destination); // record duration duration = probe.mediaDuration(); if (o.speed_scaling) duration /= o.speed_scaling_factor; if (needs_audio_filter) *needs_audio_filter = bNeedsAudioFilter; if (success) *success = true; return list; } FFmpegInterface::FFmpegInterface(QObject *parent) : ConverterInterface(parent), p(new Private) { } FFmpegInterface::~FFmpegInterface() { delete p; } // virtual functions QString FFmpegInterface::executableName() const { return ExePath::getPath("ffmpeg"); } void FFmpegInterface::reset() { p->duration = 0; p->progress = 0; p->stringBuffer.clear(); p->errmsg.clear(); } QProcess::ProcessChannel FFmpegInterface::processReadChannel() const { return QProcess::StandardError; } bool FFmpegInterface::needsAudioFiltering(const ConversionParameters& param) const { return !param.disable_audio && param.speed_scaling; } void FFmpegInterface::fillParameterList(const ConversionParameters ¶m, QStringList &list , bool *needs_audio_filter) { bool success; // TODO: return success list = p->getOptionList(param, needs_audio_filter, &success); } void FFmpegInterface::parseProcessOutput(const QString &data) { //qDebug() << data; // split incoming data by [end of line] or [carriage return] QStringList lines(data.split(QRegExp("[\r\n]"), QString::KeepEmptyParts)); if (!p->stringBuffer.isEmpty()) { // prepend buffered data lines.front().prepend(p->stringBuffer); p->stringBuffer.clear(); } if (!lines.back().isEmpty()) { // buffer incomplete data p->stringBuffer = lines.back(); lines.back().clear(); } QStringList::iterator it = lines.begin(); for (; it!=lines.end(); ++it) { // parse lines QString& line = *it; if (line.isEmpty()) continue; if (p->check_progress(line)) { emit progressRefreshed(p->progress); continue; } } } double FFmpegInterface::progress() const { return p->progress; } QString FFmpegInterface::errorMessage() const { return extract_errmsg(p->errmsg); } bool FFmpegInterface::getAudioEncoders(QList &target) { info::read_ffmpeg_info(); if (!info::ffmpeg_exist) return false; target = info::audio_encoders; return true; } bool FFmpegInterface::getAudioEncoders(QSet &target) { QList encoder_list; if (!getAudioEncoders(encoder_list)) return false; target = QSet::fromList(encoder_list); return true; } bool FFmpegInterface::getVideoEncoders(QList &target) { info::read_ffmpeg_info(); if (!info::ffmpeg_exist) return false; target = info::video_encoders; return true; } bool FFmpegInterface::getVideoEncoders(QSet &target) { QList encoder_list; if (!getVideoEncoders(encoder_list)) return false; target = QSet::fromList(encoder_list); return true; } bool FFmpegInterface::getSubtitleEncoders(QList &target) { info::read_ffmpeg_info(); if (!info::ffmpeg_exist) return false; target = info::subtitle_encoders; return true; } QString FFmpegInterface::getFFmpegVersionInfo() { info::read_ffmpeg_info(); return info::ffmpeg_version; } QString FFmpegInterface::getFFmpegCodecInfo() { info::read_ffmpeg_info(); return info::ffmpeg_codec_info; } QString FFmpegInterface::getFFmpegFormatInfo() { info::read_ffmpeg_info(); return info::ffmpeg_format_info; } bool FFmpegInterface::getSupportedMuxingFormats(QSet &target) { info::read_ffmpeg_info(); if (!info::ffmpeg_exist) return false; target = QSet::fromList(info::muxing_formats); return true; } bool FFmpegInterface::getSupportedDemuxingFormats(QSet &target) { info::read_ffmpeg_info(); if (!info::ffmpeg_exist) return false; target = QSet::fromList(info::demuxing_formats); return true; } bool FFmpegInterface::hasFFmpeg() { info::read_ffmpeg_info(); return info::ffmpeg_exist; } void FFmpegInterface::refreshFFmpegInformation() { info::is_encoders_read = false; info::read_ffmpeg_info(); } bool FFmpegInterface::getSubtitleEncoders(QSet &target) { QList encoder_list; if (!getSubtitleEncoders(encoder_list)) return false; target = QSet::fromList(encoder_list); return true; } qwinff-master/src/converter/ffmpeginterface.h000066400000000000000000000045351347323557400217610ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef FFMPEGINTERFACE_H #define FFMPEGINTERFACE_H #include #include #include #include "conversionparameters.h" #include "converterinterface.h" class FFmpegInterface : public ConverterInterface { Q_OBJECT public: explicit FFmpegInterface(QObject *parent = 0); virtual ~FFmpegInterface(); QString executableName() const; void reset(); QProcess::ProcessChannel processReadChannel() const; bool needsAudioFiltering(const ConversionParameters& param) const; void fillParameterList(const ConversionParameters& param, QStringList& list , bool *needs_audio_filter); void parseProcessOutput(const QString& data); double progress() const; QString errorMessage() const; static bool getAudioEncoders(QList& target); static bool getAudioEncoders(QSet& target); static bool getVideoEncoders(QList& target); static bool getVideoEncoders(QSet& target); static bool getSubtitleEncoders(QList& target); static bool getSubtitleEncoders(QSet& target); static QString getFFmpegVersionInfo(); static QString getFFmpegCodecInfo(); static QString getFFmpegFormatInfo(); static bool getSupportedMuxingFormats(QSet& target); static bool getSupportedDemuxingFormats(QSet& target); static bool hasFFmpeg(); static void refreshFFmpegInformation(); signals: void progressRefreshed(double percentage); public slots: private: Q_DISABLE_COPY(FFmpegInterface) struct Private; Private *p; }; #endif // FFMPEGINTERFACE_H qwinff-master/src/converter/mediaconverter.cpp000066400000000000000000000107701347323557400221740ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "mediaconverter.h" #include "ffmpeginterface.h" #include "audiofilter.h" #include "mediaprobe.h" #include "exepath.h" #include "services/filepathoperations.h" #include #include #include #include #ifdef OPERATION_TIMEOUT # define TIMEOUT OPERATION_TIMEOUT #else # define TIMEOUT 3000 #endif MediaConverter::MediaConverter(QObject *parent) : QObject(parent), m_pConv(new FFmpegInterface(this)), m_pAudioFilter(new AudioFilter(this)) { connect(&m_proc, SIGNAL(readyRead()) , this, SLOT(readProcessOutput())); connect(&m_proc, SIGNAL(finished(int,QProcess::ExitStatus)) , this, SLOT(convertProgressFinished(int,QProcess::ExitStatus))); connect(m_pConv, SIGNAL(progressRefreshed(double)) , this, SLOT(convertProgressRefreshed(double))); } MediaConverter::~MediaConverter() { this->stop(); } // public methods bool MediaConverter::start(ConversionParameters param) { if (m_proc.state() == QProcess::NotRunning) { m_stopped = false; emit progressRefreshed(0); // Save output filename. m_outputFileName = param.destination; // Generate temporary output filename. m_tmpFileName = FilePathOperations::GenerateTempFileName(m_outputFileName); // Output to temporary file. param.destination = m_tmpFileName; m_pConv->reset(); QStringList list; bool needs_audio_filter; m_proc.setReadChannel(m_pConv->processReadChannel()); m_pConv->fillParameterList(param, list, &needs_audio_filter); if (needs_audio_filter) { qDebug() << "Audio filter is turned on."; m_pAudioFilter->start(param, &m_proc); } qDebug() << m_pConv->executableName() << list.join(" "); m_proc.start(m_pConv->executableName(), list); return m_proc.waitForStarted(TIMEOUT); } return false; } void MediaConverter::stop() { if (m_proc.state() == QProcess::Running) { m_stopped = true; m_proc.kill(); m_proc.waitForFinished(-1); // wait indefinitely } } double MediaConverter::progress() { return m_pConv->progress(); } /*! Check whether external programs are available * - ffmpeg * - ffprobe */ bool MediaConverter::checkExternalPrograms(QString &msg) { //: %1 is a computer program QString errmsg = tr("%1 not found."); // check ffmpeg if (!FFmpegInterface::hasFFmpeg()) { msg = errmsg.arg(ExePath::getPath("ffmpeg")); return false; } // check ffprobe if (!MediaProbe::available()) { // The probe failed to start. msg = errmsg.arg(ExePath::getPath("ffprobe")); return false; } // sox is optional return true; } QString MediaConverter::errorMessage() const { return m_pConv->errorMessage(); } // private slots void MediaConverter::readProcessOutput() { m_pConv->parseProcessOutput(QString(m_proc.readAll())); } void MediaConverter::convertProgressFinished(int exitcode, QProcess::ExitStatus) { QFile output_file(m_outputFileName); QFile tmp_file(m_tmpFileName); if (exitcode == 0 && tmp_file.exists() && !m_stopped) { // succeed output_file.remove(); if (!tmp_file.rename(m_outputFileName)) // Rename tmpfile to outputfile. exitcode = -1; // If the rename fails, return a negative exitcode. } else { // failed tmp_file.remove(); // Remove tmpfile if conversion failed. } if (exitcode == 0 && !m_stopped) emit progressRefreshed(100); // 100% finished else emit progressRefreshed(0); emit finished(exitcode); } void MediaConverter::convertProgressRefreshed(double percentage) { emit progressRefreshed((int)percentage); } // private methods qwinff-master/src/converter/mediaconverter.h000066400000000000000000000045101347323557400216340ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef MEDIACONVERTER_H #define MEDIACONVERTER_H #include #include #include "conversionparameters.h" class ConversionParameters; class ConverterInterface; class AudioFilter; class MediaConverter : public QObject { Q_OBJECT public: explicit MediaConverter(QObject *parent = 0); ~MediaConverter(); /*! * Start the conversion process. * @return If the process is successfully started, the function returns true * Otherwise, the function returns false. */ bool start(ConversionParameters param); void stop(); double progress(); /*! * Check whether required external programs (e.g. ffmpeg) * is available. * @param msg [out] Output message if an error occurs. * @return true if all dependencies are met, false otherwise. */ static bool checkExternalPrograms(QString &msg); /*! * Get the error message if the conversion fails. * @return the last output line ffmpeg prints, likely to be * an error message */ QString errorMessage() const; signals: void finished(int exitcode); void progressRefreshed(int percentage); public slots: private slots: void readProcessOutput(); void convertProgressFinished(int, QProcess::ExitStatus); void convertProgressRefreshed(double); private: Q_DISABLE_COPY(MediaConverter) QProcess m_proc; ConversionParameters m_convParam; ConverterInterface *m_pConv; AudioFilter *m_pAudioFilter; QString m_outputFileName; QString m_tmpFileName; bool m_stopped; }; #endif // MEDIACONVERTER_H qwinff-master/src/converter/mediaprobe.cpp000066400000000000000000000270341347323557400212750ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "mediaprobe.h" #include "exepath.h" #include #include #include #ifdef OPERATION_TIMEOUT # define TIMEOUT OPERATION_TIMEOUT #else # define TIMEOUT 3000 #endif #define SECONDS_PER_HOUR 3600 #define SECONDS_PER_MINUTE 60 namespace { namespace patterns { // META const char meta[] = "Duration: ([0-9]+):([0-9]+):([0-9]+\\.[0-9]*)(, start: ([0-9]+\\.[0-9]*))?, bitrate: ([0-9]+) kb/s"; const char META_HOUR_INDEX = 1; // matched type: integer const char META_MINUTE_INDEX = 2; // matched type: integer const char META_SECOND_INDEX = 3; // matched type: double const char META_START_INDEX = 5; // matched type: double const char META_BITRATE_INDEX = 6; // matched type: integer // AUDIO const char audio[] = "Stream #([0-9]+).([0-9]+).*: Audio:\\s*([^,]*),\\s*([0-9]+)\\s*Hz,\\s*([^,]*),\\s*([^,]*),\\s*([0-9]+)\\s*kb/s"; const int AUDIO_STREAM_INDEX = 2; // matched type: integer const int AUDIO_CODEC_INDEX = 3; // matched type: string const int AUDIO_SAMPLERATE_INDEX = 4; // matched type: integer const int AUDIO_CHANNELS_INDEX = 5; // matched type: string const int AUDIO_BITRATE_INDEX = 7; // matched type: integer const char audio_check[] = "^\\s*Stream .* Audio"; // VIDEO const char video[] = "Stream #([0-9]+).([0-9]+).*: Video:\\s*([^,]*),\\s*([^,]*),\\s*([0-9]+)x([0-9]+)[^,]*" ",\\s*([0-9]+)[^,]*,\\s*([0-9]+(\\.[0-9]*)?)"; const int VIDEO_STREAM_INDEX = 2; // matched type: integer const int VIDEO_CODEC_INDEX = 3; // matched type: string const int VIDEO_WIDTH_INDEX = 5; // matched type: integer const int VIDEO_HEIGHT_INDEX = 6; // matched type: integer const int VIDEO_BITRATE_INDEX = 7; // matched type: integer const int VIDEO_FRAMERATE_INDEX = 8; // matched type: double const char video_check[] = "^\\s*Stream .* Video"; // SUBTITLE const char subtitle[] = "Stream [^(]*\\(([^:]*)\\): Subtitle:"; } // namespace patterns } // namespace /* Media Information Structures The parse() method in the structures should return true if it accepts the input, or return false otherwise. */ // stores information of the whole file struct MetaInformation { double duration; ///< duration in seconds double start; ///< start time in seconds int bitrate; ///< bitrate in kb/s QRegExp pattern; MetaInformation() : pattern(patterns::meta) { clear(); } void clear() { duration = 0; start = 0; bitrate = 0; } bool parse(const QString& line) { int index = pattern.indexIn(line); if (index != -1) { int hour = pattern.cap(patterns::META_HOUR_INDEX).toInt(); int minute = pattern.cap(patterns::META_MINUTE_INDEX).toInt(); double second = pattern.cap(patterns::META_SECOND_INDEX).toDouble(); duration = hour * SECONDS_PER_HOUR + minute * SECONDS_PER_MINUTE + second; start = pattern.cap(patterns::META_START_INDEX).toDouble(); bitrate = pattern.cap(patterns::META_BITRATE_INDEX).toInt(); return true; } return false; } }; // stores information of the audio stream struct AudioInformation { bool has_audio; int sample_rate; ///< sample rate in kb/s int bitrate; ///< bitrate in kb/s int channels; ///< number of channels QString codec; QRegExp pattern; QRegExp pattern_check; AudioInformation() : pattern(patterns::audio) , pattern_check(patterns::audio_check) { clear(); } void clear() { has_audio = false; sample_rate = 0; bitrate = 0; channels = 2; // default 2 channels codec.clear(); } bool parse(const QString& line) { int index = pattern.indexIn(line); if (index != -1) { has_audio = true; codec = pattern.cap(patterns::AUDIO_CODEC_INDEX); sample_rate = pattern.cap(patterns::AUDIO_SAMPLERATE_INDEX).toInt(); bitrate = pattern.cap(patterns::AUDIO_BITRATE_INDEX).toInt(); // extract number of channels QString channels_field = pattern.cap(patterns::AUDIO_CHANNELS_INDEX); QRegExp channels_pattern("([0-9]+)\\s+channel"); if (channels_pattern.indexIn(channels_field) != -1) { channels = channels_pattern.cap(1).toInt(); } else if (channels_field.indexOf("stereo") != -1) { channels = 2; } else if (channels_field.indexOf("mono") != -1) { channels = 1; } return true; } // audio existence must be correct if (pattern_check.indexIn(line) != -1) { has_audio = true; codec = "unknown"; } return false; } }; // stores information of video streams struct VideoInformation { bool has_video; int stream_index; int width; int height; int bitrate; ///< bitrate in kb/s double frame_rate; ///< frame rate in fps QString codec; QString format; QRegExp pattern; QRegExp pattern_check; VideoInformation() : pattern(patterns::video) , pattern_check(patterns::video_check) { clear(); } void clear() { has_video = false; stream_index = 0; width = height = 0; bitrate = 0; frame_rate = 0; codec.clear(); format.clear(); } bool parse(const QString& line) { int index = pattern.indexIn(line); if (index != -1) { has_video = true; stream_index = pattern.cap(patterns::VIDEO_STREAM_INDEX).toInt(); width = pattern.cap(patterns::VIDEO_WIDTH_INDEX).toInt(); height = pattern.cap(patterns::VIDEO_HEIGHT_INDEX).toInt(); bitrate = pattern.cap(patterns::VIDEO_BITRATE_INDEX).toInt(); frame_rate = pattern.cap(patterns::VIDEO_FRAMERATE_INDEX).toDouble(); codec = pattern.cap(patterns::VIDEO_CODEC_INDEX); return true; } // video existence must be correct if (pattern_check.indexIn(line) != -1) { has_video = true; codec = "unknown"; } return false; } }; // stores information of subtitle streams struct SubtitleInformation { bool has_subtitle; QRegExp pattern; SubtitleInformation() : pattern(patterns::subtitle) { } void clear() { has_subtitle = false; } bool parse(const QString& line) { int index = pattern.indexIn(line); if (index != -1) { has_subtitle = true; } return false; // reject all inputs } }; /* MediaProbe::Private Structure */ struct MediaProbe::Private { MetaInformation metainfo; AudioInformation audioinfo; VideoInformation videoinfo; SubtitleInformation subtitleinfo; QProcess ffprobe_proc; int exitcode; void clear(); void parse_line(const QString& line); }; // clear stored data void MediaProbe::Private::clear() { metainfo.clear(); audioinfo.clear(); videoinfo.clear(); subtitleinfo.clear(); exitcode = 0; } // parse process output void MediaProbe::Private::parse_line(const QString &line) { if (metainfo.parse(line)) return; if (audioinfo.parse(line)) return; if (videoinfo.parse(line)) return; if (subtitleinfo.parse(line)) return; } /* MediaProbe Class */ // constructor MediaProbe::MediaProbe(QObject *parent) : QObject(parent), p(new Private) { connect(&p->ffprobe_proc, SIGNAL(finished(int)) , this, SLOT(m_proc_finished(int))); } MediaProbe::~MediaProbe() { stop(); delete p; } bool MediaProbe::available() { MediaProbe probe; // Try to start the probe to see if the probing program is available. if (!probe.start("")) return false; return true; } // Start ffprobe process. bool MediaProbe::start(const QString& filename) { if (p->ffprobe_proc.state() == QProcess::NotRunning) { QStringList list; //list.push_back("-show_format"); //list.push_back("-convert_tags"); list.push_back(filename); p->ffprobe_proc.setReadChannel(QProcess::StandardError); p->ffprobe_proc.start(ExePath::getPath("ffprobe"), list); return p->ffprobe_proc.waitForStarted(TIMEOUT); } return false; } bool MediaProbe::start(const char *filename) { return start(QString(filename)); } bool MediaProbe::run(const QString &filename, int timeout) { return start(filename) && wait(timeout) && !error(); } // Wait for the process to finish. bool MediaProbe::wait(int msecs) { if (p->ffprobe_proc.state() == QProcess::Running) { return p->ffprobe_proc.waitForFinished(msecs); } return false; } // Kill the process and block until it terminates. void MediaProbe::stop() { if (p->ffprobe_proc.state() == QProcess::Running) { p->ffprobe_proc.kill(); p->ffprobe_proc.waitForFinished(-1); // wait indefinitely } } bool MediaProbe::error() const { return p->exitcode != 0; } // Media Information int MediaProbe::hours() const { return int(p->metainfo.duration) / 3600; } int MediaProbe::minutes() const { return (int(p->metainfo.duration) % 3600) / 60; } double MediaProbe::seconds() const { return p->metainfo.duration - hours()*3600 - minutes()*60; } double MediaProbe::mediaDuration() const { return p->metainfo.duration; } int MediaProbe::mediaBitRate() const { return p->metainfo.bitrate; } // Audio Information bool MediaProbe::hasAudio() const { return p->audioinfo.has_audio; } int MediaProbe::audioSampleRate() const { return p->audioinfo.sample_rate; } int MediaProbe::audioBitRate() const { return p->audioinfo.bitrate; } int MediaProbe::audioChannels() const { return p->audioinfo.channels; } const QString& MediaProbe::audioCodec() const { return p->audioinfo.codec; } // Video Information bool MediaProbe::hasVideo() const { return p->videoinfo.has_video; } int MediaProbe::videoStreamIndex() const { return p->videoinfo.stream_index; } int MediaProbe::videoWidth() const { return p->videoinfo.width; } int MediaProbe::videoHeight() const { return p->videoinfo.height; } int MediaProbe::videoBitRate() const { return p->videoinfo.bitrate; } double MediaProbe::videoFrameRate() const { return p->videoinfo.frame_rate; } const QString& MediaProbe::videoCodec() const { return p->videoinfo.codec; } // Subtitle Information bool MediaProbe::hasSubtitle() const { return p->subtitleinfo.has_subtitle; } // Private Slots void MediaProbe::m_proc_finished(int exitcode) { p->exitcode = exitcode; if (exitcode == 0) { // If the process finished normally, parse its output. p->clear(); while (p->ffprobe_proc.canReadLine()) { QString line = QString(p->ffprobe_proc.readLine()).trimmed(); p->parse_line(line); } } emit process_finished(); } qwinff-master/src/converter/mediaprobe.h000066400000000000000000000076761347323557400207540ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef MEDIAPROBE_H #define MEDIAPROBE_H #include class MediaProbe : public QObject { Q_OBJECT public: explicit MediaProbe(QObject *parent = 0); virtual ~MediaProbe(); /*! Determine whether the probing program (ffprobe) is available. */ static bool available(); /*! Start the probe on a file. * @param filename the name of the file to probe * @return If the process is started successfully, the function returns true. * Otherwise, it returns false. * @note This function does not block until the process has finished. * run() is the blocking alternative to this function. * @see run() */ bool start(const QString& filename); bool start(const char* filename); /*! Start the probing process and block until the process has finished. * @param filename the file to probe * @param timeout timeout value in milliseconds * @return If the probing is successful, the function returns true. * Otherwise, it returns false. * @note This function returns false when either the probing process * cannot be started (usually because ffprobe not installed correctly) * or the probed file is not recognized by ffprobe; so one cannot * distinguish these two only by looking at the return value of this * function. */ bool run(const QString& filename, int timeout = 3000); /*! Block until the process has finished or until msecs milliseconds has passed. * @param msecs timeout * @return If the function exits because the process has finished, the function returns true. * Otherwise, it returns false. */ bool wait(int msecs = 3000); /*! Force the probe to stop. * The function will block until the probe is stopped. */ void stop(); /*! Returns whether the previous probing process has an error. * For example, if the file is not recognized by ffprobe, the * function returns false. If ffprobe has recognized the file * and successfully extracts information from it, the function * returns true. */ bool error() const; /*! Returns the **hour** part of the duration */ int hours() const; /*! Returns the **minutes** part of the duration * The value is within 0 and 59(inclusive) */ int minutes() const; /*! Returns the **seconds** part of the duration * The value is within 0.0 and 60.0(non-inclusive) */ double seconds() const; double mediaDuration() const; int mediaBitRate() const; bool hasAudio() const; int audioSampleRate() const; int audioBitRate() const; int audioChannels() const; const QString& audioCodec() const; bool hasVideo() const; int videoStreamIndex() const; int videoWidth() const; int videoHeight() const; int videoBitRate() const; double videoFrameRate() const; const QString& videoCodec() const; bool hasSubtitle() const; signals: /*! This signal is fired when the probe finishes. */ void process_finished(); public slots: private slots: void m_proc_finished(int); private: Q_DISABLE_COPY(MediaProbe) struct Private; Private *p; }; #endif // MEDIAPROBE_H qwinff-master/src/converter/presets.cpp000066400000000000000000000205671347323557400206570ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "presets.h" #include "ffmpeginterface.h" #include "../services/versioncompare.h" #include #include #include #include struct Presets::Private { QMultiMap presets; ///< map extension to presets /*! @brief Store the previously assigned id * Each preset is assigned a unique id to indicate the order it is read. * This id is later used in sorting presets. * When a new preset is read from the file, increment m_prev_id and assign * it to the new preset, i.e. preset.id = ++m_prev_id; */ unsigned int m_prev_id; Private() : m_prev_id(0) { } bool parseXmlFile(QFile& file, bool removeUnavailableCodecs); bool parsePreset(QXmlStreamReader& xml); bool readElementData(QXmlStreamReader& xml, Preset& target); void removeUnavailablePresets(); QString getVersionAttribute(const QXmlStreamAttributes& attrs); }; bool Presets::Private::parseXmlFile(QFile &file, bool removeUnavailableCodecs) { Q_ASSERT_X(file.isOpen(), "parse xml file", "file is not opened"); QXmlStreamReader xml(&file); presets.clear(); int level = 0; // depth of current tag QString top_level_tag; // name of the tag at level 0 while (!xml.atEnd() && !xml.hasError()) { QXmlStreamReader::TokenType token = xml.readNext(); if (token == QXmlStreamReader::StartDocument) { continue; // skip StartDocument token } else if (token == QXmlStreamReader::StartElement) { if (level == 0) { top_level_tag = xml.name().toString(); ++level; } else if (level == 1 && top_level_tag == "presets") { if (!parsePreset(xml)) return false; } } else if (token == QXmlStreamReader::EndElement) { --level; } } if (xml.hasError()) { return false; } if (removeUnavailableCodecs) removeUnavailablePresets(); return true; } bool Presets::Private::parsePreset(QXmlStreamReader &xml) { if (xml.tokenType() != QXmlStreamReader::StartElement) return false; QString tag_name = xml.name().toString(); Preset preset; xml.readNext(); while (xml.tokenType() != QXmlStreamReader::EndElement || xml.name() != tag_name) { if (xml.tokenType() == QXmlStreamReader::StartElement) { if (!readElementData(xml, preset)) return false; } xml.readNext(); } // Add preset to the multimap. Use extension as the key. if (!preset.extension.isEmpty()) { preset.id = ++m_prev_id; // assign an id to preset presets.insert(preset.extension, preset); } return true; } bool Presets::Private::readElementData(QXmlStreamReader &xml, Preset& target) { if (xml.tokenType() != QXmlStreamReader::StartElement) return false; QString property_name = xml.name().toString(); QString versionrange_str; if (property_name == "params") versionrange_str = getVersionAttribute(xml.attributes()); xml.readNext(); if (xml.tokenType() != QXmlStreamReader::Characters) return true; // empty content QString property_value = xml.text().toString().trimmed(); if (property_name == "label") { target.label = property_value; } else if (property_name == "params") { Version ffmpegVersion(FFmpegInterface::getFFmpegVersionInfo()); if (versionrange_str.isEmpty() || VersionRange(versionrange_str).containsVersion(ffmpegVersion)) { target.parameters = property_value; } } else if (property_name == "extension") { target.extension = property_value; } else if (property_name == "category") { target.category = property_value; } return true; } void Presets::Private::removeUnavailablePresets() { QSet audio_encoders, video_encoders, subtitle_encoders; if (!FFmpegInterface::getAudioEncoders(audio_encoders)) Q_ASSERT(audio_encoders.isEmpty()); if (!FFmpegInterface::getVideoEncoders(video_encoders)) Q_ASSERT(video_encoders.isEmpty()); if (!FFmpegInterface::getSubtitleEncoders(subtitle_encoders)) Q_ASSERT(subtitle_encoders.isEmpty()); QRegExp audio_codec_pattern("-acodec\\s+([^ ]+)"); QRegExp video_codec_pattern("-vcodec\\s+([^ ]+)"); QRegExp subtitle_codec_pattern("-scodec\\s+([^ ]+)"); QMultiMap::iterator it = presets.begin(); while (it!=presets.end()) { bool remove = false; QString& params = it.value().parameters; // Check unavailable audio presets if (audio_codec_pattern.indexIn(params) != -1) { if (!audio_encoders.contains(audio_codec_pattern.cap(1))) { remove = true; } } // Check unavailable video presets if (!remove && video_codec_pattern.indexIn(params) != -1) { if (!video_encoders.contains(video_codec_pattern.cap(1))) { remove = true; } } // Check unavailable subtitle presets if (!remove && subtitle_codec_pattern.indexIn(params) != -1) { if (!subtitle_encoders.contains(subtitle_codec_pattern.cap(1))) { remove = true; } } if (remove) // remove the preset if any of the codecs are unavailable presets.erase(it++); else ++it; } } QString Presets::Private::getVersionAttribute(const QXmlStreamAttributes &attrs) { QString version; foreach (QXmlStreamAttribute attr, attrs) { if (attr.name() == "version") { version = attr.value().toString(); break; } } return version; } Presets::Presets(QObject *parent) : QObject(parent), p(new Private) { } Presets::~Presets() { delete p; } bool Presets::readFromFile(const QString &filename, bool removeUnavailableCodecs) { qDebug() << "Reading preset file: " << filename; QFile xmlfile(filename); if (!xmlfile.open(QIODevice::ReadOnly | QIODevice::Text)) { qDebug() << "Failed to read preset file: " << filename; return false; } //qDebug() << "Finished reading preset file."; bool ret = p->parseXmlFile(xmlfile, removeUnavailableCodecs); xmlfile.close(); return ret; } bool Presets::readFromFile(const char *filename, bool removeUnavailableCodecs) { return readFromFile(QString(filename), removeUnavailableCodecs); } bool Presets::getExtensions(QList &target) const { QList presetList = p->presets.values(); qSort(presetList); // sort presets by id target.clear(); QString extension(""); foreach (Preset preset, presetList) { if (extension != preset.extension) { // new extension appears extension = preset.extension; target.push_back(extension); } } // remove duplicate entries target = target.toSet().toList(); // sort target qSort(target); return true; } bool Presets::findPresetById(unsigned int id, Preset &target) const { QMultiMap::iterator it = p->presets.begin(); for (; it!=p->presets.end(); ++it) { if (it->id == id) { target = *it; return true; } } return false; } bool Presets::getPresets(QList &target) { target.clear(); target = p->presets.values(); return true; } bool Presets::getPresets(const QString &extension, QList &target) { target = p->presets.values(extension); return true; } bool Presets::getPresets(const char *extension, QList &target) { return getPresets(QString(extension), target); } qwinff-master/src/converter/presets.h000066400000000000000000000046371347323557400203240ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef PRESETS_H #define PRESETS_H #include #include class Preset { public: unsigned int id; QString extension; QString label; QString category; QString parameters; /*! Sorting requires less-than operator. * For convenience, the less-than relation is defined as comparing * the ids of the presets. */ bool operator <(const Preset& other) const { return id < other.id; } }; class Presets : public QObject { Q_OBJECT public: explicit Presets(QObject *parent = 0); virtual ~Presets(); bool readFromFile(const QString& filename, bool removeUnavailableCodecs=true); bool readFromFile(const char *filename, bool removeUnavailableCodecs=true); bool getExtensions(QList& target) const; bool findPresetById(unsigned int id, Preset& target) const; /*! Clear %target and write all presets to it. * @param target the list to be written to * @return If the function succeeds, it returns true. * Otherwise, it returns false. */ bool getPresets(QList& target); /*! Clear %target and write presets with the extension to it. * @return If the function succeeds, it returns true. * @param target the list to be written to * @param extension extension * Otherwise, it returns false. */ bool getPresets(const QString& extension, QList& target); /*! @see getPresets(const QString& extension, QList& target) */ bool getPresets(const char *extension, QList& target); signals: public slots: private: Q_DISABLE_COPY(Presets) struct Private; Private *p; }; #endif // PRESETS_H qwinff-master/src/extra-translations.h000066400000000000000000000026741347323557400204710ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ /** * @file extra-translations.h * @brief File containing extra translatable strings. * * This file contains translatable strings not used in the * program, but used in other places (website, desktop files...). * These strings will be extracted by lupdate so that they can be * translated just like other strings do. Not including this file * in any source files prevents generating extra object code. */ #ifndef EXTRATRANSLATIONS_H #define EXTRATRANSLATIONS_H #include class ExtraTranslations : QObject { Q_OBJECT private: ExtraTranslations() { tr("Convert between media file formats"); tr("Media Converter"); } }; #endif // EXTRATRANSLATIONS_H qwinff-master/src/get-version.sh000077500000000000000000000002211347323557400172410ustar00rootroot00000000000000#!/bin/sh # print the human-readable version string in version.h cd "`dirname $0`" sed -n 's/#define VERSION_STRING "\([^"]*\)"/\1/p' version.h qwinff-master/src/icons/000077500000000000000000000000001347323557400155605ustar00rootroot00000000000000qwinff-master/src/icons/add.png000066400000000000000000000065021347323557400170210ustar00rootroot00000000000000PNG  IHDRĴl; pHYs B(x OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3-gAMA|Q cHRMz%u0`:o_F]IDATxڴ1kTAv߽wITb 6"hD; kB,R VPTADB( ԋXdQf7?'ffD&Ŧ>3QŪGPsɋ_o܋Ɖ}罗ݷ03/Ǩz1bEJ;.P5 ǪJ:W̌gPՆzS03|K>5w%{P @7nO_ ƚohK( bAAClQcT,oAkQ(A1*.{f3s.Eetٷﶹ3s9;gXp.oXq V}ČqiPCf}S] ,vVcS}G;\b#2*]n*.\RsհK&˞ (Dcɿ s>ݪb{ 5ݷ)1.b =9 c!.&r]%edn9h-vI?465Bie?fAQo(*PTUB۬n$@`KnF#On;OeY p"D)ceuQa'#nhYNHNH%D3R[@b\cc؇!d7m 4ML]OSw@Z3V4Db!@ )g2`j((dPZYL+'??GGn3V$fL4A'~.XǦmNjToYuA%U֕əYlVOOD>T:h@SBaWN#ߝAM.%p)w3@|֌qAoE#E<OMTckoE=;=dw`žF=ˠPlFYQÞn[,\A:$  pSWcr!>&b2*kʉ [ 62S,+IcIzp3W vF11=vaυD}ZW][_u|U]%6l Bΐ v T5A}S%Wwl>; X]NK;P.u[v 0PHTHˆ+Bl_ ۋ@>)("fL+I_f}So-8rSql;8{S}6,J@t9OGַ : lf3y5WՅ(JAgiJ}NS#W;jRwG($ֲ@h QI! yz%C 1 ؓoYaQpir2E/tZ椲3utmӇ |v[&v;Uo|ֵ0=) Ivt)\RYajޑ2 c-ue &A!21dH,LhG^@XuDbg$mv/FwfBM;|+gW:=tnqA(#=CgQ &^&2D.$Bl!5eMPk6`aj,yKq?+2@}}VoY k fУ&s#kV^[f?SR-:Cݡ{>FfMPY_5]j%6l莡j[yݙQSn`upUAW}|k7wybىh+7 붭-!;6n$@N =.$L/'Wk[л̶/ofJwGi;ˉ,p٬fH6`D@n=NAAC,qM2#-iD\c9`-BBTǷ6#xdXJ|%9rKԃ1/JWU®yp,_%k$/qMYOZw={Dc!).r@mm,۰Vl\ 5US߾yԿfYZaE!ŸGU֔^ĞAw"b(f{ )3X PMBMbVֽLI?m;&hptK@:T]Xw&^5,h o0}DBFB{H$ 0/,51Ic%NCr9 >Vaִ_?32o\VZ{]􄂚DχP КެTahLiyi40U Ř~zyYmKY=( wm~&E:J$AKtg_@aiY^u3[ev<q-i|ۊ>߭]8ܦWp!,rcTsѰ;j@qY "}<".p>.=mÿLjE{0\R4Rvǘ u˸ԍy{6Q.#pЀnPu ;<6:Ak g5x+3$B G2Twώ 3ӠerOX[f'H3;aG]ֲI74*rcemG>v ;PT~ l{Y^j6tu]z>v8eGITz\|e(hIƢ[xgtyd7;co @\T"d'wxȀE+7>̻o?R+~k@۱{[WOq 4O5PpSrO ӘF~,.XXL gY\פIp`ɕ >\piIk )*'4?+64f[o,@MCe3n<ȳ[^'/Z!\Dsmn%D8x C3܋8qv@n4ulKw($fb̀ K-)w=6‹ ]},&f "5ޘ<#*>}޴ |p2SRK=W4ߺmkI NQ7BSnh;WZ+J9uLy-Ԙf^@ ΏӐ/$_s.9 P̈́#o/+@NY@*xd\Ӈмv`H V wU_BWz^5 !o6`+kH A9j­#V ͪ`IW"~誩h5ICuϣ%@J]}ud8c..<b"{_(`O$\wD\Th.4Kth1m MM''_6^rRٯUe{s%?tnU|( M%I%D_ɦ 2L &Ů*n>h'>4㶦hN~ni8 n/MT^_F~O-BB,qZ\ڬ7i6 Vg, 8c9uYI %5|fOco~u@cq]sG@֝asm,ce6$PM~Vezk$ k[5x>u@ UnÎ7\-.0mGb)Aو,ELhuPdip@݂^rO=R{}&g=~m &f@G ߺj&6{.}~ Tو<˯wiÂ{s2s/<Aa5,J/TK@w4>a)cuv~c\A' -;ҸA{t F`ʊe%AE7h#liE6fIX&:d /^'ǃ7adJ$h jCoLx$3-nj:(&fU`|49>84x3KZ ~VC81l>=c<=@]wf8Onvy UMcw@kᅑX! cp7{.u[Z~T޵]ϑyKU{vH.ߋ{zG tc`p*klš@ԕ%N#v4Av(.^8A|'TKhAMb80c 8id{mJ=(bP!xԿ-{hs-.Wo0[Paړy#\G|B)sl޾M7eʄ9%%>,QWb[Tcc?Z)MA㭰0~Gc*k sof>*PP0eGz*A^|  (,*eDCS2؏c; .ę)-^I )q)l3gaM#)# \Ͳ%ᐻn >}ׄt95  c.CV!bׇwߚIƯ`:'4aGwoYh*PX>QN H͆l wM]^(,χʚ2S^]ʶ& &r-M45?*;P%yz@ hWD1 ?iI鐝 tdSӡݏz @3mX7iYЅUZdӛP?_q9j# YhI v|VK@^}.z<#5ѿ;jV;͍([Nw/.tY 3[~J9YpA{fMd"4U|0 K!d+l)[CAv"x^"︔<=yV!\Lڥ0%![5gpwWhtnpT֖Qٶrl;h}W&f@VСU7ز+&Be,Re}̠,Rp h ƜZ)b9Xr9䬃U0Y=JJ}K 1ZCˤ^0(<5e[uHk4Apﴋ}S.%¿{AukQm&0e=ݰ5= "2$Ĥ5I6孁ykaKzX}=U;|7U> Sn v`3 Vd5;'6йM/v!1zCmS9jLźj M(tgfĔZ^]>P;,IpBTLf$}>eO?t[CxClH};fs@^r7tJL(m8ɹ4q ZѐHl "-;BQy!3ڴ[QS*?os#?dv&M=+! _GI )vCNВqeyPXvFfnGMAdZ>%q8=e IKg=ўLT05^}xMJb!?! eӟ{zt3š )a3-T7oMj +"DZ.I7Vly>"1b tQ+i9+ae|,uuCcͿn)ěSPv-l;܇YQѷtkw=zw:S3aG%XMU\K ,ENL.F?s}&ԣz4_d%u#AA,%. zd~9 VlXu#Uff9y/}{^cN'¿p5VH4Wx@> { {4=zN(b0lE3D;j25@}C͓D_}z)\@xS_W#!d0XU,SSSK .Iv<؂oxv4g@" Ӡw_́q~lmr]=w`OI0AFî:钋eo_BPt?/jXHˁi}~\ۦw}/*+JMФ-VS_9ưV y"d̆-eXtg4X7hS8I.ԎJǘp'$W߈r;G?xl~+޹PC(?Lͺ[+ 2 HUKx_ZD"a _Af$棰K \3-+_¢U )tG05I+~3j&Ҷ342z䨞'q}O{ÆŌ+hJ|*+U\SKM$(Y(R2 A2̔rϴh6f|8ʋ~?$R`N=y"'3O AY]\YŽw]?(\nK.wq3-@ uWrQwmCZŸ ?YHYURUl۶~DHҿ۱pڠsg~l1l&^N撽s>6tdK,Y'FU^רAHlň?z K |McM侴.8 Vs,gjQq|HxMakrN_#ay BFB1mLُÒߐ;8ЯݶoB& yo2<zv86~5 M49hƽvqp[i `.WR!0w2 T Buߴn!⃗u57mD?ZH8uvۏn}|Jṛ ֓uwEfA5+|mX9hNkouq}rkrC m['PP]BE#s irl<># 5Ym!=3Q?V =pϫ\Vx3&B8X;C <7oaYIyo`pG3q[ʖՠ BB[C:) ^sN)l QΌ܏rS!FAԮlJW]r<ꑉ9Xzo:fÎ_9 Hόme+77r L :D-u_@C dv-;@vBX}wnm>{e -,UeW&=InйPT ^Z)Z*?TsTqм=ZdEFj tfPRT 3>z:?Q`Ae[>mO1=; Z<vuk{([I(dwo""7t|ojh$n(f'BcY,;L. 9M4`0hm @p&۶Mznb\bWԷm{%;늿RwypP;,2WZ@Nd, IDD:d]?O&Kс9UZ*pvS + @}S !u$+w[U[|Ɯiii+CCC,\?@0ë?[wlyoW}2>Xv{˯jUsoelڡFF[6l7&DJO^G; n %%b?G/;sNJLL tZl t@t`yIS][(Z yG^9`s/[nkzF?hc9-[ ֵ'p`h3_G5>}22o3\߶F記`e Y䍍-*/ J&aa>?5ݺunfF9 Gr"I*(Q;pԬ+\gouK 464gXHHRq`ѾqqзO_2Rvm[xr`tQ;;y5$P7!#{T7w=/B݆[ Эn7|z> ,lIkay<$V5+CcO$v(JKK@nmmܶ5M:bctS@5֔ A_y_ޠӎX쳆7wHZ-ۢ@4>gm ;W/8}" s|C=۫붼TO1Fc(,@]s,Z]ˏUSF@:1i={Ø&6T6] mGXH}&~CK϶;L@9 rB 뽯l}kWHcOD5ډz7hzZ-48wW@&=Up}{EQߕ;*}cΟ8Ka}PRGBDy˾u ~->֖ZQ#aHSo=,?ABq 8n走'៛ϡ9J< ocmiZ*616C ۈ P\={W uT:U{w! ]Ъe.S*( U 6qzn@ ڬ֤ vj Xb׫ Xb=jwէX3?lQ'@}.~Gv̟/r5y_ @B t$],cVPfX$=v88+Mk3~?xfލRWthTd[ P uRmh/g rT؅ iFy =.fi@KS6ZE8Ev4}e}}z"ML{oloN,-KѮ?VVwZLQϵ ޷`ڤJ ^yi~S;S|_ N~m]C n@o⬸1 lͽJIغ 9 O PkEO>F d#3i ;\MAe^hOxa2 q} :qY\u21 A]S5",l=#Ο x^_i#Z|VnX#߿LR%jQq=1?oآ m"AE;2{Sr/-\&݀)e>a$At4^9#HC&= APS6pj[uC s$bjmq&сx@ ]\D@`hJb4^`payާPT xA?߂>5ۣ$(8(`j\6t881hw,yj ;.;zpb*bQ 9*:zo1)J,i9K>5.^ >ODŽjY1jC:Ԛ{`rYr; mD#+O5Һ$:'2h U[e?r!䱀I50%*X 0ucv@oB@f{^]ʼj9y~pdK?J98R%۝BY@ ߅]veo Ex=G@,mshbѧG7ݬh mhzswU"9lbtHWM^c#Ep6PZ\&8|v/8~ L\rx gmZP^x͑Hwzо0 yΒ3 `XI5zA!h'j ^[ xA`Y{ sMLt#OliGT^.0X 4'nWLq-{ {Ǝo͹Y`C'޺ҡBlrW]eכȼxdAfG'- ~):Ѥ 7?@j;Vӭ:j&PfWI^{ 𻲲GnNt1>f!Ś(H GrWiݎMZ/bIDnljvG76h}.mnۆx>iB] ؽß(ߏ.$A_}@, wj~8NS gdhĖDxwri14 ځDQ r]Ɯvē?DŽM7}Mrjv8v ؒx@3@ld''v-Ҷx'F eҕH.D@*ɅeE%&527DnDL7 {]{>| fO~ +Wz̦YeCF$Q/@4Qι3ULT䑧\6ԣ΀%DUk ML M `.LƵJ |v8ġ/ownQI}w2zse=`]wvBZjݵm &BB}Otc5+, t8Gj ⳍdY p7ڨ0Khi~A8뮀@LzϹbiSa#..5Q9ث[oX]%4x]?h`GV'8ikb7mLK럿x+{Ss$_ikF4κb`uBn,5 GQf/76P$T f@^2O4bJ/8 Mv&&@N.Հ1 (B)¾;%@D{_Hgyt{.f ^He_Sz&f,f2V5\Y|¾8&KF ?%96z8=Jq%wJ^<^:ƙ  [V/ú4(q8qUqV1 @^~ g)<( ,~8\Jxq`PlOQ5pvi^RIp$ ^ȣƟXzpy"WcΜ9t%w! MVll+[_l50 243v <ʋok>Gڤj_uF*uM1'/{X=. b`qOBeBئr~%`؞FWr=g˔ʂo Fxc֐h{ LIJ|z̐-@S!z'NtH$81vbV> `&A iR 6T|H<7|йKg2h:`'kvU"-ûFƔ fވ Gb- $X׈Vӏ(ϷFLnϻmi¢CXgX**Md1ʐ;ޛ eW>pSl[Լ 's=Kj ZGLr^7H@$$WUq[]8v(`n@G FN>N:3 `o`{)/DUzVF|lG^~kX.bkSS1KaXЏvcGk= {d N܅\رcpޢpKQ;w괛`d.Ɲ.] UVƝFciF4%fc(b tMXu%C(T,Jxsli{oM, E JÆ=,{5$l!\4\b;40/[Iz(i54X|@noWAMw$ "A*v{n7Jӹ(CN8Xjy1jܫ0H5^/xw˹weز۫.w@n=U o qczOZo@`P˔.n(\?O)wFS?021KZ5`qL*K1 h/*V:<)~퇲M"BSmQ%-#48 ͓dEqI6R9q@3W> N8pd7-h/26/q_J(@k;b wO)5/Nmwc|Y%y PSЮWȥ;!¤1c:?xJJzSyx-yv/,Ol@!Vm{JO4Tר5t!?T T09 DOs `!a_"}FPN!+;x uA`&?R{&̈́[i-j, g;ͶxڍZ$77HޥI9_etЁq3J(tdK]4>b:#΁s!sQG#9\t-s) +yd+f%@ԶܖPBYS-໷]R0DJ3s>3YY.L48 q '̃QL`o@UZv=ͺ?_y]p,#ЁDqwcrc#k(^Ά }5la]3BՄZ,$ `@cccOCUU/SHszyR^*Ge0u:J՟” 'Tϛ,JOM9 8"LDSuܹsa- &6F֭CF`+08\?a&u"4[bP `M0:ܿtYS }3V.*u_G,NK.D[jæ33|x1iRf~VPS>>뾺h'f_3ɩw߿& PJ*SR)Aa߸*Pf&3aW*|[E}|Oen|(df &I ~+-P*ҵGq59oAπ$GݶWAAJO^ˁsJc~P]`IQ)/A7Kw!ǐ[=?#M#_13O5ѸCdv ϼMrf~#Q/[f[-{kUI\3g{Cl5w$f@^!N-,(^)zỳZH &@fFE$aAo?(˝A&"(x 7/|4@-嫈O9rIJÂxa{ЏҲY+j@h$dASiO[;[<{^{_=8,SC{m])|:BZsmHh )-BK?9tЋ ] BI<O'9 c +4 1BHơ\EOu)i9 ɶ+!i,V϶ J8A/8{8NTt߿?d$t/^쳨<66h27%45" rsGvC`ᢅtݒ{S]o3[UNߏCfhܼh?0Ty&_ ς7?| .x|ܸqӆ 5,JMLu<.}*ILbu$@K.\e˞S$x嗙`͚5Ƃ`JaqO#c/my3~ذ~ڿҬT P**+NS;!J ?'&@ oQ=Ew)q<*x@vr{Ȉ]$A`eF3pq0ڞvWgC(Tt ALÆTSl kMk}z"Ӈ vQQ1WAS%(x3H-(C×_~I4/j∎P~y|s/q<7*3}Ҿ`ah@}"Q֞F9ڌf} FAeuTUUA0@Byq3д]h51 A*M$FzN~ <7P_sٳp rdK[΄ ŋ=2|{rO1>Zz 8("k,;fR';5|Tp1_Woa_%;ZrAzz:kNex*F`.|纝w" _Y!NnQaƍ3ab;6 ?KOE lƓ%B>/QG̺jbWBCC#zA,*J7dkhꢦpE_ %[-NEN*PJt9G>S~q䡻>ﭸf̭ l(%bƁq8x46_XO\)ܫm:077"@0,$D]&(ׁ%ji osRm`*]l{bhޒt}ͶTmݑ4לAFYk{`;6a=~glwM*cƌIM4sOd!MMDův}-4Cnl6(`qm@k wQ֕.$(H؅{hEi325nq<0]'5efpˣiբ?<Ȣn*%–(/WYe(ݶgP+Xha<GGΌq DaOy%(4WB_J[#"THcK9(F D> M-NZ#D^k# Yw;{a=>m۶ev}n=3I C1 iG͡9`MqW-RIJ8Pۈ EΈ~]Bq=i;* v>|l']w r&9lZؤ(zh3́+i  u%%)@ Wł q7Qv->9'ו2r@ZZo+U3u\@F&IU9qx}gjώVgzOX uuuPVZG8]% < #gTfAM//b`3e=D/nݺ@~XWVVZ+1ykc?i<^62^R7  $+6KaQۋY!)sy>ie3oe뿾rͰ4cm]@I+G ^&  )bYܯ C b闶2^ꞵC!|A Pl$ ek\8vlBEE价ZO}ь!B_6-;IH#|+|4T?FAZPX(,,7,({LC I0)30莋^!R~eu܀৭]oKx;iB6e >"}dZS|) j|;D'$̸cLag_D/(ⳫP) yqUwc 0vEy,X؏Md> @cൄ |%0_.@QW7a^(fGΝqeeTŧ0h uu,2=pbGF vAHx|ڀi8{ѥMJ} yн JҼ@X,|Ta~8RE NqVtR#䕭5[PR:`1ymFapsw+s׎WJ1Qio8`TT:v[o4ޗ'ă9Bs=֬Y D(mGdJp`F[SB0mWK.e궣*>=N@*nF-1ϋ-H@3[o1$L +POLLO f=i6eՍi_e􆦪Xxv#3gݹH}qM>?oZtamWPPu.M4<`č }hxfbKhϟ!.*)[WV&QrӁsS{a$]=D] ءcHKKcp[j=hΌ?:,~Ge(0ՈĽaf܁ O:<覣'OWZwGrk9$j.fU~){㸩%PiH0 Yjb̪=#bhBELaj|&:zPVU߇ zwR27.5%z>|a>A`'(@}hJ J?*AdXWsn#~)P` 췈D/6 Q碎BDwQj6~ `g1@# 'tZ URP`~–7-NѢ_ѳ't rZB_]DA:\pt>ǡ.2Y#8=?D 5Iw=+99@ /9YQw(WG!s@4 mqc֑vR@4'h#Bȣ0Y E_DM8ʪj梣ZUlOWgo ^خG١_|R aF0#UC|,{ |j`hG`ڿrD iQ!:D\WiY=![%< \羣_}۩^pl\ un%IFjB:;M!/s6":SP܀xg_3M`$(g ] e5H@z~Qs\Ms#yYώ;kaَŗK8$k+TPb"Or3N6lIg(!@>,t9/GJLpVBLsZHǺP&dALbOԐH@36C_~^ *քuI?} ["V K1p\Q?3"9PQQ p%|9sv {@h;{~Xz5#% dMT*>e)aP!SkĂ- ( xT:9. u f-IɐD(^C5ZAI{^h4٪M Ïhѓ`햕|aya=:kPAt'nN$+gDvP1#H-=%O>gh 5C""ׇ 0"=zEGq -I |]A(؆ G + A(-]]YEyDmܪjdX(YJ1'\?5(~O)PRZ1KaH7I I] zg"63.'_~ ޖPy(T$F|A-r=b‘/(\6p~JQ8'GPW ^FA&CddtW–ğ7 y R]HIMqէAQ;6<~>7$a @AO@9 a5Ԇ][ x͇;([o,XѷPU_ ƙ̣-M3H"PD!6*Nz!<aۚ&.@{fO$}ea sp]~kc,/>3FXc~ +Wq/5i=ݭi֭гgOKmsrr5T[%)wC:a4[M\=wb`AYR~&|G3SmY4-sv.FIQ$uOJLd\FH쿞o 4\< 04տnIKȁڜ<{#W$ | crfGbt+KG c< #-AfLgx >&%VNjGVW}-Y_<n <"x^0hnZp x7i?]E9u(8 6{o޼mNz6 GSG452)Z64qwۖnAL /f3+hdRVhf~nI-b4z4# P۞d!JKv"[䨞:f.5?ya;ֶv# L$`jR(h .did mÄ1@O Wp5>T!C9.><Iz'YN8ohtRl)]42Ury/R\{.ؘYwnbW*o3oɠx$kbQ?DR~VmEژTp<> 4 0QKɶSf+:wRc,4Zf >Aݥ|`L@ZhAg82yYyr Jb6|[#"a2X b%'%3j > >ZMD @Αrm4KAjz*L3ܙ__HÍKpW23@W#Rr0amٗPRuYuRMq d$Ҡ{ PJn =2Oe<Ĝ?]\F 6#7ETRf<* `_z p`sswg# d`ƌЪU+~,##F a9W>K+ ٹb9*q7qÇQ/F|$ մd}6Ztַ[ɄU_h#KЕF;9TsmM+\99d80$+uX2}Ĥ1*T}(/]Kqǂ2䕒t:7 [o[]һ{XNESTBGflswbK-ߺl9.feu#Lex1Q4`,B{; ~i~jd+]fKY|:kz6c2/x!|~k\W2ʜ6:1`j;zl9/ QE8,&g߼Ng\}^a3{Д3BXhxH>ZG~ yirL%3o#q5BϞ>wcjaK ITaO%J*Ju@vr;ȊJ`$dǽ%I?D$ي|; S7H΄\xgGJ BP14u AmB~E'lGZ$ ?4Q *7s}/$ɒ8ruJ+z&+9-gI4 hCQJ’%[x_`kՏPZC 9bnl,:Dz(f{ lٔ3>zܼ[K *)  N'@M%}M 8{lۤy#$AГ\0~xwڕBul[ &ڌd W^"pԟSsKQͨEah1D ߃ Jfc&O?vI!ئ]RjDzzvKfÍZh תsAWkقq5i;FOr׋{,66Vq8C*&hӁ.3~t0ٰpSʞ f)PQ`"N*);2O^2UY;SLo}%mg#`|^9jkq_;|$44m:rU#;i+C~Va& 1A# H̨Lq.r|߽x#`ᚙq[C [~9 48x7@YUIky+MxtL5sW§i$^nl衿, 0ENO?O1}~cM.f 4P(QpZRXM^ h=)&C@Zq&MW#W_ ۷og -=V4Gƽ=S)g$;q[m""Qhfi[ λ@MHpA 4*%,Љtd|࿝[wj)g)‚>o@(_cQ{YBM%Xi>WWrԡضw,ʟ Hp4;WS'rx`HJ\t8|VwT;֗  ƫ A7h8e94xۙjF> tq< ?/a">@.8ߙ"icQF![YGCm}>a:qi!,癒hc$;2}>*4&#/ qǖ/_vC{gرPw)[ %@VS=]|ۄ`EPVS%g%h;D̯VT:୏f—?}:4yy۞؀ރԭKGXmF"H-R+֬1'qz%@iش6Ě j+zE;J  @HOEه`۶mEwzmil1LhE$ps5l>긦,BO+=msf7@At̾4|cӦMds9{+̒aI (9 z3 3zʙx `P % Y]vgm_˾7o^OOק>U*]vEPv}ps]}y*AF ?ٹ<`C\r/#M;6 +~9a͌:lovly5ڝKL\PeXoZ`ܷ#_wFz|ꭿz#`%D&@MIA?KF'LmJ{yn?i?S,b#k}Mד"DfHjݚ^ev[^PqΓ\^šcԢvWغi?w X4VQ4׾ hO9J{(`l2/7 t u/v48Fؼu*ʹc;''g9ךR]q ,\47#a!*nT;hpUz\}D(F?{T@3M,B18vmn*ԩSpnst:9 H$9)p q#6^hqՇ*-/}8\{9%dɷx&}ުvtxʄݕ/@龈y}J_x糗?VԢk G$tH.O%*|8d P"^`sB]6E35TY1gСE*bNi̅cҾlK^#5wvEe܏?Ϛg5STnݍpU[h׊  (+[.Y9G 8,?Gڭ<ፗ˶NCYl:JEV'pDm[/Fk`ö? X\mL#2(ͥ9 kѰ TXCr|yD͎X,KD: 26m$ q~UWKq.,*߳LsόH|C`e47jeIhF1@-+gq֭e˖I3HPq I~ Prж^?s0yH!Yo2IQsh:"ywWJV\Oٿ3̟MǕ _j oeiTenƋ]oIg) WDn` L}i;N4":NFJlQ^ H w!9lp?_z(Ԍ0d="J2%K2Cj7vjdC⛘x̣sUwB2OoQH}!y81tϨYᵫn㦯blZCQcB>s/)eἦ᱑w};2)/9f_o߇10o0>$>lp `T&4zVhX|)v_@ & މk[<C:z2L0hST h!^d= IN%KgBbT1/Pdɒ?>|b?!0Uȅ?열hGo|V m6f*/Y<#MH6Hv‹S3g0[G >/_z].LP~O6 8Q OsVw[VW?z+_ZhPRc3*6N<&eFs_,+F\vci(Vz1 I{iڧ 7` @ǃ*Y:y]·"wM\gr4i3 ݺڍ}q= ذA„I<,2//&@}9HKM 'jO>h׽YY2PX3Q=@_̬HcX-3;ʵmzOnbiaҌI0OGuvwT^ui,[-{2`HO/tȏMFÔ D5𓇶XE8J-6 58A4 Ү_Om bIT"NOv  nzCety:%s-}ϳ_nM}n:3XMJTm>d+LW\v%F"^ Hc@xvͻ.Ml!b~B#1Éh(Sú`Ա#[sȞcv}eaնf-fIGAvZvF ZeR:[t1*fGȁ|#ڞ6P:eG"g⳩ILO8 X'P6 zPUF 8dZ~|To2}_A"_xg\5h̘zq&etm F }ff&?!To]DEi&`(v1r ̙30AǪ0GsǝZM.+ u{4qH<Һ޹}A/ |U/#`!C' fų{č t\4P jro`on]#`1J`R"W3WŠLoxa @q?G$Adqf8Wo P/18֘G AjVn:,`[s={?_w5w(/^t8$-ܵչ#{}!|:f{н}?JlPy3%qߎzQ Z u Apko߁'j7?`.$ypi˜/?ח\GH dK0]ϬrS~ &@tDŸ_=p]=S\ysic m'z| NfOO~و6>f!{0bhO2؋^5rc*P3%K;FgNv|kWaf95И`q <#'\l|oԬibp]̪[PTLlú@}{`0`XZn? QrzꇀdRוsJ"Smp-)sh_AQF$a˂k75bH*b qE}h >WU4,o_c!%J¦`鲥Rŧ[tݹL9JcyD6*kmd4б9h HhYz~ &,zrxe{0IkKȄ?+5 9_6ϱ'Vt~$6@$?@%ӒÄoރū75no#}[ɎK$@} rq&O`'6uLq4 .elQPN.S?uF%"P&zrf# {U0uA;ϗ_UΣ! ^ nh [zuy6h#rBͥ&C.]k/k)ə`a z>lDbHR# rf i $h`o7'CSc U7 ;e/8?4jXyJhK昻@ƽaY0ww?}h˘hL%`zr1Pa=K$\K 9=iҹQ-H_VMG*-]ٳgMCjhѢT5QAܹ3,^X&ȧz-7כ7zٍI IX_Pj>˕/Hs`qLg2hǘwC`OV~ƒ{-j59?}VĔk".āuέ?bqX/eV9&ŴKr,HUQ0P#a5AM\DF>-X>6`j{.X=:W5kVñ$+Wӧ \;f9vwUfF޷& J W@2ea괓L"Y\B j`dc߻| ),5.l9%>&k=wVXs;X?(!-]s6Q(p+쪍 Rݯ^ﳇ$cnm+-bCaO)%1bIVlD+A=:mo(4 u]{ t&EpjW_tix @ $`5 /͓`Ait0/ƶM7kZVr(T?&J~iD$ 6\("MFF$_4dazx^ C@WOgր ӣWC~?5{;~|m~`- 4RFڛA tY @`7_;>"4YY,qk^ K`FƼb/Mgƒ`_ Ю1 b1~m(SNjժ:"7`0_ɒپy&b#& M:03pԱLNT.iմz_.z0+AN ChAG@%(aN&дrWxn#UF@:^}_ KV, wϧo}(X\p#\Qshɕɪ+T0e"׵Vǂ1S& w5xpV}eΔԪ̛7N=T:@܀s 9`/x' 3Wquթ?m)IcΪ,vً|~gNr%_ć6( 6\Lce'ThiԬ!720BJ[4Ll< $`ό|ԕ >E+]%:W݄Q~p30nӐm mT&Di0j.ks %Xay086t`lƍs$jLhH`$aQK;CFUbxE"z#Am߾}0bH/DaONJrNAC"sP%8`'@1>ЊNoJ&~r0_\ =>@; !OTs68} }f\a-NxP 59 <1rlھ +&U)[ܮGnz[@K$T(=hc0qt}6,^Nc⃛^+,haV&r]ZakÆ e$ [n[?O-!j 3@ UZv҈p5&XB8iӁy{7u Y0߿~HzƁ$I `F9^`E5kqvԾL=8{5- 1&U,Uk:{8|P{߅ 0Ow]w`lŠu%K@ I>x`@o8bٍZ @2v8Y 4ipdJ+"XK`5 %%P%Z:wF6 %|ܗ4pLIs5C*l`B @.-6"XHS5P8k&y0v C~?c u!-i ϸ"f * "Pu*YNgL ]τd[X$-uԘ~]$`v.xݍed Ñ{xsMP +&5}wrjPkׂC3a OmGnz ؠx&&!pn-s`Ə!ͨ!tiRw] ?)v# 4N0I0zJf1ys{>0sLXT@z]Cn$``p}% V}H!0n71e+F|MͯI4sI{G=$G@d0_g6L GqJC'ad^XŧTGef҂Ό|- loX5$\Ax'd?K)ZUgە`X%pL1DЀ ځG#R+HHivU~׋P8xP՟7PnBSӧ훨ᠺPAނCb^fNI"ZH@p2xp6@zLUɾJeFpR-rX+,pW_Pe׏Vx-sRvÊMsg̀gc=vnH;PW(Y.<}<1߰ai%rg&*p 9"%#MGgOĮZt?z1Az@q^GիW_TeE m~F$! bz G51=\ 0qD VjXx"w2(pNy,F5ȵp>~ ӣ zy ?KB&7{$G"X/Uڀ~QP:X Kβfɣ\sՆ? N}`#`ܼsS_Y&oߨ'y 3Fu!x3uh^_.y cKohlA"'<ݔ bs;I^7wW4) }4s {#"kg%pI,>$| Ojo_,A <$v.bcaQsʊ@㦌SY%*\l<&-&VB+aɁTS$o3]/a.dj{ K;vz4[ ɔ_iwE07mgRB#0FZPzб%WdeV.oS`V@2~?o;iFPm8huvVssߚ\9Qc ){URCh[B1A>ZN!ىe~V9(&"OkQs!'4v sWRi+{v lh, 9FL. cep-C wr ]pJ *4D Fh'L(߽CMd ' ҚڵI TN G l +Sխfl1ꏓ430.Iޱez>[Jt0*(I |cn@rЫ wCjoK48/ ?j{nX~g]47Q؛4i"5M-#B]ޅ(kM#|0$Sô1m|7AH:N \U!~*DCDv]\7mڴc3nS/,cٛ e[nvN|NrEz w17WUW_чy9ҚTRs7=<:"KRMHPY}_c|ŭ·3&e37Cs`0ib!;'0`$m?K XWms!A+U :p^|Q@B`V+͘q6ж-a͠VWu$|[݂mF*] Uj!%ů⧱i)~N+Sh# Y76<%)Lyg#X[ %=P>gX&㑲&Tv%/,\N"hMhD.8;#߽RS|b҇Mv*>Q2sI3ff2z)/WBt>7E*|k`d  JI$^I%>o6hJEL+O2/`/6ޟT|G% :%( \hr/z;WqlQrsM㚸E0{˖-ǎ-w-v  SWUʆ4Ң!VI6Lo+}O2">5n6Uk F20v\_&|??FљjVu* <]Ӈ# nsrB|~|6};޸K7J?]vYA 9b;j/`y;:c?`tiTA &@J#Bw93τSN9Ez2ds,yf'"2CPgc^nIi5k||e_h2QPzRjN + Qv`h5'>$'aik:羁YCVn]s@c\uf̌sGBaq =cK'n{QLW&,nlu @@p-܀yVVV3,{B `Ŋ @&p`MJWdn` ? va0sH_[U<3aїBvїtѸ`ȗp̲5<}T-,)}4@^(]ۙ3\k;p?I) 8A7JX*mZ૯J1 QnDs whkAMn=p#, 6߰(h~ ҥKq@z`vPei"眸^YQXH }ZjϨ'"r>\!)tAX=_dtl ΃qƼ"΄3 $֧uˆsc96,5 <+mJқNS5aߨܮ[SR*x9`%$(>ޮ.aEg휒j7|s^vy%Z LFKC〫k vzR .R00jO? e۳:jϾT1BѰSNa0#;#kTW}brKLs ^#i@h&@3 tG3֢ASf>S(;;?%9v?t˄|hK,%lݷN,sRl0Kp+MA=0!OZI)pI`͌}D*KQ)9?da*U@u߮A3ht 7x=j xer^6l>/۴Vt_uTNj-Bw X^I@B/,U.'7ᒷ0=*٠Dsf# }iKQC%TksƖDy{˳[OZY /yp M_ֽCu3߾d7Q+ <xYEH3ȓ~j͡yn#s,t*{PA$\Q Ap o%g։ɰU~n@/_^Wqк2žwAV(uf@<*V8Q bPO0oܔp3aWkqh ("Tm_jW!Zt6㖇g1c{pi?ߍ.d|UA5t}?< Y9L\I)Qq`iugZPZr\^4_MOWGFWKI$ 曄ʕ"@sZ@ZiC08`&i$Rs48W!W0 {f:z,-Nn 2UI~v„&Q5զϒL SڧՈ=t~݇-6$12H@pLv_u PfAl1%F Iѭ"ɥsg3̿Q۾EB!'4wy"YӨpj̘XAK<{1 dVo0TH`:IY!$6h}zVrH݃hrW% `K&.Dx:jWMlj͢5lPFnFrۨj7(!𝚂nt:n5$o4_|lVq%d#l*H_[VOY՚΅F*9Mmhx+[)+>UvDLW1yPOX⯴X4Vlk[؋x ` X8eU/X  hwW;O4%RrU| řOTs_}._ 92@Gt޽p1 `.zr+E So9Mivތk׮믿^j~؞|QѠ<4i3hbbqqL2brUժihcXSdY0 kae0}7 y hfC|CF&SSVW_2q{ .o߇$$5M{O@:z @p7Z oUXI@IfA Kd%C<2/J@xJh@yCUi#TJ /WS Et`c zЌ(LkD05ٶZιasv7ߔhʎd]s\H0jjM; jNڋd]?|_>`[$0f;2OișP`~ ؇'@.jڙ|$,v[o*+k[^ (pU(.@MZM6`3p47ӆ^P!.|#[.j9PM(O R\xBhwom[mw!`b8(?Ȗb㟏1iӦ ,AJH4 }_vWF£^)Q#$[^tE46'9so[%($_#@!/)$c֬Y#y8q V}j>g_HTt-`C|]jT8qP㜝&Rh׋IBXP<;'Jw&?Yzo(\"~a,6ܹ\٠Sf yӠ1k0acor1>F@s9Gjd*``HP?BWs_Hz,@e' Q/~^区g{tzK吕m&t7jTI0Ri@ [?и0@ZPUAIW~=puhg>z(%)~T ",`F!q|pgLڐ wWTo|ɒj1h~~!K hEѣE/wltnjStŝ$ 7/1HZ]Ϻn o-Yu?SuNE=\j̟fGEbb 3H#ʇQB~`(DuȹO4~m ˖1@^Fub㎷R8̜9Sz:\.`>1dZ\;$ n:(QФsx$/ d]}#X1cw'~ jkXȐ5ޥ4=҈5j&yXU S>\r -'!N@e*l{0uxS鴤%'37k !|sDe>xФpzs'&ymdqxGCGWqAW{4p#p jm_x-@>!g}@pxn`Q\v'F # dVH;+<^|C ? ޵;Q)ĮAw"dsMmЮ@0db(r2sM{?{ y.M vh5*ԇ_/ lE# ܾͨ3W~-@i16 l2׎^QCC\Co &K1! o,QP>!y\#FM_T>ցUTчā<>HuȒ+Q%@T@ڵG&F EBgqƙ@8\&Ԇl p3ӂWai W1+11oby 2hI@. t ̓\c#Pg K-֫irbf:{\]zq: εͮϧBCE7Ee y?{0W`o^䒈c,aL-r;iV.SJF2b VxHL>D9<: i i6 3mz<2ILlx\Bq *z~UKu b"kw<g~pĉs?;"GFxRk+ᙉNue,;-. 8qqDBc fի!(] h0t2P pPdZ7=Rc07 G6p>\bUʏ̎44AFuDegˈ=X,aAP W{&CaFv-(/ Gj"W^‡E va,ҥKCqV? t(0M U" Ui篿\8p~z`S—`_NGIMDhW3Ba?"Ұ^\-5]ylfRn&\d WӚ5P >{@i`ɟH Kv#^ѣG;`|5k@9a"p7$,c?u֕вeK#5ieW䘍 q%%Š[wj)ȠVUǴG h 1LTYQø=1yC7ϸ l&!.rVMPw, @h9{~ס}{8O2J{C|'"(l5:Al1,K `̘1,YC Yz Ts5zNQt'̪0J'(nN:_cY2tmڴ&[ jOBRowgHq7} Q鲜CmlN8굝~o#mV}Žv\)oƮ8 Uk{`nhuVoioPԃuur<'O]1y~vz.kAG[!^'  h}*jQ' HF:0Wԫ#-|OcNŋL4zeu K^-9(p=\3gEʌM=CJdr/|l'ᗳC~8Ѹ! U?O m۶ (]=.1sgèibG.V'޾\՟\&@?^<e*'5H`k^=@EZhJN@P|y #M.e)"(A3)B؛ Nɧu]gM=4{?+Wf쾂?OkɁaw$~Ũi 5}"I[2{V;|cTTFkO:dIg| +A5'턳戍O\@?ժV GCU`v2Ms 1gS/_[>|,nC~F-``.j~-1+h\%Q}*<.B5ܹ{V<xbKտTڪ<N_Q]%5V {AB'.'JLJԈP5] <"笶 9sG뛠E1Oi}e/"Rcff) |&580ǟΓ~ D2@wory,#$32oX2t;R8;W!PbO}yd~xh7ɋi5]D98 硾2 V?u!08c=J x>6 Q˷kQ$4|@m]i- އ+-@V <\G_7mQPf W"n3r*G#A'U{bLB`HӀ L,q́0+Tf͛q ՐV%K'S]rޫ۽I7cV xzԃ{ZN` `.޶U[zٻpXyk1"%-0ju7I^ Hصk֥uJ1DmkͲ#)Q"Yj"j@6Ekes"UqbbersvHZRHCz}W^H@uHbM;\4oWQ]\K݂@gnq W9u7,Wz_2=4|})ؼxn%Kӛ+kʝr m5\TwtΟibX@;-$\z,Z&A!O((ZO-+M c] u0c{z| [qE 06 HI3 `lI6kvZAMڳՐ㸍Ȋ/"UOx~GF-Z50vF3@ +;?3oAAM3aҵ&#4xQP]e1f<]n'b+A?|NQhj(gv^n|]B{0Hi? <+8Y}_Eh>jbRմֵϓ`&@`H;{?98}npNc.,EHѬrC[[lg~8cɈA { lf0mC2>h$0䔪aE+;G?P6l|(^ wѣQlf1[SZ񂪽,7f28C\cZՏY@Pd`J!&}PI@qc`j${]wg6!U|g_j~pkz2oQ'BnO$˽}7o#s$:L;+M#@S {ݘC읛gzbt2fJ\Q_ 5TPcqK7%4ÖÄ'P矗E:WR'U0Qa᧶q#^C r L-3+ї !\{l`b5Ahv|@,U'qCI@ d&^Isrr}x}\b:ޗ֫~͌I m$b<}Juëӡ\,Wd*Cp? Q,X@J_0+߱S'ivڎBGE*(!ޯ_K4VZ ʖ++.]4c\YI?BߏQm۶7= }Gc?]7T/vMd#@J1#ҮPjԨZJCo2OH.pJ<ǐ j׆k)U [_8SW&%-C#! sYr,WmeKRX2T*S\o\;xR":-*#sX?GY .1J8~ 1J*ñ2^='ZW׶hZ4H)*7D6D Y&TX&OALn 5B*kV[cpR kԬYc? WzOurRrYEq@I::Mcr[rp`i;Gi{%to5I%}Gʕ̉#e=ʤ`E&B}cv{dJ~p듍MQͮ>0PQL)19%ػճȞ=y|/x9~Yg HOOAE/mByo]OM#&UgΜyoEa'_9l޽ v:1.F^ &sn܁SRr.h}W5X U[k׼׷;h2ռN;h\ ppVvAt+@Fu|𯁏/¾,<3(\*imjijW< J) GJ_][vW@SN9f5nP~,o{.9dENA{$xH<|qf2E9~g4B8݂Y eq%)_fV@\1t иc!J+y̝;jg2(U9q1^pX&r/<b⩕qs +X@5P>csE8]J$*':_>BoL1onfXwi E P g)hD߮Xih`ß7=#cW^gpwn۶c Gy#7TFL >^lCh[t `yj~A M6]N1HVbeh4_%''>kT%Hj~PƠ\  ?|8Pr%Tn~Jggxej2@ m \0~Vl /$wW'@q[=ioT{<,zJUw@ua`G\XZ!0V91/&0 NqoѮj'V)D2C_PMd٬6T1rl K[ |'&bK.7ߏAB%A O%@ބ5o``A dBKk4X[R5 Vog3sD9Bx5o;n{>k\ޏsM+G>޴'z{۷j#9mO\@\zdr+!.L\i#,5,DZrj͡uކZ?7 r wXǎӉ7m %_Z%OCn;Ѕ7F!  ~8qYf Mp*&Pc&MWQ#`F欬lr0xKBZjD>+cdef;|PZygg#v.ʼnqmR?.ӟz qkz8E7KT5#eۭ#]a0OQwFz8( p =m^\r|1#zص6espQ(ڵѰa÷0fVbԘIO%5n;>mV|9ĠIlhn\kʽKG cDhU6^x1L!+<*@[AN8j a ir! JiɾoxWU4ZƭXA{c\[D5etx`euEcHUF4ܽ.a(a 7xǖc @XW ZMBt8UzQc9m! 5n2(|nUFlξuqy8Sbw܍-Ep+!S]$P+ kʭW­H@L9ݰ#/+R6j$OomUh3 :9bƷ¡p,i?n0A:: jVuW|KiT+ +! `{^^>xçU+BK ~A{XȽ%|sk37;lz~)Ѧa{]~{.`= A͊KSKApf0{wsM^," *6IXfJ;wۉc2 ŲY%;.BR<㴫-`ҐLc0\s+I#P\qPj: U7?ggtl7>6p\ PV>]nJ=FJڵVo]c`ꉰyZ&̗k:CLp#9( Q4 8u8+QOMJ2۩}`լ q=6QTSYg5w=Q%W~$ WH5gI@B1%ɇ砠8*UaG'̞=)(Z+ X98u:Nêw#زwܽN5EF"ϊ) ߔC smgP9y#4̺/:o^R[{v6n$ЂІ%̎l= 8sr2d3{lxLb`b`xfK #BHI%_nz{ݐIAzV_YpvuOC1*E#vmWlҲm"oa !b4a8Nt/8XCFB0n x ko{roɒ%7^2uT拮;upi!$`;qybFG@0h!6*w/e[p}ê3r65oC6É1z~"<^s7uTKw|'iZi.os}?= L"( Իե@?ߪ/4~WUk7^k8q5tTt`*g!H5B,p@;﫠.WcOe37G!}(;o>v-wy.3y=Qs ֗xA)䛆iz擄ol\6l ZuM0@7;>~aʄɰy#7 O(ԩ@5Jd~ ɏ eY4nX~'?ǟwfϟBiP=ВqjS1aCmXI8k>lp0"Ky \#.VB¦k݉Y1h SFwi³/=wݿ[s[f}׭;wو4II&|4/AUDn+[iI@rB Y5x'Lѓ^3e2\j`\EuL=Wl筂^ 8E4;u9;KI;^vUx\Bq+,?hf2o -^3zF[E#H-z0TjOۯ76zNvH2(T / 5c03@Q@s8ڛgïl_m}-ҥKoٸq XA%~<+az9p1@s貶=Ą?8|̓dH-50jH7>8]21I rmS.pup'w~{YEQQr(y> 3OXO> 8D/΋2UsG{0FPke 蝗c}Q^߰x깭?c]מM'%*Vq>`ɧ+2|;\95) 5lB\#L<On9s#)fBOM dZR&MG0 qMJ*og@շ-yKMA&cSW"rJ )3ݾzb%p[?u؆Ϯ@{5| <%/ BE1 M `٬A}_ |oWN\-i~DK|UGe+2|a݄-n2No^DL+P }Iрq@J~xEwbZ{ɗ>avb5d <Þ_ۚƞ6L@Xe$AslBrX8hmS@ NgE&@>&F`Lf#u"n>Dd2[,?}'*KL(Pb1KOC>Ujdh2@}zXرZuxkޟCCeO@b=^@5_@%F`ܰn[ v,>b͜^rV:~DS+n,% o)yVO/z#xo 1}(eΓn,B&!6/ɖ3gO߽]}Pٖ!;(=g^*}sΝox]aOپn@SEaQX-=i/|W}|9KN ,{Nn=ׄk{Y_3 Kմɯ, 0mS˨/k? 2{MݜUvfCspsȠ/b Mسzk}00ɟU#Ȃ1,/G𕰁Կ%60ig\𛽛,THP$MUHXR>&0|%Q |wx4<$ OV`;–DN3p3B`qrRKkbT۷_|r2ku\jyS"ʷTUe,BxZ1 ,_H[as[*0~xaϭw }e ٻH0`#@{@ wE2иir3bݛnV #VQ7(5kj7<3y(1|K}5%5تeiEHnS}PL_09CêiZG#Gg< 'Ϻ}'T=ֻٞUcO.}FR W(QBߞ?Daa =]t +`QD}) p].9r~vsN9/REXB02P& Ioٲ[-4j ?]0&PI@5r޵+ouko?v|N=J6=J^H[pz@-z[y ]͎@d Cu>ǿvM3 TR\bf9}NH @~@r 9נ!ضm[6=vmV7bݔAs'n+Qʪv=rrS'0$2N[Z7mM7} [q5otbnA;)nIǵZ1Mye vlaU#IԴ7ѤT3$@80q1NnaΊaKnSHs(ccDo1Xc'¡Cgka_ʝv_sscf}n;<o|Œbيl{YsY<< `ԠpjZ[O,h&09>WJOweC=G &:VE}6uLM6Ap'$%n:O%Vti5R\üؽSk:I!/{%tgf&=N _ 6}$p 3J T/s{J4hK[ˆEW'~ʊ|u˪Ϋh~ k2dg5u׬p xG–q 8_v6 $0tWb ڈTt?֯_o{V $3%A%H`2|7Rߤ_ilE< ː! +]Rl.ōü{T󀕛9HW9'xiJ*1胡HHdx -x0b|YK )h \ S!m&.x_{ wUW e퍟=w|`ם=iM˧R#`JuRON Z7@V6%U`$sBgg 6fN:CX'@A*E=466D3وao%cq=LS)yRYӠ2i) 0K,y\T[32wk7`:&w=pٰ8 0k.XMwǤiمbOɉR?V٩%@)J葀egX|sUf |V,\ O oRI` N\?#UXjU-d1v $9uaؑma̙6mH^8&wx4o||wMPт)a**s/nC3P * .L3XJ&ĐLPZ"I뤊-N*6ЎOIhkv L -<\ēRc ] zg@y6Z9d%LM0 qP !`($xO6[ye{_gUʖzMNi?X/ &KV]7{at)k DM=C߭#B<}!j 5}}?bgikk!kq1xAo_%ڹM*hYm3ꡩ+*U5>a(U 2[IsS"l?-:q>yX#V1u3^/C $^a\#A U`'@HsVZተ `Qp"U~6Q:Ҍ 4 YD( 4{Vu]eiW Ȫ dY @/> ]33XM[WDq&CG(oļYuݨ^JG)m\DN'&FLDJasH 9C_Xt'Wg܀ MwHA{Bz3~0/=s;߮I= 5EÄkd\Wqr,Xjb2#3{՚=g gR ~b?3u'8b ?bziiDT0P_ ([nf]|Sq%®%k‘ocbfP@ghkOv]ahg& _7(|S%\运~qn<x4I9H;F)k s ׽# "4_̽Gv[As!xd?! JvI,EH~_ 38x ųf*;-Wy4#Zg??ǒ7At^9NaH,?&j!RAp9UÏ pu9KK5V%H.].W( zlK (Ov UY2{cVC@Ccyo b(OT\d@R57h:Q EHaɀΛi֬JxXzě!qbrV93 4 bU,YMܱV ?P&`%58q?Y0{s=IJn=B> ~?pKK)ކ$y(3.UINI[S)toJc <3( 6]- 6cAk~\W_ޓ7G1?hրP#Ws ;4u(wOa$whNɗdr3y,"&t,ynO_Bx7DNA0ܯ hZG >k8^*CqBylwe2.@%Z P!Ӊ|暊FZ $#e(@X\La>aCl|Kt='0H%^{|] օ@7 h|wt* |xjaI"ʢd~HF (G̻~Ѩi K.vرi8rb?߰PH w!+DjO`ך 뀄mAv*r*e& Ž4)aWJ}BA\I^);` !+Q:e5ۼe@l4]L2c,5{!f`'mM.j׋|Bt((gU"RMyɼpkupx_ߋ jIc@Ӭ~gKЁ~S L}HIW2R4kBLL~fqEN8ҁw>@WA8$Qc\1鎩X/wf[C'# 4b&@+M)&zVmՎIߣzB$RD2X@5*@̀ď-ѐ.;u0g#daqV $ 7E4ή ovX@'?1ytb>87 'H7, Sh!e5j ZD 2LԲD>@eXHIYIɞSljK3 Nf7oP> ֬ R Z&`e2eeA넨iκۦ6u5ze0zHxp䁂i'.P5VK`B F{ 2ryVTHZJ" 9 ^L#1Ym&􏻥8`G^ h}y4X#wCyFKNKp90hIK9 (Lp\D]Jmg1 :QӢY.7.4qugNCFZ(hd]6(H@YJh%IzDQAL .?oΤ4'BLG AH4w~a1rô\#X` pAxa]/j#wn B??C!@GiͿ#4,*OL m@f%਩3k]3% X{oN=fsɓIkW%Ƃ. 1i_N@˜ +Ff+6LҳDѬL]p"P#ukO{s;:9/,u[?zP;G sz"8^؀7e),p `zrRzaI;0ľRT j~pL7ܜu]>aO/{!,-0Y`߱plrWr ECҾgil>N $D?B<ǛdLh>Yqep2 'ڃh.Nۑ>JW#JTםϚ E@՟,a@Dy%8)#6M' d&H5:CF~JPgi"އxw O~~|tTF e "o5z{N,Pi{ڒ rk[}uڄY|Z7s1o{[2C&>/UG- 3x'ǣTgW/rV#̄ !X|e%>'|Y mΆuG`V tlH^ǔ61)O4%<-]f2,èNy 3  S2AWiv㥎Tf+ܴ=d^[5rrt1-6&G so'ްxAחFDr( J1uP ?]m}3a['탥6jT:8eoP'۬+1(R<~O(1Mw"+!a K١!t DB$: ULfqW\/e&AӄtqH@a"$acd~E5OH\Bt?{ڔ$k0RFH̡k P 5|6d,5 U`5Rkȵ_i_5Xv{uΉF [G cY9}̙:&u@Cc={r?}j=DcJ8VE]E,yJт 5i+k)ǡY}dIh)Xs^ qʄB@tL@j*.~x0hL|X.w.hńxFF(7f DzYØQucԲ!-FcBg6 0;}?sN={NBo$-9"&Ln|x)A4!Yg:d5 Qep Uo(>Z'x~L$f:Lf,|ZgPC.)Ep80>|L"b AA@A ea0e9^Z}CTԱ<7aĤhFSZW=j픶`)3-sh5qzއӽLIh uFpK `Y37pe/w'XduNҲ`)E+ !26?d`%1aײA00201Ï4fIAFĖ' ˈΉ!#w@vk }w@vfC6LBzmeٮf\T7vtG4wH:7נoz7@f07vD; k u .h 'lt?S` z^A_2 R q}fRO?'#v)DݮXw"݉Zt("`؎['*L@ :`@.IyA2 M = " UzW1kE|4WcfPn`%Pi_s{Wm5̆F3`VTn6d84m! M>z6LaabYlq]/9J*nȇ >wp N^q L&b=!# !aWh J" SJ{ I>\\D20aMp{wHL2@8vE6|P3Y:v~|- 䀭p*$@V",P S(Z Wu]mjdV:r0v?7kj6s U} WV*/՝]}^|]->([e]qO:&Stx515n}xfۯn+0*,}0`]3rԪZG-#&F]8L-)(`tPfQs U_~w~C]g Fe;o0Ic3k[Ye9/e4`Uts+m';7K{r0ywMIENDB`(      &)D':V1P`7gj=o@sBuCuCuCuCuCuCuCuCuCuCuCuCuCuCuCuCuCuCuCuCuCuCuCuCuCuCuCuCuCuCuCuCvDvDvDvDvDvDvDvDvDvDvDvDwDwDwDwDwDxExExExExExExExExExExExExExExExE1  $+O-Kb9um?rBN"[4kH|d|ƨoǣxE  !!"""%F(Fd9|o@N.eRwä׾߾ݹܹܸܸܸܸܸܸ۸ܸ۷۶۶۶۵}۴|ڴ|ڴ{ڴ{ٳyٳyزwرvذuׯt֮s֮qլqլoԪmԩlӨjҧhѥfѥeУcТbϡ`͟]͞[̜[˛XʚVɘSȖRǕPƓOƒMőKďIĎHÌG‹FFCABA@?=;9642}0{-{,x*v)s(s&r%p#o!m!m kihhfeEڹxE  !"#$%&&'(()**+@%Nh<SPּܸhҨaΡ`͡`ΡaϢbϢbϢbУcУdТeѤeѣeѤeѤdФeХfѤfѥfХfФeФeХeФdϤdФdФcϣcϢaϢaϢ`Ϣ_΢^͡]͟\͟\̞[˝Y˜Y˛YʚVɚSșRȘPǖOǔMƔKŒIŐGďDĎCŒB@=;97530}.{,y+x*v(t's%r$p"n!m!mljigffFڹxE  "#$%&'())*++,,-B&Tj='`mݹeЧ[͟\͟]͟]͠^͠^͡_Ρ`΢`Ρ`ϡaϣaϢaУcУcУcϣcФcУcФbФbФcФbФbУbУbϣ`УaϢaϢaϢ_ϡ^Ρ^Π]Ο]͟\͞[˞Z˝Y˜X˛W˚UʙSəQǘQǗOǖMǔLŒJŐIŐGÏEŽCŒB@=;9752~/}.{,y*w*u)u&s%r#p"n!m kjjigfeEڹxE !"$%&()**+,--../@%Sj=*cvƦmժ\͝X˛Y̛Y˝Z̞[̞\̟]͟]͠^͠^͠_͠`͡`Ϣ`Ϣ`ϣ`ϢbϢbϣaϣaϢaϣaϣ`ϣ`ϣ`ϣ`Ϣ`Ϣ`ϡ`Ρ_Π_ϡ^Ρ]͟]͟\͟\͞\̞Z̜X˜X˛W˛V˚SʚRʘQɘPȗOȕMǔKǒIƑHŐGďDÎCŒB?=<99631~/|.z,y*w)v)u's%r$p#o!n lkjihgfEڹxE  "$&')*+,--.//01$@d:%_uƥcѤSʙRʘTʙV˚W˚X˜X˜Y̞Z͞[͞[͞\͞\͟]͠^͡^Ρ^Ρ_Ϣ^Ϣ_ϡ_΢_Ρ`΢_Ρ`ϡ`Ρ_Ρ`Ρ_Ρ_Ρ_Ρ^Π^Π]͠]͟]͠\͞Z͝Z˝X˝W˛V˛V˛U˚TʚRʙPɘOȖNǕMǔKƒIŒGƑFŐDĎCA?>;:87520}.{,y*w*w)v(t&r$q$p"o!n mkjhhgfEڹxE !$&()+,-.//01122\5Qb_ϢPȗOǕPɗQɘRʘSʙTʚV˚W˛W˜X̝Y̝Z̞Z͝\͞\͟\͞\͟]Π^Π^Ϡ^ϡ^ϡ^ϡ^ϡ^Ϡ^Ϡ^Ϡ^Ϡ^Ϡ^Ϡ^Ϡ]Π]Ο\͞\̞\̞[˞Y˝Y̜X˜W˛V˛UʚTʚRʙRɘQɘOȗNǖMǔKƔIƒGőFőDďCÎB?=<;97431~/|-z,x*w)v(u&s%r%q#o!n mljihhfeE‰ڹxE !$&(*,-./012233@%Zi=BxbУMȔLƔLǕNǕNȖOɖQɗRʘRʘTʙU˚V˛V˛W˜W˝X˝YɛWVWZĘ\̞\̞\͟\͠\͠\͠\͟\Ο[͞[͟[Ο[͟Z͟Y͟Y͞X̝X̝X˝W˜U˜U˛V˛T˚S˚RʙRʘPɘOɗNȖNȕMǔJǓIƒHőGĐEĐCÎA@>=;:86420~.{.z-y+w)v(t&s%r$q"p!n mkjigffeEڹxE  #&(*,./0123344]6VvǧkիLǔGĐHőIƓKƓKƔLȕMȖNɗOɗPʗQʘRʘS˙T˚U˚TPHHHZZZbbb\\\NNNPxTXǚZ̞Y̞Y̞Y̞Y̞Z̞Y̞X̞X̝X˝X˝X˝W˜V˜U˛T˛T˚T˛RʚQʙQɚPʙOɘOɗMɖLȕKȔJƓIƒGƑEŐCďBÎ@?=<<:87431~/}.{-y-x*w)u(t&s%r$q#p!n mlkjhggfEڹxE !$'*,-/013344'Gh<>uQȗDDÎEďGŐHőHŒJƓKƔLǕMȖMȖOɗQɘPɘQʘQȗLsOOOqqqgggJJJOvTV̜V̜V˜V˜V˜V̜U˛U˛U˛V˜UʚT˚T˚S˚SʙRʚQʙPʙOɘOɗNɖMȕLǔLǓIƒHƑGŐFŐDĎBÍ@Œ?><;:87431~0~/}.{,y*w)v(u's%s$r#p"n!m mkjihgffEڹxE "%(*,.012344O-p {IcdӦDÎ?AŒBDÎEÏFđGĒIœJƓKƔLǕMȕMȖNȖOɗMHHH}}}RRRLsSʚT˛T˛T˛T˛S˛S˛S˚S˚RʚRʚQʚQʙQʙOʘOɘMɗMɗLɕKȔJȔJǓIǓHƒFőDŐDĎBÍ@?>=<;975422~1}/|,z+x*w)v'u%r%q$q"p!n nmkjihgfeEڹxE "%(*,./1234^6XշOɖ<<>@‹ABÍBÎDďEĐEđGŒHƓIƔJǕJȕKȕKKKK{{{vuuzyy~~~FFFNR˚S˚RʚRʚRʚQʙQʙPʙPʙOʘNɘNɗMɗLɖJȕJȕIǔIȓGǓGƒFƑEƑDĐAď@Î@?>=<;:865432~0|/|1}3}1|.z-x,w+v*v(t's'r&q$o$o#m#n"l"k kJÍۻxE !$')+-/012e:/h{ݷCŽ9:;=>?Œ@ŒAÎCĎDďEĐFőGŒGƒHƓIǕJȕH~hrsrqqqvvv|||SSS׶xE "%')+-./h‹?ŒAÍBÎCďDĐEđGŒFŒGœGeeevvvpppssswww}}}WWW=x^7o7o7o7o7o7o7o7o7o7o7o7n7n7n7n7n6n6n6n6n6n6n6n6n6n6n5n5n5n5n5n5n5n5m5m5m5n2k%_$_%_%_%_%_%_$_$_$_$_$_$_$_$_$_$_$_$_%`YuCQ  "%')*5j=OV̚766789:;=>?@‹@ŒBÍCÏCĐDĐEĐELLLsrrtttvvvyyz}}~SSS"G6I*iI*iI*iI*iI*iI*iI*iI*iJ*hJ*hJ*hJ*hJ*hW2X3T0wR/uR/tR/tR/tR/tR/tR/tR/tR/tR/tR/sR/sR/sR/sS0rS0rS0rS0rT0qT0qU1pU1oX2rO-c@%OA&MB&LC'KE(IH)FI*EL,BO-@S0=V1;Z48]66a84e:2i<0n?0n?#  "$&3l>YLƓ43456778:;<==?‹@ŒAÌBÎCÏCďD{nnn}}}}}~}}}}}}???66666666666=#Y(bJKDzAxAx@x@x@w@w@w@w@w@w?w?w?w?w?w?w?w?w?w?w?w>wAy5nl>0&$"   !"m?ZGÍ1|1}33557779:::;=>>?Œ@DĐPz~~~}}}www4445555444444+IVKҵVl>"!  n?ND/{0|1}2~33467799::;;<>BT˚²pppzzzvvuKKK <3333333222,GY3}n?,eoâNȗ<88764321~0}/{.{-z,x+x*w(v(u'u?Kn?  n?E|GÎ/z.{/|1}2~2~3456678899:;Iƒzܷm'^OOOzzzvuurrrppokkk///n11111100000//D'Xi=%_m vڳFÍ654331~0}/|.{-z,y+y*w)v(u&t&s&rAAyn?  n?3lKŐ,y,y-{-{.|/|0}1~3~34567778>_ѣ~ί*dj=?$L444u{{{~~}{{{wwwrrrnnnkkj;;;......------,,,@%Mj=+d~ί[Ο821~0}0}/|.{-{-z+x*x)v(u't't%s%q&rGË0jn?  l>bZW˚-y*w+x,y-z.|/{0}1~2~2345556FÎByo@P.[((5PPP{{{wwwtsspppllkhhg~~~@@@+++++******)))(((Q/\p@Czߺ@0}0}/}.{-z,z+y*x)v(v't't%s%s$q#p&qSɖYk>_  a8/~Lܽiէ-y)v*w+x+x+y-z.z0|0}1~1~22359SɗuȧTe:##$$$:::|}|vwvrrrnnnkkkhhg{{{@@@((''''''&&&&%%$$$##f;UvɨLƒ1}.z-z,y,y*x*w)v(u't&s%r%q$p#p"o'tgӥڻ~L`7, vDjž1|(u(v)w)x+x+y,y-z-{.{/|/}0~1~1~8cѤMp@Q/J !"GGGwvwqpqmnnjkkhhh~@@@$$$####""""!!!! N6c$\BJxeqO|i<b5f1n,v*w)u(u't's&r%r$p$p#p"n"n+vgvDuC~C{9&u(u)v)w*w*w+x+x,y-z.z/{/|0}0~;rد1jn?333UTTTvuummmjjjgggAAA 222JAAAVVVtutyyy```HHH6_+p(t's'r%r%q$q$p#o"n!n!n5}AyuC{uCFYJŐ&t&u'u(v(v(w)w*x*x+y+y-z-{.{/|;ߺܿYm?z;;;mYYYwwwqqqpppAAA???YYYSSS5~]'q%r$q#p#p"p"o!n!m!n mG‹XtCB( yF~ұmת+w&t&t&u'u(u(v)w*x)x*x+x,y-z-{9ԵPl>b<<>>===<<<:9:988BAB}}}}}}zzzuuurrr7oU!n!n m m m m ml!mbѡ|а yFxExEF4m3}$r%r$s%r%r&s&t&t'u&u(u(uDglllkkjkkkkkkjjjjjjiiihhhghggghhhhwwwoooyyyzzzFFFDDDCCCBBB??@=>====<;;998@@@~~{{{wvwrrrmmlnno___(f!o n m m mmll/z1kxECxE yFӲ`Т%s$s%s%s%s%s%s%s&t&t'u'u'uGjonnnmmmmmlmmlmmlllkkkkkkjkjijiiiiwwwppoyyyzzzHHHGGFDDDCCCAAA???>?>==<;;;===|||xxxttsoonhhheeeGGG"n!n n n m m m l n^ϟ|Ѱ yFxExE?3l4~%r$r%s%s%s&t&t&t't&u'u(v)wZxpppoooooooooooonmnmmmlmmllllllkkkwwwpppyyy|||JIJIIIFGGDDDCCCBBA@@??>>===<<<^^^{{{xxxuvuqrqllkgggbbblmmgfg*d!o!o!n!n!n!n!n m0y1jxE<xEw̫eӥ&t%s$r%s%s%s&s&s&t&t't'u'u;rrrrqqqppppppppooooooooomnnmmmllmwwwpppyyy~}}KKKIIHHHGFFFEDDCCC@@@???>?>===CCD~}~tttqrqmnmiiieeea`abaa3yZ!o!o!n!o!o!o!o n!ofӥtʨxExE)$_7%t%s&t%s&s&t%t&s'u&t&t't+wtڰe|stsrsrrrrrqrqqqqqqqqqppppppooonnnwwwqqqyyy~~~LLMJJJIIIGGHEFEDDDBBC@@@??>>>>AAAgggxxxooojkjfgfccc```]]]6rV"o"o"o!n!o!n!n n!n5"]xE&xEa}߷(v%t&t'u&t'u'u'u'u't't&t&uD‹@p[sttsttttttsssssrssrrrqrqqqqqqqpopwwwrrryyyMNNLLLKKKIIIGGGEEEEEDBBB@@@?>>A@AXXX~}}ssshhhdeeabb^^_^^_5xY#p#p#p"o"o"o!o!o!o$q}߶]xE~xENIŐ'u'u'u'u'u'u'u(v'v(u(u'v,y\CdUŜuvvttutttuuuuuuuuututssssssrrsqqrwwwssszzzNOONNMLLLKKJIIHGFFFFEDDCBBB@@ABCBlllGGG|||zzzpooedea``^^^fef3~\#q#p#p#q#p#p"p#p"p!pGÌ~LxE xEH9r.{'u'u'u(u(v'v(v(v(v(u(v(vHĎSU]ZwwxvvvuuuuuuvvvvvvuuuuuttttsssrrrwwwssszzzOPPONNMMMKKKJJIHHGFFFDDECCCCCCEEDopoLLL}}}{|{zzywvwooogffdddnnn3}\$q$q#q"q"p#p#q#p"o"o+v5oxECxErȦk֪(v(v(v(v'v(v(v(v)v(v(v(v,z_xE~[[[wwwvwwwwwwvvvvvvvvvvuuuuuttttttssxxxsttzzzQQRPPPOOOMMMLKKJJIHGHFFFDDDCCCFFEqqqVVVIII~~||}zzzvvvuuurrrooossr4}\$r%q%r#q$q$r$q#q#p#p#pjըnƣxExEPC‹)v)w(v)v)v(v)w)v)v)v)w(wBXxE[[[yyyxxxxxxxxxwwwwwwvvwvvvvvvvvvuuuxxxtttzzzSRSQQRPQPOOOMMMLLLJJJHHHFFFCCCFEFqqq[[[EEEEEEhhh|}}zzz{{zzzzono4}]&s%s%r%r%s%r$q$r$r$q$qBOxExEF8q/|)w)w)v*w)w)w)w)w*w*w*v+xqخnŢxE[[[|||z{zyyzxxxxxxxxxxwwvvvwwwwwwvwvxxxtttzzzTSTRRRQQQPPPNMMLLLKKKIIIHHHEEEGGGrrr[[[EEEQJJJvvvhhh5~]&t&s%s&s&s%r%r%r%r%s%r,w6oxECxEhv۲*x)x)y*y*y*x*x*x*x*x*x*x71jxE;[[[||}|||{||{{{zzyyyyyxyxxxwwxwwwwwwxxxuuuzzzUUUSSSRRRRRQOOOMMMLLLJJJIHHGGGIIIsss[[[EEEEEEMGGGZZZxxxpppKKK^^^hhh;b'u&t&u&t%s%t%t&t't&s&s&sv۱exExE |IPʖ*y*y*x*y*y*y*y*z*y*y*z*yUܾ̚ zGxE[[[}}}|{||||||}|||{zzyyyyyyyyyxxxwwwxxxvvvzzzWWWUUUSSRRRRPPPNNNMMMLKKJIJGHHJJJuut[[[EEEEEE"EEEQEEE}EEEEEEEEEEEE{EEEIEEE7aaajjjKn'u(u'u't't&u&t't'u&t&t&tPȔܾ zGxExE'#]9+y+x+x+y+y+y+y+y+y+z+z.{UxEp[[[~~~}}}|}||||||||||{{{zzzzyzyyyyyxxxxvvw{{zWWWWWVUUURRRQQQOOONNNMMLKKKIIIKKLuuu[[[EEE7aaakkke*v(t(t(t(t(u(t't'u'u't'u5![xE$xEVD{.{,y,y,y-z-z-z,y,z-y-z,y9(bxE,[[[~~~~~~~~}}}|||}|}}|}|||{{{zzzyyyxxxwww{{{WXXWXWWWVUUTSSSQQROOPOONLLLJJJLLLuuu[[[EEE7aaakkk|4(u(v(v(v)v)u(u(v(u(u(u*wAxxERxEhxܴ-{-{-{-{,{-{-{-z-{-z/}4]Ο~LxE[[[~~~www{{{ZZZXYXWXWVVUTTUSSSPPPOPOMMNLKLNNMwvw[[[EEE7aaallllOȔ)w)w)x)w)w)w(w)w)w(w(v(vwܳdxExE yFշ]Ϡ-|-|-|-|-|-|.|28=BEsĤ{I[[[xxx{{{\\\ZZ[XXYWWXVVVTUUSRRPPPOOONNMPPPxxw[[[EEE7aaammmXssڰ*x*x*x)x)x)x)x*w*w*x*x)x\ϟӳ yFxExENGŐ.}.}-|0}5=BGFGEHMxEP[[[xxx{{{]]]\\\ZZZXXXWVVUUUTTURRROOONNNPPPyyy[[[EEE7aaannnCu_-{+y+x+y+x+x+x*x+x+x+x+xEÍ~MxE xE*%`916>FŒJKJŽHF‹GŒGQǔ,dxE$[[[xxxjjjzzz^^^\]\[[ZZZZYXXVVVUUUSTTQRROOOQQRzzz[[[EEE7babopp3jQ8,z,z,z,z,z,y,z,z+y,y,x5#]xE'xEH:r?HLĐNđKĐJÏKÎIÎHHÍHÍHbϢOxE[[[dddZZZ}}}^^_^^^\]\[[[ZZZXXXVWVUUTSSSQQQSSS{{{[[[EEE7bbbppp(aGJƐ-z,{-z,z-z,z-{-z-z,{,z.{7pxEDUi\PœPŒNđLđLđLĐKĐKÏIÏJÏJÏIÎwذչ{I[[[~~~mmmnmm`_`__`^^^]\\[[[YYYWWWVVUTTSRRRTTT{{{[[[EEE7bbbqpp+[EՁҳ`Т.|.{.{.{.{-{-{-{.{.|.|.{JxE_8i}ƨOĒNđNĒNŒMőMŒKÑLÐKÐJÐJÏJĐuĤ yF[[[uuueeehhhaaa``````^]^\\\ZZZYXXXWWUUUSSSUUV}}}[[[EEE7bbbqqq.XEkŸu۲/~/}/}/}/}/}/}/}/}/|/|.|_xE|3eд߻PœOŒOŒOĒOĒNŒMđLÑLÑMđLĐKĐ^xEh[[[dddYYY~~~~~zzzzyybcbaaa```]]_]]^]]\[ZZXYYWWWUUUWVW~~~[[[EEE7bbbsss2UES/~0~/~0~0~/~0~0~0~/~/~0~sٰoŢxE/bؾ~۵QƔQƕQƕPŔPƓPƓOœNƒMŒMÒMĒMőNxEQ[[[}}}mmmzzzdddbbbaaa```^^_]]]\[\YYZWWWVUVXXX~~~[[[EEE7bbbuuu5RECz1~1~1~0~0~10~0~0~0~10fԧ}ϯxE,`žwٰRǕSǕQǕQƕQƔQƔQƔPƔOƔMŒNœOƓ=sxE:[[[tttMMMzzzfffdddbbbaaa___]]]\\\ZZZYXYWWWYYZ[[[EEE7bbbvvv8PE4l422222221211_Р׹xE,`ɣs׮SȖSȕSǕRƕRǕRƕQƔQǔPǔPǓNƓRȖ8nxE4[[[iiiIIIiij`a`ffeccdbbc```^_^]]][[[[[ZXYXZ[Z[[[EEE7bbbwww9OE/i733343433333\Ο۾xE,`Ȣu֯UȗUȗTȗTȖTȖRǕQǕPǔQǔQǔQǔVʙ+bxE#[[[___FFFWWW_`_bbba``^__]]][[[YYY\[\[[[III8bbbwww66666566666\ϠھxE-aȤxرXʚYʚWʚWʚVəVəVɘVɘSɗSȖSȖZ̛*bxE"[[[lllMMMQQQuuu[[[EEE7bbbxxy=LE"]>76777777777]ТھxE-aɥyٲZ˜Z˛XʛXʛX˛VɚVəWəVʙUʙUəXʜ7nxE3[[[fffHHHPPPEEE*EEEEEE7ccczzz:OF0i;77777778778^ѢۿxE/bţ~ڴ[˛[˛Z˜ZʜZ˛YʛXɛXɛWɚWʚWɚXʚ;qxE9[[[]]]FFFGGGcEEEEEE8cccyyz9PF;r978887888888cӦؼxE4f޻\˝\˝[˝[˜Z˜Z˜ZʜYʛXʚYʛXʚYʚKxEM[[[}}}UUUEEEGGGOEEE EEE8cccyzz5REK>Š99999999999k֬вxE9jԺ]̟\̞\̝\̞[̝[̝Z˝Z˜Y˛Y˜X˜X˛\xEd[[[rrrLLLEEEEEE8EEEEEE8ccczzz2UE[LƓAŒ::::::::::wܴuȧxE5gɭ^͞^͞]͞]͞]͞\͞\͞[̝[̝Z̜Z̜Y̜t£ yF[[[dddHHHEEEwEEE(EEEEEE8ccc{z{/XEsäMǔMǔCÎ;::;;:::;cxE+_rq_͠^Ο_͟_͟_Ο_Ο_͟]͞\̝\̝[͝[̜ҷ zG[[[[[[FFFEEE`EEE8ccc{|{-\GӊӸ{۶NǕNǕNǕDÏ=<<Š<<;‰;‹=‹=‹=Š=‹=?‹Ì>Ì>Ë>Ë>ÌEƐ(bxE-N/dt֮dУcϢcϢbϡaϢaϡ`Ρ`Ρ`ϡ_͠_͠aϢG{xEH[[[```}~~~}}}||GwbTʙRʘRɗRəSʙSʚQɘBď>Í>Ì>Ì>ÌS̛OxExEV޻fФeФdУcϣbТbТbУaϡaϡ`Ϣ`ϡ`ϡrxE[[[QQQuuu~~}|||||{{{{}}}\vSʙSʙSəSʙTəSʙVʚPȗAč?č@Í?Íi֫׻ yFxEVϵfѦfѥfѥeѥdФcФcФcУcϣaϣbϣ`ϡݹ {IxE[[[WWW~~~}}|}rwٳTʚTʚTʚUʛUʚUʚVʚW˜NɖAĎAĎAĎn xERdohѦfѥfѥfѦeЦeФcУcУcФbУbУbϣnի+cxE#[[[GGG\\\aФƯU˛U˛W˛V˛V˛W˛W̜Y̝IǓAďCƐJxE\ {I0K{oիhҧgѦgѦgѥeѤeѥdФcФdФcФcФdѥ_xEe[[[|||HHHdddwY͝W̜W̜X̜X̜W̜X̝X͝X͝Z͞V̜EǑLɗ(axE,xE *`ܸhѧhѧhѦhҦgҦgѦfѦeХeХdѤdХdФ {HxE[[[vvvabaKKKqqqcY̞Y̝Y̝Y̞Y̞ZΞZ͝Z͞[͞[͞]ΟQʘbԦ}KxE WӹjӨiӨiӨhӨiӨiӨgҧfѦfѦfѦeѦeѦq֮3jxE/[[[}}}ooo[[[QQQVxZ͟Z͟[Ξ[͟ZΟ[ΟZΟ[Ξ[͟\͠[Π\ΠsŤxEPWgnիjөjөiӨiөiӨhӧhҧfҦfҧgҧfҧfӧwĥ yF[[[}~}|}}xxxhhhVVVZZZRu[Ο[Π\Π\Ο[Ο[Π[Ο\Ο\Π\Ρ\ΡbФCzxEOxE~Lϴzܷpذpذoدoخqٰqذpذpٰqٰrٰrٰqٯqٰqٰrٱ']xEN_Y|۶{۶{۶z۵z۶z۵y۴w۴iuutuuuuuuuuuvvvvvvvvvvvvwwwwwwwww|{|{{{{{{z{zzzzyzzyyyyyyyyyyyy||{[[[xEXUս|ܷqٰqذqذpذqذqٰrٰrٰqٱrٰrٱrٰrٱrٱsٱM~~M[#YǬ߼|ܷ{۶|۶{۶z۶z۵z۴jtttttttttttttuuttuuuuuvuvvvvvvwww{{{{zzzzzyyzzzzzzzyyyxxxxxxxxx{{{[[[xEv/fzܶrٱqٱqٱrٲrٱrٱrٲrٱrٱrٱsٱtٱsٲsٲtٱ}ܷzUxE ']ݺ~ܷ}ܸ|۷|۷|ܷ{ܶjssssssssstttttttttttttuttttuutvuuz{zzzzzzzzzyyyzyyyyyyxxxxxxwwwz{z[[[xE yFK~y۶rٱrڲsٱrڲsڲtٲtڲtٲtٱtڲtٲtڱtٲtٳtٳy۴WxE zHFArݹ~ݸ}ܸ|ܸ|ܷ|ܷi[[[xETPy¤w۵rٲsڲsڲtڲuڲuڲuڲtڲuٳuٳvڳvڳuڳuڴuڳx۴7j zHBNu_޹ݹݸܸ}ܸp}}}JbW@tv۴uڳuڳu۳u۳uڴu۴u۳vڴwڴwڴwڴvڴwڴwڴv۴w۴U~MrWvݺ޹޺ܸ~ݹlb}sb}rb}sb}sb}s`um]gc]ca]da]da]da]db_eccfeboiMh\P_XY\Z[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[Y\ZP_XHk[v{ܹv۴v۴uڴw۵w۵w۴w۴v۴w۵w۵wڵwڵxڴx۴x۵w۵w۵kS(]ʱ޺޺ݹݹݺ޺޹ݹݹ޹ݹ~ݹ}ݸ}ݸ}ݸ|ܸ{ܷ}ݸo"Z yFnxExExEoVjx۵w۴w۵w۵x۵x۵w۵w۵xܵw۵x۵y۵y۵x۵y۵z۶yܶx۵ĩ"YxE0cи߻޻޻ݹݺ޹޸ݸ~ݸ~ݹ}ݹ}ݸ}ܸ}ܸ|ܷ|ݷ|ܷ{ܷ~ݹq'_{IxE3xE5 yF"[m|޷x۵w۵w۵xܵxܶx۶x۶x۶x۶zܶyܶz۵z۶z۶yܶzܶzܷzܷ˲)^xE xE!$Z޻޻ݻ޺޺޺޺ݹ޹޹޹ݹ~ݹ~ݸ}ݸ}ܸ|ܸ|ݸ|ݸ޺ǬAu~N yFmxE)xExExE*xEm {I;p}ũ}޹xܵyܷzܶyܶyܶzܶzܶzܶzܶzܶzܶzܶzܷ{ݷzܷ{ܷ{ݷzݷ{ܷѹ,`xExE.,a߼޻޻޻޻޻޻޻޻޺޺޺~ݹ~ݹ~ݹ}ݹ}ݹ}ݸ|ݸ|ݸ~޺p:n~M zHxENxE!xExExE!xEO yF|J3ik}޸zܶzܷyݶ{ܷ{ܷzܷzܷ{ܷzܷzܷ{ܷ|ݸ{ܷ|ݸ|ݷ|ݸ{ݸ|ݸ|ݸ|ݷѺ&\xE+xE-3eй߼߼߼޻߻޻޻޻޻ߺ޺޺޺޺޺~ݹ޹~޹}޸|ݸ}ݹǫX2gQ|J zHxEjxEOxE<xE7xE'xE'xE&xE'xE7xE<xEPxEj yF {IN,cR~Ʃ{ܸ{ݷ{ݷ{ܷ{ݷ|ݷ|ݸ|ݸ{ݷ|ݸ|ݸ|ݸ|ݸ|ݸ|ݸ|ݸ|޸}ݸ}޸}ݸ}ݹ~ݹ˲,`xE+xE2dʱ߼߼߻߻߼߻߻߻߻޻޻޺ݺ޺޺޹޹~޹~޹}޹޺ʯmXH{Bu4j4i3h4i@tExVjȬ|޹{ݸ{ݸ{ݸ|ݸ{ݸ{ܷ}ݹ|ݹ|ݹ}ݸ}ݹ}ݹ}ݸ}ݸ}ݸ}ݸ}ݸ}ݹ~޹}޸~޸~ݹ޺ƫ*_xExE)^z߽߽߽߼߽߽߼߼߼߻߻߻޻߻޻޻޺޺޺޻޺~޹~޹~޹޹߻~޹}޸}޹|ݸ}ݹ}ݸ}޸{ݸ}ݸ}޹|޹}޺~޺~޹޹~޹~޹~޺޹~޹~޹޺޺޺޺ߺ߼p#YxEVb߾߼߼߽߼߼߼޻߻߼߻޻޻߻߻ߺߺ~ߺ޺ߺ}޹~޺~޺~޹~ݺ߻߼߻~ݺ}޹}޹}޹}޹}ݹ}ݹ}޹}޹}޹}ݸ}ݹ}޹}޹~޺~޺~޺߹޺޺޹޺~޺~޺޺ߺ޺߻߻޺޺޻XTOpFv߾߽߽߽߼߼߼߼߻߼߼޻߻߻޺޺ߺ޻޺ߺ߻޻ߺ޺~޺~޺޺޺~޹}޹}޹޺ߺ~޺޺޺޺޺~޹}޹ߺ޺޺ߺߺ޺߻߻޺޻޻ߺ߻߻߻߻߻߻?p~Mo zH@'\Ȯ߽߽߽߼߼߼߼߻߼߼߼߻߻߼߼ߺߺ߻ߺ߻߻߻߻߻ߺߺ޺ߺߺ߻޻߻߻߻ߺ߻ߺ߻߼߻߻߼߼߼߼߼߼߼è-a zH>xE $Z]߽߼߼߽߼߼߻߼߻߼߻߼߼߼߻߻߼߼߼߼߼߼߽߼߼߼U!XxEOY2eʱ߽߾߾߽߽߼߼߼߼߽߽ƫ*`~NXxE &\UN}!XxE |K=0cme+_}L;PW*_tk&\~NUxETX+`qi']RUxExEQP.a\ӽйU*_QPxE}L4(]>otm:l#Y}L3xEQQ*_Brsӽm>o'\QPxExEQP(]/dU|ԾҼwQ+`%[QPxExExE)S_&\1c=nUméҼѻiQ;m.a&[Q]xE(xE#Y1d/8iQ3es8ic9rA+c_ؿ|ڳrլkҨhѦiѦiѦiѦiѦiѦiѦhѥhѦhХgѥfФeУdϣcϢaϢ`Ρ^Π]͟[˝Z˜Y˛WʙTɘRȖOǕMƓJőHďFB@>;752|.z,x)u(s&q$o"m!kihgeaϟkĠxE !"#$&&'()*F(Rk>WYݺmԪcϣbϢbТcУdУeѣeѤfѥeХfѥgѥfХfХfФeФdϤdФcϣbϢaϢ`΢_͡^͠]͟\˞Z˜Y˛WʚTșRȗPǕNƔKŒHŐEďCŒA>;963~0|-z+w)u's%q#o!m ljigfcРkĠxE !#$&'()*+,-I*Yl>,dwƦ|۶cϥ]͠]͟^͠^͡_Ρ`ΡaϢaϢaУcϣcϣcФcУbФbФbФbϣaУaϢ`Ϣ`ϡ_ϡ^Π]Ο]͟\͞[˝Y˜X˛VʚTʙRȘPǗNǔLƒJŐGďEB@=:852~/|-z*w)u's%q#o"m ljigebРkĠxE "$&()+,-../<#Pi<,e}˭gӦY̜X˛X˜Y̞[̞\͟\͟]͠^͠_͡_΢_΢`ϡ`Ϣ`ϢaϢ`Ϣ`΢`΢`Ρ`΢`Π_Π^Ρ]͠]͟[͞Z̞Y˜W˛V˛U˚RʙPɘOȖNǔKƒIƑFŏEĎBŒ@>;8730}.{+x*w)u's%q#p"n lkihfcРkĠwD  #&(*,-//012c9Vrã]ϠQʗQɘSʙUʚV˛W˜X̝Y͝Z͝[͞\͟\͟\Π^Π^ϡ^ϡ^ϡ^ϡ^Ϡ^Ϡ^Ϡ^Ϡ^Π^Ο\Ο\͟\̟Z̝Y˜X˛V˛UʚSʚRʙQɘOȖMǔKƓHƒGőDďC@><:641~/{,y*w)v't%r$p"o mlihhfbѠkĠwD  $'*,./0123M,km?O[͟LǕMǕMȖOɗQɘRʘSʙU˚U˛W˜WǚUR}RzTY[˝\͟\͟[͟[͟[͟[͟[͟Z̞Y̞X̝X̝W˜V˛U˛T˚SʚRʙQɘNɗMȖMȔKǓHƑGŐEďC@>=;9531~.{-y+w)v't%r$q"o mkjhgfbРkĠwD "&),.01334a8 [ҵbѤIƒGőIŒJƓLǔMȖNɖOɗQʘRʘRɘMxIII]]]xxx|||mmmTTTGGGQzWŘX̝X̝X˝X˝W˜W˜W˝V˛U˛T˚TʚSʚQʙPəOɘNɗMȕLǔIǓHƑFŐCďAÍ?><:8631~/}.{,x*v(t's%r#p!n mkjhgfcРkĠwD #'*-/123-Jh=;96421~/|,y+x)v't%r$q"o!n mkihgeaПkĠwD #'*-/12L,g zGf\Ϡ?Œ=?ŒAŒBÎDďEĐFŒHƓIƔJȕKœFFF|{|qqq]uyˬ޺޹޹޹~޹~޹}޸}޸|޸{ݷzݶyܵxܵxܵv۴vڴsڳrٱqرpذoدn׭m׬k֫iթiթhԨfӧhըm֪pجm֫l֪kըjըiԧhԦhԥfӤfңeңdҢcѡpȤwD "%(+-/X3zOбHœ89;=>@ŒBÎCďDĐFŒHƒHƓGr~~uuuttt{|{^~qzϱϱϱϱϱϱϱϰϰϰΰΰΰΰΰΰΰ~ΰ~ί~ί~ή}ή}ή}ή|ή|ή|ήzͬmġlġmġmġlġlġlĠlĠkĠkĠkĠkĠkĠkĠmƢAzwDW "&(+_7TBŒ678:<=>@ŒAÍCÎDĐEđERRRtttwww}}}0RCl>l>l>l>l>l>l>l>l>l>l>l>l>l>l>l>l>l>l>l>l>l>l>l>l>m?m?m?i=i=j=k=l>l>n?n?p@pArAsBtCvDwDtCY "$c9"\uڲ;35678:;<=?‹@ŒAÎCÏHyyyy~xxx77766666551NZTeb]\\\\\[[[[ZZZZYZXYb8~$"  c9rUm֫81}245779:;;=>FŐdӧ}}}PPPF444433 8 {I&``Sa8p  a8YOp׭5/{1}2~3466889:?X͝Ky___}}}wwwttt{{{66611111105>#Rd9}KLSʗ9432~0~/{-z,z+x*w(u&t-yl֪ݿN_7W  U14 zGԴzݵ4,z-{/|0}1~335577DĎxܵW~L`7@BA}}}xxxsssmmm???..-----,,+3a8~MXsڱ>1~0}/|-{,z+y*w)v't&s%r.yxܲ~ұ zGS01  tCiž5*w+x,y.{/|1}1~2347Nǔҳ"]h</&111aqqqzzzuuupppkkjxxxBBB*))))(((''&&0i=#]ҳHÐ/}.{-z+y*w)v't&s%r%q#p/yftC tCF}:)u)w*x+x,y-{.{/}0~1~5Z͝W yFZ4[ !!???sssnnnjjjxxxAAA$$$$$##"""!! T8o"dFLpah~wJra;y^4g-t)v(u's&r%r$q#p"n4}C{tCtCV#^GÍ'u(v)w*w*x+x,y-z.{/|7gԧ9qp@...FLLL||}qqqjij}}}BBB ???TTT{{{rrrQQQ8wZ+m&s%r$q$q#o"n!nD"]tCT]6 {HٺdҤ)v&u'u(v)v)x*x+y,y,z4n׬%_p@999_OOO|||wwwCCC###)AAA}}}TTT5|\$q#p#p"o!n m$paСظ zGP.xET0{&s&t&t'u(u)w1rGgTh_Tla^qibkhX][Z[[[[[[[[[[[[[[ZZZZZZZZZZZZZZZZZZTTTMMMJJJYYYZZZYYYZZZZZZZZZZZZZZZZZZZZZZZZMMM텅tttpppuuu{{{ttt7qW&m"o"o!n!n m,uRxExE;!\A%r%s&t't't(u(uFfmmmPPPkkkaaaqqqmmmrrryxy~~7qW"o!n!n mml=ZxE8xExͫl֩(t&r&s&t't't(u(uLucqqqkkkPPP\\\aaaZYZJJJrrreeexxxwwwvuvtttsssqqqZZZqqqssruuu{zz~~~}}}5vY"o!n!nll"niըu˩xExEK2l4%r&s&s&s't(t(u(uKvc|||nnnnnnmmmlllkkkkkkkkkqqqqqqeeenooIIIGGGFEFDDDBBA@??EEE~~}}}xxxzzz___*d!n n m ml0z0jxEHxE yFյ^ϟ%r%s%r%s&t&t&u'u(uPxg~}~kkkkkkjkkjjjiiihhhhhhqqqrrrfffnnoEDECCCAAA?>>===:::AAAzzztttnnm8jT!n m m mm l[ΝԳxExEC4m1|$s%s%s%s%s&t'u'u,ybunnnnnnnnnmlmlllllljkjqqqrssgggpopHHHEEECCCAA@>??===???~~~z{zvvvppoihhjjj\\\(f!o n n!n m.x1kxE@xE}Ѱaѡ%r%r%s%s&s&t&t'u'uIďrpqqppppppoooooonnnmmmqqqtttgggrrrJJIGGGEEECCC@@@???=>>\\\vvvqrqllkfffaaa2~[!o!n!n!o!n!n`П{ϮxExE+%`5%s%s&s&t&t&t&t&t0{WtgrrrrrrrrrqqqqqqpppoooqqquuthhhrrsKKJIIIFFGDEDBBB@@@>>>GGG{{{mmmhhhccc___5uX"o"o!o!o!n!n2|$^xE)xEdxݴ'u&t'u't'u'u'u't'uU˙CeUttttttttttstrsrrrrrqrqqquuuhhhtttMMMKKLIIIGFFEEEBBB??@JJJKKK~~~tttgfgbab]]^4|["p#p#p"p"p"o$qwܲaxExE }KGĎ'u'u(v'v(v(v(u(v1}>vO_X͠vuuuuuuuuvvvtuttttsssqqqvvviiivvvOOOLLLKJJHHGFFFDDDBBBMMLsssTTT|||yyyrrrfffddd4~\$q#p#p#p#p#p"oDŠ}KxE xEG9r.{(v(v(v(v(v)v(v(vUʙ zH[[[wwwwwwvvvvvvuvvuuutttrrrwwwijjwwwPPPOOOLMLJJJHHHEFFCCCONN}}}RRR}}}yyywwwvvvsss4~]%r%r$q%r$q#q#p*v6oxEDxElàpخ)w(v)v)v)v)w)v)v.zGxE^[[[yyyxxxxxwwwwwvvvwvvvwrrrxxxjjjxxxRRRQQQNNNLLLJJJHHHEEEOOPUUUEEEqqq~7`&s&s&s%r%r%r%r$roحižxExE |IJő)x*x*y*x)x*x*x*xGĎNxE[[[{{|{z{zzzyxyxxxwwxwwwrrryyyjjjyyySSSRRQPPPMMMKKKIIIGGGQQR[[[EEEUGGGfffsssaaaDi&t&t&t&s%s&t&s%sHÎ |IxExE1*d3*y*y*y+y*y*y*y*yt۱hxE[[[|||||||||zzzyyyyyyxxxrrryyykkk{{{VVVSSSQQQOOOMMMKJJHHHSSS[[[EEEEEE3EEEsEEEEEEEEEEEEEEEP[[[\|(u't't't't't&u&t0|(bxE/xEiQ-y,y,y,y,y,y,y,y30ixE:[[[~~}}|}||||||{{{zzzzzzrrrzzzkkk{{{WWWVUUSSSQPQNOOMMLJIJTTT[[[EEE,\\\{/z(u(u(u(u(u'u'u(vMxEexEvʩjժ-z-z-{-{-z-z-z/|NǓ~MxE[[[vvvzzzlll~~~XXXVWWUUUSSSPPPNNNLKLUUU[[[EEE,\\\tCÌ)w)w(w)v(w)v(v(viըsɧxExE zGPɖ-|-|-|/}39?B|۵ΰ zG[[[{{{{{{lllZ[[YYYWWWUUURRROPONNNXXX[[[EEE,\\\_zfԦ*x*x)x*x*x*x*x*xNȔ yFxExET=0~5>EHGŒGFYxEc[[[zzzpppddd]\\ZZZXXYVUVTTTQRROOOYYY[[[EEE,\\\J|g,y+y+y,y+y+y+y+y:SxExE5-fBHLÏLđKÏIŽHGKÏ7nxE4[[[YYYSSSyyyttt{{{^^^\\\[[ZXXXUVVSSSQQQZZZ[[[EEE,\\\9oW1},z,z-z,z,z,z,z0}+dxE2/bZRQœOĒMđMđKÐKÏJÏJÏWɘYxE[[[rrreeeiii```^^^\\\ZZZWWWUUTSSR\\\[[[EEE,\\\.fM<.|.{.|.{-|.{.|.{=vxEM>n{nPœNĒOĒMőMđLÑLđLĐeϣ}LxE[[[jjj___jjjaaa___]]]\[[YYYWWWTTT^^^[[[EEE,\\\'aGLƓ0~0~0~/}/}/}/}/}QxEh6gzŦQŔQŔPœPƓOœMĒMĒMĒr׭ zG[[[{{{]]]UUUyyy}}}bbbaaa_^_]]][[[XXYVUV`_`[[[EEE,\\\*\Eډغ[Ξ1~0~0~00~0~0~0~axE1cͰSǕRǕRƕQƔQƔPƔOƓNœܶг yF[[[|||~~~WWWbbbqqqeeebbb```]^]\\\ZZZWWXaab[[[EEE,\\\+ZE|ͮiթ22222222xܴmàxE0cϳTȖTȖSǖRǕQǕPǔPǔOƔ|ɪ yF[[[|||~~~yyyQQQQQQ[[[aaa```^]][[[YYYcbc[[[EEE,\\\-YErƥrٰ34443443u۲qŤxE2dϳUȗUȗUȗUȗSȖRǖRǕRǕvťxE[[[|}}~~nnnKKKRRRYYY]]][ZZccc[[[EEE,\\\.XEkwܴ44444444u۲pţxE3eϳWəWəVʙVȘUɘTɗSȖSȖwŦxE[[[}}|~~~eeeFFFQQQ`__[[[EEE,\\\.YElŸyݵ66666666v۳pţxE3eϴY˚XʛXʛWʚVəVɘTʘTɗ}ɫxE[[[~~~~~~[[[]]]~~~XXXEEE,]]]-YEqŤu۲77777777wܴqŤxE4fϳZ˜Z˜ZʜXʚWɛWɚVɚVə߻г yF[[[~~~~~~UUUEEEEEEPEEE EEE,\\\-[Fπͯnخ78888888{޸oâxE:kǫ\˝[˝[˝Z˜Z˜YʛYʛXʛ~۶ڿ zG[[[~~~sssLLLEEEEEE;EEEEEE,]]],\Fْپlի99999999dxE>ns^͟]̝]͞[͞Z˝[̜Z˜Y˜r׮ |IxE[[[~~~~gggHHHEEEzEEE)EEEEEE,]]](bHfҥEď;::;:::TxEk8ia__͟^͟^͟^͟^͞]͝\̝[̝hҥVxE[[[~~~~~~\\\FFFEEE[\\\0gN[̞OǕGő<;;;;‰;ByxEQ8iBJ|bϢ`͡_Ρ_͡_͠^͠]͟]͠aϢ3kxE0[[[~{{{vvvjjj‹=‹@Í/hxE6;l"2glԩbϢbΡ`ϡ`Ρ`͠_Π^͠^͠VxE\[[[N}iQɗQɗRɘSəHƒ>Ì>Ì>ËKɔUxEZU|ٴeФcУcϢbТaϡaΡ`Ρ`ΡˮxE[[[YYY~~~}~}}{{{e|SʙSʙSəTʚTʚFƑ?č?Í]ѣ zHxEQؿfѥfѥcФcФcУcУbϣbϣyٳ}JxE[[[FFFbbb~~~}}}zm֬TʚTʚUʚUʛW˜T˚DŐAĎwܵ~̮xE|JrvgѦfѥfѦeФdУcФdФbФiӨ5lxE2[[[{{{HHHnnn]ϠW̛W̛W˜W˜W̜Z͞R˚BŐWxEmxE9M~lӫhѧhѦgҦgѥfѥdФdѤdФsxE[[[```NNNyyxpY̞X̝Y̞X̞Y͝Y͞Z͝[͞R̚/hxE6xE %[}۶jӨhӨiӨiӨgҧfѦfѦfѦ}۷NxE [[[}}}mmmXXXVVV^~ZΟ[Ο[ΟZΟZΟ[͟\͟[Πp׮}KxE QԻkөkӪjөjөhҨhҧhҧhҧjԪOxES[[[~~~}|}vvvfefFFFaaaTw\Π\Ϡ\Ϡ\Π\Π]Ϡ]ϡ]Ϡ˭xE zGRbp֮mԫlԫkөjԩjԩiөiөhӨ zG[[[}}}{{{z{{yyywww|||HHHkkkRu]С^С^Т^Ϣ^С_Ϣ_ϢbҤUxENxE+`ݹnլnԬmԫlԫkԪjөkөjөq֮CwQ_Xɦ~|||{z{zzzTTTEEEMMMwwwSv_Т`ФaѣaУ`УaФ`Уuٲ"ZxEPѸpխoխn֬nլmիkԫkԫkԪkԪBeU~~~|}||||zzz[[[EEE EEELEEETTTTwbѤbѥbѥbХcѥcФcѦ˰}LxE7Oz۵p֭p֮p֮o֬nլm֬lիk֫sٰYth~~~~~~~|}}{{|zzz[[[EEEEEEcEEEaaaUxcҦcҦdҦdҧdҦdҦn֭CvxE4xERsׯrׯqׯqׯp֮o֮o֭o֭m֭w}}}}}}~~~~~}}}}|}|{{{[[[EEE*:NEIIIhhhVweӧeӧfӧfӧfӨfӨNxE zGQc{ڴtرtرrׯrدqׯqׯo֮o׮tذr|||}}}}}}~~~~~~}}}}}}|||{{{[[[ yFʮȴVsiiinnn_hԩgԨhԩhԩhԩo׮X zGOxEVuرtرtرsذsذrدrׯqׯqׯdw{{{{{{|||}}|}}}~~~~~~~}}}||||||{z{[[[xEWsٲhԩa`iԫiԪiԫiԪjժkիRxE zG\c~ܸvٳuٱuرtرsذsذrװrװauyyzzzz{{{||||||}}}}}}~~~~~~~~}}}}}}|||{||zzz[[[xEm5k߻i֪i֪jիkիkլk֫j֫k֬k֬tٱX zGYxESxٴwٳvٲvٲuٲuرtرtٱbuxxxyyyyzyzzzzzz|||}}}~~~}}}}}}}}}}}}||||{|z{z[[[xEZ#\nׯl֭m׭m׭l֭m׭l֭l׬l׭o׮OxExELO~yڴwٴwڳvڳvٲuٳtٱbuwwwxwwxxxyyyyyyyzz{{{~~~}}}}}}||||||{{{zzzzzz[[[xEXWqرn׮n׭n׮oخn׮nخnدoׯnׯ~ݹEwxEJQ̳~ܷy۴yڵxڴwڴxڴxڳbuvvvvvvvvvwwwxxxxxxyyy~~~}|}|||{||{{{{{{zzzzzz[[[xEZWuڳo׮o׮oدoخpدpذpذpدoذvڳǫ~NxE)_{۶zڵyڵy۴x۵yڵcvuuuuuvvuvvvvwvwwwwxxw~~~{{{{|{{{{yyyzzzzzzyyy[[[xEl%]w۴pذpذpٰqٰqذqٰrٰrٰqٰrڱ$[xE zGfU|ܷ{۶z۶z۵z۶cvttttttuuuuuuuuuvvvvvv~~~{{{zzzzyzzzzyyyxxxxxx[[[xE:ox۵qٰrٱrٱqٱrٱrٱrٱtٱsٲsٲL| zGd~Nç߽}ܸ|۷|ܷ|ܷcu|||}}}}}}}}}}}}}}}~~}T^Y yFZwڵrٲsڱsڲtٲtڲtٲtڳtڱtٲuٳݹu~MxE W߻~ܸ~ܸ~ܸg}}}?oZγv۳uڲuڲtڳtڲuڲwڳvڴvڳvڳwڴ|ݸTxExE>-b޻޺ݹvŨmhuqiztizthtohkigihgihhihhjiijjgnk_kecjghihihhihiiihhihiiiiiiiiihhhhhhiiiiiiihiiiiiiiiiihhhhhihiiiihhhhjjjhhhhiihiiiiiiihiihiiihhicjg`kfcxߺvڴvڴv۴w۴v۴w۴wڵwڵxڴwڴwڴ{ܷ&]xE<xE`@r޼ݹݹ޺޺޺ݹݹݹ}ݸ~ݸ|ܸ޺P|JxEPxE xE xEQ zGK~{ݷx۵w۵x۵x۵x۵xܵw۵y۵y۵yڵz۶|ܷ8mxE] yFtL|޽޻ݺ޺޺ݸ~ݸ޹~ݹ~ݸ|ܸ|ܸ|ܷ߼YSxExE8xExExE9xEPTݺy۵yܵxܵzܶyܶy۶z۶yܶz۶z۶zܶzݷ}ܹDu yFr zH|V޻޻޻޻޺޺ݺݹ~ݸ~ݹ}ݸ}ݸ|ݸ߼ȬDwO yFxEbxE3xExExExExE3xEbxEN?t~ũ޻yܶ{ܷzܶzܷzܷzܷzܷzܷzܶ{ܷ|ݷ{ݸ{ݸ޹N~ yF{ zH{M|߼޻޻޻޻޼޺޺޺޺޹~޹~޹}޸޻Ѹf>s%]~M zH yFxExExExE yF zG}L!Z:obз޺{ݷ{ܷ|ݷ|ݸ|ݸ|ݷ|ܸ|ݸ|ܸ|ݸ|ݸ}޸}޸}ݸ߼Fw yFz yFrDu߽߽߼߼߼߼߻߻޻޻޻޻޺޺~޹~޹߼ԼδʯʯϵԼ߻|ݸ{ݸ{ݸ|ݷ}ݹ}޹}޹}޹}޹}޹~޹}ݸ~޹~޹޺޹{p@p@p@p@p@p@p@p@pApApApAqAqAqArBrBrBsBsBtCtCtCuCuCvDvDvDvDwDwDwDxExExExExEI >$6_7al>T,cAv^sttttttssssrrrqqpponmmlkkjihgggffeee9rxEI  !J*Ih<sBWCxkѶ߼޺ݸ|ܶy۳wڱuٰrٮqحp׫mթlըkԧiӥbxE !"#$&0_6uqA*bcܷvװoԪiҧiѦiѦhѦhѥgХfФeϣcϣbϢ`Ρ^͠\̞Z˜YʚUəRȗOǔKŒHĐDA=952}.z+v(s&q#n!ljhflըaxE !"$&')*5b8~MMܸjҩbϢaϢbϢcУdФdФdФdФdФdФcФbϣbϣaϢ`Ρ^Π]͟\̞Z˜X˛UɚRȘOǕLƓIŐEÎB?;830|,y*v's$q"n ljhfm֩`xE "%')+,-.`7~MW}ܶbϢZ˞[̞\͟]͟^͠_Ρ_Ϣ`ϢaϢaϢ`Ϣ`Ϣ`Ϣ`Ϣ`Ρ_Ρ^Π]͟[̞Z̝W˛V˚TʙQɘOǖMǓIƑFďC@=962.{+x)v't$q"o ljhfm֩`xE  $(+-/01M,gm?G}lիUʛRʘTʙV˛X̜Y̝XUUY]̟^Ρ^Ρ^Π]Π^Π]Π\͟\͟[̞Y̝X˛V˛TʚRɘPɘNǖKǓIƑFŐCÎ@=;730}-z*w(u&r$p!nlihfm֩`xE $),/123b9ZѳkժPɗLƔMȖOɗQɘSʙT˚O|PPPhhhmmmZZZGGGTZ̞Y̞Z̞Y̞X̞X̝W˜U˛T˛TʚQʙPʘNɗMȕKǓHƑEŐCÎ@=;851~/|-y*w(t&r#p!nligfm֩`xE !&+.130Mhu^9q9q9q9q9q9p8p2k/h/h/h/h/h/h.h.g.g.g.g.h(b#^*d-g-g-f,f,f,f,f,f,fVtC #]6oRڼA578:<=@ŒAÍGŒNvg|||OOOJ1}K+kK+kK+kK+kK+k |J;rJF|@x@w@w@w@w?w?w?w?w?w?w?w |I]5mO-RS0NX2J[4Ga8Cg;?l><p@:p@ ]5\~M۽|ݶ;24679:;@W̝dyr;;;4333 7 {H*cgڻ~L\5Y  T06 zGӳ߹7/|0}24578Eďyܵ`(iL}~}vvvzzzKKK 9//// 2B&Ug;Q_uڲ?2~0}.{,z+x)v't0z|޶}Ұ zGS04  tCjž6,x-z/|1}2~35NƔѳ [h<1&HTTTwwwqqqnnnXXX"""F**)))(()7i=![ҲG0z,z+y)v't&s%r0zhtC uCF~:)v*w,y-z.{0}4W˛UrAZ4Y ===zzzonolllYYY%%%@##"""!! +N>8NDOOOSSSKKK>jV3e)t's&r$q"o4~D|uCuCQ![F'u(v)w*x+y-z2]ϟ9qqA @@@wwwsssWWW(((9###,AAApppvvvHHH1a$q#p"o!nB [uCOP. yF׸eӥ)u&t'u(v+vBiVd^[lebifY][Z[[[[[[[[[[[ZZZZZZZZZYYYMMMvvvVVVWWWYYYZZZZZZZZZZZZZZZZZZMMM󅅅~~~bbb5vY#p"o!n#obТն yF<#xExJ0{&s't'u(u?iKKK{{{VVVggg```ssrrrrzzzmmm5wY!n!n m+vHxEwxEPGĎ&r&s&t't(uDgtttaaaGGGhhhfffVVVjjjuuutttqqqpopZZZyyxzzz~~~[[[+c!n mlDPxExE|\)v%s%s&t'u'uJlooonnnmnmlllvuvfffVVVjjjKJJGFGEEEBBBCCC{{{uttHHH!m m m$pYxE{xEQB%r%s%s&t&t+xennnnnnmmmlllvvvfffVVVjjjJJJDDDAAA???BBBrrr|||vvvnnnllljij+c n n!n@PxExEnS)v%s%s&t&t&tE~qqqqqqpppoopyyygggVVVjjjLLLGGGDDDAAACCCJJJ~~~pppiiiccc4wY"o!o!n&rQxElxE {HMƒ&t't'u'u'u-zXqttttttsssrrr}||hhhVVVjjjNNNJJJFFFDDDFFF```kkkuuueef```4{Z#p"p"o"oJŏ zGxExE=2k.{'u'v(v(v(vKƑ8kTvvvvvvvvuttt~~iiiVVVjjjQQQLLLIIHFFFHHHttttttyyy~}~zzzpppggg4~\$q#q#q#p+w/ixE:xEjŸqٯ)v(v(v)v)v+yUDcUxxxwwwwvwvvvjjjWWWjjjSSSOOOLKKIIIJJJuuuNNNeee6_%r%r%r$q$qqحhxExE {IIŐ)x*x)x*x*w@RU]Zz{{zyyxxxwwwkkkWWWjjjUUUQQQNMNKKKMMMwww[[[EEEOFFFlll@f&t&s%s&s&sHÍ {HxExE.(b2*y+y*y*y+yj֩tɧxE[[[||||||{zzyyykkkWWWjjjXWWRRROOPMMMONOyyy[[[EEE?EEEEEEEEEEEEEEEWx'u't'u't'u/{'axE-xEeN-z,z-z,z,z0|=uxEJ[[[lllWWWkkkYZYUUURRROOOQQQzzz[[[EEEs+y(v(v(v(v)uKxEbxE ~Lrǥoخ-|-|/|4:OœVxE[[[lllWWWkkk\\\XWWUTUQQQSSS|||[[[EEEz;*x)x)x)w)wnجoŢ}KxE xE($^X͛7?FHGlӨ zG[[[UUUWWWyyyjjj___ZZZWWWTTTVVV}}~[[[EEEjT˙,y,y+y+y+yT˙ܾ"]xE&xEF=t\̝NđMÑKďIÎIÎ߻wǧxE[[[aaaXXX__`\\\YYYVVVXXX[[[EEEZuqٯ-{-z-{-{-{DÌ7pxEDxEb^XșNĒMőLđKÐJÐ\xEh[[[eeeWWW```^^^[[[YXXYYY[[[EEEL|h/~/}/}/}/}9JxE_xEylTǕPƓPƓOœMĒMĒG|xEK[[[~~~~~~~~~~~~}}}}}}}}}}}}}}}}}}}}}SSSYYY\\\dddddd```^]^ZZ[[[[[[[EEEAt_1~1~1~1~03[xEwxEtãSȕRǕRƔQƔPǔNœ;pxE;[[[qqq```[[[XXX^^^___\\\]]][[[EEEÌ>Ëbӥ%_xE)xE PӹdФcУbУaϡaϡoԫRxE[[[FFFiiibУSəTəUʚGƑ?ÍzݷwȨ~LxE yFlofѥeХdФcФcФdѥDyxEE[[[KKKtttX͝U˛U˛W̜V˛DőSxEhxE4ExlԪhѦgѦeѥdФdѤ̮xE[[[kkkpppQQQ~~~jX̝X̞X̝Y͝[͞YΞ,exE2xEU~۶hӨiӨhҧfѦfѦxٳRW\ZxxxkkkWWW[[[[{[Ο[ΟZΟ[͟[Πtذ |JxE|KҸlԪjԪkөiӨhӨiө^EcU{{{|||}}}ttteeeZZZeeeTv^С^ϡ^ϡ]ϡ^ϡ̮xExEETrְmԫlԫkԪjөjө߼8kT~}~|||~~~OOOIIIpppSv_Т`У`У`УfҧL~xECxEUo֭n֬nլlիkԫp֭\s~~~|}}[[[EEEEEEBEEEPPP~~~Uwbѥbѥcѥcѥ|ܷRxE yFz}ħsװqׯq׮p׭n֭m߽֬~~~yyy~~~|||[[[EEEEEEXEEEZZZUveҦeӧeӦfӨs yFxxE0f޻tױrװrدqׯp֯sذ}}}}}}}~~~zzz}}}}}}[[[oFl[nhlllkkk`gӨgӨhԩzܶ)`xE{I˱wٳtرsرsرrׯqׯj{{{||||}|}}}zzz~~~}}}|||~~~[[[xEWtٲaaiԫiԫiԫm֭ƪ{IxE0fvٳuٱuٱtذrرfyyyzzz{{{|||zzz}}}}}}|||~~~[[[xEw:p߻k֬kլk׬l׬k׬k׬߻+axE zHy}ܸxٴvڳvٳuٲgwxwxxxyyyzzzzzz}}||||{{{}}}[[[xEs-coدn׮oخnخnخoׯuٳq yFxETz۵xڴwڴxڴivvvvvvwwwxxxzzz~~~|||{{{z{z}}}[[[xEv.erٰoخpدpذpذqدqٱPxExE]Iz{۵z۶z۵iuuuuuuuuvvvvyyy}}}zzzzzzyyy}}}[[[xE<80 ??(@  1"S0;a8Sj=sp@p@p@p@p@p@p@p@pApApApAqAqArBrBsBsBsBtCtCuCvDvDvDvDwDwDxExExExExEH L,Bf:up@N(`g;&`ΰaѣW˛W˛Y̝Z͞XVW\^ϡ_ϡ_Ρ_Ρ_Ρ^Π]Ο\͟[̞Y̜W˛UʚSʙQɘNȕKƓHőEÏA>:62/{+x)v&s$p!nkignת_xE $(,/12V2x {H_߻X̝MǕOɗQɘSʙU˚P~XXXooojjjSSSTZʝZ͞[͞Z͞Y̞X̝W˜U˛TʛSʚQʙOɗMȕJǓGƑDďA>;841~.{+x(u&r#p!mkhgnת_wD  &+/13d9$^ۿZ̞GŐGŒJƓLǕMȖNJ|gsssvvvHHHP|X̞X̝W̝W˝V˜U˛SʛQʙQʙOɗMɕJǔHƒDďBÍ?=96541}/z.x+v)t'q%o#muگawD  &+.3hACÏEđFggg|||{{{jjj5hQ%^%^%^%^$^%_$^XVVVVVVVVWVPPVWWWWWWWNrB  %m?]Jő468:;=?ŒOɗ^{TTT<+i8 T8 T8 T8 T|JH~tƦ~ΰxɩuȧuȧuȧtȧsȦsȦsȦrȦtʨMm?<#:?$7F(2L,.U1)^6%j="d: p@TD1}35789CÎk֫f{{{;;;2221 8}K9qԷ{ݶpخo׭n׬l֪k֩iԨoجRp@  qA@xBŠ-z/|1~246Kƒ2kg@XXX{{{sss}}}GGG.,,,+ 2U1gp@2kDŒ/|-z+x)w'u%s=>wqA sBd%_JĎ*w+x-z/|0}4Sʗb {Ha8n">>>{{{oopvvvGGG(%%$$##" _9u$dGNi]^mgGk\9`.o(u's%q$pE$^sBck> |J_ϡ)w)w*x+y,z1~Y͝AxqA=#+%%%1HHHvvuzzzFFF:::gJJJ|||\\\8uY*k$q"p$p\͜ |Ij=xEa/z&u'u*u6aBVMGVPOUSGJHGHHGGGHHHPPPZZZZZZUUUGGGFFFWWWJJJEEEDDDDDDDDDDDDNNNJJJ.b"o!n)t^xExEK(b<&s't'u5`VVVWWWFFFlllsssxxxMMM)f!n m7'bxEIxEյaС&s&s't'u7y\rrrpppoponnnnnnYYYppp}}}jjjFFFiiiKKKIIIFFFEEE}}|8lT!n m n^ΞӳxExEK4m0{%s%s&t'u<}`mmmklljjkiiijkjXXX```FFFdddCCC@@@===CCCxxxtts___(f m m,w2kxEIxEյ]Ξ%r%s&s&t(vQqqqqoooonnmnnnnnXXXaaaFFFgggFFFCCB???@@@zzzqqqhhh5uX!o!n!n[͜ԳxExE.(b3~&t&t&t&t8ztttsrrrrrpqqrrrXXXbbbFFFiiiIIIFFEBBB???OOO~~mmmdddyyy9kT"p"o!o0z'axE-xEgu۲(u'u(v(v)vm׬[uvvvuuuuuutsttttXXXbbbFFFkkkLKLHHHEEEBBBUUUccc~~~vvvggg8qW#q#p#p#ptڰdxExE |JGĎ(v(v)v)v85hRxxxwwwvvvvuvwwwYYYcccFFFnmnONNKKKHHHDDDbbbiii]]]>t\%r%r$r#qD‹ |IxExE9/i/}*x)x)x*waТӳ-YE،|||yyyxxxwwwyyyYYYdddFFFoooQQQNNNJJKGGGdddEEEEEEoooN{h&t&s%s%s,x.gxE7xEz\*x+y+y*y/|?w7QE}}}|||{{{yyyzzzYYYdddFFFqqqSSSPPPMMMIIIfffEEEEEECEEEEEEEEEEEEQQQfy*x't't't'uZxExxE zGն^Ϡ,z-z,z,zBPAHE^^^eeeFFFstsVVVSRSOPOLLLhhhEEEEEE"VVVk~;(v)v(v(v\ϞԵ yFxExEVEÎ.}4:@qիؼ yFEEEccc___FFFutuXXXUUURRROOOkkkEEEEEE"WWW]}p[Ξ*x*x*x*xC‹UxExE<2kFÍGŒKÏJÎHhxEzEEEyyyhhhkkkllllllllllllllljjjiiifffKKKFFFZZZono[[[XXXUUUQQQlllEEEEEE"WWWOrc}߷,z,z,z,z40ixE:xEZUQƓOŒKÐJÏJÏJxEPEEEbbbFFFkkk^^^[[[WWWTTToooEEEEEE"WWWCiY.|/|.|.|/}E}xEXxEtlPŔOœNœMĒNœ2jxE2EEEzzzhhhkkkkkkkkkjjjjjjjjjjjjjjjjjjLLLIIITTTstt_``]]]ZZZVVVppqEEEEEE"WWW;cR20~0~0~0~XxErxEväRǕRƕQƔPƔSǖ'`xE"EEEeeeeeefffFFFaaa]]]___\\\XXXsssEEEEEE"WWW7`N83322cxExExŦUȗUȗSǖQǕXʚYxEEEEeeennn]]]MMMTTTYXYtttEEEEEE"WWW5^L;4444ߺdxExExŦWəVəVɘTɗ[̝ ZxEEEEeeemmmUUUUUUxxxEEEEEE"WWW5^L=6666dxExEyĥZ˛YʛWɛWʙ[˜%_xE!EEEfffmmmuuuNNNEEEEEE@EEEEEE"WWW8`N<7887dxExEup\̝[̝[˜Zʜ[˜2ixE0EEEfffnnnjjjHHHEEE~EEE.EEE#XXX>eT=Š9::9ZxEtxE]__͠^͟^͞\̝[̜I~xEMEEEgggmmm^^^EEEPPPFk[Kƒ>Š;;M~mիiӨhҧgѦfҦպ.YEՐhhhkkkVVV\\\`v[Ο[Ο[Ο\ΟbУ8oxE<xE WܷlԪkөiөiөsذ7iS~~~tttccbVVVfffTn^С^ϡ^ϡ^ϡuٱ XxE zGϴnլmիkԫkԪkԫbx|||zzzEEEJJJrrrP~k`УaФaФaФ˯TxE6Hzwٲp֭n֬mլlիz۵nnnZZZ^^^^^^^^^^^^^^^^^^^^^^^^^^^]]]^^^^^^]]]WWW~~~|}|{{{EEEEEEEEEEEEESSS~~~QzjcҦdҦdҧm֭>s}L6~Nsװqׯp׮o֮o׮m~}~~~~iii~}}}}}|||EEEEEECGE\7RFZZZX|fӧfӧgӨ}LxEU[{۶tرsذrدrׯ_{|||}|}}}}~~~iii}}}|||{{{EEExEf]~X|gΧiԪiԪqׯRxESxENvٳuرtرsذ\zzzzz{z{{{|||iii~~~}}}|||z{{EEExECx}ݷjլkլlլk׬k֬}LxExEWM}޻wٳvڳuڳ]zxxxxxxyyyzzz}}}hhh}}}|||{{{zzzEEExEz4kn׮m׮m׮n׮n׮{ܶExxEU}Lи~ܸxڴwڴ_{wwwvvvwwwxxx{z{hhh|||{{zzzzzzzEEExE~4kqذpذpذpذqذuڳ̱ {IxE($[|۶z۵_|vuvuuuuuuvvuxyyhhhzzzzzzyyyxxxDFExEFztٲqٰrٱrٱsٲtڲXxE&xEmL}|ܷ`{jjj2UEkuڳsڲtڲtڳuڳuٳEwxEk yFqmuuu\\\{{{}w۴w۴v۴wڴwڴwڴ߼j yF|Kɯn]s\qYxlTc]R`[S`[Yd`{m}Kp`CdUN`WW\Z[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[MMMEEEBGE;ME3TEZ˚xE #'*,P.cn?7oѴvزdХ_΢_Ϣ`ϢaϢaϣaϣaϢ`ϡ_Ρ]͟[͞X˜UʚQɘNǕIőEÎ@;60},x(u$q!mj<xE  ',/1e:!\Ѵ~ݸ]ΠTʙVʛRKl_Jg[O~kW\͠\͟\͟Z͟Y̝X˜U˚SʙPɗMǔIƒDď@<82.{*w's$p mi<xE %+0:"Th368Gő~޹uuubbb)))a23 yFV\Pd9^  tCiž9.{1}5Nǔ{̭ YHHHtst;;;+*+3@f;Oa~Ko5p*x(u/ysٯ׶ {HX3"vDD|;*w,y1}UʙRrAW2O,,,CTTTuuu=== )Ìwܵ~ͯxET=DxgѦcУaϢgCdUGGGmmmuUʚW˛KǔXxEoxE$[s֯fѥdФ޹8hR噙pqqLLLpppe}X̜Y͝]Ϡ*cxE/xE|JjөhӨo֬GwbkkkkkkkkkkkkkkkjjjjjjjjjjjjYYYMMMWs\Π\Ϡrد}KxE xEdinլkԪjөt~~dddYYYRp`Ф`У̰xExE/e~ܷn֭mլxڴwwwzzzzzzzzzzzzzzzzzzyyyyyyyyytttWWWEEEjGGGaaaRpdҦkլBvxE: yFѸtٱqׯqׯw}}}~~~[[[EEEEEE).XEFFFoooppp_gӨ}KxExE-:n߻tٱtرj{{{|||}}}[[[xEWjakիrرRxEW yFж{ܵvڳixxxyyy|||[[[xEqһL} {IxE;xE) yF5iry?q{IxE;xExE`~M)`M~{ħS-c~MxEnxE)xE%[<2dw6h7i6h6g6g6g/b%[ExE88888 0 ?( @  L,9g;op@tCvDvDwDwDwDwDwDwDwDwDwDxExExExExExES"$Y3jpA#]QzŦٸxE#)-V2qp@Cx׽mmuѭsׯr֮p֭nԫjӨeѦ`ϡY͝RȗJőBŠ>8IÍxE #,2f:*dؽ|ܷTxkkkzzzLLLl sدqׯn֭n֭l֫iժdҦ_СY͝SɗLŐFWʘxE !5j=LuڳOȘPZZZHHHθۿ۾ڼٻzϮxEo@YSʙCÎcҦt,XDrB|JBypĢrŤlŸkŸiG~tCuCvDwDvDBtCKDŒ?}޸AipppIII,1~MHtk|jxgwذHtCwD[)cEÍFscvo_ieW][T]YLLL四IIIWWWXXXOPPYYYHHHBp(bwDZxE zGݿ^ϟ@nlllzzzgggKKKGGGIIIYəܽ zGxExEYAy0{VvsssyyyLLLGGGvvv4c?xxEWxE yFܾV˙1}~sssGGGLLLggfonn}}};v[Tʗۼ yFxExE*%_4W̚rtttGGGMMMkkjhhh{{{Lj0{$_xE)xEkR.|SmyyyGGGMMMoooQQQEEEFFFkkkcz*vQxEjxEy˪rذHŽAr\tttvvvtttrrrGGGLLLsss[[[EEEPnnnt4k֪tɨxExEƠpիaΠ7kSGGGIIIppp[[[EEEPooolDÍV̛xExEڰiҦlө9gR四~~~VVVxxxMMMdddYYYEEEPooog{RʘNȕxExE۱mӪqլ9gR四bbbuuuMMMEEEEEEOooog{T̛QʘxExEȨzڴnԪ7kS\\\```ppppR˙_ѣxExEҷhҧAr\}W˚xܶ{ˬxExEnhgӦXpFFFuuur[ΞYxEmxE.5ks֯{```OOOxxxazfҧ7lxE,xE zGuٱIII\\\WtPxExE]\yڴt[[[eE\*gKVVVeeegX zG]xE}JkP_X {H־k}LxExEa@uq@iWս{ܷ>sxE_xEoqqq޺lxExE yFƪqf|tguo|]rFr^:kT;gS;fS;jTHn][pyú޻~Ĩ zGxE yFpp {IxExExEExDwxExExE[}Ked}KxEZxExEZ {I=;9642}0{-{,x*v)s(s&r%p#o!m!m kihhfeEڹFtĻfSPּрܸhҨaΡ`͡`ΡaϢbϢbϢbУcУdТeѤeѣeѤeѤdФeХfѤfѥfХfФeФeХeФdϤdФdФcϣcϢaϢaϢ`Ϣ_΢^͡]͟\͟\̞[˝Y˜Y˛YʚVɚSșRȘPǖOǔMƔKŒIŐGďDĎCŒB@=;97530}.{,y+x*v(t's%r$p"n!m!mljigffFڹFt[~'`mӰۀݹeЧ[͟\͟]͟]͠^͠^͡_Ρ`΢`Ρ`ϡaϣaϢaУcУcУcϣcФcУcФbФbФcФbФbУbУbϣ`УaϢaϢaϢ_ϡ^Ρ^Π]Ο]͟\͞[˞Z˝Y˜X˛W˚UʙSəQǘQǗOǖMǔLŒJŐIŐGÏEŽCŒB@=;9752~/}.{,y*w*u)u&s%r#p"n!m kjjigfeEڹEsZ~*cvƦߘmժ\͝X˛Y̛Y˝Z̞[̞\̟]͟]͠^͠^͠_͠`͡`Ϣ`Ϣ`ϣ`ϢbϢbϣaϣaϢaϣaϣ`ϣ`ϣ`ϣ`Ϣ`Ϣ`ϡ`Ρ_Π_ϡ^Ρ]͟]͟\͟\͞\̞Z̜X˜X˛W˛V˚SʚRʘQɘPȗOȕMǔKǒIƑHŐGďDÎCŒB?=<99631~/|.z,y*w)v)u's%r$p#o!n lkjihgfEڹEsj%_uƥߌcѤSʙRʘTʙV˚W˚X˜X˜Y̞Z͞[͞[͞\͞\͟]͠^͡^Ρ^Ρ_Ϣ^Ϣ_ϡ_΢_Ρ`΢_Ρ`ϡ`Ρ_Ρ`Ρ_Ρ_Ρ_Ρ^Π^Π]͠]͟]͠\͞Z͝Z˝X˝W˛V˛V˛U˚TʚRʙPɘOȖNǕMǔKƒIŒGƑFŐDĎCA?>;:87520}.{,y*w*w)v(t&r$q$p"o!n mkjhhgfEڹEs}Qbۍ_ϢPȗOǕPɗQɘRʘSʙTʚV˚W˛W˜X̝Y̝Z̞Z͝\͞\͟\͞\͟]Π^Π^Ϡ^ϡ^ϡ^ϡ^ϡ^Ϡ^Ϡ^Ϡ^Ϡ^Ϡ^Ϡ^Ϡ]Π]Ο\͞\̞\̞[˞Y˝Y̜X˜W˛V˛UʚTʚRʙRɘQɘOȗNǖMǔKƔIƒGőFőDďCÎB?=<;97431~/|-z,x*w)v(u&s%r%q#o!n mljihhfeE‰ڹEsUzBxɜbУMȔLƔLǕNǕNȖOɖQɗRʘRʘTʙU˚V˛V˛W˜W˝X˝YɛWVWZĘ\̞\̞\͟\͠\͠\͠\͟\Ο[͞[͟[Ο[͟Z͟Y͟Y͞X̝X̝X˝W˜U˜U˛V˛T˚S˚RʙRʘPɘOɗNȖNȕMǔJǓIƒHőGĐEĐCÎA@>=;:86420~.{.z-y+w)v(t&s%r$q"p!n mkjigffeEڹEsvVvǧkիLǔGĐHőIƓKƓKƔLȕMȖNɗOɗPʗQʘRʘS˙T˚U˚TPHHHZZZbbb\\\NNNPxTXǚZ̞Y̞Y̞Y̞Y̞Z̞Y̞X̞X̝X˝X˝X˝W˜V˜U˛T˛T˚T˛RʚQʙQɚPʙOɘOɗMɖLȕKȔJƓIƒGƑEŐCďBÎ@?=<<:87431~/}.{-y-x*w)u(t&s%r$q#p!n mlkjhggfEڹEs½\>uΊQȗDDÎEďGŐHőHŒJƓKƔLǕMȖMȖOɗQɘPɘQʘQȗLsOOOqqqgggJJJOvTV̜V̜V˜V˜V˜V̜U˛U˛U˛V˜UʚT˚T˚S˚SʙRʚQʙPʙOɘOɗNɖMȕLǔLǓIƒHƑGŐFŐDĎBÍ@Œ?><;:87431~0~/}.{,y*w)v(u's%s$r#p"n!m mkjihgffEڹEs {IcdӦDÎ?AŒBDÎEÏFđGĒIœJƓKƔLǕMȕMȖNȖOɗMHHH}}}RRRLsSʚT˛T˛T˛T˛S˛S˛S˚S˚RʚRʚQʚQʙQʙOʘOɘMɗMɗLɕKȔJȔJǓIǓHƒFőDŐDĎBÍ@?>=<;975422~1}/|,z+x*w)v'u%r%q$q"p!n nmkjihgfeEڹEswXշOɖ<<>@‹ABÍBÎDďEĐEđGŒHƓIƔJǕJȕKȕKKKK{{{vuuzyy~~~FFFNR˚S˚RʚRʚRʚQʙQʙPʙPʙOʘNɘNɗMɗLɖJȕJȕIǔIȓGǓGƒFƑEƑDĐAď@Î@?>=<;:865432~0|/|1}3}1|.z-x,w+v*v(t's'r&q$o$o#m#n"l"k kJÍۻBqg/h{ݷCŽ9:;=>?Œ@ŒAÎCĎDďEĐFőGŒGƒHƓIǕJȕH~hrsrqqqvvv|||SSS߳߳߳߳߳߳޳޳޲޲޲޲ݱݰݰݰݯݯݮݮܮܬ۬۬۫ګڪڪڪةباااצץ֥׬۲߰ް߰ްޯޯޯޮݮݮݭݭݭܭܬܬܬܬܮރ׶Kw`AxfҦ<678:;<=>‹?ŒAÍBÎCďDĐEđGŒFŒGœGeeevvvpppssswww}}}WWW=x^7o7o7o7o7o7o7o7o7o7o7o7n7n7n7n7n6n6n6n6n6n6n6n6n6n6n5n5n5n5n5n5n5n5m5m5m5n2k%_$_%_%_%_%_%_$_$_$_$_$_$_$_$_$_$_$_$_%`Y_OV̚766789:;=>?@‹@ŒBÍCÏCĐDĐEĐELLLsrrtttvvvyyz}}~SSSúżƽǾúĽǿ\YLƓ43456778:;<==?‹@ŒAÌBÎCÏCďD{nnn}}}}}~}}}}}}qqq(bJKDzAxAx@x@x@w@w@w@w@w@w?w?w?w?w?w?w?w?w?w?w?w>wAy5n_bZGÍ1|1}33557779:::;=>>?Œ@DĐPz~~~}}}wwwVKҵբԡӡӡӠӟџџўўНМϜϛϛΛΚ͙͚͘εVbdND/{0|1}2~33467799::;;<>BT˚²pppzzzvvuKKK̸þEo,eoâ܂Nȗ<88764321~0}/{.{-z,x+x*w(v(u'u?KepE|GÎ/z.{/|1}2~2~3456678899:;Iƒzܷm'^OOOzzzvuurrrppokkkϨ^%_m vڳFÍ654331~0}/|.{-z,y+y*w)v(u&t&s&rAAyr3lKŐ,y,y-{-{.|/|0}1~3~34567778>_ѣ~ί*dcŽ{{{~~}{{{wwwrrrnnnkkjҲļb+d~ί[Ο821~0}0}/|.{-{-z+x*x)v(u't't%s%q&rGË0jƴZW˚-y*w+x,y-z.|/{0}1~2~2345556FÎ὞ByOwPPP{{{wwwtsspppllkhhg~~~uuuOwCz̀ߺ@0}0}/}.{-z,z+y*x)v(v't't%s%s$q#p&qSɖYǶ~Lܽiէ-y)v*w+x+x+y-z.z0|0}1~1~22359SɗuȧT|}|vwvrrrnnnkkkhhg{{{sssUvɨLƒ1}.z-z,y,y*x*w)v(u't&s%r%q$p#p"o'tgӥڻ~Lljž1|(u(v)w)x+x+y,y-z-{.{/|/}0~1~1~8cѤM]GGGwvwqpqmnnjkkhhh~xxxSkJxeqO|i<b5f1n,v*w)u(u't's&r%r$p$p#p"n"n+vgmC{9&u(u)v)w*w*w+x+x,y-z.z/{/|0}0~;rد1jsTTTvuummmjjjgggzzzVVVtutyyy```HHH6_+p(t's'r%r%q$q$p#o"n!n!n5}AyYJŐ&t&u'u(v(v(w)w*x*x+y+y-z-{.{/|;ߺܿYYYYwwwqqqppp{{{YYYSSS5~]'q%r$q#p#p"p"o!n!m!n mG‹X yF~ұmת+w&t&t&u'u(u(v)w*x)x*x+x,y-z-{9⽃ԵPƴQQQ~}}}{{{zzz}}}iiisssooottsyyy|||~JJJ/b$q#q#p"p"o"n m n m%pkըzϮZI2}%s&s&t&t'u'u'u)v)w*u@kQnaQnaQoaSpcdxpaniV]Z^__bbbbbbbbbbbbbbbbbbooo{{{{{{{{{{{{{{{zzzzzzzzzppp[[[uuu~~~WWWzzzzzzssstttxxxzzzzzzzzzzzzzzzzzzzzz{{{{{{hhhcccwwwjkjmnmsrrwww||{~~ZZZ4|[#p#p"o"o"n!n!n m l.xF~VHč%r%r%s&s't'u't(u(v(u?jppp̙JJJxxxsssʵtttIII}}}iiikkkooputtzyz}~~ggg3z["o"o!n!m n mmllFUplġxܳ)u%r%r%s&s&t't't'u(t'uEgwww混|||TTTsssvvvXXX~~~꾾zzz|~}|||{{{zzzzyzxxxxwxwvwvvvhhhiiinmnkkkoonssrvvv{zz}}}ccc1^!p!o!n!nmlll#pw۲ižs.g9$r%s&r&s's's't't(u(u(uDgnonnmmmmmllllllklkkkklkkkkkjjjjjjvvvnnnyyyzzzKKJJJJHHHFFFEEECCDBBA@@@???CBByxxwwwvvvwwwyyy|||~{{{wwwSSS(g!o!n!n!mm mll4~,f yFӲcѣ&s$q%s&s%s&s's't'u(u(u(uDgjjjiiiiiihhhhhhhhhgggfffggffefddevvvnnnyyyyyyEEECCCABB@@@>>>===<<<:9:988BAB}}}}}}zzzuuurrr7oU!n!n m m m m ml!mbѡ|а yF4m3}$r%r$s%r%r&s&t&t'u&u(u(uDglllkkjkkkkkkjjjjjjiiihhhghggghhhhwwwoooyyyzzzFFFDDDCCCBBB??@=>====<;;998@@@~~{{{wvwrrrmmlnno___(f!o n m m mmll/z1k yFӲ`Т%s$s%s%s%s%s%s%s&t&t'u'u'uGjonnnmmmmmlmmlmmlllkkkkkkjkjijiiiiwwwÁppoyyyzzzHHHGGFDDDCCCAAA???>?>==<;;;===|||xxxttsoonhhheeeGGG"n!n n n m m m l n^ϟ|Ѱ yF3l4~%r$r%s%s%s&t&t&t't&u'u(v)wZxpppoooooooooooonmnmmmlmmllllllkkkwwwłpppyyy|||JIJIIIFGGDDDCCCBBA@@??>>===<<<^^^{{{xxxuvuqrqllkgggbbblmmgfg*d!o!o!n!n!n!n!n m0y1j`w̫eӥ&t%s$r%s%s%s&s&s&t&t't'u'u;rrrrqqqppppppppooooooooomnnmmmllmwwwǃpppyyy~}}KKKIIHHHGFFFEDDCCC@@@???>?>===CCD~}~tttqrqmnmiiieeea`abaa3yZ!o!o!n!o!o!o!o n!ofӥtʨd$_7%t%s&t%s&s&t%t&s'u&t&t't+wtڰe|stsrsrrrrrqrqqqqqqqqqppppppooonnnwwwɄqqqyyy~~~LLMJJJIIIGGHEFEDDDBBC@@@??>>>>AAAgggxxxooojkjfgfccc```]]]6rV"o"o"o!n!o!n!n n!n5"]a}߷(v%t&t'u&t'u'u'u'u't't&t&uD‹@p[sttsttttttsssssrssrrrqrqqqqqqqpopwww˅rrryyyMNNLLLKKKIIIGGGEEEEEDBBB@@@?>>A@AXXX~}}ssshhhdeeabb^^_^^_5xY#p#p#p"o"o"o!o!o!o$q}߶]NIŐ'u'u'u'u'u'u'u(v'v(u(u'v,y\m{uvvttutttuuuuuuuuututssssssrrsqqrwww̆ssszzzNOONNMLLLKKJIIHGFFFFEDDCBBB@@ABCBlllGGG|||zzzpooedea``^^^fef3~\#q#p#p#q#p#p"p#p"p!pGÌ~L9r.{'u'u'u(u(v'v(v(v(v(u(v(vHĎSwwxvvvuuuuuuvvvvvvuuuuuttttsssrrrwww̆ssszzzOPPONNMMMKKKJJIHHGFFFDDECCCCCCEEDopoLLL}}}{|{zzywvwooogffdddnnn3}\$q$q#q"q"p#p#q#p"o"o+v5oirȦk֪(v(v(v(v'v(v(v(v)v(v(v(v,z_wwwvwwwwwwvvvvvvvvvvuuuuuttttttssxxxЇsttzzzQQRPPPOOOMMMLKKJJIHGHFFFDDDCCCFFEqqqeeeIII~~||}zzzvvvuuurrrooossr4}\$r%q%r#q$q$r$q#q#p#p#pjըnƣmPC‹)v)w(v)v)v(v)w)v)v)v)w(wBXyyyxxxxxxxxxwwwwwwvvwvvvvvvvvvuuuxxx҉tttzzzSRSQQRPQPOOOMMMLLLJJJHHHFFFCCCFEFqqqlllhhh|}}zzz{{zzzzono4}]&s%s%r%r%s%r$q$r$r$q$qBO8q/|)w)w)v*w)w)w)w)w*w*w*v+xqخnŢo|||z{zyyzxxxxxxxxxxwwvvvwwwwwwvwvxxxԉtttzzzTSTRRRQQQPPPNMMLLLKKKIIIHHHEEEGGGrrrlllJJJvvvhhh5~]&t&s%s&s&s%r%r%r%r%s%r,w6owhv۲*x)x)y*y*y*x*x*x*x*x*x*x71j||}|||{||{{{zzyyyyyxyxxxwwxwwwwwwxxx֊uuuzzzUUUSSSRRRRRQOOOMMMLLLJJJIHHGGGIIIssslllGGGZZZxxxpppKKK^^^hhh;b'u&t&u&t%s%t%t&t't&s&s&sv۱ez |IPʖ*y*y*x*y*y*y*y*z*y*y*z*yUܾ̚}}}|{||||||}|||{zzyyyyyyyyyxxxwwwxxx֊vvvzzzWWWUUUSSRRRRPPPNNNMMMLKKJIJGHHJJJuutlllãaaajjjKn'u(u'u't't&u&t't'u&t&t&tPȔܾ zG#]9+y+x+x+y+y+y+y+y+y+z+z.{Uì~~~}}}|}||||||||||{{{zzzzyzyyyyyxxxx׋vvw{{zWWWWWVUUURRRQQQOOONNNMMLKKKIIIKKLuuulllaaakkke*v(t(t(t(t(u(t't'u'u't'u5![ѿD{.{,y,y,y-z-z-z,y,z-y-z,y9(b~~~~~~~~}}}|||}|}}|}|||{{{zzzyyyxxx،www{{{WXXWXWWWVUUTSSSQQROOPOONLLLJJJLLLuuulllaaakkk|4(u(v(v(v)v)u(u(v(u(u(u*wAxxhxܴ-{-{-{-{,{-{-{-z-{-z/}4]Ο~L~~~ًwww{{{ZZZXYXWXWVVUTTUSSSPPPOPOMMNLKLNNMwvwlllaaallllOȔ)w)w)x)w)w)w(w)w)w(w(v(vwܳd} yFշ]Ϡ-|-|-|-|-|-|.|28=BEsĤ}сڌxxx{{{\\\ZZ[XXYWWXVVVTUUSRRPPPOOONNMPPPxxwlllaaammmXssڰ*x*x*x)x)x)x)x*w*w*x*x)x\ϟӳ yFNGŐ.}.}-|0}5=BGFGEHMҀݍxxx{{{]]]\\\ZZZXXXWVVUUUTTURRROOONNNPPPyyylllaaannnCu_-{+y+x+y+x+x+x*x+x+x+x+xEÍ~M%`916>FŒJKJŽHF‹GŒGQǔ,dрxxxjjjzzz^^^\]\[[ZZZZYXXVVVUUUSTTQRROOOQQRzzzlllbabopp3jQ8,z,z,z,z,z,y,z,z+y,y,x5#]:r?HLĐNđKĐJÏKÎIÎHHÍHÍHbϢOҜdddZZZ}}}^^_^^^\]\[[[ZZZXXXVWVUUTSSSQQQSSS{{{lllbbbppp(aGJƐ-z,{-z,z-z,z-{-z-z,{,z.{7p̸\PœPŒNđLđLđLĐKĐKÏIÏJÏJÏIÎwذչ]~~~mmmnmm`_`__`^^^]\\[[[YYYWWWVVUTTSRRRTTT{{{lllbbbqppMucҳ`Т.|.{.{.{.{-{-{-{.{.|.|.{J̹}ƨOĒNđNĒNŒMőMŒKÑLÐKÐJÐJÏJĐuĤzuuueeehhhaaa``````^]^\\\ZZZYXXXWWUUUSSSUUV}}}lllbbbqqq]}okŸu۲/~/}/}/}/}/}/}/}/}/|/|.|_{д߻PœOŒOŒOĒOĒNŒMđLÑLÑMđLĐKĐ^DzdddYYY~~~~~zzzzyybcbaaa```]]_]]^]]\[ZZXYYWWWUUUWVW~~~lllbbbsssn|S/~0~/~0~0~/~0~0~0~/~/~0~sٰoŢokؾ~۵QƔQƕQƕPŔPƓPƓOœNƒMŒMÒMĒMőNҁ}}}mmmzzzdddbbbaaa```^^_]]]\[\YYZWWWVUVXXX~~~lllbbbuuu{Cz1~1~1~0~0~10~0~0~0~10fԧ}ϯ[^wٰRǕSǕQǕQƕQƔQƔQƔPƔOƔMŒNœOƓ=sӂ摑tttMMMzzzfffdddbbbaaa___]]]\\\ZZZYXYWWWYYZlllbbbvvv4l422222221211_Р׹MyXs׮SȖSȕSǕRƕRǕRƕQƔQǔPǔPǓNƓRȖ8nӂ摑iiiIIIiij`a`ffeccdbbc```^_^]]][[[[[ZXYXZ[Zlllbbbwww/i733343433333\Ο۾EsYu֯UȗUȗTȗTȖTȖRǕQǕPǔQǔQǔQǔVʙ+bӂ摑___FFFWWW_`_bbba``^__]]][[[YYY\[\lllbbbwww#]:44444444444[ϟھFtZvװWșVȘVȗUȗUȘTȗSȖRǖRǖRǖRǕYʛ*bԃ瑑XXXOOOXXX^^^^^^\\\[Z[\\\lllbbbwwx"]<54444544444[ϟھFtZwذWəWəVəVəVșUȘUɘTȗSȖSǖSǖZ˜*bӃ瑑vvvQQQPPPWWW[[[]\\lllbbbxxx#]>66666566666\ϠھFtZxرXʚYʚWʚWʚVəVəVɘVɘSɗSȖSȖZ̛*bՄ瑑lllMMMQQQuuulllbbbxxy"]>76777777777]ТھFtYyٲZ˜Z˛XʛXʛX˛VɚVəWəVʙUʙUəXʜ7nՄ葑fffHHHZZZccczzz0i;77777778778^ѢۿEs^~ڴ[˛[˛Z˜ZʜZ˛YʛXɛXɛWɚWʚWɚXʚ;qՄ钒]]]FFFcccyyz;r978887888888cӦؼJwm„޻\˝\˝[˝[˜Z˜Z˜ZʜYʛXʚYʛXʚYʚKՃ钒}}}UUUcccyzz|K>Š99999999999k֬вZyԺ]̟\̞\̝\̞[̝[̝Z˝Z˜Y˛Y˜X˜X˛\ɵՃ鑑rrrLLLccczzzq~[LƓAŒ::::::::::wܴuȧiɭ^͞^͞]͞]͞]͞\͞\͞[̝[̝Z̜Z̜Y̜t£Մ鐐dddHHHccc{z{arsäMǔMǔCÎ;::;;:::;cʷq_͠^Ο_͟_͟_Ο_Ο_͟]͞\̝\̝[͝[̜༌ҷ_Մ鐑[[[FFFccc{|{QxfӸ{۶NǕNǕNǕDÏ=<<Š<<;‰;‹=‹=‹=Š=‹=?‹Ì>Ì>Ë>Ë>ÌEƐ(b/dt֮dУcϢcϢbϡaϢaϡ`Ρ`Ρ`ϡ_͠_͠aϢG{Մ```ĵ}~~~}}}||GwbTʙRʘRɗRəSʙSʚQɘBď>Í>Ì>Ì>ÌS̛OV˅޻fФeФdУcϣbТbТbУaϡaϡ`Ϣ`ϡ`ϡrՅҕQQQuuuǿ~~}|||||{{{{}}}\vSʙSʙSəSʙTəSʙVʚPȗAč?č@Í?Íi֫׻ yFxϵfѦfѥfѥeѥdФcФcФcУcϣaϣbϣ`ϡݹ {IՅ߼WWWƼ~~~}}|}rwٳTʚTʚTʚUʛUʚUʚVʚW˜NɖAĎAĎAĎn uͺohѦfѥfѥfѦeЦeФcУcУcФbУbУbϣnի+cՄڰGGG\\\ĹaФƯU˛U˛W˛V˛V˛W˛W̜Y̝IǓAďCƐJͻK{oիhҧgѦgѦgѥeѤeѥdФcФdФcФcФdѥ_ɴՅˀ|||HHHddd³wY͝W̜W̜X̜X̜W̜X̝X͝X͝Z͞V̜EǑLɗ(a*`ՀܸhѧhѧhѦhҦgҦgѦfѦeХeХdѤdХdФྙ {HՅΉvvvabaKKKqqqþcY̞Y̝Y̝Y̞Y̞ZΞZ͝Z͞[͞[͞]ΟQʘbԦ}KtӹjӨiӨiӨhӨiӨiӨgҧfѦfѦfѦeѦeѦq֮3jԅΉ}}}ooo[[[QQQĺVxZ͟Z͟[Ξ[͟ZΟ[ΟZΟ[Ξ[͟\͠[Π\ΠsŤpgnիjөjөiӨiөiӨhӧhҧfҦfҧgҧfҧfӧwĥ}ԄΉ}~}|}}xxxhhhVVVZZZķRu[Ο[Π\Π\Ο[Ο[Π[Ο\Ο\Π\Ρ\ΡbФCzotݢДǏĎÌÍËˋŒÌÌˋ‹Š‹ŠŠ‹Š‰Š‰’Ɵβm:lqBrsݧԛ˓ƎčÍÍÍÌÌÌÍÌˋ‹‹‹‹‹ÐŘ˥ҳךӽm>op|/dU|Ծݫ֥ҠϞ͞Ξ͝͝Ν͟ΤҫֵКҼwQ+`|оe=nUméҼ̷ԽݿݿܿݽڶԫʘѻiQ;mcп΢̹rdZVWWWWVZdr̹qwinff-master/src/icons/audio_volume.png000066400000000000000000000013121347323557400207530ustar00rootroot00000000000000PNG  IHDR(-SsBITO pHYs B(xtEXtSoftwarewww.inkscape.org<tEXtTitleOptical Drive>g /PLTETTT@`+@c&M.]@JJuujLO{"M!J<<DAtxmi49:vzpuyn6<=qukrtp.358==;??AFDKPLTYUUYS^b[hlblnimqjpti{}z{u|w}l@tRNS ""#$..79;;@MNTmstz{|IDAT"3BdU6e&!%C #Kp>e:#͓;` h=1; k">g,VZpKߊWi)?k7f&a%wx|[0 tm^kvi_0 OKIENDB`qwinff-master/src/icons/banner.png000066400000000000000000001127511347323557400175420ustar00rootroot00000000000000PNG  IHDR? m pHYsod OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3-gAMA|Q cHRMz%u0`:o_FIDATxw`.TK-Yn0n`PL !mBvSn ٛ]6Klvn ɦ-8!@ L5clllYrQ4j3}|ofFͲ;4>ys0‹t{>nxw=``@ `k "Wa#!0`yl G|( b^JX|U%4 /}?|u5+pK ۃÈ{3RDD_[N}Vu(/~|үx;-Ώt>6PfH~J1oB8P(ϫo=(F>΁~#8p|;7aqR\tXjtlCq ?hוH&ԿY~TEطW^]\z@ 'S<>|qd`r@GMZcq ?2^=Ge#}a*啗ޝcC4P"76U?sf`ǫ%:@m[Vj^t83"LVpaJ!~ˏ%{Wg- ^x???>m Zc`3ItHVv <Y -$`Ga8 Bh61k,9reith8y臯G8ֻAPNJ`uzPPZ"/WcԄ}a,\^| Tͪ /XP.|O5‘vF$"I砸mɂtAɝTx/R `ǎ?S&4E},[ UUUHR! 9Tgޛp8x<'wupanFe(0' ++̞z_]c x`}x;D{Լa|pGҲ|t`?b ԄxOk?4'.޽HUT)/2@a? :qDw<(x`㚋>gǐ`rS{S]#xSĥ掣xz/ώZ?9/Soõހ!>3FlE Q˴OԌ HX6,~Y. >ՐϨ^xCXJd[XxL7g2* ݹ,4KaZj(~_w+[#,r5\0uW,_ cΏOLY x[>r'~cy nxD,.Ae0&H0 ᔔeX˲ND|E@Xv! =ʤ'0mC$itc_#_!K7 1=*ߣ\q x-GbAZaYفfUarh+*kKi-6N 5 qӇ?!@aڈO^~Hx'`3\*82mÌjC43* Bꁏ^8 &qC.K32CUUڍt^Y*&7@N< QӁRn~(?۸pMχ!,}`X1ꄬJdax?"tobŒl5xx W]KHNq¦zXPDz$J4aKfQ99Q;БGEU0541gAmɋi-ɋI gUxKOKOȞSyW5GT~מw;>{wGMM8D{P)(<Po_I?gT Axơ<‹*uuOp݇nā1 -9 '_Bxr%Z9*8eS5M%h[2Nh216f\ S$4Q9J^fL|eXe):ԟY ?Q.ZQ|_ގAAyDYQEAT쓈Wi蕉j3PBoGG >CCl/ RWW_p=h+GZ4zJPteKduX 8dAcK  hϨT}|9K,1OsַћX !eL羵 $r^t /ϑL+y!{jIl`J]pMl81p=Ԟ.  tU]K܎*T%)b@,8pPUuHZ`XVk\W<^cWf9.< ~ 6M+qԨqc K$w|PK4ؙ~ZW|s7h}Fsu=!w -{1nce9]_㍷_NJ#/OTlqmTNDPSUtA"5/b/ot /ޏOo =;04ڧD6Dd9i\fFsղQejiY  @ThS$8Ո=(_QSiJxFPZi{"s_|<8r8j+CЗ*P>kOJ.Z]-nBC?] /oۿ9.ę-vsٌkRL޹u̴lr涂T- 9}{ z:\&tkSL ©lO( @,fD[t:ϯ8wCx`$FQS~5 ̴C,;Dv⿄!e'Q߱W g/Ƒ<‹S %bɿ5~ZC"5.Z+!B+ׯh[D$L)ALBeqZdUӘfw.pWORzOLN+V.w^=eY(d+8xq;g X ѐw(tSԶ- , //10ҋ>m\Zwtzv|$d,㩓h,}֟,\9NEJJ);DQ ;R 0E_0Ehi`*DL */x磤ة>vҏJiB,t-/N|G( TYN)[-Ns /7c A9ZU1=`|\@RQ}s@db)'- Wxa 4ï_'Q]]kb…nF錟KdQWFS~ /fz$S#GwqwFfTLQJJPErhq"A cٜZ׳(Y`1 Zq@2nyL3E2tDClɛn;iH;Mm a -{銛7t+Di}z~R1< vR/aȥ;82PXBtO{iÉ>@bǮaeZ̟/.ym? PD)n(Q*)OV-@_m-XVN(Bɴ2&gq?n ]b9˞߫}Q1?$N J 0, e9Lw288Ǐc޽o~uD%t<$I @s9;90 V/E9@iQb{3=^;Yv!B2=%aeg mq`qNBrJhcy"d8]P BNM+،|vʆFYTL՘w etwttx_sAmm- mcp V$IeOztVgz a ^x1@8ڵ WoKz iİo 8d$!QS;y +?Ƌ# BHɴ## SKwDAm['" xSj)1# Ii*Boo/>  bŊ@ 8qxԦRebYZ*o~Q{x ^ū1Jb9Ht2(ID"eį|K6XN_"JFo[PJߏ|eljϸ*$ &˲044)*R~p/'i*B4ViѣwH$;g}6 1###Hӆ2:aji!LodY{I>1A ^x1c }L4^R Y;=-kǢYk?FUKx˜2̹y| (0^3@FL2!^0sø%t(Ut5TȈ5&; y[E'r7Wtwww}7"pWt}h:k[}kŘYiG#!Y~C ^x1CuUaZz -Au )" 5Ec@ ɢI BU7W #O+nW;r^\Q ;'c#a,$zRBDu Yt%nQfbHw(H]{Jҳ]?SD{DLХڙ{b}KqG<GSS݋zظq#jkk Ck[װU QLU:}%Ѩc+i.2) ^x1R+?Hl\~?4A9ۇyeWل[ lk[i&nT*p)dY>%%܆"SڎΤ}Ğe6mk-Yl.( ;ArLIԱ&D\4ٳgz+ FpsZSw@_SS̖?@b;W PZĠ ^x1+ւh9\ 'bo#MmYq!B ' 2 (* 𫃿?F! Qn*-MLsAMYz;s`:th@&ӼHyy9beDy•4;Ц|H,u$exGM7݄bR)bđN sxH*BhFL{[II 1Es /f`8S^\ }0!<88%>BPU|v*֣zmg+ .gea`FYP;һ~p8 袋n*LPtC,'UebIH|c4FG~b޼yQUUv$lq2u)MGF4de_<7Gy2N! +Ko@bc?ÈG sEK㿫g r@ _!˒,mP,CpUW]@ $:lu N@aQ\pücn*!H`hhxG]]/^Jсd6u@ 2WWSPb:BW4v&m(3&0z3,:-,3;l0Fek'dE5hl9C/x|] &cEIt㪚meY9-]֚ҭI}#Ϣ +Θ43,BH&144aD"_K8Md]H&H%?$0Q.Q/̢hq*ʴF gr`:ey3,zQY6f/W>Qm'yiEd}!Ts=^q 11i%Gt%9qˋdV\=IՊlKL?f mchhCCCXt),YH$HbRTAi} |1fM%H,Sɩb^8Mmb̆&T=Eg y32Oً0DbtH%-"wjڄѩ+lIka,Ʒuw $nK1'ӡeV#ēK "Un^%d8bR/^/sh2a"J9 8)lO1mX|˲3Fd^zs8fQ:T)s ԠH{XRx ~۸;9xXD3,,bavt!GK1,\>6Xa dB`IjײO`\ml"-Qhr 6(Guu5>aѢEHRB[[$TE$ wwDOXD eL5굉/j+ZMIܨAJ/Hl2 R!w/A10ҋYcC ,Օ$!/S]ҫ.cQ=/s|S?K"i#erqP0:=4sb+& Xr_T :ߏ2\~eXuYlj6$FGl[t_~bramh QFQMPEIL]ZJ&0atF?S!x3(J.'mZT BBCs~"ҍVPl$X0Ȯy{Gx#.ĤJk~qqT*۶q ٳ⋰h"TVV`dd]]]HHXHeD SCn|"%TR 6ly"9:}b]Ni#]/!7a\~5Ju!1:F'BCCHKU$ FZp9-;Ɋ!> 9V=4/'^}QzOfCS0[bV#;{/JKK144믿kbphǛ15袬fU—^\c(F)t9D@Lǝ-EO qtu"7 # ?].iwu-@bDN `ά*t)qʈdr3ӭЌoPYvoWOc7dm }Lꗁd\GURVLU3e455xgPUUM6aqb2bhiiAj4Qc'Co]P+QzT6UI_1/bܖڪϨiSXԍQ)/ÑzTVG1`wU M ^x1s"F8Fy ۔v|zH--@cp>}w&E ,-]न(Q Np]Jd,$Xm8|0?7Bݒ:z-((( Na45xpjęSRS]QN< !.W9$r* [T!4%)Ө418tބwӉ c)e#3&(/*\?jH5%GBE3*Cw_{P5vJYu(*IgXrm`mfN@:e$g{SzzzЀ… Q]][nHT E*%o%]V# #+!xi\Fx#t(6\2@wwx^}?8,Dl !r^x1socx $if#ݝLQ>ìj46¦@0vtq&lJg\p DVD^dj%1|EII .\?gP^6 61486g_ R0hg0ƃu0,(O| ZR%i" `V}Ѯñмb8oV"WXSY0b\T{{^̈`g] %ʫ v iJ.ݲ|(/nˆD444$4{!r;z#HaL w //7x#0<<H@)8 K̥OEt>ёV"zE` QD:@P5qdavC+!}Ѳ,A°,a$ CJ ^Yw|4;k K*_߲^xއMӰ,fU!6ҡ5@ jFydNM4Qs BG1򠙌 RmWD<bTS?NOR֩y#CvM())AWg'zzH$`)g%<]nĨ t`$[40RbΎ"eizW7ƄcY>D"?KR)e h<ҼٰOKzm3\˫@bh:?YLirJ92- '?cQ,(Bl=](7sѩ+KP(ډ\:jKipUn ,WTZDODt9NgHBF„&}[[ijZD9^ Xl!~`H, ׇ|lڴ @FU7J od!>3G@bDb4` FA#2?S$LaU.Cg ē(G&|!׮M^4l{;$–h {VYPQvAq0MV,:C.ZI]in[P&℘$Y|D[u.70-.F8ѣG /D o} c&uݔGB<$R"jUy^x1b(އBWD|9 HbbK.kQmt!M @Ax9#Hv Rp/nmxi1R`f{ض Mhͣ޷+#)(1{"h,ƴ|+j",~ÈD"7D}}=FFFOOXx1 aY?.H;B\ "rH{8r/10҃(02:dyyD]'A'-b(\F-Z3KDW 6Tg01b;cȩekTUɡ\2O*^?t!Ē!2= h*JW\ (,,DaQo>B,A ??ݻ@WW+_ '𶘃nݲ]%tavU1oSbk/wJ*1GNء||ow%7Q,AlŅQޤz!+ ܣ $N~\޸`3,ΙKQA4 )ʤ>Kmދ(3@`,B!#/?1;v GA}}=>[nAuuVN071(,()D^, I0B\Lx^̌HBHiy] E}0Y+/8ɑ 7Ѝ*Db9FB80h2QXўا'df4|M"VY&L"}>~?QXX={Ѐ 7x#>lB~F h쎡0TTDQ? /f @8DjdRtOy%L`P'a(>&n^ ЅUR~q)R`SqL+xTUvZ|$%vc0erWPrtԥ%0p(H$χ!8|0?|lܸ7QVV6-m4Boy,N# S S@bD`fW N253SEKn On񴰼b|O0Ǜc]05n10ԏI,*0`9BLo51=EԘ0e!S19*6 +W!H)b QZ\hnnƎ_GSSPZV5k`ٲeسgϩcn%E !oA~A>Ѩ\'P_`0p8@j#<ܔ*0dɅ=‹T{@[F%I>$,fNTD1u5mgyR'P6+*n<h'As?ԺX|4d36 |>0 PRVF<6BEEJ3h@ %N K]c<̪X) /fPCK"~fR4͘l*ԩURY63 8[+ۼ\.0Nc ԄSL],ɯeYh4|'ǑP8r$ vp&84R0 v[G +]QX^x1jVkʖft90M2[wOr9OʘR Jn(]Y`LѸ# =P.&-˂w4X,]vw߅C~~*++:x!({/~` ޖP3zexŌC3|,@fʷ.AQ;p!B0 M. `BLTJv}Y-ꄘZ&ȱ|3\ l|QXTc "C%q:tMMMH&, %eH!MjsR4JOꤹ}`!iJk;=]66ѽb67hsq\t^m6ZJ IT|R"ބg0jEYN*(͑WQR$35Z$+IPb9ǎQPPիWRV |l6qQ %#tJA=ggK(ͩ| PW fl``)Onc;8T)q(Mǫ@bDYd.:BURaADj )^] #?C~O.$KMm,!(JRXB\(Xk`F҆B(5 :@`>(n69goS-TN-7m zaboт$H3 !E#+>F=‹~_i;@:,OBJ@WcP;%?se*4(󦰼bFDilmE~  `0(%$+);J c$10C3j+$ZeDjH$F?rZ%fUJ-'|Rz4ŋ1225;Rrƀͽ1|^Jc` %sVJRKMdy3 10Ca~_):'`uQHD hܼ{ix7ʢ5O*3e4HDz;TT:Foo(=\r;- zi#!5L&q1mrZɹQPP=WJm?oJGPSynh˜ )v=dW ͟D/(`~di#x3 c$1?A4 "+aJ"c6圙Sz_O04xBLԞ:SvgW$il8ϭ wq'PfԟűyƢ=)/!Q^@8l7gLJokis;e'caU-~@q;Z+E0tzBI^\E΢\1AElfgJJW0stԑ+1=@ѯG]&MDoBS跑,2ŝ]f`v.ij4jFfa !j{^̐(G0Ago;J*+59MŸNe=J6 sq8"Hu\E5 .1/.pZب.JH9\YB;~Dzpoܛ͘;]1| ڻ[aCQ$ 8DUZs#BiQ7ghy1oi*9nKX*5F*6I[qDW[P_D6&`NEm1Y׫z8\fS ÛDn&yH$ܤ!c,U7N4HN).<ԕmuL9/s*Tԡ);tƺ~&O8'[QV4CJP_DPJT4Nnz~(ُD;jk0{p%owk]eO63͎XNs'\pswy m`@$Usˤ߈.δY:u:#G'=M%"= ՟88rZwTպ'Dpqٺ{;G,цmx`IWVnζ_) M8r/BiB,цhx=|)tEQ^1FC8ڀ磡m.geMmZʦVEApk/-Z=xg/0j+s<Y5m22~SC(_`3fZrI̘O,c&Tk Dګ c:tdRt:T*X,~P\\,}MhkEZlpaKj +MWSH{$xDں{~]XWu3^n;[7c/w”V_ZlþǦ|z]ŁcSƋmj' Kλ;h*.ҚV'dEDS.A0tĎc݂z 5sPPJDA\LsgBORy΁SR)Fxngl'pYm6"!j*,^.tādxx---W ˲QPPBZ#0lƷm̛7xز,ncʲ:Q X5R;nT#"#TyU&lC}϶z>ueu3u;B QLzmPmEe(Ռt?uj1,rQ'TcY TKFA@lM`ÿׯGee%f͚4S)ҎMzIIfkfT`j3&$}bNb3=7`;.(!ڦ61FA} Qܯ#W_/~ ,Z'Dߏ>|DQiX>PXz5V^ǏڪRv>)fm>vJ {I+A=MwTFzp==r)(N Mf,HbIϘW}QF^_{?v*VgW45!@ώ=C'@I=?‚Cw) Z/F=\.]cgnKّ!.wok.J233TOcժUwAcc#ߏd" ;)ljNHMx7Q__T$hDcSX }OBbL@ĴUMt)ocVVnB_$S ŴtDSlg2 x/~@bUhn?)D$̕a-,h3.G'BE;(Ud*_ºy?gD)|O2IJ.r:1 [&k弗qY0}\$1JǤ2% 㠔e5ga\S{6Y@(0QvCCC_=-[GСCF20hIQnՂm-U\FTj41؆@dgfmu5Sm]Ͳ-}'R=ԕm8&ur2l:BTEil\r-fz~Ԣ ZQU"RѠuS+b;dIin?YeeX^{v7rOe|d񶟦HHtNwǝhXE|x*S]bt(/7'lONjrp_]XVu.?}(m=AδŠ݉^l0fKltۤ9f{.YMJl,A] yٟ \W5+wy#ڄߓL,sk]/.._Ǐ#H䮔g0XO!ςs>e"*8 Md*t-~/No=ڞ;WYP rq2 \oz>RBx^L}|,),ι VzsW߀ei;U'[=K^4'Npb"=܅g+AO(qzC̋uCpfչ[k\ `R0?qAC5]yzizU5i[qRm$LIJ:Dw45$5> Y>\>㵶P^bר}9ghU2Mzu++PWWfM3hT QEg9#"Y?b#L"IC~P+!* 0aĩ^C@"Ej3d͗dIu Sٺ=3z]ǪMYxmxȽN~~*.=F|K zڹ`,B9/QPXb 4Dn ŴF}n}HEdhf_ V]KIynbUMHt4]sYjLL0(oxV%5>:b1 iW5^8+?qY!~ˇ\(P>P. T*K}]Upz+zSI?*D\Ov~T#"<[V݇+ݕ5 WJ4|2^|UF߃s)A5(j| DC ';B"rTUO4 іX.ЀB)^T;mm*Rh0$46.%b (qZ}<ԠX̔#nC-h[ĂqW|!,WQQQ&Mj{aJ<}To@_qzD4>>b6ESⴅ>V}϶q(}M;MfK܏Ü*y{;õu^DJ:+VAض,s> f) }S5 1EZL!lMmfh;[̦r#;<5oKɏ M^ )jٔwi&?3n`{!* \ PRRa%n=?&Cًӻ%?~h+y.}(BvyFbJc0yIO/牦sr"bb Tzv&^U2M,K*ۇWX>o!w@%b)s0˙Α" qK۶.*Q2d+O$]b$L8ŤM66)h#s WuDA3D yP.b|ضd27h~I K$ ϒ &?`BP__sRL6Χ !ί xfzD$AU4y矄Dq.&/:%rRv޾2=2p0~aA9fo}Aډrv%"~i,(|D-+ n_qdR\߼P_rj6ѯ\tw'v7<ܛm`Uŵx>x |U&B; m8e'WX<"|T-FC>>9&L+ Mt9RBiVWW\ə۫FO aa;D65 )2⢚;{-+tJpndzVt:gv>.D+/y튿Wg>t ``O&nҧ4I~$jD($jkkNxh2|>N8:::4ZZZgƵ^y!Na06:;;JJdUPXTK.mc޽vө3"T VrrɰhX|``O=/_69"&@0~2r6(y;š9mŸi˜^~9%t%~|Q>U"g,y;[7wں{y]hB]نi]V=5+E%&6Lɲ /% }ؽ,^! e)h!F>!s͂3V#Vg…E,"1<F_jJ{ttFuu5n (--EWO7H$N ^bT?tww50iwFf޼y g1~6(,,Į]PWWwyxP Cџ6+ꠔ%BUWy~_CGPhX52R%(,I"p'Ž~ +W*EbٺW,OݱDGV ٪N++7Ƚ* 'FA8ܓGnŗo֣v*V*DD󓈞ՊmAd%CA~(CO~O͏gTky)gcl޼W\qֆwd2iXB2@1qjic _fq +;H&tY> t8tDB!!HJҝn {BKPYY~۷oǢ4%iۡV[vl%|Pq/W, 3e \[w)z%䔗,Es_*Aɋ< Q}]e] ߠo:?_>EɿDl.\qVd_qyaƍhiiF__2a$~.]=Joqq\2>rU""gftww LMӫm.KB|CG$E~^K/oCaL<ʱwr-Eqي+[~ XS{Y?]{#O.ÎC9%'"4;FksFwn` nwWnWրwaC1u3αQX sݝxCPOD5'rȗF2CRXeL㭣P7g kx0Z>|mE V\$ GCf'ͫt/duTT hLLܯǒ%Ko>Eyy9f͚"a9<22.===([ׁ8cUŨJr9j$w%-[G࡟~%pXD xUmGXHﭛ2wUTƁ'Y2cİsY p9{v~v=5 ̀ Lb#t'O}/}8&ub&ݏx{xydzݏ3`q/_ d≄Q-B7-_X#,8n:lFA_h=lG6L&^z%lذbFOـDe_+ qk %\3۟\?w_>DWv⋟ GH~XE,L[ե94qLCX /EƐl9Mt/bmd]qfhnC[~'>pL*V"2P!fk9>Lڤ2bG1aQ]Wv??w;.?vxPV|wFqagDdSeeH(ib%5DcX,hWbITFFꡇnBEew3ڐS\9q{&{^eQ^a.HaN %ˇ1 ᫛ì*BWxL<&NYƒPWTrrpv<:K!Ti[[Ȇ6b 4wē~ ܃k6 $SScZ rjbZHjDrs] $!l1VēCxȓG/ڍ|7n<lΖe)8'.wڕV8YRqOf=[/yvWq˲s% /'37Ng~?pۿע$R+V|O> HHD';U%NPmp8fG3kϼOmw_⧨,҂UsQ\\ %,@|>IA JMwՊ|/)!,KWpX ###F2 dz}ӗUK- Ax@85Fs,8ClZW1 ʋs},06, {y~ǪU۶DNOw `֭83ƽ^cc#gD5k<g^vcppmۆE,Pjθϲw^ p^uCX7 h9Q&6yab׮]8s&%-^65GkAocQ5wb͙`v~`89[i Gϐ;Đ8RI~س,)(ǵ?mo<_ =瀜 0ܕȴȖ-[P[[na&8A{1micL 1+;~ }K8gu9$R#^-$U%$C5HmN n9tltͣ[Q?+g]}gF#Aa1uu%z0,  󣢼hooٳ18(nCS;xXX^s]q1=3 {`v rD2XJn] 3(8fe[xR%"՗9FKqխxo7?0 D@oߎ`:;;D(D4Wmc/_nT93V%\]]m_A$W|yǿۯV\}ͯ!J8 FO߰%lՕJ?0]Egi|='@@Y #-xHH' Te< f[Eee>(Zf۶eY+Cuu5{9~oE=z#(/e⧾{ &`h,?iEf>U}g@AI[k3qvQP0 wՇxtprDO&hii뽣 P(D"qR׿3&BƪFΜ{!] c?>eަWHˤ%zkH[Q#*˜P{w&n. 9[E eL+ ڋ*E@*wTQ;->Q5YT ~>$FLÉhnnFuuuNXe>3(r9]K3PU>`=nDsrM2yz\v}߲-͸P?[R^.+ @&|miiACCB8---|ry{eˌdu3S9ɏw߫Wƞ={@޿P[[k,Oݻ=ӫS15Q*R_t?y-܎uěGE"5BZDa+ NbP=K20 }B3!ere,UQ dg(f͚'x7rJw-M "1G*5ڧfRg'Z+~{]Մ)u9ca 7܀P(.|Ŷm۰qFD"B!8p@&b1 [n_ec``k֬AKK L&ՕEݰaAl۶ ]wn X~=oߎ[bƍ6l eݻwC,Ö-[ 0o<477c۶mٳaB!466bݒnھ}|d2fo.d2O Y;c亽0weaÆ?ضm[T7x.!_~g3_{5h܊xjhe"̨FT1]b .XBbGA*@[[ +j;t,PB-r5iyjKԵWPP UW]h4[4i Vy[ yi3cB`B טشHyy9o>. "޽[&jumm-ZZZl2,[ [n"v-۱f;3ǁd/&,//G,CmmmIj޽[>H|BL7nĶm؈ŋOq1+5p뭷" aٲeزe Q>Xoߎ 6FˏH,|AY {1S˔bD[`4δH(Byy4-N"hX|9vލ ̛7OWcc#$D2ILKKL0"F'D"|lJss3$z!$I,^Xd24|܌5kd|'c}k֬C=ڜT\wuue00v@ضm|"***4HH7k?.\ŭȪwDpWj5bi'o§ՙ,%-N⬅ۿ=u֡8ZNgffRpyc1i`6}9>(2|>E1r6y߆zov~Ib2N(7sŴRXׯǖ-[L&NbE"I<WWq{ 7L 'Q}˷nj$Y e8NUDQ444dݯYxZqGEEZZZ$h )|BT{쑽>HQLA[/ 8񦇲|U?m,{q%cۡ_lz0 u*q^_@`ͧlر\p0<20' iTӴ QRb;Mz>D|0@II JJJc0~ȷ0|m}7~Kٮ0.l3>MMR9Uq!jZ$ n={Ce]$O$͛7k֬8_۶m} XO&֬Ym۶!  Fxׯn޼yضm/_dl2444```dRR?9nݺY+W}P(ddC[r}sb9 n qFlݺU:E}@ЩSA577<|PcVa \X7>ugQG:bN:1gW/Wi) EcU.!o;#Gf'|0 Z0 >_V= !B^~Ս_Xpa7~ ;{dW R7 >J˩B kYrs\Z 8*e6'X,JgTm%)y/c`>8R"$4Y=ЄzbX~i}}bm~]]]ؿ?***<4L峜}TYss1,1znK|,YlËJ1r I0s e!|WĂu*gWӣ (.R̝;G`hpW">~@>>9]^~Ca  _[o,%>VdL09FzD%m&*'R.rj%N`LBie``8]" iDşS9~#r_[rIp sfJbzC>fʘD$HW\ o5=>yş`G= R8X 4phr ^f!\'94lO!ܿ {.͗ )|~?">| QTTχ{bΝX4L">Qɨ5{&jSNz/J1t6vʼnr!2 ((#`I1ܦ{jJXc8p:0j Ĵ  sw8L}4wzK_;è,nZ;7a8ҵF~e_TrCwbbE+>7⬳ҥKL&H$L&NAA0/G^8p(@0@ ر^FpW8| .{ː Е@|:yoC&5350CRbgĒ=!f%85(!cΙ8Qh: QLʧh#JЦ_^vAD]Z%8#{ D)R .4fb≎?Eֲ+"-O:ITC<мƱW={6P>Ee/mYݍntuufPuf 2b$))\ oIdQa"F&;"{ oC DޛPTUbl#)(ʸeVQPc: e "3o Y/NQ4׿m;kd" Hh{qpٺQ:@25"OȰ+Kl[joS8^;0$u PT%%%(--E0D*B*L&A)ŧKHM^vZ0(W% OSP!f2&}l7סu5(SYBJܧPN9($LRd(l8@0:{u /g#h,8TH^$ɶ]>DdDv4'qcΜx w2S* >z#|TqD.,ȢX("%S #1  E,E}9" 8 ݖvD$ZӜSlNU3}fI?}0Cu >a _.ݔW&*GPUr5^RQ&:#NE”ٔ8sbT_ҩx'qOgT&SW( 80_GX =}ʹ="+ ׸ ^x1sdUD\:X5(W`Zky]"@OH@"KN"T.'l%lSf.q'mMub3^T:M_1{^F;zCj׳%=?á\ρ2[(K6׬F\˅^3@&$=eI$#8|b'|Uw..[w V5ԂT:5w/@FVڈQ]@"k+]b9JuIZU*hQi0uP,m\(R&UCvT0sK߄*/ <%\DH1x$]p!֞s *Pt5c4, ADҦu}v jSh"øelSF1?/u*w-DU2Z@t%o ~s* -ַ训A1*)-ѐ!/}iU ^x1@d cx2a`b_6%~W ELu|{)L[>D(1:ܮ|fQ#LHȶ޹F;mv4 RʖxC^();4 Рr^ޢ<=x3 5ru\=0i~ʷzz\r,P'w!MgBE6 ]EdDƶ"Ae昮NˏzO(.uگȇaH q]UbAOZQMi_4 h_vBl2(L|&eN @}"cU"+@}=v_ěG@,ՄK/s05،d?lNwKHr#jWIq[ rq0@oKC>fT71"dIA}e|nЫ }EӜ?>8lg2NEȭCcB{#3?t`aZ%:@AgM"DAcyڇǷaǑGp悳pVݹX8h5gHӤT \>Է 'xzQOȯ)͉kU9 ػufJ 4*6JTRbKT6A;̦@=%@Nh=z ^xADƪNV@ƪB_tpN gf%̩E4Z&F:1G25miJқ]û, YBNi.E{ D ZzBH~[hkI(Bw5Z*mmLSu*NUL&pV]URmWnL[(FwMԛ‹ xy< =GP&T¹K ̟]ޑv Ļ1<ڏxr6Kk= P(I1^bһRE]5dwƃ_L$2{rOģ:SjPz+jqOoS2'JCS m._V.QEE &o{$TM[Ƹɾ3FT?՚𴰼KgM:'d=6N5x셿Bqa)ʢ*W˪PTA^ >:dzl 0=QMh,ӼK8(W A/ 0J]*\9%*fs'X(N7 xʤ/ QWbR˖cS1C£lͥ/xY9OZ &[uLzv .Do~ EeJTǜy(/Yŕ!xj0ÈH #h:T-!QSXF5{Cj*ҡHT*YrW=t>5z!TNdAe0dT-5:t_j820TwʢTN v@} "AJ1xd>m0@'p7yB(/Fa~e BUsT ˈw٠²e~},n,&*ܷхsaex Ḩ(E)T!0$q 0GP;10҃q 0A@s/#&T+D_T3nrxgY슮5xם'~ ^x^L),- // /< // /< / @ / / @ / / @ // /N>qj'N`3IENDB`qwinff-master/src/icons/check_update.png000066400000000000000000000013601347323557400207050ustar00rootroot00000000000000PNG  IHDR(-SsBITO pHYs B(xtEXtSoftwarewww.inkscape.org<bPLTEKSZNP[MSS^PQRaPaNX]^aMYZ_]`WYche no{(ރ.߆47܀.݁.VX\alstt Vjx$߆4׌KאP}ߊ}' {3Dzz2Gy9%/~ 0bhj| V| Dl\.aӫSŁƅ7V{vɁϑГ=]fɀ[Erq6tRNS"""\\\xxxxtK@IDATc`)d(f* skir B Ղ!)٪I EQz sXDU"#KsBݔEvIzYK000 +9ZYY( 3u)qtႸM?@ b-S/D@C.LG!#!F131tiIENDB`qwinff-master/src/icons/clear.png000066400000000000000000000076121347323557400173620ustar00rootroot00000000000000PNG  IHDRĴl; pHYs B(x OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3-gAMA|Q cHRMz%u0`:o_FIDATxڤYlTuƿrN;RSMX)b K  bbSFZJ.@ZmCXmQ%8tڡ3;s0-}/'_9DJ} Z\ aRJ7ޙx릡(;aRϭ\J)izUYhAvL7MX]:#땄CRܭ= ʍ1e%>[nfӿ{b"K5R'L ټfvf s W-5(ʌ'^m۠zUD$7H+}Lfx fQZ)0AZdGtۆUC6+meZU@Ej27D)bgy>dJ"O@>wr[|+'2TUGcqEՁ4VQRd,Ĝ>9$JL]}Vt0_9aB` P!KKld+v=477-VJe)WolK@)Iù<_. Z_ed1F(o= st2j@^l&h $D9T9535؅@;˃X^"s!:,Z 9QXL DH2ųxI~r ɦAB!$SIڳ RJTUU݌u]QBd ]ժ*O:9ہk,EEad >6:ٳȵ9A8}4~}U#G-4}N:qVRX2[wt4kVH;:; xH)Ao1=6x[#5B5,x!oݯY R8|t QNA$1M@tQ_3^7xrBb/ׁs,O~?`(bc Hqyr1)JN\j %pk2==ӥX {%ϾIENDB`qwinff-master/src/icons/configure.png000066400000000000000000000012241347323557400202460ustar00rootroot00000000000000PNG  IHDR(-SsBITO pHYs B(xtEXtSoftwarewww.inkscape.org<)PLTE"L!L"M$NK KĎ J4e5e5f6g7g7h8h8i8i9i;k$TͤMEr\VGW!j:{qMKzu;uP Wyf5AN.A\ZeY!M?dʠz{8 R{UQxR~cvr=&%&p:hNIENDB`qwinff-master/src/icons/cut.png000066400000000000000000000016771347323557400170740ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<H)*&{++T3oH ; wݟ=s0oޤ vk̈́4}q݇gyAJr9\vmuX<)ʷG,LNV~\Q@0X5qBYvQ>;M B4ySWOr!e+\2,|ƴ,4MH!KDi R@HɅ]BH lhhohj*/dR|lQ c\ZM^oJ.?hy(2m!%f_yLԯӕjj\^w&=Hl][ 4dEʡAkbH)[XgybD&IENDB`qwinff-master/src/icons/dialog_cancel.png000066400000000000000000000013121347323557400210270ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<GIDAT8SAO@}SLG/k[qbϽmĐO@X"X,/~|{3sϔ:%f3iډy~N]sahHSGV[r"өZpNQ[Hqdb+Y;>@9ײXz)s :3 rl@ Cpn}e @8p FQ+lJYA4{3 EE,c]䜒U .!bR;jb8:9U0\\x9]o6q뎶zxB1ѥ4/oĸ*F)r XYLS$=G.% r:B>u?>zd)%D|v-̗K|77sz{8~z򶂠mrNJ%;_,FCNg30J1v_|rƌRar!E#(14EmE^ 9z=cO#KS/޷$Y0qPamT]KIENDB`qwinff-master/src/icons/edit_preset.png000066400000000000000000000071241347323557400206010ustar00rootroot00000000000000PNG  IHDRw= pHYs oy OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3-gAMA|Q cHRMz%u0`:o_FoIDATxOHcWw^ %B+ ]TRE RD7j\ Rp3\NT3㋞nLH4]}w|W)we҃R("wO >Εi x:W~(K"|("H$"iiDJ"#"bDd8N?t:hoozx^8;;#HGHg%,UR MOR)\.LÁa6‹R˥w*h4z?xPJa&N00 Ӊi(xi322R\\\``zzz訶hx˲M5 `0x,`hw8XE<dW*胦`0 \.b;A,pa˫{|>r||1LfB3cffM6j%z~x<266@cccqGn7GGG h?_Ύ'{?1f.ooƦD䏡C]mnnf[m-555R)~?J))\tE#eMmllֆfb$IP(*[]]קRs"*t]QMĴiگvA N'J\=('"oȺOy&"ED;(IENDB`qwinff-master/src/icons/exit.png000066400000000000000000000020741347323557400172420ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDAT8kU?ޙ;~yM>BcL!U h "-j1Xt7!BqS]\%JhZ\4R^_&{ z03{Z @N `[=%cJ)4=0 q]}syk@}/0\ *ZZ1c RJr#l k|ןKi)x֚0 8I5CCC(PJNgH}S>Zk("Iڹ7yL!$B4 Z{=`5@H)Zrm~`8>y^ǵֈ!}{!nU,R q c"<=}#Gcw&399imIs[kWzJH*USPI^BS0t <Ì=RoYX{{Ug2fff{.Ǐ)ss0<: XP $ "db!D'NٳgJ%R^}UlT*$ 2"u$> ֢Z˃948 rK$&m8R,o=G*ns؇a4[?Nī",Fi40R=G,bw牃fdWYImzIIENDB`qwinff-master/src/icons/ffmpeg.png000066400000000000000000000072171347323557400175410ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs~1IDAThyՕ?UdE=34LMrqkƌ38IbFGbܗLQ%̑d"MZ(#{H{wݠT׫-}7ip偕=Żϊ} ހҒRv] *SP_P-{&(~W~CwWZîǯln_F mN]$TwE pSJ?8WV}_m'i; IUHjtXPJAe9m+ ξ(`Jov3DX4P|Ch} 녱desҝ$aFAaz J8c ޳gJj\Bl2v."(BQEƋ+>tYpTqօQDqd46I V`N@dR@$}X/DYQf*B@3 T5ؒ7]Ts'oFxBWp'Gd]A^E Tl|JqؖA.p"V0Մ%];7=uM?A0"3fG`rrn:utx)&RY_0j(ƃ<y{&[;BAZ+0kF$;p se'1zB54welYrڽ̩"!^U.bL3yn Rv{v&7!O 5@'*5Qgc*Q2MOOcq^XuU653ngalX`GOqEL“S >1X2v Āb"&xIb lr7JJJK@%z)@=YIm1̔R1/F9,\: 掘E-19-AT 36ϙ q@R.^a$ALe<5[1v"+&?ӗ,аf 0bl1*-Ib% @X'zuഘg7Ab%9Z䉏aqL?ǿAxxCQ~>[q;?r*&IuPIR @}JMlQ=S빖.6`i"NmRIz+1 ڹ߻ahXG,41f}3wBkmWwBSw@z@9k?.#dw=>elx,“h[ua l<;''INT-v<t`b3Btr MJMQX &G˹~,=)V%NOU{Ol66dM:L+V7\sX.8, 6 vӜ܆H/Kq*[ѱH-z^m\̙}?{Aڃ6򦍦#,\mi/ʥ'_D,1*˸r"#?8j=X6FM< O;8׋Ӊcr+^g.{ {aΥ9, {iRQ>]y:h{ۧ/"O^ W>-7)Ʊ `%6wr͋W.&P9c'"9p:$I&onVkAp$n׾ß;G~7NNqxWkoa|Xrm s<Ƶ/]6c"/`Q,щ4@Q"0n6A żwl;~OptuA/~ 1CFsRmX*ha+װ}=7KRxCD$(UDή|  wc.aQ7Kk:/7yO nC*{vtd/?b.h<ϟZ-| 3"1ywh&a1@ӛ~UAډFV7z>F W$dݶUܲ&*G_!P'$a>٧Lb |9V' :`q%JrjrXLMNVSi5_k~Fa jsPQl*b1<5jJVA Yr {Rܽ-)DV;o'2伡X[_ oۡZR+tjNK&=21굿P H$1ߍBIRsy^}'+|*+!]R $Cĉ$mqߪx sF|+T\:v8%(H}fi$$M D&'w(=xSqKm&ijKľr 5i)Bb}4MT)LO@Q^a6YX9ϾT)]ӵy_Xs)3@ZP*%J%DS)PJu.u|e, @waF~X Eb)P;\zZRh˓ͼjᣎfOxψFD@K+˔jX}O7qqA$=vs'], Alb &+YkLz 3O`y/|kԨQKi&=wNɻ鳻y'uxMUˤSEVzsRGBbKGD pHYs   IDATxwgU9/VPErdIlc# &t3^ & #l034 bIn۰ +rPrhۊ/_0K/W*UISWK{{-sl5ܐ[S5Ɩn%[ckl-![cK[B5Ɩn5pkl-![ckl [B5­5pkl%[ckl [cK­5ƖnuV;qcb@b;A'35MlRk>~Ivy묑%-+!:ŽLȁ83Q(SbH0Π cwc֜$ǵ;hE@f!& nOf!p qmb'#1Žg\qM w]Zx良n km]!<|5FaEn=篵ޔnF H: -vz]Tܘ`rl3&Ϙ&|{ߜ&ߙ.;25dv'OMrͼ_[A)!lsBw{RmbmWҋk\D0`ĹY/ݓpr?W>CGprh# &4lJ BR'ֹl=ni>O7|^0_*LIE*;ɕ;+\X88GM M U޳M h:YFR\1~//>%wpimu!>{3|q)a)DOJGx>!4*q뙋toWlR֛):@ 8bR5/s)i|>9P" gUNL[e,9*wpaM?fm5i;R՚z>a׏[3'B. PV9x{t>ŠDtNP3bǎt6+>leC 郠8ۼ m֚}:[!98(N& uңX}^{/D@HŎ#ߤhc;V<5c9QЩGHF5k@1,׆Xf&46imd4~gλWKIncW¬[p_7x߻qkV; 6́iK#mȀr`ߑƘv۪Y+ bǛOp89NKѹ ac>yAFN Ev翙wVXǡ[N>5HdaU3g,ұIi{+|jq^{/>c|o;<8dioPX:μVƇ6EG;nD۬wrɜzuk _XU5!֮iy~bp+ nIhi"!p$m hXI>mF'8N]0ںÂYp0Ga%GAB!|Z7*<!ĺd7rʞLKubw'-gPN*M'*6ơIuF>Y.<ۖ0QLvU;ii+;w՞wb=['cemm4]?Ϳk\7bB8sօ׺M@8*z ]xb #eA,N̻gStȪ8{0 NI0 \8w6W{qS^bwZ~XwzKրW}1"g-yX;c`7ҟU;t.tM" ƥRwv StHk-Bq 8B0: s4֑ڔNC%;:vgfYF$$IBe=/Dn>"p"߁nmjMKsItυMN5AW]iYbwƄCedY+Gz&4 ߢM|J[y]srȉծ:whhEkMep!t =]LAlb<9lwĒyųA;2ܲ Y ݀96G&,_v= ΛCG&M^6 9<י5fɓs%VV|ijDK!RΜSrdqN3]/EJ| _Ҵ zl%Pf7g&iGl&"$+.\H&.+2&ge57%[9 C9N3l?$| 宮y w27dlr,r~ll}a<}x&\b/2G耗~3nfl&D@Z_O 'Ә& ,d0BۂSXKa+֔q@kwmv9q,µ-OMAV>= Z̢!c{ D6$i&B '"aMMt5I Ziꦁ(@adm3UTTogaُ嚥ᑳ=H35 m )e¨@k+:::a ϯŗ&e󡑘FDajIьOX4`,YPJ2v"N|:W]cѓ([3=.1m0Pbt*3OM3LP5 $P()b:&N>ȌئQ_"+WmP do76Ng"LN18 h:#A2eʼn{\[11G9D WB, []q )9FZvhkH&R06V)n/b#M50s©|v3b !ivd4N::\5^;.L r~$E꼙k{4Q&qˡ<<=JRP%x¡ 1J 5?@2صƱEGZ3s$_2ym~S>*5gB:O w 6mi?ǝ_ JP;JE~W~ B2%7bHum8QcnAQ ʌh /2-O>$ N"X6 PYHXE{_/_ZjJR!CL["YˣKα9kD_^^h2Zd2>O?,vȚZq<5bH ĭ\r3y?06bܔQ:9p4kcY.4# :ZO|݈ɥ5ŒLrn⸌e\mI%dJu K1)yA=տpˏ+`Ób>Kr{4'y"F* s%nwaA'QٰHjlpBX.7 I0R)gnhTtN0Ix粍 /|N[(2z䃥'5R($*ϿWO"AWyIq+톅oƝ=dR+AxǒIuaEa? r߽Nm&$B2Yt- I! 2tDSE??<!2k 2PaᄃO(s!IK!#I@!dWՇ(V1 V~w-D[KB\.MQV6 %ѡ{,LH(LqAs.ASR+6xg3i,Krse3Cz^c^#R;{fOք2OUj ; ;ھ $\Z.D%,Eh&!CG$؀ńyX wxt9,&axHa `(Ȁ(}9Tha~zN !JbRZ(puJwpx{ԡ(faM]n=pxi (ںC1$QBE/2g籅H'zHVYaݲOq BHQjAH2"y۸K)RW'曳a@D(i-Rj_zؓ7::v,̷|s40Xar۹ oP@2`9Z*(a!$JP͘[!&T] @RFy*D0ҢQW3&.߆aE8JY8lyɮ_\IQlGF39Z堄AOq˯Qf 8Ȑ ^[,YX9Q  _zIZ0O~9Ce25V Yxir*Y\(Eˁ=| ~ gT ZBJg,\ɗ20B0CB yQӡCC!eD"%Wv׶@խPT=ȤG9˦B|_tFh괘b/O+JLwbg5.7`jqD.pqp)7rQhd%7D  M0`CL0GFxc^;?&\Pc/oKAya(pDŘyՏ2vc402rpY*,gxP"]^Pa箦lmkS<?yIFF&$$ hbh.d(H I DD` VZ37hƻ4@a>.gr BBKѡi/sGIRD1 qM!+pAt!6v(8(\X9T%"Y $Mɷy~8w\u1TwP%DD78qA&"BY%[| T$DhLn~)QB:3g>#45e k"EְLqjT24XP IOyep\IIJ@%"rK{y [n^R"E4udwfܢQ턉sh68ۆKn0>Ք]UZkЄ`^ZI L FƔ%i)֓|D`3Cy &quL!BKB@9+.QڋKJ#Z0s)[ĆP'|tE\.L:)f~p)@Б)ш qOvbRC9*7A B>\4§A*`y=ʃo﨑v* 2[&K^ޗ勇VKJX&頓hlb`|?Mq\OQV`ҌsǙ62RM):l.5is[ R eH3D16#8"NhD")TTTXRrliJH%(!JQ^t憟ct"Q*8lʾ\*" d魅& Sb>w.3JvP@0G^/08kXʕg . zf Bc2@ zA,3w4 ()dU f g./z/X.nFxwRN`hP ;{ _2%cGKvǿcHW~jUdeFcmk7;_턠%J14VE9Ȧ3V@\in ij1I+NDe(\Z^wïP@1Q sDb<{^"VT$ths߽&lc*W ",*ps/{/7P@~;l_3V2+4,cŻ) IDATWpdAHMOxt̺ YZJ[enAz-:h^>~|A<Ei;N(Q<}?_kb%(<@SO*Ђ.ԹD6𨪖6m9OcH6b0-׍op+q9Ujbn ' T%  ߔl,LyWok7JC(c)9yK_uZ@',\Z2WA,w!NU#& ~,H|upưkK1v]mM>"K`FZ,YB)u>JU>kyMM^g-/ AyE}2aŅqVj1x `~;\a/^6r{Gx $Gi%G4pӾk\CY]Ck7A^Ȥ.w(Va#<$r1vԃ("pv㐅xەM5ԨK xVq9 1=%ɣD!MYoۙwdU|5S*6BC]}/:*T( R*! *" 4AϽa鈈W3m (˾PYdO&L?i, +e6iC^08Z@hўo1&kܼż_btb'8KcjĸiCJ&ߙ5a!wi~”)cЉ?7+-eo.7=CXI~&(%Bbé>f0%Y̋żhpWy.] " Ҍ&xQ]d;%",V2M$H< zQfR"bY+e,]l|jB+Jɲ&P@Fc@R @*5GLLӪa<ń P. Iq/|}f#ȦAE/K5[m W/KQD%0XÈMq;\"%nfqn"N]_ u+{v5:vKz~Y(NXo6t}yjBCJ& }9  V' XMP5Içf cgJܼxr1XZ|(Bv_0r>R O2Zq| -2_^ N*%CԔ㥵/}sE>.M.(!JG:6bh 3v!wO&mm8jdPTʗWky>#m <mBcM?#| ] hYM4_<1ƮՔd lS-@#W&!A+mLt0ʬ&6t4ӰnmOsÂ΂O!psJ }z0(Y떍J>ld ! "(*kBiKx[;(K$$=o5̚\%D8_š Z<ܹ9>?n'4&:9n_tA;s7\eT[G@ %,ej$"m@I7_97ngFMy2S\z +>8P7\EP&'w;> e"\Ǡx'f(y'xu+vT1" ͜0e De U[trieˁcyM<;poϼ%-ׄkj Bb4<.! m-HeM~_)adA@ fww'3R`5i~n} 9ck-6/ˡoA) Qyu'#TsbtXuո@cՊL/01:HLAs̝SK"_Wܳ%Xv~:ѫx."'K3A~R8dcD.q ;F*8.xG[̉y@zKi'x;qWg@S͵;ҤWP0VO6_!U;->0i^ث:Y*izvzv1N@v'cPŒ9J!80XpmRir1y6Qj.NQ&N*eB[_FÀ(\(i wOq#-LnՑZjGv0u\OHHʞ 7=C0ZK6-ӆ,!Y7O8[p-7/p]LB&8x4Xc .p9C=!WxBNA= hƐJ^+zg@KM2p!n73rUd> rye/Z!{,(5I#zDd@e4 w}L]m,BJdC萏9L0luClP$R 9rhd&A)EX ]SwwOq0n-R;"% ?ީ?͗q:6ZuI\/isЊ451aP_G8ݳwOy t zFc2G)qD򒱛x˸ŸK!ۚ P[Td1=KP`曨ʈ'U0 \`{ _i5Q|Ü"D!//mZȧ?ON*wUM+V8O;ƣZ9B2R/m3?C*dvЙsI#n{~qO>['u4`Zn?}矐Ŕ @I޺C\Z.§@"\y1! MS_c@x,A.Н+$yEJlՆP!m1 ng(x$,3!^g= q{; l#dC~`yorFd>]a7@rՑaHqzUd6AS̛>&v߸iYCǗ_.@HԂbǭ/-deW(Yׄ7mݣp`s0h4 1/Wx vܰN}Ɓ)"OK{0WqeƉ!b*UP2"WA6}T(K?p+%zAXP,VYGX-{NuBzS4sKV>FvD3{A|yGwg^U\ʤDbܹAF7nJ.B8ǹ=ys%]QSP23FnA' S]Ef@N#U:YtDf|Ԯ~*҆(Pfpqװ=_7 N34%C(#D`q~惯\.pl)~{@أ=wbm*0@ Q"1py~B@!"AΈ-;9Ȭf]tZXmZ#gm& 9zq+#\D8,'$#\"j)dNP߉n7X)t2$1GpaaEԘDa;?v!J1 9!0CLvf\fa: ɘyp!cG 3Eɖh4z ÿE\nۼq SHoIJ>AJ-s%9LmW4g ,ԌIn{L[@Q摥>,,mĄ2pt(֤]-^(Versu`-^'Sw4{.SAMCs]ZZ/A_ q:?3?@6̳ض>J~}`oAt୆E;:r_- ԋ I3I(IH0V 9 繝r.b7Amѳ{AB"Tټ$0RJnO܏R^eRbISApI) cy>h0z C'5#\Ы*A7/!XL*x1%JmBj ޥU ,))k%H$%IH-w.G3KQ@JVS1䑀ث]쁆grzu=ӫ tP>]OK%HѢ}O:f\!DB k8ixfg9NRRf'8 4R<*;}XLvkF4l3;y/|+lLt9cs2\iY a2B1\8gŲFÃI3bmRpÕ>T iɘpMCqp) $-G:F IMJ *s,4h$A6@&2C3y>pk,QiHE 1vXqFJ\@HiA_snv7UW鈴CZ]Z@ݐ ;Lҫ ]yzFY\ݵ\^m}I$YBF$Dks^-1`&vs[ݒ0S=7"7zيMwݴtc"|摼0m׮Y/A%1c$P|ΜMɁ1 o7Z;Ӄyi1ƇF+qNob?c'#_(g"yQlh!+Q0T!V-eg'uH<AzL.K4VnHKszs3I.(Ø] /*m?E a{M= c[ѣK€W9lMR{`z ^!ؒkz-p)mhPw5Ky-B2{ (q% d<7_W{`s}Dr,/]Kom4xa+c'|Xtht0-&"$,Drpk(491.%tDs&`ksPΏdžzdY9 u0b'JA9aI>GLJ!8WKHc2We}ܣ\޸~z.4iRq$mZm(KHu>mXjf|_uK:NE}Dp~6Q!sxs.;a8o%}R1=Z="tSU=9:sJlښЌ@n\=w}z_z0!$Y,ƌ^dAޟ}K+v \GH ,mMqGV- ʇ8OḊOu伌&i7 4Lro<m||<\-nh-1J!1nZ)EV.B :.b~fSbU3tNY&?X/.b6u|jHB(0NQ1CLDXCPVyWUG k41Z%&wtDS q"ȭL &,Xidf(X 5.3 5i U/iGNUf[u0ݻ/֐d.Mr^[8 S'Rds ҲvkqzuEEv>n~QTb$F >aLLE]҂=/uM;'5Fąul4 ?Q<ܹ?v m3~;F9{̲yKW@ױtlmd s]:;'Y1w ]缑g{>^\4 B;ЪI"Ya3ˍty,)lɽ1c, Y9Zq>S޻nvɌ1΍rF"fmċJ+L莊eF̥䅞:V/ I?mj'@ 1NJ4LQ*@3䝄XQ.N67!#V He)]IRF|l\+Hg.$%fpA"^yMln-gf洺m~@ ޵*(#%YdTx_J]z` !NU}ojVfB8<(k>$ҵLXVMML HbybW1U4y=$6Yy??\#h&z+.j;e:G%2oV"c7vBtb@_m!76BBv-8,ڟ|,DCKXoҡrR*: bx5A71&\_k{XzmKGڰߞ Xǂ&)N&PɊ;1r2v7U-Qg M:n7Ae.7~X1Q~=s p 2.茙VSt9y$rsf'_e\B=A璓EfnF ћȹ&zFcA̐;[i?: gϐxј..{ HV؏RP[ot¬Ԍ)#9̐ \>{<5W.XO66mh/<̫j.1}gDGIf7m?b0\KxrLWt}eKANOFM"yZo9>,̈7³nӃ65FƌBN%"B#:y`">zԏs>iP / jh%{Plg@tf'w_OvVNo.:[ nΡ >%sn"&l:ʔ10X4eujq+ݼ78kDB@ Zfp4n~\gx8?O 'b ;]Z9= 4S;/bڳBqG_ .*}Fr #'SؓKLF+jѸbǘ燾:cne?݈<GB|TIoYؙ\ Ib\̀m}{3afRMD[gx"s㧥]0S̭I;S,X5 \+*9>]^?^8_~\S9.53{ $ $ 9!ߩl69NOnNs4!k}QgIz=`XA.uz(e#pS*Aq;^Kt@iTS;ksB'3,;rndnMDy(12(b|nӼ]$2T .5ՌcH# \hE")ܫK-F0d.LFJ3!!`6&w5q!O\Q_bݡB;%]J"LmM]c>_|#r)ĢDٷ6 >+c>$íygr $5u 9)[] :>/1d- *X v2VAnyMhq >?+еքz ,򬨝5$q[@$y+p` [GP4jT"ҌH܌=KkӠlRڱµ9ú%NJF=+&frQǎ4vC9}#FDc01j*m] ]*1fv8H=C+Cn22ߝk| Y~"CK&Gsp{y\w2ºJ߯^ j%j j>h9ln{|'5l gR-Ě>+z[j؛ENYSxyw7imtQȀ&p (Y4 Έ:ëUkƌϰtt"knmvO%vi7O=r@TT]sB6ngt{$GcϫVj|/0|:i b /_9 RL"3#3kB۱skC, C2h"9ʳnUYu:~VftE^cf.I*b 9y=*W* w e`XIn X"t!t=C9vzYCL6:x >*ccf 23w?.jA6)Xkf Hz^ҞɠCYmu(>7vC2`ȧO[tZk>Vp7R)[s/9Y ѱA8R13Œ)ޣq ( HBpo\} N,aҸ"8xzD$o\*IA 1qڎ%qjjߪҰNXirY)Rqvv?:hb߰c{**'m*ӓuxSYF-,3%qTI0*̧F= 5:& M* YP1_غ8`<#$9yWK88Fֈ!(M=3!2he3s/y'׿;Z l[ ?ujxX!(T FcTyFP4P(rlίl.h t VH8ka73u zy^*U&KG'@F>N8MlQQl.!4oy5ں®DwtşΌO =\ܽ}׼jCawSƓȑDlwpZ5aH€ 惟]>y'Sd&+~ 2Vk!~b-uC(mQB3!7J DBkt=/e3B.z)p^7k]ֽ6{{yt(!ؘJ3j/#HPKTq׵Ql,=&ٗ*V}eʪv¥]]mAθ|(pI'71@]z(4|ǵ$=VJ)Da! y˹go1<_s‚maJ( 1dd` D W Qw1 mm^Gǎ|G72]l.oBW=&\< ֑d8-(#@ k&@Fh:8WJG1dincqffHU,AR R:$YZpWe/cT5ceLĈChT>FF\iLHh%O.g7h4`8|.jUqM.@-HCfUqF80$&~wotv MtAh< "LSlM.]yKL ͔3B=tuę̬CNmݫc!@W#@e!TLvvMGt::59FhriȤ*$kw%bHDƝs;_IŠ!dqJiECn% ?{+,hZipqVVT^Ah#̶Ci I%#+|R:si=% Aډ)gPNw,%jYlҘi:%1i `4E3Z_ lɘ ⽯E/ 5u0Cmd%,R8sV%!4wv}ҤⶩZ-UZLl@ az&nBSM`wU7X1#GltT6ʓ dTƘ2Re'*RӍZg/Wbzh&:MnXaMD"!4[MNe? {|B_ѤQd1$_,ȃk.{8Cz C7QkA:@R`t^E10d<ʷ;2wqMA'<'$06(hAXYZBۮuZ%9$N9CTԂfS*w5 vܡ8#*_Ia:ΨMuH @:– ,T( ]\*1!9]t!DoEkjr\:%~KZ-R %ko}qPJQw$ѐz%eHNFJ>8Wt Z:zb>\˟s#q9RKDj4SӜ!,fYE6좼Y&Bs$ ? %&5! QB!&%Zd* :ۛa:,E6SYۤ*w^fi)쨷 aK:Zoy>nxƩPz׈7NQT*$ҘB{|az)•$ZdIZ ]FdYBq۝ecsZ4=',>~_xz8I7aG{0+~.<2+"G(R۴-6G2遫يq|a5{w8lnoBNn;aRY| \^5<=Dm M(U6 KxRmP}N7:Y6s-;ccNBiNcn"#)HdB&SR'!vb7c(D9ugVS C9rblVB }0.Ȏ+QGP+ZDZFH^t,p&TVV2B0L2ON"ƫrztw? goÜ C6! A8.Fd:& 5JX6HEQpZk9Z(ILBmOHg}.w•oy^EI[+d' gy͋oBes86A| SҐ=h#RiLt'۬qu|e{) VЍ[.yy5D(& 49dC*&-ޓM-ߵ@ZT,->yRd,iu;`I7)sF±4jF\?{3.VȚC$ddde(R(c(n1#C Qohヨ|Ɩ0k"lp\8sϼ'5=z+WG=3 TBM[!|xFF]|ĝ\[:/46f,^7W~$B<,aKQXn1h#1^nɜy1npEW|i$+9JL9mK&}3/g_H$|G&$38褚DE6oi1FR(7АO}8Z様wbOBE|{]Uy1EQ}ޔ֎Vʍw'>S(9Wvb\ "3}w}k~dVIAO]<–^Gc!:K?~مy ҩ(`(s(!W d}4H$woo{'&Q'8'15q#f[n~ h`e2#t9i7B@hc]mgC(8=z\ֽ5:ev2e.~~C46^,<2 'xsEbPAZ]Qa[p|$waF OL+hNf5ӘE5#&k5!Y6Y;vUUɶF`Fw9ǞNQ;FpA˜zO}~+}FLPɻ"offh !lsj fggU*I@bzB#:_Mf({šdG.xK_!VXd\Z?~OYd2xu4V0#?dR8!4Hy6<+ 8OUvNCV>qƤ 4RڗTiVF=]|5tΜޱ֠20C/?-: ң_tGӨOr{^}ooHhjn7p'}~{yOFhJ1 Z>l4=|sZNl9Bde]A7{!a)a3 imyەoޅiP74#3E` N/ml4fP;<:g*u!fjAs./⪟zO;'h$ p$tQKhbGaH\F^Ku],كp?뱮7xᅥ~HG2Em X5W" FX (JB Omʚe㠔*XI꿑J-"MM΀a6d]N;Y8$"%@.ۼy+~G.Ա|>!Qo ,5K7q)Dd.rB\$v !c2 &|Nm2טc.iyҕǀ>oouғϦ=5J> TV\+7piRFy8kQ%F A& (Z#BhڪDobye7kf<zrJr˜K/ߠ3e˹p'w~d&ѰKGl6ɜԉIEJ"sh㢌GY[_\z> 1暳ܓ~7#3Ⱥ`k} qݳ6VҙiF;}N5[;@rtol)rP= 2,4| Ci8y}#}.rsc7Fsu],?io|̟3 H:9ެ&H,D:uyt`N^ mvcMs#\I20؊g="bNdx˯@vM%pI}/z% K?s\J/*d)F5uVH /!=t]7o:, l  vyӞÓ.x Tr,1) B"pP1JX8bo8}rj~fwmr[W>3 ś ɺ18E+k,1] ^W2QRF=b).YT8M65/dePq߱3]Gw1Qߪd!~-$ #‹B|H60$۱KmEbV8,İs y5oB.Bjv6h,AWJmߍ;*1A(ap=*VYoGp(`FpBbwюZ\Wclu6`902Lbj&U--a`#U èqVV6G2uZ-Fn XI"ńrCR U4֩ RE3EafϡfV5)"VVN$&$*X~\Yo Rsl 1&!p7>րKO(fi7|>Lng/Obo-zkuМo`|~T+E.^v+ؚSLoZ\3?9.9[ {9|Xd; 3dʠ*HzM 0&/;,X]FI 1)ڽd5@wufHŕ?ҏ3a Yo1q1E*+ldIӵ)#hH르!$kh/&Ȑs9}"v=yA v!5ЕS-$ͷӢLVX"ƧyVS|5IdFsE44$f9xmSv 6hftWhGԉ f4A묜O(<FPlBFhR\M)N'qj'OB i/4Rkk_cGC3, FlRS[3jJ. 087{:D.:6Hhjt9u6y~^3!A.: ד^2ZA}]Hdh7[mn~Q|~+2~-j-INDЀpaxmc|Oz*rf* #5uhmvod*W c+逹[5QS^(c2 k}rk̓m:Zkg>|9)2)SUB)]*(H1& &$(8ReQawDTDՖF%d2'pakcs>;w;ź~7}o"zeua8:؎ -@?. NmwY)pe"'VO𭋏Q[&4n\U(#JH,EP$_<r=&h?#_6(pe%o^ܥ^ _+٤d䉖 \M ʀcD:(i!Z 92 LE>P>M|?yODk"%/O#cB8i ȄK`E!$ED6Sʼ?7lPL٦S93x| yi6g`W]3l-G}VDopfԌٵFVDLD/' ؤ$C4c&?m4...%`$N_Q6y<$ss.\9Ϲgp}&0HqUaqӯo݀`a>Ƀ]0u!0,Eb6B ?12 F4iamŽL#y=3xiND6A.Ry+_OJBzԼ91h\Ey.F*ZNm;#eN_o,B dW?q> q!"&V•b:m2Mٔl{hY1SdC>!tRӈٛPC 6NQ݆a-"{wrr~Ryin͘u\n2$]Dy T 6I7rw%\~ Pl*CX%11TK5ظ瘯, Z)*XQyuXq>>/}Kԝ8]ŒJĪ}?wo>CP CgPaf#q,I-QfobDxᅥ/]yUM K't(x%ĶL _(jv(x8*a$ cN3N9O'r)`uno ?ꉿF-8.#o㋗/?GѤ_0ui,oo!8"AeLԒJA ɥ+(ߣ8bMaٛ<?C4/GA귎NZV/s>vE}jDLX:I 匤6E1Տ9Ni]JUa7HG.gwJ88On\$_$bK4 ^R !n\xxīT[nq`+`9Dx;_s//P7 hwz %ln# $Gj,ϟC) z46q!swB &`a>5](v2xOf2{:.h#[du&L¹ kr<vL &vǜr5IJ|)'K8~ŕIk3 U ,qI2h] iɷއ'\rh`E6hR+V)tKLn VYXDJCJ}_&zU{ln}jqxϯ?V}JnJj:퀡@c,XL[5 RBo|}|'?%lͰ=Xg*fS:[z{"OƠad&S0Ɛf|zXy瘜L0M Zqzt9aFTWMcf 3U =b%qBq^Wm sy/];VA\L9&Md6>B](I/ЉDN@փ?8;YyP.~E9u+q;y5 n[56`רD"e1ҀSÛ>v>COW8a3*hPRuQM^~CBޫabJPVg1+x1ፆS-CY<8n=np *Z&dn7K) \>huTx ČHvrLkG=D :8^[[GnN..ЏT> BbNl}gۤbœ?hW1>!o6G׍Ayt4,~;_VΠP9fE;U bMk%GuUd,Q'4&mLDD(6:[:WO}ͷ+W=B$pdrWbkb1R!U혫&$$#̼̪j*eSRHu\͎v& &۩%.s Gʵ+9]=CMxkZ8_%hɜpn#2(NGA'%dɇ|׷(u </n]\p|Fƣ^41+X^]FOLFί~91N'1sX#&?kň#DرFE!fR9TNWCR@Z%ڊY uػ~--nRUGa5ʷR}<L?^]^-^IVA ަT1r~9|+y{y*^즴r¿&l`TS |#NWv 9"V}-/=O^KK"Q-a$˦H3g )Ϫ&XD\2)},N&W@Jr:\?OQ(X]Zȁ+s^R聍F%0;h}!GUtS!9{L}(wo|ΘH8bmQ2r`w .&Jx~f@_D# K}E%QDv2F3 =i)&[+V'C{:ԃq0b\VJx8]fraPk+Efb H{i8 lx`ǒsȇy|[aUynCcMPv(!psFG!v |sg\mvԇMUpZZmVPvqs XxYPٳUE#quˤ=ltTBz!Gȼb6])p!X,*&2\8r혥 K=_OZ†f=6RBf |amP@R"<]3,K^b'"baƦUg"L+PJ!K? h44z ooӡMRXà'ҨS/bv8Anv(l,3Rg3 T4L[tC"59=`r>M QYَ>~-O4]J'y8ed()k+z}YQ[Fhڋ)Es[`Ͻ5\BS6 .sSO+ ^Jo"Ró3 Q;IDA*sqi=k|-R"hF9sg\{+/=2zQفjq Hzat H%cRkBSFo+1}tDC%˫~觹_aΩr\ /sQII$qpR6>]zllOşkn["Aj(i2 ^ASHq䈙B?tvjGR쀬)04܄kmx;yny\_f!-Vj+loRsHbiո a mLj?%5&2u.ր 9HF\7互vDDF?Je=,(LS9t$o7w~uJ^v`Pr;(%(9:77WFaZRʚ񆧻h[(;y*R6cʪ EJ')?>q? -Diڭ_zaCݵzfv&I>dXzdCGaMENXI7ԩhxpDd m_}؜O?&щ`0@^pv0X롅@a4Xb# +JLQ6% 2 l? ŝE'Pa۠D[#1 &!syb&Mi!3=\#VBGY Qi7HAIh"qBR(yy۫[bzH}𶄵-x1r<3)Xd"A::4adxejCf:%f8R5 Cͯs)<"r$ң1!fj+8H g6T)) s59RIrryӧN] 5 l>@;ߡw8CxcX~)-Z 5k1aʈvb )u#qSwDZ^-3Քia\%ꇸFa9^O5~ۧ=L/ƨ.3fsrn7'^]9ّ`ix :=~"1t8UNn9 $TiV)HDK( =o ? qJ9ogAjn6ÓW:@`u*s.#p%#O(Su 8y~С%b!L=Y'ig-2_99^g}B1Dv7, A: APb(Z׉Acҙ'ڍBlXap}E?  TT=0sCe{ڳx)9M [&qoB\-HL<ALWFٓ+aR@2AҲ@E8^f)䂢OUtѡ/(%" n(VA'i}]"r z(LDM(L9=uUbb Ro6bUTP%ՙd5b2 ﯴ2mQ9Qx!n&Gu{U%18$S?HD}!Wo@X7@e*$T]>{籍oV|d%1U} . Z" 얈0-S$e"QAHk\JetxɄ# mE6z2b[ĹޚG'3YP9\cWcCEY ~y r ($xE򈔡LcEb1U 5q{"ʧ9RDTom>By6t= t5qMP^#ַ7DmLCG!A@b>+`VC8Fx%1? F ]" Hhm#Iy4bBdibD3)f ZiC+ G9azr'"$Ox-?b9M{idX#ō] Q+8zPsb$fB}}|ҞF ғ FLڷtr.P|㱯/ؾ w&o=cM*NH:E!3w;8isԱEɹB'wVH-?"]I@`ԓyҩ~c1H%q}#5 1B#cڃ6"o-СϻtdF{YaT Bg<rʘFnX9}_H%YY]ѬSTev50>ahCyrn´Rz-Fxd^Fm3'1pqC Xb`z@U` SЈ,N"YYo@#y;_{^~G]zN8U@䌰H!X¸OO~c|ɯ& L2;('ƚPfDug:2#rIvU;ϔGÓ 1E1J  .`;`u+-?mkgx]wp;ťKLsTm:ז]U" SM=~~8oԿW 7,ܹ:àՀ 2c97"F_+s~*;˿%w D^WRM^?E"Sr 2 ˿+>?EZ6lDL9yza8#䋂Mh)7#mYIS.,Rtr>-eNVWxkI (F[ʗsa DkT ghjqe:Q~g, VjnMF " ghwy/?©2!mPJQqjA+cv%ndy_ȩUH1^$0V" FmROIz&G@'&'yEЮ,] 9Mu :MRFa¡ʙ& x@$JqVJTQRj&"L؝iͮR;$mǤǓcnB}DU='Z$}hɐ~:(1CL)W٠)>2#<'N4z*NՌrW@(3SjM ׅ4tkMro[&廤%hK=}"l @,)փm0%d:ʊA Z,X' %03ұQgpq*#Ffר3q IGdcAL'#߬ #3d'HDB9Q4i -jK2 `IKqH/lR}L÷v(/bd dqۅ4|u'zlTv8P hd*>#'axd$9X#BNjYzӖC'׮~EÚCʴ48A 7\8 q{FL[ UT$sqIİC&T:a$∍xa{6vv= M3DnY") F((Hl~i1tE"=ĘT%2mvnjUi`vFf {5w8&ϙgpꙅ,њ] (,Ei7r2+v'0\VBbM|npFuȯu-*%M8ymwNA\K:h}`mC]Y<];c'ag&1%}WWB83Y/8.LrFdT~kr${ nv(v/JvDrGcgyvg+a&}F^m^ҰBe:'LAY9#)f ғZGHi|==N}3i6,&6o,F<`#q۩%wK =v::"0vftβDp^ +FFi.'H|),լoN֒ݑH;|6T-&㧀v3Ӆ*k:2A?DQDGHpb4Ů7Ќܬ_)ȣ>}BG~ >Kc^ 3_M{7Q,L>0`jH #&Q>pߔP̘:8V1v«K:$v)Boƃ=lv:Hbztob}$ӎdnf+4${i~"Wكado'tJyh|{' U FtȮ SFj<<]Ȫ%--Ә}f%'I{9@u'Hf*WxM챽 ?kb#͠&s`P˱lR$ # 5ф-W  yKc+ \=4 f 'eGYY*g%,yL3k B雑cl*E4fDcc֢\m?igD1Ɏ(w왐ڙY{P| %-{Bv#x7ǰה&HbaE)*ɗu[O܉_P[$7+(؆em,<-\< x$8"qP韽uC^nAqu1_ 8 }}]` Lt4;{^i2 Ux}% g8{XzZ欎V T3ww7@(Vm<[&ܟEg׺Ounjh֩CazCPU1hj="pZs%A۽te7# i5FuDZcډ3c]A~Hx"Jj'1-Ü;GIvOH"D W=փzka_ʵf3Wɘ_=8hɈXD 2cEiVNPȕ(*,7'3T2Y9g !V1L4̈5›:x5/Y&Xh qyw| eʅ*r欎.Xo5lůPq+s<#|'Gn.mLRx@ <8[[AM-B 8Y= /E-6!NU(yNRU7= GF_Ľ02ryD4 sUb?B*/EWY(SJ8wት2Vg+Wqao<%je.\& kZg=Ѽ8^>n9;z>/%T2Ks8ybIܴFp?+qz>}Nj >k[LDu &N6L) m$CՊC|v.3.OFd:3Vqm;Z!~ a#a;'aAh'l4,..罘g{6YW(J;}kVtL9g'扭ǩwe">4i%VZ`Ezfhr=ʉwtA1MciDݐ^o4e-s]}nVk,u h.^aX8/8C>v 4->n=B edʛuh=ϼՎt5s;pXY:NA O/-p]>٥3Z\cm$N9!1FP,AZ"ʕ>+K+\syZ\8AaI$3DNB&c#z1aW#VL%73~\?O8ȜC MBq<VNx"%VYZX/q Rr݌pnuNˡUx9E)䊔"sgg&`s2W1EQt]K7C 0=q#{Gr)ӫ{< +ϕ),-0_'Y-rz4tyuuiquEh- rE^[foѬEq<2I޽R fL%@Z277G(T E,/'OSlE1~Hӣlu¢m8}#KP ֊ÅCY<&(!F2^'21X>\ONxMk6c6OEw#ȳ'[^X7,dǛ:n%ou|u|u|_Fx|_Fx|_ױ_ױ_ululu|u|u|_Fx|_Fx|_ױ_ױ_uf IENDB`qwinff-master/src/icons/list_background.png000066400000000000000000000105121347323557400214370ustar00rootroot00000000000000PNG  IHDRg-bKGD pHYs+tIME \WIDATxmp\uv%[Ү;6]@HqMi&)A |ox4{MCH3)ڒ Mv` CmCZIf}N?Y/k{ҮwW7/+i>?s>/      BBr .pI]k}6LNLi}Vx(u0v( LݱXL4p9PPNȖ-[ܕDP*uS3%hRk=fD"qԩS`EP)eVafNR)ئi}>;ed}&"TR2 ΗEDnn0m摻띻@KK˸Ay Z ~uuuݑNH"&Z04G[Zrw<2a":Q= " @-)`eYoϊnE* ںoΝ;+_`az{{>22rTz͒se*%g(dRJ-'-Zrݏ(҇a~Z 0m۶-,A. S p ۷WHD9>LCb<C"kmm}Gzyfƍ'B.0V24bԔ5Z uuu|\a.BW=z~@J :h֣sz^Ts__">E0NKzwnRQg3 `dd۶ pRz{{|```ÜSO>x<,Je&`!5~BD0i*CCCC onn",eѫyq9@u@bkkkSJ#-N'Ky~~",k.Y^N8 {~^Ph\{^%ھD ~fHHp8<`Y[~7mt \{__0~cXj"'>HDя w- O!H0h}3<>|CD`82D#^#~`(C$\ ~wtBr?gm>-*l @`ODi5a-;vĆsjHpędWWyE,8^n%B C4u!f7 VJWL `H{l簄 BD@!_zOe%"H1Ok"!4mX\={sM̷\S=(Ra===U9 !YsRoU_?S}!PtS3"IZ EPצl1y}s,@Dg$R, b1!dD ߚF"pe'Nsloo? \ VK eƢ\ǂrJKR>UDʴH)u+="?YXfmjj{w&&&ii5|3PAURwF,D83<7558[fKeZbAj"'K*fSu%@sss2δ@ @"W'PY|Kglll(۶39]nP(TZkC 7p%EIzѝe;mmmA5 ._nD4?N>Ǿ"رxHJ)%0d^Ԁe ܛFRN hGʥ 8.(;_B )XPD@AP l}7ʨ =#`fR\+,Ԁ%Amm-&''mfNQ"`{n{ڵ efKH$#G$yI ("  (  'ŴY7pٲee3==;;;󹲜U<Z/WJ-m{QpY^wC"X_.4҅B JnPJU3۶=^,͆l" 3jMMMjݺu^7X :59(H¼!]׷G+H1sH?|xzzT":=Sq&pݝsdll ^7gfg񪭭boFK|8wWRk{ԧe$*"jPJ}E)u=s{瀳7̧WA@r\J?cD%*f62ljP$"pP4 c13_KD70*"ZJ4GLDoF  m۶UZum_g櫉@%\#prK2Ȳ4<֗z/Yee+**WJy^^ssxG&ֻA\k]sJ$ >iK<8C3\i],xw\rpjj*xv3/JUuuuCk #ŒK$˲ZS.7^{*,!5J{z5qp8'%YJ)OV$k׮]#_LP^׷}vuuI (k,H̃p1gCP!-6m:WF8`:ޫ xpzɥvP 8̧(7'z 134*޾> x BDTN՜Nu 8XWWWV|H BNZ(a( }`D"q53ߖo ^wi͍PJ X23~nZ)ظP^pz2$3ŽR)DN0䶶#^d,ZzfMFDg&Ts8(Y즪 8=L˟M:^eiiixβM+6o۴iGmoZZcXQ$uI 'xbILmRys/mm//%HR/ض=MşvB8dWWkjj̇LeL 3߷sΪ|M2% "7T1oBOR=KCD^u```|OXf0";\.o|0By"XwI`=Xfv1s~޸q'm? 7ϧx |g,PHxZ,&W$1kfL}_gh斩E@!$aRJsjۖWtڷ# "3H;̅9 I˲@3L&u"p.5&y3s5EԶ~?n+eN-X k"J_38%e۶s\)+fN|5 #bN8Q)jkkn߾4@㙗mii9 3ߏM0 33fV8X.VQ5@i8%n|xDtS[薞7o˛K .3 -zOk7}&wD4޲,oD@a6l$o8ixR&(`0 SKRjuIE@uV)+iE hn"Z֫}_-*X3Fgê[^=Y:GR}$p8|KO/kݼys, 3;MӼ33% v̉0 cEf?WUB x>vb˲BHff- )"r1su| \Zcǎqi5%z0s98$zf~Fp,pA2ĭettt;C1ԀBa;<,V#Pȵ#< k֬}#'0^jS)`3 _[[[?h00a% & ۶O2#Zb*'\.WΛKr" D}9׬\(&\?BΌZjii!       hIENDB`qwinff-master/src/icons/mark.png000066400000000000000000000014221347323557400172170ustar00rootroot00000000000000PNG  IHDRasBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<tEXtAuthorJakub Steiner/oIDAT8RKHTa=PSGGMgla>1"7ZeE^hS-ڸ~haPX BM԰iftf睹׹@a³s|f|Be:gƱqqElB1b0`{hkY7e0Hfܱ8zEkE1+T'!Xtlّ6]Y@J^` 9"e0?sW*)( 0~#y!LO@Ixx5KEs,&dVFW4=.Йjr zlHb CQDc!DBq%S2H`ѥhRk^^>74 a( {囄jO?;'Ի爛6dx&QR@x/wņbmABy[PJi&nbG." fmѴy[`a Pe tEK%{^y[n_>{d< fonWպϕ?NM^UEl`z:MpN?/=7R$VMGv`04dUmT57`Uhp' }wnLIENDB`qwinff-master/src/icons/media-playback-pause.png000066400000000000000000000007411347323557400222460ustar00rootroot00000000000000PNG  IHDR szzsBIT|dIDATX݊@I&!_R&m+R\@!/iꪰ6zPl950as"'@s|dGϯ}>W||#4m~P/hV.,V@Wnn6t1LiڳLt0*] ,\.u8e8N&Y`X HY~N&Y`e o-A,Ḁ<8u]*(p $z—xlfao,K̎#$ }/*p=!*W,,u]^\Y@3$ (3Cf5kcG2MȬW'fM(my~i~$ H:;ιfΜ9H '0IENDB`qwinff-master/src/icons/media-playback-start.png000066400000000000000000000020041347323557400222600ustar00rootroot00000000000000PNG  IHDR szzsBIT|dIDATXOh\Eǿ&MYfw4Cbƞm%5 [$j4-,Z`( ^Z(BfKnm43a76ۘƃœ}w~iOx}=f.-MP2zc?f'OOM}[ZO,.Ο47aa~qN!Qr CCtл " u(%9_CSJ̚沋mGWH)%8g>SL&3k~4c6 rG@(`CR ~S93{"dw}>DZ5@2 CQE0"R Ģ1aT7AX Z[S(LӬTiz X37|Z{Iv]wifffSGXh8sJ( W`;6VV wѱu%HaRmv,ضuy(BH (Fkj, X:cmmm(*b14  PP5&&]q?}3~|>oNOOoz2*DQ"k c Bs LNNxw2?'϶=[0VL-u1c sX]һ~l1|ԩWB人V*]@*  uEógM#IDUQU( D#{.^U |,,=T ÀRC +W.{~sppUet]~Fۙox'n(Wm 7f_x.BUlmzT*`Qa' ob+rRJ)])բ{Oz*|^IENDB`qwinff-master/src/icons/media-seek-backward.png000066400000000000000000000020621347323557400220460ustar00rootroot00000000000000PNG  IHDR szzsBIT|dIDATX]L[U{{o[J[m1)l8B0q0I!B/<%t!!X:RJoYZe Ȃ&/ܗ9wrq,+ @ Yaym/~ғ1x]]];=}~wog\.^p{ikgXl[Ŗw\w&TU}~@]E{{[P5H4I@(~uEElm(2!`8cY8⪩zl7}f 6ӛ407(Ks: ͗{onj VA4 g| NAt:}0d2577t z/aڑX[A&% C0 ΎꋅO=W>y7 KTVV*v[jXf#e2B`Yvt7GmE|x"Q$IXLN'nom~+FNtWr&34h'#ݷeyk1qyjwV۷bZ2<rcFyDp14±܌wvQes,Ą86h$ HJ=o,g䏏}(Y@@EYJĮg/?9%(J(~PbTR1*tQB u9$AЀ]~vUUR0\ׁivl[soaIlnmme[ C:Ku=7ooT*$BQHX,ˁc€Rlƅ_DLfE+WƦ_!EQ4m.|e󣗗L.P[=7[y.x}v%EQfA¸s/tIR-I|QџLSg+fgm$=iYId29gke%(b E#>JTTDq_BY(}"gIENDB`qwinff-master/src/icons/media-skip-backward.png000066400000000000000000000023241347323557400220660ustar00rootroot00000000000000PNG  IHDR szzsBIT|dIDATX[lTEs3gK!HL&U$o"@hbbՐvHA}E.xReUbƺ@lS(]텲rr_f~7\2{HJdʜ`$e pAxyBU$,B ]/YR\8{"0+/Oz cs f[SZZT>o~Ƒ#c)Ç3!]{ hтG]xeuD~pX @.,q2|eeOOXIQ)DH&g.7+<OZ `ڿ'*O:BZ~ w݈F#H$$ d2|JpTt[PJ'w6lbKYFc‘0 HܩLɊϭ5]oĞ-[JÑqܸ9 I", .` ι%鴄.wbw B>\ B,$"B&/Ly׮/bx/I^kB#1H.RM-+ ;. vJe(UUqB`FHP?~>Йp9Yy 0 K4-kC}޸}k$pP2JFXº4koھ~<8 lD.`,K)paCU;>k8s=Ua!RuBdOOOw†?U;wny]4Tp!ӈF#Pdv]M958p=@)YRw˕4BiV0AIN$[wW؂&iZ 4MT  gNĘ=lz=mwMΛTEだ'SUe5!2u-hViM\?V۰fCƣ2c'QRQ4(qbtb?h/,X-uNY6(qUc(e\&獪0LDz/nZϵZMB4>7ԤʥOSL4-kuhpf.^x06 Îx""@0Sx}LQ*̝d t 6x=>褃bxuhEFo͎0,kf,BoZ;5e>Y& x' F8 !02Sx8OZfJҨhlg.mOrfpűd2YVJCk]cey^u5Ÿ #y [_@,,?IENDB`qwinff-master/src/icons/qt.png000066400000000000000000000056571347323557400167270ustar00rootroot00000000000000PNG  IHDR@@iqsBIT|d pHYs@tEXtSoftwarewww.inkscape.org< ,IDATx[{pT;$! $!*/ J>(vԎ:cjۑGZ;ӡF ! y v繧l{fލq09o/{.C)Xp 0hbg8\i1 e^JjIRe~ZgG0c ,v `;pe0g1"{YVQ'DQ)%|s]{끀8]p9} KW1UCyrNZI=EbuvN#ojC<(^J(('EVwhSp*eP gnXLͰÇ ed*4H"=,IگCiWK|8Bbޗ @)eyI+ HdB++)c^K?p9*Ƅw&y!KnJ+M^j?.Ϥٗbh&3DǙq Z2.-D؃{%@xI„  4DZL遰nR=%32LE%`G88BYeo8\ 0O0Ê݊kVh̚,ƚ{i(> ]p(v~f'na Ȝ?;wkwơ}m %O0yRI)W=;΁> {TLv$Gf"7q>ңsTZ  P5 vn@vSNbGP|H՞t5Vest4V}^y/ݟxz,r(~}"FuuX=O}M\"z2UO =GIkL:pObanʊQuݝ"f ~#Eo|&@A/k_Yv 7_탲֭ 3=fYGR;[3l4Ifo NB5&tZƷ )06 B"i ŀIY anJk C3Q|! I8h*ku.}&yɦi#ODթjL=F#`2꯱aXEN[/ "h1Pǭ`1Fh$IfQ&66MwKwҏ_}z@Q|Lm7&Z}ξm o4sB)EFGHwc#d|ljU\#+] s4DFf`0gz%Fjz{|Yj;`f T+܃"? F@ᬥ~6 #Å"z^ ].~k[QeY "aĊ~&xD 1sV;~ }7a#!8nũyv9yv}haIɚiV:e!7=aq z%pL!\[fyv/`Ub#7asDol;YuW݀,3j&6PՒWTsSa6ʺW DUSR&DWV `wY\grᶼ_ckȴT6!DQՋND.֔oS -MXR]V~>4 CZ˃gXf|Xf/M/pbm-ekSҠD%|]~q1Y(gO;=VsG K%J=nGCjSS.RY`  |%lcmxۚ&^U:^iJgЊ`> ZLh6!Aq'QP$~FdZ^.-gs t,ILA*{Rg{ďQE`݄J)DA9*TiiŖ:1TsYZ jYQM%JsY+ԅb_'kGeL{Cy^9- 1I_2-\|jYx;IENDB`qwinff-master/src/icons/qwinff_128x128.png000066400000000000000000000503321347323557400206000ustar00rootroot00000000000000PNG  IHDR>a pHYs  gAMA|Q cHRMz%u0`:o_FPPIDATxg`ו6ܙA%$XT)QՋ-ٖm˅r[N}dS7$i_Mvu'[bg#Jn-Yd^II;wIKv{DsOys!1?&Ͼ)|-e6!>cxX@߀A?`3߇?ʘy y5U iVb"˲21fcpNHIIDbN(LAw G?wz|!5aZW9a3z)c`Al'P'qy_Kp!>wrja] FDÍ գ@-?<.7dI6."3 P(ɧ1P; >/ζ=-Yk?Ǔ޸V_Enn̆̚2g#G$EnRtU$PP_/mKWaFC3^>$bS)` b 0Dmf#?DS4dt3oh^ '~̌I @J[}k83xk0wB:( !K߭^fb9tl|}͏.wAyb; !OLqv{ {!~8{msV#|ڻ\܊)-uc4ۇƊ1kIPN1. 5ΛNBDLs@xmQ럁w/bב'IfFjۜU"obZ '!BAWԦPR,9VST|(\Rm` .ًCulÎ[HWK/F6DeܹnMZ?=8:p*[YKEl*h0p1a`6!`V/14 L|U1PB4R"}`ͲV泿y߷v8k#M`Cx[f.twce@"79Ɲ((%+W £TAP$4Jm+KTZJsȫr$j y5cF#dL(آ|Uin vQˢ;~5mmo_}}^MlSm?hkjjX]t#N Ta䌫S+9HZ!6쩀Ie7Bz ThrC#Й8~$QP Hg\TPdBUDQEGCd‘Z@*"D"?t~E5՗UI"3<$ 1T]Sx@$}~jblϟn/հow_ 9W‘?]Kl6~7.@cdַ޶]de8195Ý"+&`)\"0-CێㅽGlw=?[{ux{׮ ׯ zƎ![HO%τ@ĉWzd=gh>j{x'~ۊ|1zJa8{G3%v$4P$B$HDcH懠f哒#L*}d'3B]TNWoXoc0D,bUo0O =<ǿً.}HG8:'y4ùsl/()5d555Xr%|>0w\dOƲҸ:ߏT2>H$D+Dp/8;Nw~>W܅C!Fv5Ay!sl/k}]t ϯ%^xKpZ7-^ 2l>PF ʚ10n=ܩɓ'3Q"BP\ (d2 ]gl\QeA(t$Ȋ 6 M es7ɮ[>+ii;P[B?*bj"Axu߿l VOދiSo4Vcul_+L)Dx\$H@!J1X8/~G`߱6T31BXs,A?$X k/KZK#;ia`hݣ0{lܶ]ʿs_?835gv4!6! D$~DᨬʃI&tPBMLCJCsIv/&!;mCo?1Je?}P3Ę-lʓEAN\mXشnr] d|꩏ܾ]G "ՎH%Z%"A"&$-KÔm_QcPU\S& d ++b8v4\fԶL|e*?~y{D!z<޲MW݋t7'L.?QV bWbHkB@$rT('CWD*.vC24DάCq &I?$I$F$Ìw۲9=_^'¡Sq-܊_lfQ g pw#\u+n@~iXcR pfN9p)-}%Ael j%ZvoXs%H}j3XyIf6g k~fdVdL$sLD Oƒ9+bUw冿*uH3vlXy3NF^p6l c fw0K$ 6@]Ui,8o iIUSk lulmm_ mA˭ɇ{d(bC-96z5\٭wG[7۶9SPῐՋC#>c[jަIB$ ECQug6(qJ^Lb*'S\=uO?a|j23#"GN`jT\p=;l?W/1:bE3/ Ių{W2rυg]&ܫ$6g겒9Hmes{8]ErR6DŽ fFG yɡ]fy~ywPp[/_:tuF{ !Ce̮u@*bl F((#mm[^_VjzhTړ/3k`ݏݯt!WHN㘷*)hfS5h}V.XW&Fy'Z7\h:CrN Da0BPW*49ɂRԼNV>=|r)ȒM: 42lYZ~a5]yawno}(4Dn jco`u'7n)m3y |K1{Z vu>e|A$΋eIY*%3kcKկ+Kp3&tʍnϋ >vQQRMZ^?677cʕhjj`b,&jP kދy3`x y֡'~5ʄ:KCnp85\ei%IA m ~,xGr.OK"f͚|>P'{$lnyne_xb,Y BAeb" 6Mlc$f5zW,YSG@&/|-3V<2sNԞg7%FQJd7kWŔezD8t|>sb ,_*$xl03+f']w c T =Z7k 4c/Lϻuҷ566޷p\zJ~$I@6j6g[4UNҩG1V q~Oų/9aA twwc֭xTzj(Xj/Y*_$b,Tӆ3kq)efDP,@+Nh(e :h .ꧡ/ֱ3<._뼙q.yUmm^%<<|`Te3hv3wUo% $LL , R}& b1d2X7x#uuȤH$T3v4lܼT 7MBPԝoCH4UD/%XI1G_~Z7E?0~ooPYwL7t=K:l6m ط9.0!(m,IC:Plhii-܊3C-1HB 5o8TXxO`AcȆp RBF-r1[FY_ y5̝q%.G g8 "MHFmׂA !?{h2r_81RhؙPG90 Pl6cǎaϞ=>}: ,^1b;s!̴idO! TM-B4hTj&y!<վ( "hVRK1}nkgce@'q.s(yN"hTx3B]ç nբ#%D$+=i;^BBqh<ѣGuuuX|9> J\ǦfBrIWF3)g4U?TGFy <Y5%)I ؖ-&A5yF1CӔf t(/ P$תiu309gs8(!8LhHA֢4b]pe1;l:Ts[7O1 =J̙3ؽ{78EooDNg!pg*71nrTUjy'a;ƒ#Gf,)|sIiP %0k\KDZ?"LAi^.>O&},Ep V$D3pqxlQb}AœI&Qş_;j|tQ (ӛ1hnkE&2v)&@"` é4Cll&  eEԄV 6G& @7?hperjƚt,&HkP[]L.=zKT"]xx/>v#(|b|RJiho 5!M:Ȳ UU1:G&f/BAneXB[Q2 K/BB!=~=zp믹1U3{)kl5e2[^1 HFQSE@$yF8XT>!t$V魀\ƀ*o#j6gPhaߥfVED&,.`'ƫfzf5`YM E]LpޖCU acǎa֭cGѝ^ÃKbIiAu0-PbIn27P8^) [HꖅYdtWd,cg+yN؆UR t"gP„MwΘ8Ưi*ZQcNcёMYst-A K2\.~"۷oGOO4MҝlF[78WU0cVs}swh?$󣈄j]dY #[LXmlb0?hY81w<HAO~%f@noC:բ M@dԉRvP]] ǃ^<8y$w<`oۖ+*Yj9,1մ^%9-AC:@8TSK@ՊU^y5<z1[_m+( 8=)Xv)s1atDHVUT8ӘVID2 Hdx^Tbؽ{7?x<$=C)}-lV1&8j°BćksD^"sf5u$G @ba8CIzY]AʷL* TUy ;,Ip{<fq>| |RǶ^֜4RIJ6%Ii57kC[U^D$PVԬ2K,f̀ nM-q0{TZB/CIn%B"~OQfOMSB!CZ  cǎa˖-KW8e˖,kg'Z6[/Qӊ)d*-*#jI25NfL@](EIQ>fNpngi3(U ҥX I L??,Jw~?Μ9WN(so?1<_$zꩣ\f:B49& N @8*0}~qWKBWv̈M3T 2{ >gDSPZ,D"oߎSN1ǃP(B$![Ϡ( MElۘAƣ W{%pDM]QGqٸ ,)@1GdUP4ҹڣ"Iz}QSSJ|M=zl>AmAy'qo̧`Pdp"xKJqfZb9pf)oQ21Еf7:\~ϻBADv{pqlݺ D"Y?lǏAĨ70^c&'p D/!"v-R(4c"eսޛia8~LȉzYI DPB}}=|>z{{eK:::0{,i,0QʵY7 O#Rja  1M ~nDQ>|Om-m@XifNiޢN )$2q ) Q<0Sv(XR\j/fJ:?!:HůkvgZ||466bΝ:5ځ PLFv:[9a." bddČ1 @ѷWT.hs[ubmo*DHp~gUʌ+1<+$1B'\1 i(hYdU."{H.Qr,2(fFg%N1;ڂc z LK33+:KO>mUB-ZY?W~j/fiPUcAiQ[ݷ12CܡD:gq.ևPrHbH凐+&P2FQ̙Ev_9,"&Ҥ͊ ;J `^8L[*rwgp6S3hTd/C L _9ȺVh@b%ж9KcF48ގNHJ#NHH)k(fO Y?qOvnrG7M }`V|A50G%޷ /\h)! `<(ӨH1 p\p=#mI;{?PY'3'3D; Cp=}1%2[5%j1Co4맢> UUrfeses~zulPk挅vc4˻k6A si&-!0Xuj.BbRaĒ38J$j 052g6f)5㪂(Mf9seȥЪ3 *t쨼-ؔRjTPAp.;h!LTRS f,Bxm8=L!Fʦ±bnsU!E@/\tƬvxeESEۺz1 Fe9*ZlXBUBfN cKasZ7,@Ioq b>xf+CKi@lt: @>S.o:Z; kأn3ƥŜq>5'#+PJm'~eB)))d緩JA͂ȁx @Pkk@$I̙3ЀHM{phh===8u4*1"G""3j[p8(վaP![5>gT Rjed )mũcx1 9ᅋ}예1,߀ FKT,u\@ſr=d\pd t \jBBV^5k֠,ji29;8K`KK3=Pb(g )fz%1톢(H=eٕ*@tXIFz)C^a:34 k̋~fm5Ū"DS㽭v*2ZGd O,e],] |X`0:fں ZG-Q4j٥@Q7Ic7`MIn[g K@*1sd'\֓(Y&P5L8tBU_aRG_~J1{0P7+Ʒ{T A՜mׄhBE'T$8`~ !4w}>}:;Q=)/r.# ( HHPm#{1}>Qi]^{'-t%q Nsc:y81 z0U7Ya h'  ,XFMЈ򟚦Ygv2?ŋX3Vٷ)l7 |>ttv ۾}YǦaȤ3( ( es4Ֆfgbc~G#t LIx| gq1*OmM'o0민v[ ȸݣ Ҳ&L `nӊY4oH3*4X,VA@-eK02v|| FL9 90yK@E/Ǟ##_I'#]_mcLXy]=@K^̞>Ku %U88[Rd$K퇦iP*Eq֖q8A, ZeM̚8Z]]K|XŰdDq:2TU5I|*ezV ы|9`NR>bOYvZtww#\?a,IzB/,ː%٘B(.xd2(͖6r„rJ-`8{[^޻ W'V۵r B0A*71!I Lڜ:n eFP.Ğ5ElΟ{5ʱ}Na8Ӊb?NZpJ%YUhT(d hZ ~O5w3}}H^9qO%fUT ?澃۶\qjOY$d3eLlfwB FNLBofϞRkޙS(w;sXC"@GgSrav e8pbNw ]Pƭ;úwZܜDƈ᳅uօS!w)h '̱&O@?YfŰMDBGR}N̨:2iYz!Mw 69P$,Cq4k>:A$!sj\NlcOOL8'qw3beϕ浭pkh٤ַLdXB}9T8 _][ERjuؾy>'s۟yp3;Sġȁ4On?^H1:: Op޽xgl2Z ׯG>G&m#aitt)l6BFWȏ>(֭[p5bz?b mEV >,r ]: b |~4i N|=Gz? C'§hrdStD7|Fh*y 2SU՗,XPu# Jto\3 xP(H$zQWW~z$ I6 D"Zo7!JBe7\.c|Ihx<46NAUO<HIԭǶ^- xC'Ŏ?o 5`.y;LC, K3/] 0XB:?!h;+݌\x{F'tJ?5kUWWSLAgwҩ#ǯNRdR)nn7$IB6s}d\r7l_z^{-N:a ">W纓XU@mm(ۏ;vqC/-n"bZ缏ת5---hnnF(B UU~#aci̙Dn̼|u˥ş_u3j/.߶P;ξJ\V'w xjxý/<5 ɪ'$?Z@@7~'z^3ܥ@+W^5cƌ|CB,`|?5=B2 ," B8p!lrng*K4vBQ$Itwwc޽x饗 #4+"[>9U9:wg:N~o~YFK&[#g_U˩]wyGCU^SШj L6O0X-5Zp*>L1MZ=E8Nc_$yҥd2eg5PŽL:b[3>TMZnQm?ѱjzSӽ>`@ݏ|)T-ǴkNCrՄPVsN/}zm=翕*5g)Je6zGjm',^5Ǽ"|ئM>t\^̝'⾪ȗw<^k݆oy|!K%w7|jUSTp]y%>z= _bѥh; X$+3|@ p).,oZU !9H/̹1  PKz~-޸>w;ּBca^n}D slE@̙>7-~2oNh8NHՋ-z;@A-O E d BӁ@k񢍮.rCwm|oyxԳNC\~Hkix?Cy`_A{92N9k>i/dZo8_kDdAՋ!sFU ;vsfǜՈZZZ044;rB%3Ζ! f.sA `&KؿCBAg3ߧ,_纶Z#^;[Yz-s'>~0.$O^@P{W?ؾ埼 ?3Pʨr@(.m|ܾ#xf5K!o(p>L34$1|FWAUUs檫Ş-> @C!JӤ.oP(,EE S1,# Ggv" Z}zrz@Rхk]9 r`D1$Bw#O|Cw} :}95#80%ܘN$a鯭MpnJ71sLm?[3@&`B466"NpWamXYcEDe/%*F xsHft$ ,T? L41觜_;O*pv$KP~ά Bؾ};^uy8:*Vum5vyN]L? HӀek̹al;~} 555z鳨U VN Aq9N6fo\ @" eӓ7#h@A_`Ō_)@dHL{1Y (zFxa$0ů$VWj\VZJ& 2d ^3o?prϝw^.̩Gzw`,7/BV*j Dx% /!5Aͧ |^{%2FahD 3sqRgj{Ct|Yʓ 1j a1G Jon{g¬R{wXf/be7eAqII5c[SFjj\bTeDhkh'}*)s3:s 1e{NH\2g>Ae:x\-o+p/и89pE*,]9k FX;p#5!rT9+f K"'P*̞r&]JEŦ:qC5p >?J[@dאz n?%0MR" a߅&+>e^?{T:zWQƩD{> !?!", D&K& 0۹W:nu~ `EX}{:h ʼ~&WQBIENDB`qwinff-master/src/icons/qwinff_16x16.png000066400000000000000000000070001347323557400204220ustar00rootroot00000000000000PNG  IHDRa pHYs  ~ OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3-gAMA|Q cHRMz%u0`:o_FIDATxڤoTU{g>鵅bk5$ $c BI װ`Aƽ.t 75M_1DlBm+״̝}s >ad9 10 /=5z\Ww#mǻsqݪq#9L˔Z<:556;ٸ#x[%7O|gZ|sWx0N>::>W&Z׶ pɓ%wXݼGt#St$;Vbyeh4>MP9tmW:Z+p&++ˤiNe$J=D^C6@@5IABq p=Ƶ/^\o۬l؎QAӸi#8֚B@X@a1a(i I k0`nnRD&!۟EaHhb% wtkjmc 벰0֊Mv+t00+J?%[ۛXS24# 4]Q\Y^! r KGFr|3u'rMk-Rygn,V w86'D*ZcžW>Wjw=LB$e' tVTu lh_a̶?iʈ3q'Y2aF0nh0ncP­6 H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3-gAMA|Q cHRMz%u0`:o_FIDATxtoTrc D.NIp %ihVUD B%-/%UVR)BڪjJR6sl`;c3湜s޻XЦ/ZZ{KeGUl"?͘Rrow*ƙ.J՚ :AX(0jRL lzi/\rg[ R(7T/9KGwoyC{_%jcbKuV1sT]۟޽".i,J_[k=u,iErs6Kaf=lۺ'!_ȑ:Ú~~Mob,Jz[-=ze5lm_aε4[5H_L|o+WGm(sGg?%( s|O89"d%nݼIբՌ(+ذ? X~Iݣ{28ҳ46d380ƐYZ"e)Vnm6VLN+ ڲ}GN:I/5|FN \vR;o?Cj B>m6 0kgݮ_ t :Rk N癜>0z͚ﰦC+5OjqbDO_B+I%_Ў8kĉ!ڇi-Z(!luWutkϺ!aIvۿ\ZyO&ٳTUVspŴ\C %KbupJ*p}ӬA)իWy뭟bxx@E!>yh6 AP6,+׍cÙ3gطo|>O:l{mB@EsO;>n7: K6)'61y8(Q(Bv:I3 $TlSZq9h>yy<3IC233gS8+_/mO.uv*]&~W L,!JK,CrӓL3;{|@gZŞ=_pi=F|*EؿHvH%1gI5DzZYt~o0qX.>===J ؍[)jNS6b הNkȄB ޛ3W^ݴaxL,U 49}w#9p&Fp*)/\;u\z /gبߺ{r'wO&QRc!v! h:mE8fv\$+{sXwlc1:{ֲ*ыI$%-B@!;ҡM.a[g=kg7F:=)um 0q1GXZ[}di?\JSsec̟={IENDB`qwinff-master/src/icons/qwinff_256x256.png000066400000000000000000001707621347323557400206160ustar00rootroot00000000000000PNG  IHDR\rf pHYs  gAMA|Q cHRMz%u0`:o_FhIDATxwWu?9ҪK,7relzq `0N!~zK#  `L,cƽ*ջc{y+Y6ƫݷ͛{9913???0 ƏO@  /& Eϊ??d,~Oߑ3}-яH >Wfoo;& MVrJP:@8R\qX@%ɚ\0|l&7P#k'z'vEwى?b|Ns\sPG Rɽ,N8)aM.Jֳ޺x x"PX;j2mMi@m5 B{9LO- MJG 7܍BqS dT)S?s,\5/; )w<8~ ~g|ytjhx)#COD|jc]3[0ECm=뚑@**pUtGQyiWQ:ʡs lA\& E8~Mc;y]5 TS]S [;7(x೿xE{z64s*@N MXd5:[栳uPWJ0=a٤:EK?3@ ( 含ESC:DMf`8zNAHmֽw14oynp#[;q)SN(_څ%aќelV`4 ~2YDqQ/TZM)~9ݼ"BC`@ LGU9su ',[|; Fnܱ黸|=笾3W]|ywK8̂L5߾zdaycSooys1[Ɗ}(GQLDi<8^$) lJA_ܒJ b3_7v=Qls-h<5btb{o}8ܿ#}hkZc]]sZu/|w/JLAg<ޝ~͗1'#/YڵNl -b8b8kNR4UXooNFm{W1AlcLCMM4A۽{.cΕ ߹x8~@|ym빤N]ySk9Y6 NxqS8°y|F.)>#0GQnL9>~39j7,"U9ĭN,@|"eD 6K002{{'ڿ٠y.78(J|C_dxR8' ,Ŋkrɨ`xƊ(VsC<],.|t/HbLH/bi>l5 xY| >_R(;^BOۄ`u޼ξO8<FGvу]w \"A=a,.rvM&y(9Ag'򺐸RwTuC%L `A)q`+rߌsVo^aGX߾x9/X>(0'5.ǎF7/.CN.7[Rڗ8|8pg>SֺX|*ۂ7#]4g䲏@x t#8kP|,?a+EiQeg';ԶhTbv3 +;HRwɅl8xIB=^罪vIu3|BgVmMǺ/gyͽqhnzG'9\3Vb[(W&<` 2ySoی6%/]x$cܓ8֣ݱś"bcwwfM#JYE? @0)g,?(ۅ,Y|V/K<ĝǿի3M-#h@Z~q3qڋPאmĨxr >؏ A]m~)$!7|Gjs-NAZkAZSL8zD#ʢ>׌-k05Q/z ;O]W|P2%Mwo7^7^ ®1^"-Q]Gʂmli=CsU↔!I2,gf8fpc뉲 :ent6=f LPr"џ+1G2`̴MO(aĹ!YK4R\xq8k_&\u}x?N:gw2_\w֯>܇(%^.vG^ӝd0. s8 t\b/e:mI N'l2{m ~o>NH y(shFSdAN J}쁳Fq,ٸ ͹m_[28>?k…_W<'wl'ʪd2ʓ-%`6zܫW1+Wa_a:L)о-I ܴPc{T|۾όq$%xM^b*N'T^"b- G;vAR<=fS\[B>Sȣ?8wgx_yޟrF0gj?wnW/|J;qxhlwj-rOwk*{;¸Vbgc'OKfoG8x?4y|8Ux-wEVA3  FzcQ1'/&h2"qT)ÉX8k "ː\9rX'1Xډ/S?k~wv|[^ a_u8Y+/gv#S=P*4\Sn9DhK2#F .w0RRh[!Ps^ Ǥ"0KlnL2]Zs@Ei3"Tm:;aRHwUbK *1-)CV lJC^c;[QQ!'_9?LPw<v]9c;t_5}c<&v CN.T#1W%bw4WSZo\ ^]^OSD?B9;t@99fR`:+,Cp؜}lGnavη8`@( 1Y{ܞyRw30voO\U/߷ '^kp>ok^&*8<$J+',GIj8'Ubh&),(]WzrZS\)&u- r6 V皑0Q&G1:9^ 22>Wd]힖v4U7wy.ZXߌF46&0UDi!+(Eb8_"xdTi&/LCLDr.xͷ>P Out^" wb*bxp 3G0|tvJ~r súщ!N ax|$[0O0倁Lpz;JXO Ȩ T 2f:EsC+Z؆9 k9Yƺf47aԋb~TC9, ONXtlKUf"ӸTEɣtE'rfܙl"2VFuGw|#N>?ηEoB:;`yoD./sG7.DiMC1{<=Y<2V I+6fZ.ӊ8<zva:~UfĬv2CUm(|K6&Wu[ d07iɁL8d, 8Y]Ўm l*,"Y aЍ€QP6璅O|=X tӊr(rkʲ `lAZs"g(x2n \wp<}7_;U/[1z}IN}% xi `YbW[vXAP]#xrflߌbiS i*}`=77^襯蒹J*V/es\T;\rhk@S*PrUޮٙ!LNlPUB߀<CzMQ2QN4bMԟo_>r<h|eak1UIѐi|w'%<!xorhļqܷ[w?G݋BqӥJ' ϿY &McV越8LԢaS6nC1e?3I f$7B j]X+AںUEg kŞG00qeU09qR ) tT =3 $ l;QA{,j:KǯD|?+/FT7B7:TM  4vvn>ދ%ȲA ayz[DV]Mm6EU1!/]y]y.9UXt|QV;!JL T!NdA*loXMp-~~L?7_?py&UW-u)0QV|Dx^;LAsM'N</16zҳ7\7#x|Go|C_L\b5Ɗq (hSpJ gCH *F(Άh˭o7~o*g9'7\u5(U 0v"Ukn/߅;&˱L]lvJV}2hȷbq(M[ۿ @?~>45L;q.=`4 F˲+I.Z\EnL`F^baT14a2VFY,h9r σ9x'Nw~7t]:ڊK^ 7s][Xri̎}N9{#܆eS~gC7ctb_zw/g8p]'ՌM 謗obz&va#)uPUJ,D[Фu\'䱤4 םW?3on~ϧsWYqv HWWWb;sɟd2J9/bf$chjjBOOϩ// ;C#QbW+f 2#5𭠩XŨ6`a7Br+tt#J)gz^?',a/Zy ۔Q¶Om|w/,ϊwϿ1R9BO, N*QfG΅Y8`Tu1\;a^"sA@7V}q,J塲\؅G" $dE#!2[KGij˱㸐hYNVSBL`zhkzw}#ͿGPjƊγQiv!RNo/xKo εR#S1RڏW=VR-z|?Rttg4j%Vc>L%H#\2i@(w;JܨbFժ_pӵ>*||g\\PQQc/?o_oOx- [_ɡ]92箴w$ߕc΢I= mܹxY@߶h>?9 _wڋgU0;4J>un惓M;[GFz"2ɝ,d|TOo9ESB8VɦH9'}E'傰Ħ#Dj o7O6$$ivTg)*,]n#Q}y9a{k(0b-TIXˎtq>Q|e?p om55˰Ԕ>D]$G6b1pS,>ZDJ>?Ig6}͋٩=m<(Tcg/Xβ9c/ԓ-Mϼ2JAKQε[Ӹi'ap%ݏ')_ll3+LV"(Hoi` u_{͟r#~F}>uyA6L"rg-ž!fo.O"Ѡ Sn\] w'Jv eZ.~Ȣ~@pTc Owvݴ۷᳤͚ٗ|g(cE֛_Eg]G ̰֏ y=M d5˙oIv~;A)~I1tt]_]TٵY\dt3&[]0]s,=0e1vR[إp;hV V*\K3"ecUct3ƞJ9MJZŁ|vY~\W6\i]^vzh`W.9e܉ P'I PI^9AzI3ˆwT#~{H;N6EF4Eԥ|K;q`@oK.Cخ(m}QE}jw}Nv * ]ܱ4 Ljq2Z agzfC.?X @1ҝv6 e2@̘c}}߻tCb‹Po;^JvD`o2@]&\iq'P)݁O'=_#<@p߾SL3.ŎQ^h떒Tq- X +˻"e]/wD .MtC@2H]80$2複E4 nnA1X7>Z?@wR|wnn8m 6%aKXVA#ADWbLY`;`p O܃~ &K#_UQ ~_@=w.NatߡF59}@OͩdMtNb@ZA@RwMzP-F@FOQj]0m8RۡFY~6L̔,uFf H 7|-asQsSiZ'3W)'7/|{!?y pu}o)Қ|-gy = m˃8cK 7Q%wvoqWߕH#Rʒ0Yy{&&߫ #Ҙ}$)0T̺0f6ڪB ´{& c[=XqټDHd' \ C3 CЭF=.ʆ}pi/@]mȍ<?ڍIGU` fwxnF+Rt;(0=%de[h (AU%l{gϺƯPYٽ+#?8fn_Bȱ秛 O?2ЋԸ‚5R6nEIJ-k0C?R#@Qyb6 z'wEg#cR53hCgdMDTr, ۩J.Ȓ26kU{dN?L,ZK_tUܵsF~a('aHuxPqW ~<'1ق,n$rzߓ|Vl 2Gv'tn 8& wd^Dow洀L+r$GUH$ޞWo4ڎ;bEN>%&v' [\(/݋uƺևohڳLB7pʼnN®E8` 9L] 6H҅n5A N_D+}({! Ǣ֖]~\Arڮ*yT#6lDuDWif?'<X"f&&J!; Yb]dh47bՒSǿJcs 칧]1bJ'A==TDu5(mS@2n@^[O@J(L0kcfZOV^bɶȶ34>G: _ozf3?@{o/诰bywkcCZAvü^%F%,`g3 [~(@(owOZv:[GoN y/w)A*3g]W;*4ٚL#3ܘ䗈l3rSVUr|$ҥ(&-)iYu""EU Ԡl xMTw^埿};}Wb.Fd &mu fe =+20,?'/?_Ňu7}3#l?p[О<`(S=e{NO"bW Wc-0ZM(V{rYx)5t_O@SfgU(Mf[ef.𘌤:Hd9PYAI݀ Ā+*^da?T4+'܂H_1y=;>_݈S5z3J1L{Fo˄¥w FkE"XIgǢyKq +DUiK#Mξ}W`-=MV\(m%U.ʠ=5-)e1)lJ+ [X U^L2}lp dpsMV1p1.Tr߸q4cAҴSE:[xE^Ň.]x;;Re +܃e˖aٲU>O7rxIJl*L+nqK~g];Ltߓ?}E'cI2 N#䫪ڸyH i>ђQR-j]bz4 1}oXW{g!iXt #R*&~&mI^nl /]3!{qzGYDp%| -h6^ {7O+V… ڊr"T)i+o$^ՙ t \|2ˎp~p5xvw5G>fHvBNvǦGr8|,`}_H?8y c8ux󞇮.bbb@<|MHdY̸X w?֟t._@4>G?O>a-w!+K/n@ sqcAy-+Ԟ1mj؋̠ cˑ}=r$Ŭˬ/Ӵ~WI!dmajNO C"eT#u򽭉+[;.a Bw}ZH_kď?a8܋wJQlC2$4YV|Igrt Aiiw_2n{/6Zh" *./ ljJ)x|Uh^vh y0J@*id9 ''} &ud'NWX,^Zh\,\P*b:d^d\0uB mׂ8 ořkʳaH|7^Q'^fZ;ڛYL*}dDlvU3[y*~q75$owX5Odt^?#l ~fv~;j5Ձ'lz^(^$I΂8e_L@ dB%Ns/Y]Tސ߷pB[vJ:tIYEd 8N*UYnB^aKMM;[vٸ{/?}3wLJ;6}EK9gQ+B8]+77ƺf4Ѐ턟d9 设s@ܳX`gFMSX>MII UE5C(/_ Ōb|> n9l,XT*bNXIau≵@4e{0 -!P׼err"UϿêUd1:>CX( C@3= ӯ NPgKi,+z d7֮;7 g{3-9-{y랏C[QܴދjX%TcAPq&[zJ]OzKQf[^u+I(XikI43Jall 8Sؐz&=LY#laۚ;eKUr!mΙa}2tתb)bL y)ߤW_}ueJW׿3gb az^l\񈮣eZx [*: xIE_arXq b~48ʊ*^sʊ37{9J7iTV[k]%l4an2l;H!9&Uft9((HZ)w##d \D{:.wQ8($HXIVΪ8S: yRJYR(@b5_X9OT _PHC`=W\011qJRyY>Yg9sP.ƾP+`,b0\Bĺb\ .vC.="zM߷';fLb!9#8aΙ[}^HBpPJ^6 t yI:"E,^М#ɀ[qip`,˯Zx(ǔ7)fAYcIX;caSVPhz嗟G-[ua`0FFqAJepRBiag0 e^R}7' PuVN2欈y}L!yN¦]y>3iRp٪vؠ0\VWl\xgBlڻ gf''<A @J8bJK@ahf m|]_l+WK薜R!JEB>w$ 병+g"3R-*iBDi5Gz@۠X.t sR?Ec|MEZ,v29gԛn|ώB;QNU"4UE%PG)K-V,qa\k0=\O!ZZZ/|V2&b@Alӭ5W80B{ 6m’%K. /^v-Rƞ={b;q߉9,|S_)CIע& T*T*Gn f)َR\'b}?80oKA]wBlN GB9y 3R߉q<~4շFx`"ҒrvvI/ H21kՅ|MbhD%i a!ݒঢ_ـRrgɉ2dW^Q4ui5mau!Ws$D [&Ki $'C,${(H8Y@,j; w>xJ{ޭ~nGB(Ĕ%:ɶҭ=\mABX?V)v`bOv\LOf|l29-ak Eeƚ5Xzvatt=( y=ŦTyK;^cPT̨!*r34 V5kYW9ؚJ쐳~/ #_OXd5<?03\sw!]fzj:+.U&1.A$V R|?=3@82#e1R&cVf"0̡]8FF188kK.119(CG^lP[uWr=&ǩ{dǯ]ܵ-sDߐh't}> I]rF찃2t\ǒS_+@MT%J][vA4?6.ytCyڠ"/9±RCbE]]:,~q]?ET*3ݵ%O#)iS 5n7gGTH:VJ%}`i`z(][K[D;9o?"Ja#>XO}OpOzJ呉3N^q*&?R.цv 4u`dtO}L7{v\j{+Vc CBl Ie4UC1?wUg1G1aXz516:>l+O)MK™e+,bɧ =T, Q)閦K b1\Q6lK味E8 GDp FRXDl+CU9ge?`8!Dq2 %y»@ ŎЄG緜7R?@c8`T/UN y<3[kfbQpun(Oq*Ictd}}}?>&'&1:6!T, RL_o-Gz+v 8Eg;Y܎fY_g 9) $u`F,HgKC)pM*b$*he.Znj7k1Sŋ_[J&~&~o>d갠y%gij{#8AӬG=lv 'ء뚒"Y($ Gq跸9QU/ R4vӕ.SfDWWhj}(shy('o3Iırsb  5(:L`(vQozG*~4v"AIMY)@ES_ SM͵:(N8Wo^J6nxlotO&cvE}]&Km/~o% I/@ (*͵߳wmSAf,/[-O*SA/xfsFWՂw^̝;gu^# 022%#iK+ шk@xLMb>@bKF؃$̅04RFBFRA9%.4նc`\$mB&<>۷ÓO>s9\.ɉIcjj #!iH;.ZosJZpD~H n݅XRNRqGzSth NvWO(aa}m}'OvM"sk=o#WB ?^@ L;gd,>a2 @qMM0Rvc9gdLDZgjPiBw~d̶tđ0wBx I=4dL"X4}#oX8ycߺu+>񏣩 VYg 6`rbCCC(&m覷/PdZKU``48 %avm#j)8"a콰Sϰ8\+hQQ$׊2 (P(TB=lG/PU7.ţO Sw,dorWJI5 ŶD.+"ÌNۇ}{0I&Zt̼T{Rɞ|7O&͟ayZ=Fzڵ ۶mÍ7ވSN9oy[`accؿ?岻=2a$cqP̞SB 0&D<1Vq*+YոD02~4'U({z=no?VN!rmYGrو ÄCX:X vQ3Yu.=,e"E׽K=Rp⬚_ ڦB[<§ͥ#)MR4"r"b0L"xؽtT ozӛb xxއ B\F/6I ^ vUrZ\:XT V *vG PKN)$4zc,wٟ,ZÉ?9Reaˡ}p-]ȎIEHIaɚ2w#zMvH'vFkq64b霁&@NgDPmpg]`cGsce7hb6yl_X6U=3L7 hՖgtfDGG @T2zãwUvq ^c,f??[ ~-TM*8#&Q[Ij'|zafzOSif!b,gΩ*ִ߳8Ifiy2Tn'>`U+ mqZ0468ؿceg\dʓ*C!$ K00C7GB٠uszZn;-MGJL m43t,A-`yz,vrEs(P0 d066~T*egGw}j0(?nfNҚldy!Db6AkjΝB*:6&!0$)I5LC]?H. j cxь:dAa709#gkk@KK Ν fƖ-[p]wСC7]uU/5 hi=pQ_ӄ)+ B)HKCRx$tXF&0,ad-s`X܉҈B2ЈIY+cJmdMPBgt$bC?^lSɄѴAਅ:e!HnH*1)-P)QoT@R>e' * Q6j>>%S L@"X\.9qGAL !Z Dsy477 سgnfm W~l 6@ĵjk=a4[14khiz̈́\F2rT͆}{qiLp09?d6WҸci e'$ G|pTH FsM;V/QaL۰@lǞcЅziN`w-mkӕ( >,1kQ౪u}\J1,}ߣ.[ŘE~u)S455a߾}qA +eT4f).X|?L[ èf'lxsW| ,\|EnXx*&5,Mn9xa0Gwxg2y&wbZaf(>!JpQі+ǎ6s\o )nS$Yj"rTɑds0 Vnܸq1TrSۏ'؍\N PBu,{Ha8]ˑY@!1GL5uE'ՈzI]\ zS|+z#2fOHp ;%u5,ٗ9sX|<*`NȖɲew&-߸TgTrY 6 TcD?]t1r9457l;ww܁C)ؿq-%HOKh'PG&E9Xri9QLƋ?$Q/Q$Z;P߈Bix淟{dPQ%@N _e N@g[2HC>S !T,y}x6 E75YZXv=b{GN9c)Ok;&HnLwi_BC󵩳[, !+-knR@:К0 左\<lִ}vu8t6 }.6n%ti䕲E4!B.?0҇2u(PY$hՍ3w)t +d3Y &84lJ"lM귟DJt䜼.G\0Y}i?TOCB_mE$|dexp-pDcJGJ)" 쁀r9~s!\wP@ݸdQb6 l6zcccxObtt_2̏g[6ndJzVt]!Td {`FEf1ƃ&\F2w)G"8ϖM Bvy"FEPˣ C=@-sP 'aPUK9ߑjF%d12r !:VKnr9 Idt9]dr};`w@ArlU~!7-~)E#;~p# @mm-Ҍ)<ؼy3@Dr7nN4Ѵ hS.Q:;}Cs?|9G!P'7y%{N`T՝R射:c'W70,b3T>s)&F 0F(Tk ϰ͚ =]+8 '[%~G=#y2UUY=YCtנP*Tg>[p5OYh"dvbR}=sY"BMM ڊJ;v[oŞ={o?y7ݭ]H6i{w;@UL'Q("Jj >e[CNoC*T L r Ja6>mr1%l4j\袾 Gw)ϴXG-@:x|RtڹGsa#!K@;5#P.v5oAMՍz;GbSԩMeǁ]91(]\uuuhmiAMm-v܉[oU["ܼbŊ?,WĖl$_m-ʴt $"m ߪJyǪe()>&IWU>a 9VZ~.&5uỖ rt]L01rƍUg=BY^1dK7CW':Y"ݑBUɅ[ȔHH)r䣅 T|]xA2\6&f/H;\rff[D(Ӏ :-Q2Jpe~4>Wfwg4VXar]lbN !\/(i&$|M ގBm۶a۶mصk֯_.o!ax+RG"@cFSͽ(Ti 7V/\Hј$9 ̆(t}I.da 1"s%~~0.׈>{43# ugA7b9HBGH>A`:#-Ex1\mO3u]xhlrvލ_ػw/jjfsXd /_:HiS?d)iZKB=[q+E} ( = 0 ܁9OH8viMI,~dl"2D,Hh_92ɘ|!atbQw5͂p?䴊m&b@P~v RI0HZk_Yyz3 v.hRJ,Oe2Yס-&ڵ <v܉rY$*v^L(<7w+rgN y|ie!d 2fI߶dƲQ8| {nEv@>+H>D,)񝀒dm\2G$kE kjJ(>~ tdǚ` ڟRu[b YWuݚ4҂fLNNƣ> V|M5551/K[v1_.$͝4q_ Q!(Hя`e3A֪ޙV&SV:H;jºPeuaӧo\UC܀L.+TbbҋG67S; f*P:ꝝ dz>t^ٳB{91?_S&RhllDccc)DRH*T ^3-cih]K?8$۠n2TL: 9U"ɾ3Jrb6elMCغ0QD%v wًdރ/hƅ^pgM$lzʻ!D3G^4|??jM;9XC/1(+a&F \>f!a޽۱~477#ˡk <},6TO`E~N S"Q#ˎSЈf,ژY VNuY&i']i!ytYHH:z.B NI{͓J3rC$`>RcIB<*y@3iTmJ%sC2+롔G|bq?]6C}}[؄ccL!"44c #t,Sdvc9R+T\F\s˒l+[UlUm(^ ojRm7D6=sc3GIHl$u5*IZuuؿo?nf۷ό677'ȰlZM9׊g@fGq~1ͰkMz9{~vKɴxM Q?p:KRf=yvx TPRl=wQ|T+[E\A3J7Q@bӄՒk ;w-uZZZw^le#zzz099e˖aɒ%^Iqv+ :s*瑓gL4#꘏Be!(g2Jd:T-PЉٖ9LU@|H#e< u!iK-F! q45@{ ȷN̴4HI.B]ǾoІp}!nmdԇ3TcYKGUʈ2C!fsC{\ONNbx'~z\}7 /=cơF9or)eKI3hDŽjƧ' HgS:ipLƠˬqfph;d)'#0ƀ_ v  Wب44 d + h؝&gaZ.\TO^]H#njt7oz-vg2477c޼yG}[lկFkk+|\ÌGPR(4 ptegEy@ X`0*=,^׊MPTnx:32&5CScXV7 ^(u(qJUTI(uOȯ4<(@6ʹ EpE6vHXL%Y(ZoƁpUW/9ZZZt81Sq-XX{q5=V\>2WrrF5*v^ %۫~[e'@;o5`l T׶kKED`k¶=RF0[ZЗ@&IfJ\,S,Y2FBV([v C9zLiAdtSq #h`jj K.Ż.rrEw?HDpG=4@f]_IAe NhaP}Gbw v: F@'jYL2ANpշcȹ0&ׂ hJzqJZ[^ =gDkT$\\ĐL;5m=WSݎj7c<0 .,M.ONUPwߢM$y&z@ cUQX 40>5i/RxbVALGi~%@dX)\="T@ŘKa%b"8B]´O83荨jIqOpOUPTU"Gk*8˴>>Pk׮ 2cTJlK/Y:M{NfrUlJ&+_usfDHyg3ki&E}IolV`Y)۶!CY\v0!j+_DإMnn<ƶFX:d*DGpbwp2Nޮ,9| .mvlBGH>P(;ĭ:m&2|p@z7\* B+ $xzƨp?WQLtIJ"@c}&GLƥ!] N7zg\& q{/l2PT 7MgW;a fHXaJhoy⚋߷wzQwU-`[wbddcccXnsE/:3`nH֩r2lfLLcǎ SN^ff \.;-6#{b"f~;%.s00$4MWΎ0 ͍,Ew)qRp !ljjgmX겋u _cڛJ" ej"`cҨduI֕$ XOf*kPۄѡ̽vY  rnm)O G}*N}=Ys1EP}b8C;]w +p^8LC pvY$%CUZe3r._)ҚؕXrG[C]#ju( )dlϤ鍻Yi|S(0 @s[*eL'QkKN~ǜiYKr!bwB) KJq8e!)EsֳNu . X P)w{@0 SN(g0'K 0JqU4]AюzIQ2p`bqvT#Je?qd2f #c0d¶P K5P;N޺?ɵPo  `Gvpja ^>!Jnp}#}h`z&n+>%ɡ1F2J-ps!!qNG:Z H :|8puc#,Y=33FGgxz)su3Gib +@ym5ATMk0>K uV .K;Z`hJU{Jl)_`)%d v&KW~7<п=vXD>S ,`vUK'ob\Z0p30у]K@DQ(eQXAXI%W %;wt`ݺuXxSj!3cxx=Z81Յ?Ϧ޽{_aDc;4F%W&r0x$Hxnaxfާ/ }]W>BؿYkxbBx}}PJ}@h@Ī/#CYgꐡE锳%}e'GOǒֵ Q-!*C6k<`#Eب:#>sggF&R1`’y(n/*PWWN8\ \9&'Qx9#^IT=&32d|fE>>t;"3S!U&csTӊvId884:9TJi` \YA@L !ȑN".KJO'O e^ZqOW),iB#3 86L6*Ee˖!G;G=ئRc;2th ѼH򭳱>4ƻd._PJ7i'5L ۺlT|CJ)A6E>SlŚpaYe)=(`"lI| +~Gl_ze+Mh-s޼yrIyV :iSF{O455aٲe%  zxĶpJiTb!, Exzd\<zPt-q9 ؄S@t?v72fhDa0FLJQk<*UA2F , Tvk1*걓 85nrXDm_f^c4}+J MʽU>)eR0vNkM{UG7BzD0eV]'BϵVTbJN]#/:,ړ(K0齧d26ۓ"Yվ~#:$CI;N 9SNYj8$~)9Qo0F@";G\澠sp !Qa4R&C(U P\1)ual!dlA7z#uU6St<7 eJ,Ht0N~*.ҴPNL>9\)q Ob-EC_C)e):^}4kKSn;Wc(Nr#uK/G.\$v`6^lXtb}u\߉~O` -M{q٫*Be~0UE9HLb&wE'"ɼ>wak:""r٩2J[8 o/'[m%Z@;ʝw+3 ^?aG+e'9 d2Q)mJ+?AUbIQyQkoYt 1kIL@yJkZ~ סq>X p`>t5/8𐨰6dZO2qLF0^Di$BU6md?:[bɼ8<{mڦZN?7N p˛]J*v+c3vA)wANQncI:(# 6 g\c~(gŸop23C-t-m]sZD/@\nb3M:1Âglc @< $%-8wL@7fv `rj&`қj CeR(s KC/`4"Cډ5OKR!jɺ3e&!mh69<S-LSaJ%RDCaaX ~ N̳x}q]vQhgV ޹`),{b " LN-9{DJPSXyuD,/gls@eȝ1\# щa r8Ōks&b-$TA!Te,c4=cP[S{?y|LQ+!TN U#P 4P-W*+2; CeHtʮB*i|4tfT7'q e ,C[2Sbɟs6JHꙍ*7_5Mچ`KNT%4'92md|'PAn F'j S }NZ"SIBHy} R*c: 18ً  wPx LM \+8(-L p4`~wIt6Նַf{LͬL NQ}~XҊ"S^\%r^R\6[arV^FqQձF"M_;83[NzrȑtDz7dRidFflV[>p\e`N{=i΍ƙ*-9Mjs h{=ýF[}}R8XYSrxQ4 14~-Xp%5 Mm޸X[U27< ;iUvGM,"N'C׉pd{mLafRIe_fzW~L?WyB^eg/2]dI ^.@>p46$riTءhqT.1 uqĝ^~.?U5A`7``ǧ ũl۳ ږY΍/V@B BuAt2s%J܅3֜/e,[\)^ԏN9A6;RZi4Z"gX;b7B"S?"N֛D4BgfM'Kr)Re2567&$4NU *g;ׂ3Svr+lMt{F\)Ej(y*,Yd$~O^k<؎m+m(>`,ѝrܿv|+M'y  lt EFIz9A+`W\vu ƏO q1C䁘Bk ԝ®v?Ϭ>h=sBc6`l(U aGMZ:b/s4z͖ nJz`\r3'7>nt ݹqƲ дY~ NIhK! ZMB1 LGw#2X6$؏Tzlxo}}p;Zj碾 '-:Rœ>QXE3#} ԕgGnp(?Xk1 ~ti2Dt7i;Io H5e3F2ծDx$aFכ~ ^[|_{4; C|c *VH8ٰaC`-/oiiACC04ӁA`ddذa<n6n8RTqMJtֿ3 Bx.I|Z뺪e;zc]Ӵ;/E+Â1b8])-f@"Q(ګ 69دzW?ʌ;Y膳&҃O>XӄT`IdH{^th{Rƕ>93`㷪 <8DšPJ^L\$ Jk w%.8l__-nsj3TydKaI^@"px|i/8:]tmP**fU 1_3BM'/XeNCNwMIGh/ݰ薮.qXz5`ll 8t )HNya8Q.qwx۶mߪ+NƝ`9E*qlɥiGY$",s2ضԑdp]> _݌B-H%H?W@!'Jxx`ׁW2Ę B/fXCpB/-7Gg$p 9%41)ïȕb'u x wF N/LaÆKO>duYh݋IRJ%DPȈmjj矏k^U(LRH,MY{QIIHW`Kg[n_VW = qlYQO0nAJb*"ҒQ`0Wa\zʵ?Տj+iDDGb~,:6]$'5tqE`gasF̙{1jV 3gPIp&AF.V`q"U I!$ G"6lX/V^.|}}x'P,g>/*JI P159RXa#%dpcrp(i7ƲD;q>uCjWƏOMu0L:1f-{$%0.Q0!&e%98ދA{`!F% Q \ Zi(L'"S=ک*f#*Eq`Rf;uUbLrN;6%8prk]y}if5;cC^0%J%۰ҷ544+ ضmz{Qvh@c ,r^d?$2b!\.DC.8)o8:> t_lt6wOT.~ 'wo A>Wc>f _Y:l"x\a{9_Q@} Z1UoQJQm4^Y8ӕvK ٵCoj 8KLvl'$tQnNذ.;sFE"[Vb ԾH˂!bXfnؼe=p߮۰g6/,fѦĀ.)`oPCj/PR=KR䲹]{j}.;"w e /Oߍ-:-:B}#UbwS쁔`}.3B\ vsRW$LH&n Eg'xJq09; :8 'rje>M[NёSDPNIT*CXD\1_,199Um' uO' sFbe׽lL@F[?Q(aw?+YxOrOX,B C9?ͭ8Ϳ$ W4@C&pxDɢ FHY(YB.^j+T F j.FdL d4a32+fG4ϲL3RD**s,I"dgLB~mke\yEOOj?0qHrآGӌWu-XԶ Ofa6l=Է[w>'\1#i@S)Lʾ( rH `.yK/PH#!:*aTatf< >)|]Y)+\bWŒ2v uVLߕC/N ҥ x@256{Q8!.r9twwR =SY\U+m@GBvƦLLLDMKYaزS'qXl)# sOPz(03·o+.Fm9@ib#։go01%TYƒv{9u.kYQ*ii8#J'!;Q3RŻf(EF,XJbT*A;ڢU(qIc>t_Ef0(Q0Xy ( fYw =fBڜRlf D,|(mz$:9ADrrk \"3{+2 rJS Iv\|ؿ?RVZ xLG&9AGO; I]"$W*!RpW{Pge$m7{D[?Q(V*Xfrrfj#fL05@9QPS:15\|>8u*i7%A?m߹:]J`+].*ыU%H٧}U=B1~~%h F˻垙`-ء,I:JL Z20#ଳB\HzZbN " rQ  2*LEAo/@\Ӣ5] d֯ZM8frXBoP uߺӝhvi=DNR?@;/`F `+n/~vlȽԂ֟{CGo4sBJ;<'[OihL%ϘM ~T+l1U<> D"$Ԁu`}Ϩ*fX~=:JXIQ)VǙ,~AɩɈOu @ ^p0@>GXDFd#;oZH{5NYxd YNhjH6\ " @q@! @\0w.H-\9m LMsaes;擊rʪFA)\Y$ +ЌJP(8QIUaE`bxRP l~:BD;-0pS] LMME{Q$ 1U7FhwMm jjj088\sɈfJx\[Q;&=݁ytV= 쁙oӀ )m(DLf2fF9,1B=JdRȦ p00Ie8C>;fV&A@Cd#kSM=]58ރv#-=: ݞڟiwܼ5"m@"'5rx4jrZr0P$JڿdPRXsgwdphhhhjQ?BzN2=YR!&㚝) ȸĠLB& d2tvvBb #Deէe.H/m|ʢMw`Ͼ9N_x>ZD'$F) =AEEXIV;`" MŠy+`1> W6TQ@ʶX kb/n)嵺 rzcN8JWY \M4TbQFiY-6-tT倡(C`Earrb1s+V " 3, ~`Ͼ1@&5p!h4 #Iam:@Bbth0G1&NaPY10R48MǒT9T]Y.|*WC!. S)}̀q/!Z]YZjܱJ+m4m)bd9tuuallj c J&0\B~rɩId#zgx&֟,L@atvvbppeݜhwWF5͔$8 .9g(Ž{3qOqڢ硥` .!G ! -Tc]z7Q85=축q0oexfy[2 M(69+ۅK'=,]seӒNv@,c^bver8RnGQWWV =IOGhY8+V_@ Zu}FvL dbٲؼy3W9} ov; Dvl6(l:wsw4?͏s-.2s4R:(hEA&FLi#6uLI{x/eEJab,{R$<Tu^vq<=Ş& !k3сdpMڙ*!EipbO?Xp!ϟYZLqJz/=ҒVF`Up' %A6ai6Eݻׯ*al dfG)%@f{]N eؿ\eX⮂wŚԜ0w\!%XfOAqfFr;cqljJ-~F̱X$|#{~O?ơ=,U8$j/\#ed2)v~}ּsi!n<8U=z^<g(6 att{ݻw^p Xp!}رc6l؀+VדYT>"_G5:aJ,4C&%N݋?uAcxGWatͮ(xS 󊶯#.Q BMm-N*㯠P/c@6-~k/I c{~0(V .AS Xn{{;>lWHS)T!pgVŎ;0w8tDU iS>+3{B]]-V\aOu)? iқ7; Z/}ix]W:4,y%(;Ď'2̃ |몢]PMQ UaJęClǓ<[m _]]]8pFGGaF|3FFFڊD"ռ~Ad bqR,lZիWԩSc.WYc:F:(rW0So2ٳ{/166fٚܲ԰l Q1PQQ/ǎ۱SCϐU(#vE?#fu?m׾w4F Oע\v$|nۿxer[m-[<^WWԽދFtɓHS"A] Ǩm8q08())qguFy饗S^UOLv7>hB>}tNo@$s"rϾqNzfۖ"̛7 /-<9k%هe` W)ȩLti-"+vd>ͅ"~x</?ݏʒZFc0[-2bDPMxp5E Ĉ F,1ݧH?̪+Ŧ?7 }ҥu>/|8yH&22 Al+ g0C_K)((1fk(..%KP62,Ԃzm*6@8F]]=ى(׎u/Qe , `1ܴA?#?lkoSq8w1[6g&;ynH媑ҒW.YHio> Y$.2_Hۆ9={vN#h_Ջ6[kWحEt~zo?[n]vZtvv`phT:k[Yp du83-(--E(±c13x)YOO`EE;khh@CC<I{v;H`V,455!Jᥗ^B{XpGf%M|K &$'JWf^}sP.ͫGc7oğenݑfAkz&1(0첵֙SOn\u#XH``[USLpxsCs/`@֖K8 18"ѳ7W}NUdbc6mHSSwqQ2 PeEE G|;Li=;000H$uց1d2@zљ6 |^PŨ NoeT^Ӊq`XODZy.Ӂ3WcVd?"6zc=cٙW5K{n{kyn  OuV)v\aLYe0z=$.v{'o,]<T;ӦM-]'18<ޘ 6gBy-v9A# EcQoVFii)0=z̀ϑ.g(Hmkk{ƲxggzXeee,ugN @H˲GPVVٳgcexqt`JjC1ˈj `3彘Vc);oB߅|&} wA`r!@{#U+G ,oڲV_8$ffd[Oj1%0O.Y 30#pK+ YjU.:Fq'0<ѷZU)lvhI`6qۆ ^d?Od2m~6Tpd ~ L"#LuwP(BaxY0bK>Aho:~'޾q455 5QYY eeeĬY0n6̙zٳرcKv쪳]=p<0 |E%Y@ LnxW X|3?nݺ[.\{ wap[g`†lƅC3() ƶmb1$ 2vpeD"hiii |z\l`ǟ:t̙:u }}}X2Ѯg}}}8y---طovލ(^quPCW0yݑH]] ܌\Ae0 Ya]x!~]J|d ]ؾ֮{#c$6mѦ<%Ӣݥc2a(hPDrm}-;P#G?Z<}",Z_=0ENq{R fDtJR(***ixf|c<<<;wɶoGџ :vNDw%thqǜ#(D _ x0uQ])iR!b|JX W/$|@.?(@ km:8wӣ~{ P;<#lCoLOuy¢2ۦrfc8Uw#CtUV=, ==QLDtµ_PRYVw6lxo|r4?Ƌjc4շ-ԏqb1ضcLc C-YM9B0Ӌ?߿!qkVyko^'N¡%L4*p ݇ԗkPۻN ܾQu獿o˦G'I-*vBԗW.\5s; I=*H0),(:t?m4N-Eh;14/FwăɡsGsZr?F Y@;n/a.~Y?4.v*W}lx}wy\>]<~qݺZs.Iyי0D̋%Lh(Qts##5U+{4-  `gK?#N9,ۧ *Lcg;aYD)'^nyu6'.&M ӿYyP9YZ3Bw7g\dq_ya.hr}G71gzk~WmQouiZwy絜s]~R@}6Ia) yIaЁ!f͚>c }-ewe/}'>=`',4/7| I]W T2 ϻf?<غ#y- 2 uT\AFOsVۜ=}}[D7Z%H-њ{Uj3B3t1Y29Bz'b,2Ɛr=3,fԮ-oJ 1u:+:Lj\X<tkQadDAsU\JCa>|x_ggKP_}tdotKo8'!V3MUNs|). 8uAN5dr'J-Cf1,gp?nn_&"vM@DߖhkA49nhR;Q{0>^FX}5&I׀1yAZqlwM!mE7xO1|o-؉I_MWJޮ?c>8m# #ضcǎwٽpv 7o Q0OFv>]d/ LÀx͑^(sP+p1Ԕu_³}yLDT`-jgPCwYʉ]}GvadA)qBE^Ry-?fv icSzG1mD«n/l+[á+V{FWWⱸ'b.~E,&~{]*;d 2 }\q9>}Kn /_q{6\ظf3v'{#1w=phIɄLlKv@K0#Yx/ׯoV9T ,5 ?+)ƕ7c$Rv,^}Agse:S3$$<HO bN]K n1!?ҥKW]Ftuul?? })W@q1_gSQo0.\C̙3?3ˮ欼3u]O,ßB>i{>&U3˲j4*2,UϑI_0CzLk V5{?N<*Mrif!=<"ßY4o,X6vne>eUR612aX<eJhRQi a1 iP:[`N#n_0*Jv/2b|;.9,+[FAH)6.LzsGާ{le)L݁j|LUA, Ja툤+Fyb;zal.<@pV6?}d;-UU=uT_  %{gŵ *Wb5,CMt 21xjj\M? Z@KbiT20F  Xg>[@A̙3عs~"y^eB"^7˾m]۞@YU}{?xb$ LQcR] 1P5a&oo7lEz O/䶋\ɩ|ʁ4j6:py&ҏݿcNvGI6m`ܕd`)j(k1ӯ"7ܸr R]!Ld 8-J\YBߥV"Hy0tptL9R444_DWW׋_xUֲuw.o ĩ`)|xp=ʲ Acr)+0Y iL\B+YB8>kf!w VΞLۜKެHLrIצΧT`{K.y;?= Y8޽i; Ηӭ$2+/e٠uc7z 6#P,x۞eYF @)崟BM(3U0ώ(߆IiB!444ĉhkk,ČHjTͫ -Ƶ҆5?~EX=: èH |g~ˌ"^G}mz\u߂yM@A$"#깲/jk?;w~W?+()ġwOM&!ŸiG1b8RCAI PDH,8~/ #òBH!;m{^R^.jZd̜LX$X` eeeW=zڪz̮ ]8wT2`_"̔|2çXw(\c}A`*zIZ- ȚyBs1 ՗7S籶7_5 oOMd-|L>+5)C``2F#&ҔL$!8(8ՅP(Hщ ҷwxPf;/Hk$kgI5c @ҝG[xشWZZ&瑑 \⯓o qS;Šrac#9+^>'cy9n)UazV+TV䲃g_ 8}&^5r]ʊoᡯ*NcO+HJ 0m~x&xP}˞CR0ׁ%c FN,˕1c⮱eYj443TG H/{}o׮]ȖqzуD"og\brz5v|0ډd:=ɅK \{sHp>=t (8(@ђکXlz{{]\6!nw?s l`2Brرc;wif=8]t?~To.)y,O9İW~Wöa4>jzki6OLd jd>̓/ rOg@O<`xhH`% Go O:F"455>[{D7fƟݲ <1sq1ht}cAqgtf;3kx$/C,ƹ7Ih:gaExm5?~޾ہbp[& " 2dJEK)f:r\ל]8D y8|0R锋z YY!R RPMMصklKߥ&"b&w `tbdR)8GsaɛOO0tYL*JwG? ?EP98" p{66xƤ!=y'Rpr $J(WͷEX,ҝC\{O$<3eZ;"VL<߅+d'4O`PgƬ־]v c` )'.&P(ϽZ^E⊋Ȕ?2*p5Qo|68J8"{nz HL)pb=7G-Buu5pX8]֥ 9e,a,91͑SZ^Wf>*f#rkj+EX⩨,ȉvRR5r`oʒI"kP.zF.Jvh6l@<w<GM1.==--(3 :߯;[VeeeX`b~_}>Y!oYz= 3"y-En%{]HA ̙[p)eiB;A\Y ^LpG`^L}&f"SԠ7(vwkאqFPFf*^LQ0-jpT ^@S2b-n`9ID>vRoًXzl]G҉b<>Znzgྱ_aޮ&k-F&ů؃D 6hF}T:Lcn Y1&]>a8RUrq= $cLz@f=}|D3ZFX @`&SJ4g@F!x {z~7gieyrL..˪{}y qU[18эx2 n/Sb*! ]F#C\PfJgq,P1~$I466jjPVZ"D PXXB娪ٳ1{l!:1Cm0nX嵖pd||#\F-ߙ/H0*Q2?DZK ՋT[8wd>74}vA~Hz.BzKOZRzBfBX`BUϟc)19 SCHo mt{Xa.M٣\C[ gΝz DžV)3݁X"+mE.O*ֵq8+,W09 ;i uuuCMM |m#J dƂ-m^05 m>9o2xRHJ*\.]93p&,. Fk sJ xrB0.<?@ +.Sia A !cp`ÝwgCR[#Ӱuͭvae*.SQ2/%n`2p!<ץsU}Q=Ajlw۝G'zsM6w-iy`ahO0Iw`U$āe!7\z./9Yawؓ3Gڰ~%>HE1Yhoճ&eɛPBi;C!gs0!RQXBBB#!"}|rF/_g\#?k'%qH#Z1"_y A„W[)oIPqP v,Zcza.CG{fkJF'OɠLqhO cfZpGzt5YD\~gdώ q} Gw|/2[iS݀RCnYCCDt iAS2t1pN1  >d:̓4&*+疙1Ҥ*SF r򌎀 u~NaTq_ V@d 0D"aZ"Fh jѻwfyh 9zE1&I\MU3X,.Tr f,@iczs@%*|Ca<1fx zB̖ DS P/fXw#BQMdd-l"NP]#ԅ7o9 ϥ2yz7EODV}8)p*\יbz5k&8Φ@M}B21a=ٿ#3"CǚpDq.g豧CeHE\ZzOƦg9B?`s}5 VUc<9Djܵ,rsңb1o &qg&Go[М iphcG^ D?jS|m>ٳil}6."EH&l "C%)!ǒ8TQ Sǘ*9 AvxbԔmK,_ @{fT$60U4d 1, .DzE>{W*2@nڂUMK+|@_,}O{.o?̪3pq6 5)5H;zJ7M0"s`{G, B>Ifs,c}b*A<Ƽ;cNH{N(%*Ɵ \NZIbP׃DX`_ob0A`L6]>s!S.4ovcTE)J|~]D3Ab\Jh9s~_7ODa3_v5bq$S1/GeCޮԄ&ޡ%w]FrI1Ej3Θ;Q\d\/}Vbj~>LM6Oʙ$Hޥh+YM*bZ~ex(#^ӏA y0F5aM2@ES k\?=|٩T$d eoFERb`:Y@>dtalX$'~MSI.p-8J(*8 f)*7ds%,6$Кrep4V# 70e Q S[Ku DlD$L`$}oy+qeuXPi;W-DIsuSpNa"|=nT,Q6H9'IxתvL-Og&L@x5'{ 5+iJfa꼙`T)-0 ;Z*&H6BQ~wS^E&GwQg"Ny;W@m8f dD 0 [P. E޹71}Ɏ='_(WbܫjfXVi;";$d5%0hZD\I])rORKO9z~ڏItՇaot3J#+j0M23.)A9rD3Gqɋ#b_6ZnF{,,p0QlDPZrW|fg#Escjnx#l}w}weɟ/؉cwUՔ?4w ֭؂5KGqq1h;FHI=4` #14'7w` Xkf &1,-531\/0qR[H `02˪mRXIF 7-<W;mL:E][p;&^G; 0*MY;H__x]iIM *RRwZ' "ncY؃+.2L=>&CNp~w^~{?\S'.F«ppDxFc}&O2CAi 7%4b燌Y7 Փ•fBƙ9ubp5flHb9)^4ffm-w$eLZcrȰbBa B&e(l/C<'O x]gaP"L3D|z9-l%+jȧ =G;\wK|{SEk++zD ;HM"*Qqɕʞ7aˆ3XB+IzmEka PT+! agh9\(dL Bn]Z\ .tSzҦcwyׁahIyY2x%b1hY"Wr RE=HRɅ mjc'_{ &&&`9 -rH:OuU(WXq WfUƼhZ⊹kPXPhc#CN@dIZd9/׽>d~S&9l[Sאk{"=RpwTsQe{Ĵ<""ɞ ^b-O$DL+[ ?ؘ .0UAMw;Sq|# [nBmGS"lyYy}0v6zfWe()*C$A‰"E<5D:d:xjH!eLa;iEQ;!N(_^p𧟜2ZY9-3A}@Xؒ:Zh]ja!7VBAH-(LCϡ@ZY3()bbtݯɖ5 lV)pՠA,褘 j)љs-\\re|Hف^WZhTmy֣%e(-@a棢(.,AIQ96:SK x/2Oq ] thzѤYHFdIHe@B#x9(94*Q>Y8D1tܬ_G~^0vⲹkpxD& "`34@ϝqߞhQ{@aZ}sn*\J ˏ7YaԖUe  C cYjWTUn83"￙4rI,-e}jMJi zwIq€cqBGW+v 3xz1B YXdJ1`'f5 )+f ɗzM?R>O/h$fBl{*>T;7r=Wp1E1ʾ= 911G% _".r`z|+f}NyoZE7HyIENDB`qwinff-master/src/icons/qwinff_32x32.png000066400000000000000000000123051347323557400204220ustar00rootroot00000000000000PNG  IHDR szz pHYs  ~ OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3-gAMA|Q cHRMz%u0`:o_F IDATxڜiluޙ=R(.Z)$r`Uvƍ%gd+Ć8( /-?.(`ņ##^8e%B9Z(GRG>>>}ޛp4u: f9?犯CFo0Fs *{;-cƖ>|h8:\hymS:kN)MV"7T{3o90 wxuK)Ç۽g>Ͷ;hMpX I ESv7z7jU&'_o9_gfTmᙫꧢByIv PEbܳOή^dk``n!w)X@)I 9e>.ƞ>=UW"dhhs251Mb_6Hpv;zg;z7sd &JC 1c'$c-d[y]K*LOOSTRkܹuҙCI{+\6?~َիyaae\|2*sF<ήvr#Ld&(hc&1P-__8`Ш]QR}FXi}Oj_;_YK"cehOtYIR!r짗(W*CJI"@kM%/F>`lbCkr@Ml߳fev'G/%8 -:Zcǎq\pL$HӤR)5d9._KA)=8BS[3wmn%T95cBӈj܁b'Ob}Dk,$׮]Vlհ$ͣP@ 73w3ߨJ/K)J5+X\9< @L&s gw~dG}oۿ ٷ+H+$AXZ<{nB 9=zpc2" SLNyZkf,[]vcn݊Rx?\ĔDaoGOj{Ƙ-=m\/CEpF398s޽z|>O8p{dS|bY.%-v <9Hi`+?qZsoҎJJfs3,Q Mc F0 1ù"^Y@ B tudI fO6OPjb{!,njE)9W-k-9F/ 8#>JQ[`sBPR"@6Ɍ8 bڍ~g+fFٹ*׳kMx*'!96:N"L@;f aQyt2|ё[,TK2-s( <08g \)evBK_rξ2LnfbA26j#N(*Bs:R<IENDB`qwinff-master/src/icons/qwinff_48x48.png000066400000000000000000000121721347323557400204420ustar00rootroot00000000000000PNG  IHDR00W pHYs  gAMA|Q cHRMz%u0`:o_FIDATxڬyt\}?o]h_,ے, c0v2&a !q&$icB[ܴi9iiHh N1ql6`cXeɒGhw߽͌DzHO>ߙy}MJŇ}*uhPl6ſazMӖ+{Fao9'bCv57@7&cG-b~8z([n%䭷AbTVT"\@(bddp}t"e +*7084W پo&2Jy˺|rbx1L&IRFww74.]x(8"H`e2hNyy9}2:;b(H;y5M-yo<; :Zw>obhBJ) @4R)be^/{MH%%aM;1f𱂡/Zݶtoik! *yFX~c:w+ɿn .C] +X{VoHǎЃW޽A]sH%l_ In4B\I$R ѱ̀[xoooGH5K]kwxG:xv̱ek{R/B4TK0t41d2 0SŽn:l!P^QG[}}=6ի)--ԩ=4L u oDoLž eŐE)Eur:{(3[t3>#˦M,kqHqFGGQt9uo f`PǶAHZ Oe󚭜>0p|foXFbpWL#k-6 P(DYYW^y`0/>+"JM2c$ &''I&؎c۔#CH{Yr~_1۱*ʊj)PJRcxQ> r]wQWWk9p{דNylB8'|ƶD"(K2i̥' V.ap,T7,C%i' IuU{M 9iZ}a/ ]/\O>ʕ+Yf òmAJضm[=J""e MI3 ͞}>3j#8 HP:zΠќ g9˜߿?۷o `Ypu]Tl΅a(2:2Ji451CvdDM +n}͒eH*4f$EJU&+q8xylAJa#ajjjioo!^K꫔c&dC7I1\LS)2uh,+)gU HǙKrRax{ t:S:h]c޽"" <ƙLӛ48iBEaRu l*J&+ENV)T6ǾW6 I)d2!(..9r0]]]yƲGS'ut Cv,f$JptRRI$RH)QE*7ӅI-s3wa\:f\!%%דJ&9x ɵ^˽ˁyO,hFS:*@rI?SEuYP7[E!L`ll χJ7())!S\\L8Ri,d5}픗RxHl|PQ1R)\\vHh [w… Ķm$[o + dՔR."ttt\ lZs%/gsiu\Uz g&0ONP06W?L(*9 zDPW֊<WxqlK.ƍD) !HZ WX6cS#]: RAZzeJ)RNCijl[N +!%v8ɭ޺& 16: ti22=WUs+ ˠ>Dͮ˙wYR}eIN1OYǣYH'cIpMCCmmmtvv222Bln .\0!]B3\t;q5vvm~Xj| E)T G@!.7o˲0M3`bR#}Kʖ315No/l<~;97vDzS1*SVVa((**ʗF.]=<}}kD8!ʭnF!H{n ɀ`0ib ^~eS*,VTo KީC;T9$7G+}ON~X?:R1 ?VR*NC`'233eYd2:t(t]_JRTTT8wƮ=CiJ>I򭿤BvM рc?o~Y.Raf]^鷴Fɶ?1::ӧm˲]יW^yGFOֆi9riqk(oJ0m9 ]_+粆WFMfNy0C5%ťoR:);L7w˗4_=fs=ضx:iEiiiqlhh$  덆ڟ,[ (Hb*fw 3>Y݇:$@υt쬧F#ږD";{ȸ) kJiHw]d֭tww#@u2e+R{{;{ȑ#9{IMGCǢƵrߤm,!_E7ǏI;vo܎iHYq]7id8Css32 ٳ;e>0-03(3f= #m4Y(_Hid80ǼQTRDռkU C( <~͜xsX"pq (5> RW`3F$+]uBfŵqg)L*}<]=N62t}H񾃡SM˫W{RWA"\E3в^=yI_Wo˨,p/(Tʲ9x1/~q\ U̅'-M+;ַnbۨY@Қav")kK{#/F{BHuwsWYT4`>ڹLqsrr=]t핷^h KiYz ZE ԂZ#6irާ_Z|pNhsCNEF*4fCi:4l5S;M·> ~|qx`N%EIENDB`qwinff-master/src/icons/qwinff_64x64.png000066400000000000000000000170601347323557400204370ustar00rootroot00000000000000PNG  IHDR@@iq pHYs  gAMA|Q cHRMz%u0`:o_FIDATxěyx\}?9gnْWYd/8`l'@HIM{1i44yB)Mx䒥IP0mVɲhd[Hi4YYfFަyޙ33̼[Gl/b(Ɓ3@Xv?~NjR:.ܺpNo P6|oTΥj>U󩮨% !$RB&b(GpnFΓ32CJEȞI?蜹%m @ ӴPʣiGRUn*ʅYp- kQ^C4TB'k$1-ٴmU"qtvk!ZsJ޴`?~Ŗ hP8PK.M,_rFӽLb1t#% ,s{t^ TWeD3!xa^i}מK&~ 3iGHW\|͗l~R':M1Q iRl=O}+Q!lfFq8{|ͻF€CKЗ/}6sv$!n>p?seY/3yj8tF{L1`ͪȧ} 艿hY*"U{Yde^5"<9زwXv?~?}-VnS۾08ֿi%mIu )P)%`Za0ā,.3 Lt0`F5Q~Ȓ$kZl]7^)zG6.lW&M/B@ W TEҴ\hX8\0Y#%MW =w%5|P-_nc^h|cσ?v%_v5M|dnSqD< k!CU#'ot28Dzl.$*afE-fֳhrkއ $:i_Y&CnRqnfͺhҝal?T |ۿ~چ?OVO(l "̌.:ROkavnDR7623o-"Uh\~q0``>iAD.۽M?}{l?ߕ3ko~w]i9tcXDϚ Xm>d9ɉLbD:5㲁jeEΚku||d217fE_-\MWPI Cg < Hiʍ"H&wϝ?C5`ܼ鮻X9fݯiXz 4y饗[#A=xAkk+X bz|>Qf&z0 X Hd9{;+NiGxҧKSBsg|{>L%H4*B!PUQPDBqDk(>Ea~07O>̎62#:ώ4,dRKskT_ !qW1VYv6,[ʻL$H{,QK (~3Ϧ&8=skg^Tfa;K7tM\xM; pl@76N FFO_jY婯G3l!6T\qRS8s[*B2,IJ=[rq#n' iGHL5q.s%{-u )%C|EQP:-Rx(t2C9by{L}ǘ)Vbѳ{,.}W|n0޽et "gd)`8P0E^bPPEfߓH),0)O%C{xW75mF?z{@pb楗^ @ivFҴF^o}n) hZ+7^CtB][:a_)0zBa|tUL&|<hwRkunkSShiigYn(Bww7eaҍ,r=FEe]͙䌴#yKAk5@LRT*)))yOOwՅy^Ö̀Q>/u?>t(N\.$w]|;" hTb՜m_J(]鳏Rp-q&( @{=A]]yؐdrn5˖-`xxN,a E@uTaɚsӸJ4UU je/&0f^턤*:7K)W{( ee8p믿ȮM 144g͚5YO<>Joo/T 00Mcai}Q,K/0%0j_ piEэ/(Ň nB s߇E̜5]%^fY:D[[\m۶QUUE"`xxd2I.CJ;", 01 \.iZD"P( V @k( 9ut-cabF&iyeVKZ:AzU(sC qAObEyxFz1ҭI-L{9nV?O&0 w[iaZ&ҲZ۪ FTTTei?μyal"Ned-ݱXH HfFJadl^~=###$ VpbFTU׀hܸW2/HYh, \\{ri:a>H2|>]]]߿NL  ,1Ʊ,,K*j5,5XҎ N q❃!Dž"}~?QGґHAɓ'I8{]hjj/dnNϡ j$9=M8(lAH/4E+`Jⶶ(hqMSpiedMTUUJ8|0,Zt:/{v1}^2aCzfAmChٿ)L<(:~ԼO!0 EQEQhmmeΝq>ǜsU3 7zaO#"I6 t*bI%1LUBj린ҒN`:rEQ݅6NBPQQA__< gΜaΜ9TVVz.Ôɝ |(ha̷L._ 8FstaaF ZJx,q(PLׇhƳ>K$b,'} 5U#geЭ.|Zd& ׀@ J.tSxW%SIP^^Q &c?eYB!L{t:倗ZR 29y`0@ 3Hi)@8g+"I8f=ztrcM?裬_MռXe5&287%)AC=54:@<1@O*~4ŏ~2ЌtDhIALӜfcv2Elll"Oj])ov!6:Хc:GeD%g^+6Vp0gI8eZ6( GuNAkkka:W%0Pj@!3K#ŏ: T;D`@]kX xf9ʲ9Z`Ynft5@ut][p'u.De:jod-hjj l.vӧ4튯5i:ߏE_W~5]gl-R7cEA=Ղ8Cm^`o0 ]3eƴ (e7M!6l`hh=U1iC  ~s-j=lj!_ƅ,Cngba.jdS(2!GUUeҥ ك85G  cǎQ8aqRGؼ&vxwy֮Ao0쎍(|>1{/СChrS-dJ%Ybsf.4EQn||gk&þ}x7Xz5 DQ&&&8y$x`0L&ijjbppЮIc-8qht*1HQ| `̙S{]~8":+oۏ7Eޤh;o+/cOʹJ9J%UI&3`*Bp8<zh||f۶mY8\._G0M̙##^Y!%K,ZmF4kaٍ DyOl0 ÚK@^ve7JIٳ9r]]]Z:)\gv̸p{@g8sT\zIԠ`vBV9?|AFGyGW]0<`ҭ.\+"YZ׫`w۾B`3Y#m3v@&clXl5Z:Ύ{sP(DMM G'RBљ"x M.^.޷e!͢-DoU%|{>D۩^AǓg.;񊶠ofH~ kdlbj#P vWsl)@PQ' ׳f"C,%R%W~uk//>tgǶގ$TAMYuԔQ[ڲ:T7px~?dI`,dtkeB\͏\{_q;ϾSATn <+D_,%r;HQU4s[ai,[{_HCRZquwaz.?<]V='y=:P15?/$t_##O (dBbn~?6 C= p0sG ^\ȶm8|0RJ‘0@χ(D"͛ǓO>I&%SGn!g䜒; ٢Yg!0ME*_UMgSLfjԣP<[jgߓ3 ZЭ BaFB3tuu|r D1cB~xl~)P8.WuuS/ΟɂP?dP 4&pגyC_#gc<;zl$GDYz5`MӘHrf.~]0˂H{:ͭ?XXHĒ|9IiYҰ3HI4|%v?L_O'A@i4@)\;bV'=-̶K>sakP F4f7X1^O̻r#Uf.CZ)=ro'dd! IhY YNtMC9ܜ c-3u9uk_IU,]NլYhB27F:7Mqg8C:P6Ir&-̂!iK)ϒ {^6ü(N!zHNLzߒ:KKˢ,t5sC\\_,-;}ii0A< F-QKDg;eGL3/D_LA=!&qJP|_%w%IENDB`qwinff-master/src/icons/qwinff_72x72.png000066400000000000000000000215161347323557400204360ustar00rootroot00000000000000PNG  IHDRHHUG pHYs  gAMA|Q cHRMz%u0`:o_F"IDATx̜y}?z}ՌFe$, `6clC; vb{'%v1vs0` `'FHh׌fߗk ȱ_^锪o} [h@;I` otJ_s `Wo{!!$ 헅}/A (VZVBc Z. /g[ftf(s$R׀3]\aŃ)D|Xʋokk _ڊe]ײu+ڸfÕ(DRV$USBX`!5dt:?|ޑ|/`v6q8;B(W5T_fc_ |y_vٱ~3'ǒFw%Y\tZ:mWPvW+c`ܗݕ2j }_zܰV2Tw?KEzt,awƒ-[WI@ !_9kJ^|WB<=R5U~#jk?AZDzL{,(03 Q |h-ۘ{&Ͽ7e|+-"\w}a<~hz y)&ᜱl@xm/EnEp*ܻjr˶𳗿d"{+oG뫖2Woks1""FSC}Մ}0G 41Y=IʈVHcI.b$ ¾ t[|ٿ&tDP{g5͛GK"e*#Ți5UI$BZ9� 0 23?A"@V( UPWHS]+- i], E(suXfOTCD,?+ M<+8@>o=_8aD8LI.Tqd9{3Lj.L`Z 0 Ā@B@\&ZS^+M{m'a,vDv2J(!Y G*֣ąSj;1: }luƧcKVarS~C|!T#ZJfx|s3o7 =n<ک?vW=g-ܴv" ѷgg0RH *7kԅ{5Kl흡k몚O"vw"$Og,fu,C"21>; kQ6$}~2XRSK@֖|#E7R(nʍX_}!]үA3EGmnj` z 8 v (A_ usN`Mu~ӟsN>c$sȿO}K$rQ,Y0`M3_y*+e] K7駗ڳw~ D "%MxhWEAEQ<,!onoq{~OY;Ů~W’H Nfg0:Y": !H甆=rǞORQd&1,ÑKnj"?$EAQUbeKZ/h`xBƵ_qpa(ĒSZHiE(9qq6]ɳt=ghdM5kQZd=ӯҾׯPK+3^b1K=%!\~bK2h^lMZ\So<|#~5x )i"M iZ,geGeׇTgJyuӆ?z^N2m[ )Jy^(t^FJY,@Xw "%@56&?2|nͪqsUvܲtNr7[g{g|fr@B(zώιf@~E+V !8}),DQ?rQB^2Q tnyw~4/oK8Ԯ!XEcܰV'G VM{?ZJ`(uﱾ=!PUeYbTVTO,{G`,I$ y-J |(_ΕW^I}}= Βr4U*0Iٲ>tسm5vx:ՓNeeC^PP9I&u :::.HIz%!iǹpB0H\1DFӴٱ};V&0??OOOc@˲u)" 6jE%[䕓 $Ў;MٱN*εl_1"S m [A X,ƾ}|%3 6066aH$LX,Foo/HM6! 200@& e?`0f2(z əfOmռrwV?ֲٗ drk9 ؉SU#LUW]feyvhSO=0affMضm۷o'[X`l|t*ieپ%%sXNZP&X׺L{gs]l^mi[cQlXpPWc=O}3$,3_*njY˗/"VR  /088֭[蠶d"A4%J Fn-^ˊ2B B45ʮ[Yްcv]do,^xx_ G-EMuM>9¾}ظq#wl{!1?7 J~yPLD7lP،Rb6*C  4I墌Οe=cW*[Ѹhj+*0us^T`HO"AW I[[۷o)%ss I邒 (:Wqse0)#f?~a60,!V5%>zRZ4X B{W'ݕTIoeWdJ8pO}S_)Ȥ3ib'.Vz"Q^^Fuu %i Ρ @7H ~M*@kCM3 ٘[č[* O#|ȑTb 'L{+r466288DݰE ,l0&xUA`Ŋl޼FN>ŏ~Cp8 BbpHHI2FڲHdTWP[YBZ*a%k$K5$`%D)oDioL%$MrdpBU|EFu?Ή'w`i*RJZF'HI2TrTh@}y>n.jA_47'BJ{reXχҲ0sJ(UQVVFUUpfhh)w"$#IJȒPhЀ2GNOcH. L >ER.ZϼK7 ,@S4|>P0… rGwww/1‰L.O 1[KZd̍Li9OI"KJns6E., eYdrz˲4H$Bmm-UUUDQ<ș3gkeff駟\\nŀ(Jw5Pq^ERl):20$PYYImm-i[oqIR`r.2V\(͓/_fy~o4/BN~1dYٴih ʿf0eYy睔199icYiR OGmgXw?:b9 G1lc\G-dzœ:4P(aEVn)6叆ae#8.'|xw I))T0wŭI_a-j8S1,aLWjE( %q7lFQm^'B:mTUgphD ㍾ /OX,Ǝ;%ߵun3MvZV°@/* 3~ߐ Gc3N Q[)r@(hM^f*#U 6pwHWܤX=p8-7|2MZ:ljj KXq׳o><'FeTU1yԖ7329D460l.`h/̦sȐL l^pM>g&s:nD֎1 Í01-˝KںDzLX`һJEYfId籤eNhYrc]tQ|o<4>GszUo^ , ӰӱCQĉy.36v\f6@yg:{ʁ)` TlX;XQs#Χuܪ&fF421?Pآ?};}HR=WRZXn gYKJ[߱]Pp Nv!_c˖-,[ O<ٳN*B"&'ȫ=j"M 3>3p P0= GRL&609`Qw>/MeYTbڼ,m.9ZDV> kWZm݆gzrr,BTWWH$H !k<Ʈȩ71MﺻziGN /d&_}nA7zӜ^/Z:]}c7g2Qȸzh=x 7o{ӌ1?7G,cff>1 .'yn\\=9 0| +V24{)I+ʊU17!fٓE4' 7RhysA H[n3gΐJτ"zF'Lu4>+ ˪V2>=JH/kyuen< ڃ"Terz9#k=i[qkffGv[dL0kg`fJ) 栧;9T_-i>,BuTMs{EAe6U}^}2bOKԄ-or*ф]$ȘX vVTٛfxmذd2|hîϩ~B44380H)](iIh:7|R/T/svMThM`ja?1]P b^і7{h07?O6-2 l˒|>|>~eF_ᖔ^F^8$Ӊ/x4h}W{jgYU+#~7HG캑CQDxAhFY$B.uK+U7 zzzevv1V^c@UUUy&iIlTI3dEM\Evj6if~gX~0B@MիW(L':}_n/3ks|Y&)Tk$y@Ї0$itDwAJR*Dfƍ7|3tY$CQTTU%J3<bJQa!D#Ħwxa׮]e--- `& D"xHםڨkpPرz/u|rᠮ^8dXdЁG3&_Ͼטd"6X($U[&:O~3׮o?wS'+g 7[G*rc401 d2a 7߼ٳ%R7VH$>W|jΝBaEj*s9rzNlCܻ*\_}aLCqQIDn(6zeAz&$gflK!)z (s o2zjGƺJ|9oW^y%===ә4eYR)ҩ4Doo/OEѤ U辞 WN:'Ora WcP}Pp-!w8{t N "<(]qP[=PY^  Z((Bukڶbc!ήf$zkk+ΝcddssslZ{=϶^'qdWEqj6$ عrگ7Ne߯6KtrmF!# W٬ ̝vjZ,sqP)FgiK09o .4;ct +WraΜ9x.(چ 7\WΝwן09tlfesb=Rp}-[~LVX3No2J{4e7?ƛ\&bv!_:u2.[D">/^}Ƈ"׷knf#\j]7VҢj%gOu1ٗO~n:qGj 8>Ϯ]}uU_G %h/0y$#zs|7x Tv>PT7 ìY!_ɉh]ye7J 0rK6M\l{ fY& ŇC Ca*0˯gKso^~Yohnn?!wQ] :Ja_cǑHB@ߏ(hFyy9MMM<e^_H7rnŋ;b3r_ 昍ζ^L-]ݼE=7}[d61f7[L67JMM ccHi8fgfxgtܵcґNBt[-*ELiFngɾBy'5@ҲMm^K{fh$&5ResQHH.6)lWjLOOsQR~^qV!?|]\!6M{ue99n5y;e:_}[bv,ɏ|K>%Z-9.Y#!jzkWmjݛn##g MBE*2 ~4/ ks:nP^! ^6vOgBxzDIqSX(UGۚMY|I] %#7d(uxP41Mָ@7 p@RJuU;4 I"]r*'(BuSAu>(jB¿rd@9'gNr[%Jf Z}2!P&}A(M0(yZR$^Xf fSIENDB`qwinff-master/src/icons/qwinff_96x96.png000066400000000000000000000326371347323557400204600ustar00rootroot00000000000000PNG  IHDR``w8 pHYs  gAMA|Q cHRMz%u0`:o_F5IDATx}yWuwoU:==>F3%Y,ے x0IX6xA !/@NXxN ɖl#Ye5;v-/$֯3={|~w7s{;?7b)?ƍsbspbp5_f]d5N1^cj-:%F MQ"sހ:|mE'j}蜻4\?N|\2u tDЫJְu{0`$7ek*QWٌjFy~)J)ܫsZ@2d|QL%Gs?򓜜yUtڑY UehY PGE 胬!k(z:S9H T'# n_@Qe$1L%8?=mL>,Wvg~ߟxw:+ D6EaXиeH+H+3ȫIZS|ep0< !DBP"AWXj}c=8q ُDfg ڑ{wSй=HVi ܸ,j]p( 4d5 -j#>pK涤Jl)R~1r-j f5p |u"35<vpʭhktn jF0vMP$pni;bJRwbTDP"ԌB9vF"3}߮G(`gM׭m;\׊)PC.ιy n~9c8ͽVWfdJ!%>B ~Duhx?v~|ڑ{ῥ:#Oo|W` ~iyl y ܍۲tx #%q k ԇ Vw4c{+Bv'(`Zj;sc-  Ĺ)hN#טBGpCů1 [y,zv ~T硡l ۉ{;xx׎KO}!_mY{!LEAKBNPg喴92^θW:qR T$ Xlh]/Vܑ[2"uu?z?Gڎ<@a$Mg`qxsu̼k"u~n}5^\ Er> 9%3o@&ؽw?hRX]G.B^դb'wݹSM7toRB |B"tC5,UCstȬ+s3V#% M19ށy/ڑ\[w !}P|omtV5 !(z$X9t6Df|%U>D8AeJA) SHSSЙAN@AeNff"$52ZO"_pڝL>YKozo42}t9ᎡXܣ"¾(-/kLrFpvvc2>Df<8e aBH$H+Q[وMKu96/Am}&0BNIB|ȅꄑMǎg?W>|Pm|G.tvM[z{T,E:ñӯ{8r曜0S7tvl}ZP *#[W`MXsFDB2? % wR B좌5 .7~3\sii'ßzɖ/=DTpNbd4\RGE p~^F*Yo ݫ6bd~k=<~&ܼ.t.AaijPbcU;M3!ZQZ_e-)`׎e+^O)(g152{`fCJf G^P5P7to%8t@'_lͷo|77!)*&PΝߕڲ+$?_r n+ 1L΁C<1կBW%oV^A%MDE/(K 9e#c"pmhB!BBt7_s0F8+ZފZD5[ v]TDct1ŗ~)oع#R ^S1Pi#w~ _p*[It܀BP+º~cݸCUUU!{i8wy.={ma{T[a(s{r?޷C87sY9a BPb0φ/nٳ*~ %PBZ}"v~>7sC09π8lÄ6l?qfè)o'M>,}otv ̩k930 ^s)KQlRjV'bCZ3?9Xܵ#W 9)tLg qܵ!}e&}/NJ;ޱǮ[ybnj˘s5Q腅OWT뵔zBZŗXS;wKO=ԼQ0m Ohz}ombiۚunf `塪~FNNςrUXbeo}q15^^o8fKı`w,: [~'ѓ[D2L,0fTVI!=p엝ۃ®yv@f)s[1SAlɜ3pL`UW-,vnvsSԓ4;eهoDlc_g1rСX /LhtEkOaѼŸ-Tx0 *׹=(E媷됵<g+8(5a*8֊nwA)5+ms nHKK4QC.! ;xs?|kXѴ!8&;uq0ffEˣ{|?:}ȏ;DΘ킼Tc[P_]N3OS"!(]xE\1עrwv |fŭ?c-85䆫!I8O#hvk:; 6#g.ZunHnX݉7wg nl!E-XNt+Hvwd1!v1;xc*+s <[j*8pC~v 0>B먯3HMmQ1s@V9+n#jzV4״tɂk.k^k Ku%zՔRj ;+܅"+A[[?]NY\R/kQ2 tqCοl2]MMMH$iF5]v¸n8 t18[Pxl*{@ |ek JY9n YTOQnBH@vט7 uWf ъ(\qz{{x[q=%:rE flafG6ÑGq!wvm*Ο?PΘ-Ya:(PU\0C݂Ş4䚒g󋸲}^>$qO)(<G( d%@t\S8|0&''QSSz׻P[[Aczj\1MӠitMje"+beƅhx,XCևۚwf 49/"P>xJ  ϝ_yhll hջ0ǫ^5[u DSSS`aUFJ199i(F>pr8TtCМu20mB8&R}w5|#*KV7/A4RHM3x oދlн9%ab\68W_zUp15=>b1,Jl޼ H&bPթ`]f3`:c@  * T p03ҘH+A\~Zpr=AXڛb"Y%nuE֪p e 0%X]rСC8|0/^M7cETc BUU#Z6%xt]P5 aB :3QfQsD) {޲{)Rk\Dn.<2!0F{Dj"HR,qF/A! =~hiiUW][;AD2aȊl%lWUϙ놿uh30~Y(妀L6Vb1;WSR`c"=+jO xTLLt=V"Vqf *n^=tAs ._*r`'?R$&'&/̂dG^WY܉a*˫َWY^+_CNﳻ?J!q)_;=!&V3#l?^"6يU5#2iE |>9s{t]peq2$q}a$ VyY9H4 ЙV]feg`r玜ZGU=( ͕)'c 0n=" a||{AOOdY ܵsjI[gSD:'P2%ݪu9% jJy 6W``ot9 I Ls>=+)泧&9Ncs ȊbUq,T oH$~ gvڹ3m!8%31aj&E#@qN ׌+Zc$$8gI^D'3$YN% sMORjP"#娪8q= J) w (3gC![HLK",Rb 2*@ͧ/8FtK9fb UU=~IByyUU /aGq;w.w9*5y pm=5f9TmB1J;)} . VUըV͂KD Ů]p9~~CDQ6f=D "c2]##`>9)D>kz~4-z97\ @eU*+No PWWgfL&xIb8.$?4]u),nTPUg 8-ZV- ka( bᗢXŌ{M/qgGsY( F__~sÈFXz5"ϸPR !ڌӼ]@u %sj ;o{]jաZBJa9 /rQJ. G{{;QǏGGG0A@.sPOHTy˕8Ces6mqomL.A@ CԆ#`'Mr Hs{Pwhβ0'BAF<ƍkSs~̧; HP(+V@UUR) 9^4Zlqࠒ"RXC{ad6E$`V@&쟈 #ޮP"Z|O9J~ NL@+rYOH /#A9lܛcccXr\,Ë/UUpBTUUahhȱzpY˂rhP0 AWqݽ8yp=bWbiȊ |  AHJԘykXcD#7;gضmAlĮXqPO&`RP*++i&cbb$n?skUMrEF>^~)|!xr2EKb*>@52C  R(0DGRv*yP8Y(hii,A֧Ÿ59=֡ꮿz *+7w+﷏cutfgHo8_UQ"x;;&Ҍpοmݬ}gX.n\tfZHʊ,C. 2dYFP@]T8uzQӡ2hQCJ+*o7Vsz/ߏXfL1sv&8TَsCz)nsC=xG}PԼ F&B81*-gvZNN<*[ mR:-d-uWLݛfɕ4V7-3rYdYļ+7-X[鑩!M*Td?ux望8-WϾON>TнN?3n"ƘkW++"=^\)t]6,rҟΟ?-BCC|AOOb1$S)f2skffUM clzfcg 5Mk]xÌ#.mzΌA#9YEA5DEvȊ+n۟6EQ:;;||͠"! 1Ir*diLLN"耒Fͯ]}ǡiWsu>8ܿ&٨kMWpon6~|-©%Yb0}>h qSݽdgXCj8c$5fq~`hhT@Z5]=B'  Oc L#}Ž=O#ɠ:hV.Nk:EuuV.^]̴X{[m 麳f5]kN6e87Ng6 :GWW}Q$ Of TUE"@2Ft6qHvR@NQO5hqgj<;6 ݗYkNw|IusFf 4'[iagME{<utww㡇FGGf ((PULA13kΜȦhSJݤ.yߣP5ݮ)43]%AtW}`[]J4WƭފB>I99VPj_uȲ̹Q Mĵ qe8pl/|K)zaarg;G2w[汯Y46@^zlTEŖnZ",kup}b3BCmbɷVs .EI }d2+C{J>wx܍h!3&C Uq+@gLwXX R lV==K6̋bٲe61tϞK`FkDI$JE Goo/r.C,_|d3i9 C{ |M=1[XӐƇ=o,̹&{HJ2#Jt\q~(ds Vg[10CMu5EA,esv`Q =]x6@LLL HYb (Ez}> $A|E>pEQ!2rE)-wE2\qxP ~@u?a6BB!BH`8NڪZB4HIMCQUU&ٳC^] h ]%xW{ ? 629žO*,m ^qA{#$ asYe#o_C_|o)z~ްaö=D"E>w(hEQPXPQQQ 'ȍL&믿 6`ll |M@ rDQ={wX2ܵ X޺X {DY/$Rگ>kS>d2׶4֎32 "=7~c37NEBfʕ+W466>裏BuP(`c= "5vHáCi&?ۏx\٫( d2ݻ1{ u7 ڞh\-/_F2wnYHmۧ[&@k=5+R"3s<ޱc=Ix7ό3$HxMAUsX9=K,|p!cccTafpVe 9[s ߾+ʗ͜{ r)ڏ›-}h0hGbyFCxOΞ/ %)ۧ"lB~m6RD^ z15MA@A9 c%SH`(֍ֽW[l=9!5ORY 6|fժU2ilIkH4 y؈Ç?WBsy4=W0:3换|`*1ElpڶA:v/˅'쬛GEn-xҊf>~UWn>&`L7-z6s)0,bݨ]7< *װVXDYᄃmzzL;mc<.kOR70ѣ'vL~y _Om Lgq쯐*\=aS) oC>|SgGƻ\eJh^0!8~ZOv#=Gݼ#Ɏ1fn%ImS"H@ LLfSA\fܰrdYLMmWtMLWRxL<ނ,%PJ܌!lddH֝ʉ5%H/ۮ۲鑻>[38?}&nTDrO `͂M[e }'?{gS wm5B2oYXן|/1<7g_Pb`{|ڽ^c+I |gZ0xXlΞ9cO2%f@ TȄ|>VX}{ؿX,!Җ_nºiͨnBVNb"5U.8w]#1Vr b\|WykwfmN,LtAkߖX?Ÿ=O?? A{9bnʘD?&y ! J)$AwQdS|hk[`llk ZWY^ VB%;Ǿ/D)ރ7NH_|WpvBw \,JEK1<{g?{ǡi؃[ԥhsU9`7"xߏcǎ!NC|>~H>$3R455attϾ! E9*Ĺx4lepB '0B̿\˻\Wk@)Anݻ},|w=֖foH P6(h5?o>-`~*lPJ҂957 Zz\ UgEn}*)~R8xwOK9rk:vR?'iGz >d-kvL4 Р@+ -Z& =f* QC,zGF8 1 yg B@7!5~ |O >dxT RLA`bF3RX hu?35a `hT߫ڳȥ-z(6nƾ3P8z'@jdJ;E?>5k`Æ P, P@,СC8r ,Ggׂy˻`wc6d}8 #sn=i&͚c ZrKE>Gd>1zB&:54{al[AKIJcjlg*ϊ8cAss3DQD24[CQDyPbmk۔K0nl4I){Rp١p:a7#&6l)X;"sK?P^.ز>TkЙb X-nه%7QP*NM#o0jZ|vjgzo%m 8˩ S8F\mY{E:͹c"x7^~%~fy׋2GIj^Sr3wƙɃu#f֦+K4&QDU t~ӳ/L@:scAs Ù9э.̃1kVn_1?!qjfv RV>5.tgG#9g?=ƊEtdi$mf6lZ}1c?6g*:'6 7z%E8g=ۺ k umZPD{,.Q,>xHW@|K˚quG'*M͒P)`gQph vGƪxW%'p`!I3xR Ab4tA'9طO{^񀅄`ťuߧβyٳ<ˣ~`5(] 9sn*&z#%JLZ78^(V2n8#hT{ 8{Y1]&9`>1BA ݻԓݻprUc_ H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3-gAMA|Q cHRMz%u0`:o_F6IDATx=NC1ucPq ID zh((3  "{"]43{m:X6YD #"GIȪ`X"м_0NޏO\,INVR *yTBx?x_"'/W0+ffmOAQx 660a(H |xi()KPgV 4jf]R5 T_ܸDfD+ ~=s3n,S H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3-gAMA|Q cHRMz%u0`:o_FIDATxڤklef^J[zMKi QSAV%F c &FS%H!  ,7(zn^;;3;L@A=9!p+SETCq]R{(n4I_~߲B>x !q}1Ϫ6a$AD)3Y]?{ c#aA][+kMOTpI[2^;Pj)7Zo)ĵ nʗ JOV%}VvzH[cNGL9 D-OI0#-[ Je9C܀;mqt9{Tjr< )pu%fW4Pp%7 ӵI BCwP6dQT0hxޣO ׄ ހOp@ĵWm+LGǺ/l/:Տ`% Jh5ִ72V8W$NDݱv\/Gt>HW(˴yXX2w6|1ERw[gt~tYT/nFOĬjp+6Fd*Iʮ²mcF/D LE6C:3EP<284u4 QBP 7Rs4̽$K,۰>`;ХFcè}Z~9DmGG?p7,lUÇb3=!N{&:H¼S.C=ogUB!|p85ӗy3DHnҶ3gi뺳E*bSIENDB`qwinff-master/src/icons/retry.png000066400000000000000000000014521347323557400174350ustar00rootroot00000000000000PNG  IHDRĴl;bKGD pHYs B(xtIME #K(OIDAT8˭MkQs#4֊"T VX(m,. fGŶ ki&G373Idx0p9s.cqn} X\+ _Żi?xnSh"tIo&Eb[IeyD"pj QZ]ZrH%pS Vb@4æX\?`Qei+Y  fIy|%\3 _\t&P(emBEl E2 @xJ̯BQ;`(Yip- @Ш iUr]E-hmDŽVlrfv9 ip2 N@EDK.{[BAZa˜[ t*/MVλ?4$+}T ib@R/ °9 Oe]:7xzGt\.R(;L_*OF^5T)D Jebƣ"VeUߊcl.wXora?>V*ڡ.|eZK:Draf{pj&ǖ#s1I[ •G("OjEu3?:!nAnC:cIENDB`qwinff-master/src/icons/retry_all.png000066400000000000000000000074131347323557400202700ustar00rootroot00000000000000PNG  IHDRĴl; pHYs B(x OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3-gAMA|Q cHRMz%u0`:o_F&IDATxڌhU?mwW6Mr5RA2+IGDL1ԩ[H! c5Siܚy>q{9~眣jkoPqADGpq;6ێRʎZʗ/}k#wV_g1L0YtuwB+Tl$ALvl_([lqZ+ 00з(h2ӯz\(,+]VZ/^h}檌! H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3-gAMA|Q cHRMz%u0`:o_FPLTEU3f+Uq.]t5jHx3fl4e`7g7h^7h7hGv8i8iU>>???@@@AAABBBCCCDDDEEEFFFGGGHHHIIIJJJKKKLLLMMMNNNOOOPPPQQQRRRSSSTTTUUUVVVWWWXXXYYYZZZ[[[\\\]]]^^^___```aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrssstttuuuvvvwwwxxxyyyzzz{{{|||}}}~~~V2ttRNS@fIDATxڌ0CWoTU!( cL Em |pP%Jb`@*V˕ ;w@ThfB7$ϙ0'm Bd*:u꧖(7W5VFF(Ҷ Sڂ9;CRNa]풧;:K; X,]]󃹭[-$l1C!OvtGڲe.'2301.f775tC:޹!A |}'NVWu)(GKx']\ȐxV&e;=N`7QrlzzA\TP*ᅂu̠7/]|?h5+ά\t AhTW׈]Lg=;\V/7BCV3an6SXX(vsGRA fbnl^`5%1LY]] l͚.?>8ytú3>?2#uҩLeJ7}ѩǍ)JQar,ݎ֫-ںڌ;v/^|LxI7;=Zx}q,(>Ra30MJQ0f#falώ#=Cc6ecb>4V@vfva7: tTZ8B9ׅdYHohׅSQ<2 셪WvԪ`(!dPJ1E(HXR۴79=zzIENDB`qwinff-master/src/icons/start.png000066400000000000000000000073331347323557400174310ustar00rootroot00000000000000PNG  IHDR szz pHYs B(x OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3-gAMA|Q cHRMz%u0`:o_FIDATx[hU眝[4M: *I@UzP}и}(^KA苈X/TEA*Ti&`  ؐB5&6fNnї0 3a69$<6lXw!$gBrÆ> x;p[:F yUh٪O yg4_Vck*n:3DS6@HZ *lWܘ83D?ʕmA hٰhlbu`Pl/;#E&1ج6Twq`_| {&MKNuUٮݎ}#+ JXvx2?w86>`ɖ@2[ʥh҇>,AHW>0/ntegrmjVmM8}>XTt9}(FWr.dy7J!PRG JjZ恪ӵm+ Hė*¥|h$/|UGG*f_JG%o.Co*0NBr\MߴϜfjuɸT ^k`˚P <@ڊr񇛙ߘxOͺt x{H[q.~kff$~)T%5MO'H0wwZ&]_ӏ(h\H۟W^U`IWv)~.5V*0T/+ ifҫކDEℙ?ti6P%ւlnFZp}pڊ O2?۴]y9!g>%=1Z[WڐԆDlL6lXo3=AWIENDB`qwinff-master/src/icons/stop.png000066400000000000000000000023701347323557400172550ustar00rootroot00000000000000PNG  IHDRĴl;bKGDC pHYs  tIME +C+GIDAT8ˍ[hTGsnl jH[M f R DB)TzЇBPA (ڂsѴIۺI9sD߮޾M:!v#Ș&v6[' ]x8#JxwF ; 77{]]dB!rJ,}H|L ieejme޽BV # [lh'hB OZ3gBRڊmF8iB.źT*y!@)*lӧYq /?ihJ1p0r9R()IU*Ò*`r pz<8^"/bmc?Gxm=%tvM4FnaIF&i4 JJX|3HI0<^:v gY:EhBPs(Sĥ$C=~0i?*)HIr^ﯯwIx*+YY[_mxԭe2h08s ttiWU/dbmxX1|V}ֆ %ee/hy%!R`9< v oB B䣠os8SUyP,y@xP(0 (?dyIENDB`qwinff-master/src/icons/system_hibernate.png000066400000000000000000000026621347323557400216410ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org</IDAT8KlT1c{IL0yCy]TBHEJv "Y"(4( nʩn1)A AL 6c{ޙssO؎&]Hw|$!uS>P(QKU]j@QAqN}Oxx^*vȲY}}%HbF\.-us,.H˭8~tD>Ly\2K&o~܊f6uVtthWזpULer{ֵ)6lXW#\g.in]1W:>w\7v.[eǟ~z6o-wCwq&Bx}m+=d_@;SIA__7nxjU"*>Ggyzebc8\6ǟ 3 W=;E ƦW" -xL.UJ||cu3SS,1U!pޥtܪԒB4$|xFۃơC"Vm4WϣjJ>R-I2-a1e94}[0umGศȮ424>jL^il'ĕ$Zצ& .bЍ5I;CH@8e$?w$x/"RpzD}%y8FJt0!;v P4DxA TKDAªEa B *We\mגrKWcK怹i;ηx1J%xܲI"GIR)YRG~ Bi ADz>j>H,ȔֿF_JPf1?jJĀxUNUЀdU wxIENDB`qwinff-master/src/icons/system_suspend.png000066400000000000000000000025031347323557400213530ustar00rootroot00000000000000PNG  IHDRĴl;sRGBbKGD pHYs  tIME tEXtCommentid logowIDAT8u]lUW׷ڑvpvą(Kdhb Ġo%BHPH0!1S _LXPNt>h[^e'yr\ad˶1- gٷI!\D39&vEmHݕcc_ a&eb>J9PxÇ]/ll!oLz(^ Lİ e7u43s=x 8uCX( iXiwpY.É$m]t>nΈŃ*%iYRYu Eg~z@GS5w;V08dqkNT.~vz-[ .^ GU>.ҴM>+ S= ɖk 4W~ZX Y7\rXt@yv|*q!SdYkjϗa,hNŧ|c|iEe:>H HL>DTBxHꃘ%Lns0R1$[."I.-BQFy8 Wdnb`[ ታHضظ "'Lx(S)BSr'>5xWg}H&; 3>DmhF44MEd$$<@*tf=쪽F] `k(؎8箇Itfn`(F] %)&A)D4 z= ?Ou`(&.]1'8TX_=ǞU|TViƝD 8Hz1maVqwrCK-Dt@! b՘Mx j4*VƱ;5q*`:V@%-<eG~UD(s&_9eF( w_kB|~GpNU65N.IENDB`qwinff-master/src/images.qrc000066400000000000000000000037721347323557400164320ustar00rootroot00000000000000 icons/add.png icons/remove.png icons/clear.png icons/play.png icons/settings.png icons/start.png icons/stop.png icons/exit.png icons/open_folder.png icons/remove_completed.png icons/retry.png icons/retry_all.png icons/configure.png icons/system_shutdown.png icons/system_suspend.png icons/dialog_cancel.png icons/system_hibernate.png icons/preview_play.png icons/check_update.png icons/edit_preset.png icons/media-playback-pause.png icons/media-playback-start.png icons/media-seek-backward.png icons/media-seek-forward.png icons/audio_volume.png icons/media-skip-backward.png icons/mark.png icons/seek_to_begin.png icons/seek_to_end.png icons/cut.png icons/qt.png icons/ffmpeg.png icons/ffmpeg_large.png icons/banner.png icons/qwinff_16x16.png icons/qwinff_22x22.png icons/qwinff_32x32.png icons/qwinff_48x48.png icons/qwinff_64x64.png icons/qwinff_72x72.png icons/qwinff_96x96.png icons/qwinff_128x128.png icons/qwinff_256x256.png icons/list_background.png qwinff-master/src/main.cpp000066400000000000000000000160461347323557400161040ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include #include #include #include #include #include #include #include "ui/mainwindow.h" #include "services/paths.h" #include "converter/ffmpeginterface.h" #include "converter/mediaprobe.h" #include "converter/exepath.h" #include "services/notification.h" #include "services/constants.h" /** * @brief Find the absolute path of the translation of the current locale. * * @return the absolute path of the translation or an empty string if file not found. * @note This function must be called after @c Paths has been initialized. */ static QString find_translation_file() { QString locale = QLocale::system().name(); // language code + country code (xx_XX) QString language = locale.mid(0, 2); // language code (first two chars of locale) QString translation_file_basename = QDir(Paths::translationPath()).absoluteFilePath("qwinff_"); // look for qwinff_xx_XX.qm in the translation directory QString translation_language_country = translation_file_basename + locale + ".qm"; if (QFile(translation_language_country).exists()) return translation_language_country; // look for qwinff_xx.qm in the translation directory QString translation_language = translation_file_basename + language + ".qm"; if (QFile(translation_language).exists()) return translation_language; // translation for current locale not found, return empty string return ""; } /** * @brief Load program constants from constants.xml. * @return true on success, false on failure */ static bool load_constants(QApplication& app) { #ifdef DATA_PATH QString app_path = QString(DATA_PATH); (void)app; // eliminate "variable not used" warning #else QString app_path = app.applicationDirPath(); #endif QString constant_xml_filename = QDir(app_path).absoluteFilePath("constants.xml"); // open constant xml file QFile constant_xml(constant_xml_filename); constant_xml.open(QIODevice::ReadOnly); if (!constant_xml.isOpen()) { qCritical() << "Failed to read file: " << constant_xml_filename; QMessageBox::critical(0, "QWinFF", QString("Cannot load %1. The program will exit now.") .arg(constant_xml_filename)); return false; } qDebug() << "Reading file: " << constant_xml_filename; // parse the xml file if (!Constants::readFile(constant_xml)) { QMessageBox::critical(0, "QWinFF", QString("%1 contains error(s). " "Reinstall the application may solve the problem.") .arg(constant_xml_filename)); return false; } return true; } // register an external tool for use // returns whether the tool can be successfully invoked static bool register_tool(const char *id, const char *name) { QString exefile = name; // default: use the program in PATH #ifdef TOOLS_IN_DATA_PATH // Search external tools in /tools #ifdef Q_OS_WIN32 // executable files must end with .exe on MS Windows exefile = Paths::dataFileName("tools/%1.exe").arg(name); #else exefile = Paths::dataFileName("tools/%1").arg(name); #endif // Q_OS_WIN32 #endif // TOOLS_IN_DATA_PATH ExePath::setPath(id, exefile); if (ExePath::checkProgramAvailability(id)) return true; // failed to invoke the program ExePath::setPath(id, ""); // unset the tool return false; } static bool register_tool(const char *name) { return register_tool(name, name); } static void register_external_tools() { // load user settings for the tools ExePath::loadSettings(); // If the setting of ffmpeg is not available, register it again. // If "ffmpeg" doesn't exist on the system, try "avconv" instead. ExePath::checkProgramAvailability("ffmpeg") || register_tool("ffmpeg") || register_tool("ffmpeg", "avconv"); // same as "ffmpeg" (try "avprobe" if "ffprobe" not available) ExePath::checkProgramAvailability("ffprobe") || register_tool("ffprobe") || register_tool("ffprobe", "avprobe"); // same as above ExePath::checkProgramAvailability("ffplay") || register_tool("ffplay") || register_tool("ffplay", "avplay"); // these tools have no alternative names register_tool("sox"); register_tool("mplayer"); } int main(int argc, char *argv[]) { // Create Application. QApplication app(argc, argv); if (!load_constants(app)) { app.exec(); return EXIT_FAILURE; } // Register QSettings information. app.setOrganizationName("qwinff"); QSettings::setDefaultFormat(QSettings::IniFormat); if (Constants::getBool("Portable")) { // Portable App: Save settings in /qwinff.ini. QSettings::setPath(QSettings::IniFormat, QSettings::UserScope , app.applicationDirPath()); } else { // Save settings to the default Qt location } qDebug() << "Settings filename: " + QSettings().fileName(); Paths::setAppPath(app.applicationDirPath()); register_external_tools(); // Construct a string list containing all input filenames. QStringList inputFiles(app.arguments()); inputFiles.removeFirst(); // Exclude self executable name. // Setup translation QTranslator translator; QString translation_filename = find_translation_file(); if (!translation_filename.isEmpty()) { qDebug() << "Translation file: " << translation_filename; translator.load(translation_filename); app.installTranslator(&translator); } // Load translation for Qt library QTranslator translator_qt; translator_qt.load("qt_" + QLocale::system().name(), Paths::qtTranslationPath()); app.installTranslator(&translator_qt); // Setup notification Notification::init(); if (!Notification::setType(Notification::TYPE_LIBNOTIFY)) Notification::setType(Notification::TYPE_NOTIFYSEND); // Create main window. MainWindow window(0, inputFiles); window.show(); // Execute the main loop int status = app.exec(); // Tear down notification Notification::release(); #ifndef TOOLS_IN_DATA_PATH // Save path settings ExePath::saveSettings(); #endif return status; } qwinff-master/src/presets.xml000066400000000000000000001220241347323557400166550ustar00rootroot00000000000000 -sameq mp4 MPEG-4 -crf 35.0 -vcodec libx264 -vpre hq -acodec libfaac -ar 48000 -ab 128kb -coder 1 -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 -me_method hex -subq 6 -me_range 16 -g 250 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -b_strategy 1 -threads 0 mp4 MPEG-4 -crf 25.0 -vcodec libx264 -vpre hq -acodec libfaac -ar 48000 -ab 160kb -coder 1 -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 -me_method hex -subq 6 -me_range 16 -g 250 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -b_strategy 1 -threads 0 mp4 MPEG-4 -crf 15.0 -vcodec libx264 -vpre max -acodec libfaac -ar 48000 -ab 192kb -coder 1 -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 -me_method hex -subq 6 -me_range 16 -g 250 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -b_strategy 1 -threads 0 mp4 MPEG-4 -f mp4 -vcodec mpeg4 -b 400k -r 24 -s 320x240 -aspect 4:3 -acodec libfaac -ar 22050 -ac 2 -ab 48kb mp4 Blackberry -f mp4 -vcodec mpeg4 -b 400kb -r 24 -s 320x180 -aspect 16:9 -acodec libfaac -ar 22050 -ac 2 -ab 48kb mp4 Blackberry -f mp4 -r 29.97 -vcodec libxvid -s 640x480 -aspect 4:3 -maxrate 2500kb -b 2000kb -qmin 3 -qmax 5 -bufsize 4096 -mbd 2 -flags +4mv -trellis -aic -cmp 2 -subcmp 2 -g 300 -acodec libfaac -ar 48000 -ab 128kb -ac 2 mp4 Neuros OSD -f mp4 -r 25 -vcodec libxvid -s 640x480 -aspect 4:3 -maxrate 2500kb -b 2000kb -qmin 3 -qmax 5 -bufsize 4096 -mbd 2 -flags +4mv -trellis -aic -cmp 2 -subcmp 2 -g 300 -acodec libfaac -ar 48000 -ab 128kb -ac 2 mp4 Neuros OSD -f mp4 -b 800kb -r 29.97 -s 320x240 -aspect 4:3 -vcodec libxvid -ar 48000 -ab 80kb -ac 2 -acodec libfaac mp4 Neuros OSD -f mp4 -b 800kb -r 25 -s 320x240 -aspect 4:3 -vcodec libxvid -ar 48000 -ab 80kb -ac 2 -acodec libfaac mp4 Neuros OSD -f mp4 -r 29.97 -vcodec libxvid -s 704x384 -aspect 16:9 -maxrate 3000kb -b 2500kb -qmin 3 -qmax 5 -bufsize 4096 -mbd 2 -bf 2 -flags +4mv -trellis -aic -cmp 2 -subcmp 2 -g 300 -acodec libfaac -ar 48000 -ab 128kb -ac 2 mp4 Neuros OSD -f mp4 -r 25 -vcodec libxvid -s 704x384 -aspect 16:9 -maxrate 3000kb -b 2500kb -qmin 3 -qmax 5 -bufsize 4096 -mbd 2 -bf 2 -flags +4mv -trellis -aic -cmp 2 -subcmp 2 -g 300 -acodec libfaac -ar 48000 -ab 128kb -ac 2 mp4 Neuros OSD -f mp4 -b 800kb -r 29.97 -s 352x240 -aspect 16:9 -vcodec libxvid -ar 48000 -ab 80kb -ac 2 -acodec libfaac mp4 Neuros OSD -f mp4 -b 800kb -r 25 -s 352x240 -aspect 16:9 -vcodec libxvid -ar 48000 -ab 80kb -ac 2 -acodec libfaac mp4 Neuros OSD -f mp4 -r 29.97 -vcodec libxvid -s 428x320 -aspect 4:3 -maxrate 550kb -b 500kb -qmin 3 -qmax 5 -bufsize 4096 -mbd 2 -flags +4mv -trellis -aic -cmp 2 -subcmp 2 -g 300 -acodec libfaac -ar 44100 -ab 80kb -ac 2 mp4 Palm -f mp4 -r 29.97 -vcodec libxvid -s 480x320 -aspect 3:2 -maxrate 450kb -b 430kb -qmin 3 -qmax 5 -bufsize 4096 -mbd 2 -flags +4mv -trellis -aic -cmp 2 -subcmp 2 -g 300 -acodec libfaac -ar 44100 -ab 80kb -ac 2 mp4 Palm -f mp4 -r 24 -vcodec libx264 -s 240x180 -aspect 4:3 -maxrate 800kb -bufsize 80k -b 400kb -acodec libfaac -ar 44100 -ab 80kb -ac 2 mp4 Blackberry -f mp4 -r 24 -vcodec libx264 -s 320x180 -aspect 16:9 -maxrate 800kb -bufsize 80k -b 400kb -acodec libfaac -ar 44100 -ab 80kb -ac 2 mp4 Blackberry -f mp4 -s 240x192 -r 11.988 -b 192kb -ab 56kb -vcodec libxvid -acodec libfaac -ar 22050 mp4 LG -f mp4 -s 320x240 -r 11.988 -b 160k -ab 56k -vcodec libxvid -acodec libfaac mp4 LG -f mp4 -r 23.976 -vcodec libx264 -s 1280x720 -b 3000kb -aspect 16:9 -flags +loop -cmp +chroma -deblockalpha 0 -deblockbeta 0 -maxrate 3500k -bufsize 4M -bt 256k -refs 1 -bf 3 -coder 1 -me_method umh -me_range 16 -subq 7 -partitions +parti4x4+parti8x8+partp8x8+partb8x8 -g 250 -keyint_min 25 -level 30 -qmin 10 -qmax 51 -qcomp 0.6 -trellis 2 -sc_threshold 40 -i_qfactor 0.71 -acodec libfaac -ab 384kb -ar 48000 -ac 2 mp4 PS3 -f mp4 -r 23.976 -vcodec libx264 -s 1280x720 -b 3000kb -aspect 4:3 -flags +loop -cmp +chroma -deblockalpha 0 -deblockbeta 0 -maxrate 3500k -bufsize 4M -bt 256k -refs 1 -bf 3 -coder 1 -me_method umh -me_range 16 -subq 7 -partitions +parti4x4+parti8x8+partp8x8+partb8x8 -g 250 -keyint_min 25 -level 30 -qmin 10 -qmax 51 -qcomp 0.6 -trellis 2 -sc_threshold 40 -i_qfactor 0.71 -acodec libfaac -ab 384kb -ar 48000 -ac 2 mp4 PS3 -f mp4 -r 29.97 -vcodec libx264 -s 640x480 -b 1000kb -aspect 4:3 -flags +loop -cmp +chroma -deblockalpha 0 -deblockbeta 0 -b 1250k -maxrate 1500k -bufsize 4M -bt 256k -refs 1 -bf 3 -coder 1 -me_method umh -me_range 16 -subq 7 -partitions +parti4x4+parti8x8+partp8x8+partb8x8 -g 250 -keyint_min 25 -level 30 -qmin 10 -qmax 51 -qcomp 0.6 -trellis 2 -sc_threshold 40 -i_qfactor 0.71 -acodec libfaac -ab 112kb -ar 48000 -ac 2 mp4 MPEG-4 -f mp4 -r 29.97 -vcodec libx264 -s 480x272 -aspect 16:9 -b 1250kb -maxrate 4M -bufsize 4M -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 -me_method umh -subq 6 -trellis 1 -refs 2 -bf 1 -coder 1 -me_range 16 -g 300 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -bt 1250k -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -level 21 -acodec libfaac -ab 128kb -ar 48000 -ac 2 mp4 PSP -f mp4 -r 29.97 -vcodec libx264 -s 640x480 -aspect 4:3 -b 1250kb -maxrate 4M -bufsize 4M -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 -me_method umh -subq 6 -trellis 1 -refs 2 -bf 1 -coder 1 -me_range 16 -g 300 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -bt 1250k -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -level 21 -acodec libfaac -ab 128kb -ar 48000 -ac 2 mp4 PSP -f mp4 -r 29.97 -vcodec libx264 -s 704x384 -b 1000kb -aspect 16:9 -flags +loop -cmp +chroma -deblockalpha 0 -deblockbeta 0 -b 1250k -maxrate 1500k -bufsize 4M -bt 256k -refs 1 -bf 3 -coder 1 -me_method umh -me_range 16 -subq 7 -partitions +parti4x4+parti8x8+partp8x8+partb8x8 -g 250 -keyint_min 25 -level 30 -qmin 10 -qmax 51 -qcomp 0.6 -trellis 2 -sc_threshold 40 -i_qfactor 0.71 -acodec libfaac -ab 112kb -ar 48000 -ac 2 mp4 MPEG-4 -r 29.97 -vcodec libxvid -s 320x240 -aspect 4:3 -maxrate 1500k -b 1250k -qmin 3 -qmax 5 -bufsize 4096 -mbd 2 -cmp 2 -subcmp 2 -g 300 -acodec libfaac -ar 48000 -ab 80k -ac 2 mp4 walkman -f mp4 -r 15 -vcodec mpeg4 -s 320x240 -b 320kb -aspect 16:9 -acodec libfaac -ab 96kb -ar 44100 -ac 2 mp4 Nokia -f mp4 -r 15 -vcodec mpeg4 -s 320x240 -b 320kb -aspect 4:3 -acodec libfaac -ab 96kb -ar 44100 -ac 2 mp4 Nokia -vcodec libvpx -acodec libvorbis -aq 90 -ac 2 webm Google -f webm -aspect 4:3 -vcodec libvpx -g 120 -level 216 -profile:v 0 -qmax 42 -qmin 10 -rc_buf_aggressivity 0.95 -vb 2M -acodec libvorbis -aq 90 -ac 2 webm Google -f webm -aspect 16:9 -vcodec libvpx -g 120 -level 216 -profile:v 0 -qmax 42 -qmin 10 -rc_buf_aggressivity 0.95 -vb 2M -acodec libvorbis -aq 90 -ac 2 webm Google -f webm -aspect 3:2 -vcodec libvpx -vf scale=480:320 -r 13 -g 120 -level 216 -profile:v 0 -qmax 42 -qmin 10 -rc_buf_aggressivity 0.95 -vb 480k -acodec libvorbis -b:a 96000 -aq 90 -ac 2 webm Google -f webm -aspect 4:3 -vcodec libvpx -vf scale=432:320 -r 13 -g 120 -level 216 -profile:v 0 -qmax 42 -qmin 10 -rc_buf_aggressivity 0.95 -vb 480k -acodec libvorbis -b:a 96k -aq 90 -ac 2 webm Google -f webm -aspect 16:9 -vcodec libvpx -vf scale=480:272 -r 13 -g 120 -level 216 -profile:v 0 -qmax 42 -qmin 10 -rc_buf_aggressivity 0.95 -vb 480k -acodec libvorbis -b:a 96k -aq 90 -ac 2 webm Google -vn -ar 44100 -ab 1411kb -ac 2 wav Audio -acodec libmp3lame -ab 192kb -ac 2 -ar 44100 -vn mp3 Audio -acodec libmp3lame -ab 160kb -ac 2 -ar 44100 -vn mp3 Audio -acodec libmp3lame -ab 128kb -ac 2 -ar 44100 -vn mp3 Audio -acodec libmp3lame -ab 32kb -ac 1 -ar 22050 -vn mp3 Mobile Phones -acodec libmp3lame -ab 160kb -ac 2 -ar 44100 -vn mp3 Blackberry -vn -acodec wmav2 -ab 160kb wma Audio -sameq mpg Rockbox -acodec libmp3lame -ab 128kb -ar 44100 -vcodec mpeg2video -s 320x240 -b 600kb -strict -1 mpg Rockbox -acodec libmp3lame -ab 128kb -ar 44100 -vcodec mpeg2video -s 320x176 -b 600kb -strict -1 mpg Rockbox -acodec libmp3lame -ab 128kb -ar 44100 -vcodec mpeg2video -s 160x128 -b 224kb -strict -1 mpg Rockbox -acodec libmp3lame -ab 128kb -ar 44100 -vcodec mpeg2video -s 160x96 -b 224kb -strict -1 mpg Rockbox -acodec libmp3lame -ab 128kb -ar 44100 -vcodec mpeg2video -s 128x96 -b 224kb -strict -1 mpg Rockbox -acodec libmp3lame -ab 128kb -ar 44100 -vcodec mpeg2video -s 128x80 -b 224kb -strict -1 mpg Rockbox -acodec libmp3lame -ab 96kb -ar 44100 -vcodec mpeg2video -s 224x176 -b 224kb -r 10 -strict -1 mpg Rockbox -acodec libmp3lame -ab 96kb -ar 44100 -vcodec mpeg2video -s 224x128 -b 256kb -r 15 -strict -1 mpg Rockbox -acodec libmp3lame -ab 128kb -ar 44100 -vcodec mpeg2video -s 320x240 -b 400kb -strict -1 mpg Rockbox -acodec libmp3lame -ab 128kb -ar 44100 -vcodec mpeg2video -s 320x176 -b 400kb -strict -1 mpg Rockbox -acodec libmp3lame -ab 128kb -ar 44100 -vcodec mpeg2video -s 224x176 -b 320kb -r 15 -strict -1 mpg Rockbox -acodec libmp3lame -ab 128kb -ar 44100 -vcodec mpeg2video -s 224x128 -b 320kb -r 24 -strict -1 mpg Rockbox -acodec libmp3lame -ab 128kb -ar 44100 -vcodec mpeg2video -s 160x128 -b 176kb -r 15 -strict -1 mpg Rockbox -acodec libmp3lame -ab 128kb -ar 44100 -vcodec mpeg2video -s 160x96 -b 224kb -r 24 -strict -1 mpg Rockbox -acodec libmp3lame -ab 128kb -ar 44100 -vcodec mpeg2video -s 224x176 -b 320kb -strict -1 mpg Rockbox -acodec libmp3lame -ab 128kb -ar 44100 -vcodec mpeg2video -s 224x128 -b 320kb -strict -1 mpg Rockbox -acodec libmp3lame -ab 128kb -ar 44100 -vcodec mpeg2video -s 176x128 -b 256kb -strict -1 mpg Rockbox -acodec libmp3lame -ab 128kb -ar 44100 -vcodec mpeg2video -s 176x128 -b 256kb -strict -1 mpg Rockbox -f dvd -vcodec mpeg2video -r 29.97 -s 352x480 -aspect 4:3 -b 4000kb -mbd rd -trellis -mv0 -cmp 2 -subcmp 2 -acodec mp2 -ab 192kb -ar 48000 -ac 2 mpg DVD -f dvd -vcodec mpeg2video -r 29.97 -s 352x480 -aspect 16:9 -b 4000kb -mbd rd -trellis -mv0 -cmp 2 -subcmp 2 -acodec mp2 -ab 192kb -ar 48000 -ac 2 mpg DVD -f dvd -target ntsc-dvd -r 29.97 -s 720x480 -aspect 4:3 -b 8000kb -mbd rd -trellis -mv0 -cmp 0 -subcmp 2 mpg DVD -f dvd -target ntsc-dvd -r 29.97 -s 720x480 -aspect 16:9 -b 8000kb -g 12 -mbd rd -trellis -mv0 -cmp 0 -subcmp 2 mpg DVD -f dvd -target ntsc-dvd -b 5000kb -r 29.97 -s 720x480 -ar 48000 -ab 384kb mpg DVD -f vcd -target ntsc-vcd -mbd rd -trellis -mv0 -cmp 0 -subcmp 2 mpg VCD -f dvd -vcodec mpeg2video -r 25.00 -s 352x576 -aspect 4:3 -b 4000kb -mbd rd -trellis -mv0 -cmp 2 -subcmp 2 -acodec mp2 -ab 192kb -ar 48000 -ac 2 mpg DVD -f dvd -vcodec mpeg2video -r 25.00 -s 352x576 -aspect 16:9 -b 4000kb -mbd rd -trellis -mv0 -cmp 2 -subcmp 2 -acodec mp2 -ab 192kb -ar 48000 -ac 2 mpg DVD -f dvd -target pal-dvd -aspect 4:3 -b 8000kb -mbd rd -trellis -mv0 -cmp 0 -subcmp 2 mpg DVD -f dvd -target pal-dvd -aspect 16:9 -b 8000kb -mbd rd -trellis -mv0 -cmp 0 -subcmp 2 mpg DVD -f dvd -target pal-dvd -b 5000kb -r 25 -s 720x576 -ar 48000 -ab 384kb mpg DVD -f vcd -target pal-vcd -mbd rd -trellis -mv0 -cmp 0 -subcmp 2 mpg VCD -acodec libmp3lame -ab 128kb -ar 44100 -vcodec mpeg1video -s vga -b 640kb -strict -1 mpg Bravia -acodec libmp3lame -ab 128kb -ar 44100 -vcodec mpeg1video -s 640x360 -b 640kb -strict -1 mpg Bravia -acodec libmp3lame -ab 128kb -ar 44100 -vcodec mpeg1video -s 320x240 -b 480kb -strict -1 mpg Bravia -acodec libmp3lame -ab 128kb -ar 44100 -vcodec mpeg1video -s 320x180 -b 480kb -strict -1 mpg Bravia -vn -acodec libfaac -ab 112kb -ac 2 -ar 48000 m4a Audio -acodec libmp3lame -vcodec msmpeg4 -ab 192kb -b 1000kb -s 640x480 -ar 44100 avi AVI -f avi -r 29.97 -vcodec libxvid -vtag XVID -s 640x480 -aspect 4:3 -maxrate 1800kb -b 1500kb -qmin 3 -qmax 5 -bufsize 4096 -mbd 2 -bf 2 -flags +4mv -trellis -aic -cmp 2 -subcmp 2 -g 300 -acodec libmp3lame -ar 48000 -ab 128kb -ac 2 avi AVI -f avi -r 29.97 -vcodec libxvid -vtag XVID -s 704x384 -aspect 16:9 -maxrate 1800k -b 1500k -qmin 3 -qmax 5 -bufsize 4096 -mbd 2 -bf 2 -flags +4mv -trellis -aic -cmp 2 -subcmp 2 -g 300 -acodec libmp3lame -ar 48000 -ab 128k -ac 2 avi AVI -f avi -r 29.97 -croptop 58 -cropbottom 62 -vcodec libxvid -vtag XVID -s 640x272 -aspect 2.35 -maxrate 1800kb -b 1500kb -qmin 3 -qmax 5 -bufsize 4096 -mbd 2 -bf 2 -flags +4mv -trellis -aic -cmp 2 -subcmp 2 -g 300 -acodec libmp3lame -ar 48000 -ab 128kb -ac 2 avi AVI -f avi -r 29.97 -vcodec libxvid -vtag XVID -s 320x240 -aspect 4:3 -maxrate 1800kb -b 1500k -acodec libmp3lame -ar 48000 -ab 128kb -ac 2 avi Creative Zen -f avi -r 29.97 -vcodec libxvid -vtag XVID -s 320x240 -aspect 16:9 -maxrate 1800kb -b 1500kb -acodec libmp3lame -ar 48000 -ab 128kb -ac 2 avi Creative Zen -r 29.97 -vcodec libxvid -vtag XVID -s 400x240 -aspect 4:3 -maxrate 1200k -b 1200k -qmin 3 -qmax 5 -bufsize 4096 -mbd 2 -bf 2 -cmp 2 -subcmp 2 -g 300 -acodec libmp3lame -ar 44100 -ab 160k -ac 2 -async 1 avi Nokia -r 29.97 -vcodec libxvid -vtag XVID -s 400x240 -aspect 16:9 -maxrate 1200k -b 1200k -qmin 3 -qmax 5 -bufsize 4096 -mbd 2 -bf 2 -flags +4mv -trellis -aic -cmp 2 -subcmp 2 -g 300 -acodec libmp3lame -ar 44100 -ab 160k -ac 2 -async 1 avi Nokia -r 29.97 -vcodec libxvid -vtag XVID -s 400x240 -aspect 24:10 -maxrate 1200k -b 1200k -qmin 3 -qmax 5 -bufsize 4096 -mbd 2 -bf 2 -flags +4mv -trellis -aic -cmp 2 -subcmp 2 -g 300 -acodec libmp3lame -ar 44100 -ab 160k -ac 2 -async 1 avi Nokia -f avi -r 10 -s 256x192 -b 192k -bt 64k -vcodec libxvid -deinterlace -acodec libmp3lame -ar 32000 -ab 96k -ac 2 avi Tuna-Vids -f ac3 -acodec ac3 -ab 192kb -ar 48000 -ac 2 ac3 Audio -f ac3 -acodec ac3 -ab 384kb -ar 48000 -ac 2 ac3 Audio -f 3g2 -ar 22050 -ab 128kb -acodec libfaac -s qcif -r 14.985 -vn 3g2 Mobile Phones -target ntsc-dv -aspect 4:3 -f dv dv DV -target pal-dv -aspect 4:3 -f dv dv DV -vcodec flv flv Websites -vcodec flv -f flv -r 29.97 -s 320x240 -aspect 4:3 -b 300kb -g 160 -cmp dct -subcmp dct -mbd 2 -flags +aic+cbp+mv0+mv4 -trellis 1 -ac 1 -ar 22050 -ab 56kb flv Websites -vcodec flv -f flv -r 29.97 -s 320x180 -aspect 16:9 -b 300kb -g 160 -cmp dct -subcmp dct -mbd 2 -flags +aic+cbp+mv0+mv4 -trellis 1 -ac 1 -ar 22050 -ab 56kb flv Websites -acodec libvorbis -vn -ac 2 ogg Audio -acodec libvorbis -vn -ac 1 ogg Audio -acodec vorbis -vn -ac 2 ogg Audio -acodec vorbis -vn -ac 1 ogg Audio -sameq mov QuickTime -f mov -acodec libfaac -b 1250kb -r 25 -ab 128kb -s 640x480 -ac 2 -ar 48000 mov QuickTime -crf 35.0 -vcodec libx264 -acodec libfaac -ar 48000 -ab 128kb -coder 1 -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 -me_method hex -subq 6 -me_range 16 -g 250 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -b_strategy 1 -threads 0 mov QuickTime -crf 25.0 -vcodec libx264 -acodec libfaac -ar 48000 -ab 160kb -coder 1 -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 -me_method hex -subq 6 -me_range 16 -g 250 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -b_strategy 1 -threads 0 mov QuickTime -crf 15.0 -vcodec libx264 -acodec libfaac -ar 48000 -ab 192kb -coder 1 -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 -me_method hex -subq 6 -me_range 16 -g 250 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -b_strategy 1 -threads 0 mov QuickTime -vcodec wmv2 -acodec wmav2 -b 1000kb -ab 160kb -r 25 wmv WMV -vcodec wmv2 -acodec wmav2 -b 640kb -ab 128kb -r 29.97 -s 320x240 wmv WMV -vcodec wmv2 -acodec wmav2 -b 1200kb -ab 160kb -r 25 -s 720x480 wmv WMV -vcodec wmv2 -acodec wmav2 -b 640kb -ab 128kb -r 23.97 -s 320x240 wmv WMV -vcodec wmv2 -acodec wmav2 -aspect 4:3 -b 500k -ab 32k -ac 1 -ar 22050 -s 320x240 wmv WMV -r 15 -b 64kb -ac 1 -s 128x96 -ar 16000 -ab 32kb -acodec libfaac -vcodec h263 3gp Mobile Phones -r 15 -b 64kb -ac 1 -s 176x132 -padtop 6 -padbottom 6 -ar 16000 -ab 32kb -acodec libfaac -vcodec h263 3gp Mobile Phones -r 15 -b 64kb -ac 1 -s 256x144 -cropleft 40 -cropright 40 -ar 16000 -ab 32kb -acodec libfaac -vcodec h263 3gp Mobile Phones -r 15 -b 64kb -ac 1 -s 176x100 -padtop 22 -padbottom 22 -ar 16000 -ab 32kb -acodec libfaac -vcodec h263 3gp Mobile Phones -r 15 -b 128kb -s 320x240 -ar 22050 -ab 64kb -acodec libfaac -vcodec libx264 -coder 1 -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 -me_method hex -subq 6 -me_range 16 -g 250 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -b_strategy 1 -threads 0 3gp Mobile Phones -r 15 -b 128kb -s 426x240 -cropleft 52 -cropright 54 -ar 22050 -ab 64kb -acodec libfaac -vcodec libx264 -coder 1 -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 -me_method hex -subq 6 -me_range 16 -g 250 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -b_strategy 1 -threads 0 3gp Mobile Phones -r 15 -b 128kb -s 320x180 -padtop 30 -padbottom 30 -ar 22050 -ab 64kb -acodec libfaac -vcodec libx264 -coder 1 -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 -me_method hex -subq 6 -me_range 16 -g 250 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -b_strategy 1 -threads 0 3gp Mobile Phones -vcodec msmpeg4 asf Websites -vcodec flv swf Websites -ar 44100 -ab 128kb -vcodec rv10 rm RealMedia -ar 44100 -ab 128kb -vcodec rv20 rm RealMedia -vn aiff Audio -acodec flac -vn flac Audio -vn au Audio -acodec mp2 -vn mp2 Audio qwinff-master/src/qmpwidget/000077500000000000000000000000001347323557400164465ustar00rootroot00000000000000qwinff-master/src/qmpwidget/README.txt000066400000000000000000000017761347323557400201570ustar00rootroot00000000000000qmpwidget - A Qt widget for embedding MPlayer ============================================= This is a small class which allows Qt developers to embed an MPlayer instance into their application for convenient video playback. Starting with version 4.4, Qt can be build with Phonon, the KDE multimedia framework (see http://doc.trolltech.com/phonon-overview.html for an overview). However, the Phonon API provides only a limited amount of functionality, which may be too limited for some purposes. In contrast, this class provides a way of embedding a full-fledged movie player within an application. This means you can use all of MPlayer's features, but also that you will need to ship a MPlayer binary with your application if you can't make sure that it is already installed on a user system. For more information about MPlayer, please visit http://www.mplayerhq.hu/. QMPwidget is written by Jonas Gehring and licensed under GPLv3. For more information about QMPwidget, please visit http://qmpwidget.sourceforge.net/. qwinff-master/src/qmpwidget/qmpwidget.cpp000066400000000000000000001016341347323557400211600ustar00rootroot00000000000000/* * qmpwidget - A Qt widget for embedding MPlayer * Copyright (C) 2010 by Jonas Gehring * * 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 . */ #include #include #include #include #include #include #include #include #ifdef QT_OPENGL_LIB #include #endif #include "qmpwidget.h" //#define QMP_DEBUG_OUTPUT #ifdef QMP_USE_YUVPIPE #include "qmpyuvreader.h" #endif // QMP_USE_YUVPIPE // A plain video widget class QMPPlainVideoWidget : public QWidget { Q_OBJECT public: QMPPlainVideoWidget(QWidget *parent = 0) : QWidget(parent) { setAttribute(Qt::WA_NoSystemBackground); setMouseTracking(true); } void showUserImage(const QImage &image) { m_userImage = image; update(); } public slots: void displayImage(const QImage &image) { m_pixmap = QPixmap::fromImage(image); update(); } protected: void paintEvent(QPaintEvent *event) { Q_UNUSED(event); QPainter p(this); p.setCompositionMode(QPainter::CompositionMode_Source); if (!m_userImage.isNull()) { p.fillRect(rect(), Qt::black); p.drawImage(rect().center() - m_userImage.rect().center(), m_userImage); } else if (!m_pixmap.isNull()) { p.drawPixmap(rect(), m_pixmap); } else { p.fillRect(rect(), Qt::black); } p.end(); } private: QPixmap m_pixmap; QImage m_userImage; }; #ifdef QT_OPENGL_LIB // A OpenGL video widget class QMPOpenGLVideoWidget : public QGLWidget { Q_OBJECT public: QMPOpenGLVideoWidget(QWidget *parent = 0) : QGLWidget(parent), m_tex(-1) { setMouseTracking(true); } void showUserImage(const QImage &image) { m_userImage = image; makeCurrent(); if (m_tex >= 0) { deleteTexture(m_tex); } if (!m_userImage.isNull()) { m_tex = bindTexture(image); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } else { glViewport(0, 0, width(), qMax(height(), 1)); } updateGL(); } public slots: void displayImage(const QImage &image) { if (!m_userImage.isNull()) { return; } makeCurrent(); if (m_tex >= 0) { deleteTexture(m_tex); } m_tex = bindTexture(image); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); updateGL(); } protected: void initializeGL() { glEnable(GL_TEXTURE_2D); glClearColor(0, 0, 0, 0); glClearDepth(1); } void resizeGL(int w, int h) { glViewport(0, 0, w, qMax(h, 1)); } void paintGL() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); if (m_tex >= 0) { glBindTexture(GL_TEXTURE_2D, m_tex); if (!m_userImage.isNull()) { QRect r = m_userImage.rect(); r.moveTopLeft(rect().center() - m_userImage.rect().center()); glViewport(r.x(), r.y(), r.width(), r.height()); } glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex2f(-1, -1); glTexCoord2f(1, 0); glVertex2f( 1, -1); glTexCoord2f(1, 1); glVertex2f( 1, 1); glTexCoord2f(0, 1); glVertex2f(-1, 1); glEnd(); } } private: QImage m_userImage; int m_tex; }; #endif // QT_OPENGL_LIB // A custom QProcess designed for the MPlayer slave interface class QMPProcess : public QProcess { Q_OBJECT public: QMPProcess(QObject *parent = 0) : QProcess(parent), m_state(QMPwidget::NotStartedState), m_mplayerPath("mplayer"), m_fakeInputconf(NULL) #ifdef QMP_USE_YUVPIPE , m_yuvReader(NULL) #endif { resetValues(); #ifdef Q_WS_WIN m_mode = QMPwidget::EmbeddedMode; m_videoOutput = "directx,directx:noaccel"; #elif defined(Q_WS_X11) m_mode = QMPwidget::EmbeddedMode; #ifdef QT_OPENGL_LIB m_videoOutput = "gl2,gl,xv"; #else m_videoOutput = "xv"; #endif #elif defined(Q_WS_MAC) m_mode = QMPwidget::PipeMode; #ifdef QT_OPENGL_LIB m_videoOutput = "gl,quartz"; #else m_videoOutput = "quartz"; #endif #endif m_movieFinishedTimer.setSingleShot(true); m_movieFinishedTimer.setInterval(100); connect(this, SIGNAL(readyReadStandardOutput()), this, SLOT(readStdout())); connect(this, SIGNAL(readyReadStandardError()), this, SLOT(readStderr())); connect(this, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(finished())); connect(&m_movieFinishedTimer, SIGNAL(timeout()), this, SLOT(movieFinished())); } ~QMPProcess() { #ifdef QMP_USE_YUVPIPE if (m_yuvReader != NULL) { m_yuvReader->stop(); } #endif if (m_fakeInputconf != NULL) { delete m_fakeInputconf; } } // Starts the MPlayer process in idle mode void start(QWidget *widget, const QStringList &args) { if (m_mode == QMPwidget::PipeMode) { #ifdef QMP_USE_YUVPIPE m_yuvReader = new QMPYuvReader(this); #else m_mode = QMPwidget::EmbeddedMode; #endif } // Figure out the mplayer version in order to check if // "-input nodefault-bindings" is available bool useFakeInputconf = true; QString version = mplayerVersion(); if (version.contains("SVN")) { // Check revision QRegExp re("SVN-r([0-9]*)"); if (re.indexIn(version) > -1) { int revision = re.cap(1).toInt(); if (revision >= 28878) { useFakeInputconf = false; } } } QStringList myargs; myargs += "-slave"; myargs += "-idle"; myargs += "-noquiet"; myargs += "-identify"; myargs += "-nomouseinput"; myargs += "-nokeepaspect"; myargs += "-monitorpixelaspect"; myargs += "1"; if (!useFakeInputconf) { myargs += "-input"; myargs += "nodefault-bindings:conf=/dev/null"; } else { #ifndef Q_WS_WIN // Ugly hack for older versions of mplayer (used in kmplayer and other) if (m_fakeInputconf == NULL) { m_fakeInputconf = new QTemporaryFile(); if (m_fakeInputconf->open()) { writeFakeInputconf(m_fakeInputconf); } else { delete m_fakeInputconf; m_fakeInputconf = NULL; } } if (m_fakeInputconf != NULL) { myargs += "-input"; myargs += QString("conf=%1").arg(m_fakeInputconf->fileName()); } #endif } if (m_mode == QMPwidget::EmbeddedMode) { myargs += "-wid"; myargs += QString::number((int)widget->winId()); if (!m_videoOutput.isEmpty()) { myargs += "-vo"; myargs += m_videoOutput; } } else { #ifdef QMP_USE_YUVPIPE myargs += "-vo"; myargs += QString("yuv4mpeg:file=%1").arg(m_yuvReader->m_pipe); #endif } myargs += args; #ifdef QMP_DEBUG_OUTPUT qDebug() << myargs; #endif QProcess::start(m_mplayerPath, myargs); changeState(QMPwidget::IdleState); if (m_mode == QMPwidget::PipeMode) { #ifdef QMP_USE_YUVPIPE connect(m_yuvReader, SIGNAL(imageReady(const QImage &)), widget, SLOT(displayImage(const QImage &))); m_yuvReader->start(); #endif } } QString mplayerVersion() { QProcess p; p.start(m_mplayerPath, QStringList("-version")); if (!p.waitForStarted()) { return QString(); } if (!p.waitForFinished()) { return QString(); } QString output = QString(p.readAll()); QRegExp re("MPlayer ([^ ]*)"); if (re.indexIn(output) > -1) { return re.cap(1); } return output; } QProcess::ProcessState processState() const { return QProcess::state(); } void writeCommand(const QString &command) { #ifdef QMP_DEBUG_OUTPUT qDebug("in: \"%s\"", qPrintable(command)); #endif QProcess::write(command.toLocal8Bit()+"\n"); } void quit() { writeCommand("quit"); QProcess::waitForFinished(100); if (QProcess::state() == QProcess::Running) { QProcess::kill(); } QProcess::waitForFinished(-1); } void pause() { writeCommand("pause"); } void stop() { writeCommand("stop"); } signals: void stateChanged(int state); void streamPositionChanged(double position); void error(const QString &reason); void readStandardOutput(const QString &line); void readStandardError(const QString &line); private slots: void readStdout() { QStringList lines = QString::fromLocal8Bit(readAllStandardOutput()).split("\n", QString::SkipEmptyParts); for (int i = 0; i < lines.count(); i++) { lines[i].remove("\r"); #ifdef QMP_DEBUG_OUTPUT qDebug("out: \"%s\"", qPrintable(lines[i])); #endif parseLine(lines[i]); emit readStandardOutput(lines[i]); } } void readStderr() { QStringList lines = QString::fromLocal8Bit(readAllStandardError()).split("\n", QString::SkipEmptyParts); for (int i = 0; i < lines.count(); i++) { lines[i].remove("\r"); #ifdef QMP_DEBUG_OUTPUT qDebug("err: \"%s\"", qPrintable(lines[i])); #endif parseLine(lines[i]); emit readStandardError(lines[i]); } } void finished() { // Called if the *process* has finished changeState(QMPwidget::NotStartedState); } void movieFinished() { if (m_state == QMPwidget::PlayingState) { changeState(QMPwidget::IdleState); } } private: // Parses a line of MPlayer output void parseLine(const QString &line) { if (line.startsWith("Playing ")) { changeState(QMPwidget::LoadingState); } else if (line.startsWith("Cache fill:")) { changeState(QMPwidget::BufferingState); } else if (line.startsWith("Starting playback...")) { m_mediaInfo.ok = true; // No more info here changeState(QMPwidget::PlayingState); } else if (line.startsWith("File not found: ")) { changeState(QMPwidget::ErrorState); } else if (line.endsWith("ID_PAUSED")) { changeState(QMPwidget::PausedState); } else if (line.startsWith("ID_")) { parseMediaInfo(line); } else if (line.startsWith("No stream found")) { changeState(QMPwidget::ErrorState, line); } else if (line.startsWith("A:") || line.startsWith("V:")) { if (m_state != QMPwidget::PlayingState) { changeState(QMPwidget::PlayingState); } parsePosition(line); } else if (line.startsWith("Exiting...")) { changeState(QMPwidget::NotStartedState); } } // Parses MPlayer's media identification output void parseMediaInfo(const QString &line) { QStringList info = line.split("="); if (info.count() < 2) { return; } if (info[0] == "ID_VIDEO_FORMAT") { m_mediaInfo.videoFormat = info[1]; } else if (info[0] == "ID_VIDEO_BITRATE") { m_mediaInfo.videoBitrate = info[1].toInt(); } else if (info[0] == "ID_VIDEO_WIDTH") { m_mediaInfo.size.setWidth(info[1].toInt()); } else if (info[0] == "ID_VIDEO_HEIGHT") { m_mediaInfo.size.setHeight(info[1].toInt()); } else if (info[0] == "ID_VIDEO_FPS") { m_mediaInfo.framesPerSecond = info[1].toDouble(); } else if (info[0] == "ID_AUDIO_FORMAT") { m_mediaInfo.audioFormat = info[1]; } else if (info[0] == "ID_AUDIO_BITRATE") { m_mediaInfo.audioBitrate = info[1].toInt(); } else if (info[0] == "ID_AUDIO_RATE") { m_mediaInfo.sampleRate = info[1].toInt(); } else if (info[0] == "ID_AUDIO_NCH") { m_mediaInfo.numChannels = info[1].toInt(); } else if (info[0] == "ID_LENGTH") { m_mediaInfo.length = info[1].toDouble(); } else if (info[0] == "ID_SEEKABLE") { m_mediaInfo.seekable = (bool)info[1].toInt(); } else if (info[0].startsWith("ID_CLIP_INFO_NAME")) { m_currentTag = info[1]; } else if (info[0].startsWith("ID_CLIP_INFO_VALUE") && !m_currentTag.isEmpty()) { m_mediaInfo.tags.insert(m_currentTag, info[1]); } } // Parsas MPlayer's position output void parsePosition(const QString &line) { static QRegExp rx("[ :]"); QStringList info = line.split(rx, QString::SkipEmptyParts); double oldpos = m_streamPosition; for (int i = 0; i < info.count(); i++) { if ( (info[i] == "V" || info[i] == "A") && info.count() > i) { m_streamPosition = info[i+1].toDouble(); // If the movie is near its end, start a timer that will check whether // the movie has really finished. if (qAbs(m_streamPosition - m_mediaInfo.length) < 1) { m_movieFinishedTimer.start(); } } } if (oldpos != m_streamPosition) { emit streamPositionChanged(m_streamPosition); } } // Changes the current state, possibly emitting multiple signals void changeState(QMPwidget::State state, const QString &comment = QString()) { #ifdef QMP_USE_YUVPIPE if (m_yuvReader != NULL && (state == QMPwidget::ErrorState || state == QMPwidget::NotStartedState)) { m_yuvReader->stop(); m_yuvReader->deleteLater(); } #endif if (m_state == state) { return; } if (m_state == QMPwidget::PlayingState) { m_movieFinishedTimer.stop(); } m_state = state; emit stateChanged(m_state); switch (m_state) { case QMPwidget::NotStartedState: resetValues(); break; case QMPwidget::ErrorState: emit error(comment); resetValues(); break; default: break; } } // Resets the media info and position values void resetValues() { m_mediaInfo = QMPwidget::MediaInfo(); m_streamPosition = -1; } // Writes a dummy input configuration to the given device void writeFakeInputconf(QIODevice *device) { // Query list of supported keys QProcess p; p.start(m_mplayerPath, QStringList("-input") += "keylist"); if (!p.waitForStarted()) { return; } if (!p.waitForFinished()) { return; } QStringList keys = QString(p.readAll()).split("\n", QString::SkipEmptyParts); // Write dummy command for each key QTextStream out(device); for (int i = 0; i < keys.count(); i++) { keys[i].remove("\r"); out << keys[i] << " " << "ignored" << endl; } } public: QMPwidget::State m_state; QString m_mplayerPath; QString m_videoOutput; QString m_pipe; QMPwidget::Mode m_mode; QMPwidget::MediaInfo m_mediaInfo; double m_streamPosition; // This is the video position QTimer m_movieFinishedTimer; QString m_currentTag; QTemporaryFile *m_fakeInputconf; #ifdef QMP_USE_YUVPIPE QPointer m_yuvReader; #endif }; // Initialize the media info structure QMPwidget::MediaInfo::MediaInfo() : videoBitrate(0), framesPerSecond(0), sampleRate(0), numChannels(0), ok(false), length(0), seekable(false) { } /*! * \brief Constructor * * \param parent Parent widget */ QMPwidget::QMPwidget(QWidget *parent) : QWidget(parent) { setFocusPolicy(Qt::StrongFocus); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); #ifdef QT_OPENGL_LIB m_widget = new QMPOpenGLVideoWidget(this); #else m_widget = new QMPPlainVideoWidget(this); #endif QPalette p = palette(); p.setColor(QPalette::Window, Qt::black); setPalette(p); m_seekTimer.setInterval(50); m_seekTimer.setSingleShot(true); connect(&m_seekTimer, SIGNAL(timeout()), this, SLOT(delayedSeek())); m_process = new QMPProcess(this); connect(m_process, SIGNAL(stateChanged(int)), this, SLOT(mpStateChanged(int))); connect(m_process, SIGNAL(streamPositionChanged(double)), this, SLOT(mpStreamPositionChanged(double))); connect(m_process, SIGNAL(error(const QString &)), this, SIGNAL(error(const QString &))); connect(m_process, SIGNAL(readStandardOutput(const QString &)), this, SIGNAL(readStandardOutput(const QString &))); connect(m_process, SIGNAL(readStandardError(const QString &)), this, SIGNAL(readStandardError(const QString &))); } /*! * \brief Destructor * \details * This function will ask the MPlayer process to quit and block until it has really * finished. */ QMPwidget::~QMPwidget() { if (m_process->processState() == QProcess::Running) { m_process->quit(); } delete m_process; } /*! * \brief Returns the current MPlayer process state * * \returns The process state */ QMPwidget::State QMPwidget::state() const { return m_process->m_state; } /*! * \brief Returns the current media info object * \details * Please check QMPwidget::MediaInfo::ok to make sure the media * information has been fully parsed. * * \returns The media info object */ QMPwidget::MediaInfo QMPwidget::mediaInfo() const { return m_process->m_mediaInfo; } /*! * \brief Returns the current playback position * * \returns The current playback position in seconds * \sa seek() */ double QMPwidget::tell() const { return m_process->m_streamPosition; } /*! * \brief Returns the MPlayer process * * \returns The MPlayer process */ QProcess *QMPwidget::process() const { return m_process; } /*! * \brief Sets the video playback mode * \details * Please see \ref playbackmodes for a discussion of the available modes. * * \param mode The video playback mode * \sa mode() */ void QMPwidget::setMode(Mode mode) { #ifdef QMP_USE_YUVPIPE m_process->m_mode = mode; #else Q_UNUSED(mode) #endif } /*! * \brief Returns the current video playback mode * * \returns The current video playback mode * \sa setMode() */ QMPwidget::Mode QMPwidget::mode() const { return m_process->m_mode; } /*! * \brief Sets the video output mode * \details * The video output mode string will be passed to MPlayer using its \p -vo option. * Please see http://www.mplayerhq.hu/DOCS/HTML/en/video.html for an overview of * available video output modes. * * Per default, this string will have the following values: * * * * * * * * * * * * * * * * * * * * * * * * * * * *
SystemConfigurationValue
Windows\p "directx,directx:noaccel"
X11Compiled without OpenGL support\p "xv"
X11Compiled with OpenGL support\p "gl2,gl,xv"
Mac OS XCompiled without OpenGL support\p "quartz"
Mac OS XCompiled with OpenGL support\p "gl,quartz"
* * * \param output The video output mode string * \sa videoOutput() */ void QMPwidget::setVideoOutput(const QString &output) { m_process->m_videoOutput = output; } /*! * \brief Returns the current video output mode * * \returns The current video output mode * \sa setVideoOutput() */ QString QMPwidget::videoOutput() const { return m_process->m_videoOutput; } /*! * \brief Sets the path to the MPlayer executable * \details * Per default, it is assumed the MPlayer executable is * available in the current OS path. Therefore, this value is * set to "mplayer". * * \param path Path to the MPlayer executable * \sa mplayerPath() */ void QMPwidget::setMPlayerPath(const QString &path) { m_process->m_mplayerPath = path; } /*! * \brief Returns the current path to the MPlayer executable * * \returns The path to the MPlayer executable * \sa setMPlayerPath() */ QString QMPwidget::mplayerPath() const { return m_process->m_mplayerPath; } /*! * \brief Returns the version string of the MPlayer executable * \details * If the mplayer * * * \returns The version string of the MPlayer executable */ QString QMPwidget::mplayerVersion() { return m_process->mplayerVersion(); } /*! * \brief Sets a seeking slider for this widget */ void QMPwidget::setSeekSlider(QAbstractSlider *slider) { if (m_seekSlider) { m_seekSlider->disconnect(this); disconnect(m_seekSlider); } if (m_process->m_mediaInfo.ok) { slider->setRange(0, m_process->m_mediaInfo.length); } if (m_process->m_mediaInfo.ok) { slider->setEnabled(m_process->m_mediaInfo.seekable); } connect(slider, SIGNAL(valueChanged(int)), this, SLOT(seek(int))); m_seekSlider = slider; } /*! * \brief Sets a volume slider for this widget */ void QMPwidget::setVolumeSlider(QAbstractSlider *slider) { if (m_volumeSlider) { m_volumeSlider->disconnect(this); disconnect(m_volumeSlider); } slider->setRange(0, 100); slider->setValue(100); // TODO connect(slider, SIGNAL(valueChanged(int)), this, SLOT(setVolume(int))); m_volumeSlider = slider; } /*! * \brief Shows a custom image * \details * This function sets a custom image that will be shown instead of the MPlayer * video output. In order to show MPlayer's output again, call this function * with a null image. * * \note If the current playback mode is not set to \p PipeMode, this function * will have no effect if MPlayer draws to the widget. * * \param image Custom image */ void QMPwidget::showImage(const QImage &image) { #ifdef QT_OPENGL_LIB qobject_cast(m_widget)->showUserImage(image); #else qobject_cast(m_widget)->showUserImage(image); #endif } /*! * \brief Returns a suitable size hint for this widget * \details * This function is used internally by Qt. */ QSize QMPwidget::sizeHint() const { if (m_process->m_mediaInfo.ok && !m_process->m_mediaInfo.size.isNull()) { return m_process->m_mediaInfo.size; } return QWidget::sizeHint(); } /*! * \brief Starts the MPlayer process with the given arguments * \details * If there's another process running, it will be terminated first. MPlayer * will be run in idle mode and is avaiting your commands, e.g. via load(). * * \param args MPlayer command line arguments */ void QMPwidget::start(const QStringList &args) { if (m_process->processState() == QProcess::Running) { m_process->quit(); } m_process->start(m_widget, args); } /*! * \brief Loads a file or url and starts playback * * \param url File patho or url */ void QMPwidget::load(const QString &url) { Q_ASSERT_X(m_process->state() != QProcess::NotRunning, "QMPwidget::load()", "MPlayer process not started yet"); // From the MPlayer slave interface documentation: // "Try using something like [the following] to switch to the next file. // It avoids audio playback starting to play the old file for a short time // before switching to the new one. writeCommand("pausing_keep_force pt_step 1"); writeCommand("get_property pause"); QString url_escaped = QString(url).replace("'", "\\'"); writeCommand(QString("loadfile '%1'").arg(url_escaped)); } /*! * \brief Resumes playback */ void QMPwidget::play() { if (m_process->m_state == PausedState) { m_process->pause(); } } /*! * \brief Pauses playback */ void QMPwidget::pause() { if (m_process->m_state == PlayingState) { m_process->pause(); } } /*! * \brief Stops playback */ void QMPwidget::stop() { m_process->stop(); } /*! * \brief Media playback seeking * * \param offset Seeking offset in seconds * \param whence Seeking mode * \returns \p true If the seeking mode is valid * \sa tell() */ bool QMPwidget::seek(int offset, int whence) { return seek(double(offset), whence); } /*! * \brief Media playback seeking * * \param offset Seeking offset in seconds * \param whence Seeking mode * \returns \p true If the seeking mode is valid * \sa tell() */ bool QMPwidget::seek(double offset, int whence) { m_seekTimer.stop(); // Cancel all current seek requests switch (whence) { case RelativeSeek: case PercentageSeek: case AbsoluteSeek: break; default: return false; } // Schedule seek request m_seekCommand = QString("seek %1 %2").arg(offset).arg(whence); m_seekTimer.start(); return true; } /*! * \brief Toggles full-screen mode */ void QMPwidget::toggleFullScreen() { if (!isFullScreen()) { m_windowFlags = windowFlags() & (Qt::Window); m_geometry = geometry(); setWindowFlags((windowFlags() | Qt::Window)); // From Phonon::VideoWidget #ifdef Q_WS_X11 show(); raise(); setWindowState(windowState() | Qt::WindowFullScreen); #else setWindowState(windowState() | Qt::WindowFullScreen); show(); #endif } else { setWindowFlags((windowFlags() ^ (Qt::Window)) | m_windowFlags); setWindowState(windowState() & ~Qt::WindowFullScreen); setGeometry(m_geometry); show(); } } /*! * \brief Sends a command to the MPlayer process * \details * Since MPlayer is being run in slave mode, it reads commands from the standard * input. It is assumed that the interface provided by this class might not be * sufficient for some situations, so you can use this functions to directly * control the MPlayer process. * * For a complete list of commands for MPlayer's slave mode, see * http://www.mplayerhq.hu/DOCS/tech/slave.txt . * * \param command The command line. A newline character will be added internally. */ void QMPwidget::writeCommand(const QString &command) { m_process->writeCommand(command); } /*! * \brief Mouse double click event handler * \details * This implementation will toggle full screen and accept the event * * \param event Mouse event */ void QMPwidget::mouseDoubleClickEvent(QMouseEvent *event) { toggleFullScreen(); event->accept(); } /*! * \brief Keyboard press event handler * \details * This implementation tries to resemble the classic MPlayer interface. For a * full list of supported key codes, see \ref shortcuts. * * \param event Key event */ void QMPwidget::keyPressEvent(QKeyEvent *event) { bool accept = true; switch (event->key()) { case Qt::Key_P: case Qt::Key_Space: if (state() == PlayingState) { pause(); } else if (state() == PausedState) { play(); } break; case Qt::Key_F: toggleFullScreen(); break; case Qt::Key_Q: case Qt::Key_Escape: stop(); break; case Qt::Key_Minus: writeCommand("audio_delay -0.1"); break; case Qt::Key_Plus: writeCommand("audio_delay 0.1"); break; case Qt::Key_Left: seek(-10, RelativeSeek); break; case Qt::Key_Right: seek(10, RelativeSeek); break; case Qt::Key_Down: seek(-60, RelativeSeek); break; case Qt::Key_Up: seek(60, RelativeSeek); break; case Qt::Key_PageDown: seek(-600, RelativeSeek); break; case Qt::Key_PageUp: seek(600, RelativeSeek); break; case Qt::Key_Asterisk: writeCommand("volume 10"); break; case Qt::Key_Slash: writeCommand("volume -10"); break; case Qt::Key_X: writeCommand("sub_delay 0.1"); break; case Qt::Key_Z: writeCommand("sub_delay -0.1"); break; default: accept = false; break; } event->setAccepted(accept); } /*! * \brief Resize event handler * \details * If you reimplement this function, you need to call this handler, too. * * \param event Resize event */ void QMPwidget::resizeEvent(QResizeEvent *event) { Q_UNUSED(event); updateWidgetSize(); } void QMPwidget::updateWidgetSize() { if (!m_process->m_mediaInfo.size.isNull()) { QSize mediaSize = m_process->m_mediaInfo.size; QSize widgetSize = size(); double factor = qMin(double(widgetSize.width()) / mediaSize.width(), double(widgetSize.height()) / mediaSize.height()); QRect wrect(0, 0, int(factor * mediaSize.width() + 0.5), int(factor * mediaSize.height())); wrect.moveTopLeft(rect().center() - wrect.center()); m_widget->setGeometry(wrect); } else { m_widget->setGeometry(QRect(QPoint(0, 0), size())); } } void QMPwidget::delayedSeek() { if (!m_seekCommand.isEmpty()) { writeCommand(m_seekCommand); m_seekCommand = QString(); } } void QMPwidget::setVolume(int volume) { writeCommand(QString("volume %1 1").arg(volume)); } void QMPwidget::mpStateChanged(int state) { if (m_seekSlider != NULL && state == PlayingState && m_process->m_mediaInfo.ok) { m_seekSlider->setRange(0, m_process->m_mediaInfo.length); m_seekSlider->setEnabled(m_process->m_mediaInfo.seekable); } updateWidgetSize(); emit stateChanged(state); } void QMPwidget::mpStreamPositionChanged(double position) { if (m_seekSlider != NULL && m_seekCommand.isEmpty() && m_seekSlider->value() != qRound(position)) { m_seekSlider->disconnect(this); m_seekSlider->setValue(qRound(position)); connect(m_seekSlider, SIGNAL(valueChanged(int)), this, SLOT(seek(int))); } } void QMPwidget::mpVolumeChanged(int volume) { if (m_volumeSlider != NULL) { m_volumeSlider->disconnect(this); m_volumeSlider->setValue(volume); connect(m_seekSlider, SIGNAL(valueChanged(int)), this, SLOT(setVolume(int))); } } #include "qmpwidget.moc" /* Documentation follows */ /*! * \class QMPwidget * \brief A Qt widget for embedding MPlayer * \details * * \section Overview * * \subsection comm MPlayer communication * * If you want to communicate with MPlayer through its * slave mode protocol, * you can use the writeCommand() slot. If MPlayer writes to its standard output * or standard error channel, the signals readStandardOutput() and * readStandardError() will be emitted. * * \subsection controls Graphical controls * * You can connect sliders for seeking and volume adjustment to an instance of * this class. Please use setSeekSlider() and setVolumeSlider(), respectively. * * \section example Usage example * * A minimal example using this widget to play a low-res version of * Big Buck Bunny might look as follows. * Please note that the actual movie URL has been shortened for the sake of clarity. \code #include #include "qmpwidget.h" // Program entry point int main(int argc, char **argv) { QApplication app(argc, argv); QMPwidget widget; widget.show(); widget.start(QStringList("http://tinyurl.com/2vs2kg5")); return app.exec(); } \endcode * * * For further information about this project, please refer to the * main page. */ /*! * \enum QMPwidget::State * \brief MPlayer state * \details * This enumeration is somewhat identical to * Phonon's State enumeration, except that it has an additional * member which is used when the MPlayer process has not been started yet (NotStartedState) * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
ConstantValueDescription
\p QMPwidget::NotStartedState\p -1The Mplayer process has not been started yet or has already terminated.
\p QMPwidget::IdleState\p 0The MPlayer process has been started, but is idle and waiting for commands.
\p QMPwidget::LoadingState\p 1The media file is being loaded, but playback has not been started yet.
\p QMPwidget::StoppedState\p 2This constant is deprecated and is not being used
\p QMPwidget::PlayingState\p 3
\p QMPwidget::BufferingState\p 4
\p QMPwidget::PausedState\p 5
\p QMPwidget::ErrorState\p 6
*/ /*! * \enum QMPwidget::Mode * \brief Video playback modes * \details * This enumeration describes valid modes for video playback. Please see \ref playbackmodes for a * detailed description of both modes. * * * * * * * * * * * * * *
ConstantValueDescription
\p QMPwidget::EmbeddedMode\p 0MPlayer will render directly into a Qt widget.
\p QMPwidget::PipedMode\p 1MPlayer will write the video data into a FIFO which will be parsed in a seperate thread.\n The frames will be rendered by QMPwidget.
*/ /*! * \enum QMPwidget::SeekMode * \brief Seeking modes * \details * This enumeration describes valid modes for seeking the media stream. * * * * * * * * * * * * * * * * * * *
ConstantValueDescription
\p QMPwidget::RelativeSeek\p 0Relative seek in seconds
\p QMPwidget::PercantageSeek\p 1Seek to a position given by a percentage of the whole movie duration
\p QMPwidget::AbsoluteSeek\p 2Seek to a position given by an absolute time
*/ /*! * \fn void QMPwidget::stateChanged(int state) * \brief Emitted if the state has changed * \details * This signal is emitted when the state of the MPlayer process changes. * * \param state The new state */ /*! * \fn void QMPwidget::error(const QString &reason) * \brief Emitted if the state has changed to QMPwidget::ErrorState * \details * This signal is emitted when the state of the MPlayer process changes to QMPwidget::ErrorState. * * \param reason Textual error description (may be empty) */ /*! * \fn void QMPwidget::readStandardOutput(const QString &line) * \brief Signal for reading MPlayer's standard output * \details * This signal is emitted when MPlayer wrote a line of text to its standard output channel. */ /*! * \fn void QMPwidget::readStandardError(const QString &line) * \brief Signal for reading MPlayer's standard error * \details * This signal is emitted when MPlayer wrote a line of text to its standard error channel. */ qwinff-master/src/qmpwidget/qmpwidget.h000066400000000000000000000071521347323557400206250ustar00rootroot00000000000000/* * qmpwidget - A Qt widget for embedding MPlayer * Copyright (C) 2010 by Jonas Gehring * * 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 . */ #ifndef QMPWIDGET_H_ #define QMPWIDGET_H_ #include #include #include #include class QAbstractSlider; class QImage; class QProcess; class QStringList; class QMPProcess; class QMPwidget : public QWidget { Q_OBJECT Q_PROPERTY(State state READ state); Q_PROPERTY(double streamPosition READ tell); Q_PROPERTY(QString videoOutput READ videoOutput WRITE setVideoOutput); Q_PROPERTY(QString mplayerPath READ mplayerPath WRITE setMPlayerPath); Q_PROPERTY(QString mplayerVersion READ mplayerVersion); Q_ENUMS(state); public: enum State { NotStartedState = -1, IdleState, LoadingState, StoppedState, PlayingState, BufferingState, PausedState, ErrorState }; struct MediaInfo { QString videoFormat; int videoBitrate; QSize size; double framesPerSecond; QString audioFormat; double audioBitrate; int sampleRate; int numChannels; QHash tags; bool ok; double length; bool seekable; MediaInfo(); }; enum Mode { EmbeddedMode = 0, PipeMode }; enum SeekMode { RelativeSeek = 0, PercentageSeek, AbsoluteSeek }; public: QMPwidget(QWidget *parent = 0); virtual ~QMPwidget(); State state() const; MediaInfo mediaInfo() const; double tell() const; QProcess *process() const; void setMode(Mode mode); Mode mode() const; void setVideoOutput(const QString &output); QString videoOutput() const; void setMPlayerPath(const QString &path); QString mplayerPath() const; QString mplayerVersion(); void setSeekSlider(QAbstractSlider *slider); void setVolumeSlider(QAbstractSlider *slider); void showImage(const QImage &image); virtual QSize sizeHint() const; public slots: void start(const QStringList &args = QStringList()); void load(const QString &url); void play(); void pause(); void stop(); bool seek(int offset, int whence = AbsoluteSeek); bool seek(double offset, int whence = AbsoluteSeek); void toggleFullScreen(); void writeCommand(const QString &command); protected: virtual void mouseDoubleClickEvent(QMouseEvent *event); virtual void keyPressEvent(QKeyEvent *event); virtual void resizeEvent(QResizeEvent *event); private: void updateWidgetSize(); private slots: void setVolume(int volume); void mpStateChanged(int state); void mpStreamPositionChanged(double position); void mpVolumeChanged(int volume); void delayedSeek(); signals: void stateChanged(int state); void error(const QString &reason); void readStandardOutput(const QString &line); void readStandardError(const QString &line); private: QMPProcess *m_process; QWidget *m_widget; QPointer m_seekSlider; QPointer m_volumeSlider; Qt::WindowFlags m_windowFlags; QRect m_geometry; QTimer m_seekTimer; QString m_seekCommand; }; #endif // QMPWIDGET_H_ qwinff-master/src/qmpwidget/qmpyuvreader.h000066400000000000000000000172221347323557400213470ustar00rootroot00000000000000/* * qmpwidget - A Qt widget for embedding MPlayer * Copyright (C) 2010 by Jonas Gehring * * 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 . */ #include #include #include #include #ifdef Q_WS_WIN #include "windows.h" #endif #include #include // Internal YUV pipe reader class QMPYuvReader : public QThread { Q_OBJECT public: // Constructor QMPYuvReader(QObject *parent = 0) : QThread(parent), m_stop(false), m_saveme(NULL), m_savemeSize(-1) { QString tdir = QDir::tempPath(); // Create pipe in a temporary directory char *temp = new char[tdir.length() + 12]; strcpy(temp, tdir.toLocal8Bit().data()); strcat(temp, "/XXXXXX"); if (mkdtemp(temp) == NULL) { qWarning("Can't create temporary directory"); return; } strcat(temp, "/fifo"); if (mkfifo(temp, 0600) != 0) { qWarning("Can't create pipe"); return; } m_pipe = QString(temp); delete[] temp; initTables(); } // Destructor ~QMPYuvReader() { delete[] m_saveme; if (!m_pipe.isEmpty()) { QFile::remove(m_pipe); QDir().rmdir(QFileInfo(m_pipe).dir().path()); } } // Tells the thread to stop and exit void stop() { m_mutex.lock(); m_stop = true; m_mutex.unlock(); wait(); } protected: // Main thread loop void run() { FILE *f = fopen(m_pipe.toLocal8Bit().data(), "rb"); if (f == NULL) { qWarning("Can't open pipe"); return; } // Parse stream header char c; int width, height, fps, t1, t2; int n = fscanf(f, "YUV4MPEG2 W%d H%d F%d:1 I%c A%d:%d", &width, &height, &fps, &c, &t1, &t2); if (n < 3) { fclose(f); qWarning("Unsupported pipe format"); return; } unsigned char *yuv[3]; yuv[0] = new unsigned char[width * height]; yuv[1] = new unsigned char[width * height]; yuv[2] = new unsigned char[width * height]; QImage image(width, height, QImage::Format_ARGB32); // Read frames const unsigned int ysize = width * height; const unsigned int csize = width * height / 4; while (true) { m_mutex.lock(); if (m_stop) { m_mutex.unlock(); break; } m_mutex.unlock(); if (fread(yuv[0], 1, 6, f) != 6) { goto ioerror; } if (fread(yuv[0], 1, ysize, f) != ysize) { goto ioerror; } if (fread(yuv[1], 1, csize, f) != csize) { goto ioerror; } if (fread(yuv[2], 1, csize, f) != csize) { goto ioerror; } supersample(yuv[1], width, height); supersample(yuv[2], width, height); yuvToQImage(yuv, &image, width, height); emit imageReady(image); continue; ioerror: qWarning("I/O error reading from pipe"); break; } delete[] yuv[0]; delete[] yuv[1]; delete[] yuv[2]; fclose(f); } // 420 to 444 supersampling (from mjpegtools) void supersample(unsigned char *buffer, int width, int height) { unsigned char *inm, *in0, *inp, *out0, *out1; unsigned char cmm, cm0, cmp, c0m, c00, c0p, cpm, cp0, cpp; int x, y; if (m_saveme == NULL || width > m_savemeSize) { delete[] m_saveme; m_savemeSize = width; m_saveme = new unsigned char[m_savemeSize]; } memcpy(m_saveme, buffer, width); in0 = buffer + (width * height / 4) - 2; inm = in0 - width/2; inp = in0 + width/2; out1 = buffer + (width * height) - 1; out0 = out1 - width; for (y = height; y > 0; y -= 2) { if (y == 2) { in0 = m_saveme + width/2 - 2; inp = in0 + width/2; } for (x = width; x > 0; x -= 2) { cmm = ((x == 2) || (y == 2)) ? in0[1] : inm[0]; cm0 = (y == 2) ? in0[1] : inm[1]; cmp = ((x == width) || (y == 2)) ? in0[1] : inm[2]; c0m = (x == 2) ? in0[1] : in0[0]; c00 = in0[1]; c0p = (x == width) ? in0[1] : in0[2]; cpm = ((x == 2) || (y == height)) ? in0[1] : inp[0]; cp0 = (y == height) ? in0[1] : inp[1]; cpp = ((x == width) || (y == height)) ? in0[1] : inp[2]; inm--; in0--; inp--; *(out1--) = (1*cpp + 3*(cp0+c0p) + 9*c00 + 8) >> 4; *(out1--) = (1*cpm + 3*(cp0+c0m) + 9*c00 + 8) >> 4; *(out0--) = (1*cmp + 3*(cm0+c0p) + 9*c00 + 8) >> 4; *(out0--) = (1*cmm + 3*(cm0+c0m) + 9*c00 + 8) >> 4; } out1 -= width; out0 -= width; } } // Converts YCbCr data to a QImage void yuvToQImage(unsigned char *planes[], QImage *dest, int width, int height) { unsigned char *yptr = planes[0]; unsigned char *cbptr = planes[1]; unsigned char *crptr = planes[2]; // This is partly from mjpegtools for (int y = 0; y < height; y++) { QRgb *dptr = (QRgb *)dest->scanLine(y); for (int x = 0; x < width; x++) { *dptr = qRgb(qBound(0, (RGB_Y[*yptr] + R_Cr[*crptr]) >> 18, 255), qBound(0, (RGB_Y[*yptr] + G_Cb[*cbptr]+ G_Cr[*crptr]) >> 18, 255), qBound(0, (RGB_Y[*yptr] + B_Cb[*cbptr]) >> 18, 255)); ++yptr; ++cbptr; ++crptr; ++dptr; } } } // Rounding towards zero inline int zround(double n) { if (n >= 0) { return (int)(n + 0.5); } else { return (int)(n - 0.5); } } // Initializes the YCbCr -> RGB conversion tables (again, from mjpegtools) void initTables(void) { /* clip Y values under 16 */ for (int i = 0; i < 16; i++) { RGB_Y[i] = zround((1.0 * (double)(16 - 16) * 255.0 / 219.0 * (double)(1<<18)) + (double)(1<<(18-1))); } for (int i = 16; i < 236; i++) { RGB_Y[i] = zround((1.0 * (double)(i - 16) * 255.0 / 219.0 * (double)(1<<18)) + (double)(1<<(18-1))); } /* clip Y values above 235 */ for (int i = 236; i < 256; i++) { RGB_Y[i] = zround((1.0 * (double)(235 - 16) * 255.0 / 219.0 * (double)(1<<18)) + (double)(1<<(18-1))); } /* clip Cb/Cr values below 16 */ for (int i = 0; i < 16; i++) { R_Cr[i] = zround(1.402 * (double)(-112) * 255.0 / 224.0 * (double)(1<<18)); G_Cr[i] = zround(-0.714136 * (double)(-112) * 255.0 / 224.0 * (double)(1<<18)); G_Cb[i] = zround(-0.344136 * (double)(-112) * 255.0 / 224.0 * (double)(1<<18)); B_Cb[i] = zround(1.772 * (double)(-112) * 255.0 / 224.0 * (double)(1<<18)); } for (int i = 16; i < 241; i++) { R_Cr[i] = zround(1.402 * (double)(i - 128) * 255.0 / 224.0 * (double)(1<<18)); G_Cr[i] = zround(-0.714136 * (double)(i - 128) * 255.0 / 224.0 * (double)(1<<18)); G_Cb[i] = zround(-0.344136 * (double)(i - 128) * 255.0 / 224.0 * (double)(1<<18)); B_Cb[i] = zround(1.772 * (double)(i - 128) * 255.0 / 224.0 * (double)(1<<18)); } /* clip Cb/Cr values above 240 */ for (int i = 241; i < 256; i++) { R_Cr[i] = zround(1.402 * (double)(112) * 255.0 / 224.0 * (double)(1<<18)); G_Cr[i] = zround(-0.714136 * (double)(112) * 255.0 / 224.0 * (double)(1<<18)); G_Cb[i] = zround(-0.344136 * (double)(i - 128) * 255.0 / 224.0 * (double)(1<<18)); B_Cb[i] = zround(1.772 * (double)(112) * 255.0 / 224.0 * (double)(1<<18)); } } signals: void imageReady(const QImage &image); public: QString m_pipe; private: QMutex m_mutex; bool m_stop; // Conversion tables int RGB_Y[256]; int R_Cr[256]; int G_Cb[256]; int G_Cr[256]; int B_Cb[256]; // Temporary buffers unsigned char *m_saveme; int m_savemeSize; }; qwinff-master/src/qwinff.pro000066400000000000000000000130571347323557400164670ustar00rootroot00000000000000#------------------------------------------------- # # Project created by QtCreator 2011-06-25T12:27:54 # #------------------------------------------------- QT += core gui network opengl TARGET = qwinff TEMPLATE = app SOURCES += main.cpp \ ui/progressbar.cpp \ ui/mainwindow.cpp \ ui/convertlist.cpp \ ui/conversionparameterdialog.cpp \ ui/addtaskwizard.cpp \ ui/aboutffmpegdialog.cpp \ ui/optionsdialog.cpp \ ui/aboutdialog.cpp \ ui/poweroffdialog.cpp \ ui/rangeselector.cpp \ ui/timerangeedit.cpp \ converter/presets.cpp \ converter/mediaprobe.cpp \ converter/mediaconverter.cpp \ converter/ffmpeginterface.cpp \ converter/converterinterface.cpp \ converter/conversionparameters.cpp \ services/paths.cpp \ services/extensions.cpp \ services/filepathoperations.cpp \ services/notification.cpp \ services/notificationservice.cpp \ services/notificationservice-qt.cpp \ services/notificationservice-notifysend.cpp \ services/powermanagement-dummy.cpp \ converter/audiofilter.cpp \ converter/exepath.cpp \ services/versioncompare.cpp \ services/updatechecker.cpp \ services/httpdownloader.cpp \ services/updateinfoparser.cpp \ services/constants.cpp \ services/xmllookuptable.cpp \ ui/updatedialog.cpp \ services/settingtimer.cpp \ services/ffplaypreviewer.cpp \ services/abstractpreviewer.cpp \ services/mplayerpreviewer.cpp \ ui/previewdialog.cpp \ ui/interactivecuttingdialog.cpp \ ui/myqmpwidget.cpp \ ui/mediaplayerwidget.cpp \ ui/rangewidgetbinder.cpp HEADERS += \ ui/progressbar.h \ ui/mainwindow.h \ ui/convertlist.h \ ui/conversionparameterdialog.h \ ui/addtaskwizard.h \ ui/aboutffmpegdialog.h \ ui/optionsdialog.h \ ui/aboutdialog.h \ ui/poweroffdialog.h \ ui/rangeselector.h \ ui/timerangeedit.h \ converter/presets.h \ converter/mediaprobe.h \ converter/mediaconverter.h \ converter/ffmpeginterface.h \ converter/converterinterface.h \ converter/conversionparameters.h \ services/paths.h \ services/extensions.h \ services/filepathoperations.h \ version.h \ services/notification.h \ services/notificationservice.h \ services/notificationservice-qt.h \ services/notificationservice-notifysend.h \ services/powermanagement.h \ converter/audiofilter.h \ converter/exepath.h \ extra-translations.h \ services/versioncompare.h \ services/updatechecker.h \ services/httpdownloader.h \ services/updateinfoparser.h \ services/constants.h \ services/xmllookuptable.h \ ui/updatedialog.h \ services/settingtimer.h \ services/ffplaypreviewer.h \ services/abstractpreviewer.h \ services/mplayerpreviewer.h \ ui/previewdialog.h \ ui/interactivecuttingdialog.h \ ui/mediaplayerwidget.h \ ui/myqmpwidget.h \ ui/rangewidgetbinder.h FORMS += \ ui/conversionparameterdialog.ui \ ui/addtaskwizard.ui \ ui/mainwindow.ui \ ui/aboutffmpegdialog.ui \ ui/optionsdialog.ui \ ui/aboutdialog.ui \ ui/poweroffdialog.ui \ ui/updatedialog.ui \ ui/previewdialog.ui \ ui/interactivecuttingdialog.ui \ ui/mediaplayerwidget.ui RESOURCES += \ images.qrc TRANSLATIONS += \ translations/qwinff_zh_TW.ts \ translations/qwinff_ja_JP.ts \ translations/qwinff_it_IT.ts \ translations/qwinff_cs_CZ.ts \ translations/qwinff_zh_CN.ts \ translations/qwinff_ru.ts \ translations/qwinff_es_ES.ts \ translations/qwinff_es_GT.ts \ translations/qwinff_ro_RO.ts \ translations/qwinff_de.ts \ translations/qwinff_tr_TR.ts \ translations/qwinff_ar.ts \ translations/qwinff_hu_HU.ts \ translations/qwinff_pl_PL.ts \ translations/qwinff_pt_BR.ts \ translations/qwinff_fr.ts INCLUDEPATH += . unix { # If DATA_PATH is set, QWinFF searches data in DATA_PATH # Otherwise, it uses the executable path as data path. DEFINES += DATA_PATH=$(DATA_PATH) libnotify { # Linux desktop notification HEADERS += \ services/notificationservice-libnotify.h SOURCES += \ services/notificationservice-libnotify.cpp # pkgconfig CONFIG += link_pkgconfig PKGCONFIG = libnotify DEFINES += USE_LIBNOTIFY } # Shutdown QT += dbus SOURCES -= services/powermanagement-dummy.cpp SOURCES += services/powermanagement-linux.cpp } win32 { # If TOOLS_IN_DATA_PATH is set, QWinFF searches for FFmpeg executables # in /tools/ instead of PATH. DEFINES += TOOLS_IN_DATA_PATH # Application Icon RC_FILE = appicon.rc # Shutdown LIBS += -lpowrprof SOURCES -= services/powermanagement-dummy.cpp SOURCES += services/powermanagement-w32.cpp } os2 { # Application Icon RC_FILE = appicon_os2.rc # Shutdown not yet implemented on OS/2 Warp # When it is done, uncomment following lines and do proper modifications #LIBS += #SOURCES -= services/powermanagement-dummy.cpp #SOURCES += services/powermanagement-os2.cpp } # This string is shown in the about box. DEFINES += VERSION_ID_STRING=$(VERSION_ID_STRING) # External Short Blocking Operation Timeout DEFINES += OPERATION_TIMEOUT=30000 DEFINES += DEFAULT_THREAD_COUNT=1 # QMPwidget (embedded mplayer) SOURCES += qmpwidget/qmpwidget.cpp HEADERS += qmpwidget/qmpwidget.h INCLUDEPATH += qmpwidget #CONFIG += qmpwidget_pipemode !win32:qmpwidget_pipemode: { HEADERS += qmpwidget/qmpyuvreader.h DEFINES += QMP_USE_YUVPIPE } OTHER_FILES += qwinff-master/src/services/000077500000000000000000000000001347323557400162705ustar00rootroot00000000000000qwinff-master/src/services/abstractpreviewer.cpp000066400000000000000000000016341347323557400225340ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "abstractpreviewer.h" AbstractPreviewer::AbstractPreviewer(QObject *parent) : QObject(parent) { } AbstractPreviewer::~AbstractPreviewer() { } qwinff-master/src/services/abstractpreviewer.h000066400000000000000000000034231347323557400221770ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef ABSTRACTPREVIEWER_H #define ABSTRACTPREVIEWER_H #include class AbstractPreviewer : public QObject { Q_OBJECT public: explicit AbstractPreviewer(QObject *parent = 0); virtual ~AbstractPreviewer(); /** @brief Determine whether this previewer can play files. */ virtual bool available() const = 0; /** @brief Play the media file named @a filename. * * This function must be asynchronous, i.e. it must return * immediately without waiting for the player to exit. */ virtual void play(const QString& filename) = 0; /** @brief Play a portion of the file from @a t_begin to @a t_end (seconds). * * @see play(const QString&) */ virtual void play(const QString &filename, int t_begin, int t_end) = 0; virtual void playFrom(const QString &filename, int t_begin) = 0; virtual void playUntil(const QString &filename, int t_end) = 0; virtual void stop() = 0; private: Q_DISABLE_COPY(AbstractPreviewer) }; #endif // ABSTRACTPREVIEWER_H qwinff-master/src/services/constants.cpp000066400000000000000000000065471347323557400210240ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include #include #include "constants.h" #include "xmllookuptable.h" #define REGEXP_HEXDIGIT "[0-9a-fA-F]" namespace { bool constants_initialized = false; XmlLookupTable constants; QString color_pattern(QString("#(%1%1)(%1%1)(%1%1)(%1%1)?").arg(REGEXP_HEXDIGIT)); QString lookup_constant(const QString& key) { bool ok; QString result = constants.lookup(key, &ok); if (!ok) qWarning() << "Constants: lookup undefined key " << key; return result; } int hex2int(const QString& hex_str) { QString qualified_str = QString("0x%1").arg(hex_str); bool ok; int value = qualified_str.toInt(&ok, 16); if (ok) return value; else return 0; } QColor str2color(const QString& color_str) { QRegExp color(color_pattern); if (color.indexIn(color_str) >= 0) { int r_value = hex2int(color.cap(1)); int g_value = hex2int(color.cap(2)); int b_value = hex2int(color.cap(3)); int a_value = 0xff; if (!color.cap(4).isEmpty()) // with alpha value a_value = hex2int(color.cap(4)); return QColor(r_value, g_value, b_value, a_value); } else { return QColor(0, 0, 0); // default black } } } bool Constants::readFile(QFile &file) { constants.clear(); constants_initialized = false; if (constants.readFile(file)) { constants_initialized = true; constants.setPrefix("QWinFFConstants"); } return constants_initialized; } bool Constants::getBool(const char *key) { Q_ASSERT(constants_initialized); QString value = lookup_constant(key).trimmed().toLower(); if (value.isEmpty() || value == "0" || value == "false") return false; else return true; } int Constants::getInteger(const char *key) { Q_ASSERT(constants_initialized); return lookup_constant(key).toInt(); } float Constants::getFloat(const char *key) { Q_ASSERT(constants_initialized); return lookup_constant(key).toFloat(); } QString Constants::getString(const char *key) { Q_ASSERT(constants_initialized); return lookup_constant(key).trimmed(); } QStringList Constants::getSpaceSeparatedList(const char *key) { Q_ASSERT(constants_initialized); QString collapsed_string = lookup_constant(key).replace(QRegExp("[\n\t ]"), " "); return collapsed_string.split(" ", QString::SkipEmptyParts); } QColor Constants::getColor(const char *key) { Q_ASSERT(constants_initialized); return str2color(lookup_constant(key)); } qwinff-master/src/services/constants.h000066400000000000000000000024471347323557400204640ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef CONSTANTS_H #define CONSTANTS_H #include #include #include class Constants { public: static bool readFile(QFile& file); static bool getBool(const char *key); static int getInteger(const char *key); static float getFloat(const char *key); static QString getString(const char *key); static QStringList getSpaceSeparatedList(const char *key); static QColor getColor(const char *key); private: Constants(); ~Constants(); Q_DISABLE_COPY(Constants) }; #endif // CONSTANTS_H qwinff-master/src/services/extensions.cpp000066400000000000000000000035501347323557400211760ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ /* This file is taken from smplayer */ #include "extensions.h" #include "constants.h" ExtensionList::ExtensionList() : QStringList() { } QString ExtensionList::forFilter() { QString s; for (int n=0; n < count(); n++) { s = s + "*." + at(n) + " "; } if (!s.isEmpty()) s = "(" + s + ")"; return s; } QString ExtensionList::forRegExp() { QString s; for (int n=0; n < count(); n++) { if (!s.isEmpty()) s = s + "|"; s = s + "^" + at(n) + "$"; } return s; } Extensions::Extensions() { QStringList video_exts = Constants::getSpaceSeparatedList("VideoExtensions"); QStringList audio_exts = Constants::getSpaceSeparatedList("AudioExtensions"); foreach (QString ext, video_exts) _video << ext; foreach (QString ext, audio_exts) _audio << ext; // multimedia = union of video and audio _multimedia = _video; foreach (QString ext, audio_exts) { if (!_multimedia.contains(ext)) _multimedia << ext; } } Extensions::~Extensions() { } bool Extensions::contains(const QString &ext) const { return _multimedia.contains(ext, Qt::CaseInsensitive); } qwinff-master/src/services/extensions.h000066400000000000000000000025101347323557400206360ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ /* This file is taken from smplayer. */ #ifndef _EXTENSIONS_H_ #define _EXTENSIONS_H_ #include class ExtensionList : public QStringList { public: ExtensionList(); QString forFilter(); QString forRegExp(); }; class Extensions { public: Extensions(); ~Extensions(); ExtensionList video() { return _video; }; ExtensionList audio() { return _audio; }; ExtensionList multimedia() { return _multimedia; }; bool contains(const QString& ext) const; protected: ExtensionList _video, _audio; ExtensionList _multimedia; //!< video and audio }; #endif qwinff-master/src/services/ffplaypreviewer.cpp000066400000000000000000000065231347323557400222140ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "ffplaypreviewer.h" #include "converter/exepath.h" #include #include #ifdef OPERATION_TIMEOUT # define TIMEOUT OPERATION_TIMEOUT #else # define TIMEOUT 3000 #endif #define DEFAULT_WIDTH 320 #define DEFAULT_HEIGHT 180 FFplayPreviewer::FFplayPreviewer(QObject *parent) : AbstractPreviewer(parent), m_proc(new QProcess), m_w(DEFAULT_WIDTH), m_h(DEFAULT_HEIGHT) { } FFplayPreviewer::~FFplayPreviewer() { delete m_proc; } bool FFplayPreviewer::available() const { return FFplayAvailable(); } void FFplayPreviewer::play(const QString &filename) { ffplay_start(filename, -1, -1); } void FFplayPreviewer::play(const QString &filename, int t_begin, int t_end) { ffplay_start(filename, t_begin, t_end); } void FFplayPreviewer::playFrom(const QString &filename, int t_begin) { ffplay_start(filename, t_begin, -1); } void FFplayPreviewer::playUntil(const QString &filename, int t_end) { ffplay_start(filename, -1, t_end); } void FFplayPreviewer::stop() { if (m_proc->state() != QProcess::NotRunning) { m_proc->kill(); m_proc->waitForFinished(TIMEOUT); } } void FFplayPreviewer::setWindowSize(int w, int h) { m_w = w; m_h = h; } void FFplayPreviewer::setWindowTitle(QString str) { m_title = str; } bool FFplayPreviewer::FFplayAvailable() { QProcess proc; QStringList param; /* test whether ffplay could be invoked */ proc.start(ExePath::getPath("ffplay"), param); if (!proc.waitForStarted(TIMEOUT)) return false; proc.kill(); proc.waitForFinished(TIMEOUT); return true; } /* If t_begin >= 0, start from t_begin; otherwise, start from time zero. If t_end >= 0, stop at t_end; othersize, play until end of file. */ void FFplayPreviewer::ffplay_start(const QString& filename, int t_begin, int t_end) { QStringList param; stop(); param.append("-autoexit"); param.append("-x"); param.append(QString::number(m_w)); param.append("-y"); param.append(QString::number(m_h)); if (!m_title.isEmpty()) param.append("-window_title"), param.append(m_title); if (t_begin >= 0) param.append("-ss"), param.append(QString::number(t_begin)); if (t_end >= 0) { param.append("-t"); // duration if (t_begin >= 0) param.append(QString::number(t_end - t_begin)); // duration = end - begin else param.append(QString::number(t_end)); // start from time zero } param.append(filename); qDebug() << "ffplay" << param.join(" "); m_proc->start(ExePath::getPath("ffplay"), param); m_proc->waitForStarted(TIMEOUT); } qwinff-master/src/services/ffplaypreviewer.h000066400000000000000000000037311347323557400216570ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef FFPLAYPREVIEWER_H #define FFPLAYPREVIEWER_H #include "abstractpreviewer.h" class QProcess; class FFplayPreviewer : public AbstractPreviewer { Q_OBJECT public: explicit FFplayPreviewer(QObject *parent = 0); virtual ~FFplayPreviewer(); bool available() const; /** Play the media file with ffplay. * If a media file is being played, it will be stopped before * playing the new one. */ void play(const QString& filename); void play(const QString &filename, int t_begin, int t_end); void playFrom(const QString &filename, int t_begin); void playUntil(const QString &filename, int t_end); void stop(); /** Set the window size of ffplay. * This option takes effect after invoking start() again. */ void setWindowSize(int w, int h); /** Set the ffplay window title. * This option takes effect after invoking start() again. * If str is empty, default title is displayed (filename). */ void setWindowTitle(QString str); static bool FFplayAvailable(); signals: public slots: private: QProcess *m_proc; int m_w, m_h; QString m_title; void ffplay_start(const QString&, int, int); }; #endif // FFPLAYPREVIEWER_H qwinff-master/src/services/filepathoperations.cpp000066400000000000000000000051421347323557400226760ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "filepathoperations.h" #include FilePathOperations::FilePathOperations() { } QString FilePathOperations::GenerateUniqueFileName(const QDir& output_dir, const QString& input_file_basename , const QString& ext, const QHash& extra) { int filename_index = 1; QString result; do { // The index part of the file QString str_index(""); if (filename_index > 1) { // If the index is larger than 1, append -index to the filename. str_index = QString("-%1").arg(filename_index); } // Fill in output filename. result = output_dir.absoluteFilePath(input_file_basename) // filename + str_index // index + '.' // point + ext; // extension ++filename_index; } while (QFileInfo(result).exists() || extra.contains(result)); // If file(n) exists, try file(n+1). return result; } QString FilePathOperations::GenerateUniqueFileName(const QString &filename, const QHash& extra) { QDir dir = QFileInfo(filename).dir(); QString basename = QFileInfo(filename).completeBaseName(); QString ext = QFileInfo(filename).suffix(); return GenerateUniqueFileName(dir, basename, ext, extra); } QString FilePathOperations::GenerateTempFileName(const QString& filename) { QString result; do { // Generate temporary file name. result = QString("%1-%2-temp-%3.%4").arg(filename) .arg(qrand()).arg(QCoreApplication::applicationPid()) .arg(QFileInfo(filename).suffix()); } while (QFileInfo(result).exists()); // Regenerate if exists. return result; } qwinff-master/src/services/filepathoperations.h000066400000000000000000000032741347323557400223470ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef FILEPATHOPERATIONS_H #define FILEPATHOPERATIONS_H #include #include #include class FilePathOperations { public: static QString GenerateUniqueFileName(const QDir& output_dir, const QString& input_file_basename , const QString& ext , const QHash& extra); /*! Ensure unique output filename. If the destination filename already exists either on disk or in %extra, rename it to prevent overwritting completed tasks. @param filename the expected filename @param extra additional filenames to exclude */ static QString GenerateUniqueFileName(const QString& filename , const QHash& extra); static QString GenerateTempFileName(const QString& filename); private: FilePathOperations(); }; #endif // FILEPATHOPERATIONS_H qwinff-master/src/services/httpdownloader.cpp000066400000000000000000000050101347323557400220260ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include #include #include #include "httpdownloader.h" #define BUFFER_SIZE 1024 HttpDownloader::HttpDownloader(QObject *parent) : QObject(parent), m_sizeLimit(0) { connect(&m_webCtrl, SIGNAL(finished(QNetworkReply*)), this, SLOT(slotDownloadFinished(QNetworkReply*))); } HttpDownloader::~HttpDownloader() { cancelAllDownloads(); } void HttpDownloader::setSizeLimit(unsigned int limit) { m_sizeLimit = limit; } unsigned int HttpDownloader::sizeLimit() const { return m_sizeLimit; } void HttpDownloader::startDownload(QString url) { QNetworkReply *reply = m_webCtrl.get(QNetworkRequest(url)); m_downloads[reply] = url; } void HttpDownloader::cancelAllDownloads() { QList replies = m_downloads.keys(); foreach (QNetworkReply *reply, replies) { reply->abort(); reply->deleteLater(); } m_downloads.clear(); } void HttpDownloader::slotDownloadFinished(QNetworkReply *reply) { QString url = m_downloads[reply]; bool success = !reply->error(); QString content; readData(content, reply); m_downloads.remove(reply); reply->deleteLater(); emit downloadFinished(success, url, content); } // read at most m_sizeLimit bytes from reply to dest // or read all data if m_sizeLimit is 0 void HttpDownloader::readData(QString &dest, QNetworkReply *reply) { if (m_sizeLimit == 0) { dest = reply->readAll(); } else { std::vector buffer; buffer.resize(m_sizeLimit + 1); // reserve data length and NULL byte reply->read(buffer.data(), m_sizeLimit); // buffer.data() is char* buffer[m_sizeLimit] = 0; // terminate the data with NULL dest = QString(buffer.data()); // convert the data to QString } } qwinff-master/src/services/httpdownloader.h000066400000000000000000000034411347323557400215010ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef HTTPDOWNLOADER_H #define HTTPDOWNLOADER_H #include #include #include #include class HttpDownloader : public QObject { Q_OBJECT public: explicit HttpDownloader(QObject *parent = 0); virtual ~HttpDownloader(); /** * @brief Set the maximum allowable download size. * @param limit the size limit in bytes. 0 means unlimited. */ void setSizeLimit(unsigned int limit); /** * @brief Get the maximum allowable download size. * @return the size limit in bytes */ unsigned int sizeLimit() const; public slots: void startDownload(QString url); void cancelAllDownloads(); signals: void downloadFinished(bool success, QString url, QString content); private slots: void slotDownloadFinished(QNetworkReply *reply); private: QNetworkAccessManager m_webCtrl; unsigned int m_sizeLimit; QMap m_downloads; void readData(QString& dest, QNetworkReply *reply); }; #endif // HTTPDOWNLOADER_H qwinff-master/src/services/mplayerpreviewer.cpp000066400000000000000000000043011347323557400223740ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include #include "converter/exepath.h" #include "mplayerpreviewer.h" #define TIMEOUT 3000 MPlayerPreviewer::MPlayerPreviewer(QObject *parent) : AbstractPreviewer(parent), m_proc(new QProcess(this)) { } bool MPlayerPreviewer::available() const { QProcess proc; QStringList param; // test whether mplayer could be invoked proc.start(ExePath::getPath("mplayer"), param); if (!proc.waitForStarted(TIMEOUT)) return false; proc.kill(); proc.waitForFinished(TIMEOUT); return true; } void MPlayerPreviewer::play(const QString& filename) { play(filename, -1, -1); } void MPlayerPreviewer::play(const QString &filename, int t_begin, int t_end) { QStringList param; stop(); if (t_begin >= 0) // set begin time: -ss param.append("-ss"), param.append(QString::number(t_begin)); else t_begin = 0; if (t_end >= 0) { // set end time: -endpos param.append("-endpos"); param.append(QString::number(t_end - t_begin)); } param.append(filename); m_proc->start(ExePath::getPath("mplayer"), param); m_proc->waitForStarted(TIMEOUT); } void MPlayerPreviewer::playFrom(const QString &filename, int t_begin) { play(filename, t_begin, -1); } void MPlayerPreviewer::playUntil(const QString &filename, int t_end) { play(filename, t_end, -1); } void MPlayerPreviewer::stop() { m_proc->kill(); m_proc->waitForFinished(TIMEOUT); } qwinff-master/src/services/mplayerpreviewer.h000066400000000000000000000027041347323557400220460ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef MPLAYERPREVIEWER_H #define MPLAYERPREVIEWER_H #include #include "abstractpreviewer.h" class MPlayerPreviewer : public AbstractPreviewer { Q_OBJECT public: explicit MPlayerPreviewer(QObject *parent = 0); bool available() const; /** Play the media file with ffplay. * If a media file is being played, it will be stopped before * playing the new one. */ void play(const QString& filename); void play(const QString &filename, int t_begin, int t_end); void playFrom(const QString &filename, int t_begin); void playUntil(const QString &filename, int t_end); void stop(); private: QProcess *m_proc; }; #endif // MPLAYERPREVIEWER_H qwinff-master/src/services/notification.cpp000066400000000000000000000046731347323557400214740ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "notification.h" #include "notificationservice-qt.h" #include "notificationservice-notifysend.h" #ifdef USE_LIBNOTIFY #include "notificationservice-libnotify.h" #endif namespace { NotificationService* notify_service[Notification::END_OF_TYPE]; } Notification::NotificationType Notification::m_type; #define SERVICE(type, cl) notify_service[type] = new cl(); void Notification::init() { // define all notification services here SERVICE(TYPE_MSGBOX, NotificationService_qt); SERVICE(TYPE_NOTIFYSEND, NotificationService_NotifySend); #ifdef USE_LIBNOTIFY SERVICE(TYPE_LIBNOTIFY, NotificationService_libnotify); #endif // default to msgbox m_type = TYPE_MSGBOX; } #undef SERVICE void Notification::release() { for (int i=0; i= END_OF_TYPE) return false; NotificationService *service = notify_service[type]; if (!service) return false; return service->serviceAvailable(); } bool Notification::setType(NotificationType type) { if (serviceAvailable(type)) { m_type = type; return true; } else { m_type = TYPE_MSGBOX; return false; } } void Notification::send(QWidget *parent, QString title, QString message) { if (m_type < 0 || m_type >= END_OF_TYPE) return; notify_service[m_type]->send(parent, title, message); } void Notification::send(QWidget *parent, QString title, QString message, int level) { if (m_type < 0 || m_type >= END_OF_TYPE) return; notify_service[m_type]->send(parent, title, message, level); } qwinff-master/src/services/notification.h000066400000000000000000000041361347323557400211330ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef NOTIFICATION_H #define NOTIFICATION_H #include #include "notificationservice.h" QT_BEGIN_NAMESPACE class QWidget; QT_END_NAMESPACE class Notification { public: enum NotificationType { TYPE_MSGBOX = 0, ///< use non-blocking message box TYPE_LIBNOTIFY, ///< use libnotify which doesn't require the command-line utility TYPE_NOTIFYSEND, ///< use the notify-send command line utility END_OF_TYPE }; /** Initialize the notification subsystem. * @warning This function is not thread-safe. Only call it in the main thread. */ static void init(); /** Release the notification subsystem. */ static void release(); /** Determine whether the notification type is available in the system. */ static bool serviceAvailable(NotificationType type); /** Decide how the notification will be sent. * @param type the type of the notification * @return If the function succeeds, the function returns true. * Otherwise, the function returns false and fallback to TYPE_QT. */ static bool setType(NotificationType type); static void send(QWidget *parent, QString title, QString message); static void send(QWidget *parent, QString title, QString message, int level); private: static NotificationType m_type; }; #endif // NOTIFICATION_H qwinff-master/src/services/notificationservice-libnotify.cpp000066400000000000000000000055501347323557400250450ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "notificationservice-libnotify.h" #include NotificationService_libnotify::NotificationService_libnotify() : m_success(true) { if (!notify_is_initted()) m_success = notify_init("QWinFF"); } NotificationService_libnotify::~NotificationService_libnotify() { /* Do not call notify_uninit() here because other instances of this class may be still using the notification system. */ } void NotificationService_libnotify::send(QWidget *parent, QString title, QString message) { send(parent, title, message, NotifyLevel::INFO); } void NotificationService_libnotify::send(QWidget */*parent*/, QString title, QString message, int level) { const char *icon; // icon switch (level) { case NotifyLevel::INFO: icon = "dialog-information"; break; case NotifyLevel::WARNING: icon = "dialog-warning"; break; case NotifyLevel::CRITICAL: icon = "dialog-error"; break; default: // no icon icon = ""; } /* In older libnotify, notify_notification_new() takes 4 arguments. */ #ifdef NOTIFY_CHECK_VERSION #if NOTIFY_CHECK_VERSION(0, 7, 0) NotifyNotification *msg = notify_notification_new(title.toLocal8Bit().data() , message.toLocal8Bit().data(), icon); #else NotifyNotification *msg = notify_notification_new(title.toLocal8Bit().data() , message.toLocal8Bit().data(), icon, 0); #endif #else NotifyNotification *msg = notify_notification_new(title.toLocal8Bit().data() , message.toLocal8Bit().data(), icon, 0); #endif notify_notification_show(msg, 0); } bool NotificationService_libnotify::serviceAvailable() const { return m_success; } QString NotificationService_libnotify::getVersion() { #if defined(NOTIFY_VERSION_MAJOR) && defined(NOTIFY_VERSION_MINOR) && defined(NOTIFY_VERSION_MICRO) return QString("%1.%2.%3").arg(NOTIFY_VERSION_MAJOR) .arg(NOTIFY_VERSION_MINOR).arg(NOTIFY_VERSION_MICRO); #else return QString(""); #endif } qwinff-master/src/services/notificationservice-libnotify.h000066400000000000000000000030611347323557400245050ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef NOTIFICATIONSERVICE_LIBNOTIFY_H #define NOTIFICATIONSERVICE_LIBNOTIFY_H #include "notificationservice.h" /** An implementation of notification functions by using the libnotify library directly. This is the most preferred notification mechanism on Linux as it is desktop-independent and doesn't require the libnotify command line tools. */ class NotificationService_libnotify : public NotificationService { public: NotificationService_libnotify(); ~NotificationService_libnotify(); virtual void send(QWidget *parent, QString titie, QString message); virtual void send(QWidget *parent, QString title, QString message, int level); virtual bool serviceAvailable() const; static QString getVersion(); private: bool m_success; }; #endif // NOTIFICATIONSERVICE_LIBNOTIFY_H qwinff-master/src/services/notificationservice-notifysend.cpp000066400000000000000000000054101347323557400252230ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "notificationservice-notifysend.h" #include #include #define NOTIFY_SEND_EXECUTABLE "notify-send" NotificationService_NotifySend::NotificationService_NotifySend() { } NotificationService_NotifySend::~NotificationService_NotifySend() { } void NotificationService_NotifySend::send(QWidget *parent, QString title, QString message) { send(parent, title, message, NotifyLevel::INFO); } void NotificationService_NotifySend::send(QWidget */*parent*/, QString title, QString message, int level) { /* notify-send usage: notify-send [OPTION...] [BODY] - create a notification Application Options: -u, --urgency=LEVEL Specifies the urgency level (low, normal, critical). -t, --expire-time=TIME Specifies the timeout in milliseconds at which to expire the notification. -i, --icon=ICON[,ICON...] Specifies an icon filename or stock icon to display. -c, --category=TYPE[,TYPE...] Specifies the notification category. -h, --hint=TYPE:NAME:VALUE Specifies basic extra data to pass. Valid types are int, double, string and byte. -v, --version Version of the package. */ QProcess proc; QStringList options; // add icon options.append("-i"); switch (level) { case NotifyLevel::INFO: options.append("dialog-information"); break; case NotifyLevel::WARNING: options.append("dialog-warning"); break; case NotifyLevel::CRITICAL: options.append("dialog-error"); break; default: // no icon options.pop_back(); } options.append(title); options.append(message); proc.start(NOTIFY_SEND_EXECUTABLE, options); proc.waitForFinished(1000); } bool NotificationService_NotifySend::serviceAvailable() const { QProcess proc; bool ret; proc.start(NOTIFY_SEND_EXECUTABLE); ret = proc.waitForStarted(1000); proc.kill(); proc.waitForFinished(1000); return ret; } qwinff-master/src/services/notificationservice-notifysend.h000066400000000000000000000026041347323557400246720ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef NOTIFICATIONSERVICENOTIFYSEND_H #define NOTIFICATIONSERVICENOTIFYSEND_H #include "notificationservice.h" /** An implementation of notification functions by calling the command-line tool "notify-send" to send messages. */ class NotificationService_NotifySend : public NotificationService { public: NotificationService_NotifySend(); virtual ~NotificationService_NotifySend(); virtual void send(QWidget *parent, QString title, QString message); virtual void send(QWidget *parent, QString title, QString message, int level); virtual bool serviceAvailable() const; }; #endif // NOTIFICATIONSERVICENOTIFYSEND_H qwinff-master/src/services/notificationservice-qt.cpp000066400000000000000000000040361347323557400234700ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "notificationservice-qt.h" #include #include NotificationService_qt::NotificationService_qt() { } NotificationService_qt::~NotificationService_qt() { } void NotificationService_qt::send(QWidget *parent, QString title, QString message) { send(parent, title, message, NotifyLevel::INFO); } void NotificationService_qt::send(QWidget *parent, QString title, QString message, int level) { QMessageBox *msgbox = new QMessageBox(parent); msgbox->setAttribute(Qt::WA_DeleteOnClose); // delete itself on close msgbox->setWindowFlags(msgbox->windowFlags() | Qt::WindowStaysOnTopHint); // always on top msgbox->setStandardButtons(QMessageBox::Ok); msgbox->setWindowTitle(title); msgbox->setText(message); msgbox->setModal(false); // non-modal message box switch (level) { case NotifyLevel::INFO: msgbox->setIcon(QMessageBox::Information); break; case NotifyLevel::WARNING: msgbox->setIcon(QMessageBox::Warning); break; case NotifyLevel::CRITICAL: msgbox->setIcon(QMessageBox::Critical); break; default: msgbox->setIcon(QMessageBox::NoIcon); } msgbox->show(); } bool NotificationService_qt::serviceAvailable() const { return true; } qwinff-master/src/services/notificationservice-qt.h000066400000000000000000000024711347323557400231360ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef NOTIFICATIONSERVICEQT_H #define NOTIFICATIONSERVICEQT_H #include "notificationservice.h" /** An implementation of notification functions by an always-on-top, non-modal QMessageBox */ class NotificationService_qt : public NotificationService { public: NotificationService_qt(); virtual ~NotificationService_qt(); virtual void send(QWidget *parent, QString titie, QString message); virtual void send(QWidget *parent, QString title, QString message, int level); virtual bool serviceAvailable() const; }; #endif // NOTIFICATIONSERVICEQT_H qwinff-master/src/services/notificationservice.cpp000066400000000000000000000017011347323557400230420ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "notificationservice.h" NotificationService::~NotificationService() { // This empty destructor is necessary because we have to call // the destructor of the derived classes. } qwinff-master/src/services/notificationservice.h000066400000000000000000000031171347323557400225120ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef NOTIFICATIONSERVICE_H #define NOTIFICATIONSERVICE_H #include QT_BEGIN_NAMESPACE class QWidget; QT_END_NAMESPACE class NotifyLevel { public: enum { INFO = 0, WARNING, CRITICAL }; }; class NotificationService { public: virtual ~NotificationService(); /** Send notification * @note Any implementation of this function should not block. */ virtual void send(QWidget *parent, QString title, QString message) = 0; /** Send notification with an image * @note Any implementation of this function should not block. */ virtual void send(QWidget *parent, QString title, QString message, int level) = 0; /** Determine whether the notification service is available. */ virtual bool serviceAvailable() const = 0; }; #endif // NOTIFICATIONSERVICE_H qwinff-master/src/services/paths.cpp000066400000000000000000000034351347323557400201200ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "paths.h" #include #include #include namespace { QString app_path; } void Paths::setAppPath(const QString &path) { app_path = path; qDebug() << "Set application path: " + app_path; qDebug() << "Application Path: " + app_path; qDebug() << "Data Path: " + dataPath(); qDebug() << "translationPath: " + translationPath(); } QString Paths::appPath() { return app_path; } QString Paths::dataPath() { #ifdef DATA_PATH return QString(DATA_PATH); #else return app_path; #endif } QString Paths::dataFileName(const QString &filename) { return QDir(dataPath()).absoluteFilePath(filename); } QString Paths::translationPath() { return QDir(dataPath()).absoluteFilePath("translations"); } QString Paths::qtTranslationPath() { #ifndef Q_OS_WIN32 // unix: load qt translation file from the default path return QLibraryInfo::location(QLibraryInfo::TranslationsPath); #else // windows: load qt translation file from translation directory return translationPath(); #endif } qwinff-master/src/services/paths.h000066400000000000000000000021271347323557400175620ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef PATHS_H #define PATHS_H #include class Paths { public: static void setAppPath(const QString& path); static QString appPath(); static QString dataPath(); static QString dataFileName(const QString& filename); static QString translationPath(); static QString qtTranslationPath(); }; #endif // PATHS_H qwinff-master/src/services/powermanagement-dummy.cpp000066400000000000000000000021271347323557400233200ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ /* Dummy Implementation of PowerManagement class that does nothing */ #include "powermanagement.h" bool PowerManagement::sendRequest(int action) { return false; } bool PowerManagement::implemented() { /* Returns false because this implementation doesn't provide any power management functionality. */ return false; } qwinff-master/src/services/powermanagement-linux.cpp000066400000000000000000000217741347323557400233350ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ /* Linux Implementation of PowerManagement class */ #include "powermanagement.h" #include #include #include #include namespace { /* The following power management functions were taken from qshutdown: * * power_suspend() * power_shutdown() * power_hibernate() * * qshutdown is a program to shutdown/reboot/suspend/hibernate the computer. * For more information, please visit * https://launchpad.net/~hakaishi/+archive/qshutdown */ const bool verbose = true; bool power_suspend() { bool gnome_power1 = false; bool gnome_power2 = false; bool hal_works = false; QDBusMessage response; gnome_power1 = QProcess::startDetached("gnome-power-cmd.sh suspend"); gnome_power2 = QProcess::startDetached("gnome-power-cmd suspend"); if (!gnome_power1 && !gnome_power2 && verbose) qWarning() << "W: gnome-power-cmd and gnome-power-cmd.sh didn't work"; if (!gnome_power1 && !gnome_power2) { QDBusInterface powermanagement("org.freedesktop.Hal", "/org/freedesktop/Hal/devices/computer", "org.freedesktop.Hal.Device.SystemPowerManagement", QDBusConnection::systemBus()); response = powermanagement.call("Suspend", 0); if (response.type() == QDBusMessage::ErrorMessage) { if (verbose) qWarning() << "W: " << response.errorName() << ":" << response.errorMessage(); } else hal_works = true; } if (!hal_works && !gnome_power1 && !gnome_power2) { QDBusInterface powermanagement("org.freedesktop.DeviceKit.Power", "/org/freedesktop/DeviceKit/Power", "org.freedesktop.DeviceKit.Power", QDBusConnection::systemBus()); response = powermanagement.call("Suspend"); if (response.type() == QDBusMessage::ErrorMessage) { if (verbose) qWarning() << "W: " << response. errorName() << ":" << response. errorMessage(); } else hal_works = true; } if (!hal_works) { QDBusInterface powermanagement("org.freedesktop.PowerManagement", "/org/freedesktop/PowerManagement", "org.freedesktop.PowerManagement", QDBusConnection::sessionBus()); response = powermanagement.call("Suspend"); if (response.type() == QDBusMessage::ErrorMessage) { if (verbose) qWarning() << "W: " << response.errorName() << ":" << response.errorMessage(); } else hal_works = true; } return hal_works; } bool power_shutdown() { bool shutdown_works = false; bool gnome_power1 = false; bool gnome_power2 = false; bool hal_works = false; QDBusMessage response; QDBusInterface gnomeSessionManager("org.gnome.SessionManager", "/org/gnome/SessionManager", "org.gnome.SessionManager", QDBusConnection::sessionBus()); response = gnomeSessionManager.call("RequestShutdown"); if (response.type() == QDBusMessage::ErrorMessage) { if (verbose) qWarning() << "W: " << response. errorName() << ":" << response.errorMessage(); gnome_power1 = QProcess::startDetached("gnome-power-cmd.sh shutdown"); gnome_power2 = QProcess::startDetached("gnome-power-cmd shutdown"); if (verbose && !gnome_power1 && !gnome_power2) qWarning() << "W: gnome-power-cmd and gnome-power-cmd.sh didn't work"; } else shutdown_works = true; if (!shutdown_works) { QDBusInterface kdeSessionManager("org.kde.ksmserver", "/KSMServer", "org.kde.KSMServerInterface", QDBusConnection::sessionBus()); response = kdeSessionManager.call("logout", 0, 2, 2); if (response.type() == QDBusMessage::ErrorMessage) { if (verbose) qWarning() << "W: " << response. errorName() << ":" << response.errorMessage(); } else shutdown_works = true; } if (!shutdown_works && !gnome_power1 && !gnome_power2) { QDBusInterface powermanagement("org.freedesktop.Hal", "/org/freedesktop/Hal/devices/computer", "org.freedesktop.Hal.Device.SystemPowerManagement", QDBusConnection::systemBus()); response = powermanagement.call("Shutdown"); if (response.type() == QDBusMessage::ErrorMessage) { if (verbose) qWarning() << "W: " << response. errorName() << ":" << response. errorMessage(); } else hal_works = true; } if (!hal_works && !shutdown_works && !gnome_power1 && !gnome_power2) { QDBusInterface powermanagement("org.freedesktop.ConsoleKit", "/org/freedesktop/ConsoleKit/Manager", "org.freedesktop.ConsoleKit.Manager", QDBusConnection::systemBus()); response = powermanagement.call("Stop"); if (response.type() == QDBusMessage::ErrorMessage) { if (verbose) qWarning() << "W: " << response. errorName() << ":" << response. errorMessage(); QProcess::startDetached("sudo shutdown -P now"); } } return shutdown_works; } bool power_hibernate() { bool gnome_power1 = false; bool gnome_power2 = false; bool hal_works = false; QDBusMessage response; gnome_power1 = QProcess::startDetached("gnome-power-cmd.sh hibernate"); gnome_power2 = QProcess::startDetached("gnome-power-cmd hibernate"); if (!gnome_power1 && !gnome_power2 && verbose) qWarning() << "W: gnome-power-cmd and gnome-power-cmd.sh didn't work"; if (!gnome_power1 && !gnome_power2) { QDBusInterface powermanagement("org.freedesktop.Hal", "/org/freedesktop/Hal/devices/computer", "org.freedesktop.Hal.Device.SystemPowerManagement", QDBusConnection::systemBus()); response = powermanagement.call("Hibernate"); if (response.type() == QDBusMessage::ErrorMessage) { if (verbose) qWarning() << "W: " << response. errorName() << ":" << response. errorMessage(); } else hal_works = true; } if (!hal_works && !gnome_power1 && !gnome_power2) { QDBusInterface powermanagement("org.freedesktop.DeviceKit.Power", "/org/freedesktop/DeviceKit/Power", "org.freedesktop.DeviceKit.Power", QDBusConnection::systemBus()); response = powermanagement.call("Hibernate"); if (response.type() == QDBusMessage::ErrorMessage) { if (verbose) qWarning() << "W: " << response. errorName() << ":" << response. errorMessage(); } } if (!hal_works) { QDBusInterface powermanagement("org.freedesktop.PowerManagement", "/org/freedesktop/PowerManagement", "org.freedesktop.PowerManagement", QDBusConnection::sessionBus()); response = powermanagement.call("Hibernate"); if (response.type() == QDBusMessage::ErrorMessage) { if (verbose) qWarning() << "W: " << response.errorName() << ":" << response.errorMessage(); } else hal_works = true; } return hal_works; } } // anonymous namespace bool PowerManagement::sendRequest(int action) { switch (action) { case SHUTDOWN: return power_shutdown(); case SUSPEND: return power_suspend(); case HIBERNATE: return power_hibernate(); } return false; } bool PowerManagement::implemented() { return true; } qwinff-master/src/services/powermanagement-w32.cpp000066400000000000000000000051261347323557400226020ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ /* Windows32 Implementation of PowerManagement class */ #include "powermanagement.h" #include #include namespace { bool adjustPrivilegeForShutdown() { HANDLE hCurrentProc = GetCurrentProcess(); HANDLE hToken; LUID tmpLuid; TOKEN_PRIVILEGES tkp; LUID_AND_ATTRIBUTES luidAttr; if (!OpenProcessToken(hCurrentProc , TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY , &hToken)) return false; if (!LookupPrivilegeValueA("", "SeShutdownPrivilege", &tmpLuid)) return false; luidAttr.Luid = tmpLuid; luidAttr.Attributes = SE_PRIVILEGE_ENABLED; tkp.PrivilegeCount = 1; tkp.Privileges[0] = luidAttr; if (!AdjustTokenPrivileges(hToken, false, &tkp , sizeof(TOKEN_PRIVILEGES), 0, 0)) return false; return true; } bool power_suspend() { /* BOOLEAN WINAPI SetSuspendState( __in BOOLEAN Hibernate, __in BOOLEAN ForceCritical, __in BOOLEAN DisableWakeEvent ); */ bool hal_works = SetSuspendState(false, true, false); return hal_works; } bool power_hibernate() { /* SetSuspendState: see power_suspend() */ bool hal_works = SetSuspendState(true, true, false); return hal_works; } bool power_shutdown() { bool shutdown_works = false; if (!adjustPrivilegeForShutdown()) return false; shutdown_works = ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE | EWX_POWEROFF, 0); return shutdown_works; } } // anonymous namespace bool PowerManagement::sendRequest(int action) { switch (action) { case SHUTDOWN: return power_shutdown(); case SUSPEND: return power_suspend(); case HIBERNATE: return power_hibernate(); } return false; } bool PowerManagement::implemented() { return true; } qwinff-master/src/services/powermanagement.h000066400000000000000000000027401347323557400216350ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef POWERMANAGEMENT_H #define POWERMANAGEMENT_H class PowerManagement { public: /* Power Management Function ID */ enum PowerAction { SHUTDOWN = 0, SUSPEND, HIBERNATE, ACTION_COUNT }; /** * Send the power management action. * @param action a PowerAction indicating the desired action */ static bool sendRequest(int action); /* This function is used to check whether there's an implementation for the current build. You should always return true in this function when implementing PowerManagement for another system/environment. */ static bool implemented(); private: PowerManagement(); }; #endif // POWERMANAGEMENT_H qwinff-master/src/services/settingtimer.cpp000066400000000000000000000033571347323557400215220ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include #include #include "settingtimer.h" namespace { qint64 msecsTo(const QDateTime& t1, const QDateTime& t2) { qint64 days = t1.daysTo(t2); qint64 msecs = t1.time().msecsTo(t2.time()); return days * (24*60*60*1000) + msecs; } } SettingTimer::SettingTimer(const QString& key) : m_key(key) { } void SettingTimer::start() { restart(); } void SettingTimer::restart() { QSettings().setValue(m_key, QDateTime::currentDateTime()); } void SettingTimer::invalidate() { QSettings().remove(m_key); } bool SettingTimer::isValid() const { return QSettings().contains(m_key); } qint64 SettingTimer::elapsedMilliseconds() const { QDateTime prev_time = QSettings().value(m_key).toDateTime(); QDateTime current_time = QDateTime::currentDateTime(); return msecsTo(prev_time, current_time); } qint64 SettingTimer::elapsedSeconds() const { const int milliseconds_per_second = 1000; return elapsedMilliseconds() / milliseconds_per_second; } qwinff-master/src/services/settingtimer.h000066400000000000000000000022551347323557400211630ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef SETTINGTIMER_H #define SETTINGTIMER_H #include /** * @brief timer using QSettings to maintain the time across sessions */ class SettingTimer { public: SettingTimer(const QString& key); void start(); void restart(); void invalidate(); bool isValid() const; qint64 elapsedMilliseconds() const; qint64 elapsedSeconds() const; private: QString m_key; }; #endif // SETTINGTIMER_H qwinff-master/src/services/updatechecker.cpp000066400000000000000000000063251347323557400216110ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "updatechecker.h" #include "httpdownloader.h" #include "updateinfoparser.h" #include "../version.h" #include "constants.h" class UpdateChecker::Private { public: UpdateChecker::CheckResult result; QString version; unsigned int versionId; QString release_note; QString release_date; QString download_url; QString download_page; HttpDownloader downloader; Private() : result(UpdateChecker::None) { } }; UpdateChecker::UpdateChecker(QObject *parent) : QObject(parent), p(new Private) { p->downloader.setSizeLimit(Constants::getInteger("UpdateInfoSizeLimit")); connect(&p->downloader, SIGNAL(downloadFinished(bool,QString,QString)), this, SLOT(downloadFinished(bool,QString,QString))); } UpdateChecker::~UpdateChecker() { delete p; } UpdateChecker::CheckResult UpdateChecker::result() const { return p->result; } bool UpdateChecker::hasUpdate() const { return p->result == UpdateChecker::UpdateFound; } QString UpdateChecker::versionName() const { return p->version; } unsigned int UpdateChecker::versionId() const { return p->versionId; } QString UpdateChecker::releaseDate() const { return p->release_date; } QString UpdateChecker::releaseNotes() const { return p->release_note; } QString UpdateChecker::downloadUrl() const { return p->download_url; } QString UpdateChecker::downloadPage() const { return p->download_page; } void UpdateChecker::checkUpdate() { QString update_url = Constants::getString("UpdateInfoUrl"); p->downloader.startDownload(update_url); } void UpdateChecker::downloadFinished(bool success, QString /*url*/, QString content) { if (success) { XmlUpdateInfoParser parser; if (!parser.parse(content)) { // parse error p->result = DataError; } else if (parser.versionId() > VERSION_INTEGER) { // new version > current version p->result = UpdateFound; p->version = parser.version(); p->versionId = parser.versionId(); p->release_note = parser.releaseNotes(); p->release_date = parser.releaseDate(); p->download_url = parser.downloadUrl(); p->download_page = parser.downloadPage(); } else { // no new version found p->result = UpdateNotFound; } } else { // failed to connect to server p->result = ConnectionError; } emit receivedResult(static_cast(p->result)); } qwinff-master/src/services/updatechecker.h000066400000000000000000000033201347323557400212460ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef UPDATECHECKER_H #define UPDATECHECKER_H #include #include #include /** * @brief Get update information from google code. */ class UpdateChecker : public QObject { Q_OBJECT public: explicit UpdateChecker(QObject *parent = 0); ~UpdateChecker(); enum CheckResult { None, ConnectionError, DataError, UpdateNotFound, UpdateFound }; CheckResult result() const; bool hasUpdate() const; QString versionName() const; unsigned int versionId() const; QString releaseDate() const; QString releaseNotes() const; QString downloadUrl() const; QString downloadPage() const; signals: void receivedResult(int result); public slots: void checkUpdate(); private slots: void downloadFinished(bool, QString, QString); private: Q_DISABLE_COPY(UpdateChecker) class Private; Private *p; }; #endif // UPDATECHECKER_H qwinff-master/src/services/updateinfoparser.cpp000066400000000000000000000042201347323557400223450ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include #include "updateinfoparser.h" #include "constants.h" #include "xmllookuptable.h" XmlUpdateInfoParser::XmlUpdateInfoParser() { } XmlUpdateInfoParser::~XmlUpdateInfoParser() { } bool XmlUpdateInfoParser::parse(QString s) { XmlLookupTable table; if (!table.readString(s)) return false; table.setPrefix("QWinFFVersionInfo"); m_version = table.lookup("Name"); m_vid = table.lookup("VersionId"); m_releaseDate = table.lookup("ReleaseDate"); m_releaseNotes = table.lookup("ReleaseNotes"); #ifdef Q_OS_WIN32 if (Constants::getBool("Portable")) { m_downloadUrl = table.lookup("DownloadLinks/WindowsPortable"); } else { m_downloadUrl = table.lookup("DownloadLinks/WindowsInstaller"); } #else m_downloadUrl = ""; #endif m_downloadPage = table.lookup("DownloadPage"); if (!m_version.isEmpty()) return true; else return false; } QString XmlUpdateInfoParser::version() const { return m_version; } unsigned int XmlUpdateInfoParser::versionId() const { return m_vid.toUInt(); } QString XmlUpdateInfoParser::releaseDate() const { return m_releaseDate; } QString XmlUpdateInfoParser::releaseNotes() const { return m_releaseNotes; } QString XmlUpdateInfoParser::downloadUrl() const { return m_downloadUrl; } QString XmlUpdateInfoParser::downloadPage() const { return m_downloadPage; } qwinff-master/src/services/updateinfoparser.h000066400000000000000000000034461347323557400220230ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef UPDATEINFOPARSER_H #define UPDATEINFOPARSER_H #include class UpdateInfoParser { public: UpdateInfoParser() { } virtual ~UpdateInfoParser() { } virtual bool parse(QString s) = 0; virtual QString version() const = 0; virtual QString releaseDate() const = 0; virtual QString releaseNotes() const = 0; virtual QString downloadUrl() const = 0; virtual QString downloadPage() const = 0; }; QT_BEGIN_NAMESPACE class QXmlStreamReader; class QXmlStreamAttributes; QT_END_NAMESPACE class XmlUpdateInfoParser : public UpdateInfoParser { public: XmlUpdateInfoParser(); ~XmlUpdateInfoParser(); bool parse(QString s); QString version() const; unsigned int versionId() const; QString releaseDate() const; QString releaseNotes() const; QString downloadUrl() const; QString downloadPage() const; private: QString m_version; QString m_vid; QString m_releaseDate; QString m_releaseNotes; QString m_downloadUrl; QString m_downloadPage; }; #endif // UPDATEINFOPARSER_H qwinff-master/src/services/versioncompare.cpp000066400000000000000000000077501347323557400220410ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "versioncompare.h" #include // Version /* patterns to extract the version number * first matched pattern will be used */ static const char *version_patterns[] = { "([0-9]+)\\.([0-9]+)\\.([0-9]+)", "([0-9]+)\\.([0-9]+)", "([0-9]+)", 0 // end of array }; Version::Version(int major, int minor, int patch) : m_major(major), m_minor(minor), m_patch(patch) { } Version::Version(const QString &s) { m_major = m_minor = m_patch = -1; // invalid value for (int i=0; version_patterns[i]; i++) { // try each pattern QRegExp pattern(version_patterns[i]); if (pattern.indexIn(s) != -1) { const QStringList cap = pattern.capturedTexts(); const int capture_count = cap.size() - 1; m_major = m_minor = m_patch = 0; if (capture_count >= 1) m_major = cap[1].toInt(); if (capture_count >= 2) m_minor = cap[2].toInt(); if (capture_count >= 3) m_patch = cap[3].toInt(); break; } } } Version Version::fromString(const QString &s) { return Version(s); } QString Version::toString() const { return QString("%1.%2.%3").arg(m_major).arg(m_minor).arg(m_patch); } bool Version::operator <(const Version& other) const { if (m_major < 0 || other.m_major < 0) // invalid value return false; if (m_major == other.m_major) { if (m_minor == other.m_minor) { return m_patch < other.m_patch; } else return m_minor < other.m_minor; } else return m_major < other.m_major; } bool Version::operator >(const Version& other) const { return other < *this; } bool Version::operator ==(const Version& other) const { return !(other < *this || *this < other); } bool Version::operator !=(const Version& other) const { return other < *this || *this < other; } bool Version::operator <=(const Version& other) const { return !(other < *this); } bool Version::operator >=(const Version& other) const { return !(*this < other); } // VersionRange VersionRange::VersionRange(const QString &s) { if (!s.isEmpty()) { QStringList lst = s.split(",", QString::SkipEmptyParts); foreach (QString range, lst) { m_range.push_back(range.trimmed()); } } } bool VersionRange::containsVersion(const Version &version) const { foreach (QString range, m_range) { if (match_range(range, version)) return true; } return false; } bool VersionRange::match_range(const QString& range, const Version &version) const { if (range.indexOf("~") != -1) { // v1~v2 QStringList ranges = range.split("~"); Version version_lower(ranges[0]), version_upper(ranges[1]); return version_lower <= version && version <= version_upper; } else if (range.startsWith("le")) { // v<=v0 return version <= Version(range); } else if (range.startsWith("ge")) { // v>=v0 return version >= Version(range); } else if (range.startsWith("lt")) { // vv0 return version > Version(range); } else { // v==v0 return version == Version(range); } } qwinff-master/src/services/versioncompare.h000066400000000000000000000041161347323557400214770ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef VERSIONCOMPARE_H #define VERSIONCOMPARE_H #include class Version { public: Version(int major, int minor, int patch); explicit Version(const QString& s); static Version fromString(const QString& s); QString toString() const; bool operator <(const Version& other) const; bool operator >(const Version& other) const; bool operator ==(const Version& other) const; bool operator !=(const Version& other) const; bool operator <=(const Version& other) const; bool operator >=(const Version& other) const; private: int m_major, m_minor, m_patch; }; /** * @brief This class represets a set of versions. * * The format of version range string can contain multiple * intervals separated by commas. Each interval can be in one of the * following formats: * "x.x.x~x.x.x" (inclusive range), * "lt x.x.x", (less than), * "gt x.x.x", (greater than), * "le x.x.x", (less than or equal to), * "ge x.x.x", (greater than or equal to) * and "x.x.x" (exactly the version). */ class VersionRange { public: explicit VersionRange(const QString& s); static VersionRange fromString(const QString& s); bool containsVersion(const Version& version) const; private: QStringList m_range; bool match_range(const QString& range, const Version& version) const; }; #endif // VERSIONCOMPARE_H qwinff-master/src/services/xmllookuptable.cpp000066400000000000000000000063551347323557400220470ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include #include #include #include "xmllookuptable.h" XmlLookupTable::XmlLookupTable() { } bool XmlLookupTable::readFile(QIODevice &file) { if (!file.isOpen()) return false; int depth = 0; QXmlStreamReader reader(&file); QStringList path; m_data.clear(); while (!reader.atEnd() && !reader.hasError()) { QXmlStreamReader::TokenType token = reader.readNext(); if (token == QXmlStreamReader::StartElement) { path.push_back(reader.name().toString()); Entry& entry = m_data[path.join("/")]; QXmlStreamAttributes attributes = reader.attributes(); entry.attributes.clear(); foreach (QXmlStreamAttribute attr, attributes) entry.attributes[attr.name().toString()] = attr.value().toString(); ++depth; } else if (token == QXmlStreamReader::Characters) { Entry& entry = m_data[path.join("/")]; entry.data += reader.text().toString().trimmed(); } else if (token == QXmlStreamReader::EndElement) { if (depth <= 0) return false; // malformed xml --depth; path.pop_back(); } } return !reader.hasError(); } bool XmlLookupTable::readString(const QString &s) { QByteArray barray = s.toUtf8(); QBuffer buffer(&barray); buffer.open(QIODevice::ReadOnly); return readFile(buffer); } void XmlLookupTable::setPrefix(const QString &s) { m_prefix = s.trimmed(); while (m_prefix.endsWith("/")) // remove trailing '/' m_prefix.chop(1); } QString XmlLookupTable::prefix() const { return m_prefix; } QString XmlLookupTable::lookup(const QString &path, bool *ok) const { QHash::ConstIterator it = m_data.find(full_path(path)); bool found = (it != m_data.end()); if (ok) *ok = found; if (found) return it->data; else return QString(); // default } QString XmlLookupTable::operator [](const QString& path) const { return m_data[full_path(path)].data; } QString XmlLookupTable::attribute(QString path, QString attr) const { const QMap &attributes = m_data[full_path(path)].attributes; return attributes[attr]; } void XmlLookupTable::clear() { m_data.clear(); } QString XmlLookupTable::full_path(const QString &path) const { if (!m_prefix.isEmpty()) return m_prefix + "/" + path; else return path; } qwinff-master/src/services/xmllookuptable.h000066400000000000000000000057451347323557400215160ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef XMLLOOKUPTABLE_H #define XMLLOOKUPTABLE_H #include #include #include #include /** * @brief Read an xml file and provide path lookup syntax. */ class XmlLookupTable { public: XmlLookupTable(); /** * @brief Read xml from file. * @param file a QIODevice opened for reading * @note Existing data are cleared no matter the function succeeds or fails. * @return true if succeed, false if failed */ bool readFile(QIODevice& file); /** * @brief Read xml from string * @param s a string to read from * @note Existing data are cleared no matter the function succeeds or fails. * @return true if succeed, false if failed */ bool readString(const QString& s); /** * @brief Set the lookup prefix. * * The lookup prefix will be prepended to the path in each lookup. * Setting the prefix can prevent repeatly typing common prefixes. * * @param path the path to be prepended */ void setPrefix(const QString& path); /** * @brief get the current prefix */ QString prefix() const; /** * @brief Find the data associated with @a path. * * @param path the path to lookup. Note that the prefix will be prepended * to this path. The path is similar to unix file paths but without leading * or trailing '/'. For example: level1/level2/level3 * * @return the data associated witht @a path. */ QString lookup(const QString &path, bool *ok=0) const; /** * @brief alias for lookup() * * @see lookup() */ QString operator [](const QString &path) const; /** * @brief Get the value of the attribute associated with @a path. * * @param path the path to the node * * @param attr name of the attribute * * @see lookup() */ QString attribute(QString path, QString attr) const; /** * @brief Clear all xml data. */ void clear(); private: class Entry { public: QMap attributes; QString data; }; QHash m_data; QString m_prefix; QString full_path(const QString &path) const; }; #endif // XMLLOOKUPTABLE_H qwinff-master/src/tests/000077500000000000000000000000001347323557400156075ustar00rootroot00000000000000qwinff-master/src/tests/run-tests.sh000077500000000000000000000015061347323557400201140ustar00rootroot00000000000000#!/bin/sh # Run all unit tests # The name of each qt project file should be the same as that of its containing # directory. For example, unit test "testversioncompare" has the following # directory hierachy: # testversioncompare/ # testversioncompare.pro # testversioncompare.cpp # testversioncompare.h TMP_OUTPUT=tmp-output.txt run_command() { "$@" STATUS=$? if [ $STATUS -ne 0 ]; then cat $TMP_OUTPUT rm -f $TMP_OUTPUT echo "$1 returned exit status $STATUS" exit 1 fi rm -f $TMP_OUTPUT } run_test() { DIR="$1" cd "$DIR" if [ -f "${DIR}.pro" ]; then echo "running test: ${DIR}" run_command qmake run_command make run_command ./${DIR} else echo "warning: ${DIR}/${DIR}.pro not found" fi cd .. } for dir in *; do if [ -d "$dir" ]; then # it is a directory run_test "$dir" fi done qwinff-master/src/tests/testupdateinfoparser/000077500000000000000000000000001347323557400220625ustar00rootroot00000000000000qwinff-master/src/tests/testupdateinfoparser/testupdateinfoparser.cpp000066400000000000000000000026071347323557400270460ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "testupdateinfoparser.h" QTEST_MAIN(TestUpdateInfoParser) void TestUpdateInfoParser::testParseXml() { const char *xml = "" "" "0.1.8" "20120213" "release notes" ""; XmlUpdateInfoParser parser; bool success = parser.parse(QString(xml)); QVERIFY(success); QCOMPARE(QString("0.1.8"), parser.version()); QCOMPARE(QString("20120213"), parser.releaseDate()); QCOMPARE(QString("release notes"), parser.releaseNotes()); /* download link not tested because it varies across platforms */ } qwinff-master/src/tests/testupdateinfoparser/testupdateinfoparser.h000066400000000000000000000020151347323557400265040ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef TESTUPDATEINFOPARSER_H #define TESTUPDATEINFOPARSER_H #include #include "../../services/updateinfoparser.h" class TestUpdateInfoParser : public QObject { Q_OBJECT private slots: void testParseXml(); }; #endif // TESTUPDATEINFOPARSER_H qwinff-master/src/tests/testupdateinfoparser/testupdateinfoparser.pro000066400000000000000000000010041347323557400270520ustar00rootroot00000000000000###################################################################### # Automatically generated by qmake (2.01a) ?? 7? 19 11:46:16 2013 ###################################################################### CONFIG += qtestlib TEMPLATE = app TARGET = testupdateinfoparser # Input HEADERS += testupdateinfoparser.h ../../services/updateinfoparser.h \ ../../services/xmllookuptable.cpp SOURCES += testupdateinfoparser.cpp ../../services/updateinfoparser.cpp \ ../../services/xmllookuptable.cpp qwinff-master/src/tests/testversioncompare/000077500000000000000000000000001347323557400215435ustar00rootroot00000000000000qwinff-master/src/tests/testversioncompare/testversioncompare.cpp000066400000000000000000000040751347323557400262110ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "testversioncompare.h" QTEST_MAIN(TestVersionCompare) void TestVersionCompare::testVersionEquality() { Version v1("0.1.0"), v2("0.1.0"), v3("1.1.0"); QCOMPARE(v1, v2); QVERIFY(v1 != v3); QVERIFY(v2 != v3); QVERIFY(!(v1 == v3)); QVERIFY(!(v2 == v3)); QVERIFY(!(v1 != v2)); } void TestVersionCompare::testVersionInequality() { const int COUNT = 10; Version *v[COUNT*COUNT*COUNT] = {0}; for (int i=0; i v1); QVERIFY(v1 <= v1); QVERIFY(v1 >= v1); } for (int i=0; i * * 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 . */ #ifndef TESTVERSIONCOMPARE_H #define TESTVERSIONCOMPARE_H #include #include "../../services/versioncompare.h" class TestVersionCompare : public QObject { Q_OBJECT private slots: void testVersionEquality(); void testVersionInequality(); void testVersionSingleRange(); }; #endif // TESTVERSIONCOMPARE_H qwinff-master/src/tests/testversioncompare/testversioncompare.pro000066400000000000000000000006251347323557400262240ustar00rootroot00000000000000###################################################################### # Automatically generated by qmake (2.01a) ?? 7? 2 21:43:55 2013 ###################################################################### CONFIG += qtestlib TARGET = testversioncompare TEMPLATE = app # Directories HEADERS += \ testversioncompare.h SOURCES += \ testversioncompare.cpp \ ../../services/versioncompare.cpp qwinff-master/src/translations/000077500000000000000000000000001347323557400171665ustar00rootroot00000000000000qwinff-master/src/translations/qwinff_ar.ts000066400000000000000000001163761347323557400215300ustar00rootroot00000000000000 AboutDialog About QWinFF نبذة عن QWinFF Information المعلومات Translators المترجمون Version: %1 الإصدار: %1 Portable محمول Compiled with Qt %1 جُمِّع بواسطة منصة Qt %1 Compiled with libnotify %1 جُمِّع بواسطة libnotify %1 QWinFF is a gui frontend for FFmpeg. QWinFF هو نهاية أمامية ذات واجهة رسومية لـFFmpeg. Programming: %1 برمجه: %1 Logo Design: %1 صمم شعاره: %1 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 or 3. هذا برنامج حرّ، بإمكانك توزيعه و/أو تعديله بما يوافق أحكام رخصة GPL الإصدار الثاني أو الثالث. QWinFF Homepage: %1 موقع البرنامج: %1 Some audio-processing functionalities are provided by SoX. توفّر SoX بعض وظائف معالجة الصوت. FFmpeg presets were taken from WinFF. أُخذت وصفات التحويل الجاهزة لـFFmpeg من WinFF. Japanese Japanese Language اليابانية Italian Italian Language الإيطالية Czech Czech Language التشيكية Simplified Chinese Chinese character set used in China الصينية المبسطة Russian Russian Language الروسية Spanish (Spain) Spanish Language (Spain) الإسبانية (إسبانيا) Spanish (Guatemala) Spanish Language (Guatemala) الإسبانية (غواتيمالا) Romanian Romanian Language الرومانية Turkish Turkish Language التركية Arabic Arabic Language العربية Hungarian Hungarian Langauge هنجاريه Polish Polish Language French French Language AboutFFmpegDialog About FFmpeg نبذة عن FFmpeg FFmpeg FFmpeg Available Codecs المرمزات المتاحة FFmpeg is a complete, cross-platform solution to record, convert and stream audio and video. It includes libavcodec - the leading audio/video codec library. ffmpeg description FFmpeg حلّ متكامل وعابر للأنظمة لتسجيل الصوت والفيديو وتحويلهما ودَفقهما. يضم libavcodec: مكتبة ترميز الصوت والفيديو الرائدة. FFmpeg is free software licensed under the LGPL or GPL. FFmpeg برنامج حرّ يرخص وفق LGPL أو GPL. Please visit %1 for more information. زُر %1 لمعلومات أكثر. AddTaskWizard Add Tasks إضافة مَهامَ Files to be converted الملفات المُراد تحويلها Add files. أضف ملفات. Remove selected files. أزِل الملفات المحددة. Output Settings ضبط الخرج Edit تحرير Auto adjust output bitrate to reduce output file size. اضبط معدل البِتّات تلقائيًّا للإقلال من حجم الملف الناتج. Auto Adjust Audio Bitrate الضبط التلقائي لمعدل بتات الصوت Preset الوصفة الجاهزة Convert to حوّل إلى Output Path مسار الخرج Select &folder ا&ختر مجلداً Browse استعرض Create &new folder in source folder Create a new folder (e.g. qwinff_output) in the folder containing the input files. Put the output files in the newly created folder. أنشئ مجلداً &جديداً في مجلد الدَخل Folder Name اسم المجلد Output to &source folder put the output files in the same folder as the input files أخرج إلى مجلد الد&خل Please select at least one file. رجاءً اختر ملفاً واحداً أو أكثر. Select Files This text is the title of an openfile dialog. اختر ملفات Multimedia الوسائط المتعددة Video الفيديو Audio الصوت All files كل الملفات Select Directory This text is the title of an open directory dialog. اختر مجلداً Searching for files... يبحث عن الملفات ... Some files could not be found. لم تُوجد بعض الملفات. Folder does not exist. Create a new folder? لم يُوجد المجلد. أتريد إنشاء واحدٍ جديد؟ Failed to create folder. Please select another output folder. غير قادر على إنشاء المجلد. رجاء اختر مجلداً آخر للخرج. ConversionParameterDialog Conversion Parameters معاملات التحويل Audio الصوت Disable Audio أزل الصوت Audio Options خيارات الصوت Sample Rate نسبة التردد Hz هرتز Bitrate معدل البتات (auto) ( تلقائي) kb/s ك.ب/ثا Channels القنوات Volume حجم الصوت % % Video الفيديو Disable Video أزل الفيديو Video Options خيارات الفيديو Same Quantizer as Source المعامل الكمّي كما في المصدر Deinterlace فك التشابك Width العرض px بكسل Height الارتفاع Crop قصّ Time time-related options (speed, length) الوقت Cutting video time cutting: options for begin time and end time التقطيع Cut Cut video; select a range to convert &Preview م&عاينة Scaling time scaling, changing the speed of the output file التمديد والتقليص Speed السرعة Advanced متقدمة FFmpeg FFmpeg Additional FFmpeg Options مزيدٌ من خيارات FFmpeg ConvertList Cancel Cancel the operation of adding new tasks ألغِ Adding files (%1/%2) This text is the progress indicator of adding multiple tasks. %1 is the number of files that are already added. %2 is the total number of files. يضيف الملفات (%1/%2) Some files are not recognized by the converter. لم يتعرف المُحوِّل على بعض الملفات. New File Name اسم الملف الجديد Please input the new name for the output file. رجاءً أدخل اسماً جديداً لملف الخرج. Output Directory مجلد الخرج Error Message from FFmpeg: رسالة خطأ من FFmpeg : Drag and drop files here to add tasks. اسحب وأسقط الملفات لإضافة مَهمّات. Hide "%1" Hide a column in the list. For example, the text maybe 'Hide "Duration"'. The two " are quotation marks in English, you may replace it with local quotation marks. أخفِ "%1" Restore All Columns استعد كل الأعمدة Source المُنطَلق Destination المُستقَر Duration المدة File Size حجم الملف Sample Rate Audio نسبة التردد Audio Bitrate معدل بتات الصوت Channels Audio القنوات Audio Codec مُرمِّز الصوت Dimensions الأبعاد Video Bitrate معدل بتات الفيديو Framerate Video معدّل الإطارات Video Codec مُرمِّز الفيديو Progress التقدم %1 Hz %1 هرتز %1 kb/s %1 ك.ب/ثا %1 fps %1 إطار/ثا Removing tasks... Remove files from the tasklist يحذف المهام... KiB ك.ب MiB م.ب GiB ج.ب TiB ت.ب B Bytes بايت File Exists الملف مُوجَد من قبل %1 already exists on disk or in the task list. Still use this name as the output filename? الملف "%1" موجَد على القرص أو في قائمة المهام. أما زلت راغباً في استخدام هذا الاسم لملف الخرج؟ Remove Task احذف المهمة Cannot remove a task while it is in progress. غير قادر على حذف مهمة وهي جارية. Finished The text to be displayed on the progress bar when a conversion finishes تمّت Failed The text to be displayed on the progress bar when a conversion fails فشِلت Error: %1 %1 is the error message خطأ: %1 ExtraTranslations Convert between media file formats حوّل ملفات الوسائط المتعددة من صيغة إلى أخرى Media Converter محول الوسائط InteractiveCuttingDialog Cutting Cutting as in "cutting video" التقطيع Mark as Begin Seek to Begin Play Selection Mark as End Seek to End %1 not found MainWindow QWinFF QWinFF Start conversion process. ابدأ عملية التحويل. &Start ا&بدأ &File &ملف &Convert ت&حويل &About &نبذة &Edit تح&رير &Add Files أ&ضف ملفات Add files for conversion. أضف ملفات تريد تحويلها. Ctrl+N تحكّم+N E&xit أن&ه Exit the program. أنهِ البرنامج. F9 F9 S&top أو&قف Stop conversion process. أوقف عملية التحويل. Set &Parameters اضبط المُ&عامِلات Set Parameters Edit output file parameters. اضبط المعاملات Edit conversion parameters of selected files. عدّل معاملات تحويل الملفات المُختارة. About &Qt عن &Qt About Qt نبذة عن Qt &Open Output Folder افتح مجلد ال&خرج Open output folder of the selected file. افتح المجلد المحتوي على ناتج الملف المحدد. About &FFmpeg عن &FFmpeg About FFmpeg نبذة عن FFmpeg &Remove Selected remove selected (tasks, items) أ&زل المُختارة Remove all selected items in the list. أزل كل العناصر المختارة في القائمة. R&emove Completed remove completed (task, items) أزل ال&تامّة Remove Completed Items أزل العناصر التامة Remove all completed items in the list. أزل كل العناصر التامّة في القائمة. &Clear List ن&ظّف القائمة Clear List نظف القائمة Remove all items in the list. أزل كل العناصر في القائمة. &Retry حاول &ثانيةً Retry حاول ثانيةً Retry selected tasks. حاول إتمام المهمات المختارة. Retry &All حاول إتمام ال&كلّ Retry all tasks. حاول إتمام كل المهمات. &Options ال&خيارات Options الخيارات About Q&WinFF عن Q&WinFF About This Program نبذة عن هذا البرنامج Change Output &Filename غيّر اسم ملف ال&خرج Change the output filename of the selected item. غير اسم ملف الخرج للعنصر المختار. Change Output &Directory غيّر م&جلد الخرج Change the output directory of the selected items. غير مجلد الخرج للعناصر المختارة. Show Error &Message أظهر ر&سالة الخطأ Check For &Updates التم&س التحديثات Cut Cut video file (select a time range to conert) All tasks have finished. تمّت كل المهمات. Nothing to convert. لا شيء يُحوَّل. Conversion is still in progress. Abort? التحويل جارٍ. أتريد إيقافه قسراً؟ Shutdown Shutdown the computer (completely poweroff) أوقف تشغيل الجهاز Shutdown when all tasks are done. أوقف تشغيل الحاسوب عند إتمام كل المهمات. Suspend Suspend the computer (sleep to ram, standby) علّق الجهاز Suspend when all tasks are done. علّق الحاسوب عند إتمام كل المهمات. Hibernate Hibernate the computer (sleep to disk, completely poweroff) أسبِت الجهاز Hibernate when all tasks are done. أَسبِت الجهاز عند إتمام كل المهمات. This program is going to check for updates online. Do you allow this program to use the Internet to check for updates? سيلتمس هذا البرنامج التحديثات من الإنترنت. أتسمح له باستخدامها؟ Failed to load preset file. The application will quit now. فشلَ في تحميل ملف الوصفات. سيُنهى التطبيق الآن. Elapsed Time: %1 h %2 m %3 s الوقت المُنقضي: %1 سا و%2 د و%3 ثا Converting %1/%2 Converting the %1-th file in %2 files. %2 is the number of files. يحوّل %1 من %2 MediaConverter %1 not found. %1 is a computer program لم يُوجد البرنامج "%1". OptionsDialog Options خيارات General عامّة Check for updates on program startup التمس التحديثات عند بدء البرنامج Automatically start conversion after adding files to the list. ابدأ التحويل مباشرة بعد إضافة الملفات إلى القائمة. Start conversion automatically ابدأ التحويل تلقائياً FFmpeg FFmpeg Number of threads to use in conversion عدد الخيوط المستخدمة في التحويل <html><head/><body><p>Hide output formats that are not available in the current ffmpeg installation. It is recommended to turn this option on unless you are sure that QWinFF has failed to detect available formats. (requires restarting QWinFF to take effect)</p></body></html> <html><head/><body><p>أخفِ صيغ الخرج التي لا تتوفر في التثبيت الحالي لـFFmpeg. يُفضّل تفعيل هذا الخيار إلا إن كنت على يقين من أن QWinFF فَشِل في اكتشاف الصيغ المتوفّرة. (يتطلب هذا إعادة تشغيل QWinFF ليصبح نافذ المفعول)</p></body></html> Hide unavailable formats (requires restarting) أخفِ الصيغ غير المتوفرة (يتطلب إعادة تشغيل البرنامج) Tools أدوات You have to restart QWinFF for the changes to take effect. عليك إعادة تشغيل QWinFF لتصبح التغييرات نافذة المفعول. Name الاسم Command الأمر PoweroffDialog QWinFF QWinFF Cancel ألغِ Shutdown immediately Shutdown the computer أوقف تشغيل الجهاز فوراً Suspend immediately Suspend the computer (sleep to ram, standby) علّق الجهاز فوراً Hibernate immediately Hibernate the computer (sleep to disk, completely poweroff) أسبت الجهاز فوراً Shutdown Shutdown the computer أوقف تشغيل الجهاز Suspend Suspend the computer (sleep to ram, standby) علّق الجهاز Hibernate Hibernate the computer (sleep to disk, completely poweroff) أسبِت الجهاز Operation Failed: %1 فشلت العملية: %1 Shutting down in <b>%1</b> seconds سيوقف تشغيل الجهاز خلال <b>%1</b> ثا Suspending in <b>%1</b> seconds سيعلق الجهاز خلال <b>%1</b> ثا Hibernating in <b>%1</b> seconds سيُسَبتُ الجهاز خلال <b>%1</b> ثا PreviewDialog Dialog Play Selected Range %1 not found Begin noun, the beginning of the video End noun, the end of the video Play %1~%2 play the video from time %1 to time %2. %1 and %2 are time in hh:mm:ss format. TimeRangeEdit From Begin من البداية To End إلى النهاية UpdateDialog Show &Release Notes اعرض ملاحظات الإ&صدار Check for updates on program startup التمس التحديثات عند بدء البرنامج Downloading update information... يُنزل معلومات التحديث... Cannot connect to server. غير قادر على الاتصال بالخادوم. Failed to parse the received data. فشلَ في تفسير البيانات المستقبَلة. You are already using the latest version of QWinFF. تستخدم أحدث نسخة من QWinFF. An unknown error has occurred. وقع خطأ غير معروف. A new version of QWinFF has been released! أُصدرت نسخة جديدة من QWinFF! Version <b>%1</b> is available at %2. %1 is version number, %2 is the project homepage يتوفر الإصدار <b>%1</b> على %2. You can download this version using the link: بإمكانك تنزيل هذه النسخة من الرابط: qwinff-master/src/translations/qwinff_cs_CZ.ts000066400000000000000000001101461347323557400221140ustar00rootroot00000000000000 AboutDialog About QWinFF Informace o QWinFF Information Informace Translators Překladatelé Version: %1 Verze: %1 Portable Přenosný Compiled with Qt %1 Zkompilováno pomocí Qt %1 Compiled with libnotify %1 Zkompilováno s knihovnou libnotify %1 QWinFF is a gui frontend for FFmpeg. QWinFF je grafické prostředí pro FFmpeg. Programming: %1 Programátor: %1 Logo Design: %1 Autor Loga: %1 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 or 3. Tento program je freeware; smíte jej šířit a/nebo modifikovat v souladu s licencí GNU GPL v2 nebo v3. QWinFF Homepage: %1 Some audio-processing functionalities are provided by SoX. Některé funkce pro zpracování zvuku poskytl SoX. FFmpeg presets were taken from WinFF. Nastavení FFmpeg bylo převzato z WinFF. Japanese Japanese Language Japonština Italian Italian Language Italština Czech Czech Language Čeština Simplified Chinese Chinese character set used in China Russian Russian Language Ruština Spanish (Spain) Spanish Language (Spain) Španělština (Španělsko) Spanish (Guatemala) Spanish Language (Guatemala) Španělština (Guatemala) Romanian Romanian Language Rumunština Turkish Turkish Language Arabic Arabic Language Hungarian Hungarian Langauge Polish Polish Language French French Language AboutFFmpegDialog About FFmpeg O FFmpeg FFmpeg FFmpeg Available Codecs Dostupné kodeky FFmpeg is a complete, cross-platform solution to record, convert and stream audio and video. It includes libavcodec - the leading audio/video codec library. ffmpeg description FFmpef je kompletní řešení pro nahrávání, konverzi a streamování audia a videa, fungující nad několika platformami. Obsahuje kodek libav - přední knihovnu pro převod audia a videa. FFmpeg is free software licensed under the LGPL or GPL. FFmpeg je freeware licencovaný pod LGPL nebo GPL. Please visit %1 for more information. Chcete-li získat další informace, prosím navštivte %1 . AddTaskWizard Add Tasks Přidej úlohy Files to be converted Soubory ke konverzi Add files. Přidat soubory. Remove selected files. Odebrat zvolené soubory. Output Settings Nastavení výstupu Edit Upravit Auto adjust output bitrate to reduce output file size. Automaticky nastavit výstupní bitrate pro zmenšení velikosti výstupního souboru. Auto Adjust Audio Bitrate Automaticky nastavit bitrate audia Preset Předvolby Convert to Konvertovat do Output Path Cesta k výstupnímu soubotu Select &folder Browse Procházet Create &new folder in source folder Create a new folder (e.g. qwinff_output) in the folder containing the input files. Put the output files in the newly created folder. Folder Name Output to &source folder put the output files in the same folder as the input files Please select at least one file. Prosím vyberte nejméně jeden soubor. Select Files This text is the title of an openfile dialog. Vyberte soubory Multimedia Multimédia Video Video Audio Audio All files Všechny soubory Select Directory This text is the title of an open directory dialog. Vyberte prosím andresář Searching for files... Some files could not be found. Některé soubory nebyli nalezeny. Folder does not exist. Create a new folder? Složka neexistuje. Přejete si ji vytvořit? Failed to create folder. Please select another output folder. Vytvoření složky selhalo. Prosím vyberte jinou výstupní složku. ConversionParameterDialog Conversion Parameters Parametry konverze Audio Audio Disable Audio Vypnout Audio Audio Options Nastavení audia Sample Rate Vzorkovací frekvence Hz Hz Bitrate Bitrate (auto) (automaticky) kb/s kb/s Channels Počet kánálů Volume Hlasitost % % Video Video Disable Video Vypnout video Video Options Nastavení videa Same Quantizer as Source Deinterlace Bez prokládání Width Šířka px (sp)px Height Výška Crop Oříznout Time time-related options (speed, length) Čas Cutting video time cutting: options for begin time and end time Sřih Cut Cut video; select a range to convert &Preview &Náhled Scaling time scaling, changing the speed of the output file Zvětšení Speed Rychlost Advanced Rozřířené FFmpeg FFmpeg Additional FFmpeg Options Další nastavení FFmpeg ConvertList Cancel Cancel the operation of adding new tasks Zrušit Adding files (%1/%2) This text is the progress indicator of adding multiple tasks. %1 is the number of files that are already added. %2 is the total number of files. Přidávání souboru (%1 z %2) Some files are not recognized by the converter. Některé soubory nebyli rozpoznány. New File Name Název nového souboru Please input the new name for the output file. Prosím vložte jméno výstupního souboru. Output Directory Výstupní Složka Error Message from FFmpeg: Chyba FFmpeg: Drag and drop files here to add tasks. Hide "%1" Hide a column in the list. For example, the text maybe 'Hide "Duration"'. The two " are quotation marks in English, you may replace it with local quotation marks. Skrýt "%1" Restore All Columns Obnovit všechny sloupce Source Zdroj Destination Cíl Duration Délka File Size Velikost souboru Sample Rate Audio Vzorkovací frekvence Audio Bitrate Bitrate zvuku Channels Audio Počet kanálů Audio Codec Audio kodek Dimensions Rozměry Video Bitrate Bitrate videa Framerate Video Počet snímků za vteřinu Video Codec Kodek videa Progress Průběh %1 Hz %1 Hz %1 kb/s %1 kb/s %1 fps %1 fps Removing tasks... Remove files from the tasklist Odebírám úlohy... KiB KiB MiB MiB GiB GiB TiB TiB B Bytes B File Exists Soubor existuje %1 already exists on disk or in the task list. Still use this name as the output filename? %1 už existuje na disku nebo v seznamu úloh. Opravdu použít toto jméno výstupního souboru? Remove Task Odebrat úlohu Cannot remove a task while it is in progress. Není možné odebrat úlohu která právě probíhá. Finished The text to be displayed on the progress bar when a conversion finishes Dokončeno Failed The text to be displayed on the progress bar when a conversion fails Došlo k selhání Error: %1 %1 is the error message Chyba:%1 ExtraTranslations Convert between media file formats Převést mezi formáty souborů Media Converter Převodník médií InteractiveCuttingDialog Cutting Cutting as in "cutting video" Sřih Mark as Begin Seek to Begin Play Selection Mark as End Seek to End %1 not found MainWindow QWinFF QWinFF Start conversion process. Začít konverzi. &Start &Start &File &Soubor &Convert &Konvertovat &About &O QWinFF &Edit &Upravit &Add Files &Přidat soubory Add files for conversion. Přidat soubory pro konverzi. Ctrl+N Ctrl+N E&xit &Konec Exit the program. Ukončit program. F9 F9 S&top S&top Stop conversion process. Zastavit konverzi. Set &Parameters Nastavit &Parametry Set Parameters Edit output file parameters. Nastavit Parametry Edit conversion parameters of selected files. Změnit parametry konverze vybraných souborů. About &Qt O &Qt About Qt O Qt &Open Output Folder &Otevřít výstupní složku Open output folder of the selected file. About &FFmpeg O &FFmpeg About FFmpeg O FFmpeg &Remove Selected remove selected (tasks, items) &Odebrat vybrané Remove all selected items in the list. Odebrat všechny vybrané ze seznamu. R&emove Completed remove completed (task, items) O&debrat celý seznam Remove Completed Items Odebrat celý seznam Remove all completed items in the list. Odebrat všechny dokončené ze seznamu. &Clear List &Vymazat seznam Clear List Vymazat seznam Remove all items in the list. Odebrat všechny soubory na seznamu. &Retry &Opakovat Retry Opakovat Retry selected tasks. Opakovat vybrané úlohy. Retry &All Opakovat &všechny Retry all tasks. Opakovat všechny úlohy. &Options &Nastavení Options Nastavení About Q&WinFF O Q&WinFF About This Program O tomto programu Change Output &Filename Změnit jméno výstupního &souboru Change the output filename of the selected item. Zmenít jméno výstupního souboru vybrané položky. Change Output &Directory Zmenit výstupní &složku Change the output directory of the selected items. Změnit výstupní složku vybrané položky. Show Error &Message Zobrazit Chybovou &Hlášku Check For &Updates Cut Cut video file (select a time range to conert) All tasks have finished. Všechny úlohy dokončeny. Nothing to convert. Není co konvertovat. Conversion is still in progress. Abort? Konverze stále probíhá, Ukončit? Shutdown Shutdown the computer (completely poweroff) Vypnout Shutdown when all tasks are done. Vyponout po dokončení všech úloh. Suspend Suspend the computer (sleep to ram, standby) Uspat Suspend when all tasks are done. Uspat po dokončení všech úloh. Hibernate Hibernate the computer (sleep to disk, completely poweroff) Hibernovat Hibernate when all tasks are done. Hibernovat po dokončení všech úloh. This program is going to check for updates online. Do you allow this program to use the Internet to check for updates? Failed to load preset file. The application will quit now. Nepodařilo se načíst soubor předvoleb. Tato aplikace se nyní ukončí. Elapsed Time: %1 h %2 m %3 s Uplynuvší čas: %1 h %2 m %3 s Converting %1/%2 Converting the %1-th file in %2 files. %2 is the number of files. MediaConverter %1 not found. %1 is a computer program OptionsDialog Options Nastavení General Check for updates on program startup Automatically start conversion after adding files to the list. Start conversion automatically FFmpeg FFmpeg Number of threads to use in conversion Počet vláken které je možné použít pro konverzi <html><head/><body><p>Hide output formats that are not available in the current ffmpeg installation. It is recommended to turn this option on unless you are sure that QWinFF has failed to detect available formats. (requires restarting QWinFF to take effect)</p></body></html> Hide unavailable formats (requires restarting) Tools Nástroje You have to restart QWinFF for the changes to take effect. Name Command Příkaz PoweroffDialog QWinFF QWinFF Cancel Zrušit Shutdown immediately Shutdown the computer Vypnout okamžitě Suspend immediately Suspend the computer (sleep to ram, standby) Uspat okamžitě Hibernate immediately Hibernate the computer (sleep to disk, completely poweroff) Hibernovat okamžitě Shutdown Shutdown the computer Vypnout Suspend Suspend the computer (sleep to ram, standby) Uspat Hibernate Hibernate the computer (sleep to disk, completely poweroff) Hibernovat Operation Failed: %1 Oprarace se nepovedla: %1 Shutting down in <b>%1</b> seconds Vypínám za <b>%1</b> sekund Suspending in <b>%1</b> seconds Uspávám za <b>%1</b> sekund Hibernating in <b>%1</b> seconds Hibernuji za <b>%1</b> sekund PreviewDialog Dialog Play Selected Range %1 not found Begin noun, the beginning of the video End noun, the end of the video Play %1~%2 play the video from time %1 to time %2. %1 and %2 are time in hh:mm:ss format. TimeRangeEdit From Begin Od začátku To End Do konce UpdateDialog Show &Release Notes Check for updates on program startup Downloading update information... Cannot connect to server. Failed to parse the received data. You are already using the latest version of QWinFF. An unknown error has occurred. A new version of QWinFF has been released! Version <b>%1</b> is available at %2. %1 is version number, %2 is the project homepage You can download this version using the link: qwinff-master/src/translations/qwinff_de.ts000066400000000000000000001123421347323557400215030ustar00rootroot00000000000000 AboutDialog About QWinFF Über QWinFF Information Information Translators Übersetzer Version: %1 Version: %1 Portable Portable Compiled with Qt %1 Kompiliert mit Qt %1 Compiled with libnotify %1 Kompiliert mit libnotify %1 QWinFF is a gui frontend for FFmpeg. QWinFF ist eine grafische Oberfläche für FFmpeg. Programming: %1 Programmierer: %1 Logo Design: %1 Logo Design: %1 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 or 3. Dieses Programm ist freie Software; Du kannst es weiterverteilen und/oder es verändern unter den Regeln der GNU General Public Lizenz Version 2 oder 3. QWinFF Homepage: %1 QWinFF Homepage: %1 Some audio-processing functionalities are provided by SoX. Einige Audio verarbeitende Funktionen werden von SoX bereitgestellt. FFmpeg presets were taken from WinFF. Die Voreinstellungen von FFmpeg wurden aus WinFF übernommen. Japanese Japanese Language Japanisch Italian Italian Language Italienisch Czech Czech Language Tschechisch Simplified Chinese Chinese character set used in China Chinesisch Russian Russian Language Russisch Spanish (Spain) Spanish Language (Spain) Spanisch (Spanien) Spanish (Guatemala) Spanish Language (Guatemala) Spanisch (Guatemala) Romanian Romanian Language Rumänisch Turkish Turkish Language Türkisch Arabic Arabic Language Arabisch Hungarian Hungarian Langauge Ungarisch Polish Polish Language Polnisch French French Language AboutFFmpegDialog About FFmpeg Über FFmpeg FFmpeg FFmpeg Available Codecs Verfügbare Codecs FFmpeg is a complete, cross-platform solution to record, convert and stream audio and video. It includes libavcodec - the leading audio/video codec library. ffmpeg description FFmpeg ist eine umfangreiche und plattformunabhängige Lösung um Audio und Video aufzunehmen, zu konvertieren und streamen. Es beinhaltet libavacodec - die führende Audio/Video Codec Bibliothek. FFmpeg is free software licensed under the LGPL or GPL. FFmpeg ist freie Software und steht unter der LGPL oder GPL. Please visit %1 for more information. Bitte besuchen Sie %1 für weitere Informationen. AddTaskWizard Add Tasks Aufgabe hinzufügen Files to be converted Zu konvertierende Dateien Add files. Dateien hinzufügen. Remove selected files. Markierte Dateien entfernen. Output Settings Ausgabeeinstellungen Edit Editieren Auto adjust output bitrate to reduce output file size. Automatische Einstellung der Bitrate um die Dateigröße zu reduzieren. Auto Adjust Audio Bitrate Automatische Einstellung der Audio Bitrate Preset Voreinstellung Convert to Konvertiere zu Output Path Ausgabepfad Select &folder &Ordner auswählen Browse Durchsuchen Create &new folder in source folder Create a new folder (e.g. qwinff_output) in the folder containing the input files. Put the output files in the newly created folder. Erstelle %neuen Ordner im Quellverzeichnis Folder Name Verzeichnisname Output to &source folder put the output files in the same folder as the input files Ausgabe und &Quellordner identisch Please select at least one file. Bitte zumindest eine Datei auswählen. Select Files This text is the title of an openfile dialog. Dateien auswählen Multimedia Multimedia Video Video Audio Audio All files Dateien hinzufügen Select Directory This text is the title of an open directory dialog. Verzeichnis auswählen Searching for files... Suche nach Dateien... Some files could not be found. Einige Dateien wurden nicht gefunden. Folder does not exist. Create a new folder? Verzeichnis existiert nicht. Neuen Ordner erstellen? Failed to create folder. Please select another output folder. Ordner konnte nicht erstellt werden. Bitte anderes Verzeichnis wählen. ConversionParameterDialog Conversion Parameters Parameter der Konvertierung Audio Audio Disable Audio Audio deaktivieren Audio Options Audio Optionen Sample Rate Abtastrate Hz Hz Bitrate Bitrate (auto) (auto) kb/s kb/s Channels Kanäle Volume Lautstärke % % Video Video Disable Video Video deaktiveren Video Options Video Optionen Same Quantizer as Source Gleicher Quantifizierer wie Quelldatei Deinterlace Deinterlace Width Breite px px Height Höhe Crop Ausschnitt Time time-related options (speed, length) Zeit Cutting video time cutting: options for begin time and end time Schneiden Cut Cut video; select a range to convert Schneide &Preview &Vorschau Scaling time scaling, changing the speed of the output file Skalierung Speed Geschwindigkeit Advanced Erweitert FFmpeg FFmpeg Additional FFmpeg Options Zusätzliche FFmpeg Optionen ConvertList Cancel Cancel the operation of adding new tasks Abbrechen Adding files (%1/%2) This text is the progress indicator of adding multiple tasks. %1 is the number of files that are already added. %2 is the total number of files. Füge Dateien hinzu (%1/%2) Some files are not recognized by the converter. Einige Dateien wurden vom Konverter nicht berücksichtigt. New File Name Neuer Dateiname Please input the new name for the output file. Bitte neuen Namen für die Ausgabedatei eingeben. Output Directory Ausgabeverzeichnis Error Message from FFmpeg: Fehlermeldung von FFmpeg: Drag and drop files here to add tasks. Um Aufgaben hinzuzufügen, hierher Dateien ablegen (drag & drop). Hide "%1" Hide a column in the list. For example, the text maybe 'Hide "Duration"'. The two " are quotation marks in English, you may replace it with local quotation marks. Verberge "%1" Restore All Columns Alle Spalten wiederherstellen Source Quelle Destination Ziel Duration Dauer File Size Dateigröße Sample Rate Audio Abtastrate Audio Bitrate Audio Bitrate Channels Audio Kanäle Audio Codec Audio Codec Dimensions Format Video Bitrate Video Bitrate Framerate Video Bildfrequenz Video Codec Video Codec Progress Fortschritt %1 Hz %1 Hz %1 kb/s %1 kb/s %1 fps %1 fps Removing tasks... Remove files from the tasklist Entferne Aufgaben... KiB KiB MiB MiB GiB GiB TiB TiB B Bytes B File Exists Datei vorhanden %1 already exists on disk or in the task list. Still use this name as the output filename? %1 ist auf dem Medium oder in der Aufgabenliste bereits vorhanden. Diesen Namen trotzdem für die Ausgabedatei verwenden? Remove Task Entferne Aufgabe Cannot remove a task while it is in progress. Während der Abarbeitung kann keine Aufgabe entfernt werden. Finished The text to be displayed on the progress bar when a conversion finishes Abgeschlossen Failed The text to be displayed on the progress bar when a conversion fails Fehlgeschlagen Error: %1 %1 is the error message Fehler: %1 ExtraTranslations Convert between media file formats Konvertiere zwischen verschiedenen Medienformaten Media Converter Media Konverter InteractiveCuttingDialog Cutting Cutting as in "cutting video" Schneide Mark as Begin Markiere als Anfang Seek to Begin Springe zum Anfang Play Selection Auswahl abspielen Mark as End Markiere als Ende Seek to End Springe zum Ende %1 not found %1 nicht gefunden MainWindow QWinFF QWinFF Start conversion process. Starte den Umwandlungsprozess. &Start &Start &File &Datei &Convert &Konvertiere &About &Über &Edit &Bearbeiten &Add Files &Dateien hinzufügen Add files for conversion. Dateien für Konvertierung hinzufügen Ctrl+N Ctrl+N E&xit B&eenden Exit the program. Das Programm beenden. F9 F9 S&top S&topp Stop conversion process. Stoppe den Umwandlungsprozess. Set &Parameters &Parameter einstellen Set Parameters Edit output file parameters. Parameter einstellen Edit conversion parameters of selected files. Konvertierungsparameter der ausgewählten Dateien ändern. About &Qt Über &Qt About Qt Über Qt &Open Output Folder &Öffne Ausgabeordner Open output folder of the selected file. Ausgabeordner der gewählten Datei öffnen. About &FFmpeg Über &FFmpeg About FFmpeg Über FFmpeg &Remove Selected remove selected (tasks, items) &Entferne markierte Remove all selected items in the list. Entferne alle markierten Objekte aus der Liste. R&emove Completed remove completed (task, items) E&ntferne fertiggestellte Remove Completed Items Entferne fertiggestellte Objekte Remove all completed items in the list. Entferne alle fertiggestellten Objekte aus der Liste. &Clear List &Lösche Liste Clear List Liste löschen Remove all items in the list. Entferne alle Objekte aus der Liste. &Retry &Wiederholen Retry Wiederholen Retry selected tasks. Wiederhole ausgewählte Aufgaben. Retry &All Wiederhole &alles Retry all tasks. Wiederhole alle Aufgaben. &Options &Optionen Options Optionen About Q&WinFF Über Q&WinFF About This Program Über dieses Programm Change Output &Filename Ändere &Dateiname der Ausgabe Change the output filename of the selected item. Ändere den Ausgabenamen der ausgewählten Datei. Change Output &Directory Ändere &Verzeichnis der Ausgabe Change the output directory of the selected items. Ändere Ausgabeverzeichnis der gewählten Dateien. Show Error &Message Zeige &Fehlermeldung Check For &Updates Suche nach &Updates Cut Cut video file (select a time range to conert) Schneide All tasks have finished. Alle Aufgaben abgeschlossen. Nothing to convert. Nichts zu konvertieren. Conversion is still in progress. Abort? Konvertierung läuft. Abbrechen? Shutdown Shutdown the computer (completely poweroff) Herunterfahren Shutdown when all tasks are done. Herunterfahren nachdem alle Aufgaben fertig sind. Suspend Suspend the computer (sleep to ram, standby) Standby Suspend when all tasks are done. Standby nachdem alle Aufgaben fertig sind. Hibernate Hibernate the computer (sleep to disk, completely poweroff) Ruhezustand Hibernate when all tasks are done. Ruhezustand nachdem alle Aufgaben fertig sind. This program is going to check for updates online. Do you allow this program to use the Internet to check for updates? Dieses Programm wird Online nach Updates suchen. Möchten Sie dem Programm den Internetzugriff erlauben? Failed to load preset file. The application will quit now. Laden der Voreinstellungen fehlgeschlaten. Das Programm wird nun beendet. Elapsed Time: %1 h %2 m %3 s Ausführungszeit: %1 h %2 m %3 s Converting %1/%2 Converting the %1-th file in %2 files. %2 is the number of files. Konvertiere %1/%2 MediaConverter %1 not found. %1 is a computer program %1 nicht gefunden. OptionsDialog Options Optionen General Allgemeines Check for updates on program startup Prüfe auf Updates bei Programmstart Automatically start conversion after adding files to the list. Starte Konvertierung automatisch nachdem Dateien der Liste hinzugefügt wurden. Start conversion automatically Starte Konvertierung automatisch FFmpeg FFmpeg Number of threads to use in conversion Anzahl der Prozessorthreads für Konvertierung <html><head/><body><p>Hide output formats that are not available in the current ffmpeg installation. It is recommended to turn this option on unless you are sure that QWinFF has failed to detect available formats. (requires restarting QWinFF to take effect)</p></body></html> <html><head/><body><p>Verberge Ausgabeformate, welche bei der installierten FFmpeg Version nicht verfügbar sind. Es ist empfholen diese Option zu aktivieren, es sei denn Sie sind sicher, dass QWinFF die verfügbaren Formate falsch erkannt hat. (Neustart von QWinFF notwendig)</p></body></html> Hide unavailable formats (requires restarting) Verberge nicht verfügbare Formate (Neustart erforderlich) Tools Werkzeuge You have to restart QWinFF for the changes to take effect. Sie müssen QWinFF neu starten, damit die Änderungen wirksam werden. Name Name Command Kommando PoweroffDialog QWinFF QWinFF Cancel Abbrechen Shutdown immediately Shutdown the computer Sofort herunterfahren Suspend immediately Suspend the computer (sleep to ram, standby) Sofort in Standby Hibernate immediately Hibernate the computer (sleep to disk, completely poweroff) Sofort in Ruhezustand Shutdown Shutdown the computer Herunterfahren Suspend Suspend the computer (sleep to ram, standby) Standby Hibernate Hibernate the computer (sleep to disk, completely poweroff) Ruhezustand Operation Failed: %1 Operation fehlgeschlagen: %1 Shutting down in <b>%1</b> seconds Herunterfahren in <b>%1</b> Sekunden Suspending in <b>%1</b> seconds Standby in <b>%1</b> Sekunden Hibernating in <b>%1</b> seconds Ruhezustand in <b>%1</b> Sekunden PreviewDialog Dialog Dialog Play Selected Range Ausgewählten Bereich abspielen %1 not found %1 nicht gefunden Begin noun, the beginning of the video Anfang End noun, the end of the video Ende Play %1~%2 play the video from time %1 to time %2. %1 and %2 are time in hh:mm:ss format. Abspielen %1~%2 TimeRangeEdit From Begin Vom Anfang To End Bis Ende UpdateDialog Show &Release Notes Zeige &Veröffentlichungsinfo Check for updates on program startup Suche nach Updates bei Programmstart Downloading update information... Lade Update-Informationen herunter... Cannot connect to server. Kann keine Verbindung zum Server herstellen. Failed to parse the received data. Kann empfangene Daten nicht analysieren. You are already using the latest version of QWinFF. Sie nutzen bereits die aktuellste Version von QWinFF. An unknown error has occurred. Ein unbekannter Fehler ist aufgetreten. A new version of QWinFF has been released! Eine neue Version von QWinFF wurde veröffentlicht! Version <b>%1</b> is available at %2. %1 is version number, %2 is the project homepage Version <b>%1</b> ist verfügbar unter %2. You can download this version using the link: Sie können mit diesem Link die Version herunterladen: qwinff-master/src/translations/qwinff_es_ES.ts000066400000000000000000001124571347323557400221200ustar00rootroot00000000000000 AboutDialog About QWinFF Acerca de QWinFF Information Información Translators Traductores Version: %1 Versión:%1 Portable Portable Compiled with Qt %1 Compilado con Qt %1 Compiled with libnotify %1 Compilado con libnotify %1 QWinFF is a gui frontend for FFmpeg. QWinFF es una interfaz gráfica de usuario para FFmpeg. Programming: %1 Programado: %1 Logo Design: %1 Diseño del Logo: %1 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 or 3. Este programa es software libre; tu puedes redistribuirlo y/o modificarlo bajo los términos de GNU Licencia Publica General versión 2 o 3. QWinFF Homepage: %1 Pagina web de QWinFF: %1 Some audio-processing functionalities are provided by SoX. Algunas funcionalidades de procesamiento de audio son provistas por SoX. FFmpeg presets were taken from WinFF. Pre-configuraciones de FFmepg fueron tomadas de WinFF. Japanese Japanese Language Japonés Italian Italian Language Italiano Czech Czech Language Checo Simplified Chinese Chinese character set used in China Chino Simplificado Russian Russian Language Ruso Spanish (Spain) Spanish Language (Spain) Español (España) Spanish (Guatemala) Spanish Language (Guatemala) Español (Guatemala) Romanian Romanian Language Rumano Turkish Turkish Language Arabic Arabic Language Hungarian Hungarian Langauge Polish Polish Language French French Language AboutFFmpegDialog About FFmpeg Acerca de FFmpeg FFmpeg FFmpeg Available Codecs Codecs disponibles FFmpeg is a complete, cross-platform solution to record, convert and stream audio and video. It includes libavcodec - the leading audio/video codec library. ffmpeg description FFmpeg es una completa solución multi-plataforma para grabar, convertir y transmitir audio y video. incluye libavcodec - la libreria lider de audio/video. FFmpeg is free software licensed under the LGPL or GPL. FFmpeg es software libre bajo licencia LGPL o GPL. Please visit %1 for more information. Por favor visite %1 para mas información. AddTaskWizard Add Tasks Agregar tareas Files to be converted Archivos a ser convertidos Add files. Agregar Archivos. Remove selected files. Remover archivos seleccionados. Output Settings Configuración de salida Edit Editar Auto adjust output bitrate to reduce output file size. Auto ajustar el bitrate de salida para reducir el tamaño de archivo de salida. Auto Adjust Audio Bitrate Auto ajustar el bitrate del audio Preset Convert to Convertir a Output Path Directorio de salida Select &folder Seleccionar &Carpeta Browse Explorar Create &new folder in source folder Create a new folder (e.g. qwinff_output) in the folder containing the input files. Put the output files in the newly created folder. Crear un nuevo folder en el folder de origen Folder Name Nombre de la carpeta Output to &source folder put the output files in the same folder as the input files Salida a la carpeta de origen Please select at least one file. Por favor seleccione al menos un archivo. Select Files This text is the title of an openfile dialog. Seleccione archivos Multimedia Multimedia Video Video Audio Audio All files Todos los archivos Select Directory This text is the title of an open directory dialog. Seleccione un directorio Searching for files... Buscando archivos... Some files could not be found. Algunos archivos no puedieron ser encontrados. Folder does not exist. Create a new folder? EL folder no existe. ¿Crear un nuevo folder? Failed to create folder. Please select another output folder. Fallo al crear el folder. Por favor seleccione otro folder de salida. ConversionParameterDialog Conversion Parameters Parámetros de conversión Audio Audio Disable Audio Desactivar audio Audio Options Opciones de Audio Sample Rate Hz Hz Bitrate Bitrate (auto) (auto) kb/s kb/s Channels Canales Volume Volume % % Video Video Disable Video Desactivar Video Video Options Opciones de video Same Quantizer as Source Deinterlace Desentrelazar Width Ancho px px Height Alto Crop Time time-related options (speed, length) Tiempo Cutting video time cutting: options for begin time and end time Cut Cut video; select a range to convert &Preview &Previsualizar Scaling time scaling, changing the speed of the output file Speed Velocidad Advanced Avanzado FFmpeg FFmpeg Additional FFmpeg Options Opciones adicionales de FFmpeg ConvertList Cancel Cancel the operation of adding new tasks Cancelar Adding files (%1/%2) This text is the progress indicator of adding multiple tasks. %1 is the number of files that are already added. %2 is the total number of files. Añadiendo archivos (%1/%2) Some files are not recognized by the converter. Algunos archivos no son reconocidos por el convertidor. New File Name Nuevo Nombre de Archivo Please input the new name for the output file. Por favor ingrese el nuevo nombre para el archivo de salida. Output Directory Directorio de Salida Error Message from FFmpeg: Mensage de error de FFmpeg: Drag and drop files here to add tasks. Arrastre y suelte los archivos aquí para añadir tareas. Hide "%1" Hide a column in the list. For example, the text maybe 'Hide "Duration"'. The two " are quotation marks in English, you may replace it with local quotation marks. Hide "%1" Restore All Columns Restaurar todas las columnas Source Fuente Destination Destino Duration Duración File Size Tamaño del archivo Sample Rate Audio Audio Bitrate Channels Audio Canales Audio Codec Dimensions Dimensiones Video Bitrate Framerate Video Video Codec Codec de video Progress Progreso %1 Hz %1 Hz %1 kb/s %1 kb/s %1 fps %1 fps Removing tasks... Remove files from the tasklist Removiendo tareas... KiB KiB MiB MiB GiB GiB TiB TiB B Bytes B File Exists El archivo existe %1 already exists on disk or in the task list. Still use this name as the output filename? %1 ya existe en el disco o en la lista de tareas. Aún así utilizar este nombre como nombre de archivo de salida? Remove Task Remover Tarea Cannot remove a task while it is in progress. No puede remover un tarea mientras está en progreso. Finished The text to be displayed on the progress bar when a conversion finishes Terminado Failed The text to be displayed on the progress bar when a conversion fails Falló Error: %1 %1 is the error message Error: %1 ExtraTranslations Convert between media file formats Convertir entre formados de archivos Media Converter Convertidor de Medios InteractiveCuttingDialog Cutting Cutting as in "cutting video" Mark as Begin Seek to Begin Play Selection Mark as End Seek to End %1 not found %1 no encontrado MainWindow QWinFF QWinFF Start conversion process. Iniciar proceso de converción. &Start &Iniciar &File &Archivo &Convert &Convertir &About Ace&rca de &Edit &Editar &Add Files A&ñadir Archivos Add files for conversion. Añadir archivos para convertir. Ctrl+N Ctrl+N E&xit &Salir Exit the program. Salir del programa. F9 F9 S&top &Detener Stop conversion process. Deterner proceso de converción. Set &Parameters Configurar &Parámetros Set Parameters Edit output file parameters. Configurar Parámetros Edit conversion parameters of selected files. Editar los parámetros de los archivos seleccionados. About &Qt Acerca de &Qt About Qt Acerca de Qt &Open Output Folder &Abrir directorio de salida Open output folder of the selected file. Abrir carpeta de salida del archivo seleccionado. About &FFmpeg Acerca de &FFmpeg About FFmpeg Acerca de FFmpeg &Remove Selected remove selected (tasks, items) &Remover Seleccionados Remove all selected items in the list. Remover todos los archivos seleccionados. R&emove Completed remove completed (task, items) Re&mover completado Remove Completed Items Remover archivos completados Remove all completed items in the list. Remover todos los archivos completados. &Clear List &Limpiar la lista Clear List Limpiar la lista Remove all items in the list. Remover todos los objetos en la lista. &Retry &Reintentar Retry Reintentar Retry selected tasks. Reintentar las tareas seleccionadas. Retry &All Reintentar &Todo Retry all tasks. Reintentar todas las tareas. &Options &Opciones Options Opciones About Q&WinFF Acerca de Q&WinFF About This Program Acerca de este programa Change Output &Filename &Carmbiar el nombre del archivo de salida Change the output filename of the selected item. Cambiar el nombre de salida de los archivos seleccionados. Change Output &Directory Cambiar el directorio de &salida Change the output directory of the selected items. Cambiar el directorio de salida de los archivos seleccionados. Show Error &Message &Mostrar mensage de error Check For &Updates Buscar &actualizaciones Cut Cut video file (select a time range to conert) All tasks have finished. Todas las tareas han finalizado. Nothing to convert. Nada que convertir. Conversion is still in progress. Abort? Converción aun en progreso. ¿Abortar? Shutdown Shutdown the computer (completely poweroff) Apagar Shutdown when all tasks are done. Apagar cuando todas las tareas esten terminadas. Suspend Suspend the computer (sleep to ram, standby) Suspender Suspend when all tasks are done. Suspender cuando todas las tareas esten terminadas. Hibernate Hibernate the computer (sleep to disk, completely poweroff) Hibernar Hibernate when all tasks are done. Hibernar cuando todas las tareas esten terminadas. This program is going to check for updates online. Do you allow this program to use the Internet to check for updates? Este programa va a comprobar si hay actualizaciones en línea. ¿Quiere dar permite a este programa a utilizar Internet para buscar actualizaciones? Failed to load preset file. The application will quit now. Fallo al cargar el archivo preestablecido. La aplicación se cerrará ahora. Elapsed Time: %1 h %2 m %3 s Tiempo estimado: %1 h %2 m %3 s Converting %1/%2 Converting the %1-th file in %2 files. %2 is the number of files. Convirtiendo %1/%2 MediaConverter %1 not found. %1 is a computer program %1 no encontrado. OptionsDialog Options Opciones General General Check for updates on program startup Buscar actualizaciones al iniciar el programa Automatically start conversion after adding files to the list. Iniciar automáticamente la conversión después de añadir archivos a la lista. Start conversion automatically Iniciar conversión automáticamente FFmpeg FFmpeg Number of threads to use in conversion Numero de procesos a usar en la converción <html><head/><body><p>Hide output formats that are not available in the current ffmpeg installation. It is recommended to turn this option on unless you are sure that QWinFF has failed to detect available formats. (requires restarting QWinFF to take effect)</p></body></html> <html><head/><body><p>Ocultar formatos de salida que no estan disponibles en la actual instalación de ffmpeg. Es recomendable activar esta opción hasta que este seguro que QWinFF ha fallado en detectar los formatos disponibles. (Se necesita reiniciar QWinFF para que la configuración tome efecto)</p></body></html> Hide unavailable formats (requires restarting) Ocultar formatos no disponibles (Requiere reiniciar) Tools Herramientas You have to restart QWinFF for the changes to take effect. Usted debe reiniciar QWinFF para que los cambios tomen efecto. Name Nombre Command Comando PoweroffDialog QWinFF QWinFF Cancel Cancelar Shutdown immediately Shutdown the computer Apagar inmediatamente Suspend immediately Suspend the computer (sleep to ram, standby) Suspender inmediatamente Hibernate immediately Hibernate the computer (sleep to disk, completely poweroff) Hibernar inmediatamente Shutdown Shutdown the computer Apagar Suspend Suspend the computer (sleep to ram, standby) Suspender Hibernate Hibernate the computer (sleep to disk, completely poweroff) Hibernar Operation Failed: %1 Operación fallida: %1 Shutting down in <b>%1</b> seconds Apagar en <b>%1</b> segundos Suspending in <b>%1</b> seconds Suspender en <b>%1</b> segundos Hibernating in <b>%1</b> seconds Hibernar en <b>%1</b> segundos PreviewDialog Dialog Diálogo Play Selected Range Reproducir Rango Seleccionado %1 not found %1 no encontrado Begin noun, the beginning of the video Inicio End noun, the end of the video Final Play %1~%2 play the video from time %1 to time %2. %1 and %2 are time in hh:mm:ss format. Reprodución %1~%2 TimeRangeEdit From Begin Desde el inicio To End Al Final UpdateDialog Show &Release Notes Ver Notas del lanzamiento. Check for updates on program startup Buscar actualizaciones al iniciar el programa Downloading update information... Cannot connect to server. No se puede conectar al servidor. Failed to parse the received data. Error al analizar los datos recibidos. You are already using the latest version of QWinFF. Ya está usando la versión mas reciente de QWinFF. An unknown error has occurred. Un error desconocido ha ocurrido. A new version of QWinFF has been released! ¡Una nueva versión de QWinFF ha sido lanzada! Version <b>%1</b> is available at %2. %1 is version number, %2 is the project homepage You can download this version using the link: Puede descargar esta versión usando el enlace: qwinff-master/src/translations/qwinff_es_GT.ts000066400000000000000000001131221347323557400221110ustar00rootroot00000000000000 AboutDialog About QWinFF Acerca de QWinFF Information Información Translators Traductores Version: %1 Versión:%1 Portable Portable Compiled with Qt %1 Compilado con Qt %1 Compiled with libnotify %1 Compilado con libnotify %1 QWinFF is a gui frontend for FFmpeg. QWinFF es una interfaz gráfica de usuario para FFmpeg. Programming: %1 Programado: %1 Logo Design: %1 Diseño del Logo: %1 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 or 3. Este programa es software libre; tu puedes redistribuirlo y/o modificarlo bajo los términos de GNU Licencia Publica General versión 2 o 3. QWinFF Homepage: %1 Pagina web de QWinFF: %1 Some audio-processing functionalities are provided by SoX. Algunas funcionalidades de procesamiento de audio son provistas por SoX. FFmpeg presets were taken from WinFF. Pre-configuraciones de FFmepg fueron tomadas de WinFF. Japanese Japanese Language Japonés Italian Italian Language Italiano Czech Czech Language Checo Simplified Chinese Chinese character set used in China Chino Simplificado Russian Russian Language Spanish (Spain) Spanish Language (Spain) Spanish (Guatemala) Spanish Language (Guatemala) Romanian Romanian Language Turkish Turkish Language Arabic Arabic Language Hungarian Hungarian Langauge Polish Polish Language French French Language AboutFFmpegDialog About FFmpeg Acerca de FFmpeg FFmpeg FFmpeg Available Codecs Codecs disponibles FFmpeg is a complete, cross-platform solution to record, convert and stream audio and video. It includes libavcodec - the leading audio/video codec library. ffmpeg description FFmpeg es una completa solución multi-plataforma para grabar, convertir y transmitir audio y video. incluye libavcodec - la libreria lider de audio/video. FFmpeg is free software licensed under the LGPL or GPL. FFmpeg es software libre bajo licencia LGPL o GPL. Please visit %1 for more information. Por favor visite %1 para mas información. AddTaskWizard Add Tasks Agregar tareas Files to be converted Archivos a ser convertidos Add files. Agregar Archivos. Remove selected files. Remover archivos seleccionados. Output Settings Configuración de salida Convert to Convertir a Create &new folder in source folder Create a new folder (e.g. qwinff_output) in the folder containing the input files. Put the output files in the newly created folder. Folder Name Output to &source folder put the output files in the same folder as the input files Preset Preestablecido Edit Editar Output Path Directorio de salida Select &folder Browse Explorar Auto adjust output bitrate to reduce output file size. Auto ajustar el bitrate de salida para reducir el tamaño de archivo de salida. Auto Adjust Audio Bitrate Auto ajustar el bitrate del audio Please select at least one file. Por favor seleccione al menos un archivo. Folder does not exist. Create a new folder? EL folder no existe. ¿Crear un nuevo folder? Failed to create folder. Please select another output folder. Fallo al crear el folder. Por favor seleccione otro folder de salida. Select Files This text is the title of an openfile dialog. Seleccione archivos Multimedia Video Audio All files Todos los archivos Some files could not be found. Algunos archivos no puedieron ser encontrados. Select Directory This text is the title of an open directory dialog. Seleccione un directorio Searching for files... ConversionParameterDialog Conversion Parameters Parámetros de conversión Audio Disable Audio Desactivar audio Audio Options Opciones de Audio Sample Rate Muestreo Hz Channels Canales (auto) Volume % Bitrate kb/s Video Disable Video Desactivar Video Video Options Opciones de video Width Ancho px Height Alto Use same video quality as source (implies VBR). Usar la misma calidad de video que la fuente (implica VBR). Deinterlace Desentrelazar Crop Cortar Same Quantizer as Source Time time-related options (speed, length) Tiempo Cutting video time cutting: options for begin time and end time Cortando From Begin Desde el inicio To End Al Final &Preview &Previsualizar Scaling time scaling, changing the speed of the output file Escala Speed Velocidad Advanced Avanzado FFmpeg FFmpeg Additional FFmpeg Options Opciones adicionales de FFmpeg Cut Cut video; select a range to convert ConvertList Cancel Cancel the operation of adding new tasks Cancelar Adding files (%1/%2) This text is the progress indicator of adding multiple tasks. %1 is the number of files that are already added. %2 is the total number of files. Añadiendo archivos (%1/%2) Some files are not recognized by the converter. Algunos archivos no son reconocidos por el convertidor. Remove Task Remover Tarea Cannot remove a task while it is in progress. No puede remover un tarea mientras está en progreso. New File Name Nuevo Nombre de Archivo Please input the new name for the output file. Por favor ingrese el nuevo nombre para el archivo de salida. Output Directory Directorio de Salida Error Message from FFmpeg: Mensage de error de FFmpeg: Failed The text to be displayed on the progress bar when a conversion fails Falló Error: %1 %1 is the error message Error: %1 Finished The text to be displayed on the progress bar when a conversion finishes Terminado Drag and drop files here to add tasks. Hide "%1" Hide a column in the list. For example, the text maybe 'Hide "Duration"'. The two " are quotation marks in English, you may replace it with local quotation marks. Hide "%1" Restore All Columns Restaurar todas las columnas Source Fuente Destination Destino Duration Duración File Size Tamaño del archivo Sample Rate Audio Muestreo Audio Bitrate Channels Audio Canales Audio Codec Codec de audio Dimensions Dimensiones Video Bitrate Framerate Video Video Codec Codec de video Progress Progreso %1 Hz %1 kb/s %1 fps Removing tasks... Remove files from the tasklist Removiendo tareas... KiB MiB GiB TiB B Bytes File Exists El archivo existe %1 already exists on disk or in the task list. Still use this name as the output filename? %1 ya existe en el disco o en la lista de tareas. Aún así utilizar este nombre como nombre de archivo de salida? ExtraTranslations Convert between media file formats Convertir entre formados de archivos Media Converter Convertidor de Medios InteractiveCuttingDialog Mark as Begin Seek to Begin Play Selection Mark as End Seek to End %1 not found Cutting Cutting as in "cutting video" Cortando MainWindow QWinFF QWinFF &File &Archivo &Convert &Convertir &About Ace&rca de &Edit &Editar &Add Files A&ñadir Archivos Add files for conversion. Añadir archivos para convertir. Ctrl+N Ctrl+N E&xit &Salir Exit the program. Salir del programa. &Start &Iniciar Start conversion process. Iniciar proceso de converción. F9 S&top &Detener Stop conversion process. Deterner proceso de converción. Set &Parameters Configurar &Parámetros Set Parameters Edit output file parameters. Configurar Parámetros Edit conversion parameters of selected files. Editar los parámetros de los archivos seleccionados. About &Qt Acerca de &Qt About Qt Acerca de Qt &Open Output Folder &Abrir directorio de salida Open output folder of the selected file. About &FFmpeg Acerca de &FFmpeg About FFmpeg Acerca de FFmpeg &Remove Selected remove selected (tasks, items) &Remover Seleccionados Remove all selected items in the list. Remover todos los archivos seleccionados. R&emove Completed remove completed (task, items) Re&mover completado Remove Completed Items Remover archivos completados Remove all completed items in the list. Remover todos los archivos completados. &Clear List &Limpiar la lista Clear List Limpiar la lista Remove all items in the list. Remover todos los objetos en la lista. &Retry &Reintentar Retry Reintentar Retry selected tasks. Reintentar las tareas seleccionadas. Retry &All Reintentar &Todo Retry all tasks. Reintentar todas las tareas. &Options &Opciones Options Opciones About Q&WinFF Acerca de Q&WinFF About This Program Acerca de este programa Change Output &Filename &Carmbiar el nombre del archivo de salida Change the output filename of the selected item. Cambiar el nombre de salida de los archivos seleccionados. Change Output &Directory Cambiar el directorio de &salida Change the output directory of the selected items. Cambiar el directorio de salida de los archivos seleccionados. Show Error &Message &Mostrar mensage de error Check For &Updates All tasks have finished. Todas las tareas han finalizado. Nothing to convert. Nada que convertir. Conversion is still in progress. Abort? Converción aun en progreso. ¿Abortar? Elapsed Time: %1 h %2 m %3 s Shutdown Shutdown the computer (completely poweroff) Apagar Shutdown when all tasks are done. Apagar cuando todas las tareas esten terminadas. Suspend Suspend the computer (sleep to ram, standby) Suspender Suspend when all tasks are done. Suspender cuando todas las tareas esten terminadas. Hibernate Hibernate the computer (sleep to disk, completely poweroff) Hibernar Hibernate when all tasks are done. Hibernar cuando todas las tareas esten terminadas. This program is going to check for updates online. Do you allow this program to use the Internet to check for updates? Failed to load preset file. The application will quit now. Fallo al cargar el archivo preestablecido. La aplicación se cerrará ahora. Converting %1/%2 Converting the %1-th file in %2 files. %2 is the number of files. Cut Cut video file (select a time range to conert) MediaConverter %1 not found. %1 is a computer program OptionsDialog Options Opciones General Check for updates on program startup Automatically start conversion after adding files to the list. Start conversion automatically FFmpeg FFmpeg Number of threads to use in conversion Numero de procesos a usar en la converción <html><head/><body><p>Hide output formats that are not available in the current ffmpeg installation. It is recommended to turn this option on unless you are sure that QWinFF has failed to detect available formats. (requires restarting QWinFF to take effect)</p></body></html> <html><head/><body><p>Ocultar formatos de salida que no estan disponibles en la actual instalación de ffmpeg. Es recomendable activar esta opción hasta que este seguro que QWinFF ha fallado en detectar los formatos disponibles. (Se necesita reiniciar QWinFF para que la configuración tome efecto)</p></body></html> Hide unavailable formats (requires restarting) Ocultar formatos no disponibles (Requiere reiniciar) Tools You have to restart QWinFF for the changes to take effect. Name Command PoweroffDialog QWinFF QWinFF Cancel Cancelar Shutdown immediately Shutdown the computer Apagar inmediatamente Suspend immediately Suspend the computer (sleep to ram, standby) Suspender inmediatamente Hibernate immediately Hibernate the computer (sleep to disk, completely poweroff) Hibernar inmediatamente Shutdown Shutdown the computer Apagar Suspend Suspend the computer (sleep to ram, standby) Suspender Hibernate Hibernate the computer (sleep to disk, completely poweroff) Hibernar Operation Failed: %1 Operación fallida: %1 Shutting down in <b>%1</b> seconds Apagar en <b>%1</b> segundos Suspending in <b>%1</b> seconds Suspender en <b>%1</b> segundos Hibernating in <b>%1</b> seconds Hibernar en <b>%1</b> segundos PreviewDialog Dialog Play Selected Range %1 not found Begin noun, the beginning of the video End noun, the end of the video Play %1~%2 play the video from time %1 to time %2. %1 and %2 are time in hh:mm:ss format. TimeRangeEdit From Begin Desde el inicio To End Al Final UpdateDialog Show &Release Notes Check for updates on program startup Downloading update information... Cannot connect to server. Failed to parse the received data. You are already using the latest version of QWinFF. An unknown error has occurred. A new version of QWinFF has been released! Version <b>%1</b> is available at %2. %1 is version number, %2 is the project homepage You can download this version using the link: qwinff-master/src/translations/qwinff_fr.ts000066400000000000000000001134511347323557400215240ustar00rootroot00000000000000 AboutDialog About QWinFF A propos de QWinFF Information Information Translators Traducteurs Version: %1 Version: %1 Portable Portable Compiled with Qt %1 Compilé avec Qt %1 Compiled with libnotify %1 Compilé avec libnotify %1 QWinFF is a gui frontend for FFmpeg. QWinFF est une interface graphique pour FFmpeg. Programming: %1 Programmeur : %1 Logo Design: %1 Auteur du logo : %1 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 or 3. Ce programme est un logiciel libre. Vous pouvez le redistribuer et/ou le modifier, sous les termes de la licence GNU General Public License version 2 ou 3. QWinFF Homepage: %1 Site web de QWinFF : %1 Some audio-processing functionalities are provided by SoX. Certaines fonctionnalités du traitement audio sont fournis par SOX. FFmpeg presets were taken from WinFF. Les présélections pour FFmpeg sont tirées de WinFF. Japanese Japanese Language Japonais Italian Italian Language Italien Czech Czech Language Tchèque Simplified Chinese Chinese character set used in China Chinois simplifié Russian Russian Language Russe Spanish (Spain) Spanish Language (Spain) Espagnol (Espagne) Spanish (Guatemala) Spanish Language (Guatemala) Espagnol (Guatemala) Romanian Romanian Language Roumain Turkish Turkish Language Turc Arabic Arabic Language Arabe Hungarian Hungarian Langauge Hongrois Polish Polish Language Polonais French French Language AboutFFmpegDialog About FFmpeg A propos de FFmpeg FFmpeg FFmpeg Available Codecs Codecs disponibles FFmpeg is a complete, cross-platform solution to record, convert and stream audio and video. It includes libavcodec - the leading audio/video codec library. ffmpeg description FFmpeg est une solution complète et multi-plateforme, pour enregistrer, convertir et diffuser de l'audio et de la vidéo. Il comprend libavcodec - la principale bibliothèque de codec audio/vidéo. FFmpeg is free software licensed under the LGPL or GPL. FFmpeg est un logiciel libre sous licence LGPL ou GPL. Please visit %1 for more information. Pour plus d'informations visitez : %1. AddTaskWizard Add Tasks Nouvelle conversion Files to be converted Les fichiers à convertir Add files. Ajouter des fichiers. Remove selected files. Enlever les fichiers sélectionnés. Output Settings Options de conversion Edit Modifier Auto adjust output bitrate to reduce output file size. Ajuster automatiquement le qualité pour réduire le poids du fichier. Auto Adjust Audio Bitrate Ajustement automatique de la qualité audio Preset Présélection Convert to Convertir en Output Path Dossier de sortie Select &folder Sélectionner un &dossier Browse Parcourir Create &new folder in source folder Create a new folder (e.g. qwinff_output) in the folder containing the input files. Put the output files in the newly created folder. Créer un &nouveau dossier à côté du fichier d'origine Folder Name Nom du dossier Output to &source folder put the output files in the same folder as the input files Enregistrer dans le dossier d'&origine Please select at least one file. Sélectionnez au moins un fichier. Select Files This text is the title of an openfile dialog. Sélectionner un fichier Multimedia Multimédia Video Vidéo Audio Audio All files Tous les fichiers Select Directory This text is the title of an open directory dialog. Sélectionner un dossier Searching for files... Recherche de fichiers en cours... Some files could not be found. Certains fichiers sont introuvable. Folder does not exist. Create a new folder? Ce dossier n'existe pas. Voulez-vous le créer ? Failed to create folder. Please select another output folder. Impossible de créer le dossier. Sélectionnez-en un autre. ConversionParameterDialog Conversion Parameters Paramètres de conversion Audio Audio Disable Audio Désactiver le son Audio Options Options pour le son Sample Rate Taux d'échantillonnage Hz Hz Bitrate Qualité (auto) (automatique) kb/s kb/s Channels Canaux Volume Volume % % Video Vidéo Disable Video Désactiver la vidéo Video Options Options pour la vidéo Same Quantizer as Source Même quantificateur que la source Deinterlace Désentrelacer Width Largeur px px Height Hauteur Crop Rogner Time time-related options (speed, length) Durée Cutting video time cutting: options for begin time and end time Couper Cut Cut video; select a range to convert Couper &Preview &Prévisualiser Scaling time scaling, changing the speed of the output file Ajuster la durée Speed Vitesse Advanced Avancé FFmpeg FFmpeg Additional FFmpeg Options Paramètres transmis à FFmpeg ConvertList Cancel Cancel the operation of adding new tasks Annuler Adding files (%1/%2) This text is the progress indicator of adding multiple tasks. %1 is the number of files that are already added. %2 is the total number of files. Ajout en cours du fichier (%1/%2) Some files are not recognized by the converter. Certains fichiers ne sont pas reconnus par le convertisseur. New File Name Nouveau nom de fichier Please input the new name for the output file. Insérez le nouveau nom du fichier de sortie. Output Directory Dossier de sortie Error Message from FFmpeg: Message d'erreur de FFmpeg : Drag and drop files here to add tasks. Glisser et déposer ici les fichiers à ajouter à la liste. Hide "%1" Hide a column in the list. For example, the text maybe 'Hide "Duration"'. The two " are quotation marks in English, you may replace it with local quotation marks. Cacher "%1" Restore All Columns Restaurer toutes les colonnes Source Source Destination Destination Duration Durée File Size Taille du fichier Sample Rate Audio Taux d'échantillonage Audio Bitrate Qualité audio Channels Audio Canaux Audio Codec Codec audio Dimensions Dimensions Video Bitrate Qualité vidéo Framerate Video Nombre d'image par seconde Video Codec Codec vidéo Progress Progression %1 Hz %1 Hz %1 kb/s %1 kb/s %1 fps %1 fps Removing tasks... Remove files from the tasklist Suppresion des tâches de la liste... KiB KiB MiB MiB GiB GiB TiB TiB B Bytes B File Exists Fichier existant %1 already exists on disk or in the task list. Still use this name as the output filename? %1 existe déjà sur le disque ou bien il est déjà dans le liste des tâches. Utiliser encore ce nom comme nom de ficher de sortie ? Remove Task Supprimer une tâche Cannot remove a task while it is in progress. Impossibled'enlever une tâche quand elle se convertie. Finished The text to be displayed on the progress bar when a conversion finishes Terminé Failed The text to be displayed on the progress bar when a conversion fails Erreur Error: %1 %1 is the error message Erreur : %1 ExtraTranslations Convert between media file formats Convertir en différents format de fichier média Media Converter Convertir un média InteractiveCuttingDialog Cutting Cutting as in "cutting video" Couper le début et la fin Mark as Begin Indiquer comme nouveau début Seek to Begin Positionner le curseur au début Play Selection Lire la sélection Mark as End Indiquer comme nouvelle fin Seek to End Positionner le curseur à la fin %1 not found %1 introuvable MainWindow QWinFF QWinFF Start conversion process. Démarrer le processus de conversion. &Start &Convertir &File &Fichier &Convert &Convertir &About A &propos de &Edit &Modifier &Add Files &Ajouter des fichiers Add files for conversion. Ajouter des fichiers pour la conversion. Ctrl+N Ctrl+N E&xit &Quitter Exit the program. Quitter le programme. F9 F9 S&top Arrê&ter Stop conversion process. Stopper le processus de conversion. Set &Parameters Configurer les &paramètres Set Parameters Edit output file parameters. Configurer des paramètres Edit conversion parameters of selected files. Modifier les paramètres de conversion des fichiers sélectionnés. About &Qt A propos de &Qt About Qt A propos de Qt &Open Output Folder &Ouvrir le dossier de sortie Open output folder of the selected file. Ouvrir le dossier de sortie du fichier sélectionné. About &FFmpeg A propos de &FFmpeg About FFmpeg A propos de FFmpeg &Remove Selected remove selected (tasks, items) &Enlever la sélection Remove all selected items in the list. Enlever tous les éléments sélectionnés de la liste. R&emove Completed remove completed (task, items) Enl&ever les conversions terminés Remove Completed Items Enlever les éléments terminés Remove all completed items in the list. Enlever tous les éléments convertis de la liste. &Clear List Effa&cer la liste Clear List Effacer la liste Remove all items in the list. Enlever tous les éléments de la liste. &Retry &Réessayer Retry Réessayer Retry selected tasks. Réessayer les tâches sélectionnés. Retry &All Tout réess&ayer Retry all tasks. Tout réessayer. &Options &Options Options Options About Q&WinFF A propos de Q&WinFF About This Program A propos de ce programme Change Output &Filename Changer le nom de l'élé&ment à la conversion Change the output filename of the selected item. Changer le nom de l'élément sélectionné, à la conversion. Change Output &Directory Changer le &dossier de sortie Change the output directory of the selected items. Changer le dossier de sortie des titres sélectionnés. Show Error &Message Montrer les &messages d'erreurs Check For &Updates &Vérifier les mises à jours Cut Cut video file (select a time range to conert) Couper All tasks have finished. Toutes les tâches sont terminés. Nothing to convert. Rien à convertir. Conversion is still in progress. Abort? Conversion en cours... Annuler ? Shutdown Shutdown the computer (completely poweroff) Eteindre Shutdown when all tasks are done. Eteindre quand toutes les tâches seront terminés. Suspend Suspend the computer (sleep to ram, standby) Mettre en veille Suspend when all tasks are done. Mettre en veille quand toutes les tâches seront terminés. Hibernate Hibernate the computer (sleep to disk, completely poweroff) Hiberner Hibernate when all tasks are done. Hiberner quand toutes les tâches seront terminés. This program is going to check for updates online. Do you allow this program to use the Internet to check for updates? Ce programme va vérifier les mises à jour en ligne. Voulez-vous permettre à ce programme d'utiliser Internet pour vérifier les mises à jour ? Failed to load preset file. The application will quit now. Impossible d'ouvrir le fichier des préselections. L'application va se terminer. Elapsed Time: %1 h %2 m %3 s Durée restante : %1h %2m %3s Converting %1/%2 Converting the %1-th file in %2 files. %2 is the number of files. Conversion %1/%2 MediaConverter %1 not found. %1 is a computer program %1 introuvable. OptionsDialog Options Options General Général Check for updates on program startup Vérifier les mises à jour au démarrage du programme Automatically start conversion after adding files to the list. Conversion automatique des fichiers après leurs ajout à la liste. Start conversion automatically Démarrer la conversion automatiquement FFmpeg FFmpeg Number of threads to use in conversion Nombre de processus à utiliser pour la conversion <html><head/><body><p>Hide output formats that are not available in the current ffmpeg installation. It is recommended to turn this option on unless you are sure that QWinFF has failed to detect available formats. (requires restarting QWinFF to take effect)</p></body></html> <html><head/><body><p>Masquer les formats de sortie qui ne sont pas disponibles dans l'installation actuelle de FFmpeg. Il est recommandé d'activer cette option seulement si vous êtes sûr que QWinFF n'a pas réussi à détecter les formats disponibles. (nécessite le redémarrage QWinFF pour être effectif)</p></body></html> Hide unavailable formats (requires restarting) Cacher les formats indisponibles (nécessite le redémarrage) Tools outils You have to restart QWinFF for the changes to take effect. Vous devez redémarrer QWinFF pour que les changements soit effectifs. Name Nom Command Commande PoweroffDialog QWinFF QWinFF Cancel Annuler Shutdown immediately Shutdown the computer Eteindre tout de suite Suspend immediately Suspend the computer (sleep to ram, standby) Mise en veille tout de suite Hibernate immediately Hibernate the computer (sleep to disk, completely poweroff) Hiberner tout de suite Shutdown Shutdown the computer Eteindre Suspend Suspend the computer (sleep to ram, standby) Mise en veille Hibernate Hibernate the computer (sleep to disk, completely poweroff) Hiberner Operation Failed: %1 Opération annulé : %1 Shutting down in <b>%1</b> seconds Extinction dans <b>%1</b> secondes Suspending in <b>%1</b> seconds Mise en veille dans <b>%1</b> secondes Hibernating in <b>%1</b> seconds Hiberner dans <b>%1</b> secondes PreviewDialog Dialog Dialogue Play Selected Range Lire la zone sélectionné %1 not found %1 introuvable Begin noun, the beginning of the video Début End noun, the end of the video Fin Play %1~%2 play the video from time %1 to time %2. %1 and %2 are time in hh:mm:ss format. Lire de %1 jusqu'à %2 TimeRangeEdit From Begin Début à To End Fin à UpdateDialog Show &Release Notes Montrer les notes des &sorties Check for updates on program startup Vérifier les mises à jours au démarrage du programme Downloading update information... Télécharger les dernières informations... Cannot connect to server. Impossible de se connecter au serveur. Failed to parse the received data. Impossible de découper les données reçus. You are already using the latest version of QWinFF. Vous utilisez déjà la dernière version de QWinFF. An unknown error has occurred. Une erreur inconnue est apparue. A new version of QWinFF has been released! Une nouvelle version de QWinFF est sortie ! Version <b>%1</b> is available at %2. %1 is version number, %2 is the project homepage La version <b>%1</b> est disponible sur %2. You can download this version using the link: Vous pouvez télécharger cette version depuis le lien : qwinff-master/src/translations/qwinff_hu_HU.ts000066400000000000000000001127051347323557400221260ustar00rootroot00000000000000 AboutDialog About QWinFF A QWinFF-ről Information Információ Translators Fordítók Version: %1 Verzió: %1 Portable Hordozható Compiled with Qt %1 Fordítva Qt %1 verzióval Compiled with libnotify %1 Fordítva libnotify %1 verzióval QWinFF is a gui frontend for FFmpeg. QWinFF egy grafikus előtétprogram az FFmpeg-hez. Programming: %1 A program készítője: %1 Logo Design: %1 Logo terv: %1 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 or 3. Ez a program szabad szoftver: terjeszthető és/vagy módosítható a GNU Általános Nyilvános Licenc (GNU GPLv2 / GPLv3) szerint. QWinFF Homepage: %1 QWinFF honlap: %1 Some audio-processing functionalities are provided by SoX. Néhány audió feldolgozó funkciót a SoX biztosít. FFmpeg presets were taken from WinFF. Az FFmpeg alapbeállításai a WinFF-ből származnak. Japanese Japanese Language Japán Italian Italian Language Olasz Czech Czech Language Cseh Simplified Chinese Chinese character set used in China Egyszerűsített kínai Russian Russian Language Orosz Spanish (Spain) Spanish Language (Spain) Spanyol Spanish (Guatemala) Spanish Language (Guatemala) Spanyol (Guatemala) Romanian Romanian Language Román Turkish Turkish Language Török Arabic Arabic Language Arab Hungarian Hungarian Langauge Magyar Polish Polish Language French French Language AboutFFmpegDialog About FFmpeg Az FFmpeg-ről: FFmpeg FFmpeg Available Codecs Elérhető kodekek FFmpeg is a complete, cross-platform solution to record, convert and stream audio and video. It includes libavcodec - the leading audio/video codec library. ffmpeg description Az FFmpeg teljes körű, keresztplatfomos megoldás videó- és hangfájlok felvételére, átalakítására és továbbítására. Ez tartalmazza a vezető audio/video könytárat, a libavcodec-et. FFmpeg is free software licensed under the LGPL or GPL. Az FFmpeg szabad szoftver. Licensze: LGPL vagy GPL Please visit %1 for more information. További információért látogassa meg a honlapot: %1 AddTaskWizard Add Tasks Feladat hozzáadása Files to be converted Átalakítandó fájlok Add files. Fájlok hozzáadása Remove selected files. Kiválasztott fájlok eltávolítása Output Settings Kimeneti beállítások Edit Szerkesztés Auto adjust output bitrate to reduce output file size. A kimeneti bitráta automatikus beállítása a fájlméret csökkentése érdekében. Auto Adjust Audio Bitrate Audio bitráta automatikus beállítása Preset Előbeállítás Convert to Átalakítás ebbe: Output Path Kimeneti elérési út Select &folder Mappa kiválasztása Browse Böngészés Create &new folder in source folder Create a new folder (e.g. qwinff_output) in the folder containing the input files. Put the output files in the newly created folder. Új mappa létrehozása a bemeneti fájlok mappájában Folder Name Mappa neve Output to &source folder put the output files in the same folder as the input files Kimeneti fájlok a forrás mappába Please select at least one file. Legalább egy fájlt válasszon ki Select Files This text is the title of an openfile dialog. Fájlok kiválasztása Multimedia Multimédia Video Videó Audio Audió All files Minden fájl Select Directory This text is the title of an open directory dialog. Válasszon Könyvtárat Searching for files... Fájlok keresése... Some files could not be found. Néhány fájl nem található Folder does not exist. Create a new folder? A mappa nem létezik. Létrehozza? Failed to create folder. Please select another output folder. Mappa létrehozása sikertelen. Válasszon másik kimeneti mappát. ConversionParameterDialog Conversion Parameters Átalakítási paraméterek Audio Audió Disable Audio Audió inaktív Audio Options Audió lehetőségek Sample Rate MIntavételezési ráta Hz Hz Bitrate Bitráta (auto) (auto) kb/s kb/s Channels Csatornák Volume Hangerő % % Video Videó Disable Video Inaktív videó Video Options Videó lehetőségek Same Quantizer as Source A forrásal megegyező kvantáló Deinterlace Váltottsorosság megszüntetése Width Szélesség px px Height Magasság Crop Levágás Time time-related options (speed, length) Idő Cutting video time cutting: options for begin time and end time Vágás Cut Cut video; select a range to convert &Preview &Előnézet Scaling time scaling, changing the speed of the output file Méretezés Speed Sebesség Advanced Haladó FFmpeg FFmpeg Additional FFmpeg Options További FFmpeg lehetőségek ConvertList Cancel Cancel the operation of adding new tasks Mégsem Adding files (%1/%2) This text is the progress indicator of adding multiple tasks. %1 is the number of files that are already added. %2 is the total number of files. Fájlok hozzáadása (%1/%2) Some files are not recognized by the converter. Néhány fájl az átalakító számára nem felismerhető. New File Name Új fájlnév Please input the new name for the output file. Adjon meg új nevet a kimeneti fájlnak. Output Directory Kimeneti könyvtár Error Message from FFmpeg: FFmpeg hibaüzenet: Drag and drop files here to add tasks. Húzzon ide fájlokat a feladatok hozzáadásához. Hide "%1" Hide a column in the list. For example, the text maybe 'Hide "Duration"'. The two " are quotation marks in English, you may replace it with local quotation marks. "%1" elrejtése Restore All Columns Összes oszlop visszaállítása Source Forrás Destination Cél Duration Időtartam File Size Fájl mérete Sample Rate Audio MIntavételezési ráta Audio Bitrate Audió bitráta Channels Audio Csatornák Audio Codec Audió kodek Dimensions Méret Video Bitrate Videó bitráta Framerate Video Képkockák Video Codec Videó kodek Progress Folyamat %1 Hz %1 Hz %1 kb/s %1 kb/s %1 fps %1 fps Removing tasks... Remove files from the tasklist Feladat eltávolítása... KiB KiB MiB MiB GiB GiB TiB TiB B Bytes B File Exists Létező fájl %1 already exists on disk or in the task list. Still use this name as the output filename? A(z) %1 már létezik a lemezen vagy a feladatlistában. Továbbra is ezt használjha kimeneti fájlnévként? Remove Task Feladat eltávolítása Cannot remove a task while it is in progress. Folyamatban lévő feladat nem távolítható el! Finished The text to be displayed on the progress bar when a conversion finishes Befejezve Failed The text to be displayed on the progress bar when a conversion fails Sikertelen Error: %1 %1 is the error message Hiba :%1 ExtraTranslations Convert between media file formats Média fájlformátumok átalakítása Media Converter Média átalakító InteractiveCuttingDialog Cutting Cutting as in "cutting video" Vágás Mark as Begin Seek to Begin Play Selection Mark as End Seek to End %1 not found MainWindow QWinFF QWinFF Start conversion process. Átalakítás indítása. &Start &Indítás &File &Fájl &Convert &Átalakítás &About &Edit &Szerkesztés &Add Files &Fájlok Hozzáadása Add files for conversion. Fájlok hozzáadása átalakításhoz. Ctrl+N Ctrl+N E&xit Kilépés Exit the program. Kilépés a programból F9 F9 S&top Állj Stop conversion process. Átalakításai folymat megállítása. Set &Parameters Változók beállítása Set Parameters Edit output file parameters. Kimeneti változók beállítása Edit conversion parameters of selected files. A kiválasztott fájlok átalakítási változóinak beállítása. About &Qt A Qt-ről About Qt A Qt-ről &Open Output Folder &Kimeneti könyvtár megnyitása Open output folder of the selected file. A kiválasztott fájl kimeneti mappájának megnyitása. About &FFmpeg Az FFmpeg-ről About FFmpeg Az FFmpeg-ről: &Remove Selected remove selected (tasks, items) &Kiválasztottak eltávolítása Remove all selected items in the list. Minden kiválasztott elem eltávolítása a listáról. R&emove Completed remove completed (task, items) Eltávolítás befejezve Remove Completed Items Elkemek eltávolítása befejezve Remove all completed items in the list. Az összes elkészült elem eltávolítása a listáról. &Clear List Lista ürítése Clear List Lista ürítése Remove all items in the list. Minden listán lévő elem eltávolítása &Retry &Újra Retry Újra Retry selected tasks. Kiválasztott feladatok újrapróbálása. Retry &All Újra &mindet Retry all tasks. Minden feladat újrapróbálása. &Options &Opciók Options Opciók About Q&WinFF A QWinFF-ről About This Program Erről a programról Change Output &Filename Kimeneti fájlnév megváltoztatása Change the output filename of the selected item. Kiválasztott elemek kimeneti fájlnevének megváltoztatása. Change Output &Directory Kimeneti könyvtár megváltoztatása Change the output directory of the selected items. Kiválasztott elemek kimeneti könytárának megváltoztatása Show Error &Message Hibaüzenetek megjelenítése Check For &Updates Frissítések ellenőrzése Cut Cut video file (select a time range to conert) All tasks have finished. Minden feladat befejeződött. Nothing to convert. Nincs mit átalakítani. Conversion is still in progress. Abort? Átalakítás folymatban. Megszakítja? Shutdown Shutdown the computer (completely poweroff) Leállítás Shutdown when all tasks are done. Leállítás ha minden feladat befejeződött. Suspend Suspend the computer (sleep to ram, standby) Felfüggesztés Suspend when all tasks are done. Felfüggesztés ha minden feladat befejeződött. Hibernate Hibernate the computer (sleep to disk, completely poweroff) Hibernálás Hibernate when all tasks are done. Hibernálás ha minden feladat befejeződött. This program is going to check for updates online. Do you allow this program to use the Internet to check for updates? A program ellenőrzi a frissítéseket, ehhez az internet kapcsolatot használja. Engedélyezi az internet hozzáférést a program számára? Failed to load preset file. The application will quit now. Nem sikerült betölteni az előbeállító fájlt. Az alkalmazás most kilép. Elapsed Time: %1 h %2 m %3 s Hátralévő idő: %1 ó %2 p %3 mp Converting %1/%2 Converting the %1-th file in %2 files. %2 is the number of files. Átalakítás: %1/%2 összesen MediaConverter %1 not found. %1 is a computer program %1 nem található. OptionsDialog Options Opciók General Általános Check for updates on program startup Frissítések keresése a program indulásakor Automatically start conversion after adding files to the list. Átalakítás automatikus indítása a fájlok hozzáadása után. Start conversion automatically Átalakítás automatikus indítása FFmpeg FFmpeg Number of threads to use in conversion Konvertálási szálak száma <html><head/><body><p>Hide output formats that are not available in the current ffmpeg installation. It is recommended to turn this option on unless you are sure that QWinFF has failed to detect available formats. (requires restarting QWinFF to take effect)</p></body></html> <html><head/><body><p>Elrejti az FFmpeg jelenlegi telepítésében nem elérhető kimeneti fájlokat. Ajánlott ezt a lehetőséget bekapcsolni, kivéve, ha biztos benne, hogy a QWinFF nem ismerte fel a kimeneti formátumokat. (A QWinFF újraindítása szükséges a változtatás érvényesítéséhez)</p></body></html> Hide unavailable formats (requires restarting) Nem elérhető formátumok elrejtése (újraindítást igényel) Tools Eszközök You have to restart QWinFF for the changes to take effect. Újra kell indítania a QWinff-et a változtatások érvényesítéséhez. Name Név Command Parancs PoweroffDialog QWinFF QWinFF Cancel Mégsem Shutdown immediately Shutdown the computer Azonnali leállítás Suspend immediately Suspend the computer (sleep to ram, standby) Azonnali felfüggesztés Hibernate immediately Hibernate the computer (sleep to disk, completely poweroff) Azonnali hibernálás Shutdown Shutdown the computer Leállítás Suspend Suspend the computer (sleep to ram, standby) Felfüggesztés Hibernate Hibernate the computer (sleep to disk, completely poweroff) Hibernálás Operation Failed: %1 %1 művelet sikertelen Shutting down in <b>%1</b> seconds Leállítás <b>%1 másoperc</b> múlva Suspending in <b>%1</b> seconds Felfüggesztés <b>%1 másoperc</b> múlva Hibernating in <b>%1</b> seconds Hibernálás <b>%1 másoperc</b> múlva PreviewDialog Dialog Play Selected Range %1 not found Begin noun, the beginning of the video End noun, the end of the video Play %1~%2 play the video from time %1 to time %2. %1 and %2 are time in hh:mm:ss format. TimeRangeEdit From Begin Elejétől To End Végéig UpdateDialog Show &Release Notes Kiadási megjegyzések Check for updates on program startup Frissítések keresése a program indításakor Downloading update information... Frissítési információk letöltése... Cannot connect to server. Nem lehet kapcsolódni a kiszolgálóhoz Failed to parse the received data. A fogadott adatok elemzése sikertelen. You are already using the latest version of QWinFF. Már a QWinFF legújabb kiadását használja. An unknown error has occurred. Ismeretlen hiba! A new version of QWinFF has been released! A QWinFF új kiadása elérhető! Version <b>%1</b> is available at %2. %1 is version number, %2 is the project homepage A <b>%1</b> kiadás elérhető itt: %2 You can download this version using the link: Ezt a kiadást letöltheti az alábbi linken: qwinff-master/src/translations/qwinff_it_IT.ts000066400000000000000000001120601347323557400221200ustar00rootroot00000000000000 AboutDialog About QWinFF Info su QWinFF Information Informazioni Translators Traduttori Version: %1 Versione: %1 Portable Portatile Compiled with Qt %1 Compilato con Qt %1 Compiled with libnotify %1 Compilato con libnotify %1 QWinFF is a gui frontend for FFmpeg. QWinFF è una gui per FFmpeg. Programming: %1 Programming: %1 Logo Design: %1 Logo Design: %1 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 or 3. Questo programma è software libero; sei libero di ridistribuirlo e/o modificarlo nei termini della GNU General Public License versione 2 o 3. QWinFF Homepage: %1 Homepage di QWinFF: %1 Some audio-processing functionalities are provided by SoX. Alcune funzionalità di elaborazione audio sono fornite da SoX. FFmpeg presets were taken from WinFF. I preset FFmpeg sono stati presi da WinFF. Japanese Japanese Language Giapponese Italian Italian Language Italiano Czech Czech Language Ceco Simplified Chinese Chinese character set used in China Cinese semplificato Russian Russian Language Russo Spanish (Spain) Spanish Language (Spain) Spagnolo (Spagna) Spanish (Guatemala) Spanish Language (Guatemala) Spagnolo (Guatemala) Romanian Romanian Language Rumeno Turkish Turkish Language Turco Arabic Arabic Language Arabo Hungarian Hungarian Langauge Ungherese Polish Polish Language Polacco French French Language AboutFFmpegDialog About FFmpeg Info su FFmpeg FFmpeg FFmpeg Available Codecs Codec disponibili FFmpeg is a complete, cross-platform solution to record, convert and stream audio and video. It includes libavcodec - the leading audio/video codec library. ffmpeg description FFmpeg è una soluzione completa e cross-platform per registrare, convertire e condividere audio e video. Include libavcodec - la libreria audio/video principale. FFmpeg is free software licensed under the LGPL or GPL. FFmpeg è software libero, concesso in licenza sotto i termini della LGPL o GPL. Please visit %1 for more information. Visita %1 per maggiori informazioni. AddTaskWizard Add Tasks Aggiungi lavoro Files to be converted Files da convertire Add files. Aggiungi file. Remove selected files. Rimuovi i file selezionati. Output Settings Impostazioni Output Edit Modifica Auto adjust output bitrate to reduce output file size. Regola automaticamente il bitrate per ridurre le dimensioni finali. Auto Adjust Audio Bitrate Regola automaticamente il Bitrate Preset Preimpostazioni Convert to Converti in Output Path Path di Output Select &folder Seleziona &cartella Browse Sfoglia Create &new folder in source folder Create a new folder (e.g. qwinff_output) in the folder containing the input files. Put the output files in the newly created folder. Crea una &nuova cartella nella cartella di origine Folder Name Nome cartella Output to &source folder put the output files in the same folder as the input files Salva nella cartella di &origine Please select at least one file. Seleziona almeno un file. Select Files This text is the title of an openfile dialog. Seleziona i File Multimedia Multimedia Video Video Audio Audio All files Tutti i file Select Directory This text is the title of an open directory dialog. Seleziona Directory Searching for files... Ricerca dei file... Some files could not be found. Alcuni file non possono essere trovati. Folder does not exist. Create a new folder? La cartella non esiste. Vuoi crearne una nuova? Failed to create folder. Please select another output folder. Errore creazione cartella. Seleziona un'altra cartella di destinazione. ConversionParameterDialog Conversion Parameters Parametri di conversione Audio Audio Disable Audio Disabilita Audio Audio Options Opzioni Audio Sample Rate Sample Rate Hz Hz Bitrate Bitrate (auto) (auto) kb/s kb/s Channels Canali Volume Volume % % Video Video Disable Video Disabilita Video Video Options Opzioni Video Same Quantizer as Source Stesso Quantizzatore della Sorgente Deinterlace Deinterlaccia Width Larghezza px px Height Altezza Crop Taglia Time time-related options (speed, length) Tempo Cutting video time cutting: options for begin time and end time Taglio Cut Cut video; select a range to convert Taglia &Preview &Anteprima Scaling time scaling, changing the speed of the output file Modifica velocità Speed Velocità Advanced Avanzato FFmpeg FFmpeg Additional FFmpeg Options Opzioni FFmpeg Addizionali ConvertList Cancel Cancel the operation of adding new tasks Cancella Adding files (%1/%2) This text is the progress indicator of adding multiple tasks. %1 is the number of files that are already added. %2 is the total number of files. Aggiungi i file (%1/%2) Some files are not recognized by the converter. Alcuni file non sono stati riconosciuti dal convertitore. New File Name Nuovo Nome Please input the new name for the output file. Inserisci il nome del file di output. Output Directory Directory di Output Error Message from FFmpeg: Messaggio di errore da FFmpeg: Drag and drop files here to add tasks. Trascina qui i file per aggiungere operazioni. Hide "%1" Hide a column in the list. For example, the text maybe 'Hide "Duration"'. The two " are quotation marks in English, you may replace it with local quotation marks. Nascondi "%1" Restore All Columns Ripristina tutte le colonne Source Sorgente Destination Destinazione Duration Durata File Size Dimensione File Sample Rate Audio Sample Rate Audio Bitrate Audio Bitrate Channels Audio Canali Audio Codec Codec Audio Dimensions Dimensioni Video Bitrate Video Bitrate Framerate Video Framerate Video Codec Video Codec Progress Progressione %1 Hz %1 Hz %1 kb/s %1 kb/s %1 fps %1 fps Removing tasks... Remove files from the tasklist Rimuovo i lavori... KiB KiB MiB MiB GiB GiB TiB TiB B Bytes B File Exists Il file esiste %1 already exists on disk or in the task list. Still use this name as the output filename? %1 esiste già sul disco o nella lista dei lavori. Vuoi usare lo stesso nome anche per l'output (il file verrà sovrascritto)? Remove Task Rimuovi lavoro Cannot remove a task while it is in progress. Non posso rimuovere un lavoro in corso. Finished The text to be displayed on the progress bar when a conversion finishes Finito Failed The text to be displayed on the progress bar when a conversion fails Fallito Error: %1 %1 is the error message %1 è il messaggio di errore ExtraTranslations Convert between media file formats Converte file multimediali in vari formati Media Converter Convertitore di file multimediali InteractiveCuttingDialog Cutting Cutting as in "cutting video" Taglio Mark as Begin Marca come inizio Seek to Begin Cerca l'inizio Play Selection Riproduci selezione Mark as End Marca come fine Seek to End Cerca la fine %1 not found %1 non trovato MainWindow QWinFF QWinFF Start conversion process. Inizia la conversione. &Start &Start &File &File &Convert &Converti &About &Info &Edit &Modifica &Add Files &Aggiungi file Add files for conversion. Aggiungi file da convertire. Ctrl+N Ctrl+N E&xit E&sci Exit the program. Esci dal programma. F9 F9 S&top S&top Stop conversion process. Ferma la conversione. Set &Parameters Imposta &Parametri Set Parameters Edit output file parameters. Imposta parametri Edit conversion parameters of selected files. Modifica i parametri per i file selezionati. About &Qt Info su &Qt About Qt Info su Qt &Open Output Folder &Apri Cartella di Destinazione Open output folder of the selected file. Apri la cartella di destinazione del file selezionato. About &FFmpeg Info su &FFmpeg About FFmpeg Info su FFmpeg &Remove Selected remove selected (tasks, items) &Rimuovi gli oggetti selezionati Remove all selected items in the list. Rimuove gli oggetti selezionati dalla lista. R&emove Completed remove completed (task, items) R&imuovi completati Remove Completed Items Rimuove i lavori completati Remove all completed items in the list. Rimuove tutti i lavori completati. &Clear List &Pulisci Lista Clear List Pulisci lista Remove all items in the list. Rimuove tutti i lavori dalla lista. &Retry &Riprova Retry Riprova Retry selected tasks. Riprova i lavori selezionati. Retry &All Riprova &Tutti Retry all tasks. Riprova tutti i lavori. &Options &Opzioni Options Opzioni About Q&WinFF Info su Q&WinFF About This Program Info sul programma Change Output &Filename Cambia il &Nome file di output Change the output filename of the selected item. Cambia il nome del file di output. Change Output &Directory Cambia la &Cartella di output Change the output directory of the selected items. Cambia la cartella di output dei lavori selezionati. Show Error &Message Mostra &messaggio di errore Check For &Updates Controlla gli &aggiornamenti Cut Cut video file (select a time range to conert) Taglia All tasks have finished. Tutti i processi sono completati. Nothing to convert. Niente da convertire. Conversion is still in progress. Abort? La conversione è ancora in corso. Arresto la conversione? Shutdown Shutdown the computer (completely poweroff) Spegni Shutdown when all tasks are done. Spegni quando tutti i lavori sono completati. Suspend Suspend the computer (sleep to ram, standby) Sospendi Suspend when all tasks are done. Sospendi quando tutti i lavori sono completati. Hibernate Hibernate the computer (sleep to disk, completely poweroff) Iberna Hibernate when all tasks are done. Iberna quando tutti i lavori sono completati. This program is going to check for updates online. Do you allow this program to use the Internet to check for updates? Questo programma controllerà gli aggiornamenti online. Consentire al programma di accedere ad Internet per controllare gli aggiornamenti? Failed to load preset file. The application will quit now. Caricamento file predefinito fallito. L'applicazione ora si chiuderà. Elapsed Time: %1 h %2 m %3 s Tempo stimato: %1 h %2 m %3 s Converting %1/%2 Converting the %1-th file in %2 files. %2 is the number of files. Conversione %1/%2 MediaConverter %1 not found. %1 is a computer program %1 non trovato. OptionsDialog Options Opzioni General Generale Check for updates on program startup Controlla gli aggiornamenti all'avvio del programma Automatically start conversion after adding files to the list. Avvia automaticamente la conversione dopo aver aggiunto i file all'elenco. Start conversion automatically Inizia la conversione automaticamente. FFmpeg FFmpeg Number of threads to use in conversion Numero di impostazioni da usare per la conversione <html><head/><body><p>Hide output formats that are not available in the current ffmpeg installation. It is recommended to turn this option on unless you are sure that QWinFF has failed to detect available formats. (requires restarting QWinFF to take effect)</p></body></html> <html><head/><body><p>Nascondi i formati di output non disponibili nell'attuale installazione di ffmpeg. Si consiglia di attivare questa opzione a meno che non si sia certi che QWinFF abbia fallito nel rilevare i formati disponibili. (richiede il riavvio di QWinFF)</p></body></html> Hide unavailable formats (requires restarting) Nascondi formati non disponibili (richiede riavvio) Tools Strumenti You have to restart QWinFF for the changes to take effect. È necessario riavviare QWinFF affinché le modifiche abbiano effetto. Name Nome Command Comando PoweroffDialog QWinFF QWinFF Cancel Annulla Shutdown immediately Shutdown the computer Spegni immediatamente Suspend immediately Suspend the computer (sleep to ram, standby) Sospendi immediatamente Hibernate immediately Hibernate the computer (sleep to disk, completely poweroff) Iberna immediatamente Shutdown Shutdown the computer Spegni Suspend Suspend the computer (sleep to ram, standby) Sospendi Hibernate Hibernate the computer (sleep to disk, completely poweroff) Iberna Operation Failed: %1 Operazione fallita: %1 Shutting down in <b>%1</b> seconds Spegnimento tra <b>%1</b> secondi Suspending in <b>%1</b> seconds Sospensione tra <b>%1</b> secondi Hibernating in <b>%1</b> seconds Ibernazione tra <b>%1</b> secondi PreviewDialog Dialog Finestra di dialogo Play Selected Range Riproduci lo spazio selezionato %1 not found %1 non trovato Begin noun, the beginning of the video Inizio End noun, the end of the video Fine Play %1~%2 play the video from time %1 to time %2. %1 and %2 are time in hh:mm:ss format. Riproduci %1~%2 TimeRangeEdit From Begin Dall'Inizio To End Alla Fine UpdateDialog Show &Release Notes Mostra le note di &rilascio Check for updates on program startup Controlla gli aggiornamenti all'avvio del programma Downloading update information... Download delle informazioni sull'aggiornamento... Cannot connect to server. Impossibile contattare il server. Failed to parse the received data. Impossibile analizzare i dati ricevuti. You are already using the latest version of QWinFF. Stai già utilizzando la versione più recente di QWinFF. An unknown error has occurred. Si è verificato un errore sconosciuto. A new version of QWinFF has been released! È stata rilasciata una nuova versione di QWinFF! Version <b>%1</b> is available at %2. %1 is version number, %2 is the project homepage È disponibile la versione <b>%1</b> su %2. You can download this version using the link: Puoi scaricare questa versione usando il collegamento: qwinff-master/src/translations/qwinff_ja_JP.ts000066400000000000000000001143101347323557400220730ustar00rootroot00000000000000 AboutDialog About QWinFF QWinFF について Information 情報 Translators 翻訳者 Version: %1 バージョン: %1 Portable ポータブル Compiled with Qt %1 コンパイルに使用された Qt :%1 Compiled with libnotify %1 コンパイルに使用された libnotify: %1 QWinFF is a gui frontend for FFmpeg. QWinFF は FFmpeg のGUI フロントエンドツールです. Programming: %1 プログラミング:%1 Logo Design: %1 ロゴデザイン:%1 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 or 3. このプログラムはフリーウェアです。 GNU一般共有使用許諾第2版(または 第3版)に基づき、ソフトウェアの変更、再配布は許可されます。 QWinFF Homepage: %1 QWinFF 公式サイト: %1 Some audio-processing functionalities are provided by SoX. いくつかの音声処理機能は SoX により提供されています. FFmpeg presets were taken from WinFF. WinFFの FFmpeg プリセットを使用しています. Japanese Japanese Language 日本語 Italian Italian Language イタリア語 Czech Czech Language チェコ語 Simplified Chinese Chinese character set used in China 中国語(簡体字) Russian Russian Language ロシア語 Spanish (Spain) Spanish Language (Spain) スペイン語 (スペイン) Spanish (Guatemala) Spanish Language (Guatemala) スペイン語 (グアテマラ) Romanian Romanian Language ルーマニア語 Turkish Turkish Language トルコ語 Arabic Arabic Language アラビア語 Hungarian Hungarian Langauge ハンガリー語 Polish Polish Language French French Language AboutFFmpegDialog About FFmpeg FFmpeg について FFmpeg FFmpeg Available Codecs 利用可能なコーデック FFmpeg is a complete, cross-platform solution to record, convert and stream audio and video. It includes libavcodec - the leading audio/video codec library. ffmpeg description FFmpeg は完全なクロスプラットフォームに対応した、音声、映像ストリームの変換ツールで、主要な音声/ 映像コーデック・ライブラリが含まれています。 FFmpeg is free software licensed under the LGPL or GPL. FFmpeg は、LGPL / GPL ライセンスに基づき公開されているフリーソフトウェアです. Please visit %1 for more information. FFmpeg に関する情報: %1. AddTaskWizard Add Tasks タスクを追加 Files to be converted 変換対象のファイル Add files. ファイルを追加. Remove selected files. 選択されたファイルを除去. Output Settings 出力設定 Edit 編集 Auto adjust output bitrate to reduce output file size. 出力ファイルサイズが軽減するように出力ビットレートを自動調整. Auto Adjust Audio Bitrate 音声ビットレートを自動調整 Preset プリセット Convert to 変換形式 Output Path 出力パス Select &folder ファイルを選択(&F) Browse 参照 Create &new folder in source folder Create a new folder (e.g. qwinff_output) in the folder containing the input files. Put the output files in the newly created folder. ソースフォルダに新規フォルダを作成(&N) Folder Name フォルダ名 Output to &source folder put the output files in the same folder as the input files ソースフォルダに出力(&S) Please select at least one file. ファイルを選択してください. Select Files This text is the title of an openfile dialog. ファイルを選択 Multimedia マルチメディア Video 映像 Audio 音声 All files すべてのファイル Select Directory This text is the title of an open directory dialog. ディレクトリを選択 Searching for files... ファイルを検索中... Some files could not be found. いくつかのファイルが見つかりません. Folder does not exist. Create a new folder? フォルダが存在しません、新たに作成しますか? Failed to create folder. Please select another output folder. フォルダ作成に失敗、別の出力フォルダを選択してください. ConversionParameterDialog Conversion Parameters 変換パラメータ Audio 音声 Disable Audio 音声を無効 Audio Options 音声設定 Sample Rate サンプルレート Hz Hz Bitrate ビットレート (auto) 自動 kb/s kb/秒 Channels チャンネル Volume 音量 % % Video 映像 Disable Video 映像を無効 Video Options 映像設定 Same Quantizer as Source ソースと同じ量子化 Deinterlace インターレース解除 Width px px Height 高さ Crop クロップ Time time-related options (speed, length) 時間 Cutting video time cutting: options for begin time and end time 動画のカット Cut Cut video; select a range to convert &Preview プレビュー(&P) Scaling time scaling, changing the speed of the output file スケーリング Speed 速度 Advanced 拡張 FFmpeg FFMpeg Additional FFmpeg Options FFmpeg 追加オプション ConvertList Cancel Cancel the operation of adding new tasks キャンセル Adding files (%1/%2) This text is the progress indicator of adding multiple tasks. %1 is the number of files that are already added. %2 is the total number of files. ファイルを追加 (%1/%2) Some files are not recognized by the converter. いくつかのファイルは認識できません. New File Name 新しいファイル名 Please input the new name for the output file. 出力ファイルの名前を入力してください. Output Directory 出力ディレクトリ Error Message from FFmpeg: FFmpegからのエラーメッセージ: Drag and drop files here to add tasks. ファイルをここにドロップでタスクを追加. Hide "%1" Hide a column in the list. For example, the text maybe 'Hide "Duration"'. The two " are quotation marks in English, you may replace it with local quotation marks. "%1" を隠す Restore All Columns すべての列を復元 Source ソース Destination 対象 Duration 再生時間 File Size ファイルサイズ Sample Rate Audio サンプルレート Audio Bitrate 音声ビットレート Channels Audio チャンネル Audio Codec 音声コーデック Dimensions 映像の寸法 Video Bitrate 映像ビットレート Framerate Video フレームレート Video Codec 映像コーデック Progress 進捗状況 %1 Hz %1 Hz %1 kb/s %1 kb/s %1 fps %1 fps Removing tasks... Remove files from the tasklist タスクを除去中... KiB KiB MiB MiB GiB GiB TiB TiB B Bytes B File Exists ファイルが存在します %1 already exists on disk or in the task list. Still use this name as the output filename? %1 と同名のファイルがディスク上、またはタスク一覧に存在します. 本当にこの名前でファイルを出力しますか? Remove Task タスクを除去 Cannot remove a task while it is in progress. 処理中のタスクは除去できません. Finished The text to be displayed on the progress bar when a conversion finishes 完了 Failed The text to be displayed on the progress bar when a conversion fails 失敗 Error: %1 %1 is the error message エラー: %1 ExtraTranslations Convert between media file formats 音声とビデオファイルの変換 Media Converter メディア変換 InteractiveCuttingDialog Cutting Cutting as in "cutting video" 動画のカット Mark as Begin Seek to Begin Play Selection Mark as End Seek to End %1 not found MainWindow QWinFF QWinFF Start conversion process. 変換を開始. &Start 開始(&S) &File ファイル(&F) &Convert 変換(&C) &About 情報(&A) &Edit 編集(&E) &Add Files ファイルを追加(&A) Add files for conversion. 変換するファイルを追加. Ctrl+N Ctrl+N E&xit 終了(&E) Exit the program. プログラムを終了. F9 F9 S&top 停止(&T) Stop conversion process. 変換処理を停止. Set &Parameters パラメータを設定(&P) Set Parameters Edit output file parameters. パラメータを設定 Edit conversion parameters of selected files. 選択されたファイルの変換パラメータを編集. About &Qt &Qt について About Qt Qt について &Open Output Folder 出力先を開く(&O) Open output folder of the selected file. 選択されたファイルの出力先を開く. About &FFmpeg &FFmpeg について About FFmpeg FFmpeg について &Remove Selected remove selected (tasks, items) 選択された項目を除去(&R) Remove all selected items in the list. すべての選択された項目を一覧から除去. R&emove Completed remove completed (task, items) 完了済みの項目を除去(&E) Remove Completed Items 完了済の項目を除去 Remove all completed items in the list. すべての完了済項目を一覧から除去. &Clear List リストをクリア(&C) Clear List 一覧をクリア Remove all items in the list. すべての項目を一覧から除去. &Retry 再試行(&R) Retry 再試行 Retry selected tasks. 選択されたタスクを再試行. Retry &All すべてを再試行(&A) Retry all tasks. すべてのタスクを再試行. &Options 設定(&O) Options 設定 About Q&WinFF Q&WinFF について About This Program このプログラムについて Change Output &Filename 出力ファイル名を変更(&F) Change the output filename of the selected item. 選択された項目の出力ファイル名を変更. Change Output &Directory 出力ディレクトリを変更(&D) Change the output directory of the selected items. 選択された項目の出力ディレクトリを変更. Show Error &Message エラーメッセージを表示(&M) Check For &Updates 更新のチェック(&U) Cut Cut video file (select a time range to conert) All tasks have finished. すべてのタスクが完了しました. Nothing to convert. 変換されていません. Conversion is still in progress. Abort? 変換処理を実行中です、中断しますか? Shutdown Shutdown the computer (completely poweroff) シャットダウン Shutdown when all tasks are done. 全タスク完了後にシャットダウン. Suspend Suspend the computer (sleep to ram, standby) サスペンド Suspend when all tasks are done. 全タスク完了後にスリープ. Hibernate Hibernate the computer (sleep to disk, completely poweroff) 休止状態 Hibernate when all tasks are done. 全タスク完了後に休止状態. This program is going to check for updates online. Do you allow this program to use the Internet to check for updates? アップデートの確認にはオンライン接続が必要です、このプログラムのインターネットへの接続を許可しますか? Failed to load preset file. The application will quit now. プリセットの読み込みに失敗、アプリケーションを終了します. Elapsed Time: %1 h %2 m %3 s 経過時間: %1 時 %2 分 %3 秒 Converting %1/%2 Converting the %1-th file in %2 files. %2 is the number of files. 変換中 %1/%2 MediaConverter %1 not found. %1 is a computer program %1 が見つかりません。 OptionsDialog Options 設定 General 一般 Check for updates on program startup 起動時にアップデートの有無を確認 Automatically start conversion after adding files to the list. リストにファイルが追加されたら、自動的に変換を開始する. Start conversion automatically 変換を自動的に開始 FFmpeg FFmpeg Number of threads to use in conversion 変換時に使用するスレッド数 <html><head/><body><p>Hide output formats that are not available in the current ffmpeg installation. It is recommended to turn this option on unless you are sure that QWinFF has failed to detect available formats. (requires restarting QWinFF to take effect)</p></body></html> <html><head/><body><p>現在インストールされている ffmpeg では利用できない出力形式を非表示にします。QWinFF による利用可能な形式の検出があきらかに失敗している場合を除き、このオプションは有効にしておくことをお勧めします。(設定の変更には QWinFF の再起動が必要)</p></body></html> Hide unavailable formats (requires restarting) 利用できない形式は隠す (再起動が必要) Tools ツール You have to restart QWinFF for the changes to take effect. ここでの変更は QWinFF の再起動後に適用されます. Name 名前 Command コマンド PoweroffDialog QWinFF QWinFF Cancel キャンセル Shutdown immediately Shutdown the computer すぐにシャットダウン Suspend immediately Suspend the computer (sleep to ram, standby) すぐにスリープ Hibernate immediately Hibernate the computer (sleep to disk, completely poweroff) すぐに休止状態 Shutdown Shutdown the computer シャットダウン Suspend Suspend the computer (sleep to ram, standby) スリープ Hibernate Hibernate the computer (sleep to disk, completely poweroff) ハイバネート Operation Failed: %1 処理に失敗: %1 Shutting down in <b>%1</b> seconds シャットダウンまで <b>%1</b> 秒 Suspending in <b>%1</b> seconds スリープまで <b>%1</b> 秒 Hibernating in <b>%1</b> seconds 休止状態まで <b>%1</b> 秒 PreviewDialog Dialog Play Selected Range %1 not found Begin noun, the beginning of the video End noun, the end of the video Play %1~%2 play the video from time %1 to time %2. %1 and %2 are time in hh:mm:ss format. TimeRangeEdit From Begin 最初から To End 最後まで UpdateDialog Show &Release Notes 更新履歴を表示(&R) Check for updates on program startup 起動時にアップデートを確認 Downloading update information... 更新情報をダウンロード中... Cannot connect to server. サーバに接続できません. Failed to parse the received data. 受信データの解析に失敗. You are already using the latest version of QWinFF. あなたは最新の QWinFF を使用中です. An unknown error has occurred. 不明なエラーが発生. A new version of QWinFF has been released! QWinFF の新バージョンが公開されています! Version <b>%1</b> is available at %2. %1 is version number, %2 is the project homepage バージョン <b>%1</b> %2 が利用可能. You can download this version using the link: このリンクからダウンロード可能です: qwinff-master/src/translations/qwinff_pl_PL.ts000066400000000000000000001131331347323557400221200ustar00rootroot00000000000000 AboutDialog About QWinFF Informacje o: QWinFF Information Informacje Translators Tłumaczenia Version: %1 Wersja: %1 Portable Portable Compiled with Qt %1 Skompilowany z Qt %1 Compiled with libnotify %1 Skompilowany z libnotify %1 QWinFF is a gui frontend for FFmpeg. QWinFF ,to nakładką gui dla FFmpeg. Programming: %1 Programista: %1 Logo Design: %1 Logo projektu: %1 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 or 3. Ten program jest wolnym oprogramowaniem, możesz go rozprowadzać dalej , lub modyfikować zgodnie z warunkami licencji GNU GPL w wersji 2 lub 3. QWinFF Homepage: %1 Strona domowa QWinFF : %1 Some audio-processing functionalities are provided by SoX. Niektóre funkcje przetwarzania dźwięku są dostarczane przez: SoX. FFmpeg presets were taken from WinFF. Domyślne ustawienia FFmpeg pochodzą z WinFF. Japanese Japanese Language Japoński Italian Italian Language Włoski Czech Czech Language Czeski Simplified Chinese Chinese character set used in China Chiński uproszczony Russian Russian Language Rosyjski Spanish (Spain) Spanish Language (Spain) Hiszpański (Hiszpania) Spanish (Guatemala) Spanish Language (Guatemala) Hiszpański (Gwatemala) Romanian Romanian Language Rumuński Turkish Turkish Language Turecki Arabic Arabic Language Arabski Hungarian Hungarian Langauge Węgierski Polish Polish Language Polski French French Language AboutFFmpegDialog About FFmpeg Informacje o: FFmpeg FFmpeg FFmpeg Available Codecs Dostępne kodeki FFmpeg is a complete, cross-platform solution to record, convert and stream audio and video. It includes libavcodec - the leading audio/video codec library. ffmpeg description FFmpeg to kompletne, wielosystemowe rozwiązanie do nagrywania i konwersji strumieni audio i wideo. Obejmuje libavcodec - wiodącą bibliotekę kodeków audio / wideo. FFmpeg is free software licensed under the LGPL or GPL. FFmpeg to wolne oprogramowanie na licencji LGPL lub GPL. Please visit %1 for more information. Odwiedź %1 aby uzyskać więcej informacji. AddTaskWizard Add Tasks Dodaj zadania Files to be converted Pliki do konwersji Add files. Dodaj pliki Remove selected files. Usuń wybrane pliki. Output Settings Ustawienia wyjściowe Edit Edytuj Auto adjust output bitrate to reduce output file size. Automatyczna regulacja przepustowości, w celu zmniejszenia rozmiaru pliku wyjściowego. Auto Adjust Audio Bitrate Automatyczna regulacja przepustowości audio Preset Ustawienia domyślne Convert to Konwersja do Output Path Ścieżka zapisu konwersji Select &folder Wybierz &folder Browse Przeglądaj Create &new folder in source folder Create a new folder (e.g. qwinff_output) in the folder containing the input files. Put the output files in the newly created folder. Utwórz &nowy folder w folderze źródłowym Folder Name Nazwa folderu Output to &source folder put the output files in the same folder as the input files Zapisz w &folderze źródłowym Please select at least one file. Proszę wybrać co najmniej jeden plik. Select Files This text is the title of an openfile dialog. Wybierz pliki Multimedia Multimedia Video Wideo Audio Audio All files Wszystkie pliki Select Directory This text is the title of an open directory dialog. Wybierz katalog Searching for files... Wyszukiwanie plików... Some files could not be found. Niektórych plików nie można znaleźć. Folder does not exist. Create a new folder? Folder nie istnieje. Utworzyć nowy folder? Failed to create folder. Please select another output folder. Nie udało się utworzyć folderu. Proszę wybrać inny folder wyjściowy. ConversionParameterDialog Conversion Parameters Parametry konwersji Audio Audio Disable Audio Wyłącz audio Audio Options Opcje audio Sample Rate Częstotliwość próbkowania Hz Hz Bitrate Przepustowość (auto) (auto) kb/s kb/s Channels Kanały Volume Głośność % % Video Wideo Disable Video Wyłącz wideo Video Options Opcje wideo Same Quantizer as Source Przetwarzanie sygnału, podobnie jako źródło Deinterlace Przeplot Width Szerokość px Pikseli Height Wysokość Crop Przytnij Time time-related options (speed, length) Czas Cutting video time cutting: options for begin time and end time Cięcie Cut Cut video; select a range to convert Cięcie &Preview &Podgląd Scaling time scaling, changing the speed of the output file Skalowanie Speed Prędkość Advanced Zaawansowane FFmpeg FFmpeg Additional FFmpeg Options Dodatkowe opcje FFmpeg ConvertList Cancel Cancel the operation of adding new tasks Anuluj Adding files (%1/%2) This text is the progress indicator of adding multiple tasks. %1 is the number of files that are already added. %2 is the total number of files. Dodawanie plików (%1/%2) Some files are not recognized by the converter. Niektóre pliki nie są rozpoznawane przez konwerter. New File Name Nowa nazwa pliku Please input the new name for the output file. Proszę wpisać nową nazwę, dla pliku wyjściowego. Output Directory Katalog wyjściowy Error Message from FFmpeg: Komunikat o błędzie z FFmpeg: Drag and drop files here to add tasks. Przeciągnij i upuść pliki tutaj, następnie ustaw parametry konwersji. Hide "%1" Hide a column in the list. For example, the text maybe 'Hide "Duration"'. The two " are quotation marks in English, you may replace it with local quotation marks. Ukryj "%1" Restore All Columns Przywróć wszystkie kolumny Source Źródło Destination Miejsce docelowe Duration Czas nagrania File Size Wielkość pliku Sample Rate Audio Częstotliwość próbkowania Audio Bitrate Przepustowość audio Channels Audio Kanały Audio Codec Audio kodek Dimensions Wymiar Video Bitrate Wideo przepustowość Framerate Video Częstotliwość wyświetlania klatek Video Codec Wideo kodek Progress Postęp %1 Hz %1 Hz %1 kb/s %1 kb/s %1 fps %1 fps Removing tasks... Remove files from the tasklist Usuwanie zadań... KiB KB MiB MB GiB GB TiB TB B Bytes B File Exists Plik istnieje %1 already exists on disk or in the task list. Still use this name as the output filename? %1 już istnieje na dysku lub na liście zadań. Nadal używać tej nazwy jako nazwy pliku wyjściowego? Remove Task Usuń zadanie Cannot remove a task while it is in progress. Nie można usunąć zadanie, gdy jest w toku. Finished The text to be displayed on the progress bar when a conversion finishes Zakończono Failed The text to be displayed on the progress bar when a conversion fails Nie udało się Error: %1 %1 is the error message Błąd: %1 ExtraTranslations Convert between media file formats Konwersja plików multimedialnych pomiędzy różnymi formatami. Media Converter Konwerter mediów InteractiveCuttingDialog Cutting Cutting as in "cutting video" Cięcie Mark as Begin Wskaż jako nowy początek Seek to Begin Skocz do nowego początku Play Selection Odtwórz wybrany materiał Mark as End Wskaż jako nowy koniec Seek to End Skocz do nowego końca %1 not found % 1 nie został znaleziony MainWindow QWinFF QWinFF Start conversion process. Rozpoczyna proces konwersji. &Start &Start &File &Plik &Convert &Konwersja &About &Informacje o: &Edit &Edytuj &Add Files &Dodaj pliki Add files for conversion. Dodaj pliki do konwersji. Ctrl+N Ctrl+N E&xit W&yjście Exit the program. Wyjście z programu. F9 F9 S&top S&top Stop conversion process. Zatrzymaj proces konwersji. Set &Parameters Ustawienia &parametrów Set Parameters Edit output file parameters. Ustawienia parametrów Edit conversion parameters of selected files. Parametry edycji konwersji, wybranych plików. About &Qt Informacje o: &Qt About Qt Informacje o: Qt &Open Output Folder &Otwórz folder zapisu Open output folder of the selected file. Otwórz folder zapisu, wybranego pliku. About &FFmpeg Informacje o: &FFmpeg About FFmpeg Informacje o: FFmpeg &Remove Selected remove selected (tasks, items) &Usuń zaznaczone Remove all selected items in the list. Usuń wszystkie wybrane pozycje na liście. R&emove Completed remove completed (task, items) U&suń wykonane Remove Completed Items Usuń wykonane zadania Remove all completed items in the list. Usuń wszystkie zaznaczone pozycje na liście. &Clear List &Wyczyść listę Clear List Wyczyść listę Remove all items in the list. Usuń wszystkie przedmioty z listy. &Retry &Spróbuj ponownie Retry Spróbuj ponownie Retry selected tasks. Ponów wybrane zadania. Retry &All Ponów &wszystko Retry all tasks. Ponów wszystkie zadania. &Options &Opcje Options Opcje About Q&WinFF Informacje o: Q&WinFF About This Program Informacje o: programie Change Output &Filename Zmień nazwę pliku &na wyjściu Change the output filename of the selected item. Zmień nazwę pliku wyjściowego wybranego elementu. Change Output &Directory Zmień lokalizację &zapisu Change the output directory of the selected items. Zmień katalog docelowy, wybranych plików. Show Error &Message Wyświetl informację o błędzie Check For &Updates Sprawdź &aktualizacje Cut Cut video file (select a time range to conert) Cięcie All tasks have finished. Wszystkie zadania zostały zakończone. Nothing to convert. Nic do konwersji. Conversion is still in progress. Abort? Konwersja jest nadal w toku, przerwać? Shutdown Shutdown the computer (completely poweroff) Zamyka komputer Shutdown when all tasks are done. Zamyka komputer, gdy wszystkie zadania są wykonywane. Suspend Suspend the computer (sleep to ram, standby) Zawiesza system. Suspend when all tasks are done. Zawiesza system, gdy wszystkie zadania są wykonywane. Hibernate Hibernate the computer (sleep to disk, completely poweroff) Hibernuje system. Hibernate when all tasks are done. Hibernuje system, gdy wszystkie zadania są wykonywane. This program is going to check for updates online. Do you allow this program to use the Internet to check for updates? Ten program, będzie sprawdzać dostępność aktualizacji po przez łączenie się z Internetem. Czy wyrażasz zgodę na to? Failed to load preset file. The application will quit now. Nie udało się załadować żadnego pliku . Aplikacja zostanie teraz zamknięta. Elapsed Time: %1 h %2 m %3 s Czas trwania konwersji : %1 h %2 m %3 s Converting %1/%2 Converting the %1-th file in %2 files. %2 is the number of files. Konwersja %1/%2 MediaConverter %1 not found. %1 is a computer program %1 nie został znaleziony. OptionsDialog Options Opcje General Ogólne Check for updates on program startup Sprawdź aktualizacje, przy starcie programu Automatically start conversion after adding files to the list. Automatycznie rozpoczyna konwersję, po dodaniu plików do listy. Start conversion automatically Automatycznie rozpoczyna konwersję FFmpeg FFmpeg Number of threads to use in conversion Liczba wątków do wykorzystania w konwersji <html><head/><body><p>Hide output formats that are not available in the current ffmpeg installation. It is recommended to turn this option on unless you are sure that QWinFF has failed to detect available formats. (requires restarting QWinFF to take effect)</p></body></html> <html><head/><body><p>Ukryj formaty wyjściowe, które są niedostępne w bieżącej instalacji ffmpeg. Zaleca się, aby włączyć tę opcję, w przypadku gdy są podejrzenia, że WinFF nie wykrywa prawidłowo dostępne formaty. (wymaga ponownego uruchomienia WinFF, po to aby zmiany zaczęły obowiązywać)</p></body></html> Hide unavailable formats (requires restarting) Ukrywanie niedostępnych formatów (wymaga ponownego uruchomienia) Tools Narzędzia You have to restart QWinFF for the changes to take effect. Należy ponownie uruchomić QWinFF , aby zmiany odniosły skutek. Name Nazwa Command Komenda PoweroffDialog QWinFF QWinFF Cancel Anuluj Shutdown immediately Shutdown the computer Zamknij komputer, natychmiast. Suspend immediately Suspend the computer (sleep to ram, standby) Włącz zawieszenie natychmiast Hibernate immediately Hibernate the computer (sleep to disk, completely poweroff) Włącz hibernacje, natychmiast Shutdown Shutdown the computer Zamyka komputer Suspend Suspend the computer (sleep to ram, standby) Zawiesza system Hibernate Hibernate the computer (sleep to disk, completely poweroff) Hibernuje system Operation Failed: %1 Operacja nie powiodła się: %1 Shutting down in <b>%1</b> seconds Zamknięcie komputera, za <b>%1</b> sekund Suspending in <b>%1</b> seconds Zawieszenie systemu, za <b>%1</b> sekund Hibernating in <b>%1</b> seconds Hibernacja systemu, za <b>%1</b> sekund PreviewDialog Dialog Dialog Play Selected Range Odtwórz zaznaczony materiał %1 not found %1 nie znaleziono Begin noun, the beginning of the video Początek End noun, the end of the video Koniec Play %1~%2 play the video from time %1 to time %2. %1 and %2 are time in hh:mm:ss format. Odtwarzanie %1~%2 TimeRangeEdit From Begin Od początku - bez opcji cięcia To End Do końca - bez opcji cięcia UpdateDialog Show &Release Notes Pokarz &Informacje o wydaniu Check for updates on program startup Sprawdź aktualizacje przy starcie programu. Downloading update information... Pobieranie informacji o aktualizacji ... Cannot connect to server. Nie można połączyć się z serwerem. Failed to parse the received data. Nie udało się przetworzyć dane. You are already using the latest version of QWinFF. Używasz najnowszej wersji QWinFF. An unknown error has occurred. Wystąpił nieznany błąd. A new version of QWinFF has been released! Nowa wersja QWinFF, została wydana! Version <b>%1</b> is available at %2. %1 is version number, %2 is the project homepage Wersja <b>%1</b> jest dostępna w %2. You can download this version using the link: Możesz pobrać tą wersję, za pomocą linku: qwinff-master/src/translations/qwinff_pt_BR.ts000066400000000000000000001124241347323557400221220ustar00rootroot00000000000000 AboutDialog About QWinFF Sobre o QWinFF Information Informação Translators Tradutores Version: %1 Versão: %1 Portable Portátil Compiled with Qt %1 Compilado com Qt %1 Compiled with libnotify %1 Compilado com libnotify %1 QWinFF is a gui frontend for FFmpeg. QWinFF é uma interface para o FFmpeg. Programming: %1 Programação: %1 Logo Design: %1 Logo Design: %1 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 or 3. Este programa é um software livre; você pode redistribuir e/ou modificar sob os termos da GNU GPL versão 2 ou 3. QWinFF Homepage: %1 Página inicial do QWinFF: %1 Some audio-processing functionalities are provided by SoX. Algumas funcionalidades de processamento de áudio são providenciadas pelo SoX. FFmpeg presets were taken from WinFF. As predefinições do FFmpeg foram retirados do WinFF. Japanese Japanese Language Japonês Italian Italian Language Italiano Czech Czech Language Tcheco Simplified Chinese Chinese character set used in China Chinês simplificado Russian Russian Language Russo Spanish (Spain) Spanish Language (Spain) Espanhol (Espanha) Spanish (Guatemala) Spanish Language (Guatemala) Espanhol (Guatemala) Romanian Romanian Language Romeno Turkish Turkish Language Turco Arabic Arabic Language Árabe Hungarian Hungarian Langauge Húngaro Polish Polish Language Polonês French French Language AboutFFmpegDialog About FFmpeg Sobre o FFmpeg FFmpeg FFmpeg Available Codecs Codecs disponíveis FFmpeg is a complete, cross-platform solution to record, convert and stream audio and video. It includes libavcodec - the leading audio/video codec library. ffmpeg description FFmpeg é uma solução multiplataforma completa para gravação, conversão e transmissão de áudio e vídeo. Ele inclui o libavcodec - a biblioteca principal de áudio e vídeo. FFmpeg is free software licensed under the LGPL or GPL. FFmpeg é um software livre licenciado sob a LGPL ou GPL. Please visit %1 for more information. Por favor, visite %1 para mais informações. AddTaskWizard Add Tasks Adicionar tarefas Files to be converted Arquivos para serem convertidos Add files. Adicionar arquivos. Remove selected files. Remover arquivos selecionados. Output Settings Configurações de saída Edit Editar Auto adjust output bitrate to reduce output file size. Ajustar automaticamente a taxa de bits de saída para reduzir o tamanho do arquivo de saída. Auto Adjust Audio Bitrate Ajustar automaticamente a taxa de bits de saída Preset Predefinições Convert to Converter para Output Path Caminho de saída Select &folder Selecionar pasta Browse Navegar Create &new folder in source folder Create a new folder (e.g. qwinff_output) in the folder containing the input files. Put the output files in the newly created folder. Criar nova pasta na pasta de origem Folder Name Nome da pasta Output to &source folder put the output files in the same folder as the input files Saída para a pasta de origem Please select at least one file. Por favor, selecione pelo menos um arquivo. Select Files This text is the title of an openfile dialog. Selecionar arquivos Multimedia Multimídia Video Vídeo Audio Áudio All files Todos os arquivos Select Directory This text is the title of an open directory dialog. Selecionar diretório Searching for files... Procurando arquivos... Some files could not be found. Alguns arquivos não foram encontrados. Folder does not exist. Create a new folder? Pasta não existe. Criar uma nova pasta? Failed to create folder. Please select another output folder. Falha ao criar pasta. Por favor, selecione outra pasta de saída. ConversionParameterDialog Conversion Parameters Parametros de conversão Audio Áudio Disable Audio Desabilitar áudio Audio Options Opções de áudio Sample Rate Taxa de amostragem Hz Hz Bitrate Taxa de bits (auto) (automático) kb/s kb/s Channels Canais Volume Volume % % Video Vídeo Disable Video Desabilitar vídeo Video Options Opções de vídeo Same Quantizer as Source Mesmo quantificador como fonte Deinterlace Desentrelaçar Width Largura px px Height Altura Crop Recortar Time time-related options (speed, length) Tempo Cutting video time cutting: options for begin time and end time Cortando Cut Cut video; select a range to convert Cortar &Preview Visualizar Scaling time scaling, changing the speed of the output file Escalando Speed Velocidade Advanced Avançado FFmpeg FFmpeg Additional FFmpeg Options Opções adicionais do FFmpeg ConvertList Cancel Cancel the operation of adding new tasks Cancelar Adding files (%1/%2) This text is the progress indicator of adding multiple tasks. %1 is the number of files that are already added. %2 is the total number of files. Adicionar arquivos (%1%2) Some files are not recognized by the converter. Alguns arquivos não foram reconhecidos pelo conversor. New File Name Novo nome de arquivo Please input the new name for the output file. Por favor, forneça um novo nome para o arquivo de saída. Output Directory Diretório de saída Error Message from FFmpeg: Mensagem de erro do FFmpeg: Drag and drop files here to add tasks. Arrastar e soltar arquivos aqui para adicionar tarefas. Hide "%1" Hide a column in the list. For example, the text maybe 'Hide "Duration"'. The two " are quotation marks in English, you may replace it with local quotation marks. Ocultar "%1" Restore All Columns Restaurar todas as colunas Source Origem Destination Destino Duration Duração File Size Tamanho do arquivo Sample Rate Audio Taxa de amostragem Audio Bitrate Taxa de bits do áudio Channels Audio Canais Audio Codec Codec de áudio Dimensions Dimensões Video Bitrate Taxa de bits do vídeo Framerate Video Taxa de quadros Video Codec Codec de vídeo Progress Progresso %1 Hz %1 Hz %1 kb/s %1 kb/s %1 fps %1 fps Removing tasks... Remove files from the tasklist Removendo tarefas... KiB KiB MiB MiB GiB GiB TiB TiB B Bytes B File Exists Arquivo existe %1 already exists on disk or in the task list. Still use this name as the output filename? %1 já existe no disco ou na lista de tarefa. Ainda assim deseja usar este nome para o arquivo de saída? Remove Task Remover tarefa Cannot remove a task while it is in progress. Não é possível remover uma tarefa quando ela está em progresso. Finished The text to be displayed on the progress bar when a conversion finishes Concluído Failed The text to be displayed on the progress bar when a conversion fails Falhou Error: %1 %1 is the error message Erro: %1 ExtraTranslations Convert between media file formats Converter entre formatos de arquivos de mídia Media Converter Conversor de mídia InteractiveCuttingDialog Cutting Cutting as in "cutting video" Cortando Mark as Begin Marcar como início Seek to Begin Procurar o inicío Play Selection Reproduzir seleção Mark as End Marcar como final Seek to End Procurar o final %1 not found %1 não encontrado MainWindow QWinFF QWinFF Start conversion process. Iniciar processo de conversão. &Start Iniciar &File Arquivo &Convert &Conversor &About Sobre &Edit &Editar &Add Files &Adicionar arquivos Add files for conversion. Adicionar arquivos para conversão. Ctrl+N Ctrl+N E&xit Sair Exit the program. Sair do programa. F9 F9 S&top Parar Stop conversion process. Parar processo de conversão. Set &Parameters Definir &parâmetros Set Parameters Edit output file parameters. Definir parâmetros Edit conversion parameters of selected files. Editar parâmetros de conversão dos arquivos selecionados. About &Qt Sobre o &Qt About Qt Sobre o Qt &Open Output Folder Abrir pasta de saída Open output folder of the selected file. Abrir pasta de saída do arquivo selecionado. About &FFmpeg Sobre o &FFmpeg About FFmpeg Sobre o FFmpeg &Remove Selected remove selected (tasks, items) &Remover selecionado Remove all selected items in the list. Remover todos os itens selecionados na lista. R&emove Completed remove completed (task, items) R&emover concluídos Remove Completed Items Remover itens concluídos Remove all completed items in the list. Remover todos os itens concluídos da lista. &Clear List Limpar lista Clear List Limpar lista Remove all items in the list. Remover todos os itens da lista. &Retry Tentar novamente Retry Tentar novamente Retry selected tasks. Executar novamente as tarefas selecionadas. Retry &All Executar tudo novamente Retry all tasks. Executar todas as tarefas. &Options &Opções Options Opções About Q&WinFF Sobre o Q&WinFF About This Program Sobre este programa Change Output &Filename Alterar o nome do arquivo de saída Change the output filename of the selected item. Alterar o nome do arquivo de saída do arquivo selecionado. Change Output &Directory Alterar a pasta de saída Change the output directory of the selected items. Alterar a pasta de saída dos arquivos selecionados. Show Error &Message Mostrar mensagem de erro Check For &Updates Verificar atualizações Cut Cut video file (select a time range to conert) Cortar All tasks have finished. Todas as tarefas foram concluidas. Nothing to convert. Nada para converter. Conversion is still in progress. Abort? A conversão está em progresso. Abortar? Shutdown Shutdown the computer (completely poweroff) Desligar Shutdown when all tasks are done. Desligar quando todas as tarefas estivem concluidas. Suspend Suspend the computer (sleep to ram, standby) Suspender Suspend when all tasks are done. Suspender quando todas as tarefas estiverem concluídas. Hibernate Hibernate the computer (sleep to disk, completely poweroff) Hibernar Hibernate when all tasks are done. Hibernar quando todas as tarefas estiverem concluídas. This program is going to check for updates online. Do you allow this program to use the Internet to check for updates? Este programa vai verificar se há atualizações online. Você permite que este programa use a Internet para verificar se há atualizações? Failed to load preset file. The application will quit now. Falha ao carregar o arquivo com configurações predefinidas. Esta aplicação irá encerrar agora. Elapsed Time: %1 h %2 m %3 s Tempo transcorrido: %1 h %2 m %3 s Converting %1/%2 Converting the %1-th file in %2 files. %2 is the number of files. Convertendo %1/%2 MediaConverter %1 not found. %1 is a computer program %1 não encontrado. OptionsDialog Options Opções General Geral Check for updates on program startup Verificar atualizações ao inicializar o programa Automatically start conversion after adding files to the list. Iniciar conversão automáticamente após adicionar arquivos para a lista. Start conversion automatically Iniciar conversão automaticamente FFmpeg FFmpeg Number of threads to use in conversion Número de threads (fluxo de execução) para usar na conversão <html><head/><body><p>Hide output formats that are not available in the current ffmpeg installation. It is recommended to turn this option on unless you are sure that QWinFF has failed to detect available formats. (requires restarting QWinFF to take effect)</p></body></html> <html><head/><body><p>Ocultar formatos de saída que não estão disponíveis na instalação atual do ffmpeg. Recomenda-se a ativar essa opção, a menos que você tenha certeza que o QWinFF falhou em detectar os formatos disponíveis. (requer a reinicialização QWinFF para entrar em vigor)</p></body></html> Hide unavailable formats (requires restarting) Ocultar formatos indisponíveis (requer reinicialização) Tools Ferramentas You have to restart QWinFF for the changes to take effect. Você tem que reiniciar o QWinFF para que as alterações tenham efeito. Name Nome Command Comando PoweroffDialog QWinFF QWinFF Cancel Cancelar Shutdown immediately Shutdown the computer Desligar imediatamente Suspend immediately Suspend the computer (sleep to ram, standby) Suspender imediatamente Hibernate immediately Hibernate the computer (sleep to disk, completely poweroff) Hibernar imediatamente Shutdown Shutdown the computer Desligar Suspend Suspend the computer (sleep to ram, standby) Suspender Hibernate Hibernate the computer (sleep to disk, completely poweroff) Hibernar Operation Failed: %1 Operação falhou: %1 Shutting down in <b>%1</b> seconds Desligando em <b>%1</b> segundos Suspending in <b>%1</b> seconds Suspendendo em <b>%1</b> segundos Hibernating in <b>%1</b> seconds Hibernando em <b>%1</b> segundos PreviewDialog Dialog Dialogo Play Selected Range Executar intervalo selecionado %1 not found %1 não encontrado Begin noun, the beginning of the video Início End noun, the end of the video Final Play %1~%2 play the video from time %1 to time %2. %1 and %2 are time in hh:mm:ss format. Executar %1~%2 TimeRangeEdit From Begin Para o início To End Para o final UpdateDialog Show &Release Notes Mostrar notas de lançamento Check for updates on program startup Verificar por atualizações ao inicializar o programa Downloading update information... Baixando informações de atualização... Cannot connect to server. Não foi possível conectar ao servidor. Failed to parse the received data. Falha ao analisar os dados recebidos. You are already using the latest version of QWinFF. Você já está usando a versão recente do QWinFF. An unknown error has occurred. Ocorreu um erro desconhecido. A new version of QWinFF has been released! Uma nova versão do QWinFF foi lançada! Version <b>%1</b> is available at %2. %1 is version number, %2 is the project homepage A versão <b>%1</b> está disponível em %2. You can download this version using the link: Você pode baixar essa versão usando o link: qwinff-master/src/translations/qwinff_ro_RO.ts000066400000000000000000001127311347323557400221350ustar00rootroot00000000000000 AboutDialog About QWinFF Despre QWinFF Information Informații Translators Traducători Version: %1 Versiune: %1 Portable Portabil Compiled with Qt %1 Compilat cu Qt %1 Compiled with libnotify %1 Compilat cu libnotify %1 QWinFF is a gui frontend for FFmpeg. QWinFF este o interfață GUI pentru FFmpeg. Programming: %1 Programare: %1 Logo Design: %1 Design logo: %1 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 or 3. Acest program este software liber; îl poți redistribui și/sau modifica în conformitate cu termenii Licenței Publice Generale GNU versiunea 2 sau 3. QWinFF Homepage: %1 Pagina acasă QWinFF: %1 Some audio-processing functionalities are provided by SoX. Unele funcționalități de prelucrare audio sunt oferite de SoX. FFmpeg presets were taken from WinFF. Presetările FFmpeg au fost luate din WinFF. Japanese Japanese Language Japoneză Italian Italian Language Italiană Czech Czech Language Cehă Simplified Chinese Chinese character set used in China Chineză simplificată Russian Russian Language Rusă Spanish (Spain) Spanish Language (Spain) Spaniolă (Spania) Spanish (Guatemala) Spanish Language (Guatemala) Spaniolă (Guatemala) Romanian Romanian Language Română Turkish Turkish Language Turcă Arabic Arabic Language Arabă Hungarian Hungarian Langauge Polish Polish Language French French Language AboutFFmpegDialog About FFmpeg Despre FFmpeg FFmpeg FFmpeg Available Codecs Codecuri disponibile FFmpeg is a complete, cross-platform solution to record, convert and stream audio and video. It includes libavcodec - the leading audio/video codec library. ffmpeg description FFmpeg este un sistem complet, soluție cross-platform pentru a înregistra, converti fluxuri audio și video. Acesta include libavcodec - bibliotecă codec lider în materie. FFmpeg is free software licensed under the LGPL or GPL. FFmpeg este un software gratuit sub licența LGPL sau GPL. Please visit %1 for more information. Te rog vizitează %1 pentru mai multe informații. AddTaskWizard Add Tasks Adaugă sarcini Files to be converted Fișierele care urmează să fie convertite Add files. Adaugă fișiere. Remove selected files. Elimină fișierele selectate. Output Settings Setări de ieșire Edit Editare Auto adjust output bitrate to reduce output file size. Ajustare automată a ratei de biți de ieșire pentru a reduce dimensiunea fișierului rezultat. Auto Adjust Audio Bitrate Ajustare automată a ratei de biți audio Preset Presetate Convert to Conversie în Output Path Calea de ieșire Select &folder Selectează &dosar Browse Răsfoiește Create &new folder in source folder Create a new folder (e.g. qwinff_output) in the folder containing the input files. Put the output files in the newly created folder. Creează un nou dosar în dosarul sursă Folder Name Nume dosar Output to &source folder put the output files in the same folder as the input files Scrie în dosarul &sursă Please select at least one file. Selectează cel puțin un fișier. Select Files This text is the title of an openfile dialog. Selectează fișiere Multimedia Multimedia Video Video Audio Audio All files Toate fișierele Select Directory This text is the title of an open directory dialog. Selectează dosarul Searching for files... Some files could not be found. Unele fișiere nu au putut fi găsite. Folder does not exist. Create a new folder? Dosarul nu există. Creezi un dosar nou? Failed to create folder. Please select another output folder. Crearea dosarului a eșuat. Te rog selectează un alt dosar de ieșire. ConversionParameterDialog Conversion Parameters Parametrii de conversie Audio Audio Disable Audio Dezactivează audio Audio Options Opțiuni audio Sample Rate Rată de eșantionare Hz Hz Bitrate Rată de biți (auto) (auto) kb/s kb/s Channels Canale Volume Volum % % Video Video Disable Video Dezactivează video Video Options Opțiuni video Same Quantizer as Source Quantizer Identic cu al Sursei Deinterlace Deinterlace Width Lățime px px Height Înălțime Crop Decupează Time time-related options (speed, length) Timp Cutting video time cutting: options for begin time and end time Tăiere Cut Cut video; select a range to convert &Preview &Previzualizare Scaling time scaling, changing the speed of the output file Scalarea Speed Viteză Advanced Avansate FFmpeg FFmpeg Additional FFmpeg Options Opțiuni suplimentare FFmpeg ConvertList Cancel Cancel the operation of adding new tasks Renunță Adding files (%1/%2) This text is the progress indicator of adding multiple tasks. %1 is the number of files that are already added. %2 is the total number of files. Adăugare fișiere (%1/%2) Some files are not recognized by the converter. Unele fișiere nu sunt recunoscute de către convertor. New File Name Numele noului fișier Please input the new name for the output file. Vă rugăm să introduceți noul nume a fișierului în ieșire Output Directory Directorul de Ieșire Error Message from FFmpeg: Mesajul de eroare de la FFmpeg: Drag and drop files here to add tasks. Trage fișiere aici pentru a adăuga sarcini. Hide "%1" Hide a column in the list. For example, the text maybe 'Hide "Duration"'. The two " are quotation marks in English, you may replace it with local quotation marks. Ascunde "%1" Restore All Columns Restaurarea tuturor coloanelor Source Sursă Destination Destinație Duration Durată File Size Dimensiune Sample Rate Audio Rată de eșantionare Audio Bitrate Rată de biți audio Channels Audio Canale Audio Codec Codec audio Dimensions Dimensiuni Video Bitrate Rată de biți video Framerate Video Framerate Video Codec Codec video Progress Progres %1 Hz %1 Hz %1 kb/s %1 kb/s %1 fps %1 fps Removing tasks... Remove files from the tasklist Eliminare sarcini... KiB KiB MiB MiB GiB GiB TiB TiB B Bytes B File Exists Fișierul există %1 already exists on disk or in the task list. Still use this name as the output filename? %1 există deja pe disc sau în lista de activități. Folosesc oricum acest nume ca numele fișierului de ieșire? Remove Task Elimină sarcina Cannot remove a task while it is in progress. Nu se poate șterge o sarcină în timp ce este în curs de desfășurare. Finished The text to be displayed on the progress bar when a conversion finishes Terminat Failed The text to be displayed on the progress bar when a conversion fails A eșuat Error: %1 %1 is the error message Eroare: %1 ExtraTranslations Convert between media file formats Converteşte formatele de fișiere media Media Converter Media Converter InteractiveCuttingDialog Cutting Cutting as in "cutting video" Tăiere Mark as Begin Seek to Begin Play Selection Mark as End Seek to End %1 not found MainWindow QWinFF QWinFF Start conversion process. Începe procesul de conversie. &Start &Start &File &Fișier &Convert &Conversie &About &Despre &Edit &Editare &Add Files &Adaugă fișiere Add files for conversion. Adaugă fișiere pentru conversie. Ctrl+N Ctrl+N E&xit Term&ină Exit the program. Ieșire din program. F9 F9 S&top S&top Stop conversion process. Oprirea procesului de conversie. Set &Parameters Setare &parametrii Set Parameters Edit output file parameters. Setare parametrii Edit conversion parameters of selected files. Editarea parametrilor de conversie ale fișierelor selectate. About &Qt Despre &Qt About Qt Despre Qt &Open Output Folder &Deschide Folderul de Ieşire Open output folder of the selected file. Deschide dosarul de ieșire al fișierului selectat. About &FFmpeg Despre & FFmpeg About FFmpeg Despre FFmpeg &Remove Selected remove selected (tasks, items) &Eliminarea celor Selecționate Remove all selected items in the list. Eliminarea tuturor elementelor selectate din lista. R&emove Completed remove completed (task, items) E&liminarea celor Finalizate Remove Completed Items Eliminarea Elemente Finalizate Remove all completed items in the list. Elimina toate elementele finalizate din listă. &Clear List &Golire listă Clear List Golire listă Remove all items in the list. Eliminarea tuturor elementelor din lista. &Retry &Reîncercați Retry Reîncercați Retry selected tasks. Reîncercați elementele selectate Retry &All Reîncercați &Toate Retry all tasks. Reîncercați toate sarcinile. &Options &Opțiuni Options Opțiuni About Q&WinFF Despre Q&WinFF About This Program Despre Acest Program Change Output &Filename Modificarea &Numele Fișierului În Ieșire Change the output filename of the selected item. Modificarea fișierului de ieșire a elementului selectat. Change Output &Directory Modificarea &Directorului de Ieșire Change the output directory of the selected items. Schimbați directorul de ieșire ale elementelor selectate. Show Error &Message Afişează &Mesajul de Eroare Check For &Updates Verifică pentru act&ualizări Cut Cut video file (select a time range to conert) All tasks have finished. Toate sarcinile s-au terminat. Nothing to convert. Nimic de convertit. Conversion is still in progress. Abort? Conversia este încă în curs. Abandonați? Shutdown Shutdown the computer (completely poweroff) Shutdown Shutdown when all tasks are done. Shutdown atunci când toate sarcinile au fost finalizate. Suspend Suspend the computer (sleep to ram, standby) Suspendare Suspend when all tasks are done. Suspendare atunci când toate sarcinile au fost efectuate. Hibernate Hibernate the computer (sleep to disk, completely poweroff) Hibernare Hibernate when all tasks are done. Hibernare când toate sarcinile sunt efectuate. This program is going to check for updates online. Do you allow this program to use the Internet to check for updates? Acest program va căuta actualizări pe internet. Îi permiți acestui program să folosească internetul pentru a verifica dacă există actualizări? Failed to load preset file. The application will quit now. Imposibilă încărcarea fișierului presetat. Aplicaţia se va închide acum. Elapsed Time: %1 h %2 m %3 s Timp scurs: %1 h %2 m %3 s Converting %1/%2 Converting the %1-th file in %2 files. %2 is the number of files. Se execută conversia %1/%2 MediaConverter %1 not found. %1 is a computer program %1 nu a fost găsit. OptionsDialog Options Opțiuni General General Check for updates on program startup Verifică pentru actualizări la pornirea programului Automatically start conversion after adding files to the list. Pornește automat conversia după adăugarea fișierelor în listă. Start conversion automatically Pornește conversia automat FFmpeg FFmpeg Number of threads to use in conversion Numărul de threaduri utilizate în conversie <html><head/><body><p>Hide output formats that are not available in the current ffmpeg installation. It is recommended to turn this option on unless you are sure that QWinFF has failed to detect available formats. (requires restarting QWinFF to take effect)</p></body></html> <html><head/><body><p>Ascunde formatele de ieșire care nu sunt disponibile în instalarea curentă FFMPEG. Este recomandat să dezactivați această opțiune numai în cazul în care sunteți sigur că QWinFF nu a reușit să detecteze corect formatele disponibile. (Necesită repornirea QWinFF )</p></body></html> Hide unavailable formats (requires restarting) Ascunde formatele indisponibile (necesită repornirea) Tools Instrumente You have to restart QWinFF for the changes to take effect. Trebuie să reporniți QWinFF pentru ca modificările să aibă efect. Name Nume Command Comandă PoweroffDialog QWinFF QWinFF Cancel Anulare Shutdown immediately Shutdown the computer Shutdown imediat Suspend immediately Suspend the computer (sleep to ram, standby) Suspendare imediată Hibernate immediately Hibernate the computer (sleep to disk, completely poweroff) Hibernare imediată Shutdown Shutdown the computer Shutdown Suspend Suspend the computer (sleep to ram, standby) Suspendare Hibernate Hibernate the computer (sleep to disk, completely poweroff) Hibernare Operation Failed: %1 Operație eșuată: %1 Shutting down in <b>%1</b> seconds Stingere în <b>%1</b> secunde Suspending in <b>%1</b> seconds Suspendare în <b>%1</b> secunde Hibernating in <b>%1</b> seconds Hibernare în <b>%1</b> secunde PreviewDialog Dialog Play Selected Range %1 not found Begin noun, the beginning of the video End noun, the end of the video Play %1~%2 play the video from time %1 to time %2. %1 and %2 are time in hh:mm:ss format. TimeRangeEdit From Begin De la început To End Până la capăt UpdateDialog Show &Release Notes A&rată notele de lansare Check for updates on program startup Verifică pentru actualizări la pornirea programului Downloading update information... Se descarcă informațiile despre actualizare... Cannot connect to server. Nu se poate efectua conectarea la server. Failed to parse the received data. Interpretarea datelor primite a eșuat. You are already using the latest version of QWinFF. Deja folosești ultima versiune de QWinFF. An unknown error has occurred. A intervenit o eroare necunoscută. A new version of QWinFF has been released! A apărut o nouă versiune de QWinFF! Version <b>%1</b> is available at %2. %1 is version number, %2 is the project homepage Versiunea <b>%1</b> este disponibilă la %2. You can download this version using the link: Poți descărca această versiunea folosind legătura: qwinff-master/src/translations/qwinff_ru.ts000066400000000000000000001230151347323557400215400ustar00rootroot00000000000000 AboutDialog About QWinFF О QWinFF Information Информация Translators Переводчики Version: %1 Версия: %1 Portable Переносная Compiled with Qt %1 Скомпилированно с помощью Qt %1 Compiled with libnotify %1 Скомпилированно с libnotify %1 QWinFF is a gui frontend for FFmpeg. QWinFF — графический интерфейс для FFmpeg. Programming: %1 Программирование: %1 Logo Design: %1 Дизайн логотипа: %1 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 or 3. Это свободное программное обеспечение. Вы можете распространять и изменять его на условиях GNU General Public License версии 2 или 3. QWinFF Homepage: %1 Домашняя страница QWinFF: %1 Some audio-processing functionalities are provided by SoX. Некоторые функции обработки аудио предоставлены SoX. FFmpeg presets were taken from WinFF. Предустановки FFmpeg были заимствованы из WinFF. Japanese Japanese Language Японский Italian Italian Language Итальянский Czech Czech Language Чешский Simplified Chinese Chinese character set used in China Упрощённый китайский Russian Russian Language Русский Spanish (Spain) Spanish Language (Spain) Испанский (Испания) Spanish (Guatemala) Spanish Language (Guatemala) Испанский (Гватемала) Romanian Romanian Language Румынский Turkish Turkish Language Турецкий Arabic Arabic Language Арабский Hungarian Hungarian Langauge Болгарский Polish Polish Language Польский French French Language Французский AboutFFmpegDialog About FFmpeg О FFmpeg FFmpeg FFmpeg Available Codecs Доступные кодеки FFmpeg is a complete, cross-platform solution to record, convert and stream audio and video. It includes libavcodec - the leading audio/video codec library. ffmpeg description FFmpeg — полноценное кроссплатформенное решение для записи, конвертации и вещания аудио и видео. Оно включает libavcodec — ведущую библиотеку кодеков для аудио и видео. FFmpeg is free software licensed under the LGPL or GPL. FFmpeg — свободное программное обеспечение, лицензированное под LGPL или GPL. Please visit %1 for more information. Посетите %1, чтобы получить дополнительную информацию. AddTaskWizard Add Tasks Добавить задания Files to be converted Файлы для преобразования Add files. Добавить файлы. Remove selected files. Удалить выбранные файлы. Output Settings Настройки вывода Edit Правка Auto adjust output bitrate to reduce output file size. Автоматически подстроить битрейт для уменьшения размера итогового файла. Auto Adjust Audio Bitrate Автоматически подстроить битрейт звука Preset Предустановки Convert to Преобразовать в Output Path Путь вывода Select &folder Выберите &папку Browse Обзор Create &new folder in source folder Create a new folder (e.g. qwinff_output) in the folder containing the input files. Put the output files in the newly created folder. Создать &новую папку в исходной Folder Name Имя папки Output to &source folder put the output files in the same folder as the input files Выводить в &исходную папку Please select at least one file. Нужно выбрать хотя бы один файл. Select Files This text is the title of an openfile dialog. Выбрать файлы Multimedia Мультимедиа Video Видео Audio Аудио All files Все файлы Select Directory This text is the title of an open directory dialog. Выбрать папку Searching for files... Поиск файлов... Some files could not be found. Некоторые файлы не найдены. Folder does not exist. Create a new folder? Папка не существует. Создать новую папку? Failed to create folder. Please select another output folder. Не удалось создать папку. Укажите другую папку. ConversionParameterDialog Conversion Parameters Параметры преобразования Audio Аудио Disable Audio Отключить аудио Audio Options Настройки аудио Sample Rate Частота дискретизации Hz Гц Bitrate Битрейт (auto) (авто) kb/s Кб/с Channels Каналы Volume Громкость % % Video Видео Disable Video Отключить видео Video Options Настройки видео Same Quantizer as Source Такой же квантователь, как у исходного Deinterlace Деинтерлейсинг Width Ширина px px Height Высота Crop Кадрирование Time time-related options (speed, length) Время Cutting video time cutting: options for begin time and end time Обрезка Cut Cut video; select a range to convert Вырезать &Preview &Предпросмотр Scaling time scaling, changing the speed of the output file Масштабирование Speed Скорость Advanced Дополнительно FFmpeg FFmpeg Additional FFmpeg Options Дополнительные настройки FFmpeg ConvertList Cancel Cancel the operation of adding new tasks Отмена Adding files (%1/%2) This text is the progress indicator of adding multiple tasks. %1 is the number of files that are already added. %2 is the total number of files. Добавление файлов (%1/%2) Some files are not recognized by the converter. Некоторые файлы не опознаны конвертером. New File Name Новое имя файла Please input the new name for the output file. Требуется указать новое имя итогового файла. Output Directory Папка вывода Error Message from FFmpeg: Сообщение об ошибке от FFmpeg: Drag and drop files here to add tasks. Перетащите сюда файлы, чтобы добавить задания. Hide "%1" Hide a column in the list. For example, the text maybe 'Hide "Duration"'. The two " are quotation marks in English, you may replace it with local quotation marks. Скрыть "%1" Restore All Columns Восстановить все столбцы Source Источник Destination Назначение Duration Длительность File Size Размер файла Sample Rate Audio Частота дискретизации Audio Bitrate Битрейт аудио Channels Audio Каналы Audio Codec Кодек аудио Dimensions Измерения Video Bitrate Битрейт видео Framerate Video Частота кадров Video Codec Кодек видео Progress Прогресс %1 Hz %1 Гц %1 kb/s %1 Кб/с %1 fps %1 fps Removing tasks... Remove files from the tasklist Удаление заданий… KiB КиБ MiB МиБ GiB ГиБ TiB ТиБ B Bytes Б File Exists Файл существует %1 already exists on disk or in the task list. Still use this name as the output filename? %1 уже существует на диске или в списке заданий. Всё равно использовать это имя файла в качестве итогового? Remove Task Удалить задание Cannot remove a task while it is in progress. Нельзя удалить задание, пока оно выполняется. Finished The text to be displayed on the progress bar when a conversion finishes Завершено Failed The text to be displayed on the progress bar when a conversion fails Не удалось Error: %1 %1 is the error message Ошибка: %1 ExtraTranslations Convert between media file formats Преобразование между медиа-форматами Media Converter Медиа-конвертер InteractiveCuttingDialog Cutting Cutting as in "cutting video" Обрезка Mark as Begin Отметить начало Seek to Begin Перейти в конец Play Selection Воспроизвести выделенное Mark as End Отметить конец Seek to End Перейти в начало %1 not found %1 не найден MainWindow QWinFF QWinFF Start conversion process. Запустить процесс преобразования. &Start &Старт &File &Файл &Convert П&реобразовать &About &О приложении &Edit &Правка &Add Files &Добавить файлы Add files for conversion. Добавить файлы для преобразования. Ctrl+N Ctrl+N E&xit В&ыход Exit the program. Выйти из приложения. F9 F9 S&top С&топ Stop conversion process. Остановить процесс преобразования. Set &Parameters Настроить &параметры Set Parameters Edit output file parameters. Настроить параметры Edit conversion parameters of selected files. Редактировать параметры преобразования файлов. About &Qt О &Qt About Qt О Qt &Open Output Folder &Открыть папку вывода Open output folder of the selected file. Открыть выходную папку выбранного файла. About &FFmpeg О &FFmpeg About FFmpeg О FFmpeg &Remove Selected remove selected (tasks, items) &Удалить выбранное Remove all selected items in the list. Удалить выбранные элементы из списка. R&emove Completed remove completed (task, items) У&далить завершёные Remove Completed Items Удалить завершённые элементы Remove all completed items in the list. Удалить завершённые элементы из списка &Clear List Оч&истить список Clear List Очистить список Remove all items in the list. Удалить все элементы из списка &Retry &Попробовать снова Retry Попробовать снова Retry selected tasks. Перезапустить выбранные задания. Retry &All Перезапустить &все Retry all tasks. Перезапустить все задания. &Options &Настройки Options Настройки About Q&WinFF О Q&WinFF About This Program Об этом приложении Change Output &Filename Изменить имя итогового &файла Change the output filename of the selected item. Изменить имя итогового файла выбранного элемента. Change Output &Directory Изменить папку &вывода Change the output directory of the selected items. Изменить папку вывода выбранного элемента. Show Error &Message Показать &сообщение об ошибке Check For &Updates Проверить &обновления Cut Cut video file (select a time range to conert) Вырезать All tasks have finished. Все задания завершены. Nothing to convert. Нет объектов для преобразования. Conversion is still in progress. Abort? Выполняется преобразование. Прервать? Shutdown Shutdown the computer (completely poweroff) Выключение Shutdown when all tasks are done. Выключить при завершении всех заданий. Suspend Suspend the computer (sleep to ram, standby) Ждущий режим Suspend when all tasks are done. Перейти в ждущий режим при завершении всех заданий. Hibernate Hibernate the computer (sleep to disk, completely poweroff) Гибернация Hibernate when all tasks are done. Перейти в состояние гибернации после завершения всех заданий. This program is going to check for updates online. Do you allow this program to use the Internet to check for updates? Приложение проверит наличие обновление. Разрешить приложению использовать Интернет для поиска обновлений? Failed to load preset file. The application will quit now. Не удалось загрузить файл предустановок. Приложение завершается. Elapsed Time: %1 h %2 m %3 s Оставшееся время: %1 ч %2 м %3 c Converting %1/%2 Converting the %1-th file in %2 files. %2 is the number of files. Преобразование %1/%2 MediaConverter %1 not found. %1 is a computer program %1 не найден. OptionsDialog Options Настройки General Основной Check for updates on program startup Проверять обновления при запуске приложения Automatically start conversion after adding files to the list. Начинать преобразование автоматически после добавления файлов в список. Start conversion automatically Начинать преобразование автоматически FFmpeg FFmpeg Number of threads to use in conversion Количество потоков при конвертации <html><head/><body><p>Hide output formats that are not available in the current ffmpeg installation. It is recommended to turn this option on unless you are sure that QWinFF has failed to detect available formats. (requires restarting QWinFF to take effect)</p></body></html> <html><head/><body><p>Скрыть форматы вывода, недоступные в текущей установке ffmpeg. Рекомендуется включить эту опцию, если только вы не уверены, что QWinFF не смог обнаружить доступные форматы. (Требуется перезапуск QWinFF)</p></body></html> Hide unavailable formats (requires restarting) Скрыть недоступные форматы (требуется перезапуск) Tools Инструменты You have to restart QWinFF for the changes to take effect. Перезапустите QWinFF, чтобы настройки вступили в силу. Name Имя Command Команда PoweroffDialog QWinFF QWinFF Cancel Отмена Shutdown immediately Shutdown the computer Завершить работу немедленно Suspend immediately Suspend the computer (sleep to ram, standby) Перейти в ждущий режим немедленно Hibernate immediately Hibernate the computer (sleep to disk, completely poweroff) Перейти в состояние гибернации немедленно Shutdown Shutdown the computer Завершить Suspend Suspend the computer (sleep to ram, standby) Ждущий режим Hibernate Hibernate the computer (sleep to disk, completely poweroff) Гибернация Operation Failed: %1 Операция не удалась: %1 Shutting down in <b>%1</b> seconds Завершение работы через <b>%1</b> с. Suspending in <b>%1</b> seconds Переход в ждущий режим через <b>%1</b> c. Hibernating in <b>%1</b> seconds Переход в состояние гибернации через <b>%1</b> c. PreviewDialog Dialog Предпросмотр Play Selected Range Воспроизвести выбранный участок %1 not found %1 не найден Begin noun, the beginning of the video Начало End noun, the end of the video Конец Play %1~%2 play the video from time %1 to time %2. %1 and %2 are time in hh:mm:ss format. Воспроизвести %1~%2 TimeRangeEdit From Begin Начало To End Конец UpdateDialog Show &Release Notes Примечания к &релизу Check for updates on program startup Проверять обновления при запуске приложения Downloading update information... Загружается информация об обновлении... Cannot connect to server. Не удалось связаться с сервером. Failed to parse the received data. Не удалось обработать полученные данные. You are already using the latest version of QWinFF. Ваша версия QWinFF не нуждается в обновлении. An unknown error has occurred. Произошла неизвестная ошибка. A new version of QWinFF has been released! Опубликована новая версия QWinFF! Version <b>%1</b> is available at %2. %1 is version number, %2 is the project homepage Версия <b>%1</b> доступна в %2. You can download this version using the link: Вы можете скачать эту версию используя ссылку: qwinff-master/src/translations/qwinff_tr_TR.ts000066400000000000000000001112541347323557400221460ustar00rootroot00000000000000 AboutDialog About QWinFF QWinFF Hakkında Information Bilgi Translators Çevirmenler Version: %1 Sürüm: %1 Portable Taşınabilir Compiled with Qt %1 Qt ile derlendi %1 Compiled with libnotify %1 libnotify ile derlendi %1 QWinFF is a gui frontend for FFmpeg. QWinFF FFmpeg arayüzdür. Programming: %1 Programlama: %1 Logo Design: %1 Logo Tasarımı: %1 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 or 3. Bu program ücretsiz bir yazılımdır; GNU Genel Kamu Lisansı sürümü 2 veya 3 şartları altında yeniden dağıtabilir ve/veya değiştirebilirsiniz. QWinFF Homepage: %1 QWinFF Web Sayfası: %1 Some audio-processing functionalities are provided by SoX. Bazı ses işleme işlevleri SOX tarafından sağlanmaktadır. FFmpeg presets were taken from WinFF. WinFF'den öntanımlı FFmpeg ayarları. Japanese Japanese Language Japonca Italian Italian Language İtalyanca Czech Czech Language Çekce Simplified Chinese Chinese character set used in China Basitleştirilmiş Çince Russian Russian Language Rusça Spanish (Spain) Spanish Language (Spain) İspanyolca (İspanya) Spanish (Guatemala) Spanish Language (Guatemala) İspanyolca (Guatemala) Romanian Romanian Language Romen Turkish Turkish Language Türkçe Arabic Arabic Language Hungarian Hungarian Langauge Polish Polish Language French French Language AboutFFmpegDialog About FFmpeg FFmpeg Hakkında FFmpeg FFmpeg Available Codecs Mevcut Kodlayıcılar FFmpeg is a complete, cross-platform solution to record, convert and stream audio and video. It includes libavcodec - the leading audio/video codec library. ffmpeg description FFmpeg, kayıt ve dönüştürme ses ve video akışı için tam bir çapraz platform çözümüdür.Önde gelen ses/video kodlayıcı kütüphanesi - libavcodec içerir. FFmpeg is free software licensed under the LGPL or GPL. FFmpeg LGPL veya GPL lisanslı ücretsiz bir yazılımdır. Please visit %1 for more information. Daha fazla bilgi için %1 ziyaret edin. AddTaskWizard Add Tasks Görevler ekle Files to be converted Dönüştürülecek dosyalar Add files. Dosyaları ekle. Remove selected files. Seçilen dosyaları kaldır. Output Settings Çıkış Ayarları Edit Düzenle Auto adjust output bitrate to reduce output file size. Otomatik çıktı dosya boyutunu azaltmak için çıkış bit hızını ayarlayabilirsiniz. Auto Adjust Audio Bitrate Otomatik ses bit hızı ayarlayın Preset Önayar Convert to Dönüştür Output Path Çıkış Yolu Select &folder Browse Gözat Create &new folder in source folder Create a new folder (e.g. qwinff_output) in the folder containing the input files. Put the output files in the newly created folder. Folder Name Output to &source folder put the output files in the same folder as the input files Please select at least one file. En az bir dosya seçiniz. Select Files This text is the title of an openfile dialog. Dosyaları Seç Multimedia Çokluortam Video Video Audio Ses All files Tüm dosyalar Select Directory This text is the title of an open directory dialog. Dizin Seç Searching for files... Some files could not be found. Bazı dosyalar bulunamadı. Folder does not exist. Create a new folder? Dizin yok. Yeni bir dizin oluşturun mu? Failed to create folder. Please select another output folder. Dizin oluşturulamadı. Başka bir çıkış dizini seçin. ConversionParameterDialog Conversion Parameters Dönüşüm Parametreleri Audio Ses Disable Audio Sesi devre dışı bırak Audio Options Ses Seçenekleri Sample Rate Örnekleme Oranı Hz Hz Bitrate Bit Hızı (auto) (otomatik) kb/s kb/s Channels Kanallar Volume ses seviyesi % % Video Video Disable Video Videoyu Dışı Bırak Video Options Video Seçenekleri Same Quantizer as Source Kaynakla aynı nicemleyici Deinterlace Görüntü çözme Width Genişlik px px Height Yükseklik Crop Kırp Time time-related options (speed, length) Süre Cutting video time cutting: options for begin time and end time Kırpma Cut Cut video; select a range to convert &Preview &Önizleme Scaling time scaling, changing the speed of the output file Ölçeklendirme Speed Hız Advanced Gelişmiş FFmpeg FFmpeg Additional FFmpeg Options Ek FFmpeg Seçenekleri ConvertList Cancel Cancel the operation of adding new tasks İptal Adding files (%1/%2) This text is the progress indicator of adding multiple tasks. %1 is the number of files that are already added. %2 is the total number of files. Dosyalar ekleniyor (%1/%2) Some files are not recognized by the converter. Bazı dosyalar dönüştürücü tarafından tanınmamaktadır. New File Name Yeni Dosya Adı Please input the new name for the output file. Lütfen çıktı dosyası için yeni ad girin. Output Directory Çıktı Dizini Error Message from FFmpeg: FFmpeg tarafından hata iletisi: Drag and drop files here to add tasks. Hide "%1" Hide a column in the list. For example, the text maybe 'Hide "Duration"'. The two " are quotation marks in English, you may replace it with local quotation marks. Gizle "%1" Restore All Columns Tüm Sütunları eski haline getir Source kaynak Destination Hedef Duration Süreç File Size Dosya Boyutu Sample Rate Audio Örnekleme Oranı Audio Bitrate Ses bit hızı Channels Audio Kanallar Audio Codec Ses Kodlayıcı Dimensions Ölçüler Video Bitrate Video bit hızı Framerate Video Kare Hızı Video Codec Video Kodlayıcı Progress İlerleme %1 Hz %1 Hz %1 kb/s %1 kb/s %1 fps %1 fps Removing tasks... Remove files from the tasklist Görevler kaldırılıyor ... KiB KiB MiB MiB GiB GiB TiB TiB B Bytes B File Exists Dosya Var %1 already exists on disk or in the task list. Still use this name as the output filename? %1 diskinizde veya görev listesinde zaten var. Hala çıkış dosya adı olarak bu ad kullanılınsın mı? Remove Task Görev kaldır Cannot remove a task while it is in progress. İşlem devam ederken görev kaldırılamaz. Finished The text to be displayed on the progress bar when a conversion finishes Bitti Failed The text to be displayed on the progress bar when a conversion fails Başarısız Error: %1 %1 is the error message Hata: %1 ExtraTranslations Convert between media file formats Çokluortam dosya biçimleri arasında dönüştürme Media Converter Çokluortam Dönüştürücü InteractiveCuttingDialog Cutting Cutting as in "cutting video" Kırpma Mark as Begin Seek to Begin Play Selection Mark as End Seek to End %1 not found MainWindow QWinFF QWinFF Start conversion process. Dönüştürme işlemini başlat. &Start &Başlat &File &Dosya &Convert Dö&nüştür &About &Hakkında &Edit Düzenl&e &Add Files &Dosya Ekle Add files for conversion. Dönüşüm için dosyaları ekleyin. Ctrl+N Ctrl+N E&xit &Çık Exit the program. Programdan çık. F9 F9 S&top &Durdur Stop conversion process. Dönüştürme işlemi durdur. Set &Parameters Ayar &Parametreler Set Parameters Edit output file parameters. Parametre Ayarları Edit conversion parameters of selected files. Seçilen dosyaların dönüşüm parametrelerini düzenleyin. About &Qt Hakkında &Qt About Qt Qt Hakkında &Open Output Folder &Çıktı Klasörünü Aç Open output folder of the selected file. About &FFmpeg Hakkında &FFmpeg About FFmpeg FFmpeg Hakkında &Remove Selected remove selected (tasks, items) &Seçileni kaldır Remove all selected items in the list. Listede seçili tüm öğeleri kaldır. R&emove Completed remove completed (task, items) &Tamamlananları kaldır Remove Completed Items Tamamlanan Öğeleri Kaldır Remove all completed items in the list. Listedeki tüm tamamlanan öğeleri kaldır. &Clear List &Listeyi Temizle Clear List Listeyi Temizle Remove all items in the list. Listedeki tüm öğeleri kaldırın. &Retry &Tekrar dene Retry Tekrar dene Retry selected tasks. Seçilen görevler yeniden deneyin. Retry &All Tekrar dene &Hepsi Retry all tasks. Tüm görevleri yeniden deneyin. &Options &Seçenekler Options Seçenekler About Q&WinFF Hakkında Q&WinFF About This Program Bu Program Hakkında Change Output &Filename Çıktı &Dosya Adı Değiştir Change the output filename of the selected item. Seçili öğenin çıkış dosya adı değiştirin. Change Output &Directory Değiştir Çıktı &Dizin Change the output directory of the selected items. Seçilen öğelerin çıkış dizinini değiştirin. Show Error &Message Hata Göster &İleti Check For &Updates Cut Cut video file (select a time range to conert) All tasks have finished. Tüm görevleri tamamladı. Nothing to convert. Dönüştürmek için bir şey yok. Conversion is still in progress. Abort? Dönüşüm devam etmektedir. İptal edilsin mi? Shutdown Shutdown the computer (completely poweroff) Kapat Shutdown when all tasks are done. Tüm görevler bittiğinde kapat. Suspend Suspend the computer (sleep to ram, standby) Askıya al Suspend when all tasks are done. Tüm görevler bittiğinde askıya al. Hibernate Hibernate the computer (sleep to disk, completely poweroff) Hazırda Beklet Hibernate when all tasks are done. Tüm görevler bittiğinde hazırda beklet. This program is going to check for updates online. Do you allow this program to use the Internet to check for updates? Failed to load preset file. The application will quit now. Önayar dosyası yüklenemedi.Uygulamadan şimdi çıkılacak. Elapsed Time: %1 h %2 m %3 s geçen zaman: %1 h %2 m %3 s Converting %1/%2 Converting the %1-th file in %2 files. %2 is the number of files. MediaConverter %1 not found. %1 is a computer program %1 bulunamadı. OptionsDialog Options Seçenekler General Check for updates on program startup Automatically start conversion after adding files to the list. Start conversion automatically FFmpeg FFmpeg Number of threads to use in conversion Dönüşümde kullanılacak iş parçacığı sayısı <html><head/><body><p>Hide output formats that are not available in the current ffmpeg installation. It is recommended to turn this option on unless you are sure that QWinFF has failed to detect available formats. (requires restarting QWinFF to take effect)</p></body></html> <html><head/><body><p>Geçerli ffmpeg kurulumunda bulunmayan çıkış biçimleri gizle. QWinFF kullanılabilir biçimleri algılamak için başarısız olduğuna emin olmadıkça bu seçeneği açmak için önerilir.(QWinFF etkili olması için yeniden başlatma gerektirir)</p></body></html> Hide unavailable formats (requires restarting) Kullanılamaz biçimleri gizle (yeniden başlatma gerektirir) Tools Araçlar You have to restart QWinFF for the changes to take effect. Değişikliklerin etkili olması için QWinFF yeniden başlatılmalıdır. Name Ad Command Komut PoweroffDialog QWinFF QWinFF Cancel İptal Shutdown immediately Shutdown the computer Hemen kapat Suspend immediately Suspend the computer (sleep to ram, standby) Hemen askıya al Hibernate immediately Hibernate the computer (sleep to disk, completely poweroff) Hemen hazırda beklet Shutdown Shutdown the computer Kapat Suspend Suspend the computer (sleep to ram, standby) Askıya al Hibernate Hibernate the computer (sleep to disk, completely poweroff) Hazırda beklet Operation Failed: %1 İşlem Başarısız: %1 Shutting down in <b>%1</b> seconds <b>%1</b> saniye içinde kapatılıyor Suspending in <b>%1</b> seconds <b>%1</b> saniye içinde askıya alınıyor Hibernating in <b>%1</b> seconds Hazırda beklet <b>%1</b> saniye içinde gerçekleşecek PreviewDialog Dialog Play Selected Range %1 not found Begin noun, the beginning of the video End noun, the end of the video Play %1~%2 play the video from time %1 to time %2. %1 and %2 are time in hh:mm:ss format. TimeRangeEdit From Begin Başından To End Sonuna UpdateDialog Show &Release Notes Check for updates on program startup Downloading update information... Cannot connect to server. Failed to parse the received data. You are already using the latest version of QWinFF. An unknown error has occurred. A new version of QWinFF has been released! Version <b>%1</b> is available at %2. %1 is version number, %2 is the project homepage You can download this version using the link: qwinff-master/src/translations/qwinff_zh_CN.ts000066400000000000000000001101561347323557400221150ustar00rootroot00000000000000 AboutDialog About QWinFF 关于QWinFF Information 资讯 Translators 翻译者 Version: %1 版本: %1 Portable 绿色版 Compiled with Qt %1 Qt 编译版本:%1 Compiled with libnotify %1 libnotify 編译版本: %1 QWinFF is a gui frontend for FFmpeg. FFmpeg影音转换器前端介面 Programming: %1 程式设计:%1 Logo Design: %1 Logo 设计:%1 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 or 3. 这个程序是自由软件,你可以在GNU授权条款(第二或第三版)下修改及散布此软件。 QWinFF Homepage: %1 QWinFF首页: %1 Some audio-processing functionalities are provided by SoX. 某些音效处理的功能由SoX提供. FFmpeg presets were taken from WinFF. FFmpeg的预设参数来自WinFF专案. Japanese Japanese Language 日文 Italian Italian Language 意大利文 Czech Czech Language 捷克語 Simplified Chinese Chinese character set used in China 简体中文 Russian Russian Language 俄语 Spanish (Spain) Spanish Language (Spain) 西班牙语 (西班牙) Spanish (Guatemala) Spanish Language (Guatemala) 西班牙语 (瓜地马拉) Romanian Romanian Language 罗马尼亚语 Turkish Turkish Language 土耳其文 Arabic Arabic Language 阿拉伯文 Hungarian Hungarian Langauge Polish Polish Language French French Language AboutFFmpegDialog About FFmpeg 关于FFmpeg FFmpeg FFmpeg Available Codecs 编/解码器 FFmpeg is a complete, cross-platform solution to record, convert and stream audio and video. It includes libavcodec - the leading audio/video codec library. ffmpeg description FFmpeg是一个集录制、转换、影音串流功能为一体的跨平台解决方案。它包含了强大的影音编码解码模组--libavcodec。 FFmpeg is free software licensed under the LGPL or GPL. FFmpeg是以LGPL及GPL发布的自由软件。 Please visit %1 for more information. 造访FFmpeg网站以获得更多资讯: %1 AddTaskWizard Add Tasks 新增任务 Files to be converted 要转换的文件 Add files. 新增文件 Remove selected files. 移除选择的文件 Output Settings 输出设置 Edit 编辑 Auto adjust output bitrate to reduce output file size. 自动调整输出比特率以减少输出文件大小 Auto Adjust Audio Bitrate 自动调整音频比特率 Preset 设定档 Convert to 转换成 Output Path 输出文件夹 Select &folder 选择文件夹(&F) Browse 浏览 Create &new folder in source folder Create a new folder (e.g. qwinff_output) in the folder containing the input files. Put the output files in the newly created folder. 在来源文件夹创建新的文件夹(&N) Folder Name 文件夹名称 Output to &source folder put the output files in the same folder as the input files 输出到来源文件夹(&S) Please select at least one file. 请至少选择一个文件 Select Files This text is the title of an openfile dialog. 选择文件 Multimedia 多媒体 Video 影片 Audio 声音 All files 所有文件 Select Directory This text is the title of an open directory dialog. 选择文件夹 Searching for files... Some files could not be found. 无法找到其中的一些文件 Folder does not exist. Create a new folder? 文件夹不存在。要建立新的文件夹嗎? Failed to create folder. Please select another output folder. 建立文件夹失败。请选择另一个输出文件夹。 ConversionParameterDialog Conversion Parameters 转换参数 Audio 声音 Disable Audio 禁止声音输出 Audio Options 声音选项 Sample Rate 取样率 Hz Hz Bitrate 比特率 (auto) 自动 kb/s kb/秒 Channels 声道 Volume 音量 % % Video 影像 Disable Video 禁止影像输出 Video Options 影像选项 Same Quantizer as Source 使用与来源相同的量化单位(Quantizer) Deinterlace 去交错 Width 宽度 px px Height 高度 Crop 裁切 Time time-related options (speed, length) 时间 Cutting video time cutting: options for begin time and end time 裁剪 Cut Cut video; select a range to convert &Preview 预览(&P) Scaling time scaling, changing the speed of the output file 改变长度 Speed 速度 Advanced 进阶 FFmpeg FFmpeg Additional FFmpeg Options 其他FFmpeg参数 ConvertList Cancel Cancel the operation of adding new tasks 取消 Adding files (%1/%2) This text is the progress indicator of adding multiple tasks. %1 is the number of files that are already added. %2 is the total number of files. 正在新增文件 (%1/%2) Some files are not recognized by the converter. 有一些文件无法识别 New File Name 新的文件名称 Please input the new name for the output file. 请输出新的文件名称 Output Directory 输出文件夹 Error Message from FFmpeg: FFmpeg的错误信息: Drag and drop files here to add tasks. 拖放文件到此以新增任务 Hide "%1" Hide a column in the list. For example, the text maybe 'Hide "Duration"'. The two " are quotation marks in English, you may replace it with local quotation marks. 隐藏 "%1" Restore All Columns 回复所有任务 Source 来源 Destination 输出 Duration 长度 File Size 文件大小 Sample Rate Audio 取样率 Audio Bitrate 声音比特率 Channels Audio 声道 Audio Codec 声音编码器 Dimensions 影像尺寸 Video Bitrate 影像比特率 Framerate Video 影格率 Video Codec 影像编码器 Progress 进度 %1 Hz %1 Hz %1 kb/s %1 kb/秒 %1 fps %1 帧/秒 Removing tasks... Remove files from the tasklist 正在移除任务 KiB KiB MiB MiB GiB GiB TiB TiB B Bytes B File Exists 文件已存在 %1 already exists on disk or in the task list. Still use this name as the output filename? %1 已经存在。确定还要用这个名称作为输出文件吗? Remove Task 移除任务 Cannot remove a task while it is in progress. 无法移除正在进行的任务 Finished The text to be displayed on the progress bar when a conversion finishes 已完成 Failed The text to be displayed on the progress bar when a conversion fails 失败 Error: %1 %1 is the error message 错误: %1 ExtraTranslations Convert between media file formats 转换影音文件格式 Media Converter 影音转换器 InteractiveCuttingDialog Cutting Cutting as in "cutting video" 裁剪 Mark as Begin Seek to Begin Play Selection Mark as End Seek to End %1 not found MainWindow QWinFF QWinFF Start conversion process. 开始转换 &Start 开始(&S) &File 文件(&F) &Convert 转换(&C) &About 关于(&A) &Edit 编辑(&E) &Add Files 加入文件(&A) Add files for conversion. 加入要转换的文件 Ctrl+N Ctrl+N E&xit 离开(&E) Exit the program. 离开此程式 F9 F9 S&top 停止(&T) Stop conversion process. 停止转换 Set &Parameters 设定转换参数(&P) Set Parameters Edit output file parameters. 设定转换参数 Edit conversion parameters of selected files. 编辑选择文件的转换参数 About &Qt 关于&Qt About Qt 关于Qt &Open Output Folder 打开输出文件夹(&O) Open output folder of the selected file. 开启已选文件的输出文件夹。 About &FFmpeg 关于&FFmpeg About FFmpeg 关于FFmpeg &Remove Selected remove selected (tasks, items) 移除选择的任务(&R) Remove all selected items in the list. 移除清单中所有选择的项目 R&emove Completed remove completed (task, items) 移除完成的任务(&e) Remove Completed Items 移除已完成的项目 Remove all completed items in the list. 移除清单中所有已完成的项目 &Clear List 清除清单(&C) Clear List 清除清单 Remove all items in the list. 移除清单中所有项目 &Retry 重试(&R) Retry 重试 Retry selected tasks. 重试选择的文件 Retry &All 全部重试(&A) Retry all tasks. 重试所有的任务 &Options 选项(&O) Options 选项 About Q&WinFF 关于Q&WinFF About This Program 关于这个程序 Change Output &Filename 修改输出文件名(&F) Change the output filename of the selected item. 修改选择文件的输出文件名称 Change Output &Directory 修改输出文件夹(&D) Change the output directory of the selected items. 修改选择文件的输出文件夹 Show Error &Message 显示错误信息(&M) Check For &Updates 检查更新(&U) Cut Cut video file (select a time range to conert) All tasks have finished. 所有的文件都已转换完成 Nothing to convert. 沒有要转换的文件 Conversion is still in progress. Abort? 文件还在转换中。確定要离开吗? Shutdown Shutdown the computer (completely poweroff) 关机 Shutdown when all tasks are done. 所有任务结束后关机 Suspend Suspend the computer (sleep to ram, standby) 待机 Suspend when all tasks are done. 所有任务结束后待机 Hibernate Hibernate the computer (sleep to disk, completely poweroff) 休眠 Hibernate when all tasks are done. 所有任务结束后休眠 This program is going to check for updates online. Do you allow this program to use the Internet to check for updates? 这个程序将检查在线更新。您要允许这个程序使用互联网检查更新吗? Failed to load preset file. The application will quit now. 无法载入设定档,程序将立刻结束。 Elapsed Time: %1 h %2 m %3 s 经过时间: %1 时 %2 分 %3 秒 Converting %1/%2 Converting the %1-th file in %2 files. %2 is the number of files. 正在转换 %1/%2 MediaConverter %1 not found. %1 is a computer program 找不到 %1. OptionsDialog Options 选项 General 常规 Check for updates on program startup 程序启动时检查更新 Automatically start conversion after adding files to the list. 将文件加入清单后自动开始转换 Start conversion automatically 自动开始转换 FFmpeg FFmpeg Number of threads to use in conversion 转换时使用的线程数 <html><head/><body><p>Hide output formats that are not available in the current ffmpeg installation. It is recommended to turn this option on unless you are sure that QWinFF has failed to detect available formats. (requires restarting QWinFF to take effect)</p></body></html> <html><head/><body><p>隐藏目前系统上的ffmpeg无法使用的输出格式. 建议开启此选项, 除非你确定 QWinFF 搞错了. (需要重启QWinFF)</p></body></html> Hide unavailable formats (requires restarting) 隐藏无法使用的格式 (需要重启) Tools 工具 You have to restart QWinFF for the changes to take effect. 需要重启 QWinFF 以使用新的设定. Name 名称 Command 命令 PoweroffDialog QWinFF QWinFF Cancel 取消 Shutdown immediately Shutdown the computer 立刻关机 Suspend immediately Suspend the computer (sleep to ram, standby) 立刻待机 Hibernate immediately Hibernate the computer (sleep to disk, completely poweroff) 立刻休眠 Shutdown Shutdown the computer 关机 Suspend Suspend the computer (sleep to ram, standby) 待机 Hibernate Hibernate the computer (sleep to disk, completely poweroff) 休眠 Operation Failed: %1 执行失败: %1 Shutting down in <b>%1</b> seconds 电脑将于 <b>%1</b> 秒后关机 Suspending in <b>%1</b> seconds 电脑将于 <b>%1</b> 秒后待机 Hibernating in <b>%1</b> seconds 电脑将于 <b>%1</b> 秒后休眠 PreviewDialog Dialog Play Selected Range %1 not found Begin noun, the beginning of the video End noun, the end of the video Play %1~%2 play the video from time %1 to time %2. %1 and %2 are time in hh:mm:ss format. TimeRangeEdit From Begin 从文件开头开始 To End 到文件结尾 UpdateDialog Show &Release Notes 显示发行说明(&R) Check for updates on program startup 程序启动时检查更新 Downloading update information... 正在下载更新信息... Cannot connect to server. 无法连接到服务器. Failed to parse the received data. 无法分析接收到的数据。 You are already using the latest version of QWinFF. 您已使用最新版本的 QWinFF。 An unknown error has occurred. 发生了不明的错误。 A new version of QWinFF has been released! 新版的 QWinFF 已发布! Version <b>%1</b> is available at %2. %1 is version number, %2 is the project homepage 版本 <b>%1</b> 可从 %2 取得. You can download this version using the link: 您可以从以下链接下载这个版本: qwinff-master/src/translations/qwinff_zh_TW.ts000066400000000000000000001077401347323557400221540ustar00rootroot00000000000000 AboutDialog About QWinFF 關於QWinFF Information 資訊 Translators 翻譯者 Version: %1 版本: %1 Portable 綠色版 Compiled with Qt %1 Qt 編譯版本:%1 Compiled with libnotify %1 libnotify 編譯版本: %1 QWinFF is a gui frontend for FFmpeg. FFmpeg影音轉檔器前端介面 Programming: %1 程式設計:%1 Logo Design: %1 Logo 設計:%1 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 or 3. 這個程式是自由軟體,你可以在GNU授權條款(第二或第三版)下修改及散佈此軟體。 QWinFF Homepage: %1 QWinFF首頁: %1 Some audio-processing functionalities are provided by SoX. 某些音效處理的功能由SoX提供. FFmpeg presets were taken from WinFF. FFmpeg的預設參數來自WinFF專案. Japanese Japanese Language 日文 Italian Italian Language 義大利文 Czech Czech Language 捷克語 Simplified Chinese Chinese character set used in China 簡體中文 Russian Russian Language 俄文 Spanish (Spain) Spanish Language (Spain) 西班牙語 (西班牙) Spanish (Guatemala) Spanish Language (Guatemala) 西班牙語 (瓜地馬拉) Romanian Romanian Language 羅馬尼亞語 Turkish Turkish Language 土耳其文 Arabic Arabic Language 阿拉伯文 Hungarian Hungarian Langauge 匈牙利語 Polish Polish Language 波蘭語 French French Language AboutFFmpegDialog About FFmpeg 關於FFmpeg FFmpeg FFmpeg Available Codecs 編/解碼器 FFmpeg is a complete, cross-platform solution to record, convert and stream audio and video. It includes libavcodec - the leading audio/video codec library. ffmpeg description FFmpeg是一個集錄製、轉換、影音串流功能為一體的跨平台解決方案。它包含了強大的影音編碼解碼模組--libavcodec。 FFmpeg is free software licensed under the LGPL or GPL. FFmpeg是以LGPL及GPL發佈的自由軟體。 Please visit %1 for more information. 造訪FFmpeg網站以獲得更多資訊: %1 AddTaskWizard Add Tasks 新增任務 Files to be converted 要轉換的檔案 Add files. 新增檔案 Remove selected files. 移除選取的檔案 Output Settings 輸出設定 Edit 編輯 Auto adjust output bitrate to reduce output file size. 自動調整輸出位元率以減少輸出檔案大小 Auto Adjust Audio Bitrate 自動調整聲音位元率 Preset 設定檔 Convert to 轉換成 Output Path 輸出資料夾 Select &folder 選擇資料夾(&F) Browse 瀏覽 Create &new folder in source folder Create a new folder (e.g. qwinff_output) in the folder containing the input files. Put the output files in the newly created folder. 建立新的資料夾(&N) Folder Name 資料夾名稱 Output to &source folder put the output files in the same folder as the input files 輸出到來源資料夾(&S) Please select at least one file. 請至少選擇一個檔案 Select Files This text is the title of an openfile dialog. 選擇檔案 Multimedia 多媒體 Video 影片 Audio 聲音 All files 所有檔案 Select Directory This text is the title of an open directory dialog. 選擇資料夾 Searching for files... 正在搜尋檔案... Some files could not be found. 無法找到其中的一些檔案 Folder does not exist. Create a new folder? 資料夾不存在。要建立新的資料夾嗎? Failed to create folder. Please select another output folder. 建立資料夾失敗。請選擇另一個輸出資料夾。 ConversionParameterDialog Conversion Parameters 轉換參數 Audio 聲音 Disable Audio 禁止聲音輸出 Audio Options 聲音選項 Sample Rate 取樣率 Hz Hz Bitrate 位元率 (auto) 自動 kb/s kb/s Channels 聲道 Volume 音量 % % Video 影像 Disable Video 禁止影像輸出 Video Options 影像選項 Same Quantizer as Source 與來源使用相同的量化單位(Quantizer) Deinterlace 去交錯 Width 寬度 px px Height 高度 Crop 裁切 Time time-related options (speed, length) 時間 Cutting video time cutting: options for begin time and end time 剪裁 Cut Cut video; select a range to convert 剪裁 &Preview 預覽(&P) Scaling time scaling, changing the speed of the output file 改變速度 Speed 速度 Advanced 進階 FFmpeg FFmpeg Additional FFmpeg Options 其他FFmpeg參數 ConvertList Cancel Cancel the operation of adding new tasks 取消 Adding files (%1/%2) This text is the progress indicator of adding multiple tasks. %1 is the number of files that are already added. %2 is the total number of files. 正在新增檔案 (%1/%2) Some files are not recognized by the converter. 有一些檔案無法辨識 New File Name 新的檔案名稱 Please input the new name for the output file. 請輸出新的檔案名稱 Output Directory 輸出資料夾 Error Message from FFmpeg: FFmpeg的錯誤訊息: Drag and drop files here to add tasks. 拖放檔案至此以新增任務 Hide "%1" Hide a column in the list. For example, the text maybe 'Hide "Duration"'. The two " are quotation marks in English, you may replace it with local quotation marks. 隱藏 "%1" Restore All Columns 回復所有欄位 Source 來源 Destination 輸出 Duration 長度 File Size 檔案大小 Sample Rate Audio 取樣率 Audio Bitrate 聲音位元率 Channels Audio 聲道 Audio Codec 聲音編碼器 Dimensions 影像尺寸 Video Bitrate 影像位元率 Framerate Video 影格率 Video Codec 影像編碼器 Progress 進度 %1 Hz %1 Hz %1 kb/s %1 kb/s %1 fps %1 畫格/秒 Removing tasks... Remove files from the tasklist 正在移除任務 KiB KiB MiB MiB GiB GiB TiB TiB B Bytes B File Exists 檔案已存在 %1 already exists on disk or in the task list. Still use this name as the output filename? %1 已經存在。確定還要用這個名稱作為輸出檔案嗎? Remove Task 移除任務 Cannot remove a task while it is in progress. 無法移除正在進行的任務 Finished The text to be displayed on the progress bar when a conversion finishes 已完成 Failed The text to be displayed on the progress bar when a conversion fails 失敗 Error: %1 %1 is the error message 錯誤: %1 ExtraTranslations Convert between media file formats 轉換影音檔案格式 Media Converter 影音轉檔器 InteractiveCuttingDialog Cutting Cutting as in "cutting video" 剪裁 Mark as Begin 標記為開始 Seek to Begin 快轉到開始 Play Selection 播放選擇區域 Mark as End 標記為結束 Seek to End 快轉到結束 %1 not found 找不到 %1 MainWindow QWinFF QWinFF Start conversion process. 開始轉換 &Start 開始(&S) &File 檔案(&F) &Convert 轉換(&C) &About 關於(&A) &Edit 編輯(&E) &Add Files 加入檔案(&A) Add files for conversion. 加入要轉換的檔案 Ctrl+N Ctrl+N E&xit 離開(&E) Exit the program. 離開此程式 F9 F9 S&top 停止(&T) Stop conversion process. 停止轉換 Set &Parameters 設定轉換參數(&P) Set Parameters Edit output file parameters. 設定轉換參數 Edit conversion parameters of selected files. 編輯選取檔案的轉換參數 About &Qt 關於&Qt About Qt 關於Qt &Open Output Folder 開啟輸出資料夾(&O) Open output folder of the selected file. 開啟已選檔案的輸出資料夾。 About &FFmpeg 關於&FFmpeg About FFmpeg 關於FFmpeg &Remove Selected remove selected (tasks, items) 移除選取的任務(&R) Remove all selected items in the list. 移除清單中所有選取的項目 R&emove Completed remove completed (task, items) 移除完成的任務(&e) Remove Completed Items 移除已完成的項目 Remove all completed items in the list. 移除清單中所有已完成的項目 &Clear List 清除清單(&C) Clear List 清除清單 Remove all items in the list. 移除清單中所有項目 &Retry 重試(&R) Retry 重試 Retry selected tasks. 重試選取的檔案 Retry &All 全部重試(&A) Retry all tasks. 重試所有的任務 &Options 選項(&O) Options 選項 About Q&WinFF 關於Q&WinFF About This Program 關於這個程式 Change Output &Filename 修改輸出檔名(&F) Change the output filename of the selected item. 修改選取檔案的輸出檔案名稱 Change Output &Directory 修改輸出資料夾(&D) Change the output directory of the selected items. 修改選取檔案的輸出資料夾 Show Error &Message 顯示錯誤訊息(&M) Check For &Updates 檢查更新(&U) Cut Cut video file (select a time range to conert) 剪裁 All tasks have finished. 所有檔案都已轉換完成 Nothing to convert. 沒有要轉換的檔案 Conversion is still in progress. Abort? 檔案還在轉換中。確定要離開嗎? Shutdown Shutdown the computer (completely poweroff) 關機 Shutdown when all tasks are done. 所有任務結束後關機 Suspend Suspend the computer (sleep to ram, standby) 待機 Suspend when all tasks are done. 所有任務結束後待機 Hibernate Hibernate the computer (sleep to disk, completely poweroff) 休眠 Hibernate when all tasks are done. 所有任務結束後休眠 This program is going to check for updates online. Do you allow this program to use the Internet to check for updates? 此程式將檢查線上更新。您要允許這個程式透過網路檢查更新嗎? Failed to load preset file. The application will quit now. 無法載入設定檔,程式將立刻結束。 Elapsed Time: %1 h %2 m %3 s 經過時間: %1 時 %2 分 %3 秒 Converting %1/%2 Converting the %1-th file in %2 files. %2 is the number of files. 正在轉換 %1/%2 MediaConverter %1 not found. %1 is a computer program 找不到 %1. OptionsDialog Options 選項 General 一般 Check for updates on program startup 程式啟動時檢查更新 Automatically start conversion after adding files to the list. 將檔案加入清單後自動開始轉換 Start conversion automatically 自動開始轉換 FFmpeg FFmpeg Number of threads to use in conversion 轉換時使用的線程數 <html><head/><body><p>Hide output formats that are not available in the current ffmpeg installation. It is recommended to turn this option on unless you are sure that QWinFF has failed to detect available formats. (requires restarting QWinFF to take effect)</p></body></html> <html><head/><body><p>隱藏目前系統上的ffmpeg無法使用的輸出格式. 建議開啟此選項, 除非你確定 QWinFF 搞錯了. (需要重啟QWinFF)</p></body></html> Hide unavailable formats (requires restarting) 隱藏無法使用的格式 (需要重啟) Tools 工具 You have to restart QWinFF for the changes to take effect. 需要重啟 QWinFF 以套用設定. Name 名稱 Command 指令 PoweroffDialog QWinFF QWinFF Cancel 取消 Shutdown immediately Shutdown the computer 立刻關機 Suspend immediately Suspend the computer (sleep to ram, standby) 立刻待機 Hibernate immediately Hibernate the computer (sleep to disk, completely poweroff) 立刻休眠 Shutdown Shutdown the computer 關機 Suspend Suspend the computer (sleep to ram, standby) 待機 Hibernate Hibernate the computer (sleep to disk, completely poweroff) 休眠 Operation Failed: %1 執行失敗: %1 Shutting down in <b>%1</b> seconds 電腦將於 <b>%1</b> 秒後關機 Suspending in <b>%1</b> seconds 電腦將於 <b>%1</b> 秒後待機 Hibernating in <b>%1</b> seconds 電腦將於 <b>%1</b> 秒後休眠 PreviewDialog Dialog 對話框 Play Selected Range 播放選擇範圍 %1 not found 找不到 %1 Begin noun, the beginning of the video 開始 End noun, the end of the video 結束 Play %1~%2 play the video from time %1 to time %2. %1 and %2 are time in hh:mm:ss format. 播放 %1~%2 TimeRangeEdit From Begin 從檔案開頭開始 To End 到檔案結尾 UpdateDialog Show &Release Notes 顯示發行備註(&R) Check for updates on program startup 程式啟動時檢查更新 Downloading update information... 正在下載更新資訊... Cannot connect to server. 無法連線到伺服器. Failed to parse the received data. 無法分析取得的資料. You are already using the latest version of QWinFF. 您已經使用了最新版本的 QWinFF. An unknown error has occurred. 發生了未知的錯誤. A new version of QWinFF has been released! 已有 QWinFF 的更新! Version <b>%1</b> is available at %2. %1 is version number, %2 is the project homepage 版本 <b>%1</b> 可從 %2 下載. You can download this version using the link: 您可以從以下連結下載這個版本: qwinff-master/src/ui/000077500000000000000000000000001347323557400150625ustar00rootroot00000000000000qwinff-master/src/ui/aboutdialog.cpp000066400000000000000000000151441347323557400200650ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include #include #include "aboutdialog.h" #include "ui_aboutdialog.h" #include "version.h" #include "services/constants.h" #ifdef USE_LIBNOTIFY #include "services/notificationservice-libnotify.h" #endif #define PROJECT_HOMEPAGE "http://qwinff.github.io" namespace { QString url(QString lnk) { return QString("%1").arg(lnk); } } AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDialog) { ui->setupUi(this); QTextBrowser *info = ui->txtInfo; QTextBrowser *translators = ui->txtTranslators; info->setOpenExternalLinks(true); info->setText( "QWinFF © 2011 Timothy Lin <lzh9102@gmail.com>
" + tr("Version: %1").arg(VERSION_STRING) #ifdef VERSION_ID_STRING + QString(" %1").arg(QString(VERSION_ID_STRING)) #endif + " " + ((Constants::getBool("Portable")) /*: Portable version (no installation, no writing registry) */ ? tr("Portable") : "") + "
" /*: Qt version */ + tr("Compiled with Qt %1").arg(QT_VERSION_STR) #ifdef USE_LIBNOTIFY /*: libnotify version */ + "
" + tr("Compiled with libnotify %1") .arg(NotificationService_libnotify::getVersion()) #endif + "

" + tr("QWinFF is a gui frontend for FFmpeg.") + "

" //: %1 is the name and email of the programmer + tr("Programming: %1").arg("Timothy Lin <lzh9102@gmail.com>") + "
" //: %1 is the name and email of the logo designer + tr("Logo Design: %1").arg("kuanyui <azazabc123@gmail.com>") + "

" + tr("This program is free software; you can redistribute it and/or modify it " "under the terms of the GNU General Public License version 2 or 3.") + "

" + tr("QWinFF Homepage: %1").arg(url(PROJECT_HOMEPAGE)) + "

" + tr("Some audio-processing functionalities are provided by SoX.") + " (" + url("http://sox.sourceforge.net/") + ")

" + tr("FFmpeg presets were taken from WinFF.") + "

" ); translators->setHtml(getTranslators()); //translators->setText(getTranslators()); // Constraint the width of text area to the width of the banner. //info->setMaximumWidth(ui->lblBanner->pixmap()->width()); // Set the background color of the textbox to the color of the window. QPalette p = info->palette(); p.setColor(QPalette::Base, this->palette().color(QPalette::Window)); info->setPalette(p); info->setFrameShape(QTextBrowser::NoFrame); // Hide textbox border. translators->setPalette(p); translators->setFrameShape(QTextBrowser::NoFrame); // Make the window size fixed. this->adjustSize(); this->setMinimumWidth(this->width()); this->setMinimumHeight(this->height()); this->setMaximumWidth(this->width()); this->setMaximumHeight(this->height()); ui->tabInfo->setAutoFillBackground(true); ui->tabTranslators->setAutoFillBackground(true); } AboutDialog::~AboutDialog() { delete ui; } QString AboutDialog::getTranslators() { struct {QString locale; QString translator;} table[] = { //: Japanese Language {"ja_JP",trad(tr("Japanese"), "Tilt ")}, //: Italian Language {"it_IT",trad(tr("Italian"), QStringList() << "TheJoe (http://thejoe.it/)" << "Francesco Marinucci ")}, //: French Language {"fr_FR", trad(tr("French") , "Thomas Debesse ")}, //: Czech Language {"cs_CZ", trad(tr("Czech"), "Petr Gaďorek ")}, //: Chinese character set used in China {"zh_CN", trad(tr("Simplified Chinese") , "杨永明 ")}, //: Russian Language {"ru", trad(tr("Russian") , "Stanislav Hanzhin ")}, //: Spanish Language (Spain) {"es_ES", trad(tr("Spanish (Spain)") , "Ermides González ")}, //: Spanish Language (Guatemala) {"es_GT", trad(tr("Spanish (Guatemala)") , "Ermides González ")}, //: Romanian Language {"ro_RO", trad(tr("Romanian") , "SymbianFlo ")}, //: Turkish Language {"tr_TR", trad(tr("Turkish") , "Mustafa Kılıç")}, //: Arabic Language {"ar", trad(tr("Arabic") , "Mohammed Ali")}, //: Hungarian Langauge {"hu_HU", trad(tr("Hungarian") , "András Földi")}, //: Polish Language {"pl_PL", trad(tr("Polish") , "Toratora")}, }; const int size = sizeof(table) / sizeof(table[0]); QStringList translators; QString current_locale = QLocale::system().name(); for (int i=0; i", ">") + ""; } s+= ""; return QString("%1: %2").arg(lang).arg(s); } qwinff-master/src/ui/aboutdialog.h000066400000000000000000000023071347323557400175270ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef ABOUTDIALOG_H #define ABOUTDIALOG_H #include namespace Ui { class AboutDialog; } class AboutDialog : public QDialog { Q_OBJECT public: explicit AboutDialog(QWidget *parent = 0); ~AboutDialog(); private: Ui::AboutDialog *ui; QString getTranslators(); QString trad(const QString& lang, const QString& author); QString trad(const QString & lang, const QStringList & authors); }; #endif // ABOUTDIALOG_H qwinff-master/src/ui/aboutdialog.ui000066400000000000000000000051501347323557400177140ustar00rootroot00000000000000 AboutDialog 0 0 426 339 About QWinFF 0 :/app/icons/banner.png QTabWidget::South 0 Information Translators Qt::Horizontal QDialogButtonBox::Ok buttonBox accepted() AboutDialog accept() 248 254 157 274 buttonBox rejected() AboutDialog reject() 316 260 286 274 qwinff-master/src/ui/aboutffmpegdialog.cpp000066400000000000000000000043521347323557400212510ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "aboutffmpegdialog.h" #include "ui_aboutffmpegdialog.h" #include "converter/ffmpeginterface.h" AboutFFmpegDialog::AboutFFmpegDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutFFmpegDialog) { ui->setupUi(this); QTextBrowser *info = ui->txtInfo; QTextBrowser *codecinfo = ui->txtCodecInfo; info->setText( /*: ffmpeg description */ tr("FFmpeg is a complete, cross-platform solution to record, " "convert and stream audio and video. It includes " "libavcodec - the leading audio/video codec library.") + "

" + tr("FFmpeg is free software licensed under the LGPL or GPL.") + "

" /*: visit ffmpeg website */ + tr("Please visit %1 for more information.") .arg("http://ffmpeg.org") + "

" + FFmpegInterface::getFFmpegVersionInfo().replace("\n", "
") ); info->setOpenExternalLinks(true); info->setFrameShape(QTextBrowser::NoFrame); codecinfo->setFrameShape(QTextBrowser::NoFrame); ui->tabFFmpeg->setAutoFillBackground(true); ui->tabCodecs->setAutoFillBackground(true); QPalette p = info->palette(); p.setColor(QPalette::Base, ui->tabFFmpeg->palette().color(QPalette::Window)); info->setPalette(p); codecinfo->setPalette(p); codecinfo->setText(FFmpegInterface::getFFmpegCodecInfo()); } AboutFFmpegDialog::~AboutFFmpegDialog() { delete ui; } qwinff-master/src/ui/aboutffmpegdialog.h000066400000000000000000000021261347323557400207130ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef ABOUTFFMPEGDIALOG_H #define ABOUTFFMPEGDIALOG_H #include namespace Ui { class AboutFFmpegDialog; } class AboutFFmpegDialog : public QDialog { Q_OBJECT public: explicit AboutFFmpegDialog(QWidget *parent = 0); ~AboutFFmpegDialog(); private: Ui::AboutFFmpegDialog *ui; }; #endif // ABOUTFFMPEGDIALOG_H qwinff-master/src/ui/aboutffmpegdialog.ui000066400000000000000000000077211347323557400211070ustar00rootroot00000000000000 AboutFFmpegDialog 0 0 551 379 Qt::NoContextMenu About FFmpeg :/app/icons/ffmpeg.png:/app/icons/ffmpeg.png 0 FFmpeg 0 0 128 128 :/app/icons/ffmpeg_large.png true Qt::Vertical 20 40 0 0 Available Codecs Qt::Horizontal QDialogButtonBox::Ok buttonBox accepted() AboutFFmpegDialog accept() 248 254 157 274 buttonBox rejected() AboutFFmpegDialog reject() 316 260 286 274 qwinff-master/src/ui/addtaskwizard.cpp000066400000000000000000000434431347323557400204320ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "addtaskwizard.h" #include "ui_addtaskwizard.h" #include "converter/presets.h" #include "conversionparameterdialog.h" #include "services/extensions.h" #include "services/paths.h" #include "services/constants.h" #include #include #include #include #include #include #define DEFAULT_OUTPUT_TO_SOURCE_DIR Constants::getBool("OutputToSourceFolder") #define PAGEID_SELECTFILES 0 #define PAGEID_PARAMS 1 #define BUSY_INDICATOR_MINIMUM_DURATION 100 enum OutputPathType { SelectFolder, NewFolder, SourceFolder }; AddTaskWizard::AddTaskWizard(Presets *presets, QWidget *parent) : QWizard(parent), ui(new Ui::AddTaskWizard), m_presets(presets), m_current_param(new ConversionParameters), m_exts(new Extensions()) { ui->setupUi(this); // setup signals/slots connect(ui->btnAdd, SIGNAL(clicked()) , this, SLOT(slotAddFilesToList())); connect(ui->btnRemove, SIGNAL(clicked()) , this, SLOT(slotRemoveFilesFromList())); connect(ui->cbExtension, SIGNAL(currentIndexChanged(int)) , this, SLOT(slotExtensionSelected(int))); connect(ui->cbPreset, SIGNAL(currentIndexChanged(int)) , this, SLOT(slotPresetSelected(int))); connect(ui->btnEditPreset, SIGNAL(clicked()) , this, SLOT(slotEditPresetButton())); connect(ui->btnBrowseOutputPath, SIGNAL(clicked()) , this, SLOT(slotBrowseOutputPathButton())); connect(this, SIGNAL(accepted()) , this, SLOT(slotFinished())); connect(ui->rbSelectFolder, SIGNAL(toggled(bool)) , ui->cbOutputPath, SLOT(setEnabled(bool))); connect(ui->rbSelectFolder, SIGNAL(toggled(bool)) , ui->btnBrowseOutputPath, SLOT(setEnabled(bool))); connect(ui->rbNewFolder, SIGNAL(toggled(bool)) , ui->txtNewFolderName, SLOT(setEnabled(bool))); ui->rbSelectFolder->setChecked(true); // trigger toggled() event ui->rbNewFolder->setChecked(true); // trigger toggled() event ui->rbSourceFolder->setChecked(true); // trigger toggled() event ui->lstFiles->setSelectionMode(QAbstractItemView::ExtendedSelection); load_extensions(); ui->cbOutputPath->setEditable(true); load_settings(); QSettings settings; // Load Geometry restoreGeometry(settings.value("addtaskwizard/geometry").toByteArray()); // Hide "auto adjust bitrate" checkbox. ui->chkAutoAdjustBitrate->setVisible(false); } AddTaskWizard::~AddTaskWizard() { QSettings settings; // Save Geometry settings.setValue("addtaskwizard/geometry", saveGeometry()); delete ui; delete m_current_param; delete m_exts; } const QList& AddTaskWizard::getConversionParameters() const { return m_params; } int AddTaskWizard::exec_openfile() { ui->lstFiles->clear(); if (startId() == PAGEID_SELECTFILES) { // popup select file dialog slotAddFilesToList(); if (ui->lstFiles->count() == 0) return QWizard::Rejected; } return QWizard::exec(); } int AddTaskWizard::exec(const QStringList &files) { ui->lstFiles->clear(); addFiles(files); return QWizard::exec(); } bool AddTaskWizard::validateCurrentPage() { switch (currentId()) { case 0: // Select input files // check if the list is empty if (ui->lstFiles->count() != 0) { // complete return true; } else { QMessageBox::information(this, this->windowTitle() , tr("Please select at least one file.")); return false; } break; case 1: // Select conversion parameters if (get_output_path_type() == SelectFolder) { if (!create_directory(ui->cbOutputPath->currentText())) return false; } else if (get_output_path_type() == NewFolder) { for (int i=0; ilstFiles->count(); i++) { QString input_file = ui->lstFiles->item(i)->text(); QString output_path = get_output_path(input_file); if (!create_directory(output_path, /* do not confirm */ false)) return false; } } return true; break; } return true; } void AddTaskWizard::slotAddFilesToList() { /*: This text is the title of an openfile dialog. */ QStringList files = QFileDialog::getOpenFileNames(this, tr("Select Files"), m_prev_path, // default path tr("Multimedia") + m_exts->multimedia().forFilter() + ";;" + tr("Video") + m_exts->video().forFilter() + ";;" + tr("Audio") + m_exts->audio().forFilter() + ";;" + tr("All files") + "(*)" ); if (!files.isEmpty()) { addFiles(files); // Save open file path. m_prev_path = QFileInfo(files[0]).path(); // save previous open path QSettings settings; settings.setValue("addtaskwizard/openfilepath", m_prev_path); } else { // no file selected } } void AddTaskWizard::slotRemoveFilesFromList() { QList itemList = ui->lstFiles->selectedItems(); foreach (QListWidgetItem *item, itemList) { ui->lstFiles->takeItem(ui->lstFiles->row(item)); } } void AddTaskWizard::slotEditPresetButton() { ConversionParameterDialog dialog(this); bool singleFile = (ui->lstFiles->count() == 1); ConversionParameters param = *m_current_param; dialog.setGeometry(this->x(), this->y(), dialog.width(), dialog.height()); if (singleFile) { param.source = ui->lstFiles->item(0)->text(); } if (dialog.exec(param, singleFile)) { m_current_param->copyConfigurationFrom(param); m_cbpreset_index = ui->cbPreset->currentIndex(); ui->cbPreset->setCurrentIndex(-1); // select no item } } void AddTaskWizard::slotBrowseOutputPathButton() { /*: This text is the title of an open directory dialog. */ QString selected_path = QFileDialog::getExistingDirectory(this, tr("Select Directory") , ui->cbOutputPath->currentText()); if (!selected_path.isEmpty()) ui->cbOutputPath->setEditText(selected_path); } // When the user selects an extension, insert all possible presets // into the preset combobox. void AddTaskWizard::slotExtensionSelected(int ext_index) { if (ext_index == -1) return; QString extension = ui->cbExtension->itemData(ext_index).toString(); QList presetList; ui->cbPreset->clear(); if (m_presets->getPresets(extension, presetList)) { qSort(presetList); // Sort the presets by the order in the xml file. foreach (Preset preset, presetList) { ui->cbPreset->addItem(preset.label, preset.id); } } // Restore the last used preset of the extension. if (ext_index >= 0 && ext_index < m_ext_preset.size()) { // index in the preset combobox int index = m_ext_preset[ext_index].toInt(); if (index >= 0 && index < ui->cbPreset->count()) ui->cbPreset->setCurrentIndex(index); else ui->cbPreset->setCurrentIndex(0); } } void AddTaskWizard::slotPresetSelected(int index) { if (index == -1) return; int id = ui->cbPreset->itemData(index).toUInt(); Preset preset; if (!m_presets->findPresetById(id, preset)) { return; // assert false } *m_current_param = ConversionParameters::fromFFmpegParameters(preset.parameters); } // This function is executed when the users presses "Finish" void AddTaskWizard::slotFinished() { const int size = ui->lstFiles->count(); m_params.clear(); // The variable "param" is reused in the loop. ConversionParameters param(*m_current_param); const int ext_index = ui->cbExtension->currentIndex(); const QString ext = ui->cbExtension->itemData(ext_index).toString(); // Write conversion parameters to m_params. for (int i=0; ilstFiles->item(i)->text(); QString input_file_basename = QFileInfo(input_filename).completeBaseName(); QDir output_dir(get_output_path(input_filename)); // Fill in input and output filenames // IMPORTANT: Only "source" and "destination" should be modified in the loop. param.source = input_filename; param.destination = output_dir.absoluteFilePath(input_file_basename + "." + ext); // Save the configuration for the file. m_params.append(param); } save_settings(); } void AddTaskWizard::addFiles(const QStringList &files) { // create a busy-indicator dialog QProgressDialog dlgProgress(this); dlgProgress.setRange(0, 0); // no min/max values, work as busy-indicator dlgProgress.setWindowModality(Qt::WindowModal); dlgProgress.setMinimumDuration(BUSY_INDICATOR_MINIMUM_DURATION); dlgProgress.setAutoClose(false); // don't close when value reaches 0 dlgProgress.setLabelText(tr("Searching for files...")); dlgProgress.show(); // add files to the list QStringList incorrect_files; // Record files that are not valid for conversion. foreach (QString file, files) { recursively_add_file(file, incorrect_files, dlgProgress); } dlgProgress.hide(); // show error message if a file could not be found if (!incorrect_files.isEmpty()) { QMessageBox msgBox; msgBox.setText(tr("Some files could not be found.")); msgBox.setDetailedText(incorrect_files.join("\n")); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setIcon(QMessageBox::Warning); msgBox.exec(); } } bool AddTaskWizard::load_extensions() { // update extension combo bar QList extensions; m_presets->getExtensions(extensions); ui->cbExtension->clear(); foreach (QString ext, extensions) { ui->cbExtension->addItem(ext.toUpper(), QVariant(ext)); } return true; } void AddTaskWizard::load_settings() { QSettings settings; // extension combobox int ext_index = settings.value("addtaskwizard/extension").toInt(); if (ext_index < 0 || ext_index >= ui->cbExtension->count()) ext_index = 0; ui->cbExtension->setCurrentIndex(ext_index); m_ext_preset = settings.value("addtaskwizard/selected_presets").toList().toVector(); m_ext_preset.resize(ui->cbExtension->count()); //ui->chkAutoAdjustBitrate->setChecked( // settings.value("addtaskwizard/auto_audio_bitrate", false).toBool()); ui->chkAutoAdjustBitrate->setChecked(false); if (ext_index >= 0 && ext_index < m_ext_preset.size()) { // preset combobox QApplication::processEvents(); int preset_index = m_ext_preset[ext_index].toInt(); if (preset_index < 0 || preset_index >= ui->cbPreset->count()) preset_index = 0; ui->cbPreset->setCurrentIndex(preset_index); } // open file dialog default path m_prev_path = settings.value("addtaskwizard/openfilepath" , QDir::homePath()).toString(); // Load recent output paths. QStringList recent_paths = settings.value("addtaskwizard/recentpaths").toStringList(); ui->cbOutputPath->clear(); ui->cbOutputPath->addItems(recent_paths); if (ui->cbOutputPath->count() == 0) { ui->cbOutputPath->addItem(QDir::homePath()); } ui->cbOutputPath->setCurrentIndex(0); // Select the most recent path. const int output_path_type = settings.value("addtaskwizard/output_path_type").toInt(); set_output_path_type(output_path_type); const QString new_folder_name = settings.value( "addtaskwizard/new_folder_name", Constants::getString("NewFolderName")).toString(); ui->txtNewFolderName->setText(new_folder_name); } void AddTaskWizard::save_settings() { QSettings settings; settings.setValue("addtaskwizard/extension", ui->cbExtension->currentIndex()); const int ext_index = ui->cbExtension->currentIndex(); int preset_index = ui->cbPreset->currentIndex(); if (preset_index < 0) // The user has edited the preset, so no preset is selected. preset_index = m_cbpreset_index; // Save the last selected preset instead. if (ext_index >= 0 && ext_index < m_ext_preset.size()) m_ext_preset[ext_index] = preset_index; //settings.setValue("addtaskwizard/auto_audio_bitrate", ui->chkAutoAdjustBitrate->isChecked()); // the last used preset of each extension settings.setValue("addtaskwizard/selected_presets", m_ext_preset.toList()); // Save recent output paths QStringList recent_paths; recent_paths.push_back(ui->cbOutputPath->currentText()); // Save current text. for (int i=0; icbOutputPath->count(); i++) { QString path = ui->cbOutputPath->itemText(i); if (recent_paths.indexOf(path) == -1) // avoid duplicate items recent_paths.push_back(ui->cbOutputPath->itemText(i)); } const int num_recent_paths = Constants::getInteger("NumRecentPaths"); if (recent_paths.size() > num_recent_paths) { // Make the list contain at most num_recent_paths items. recent_paths = recent_paths.mid(0, num_recent_paths); } settings.setValue("addtaskwizard/recentpaths", recent_paths); settings.setValue("addtaskwizard/output_path_type", get_output_path_type()); settings.setValue("addtaskwizard/new_folder_name", ui->txtNewFolderName->text()); } void AddTaskWizard::set_output_path_type(int n) { switch (n) { case SelectFolder: ui->rbSelectFolder->setChecked(true); break; case NewFolder: ui->rbNewFolder->setChecked(true); break; case SourceFolder: ui->rbSourceFolder->setChecked(true); break; default: Q_ASSERT(false); } } int AddTaskWizard::get_output_path_type() { if (ui->rbNewFolder->isChecked()) return NewFolder; if (ui->rbSourceFolder->isChecked()) return SourceFolder; else return SelectFolder; } QString AddTaskWizard::get_output_path(const QString &input_filename) { QString input_folder_name(QFileInfo(input_filename).absolutePath()); QDir input_folder(input_folder_name); switch (get_output_path_type()) { case SelectFolder: return ui->cbOutputPath->currentText(); case NewFolder: return input_folder.absoluteFilePath(ui->txtNewFolderName->text()); case SourceFolder: return input_folder.absoluteFilePath(input_folder_name); default: Q_ASSERT(false); } return ""; } bool AddTaskWizard::create_directory(const QString &dir, bool confirm) { // check if output directory exists QDir output_dir(dir); if (output_dir.exists()) { return true; } else { // The folder doesn't exist. // Prompt the user to create new folder. QMessageBox::StandardButton reply; if (confirm) reply = QMessageBox::warning(this, this->windowTitle() , tr("Folder does not exist. Create a new folder?") , QMessageBox::Yes | QMessageBox::No); else reply = QMessageBox::Yes; if (reply == QMessageBox::Yes) { // The user chooses to create folder. qDebug() << "Try to create folder " << output_dir.path(); bool succeed = QDir().mkpath(output_dir.path()); if (!succeed) { // failed to create folder QMessageBox::critical(this, this->windowTitle() , tr("Failed to create folder. " "Please select another output folder.") , QMessageBox::Ok); } return succeed; } else { return false; } } } void AddTaskWizard::recursively_add_file( const QString &file, // input QStringList &incorrect_files, // output QProgressDialog &dlgProgress, int depth) { // ignore extensions that are not known as media files when doing // recursive search bool ignore_unknown_extensions = (depth > 0); QFileInfo fileinfo(file); if (fileinfo.isFile()) { // file if (ignore_unknown_extensions && !m_exts->contains(fileinfo.suffix())) return; // ignore unknown extensions QListWidgetItem *item = new QListWidgetItem(file); item->setToolTip(file); ui->lstFiles->addItem(item); } else if (fileinfo.isDir()) { // directory QDir dir(file); QStringList children = list_directory(dir); foreach (QString child, children) { // traverse directory // check for cancel events prior to recursion QApplication::processEvents(); if (dlgProgress.wasCanceled()) return; recursively_add_file(dir.absoluteFilePath(child), incorrect_files, dlgProgress, depth+1); } } else { incorrect_files.append(file); } } QStringList AddTaskWizard::list_directory(const QDir &dir) { QDir::Filters filters = QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot; return dir.entryList(filters); } qwinff-master/src/ui/addtaskwizard.h000066400000000000000000000056121347323557400200730ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef ADDTASKWIZARD_H #define ADDTASKWIZARD_H #include namespace Ui { class AddTaskWizard; } QT_BEGIN_NAMESPACE class QDir; class QProgressDialog; QT_END_NAMESPACE class Extensions; class Presets; class ConversionParameters; class ConversionParameterDialog; class AddTaskWizard : public QWizard { Q_OBJECT public: explicit AddTaskWizard(Presets *presets, QWidget *parent = 0); ~AddTaskWizard(); /*! Returns conversion parameters for all files * including input/output filenames. */ const QList& getConversionParameters() const; /*! Popup open file dialog on the file selection page. */ int exec_openfile(); /*! Fill in the files and execute the wizard. * The wizard will skip the file-selecting page. * @param files files to convert */ int exec(const QStringList& files); protected: bool validateCurrentPage(); private slots: void slotAddFilesToList(); void slotRemoveFilesFromList(); void slotEditPresetButton(); void slotBrowseOutputPathButton(); void slotExtensionSelected(int); void slotPresetSelected(int); void slotFinished(); void addFiles(const QStringList& files); private: Ui::AddTaskWizard *ui; QString m_prev_path; //!< the most recently opened path of the file dialog. Presets *m_presets; QList m_params; ConversionParameters *m_current_param; QVector m_ext_preset; //!< the mapping between extension and the last selected preset. int m_cbpreset_index; //!< saves the index of the preset combobox Extensions *m_exts; //!< media file extensions bool load_extensions(); void load_settings(); void save_settings(); void set_output_path_type(int n); int get_output_path_type(); QString get_output_path(const QString& input_filename); bool create_directory(const QString& dir, bool confirm=true); void recursively_add_file(const QString& file, QStringList& incorrect_files, QProgressDialog& dlgProgress, int depth=0); QStringList list_directory(const QDir &dir); }; #endif // ADDTASKWIZARD_H qwinff-master/src/ui/addtaskwizard.ui000066400000000000000000000224211347323557400202560ustar00rootroot00000000000000 AddTaskWizard 0 0 577 428 Add Tasks 75 true Files to be converted QAbstractItemView::ExtendedSelection Add files. :/actions/icons/add.png:/actions/icons/add.png 16 16 Remove selected files. :/actions/icons/remove.png:/actions/icons/remove.png Qt::Vertical 20 40 75 true Output Settings 0 0 Edit :/actions/icons/edit_preset.png:/actions/icons/edit_preset.png 0 0 Auto adjust output bitrate to reduce output file size. Auto Adjust Audio Bitrate Preset 0 0 Convert to Output Path Select &folder Qt::Horizontal QSizePolicy::Minimum 40 20 0 0 Browse Create &new folder in source folder Qt::Horizontal QSizePolicy::Minimum 40 20 Folder Name Qt::Horizontal QSizePolicy::Minimum 40 20 Output to &source folder cbExtension cbPreset btnEditPreset chkAutoAdjustBitrate btnAdd btnRemove lstFiles qwinff-master/src/ui/conversionparameterdialog.cpp000066400000000000000000000235071347323557400230430ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "conversionparameterdialog.h" #include "converter/audiofilter.h" #include "converter/mediaprobe.h" #include "services/ffplaypreviewer.h" #include "services/mplayerpreviewer.h" #include "rangewidgetbinder.h" #include "rangeselector.h" #include "timerangeedit.h" #include "interactivecuttingdialog.h" #include "previewdialog.h" #include "ui_conversionparameterdialog.h" #include #include #define TO_BYTEPERCENT(percent) ((percent) * 256 / 100) #define TO_PERCENT(bytepercent) ((bytepercent) * 100 / 256) #define DEFAULT_AUDIO_BITRATE 64 #define DEFAULT_VIDEO_BITRATE 200 #define DEFAULT_AUDIO_CHANNELS 2 ConversionParameterDialog::ConversionParameterDialog(QWidget *parent) : QDialog(parent), ui(new Ui::ConversionParameterDialog), m_timeEdit(new TimeRangeEdit(this)), m_rangeSel(new RangeSelector(this)), m_previewer(0) { ui->setupUi(this); // bind visual range selection and range edit (auto sync between them) new RangeWidgetBinder(m_rangeSel, m_timeEdit, this); ui->layoutTimeSel->addWidget(m_rangeSel); ui->layoutTimeSel->addWidget(m_timeEdit); // Setup audio sample rate selection ui->cbAudioSampleRate->addItem("44100"); ui->cbAudioSampleRate->addItem("22050"); ui->cbAudioSampleRate->addItem("11025"); connect(ui->btnPreview, SIGNAL(clicked()), this, SLOT(preview_time_selection())); connect(ui->btnInteractiveCutting, SIGNAL(clicked()), SLOT(interactive_cutting())); connect(ui->chkDisableAudio, SIGNAL(toggled(bool)), SLOT(audio_tab_update_enabled_widgets())); connect(ui->chkCopyAudio, SIGNAL(toggled(bool)), SLOT(audio_tab_update_enabled_widgets())); connect(ui->chkDisableVideo, SIGNAL(toggled(bool)), SLOT(video_tab_update_enabled_widgets())); connect(ui->chkCopyVideo, SIGNAL(toggled(bool)), SLOT(video_tab_update_enabled_widgets())); // Hide speed-changing options if sox is not available. m_enableAudioProcessing = AudioFilter::available(); if (!m_enableAudioProcessing) ui->groupScaling->setVisible(false); m_previewer = create_previewer(); } ConversionParameterDialog::~ConversionParameterDialog() { delete ui; } bool ConversionParameterDialog::exec(ConversionParameters& param, bool single_file) { m_singleFile = single_file; m_param = ¶m; read_fields(param); bool accepted = (QDialog::exec() == QDialog::Accepted); if (accepted) { write_fields(param); } return accepted; } void ConversionParameterDialog::preview_time_selection() { if (PreviewDialog::available()) { PreviewDialog(this).exec(m_param->source, m_timeEdit->fromBegin(), m_timeEdit->beginTime(), m_timeEdit->toEnd(), m_timeEdit->endTime()); } else { int timeBegin = -1, timeEnd = -1; if (!m_timeEdit->fromBegin()) timeBegin = m_timeEdit->beginTime(); if (!m_timeEdit->toEnd()) timeEnd = m_timeEdit->endTime(); m_previewer->play(m_param->source, timeBegin, timeEnd); } } void ConversionParameterDialog::interactive_cutting() { if (m_singleFile) { InteractiveCuttingDialog(this).exec(m_param->source, m_timeEdit); } } AbstractPreviewer *ConversionParameterDialog::create_previewer() { //AbstractPreviewer *previewer; // Use mplayer by default. //previewer = new MPlayerPreviewer(this); //if (previewer->available()) // return previewer; // mplayer not available, use ffplay as fallback //delete previewer; return new FFplayPreviewer(this); } // read the fields from the ConversionParameters void ConversionParameterDialog::read_fields(const ConversionParameters& param) { // Additional Options ui->txtFFmpegOptions->setPlainText(param.ffmpeg_options); // Audio Options ui->chkDisableAudio->setChecked(param.disable_audio); ui->chkCopyAudio->setChecked(param.copy_audio); ui->spinAudioBitrate->setValue(param.audio_bitrate); ui->cbAudioSampleRate->setEditText(QString::number(param.audio_sample_rate)); ui->spinChannels->setValue(param.audio_channels); if (param.audio_volume) ui->spinVolume->setValue(TO_PERCENT(param.audio_volume)); else ui->spinVolume->setValue(100); // Video Options ui->chkDisableVideo->setChecked(param.disable_video); ui->chkCopyVideo->setChecked(param.copy_video); ui->spinVideoBitrate->setValue(param.video_bitrate); ui->spinWidth->setValue(param.video_width); ui->spinHeight->setValue(param.video_height); ui->chkVideoSameQuality->setChecked(param.video_same_quality); ui->chkDeinterlace->setChecked(param.video_deinterlace); ui->spinCropTop->setValue(param.video_crop_top); ui->spinCropBottom->setValue(param.video_crop_bottom); ui->spinCropLeft->setValue(param.video_crop_left); ui->spinCropRight->setValue(param.video_crop_right); // Time Options bool show_slider = false; m_rangeSel->setVisible(false); // hide slider if this dialog is reused if (m_singleFile) { // time slider: only show in single file mode MediaProbe probe; if (probe.run(param.source)) { // probe the source file, blocking call // success, set the duration and show the range slider int duration = (int)probe.mediaDuration(); m_timeEdit->setMaxTime(duration); m_rangeSel->setMaxValue(duration); m_rangeSel->setVisible(true); show_slider = true; } } bool show_preview_button = show_slider && m_previewer->available(); bool show_cutting_button = show_slider && InteractiveCuttingDialog::available(); ui->btnPreview->setVisible(show_preview_button); ui->btnInteractiveCutting->setVisible(show_cutting_button); if (param.time_begin > 0) { m_timeEdit->setBeginTime(param.time_begin); m_timeEdit->setFromBegin(false); } else { m_timeEdit->setBeginTime(0); m_timeEdit->setFromBegin(true); } if (param.time_end > 0) { m_timeEdit->setEndTime(param.time_end); m_timeEdit->setToEnd(false); } else { m_timeEdit->setEndTime(0); m_timeEdit->setToEnd(true); } if (param.speed_scaling) ui->spinSpeedFactor->setValue(param.speed_scaling_factor * 100.0); else ui->spinSpeedFactor->setValue(100.0); // Subtitle Options //ui->chkDisableSubtitle->setChecked(param.disable_subtitle); } //#define QTIME_TO_SECS(t) ((t.hour()) * 3600 + (t.minute()) * 60 + (t.second())) // write the fields to the ConversionParameters void ConversionParameterDialog::write_fields(ConversionParameters& param) { // Additional Options param = param.fromFFmpegParameters(ui->txtFFmpegOptions->toPlainText()); // Audio Options param.disable_audio = ui->chkDisableAudio->isChecked(); param.copy_audio = ui->chkCopyAudio->isChecked(); param.audio_sample_rate = ui->cbAudioSampleRate->currentText().toInt(); param.audio_bitrate = ui->spinAudioBitrate->value(); param.audio_channels = ui->spinChannels->value(); param.audio_volume = TO_BYTEPERCENT(ui->spinVolume->value()); // Video Options param.disable_video = ui->chkDisableVideo->isChecked(); param.copy_video = ui->chkCopyVideo->isChecked(); param.video_bitrate = ui->spinVideoBitrate->value(); param.video_same_quality = ui->chkVideoSameQuality->isChecked(); param.video_deinterlace = ui->chkDeinterlace->isChecked(); param.video_width = ui->spinWidth->value(); param.video_height = ui->spinHeight->value(); param.video_crop_top = ui->spinCropTop->value(); param.video_crop_bottom = ui->spinCropBottom->value(); param.video_crop_left = ui->spinCropLeft->value(); param.video_crop_right = ui->spinCropRight->value(); // Time Options if (m_timeEdit->fromBegin()) param.time_begin = 0; else param.time_begin = m_timeEdit->beginTime(); if (m_timeEdit->toEnd()) param.time_end = 0; else // ffmpeg accepts duration, not end time param.time_end = m_timeEdit->endTime(); double speed_ratio = ui->spinSpeedFactor->value(); if (!m_enableAudioProcessing || std::abs(speed_ratio - 100.0) <= 0.01) { param.speed_scaling = false; param.speed_scaling_factor = 1.0; } else { param.speed_scaling = true; param.speed_scaling_factor = speed_ratio / 100.0; } } void ConversionParameterDialog::audio_tab_update_enabled_widgets() { bool disable_audio = ui->chkDisableAudio->isChecked(); bool copy_audio = ui->chkCopyAudio->isChecked(); ui->chkDisableAudio->setEnabled(true); // always enabled ui->chkCopyAudio->setEnabled(!disable_audio); ui->groupAudioOptions->setEnabled(!disable_audio && !copy_audio); } void ConversionParameterDialog::video_tab_update_enabled_widgets() { bool disable_video= ui->chkDisableVideo->isChecked(); bool copy_video = ui->chkCopyVideo->isChecked(); ui->chkDisableVideo->setEnabled(true); // always enabled ui->chkCopyVideo->setEnabled(!disable_video); ui->groupVideoOptions->setEnabled(!disable_video && !copy_video); } qwinff-master/src/ui/conversionparameterdialog.h000066400000000000000000000044041347323557400225030ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef CONVERSIONPARAMETERDIALOG_H #define CONVERSIONPARAMETERDIALOG_H #include #include "converter/conversionparameters.h" namespace Ui { class ConversionParameterDialog; } class RangeSelector; class TimeRangeEdit; class AbstractPreviewer; class ConversionParameterDialog : public QDialog { Q_OBJECT public: explicit ConversionParameterDialog(QWidget *parent = 0); ~ConversionParameterDialog(); /*! This function blocks until the dialog is closed. * @param param If the user presses OK, the modified parameter is written back. * @param single_file If @a single_file is true, the dialog will probe * the file indicated by @c param.source and show some additional options. * default: false. * @return If the user presses OK, the function returns true. * Otherwise, it returns false. */ bool exec(ConversionParameters& param, bool single_file=false); private slots: void preview_time_selection(); void interactive_cutting(); AbstractPreviewer *create_previewer(); void audio_tab_update_enabled_widgets(); void video_tab_update_enabled_widgets(); private: Ui::ConversionParameterDialog *ui; void read_fields(const ConversionParameters& param); void write_fields(ConversionParameters& param); bool m_enableAudioProcessing; bool m_singleFile; TimeRangeEdit *m_timeEdit; RangeSelector *m_rangeSel; ConversionParameters *m_param; AbstractPreviewer *m_previewer; }; #endif // CONVERSIONPARAMETERDIALOG_H qwinff-master/src/ui/conversionparameterdialog.ui000066400000000000000000000507511347323557400226770ustar00rootroot00000000000000 ConversionParameterDialog 0 0 403 423 0 0 Conversion Parameters 0 Audio Disable Audio Copy Audio (Do not re-encode) Audio Options Sample Rate true Hz Bitrate QAbstractSpinBox::NoButtons (auto) 9999 64 kb/s Channels (auto) 0 2 2 Volume 1 200 100 % Video Disable Video Copy Video (Do not re-encode) Video Options Same Quantizer as Source Same Quantizer as Source Deinterlace Width QAbstractSpinBox::UpDownArrows px 9999 Qt::Horizontal 40 20 Height QAbstractSpinBox::UpDownArrows px 9999 Qt::Horizontal 40 20 Bitrate QAbstractSpinBox::NoButtons (auto) 9999 kb/s QAbstractSpinBox::UpDownArrows px 9999 QAbstractSpinBox::UpDownArrows px 9999 Crop Qt::AlignCenter QAbstractSpinBox::UpDownArrows px 9999 QAbstractSpinBox::UpDownArrows px 9999 Qt::Vertical 20 40 Time Cutting Qt::Horizontal 40 20 Cut :/actions/icons/cut.png:/actions/icons/cut.png &Preview :/actions/icons/preview_play.png:/actions/icons/preview_play.png Scaling Speed % 10.000000000000000 1000.000000000000000 Advanced FFmpeg Additional FFmpeg Options Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok cbAudioSampleRate spinAudioBitrate spinChannels spinVolume spinWidth spinHeight spinVideoBitrate spinCropTop spinCropLeft spinCropRight spinCropBottom txtFFmpegOptions buttonBox buttonBox accepted() ConversionParameterDialog accept() 253 417 157 274 buttonBox rejected() ConversionParameterDialog reject() 321 417 286 274 qwinff-master/src/ui/convertlist.cpp000066400000000000000000001136271347323557400201540ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "convertlist.h" #include "progressbar.h" #include "converter/mediaconverter.h" #include "converter/mediaprobe.h" #include "services/filepathoperations.h" #include "services/constants.h" #include "ui/conversionparameterdialog.h" #include "ui/interactivecuttingdialog.h" #include "addtaskwizard.h" #include "services/extensions.h" #define TIMEOUT 3000 #define MIN_DURATION 100 // Minimum duration(milliseconds) to show progress dialog. namespace { QString htmlEscape(QString s) { #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) return s.toHtmlEscaped(); #else // Qt4 return Qt::escape(s); #endif } } class Task : public QObject { public: explicit Task(QObject *parent = 0) : QObject(parent) { } virtual ~Task() { } enum TaskStatus { QUEUED, RUNNING, FINISHED, FAILED }; int id; TaskStatus status; ConversionParameters param; QTreeWidgetItem *listitem; QString errmsg; }; /* This enum defines the columns of the list. The last item is always NUM_COLUMNS, which is used to identify how many columns there are. To add a new item, just follow the following steps: (1) Add a new enumeration constant to ConvertListColumns before NUM_COLUMNS. (2) Search for the function "init_treewidget_fill_column_titles" and fill in the title of the new field there. Read the instruction before the function body for details. (3) Search for the function "init_treewidget_columns_visibility" and set the default visibility of the field. (4) Search for the function "fill_list_fields". This function is called when a new task is being added to the list. Fill in the field according to the parameter and the probing result. */ enum ConvertListColumns { COL_SOURCE, COL_DESTINATION, COL_DURATION, COL_FILE_SIZE, COL_AUDIO_SAMPLE_RATE, COL_AUDIO_BITRATE, COL_AUDIO_CHANNELS, COL_AUDIO_CODEC, COL_VIDEO_DIMENSIONS, COL_VIDEO_BITRATE, COL_VIDEO_FRAMERATE, COL_VIDEO_CODEC, COL_PROGRESS, NUM_COLUMNS }; class ConvertList::ListEventFilter : public QObject { public: ListEventFilter(ConvertList *parent) : QObject(parent), m_parent(parent) { } // Propagate events from the list to its parent. bool eventFilter(QObject */*object*/, QEvent *event) { switch (event->type()) { case QEvent::KeyPress: return m_parent->list_keyPressEvent(static_cast(event)); case QEvent::DragEnter: m_parent->list_dragEnterEvent(static_cast(event)); return true; case QEvent::DragMove: m_parent->list_dragMoveEvent(static_cast(event)); return true; case QEvent::DragLeave: m_parent->list_dragLeaveEvent(static_cast(event)); return true; case QEvent::Drop: m_parent->list_dropEvent(static_cast(event)); return true; case QEvent::ChildRemoved: m_parent->list_childRemovedEvent(static_cast(event)); return true; case QEvent::MouseButtonPress: m_parent->list_mousePressEvent(static_cast(event)); return false; // don't eat mouse events default: break; } return false; } private: ConvertList *m_parent; }; ConvertList::ConvertList(Presets *presets, QWidget *parent) : QWidget(parent), m_list(new QTreeWidget(this)), m_listEventFilter(new ListEventFilter(this)), prev_index(0), m_converter(new MediaConverter(this)), m_probe(new MediaProbe(this)), m_current_task(0), is_busy(false), run_next(false), m_presets(presets) { QLayout *layout = new QHBoxLayout(this); this->setLayout(layout); init_treewidget(m_list); layout->addWidget(m_list); connect(m_converter, SIGNAL(finished(int)) , this, SLOT(task_finished_slot(int))); connect(m_converter, SIGNAL(progressRefreshed(int)), this, SLOT(progress_refreshed(int))); connect(m_list, SIGNAL(itemSelectionChanged()), this, SIGNAL(itemSelectionChanged())); connect(m_list, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(slotDoubleClick(QModelIndex))); // Propagate context menu event. m_list->setContextMenuPolicy(Qt::CustomContextMenu); connect(m_list, SIGNAL(customContextMenuRequested(QPoint)) , this, SIGNAL(customContextMenuRequested(QPoint))); // enable drag/drop functions m_list->setAcceptDrops(true); // allow selecting multiple items m_list->setSelectionMode(QAbstractItemView::ExtendedSelection); // Propagate events from the QTreeWidget to ConvertList. m_list->installEventFilter(m_listEventFilter); m_list->viewport()->installEventFilter(m_listEventFilter); // Enable internal drag-and-drop of list items m_list->setDragDropMode(QAbstractItemView::InternalMove); QSettings settings; QHeaderView *header = m_list->header(); /* Only restore header states if the column count of the stored header state is the same as the current column count. Otherwise, the stored state is meaningless and should not be used. */ int prev_column_count = settings.value("convertlist/column_count").toInt(); if (prev_column_count == NUM_COLUMNS) header->restoreState(settings.value("convertlist/header_state").toByteArray()); header->setContextMenuPolicy(Qt::CustomContextMenu); connect(header, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(slotHeaderContextMenu(QPoint))); m_startTime.start(); show_background_image(); } ConvertList::~ConvertList() { QSettings settings; /* must store column count along with header state, because saved header state is meaningless if the column count changes. */ settings.setValue("convertlist/header_state", m_list->header()->saveState()); settings.setValue("convertlist/column_count", NUM_COLUMNS); } bool ConvertList::addTask(ConversionParameters param) { // get source file information qDebug() << "Probe media file: " << param.source; if (!m_probe->run(param.source, TIMEOUT)) { if (m_probe->error()) qDebug() << "Failed to get media information"; else qDebug() << "FFprobe timeout"; // failed to get media information immediately return false; } /* Ensure unique output filename. If the destination filename already exists either on disk or in the ConvertList, rename it to prevent overwritting completed tasks. */ param.destination = FilePathOperations::GenerateUniqueFileName(param.destination, output_filenames()); output_filenames_push(param.destination); // Record the filename for future reference. QStringList columns; for (int i=0; iparam = param; task->status = Task::QUEUED; task->id = ++prev_index; task->listitem = item; QVariant task_var = qVariantFromValue((void*)task); item->setData(0, Qt::UserRole, task_var); // Prevent dropping directly on an item item->setFlags(item->flags() & ~Qt::ItemIsDropEnabled); m_list->addTopLevelItem(item); progressBar(task)->adjustSize(); update_tooltip(item); hide_background_image(); qDebug() << QString("Added: \"%1\" -> \"%2\"").arg(param.source).arg(param.destination); return true; } int ConvertList::addTasks(const QList ¶mList) { const int file_count = paramList.size(); int success_count = 0; // Record the files that are not recognized by the converter. QStringList failed_files; // Create progress dialog. /* Translators: *//*: Cancel the operation of adding new tasks */ QProgressDialog dlgProgress(QString(""), tr("Cancel"), 0, file_count, /* min/max */ this); dlgProgress.setWindowModality(Qt::WindowModal); dlgProgress.setMinimumDuration(MIN_DURATION); int progress_count = 0; QList::const_iterator it = paramList.begin(); for (; it!=paramList.end(); ++it) { // Indicate the current progress. /*: This text is the progress indicator of adding multiple tasks. %1 is the number of files that are already added. %2 is the total number of files. */ dlgProgress.setLabelText(tr("Adding files (%1/%2)") .arg(progress_count).arg(file_count)); // Update progress dialog. dlgProgress.setValue(progress_count++); // Check if the user has canceled the operation. if (dlgProgress.wasCanceled()) break; if (addTask(*it)) { // This step takes the most of the time. success_count++; } else { failed_files.push_back(it->source); // Record failed files. qDebug() << QString("Failed to add file: %1").arg(it->source); } } dlgProgress.setValue(file_count); // Terminate the progress indicator. if (!failed_files.isEmpty()) { // Some files are incorrect. QMessageBox msgBox; msgBox.setText(tr("Some files are not recognized by the converter.")); msgBox.setDetailedText(failed_files.join("\n")); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setIcon(QMessageBox::Warning); msgBox.exec(); } // start conversion if autostart is true const bool autostart_default = Constants::getBool("AutoStartConversion"); bool autostart = QSettings().value("options/auto_start_conversion", autostart_default).toBool(); if (autostart && count() > 0) start(); return success_count; } bool ConvertList::isBusy() const { return is_busy; } bool ConvertList::isEmpty() const { return m_list->topLevelItemCount() == 0; } int ConvertList::count() const { return m_list->topLevelItemCount(); } int ConvertList::selectedCount() const { return m_list->selectedItems().size(); } int ConvertList::finishedCount() const { return finished_items().size(); } int ConvertList::elapsedTime() const { return is_busy ? m_startTime.elapsed() : 0; } const ConversionParameters* ConvertList::getCurrentIndexParameter() const { Task *task = first_selected_task(); return task ? &task->param : 0; } bool ConvertList::selectedTaskFailed() const { Task *task = first_selected_task(); if (!task || selectedCount() != 1) return false; return task->status == Task::FAILED; } // Public Slots void ConvertList::start() { if (is_busy && !run_next) return; run_next = false; if (!is_busy) { // new session: start timing m_startTime.restart(); is_busy = true; emit started(); } if (!run_first_queued_task()) { // no task is executed this->stop(); emit all_tasks_finished(); emit stopped(); } } void ConvertList::stop() { is_busy = false; if (m_current_task) { progress_refreshed(0); m_current_task->status = Task::QUEUED; progressBar(m_current_task)->setActive(false); m_current_task = 0; emit stopped(); } m_converter->stop(); } void ConvertList::removeSelectedItems() { remove_items(m_list->selectedItems()); } void ConvertList::removeCompletedItems() { remove_items(finished_items()); } void ConvertList::editSelectedParameters() { QList itemList = m_list->selectedItems(); if (itemList.isEmpty()) return; Task *first_sel_task = get_task(itemList[0]); Q_ASSERT(first_sel_task != 0); ConversionParameters param = first_sel_task->param; bool singleItem = (itemList.size() == 1); ConversionParameterDialog dialog(this->parentWidget()); if (dialog.exec(param, singleItem)) { foreach (QTreeWidgetItem* item, itemList) { Task *task = get_task(item); // copy conversion parameters // Be sure not to use assignment because it will overwrite the filename. task->param.copyConfigurationFrom(param); reset_task(task); } } } void ConvertList::changeSelectedOutputFile() { Task *task = first_selected_task(); if (!task) return; ConversionParameters ¶m = task->param; QString orig_name = QFileInfo(param.destination).completeBaseName(); QString dir = QFileInfo(param.destination).path(); QString ext = QFileInfo(param.destination).suffix(); QString new_name = orig_name; bool try_again = false; do { new_name = QInputDialog::getText(this, tr("New File Name") , tr("Please input the new name for the output file.") , QLineEdit::Normal, new_name); try_again = false; if (!new_name.isEmpty() && new_name != orig_name) { QString orig_file = param.destination; QString file = QDir(dir).absoluteFilePath(new_name + "." + ext); QMessageBox::StandardButtons overwrite = QMessageBox::No; if (!change_output_file(task, file, overwrite, false)) try_again = true; } } while (try_again); } void ConvertList::changeSelectedOutputDirectory() { Task *task = first_selected_task(); if (!task) return; ConversionParameters ¶m = task->param; QString orig_path = QFileInfo(param.destination).path(); QString path = QFileDialog::getExistingDirectory(this, tr("Output Directory") , orig_path); if (!path.isEmpty()) { // Apply the output path to all selected items QMessageBox::StandardButtons overwrite = QMessageBox::No; QList itemList = m_list->selectedItems(); foreach (QTreeWidgetItem *item, itemList) { QString orig_file = task->param.destination; QString name = QFileInfo(orig_file).fileName(); QString file = QDir(path).absoluteFilePath(name); change_output_file(get_task(item), file, overwrite, true); } } } void ConvertList::cutSelectedTask() { /* This operation only changes begin time and duration of the parameter, so there is no need to refresh the list */ if (selectedCount() != 1 || !InteractiveCuttingDialog::available()) return; ConversionParameters *param = &first_selected_task()->param; InteractiveCuttingDialog(this).exec(param); } void ConvertList::retrySelectedItems() { QList itemList = m_list->selectedItems(); if (itemList.isEmpty()) return; foreach (QTreeWidgetItem* item, itemList) reset_task(get_task(item)); start(); } void ConvertList::retryAll() { const int list_size = m_list->topLevelItemCount(); for (int i=0; itopLevelItem(i); reset_task(get_task(item)); } start(); } void ConvertList::showErrorMessage() { Task *task = first_selected_task(); if (task) { QMessageBox msgBox; msgBox.setText(tr("Error Message from FFmpeg:\n\n") + task->errmsg); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setIcon(QMessageBox::Information); msgBox.exec(); } } void ConvertList::clear() { const int item_count = count(); QList itemList; for (int i=0; itopLevelItem(i)); remove_items(itemList); } // Private Slots void ConvertList::task_finished_slot(int exitcode) { if (m_current_task) { m_current_task->status = (exitcode == 0) ? Task::FINISHED : Task::FAILED; if (exitcode != 0) m_current_task->errmsg = m_converter->errorMessage(); else m_current_task->errmsg = ""; refresh_progressbar(m_current_task); m_current_task = 0; emit task_finished(exitcode); run_next = true; this->start(); // start next task } } void ConvertList::progress_refreshed(int percentage) { if (m_current_task) { qDebug() << "Progress Refreshed: " << percentage << "%"; progressBar(m_current_task)->setValue(percentage); } } void ConvertList::show_background_image() { m_list->viewport()->setStyleSheet( "background-image: url(:/other/icons/list_background.png);" "background-position: center;" "background-repeat: no-repeat;"); QString tip = tr("Drag and drop files here to add tasks."); m_list->viewport()->setStatusTip(tip); m_list->viewport()->setToolTip(tip); } void ConvertList::hide_background_image() { m_list->viewport()->setStyleSheet(""); m_list->viewport()->setStatusTip(""); m_list->viewport()->setToolTip(""); } void ConvertList::slotHeaderContextMenu(QPoint point) { const int header_count = m_list->header()->count(); const int current_column = m_list->header()->logicalIndexAt(point); // Count visible columns. int visible_column_count = 0, visible_column_index = 0; for (int i=0; iisColumnHidden(i)) { ++visible_column_count; visible_column_index = i; } } QMenu menu; // Add the item under the mouse to the list if (current_column >= 0 && visible_column_count > 1) { QAction *action = new QAction(&menu); QString column_text = m_list->headerItem()->text(current_column); /*: Hide a column in the list. For example, the text maybe 'Hide "Duration"'. The two \" are quotation marks in English, you may replace it with local quotation marks. */ QString action_text = tr("Hide \"%1\"").arg(column_text); action->setText(action_text); action->setData(current_column); action->setCheckable(false); action->setChecked(false); menu.addAction(action); } QAction *actionRestore = new QAction(&menu); actionRestore->setText(tr("Restore All Columns")); actionRestore->setData(-1); connect(actionRestore, SIGNAL(triggered()), this, SLOT(slotRestoreListHeaders())); menu.addAction(actionRestore); menu.addSeparator(); // Construct the rest of the menu and uncheck hidden items. for (int i=0; iheaderItem()->text(i); QAction *action = new QAction(title, &menu); action->setCheckable(true); action->setChecked(!m_list->isColumnHidden(i)); action->setData(i); // save the column index // not allow user to hide the last column if (visible_column_count > 1 || visible_column_index != i) menu.addAction(action); } connect(&menu, SIGNAL(triggered(QAction*)), this, SLOT(slotHeaderContextMenuTriggered(QAction*))); menu.exec(QCursor::pos()); } void ConvertList::slotHeaderContextMenuTriggered(QAction *action) { const int column_index = action->data().toInt(); if (column_index >= 0) m_list->setColumnHidden(column_index, !action->isChecked()); } void ConvertList::slotRestoreListHeaders() { const int column_count = m_list->columnCount(); QHeaderView *header = m_list->header(); for (int i=0; ishowColumn(i); header->resizeSection(i, header->defaultSectionSize()); } // Restore default value. init_treewidget_columns_visibility(m_list); } void ConvertList::slotDoubleClick(QModelIndex index) { int row = index.row(); if (row >= 0 && row < count()) { QTreeWidgetItem *item = m_list->topLevelItem(row); Task *task = get_task(item); if (task) { switch (task->status) { case Task::QUEUED: case Task::FAILED: // Show ConversionParameterDialog editSelectedParameters(); break; case Task::FINISHED: // Open output folder { QString folder_path = QFileInfo(task->param.destination).path(); if (QFileInfo(folder_path).exists()) { QDesktopServices::openUrl(QUrl::fromLocalFile(folder_path)); } } break; default: break; } } } } void ConvertList::slotAllItemsRemoved() { show_background_image(); } // Events bool ConvertList::list_keyPressEvent(QKeyEvent *event) { if (event->key() == Qt::Key_Delete) { // Remove all selected items. removeSelectedItems(); return true; // processed } else { return false; // not processed } } void ConvertList::list_dragEnterEvent(QDragEnterEvent *event) { if (event->mimeData()->hasUrls()) event->acceptProposedAction(); } void ConvertList::list_dragMoveEvent(QDragMoveEvent *event) { const QMimeData *mimeData = event->mimeData(); if (mimeData && mimeData->hasUrls()) event->acceptProposedAction(); } void ConvertList::list_dragLeaveEvent(QDragLeaveEvent *event) { event->accept(); } // The user drops files into the area. void ConvertList::list_dropEvent(QDropEvent *event) { const QMimeData *mimeData = event->mimeData(); if (mimeData && mimeData->hasUrls()) { QList urlList = mimeData->urls(); AddTaskWizard wizard(m_presets, parentWidget()); QStringList files; Extensions exts; // convert urls into local paths foreach (QUrl url, urlList) { QString file = url.toLocalFile(); // local file name files.append(file); } // show add task wizard if (!files.isEmpty() && wizard.exec(files) == QWizard::Accepted) { addTasks(wizard.getConversionParameters()); } } } void ConvertList::list_childRemovedEvent(QChildEvent */*event*/) { const int task_count = count(); // refresh all ProgressBar objects for (int i=0; itopLevelItem(i))); } } void ConvertList::list_mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton && isEmpty()) { // open add task wizard if the list is empty AddTaskWizard wizard(m_presets, this); if (wizard.exec_openfile() == QDialog::Accepted) { addTasks(wizard.getConversionParameters()); } } } // Functions to access m_outputFileNames void ConvertList::output_filenames_push(const QString& filename) { if (m_outputFileNames.contains(filename)) { ++m_outputFileNames[filename]; } else { m_outputFileNames.insert(filename, 1); } } void ConvertList::output_filenames_pop(const QString &filename) { int count = m_outputFileNames.value(filename, 0); if (count > 1) { --m_outputFileNames[filename]; } else if (count == 1) { m_outputFileNames.remove(filename); } } QHash& ConvertList::output_filenames() { return m_outputFileNames; } // Initialize the QTreeWidget listing files. void ConvertList::init_treewidget(QTreeWidget *w) { Q_ASSERT_X(w, "ConvertList::init_treewidget", "w: null pointer"); w->setColumnCount(NUM_COLUMNS); QStringList columnTitle; for (int i=0; isetHeaderLabels(columnTitle); //w->header()->setMovable(false); // disable title drag-drop reordering w->setRootIsDecorated(false); w->setUniformRowHeights(true); init_treewidget_columns_visibility(w); } /* Fill in the column titles of each field. Use the COL_* macros as the index. Example: columnTitle[COL_SOURCE] = tr("Source"); */ void ConvertList::init_treewidget_fill_column_titles(QStringList &columnTitle) { columnTitle[COL_SOURCE] = tr("Source"); columnTitle[COL_DESTINATION] = tr("Destination"); columnTitle[COL_DURATION] = tr("Duration"); columnTitle[COL_FILE_SIZE] = tr("File Size"); // Audio Information columnTitle[COL_AUDIO_SAMPLE_RATE] = /*: Audio */ tr("Sample Rate"); columnTitle[COL_AUDIO_BITRATE] = tr("Audio Bitrate"); columnTitle[COL_AUDIO_CHANNELS] = /*: Audio */ tr("Channels"); columnTitle[COL_AUDIO_CODEC] = tr("Audio Codec"); // Video Information columnTitle[COL_VIDEO_DIMENSIONS] = tr("Dimensions"); columnTitle[COL_VIDEO_BITRATE] = tr("Video Bitrate"); columnTitle[COL_VIDEO_FRAMERATE] = /*: Video */ tr("Framerate"); columnTitle[COL_VIDEO_CODEC] = tr("Video Codec"); columnTitle[COL_PROGRESS] = tr("Progress"); // Check if all columns have titles for (int i=0; ihideColumn(COL_DURATION, true); */ void ConvertList::init_treewidget_columns_visibility(QTreeWidget *w) { w->hideColumn(COL_FILE_SIZE); // Audio Information w->hideColumn(COL_AUDIO_SAMPLE_RATE); w->hideColumn(COL_AUDIO_BITRATE); w->hideColumn(COL_AUDIO_CHANNELS); w->hideColumn(COL_AUDIO_CODEC); // Video Information w->hideColumn(COL_VIDEO_DIMENSIONS); w->hideColumn(COL_VIDEO_BITRATE); w->hideColumn(COL_VIDEO_FRAMERATE); w->hideColumn(COL_VIDEO_CODEC); } bool ConvertList::run_first_queued_task() { // execute the first queued task in the list and return // returns true if a task is run, false if none const int task_count = count(); for (int i=0; itopLevelItem(i); Task *task = get_task(item); if (task->status == Task::QUEUED) { QSettings settings; // start the task is_busy = true; task->status = Task::RUNNING; m_current_task = task; progressBar(task)->setActive(true); task->param.threads = settings.value("options/threads", DEFAULT_THREAD_COUNT).toInt(); qDebug() << "Threads: " + QString::number(task->param.threads); m_converter->start(task->param); emit start_conversion(i, task->param); return true; } } return false; } /* Fill in the columns of the list according to the conversion parameter and the probing results. QStringList columns will be filled with empty items in advanced and the MediaProbe probe will be ready for reading. Just write available information to the corresponding fields. Use the COL_* macros as the array index. Example: columns[COL_SOURCE] = param.source; */ void ConvertList::fill_list_fields(ConversionParameters ¶m, MediaProbe &probe, QStringList &columns) { columns[COL_SOURCE] = QFileInfo(param.source).fileName(); // source file columns[COL_DESTINATION] = QFileInfo(param.destination).fileName(); // destination file columns[COL_DURATION] = QString().sprintf("%02d:%02d:%02.0f" // duration , probe.hours() // hours , probe.minutes() // minutes , probe.seconds()); // seconds // File Size columns[COL_FILE_SIZE] = to_human_readable_size_1024(QFileInfo(param.source).size()); // Audio Information if (probe.hasAudio()) { columns[COL_AUDIO_SAMPLE_RATE] = tr("%1 Hz").arg(probe.audioSampleRate()); columns[COL_AUDIO_BITRATE] = tr("%1 kb/s").arg(probe.audioBitRate()); columns[COL_AUDIO_CHANNELS] = QString::number(probe.audioChannels()); columns[COL_AUDIO_CODEC] = probe.audioCodec(); } // Video Information if (probe.hasVideo()) { columns[COL_VIDEO_DIMENSIONS] = QString("%1x%2") .arg(probe.videoWidth()).arg(probe.videoHeight()); columns[COL_VIDEO_BITRATE] = tr("%1 kb/s").arg(probe.videoBitRate()); columns[COL_VIDEO_FRAMERATE] = tr("%1 fps").arg(probe.videoFrameRate()); columns[COL_VIDEO_CODEC] = probe.videoCodec(); } } // Reset the item to the queued state. void ConvertList::reset_task(Task *task) { if (task && task->status != Task::RUNNING) { task->status = Task::QUEUED; refresh_progressbar(task); } } // Remove items in the list. // A progress dialog is shown if the operation takes time longer than MIN_DURATION. void ConvertList::remove_items(const QList& itemList) { /*: Remove files from the tasklist */ QProgressDialog dlgProgress(tr("Removing tasks..."), tr("Cancel"), 0, itemList.count(), this); dlgProgress.setWindowModality(Qt::WindowModal); dlgProgress.setMinimumDuration(MIN_DURATION); int progress_count = 0; foreach (QTreeWidgetItem *item, itemList) { // Update the progress value. dlgProgress.setValue(++progress_count); // Check if the user has canceled the operation. if (dlgProgress.wasCanceled()) break; remove_item(item); } dlgProgress.setValue(itemList.size()); } /** * Retrieve the ProgressBar widget associated with the task. * This function creates the widget if it doesn't exist. * @return Returns the pointer to the ProgressBar widget. */ ProgressBar* ConvertList::progressBar(Task *task) { ProgressBar *prog = (ProgressBar*) m_list->itemWidget(task->listitem, COL_PROGRESS); if (!prog) { prog = new ProgressBar(); m_list->setItemWidget(task->listitem, COL_PROGRESS, prog); } return prog; } // Convert bytes to human readable form such as // "10 KiB" instead of "102400 Bytes". QString ConvertList::to_human_readable_size_1024(qint64 nBytes) { float num = nBytes; QStringList list; list << tr("KiB") << tr("MiB") << tr("GiB") << tr("TiB"); QStringListIterator i(list); QString /*: Bytes */ unit(tr("B")); while(num >= 1024.0 && i.hasNext()) { unit = i.next(); num /= 1024.0; } return QString().setNum(num,'f',2)+" "+unit; } /** Change the @c destination of the @a task to @a new_file * and update relevant fields in the list. * @warning @a task must not be NULL * @return true if success, false if failed */ bool ConvertList::change_output_file(Task *task, const QString &new_file , QMessageBox::StandardButtons &overwrite, bool show_all_buttons) { if (overwrite == QMessageBox::NoToAll) return false; ConversionParameters ¶m = task->param; QTreeWidgetItem *item = task->listitem; QString orig_file = param.destination; if (new_file == orig_file) return true; // success: no need to rename if ((QFileInfo(new_file).exists() || output_filenames().contains(new_file)) && overwrite != QMessageBox::YesToAll) { QMessageBox::StandardButtons flags = QMessageBox::Yes | QMessageBox::No; if (show_all_buttons) { flags |= QMessageBox::YesToAll | QMessageBox::NoToAll; } // The file name already exists. // Ask the user whether to force using the file name. overwrite = QMessageBox::warning(this, tr("File Exists"), tr("%1 already exists on disk or in the task list. " "Still use this name as the output filename?").arg(new_file) , flags); if (overwrite != QMessageBox::Yes && overwrite != QMessageBox::YesToAll) return false; } param.destination = new_file; // Rebuild the set of all output filenames in the list. output_filenames_pop(orig_file); output_filenames_push(new_file); // Update item text item->setText(COL_DESTINATION, QFileInfo(new_file).fileName()); update_tooltip(item); qDebug() << "Output filename changed: " + orig_file + " => " + new_file; return true; } /** * @brief Remove the @a item along with the associated Task object. */ void ConvertList::remove_item(QTreeWidgetItem *item) { Task *task = get_task(item); Q_ASSERT(task != 0); if (task->status != Task::RUNNING) { // not a running task output_filenames_pop(task->param.destination); const int item_index = m_list->indexOfTopLevelItem(item); QTreeWidgetItem *item = m_list->takeTopLevelItem(item_index); /* Delete the Task object * The ownership of the Task object belongs to m_list. * However, it is no longer used when the corresponding * list item is deleted, so it's OK to delete it here. */ delete get_task(item); delete item; qDebug() << "Removed list item " << item_index; if (isEmpty()) // removed the last item slotAllItemsRemoved(); } else { // The task is being executed. if (false) // Silently ignore the event. QMessageBox::warning(this, tr("Remove Task") , tr("Cannot remove a task while it is in progress.") , QMessageBox::Ok); } } /** * @brief This function returns the pointer to the first selected task. * @retval 0 No item is selected. */ Task* ConvertList::first_selected_task() const { QList itemList = m_list->selectedItems(); if (itemList.isEmpty()) return 0; else return get_task(itemList[0]); } /** * @brief Retrieve the task associated with the tree item * @retval 0 The task doesn't exist. */ Task* ConvertList::get_task(QTreeWidgetItem *item) const { return (Task*)item->data(0, Qt::UserRole).value(); } void ConvertList::refresh_progressbar(Task *task) { ProgressBar *prog = progressBar(task); switch (task->status) { case Task::QUEUED: prog->setValue(0); prog->setToolTip(""); prog->setStatusTip(""); prog->setActive(false); break; case Task::RUNNING: prog->setValue(m_converter->progress()); prog->setToolTip(""); prog->setStatusTip(""); prog->setActive(true); break; case Task::FINISHED: prog->setValue(100); /*: The text to be displayed on the progress bar when a conversion finishes */ prog->showText(tr("Finished")); prog->setToolTip(tr("Finished")); prog->setStatusTip(""); prog->setActive(false); break; case Task::FAILED: prog->setValue(0); /*: The text to be displayed on the progress bar when a conversion fails */ prog->showText(tr("Failed")); //: %1 is the error message prog->setToolTip(tr("Error: %1").arg(task->errmsg)); prog->setStatusTip(prog->toolTip()); // show error message in statusbar prog->setActive(false); break; default: qDebug() << "Error: incorrect task status"; break; } } void ConvertList::update_tooltip(QTreeWidgetItem *item) { QStringList tip; // List all columns except "progress" in tooltip. tip << "

"; // prevent automatic linebreak int count = 0; for (int i=0; iisColumnHidden(i)) { if (count++ != 0) tip << "
"; // prepend linebreak if necessary // show full filename for source and destination // otherwise, show the content of the column QString content; if (i == COL_SOURCE) content = get_task(item)->param.source; else if (i == COL_DESTINATION) content= get_task(item)->param.destination; else content = item->text(i); // show only visible columns tip << "" + m_list->headerItem()->text(i) // column title + ": " + htmlEscape(content) // column content ; } } tip << "

"; QString tip_str = tip.join(""); // set tooltip for every column in the row for (int i=0; isetToolTip(i, tip_str); } } QList ConvertList::finished_items() const { QList itemList; const int item_count = count(); for (int i=0; itopLevelItem(i)); if (task->status == Task::FINISHED) { itemList.push_back(task->listitem); } } return itemList; } qwinff-master/src/ui/convertlist.h000066400000000000000000000151371347323557400176160ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef CONVERTLIST_H #define CONVERTLIST_H #include #include #include #include #include #include #include "converter/conversionparameters.h" class MediaConverter; class MediaProbe; class QTreeWidget; class QTreeWidgetItem; class ProgressBar; class Presets; class Task; class ConvertList : public QWidget { Q_OBJECT public: explicit ConvertList(Presets *presets, QWidget *parent = 0); ~ConvertList(); /*! Append a task to the list * @param param the conversion parameter including the source and destination filename. * @return If the function succeeds, it returns true. * Otherwise, it returns false. */ bool addTask(ConversionParameters param); /*! Append a list of tasks to the list * @param paramList the list of conversion parameters * @return the number of successfully added tasks. */ int addTasks(const QList& paramList); bool isBusy() const; bool isEmpty() const; int count() const; int selectedCount() const; int finishedCount() const; /*! Get the elapsed time of the session (in milliseconds). * @retval 0 the converter is idle. */ int elapsedTime() const; /*! Returns the pointer to the ConversionParameters object of the * currently selected item. * @return If the function fails, it returns NULL. * @retval NULL the parameter doesn't exist */ const ConversionParameters* getCurrentIndexParameter() const; /*! Determine whether the selected task has failed. * @note If multiple tasks are selected, this function always returns false. */ bool selectedTaskFailed() const; signals: void start_conversion(int index, ConversionParameters param); void task_finished(int); void all_tasks_finished(); void customContextMenuRequested(const QPoint &pos); void itemSelectionChanged(); void started(); void stopped(); public slots: /*! Start the conversion progress. * If another task is being processed, the function does nothing. */ void start(); /*! Stop the conversion progress */ void stop(); /*! Remove all selected tasks but quietly ignore tasks in progress. */ void removeSelectedItems(); /*! Remove all tasks marked as completed. */ void removeCompletedItems(); /*! Popup edit-parameter dialog. * The parameter of the first selected task will be used as the default * configuration. If the user presses OK in the dialog, all selected * tasks will be set to the same parameter. */ void editSelectedParameters(); /*! Popup an input box to change the output filename * of the **first** selected file. * @warning If multiple files are selected, only the first * file will be changed. */ void changeSelectedOutputFile(); /*! Popup a directory selection dialog to change the output directory. */ void changeSelectedOutputDirectory(); /*! Select a time range to convert. */ void cutSelectedTask(); /*! Mark selected items as queued so that they will be converted again. * If the converter is idle, start converting those items. * Otherwise, the items are simply marked as queued. */ void retrySelectedItems(); void retryAll(); /*! Popup a message box to show the error message from ffmpeg. * This function only shows the error message for the first selected task. */ void showErrorMessage(); /*! Remove all tasks but quietly ignore tasks that are in progress. */ void clear(); private slots: void task_finished_slot(int); void progress_refreshed(int); void show_background_image(); void hide_background_image(); void slotHeaderContextMenu(QPoint); void slotHeaderContextMenuTriggered(QAction*); void slotRestoreListHeaders(); void slotDoubleClick(QModelIndex); void slotAllItemsRemoved(); protected: bool list_keyPressEvent(QKeyEvent *event); void list_dragEnterEvent(QDragEnterEvent *event); void list_dragMoveEvent(QDragMoveEvent *event); void list_dragLeaveEvent(QDragLeaveEvent *event); void list_dropEvent(QDropEvent *event); void list_childRemovedEvent(QChildEvent *event); void list_mousePressEvent(QMouseEvent *event); private: Q_DISABLE_COPY(ConvertList) class ListEventFilter; friend class ListEventFilter; QTreeWidget *m_list; ListEventFilter *m_listEventFilter; int prev_index; MediaConverter *m_converter; MediaProbe *m_probe; Task *m_current_task; bool is_busy; bool run_next; ///< run next task regardless of the value of is_busy Presets *m_presets; /** this variable should only be accessed by the output_filename_set* functions */ QHash m_outputFileNames; void output_filenames_push(const QString& filename); void output_filenames_pop(const QString& filename); QHash& output_filenames(); QTime m_startTime; void init_treewidget(QTreeWidget*); void init_treewidget_fill_column_titles(QStringList&); void init_treewidget_columns_visibility(QTreeWidget*); bool run_first_queued_task(); void fill_list_fields(ConversionParameters&, MediaProbe&, QStringList&); void reset_task(Task *task); void remove_items(const QList&); ProgressBar* progressBar(Task*); QString to_human_readable_size_1024(qint64 nBytes); bool change_output_file(Task *task, const QString& new_file , QMessageBox::StandardButtons &overwrite, bool show_all_buttons); void remove_item(QTreeWidgetItem *item); Task* first_selected_task() const; Task* get_task(QTreeWidgetItem*) const; void refresh_progressbar(Task*); void update_tooltip(QTreeWidgetItem *item); QList finished_items() const; }; #endif // CONVERTLIST_H qwinff-master/src/ui/interactivecuttingdialog.cpp000066400000000000000000000135151347323557400226660ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include #include #include #include "interactivecuttingdialog.h" #include "ui_interactivecuttingdialog.h" #include "mediaplayerwidget.h" #include "rangeselector.h" #include "timerangeedit.h" #include "rangewidgetbinder.h" #include "converter/exepath.h" #include "converter/conversionparameters.h" InteractiveCuttingDialog::InteractiveCuttingDialog(QWidget *parent) : QDialog(parent), ui(new Ui::InteractiveCuttingDialog), player(new MediaPlayerWidget(this)), m_rangeSel(new RangeSelector(this)), m_rangeEdit(new TimeRangeEdit(this)) { ui->setupUi(this); ui->layoutPlayer->addWidget(player); ui->layoutRangeSelector->addWidget(m_rangeSel); ui->layoutRangeEdit->addWidget(m_rangeEdit); // automatically sync between m_rangeSel and m_rangeEdit new RangeWidgetBinder(m_rangeSel, m_rangeEdit, this); connect(player, SIGNAL(stateChanged()), SLOT(playerStateChanged())); connect(ui->btnAsBegin, SIGNAL(clicked()), SLOT(set_as_begin())); connect(ui->btnAsEnd, SIGNAL(clicked()), SLOT(set_as_end())); connect(ui->btnToBegin, SIGNAL(clicked()), SLOT(seek_to_selection_begin())); connect(ui->btnToEnd, SIGNAL(clicked()), SLOT(seek_to_selection_end())); connect(ui->btnPlaySelection, SIGNAL(clicked()), SLOT(play_selection())); setFromBegin(true); setToEnd(true); } InteractiveCuttingDialog::~InteractiveCuttingDialog() { delete ui; } bool InteractiveCuttingDialog::available() { return ExePath::checkProgramAvailability("mplayer"); } bool InteractiveCuttingDialog::fromBegin() const { return m_rangeEdit->fromBegin(); } bool InteractiveCuttingDialog::toEnd() const { return m_rangeEdit->toEnd(); } int InteractiveCuttingDialog::beginTime() const { return m_rangeEdit->beginTime(); } int InteractiveCuttingDialog::endTime() const { return m_rangeEdit->endTime(); } void InteractiveCuttingDialog::setFromBegin(bool from_begin) { m_rangeEdit->setFromBegin(from_begin); } void InteractiveCuttingDialog::setToEnd(bool to_end) { m_rangeEdit->setToEnd(to_end); } void InteractiveCuttingDialog::setBeginTime(int sec) { m_rangeEdit->setBeginTime(sec); } void InteractiveCuttingDialog::setEndTime(int sec) { m_rangeEdit->setEndTime(sec); } int InteractiveCuttingDialog::exec(const QString &filename) { if (available()) { player->load(filename); return exec(); } else { QMessageBox::critical(this, windowTitle(), tr("%1 not found").arg("mplayer")); return QDialog::Rejected; } } int InteractiveCuttingDialog::exec(const QString &filename, TimeRangeEdit *range) { setBeginTime(range->beginTime()); setEndTime(range->endTime()); setFromBegin(range->fromBegin()); setToEnd(range->toEnd()); int status = exec(filename); if (status == QDialog::Accepted) { range->setBeginTime(beginTime()); range->setEndTime(endTime()); range->setFromBegin(fromBegin()); range->setToEnd(toEnd()); } return status; } int InteractiveCuttingDialog::exec(ConversionParameters *param) { // TODO: extract the conversion logic to getter and setter in ConversionParameters // convert begin and duration to begin and end time setBeginTime(param->time_begin); setFromBegin(param->time_begin == 0); if (param->time_end > 0) { // time_end == 0 means "to end" setEndTime(param->time_end); setToEnd(false); } else { setToEnd(true); } int status = exec(param->source); // convert from begin and end time back to begin and duration if (status == QDialog::Accepted) { param->time_begin = fromBegin() ? 0 : beginTime(); param->time_end = toEnd() ? 0 : endTime(); } return status; } int InteractiveCuttingDialog::exec() { load_settings(); int status = QDialog::exec(); save_settings(); return status; } void InteractiveCuttingDialog::playerStateChanged() { int duration = ceil(player->duration()); if (player->ok() && duration != m_rangeEdit->maxTime()) { // get media duration and set limits // change range edit after visual selection m_rangeSel->setMaxValue(duration); m_rangeEdit->setMaxTime(duration); } } void InteractiveCuttingDialog::set_as_begin() { m_rangeEdit->setBeginTime(floor(player->position())); } void InteractiveCuttingDialog::set_as_end() { m_rangeEdit->setEndTime(ceil(player->position())); } void InteractiveCuttingDialog::seek_to_selection_begin() { int begin_time = m_rangeEdit->beginTime(); player->seek_and_pause(begin_time); } void InteractiveCuttingDialog::seek_to_selection_end() { int end_time = m_rangeEdit->endTime(); player->seek_and_pause(end_time); } void InteractiveCuttingDialog::play_selection() { player->playRange(m_rangeEdit->beginTime(), m_rangeEdit->endTime()); } void InteractiveCuttingDialog::load_settings() { QSettings settings; restoreGeometry(settings.value("cutting_dialog/geometry").toByteArray()); } void InteractiveCuttingDialog::save_settings() { QSettings settings; settings.setValue("cutting_dialog/geometry", saveGeometry()); } qwinff-master/src/ui/interactivecuttingdialog.h000066400000000000000000000051371347323557400223340ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef INTERACTIVECUTTINGDIALOG_H #define INTERACTIVECUTTINGDIALOG_H #include namespace Ui { class InteractiveCuttingDialog; } class MediaPlayerWidget; class TimeRangeEdit; class RangeSelector; class ConversionParameters; class InteractiveCuttingDialog : public QDialog { Q_OBJECT public: explicit InteractiveCuttingDialog(QWidget *parent = 0); ~InteractiveCuttingDialog(); static bool available(); bool fromBegin() const; bool toEnd() const; int beginTime() const; int endTime() const; public slots: void setFromBegin(bool); void setToEnd(bool); void setBeginTime(int); void setEndTime(int); /** * @brief Start the dialog to cut a file * @param filename the file to process * @return QDialog::Accepted if the user selects a range. */ int exec(const QString& filename); /** * @brief Start the dialog to cut a file and modify @a range if the user presses OK. * @param filename the file to process * @param range [in,out] the range widget to be modified * @return */ int exec(const QString& filename, TimeRangeEdit *range); /** * @brief Start the dialog to cut @c param->source and modify time_begin and time_end * if the user presses OK. * @param param [in,out] pointer to the ConversionParameters object to be modified * @return */ int exec(ConversionParameters *param); private slots: int exec(); void playerStateChanged(); void set_as_begin(); void set_as_end(); void seek_to_selection_begin(); void seek_to_selection_end(); void play_selection(); private: Ui::InteractiveCuttingDialog *ui; MediaPlayerWidget *player; RangeSelector *m_rangeSel; TimeRangeEdit *m_rangeEdit; void load_settings(); void save_settings(); }; #endif // INTERACTIVECUTTINGDIALOG_H qwinff-master/src/ui/interactivecuttingdialog.ui000066400000000000000000000122171347323557400225170ustar00rootroot00000000000000 InteractiveCuttingDialog 0 0 857 600 Cutting QFrame::StyledPanel QFrame::Raised QFrame::StyledPanel QFrame::Raised Mark as Begin :/actions/icons/mark.png:/actions/icons/mark.png Seek to Begin :/actions/icons/seek_to_begin.png:/actions/icons/seek_to_begin.png 0 0 Play Selection :/actions/icons/preview_play.png:/actions/icons/preview_play.png Mark as End :/actions/icons/mark.png:/actions/icons/mark.png Seek to End :/actions/icons/seek_to_end.png:/actions/icons/seek_to_end.png QFrame::StyledPanel QFrame::Raised Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() InteractiveCuttingDialog accept() 222 280 157 274 buttonBox rejected() InteractiveCuttingDialog reject() 290 286 286 274 qwinff-master/src/ui/mainwindow.cpp000066400000000000000000000644141347323557400177530ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "mainwindow.h" #include "ui_mainwindow.h" #include "convertlist.h" #include "addtaskwizard.h" #include "aboutffmpegdialog.h" #include "optionsdialog.h" #include "aboutdialog.h" #include "poweroffdialog.h" #include "updatedialog.h" #include "services/paths.h" #include "services/notification.h" #include "services/powermanagement.h" #include "converter/mediaconverter.h" #include "converter/presets.h" #include "services/updatechecker.h" #include "services/constants.h" #include "services/settingtimer.h" #include "interactivecuttingdialog.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include MainWindow::MainWindow(QWidget *parent, const QStringList& fileList) : QMainWindow(parent), ui(new Ui::MainWindow), m_presets(new Presets(this)), m_list(new ConvertList(m_presets, this)), m_argv_input_files(fileList), m_elapsedTimeLabel(new QLabel(this)), m_timer(new QTimer(this)), m_poweroff_button(0), m_poweroff_actiongroup(0), m_update_checker(new UpdateChecker(this)) { ui->setupUi(this); connect(m_list, SIGNAL(task_finished(int)), this, SLOT(task_finished(int))); connect(m_list, SIGNAL(all_tasks_finished()), this, SLOT(all_tasks_finished())); connect(m_list, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(slotListContextMenu(QPoint))); connect(m_list, SIGNAL(itemSelectionChanged()), this, SLOT(refresh_action_states())); connect(m_timer, SIGNAL(timeout()), this, SLOT(timerEvent())); connect(m_list, SIGNAL(started()), this, SLOT(conversion_started())); connect(m_list, SIGNAL(stopped()), this, SLOT(conversion_stopped())); connect(m_update_checker, SIGNAL(receivedResult(int)), this, SLOT(received_update_result(int))); connect(ui->btnStartConversion, SIGNAL(clicked()), this, SLOT(slotStartConversion())); setup_widgets(); setup_menus(); setup_poweroff_button(); setup_toolbar(Constants::getSpaceSeparatedList("ToolbarEntries")); setup_statusbar(); setup_appicon(); load_settings(); refresh_action_states(); if (!check_execute_conditions()) { // Close the window immediately after it has started. QTimer::singleShot(0, this, SLOT(close())); } else { QTimer::singleShot(0, this, SLOT(window_ready())); } } MainWindow::~MainWindow() { delete ui; } void MainWindow::window_ready() { if (!m_argv_input_files.isEmpty()) { add_files(m_argv_input_files); } QSettings settings; if (settings.value("options/check_update_on_startup", Constants::getBool("CheckUpdateOnStartup")).toBool()) { if (ask_for_update_permission()) m_update_checker->checkUpdate(); } refresh_status(); } void MainWindow::task_finished(int /*exitcode*/) { // if (exitcode == 0) { // succeed // QMessageBox::information(this, this->windowTitle() // , tr("Conversion finished successfully.") // , QMessageBox::Ok); // } else { // failed // QMessageBox::critical(this, this->windowTitle() // , tr("Conversion failed.") // , QMessageBox::Ok); // } } void MainWindow::all_tasks_finished() { Notification::send(this, "QWinFF", tr("All tasks have finished."), NotifyLevel::INFO); activateWindow(); // notify the user (make taskbar entry blink) refresh_action_states(); if (PowerManagement::implemented() && m_poweroff_button->isChecked()) { // show poweroff dialog if (PoweroffDialog(this).exec(get_poweroff_behavior()) == QDialog::Accepted) { save_settings(); // save settings in case of power failure } } } // Menu Events void MainWindow::slotAddFiles() { add_files(); } void MainWindow::slotOptions() { OptionsDialog dialog(this); dialog.exec(); } void MainWindow::slotSetTools() { OptionsDialog dialog(this); dialog.exec_tools(); } void MainWindow::slotExit() { this->close(); } void MainWindow::slotStartConversion() { if (m_list->isEmpty()) { QMessageBox::information(this, this->windowTitle(), tr("Nothing to convert."), QMessageBox::Ok); } else { m_list->start(); } } void MainWindow::slotStopConversion() { m_list->stop(); } void MainWindow::slotSetConversionParameters() { if (m_list->selectedCount() > 0) { m_list->editSelectedParameters(); } } // Open the output folder of the file. void MainWindow::slotOpenOutputFolder() { const ConversionParameters *param = m_list->getCurrentIndexParameter(); if (param) { QString folder_path = QFileInfo(param->destination).path(); if (QFileInfo(folder_path).exists()) { QDesktopServices::openUrl(QUrl::fromLocalFile(folder_path)); } } } void MainWindow::slotAboutQt() { QMessageBox::aboutQt(this); } void MainWindow::slotAboutFFmpeg() { AboutFFmpegDialog(this).exec(); } void MainWindow::slotAbout() { AboutDialog(this).exec(); } void MainWindow::slotShowUpdateDialog() { if (ask_for_update_permission()) { UpdateChecker update_checker; UpdateDialog(this).exec(update_checker); } } void MainWindow::slotCut() { m_list->cutSelectedTask(); } void MainWindow::slotListContextMenu(QPoint /*pos*/) { refresh_action_states(); QMenu menu; menu.addAction(ui->actionOpenOutputFolder); menu.addSeparator(); menu.addAction(ui->actionRemoveSelectedItems); menu.addSeparator(); menu.addAction(ui->actionRetry); menu.addAction(ui->actionRetryAll); menu.addSeparator(); menu.addAction(ui->actionShowErrorMessage); menu.addAction(ui->actionChangeOutputFilename); menu.addAction(ui->actionChangeOutputDirectory); menu.addAction(ui->actionSetParameters); menu.addAction(ui->actionCut); menu.exec(QCursor::pos()); } // Events void MainWindow::closeEvent(QCloseEvent *event) { if (m_list->isBusy()) { int reply = QMessageBox::warning(this, this->windowTitle(), tr("Conversion is still in progress. Abort?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); if (reply == QMessageBox::No) { event->ignore(); return; } } m_list->stop(); save_settings(); } void MainWindow::timerEvent() { refresh_status(); } void MainWindow::conversion_started() { m_elapsedTimeLabel->clear(); m_timer->start(1000); refresh_status(); refresh_action_states(); } void MainWindow::conversion_stopped() { m_timer->stop(); refresh_status(); refresh_action_states(); } void MainWindow::update_poweroff_button(int id) { const char *icon_id = ""; QString title = ""; QString status_tip = ""; switch (id) { case PowerManagement::SHUTDOWN: icon_id = ":/actions/icons/system_shutdown.png"; title = tr("Shutdown"); status_tip = tr("Shutdown when all tasks are done."); break; case PowerManagement::SUSPEND: icon_id = ":/actions/icons/system_suspend.png"; title = tr("Suspend"); status_tip = tr("Suspend when all tasks are done."); break; case PowerManagement::HIBERNATE: icon_id = ":/actions/icons/system_hibernate.png"; title = tr("Hibernate"); status_tip = tr("Hibernate when all tasks are done."); break; default: Q_ASSERT(!"Incorrect id! Be sure to handle every power action in switch()."); } m_poweroff_button->setIcon(QIcon(icon_id)); m_poweroff_button->setToolTip(status_tip); m_poweroff_button->setStatusTip(status_tip); ui->actionPoweroff->setIcon(QIcon(icon_id)); ui->actionPoweroff->setText(title); ui->actionPoweroff->setStatusTip(status_tip); } void MainWindow::received_update_result(int status) { if (status == UpdateChecker::UpdateFound) { QSettings settings; SettingTimer timer("mainwindow/last_remind_update_time"); const int seconds_per_day = 86400; const unsigned int prev_update_version = settings.value("mainwindow/last_remind_update_version").toUInt(); const unsigned int new_update_version = m_update_checker->versionId(); const bool timeout = !timer.isValid() || timer.elapsedSeconds() > seconds_per_day; const bool is_different_version = new_update_version != prev_update_version; // Show update dialog only if the update dialog has not been shown // for a certain period or the version is different. if (timeout || is_different_version) { UpdateDialog(this).exec(*m_update_checker); timer.restart(); settings.setValue("mainwindow/last_remind_update_version", new_update_version); } } } // Private Methods /* Check if all execute conditions are met. This function should return true if all the conditions are met and return false if any of the conditions fails. */ bool MainWindow::check_execute_conditions() { QString errmsg; // check external programs if (!MediaConverter::checkExternalPrograms(errmsg)) { QMessageBox::critical(this, this->windowTitle(), errmsg); #ifdef TOOLS_IN_DATA_PATH return false; // fatal: ffmpeg should be in the data path but doesn't exist #else QTimer::singleShot(0, this, SLOT(slotSetTools())); #endif } // load presets if (!load_presets()) return false; return true; } // We should respect the user and ask before connecting to the Internet to // check for updates. // If the user says yes, remember the decision and don't ask next time. // If the user says no, disable checking for updates on startup. bool MainWindow::ask_for_update_permission() { const char *setting_key = "update_permission"; QSettings settings; bool permitted = settings.value(setting_key, false).toBool(); if (permitted) return true; QString msg = tr("This program is going to check for updates online. " "Do you allow this program to use the Internet " "to check for updates?"); int reply = QMessageBox::information(this, windowTitle(), msg, QMessageBox::Yes, QMessageBox::No); if (reply == QMessageBox::Yes) { // permitted settings.setValue(setting_key, true); // don't ask next time return true; } else { // rejected // disable auto update because the user probably doesn't like it settings.setValue("options/check_update_on_startup", false); return false; } } // Popup wizard to add tasks. void MainWindow::add_files() { AddTaskWizard wizard(m_presets, this); if (wizard.exec_openfile() == QDialog::Accepted) { // Add all input files to the list. const QList ¶mList = wizard.getConversionParameters(); m_list->addTasks(paramList); } } void MainWindow::add_files(const QStringList &fileList) { AddTaskWizard wizard(m_presets, this); if (wizard.exec(fileList) == QDialog::Accepted) { // Add all input files to the list. const QList ¶mList = wizard.getConversionParameters(); m_list->addTasks(paramList); } } void MainWindow::setup_widgets() { // list ui->layoutListPlaceholder->addWidget(m_list); m_list->adjustSize(); m_list->setContextMenuPolicy(Qt::CustomContextMenu); ui->lblTime->clear(); } void MainWindow::setup_menus() { /* === Menu Events === */ // File connect(ui->actionAddFiles, SIGNAL(triggered()), this, SLOT(slotAddFiles())); connect(ui->actionOptions, SIGNAL(triggered()), this, SLOT(slotOptions())); connect(ui->actionExit, SIGNAL(triggered()), this, SLOT(slotExit())); // Edit connect(ui->menuEdit, SIGNAL(aboutToShow()), this, SLOT(refresh_action_states())); connect(ui->actionRemoveSelectedItems, SIGNAL(triggered()), m_list, SLOT(removeSelectedItems())); connect(ui->actionRemoveCompletedItems, SIGNAL(triggered()), m_list, SLOT(removeCompletedItems())); connect(ui->actionClearList, SIGNAL(triggered()), m_list, SLOT(clear())); connect(ui->actionSetParameters, SIGNAL(triggered()), this, SLOT(slotSetConversionParameters())); connect(ui->actionOpenOutputFolder, SIGNAL(triggered()), this, SLOT(slotOpenOutputFolder())); connect(ui->actionChangeOutputFilename, SIGNAL(triggered()), m_list, SLOT(changeSelectedOutputFile())); connect(ui->actionChangeOutputDirectory, SIGNAL(triggered()), m_list, SLOT(changeSelectedOutputDirectory())); connect(ui->actionShowErrorMessage, SIGNAL(triggered()), m_list, SLOT(showErrorMessage())); connect(ui->actionCut, SIGNAL(triggered()), SLOT(slotCut())); ui->actionCut->setVisible(InteractiveCuttingDialog::available()); // Convert connect(ui->menuConvert, SIGNAL(aboutToShow()), this, SLOT(refresh_action_states())); connect(ui->actionStartConversion, SIGNAL(triggered()), this, SLOT(slotStartConversion())); connect(ui->actionStopConversion, SIGNAL(triggered()), this, SLOT(slotStopConversion())); connect(ui->actionRetry, SIGNAL(triggered()), m_list, SLOT(retrySelectedItems())); connect(ui->actionRetry, SIGNAL(triggered()), this, SLOT(refresh_action_states())); connect(ui->actionRetryAll, SIGNAL(triggered()), m_list, SLOT(retryAll())); connect(ui->actionRetryAll, SIGNAL(triggered()), this, SLOT(refresh_action_states())); // About connect(ui->actionAboutQt, SIGNAL(triggered()), this, SLOT(slotAboutQt())); connect(ui->actionAboutFFmpeg, SIGNAL(triggered()), this, SLOT(slotAboutFFmpeg())); connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(slotAbout())); connect(ui->actionCheckUpdate, SIGNAL(triggered()), this, SLOT(slotShowUpdateDialog())); } void MainWindow::setup_toolbar(const QStringList &entries) { Q_ASSERT(m_poweroff_button && "setup_poweroff_button() must be called first"); // construct a table of available actions // map action name to action pointer QMap toolbar_table; #define ADD_ACTION(name) toolbar_table[QString(#name).toUpper()] = ui->action ## name ADD_ACTION(AddFiles); ADD_ACTION(Options); ADD_ACTION(Exit); ADD_ACTION(RemoveSelectedItems); ADD_ACTION(RemoveCompletedItems); ADD_ACTION(ClearList); ADD_ACTION(OpenOutputFolder); ADD_ACTION(SetParameters); ADD_ACTION(ChangeOutputFilename); ADD_ACTION(ChangeOutputDirectory); // TODO: rename to "folder" ADD_ACTION(ShowErrorMessage); ADD_ACTION(StartConversion); ADD_ACTION(StopConversion); ADD_ACTION(Retry); ADD_ACTION(RetryAll); // "Shutdown" button is special, so we don't add it here #define POWEROFF_BUTTON_NAME "POWEROFF" ADD_ACTION(AboutQt); ADD_ACTION(AboutFFmpeg); ADD_ACTION(About); ADD_ACTION(CheckUpdate); for (int i=0; itoolBar->addWidget(m_poweroff_button); else if (entry == "|") // separator ui->toolBar->addSeparator(); else if (toolbar_table.contains(entry)) ui->toolBar->addAction(toolbar_table[entry]); } } void MainWindow::setup_statusbar() { ui->statusBar->addPermanentWidget(m_elapsedTimeLabel); } /* * Setup the poweroff button and menu. * The poweroff button is handled differently from other menu and buttons. * Its icon and title changes as the action changes. * When this function finishes, m_poweroff_button will point to the constructed * button widget. */ void MainWindow::setup_poweroff_button() { QToolButton *button = new QToolButton(this); QMenu *menu = new QMenu(this); QList actionList; QSignalMapper *signalMapper = new QSignalMapper(this); QActionGroup *checkGroup = new QActionGroup(this); m_poweroff_button = button; m_poweroff_actiongroup = checkGroup; // Insert all actions into the list. for (int i=0; iaddAction(action); action->setCheckable(true); action->setActionGroup(checkGroup); } button->setMenu(menu); button->setPopupMode(QToolButton::MenuButtonPopup); // ensure that the toolbutton and actionPoweroff are both checkable ui->actionPoweroff->setCheckable(true); button->setCheckable(true); button->setChecked(false); /* Synchronize the checked state of the toolbutton and actionPoweroff. This cyclic connection doesn't cause an infinite loop because toggled(bool) is only triggered when the checked() state changes. */ connect(button, SIGNAL(toggled(bool)) , ui->actionPoweroff, SLOT(setChecked(bool))); connect(ui->actionPoweroff, SIGNAL(toggled(bool)) , button, SLOT(setChecked(bool))); // update the poweroff button when the action changes for (int i=0; isetMapping(action, i); connect(action, SIGNAL(triggered()) , signalMapper, SLOT(map())); connect(signalMapper, SIGNAL(mapped(int)) , this, SLOT(update_poweroff_button(int))); } actionList.at(0)->trigger(); /* Check if the power management functions are available. If not, hide poweroff button and menus. */ if (!PowerManagement::implemented()) { m_poweroff_button->setVisible(false); ui->actionPoweroff->setVisible(false); } } // Fill window icon with multiple sizes of images. void MainWindow::setup_appicon() { QIcon icon; QDir iconDir = QDir(":/app/icons/"); QStringList fileList = iconDir.entryList(); QRegExp pattern("^qwinff_[0-9]+x[0-9]+\\.png$"); foreach (QString file, fileList) { if (pattern.indexIn(file) >= 0) { icon.addPixmap(QPixmap(iconDir.absoluteFilePath(file))); } } setWindowIcon(icon); ui->actionAbout->setIcon(icon); } void MainWindow::set_poweroff_behavior(int action) { if (action >= PowerManagement::ACTION_COUNT) action = PowerManagement::SHUTDOWN; m_poweroff_actiongroup->actions().at(action)->trigger(); } int MainWindow::get_poweroff_behavior() { for (int i=0; iactions().size(); i++) { if (m_poweroff_actiongroup->actions().at(i)->isChecked()) return i; } return PowerManagement::SHUTDOWN; } bool MainWindow::load_presets() { // The default preset file is located in /presets.xml QString default_preset_file = QDir(Paths::dataPath()).absoluteFilePath("presets.xml"); QString local_preset_file; if (!Constants::getBool("Portable")) { // non-portable app // rename local preset file created by older versions of qwinff // operation: mv ~/.qwinff/presets.xml ~/.qwinff/presets.xml.old QString local_preset_file_old = QDir(QDir::homePath()).absoluteFilePath(".qwinff/presets.xml"); if (QFile(local_preset_file_old).exists()) { QFile::remove(local_preset_file_old + ".old"); if (QFile::rename(local_preset_file_old, local_preset_file_old + ".old")) { qDebug() << local_preset_file_old + " is no longer used, " "rename to " + local_preset_file_old + ".old"; } } // use global preset temporarily local_preset_file = default_preset_file; } else { // portable app local_preset_file = default_preset_file; } QSettings settings; bool removeUnavailableCodecs = settings.value("options/hideformats", true).toBool(); // Load the preset file from the user's home directory // The presets are loaded once and shared between objects // that need the information. if (!m_presets->readFromFile(local_preset_file, removeUnavailableCodecs)) { QMessageBox::critical(this, this->windowTitle(), tr("Failed to load preset file. " "The application will quit now.")); return false; } return true; } // Hide unused actions void MainWindow::refresh_action_states() { int selected_file_count = m_list->selectedCount(); // Hide actionSetParameters if no item in m_list is selected. bool hide_SetParameters = (selected_file_count == 0); // Hide actionStartConversion if the conversion is in progress. bool hide_StartConversion = m_list->isBusy(); // Hide actionStopConversion if nothing is being converted. bool hide_StopConversion = !m_list->isBusy(); // Show actionOpenOutputFolder only if 1 file is selected. bool hide_OpenFolder = (selected_file_count <= 0); // Hide actionRemoveSelectedItems if no file is selected. bool hide_RemoveSelectedItems = (selected_file_count == 0); bool hide_Retry = (selected_file_count == 0); bool hide_RetryAll = (m_list->isEmpty()); bool hide_ClearList = (m_list->isEmpty()); bool hide_ChangeOutputFilename = m_list->selectedCount() != 1; bool hide_ChangeOutputDirectory = m_list->selectedCount() <= 0; /* Show actionShowErrorMessage if and only if one task is selected and the state of the selected task is FAILED */ bool hide_ShowErrorMessage = (selected_file_count != 1 || !m_list->selectedTaskFailed()); ui->actionSetParameters->setDisabled(hide_SetParameters); ui->actionStartConversion->setDisabled(hide_StartConversion); ui->actionStopConversion->setDisabled(hide_StopConversion); ui->actionOpenOutputFolder->setDisabled(hide_OpenFolder); ui->actionRemoveSelectedItems->setDisabled(hide_RemoveSelectedItems); ui->actionRetry->setDisabled(hide_Retry); ui->actionRetryAll->setDisabled(hide_RetryAll); ui->actionClearList->setDisabled(hide_ClearList); ui->actionChangeOutputFilename->setDisabled(hide_ChangeOutputFilename); ui->actionChangeOutputDirectory->setDisabled(hide_ChangeOutputDirectory); ui->actionShowErrorMessage->setDisabled(hide_ShowErrorMessage); ui->actionCut->setEnabled(selected_file_count == 1); // cut only 1 file at a time } void MainWindow::load_settings() { QSettings settings; restoreGeometry(settings.value("mainwindow/geometry").toByteArray()); restoreState(settings.value("mainwindow/state").toByteArray()); int poweroff_behavior = settings.value("options/poweroff_behavior" , PowerManagement::SHUTDOWN).toInt(); set_poweroff_behavior(poweroff_behavior); } void MainWindow::save_settings() { QSettings settings; settings.setValue("mainwindow/geometry", saveGeometry()); settings.setValue("mainwindow/state", saveState()); settings.setValue("options/poweroff_behavior", get_poweroff_behavior()); } void MainWindow::refresh_status() { refresh_statusbar(); refresh_titlebar(); } void MainWindow::refresh_statusbar() { if (m_list->isBusy()) { int total_seconds = m_list->elapsedTime() / 1000; int hours = total_seconds / 3600; int minutes = (total_seconds / 60) % 60; int seconds = total_seconds % 60; QString timeinfo = tr("Elapsed Time: %1 h %2 m %3 s") .arg(hours).arg(minutes).arg(seconds); //m_elapsedTimeLabel->setText(timeinfo); ui->lblTime->setText(timeinfo); } else { //m_elapsedTimeLabel->clear(); //ui->lblTime->clear(); } } void MainWindow::refresh_titlebar() { const int task_count = m_list->count(); const int finished_task_count = m_list->finishedCount(); if (finished_task_count < task_count && m_list->isBusy()) { //: Converting the %1-th file in %2 files. %2 is the number of files. setWindowTitle(tr("Converting %1/%2") .arg(finished_task_count+1).arg(task_count)); } else { setWindowTitle(tr("QWinFF")); } } qwinff-master/src/ui/mainwindow.h000066400000000000000000000060651347323557400174160ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef MAINWINDOW_H #define MAINWINDOW_H #include #include class ConvertList; namespace Ui { class MainWindow; } QT_BEGIN_NAMESPACE class QLabel; class QToolButton; class QActionGroup; QT_END_NAMESPACE class Presets; class UpdateChecker; class MainWindow : public QMainWindow { Q_OBJECT public: /*! Construct the main window * @param parent the parent of the QObject * @param fileList the input files from argv */ explicit MainWindow(QWidget *parent = 0, const QStringList& fileList = QStringList()); ~MainWindow(); private slots: void window_ready(); //!< The main window is completely loaded. void task_finished(int); void all_tasks_finished(); // Menu Events void slotAddFiles(); void slotOptions(); void slotSetTools(); void slotExit(); void slotStartConversion(); void slotStopConversion(); void slotSetConversionParameters(); void slotOpenOutputFolder(); void slotAboutQt(); void slotAboutFFmpeg(); void slotAbout(); void slotShowUpdateDialog(); void slotCut(); void slotListContextMenu(QPoint); void refresh_action_states(); void timerEvent(); ///< 1-second timer event void conversion_started(); void conversion_stopped(); void update_poweroff_button(int); void received_update_result(int); protected: void closeEvent(QCloseEvent *); private: Ui::MainWindow *ui; Presets *m_presets; //!< the preset loader that lives throughout the program ConvertList *m_list; const QStringList m_argv_input_files; QLabel *m_elapsedTimeLabel; QTimer *m_timer; QToolButton *m_poweroff_button; QActionGroup *m_poweroff_actiongroup; UpdateChecker *m_update_checker; bool check_execute_conditions(); bool ask_for_update_permission(); void add_files(); void add_files(const QStringList& files); void setup_widgets(); void setup_menus(); void setup_toolbar(const QStringList& entries); void setup_statusbar(); void setup_poweroff_button(); void setup_appicon(); void set_poweroff_behavior(int); int get_poweroff_behavior(); bool load_presets(); void load_settings(); void save_settings(); void refresh_status(); void refresh_statusbar(); void refresh_titlebar(); }; #endif // MAINWINDOW_H qwinff-master/src/ui/mainwindow.ui000066400000000000000000000301171347323557400175770ustar00rootroot00000000000000 MainWindow 0 0 491 378 QWinFF QLayout::SetDefaultConstraint 20 20 ElapsedTime Qt::Horizontal 40 20 0 0 Start conversion process. Start conversion process. &Start :/actions/icons/start.png:/actions/icons/start.png 0 0 491 27 &File &Convert &About &Edit TopToolBarArea false :/actions/icons/add.png:/actions/icons/add.png &Add Files Add files for conversion. Ctrl+N :/actions/icons/exit.png:/actions/icons/exit.png E&xit Exit the program. :/actions/icons/start.png:/actions/icons/start.png &Start Start conversion process. F9 :/actions/icons/stop.png:/actions/icons/stop.png S&top Stop conversion process. :/actions/icons/settings.png:/actions/icons/settings.png Set &Parameters Set Parameters Edit conversion parameters of selected files. :/app/icons/qt.png:/app/icons/qt.png About &Qt About Qt :/actions/icons/open_folder.png:/actions/icons/open_folder.png &Open Output Folder Open output folder of the selected file. :/app/icons/ffmpeg.png:/app/icons/ffmpeg.png About &FFmpeg About FFmpeg :/actions/icons/remove.png:/actions/icons/remove.png &Remove Selected Remove all selected items in the list. :/actions/icons/remove_completed.png:/actions/icons/remove_completed.png R&emove Completed Remove Completed Items Remove all completed items in the list. :/actions/icons/clear.png:/actions/icons/clear.png &Clear List Clear List Remove all items in the list. :/actions/icons/retry.png:/actions/icons/retry.png &Retry Retry Retry selected tasks. :/actions/icons/retry_all.png:/actions/icons/retry_all.png Retry &All Retry all tasks. :/actions/icons/configure.png:/actions/icons/configure.png &Options Options About Q&WinFF About This Program Change Output &Filename Change the output filename of the selected item. Change Output &Directory Change the output directory of the selected items. Poweroff Show Error &Message :/actions/icons/check_update.png:/actions/icons/check_update.png Check For &Updates :/actions/icons/cut.png:/actions/icons/cut.png Cut qwinff-master/src/ui/mediaplayerwidget.cpp000066400000000000000000000154371347323557400213000ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include #include #include "mediaplayerwidget.h" #include "ui_mediaplayerwidget.h" #include "myqmpwidget.h" #include "services/constants.h" #define DEFAULT_VOLUME Constants::getInteger("MediaPlayer/DefaultVolume") #define SLIDER_STYLESHEET Constants::getString("MediaPlayer/SliderStyle") #define MINIMUM_HEIGHT 210 #define MAX_VOLUME 100 #define VOLUME_SETTING_KEY "mediaplayer/volume" namespace { QString sec2hms(int seconds) { int h = seconds / 3600; int m = (seconds % 3600) / 60; int s = (seconds % 60); QString result; result.sprintf("%02d:%02d:%02d", h, m, s); return result; } } MediaPlayerWidget::MediaPlayerWidget(QWidget *parent) : QWidget(parent), ui(new Ui::MediaPlayerWidget), m_playUntil(-1) { ui->setupUi(this); ui->slideVolume->setRange(0, MAX_VOLUME); mplayer = new MyQMPwidget(this); mplayer->start(); mplayer->setAcceptDrops(false); mplayer->setSeekSlider(ui->slideSeek); mplayer->setVolumeSlider(ui->slideVolume); ui->layoutPlayer->addWidget(mplayer); ui->slideSeek->setStyleSheet(SLIDER_STYLESHEET); connect(mplayer, SIGNAL(stateChanged(int)), SLOT(playerStateChanged())); connect(ui->slideSeek, SIGNAL(valueChanged(int)), SLOT(seekSliderChanged())); connect(ui->btnPlayPause, SIGNAL(clicked()), SLOT(togglePlayPause())); connect(ui->btnBack, SIGNAL(clicked()), SLOT(seekBack())); connect(ui->btnForward, SIGNAL(clicked()), SLOT(seekForward())); connect(ui->btnReset, SIGNAL(clicked()), SLOT(resetPosition())); setMinimumHeight(MINIMUM_HEIGHT); load_volume(); } MediaPlayerWidget::~MediaPlayerWidget() { save_volume(); delete ui; } bool MediaPlayerWidget::ok() const { MyQMPwidget::MediaInfo info = mplayer->mediaInfo(); return info.ok; } double MediaPlayerWidget::duration() const { MyQMPwidget::MediaInfo info = mplayer->mediaInfo(); if (info.ok) return info.length; else return 0; } double MediaPlayerWidget::position() const { return mplayer->tell(); } // public slots void MediaPlayerWidget::load(const QString &url) { m_file = url; mplayer->load(url); ui->slideVolume->setValue(m_volume); mplayer->pause(); } void MediaPlayerWidget::reload() { load(m_file); } void MediaPlayerWidget::play() { mplayer->play(); ui->btnPlayPause->setFocus(); refreshButtonState(); } void MediaPlayerWidget::playRange(int begin_sec, int end_sec) { if (mplayer->state() == MyQMPwidget::IdleState) reload(); if (begin_sec >= 0) seek(begin_sec); else seek(0); if (end_sec >= 0) m_playUntil = end_sec; else m_playUntil = -1; play(); } void MediaPlayerWidget::pause() { mplayer->pause(); ui->btnPlayPause->setFocus(); refreshButtonState(); } void MediaPlayerWidget::seek(int sec) { mplayer->seek(sec); } void MediaPlayerWidget::seek_and_pause(int sec) { // seek() is asynchrous. If call mplayer->seek(); mplayer->pause(); in a row, // the latter command will be ignored because seek() is not done yet. mplayer->seek(sec); m_playUntil = sec; // seek() is asynchrouse } void MediaPlayerWidget::togglePlayPause() { switch (mplayer->state()) { case MyQMPwidget::IdleState: reload(); if (ui->slideSeek->value() < ui->slideSeek->maximum()) { // user seeks mplayer->seek(ui->slideSeek->value()); } else { // otherwise rewind to begin ui->slideSeek->setValue(0); } pause(); break; case MyQMPwidget::PlayingState: pause(); break; case MyQMPwidget::PausedState: play(); break; default: break; } } // events void MediaPlayerWidget::wheelEvent(QWheelEvent *event) { int numDegrees = event->delta() / 8; // delta is in eighths of a degree if (event->orientation() == Qt::Vertical) { if (numDegrees >= 0) { seekForward(); } else { seekBackward(); } } } void MediaPlayerWidget::mousePressEvent(QMouseEvent */*event*/) { togglePlayPause(); } // private slots void MediaPlayerWidget::refreshTimeDisplay() { MyQMPwidget::MediaInfo info = mplayer->mediaInfo(); int duration, position, remaining; if (info.ok) { duration = info.length; position = mplayer->tell(); if (position < 0) position = 0; remaining = duration - position; } else { duration = position = remaining = 0; } ui->lblPosition->setText(QString("%1 / %2") .arg(sec2hms(position)) .arg(sec2hms(duration))); ui->lblRemaining->setText(QString("-%1").arg(sec2hms(remaining))); } void MediaPlayerWidget::refreshButtonState() { QString button_icon = ":/actions/icons/media-playback-start"; switch (mplayer->state()) { case MyQMPwidget::PlayingState: button_icon = ":/actions/icons/media-playback-pause"; break; default: break; } ui->btnPlayPause->setIcon(QIcon(button_icon)); } void MediaPlayerWidget::playerStateChanged() { refreshTimeDisplay(); refreshButtonState(); emit stateChanged(); } void MediaPlayerWidget::seekSliderChanged() { refreshTimeDisplay(); if (m_playUntil >= 0 && position() >= m_playUntil) { // reaches temporary pause position m_playUntil = -1; pause(); } } void MediaPlayerWidget::seekBackward() { mplayer->seek(-3, MyQMPwidget::RelativeSeek); } void MediaPlayerWidget::seekForward() { mplayer->seek(3, MyQMPwidget::RelativeSeek); } void MediaPlayerWidget::resetPosition() { mplayer->seek(0); } void MediaPlayerWidget::load_volume() { QSettings settings; m_volume = DEFAULT_VOLUME; if (settings.contains(VOLUME_SETTING_KEY)) m_volume = settings.value(VOLUME_SETTING_KEY).toInt(); if (m_volume < 0) m_volume = 0; if (m_volume > MAX_VOLUME) m_volume = MAX_VOLUME; } void MediaPlayerWidget::save_volume() { m_volume = ui->slideVolume->value(); QSettings().setValue(VOLUME_SETTING_KEY, m_volume); } qwinff-master/src/ui/mediaplayerwidget.h000066400000000000000000000056341347323557400207430ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef MEDIAPLAYERWIDGET_H #define MEDIAPLAYERWIDGET_H #include namespace Ui { class MediaPlayerWidget; } class MyQMPwidget; class MediaPlayerWidget : public QWidget { Q_OBJECT public: explicit MediaPlayerWidget(QWidget *parent = 0); ~MediaPlayerWidget(); bool ok() const; double duration() const; double position() const; signals: void stateChanged(); public slots: /** * @brief Load media for playing from @a url. * * @param url path of the file */ void load(const QString& url); /** * @brief Reload previously loaded file. */ void reload(); /** * @brief Start playing the loaded file. */ void play(); /** * @brief Play the media file from @a begin_sec to @a end_sec. * The playback will pause as soon as @c position reaches @a end_sec. * The range of the slider is not modified, as opposed to @c setRangeLimit(). * * @param begin_sec the beginning point in seconds. -1 means play from beginning * @param end_sec the end point in seconds. -1 means play until end */ void playRange(int begin_sec, int end_sec); /** * @brief Seek to @a sec and start playing. * * @param sec position in seconds */ void seek(int sec); /** * @brief Seek to @a sec and pause. * @param sec */ void seek_and_pause(int sec); /** * @brief Pause the media playback. */ void pause(); /** * @brief Toggle between Pause and Play. */ void togglePlayPause(); protected: void wheelEvent(QWheelEvent *); void mousePressEvent(QMouseEvent *); private slots: void refreshTimeDisplay(); void refreshButtonState(); void playerStateChanged(); void seekSliderChanged(); void seekBackward(); void seekForward(); void resetPosition(); private: Ui::MediaPlayerWidget *ui; MyQMPwidget *mplayer; QString m_file; // media playback will stop when position() reaches m_playUntil int m_playUntil; int m_volume; Q_DISABLE_COPY(MediaPlayerWidget) void load_volume(); void save_volume(); }; #endif // MEDIAPLAYERWIDGET_H qwinff-master/src/ui/mediaplayerwidget.ui000066400000000000000000000103751347323557400211270ustar00rootroot00000000000000 MediaPlayerWidget 0 0 590 300 :/actions/icons/media-playback-start.png:/actions/icons/media-playback-start.png :/actions/icons/media-skip-backward.png:/actions/icons/media-skip-backward.png :/actions/icons/media-seek-backward.png:/actions/icons/media-seek-backward.png :/actions/icons/media-seek-forward.png:/actions/icons/media-seek-forward.png Qt::Horizontal 40 20 :/actions/icons/audio_volume.png 100 Qt::Horizontal Position Qt::Horizontal 40 20 Remaining Qt::Horizontal btnBack slideSeek btnForward slideVolume btnPlayPause qwinff-master/src/ui/myqmpwidget.cpp000066400000000000000000000026611347323557400201420ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "myqmpwidget.h" #include "converter/exepath.h" MyQMPwidget::MyQMPwidget(QWidget *parent) : QMPwidget(parent) { QMPwidget::setMPlayerPath(ExePath::getPath("mplayer")); // disable mouse doubleclick event by not passing it to QMPwidget } MyQMPwidget::~MyQMPwidget() { } void MyQMPwidget::mouseDoubleClickEvent(QMouseEvent */*event*/) { // disable mouse doubleclick event by not passing it to QMPwidget } void MyQMPwidget::keyPressEvent(QKeyEvent */*event*/) { // disable key events by not passing them to QMPwidget } void MyQMPwidget::load(const QString &url) { QMPwidget::load(url); } void MyQMPwidget::pause() { QMPwidget::writeCommand("pause"); } qwinff-master/src/ui/myqmpwidget.h000066400000000000000000000023431347323557400176040ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef MYQMPWIDGET_H #define MYQMPWIDGET_H #include "qmpwidget/qmpwidget.h" class MyQMPwidget : public QMPwidget { Q_OBJECT public: explicit MyQMPwidget(QWidget *parent = 0); virtual ~MyQMPwidget(); protected: virtual void mouseDoubleClickEvent(QMouseEvent *event); virtual void keyPressEvent(QKeyEvent *event); signals: public slots: void load(const QString &url); void pause(); private: Q_DISABLE_COPY(MyQMPwidget) }; #endif // MYQMPWIDGET_H qwinff-master/src/ui/optionsdialog.cpp000066400000000000000000000077641347323557400204570ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "optionsdialog.h" #include "ui_optionsdialog.h" #include "converter/exepath.h" #include "converter/mediaconverter.h" #include "services/constants.h" #include #include #include OptionsDialog::OptionsDialog(QWidget *parent) : QDialog(parent), ui(new Ui::OptionsDialog) { ui->setupUi(this); ui->spinThreads->setMinimum(1); // at least 1 thread #ifndef TOOLS_IN_DATA_PATH // initialize program list ui->toolTable->verticalHeader()->setVisible(false); ui->toolTable->horizontalHeader()->setStretchLastSection(true); QList program_list = ExePath::getPrograms(); for (int i=0; itoolTable->insertRow(i); ui->toolTable->setItem(i, 0, new QTableWidgetItem(program_list[i])); ui->toolTable->setItem(i, 1, new QTableWidgetItem("")); // make tool name not editable QTableWidgetItem *item = ui->toolTable->item(i, 0); item->setFlags(item->flags() ^ Qt::ItemIsEditable); } #else ui->tabTools->setVisible(false); #endif } OptionsDialog::~OptionsDialog() { delete ui; } int OptionsDialog::exec() { read_fields(); bool accepted = (QDialog::exec() == QDialog::Accepted); if (accepted) { write_fields(); } return accepted; } int OptionsDialog::exec_tools() { ui->tabWidget->setCurrentIndex(ui->tabWidget->indexOf(ui->tabTools)); return exec(); } void OptionsDialog::read_fields() { QSettings settings; ui->spinThreads->setValue(settings.value("options/threads", DEFAULT_THREAD_COUNT).toInt()); ui->chkHideFormats->setChecked(settings.value("options/hideformats", true).toBool()); ui->chkCheckUpdates->setChecked(settings.value("options/check_update_on_startup", Constants::getBool("CheckUpdateOnStartup")).toBool()); ui->chkAutoStartConversion->setChecked(settings.value("options/auto_start_conversion", Constants::getBool("AutoStartConversion")).toBool()); #ifndef TOOLS_IN_DATA_PATH // ExePath to table const int count = ui->toolTable->rowCount(); for (int i=0; itoolTable->item(i, 0); QTableWidgetItem *item_path = ui->toolTable->item(i, 1); item_path->setText(ExePath::getPath(item_program->text())); } #endif } void OptionsDialog::write_fields() { QSettings settings; settings.setValue("options/threads", ui->spinThreads->value()); settings.setValue("options/hideformats", ui->chkHideFormats->isChecked()); settings.setValue("options/check_update_on_startup", ui->chkCheckUpdates->isChecked()); settings.setValue("options/auto_start_conversion", ui->chkAutoStartConversion->isChecked()); #ifndef TOOLS_IN_DATA_PATH // table to ExePath const int count = ui->toolTable->rowCount(); for (int i=0; itoolTable->item(i, 0); QTableWidgetItem *item_path = ui->toolTable->item(i, 1); ExePath::setPath(item_program->text(), item_path->text()); } // check programs QString errmsg; if (!MediaConverter::checkExternalPrograms(errmsg)) { QMessageBox::critical(this, this->windowTitle(), errmsg); } #endif } qwinff-master/src/ui/optionsdialog.h000066400000000000000000000022171347323557400201100ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef OPTIONSDIALOG_H #define OPTIONSDIALOG_H #include namespace Ui { class OptionsDialog; } class OptionsDialog : public QDialog { Q_OBJECT public: explicit OptionsDialog(QWidget *parent = 0); ~OptionsDialog(); int exec(); int exec_tools(); private: Ui::OptionsDialog *ui; void read_fields(); void write_fields(); }; #endif // OPTIONSDIALOG_H qwinff-master/src/ui/optionsdialog.ui000066400000000000000000000130241347323557400202740ustar00rootroot00000000000000 OptionsDialog 0 0 485 382 Options 0 General Check for updates on program startup Automatically start conversion after adding files to the list. Start conversion automatically Qt::Vertical 20 40 FFmpeg QFormLayout::ExpandingFieldsGrow Number of threads to use in conversion <html><head/><body><p>Hide output formats that are not available in the current ffmpeg installation. It is recommended to turn this option on unless you are sure that QWinFF has failed to detect available formats. (requires restarting QWinFF to take effect)</p></body></html> Hide unavailable formats (requires restarting) Tools You have to restart QWinFF for the changes to take effect. true false false 2 Name Command Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() OptionsDialog accept() 252 377 157 274 buttonBox rejected() OptionsDialog reject() 320 377 286 274 qwinff-master/src/ui/poweroffdialog.cpp000066400000000000000000000120011347323557400205670ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include #include #include #include #include "poweroffdialog.h" #include "ui_poweroffdialog.h" #include "services/powermanagement.h" #include "services/constants.h" PoweroffDialog::PoweroffDialog(QWidget *parent) : QDialog(parent), ui(new Ui::PoweroffDialog), m_timer(new QTimer(this)) { ui->setupUi(this); connect(ui->btnExecute, SIGNAL(clicked()) , this, SLOT(btnExecute_click())); connect(ui->btnCancel, SIGNAL(clicked()) , this, SLOT(btnCancel_click())); connect(this, SIGNAL(accepted()) , this, SLOT(dialog_accepted())); connect(this, SIGNAL(rejected()) , this, SLOT(dialog_rejected())); connect(m_timer, SIGNAL(timeout()) , this, SLOT(timer_event())); // setup timer m_timer->setInterval(1000); // 1 second m_timer->setSingleShot(false); // always execute the timer m_timer->stop(); // topmost frameless window setWindowFlags(Qt::Window | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::ToolTip); } PoweroffDialog::~PoweroffDialog() { delete ui; } int PoweroffDialog::exec(int action) { const char *icon_id = ""; QString button_text = ""; switch (action) { case PowerManagement::SHUTDOWN: //: Shutdown the computer button_text = tr("Shutdown immediately"); icon_id = ":/actions/icons/system_shutdown"; break; case PowerManagement::SUSPEND: //: Suspend the computer (sleep to ram, standby) button_text = tr("Suspend immediately"); icon_id = ":/actions/icons/system_suspend"; break; case PowerManagement::HIBERNATE: //: Hibernate the computer (sleep to disk, completely poweroff) button_text = tr("Hibernate immediately"); icon_id = ":/actions/icons/system_hibernate"; break; default: Q_ASSERT(!"Incorrect id! Be sure to handle every power action in switch()."); } ui->btnExecute->setIcon(QIcon(icon_id)); ui->btnExecute->setText(button_text); m_action = action; m_time = Constants::getInteger("PoweroffTimeout"); m_timer->start(); refresh_message(); adjustSize(); // center window in screen const QRect screen = QApplication::desktop()->screenGeometry(); move(screen.center() - this->rect().center()); return QDialog::exec(); } int PoweroffDialog::exec() { return QDialog::Rejected; } void PoweroffDialog::show() { } void PoweroffDialog::btnExecute_click() { accept(); } void PoweroffDialog::btnCancel_click() { reject(); } void PoweroffDialog::dialog_accepted() { m_timer->stop(); m_success = PowerManagement::sendRequest(m_action); if (!m_success) { QString action_str; switch (m_action) { case PowerManagement::SHUTDOWN: //: Shutdown the computer action_str = tr("Shutdown"); break; case PowerManagement::SUSPEND: //: Suspend the computer (sleep to ram, standby) action_str = tr("Suspend"); break; case PowerManagement::HIBERNATE: //: Hibernate the computer (sleep to disk, completely poweroff) action_str = tr("Hibernate"); break; default: Q_ASSERT(!"Incorrect id! Be sure to handle every power action in switch()."); } QMessageBox::critical(this, windowTitle(), tr("Operation Failed: %1").arg(action_str)); } } void PoweroffDialog::dialog_rejected() { m_timer->stop(); } void PoweroffDialog::timer_event() { if (--m_time <= 0) { m_timer->stop(); accept(); } refresh_message(); } void PoweroffDialog::refresh_message() { QString msg; switch (m_action) { case PowerManagement::SHUTDOWN: msg = tr("Shutting down in %1 seconds").arg(m_time); break; case PowerManagement::SUSPEND: msg = tr("Suspending in %1 seconds").arg(m_time); break; case PowerManagement::HIBERNATE: msg = tr("Hibernating in %1 seconds").arg(m_time); break; default: Q_ASSERT(!"Incorrect id! Be sure to handle every power action in switch()."); } ui->lblMessage->setText(msg); } qwinff-master/src/ui/poweroffdialog.h000066400000000000000000000026271347323557400202510ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef POWEROFFDIALOG_H #define POWEROFFDIALOG_H #include namespace Ui { class PoweroffDialog; } class QTimer; class PoweroffDialog : public QDialog { Q_OBJECT public: explicit PoweroffDialog(QWidget *parent = 0); ~PoweroffDialog(); public slots: int exec(int action); private slots: int exec(); void show(); void btnExecute_click(); void btnCancel_click(); void dialog_accepted(); void dialog_rejected(); void timer_event(); void refresh_message(); private: Ui::PoweroffDialog *ui; QTimer *m_timer; int m_action; bool m_success; int m_time; }; #endif // POWEROFFDIALOG_H qwinff-master/src/ui/poweroffdialog.ui000066400000000000000000000042431347323557400204330ustar00rootroot00000000000000 PoweroffDialog Qt::ApplicationModal 0 0 343 128 QWinFF 0 0 :/app/icons/qwinff_64x64.png false lblMessage Qt::AlignCenter DoAction Cancel :/actions/icons/dialog_cancel.png:/actions/icons/dialog_cancel.png qwinff-master/src/ui/previewdialog.cpp000066400000000000000000000060501347323557400204300ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include #include #include "mediaplayerwidget.h" #include "previewdialog.h" #include "converter/exepath.h" #include "ui_previewdialog.h" namespace { QString sec2hms(int seconds) { int h = seconds / 3600; int m = (seconds % 3600) / 60; int s = (seconds % 60); QString result; result.sprintf("%02d:%02d:%02d", h, m, s); return result; } } PreviewDialog::PreviewDialog(QWidget *parent) : QDialog(parent), ui(new Ui::PreviewDialog), m_player(new MediaPlayerWidget(this)) { ui->setupUi(this); ui->layoutPlayer->addWidget(m_player); connect(ui->btnPlayRange, SIGNAL(clicked()), SLOT(playSelectedRange())); } PreviewDialog::~PreviewDialog() { delete ui; } bool PreviewDialog::available() { return ExePath::checkProgramAvailability("mplayer"); } int PreviewDialog::exec(const QString &filename, bool from_begin, int begin_sec, bool to_end, int end_sec) { if (available()) { m_beginTime = from_begin ? -1 : begin_sec; m_endTime = to_end ? -1 : end_sec; m_player->load(filename); playSelectedRange(); refreshRange(); return exec(); } else { QMessageBox::critical(this, windowTitle(), tr("%1 not found").arg("mplayer")); return QDialog::Rejected; } } int PreviewDialog::exec() { load_settings(); int status = QDialog::exec(); save_settings(); return status; } void PreviewDialog::playSelectedRange() { m_player->playRange(m_beginTime, m_endTime); } void PreviewDialog::refreshRange() { //: noun, the beginning of the video QString begin_time = tr("Begin"); //: noun, the end of the video QString end_time = tr("End"); if (m_beginTime >= 0) begin_time = sec2hms(m_beginTime); if (m_endTime >= 0) end_time = sec2hms(m_endTime); //: play the video from time %1 to time %2. %1 and %2 are time in hh:mm:ss format. ui->btnPlayRange->setText(tr("Play %1~%2").arg(begin_time).arg(end_time)); } void PreviewDialog::load_settings() { QSettings settings; restoreGeometry(settings.value("preview_dialog/geometry").toByteArray()); } void PreviewDialog::save_settings() { QSettings settings; settings.setValue("preview_dialog/geometry", saveGeometry()); } qwinff-master/src/ui/previewdialog.h000066400000000000000000000027201347323557400200750ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef PREVIEWDIALOG_H #define PREVIEWDIALOG_H #include namespace Ui { class PreviewDialog; } class MediaPlayerWidget; class PreviewDialog : public QDialog { Q_OBJECT public: explicit PreviewDialog(QWidget *parent = 0); ~PreviewDialog(); static bool available(); public slots: int exec(const QString &filename, bool from_begin, int begin_sec, bool to_end, int end_sec); private slots: int exec(); void playSelectedRange(); void refreshRange(); private: Ui::PreviewDialog *ui; MediaPlayerWidget *m_player; int m_beginTime; int m_endTime; void load_settings(); void save_settings(); }; #endif // PREVIEWDIALOG_H qwinff-master/src/ui/previewdialog.ui000066400000000000000000000037361347323557400202730ustar00rootroot00000000000000 PreviewDialog 0 0 800 600 Dialog Play Selected Range :/actions/icons/preview_play.png:/actions/icons/preview_play.png Qt::Horizontal QDialogButtonBox::Ok buttonBox accepted() PreviewDialog accept() 248 254 157 274 buttonBox rejected() PreviewDialog reject() 316 260 286 274 qwinff-master/src/ui/progressbar.cpp000066400000000000000000000070241347323557400201220ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include #include #include #include "progressbar.h" #include "services/constants.h" ProgressBar::ProgressBar(QWidget *parent) : QWidget(parent), m_percentage(0), m_active(false), m_show_text(false) { //qDebug() << "ProgressBar Constructor"; } ProgressBar::~ProgressBar() { //qDebug() << "ProgressBar Destructor"; } void ProgressBar::setValue(unsigned int value) { if (value != m_percentage) { m_percentage = (value <= 100) ? value : 100; this->repaint(); } m_show_text = false; } void ProgressBar::showText(const QString &str) { m_show_text = true; m_text = str; this->repaint(); } void ProgressBar::setActive(bool active) { if (m_active != active) { m_active = active; this->repaint(); } } bool ProgressBar::isActive() const { return m_active; } void ProgressBar::paintEvent(QPaintEvent*) { QPainter painter(this); QPen pen; QColor color_margin = Constants::getColor("ProgressBar/Colors/Margin"); QColor color_center = Constants::getColor("ProgressBar/Colors/Center"); QColor color_border = Constants::getColor("ProgressBar/Colors/Border"); QColor color_text = Constants::getColor("ProgressBar/Colors/Text"); QColor color_background = Constants::getColor("ProgressBar/Colors/Background"); //if (m_percentage >= 0) { QRect rect_region(0, 0, width()-1, height()-1); // draw background QBrush background_brush(color_background); painter.setPen(Qt::NoPen); painter.setBrush(background_brush); painter.drawRect(rect_region); if (m_percentage > 0) { // draw progress bar QRect rect_progress(0, 0, (width()*m_percentage/100)-1, height()-1); QLinearGradient gradient(0, 0, 0, rect_progress.bottom()); gradient.setColorAt(0, color_margin); gradient.setColorAt(0.5, color_center); gradient.setColorAt(1, color_margin); painter.setBrush(gradient); painter.setPen(Qt::NoPen); // Don't draw the border. painter.drawRect(rect_progress); } // Restore the pen such that the text can be rendered. pen.setColor(color_text); painter.setPen(pen); if (!m_show_text) { // show percentage painter.drawText(rect_region, QString("%1\%").arg(m_percentage) , QTextOption(Qt::AlignCenter)); } else { // show custom text painter.drawText(rect_region, m_text, QTextOption(Qt::AlignCenter)); } if (m_active) { pen.setColor(color_border); painter.setPen(pen); painter.setBrush(Qt::NoBrush); // disable filling painter.drawRect(0, 0, width()-1, height()-1); } } } qwinff-master/src/ui/progressbar.h000066400000000000000000000030521347323557400175640ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef PROGRESSBAR_H #define PROGRESSBAR_H #include class ProgressBar : public QWidget { Q_OBJECT public: explicit ProgressBar(QWidget *parent = 0); ~ProgressBar(); /*! @brief Set the value of the progress @param value The percentage of the progress(0~100) */ void setValue(unsigned int value); /*! @brief Show the string on the progress bar. @param str string to display @note The string will be displayed until the next value update. */ void showText(const QString& str); void setActive(bool active); bool isActive() const; signals: public slots: private: unsigned int m_percentage; bool m_active; bool m_show_text; QString m_text; void paintEvent(QPaintEvent*); }; #endif // PROGRESSBAR_H qwinff-master/src/ui/rangeselector.cpp000066400000000000000000000154531347323557400204330ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include #include #include "rangeselector.h" #include "services/constants.h" // rounded rectangle radius #define ROUNDRECT_RADIUS Constants::getFloat("RangeSelector/RoundRectRadius") #define COLOR(name) Constants::getColor("RangeSelector/Colors/" name) // container color #define COLOR_CONT_BG_GRAD_1 COLOR("Container/BackgroundGradient1") #define COLOR_CONT_BG_GRAD_2 COLOR("Container/BackgroundGradient2") #define COLOR_CONT_OUT_BORDER COLOR("Container/OuterBorder") #define COLOR_CONT_IN_BORDER COLOR("Container/InnerBorder") // range indicator color #define COLOR_RANGE_BG_GRAD_1 COLOR("Range/BackgroundGradient1") #define COLOR_RANGE_BG_GRAD_2 COLOR("Range/BackgroundGradient2") #define COLOR_RANGE_OUT_BORDER COLOR("Range/OuterBorder") #define COLOR_RANGE_IN_BORDER COLOR("Range/InnerBorder") RangeSelector::RangeSelector(QWidget *parent) : QWidget(parent), m_max(255), m_min(0), m_val_begin(0), m_val_end(128), m_mouseDown(false) { setMinimumSize(20, 20); setMaximumHeight(20); emit beginValueChanged(m_val_begin); emit endValueChanged(m_val_end); } RangeSelector::~RangeSelector() { } int RangeSelector::beginValue() const { return m_val_begin; } int RangeSelector::endValue() const { return m_val_end; } int RangeSelector::minValue() const { return m_min; } int RangeSelector::maxValue() const { return m_max; } void RangeSelector::setBeginValue(int value) { if (m_val_begin != value && m_min <= value && value <= m_max && value < m_val_end) { m_val_begin = value; repaint(); emit valueChanged(); emit beginValueChanged(m_val_begin); } } void RangeSelector::setEndValue(int value) { if (m_val_end != value && m_min <= value && value <= m_max && value > m_val_begin) { m_val_end = value; repaint(); emit valueChanged(); emit endValueChanged(m_val_end); } } void RangeSelector::setMaxValue(int maxValue) { if (maxValue > m_min) { m_max = maxValue; m_val_begin = m_min; m_val_end = m_max; repaint(); } } void RangeSelector::mouseDown(QPoint pos) { int newValue = pos_to_val(pos.x()); m_dragEdge = edgeToMove(pos); if (m_dragEdge == EDGE_BEGIN) setBeginValue(newValue); else setEndValue(newValue); } void RangeSelector::mouseDrag(QPoint newpos) { const int newval = pos_to_val(newpos.x()); switch (m_dragEdge) { case EDGE_BEGIN: setBeginValue(newval); break; case EDGE_END: setEndValue(newval); break; default: Q_ASSERT(!"undefined value: m_dragEdge"); } } void RangeSelector::mouseClick(QPoint) { } int RangeSelector::pos_begin() { return width() * m_val_begin / (m_max - m_min); } int RangeSelector::pos_end() { return width() * m_val_end / (m_max - m_min); } int RangeSelector::pos_to_val(int pos) { if (width() > 0) return pos * (m_max - m_min) / width(); else return 0; } // which edge to be moved if the user clicks at pos // returns EDGE_BEGIN or EDGE_END RangeSelector::Edge RangeSelector::edgeToMove(const QPoint &pos) { const int newval = pos_to_val(pos.x()); const int distance_to_begin = abs(newval - m_val_begin); const int distance_to_end = abs(newval - m_val_end); if (distance_to_begin < distance_to_end) return EDGE_BEGIN; // pos is closer to the begin edge else return EDGE_END; // pos is closer to the end edge } void RangeSelector::drawContainer(QPainter &painter, QPen &pen) { // background QRect background_region(0, 0, width(), height()); QLinearGradient background_gradient(0, 0, 0, background_region.bottom()); background_gradient.setColorAt(0.0, COLOR_CONT_BG_GRAD_1); background_gradient.setColorAt(1.0, COLOR_CONT_BG_GRAD_2); painter.setBrush(background_gradient); painter.setPen(Qt::NoPen); painter.drawRoundedRect(background_region, ROUNDRECT_RADIUS, ROUNDRECT_RADIUS); // outer border QRect outer_border_region(0, 0, width()-1, height()-1); pen.setColor(COLOR_CONT_OUT_BORDER); painter.setPen(pen); painter.drawRoundedRect(outer_border_region, ROUNDRECT_RADIUS, ROUNDRECT_RADIUS); // inner border QRect inner_border_region(1, 1, width()-3, height()-3); pen.setColor(COLOR_CONT_IN_BORDER); painter.setPen(pen); painter.drawRoundedRect(inner_border_region, ROUNDRECT_RADIUS, ROUNDRECT_RADIUS); } void RangeSelector::drawRange(QPainter &painter, QPen &pen) { const int begin = pos_begin(), end = pos_end(); // background QRect background_region(begin, 0, end - begin - 1, height() - 1); QLinearGradient background_gradient(0, 0, 0, background_region.bottom()); background_gradient.setColorAt(0.0, COLOR_RANGE_BG_GRAD_1); background_gradient.setColorAt(1.0, COLOR_RANGE_BG_GRAD_2); painter.setBrush(background_gradient); painter.setPen(Qt::NoPen); painter.drawRoundedRect(background_region, ROUNDRECT_RADIUS, ROUNDRECT_RADIUS); // outer border QRect outer_border_region(begin, 0, end-begin-1, height()-1); pen.setColor(COLOR_RANGE_OUT_BORDER); painter.setPen(pen); painter.drawRoundedRect(outer_border_region, ROUNDRECT_RADIUS, ROUNDRECT_RADIUS); // inner border QRect inner_border_region(begin+1, 1, end-begin-3, height()-3); pen.setColor(COLOR_RANGE_IN_BORDER); painter.setPen(pen); painter.drawRoundedRect(inner_border_region, ROUNDRECT_RADIUS, ROUNDRECT_RADIUS); } void RangeSelector::paintEvent(QPaintEvent *) { QPainter painter(this); QPen pen; drawContainer(painter, pen); drawRange(painter, pen); } void RangeSelector::mousePressEvent(QMouseEvent *e) { m_mouseDownPos = e->pos(); m_mouseDown = true; mouseDown(m_mouseDownPos); } void RangeSelector::mouseReleaseEvent(QMouseEvent *e) { if (m_mouseDown && m_mouseDownPos == e->pos()) { mouseClick(m_mouseDownPos); // click event } m_mouseDown = false; } void RangeSelector::mouseMoveEvent(QMouseEvent *e) { if (m_mouseDown) { mouseDrag(e->pos()); } } qwinff-master/src/ui/rangeselector.h000066400000000000000000000040161347323557400200710ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef RANGESELECTOR_H #define RANGESELECTOR_H #include class RangeSelector : public QWidget { Q_OBJECT public: explicit RangeSelector(QWidget *parent = 0); ~RangeSelector(); int beginValue() const; int endValue() const; int minValue() const; int maxValue() const; signals: void valueChanged(); void beginValueChanged(int newvalue); void endValueChanged(int newvalue); public slots: void setBeginValue(int beginValue); void setEndValue(int beginValue); void setMaxValue(int maxValue); private slots: void mouseDown(QPoint pos); void mouseDrag(QPoint newpos); void mouseClick(QPoint pos); private: Q_DISABLE_COPY(RangeSelector) enum Edge {EDGE_BEGIN, EDGE_END}; int pos_begin(); int pos_end(); int pos_to_val(int pos); Edge edgeToMove(const QPoint &pos); void drawContainer(QPainter& painter, QPen& pen); void drawRange(QPainter& painter, QPen& pen); void paintEvent(QPaintEvent *); void mousePressEvent(QMouseEvent *); void mouseReleaseEvent(QMouseEvent *); void mouseMoveEvent(QMouseEvent *); int m_max; int m_min; int m_val_begin; int m_val_end; Edge m_dragEdge; bool m_mouseDown; QPoint m_mouseDownPos; }; #endif // RANGESELECTOR_H qwinff-master/src/ui/rangewidgetbinder.cpp000066400000000000000000000040021347323557400212460ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include "rangewidgetbinder.h" RangeWidgetBinder::RangeWidgetBinder(RangeSelector *sel, TimeRangeEdit *edit, QObject *parent) : QObject(parent), m_selector(sel), m_rangeEdit(edit) { connect(m_selector, SIGNAL(valueChanged()), SLOT(sync_sel_to_edit())); connect(m_rangeEdit, SIGNAL(valueChanged()), SLOT(sync_edit_to_sel())); } // sync m_selector (visual) value to m_rangeEdit (text) void RangeWidgetBinder::sync_sel_to_edit() { int begin_time = m_selector->beginValue(); int end_time = m_selector->endValue(); bool from_begin = (begin_time == 0); bool to_end = (end_time == m_selector->maxValue()); m_rangeEdit->setBeginTime(begin_time); m_rangeEdit->setEndTime(end_time); m_rangeEdit->setFromBegin(from_begin); m_rangeEdit->setToEnd(to_end); } // sync m_rangeEdit (text) value to m_selector (visual) void RangeWidgetBinder::sync_edit_to_sel() { int begin_time = m_rangeEdit->beginTime(); int end_time = m_rangeEdit->endTime(); if (m_rangeEdit->fromBegin()) begin_time = 0; if (m_rangeEdit->toEnd()) end_time = m_rangeEdit->maxTime(); m_selector->setBeginValue(begin_time); m_selector->setEndValue(end_time); } qwinff-master/src/ui/rangewidgetbinder.h000066400000000000000000000025461347323557400207260ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef RANGEWIDGETBINDER_H #define RANGEWIDGETBINDER_H #include #include "rangeselector.h" #include "timerangeedit.h" /** * @brief Automatically sync between a RangeSelector and a TimeRangeEdit. */ class RangeWidgetBinder : public QObject { Q_OBJECT public: explicit RangeWidgetBinder(RangeSelector *sel, TimeRangeEdit *edit, QObject *parent = 0); private slots: void sync_sel_to_edit(); void sync_edit_to_sel(); private: RangeSelector *m_selector; TimeRangeEdit *m_rangeEdit; }; #endif // RANGEWIDGETBINDER_H qwinff-master/src/ui/timerangeedit.cpp000066400000000000000000000104421347323557400204100ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include #include #include #include #include #include "timerangeedit.h" #define SECS_TO_QTIME(s) QTime(0, 0).addSecs(s) #define QTIME_TO_SECS(t) (t).hour()*3600 + (t).minute()*60 + (t).second() TimeRangeEdit::TimeRangeEdit(QWidget *parent) : QWidget(parent), m_timeBegin(new QTimeEdit(this)), m_timeEnd(new QTimeEdit(this)), m_chkFromBegin(new QCheckBox(this)), m_chkToEnd(new QCheckBox(this)) { m_chkFromBegin->setText(tr("From Begin")); m_chkToEnd->setText(tr("To End")); m_timeBegin->setDisplayFormat("hh:mm:ss"); m_timeBegin->setSelectedSection(QTimeEdit::SecondSection); m_timeEnd->setDisplayFormat("hh:mm:ss"); m_timeEnd->setSelectedSection(QTimeEdit::SecondSection); QHBoxLayout *main_layout = new QHBoxLayout(this); QVBoxLayout *left_layout = new QVBoxLayout(this); QVBoxLayout *right_layout = new QVBoxLayout(this); left_layout->addWidget(m_chkFromBegin); left_layout->addWidget(m_timeBegin); right_layout->addWidget(m_chkToEnd); right_layout->addWidget(m_timeEnd); main_layout->addLayout(left_layout); main_layout->addLayout(right_layout); setLayout(main_layout); connect(m_timeBegin, SIGNAL(timeChanged(QTime)), SLOT(time_changed())); connect(m_timeEnd, SIGNAL(timeChanged(QTime)), SLOT(time_changed())); connect(m_chkFromBegin, SIGNAL(toggled(bool)), SLOT(time_changed())); connect(m_chkToEnd, SIGNAL(toggled(bool)), SLOT(time_changed())); setFromBegin(true); setToEnd(true); } int TimeRangeEdit::maxTime() const { return QTIME_TO_SECS(m_timeEnd->maximumTime()); } int TimeRangeEdit::beginTime() const { if (m_chkFromBegin->isChecked()) return QTIME_TO_SECS(m_timeBegin->minimumTime()); else return QTIME_TO_SECS(m_timeBegin->time()); } int TimeRangeEdit::endTime() const { if (m_chkToEnd->isChecked()) return QTIME_TO_SECS(m_timeEnd->maximumTime()); else return QTIME_TO_SECS(m_timeEnd->time()); } bool TimeRangeEdit::fromBegin() const { return m_chkFromBegin->isChecked(); } bool TimeRangeEdit::toEnd() const { return m_chkToEnd->isChecked(); } void TimeRangeEdit::setMaxTime(int sec) { m_timeBegin->setMinimumTime(SECS_TO_QTIME(0)); m_timeEnd->setMaximumTime(SECS_TO_QTIME(sec)); emit valueChanged(); } void TimeRangeEdit::setBeginTime(int sec) { if (sec != beginTime()) { m_timeBegin->setTime(SECS_TO_QTIME(sec)); m_chkFromBegin->setChecked((sec == 0)); } } void TimeRangeEdit::setEndTime(int sec) { if (sec != endTime()) { m_timeEnd->setTime(SECS_TO_QTIME(sec)); m_chkToEnd->setChecked((sec == QTIME_TO_SECS(m_timeEnd->maximumTime()))); } } void TimeRangeEdit::setFromBegin(bool from_begin) { m_chkFromBegin->setChecked(from_begin); } void TimeRangeEdit::setToEnd(bool to_end) { m_chkToEnd->setChecked(to_end); } void TimeRangeEdit::time_changed() { // the latest allowed begin time is end time QTime begin_max = m_timeEnd->time().addSecs(-1); if (m_chkToEnd->isChecked()) begin_max = m_timeEnd->maximumTime(); // end time is media duration // the earliest allowed end time is begin time QTime end_min = m_timeBegin->time().addSecs(1); if (m_chkFromBegin->isChecked()) end_min = SECS_TO_QTIME(0); // begin time is zero m_timeBegin->setMaximumTime(begin_max); m_timeEnd->setMinimumTime(end_min); m_timeBegin->setDisabled(m_chkFromBegin->isChecked()); m_timeEnd->setDisabled(m_chkToEnd->isChecked()); emit valueChanged(); } qwinff-master/src/ui/timerangeedit.h000066400000000000000000000043551347323557400200630ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef TIMERANGEEDIT_H #define TIMERANGEEDIT_H #include QT_BEGIN_NAMESPACE class QTimeEdit; class QCheckBox; QT_END_NAMESPACE class TimeRangeEdit : public QWidget { Q_OBJECT public: explicit TimeRangeEdit(QWidget *parent = 0); int maxTime() const; /** * @brief begin time * @return If fromBegin() is false, this function returns the begin time. * If fromBegin() is true, the return value is 0. */ int beginTime() const; /** * @brief endTime * @return If toEnd() is false, this fuction returns the end time. * If toEnd() is true, the return value is the same as maxTime(). */ int endTime() const; /** * @brief whether the "from begin" checkbox is checked */ bool fromBegin() const; /** * @brief whether the "to end" checkbox is checked */ bool toEnd() const; public slots: /** * @brief Set the maximum duration to @a sec * @param sec the maximum duration in seconds */ void setMaxTime(int sec); /** * @brief Set the begin time to @a sec */ void setBeginTime(int sec); /** * @brief Set the end time to @a sec */ void setEndTime(int sec); void setFromBegin(bool); void setToEnd(bool); signals: void valueChanged(); private slots: void time_changed(); private: QTimeEdit *m_timeBegin; QTimeEdit *m_timeEnd; QCheckBox *m_chkFromBegin; QCheckBox *m_chkToEnd; }; #endif // TIMERANGEEDIT_H qwinff-master/src/ui/updatedialog.cpp000066400000000000000000000112271347323557400202330ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #include #include "updatedialog.h" #include "ui_updatedialog.h" #include "services/updatechecker.h" #include "services/constants.h" UpdateDialog::UpdateDialog(QWidget *parent) : QDialog(parent), m_updateChecker(0), ui(new Ui::UpdateDialog) { ui->setupUi(this); connect(ui->btnReleaseNotes, SIGNAL(toggled(bool)), this, SLOT(slotToggleReleaseNotes(bool))); connect(ui->chkCheckUpdateOnStartup, SIGNAL(toggled(bool)), this, SLOT(slotToggleCheckUpdateOnStartup(bool))); // read check_update_on_startup setting to chkCheckUpdateOnStartup ui->chkCheckUpdateOnStartup->setChecked( QSettings().value("options/check_update_on_startup", Constants::getBool("CheckUpdateOnStartup")).toBool()); } UpdateDialog::~UpdateDialog() { delete ui; } int UpdateDialog::exec(UpdateChecker &uc) { m_updateChecker = &uc; return exec(); } int UpdateDialog::exec() { Q_ASSERT(m_updateChecker); connect(m_updateChecker, SIGNAL(receivedResult(int)), this, SLOT(slotReceivedUpdateResult(int))); if (!m_updateChecker->hasUpdate()) checkUpdate(); else updateFound(); int status = QDialog::exec(); disconnect(m_updateChecker, SIGNAL(receivedResult(int)), this, SLOT(slotReceivedUpdateResult(int))); return status; } void UpdateDialog::checkUpdate() { Q_ASSERT(m_updateChecker); ui->btnReleaseNotes->setVisible(false); ui->btnReleaseNotes->setChecked(false); ui->txtReleaseNotes->setVisible(false); ui->lblStatus->setText(tr("Downloading update information...")); m_updateChecker->checkUpdate(); resizeToFit(); } void UpdateDialog::updateFound() { Q_ASSERT(m_updateChecker); ui->btnReleaseNotes->setVisible(true); ui->btnReleaseNotes->setChecked(false); ui->txtReleaseNotes->setVisible(false); ui->lblStatus->setText(get_status()); ui->txtReleaseNotes->setHtml(m_updateChecker->releaseNotes()); resizeToFit(); } void UpdateDialog::slotReceivedUpdateResult(int result) { Q_ASSERT(m_updateChecker); if (m_updateChecker->hasUpdate()) { updateFound(); return; } QString message; switch (result) { case UpdateChecker::ConnectionError: message = tr("Cannot connect to server."); break; case UpdateChecker::DataError: message = tr("Failed to parse the received data."); break; case UpdateChecker::UpdateNotFound: message = tr("You are already using the latest version of QWinFF."); break; default: message = tr("An unknown error has occurred."); } ui->lblStatus->setText(QString("%1").arg(message)); resizeToFit(); } void UpdateDialog::slotToggleReleaseNotes(bool checked) { // show/hide release notes ui->txtReleaseNotes->setVisible(checked); resizeToFit(); } void UpdateDialog::slotToggleCheckUpdateOnStartup(bool checked) { QSettings settings; settings.setValue("options/check_update_on_startup", checked); } void UpdateDialog::resizeToFit() { resize(width(), ui->lblStatus->height() + ui->btnReleaseNotes->height()); resize(sizeHint()); } QString UpdateDialog::get_status() { QStringList result; result << tr("A new version of QWinFF has been released!"); result << "
"; //: %1 is version number, %2 is the project homepage result << tr("Version %1 is available at %2.") .arg(m_updateChecker->versionName(), link(m_updateChecker->downloadPage())); QString url = m_updateChecker->downloadUrl(); if (!url.isEmpty()) { result << "
"; result << tr("You can download this version using the link:"); result << "

"; result << link(m_updateChecker->downloadUrl()); } return result.join(""); } QString UpdateDialog::link(const QString &s) { return QString("%1").arg(s); } qwinff-master/src/ui/updatedialog.h000066400000000000000000000027271347323557400177050ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef UPDATEDIALOG_H #define UPDATEDIALOG_H #include namespace Ui { class UpdateDialog; } class UpdateChecker; class UpdateDialog : public QDialog { Q_OBJECT public: explicit UpdateDialog(QWidget *parent = 0); ~UpdateDialog(); public slots: int exec(UpdateChecker& uc); private slots: int exec(); void checkUpdate(); void updateFound(); void slotReceivedUpdateResult(int result); void slotToggleReleaseNotes(bool checked); void slotToggleCheckUpdateOnStartup(bool checked); void resizeToFit(); private: UpdateChecker *m_updateChecker; Ui::UpdateDialog *ui; QString get_status(); QString link(const QString &s); }; #endif // UPDATEDIALOG_H qwinff-master/src/ui/updatedialog.ui000066400000000000000000000056471347323557400200770ustar00rootroot00000000000000 UpdateDialog 0 0 400 300 0 0 lblStatus true Qt::Horizontal 40 20 Show &Release Notes true false false Check for updates on program startup Qt::Horizontal QDialogButtonBox::Ok buttonBox accepted() UpdateDialog accept() 248 254 157 274 buttonBox rejected() UpdateDialog reject() 316 260 286 274 qwinff-master/src/update-translations.sh000077500000000000000000000001711347323557400210040ustar00rootroot00000000000000#!/bin/sh # run lupdate on the project to update translation files cd "`dirname $0`" lupdate -locations none qwinff.pro qwinff-master/src/version.h000066400000000000000000000020111347323557400162750ustar00rootroot00000000000000/* QWinFF - a qt4 gui frontend for ffmpeg * Copyright (C) 2011-2013 Timothy Lin * * 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 . */ #ifndef VERSION_H #define VERSION_H // human-readable version string (VersionName) #define VERSION_STRING "0.2.1" // machine-readable version id (VersionId) // the update-checker compares versions using this integer #define VERSION_INTEGER 21 #endif // VERSION_H qwinff-master/windows_build.bat000077500000000000000000000021251347323557400172220ustar00rootroot00000000000000@echo off set DEST_DIR=.\windows_release :: Save version string to variable %VERSION% for /f "delims=" %%v in ('sh src\get-version.sh') do @set VERSION=%%v pushd src lrelease qwinff.pro qmake mingw32-make release popd :: Create output directory if it does not exist. if not exist "%DEST_DIR%" mkdir "%DEST_DIR%" if not exist "%DEST_DIR%\tools" mkdir "%DEST_DIR%\tools" if not exist "%DEST_DIR%\translations" mkdir "%DEST_DIR%\translations" :: Copy the final executable to the output directory. copy ".\src\release\qwinff.exe" "%DEST_DIR%" :: Copy data files to the output directory. copy ".\src\presets.xml" "%DEST_DIR%" sed "s/\(]*>\)[\t ]*false/\1true/" ".\src\constants.xml" > "%DEST_DIR%/constants.xml" copy ".\src\translations\*.qm" "%DEST_DIR%\translations" copy "COPYING.txt" "%DEST_DIR%\license.txt" copy "CHANGELOG.txt" "%DEST_DIR%\changelog.txt" sed "s/@QWINFF_VERSION@/%VERSION%/" "qwinff.nsi.in" > "%DEST_DIR%\qwinff.nsi" unix2dos "%DEST_DIR%\license.txt" unix2dos "%DEST_DIR%\changelog.txt" @echo Files have been copied to %DEST_DIR% qwinff-master/windows_build_portable.bat000077500000000000000000000004201347323557400211060ustar00rootroot00000000000000@echo off :: build qwinff call windows_build.bat set DEST_DIR=.\windows_release_portable :: copy files to destination mkdir %DEST_DIR% cp -r windows_release/* %DEST_DIR% sed --in-place "s/\(]*>\)[\t ]*false/\1true/" "%DEST_DIR%/constants.xml"