kylin-video/0000755000175000017500000000000013637130602011731 5ustar fengfengkylin-video/man/0000755000175000017500000000000013517016402012502 5ustar fengfengkylin-video/man/kylin-video.10000644000175000017500000000156713517016402015027 0ustar fengfeng.TH kylin-video 1 "19 June 2017" "The Kylin Video Project" "Kylin Video" .SH NAME kylin-video \- The best GUI frontend for MPlayer .SH SYNOPSIS .B kylin-video .SH DESCRIPTION .TP Kylin Video is a GUI media player based on Qt 5, using \fBmplayer\fR(1) as its backend. .PP .SH SEE ALSO \fBmplayer\fR(1) .SH AUTHOR The author of Kylin Video is lixiang . This manual page was written by lixiang for the Kylin project (but may be used by others). Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 2 or any later version published by the Free Software Foundation. On Debian systems, the complete text of the GNU General Public License can be found in \fB/usr/share/common-licenses/GPL\fR. .SH BUGS Please submit bugs to \fBhttps://github.com/ukui/kylin-video/issues\fR. kylin-video/kylin-video.pro0000644000175000017500000000041013605242413014677 0ustar fengfengTEMPLATE = subdirs SUBDIRS = \ src TRANSLATIONS += \ src/translations/kylin-video_zh_CN.ts \ src/translations/kylin-video_pt.ts \ src/translations/kylin-video_fr.ts \ src/translations/kylin-video_ru.ts \ src/translations/kylin-video_bo.ts kylin-video/snap/0000755000175000017500000000000013517016402012670 5ustar fengfengkylin-video/snap/gui/0000755000175000017500000000000013517016402013454 5ustar fengfengkylin-video/snap/gui/kylin-video.desktop0000644000175000017500000000146713517016402017311 0ustar fengfeng[Desktop Entry] Name=Kylin Video Name[zh_CN]=麒麟影音 Comment=A great MPlayer front-end Comment[zh_CN]=麒麟影音 GenericName=Kylin Video GenericName[zh_CN]=麒麟影音 Exec=kylin-video %U Icon=${SNAP}/meta/gui/kylin-video.png MimeType=audio/ac3;audio/mp4;audio/mpeg;audio/vnd.rn-realaudio;audio/vorbis;audio/x-adpcm;audio/x-matroska;audio/x-mp2;audio/x-mp3;audio/x-ms-wma;audio/x-vorbis;audio/x-wav;audio/mpegurl;audio/x-mpegurl;audio/x-pn-realaudio;audio/x-scpls;audio/aac;audio/flac;audio/ogg;video/avi;video/mp4;video/flv;video/mpeg;video/quicktime;video/vnd.rn-realvideo;video/x-matroska;video/x-ms-asf;video/x-msvideo;video/x-ms-wmv;video/x-ogm;video/x-theora;video/webm; Type=Application Categories=Qt;KDE;AudioVideo;Player;Video; Keywords=movie;player;media;kde;qt; X-Ayatana-Desktop-Shortcuts=Screen;Window kylin-video/snap/gui/kylin-video.png0000644000175000017500000001727213517016402016425 0ustar fengfengPNG  IHDR@@R tEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp IDATx7"-3guԊ=sT ~^  Fkwa %Y _'ыdT|vJfP|9}7{IP ggڷ0Ƽ })f@AƋ3lJ7# ?߼~V(qܸv.ma 8Yپ}},g;[Fff?ԣG>|t01 [X/ VߤWϯ5[/+Pk Egi ~b  QP!ZT,TF$x9:3 Lrcc%B}1x.QYݟk>&!1HiA M_ n?嫀Ah0AE(n,odR؁JC0(BҲ"QF_`pl|_@;2BSD~ۃ~Hl H$M 88X;I}Kĩզf@bBhJH-+CeS b\"' !7=yt K㷝nptäMFԷ&1 " 3dJ`AYڸIp;7Mբ?"*HPJ ! ʅ$ m{{?潙;3vc7̝9~} {W*0VTl (lk7 ԪT^x5P%eMZ҂lu(0e4O?*6 |Xi2 SYBLM2:d$EM(5 @!WqƇ yYJddi"OiBk$EDg+>hS"ݭ3/C _kHUb^ Mr޼uŤ/X#Rb_xg hx7RH vS'O}N S0d`+X93)՚/6 yEV4D?/'Sl5eBkL 4>$m{{՛הjs=s(E8.P`h,w=5=0T09,.d1op~Xp6ᄆPӗ_:I[ 0gD;b3qHee+}\97gG `ӆ~/lw4n [q,4k8' %ljb2O< ~=۷)TnPR&\z)srU[f7#g>|/7qF rL_C|d4mm2&ٴ>S$'+ۆhޜsv|80 qw׬\+U{FlYm` RuNP i>䦫+]'wKT24;[9b>=?T(k+4ۯ_p"=:gYcsM=AS?k# CuX ꓻZuĔHLO8 TɆ&Wֹ:oё*Ф.`v>44dk3A8nNV F$T?ݔmܹ1kwhebCcC jDA@#!ZDTB@HD" X"B )4<bx I ?**&U1Z%@yyιwf+?Ng3umȒ+|^`4n &$,l\W \/PSX?5kJa#%ֈa4p(q)uMnsT>;兴-@reY6,GZx<'+{ )kV()&LS+Z˺<"\~6]YC9┤%rfPWFe%8d{\ORJ>ʧ.+Qa05j&mH881;+tO>iN,ĆޥB)߶8$@Q68|z4Jsy[}gV ?5~2EƊjw?]Dn@*~C.@^mGGeAIfՃ/iPXini;Z *UF"cߘWpanfXyx@FީDCNmC~h#tZήS/yݪ=HjʁWETYg)r('B"2W3B,LBlAC1N3 .άQڐ"֨ QL .^ډJhX@^މ V-BI/=tv0 SIݰUİPN=\H/UT55 5Y1{%P7 &Ab-X;|'T x#?Sq$hAk-{qމ/v "nwg|jSFʆ!ӽ`pı5oZ.CL.G>ٖ̥Dbkpx}GkG1t[[7W"e*sw'k! WPoB 4I]sF,ۼkmMlCED_QW]u@%d-mܺқד5_˞~oZN 6݃{D@n_{gip)g}>ԝ0  /8g;3hΜ8ñw$I -BRUutmQ=ơ÷R O"GdM`M[bVo #KڳkZn>dOlhVUfބ_ȉu̒5U PPWɤ ,ɟ-. jegک^("(s"$sN=Mҗ?W~ʀo)N }+ 򈜷 &5F(ZMvNK_* ?^ x Q̌vU6ya[ww/p "k`f7 w>o!g=vN.ZEqѤ4PN,i },4QKRa`KP2ɉZ/ԜF-4eGmu.䧡J-Zm—YI8Vvnv7uk}{.nVFy`2mN Y<ldB6#V4Z3g`e.nkI@.1}1vxgFpoQ7ep㛿Pjl6+3CuqaN*Y@I+>1|amTEpDGp:_ف$ D 1 :t::~~4%1Rs(D2#9?L; , xӌ`_2HB.:ǘc Rcb*Ph7[Y}emWә4[$P45X&P^0x4._<мkBW;h0O[ B$b"(<?lj̀j8DDGX̲=`*WyG"9f~.[mDw0f>(1X i^4m.U@ գ>c"P靲4V{CI*++5cƗVR\|YG aY ݩ`8&(xJ@#3W{li2A5æ=J nĠw&glYa`phϞoe*^k!@O]I.kom,THQT8Qe}a 7ZEFӧMm~Ф#GNcQ*>4K0#2 e~k#C!H$g|>?<ѹm8' ~#SN:aNۚt̾Ǐ:Ag2L!UbuuT?<:mza5oy](D'߷x(3tN8$6'ya6 vB9Hѣ'OӢ>)PD녘e&,Z:{M xgHl9>:k:=d׻QY@]Sv*`(PYטtD Mk2$sQQJyY; Յc{^ٮ/zq)5/ՠW>BP; _E/_gݨɤPZ$\ y|_UU&evJO ĥM͓&Зi::" yne XOpkb05dDBv!CM:f1 ^6\^hlx͸#N1&xg) pR!_[ԕq٤@2xjsm:%w:Lg@_4qeiwƞ s듥ą ]lE._{aM@|1b . 7vJz\ہ{A Wed, 25 Mar 2020 15:32:12 +0800 kylin-video (2.0.1-4) unstable; urgency=medium * Support Key_Space for playback and pause control. * Support preview. * Solve some bugs caused by playlist cleaned. * Solve the problem that URLs in recent playlists cannot be played. * Make play order settings work. * When the mainwindow is set to be set on the top, make the subwindow display normally. * Solve the bug that the playlist is cleared when switching the playback engine. * Fixed the bug that failed to preview video on FT platform. * Solve the bug that when the random number is greater than the total number of playlists, the Prev and Next buttons will fail. * When the newly added file is already in the playlist, will not be prompted to add the failed information. -- lixiang Fri, 21 Feb 2020 15:37:26 +0800 kylin-video (2.0.1-3) unstable; urgency=medium * Fixed that when player is running, cannot right-click the video file to select the player to play. * Update Logo. -- lixiang Tue, 14 Jan 2020 18:09:57 +0800 kylin-video (2.0.1-2) unstable; urgency=medium * Set different driving parameters for different graphics cards on the arm64 platform. * Fixed the bug that audioEqualizerFilter() causes no sound when using MPV to play video. -- lixiang Fri, 06 Dec 2019 09:49:30 +0800 kylin-video (2.0.1-1) unstable; urgency=medium * Remove the useless code. * Debian/control: - Move libcrystalhd3 | firmware-crystalhd from depends to suggests. -- handsome_feng Mon, 23 Sep 2019 19:17:20 +0800 kylin-video (2.0.0-1) unstable; urgency=medium * Supported Interface Size Tension. * Added new files, such as videowindow.cpp, autohidecursorwidget.cpp and displaylayercomposer.cpp. * Add remote controller dbus. * Add equalizer and filter for audio. * Fixed the exception of the esctip. * Access icon from theme. * Modified the path of translated pm files and the timing of generation. * Updated these modules: preferences, core, mplayerprocess and mpvprocess. * Rewrote playlist with model and delegate. * Added OSD info. * Optimized partial parameters for mpv and mplayer. * Debian/control: - Add qtbase5-private-dev and libcrystalhd-dev to build-depends. - Add libcrystalhd3 | firmware-crystalhd to depends. - Bump standards vertion to 4.4.0. - Bump compat level to 12. -- handsome_feng Mon, 12 Aug 2019 15:10:39 +0800 kylin-video (1.1.7-1) unstable; urgency=low * Initial release. (Closes: #904002) -- handsome_feng Tue, 17 Jul 2018 15:52:31 +0800 kylin-video/AUTHORS0000644000175000017500000000004313517016402012774 0ustar fengfengli xiang kylin-video/kylin-video.desktop0000644000175000017500000000144213517016402015555 0ustar fengfeng[Desktop Entry] Name=Kylin Video Name[zh_CN]=麒麟影音 Comment=A great MPlayer front-end Comment[zh_CN]=麒麟影音 GenericName=Kylin Video GenericName[zh_CN]=麒麟影音 Exec=kylin-video %U Icon=kylin-video MimeType=audio/ac3;audio/mp4;audio/mpeg;audio/vnd.rn-realaudio;audio/vorbis;audio/x-adpcm;audio/x-matroska;audio/x-mp2;audio/x-mp3;audio/x-ms-wma;audio/x-vorbis;audio/x-wav;audio/mpegurl;audio/x-mpegurl;audio/x-pn-realaudio;audio/x-scpls;audio/aac;audio/flac;audio/ogg;video/avi;video/mp4;video/flv;video/mpeg;video/quicktime;video/vnd.rn-realvideo;video/x-matroska;video/x-ms-asf;video/x-msvideo;video/x-ms-wmv;video/x-ogm;video/x-theora;video/webm; Type=Application Categories=Qt;KDE;AudioVideo;Player;Video; Keywords=movie;player;media;kde;qt; X-Ayatana-Desktop-Shortcuts=Screen;Window kylin-video/COPYING0000644000175000017500000004312213517016402012764 0ustar fengfeng GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. kylin-video/doc/0000755000175000017500000000000013517016402012474 5ustar fengfengkylin-video/doc/appearence.png0000644000175000017500000026443213517016402015320 0ustar fengfengPNG  IHDRX:(sBIT|dtEXtSoftwaregnome-screenshot> IDATx{%Ey 3Hcdi0bT$BHb%zW|$HVM|W?C(+D*h+  9gzˮ~zsfٻ.OWS !B!#Yi!B! B!2PB!BȌBAH!B!3 !!B!(B!2PB!BȌBAH!B!3\hSzzp ݏvἳGL<'  uB`y.<`Ϣw`áX"B!@P['%|{>d,}YPX%ح{y~Gaއ' N|2m!B!pai/yAx1wz,.C5u8/'mדEPƙAsI?/Wأ-b xb^,ظq#6n$H:c9,}缡as oߎ?x^ؾ};8{xS8Sҗ=Ƕm۰cU¶m۰m6G>رz*?p|S' x^پ};#g>x㍘я⢋.E>w?zy+y53៴ZW:W?_ҧs~/O}Q~pzϏc׼F_%\[KMo'x~W\/r裏M6 /P̣|35]'R}N}m髮J߿_zgu]g-;޽{v~~~Gn-ﲦn;vKرZv)}{ֲ>ߺvI]g^q_}~9}zKX'Ч/ڶU?l;AxNj޼yZs9Gp G?5}%.R}￿Z}Ho۶M'I: ^ZZ/,,4M.z~ ^PH}SҟRjj~~~~V>([v$upQXLoio@$HuH=~W_<ҿ;3m؄G_Bo3<z+xzxކ;wgP*߻.owc qꩧ_z|c+^ |}݇طozsogVW~WpuK.w޽7nh!82'> eMC!Bȸ48Zhj;_;wXa%AֹI|^Cþ rA#qSc`b.QtY5gqM7݄oO{gun&%/矏XЇ>]va˖-{y睇k> on]w݅۷UW^+]v.b\{KX~=^DoB!2 HN VTcuGa衇'=d)6nX#9Vw#b޸#Gugk/[~qgN5!B!DEz2H`g˰=8y8УD/Qظ~nm?pr H=_8ss(N?t?Ď;w^iE8qwcƍ8餓k.lڴ szX\\ĉ'?S\xᅸ;q--oy ~aE/`nn;v_rann|0>nfoęgo|_ 8 NJ)\xZoiB!B;vTv=vd6?䏮_Glx26nڄ<<XĖDfȲY! ]>ҋ,y9n݊K/طo: vmU8q|X\\^2,..b=8q1WWq7C`0l|k_=q>ltMwp 'nϷ-<hnB!B&{1;w;Npǎx[Z!!Tiz!<)3w?M p} MSu!XZ\Ġ4Ͱw;>8?>(^wuQPJannysԧ>_pqo _B(3<_•W^__e]. ge|_ƍq7^q)۷o{/} |󞇛n |;+1Elݺ??Q|_BZ !B!)O,M!wqHbh ݸ[ ^Ï܅bϞGx}~'߾ݓ`O/gysC9{޽{qWUW][n?16n܈__5'?I< '׽u8{,nF֭[qWꫯooȽ?: tA?=yٟY/>9};38wq~>?N>d BB!2USflZO]~6$<{؋MGoơ?wKƏ{6y =myq{xd##q'e1G>[nW\q}Ql޼KKKG?O?w//5y {,Nܹlڴ r x98s؁GpQH{2 s 0`ӡz?}k7wyC9z׻7~p7SOŦMp7}/z[ ~ B!B!B!B.Ie!B!]( !B!dF $B!B!Bf BB!BQ( !B!dF $B!B!Bf BB!BQ( !B!dF $B!B!Bf BB!BQ( !B!dF $B!B!Bf BB!BQ( !B!dF $B!B!Bf BB!BQ( !B!dF $B!B!Bf BB!BQ( !B!dF $B!B!Bf BB!BQ( !B!dF $B!B!Bf BB!BQ( !B!dF $B!B!Bf BB!BQ( !B!dF $B!B!Bf BB!BQ( !B!dF $B!B!Bf BB!BQ( !B!dF $B!B!Bf BB!BQ( !B!dF $B!B!Bf BB!BQ( !B!dF $B!B!Bf BB!BQ( !B!dF $B!B!Bf BB!BQ( !B!dF $B!B!Bf BB!BQ( !B!dF $B!B!Bf BB!BQ( !B!dF $B!B!Bf BB!BQ( !B!dF $B!B!Bf6+g!B!S2!B! %B!B!Bf BB!BQ( !B!dF $B!B!Bf BB!BQ( !B!dF $B!B!Bf BB!BQVBV=|WB!B@!!J[@!B(ti2M(EO#!BY!$dB!,L#1B( !BXP2m eh)!B BBV3B!1 $d5C!!B2J!AAZ9|hGYPB!dFĕ­SeR0B BB!,~^BPB!dY)L+V'fM%#!C8 !B&C`+Әiem]m4Mz !='ey$ BB!L g '!dQB!t ! ( !-j $BHwP 2PB!d!$6B! ?BYSPB!~o.$DBAH!sZڭuPRF:2{G!"(4%]oPM4&fkB0z !- $BfK8bpm4#G BBH 2J!wpv|_b/4^BȬA1(ToԶX+{OM箋-_*sABf5Bi|ΒwbcچƎYm;Lsۙc]g&dPBYYLNU'GiՌm0P :r'G"BA^˝ǩ$Csk&dpRB!d0U"@ȈpRBڀ`1VFwewKz兂'9B0d6R44N1f~Uآ=]eتRwYO(oT0\45$D6 $1HdPtşIK[&h$Ĝ%H')bʍDe9(iTPB H*FmpH6L=]:qBV BBt3MxFi9Ri-~arBx޿uBQxm'3 g%L'#eXJ6=h M3 Z| = 3 !!d:?fo &p;4L7!Ҥ ^ &7uןk<12J>i73 z&"!q,׬(^)mD;؜hڭMnTa IYpey2#CH!>BG2]^Ii`Ey`!ĖJוw7&߸jSV:*e27YVtc;y\c͓ -W ݛtZH=Ɉ`2_L; %L'ivDEa`5/(%5m^-m?e^" 7LeJ}?! NAk%3.Cq$: 3Mp&(]sy'k);!$@Nؤd`zYMbclmuCͤڥKWR v~I;:5h"g&k Bv{1F2MQ޶ͿcA׻bt1j|\SwL:KPmCeK͉\CWY#PK/|yt1bZkx=J(LŘxBڬOm xl(/ϲ qtAk xy!k2JmyIxeD_KA2F+$T[)e F:m-3ו(v|iy+q޵f'5=d1}8x8`孉&1;SSaR @!ft:hFCB $g5tF }X U e >1$qGG' c 1y]an,]!%RJ#Ynx3_qdaQzG!XvIn8N`cڡUOou-:ߺ+!WhVZAV)0Sܑ|rF&}> e+qC9.uJM1Zy=C |<|Һry2ݎGzYEdu BBY-t1F#j!+be} H>._~߹!dwKB:ڢֲÅμ($g:ygh)F‹øeꍪ$6m u k&p!>1CHuMui`پ{"pb#CPBdfw< ecҕrZ(IDeЮq̰ߘM6{c /opm% BV !ɗ:Cʬ#1Hׅ7p$O3v~0j1x*HF IDAT26KZvt\!oiV"aԠ $Pͺ1L4۲"FIטfyeaY17/8KwI:B[D CBB,( e(̂{ &1.amma"@YV)Lwcߐв֍&4]R t6,n5z{'oזa^2&5^j $dY 4QCG5uL 8!egXQ=n,O}uJ⽋n;EyPE4`:KL FIŴJ\C:݄v|O gBV BBfU% [k/]&-uHnjkU˘ccf c ]cx7IǜC/_{JעTbVQ6F0s,[P,k5ސW>\8m\榗5mijwΎ3.,)[!z YmZ9qcea(aȥWU>ou:ԞL=ϼV8Xӆ1{y) <ʞrjvCHW..KӾ!ЬS,5뮯nG(D51? Xhcg!].o!d $dja|(L".BCqDR@ҙ^, -ڡpP*-,ԅDOhX>50$!!U!8ZaAA8!5/Ҥ@ A!( |j1Q,353mi1Q҂`Se 8nB0W+[[5Ψz tx$ZJЕM23Ou&0^1hu%!eּn?:]Ą0|{L9b\-XEAk^) }HQbxs t 8]LVL4H.^ ^8pL;],fd3^*oz}B0B4a^Ӑ^O޺!;C(kБ(I@uƲ(/TdZT^A|o|Wc;AX~Ued Y`dݡQS5Dms>y JDzĠW|˧0W"LV6W:,'22贏li!IK/YX,Bj( [^>,eQƈB B $d5f(K;m=e(q&|uQa35PM!WY";˧vBAUYawE^1,WI e{;mj%PZggCYr3ژ@oHfP]{C˪宀wEoG2YWZƑEdž(2CAHȴ,!|{+glV񥋡^;$ +h1EG}FO'uݕWvpf^s"S^;?)O2wNGl+ '0bLnc1 RgB.(֝{rۜOc:OTXybVxl&^R !!ʲw)L"tI׉8\ŗ. ŽQ۲1]6zk]>emk$r뚄$ND֪"9&K>O=jĩ ky^'*Gz^(=,kXg;m+L!h,Sְ)z[&ym)b0t$ To>Ӣ.DJ%,Om3:1 X>Jo*6I(tpX,Kio_G#YF( )֒WJ!Z-;I0iURBZ̓6Ac%zZ&O_1!Q860(ڤS*O;TE !cX' O~$?T2_S8ܮJ!SEÉPkSlDHD20m. Q[(H],/!0OGkΚFJE`ݶQtxh!+e~x:<ҋ*`kENY5;Ʋ((m6V6J|Pd%q]|B\$M$S-'*KzsP/C v؉}+d!1ޘ+/{gA"RF S(нf!0L  bЭ m̉x!tWǐ/BYӶl-Ԅ -!h%," P^D>CĢl%NR +W#/R dի:jT^|6V>8VxVW0agՔvTBxmzwDOxi>=Je:6H^ˑY@Fe2!໚BMORSX%/icq!oIlIhXJ3J\ps=eEWC@%q("PN՞61mpŧ+Hk^G}qf[˲~[5>?Eh>L A?}Tv!ik5t%SKPf <ܨU{"dXI4 oxn B6zD|4D5ILUPWOM@:\/dw RS3@PH¹ Mͭ^=Q BAgi5(A4[#'rܶ4;JBPAq!!ٕ( $CF Y V3ڈ?1f8nb`8k:e£X2$N0kJ.-J!% y1cdR;ͲL+LCBi|R*\2YNT:@i p2hYj+yK{7rҺHb]׌@^p٨I &(2]P2&`kx],19W^7..^̟F`t.LУ.$` Jj]ADo%'D*٬Q 귾bU?l_Y)0 [<8-%}+5cMa4IZ6)c v( 34δ٬"m+.!SDs=BHWLTEZ4=?! y3;Q,lq7>/UBe}eRx%}x,cQ114-L;CsC7#;-{F܀3Pv|>6&~17^ OmC:ĩCz>. oo2J:sA֢v_+W|ᯱhKT/m ғ7$283pQ+*EB#e8k4 ,)d&xaR:Ix e-IhQ'4@:"ê؎*lmU&zʔqPV\>n|`2oi=JuA`<պdFZ')*ܳZ`o>HƎ0;iY]_uMp= z*yo"I̕ =NRgXACiY H5!h[hZ~\C 4;w J Djybƨņ B6X73j-ZڦtDYPVP RH^ڇƉLjP lE>0L~%g7c3ʇZgyNh.=Z&#"N\oj~=u:,N=l 3I4O!xb0<`>2Դ)tۈŢKc06! #~s0yn_~wCTfF*džooF[ռcvȖd C}V2c%[hF#T|6w]QBRI#TEd=X/M+e4PIio&?dL( !Jg<ЛϧPt-:R>/dw9i lގry$b/zʎMu+g&͐ӐȕkP$*kZ-p Q`yİdZeW'pV!fgU&OVʎW~1419:[ %QBkxo"!!Ag^Nը%jcK!d idB@ t}^&!w`- Jo(|#u=-[eDƺCΦ6KcЪn!=RI& t!/:EmaeP'qŘdGH<UL[|t?1, ;l&x1&߼׽r:-Ĺ΍95cËt)ӦP{C\NvwL8[ztM%d9 $dtj蜵-k\x) =(buc3f*#F:&6LqK+ykSDx bEqF'ݝTRU.`Q?o}Z>GdU66 *, [ܗ]3",$>Ww].^-Ӿek9Hazwܜ]c'xB璻f;&#Ż*i/pѲ|BT5,!- $dRt&:z]q7ACYfXB+}HHк /oݿc0 I|"%03x~0QcoYuώf(@2 1X %1qP5!"pWNUOz sX;#ϮzK# _>pIזZڬ ^hJ JEGbSd;g8LΤ4ynjGY(6o ?5 bW(US=QuSBxŰ򜲎nxbU#:aT- E=ŌR1JkP_IkKk;9s܈f-E[ۡ 'NFB;AQV=_9J敼֢S/d{BV BB&!B0xj)\tܻ )&y$HL."/R{Pkvs8 UDS8ۦM\(=Im^,7J锝wS\f>e}KUʔ{jn5 6Z ޾3[aXh}Æ tjPmye) :-خF u钬 vZېe=l''d2kP5; "WZ>MKkDf'ks8n2;Ğ]SITFY[armĠ)1$f-a͐9j~eEXJl++`sk#<{+@KCa|V`K]RR8מhy )_8([܉r4YOZ-J!L@.UR@: uѭ[n EVyB1Ey6nxjLR7= >zLaTikcp9` kwy,V^2{}x%3O9"QNa:I \_WgT+4稤 A%sô:{XNUa +;J}l^IW*ZP1vʒ܈ʱ-O\uz=DB A IDAT!!S8Bruxk 7$c't&V0H+'lQWIܛ>/+&ox$&]1複!|-m& Q}ӻw'`I 謏d~cLpW`&U@wK5w"fP}_"asCz -^[PoD$lΦ:Rmó;(E.B& !!ʤWU_s(jщ,x_-$D2jV<*Z9汯>/6p2Šl| HZ,#}zݐIBMMk.7QC3.@*(T[J% bQ}UP{>zECj{ ^Z~ IZNx0PV膂^]Ɔ{l|n݀nw`Ntshcq7BKُy mm~n ?U;/Bvė tRCZ^lBx', ÉFql$/N.P( 邱Ď7_c(ReuAt'!F8'-#6򅌉Epx ߧ*  3=~5f)w6(E6-E{}Q /Yr-cL@pK2E#;HCKtVZA:C9ֵk/M.f|shit\47+)l\(ZdҸPe?.5CPȖ6u쉮sp.(  Ëz]kvum:+w8֔17_D/'s,T9h/(OgtڇNrQrI P>Jm%1#XA80q|tY'5Wۗ[`x@~Xß  6IyFXBĪ أ|UXh8~T^Pi@%;]%]CVq5g%x+|d|N(!8dEW]V3 Q4_tZׅnWpq~n~_&O@E3-.+.< vbО3?1^dK{$2.S܏GOfzUkO7#ock2j/=Xβi~ T)EEKᙞ65h0Y}S7fu\UIaV/+ @AH*!;(f2O<4A 57XC7–<$on(o><;%csl4z|ĕ)V~3>6V9P>k̙SZf5 FԺx} jm_D$h2Ruvw #Y$u>2|Urw{Cc c('?Fa3 XZߛRu6@8A@ý BBukOz<Rgi7A#R|6ьq:q%b;!mE)3޸F|,ˣIgAh"|7)兩ypu n;8DoLi^O35$v6ye5;ץ뢯 Y7-5# 1ToXUwXGTqׯmؓ$ PEm}CtNey Mۂa{R<.o~|RI UxYJoJbܕеsaW8bA1F0?cHC[3sg`ԭDV;/aAU7/Wo(QI.,I'1OF5 oij =ʮ:(^o)Tj!^kV\lؐr%CCN#b|!,"[mA6D /T*$v1&Qs둬 ya?e{ AzT{m52Rlc[ T¡D87\  \u6Np)`N㙈f $ ]EWv,-.HMԎN5e糓WO@*x[VsVE[ ]afuP[kc\MQ4R8ȚZ#tR¿ ϬC1.ZtsC61i5חߕ#5JkdZdXM6N`>!kH0c[KOѶxӦej۩hv+-17;8gۙ(:ҁ`z!JIn^8KPl؉gRr;Qcx.O.vf#4Wށ76oFxg-[Iy[Y%@CT=rChh5+0{`;W ns*1WTbߡŭ@Rj|ܠʊ(Rp(Z@PQ8af٫cg=pK=o-y˿}97s4_L֭-3GQH&!!myVvyF~HjK7 yfEJgnB@q$7&*`Gw]ŊDZ>FEP I>1 a4blW- /&ʗ0 ^S rf38@g(#r[b#.IH%;,Ky@_Np̵ܸsPwUa6X2M+Zy¼7)_-,TNR !miՙH). j=f̦N~ˉnqԆPQuOEu,oy:fR#n|9m!ӓ B7sGx*;<:(Yvu)ei@^FDd'h) {` ʭ(_~`7/J H`#m] j]!ߌ2R)޺“b"~*ϱ{TvK^[;nmLF7ݰl$O}mezu2҈ᵍe2IV҆e-pf}77QŠm|mt1{Ud!+ljL"cW8#xitYG4"[`'fazhFfHp5w뮲TI<0K:V.m5&M8 =Lll= ah2ߵf=m||dɾc+TJ[OLj!!!Xp.YlY7^hOP1k4 ?-' ;arX-yDWmFl.]([G ҕj8I  aAq,rPjO(4+2js'M /[,UX,K!ᶇ^|-`Bf0Fv k<Ӄ>`dNz!!S;bț 1XSRŬv-چ57t#ZQ[޺Cc/uq\^ZzWO$y4 XslZmWV,5P|]䤵= (g] _J J yIEXsb^RSRȰ~Ds8x(W~4aCڹ0noa@Q9i#碼C?1ZȊaT_NbhNL:2w GApUid:>o!񉤨1LdQ˭]oVa| Y? K5)fnU.o|YUbWl"į`xa fae@~l[w8h(L!}J (,D硐R*KkTW4*.շ1Әƃ.3myǁJMZNtd99e[ ^RtrƗ {G|">98?y+zif@% @Z93dZ/I!3h$3>UY)0Ե.4 @+@栱K? ߼n G@ͭøTt2@gCI}gcEG_Hoգ>AXp۞pCo|K,TzXtOCy%2 KsAئ!]W5-7xO"T~U1f$6M;Bm%Ps0APTB8G[ۦW</"D1s1mq<1ӦSεaPRN$аHޙ5(S j#[EAHVH,w0_5 $Yǘ£6oJz  IDAT_{A@ot;AZk4={w!/yC%q#r;B}5q=iHǧ(];T5a69b0c_5 =fiiyWQˣ۷rqK1|_}ꌡ #/ \!7  !36C:1d.(BvzSL#HSf5``SO~Eh8~ ^LwV@J!C J[y>ȯtׇ@d|13d0a0 ,HCƉm "c𦎙r]?ա84&(&f ޜ"VEsnŀ+^0P僛t[ | `0y.a*lW@/]K!Ny=P5/Jgxf]P82ׯ]1)ه 9Wfw2kdAYsF鳃sQu:2<RR,)w-<`pF!t1[/BOpf{riztqA0Gb9hM-YM:C>(CzfՒX%" T+ɀ*|BB*'$k uD6Qn d4%2@=`4%P X pAĒS8hB~w?K wmՍ!kC)Wp.a0;d*Syy)ńr3H$A0F(]GAlAJ5>ek9rmdV!"]vUɦ?Sjwx' '@LyYcʚi |b ԮЊE.=a[U V#:v.%w),֌11Gax]~ETjJWT݃fW OP#saMhS-d>@~3QǬ7cHSclNE%6 s^qbC+ƈ{njE#,S0]nct2mcپiR9^B19ٚDꙒLEvԣb`nt]0f.U#(4$|WSמ] >X5vUL̈́jK&h:TkkgQXR٤"y/ݎgiCbX̮fg"""L6@D8z@{6 ^Nf3tbcpC+jMD xFa 5Bm 6HP;0XJt/U T<&`aRc?0-4 >h@BR"lu+ԥ%*Bc>0/I ${\L5l7trƈ5ʇ~1 D&c^g3D?RRRRJ5IϰwivSֳ6,Cz6ҭLm4uT5u=9V )PidRyhP$4' |B`q4ShhA(cƯ^~^è dP! xx.1фb)i& :' 'ƀT0oS ֚Z8xQq ݻfAuOAY sKk˩|F*#,68=3mwZ`ec/Pmn$C ឈ@ Ngm lRRJYΪ۞y}g{TV@U㘽7zO5;2reV ł` !B NaH`<"#xⱿ5`#3ϬAUGmARJJ5MBτ TԆah-0w6%[:4)Ԧ4AB2BCcM)T-Ke F\`-xM:@ӑ!c2H%z:fTLKWv䤁iJ'l r[Φ,O Usrn4!ѻMT-:Cs@sjX3jSR$KL邁D;/&X͈EQGr&vXx4kY[2̰pnޅ`0+!{]_y -irp*(]g]Cw)tRʬI7ϵtЯu"y,xqTPr2zhO"-W> ]*ЯTAfuxq_oCkɉgn5n* dBۥbfAUQ01]^y@n"!*r'#<`h֥HOAA\!x{0l#Xv*|ٻfIl?c\KZp0;r3_m֦m0菌эIL(/5f3zuظłFsز` ].igT!+hʷvmciLo,Ku }$uKH C@:>&C/C ӌ}/]䠡ƒKBH^UA~$dSrߕ|@2k23Cxݞ,sgUdk&||S$BƯOV #̀mG jPyRmRn|>Wy*}o1>%d!W*jF۾t&Xb8== Fn^mJ _Zhԧ{A>!j^+0QmeA h%f_*}Ͼ0㱜(/]nd0` 0asę(m- Vjo'%1kg)EF5SDŽ-+I=\l2 c:u& Ehy1uPfe2}Aq ;m gCWw]el7yaT@5 _Bxd:biz"Ou Y 2=)a)SJl Ǽox0 [ze'l\/%ʅ4{4[ 3?ws-°Ju$$Vz2@Ѻج2DjwTA@>4u)!6&<~9x+w-I0UAX0"0Gx|<Ę(Ew Zj# ǞD#XTk,8ߍ2~f̂{ T0n9 Y Jmrrb]MI\F X +(0ʓLR)j7'![:c\e3"\L`;ؕ{]^q;*]\:X奆{<4{ c(B"ZǜqHjg.&"B($2BؿPZG+US2u_~?~5q nylj-~^I1 01k`U7FfxI'c΢Wa.oǂ] o L2OL2 ђ K% fBhSleGQ@e&`!e)Ca5Lj3G5K &3U~kWz٪'ZrBd[vS tMH)]9$|,Kf,eLG%'CS S^:ŒľV3eD٤HM.},0 &d񱨾.@[y*FcjUtٺJ!,s}\9zaݿ90NS2u&ۣOEDĹ Ju$Dc]2A4Cڜ>ۺ3?;`%˛0t ݯv~ȯ"~w{0'8hA }J8rl+ PonÆt;+ilyQJ@XJ).(aAa}(2 w\0- 8-_[n''"J $͂&B਀].ju>3p?G5My /vPhJ7m 7'y$D,dN Z?H?WU7$W!*ȯ[6 w.@H— ģr#gd\Fil `.nj1mS^@B79N3*2eoAB?Q/Z(ۓq*&Rt$D{S~Z\imTy}K>k͍t/l ϖcfG Dm:\068lB^uϦذ܎F4T h&Li_]R6RʬHVet| @~ Jpn7A ,3"4Z|pA2c(ìD" c`D6(*@ &Mz% M w:oҬ'3,T'b@P=/3L] 8DоCFQJl6)w~e;N2cB ]4c#f]:ecd֑)|.$\^gd&긾pvc<- IDAT;3܆rk:QYKf`Fպ7^m4פCw'F/ȱr2(=Dxs F j9+ڍrf"߶>;m*y*ZƬ71ks`ʐ7a##OKNT ~gMlo$ 8H P !yCPNO4}-ڰC3Ҩ2EyaȐaq?'n^S+}Q5_m&ӕH տB?~9iSN1ȶv <̓uE9f/uG8HHfHoSQ?L @T:dc=`Tp 9eXw/m?9& A 5LIS^zwV"0hyc8G&6g]ǜeϧgs zc[;XJ)R\Pt4{_@~ TSRSZB5Tk ~{0_C݂n ٢d^ T sNRJ abjg_r P  ș"@@_ (/Oh@yHy {jڪ(x`fZ-ZM2?0 Y_{q%ΪC>9 5<PZibl#l-5:L.ݝ}yc2eToN&N<ZS Y'*ߑoԬ~IC@fw)g4y^"uN5c;_G[lS:)PJ)O/ݾ41c 7Fz\3SqЫ  .M>˖RVAO2O\9sWT Q*gBBm"C@CȐ@qz]*PXy6u{1@b #hZh4[ځ hTGCs?'o]A!hT +_NK^\)2 L92s.. k >oHV\:ld{ve&+dY<9ԓ Y07p70J֋l.7CF\-1A`Ee٠+;f|B2m5:X57",,fXQb>3:M[ulGǒhwc$n4yͥI K)ِٞK/(KpVǴꐭjS0Pn<,~!0HV]c hdx28r52Dt=v_]sFG{U qL8"BNʅ>nЬ 1*S38O%D MF x1IzVF;+P؜}着u @?sY:I h@7}99s}g(YRJ>_` kK2e'p4ZO=N1t Em|vOnrcpc6quf`@S13X(l@-4-1Q +j}w麩?Qt bN1_cӹg.'-ׯ]:*Ō"V@tE}\8]UvynJZ3(.F=W^fֿsYRJyneR6j0:p)HIe!` [=oZ&<"lj4\0 D 3ԪJl|ZrTqu%dKx' h'd|NǖlM3XH+&t!2 jn!%0V] `HC {\x i{"[S`0mε#!_WY׾]Fs`2qmN;7+ ʶ@}hx 9N؀t:=x;B`1Cb: 3d}Q|S*\X_f ʄ`S©'N=?9Dk1+Xcr!]l[!DcPW`0jѻALN#}gCl)a)̚l.؅ncpЂlLT;`Z@U9|[mu8ֵ&5 `*Z:vD nOt*L#8XA&hg#; )mid! EZAR2ćX21V fRqJTn2! l=_>P /\5ӷvKX,@$^tz"\|/_aSufd(&lz8R659;dzk4Iw,LT2+wc5a[aNP~=]nEgdK^I2ZJ)Lk8,igl!cNlNB10vX^2oS&KXZvOf>7@ %[.Ƨ֣״++^ KB]J)94r r NcIQ8Th7Oɕb'ިިCZ@<ͲX-;UxWk _H`nan?um$T+v@pۢTC3q4Eyuܺ-)bwؽ0(ex:;`e-ynq,5{߅sG3,azXy-WOTk2ƀvl^6m+Ӭ^\w~k,O桇ӿic$6O)֬y>h]#:=N3]HZ l:sLNzm#Rϝ<\xl6'xgAz8+.dK)%ہߴ!yFNΰrІiu_8"{^^QA^gBBP 3Ev4 c `HPPbwf B%>Ov Va0ztG"*C: ၹǖ}/nDL oI4~Zk3s+Muc5짏ǵWV8.\D5}.:0}|[8c/ Gy,EsgM>ys?\}) p{ 9T3e'h&Q`ό;9%޴Νu!ׯ\% ~3GA7ru7DlO-@`U Ќc]=m5#>up(f̦b-1$ҝό~>KvU3EuϢ a)HJ@XJ)ihfm=|<Imb1`bPs-ۯ@| 5ʠQZevMbWQo0ըch`Pe)QT~ IwMo)h@% Ѩ7j0<^B'2 R=kWTX'6AT^˳Ϳ ϯ <`+E—!lTgFqaٮSɵWFcun\(*N{ o+GO4hm & w})9k_Y_R~Za\z ](?9 _|)Ko(0 .XOy !zAH{Ѹݑ!̪*L. $kO2ifx',3&`H XvEiz(:(CUWMd`{HpV:ğӺ-!K Uq5:u#NOkJe 3, Jơ˺۲ 3]AYMVX0Ax@Ȍj?{i\q0ܡMmy$7{d`]EH0$$K}_ŗ+1gtT̚Lƒh0f[B(7T 25j<Ȃ &bCL&}KB N)}7^>::6::v֯_ի`5Xh/^ׯMK'5Nĸ9`Ķ_yXq89 ɀQk>d_"]g |^!x+^?X~ ![vS5Cx?ĕ? JO `j+W08 IN00>ڥ6Q}:Ș{,(z@ج+=RJRF-`b _5ҳ"l Ih264ODKRuݫၹ 4jg=H"1q.vۼ' OuףVRĬ fqբg4h6h6IIlLA@S6vR5#ڇ1~z7-\d <0͎n.0Are̤@9@?_0F枻\c?|eTΉ9m eCxE'l;GGKpoe{VKO;KKkn;;ĊoUhƊxL?n X~:Xu}rz.R:S紳7YrUG㽇yV\An:{ί;{NrJiy| .9(*!]L{7YyPP^Z)08Πg5r9;a>B6=JR?ZMGdIm13p!7 Rt%Fj a2謎n}]uaa]w$˓=*↛ aZ5wy'#SqǏms/~É [r~q/mF+ ېaV8ez7jgz;Gc`00NR,9\#E U%$.*xo%^8׵DÌ1o~NbWOkaМsur,=2\@$]^'LlM)0Z}.b5-QRH=)[)RRJg aqqV`A)REZ`xגU BM A^ghpD0`5($ـB ]$ӮxN !ǩ$~*bU0gxժ HB19FT!9YhDjP(6ACԄ`m_8,XBm0@+.K7G{GGin1x颙װ'ygb\{ d}淞H8S -Ŝ`fݖ*3Z(q̖Q ea%_zʙكN=_v_rv~ksXp>c Lh ɛJT>.O//.p.Oǎ|/FGGo?3ul=9`Su֠R޾ fD%;h;bH σya}߆^Z Wajj ̝P-U5[UyjѩGcA`g*^Rz2a)̺)r26YaJ?O7BmTl4 2D!^}'~>T} (VBAm"$b}H-$L SEQVlq'>yxɋ(JB@`191z&KuFj>X)4q^ӿG@JBS#E;wǺBRp&b٠ 0k*dywdNH!7= (Z|?8 XEx>^/;b m܃Um ӉsW6zɣso m]<ξѱԵ>}@:d. ~ -ZD8BFcô7ye_9ɕ;|& tLEٞ <@TAAkd6k/L?&vbͻu翛S}a7[حG潔Rz!,d-]8z~̤e Q7<W9 I: +!jj/|;P߰ BĬiiAb L;IL.%"jUm!^m^%~_k~fF_ yZ6&'ϳKzb"2fQ(@ {QBVa #FM2ƣwaacu񭳿> ]"4&[\G0ZlWD!8ЛA Qy} OCLP[{ [aN{Z)>8:fgˊ'j;!RJe)a)l)u3!iwYk`PfB5>obR#A6@Xa<_ d35)W_(FE0^}VT D oO|?ˎ;/ƚ_A;harJOX`06]Dc ]J`7Qm90$M IDATk jAa>aX ltKp~= {[_LO9| &kͩѲ躹lpu"0^0:<> ctAo_tw`?~c-#֭> x)@{_؜+s\rX!,9䝸&L3ex(|דd&]NgF#[l8mF,gP& Ak q;d"]i[ 7?#v07,2oqQK K)esw:ALm V)0RR `^T*}PW3LLF5:Y a8@a X]*aNfBT-dfE.ŗ]'|~wA ,1d.W MF+a@ddېbPa꾛zf-! a]#_>_ҩ8{솫~s9}q?{>m7 ~s/1kǀo…8SO?I'?-qq?o|{gsxˮ;W}׮~98Gogqժ;Aƒ Zr=(G?]gKO9ӽ~k嫢6ȯf{\{8Kqޏkzmܺ,qWg:7(>}'sg4oXsÖ>H^T5&Sr6 O(i-YuR(KRRJIˬ1xCOut͝^$2yxC@TA+eSOB`"}`X ! Z$"fmgxrDaƌϛ2TϘ;]t {l0\}-^λ~4- B $g&*ZoIMj'?Z1qW5!tuB Z珨m rTDch/ynXh>u\a'f 8ڠޜ&zr{/_"Ӱp wUw>dMjBnWy yr~Tŀ?UoƩ_^˗]>gًAN_wŲϯ>g]GT1 쬰&$rp'6;אgYI@y:YQ!$FZ;J=a`tr}tLEdLjT0=H3'.j)XJ@XJ)T =`! b`ɗd 4BO+D xᯏ?: bR/ƷzjXD&B̤Q-nloyKq/O&sF{aȰ@l'kL B@ (Mm E*-#1yɞE`'ˮiʗO&r>spvc-ria_e^5kc&mMTdmo.ΐׯEdc`ȨIq>~I:)۾4S࠮y7 ,۠PP6ZdZIg Hx u94z%,YrRJ٠̜Ξ_;ա,S޳HcaDA $ ȍ2;~MYVឿ߁fЈ6a!amCzOsN+"c7 >i )%< Bmua8Ŀ֍cr6 ]XcF4K&EnЍ0x/!4 *fvj2&,rv;kF'*x̔ѩty:Q~"{~?_9 7G{'p1W5[%}auð↛p;\lۓjLόG~=/҇nz&vg>}#0K%G08zm% o8ygQ=ϭ,qm ېI茻BMpЀ )dkܞ SQRA @>Py5@xV:h0(I+`)ϒ a)dٻҥNnvR0 UF@FM * v|_fPN4 WVD :DfjZj-9Mh R )~!DA|O>3^-^Kq\~sGG 9e&,٣tvw˲xSbj:0FwT.Uxi!aSrIcsV4Nl ӦdKml)l69 Wn2u݋^S qma3cx☏}޺YX@sڝ/wӞzc_O2?9^ q]8h3cɴObW:Dpzr=@o]N}08,Μ+׬Up؂l1H~.[* &8b9lIŌJAkrC 9򣸈 H`.zCnӢK Xʳ,% ,Z %ziiqDI6ЁJ>exR9P3Lfi0& #H DcPA <阅 )~ҽ%9^T0g(Dxoǫ?t~}u32 !@RpњJ{=Yk(Ĩѱ(q=Ip_m <Ø3gV'd&Y~dQ 񁎎0}t}xk=u]U7 GwC2-}ͱ5zz73o~T˩:-prr?|=8Kq#>tL\f/8sd<@Z V !iPj'wR[lz?d(׸-ȠVD!MA:Z`n[waswϙTȩ4Ӑ H K)%OM0UW饬ewv Fyj ~aX RtR2YqY|h7fY;24h4qu}H풙`Lï6(߇'01v/)^[_^O>j7H+0aXsDT-#PjQ,-cŠD'6Na^y^Ѥ+:'m'=je;_wlO2 c;Bų nױ3@.a ~KXCQ%e/=,+jchd_hn:wK=vf&F_>ӧцz~[/{@Muk`O(*|mЀA^A$@Vk uM5 ;a M 9cl*c?Ӌ2[J)$% , /iX Xu4zex=+d&[(D.߬KBA0  !AB8lKLa:>l6Q}7ۼs/@@Z@] (0Ac6\m0 ނr@g0j&H%ξt2rm7FZ?u7nqQ駞c񮖋/\_D2m327zD.m#{OP]!]^ڨ 6\sչ;5`( xvYWB&R&$bO``GU[㜳 pػ>]veCںX2,M"YOBWscya "f0Dvs7D Y[2yw? 146kASľ%,9R"(b5f vѐafXE09Uj4 r Ih\# 9f j#OM>FP a,}̮ Rͱ~*SkHD=ĭYbLɱ\&B[GK> > NiRBXS33["}qd$MǢo {w;(P|Wn,UVx ;yR\~xK_[6<SBt϶Fz;᥯|}ֲCܓ9{3N:5ONx6t Nxq߯6NY}3'J֤ɶOg _gakN;Ci~8S338BM^_E ueg+O\Erre22ω r\PvjBXFbgutTZ2C4GXbxPQ $EG3HX[V#S.CE&!f9C&gbQcRʸ }+4]R(hZ Gxkq뾇X6^{ŹIbX|PJx[G!"l~.supՊjR =d_ҐcܑvX}ǒ,lK}s_Q{u+w 6C<寷N>Sp?` ?EL~?ٌu79Vd+&p4Nz{q33N՗?޵齘”3>x7fU'3j/$)qVdP*ˠ?UXNb聾 ڢW ֨'CD@yDHcl \?88Z,ݣO /} e w*MJhrسn:2@Ec҇I5BJAU[2>6DUq0N59wpԡO6adx(2X~NJp9d1SU@|-zSrҵ*.вdZY[r!YK[brɢ6sCԙD9 srnpC&E؞=t9}ukq&Hl1 &Azx*,#ZZ|7S7ثjEID>y|{LV5>cp *>r~$Qr6g\ V~њxbbww5ŽXee252pR>u-&e )g?@- k3`Fa5 1IIX6X$Z{Ƞimb?;}E0l׋qpoÛ_ AXاyNR~q%U,QezGPY.`X)\; ٞ*|M[pޅέ?0q=ɽ/W)Yl%VҝB&yr3u9cdPO 0 a#7wK>$G,GRܛO,e,ʢ"HcWj&5j@"D|o %DY\m3Q3p>=Z^ Ydi 68G?K\˟g8VFGG0<2V kLA38j+2򂛚l;Mq&1Þ x50]FkSsK9q p>Wh_NYg3saOYI'~HLiTMAf=UBzhC4(E͟RƘFCƿ_]󳟣lf;c`M=lɣID|K/}U i'%.okx&5jTY߂Q­P_Z*k@D'W$9mEK ce!]AL8IRr b/Om,SF]-/*P;iB3??Y 7~t+k1;Jrƅ"QTu,!7!K&5_|sN)M[M<`C6W_lz|{ܢ xϻ2!!18j%gѝԓ? ox_ww՚ɋp]~/|α;č T_/(o1F|$do~ xk7[O#yN _~w-ָhXU{x,ҶeorN'd4Pg`u*i=oؓS/t6 @rkXBԄFxIaI[C14\=ed9 C´APInF̀vdi;ql IDAT; ,MB;9^d%4i33;v0<4o\Wwݍ5A9aqcՏpǬ<%@f- 侸k#Tz޸phXEO'6$2d/jjQr~JMo#geüي}[`2>0qU+qpշk^%eMNLnqREY`]oRd<pnҒosʔr%~q>/~<\zٵKe=GWbVG$\;*.&!K>K=X332:>eB*q1$N,9] dAMkؓ$"ԳU'5\fG2Y9\c+@k]'6jBX eVšЛR2Vdpb*2GY+Cl^*=ݎT 2ASG@RfV_nV:]_u33QFIafE }DM,9殟cVpnnkއf qCj^vV@I\F@n8*Y=slmSSFda)C?ŏ7쏎8/O~<w!{m4NlqdB?nQC=15DƒVF2lrb'4{7u$Cr&0 ՆKn+d,ϳz73yvju֨DDeFA{,nLMFK+R2(So]R?SgǷ[Dʲ?eQٝSC68PlڴEY ]nR$tUaqǠŤ<9NIɠy&S;Ƴ;_ҧ?I`{+_/F)q^.Wv=̤u-{}d+7z"_"2AsA.`('cǧnQ㉁BXBK\9W^|}&I2@c~ G|r-Ő XFX=QL=v?UdB4 v;f n r~y `A8ы"{k_myA 01:fkuSR  Ga!ND@7dedc}b+jbr"!iYYt߇o|y[>;m1̶wuuabrnެ)EX>ƛ~oa&ɕW_+._3N{)xcXNdu߆ ^޾g2o'qqX0;oYg|~y2o>=ǒ~;ȌruI\W VbwA`A" ),\"{)vKtrF jBX6tnCJQ-/ȧX@[h6%ѤŮ>yǤR2qIf.#Chfl O$uC : DvLM!f A2Ȥb Ē!Yhw1Z6:6뭏ވx+P`x42 shGobXB, h\ƒ 1JUSr@WQcQG︣\9soozM?}S{pޅtKۥW6|_q|b<2= p uQWeb6,(R`JZP/ƆQy6۪Bx٠6yH$球+9?n=3{peM82ZeZ1OO|83@31oi22cŵ%\>X9m%l)4g*w˻P{j5 P j [kZXI%L:C&XʐAe ESkZm<ꭈ"8bTib}1dEg2$LKFg7Ӛ7 Iqcǎ)t]% JfN9l*oB!N۶Oip[q?+ 7UwDTgo9`Kz\g@a4tXNt%#@w[{%nRELZ<{kGgfVl87(|Ob_9k!lx9v>ciӖB|3O(x~v?`ՊI|A3I  /:De;N~Or,9`cg|7ne^9E0e՟80\sx /Ɖoz>ro*{ܺo>W\\X`n}.cM8UqPWVz+kV㉏֨Ф0զUG17q[ƪ@An2d0V-,kl[H+,lT@QeJe@Pɤ '/DF˪8%10 B/=s<8cWO?nؘcj#?PwTLNN_lYe,-n;g|k=Reqɨ}]3*rȅ=VVN,3D:QK1Ee2U.ѻ75h̃We4~̖/eZƖPw; ̚ wfTĆrLK@v$!H o2FXG&E@0 &pUhȞm4[Lt031@[߾#br!(~K,} )YCSӧ$ HcM%Äme`S%cJ^C(vV ǂhnFx4;l7-ozG7SӸ⊫swy.7Zlڴ_O_}> &CGW}">y? !26mR>~g}:슫q!gv2K_Lr‹./w#T4ʗb\xѥ[KI5s_e''.\˻b~KO| Nziӌk?{}li(GzXO_cs>X3?9|9-I ]<'}d|S(%cůѩ0瞗!)7gS˯_!{߮Z1֮I>_9V*C|9fO9 6US}mToHe?Sp!Vэu^D't<|s-qxιsmӚLYm(Y>rױiG҈樫\BexPrx>[no}pgxʁk~:2τfq[pQAη‹.y,%f>| /J3a_q7)Hd~79+d"3NM41]خU+&pqwZ $_ Nf AN9vFIǷ壪&9h-tr=] {GE9ũdWZZv8p&RwQ,g/SA[uq,{K:14:mI޹ʜ˨=ѷԨ8F==R *0\Ү22kY3kV>6 K\k1>6`T &!CR G lW=@ AbS )!9Zht4=N|?^\ cdd$4Ϸ1 oNF~0A]hY c}95 j&?#n`Yo~?hŔ\g&̐!1dh )a+rS%!sOt@٤4 "ǽ*hv3v 1x~d̤f.u<^cইp߯O/?.gsh6#<6c=_2k謺)۽.BpjBhO۔[^{ȨY,Bv~qp?+sI-e ^c@m!QcwEo' C2hݛchrT0ƪ?I#SG{hIVّ= !-?p8 *Jh݄&B!lض}ҝqՍ@$*/ -2BDQ94?.\p/~1 5 !K5D6c)tɠ cemmlF=L<#m1Z"wJI|rd+! qImEMh~MBe %ʔgt% >?uS'ړHعߝq#n>.'.|d y{rj3f^޳#EÂ6oQUȑ)ӚP{ 2Ho`c^SB+ױAiF5!Qcwc.e ד*lJy7Ī/3pj0Z!@-fcKF8&G1ƛxS7~u3¡D!M*Xm-mvDQ"Br!-P3k󘛝پ^y-x ڝ6VNN*kЏ T"gJY>zCIUR$1dkcуA_&:El.pL'|G|,8* "X 4i2[=BT2!V3]*qe^,K|{1WCU|#OUo 5lBQ\c;'{=s ?~ 'M%[nq3uu>ot3'b ЏƋ[~jx&5j U< Gb?PcX%H[rqₙr3(jjR q,Hcsxp0 B&PXuDرcZs- Hdc ¨z MH$&Ttѝ;wi#  'ad[})S y9*lQhE:︊ N<{%zscLuAeqtLXr?cS)"-!4͂&.ᄈu%r[_%N)Z ea(KlsHM[UHQBµA?&͵r bqˮ<&ysRJXBqP5v-jBXeȠhigK3KsJ{N+ Rq6D Ah:q{-}.~jkbA"c ! ̷1m70bb\]Om Z h56(靸qOoGk~Z&WYŕNd-+l%Xo ݎn#6:%$f*h݃>D0gsY 92u CSa2 }Ldbղ֓J|[$(νNHC2;2%JfeRWcW~-Be,:ȔF]ERAzBC>Ɋ+&!mX4J?uRHfi |=4 ,S4[b RP &j~gȠ:F0+ϤXQ2L!Ўm2,~kJ ,+r)Yn>.c!tyOAR eN9ɾ_ux͙lQ IDATr]dIM $4 RǺEeT`=DfBx[]EAG@ +dbK`M0kY a{ *O%Fl d㳸.wf9*?sHBc=#A8C4 <]6\ۻы;ḧ́dBm0ךG BdLr)e8P^F!f\zո?E{rj("30CiNqi܎e+u"LmV fSj@rk4as&m-z@#+̶:k"hQEsrV6ea.aI]e SWC.}VWR9muJZjM˔ϹD@Fx, D0 q{;d{ks}|?.uKN (\zF5RԄF= u?c59 Hf]dJ^6ɹk&ӱ޿lCܧ %zsf=8O_܀+fgwbzj*dTMhW )LcŴK"vܾ*W)&0R} xiKcubcAzƋ {1י2A^mnGE $)U[wIv]#F\a|l CCCiXjVjˮJ+-"K05ϤKt'L!}e ^ǽ6nmĨDh %->eDĂ%6 &g2bV^DlA[@}NZlSv@f(*zd%H !ʗHȦCrRv`{ve %?2\`34q5e׷p"p $[N7]MI,\U;YyM^;ͧ¸&)|}jYx=5)2rlrː*竚%(~ƘOgkh:-Y )m>W wdФ ^hL`d2NgrM5lo}Uɤu?VN+Ix CMkxC8^' Oo)F?Y21iPONۓZƤ^K;@u#_<cS279iHӲjw8i¨h)~1g)عP%5Y TcJWꨣL[0ȓtTŊ" oֻӾa̴+M"q4!p"v*ڊ FeOGRf-\:U U&Z*T_)!V}vծV{Ʉljծ}Og=L]iLT%EO" 7I*p?D0(wZ 慒${\(_4n?xťd{9V6Z5!QcOG ɐ1AA#]3-,SWJ`)DzV"˷]4WL拓-+08.q,C`j+X$$H,i!^>aA7%ga$ed7u'ݖϴ_j+XVDsm![[Ohs0,w s~X;>.Da$ܾ!qqѲrW[S#}rRi%,M?W=CgY~Jiiݮl}\>W ;f?[}qY/hEx"2 n=h `O5X]Me5vqQŗ䞯Q ֨x!C#&V†M44xvp0S^}13OqNƅ@R@01D{GH6k ^ "^%ڪ 3%fr)9C.c]q ct%I+gZvJuZĈwbQ//y1 ̩}U0u'Bc}dyzϵF3^h[[Kzjmlb 4I]LA^u >Kjb bh9±4'3YH5)j אұO r`rcQk @M/eqS\WŹcW[Po;Q֛L#Xra6JI4o):8:Vq!bTC| G{`8k߸l8>[l?NI0R_ $H2@85Y}m"jPě$DsXj,uhJ2S[1ϓqػAge 9!r> !Ѹr- lbL&Xؚx0bEK͜lF:%h>"J~2i2 IӚQI1dL|[2KWi3ylܱ?}\Z&$GD<w v8(byV ZX,QB)_݂D"ڗY~KeU*L,55!Qq1 q%[(ÀK UF;W˂A:+!Hł $tfcL?ad@t;o\z?bsSBI8&4K%HJ!)!@:h$ )3JiNkM!IP[\4z;0f;l,;)h>f<Ӷ A؄xh3q*9\0TWhH=aE81WGL\Wv+d8rdVf&I ,C2Q}2k=PGno[`Uk؝E`awM_Ta K8^OԄF 01#_N)Mi]2JJ sI Bw6 l&F9-%<:y4a`&LJM8QFVs-Lge¥,dʸWVN`!iXv1 Axhn^, *EY)2)S(rm^e+] /w}%vN%>$hݰ$S~'AIYXkHKˆ?מZqS__rPZdFS8/4e-cjwRbQ(!ϥ$/rGNJD5!񻍪3A^UI X ¯d͔1*L^0VQW" 1L B ĆßE;rH#`m:SgR"ĐC #[ڂ YEYn=-4F&p߁1f@Dؼщ xFG!/7?Br0dU"6%Пu3Z/):W5Jʭ|=?mE,”{12A&J's|m)Sd:׷mp`M|]bFucJ7BK:.j2Xn!j("nv{~)g`ȓcD]4Kү,S~[u{}op!@BUԺ>BLEmŘIFAq  B$%ba㈧< ? AʝMS\3YR 4yLt9OAmA<-щI宯#}Hœ[yh<3`x"S;gƙ>*5am-"Q=]DeOB$mEQu+QdY ٲֳ(d!D9A//:pY/h^Dyiy/p>q'Z}ǝkSj\ \r]5,xUa&d Ƽ(]e3$h^fB[v-`flqHVJiG@@3A@{&BILDcT %ڝG'-}಍_}a(0>2 nzI@DhslrSb9{2!H-FFgv&g)~w`dJfښNf1Աn,e@{ ߋƃ?-ߧ}{1Ysf@J 3.e֘-%`VhX`3&z\_cr &n{l3& yƩ p%2cI !5/v!V8}ϳQ\#fET"s;ہq` ildPr&n+$E?yk[iQO\VYYhli2Fwv@C_{"g;SM+-;%Si*dc`)\h}}SWJ[R5"S}-_UXej( Mz0uXRgɳ6z|K* 0ǝma M)c%ˋ~ LkP8'm1VN&|t`o>. ѱ c"j6 6| X^$i>#\ zy+iZ 5j a'.|fsaʐ,ƐfY()z`"คP\˪g뗾m] 2*nj'njtyYP AlnF+jMvnDz'}~t絸+_bbt9pv2HiȊLXIMN1,.$1zsS`/G!՗tW[ H@? b-9+ w,OD*a10V9<,\n C=pqT4Pv-͢Zl_d ̤DŽK8yr.AvUg2`̄bSz#sMUIr߾s zb[(T3}>BMk a 6 !i˞hkk_:)X&(9lSF~u o ۘҐ{nf}fuWT>b7Z jŐ fBE\ fEhw$W604%uЍ9ppK4!A -Ygq?CژJ%=}-R"A#^z30z9.:33iItb RtW ++B%sxծ *ӏW$&Ϗ*쨏J̐de-X>D+,?!L䬯 (¬ֿZcW+c]DxW(u]dMTX22we{jBX.A& RK+'m5GAa(}&qIRLu>~6U0ԆFVtݙ22=7rFOI^朌5KDhIt=LJ-ARwA"'{~[~vT$T R[8ʼ([}[|w XEhÒ@:L񛝌,Z 26U~wP0T${3 6e efɟMyM sDZ{sZl>ªLv`lN=Y[:zZoh>oU\RT|Yg.$F+ ؅e *|5&5xL-&eiKȠN􆥄h@ d6NUCgݣ50q/͖Gz۽4QdmhXh, Лx`HB1vnК[bx,1f[S !z哰b81ݚ/GxݚEAԛGu{]ҾO"h l #hb9aO{&&]pd"Ewv:B2Jlo3""p=Q5py Un@fN2rbJ $}E YvwړINUpI#\aC P29Rzg Qh* :bU:+W^4 8RZi7@MX3ұkTToLKUF5!ąl<k A"miBB Tr綅F+ x- IDATS%@w[ e4Hs;bm!58MGLh .c#=4F$'4G ;-@aZV.xo`mhf I'JB@1e{c|)X}0|$X2FԞ = umDOl6b0Ɨ|@͑ᒢZ>%H丏l1 żڛd-מH)O:oUjtI| p;-I}*!?k+Z*Z2X岔b!.&7}9I_4,wt+"_L,f| @`jBX㉍]JH"% Aj-4EPb.p J~d#TI/Y{^{i>Dj{g %QB1@kGq`x߶[yȲCÄpDEd( ~*dDɌ^(B/AXE  h h6! 0KD2F8F%XTa^2Z6c<IEP/es~:o!E`(Pݱ\h w,}& lkI)c֮B[!Pc9 )W⸫,Av~yRv=`Jdf\*^~#gU=AeI?i">bI}4?9`.8(ߒWB󅓆M&V}S,総p$ȋSa&c&5 a BK95J-B$͆}9xUrӽpeXiiPd™61HYw2I!HtwFC K̶$CCAS`H8BGuT[Ð6 e !EZ8RR' Ӎ0ۋ1eLP=t -F>‰ VQ`'PY q eRhVQu-(ۮ 9]Lls2ZΥ?Kʧ̶LY2 0er{uϙI/7 $`b4_pQJ ]WjP_r8iδ#{bT&{|5!Qc`@8%\BfcW 9+G e駨zSNlR)!(!ą3W {%(Db`F9, Cp !Aj-$YmI%dO#4VIbe$Z=F+Z=$YQ&t/?BrCl!aU,c)cRH*rY[;kͭ$gB]]\dSx=!N~ʚ)bdK8X\].V/M? b,1`xHj,jYy!x?jCPO\>*Y`;f3SȟO!YtڲR70ŨHQѝ=@hk]`%!!A!6DS hA( 431gW21ЉЎmIƌTH  5aD@z1_ k'l؄qN bo~('UEVDdy02ɸ{?BaK6tN* <*~pS>k7y6Xʄ*Q<,Z#jB "ZŔ; |PKXLr}֧ *QOԄF 汌JQ< pY?\ ٮ^RhSh H*XؐlD%XNv ' sNeyDz Ŭ]@c@Hpg1(CrDDLPB#VSAj} ` lx_rzuROy%>wgf>0j eP &' HչV&ܾ:*#_u6!Jduw݊TVD YB|VɄo4IDcND !;qGs}@n)ȳF=5!Qc xކE Zf!JlXh jM83UERuiu6dЧYy^DIqf;#FZc&Bt!G3$)wXwwL,O揔Nτp'cF, c]qM]Fc"^!" -NeU+)v)Ҡ94OoC֋s AפVGJ"Ga@6dϱ :u(7йOkhۺ,|Lu"&-onj4]hp,IO7Ey3d-LWE2F'XFh_n|K^Z};YONyeG%{@5jTFMkԨ %1 Iz*@үA[&l;Tq8(.0YHޙLRw[=ϱ',Yc5ൃ7^xCl&b)rX-Yq+zI,U"^)YJlKQbg9 cllu`s^瘮>~tWWU_5߯~,H|-Gbg>Zf¾LT @%V9}r|l$bX2K,yX"c2­'W& "V|JEJ >@F.{"zE@g"V#pW=YAr+!åX ڞL4fm>x^_inN"wQ[6`3Q$2"LdiRBe&d,R9~`}c|*Ǧ2:G"%KfBnD*ٗ\{Z~ ErYV%/?0q5"u׌"~fwItro2/MDgbE !Rq ű0e?{RRiAG93= [8mxu_ފyJ #e0Mut*9 o(zm̼day_/օFIu\`2պQ=VoGLz H[ϕmVq ES/| itq áȊ7]DޏX@# dr2 d'+r#2d&iSW1tj\brKD$i).K!Ēqd¾!^Ƒ7!{a_bL(b-:_o*  t{".}HS]N#&c&r0蓩i4hT~0+ V_'Bf5"<{ۏ߆n!V )z{,&v!#WcXκƨZ2Dm%o5Yo:$i1:-s JȔʮ|[uV/I( 'ZT$ ُPqʹJ\5I 'el׹mjyڞ/t6EC\r~*~<>a C a h(X\Q X 'R&q˪ W+ B#g٣|5~p;]_"XAH\[|.ba씛UBd! p$:VqrQ ( ڞԽRĞzBu.֨.Sy֝E%>5۴2uS- [UEy ˯٨f3x9S"OAB $ +E"EB F?V pV s\>0&W$M?M4BB.`FF ſe!ȺxF|F.AB1򅈭zQ` 9Yāebᗈ[ir)T Ip(`K37`Gc@8k6D`r\'le)M11oDK ))Le 6S٥ҴMm W;S*hJ kEsE&QDUٴpJzN""V00F-^hF/24=X͉ԎMe{Z^Np&3Psuj,@~QeT|PM!u!8TTųMSnpM.Z;jBΉ-]3m9Wmk5M .yLu=912k mG)B̙Uk5/wayT"h@˖$~ʠAr jlwV9hPTҘSx(cB2?T#mn={]O\Ⱥ'NPl&u|KO(iZ"immlB+ WgӸ!6U tγL"s֏X;c@#TDG=y{-7 <aPIˉO0ȴmJy07Z&sBXgtDzL"/H?dIa q5]W0"{{) ! -$s"g#eG`/BLD40F4.F ut|3RMcy MVD`вyk2@_ƹ2 KҞy?uXe R2q+].@}Qr;A4d2eBN_B[+cM(IwU2ͳet W6l;Ε:g a,( a<%8M$E^A|_1 M0* m4Wt LQC ʩ 7nK|HIF2۔r@q*>P;}-Tv˨}QT>_`roU|)k{IX0+tO-+vg>P`?݉Zl>ДWф_wPGevTE`&+*ȊR\ƌ fPu"uSJېjՓpSYґÁT,|/K`?2L LhU jOF,^s-ەy|%˜Wf5qEEeN4E(/&Vd$d$$Ff,Dq2L«D2D8cl k Q $ BDsmnlFP vaWaU4*E;["gJR؅ +"ej^Wj}HԆQF )C*+vz2̫&"*ΖD&a;".Pu~`2hbY?[~k_zYc+-&'D_R7QFlg3++dfIrq=1o\>gJroV?'UnO>ew۞gme u@#KesPb7(a6:dhVgZ?V2[(dhDg\ҵEoXuj]\|Eo g,"b$ @1#mB߼hy9L[7 Ig4GAdhi*(;:6=s eةd́5}0khn[z vNbKH $ą1HLDjW!k%|yr NnAzwkk%D#'.ٙUQXc’yc|)ù٭6O[Tt˼Jvij"d*4/[{艙UEA[BNC >y)(xL0 eHBDrF~`k+oRs !]i?X]VŤ3孊Iyfz\2_FKfeue帻$f2 oC v1t 9_|~=R $!Q%'dR_f*Ԩl.Kk)բ])Z3s5kVݮ|1wn;2Ljd$F-M.p1+먺"\|brTE0g=c$$MJЈfVB>¥C@kn`v<~"@[[p"/Zե!郂U[oAiNg{3vwBxB,P -~}S ;Xe4qūEDZjiە"3?E!E$ͽ A8bPfn0w|l`m`zSAb BQmC9ַZ,\J7Wθzskpe.Jo =E1HH $0d_ahWT x3^ F_^XzRL=hIA [PB!Mw{il9WfNRwwz@ɟcTٮnANXzCA+,^Rbau_MVAcjkluc3VAt,mNIWi: !CAH ױu"K?Kٙc @[Ĺ@Dzɶu4u$nG&A 44ٺ3S ._ju[ۗiǻɲjlr}mb!uAD[|9|wB}Jkkj `8˹yz,e-nwit2HH7aPB8F`sqΚG ?J|g`:99|2l>FٖXnSŚSclq`sO3KRϧL}_?=Lڌ!NTP 7`f%J`R!{Hx'o IDATu5sיzsfV V3q% nY66I# r^#Jup(t^  B2ݴbphg;r9I-\ݕs}i US]:tsu:9qiIgt_-ו!22~G3s"/EϮa=GW?}mwH?Uc$W{V [`v 2Bq}r2TڪL;k;̡71p ,>Ly)dm[Up|kZ>1HgK]a}  $Q &,Ѷyt>pVQN\ O5]HLĠiƧV+=}f0x+|EiOŲ/YjJ /I5_k\˒Dsbv5Do2\|ʵ4;^$ BRB=3ћ?&m⛑0U%K `W0lwNW}MH_&ZNI;NHI(tRtϱʔ#[ӠQ, FkS]%"w>dr.3plu cA2ZT {|,ER cg3a'l&:KfشQ|NQ C8!zG:jy,xuZ2ˑ=0%$|].!܄HyuNê7d,ŽjC|'5Ai*HDZs3:#sJ=LXlvhQI9RZF c/# V ܳ/LUiﶒo4Y ιv`PG|FdK@ S ɸ&G8ޕDl?*d؇z߂\>k[a"kc41hB &Ǜ3bEV#1v3o뀛m'ZBFF,ڱDQGPv(MXtIb1F'U,-&0X;+&R^,Վ2Ve;*p!ͬWl3Y?d؏2(wV^N.Kf`Yᡉ4@m(U z̮apH-]\[}rc0gX@ј #1:s}1٣NEЛ Bp/v+3P<(uR<$o~ V胃g{E'Z ǢWS++P[TN,A@},R$0Ayg3BcI4 "@HԅKQВ[$]M&Kye@y[T$+fND\K1 9|}51dz TXCbPŔv8o. M"T]لu3QqY$tt#dܡL 8O-JduY}z``MPa:+G/2hܖ|׬|&kWlAPfV@Cf ːG.bsΏq'Cj/YCYҋ`&Kѳb+Q?U'mA:ӯUF/v/J#̊3kPInj!سAYvw C !!uhJX3.1 zQڠ¤(("GB9G%]8#!g,0N$ODof*&}qDUe4,{YelWB mHO[کZ<{a5ޑo+y|V"Yw}.LNwqt~f6أL!#LmZ9ʊB1kZwRAnw:a$n(Mo&~B#Q[ "q^T>ĠbE($Tv{E3 B7 y.8Pˢ"Hm-q_5ڧM*(>N;LyhYM+zml55}/# }A =}.%X\wB!!uq7i񃞳(DLSO/"gb MoPc, GLܵl#.YwAź&%ݱ&ٲj20{VBD7`y[]rP(< Zzf"%6D+Z]k"'mL௩hjl@jyxýIc= $QO Sݰ&,m&{FlHg:CZ:gM;]Q(S1KE*3C}y )P쮒#ho1HiF*sS!h<iB/v%e{}t t~`bbL3V$UگF(tTKŁ6B:-dzܨ&+ȞRJb-芁6ScѩjsˀwRK#<h]2UmB,6!iGrjgN3]!!^)Z|;UzXoca?#2Jer~dLvn[#bb0?Чdð?yu]YA?S_Sd*_Fd5 <տc*+ }y8b( z4><[qK2eZu⽥P̙2Z 5w܂j}"% ǹ)⹁2\A#!eNjx1x[\dX-yC]a+a.NP <52[UQXe5908*3x/iEݖy0Y ͹ʛ\L})j4qB9nkòl[JH $iB "XGMAֿ~19ɸB2GW@MeHEBdU418b(,A^Tiq-VkkW\A+yl|qTj{۸D<H:He)^] :#BX:#cӴBDǮB$3hD/hBsRr+kv } |;*&V)$1R|dsU#W#C,gW W1ߙ ȥsօBB: -dTt,JDE48siB[4D)4 Aq%8AY?qjӳX\w23Nj0{DIm>m̷Dȸ|Sh9U2=WՉ2 (tc1"VtԿr pi w\GNf(w|leppX,wDߓĢ.W5Qʫ =h2F_j8.኎S%/p0S;!6UەUz+!Z$PKkRS jqǴB#h?R] &+Z'ل9UHmD.Al\Е0̒S;mrnzu3:J_k`S[մ;F ћ X2,U,tVڝεe1d2Ӆ8BԎLgMZ]2 7Vg$ǁ0zeuY5XSyÉt:%m+!#BBFN,C Hr KttlbKQ]E%fR@Yƙv1RYK }qaς=yJ CR*93@^4%rl3<n|y1;Y, 4Z$uKb3~YMגbCAHV bbQ)BTN }",ܝT a&-$ ./ΰ<|)p~-D.y!5\H!䅉$6li{[6)|Al\InR( iё2@Ü>.WzvVs-m0eKɮvD\GRIҗ@vP(%*°tE:XP:*IƠV͈q] J83pgYḊB!!.*6j(u e?ߨV03h2!X;MοBkzgԿ+""~ݰyk լ2k*.-$X9_\v>9Z~$z %!à='B:JNqyIvZgy ~B0#ʱ6kA5O{|ŤDGKی sR涛\E,d8A? c)V0^qV t j^ i#O/AL;^DsM Tv<'(3'ϫm]vA gٖD}iKB}CD=<% \ # kDiM@Y j7<=.ŠgtQB&bc#x,u|L"N;4@{.>o(8&xaܷn2]3j00 rt# ]`v5<@.˵K\,رZ_%6WSJB8@AHڝIؠZ脺~MLsTυAG"gth $4Yy*gO`7 @2DR.ڗ}Dce}>EbLm]\Avv2 !0?2t ?:L2˄s4 (s45bb3:/{=KvzHd/w}"7M(bXlT[oPQҘx,|༫!#w;W^%2tFuQra8tTơ #k`gP(i2jdG+B`?G /AawHڽ1yE.ĚfQzba?/BbGu-u4ǯwQ2OT\!$/:jcn9kipDT?Xz& -9G" %drynm+Jsڣ2VB?LzGRkcYPW>~s{r5peӰ5:.2tDHhcb)a-ߜ;ɾ HټՀ !cTD %Kwh$wUʲX E}ߑ`E@NDRu,i2My[PTJ"0nSBCd*xWCm3!S!!.|Qa ȊACbf( 4* ;B 2lV6aRvq"n˴A(4>yVZD3OfeUn) $d $E/Q*µ my> r+.5 meQ NQYO0\Ġ|[i5A}iמ xIRU|"+b FdӖs\Ƀs  u,2+/rOzgotcWJK,P^gjП2b7\^a\zU鮤&QFow)8W\nɄQF 0 rj~a8s5 + YF\;+| H͟ø^H>חM9JYu?GU<Ӧ&P۶743K[vYgJ^E&ԁPGNJ}`ӏخx* 2ӆ.,;}-)Q#°pmB6 KФ^E<2UxL맶I[9^VJ}>e&L*CHHm#,^u7Y|;KVUt+`bj쌐׳P]cjMhEu:R2n{]D(t\ $ZTgcdb𫝧_q w};.WM~Ln5ȋcg₲J8W*Vf`)e i72OwьRn Qf IDATɢ/_KqYI]aAAHH6S ˼'.v[ߠ"sѣzB{Ǧ($#s Lis!zta,0YWUy%s p2\꞉2:n6ff /WxPxo2/=M=vm6!]"tq4c3PI#&41,:ɕ;EfQX] $L+a{ G$e-P@ ~=]EawRFJQGf\\e'|hWc)ZgW !!!eimH-elӣ2 ~slH4`{AYo'yl?eηio%rKQ#;hf"z+ !!!u3!/2ԧ[Ecskj'&T|V3WʬD<|,hAfCVy&j(s߄ !!uhSB`(,YtG&\kX :Y"De/oHZrapU,98&}EX}>T2 4!!!!uVŹrsO. 錸a9:GO7[pi,KYQ7Lʾ&UK ֶ@zX ;C662g0ʼLzeBZ%(NB.%BAnuAH%Foawt˛j `{yyXݯuM@iDի !-ԥU1w( 2OKXjg $mPqޠ[mzVR8f[ ]Gj[ ;|^\6r'WئbBJu 4I:-Q#J\Zc[ďҋՏ.-J3} b8WJ[ &k-?b(BP:V:ɭ5jFVi.5&24 X*azoNμ./[K[X:?5+ϲiGLmYԶUlͼՁ2h!$IZ:(љv[ a[֎_w[': (&8uS>kb*+ꪯٞƞm=4Cq1QV#th^BX3Ul6PUDIb2!k@&ce{ʻT8W4YE|vfi$ XEaTh&a Sd3q(r u ¦%z]mVKMAH]F S,:\삩Zӫo,|MZTZYw %eLٮOu(; Y2841z 4B8AAHȤѸy"Bwݼ#yՅpdoiĕz_H5/4G9%ʜov2.ɿ=X'BHAd1 +[}ܡSU|P>Bj2DuE}2YKܸa :0ڱ6*TF C 3!* V؏G|',=yb'9R.=MT|NL~EBÿlE:ƗǞ悪߬k{SNb axeg+b/!6BrApXݽ2 ^d1a\ t{߯1ěMI巛dYcw\&gl46d8"l/[m( t( &r,fkjA5)- hjr$ FH낾*Ds|mJt|nz:ӹۈ֭1&Ta0^E ֜c歇`R;K6g#PuH$ ש߁1ҽ Q$L.Y\Oc+RZ9?LBb]C ! 1?tv"ph~su NiU"f  CȰeݤnL͊%ԑΦ*Nmͯ,pSeV-Vƅ _B BB/ UU2gdؖT*RKJP=I,-{ _H)S(M^" ,<}Кu!( &d/AZ_>MQeW~RęUR 9&miךBAHp'j).m95.$jeWRp wbh0y!@0 26:DI)p A[|v'е`BS{R )) !CBB)D{nj[ 9>s[s5-W|PsO>AQf.>WP$XS{P#BP2Jj(4BӅ^kscsR9u*}@ѷw\)#AAHȨ(4&--c¨7y&\rMBS%a4SNA"`7[ BEaY bߦ(wj0 u d(VQ)42jEJ/( Hp7V27K05ך(3!#e(̳+,ہn869@Z>=Mʴ!Sp_;! !:&MW,i2 } #䙚ze4p؅ߌ.Յ2P%`%jU$LڢRM_Ԝie@S8ԑ2PE:XȯhL5u^uM. UZв_Mgu%ތs1't` # gTOW}e-)5]'}>D0ﳯDP.[o?XBLm!ԇBBLg-faԷ5A 2*5D՟D0ہ:eaQz9c$!Pu:# Vlވ8>b`2K*0WM4϶2LL$|n.AAHH / "lވ>8BkE٨5% :hإPxN2\s"d>u.f4 )0BF !!B\E?6Id1##!!̌i"Bȴv(  !B!8@QWB&)-IK:TBx@AH8c7!gBxYLc,ŔܗD'96B h!$dҠ-.wQޗ[BcABA !! Q`ݺTt |(!!!G ޓn_)D BLRj:!v\By'( !CcL3$HaJeUtO&Vw Nj MeׇBT*B"lBĶ3@!Gi Yb]x! 2JPX &]]y)Ϩ!S?fB0,&q%!U6HKNc[AhBȰ*[,PqRjʱx@TS~tB!Q*m",|9;IS}hqQ~] v%!da+N.Kk<82 T~O|\tqgVtLv}9Ӵfy#BPBH;͠ lQ IJz9B!B>2J!B!S !!B!L)B!2PB!BȔBAH!B!S !!B!L)B!2PB!BȔBAH!B!S !!B!L)B!2PB!BȔBAH!B!Sʌoµk׶YNrQWB!BZBB!BR( !B!dJ $B!)B!B BB!BR( !B!dJ $B!)B!B BB!BR( !B!dJ $B!)B!B BB!BR( !B!dJ $B!)B!B BB!BR:%?|ϏB!2̌*'p~7?яϏ:2Q|7 .wމ[oj۷cϞ=XZZCgsssv*||GTw8̶6;.ۇ;~ԡS݋[駟ƃ> G!G;vcŝwi0t)`ݺu[on'dK.wQWL>(%袰Mocaa+i: r ~!Ο gy֭[qEk6jBԱqF\pxugW\qE4O{ 2,1xqǍ*d>,RgŦMÙm!;߉Oؽ{7^~kV B8|0nvlڴ ۷o~3<裕B![lM{n غu+ 9眓nW}hM)<.'?s=m۶aػwu{#-1+8Ν;qwL{Iᡇ/K|ݻq'R˚5kp饗oSO=5tR/sņ p=tJ!777šN/vڅ۷cv[#RB\b;駟nMvZ\r%FA. ^z)N9O>믿]wn, ߿O?tkرw|QW@Ǣxq7__=!L$x;p7 7ܐo9tnܜAu_w#!T1XݻvZlٲuꫯƕW^XjVZ+qWguU  s9gUH鬅P% Cݻ?<>я]zJֈ?^~u&d9ӱuV}طo1Cn0 guqK/O~{OdQ6=V1a,..W^p Ї>;mio~7 n޼;w̸?8x 6n~%Ge]5z˖-ˆP#2L ! я~ԪEq~-pwG\~.lAطoଳŸ>Ow~w} 7x# ֭J||;xWzҽUW]k??ù[x^7nEB/ƫݻwOO?gy&ك}ᢋ.Š+r}cÚ5k{nرcntB^^z)V^]vW_uHM^}Uڵ+so wqyOK/d<+F"֯_^{p5< 8sN}#sEG>w׿~|+\~kq={?i\| /pW[]عs'/> ~_o駟+V+ėet;v>|;"/w}8餓8~7֬YXZZC=}c{qgó>g}{piƶmo{qꩧ{^x=wq8x .xVZe2`Æ ضmy<|?&|{g|3 /Zd X\\?7qKu钻lڴ;j4_}UkZp]wY $M1vBz r y\tEx{;zlܸ/bQG;'|2|4SO=FZfM:zkKw '`nn.w:tr j*:ӹ`B.u[o7_ucʕXn]Ay/1'yҭ]^/]wСCX\\1 0;;Yg:W!7o۱g<<ك۷7'sKQ0!fl-]cÇ0|;ށ5ks1/}KtIZӾo9u;G>bMw17ƍ!{WX DtZz5r!vM7km钴꾥%\G5\ RrJ.YBH̨ !.mYduVJȑN1ւp͚58s!7<2W_}5cZj_sy:tIڕ+W⭷J%1t=={rۏ9}N~Nߧ0 1;;; ٌPT?=B'x.g}61S{8Sp_Wθp;S3L(IDATtRuann/Rnk5k`vvKKKXnpakue,jtD1CaժUˉWW#GXGc׮]رc?x~tXbvu#ИæMgoذ$:|(\sq޽T+2,f.!矏3<wq~|d{ŋ//~8묳صk0w\veزe >bW]u/5ooG3<_ӟO<>k.gk{p%`֭رcz>7n3G<6mڄ 6`Xzu~۶m? t>ׯLJ?aKxW077ƍ\#d9tz:tgpǎJ&{,>d-! /BNڦLa_j&޽{կ~kC=N94B 'SN9ice!ܰa>я_M7ԙ0ğk_.b~7q 'ફ믿/i5k֤-?#կ *{9\yҗ+W3{<}RJtM qiᩧJ-QGm۶ȑ#qѨLa>>O_-iP\m\# i&\r%΅I9p?!QWLKkac޽w͛7cڵe& _.2\z饩דO>믿]w I{bXv-?3ךv9 A>llܸ'Gyq߷-|[mO;|0/-ٳ8'PgժU8csYӼVw{Gǒ2E閖pm嶫Ae\G1W_q{u\>?;4#"lݺպN7ވvdQ.B\xFQOd][lI0Į]k׮QW B;O 7Zڝ֭ù瞋tM2't{9QW2d8]v8.r-6裏6n'j*ر#nߵkWmAH[qNQsNd\{i "QBN\n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Translate Toolkit 1.13.0\n" #: AboutDialog#1 msgid "About" msgstr "Sobre" #: AboutDialog#2 msgid "Contributor" msgstr "Contribuinte" #: AboutDialog#3 msgid "" "\n" "\n" "

<" "br />

" msgstr " \ n \ np, li {espaço em branco: pre-wrap; } \ n \ n


" #: AboutDialog#4 msgctxt "AboutDialog#4" msgid "OK" msgstr "Está bem" #: AboutDialog#5 msgid "" "Kylin Video is developed on the basis of SMPlayer, is a graphical interface " "for MPlayer and MPV." msgstr "O Kylin Video é desenvolvido com base no SMPlayer, é uma interface gráfica para o MPlayer e o MPV." #: AboutDialog#6 msgctxt "AboutDialog#6" msgid "Kylin Video" msgstr "Vídeo Kylin" #: AboutDialog#7 msgid "Version: %1" msgstr "Versão 1" #: AboutDialog#8 msgid "Using Qt %1 (compiled with Qt %2)" msgstr "Usando Qt% 1 (compilado com Qt% 2)" #: AboutDialog#9 msgctxt "AboutDialog#9" msgid "Playback engine:" msgstr "Mecanismo de reprodução:" #: ActionsEditor#1 msgid "Shortcut" msgstr "Atalho" #: ActionsEditor#2 msgid "Description" msgstr "Descrição" #: ActionsEditor#3 msgid "Name" msgstr "Nome" #: AudioDelayDialog#1 msgid "Audio delay" msgstr "Atraso de áudio" #: AudioDelayDialog#2 msgctxt "AudioDelayDialog#2" msgid "OK" msgstr "Está bem" #: AudioDelayDialog#3 msgctxt "AudioDelayDialog#3" msgid "Cancel" msgstr "Cancelar" #: AudioDelayDialog#4 msgid "Audio delay (in milliseconds):" msgstr "Atraso de áudio (em milissegundos):" #: BaseGui#1 msgctxt "BaseGui#1" msgid "Kylin Video" msgstr "Vídeo Kylin" #: BaseGui#2 msgid "Open" msgstr "Abrir" #: BaseGui#3 msgid "Open &File..." msgstr "Abrir arquivo..." #: BaseGui#4 msgid "Directory..." msgstr "Diretório..." #: BaseGui#5 msgid "&URL..." msgstr "& URL ..." #: BaseGui#6 msgid "&Clear" msgstr "&Claro" #: BaseGui#7 msgid "Recent files" msgstr "Arquivos recentes" #: BaseGui#8 msgid "Play control" msgstr "Controle de reprodução" #: BaseGui#9 msgid "Forward and rewind" msgstr "Avançar e retroceder" #: BaseGui#10 msgid "&Jump to..." msgstr "&Pule para..." #: BaseGui#11 msgid "Play Speed" msgstr "Velocidade de jogo" #: BaseGui#12 msgid "Normal speed" msgstr "Velocidade normal" #: BaseGui#13 msgid "Half speed" msgstr "Meia velocidade" #: BaseGui#14 msgid "Double speed" msgstr "Velocidade dupla" #: BaseGui#15 msgid "Speed -10%" msgstr "Velocidade -10%" #: BaseGui#16 msgid "Speed +10%" msgstr "Velocidade + 10%" #: BaseGui#17 msgid "Speed -4%" msgstr "Velocidade de -4%" #: BaseGui#18 msgid "Speed +4%" msgstr "Velocidade + 4%" #: BaseGui#19 msgid "Speed -1%" msgstr "Velocidade -1%" #: BaseGui#20 msgid "Speed +1%" msgstr "Velocidade + 1%" #: BaseGui#21 msgctxt "BaseGui#21" msgid "Next" msgstr "Próximo" #: BaseGui#22 msgid "Previous" msgstr "Anterior" #: BaseGui#23 msgid "&Auto" msgstr "&Auto" #: BaseGui#24 msgid "&Disabled" msgstr "&Desativado" #: BaseGui#25 msgid "Aspect ratio" msgstr "Proporção da tela" #: BaseGui#26 msgid "&Off" msgstr "&Fora" #: BaseGui#27 msgid "&Rotate by 90 degrees clockwise and flip" msgstr "& Rodar 90 graus no sentido dos ponteiros do relógio e virar" #: BaseGui#28 msgid "Rotate by 90 degrees &clockwise" msgstr "Rodar 90 graus e no sentido horário" #: BaseGui#29 msgid "Rotate by 90 degrees counterclock&wise" msgstr "Gire em 90 graus no sentido anti-horário e sábio" #: BaseGui#30 msgid "Rotate by 90 degrees counterclockwise and &flip" msgstr "Gire 90 graus no sentido anti-horário e & flip" #: BaseGui#31 msgid "Fli&p image" msgstr "Imagem Fli & p" #: BaseGui#32 msgid "Mirr&or image" msgstr "Mirr e ou imagem" #: BaseGui#33 msgid "Frame rotation" msgstr "Rotação do quadro" #: BaseGui#34 msgid "&Rotate" msgstr "E girar" #: BaseGui#35 msgid "&Screenshot" msgstr "Captura de tela" #: BaseGui#36 msgid "&Always" msgstr "&Sempre" #: BaseGui#37 msgid "&Never" msgstr "&Nunca" #: BaseGui#38 msgid "While &playing" msgstr "Enquanto jogando" #: BaseGui#39 msgid "S&tay on top" msgstr "Fique no topo" #: BaseGui#40 msgid "Order play" msgstr "Peça de ordem" #: BaseGui#41 msgid "Random play" msgstr "Jogada aleatória" #: BaseGui#42 msgid "List loop play" msgstr "Listar jogo de loop" #: BaseGui#43 msgid "Play order" msgstr "Ordem de jogo" #: BaseGui#44 msgid "&Stereo" msgstr "&Estéreo" #: BaseGui#45 msgid "&4.0 Surround" msgstr "& 4.0 Surround" #: BaseGui#46 msgid "&5.1 Surround" msgstr "& 5.1 Surround" #: BaseGui#47 msgid "&6.1 Surround" msgstr "& 6.1 Surround" #: BaseGui#48 msgid "&7.1 Surround" msgstr "& 7.1 Surround" #: BaseGui#49 msgid "&Channels" msgstr "E canais" #: BaseGui#50 msgctxt "BaseGui#50" msgid "Audio" msgstr "Audio" #: BaseGui#51 msgid "&Mute" msgstr "&Mudo" #: BaseGui#52 msgid "Volume -" msgstr "Volume -" #: BaseGui#53 msgid "Volume +" msgstr "Volume +" #: BaseGui#54 msgid "Delay -" msgstr "Atraso -" #: BaseGui#55 msgid "Delay +" msgstr "Atraso +" #: BaseGui#56 msgid "Set dela&y..." msgstr "Definir dela ..." #: BaseGui#57 msgid "&Left channel" msgstr "E canal esquerdo" #: BaseGui#58 msgid "&Right channel" msgstr "Canal direito" #: BaseGui#59 msgid "&Mono" msgstr "&Mono" #: BaseGui#60 msgid "Re&verse" msgstr "Marcha ré" #: BaseGui#61 msgid "&Stereo mode" msgstr "E modo estéreo" #: BaseGui#62 msgctxt "BaseGui#62" msgid "Subtitles" msgstr "Legendas" #: BaseGui#63 msgid "Load..." msgstr "Carga..." #: BaseGui#64 msgid "Subtitle &visibility" msgstr "Legenda e visibilidade" #: BaseGui#65 msgid "Preferences" msgstr "Preferências" #: BaseGui#66 msgid "View &info and properties..." msgstr "Ver e informações e propriedades ..." #: BaseGui#67 msgctxt "BaseGui#67" msgid "Help" msgstr "Socorro" #: BaseGui#68 msgid "About &Kylin Video" msgstr "Sobre o & Kylin Video" #: BaseGui#69 msgid "Quit" msgstr "Sair" #: BaseGui#70 msgid "Open Homepage" msgstr "Homepage Aberta" #: BaseGui#71 msgid "Open screenshots folder" msgstr "Abra a pasta screenshots" #: BaseGui#72 msgctxt "BaseGui#72" msgid "PlayList" msgstr "Lista de reprodução" #: BaseGui#73 msgid "Play/Pause" msgstr "A pausa" #: BaseGui#74 msgctxt "BaseGui#74" msgid "Stop" msgstr "Pare" #: BaseGui#75 msgid "Fullscreen" msgstr "Tela cheia" #: BaseGui#76 msgid "Video filters are disabled when using vdpau" msgstr "Os filtros de vídeo são desativados ao usar o vdpau" #: BaseGui#77 msgid "-%1" msgstr "-% 1" #: BaseGui#78 msgid "+%1" msgstr "+% 1" #: BaseGui#79 msgid "" msgstr "" #: BaseGui#80 msgid "Confirm deletion - Kylin Video" msgstr "Confirme a exclusão - Kylin Video" #: BaseGui#81 msgid "Delete the list of recent files?" msgstr "Excluir a lista de arquivos recentes?" #: BaseGui#82 msgid "Choose a file" msgstr "Escolha um arquivo" #: BaseGui#83 msgctxt "BaseGui#83" msgid "Multimedia" msgstr "Multimídia" #: BaseGui#84 msgctxt "BaseGui#84" msgid "Video" msgstr "Vídeo" #: BaseGui#85 msgid "Playlists" msgstr "Listas de reprodução" #: BaseGui#86 msgctxt "BaseGui#86" msgid "All files" msgstr "Todos os arquivos" #: BaseGui#87 msgctxt "BaseGui#87" msgid "Choose a directory" msgstr "Escolha um diretório" #: BaseGui#88 msgid "&Jump to:" msgstr "&Pule para:" #: BaseGui#89 msgid "Kylin Video - Seek" msgstr "Vídeo de Kylin - busca" #: BaseGui#90 msgid "Kylin Video - Subtitle delay" msgstr "Vídeo Kylin - Atraso de legendas" #: BaseGui#91 msgid "Subtitle delay (in milliseconds):" msgstr "Atraso de legendas (em milissegundos):" #: BaseGui#92 msgid "Error detected" msgstr "Erro detectado" #: BaseGui#93 msgid "Unfortunately this video can't be played." msgstr "Infelizmente este vídeo não pode ser reproduzido." #: BaseGui#94 msgid "The server returned '%1'" msgstr "O servidor retornou '% 1'" #: BaseGui#95 msgid "Jump to %1" msgstr "Ir para% 1" #: BaseGui#96 msgid "%1 Error" msgstr "% 1 erro" #: BaseGui#97 msgid "'%1' was not found!" msgstr "'% 1' não foi encontrado!" #: BaseGui#98 msgid "%1 has finished unexpectedly." msgstr "% 1 terminou inesperadamente." #: BaseGui#99 msgid "Exit code: %1" msgstr "Código de saída:% 1" #: BaseGui#100 msgid "%1 failed to start." msgstr "% 1 falhou ao iniciar." #: BaseGui#101 msgid "Please check the %1 path in preferences." msgstr "Por favor, verifique o caminho% 1 nas preferências." #: BaseGui#102 msgid "%1 has crashed." msgstr "% 1 caiu." #: BaseGui#103 msgid "See the log for more info." msgstr "Veja o log para mais informações." #: BaseGui#104 msgctxt "BaseGui#104" msgid "Information" msgstr "Em formação" #: BaseGui#105 msgid "The screenshot folder does not exist!" msgstr "A pasta de screenshots não existe!" #: BottomWidget#1 msgctxt "BottomWidget#1" msgid "Stop" msgstr "Pare" #: BottomWidget#2 msgid "Prev" msgstr "Anterior" #: BottomWidget#3 msgid "Play / Pause" msgstr "A pausa" #: BottomWidget#4 msgctxt "BottomWidget#4" msgid "Next" msgstr "Próximo" #: BottomWidget#5 msgid "Mute" msgstr "Mudo" #: BottomWidget#6 msgid "Play List" msgstr "Lista de reprodução" #: Core#1 msgid "Screenshot NOT taken, folder not configured" msgstr "Captura de tela NÃO capturada, pasta não configurada" #: Core#2 msgid "Screenshots NOT taken, folder not configured" msgstr "Capturas de tela NÃO tiradas, pasta não configurada" #: Core#3 msgid "\"A\" marker set to %1" msgstr "Marcador "A \" definido para% 1" #: Core#4 msgid "\"B\" marker set to %1" msgstr "Marcador \ "B \" definido para% 1" #: Core#5 msgid "A-B markers cleared" msgstr "Marcadores AB apagados" #: Core#6 msgid "Brightness: %1" msgstr "Brilho:% 1" #: Core#7 msgid "Contrast: %1" msgstr "Contraste:% 1" #: Core#8 msgid "Gamma: %1" msgstr "Gama:% 1" #: Core#9 msgid "Hue: %1" msgstr "Matiz:% 1" #: Core#10 msgid "Saturation: %1" msgstr "Saturação:% 1" #: Core#11 msgid "Speed: %1" msgstr "Velocidade:% 1" #: Core#12 msgid "Volume: %1" msgstr "Volume 1" #: Core#13 msgid "Subtitle delay: %1 ms" msgstr "Atraso de legendas:% 1 ms" #: Core#14 msgid "Audio delay: %1 ms" msgstr "Atraso de áudio:% 1 ms" #: Core#15 msgid "Subtitles on" msgstr "Legendas em" #: Core#16 msgid "Subtitles off" msgstr "Legendas desativadas" #: Core#17 msgid "Aspect ratio: %1" msgstr "Proporção:% 1" #: Core#18 msgid "Mouse wheel seeks now" msgstr "Roda do mouse procura agora" #: Core#19 msgid "Mouse wheel changes volume now" msgstr "A roda do mouse altera o volume agora" #: Core#20 msgid "Mouse wheel changes zoom level now" msgstr "A roda do mouse altera o nível de zoom agora" #: Core#21 msgid "Mouse wheel changes speed now" msgstr "A roda do mouse muda de velocidade agora" #: Core#22 msgid "Zoom: %1" msgstr "Zoom:% 1" #: Core#23 msgid "Screenshot saved as %1" msgstr "Captura de tela salva como% 1" #: Core#24 msgid "Updating the font cache. This may take some seconds..." msgstr "Atualizando o cache da fonte. Isso pode demorar alguns segundos ..." #: Core#25 msgid "Buffering..." msgstr "Carregando..." #: Core#26 msgid "Starting..." msgstr "Iniciando..." #: ErrorDialog#1 msgid "MPlayer Error" msgstr "Erro do MPlayer" #: ErrorDialog#2 msgctxt "ErrorDialog#2" msgid "OK" msgstr "Está bem" #: ErrorDialog#3 msgid "icon" msgstr "ícone" #: ErrorDialog#4 msgid "Oops, something wrong happened" msgstr "Oops, algo de errado aconteceu" #: ErrorDialog#5 msgid "Error" msgstr "Erro" #: ErrorDialog#6 msgid "Show log" msgstr "Mostrar log" #: ErrorDialog#7 msgid "Hide log" msgstr "Ocultar log" #: EscTip#1 msgid "Press ESC to exit full screen mode" msgstr "Pressione ESC para sair do modo de tela cheia" #: FileChooser#1 msgid "Click to select a file or folder" msgstr "Clique para selecionar um arquivo ou pasta" #: FilePropertiesDialog#1 msgctxt "FilePropertiesDialog#1" msgid "Kylin Video - Preferences" msgstr "Vídeo Kylin - Preferências" #: FilePropertiesDialog#2 msgid "Properties" msgstr "Propriedades" #: FilePropertiesDialog#3 msgid "&Select the demuxer that will be used for this file:" msgstr "& Selecione o demuxer que será usado para este arquivo:" #: FilePropertiesDialog#4 msgid "&Reset" msgstr "&Restabelecer" #: FilePropertiesDialog#5 msgid "&Select the video codec:" msgstr "& Selecione o codec de vídeo:" #: FilePropertiesDialog#6 msgid "&Select the audio codec:" msgstr "& Selecione o codec de áudio:" #: FilePropertiesDialog#7 msgid "Reset" msgstr "Restabelecer" #: FilePropertiesDialog#8 msgctxt "FilePropertiesDialog#8" msgid "Apply" msgstr "Aplique" #: FilePropertiesDialog#9 msgctxt "FilePropertiesDialog#9" msgid "OK" msgstr "Está bem" #: FilePropertiesDialog#10 msgctxt "FilePropertiesDialog#10" msgid "Cancel" msgstr "Cancelar" #: FilePropertiesDialog#11 msgctxt "FilePropertiesDialog#11" msgid "Information" msgstr "Em formação" #: FilePropertiesDialog#12 msgid "Demuxer" msgstr "Demuxer" #: FilePropertiesDialog#13 msgid "Video codec" msgstr "Codec de vídeo" #: FilePropertiesDialog#14 msgid "Audio codec" msgstr "Codec de áudio" #: HelpDialog#1 msgid "Kylin Video - Help" msgstr "Vídeo Kylin - Ajuda" #: HelpDialog#2 msgctxt "HelpDialog#2" msgid "Help" msgstr "Socorro" #: HelpDialog#3 msgctxt "HelpDialog#3" msgid "OK" msgstr "Está bem" #: HelpDialog#4 msgid "Supported formats" msgstr "Formatos Suportados" #: InputURL#1 msgid "Enter URL" msgstr "Insira o URL" #: InputURL#2 msgctxt "InputURL#2" msgid "OK" msgstr "Está bem" #: InputURL#3 msgctxt "InputURL#3" msgid "Cancel" msgstr "Cancelar" #: InputURL#4 msgid "URL:" msgstr "URL:" #: Languages#1 msgid "Afar" msgstr "Longe" #: Languages#2 msgid "Abkhazian" msgstr "Abecásio" #: Languages#3 msgid "Avestan" msgstr "Avestan" #: Languages#4 msgid "Afrikaans" msgstr "afrikaans" #: Languages#5 msgid "Akan" msgstr "Akan" #: Languages#6 msgid "Amharic" msgstr "Amárico" #: Languages#7 msgid "Aragonese" msgstr "Aragonês" #: Languages#8 msgid "Arabic" msgstr "árabe" #: Languages#9 msgid "Assamese" msgstr "Assamês" #: Languages#10 msgid "Avaric" msgstr "Avaric" #: Languages#11 msgid "Aymara" msgstr "Aimará" #: Languages#12 msgid "Azerbaijani" msgstr "Azerbaijanês" #: Languages#13 msgid "Bashkir" msgstr "Bashkir" #: Languages#14 msgid "Belarusian" msgstr "Bielorrusso" #: Languages#15 msgid "Bulgarian" msgstr "búlgaro" #: Languages#16 msgid "Bihari" msgstr "Bihari" #: Languages#17 msgid "Bislama" msgstr "Bislama" #: Languages#18 msgid "Bambara" msgstr "Bambara" #: Languages#19 msgid "Bengali" msgstr "bengali" #: Languages#20 msgid "Tibetan" msgstr "Tibetano" #: Languages#21 msgid "Breton" msgstr "Bretão" #: Languages#22 msgid "Bosnian" msgstr "Bósnio" #: Languages#23 msgid "Catalan" msgstr "catalão" #: Languages#24 msgid "Chechen" msgstr "Checheno" #: Languages#25 msgid "Corsican" msgstr "Corso" #: Languages#26 msgid "Cree" msgstr "Cree" #: Languages#27 msgid "Czech" msgstr "Checo" #: Languages#28 msgid "Church" msgstr "Igreja" #: Languages#29 msgid "Chuvash" msgstr "Chuvache" #: Languages#30 msgid "Welsh" msgstr "galês" #: Languages#31 msgid "Danish" msgstr "dinamarquês" #: Languages#32 msgid "German" msgstr "alemão" #: Languages#33 msgid "Divehi" msgstr "Divehi" #: Languages#34 msgid "Dzongkha" msgstr "Dzongkha" #: Languages#35 msgid "Ewe" msgstr "Ovelha" #: Languages#36 msgid "Greek" msgstr "grego" #: Languages#37 msgid "English" msgstr "Inglês" #: Languages#38 msgid "Esperanto" msgstr "esperanto" #: Languages#39 msgid "Spanish" msgstr "espanhol" #: Languages#40 msgid "Estonian" msgstr "estoniano" #: Languages#41 msgid "Basque" msgstr "Basco" #: Languages#42 msgid "Persian" msgstr "persa" #: Languages#43 msgid "Fulah" msgstr "Fulah" #: Languages#44 msgid "Finnish" msgstr "finlandês" #: Languages#45 msgid "Fijian" msgstr "Fijiano" #: Languages#46 msgid "Faroese" msgstr "Feroês" #: Languages#47 msgid "French" msgstr "francês" #: Languages#48 msgid "Frisian" msgstr "Frísio" #: Languages#49 msgid "Irish" msgstr "irlandês" #: Languages#50 msgid "Gaelic" msgstr "gaélico" #: Languages#51 msgid "Galician" msgstr "Galego" #: Languages#52 msgid "Guarani" msgstr "Guarani" #: Languages#53 msgid "Gujarati" msgstr "Gujarati" #: Languages#54 msgid "Manx" msgstr "Manx" #: Languages#55 msgid "Hausa" msgstr "Hausa" #: Languages#56 msgid "Hebrew" msgstr "hebraico" #: Languages#57 msgid "Hindi" msgstr "hindi" #: Languages#58 msgid "Hiri" msgstr "Hiri" #: Languages#59 msgid "Croatian" msgstr "croata" #: Languages#60 msgid "Haitian" msgstr "haitiano" #: Languages#61 msgid "Hungarian" msgstr "húngaro" #: Languages#62 msgid "Armenian" msgstr "Armênio" #: Languages#63 msgid "Herero" msgstr "Herero" #: Languages#64 msgid "Chamorro" msgstr "Chamorro" #: Languages#65 msgid "Interlingua" msgstr "Interlíngua" #: Languages#66 msgid "Indonesian" msgstr "indonésio" #: Languages#67 msgid "Interlingue" msgstr "Interlingue" #: Languages#68 msgid "Igbo" msgstr "Igbo" #: Languages#69 msgid "Sichuan" msgstr "Sichuan" #: Languages#70 msgid "Inupiaq" msgstr "Inupiaq" #: Languages#71 msgid "Ido" msgstr "Eu faço" #: Languages#72 msgid "Icelandic" msgstr "islandês" #: Languages#73 msgid "Italian" msgstr "italiano" #: Languages#74 msgid "Inuktitut" msgstr "Inuktitut" #: Languages#75 msgid "Japanese" msgstr "japonês" #: Languages#76 msgid "Javanese" msgstr "Javanês" #: Languages#77 msgid "Georgian" msgstr "Georgiano" #: Languages#78 msgid "Kongo" msgstr "Kongo" #: Languages#79 msgid "Kikuyu" msgstr "Kikuyu" #: Languages#80 msgid "Kuanyama" msgstr "Kuanyama" #: Languages#81 msgid "Kazakh" msgstr "Cazaque" #: Languages#82 msgid "Greenlandic" msgstr "Gronelandês" #: Languages#83 msgid "Khmer" msgstr "Khmer" #: Languages#84 msgid "Kannada" msgstr "Canará" #: Languages#85 msgid "Korean" msgstr "coreano" #: Languages#86 msgid "Kanuri" msgstr "Kanuri" #: Languages#87 msgid "Kashmiri" msgstr "Caxemira" #: Languages#88 msgid "Kurdish" msgstr "curdo" #: Languages#89 msgid "Komi" msgstr "Komi" #: Languages#90 msgid "Cornish" msgstr "Cornish" #: Languages#91 msgid "Kirghiz" msgstr "Kirghiz" #: Languages#92 msgid "Latin" msgstr "Latim" #: Languages#93 msgid "Luxembourgish" msgstr "Luxemburguês" #: Languages#94 msgid "Ganda" msgstr "Ganda" #: Languages#95 msgid "Limburgan" msgstr "Limburgan" #: Languages#96 msgid "Lingala" msgstr "Lingala" #: Languages#97 msgid "Lao" msgstr "Lao" #: Languages#98 msgid "Lithuanian" msgstr "lituano" #: Languages#99 msgid "Luba-Katanga" msgstr "Luba-Katanga" #: Languages#100 msgid "Latvian" msgstr "letão" #: Languages#101 msgid "Malagasy" msgstr "malgaxe" #: Languages#102 msgid "Marshallese" msgstr "Marshalês" #: Languages#103 msgid "Maori" msgstr "maori" #: Languages#104 msgid "Macedonian" msgstr "Macedônio" #: Languages#105 msgid "Malayalam" msgstr "Malaiala" #: Languages#106 msgid "Mongolian" msgstr "mongol" #: Languages#107 msgid "Moldavian" msgstr "Moldavo" #: Languages#108 msgid "Marathi" msgstr "Marathi" #: Languages#109 msgid "Malay" msgstr "malaio" #: Languages#110 msgid "Maltese" msgstr "maltês" #: Languages#111 msgid "Burmese" msgstr "birmanês" #: Languages#112 msgid "Nauru" msgstr "Nauru" #: Languages#113 msgid "Bokmål" msgstr "Bokmål" #: Languages#114 msgid "Ndebele" msgstr "Ndebele" #: Languages#115 msgid "Nepali" msgstr "Nepalês" #: Languages#116 msgid "Ndonga" msgstr "Ndonga" #: Languages#117 msgid "Dutch" msgstr "holandês" #: Languages#118 msgid "Norwegian Nynorsk" msgstr "Nynorsk norueguês" #: Languages#119 msgid "Norwegian" msgstr "norueguês" #: Languages#120 msgid "Navajo" msgstr "Navajo" #: Languages#121 msgid "Chichewa" msgstr "Chique" #: Languages#122 msgid "Occitan" msgstr "Occitano" #: Languages#123 msgid "Ojibwa" msgstr "Ojibwa" #: Languages#124 msgid "Oromo" msgstr "Oromo" #: Languages#125 msgid "Oriya" msgstr "Oriya" #: Languages#126 msgid "Ossetian" msgstr "Ossétia" #: Languages#127 msgid "Panjabi" msgstr "Panjabi" #: Languages#128 msgid "Pali" msgstr "Pali" #: Languages#129 msgid "Polish" msgstr "polonês" #: Languages#130 msgid "Pushto" msgstr "Empurre para" #: Languages#131 msgid "Portuguese" msgstr "Português" #: Languages#132 msgid "Quechua" msgstr "Quíchua" #: Languages#133 msgid "Romansh" msgstr "Romanche" #: Languages#134 msgid "Rundi" msgstr "Rundi" #: Languages#135 msgid "Romanian" msgstr "romena" #: Languages#136 msgid "Russian" msgstr "russo" #: Languages#137 msgid "Kinyarwanda" msgstr "Kinyarwanda" #: Languages#138 msgid "Sanskrit" msgstr "sânscrito" #: Languages#139 msgid "Sardinian" msgstr "Sardo" #: Languages#140 msgid "Sindhi" msgstr "Sindi" #: Languages#141 msgid "Sami" msgstr "Sami" #: Languages#142 msgid "Sango" msgstr "Sango" #: Languages#143 msgid "Sinhala" msgstr "Cingalês" #: Languages#144 msgid "Slovak" msgstr "Eslovaco" #: Languages#145 msgid "Slovene" msgstr "Esloveno" #: Languages#146 msgid "Samoan" msgstr "Samoano" #: Languages#147 msgid "Shona" msgstr "Shona" #: Languages#148 msgid "Somali" msgstr "Somali" #: Languages#149 msgid "Albanian" msgstr "albanês" #: Languages#150 msgid "Serbian" msgstr "sérvio" #: Languages#151 msgid "Swati" msgstr "Swati" #: Languages#152 msgid "Sotho" msgstr "Soto" #: Languages#153 msgid "Sundanese" msgstr "Sundanês" #: Languages#154 msgid "Swedish" msgstr "sueco" #: Languages#155 msgid "Swahili" msgstr "Suaíli" #: Languages#156 msgid "Tamil" msgstr "Tâmil" #: Languages#157 msgid "Telugu" msgstr "Télugo" #: Languages#158 msgid "Tajik" msgstr "Tadjique" #: Languages#159 msgid "Thai" msgstr "tailandês" #: Languages#160 msgid "Tigrinya" msgstr "Tigrina" #: Languages#161 msgid "Turkmen" msgstr "Turcomano" #: Languages#162 msgid "Tagalog" msgstr "Tagalo" #: Languages#163 msgid "Tswana" msgstr "Tswana" #: Languages#164 msgid "Tonga" msgstr "Tonga" #: Languages#165 msgid "Turkish" msgstr "turco" #: Languages#166 msgid "Tsonga" msgstr "Tsonga" #: Languages#167 msgid "Tatar" msgstr "Tatar" #: Languages#168 msgid "Twi" msgstr "Twi" #: Languages#169 msgid "Tahitian" msgstr "Taitiano" #: Languages#170 msgid "Uighur" msgstr "Uigur" #: Languages#171 msgid "Ukrainian" msgstr "ucraniano" #: Languages#172 msgid "Urdu" msgstr "urdu" #: Languages#173 msgid "Uzbek" msgstr "Uzbeque" #: Languages#174 msgid "Venda" msgstr "Venda" #: Languages#175 msgid "Vietnamese" msgstr "vietnamita" #: Languages#176 msgid "Volapük" msgstr "Volapuque" #: Languages#177 msgid "Walloon" msgstr "valão" #: Languages#178 msgid "Wolof" msgstr "Uólofe" #: Languages#179 msgid "Xhosa" msgstr "Xhosa" #: Languages#180 msgid "Yiddish" msgstr "Iídiche" #: Languages#181 msgid "Yoruba" msgstr "Ioruba" #: Languages#182 msgid "Zhuang" msgstr "Zhuang" #: Languages#183 msgid "Chinese" msgstr "chinês" #: Languages#184 msgid "Zulu" msgstr "zulu" #: Languages#185 msgid "Arabic - Syria" msgstr "Árabe - Síria" #: Languages#186 msgid "Unicode" msgstr "Unicode" #: Languages#187 msgid "UTF-8" msgstr "UTF-8" #: Languages#188 msgid "Western European Languages" msgstr "Idiomas da Europa Ocidental" #: Languages#189 msgid "Western European Languages with Euro" msgstr "Línguas da Europa Ocidental com Euro" #: Languages#190 msgid "Slavic/Central European Languages" msgstr "Idiomas eslavos / da Europa Central" #: Languages#191 msgid "Esperanto, Galician, Maltese, Turkish" msgstr "Esperanto, galego, maltês, turco" #: Languages#192 msgid "Old Baltic charset" msgstr "Charset antigo do Báltico" #: Languages#193 msgid "Cyrillic" msgstr "cirílico" #: Languages#194 msgid "Modern Greek" msgstr "Grego moderno" #: Languages#195 msgid "Baltic" msgstr "báltico" #: Languages#196 msgid "Celtic" msgstr "céltico" #: Languages#197 msgid "South-Eastern European" msgstr "Europa do Sudeste" #: Languages#198 msgid "Hebrew charsets" msgstr "Charsets hebreus" #: Languages#199 msgid "Ukrainian, Belarusian" msgstr "Ucraniano, bielorrusso" #: Languages#200 msgid "Simplified Chinese charset" msgstr "Charset chinês simplificado" #: Languages#201 msgid "Traditional Chinese charset" msgstr "Charset chinês tradicional" #: Languages#202 msgid "Japanese charsets" msgstr "Charutos japoneses" #: Languages#203 msgid "Korean charset" msgstr "Charset coreano" #: Languages#204 msgid "Thai charset" msgstr "Charset tailandês" #: Languages#205 msgid "Cyrillic Windows" msgstr "Janelas Cirílicas" #: Languages#206 msgid "Slavic/Central European Windows" msgstr "Janelas eslavas / européias centrais" #: Languages#207 msgid "Arabic Windows" msgstr "Janelas árabes" #: Languages#208 msgid "Modern Greek Windows" msgstr "Janelas gregas modernas" #: LineEditWithIcon#1 msgid "Change" msgstr "mudança" #: MPVProcess#1 msgid "the '%1' filter is not supported by mpv" msgstr "o filtro '% 1' não é suportado pelo mpv" #: MessageDialog#1 msgid "Ok" msgstr "Está bem" #: MessageDialog#2 msgctxt "MessageDialog#2" msgid "Cancel" msgstr "Cancelar" #: MessageDialog#3 msgctxt "MessageDialog#3" msgid "Yes" msgstr "sim" #: MessageDialog#4 msgctxt "MessageDialog#4" msgid "No" msgstr "Não" #: MplayerProcess#1 msgid "This option is not supported by MPlayer" msgstr "Esta opção não é suportada pelo MPlayer" #: Playlist#1 msgid "Playlist is empty" msgstr "A lista de reprodução está vazia" #: Playlist#2 msgid "Add File" msgstr "Adicionar ficheiro" #: Playlist#3 msgctxt "Playlist#3" msgid "PlayList" msgstr "Lista de reprodução" #: Playlist#4 msgctxt "Playlist#4" msgid "Clear" msgstr "Claro" #: Playlist#5 msgid "Add" msgstr "Adicionar" #: Playlist#6 msgid "Play" msgstr "Toque" #: Playlist#7 msgid "Remove &selected" msgstr "Remover e selecionado" #: Playlist#8 msgid "&Delete file from disk" msgstr "& Excluir arquivo do disco" #: Playlist#9 msgid "Reached the end of the playlist" msgstr "Atingiu o final da playlist" #: Playlist#10 msgid "Select one or more files to open" msgstr "Selecione um ou mais arquivos para abrir" #: Playlist#11 msgctxt "Playlist#11" msgid "Multimedia" msgstr "Multimídia" #: Playlist#12 msgctxt "Playlist#12" msgid "All files" msgstr "Todos os arquivos" #: Playlist#13 msgctxt "Playlist#13" msgid "Choose a directory" msgstr "Escolha um diretório" #: Playlist#14 msgid "Confirm remove" msgstr "Confirme remover" #: Playlist#15 msgid "You're about to remove the file '%1' from the playlist." msgstr "Você está prestes a remover o arquivo '% 1' da playlist." #: Playlist#16 msgid "Are you sure you want to proceed?" msgstr "Tem certeza de que deseja continuar?" #: Playlist#17 msgid "Confirm deletion" msgstr "Confirme a exclusão" #: Playlist#18 msgid "You're about to DELETE the file '%1' from your drive." msgstr "Você está prestes a DELETAR o arquivo '% 1' da sua unidade." #: Playlist#19 msgid "This action cannot be undone. Are you sure you want to proceed?" msgstr "Essa ação não pode ser desfeita. Tem certeza de que deseja continuar?" #: Playlist#20 msgid "Deletion failed" msgstr "A exclusão falhou" #: Playlist#21 msgid "It wasn't possible to delete '%1'" msgstr "Não foi possível excluir '% 1'" #: Playlist#22 msgid "Error deleting the file" msgstr "Erro ao excluir o arquivo" #: Playlist#23 msgid "It's not possible to delete '%1' from the filesystem." msgstr "Não é possível excluir '% 1' do sistema de arquivos." #: PrefAudio#1 msgid "Volume" msgstr "Volume" #: PrefAudio#2 msgid "Global volume" msgstr "Volume global" #: PrefAudio#3 msgid "Use software volume control" msgstr "Use o controle de volume de software" #: PrefAudio#4 msgid "Max. Amplification:" msgstr "Max. Amplificação:" #: PrefAudio#5 msgid "Volume normalization by default" msgstr "Normalização de volume por padrão" #: PrefAudio#6 msgid "Synchronization" msgstr "Sincronização" #: PrefAudio#7 msgid "Audio/video auto synchronization" msgstr "Sincronização automática de áudio / vídeo" #: PrefAudio#8 msgid "Factor:" msgstr "Fator:" #: PrefAudio#9 msgctxt "PrefAudio#9" msgid "Output driver:" msgstr "Driver de saída:" #: PrefAudio#10 msgid "Channels by default:" msgstr "Canais por padrão:" #: PrefAudio#11 msgid "2 (Stereo)" msgstr "2 (estéreo)" #: PrefAudio#12 msgid "4 (4.0 Surround)" msgstr "4 (4,0 Surround)" #: PrefAudio#13 msgid "6 (5.1 Surround)" msgstr "6 (5.1 Surround)" #: PrefAudio#14 msgid "7 (6.1 Surround)" msgstr "7 (6.1 Surround)" #: PrefAudio#15 msgid "8 (7.1 Surround)" msgstr "8 (7.1 Surround)" #: PrefAudio#16 msgctxt "PrefAudio#16" msgid "Default" msgstr "Padrão" #: PrefAudio#17 msgid "Audio output driver" msgstr "Driver de saída de áudio" #: PrefAudio#18 msgid "Select the audio output driver." msgstr "Selecione o driver de saída de áudio." #: PrefAudio#19 msgid "" "%1 is the recommended one. Try to avoid %2 and %3, they are slow and can " "have an impact on performance." msgstr "% 1 é o recomendado. Tente evitar% 2 e% 3, eles são lentos e podem ter um impacto no desempenho." #: PrefAudio#20 msgid "Channels by default" msgstr "Canais por padrão" #: PrefAudio#21 msgid "" "Requests the number of playback channels. MPlayer asks the decoder to decode " "the audio into as many channels as specified. Then it is up to the decoder " "to fulfill the requirement. This is usually only important when playing " "videos with AC3 audio (like DVDs). In that case liba52 does the decoding by " "default and correctly downmixes the audio into the requested number of " "channels. Note: This option is honored by codecs (AC3 only), filters " "(surround) and audio output drivers (OSS at least)." msgstr "Solicita o número de canais de reprodução. O MPlayer pede ao decodificador para decodificar o áudio em quantos canais forem especificados. Então cabe ao decodificador cumprir o requisito. Isso geralmente é importante apenas ao reproduzir vídeos com áudio AC3 (como DVDs). Nesse caso, a liba52 faz a decodificação por padrão e ajusta corretamente o áudio para o número solicitado de canais. Nota : Esta opção é respeitada por codecs (somente AC3), filtros (surround) e drivers de saída de áudio (OSS pelo menos)." #: PrefAudio#22 msgid "" "If this option is checked, the same volume will be used for all files you " "play. If the option is not checked each file uses its own volume." msgstr "Se esta opção estiver marcada, o mesmo volume será usado para todos os arquivos que você reproduzir. Se a opção não estiver marcada, cada arquivo usa seu próprio volume." #: PrefAudio#23 msgid "This option also applies for the mute control." msgstr "Esta opção também se aplica ao controle de mudo." #: PrefAudio#24 msgid "Software volume control" msgstr "Controle de volume de software" #: PrefAudio#25 msgid "" "Check this option to use the software mixer, instead of using the sound card " "mixer." msgstr "Marque esta opção para usar o mixer de software, em vez de usar o mixer da placa de som." #: PrefAudio#26 msgid "Max. Amplification" msgstr "Max. Amplificação" #: PrefAudio#27 msgid "" "Sets the maximum amplification level in percent (default: 110). A value of " "200 will allow you to adjust the volume up to a maximum of double the " "current level. With values below 100 the initial volume (which is 100%) will " "be above the maximum, which e.g. the OSD cannot display correctly." msgstr "Define o nível máximo de amplificação em porcentagem (padrão: 110). Um valor de 200 permitirá ajustar o volume até o dobro do nível atual. Com valores abaixo de 100, o volume inicial (que é 100%) estará acima do máximo, o que, por exemplo, o OSD não pode exibir corretamente." #: PrefAudio#28 msgid "Maximizes the volume without distorting the sound." msgstr "Maximiza o volume sem distorcer o som." #: PrefAudio#29 msgid "Gradually adjusts the A/V sync based on audio delay measurements." msgstr "Gradualmente, ajusta a sincronização A / V com base nas medições de atraso de áudio." #: PrefGeneral#1 msgid "Pause when minimized" msgstr "Pausa quando minimizado" #: PrefGeneral#2 msgid "MPlayer" msgstr "MPlayer" #: PrefGeneral#3 msgid "MPV" msgstr "MPV" #: PrefGeneral#4 msgctxt "PrefGeneral#4" msgid "Playback engine:" msgstr "Mecanismo de reprodução:" #: PrefGeneral#5 msgid "Preview when video is playing" msgstr "Visualizar quando o vídeo está sendo reproduzido" #: PrefGeneral#6 msgid "" "If this option is enabled, the file will be paused when the main window is " "hidden. When the window is restored, playback will be resumed." msgstr "Se esta opção estiver ativada, o arquivo será pausado quando a janela principal estiver oculta. Quando a janela é restaurada, a reprodução será retomada." #: PrefGeneral#7 msgid "Preview when the video is playing" msgstr "Visualizar quando o vídeo está sendo reproduzido" #: PrefGeneral#8 msgid "" "If this option is enabled, the video preview will be displayed when the " "mouse is placed on the progress bar." msgstr "Se esta opção estiver ativada, a visualização do vídeo será exibida quando o mouse for colocado na barra de progresso." #: PrefGeneral#9 msgid "Select MPlayer as playback engine" msgstr "Selecione o MPlayer como mecanismo de reprodução" #: PrefGeneral#10 msgid "" "If you change the playback engine to MPlayer, please restart Kylin Video." msgstr "Se você alterar o mecanismo de reprodução para o MPlayer, reinicie o Kylin Video." #: PrefGeneral#11 msgid "Select MPV as playback engine" msgstr "Selecione MPV como mecanismo de reprodução" #: PrefGeneral#12 msgid "If you change the playback engine to MPV, please restart Kylin Video." msgstr "Se você alterar o mecanismo de reprodução para MPV, reinicie o Kylin Video." #: PrefPerformance#1 msgid "Cache" msgstr "Cache" #: PrefPerformance#2 msgid "Cache for local files:" msgstr "Cache para arquivos locais:" #: PrefPerformance#3 msgid "KB" msgstr "KB" #: PrefPerformance#4 msgid "Cache for streams:" msgstr "Cache para fluxos:" #: PrefPerformance#5 msgid "Decode" msgstr "Decodificar" #: PrefPerformance#6 msgid "Threads for decoding (MPEG-1/2 and H.264 only):" msgstr "Threads para decodificação (somente MPEG-1/2 e H.264):" #: PrefPerformance#7 msgid "Hardware decoding" msgstr "Decodificação de hardware" #: PrefPerformance#8 msgid "None" msgstr "Nenhum" #: PrefPerformance#9 msgctxt "PrefPerformance#9" msgid "Auto" msgstr "Auto" #: PrefPerformance#10 msgctxt "PrefPerformance#10" msgid "Performance" msgstr "atuação" #: PrefPerformance#11 msgid "Threads for decoding" msgstr "Tópicos para decodificação" #: PrefPerformance#12 msgid "" "Sets the number of threads to use for decoding. Only for MPEG-1/2 and H.264" msgstr "Define o número de segmentos a serem usados ​​para decodificação. Apenas para MPEG-1/2 e H.264" #: PrefPerformance#13 msgid "" "Sets the hardware video decoding API. If hardware decoding is not possible, " "software decoding will be used instead." msgstr "Define a API de decodificação de vídeo de hardware. Se a decodificação de hardware não for possível, a decodificação de software será usada." #: PrefPerformance#14 msgid "Available options:" msgstr "Opções disponíveis:" #: PrefPerformance#15 msgid "None: only software decoding will be used." msgstr "Nenhum: somente a decodificação de software será usada." #: PrefPerformance#16 msgid "" "Auto: it tries to automatically enable hardware decoding using the first " "available method." msgstr "Automático: ele tenta ativar automaticamente a decodificação de hardware usando o primeiro método disponível." #: PrefPerformance#17 msgid "vdpau: for the vdpau and opengl video outputs." msgstr "vdpau: para as saídas de vídeo vdpau e opengl." #: PrefPerformance#18 msgid "vaapi: for the opengl and vaapi video outputs. For Intel GPUs only." msgstr "vaapi: para as saídas de vídeo opengl e vaapi. Apenas para GPUs Intel." #: PrefPerformance#19 msgid "vaapi-copy: it copies video back into system RAM. For Intel GPUs only." msgstr "vaapi-copy: copia o vídeo de volta para a RAM do sistema. Apenas para GPUs Intel." #: PrefPerformance#20 msgctxt "PrefPerformance#20" msgid "This option only works with mpv." msgstr "Esta opção só funciona com o mpv." #: PrefPerformance#21 msgid "Cache for files" msgstr "Cache para arquivos" #: PrefPerformance#22 msgid "" "This option specifies how much memory (in kBytes) to use when precaching a " "file." msgstr "Esta opção especifica a quantidade de memória (em kBytes) a ser usada ao precazer um arquivo." #: PrefPerformance#23 msgid "Cache for streams" msgstr "Cache para fluxos" #: PrefPerformance#24 msgid "" "This option specifies how much memory (in kBytes) to use when precaching a " "URL." msgstr "Esta opção especifica a quantidade de memória (em kBytes) a ser usada ao preceder um URL." #: PrefScreenShot#1 msgid "Screenshots" msgstr "Screenshots" #: PrefScreenShot#2 msgid "Enable screenshots" msgstr "Ativar capturas de tela" #: PrefScreenShot#3 msgid "Folder:" msgstr "Pasta:" #: PrefScreenShot#4 msgid "Template:" msgstr "Modelo:" #: PrefScreenShot#5 msgid "Format:" msgstr "Formato:" #: PrefScreenShot#6 msgid "Select a directory" msgstr "Selecione um diretório" #: PrefScreenShot#7 msgid "" "You can use this option to enable or disable the possibility to take " "screenshots." msgstr "Você pode usar essa opção para ativar ou desativar a possibilidade de fazer capturas de tela." #: PrefScreenShot#8 msgid "Screenshots folder" msgstr "Pasta de imagens" #: PrefScreenShot#9 msgid "" "Here you can specify a folder where the screenshots taken by Kylin Video " "will be stored. If the folder is not valid the screenshot feature will be " "disabled." msgstr "Aqui você pode especificar uma pasta onde as imagens capturadas pelo Kylin Video serão armazenadas. Se a pasta não for válida, o recurso de captura de tela será desativado." #: PrefScreenShot#10 msgid "Template for screenshots" msgstr "Modelo para capturas de tela" #: PrefScreenShot#11 msgid "This option specifies the filename template used to save screenshots." msgstr "Esta opção especifica o modelo de nome de arquivo usado para salvar capturas de tela." #: PrefScreenShot#12 msgid "For example %1 would save the screenshot as 'moviename_0001.png'." msgstr "Por exemplo,% 1 salvaria a captura de tela como 'moviename_0001.png'." #: PrefScreenShot#13 msgid "" "%1 specifies the filename of the video without the extension, %2 adds a 4 " "digit number padded with zeros." msgstr "% 1 especifica o nome do arquivo do vídeo sem a extensão,% 2 adiciona um número de 4 dígitos preenchido com zeros." #: PrefScreenShot#14 msgid "For a full list of the template specifiers visit this link:" msgstr "Para obter uma lista completa dos especificadores de modelo, acesse este link:" #: PrefScreenShot#15 msgctxt "PrefScreenShot#15" msgid "This option only works with mpv." msgstr "Esta opção só funciona com o mpv." #: PrefScreenShot#16 msgid "Format for screenshots" msgstr "Formato para capturas de tela" #: PrefScreenShot#17 msgid "" "This option allows one to choose the image file type used for saving " "screenshots." msgstr "Esta opção permite escolher o tipo de arquivo de imagem usado para salvar capturas de tela." #: PrefShortCut#1 msgid "" "Here you can change any key shortcut. To do it double click or press enter " "over a shortcut cell. " msgstr "Aqui você pode alterar qualquer atalho chave. Para fazer isso, clique duas vezes ou pressione enter sobre uma célula de atalho. " #: PrefShortCut#2 msgid "ShortCut" msgstr "Atalho" #: PrefShortCut#3 msgid "" "Here you can change any key shortcut. To do it double click or start typing " "over a shortcut cell." msgstr "Aqui você pode alterar qualquer atalho chave. Para fazer isso, clique duas vezes ou comece a digitar em uma célula de atalho." #: PrefShortCut#4 msgctxt "PrefShortCut#4" msgid "Shortcut Key" msgstr "Tecla de atalho" #: PrefShortCut#5 msgid "Shortcut editor" msgstr "Editor de atalhos" #: PrefShortCut#6 msgid "" "This table allows you to change the key shortcuts of most available actions. " "Double click or press enter on a item, or press the Change shortcut " "button to enter in the Modify shortcut dialog. There are two ways to " "change a shortcut: if the Capture button is on then just press the " "new key or combination of keys that you want to assign for the action (" "unfortunately this doesn't work for all keys). If the Capture button " "is off then you could enter the full name of the key." msgstr "Esta tabela permite que você altere os atalhos de teclas da maioria das ações disponíveis. Clique duas vezes ou pressione enter em um item, ou pressione o botão Alterar atalho para entrar no diálogo Modificar atalho . Há duas maneiras de alterar um atalho: se o botão Capturar estiver ativado, pressione a nova tecla ou a combinação de teclas que deseja atribuir à ação (infelizmente isso não funciona para todas as teclas ). Se o botão Capturar estiver desativado, você poderá digitar o nome completo da chave." #: PrefSubtitles#1 msgid "Autoload" msgstr "Carregamento Automático" #: PrefSubtitles#2 msgid "Autoload subtitles files (*.srt, *.sub...):" msgstr "Carregar automaticamente arquivos de legendas (* .srt, * .sub ...):" #: PrefSubtitles#3 msgid "Same name as movie" msgstr "Mesmo nome do filme" #: PrefSubtitles#4 msgid "All subs containing movie name" msgstr "Todos os subs contendo nome do filme" #: PrefSubtitles#5 msgid "All subs in directory" msgstr "Todos os subs no diretório" #: PrefSubtitles#6 msgid "Encoding" msgstr "Codificação" #: PrefSubtitles#7 msgid "Default subtitle encoding:" msgstr "Codificação de legendas padrão:" #: PrefSubtitles#8 msgid "Try to autodetect for this language:" msgstr "Tente se autodetectar para este idioma:" #: PrefSubtitles#9 msgctxt "PrefSubtitles#9" msgid "Subtitles" msgstr "Legendas" #: PrefSubtitles#10 msgid "Select the subtitle autoload method." msgstr "Selecione o método de carregamento automático de legendas." #: PrefSubtitles#11 msgid "Default subtitle encoding" msgstr "Codificação de legendas padrão" #: PrefSubtitles#12 msgid "Select the encoding which will be used for subtitle files by default." msgstr "Selecione a codificação que será usada para arquivos de legenda por padrão." #: PrefSubtitles#13 msgid "Try to autodetect for this language" msgstr "Tente autodetectar para este idioma" #: PrefSubtitles#14 msgid "" "When this option is on, the encoding of the subtitles will be tried to be " "autodetected for the given language. It will fall back to the default " "encoding if the autodetection fails. This option requires a MPlayer compiled " "with ENCA support." msgstr "Quando esta opção estiver ativada, a codificação das legendas será tentada para ser detectada automaticamente para o idioma especificado. Ele retornará à codificação padrão se a detecção automática falhar. Esta opção requer um MPlayer compilado com suporte ENCA." #: PrefSubtitles#15 msgid "Subtitle language" msgstr "Idioma da legenda" #: PrefSubtitles#16 msgid "" "Select the language for which you want the encoding to be guessed " "automatically." msgstr "Selecione o idioma para o qual você deseja que a codificação seja adivinhada automaticamente." #: PrefSubtitles#17 msgid "Font" msgstr "Fonte" #: PrefVideo#1 msgid "Enable postprocessing by default" msgstr "Ativar o pós-processamento por padrão" #: PrefVideo#2 msgid "Draw video using slices" msgstr "Desenhe vídeos usando fatias" #: PrefVideo#3 msgid "Direct rendering" msgstr "Renderização direta" #: PrefVideo#4 msgid "Double buffering" msgstr "Double buffering" #: PrefVideo#5 msgid "Use software video equalizer" msgstr "Use o equalizador de vídeo por software" #: PrefVideo#6 msgctxt "PrefVideo#6" msgid "Output driver:" msgstr "Driver de saída:" #: PrefVideo#7 msgctxt "PrefVideo#7" msgid "Default" msgstr "Padrão" #: PrefVideo#8 msgid "slow" msgstr "lento" #: PrefVideo#9 msgid "Video output driver" msgstr "Driver de saída de vídeo" #: PrefVideo#10 msgid "Select the video output driver. %1 provides the best performance." msgstr "Selecione o driver de saída de vídeo. % 1 fornece o melhor desempenho." #: PrefVideo#11 msgid "Postprocessing will be used by default on new opened files." msgstr "O pós-processamento será usado por padrão em novos arquivos abertos." #: PrefVideo#12 msgid "Software video equalizer" msgstr "Equalizador de vídeo de software" #: PrefVideo#13 msgid "" "You can check this option if video equalizer is not supported by your " "graphic card or the selected video output driver.
Note: this " "option can be incompatible with some video output drivers." msgstr "Você pode marcar esta opção se o equalizador de vídeo não for suportado pela placa gráfica ou pelo driver de saída de vídeo selecionado.
Observação: essa opção pode ser incompatível com alguns drivers de saída de vídeo." #: PrefVideo#14 msgid "" "If checked, turns on direct rendering (not supported by all codecs and video " "outputs)
Warning: May cause OSD/SUB corruption!" msgstr "Se marcado, ativa a renderização direta (não suportada por todos os codecs e saídas de vídeo)
Aviso: Pode causar corrupção de OSD / SUB!" #: PrefVideo#15 msgid "" "Double buffering fixes flicker by storing two frames in memory, and " "displaying one while decoding another. If disabled it can affect OSD " "negatively, but often removes OSD flickering." msgstr "Correções de buffer duplo piscam armazenando dois quadros na memória e exibindo um enquanto decodifica outro. Se desativado, pode afetar o OSD negativamente, mas muitas vezes remove a oscilação do OSD." #: PrefVideo#16 msgid "" "Enable/disable drawing video by 16-pixel height slices/bands. If disabled, " "the whole frame is drawn in a single run. May be faster or slower, depending " "on video card and available cache. It has effect only with libmpeg2 and " "libavcodec codecs." msgstr "Ativar / desativar o desenho de vídeo por fatias / bandas de altura de 16 pixels. Se desativado, o quadro inteiro é desenhado em uma única execução. Pode ser mais rápido ou mais lento, dependendo da placa de vídeo e do cache disponível. Ele tem efeito somente com os codecs libmpeg2 e libavcodec." #: PreferencesDialog#1 msgctxt "PreferencesDialog#1" msgid "Kylin Video - Preferences" msgstr "Vídeo Kylin - Preferências" #: PreferencesDialog#2 msgid "Preference" msgstr "Preferência" #: PreferencesDialog#3 msgctxt "PreferencesDialog#3" msgid "Cancel" msgstr "Cancelar" #: PreferencesDialog#4 msgctxt "PreferencesDialog#4" msgid "Apply" msgstr "Aplique" #: PreferencesDialog#5 msgctxt "PreferencesDialog#5" msgid "OK" msgstr "Está bem" #: PreferencesDialog#6 msgid "General" msgstr "Geral" #: PreferencesDialog#7 msgctxt "PreferencesDialog#7" msgid "Video" msgstr "Vídeo" #: PreferencesDialog#8 msgctxt "PreferencesDialog#8" msgid "Audio" msgstr "Audio" #: PreferencesDialog#9 msgctxt "PreferencesDialog#9" msgid "Performance" msgstr "atuação" #: PreferencesDialog#10 msgctxt "PreferencesDialog#10" msgid "Subtitles" msgstr "Legendas" #: PreferencesDialog#11 msgid "ScreenShot" msgstr "ScreenShot" #: PreferencesDialog#12 msgctxt "PreferencesDialog#12" msgid "Shortcut Key" msgstr "Tecla de atalho" #: QObject#1 #, fuzzy msgid "%n second(s)" msgstr "\n \n \n " #: QObject#2 #, fuzzy msgid "%n minute(s)" msgstr "\n \n \n " #: QObject#3 msgid "%1 and %2" msgstr "% 1 e% 2" #: QObject#4 msgid "This is Kylin Vedio v. %1 running on %2" msgstr "Este é o Kylin Vedio v.% 1 executado em% 2" # aspect_ratio #: QObject#5 msgid "disabled" msgstr "Desativado" # aspect_ratio #: QObject#6 msgid "auto" msgstr "auto" # aspect_ratio #: QObject#7 msgid "unknown" msgstr "desconhecido" #: ShortcutGetter#1 msgid "Modify shortcut" msgstr "Modificar atalho" #: ShortcutGetter#2 msgid "Add shortcut" msgstr "Adicionar atalho" #: ShortcutGetter#3 msgid "Remove shortcut" msgstr "Remover atalho" #: ShortcutGetter#4 msgid "Press the key combination you want to assign" msgstr "Pressione a combinação de teclas que você deseja atribuir" #: ShortcutGetter#5 msgctxt "ShortcutGetter#5" msgid "Clear" msgstr "Claro" #: ShortcutGetter#6 msgctxt "ShortcutGetter#6" msgid "OK" msgstr "Está bem" #: ShortcutGetter#7 msgctxt "ShortcutGetter#7" msgid "Cancel" msgstr "Cancelar" #: ShortcutGetter#8 msgid "Capture" msgstr "Capturar" #: ShortcutGetter#9 msgid "Capture keystrokes" msgstr "Capture as teclas digitadas" #: SupportFormats#1 msgid "Video formats" msgstr "Formatos de vídeo" #: SupportFormats#2 msgid "Audio formats" msgstr "Formatos de áudio" #: SupportFormats#3 msgid "Subtitles formats" msgstr "Formatos de legendas" #: SupportFormats#4 msgid "" "Some video formats do not support preview and seek by dragging, e.g. the swf." msgstr "Alguns formatos de vídeo não suportam a visualização e buscam arrastando, por exemplo, o swf." #: TimeDialog#1 msgid "Seek" msgstr "Procurar" #: TimeDialog#2 msgctxt "TimeDialog#2" msgid "OK" msgstr "Está bem" #: TimeDialog#3 msgctxt "TimeDialog#3" msgid "Cancel" msgstr "Cancelar" #: TimeDialog#4 msgid "Jump to:" msgstr "Pule para:" #: TitleWidget#1 msgctxt "TitleWidget#1" msgid "Kylin Video" msgstr "Vídeo Kylin" #: TristateCombo#1 msgctxt "TristateCombo#1" msgid "Auto" msgstr "Auto" #: TristateCombo#2 msgctxt "TristateCombo#2" msgid "Yes" msgstr "sim" #: TristateCombo#3 msgctxt "TristateCombo#3" msgid "No" msgstr "Não" #: VideoPreview#1 msgid "The length of the video is 0" msgstr "O comprimento do vídeo é 0" #: VideoPreview#2 msgid "The temporary directory (%1) can't be created" msgstr "O diretório temporário (% 1) não pode ser criado" #: VideoPreview#3 msgid "The file %1 doesn't exist" msgstr "O arquivo% 1 não existe" #: VideoPreview#4 msgid "The mplayer process didn't run" msgstr "O processo do mplayer não foi executado" #: VideoPreview#5 msgid "No filename" msgstr "Nenhum nome de arquivo" #: VideoPreview#6 msgid "" "The mplayer process didn't start while trying to get info about the video" msgstr "O processo do mplayer não começou ao tentar obter informações sobre o vídeo" kylin-video/src/translations/generate_translations_pm.sh0000755000175000017500000000015613524205650022672 0ustar fengfeng#! /bin/bash ts_file_list=(`ls translations/*.ts`) for ts in "${ts_file_list[@]}" do lrelease "${ts}" done kylin-video/src/translations/kylin-video_fr.qm0000644000175000017500000020025613625147453020537 0ustar fengfeng!rr&x Cd9@M ` p`jyFȵJ5M^g^}  !$ J"$ez|*Q+FOSt+LSGpHw9&Hw9CHX_HހIyeJ+tPJ+K )Kʘ*oLb LbM-Mx-1N._N/gO0SP2Q4Rd5R6S8S9T;HV=V?=XqY@Yĩ?YAAjZjDNZF9ZFhZIZFZةEp[dG\o2f\ġK \n\U]J]ØK^cVM^M;gz_R~N76C)RRrz/.2X5eÙ^>J ^.1l\lT," "f6sR?`0a d!*G3 |zJtϦ4H |xeXxZ59 ^O x 8enD#[,wBq RNRrB~L]K!1w.75c.5ue19 :+RAS {W9Ȱ6͢S,ؘ ƾ&cZ=Tmj_Xq7r5a+rC3C:Щk*LOQNcWq^_k"9B9i~79W\\{(Uv( $vҔ[ f~eQ hI$ 4<71 Pca:S~[=Qad~eQlefBjHm'rJ:$Mx"$#u%8#I kII IpNIx'I޹II^&QEOw7:'N)Ș(&ĖRaUEP*-u;**?7*~,a-^0Ę,ܓ~.+{;/쌏0#Q gw#x8! _Q '+:D\44m_P -4#n q%Bo&~5:_QW=[TBa՝H;uKd;Lh)<[6`<j3.v0>|?I@AE~@w .<g3"JBHl{C8)D;F9edHAHI+jI+j9<5/߮C4OPQGM &GM:I1sXIM_ `đcRWb*_'J>K(`TTWk5~5~ I+ɟ.>~֣*R>㞳:EED/ Y eV!t|#Q"D5ƃFgEwGZAGZ_IbREWL eL"FO'ݙ8/-7 $>!Um$AZ.@hI3q5NH|~]^I$B$^%E45.ы5A  ?Oi%SI3q{v̪>#dρQ4oK'ÑO 1!F ]ce ]u Q. (q% h>1 h>] jO>& q1 u1  >& c 5J sl s s ȏ.A; <& ʟ.@ xt ۊ<< G#c 꽺 ' L' .A (V ~ qBx l37 nt *Go 6C dUr hPD iP( }E #Q 8#? l = %V ` z < $=) K+ ŷ # t~G tc IW ‹kY ‹mZ < K ΂ yE= ۰E .G Z^ > ` u* T ! q ,`t 2~ 3 <'\3 CUK: E9 F X F s _4bW gBi gJ hjz sBb t9 6O E~ Ts .VK I ȟU U x8h ti tUiy j Uj<  > b H #I* ̛:k  i) ^  I.  " &#{ &#. (c0 +[2- =Y B)b BR:R B:# FG* N0* OJ} RVT hۮ- z~x |9a m \,.  1^ v % sǭ d^ b 1 P,  qD{ EW *7OI 74<b :n4~ ZtN{ b i8:q k 6K >- q n  }L| < #))O YH+>\2:;^zaDcFaOlWls%sJxa~>/4m'NbR@; .+Jk drU(A'H͔ *3gKXhY8i}Y8ic5ix?iTBiT huwz´4NXwZ7paXBLZ>QGMhi4v<! DOCTYPE HTML PUBLIC \ "- // W3C // DTD HTML 4.0 // EN " \ "http: //www.w3.org/TR/REC-html40/strict.dtd "> \ n <html> <head> <meta name = \ "qrichtext " content = \ "1 " /> <style type = \ "text / css "> \ np, li {espace blanc: pre-wrap; } \ n </ style> </ head> <body style = \ "font-family: 'Ubuntu'; font-size: 11pt; font-weight: 400; font-style: normal; "> \ n <p style = \ "- qt-paragraph-type: vide; marge suprieure: 0px; marge infrieure: 0px; marge gauche: 0px; marge droite: 0px; -qt-block-indent: 0; retrait du texte: 0px; \ "> <br /> </ p> </ body> </ html>


 AboutDialogSurAbout AboutDialogDonateur Contributor AboutDialogKylin Vido Kylin Video AboutDialogD'accordOK AboutDialog$Moteur de lecture:Playback engine: AboutDialogFUtiliser Qt% 1 (compil avec Qt% 2)!Using Qt %1 (compiled with Qt %2) AboutDialogVersion 1 Version: %1 AboutDialog*Choisissez un fichier Choose a file ActionsEditorLa description Description ActionsEditor ErreurError ActionsEditor prnomName ActionsEditorRaccourciShortcut ActionsEditorDlai audio Audio delayAudioDelayDialog>Dlai audio (en millisecondes):Audio delay (in milliseconds):AudioDelayDialogAnnulerCancelAudioDelayDialogD'accordOKAudioDelayDialog&Rinitialiser&ResetAudioEqualizerInformation InformationAudioEqualizerMuetMute BottomWidgetProchainNext BottomWidgetJouer pause Play / Pause BottomWidgetPlaylist Play List BottomWidgetPrevPrev BottomWidgetArrtezStop BottomWidget:Marqueur \ "A " dfini sur% 1"A" marker set to %1Core:Marqueur \ "B " dfini sur% 1"B" marker set to %1Core(Marqueurs AB effacsA-B markers clearedCore$Ratio d'aspect:% 1Aspect ratio: %1Core$Dlai audio:% 1 msAudio delay: %1 msCoreLuminosit:% 1Brightness: %1Core4Mise en mmoire tampon ... Buffering...CoreContraste:% 1 Contrast: %1CoreGamma:% 1 Gamma: %1CoreTeinte:% 1Hue: %1CorehLa molette de la souris change de vitesse maintenantMouse wheel changes speed nowCorefLa molette de la souris change le volume maintenantMouse wheel changes volume nowCorevLa molette de la souris change le niveau de zoom maintenant"Mouse wheel changes zoom level nowCoreNMolette de la souris cherche maintenantMouse wheel seeks nowCoreSaturation:% 1Saturation: %1Core`Capture d'cran NON prise, dossier non configur+Screenshot NOT taken, folder not configuredCoreTCapture d'cran enregistre en tant que% 1Screenshot saved as %1CoredCaptures d'cran NON prises, dossier non configur,Screenshots NOT taken, folder not configuredCoreVitesse:% 1 Speed: %1CoreDpart... Starting...Core8Dlai des sous-titres:% 1 msSubtitle delay: %1 msCoreSous-titres off Subtitles offCoreSous-titres sur Subtitles onCoreMise jour du cache de polices. Cela peut prendre quelques secondes ...6Updating the font cache. This may take some seconds...CoreVolume 1 Volume: %1CoreZoom:% 1Zoom: %1Core ErreurError ErrorDialog$Masquer le journalHide log ErrorDialogErreur MPlayer MPlayer Error ErrorDialogD'accordOK ErrorDialogLOups, quelque chose de faux est arrivOops, something wrong happened ErrorDialog&Afficher le journalShow log ErrorDialog icneicon ErrorDialogdAppuyez sur Echap pour quitter le mode plein cran"Press ESC to exit full screen modeEscTipdCliquez pour slectionner un fichier ou un dossier Click to select a file or folder FileChooser&Rinitialiser&ResetFilePropertiesDialog<& Slectionnez le codec audio:&Select the audio codec:FilePropertiesDialog& Slectionnez le dmultiplexeur qui sera utilis pour ce fichier:4&Select the demuxer that will be used for this file:FilePropertiesDialog<& Slectionnez le codec vido:&Select the video codec:FilePropertiesDialogAppliquerApplyFilePropertiesDialogUn codec audio Audio codecFilePropertiesDialogAnnulerCancelFilePropertiesDialogDemuxerDemuxerFilePropertiesDialogInformation InformationFilePropertiesDialog2Kylin Video - PrfrencesKylin Video - PreferencesFilePropertiesDialogD'accordOKFilePropertiesDialogProprits PropertiesFilePropertiesDialogRinitialiserResetFilePropertiesDialogCodec vido Video codecFilePropertiesDialogAidez-moiHelp HelpDialog$Kylin Video - AideKylin Video - Help HelpDialogD'accordOK HelpDialog,Formats pris en chargeSupported formats HelpDialogAnnulerCancelInputURLEntrer l'URL Enter URLInputURLD'accordOKInputURLURL:URL:InputURLAbkhaze Abkhazian LanguagesAu loinAfar Languagesafrikaans Afrikaans LanguagesAkanAkan LanguagesalbanaisAlbanian LanguagesAmhariqueAmharic Languages arabeArabic LanguagesArabe - SyrieArabic - Syria LanguagesWindows arabeArabic Windows LanguagesAragonais Aragonese LanguagesarmnienArmenian LanguagesAssamaisAssamese Languages AvaricAvaric LanguagesAvestanAvestan Languages AymaraAymara Languagesazerbadjanais Azerbaijani LanguagesbaltiqueBaltic LanguagesBambaraBambara LanguagesBachkirBashkir Languages basqueBasque LanguagesBilorusse Belarusian LanguagesbengaliBengali Languages BihariBihari LanguagesBislamaBislama Languages BokmlBokmål LanguagesBosniaqueBosnian Languages BretonBreton Languagesbulgare Bulgarian Languages birmanBurmese LanguagescatalanCatalan LanguagesceltiqueCeltic LanguagesChamorroChamorro LanguagesTchtchneChechen LanguagesChichewaChichewa LanguageschinoisChinese Languages gliseChurch LanguagesChuvashChuvash LanguagescornouaillaisCornish Languages CorseCorsican LanguagesCriCree Languages croateCroatian LanguagescyrilliqueCyrillic Languages$Windows cyrilliqueCyrillic Windows LanguagestchqueCzech Languages danoisDanish Languages DivehiDivehi LanguagesnerlandaisDutch LanguagesDzongkhaDzongkha LanguagesAnglaisEnglish Languagesespranto Esperanto LanguagesDEspranto, galicien, maltais, turc%Esperanto, Galician, Maltese, Turkish LanguagesestonienEstonian LanguagesEweEwe LanguagesFroenFaroese LanguagesFidjienFijian LanguagesfinlandaisFinnish LanguagesfranaisFrench Languages frisonFrisian Languages FulahFulah LanguagesgaliqueGaelic LanguagesGalicienGalician Languages GandaGanda LanguagesgorgienGeorgian LanguagesallemandGerman LanguagesgrecGreek Languagesgroenlandais Greenlandic LanguagesGuaraniGuarani LanguagesGujaratiGujarati LanguageshatienHaitian Languages HausaHausa Languages hbreuHebrew Languages2Jeux de caractres hbreuHebrew charsets Languages HereroHerero Languages hindiHindi LanguagesHiriHiri Languageshongrois Hungarian Languagesislandais Icelandic LanguagesJe faisIdo LanguagesIgboIgbo Languagesindonsien Indonesian LanguagesInterlingua Interlingua LanguagesInterlingue Interlingue LanguagesInuktitut Inuktitut LanguagesInupiaqInupiaq LanguagesirlandaisIrish LanguagesitalienItalian LanguagesJaponaisJapanese Languages6Jeux de caractres japonaisJapanese charsets LanguagesJavanaisJavanese LanguagesKannadaKannada Languages KanuriKanuri LanguagesCachemireKashmiri Languages KazakhKazakh Languages KhmerKhmer Languages KikuyuKikuyu LanguagesKinyarwanda Kinyarwanda LanguageskirghizKirghiz LanguagesKomiKomi Languages KongoKongo Languages corenKorean Languages0Jeu de caractres corenKorean charset LanguagesKuanyamaKuanyama Languages kurdeKurdish LanguagesLaoLao Languages LatinLatin Languages lettonLatvian LanguagesLimburgan Limburgan LanguagesLingalaLingala Languageslituanien Lithuanian LanguagesLuba-Katanga Luba-Katanga LanguagesLuxembourgeois Luxembourgish LanguagesMacdonien Macedonian LanguagesmalgacheMalagasy Languages malaisMalay LanguagesMalayalam Malayalam LanguagesmaltaisMaltese LanguagesMannoisManx Languages MaoriMaori LanguagesMarathiMarathi LanguagesMarshallais Marshallese LanguagesGrec moderne Modern Greek Languages(Windows grec moderneModern Greek Windows LanguagesMoldave Moldavian Languages mongol Mongolian Languages NauruNauru Languages NavajoNavajo LanguagesNdebeleNdebele Languages NdongaNdonga LanguagesNpalaisNepali Languagesnorvgien Norwegian Languages"Nynorsk norvgienNorwegian Nynorsk LanguagesOccitanOccitan Languages OjibwaOjibwa Languages<Ancien jeu de caractres balteOld Baltic charset Languages OriyaOriya Languages OromoOromo Languages OssteOssetian LanguagesPaliPali LanguagesPanjabiPanjabi Languages persanPersian LanguagespolonaisPolish LanguagesPortugais Portuguese LanguagesPouchtoPushto LanguagesQuechuaQuechua LanguagesroumainRomanian LanguagesLe romancheRomansh Languages RundiRundi Languages russeRussian LanguagesSamiSami Languages SamoanSamoan Languages SangoSango LanguagessanskritSanskrit Languages Sarde Sardinian Languages serbeSerbian Languages ShonaShona LanguagesSichuanSichuan LanguagesFJeu de caractres chinois simplifiSimplified Chinese charset Languages SindhiSindhi LanguagesCinghalaisSinhala LanguagesDLangues slaves / d'Europe centrale!Slavic/Central European Languages LanguagesFFentres slaves / d'Europe centraleSlavic/Central European Windows LanguagesslovaqueSlovak LanguagesslovneSlovene Languages somaliSomali Languages SothoSotho Languages"Europe du Sud-EstSouth-Eastern European LanguagesEspanolSpanish LanguagesSundanese Sundanese LanguagesSwahiliSwahili Languages SwatiSwati LanguagessudoisSwedish LanguagesTagalogTagalog LanguagesTahitienTahitian Languages TadjikTajik Languages TamilTamil Languages tatarTatar Languages TeluguTelugu LanguagesthalandaisThai Languages,Jeu de caractres tha Thai charset LanguagesTibtainTibetan LanguagesTigrinyaTigrinya Languages TongaTonga LanguagesLJeu de caractres chinois traditionnelTraditional Chinese charset Languages TsongaTsonga Languages TswanaTswana LanguagesturcTurkish LanguagesTurkmneTurkmen LanguagesTwiTwi Languages UTF-8UTF-8 LanguagesOughourUighur Languagesukrainien Ukrainian Languages*Ukrainien, bilorusseUkrainian, Belarusian LanguagesUnicodeUnicode Languages OurdouUrdu Languages OuzbekUzbek Languages VendaVenda Languagesvietnamien Vietnamese LanguagesVolapkVolapük Languages WallonWalloon LanguagesgalloisWelsh Languages8Langues d'Europe occidentaleWestern European Languages LanguagesPLangues d'Europe occidentale avec l'euro$Western European Languages with Euro Languages WolofWolof Languages XhosaXhosa LanguagesyiddishYiddish Languages YorubaYoruba Languages ZhuangZhuang Languages zoulouZulu LanguagesChangementChangeLineEditWithIcon`le filtre '% 1' n'est pas pris en charge par mpv'the '%1' filter is not supported by mpv MPVProcess% 1 erreur%1 Error MainWindow0% 1 n'a pas pu dmarrer.%1 failed to start. MainWindow"% 1 s'est cras.%1 has crashed. MainWindowH% 1 a termin de manire inattendue.%1 has finished unexpectedly. MainWindow& 4.0 Surround &4.0 Surround MainWindow& 5.1 Surround &5.1 Surround MainWindow& 6.1 Surround &6.1 Surround MainWindow& 7.1 Surround &7.1 Surround MainWindow&Toujours&Always MainWindow &Auto&Auto MainWindowEt chanes &Channels MainWindow &Clair&Clear MainWindow&Dsactiv &Disabled MainWindow&Sauter ... &Jump to... MainWindow&Sauter : &Jump to: MainWindow& Canal gauche &Left channel MainWindow &Mono&Mono MainWindow &Muet&Mute MainWindow&Jamais&Never MainWindow&De&Off MainWindow& Canal droit&Right channel MainWindow&Tourner&Rotate MainWindow& Rotation de 90 degrs dans le sens des aiguilles d'une montre et retournez(&Rotate by 90 degrees clockwise and flip MainWindow &Capture d'cran &Screenshot MainWindow&Stro&Stereo MainWindow& Mode stro &Stereo mode MainWindow& URL ...&URL... MainWindow2'% 1' n'a pas t trouv!'%1' was not found! MainWindow+% 1+%1 MainWindow-%1-%1 MainWindow <vide> MainWindow2 propos de & Kylin VideoAbout &Kylin Video MainWindow"Tous les fichiers All files MainWindowRatio d'aspect Aspect ratio MainWindowl'audioAudio MainWindow0Choisissez un rpertoireChoose a directory MainWindow*Choisissez un fichier Choose a file MainWindowLConfirmer la suppression - Kylin VideoConfirm deletion - Kylin Video MainWindowRetard +Delay + MainWindowRetard -Delay - MainWindowPSupprimer la liste des fichiers rcents? Delete the list of recent files? MainWindowAnnuaire... Directory... MainWindowDouble vitesse Double speed MainWindowErreur dtecteError detected MainWindow$Code de sortie:% 1 Exit code: %1 MainWindowFli & p image Fli&p image MainWindow*Avancer et rembobinerForward and rewind MainWindow"Rotation du cadreFrame rotation MainWindowPlein cran Fullscreen MainWindowDemi vitesse Half speed MainWindowAidez-moiHelp MainWindowInformation Information MainWindowAller % 1 Jump to %1 MainWindowKylin Vido Kylin Video MainWindow.Kylin Video - RechercheKylin Video - Seek MainWindow>Kylin Video - Retard sous-titreKylin Video - Subtitle delay MainWindow4Lecture en boucle de listeList loop play MainWindowCharge...Load... MainWindowImage miroir Mirr&or image MainWindowMultimdia Multimedia MainWindowProchainNext MainWindowVitesse normale Normal speed MainWindow OuvrirOpen MainWindow"Fichier ouvert... Open &File... MainWindow0Ouvrir la page d'accueil Open Homepage MainWindowLOuvrir le dossier des captures d'cranOpen screenshots folder MainWindowJeu d'ordre Order play MainWindow$Vitesse de lecture Play Speed MainWindowContrle de jeu Play control MainWindowOrdre de jeu Play order MainWindowPlaylistPlayList MainWindowPlaylists Playlists MainWindowxVeuillez vrifier le chemin d'accs% 1 dans les prfrences.(Please check the %1 path in preferences. MainWindowPrfrences Preferences MainWindowprcdentPrevious MainWindowQuitterQuit MainWindowJeu alatoire Random play MainWindowSens inverseRe&verse MainWindow Fichiers rcents Recent files MainWindowFaire pivoter de 90 degrs et dans le sens des aiguilles d'une montreRotate by 90 degrees &clockwise MainWindowFaire pivoter de 90 degrs dans le sens inverse des aiguilles d'une montre&Rotate by 90 degrees counterclock&wise MainWindowFaire pivoter de 90 degrs dans le sens antihoraire et & retourner/Rotate by 90 degrees counterclockwise and &flip MainWindow*S & tay sur le dessus S&tay on top MainWindowRVoir le journal pour plus d'informations.See the log for more info. MainWindow$Rgler le dlai... Set dela&y... MainWindowVitesse + 1% Speed +1% MainWindowVitesse + 10% Speed +10% MainWindowVitesse + 4% Speed +4% MainWindowVitesse -1% Speed -1% MainWindowVitesse -10% Speed -10% MainWindowVitesse -4% Speed -4% MainWindowArrtezStop MainWindow0Sous-titre et visibilitSubtitle &visibility MainWindowRDlai des sous-titres (en millisecondes):!Subtitle delay (in milliseconds): MainWindowLes sous-titres Subtitles MainWindowVLe dossier de capture d'cran n'existe pas!%The screenshot folder does not exist! MainWindow4Le serveur a renvoy '% 1'The server returned '%1' MainWindowdMalheureusement, cette vido ne peut pas tre lue.)Unfortunately this video can't be played. MainWindow VidoVideo MainWindowLes filtres vido sont dsactivs lors de l'utilisation de vdpau+Video filters are disabled when using vdpau MainWindow:Voir & info et proprits ...View &info and properties... MainWindowVolume +Volume + MainWindowLe volume -Volume - MainWindow*Pendant que je jouaisWhile &playing MainWindowAnnulerCancel MessageDialogNonNo MessageDialogD'accordOk MessageDialogOuiYes MessageDialogXCette option n'est pas supporte par MPlayer'This option is not supported by MPlayerMplayerProcess@& Supprimer le fichier du disque&Delete file from disk PlayListView JouerPlay PlayListView(Enlever la slectionRemove &selected PlayListViewAjouterAddPlaylist$Ajouter le fichierAdd FilePlaylist"Tous les fichiers All filesPlaylistFtes-vous sur de vouloir continuer?!Are you sure you want to proceed?Playlist0Choisissez un rpertoireChoose a directoryPlaylist ClairClearPlaylist0Confirmer la suppressionConfirm deletionPlaylist&Confirmer supprimerConfirm removePlaylistMultimdia MultimediaPlaylistPlaylistPlayListPlaylist(La playlist est videPlaylist is emptyPlaylistPlaylists PlaylistsPlaylist:Atteint la fin de la playlistReached the end of the playlistPlaylist\Slectionnez un ou plusieurs fichiers ouvrir Select one or more files to openPlaylistCette action ne peut pas tre annule. tes-vous sur de vouloir continuer??This action cannot be undone. Are you sure you want to proceed?PlaylistAnnulerCancelPoweroffDialogD'accordOkPoweroffDialog% 1 est le recommand. Essayez d viter les% 2 et% 3, ils sont lents et peuvent avoir un impact sur les performances.g%1 is the recommended one. Try to avoid %2 and %3, they are slow and can have an impact on performance. PrefAudio2 (stro) 2 (Stereo) PrefAudio 4 (4.0 Surround)4 (4.0 Surround) PrefAudio 6 (Surround 5.1)6 (5.1 Surround) PrefAudio 7 (6.1 Surround)7 (6.1 Surround) PrefAudio 8 (7.1 Surround)8 (7.1 Surround) PrefAudio,Pilote de sortie audioAudio output driver PrefAudioRSynchronisation automatique audio / vido Audio/video auto synchronization PrefAudio"Canaux par dfautChannels by default PrefAudio$Canaux par dfaut:Channels by default: PrefAudioCochez cette option pour utiliser le mlangeur logiciel au lieu d'utiliser le mlangeur de carte son.SCheck this option to use the software mixer, instead of using the sound card mixer. PrefAudio DfautDefault PrefAudioFacteur:Factor: PrefAudioVolume global Global volume PrefAudioAjuste progressivement la synchronisation A / V en fonction des mesures de retard audio.AGradually adjusts the A/V sync based on audio delay measurements. PrefAudioLSi cette option est coche, le mme volume sera utilis pour tous les fichiers que vous lisez. Si l'option n'est pas coche, chaque fichier utilise son propre volume.If this option is checked, the same volume will be used for all files you play. If the option is not checked each file uses its own volume. PrefAudio$Max. AmplificationMax. Amplification PrefAudio&Max. Amplification:Max. Amplification: PrefAudioPMaximise le volume sans dformer le son.2Maximizes the volume without distorting the sound. PrefAudio"Pilote de sortie:Output driver: PrefAudioNDemande le nombre de canaux de lecture. MPlayer demande au dcodeur de dcoder l'audio en autant de canaux que spcifi. Ensuite, il appartient au dcodeur de satisfaire l'exigence. Cela n est gnralement important que lors de la lecture de vidos avec l audio AC3 (comme des DVD). Dans ce cas, liba52 effectue le dcodage par dfaut et mlange correctement le son dans le nombre de canaux demand. <b> Remarque </ b>: cette option est respecte par les codecs (AC3 uniquement), les filtres (surround) et les pilotes de sortie audio (au moins OSS).Requests the number of playback channels. MPlayer asks the decoder to decode the audio into as many channels as specified. Then it is up to the decoder to fulfill the requirement. This is usually only important when playing videos with AC3 audio (like DVDs). In that case liba52 does the decoding by default and correctly downmixes the audio into the requested number of channels. Note: This option is honored by codecs (AC3 only), filters (surround) and audio output drivers (OSS at least). PrefAudioNSlectionnez le pilote de sortie audio.Select the audio output driver. PrefAudio~Dfinit le niveau d'amplification maximum en pourcentage (par dfaut: 110). Une valeur de 200 vous permettra d ajuster le volume jusqu  doubler le niveau actuel. Avec des valeurs infrieures 100, le volume initial (100%) sera suprieur au maximum, ce qui signifie que le menu OSD ne peut pas s'afficher correctement. Sets the maximum amplification level in percent (default: 110). A value of 200 will allow you to adjust the volume up to a maximum of double the current level. With values below 100 the initial volume (which is 100%) will be above the maximum, which e.g. the OSD cannot display correctly. PrefAudio<Contrle du volume du logicielSoftware volume control PrefAudioSynchronisationSynchronization PrefAudiofCette option s'applique galement au contrle muet..This option also applies for the mute control. PrefAudioTUtiliser le logiciel de contrle du volumeUse software volume control PrefAudioLe volumeVolume PrefAudioDNormalisation de volume par dfautVolume normalization by default PrefAudio0Si cette option est active, le fichier sera suspendu lorsque la fentre principale est masque. Lorsque la fentre est restaure, la lecture reprendra.If this option is enabled, the file will be paused when the main window is hidden. When the window is restored, playback will be resumed. PrefGeneralSi cette option est active, l'aperu vido sera affich lorsque la souris sera place sur la barre de progression.lIf this option is enabled, the video preview will be displayed when the mouse is placed on the progress bar. PrefGeneralSi vous changez le moteur de lecture en MPV, redmarrez Kylin Video.EIf you change the playback engine to MPV, please restart Kylin Video. PrefGeneralSi vous modifiez le moteur de lecture en MPlayer, redmarrez Kylin Video.IIf you change the playback engine to MPlayer, please restart Kylin Video. PrefGeneralMPVMPV PrefGeneralMPlayerMPlayer PrefGeneral(Pause quand minimisPause when minimized PrefGeneral$Moteur de lecture:Playback engine: PrefGeneral^Aperu lorsque la vido est en cours de lecture!Preview when the video is playing PrefGeneral^Aperu lorsque la vido est en cours de lecturePreview when video is playing PrefGeneralPSlectionnez MPV comme moteur de lectureSelect MPV as playback engine PrefGeneralXSlectionnez MPlayer comme moteur de lecture!Select MPlayer as playback engine PrefGeneralAutoAutoPrefPerformanceAuto: il tente d'activer automatiquement le dcodage matriel l'aide de la premire mthode disponible.ZAuto: it tries to automatically enable hardware decoding using the first available method.PrefPerformance(Options disponibles:Available options:PrefPerformance CacheCachePrefPerformance.Cache pour les fichiersCache for filesPrefPerformance>Cache pour les fichiers locaux:Cache for local files:PrefPerformance&Cache pour les fluxCache for streamsPrefPerformance(Cache pour les flux:Cache for streams:PrefPerformanceDcoderDecodePrefPerformance"Dcodage matrielHardware decodingPrefPerformanceKBKBPrefPerformance AucunNonePrefPerformance\Aucun: seul le dcodage logiciel sera utilis.*None: only software decoding will be used.PrefPerformancePerformance PerformancePrefPerformanceDfinit l'API de dcodage vido matriel. Si le dcodage matriel n'est pas possible, le dcodage logiciel sera utilis la place.sSets the hardware video decoding API. If hardware decoding is not possible, software decoding will be used instead.PrefPerformanceDfinit le nombre de threads utiliser pour le dcodage. Uniquement pour MPEG-1/2 et H.264KSets the number of threads to use for decoding. Only for MPEG-1/2 and H.264PrefPerformanceNCette option ne fonctionne qu'avec mpv. This option only works with mpv.PrefPerformanceCette option spcifie la quantit de mmoire (en kilo-octets) utiliser lors de la mise en cache pralable d'une URL.OThis option specifies how much memory (in kBytes) to use when precaching a URL.PrefPerformanceCette option spcifie la quantit de mmoire (en kilo-octets) utiliser lors de la mise en cache d'un fichier.PThis option specifies how much memory (in kBytes) to use when precaching a file.PrefPerformance Fils de dcodageThreads for decodingPrefPerformanceFils de filetage pour le dcodage (MPEG-1/2 et H.264 uniquement):/Threads for decoding (MPEG-1/2 and H.264 only):PrefPerformancevaapi-copy: il copie la vido dans la RAM du systme. Pour les GPU Intel uniquement.Fvaapi-copy: it copies video back into system RAM. For Intel GPUs only.PrefPerformancevaapi: pour les sorties vido opengl et vaapi. Pour les GPU Intel uniquement.Cvaapi: for the opengl and vaapi video outputs. For Intel GPUs only.PrefPerformance\vdpau: pour les sorties vido vdpau et opengl..vdpau: for the vdpau and opengl video outputs.PrefPerformance% 1 spcifie le nom de fichier de la vido sans l'extension,% 2 ajoute un nombre 4 chiffres complt de zros.i%1 specifies the filename of the video without the extension, %2 adds a 4 digit number padded with zeros.PrefScreenShot8Activer les captures d'cranEnable screenshotsPrefScreenShotDossier:Folder:PrefScreenShotPour une liste complte des spcificateurs de modles, visitez ce lien:;For a full list of the template specifiers visit this link:PrefScreenShotPar exemple,% 1 enregistre la capture d'cran sous le nom "moviename_0001.png".AFor example %1 would save the screenshot as 'moviename_0001.png'.PrefScreenShot@Format pour les captures d'cranFormat for screenshotsPrefScreenShotFormat:Format:PrefScreenShotIci, vous pouvez spcifier un dossier dans lequel les captures d'cran prises par Kylin Video seront stockes. Si le dossier n'est pas valide, la fonctionnalit de capture d'cran sera dsactive.Here you can specify a folder where the screenshots taken by Kylin Video will be stored. If the folder is not valid the screenshot feature will be disabled.PrefScreenShot Captures d'cran ScreenshotsPrefScreenShot8Dossier des captures d'cranScreenshots folderPrefScreenShot4Slectionnez un rpertoireSelect a directoryPrefScreenShot@Modle pour les captures d'cranTemplate for screenshotsPrefScreenShotModle: Template:PrefScreenShotCette option permet de choisir le type de fichier image utilis pour enregistrer des captures d'cran.QThis option allows one to choose the image file type used for saving screenshots.PrefScreenShotNCette option ne fonctionne qu'avec mpv. This option only works with mpv.PrefScreenShotCette option spcifie le modle de nom de fichier utilis pour enregistrer les captures d'cran.EThis option specifies the filename template used to save screenshots.PrefScreenShotVous pouvez utiliser cette option pour activer ou dsactiver la possibilit de prendre des captures d'cran.QYou can use this option to enable or disable the possibility to take screenshots.PrefScreenShotIci, vous pouvez changer n'importe quel raccourci clavier. Pour ce faire, double-cliquez ou appuyez sur Entre sur une cellule de raccourci. aHere you can change any key shortcut. To do it double click or press enter over a shortcut cell.  PrefShortCutIci, vous pouvez changer n'importe quel raccourci clavier. Pour ce faire, double-cliquez ou commencez taper sur une cellule de raccourci.aHere you can change any key shortcut. To do it double click or start typing over a shortcut cell. PrefShortCutRaccourciShortCut PrefShortCut&Touche de raccourci Shortcut Key PrefShortCut(diteur de raccourciShortcut editor PrefShortCutCe tableau vous permet de modifier les raccourcis clavier de la plupart des actions disponibles. Double-cliquez ou appuyez sur entre pour un lment, ou appuyez sur le bouton <b> Modifier le raccourci </ b> pour entrer dans la bote de dialogue <i> Modifier le raccourci </ i>. Il existe deux manires de modifier un raccourci: si le bouton <b> Capturer </ b> est activ, appuyez simplement sur la nouvelle touche ou sur la nouvelle combinaison de touches affecter l'action (malheureusement, cela ne fonctionne pas pour toutes les touches). ). Si le bouton <b> Capturer </ b> est dsactiv, vous pouvez entrer le nom complet de la cl.This table allows you to change the key shortcuts of most available actions. Double click or press enter on a item, or press the Change shortcut button to enter in the Modify shortcut dialog. There are two ways to change a shortcut: if the Capture button is on then just press the new key or combination of keys that you want to assign for the action (unfortunately this doesn't work for all keys). If the Capture button is off then you could enter the full name of the key. PrefShortCutZTous les sous-marins contenant le nom du filmAll subs containing movie name PrefSubtitlesNTous les sous-rpertoires du rpertoireAll subs in directory PrefSubtitles,Chargement automatiqueAutoload PrefSubtitlesChargement automatique des fichiers de sous-titres (* .srt, * .sub ...):+Autoload subtitles files (*.srt, *.sub...): PrefSubtitlesFEncodage par dfaut des sous-titresDefault subtitle encoding PrefSubtitlesHEncodage par dfaut des sous-titres:Default subtitle encoding: PrefSubtitles CodageEncoding PrefSubtitles&Police de caractreFont PrefSubtitles(Mme nom que le filmSame name as movie PrefSubtitlesSlectionnez le codage qui sera utilis par dfaut pour les fichiers de sous-titres.ESelect the encoding which will be used for subtitle files by default. PrefSubtitlesSlectionnez la langue pour laquelle vous voulez que l'encodage soit devin automatiquement.PSelect the language for which you want the encoding to be guessed automatically. PrefSubtitlesSlectionnez la mthode de chargement automatique des sous-titres.$Select the subtitle autoload method. PrefSubtitles,Langue des sous-titresSubtitle language PrefSubtitlesLes sous-titres Subtitles PrefSubtitles`Essayez de dtecter automatiquement cette langue#Try to autodetect for this language PrefSubtitlesbEssayez de dtecter automatiquement cette langue:$Try to autodetect for this language: PrefSubtitlesLorsque cette option est active, le codage des sous-titres sera dtect automatiquement pour la langue donne. Si l'encodage automatique choue, le codage par dfaut est rtabli. Cette option ncessite un MPlayer compil avec le support ENCA.When this option is on, the encoding of the subtitles will be tried to be autodetected for the given language. It will fall back to the default encoding if the autodetection fails. This option requires a MPlayer compiled with ENCA support. PrefSubtitles DfautDefault PrefVideoRendu directDirect rendering PrefVideoDouble tamponDouble buffering PrefVideoLa double mise en mmoire tampon corrige le scintillement en stockant deux images en mmoire et en affichant une image tout en en dcodant une autre. Si elle est dsactive, cela peut avoir un effet ngatif sur l'OSD, mais limine souvent le scintillement de l'OSD.Double buffering fixes flicker by storing two frames in memory, and displaying one while decoding another. If disabled it can affect OSD negatively, but often removes OSD flickering. PrefVideoNDessiner une vido l'aide de tranchesDraw video using slices PrefVideoJActiver le post-traitement par dfaut Enable postprocessing by default PrefVideozActiver / dsactiver le dessin vido par tranches / bandes de 16 pixels de hauteur. Si cette option est dsactive, l ensemble du cadre est dessin en un seul passage. Peut tre plus rapide ou plus lent, en fonction de la carte vido et du cache disponible. Cela n'a d'effet qu'avec les codecs libmpeg2 et libavcodec.Enable/disable drawing video by 16-pixel height slices/bands. If disabled, the whole frame is drawn in a single run. May be faster or slower, depending on video card and available cache. It has effect only with libmpeg2 and libavcodec codecs. PrefVideoSi cette case est coche, le rendu direct est activ (non pris en charge par tous les codecs et les sorties vido) <br> <b> Avertissement: </ b> Peut entraner une corruption du systme OSD / SUB!If checked, turns on direct rendering (not supported by all codecs and video outputs)
Warning: May cause OSD/SUB corruption! PrefVideo"Pilote de sortie:Output driver: PrefVideoLe post-traitement sera utilis par dfaut sur les nouveaux fichiers ouverts.;Postprocessing will be used by default on new opened files. PrefVideoSlectionnez le pilote de sortie vido. % 1 offre les meilleures performances.ASelect the video output driver. %1 provides the best performance. PrefVideo0galiseur vido logicielSoftware video equalizer PrefVideoHUtiliser un galiseur vido logicielUse software video equalizer PrefVideo,Pilote de sortie vidoVideo output driver PrefVideoVous pouvez cocher cette option si l'galiseur vido n'est pas pris en charge par votre carte graphique ou le pilote de sortie vido slectionn. <br> <b> Remarque: </ b> cette option peut tre incompatible avec certains pilotes de sortie vido.You can check this option if video equalizer is not supported by your graphic card or the selected video output driver.
Note: this option can be incompatible with some video output drivers. PrefVideolentslow PrefVideoAppliquerApplyPreferencesDialogl'audioAudioPreferencesDialogAnnulerCancelPreferencesDialogGnralGeneralPreferencesDialog2Kylin Video - PrfrencesKylin Video - PreferencesPreferencesDialogD'accordOKPreferencesDialogPerformance PerformancePreferencesDialogPrfrence PreferencePreferencesDialogCapture d'cran ScreenShotPreferencesDialog&Touche de raccourci Shortcut KeyPreferencesDialogLes sous-titres SubtitlesPreferencesDialog VidoVideoPreferencesDialog% 1 et% 2 %1 and %2QObject  %n minute(s)QObject  %n second(s)QObjectlCeci est Kylin Vedio v.% 1 en cours d'excution sur% 2'This is Kylin Vedio v. %1 running on %2QObjectautoautoQObjectdsactivedisabledQObjectinconnuunknownQObject(Ajouter un raccourci Add shortcutShortcutGetterAnnulerCancelShortcutGetterCapturerCaptureShortcutGetter$Saisir les frappesCapture keystrokesShortcutGetter ClairClearShortcutGetter*Modifier le raccourciModify shortcutShortcutGetterD'accordOKShortcutGetterAppuyez sur la combinaison de touches que vous souhaitez attribuer.,Press the key combination you want to assignShortcutGetter,Supprimer le raccourciRemove shortcutShortcutGetterFormats audio Audio formatsSupportFormatsCertains formats vido ne prennent pas en charge la prvisualisation et la recherche par glissement, par exemple le swf.MSome video formats do not support preview and seek by dragging, e.g. the swf.SupportFormats,Formats de sous-titresSubtitles formatsSupportFormatsFormats vido Video formatsSupportFormatsAnnulerCancel TimeDialogSauter :Jump to: TimeDialogD'accordOK TimeDialogChercherSeek TimeDialogKylin Vido Kylin Video TitleWidgetAutoAuto TristateComboNonNo TristateComboOuiYes TristateCombo*Pas de nom de fichier No filename VideoPreview4Le fichier% 1 n'existe pasThe file %1 doesn't exist VideoPreview:La longueur de la vido est 0The length of the video is 0 VideoPreviewNLe processus mplayer n'a pas fonctionnThe mplayer process didn't run VideoPreviewLe processus mplayer n'a pas dmarr alors que l'on tentait d'obtenir des informations sur la vido.IThe mplayer process didn't start while trying to get info about the video VideoPreviewhLe rpertoire temporaire (% 1) ne peut pas tre cr-The temporary directory (%1) can't be created VideoPreviewkylin-video/src/translations/kylin-video.pot0000644000175000017500000010745313517016402020227 0ustar fengfeng#, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-10-15 15:13+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Translate Toolkit 1.13.0\n" #: AboutDialog#1 msgid "About" msgstr "" #: AboutDialog#2 msgid "Contributor" msgstr "" #: AboutDialog#3 msgid "" "\n" "\n" "

<" "br />

" msgstr "" #: AboutDialog#4 msgctxt "AboutDialog#4" msgid "OK" msgstr "" #: AboutDialog#5 msgid "" "Kylin Video is developed on the basis of SMPlayer, is a graphical interface " "for MPlayer and MPV." msgstr "" #: AboutDialog#6 msgctxt "AboutDialog#6" msgid "Kylin Video" msgstr "" #: AboutDialog#7 msgid "Version: %1" msgstr "" #: AboutDialog#8 msgid "Using Qt %1 (compiled with Qt %2)" msgstr "" #: AboutDialog#9 msgctxt "AboutDialog#9" msgid "Playback engine:" msgstr "" #: ActionsEditor#1 msgid "Shortcut" msgstr "" #: ActionsEditor#2 msgid "Description" msgstr "" #: ActionsEditor#3 msgid "Name" msgstr "" #: AudioDelayDialog#1 msgid "Audio delay" msgstr "" #: AudioDelayDialog#2 msgctxt "AudioDelayDialog#2" msgid "OK" msgstr "" #: AudioDelayDialog#3 msgctxt "AudioDelayDialog#3" msgid "Cancel" msgstr "" #: AudioDelayDialog#4 msgid "Audio delay (in milliseconds):" msgstr "" #: BaseGui#1 msgctxt "BaseGui#1" msgid "Kylin Video" msgstr "" #: BaseGui#2 msgid "Open" msgstr "" #: BaseGui#3 msgid "Open &File..." msgstr "" #: BaseGui#4 msgid "Directory..." msgstr "" #: BaseGui#5 msgid "&URL..." msgstr "" #: BaseGui#6 msgid "&Clear" msgstr "" #: BaseGui#7 msgid "Recent files" msgstr "" #: BaseGui#8 msgid "Play control" msgstr "" #: BaseGui#9 msgid "Forward and rewind" msgstr "" #: BaseGui#10 msgid "&Jump to..." msgstr "" #: BaseGui#11 msgid "Play Speed" msgstr "" #: BaseGui#12 msgid "Normal speed" msgstr "" #: BaseGui#13 msgid "Half speed" msgstr "" #: BaseGui#14 msgid "Double speed" msgstr "" #: BaseGui#15 msgid "Speed -10%" msgstr "" #: BaseGui#16 msgid "Speed +10%" msgstr "" #: BaseGui#17 msgid "Speed -4%" msgstr "" #: BaseGui#18 msgid "Speed +4%" msgstr "" #: BaseGui#19 msgid "Speed -1%" msgstr "" #: BaseGui#20 msgid "Speed +1%" msgstr "" #: BaseGui#21 msgctxt "BaseGui#21" msgid "Next" msgstr "" #: BaseGui#22 msgid "Previous" msgstr "" #: BaseGui#23 msgid "&Auto" msgstr "" #: BaseGui#24 msgid "&Disabled" msgstr "" #: BaseGui#25 msgid "Aspect ratio" msgstr "" #: BaseGui#26 msgid "&Off" msgstr "" #: BaseGui#27 msgid "&Rotate by 90 degrees clockwise and flip" msgstr "" #: BaseGui#28 msgid "Rotate by 90 degrees &clockwise" msgstr "" #: BaseGui#29 msgid "Rotate by 90 degrees counterclock&wise" msgstr "" #: BaseGui#30 msgid "Rotate by 90 degrees counterclockwise and &flip" msgstr "" #: BaseGui#31 msgid "Fli&p image" msgstr "" #: BaseGui#32 msgid "Mirr&or image" msgstr "" #: BaseGui#33 msgid "Frame rotation" msgstr "" #: BaseGui#34 msgid "&Rotate" msgstr "" #: BaseGui#35 msgid "&Screenshot" msgstr "" #: BaseGui#36 msgid "&Always" msgstr "" #: BaseGui#37 msgid "&Never" msgstr "" #: BaseGui#38 msgid "While &playing" msgstr "" #: BaseGui#39 msgid "S&tay on top" msgstr "" #: BaseGui#40 msgid "Order play" msgstr "" #: BaseGui#41 msgid "Random play" msgstr "" #: BaseGui#42 msgid "List loop play" msgstr "" #: BaseGui#43 msgid "Play order" msgstr "" #: BaseGui#44 msgid "&Stereo" msgstr "" #: BaseGui#45 msgid "&4.0 Surround" msgstr "" #: BaseGui#46 msgid "&5.1 Surround" msgstr "" #: BaseGui#47 msgid "&6.1 Surround" msgstr "" #: BaseGui#48 msgid "&7.1 Surround" msgstr "" #: BaseGui#49 msgid "&Channels" msgstr "" #: BaseGui#50 msgctxt "BaseGui#50" msgid "Audio" msgstr "" #: BaseGui#51 msgid "&Mute" msgstr "" #: BaseGui#52 msgid "Volume -" msgstr "" #: BaseGui#53 msgid "Volume +" msgstr "" #: BaseGui#54 msgid "Delay -" msgstr "" #: BaseGui#55 msgid "Delay +" msgstr "" #: BaseGui#56 msgid "Set dela&y..." msgstr "" #: BaseGui#57 msgid "&Left channel" msgstr "" #: BaseGui#58 msgid "&Right channel" msgstr "" #: BaseGui#59 msgid "&Mono" msgstr "" #: BaseGui#60 msgid "Re&verse" msgstr "" #: BaseGui#61 msgid "&Stereo mode" msgstr "" #: BaseGui#62 msgctxt "BaseGui#62" msgid "Subtitles" msgstr "" #: BaseGui#63 msgid "Load..." msgstr "" #: BaseGui#64 msgid "Subtitle &visibility" msgstr "" #: BaseGui#65 msgid "Preferences" msgstr "" #: BaseGui#66 msgid "View &info and properties..." msgstr "" #: BaseGui#67 msgctxt "BaseGui#67" msgid "Help" msgstr "" #: BaseGui#68 msgid "About &Kylin Video" msgstr "" #: BaseGui#69 msgid "Quit" msgstr "" #: BaseGui#70 msgid "Open Homepage" msgstr "" #: BaseGui#71 msgid "Open screenshots folder" msgstr "" #: BaseGui#72 msgctxt "BaseGui#72" msgid "PlayList" msgstr "" #: BaseGui#73 msgid "Play/Pause" msgstr "" #: BaseGui#74 msgctxt "BaseGui#74" msgid "Stop" msgstr "" #: BaseGui#75 msgid "Fullscreen" msgstr "" #: BaseGui#76 msgid "Video filters are disabled when using vdpau" msgstr "" #: BaseGui#77 msgid "-%1" msgstr "" #: BaseGui#78 msgid "+%1" msgstr "" #: BaseGui#79 msgid "" msgstr "" #: BaseGui#80 msgid "Confirm deletion - Kylin Video" msgstr "" #: BaseGui#81 msgid "Delete the list of recent files?" msgstr "" #: BaseGui#82 msgid "Choose a file" msgstr "" #: BaseGui#83 msgctxt "BaseGui#83" msgid "Multimedia" msgstr "" #: BaseGui#84 msgctxt "BaseGui#84" msgid "Video" msgstr "" #: BaseGui#85 msgid "Playlists" msgstr "" #: BaseGui#86 msgctxt "BaseGui#86" msgid "All files" msgstr "" #: BaseGui#87 msgctxt "BaseGui#87" msgid "Choose a directory" msgstr "" #: BaseGui#88 msgid "&Jump to:" msgstr "" #: BaseGui#89 msgid "Kylin Video - Seek" msgstr "" #: BaseGui#90 msgid "Kylin Video - Subtitle delay" msgstr "" #: BaseGui#91 msgid "Subtitle delay (in milliseconds):" msgstr "" #: BaseGui#92 msgid "Error detected" msgstr "" #: BaseGui#93 msgid "Unfortunately this video can't be played." msgstr "" #: BaseGui#94 msgid "The server returned '%1'" msgstr "" #: BaseGui#95 msgid "Jump to %1" msgstr "" #: BaseGui#96 msgid "%1 Error" msgstr "" #: BaseGui#97 msgid "'%1' was not found!" msgstr "" #: BaseGui#98 msgid "%1 has finished unexpectedly." msgstr "" #: BaseGui#99 msgid "Exit code: %1" msgstr "" #: BaseGui#100 msgid "%1 failed to start." msgstr "" #: BaseGui#101 msgid "Please check the %1 path in preferences." msgstr "" #: BaseGui#102 msgid "%1 has crashed." msgstr "" #: BaseGui#103 msgid "See the log for more info." msgstr "" #: BaseGui#104 msgctxt "BaseGui#104" msgid "Information" msgstr "" #: BaseGui#105 msgid "The screenshot folder does not exist!" msgstr "" #: BottomWidget#1 msgctxt "BottomWidget#1" msgid "Stop" msgstr "" #: BottomWidget#2 msgid "Prev" msgstr "" #: BottomWidget#3 msgid "Play / Pause" msgstr "" #: BottomWidget#4 msgctxt "BottomWidget#4" msgid "Next" msgstr "" #: BottomWidget#5 msgid "Mute" msgstr "" #: BottomWidget#6 msgid "Play List" msgstr "" #: Core#1 msgid "Screenshot NOT taken, folder not configured" msgstr "" #: Core#2 msgid "Screenshots NOT taken, folder not configured" msgstr "" #: Core#3 msgid "\"A\" marker set to %1" msgstr "" #: Core#4 msgid "\"B\" marker set to %1" msgstr "" #: Core#5 msgid "A-B markers cleared" msgstr "" #: Core#6 msgid "Brightness: %1" msgstr "" #: Core#7 msgid "Contrast: %1" msgstr "" #: Core#8 msgid "Gamma: %1" msgstr "" #: Core#9 msgid "Hue: %1" msgstr "" #: Core#10 msgid "Saturation: %1" msgstr "" #: Core#11 msgid "Speed: %1" msgstr "" #: Core#12 msgid "Volume: %1" msgstr "" #: Core#13 msgid "Subtitle delay: %1 ms" msgstr "" #: Core#14 msgid "Audio delay: %1 ms" msgstr "" #: Core#15 msgid "Subtitles on" msgstr "" #: Core#16 msgid "Subtitles off" msgstr "" #: Core#17 msgid "Aspect ratio: %1" msgstr "" #: Core#18 msgid "Mouse wheel seeks now" msgstr "" #: Core#19 msgid "Mouse wheel changes volume now" msgstr "" #: Core#20 msgid "Mouse wheel changes zoom level now" msgstr "" #: Core#21 msgid "Mouse wheel changes speed now" msgstr "" #: Core#22 msgid "Zoom: %1" msgstr "" #: Core#23 msgid "Screenshot saved as %1" msgstr "" #: Core#24 msgid "Updating the font cache. This may take some seconds..." msgstr "" #: Core#25 msgid "Buffering..." msgstr "" #: Core#26 msgid "Starting..." msgstr "" #: ErrorDialog#1 msgid "MPlayer Error" msgstr "" #: ErrorDialog#2 msgctxt "ErrorDialog#2" msgid "OK" msgstr "" #: ErrorDialog#3 msgid "icon" msgstr "" #: ErrorDialog#4 msgid "Oops, something wrong happened" msgstr "" #: ErrorDialog#5 msgid "Error" msgstr "" #: ErrorDialog#6 msgid "Show log" msgstr "" #: ErrorDialog#7 msgid "Hide log" msgstr "" #: EscTip#1 msgid "Press ESC to exit full screen mode" msgstr "" #: FileChooser#1 msgid "Click to select a file or folder" msgstr "" #: FilePropertiesDialog#1 msgctxt "FilePropertiesDialog#1" msgid "Kylin Video - Preferences" msgstr "" #: FilePropertiesDialog#2 msgid "Properties" msgstr "" #: FilePropertiesDialog#3 msgid "&Select the demuxer that will be used for this file:" msgstr "" #: FilePropertiesDialog#4 msgid "&Reset" msgstr "" #: FilePropertiesDialog#5 msgid "&Select the video codec:" msgstr "" #: FilePropertiesDialog#6 msgid "&Select the audio codec:" msgstr "" #: FilePropertiesDialog#7 msgid "Reset" msgstr "" #: FilePropertiesDialog#8 msgctxt "FilePropertiesDialog#8" msgid "Apply" msgstr "" #: FilePropertiesDialog#9 msgctxt "FilePropertiesDialog#9" msgid "OK" msgstr "" #: FilePropertiesDialog#10 msgctxt "FilePropertiesDialog#10" msgid "Cancel" msgstr "" #: FilePropertiesDialog#11 msgctxt "FilePropertiesDialog#11" msgid "Information" msgstr "" #: FilePropertiesDialog#12 msgid "Demuxer" msgstr "" #: FilePropertiesDialog#13 msgid "Video codec" msgstr "" #: FilePropertiesDialog#14 msgid "Audio codec" msgstr "" #: HelpDialog#1 msgid "Kylin Video - Help" msgstr "" #: HelpDialog#2 msgctxt "HelpDialog#2" msgid "Help" msgstr "" #: HelpDialog#3 msgctxt "HelpDialog#3" msgid "OK" msgstr "" #: HelpDialog#4 msgid "Supported formats" msgstr "" #: InputURL#1 msgid "Enter URL" msgstr "" #: InputURL#2 msgctxt "InputURL#2" msgid "OK" msgstr "" #: InputURL#3 msgctxt "InputURL#3" msgid "Cancel" msgstr "" #: InputURL#4 msgid "URL:" msgstr "" #: Languages#1 msgid "Afar" msgstr "" #: Languages#2 msgid "Abkhazian" msgstr "" #: Languages#3 msgid "Avestan" msgstr "" #: Languages#4 msgid "Afrikaans" msgstr "" #: Languages#5 msgid "Akan" msgstr "" #: Languages#6 msgid "Amharic" msgstr "" #: Languages#7 msgid "Aragonese" msgstr "" #: Languages#8 msgid "Arabic" msgstr "" #: Languages#9 msgid "Assamese" msgstr "" #: Languages#10 msgid "Avaric" msgstr "" #: Languages#11 msgid "Aymara" msgstr "" #: Languages#12 msgid "Azerbaijani" msgstr "" #: Languages#13 msgid "Bashkir" msgstr "" #: Languages#14 msgid "Belarusian" msgstr "" #: Languages#15 msgid "Bulgarian" msgstr "" #: Languages#16 msgid "Bihari" msgstr "" #: Languages#17 msgid "Bislama" msgstr "" #: Languages#18 msgid "Bambara" msgstr "" #: Languages#19 msgid "Bengali" msgstr "" #: Languages#20 msgid "Tibetan" msgstr "" #: Languages#21 msgid "Breton" msgstr "" #: Languages#22 msgid "Bosnian" msgstr "" #: Languages#23 msgid "Catalan" msgstr "" #: Languages#24 msgid "Chechen" msgstr "" #: Languages#25 msgid "Corsican" msgstr "" #: Languages#26 msgid "Cree" msgstr "" #: Languages#27 msgid "Czech" msgstr "" #: Languages#28 msgid "Church" msgstr "" #: Languages#29 msgid "Chuvash" msgstr "" #: Languages#30 msgid "Welsh" msgstr "" #: Languages#31 msgid "Danish" msgstr "" #: Languages#32 msgid "German" msgstr "" #: Languages#33 msgid "Divehi" msgstr "" #: Languages#34 msgid "Dzongkha" msgstr "" #: Languages#35 msgid "Ewe" msgstr "" #: Languages#36 msgid "Greek" msgstr "" #: Languages#37 msgid "English" msgstr "" #: Languages#38 msgid "Esperanto" msgstr "" #: Languages#39 msgid "Spanish" msgstr "" #: Languages#40 msgid "Estonian" msgstr "" #: Languages#41 msgid "Basque" msgstr "" #: Languages#42 msgid "Persian" msgstr "" #: Languages#43 msgid "Fulah" msgstr "" #: Languages#44 msgid "Finnish" msgstr "" #: Languages#45 msgid "Fijian" msgstr "" #: Languages#46 msgid "Faroese" msgstr "" #: Languages#47 msgid "French" msgstr "" #: Languages#48 msgid "Frisian" msgstr "" #: Languages#49 msgid "Irish" msgstr "" #: Languages#50 msgid "Gaelic" msgstr "" #: Languages#51 msgid "Galician" msgstr "" #: Languages#52 msgid "Guarani" msgstr "" #: Languages#53 msgid "Gujarati" msgstr "" #: Languages#54 msgid "Manx" msgstr "" #: Languages#55 msgid "Hausa" msgstr "" #: Languages#56 msgid "Hebrew" msgstr "" #: Languages#57 msgid "Hindi" msgstr "" #: Languages#58 msgid "Hiri" msgstr "" #: Languages#59 msgid "Croatian" msgstr "" #: Languages#60 msgid "Haitian" msgstr "" #: Languages#61 msgid "Hungarian" msgstr "" #: Languages#62 msgid "Armenian" msgstr "" #: Languages#63 msgid "Herero" msgstr "" #: Languages#64 msgid "Chamorro" msgstr "" #: Languages#65 msgid "Interlingua" msgstr "" #: Languages#66 msgid "Indonesian" msgstr "" #: Languages#67 msgid "Interlingue" msgstr "" #: Languages#68 msgid "Igbo" msgstr "" #: Languages#69 msgid "Sichuan" msgstr "" #: Languages#70 msgid "Inupiaq" msgstr "" #: Languages#71 msgid "Ido" msgstr "" #: Languages#72 msgid "Icelandic" msgstr "" #: Languages#73 msgid "Italian" msgstr "" #: Languages#74 msgid "Inuktitut" msgstr "" #: Languages#75 msgid "Japanese" msgstr "" #: Languages#76 msgid "Javanese" msgstr "" #: Languages#77 msgid "Georgian" msgstr "" #: Languages#78 msgid "Kongo" msgstr "" #: Languages#79 msgid "Kikuyu" msgstr "" #: Languages#80 msgid "Kuanyama" msgstr "" #: Languages#81 msgid "Kazakh" msgstr "" #: Languages#82 msgid "Greenlandic" msgstr "" #: Languages#83 msgid "Khmer" msgstr "" #: Languages#84 msgid "Kannada" msgstr "" #: Languages#85 msgid "Korean" msgstr "" #: Languages#86 msgid "Kanuri" msgstr "" #: Languages#87 msgid "Kashmiri" msgstr "" #: Languages#88 msgid "Kurdish" msgstr "" #: Languages#89 msgid "Komi" msgstr "" #: Languages#90 msgid "Cornish" msgstr "" #: Languages#91 msgid "Kirghiz" msgstr "" #: Languages#92 msgid "Latin" msgstr "" #: Languages#93 msgid "Luxembourgish" msgstr "" #: Languages#94 msgid "Ganda" msgstr "" #: Languages#95 msgid "Limburgan" msgstr "" #: Languages#96 msgid "Lingala" msgstr "" #: Languages#97 msgid "Lao" msgstr "" #: Languages#98 msgid "Lithuanian" msgstr "" #: Languages#99 msgid "Luba-Katanga" msgstr "" #: Languages#100 msgid "Latvian" msgstr "" #: Languages#101 msgid "Malagasy" msgstr "" #: Languages#102 msgid "Marshallese" msgstr "" #: Languages#103 msgid "Maori" msgstr "" #: Languages#104 msgid "Macedonian" msgstr "" #: Languages#105 msgid "Malayalam" msgstr "" #: Languages#106 msgid "Mongolian" msgstr "" #: Languages#107 msgid "Moldavian" msgstr "" #: Languages#108 msgid "Marathi" msgstr "" #: Languages#109 msgid "Malay" msgstr "" #: Languages#110 msgid "Maltese" msgstr "" #: Languages#111 msgid "Burmese" msgstr "" #: Languages#112 msgid "Nauru" msgstr "" #: Languages#113 msgid "Bokmål" msgstr "" #: Languages#114 msgid "Ndebele" msgstr "" #: Languages#115 msgid "Nepali" msgstr "" #: Languages#116 msgid "Ndonga" msgstr "" #: Languages#117 msgid "Dutch" msgstr "" #: Languages#118 msgid "Norwegian Nynorsk" msgstr "" #: Languages#119 msgid "Norwegian" msgstr "" #: Languages#120 msgid "Navajo" msgstr "" #: Languages#121 msgid "Chichewa" msgstr "" #: Languages#122 msgid "Occitan" msgstr "" #: Languages#123 msgid "Ojibwa" msgstr "" #: Languages#124 msgid "Oromo" msgstr "" #: Languages#125 msgid "Oriya" msgstr "" #: Languages#126 msgid "Ossetian" msgstr "" #: Languages#127 msgid "Panjabi" msgstr "" #: Languages#128 msgid "Pali" msgstr "" #: Languages#129 msgid "Polish" msgstr "" #: Languages#130 msgid "Pushto" msgstr "" #: Languages#131 msgid "Portuguese" msgstr "" #: Languages#132 msgid "Quechua" msgstr "" #: Languages#133 msgid "Romansh" msgstr "" #: Languages#134 msgid "Rundi" msgstr "" #: Languages#135 msgid "Romanian" msgstr "" #: Languages#136 msgid "Russian" msgstr "" #: Languages#137 msgid "Kinyarwanda" msgstr "" #: Languages#138 msgid "Sanskrit" msgstr "" #: Languages#139 msgid "Sardinian" msgstr "" #: Languages#140 msgid "Sindhi" msgstr "" #: Languages#141 msgid "Sami" msgstr "" #: Languages#142 msgid "Sango" msgstr "" #: Languages#143 msgid "Sinhala" msgstr "" #: Languages#144 msgid "Slovak" msgstr "" #: Languages#145 msgid "Slovene" msgstr "" #: Languages#146 msgid "Samoan" msgstr "" #: Languages#147 msgid "Shona" msgstr "" #: Languages#148 msgid "Somali" msgstr "" #: Languages#149 msgid "Albanian" msgstr "" #: Languages#150 msgid "Serbian" msgstr "" #: Languages#151 msgid "Swati" msgstr "" #: Languages#152 msgid "Sotho" msgstr "" #: Languages#153 msgid "Sundanese" msgstr "" #: Languages#154 msgid "Swedish" msgstr "" #: Languages#155 msgid "Swahili" msgstr "" #: Languages#156 msgid "Tamil" msgstr "" #: Languages#157 msgid "Telugu" msgstr "" #: Languages#158 msgid "Tajik" msgstr "" #: Languages#159 msgid "Thai" msgstr "" #: Languages#160 msgid "Tigrinya" msgstr "" #: Languages#161 msgid "Turkmen" msgstr "" #: Languages#162 msgid "Tagalog" msgstr "" #: Languages#163 msgid "Tswana" msgstr "" #: Languages#164 msgid "Tonga" msgstr "" #: Languages#165 msgid "Turkish" msgstr "" #: Languages#166 msgid "Tsonga" msgstr "" #: Languages#167 msgid "Tatar" msgstr "" #: Languages#168 msgid "Twi" msgstr "" #: Languages#169 msgid "Tahitian" msgstr "" #: Languages#170 msgid "Uighur" msgstr "" #: Languages#171 msgid "Ukrainian" msgstr "" #: Languages#172 msgid "Urdu" msgstr "" #: Languages#173 msgid "Uzbek" msgstr "" #: Languages#174 msgid "Venda" msgstr "" #: Languages#175 msgid "Vietnamese" msgstr "" #: Languages#176 msgid "Volapük" msgstr "" #: Languages#177 msgid "Walloon" msgstr "" #: Languages#178 msgid "Wolof" msgstr "" #: Languages#179 msgid "Xhosa" msgstr "" #: Languages#180 msgid "Yiddish" msgstr "" #: Languages#181 msgid "Yoruba" msgstr "" #: Languages#182 msgid "Zhuang" msgstr "" #: Languages#183 msgid "Chinese" msgstr "" #: Languages#184 msgid "Zulu" msgstr "" #: Languages#185 msgid "Arabic - Syria" msgstr "" #: Languages#186 msgid "Unicode" msgstr "" #: Languages#187 msgid "UTF-8" msgstr "" #: Languages#188 msgid "Western European Languages" msgstr "" #: Languages#189 msgid "Western European Languages with Euro" msgstr "" #: Languages#190 msgid "Slavic/Central European Languages" msgstr "" #: Languages#191 msgid "Esperanto, Galician, Maltese, Turkish" msgstr "" #: Languages#192 msgid "Old Baltic charset" msgstr "" #: Languages#193 msgid "Cyrillic" msgstr "" #: Languages#194 msgid "Modern Greek" msgstr "" #: Languages#195 msgid "Baltic" msgstr "" #: Languages#196 msgid "Celtic" msgstr "" #: Languages#197 msgid "South-Eastern European" msgstr "" #: Languages#198 msgid "Hebrew charsets" msgstr "" #: Languages#199 msgid "Ukrainian, Belarusian" msgstr "" #: Languages#200 msgid "Simplified Chinese charset" msgstr "" #: Languages#201 msgid "Traditional Chinese charset" msgstr "" #: Languages#202 msgid "Japanese charsets" msgstr "" #: Languages#203 msgid "Korean charset" msgstr "" #: Languages#204 msgid "Thai charset" msgstr "" #: Languages#205 msgid "Cyrillic Windows" msgstr "" #: Languages#206 msgid "Slavic/Central European Windows" msgstr "" #: Languages#207 msgid "Arabic Windows" msgstr "" #: Languages#208 msgid "Modern Greek Windows" msgstr "" #: LineEditWithIcon#1 msgid "Change" msgstr "" #: MPVProcess#1 msgid "the '%1' filter is not supported by mpv" msgstr "" #: MessageDialog#1 msgid "Ok" msgstr "" #: MessageDialog#2 msgctxt "MessageDialog#2" msgid "Cancel" msgstr "" #: MessageDialog#3 msgctxt "MessageDialog#3" msgid "Yes" msgstr "" #: MessageDialog#4 msgctxt "MessageDialog#4" msgid "No" msgstr "" #: MplayerProcess#1 msgid "This option is not supported by MPlayer" msgstr "" #: Playlist#1 msgid "Playlist is empty" msgstr "" #: Playlist#2 msgid "Add File" msgstr "" #: Playlist#3 msgctxt "Playlist#3" msgid "PlayList" msgstr "" #: Playlist#4 msgctxt "Playlist#4" msgid "Clear" msgstr "" #: Playlist#5 msgid "Add" msgstr "" #: Playlist#6 msgid "Play" msgstr "" #: Playlist#7 msgid "Remove &selected" msgstr "" #: Playlist#8 msgid "&Delete file from disk" msgstr "" #: Playlist#9 msgid "Reached the end of the playlist" msgstr "" #: Playlist#10 msgid "Select one or more files to open" msgstr "" #: Playlist#11 msgctxt "Playlist#11" msgid "Multimedia" msgstr "" #: Playlist#12 msgctxt "Playlist#12" msgid "All files" msgstr "" #: Playlist#13 msgctxt "Playlist#13" msgid "Choose a directory" msgstr "" #: Playlist#14 msgid "Confirm remove" msgstr "" #: Playlist#15 msgid "You're about to remove the file '%1' from the playlist." msgstr "" #: Playlist#16 msgid "Are you sure you want to proceed?" msgstr "" #: Playlist#17 msgid "Confirm deletion" msgstr "" #: Playlist#18 msgid "You're about to DELETE the file '%1' from your drive." msgstr "" #: Playlist#19 msgid "This action cannot be undone. Are you sure you want to proceed?" msgstr "" #: Playlist#20 msgid "Deletion failed" msgstr "" #: Playlist#21 msgid "It wasn't possible to delete '%1'" msgstr "" #: Playlist#22 msgid "Error deleting the file" msgstr "" #: Playlist#23 msgid "It's not possible to delete '%1' from the filesystem." msgstr "" #: PrefAudio#1 msgid "Volume" msgstr "" #: PrefAudio#2 msgid "Global volume" msgstr "" #: PrefAudio#3 msgid "Use software volume control" msgstr "" #: PrefAudio#4 msgid "Max. Amplification:" msgstr "" #: PrefAudio#5 msgid "Volume normalization by default" msgstr "" #: PrefAudio#6 msgid "Synchronization" msgstr "" #: PrefAudio#7 msgid "Audio/video auto synchronization" msgstr "" #: PrefAudio#8 msgid "Factor:" msgstr "" #: PrefAudio#9 msgctxt "PrefAudio#9" msgid "Output driver:" msgstr "" #: PrefAudio#10 msgid "Channels by default:" msgstr "" #: PrefAudio#11 msgid "2 (Stereo)" msgstr "" #: PrefAudio#12 msgid "4 (4.0 Surround)" msgstr "" #: PrefAudio#13 msgid "6 (5.1 Surround)" msgstr "" #: PrefAudio#14 msgid "7 (6.1 Surround)" msgstr "" #: PrefAudio#15 msgid "8 (7.1 Surround)" msgstr "" #: PrefAudio#16 msgctxt "PrefAudio#16" msgid "Default" msgstr "" #: PrefAudio#17 msgid "Audio output driver" msgstr "" #: PrefAudio#18 msgid "Select the audio output driver." msgstr "" #: PrefAudio#19 msgid "" "%1 is the recommended one. Try to avoid %2 and %3, they are slow and can " "have an impact on performance." msgstr "" #: PrefAudio#20 msgid "Channels by default" msgstr "" #: PrefAudio#21 msgid "" "Requests the number of playback channels. MPlayer asks the decoder to decode " "the audio into as many channels as specified. Then it is up to the decoder " "to fulfill the requirement. This is usually only important when playing " "videos with AC3 audio (like DVDs). In that case liba52 does the decoding by " "default and correctly downmixes the audio into the requested number of " "channels. Note: This option is honored by codecs (AC3 only), filters " "(surround) and audio output drivers (OSS at least)." msgstr "" #: PrefAudio#22 msgid "" "If this option is checked, the same volume will be used for all files you " "play. If the option is not checked each file uses its own volume." msgstr "" #: PrefAudio#23 msgid "This option also applies for the mute control." msgstr "" #: PrefAudio#24 msgid "Software volume control" msgstr "" #: PrefAudio#25 msgid "" "Check this option to use the software mixer, instead of using the sound card " "mixer." msgstr "" #: PrefAudio#26 msgid "Max. Amplification" msgstr "" #: PrefAudio#27 msgid "" "Sets the maximum amplification level in percent (default: 110). A value of " "200 will allow you to adjust the volume up to a maximum of double the " "current level. With values below 100 the initial volume (which is 100%) will " "be above the maximum, which e.g. the OSD cannot display correctly." msgstr "" #: PrefAudio#28 msgid "Maximizes the volume without distorting the sound." msgstr "" #: PrefAudio#29 msgid "Gradually adjusts the A/V sync based on audio delay measurements." msgstr "" #: PrefGeneral#1 msgid "Pause when minimized" msgstr "" #: PrefGeneral#2 msgid "MPlayer" msgstr "" #: PrefGeneral#3 msgid "MPV" msgstr "" #: PrefGeneral#4 msgctxt "PrefGeneral#4" msgid "Playback engine:" msgstr "" #: PrefGeneral#5 msgid "Preview when video is playing" msgstr "" #: PrefGeneral#6 msgid "" "If this option is enabled, the file will be paused when the main window is " "hidden. When the window is restored, playback will be resumed." msgstr "" #: PrefGeneral#7 msgid "Preview when the video is playing" msgstr "" #: PrefGeneral#8 msgid "" "If this option is enabled, the video preview will be displayed when the " "mouse is placed on the progress bar." msgstr "" #: PrefGeneral#9 msgid "Select MPlayer as playback engine" msgstr "" #: PrefGeneral#10 msgid "" "If you change the playback engine to MPlayer, please restart Kylin Video." msgstr "" #: PrefGeneral#11 msgid "Select MPV as playback engine" msgstr "" #: PrefGeneral#12 msgid "If you change the playback engine to MPV, please restart Kylin Video." msgstr "" #: PrefPerformance#1 msgid "Cache" msgstr "" #: PrefPerformance#2 msgid "Cache for local files:" msgstr "" #: PrefPerformance#3 msgid "KB" msgstr "" #: PrefPerformance#4 msgid "Cache for streams:" msgstr "" #: PrefPerformance#5 msgid "Decode" msgstr "" #: PrefPerformance#6 msgid "Threads for decoding (MPEG-1/2 and H.264 only):" msgstr "" #: PrefPerformance#7 msgid "Hardware decoding" msgstr "" #: PrefPerformance#8 msgid "None" msgstr "" #: PrefPerformance#9 msgctxt "PrefPerformance#9" msgid "Auto" msgstr "" #: PrefPerformance#10 msgctxt "PrefPerformance#10" msgid "Performance" msgstr "" #: PrefPerformance#11 msgid "Threads for decoding" msgstr "" #: PrefPerformance#12 msgid "" "Sets the number of threads to use for decoding. Only for MPEG-1/2 and H.264" msgstr "" #: PrefPerformance#13 msgid "" "Sets the hardware video decoding API. If hardware decoding is not possible, " "software decoding will be used instead." msgstr "" #: PrefPerformance#14 msgid "Available options:" msgstr "" #: PrefPerformance#15 msgid "None: only software decoding will be used." msgstr "" #: PrefPerformance#16 msgid "" "Auto: it tries to automatically enable hardware decoding using the first " "available method." msgstr "" #: PrefPerformance#17 msgid "vdpau: for the vdpau and opengl video outputs." msgstr "" #: PrefPerformance#18 msgid "vaapi: for the opengl and vaapi video outputs. For Intel GPUs only." msgstr "" #: PrefPerformance#19 msgid "vaapi-copy: it copies video back into system RAM. For Intel GPUs only." msgstr "" #: PrefPerformance#20 msgctxt "PrefPerformance#20" msgid "This option only works with mpv." msgstr "" #: PrefPerformance#21 msgid "Cache for files" msgstr "" #: PrefPerformance#22 msgid "" "This option specifies how much memory (in kBytes) to use when precaching a " "file." msgstr "" #: PrefPerformance#23 msgid "Cache for streams" msgstr "" #: PrefPerformance#24 msgid "" "This option specifies how much memory (in kBytes) to use when precaching a " "URL." msgstr "" #: PrefScreenShot#1 msgid "Screenshots" msgstr "" #: PrefScreenShot#2 msgid "Enable screenshots" msgstr "" #: PrefScreenShot#3 msgid "Folder:" msgstr "" #: PrefScreenShot#4 msgid "Template:" msgstr "" #: PrefScreenShot#5 msgid "Format:" msgstr "" #: PrefScreenShot#6 msgid "Select a directory" msgstr "" #: PrefScreenShot#7 msgid "" "You can use this option to enable or disable the possibility to take " "screenshots." msgstr "" #: PrefScreenShot#8 msgid "Screenshots folder" msgstr "" #: PrefScreenShot#9 msgid "" "Here you can specify a folder where the screenshots taken by Kylin Video " "will be stored. If the folder is not valid the screenshot feature will be " "disabled." msgstr "" #: PrefScreenShot#10 msgid "Template for screenshots" msgstr "" #: PrefScreenShot#11 msgid "This option specifies the filename template used to save screenshots." msgstr "" #: PrefScreenShot#12 msgid "For example %1 would save the screenshot as 'moviename_0001.png'." msgstr "" #: PrefScreenShot#13 msgid "" "%1 specifies the filename of the video without the extension, %2 adds a 4 " "digit number padded with zeros." msgstr "" #: PrefScreenShot#14 msgid "For a full list of the template specifiers visit this link:" msgstr "" #: PrefScreenShot#15 msgctxt "PrefScreenShot#15" msgid "This option only works with mpv." msgstr "" #: PrefScreenShot#16 msgid "Format for screenshots" msgstr "" #: PrefScreenShot#17 msgid "" "This option allows one to choose the image file type used for saving " "screenshots." msgstr "" #: PrefShortCut#1 msgid "" "Here you can change any key shortcut. To do it double click or press enter " "over a shortcut cell. " msgstr "" #: PrefShortCut#2 msgid "ShortCut" msgstr "" #: PrefShortCut#3 msgid "" "Here you can change any key shortcut. To do it double click or start typing " "over a shortcut cell." msgstr "" #: PrefShortCut#4 msgctxt "PrefShortCut#4" msgid "Shortcut Key" msgstr "" #: PrefShortCut#5 msgid "Shortcut editor" msgstr "" #: PrefShortCut#6 msgid "" "This table allows you to change the key shortcuts of most available actions. " "Double click or press enter on a item, or press the Change shortcut " "button to enter in the Modify shortcut dialog. There are two ways to " "change a shortcut: if the Capture button is on then just press the " "new key or combination of keys that you want to assign for the action (" "unfortunately this doesn't work for all keys). If the Capture button " "is off then you could enter the full name of the key." msgstr "" #: PrefSubtitles#1 msgid "Autoload" msgstr "" #: PrefSubtitles#2 msgid "Autoload subtitles files (*.srt, *.sub...):" msgstr "" #: PrefSubtitles#3 msgid "Same name as movie" msgstr "" #: PrefSubtitles#4 msgid "All subs containing movie name" msgstr "" #: PrefSubtitles#5 msgid "All subs in directory" msgstr "" #: PrefSubtitles#6 msgid "Encoding" msgstr "" #: PrefSubtitles#7 msgid "Default subtitle encoding:" msgstr "" #: PrefSubtitles#8 msgid "Try to autodetect for this language:" msgstr "" #: PrefSubtitles#9 msgctxt "PrefSubtitles#9" msgid "Subtitles" msgstr "" #: PrefSubtitles#10 msgid "Select the subtitle autoload method." msgstr "" #: PrefSubtitles#11 msgid "Default subtitle encoding" msgstr "" #: PrefSubtitles#12 msgid "Select the encoding which will be used for subtitle files by default." msgstr "" #: PrefSubtitles#13 msgid "Try to autodetect for this language" msgstr "" #: PrefSubtitles#14 msgid "" "When this option is on, the encoding of the subtitles will be tried to be " "autodetected for the given language. It will fall back to the default " "encoding if the autodetection fails. This option requires a MPlayer compiled " "with ENCA support." msgstr "" #: PrefSubtitles#15 msgid "Subtitle language" msgstr "" #: PrefSubtitles#16 msgid "" "Select the language for which you want the encoding to be guessed " "automatically." msgstr "" #: PrefSubtitles#17 msgid "Font" msgstr "" #: PrefVideo#1 msgid "Enable postprocessing by default" msgstr "" #: PrefVideo#2 msgid "Draw video using slices" msgstr "" #: PrefVideo#3 msgid "Direct rendering" msgstr "" #: PrefVideo#4 msgid "Double buffering" msgstr "" #: PrefVideo#5 msgid "Use software video equalizer" msgstr "" #: PrefVideo#6 msgctxt "PrefVideo#6" msgid "Output driver:" msgstr "" #: PrefVideo#7 msgctxt "PrefVideo#7" msgid "Default" msgstr "" #: PrefVideo#8 msgid "slow" msgstr "" #: PrefVideo#9 msgid "Video output driver" msgstr "" #: PrefVideo#10 msgid "Select the video output driver. %1 provides the best performance." msgstr "" #: PrefVideo#11 msgid "Postprocessing will be used by default on new opened files." msgstr "" #: PrefVideo#12 msgid "Software video equalizer" msgstr "" #: PrefVideo#13 msgid "" "You can check this option if video equalizer is not supported by your " "graphic card or the selected video output driver.
Note: this " "option can be incompatible with some video output drivers." msgstr "" #: PrefVideo#14 msgid "" "If checked, turns on direct rendering (not supported by all codecs and video " "outputs)
Warning: May cause OSD/SUB corruption!" msgstr "" #: PrefVideo#15 msgid "" "Double buffering fixes flicker by storing two frames in memory, and " "displaying one while decoding another. If disabled it can affect OSD " "negatively, but often removes OSD flickering." msgstr "" #: PrefVideo#16 msgid "" "Enable/disable drawing video by 16-pixel height slices/bands. If disabled, " "the whole frame is drawn in a single run. May be faster or slower, depending " "on video card and available cache. It has effect only with libmpeg2 and " "libavcodec codecs." msgstr "" #: PreferencesDialog#1 msgctxt "PreferencesDialog#1" msgid "Kylin Video - Preferences" msgstr "" #: PreferencesDialog#2 msgid "Preference" msgstr "" #: PreferencesDialog#3 msgctxt "PreferencesDialog#3" msgid "Cancel" msgstr "" #: PreferencesDialog#4 msgctxt "PreferencesDialog#4" msgid "Apply" msgstr "" #: PreferencesDialog#5 msgctxt "PreferencesDialog#5" msgid "OK" msgstr "" #: PreferencesDialog#6 msgid "General" msgstr "" #: PreferencesDialog#7 msgctxt "PreferencesDialog#7" msgid "Video" msgstr "" #: PreferencesDialog#8 msgctxt "PreferencesDialog#8" msgid "Audio" msgstr "" #: PreferencesDialog#9 msgctxt "PreferencesDialog#9" msgid "Performance" msgstr "" #: PreferencesDialog#10 msgctxt "PreferencesDialog#10" msgid "Subtitles" msgstr "" #: PreferencesDialog#11 msgid "ScreenShot" msgstr "" #: PreferencesDialog#12 msgctxt "PreferencesDialog#12" msgid "Shortcut Key" msgstr "" #: QObject#1 #, fuzzy msgid "%n second(s)" msgstr "" "\n" " \n" " \n" " " #: QObject#2 #, fuzzy msgid "%n minute(s)" msgstr "" "\n" " \n" " \n" " " #: QObject#3 msgid "%1 and %2" msgstr "" #: QObject#4 msgid "This is Kylin Vedio v. %1 running on %2" msgstr "" # aspect_ratio #: QObject#5 msgid "disabled" msgstr "" # aspect_ratio #: QObject#6 msgid "auto" msgstr "" # aspect_ratio #: QObject#7 msgid "unknown" msgstr "" #: ShortcutGetter#1 msgid "Modify shortcut" msgstr "" #: ShortcutGetter#2 msgid "Add shortcut" msgstr "" #: ShortcutGetter#3 msgid "Remove shortcut" msgstr "" #: ShortcutGetter#4 msgid "Press the key combination you want to assign" msgstr "" #: ShortcutGetter#5 msgctxt "ShortcutGetter#5" msgid "Clear" msgstr "" #: ShortcutGetter#6 msgctxt "ShortcutGetter#6" msgid "OK" msgstr "" #: ShortcutGetter#7 msgctxt "ShortcutGetter#7" msgid "Cancel" msgstr "" #: ShortcutGetter#8 msgid "Capture" msgstr "" #: ShortcutGetter#9 msgid "Capture keystrokes" msgstr "" #: SupportFormats#1 msgid "Video formats" msgstr "" #: SupportFormats#2 msgid "Audio formats" msgstr "" #: SupportFormats#3 msgid "Subtitles formats" msgstr "" #: SupportFormats#4 msgid "" "Some video formats do not support preview and seek by dragging, e.g. the swf." msgstr "" #: TimeDialog#1 msgid "Seek" msgstr "" #: TimeDialog#2 msgctxt "TimeDialog#2" msgid "OK" msgstr "" #: TimeDialog#3 msgctxt "TimeDialog#3" msgid "Cancel" msgstr "" #: TimeDialog#4 msgid "Jump to:" msgstr "" #: TitleWidget#1 msgctxt "TitleWidget#1" msgid "Kylin Video" msgstr "" #: TristateCombo#1 msgctxt "TristateCombo#1" msgid "Auto" msgstr "" #: TristateCombo#2 msgctxt "TristateCombo#2" msgid "Yes" msgstr "" #: TristateCombo#3 msgctxt "TristateCombo#3" msgid "No" msgstr "" #: VideoPreview#1 msgid "The length of the video is 0" msgstr "" #: VideoPreview#2 msgid "The temporary directory (%1) can't be created" msgstr "" #: VideoPreview#3 msgid "The file %1 doesn't exist" msgstr "" #: VideoPreview#4 msgid "The mplayer process didn't run" msgstr "" #: VideoPreview#5 msgid "No filename" msgstr "" #: VideoPreview#6 msgid "" "The mplayer process didn't start while trying to get info about the video" msgstr "" kylin-video/src/translations/kylin-video_fr.po0000644000175000017500000014642413517016402020533 0ustar fengfeng#, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-10-15 15:13+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Translate Toolkit 1.13.0\n" #: AboutDialog#1 msgid "About" msgstr "Sur" #: AboutDialog#2 msgid "Contributor" msgstr "Donateur" #: AboutDialog#3 msgid "" "\n" "\n" "

<" "br />

" msgstr " \ n


 AboutDialog SobreAbout AboutDialogContribuinte Contributor AboutDialogVdeo Kylin Kylin Video AboutDialogEst bemOK AboutDialog0Mecanismo de reproduo:Playback engine: AboutDialogDUsando Qt% 1 (compilado com Qt% 2)!Using Qt %1 (compiled with Qt %2) AboutDialogVerso 1 Version: %1 AboutDialog$Escolha um arquivo Choose a file ActionsEditorDescrio Description ActionsEditorErroError ActionsEditorNomeName ActionsEditor AtalhoShortcut ActionsEditorAtraso de udio Audio delayAudioDelayDialogFAtraso de udio (em milissegundos):Audio delay (in milliseconds):AudioDelayDialogCancelarCancelAudioDelayDialogEst bemOKAudioDelayDialog&Restabelecer&ResetAudioEqualizerEm formao InformationAudioEqualizerMudoMute BottomWidgetPrximoNext BottomWidgetA pausa Play / Pause BottomWidget&Lista de reproduo Play List BottomWidgetAnteriorPrev BottomWidgetPareStop BottomWidget<Marcador "A " definido para% 1"A" marker set to %1Core@Marcador \ "B " definido para% 1"B" marker set to %1Core,Marcadores AB apagadosA-B markers clearedCoreProporo:% 1Aspect ratio: %1Core,Atraso de udio:% 1 msAudio delay: %1 msCoreBrilho:% 1Brightness: %1CoreCarregando... Buffering...CoreContraste:% 1 Contrast: %1CoreGama:% 1 Gamma: %1CoreMatiz:% 1Hue: %1CorePA roda do mouse muda de velocidade agoraMouse wheel changes speed nowCoreJA roda do mouse altera o volume agoraMouse wheel changes volume nowCoreXA roda do mouse altera o nvel de zoom agora"Mouse wheel changes zoom level nowCore6Roda do mouse procura agoraMouse wheel seeks nowCoreSaturao:% 1Saturation: %1CorehCaptura de tela NO capturada, pasta no configurada+Screenshot NOT taken, folder not configuredCore:Captura de tela salva como% 1Screenshot saved as %1CorefCapturas de tela NO tiradas, pasta no configurada,Screenshots NOT taken, folder not configuredCoreVelocidade:% 1 Speed: %1CoreIniciando... Starting...Core2Atraso de legendas:% 1 msSubtitle delay: %1 msCore(Legendas desativadas Subtitles offCoreLegendas em Subtitles onCoreAtualizando o cache da fonte. Isso pode demorar alguns segundos ...6Updating the font cache. This may take some seconds...CoreVolume 1 Volume: %1CoreZoom:% 1Zoom: %1CoreErroError ErrorDialogOcultar logHide log ErrorDialogErro do MPlayer MPlayer Error ErrorDialogEst bemOK ErrorDialog<Oops, algo de errado aconteceuOops, something wrong happened ErrorDialogMostrar logShow log ErrorDialog coneicon ErrorDialogZPressione ESC para sair do modo de tela cheia"Press ESC to exit full screen modeEscTipTClique para selecionar um arquivo ou pasta Click to select a file or folder FileChooser&Restabelecer&ResetFilePropertiesDialog:& Selecione o codec de udio:&Select the audio codec:FilePropertiesDialogn& Selecione o demuxer que ser usado para este arquivo:4&Select the demuxer that will be used for this file:FilePropertiesDialog:& Selecione o codec de vdeo:&Select the video codec:FilePropertiesDialogApliqueApplyFilePropertiesDialogCodec de udio Audio codecFilePropertiesDialogCancelarCancelFilePropertiesDialogDemuxerDemuxerFilePropertiesDialogEm formao InformationFilePropertiesDialog4Vdeo Kylin - PrefernciasKylin Video - PreferencesFilePropertiesDialogEst bemOKFilePropertiesDialogPropriedades PropertiesFilePropertiesDialogRestabelecerResetFilePropertiesDialogCodec de vdeo Video codecFilePropertiesDialogSocorroHelp HelpDialog&Vdeo Kylin - AjudaKylin Video - Help HelpDialogEst bemOK HelpDialog&Formatos SuportadosSupported formats HelpDialogCancelarCancelInputURLInsira o URL Enter URLInputURLEst bemOKInputURLURL:URL:InputURLAbecsio Abkhazian Languages LongeAfar Languagesafrikaans Afrikaans LanguagesAkanAkan LanguagesalbansAlbanian LanguagesAmricoAmharic Languages rabeArabic Languagesrabe - SriaArabic - Syria LanguagesJanelas rabesArabic Windows LanguagesAragons Aragonese LanguagesArmnioArmenian LanguagesAssamsAssamese Languages AvaricAvaric LanguagesAvestanAvestan Languages AimarAymara LanguagesAzerbaijans Azerbaijani LanguagesblticoBaltic LanguagesBambaraBambara LanguagesBashkirBashkir Languages BascoBasque LanguagesBielorrusso Belarusian LanguagesbengaliBengali Languages BihariBihari LanguagesBislamaBislama Languages BokmlBokmål Languages BsnioBosnian Languages BretoBreton Languagesblgaro Bulgarian LanguagesbirmansBurmese LanguagescataloCatalan LanguagesclticoCeltic LanguagesChamorroChamorro LanguagesChechenoChechen Languages ChiqueChichewa Languages chinsChinese Languages IgrejaChurch LanguagesChuvacheChuvash LanguagesCornishCornish Languages CorsoCorsican LanguagesCreeCree Languages croataCroatian LanguagescirlicoCyrillic Languages"Janelas CirlicasCyrillic Windows Languages ChecoCzech LanguagesdinamarqusDanish Languages DivehiDivehi LanguagesholandsDutch LanguagesDzongkhaDzongkha Languages InglsEnglish Languagesesperanto Esperanto Languages@Esperanto, galego, malts, turco%Esperanto, Galician, Maltese, Turkish LanguagesestonianoEstonian Languages OvelhaEwe Languages FerosFaroese LanguagesFijianoFijian LanguagesfinlandsFinnish LanguagesfrancsFrench Languages FrsioFrisian Languages FulahFulah LanguagesgalicoGaelic Languages GalegoGalician Languages GandaGanda LanguagesGeorgianoGeorgian Languages alemoGerman Languages gregoGreek LanguagesGronelands Greenlandic LanguagesGuaraniGuarani LanguagesGujaratiGujarati LanguageshaitianoHaitian Languages HausaHausa LanguageshebraicoHebrew Languages Charsets hebreusHebrew charsets Languages HereroHerero Languages hindiHindi LanguagesHiriHiri Languageshngaro Hungarian Languagesislands Icelandic LanguagesEu faoIdo LanguagesIgboIgbo Languagesindonsio Indonesian LanguagesInterlngua Interlingua LanguagesInterlingue Interlingue LanguagesInuktitut Inuktitut LanguagesInupiaqInupiaq LanguagesirlandsIrish LanguagesitalianoItalian LanguagesjaponsJapanese Languages$Charutos japonesesJapanese charsets LanguagesJavansJavanese Languages CanarKannada Languages KanuriKanuri LanguagesCaxemiraKashmiri LanguagesCazaqueKazakh Languages KhmerKhmer Languages KikuyuKikuyu LanguagesKinyarwanda Kinyarwanda LanguagesKirghizKirghiz LanguagesKomiKomi Languages KongoKongo LanguagescoreanoKorean LanguagesCharset coreanoKorean charset LanguagesKuanyamaKuanyama Languages curdoKurdish LanguagesLaoLao Languages LatimLatin Languages letoLatvian LanguagesLimburgan Limburgan LanguagesLingalaLingala Languageslituano Lithuanian LanguagesLuba-Katanga Luba-Katanga LanguagesLuxemburgus Luxembourgish LanguagesMacednio Macedonian LanguagesmalgaxeMalagasy Languages malaioMalay LanguagesMalaiala Malayalam Languages maltsMaltese LanguagesManxManx Languages maoriMaori LanguagesMarathiMarathi LanguagesMarshals Marshallese LanguagesGrego moderno Modern Greek Languages.Janelas gregas modernasModern Greek Windows LanguagesMoldavo Moldavian Languages mongol Mongolian Languages NauruNauru Languages NavajoNavajo LanguagesNdebeleNdebele Languages NdongaNdonga LanguagesNepalsNepali Languagesnoruegus Norwegian Languages"Nynorsk noruegusNorwegian Nynorsk LanguagesOccitanoOccitan Languages OjibwaOjibwa Languages2Charset antigo do BlticoOld Baltic charset Languages OriyaOriya Languages OromoOromo LanguagesOsstiaOssetian LanguagesPaliPali LanguagesPanjabiPanjabi Languages persaPersian LanguagespolonsPolish LanguagesPortugus Portuguese LanguagesEmpurre paraPushto LanguagesQuchuaQuechua Languages romenaRomanian LanguagesRomancheRomansh Languages RundiRundi Languages russoRussian LanguagesSamiSami LanguagesSamoanoSamoan Languages SangoSango LanguagessnscritoSanskrit Languages Sardo Sardinian Languages srvioSerbian Languages ShonaShona LanguagesSichuanSichuan Languages6Charset chins simplificadoSimplified Chinese charset Languages SindiSindhi LanguagesCingalsSinhala LanguagesFIdiomas eslavos / da Europa Central!Slavic/Central European Languages LanguagesHJanelas eslavas / europias centraisSlavic/Central European Windows LanguagesEslovacoSlovak LanguagesEslovenoSlovene Languages SomaliSomali LanguagesSotoSotho Languages"Europa do SudesteSouth-Eastern European LanguagesespanholSpanish LanguagesSundans Sundanese Languages SualiSwahili Languages SwatiSwati Languages suecoSwedish Languages TagaloTagalog LanguagesTaitianoTahitian LanguagesTadjiqueTajik Languages TmilTamil Languages TatarTatar Languages TlugoTelugu LanguagestailandsThai Languages"Charset tailands Thai charset LanguagesTibetanoTibetan LanguagesTigrinaTigrinya Languages TongaTonga Languages4Charset chins tradicionalTraditional Chinese charset Languages TsongaTsonga Languages TswanaTswana Languages turcoTurkish LanguagesTurcomanoTurkmen LanguagesTwiTwi Languages UTF-8UTF-8 Languages UigurUighur Languagesucraniano Ukrainian Languages,Ucraniano, bielorrussoUkrainian, Belarusian LanguagesUnicodeUnicode LanguagesurduUrdu LanguagesUzbequeUzbek Languages VendaVenda Languagesvietnamita Vietnamese LanguagesVolapuqueVolapük Languages valoWalloon Languages galsWelsh Languages6Idiomas da Europa OcidentalWestern European Languages LanguagesHLnguas da Europa Ocidental com Euro$Western European Languages with Euro Languages UlofeWolof Languages XhosaXhosa LanguagesIdicheYiddish Languages IorubaYoruba Languages ZhuangZhuang LanguageszuluZulu LanguagesmudanaChangeLineEditWithIconNo filtro '% 1' no suportado pelo mpv'the '%1' filter is not supported by mpv MPVProcess% 1 erro%1 Error MainWindow,% 1 falhou ao iniciar.%1 failed to start. MainWindow% 1 caiu.%1 has crashed. MainWindow:% 1 terminou inesperadamente.%1 has finished unexpectedly. MainWindow& 4.0 Surround &4.0 Surround MainWindow& 5.1 Surround &5.1 Surround MainWindow& 6.1 Surround &6.1 Surround MainWindow& 7.1 Surround &7.1 Surround MainWindow&Sempre&Always MainWindow &Auto&Auto MainWindowE canais &Channels MainWindow &Claro&Clear MainWindow&Desativado &Disabled MainWindow&Pule para... &Jump to... MainWindow&Pule para: &Jump to: MainWindow E canal esquerdo &Left channel MainWindow &Mono&Mono MainWindow &Mudo&Mute MainWindow &Nunca&Never MainWindow &Fora&Off MainWindowCanal direito&Right channel MainWindowE girar&Rotate MainWindowx& Rodar 90 graus no sentido dos ponteiros do relgio e virar(&Rotate by 90 degrees clockwise and flip MainWindowCaptura de tela &Screenshot MainWindow&Estreo&Stereo MainWindowE modo estreo &Stereo mode MainWindow& URL ...&URL... MainWindow2'% 1' no foi encontrado!'%1' was not found! MainWindow+% 1+%1 MainWindow-% 1-%1 MainWindow<vazio> MainWindow*Sobre o & Kylin VideoAbout &Kylin Video MainWindow"Todos os arquivos All files MainWindow"Proporo da tela Aspect ratio MainWindow AudioAudio MainWindow(Escolha um diretrioChoose a directory MainWindow$Escolha um arquivo Choose a file MainWindowBConfirme a excluso - Kylin VideoConfirm deletion - Kylin Video MainWindowAtraso +Delay + MainWindowAtraso -Delay - MainWindowJExcluir a lista de arquivos recentes? Delete the list of recent files? MainWindowDiretrio... Directory... MainWindow Velocidade dupla Double speed MainWindowErro detectadoError detected MainWindow&Cdigo de sada:% 1 Exit code: %1 MainWindowImagem Fli & p Fli&p image MainWindow(Avanar e retrocederForward and rewind MainWindow"Rotao do quadroFrame rotation MainWindowTela cheia Fullscreen MainWindowMeia velocidade Half speed MainWindowSocorroHelp MainWindowEm formao Information MainWindowIr para% 1 Jump to %1 MainWindowVdeo Kylin Kylin Video MainWindow,Vdeo de Kylin - buscaKylin Video - Seek MainWindow@Vdeo Kylin - Atraso de legendasKylin Video - Subtitle delay MainWindow&Listar jogo de loopList loop play MainWindowCarga...Load... MainWindow Mirr e ou imagem Mirr&or image MainWindowMultimdia Multimedia MainWindowPrximoNext MainWindow"Velocidade normal Normal speed MainWindow AbrirOpen MainWindow Abrir arquivo... Open &File... MainWindowHomepage Aberta Open Homepage MainWindow0Abra a pasta screenshotsOpen screenshots folder MainWindowPea de ordem Order play MainWindow$Velocidade de jogo Play Speed MainWindow,Controle de reproduo Play control MainWindowOrdem de jogo Play order MainWindow&Lista de reproduoPlayList MainWindow(Listas de reproduo Playlists MainWindowfPor favor, verifique o caminho% 1 nas preferncias.(Please check the %1 path in preferences. MainWindowPreferncias Preferences MainWindowAnteriorPrevious MainWindowSairQuit MainWindow Jogada aleatria Random play MainWindowMarcha rRe&verse MainWindow"Arquivos recentes Recent files MainWindowFRodar 90 graus e no sentido horrioRotate by 90 degrees &clockwise MainWindow`Gire em 90 graus no sentido anti-horrio e sbio&Rotate by 90 degrees counterclock&wise MainWindow\Gire 90 graus no sentido anti-horrio e & flip/Rotate by 90 degrees counterclockwise and &flip MainWindowFique no topo S&tay on top MainWindowBVeja o log para mais informaes.See the log for more info. MainWindow Definir dela ... Set dela&y... MainWindowVelocidade + 1% Speed +1% MainWindow Velocidade + 10% Speed +10% MainWindowVelocidade + 4% Speed +4% MainWindowVelocidade -1% Speed -1% MainWindowVelocidade -10% Speed -10% MainWindow"Velocidade de -4% Speed -4% MainWindowPareStop MainWindow,Legenda e visibilidadeSubtitle &visibility MainWindowLAtraso de legendas (em milissegundos):!Subtitle delay (in milliseconds): MainWindowLegendas Subtitles MainWindowDA pasta de screenshots no existe!%The screenshot folder does not exist! MainWindow2O servidor retornou '% 1'The server returned '%1' MainWindowbInfelizmente este vdeo no pode ser reproduzido.)Unfortunately this video can't be played. MainWindow VdeoVideo MainWindowfOs filtros de vdeo so desativados ao usar o vdpau+Video filters are disabled when using vdpau MainWindowHVer e informaes e propriedades ...View &info and properties... MainWindowVolume +Volume + MainWindowVolume -Volume - MainWindow Enquanto jogandoWhile &playing MainWindowCancelarCancel MessageDialogNoNo MessageDialogEst bemOk MessageDialogsimYes MessageDialogNEsta opo no suportada pelo MPlayer'This option is not supported by MPlayerMplayerProcess4& Excluir arquivo do disco&Delete file from disk PlayListView ToquePlay PlayListView*Remover e selecionadoRemove &selected PlayListViewAdicionarAddPlaylist$Adicionar ficheiroAdd FilePlaylist"Todos os arquivos All filesPlaylistHTem certeza de que deseja continuar?!Are you sure you want to proceed?Playlist(Escolha um diretrioChoose a directoryPlaylist ClaroClearPlaylist&Confirme a exclusoConfirm deletionPlaylist Confirme removerConfirm removePlaylistMultimdia MultimediaPlaylist&Lista de reproduoPlayListPlaylist@A lista de reproduo est vaziaPlaylist is emptyPlaylist(Listas de reproduo PlaylistsPlaylist6Atingiu o final da playlistReached the end of the playlistPlaylistPSelecione um ou mais arquivos para abrir Select one or more files to openPlaylistEssa ao no pode ser desfeita. Tem certeza de que deseja continuar??This action cannot be undone. Are you sure you want to proceed?PlaylistCancelarCancelPoweroffDialogEst bemOkPoweroffDialog% 1 o recomendado. Tente evitar% 2 e% 3, eles so lentos e podem ter um impacto no desempenho.g%1 is the recommended one. Try to avoid %2 and %3, they are slow and can have an impact on performance. PrefAudio2 (estreo) 2 (Stereo) PrefAudio 4 (4,0 Surround)4 (4.0 Surround) PrefAudio 6 (5.1 Surround)6 (5.1 Surround) PrefAudio 7 (6.1 Surround)7 (6.1 Surround) PrefAudio 8 (7.1 Surround)8 (7.1 Surround) PrefAudio0Driver de sada de udioAudio output driver PrefAudioRSincronizao automtica de udio / vdeo Audio/video auto synchronization PrefAudio"Canais por padroChannels by default PrefAudio$Canais por padro:Channels by default: PrefAudioMarque esta opo para usar o mixer de software, em vez de usar o mixer da placa de som.SCheck this option to use the software mixer, instead of using the sound card mixer. PrefAudio PadroDefault PrefAudio Fator:Factor: PrefAudioVolume global Global volume PrefAudioGradualmente, ajusta a sincronizao A / V com base nas medies de atraso de udio.AGradually adjusts the A/V sync based on audio delay measurements. PrefAudioRSe esta opo estiver marcada, o mesmo volume ser usado para todos os arquivos que voc reproduzir. Se a opo no estiver marcada, cada arquivo usa seu prprio volume.If this option is checked, the same volume will be used for all files you play. If the option is not checked each file uses its own volume. PrefAudio"Max. AmplificaoMax. Amplification PrefAudio$Max. Amplificao:Max. Amplification: PrefAudioLMaximiza o volume sem distorcer o som.2Maximizes the volume without distorting the sound. PrefAudio Driver de sada:Output driver: PrefAudioSolicita o nmero de canais de reproduo. O MPlayer pede ao decodificador para decodificar o udio em quantos canais forem especificados. Ento cabe ao decodificador cumprir o requisito. Isso geralmente importante apenas ao reproduzir vdeos com udio AC3 (como DVDs). Nesse caso, a liba52 faz a decodificao por padro e ajusta corretamente o udio para o nmero solicitado de canais. <b> Nota </ b>: Esta opo respeitada por codecs (somente AC3), filtros (surround) e drivers de sada de udio (OSS pelo menos).Requests the number of playback channels. MPlayer asks the decoder to decode the audio into as many channels as specified. Then it is up to the decoder to fulfill the requirement. This is usually only important when playing videos with AC3 audio (like DVDs). In that case liba52 does the decoding by default and correctly downmixes the audio into the requested number of channels. Note: This option is honored by codecs (AC3 only), filters (surround) and audio output drivers (OSS at least). PrefAudioJSelecione o driver de sada de udio.Select the audio output driver. PrefAudio&Define o nvel mximo de amplificao em porcentagem (padro: 110). Um valor de 200 permitir ajustar o volume at o dobro do nvel atual. Com valores abaixo de 100, o volume inicial (que 100%) estar acima do mximo, o que, por exemplo, o OSD no pode exibir corretamente. Sets the maximum amplification level in percent (default: 110). A value of 200 will allow you to adjust the volume up to a maximum of double the current level. With values below 100 the initial volume (which is 100%) will be above the maximum, which e.g. the OSD cannot display correctly. PrefAudio<Controle de volume de softwareSoftware volume control PrefAudioSincronizaoSynchronization PrefAudio`Esta opo tambm se aplica ao controle de mudo..This option also applies for the mute control. PrefAudioHUse o controle de volume de softwareUse software volume control PrefAudio VolumeVolume PrefAudioBNormalizao de volume por padroVolume normalization by default PrefAudio2Se esta opo estiver ativada, o arquivo ser pausado quando a janela principal estiver oculta. Quando a janela restaurada, a reproduo ser retomada.If this option is enabled, the file will be paused when the main window is hidden. When the window is restored, playback will be resumed. PrefGeneralSe esta opo estiver ativada, a visualizao do vdeo ser exibida quando o mouse for colocado na barra de progresso.lIf this option is enabled, the video preview will be displayed when the mouse is placed on the progress bar. PrefGeneralSe voc alterar o mecanismo de reproduo para MPV, reinicie o Kylin Video.EIf you change the playback engine to MPV, please restart Kylin Video. PrefGeneralSe voc alterar o mecanismo de reproduo para o MPlayer, reinicie o Kylin Video.IIf you change the playback engine to MPlayer, please restart Kylin Video. PrefGeneralMPVMPV PrefGeneralMPlayerMPlayer PrefGeneral.Pausa quando minimizadoPause when minimized PrefGeneral0Mecanismo de reproduo:Playback engine: PrefGeneral`Visualizar quando o vdeo est sendo reproduzido!Preview when the video is playing PrefGeneral`Visualizar quando o vdeo est sendo reproduzidoPreview when video is playing PrefGeneralTSelecione MPV como mecanismo de reproduoSelect MPV as playback engine PrefGeneral`Selecione o MPlayer como mecanismo de reproduo!Select MPlayer as playback engine PrefGeneralAutoAutoPrefPerformanceAutomtico: ele tenta ativar automaticamente a decodificao de hardware usando o primeiro mtodo disponvel.ZAuto: it tries to automatically enable hardware decoding using the first available method.PrefPerformance&Opes disponveis:Available options:PrefPerformance CacheCachePrefPerformance&Cache para arquivosCache for filesPrefPerformance6Cache para arquivos locais:Cache for local files:PrefPerformance"Cache para fluxosCache for streamsPrefPerformance$Cache para fluxos:Cache for streams:PrefPerformanceDecodificarDecodePrefPerformance2Decodificao de hardwareHardware decodingPrefPerformanceKBKBPrefPerformance NenhumNonePrefPerformancenNenhum: somente a decodificao de software ser usada.*None: only software decoding will be used.PrefPerformanceatuao PerformancePrefPerformanceDefine a API de decodificao de vdeo de hardware. Se a decodificao de hardware no for possvel, a decodificao de software ser usada.sSets the hardware video decoding API. If hardware decoding is not possible, software decoding will be used instead.PrefPerformanceDefine o nmero de segmentos a serem usados para decodificao. Apenas para MPEG-1/2 e H.264KSets the number of threads to use for decoding. Only for MPEG-1/2 and H.264PrefPerformanceBEsta opo s funciona com o mpv. This option only works with mpv.PrefPerformanceEsta opo especifica a quantidade de memria (em kBytes) a ser usada ao preceder um URL.OThis option specifies how much memory (in kBytes) to use when precaching a URL.PrefPerformanceEsta opo especifica a quantidade de memria (em kBytes) a ser usada ao precazer um arquivo.PThis option specifies how much memory (in kBytes) to use when precaching a file.PrefPerformance4Tpicos para decodificaoThreads for decodingPrefPerformancelThreads para decodificao (somente MPEG-1/2 e H.264):/Threads for decoding (MPEG-1/2 and H.264 only):PrefPerformancevaapi-copy: copia o vdeo de volta para a RAM do sistema. Apenas para GPUs Intel.Fvaapi-copy: it copies video back into system RAM. For Intel GPUs only.PrefPerformancevaapi: para as sadas de vdeo opengl e vaapi. Apenas para GPUs Intel.Cvaapi: for the opengl and vaapi video outputs. For Intel GPUs only.PrefPerformance\vdpau: para as sadas de vdeo vdpau e opengl..vdpau: for the vdpau and opengl video outputs.PrefPerformance% 1 especifica o nome do arquivo do vdeo sem a extenso,% 2 adiciona um nmero de 4 dgitos preenchido com zeros.i%1 specifies the filename of the video without the extension, %2 adds a 4 digit number padded with zeros.PrefScreenShot.Ativar capturas de telaEnable screenshotsPrefScreenShot Pasta:Folder:PrefScreenShotPara obter uma lista completa dos especificadores de modelo, acesse este link:;For a full list of the template specifiers visit this link:PrefScreenShotPor exemplo,% 1 salvaria a captura de tela como 'moviename_0001.png'.AFor example %1 would save the screenshot as 'moviename_0001.png'.PrefScreenShot:Formato para capturas de telaFormat for screenshotsPrefScreenShotFormato:Format:PrefScreenShotXAqui voc pode especificar uma pasta onde as imagens capturadas pelo Kylin Video sero armazenadas. Se a pasta no for vlida, o recurso de captura de tela ser desativado.Here you can specify a folder where the screenshots taken by Kylin Video will be stored. If the folder is not valid the screenshot feature will be disabled.PrefScreenShotScreenshots ScreenshotsPrefScreenShot Pasta de imagensScreenshots folderPrefScreenShot,Selecione um diretrioSelect a directoryPrefScreenShot8Modelo para capturas de telaTemplate for screenshotsPrefScreenShotModelo: Template:PrefScreenShotEsta opo permite escolher o tipo de arquivo de imagem usado para salvar capturas de tela.QThis option allows one to choose the image file type used for saving screenshots.PrefScreenShotBEsta opo s funciona com o mpv. This option only works with mpv.PrefScreenShotEsta opo especifica o modelo de nome de arquivo usado para salvar capturas de tela.EThis option specifies the filename template used to save screenshots.PrefScreenShotVoc pode usar essa opo para ativar ou desativar a possibilidade de fazer capturas de tela.QYou can use this option to enable or disable the possibility to take screenshots.PrefScreenShotAqui voc pode alterar qualquer atalho chave. Para fazer isso, clique duas vezes ou pressione enter sobre uma clula de atalho. aHere you can change any key shortcut. To do it double click or press enter over a shortcut cell.  PrefShortCutAqui voc pode alterar qualquer atalho chave. Para fazer isso, clique duas vezes ou comece a digitar em uma clula de atalho.aHere you can change any key shortcut. To do it double click or start typing over a shortcut cell. PrefShortCut AtalhoShortCut PrefShortCutTecla de atalho Shortcut Key PrefShortCut"Editor de atalhosShortcut editor PrefShortCutLEsta tabela permite que voc altere os atalhos de teclas da maioria das aes disponveis. Clique duas vezes ou pressione enter em um item, ou pressione o boto <b> Alterar atalho </ b> para entrar no dilogo <i> Modificar atalho </ i>. H duas maneiras de alterar um atalho: se o boto <b> Capturar </ b> estiver ativado, pressione a nova tecla ou a combinao de teclas que deseja atribuir ao (infelizmente isso no funciona para todas as teclas ). Se o boto <b> Capturar </ b> estiver desativado, voc poder digitar o nome completo da chave.This table allows you to change the key shortcuts of most available actions. Double click or press enter on a item, or press the Change shortcut button to enter in the Modify shortcut dialog. There are two ways to change a shortcut: if the Capture button is on then just press the new key or combination of keys that you want to assign for the action (unfortunately this doesn't work for all keys). If the Capture button is off then you could enter the full name of the key. PrefShortCutHTodos os subs contendo nome do filmeAll subs containing movie name PrefSubtitles4Todos os subs no diretrioAll subs in directory PrefSubtitles.Carregamento AutomticoAutoload PrefSubtitlesCarregar automaticamente arquivos de legendas (* .srt, * .sub ...):+Autoload subtitles files (*.srt, *.sub...): PrefSubtitles<Codificao de legendas padroDefault subtitle encoding PrefSubtitles>Codificao de legendas padro:Default subtitle encoding: PrefSubtitlesCodificaoEncoding PrefSubtitles FonteFont PrefSubtitles&Mesmo nome do filmeSame name as movie PrefSubtitlesSelecione a codificao que ser usada para arquivos de legenda por padro.ESelect the encoding which will be used for subtitle files by default. PrefSubtitlesSelecione o idioma para o qual voc deseja que a codificao seja adivinhada automaticamente.PSelect the language for which you want the encoding to be guessed automatically. PrefSubtitlestSelecione o mtodo de carregamento automtico de legendas.$Select the subtitle autoload method. PrefSubtitles"Idioma da legendaSubtitle language PrefSubtitlesLegendas Subtitles PrefSubtitlesFTente autodetectar para este idioma#Try to autodetect for this language PrefSubtitlesNTente se autodetectar para este idioma:$Try to autodetect for this language: PrefSubtitles Quando esta opo estiver ativada, a codificao das legendas ser tentada para ser detectada automaticamente para o idioma especificado. Ele retornar codificao padro se a deteco automtica falhar. Esta opo requer um MPlayer compilado com suporte ENCA.When this option is on, the encoding of the subtitles will be tried to be autodetected for the given language. It will fall back to the default encoding if the autodetection fails. This option requires a MPlayer compiled with ENCA support. PrefSubtitles PadroDefault PrefVideo&Renderizao diretaDirect rendering PrefVideo Double bufferingDouble buffering PrefVideoCorrees de buffer duplo piscam armazenando dois quadros na memria e exibindo um enquanto decodifica outro. Se desativado, pode afetar o OSD negativamente, mas muitas vezes remove a oscilao do OSD.Double buffering fixes flicker by storing two frames in memory, and displaying one while decoding another. If disabled it can affect OSD negatively, but often removes OSD flickering. PrefVideo8Desenhe vdeos usando fatiasDraw video using slices PrefVideoJAtivar o ps-processamento por padro Enable postprocessing by default PrefVideoPAtivar / desativar o desenho de vdeo por fatias / bandas de altura de 16 pixels. Se desativado, o quadro inteiro desenhado em uma nica execuo. Pode ser mais rpido ou mais lento, dependendo da placa de vdeo e do cache disponvel. Ele tem efeito somente com os codecs libmpeg2 e libavcodec.Enable/disable drawing video by 16-pixel height slices/bands. If disabled, the whole frame is drawn in a single run. May be faster or slower, depending on video card and available cache. It has effect only with libmpeg2 and libavcodec codecs. PrefVideo.Se marcado, ativa a renderizao direta (no suportada por todos os codecs e sadas de vdeo) <br> <b> Aviso: </ b> Pode causar corrupo de OSD / SUB!If checked, turns on direct rendering (not supported by all codecs and video outputs)
Warning: May cause OSD/SUB corruption! PrefVideo Driver de sada:Output driver: PrefVideoO ps-processamento ser usado por padro em novos arquivos abertos.;Postprocessing will be used by default on new opened files. PrefVideoSelecione o driver de sada de vdeo. % 1 fornece o melhor desempenho.ASelect the video output driver. %1 provides the best performance. PrefVideo@Equalizador de vdeo de softwareSoftware video equalizer PrefVideoNUse o equalizador de vdeo por softwareUse software video equalizer PrefVideo0Driver de sada de vdeoVideo output driver PrefVideoVoc pode marcar esta opo se o equalizador de vdeo no for suportado pela placa grfica ou pelo driver de sada de vdeo selecionado. <br> <b> Observao: </ b> essa opo pode ser incompatvel com alguns drivers de sada de vdeo.You can check this option if video equalizer is not supported by your graphic card or the selected video output driver.
Note: this option can be incompatible with some video output drivers. PrefVideo lentoslow PrefVideoApliqueApplyPreferencesDialog AudioAudioPreferencesDialogCancelarCancelPreferencesDialog GeralGeneralPreferencesDialog4Vdeo Kylin - PrefernciasKylin Video - PreferencesPreferencesDialogEst bemOKPreferencesDialogatuao PerformancePreferencesDialogPreferncia PreferencePreferencesDialogScreenShot ScreenShotPreferencesDialogTecla de atalho Shortcut KeyPreferencesDialogLegendas SubtitlesPreferencesDialog VdeoVideoPreferencesDialog% 1 e% 2 %1 and %2QObject  %n minute(s)QObject  %n second(s)QObjectTEste o Kylin Vedio v.% 1 executado em% 2'This is Kylin Vedio v. %1 running on %2QObjectautoautoQObjectDesativadodisabledQObjectdesconhecidounknownQObject Adicionar atalho Add shortcutShortcutGetterCancelarCancelShortcutGetterCapturarCaptureShortcutGetter6Capture as teclas digitadasCapture keystrokesShortcutGetter ClaroClearShortcutGetter Modificar atalhoModify shortcutShortcutGetterEst bemOKShortcutGetterrPressione a combinao de teclas que voc deseja atribuir,Press the key combination you want to assignShortcutGetterRemover atalhoRemove shortcutShortcutGetter"Formatos de udio Audio formatsSupportFormatsAlguns formatos de vdeo no suportam a visualizao e buscam arrastando, por exemplo, o swf.MSome video formats do not support preview and seek by dragging, e.g. the swf.SupportFormats(Formatos de legendasSubtitles formatsSupportFormats"Formatos de vdeo Video formatsSupportFormatsCancelarCancel TimeDialogPule para:Jump to: TimeDialogEst bemOK TimeDialogProcurarSeek TimeDialogVdeo Kylin Kylin Video TitleWidgetAutoAuto TristateComboNoNo TristateCombosimYes TristateCombo,Nenhum nome de arquivo No filename VideoPreview.O arquivo% 1 no existeThe file %1 doesn't exist VideoPreview4O comprimento do vdeo 0The length of the video is 0 VideoPreviewNO processo do mplayer no foi executadoThe mplayer process didn't run VideoPreviewO processo do mplayer no comeou ao tentar obter informaes sobre o vdeoIThe mplayer process didn't start while trying to get info about the video VideoPreview`O diretrio temporrio (% 1) no pode ser criado-The temporary directory (%1) can't be created VideoPreviewkylin-video/src/translations/kylin-video_ru.ts0000644000175000017500000037205713625147453020600 0ustar fengfeng AboutDialog About Около Contributor участник <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> <! DOCTYPE HTML PUBLIC \ "- // W3C // DTD HTML 4.0 // EN " \ "http: //www.w3.org/TR/REC-html40/strict.dtd "> \ n <html> <head> <meta name = \ "qrichtext " content = \ "1 " /> <style type = \ "text / css "> \ np, li {white-space: pre-wrap; } \ n </ style> </ head> <body style = \ "font-family: 'Ubuntu'; font-size: 11pt; font-weight: 400; font-style: normal; "> \ n <p style = \ "- qt-paragraph-type: empty; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px; \ "> <br /> </ p> </ body> </ html> OK Хорошо Kylin Video is developed on the basis of SMPlayer, is a graphical interface for MPlayer and MPV. Kylin Video разработан на базе SMPlayer, представляет собой графический интерфейс для MPlayer и MPV. Kylin Video Kylin Video Version: %1 Версия:% 1 Using Qt %1 (compiled with Qt %2) Используя Qt% 1 (скомпилированный с Qt% 2) Playback engine: Механизм воспроизведения: Kylin Video is developed on the basis of %1, is a graphical interface for %2 and %3. Links: Code website: Developer's personal home page: ActionsEditor Shortcut кратчайший путь Description Описание Name название Choose a filename Key files Confirm overwrite? The file %1 already exists. Do you want to overwrite? Error ошибка The file couldn't be saved Choose a file Выберите файл The file couldn't be loaded AudioDelayDialog Audio delay Задержка звука OK Хорошо Cancel отменить Audio delay (in milliseconds): Задержка звука (в миллисекундах): AudioEqualizer Audio Equalizer %1 Hz %1 kHz &Preset &Apply &Reset &Сброс &Set as default values &Close Flat Classical Club Dance Full bass Full bass and treble Full treble Headphones Large hall Live Party Pop Reggae Rock Ska Soft Soft rock Techno Custom Use the current values as default values for new videos. Set all controls to zero. Information Информация The current values have been stored to be used as default. BaseGui Kylin Video Kylin Video Open открыто Open &File... Открыть файл... Directory... Справочник ... &URL... & URL ... &Clear &Очистить Recent files Недавние файлы Play control Управление воспроизведением Forward and rewind Перемотка вперед и назад &Jump to... &Прыгать, чтобы... Play Speed Скорость воспроизведения Normal speed Нормальная скорость Half speed Половина скорости Double speed Двойная скорость Speed -10% Скорость -10% Speed +10% Скорость + 10% Speed -4% Скорость -4% Speed +4% Скорость + 4% Speed -1% Скорость -1% Speed +1% Скорость + 1% Next следующий Previous предыдущий &Auto &Авто &Disabled &Инвалид Aspect ratio Соотношение сторон &Off & Off &Rotate by 90 degrees clockwise and flip & Повернуть на 90 градусов по часовой стрелке и перевернуть Rotate by 90 degrees &clockwise Повернуть на 90 градусов и по часовой стрелке Rotate by 90 degrees counterclock&wise Поворот на 90 градусов против часовой стрелки и мудрый Rotate by 90 degrees counterclockwise and &flip Поверните на 90 градусов против часовой стрелки и переверните Fli&p image Fli & p image Mirr&or image Зеркальное изображение Frame rotation Вращение рамы &Rotate & Rotate &Screenshot &Скриншот &Always &Всегда &Never &Никогда While &playing Во время игры S&tay on top S & tay сверху Order play Заказать игру Random play Случайная игра List loop play Список воспроизведения в цикле Play order Порядок воспроизведения &Stereo &Стерео &4.0 Surround & 4.0 Surround &5.1 Surround & 5.1 Surround &6.1 Surround & 6.1 Surround &7.1 Surround & 7.1 Surround &Channels &Каналы Audio аудио &Mute & Mute Volume - Объем - Volume + Объем + Delay - Задержка - Delay + Задержка + Set dela&y... Установить dela & y ... &Left channel & Левый канал &Right channel & Правый канал &Mono &Моно Re&verse Задний ход &Stereo mode & Стерео режим Subtitles Субтитры Load... Загрузить ... Subtitle &visibility Субтитры и видимость Preferences предпочтения View &info and properties... Просмотр и информация и свойства ... Help Помогите About &Kylin Video О компании & Kylin Video Quit Уволиться Open Homepage Открыть домашнюю страницу Open screenshots folder Открыть папку скриншотов PlayList PlayList Play/Pause Воспроизведение / Пауза Stop Стоп Fullscreen Полноэкранный Video filters are disabled when using vdpau Видеоэффекты отключены при использовании vdpau -%1 - 1% +%1 + 1% <empty> <Пусто> Confirm deletion - Kylin Video Подтвердить удаление - Kylin Video Delete the list of recent files? Удалить список последних файлов? Choose a file Выберите файл Multimedia мультимедиа Video видео Playlists Плейлисты All files Все файлы Choose a directory Выберите каталог &Jump to: &Прыгать, чтобы: Kylin Video - Seek Kylin Video - Ищите Kylin Video - Subtitle delay Kylin Video - Задержка субтитров Subtitle delay (in milliseconds): Задержка субтитров (в миллисекундах): Error detected Обнаружена ошибка Unfortunately this video can't be played. К сожалению, это видео невозможно воспроизвести. The server returned '%1' Сервер вернул '% 1' Jump to %1 Перейти к% 1 %1 Error % 1 Ошибка '%1' was not found! «% 1» не найден! %1 has finished unexpectedly. % 1 закончил неожиданно. Exit code: %1 Код выхода:% 1 %1 failed to start. % 1 не удалось запустить. Please check the %1 path in preferences. Проверьте путь% 1 в настройках. %1 has crashed. % 1 разбился. See the log for more info. См. Журнал для получения дополнительной информации. Information Информация The screenshot folder does not exist! Папки для скриншотов не существует! BottomWidget Stop Стоп Prev Предыдущая Play / Pause Воспроизвести / Пауза Next следующий Mute безгласный Play List Список воспроизведения Core Screenshot NOT taken, folder not configured Снимок экрана не сделан, папка не настроена Screenshots NOT taken, folder not configured Скриншоты НЕ приняты, папка не настроена "A" marker set to %1 Маркер «А» установлен на% 1 "B" marker set to %1 Маркер «B» установлен в% 1 A-B markers cleared Маркеры AB очищены Brightness: %1 Яркость:% 1 Contrast: %1 Контраст:% 1 Gamma: %1 Гамма:% 1 Hue: %1 Оттенок:% 1 Saturation: %1 Насыщенность:% 1 Speed: %1 Скорость:% 1 Volume: %1 Объем:% 1 Subtitle delay: %1 ms Задержка субтитров:% 1 мс Audio delay: %1 ms Задержка звука:% 1 мс Subtitles on Субтитры на Subtitles off Субтитры отключены Aspect ratio: %1 Соотношение сторон:% 1 Mouse wheel seeks now Колесо мыши теперь ищет Mouse wheel changes volume now Теперь колесо мыши меняет громкость Mouse wheel changes zoom level now Колесо мыши меняет масштаб Mouse wheel changes speed now Теперь колесо мыши меняет скорость Zoom: %1 Масштаб:% 1 Screenshot saved as %1 Снимок экрана, сохраненный как% 1 Updating the font cache. This may take some seconds... Обновление кеша шрифтов. Это может занять несколько секунд ... Buffering... Буферизация ... Starting... Начиная с ... Font scale: %1 ErrorDialog MPlayer Error Ошибка MPlayer OK Хорошо icon значок Oops, something wrong happened Ой, что-то не так случилось Error ошибка Show log Показать журнал Hide log Скрыть журнал EscTip Press ESC to exit full screen mode Нажмите ESC для выхода из полноэкранного режима FileChooser Click to select a file or folder Нажмите, чтобы выбрать файл или папку FilePropertiesDialog Kylin Video - Preferences Kylin Video - Настройки Properties свойства &Select the demuxer that will be used for this file: & Выберите демультиплекс, который будет использоваться для этого файла: &Reset &Сброс &Select the video codec: & Выберите видеокодек: &Select the audio codec: & Выберите аудиокодек: Reset Сброс Apply Применять OK Хорошо Cancel отменить Information Информация Demuxer Demuxer Video codec Видео кодек Audio codec Аудиокодек GlobalShortcutsDialog Media &Play Media &Stop Media Pre&vious Media &Next Media P&ause Media &Record Volume &Mute Volume &Down Volume &Up Global Shortcuts Select the multimedia keys that kylin-video will capture. HelpDialog Kylin Video - Help Kylin Video - Помощь Help Помогите OK Хорошо Supported formats Поддерживаемые форматы InputURL Enter URL Введите URL-адрес OK Хорошо Cancel отменить URL: URL: Languages Afar издалека Abkhazian абхазская Avestan Avestan Afrikaans африкаанс Akan Акан Amharic амхарский Aragonese арагонский Arabic арабский Assamese Ассамский Avaric аварский Aymara аймара Azerbaijani азербайджанец Bashkir башкирский Belarusian Белорусский Bulgarian болгарский Bihari Бихари Bislama Бислама Bambara Bambara Bengali бенгальский Tibetan тибетский Breton бретонский Bosnian боснийский Catalan каталонский Chechen чеченец Corsican корсиканец Cree Cree Czech чешский язык Church церковь Chuvash чувашский Welsh валлийский Danish датский German Немецкий Divehi мальдивский Dzongkha Dzongkha Ewe овца Greek греческий English английский Esperanto эсперанто Spanish испанский Estonian эстонский Basque баскский Persian персидский Fulah фулах Finnish финский Fijian Fijian Faroese Фарерская French Французский Frisian фризский Irish ирландский Gaelic гаэльский Galician Галицкая Guarani Гуарани Gujarati гуджарати Manx с острова Мэн Hausa хауса Hebrew иврит Hindi хинди Hiri Hiri Croatian хорватский Haitian гаитянский Hungarian Венгерский Armenian армянин Herero гереро Chamorro Чаморро Interlingua Интерлингва Indonesian индонезийский Interlingue Интерлингве Igbo Игбо Sichuan Сычуань Inupiaq Инупиак Ido Я делаю Icelandic исландский Italian итальянский Inuktitut Inuktitut Japanese японский язык Javanese яванский Georgian грузинский Kongo Kongo Kikuyu кикуйю Kuanyama Kuanyama Kazakh казах Greenlandic гренландский Khmer кхмерский Kannada каннада Korean корейский язык Kanuri канури Kashmiri Kashmiri Kurdish курдский Komi Коми Cornish корнуоллский Kirghiz киргизы Latin латынь Luxembourgish люксембургский Ganda Ganda Limburgan Limburgan Lingala Lingala Lao Лао Lithuanian Литовский язык Luba-Katanga Luba-Катанга Latvian Латышский Malagasy малагасиец Marshallese Marshallese Maori маори Macedonian македонский Malayalam Malayalam Mongolian монгольский Moldavian молдаванин Marathi маратхи Malay малайский Maltese мальтийский Burmese бирманский Nauru Науру Bokmål букмол Ndebele Ndebele Nepali непальский Ndonga Ndonga Dutch Голландский Norwegian Nynorsk Норвежский нюнорск Norwegian норвежский язык Navajo навахо Chichewa Chichewa Occitan Occitan Ojibwa оджибва Oromo ор Oriya Ория Ossetian осетинский Panjabi Panjabi Pali пали Polish польский Pushto пушту Portuguese португальский Quechua кечуа Romansh ретороманский диалект Rundi Рунди Romanian румынский Russian русский Kinyarwanda киньяруанда Sanskrit санскрит Sardinian сардинец Sindhi Sindhi Sami Сами Sango Санго Sinhala Sinhala Slovak словацкий Slovene словенец Samoan Samoan Shona Shona Somali сомалийский Albanian албанский Serbian сербский Swati Свати Sotho сото Sundanese Суданский Swedish шведский Swahili суахили Tamil тамильский Telugu телугу Tajik таджикский Thai тайский Tigrinya тигринья Turkmen туркменский Tagalog тагальского Tswana Tswana Tonga Тонга Turkish турецкий Tsonga Тсонга Tatar татарин Twi Twi Tahitian Tahitian Uighur Уйгурский Ukrainian украинец Urdu урду Uzbek узбек Venda Венда Vietnamese вьетнамский Volapük Volapük Walloon валлонский Wolof Волоф Xhosa Кос Yiddish идиш Yoruba йоруба Zhuang Чжуан Chinese китайский язык Zulu зулус Arabic - Syria Арабский - Сирия Unicode Unicode UTF-8 UTF-8, Western European Languages Западноевропейские языки Western European Languages with Euro Западноевропейские языки с евро Slavic/Central European Languages Славянские / центральноевропейские языки Esperanto, Galician, Maltese, Turkish Эсперанто, Галисийский, Мальтийский, Турецкий Old Baltic charset Старая балтийская кодировка Cyrillic кириллица Modern Greek Современный греческий Baltic балтийский Celtic кельтский South-Eastern European Юго-Восточная Европа Hebrew charsets Ивритские кодировки Ukrainian, Belarusian Украинский, белорусский Simplified Chinese charset Упрощенная китайская кодировка Traditional Chinese charset Традиционная китайская кодировка Japanese charsets Японские кодировки Korean charset Корейская кодировка Thai charset Тайская кодировка Cyrillic Windows Кириллические окна Slavic/Central European Windows Славянские / центральноевропейские окна Arabic Windows Арабские Windows Modern Greek Windows Современные греческие окна LineEditWithIcon Change + Изменить MPVProcess the '%1' filter is not supported by mpv фильтр «% 1» не поддерживается mpv File: Video: Resolution: Frames per second: Estimated: Aspect Ratio: Bitrate: Dropped frames: Audio: Sample Rate: Channels: Audio/video synchronization: Cache fill: Used cache: MainWindow Kylin Video Kylin Video Open открыто Open &File... Открыть файл... Directory... Справочник ... &URL... & URL ... &Clear &Очистить Recent files Недавние файлы Play control Управление воспроизведением Forward and rewind Перемотка вперед и назад &Jump to... &Прыгать, чтобы... Play Speed Скорость воспроизведения Normal speed Нормальная скорость Half speed Половина скорости Double speed Двойная скорость Speed -10% Скорость -10% Speed +10% Скорость + 10% Speed -4% Скорость -4% Speed +4% Скорость + 4% Speed -1% Скорость -1% Speed +1% Скорость + 1% Next следующий Previous предыдущий &Auto &Авто &Disabled &Инвалид Aspect ratio Соотношение сторон &Off & Off &Rotate by 90 degrees clockwise and flip & Повернуть на 90 градусов по часовой стрелке и перевернуть Rotate by 90 degrees &clockwise Повернуть на 90 градусов и по часовой стрелке Rotate by 90 degrees counterclock&wise Поворот на 90 градусов против часовой стрелки и мудрый Rotate by 90 degrees counterclockwise and &flip Поверните на 90 градусов против часовой стрелки и переверните Fli&p image Fli & p image Mirr&or image Зеркальное изображение Frame rotation Вращение рамы &Rotate & Rotate &Screenshot &Скриншот &Always &Всегда &Never &Никогда While &playing Во время игры S&tay on top S & tay сверху Order play Заказать игру Random play Случайная игра List loop play Список воспроизведения в цикле Play order Порядок воспроизведения &Stereo &Стерео &4.0 Surround & 4.0 Surround &5.1 Surround & 5.1 Surround &6.1 Surround & 6.1 Surround &7.1 Surround & 7.1 Surround &Channels &Каналы Audio аудио &Mute & Mute Volume - Объем - Volume + Объем + Delay - Задержка - Delay + Задержка + Set dela&y... Установить dela & y ... &Left channel & Левый канал &Right channel & Правый канал &Mono &Моно Re&verse Задний ход &Stereo mode & Стерео режим Subtitles Субтитры Load... Загрузить ... Subtitle &visibility Субтитры и видимость Preferences предпочтения View &info and properties... Просмотр и информация и свойства ... Help Помогите About &Kylin Video О компании & Kylin Video Quit Уволиться Show &info on OSD Size &+ Size &- Show times with &milliseconds Subtitles onl&y Volume + &Seek Volume + Seek + &Timer Volume + Seek + Timer + T&otal time &OSD PlayList PlayList Play/Pause Воспроизведение / Пауза Stop Стоп Fullscreen Полноэкранный Open Homepage Открыть домашнюю страницу Open screenshots folder Открыть папку скриншотов Failed to add files! Video filters are disabled when using vdpau Видеоэффекты отключены при использовании vdpau -%1 - 1% +%1 + 1% <empty> <Пусто> Confirm deletion - Kylin Video Подтвердить удаление - Kylin Video Delete the list of recent files? Удалить список последних файлов? Choose a file Выберите файл Multimedia мультимедиа Video видео Playlists Плейлисты All files Все файлы Choose a directory Выберите каталог &Jump to: &Прыгать, чтобы: Kylin Video - Seek Kylin Video - Ищите Kylin Video - Subtitle delay Kylin Video - Задержка субтитров Subtitle delay (in milliseconds): Задержка субтитров (в миллисекундах): Error detected Обнаружена ошибка Unfortunately this video can't be played. К сожалению, это видео невозможно воспроизвести. The server returned '%1' Сервер вернул '% 1' Jump to %1 Перейти к% 1 %1 Error % 1 Ошибка '%1' was not found! «% 1» не найден! %1 has finished unexpectedly. % 1 закончил неожиданно. Exit code: %1 Код выхода:% 1 %1 failed to start. % 1 не удалось запустить. Please check the %1 path in preferences. Проверьте путь% 1 в настройках. %1 has crashed. % 1 разбился. See the log for more info. См. Журнал для получения дополнительной информации. Information Информация The screenshot folder does not exist! Папки для скриншотов не существует! Warning - Using old MPlayer Please, update your MPlayer. (This warning won't be displayed anymore) The version of MPlayer (%1) installed on your system is obsolete. kylin-video can't work well with it: some options won't work, subtitle selection may fail... A:%1 B:%1 &Extrastereo &Karaoke Volume &normalization &Headphone optimization &Filters &Load external file... U&nload E&qualizer Reset audio equalizer MaskWidget Loading... MessageDialog Ok Хорошо Cancel отменить Yes да No нет MplayerProcess This option is not supported by MPlayer Этот параметр не поддерживается MPlayer PlayListView Play Играть Remove &selected Убрать выбранное &Delete file from disk & Удалить файл с диска Playlist Playlist is empty Плейлист пуст Add File Добавить файл PlayList PlayList Clear Очистить Add добавлять Play Играть Remove &selected Убрать выбранное &Delete file from disk & Удалить файл с диска Reached the end of the playlist Достигнут конец плейлиста Select one or more files to open Выберите один или несколько файлов для открытия Multimedia мультимедиа All files Все файлы Choose a directory Выберите каталог Confirm remove Подтвердить удаление You're about to remove the file '%1' from the playlist. Вы собираетесь удалить файл «% 1» из списка воспроизведения. Are you sure you want to proceed? Вы уверены, что хотите продолжить? Confirm deletion Подтвердить удаление You're about to DELETE the file '%1' from your drive. Вы собираетесь удалить файл «% 1» с вашего диска. This action cannot be undone. Are you sure you want to proceed? Это действие не может быть отменено. Вы уверены, что хотите продолжить? Deletion failed Не удалось выполнить удаление It wasn't possible to delete '%1' Не удалось удалить '% 1' Error deleting the file Ошибка удаления файла It's not possible to delete '%1' from the filesystem. Невозможно удалить «% 1» из файловой системы. Choose a filename Playlists Плейлисты Confirm overwrite? The file %1 already exists. Do you want to overwrite? You're about to remove the file from the playlist. You're about to Delete the files from your drive. Confirm remove all You're about to empty the playlist. Reached the top of the playlist PoweroffDialog The computer will shut down in %1 seconds. Press <b>Cancel</b> to abort shutdown. Ok Хорошо Cancel отменить PrefAudio Volume объем Global volume Глобальный объем Use software volume control Использовать регулятор громкости программного обеспечения Max. Amplification: Максимум. Усиление: Volume normalization by default Нормализация по умолчанию Synchronization синхронизация Audio/video auto synchronization Автоматическая синхронизация аудио / видео Factor: фактор: Output driver: Выходной драйвер: Channels by default: Каналы по умолчанию: 2 (Stereo) 2 (стерео) 4 (4.0 Surround) 4 (4.0 Surround) 6 (5.1 Surround) 6 (5.1 Surround) 7 (6.1 Surround) 7 (6.1 Surround) 8 (7.1 Surround) 8 (7.1 Surround) Default По умолчанию Audio output driver Драйвер аудиовыхода Select the audio output driver. Выберите драйвер аудиовыхода. %1 is the recommended one. Try to avoid %2 and %3, they are slow and can have an impact on performance. % 1 рекомендуется. Старайтесь избегать% 2 и% 3, они медленны и могут влиять на производительность. Channels by default Каналы по умолчанию Requests the number of playback channels. MPlayer asks the decoder to decode the audio into as many channels as specified. Then it is up to the decoder to fulfill the requirement. This is usually only important when playing videos with AC3 audio (like DVDs). In that case liba52 does the decoding by default and correctly downmixes the audio into the requested number of channels. <b>Note</b>: This option is honored by codecs (AC3 only), filters (surround) and audio output drivers (OSS at least). Запросит количество каналов воспроизведения. MPlayer просит декодер декодировать аудио на столько каналов, сколько указано. Тогда для декодера требуется выполнение этого требования. Это обычно важно только при воспроизведении видео с аудио AC3 (например, DVD-дисков). В этом случае liba52 выполняет декодирование по умолчанию и корректно микширует аудио в запрошенное количество каналов. <b> Примечание </ b>: эта опция соблюдается кодеками (только для AC3), фильтрами (объемным) и драйверами вывода звука (по крайней мере, OSS). If this option is checked, the same volume will be used for all files you play. If the option is not checked each file uses its own volume. Если этот параметр установлен, то тот же объем будет использоваться для всех файлов, которые вы играете. Если опция не проверена, каждый файл использует свой собственный том. This option also applies for the mute control. Этот параметр также применяется для управления отключением звука. Software volume control Контроль громкости программного обеспечения Check this option to use the software mixer, instead of using the sound card mixer. Установите этот параметр, чтобы использовать программный микшер, вместо использования микшера звуковой карты. Max. Amplification Максимум. усиление Sets the maximum amplification level in percent (default: 110). A value of 200 will allow you to adjust the volume up to a maximum of double the current level. With values below 100 the initial volume (which is 100%) will be above the maximum, which e.g. the OSD cannot display correctly. Устанавливает максимальный уровень усиления в процентах (по умолчанию: 110). Значение 200 позволит вам отрегулировать громкость до максимума в два раза выше текущего уровня. При значениях ниже 100 начальный объем (который равен 100%) будет превышать максимальный, что, например, экранное меню не может отображаться правильно. Maximizes the volume without distorting the sound. Максимизирует громкость без искажения звука. Gradually adjusts the A/V sync based on audio delay measurements. Постепенно настраивает A / V-синхронизацию на основе измерений задержки звука. PrefGeneral Pause when minimized Пауза при минимизации MPlayer MPlayer MPV MPV Playback engine: Механизм воспроизведения: Preview when video is playing Предварительный просмотр при воспроизведении видео If this option is enabled, the file will be paused when the main window is hidden. When the window is restored, playback will be resumed. Если этот параметр включен, файл будет приостановлен, когда основное окно будет скрыто. Когда окно будет восстановлено, воспроизведение будет возобновлено. Preview when the video is playing Предварительный просмотр при воспроизведении видео If this option is enabled, the video preview will be displayed when the mouse is placed on the progress bar. Если эта опция включена, предварительный просмотр видео будет отображаться, когда мышь будет установлена ​​на индикатор выполнения. Select MPlayer as playback engine Выберите MPlayer в качестве механизма воспроизведения If you change the playback engine to MPlayer, please restart Kylin Video. Если вы измените движок воспроизведения на MPlayer, перезапустите Kylin Video. Select MPV as playback engine Выберите MPV в качестве механизма воспроизведения If you change the playback engine to MPV, please restart Kylin Video. Если вы измените движок воспроизведения на MPV, перезапустите Kylin Video. PrefPerformance Cache кэш Cache for local files: Кэш для локальных файлов: KB KB Cache for streams: Кэш для потоков: Decode раскодировать Threads for decoding (MPEG-1/2 and H.264 only): Темы для декодирования (только для MPEG-1/2 и H.264): Hardware decoding Аппаратное декодирование None Никто Auto Авто Performance Спектакль Threads for decoding Темы для декодирования Sets the number of threads to use for decoding. Only for MPEG-1/2 and H.264 Устанавливает количество потоков для декодирования. Только для MPEG-1/2 и H.264 Sets the hardware video decoding API. If hardware decoding is not possible, software decoding will be used instead. Устанавливает API декодирования аппаратного видео. Если аппаратное декодирование невозможно, вместо этого будет использоваться программное декодирование. Available options: Доступные Варианты: None: only software decoding will be used. Нет: будет использоваться только программное декодирование. Auto: it tries to automatically enable hardware decoding using the first available method. Авто: он пытается автоматически включить аппаратное декодирование с использованием первого доступного метода. vdpau: for the vdpau and opengl video outputs. vdpau: для видеовыходов vdpau и opengl. vaapi: for the opengl and vaapi video outputs. For Intel GPUs only. vaapi: для видеовыходов opengl и vaapi. Только для графических процессоров Intel. vaapi-copy: it copies video back into system RAM. For Intel GPUs only. vaapi-copy: копирует видео обратно в оперативную память системы. Только для графических процессоров Intel. This option only works with mpv. Этот параметр работает только с mpv. Cache for files Кэш для файлов This option specifies how much memory (in kBytes) to use when precaching a file. Этот параметр указывает, сколько памяти (в kBytes) следует использовать при преследовании файла. Cache for streams Кэш для потоков This option specifies how much memory (in kBytes) to use when precaching a URL. Этот параметр указывает, сколько памяти (в kBytes) следует использовать при доработке URL-адреса. PrefScreenShot Screenshots Скриншоты Enable screenshots Включить скриншоты Folder: Папка: Template: Шаблон: Format: Формат: Select a directory Выберите каталог You can use this option to enable or disable the possibility to take screenshots. Вы можете использовать этот параметр, чтобы включить или отключить возможность делать скриншоты. Screenshots folder Папка скриншотов Here you can specify a folder where the screenshots taken by Kylin Video will be stored. If the folder is not valid the screenshot feature will be disabled. Здесь вы можете указать папку, в которой будут сохранены снимки экрана, сделанные Kylin Video. Если папка недействительна, функция скриншота будет отключена. Template for screenshots Шаблон для скриншотов This option specifies the filename template used to save screenshots. Этот параметр указывает шаблон имени файла, используемый для сохранения скриншотов. For example %1 would save the screenshot as 'moviename_0001.png'. Например,% 1 сохранит скриншот как «moviename_0001.png». %1 specifies the filename of the video without the extension, %2 adds a 4 digit number padded with zeros. % 1 указывает имя файла видео без расширения,% 2 добавляет 4-значное число, заполненное нулями. For a full list of the template specifiers visit this link: Полный список спецификаторов шаблонов можно найти по этой ссылке: This option only works with mpv. Этот параметр работает только с mpv. Format for screenshots Формат для скриншотов This option allows one to choose the image file type used for saving screenshots. Эта опция позволяет выбрать тип файла изображения, используемый для сохранения снимков экрана. PrefShortCut Here you can change any key shortcut. To do it double click or press enter over a shortcut cell. Здесь вы можете изменить любой ключевой ярлык. Для этого дважды щелкните или нажмите enter через ячейку быстрого доступа. ShortCut ShortCut Here you can change any key shortcut. To do it double click or start typing over a shortcut cell. Здесь вы можете изменить любой ключевой ярлык. Чтобы сделать это, дважды щелкните или начните вводить текст по ячейке быстрого доступа. Shortcut Key Быстрая клавиша Shortcut editor Редактор ярлыков This table allows you to change the key shortcuts of most available actions. Double click or press enter on a item, or press the <b>Change shortcut</b> button to enter in the <i>Modify shortcut</i> dialog. There are two ways to change a shortcut: if the <b>Capture</b> button is on then just press the new key or combination of keys that you want to assign for the action (unfortunately this doesn't work for all keys). If the <b>Capture</b> button is off then you could enter the full name of the key. В этой таблице вы можете изменить ключевые ярлыки большинства доступных действий. Дважды щелкните или нажмите клавишу ввода для элемента или нажмите кнопку <b> Изменить ярлык </ b>, чтобы войти в диалоговое окно <i> Изменить ярлык </ i>. Есть два способа изменить ярлык: если кнопка <b> Capture </ b> включена, просто нажмите новую клавишу или комбинацию клавиш, которые вы хотите назначить для действия (к сожалению, это не работает для всех клавиш ). Если кнопка <b> Capture </ b> выключена, вы можете ввести полное имя ключа. PrefSubtitles Autoload Автозагрузка Autoload subtitles files (*.srt, *.sub...): Файлы субтитров Autoload (* .srt, * .sub ...): Same name as movie То же имя, что и фильм All subs containing movie name Все субтитры, содержащие название фильма All subs in directory Все подкаталоги в каталоге Encoding кодирование Default subtitle encoding: Кодировка субтитров по умолчанию: Try to autodetect for this language: Попробуйте автоопределить для этого языка: Subtitles Субтитры Select the subtitle autoload method. Выберите метод автозагрузки субтитров. Default subtitle encoding Кодировка субтитров по умолчанию Select the encoding which will be used for subtitle files by default. Выберите кодировку, которая будет использоваться для файлов субтитров по умолчанию. Try to autodetect for this language Попробуйте автоопределить для этого языка When this option is on, the encoding of the subtitles will be tried to be autodetected for the given language. It will fall back to the default encoding if the autodetection fails. This option requires a MPlayer compiled with ENCA support. Когда эта опция включена, кодировка субтитров будет проверена автоматически для данного языка. Он вернется к кодировке по умолчанию, если автоопределение не удастся. Для этого параметра требуется MPlayer, скомпилированный с поддержкой ENCA. Subtitle language Язык субтитров Select the language for which you want the encoding to be guessed automatically. Выберите язык, для которого вы хотите, чтобы кодировка была угадана автоматически. Font Шрифт PrefVideo Enable postprocessing by default Включить постобработку по умолчанию Draw video using slices Рисование видео с помощью фрагментов Direct rendering Прямая передача Double buffering Двойная буферизация Use software video equalizer Использовать программный видеоэквалайзер Output driver: Выходной драйвер: Default По умолчанию slow медленный Video output driver Драйвер видеовыхода Select the video output driver. %1 provides the best performance. Выберите драйвер видеовыхода. % 1 обеспечивает лучшую производительность. Postprocessing will be used by default on new opened files. Постобработка будет использоваться по умолчанию для новых открытых файлов. Software video equalizer Программный видеоэквалайзер You can check this option if video equalizer is not supported by your graphic card or the selected video output driver.<br><b>Note:</b> this option can be incompatible with some video output drivers. Вы можете проверить эту опцию, если видеоэквалайзер не поддерживается графической картой или выбранным драйвером вывода видео. <br> <b> Примечание: </ b> этот параметр может быть несовместим с некоторыми драйверами вывода видео. If checked, turns on direct rendering (not supported by all codecs and video outputs)<br><b>Warning:</b> May cause OSD/SUB corruption! Если отмечено, включается прямая рендеринг (не поддерживается всеми кодеками и видеовыходами) <br> <b> Предупреждение: </ b> Может вызвать повреждение OSD / SUB! Double buffering fixes flicker by storing two frames in memory, and displaying one while decoding another. If disabled it can affect OSD negatively, but often removes OSD flickering. Двойная буферизация фиксирует мерцание, сохраняя два кадра в памяти и отображая их при декодировании другого. Если он отключен, он может негативно повлиять на экранное меню, но часто удаляет мерцание экранного меню. Enable/disable drawing video by 16-pixel height slices/bands. If disabled, the whole frame is drawn in a single run. May be faster or slower, depending on video card and available cache. It has effect only with libmpeg2 and libavcodec codecs. Включить / отключить рисование видео на 16-пиксельных срезах / диапазонах. Если он отключен, весь кадр рисуется за один проход. Может быть быстрее или медленнее, в зависимости от видеокарты и доступного кеша. Он действует только с кодеками libmpeg2 и libavcodec. PreferencesDialog Kylin Video - Preferences Kylin Video - Настройки Preference предпочтение Cancel отменить Apply Применять OK Хорошо General генеральный Video видео Audio аудио Performance Спектакль Subtitles Субтитры ScreenShot Скриншот Shortcut Key Быстрая клавиша QObject %n second(s) %n minute(s) %1 and %2 % 1 и% 2 This is Kylin Vedio v. %1 running on %2 Это Kylin Vedio v.% 1 работает на% 2 disabled aspect_ratio отключен auto aspect_ratio авто unknown aspect_ratio неизвестный ShortcutGetter Modify shortcut Изменить ярлык Add shortcut Добавьте ярлык Remove shortcut Удалить ярлык Press the key combination you want to assign Нажмите комбинацию клавиш, которую вы хотите назначить Clear Очистить OK Хорошо Cancel отменить Capture Захватить Capture keystrokes Захват нажатий клавиш SupportFormats Video formats Видео форматы Audio formats Аудио форматы Subtitles formats Форматы субтитров Some video formats do not support preview and seek by dragging, e.g. the swf. Некоторые видеоформаты не поддерживают предварительный просмотр и поиск путем перетаскивания, например swf. TimeDialog Seek Искать OK Хорошо Cancel отменить Jump to: Прыгать, чтобы: TitleWidget Kylin Video Kylin Video TristateCombo Auto Авто Yes да No нет VideoPreview The length of the video is 0 Длина видео равна 0 The temporary directory (%1) can't be created Временный каталог (% 1) не может быть создан The file %1 doesn't exist Файл% 1 не существует The mplayer process didn't run Процесс mplayer не запускался No filename Нет имени файла The mplayer process didn't start while trying to get info about the video Процесс mplayer не начинался, пытаясь получить информацию о видео The mpv process didn't run kylin-video/src/translations/.tx/0000755000175000017500000000000013517016402015750 5ustar fengfengkylin-video/src/translations/.tx/config0000644000175000017500000000043613517016402017143 0ustar fengfeng[main] host = https://www.transifex.com [smplayer.english] type = QT file_filter = smplayer_.ts source_lang = en source_file = smplayer_en_US.ts trans.he = smplayer_he_IL.ts trans.vi = smplayer_vi_VN.ts trans.ru = smplayer_ru_RU.ts trans.uk = smplayer_uk_UA.ts minimum_perc = 50 kylin-video/src/translations/kylin-video_ru.qm0000644000175000017500000017465213625147453020570 0ustar fengfengrqx kd9@_#`` `joyGJȵK5N/^gA]R{ !" J9""$ez{&*Q+FOSz+LSGRHw9Hw9uHX)HزIyJ+sJ+ގK (Kʘ)LbLbM-"Mx,N-N.O/P2Q4 Rd5 R6[S8rS9WT;(V=V?=X#Y@Yĩ?YAAZjD~ZF{ZFZIZFZةE[dH3\o1\ġKW\mF\a]K*]ØL/^cVMN^M{gz_rR}N6C(pRfyJ/.2>X5eÙ^N>Jl^.blT:" ",6s[R`0a d!)G3B2 |xJsϦH|w)XZ4 ] x emt#[,wBp RNRr~]vK W1M.65c"5t18:+R/S {W Ȱ5͢S4ؘƾ%icYTl_W.Yq65S+rC3C:ЩjLO$QNcWq^_2kɖ89E~6W\w\yUt $ҔZf*~eKQ 4g$ 4L71VPca S~[=Qd~ieQkf0jH`m rJa:#x #"9$d8"I iItIIoNIvIIݺI|^%1EOu:&N[Ș',RahUE<P)5-u;)g7q*%~+,0 Ę,ܓ~-{:/쌏/Q f#x7 _Q '+9\3u3_P -4>#n %Bn&~57:_QO=ZBa5H;UKd;Lh);[ `<j3-v0>|?I@A#E~@ .<g3!FJB\l{C^8)DD;G9ddHAI I+j++j9L<5߮CNOPwQGBM &~GNfI0XI/_ d`đcRWX*^Jۖ>9'`TTW?5~5~I*Iɟ.>l֣RR㞳:JEED/2 Y eVe!s2#Q 5eFgE GZGZ_Q'bVROWLfe!FE'ݙ88/,7 "> Um$AZ.@hI2yq5NH|7~\^J5#KB#~^#E3.̕5A ?Ii$)I3 qy̪>"mdZρQ4no''Ox 1 ]cY ]t Q. (q$ h> h>]8 jO>$ q1 u1\ >% c 5Ք sk s\ s" ȏ.AS <% ʟ.@, xt ۊ< G#; 꽺 & L& .A '^ }; qB l2 nX *Go 6D dUq hPE iP' }F #Q 8" lA = %U ` xr <8 $= K+ ŷ # t| tȹ I ‹kYo ‹mY < ΂ yEu ۰E .G Z^  _ s To ! p ,`> 2~ 3j <'[ CUK E9 F XW F r _4b gBi% gJ hi sBb t9 5 E~1 T .V- I^ ȟU Uv x7 tij tUh j/ Ui _ > ڒ I9 #In ̛:j Y h ^  I.f  " &#9 &#f (c0G +[1 = B)a BR:R B: FGz N0* OJ RV6 hۮ-O z} |9M m \+ =  1 u: %J s{ d bG 1 P+  qD EW *7O_ 74<bj :n4 ZtNz= b i8: k 6K >,T k n ~ }L <# #()P  :X+>\029;^aDcaOlWlqsxa~>.m&NbQ@;_QGMi0X<! DOCTYPE HTML PUBLIC \ "- // W3C // DTD HTML 4.0 // EN " \ "http: //www.w3.org/TR/REC-html40/strict.dtd "> \ n <html> <head> <meta name = \ "qrichtext " content = \ "1 " /> <style type = \ "text / css "> \ np, li {white-space: pre-wrap; } \ n </ style> </ head> <body style = \ "font-family: 'Ubuntu'; font-size: 11pt; font-weight: 400; font-style: normal; "> \ n <p style = \ "- qt-paragraph-type: empty; margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-block-indent: 0; text-indent: 0px; \ "> <br /> </ p> </ body> </ html>


 AboutDialog :>;>About AboutDialogCG0AB=8: Contributor AboutDialogKylin Video Kylin Video AboutDialog %>@>H>OK AboutDialog25E0=87< 2>A?@>872545=8O:Playback engine: AboutDialogTA?>;L7CO Qt% 1 (A:><?8;8@>20==K9 A Qt% 2)!Using Qt %1 (compiled with Qt %2) AboutDialog5@A8O:% 1 Version: %1 AboutDialogK15@8B5 D09; Choose a file ActionsEditor?8A0=85 Description ActionsEditor >H81:0Error ActionsEditor=0720=85Name ActionsEditor:@0BG09H89 ?CBLShortcut ActionsEditor045@6:0 72C:0 Audio delayAudioDelayDialogB045@6:0 72C:0 (2 <8;;8A5:C=40E):Audio delay (in milliseconds):AudioDelayDialog>B<5=8BLCancelAudioDelayDialog %>@>H>OKAudioDelayDialog &!1@>A&ResetAudioEqualizer=D>@<0F8O InformationAudioEqualizer1573;0A=K9Mute BottomWidgetA;54CNI89Next BottomWidget*>A?@>8725AB8 / 0C70 Play / Pause BottomWidget,!?8A>: 2>A?@>872545=8O Play List BottomWidget@54K4CI0OPrev BottomWidget!B>?Stop BottomWidget60@:5@  CAB0=>2;5= =0% 1"A" marker set to %1Core40@:5@ B CAB0=>2;5= 2% 1"B" marker set to %1Core$0@:5@K AB >G8I5=KA-B markers clearedCore,!>>B=>H5=85 AB>@>=:% 1Aspect ratio: %1Core*045@6:0 72C:0:% 1 <AAudio delay: %1 msCore/@:>ABL:% 1Brightness: %1CoreCD5@870F8O ... Buffering...Core>=B@0AB:% 1 Contrast: %1Core0<<0:% 1 Gamma: %1CoreBB5=>::% 1Hue: %1CoreD"5?5@L :>;5A> <KH8 <5=O5B A:>@>ABLMouse wheel changes speed nowCoreF"5?5@L :>;5A> <KH8 <5=O5B 3@><:>ABLMouse wheel changes volume nowCore4>;5A> <KH8 <5=O5B <0AHB01"Mouse wheel changes zoom level nowCore.>;5A> <KH8 B5?5@L 8I5BMouse wheel seeks nowCore 0AKI5==>ABL:% 1Saturation: %1CoreV!=8<>: M:@0=0 =5 A45;0=, ?0?:0 =5 =0AB@>5=0+Screenshot NOT taken, folder not configuredCoreB!=8<>: M:@0=0, A>E@0=5==K9 :0:% 1Screenshot saved as %1CoreP!:@8=H>BK  ?@8=OBK, ?0?:0 =5 =0AB@>5=0,Screenshots NOT taken, folder not configuredCore!:>@>ABL:% 1 Speed: %1Core0G8=0O A ... Starting...Core2045@6:0 AC1B8B@>2:% 1 <ASubtitle delay: %1 msCore$!C1B8B@K >B:;NG5=K Subtitles offCore!C1B8B@K =0 Subtitles onCore|1=>2;5=85 :5H0 H@8DB>2. -B> <>65B 70=OBL =5A:>;L:> A5:C=4 ...6Updating the font cache. This may take some seconds...Core1J5<:% 1 Volume: %1Core0AHB01:% 1Zoom: %1Core >H81:0Error ErrorDialog!:@KBL 6C@=0;Hide log ErrorDialogH81:0 MPlayer MPlayer Error ErrorDialog %>@>H>OK ErrorDialog69, GB>-B> =5 B0: A;CG8;>ALOops, something wrong happened ErrorDialog>:070BL 6C@=0;Show log ErrorDialog 7=0G>:icon ErrorDialog^06<8B5 ESC 4;O 2KE>40 87 ?>;=>M:@0==>3> @568<0"Press ESC to exit full screen modeEscTipJ06<8B5, GB>1K 2K1@0BL D09; 8;8 ?0?:C Click to select a file or folder FileChooser &!1@>A&ResetFilePropertiesDialog,& K15@8B5 0C48>:>45::&Select the audio codec:FilePropertiesDialog& K15@8B5 45<C;LB8?;5:A, :>B>@K9 1C45B 8A?>;L7>20BLAO 4;O MB>3> D09;0:4&Select the demuxer that will be used for this file:FilePropertiesDialog,& K15@8B5 2845>:>45::&Select the video codec:FilePropertiesDialog@8<5=OBLApplyFilePropertiesDialogC48>:>45: Audio codecFilePropertiesDialog>B<5=8BLCancelFilePropertiesDialogDemuxerDemuxerFilePropertiesDialog=D>@<0F8O InformationFilePropertiesDialog.Kylin Video - 0AB@>9:8Kylin Video - PreferencesFilePropertiesDialog %>@>H>OKFilePropertiesDialogA2>9AB20 PropertiesFilePropertiesDialog !1@>AResetFilePropertiesDialog845> :>45: Video codecFilePropertiesDialog><>38B5Help HelpDialog(Kylin Video - ><>ILKylin Video - Help HelpDialog %>@>H>OK HelpDialog,>445@68205<K5 D>@<0BKSupported formats HelpDialog>B<5=8BLCancelInputURL"2548B5 URL-04@5A Enter URLInputURL %>@>H>OKInputURLURL:URL:InputURL01E07A:0O Abkhazian Languages8740;5:0Afar Languages0D@8:00=A Afrikaans Languages:0=Akan Languages0;10=A:89Albanian Languages0<E0@A:89Amharic Languages0@01A:89Arabic Languages @01A:89 - !8@8OArabic - Syria Languages @01A:85 WindowsArabic Windows Languages0@03>=A:89 Aragonese Languages0@<O=8=Armenian LanguagesAA0<A:89Assamese Languages020@A:89Avaric LanguagesAvestanAvestan Languages 09<0@0Aymara Languages075@109460=5F Azerbaijani Languages10;B89A:89Baltic LanguagesBambaraBambara Languages10H:8@A:89Bashkir Languages10A:A:89Basque Languages5;>@CAA:89 Belarusian Languages15=30;LA:89Bengali Languages 8E0@8Bihari Languages8A;0<0Bislama Languages 1C:<>;Bokmål Languages1>A=89A:89Bosnian Languages1@5B>=A:89Breton Languages1>;30@A:89 Bulgarian Languages18@<0=A:89Burmese Languages:0B0;>=A:89Catalan Languages:5;LBA:89Celtic Languages'0<>@@>Chamorro LanguagesG5G5=5FChechen LanguagesChichewaChichewa Languages:8B09A:89 O7K:Chinese LanguagesF5@:>2LChurch LanguagesGC20HA:89Chuvash Languages:>@=C>;;A:89Cornish Languages:>@A8:0=5FCorsican LanguagesCreeCree LanguagesE>@20BA:89Croatian Languages:8@8;;8F0Cyrillic Languages$8@8;;8G5A:85 >:=0Cyrillic Windows LanguagesG5HA:89 O7K:Czech Languages40BA:89Danish Languages<0;L482A:89Divehi Languages>;;0=4A:89Dutch LanguagesDzongkhaDzongkha Languages0=3;89A:89English LanguagesMA?5@0=B> Esperanto LanguagesZ-A?5@0=B>, 0;8A89A:89, 0;LB89A:89, "C@5F:89%Esperanto, Galician, Maltese, Turkish LanguagesMAB>=A:89Estonian Languages>2F0Ewe Languages$0@5@A:0OFaroese Languages FijianFijian LanguagesD8=A:89Finnish Languages$@0=FC7A:89French LanguagesD@87A:89Frisian Languages DC;0EFulah Languages30M;LA:89Gaelic Languages0;8F:0OGalician Languages GandaGanda Languages3@C78=A:89Georgian Languages5<5F:89German Languages3@5G5A:89Greek Languages3@5=;0=4A:89 Greenlandic LanguagesC0@0=8Guarani Languages3C460@0B8Gujarati Languages308BO=A:89Haitian Languages E0CA0Hausa Languages 82@8BHebrew Languages&2@8BA:85 :>48@>2:8Hebrew charsets Languages 35@5@>Herero Languages E8=48Hindi LanguagesHiriHiri Languages5=35@A:89 Hungarian Languages8A;0=4A:89 Icelandic Languages/ 45;0NIdo Languages31>Igbo Languages8=4>=5789A:89 Indonesian Languages=B5@;8=320 Interlingua Languages=B5@;8=325 Interlingue LanguagesInuktitut Inuktitut Languages=C?80:Inupiaq Languages8@;0=4A:89Irish Languages8B0;LO=A:89Italian LanguagesO?>=A:89 O7K:Japanese Languages$/?>=A:85 :>48@>2:8Japanese charsets LanguagesO20=A:89Javanese Languages:0==040Kannada Languages :0=C@8Kanuri LanguagesKashmiriKashmiri Languages :070EKazakh Languages:E<5@A:89Khmer Languages :8:C9NKikuyu Languages:8=LO@C0=40 Kinyarwanda Languages:8@387KKirghiz Languages><8Komi Languages KongoKongo Languages:>@59A:89 O7K:Korean Languages&>@59A:0O :>48@>2:0Korean charset LanguagesKuanyamaKuanyama Languages:C@4A:89Kurdish Languages0>Lao Languages ;0BK=LLatin Languages0BKHA:89Latvian LanguagesLimburgan Limburgan LanguagesLingalaLingala Languages8B>2A:89 O7K: Lithuanian LanguagesLuba-0B0=30 Luba-Katanga Languages;N:A5<1C@3A:89 Luxembourgish Languages<0:54>=A:89 Macedonian Languages<0;030A85FMalagasy Languages<0;09A:89Malay LanguagesMalayalam Malayalam Languages<0;LB89A:89Maltese LanguagesA >AB@>20 M=Manx Languages <0>@8Maori Languages<0@0BE8Marathi LanguagesMarshallese Marshallese Languages*!>2@5<5==K9 3@5G5A:89 Modern Greek Languages4!>2@5<5==K5 3@5G5A:85 >:=0Modern Greek Windows Languages<>;4020=8= Moldavian Languages<>=3>;LA:89 Mongolian Languages 0C@CNauru Languages =020E>Navajo LanguagesNdebeleNdebele Languages NdongaNdonga Languages=5?0;LA:89Nepali Languages=>@256A:89 O7K: Norwegian Languages$>@256A:89 =N=>@A:Norwegian Nynorsk LanguagesOccitanOccitan Languages>468120Ojibwa Languages6!B0@0O 10;B89A:0O :>48@>2:0Old Baltic charset Languages@8OOriya Languages>@Oromo Languages>A5B8=A:89Ossetian Languages?0;8Pali LanguagesPanjabiPanjabi Languages?5@A84A:89Persian Languages?>;LA:89Polish Languages?>@BC30;LA:89 Portuguese Languages ?CHBCPushto Languages :5GC0Quechua Languages@C<K=A:89Romanian Languages*@5B>@><0=A:89 480;5:BRomansh Languages  C=48Rundi Languages@CAA:89Russian Languages!0<8Sami Languages SamoanSamoan Languages !0=3>Sango LanguagesA0=A:@8BSanskrit LanguagesA0@48=5F Sardinian LanguagesA5@1A:89Serbian Languages ShonaShona Languages!KGC0=LSichuan Languages<#?@>I5==0O :8B09A:0O :>48@>2:0Simplified Chinese charset Languages SindhiSindhi LanguagesSinhalaSinhala LanguagesP!;02O=A:85 / F5=B@0;L=>52@>?59A:85 O7K:8!Slavic/Central European Languages LanguagesN!;02O=A:85 / F5=B@0;L=>52@>?59A:85 >:=0Slavic/Central European Windows LanguagesA;>20F:89Slovak LanguagesA;>25=5FSlovene LanguagesA><0;89A:89Somali LanguagesA>B>Sotho Languages(.3>->AB>G=0O 2@>?0South-Eastern European Languages8A?0=A:89Spanish Languages!C40=A:89 Sundanese LanguagesAC0E8;8Swahili Languages !20B8Swati LanguagesH254A:89Swedish LanguagesB030;LA:>3>Tagalog LanguagesTahitianTahitian LanguagesB0468:A:89Tajik LanguagesB0<8;LA:89Tamil LanguagesB0B0@8=Tatar Languages B5;C3CTelugu LanguagesB09A:89Thai Languages""09A:0O :>48@>2:0 Thai charset LanguagesB815BA:89Tibetan LanguagesB83@8=LOTigrinya Languages ">=30Tonga Languages@"@048F8>==0O :8B09A:0O :>48@>2:0Traditional Chinese charset Languages "A>=30Tsonga Languages TswanaTswana LanguagesBC@5F:89Turkish LanguagesBC@:<5=A:89Turkmen LanguagesTwiTwi Languages UTF-8,UTF-8 Languages#93C@A:89Uighur LanguagesC:@08=5F Ukrainian Languages.#:@08=A:89, 15;>@CAA:89Ukrainian, Belarusian LanguagesUnicodeUnicode LanguagesC@4CUrdu Languages C715:Uzbek Languages 5=40Venda Languages2L5B=0<A:89 Vietnamese LanguagesVolapkVolapük Languages20;;>=A:89Walloon Languages20;;89A:89Welsh Languages00?04=>52@>?59A:85 O7K:8Western European Languages Languages>0?04=>52@>?59A:85 O7K:8 A 52@>$Western European Languages with Euro Languages >;>DWolof Languages>AXhosa Languages848HYiddish Languages 9>@C10Yoruba Languages '6C0=Zhuang Languages 7C;CAZulu Languages+ 7<5=8BLChangeLineEditWithIconDD8;LB@ % 1 =5 ?>445@68205BAO mpv'the '%1' filter is not supported by mpv MPVProcess% 1 H81:0%1 Error MainWindow2% 1 =5 C40;>AL 70?CAB8BL.%1 failed to start. MainWindow% 1 @0718;AO.%1 has crashed. MainWindow0% 1 70:>=G8; =5>6840==>.%1 has finished unexpectedly. MainWindow& 4.0 Surround &4.0 Surround MainWindow& 5.1 Surround &5.1 Surround MainWindow& 6.1 Surround &6.1 Surround MainWindow& 7.1 Surround &7.1 Surround MainWindow&A5340&Always MainWindow &2B>&Auto MainWindow&0=0;K &Channels MainWindow&G8AB8BL&Clear MainWindow&=20;84 &Disabled MainWindow$&@K30BL, GB>1K... &Jump to... MainWindow &@K30BL, GB>1K: &Jump to: MainWindow& 52K9 :0=0; &Left channel MainWindow &>=>&Mono MainWindow & Mute&Mute MainWindow&8:>340&Never MainWindow & Off&Off MainWindow& @02K9 :0=0;&Right channel MainWindow& Rotate&Rotate MainWindowv& >25@=CBL =0 90 3@04CA>2 ?> G0A>2>9 AB@5;:5 8 ?5@525@=CBL(&Rotate by 90 degrees clockwise and flip MainWindow&!:@8=H>B &Screenshot MainWindow&!B5@5>&Stereo MainWindow& !B5@5> @568< &Stereo mode MainWindow& URL ...&URL... MainWindow % 1 =5 =0945=!'%1' was not found! MainWindow+ 1%+%1 MainWindow- 1%-%1 MainWindow<CAB>> MainWindow0 :><?0=88 & Kylin VideoAbout &Kylin Video MainWindowA5 D09;K All files MainWindow$!>>B=>H5=85 AB>@>= Aspect ratio MainWindow 0C48>Audio MainWindow K15@8B5 :0B0;>3Choose a directory MainWindowK15@8B5 D09; Choose a file MainWindowD>4B25@48BL C40;5=85 - Kylin VideoConfirm deletion - Kylin Video MainWindow045@6:0 +Delay + MainWindow045@6:0 -Delay - MainWindow@#40;8BL A?8A>: ?>A;54=8E D09;>2? Delete the list of recent files? MainWindow!?@02>G=8: ... Directory... MainWindow 2>9=0O A:>@>ABL Double speed MainWindow"1=0@C65=0 >H81:0Error detected MainWindow>4 2KE>40:% 1 Exit code: %1 MainWindowFli & p image Fli&p image MainWindow05@5<>B:0 2?5@54 8 =0704Forward and rewind MainWindow@0I5=85 @0<KFrame rotation MainWindow>;=>M:@0==K9 Fullscreen MainWindow">;>28=0 A:>@>AB8 Half speed MainWindow><>38B5Help MainWindow=D>@<0F8O Information MainWindow5@59B8 :% 1 Jump to %1 MainWindowKylin Video Kylin Video MainWindow&Kylin Video - I8B5Kylin Video - Seek MainWindow@Kylin Video - 045@6:0 AC1B8B@>2Kylin Video - Subtitle delay MainWindow<!?8A>: 2>A?@>872545=8O 2 F8:;5List loop play MainWindow03@C78BL ...Load... MainWindow,5@:0;L=>5 87>1@065=85 Mirr&or image MainWindow<C;LB8<5480 Multimedia MainWindowA;54CNI89Next MainWindow&>@<0;L=0O A:>@>ABL Normal speed MainWindow>B:@KB>Open MainWindowB:@KBL D09;... Open &File... MainWindow2B:@KBL 4><0H=NN AB@0=8FC Open Homepage MainWindow0B:@KBL ?0?:C A:@8=H>B>2Open screenshots folder MainWindow0:070BL 83@C Order play MainWindow0!:>@>ABL 2>A?@>872545=8O Play Speed MainWindow6#?@02;5=85 2>A?@>872545=85< Play control MainWindow.>@O4>: 2>A?@>872545=8O Play order MainWindowPlayListPlayList MainWindow;59;8ABK Playlists MainWindow>@>25@LB5 ?CBL% 1 2 =0AB@>9:0E.(Please check the %1 path in preferences. MainWindow?@54?>GB5=8O Preferences MainWindow?@54K4CI89Previous MainWindow#2>;8BLAOQuit MainWindow!;CG09=0O 83@0 Random play MainWindow04=89 E>4Re&verse MainWindow5402=85 D09;K Recent files MainWindowZ>25@=CBL =0 90 3@04CA>2 8 ?> G0A>2>9 AB@5;:5Rotate by 90 degrees &clockwise MainWindowl>2>@>B =0 90 3@04CA>2 ?@>B82 G0A>2>9 AB@5;:8 8 <C4@K9&Rotate by 90 degrees counterclock&wise MainWindowz>25@=8B5 =0 90 3@04CA>2 ?@>B82 G0A>2>9 AB@5;:8 8 ?5@525@=8B5/Rotate by 90 degrees counterclockwise and &flip MainWindowS & tay A25@EC S&tay on top MainWindowf!<. C@=0; 4;O ?>;CG5=8O 4>?>;=8B5;L=>9 8=D>@<0F88.See the log for more info. MainWindow.#AB0=>28BL dela & y ... Set dela&y... MainWindow!:>@>ABL + 1% Speed +1% MainWindow!:>@>ABL + 10% Speed +10% MainWindow!:>@>ABL + 4% Speed +4% MainWindow!:>@>ABL -1% Speed -1% MainWindow!:>@>ABL -10% Speed -10% MainWindow!:>@>ABL -4% Speed -4% MainWindow!B>?Stop MainWindow(!C1B8B@K 8 2848<>ABLSubtitle &visibility MainWindowJ045@6:0 AC1B8B@>2 (2 <8;;8A5:C=40E):!Subtitle delay (in milliseconds): MainWindow!C1B8B@K Subtitles MainWindowF0?:8 4;O A:@8=H>B>2 =5 ACI5AB2C5B!%The screenshot folder does not exist! MainWindow&!5@25@ 25@=C; '% 1'The server returned '%1' MainWindow` A>60;5=8N, MB> 2845> =52>7<>6=> 2>A?@>8725AB8.)Unfortunately this video can't be played. MainWindow 2845>Video MainWindow\845>MDD5:BK >B:;NG5=K ?@8 8A?>;L7>20=88 vdpau+Video filters are disabled when using vdpau MainWindowH@>A<>B@ 8 8=D>@<0F8O 8 A2>9AB20 ...View &info and properties... MainWindow1J5< +Volume + MainWindow1J5< -Volume - MainWindow> 2@5<O 83@KWhile &playing MainWindow>B<5=8BLCancel MessageDialog=5BNo MessageDialog %>@>H>Ok MessageDialog40Yes MessageDialogN-B>B ?0@0<5B@ =5 ?>445@68205BAO MPlayer'This option is not supported by MPlayerMplayerProcess,& #40;8BL D09; A 48A:0&Delete file from disk PlayListView 3@0BLPlay PlayListView #1@0BL 2K1@0==>5Remove &selected PlayListView4>102;OBLAddPlaylist>1028BL D09;Add FilePlaylistA5 D09;K All filesPlaylistDK C25@5=K, GB> E>B8B5 ?@>4>;68BL?!Are you sure you want to proceed?Playlist K15@8B5 :0B0;>3Choose a directoryPlaylistG8AB8BLClearPlaylist(>4B25@48BL C40;5=85Confirm deletionPlaylist(>4B25@48BL C40;5=85Confirm removePlaylist<C;LB8<5480 MultimediaPlaylistPlayListPlayListPlaylist;59;8AB ?CABPlaylist is emptyPlaylist;59;8ABK PlaylistsPlaylist2>AB83=CB :>=5F ?;59;8AB0Reached the end of the playlistPlaylist^K15@8B5 >48= 8;8 =5A:>;L:> D09;>2 4;O >B:@KB8O Select one or more files to openPlaylist-B> 459AB285 =5 <>65B 1KBL >B<5=5=>. K C25@5=K, GB> E>B8B5 ?@>4>;68BL??This action cannot be undone. Are you sure you want to proceed?Playlist>B<5=8BLCancelPoweroffDialog %>@>H>OkPoweroffDialog% 1 @5:><5=4C5BAO. !B0@09B5AL 871530BL% 2 8% 3, >=8 <54;5==K 8 <>3CB 2;8OBL =0 ?@>872>48B5;L=>ABL.g%1 is the recommended one. Try to avoid %2 and %3, they are slow and can have an impact on performance. PrefAudio2 (AB5@5>) 2 (Stereo) PrefAudio 4 (4.0 Surround)4 (4.0 Surround) PrefAudio 6 (5.1 Surround)6 (5.1 Surround) PrefAudio 7 (6.1 Surround)7 (6.1 Surround) PrefAudio 8 (7.1 Surround)8 (7.1 Surround) PrefAudio&@0925@ 0C48>2KE>40Audio output driver PrefAudioT2B><0B8G5A:0O A8=E@>=870F8O 0C48> / 2845> Audio/video auto synchronization PrefAudio&0=0;K ?> C<>;G0=8NChannels by default PrefAudio(0=0;K ?> C<>;G0=8N:Channels by default: PrefAudio#AB0=>28B5 MB>B ?0@0<5B@, GB>1K 8A?>;L7>20BL ?@>3@0<<=K9 <8:H5@, 2<5AB> 8A?>;L7>20=8O <8:H5@0 72C:>2>9 :0@BK.SCheck this option to use the software mixer, instead of using the sound card mixer. PrefAudio> C<>;G0=8NDefault PrefAudioD0:B>@:Factor: PrefAudio ;>10;L=K9 >1J5< Global volume PrefAudio>AB5?5==> =0AB@08205B A / V-A8=E@>=870F8N =0 >A=>25 87<5@5=89 7045@6:8 72C:0.AGradually adjusts the A/V sync based on audio delay measurements. PrefAudio\A;8 MB>B ?0@0<5B@ CAB0=>2;5=, B> B>B 65 >1J5< 1C45B 8A?>;L7>20BLAO 4;O 2A5E D09;>2, :>B>@K5 2K 83@05B5. A;8 >?F8O =5 ?@>25@5=0, :064K9 D09; 8A?>;L7C5B A2>9 A>1AB25==K9 B><.If this option is checked, the same volume will be used for all files you play. If the option is not checked each file uses its own volume. PrefAudio$0:A8<C<. CA8;5=85Max. Amplification PrefAudio&0:A8<C<. #A8;5=85:Max. Amplification: PrefAudioX0:A8<878@C5B 3@><:>ABL 157 8A:065=8O 72C:0.2Maximizes the volume without distorting the sound. PrefAudio"KE>4=>9 4@0925@:Output driver: PrefAudio"0?@>A8B :>;8G5AB2> :0=0;>2 2>A?@>872545=8O. MPlayer ?@>A8B 45:>45@ 45:>48@>20BL 0C48> =0 AB>;L:> :0=0;>2, A:>;L:> C:070=>. ">340 4;O 45:>45@0 B@51C5BAO 2K?>;=5=85 MB>3> B@51>20=8O. -B> >1KG=> 206=> B>;L:> ?@8 2>A?@>872545=88 2845> A 0C48> AC3 (=0?@8<5@, DVD-48A:>2).  MB>< A;CG05 liba52 2K?>;=O5B 45:>48@>20=85 ?> C<>;G0=8N 8 :>@@5:B=> <8:H8@C5B 0C48> 2 70?@>H5==>5 :>;8G5AB2> :0=0;>2. <b> @8<5G0=85 </ b>: MB0 >?F8O A>1;N405BAO :>45:0<8 (B>;L:> 4;O AC3), D8;LB@0<8 (>1J5<=K<) 8 4@0925@0<8 2K2>40 72C:0 (?> :@09=59 <5@5, OSS).Requests the number of playback channels. MPlayer asks the decoder to decode the audio into as many channels as specified. Then it is up to the decoder to fulfill the requirement. This is usually only important when playing videos with AC3 audio (like DVDs). In that case liba52 does the decoding by default and correctly downmixes the audio into the requested number of channels. Note: This option is honored by codecs (AC3 only), filters (surround) and audio output drivers (OSS at least). PrefAudio:K15@8B5 4@0925@ 0C48>2KE>40.Select the audio output driver. PrefAudio#AB0=02;8205B <0:A8<0;L=K9 C@>25=L CA8;5=8O 2 ?@>F5=B0E (?> C<>;G0=8N: 110). =0G5=85 200 ?>72>;8B 20< >B@53C;8@>20BL 3@><:>ABL 4> <0:A8<C<0 2 420 @070 2KH5 B5:CI53> C@>2=O. @8 7=0G5=8OE =865 100 =0G0;L=K9 >1J5< (:>B>@K9 @025= 100%) 1C45B ?@52KH0BL <0:A8<0;L=K9, GB>, =0?@8<5@, M:@0==>5 <5=N =5 <>65B >B>1@060BLAO ?@028;L=>. Sets the maximum amplification level in percent (default: 110). A value of 200 will allow you to adjust the volume up to a maximum of double the current level. With values below 100 the initial volume (which is 100%) will be above the maximum, which e.g. the OSD cannot display correctly. PrefAudioV>=B@>;L 3@><:>AB8 ?@>3@0<<=>3> >15A?5G5=8OSoftware volume control PrefAudioA8=E@>=870F8OSynchronization PrefAudio-B>B ?0@0<5B@ B0:65 ?@8<5=O5BAO 4;O C?@02;5=8O >B:;NG5=85< 72C:0..This option also applies for the mute control. PrefAudiorA?>;L7>20BL @53C;OB>@ 3@><:>AB8 ?@>3@0<<=>3> >15A?5G5=8OUse software volume control PrefAudio >1J5<Volume PrefAudio2>@<0;870F8O ?> C<>;G0=8NVolume normalization by default PrefAudio6A;8 MB>B ?0@0<5B@ 2:;NG5=, D09; 1C45B ?@8>AB0=>2;5=, :>340 >A=>2=>5 >:=> 1C45B A:@KB>. >340 >:=> 1C45B 2>AAB0=>2;5=>, 2>A?@>872545=85 1C45B 2>7>1=>2;5=>.If this option is enabled, the file will be paused when the main window is hidden. When the window is restored, playback will be resumed. PrefGeneralA;8 MB0 >?F8O 2:;NG5=0, ?@5420@8B5;L=K9 ?@>A<>B@ 2845> 1C45B >B>1@060BLAO, :>340 <KHL 1C45B CAB0=>2;5=0 =0 8=48:0B>@ 2K?>;=5=8O.lIf this option is enabled, the video preview will be displayed when the mouse is placed on the progress bar. PrefGeneralA;8 2K 87<5=8B5 4286>: 2>A?@>872545=8O =0 MPV, ?5@570?CAB8B5 Kylin Video.EIf you change the playback engine to MPV, please restart Kylin Video. PrefGeneralA;8 2K 87<5=8B5 4286>: 2>A?@>872545=8O =0 MPlayer, ?5@570?CAB8B5 Kylin Video.IIf you change the playback engine to MPlayer, please restart Kylin Video. PrefGeneralMPVMPV PrefGeneralMPlayerMPlayer PrefGeneral*0C70 ?@8 <8=8<870F88Pause when minimized PrefGeneral25E0=87< 2>A?@>872545=8O:Playback engine: PrefGenerald@5420@8B5;L=K9 ?@>A<>B@ ?@8 2>A?@>872545=88 2845>!Preview when the video is playing PrefGenerald@5420@8B5;L=K9 ?@>A<>B@ ?@8 2>A?@>872545=88 2845>Preview when video is playing PrefGeneralbK15@8B5 MPV 2 :0G5AB25 <5E0=87<0 2>A?@>872545=8OSelect MPV as playback engine PrefGeneraljK15@8B5 MPlayer 2 :0G5AB25 <5E0=87<0 2>A?@>872545=8O!Select MPlayer as playback engine PrefGeneral2B>AutoPrefPerformance2B>: >= ?KB05BAO 02B><0B8G5A:8 2:;NG8BL 0??0@0B=>5 45:>48@>20=85 A 8A?>;L7>20=85< ?5@2>3> 4>ABC?=>3> <5B>40.ZAuto: it tries to automatically enable hardware decoding using the first available method.PrefPerformance&>ABC?=K5 0@80=BK:Available options:PrefPerformance:MHCachePrefPerformanceMH 4;O D09;>2Cache for filesPrefPerformance2MH 4;O ;>:0;L=KE D09;>2:Cache for local files:PrefPerformanceMH 4;O ?>B>:>2Cache for streamsPrefPerformance MH 4;O ?>B>:>2:Cache for streams:PrefPerformance@0A:>48@>20BLDecodePrefPerformance0??0@0B=>5 45:>48@>20=85Hardware decodingPrefPerformanceKBKBPrefPerformance 8:B>NonePrefPerformancev5B: 1C45B 8A?>;L7>20BLAO B>;L:> ?@>3@0<<=>5 45:>48@>20=85.*None: only software decoding will be used.PrefPerformance!?5:B0:;L PerformancePrefPerformance2#AB0=02;8205B API 45:>48@>20=8O 0??0@0B=>3> 2845>. A;8 0??0@0B=>5 45:>48@>20=85 =52>7<>6=>, 2<5AB> MB>3> 1C45B 8A?>;L7>20BLAO ?@>3@0<<=>5 45:>48@>20=85.sSets the hardware video decoding API. If hardware decoding is not possible, software decoding will be used instead.PrefPerformance#AB0=02;8205B :>;8G5AB2> ?>B>:>2 4;O 45:>48@>20=8O. ">;L:> 4;O MPEG-1/2 8 H.264KSets the number of threads to use for decoding. Only for MPEG-1/2 and H.264PrefPerformanceH-B>B ?0@0<5B@ @01>B05B B>;L:> A mpv. This option only works with mpv.PrefPerformance-B>B ?0@0<5B@ C:07K205B, A:>;L:> ?0<OB8 (2 kBytes) A;54C5B 8A?>;L7>20BL ?@8 4>@01>B:5 URL-04@5A0.OThis option specifies how much memory (in kBytes) to use when precaching a URL.PrefPerformance-B>B ?0@0<5B@ C:07K205B, A:>;L:> ?0<OB8 (2 kBytes) A;54C5B 8A?>;L7>20BL ?@8 ?@5A;54>20=88 D09;0.PThis option specifies how much memory (in kBytes) to use when precaching a file.PrefPerformance,"5<K 4;O 45:>48@>20=8OThreads for decodingPrefPerformancej"5<K 4;O 45:>48@>20=8O (B>;L:> 4;O MPEG-1/2 8 H.264):/Threads for decoding (MPEG-1/2 and H.264 only):PrefPerformancevaapi-copy: :>?8@C5B 2845> >1@0B=> 2 >?5@0B82=CN ?0<OBL A8AB5<K. ">;L:> 4;O 3@0D8G5A:8E ?@>F5AA>@>2 Intel.Fvaapi-copy: it copies video back into system RAM. For Intel GPUs only.PrefPerformancevaapi: 4;O 2845>2KE>4>2 opengl 8 vaapi. ">;L:> 4;O 3@0D8G5A:8E ?@>F5AA>@>2 Intel.Cvaapi: for the opengl and vaapi video outputs. For Intel GPUs only.PrefPerformanceNvdpau: 4;O 2845>2KE>4>2 vdpau 8 opengl..vdpau: for the vdpau and opengl video outputs.PrefPerformance% 1 C:07K205B 8<O D09;0 2845> 157 @0AH8@5=8O,% 2 4>102;O5B 4-7=0G=>5 G8A;>, 70?>;=5==>5 =C;O<8.i%1 specifies the filename of the video without the extension, %2 adds a 4 digit number padded with zeros.PrefScreenShot$:;NG8BL A:@8=H>BKEnable screenshotsPrefScreenShot 0?:0:Folder:PrefScreenShot>;=K9 A?8A>: A?5F8D8:0B>@>2 H01;>=>2 <>6=> =09B8 ?> MB>9 AAK;:5:;For a full list of the template specifiers visit this link:PrefScreenShotp0?@8<5@,% 1 A>E@0=8B A:@8=H>B :0: moviename_0001.png.AFor example %1 would save the screenshot as 'moviename_0001.png'.PrefScreenShot*$>@<0B 4;O A:@8=H>B>2Format for screenshotsPrefScreenShot$>@<0B:Format:PrefScreenShot:45AL 2K <>65B5 C:070BL ?0?:C, 2 :>B>@>9 1C4CB A>E@0=5=K A=8<:8 M:@0=0, A45;0==K5 Kylin Video. A;8 ?0?:0 =5459AB28B5;L=0, DC=:F8O A:@8=H>B0 1C45B >B:;NG5=0.Here you can specify a folder where the screenshots taken by Kylin Video will be stored. If the folder is not valid the screenshot feature will be disabled.PrefScreenShot!:@8=H>BK ScreenshotsPrefScreenShot 0?:0 A:@8=H>B>2Screenshots folderPrefScreenShot K15@8B5 :0B0;>3Select a directoryPrefScreenShot*(01;>= 4;O A:@8=H>B>2Template for screenshotsPrefScreenShot(01;>=: Template:PrefScreenShot-B0 >?F8O ?>72>;O5B 2K1@0BL B8? D09;0 87>1@065=8O, 8A?>;L7C5<K9 4;O A>E@0=5=8O A=8<:>2 M:@0=0.QThis option allows one to choose the image file type used for saving screenshots.PrefScreenShotH-B>B ?0@0<5B@ @01>B05B B>;L:> A mpv. This option only works with mpv.PrefScreenShot-B>B ?0@0<5B@ C:07K205B H01;>= 8<5=8 D09;0, 8A?>;L7C5<K9 4;O A>E@0=5=8O A:@8=H>B>2.EThis option specifies the filename template used to save screenshots.PrefScreenShotK <>65B5 8A?>;L7>20BL MB>B ?0@0<5B@, GB>1K 2:;NG8BL 8;8 >B:;NG8BL 2>7<>6=>ABL 45;0BL A:@8=H>BK.QYou can use this option to enable or disable the possibility to take screenshots.PrefScreenShot45AL 2K <>65B5 87<5=8BL ;N1>9 :;NG52>9 O@;K:. ;O MB>3> 42064K I5;:=8B5 8;8 =06<8B5 enter G5@57 OG59:C 1KAB@>3> 4>ABC?0. aHere you can change any key shortcut. To do it double click or press enter over a shortcut cell.  PrefShortCut45AL 2K <>65B5 87<5=8BL ;N1>9 :;NG52>9 O@;K:. 'B>1K A45;0BL MB>, 42064K I5;:=8B5 8;8 =0G=8B5 22>48BL B5:AB ?> OG59:5 1KAB@>3> 4>ABC?0.aHere you can change any key shortcut. To do it double click or start typing over a shortcut cell. PrefShortCutShortCutShortCut PrefShortCutKAB@0O :;028H0 Shortcut Key PrefShortCut  540:B>@ O@;K:>2Shortcut editor PrefShortCut  MB>9 B01;8F5 2K <>65B5 87<5=8BL :;NG52K5 O@;K:8 1>;LH8=AB20 4>ABC?=KE 459AB289. 2064K I5;:=8B5 8;8 =06<8B5 :;028HC 22>40 4;O M;5<5=B0 8;8 =06<8B5 :=>?:C <b> 7<5=8BL O@;K: </ b>, GB>1K 2>9B8 2 480;>3>2>5 >:=> <i> 7<5=8BL O@;K: </ i>. ABL 420 A?>A>10 87<5=8BL O@;K:: 5A;8 :=>?:0 <b> Capture </ b> 2:;NG5=0, ?@>AB> =06<8B5 =>2CN :;028HC 8;8 :><18=0F8N :;028H, :>B>@K5 2K E>B8B5 =07=0G8BL 4;O 459AB28O (: A>60;5=8N, MB> =5 @01>B05B 4;O 2A5E :;028H ). A;8 :=>?:0 <b> Capture </ b> 2K:;NG5=0, 2K <>65B5 225AB8 ?>;=>5 8<O :;NG0.This table allows you to change the key shortcuts of most available actions. Double click or press enter on a item, or press the Change shortcut button to enter in the Modify shortcut dialog. There are two ways to change a shortcut: if the Capture button is on then just press the new key or combination of keys that you want to assign for the action (unfortunately this doesn't work for all keys). If the Capture button is off then you could enter the full name of the key. PrefShortCutPA5 AC1B8B@K, A>45@60I85 =0720=85 D8;L<0All subs containing movie name PrefSubtitles4A5 ?>4:0B0;>38 2 :0B0;>35All subs in directory PrefSubtitles2B>703@C7:0Autoload PrefSubtitles\$09;K AC1B8B@>2 Autoload (* .srt, * .sub ...):+Autoload subtitles files (*.srt, *.sub...): PrefSubtitles@>48@>2:0 AC1B8B@>2 ?> C<>;G0=8NDefault subtitle encoding PrefSubtitlesB>48@>2:0 AC1B8B@>2 ?> C<>;G0=8N:Default subtitle encoding: PrefSubtitles:>48@>20=85Encoding PrefSubtitles (@8DBFont PrefSubtitles,"> 65 8<O, GB> 8 D8;L<Same name as movie PrefSubtitlesK15@8B5 :>48@>2:C, :>B>@0O 1C45B 8A?>;L7>20BLAO 4;O D09;>2 AC1B8B@>2 ?> C<>;G0=8N.ESelect the encoding which will be used for subtitle files by default. PrefSubtitlesK15@8B5 O7K:, 4;O :>B>@>3> 2K E>B8B5, GB>1K :>48@>2:0 1K;0 C3040=0 02B><0B8G5A:8.PSelect the language for which you want the encoding to be guessed automatically. PrefSubtitlesLK15@8B5 <5B>4 02B>703@C7:8 AC1B8B@>2.$Select the subtitle autoload method. PrefSubtitles/7K: AC1B8B@>2Subtitle language PrefSubtitles!C1B8B@K Subtitles PrefSubtitlesR>?@>1C9B5 02B>>?@545;8BL 4;O MB>3> O7K:0#Try to autodetect for this language PrefSubtitlesT>?@>1C9B5 02B>>?@545;8BL 4;O MB>3> O7K:0:$Try to autodetect for this language: PrefSubtitles>340 MB0 >?F8O 2:;NG5=0, :>48@>2:0 AC1B8B@>2 1C45B ?@>25@5=0 02B><0B8G5A:8 4;O 40==>3> O7K:0. = 25@=5BAO : :>48@>2:5 ?> C<>;G0=8N, 5A;8 02B>>?@545;5=85 =5 C40ABAO. ;O MB>3> ?0@0<5B@0 B@51C5BAO MPlayer, A:><?8;8@>20==K9 A ?>445@6:>9 ENCA.When this option is on, the encoding of the subtitles will be tried to be autodetected for the given language. It will fall back to the default encoding if the autodetection fails. This option requires a MPlayer compiled with ENCA support. PrefSubtitles> C<>;G0=8NDefault PrefVideo@O<0O ?5@540G0Direct rendering PrefVideo&2>9=0O 1CD5@870F8ODouble buffering PrefVideo2>9=0O 1CD5@870F8O D8:A8@C5B <5@F0=85, A>E@0=OO 420 :04@0 2 ?0<OB8 8 >B>1@060O 8E ?@8 45:>48@>20=88 4@C3>3>. A;8 >= >B:;NG5=, >= <>65B =530B82=> ?>2;8OBL =0 M:@0==>5 <5=N, => G0AB> C40;O5B <5@F0=85 M:@0==>3> <5=N.Double buffering fixes flicker by storing two frames in memory, and displaying one while decoding another. If disabled it can affect OSD negatively, but often removes OSD flickering. PrefVideoH 8A>20=85 2845> A ?><>ILN D@03<5=B>2Draw video using slices PrefVideoF:;NG8BL ?>AB>1@01>B:C ?> C<>;G0=8N Enable postprocessing by default PrefVideo :;NG8BL / >B:;NG8BL @8A>20=85 2845> =0 16-?8:A5;L=KE A@570E / 480?07>=0E. A;8 >= >B:;NG5=, 25AL :04@ @8AC5BAO 70 >48= ?@>E>4. >65B 1KBL 1KAB@55 8;8 <54;5==55, 2 7028A8<>AB8 >B 2845>:0@BK 8 4>ABC?=>3> :5H0. = 459AB2C5B B>;L:> A :>45:0<8 libmpeg2 8 libavcodec.Enable/disable drawing video by 16-pixel height slices/bands. If disabled, the whole frame is drawn in a single run. May be faster or slower, depending on video card and available cache. It has effect only with libmpeg2 and libavcodec codecs. PrefVideoBA;8 >B<5G5=>, 2:;NG05BAO ?@O<0O @5=45@8=3 (=5 ?>445@68205BAO 2A5<8 :>45:0<8 8 2845>2KE>40<8) <br> <b> @54C?@5645=85: </ b> >65B 2K720BL ?>2@5645=85 OSD / SUB!If checked, turns on direct rendering (not supported by all codecs and video outputs)
Warning: May cause OSD/SUB corruption! PrefVideo"KE>4=>9 4@0925@:Output driver: PrefVideo>AB>1@01>B:0 1C45B 8A?>;L7>20BLAO ?> C<>;G0=8N 4;O =>2KE >B:@KBKE D09;>2.;Postprocessing will be used by default on new opened files. PrefVideoK15@8B5 4@0925@ 2845>2KE>40. % 1 >15A?5G8205B ;CGHCN ?@>872>48B5;L=>ABL.ASelect the video output driver. %1 provides the best performance. PrefVideo6@>3@0<<=K9 2845>M:20;0975@Software video equalizer PrefVideoPA?>;L7>20BL ?@>3@0<<=K9 2845>M:20;0975@Use software video equalizer PrefVideo&@0925@ 2845>2KE>40Video output driver PrefVideoK <>65B5 ?@>25@8BL MBC >?F8N, 5A;8 2845>M:20;0975@ =5 ?>445@68205BAO 3@0D8G5A:>9 :0@B>9 8;8 2K1@0==K< 4@0925@>< 2K2>40 2845>. <br> <b> @8<5G0=85: </ b> MB>B ?0@0<5B@ <>65B 1KBL =5A>2<5AB8< A =5:>B>@K<8 4@0925@0<8 2K2>40 2845>.You can check this option if video equalizer is not supported by your graphic card or the selected video output driver.
Note: this option can be incompatible with some video output drivers. PrefVideo<54;5==K9slow PrefVideo@8<5=OBLApplyPreferencesDialog 0C48>AudioPreferencesDialog>B<5=8BLCancelPreferencesDialog35=5@0;L=K9GeneralPreferencesDialog.Kylin Video - 0AB@>9:8Kylin Video - PreferencesPreferencesDialog %>@>H>OKPreferencesDialog!?5:B0:;L PerformancePreferencesDialog?@54?>GB5=85 PreferencePreferencesDialog!:@8=H>B ScreenShotPreferencesDialogKAB@0O :;028H0 Shortcut KeyPreferencesDialog!C1B8B@K SubtitlesPreferencesDialog 2845>VideoPreferencesDialog% 1 8% 2 %1 and %2QObject  %n minute(s)QObject  %n second(s)QObjectH-B> Kylin Vedio v.% 1 @01>B05B =0% 2'This is Kylin Vedio v. %1 running on %2QObject02B>autoQObject>B:;NG5=disabledQObject=58725AB=K9unknownQObject>102LB5 O@;K: Add shortcutShortcutGetter>B<5=8BLCancelShortcutGetter0E20B8BLCaptureShortcutGetter*0E20B =060B89 :;028HCapture keystrokesShortcutGetterG8AB8BLClearShortcutGetter7<5=8BL O@;K:Modify shortcutShortcutGetter %>@>H>OKShortcutGetterl06<8B5 :><18=0F8N :;028H, :>B>@CN 2K E>B8B5 =07=0G8BL,Press the key combination you want to assignShortcutGetter#40;8BL O@;K:Remove shortcutShortcutGetterC48> D>@<0BK Audio formatsSupportFormats5:>B>@K5 2845>D>@<0BK =5 ?>445@6820NB ?@5420@8B5;L=K9 ?@>A<>B@ 8 ?>8A: ?CB5< ?5@5B0A:820=8O, =0?@8<5@ swf.MSome video formats do not support preview and seek by dragging, e.g. the swf.SupportFormats"$>@<0BK AC1B8B@>2Subtitles formatsSupportFormats845> D>@<0BK Video formatsSupportFormats>B<5=8BLCancel TimeDialog@K30BL, GB>1K:Jump to: TimeDialog %>@>H>OK TimeDialog A:0BLSeek TimeDialogKylin Video Kylin Video TitleWidget2B>Auto TristateCombo=5BNo TristateCombo40Yes TristateCombo5B 8<5=8 D09;0 No filename VideoPreview*$09;% 1 =5 ACI5AB2C5BThe file %1 doesn't exist VideoPreview&;8=0 2845> @02=0 0The length of the video is 0 VideoPreview:@>F5AA mplayer =5 70?CA:0;AOThe mplayer process didn't run VideoPreview@>F5AA mplayer =5 =0G8=0;AO, ?KB0OAL ?>;CG8BL 8=D>@<0F8N > 2845>IThe mplayer process didn't start while trying to get info about the video VideoPreviewX@5<5==K9 :0B0;>3 (% 1) =5 <>65B 1KBL A>740=-The temporary directory (%1) can't be created VideoPreviewkylin-video/src/translations/kylin-video_fr.ts0000644000175000017500000034557313625147453020564 0ustar fengfeng AboutDialog About Sur Contributor Donateur <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> <! DOCTYPE HTML PUBLIC \ "- // W3C // DTD HTML 4.0 // EN " \ "http: //www.w3.org/TR/REC-html40/strict.dtd "> \ n <html> <head> <meta name = \ "qrichtext " content = \ "1 " /> <style type = \ "text / css "> \ np, li {espace blanc: pre-wrap; } \ n </ style> </ head> <body style = \ "font-family: 'Ubuntu'; font-size: 11pt; font-weight: 400; font-style: normal; "> \ n <p style = \ "- qt-paragraph-type: vide; marge supérieure: 0px; marge inférieure: 0px; marge gauche: 0px; marge droite: 0px; -qt-block-indent: 0; retrait du texte: 0px; \ "> <br /> </ p> </ body> </ html> OK D'accord Kylin Video is developed on the basis of SMPlayer, is a graphical interface for MPlayer and MPV. Kylin Video est développé sur la base de SMPlayer, est une interface graphique pour MPlayer et MPV. Kylin Video Kylin Vidéo Version: %1 Version 1 Using Qt %1 (compiled with Qt %2) Utiliser Qt% 1 (compilé avec Qt% 2) Playback engine: Moteur de lecture: Kylin Video is developed on the basis of %1, is a graphical interface for %2 and %3. Links: Code website: Developer's personal home page: ActionsEditor Shortcut Raccourci Description La description Name prénom Choose a filename Key files Confirm overwrite? The file %1 already exists. Do you want to overwrite? Error Erreur The file couldn't be saved Choose a file Choisissez un fichier The file couldn't be loaded AudioDelayDialog Audio delay Délai audio OK D'accord Cancel Annuler Audio delay (in milliseconds): Délai audio (en millisecondes): AudioEqualizer Audio Equalizer %1 Hz %1 kHz &Preset &Apply &Reset &Réinitialiser &Set as default values &Close Flat Classical Club Dance Full bass Full bass and treble Full treble Headphones Large hall Live Party Pop Reggae Rock Ska Soft Soft rock Techno Custom Use the current values as default values for new videos. Set all controls to zero. Information Information The current values have been stored to be used as default. BaseGui Kylin Video Kylin Vidéo Open Ouvrir Open &File... Fichier ouvert... Directory... Annuaire... &URL... & URL ... &Clear &Clair Recent files Fichiers récents Play control Contrôle de jeu Forward and rewind Avancer et rembobiner &Jump to... &Sauter à... Play Speed Vitesse de lecture Normal speed Vitesse normale Half speed Demi vitesse Double speed Double vitesse Speed -10% Vitesse -10% Speed +10% Vitesse + 10% Speed -4% Vitesse -4% Speed +4% Vitesse + 4% Speed -1% Vitesse -1% Speed +1% Vitesse + 1% Next Prochain Previous précédent &Auto &Auto &Disabled &Désactivé Aspect ratio Ratio d'aspect &Off &De &Rotate by 90 degrees clockwise and flip & Rotation de 90 degrés dans le sens des aiguilles d'une montre et retournez Rotate by 90 degrees &clockwise Faire pivoter de 90 degrés et dans le sens des aiguilles d'une montre Rotate by 90 degrees counterclock&wise Faire pivoter de 90 degrés dans le sens inverse des aiguilles d'une montre Rotate by 90 degrees counterclockwise and &flip Faire pivoter de 90 degrés dans le sens antihoraire et & retourner Fli&p image Fli & p image Mirr&or image Image miroir Frame rotation Rotation du cadre &Rotate &Tourner &Screenshot &Capture d'écran &Always &Toujours &Never &Jamais While &playing Pendant que je jouais S&tay on top S & tay sur le dessus Order play Jeu d'ordre Random play Jeu aléatoire List loop play Lecture en boucle de liste Play order Ordre de jeu &Stereo &Stéréo &4.0 Surround & 4.0 Surround &5.1 Surround & 5.1 Surround &6.1 Surround & 6.1 Surround &7.1 Surround & 7.1 Surround &Channels Et chaînes Audio l'audio &Mute &Muet Volume - Le volume - Volume + Volume + Delay - Retard - Delay + Retard + Set dela&y... Régler le délai... &Left channel & Canal gauche &Right channel & Canal droit &Mono &Mono Re&verse Sens inverse &Stereo mode & Mode stéréo Subtitles Les sous-titres Load... Charge... Subtitle &visibility Sous-titre et visibilité Preferences Préférences View &info and properties... Voir & info et propriétés ... Help Aidez-moi About &Kylin Video À propos de & Kylin Video Quit Quitter Open Homepage Ouvrir la page d'accueil Open screenshots folder Ouvrir le dossier des captures d'écran PlayList Playlist Play/Pause Jouer pause Stop Arrêtez Fullscreen Plein écran Video filters are disabled when using vdpau Les filtres vidéo sont désactivés lors de l'utilisation de vdpau -%1 -%1 +%1 +% 1 <empty> <vide> Confirm deletion - Kylin Video Confirmer la suppression - Kylin Video Delete the list of recent files? Supprimer la liste des fichiers récents? Choose a file Choisissez un fichier Multimedia Multimédia Video Vidéo Playlists Playlists All files Tous les fichiers Choose a directory Choisissez un répertoire &Jump to: &Sauter à: Kylin Video - Seek Kylin Video - Recherche Kylin Video - Subtitle delay Kylin Video - Retard sous-titre Subtitle delay (in milliseconds): Délai des sous-titres (en millisecondes): Error detected Erreur détectée Unfortunately this video can't be played. Malheureusement, cette vidéo ne peut pas être lue. The server returned '%1' Le serveur a renvoyé '% 1' Jump to %1 Aller à% 1 %1 Error % 1 erreur '%1' was not found! '% 1' n'a pas été trouvé! %1 has finished unexpectedly. % 1 a terminé de manière inattendue. Exit code: %1 Code de sortie:% 1 %1 failed to start. % 1 n'a pas pu démarrer. Please check the %1 path in preferences. Veuillez vérifier le chemin d'accès% 1 dans les préférences. %1 has crashed. % 1 s'est écrasé. See the log for more info. Voir le journal pour plus d'informations. Information Information The screenshot folder does not exist! Le dossier de capture d'écran n'existe pas! BottomWidget Stop Arrêtez Prev Prev Play / Pause Jouer pause Next Prochain Mute Muet Play List Playlist Core Screenshot NOT taken, folder not configured Capture d'écran NON prise, dossier non configuré Screenshots NOT taken, folder not configured Captures d'écran NON prises, dossier non configuré "A" marker set to %1 Marqueur \ "A " défini sur% 1 "B" marker set to %1 Marqueur \ "B " défini sur% 1 A-B markers cleared Marqueurs AB effacés Brightness: %1 Luminosité:% 1 Contrast: %1 Contraste:% 1 Gamma: %1 Gamma:% 1 Hue: %1 Teinte:% 1 Saturation: %1 Saturation:% 1 Speed: %1 Vitesse:% 1 Volume: %1 Volume 1 Subtitle delay: %1 ms Délai des sous-titres:% 1 ms Audio delay: %1 ms Délai audio:% 1 ms Subtitles on Sous-titres sur Subtitles off Sous-titres off Aspect ratio: %1 Ratio d'aspect:% 1 Mouse wheel seeks now Molette de la souris cherche maintenant Mouse wheel changes volume now La molette de la souris change le volume maintenant Mouse wheel changes zoom level now La molette de la souris change le niveau de zoom maintenant Mouse wheel changes speed now La molette de la souris change de vitesse maintenant Zoom: %1 Zoom:% 1 Screenshot saved as %1 Capture d'écran enregistrée en tant que% 1 Updating the font cache. This may take some seconds... Mise à jour du cache de polices. Cela peut prendre quelques secondes ... Buffering... Mise en mémoire tampon ... Starting... Départ... Font scale: %1 ErrorDialog MPlayer Error Erreur MPlayer OK D'accord icon icône Oops, something wrong happened Oups, quelque chose de faux est arrivé Error Erreur Show log Afficher le journal Hide log Masquer le journal EscTip Press ESC to exit full screen mode Appuyez sur Echap pour quitter le mode plein écran FileChooser Click to select a file or folder Cliquez pour sélectionner un fichier ou un dossier FilePropertiesDialog Kylin Video - Preferences Kylin Video - Préférences Properties Propriétés &Select the demuxer that will be used for this file: & Sélectionnez le démultiplexeur qui sera utilisé pour ce fichier: &Reset &Réinitialiser &Select the video codec: & Sélectionnez le codec vidéo: &Select the audio codec: & Sélectionnez le codec audio: Reset Réinitialiser Apply Appliquer OK D'accord Cancel Annuler Information Information Demuxer Demuxer Video codec Codec vidéo Audio codec Un codec audio GlobalShortcutsDialog Media &Play Media &Stop Media Pre&vious Media &Next Media P&ause Media &Record Volume &Mute Volume &Down Volume &Up Global Shortcuts Select the multimedia keys that kylin-video will capture. HelpDialog Kylin Video - Help Kylin Video - Aide Help Aidez-moi OK D'accord Supported formats Formats pris en charge InputURL Enter URL Entrer l'URL OK D'accord Cancel Annuler URL: URL: Languages Afar Au loin Abkhazian Abkhaze Avestan Avestan Afrikaans afrikaans Akan Akan Amharic Amharique Aragonese Aragonais Arabic arabe Assamese Assamais Avaric Avaric Aymara Aymara Azerbaijani azerbaïdjanais Bashkir Bachkir Belarusian Biélorusse Bulgarian bulgare Bihari Bihari Bislama Bislama Bambara Bambara Bengali bengali Tibetan Tibétain Breton Breton Bosnian Bosniaque Catalan catalan Chechen Tchétchène Corsican Corse Cree Cri Czech tchèque Church Église Chuvash Chuvash Welsh gallois Danish danois German allemand Divehi Divehi Dzongkha Dzongkha Ewe Ewe Greek grec English Anglais Esperanto espéranto Spanish Espanol Estonian estonien Basque basque Persian persan Fulah Fulah Finnish finlandais Fijian Fidjien Faroese Féroïen French français Frisian frison Irish irlandais Gaelic gaélique Galician Galicien Guarani Guarani Gujarati Gujarati Manx Mannois Hausa Hausa Hebrew hébreu Hindi hindi Hiri Hiri Croatian croate Haitian haïtien Hungarian hongrois Armenian arménien Herero Herero Chamorro Chamorro Interlingua Interlingua Indonesian indonésien Interlingue Interlingue Igbo Igbo Sichuan Sichuan Inupiaq Inupiaq Ido Je fais Icelandic islandais Italian italien Inuktitut Inuktitut Japanese Japonais Javanese Javanais Georgian géorgien Kongo Kongo Kikuyu Kikuyu Kuanyama Kuanyama Kazakh Kazakh Greenlandic groenlandais Khmer Khmer Kannada Kannada Korean coréen Kanuri Kanuri Kashmiri Cachemire Kurdish kurde Komi Komi Cornish cornouaillais Kirghiz kirghiz Latin Latin Luxembourgish Luxembourgeois Ganda Ganda Limburgan Limburgan Lingala Lingala Lao Lao Lithuanian lituanien Luba-Katanga Luba-Katanga Latvian letton Malagasy malgache Marshallese Marshallais Maori Maori Macedonian Macédonien Malayalam Malayalam Mongolian mongol Moldavian Moldave Marathi Marathi Malay malais Maltese maltais Burmese birman Nauru Nauru Bokmål Bokmål Ndebele Ndebele Nepali Népalais Ndonga Ndonga Dutch néerlandais Norwegian Nynorsk Nynorsk norvégien Norwegian norvégien Navajo Navajo Chichewa Chichewa Occitan Occitan Ojibwa Ojibwa Oromo Oromo Oriya Oriya Ossetian Ossète Panjabi Panjabi Pali Pali Polish polonais Pushto Pouchto Portuguese Portugais Quechua Quechua Romansh Le romanche Rundi Rundi Romanian roumain Russian russe Kinyarwanda Kinyarwanda Sanskrit sanskrit Sardinian Sarde Sindhi Sindhi Sami Sami Sango Sango Sinhala Cinghalais Slovak slovaque Slovene slovène Samoan Samoan Shona Shona Somali somali Albanian albanais Serbian serbe Swati Swati Sotho Sotho Sundanese Sundanese Swedish suédois Swahili Swahili Tamil Tamil Telugu Telugu Tajik Tadjik Thai thaïlandais Tigrinya Tigrinya Turkmen Turkmène Tagalog Tagalog Tswana Tswana Tonga Tonga Turkish turc Tsonga Tsonga Tatar tatar Twi Twi Tahitian Tahitien Uighur Ouïghour Ukrainian ukrainien Urdu Ourdou Uzbek Ouzbek Venda Venda Vietnamese vietnamien Volapük Volapük Walloon Wallon Wolof Wolof Xhosa Xhosa Yiddish yiddish Yoruba Yoruba Zhuang Zhuang Chinese chinois Zulu zoulou Arabic - Syria Arabe - Syrie Unicode Unicode UTF-8 UTF-8 Western European Languages Langues d'Europe occidentale Western European Languages with Euro Langues d'Europe occidentale avec l'euro Slavic/Central European Languages Langues slaves / d'Europe centrale Esperanto, Galician, Maltese, Turkish Espéranto, galicien, maltais, turc Old Baltic charset Ancien jeu de caractères balte Cyrillic cyrillique Modern Greek Grec moderne Baltic baltique Celtic celtique South-Eastern European Europe du Sud-Est Hebrew charsets Jeux de caractères hébreu Ukrainian, Belarusian Ukrainien, biélorusse Simplified Chinese charset Jeu de caractères chinois simplifié Traditional Chinese charset Jeu de caractères chinois traditionnel Japanese charsets Jeux de caractères japonais Korean charset Jeu de caractères coréen Thai charset Jeu de caractères thaï Cyrillic Windows Windows cyrillique Slavic/Central European Windows Fenêtres slaves / d'Europe centrale Arabic Windows Windows arabe Modern Greek Windows Windows grec moderne LineEditWithIcon Change Changement MPVProcess the '%1' filter is not supported by mpv le filtre '% 1' n'est pas pris en charge par mpv File: Video: Resolution: Frames per second: Estimated: Aspect Ratio: Bitrate: Dropped frames: Audio: Sample Rate: Channels: Audio/video synchronization: Cache fill: Used cache: MainWindow Kylin Video Kylin Vidéo Open Ouvrir Open &File... Fichier ouvert... Directory... Annuaire... &URL... & URL ... &Clear &Clair Recent files Fichiers récents Play control Contrôle de jeu Forward and rewind Avancer et rembobiner &Jump to... &Sauter à... Play Speed Vitesse de lecture Normal speed Vitesse normale Half speed Demi vitesse Double speed Double vitesse Speed -10% Vitesse -10% Speed +10% Vitesse + 10% Speed -4% Vitesse -4% Speed +4% Vitesse + 4% Speed -1% Vitesse -1% Speed +1% Vitesse + 1% Next Prochain Previous précédent &Auto &Auto &Disabled &Désactivé Aspect ratio Ratio d'aspect &Off &De &Rotate by 90 degrees clockwise and flip & Rotation de 90 degrés dans le sens des aiguilles d'une montre et retournez Rotate by 90 degrees &clockwise Faire pivoter de 90 degrés et dans le sens des aiguilles d'une montre Rotate by 90 degrees counterclock&wise Faire pivoter de 90 degrés dans le sens inverse des aiguilles d'une montre Rotate by 90 degrees counterclockwise and &flip Faire pivoter de 90 degrés dans le sens antihoraire et & retourner Fli&p image Fli & p image Mirr&or image Image miroir Frame rotation Rotation du cadre &Rotate &Tourner &Screenshot &Capture d'écran &Always &Toujours &Never &Jamais While &playing Pendant que je jouais S&tay on top S & tay sur le dessus Order play Jeu d'ordre Random play Jeu aléatoire List loop play Lecture en boucle de liste Play order Ordre de jeu &Stereo &Stéréo &4.0 Surround & 4.0 Surround &5.1 Surround & 5.1 Surround &6.1 Surround & 6.1 Surround &7.1 Surround & 7.1 Surround &Channels Et chaînes Audio l'audio &Mute &Muet Volume - Le volume - Volume + Volume + Delay - Retard - Delay + Retard + Set dela&y... Régler le délai... &Left channel & Canal gauche &Right channel & Canal droit &Mono &Mono Re&verse Sens inverse &Stereo mode & Mode stéréo Subtitles Les sous-titres Load... Charge... Subtitle &visibility Sous-titre et visibilité Preferences Préférences View &info and properties... Voir & info et propriétés ... Help Aidez-moi About &Kylin Video À propos de & Kylin Video Quit Quitter Show &info on OSD Size &+ Size &- Show times with &milliseconds Subtitles onl&y Volume + &Seek Volume + Seek + &Timer Volume + Seek + Timer + T&otal time &OSD PlayList Playlist Play/Pause Jouer pause Stop Arrêtez Fullscreen Plein écran Open Homepage Ouvrir la page d'accueil Open screenshots folder Ouvrir le dossier des captures d'écran Failed to add files! Video filters are disabled when using vdpau Les filtres vidéo sont désactivés lors de l'utilisation de vdpau -%1 -%1 +%1 +% 1 <empty> <vide> Confirm deletion - Kylin Video Confirmer la suppression - Kylin Video Delete the list of recent files? Supprimer la liste des fichiers récents? Choose a file Choisissez un fichier Multimedia Multimédia Video Vidéo Playlists Playlists All files Tous les fichiers Choose a directory Choisissez un répertoire &Jump to: &Sauter à: Kylin Video - Seek Kylin Video - Recherche Kylin Video - Subtitle delay Kylin Video - Retard sous-titre Subtitle delay (in milliseconds): Délai des sous-titres (en millisecondes): Error detected Erreur détectée Unfortunately this video can't be played. Malheureusement, cette vidéo ne peut pas être lue. The server returned '%1' Le serveur a renvoyé '% 1' Jump to %1 Aller à% 1 %1 Error % 1 erreur '%1' was not found! '% 1' n'a pas été trouvé! %1 has finished unexpectedly. % 1 a terminé de manière inattendue. Exit code: %1 Code de sortie:% 1 %1 failed to start. % 1 n'a pas pu démarrer. Please check the %1 path in preferences. Veuillez vérifier le chemin d'accès% 1 dans les préférences. %1 has crashed. % 1 s'est écrasé. See the log for more info. Voir le journal pour plus d'informations. Information Information The screenshot folder does not exist! Le dossier de capture d'écran n'existe pas! Warning - Using old MPlayer Please, update your MPlayer. (This warning won't be displayed anymore) The version of MPlayer (%1) installed on your system is obsolete. kylin-video can't work well with it: some options won't work, subtitle selection may fail... A:%1 B:%1 &Extrastereo &Karaoke Volume &normalization &Headphone optimization &Filters &Load external file... U&nload E&qualizer Reset audio equalizer MaskWidget Loading... MessageDialog Ok D'accord Cancel Annuler Yes Oui No Non MplayerProcess This option is not supported by MPlayer Cette option n'est pas supportée par MPlayer PlayListView Play Jouer Remove &selected Enlever la sélection &Delete file from disk & Supprimer le fichier du disque Playlist Playlist is empty La playlist est vide Add File Ajouter le fichier PlayList Playlist Clear Clair Add Ajouter Play Jouer Remove &selected Enlever la sélection &Delete file from disk & Supprimer le fichier du disque Reached the end of the playlist Atteint la fin de la playlist Select one or more files to open Sélectionnez un ou plusieurs fichiers à ouvrir Multimedia Multimédia All files Tous les fichiers Choose a directory Choisissez un répertoire Confirm remove Confirmer supprimer You're about to remove the file '%1' from the playlist. Vous êtes sur le point de supprimer le fichier '% 1' de la liste de lecture. Are you sure you want to proceed? Êtes-vous sur de vouloir continuer? Confirm deletion Confirmer la suppression You're about to DELETE the file '%1' from your drive. Vous êtes sur le point de supprimer le fichier '% 1' de votre lecteur. This action cannot be undone. Are you sure you want to proceed? Cette action ne peut pas être annulée. Êtes-vous sur de vouloir continuer? Deletion failed La suppression a échoué It wasn't possible to delete '%1' Il n'était pas possible de supprimer '% 1' Error deleting the file Erreur lors de la suppression du fichier It's not possible to delete '%1' from the filesystem. Il n'est pas possible de supprimer '% 1' du système de fichiers. Choose a filename Playlists Playlists Confirm overwrite? The file %1 already exists. Do you want to overwrite? You're about to remove the file from the playlist. You're about to Delete the files from your drive. Confirm remove all You're about to empty the playlist. Reached the top of the playlist PoweroffDialog The computer will shut down in %1 seconds. Press <b>Cancel</b> to abort shutdown. Ok D'accord Cancel Annuler PrefAudio Volume Le volume Global volume Volume global Use software volume control Utiliser le logiciel de contrôle du volume Max. Amplification: Max. Amplification: Volume normalization by default Normalisation de volume par défaut Synchronization Synchronisation Audio/video auto synchronization Synchronisation automatique audio / vidéo Factor: Facteur: Output driver: Pilote de sortie: Channels by default: Canaux par défaut: 2 (Stereo) 2 (stéréo) 4 (4.0 Surround) 4 (4.0 Surround) 6 (5.1 Surround) 6 (Surround 5.1) 7 (6.1 Surround) 7 (6.1 Surround) 8 (7.1 Surround) 8 (7.1 Surround) Default Défaut Audio output driver Pilote de sortie audio Select the audio output driver. Sélectionnez le pilote de sortie audio. %1 is the recommended one. Try to avoid %2 and %3, they are slow and can have an impact on performance. % 1 est le recommandé. Essayez d’éviter les% 2 et% 3, ils sont lents et peuvent avoir un impact sur les performances. Channels by default Canaux par défaut Requests the number of playback channels. MPlayer asks the decoder to decode the audio into as many channels as specified. Then it is up to the decoder to fulfill the requirement. This is usually only important when playing videos with AC3 audio (like DVDs). In that case liba52 does the decoding by default and correctly downmixes the audio into the requested number of channels. <b>Note</b>: This option is honored by codecs (AC3 only), filters (surround) and audio output drivers (OSS at least). Demande le nombre de canaux de lecture. MPlayer demande au décodeur de décoder l'audio en autant de canaux que spécifié. Ensuite, il appartient au décodeur de satisfaire à l'exigence. Cela n’est généralement important que lors de la lecture de vidéos avec l’audio AC3 (comme des DVD). Dans ce cas, liba52 effectue le décodage par défaut et mélange correctement le son dans le nombre de canaux demandé. <b> Remarque </ b>: cette option est respectée par les codecs (AC3 uniquement), les filtres (surround) et les pilotes de sortie audio (au moins OSS). If this option is checked, the same volume will be used for all files you play. If the option is not checked each file uses its own volume. Si cette option est cochée, le même volume sera utilisé pour tous les fichiers que vous lisez. Si l'option n'est pas cochée, chaque fichier utilise son propre volume. This option also applies for the mute control. Cette option s'applique également au contrôle muet. Software volume control Contrôle du volume du logiciel Check this option to use the software mixer, instead of using the sound card mixer. Cochez cette option pour utiliser le mélangeur logiciel au lieu d'utiliser le mélangeur de carte son. Max. Amplification Max. Amplification Sets the maximum amplification level in percent (default: 110). A value of 200 will allow you to adjust the volume up to a maximum of double the current level. With values below 100 the initial volume (which is 100%) will be above the maximum, which e.g. the OSD cannot display correctly. Définit le niveau d'amplification maximum en pourcentage (par défaut: 110). Une valeur de 200 vous permettra d’ajuster le volume jusqu’à doubler le niveau actuel. Avec des valeurs inférieures à 100, le volume initial (100%) sera supérieur au maximum, ce qui signifie que le menu OSD ne peut pas s'afficher correctement. Maximizes the volume without distorting the sound. Maximise le volume sans déformer le son. Gradually adjusts the A/V sync based on audio delay measurements. Ajuste progressivement la synchronisation A / V en fonction des mesures de retard audio. PrefGeneral Pause when minimized Pause quand minimisé MPlayer MPlayer MPV MPV Playback engine: Moteur de lecture: Preview when video is playing Aperçu lorsque la vidéo est en cours de lecture If this option is enabled, the file will be paused when the main window is hidden. When the window is restored, playback will be resumed. Si cette option est activée, le fichier sera suspendu lorsque la fenêtre principale est masquée. Lorsque la fenêtre est restaurée, la lecture reprendra. Preview when the video is playing Aperçu lorsque la vidéo est en cours de lecture If this option is enabled, the video preview will be displayed when the mouse is placed on the progress bar. Si cette option est activée, l'aperçu vidéo sera affiché lorsque la souris sera placée sur la barre de progression. Select MPlayer as playback engine Sélectionnez MPlayer comme moteur de lecture If you change the playback engine to MPlayer, please restart Kylin Video. Si vous modifiez le moteur de lecture en MPlayer, redémarrez Kylin Video. Select MPV as playback engine Sélectionnez MPV comme moteur de lecture If you change the playback engine to MPV, please restart Kylin Video. Si vous changez le moteur de lecture en MPV, redémarrez Kylin Video. PrefPerformance Cache Cache Cache for local files: Cache pour les fichiers locaux: KB KB Cache for streams: Cache pour les flux: Decode Décoder Threads for decoding (MPEG-1/2 and H.264 only): Fils de filetage pour le décodage (MPEG-1/2 et H.264 uniquement): Hardware decoding Décodage matériel None Aucun Auto Auto Performance Performance Threads for decoding Fils de décodage Sets the number of threads to use for decoding. Only for MPEG-1/2 and H.264 Définit le nombre de threads à utiliser pour le décodage. Uniquement pour MPEG-1/2 et H.264 Sets the hardware video decoding API. If hardware decoding is not possible, software decoding will be used instead. Définit l'API de décodage vidéo matériel. Si le décodage matériel n'est pas possible, le décodage logiciel sera utilisé à la place. Available options: Options disponibles: None: only software decoding will be used. Aucun: seul le décodage logiciel sera utilisé. Auto: it tries to automatically enable hardware decoding using the first available method. Auto: il tente d'activer automatiquement le décodage matériel à l'aide de la première méthode disponible. vdpau: for the vdpau and opengl video outputs. vdpau: pour les sorties vidéo vdpau et opengl. vaapi: for the opengl and vaapi video outputs. For Intel GPUs only. vaapi: pour les sorties vidéo opengl et vaapi. Pour les GPU Intel uniquement. vaapi-copy: it copies video back into system RAM. For Intel GPUs only. vaapi-copy: il copie la vidéo dans la RAM du système. Pour les GPU Intel uniquement. This option only works with mpv. Cette option ne fonctionne qu'avec mpv. Cache for files Cache pour les fichiers This option specifies how much memory (in kBytes) to use when precaching a file. Cette option spécifie la quantité de mémoire (en kilo-octets) à utiliser lors de la mise en cache d'un fichier. Cache for streams Cache pour les flux This option specifies how much memory (in kBytes) to use when precaching a URL. Cette option spécifie la quantité de mémoire (en kilo-octets) à utiliser lors de la mise en cache préalable d'une URL. PrefScreenShot Screenshots Captures d'écran Enable screenshots Activer les captures d'écran Folder: Dossier: Template: Modèle: Format: Format: Select a directory Sélectionnez un répertoire You can use this option to enable or disable the possibility to take screenshots. Vous pouvez utiliser cette option pour activer ou désactiver la possibilité de prendre des captures d'écran. Screenshots folder Dossier des captures d'écran Here you can specify a folder where the screenshots taken by Kylin Video will be stored. If the folder is not valid the screenshot feature will be disabled. Ici, vous pouvez spécifier un dossier dans lequel les captures d'écran prises par Kylin Video seront stockées. Si le dossier n'est pas valide, la fonctionnalité de capture d'écran sera désactivée. Template for screenshots Modèle pour les captures d'écran This option specifies the filename template used to save screenshots. Cette option spécifie le modèle de nom de fichier utilisé pour enregistrer les captures d'écran. For example %1 would save the screenshot as 'moviename_0001.png'. Par exemple,% 1 enregistre la capture d'écran sous le nom "moviename_0001.png". %1 specifies the filename of the video without the extension, %2 adds a 4 digit number padded with zeros. % 1 spécifie le nom de fichier de la vidéo sans l'extension,% 2 ajoute un nombre à 4 chiffres complété de zéros. For a full list of the template specifiers visit this link: Pour une liste complète des spécificateurs de modèles, visitez ce lien: This option only works with mpv. Cette option ne fonctionne qu'avec mpv. Format for screenshots Format pour les captures d'écran This option allows one to choose the image file type used for saving screenshots. Cette option permet de choisir le type de fichier image utilisé pour enregistrer des captures d'écran. PrefShortCut Here you can change any key shortcut. To do it double click or press enter over a shortcut cell. Ici, vous pouvez changer n'importe quel raccourci clavier. Pour ce faire, double-cliquez ou appuyez sur Entrée sur une cellule de raccourci. ShortCut Raccourci Here you can change any key shortcut. To do it double click or start typing over a shortcut cell. Ici, vous pouvez changer n'importe quel raccourci clavier. Pour ce faire, double-cliquez ou commencez à taper sur une cellule de raccourci. Shortcut Key Touche de raccourci Shortcut editor Éditeur de raccourci This table allows you to change the key shortcuts of most available actions. Double click or press enter on a item, or press the <b>Change shortcut</b> button to enter in the <i>Modify shortcut</i> dialog. There are two ways to change a shortcut: if the <b>Capture</b> button is on then just press the new key or combination of keys that you want to assign for the action (unfortunately this doesn't work for all keys). If the <b>Capture</b> button is off then you could enter the full name of the key. Ce tableau vous permet de modifier les raccourcis clavier de la plupart des actions disponibles. Double-cliquez ou appuyez sur entrée pour un élément, ou appuyez sur le bouton <b> Modifier le raccourci </ b> pour entrer dans la boîte de dialogue <i> Modifier le raccourci </ i>. Il existe deux manières de modifier un raccourci: si le bouton <b> Capturer </ b> est activé, appuyez simplement sur la nouvelle touche ou sur la nouvelle combinaison de touches à affecter à l'action (malheureusement, cela ne fonctionne pas pour toutes les touches). ). Si le bouton <b> Capturer </ b> est désactivé, vous pouvez entrer le nom complet de la clé. PrefSubtitles Autoload Chargement automatique Autoload subtitles files (*.srt, *.sub...): Chargement automatique des fichiers de sous-titres (* .srt, * .sub ...): Same name as movie Même nom que le film All subs containing movie name Tous les sous-marins contenant le nom du film All subs in directory Tous les sous-répertoires du répertoire Encoding Codage Default subtitle encoding: Encodage par défaut des sous-titres: Try to autodetect for this language: Essayez de détecter automatiquement cette langue: Subtitles Les sous-titres Select the subtitle autoload method. Sélectionnez la méthode de chargement automatique des sous-titres. Default subtitle encoding Encodage par défaut des sous-titres Select the encoding which will be used for subtitle files by default. Sélectionnez le codage qui sera utilisé par défaut pour les fichiers de sous-titres. Try to autodetect for this language Essayez de détecter automatiquement cette langue When this option is on, the encoding of the subtitles will be tried to be autodetected for the given language. It will fall back to the default encoding if the autodetection fails. This option requires a MPlayer compiled with ENCA support. Lorsque cette option est activée, le codage des sous-titres sera détecté automatiquement pour la langue donnée. Si l'encodage automatique échoue, le codage par défaut est rétabli. Cette option nécessite un MPlayer compilé avec le support ENCA. Subtitle language Langue des sous-titres Select the language for which you want the encoding to be guessed automatically. Sélectionnez la langue pour laquelle vous voulez que l'encodage soit deviné automatiquement. Font Police de caractère PrefVideo Enable postprocessing by default Activer le post-traitement par défaut Draw video using slices Dessiner une vidéo à l'aide de tranches Direct rendering Rendu direct Double buffering Double tampon Use software video equalizer Utiliser un égaliseur vidéo logiciel Output driver: Pilote de sortie: Default Défaut slow lent Video output driver Pilote de sortie vidéo Select the video output driver. %1 provides the best performance. Sélectionnez le pilote de sortie vidéo. % 1 offre les meilleures performances. Postprocessing will be used by default on new opened files. Le post-traitement sera utilisé par défaut sur les nouveaux fichiers ouverts. Software video equalizer Égaliseur vidéo logiciel You can check this option if video equalizer is not supported by your graphic card or the selected video output driver.<br><b>Note:</b> this option can be incompatible with some video output drivers. Vous pouvez cocher cette option si l'égaliseur vidéo n'est pas pris en charge par votre carte graphique ou le pilote de sortie vidéo sélectionné. <br> <b> Remarque: </ b> cette option peut être incompatible avec certains pilotes de sortie vidéo. If checked, turns on direct rendering (not supported by all codecs and video outputs)<br><b>Warning:</b> May cause OSD/SUB corruption! Si cette case est cochée, le rendu direct est activé (non pris en charge par tous les codecs et les sorties vidéo) <br> <b> Avertissement: </ b> Peut entraîner une corruption du système OSD / SUB! Double buffering fixes flicker by storing two frames in memory, and displaying one while decoding another. If disabled it can affect OSD negatively, but often removes OSD flickering. La double mise en mémoire tampon corrige le scintillement en stockant deux images en mémoire et en affichant une image tout en en décodant une autre. Si elle est désactivée, cela peut avoir un effet négatif sur l'OSD, mais élimine souvent le scintillement de l'OSD. Enable/disable drawing video by 16-pixel height slices/bands. If disabled, the whole frame is drawn in a single run. May be faster or slower, depending on video card and available cache. It has effect only with libmpeg2 and libavcodec codecs. Activer / désactiver le dessin vidéo par tranches / bandes de 16 pixels de hauteur. Si cette option est désactivée, l’ensemble du cadre est dessiné en un seul passage. Peut être plus rapide ou plus lent, en fonction de la carte vidéo et du cache disponible. Cela n'a d'effet qu'avec les codecs libmpeg2 et libavcodec. PreferencesDialog Kylin Video - Preferences Kylin Video - Préférences Preference Préférence Cancel Annuler Apply Appliquer OK D'accord General Général Video Vidéo Audio l'audio Performance Performance Subtitles Les sous-titres ScreenShot Capture d'écran Shortcut Key Touche de raccourci QObject %n second(s) %n minute(s) %1 and %2 % 1 et% 2 This is Kylin Vedio v. %1 running on %2 Ceci est Kylin Vedio v.% 1 en cours d'exécution sur% 2 disabled aspect_ratio désactivée auto aspect_ratio auto unknown aspect_ratio inconnu ShortcutGetter Modify shortcut Modifier le raccourci Add shortcut Ajouter un raccourci Remove shortcut Supprimer le raccourci Press the key combination you want to assign Appuyez sur la combinaison de touches que vous souhaitez attribuer. Clear Clair OK D'accord Cancel Annuler Capture Capturer Capture keystrokes Saisir les frappes SupportFormats Video formats Formats vidéo Audio formats Formats audio Subtitles formats Formats de sous-titres Some video formats do not support preview and seek by dragging, e.g. the swf. Certains formats vidéo ne prennent pas en charge la prévisualisation et la recherche par glissement, par exemple le swf. TimeDialog Seek Chercher OK D'accord Cancel Annuler Jump to: Sauter à: TitleWidget Kylin Video Kylin Vidéo TristateCombo Auto Auto Yes Oui No Non VideoPreview The length of the video is 0 La longueur de la vidéo est 0 The temporary directory (%1) can't be created Le répertoire temporaire (% 1) ne peut pas être créé The file %1 doesn't exist Le fichier% 1 n'existe pas The mplayer process didn't run Le processus mplayer n'a pas fonctionné No filename Pas de nom de fichier The mplayer process didn't start while trying to get info about the video Le processus mplayer n'a pas démarré alors que l'on tentait d'obtenir des informations sur la vidéo. The mpv process didn't run kylin-video/src/translations/kylin-video_zh_CN.qm0000644000175000017500000014402513625147453021132 0ustar fengfenga_eQ_+FTpatK.KafEGLNc\OX|R~1#L҄ T00SS)*U&9-0 v8X15H5DL YL LUsVEfUh)5-rf%xX (97 `A`^y<ȵ?5B@^)gSp ! J3"&$ezp(4*G+FOJ+LJZ<7Zة;0[d=A\o+B\ġ?\a\]?]Ø@^cVAF^AqgzUxiMRRqN$i6C#dHwoL/.+X5YCÙTN>?^.}lK""6swR`0a.d!$G,XIӞ S |o o})JhiϦz|H|m>~{XxhZ- T  x ea#RQ,wBex4WkRNIcr&~;~|SoK1[./&5Wx5i10w92f+HF61JͪD{N7Ȱ.͢Jؘƾ!)cPTa8c =m\_Nxq/5w+rC3C:Щ^'LEQNWWKdWq^Tk"11PzD~/UWR\oU|i $ҔQ3ZG~YzQ[$ 4r71PcV8S~][=Qd~geQ_&fj=jmrJ:-x6*Bs B8I;IIIdIlI+II^ EOk :!BCȘ"RVnU:P$A-u3p]$kS\$/*~&'&)Ę&|ܓ~'{2(쌏)QQjZ#x0 _G, '+1\,,_F --6#n%Bb(&~.0Rj:_Gn=QBaDMzBH2Kd3LLh)3x[`4;j3(v05|6~nX<u I@$AzE~7; .4g3J8l{98):O .;<`9Y+Ou+Oh,d=A=>+j+jϬ*E9<5{[R߮9ZOFQGA &rGAHI*}XIG_ `đcRW*TJD5U#`KTN5~<5~IoIojI%ɟ.5D֣R㞳2EE D) YwJL4g eMC!g#Qb%CI3rc-5FgEGZtuGZ1_3tbRW@5$`YGߏ ;{ #D@'ݙ0z/'&7 >Fl2YU C}Um$8pZ.7hI+q5Nt|~S&^>[B^E,.5Y\Z7` 63>kc|i I,,qo̪>XρQ-bo?'3lO 1| ]W ]io Q./ (q n  h>S h>Sz jO> q* u*  >! &_ c 5: by s^ s s ȏ.7 <!Z ʟ.6 xt ۊ3 G# 꽺2 " L"i K .8C " q q8 3?H l+ r\n r\ n` *Gdq 69 QO dUf fW hP: iP" }; #G lh 8E _| 4 %L U n <{V $4i K% l~ a ŷ( # tqw t IM ‹kPK ‹mPy < ΂ y; ۰;[ .< ~d Z^ z UD h T Kb ! e ,U 2~ 3z <'R CU@ E9I F O F gZ _4V gB] gJ h] kϳ l sBWG t9S xf .{ BQf E~t K .M IF ȟL L` x0J t]5 tU\ ] U]g  5 r > #>4 ̛:^l { C [ ^  I(^ U "1 &# &# (c* +[+ = B)V BR:I B:- F< N0$ O?U RV hۮ' zq |9; m \% wl8  1z j= %> sy X bi F^ 1s 3H P&Q  q:k EW (%rd *7E . Br 74<W :n4e ZtNp b g i8: k sЬ E 6@f p >& n > }@ <[ ##)FZ eO+>R21;^aDcaFlNlfssxa~~`>(m!bH@;3n (1%B dfNbA";H *z*I3gKX[GY8iY8ic.CixiTiTnuwz4NwZ/O9 LP>}Q=AiQsNAbout AboutDialog NxbX{ Code website: AboutDialog!s. Contributor AboutDialog_SрN*NN;uDeveloper's personal home page: AboutDialog_q Kylin Video AboutDialog@_qWN %1 ۈL_S f/ %2 T %3 vV_bSRMz0TKylin Video is developed on the basis of %1, is a graphical interface for %2 and %3. AboutDialogc:Links: AboutDialogxn[OK AboutDialog de>_dPlayback engine: AboutDialog.kcW(Ou( Qt %1 (u( Qt %2 )!Using Qt %1 (compiled with Qt %2) AboutDialog rHg,: %1 Version: %1 AboutDialog bNN*eN Choose a file ActionsEditor bNN*eNT Choose a filename ActionsEditorxnf/T&v?Confirm overwrite? ActionsEditorcϏ Description ActionsEditorError ActionsEditor.eN Key files ActionsEditorT yName ActionsEditor_cw.Shortcut ActionsEditor$eN %1 ][XW(0 ``󉁉vT?5The file %1 already exists. Do you want to overwrite? ActionsEditorelR}eNThe file couldn't be loaded ActionsEditorelO[XeNThe file couldn't be saved ActionsEditor^ Audio delayAudioDelayDialog^(ky):Audio delay (in milliseconds):AudioDelayDialogSmCancelAudioDelayDialogxn[OKAudioDelayDialog %1 Hz%1 HzAudioEqualizer %1 kHz%1 kHzAudioEqualizer ^u((&A)&ApplyAudioEqualizer Qs(&C)&CloseAudioEqualizer _SRM(&P)&PresetAudioEqualizer n(&R)&ResetAudioEqualizernN:؋P<(&S)&Set as default valuesAudioEqualizer WGaVhAudio EqualizerAudioEqualizerSQx ClassicalAudioEqualizerONPClubAudioEqualizer[NICustomAudioEqualizerfDanceAudioEqualizer^sWfFlatAudioEqualizerON Full bassAudioEqualizerONFull bass and trebleAudioEqualizerؗ Full trebleAudioEqualizer3g: HeadphonesAudioEqualizerO`o InformationAudioEqualizerY'S Large hallAudioEqualizersW:LiveAudioEqualizerm>[PartyAudioEqualizermALPopAudioEqualizervւfReggaeAudioEqualizerdGnRockAudioEqualizer\b@g vcR6nN:0Set all controls to zero.AudioEqualizereSaSkaAudioEqualizer{gSoftAudioEqualizer{dGn Soft rockAudioEqualizer u5[PfTechnoAudioEqualizer _SRMvP<]P[XO\N:؋P/fP\ Play / Pause BottomWidgetde>Rh Play List BottomWidgetN NN*Prev BottomWidgetP\kbStop BottomWidget"A"hnR0 %1"A" marker set to %1Core"B"hnR0 %1"B" marker set to %1CoreA-B h]ndA-B markers clearedCore~j*k: %1Aspect ratio: %1Core^: %1kyAudio delay: %1 msCore N^: %1Brightness: %1Core QN-... Buffering...Core[k^: %1 Contrast: %1Core[WOS)e>: %1Font scale: %1Core O=s: %1 Gamma: %1Core r: %1Hue: %1Core hnڏnfe9^Mouse wheel changes speed nowCore hnڏnfe9Mouse wheel changes volume nowCore hnڏnfe9)e>{I~"Mouse wheel changes zoom level nowCore hnڏn[OMMouse wheel seeks nowCoreqT^: %1Saturation: %1Core elՏۈL\O^Ub*V lg MneNY9+Screenshot NOT taken, folder not configuredCoreb*VO[XN: %1Screenshot saved as %1Core elՏۈL\O^Ub*V lg MneNY9,Screenshots NOT taken, folder not configuredCore ^: %1 Speed: %1CorekcW(_Y... Starting...Core[W^U^: %1kySubtitle delay: %1 msCore[W^UQs Subtitles offCore[W^U_T/ Subtitles onCore(kcW(fe[WOS[X0SQyҔ...6Updating the font cache. This may take some seconds...Core : %1 Volume: %1Core )e>: %1Zoom: %1CoreError ErrorDialoge_Hide log ErrorDialogMPlayer  MPlayer Error ErrorDialogxn[OK ErrorDialog ..QNOops, something wrong happened ErrorDialogf>y:e_Show log ErrorDialogiconicon ErrorDialogc ESC .QQh\O"Press ESC to exit full screen modeEscTipSUQN bNN*eNbeNY9 Click to select a file or folder FileChooser n(&R)&ResetFilePropertiesDialog bxVh(&S):&Select the audio codec:FilePropertiesDialog$ b\u(NkdeNvY u(Vh(&S):4&Select the demuxer that will be used for this file:FilePropertiesDialog bƘxVh(&S):&Select the video codec:FilePropertiesDialog^u(ApplyFilePropertiesDialog xVh Audio codecFilePropertiesDialogSmCancelFilePropertiesDialogY u(VhDemuxerFilePropertiesDialogO`o InformationFilePropertiesDialog_q - nKylin Video - PreferencesFilePropertiesDialogxn[OKFilePropertiesDialog\^`' PropertiesFilePropertiesDialognResetFilePropertiesDialog ƘxVh Video codecFilePropertiesDialog^.RHelp HelpDialog_q - ^.RKylin Video - Help HelpDialogxn[OK HelpDialog e/cvh<_Supported formats HelpDialogSmCancelInputURLQeQW@ Enter URLInputURLxn[OKInputURLQW@:URL:InputURL ?^TȉN Abkhazian Languages?l\Afar Languages SW^wQp Afrikaans Languages?WNAkan Languages ?\]\\Uighur LanguagesNLQKQp Ukrainian LanguagesNLQKQp v}OWeUkrainian, Belarusian LanguagesUnicodeUnicode LanguagesNL\Urdu Languages NLQyR+QKUzbek LanguageseVenda LanguagesSW Vietnamese Languages lbfnQKVolapük Languagest柙Walloon LanguagesZ\XWelsh Languagesk'Western European Languages Languages k'(k'v)$Western European Languages with Euro LanguageslmY+Wolof Languagesyф(Xhosa Languagesa{,~Yiddish Languages~]Yoruba LanguagesXZhuang LanguagesyVZulu Languagesfe9ChangeLineEditWithIcon YkO Aspect Ratio: MPVProcess/ƘT keAudio/video synchronization: MPVProcessAudio: MPVProcessOMsBitrate: MPVProcess [XXkQE Cache fill: MPVProcessS Channels: MPVProcess]N"Y1vu;bDropped frames: MPVProcessO0 Estimated: MPVProcesseNFile: MPVProcesskyf>y:vu;bepFrames per second: MPVProcessg^ Resolution: MPVProcessSh7s Sample Rate: MPVProcess Ou([X Used cache: MPVProcessƘVideo: MPVProcessmpvN e/c '%1' nVh'the '%1' filter is not supported by mpv MPVProcess %1 %1 Error MainWindow%1 T/RY1%0%1 failed to start. MainWindow%1 ]])n0%1 has crashed. MainWindow%1 ]aY~g_0%1 has finished unexpectedly. MainWindow4.0 s~X(&4) &4.0 Surround MainWindow5.1 s~X(&5) &5.1 Surround MainWindow6.1 s~X(&6) &6.1 Surround MainWindow7.1 s~X(&7) &7.1 Surround MainWindow Y~(&A)&Always MainWindow R(&A)&Auto MainWindow XS(&C) &Channels MainWindow nd(&C)&Clear MainWindow yu((&D) &Disabled MainWindowDRzOSX(&E) &Extrastereo MainWindownVh(&F)&Filters MainWindowOS3g:(&h)&Headphone optimization MainWindowlR0(&J)... &Jump to... MainWindowlR0(&J): &Jump to: MainWindowSab OK(&K)&Karaoke MainWindow]XS(&L) &Left channel MainWindowR}YeN(&L)...&Load external file... MainWindowSUXS(&M)&Mono MainWindow Y(&M)&Mute MainWindow NN (&N)&Never MainWindow\O^Uf>y:(&O)&OSD MainWindow Qs(&O)&Off MainWindowSXS(&R)&Right channel MainWindow eˏl(&R)&Rotate MainWindowzeeˏl90^^vl(&R)(&Rotate by 90 degrees clockwise and flip MainWindow\O^Ub*V(&S) &Screenshot MainWindowzOSX(&S)&Stereo MainWindowzOSXj!_(&S) &Stereo mode MainWindowQW@(&U)...&URL... MainWindow'%1' lg b~R0'%1' was not found! MainWindow(kdfTJ\N Qf>y:))(This warning won't be displayed anymore) MainWindow+%1+%1 MainWindow-%1-%1 MainWindow MainWindowA:%1A:%1 MainWindowQsN _qAbout &Kylin Video MainWindowb@g eN All files MainWindowu;bkO Aspect ratio MainWindowAudio MainWindowB:%1B:%1 MainWindow bNN*v_UChoose a directory MainWindow bNN*eN Choose a file MainWindowxnR d - _qConfirm deletion - Kylin Video MainWindow^ +Delay + MainWindow^ -Delay - MainWindowR dgveNRhT? Delete the list of recent files? MainWindow v_U... Directory... MainWindowSP ^ Double speed MainWindowWGaVh(&Q) E&qualizer MainWindow hmKR0Error detected MainWindowQNx: %1 Exit code: %1 MainWindowmReNY1%Failed to add files! MainWindowlVP(&P) Fli&p image MainWindow__Forward and rewind MainWindowu;beˏlFrame rotation MainWindowQh\O Fullscreen MainWindowSJ Half speed MainWindow^.RHelp MainWindow Information MainWindow lR0 %1 Jump to %1 MainWindow_q Kylin Video MainWindow_q - [OMKylin Video - Seek MainWindow_q - [W^U^Kylin Video - Subtitle delay MainWindow Rh_sde>List loop play MainWindow R}...Load... MainWindow\PVP(&O) Mirr&or image MainWindowYZOS Multimedia MainWindowN NN*Next MainWindowkc^8^ Normal speed MainWindowbS_Open MainWindowbS_eN(&F)... Open &File... MainWindow bS_N;uLb Open Homepage MainWindowbS_b*VeNY9Open screenshots folder MainWindowz^de> Order play MainWindowde>^ Play Speed MainWindowde>cR6 Play control MainWindowde>z^ Play order MainWindowde>RhPlayList MainWindowde>Rh Playlists MainWindowhg噖 yN-v %1 _0(Please check the %1 path in preferences. MainWindowfe`v MPlayer0Please, update your MPlayer. MainWindown Preferences MainWindowN NN*Previous MainWindowQQuit MainWindowg:de> Random play MainWindow Sv(&v)Re&verse MainWindow gveN Recent files MainWindownWGaVhReset audio equalizer MainWindowzeeˏl90^(&C)Rotate by 90 degrees &clockwise MainWindoweeˏl90^(&W)&Rotate by 90 degrees counterclock&wise MainWindoweeˏl90^^vl(&F)/Rotate by 90 degrees counterclockwise and &flip MainWindow nv(&T) S&tay on top MainWindowfYO`oS–e_0See the log for more info. MainWindown^(&Y)... Set dela&y... MainWindowW( OSD N-f>y:O`o(&i)Show &info on OSD MainWindowNkyf>y:eShow times with &milliseconds MainWindow Y'\ &+Size &+ MainWindow Y'\ &-Size &- MainWindow ^+1% Speed +1% MainWindow ^+10% Speed +10% MainWindow ^+4% Speed +4% MainWindow ^-1% Speed -1% MainWindow ^-10% Speed -10% MainWindow ^-4% Speed -4% MainWindowP\kbStop MainWindow[W^US`'(&V)Subtitle &visibility MainWindow[W^U^(ky):!Subtitle delay (in milliseconds): MainWindow[W^U Subtitles MainWindowN[W^U(&Y)Subtitles onl&y MainWindowb*VeNY9N [XW(%The screenshot folder does not exist! MainWindowg RVhV'%1'The server returned '%1' MainWindow|`v|~N [v MPlayer(%1)rHg,]e0_qelkc^8ЈL[: g N yelkc^8]O\ [W^U bSOY1eH...The version of MPlayer (%1) installed on your system is obsolete. kylin-video can't work well with it: some options won't work, subtitle selection may fail... MainWindowSx}YeN(&N)U&nload MainWindowbkIkdƘN de>)Unfortunately this video can't be played. MainWindowƘVideo MainWindow$Ou( VDPAU e\yu(ƘnVh+Video filters are disabled when using vdpau MainWindowZOSO`o(&I)...View &info and properties... MainWindowhQS(&N)Volume &normalization MainWindow +Volume + MainWindow+[OM(&S)Volume + &Seek MainWindow+[OM+eVh(&T)Volume + Seek + &Timer MainWindow"+[OM+eVh+`;e(&O)#Volume + Seek + Timer + T&otal time MainWindow -Volume - MainWindow(fTJ - kcW(Ou(ev MPlayerWarning - Using old MPlayer MainWindow_Sde>e(&P)While &playing MainWindow Loading... MaskWidgetSmCancel MessageDialogT&No MessageDialogxn[Ok MessageDialogf/Yes MessageDialogMPlayerN e/c y'This option is not supported by MPlayerMplayerProcessNxlvR d(&D)&Delete file from disk PlayListViewde>Play PlayListViewR d [(&S)Remove &selected PlayListViewmRAddPlaylistXReNAdd FilePlaylistb@g eN All filesPlaylistO`xn[~~!Are you sure you want to proceed?Playlist bNN*v_UChoose a directoryPlaylist bNN*eNT Choose a filenamePlaylistndClearPlaylistxnR dConfirm deletionPlaylistxnf/T&v?Confirm overwrite?PlaylistxnydConfirm removePlaylistxnydb@g eNConfirm remove allPlaylistYZOS MultimediaPlaylistde>RhPlayListPlaylist de>RhN:zzPlaylist is emptyPlaylistde>Rh PlaylistsPlaylist]~R0de>Rh^Reached the end of the playlistPlaylist]~R0de>RhvReached the top of the playlistPlaylist bNN*bYN*bS_veN Select one or more files to openPlaylist$eN %1 ][XW(0 ``󉁉vT?5The file %1 already exists. Do you want to overwrite?PlaylistkddO\N Sd0O`xn[~~?This action cannot be undone. Are you sure you want to proceed?Playlist\N`vxlvR deN01You're about to Delete the files from your drive.Playlist\nzzde>Rh0#You're about to empty the playlist.Playlist\Nde>RhN-ydeN02You're about to remove the file from the playlist.PlaylistSmCancelPoweroffDialogxn[OkPoweroffDialogc <b>Sm</b>.SmQsg:&Press Cancel to abort shutdown.PoweroffDialogu5\OW( %1 yQQsg:*The computer will shut down in %1 seconds.PoweroffDialogFcPOu( %10\=ϐQM %2 T %3 [N^_ab NO_qT`'0g%1 is the recommended one. Try to avoid %2 and %3, they are slow and can have an impact on performance. PrefAudio2 (zOSX) 2 (Stereo) PrefAudio4 (4.0 s~X)4 (4.0 Surround) PrefAudio6 (5.1 s~X)6 (5.1 Surround) PrefAudio7 (6.1 s~X)7 (6.1 Surround) PrefAudio8 (7.1 s~X)8 (7.1 Surround) PrefAudio 󘑏QqRAudio output driver PrefAudio/ƘRT ke Audio/video auto synchronization PrefAudio؋XSChannels by default PrefAudio ؋XS:Channels by default: PrefAudio0R kd yNOu(oNmVh N Ou(XSamVh0SCheck this option to use the software mixer, instead of using the sound card mixer. PrefAudio؋Default PrefAudioV[P:Factor: PrefAudioQh\@ Global volume PrefAudio,WN^vmKP<keet A/V T ke0AGradually adjusts the A/V sync based on audio delay measurements. PrefAudiodYgR kd y `de>vb@g eN\Ou(vT v0Ygkd yg*R kN*eN\Ou(Qv]v0If this option is checked, the same volume will be used for all files you play. If the option is not checked each file uses its own volume. PrefAudio gY'e>Y'sMax. Amplification PrefAudio gY'e>Y's:Max. Amplification: PrefAudioXlg Y1wvgY'02Maximizes the volume without distorting the sound. PrefAudio QqR:Output driver: PrefAudio^c[de>XSvep0MPlayer TJɉxVh\󘑉xbY\XS Qu1xVhge[skdlB0^8Sg W(de>^&g AC3 (kY DVD)vƘebMg u(0W(`QN \؋Ou( liba52 x^vbkcxnW0mTbvXSep0<b>la</b>: kd y x(N AC3)0nVh(s~X)T󘑏QqR(OSSbf~)N n፳0Requests the number of playback channels. MPlayer asks the decoder to decode the audio into as many channels as specified. Then it is up to the decoder to fulfill the requirement. This is usually only important when playing videos with AC3 audio (like DVDs). In that case liba52 does the decoding by default and correctly downmixes the audio into the requested number of channels. Note: This option is honored by codecs (AC3 only), filters (surround) and audio output drivers (OSS at least). PrefAudio b󘑏QqR0Select the audio output driver. PrefAudio֋ngY'e>Y'~R+vv~Rk(؋P<: 110)0Py:)\N kcxnf>y:0 Sets the maximum amplification level in percent (default: 110). A value of 200 will allow you to adjust the volume up to a maximum of double the current level. With values below 100 the initial volume (which is 100%) will be above the maximum, which e.g. the OSD cannot display correctly. PrefAudioOu(oNcR6Software volume control PrefAudioT keSynchronization PrefAudiokd yN_u(NYcR60.This option also applies for the mute control. PrefAudioOu(oNcR6Use software volume control PrefAudioVolume PrefAudio؋hQSVolume normalization by default PrefAudioLYgT/u(kd y N;zSYNr`e eN\fP\0zSSe \`bY de>0If this option is enabled, the file will be paused when the main window is hidden. When the window is restored, playback will be resumed. PrefGeneralnW(^gaN e Of>y:ƘV0lIf this option is enabled, the video preview will be displayed when the mouse is placed on the progress bar. PrefGeneral,YgO`Rcbde>_dN:MPV T/_q0EIf you change the playback engine to MPV, please restart Kylin Video. PrefGeneral4YgO`Rcbde>_dN:MPlayer T/_q0IIf you change the playback engine to MPlayer, please restart Kylin Video. PrefGeneralMPVMPV PrefGeneralMPlayerMPlayer PrefGeneral g\SefP\Pause when minimized PrefGeneral de>_dPlayback engine: PrefGeneralƘde>eۈL!Preview when the video is playing PrefGeneralƘde>eۈLPreview when video is playing PrefGeneral b MPV O\N:de>_dSelect MPV as playback engine PrefGeneral" b MPlayer O\N:de>_d!Select MPlayer as playback engine PrefGeneralRAutoPrefPerformance(RR\Ou({,NySu(vxle_0ZAuto: it tries to automatically enable hardware decoding using the first available method.PrefPerformance Su( yAvailable options:PrefPerformance[XCachePrefPerformance g,W0eN[XCache for filesPrefPerformanceg,W0eN[X:Cache for local files:PrefPerformancemA[XCache for streamsPrefPerformancemA[X:Cache for streams:PrefPerformancexDecodePrefPerformancexlNxHardware decodingPrefPerformanceKBKBPrefPerformanceeNonePrefPerformanceeNu(o0*None: only software decoding will be used.PrefPerformance`' PerformancePrefPerformance6nxlNx API0YgelOu(xl ROOu(o0sSets the hardware video decoding API. If hardware decoding is not possible, software decoding will be used instead.PrefPerformanceBnu(Nxv~z ep0NŐu(N MPEG-1/2 T H.264KSets the number of threads to use for decoding. Only for MPEG-1/2 and H.264PrefPerformancekd yNe/c mpv0 This option only works with mpv.PrefPerformanceBkd ySc[[X URL eOu(Y\Q[X(N KB N:SUOM)0OThis option specifies how much memory (in kBytes) to use when precaching a URL.PrefPerformancey:Q0.vdpau: for the vdpau and opengl video outputs.PrefPerformanceR%1 c[ƘveNT N T+bi\UT %2 W(NKTmR 4OMep N Yvu(0XkQE0i%1 specifies the filename of the video without the extension, %2 adds a 4 digit number padded with zeros.PrefScreenShot T/u(\O^Ub*VEnable screenshotsPrefScreenShoteNY9:Folder:PrefScreenShot [etj!gf{&Rhkdc;For a full list of the template specifiers visit this link:PrefScreenShotJOY %1 \O\b*VO[XN: moviename_0001.png  0AFor example %1 would save the screenshot as 'moviename_0001.png'.PrefScreenShotb*\Oh7_Format for screenshotsPrefScreenShoth<_:Format:PrefScreenShotbW(ّ`SNc[NN*_q\u(ge[XP\O^Ub*VveNY90YgeNY9f/eeHv \O^Ub*VR\yu(0Here you can specify a folder where the screenshots taken by Kylin Video will be stored. If the folder is not valid the screenshot feature will be disabled.PrefScreenShot\O^Ub*V ScreenshotsPrefScreenShot\O^Ub*VeNY9Screenshots folderPrefScreenShot bNN*v_USelect a directoryPrefScreenShot \O^Ub*Vj!gTemplate for screenshotsPrefScreenShotj!g Template:PrefScreenShotkd y` bƘb*Vvh<_0QThis option allows one to choose the image file type used for saving screenshots.PrefScreenShotkd yNŐu(Nmpv0 This option only works with mpv.PrefScreenShot*kd y[NIO[XƘb*\OeOu(veNT j!g0EThis option specifies the filename template used to save screenshots.PrefScreenShot0`SNOu(kd yT/u(byu(f/T&SNۈL\O^Ub*V0QYou can use this option to enable or disable the possibility to take screenshots.PrefScreenShotNW(ّ`SNfe9NOU_cw.0PZR0Np W(NN*_cw.SUQChfe9_cw.</b> c SQe <i>Oe9_cw.</i> [hF0g N$yelgefe9_cw.: Yg <b>cUcI</b> c ]T/u( NHSc N ``cm>~kdRO\vec .b~T.(_Wa^vN u(Nb@g vc .)0Yg <b>cUcI</b> c ]Qs NH`SN叓Qec .v[etT y0This table allows you to change the key shortcuts of most available actions. Double click or press enter on a item, or press the Change shortcut button to enter in the Modify shortcut dialog. There are two ways to change a shortcut: if the Capture button is on then just press the new key or combination of keys that you want to assign for the action (unfortunately this doesn't work for all keys). If the Capture button is off then you could enter the full name of the key. PrefShortCutb@g ST+_qrGT yv[W^UAll subs containing movie name PrefSubtitlesv_UN-vb@g [W^UAll subs in directory PrefSubtitlesRR}[W^UeNAutoload PrefSubtitles2RR}[W^UeN(*.srt0*.sub...):+Autoload subtitles files (*.srt, *.sub...): PrefSubtitles ؋[W^UxDefault subtitle encoding PrefSubtitles؋[W^Ux:Default subtitle encoding: PrefSubtitlesxEncoding PrefSubtitles[WOSFont PrefSubtitlesN_qrGvT yvT Same name as movie PrefSubtitles b\u(N[W^UeNv؋x0ESelect the encoding which will be used for subtitle files by default. PrefSubtitles" b``u(NRcmKxv0PSelect the language for which you want the encoding to be guessed automatically. PrefSubtitles b[W^UvRR}el0$Select the subtitle autoload method. PrefSubtitles[W^USubtitle language PrefSubtitles[W^U Subtitles PrefSubtitles\ՁRhmKkd#Try to autodetect for this language PrefSubtitles\ՁRhmKkd:$Try to autodetect for this language: PrefSubtitles_T/kd ye \\ՁRhmKc[v[W^Ux0YgRhmKY1% [\VR0؋vx0kd y MPlayer g ENCA e/c0When this option is on, the encoding of the subtitles will be tried to be autodetected for the given language. It will fall back to the default encoding if the autodetection fails. This option requires a MPlayer compiled with ENCA support. PrefSubtitles؋Default PrefVideovcn2gDirect rendering PrefVideoSQDouble buffering PrefVideoW(Q[XN-[XPN$^' W(f>y:N^'vT exSN^'vSQgeOY p0Ygyu([O[ OSD (\O^Uf>y:)Nub_qT OF^8^8Sd OSD (\O^Uf>y:)vp0Double buffering fixes flicker by storing two frames in memory, and displaying one while decoding another. If disabled it can affect OSD negatively, but often removes OSD flickering. PrefVideoOu(RrGe_~R6ƘDraw video using slices PrefVideo؋T/u(TgYt Enable postprocessing by default PrefVideoT/u(/yu(N 16-P} vrG/^&e_~R6Ƙ0Ygyu( \Nk!ЈL~R6etN*^'0Sf_bfab SQNf>SaTSu(v[X0[S[ libmpeg2 T libavcodec xVhg eHg0Enable/disable drawing video by 16-pixel height slices/bands. If disabled, the whole frame is drawn in a single run. May be faster or slower, depending on video card and available cache. It has effect only with libmpeg2 and libavcodec codecs. PrefVideoYgR \bS_vcn2g(N b@g vxVhTƘQe/c)<br><b>fTJ:</b> SO[ OSD (\O^Uf>y:)/SUB v!If checked, turns on direct rendering (not supported by all codecs and video outputs)
Warning: May cause OSD/SUB corruption! PrefVideo QqR:Output driver: PrefVideo"؋W(ebS_veNN Ou(TgYt0;Postprocessing will be used by default on new opened files. PrefVideo( bƘQqR0%1 ScOgOs`'0ASelect the video output driver. %1 provides the best performance. PrefVideoOu(oNƘWGaVhSoftware video equalizer PrefVideoOu(oNƘWGaVhUse software video equalizer PrefVideo ƘQqRVideo output driver PrefVideoYg`vf>y:Sabb@ vƘQqRN e/cƘWGaVh `SNR kd y0<br><b>la:</b> kd ySNgNƘQqRN Q|[0You can check this option if video equalizer is not supported by your graphic card or the selected video output driver.
Note: this option can be incompatible with some video output drivers. PrefVideoabslow PrefVideo^u(ApplyPreferencesDialogAudioPreferencesDialogSmCancelPreferencesDialog^8GeneralPreferencesDialog_q - nKylin Video - PreferencesPreferencesDialogxn[OKPreferencesDialog`' PerformancePreferencesDialogn PreferencePreferencesDialog\O^Ub*V ScreenShotPreferencesDialog_cw. Shortcut KeyPreferencesDialog[W^U SubtitlesPreferencesDialogƘVideoPreferencesDialog%1 T %2 %1 and %2QObject%nR %n minute(s)QObject%ny %n second(s)QObject*f/ЈLW( %2 N v_q v. %1'This is Kylin Vedio v. %1 running on %2QObjectRautoQObjectyu(disabledQObjectg*wunknownQObject mR_cw. Add shortcutShortcutGetterSmCancelShortcutGettercUcICaptureShortcutGettercUcIc .Capture keystrokesShortcutGetterndClearShortcutGetter Oe9_cw.Modify shortcutShortcutGetterxn[OKShortcutGetterc N ``RMv~T.,Press the key combination you want to assignShortcutGetter yd_cw.Remove shortcutShortcutGetterh<_ Audio formatsSupportFormats2NNƘh<_N e/cT hbR[OM kYswf0MSome video formats do not support preview and seek by dragging, e.g. the swf.SupportFormats[W^Uh<_Subtitles formatsSupportFormatsƘh<_ Video formatsSupportFormatsSmCancel TimeDialoglR0:Jump to: TimeDialogxn[OK TimeDialog[OMSeek TimeDialog_q Kylin Video TitleWidgetRAuto TristateComboT&No TristateCombof/Yes TristateCombo lg eNT  No filename VideoPrevieweN %1 N [XW(The file %1 doesn't exist VideoPreviewƘv^f/ 0The length of the video is 0 VideoPreviewMPlayer z lg ЈLThe mplayer process didn't run VideoPreview0VS։ƘO`oe MPlayer z lg T/RIThe mplayer process didn't start while trying to get info about the video VideoPreviewMPV z lg ЈLThe mpv process didn't run VideoPreviewelR^N4ev_U(%1)-The temporary directory (%1) can't be created VideoPreviewkylin-video/src/translations/kylin-video_zh_CN.ts0000644000175000017500000153577713625147453021166 0ustar fengfeng AboutDialog Kylin Video is a graphical interface for MPlayer and MPV. 麒麟影音是MPlayer和MPV的图形化前端。 Kylin Video is developed on the basis of SMPlayer, is a graphical interface for MPlayer and MPV. 麒麟影音基于SMPlayer进行开发,是MPlayer和MPV的图形化前端。 Kylin Video is developed on the basis of %1, is a graphical interface for %2 and %3. 麒麟影音基于 %1 进行开发,是 %2 和 %3 的图形化前端。 Version: %1 版本: %1 Kylin Video 麒麟影音 Playback engine: 播放引擎: Links: 链接: Code website: 代码托管: Developer's personal home page: 开发者个人主页: Official website: 官方网站: Support forum: 支持论坛: Kylin Video is a graphical interface for %1. 麒麟影音是 %1 的图形化前端 Click here to know the translators from the transifex teams 点击这里查看 transifex 翻译团队的成员 Many people contributed with translations. 许多人贡献了翻译。 You can also help to translate SMPlayer into your own language. 你也可以帮助翻译视频播放器 Visit %1 and join a translation team. 访问 %1 并加入翻译团队 Using %1 使用 %1 SMPlayer is a graphical interface for %1 and %2. 视频播放器是 %1 和 %2 的图形化前端 Subtitles service powered by %1 字幕服务由 %1 提供 <b>%1</b> (%2) <b>%1</b> (%2) About SMPlayer 关于视频播放器 About Kylin Video 关于 麒麟影音 Page 佩奇 &Info 信息(&I) icon 图标 &Contributions 贡献(&C) &Translators 翻译(&T) &License 许可证(&L) Portable Edition 便携版 Using Qt %1 (compiled with Qt %2) 正在使用 Qt %1 (用 Qt %2 编译) SMPlayer logo by %1 视频播放器标志由 %1 设计 Read the entire license 阅读整个许可证 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 这是自由软件,你可以在自由软件基金会发布的GNU通用公共许可证的诸条款之下,重新发布和(或者)修改它。许可证为第二版或者任何之后的版本。 Read a translation 阅读翻译 OK 确定 Kylin Video logo by %1 麒麟影音标志由 %1 设计 Packages for Windows created by %1 适用于 Windows 的软件包由 %1 创建 Many other people contributed with patches. See the Changelog for details. 还有许多人贡献了补丁。有关详细信息,请参阅变更日志(Changelog)。 You can also help to translate Kylin Video into your own language. 你也可以帮助翻译麒麟影音。 About 关于 Contributor 贡献者 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> ActionsEditor Name 名称 Description 描述 Shortcut 快捷键 &Save 保存(&S) &Load 加载(&L) Key files 键文件 Choose a filename 选择一个文件名 Confirm overwrite? 确认是否覆盖? The file %1 already exists. Do you want to overwrite? 文件 %1 已存在。 您想要覆盖吗? Choose a file 选择一个文件 Error 错误 The file couldn't be saved 无法保存该文件 The file couldn't be loaded 无法加载该文件 &Change shortcut... 更改快捷键(&C)... AudioDelayDialog Audio delay 音频延迟 OK 确定 Cancel 取消 Audio delay (in milliseconds): 音频延迟(毫秒): AudioEqualizer Audio Equalizer 音频均衡器 %1 Hz %1 Hz %1 kHz %1 kHz &Preset 当前(&P) &Apply 应用(&A) &Reset 重置(&R) &Set as default values 设置为默认值(&S) &Close 关闭(&C) Flat 平坦 Classical 古典 Club 俱乐部 Dance 舞曲 Full bass 重低音 Full bass and treble 超重低音 Full treble 超高音 Headphones 耳机 Large hall 大厅 Live 现场 Party 派对 Pop 流行 Reggae 雷盖舞曲 Rock 摇滚 Ska 斯卡 Soft 轻柔 Soft rock 轻摇滚 Techno 电子舞曲 Custom 自定义 Use the current values as default values for new videos. 使用当前的值作为新视频的默认值。 Set all controls to zero. 将所有的控制都设置为零。 Information 信息 The current values have been stored to be used as default. 当前的值已被储存作为默认值使用。 BaseGui &Open 打开(&O) SMPlayer 视频播放器 - SMPlayer - 视频播放器 &Play 播放(&P) &Video 视频(&V) &Audio 音频(&A) &Subtitles 字幕(&S) &Browse 浏览(&B) Op&tions 选项(&T) &Help 帮助(&H) &File... 文件(&F)... D&irectory... 目录(&i)... &Playlist... 播放列表(&P)... &DVD from drive DVD 驱动器(&D) D&VD from folder... DVD 文件夹(&V)... &URL... 网址(&U)... &Clear 清除(&C) &Recent files 最近的文件(&R) P&lay 播放(&L) &Pause 暂停(&P) &Stop 停止(&S) &Frame step 逐帧步进(&F) &Normal speed 正常速度(&N) &Double speed 双倍速度(&D) Speed &-10% 速度-10%(&-) Speed &+10% 速度+10%(&+) &Off closed captions menu 关(&O) Sp&eed 速度(&E) &Repeat 重复(&R) &Fullscreen 全屏(&F) &Compact mode 简洁模式(&C) Si&ze 大小(&Z) &Aspect ratio 宽高比(&A) &None 无(&N) &Lowpass5 Lowpass5(&L) Linear &Blend 线性混合(&B) &Deinterlace 去交错(&D) &Postprocessing 后期处理(&P) &Autodetect phase 自动检测相位(&A) &Deblock 去块(&D) De&ring 去环(&R) Add n&oise 增噪(&O) F&ilters 过滤器(&I) &Equalizer 均衡器(&E) &Screenshot 屏幕截图(&S) S&tay on top 置顶(&T) &Extrastereo 附加立体声(&E) &Karaoke 卡拉 OK(&K) &Filters 过滤器(&F) &Stereo 立体声(&S) &4.0 Surround 4.0 环绕声(&4) &5.1 Surround 5.1 环绕声(&5) &Channels 声道(&C) &Left channel 左声道(&L) &Right channel 右声道(&R) &Stereo mode 立体声模式(&S) &Mute 静音(&M) Volume &- 音量 &- Volume &+ 音量 &+ &Delay - 延迟-(&D) D&elay + 延迟+(&E) &Select 选择(&S) &Load... 加载(&L)... Delay &- 延迟 &- Delay &+ 延迟 &+ &Up 向上(&U) &Down 向下(&D) &Title 标题(&T) &Chapter 章节(&C) &Angle 角度(&A) &Playlist 播放列表(&P) &Disabled 禁用(&D) &OSD 屏幕显示(&O) &View logs 查看日志(&V) P&references 首选项(&R) About &SMPlayer 关于视频播放器(&S) <empty> <空> Confirm deletion - Kylin Video 确认删除 - 麒麟影音 Video 视频 Audio 音频 Failed to add files! 添加文件失败! Open 打开 Open &File... 打开文件(&F)... Play control 播放控制 Forward and rewind 快进快退 Play Speed 播放速度 Show &info on OSD 在 OSD 中显示信息(&i) Show times with &milliseconds 以毫秒显示时间 Open Homepage 打开主界面 Open screenshots folder 打开截图文件夹 PlayList 播放列表 Play/Pause 播放/暂停 Fullscreen 全屏 Playlists 播放列表 All files 所有文件 Choose a file 选择一个文件 &YouTube%1 browser YouTube%1 浏览器(&Y) &Donate / Share with your friends 捐赠 / 分享给您的朋友 (&D) SMPlayer - Information 视频播放器 - 信息 The CDROM / DVD drives are not configured yet. The configuration dialog will be shown now, so you can do it. CDROM/DVD 驱动器尚未配置。 现在将显示配置对话框,以便您可以配置它。 Select the Blu-ray folder 选择Blu-ray文件夹 Choose a directory 选择一个目录 Subtitles 字幕 Kylin Video - Seek 麒麟影音 - 定位 Kylin Video - Audio delay 麒麟影音 - 音频延迟 Kylin Video - Subtitle delay 麒麟影音 - 字幕延迟 Error detected 检测到错误 Unfortunately this video can't be played. 抱歉此视频不能播放 Playing %1 正在播放 %1 Pause 暂停 Stop 停止 Play / Pause 播放/暂停 Pause / Frame step 暂停/逐帧步进 U&nload 卸载外部文件(&N) V&CD VCD(&C) C&lose 关闭(&L) View &info and properties... 媒体信息(&I)... Zoom &- 缩放 &- Kylin Video 麒麟影音 Directory... 目录... Recent files 最近的文件 Play 播放 Speed 速度 Normal speed 正常速度 Half speed 半速 Double speed 双倍速度 Speed -10% 速度-10% Speed +10% 速度+10% Speed -4% 速度-4% Speed +4% 速度+4% Speed -1% 速度-1% Speed +1% 速度+1% Next 下一个 Previous 上一个 Frame rotation 画面旋转 Shortcuts 快捷键 Order play 顺序播放 Random play 随机播放 List loop play 列表循环播放 Play order 播放顺序 Help 帮助 The screenshot folder does not exist! 截图文件夹不存在! Zoom &+ 缩放 &+ &Reset 重置(&R) Move &left 向左移动(&L) Move &right 向右移动(&R) Move &up 向上移动(&U) Move &down 向下移动(&d) Zoom 缩放 Aspect ratio 画面比例 Postprocessing 后期处理质量 Autodetect phase 自动检测相位 Deblock 去块 Dering 去环 Debanding (gradfun) 去带(Gradfun) Add noise 增噪 Add black borders 添加黑边 Software scaling 软件缩放 Filters 过滤器 Denoise 降噪 Blur/Sharp 模糊/锐化 Volume - 音量 - Volume + 音量 + Delay - 延迟 - Delay + 延迟 + Load... 加载... Preferences 设置 About &Kylin Video 关于 麒麟影音 Quit 退出 &Previous line in subtitles 上一行字幕(&P) N&ext line in subtitles 下一行字幕(&e) %1 log %1 日志 SMPlayer log 视频播放器日志 -%1 -%1 +%1 +%1 Dec volume (2) 降低音量(2) &Blu-ray from drive 从驱动器播放 &Blu-ray (&B) Blu-&ray from folder... 从文件夹播放 Blu-ray(&B)... Fra&me back step 返回上一帧(&m) &Half speed 半速(&H) Thumb&nail Generator... 缩略图生成器…(&n) Stereo &3D filter Stereo &3D 滤镜 Debanding (&gradfun) 去带(Gradfun)(&g) Seek to next subtitle 使用下个字幕 Seek to previous subtitle 使用上个字幕 Use custo&m style 使用自定义风格 (&m) Find subtitles at &OpenSubtitles.org... 在 OpenSubtitles.org 上查找字幕(&O)... &Default subfps menu 默认(&D) First Steps &Guide 第一步指南(&G) Update &Youtube code 更新Youtube代码(&Y) &Open configuration folder 打开配置文件夹(&O) Size &+ 大小 &+ Size &- 大小 &- Inc volume (2) 增加音量(2) Exit fullscreen 退出全屏 OSD - Next level 屏幕显示 - 下一层 Dec contrast 降低对比度 Inc contrast 增加对比度 Dec brightness 降低亮度 Inc brightness 增加亮度 Dec hue 降低色调 Inc hue 增加色调 Dec saturation 降低饱和度 Dec gamma 降低伽玛 Next audio 下一个音轨 Next subtitle 下一个字幕 Next chapter 下一个章节 Previous chapter 上一个章节 Show playback time on OSD 在 OSD 上显示播放时间 De&noise 降噪(&n) Blur/S&harp 模糊/锐化(&h) &Off denoise menu 关(&O) &Normal denoise menu 标准(&N) &Soft denoise menu 柔和(&S) &None unsharp menu 无(&N) &Blur unsharp menu 模糊(&B) &Sharpen unsharp menu 锐化(&S) &6.1 Surround 6.1 环绕声(&6) &7.1 Surround 7.1 环绕声(&7) &Mono 单声道(&M) Re&verse 反相(&v) Secondary trac&k 第二轨道(&k) F&rames per second 每秒帧数(&R) Connection failed 连接失败 The video you requested needs to open a HTTPS connection. 您请求的视频需要使用HTTPS连接。 Unfortunately the OpenSSL component, required for it, is not available in your system. 很不幸,此功能需要openssl组件,而您的系统中没有。 Please, visit %1 to know how to fix this problem. 请访问 %1 查看如何解决此问题。 this link 此链接 Unfortunately due to changes in the Youtube page, this video can't be played. 抱歉因 Youtube页面的变化,此视频不能播放 Problems with Youtube Youtube的问题 %1 Error %1 错误 %1 was not found! %1 没有被找到! %1 has finished unexpectedly. %1 已意外结束。 %1 failed to start. %1 启动失败。 Please check the %1 path in preferences. 请检查首选项中的 %1 路径。 %1 has crashed. %1 已崩溃。 The YouTube Browser is not installed. YouTube 浏览器未安装。 Visit %1 to get it. 请访问 %1 获取。 Unfortunately due to changes in the Youtube page, the video '%1' can't be played. 抱歉因 Youtube变化,视频 '%1' 不能播放 Do you want to update the Youtube code? This may fix the problem. 你想更新Youtube代码吗?这样或许能解决问题。 Maybe updating SMPlayer could fix the problem. 或许更新视频播放器能解决这问题。 S&hare SMPlayer with your friends 和朋友分享视频播放器(&h) Information 信息 You need to restart SMPlayer to use the new GUI. 您需要重新启动视频播放器以使用新的 GUI。 Confirm deletion - SMPlayer 确认删除 - 视频播放器 Delete the list of recent files? 要删除最近的文件列表吗? The current values have been stored to be used as default. 当前的值已被储存作为默认值使用。 Inc saturation 增加饱和度 Inc gamma 增加伽玛 &Load external file... 加载外部文件(&L)... &Kerndeint Kerndeint(&K) &Yadif (normal) Yadif (标准)(&Y) Y&adif (double framerate) Yadif (双倍帧率)(&A) &Next 下一个(&N) Pre&vious 上一个(&V) Volume &normalization 音量标准化(&N) &Audio CD 音频 CD(&A) &Toggle double size 切换双倍大小(&T) S&ize - 大小-(&I) Si&ze + 大小+(&Z) Add &black borders 添加黑边(&B) Soft&ware scaling 软件缩放(&W) &FAQ FAQ(&F) &Command line options 命令行选项(&C) SMPlayer command line options 视频播放器命令行选项 &Forced subtitles only 仅强制字幕(&F) Reset video equalizer 重置视频均衡器 The server returned '%1' 服务器返回'%1' '%1' was not found! '%1' 没有被找到! Exit code: %1 退出代码: %1 See the log for more info. 更多信息请参阅日志。 &Rotate 旋转(&R) &Off 关(&O) &Rotate by 90 degrees clockwise and flip 顺时针旋转90度并翻转(&R) Rotate by 90 degrees &clockwise 顺时针旋转90度(&C) Rotate by 90 degrees counterclock&wise 逆时针旋转90度(&W) Rotate by 90 degrees counterclockwise and &flip 逆时针旋转90度并翻转(&F) &Jump to... 跳转到(&J)... Show context menu 显示上下文菜单 Multimedia 多媒体 E&qualizer 均衡器(&Q) Reset audio equalizer 重置音频均衡器 Upload su&btitles to OpenSubtitles.org... 上传字幕到 OpenSubtitles.org(&B)... &Auto 自动(&A) Speed -&4% 速度-4%(&4) &Speed +4% 速度+4%(&S) Speed -&1% 速度-1%(&1) S&peed +1% 速度+1%(&P) Scree&n 屏幕(&N) &Default 默认(&D) Mirr&or image 镜像图像(&O) Next video 下一个视轨 &Track video 视轨(&T) &Track audio 音轨(&T) Warning - Using old MPlayer 警告 - 正在使用过时的 MPlayer The version of MPlayer (%1) installed on your system is obsolete. SMPlayer can't work well with it: some options won't work, subtitle selection may fail... 您的系统上安装的 MPlayer(%1)版本已过时。视频播放器无法正常运行它: 有些选项无法正常工作,字幕选择可能会失效... Please, update your MPlayer. 请更新您的 MPlayer。 (This warning won't be displayed anymore) (此警告将不再显示) Next aspect ratio 下一个纵横比 &Auto zoom 自动缩放(&A) Zoom for &16:9 缩放为 16:9(&1) Zoom for &2.35:1 缩放为 2.35:1(&2) &Always 始终(&A) &Never 从不(&N) While &playing 当播放时(&P) DVD &menu DVD 菜单(&M) DVD &previous menu 上一级 DVD 菜单(&P) DVD menu, move up DVD 菜单,上移 DVD menu, move down DVD 菜单,下移 DVD menu, move left DVD 菜单,左移 DVD menu, move right DVD 菜单,右移 DVD menu, select option DVD 菜单,选择选项 DVD menu, mouse click DVD 菜单,鼠标单击 Set dela&y... 设置延迟(&Y)... Se&t delay... 设置延迟(&T)... &Jump to: 跳转到(&J): SMPlayer - Seek 视频播放器 - 定位 SMPlayer - Audio delay 视频播放器 - 音频延迟 Audio delay (in milliseconds): 音频延迟(毫秒): SMPlayer - Subtitle delay 视频播放器 - 字幕延迟 Subtitle delay (in milliseconds): 字幕延迟(毫秒): Toggle stay on top 切换保持在最前端 Jump to %1 跳转到 %1 Start/stop takin&g screenshots 开始/停止屏幕截图(&G) Subtitle &visibility 字幕可见性(&V) Next wheel function 下一个滚轮功能 P&rogram program 程序(&R) &TV 电视(&T) Radi&o 广播(&O) Subtitles onl&y 仅字幕(&Y) Volume + &Seek 音量+定位(&S) Volume + Seek + &Timer 音量+定位+计时器(&T) Volume + Seek + Timer + T&otal time 音量+定位+计时器+总时间(&O) Video filters are disabled when using vdpau 使用 VDPAU 时将禁用视频过滤器 Fli&p image 翻转图像(&P) Zoo&m 缩放(&M) Show filename on OSD 在"屏幕显示"上显示文件名 Set &A marker 设置 A 标记(&A) Set &B marker 设置 B 标记(&B) &Clear A-B markers 清除 A-B 标记(&C) &A-B section A-B 区间(&A) Toggle deinterlacing 切换去交错 &Closed captions 闭路字幕(&C) &Disc 光盘(&D) F&avorites 收藏夹(&A) Check for &updates 检查更新(&U) BaseGuiPlus SMPlayer is still running here 视频播放器仍在运行 S&how icon in system tray 在系统托盘上显示图标(&H) &Hide 隐藏(&H) &Restore 还原(&R) &Quit 退出(&Q) Playlist 播放列表 BookmarkDialog Name 名称 BottomWidget Previous 上一个 Next 下一个 Play/Pause 播放/暂停 FullScreen 全屏 Open 打开 Playlist 播放列表 Stop 停止 Prev 上一个 Play / Pause 播放/暂停 Mute 静音 Open File 打开文件 Play List 播放列表 CodeDownloader Downloading... 下载中… Connecting to %1 正在连接到 1% The Youtube code has been updated successfully. Youtube代码已成功更新 Installed version: %1 已安装版本: %1 Success Success Error Error An error happened writing %1 An error happened writing %1 An error happened while downloading the file:<br>%1 An error happened while downloading the file:<br>%1 Core Brightness: %1 亮度: %1 Contrast: %1 对比度: %1 Gamma: %1 伽玛: %1 Hue: %1 色调: %1 Saturation: %1 饱和度: %1 Volume: %1 音量: %1 Zoom: %1 缩放: %1 Buffering... 缓冲中... Font scale: %1 字体缩放: %1 Aspect ratio: %1 纵横比: %1 Updating the font cache. This may take some seconds... 正在更新字体缓存。这可能需要几秒钟... Subtitle delay: %1 ms 字幕延迟: %1毫秒 Audio delay: %1 ms 音频延迟: %1毫秒 Speed: %1 速度: %1 Unable to retrieve the Youtube page 无法取回Youtube页面 Unable to locate the URL of the video 无法定位视频的URL Subtitles on 字幕开启 Subtitles off 字幕关闭 Mouse wheel seeks now 鼠标滚轮定位 Mouse wheel changes volume now 鼠标滚轮更改音量 Mouse wheel changes zoom level now 鼠标滚轮更改缩放等级 Mouse wheel changes speed now 鼠标滚轮更改速度 Screenshot saved as %1 截图保存为 %1 Starting... 正在开始... Screenshot NOT taken, folder not configured 无法进行屏幕截图,没有配置文件夹 Screenshots NOT taken, folder not configured 无法进行屏幕截图,没有配置文件夹 "A" marker set to %1 "A"标记设置到 %1 "B" marker set to %1 "B"标记设置到 %1 A-B markers cleared A-B 标记已清除 Connecting to %1 正在连接到 1% DefaultGui Audio 音频 Subtitle 字幕 &Main toolbar 主工具栏(&M) &Language toolbar 语言工具栏(&L) &Toolbars 工具栏(&T) Ready 准备好 A:%1 A:%1 B:%1 B:%1 Status&bar 状态栏(&B) &Video info 视频信息(&V) &Frame counter 帧计数器(&F) Edit main &toolbar 编辑主工具栏(&T) Edit &control bar 编辑控制条(&C) Edit m&ini control bar 编译迷你控制条(&I) Edit &floating control 编辑浮动控制条(&F) %1x%2 %3 fps width + height + fps %1x%2 %3帧/秒 EqSlider icon icon ErrorDialog Hide log 隐藏日志 Show log 显示日志 MPlayer Error MPlayer 错误 OK 确定 icon icon Oops, something wrong happened 额..出错了 Error 错误 EscTip Press ESC to exit full screen mode 请按 ESC 键退出全屏 FavoriteEditor Icon 图标 Name 名称 Media 媒体 Favorite editor 收藏夹编辑器 Favorite list 收藏夹列表 You can edit, delete, sort or add new items. Double click on a cell to edit its contents. 您可以编辑、删除、排序或添加新的项目。双击一个单元格可以编辑其内容。 Select an icon file 选择一个图标文件 Images 图像 icon icon D&elete 删除(&E) Delete &all 删除全部(&A) &Up 向上(&U) &Down 向下(&D) &New item 新建项目(&N) New &submenu 新建子菜单(&S) Favorites Jump to item 跳转到项目 Enter the number of the item in the list to jump: 输入在列表中要跳转的项目编号: &Edit... 编辑(&E)... &Jump... 跳转(&J)... &Next 下一个(&N) &Previous 上一个(&P) &Add current media 添加当前媒体(&A) FileChooser Click to select a file or folder 单击以选择一个文件或文件夹 FileDownloader Downloading... 正在下载... Connecting to %1 正在连接到 1% FilePropertiesDialog SMPlayer - File properties 视频播放器 - 文件属性 &Information 信息(&I) &Demuxer 解复用器(&D) Kylin Video - Preferences 麒麟影音 - 设置 Kylin Video - Properties 麒麟影音 - 属性 Kylin video - Properties 麒麟影音 - 属性 Properties 属性 &Select the demuxer that will be used for this file: 选择将用于此文件的解复用器(&S): &Reset 重置(&R) Reset 重置 &Video codec 视频编解码器(&V) &Select the video codec: 选择视频编解码器(&S): A&udio codec 音频编解码器(&U) &Select the audio codec: 选择音频编解码器(&S): You can also pass additional video filters. Separate them with ",". Do not use spaces! Example: scale=512:-2,mirror 您还可以传送额外的视频过滤器。 请用" , "隔开它们。不要使用空格! 示例: scale=512:-2,mirror And finally audio filters. Same rule as for video filters. Example: extrastereo,karaoke 最后是音频过滤器。和视频过滤器的规则相同。 示例: extrastereo,karaoke &Options: 选项(&O): V&ideo filters: 视频过滤器(&I): Audio &filters: 音频过滤器(&F): Information 信息 Demuxer 解复用器 Video codec 视频编解码器 Audio codec 音频编解码器 OK 确定 Cancel 取消 Apply 应用 O&ptions for %1 %1 的参数项 (&p) Additional Options for %1 %1 的额外参数项 Here you can pass extra options to %1. 你可以在这里为 %1 设置额外的参数。 Write them separated by spaces. 在这里输入,使用空格隔开。 Example: 示例: FindSubtitlesConfigDialog HTTP HTTP SOCKS5 SOCKS5 Enable/disable the use of the proxy. 启用/禁用使用代理。 The host name of the proxy. 代理的主机名。 The port of the proxy. 代理的端口。 If the proxy requires authentication, this sets the username. 如果代理需要身份验证,请在这里设置用户名。 The password for the proxy. <b>Warning:</b> the password will be saved as plain text in the configuration file. 代理的密码。<b>警告:</b> 密码将被作为纯文本保存在配置文件中。 Select the proxy type to be used. 选择要使用的代理类型。 Options 选项 Server 服务器 &OpenSubtitles server: OpenSubtitles 服务器(&O): Proxy 代理 &Enable proxy 启用代理(&E) &Host: 主机(&H): &Port: 端口(&P): &Username: 用户名(&U): Pa&ssword: 密码(&S): &Type: 类型(&T): Misc Misc A&ppend language code to the subtitle filename 将语言代码附加到字幕文件名中(&p) Number of &retries: 条目数(&r): FindSubtitlesWindow Language 语言 Name 名称 Format 格式 Files 文件 Date 日期 Uploaded by 上传者 Portuguese - Brasil 葡萄牙语-巴西 All 全部 Close 关闭 Login to opensubtitles.org has failed 登陆到opensubtitles.org失败 Search has failed 搜索失败 %n subtitle(s) extracted 已提取%n个字幕 Error fixing the subtitle lines 修复字幕行时出错 &Download 下载(&D) &Copy link to clipboard 复制链接到剪贴板(&C) Error 错误 Download failed: %1. 下载失败: %1。 Connecting to %1... 正在连接到 %1... Downloading... 正在下载... Done. 完成。 %1 files available %1个文件可用 Failed to parse the received data. 无法分析接收到的数据。 Find Subtitles 查找字幕 &Subtitles for 字幕用于(&S) &Language: 语言(&L): &Refresh 刷新(&R) Subtitle saved as %1 字幕已保存为 %1 Overwrite? 是否覆盖? The file %1 already exits, overwrite? 文件 %1 已存在,是否覆盖? Error saving file 保存文件时出错 It wasn't possible to save the downloaded file in folder %1 Please check the permissions of that folder. 无法在文件夹 %1 中保存下载的文件 请检查该文件夹的权限。 Download failed 下载失败 Temporary file %1 临时文件 %1 &Options 选项(&O) FontCacheDialog SMPlayer is initializing 视频播放器正在初始化 Creating a font cache... 正在创建字体缓存... GlobalShortcutsDialog Select the multimedia keys that kylin-video will capture. Media &Play Media &Stop Media Pre&vious Media &Next Media P&ause Media &Record Volume &Mute Volume &Down Volume &Up Global Shortcuts HelpDialog Kylin Video - Preferences 麒麟影音 - 设置 Kylin Video - Help 麒麟影音 - 帮助 Help 帮助 OK 确定 Supported formats 支持的格式 Supported shortcuts 支持的快捷键 InfoFile General 常规 Size 大小 %1 KB (%2 MB) %1 KB (%2 MB) URL URL Length 长度 Demuxer 解复用器 Name 名称 Artist 艺术家 Author 作者 Album 专辑 Genre 流派 Date 日期 Track 轨道 Copyright 版权 Comment 注释 Software 软件 Clip info 剪辑信息 Video 视频 Resolution 分辨率 Aspect ratio 纵横比 Format 格式 Bitrate 比特率 %1 kbps %1kbps Frames per second 每秒帧数 Selected codec 已选编解码器 Initial Audio Stream 初始音频流 Rate 采样率 %1 Hz %1 Hz Channels 声道 Audio Streams 音频流 Language 语言 empty Subtitles 字幕 Type 类型 ID Info for translators: this is a identification code ID # Info for translators: this is a abbreviation for number # Stream title 流标题 Stream URL 流 URL File 文件 InputDVDDirectory Choose a directory 选择一个目录 SMPlayer - Play a DVD from a folder 视频播放器 - 从文件夹播放 DVD You can play a DVD from your hard disc. Just select the folder which contains the VIDEO_TS and AUDIO_TS directories. 你可以从播放硬盘中的DVD。选择包含 VIDEO_TS 和 AUDIO_TS 的文件夹即可。 Choose a directory... 选择目录... InputMplayerVersion SMPlayer - Enter the MPlayer version 视频播放器 - 输入 MPlayer 版本 SMPlayer couldn't identify the MPlayer version you're using. 视频播放器无法识别您正在使用的 MPlayer 版本。 Version reported by MPlayer: MPlayer 报告的版本: Please, &select the correct version: 请选择正确的版本(&S): 1.0rc1 or older 1.0rc1 或更旧 1.0rc2 1.0rc2 1.0rc3 or newer 1.0rc3 或更新 InputURL SMPlayer - Enter URL 视频播放器 - 输入 URL Kylin Video - Enter URL 麒麟影音 - 输入 URL &URL: URL(&U): OK 确定 Enter URL 输入网址 Cancel 取消 URL: 网址: Languages Afar 阿法尔语 Abkhazian 阿布哈西亚语 Afrikaans 南非荷兰语 Amharic 阿姆哈拉语 Arabic 阿拉伯语 Assamese 阿萨姆语 Aymara 艾马拉语 Azerbaijani 阿塞拜疆语 Bashkir 巴什基尔语 Bulgarian 保加利亚语 Bihari 比哈尔语 Bislama 比斯拉马语 Bengali 孟加拉语 Tibetan 藏语 Breton 布列塔尼语 Catalan 加泰罗尼亚语 Corsican 科西嘉语 Czech 捷克语 Welsh 威尔士语 Danish 丹麦语 German 德语 Greek 希腊语 English 英语 Esperanto 世界语 Spanish 西班牙语 Estonian 爱沙尼亚语 Basque 巴斯克语 Persian 波斯语 Finnish 芬兰语 Faroese 法罗语 French 法语 Frisian 弗里西亚语 Irish 爱尔兰语 Galician 加利西亚语 Guarani 瓜拉尼语 Gujarati 古吉拉特语 Hausa 豪萨语 Hebrew 希伯来语 Hindi 印地语 Croatian 克罗地亚语 Hungarian 匈牙利语 Armenian 亚美尼亚语 Interlingua 国际语A Indonesian 印度尼西亚语 Interlingue 国际语E Icelandic 冰岛语 Italian 意大利语 Inuktitut 因纽特语 Japanese 日语 Javanese 爪哇语 Georgian 格鲁吉亚语 Kazakh 哈萨克语 Greenlandic 格陵兰语 Kannada 卡纳达语 Korean 韩国语 Kashmiri 克什米尔语 Kurdish 库尔德语 Kirghiz 吉尔吉斯语 Latin 拉丁语 Lingala 林加拉语 Lithuanian 立陶宛语 Latvian 拉脱维亚语 Malagasy 马达加斯加语 Maori 毛利语 Macedonian 马其顿语 Malayalam 马拉雅拉姆语 Mongolian 蒙古语 Moldavian 摩尔达维亚语 Marathi 马拉地语 Malay 马来语 Maltese 马耳他语 Burmese 缅甸语 Nauru 瑙鲁语 Nepali 尼泊尔语 Dutch 荷兰语 Norwegian Nynorsk 耐诺斯克挪威语 Norwegian 挪威语 Occitan 欧西坦语 Oriya 奥里亚语 Polish 波兰语 Portuguese 葡萄牙语 Quechua 克丘亚语 Romanian 罗马尼亚语 Russian 俄语 Kinyarwanda 基尼亚卢旺达语 Sanskrit 梵语 Sindhi 信德语 Slovak 斯洛伐克语 Samoan 萨摩亚语 Shona 绍纳语 Somali 索马里语 Albanian 阿尔巴尼亚语 Serbian 塞尔维亚语 Sundanese 巽他语 Swedish 瑞典语 Swahili 斯瓦希里语 Tamil 泰米尔语 Telugu 泰卢固语 Tajik 塔吉克语 Thai 泰语 Tigrinya 提格利尼亚语 Turkmen 土库曼语 Tagalog 塔加洛语 Tonga 汤加语 Turkish 土耳其语 Tsonga 聪加语 Tatar 鞑靼语 Twi 契维语 Uighur 维吾尔语 Ukrainian 乌克兰语 Urdu 乌尔都语 Uzbek 乌兹别克语 Vietnamese 越南语 Wolof 沃洛夫语 Xhosa 科萨语 Yiddish 意第绪语 Yoruba 约鲁巴语 Zhuang 壮语 Chinese 汉语 Zulu 祖鲁语 Arabic - Syria 阿拉伯语 - 叙利亚 Unicode Unicode UTF-8 UTF-8 Western European Languages 西欧 Western European Languages with Euro 西欧(欧盟) Slavic/Central European Languages 斯拉夫语/中欧 Esperanto, Galician, Maltese, Turkish 世界语,加利西亚,马耳他,土耳其 Old Baltic charset 旧波罗的海字符集 Cyrillic 西里尔文 Modern Greek 现代希腊语 Baltic 波罗的海语 Celtic 凯尔特语 South-Eastern European 东南欧洲 Hebrew charsets 希伯来语字符集 Ukrainian, Belarusian 乌克兰语,白俄罗斯 Simplified Chinese charset 简体中文字符集 Traditional Chinese charset 繁体中文字符集 Japanese charsets 日语字符集 Korean charset 朝鲜语字符集 Thai charset 泰语字符集 Cyrillic Windows 西里尔文 Windows Slavic/Central European Windows 斯拉夫语/中欧 Windows Arabic Windows 阿拉伯语 Windows Avestan 阿维斯陀语 Akan 阿坎语 Aragonese 阿拉贡语 Avaric 阿瓦尔语 Belarusian 白俄罗斯语 Bambara 班巴拉语 Bosnian 波斯尼亚语 Chechen 车臣语 Cree 克里语 Church 古教会斯拉夫语 Chuvash 楚瓦什语 Divehi 迪维希语 Dzongkha 宗卡语 Ewe 埃维语 Fulah 富拉语 Fijian 斐济语 Gaelic 盖尔语 Manx 马恩岛语 Hiri 希里莫图语 Haitian 海地克里奥尔语 Herero 赫雷罗语 Chamorro 查莫罗语 Igbo 伊博语 Sichuan 四川彝语 Inupiaq 依努庇克语 Ido 伊多语 Kongo 刚果语 Kikuyu 基库尤语 Kuanyama 宽亚玛语 Khmer 高棉语 Kanuri 卡努里语 Komi 科米语 Cornish 康沃尔语 Luxembourgish 卢森堡语 Ganda 干达语 Limburgan 林堡语 Lao 老挝语 Luba-Katanga 卢巴-加丹加语 Marshallese 马绍尔语 Bokmål 博克马尔语 Ndebele 北恩德贝勒语 Ndonga 恩敦加语 Navajo 纳瓦霍语 Chichewa 齐切瓦语 Ojibwa 奥吉布瓦语 Oromo 奥罗莫语 Ossetian 奥塞梯语 Panjabi 旁遮普语 Pali 巴利语 Pushto 普什图语 Romansh 罗曼什语 Rundi 基隆迪语 Sardinian 萨丁尼亚语 Sami 北萨米语 Sango 桑戈语 Sinhala 僧加罗语 Slovene 斯洛文尼亚语 Swati 斯瓦特语 Sotho 南索托语 Tswana 茨瓦纳语 Tahitian 塔希提语 Venda 文达语 Volapük 沃拉普克语 Walloon 瓦龙语 Modern Greek Windows 现代希腊语 Windows LineEditWithIcon Change 更改 LogWindow Choose a filename to save under 选择一个要保存在下面的文件名 Confirm overwrite? 确认是否覆盖? The file already exists. Do you want to overwrite? 该文件已存在。 您想要覆盖吗? Error saving file 保存文件时出错 The log couldn't be saved 无法保存日志 Logs 日志 LogWindowBase Save 保存 Copy to clipboard 复制到剪贴板 &Close 关闭(&C) Close 关闭 MPVProcess the '%1' filter is not supported by mpv mpv不支持 '%1' 过滤器 File: 文件: Video: 视频: Resolution: 解析度: Frames per second: 每秒显示的画面数: Estimated: 预估: Aspect Ratio: 外观比例: Bitrate: 位率: Dropped frames: 已丢失的画面: Audio: 音频: Sample Rate: 取样率: Channels: 频道: Audio/video synchronization: 音/视频同步: Cache fill: 缓存填充: Used cache: 使用缓存: MainWindow Kylin Video 麒麟影音 A:%1 A:%1 B:%1 B:%1 Open 打开 Open &File... 打开文件(&F)... Directory... 目录... &URL... 网址(&U)... &Clear 清除(&C) Recent files 最近的文件 Play control 播放控制 Forward and rewind 快进快退 &Jump to... 跳转到(&J)... Play Speed 播放速度 Normal speed 正常速度 Half speed 半速 Double speed 双倍速度 Speed -10% 速度-10% Speed +10% 速度+10% Speed -4% 速度-4% Speed +4% 速度+4% Speed -1% 速度-1% Speed +1% 速度+1% Next 下一个 Previous 上一个 &Auto 自动(&A) &Disabled 禁用(&D) Aspect ratio 画面比例 &Off 关(&O) &Rotate by 90 degrees clockwise and flip 顺时针旋转90度并翻转(&R) Rotate by 90 degrees &clockwise 顺时针旋转90度(&C) Rotate by 90 degrees counterclock&wise 逆时针旋转90度(&W) Rotate by 90 degrees counterclockwise and &flip 逆时针旋转90度并翻转(&F) Fli&p image 翻转图像(&P) Mirr&or image 镜像图像(&O) Frame rotation 画面旋转 &Rotate 旋转(&R) &Screenshot 屏幕截图(&S) &Always 始终(&A) &Never 从不(&N) While &playing 当播放时(&P) S&tay on top 置顶(&T) Order play 顺序播放 Random play 随机播放 List loop play 列表循环播放 Play order 播放顺序 &Stereo 立体声(&S) &4.0 Surround 4.0 环绕声(&4) &5.1 Surround 5.1 环绕声(&5) &6.1 Surround 6.1 环绕声(&6) &7.1 Surround 7.1 环绕声(&7) &Channels 声道(&C) Audio 音频 &Mute 静音(&M) &Extrastereo 附加立体声(&E) &Karaoke 卡拉 OK(&K) Volume &normalization 音量标准化(&N) &Headphone optimization 优化耳机(&h) &Filters 过滤器(&F) Volume - 音量 - Volume + 音量 + Delay - 延迟 - Delay + 延迟 + Set dela&y... 设置延迟(&Y)... &Load external file... 加载外部文件(&L)... U&nload 卸载外部文件(&N) E&qualizer 均衡器(&Q) Reset audio equalizer 重置音频均衡器 &Left channel 左声道(&L) &Right channel 右声道(&R) &Mono 单声道(&M) Re&verse 反相(&v) &Stereo mode 立体声模式(&S) Subtitles 字幕 Load... 加载... Subtitle &visibility 字幕可见性(&V) Preferences 设置 View &info and properties... 媒体信息(&I)... Help 帮助 About &Kylin Video 关于 麒麟影音 Quit 退出 Show &info on OSD 在 OSD 中显示信息(&i) Size &+ 大小 &+ Size &- 大小 &- Show times with &milliseconds 以毫秒显示时间 Subtitles onl&y 仅字幕(&Y) Volume + &Seek 音量+定位(&S) Volume + Seek + &Timer 音量+定位+计时器(&T) Volume + Seek + Timer + T&otal time 音量+定位+计时器+总时间(&O) &OSD 屏幕显示(&O) PlayList 播放列表 Play/Pause 播放/暂停 Stop 停止 Fullscreen 全屏 Open Homepage 打开主界面 Open screenshots folder 打开截图文件夹 Failed to add files! 添加文件失败! Video filters are disabled when using vdpau 使用 VDPAU 时将禁用视频过滤器 -%1 -%1 +%1 +%1 <empty> <空> Confirm deletion - Kylin Video 确认删除 - 麒麟影音 Delete the list of recent files? 要删除最近的文件列表吗? Choose a file 选择一个文件 Multimedia 多媒体 Video 视频 Playlists 播放列表 All files 所有文件 Choose a directory 选择一个目录 &Jump to: 跳转到(&J): Kylin Video - Seek 麒麟影音 - 定位 Kylin Video - Subtitle delay 麒麟影音 - 字幕延迟 Subtitle delay (in milliseconds): 字幕延迟(毫秒): Error detected 检测到错误 Unfortunately this video can't be played. 抱歉此视频不能播放 The server returned '%1' 服务器返回'%1' Jump to %1 跳转到 %1 %1 Error %1 错误 '%1' was not found! '%1' 没有被找到! %1 has finished unexpectedly. %1 已意外结束。 Exit code: %1 退出代码: %1 %1 failed to start. %1 启动失败。 Please check the %1 path in preferences. 请检查首选项中的 %1 路径。 %1 has crashed. %1 已崩溃。 See the log for more info. 更多信息请参阅日志。 Information The screenshot folder does not exist! 截图文件夹不存在! Warning - Using old MPlayer 警告 - 正在使用过时的 MPlayer The version of MPlayer (%1) installed on your system is obsolete. kylin-video can't work well with it: some options won't work, subtitle selection may fail... 您的系统上安装的 MPlayer(%1)版本已过时。麒麟影音无法正常运行它: 有些选项无法正常工作,字幕选择可能会失效... The version of MPlayer (%1) installed on your system is obsolete. SMPlayer can't work well with it: some options won't work, subtitle selection may fail... 您的系统上安装的 MPlayer(%1)版本已过时。视频播放器无法正常运行它: 有些选项无法正常工作,字幕选择可能会失效... Please, update your MPlayer. 请更新您的 MPlayer。 (This warning won't be displayed anymore) (此警告将不再显示) MaskWidget Loading... MediaBarPanel Form 表格 MediaPanel Shuffle playlist 乱序播放列表 Repeat playlist 重复播放列表 MediaPanelClass MediaPanel 媒体面板 MessageDialog OK 确定 Ok 确定 Cancel 取消 Yes No MiniGui Control bar 控制条 Edit &control bar 编辑控制条(&C) Edit &floating control 编辑浮动控制条(&F) MpcGui Control bar 控制条 Seek bar 定位栏 -%1 -%1 +%1 +%1 MplayerProcess This option is not supported by MPlayer MPlayer不支持该选项 MultilineInputDialog Enter URL(s) 输入网址(s) Enter the URL(s) to be added to the playlist. One per line. 输入要添加到播放列表的网址(s)。每行一个。 PlayControl Rewind 后退 Forward 前进 Play / Pause 播放/暂停 Stop 停止 Record 录制 Next file in playlist 播放列表中的下一个文件 Previous file in playlist 播放列表中的上一个文件 PlayListView Play 播放 Remove &selected 删除选定(&S) &Delete file from disk 从硬盘删除(&D) Delete 删除 Playlist Name 名称 Length 长度 &Play 播放(&P) &Edit 编辑(&E) Playlists 播放列表 Choose a file 选择一个文件 Choose a filename 选择一个文件名 Confirm overwrite? 确认是否覆盖? The file %1 already exists. Do you want to overwrite? 文件 %1 已存在。 您想要覆盖吗? Reached the top of the playlist 已经到达播放列表顶部 You're about to remove the file from the playlist. 将从播放列表中移除文件。 You're about to Delete the files from your drive. 将从您的硬盘删除文件。 Confirm remove all 确认移除所有文件 You're about to empty the playlist. 将清空播放列表。 All files 所有文件 Select one or more files to open 选择一个或多个要打开的文件 Playlist is empty 播放列表为空 PlayList 播放列表 Clear 清除 Add File 增加文件 Add 添加 Play 播放 Reached the end of the playlist 已经到达播放列表底部 Choose a directory 选择一个目录 Edit name 编辑名称 Type the name that will be displayed in the playlist for this file: 键入该文件将显示在播放列表中的名称: &Load 加载(&L) &Save 保存(&S) &Next 下一个(&N) Pre&vious 上一个(&V) Move &up 向上移动(&U) Move &down 向下移动(&D) &Repeat 重复(&R) S&huffle 乱序(&H) Add &current file 添加当前文件(&C) Add &file(s) 添加文件(&F) Add &directory 添加目录(&D) Add &URL(s) 添加网址(s) (U) Remove &selected 删除选定(&S) Remove &all 删除全部(&A) &Delete file from disk 从硬盘删除(&D) SMPlayer - Playlist 视频播放器 - 播放列表 Confirm remove 确认移除 You're about to remove the file '%1' from the playlist. 将从播放列表中移除文件 '%1'。 Are you sure you want to proceed? 你确定要继续? Confirm deletion 确认删除 You're about to DELETE the file '%1' from your drive. 将从您的硬盘删除文件 '%1' This action cannot be undone. Are you sure you want to proceed? 此操作不可撤销。你确定要继续? Deletion failed 删除失败 It wasn't possible to delete '%1' 无法删除 '%1' Error deleting the file 删除文件出错 It's not possible to delete '%1' from the filesystem. 无法从文件系统删除 '%1' Add... 添加... Remove... 删除... Playlist modified 播放列表己修改 There are unsaved changes, do you want to save the playlist? 有未保存的更改,您想要保存该播放列表吗? Multimedia 多媒体 PoweroffDialog The computer will shut down in %1 seconds. 电脑将会在 %1 秒内关机 Press <b>Cancel</b> to abort shutdown. 按<b>取消</b>键取消关机 Ok 确定 Cancel 取消 PrefAdvanced Advanced 高级 Auto 自动 &Advanced 高级(&A) Log SMPlayer output 记录视频播放器输出 This option is mainly intended for debugging the application. 此选项主要用于调试应用程序。 Checking this option may reduce flickering, but it also might produce that the video won't be displayed properly. 勾选此选项可减少闪烁,但也可能会造成视频无法正确显示。 Filter for SMPlayer logs 视频播放器日志筛选器 &Monitor aspect: 显示器纵横比(&M): Use the la&vf demuxer by default 默认使用lavf 分流器(&v) &Options: 选项(&O): V&ideo filters: 视频过滤器(&I): Audio &filters: 音频过滤器(&F): &Colorkey: 色键(&C): You can also pass additional video filters. Separate them with ",". Do not use spaces! Example: scale=512:-2,mirror 您还可以传送额外的视频过滤器。 请用" , "隔开它们。不要使用空格! 示例: scale=512:-2,mirror And finally audio filters. Same rule as for video filters. Example: extrastereo,karaoke 最后是音频过滤器。和视频过滤器的规则相同。 示例: extrastereo,karaoke SMPlayer 视频播放器 Log &SMPlayer output 记录视频播放器输出(&S) &Filter for SMPlayer logs: 视频播放器日志筛选器(&F): C&hange... 更改(&H)... Logs 日志 Monitor aspect 显示器纵横比 Select the aspect ratio of your monitor. 选择您的显示器纵横比。 Use the lavf demuxer by default 默认使用lavf 分流器 If this option is checked, the lavf demuxer will be used for all formats. 如果勾选此项,lavf分流器将会被用于所有格式的文件。 Colorkey 色键 If you see parts of the video over any other window, you can change the colorkey to fix it. Try to select a color close to black. 如果您在任何其他窗口上看到了部分视频,您可以通过更改色键来修复它。请尽量选择接近黑色的颜色。 Options 选项 Video filters 视频过滤器 Audio filters 音频过滤器 Repaint the background of the video window 重绘视频窗口背景 Repaint the backgroun&d of the video window 重绘视频窗口背景(&D) IPv4 IPv4 Use IPv4 on network connections. Falls back on IPv6 automatically. 使用 IPv4 网络连接。失败自动返回 IPv6。 IPv6 IPv6 Use IPv6 on network connections. Falls back on IPv4 automatically. 使用 IPv6 网络连接。失败自动返回 IPv4。 Network Connection 网络连接 IPv&4 IPv4(&4) IPv&6 IPv6(&6) Lo&gs 日志(&G) Rebuild index if needed 需要时重建索引 Rebuild &index if needed 需要时重建索引(&I) If this option is checked, SMPlayer will store the debugging messages that SMPlayer outputs (you can see the log in <b>Options -> View logs -> SMPlayer</b>). This information can be very useful for the developer in case you find a bug. 如果勾选此选项,视频播放器将存储其输出的调试信息(在 <b>选项 -> 查看日志 -> 视频播放器</b> 中您可以看到该日志)。在您发现 Bug 时,此信息可能对开发者非常有用。 Log %1 output 记录 %1 输出 If checked, SMPlayer will store the output of %1 (you can see it in <b>Options -> View logs -> %1</b>). In case of problems this log can contain important information, so it's recommended to keep this option checked. 如果勾选,视频播放器将存储 %1 的输出(在 <b>选项 -> 查看日志 -> %1 </b>中可以看到它)。出现问题时,该日志会记录重要的信息,因此建议保持勾选此选项。 Autosave %1 log 自动保存 %1 日志 If this option is checked, the %1 log will be saved to the specified file every time a new file starts to play. It's intended for external applications, so they can get info about the file you're playing. 如果勾选此选项,每次有新文件开始播放时,%1 日志将被保存到指定的文件。这样做有便于外部应用程序获取当前播放文件的信息。 Autosave %1 log filename 自动保存 %1 日志的文件名 Enter here the path and filename that will be used to save the %1 log. 在这里输入保存 %1 日志的路径及文件名。 This option allows you to filter the SMPlayer messages that will be stored in the log. Here you can write any regular expression.<br>For instance: <i>^Core::.*</i> will display only the lines starting with <i>Core::</i> 此选项允许筛选将被存储在日志中的视频播放器消息。在这里您可以编写任何正则表达式。<br>例如: <i>^Core::..*</i> 将只显示以 <i>Core::</i> 开始的行 Correct pts 校正 PTS &Run %1 in its own window 让 %1 在其自己的窗口中运行(&R) &Pass short filenames (8+3) to %1 传送短文件名(8+3)到 %1 (&P) R&eport %1 crashes 报告 %1 崩溃 (&e) O&ptions for %1 %1 的参数项 (&p) Here you can pass extra options to %1. 你可以在此处输入 %1 的额外参数。 Write them separated by spaces. 使用空格分隔。 Log %1 &output 记录 %1 输出(&o) A&utosave %1 log to file 自动保存 %1 日志到文件(&u) Run %1 in its own window 让 %1 在其自己的窗口中运行 If you check this option, the %1 video window won't be embedded in SMPlayer's main window but instead it will use its own window. Note that mouse and keyboard events will be handled directly by %1, that means key shortcuts and mouse clicks probably won't work as expected when the %1 window has the focus. 如果勾选此选项,%1 的视频窗口将不会被嵌入到视频播放器的主窗口中,而它将使用其自己的窗口。需要注意的是,键盘和鼠标事件将由 %1 直接处理,这意味着当焦点在 %1 窗口时,快捷键和鼠标点击很可能无法按预期工作。 Pass short filenames (8+3) to %1 传送短文件名(8+3)到 %1 If this option is checked, SMPlayer will pass to %1 the short version of the filenames. 如果勾选此选项,视频播放器将会将短文件名传送给 %1。 Report %1 crashes 报告 %1 崩溃 If this option is checked, a window will appear to inform about %1 crashes. Otherwise those failures will be silently ignored. 如果勾选此选项,将会出现一个窗口通知 %1 崩溃。否则这些故障将被忽略。 Switches %1 to an experimental mode where timestamps for video frames are calculated differently and video filters which add new frames or modify timestamps of existing ones are supported. The more accurate timestamps can be visible for example when playing subtitles timed to scene changes with the SSA/ASS library enabled. Without correct pts the subtitle timing will typically be off by some frames. This option does not work correctly with some demuxers and codecs. 切换 %1 到试验模式,其中视频帧时间戳的计算方式不同,且支持视频过滤器添加新的帧或修改现有的时间戳。例如当正在播放的字幕同步到场景变化时(已启用 SSA/ASS 库),可得到更精确的时间戳。如果没有校正 PTS,字幕同步通常会被某些帧关闭。此选项不能与某些解复用器和编解码器一起正常工作。 Actions list 动作列表 Here you can specify a list of <i>actions</i> which will be run every time a file is opened. You'll find all available actions in the key shortcut editor in the <b>Keyboard and mouse</b> section. The actions must be separated by spaces. Checkable actions can be followed by <i>true</i> or <i>false</i> to enable or disable the action. 在这里您可以指定一个每次打开文件时将运行的 <i>动作</i> 列表。在 <b>键盘和鼠标</b> 部分的快捷键编辑器中您会发现所有的可用动作。动作之间必须由空格隔开。可选动作可以在后面用 <i>true</i> 或 <i>false</i> 来启用或禁用它。 Limitation: the actions are run only when a file is opened and not when the mplayer process is restarted (e.g. you select an audio or video filter). 局限: 只有当某个文件被打开,而且 MPlayer 进程没有被重启(例如您选择音频或视频过滤器)时动作才会运行。 Options for %1 %1 选项 Here you can type options for %1. 你可以在这里输入 %1 的参数。 Here you can add video filters for %1. 你可以为 %1 添加视频过滤器。 Write them separated by commas. Don't use spaces! 请使用逗号分隔每个参数。不要使用空格! Here you can add audio filters for %1. 你可以在这里为 %1 添加音频过滤器。 Network 网络 R&un the following actions every time a file is opened. The actions must be separated with spaces: 每次打开文件时运行下列动作。动作之间必须由空格隔开(&U): &Network 网络(&N) Example: 示例: Rebuilds index of files if no index was found, allowing seeking. Useful with broken/incomplete downloads, or badly created files. This option only works if the underlying media supports seeking (i.e. not with stdin, pipe, etc).<br> <b>Note:</b> the creation of the index may take some time. 在没有找到索引的情况下重建文件索引,从而允许定位。这对于损坏/未完成下载或制作低劣的文件很有用。此选项仅适用原本支持定位的媒体(即不能是 stdin、pipe 等)。<br><b>注意:</b> 创建索引可能需要一些时间。 C&orrect PTS: 校正 PTS(&O): &Verbose 详细信息(&V) Save SMPlayer log to file 保存视频播放器日志到文件 If this option is checked, the SMPlayer log wil be recorded to %1 如果勾选此选项,视频播放器日志将被记录到 %1 Sa&ve SMPlayer log to a file 保存视频播放器日志到文件(&V) Show tag info in window title 在窗口标题上显示标签信息 If this option is enabled, information from tags will be shown in window title. Otherwise only the filename will be shown. 如果启用此选项,标签中的信息将显示在窗口标题上。否则将只显示文件名。 Show tag in&fo in window title 在窗口标题上显示标签信息(&F) PrefAssociations Warning 警告 Not all files could be associated. Please check your security permissions and retry. 并非所有文件都被关联。请检查您的安全权限,然后重试。 File Types 文件类型 Select all 选择全部 Check all file types in the list 勾选列表中的所有文件类型 Uncheck all file types in the list 取消勾选列表中的所有文件类型 List of file types 文件类型列表 Note: 注意: Restoration doesn't work on Windows Vista. Windows Vista 下不支持重置。 File types 文件类型 Media files handled by SMPlayer: 由视频播放器处理的媒体文件: Select All 选择全部 Select None 取消选择 Check the media file extensions you would like SMPlayer to handle. When you click Apply, the checked files will be associated with SMPlayer. If you uncheck a media type, the file association will be restored. 勾选您想使用视频播放器处理的媒体文件扩展名。当您单击"应用"时,勾选的文件将被关联到视频播放器。如果您取消勾选一种媒体类型,该文件关联将被恢复。 Select none 取消选择 PrefAudio A&udio 音频(&U) Ou&tput driver: 输出驱动(&T): C&hannels by default: 默认声道(&H): Volume 音量 Use software volume control 使用软件音量控制 Max. Amplification: 最大放大率: Audio/video auto synchronization 音频/视频自动同步 Factor: 因子: Output driver: 输出驱动: Channels by default: 默认声道: Glo&bal volume 全局音量(&B) Use s&oftware volume control 使用软件音量控制(&O) Ma&x. Amplification: 最大放大率(&X): Volume &normalization by default 默认音量标准化(&N) Synchronization 同步 Audio/video auto &synchronization 音频/视频自动同步(&S) &Factor: 因子(&F): 2 (Stereo) 2 (立体声) 4 (4.0 Surround) 4 (4.0 环绕声) 6 (5.1 Surround) 6 (5.1 环绕声) 7 (6.1 Surround) 7 (6.1 环绕声) 8 (7.1 Surround) 8 (7.1 环绕声) Default 默认 Audio output driver 音频输出驱动 Select the audio output driver. 选择音频输出驱动。 %1 is the recommended one. Try to avoid %2 and %3, they are slow and can have an impact on performance. 推荐使用 %1。尽量避免 %2 和 %3,它们速度很慢,且会影响性能。 Channels by default 默认声道 Requests the number of playback channels. MPlayer asks the decoder to decode the audio into as many channels as specified. Then it is up to the decoder to fulfill the requirement. This is usually only important when playing videos with AC3 audio (like DVDs). In that case liba52 does the decoding by default and correctly downmixes the audio into the requested number of channels. <b>Note</b>: This option is honored by codecs (AC3 only), filters (surround) and audio output drivers (OSS at least). 指定播放声道的数量。MPlayer 告诉解码器需要将音频解码成多少声道,再由解码器来实现此需求。通常只有在播放带有 AC3 音频(比如 DVD)的视频时才有用。在该情况下将默认使用 liba52 解码并把音频正确地混合成需要的声道数量。<b>注意</b>: 此选项需要 编码(仅 AC3)、过滤器(环绕声)和音频输出驱动(OSS或更高级)三者都满足。 Gradually adjusts the A/V sync based on audio delay measurements. 基于音频延迟的测量值逐步调整 A/V 同步。 Global volume 全局音量 If this option is checked, the same volume will be used for all files you play. If the option is not checked each file uses its own volume. 如果勾选此选项,您播放的所有文件都将使用相同的音量。如果此选项未被勾选,每个文件将使用其自己的音量。 This option also applies for the mute control. 此选项也适用于静音控制。 Software volume control 使用软件音量控制 Check this option to use the software mixer, instead of using the sound card mixer. 勾选此选项以使用软件混音器,而不使用声卡混音器。 Max. Amplification 最大放大率 Sets the maximum amplification level in percent (default: 110). A value of 200 will allow you to adjust the volume up to a maximum of double the current level. With values below 100 the initial volume (which is 100%) will be above the maximum, which e.g. the OSD cannot display correctly. 设置最大放大级别的百分比(默认值: 110)。该值为 200 时允许您调整的最大音量为目前级别的两倍。该值低于 100 时,初始音量(为100%)将高于可调整的最大值,这时例如 OSD (屏幕显示)将不能正确显示。 Volume normalization by default 默认音量标准化 Maximizes the volume without distorting the sound. 声音没有失真的最大音量。 PrefDrives Drives 驱动器 CD device 选择您的 CD 驱动器 Choose your CDROM device. It will be used to play VCDs and Audio CDs. 选择您的 CDROM 驱动器。它将用于播放 VCD 和音频 CD。 DVD device 选择您的 DVD 驱动器 Choose your DVD device. It will be used to play DVDs. 选择您的 DVD 驱动器。它将用于播放 DVD。 If this option is checked, SMPlayer will play DVDs using dvdnav. Requires a recent version of MPlayer compiled with dvdnav support. 如果勾选此项,视频播放器会使用 dvdnav 播放 DVD。需要启用了 dvdnav 支持的较新版 MPlayer Select your &CD device: 选择您的 CD 驱动器(&C): Select your &DVD device: 选择您的 DVD 驱动器(&D): Select your &Blu-ray device: 选择您的 Blu-ray 驱动器(&B): SMPlayer does not choose any CDROM or DVD devices by default. So before you can actually play a CD or DVD you have to select the devices you want to use (they can be the same). 视频播放器默认不会选择任何 CDROM 或 DVD 驱动器。因此在您实际播放 CD 或 DVD 之前,您必须选择您想要使用的驱动器(它们可以是相同的)。 Blu-ray device Blu-ray驱动器 Choose your Blu-ray device. It will be used to play Blu-ray discs. 选择您的 Blu-ray 驱动器。它将用于播放蓝光光盘。 Enable DVD menus 启用 DVD 菜单 <b>Note 1</b>: cache will be disabled, this can affect performance. <b>注意 1</b>: 缓存将被禁用,这会影响性能。 <b>Note 2</b>: you may want to assign the action "activate option in DVD menus" to one of the mouse buttons. <b>注意 2</b>: 您可能需要指派"激活 DVD 菜单中的选项"动作到某一鼠标按钮。 <b>Note 3</b>: this feature is under development, expect a lot of issues with it. <b>注意 3</b>: 此功能正在开发中,估计它的问题很多。 &Enable DVD menus (experimental) 启用 DVD 菜单(试验)(&E) &Scan for CD/DVD drives 扫描 CD/DVD 驱动器(&S) PrefGeneral General 常规 &General 常规(&G) Media settings 媒体设置 Start videos in fullscreen 以全屏开始视频 Disable screensaver 禁用屏幕保护程序 Select the mplayer executable 选择 MPlayer 可执行文件 7 (6.1 Surround) 7 (6.1 环绕声) 8 (7.1 Surround) 8 (7.1 环绕声) Executables 可执行文件 All files 所有文件 Select a directory 选择一个目录 %1 &executable: %1 可执行文件(&e): Default 默认 %1 executable %1 可执行文件 Here you must specify the %1 executable that SMPlayer will use. 你必须在这里指定 %1 可执行文件的位置。 Screenshots folder 屏幕截图文件夹 Here you can specify a folder where the screenshots taken by Kylin Video will be stored. If the folder is not valid the screenshot feature will be disabled. 在这里您可以指定一个麒麟影音将用来存储屏幕截图的文件夹。如果文件夹是无效的,屏幕截图功能将被禁用。 Template for screenshots 屏幕截图模板 For example %1 would save the screenshot as 'moviename_0001.png'. 例如,%1 将会将截图保存为 ‘moviename_0001.png’ 。 %1 specifies the filename of the video without the extension, %2 adds a 4 digit number padded with zeros. %1 指定视频的文件名(不含扩展名), %2 在之后添加 4位数,不够的用0填充。 Format for screenshots 截屏样式 This option allows you to choose the image file type used for saving screenshots. 此选项让您选择视频截图的格式。 If this option is enabled, the computer will shut down just after SMPlayer is closed. 如果启用此选项,视频播放器关闭后电脑会跟着关闭 Video output driver 视频输出驱动 Audio output driver 音频输出驱动 Select the audio output driver. 选择音频输出驱动。 Remember settings 记住所有文件的设置 Preferred audio language 首选音频语言 Preferred subtitle language 首选字幕语言 Software video equalizer 使用软件视频均衡器 This option specifies the filename template used to save screenshots. 此选项定义保存视频截屏时使用的文件名模板。 For a full list of the template specifiers visit this link: 完整模板说明符列表请访问此链接: This option only works with mpv. 此选项仅适用于mpv。 Shut down computer 关机 You can check this option if video equalizer is not supported by your graphic card or the selected video output driver.<br><b>Note:</b> this option can be incompatible with some video output drivers. 如果您的显示卡或所选的视频输出驱动不支持视频均衡器,您可以勾选此选项。<br><b>注意:</b> 此选项可能与某些视频输出驱动不兼容。 If this option is checked, all videos will start to play in fullscreen mode. 如果勾选此选项,所有视频都将以全屏模式开始播放。 Global audio equalizer 全局音频均衡器 If this option is checked, all media files share the audio equalizer. 如果勾选此项,所有媒体文件使用相同的均衡器 If it's not checked, the audio equalizer values are saved along each file and loaded back when the file is played later. 如果不勾选,音频均衡设置会和文件关联保存,当文件再次播放时使用这个设置 Software volume control 使用软件音量控制 Check this option to use the software mixer, instead of using the sound card mixer. 勾选此选项以使用软件混音器,而不使用声卡混音器。 Postprocessing quality 后期处理质量 Dynamically changes the level of postprocessing depending on the available spare CPU time. The number you specify will be the maximum level used. Usually you can use some big number. 根据可用的 CPU 空闲时间动态更改后期处理的级别。您指定的数字将被作为最高级别使用。通常您可以使用大一些的数字。 &Audio: 音频(&A): &Remember settings for all files (audio track, subtitles...) 记住所有文件的设置(音轨、字幕...)(&R) Su&btitles: 字幕(&B): &Quality: 质量(&Q): Temp&late: 模板(&l): F&ormat: 格式(&o) : S&hut down computer 关机(&S) Start videos in &fullscreen 以全屏开始视频(&F) Disable &screensaver 禁用屏幕保护程序(&S) Global audio e&qualizer 全局音频均衡器(&e) Use s&oftware volume control 使用软件音量控制(&O) Ma&x. Amplification: 最大放大率(&X): &AC3/DTS pass-through S/PDIF AC3/DTS 直通 S/PDIF(&A) Direct rendering 直接渲染 Double buffering 双缓冲 D&irect rendering 直接渲染(&I) Dou&ble buffering 双缓冲(&B) Double buffering fixes flicker by storing two frames in memory, and displaying one while decoding another. If disabled it can affect OSD negatively, but often removes OSD flickering. 通过在内存中存储两帧,在显示一帧的同时解码另一帧的双缓冲来修复闪烁问题。如果禁用它会对 OSD (屏幕显示)产生负面影响,但常常能去除 OSD (屏幕显示)的闪烁。 &Enable postprocessing by default 默认启用后期处理(&E) Volume &normalization by default 默认音量标准化(&N) Close when finished 结束播放时关闭 If this option is checked, the main window will be automatically closed when the current file/playlist finishes. 如果勾选此选项,当前的文件/播放列表结束时,主窗口将自动关闭。 2 (Stereo) 2 (立体声) 4 (4.0 Surround) 4 (4.0 环绕声) 6 (5.1 Surround) 6 (5.1 环绕声) C&hannels by default: 默认声道(&H): &Pause when minimized 最小化时暂停(&P) Pause when minimized 最小化时暂停 MPlayer MPlayer MPV MPV Playback engine: 播放引擎: Preview when video is playing 视频播放时进行预览 Enable postprocessing by default 默认启用后期处理 Max. Amplification 最大放大率 AC3/DTS pass-through S/PDIF AC3/DTS 直通 S/PDIF Volume normalization by default 默认音量标准化 Maximizes the volume without distorting the sound. 声音没有失真的最大音量。 Channels by default 默认声道 Sets the maximum amplification level in percent (default: 110). A value of 200 will allow you to adjust the volume up to a maximum of double the current level. With values below 100 the initial volume (which is 100%) will be above the maximum, which e.g. the OSD cannot display correctly. 设置最大放大级别的百分比(默认值: 110)。该值为 200 时允许您调整的最大音量为目前级别的两倍。该值低于 100 时,初始音量(为100%)将高于可调整的最大值,这时例如 OSD (屏幕显示)将不能正确显示。 Postprocessing will be used by default on new opened files. 默认在新打开的文件上使用后期处理。 Audio track 音频轨道 Specifies the default audio track which will be used when playing new files. If the track doesn't exist, the first one will be used. <br><b>Note:</b> the <i>"preferred audio language"</i> has preference over this option. 指定播放新文件时将使用的默认音轨。如果所选轨道不存在,将使用第一个轨道。<br><b>注意:</b> <i>"首选音频语言"</i> 优先于此选项。 Subtitle track 字幕轨道 Specifies the default subtitle track which will be used when playing new files. If the track doesn't exist, the first one will be used. <br><b>Note:</b> the <i>"preferred subtitle language"</i> has preference over this option. 指定播放新文件时将使用的默认字幕轨道。如果所选轨道不存在,将使用第一个轨道。<br><b>注意:</b> <i>"首选字幕语言"</i> 优先于此选项。 Or choose a track number: 或选择一个轨道号: Audi&o: 音频(&O): Preferred language: 首选语言: Preferre&d audio and subtitles 首选音频和字幕(&D) &Subtitle: 字幕(&S): Here you can type your preferred language for the audio and subtitle streams. When a media with multiple audio or subtitle streams is found, SMPlayer will try to use your preferred language. This only will work with media that offer info about the language of audio and subtitle streams, like DVDs or mkv files.<br>These fields accept regular expressions. Example: <b>es|esp|spa</b> will select the track if it matches with <i>es</i>, <i>esp</i> or <i>spa</i>. 在这里您可以键入您的音频和字幕流的首选语言。当发现媒体具有多个音频或字幕流时,视频播放器将尝试使用您的首选语言。这仅工作于提供音频和字幕流语言信息的媒体,比如 DVD 或 MKV 文件。<br>这些字段接受正则表达式。示例: <b>es|esp|spa</b> 将选择匹配 <i>es</i>、<i>esp</i> 或 <i>spa</i> 的轨道。 High speed &playback without altering pitch 高速播放而不改变音调(&P) High speed playback without altering pitch 高速播放而不改变音调 Allows you to change the playback speed without altering pitch. Requires at least MPlayer dev-SVN-r24924. 允许更改播放速度而不改变音调。至少需要 MPlayer dev-SVN-r24924。 &Video 视频(&V) Use s&oftware video equalizer 使用软件视频均衡器(&O) A&udio 音频(&U) Volume 音量 Video 视频 Audio 音频 Preferred audio and subtitles 首选音频和字幕 None Lowpass5 Lowpass5 Yadif (normal) Yadif (标准) Yadif (double framerate) Yadif (双倍帧率) Linear Blend 线性混合 Kerndeint Kerndeint Deinterlace by default 默认去交错 Select the deinterlace filter that you want to be used for new videos opened. 选择您想在打开新视频时使用的去交错过滤器。 Remember time position 记住时间位置 Remember &time position 记住时间位置(&T) Enable the audio equalizer 启用音频均衡器 Check this option if you want to use the audio equalizer. 如果您想使用音频均衡器,请勾选此选项。 &Enable the audio equalizer 启用音频均衡器(&E) Draw video using slices 使用切片方式绘制视频 Enable/disable drawing video by 16-pixel height slices/bands. If disabled, the whole frame is drawn in a single run. May be faster or slower, depending on video card and available cache. It has effect only with libmpeg2 and libavcodec codecs. 启用/禁用以 16-像素高的片/带方式绘制视频。如果禁用,将一次运行绘制整个帧。可能更快或更慢,这取决于显卡和可用的缓存。它只对 libmpeg2 和 libavcodec 编解码器有效果。 Dra&w video using slices 使用切片方式绘制视频(&W) &Close when finished playback 结束播放时关闭(&C) fast 快速 slow 慢速 fast - ATI cards 快速 - ATI 卡 User defined... 用户定义... Default zoom 默认缩放 This option sets the default zoom which will be used for new videos. 此选项可设置将用于新视频的默认缩放级别。 Default &zoom: 默认缩放(&Z): If this setting is wrong, SMPlayer won't be able to play anything! 如果此设置是错误的,视频播放器将无法播放任何东西! Select the video output driver. %1 provides the best performance. 选择视频输出驱动。%1 可提供最佳性能。 %1 is the recommended one. Try to avoid %2 and %3, they are slow and can have an impact on performance. 推荐使用 %1。尽量避免 %2 和 %3,它们速度很慢,且会影响性能。 Usually SMPlayer will remember the settings for each file you play (audio track selected, volume, filters...). Disable this option if you don't like this feature. 通常视频播放器将记住您所播放的每个文件的设置(音轨选择、音量、过滤器...)。如果您不喜欢这个功能,请禁用此选项。 If this option is enabled, the file will be paused when the main window is hidden. When the window is restored, playback will be resumed. 如果启用此选项,主窗口处于隐藏状态时,文件将被暂停。窗口还原时,将恢复播放。 Preview when the video is playing 视频播放时进行预览 If this option is enabled, the video preview will be displayed when the mouse is placed on the progress bar. 如果此选项打开,则当鼠标放置在进度条上时,会显示视频预览图。 Select MPlayer as playback engine 选择 MPlayer 作为播放引擎 If you change the playback engine to MPlayer, please restart Kylin Video. 如果你切换播放引擎为MPlayer,请重启麒麟影音。 Select MPV as playback engine 选择 MPV 作为播放引擎 If you change the playback engine to MPV, please restart Kylin Video. 如果你切换播放引擎为MPV,请重启麒麟影音。 Check this option to disable the screensaver while playing.<br>The screensaver will enabled again when play finishes. 勾选此选项可在播放时禁用屏幕保护程序。<br>播放结束时屏幕保护程序将再次启用。 Here you can type your preferred language for the audio streams. When a media with multiple audio streams is found, SMPlayer will try to use your preferred language.<br>This only will work with media that offer info about the language of the audio streams, like DVDs or mkv files.<br>This field accepts regular expressions. Example: <b>es|esp|spa</b> will select the audio track if it matches with <i>es</i>, <i>esp</i> or <i>spa</i>. 在这里您可以键入您的音频流首选语言。当发现媒体具有多个音频流时,视频播放器将尝试使用您的首选语言。<br>这仅工作于提供音频流语言信息的媒体,比如 DVD 或 MKV 文件。<br>这些字段接受正则表达式。示例: <b>es|esp|spa</b> 将选择匹配 <i>es</i>、<i>esp</i> 或 <i>spa</i> 的音轨。 Here you can type your preferred language for the subtitle stream. When a media with multiple subtitle streams is found, SMPlayer will try to use your preferred language.<br>This only will work with media that offer info about the language of the subtitle streams, like DVDs or mkv files.<br>This field accepts regular expressions. Example: <b>es|esp|spa</b> will select the subtitle stream if it matches with <i>es</i>, <i>esp</i> or <i>spa</i>. 在这里您可以键入您的字幕流首选语言。当发现媒体具有多个字幕流时,视频播放器将尝试使用您的首选语言。<br>这仅工作于提供字幕流语言信息的媒体,比如 DVD 或 MKV 文件。<br>这些字段接受正则表达式。示例: <b>es|esp|spa</b> 将选择匹配 <i>es</i>、<i>esp</i> 或 <i>spa</i> 的字幕流。 Ou&tput driver: 输出驱动(&T): Add black borders on fullscreen 全屏时添加黑边 If this option is enabled, black borders will be added to the image in fullscreen mode. This allows subtitles to be displayed on the black borders. 如果启用此选项,则会在全屏模式的图像上添加黑色边框。这将允许字幕显示在黑色边框上。 &Add black borders on fullscreen 全屏时添加黑边(&A) one ini file 一个 ini 文件 multiple ini files 多个 ini 文件 Method to store the file settings 存储文件设置的方法 This option allows you to change the way the file settings would be stored. The following options are available: 此选项允许更改存储文件设置的方式。可使用以下选项: <b>one ini file</b>: the settings for all played files will be saved in a single ini file (%1) <b>一个 ini 文件</b>: 所有播放过的文件的设置将被保存于单个 ini 文件(%1)中 The latter method could be faster if there is info for a lot of files. 如果有大量的文件信息,后一种方法可能会更快。 &Store settings in 存储设置于(&S) <b>multiple ini files</b>: one ini file will be used for each played file. Those ini files will be saved in the folder %1 <b>多个 ini 文件</b>: 每个播放过的文件都将使用其自己的 ini 文件。这些 ini 文件将被保存于文件夹 %1 中 If you check this option, SMPlayer will remember the last position of the file when you open it again. This option works only with regular files (not with DVDs, CDs, URLs...). 如果您勾选此选项,视频播放器将记住文件的最后播放位置,当您再次打开它时可由该位置开始播放。此选项仅适用于常规文件(不包括 DVD、CD、URL...)。 If checked, turns on direct rendering (not supported by all codecs and video outputs)<br><b>Warning:</b> May cause OSD/SUB corruption! 如果勾选,将打开直接渲染(还不被所有的编解码器和视频输出支持)<br><b>警告:</b> 可能会导致 OSD (屏幕显示)/SUB 的讹误! Requests the number of playback channels. MPlayer asks the decoder to decode the audio into as many channels as specified. Then it is up to the decoder to fulfill the requirement. This is usually only important when playing videos with AC3 audio (like DVDs). In that case liba52 does the decoding by default and correctly downmixes the audio into the requested number of channels. <b>Note</b>: This option is honored by codecs (AC3 only), filters (surround) and audio output drivers (OSS at least). 指定播放声道的数量。MPlayer 告诉解码器需要将音频解码成多少声道,再由解码器来实现此需求。通常只有在播放带有 AC3 音频(比如 DVD)的视频时才有用。在该情况下将默认使用 liba52 解码并把音频正确地混合成需要的声道数量。<b>注意</b>: 此选项需要 编码(仅 AC3)、过滤器(环绕声)和音频输出驱动(OSS或更高级)三者都满足。 Enable screenshots 启用屏幕截图 You can use this option to enable or disable the possibility to take screenshots. 您可以使用此选项启用或禁用是否可以进行屏幕截图。 Here you can specify a folder where the screenshots taken by SMPlayer will be stored. If the folder is not valid the screenshot feature will be disabled. 在这里您可以指定一个视频播放器将用来存储屏幕截图的文件夹。如果文件夹是无效的,屏幕截图功能将被禁用。 Screenshots 屏幕截图 &Enable screenshots 启用屏幕截图(&E) &Folder: 文件夹(&F): Global volume 全局音量 If this option is checked, the same volume will be used for all files you play. If the option is not checked each file uses its own volume. 如果勾选此选项,您播放的所有文件都将使用相同的音量。如果此选项未被勾选,每个文件将使用其自己的音量。 This option also applies for the mute control. 此选项也适用于静音控制。 Glo&bal volume 全局音量(&B) Switch screensaver off 切换关闭屏幕保护程序 This option switches the screensaver off just before starting to play a file and switches it on when playback finishes. If this option is enabled, the screensaver won't appear even if playing audio files or when a file is paused. 此选项仅在开始播放文件之前切换关闭屏幕保护程序,当播放结束时将切换开启屏幕保护程序。如果启用此选项,即使是播放音频文件或文件暂停时,屏幕保护程序也不会出现。 Avoid screensaver 避免屏幕保护程序 When this option is checked, SMPlayer will try to prevent the screensaver to be shown when playing a video file. The screensaver will be allowed to be shown if playing an audio file or in pause mode. This option only works if the SMPlayer window is in the foreground. 勾选此选项时,视频播放器将尝试阻止在播放视频文件时显示屏幕保护程序。如果是播放音频文件或处于暂停模式,屏幕保护程序将被允许显示。此选项仅适用于视频播放器窗口位于前台时。 Screensaver 屏幕保护程序 Swit&ch screensaver off 切换关闭屏幕保护程序(&C) Avoid &screensaver 避免屏幕保护程序(&S) Audio/video auto synchronization 音频/视频自动同步 Gradually adjusts the A/V sync based on audio delay measurements. 基于音频延迟的测量值逐步调整 A/V 同步。 A-V sync correction A-V 同步修正 Maximum A-V sync correction per frame (in seconds) 每帧的最大 A-V 同步修正(以秒为单位) Synchronization 同步 Audio/video auto &synchronization 音频/视频自动同步(&S) &Factor: 因子(&F): A-V sync &correction A-V 同步修正(&C) &Max. correction: 最大修正(&M): <b>Note:</b> This option won't be used for TV channels. <b>注意:</b> 此选项不会用于电视频道。 Dei&nterlace by default (except for TV): 默认去交错(不包括电视)(&N): Uses hardware AC3 passthrough. 使用硬件 AC3 直通输出。 <b>Note:</b> none of the audio filters will be used when this option is enabled. <b>注意:</b> 启用此选项时将不会使用音频过滤器。 snap mode Snap 模式 slower dive mode 较慢的 DIVE 模式 uniaud mode UniAud 模式 dart mode DART 模式 %1 is the recommended one. %2 is only available on older MPlayer (before version %3) 推荐使用 %1。%2 仅适用于较旧的 MPlayer (%3 之前的版本) Configu&re... 配置(&R)... PrefInput Keyboard and mouse 键盘和鼠标 &Keyboard 键盘(&K) &Mouse 鼠标(&M) Button functions: 按钮功能: Don't &trigger the left click action with a double click 不要用双击来触发左击(&t) Media seeking 媒体定位 Volume control 音量控制 Zoom video 缩放视频 None Here you can change any key shortcut. To do it double click or press enter over a shortcut cell. Optionally you can also save the list to share it with other people or load it in another computer. 在这里您可以更改任何快捷键。要做到这一点,请在一个快捷键单元格上双击或按回车。您也可以选择保存该列表以与其他人分享,或在另一台计算机上加载。 Here you can change any key shortcut. To do it double click or start typing over a shortcut cell. Optionally you can also save the list to share it with other people or load it in another computer. 在这里您可以更改任何快捷键。要做到这一点,请在一个快捷键单元格上双击以开始键入。您也可以选择保存该列表以与其他人分享,或在另一台计算机上加载。 &Left click 左键单击(&L) &Double click 双击(&D) &Wheel function: 滚轮功能(&W): Shortcut editor 快捷键编辑器 This table allows you to change the key shortcuts of most available actions. Double click or press enter on a item, or press the <b>Change shortcut</b> button to enter in the <i>Modify shortcut</i> dialog. There are two ways to change a shortcut: if the <b>Capture</b> button is on then just press the new key or combination of keys that you want to assign for the action (unfortunately this doesn't work for all keys). If the <b>Capture</b> button is off then you could enter the full name of the key. 此表格允许您更改大多数现有动作的快捷键。在一个项目上双击或按回车,或按 <b>更改快捷键</b> 按钮可进入 <i>修改快捷键</i> 对话框。有两种方法来更改快捷键: 如果 <b>捕捉</b> 按钮已启用,那么只需按下您想要指派给此动作的新按键或组合键(很遗憾这并不适用于所有的按键)。如果 <b>捕捉</b> 按钮已关闭,那么您可以输入按键的完整名称。 Left click 左键单击 Select the action for left click on the mouse. 选择单击鼠标左键的动作。 Double click 双击 Select the action for double click on the mouse. 选择双击鼠标的动作。 Wheel function 滚轮功能 Select the action for the mouse wheel. 选择鼠标滚轮的动作。 Play 播放 Pause 暂停 Stop 停止 Fullscreen 全屏 Compact 简洁模式 Screenshot 屏幕截图 Mute 静音 Frame counter 帧计数器 Reset zoom 重置缩放 Exit fullscreen 退出全屏 Double size 双倍大小 Play / Pause 播放/暂停 Pause / Frame step 暂停/逐帧步进 Playlist 播放列表 Preferences 首选项 No function 无功能 Change speed 更改速度 Normal speed 正常速度 Keyboard 键盘 Mouse 鼠标 Middle click 中键单击 Select the action for middle click on the mouse. 选择单击鼠标中键的动作。 M&iddle click 中键单击(&I) X Button &1 X 按钮 1(&1) X Button &2 X 按钮 2(&2) Go backward (short) 后退(短) Go backward (medium) 后退(中) Go backward (long) 后退(长) Go forward (short) 前进(短) Go forward (medium) 前进(中) Go forward (long) 前进(长) OSD - Next level 屏幕显示 - 下一层 Show context menu 显示上下文菜单 &Right click 右键单击(&R) Increase volume 增加音量 Decrease volume 降低音量 X Button 1 X 按钮 1 Select the action for the X button 1. 选择 X 按钮 1 的动作。 X Button 2 X 按钮 2 Select the action for the X button 2. 选择 X 按钮 2 的动作。 Show video equalizer 显示视频均衡器 Show audio equalizer 显示音频均衡器 Always on top 始终在最前端 Never on top 从不在最前端 On top while playing 当播放时在最前端 Next chapter 下一个章节 Previous chapter 上一个章节 Activate option under mouse in DVD menus 激活 DVD 菜单中的选项 Return to main DVD menu 返回 DVD 主菜单 Return to previous menu in DVD menus 返回上一级 DVD 菜单 Move cursor up in DVD menus DVD 菜单中向上移动光标 Move cursor down in DVD menus DVD 菜单中向下移动光标 Move cursor left in DVD menus DVD 菜单中向左移动光标 Move cursor right in DVD menus DVD 菜单中向右移动光标 Activate highlighted option in DVD menus 激活 DVD 菜单中高亮显示的选项 Don't trigger the left click function with a double click 不要用双击来触发左击(&t) If this option is enabled when you double click on the video area only the double click function will be triggered. The left click action won't be activated. 如果开启此选项,当你在视频区域双击时,只会触发双击行为。左键行为不会被启动 By enabling this option the left click is delayed %1 milliseconds because it's necessary to wait that time to know if there's a double click or not. 启用此项,左击后会先有个%1毫秒的延迟,再执行单击操作,如果此延迟内再次单击,则是双击操作。 Change function of wheel 更改滚轮功能 Media &seeking 媒体定位(&S) &Zoom video 缩放视频(&Z) &Volume control 音量控制(&V) &Change speed 更改速度(&C) Mouse wheel functions 鼠标滚轮功能 Check it to enable seeking as one function. 勾选它以启用"定位"作为一个功能。 Check it to enable changing volume as one function. 勾选它以启用"更改音量"作为一个功能。 Check it to enable zooming as one function. 勾选它以启用"缩放"作为一个功能。 Check it to enable changing speed as one function. 勾选它以启用"更改速度"作为一个功能。 M&ouse wheel functions 鼠标滚轮功能(&O) Select the actions that should be cycled through when using the "Change function of wheel" option. 选择使用"更改滚轮功能"选项时应循环的动作。 Reverse mouse wheel seeking 反向滚轮媒体定位 Check it to seek in the opposite direction. 勾选它以启用"反向定位"。 R&everse wheel media seeking 反向滚轮媒体定位(&E) PrefInterface Interface 界面 <Autodetect> <自动检测> Default 默认 &Interface 界面(&I) Never 从不 Whenever it's needed 当需要时 Only after loading a new video 仅在加载新视频后 Privac&y 隐私(&Y) Recent files 最近的文件 Language 语言 Here you can change the language of the application. 在这里您可以更改应用程序的语言。 &Short jump 短跳转(&S) &Medium jump 中等跳转(&M) &Long jump 长跳转(&L) Mouse &wheel jump 鼠标滚轮跳转(&W) &Use only one running instance of SMPlayer 仅使用一个正在运行的视频播放器实例(&U) Ma&x. items 最大项目数(&X) St&yle: 样式(&Y): Ico&n set: 图标集(&N): L&anguage: 语言(&A): Main window 主窗口 Auto&resize: 自动调整大小(&R): Center &window 居中窗口(&w) R&emember position and size 记住位置和大小(&E) &Move the window when the video area is dragged 拖动视频区域时移动窗口(&M) S&kin: 皮肤(K): Default font: 默认字体: &Change... 更改(&C)... &Behaviour of time slider: 时间滑块行为(&B): Seek to position while dragging 定位到拖动时的位置 Seek to position when released 定位到放开时的位置 Pressi&ng the stop button once resets the time position 按下停止按钮会重置时间位置(&N) The floating control appears in fullscreen mode when the mouse is moved. 全屏模式下当鼠标移动时浮动控制将会出现。 Show only when moving the mouse to the &bottom of the screen 仅在鼠标移动到屏幕底部时出现(&b) Tim&e (in milliseconds) to hide the control: 隐藏控制条的时间(毫秒): URLs URL &Max. items 最大项目数(&M) &Remember last directory 记住上次的目录(&R) TextLabel 文本标签 &Seeking 定位(&S) &Absolute seeking 绝对定位(&A) &Relative seeking 相对定位(&R) Ins&tances 实例(&T) Autoresize 自动调整大小 The main window can be resized automatically. Select the option you prefer. 主窗口可以自动调整大小。请选择您喜欢的选项。 Remember position and size 记住位置和大小 If you check this option, the position and size of the main window will be saved and restored when you run SMPlayer again. 如果您勾选此选项,主窗口的位置和大小将被保存,当您再次运行视频播放器时将恢复它们。 Select the graphic interface you prefer for the application. 选择您喜欢的程序外观。 The <b>Basic GUI</b> provides the traditional interface, with the toolbar and control bar. <b>基础 GUI</b> 提供传统的界面,拥有工具栏和控制栏 The <b>Mini GUI</b> provides a more simple interface, without toolbar and a control bar with few buttons. <b>迷你 GUI</b> 提供一个更为简洁的界面,没有工具栏,有一个拥有很少按钮的控制栏 The <b>Skinnable GUI</b> provides an interface where several skins are available. <b>可换肤 GUI</b>提供一个支持皮肤的界面 The <b>Mpc GUI</b> looks like the interface in Media Player Classic. <b>Mpc GUI</b> 界面和 Media Player Classic 长得很像 Privacy 隐私 Select the maximum number of items that will be shown in the <b>Open->Recent files</b> submenu. If you set it to 0 that menu won't be shown at all. 选择将显示在 <b>打开 -> 最近的文件</b> 子菜单中的最大项目数。如果您将它设置为 0,将不会显示此菜单。 Icon set 图标集 Basic GUI 基础GUI Skinnable GUI 可换肤 GUI Center window 居中窗口 When this option is enabled, the main window will be centered on the desktop. 如果启用此选项,主窗口将会显示在桌面的正中央。 Move the window when the video area is dragged 拖动视频区域时移动窗口 If this option is checked, the main window will be moved if you drag the mouse over the video area. 如果此选项打开,如果用鼠标拖动视频区域时主窗口会跟着移动 Select the icon set you prefer for the application. 选择您喜欢的应用程序图标集。 Skin 皮肤 Select the skin you prefer for the application. Only available with the skinnable GUI. 选择您喜欢的应用程序皮肤。仅适用于"可换肤 GUI"。 Style 样式 Select the style you prefer for the application. 选择您喜欢的应用程序样式。 Default font 默认字体 You can change here the application's font. 您可以在这里更改应用程序的字体。 Seeking 定位 Short jump 短跳转 Select the time that should be go forward or backward when you choose the %1 action. 选择当您选定"%1"动作时应前进或后退的时间。 short jump 短跳转 Medium jump 中等跳转 medium jump 中等跳转 Long jump 长跳转 long jump 长跳转 Mouse wheel jump 鼠标滚轮跳转 Select the time that should be go forward or backward when you move the mouse wheel. 选择当您滚动鼠标滚轮时应前进或后退的时间。 Behaviour of time slider 时间滑块行为 Select what to do when dragging the time slider. 选择拖动时间滑块时该做什么。 Pressing the stop button once resets the time position 按下停止按钮会重置时间位置 By default when the stop button is pressed the time position is remembered so if you press play button the media will resume at the same point. You need to press the stop button twice to reset the time position, but if this option is checked the time position will be set to 0 with only once press of the stop button. 默认情况下,按下停止按钮后会记录时间位置再停止播放,下次按了播放键后会继续播放。你必须按两下停止按钮才能重置时间,如果勾选此项,只需按一下停止键就能将时间重置为0 Show only when moving the mouse to the bottom of the screen 仅在鼠标移动到屏幕底部时出现 If this option is checked, the floating control will only be displayed when the mouse is moved to the bottom of the screen. Otherwise the control will appear whenever the mouse is moved, no matter its position. 如果勾选此项,浮动控制条仅会在鼠标移动到屏幕底部时显示。否则浮动控制框只要在鼠标移动时就显示 If this option is enabled, the floating control will appear in compact mode too. 如果启用此选项,浮动控制条将出现在简洁模式中。 This option only works with the basic GUI. 此选项仅适用于基础GUI <b>Warning:</b> the floating control has not been designed for compact mode and it might not work properly. <b>警告:</b> 浮动控制条并不是为简洁模式而设计的,它可能无法正常工作。 Time to hide the control 隐藏控制条的时间 Sets the time (in milliseconds) to hide the control after the mouse went away from the control. 设置鼠标离开控制条后,控制条隐藏的时间(毫秒) Max. URLs URL Select the maximum number of items that the <b>Open->URL</b> dialog will remember. Set it to 0 if you don't want any URL to be stored. 选择 <b>打开 -> URL</b> 对话框将记住的最大项目数。如果您不想存储任何 URL,请将它设置为 0。 Remember last directory 记住上次的目录 If this option is checked, SMPlayer will remember the last folder you use to open a file. 如果勾选此选项,视频播放器将记住上次您用来打开文件时的文件夹。 Seeking method 定位方法 Sets the method to be used when seeking with the slider. Absolute seeking may be a little bit more accurate, while relative seeking may work better with files with a wrong length. 设置用滑块定位时所使用的方法。绝对定位可能更精确一点,而相对定位可以在文件有错误长度时更好地工作。 Instances 实例 Use only one running instance of SMPlayer 仅使用一个正在运行的视频播放器实例 Check this option if you want to use an already running instance of SMPlayer when opening other files. 如果您想要在打开其他文件时使用一个已经运行的视频播放器实例,请勾选此选项。 Mini GUI 迷你 GUI GUI GUI &GUI GUI(&G) Floating control 浮动控制条 Animated 动画 If this option is enabled, the floating control will appear with an animation. 如果启用此选项,浮动控制条将以动画形式出现。 Width 宽度 Specifies the width of the control (as a percentage). 指定浮动控制条的宽度(以百分比表示)。 Margin 边距 This option sets the number of pixels that the floating control will be away from the bottom of the screen. Useful when the screen is a TV, as the overscan might prevent the control to be visible. 此选项可设置浮动控制框与屏幕底部距离的像素数。当屏幕是电视时有用,因为过扫描可能会阻碍浮动控制的可见性。 Display in compact mode too 在简洁模式中显示 &Floating control 浮动控制条(&F) &Animated 动画(&A) &Width: 宽度(&W): 0 0 &Margin: 边距(&M): Display in &compact mode too 在简洁模式中显示(&C) Mpc GUI MPC GUI Hide video window when playing audio files 播放音频文件时隐藏视频窗口 If this option is enabled the video window will be hidden when playing audio files. 如果启用此选项,播放音频文件时视频窗口将被隐藏。 &Hide video window when playing audio files 播放音频文件时隐藏视频窗口(&H) Precise seeking 精确定位 If this option is enabled, seeks are more accurate but they can be a little bit slower. May not work with some video formats. 如果启用此选项,定位会更精确,但它稍有点慢。可能无法同一些视频格式正常工作。 Note: this option only works with MPlayer2 注意: 此选项仅适用于 MPlayer2 &Precise seeking 精确定位(&P) PrefNetwork &Youtube (and other sites) &Youtube (以及其他网站) &Enable Youtube internal support 启用 Youtube 内部支持 (&E) Playback &quality 播放质量 (&q) &User agent 用户代理 (&U) Enable &MPV's support for streaming sites 启用 &MPV 流媒体网站支持 &Proxy 代理(&P) &Enable proxy 启用代理(&E) &Host: 主机(&H): &Port: 端口(&P): &Username: 用户名(&U): Pa&ssword: 密码(&s): &Type: 类型(&T): HTTP HTTP SOCKS5 SOCKS5 Network 网络 Youtube Youtube Enable Youtube internal support 启用 Youtube 内部支持 If this option is checked, SMPlayer will try to play videos from Youtube URLs. 如果勾选此项,视频播放器将尝试从 Youtube 链接播放视频。 Youtube quality Youtube 质量 Select the preferred quality for youtube videos. 选择 Youtube 视频优先选用的画质质量。 User agent 用户代理 Set the user agent that SMPlayer will use when connecting to Youtube. 设置连接 Youtube 时使用的代理。 Enable MPV's support for streaming sites 启用 MPV 流媒体网站支持 If this option is checked, SMPlayer will try to play videos from streaming sites like Youtube, Dailymotion, Vimeo, Vevo, etc. 如果勾选此项,视频播放器将会尝试从 Youtube,DailyMotion,Vimeo,Vevo等流媒体网站播放视频。 Requires mpv and youtube-dl. 需要安装mpv和youtube-dl。 Proxy 代理 Enable proxy 启用代理 Enable/disable the use of the proxy. 启用/禁用代理功能。 Host 主机 The host name of the proxy. 代理服务器主机名。 Port 端口 The port of the proxy. 代理服务器端口号。 Username 用户名 If the proxy requires authentication, this sets the username. 如果代理需要认证,请在这里设置用户名。 Password 密码 The password for the proxy. <b>Warning:</b> the password will be saved as plain text in the configuration file. 代理服务器密码。<b>注意:</b>密码会以明文形式保存在配置文件中。 Type 类型 Select the proxy type to be used. 选择要使用的代理类型 PrefPerformance Performance 性能 &Performance 性能(&P) Priority 优先级 Select the priority for the MPlayer process. 选择 MPlayer 进程的优先级。 realtime 实时 high abovenormal 高于普通 normal 普通 belownormal 低于普通 idle 空闲 Decoding 解码中 Hardware &decoding 硬解 (&d) Cache for local files: 本地文件缓存: KB KB Cache for streams: 流缓存: Decode 解码 Threads for decoding (MPEG-1/2 and H.264 only): 解码线程(仅 MPEG-1/2 和 H.264): Form 表格 Setting a cache may improve performance on slow media 设置缓存可能会提高慢速媒体的性能 Allow frame drop 允许丢帧 Skip displaying some frames to maintain A/V sync on slow systems. 跳过显示一些帧从而在缓慢的系统上保持 A/V 同步。 Allow hard frame drop 允许严重丢帧 More intense frame dropping (breaks decoding). Leads to image distortion! 更加强烈的丢帧(中断解码过程)。将导致图像失真! Priorit&y: 优先级(&Y): &Allow frame drop 允许丢帧(&A) Allow &hard frame drop (can lead to image distortion) 允许严重丢帧(可导致图像失真)(&H) &Fast audio track switching 快速切换音轨(&F) Fast &seek to chapters in dvds 快速定位到 DVD 章节(&S) Fast audio track switching 快速切换音轨 Fast seek to chapters in dvds 快速定位到 DVD 章节 If checked, it will try the fastest method to seek to chapters but it might not work with some discs. 如果勾选,它将尝试以最快的方法定位到章节,但它可能无法工作于某些光盘。 Skip loop filter 跳过环路过滤器 H.264 H.264 Possible values:<br> <b>Yes</b>: it will try the fastest method to switch the audio track (it might not work with some formats).<br> <b>No</b>: the MPlayer process will be restarted whenever you change the audio track.<br> <b>Auto</b>: SMPlayer will decide what to do according to the MPlayer version. 可允许的值:<br> <b>是</b>: 它将尝试以最快的方法来切换音轨(它可能无法工作于某些格式)。<br> <b>否</b>: 每当您更改音轨,MPlayer 进程将重新启动。<br> <b>自动</b>: 视频播放器将根据 MPlayer 版本来决定如何做。 Cache for files 本地文件缓存 This option specifies how much memory (in kBytes) to use when precaching a file. 此选项可指定预缓存文件时要使用多少内存(以 KB 为单位)。 Cache for streams 流缓存 This option specifies how much memory (in kBytes) to use when precaching a URL. 此选项可指定预缓存 URL 时要使用多少内存(以 KB 为单位)。 Cache for DVDs DVD 缓存 This option specifies how much memory (in kBytes) to use when precaching a DVD.<br><b>Warning:</b> Seeking might not work properly (including chapter switching) when using a cache for DVDs. 此选项可指定预缓存 DVD 时要使用多少内存(以 KB 为单位)。<br><b>警告:</b> 使用 DVD 缓存时定位可能无法正常工作(包括章节切换)。 &Cache 缓存(&C) Cache for &DVDs: DVD 缓存(&D): Cache for &local files: 本地文件缓存(&L): Cache for &streams: 流缓存(&S): Enabled 启用 Skip (always) 跳过(始终) Skip only on HD videos 仅跳过高清视频 Loop &filter 环路过滤器(&F) Try to use non-free CoreAVC codec when no other codec is specified and non-VDPAU video output selected. Requires MPlayer build with CoreAVC support. 没有指定其他编解码器和选择了非 VDPAU 视频输出时,将尝试使用非自由的 CoreAVC 编解码器。需要 MPlayer 构建有 CoreAVC 支持。 This option allows you to skips the loop filter (AKA deblocking) during H.264 decoding. Since the filtered frame is supposed to be used as reference for decoding dependent frames this has a worse effect on quality than not doing deblocking on e.g. MPEG-2 video. But at least for high bitrate HDTV this provides a big speedup with no visible quality loss. 此选项允许在 H.264 解码期间跳过环路过滤器(也叫做"去块")。因为经过过滤的帧会被当作解码依赖帧引用,而在质量上这比不对视频(例如 MPEG-2)进行去块的效果更差。但是去块至少对高比特率的 HDTV 提供了不损失视觉品质的大幅加速。 None Auto 自动 Hardware decoding 硬件解码 Sets the hardware video decoding API. If hardware decoding is not possible, software decoding will be used instead. 设置硬件解码 API。如果无法使用硬解,则会使用软解。 Available options: 可用选项: None: only software decoding will be used. 无:仅用软解。 Auto: it tries to automatically enable hardware decoding using the first available method. 自动:自动尝试使用第一种可用的硬解方式。 vdpau: for the vdpau and opengl video outputs. vdpau:用于 vdpau 以及 opengl 显示输出。 vaapi: for the opengl and vaapi video outputs. For Intel GPUs only. vaapi:用于 opengl 以及 vaapi 视频输出。仅支持 Intel GPU。 vaapi-copy: it copies video back into system RAM. For Intel GPUs only. vaapi-copy:将视频拷贝回系统内存中。仅支持 Intel GPU。 dxva2-copy: it copies video back to system RAM. Experimental. dxva2-copy:将视频拷贝回系统内存中。试验性功能。 This option only works with mpv. 此选项仅支持 mpv。 Possible values: 可允许的值: <b>Enabled</b>: the loop filter is not skipped <b>启用</b>: 不跳过环路过滤器 <b>Skip (always)</b>: the loop filter is skipped no matter the resolution of the video <b>跳过(始终)</b>: 跳过环路过滤器,不论视频的分辨率 <b>Skip only on HD videos</b>: the loop filter will be skipped only on videos which height is %1 or greater. <b>仅跳过高清视频</b>: 仅在视频高度是 %1 或更高时环路过滤器将被跳过。 Cache 缓存 Cache for audio CDs 音频 CD 缓存 This option specifies how much memory (in kBytes) to use when precaching an audio CD. 此选项可指定预缓存音频 CD 时要使用多少内存(以 KB 为单位)。 Cache for &audio CDs: 音频 CD 缓存(&A): Cache for VCDs VCD 缓存 This option specifies how much memory (in kBytes) to use when precaching a VCD. 此选项可指定预缓存 VCD 时要使用多少内存(以 KB 为单位)。 Cache for &VCDs: VCD 缓存(&V): Threads for decoding 解码线程 Sets the number of threads to use for decoding. Only for MPEG-1/2 and H.264 设置要用于解码的线程数。仅适用于 MPEG-1/2 和 H.264 &Threads for decoding (MPEG-1/2 and H.264 only): 解码线程(仅 MPEG-1/2 和 H.264)(&T): Set process priority for mplayer according to the predefined priorities available under Windows.<br><b>Warning:</b> Using realtime priority can cause system lockup. 根据 Windows 下可用的预定义优先级设置 MPlayer 进程的优先级。<br><b>警告:</b> 使用实时优先级会导致系统锁死。 Use CoreAVC if no other codec specified 没有指定其他编解码器时使用 CoreAVC &Use CoreAVC if no other codec specified 没有指定其他编解码器时使用 CoreAVC(&U) Cache for &TV: 电视缓存(&T): PrefPlaylist Playlist 播放列表 Automatically add files to playlist 自动将文件添加到播放列表 If this option is enabled, every time a file is opened, SMPlayer will first clear the playlist and then add the file to it. In case of DVDs, CDs and VCDs, all titles in the disc will be added to the playlist. 如果启用此选项,每当打开一个文件时,视频播放器将先清除播放列表,然后再将该文件添加到其中。若是 DVD、CD 和 VCD,光盘中的所有标题都将被添加到播放列表。 None Video files 视频文件 Audio files 音频 Video and audio files 视频和音频文件 Consecutive files 连续的文件 Add files from folder 从文件夹添加 This option allows you to add files automatically to the playlist: 此选项允许自动添加文件到列表 <b>None</b>: no files will be added <b>空</b>: 不会添加任何文件 <b>Video files</b>: all video files found in the folder will be added <b>视频文件</b>: 文件夹中所有视频文件都会被添加 <b>Audio files</b>: all audio files found in the folder will be added <b>音频文件</b>: 文件夹中所有音频文件都会被添加 <b>Video and audio files</b>: all video and audio files found in the folder will be added <b>视频和音频文件</b>: 文件夹中所有视频和音频文件都会被添加 <b>Consecutive files</b>: consecutive files (like video_1.avi, video_2.avi) will be added <b>连续文件</b>: 连续文件(如 video_1.avi, video_2.avi)会被添加 Play files from start 从开头播放文件 If this option is enabled, all files from the playlist will start to play from the beginning instead of resuming from a previous playback. 如果打开此选项,所有播放列表里的文件都会从开始播放而不是从上次播放停止位置开始。 Get info automatically about files added 自动获取新添加文件的信息 Save copy of playlist on exit 退出时保存播放列表的副本 If this option is checked, a copy of the playlist will be saved in the smplayer configuration when smplayer is closed, and it will reloaded automatically when smplayer is run again. 如果勾选此项,当smplayer关闭时,一个播放列表的副本会被保存在smplayer配置文件夹下,在下次smplayer运行时重新载入此文件。 Play next file even if the previous file failed 上个文件播放失败时继续播放下个文件 If this option is enabled, the playlist will ignore playback errors from a previous file and will play the next file in the list. 如果启用此项,播放列表将会忽略此错误并继续播放下个文件。 &Playlist 播放列表(&P) &Automatically add files to playlist 自动将文件添加到播放列表(&A) Add files in directories recursively 添加子目录中的文件 Check this option if you want that adding a directory will also add the files in subdirectories recursively. Otherwise only the files in the selected directory will be added. 如果您想在添加一个目录时也递归添加子目录中的文件,请勾选此选项。否则将只添加所选目录中的文件。 Check this option to inquire the files to be added to the playlist for some info. That allows you to show the title name (if available) and length of the files. Otherwise this info won't be available until the file is actually played. Beware: this option can be slow, specially if you add many files. 勾选此选项可以查询文件添加到播放列表中的一些信息。这将允许显示文件的标题名称(如果可用)和长度。否则在文件被实际播放之前这些信息将不可用。注意: 这个选项可能会很慢,特别是当您添加的文件过多时。 Add files from &folder: 从文件夹添加(&f) P&lay files from start 从开始处播放文件(&L) Add files in directories &recursively 添加子目录中的文件(&R) Get &info automatically about files added (slow) 自动获取文件的信息(较慢)(&I) &Save copy of playlist on exit 退出时保存播放列表的副本(&S) Play &next file even if the previous file failed 上个文件播放失败时继续播放下个文件 (&n) PrefScreenShot &ScreenShot 屏幕截图(&S) Screenshots 屏幕截图 Folder: 文件夹: Template: 模板: Format: 格式: &Enable screenshots 启用屏幕截图(&E) &Folder: 文件夹(&F): Temp&late: 模板(&l): F&ormat: 格式(&o) : Select a directory 选择一个目录 Enable screenshots 启用屏幕截图 You can use this option to enable or disable the possibility to take screenshots. 您可以使用此选项启用或禁用是否可以进行屏幕截图。 Screenshots folder 屏幕截图文件夹 Here you can specify a folder where the screenshots taken by Kylin Video will be stored. If the folder is not valid the screenshot feature will be disabled. 在这里您可以指定一个麒麟影音将用来存储屏幕截图的文件夹。如果文件夹是无效的,屏幕截图功能将被禁用。 Template for screenshots 屏幕截图模板 This option specifies the filename template used to save screenshots. 此选项定义保存视频截屏时使用的文件名模板。 For example %1 would save the screenshot as 'moviename_0001.png'. 例如,%1 将会将截图保存为 ‘moviename_0001.png’ 。 %1 specifies the filename of the video without the extension, %2 adds a 4 digit number padded with zeros. %1 指定视频的文件名(不含扩展名), %2 在之后添加 4位数,不够的用0填充。 For a full list of the template specifiers visit this link: 完整模板说明符列表请访问此链接: This option only works with mpv. 此选项仅适用于mpv。 Format for screenshots 截屏样式 This option allows one to choose the image file type used for saving screenshots. 此选项让您选择视频截图的格式。 This option allows you to choose the image file type used for saving screenshots. 此选项让您选择视频截图的格式。 PrefShortCut Here you can change any key shortcut. To do it double click or press enter over a shortcut cell. 在这里您可以更改任何快捷键。要做到这一点,请在一个快捷键单元格上双击或按回车。 ShortCut 快捷键 Here you can change any key shortcut. To do it double click or start typing over a shortcut cell. 在这里您可以更改任何快捷键。要做到这一点,请在一个快捷键单元格上双击或按回车。 Shortcut Key 快捷键 Shortcut editor 快捷键编辑器 This table allows you to change the key shortcuts of most available actions. Double click or press enter on a item, or press the <b>Change shortcut</b> button to enter in the <i>Modify shortcut</i> dialog. There are two ways to change a shortcut: if the <b>Capture</b> button is on then just press the new key or combination of keys that you want to assign for the action (unfortunately this doesn't work for all keys). If the <b>Capture</b> button is off then you could enter the full name of the key. 此表格允许您更改大多数现有动作的快捷键。在一个项目上双击或按回车,或按 <b>更改快捷键</b> 按钮可进入 <i>修改快捷键</i> 对话框。有两种方法来更改快捷键: 如果 <b>捕捉</b> 按钮已启用,那么只需按下您想要指派给此动作的新按键或组合键(很遗憾这并不适用于所有的按键)。如果 <b>捕捉</b> 按钮已关闭,那么您可以输入按键的完整名称。 PrefSubtitles Subtitles 字幕 &Subtitles 字幕(&S) Autoload 自动加载字幕文件 Autoload subtitles files (*.srt, *.sub...): 自动加载字幕文件(*.srt、*.sub...): Same name as movie 与影片的名称相同 All subs containing movie name 所有包含影片名称的字幕 All subs in directory 目录中的所有字幕 Default subtitle encoding: 默认字幕编码: Try to autodetect for this language: 尝试自动检测此语言: Use the &ASS library 使用 ASS 库(&A) Enable &Windows fonts 启用 Windows 字体(&W) Font 字体 Size 大小 Au&toload subtitles files (*.srt, *.sub...): 自动加载字幕文件(*.srt、*.sub...)(&T): S&elect first available subtitle 选择首个可用的字幕(&E) &Default subtitle encoding: 默认字幕编码(&D): &Include subtitles on screenshots 屏幕截图时包含字幕(&I) Select first available subtitle 选择首个可用的字幕 Default subtitle encoding 默认字幕编码 Include subtitles on screenshots 屏幕截图时包含字幕 Text color 文本颜色 Select the color for the text of the subtitles. 选择字幕的文本颜色。 Border color 边框颜色 Select the color for the border of the subtitles. 选择字幕的边框颜色。 Select the subtitle autoload method. 选择字幕的自动加载方法。 If there are one or more subtitle tracks available, one of them will be automatically selected, usually the first one, although if one of them matches the user's preferred language that one will be used instead. 如果有一个或多个字幕轨道可用,其中一个将被自动选择,通常是第一个,但如果其中一个匹配用户的首选语言,将会改为使用该字幕。 Select the encoding which will be used for subtitle files by default. 选择将用于字幕文件的默认编码。 Try to autodetect for this language 尝试自动检测此语言 When this option is on, the encoding of the subtitles will be tried to be autodetected for the given language. It will fall back to the default encoding if the autodetection fails. This option requires a MPlayer compiled with ENCA support. 开启此选项时,将尝试自动检测指定语言的字幕编码。如果自动检测失败,它将退回到默认的编码。此选项需要 MPlayer 编译有 ENCA 支持。 Subtitle language 字幕语言 Select the language for which you want the encoding to be guessed automatically. 选择您想要用于自动推测编码的语言。 Encoding 编码 Try to a&utodetect for this language: 尝试自动检测此语言(&U): Outline 轮廓 Select the font for the subtitles. 选择字幕的字体。 Use the ASS library 使用 ASS 库 This option enables the ASS library, which allows you to display subtitles with multiple colors, fonts... 此选项会启用 ASS 库,这允许字幕以多种颜色,字体显示... You should normally not disable this option. Do it only if your MPlayer is compiled without freetype support. <b>Disabling this option could make subtitles not to work at all!</b> 您通常不应禁用该选项。除非您的 MPlayer 编译时没有启用 FreeType 支持。<b>禁用该选项可能导致字幕无法工作!</b> Enable Windows fonts 启用 Windows 字体 If this option is enabled the Windows system fonts will be available for subtitles. There's an inconvenience: a font cache have to be created which can take some time. 如果启用此项那么Windows 系统字体将会用于字幕显示。不过有个不便:需要花时间创建字体缓存。 If this option is not checked then only a few fonts bundled with SMPlayer can be used, but this is faster. 如果不勾选此项,那只有视频播放器内置的字体可用,但是更快。 The size in pixels. 以像素为单位的大小。 Bold 粗体 If checked, the text will be displayed in <b>bold</b>. 如果勾选,将以 <b>粗体</b> 显示文本。 Italic 斜体 If checked, the text will be displayed in <i>italic</i>. 如果勾选,将以 <i>斜体</i> 显示文本。 Left margin 左边距 Specifies the left margin in pixels. 以像素为单位指定左边距。 Right margin 右边距 Specifies the right margin in pixels. 以像素为单位指定右边距。 Vertical margin 垂直边距 Specifies the vertical margin in pixels. 以像素为单位指定垂直边距。 Horizontal alignment 水平对齐 Specifies the horizontal alignment. Possible values are left, centered and right. 指定水平对齐方式。可允许的值有 左、居中和右。 Vertical alignment 垂直对齐 Specifies the vertical alignment. Possible values: bottom, middle and top. 指定垂直对齐方式。可允许的值: 底部、中部和顶部。 Border style 边框样式 Specifies the border style. Possible values: outline and opaque box. 指定边框样式。可允许的值: 轮廓和不透明框。 Shadow 阴影 Apply style to ASS files too 将风格也应用到 ASS 文件 Si&ze: 大小(&Z): Bol&d 粗体(&D) &Italic 斜体(&I) Colors 颜色 &Text: 文本(&T): &Border: 边框(&B): Margins 边距 L&eft: 左(&E): &Right: 右(&R): Verti&cal: 垂直(&C): Alignment 对齐方式 &Horizontal: 水平(&H): &Vertical: 垂直(&V): Border st&yle: 边框样式(&Y): &Outline: 轮廓(&O): Shado&w: 阴影(&W): A&pply style to ASS files too 将风格也应用到 ASS 文件(&p) Use custo&m style 使用自定义风格 (&m) The following options allows you to define the style to be used for non-styled subtitles (srt, sub...). 下面的选项允许您定义用于无样式字幕(srt、sub...)的样式。 Left horizontal alignment Centered horizontal alignment 居中 Right horizontal alignment Bottom vertical alignment 底部 Middle vertical alignment 中部 Top vertical alignment 顶部 Outline border style 轮廓 Opaque box border style 不透明框 If border style is set to <i>outline</i>, this option specifies the width of the outline around the text in pixels. 如果边框样式设置为 <i>轮廓</i>,此选项将以像素为单位指定文本周围轮廓的宽度。 If border style is set to <i>outline</i>, this option specifies the depth of the drop shadow behind the text in pixels. 如果边框样式设置为 <i>轮廓</i>,此选项将以像素为单位指定文本后面阴影效果的深度。 This option does NOT change the size of the subtitles in the current video. To do so, use the options <i>Size+</i> and <i>Size-</i> in the subtitles menu. 此选项不会更改当前视频的字幕大小。要执行此操作,请使用字幕菜单中的 <i>大小+</i> 和 <i>大小-</i> 选项。 Default scale 默认缩放 This option specifies the default font scale for SSA/ASS subtitles which will be used for new opened files. 此选项可为新打开的文件指定用于 SSA/ASS 字幕的默认字体缩放。 Line spacing 行距 This specifies the spacing that will be used to separate multiple lines. It can have negative values. 指定将用于分隔多行的间距。它可以是负值。 &Font and colors 字体和颜色(&F) Defa&ult scale: 默认缩放(&U): &Line spacing: 行距(&L): Freetype support FreeType 支持 Freet&ype support FreeType 支持(&Y) If this option is checked, the subtitles will appear in the screenshots. <b>Note:</b> it may cause some troubles sometimes. 如果勾选此选项,字幕将出现在屏幕截图中。<b>注意:</b> 它有时可能会引起一些故障。 Customize SSA/ASS style 自定义 SSA/ASS 样式 Here you can enter your customized SSA/ASS style. 在这里您可以输入您的自定义 SSA/ASS 样式。 Clear the edit line to disable the customized style. 清除编辑行以禁用自定义样式。 SSA/ASS style SSA/ASS 样式 Shadow color 阴影颜色 This color will be used for the shadow of the subtitles. 此颜色将用于字幕的阴影。 Shadow: 阴影: Custo&mize... 自定义(&M)... If this option is checked, the style defined above will be applied to ass subtitles too. 如果勾选此选项,上面定义的样式将被应用到 ASS 字幕。 PrefTV TV and radio 电视和广播 None Lowpass5 Lowpass5 Yadif (normal) Yadif (标准) Yadif (double framerate) Yadif (双倍帧率) Linear Blend 线性混合 Kerndeint Kerndeint Deinterlace by default for TV 默认电视去交错 Select the deinterlace filter that you want to be used for TV channels. 选择您想要用于电视频道的去交错过滤器。 Rescan ~/.mplayer/channels.conf on startup 启动时重新扫描 ~/.mplayer/channels.conf &TV and radio 电视和广播(&T) Dei&nterlace by default for TV: 默认电视去交错(&N): If this option is enabled, SMPlayer will look for new TV and radio channels on ~/.mplayer/channels.conf.ter or ~/.mplayer/channels.conf. 如果启用此选项,视频播放器将在 ~/.mplayer/channels.conf.ter 或 ~/.mplayer/channels.conf 中寻找新的电视和广播频道。 &Check for new channels on startup 启动时检查新频道(&C) PrefUpdates U&pdates 更新(U) Check for &updates 检查更新(&U) Check interval (in &days) 检查间隔(天) &Open an informative page after an upgrade 更新后打开介绍信息页面(&O) Updates 更新 Check for updates 检查更新 If this option is enabled, SMPlayer will check for updates and display a notification if a new version is available. 如果此项开启,视频播放器会检查并提示有更新 Check interval 检查间隔 You can enter here the interval (in days) for the update checks. 你可以输入检查更新的间隔(单位:天) Open an informative page after an upgrade 更新后打开介绍信息页面 If this option is enabled, an informative page about SMPlayer will be opened after an upgrade. 如果启用此项,在更新后会打开一个关于视频播放器的信息页面。 PrefVideo &Video 视频(&V) Ou&tput driver: 输出驱动(&T): &Enable postprocessing by default 默认启用后期处理(&E) Use s&oftware video equalizer 使用软件视频均衡器(&O) D&irect rendering 直接渲染(&I) Dou&ble buffering 双缓冲(&B) Dra&w video using slices 使用切片方式绘制视频(&W) Default 默认 slow 慢速 Video output driver 视频输出驱动 Select the video output driver. %1 provides the best performance. 选择视频输出驱动。%1 可提供最佳性能。 Enable postprocessing by default 默认启用后期处理 Use software video equalizer 使用软件视频均衡器 Output driver: 输出驱动: Postprocessing will be used by default on new opened files. 默认在新打开的文件上使用后期处理。 Software video equalizer 使用软件视频均衡器 You can check this option if video equalizer is not supported by your graphic card or the selected video output driver.<br><b>Note:</b> this option can be incompatible with some video output drivers. 如果您的显示卡或所选的视频输出驱动不支持视频均衡器,您可以勾选此选项。<br><b>注意:</b> 此选项可能与某些视频输出驱动不兼容。 Direct rendering 直接渲染 If checked, turns on direct rendering (not supported by all codecs and video outputs)<br><b>Warning:</b> May cause OSD/SUB corruption! 如果勾选,将打开直接渲染(还不被所有的编解码器和视频输出支持)<br><b>警告:</b> 可能会导致 OSD (屏幕显示)/SUB 的讹误! Double buffering 双缓冲 Double buffering fixes flicker by storing two frames in memory, and displaying one while decoding another. If disabled it can affect OSD negatively, but often removes OSD flickering. 通过在内存中存储两帧,在显示一帧的同时解码另一帧的双缓冲来修复闪烁问题。如果禁用它会对 OSD (屏幕显示)产生负面影响,但常常能去除 OSD (屏幕显示)的闪烁。 Draw video using slices 使用切片方式绘制视频 Enable/disable drawing video by 16-pixel height slices/bands. If disabled, the whole frame is drawn in a single run. May be faster or slower, depending on video card and available cache. It has effect only with libmpeg2 and libavcodec codecs. 启用/禁用以 16-像素高的片/带方式绘制视频。如果禁用,将一次运行绘制整个帧。可能更快或更慢,这取决于显卡和可用的缓存。它只对 libmpeg2 和 libavcodec 编解码器有效果。 PreferencesDialog SMPlayer - Help 视频播放器 - 帮助 General 常规 Video 视频 Audio 音频 Performance 性能 Subtitles 字幕 ScreenShot 屏幕截图 Shortcut Key 快捷键 Cache 缓存 OK 确定 Cancel 取消 Preference 设置 Apply 应用 Help 帮助 SMPlayer - Preferences 视频播放器 - 首选项 Kylin Video - Preferences 麒麟影音 - 设置 Kylin Video - Preference 麒麟影音 - 设置 QObject will show this message and then will exit. 将显示此消息,然后将退出。 the main window will be closed when the file/playlist finishes. 文件/播放列表结束时,主窗口将被关闭。 This is SMPlayer v. %1 running on %2 这是运行在 %2 上的视频播放器 v. %1 tries to make a connection to another running instance and send to it the specified action. Example: -send-action pause The rest of options (if any) will be ignored and the application will exit. It will return 0 on success or -1 on failure. 尝试连接到另一个正在运行的实例,然后向它发送指定的动作。示例: -send-action pause 其余的选项(如果有的话)将被忽略,应用程序将退出。它将在成功时返回 0,失败时返回 -1。 action_list is a list of actions separated by spaces. The actions will be executed just after loading the file (if any) in the same order you entered. For checkable actions you can pass true or false as parameter. Example: -actions "fullscreen compact true". Quotes are necessary in case you pass more than one action. "动作列表"是个由空格隔开的动作列表。动作将仅在加载文件(如果有的话)后按您输入的顺序执行。对于可选的动作,您可以传送 true 或 false 参数。示例: -actions "fullscreen compact true"。在您传送多个动作时必须要用引号。 media 媒体 if there's another instance running, the media will be added to that instance's playlist. If there's no other instance, this option will be ignored and the files will be opened in a new instance. 如果有另外一个实例正在运行,媒体将被添加到该实例的播放列表中。如果没有其他实例,此选项将被忽略,文件将被在一个新实例中打开。 the main window won't be closed when the file/playlist finishes. 文件/播放列表结束时,主窗口将不会被关闭。 the video will be played in fullscreen mode. 视频将在全屏模式下播放。 the video will be played in window mode. 视频将在窗口模式下播放。 Enqueue in SMPlayer 添加到视频播放器队列 opens the mini gui instead of the default one. 打开"迷你 GUI",而不是默认的。 Restores the old associations and cleans up the registry. 恢复原来的关联,然后清理注册表。 Usage: 用法: directory 目录 action_name 动作名称 action_list 动作列表 opens the default gui. 打开"默认 GUI" subtitle_file 字幕文件 specifies the subtitle file to be loaded for the first video. 指定将被首个视频加载的字幕文件。 %n second(s) %n秒 %n minute(s) %n分 %1 and %2 %1 和 %2 specifies the directory where smplayer will store its configuration files (smplayer.ini, smplayer_files.ini...) 指定视频播放器将存储其配置文件(smplayer.ini、smplayer_files.ini...)的目录位置 disabled aspect_ratio 禁用 auto aspect_ratio 自动 unknown aspect_ratio 未知 opens the mpc gui. 打开"MPC GUI" width 宽度 height 高度 opens the gui with support for skins. 打开可换肤 GUI sets the stay on top option to always. 设置为总是置顶。 sets the stay on top option to never. 设置永不置顶。 sets the media title for the first video. 为第一个视频设置媒体标题。 specifies the coordinates where the main window will be displayed. 指定将显示主窗口的坐标位置。 specifies the size of the main window. 指定主窗口的大小。 'media' is any kind of file that SMPlayer can open. It can be a local file, a DVD (e.g. dvd://1), an Internet stream (e.g. mms://....) or a local playlist in format m3u or pls. "媒体"是视频播放器可以打开的任何类型的文件。它可以是本地文件、DVD (例如 dvd://1)、网络流(例如 mms://....)或 m3u/pls 格式的本地播放列表。 SMPlayer is my favorite media player for my PC. Check it out! This text is to be published on twitter and the translation should not be more than 99 characters long 视频播放器是我最喜欢的多媒体播放器。快来看看! This is Kylin Vedio v. %1 running on %2 这是运行在 %2 上的麒麟影音 v. %1 ShareDialog Support SMPlayer 支持视频播放器 &Remind me later 稍后提醒我(&R) Donate with PayPal 使用 PayPal 捐赠 You can support SMPlayer by sending a donation or sharing it with your friends. 你可以通过捐赠或帮助宣传来支持视频播放器 ShareWidget Donate with PayPal 使用 PayPal 捐赠 Share SMPlayer in Facebook 将视频播放器分享到 Facebook Share SMPlayer in Twitter 将视频播放器分享到 Twitter Support SMPlayer 支持视频播放器 Donate / Share SMPlayer with your friends 将视频播放器分享给朋友/捐赠 ShortcutGetter Modify shortcut 修改快捷键 Clear 清除 Press the key combination you want to assign 按下您想要分配的组合键 Add shortcut 添加快捷键 Remove shortcut 移除快捷键 OK 确定 Cancel 取消 Capture 捕捉 Capture keystrokes 捕捉按键 ShortcutsWidget Kylin Video - Shortcuts 麒麟影音 - 快捷键 Forward %1 快进 %1 Rewind %1 快退 %1 Play control 播放控制 Other control 其他控制 Close 关闭 Play/Pause 播放/暂停 Previous 上一个 Next 下一个 Jump to... 跳转到... Mute 静音 Volume + 音量 + Volume - 音量 - Set audio delay 设置音频延迟 Increase or decrease audio delay 增加或减少音频延迟 Playlist 播放列表 About 关于 Quit 退出 FullScreen/Cancel fullScreen 全屏/取消全屏 Audio delay +/-/= 音频延迟 +/-/= Open File 打开文件 Screenshot 屏幕截图 Preferences 设置 View info and properties... 媒体信息... ShutdownDialog Shutting down computer 电脑关机中 Playback has finished. SMPlayer is about to exit. 已播放完毕,视频播放器即将退出。 The computer will shut down in %1 seconds. 电脑将会在 %1 秒内关机 Press <b>Cancel</b> to abort shutdown. 按<b>取消</b>键取消关机 SkinGui &Toolbars 工具栏(&T) Status&bar 状态栏(&B) &Main toolbar 主工具栏(&M) Edit main &toolbar 编辑主工具栏(&T) Edit &floating control 编辑浮动控制条(&F) &Video info 视频信息(&V) &Scroll title 滚屏标题(&S) Playing %1 正在播放 %1 Pause 暂停 Stop 停止 Stereo3dDialog Stereo 3D filter Stereo 3D 滤镜 &3D format of the video: 视频的 3D 格式(&3): &Output format: 输出格式(&O): Side by side parallel (left eye left, right eye right) 左右式(左眼在左,右眼在右) Side by side crosseye (right eye left, left eye right) 左右交叉式(右眼在左,左眼在右) Side by side with half width resolution (left eye left, right eye right) 左右格式半宽分辨率(左眼在左,右眼在右) Side by side with half width resolution (right eye left, left eye right) 左右交叉式半宽分辨率(右眼在左,左眼在右) Above-below (left eye above, right eye below) 上下式3D(左眼在上,右眼在下) Above-below (right eye above, left eye below) 上下式3D(右眼在上,左眼在下) Above-below with half height resolution (left eye above, right eye below) 上下式3D,半分辨率(左眼在上,右眼在下) Above-below with half height resolution (right eye above, left eye below) 上下式3D,半分辨率(右眼在上,左眼在下) Anaglyph red/cyan gray Anaglyph 红/青 灰色 Anaglyph red/cyan half colored Anaglyph 红/青半彩色 Anaglyph red/cyan color Anaglyph 红/青全彩色 Anaglyph red/cyan color optimized with the least-squares projection of Dubois Anaglyph 红/青全色(使用Dubois的小方格投射优化) Anaglyph green/magenta gray Anaglyph 绿/洋红 灰色 Anaglyph green/magenta half colored Anaglyph 绿/洋红半彩色 Anaglyph green/magenta colored Anaglyph 绿/洋红全彩色 Anaglyph yellow/blue gray Anaglyph 黄/蓝 灰色 Anaglyph yellow/blue half colored Anaglyph 黄/蓝半彩色 Anaglyph yellow/blue colored Anaglyph 黄/蓝全彩色 Interleaved rows (left eye has top row, right eye starts on next row) 插入排(左眼在最上一排,然后是右眼) Interleaved rows (right eye has top row, left eye starts on next row) 插入排(右眼在最上一排,然后是左眼) Mono output (left eye only) 单频道输出(仅左眼) Mono output (right eye only) 单频道输出(仅输出右眼) None Auto 自动 SubChooserDialog Subtitle selection 字幕选择 This archive contains more than one subtitle file. Please choose the ones you want to extract. 此存档包含多个字幕文件。请选择您想要提取的。 Select All 选择全部 Select None 取消选择 SupportFormats Video formats 视频格式 Audio formats 音频格式 Subtitles formats 字幕格式 Some video formats do not support preview and seek by dragging, e.g. the swf. 一些视频格式不支持预览和鼠标拖动定位,比如swf。 SupportShortcuts Play control shortcuts 播放控制快捷键 Other control shortcuts 其他控制快捷键 Play/Pause: Space 播放/暂停: Space Previous: Ctrl + < 上一个: Ctrl + < Next: Ctrl + < 下一个: Ctrl + > Forward %1: Right(→) 快进 %1: Right(→) Forward %1: Up(↑) 快进 %1: Up(↑) Forward %1: PgUp 快进 %1: PgUp Rewind %1: Left(←) 快退 %1: Left(←) Rewind %1: Down(↓) 快退 %1: Down(↓) Rewind %1: PgDn 快退 %1: PgDn Jump to...: Ctrl + J 跳转到...: Ctrl + J Mute: M 静音: M Volume +: 9 增加音量: 9 Volume -: 0 降低音量: 0 Set audio delay: Y 设置音频延迟: Y Increase or decrease audio delay: + / - / = 增加或减少音频延迟: + / - / = Playlist: F3 播放列表: F3 Open File: Ctrl + F 打开文件: Ctrl + F Screenshot: S 屏幕截图: S Preferences: Ctrl + P 设置: Ctrl + P View info and properties...: Ctrl + I 媒体信息...: Ctrl + I About: Ctrl + A 关于: Ctrl + A Quit: Ctrl + Q 退出:Ctrl + Q FullScreen/Cancel fullScreen: Ctrl + Enter 全屏/取消全屏: Ctrl + Enter SystemTray Kylin Video 麒麟影音 Open Homepage 打开主界面 Open screenshots folder 打开截图文件夹 Preferences 设置 Help 帮助 About 关于 Information 提示 Show 显示 View &info and properties... 查看信息和属性(&I)... P&references 设置(&R) About &Kylin Video 关于 麒麟影音 About &SMPlayer 关于视频播放器(&S) Quit 退出 TVList Channel editor 频道编辑器 TV/Radio list 电视/广播列表 TimeDialog &Jump to: 跳转到(&J): OK 确定 Seek 定位 Cancel 取消 Jump to: 跳转到: TitleWidget Kylin Video 麒麟影音 ToolbarEditor Toolbar Editor 工具栏编辑器 &Available actions: 可用动作(&A): &Left 向左(&L) &Right 向右(&R) &Down 向下(&D) &Up 向上(&U) Curre&nt actions: 当前动作(&N): &Icon size: 图标大小(&I): Add &separator 添加分隔符(&S) Time slider 时间滑块 Volume slider 音量滑块 Display time 显示时间 3 in 1 rewind 3合1后退 3 in 1 forward 3合1前进 TristateCombo Auto 自动 Yes No UpdateChecker Failed to get the latest version number 获取最新版的版本号失败 New version available 有新版本 A new version of SMPlayer is available. 新版视频播放器出来啦。 Installed version: %1 已安装版本:%1 Available version: %1 可更新版本:%1 Would you like to know more about this new version? 想更加详细地了解新版本? Checking for updates 检查更新中 Congratulations, SMPlayer is up to date. 恭喜,视频播放器已是最新。 Error 错误 An error happened while trying to retrieve information about the latest version available. 或许最新版信息时出错。 Error code: %1 错误代码:%1 VDPAUProperties VDPAU Properties VDPAU 属性 Select the vdpau codecs to use. Not all of them may work. 选择要使用的 VDPAU 编解码器。它们并非都能工作。 ffh&264vdpau ffh264vdpau(&2) ff&mpeg12vdpau ffmpeg12vdpau(&M) ff&wmv3vdpau ffwmv3vdpau(&W) ff&vc1vdpau ffvc1vdpau(&V) ffodiv&xvdpau ffodivxvdpau(&X) &Disable software video filters 禁用软件视频过滤器(&D) VideoEqualizer Video Equalizer 视频均衡器 &Contrast 对比度(&C) &Brightness 亮度(&B) &Hue 色调(&H) &Saturation 饱和度(&S) &Gamma &Gamma Software &equalizer 软件均衡器(&e) Set as &default values 设为默认值(&d) &Reset 重置(&R) Use the current values as default values for new videos. 使用当前的值作为新视频的默认值。 Set all controls to zero. 将全部设置清零。 VideoPreview Video preview 视频预览 Cancel 取消 Thumbnail Generator 缩略图生成器 Generated by SMPlayer 由视频播放器生成 Creating thumbnails... 正在创建缩略图... Size: %1 MB 大小: %1 MB Length: %1 长度: %1 Save file 保存文件 Error saving file 保存文件时出错 The file couldn't be saved 无法保存该文件 Error 错误 The following error has occurred while creating the thumbnails: 创建缩略图时发生以下错误: The temporary directory (%1) can't be created 无法创建临时目录(%1) The mpv process didn't run MPV 进程没有运行 The mplayer process didn't run MPlayer 进程没有运行 Resolution: %1x%2 分辨率: %1x%2 Video format: %1 视频格式: %1 Frames per second: %1 每秒帧数: %1 Aspect ratio: %1 纵横比: %1 The file %1 can't be loaded 无法加载文件 %1 No filename 没有文件名 The mplayer process didn't start while trying to get info about the video 试图获取视频信息时,MPlayer 进程没有启动 The length of the video is 0 视频的长度是 0 The file %1 doesn't exist 文件 %1 不存在 Images 图像 No info 无信息 %1 kbps %1kbps %1 Hz %1 Hz Video bitrate: %1 视频比特率: %1 Audio bitrate: %1 音频比特率: %1 Audio rate: %1 音频采样率: %1 VideoPreviewConfigDialog Default 默认 Thumbnail Generator 缩略图生成器 &File: 文件(&F): &Columns: 列(&C): &Rows: 行(&R): &Aspect ratio: 纵横比(&A): &Maximum width: 最大宽度(&M): The preview will be created for the video you specify here. 将为您在这里指定的视频创建预览。 The thumbnails will be arranged on a table. 缩略图将被排列在一个表格中。 This option specifies the number of columns of the table. 此选项可指定表格的列数。 This option specifies the number of rows of the table. 此选项可指定表格的行数。 If you check this option, the playing time will be displayed at the bottom of each thumbnail. 如果您勾选此选项,播放时间将显示在每个缩略图的底部。 If the aspect ratio of the video is wrong, you can specify a different one here. 如果视频的纵横比是错误的,您可以在这里指定一个不同的。 Usually the first frames are black, so it's a good idea to skip some seconds at the beginning of the video. This option allows you to specify how many seconds will be skipped. 通常情况下第一帧都是黑色的,因此视频开始时跳过几秒钟是个好主意。此选项允许指定多少秒将被跳过。 This option specifies the maximum width in pixels that the generated preview image will have. 此选项可指定生成预览图像的最大宽度(以像素为单位)。 Some frames will be extracted from the video in order to create the preview. Here you can choose the image format for the extracted frames. PNG may give better quality. 某些帧将被从视频中提取以创建预览。在这里您可以选择被提取帧的图像格式。PNG 的质量可能会更好。 Add playing &time to thumbnails 添加播放时间到缩略图(&T) &Seconds to skip at the beginning: 开始时跳过的秒数(&S): &Extract frames as 提取帧为(&E) Enter here the DVD device or a folder with a DVD image. 在这里输入 DVD 驱动器或 DVD 镜像文件夹。 &DVD device: DVD 驱动器(&D): Remember folder used to &save the preview 记住用来保存预览的文件夹(&S) VolumeControlPanel Playlist 播放列表 Fullscreen on/off 全屏开/关 Video equalizer 视频均衡器 VolumeSliderAction Volume 音量 kylin-video/src/translations/kylin-video_pt.ts0000644000175000017500000034207613625147453020573 0ustar fengfeng AboutDialog About Sobre Contributor Contribuinte <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> <! DOCTYPE HTML PUBLIC \ "- // W3C // DTD HTML 4.0 // PT " \ "http: //www.w3.org/TR/REC-html40/strict.dtd "> \ n <html> <head> <meta nome = \ "qrichtext " content = \ "1 " /> <estilo type = \ "text / css "> \ np, li {espaço em branco: pre-wrap; } \ n </ style> </ head> <estilo de corpo = \ "font-family: 'Ubuntu'; tamanho da fonte: 11pt; peso da fonte: 400; estilo da fonte: normal; "> \ n <p style = \ "- qt-paragraph-type: vazio; margin-top: 0px; margin-bottom: 0px; margem-esquerda: 0px; margem-direita: 0px; -qt-block-indent: 0; text-indent: 0px; \ "> <br /> </ p> </ body> </ html> OK Está bem Kylin Video is developed on the basis of SMPlayer, is a graphical interface for MPlayer and MPV. O Kylin Video é desenvolvido com base no SMPlayer, é uma interface gráfica para o MPlayer e o MPV. Kylin Video Vídeo Kylin Version: %1 Versão 1 Using Qt %1 (compiled with Qt %2) Usando Qt% 1 (compilado com Qt% 2) Playback engine: Mecanismo de reprodução: Kylin Video is developed on the basis of %1, is a graphical interface for %2 and %3. Links: Code website: Developer's personal home page: ActionsEditor Shortcut Atalho Description Descrição Name Nome Choose a filename Key files Confirm overwrite? The file %1 already exists. Do you want to overwrite? Error Erro The file couldn't be saved Choose a file Escolha um arquivo The file couldn't be loaded AudioDelayDialog Audio delay Atraso de áudio OK Está bem Cancel Cancelar Audio delay (in milliseconds): Atraso de áudio (em milissegundos): AudioEqualizer Audio Equalizer %1 Hz %1 kHz &Preset &Apply &Reset &Restabelecer &Set as default values &Close Flat Classical Club Dance Full bass Full bass and treble Full treble Headphones Large hall Live Party Pop Reggae Rock Ska Soft Soft rock Techno Custom Use the current values as default values for new videos. Set all controls to zero. Information Em formação The current values have been stored to be used as default. BaseGui Kylin Video Vídeo Kylin Open Abrir Open &File... Abrir arquivo... Directory... Diretório... &URL... & URL ... &Clear &Claro Recent files Arquivos recentes Play control Controle de reprodução Forward and rewind Avançar e retroceder &Jump to... &Pule para... Play Speed Velocidade de jogo Normal speed Velocidade normal Half speed Meia velocidade Double speed Velocidade dupla Speed -10% Velocidade -10% Speed +10% Velocidade + 10% Speed -4% Velocidade de -4% Speed +4% Velocidade + 4% Speed -1% Velocidade -1% Speed +1% Velocidade + 1% Next Próximo Previous Anterior &Auto &Auto &Disabled &Desativado Aspect ratio Proporção da tela &Off &Fora &Rotate by 90 degrees clockwise and flip & Rodar 90 graus no sentido dos ponteiros do relógio e virar Rotate by 90 degrees &clockwise Rodar 90 graus e no sentido horário Rotate by 90 degrees counterclock&wise Gire em 90 graus no sentido anti-horário e sábio Rotate by 90 degrees counterclockwise and &flip Gire 90 graus no sentido anti-horário e & flip Fli&p image Imagem Fli & p Mirr&or image Mirr e ou imagem Frame rotation Rotação do quadro &Rotate E girar &Screenshot Captura de tela &Always &Sempre &Never &Nunca While &playing Enquanto jogando S&tay on top Fique no topo Order play Peça de ordem Random play Jogada aleatória List loop play Listar jogo de loop Play order Ordem de jogo &Stereo &Estéreo &4.0 Surround & 4.0 Surround &5.1 Surround & 5.1 Surround &6.1 Surround & 6.1 Surround &7.1 Surround & 7.1 Surround &Channels E canais Audio Audio &Mute &Mudo Volume - Volume - Volume + Volume + Delay - Atraso - Delay + Atraso + Set dela&y... Definir dela ... &Left channel E canal esquerdo &Right channel Canal direito &Mono &Mono Re&verse Marcha ré &Stereo mode E modo estéreo Subtitles Legendas Load... Carga... Subtitle &visibility Legenda e visibilidade Preferences Preferências View &info and properties... Ver e informações e propriedades ... Help Socorro About &Kylin Video Sobre o & Kylin Video Quit Sair Open Homepage Homepage Aberta Open screenshots folder Abra a pasta screenshots PlayList Lista de reprodução Play/Pause A pausa Stop Pare Fullscreen Tela cheia Video filters are disabled when using vdpau Os filtros de vídeo são desativados ao usar o vdpau -%1 -% 1 +%1 +% 1 <empty> <vazio> Confirm deletion - Kylin Video Confirme a exclusão - Kylin Video Delete the list of recent files? Excluir a lista de arquivos recentes? Choose a file Escolha um arquivo Multimedia Multimídia Video Vídeo Playlists Listas de reprodução All files Todos os arquivos Choose a directory Escolha um diretório &Jump to: &Pule para: Kylin Video - Seek Vídeo de Kylin - busca Kylin Video - Subtitle delay Vídeo Kylin - Atraso de legendas Subtitle delay (in milliseconds): Atraso de legendas (em milissegundos): Error detected Erro detectado Unfortunately this video can't be played. Infelizmente este vídeo não pode ser reproduzido. The server returned '%1' O servidor retornou '% 1' Jump to %1 Ir para% 1 %1 Error % 1 erro '%1' was not found! '% 1' não foi encontrado! %1 has finished unexpectedly. % 1 terminou inesperadamente. Exit code: %1 Código de saída:% 1 %1 failed to start. % 1 falhou ao iniciar. Please check the %1 path in preferences. Por favor, verifique o caminho% 1 nas preferências. %1 has crashed. % 1 caiu. See the log for more info. Veja o log para mais informações. Information Em formação The screenshot folder does not exist! A pasta de screenshots não existe! BottomWidget Stop Pare Prev Anterior Play / Pause A pausa Next Próximo Mute Mudo Play List Lista de reprodução Core Screenshot NOT taken, folder not configured Captura de tela NÃO capturada, pasta não configurada Screenshots NOT taken, folder not configured Capturas de tela NÃO tiradas, pasta não configurada "A" marker set to %1 Marcador "A " definido para% 1 "B" marker set to %1 Marcador \ "B " definido para% 1 A-B markers cleared Marcadores AB apagados Brightness: %1 Brilho:% 1 Contrast: %1 Contraste:% 1 Gamma: %1 Gama:% 1 Hue: %1 Matiz:% 1 Saturation: %1 Saturação:% 1 Speed: %1 Velocidade:% 1 Volume: %1 Volume 1 Subtitle delay: %1 ms Atraso de legendas:% 1 ms Audio delay: %1 ms Atraso de áudio:% 1 ms Subtitles on Legendas em Subtitles off Legendas desativadas Aspect ratio: %1 Proporção:% 1 Mouse wheel seeks now Roda do mouse procura agora Mouse wheel changes volume now A roda do mouse altera o volume agora Mouse wheel changes zoom level now A roda do mouse altera o nível de zoom agora Mouse wheel changes speed now A roda do mouse muda de velocidade agora Zoom: %1 Zoom:% 1 Screenshot saved as %1 Captura de tela salva como% 1 Updating the font cache. This may take some seconds... Atualizando o cache da fonte. Isso pode demorar alguns segundos ... Buffering... Carregando... Starting... Iniciando... Font scale: %1 ErrorDialog MPlayer Error Erro do MPlayer OK Está bem icon ícone Oops, something wrong happened Oops, algo de errado aconteceu Error Erro Show log Mostrar log Hide log Ocultar log EscTip Press ESC to exit full screen mode Pressione ESC para sair do modo de tela cheia FileChooser Click to select a file or folder Clique para selecionar um arquivo ou pasta FilePropertiesDialog Kylin Video - Preferences Vídeo Kylin - Preferências Properties Propriedades &Select the demuxer that will be used for this file: & Selecione o demuxer que será usado para este arquivo: &Reset &Restabelecer &Select the video codec: & Selecione o codec de vídeo: &Select the audio codec: & Selecione o codec de áudio: Reset Restabelecer Apply Aplique OK Está bem Cancel Cancelar Information Em formação Demuxer Demuxer Video codec Codec de vídeo Audio codec Codec de áudio GlobalShortcutsDialog Media &Play Media &Stop Media Pre&vious Media &Next Media P&ause Media &Record Volume &Mute Volume &Down Volume &Up Global Shortcuts Select the multimedia keys that kylin-video will capture. HelpDialog Kylin Video - Help Vídeo Kylin - Ajuda Help Socorro OK Está bem Supported formats Formatos Suportados InputURL Enter URL Insira o URL OK Está bem Cancel Cancelar URL: URL: Languages Afar Longe Abkhazian Abecásio Avestan Avestan Afrikaans afrikaans Akan Akan Amharic Amárico Aragonese Aragonês Arabic árabe Assamese Assamês Avaric Avaric Aymara Aimará Azerbaijani Azerbaijanês Bashkir Bashkir Belarusian Bielorrusso Bulgarian búlgaro Bihari Bihari Bislama Bislama Bambara Bambara Bengali bengali Tibetan Tibetano Breton Bretão Bosnian Bósnio Catalan catalão Chechen Checheno Corsican Corso Cree Cree Czech Checo Church Igreja Chuvash Chuvache Welsh galês Danish dinamarquês German alemão Divehi Divehi Dzongkha Dzongkha Ewe Ovelha Greek grego English Inglês Esperanto esperanto Spanish espanhol Estonian estoniano Basque Basco Persian persa Fulah Fulah Finnish finlandês Fijian Fijiano Faroese Feroês French francês Frisian Frísio Irish irlandês Gaelic gaélico Galician Galego Guarani Guarani Gujarati Gujarati Manx Manx Hausa Hausa Hebrew hebraico Hindi hindi Hiri Hiri Croatian croata Haitian haitiano Hungarian húngaro Armenian Armênio Herero Herero Chamorro Chamorro Interlingua Interlíngua Indonesian indonésio Interlingue Interlingue Igbo Igbo Sichuan Sichuan Inupiaq Inupiaq Ido Eu faço Icelandic islandês Italian italiano Inuktitut Inuktitut Japanese japonês Javanese Javanês Georgian Georgiano Kongo Kongo Kikuyu Kikuyu Kuanyama Kuanyama Kazakh Cazaque Greenlandic Gronelandês Khmer Khmer Kannada Canará Korean coreano Kanuri Kanuri Kashmiri Caxemira Kurdish curdo Komi Komi Cornish Cornish Kirghiz Kirghiz Latin Latim Luxembourgish Luxemburguês Ganda Ganda Limburgan Limburgan Lingala Lingala Lao Lao Lithuanian lituano Luba-Katanga Luba-Katanga Latvian letão Malagasy malgaxe Marshallese Marshalês Maori maori Macedonian Macedônio Malayalam Malaiala Mongolian mongol Moldavian Moldavo Marathi Marathi Malay malaio Maltese maltês Burmese birmanês Nauru Nauru Bokmål Bokmål Ndebele Ndebele Nepali Nepalês Ndonga Ndonga Dutch holandês Norwegian Nynorsk Nynorsk norueguês Norwegian norueguês Navajo Navajo Chichewa Chique Occitan Occitano Ojibwa Ojibwa Oromo Oromo Oriya Oriya Ossetian Ossétia Panjabi Panjabi Pali Pali Polish polonês Pushto Empurre para Portuguese Português Quechua Quíchua Romansh Romanche Rundi Rundi Romanian romena Russian russo Kinyarwanda Kinyarwanda Sanskrit sânscrito Sardinian Sardo Sindhi Sindi Sami Sami Sango Sango Sinhala Cingalês Slovak Eslovaco Slovene Esloveno Samoan Samoano Shona Shona Somali Somali Albanian albanês Serbian sérvio Swati Swati Sotho Soto Sundanese Sundanês Swedish sueco Swahili Suaíli Tamil Tâmil Telugu Télugo Tajik Tadjique Thai tailandês Tigrinya Tigrina Turkmen Turcomano Tagalog Tagalo Tswana Tswana Tonga Tonga Turkish turco Tsonga Tsonga Tatar Tatar Twi Twi Tahitian Taitiano Uighur Uigur Ukrainian ucraniano Urdu urdu Uzbek Uzbeque Venda Venda Vietnamese vietnamita Volapük Volapuque Walloon valão Wolof Uólofe Xhosa Xhosa Yiddish Iídiche Yoruba Ioruba Zhuang Zhuang Chinese chinês Zulu zulu Arabic - Syria Árabe - Síria Unicode Unicode UTF-8 UTF-8 Western European Languages Idiomas da Europa Ocidental Western European Languages with Euro Línguas da Europa Ocidental com Euro Slavic/Central European Languages Idiomas eslavos / da Europa Central Esperanto, Galician, Maltese, Turkish Esperanto, galego, maltês, turco Old Baltic charset Charset antigo do Báltico Cyrillic cirílico Modern Greek Grego moderno Baltic báltico Celtic céltico South-Eastern European Europa do Sudeste Hebrew charsets Charsets hebreus Ukrainian, Belarusian Ucraniano, bielorrusso Simplified Chinese charset Charset chinês simplificado Traditional Chinese charset Charset chinês tradicional Japanese charsets Charutos japoneses Korean charset Charset coreano Thai charset Charset tailandês Cyrillic Windows Janelas Cirílicas Slavic/Central European Windows Janelas eslavas / européias centrais Arabic Windows Janelas árabes Modern Greek Windows Janelas gregas modernas LineEditWithIcon Change mudança MPVProcess the '%1' filter is not supported by mpv o filtro '% 1' não é suportado pelo mpv File: Video: Resolution: Frames per second: Estimated: Aspect Ratio: Bitrate: Dropped frames: Audio: Sample Rate: Channels: Audio/video synchronization: Cache fill: Used cache: MainWindow Kylin Video Vídeo Kylin Open Abrir Open &File... Abrir arquivo... Directory... Diretório... &URL... & URL ... &Clear &Claro Recent files Arquivos recentes Play control Controle de reprodução Forward and rewind Avançar e retroceder &Jump to... &Pule para... Play Speed Velocidade de jogo Normal speed Velocidade normal Half speed Meia velocidade Double speed Velocidade dupla Speed -10% Velocidade -10% Speed +10% Velocidade + 10% Speed -4% Velocidade de -4% Speed +4% Velocidade + 4% Speed -1% Velocidade -1% Speed +1% Velocidade + 1% Next Próximo Previous Anterior &Auto &Auto &Disabled &Desativado Aspect ratio Proporção da tela &Off &Fora &Rotate by 90 degrees clockwise and flip & Rodar 90 graus no sentido dos ponteiros do relógio e virar Rotate by 90 degrees &clockwise Rodar 90 graus e no sentido horário Rotate by 90 degrees counterclock&wise Gire em 90 graus no sentido anti-horário e sábio Rotate by 90 degrees counterclockwise and &flip Gire 90 graus no sentido anti-horário e & flip Fli&p image Imagem Fli & p Mirr&or image Mirr e ou imagem Frame rotation Rotação do quadro &Rotate E girar &Screenshot Captura de tela &Always &Sempre &Never &Nunca While &playing Enquanto jogando S&tay on top Fique no topo Order play Peça de ordem Random play Jogada aleatória List loop play Listar jogo de loop Play order Ordem de jogo &Stereo &Estéreo &4.0 Surround & 4.0 Surround &5.1 Surround & 5.1 Surround &6.1 Surround & 6.1 Surround &7.1 Surround & 7.1 Surround &Channels E canais Audio Audio &Mute &Mudo Volume - Volume - Volume + Volume + Delay - Atraso - Delay + Atraso + Set dela&y... Definir dela ... &Left channel E canal esquerdo &Right channel Canal direito &Mono &Mono Re&verse Marcha ré &Stereo mode E modo estéreo Subtitles Legendas Load... Carga... Subtitle &visibility Legenda e visibilidade Preferences Preferências View &info and properties... Ver e informações e propriedades ... Help Socorro About &Kylin Video Sobre o & Kylin Video Quit Sair Show &info on OSD Size &+ Size &- Show times with &milliseconds Subtitles onl&y Volume + &Seek Volume + Seek + &Timer Volume + Seek + Timer + T&otal time &OSD PlayList Lista de reprodução Play/Pause A pausa Stop Pare Fullscreen Tela cheia Open Homepage Homepage Aberta Open screenshots folder Abra a pasta screenshots Failed to add files! Video filters are disabled when using vdpau Os filtros de vídeo são desativados ao usar o vdpau -%1 -% 1 +%1 +% 1 <empty> <vazio> Confirm deletion - Kylin Video Confirme a exclusão - Kylin Video Delete the list of recent files? Excluir a lista de arquivos recentes? Choose a file Escolha um arquivo Multimedia Multimídia Video Vídeo Playlists Listas de reprodução All files Todos os arquivos Choose a directory Escolha um diretório &Jump to: &Pule para: Kylin Video - Seek Vídeo de Kylin - busca Kylin Video - Subtitle delay Vídeo Kylin - Atraso de legendas Subtitle delay (in milliseconds): Atraso de legendas (em milissegundos): Error detected Erro detectado Unfortunately this video can't be played. Infelizmente este vídeo não pode ser reproduzido. The server returned '%1' O servidor retornou '% 1' Jump to %1 Ir para% 1 %1 Error % 1 erro '%1' was not found! '% 1' não foi encontrado! %1 has finished unexpectedly. % 1 terminou inesperadamente. Exit code: %1 Código de saída:% 1 %1 failed to start. % 1 falhou ao iniciar. Please check the %1 path in preferences. Por favor, verifique o caminho% 1 nas preferências. %1 has crashed. % 1 caiu. See the log for more info. Veja o log para mais informações. Information Em formação The screenshot folder does not exist! A pasta de screenshots não existe! Warning - Using old MPlayer Please, update your MPlayer. (This warning won't be displayed anymore) The version of MPlayer (%1) installed on your system is obsolete. kylin-video can't work well with it: some options won't work, subtitle selection may fail... A:%1 B:%1 &Extrastereo &Karaoke Volume &normalization &Headphone optimization &Filters &Load external file... U&nload E&qualizer Reset audio equalizer MaskWidget Loading... MessageDialog Ok Está bem Cancel Cancelar Yes sim No Não MplayerProcess This option is not supported by MPlayer Esta opção não é suportada pelo MPlayer PlayListView Play Toque Remove &selected Remover e selecionado &Delete file from disk & Excluir arquivo do disco Playlist Playlist is empty A lista de reprodução está vazia Add File Adicionar ficheiro PlayList Lista de reprodução Clear Claro Add Adicionar Play Toque Remove &selected Remover e selecionado &Delete file from disk & Excluir arquivo do disco Reached the end of the playlist Atingiu o final da playlist Select one or more files to open Selecione um ou mais arquivos para abrir Multimedia Multimídia All files Todos os arquivos Choose a directory Escolha um diretório Confirm remove Confirme remover You're about to remove the file '%1' from the playlist. Você está prestes a remover o arquivo '% 1' da playlist. Are you sure you want to proceed? Tem certeza de que deseja continuar? Confirm deletion Confirme a exclusão You're about to DELETE the file '%1' from your drive. Você está prestes a DELETAR o arquivo '% 1' da sua unidade. This action cannot be undone. Are you sure you want to proceed? Essa ação não pode ser desfeita. Tem certeza de que deseja continuar? Deletion failed A exclusão falhou It wasn't possible to delete '%1' Não foi possível excluir '% 1' Error deleting the file Erro ao excluir o arquivo It's not possible to delete '%1' from the filesystem. Não é possível excluir '% 1' do sistema de arquivos. Choose a filename Playlists Listas de reprodução Confirm overwrite? The file %1 already exists. Do you want to overwrite? You're about to remove the file from the playlist. You're about to Delete the files from your drive. Confirm remove all You're about to empty the playlist. Reached the top of the playlist PoweroffDialog The computer will shut down in %1 seconds. Press <b>Cancel</b> to abort shutdown. Ok Está bem Cancel Cancelar PrefAudio Volume Volume Global volume Volume global Use software volume control Use o controle de volume de software Max. Amplification: Max. Amplificação: Volume normalization by default Normalização de volume por padrão Synchronization Sincronização Audio/video auto synchronization Sincronização automática de áudio / vídeo Factor: Fator: Output driver: Driver de saída: Channels by default: Canais por padrão: 2 (Stereo) 2 (estéreo) 4 (4.0 Surround) 4 (4,0 Surround) 6 (5.1 Surround) 6 (5.1 Surround) 7 (6.1 Surround) 7 (6.1 Surround) 8 (7.1 Surround) 8 (7.1 Surround) Default Padrão Audio output driver Driver de saída de áudio Select the audio output driver. Selecione o driver de saída de áudio. %1 is the recommended one. Try to avoid %2 and %3, they are slow and can have an impact on performance. % 1 é o recomendado. Tente evitar% 2 e% 3, eles são lentos e podem ter um impacto no desempenho. Channels by default Canais por padrão Requests the number of playback channels. MPlayer asks the decoder to decode the audio into as many channels as specified. Then it is up to the decoder to fulfill the requirement. This is usually only important when playing videos with AC3 audio (like DVDs). In that case liba52 does the decoding by default and correctly downmixes the audio into the requested number of channels. <b>Note</b>: This option is honored by codecs (AC3 only), filters (surround) and audio output drivers (OSS at least). Solicita o número de canais de reprodução. O MPlayer pede ao decodificador para decodificar o áudio em quantos canais forem especificados. Então cabe ao decodificador cumprir o requisito. Isso geralmente é importante apenas ao reproduzir vídeos com áudio AC3 (como DVDs). Nesse caso, a liba52 faz a decodificação por padrão e ajusta corretamente o áudio para o número solicitado de canais. <b> Nota </ ​​b>: Esta opção é respeitada por codecs (somente AC3), filtros (surround) e drivers de saída de áudio (OSS pelo menos). If this option is checked, the same volume will be used for all files you play. If the option is not checked each file uses its own volume. Se esta opção estiver marcada, o mesmo volume será usado para todos os arquivos que você reproduzir. Se a opção não estiver marcada, cada arquivo usa seu próprio volume. This option also applies for the mute control. Esta opção também se aplica ao controle de mudo. Software volume control Controle de volume de software Check this option to use the software mixer, instead of using the sound card mixer. Marque esta opção para usar o mixer de software, em vez de usar o mixer da placa de som. Max. Amplification Max. Amplificação Sets the maximum amplification level in percent (default: 110). A value of 200 will allow you to adjust the volume up to a maximum of double the current level. With values below 100 the initial volume (which is 100%) will be above the maximum, which e.g. the OSD cannot display correctly. Define o nível máximo de amplificação em porcentagem (padrão: 110). Um valor de 200 permitirá ajustar o volume até o dobro do nível atual. Com valores abaixo de 100, o volume inicial (que é 100%) estará acima do máximo, o que, por exemplo, o OSD não pode exibir corretamente. Maximizes the volume without distorting the sound. Maximiza o volume sem distorcer o som. Gradually adjusts the A/V sync based on audio delay measurements. Gradualmente, ajusta a sincronização A / V com base nas medições de atraso de áudio. PrefGeneral Pause when minimized Pausa quando minimizado MPlayer MPlayer MPV MPV Playback engine: Mecanismo de reprodução: Preview when video is playing Visualizar quando o vídeo está sendo reproduzido If this option is enabled, the file will be paused when the main window is hidden. When the window is restored, playback will be resumed. Se esta opção estiver ativada, o arquivo será pausado quando a janela principal estiver oculta. Quando a janela é restaurada, a reprodução será retomada. Preview when the video is playing Visualizar quando o vídeo está sendo reproduzido If this option is enabled, the video preview will be displayed when the mouse is placed on the progress bar. Se esta opção estiver ativada, a visualização do vídeo será exibida quando o mouse for colocado na barra de progresso. Select MPlayer as playback engine Selecione o MPlayer como mecanismo de reprodução If you change the playback engine to MPlayer, please restart Kylin Video. Se você alterar o mecanismo de reprodução para o MPlayer, reinicie o Kylin Video. Select MPV as playback engine Selecione MPV como mecanismo de reprodução If you change the playback engine to MPV, please restart Kylin Video. Se você alterar o mecanismo de reprodução para MPV, reinicie o Kylin Video. PrefPerformance Cache Cache Cache for local files: Cache para arquivos locais: KB KB Cache for streams: Cache para fluxos: Decode Decodificar Threads for decoding (MPEG-1/2 and H.264 only): Threads para decodificação (somente MPEG-1/2 e H.264): Hardware decoding Decodificação de hardware None Nenhum Auto Auto Performance atuação Threads for decoding Tópicos para decodificação Sets the number of threads to use for decoding. Only for MPEG-1/2 and H.264 Define o número de segmentos a serem usados ​​para decodificação. Apenas para MPEG-1/2 e H.264 Sets the hardware video decoding API. If hardware decoding is not possible, software decoding will be used instead. Define a API de decodificação de vídeo de hardware. Se a decodificação de hardware não for possível, a decodificação de software será usada. Available options: Opções disponíveis: None: only software decoding will be used. Nenhum: somente a decodificação de software será usada. Auto: it tries to automatically enable hardware decoding using the first available method. Automático: ele tenta ativar automaticamente a decodificação de hardware usando o primeiro método disponível. vdpau: for the vdpau and opengl video outputs. vdpau: para as saídas de vídeo vdpau e opengl. vaapi: for the opengl and vaapi video outputs. For Intel GPUs only. vaapi: para as saídas de vídeo opengl e vaapi. Apenas para GPUs Intel. vaapi-copy: it copies video back into system RAM. For Intel GPUs only. vaapi-copy: copia o vídeo de volta para a RAM do sistema. Apenas para GPUs Intel. This option only works with mpv. Esta opção só funciona com o mpv. Cache for files Cache para arquivos This option specifies how much memory (in kBytes) to use when precaching a file. Esta opção especifica a quantidade de memória (em kBytes) a ser usada ao precazer um arquivo. Cache for streams Cache para fluxos This option specifies how much memory (in kBytes) to use when precaching a URL. Esta opção especifica a quantidade de memória (em kBytes) a ser usada ao preceder um URL. PrefScreenShot Screenshots Screenshots Enable screenshots Ativar capturas de tela Folder: Pasta: Template: Modelo: Format: Formato: Select a directory Selecione um diretório You can use this option to enable or disable the possibility to take screenshots. Você pode usar essa opção para ativar ou desativar a possibilidade de fazer capturas de tela. Screenshots folder Pasta de imagens Here you can specify a folder where the screenshots taken by Kylin Video will be stored. If the folder is not valid the screenshot feature will be disabled. Aqui você pode especificar uma pasta onde as imagens capturadas pelo Kylin Video serão armazenadas. Se a pasta não for válida, o recurso de captura de tela será desativado. Template for screenshots Modelo para capturas de tela This option specifies the filename template used to save screenshots. Esta opção especifica o modelo de nome de arquivo usado para salvar capturas de tela. For example %1 would save the screenshot as 'moviename_0001.png'. Por exemplo,% 1 salvaria a captura de tela como 'moviename_0001.png'. %1 specifies the filename of the video without the extension, %2 adds a 4 digit number padded with zeros. % 1 especifica o nome do arquivo do vídeo sem a extensão,% 2 adiciona um número de 4 dígitos preenchido com zeros. For a full list of the template specifiers visit this link: Para obter uma lista completa dos especificadores de modelo, acesse este link: This option only works with mpv. Esta opção só funciona com o mpv. Format for screenshots Formato para capturas de tela This option allows one to choose the image file type used for saving screenshots. Esta opção permite escolher o tipo de arquivo de imagem usado para salvar capturas de tela. PrefShortCut Here you can change any key shortcut. To do it double click or press enter over a shortcut cell. Aqui você pode alterar qualquer atalho chave. Para fazer isso, clique duas vezes ou pressione enter sobre uma célula de atalho. ShortCut Atalho Here you can change any key shortcut. To do it double click or start typing over a shortcut cell. Aqui você pode alterar qualquer atalho chave. Para fazer isso, clique duas vezes ou comece a digitar em uma célula de atalho. Shortcut Key Tecla de atalho Shortcut editor Editor de atalhos This table allows you to change the key shortcuts of most available actions. Double click or press enter on a item, or press the <b>Change shortcut</b> button to enter in the <i>Modify shortcut</i> dialog. There are two ways to change a shortcut: if the <b>Capture</b> button is on then just press the new key or combination of keys that you want to assign for the action (unfortunately this doesn't work for all keys). If the <b>Capture</b> button is off then you could enter the full name of the key. Esta tabela permite que você altere os atalhos de teclas da maioria das ações disponíveis. Clique duas vezes ou pressione enter em um item, ou pressione o botão <b> Alterar atalho </ b> para entrar no diálogo <i> Modificar atalho </ i>. Há duas maneiras de alterar um atalho: se o botão <b> Capturar </ b> estiver ativado, pressione a nova tecla ou a combinação de teclas que deseja atribuir à ação (infelizmente isso não funciona para todas as teclas ). Se o botão <b> Capturar </ b> estiver desativado, você poderá digitar o nome completo da chave. PrefSubtitles Autoload Carregamento Automático Autoload subtitles files (*.srt, *.sub...): Carregar automaticamente arquivos de legendas (* .srt, * .sub ...): Same name as movie Mesmo nome do filme All subs containing movie name Todos os subs contendo nome do filme All subs in directory Todos os subs no diretório Encoding Codificação Default subtitle encoding: Codificação de legendas padrão: Try to autodetect for this language: Tente se autodetectar para este idioma: Subtitles Legendas Select the subtitle autoload method. Selecione o método de carregamento automático de legendas. Default subtitle encoding Codificação de legendas padrão Select the encoding which will be used for subtitle files by default. Selecione a codificação que será usada para arquivos de legenda por padrão. Try to autodetect for this language Tente autodetectar para este idioma When this option is on, the encoding of the subtitles will be tried to be autodetected for the given language. It will fall back to the default encoding if the autodetection fails. This option requires a MPlayer compiled with ENCA support. Quando esta opção estiver ativada, a codificação das legendas será tentada para ser detectada automaticamente para o idioma especificado. Ele retornará à codificação padrão se a detecção automática falhar. Esta opção requer um MPlayer compilado com suporte ENCA. Subtitle language Idioma da legenda Select the language for which you want the encoding to be guessed automatically. Selecione o idioma para o qual você deseja que a codificação seja adivinhada automaticamente. Font Fonte PrefVideo Enable postprocessing by default Ativar o pós-processamento por padrão Draw video using slices Desenhe vídeos usando fatias Direct rendering Renderização direta Double buffering Double buffering Use software video equalizer Use o equalizador de vídeo por software Output driver: Driver de saída: Default Padrão slow lento Video output driver Driver de saída de vídeo Select the video output driver. %1 provides the best performance. Selecione o driver de saída de vídeo. % 1 fornece o melhor desempenho. Postprocessing will be used by default on new opened files. O pós-processamento será usado por padrão em novos arquivos abertos. Software video equalizer Equalizador de vídeo de software You can check this option if video equalizer is not supported by your graphic card or the selected video output driver.<br><b>Note:</b> this option can be incompatible with some video output drivers. Você pode marcar esta opção se o equalizador de vídeo não for suportado pela placa gráfica ou pelo driver de saída de vídeo selecionado. <br> <b> Observação: </ b> essa opção pode ser incompatível com alguns drivers de saída de vídeo. If checked, turns on direct rendering (not supported by all codecs and video outputs)<br><b>Warning:</b> May cause OSD/SUB corruption! Se marcado, ativa a renderização direta (não suportada por todos os codecs e saídas de vídeo) <br> <b> Aviso: </ b> Pode causar corrupção de OSD / SUB! Double buffering fixes flicker by storing two frames in memory, and displaying one while decoding another. If disabled it can affect OSD negatively, but often removes OSD flickering. Correções de buffer duplo piscam armazenando dois quadros na memória e exibindo um enquanto decodifica outro. Se desativado, pode afetar o OSD negativamente, mas muitas vezes remove a oscilação do OSD. Enable/disable drawing video by 16-pixel height slices/bands. If disabled, the whole frame is drawn in a single run. May be faster or slower, depending on video card and available cache. It has effect only with libmpeg2 and libavcodec codecs. Ativar / desativar o desenho de vídeo por fatias / bandas de altura de 16 pixels. Se desativado, o quadro inteiro é desenhado em uma única execução. Pode ser mais rápido ou mais lento, dependendo da placa de vídeo e do cache disponível. Ele tem efeito somente com os codecs libmpeg2 e libavcodec. PreferencesDialog Kylin Video - Preferences Vídeo Kylin - Preferências Preference Preferência Cancel Cancelar Apply Aplique OK Está bem General Geral Video Vídeo Audio Audio Performance atuação Subtitles Legendas ScreenShot ScreenShot Shortcut Key Tecla de atalho QObject %n second(s) %n minute(s) %1 and %2 % 1 e% 2 This is Kylin Vedio v. %1 running on %2 Este é o Kylin Vedio v.% 1 executado em% 2 disabled aspect_ratio Desativado auto aspect_ratio auto unknown aspect_ratio desconhecido ShortcutGetter Modify shortcut Modificar atalho Add shortcut Adicionar atalho Remove shortcut Remover atalho Press the key combination you want to assign Pressione a combinação de teclas que você deseja atribuir Clear Claro OK Está bem Cancel Cancelar Capture Capturar Capture keystrokes Capture as teclas digitadas SupportFormats Video formats Formatos de vídeo Audio formats Formatos de áudio Subtitles formats Formatos de legendas Some video formats do not support preview and seek by dragging, e.g. the swf. Alguns formatos de vídeo não suportam a visualização e buscam arrastando, por exemplo, o swf. TimeDialog Seek Procurar OK Está bem Cancel Cancelar Jump to: Pule para: TitleWidget Kylin Video Vídeo Kylin TristateCombo Auto Auto Yes sim No Não VideoPreview The length of the video is 0 O comprimento do vídeo é 0 The temporary directory (%1) can't be created O diretório temporário (% 1) não pode ser criado The file %1 doesn't exist O arquivo% 1 não existe The mplayer process didn't run O processo do mplayer não foi executado No filename Nenhum nome de arquivo The mplayer process didn't start while trying to get info about the video O processo do mplayer não começou ao tentar obter informações sobre o vídeo The mpv process didn't run kylin-video/src/translations/kylin-video_bo.ts0000644000175000017500000043457413605242413020543 0ustar fengfeng AboutDialog About Contributor <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> OK Kylin Video is developed on the basis of %1, is a graphical interface for %2 and %3. Kylin Video Version: %1 Using Qt %1 (compiled with Qt %2) Playback engine: Links: Code website: Developer's personal home page: ActionsEditor Shortcut Description Name Choose a filename Key files Confirm overwrite? The file %1 already exists. Do you want to overwrite? Error The file couldn't be saved Choose a file The file couldn't be loaded AudioDelayDialog Audio delay OK Cancel Audio delay (in milliseconds): AudioEqualizer Audio Equalizer %1 Hz %1 kHz &Preset &Apply &Reset &Set as default values &Close Flat Classical Club Dance Full bass Full bass and treble Full treble Headphones Large hall Live Party Pop Reggae Rock Ska Soft Soft rock Techno Custom Use the current values as default values for new videos. Set all controls to zero. Information The current values have been stored to be used as default. BottomWidget Stop Prev Play / Pause Next Mute Play List Core Screenshot NOT taken, folder not configured Screenshots NOT taken, folder not configured "A" marker set to %1 "B" marker set to %1 A-B markers cleared Brightness: %1 Contrast: %1 Gamma: %1 Hue: %1 Saturation: %1 Speed: %1 Volume: %1 Subtitle delay: %1 ms Audio delay: %1 ms Font scale: %1 Subtitles on Subtitles off Aspect ratio: %1 Mouse wheel seeks now Mouse wheel changes volume now Mouse wheel changes zoom level now Mouse wheel changes speed now Zoom: %1 Screenshot saved as %1 Updating the font cache. This may take some seconds... Buffering... Starting... ErrorDialog MPlayer Error OK icon Oops, something wrong happened Error Show log Hide log EscTip Press ESC to exit full screen mode FileChooser Click to select a file or folder FilePropertiesDialog Kylin Video - Preferences Properties &Select the demuxer that will be used for this file: &Reset &Select the video codec: &Select the audio codec: Reset Apply OK Cancel Information Demuxer Video codec Audio codec GlobalShortcutsDialog Select the multimedia keys that kylin-video will capture. Media &Play Media &Stop Media Pre&vious Media &Next Media P&ause Media &Record Volume &Mute Volume &Down Volume &Up Global Shortcuts HelpDialog Kylin Video - Help Help OK Supported formats InputURL Enter URL OK Cancel URL: Languages Afar Abkhazian Avestan Afrikaans Akan Amharic Aragonese Arabic Assamese Avaric Aymara Azerbaijani Bashkir Belarusian Bulgarian Bihari Bislama Bambara Bengali Tibetan Breton Bosnian Catalan Chechen Corsican Cree Czech Church Chuvash Welsh Danish German Divehi Dzongkha Ewe Greek English Esperanto Spanish Estonian Basque Persian Fulah Finnish Fijian Faroese French Frisian Irish Gaelic Galician Guarani Gujarati Manx Hausa Hebrew Hindi Hiri Croatian Haitian Hungarian Armenian Herero Chamorro Interlingua Indonesian Interlingue Igbo Sichuan Inupiaq Ido Icelandic Italian Inuktitut Japanese Javanese Georgian Kongo Kikuyu Kuanyama Kazakh Greenlandic Khmer Kannada Korean Kanuri Kashmiri Kurdish Komi Cornish Kirghiz Latin Luxembourgish Ganda Limburgan Lingala Lao Lithuanian Luba-Katanga Latvian Malagasy Marshallese Maori Macedonian Malayalam Mongolian Moldavian Marathi Malay Maltese Burmese Nauru Bokmål Ndebele Nepali Ndonga Dutch Norwegian Nynorsk Norwegian Navajo Chichewa Occitan Ojibwa Oromo Oriya Ossetian Panjabi Pali Polish Pushto Portuguese Quechua Romansh Rundi Romanian Russian Kinyarwanda Sanskrit Sardinian Sindhi Sami Sango Sinhala Slovak Slovene Samoan Shona Somali Albanian Serbian Swati Sotho Sundanese Swedish Swahili Tamil Telugu Tajik Thai Tigrinya Turkmen Tagalog Tswana Tonga Turkish Tsonga Tatar Twi Tahitian Uighur Ukrainian Urdu Uzbek Venda Vietnamese Volapük Walloon Wolof Xhosa Yiddish Yoruba Zhuang Chinese Zulu Arabic - Syria Unicode UTF-8 Western European Languages Western European Languages with Euro Slavic/Central European Languages Esperanto, Galician, Maltese, Turkish Old Baltic charset Cyrillic Modern Greek Baltic Celtic South-Eastern European Hebrew charsets Ukrainian, Belarusian Simplified Chinese charset Traditional Chinese charset Japanese charsets Korean charset Thai charset Cyrillic Windows Slavic/Central European Windows Arabic Windows Modern Greek Windows LineEditWithIcon Change MPVProcess the '%1' filter is not supported by mpv File: Video: Resolution: Frames per second: Estimated: Aspect Ratio: Bitrate: Dropped frames: Audio: Sample Rate: Channels: Audio/video synchronization: Cache fill: Used cache: MainWindow Kylin Video A:%1 B:%1 Warning - Using old MPlayer The version of MPlayer (%1) installed on your system is obsolete. kylin-video can't work well with it: some options won't work, subtitle selection may fail... Please, update your MPlayer. (This warning won't be displayed anymore) Open Open &File... Directory... &URL... &Clear Recent files &Always &Never While &playing S&tay on top Play control Forward and rewind &Jump to... Play Speed Normal speed Half speed Double speed Speed -10% Speed +10% Speed -4% Speed +4% Speed -1% Speed +1% Next Previous Order play Random play List loop play Play order &Auto &Disabled Aspect ratio &Off &Rotate by 90 degrees clockwise and flip Rotate by 90 degrees &clockwise Rotate by 90 degrees counterclock&wise Rotate by 90 degrees counterclockwise and &flip Fli&p image Mirr&or image Frame rotation &Rotate &Stereo &4.0 Surround &5.1 Surround &6.1 Surround &7.1 Surround &Channels Audio &Mute &Extrastereo &Karaoke Volume &normalization &Headphone optimization &Filters Volume - Volume + Delay - Delay + Set dela&y... Choose a file All files &Load external file... U&nload E&qualizer Reset audio equalizer &Left channel &Right channel &Mono Re&verse &Stereo mode &Screenshot Subtitles Load... Subtitle &visibility Show &info on OSD Size &+ Size &- Show times with &milliseconds Subtitles onl&y Volume + &Seek Volume + Seek + &Timer Volume + Seek + Timer + T&otal time &OSD Preferences View &info and properties... Help About &Kylin Video Quit PlayList Play/Pause Stop Fullscreen Open Homepage Open screenshots folder Information The screenshot folder does not exist! Failed to add files! Video filters are disabled when using vdpau -%1 +%1 <empty> Confirm deletion - Kylin Video Delete the list of recent files? Multimedia Video Playlists Choose a directory &Jump to: Kylin Video - Seek Kylin Video - Subtitle delay Subtitle delay (in milliseconds): Error detected Unfortunately this video can't be played. The server returned '%1' Jump to %1 %1 Error '%1' was not found! %1 has finished unexpectedly. Exit code: %1 %1 failed to start. Please check the %1 path in preferences. %1 has crashed. See the log for more info. MaskWidget Loading... MessageDialog Ok Cancel Yes No MplayerProcess This option is not supported by MPlayer PlayListView Play Remove &selected &Delete file from disk Playlist Playlist is empty Add File PlayList Clear Add Choose a filename Playlists All files Confirm overwrite? The file %1 already exists. Do you want to overwrite? Reached the end of the playlist Select one or more files to open Multimedia Choose a directory Confirm remove You're about to remove the file from the playlist. Are you sure you want to proceed? Confirm deletion You're about to Delete the files from your drive. This action cannot be undone. Are you sure you want to proceed? Confirm remove all You're about to empty the playlist. PoweroffDialog The computer will shut down in %1 seconds. Press <b>Cancel</b> to abort shutdown. Ok Cancel PrefAudio Volume Global volume Use software volume control Max. Amplification: Volume normalization by default Synchronization Audio/video auto synchronization Factor: Output driver: Channels by default: Default 2 (Stereo) 4 (4.0 Surround) 6 (5.1 Surround) 7 (6.1 Surround) 8 (7.1 Surround) Audio output driver Select the audio output driver. %1 is the recommended one. Try to avoid %2 and %3, they are slow and can have an impact on performance. Channels by default Requests the number of playback channels. MPlayer asks the decoder to decode the audio into as many channels as specified. Then it is up to the decoder to fulfill the requirement. This is usually only important when playing videos with AC3 audio (like DVDs). In that case liba52 does the decoding by default and correctly downmixes the audio into the requested number of channels. <b>Note</b>: This option is honored by codecs (AC3 only), filters (surround) and audio output drivers (OSS at least). If this option is checked, the same volume will be used for all files you play. If the option is not checked each file uses its own volume. This option also applies for the mute control. Software volume control Check this option to use the software mixer, instead of using the sound card mixer. Max. Amplification Sets the maximum amplification level in percent (default: 110). A value of 200 will allow you to adjust the volume up to a maximum of double the current level. With values below 100 the initial volume (which is 100%) will be above the maximum, which e.g. the OSD cannot display correctly. Maximizes the volume without distorting the sound. Gradually adjusts the A/V sync based on audio delay measurements. PrefGeneral Pause when minimized MPlayer MPV Playback engine: Preview when video is playing If this option is enabled, the file will be paused when the main window is hidden. When the window is restored, playback will be resumed. Preview when the video is playing If this option is enabled, the video preview will be displayed when the mouse is placed on the progress bar. Select MPlayer as playback engine If you change the playback engine to MPlayer, please restart Kylin Video. Select MPV as playback engine If you change the playback engine to MPV, please restart Kylin Video. PrefPerformance Cache Cache for local files: KB Cache for streams: Decode Threads for decoding (MPEG-1/2 and H.264 only): Hardware decoding None Auto Performance Threads for decoding Sets the number of threads to use for decoding. Only for MPEG-1/2 and H.264 Sets the hardware video decoding API. If hardware decoding is not possible, software decoding will be used instead. Available options: None: only software decoding will be used. Auto: it tries to automatically enable hardware decoding using the first available method. vdpau: for the vdpau and opengl video outputs. vaapi: for the opengl and vaapi video outputs. For Intel GPUs only. vaapi-copy: it copies video back into system RAM. For Intel GPUs only. This option only works with mpv. Cache for files This option specifies how much memory (in kBytes) to use when precaching a file. Cache for streams This option specifies how much memory (in kBytes) to use when precaching a URL. PrefScreenShot Screenshots Enable screenshots Folder: Template: Format: Select a directory You can use this option to enable or disable the possibility to take screenshots. Screenshots folder Here you can specify a folder where the screenshots taken by Kylin Video will be stored. If the folder is not valid the screenshot feature will be disabled. Template for screenshots This option specifies the filename template used to save screenshots. For example %1 would save the screenshot as 'moviename_0001.png'. %1 specifies the filename of the video without the extension, %2 adds a 4 digit number padded with zeros. For a full list of the template specifiers visit this link: This option only works with mpv. Format for screenshots This option allows one to choose the image file type used for saving screenshots. PrefShortCut Here you can change any key shortcut. To do it double click or press enter over a shortcut cell. ShortCut Here you can change any key shortcut. To do it double click or start typing over a shortcut cell. Shortcut Key Shortcut editor This table allows you to change the key shortcuts of most available actions. Double click or press enter on a item, or press the <b>Change shortcut</b> button to enter in the <i>Modify shortcut</i> dialog. There are two ways to change a shortcut: if the <b>Capture</b> button is on then just press the new key or combination of keys that you want to assign for the action (unfortunately this doesn't work for all keys). If the <b>Capture</b> button is off then you could enter the full name of the key. PrefSubtitles Autoload Autoload subtitles files (*.srt, *.sub...): Same name as movie All subs containing movie name All subs in directory Encoding Default subtitle encoding: Try to autodetect for this language: Subtitles Select the subtitle autoload method. Default subtitle encoding Select the encoding which will be used for subtitle files by default. Try to autodetect for this language When this option is on, the encoding of the subtitles will be tried to be autodetected for the given language. It will fall back to the default encoding if the autodetection fails. This option requires a MPlayer compiled with ENCA support. Subtitle language Select the language for which you want the encoding to be guessed automatically. Font PrefVideo Enable postprocessing by default Draw video using slices Direct rendering Double buffering Use software video equalizer Output driver: Default slow Video output driver Select the video output driver. %1 provides the best performance. Postprocessing will be used by default on new opened files. Software video equalizer You can check this option if video equalizer is not supported by your graphic card or the selected video output driver.<br><b>Note:</b> this option can be incompatible with some video output drivers. If checked, turns on direct rendering (not supported by all codecs and video outputs)<br><b>Warning:</b> May cause OSD/SUB corruption! Double buffering fixes flicker by storing two frames in memory, and displaying one while decoding another. If disabled it can affect OSD negatively, but often removes OSD flickering. Enable/disable drawing video by 16-pixel height slices/bands. If disabled, the whole frame is drawn in a single run. May be faster or slower, depending on video card and available cache. It has effect only with libmpeg2 and libavcodec codecs. PreferencesDialog Kylin Video - Preferences Preference Cancel Apply OK General Video Audio Performance Subtitles ScreenShot Shortcut Key QObject This is Kylin Vedio v. %1 running on %2 disabled aspect_ratio auto aspect_ratio unknown aspect_ratio %n second(s) %n minute(s) %1 and %2 ShortcutGetter Modify shortcut Add shortcut Remove shortcut Press the key combination you want to assign Clear OK Cancel Capture Capture keystrokes SupportFormats Video formats Audio formats Subtitles formats Some video formats do not support preview and seek by dragging, e.g. the swf. TimeDialog Seek OK Cancel Jump to: TitleWidget Kylin Video TristateCombo Auto Yes No VideoPreview The length of the video is 0 The temporary directory (%1) can't be created The file %1 doesn't exist The mplayer process didn't run No filename The mplayer process didn't start while trying to get info about the video kylin-video/src/translations/kylin-video_ru.po0000644000175000017500000017157713517016402020561 0ustar fengfeng#, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-10-15 15:13+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Translate Toolkit 1.13.0\n" #: AboutDialog#1 msgid "About" msgstr "Около" #: AboutDialog#2 msgid "Contributor" msgstr "участник" #: AboutDialog#3 msgid "" "\n" "\n" "

<" "br />

" msgstr " \ n "+ s + ""; return page; } #ifdef INFO_SIMPLE_LAYOUT QString InfoFile::title(QString text, QString /* icon */) { return QString("

%1

").arg(text); } QString InfoFile::openPar(QString text) { return "

" + text + "

    "; } QString InfoFile::closePar() { return "
"; } QString InfoFile::openItem() { return "
  • "; } QString InfoFile::closeItem() { return "
  • "; } QString InfoFile::addItem( QString tag, QString value ) { return openItem() + QString("%1: %2").arg(tag).arg(value) + closeItem(); } QString InfoFile::addTrackColumns(QStringList /* l */) { return ""; } QString InfoFile::addTrack(int n, QString lang, QString name, int ID, QString type) { QString s = "" + kylin_tr("Track %1").arg(n) + ""; #if 1 s += "
      "; if (!lang.isEmpty()) s += "
    • " + kylin_tr("Language: %1").arg(lang) + "
    • "; if (!name.isEmpty()) s += "
    • " + kylin_tr("Name: %1").arg(name) + "
    • "; // s += "
    • " + kylin_tr("Language: %1").arg(lang) + "
    • "; // s += "
    • " + kylin_tr("Name: %1").arg(name) + "
    • "; s += "
    • " + kylin_tr("ID: %1").arg(ID) + "
    • "; if (!type.isEmpty()) { s += "
    • " + kylin_tr("Type: %1").arg(type) + "
    • "; } s += "
    "; #else s += "
     • " + kylin_tr("Language: %1").arg(lang); s += "
     • " + kylin_tr("Name: %1").arg(name); s += "
     • " + kylin_tr("ID: %1").arg(ID); if (!type.isEmpty()) { s += "
     • " + kylin_tr("Type: %1").arg(type); } #endif return s; } QString InfoFile::defaultStyle() { return "ul { margin: 0px; }" //"body { background-color: gray; }" "h2 { background-color: whitesmoke; color: navy;}" ; } #else QString InfoFile::title(QString text, QString icon) { return QString("

    %2

    ").arg(Images::file(icon)).arg(text); } QString InfoFile::openPar(QString text) { // return "

    " + text + "

    " // ""; //kobe 20170627 return "

    " + text + "

    " "
    "; } QString InfoFile::closePar() { row = 0; return "
    "; } QString InfoFile::openItem() { return "";//height="100" bgColor="red"; // if (row % 2 == 1) // return ""; // else // return ""; } QString InfoFile::closeItem() { return ""; } QString InfoFile::addTrackColumns(QStringList l) { row = 0; QString s = openItem(); foreach(QString i, l) { s += "" + i + ""; } s += closeItem(); return s; } QString InfoFile::addItem( QString tag, QString value ) { row++; return openItem() + "" + tag + "" + "" + value + "" + closeItem(); } QString InfoFile::addTrack(int n, QString lang, QString name, int ID, QString type) { QString s = "" + QString::number(n) + ""; if (!type.isEmpty()) s += "" + type + ""; s += QString("%1%2%3").arg(lang).arg(name).arg(ID); return s; } QString InfoFile::defaultStyle() { return ""; } #endif /* QString QCoreApplication::translate (const char * context, const char * sourceText, const char * disambiguation, Encoding encoding, int n ) 其实,这个才是真正进行翻译操作的函数,前面我们提到的tr最终是通过调用该函数来实现翻译功能的(稍后我们会看tr是如何调用translate的)。 对tr和这个函数,manual中都有比较详尽的解释。我们这儿简单看一下它的这几个参数: context 上下文,一般就是需要翻译的字符串所在的类的名字 sourceText 需要翻译的字符串。(我们关注的编码其实就是它的编码) disambiguation 消除歧义用的。(比如我们的类内出现两处"close",一处含义是关闭,另一处含义是亲密的。显然需要让翻译人员知道这点区别) encoding 指定编码。它有两个值 CodecForTr 使用setCodecForTr()设置的编码来解释 sourceText UnicodeUTF8 使用utf8编码来解释 sourceText 其实这两个分别对应tr和trUtf8 n 处理单复数(对中文来说,不存在这个问题) */ inline QString InfoFile::kylin_tr(const char * sourceText, const char * comment, int n) { #if QT_VERSION >= 0x050000 return QCoreApplication::translate("InfoFile", sourceText, comment, n ); #else return QCoreApplication::translate("InfoFile", sourceText, comment, QCoreApplication::CodecForTr, n ); #endif } kylin-video/src/smplayer/mylineedit.h0000644000175000017500000000223213517016402016665 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef MYLINEEDIT_H #define MYLINEEDIT_H #include "lineedit_with_icon.h" class QToolButton; class MyLineEdit : public LineEditWithIcon { Q_OBJECT public: MyLineEdit(QWidget *parent = 0); protected: virtual void setupButton(); private slots: void updateCloseButton(const QString &text); }; #endif // MYLINEEDIT_H kylin-video/src/smplayer/audioequalizer.h0000644000175000017500000000524013637124061017553 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2018 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef AUDIOEQUALIZER_H #define AUDIOEQUALIZER_H #include #include #include #include "audioequalizerlist.h" #include #include #include #include "audioequalizerlist.h" #include "utils.h" class QLabel; class QComboBox; class QPushButton; class EqSlider; class AudioEqualizer : public QWidget { Q_OBJECT public: enum Preset { User_defined = 0, Flat = 1, Pop = 2, Rock = 3, Classical = 4, Club = 5, Dance = 6, Fullbass = 7, FullbassTreble = 8, Fulltreble = 9, Headphones = 10, LargeHall = 11, Live = 12, Party = 13, Reggae = 14, Ska = 15, Soft = 16, SoftRock = 17, Techno = 18 }; AudioEqualizer( QWidget* parent = 0, Qt::WindowFlags f = Qt::Dialog ); ~AudioEqualizer(); EqSlider * eq[10]; void setEqualizer(AudioEqualizerList l); virtual bool eventFilter(QObject *, QEvent *); void moveDialog(QPoint diff); signals: void visibilityChanged(); void applyClicked(AudioEqualizerList new_values); void valuesChanged(AudioEqualizerList values); public slots: void reset(); void setDefaults(); protected slots: void applyButtonClicked(); void presetChanged(int index); void updatePresetCombo(); protected: virtual void hideEvent( QHideEvent * ); virtual void showEvent( QShowEvent * ); virtual void changeEvent( QEvent * event ); virtual void retranslateStrings(); void createPresets(); void setValues(AudioEqualizerList l); int findPreset(AudioEqualizerList l); protected: QLabel * presets_label; QComboBox * presets_combo; QPushButton * apply_button; QPushButton * reset_button; QPushButton * set_default_button; QPushButton * close_button; QMap preset_list; DragState m_dragState; QPoint m_startDrag; }; #endif kylin-video/src/smplayer/mpvprocess.h0000644000175000017500000001666213517016402016737 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef MPVPROCESS_H #define MPVPROCESS_H #include #include #include "playerprocess.h" #define OSD_WITH_TIMER //#ifndef USE_OLD_VIDEO_EQ class SoftVideoEq { public: SoftVideoEq() { contrast = brightness = hue = saturation = gamma = 0; }; SoftVideoEq(int c, int b, int h, int s, int g) { contrast = c; brightness = b; hue = h, saturation = s; gamma = g; } int contrast, brightness, hue, saturation, gamma; }; //#endif class QStringList; class MPVProcess : public PlayerProcess { Q_OBJECT public: MPVProcess(const QString &snap, QObject * parent = 0); ~MPVProcess(); bool start(); // Command line options void addArgument(const QString & a);//kobe 20170705 void setMedia(const QString & media, bool is_playlist = false); void disableInput(); void setFixedOptions(); void setOption(const QString & option_name, const QVariant & value = QVariant()); void addUserOption(const QString & option); void addVF(const QString & filter_name, const QVariant & value = QVariant()); void addAF(const QString & filter_name, const QVariant & value = QVariant()); void addStereo3DFilter(const QString & in, const QString & out); void setSubStyles(const AssStyles & styles, const QString & assStylesFile = QString::null); void setSubEncoding(const QString & codepage, const QString & enca_lang); void setVideoEqualizerOptions(int contrast, int brightness, int hue, int saturation, int gamma, bool soft_eq); // Slave commands void quit(); void setVolume(int v); void setOSD(int o); void setAudio(int ID); void setVideo(int ID); void setSubtitle(int type, int ID); void disableSubtitles(); void setSecondarySubtitle(int ID); void disableSecondarySubtitles(); void setSubtitlesVisibility(bool b); void seek(double secs, int mode, bool precise); void mute(bool b); void setPause(bool b); void frameStep(); void frameBackStep(); void showOSDText(const QString & text, int duration, int level); void showFilenameOnOSD(int duration = 2000); void showMediaInfoOnOSD(); void showTimeOnOSD(); void setContrast(int value); void setBrightness(int value); void setHue(int value); void setSaturation(int value); void setGamma(int value); void setChapter(int ID); void nextChapter(); void previousChapter(); void setExternalSubtitleFile(const QString & filename); void setSubPos(int pos); void setSubScale(double value); void setSubStep(int value); void seekSub(int value);//kobe 20170705 void setSubForcedOnly(bool b); void setSpeed(double value); //#ifdef MPLAYER_SUPPORT void enableKaraoke(bool b); void enableExtrastereo(bool b); //#endif void enableVolnorm(bool b, const QString & option); void enableEarwax(bool b); // void setAudioEqualizer(const QString & values); void setAudioEqualizer(AudioEqualizerList); void setAudioDelay(double delay); void setSubDelay(double delay); void setLoop(int v); void setAMarker(int sec); void setBMarker(int sec); void clearABMarkers(); void takeScreenshot(ScreenshotType t, bool include_subtitles = false); //#ifdef CAPTURE_STREAM // void switchCapturing(); //#endif void setTitle(int ID); void changeVF(const QString & filter, bool enable, const QVariant & option = QVariant()); void changeAF(const QString & filter, bool enable, const QVariant & option = QVariant()); void changeStereo3DFilter(bool enable, const QString & in, const QString & out); //#if DVDNAV_SUPPORT // void discSetMousePos(int x, int y); // void discButtonPressed(const QString & button_name); //#endif void setAspect(double aspect); void setFullscreen(bool b); void toggleDeinterlace(); void askForLength(); void setOSDScale(double value); void setOSDFractions(bool active); void setChannelsFile(const QString &); void enableScreenshots(const QString & dir, const QString & templ = QString::null, const QString & format = QString::null); void enableOSDInCommands(bool b) { use_osd_in_commands = b; }; bool isOSDInCommandsEnabled() { return use_osd_in_commands; }; QString mpvVersion() { return mpv_version; }; protected: bool isOptionAvailable(const QString & option); void addVFIfAvailable(const QString & vf, const QString & value = QString::null); void messageFilterNotSupported(const QString & filter_name); QString lavfi(const QString & filter_name, const QVariant & option = QVariant()); QString audioEqualizerFilter(AudioEqualizerList); //#ifndef USE_OLD_VIDEO_EQ QString videoEqualizerFilter(SoftVideoEq); void updateSoftVideoEqualizerFilter(); //#endif //#ifdef OSD_WITH_TIMER void toggleInfoOnOSD(); //#endif protected slots: void parseLine(QByteArray ba); void processFinished(int exitCode, QProcess::ExitStatus exitStatus); void gotError(QProcess::ProcessError); void requestChapterInfo(); // void requestBitrateInfo(); //#ifdef OSD_WITH_TIMER void displayInfoOnOSD(); //#endif signals: void receivedScreenshot(QString);//20170722 protected: virtual void initializeOptionVars(); void updateAudioTrack(int ID, const QString & name, const QString & lang, bool selected); void updateSubtitleTrack(int ID, const QString & name, const QString & lang, bool selected); void updateVideoTrack(int ID, const QString & name, const QString & lang, bool selected); private: bool notified_mplayer_is_running; bool notified_pause; bool received_end_of_file; int last_sub_id; int mplayer_svn; QString mpv_version; bool verbose; //字幕 SubTracks subs; bool subtitle_info_received; bool subtitle_info_changed; int selected_subtitle; //音频 Tracks audios; bool audio_info_changed; int selected_audio; //视频 Tracks videos; bool video_info_changed; int selected_video; //章节 Chapters chapters; bool chapter_info_changed; int dvd_current_title; int br_current_title; QString previous_eq; AudioEqualizerList previous_eq_list; //#ifndef USE_OLD_VIDEO_EQ bool use_soft_eq; SoftVideoEq current_soft_eq; SoftVideoEq previous_soft_eq; //#endif //#ifdef CAPTURE_STREAM // bool capturing; //#endif QString m_snap; //#ifdef OSD_WITH_TIMER QTimer * osd_timer; //#endif bool use_osd_in_commands; // Regular expressions QRegExp rx_av; QRegExp rx_dsize; QRegExp rx_vo; QRegExp rx_ao; QRegExp rx_paused; QRegExp rx_endoffile; QRegExp rx_audio; QRegExp rx_subs; QRegExp rx_videocodec; QRegExp rx_audiocodec; QRegExp rx_chaptername; QRegExp rx_trackinfo; QRegExp rx_forbidden; //#if DVDNAV_SUPPORT // QRegExp rx_switch_title; //#endif QRegExp rx_playing; QRegExp rx_generic; QRegExp rx_stream_title; QRegExp rx_debug; void initializeRX(); }; #endif kylin-video/src/smplayer/globalshortcuts/0000755000175000017500000000000013524205650017574 5ustar fengfengkylin-video/src/smplayer/globalshortcuts/globalshortcuts.h0000644000175000017500000000402013517016402023155 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2017 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef GLOBALSHORTCUTS_H #define GLOBALSHORTCUTS_H #include #include #include class GlobalShortcuts : public QObject, public QAbstractNativeEventFilter { Q_OBJECT public: enum MediaKey { VolumeMute = 1, VolumeDown = 2, VolumeUp = 4, MediaPlay = 8, MediaStop = 16, MediaPrevious = 32, MediaNext = 64, MediaPause = 128, MediaRecord = 256 }; Q_DECLARE_FLAGS(MediaKeys, MediaKey) GlobalShortcuts( QObject* parent = 0 ); ~GlobalShortcuts(); bool isEnabled() { return enabled; }; // It should be called before setEnabled void setGrabbedKeys(MediaKeys keys); MediaKeys grabbedKeys() { return grabbed_keys; }; virtual bool nativeEventFilter(const QByteArray & eventType, void * message, long * result); public slots: void setEnabled(bool); private: void registerAll(); void unregisterAll(); bool registerShortcut(quint32 nativeKey, quint32 nativeMods); bool unregisterShortcut(quint32 nativeKey, quint32 nativeMods); void activateShortcut(Qt::Key); void createKeysList(); QMap key_list; bool enabled; MediaKeys grabbed_keys; }; Q_DECLARE_OPERATORS_FOR_FLAGS(GlobalShortcuts::MediaKeys) #endif kylin-video/src/smplayer/globalshortcuts/globalshortcuts_win.cpp0000644000175000017500000000534613517016402024401 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2017 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include bool GlobalShortcuts::nativeEventFilter(const QByteArray & /*eventType*/, void * message, long * /*result*/) { //qDebug() << "GlobalShortcuts::nativeEventFilter"; if (!isEnabled()) return false; MSG* msg = static_cast(message); if (msg->message == WM_HOTKEY) { const quint32 keycode = HIWORD(msg->lParam); //const quint32 modifiers = LOWORD(msg->lParam); qDebug() << "GlobalShortcuts::nativeEventFilter: keycode:" << keycode; if (key_list.contains(keycode)) { activateShortcut(key_list[keycode]); } } return false; } bool GlobalShortcuts::registerShortcut(quint32 nativeKey, quint32 nativeMods) { qDebug() << "GlobalShortcuts::registerShortcut: nativeKey:" << nativeKey; return RegisterHotKey(0, nativeMods ^ nativeKey, nativeMods, nativeKey); } bool GlobalShortcuts::unregisterShortcut(quint32 nativeKey, quint32 nativeMods) { qDebug() << "GlobalShortcuts::unregisterShortcut: nativeKey:" << nativeKey; return UnregisterHotKey(0, nativeMods ^ nativeKey); } void GlobalShortcuts::createKeysList() { key_list.clear(); if (grabbed_keys.testFlag(VolumeDown)) { key_list[VK_VOLUME_DOWN] = Qt::Key_VolumeDown; } if (grabbed_keys.testFlag(VolumeUp)) { key_list[VK_VOLUME_UP] = Qt::Key_VolumeUp; } if (grabbed_keys.testFlag(VolumeMute)) { key_list[VK_VOLUME_MUTE] = Qt::Key_VolumeMute; } if (grabbed_keys.testFlag(MediaPlay)) { key_list[VK_MEDIA_PLAY_PAUSE] = Qt::Key_MediaPlay; } if (grabbed_keys.testFlag(MediaStop)) { key_list[VK_MEDIA_STOP] = Qt::Key_MediaStop; } if (grabbed_keys.testFlag(MediaPrevious)) { key_list[VK_MEDIA_PREV_TRACK] = Qt::Key_MediaPrevious; } if (grabbed_keys.testFlag(MediaNext)) { key_list[VK_MEDIA_NEXT_TRACK] = Qt::Key_MediaNext; } if (grabbed_keys.testFlag(MediaPlay)) { key_list[VK_PLAY] = Qt::Key_MediaPlay; } //key_list[VK_F11] = Qt::Key_MediaPlay; // TEST //key_list[] = Qt::Key_MediaPause; //key_list[] = Qt::Key_MediaRecord; } kylin-video/src/smplayer/globalshortcuts/globalshortcuts_linux.cpp0000644000175000017500000001076413517016402024743 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2017 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include class X11Data { public: X11Data() { QPlatformNativeInterface *native = qApp->platformNativeInterface(); void *display = native->nativeResourceForScreen(QByteArray("display"), QGuiApplication::primaryScreen()); disp = reinterpret_cast(display); } Display *display() { return disp; } Window rootWindow() { return DefaultRootWindow(display()); } bool isValid() { return disp != 0; } quint32 keysymToKeycode(KeySym keysym) { if (isValid()) { return XKeysymToKeycode(display(), keysym); } return 0; } private: Display * disp; }; bool GlobalShortcuts::nativeEventFilter(const QByteArray & eventType, void * message, long * /*result*/) { //qDebug() << "GlobalShortcuts::nativeEventFilter"; if (!isEnabled()) return false; xcb_key_press_event_t *kev = 0; if (eventType == "xcb_generic_event_t") { xcb_generic_event_t *ev = static_cast(message); if ((ev->response_type & 127) == XCB_KEY_PRESS) { kev = static_cast(message); } if (kev != 0) { unsigned int keycode = kev->detail; qDebug() << "GlobalShortcuts::nativeEventFilter: keycode:" << keycode; if (key_list.contains(keycode)) { activateShortcut(key_list[keycode]); return true; } } } return false; } bool GlobalShortcuts::registerShortcut(quint32 nativeKey, quint32 nativeMods) { qDebug() << "GlobalShortcuts::registerShortcut: nativeKey:" << nativeKey; X11Data x11; if (x11.isValid()) { Display * display = x11.display(); Window window = x11.rootWindow(); Bool owner = True; int pointer = GrabModeAsync; int keyboard = GrabModeAsync; XGrabKey(display, nativeKey, nativeMods, window, owner, pointer, keyboard); XGrabKey(display, nativeKey, nativeMods | Mod2Mask, window, owner, pointer, keyboard); XSync(display, False); return true; } return false; } bool GlobalShortcuts::unregisterShortcut(quint32 nativeKey, quint32 nativeMods) { qDebug() << "GlobalShortcuts::unregisterShortcut: nativeKey:" << nativeKey; X11Data x11; if (x11.isValid()) { Display * display = x11.display(); Window window = x11.rootWindow(); XUngrabKey(display, nativeKey, nativeMods, window); XUngrabKey(display, nativeKey, nativeMods | Mod2Mask, window); XSync(display, False); return true; } return false; } void GlobalShortcuts::createKeysList() { X11Data x11; key_list.clear(); if (grabbed_keys.testFlag(VolumeDown)) { key_list[x11.keysymToKeycode(XF86XK_AudioLowerVolume)] = Qt::Key_VolumeDown; } if (grabbed_keys.testFlag(VolumeUp)) { key_list[x11.keysymToKeycode(XF86XK_AudioRaiseVolume)] = Qt::Key_VolumeUp; } if (grabbed_keys.testFlag(VolumeMute)) { key_list[x11.keysymToKeycode(XF86XK_AudioMute)] = Qt::Key_VolumeMute; } if (grabbed_keys.testFlag(MediaPlay)) { key_list[x11.keysymToKeycode(XF86XK_AudioPlay)] = Qt::Key_MediaPlay; } if (grabbed_keys.testFlag(MediaStop)) { key_list[x11.keysymToKeycode(XF86XK_AudioStop)] = Qt::Key_MediaStop; } if (grabbed_keys.testFlag(MediaPrevious)) { key_list[x11.keysymToKeycode(XF86XK_AudioPrev)] = Qt::Key_MediaPrevious; } if (grabbed_keys.testFlag(MediaNext)) { key_list[x11.keysymToKeycode(XF86XK_AudioNext)] = Qt::Key_MediaNext; } if (grabbed_keys.testFlag(MediaPause)) { key_list[x11.keysymToKeycode(XF86XK_AudioPause)] = Qt::Key_MediaPause; } if (grabbed_keys.testFlag(MediaRecord)) { key_list[x11.keysymToKeycode(XF86XK_AudioRecord)] = Qt::Key_MediaRecord; } //key_list[x11.keysymToKeycode(0xffc8)] = Qt::Key_F11; // Test //qDebug() << "GlobalShortcuts::createKeysList:" << key_list; } kylin-video/src/smplayer/globalshortcuts/globalshortcuts.cpp0000644000175000017500000000743313517016402023523 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2017 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "globalshortcuts.h" #include #include #include #include #include #include #include #include GlobalShortcuts::GlobalShortcuts(QObject* parent) : QObject(parent) , enabled(false) { qDebug("GlobalShortcuts::GlobalShortcuts"); QAbstractEventDispatcher::instance()->installNativeEventFilter(this); grabbed_keys = VolumeMute | VolumeDown | VolumeUp | MediaPlay | MediaStop | MediaPrevious | MediaNext | MediaPause | MediaRecord; createKeysList(); //setEnabled(true); } GlobalShortcuts::~GlobalShortcuts() { if (enabled) setEnabled(false); } void GlobalShortcuts::setGrabbedKeys(MediaKeys keys) { if (keys != grabbed_keys) { grabbed_keys = keys; createKeysList(); } } void GlobalShortcuts::setEnabled(bool b) { qDebug() << "GlobalShortcuts::setEnabled:" << b; if (b == enabled) return; if (b) registerAll(); else unregisterAll(); enabled = b; } void GlobalShortcuts::registerAll() { QMapIterator i(key_list); while (i.hasNext()) { i.next(); registerShortcut(i.key(), 0); } } void GlobalShortcuts::unregisterAll() { QMapIterator i(key_list); while (i.hasNext()) { i.next(); unregisterShortcut(i.key(), 0); } } void GlobalShortcuts::activateShortcut(Qt::Key key) { #ifdef Q_OS_LINUX //if (QApplication::activeWindow()) return; #endif QKeySequence ks(key); qDebug() << "GlobalShortcuts::activateShortcut:" << key << "shortcut:" << ks; #if 0 Qt::KeyboardModifiers modifier = Qt::NoModifier; QString name = ks.toString(); QKeyEvent key_event(QEvent::KeyPress, key, modifier, name); qDebug() << "GlobalShortcuts::activateShortcut: name:" << name; if (parent()) QCoreApplication::sendEvent(parent(), &key_event); #else // Search actions with the shortcut if (isEnabled() && parent()) { QWidget * w = qobject_cast(parent()); if (!w) { qWarning("GlobalShortcuts::activateShortcut: parent is not a widget"); return; } QList actions = w->actions(); foreach(QAction * action, actions) { QList shortcuts = action->shortcuts(); foreach(QKeySequence s, shortcuts) { bool match = (s == ks); //qDebug() << "GlobalShortcuts::activateShortcut: action:" << action << "shortcut:" << s << "match:" << match; if (match) { qDebug() << "GlobalShortcuts::activateShortcut: action found:" << action->objectName() << "enabled:" << action->isEnabled(); } if (match && action->isEnabled()) { // SkinGui changes the play/pause action to checkable, which doesn't work if called toggle if (action->isCheckable() && action->objectName() != "playOrPause") { action->toggle(); } else { action->trigger(); } return; } } } } #endif } #include "moc_globalshortcuts.cpp" #ifdef Q_OS_UNIX #include "globalshortcuts_linux.cpp" #endif #ifdef Q_OS_WIN #include "globalshortcuts_win.cpp" #endif kylin-video/src/smplayer/globalshortcuts/globalshortcutsdialog.h0000644000175000017500000000230013517016402024334 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2018 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef GLOBALSHORTCUTSDIALOG_H #define GLOBALSHORTCUTSDIALOG_H #include "ui_globalshortcutsdialog.h" #include class GlobalShortcutsDialog : public QDialog, public Ui::GlobalShortcutsDialog { Q_OBJECT public: GlobalShortcutsDialog(QWidget* parent = 0, Qt::WindowFlags f = 0); ~GlobalShortcutsDialog(); void setGrabbedKeys(int); int grabbedKeys(); }; #endif kylin-video/src/smplayer/globalshortcuts/globalshortcutsdialog.ui0000644000175000017500000001123713524205650024536 0ustar fengfeng GlobalShortcutsDialog Qt::WindowModal 0 0 400 226 Dialog Select the multimedia keys that kylin-video will capture. true Media &Play Media &Stop Media Pre&vious Media &Next Media P&ause Qt::Vertical 20 40 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok Media &Record Volume &Mute Volume &Down Volume &Up Qt::Vertical 20 40 play_check stop_check previous_check next_check pause_check record_check mute_check voldown_check volup_check buttonBox buttonBox accepted() GlobalShortcutsDialog accept() 248 254 157 274 buttonBox rejected() GlobalShortcutsDialog reject() 316 260 286 274 kylin-video/src/smplayer/globalshortcuts/globalshortcutsdialog.cpp0000644000175000017500000000510613524205650024701 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2018 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "globalshortcutsdialog.h" #include "globalshortcuts.h" GlobalShortcutsDialog::GlobalShortcutsDialog(QWidget* parent, Qt::WindowFlags f ) : QDialog(parent, f) { setupUi(this); setWindowTitle("Kylin Video - " + tr("Global Shortcuts")); } GlobalShortcutsDialog::~GlobalShortcutsDialog() { } void GlobalShortcutsDialog::setGrabbedKeys(int keys) { GlobalShortcuts::MediaKeys k = (GlobalShortcuts::MediaKeys) keys; play_check->setChecked(k.testFlag(GlobalShortcuts::MediaPlay)); stop_check->setChecked(k.testFlag(GlobalShortcuts::MediaStop)); previous_check->setChecked(k.testFlag(GlobalShortcuts::MediaPrevious)); next_check->setChecked(k.testFlag(GlobalShortcuts::MediaNext)); pause_check->setChecked(k.testFlag(GlobalShortcuts::MediaPause)); record_check->setChecked(k.testFlag(GlobalShortcuts::MediaRecord)); mute_check->setChecked(k.testFlag(GlobalShortcuts::VolumeMute)); voldown_check->setChecked(k.testFlag(GlobalShortcuts::VolumeDown)); volup_check->setChecked(k.testFlag(GlobalShortcuts::VolumeUp)); } int GlobalShortcutsDialog::grabbedKeys() { GlobalShortcuts::MediaKeys k(QFlag (0)); if (play_check->isChecked()) k = k | GlobalShortcuts::MediaPlay; if (stop_check->isChecked()) k = k | GlobalShortcuts::MediaStop; if (previous_check->isChecked()) k = k | GlobalShortcuts::MediaPrevious; if (next_check->isChecked()) k = k | GlobalShortcuts::MediaNext; if (pause_check->isChecked()) k = k | GlobalShortcuts::MediaPause; if (record_check->isChecked()) k = k | GlobalShortcuts::MediaRecord; if (mute_check->isChecked()) k = k | GlobalShortcuts::VolumeMute; if (voldown_check->isChecked()) k = k | GlobalShortcuts::VolumeDown; if (volup_check->isChecked()) k = k | GlobalShortcuts::VolumeUp; return k; } #include "moc_globalshortcutsdialog.cpp" kylin-video/src/smplayer/prefaudio.ui0000644000175000017500000001750613517016402016700 0ustar fengfeng PrefAudio 0 0 470 371 10 20 451 111 Volume 4 4 4 4 Global volume 6 0 0 0 0 Use software volume control Qt::Horizontal 20 20 false Max. Amplification: false softvol_max_spin false 10 10000 Volume normalization by default 10 140 451 59 Synchronization 4 4 4 4 Audio/video auto synchronization Qt::Horizontal QSizePolicy::Expanding 40 31 false Factor: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false autosync_spin false 0 1000 100 10 210 451 29 Output driver: false ao_combo 0 0 false Qt::Horizontal 81 20 10 250 451 29 6 0 0 0 0 Channels by default: channels_combo Qt::Horizontal 40 20 kylin-video/src/smplayer/preferencesdialog.ui0000644000175000017500000000625413637124061020405 0ustar fengfeng PreferencesDialog 0 0 675 425 Kylin Video - Preferences 0 0 160 425 49 20 101 33 Preference Qt::AlignCenter 0 72 160 353 0 0 QFrame::StyledPanel QFrame::Raised 14 20 32 32 Qt::AlignCenter 181 20 470 360 0 0 -1 570 390 91 25 Cancel 369 390 91 25 Apply 470 390 91 25 OK kylin-video/src/smplayer/prefwidget.h0000644000175000017500000000354413517016402016671 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _PREFWIDGET_H_ #define _PREFWIDGET_H_ #include #include #include #define TEST_AND_SET( Pref, Dialog ) \ if ( Pref != Dialog ) { Pref = Dialog; requires_restart = true; } class QEvent; class PrefWidget : public QWidget { public: PrefWidget(QWidget * parent = 0, Qt::WindowFlags f = 0 ); ~PrefWidget(); // Return the name of the section virtual QString sectionName(); virtual QPixmap sectionIcon(); // Return true if the changes made require to restart the mplayer // process. Should be call just after the changes have been applied. virtual bool requiresRestart() { return requires_restart; }; virtual QString help() { return help_message; }; protected: virtual void retranslateStrings(); virtual void changeEvent ( QEvent * event ) ; // Help void addSectionTitle(const QString & title); void setWhatsThis( QWidget *w, const QString & title, const QString & text); void clearHelp(); virtual void createHelp(); bool requires_restart; private: QString help_message; }; #endif kylin-video/src/smplayer/discname.h0000644000175000017500000000330113517016402016303 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2018 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef DISCNAME_H #define DISCNAME_H #include #define DISCNAME_TEST 0 class DiscData { public: DiscData() { protocol = ""; device = ""; title = 0; }; DiscData(const QString & protocol, int title, const QString & device) { this->protocol = protocol; this->title = title; this->device = device; }; ~DiscData() {}; QString protocol; QString device; int title; }; class DiscName { public: enum Disc { DVD = 1, DVDNAV = 2, VCD = 3, CDDA = 4, BLURAY = 5 }; static QString join(Disc type, int title, const QString & device); static QString join(const DiscData & d); static QString joinDVD(int title, const QString & device, bool use_dvdnav = false); static DiscData split(const QString & disc_url, bool *ok = 0); #if DISCNAME_TEST static void test(); #endif protected: static QString removeTrailingSlash(const QString & device); }; #endif kylin-video/src/smplayer/inputurl.cpp0000644000175000017500000001607413637124061016754 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "inputurl.h" #include "../smplayer/images.h" #include "../smplayer/mylineedit.h" #include #include #include #include //http://rbv01.ku6.com/WrTcR6Yik9QIW4XIcxYvDw.mp4 InputURL::InputURL( QWidget* parent, Qt::WindowFlags f ) : QDialog(parent, f) , m_dragState(NOT_DRAGGING) , m_startDrag(QPoint(0,0)) { setupUi(this); this->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint); this->setFixedSize(500, 170); this->setStyleSheet("QDialog{border: 1px solid #121212;border-radius:1px;background-color:#1f1f1f;}"); this->setWindowIcon(QIcon::fromTheme("kylin-video", QIcon(":/res/kylin-video.png"))); // this->setWindowIcon(QIcon::fromTheme("kylin-video", QIcon(":/res/kylin-video.png")).pixmap(QSize(64, 64)).scaled(64, 64, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); this->setAutoFillBackground(true); this->setMouseTracking(true); installEventFilter(this); // setMinimumSize( QSize(500,140) ); // setMaximumSize( QSize(600,170) ); //layout()->setSizeConstraint(QLayout::SetFixedSize); title_label->setStyleSheet("QLabel{background:transparent;font-size:14px;color:#999999;font-family:方正黑体_GBK;}");//font-weight:bold; label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}");//font-weight:bold; // url_icon->setPixmap( Images::icon("url_big", 48) ); url_edit->setFocus(); url_edit->setFixedHeight(27); url_edit->setStyleSheet("QComboBox{width:150px;height:27px;border:1px solid #000000;background:#0f0f0f;font-size:12px;font-family:方正黑体_GBK;background-position:center left;padding-left:5px;color:#999999;selection-color:#ffffff;selection-background-color:#1f1f1f;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox::drop-down {width:17px;border:none;background:transparent;}QComboBox::drop-down:hover {background:transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView{border:1px solid #0a9ff5;background:#262626;outline:none;}"); MyLineEdit *edit = new MyLineEdit(this); edit->setFixedHeight(25); url_edit->setLineEdit(edit); closeBtn->setFocusPolicy(Qt::NoFocus); closeBtn->setStyleSheet("QPushButton{background-image:url(':/res/close_normal.png');border:0px;}QPushButton:hover{background:url(':/res/close_hover.png');}QPushButton:pressed{background:url(':/res/close_press.png');}"); okBtn->setFixedSize(91, 25); okBtn->setText(tr("OK")); okBtn->setFocusPolicy(Qt::NoFocus); okBtn->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); cancelBtn->setFixedSize(91, 25); cancelBtn->setText(tr("Cancel")); cancelBtn->setFocusPolicy(Qt::NoFocus); cancelBtn->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #000000;color:#999999;}QPushButton:hover{background-color:#1f1f1f;border:1px solid #0f0f0f;color:#ffffff;} QPushButton:pressed{background-color:#0d0d0d;border:1px solid #000000;color:#ffffff;}"); this->initConnect(); } InputURL::~InputURL() { } void InputURL::initConnect() { connect(okBtn, SIGNAL(clicked()), this, SLOT(accept())); connect(cancelBtn, SIGNAL(clicked()), this, SLOT(close())); connect(closeBtn, SIGNAL(clicked()), this, SLOT(close())); } void InputURL::setURL(QString url) { url_edit->addItem(url); } QString InputURL::url() { return url_edit->currentText().trimmed(); } void InputURL::moveDialog(QPoint diff) { #if QT_VERSION >= 0x050000 // Move the window with some delay. // Seems to work better with Qt 5 static QPoint d; static int count = 0; d += diff; count++; if (count > 3) { QPoint new_pos = pos() + d; if (new_pos.y() < 0) new_pos.setY(0); if (new_pos.x() < 0) new_pos.setX(0); move(new_pos); count = 0; d = QPoint(0,0); } #else move(pos() + diff); #endif } bool InputURL::eventFilter( QObject * object, QEvent * event ) { QEvent::Type type = event->type(); if (type != QEvent::MouseButtonPress && type != QEvent::MouseButtonRelease && type != QEvent::MouseMove) return false; QMouseEvent *mouseEvent = dynamic_cast(event); if (!mouseEvent) return false; if (mouseEvent->modifiers() != Qt::NoModifier) { m_dragState = NOT_DRAGGING; return false; } if (type == QEvent::MouseButtonPress) { if (mouseEvent->button() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } m_dragState = START_DRAGGING; m_startDrag = mouseEvent->globalPos(); // Don't filter, so others can have a look at it too return false; } if (type == QEvent::MouseButtonRelease) { if (m_dragState != DRAGGING || mouseEvent->button() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } // Stop dragging and eat event m_dragState = NOT_DRAGGING; event->accept(); return true; } // type == QEvent::MouseMove if (m_dragState == NOT_DRAGGING) return false; // buttons() note the s if (mouseEvent->buttons() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } QPoint pos = mouseEvent->globalPos(); QPoint diff = pos - m_startDrag; if (m_dragState == START_DRAGGING) { // Don't start dragging before moving at least DRAG_THRESHOLD pixels if (abs(diff.x()) < 4 && abs(diff.y()) < 4) return false; m_dragState = DRAGGING; } this->moveDialog(diff); m_startDrag = pos; event->accept(); return true; } //#include "moc_inputurl.cpp" kylin-video/src/smplayer/images.h0000644000175000017500000000335313517016402015774 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IMAGES_H #define IMAGES_H #include #include #include //#define USE_RESOURCES //#define SMCODE class Images { public: static void setThemesPath(const QString & folder); static void setTheme(const QString & name); static QPixmap icon(QString name, int size=-1); static QPixmap flippedIcon(QString name, int size=-1); //! Returns the filename of the icon static QString file(const QString & icon_name); //#ifdef SMCODE // static QString styleSheet(); // static QString themesDirectory(); //#endif static bool is_internal; //#ifdef USE_RESOURCES static bool has_rcc; //#endif private: static QPixmap resize(QPixmap *p, int size=20); static QPixmap flip(QPixmap *p); static QString current_theme; static QString themes_path; //#ifdef USE_RESOURCES static QString resourceFilename(); static QString last_resource_loaded; //#endif }; #endif kylin-video/src/smplayer/preferences.cpp0000644000175000017500000015132113625147453017375 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "preferences.h" #include "../smplayer/global.h" #include "../smplayer/paths.h" #include "../smplayer/mediasettings.h" #include "../smplayer/recents.h" #include "../smplayer/urlhistory.h" #include "../smplayer/filters.h" #include "../utils.h" #include #include #include #include #include #include #if QT_VERSION >= 0x050000 #include #endif #if QT_VERSION >= 0x040400 #include #endif //#ifdef GLOBALSHORTCUTS #include "../smplayer/globalshortcuts/globalshortcuts.h" //#endif #define USE_CONFIG_VERSION #ifdef USE_CONFIG_VERSION #define CURRENT_CONFIG_VERSION 5 #endif using namespace Global; Preferences::Preferences(const QString &arch) { arch_type = arch; history_recents = new Recents; history_urls = new URLHistory; filters = new Filters; m_decoingType = this->getHardwareDecodingType(); reset(); load(); } Preferences::~Preferences() { save(); delete history_recents; delete history_urls; delete filters; m_videoMap.clear(); } VideoPtr Preferences::generateVedioData(const QString &filepath, QString &name, double duration) { //filepath.absoluteFilePath() if (m_videoMap.contains(filepath)) { return m_videoMap.value(filepath); } VideoPtr video = VideoPtr(new VideoData); Q_ASSERT(video != nullptr); video->m_localpath = filepath;//filepath.absoluteFilePath(); video->m_name = name; video->m_duration = duration; return video; } bool Preferences::isEmpty() const { return this->m_videoMap.isEmpty(); } const VideoPtr Preferences::video(const QString &hash) const { return this->m_videoMap.value(hash); } bool Preferences::contains(const VideoPtr video) const { if (!video.isNull()) return m_videoMap.contains(video->m_localpath); return false; } bool Preferences::contains(const QString &filepath) const { return this->m_videoMap.contains(filepath); } void Preferences::updatePlaylist(QStringList playlist) { qDebug() << "playlist=" << playlist; // QMap videoMap = m_videoMap; // QMap fileMap; // for (int i = 0; i < this->rowCount(); ++i) { // auto index = this->index(i, 0); // auto filepath = this->data(index).toString();//没有重写model的data函数时 // Q_ASSERT(!filepath.isEmpty()); // fileMap.insert(filepath, i); // } // QStringList sortList; // if (fileMap.count() > 0) { // QMap::iterator j; // for (j = fileMap.begin(); j != fileMap.end(); ++j) { // sortList.insert(j.value(), j.key()); // } // } // qDebug() << "########sortList=" << sortList; // QMap videos; // QMap myvideos; // for(int n=0; n < sortList.size(); ++n) { // qDebug() << "===========" << n; // QMap::iterator k; // int mydex = 0; // for (k = pref->m_videoMap.begin(); k != pref->m_videoMap.end(); ++k) { // qDebug() << "mydex===========" << mydex; // mydex ++; // if (sortList.at(n) == k.key()) { // videos.insert(k.key(), k.value()); // qDebug() << "$$$$$2" << k.key() << k.value()->localpath(); // myvideos.insert(k.key(), k.value()->localpath()); // break; // } // } // } // QMap::iterator m; // for (m = videos.begin(); m != videos.end(); ++m) { // qDebug() << "$$$$$3" << m.key() << m.value()->localpath(); // } //// myvideos.insert("a", "aaa"); //// myvideos.insert("b", "bbb"); //// myvideos.insert("c", "ccc"); // QMap::iterator l; // for (l = myvideos.begin(); l != myvideos.end(); ++l) { // qDebug() << "$$$$$4" << l.key() << l.value(); // } } void Preferences::reset() { #ifdef USE_CONFIG_VERSION config_version = CURRENT_CONFIG_VERSION; #endif //edited by kobe 20180623 mplayer_bin = "/usr/bin/mpv";//mplayer_bin = QString("%1/mpv").arg(Paths::appPath()); //20191206 if (arch_type == "aarch64") { vo = "vdpau"; } else { vo = "xv"; } //ao = "pulse";//ao = ""; //vo = "player_default"; ao = "player_default"; use_screenshot = true; screenshot_template = "cap_%F_%p_%02n"; screenshot_format = "jpg"; screenshot_directory=""; #if QT_VERSION < 0x040400 QString default_screenshot_path = Paths::configPath() + "/screenshots"; if (QFile::exists(default_screenshot_path)) { screenshot_directory = default_screenshot_path; } #endif remember_media_settings = true; remember_time_pos = true; remember_stream_settings = true; remember_media_settings = true; remember_time_pos = true; remember_stream_settings = true; alang = ""; slang = ""; use_direct_rendering = false; use_double_buffer = true; use_soft_video_eq = false; use_slices = false; autoq = 6; //#ifdef ADD_BLACKBORDERS_FS add_blackborders_on_fullscreen = false; //#endif disable_screensaver = true; vdpau.ffh264vdpau = true; vdpau.ffmpeg12vdpau = true; vdpau.ffwmv3vdpau = true; vdpau.ffvc1vdpau = true; vdpau.ffodivxvdpau = false; vdpau.ffhevcvdpau = false; vdpau.disable_video_filters = true;//kobe 20180612 use_soft_vol = true; softvol_max = 110; // 110 = default value in mplayer use_scaletempo = Detect; use_hwac3 = false; use_audio_equalizer = true; global_volume = true; volume = 50; mute = false; global_audio_equalizer = true; audio_equalizer << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; // FIXME: use initial_audio_equalizer (but it's set later) autosync = false; autosync_factor = 30;//100 调整音视频同步,帮助文件指出 置为30为最佳 use_mc = false; mc_value = 0; autoload_m4a = true; min_step = 4; osd = Seek; osd_scale = 1; subfont_osd_scale = 3; osd_delay = 5000; //#ifdef MPV_SUPPORT osd_fractions = false; //#endif osd_bar_pos = 80; osd_show_filename_duration = 2000; //kobe:pref->file_settings_method 记住时间位置的配置设置在一个ini文件时为normal,在多个ini文件时为hash file_settings_method = "normal";//"hash"; // Possible values: normal & hash tablet_mode = false; /* *************** Drives (CD/DVD) *************** */ dvd_device = ""; cdrom_device = ""; //#ifdef BLURAY_SUPPORT // bluray_device = ""; //#endif //#ifndef Q_OS_WIN // Try to set default values if (QFile::exists("/dev/dvd")) dvd_device = "/dev/dvd"; if (QFile::exists("/dev/cdrom")) cdrom_device = "/dev/cdrom"; //#endif //#ifdef Q_OS_WIN // enable_audiocd_on_windows = false; //#endif vcd_initial_title = 2; // Most VCD's start at title #2 //#if DVDNAV_SUPPORT // use_dvdnav = false; //#endif /* *********** Performance *********** */ frame_drop = false; hard_frame_drop = false; coreavc = false; h264_skip_loop_filter = LoopEnabled; HD_height = 720; //#ifdef OBSOLETE_FAST_AUDIO_CHANGE // // MPlayer 1.0rc1 require restart, new versions don't // fast_audio_change = Detect; //#endif threads = 4;//1 hwdec = "no";//"auto" //hwdec = "rkmpp-copy"; cache_auto = true; cache_for_files = 2048; cache_for_streams = 2048; cache_for_dvds = 0; // not recommended to use cache for dvds cache_for_vcds = 1024; cache_for_audiocds = 1024; //#ifdef TV_SUPPORT // cache_for_tv = 3000; //#endif /* ********* Subtitles ********* */ subcp = "UTF-8";//"ISO-8859-1"; use_enca = false; enca_lang = QString(QLocale::system().name()).section("_",0,0); subfuzziness = 1; autoload_sub = true; use_ass_subtitles = true; enable_ass_styles = true; ass_line_spacing = 0; use_forced_subs_only = false; sub_visibility = true; subtitles_on_screenshots = false; change_sub_scale_should_restart = Detect; fast_load_sub = true; // ASS styles // Nothing to do, default values are given in // AssStyles constructor force_ass_styles = false; user_forced_ass_style.clear(); freetype_support = true; /* ******** Advanced ******** */ use_mplayer_window = false; use_idx = false; use_lavf_demuxer = false; mplayer_additional_options=""; // #if defined(PORTABLE_APP) && defined(FONTS_HACK) // mplayer_additional_options="-nofontconfig"; // #endif mplayer_additional_video_filters=""; mplayer_additional_audio_filters=""; verbose_log = false; // "Repaint video background" in the preferences dialog // #ifndef Q_OS_WIN // Note: on linux there could be flickering when using mplayer if this option is true // but setting it to false could display a corrupted window // from the moment the user press play until playback actually starts repaint_video_background = true; use_edl_files = true; //#ifdef MPLAYER_SUPPORT use_playlist_option = false; //#endif prefer_ipv4 = true; use_short_pathnames = false; change_video_equalizer_on_startup = true; use_pausing_keep_force = true; use_correct_pts = Detect; actions_to_run = ""; show_tag_in_window_title = true; time_to_kill_mplayer = 5000;//1000 //#ifdef MPV_SUPPORT mpv_osd_media_info = ""; //#endif //#ifdef MPLAYER_SUPPORT mplayer_osd_media_info = ""; //#endif //#ifdef MPV_SUPPORT emulate_mplayer_ab_section = false; //#endif use_native_open_dialog = true; /* ********* GUI stuff ********* */ fullscreen = false; start_in_fullscreen = false; compact_mode = false; stay_on_top = NeverOnTop; size_factor = 100; // 100% play_order = OrderPlay; // resize_method = Afterload;//kobe: Never; resize_method = Never;//Afterload center_window = false; center_window_if_outside = false; //#ifdef GLOBALSHORTCUTS use_global_shortcuts = false; global_shortcuts_grabbed_keys = GlobalShortcuts::MediaPlay | GlobalShortcuts::MediaStop | GlobalShortcuts::MediaPrevious | GlobalShortcuts::MediaNext | GlobalShortcuts::MediaPause | GlobalShortcuts::MediaRecord | GlobalShortcuts::VolumeMute | GlobalShortcuts::VolumeDown | GlobalShortcuts::VolumeUp; //#endif //#if DVDNAV_SUPPORT // mouse_left_click_function = "dvdnav_mouse"; //#else mouse_left_click_function = ""; //#endif mouse_right_click_function = "show_context_menu"; mouse_double_click_function = "fullscreen"; mouse_middle_click_function = "mute"; mouse_xbutton1_click_function = ""; mouse_xbutton2_click_function = ""; wheel_function = Seeking; wheel_function_cycle = Seeking | Volume | Zoom | ChangeSpeed; wheel_function_seeking_reverse = false; drag_function = MoveWindow; seeking1 = 10; seeking2 = 60; seeking3 = 10*60; seeking4 = 30; update_while_seeking = false; //#if ENABLE_DELAYED_DRAGGING time_slider_drag_delay = 100; //#endif relative_seeking = false; precise_seeking = true; reset_stop = false; delay_left_click = false; language = ""; balloon_count = 5; restore_pos_after_fullscreen = false; save_window_size_on_exit = true; close_on_finish = false; default_font = ""; pause_when_hidden = false; allow_video_movement = false; gui = "DefaultGUI"; iconset = "H2O"; gui_minimum_width = 0; // 0 == disabled default_size = QSize(683, 509); //#ifdef Q_OS_WIN // report_mplayer_crashes = false; //#else report_mplayer_crashes = true; //#endif reported_mplayer_is_old = false; auto_add_to_playlist = true; media_to_add_to_playlist = NoFiles; animated_logo = true; preview_when_playing = true; // playlist_key = "F3"; // prev_key = "<, Media Previous"; // next_key = ">, Media Next"; /* *********** Directories *********** */ latest_dir = QDir::homePath(); // last_dvd_directory=""; // save_dirs = true; /* ************** Initial values ************** */ initial_sub_scale = 5; initial_sub_scale_ass = 1; initial_volume = 40; initial_contrast = 0; initial_brightness = 0; initial_hue = 0; initial_saturation = 0; initial_gamma = 0; initial_audio_equalizer << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0; initial_zoom_factor = 1.0; initial_sub_pos = 100; // 100% //#ifdef INITIAL_BLACKBORDERS initial_blackborders = false; //#endif initial_postprocessing = false; initial_volnorm = false; initial_deinterlace = MediaSettings::NoDeinterlace; initial_audio_channels = MediaSettings::ChStereo;//MediaSettings::ChDefault; initial_stereo_mode = MediaSettings::Stereo; //#if SELECT_TRACKS_ON_STARTUP initial_audio_track = 0; initial_subtitle_track = 0; //#endif /* ************ MPlayer info ************ */ mplayer_detected_version = -1; //None version parsed yet mplayer_user_supplied_version = -1; /* ******* History ******* */ history_recents->clear(); history_urls->clear(); /* ******* Filters ******* */ filters->init(); ; m_videoMap.clear(); } void Preferences::save() { // qDebug("Preferences::save"); QSettings * set = settings; /* ******* General ******* */ set->beginGroup("General"); // set->setValue("config_version", config_version); set->setValue("mplayer_bin", mplayer_bin); set->setValue("driver/vo", vo); set->setValue("driver/audio_output", ao); set->setValue("use_screenshot", use_screenshot); set->setValue("screenshot_template", screenshot_template); set->setValue("screenshot_format", screenshot_format); //qDebug() << "save screenshot_directory="<< screenshot_directory; #if QT_VERSION >= 0x040400 set->setValue("screenshot_folder", screenshot_directory); #else set->setValue("screenshot_directory", screenshot_directory); #endif // set->setValue("remember_media_settings", remember_media_settings); // set->setValue("remember_time_pos", remember_time_pos); // set->setValue("remember_stream_settings", remember_stream_settings); // set->setValue("alang", alang); // set->setValue("slang", slang); set->setValue("use_direct_rendering", use_direct_rendering); set->setValue("use_double_buffer", use_double_buffer); set->setValue("use_soft_video_eq", use_soft_video_eq); set->setValue("use_slices", use_slices ); set->setValue("autoq", autoq); //#ifdef ADD_BLACKBORDERS_FS // set->setValue("add_blackborders_on_fullscreen", add_blackborders_on_fullscreen); //#endif // set->setValue("disable_screensaver", disable_screensaver); // set->setValue("vdpau_ffh264vdpau", vdpau.ffh264vdpau); // set->setValue("vdpau_ffmpeg12vdpau", vdpau.ffmpeg12vdpau); // set->setValue("vdpau_ffwmv3vdpau", vdpau.ffwmv3vdpau); // set->setValue("vdpau_ffvc1vdpau", vdpau.ffvc1vdpau); // set->setValue("vdpau_ffodivxvdpau", vdpau.ffodivxvdpau); // set->setValue("vdpau_ffhevcvdpau", vdpau.ffhevcvdpau); // set->setValue("vdpau_disable_video_filters", vdpau.disable_video_filters); set->setValue("use_soft_vol", use_soft_vol); set->setValue("softvol_max", softvol_max); set->setValue("use_scaletempo", use_scaletempo); set->setValue("use_hwac3", use_hwac3 ); // set->setValue("use_audio_equalizer", use_audio_equalizer ); set->setValue("global_volume", global_volume); set->setValue("volume", volume); set->setValue("mute", mute); set->setValue("global_audio_equalizer", global_audio_equalizer); set->setValue("audio_equalizer", audio_equalizer); set->setValue("autosync", autosync); set->setValue("autosync_factor", autosync_factor); // set->setValue("use_mc", use_mc); // set->setValue("mc_value", mc_value); // set->setValue("autoload_m4a", autoload_m4a); set->setValue("min_step", min_step); set->setValue("osd", osd); set->setValue("osd_scale", osd_scale); set->setValue("subfont_osd_scale", subfont_osd_scale); set->setValue("osd_delay", osd_delay); //#ifdef MPV_SUPPORT set->setValue("osd_fractions", osd_fractions); //#endif set->setValue("osd_bar_pos", osd_bar_pos); set->setValue("osd_show_filename_duration", osd_show_filename_duration); // set->setValue("file_settings_method", file_settings_method); // set->setValue("tablet_mode", tablet_mode); set->endGroup(); // General /* *************** Drives (CD/DVD) *************** */ /* set->beginGroup( "drives"); set->setValue("dvd_device", dvd_device); set->setValue("cdrom_device", cdrom_device); //#ifdef BLURAY_SUPPORT // set->setValue("bluray_device", bluray_device); //#endif //#ifdef Q_OS_WIN // set->setValue("enable_audiocd_on_windows", enable_audiocd_on_windows); //#endif set->setValue("vcd_initial_title", vcd_initial_title); //#if DVDNAV_SUPPORT // set->setValue("use_dvdnav", use_dvdnav); //#endif set->endGroup(); // drives */ /* *********** Performance *********** */ set->beginGroup( "performance"); // set->setValue("frame_drop", frame_drop); // set->setValue("hard_frame_drop", hard_frame_drop); // set->setValue("coreavc", coreavc); // set->setValue("h264_skip_loop_filter", h264_skip_loop_filter); set->setValue("HD_height", HD_height); set->setValue("threads", threads); set->setValue("hwdec", hwdec); // set->setValue("cache_auto", cache_auto); set->setValue("cache_for_files", cache_for_files); set->setValue("cache_for_streams", cache_for_streams); // set->setValue("cache_for_dvds", cache_for_dvds); // set->setValue("cache_for_vcds", cache_for_vcds); // set->setValue("cache_for_audiocds", cache_for_audiocds); set->endGroup(); // performance /* ********* Subtitles ********* */ set->beginGroup("subtitles"); set->setValue("subcp", subcp); set->setValue("use_enca", use_enca); set->setValue("enca_lang", enca_lang); // set->setValue("subfuzziness", subfuzziness); // set->setValue("autoload_sub", autoload_sub); // set->setValue("use_ass_subtitles", use_ass_subtitles); // set->setValue("enable_ass_styles", enable_ass_styles); // set->setValue("ass_line_spacing", ass_line_spacing); // set->setValue("use_forced_subs_only", use_forced_subs_only); set->setValue("sub_visibility", sub_visibility); // set->setValue("subtitles_on_screenshots", subtitles_on_screenshots); // set->setValue("change_sub_scale_should_restart", change_sub_scale_should_restart); // set->setValue("fast_load_sub", fast_load_sub); // ASS styles // ass_styles.save(set); // set->setValue("force_ass_styles", force_ass_styles); // set->setValue("user_forced_ass_style", user_forced_ass_style); // set->setValue("freetype_support", freetype_support); set->endGroup(); // subtitles /* ******** Advanced ******** */ set->beginGroup( "advanced"); // set->setValue("use_mplayer_window", use_mplayer_window); set->setValue("use_idx", use_idx); set->setValue("use_lavf_demuxer", use_lavf_demuxer); // set->setValue("mplayer_additional_options", mplayer_additional_options); // set->setValue("mplayer_additional_video_filters", mplayer_additional_video_filters); // set->setValue("mplayer_additional_audio_filters", mplayer_additional_audio_filters); // set->setValue("repaint_video_background", repaint_video_background); set->setValue("use_edl_files", use_edl_files); //#ifdef MPLAYER_SUPPORT set->setValue("use_playlist_option", use_playlist_option); //#endif // set->setValue("prefer_ipv4", prefer_ipv4); set->setValue("use_short_pathnames", use_short_pathnames); // set->setValue("change_video_equalizer_on_startup", change_video_equalizer_on_startup); // set->setValue("use_pausing_keep_force", use_pausing_keep_force); // set->setValue("correct_pts", use_correct_pts); set->setValue("actions_to_run", actions_to_run); set->setValue("show_tag_in_window_title", show_tag_in_window_title); set->setValue("time_to_kill_player", time_to_kill_mplayer); //#ifdef MPV_SUPPORT set->setValue("mpv_osd_media_info", mpv_osd_media_info); //#endif //#ifdef MPLAYER_SUPPORT set->setValue("mplayer_osd_media_info", mplayer_osd_media_info); //#endif //#ifdef MPV_SUPPORT // set->setValue("emulate_mplayer_ab_section", emulate_mplayer_ab_section); //#endif // set->setValue("use_native_open_dialog", use_native_open_dialog); set->endGroup(); // advanced /* ********* GUI stuff ********* */ set->beginGroup("gui"); set->setValue("fullscreen", fullscreen); // set->setValue("start_in_fullscreen", start_in_fullscreen); // set->setValue("compact_mode", compact_mode); set->setValue("stay_on_top", (int) stay_on_top); // set->setValue("size_factor", size_factor); // set->setValue("resize_method", resize_method); // set->setValue("center_window", center_window); // set->setValue("center_window_if_outside", center_window_if_outside); //#ifdef GLOBALSHORTCUTS // set->setValue("use_global_shortcuts", use_global_shortcuts); // set->setValue("global_shortcuts_grabbed_keys", global_shortcuts_grabbed_keys); //#endif // set->setValue("mouse_left_click_function", mouse_left_click_function); // set->setValue("mouse_right_click_function", mouse_right_click_function); // set->setValue("mouse_double_click_function", mouse_double_click_function); // set->setValue("mouse_middle_click_function", mouse_middle_click_function); // set->setValue("mouse_xbutton1_click_function", mouse_xbutton1_click_function); // set->setValue("mouse_xbutton2_click_function", mouse_xbutton2_click_function); set->setValue("mouse_wheel_function", wheel_function); set->setValue("wheel_function_cycle", (int) wheel_function_cycle); set->setValue("wheel_function_seeking_reverse", wheel_function_seeking_reverse); // set->setValue("drag_function", drag_function); set->setValue("seeking1", seeking1); set->setValue("seeking2", seeking2); set->setValue("seeking3", seeking3); set->setValue("seeking4", seeking4); // set->setValue("update_while_seeking", update_while_seeking); //#if ENABLE_DELAYED_DRAGGING set->setValue("time_slider_drag_delay", time_slider_drag_delay); //#endif // set->setValue("relative_seeking", relative_seeking); // set->setValue("precise_seeking", precise_seeking); // set->setValue("reset_stop", reset_stop); // set->setValue("delay_left_click", delay_left_click); // set->setValue("language", language); // set->setValue("iconset", iconset); // set->setValue("balloon_count", balloon_count); // set->setValue("restore_pos_after_fullscreen", restore_pos_after_fullscreen); // set->setValue("save_window_size_on_exit", save_window_size_on_exit); // set->setValue("close_on_finish", close_on_finish); // set->setValue("default_font", default_font); set->setValue("pause_when_hidden", pause_when_hidden); set->setValue("allow_video_movement", allow_video_movement); // set->setValue("gui", gui); // set->setValue("gui_minimum_width", gui_minimum_width); // set->setValue("default_size", default_size); // set->setValue("report_player_crashes", report_mplayer_crashes); // set->setValue("reported_mplayer_is_old", reported_mplayer_is_old); // set->setValue("auto_add_to_playlist", auto_add_to_playlist); set->setValue("media_to_add_to_playlist", media_to_add_to_playlist); set->setValue("preview_when_playing", preview_when_playing); // set->setValue("playlist_key", playlist_key); // set->setValue("next_key", next_key); // set->setValue("prev_key", prev_key); set->endGroup(); // gui /* *********** Directories *********** */ set->beginGroup( "directories"); // if (save_dirs) { // set->setValue("latest_dir", latest_dir); // set->setValue("last_dvd_directory", last_dvd_directory); // } else { // set->setValue("latest_dir", ""); // set->setValue("last_dvd_directory", ""); // } // set->setValue("save_dirs", save_dirs); set->setValue("latest_dir", latest_dir); set->endGroup(); // directories*/ /* ************** Initial values ************** */ set->beginGroup( "defaults"); set->setValue("initial_sub_scale", initial_sub_scale); set->setValue("initial_sub_scale_ass", initial_sub_scale_ass); set->setValue("initial_volume", initial_volume); set->setValue("initial_contrast", initial_contrast); set->setValue("initial_brightness", initial_brightness); set->setValue("initial_hue", initial_hue); set->setValue("initial_saturation", initial_saturation); set->setValue("initial_gamma", initial_gamma); set->setValue("initial_audio_equalizer", initial_audio_equalizer); set->setValue("initial_zoom_factor", initial_zoom_factor); set->setValue("initial_sub_pos", initial_sub_pos); set->setValue("initial_volnorm", initial_volnorm); //#ifdef INITIAL_BLACKBORDERS set->setValue("initial_blackborders", initial_blackborders); //#endif set->setValue("initial_postprocessing", initial_postprocessing); set->setValue("initial_deinterlace", initial_deinterlace); set->setValue("audio_channels", initial_audio_channels); set->setValue("initial_stereo_mode", initial_stereo_mode); set->setValue("preferred_audio_track", initial_audio_track); set->setValue("preferred_subtitle_track", initial_subtitle_track); set->endGroup(); // defaults /* ************ MPlayer info ************ */ set->beginGroup( "mplayer_info"); set->setValue("mplayer_detected_version", mplayer_detected_version); set->setValue("mplayer_user_supplied_version", mplayer_user_supplied_version); set->endGroup(); // mplayer_info /* ******* History ******* */ set->beginGroup("history"); set->setValue("recents", history_recents->toStringList()); set->setValue("recents/max_items", history_recents->maxItems()); set->setValue("urls", history_urls->toStringList()); set->setValue("urls/max_items", history_urls->maxItems()); set->endGroup(); // history /* ******* Filters ******* */ filters->save(set); set->sync(); } void Preferences::load() { //qDebug("Preferences::load"); QSettings * set = settings; /* ******* General ******* */ set->beginGroup("General"); // config_version = set->value("config_version", 0).toInt(); mplayer_bin = set->value("mplayer_bin", mplayer_bin).toString(); //edited by kobe 20180623 if (mplayer_bin.isEmpty()) { mplayer_bin = "/usr/bin/mpv";//mplayer_bin = QString("%1/mpv").arg(Paths::appPath()); } vo = set->value("driver/vo", vo).toString(); ao = set->value("driver/audio_output", ao).toString(); use_screenshot = set->value("use_screenshot", use_screenshot).toBool(); screenshot_template = set->value("screenshot_template", screenshot_template).toString(); if (screenshot_template.isEmpty()) screenshot_template = "cap_%F_%p_%02n"; screenshot_format = set->value("screenshot_format", screenshot_format).toString(); if (screenshot_format.isEmpty()) screenshot_format = "jpg"; #if QT_VERSION >= 0x040400 screenshot_directory = set->value("screenshot_folder", screenshot_directory).toString(); setupScreenshotFolder(); #else screenshot_directory = set->value("screenshot_directory", screenshot_directory).toString(); #endif // remember_media_settings = set->value("remember_media_settings", remember_media_settings).toBool(); // remember_time_pos = set->value("remember_time_pos", remember_time_pos).toBool(); // remember_stream_settings = set->value("remember_stream_settings", remember_stream_settings).toBool(); // alang = set->value("alang", alang).toString(); // slang = set->value("slang", slang).toString(); use_direct_rendering = set->value("use_direct_rendering", use_direct_rendering).toBool(); use_double_buffer = set->value("use_double_buffer", use_double_buffer).toBool(); use_soft_video_eq = set->value("use_soft_video_eq", use_soft_video_eq).toBool(); use_slices = set->value("use_slices", use_slices ).toBool(); // autoq = set->value("autoq", autoq).toInt(); // disable_screensaver = set->value("disable_screensaver", disable_screensaver).toBool(); // add_blackborders_on_fullscreen = set->value("add_blackborders_on_fullscreen", add_blackborders_on_fullscreen).toBool(); // vdpau.ffh264vdpau = set->value("vdpau_ffh264vdpau", vdpau.ffh264vdpau).toBool(); // vdpau.ffmpeg12vdpau = set->value("vdpau_ffmpeg12vdpau", vdpau.ffmpeg12vdpau).toBool(); // vdpau.ffwmv3vdpau = set->value("vdpau_ffwmv3vdpau", vdpau.ffwmv3vdpau).toBool(); // vdpau.ffvc1vdpau = set->value("vdpau_ffvc1vdpau", vdpau.ffvc1vdpau).toBool(); // vdpau.ffodivxvdpau = set->value("vdpau_ffodivxvdpau", vdpau.ffodivxvdpau).toBool(); // vdpau.ffhevcvdpau = set->value("vdpau_ffhevcvdpau", vdpau.ffhevcvdpau).toBool(); // vdpau.disable_video_filters = set->value("vdpau_disable_video_filters", vdpau.disable_video_filters).toBool(); use_soft_vol = set->value("use_soft_vol", use_soft_vol).toBool(); softvol_max = set->value("softvol_max", softvol_max).toInt(); use_scaletempo = (OptionState) set->value("use_scaletempo", use_scaletempo).toInt(); use_hwac3 = set->value("use_hwac3", use_hwac3 ).toBool(); // use_audio_equalizer = set->value("use_audio_equalizer", use_audio_equalizer ).toBool(); use_audio_equalizer = true; global_volume = set->value("global_volume", global_volume).toBool(); volume = set->value("volume", volume).toInt(); mute = set->value("mute", mute).toBool(); global_audio_equalizer = set->value("global_audio_equalizer", global_audio_equalizer).toBool(); audio_equalizer = set->value("audio_equalizer", audio_equalizer).toList(); autosync = set->value("autosync", autosync).toBool(); autosync_factor = set->value("autosync_factor", autosync_factor).toInt(); // use_mc = set->value("use_mc", use_mc).toBool(); // mc_value = set->value("mc_value", mc_value).toDouble(); // autoload_m4a = set->value("autoload_m4a", autoload_m4a).toBool(); min_step = set->value("min_step", min_step).toInt(); osd = set->value("osd", osd).toInt(); //osd = 0;//kobe:选项->屏幕显示->仅字幕,该版本会屏蔽“屏幕显示”菜单,全部默认为仅字幕,即配置文件~/.config/smplayer/smplayer.ini的osd字段不管是多少,定制版播放器启动后都重新设置该值为0(仅字幕) osd_scale = set->value("osd_scale", osd_scale).toDouble(); subfont_osd_scale = set->value("subfont_osd_scale", subfont_osd_scale).toDouble(); osd_delay = set->value("osd_delay", osd_delay).toInt(); //#ifdef MPV_SUPPORT osd_fractions = set->value("osd_fractions", osd_fractions).toBool(); //#endif osd_bar_pos = set->value("osd_bar_pos", osd_bar_pos).toInt(); osd_show_filename_duration = set->value("osd_show_filename_duration", osd_show_filename_duration).toInt(); // file_settings_method = set->value("file_settings_method", file_settings_method).toString(); // tablet_mode = set->value("tablet_mode", tablet_mode).toBool(); set->endGroup(); // General /* *************** Drives (CD/DVD) *************** */ /* set->beginGroup( "drives"); dvd_device = set->value("dvd_device", dvd_device).toString(); cdrom_device = set->value("cdrom_device", cdrom_device).toString(); //#ifdef BLURAY_SUPPORT // bluray_device = set->value("bluray_device", bluray_device).toString(); //#endif vcd_initial_title = set->value("vcd_initial_title", vcd_initial_title ).toInt(); //#if DVDNAV_SUPPORT // use_dvdnav = set->value("use_dvdnav", use_dvdnav).toBool(); //#endif set->endGroup(); // drives */ /* *********** Performance *********** */ set->beginGroup( "performance"); // frame_drop = set->value("frame_drop", frame_drop).toBool(); // hard_frame_drop = set->value("hard_frame_drop", hard_frame_drop).toBool(); // coreavc = set->value("coreavc", coreavc).toBool(); // h264_skip_loop_filter = (H264LoopFilter) set->value("h264_skip_loop_filter", h264_skip_loop_filter).toInt(); HD_height = set->value("HD_height", HD_height).toInt(); threads = set->value("threads", threads).toInt(); hwdec = set->value("hwdec", hwdec).toString(); // cache_auto = set->value("cache_auto", cache_auto).toBool(); cache_for_files = set->value("cache_for_files", cache_for_files).toInt(); cache_for_streams = set->value("cache_for_streams", cache_for_streams).toInt(); // cache_for_dvds = set->value("cache_for_dvds", cache_for_dvds).toInt(); // cache_for_vcds = set->value("cache_for_vcds", cache_for_vcds).toInt(); // cache_for_audiocds = set->value("cache_for_audiocds", cache_for_audiocds).toInt(); set->endGroup(); // performance /* ********* Subtitles ********* */ set->beginGroup("subtitles"); subcp = set->value("subcp", subcp).toString(); if (subcp.isEmpty()) subcp = "UTF-8";//ISO-8859-1";//kobe use_enca = set->value("use_enca", use_enca).toBool(); enca_lang = set->value("enca_lang", enca_lang).toString(); if (enca_lang.isEmpty()) enca_lang = "zh";//kobe // subfuzziness = set->value("subfuzziness", subfuzziness).toInt(); // autoload_sub = set->value("autoload_sub", autoload_sub).toBool(); // use_ass_subtitles = set->value("use_ass_subtitles", use_ass_subtitles).toBool(); // enable_ass_styles = set->value("enable_ass_styles", enable_ass_styles).toBool(); // ass_line_spacing = set->value("ass_line_spacing", ass_line_spacing).toInt(); // use_forced_subs_only = set->value("use_forced_subs_only", use_forced_subs_only).toBool(); sub_visibility = set->value("sub_visibility", sub_visibility).toBool(); // subtitles_on_screenshots = set->value("subtitles_on_screenshots", subtitles_on_screenshots).toBool(); // change_sub_scale_should_restart = (OptionState) set->value("change_sub_scale_should_restart", change_sub_scale_should_restart).toInt(); // fast_load_sub = set->value("fast_load_sub", fast_load_sub).toBool(); // // ASS styles // ass_styles.load(set); // force_ass_styles = set->value("force_ass_styles", force_ass_styles).toBool(); // user_forced_ass_style = set->value("user_forced_ass_style", user_forced_ass_style).toString(); // freetype_support = set->value("freetype_support", freetype_support).toBool(); set->endGroup(); // subtitles /* ******** Advanced ******** */ set->beginGroup( "advanced"); // use_mplayer_window = set->value("use_mplayer_window", use_mplayer_window).toBool(); use_idx = set->value("use_idx", use_idx).toBool(); use_lavf_demuxer = set->value("use_lavf_demuxer", use_lavf_demuxer).toBool(); // mplayer_additional_options = set->value("mplayer_additional_options", mplayer_additional_options).toString(); // mplayer_additional_video_filters = set->value("mplayer_additional_video_filters", mplayer_additional_video_filters).toString(); // mplayer_additional_audio_filters = set->value("mplayer_additional_audio_filters", mplayer_additional_audio_filters).toString(); // verbose_log = set->value("verbose_log", verbose_log).toBool(); // repaint_video_background = set->value("repaint_video_background", repaint_video_background).toBool(); use_edl_files = set->value("use_edl_files", use_edl_files).toBool(); //#ifdef MPLAYER_SUPPORT use_playlist_option = set->value("use_playlist_option", use_playlist_option).toBool(); //#endif // prefer_ipv4 = set->value("prefer_ipv4", prefer_ipv4).toBool(); use_short_pathnames = set->value("use_short_pathnames", use_short_pathnames).toBool(); // use_pausing_keep_force = set->value("use_pausing_keep_force", use_pausing_keep_force).toBool(); // use_correct_pts = (OptionState) set->value("correct_pts", use_correct_pts).toInt(); actions_to_run = set->value("actions_to_run", actions_to_run).toString(); show_tag_in_window_title = set->value("show_tag_in_window_title", show_tag_in_window_title).toBool(); time_to_kill_mplayer = set->value("time_to_kill_player", time_to_kill_mplayer).toInt(); //#ifdef MPV_SUPPORT mpv_osd_media_info = set->value("mpv_osd_media_info", mpv_osd_media_info).toString(); //#endif //#ifdef MPLAYER_SUPPORT mplayer_osd_media_info = set->value("mplayer_osd_media_info", mplayer_osd_media_info).toString(); //#endif ////#ifdef MPV_SUPPORT // emulate_mplayer_ab_section = set->value("emulate_mplayer_ab_section", emulate_mplayer_ab_section).toBool(); ////#endif // use_native_open_dialog = set->value("use_native_open_dialog", use_native_open_dialog).toBool(); set->endGroup(); // advanced /* ********* GUI stuff ********* */ set->beginGroup("gui"); fullscreen = set->value("fullscreen", fullscreen).toBool(); // start_in_fullscreen = set->value("start_in_fullscreen", start_in_fullscreen).toBool(); // compact_mode = set->value("compact_mode", compact_mode).toBool(); stay_on_top = (Preferences::OnTop) set->value("stay_on_top", (int) stay_on_top).toInt(); // size_factor = set->value("size_factor", size_factor).toInt(); // resize_method = set->value("resize_method", resize_method).toInt(); // center_window = set->value("center_window", center_window).toBool(); // center_window_if_outside = set->value("center_window_if_outside", center_window_if_outside).toBool(); // use_global_shortcuts = set->value("use_global_shortcuts", use_global_shortcuts).toBool(); // global_shortcuts_grabbed_keys = set->value("global_shortcuts_grabbed_keys", global_shortcuts_grabbed_keys).toInt(); // mouse_left_click_function = set->value("mouse_left_click_function", mouse_left_click_function).toString(); // mouse_right_click_function = set->value("mouse_right_click_function", mouse_right_click_function).toString(); // mouse_double_click_function = set->value("mouse_double_click_function", mouse_double_click_function).toString(); // mouse_middle_click_function = set->value("mouse_middle_click_function", mouse_middle_click_function).toString(); // mouse_xbutton1_click_function = set->value("mouse_xbutton1_click_function", mouse_xbutton1_click_function).toString(); // mouse_xbutton2_click_function = set->value("mouse_xbutton2_click_function", mouse_xbutton2_click_function).toString(); wheel_function = set->value("mouse_wheel_function", wheel_function).toInt(); { int wheel_function_cycle_int = set->value("wheel_function_cycle", (int) wheel_function_cycle).toInt(); wheel_function_cycle = (WheelFunctions) wheel_function_cycle_int; } wheel_function_seeking_reverse = set->value("wheel_function_seeking_reverse", wheel_function_seeking_reverse).toBool(); // drag_function = set->value("drag_function", drag_function).toInt(); seeking1 = set->value("seeking1", seeking1).toInt(); seeking2 = set->value("seeking2", seeking2).toInt(); seeking3 = set->value("seeking3", seeking3).toInt(); seeking4 = set->value("seeking4", seeking4).toInt(); // update_while_seeking = set->value("update_while_seeking", update_while_seeking).toBool(); //#if ENABLE_DELAYED_DRAGGING time_slider_drag_delay = set->value("time_slider_drag_delay", time_slider_drag_delay).toInt(); //#endif // relative_seeking = set->value("relative_seeking", relative_seeking).toBool(); // precise_seeking = set->value("precise_seeking", precise_seeking).toBool(); // reset_stop = set->value("reset_stop", reset_stop).toBool(); // delay_left_click = set->value("delay_left_click", delay_left_click).toBool(); // language = set->value("language", language).toString(); // iconset= set->value("iconset", iconset).toString(); // balloon_count = set->value("balloon_count", balloon_count).toInt(); // restore_pos_after_fullscreen = set->value("restore_pos_after_fullscreen", restore_pos_after_fullscreen).toBool(); // save_window_size_on_exit = set->value("save_window_size_on_exit", save_window_size_on_exit).toBool(); // close_on_finish = set->value("close_on_finish", close_on_finish).toBool(); // default_font = set->value("default_font", default_font).toString(); pause_when_hidden = set->value("pause_when_hidden", pause_when_hidden).toBool(); // allow_video_movement = set->value("allow_video_movement", allow_video_movement).toBool(); // gui = set->value("gui", gui).toString(); // gui_minimum_width = set->value("gui_minimum_width", gui_minimum_width).toInt(); // default_size = set->value("default_size", default_size).toSize(); // report_mplayer_crashes = set->value("report_player_crashes", report_mplayer_crashes).toBool(); reported_mplayer_is_old = set->value("reported_mplayer_is_old", reported_mplayer_is_old).toBool(); // auto_add_to_playlist = set->value("auto_add_to_playlist", auto_add_to_playlist).toBool(); media_to_add_to_playlist = (AutoAddToPlaylistFilter) set->value("media_to_add_to_playlist", media_to_add_to_playlist).toInt(); preview_when_playing = set->value("preview_when_playing", preview_when_playing).toBool(); if (!preview_when_playing) { preview_when_playing = true; } // playlist_key = set->value("playlist_key", playlist_key).toString(); // next_key = set->value("next_key", next_key).toString(); // prev_key = set->value("prev_key", prev_key).toString(); set->endGroup(); // gui /* *********** Directories *********** */ set->beginGroup( "directories"); // save_dirs = set->value("save_dirs", save_dirs).toBool(); // if (save_dirs) { // latest_dir = set->value("latest_dir", latest_dir).toString(); // last_dvd_directory = set->value("last_dvd_directory", last_dvd_directory).toString(); // } latest_dir = set->value("latest_dir", latest_dir).toString(); set->endGroup(); // directories /* ************** Initial values ************** */ set->beginGroup( "defaults"); initial_sub_scale = set->value("initial_sub_scale", initial_sub_scale).toDouble(); initial_sub_scale_ass = set->value("initial_sub_scale_ass", initial_sub_scale_ass).toDouble(); initial_volume = set->value("initial_volume", initial_volume).toInt(); initial_contrast = set->value("initial_contrast", initial_contrast).toInt(); initial_brightness = set->value("initial_brightness", initial_brightness).toInt(); initial_hue = set->value("initial_hue", initial_hue).toInt(); initial_saturation = set->value("initial_saturation", initial_saturation).toInt(); initial_gamma = set->value("initial_gamma", initial_gamma).toInt(); initial_audio_equalizer = set->value("initial_audio_equalizer", initial_audio_equalizer).toList(); initial_zoom_factor = set->value("initial_zoom_factor", initial_zoom_factor).toDouble(); initial_sub_pos = set->value("initial_sub_pos", initial_sub_pos).toInt(); initial_volnorm = set->value("initial_volnorm", initial_volnorm).toBool(); //#ifdef INITIAL_BLACKBORDERS initial_blackborders = set->value("initial_blackborders", initial_blackborders).toBool(); //#endif initial_postprocessing = set->value("initial_postprocessing", initial_postprocessing).toBool(); initial_deinterlace = set->value("initial_deinterlace", initial_deinterlace).toInt(); initial_audio_channels = set->value("audio_channels", initial_audio_channels).toInt(); initial_stereo_mode = set->value("initial_stereo_mode", initial_stereo_mode).toInt(); initial_audio_track = set->value("preferred_audio_track", initial_audio_track).toInt(); initial_subtitle_track = set->value("preferred_subtitle_track", initial_subtitle_track).toInt(); set->endGroup(); // defaults /* ************ MPlayer info ************ */ set->beginGroup( "mplayer_info"); mplayer_detected_version = set->value("mplayer_detected_version", mplayer_detected_version).toInt(); mplayer_user_supplied_version = set->value("mplayer_user_supplied_version", mplayer_user_supplied_version).toInt(); set->endGroup(); // mplayer_info /* ******* History ******* */ set->beginGroup("history"); history_recents->setMaxItems( set->value("recents/max_items", history_recents->maxItems()).toInt() ); history_recents->fromStringList( set->value("recents", history_recents->toStringList()).toStringList() ); history_urls->setMaxItems( set->value("urls/max_items", history_urls->maxItems()).toInt() ); history_urls->fromStringList( set->value("urls", history_urls->toStringList()).toStringList() ); set->endGroup(); // history /* ******* Filters ******* */ filters->load(set); //lixiang reset vo and hwdec for arm64 (only mpv support hwdec) //20191206 if (arch_type == "aarch64") { if (m_decoingType == AmdVdpau) { vo = "vdpau"; hwdec = "vdpau"; } else if (m_decoingType == Jm7200Xv || m_decoingType == Sm768Xv) { vo = "xv"; hwdec = "no"; } else if (m_decoingType == Gp101X11) { vo = "x11"; hwdec = "no"; } else { vo = "xv"; hwdec = "no"; } } //edited by kobe 20180623 /*if (!QFile::exists(mplayer_bin)) { QString app_path = Utils::findExecutable(mplayer_bin); //qDebug("Preferences::load: app_path: %s", app_path.toUtf8().constData()); if (!app_path.isEmpty()) { mplayer_bin = app_path; } else { // Executable not found, try to find an alternative if (mplayer_bin.startsWith("mplayer")) { app_path = Utils::findExecutable("mpv"); if (!app_path.isEmpty()) mplayer_bin = app_path; } else if (mplayer_bin.startsWith("mpv")) { app_path = Utils::findExecutable("mplayer"); if (!app_path.isEmpty()) mplayer_bin = app_path; } } }*/ } void Preferences::setupScreenshotFolder() { #if QT_VERSION >= 0x040400 if (screenshot_directory.isEmpty()) { #if QT_VERSION >= 0x050000 QString pdir = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); if (pdir.isEmpty()) pdir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); if (pdir.isEmpty()) pdir = QStandardPaths::writableLocation(QStandardPaths::HomeLocation); #else QString pdir = QDesktopServices::storageLocation(QDesktopServices::PicturesLocation); if (pdir.isEmpty()) pdir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation); if (pdir.isEmpty()) pdir = QDesktopServices::storageLocation(QDesktopServices::HomeLocation); #endif if (pdir.isEmpty()) pdir = "/tmp"; if (!QFile::exists(pdir)) { qWarning("Preferences::setupScreenshotFolder: folder '%s' does not exist. Using /tmp as fallback", pdir.toUtf8().constData()); pdir = "/tmp"; } QString default_screenshot_path = QDir::toNativeSeparators(pdir + "/kylin_video_screenshots"); if (!QFile::exists(default_screenshot_path)) { qDebug("Preferences::setupScreenshotFolder: creating '%s'", default_screenshot_path.toUtf8().constData()); if (!QDir().mkdir(default_screenshot_path)) { qWarning("Preferences::setupScreenshotFolder: failed to create '%s'", default_screenshot_path.toUtf8().constData()); } } if (QFile::exists(default_screenshot_path)) { screenshot_directory = default_screenshot_path; } qDebug() << "setup default_screenshot_path=" << default_screenshot_path; } else { screenshot_directory = QDir::toNativeSeparators(screenshot_directory); if (!QFile::exists(screenshot_directory)) { if (!QDir().mkdir(screenshot_directory)) { qWarning("Preferences::setupScreenshotFolder: failed to create '%s'", screenshot_directory.toUtf8().constData()); } } } #endif } void Preferences::updatePredefinedList() { //# 对于PCIe设备的预处理 //# 格式:"VID:PID:ClassID:预设分数:描述信息" //# 一行一条规则 //# VID、PID中,-1或者0xFFFF代表匹配所有 //# ClassID中,-1或者0xFFFFFF代表匹配所有 //# 例如:"0x8086:0x1901:0x0:0:Intel PCIe Controller (x16)" QStringList itemList; itemList.append("0731:7200:-1:0:JINGJIA MICRO JM7200 Graphics Card"); itemList.append("126f:-1:-1:0:SM750/SM768"); itemList.append("1a03:-1:-1:0:BMCd"); itemList.append("1002:-1:-1:300:AMD Graphics Card"); itemList.append("0709:0001:-1:0:709 GP101 Graphics Card"); foreach (QString item, itemList) { item = item.trimmed(); if (item.startsWith("#")) continue; if (item.startsWith("//")) continue; PciePredefined device; QStringList stringList = item.split(":"); bool ok; if (stringList.count() < 5) continue; device.vid = stringList[0].toInt(&ok, 16); if (device.vid == -1) device.vid = 0xFFFF; stringList.removeAt(0); device.pid = stringList[0].toInt(&ok, 16); if (device.pid == -1) device.pid = 0xFFFF; stringList.removeAt(0); device.cid = stringList[0].toInt(&ok, 16); if (device.cid == -1) device.cid = 0xFFFFFF; stringList.removeAt(0); device.score = stringList[0].toInt(&ok, 10); stringList.removeAt(0); device.description = stringList.join(":").trimmed(); predefinedList.append(device); } } void Preferences::updatePcieList() { QDir dir("/sys/bus/pci/devices/"); if (!dir.exists()) return; dir.setFilter(QDir::Dirs); QStringList busList = dir.entryList(); busList.removeOne("."); busList.removeOne(".."); foreach(QString bus, busList) { PcieInfo info; QString path; QFile file; QByteArray charArray; bool ok; int id; path = dir.absoluteFilePath(bus + "/" + "vendor"); file.setFileName(path); file.open(QIODevice::ReadOnly | QIODevice::Text); charArray = file.readAll(); file.close(); id = QString(charArray).toInt(&ok, 16); info.vid = id; path = dir.absoluteFilePath(bus + "/" + "device"); file.setFileName(path); file.open(QIODevice::ReadOnly | QIODevice::Text); charArray = file.readAll(); file.close(); id = QString(charArray).toInt(&ok, 16); info.pid = id; path = dir.absoluteFilePath(bus + "/" + "class"); file.setFileName(path); file.open(QIODevice::ReadOnly | QIODevice::Text); charArray = file.readAll(); file.close(); id = QString(charArray).toInt(&ok, 16); info.cid = id; pcieList.append(info); //qDebug() << path + QString(": 0x%1, 0x%2, 0x%3").arg(info.vid, 4, 16).arg(info.pid, 4, 16, QChar('0')).arg(info.cid, 4, 16); } // foreach(PcieInfo info, pcieList) { // qDebug() << QString(": 0x%1, 0x%2, 0x%3").arg(info.vid, 4, 16).arg(info.pid, 4, 16, QChar('0')).arg(info.cid, 4, 16); // } } Preferences::HardDecodingType Preferences::getHardwareDecodingType() { //默认值为-1,表示使用软解 HardDecodingType type = DefaultSoftDecoding; updatePredefinedList(); int size = predefinedList.size(); if (size > 0) { updatePcieList(); foreach (PciePredefined predefined, predefinedList) { foreach(PcieInfo info, pcieList) { if ( ((predefined.vid == info.vid) || (predefined.vid == 0xFFFF)) && ((predefined.pid == info.pid) || (predefined.pid == 0xFFFF)) && ((predefined.cid == info.cid) || (predefined.cid == 0xFFFFFF))) { printf("Find %s device(%04x:%04x.%04x), " "use predefine score: %d\n", predefined.description.toUtf8().data(), predefined.vid, predefined.pid, predefined.cid, predefined.score); char vidstr[128] = {0}; snprintf(vidstr, sizeof(vidstr), "%04x", predefined.vid); //printf("vidstr:%s\n", vidstr); QString vid = QString::fromStdString(std::string(vidstr)); //qDebug() << "vid:" << vid; //Find AMD Graphics Card device(1002:ffff.ffffff), use predefine score: 300 if (predefined.description == "AMD Graphics Card" && vid == "1002") { type = AmdVdpau; } else if (predefined.description == "JINGJIA MICRO JM7200 Graphics Card" && vid == "0731") { type = Jm7200Xv; } else if (predefined.description == "709 GP101 Graphics Card" && vid == "0709") { type = Gp101X11; } else if (predefined.description == "SM750/SM768" && vid == "126f") { type = Sm768Xv; } return type; } } } } return type; } kylin-video/src/smplayer/prefscreenshot.h0000644000175000017500000000356113517016402017562 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _PREFSCREENSHOT_H_ #define _PREFSCREENSHOT_H_ #include "ui_prefscreenshot.h" #include "../smplayer/prefwidget.h" #include "../smplayer/inforeader.h" #include "../smplayer/deviceinfo.h" #include "../smplayer/preferences.h" class PrefScreenShot : public PrefWidget, public Ui::PrefScreenShot { Q_OBJECT public: PrefScreenShot( QWidget * parent = 0, Qt::WindowFlags f = 0 ); ~PrefScreenShot(); // Pass data to the dialog void setData(Preferences * pref); // Apply changes void getData(Preferences * pref); bool fileSettingsMethodChanged() { return filesettings_method_changed; }; protected: virtual void createHelp(); void setUseScreenshots(bool b); bool useScreenshots(); void setScreenshotDir( QString path ); QString screenshotDir(); void setScreenshotFormat(const QString format); QString screenshotFormat(); protected: virtual void retranslateStrings(); private: bool filesettings_method_changed; }; #endif kylin-video/src/smplayer/myaction.h0000644000175000017500000000364513517016402016356 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYACTION_H_ #define _MYACTION_H_ #include #include #include #include class MyAction : public QAction { public: //! Creates a new MyAction with name \a name. If \a autoadd is true //! the action will be added to the parent MyAction ( QObject * parent, const char * name, bool autoadd = true ); //! Creates a new MyAction. If \a autoadd is true //! the action will be added to the parent MyAction ( QObject * parent, bool autoadd = true ); MyAction ( const QString & text, QKeySequence accel, QObject * parent, const char * name = "", bool autoadd = true ); MyAction ( QKeySequence accel, QObject * parent, const char * name = "", bool autoadd = true ); ~MyAction(); void addShortcut(QKeySequence key); //! Change the icon and text of the action. void change(const QIcon & icon, const QString & text ); //! Change the text of the action. void change(const QString & text); protected: //! Checks if the parent is a QWidget and adds the action to it. void addActionToParent(); }; #endif kylin-video/src/smplayer/mycombobox.h0000644000175000017500000000271613517016402016707 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYCOMBOBOX_H_ #define _MYCOMBOBOX_H_ #include #include //! This class adds some Qt 3 compatibility functions which don't have a //! direct equivalent in Qt 4. class MyComboBox : public QComboBox { public: MyComboBox( QWidget * parent = 0 ); ~MyComboBox(); void setCurrentText ( const QString & text ); void insertStringList ( const QStringList & list, int index = -1 ); }; class MyFontComboBox : public QFontComboBox { public: MyFontComboBox( QWidget * parent = 0 ); ~MyFontComboBox(); void setCurrentText ( const QString & text ); void setFontsFromDir(const QString & fontdir); }; #endif kylin-video/src/smplayer/tristatecombo.h0000644000175000017500000000255113517016402017405 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /*! This class is to replace some QCheckBox with a combo with three possible values: true, false or autodetect */ #ifndef _TRISTATE_COMBO_H_ #define _TRISTATE_COMBO_H_ #include #include "../smplayer/preferences.h" class TristateCombo : public QComboBox { Q_OBJECT public: TristateCombo( QWidget * parent = 0 ); ~TristateCombo(); void setState( Preferences::OptionState v ); Preferences::OptionState state(); protected: virtual void retranslateStrings(); virtual void changeEvent( QEvent * event ); }; #endif kylin-video/src/smplayer/mediadata.h0000644000175000017500000000471713517016402016445 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MEDIADATA_H_ #define _MEDIADATA_H_ /* Here we store some volatile info about the file we need to remember */ #include "tracks.h" #include "subtracks.h" #include "titletracks.h" #include "chapters.h" #include #include // Types of media #define TYPE_UNKNOWN -1 #define TYPE_FILE 0 #define TYPE_DVD 1 #define TYPE_STREAM 2 #define TYPE_VCD 3 #define TYPE_AUDIO_CD 4 #define TYPE_TV 5 //#ifdef BLURAY_SUPPORT //#define TYPE_BLURAY 6 //#endif class MediaData { public: MediaData(); virtual ~MediaData(); virtual void reset(); QString m_filename; double duration; QStringList extra_params; // For streams //Resolution of the video int video_width; int video_height; double video_aspect; int type; // file, dvd... QString dvd_id; bool novideo; // Only audio bool initialized; void list(); // Tracks videos; // Tracks audios; // SubTracks subs; TitleTracks titles; // for DVDs Chapters chapters; int n_chapters; // Clip info QString clip_name; QString clip_artist; QString clip_author; QString clip_album; QString clip_genre; QString clip_date; QString clip_track; QString clip_copyright; QString clip_comment; QString clip_software; QString stream_title; QString stream_url; QString stream_path; // From mpv // Other data not really useful for us, // just to show info to the user. QString demuxer; QString video_format; QString audio_format; int video_bitrate; QString video_fps; int audio_bitrate; int audio_rate; int audio_nch; // channels? QString video_codec; QString audio_codec; /*QString info();*/ QString displayName(bool show_tag = true); }; #endif kylin-video/src/smplayer/filesettings.h0000644000175000017500000000261513517016402017227 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2018 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef FILESETTINGS_H #define FILESETTINGS_H #include "filesettingsbase.h" class QSettings; class FileSettings : public FileSettingsBase { public: FileSettings(QString directory); virtual ~FileSettings(); virtual bool existSettingsFor(QString filename, int type); virtual void loadSettingsFor(QString filename, int type, MediaSettings & mset, int player); virtual void saveSettingsFor(QString filename, int type, MediaSettings & mset, int player); static QString filenameToGroupname(const QString & filename, int type); private: QSettings * my_settings; }; #endif kylin-video/src/smplayer/prefsubtitles.ui0000644000175000017500000001253113517016402017606 0ustar fengfeng PrefSubtitles 0 0 470 360 10 20 448 91 Autoload 9 9 9 9 6 Qt::Horizontal QSizePolicy::Expanding 131 21 Autoload subtitles files (*.srt, *.sub...): false font_autoload_combo Same name as movie All subs containing movie name All subs in directory 10 120 448 104 Encoding 6 0 0 0 0 Default subtitle encoding: false font_encoding_combo 0 0 false Qt::Horizontal QSizePolicy::Expanding 161 31 0 Try to autodetect for this language: false 0 0 Qt::Horizontal 40 20 kylin-video/src/smplayer/videopreview.h0000644000175000017500000000665613625147453017263 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _VIDEOPREVIEW_H_ #define _VIDEOPREVIEW_H_ #include #include #include class VideoInfo { public: VideoInfo() { filename.clear(); width = 0; height = 0; length = 0; size = 0; fps = 0; aspect = 0; video_bitrate = 0; audio_bitrate = 0; audio_rate = 0; video_format.clear(); }; ~VideoInfo() {}; QString filename; int width; int height; int length; qint64 size; double fps; double aspect; int video_bitrate; int audio_bitrate; int audio_rate; QString video_format; QString audio_format; }; class VideoPreview : public QObject { Q_OBJECT public: enum ExtractFormat { JPEG = 1, PNG = 2 }; VideoPreview(QString mplayer_path, QObject *parent = 0); ~VideoPreview(); void setMplayerPath(QString mplayer_path); QString mplayerPath() { return mplayer_bin; }; void setVideoFile(QString file) { prop.input_video = file; }; QString videoFile() { return prop.input_video; }; void setDVDDevice(const QString & dvd_device) { prop.dvd_device = dvd_device; }; QString DVDDevice() { return prop.dvd_device; }; void setInitialStep(int step) { prop.initial_step = step; }; int initialStep() { return prop.initial_step; }; void setMaxWidth(int w) { prop.max_width = w; }; int maxWidth() { return prop.max_width; }; void setDisplayOSD(bool b) { prop.display_osd = b; }; bool displayOSD() { return prop.display_osd; }; void setAspectRatio(double asp) { prop.aspect_ratio = asp; }; double aspectRatio() { return prop.aspect_ratio; }; void setExtractFormat( ExtractFormat format ) { prop.extract_format = format; }; ExtractFormat extractFormat() { return prop.extract_format; }; bool createPreThumbnail(int seek); VideoInfo getInfo(const QString & mplayer_path, const QString & filename); QString errorMessage() { return error_message; }; QString getCurrentPicture() { return current_picture;}; protected: bool extractImages(int seek); bool runPlayer(int seek, double aspect_ratio); // void displayVideoInfo(const VideoInfo & i); void cleanDir(QString directory/*, bool removeDir=false*/); QString framePicture(); //#if defined(Q_OS_LINUX) && !defined(NO_SMPLAYER_SUPPORT) bool isOptionAvailableinMPV(const QString & option); //#endif QString mplayer_bin; QString output_dir; QString full_output_dir; struct Properties { QString input_video; QString dvd_device; int initial_step, max_width; double aspect_ratio; bool display_osd; ExtractFormat extract_format; } prop; QString last_directory; bool save_last_directory; QString error_message; QString current_picture; }; #endif kylin-video/src/smplayer/mplayerprocess.h0000644000175000017500000001175713517016402017606 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MPLAYERPROCESS_H_ #define _MPLAYERPROCESS_H_ #include #include "playerprocess.h" #include "mediadata.h" class QStringList; class MplayerProcess : public PlayerProcess { Q_OBJECT public: MplayerProcess(QObject * parent = 0); ~MplayerProcess(); bool start(); // Command line options void setMedia(const QString & media, bool is_playlist = false); void setFixedOptions(); void disableInput(); void setOption(const QString & option_name, const QVariant & value = QVariant()); void addUserOption(const QString & option); void addVF(const QString & filter_name, const QVariant & value = QVariant()); void addAF(const QString & filter_name, const QVariant & value = QVariant()); void addStereo3DFilter(const QString & in, const QString & out); void setSubStyles(const AssStyles & styles, const QString & assStylesFile = QString::null); void setSubEncoding(const QString & codepage, const QString & enca_lang); void setVideoEqualizerOptions(int contrast, int brightness, int hue, int saturation, int gamma, bool soft_eq); // Slave commands void quit(); void setVolume(int v); void setOSD(int o); void setAudio(int ID); void setVideo(int ID); void setSubtitle(int type, int ID); void disableSubtitles(); void setSecondarySubtitle(int /*ID*/) {}; void disableSecondarySubtitles() {}; void setSubtitlesVisibility(bool b); void seek(double secs, int mode, bool precise); void mute(bool b); void setPause(bool b); void frameStep(); void frameBackStep(); void showOSDText(const QString & text, int duration, int level); void showFilenameOnOSD(int duration = 2000); void showMediaInfoOnOSD(); void showTimeOnOSD(); void setContrast(int value); void setBrightness(int value); void setHue(int value); void setSaturation(int value); void setGamma(int value); void setChapter(int ID); void nextChapter(); void previousChapter(); void setExternalSubtitleFile(const QString & filename); void setSubPos(int pos); void setSubScale(double value); void setSubStep(int value); //#ifdef MPV_SUPPORT void seekSub(int value); //#endif void setSubForcedOnly(bool b); void setSpeed(double value); void enableKaraoke(bool b); void enableExtrastereo(bool b); void enableVolnorm(bool b, const QString & option); //#ifdef MPV_SUPPORT void enableEarwax(bool /*b*/) {}; //#endif // void setAudioEqualizer(const QString & values); void setAudioEqualizer(AudioEqualizerList); void setAudioDelay(double delay); void setSubDelay(double delay); void setLoop(int v); void setAMarker(int sec); void setBMarker(int sec); void clearABMarkers(); void takeScreenshot(ScreenshotType t, bool include_subtitles = false); //#ifdef CAPTURE_STREAM // void switchCapturing(); //#endif void setTitle(int ID); void changeVF(const QString & filter, bool enable, const QVariant & option = QVariant()); void changeAF(const QString & filter, bool enable, const QVariant & option = QVariant()); void changeStereo3DFilter(bool enable, const QString & in, const QString & out); //#if DVDNAV_SUPPORT // void discSetMousePos(int x, int y); // void discButtonPressed(const QString & button_name); //#endif void setAspect(double aspect); void setFullscreen(bool b); void toggleDeinterlace(); void askForLength(); void setOSDScale(double value); void setOSDFractions(bool) {}; void setChannelsFile(const QString &) {}; void enableScreenshots(const QString & dir, const QString & templ = QString::null, const QString & format = QString::null); //#ifdef CAPTURE_STREAM // void setCaptureDirectory(const QString & dir); //#endif void enableOSDInCommands(bool) {}; bool isOSDInCommandsEnabled() { return true; }; protected slots: void parseLine(QByteArray ba); void processFinished(int exitCode, QProcess::ExitStatus exitStatus); void gotError(QProcess::ProcessError); protected: virtual void initializeOptionVars(); private: bool notified_mplayer_is_running; bool received_end_of_file; int last_sub_id; int mplayer_svn; SubTracks subs; bool subtitle_info_received; bool subtitle_info_changed; Tracks audios; bool audio_info_changed; Tracks videos; bool video_info_changed; int dvd_current_title; int br_current_title; }; #endif kylin-video/src/smplayer/cleanconfig.h0000644000175000017500000000035413517016402016775 0ustar fengfeng #ifndef CLEANCONFIG_H #define CLEANCONFIG_H #include #include class CleanConfig { public: static void clean(const QString &config_path); private: static QStringList listDir(const QString &path); }; #endif kylin-video/src/smplayer/filesettingshash.cpp0000644000175000017500000000714713517016402020433 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2018 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "filesettingshash.h" #include "mediasettings.h" #include "mediadata.h" #include "filehash.h" // hash function #include #include #include #include FileSettingsHash::FileSettingsHash(QString directory) : FileSettingsBase(directory) { base_dir = directory + "/file_settings"; } FileSettingsHash::~FileSettingsHash() { } QString FileSettingsHash::configFile(const QString & filename, int type, QString * output_dir) { QString res; QString hash; if (type == TYPE_FILE) { hash = FileHash::calculateHash(filename); } else { QByteArray ba; for (int n = filename.count()-1; n >= 0; --n) { ba += filename.at(n); } //qDebug() << "FileSettingsHash::configFile: ba:" << ba; hash = ba.toBase64(); } if (!hash.isEmpty()) { if (output_dir != 0) (*output_dir) = hash[0]; res = base_dir +"/"+ hash[0] +"/"+ hash + ".ini"; } return res; } bool FileSettingsHash::existSettingsFor(QString filename, int type) { qDebug() << "FileSettingsHash::existSettingsFor:" << filename; if (type != TYPE_FILE && type != TYPE_STREAM) return false; QString config_file = configFile(filename, type); qDebug() << "FileSettingsHash::existSettingsFor: config_file:" << config_file; return QFile::exists(config_file); } void FileSettingsHash::loadSettingsFor(QString filename, int type, MediaSettings & mset, int player) { qDebug() << "FileSettings::loadSettingsFor:" << filename << "type:" << type; if (type != TYPE_FILE && type != TYPE_STREAM) return; QString config_file = configFile(filename, type); qDebug() << "FileSettingsHash::loadSettingsFor: config_file:" << config_file; mset.reset(); if ((!config_file.isEmpty()) && (QFile::exists(config_file))) { QSettings settings(config_file, QSettings::IniFormat); settings.beginGroup("file_settings"); mset.load(&settings, player); settings.endGroup(); } } void FileSettingsHash::saveSettingsFor(QString filename, int type, MediaSettings & mset, int player) { qDebug() << "FileSettingsHash::saveSettingsFor:" << filename << "type:" << type; if (type != TYPE_FILE && type != TYPE_STREAM) return; QString output_dir; QString config_file = configFile(filename, type, &output_dir); qDebug() << "FileSettingsHash::saveSettingsFor: config_file:" << config_file; qDebug() << "FileSettingsHash::saveSettingsFor: output_dir:" << output_dir; if (!config_file.isEmpty()) { QDir d(base_dir); if (!d.exists(output_dir)) { if (!d.mkpath(output_dir)) { qWarning() << "FileSettingsHash::saveSettingsFor: can't create directory" << QString(base_dir + "/" + output_dir); return; } } QSettings settings(config_file, QSettings::IniFormat); /* settings.setValue("filename", filename); */ settings.beginGroup("file_settings"); mset.save(&settings, player); settings.endGroup(); settings.sync(); } } kylin-video/src/smplayer/reminderdialog.cpp0000644000175000017500000000442413517016402020047 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "reminderdialog.h" #include "images.h" #include ReminderDialog::ReminderDialog( QWidget* parent, Qt::WindowFlags f ) : QDialog(parent, f) { setupUi(this); setMinimumSize(QSize(500, 100)); icon_label->setPixmap(Images::icon("donate_big")); text_label->setText( tr("If you like SMPlayer and want to support its development, you can send a donation. " "Even the smallest one is highly appreciated.") + "

    "+ tr("Or you maybe you want to share SMPlayer with your friends in Facebook.") + "

    " + tr("What would you like to do?") ); donate_button = buttonBox->addButton(tr("&Donate"), QDialogButtonBox::ActionRole); facebook_button = buttonBox->addButton(tr("&Share with my friends"), QDialogButtonBox::ActionRole); close_button = buttonBox->button(QDialogButtonBox::Close); donate_button->setDefault(true); donate_button->setFocus(); adjustSize(); //layout()->setSizeConstraint(QLayout::SetFixedSize); connect(buttonBox, SIGNAL(clicked(QAbstractButton *)), this, SLOT(button_clicked(QAbstractButton *))); } ReminderDialog::~ReminderDialog() { } void ReminderDialog::button_clicked(QAbstractButton * button) { int res = Close; if (button == donate_button) res = Donate; else if (button == facebook_button) res = Share; qDebug("ReminderDialog::button_clicked: res: %d", res); done(res); } bool ReminderDialog::isRemindChecked() { return remind_check->isChecked(); } #include "moc_reminderdialog.cpp" kylin-video/src/smplayer/shortcutgetter.h0000644000175000017500000000402613637124061017617 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Note: The ShortcutGetter class is taken from the source code of Edyuk (http://www.edyuk.org/), from file 3rdparty/qcumber/qshortcutdialog.cpp Copyright (C) 2006 FullMetalCoder License: GPL I modified it to support multiple shortcuts and some other few changes. */ #ifndef SHORTCUTGETTER_H #define SHORTCUTGETTER_H #include "../utils.h" #include #include class QLineEdit; class ShortcutGetter : public QDialog { Q_OBJECT public: ShortcutGetter(/*bool isbtn = false, */QWidget *parent = 0); QString exec(const QString& s); protected slots: void setCaptureKeyboard(bool b); void rowChanged(int row); void textChanged(const QString & text); void addItemClicked(); void removeItemClicked(); protected: bool captureKeyboard() { return capture; }; bool event(QEvent *e); bool eventFilter(QObject *o, QEvent *e); void setText(); // virtual bool eventFilter(QObject *, QEvent *); // void moveDialog(QPoint diff); private: bool bStop; QLineEdit *leKey; QStringList lKeys; bool capture; QListWidget * list; QPushButton * addItem; QPushButton * removeItem; QPushButton *closeBtn; DragState m_dragState; QPoint m_startDrag; }; #endif kylin-video/src/smplayer/filepropertiesdialog.h0000644000175000017500000000545113517016402020744 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _FILEPROPERTIESDIALOG_H_ #define _FILEPROPERTIESDIALOG_H_ #include "ui_filepropertiesdialog.h" #include "../smplayer/inforeader.h" #include "../smplayer/mediadata.h" #include "../utils.h" class QPushButton; class TitleButton; class FilePropertiesDialog : public QDialog, public Ui::FilePropertiesDialog { Q_OBJECT public: enum Section { Info=0, Demuxer=1, AC=2, VC=3, Options=4}; FilePropertiesDialog( QWidget* parent = 0, Qt::WindowFlags f = 0 ); ~FilePropertiesDialog(); // void setMediaData(MediaData md); void setMediaData(MediaData md, Tracks videos, Tracks audios, SubTracks subs); // Call it as soon as possible void setCodecs(InfoList vc, InfoList ac, InfoList demuxer); void setDemuxer(QString demuxer, QString original_demuxer=""); QString demuxer(); void setVideoCodec(QString vc, QString original_vc=""); QString videoCodec(); void setAudioCodec(QString ac, QString original_ac=""); QString audioCodec(); virtual bool eventFilter(QObject *, QEvent *); void moveDialog(QPoint diff); public slots: void accept(); // Reimplemented to send a signal virtual void reject(); void apply(); void onButtonClicked(int id); void setCurrentID(int id); signals: void applied(); protected slots: virtual void on_resetDemuxerButton_clicked(); virtual void on_resetACButton_clicked(); virtual void on_resetVCButton_clicked(); protected: bool hasCodecsList() { return codecs_set; }; int find(QString s, InfoList &list); void showInfo(); protected: virtual void retranslateStrings(); virtual void changeEvent ( QEvent * event ) ; private: bool codecs_set; InfoList vclist, aclist, demuxerlist; QString orig_demuxer, orig_ac, orig_vc; MediaData media_data; Tracks video_tracks; Tracks audio_tracks; SubTracks sub_tracks; QList m_buttonList; DragState m_dragState; QPoint m_startDrag; }; #endif kylin-video/src/smplayer/timedialog.h0000644000175000017500000000267313517016402016651 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _TIMEDIALOG_H_ #define _TIMEDIALOG_H_ #include "ui_timedialog.h" #include "../utils.h" class QPushButton; class TimeDialog : public QDialog, public Ui::TimeDialog { Q_OBJECT public: TimeDialog( QWidget* parent = 0, Qt::WindowFlags f = 0 ); ~TimeDialog(); int time(); int maximumTime(); QString label(); void initConnect(); virtual bool eventFilter(QObject *, QEvent *); void moveDialog(QPoint diff); public slots: void setTime(int seconds); void setMaximumTime( int seconds ); void setLabel(const QString & label); private: DragState m_dragState; QPoint m_startDrag; }; #endif kylin-video/src/smplayer/audiodelaydialog.cpp0000644000175000017500000001621213637124061020364 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "audiodelaydialog.h" #include "../smplayer/images.h" #include "../smplayer/version.h" #include "../smplayer/global.h" #include "../smplayer/paths.h" #include #include #include using namespace Global; AudioDelayDialog::AudioDelayDialog(QWidget * parent, Qt::WindowFlags f) : QDialog(parent, f) , m_dragState(NOT_DRAGGING) , m_startDrag(QPoint(0,0)) { setupUi(this); this->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint); this->setFixedSize(380, 170); this->setStyleSheet("QDialog{border: 1px solid #121212;border-radius:1px;background-color:#1f1f1f;}"); this->setWindowIcon(QIcon::fromTheme("kylin-video", QIcon(":/res/kylin-video.png"))); // this->setWindowIcon(QIcon::fromTheme("kylin-video", QIcon(":/res/kylin-video.png")).pixmap(QSize(64, 64)).scaled(64, 64, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); this->setAutoFillBackground(true); this->setMouseTracking(true); installEventFilter(this); title_label->setStyleSheet("QLabel{background:transparent;font-size:14px;color:#999999;font-family:方正黑体_GBK;}");//font-weight:bold; label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}");//font-weight:bold; spinBox->setStyleSheet("QSpinBox {height: 24px;min-width: 40px;border: 1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QSpinBox:hover {height: 24px;min-width: 40px;background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QSpinBox:enabled {color: #999999;}QSpinBox:enabled:hover, QSpinBox:enabled:focus {color: #999999;}QSpinBox:!enabled {color: #383838;background: transparent;}QSpinBox::up-button {border: none;width: 17px;height: 12px;image: url(:/res/spin_top_arrow_normal.png);}QSpinBox::up-button:hover {image: url(:/res/spin_top_arrow_hover.png);}QSpinBox::up-button:pressed {image: url(:/res/spin_top_arrow_press.png);}QSpinBox::up-button:!enabled {background: transparent;}QSpinBox::up-button:enabled:hover {background: rgb(255, 255, 255, 30);}QSpinBox::down-button {border: none;width: 17px;height: 12px;image: url(:/res/spin_bottom_arrow_normal.png);}QSpinBox::down-button:hover {image: url(:/res/spin_bottom_arrow_hover.png);}QSpinBox::down-button:pressed {image: url(:/res/spin_bottom_arrow_press.png);}QSpinBox::down-button:!enabled {background: transparent;}QSpinBox::down-button:hover{background: #0f0f0f;}"); closeBtn->setFocusPolicy(Qt::NoFocus); closeBtn->setStyleSheet("QPushButton{background-image:url(':/res/close_normal.png');border:0px;}QPushButton:hover{background:url(':/res/close_hover.png');}QPushButton:pressed{background:url(':/res/close_press.png');}"); okBtn->setFixedSize(91, 25); okBtn->setText(tr("OK")); okBtn->setFocusPolicy(Qt::NoFocus); okBtn->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); cancelBtn->setFixedSize(91, 25); cancelBtn->setText(tr("Cancel")); cancelBtn->setFocusPolicy(Qt::NoFocus); cancelBtn->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #000000;color:#999999;}QPushButton:hover{background-color:#1f1f1f;border:1px solid #0f0f0f;color:#ffffff;} QPushButton:pressed{background-color:#0d0d0d;border:1px solid #000000;color:#ffffff;}"); this->initConnect(); } AudioDelayDialog::~AudioDelayDialog() { } void AudioDelayDialog::setDefaultValue(int audio_delay) { spinBox->setValue(audio_delay); } int AudioDelayDialog::getCurrentValue() { return spinBox->value(); } void AudioDelayDialog::initConnect() { connect(okBtn, SIGNAL(clicked()), this, SLOT(accept())); connect(cancelBtn, SIGNAL(clicked()), this, SLOT(close())); connect(closeBtn, SIGNAL(clicked()), this, SLOT(close())); } void AudioDelayDialog::moveDialog(QPoint diff) { #if QT_VERSION >= 0x050000 // Move the window with some delay. // Seems to work better with Qt 5 static QPoint d; static int count = 0; d += diff; count++; if (count > 3) { QPoint new_pos = pos() + d; if (new_pos.y() < 0) new_pos.setY(0); if (new_pos.x() < 0) new_pos.setX(0); move(new_pos); count = 0; d = QPoint(0,0); } #else move(pos() + diff); #endif } bool AudioDelayDialog::eventFilter( QObject * object, QEvent * event ) { QEvent::Type type = event->type(); if (type != QEvent::MouseButtonPress && type != QEvent::MouseButtonRelease && type != QEvent::MouseMove) return false; QMouseEvent *mouseEvent = dynamic_cast(event); if (!mouseEvent) return false; if (mouseEvent->modifiers() != Qt::NoModifier) { m_dragState = NOT_DRAGGING; return false; } if (type == QEvent::MouseButtonPress) { if (mouseEvent->button() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } m_dragState = START_DRAGGING; m_startDrag = mouseEvent->globalPos(); // Don't filter, so others can have a look at it too return false; } if (type == QEvent::MouseButtonRelease) { if (m_dragState != DRAGGING || mouseEvent->button() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } // Stop dragging and eat event m_dragState = NOT_DRAGGING; event->accept(); return true; } // type == QEvent::MouseMove if (m_dragState == NOT_DRAGGING) return false; // buttons() note the s if (mouseEvent->buttons() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } QPoint pos = mouseEvent->globalPos(); QPoint diff = pos - m_startDrag; if (m_dragState == START_DRAGGING) { // Don't start dragging before moving at least DRAG_THRESHOLD pixels if (abs(diff.x()) < 4 && abs(diff.y()) < 4) return false; m_dragState = DRAGGING; } this->moveDialog(diff); m_startDrag = pos; event->accept(); return true; } kylin-video/src/smplayer/preferencesdialog.cpp0000644000175000017500000003012013637124061020537 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "preferencesdialog.h" #include #include #include #include "prefgeneral.h" #include "prefvideo.h" #include "prefaudio.h" #include "prefperformance.h" #include "prefsubtitles.h" #include "prefscreenshot.h" #include "prefshortcut.h" #include "../titlebutton.h" #include "preferences.h" #include #include #include PreferencesDialog::PreferencesDialog(QString arch_type, QString snap, QWidget * parent, Qt::WindowFlags f) : QDialog(parent, f ) , m_dragState(NOT_DRAGGING) , m_startDrag(QPoint(0,0)) { setupUi(this); this->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint); this->setFixedSize(675, 425); this->setStyleSheet("QDialog{border: 1px solid #121212;border-radius:1px;background-color:#1f1f1f;}"); this->setWindowIcon(QIcon::fromTheme("kylin-video", QIcon(":/res/kylin-video.png"))); // this->setWindowIcon(QIcon::fromTheme("kylin-video", QIcon(":/res/kylin-video.png")).pixmap(QSize(64, 64)).scaled(64, 64, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); this->setAttribute(Qt::WA_DeleteOnClose); this->setAutoFillBackground(true); this->setMouseTracking(true); installEventFilter(this); title_widget->setAutoFillBackground(true); title_widget->setStyleSheet("QWidget{border:none;background-color:#2e2e2e;}"); connect(okButton, SIGNAL(clicked()), this, SLOT(accept())); connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject())); connect(applyButton, SIGNAL(clicked()), this, SLOT(apply())); okButton->setFixedSize(91, 25); cancelButton->setFixedSize(91, 25); applyButton->setFixedSize(91, 25); okButton->setFocusPolicy(Qt::NoFocus); cancelButton->setFocusPolicy(Qt::NoFocus); applyButton->setFocusPolicy(Qt::NoFocus); okButton->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); cancelButton->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #000000;color:#999999;}QPushButton:hover{background-color:#1f1f1f;border:1px solid #0f0f0f;color:#ffffff;} QPushButton:pressed{background-color:#0d0d0d;border:1px solid #000000;color:#ffffff;}"); applyButton->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); title_label->setStyleSheet("QLabel{background:transparent;font-family: 方正黑体_GBK;font-size:18px;color:#999999;}"); QVBoxLayout *layout = new QVBoxLayout(this); layout->setContentsMargins(0, 5, 0, 0); layout->setSpacing(0); page_general = new PrefGeneral; addSection(page_general); pages->setCurrentWidget(page_general); TitleButton *btn = new TitleButton(0, false, tr("General")); connect(btn, SIGNAL(clicked(int)), this, SLOT(onButtonClicked(int))); layout->addWidget(btn); m_buttonList << btn; btn->setActived(true); page_video = new PrefVideo(arch_type, snap); addSection(page_video); btn = new TitleButton(1, false, tr("Video")); connect(btn, SIGNAL(clicked(int)), this, SLOT(onButtonClicked(int))); layout->addWidget(btn); m_buttonList << btn; page_audio = new PrefAudio(snap); addSection(page_audio); btn = new TitleButton(2, false, tr("Audio")); connect(btn, SIGNAL(clicked(int)), this, SLOT(onButtonClicked(int))); layout->addWidget(btn); m_buttonList << btn; page_performance = new PrefPerformance; addSection( page_performance ); btn = new TitleButton(3, false, tr("Performance")); connect(btn, SIGNAL(clicked(int)), this, SLOT(onButtonClicked(int))); layout->addWidget(btn); m_buttonList << btn; page_subtitles = new PrefSubtitles; addSection(page_subtitles); btn = new TitleButton(4, false, tr("Subtitles")); connect(btn, SIGNAL(clicked(int)), this, SLOT(onButtonClicked(int))); layout->addWidget(btn); m_buttonList << btn; page_screenshot = new PrefScreenShot; addSection(page_screenshot); btn = new TitleButton(5, false, tr("ScreenShot")); connect(btn, SIGNAL(clicked(int)), this, SLOT(onButtonClicked(int))); layout->addWidget(btn); m_buttonList << btn; page_shortcut = new PrefShortCut; addSection(page_shortcut); btn = new TitleButton(6, false, tr("Shortcut Key")); connect(btn, SIGNAL(clicked(int)), this, SLOT(onButtonClicked(int))); layout->addWidget(btn); m_buttonList << btn; layout->addStretch(); sections->setLayout(layout); connect(page_general, SIGNAL(ready_to_update_driver()), page_video, SLOT(update_driver_combobox())); connect(page_general, SIGNAL(ready_to_update_driver()), page_audio, SLOT(update_driver_combobox())); retranslateStrings(); } PreferencesDialog::~PreferencesDialog() { for(int i=0; iid() == id) { button->setActived(true); } else { button->setActived(false); } } } void PreferencesDialog::onButtonClicked(int id) { setCurrentID(id); if (id == 0) { pages->setCurrentWidget(page_general); } else if (id == 1) { pages->setCurrentWidget(page_video); } else if (id == 2) { pages->setCurrentWidget(page_audio); } else if (id == 3) { pages->setCurrentWidget(page_performance); } else if (id == 4) { pages->setCurrentWidget(page_subtitles); } else if (id == 5) { pages->setCurrentWidget(page_screenshot); } else if (id == 6) { pages->setCurrentWidget(page_shortcut); } } void PreferencesDialog::showSection(Section s) { qDebug("PreferencesDialog::showSection: %d", s); } void PreferencesDialog::retranslateStrings() { retranslateUi(this); icon_label->setPixmap(QPixmap(":/res/settings.png")); okButton->setText(tr("OK")); cancelButton->setText(tr("Cancel")); applyButton->setText(tr("Apply")); } void PreferencesDialog::accept() { hide(); setResult( QDialog::Accepted ); emit applied(); } void PreferencesDialog::apply() { setResult( QDialog::Accepted ); emit applied(); } void PreferencesDialog::reject() { hide(); setResult( QDialog::Rejected ); setResult( QDialog::Accepted ); } void PreferencesDialog::addSection(PrefWidget *w) { pages->addWidget(w); } void PreferencesDialog::setData(Preferences * pref) { page_general->setData(pref); page_video->setData(pref); page_audio->setData(pref); page_performance->setData(pref); page_subtitles->setData(pref); page_screenshot->setData(pref); page_shortcut->setData(pref); } void PreferencesDialog::getData(Preferences * pref) { page_general->getData(pref); page_video->getData(pref); page_audio->getData(pref); page_performance->getData(pref); page_subtitles->getData(pref); page_screenshot->getData(pref); page_shortcut->getData(pref); } bool PreferencesDialog::requiresRestart() { bool need_restart = page_general->requiresRestart(); if (!need_restart) need_restart = page_video->requiresRestart(); if (!need_restart) need_restart = page_audio->requiresRestart(); if (!need_restart) need_restart = page_performance->requiresRestart(); if (!need_restart) need_restart = page_subtitles->requiresRestart(); if (!need_restart) need_restart = page_screenshot->requiresRestart(); if (!need_restart) need_restart = page_shortcut->requiresRestart(); return need_restart; } // Language change stuff void PreferencesDialog::changeEvent(QEvent *e) { if (e->type() == QEvent::LanguageChange) { retranslateStrings(); } else { QDialog::changeEvent(e); } } void PreferencesDialog::moveDialog(QPoint diff) { #if QT_VERSION >= 0x050000 // Move the window with some delay. // Seems to work better with Qt 5 static QPoint d; static int count = 0; d += diff; count++; if (count > 3) { // qDebug() << "> 3PreferencesDialog::moveWindowDiff:" << d; QPoint new_pos = pos() + d; if (new_pos.y() < 0) new_pos.setY(0); if (new_pos.x() < 0) new_pos.setX(0); // qDebug() << "PreferencesDialog::moveWindowDiff: new_pos:" << new_pos; move(new_pos); count = 0; d = QPoint(0,0); } #else move(pos() + diff); #endif } bool PreferencesDialog::eventFilter( QObject * object, QEvent * event ) { QEvent::Type type = event->type(); if (type != QEvent::MouseButtonPress && type != QEvent::MouseButtonRelease && type != QEvent::MouseMove) return false; QMouseEvent *mouseEvent = dynamic_cast(event); if (!mouseEvent) return false; if (mouseEvent->modifiers() != Qt::NoModifier) { m_dragState = NOT_DRAGGING; return false; } if (type == QEvent::MouseButtonPress) { if (mouseEvent->button() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } m_dragState = START_DRAGGING; m_startDrag = mouseEvent->globalPos(); // Don't filter, so others can have a look at it too return false; } if (type == QEvent::MouseButtonRelease) { if (m_dragState != DRAGGING || mouseEvent->button() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } // Stop dragging and eat event m_dragState = NOT_DRAGGING; event->accept(); return true; } // type == QEvent::MouseMove if (m_dragState == NOT_DRAGGING) return false; // buttons() note the s if (mouseEvent->buttons() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } QPoint pos = mouseEvent->globalPos(); QPoint diff = pos - m_startDrag; if (m_dragState == START_DRAGGING) { // Don't start dragging before moving at least DRAG_THRESHOLD pixels if (abs(diff.x()) < 4 && abs(diff.y()) < 4) return false; m_dragState = DRAGGING; } this->moveDialog(diff); m_startDrag = pos; event->accept(); return true; } kylin-video/src/smplayer/titletracks.h0000644000175000017500000000447713517016402017070 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _TITLETRACKS_H_ #define _TITLETRACKS_H_ #include #include "../utils.h" /* Class to store info about DVD titles */ class TitleData { public: TitleData() { _name = ""; _duration = 0; _ID = -1; _chapters = 0; _angles = 0; }; ~TitleData() {}; void setName( const QString & n ) { _name = n; }; void setDuration( double d ) { _duration = d; }; void setChapters( int n ) { _chapters = n; }; void setAngles( int n ) { _angles = n; }; void setID( int id ) { _ID = id; }; QString name() const { return _name; }; double duration() const { return _duration; }; int chapters() const { return _chapters; }; int angles() const { return _angles; }; int ID() const { return _ID; }; QString displayName() const { QString dname = ""; if (!_name.isEmpty()) { dname = _name; } else dname = QString::number(_ID); if (_duration > 0) { dname += " ("+ Utils::formatTime( (int) _duration ) +")"; } return dname; }; protected: QString _name; double _duration; int _chapters; int _angles; int _ID; }; class TitleTracks { public: TitleTracks(); ~TitleTracks(); void clear(); void list(); void addName(int ID, QString name); void addDuration(int ID, double duration); void addChapters(int ID, int n); void addAngles(int ID, int n); void addID(int ID); int numItems(); bool existsItemAt(int n); TitleData itemAt(int n); TitleData item(int ID); int find(int ID); protected: typedef QMap TitleMap; TitleMap tm; }; #endif kylin-video/src/smplayer/mylineedit.cpp0000644000175000017500000000271513517016402017226 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "mylineedit.h" #include #include #include "images.h" MyLineEdit::MyLineEdit(QWidget *parent) : LineEditWithIcon(parent) { this->setFixedHeight(25); setupButton(); button->hide(); button->setCursor(Qt::PointingHandCursor); connect(button, SIGNAL(clicked()), this, SLOT(clear())); connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(updateCloseButton(const QString&))); } void MyLineEdit::setupButton() { setIcon(Images::icon("clear_left")); } void MyLineEdit::updateCloseButton(const QString& text) { button->setVisible(!text.isEmpty()); } //#include "moc_mylineedit.cpp" kylin-video/src/smplayer/mediadata.cpp0000644000175000017500000000762413517016402017000 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "mediadata.h" #include #include #include MediaData::MediaData() { reset(); } MediaData::~MediaData() { } void MediaData::reset() { m_filename=""; dvd_id=""; type = TYPE_UNKNOWN; duration=0; extra_params.clear(); novideo = false; video_width=0; video_height=0; video_aspect= (double) 4/3; // videos.clear(); // audios.clear(); // subs.clear(); titles.clear(); chapters.clear(); n_chapters = 0; initialized=false; // Clip info; clip_name = ""; clip_artist = ""; clip_author = ""; clip_album = ""; clip_genre = ""; clip_date = ""; clip_track = ""; clip_copyright = ""; clip_comment = ""; clip_software = ""; stream_title = ""; stream_url = ""; stream_path = ""; // Other data demuxer=""; video_format=""; audio_format=""; video_bitrate=0; video_fps=""; audio_bitrate=0; audio_rate=0; audio_nch=0; video_codec=""; audio_codec=""; } QString MediaData::displayName(bool show_tag) { if (show_tag) { if (!stream_title.isEmpty()) { return stream_title; } // else // if (!clip_name.isEmpty()) return clip_name;//0526 } //kobe:有的rmvb视频的clip_name存在乱码 0526 QString name; if (name.isEmpty()) { QFileInfo fi(m_filename); if (fi.exists()) { // Local file name = fi.fileName(); } else { // Stream name = m_filename; } } return name; // QFileInfo fi(m_filename); // if (fi.exists()) // return fi.fileName(); // m_filename without path // else // return m_filename; } void MediaData::list() { // qDebug("MediaData::list"); // qDebug(" m_filename: '%s'", m_filename.toUtf8().data()); // qDebug(" duration: %f", duration); // qDebug(" video_width: %d", video_width); // qDebug(" video_height: %d", video_height); // qDebug(" video_aspect: %f", video_aspect); // qDebug(" type: %d", type); // qDebug(" novideo: %d", novideo); // qDebug(" dvd_id: '%s'", dvd_id.toUtf8().data()); // qDebug(" initialized: %d", initialized); // qDebug(" chapters: %d", n_chapters); // qDebug(" Subs:"); // subs.list(); // qDebug(" Videos:"); // videos.list(); // qDebug(" Audios:"); // audios.list(); // qDebug(" Titles:"); titles.list(); //qDebug(" chapters: %d", chapters); //qDebug(" angles: %d", angles); //kobe // qDebug(" demuxer: '%s'", demuxer.toUtf8().data() );//avi real // qDebug(" video_format: '%s'", video_format.toUtf8().data() );//XVID RV40 // qDebug(" audio_format: '%s'", audio_format.toUtf8().data() );//85 cook // qDebug(" video_bitrate: %d", video_bitrate );//1113640 0 // qDebug(" video_fps: '%s'", video_fps.toUtf8().data() );//25.000 23.000 // qDebug(" audio_bitrate: %d", audio_bitrate );//224000 64080 // qDebug(" audio_rate: %d", audio_rate );//44100 44100 // qDebug(" audio_nch: %d", audio_nch );//2 2 // qDebug(" video_codec: '%s'", video_codec.toUtf8().data() );//ffodivx ffrv40 // qDebug(" audio_codec: '%s'", audio_codec.toUtf8().data() );//mpg123 ffcook } kylin-video/src/smplayer/errordialog.h0000644000175000017500000000300413517016402017031 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _ERRORDIALOG_H_ #define _ERRORDIALOG_H_ #include "ui_errordialog.h" #include "../utils.h" class ErrorDialog : public QDialog, public Ui::ErrorDialog { Q_OBJECT public: ErrorDialog( QWidget* parent = 0, Qt::WindowFlags f = 0 ); ~ErrorDialog(); virtual bool eventFilter(QObject *, QEvent *); void moveDialog(QPoint diff); public slots: void setText(QString error); void setLog(QString log_text); void setTitleText(QString error); void hideDetailBtn(); protected slots: void toggleLog(bool); private: DragState m_dragState; QPoint m_startDrag; }; #endif kylin-video/src/smplayer/prefwidget.cpp0000644000175000017500000000350213524205650017221 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "prefwidget.h" #include PrefWidget::PrefWidget(QWidget * parent, Qt::WindowFlags f ) : QWidget(parent, f) { requires_restart = false; help_message = ""; } PrefWidget::~PrefWidget() { } QString PrefWidget::sectionName() { return QString(); } QPixmap PrefWidget::sectionIcon() { return QPixmap(); } void PrefWidget::addSectionTitle(const QString & title) { help_message += "

    "+title+"

    "; } void PrefWidget::setWhatsThis( QWidget *w, const QString & title, const QString & text) { w->setWhatsThis(text); help_message += ""+title+"
    "+text+"

    "; w->setToolTip(""+ text +"" ); } void PrefWidget::clearHelp() { help_message = "

    " + sectionName() + "

    "; } void PrefWidget::createHelp() { } // Language change stuff void PrefWidget::changeEvent(QEvent *e) { if (e->type() == QEvent::LanguageChange) { retranslateStrings(); } else { QWidget::changeEvent(e); } } void PrefWidget::retranslateStrings() { } kylin-video/src/smplayer/filesettingsbase.cpp0000644000175000017500000000154613517016402020417 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2018 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "filesettingsbase.h" kylin-video/src/smplayer/timedialog.ui0000644000175000017500000000503413637124061017035 0ustar fengfeng TimeDialog 0 0 380 170 380 170 380 170 Seek 160 130 91 25 OK 260 130 91 25 Cancel 344 0 36 36 95 10 191 20 Seek Qt::AlignCenter 60 64 91 29 0 0 Jump to: Qt::AlignCenter time_edit 165 65 141 27 kylin-video/src/smplayer/scrollermodule.cpp0000644000175000017500000000315213517016402020112 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2018 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "scrollermodule.h" #include #if QT_VERSION >= 0x050000 #include #include #endif void ScrollerModule::setScroller(QObject *w, bool touch) { #if QT_VERSION >= 0x050000 QScroller::grabGesture(w, touch ? QScroller::TouchGesture : QScroller::LeftMouseButtonGesture); // Change properties QVariant overshoot = QVariant::fromValue(QScrollerProperties::OvershootAlwaysOff); QScrollerProperties sp = QScroller::scroller(w)->scrollerProperties(); sp.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy, overshoot); sp.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, overshoot); QScroller::scroller(w)->setScrollerProperties(sp); #endif } kylin-video/src/smplayer/prefgeneral.ui0000644000175000017500000000357113517016402017211 0ustar fengfeng PrefGeneral 0 0 470 360 10 60 448 22 Pause when minimized 128 23 117 22 MPlayer 250 23 117 22 MPV 10 20 121 27 Playback engine: cache_files_spin 10 95 448 22 Preview when video is playing kylin-video/src/smplayer/timeslider.h0000644000175000017500000000465413637124061016701 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef TIMESLIDER_H #define TIMESLIDER_H #include "myslider.h" class TimeTip; class TimeSlider : public MySlider { Q_OBJECT // Q_PROPERTY(bool status READ isStatus WRITE setStatus)//kobe public: TimeSlider( QWidget * parent ); ~TimeSlider(); // void setStatus(bool e) { status = e; }//kobe // bool isStatus() const { return status; }//kobe void show_time_value(int time); void set_preview_flag(bool b); void show_save_preview_image(int time, QString filepath); public slots: virtual void setPos(int); // Don't use setValue! virtual int pos(); virtual void setDuration(double t) { total_time = t; }; virtual double duration() { return total_time; }; void setDragDelay(int); int dragDelay(); void hideTip(); signals: void posChanged(int); void draggingPos(int); // //! Emitted with a few ms of delay void delayedDraggingPos(int); void wheelUp(); void wheelDown(); void active_status(bool); void requestSavePreviewImage(int time, QPoint pos); void requestHideTip(); protected slots: void stopUpdate(); void resumeUpdate(); void mouseReleased(); void valueChanged_slot(int); void checkDragging(int); void sendDelayedPos(); protected: virtual void wheelEvent(QWheelEvent * e); virtual bool event(QEvent *event); void enterEvent(QEvent *event); void leaveEvent(QEvent *event); bool eventFilter(QObject *obj, QEvent *event); private: bool dont_update; int position; double total_time; TimeTip *hintWidget; int last_pos_to_send; QTimer * timer; // bool status;//kobe QPoint cur_pos; bool preview; }; #endif kylin-video/src/smplayer/actionseditor.cpp0000644000175000017500000005057013625147453017747 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2018 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* This is based on qq14-actioneditor-code.zip from Qt */ #include "actionseditor.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "images.h" #include "filedialog.h" #include "paths.h" #include "shortcutgetter.h" #if QT_VERSION >= 0x050000 #include "scrollermodule.h" #endif /* #include #include class MyDelegate : public QItemDelegate { public: MyDelegate(QObject *parent = 0); QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; virtual void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index ) const; }; MyDelegate::MyDelegate(QObject *parent) : QItemDelegate(parent) { } static QString old_accel_text; QWidget * MyDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem & option, const QModelIndex & index) const { qDebug("MyDelegate::createEditor"); old_accel_text = index.model()->data(index, Qt::DisplayRole).toString(); //qDebug( "text: %s", old_accel_text.toUtf8().data()); return QItemDelegate::createEditor(parent, option, index); } void MyDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { QLineEdit *line_edit = static_cast(editor); QString accelText = QKeySequence(line_edit->text()).toString(); if (accelText.isEmpty() && !line_edit->text().isEmpty()) { model->setData(index, old_accel_text); } else { model->setData(index, accelText); } } */ QString ActionsEditor::shortcutsToString(QList shortcuts_list) { QString accelText = ""; for (int n=0; n < shortcuts_list.count(); n++) { accelText += shortcuts_list[n].toString(QKeySequence::PortableText); if (n < (shortcuts_list.count()-1)) accelText += ", "; } //qDebug("ActionsEditor::shortcutsToString: accelText: '%s'", accelText.toUtf8().constData()); return accelText; } QList ActionsEditor::stringToShortcuts(QString shortcuts) { QList shortcuts_list; QStringList l = shortcuts.split(", "); for (int n=0; n < l.count(); n++) { //qDebug("%s", l[n].toUtf8().data()); #if QT_VERSION >= 0x040300 // Qt 4.3 and 4.4 (at least on linux) seems to have a problem when using Traditional Chinese // QKeysequence deletes the arrow key names from the shortcut // so this is a work-around. QString s = l[n].simplified(); #else QString s = QKeySequence( l[n].simplified() ); #endif //Work-around for Simplified-Chinese s.replace( QString::fromUtf8("左"), "Left"); s.replace( QString::fromUtf8("下"), "Down"); s.replace( QString::fromUtf8("右"), "Right"); s.replace( QString::fromUtf8("上"), "Up"); shortcuts_list.append( s ); //qDebug("ActionsEditor::stringToShortcuts: shortcut %d: '%s'", n, s.toUtf8().data()); } return shortcuts_list; } #define COL_CONFLICTS 0 #define COL_SHORTCUT 1 #define COL_DESC 2 #define COL_NAME 3 ActionsEditor::ActionsEditor(QWidget * parent, Qt::WindowFlags f) : QWidget(parent, f) { latest_dir = Paths::shortcutsPath(); actionsTable = new QTableWidget(0, COL_NAME +1, this); actionsTable->setSelectionMode(QAbstractItemView::SingleSelection); actionsTable->setSelectionBehavior(QAbstractItemView::SelectRows); actionsTable->verticalHeader()->hide(); #if QT_VERSION >= 0x050000 ScrollerModule::setScroller(actionsTable->viewport()); actionsTable->horizontalHeader()->setSectionResizeMode(COL_DESC, QHeaderView::Stretch); actionsTable->horizontalHeader()->setSectionResizeMode(COL_NAME, QHeaderView::Stretch); actionsTable->horizontalHeader()->setSectionResizeMode(COL_CONFLICTS, QHeaderView::ResizeToContents); #else actionsTable->horizontalHeader()->setResizeMode(COL_DESC, QHeaderView::Stretch); actionsTable->horizontalHeader()->setResizeMode(COL_NAME, QHeaderView::Stretch); actionsTable->horizontalHeader()->setResizeMode(COL_CONFLICTS, QHeaderView::ResizeToContents); #endif actionsTable->setAlternatingRowColors(true); //actionsTable->setItemDelegateForColumn( COL_SHORTCUT, new MyDelegate(actionsTable) ); actionsTable->horizontalHeader()->setHighlightSections(false);//点击表时不对表头行光亮(获取焦点) actionsTable->setAlternatingRowColors(true); actionsTable->setStyleSheet("font-family:方正黑体_GBK;font-size:12px;color:#999999;selection-background-color:red;alternate-background-color: #2e2e2e; background:transparent;"); actionsTable->horizontalHeader()->setStyleSheet("QHeaderView::section{font-family:方正黑体_GBK;font-size:13px;color:#999999;background:transparent;}"); //设置表头背景色 actionsTable->horizontalScrollBar()->setStyleSheet("QScrollBar{background:transparent; height:10px;}" "QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}" "QScrollBar::handle:hover{background:gray;}" "QScrollBar::sub-line{background:transparent;}" "QScrollBar::add-line{background:transparent;}"); actionsTable->verticalScrollBar()->setStyleSheet("QScrollBar{background:transparent; width: 10px;}" "QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}" "QScrollBar::handle:hover{background:gray;}" "QScrollBar::sub-line{background:transparent;}" "QScrollBar::add-line{background:transparent;}"); actionsTable->setSelectionBehavior(QAbstractItemView::SelectRows); actionsTable->setSelectionMode(QAbstractItemView::ExtendedSelection); // connect(actionsTable, SIGNAL(currentItemChanged(QTableWidgetItem *,QTableWidgetItem *)), // this, SLOT(recordAction(QTableWidgetItem *)) ); // connect(actionsTable, SIGNAL(itemChanged(QTableWidgetItem *)), // this, SLOT(validateAction(QTableWidgetItem *)) ); connect(actionsTable, SIGNAL(itemActivated(QTableWidgetItem *)), this, SLOT(editShortcut()) ); // saveButton = new QPushButton(this); // loadButton = new QPushButton(this); // connect(saveButton, SIGNAL(clicked()), this, SLOT(saveActionsTable())); // connect(loadButton, SIGNAL(clicked()), this, SLOT(loadActionsTable())); //#if USE_SHORTCUTGETTER // editButton = new QPushButton(this); // connect( editButton, SIGNAL(clicked()), this, SLOT(editShortcut()) ); //#endif /*QHBoxLayout *buttonLayout = new QHBoxLayout; buttonLayout->setSpacing(8); //#if USE_SHORTCUTGETTER // buttonLayout->addWidget(editButton); //#endif buttonLayout->addStretch(1); buttonLayout->addWidget(loadButton); buttonLayout->addWidget(saveButton);*/ QVBoxLayout *mainLayout = new QVBoxLayout(this); mainLayout->setMargin(8); mainLayout->setSpacing(8); mainLayout->addWidget(actionsTable); // mainLayout->addLayout(buttonLayout); retranslateStrings(); } ActionsEditor::~ActionsEditor() { } void ActionsEditor::retranslateStrings() { actionsTable->setHorizontalHeaderLabels( QStringList() << "" << tr("Shortcut") << tr("Description") << tr("Name") ); // saveButton->setText(tr("&Save")); // saveButton->setIcon(Images::icon("save")); // loadButton->setText(tr("&Load")); // loadButton->setIcon(Images::icon("open")); //#if USE_SHORTCUTGETTER // editButton->setText(tr("&Change shortcut...")); //#endif //updateView(); // The actions are translated later, so it's useless } bool ActionsEditor::isEmpty() { return actionsList.isEmpty(); } void ActionsEditor::clear() { actionsList.clear(); } void ActionsEditor::addActions(QWidget *widget) { QAction *action; QList actions = widget->findChildren(); for (int n=0; n < actions.count(); n++) { action = static_cast (actions[n]); /* if (!action->objectName().isEmpty()) { qDebug("ActionsEditor::addActions: action # %d: '%s' menu: %d", n, action->objectName().toUtf8().constData(), action->menu()!=0); } */ if (!action->objectName().isEmpty() && action->objectName() != "pl_play" && action->objectName() != "pl_remove_selected" && action->objectName() != "pl_delete_from_disk" && !action->inherits("QWidgetAction") && (action->menu()==0) ) actionsList.append(action); } updateView(); } void ActionsEditor::updateView() { actionsTable->setRowCount( actionsList.count() ); QAction *action; QString accelText; //#if !USE_SHORTCUTGETTER dont_validate = true; //#endif //actionsTable->setSortingEnabled(false); for (int n=0; n < actionsList.count(); n++) { action = static_cast (actionsList[n]); //#if USE_MULTIPLE_SHORTCUTS accelText = shortcutsToString( action->shortcuts() ); //#else // accelText = action->shortcut().toString(); //#endif // Conflict column QTableWidgetItem * i_conf = new QTableWidgetItem(); // Name column QTableWidgetItem * i_name = new QTableWidgetItem(action->objectName()); // Desc column QTableWidgetItem * i_desc = new QTableWidgetItem(action->text().replace("&","")); i_desc->setIcon( action->icon() ); // Shortcut column QTableWidgetItem * i_shortcut = new QTableWidgetItem(accelText); int column_height = i_shortcut->sizeHint().height(); i_shortcut->setSizeHint(QSize(150, column_height)); // Set flags //#if !USE_SHORTCUTGETTER // i_conf->setFlags(Qt::ItemIsEnabled); // i_name->setFlags(Qt::ItemIsEnabled); // i_desc->setFlags(Qt::ItemIsEnabled); //#else i_conf->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); i_name->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); i_desc->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); i_shortcut->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); //#endif // Add items to table actionsTable->setItem(n, COL_CONFLICTS, i_conf ); actionsTable->setItem(n, COL_NAME, i_name ); actionsTable->setItem(n, COL_DESC, i_desc ); actionsTable->setItem(n, COL_SHORTCUT, i_shortcut ); } hasConflicts(); // Check for conflicts actionsTable->resizeColumnsToContents(); actionsTable->setCurrentCell(0, COL_SHORTCUT); //#if !USE_SHORTCUTGETTER dont_validate = false; //#endif //actionsTable->setSortingEnabled(true); } void ActionsEditor::applyChanges() { qDebug("ActionsEditor::applyChanges"); for (int row = 0; row < (int)actionsList.size(); ++row) { QAction *action = actionsList[row]; QTableWidgetItem *i = actionsTable->item(row, COL_SHORTCUT); //#if USE_MULTIPLE_SHORTCUTS action->setShortcuts( stringToShortcuts(i->text()) ); //#else // action->setShortcut( QKeySequence(i->text()) ); //#endif } } //#if !USE_SHORTCUTGETTER void ActionsEditor::recordAction(QTableWidgetItem * i) { //qDebug("ActionsEditor::recordAction"); //QTableWidgetItem * i = actionsTable->currentItem(); if (i->column() == COL_SHORTCUT) { //qDebug("ActionsEditor::recordAction: %d %d %s", i->row(), i->column(), i->text().toUtf8().data()); oldAccelText = i->text(); } } void ActionsEditor::validateAction(QTableWidgetItem * i) { //qDebug("ActionsEditor::validateAction"); if (dont_validate) return; if (i->column() == COL_SHORTCUT) { QString accelText = QKeySequence(i->text()).toString(); if (accelText.isEmpty() && !i->text().isEmpty()) { /* QAction * action = static_cast (actionsList[i->row()]); QString oldAccelText= action->accel().toString(); */ i->setText(oldAccelText); } else { i->setText(accelText); } if (hasConflicts()) qApp->beep(); } } //#else void ActionsEditor::editShortcut() { QTableWidgetItem * i = actionsTable->item( actionsTable->currentRow(), COL_SHORTCUT ); if (i) { //QTableWidgetItem * j = actionsTable->item( actionsTable->currentRow(), COL_NAME ); ShortcutGetter d(this); QString result = d.exec( i->text() ); if (!result.isNull()) { //qDebug("ActionsEditor::editShortcut: result: '%s'", result.toUtf8().constData()); QString accelText = QKeySequence(result).toString(QKeySequence::PortableText); i->setText(accelText); if (hasConflicts()) qApp->beep();//使用默认的音量和铃声,发出铃声 } } } //#endif int ActionsEditor::findActionName(const QString & name) { for (int row=0; row < actionsTable->rowCount(); row++) { if (actionsTable->item(row, COL_NAME)->text() == name) return row; } return -1; } bool ActionsEditor::containsShortcut(const QString & accel, const QString & shortcut) { QStringList shortcut_list = accel.split(", "); QString s; foreach(s, shortcut_list) { s = s.trimmed(); //qDebug("ActionsEditor::containsShortcut: comparing '%s' with '%s'", s.toUtf8().constData(), shortcut.toUtf8().constData()); if (s == shortcut) return true; } return false; } int ActionsEditor::findActionAccel(const QString & accel, int ignoreRow) { QStringList shortcuts = accel.split(", "); QString shortcut; for (int row = 0; row < actionsTable->rowCount(); row++) { QTableWidgetItem * i = actionsTable->item(row, COL_SHORTCUT); if (i && row != ignoreRow) { if (!i->text().isEmpty()) { foreach(shortcut, shortcuts) { if (containsShortcut(i->text(), shortcut.trimmed())) { return row; } } } } } return -1; } bool ActionsEditor::hasConflicts() { int found; bool conflict = false; QString accelText; QTableWidgetItem *i; for (int n = 0; n < actionsTable->rowCount(); n++) { //actionsTable->setText( n, COL_CONFLICTS, " "); i = actionsTable->item( n, COL_CONFLICTS ); if (i) i->setIcon( QPixmap() ); i = actionsTable->item(n, COL_SHORTCUT ); if (i) { accelText = i->text(); if (!accelText.isEmpty()) { found = findActionAccel( accelText, n ); if ( (found != -1) /*&& (found != n)*/ ) { conflict = true; //actionsTable->setText( n, COL_CONFLICTS, "!"); actionsTable->item( n, COL_CONFLICTS )->setIcon( Images::icon("conflict") ); } } } } //if (conflict) qApp->beep(); return conflict; } void ActionsEditor::saveActionsTable() { QString s = MyFileDialog::getSaveFileName( this, tr("Choose a filename"), latest_dir, tr("Key files") +" (*.keys)" ); if (!s.isEmpty()) { // If filename has no extension, add it if (QFileInfo(s).suffix().isEmpty()) { s = s + ".keys"; } if (QFileInfo(s).exists()) { int res = QMessageBox::question( this, tr("Confirm overwrite?"), tr("The file %1 already exists.\n" "Do you want to overwrite?").arg(s), QMessageBox::Yes, QMessageBox::No, Qt::NoButton); if (res == QMessageBox::No ) { return; } } latest_dir = QFileInfo(s).absolutePath(); bool r = saveActionsTable(s); if (!r) { QMessageBox::warning(this, tr("Error"), tr("The file couldn't be saved"), QMessageBox::Ok, Qt::NoButton); } } } bool ActionsEditor::saveActionsTable(const QString & filename) { qDebug("ActionsEditor::saveActions: '%s'", filename.toUtf8().data()); QFile f( filename ); if ( f.open( QIODevice::WriteOnly ) ) { QTextStream stream( &f ); stream.setCodec("UTF-8"); for (int row=0; row < actionsTable->rowCount(); row++) { stream << actionsTable->item(row, COL_NAME)->text() << "\t" << actionsTable->item(row, COL_SHORTCUT)->text() << "\n"; } f.close(); return true; } return false; } void ActionsEditor::loadActionsTable() { QString s = MyFileDialog::getOpenFileName( this, tr("Choose a file"), latest_dir, tr("Key files") +" (*.keys)" ); if (!s.isEmpty()) { latest_dir = QFileInfo(s).absolutePath(); bool r = loadActionsTable(s); if (!r) { QMessageBox::warning(this, tr("Error"), tr("The file couldn't be loaded"), QMessageBox::Ok, Qt::NoButton); } } } bool ActionsEditor::loadActionsTable(const QString & filename) { qDebug() << "ActionsEditor::loadActions:" << filename; int row; QFile f( filename ); if ( f.open( QIODevice::ReadOnly ) ) { //#if !USE_SHORTCUTGETTER dont_validate = true; //#endif QTextStream stream( &f ); stream.setCodec("UTF-8"); QString line; while ( !stream.atEnd() ) { line = stream.readLine().trimmed(); qDebug() << "ActionsEditor::loadActions: line:" << line; QString name; QString accelText; int pos = line.indexOf(QRegExp("\\t|\\s")); //qDebug() << "ActionsEditor::loadActions: pos:" << pos; if (pos == -1) { name = line; } else { name = line.left(pos); accelText = line.mid(pos+1).trimmed(); } qDebug() << "ActionsEditor::loadActions: name:" << name << "accel:" << accelText; if (!name.isEmpty()) { row = findActionName(name); if (row > -1) { qDebug() << "ActionsEditor::loadActions: action found!"; actionsTable->item(row, COL_SHORTCUT)->setText(accelText); } } else { qDebug() << "ActionsEditor::loadActions: error in line"; } } f.close(); hasConflicts(); // Check for conflicts //#if !USE_SHORTCUTGETTER dont_validate = false; //#endif return true; } else { return false; } } // Static functions void ActionsEditor::saveToConfig(QObject *o, QSettings *set) { qDebug("ActionsEditor::saveToConfig"); set->beginGroup("actions"); QAction *action; QList actions = o->findChildren(); for (int n=0; n < actions.count(); n++) { action = static_cast (actions[n]); if (!action->objectName().isEmpty() && !action->inherits("QWidgetAction")) { //#if USE_MULTIPLE_SHORTCUTS QString accelText = shortcutsToString(action->shortcuts()); //#else // QString accelText = action->shortcut().toString(); //#endif set->setValue(action->objectName(), accelText); } } set->endGroup(); } void ActionsEditor::loadFromConfig(QObject *o, QSettings *set) { //qDebug("ActionsEditor::loadFromConfig"); set->beginGroup("actions"); QAction *action; QString accelText; QList actions = o->findChildren(); for (int n=0; n < actions.count(); n++) { action = static_cast (actions[n]); if (!action->objectName().isEmpty() && !action->inherits("QWidgetAction")) { //#if USE_MULTIPLE_SHORTCUTS QString current = shortcutsToString(action->shortcuts()); accelText = set->value(action->objectName(), current).toString(); action->setShortcuts( stringToShortcuts( accelText ) ); //#else // accelText = set->value(action->objectName(), action->shortcut().toString()).toString(); // action->setShortcut(QKeySequence(accelText)); //#endif } } set->endGroup(); } QAction * ActionsEditor::findAction(QObject *o, const QString & name) { QAction *action; QList actions = o->findChildren(); for (int n=0; n < actions.count(); n++) { action = static_cast (actions[n]); /* qDebug("ActionsEditor::findAction: %s", action->objectName().toLatin1().constData()); */ if (name == action->objectName()) return action; } return 0; } QStringList ActionsEditor::actionsNames(QObject *o) { QStringList l; QAction *action; QList actions = o->findChildren(); for (int n=0; n < actions.count(); n++) { action = static_cast (actions[n]); //qDebug("action name: '%s'", action->objectName().toUtf8().data()); //qDebug("action name: '%s'", action->text().toUtf8().data()); if (!action->objectName().isEmpty()) l.append( action->objectName() ); } return l; } // Language change stuff void ActionsEditor::changeEvent(QEvent *e) { if (e->type() == QEvent::LanguageChange) { retranslateStrings(); } else { QWidget::changeEvent(e); } } //#include "moc_actionseditor.cpp" kylin-video/src/smplayer/mpvoptions.cpp0000644000175000017500000013550313637124037017312 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include "inforeader.h" #include "deviceinfo.h" #include "mpvprocess.h"// src/smplayer/mpvoptions.cpp:109: Qualifying with unknown namespace/class ::MPVProcess #define EQ_OLD 0 #define EQ_ANEQUALIZER 1 #define EQ_FIREQUALIZER 2 #define EQ_FIREQUALIZER_LIST 3 #define EQ_SUPEREQUALIZER 4 #define EQ_FEQUALIZER 5 //#define USE_EQUALIZER EQ_FIREQUALIZER #define LETTERBOX_OLD 1 #define LETTERBOX_PAD 2 #define LETTERBOX_PAD_WITH_ASPECT 3 //#ifdef Q_OS_WIN //#define USE_LETTERBOX LETTERBOX_PAD_WITH_ASPECT //#else #define USE_LETTERBOX LETTERBOX_PAD //#endif #define OSD_PREFIX use_osd_in_commands ? "" : "no-osd" //#define OSD_PREFIX "" void MPVProcess::addArgument(const QString & /*a*/) { } void MPVProcess::initializeOptionVars() { //qDebug("MPVProcess::initializeOptionVars"); PlayerProcess::initializeOptionVars(); //#ifdef OSD_WITH_TIMER osd_timer = new QTimer(this); osd_timer->setInterval(500); connect(osd_timer, SIGNAL(timeout()), this, SLOT(displayInfoOnOSD())); //#endif use_osd_in_commands = true; } void MPVProcess::setMedia(const QString & media, bool is_playlist) { // INFO_VIDEO_ASPECT for ubuntukylin 20.04 arg << "--term-playing-msg=" "MPV_VERSION=${=mpv-version:}\n" "INFO_VIDEO_WIDTH=${=width}\nINFO_VIDEO_HEIGHT=${=height}\n" "INFO_VIDEO_ASPECT=${=video-aspect}\n" // old // "INFO_VIDEO_ASPECT=${=video-params/aspect}\n" // "INFO_VIDEO_DSIZE=${=dwidth}x${=dheight}\n" "INFO_VIDEO_FPS=${=container-fps:${=fps}}\n" // "INFO_VIDEO_BITRATE=${=video-bitrate}\n" "INFO_VIDEO_FORMAT=${=video-format}\n" "INFO_VIDEO_CODEC=${=video-codec}\n" // "INFO_AUDIO_BITRATE=${=audio-bitrate}\n" // "INFO_AUDIO_FORMAT=${=audio-format}\n" // old "INFO_AUDIO_FORMAT=${=audio-codec-name}\n" "INFO_AUDIO_CODEC=${=audio-codec}\n" // "INFO_AUDIO_RATE=${=audio-samplerate}\n" // old "INFO_AUDIO_RATE=${=audio-params/samplerate}\n" // "INFO_AUDIO_NCH=${=audio-channels}\n" // old "INFO_AUDIO_NCH=${=audio-params/channel-count}\n" // "INFO_LENGTH=${=length}\n" "INFO_LENGTH=${=duration:${=length}}\n" "INFO_DEMUXER=${=current-demuxer:${=demuxer}}\n" "INFO_SEEKABLE=${=seekable}\n" "INFO_TITLES=${=disc-titles}\n" "INFO_CHAPTERS=${=chapters}\n" "INFO_TRACKS_COUNT=${=track-list/count}\n" "METADATA_TITLE=${metadata/by-key/title:}\n" "METADATA_ARTIST=${metadata/by-key/artist:}\n" "METADATA_ALBUM=${metadata/by-key/album:}\n" "METADATA_GENRE=${metadata/by-key/genre:}\n" "METADATA_DATE=${metadata/by-key/date:}\n" "METADATA_TRACK=${metadata/by-key/track:}\n" "METADATA_COPYRIGHT=${metadata/by-key/copyright:}\n" "INFO_MEDIA_TITLE=${=media-title:}\n" "INFO_STREAM_PATH=${stream-path}\n"; //#ifndef Q_OS_WIN arg << "--audio-client-name=KylinVideo"; //#endif //#ifdef CUSTOM_STATUS arg << "--term-status-msg=STATUS: ${=time-pos} / ${=duration:${=length:0}} P: ${=pause} B: ${=paused-for-cache} I: ${=core-idle} VB: ${=video-bitrate:0} AB: ${=audio-bitrate:0}"; //#endif //qDebug() << "MPVProcess::setMedia file=" << media; if (is_playlist) { arg << "--playlist=" + media; } else { arg << media; } //#ifdef CAPTURE_STREAM // capturing = false; //#endif } void MPVProcess::setFixedOptions() { arg << "--no-config"; arg << "--no-quiet"; arg << "--terminal"; arg << "--no-msg-color"; arg << "--input-file=/dev/stdin"; arg << "--msg-level=ffmpeg/demuxer=error"; //TODO static QStringList option_list; InfoReader * ir = InfoReader::obj(this->m_snap, executable()); ir->getInfo(); option_list = ir->optionList(); if (option_list.contains("--gpu-context")) { arg << "--gpu-context=x11egl"; } //arg << "--no-osc"; //arg << "--msg-level=vd=v"; //arg << "--video-stereo-mode=no"; } void MPVProcess::disableInput() { arg << "--no-input-default-bindings"; if (isOptionAvailable("--input-vo-keyboard")) { arg << "--input-vo-keyboard=no"; } else { arg << "--input-x11-keyboard=no"; } arg << "--no-input-cursor"; arg << "--cursor-autohide=no"; } bool MPVProcess::isOptionAvailable(const QString & option) { static QStringList option_list; static QString mpv_bin; if (option_list.isEmpty() || mpv_bin != executable()) { InfoReader * ir = InfoReader::obj(this->m_snap, executable()); ir->getInfo(); option_list = ir->optionList(); mpv_bin = executable(); //qDebug() << "MPVProcess::isOptionAvailable: option_list:" << option_list; } return option_list.contains(option); /*InfoReader * ir = InfoReader::obj(this->m_snap, executable());//20181212 ir->getInfo(); //qDebug() << "MPVProcess::isOptionAvailable: option_list:" << ir->optionList(); return ir->optionList().contains(option);*/ } void MPVProcess::addVFIfAvailable(const QString & vf, const QString & value) { InfoReader * ir = InfoReader::obj(this->m_snap, executable());//20181212 ir->getInfo(); if (ir->vfList().contains(vf)) { QString s = "--vf-add=" + vf; if (!value.isEmpty()) s += "=" + value; arg << s; } else { QString f = vf +"="+ value; qDebug("MPVProcess::addVFIfAvailable: filter %s is not used because it's not available", f.toLatin1().constData()); } } void MPVProcess::messageFilterNotSupported(const QString & filter_name) { QString text = QString(tr("the '%1' filter is not supported by mpv").arg(filter_name)); writeToStdin(QString("show_text \"%1\" 3000").arg(text)); } void MPVProcess::enableScreenshots(const QString & dir, const QString & templ, const QString & format) { if (!templ.isEmpty()) { arg << "--screenshot-template=" + templ; } if (!format.isEmpty()) { arg << "--screenshot-format=" + format; } if (!dir.isEmpty()) { QString d = QDir::toNativeSeparators(dir); if (!isOptionAvailable("--screenshot-directory")) { qDebug() << "MPVProcess::enableScreenshots: the option --screenshot-directory is not available in this version of mpv"; qDebug() << "MPVProcess::enableScreenshots: changing working directory to" << d; setWorkingDirectory(d); } else { arg << "--screenshot-directory=" + d; } } } void MPVProcess::setOption(const QString & option_name, const QVariant & value) { if (option_name == "cache") { int cache = value.toInt(); if (cache > 31) { if (isOptionAvailable("--demuxer-max-bytes")) { int bytes = value.toString().toInt() * 1024; arg << "--demuxer-max-bytes=" + QString::number(bytes); } else { arg << "--cache=" + value.toString(); } } else { arg << "--cache=no"; } } else if (option_name == "cache_auto") { arg << "--cache=auto"; } else if (option_name == "ss") { arg << "--start=" + value.toString(); } else if (option_name == "endpos") { arg << "--length=" + value.toString(); } else if (option_name == "loop") { QString loop = "--loop"; if (isOptionAvailable("--loop-file")) loop = "--loop-file"; QString o = value.toString(); if (o == "0") o = "inf"; arg << loop + "=" + o; } else if (option_name == "ass") { arg << "--sub-ass"; } else if (option_name == "noass") { arg << "--no-sub-ass"; } else if (option_name == "sub-fuzziness") { QString v; switch (value.toInt()) { case 1: v = "fuzzy"; break; case 2: v = "all"; break; default: v = "exact"; } arg << "--sub-auto=" + v; } else if (option_name == "audiofile") { arg << "--audio-file=" + value.toString(); } else if (option_name == "delay") { arg << "--audio-delay=" + value.toString(); } else if (option_name == "subdelay") { arg << "--sub-delay=" + value.toString(); } else if (option_name == "sub") { arg << "--sub-file=" + value.toString(); } else if (option_name == "subpos") { arg << "--sub-pos=" + value.toString(); } else if (option_name == "font") { arg << "--osd-font=" + value.toString(); } else if (option_name == "subcp") { QString cp = value.toString(); if (!cp.startsWith("enca")) cp = "utf8:" + cp; arg << "--sub-codepage=" + cp; } else if (option_name == "osd-level") { arg << "--osd-level=" + value.toString(); } else if (option_name == "osd-fractions") { bool use_fractions = value.toBool(); if (use_fractions) arg << "--osd-fractions"; } else if (option_name == "osd-bar-pos") { if (isOptionAvailable("--osd-bar-align-y")) { if (value.toInt() >= 0 && value.toInt() <= 100) { double position = double (value.toInt() * 2 - 100) / 100; arg << "--osd-bar-align-y=" + QString::number(position); } } } else if (option_name == "sws") { arg << "--sws-scaler=lanczos"; } else if (option_name == "channels") { arg << "--audio-channels=" + value.toString(); } else if (option_name == "subfont-text-scale" || option_name == "ass-font-scale") { arg << "--sub-scale=" + value.toString(); } else if (option_name == "ass-line-spacing") { QString line_spacing = "--ass-line-spacing"; if (isOptionAvailable("--sub-ass-line-spacing")) line_spacing = "--sub-ass-line-spacing"; arg << line_spacing + "=" + value.toString(); } else if (option_name == "ass-force-style") { QString ass_force_style = "--ass-force-style"; if (isOptionAvailable("--sub-ass-force-style")) ass_force_style = "--sub-ass-force-style"; arg << ass_force_style + "=" + value.toString(); } else if (option_name == "stop-xscreensaver") { bool stop_ss = value.toBool(); if (stop_ss) arg << "--stop-screensaver"; else arg << "--no-stop-screensaver"; } else if (option_name == "correct-pts") { bool b = value.toBool(); if (b) arg << "--correct-pts"; else arg << "--no-correct-pts"; } else if (option_name == "idx") { arg << "--index=default"; } else if (option_name == "softvol") { if (value.toString() == "off") { if (isOptionAvailable("--volume-max")) { arg << "--volume-max=100"; } } else { int v = value.toInt(); if (v < 100) v = 100; if (isOptionAvailable("--volume-max")) { arg << "--volume-max=" + QString::number(v); } else { arg << "--softvol=yes"; arg << "--softvol-max=" + QString::number(v); } } } else if (option_name == "subfps") { arg << "--sub-fps=" + value.toString(); } else if (option_name == "forcedsubsonly") { arg << "--sub-forced-only"; } else if (option_name == "prefer-ipv4" || option_name == "prefer-ipv6" || option_name == "dr" || option_name == "double" || option_name == "adapter" || option_name == "edl" || option_name == "slices" || option_name == "colorkey" || option_name == "subcc" || option_name == "vobsub" || option_name == "zoom" || option_name == "flip-hebrew" || option_name == "autoq") { // Ignore } else if (option_name == "tsprog") { // Unsupported } else if (option_name == "dvdangle") { /* arg << "--dvd-angle=" + value.toString(); */ } else if (option_name == "threads") { arg << "--vd-lavc-threads=" + value.toString(); } else if (option_name == "skiploopfilter") { arg << "--vd-lavc-skiploopfilter=all"; } else if (option_name == "keepaspect" || option_name == "fs") { bool b = value.toBool(); if (b) arg << "--" + option_name; else arg << "--no-" + option_name; } else if (option_name == "vo") { QString vo = value.toString(); if (vo.endsWith(",")) vo.chop(1); // #ifndef Q_OS_WIN if (isOptionAvailable("--xv-adaptor")) { QRegExp rx("xv:adaptor=(\\d+)"); if (rx.indexIn(vo) > -1) { QString adaptor = rx.cap(1); vo = "xv"; arg << "--xv-adaptor=" + adaptor; } } // #endif // Remove options (used by mplayer) int pos = vo.indexOf(":"); if (pos > -1) vo = vo.left(pos); if (vo == "gl") vo = "opengl"; arg << "--vo=" + vo + ","; } else if (option_name == "ao") { QString ao = value.toString(); QStringList l; if (ao.contains(":")) l = DeviceInfo::extractDevice(ao); if (l.count() > 0) ao = l[0]; if (isOptionAvailable("--audio-device")) { if (l.count() == 3) { // #ifndef Q_OS_WIN if (l[0] == "pulse") { arg << "--audio-device=pulse/" + l[2]; } // #if USE_MPV_ALSA_DEVICES // else // if (l[0] == "alsa") { // arg << "--audio-device=alsa/" + l[1]; // } // #endif // #else // if (l[0] == "dsound") { // arg << "--audio-device=dsound/" + l[1]; // } // else // if (l[0] == "wasapi") { // arg << "--audio-device=wasapi/" + l[1]; // } // #endif } } else { // #ifndef Q_OS_WIN if (l.count() > 1) { if (l[0] == "alsa") { ao = "alsa:device=[hw:" + l[1] + "]"; } else if (l[0] == "pulse") { ao = "pulse::" + l[1]; } } // #endif } // Remove options (used by mplayer) int pos = ao.indexOf(":"); if (pos > -1) ao = ao.left(pos); arg << "--ao=" + ao + ","; } else if (option_name == "vc") { qDebug() << "MPVProcess::setOption: video codec ignored"; } else if (option_name == "ac") { qDebug() << "MPVProcess::setOption: audio codec ignored"; } else if (option_name == "afm") { QString s = value.toString(); if (s == "hwac3") arg << "--audio-spdif=ac3,dts-hd,truehd"; } else if (option_name == "enable_streaming_sites_support") { if (isOptionAvailable("--ytdl")) { if (value.toBool()) arg << "--ytdl"; else arg << "--ytdl=no"; } } else if (option_name == "ytdl_quality") { if (isOptionAvailable("--ytdl-format")) { QString quality = value.toString(); if (!quality.isEmpty()) arg << "-ytdl-format=" + quality; } } else if (option_name == "fontconfig") { if (isOptionAvailable("--use-text-osd")) { bool b = value.toBool(); if (b) arg << "--use-text-osd=yes"; else arg << "--use-text-osd=no"; } } else if (option_name == "verbose") { arg << "-v"; verbose = true; } else if (option_name == "mute") { arg << "--mute=yes"; } else if (option_name == "scaletempo") { if (isOptionAvailable("--audio-pitch-correction")) { bool enabled = value.toBool(); if (enabled) arg << "--audio-pitch-correction=yes"; else arg << "--audio-pitch-correction=no"; } } else if (option_name == "vf-add") { if (!value.isNull()) arg << "--vf-add=" + value.toString(); } else if (option_name == "af-add") { if (!value.isNull()) arg << "--af-add=" + value.toString(); } else if (option_name == "aid" || option_name == "sid" || option_name == "secondary-sid" || option_name == "vid") { int v = value.toInt(); arg << QString("--%1=%2").arg(option_name).arg(v > -1 ? value.toString() : "no"); } else if (option_name == "wid" || option_name == "alang" || option_name == "slang" || option_name == "volume" || option_name == "ass-styles" || option_name == "embeddedfonts" || option_name == "osd-scale" || option_name == "speed" || option_name == "contrast" || option_name == "brightness" || option_name == "hue" || option_name == "saturation" || option_name == "gamma" || option_name == "monitorpixelaspect" || option_name == "monitoraspect" || option_name == "mc" || option_name == "framedrop" || option_name == "priority" || option_name == "hwdec" || option_name == "autosync" || option_name == "dvd-device" || option_name == "cdrom-device" || option_name == "demuxer" || option_name == "frames" || option_name == "user-agent" || option_name == "referrer" || option_name == "ab-loop-a" || option_name == "ab-loop-b") { QString s = "--" + option_name; if (!value.isNull()) s += "=" + value.toString(); arg << s; } else { qDebug() << "MPVProcess::setOption: unknown option:" << option_name; } } void MPVProcess::addUserOption(const QString & option) { //qDebug() << "MPVProcess::addUserOption:" << option; // Remove quotes QString s = option; if (s.count("=\"") == 1 && s.endsWith("\"")) { s.replace("=\"", "="); s.chop(1); } else if (s.startsWith("\"") && s.endsWith("\"")) { s.remove(0, 1); s.chop(1); } //qDebug() << "MPVProcess::addUserOption: s:" << s; arg << s; if (option == "-v") { verbose = true; } } void MPVProcess::setSubEncoding(const QString & codepage, const QString & enca_lang) { Q_UNUSED(enca_lang) if (!codepage.isEmpty()) { arg << "--sub-codepage=" + codepage; } } void MPVProcess::addVF(const QString & filter_name, const QVariant & value) { QString option = value.toString(); QString lavfi_filter = lavfi(filter_name, value); if (!lavfi_filter.isEmpty()) { arg << "--vf-add=" + lavfi_filter; } else //USE_LETTERBOX: 2 LETTERBOX_OLD: 1 /*#if USE_LETTERBOX == LETTERBOX_OLD if (filter_name == "letterbox") { QSize desktop_size = value.toSize(); double aspect = (double) desktop_size.width() / desktop_size.height(); arg << "--vf-add=" + QString("expand=aspect=%1").arg(aspect); } else #endif*/ if ((filter_name == "harddup") || (filter_name == "hue")) { // ignore } else /* if (filter_name == "eq2") { #ifdef USE_OLD_VIDEO_EQ arg << "--vf-add=eq"; #else arg << "--vf-add=@eq:lavfi=[eq]"; #endif } else */ if (filter_name == "subs_on_screenshots") { // Ignore } else { if (filter_name == "pp") { QString s; if (option.isEmpty()) s = "[pp]"; else s = "[pp=" + option + "]"; addVFIfAvailable("lavfi", s); } else { QString s = filter_name; if (!option.isEmpty()) s += "=" + option; arg << "--vf-add=" + s; } } } void MPVProcess::addStereo3DFilter(const QString & in, const QString & out) { QString input; if (!in.isEmpty()) input = "in=" + in + ":"; QString output; if (!out.isEmpty()) output = "out=" + out; arg << "--vf-add=lavfi=[stereo3d=" + input + output + "]"; } void MPVProcess::setVideoEqualizerOptions(int contrast, int brightness, int hue, int saturation, int gamma, bool soft_eq) { //#ifndef USE_OLD_VIDEO_EQ use_soft_eq = soft_eq; //#endif if (soft_eq) { // #ifdef USE_OLD_VIDEO_EQ // arg << "--vf-add=lavfi=[eq]"; // #else current_soft_eq = SoftVideoEq(contrast, brightness, hue, saturation, gamma); QString f = videoEqualizerFilter(current_soft_eq); arg << "--vf-add=" + f; previous_soft_eq = current_soft_eq; // #endif } //#ifndef USE_OLD_VIDEO_EQ else //#endif { if (contrast != 0) arg << "--contrast=" + QString::number(contrast); if (brightness != 0) arg << "--brightness=" + QString::number(brightness); if (hue != 0) arg << "--hue=" + QString::number(hue); if (saturation != 0) arg << "--saturation=" + QString::number(saturation); if (gamma != 0) arg << "--gamma=" + QString::number(gamma); } } void MPVProcess::addAF(const QString & filter_name, const QVariant & value) { QString option = value.toString(); // filter_name = "equalizer" QString lavfi_filter = lavfi(filter_name, value); if (!lavfi_filter.isEmpty()) { arg << "--af-add=" + lavfi_filter; } else if (filter_name == "volnorm") { QString s = "drc"; if (!option.isEmpty()) s += "=" + option; arg << "--af-add=" + s; } else if (filter_name == "channels") { if (option == "2:2:0:1:0:0") arg << "--af-add=channels=2:[0-1,0-0]"; else if (option == "2:2:1:0:1:1") arg << "--af-add=channels=2:[1-0,1-1]"; else if (option == "2:2:0:1:1:0") arg << "--af-add=channels=2:[0-1,1-0]"; } else if (filter_name == "pan") { if (option == "1:0.5:0.5") { arg << "--af-add=pan=1:[0.5,0.5]"; } } else if (filter_name == "equalizer") { //这里设置错误将导致播放无声音,且音量调整无效 // for ubuntukylin 16.04 /*previous_eq = option; arg << "--af-add=equalizer=" + option;*/ // for ubuntukylin 20.04 AudioEqualizerList al = value.toList(); QString f = audioEqualizerFilter(al);//lavfi=[firequalizer=gain='cubic_interpolate(f)':zero_phase=on:wfunc=tukey:delay=0.027:gain_entry='entry(0,0);entry(62.5,0);entry(125,0);entry(250,0);entry(500,0);entry(1000,0);entry(2000,0);entry(4000,0);entry(8000,0);entry(16000,0)'] arg << "--af-add=" + f; previous_eq = f; previous_eq_list = al; } else if (filter_name == "extrastereo" || filter_name == "karaoke") { //Not supported anymore //Ignore } else { qDebug() << "MPVProcess::addAF 444444"; QString s = filter_name; if (!option.isEmpty()) s += "=" + option; arg << "--af-add=" + s; } /* //20.04之前的系统,在使用mpv播放时需要使用以下代码,否则播放无声音,且音量调整无效 QString option = value.toString(); qDebug() << "MPVProcess::addAF filter_name:" << filter_name << ", option:" << option; // filter_name = "equalizer" if (filter_name == "volnorm") { qDebug() << "MPVProcess::addAF 0000"; QString s = "drc"; if (!option.isEmpty()) s += "=" + option; arg << "--af-add=" + s; } else if (filter_name == "channels") { qDebug() << "MPVProcess::addAF 1111"; if (option == "2:2:0:1:0:0") arg << "--af-add=channels=2:[0-1,0-0]"; else if (option == "2:2:1:0:1:1") arg << "--af-add=channels=2:[1-0,1-1]"; else if (option == "2:2:0:1:1:0") arg << "--af-add=channels=2:[0-1,1-0]"; } else if (filter_name == "pan") { qDebug() << "MPVProcess::addAF 2222222222222"; if (option == "1:0.5:0.5") { arg << "--af-add=pan=1:[0.5,0.5]"; } } else if (filter_name == "equalizer") { qDebug() << "MPVProcess::addAF 333333333333"; previous_eq = option; arg << "--af-add=equalizer=" + option; } else if (filter_name == "extrastereo" || filter_name == "karaoke") { //Not supported anymore //Ignore } else { qDebug() << "MPVProcess::addAF 444444"; QString s = filter_name; if (!option.isEmpty()) s += "=" + option; arg << "--af-add=" + s; } */ //20.04系统,在使用mpv播放时需要使用以下代码,否则播放无声音,且音量调整无效 /* QString option = value.toString(); QString lavfi_filter = lavfi(filter_name, value); if (!lavfi_filter.isEmpty()) { arg << "--af-add=" + lavfi_filter; } else if (filter_name == "equalizer") { AudioEqualizerList al = value.toList(); QString f = audioEqualizerFilter(al); arg << "--af-add=" + f; previous_eq = f; previous_eq_list = al; } else { QString s = filter_name; if (!option.isEmpty()) s += "=" + option; arg << "--af-add=" + s; } */ } /*void MPVProcess::addAF(const QString & filter_name, const QVariant & value) { QString option = value.toString(); QString lavfi_filter = lavfi(filter_name, value); if (!lavfi_filter.isEmpty()) { arg << "--af-add=" + lavfi_filter; } else if (filter_name == "equalizer") { AudioEqualizerList al = value.toList(); QString f = audioEqualizerFilter(al);//20191206 导致mpv播放没有声音 arg << "--af-add=" + f; previous_eq = f; previous_eq_list = al; } else { QString s = filter_name; if (!option.isEmpty()) s += "=" + option; arg << "--af-add=" + s; } }*/ void MPVProcess::quit() { writeToStdin("quit 0"); } void MPVProcess::setVolume(int v) { writeToStdin("set volume " + QString::number(v)); } void MPVProcess::setOSD(int o) { // writeToStdin("osd " + QString::number(o)); writeToStdin("no-osd set osd-level " + QString::number(o)); } void MPVProcess::setAudio(int ID) { // writeToStdin("set aid " + QString::number(ID)); writeToStdin(QString("%1 set aid %2").arg(OSD_PREFIX).arg(ID)); } void MPVProcess::setVideo(int ID) { // writeToStdin("set vid " + QString::number(ID)); writeToStdin(QString("%1 set vid %2").arg(OSD_PREFIX).arg(ID)); } void MPVProcess::setSubtitle(int type, int ID) { Q_UNUSED(type); writeToStdin(QString("%1 set sid %2").arg(OSD_PREFIX).arg(ID)); // writeToStdin("set sid " + QString::number(ID)); } void MPVProcess::disableSubtitles() { // writeToStdin("set sid no"); writeToStdin("no-osd set sid no"); } void MPVProcess::setSecondarySubtitle(int ID) { // writeToStdin("set secondary-sid " + QString::number(ID)); writeToStdin(QString("%1 set secondary-sid %2").arg(OSD_PREFIX).arg(ID)); } void MPVProcess::disableSecondarySubtitles() { // writeToStdin("set secondary-sid no"); writeToStdin("no-osd set secondary-sid no"); } void MPVProcess::setSubtitlesVisibility(bool b) { // writeToStdin(QString("set sub-visibility %1").arg(b ? "yes" : "no")); writeToStdin(QString("no-osd set sub-visibility %1").arg(b ? "yes" : "no")); } void MPVProcess::seek(double secs, int mode, bool precise) { QString s = "seek " + QString::number(secs) + " "; switch (mode) { case 0 : s += "relative "; break; case 1 : s += "absolute-percent "; break; case 2 : s += "absolute "; break; } if (precise) s += "exact"; else s += "keyframes"; //qDebug() << "*****************MPVProcess::seek="<stop(); //#endif showOSDText("${filename}", duration, 0);//writeToStdin("show_text \"${filename}\" 2000 0"); } void MPVProcess::showMediaInfoOnOSD() { //#ifdef OSD_WITH_TIMER toggleInfoOnOSD(); //#else // showOSDText("${filename}", 2000, 0); //#endif } void MPVProcess::showTimeOnOSD() { //#ifdef OSD_WITH_TIMER osd_timer->stop(); //#endif writeToStdin("show_text \"${time-pos} ${?duration:/ ${duration} (${percent-pos}%)}\" 2000 0"); } //#ifdef OSD_WITH_TIMER void MPVProcess::toggleInfoOnOSD() { if (!osd_timer->isActive()) { osd_timer->start(); displayInfoOnOSD(); } else { osd_timer->stop(); showOSDText("", 100, 0); } } void MPVProcess::displayInfoOnOSD() { QString b1 = "{\\\\b1}"; QString b0 = "{\\\\b0}"; QString tab = "\\\\h\\\\h\\\\h\\\\h\\\\h"; QString nl = "\\n"; QString s = "${osd-ass-cc/0}{\\\\fs14}" + b1 + tr("File:") + b0 +" ${filename}" + nl + "${time-pos} ${?duration:/ ${duration} (${percent-pos}%)}" + nl + nl + //b1 + tr("Title:") + b0 + " ${media-title}" + nl + nl + b1 + tr("Video:") + b0 + " ${video-codec}" + nl + tab + b1 + tr("Resolution:") + b0 +" ${=width}x${=height}" + nl + tab + b1 + tr("Frames per second:") + b0 + " ${container-fps:${fps}} " + b1 + tr("Estimated:") + b0 + " ${estimated-vf-fps}" + nl + //tab + b1 + tr("Display FPS:") + b0 + " ${display-fps}" + nl + tab + b1 + tr("Aspect Ratio:") + b0 + " ${video-params/aspect}" + nl + tab + b1 + tr("Bitrate:") + b0 + " ${video-bitrate}" + nl + tab + b1 + tr("Dropped frames:") + b0 + " ${decoder-frame-drop-count:${drop-frame-count}}" + nl + nl + b1 + tr("Audio:") + b0 + " ${audio-codec}" + nl + tab + b1 + tr("Bitrate:") + b0 + " ${audio-bitrate}" + nl + tab + b1 + tr("Sample Rate:") + b0 + " ${audio-params/samplerate} Hz" + nl + tab + b1 + tr("Channels:") + b0 + " ${audio-params/channel-count}" + nl + nl + b1 + tr("Audio/video synchronization:") + b0 + " ${avsync}" + nl + b1 + tr("Cache fill:") + b0 + " ${cache:0}%" + nl + b1 + tr("Used cache:") + b0 + " ${cache-used:0}" + nl; if (!osd_media_info.isEmpty()) s = osd_media_info; showOSDText(s, 2000, 0); if (!isRunning()) osd_timer->stop(); } //#endif void MPVProcess::setContrast(int value) { //#ifndef USE_OLD_VIDEO_EQ if (use_soft_eq) { current_soft_eq.contrast = value; updateSoftVideoEqualizerFilter(); } else //#endif writeToStdin("set contrast " + QString::number(value)); } void MPVProcess::setBrightness(int value) { //#ifndef USE_OLD_VIDEO_EQ if (use_soft_eq) { current_soft_eq.brightness = value; updateSoftVideoEqualizerFilter(); } else //#endif writeToStdin("set brightness " + QString::number(value)); } void MPVProcess::setHue(int value) { //#ifndef USE_OLD_VIDEO_EQ if (use_soft_eq) { current_soft_eq.hue = value; updateSoftVideoEqualizerFilter(); } else //#endif writeToStdin("set hue " + QString::number(value)); } void MPVProcess::setSaturation(int value) { //#ifndef USE_OLD_VIDEO_EQ if (use_soft_eq) { current_soft_eq.saturation = value; updateSoftVideoEqualizerFilter(); } else //#endif writeToStdin("set saturation " + QString::number(value)); } void MPVProcess::setGamma(int value) { //#ifndef USE_OLD_VIDEO_EQ if (use_soft_eq) { current_soft_eq.gamma = value; updateSoftVideoEqualizerFilter(); } else //#endif writeToStdin("set gamma " + QString::number(value)); } void MPVProcess::setChapter(int ID) { writeToStdin("set chapter " + QString::number(ID)); } void MPVProcess::nextChapter() { writeToStdin("add chapter 1"); } void MPVProcess::previousChapter() { writeToStdin("add chapter -1"); } void MPVProcess::setExternalSubtitleFile(const QString & filename) { writeToStdin("sub_add \""+ filename +"\""); //writeToStdin("print_text ${track-list}"); writeToStdin("print_text \"INFO_TRACKS_COUNT=${=track-list/count}\""); } void MPVProcess::setSubPos(int pos) { writeToStdin("set sub-pos " + QString::number(pos)); } void MPVProcess::setSubScale(double value) { writeToStdin("set sub-scale " + QString::number(value)); } void MPVProcess::setSubStep(int value) { writeToStdin("sub_step " + QString::number(value)); } void MPVProcess::seekSub(int value) {//kobe 20170705 writeToStdin("sub-seek " + QString::number(value)); } void MPVProcess::setSubForcedOnly(bool b) { writeToStdin(QString("set sub-forced-only %1").arg(b ? "yes" : "no")); } void MPVProcess::setSpeed(double value) { writeToStdin("set speed " + QString::number(value)); } void MPVProcess::enableKaraoke(bool b) { changeAF("karaoke", b); //messageFilterNotSupported("karaoke"); } void MPVProcess::enableExtrastereo(bool b) { changeAF("extrastereo", b); } void MPVProcess::enableVolnorm(bool b, const QString & option) { changeAF("volnorm", b, option); } void MPVProcess::enableEarwax(bool b) { changeAF("earwax", b); } void MPVProcess::setAudioEqualizer(AudioEqualizerList l) { //TODO: previous_eq_list QString eq_filter = audioEqualizerFilter(l); if (previous_eq == eq_filter) return; if (!previous_eq.isEmpty()) { writeToStdin("af del \"" + previous_eq + "\""); } writeToStdin("af add \"" + eq_filter + "\""); previous_eq = eq_filter; } void MPVProcess::setAudioDelay(double delay) { writeToStdin("set audio-delay " + QString::number(delay)); } void MPVProcess::setSubDelay(double delay) { writeToStdin("set sub-delay " + QString::number(delay)); } void MPVProcess::setLoop(int v) { QString o; switch (v) { case -1: o = "no"; break; case 0: o = "inf"; break; default: o = QString::number(v); } // writeToStdin(QString("set loop %1").arg(o)); writeToStdin(QString("set loop-file %1").arg(o)); } void MPVProcess::setAMarker(int sec) { writeToStdin(QString("set ab-loop-a %1").arg(sec)); } void MPVProcess::setBMarker(int sec) { writeToStdin(QString("set ab-loop-b %1").arg(sec)); } void MPVProcess::clearABMarkers() { writeToStdin("set ab-loop-a no"); writeToStdin("set ab-loop-b no"); } void MPVProcess::takeScreenshot(ScreenshotType t, bool include_subtitles) {//20170722 // qDebug() << "MPVProcess::takeScreenshot"; writeToStdin(QString("screenshot %1 %2").arg(include_subtitles ? "subtitles" : "video").arg(t == Single ? "single" : "each-frame"));//cmd:screenshot video single } //#ifdef CAPTURE_STREAM //void MPVProcess::switchCapturing() { // if (!capture_filename.isEmpty()) { // if (!capturing) { // QString f = capture_filename; //// #ifdef Q_OS_WIN //// // I hate Windows //// f = f.replace("\\", "\\\\"); //// #endif // writeToStdin("set stream-capture \"" + f + "\""); // } else { // writeToStdin("set stream-capture \"\""); // } // capturing = !capturing; // } //} //#endif void MPVProcess::setTitle(int ID) { writeToStdin("set disc-title " + QString::number(ID)); } //#if DVDNAV_SUPPORT //void MPVProcess::discSetMousePos(int x, int y) { // qDebug("MPVProcess::discSetMousePos: %d %d", x, y); // //writeToStdin(QString("discnav mouse_move %1 %2").arg(x).arg(y)); // // mouse_move doesn't accept options :? // // For some reason this doesn't work either... // // So it's not possible to select options in the dvd menus just // // because there's no way to pass the mouse position to mpv, or it // // ignores it. // writeToStdin(QString("mouse %1 %2").arg(x).arg(y)); // //writeToStdin("discnav mouse_move"); //} //void MPVProcess::discButtonPressed(const QString & button_name) { // writeToStdin("discnav " + button_name); //} //#endif void MPVProcess::setAspect(double aspect) { writeToStdin("set video-aspect " + QString::number(aspect)); } void MPVProcess::setFullscreen(bool b) { writeToStdin(QString("set fullscreen %1").arg(b ? "yes" : "no")); } void MPVProcess::toggleDeinterlace() { writeToStdin("cycle deinterlace"); } void MPVProcess::askForLength() { writeToStdin("print_text \"INFO_LENGTH=${=length}\""); } void MPVProcess::setOSDScale(double value) { writeToStdin("set osd-scale " + QString::number(value)); } void MPVProcess::setOSDFractions(bool active) { writeToStdin(QString("no-osd set osd-fractions %1").arg(active ? "yes" : "no")); } void MPVProcess::changeVF(const QString & filter, bool enable, const QVariant & option) { QString f; QString lavfi_filter = lavfi(filter, option); if (!lavfi_filter.isEmpty()) { f = lavfi_filter; } //USE_LETTERBOX: 2 LETTERBOX_OLD: 1 /*#if USE_LETTERBOX == LETTERBOX_OLD else if (filter == "letterbox") { QSize desktop_size = option.toSize(); double aspect = (double) desktop_size.width() / desktop_size.height(); f = QString("expand=aspect=%1").arg(aspect); } #endif*/ else { qDebug() << "MPVProcess::changeVF: unknown filter:" << filter; } if (!f.isEmpty()) { writeToStdin(QString("vf %1 \"%2\"").arg(enable ? "add" : "del").arg(f)); } } void MPVProcess::changeAF(const QString & filter, bool enable, const QVariant & option) { //qDebug() << "MPVProcess::changeAF:" << filter << enable; QString f; QString lavfi_filter = lavfi(filter, option); if (!lavfi_filter.isEmpty()) { f = lavfi_filter; } if (!f.isEmpty()) { writeToStdin(QString("af %1 \"%2\"").arg(enable ? "add" : "del").arg(f)); } } void MPVProcess::changeStereo3DFilter(bool enable, const QString & in, const QString & out) { // QString filter = "stereo3d=" + in + ":" + out; // writeToStdin(QString("vf %1 \"%2\"").arg(enable ? "add" : "del").arg(filter)); QString input; if (!in.isEmpty()) input = "in=" + in + ":"; QString output; if (!out.isEmpty()) output = "out=" + out; QString filter = "lavfi=[stereo3d=" + input + output + "]"; writeToStdin(QString("vf %1 \"%2\"").arg(enable ? "add" : "del").arg(filter)); } #define SUBOPTION(name, alternative1, alternative2) \ QString name; \ if (isOptionAvailable(alternative1)) name = alternative1; \ else \ if (isOptionAvailable(alternative2)) name = alternative2; void MPVProcess::setSubStyles(const AssStyles & styles, const QString &) { SUBOPTION(sub_font, "--sub-font", "--sub-text-font"); SUBOPTION(sub_color, "--sub-color", "--sub-text-color"); QString sub_shadow_color = "--sub-text-shadow-color"; if (isOptionAvailable("--sub-shadow-color")) sub_shadow_color = "--sub-shadow-color"; QString sub_back_color = "--sub-text-back-color"; if (isOptionAvailable("--sub-back-color")) sub_back_color = "--sub-back-color"; SUBOPTION(sub_border_color, "--sub-border-color", "--sub-text-border-color"); SUBOPTION(sub_border_size, "--sub-border-size", "--sub-text-border-size"); SUBOPTION(sub_shadow_offset, "--sub-shadow-offset", "--sub-text-shadow-offset"); SUBOPTION(sub_font_size, "--sub-font-size", "--sub-text-font-size"); SUBOPTION(sub_bold, "--sub-bold", "--sub-text-bold"); SUBOPTION(sub_italic, "--sub-italic", "--sub-text-italic"); SUBOPTION(sub_align_x, "--sub-align-x", "--sub-text-align-x"); SUBOPTION(sub_align_y, "--sub-align-y", "--sub-text-align-y"); QString sub_margin_y = ""; if (isOptionAvailable("--sub-margin-y")) sub_margin_y = "--sub-margin-y"; QString sub_margin_x = ""; if (isOptionAvailable("--sub-margin-x")) sub_margin_x = "--sub-margin-x"; if (!sub_font.isEmpty()) { QString font = styles.fontname; //arg << "--sub-text-font=" + font.replace(" ", ""); arg << sub_font + "=" + font; } if (!sub_color.isEmpty()) { arg << sub_color + "=#" + ColorUtils::colorToAARRGGBB(styles.primarycolor); } arg << sub_shadow_color + "=#" + ColorUtils::colorToAARRGGBB(styles.backcolor); if (styles.borderstyle == AssStyles::Opaque) { arg << sub_back_color + "=#" + ColorUtils::colorToAARRGGBB(styles.backgroundcolor); } if (!sub_border_color.isEmpty()) { arg << sub_border_color + "=#" + ColorUtils::colorToAARRGGBB(styles.outlinecolor); } if (!sub_border_size.isEmpty()) { arg << sub_border_size + "=" + QString::number(styles.outline * 2.5); } if (!sub_shadow_offset.isEmpty()) { arg << sub_shadow_offset + "=" + QString::number(styles.shadow * 2.5); } if (!sub_font_size.isEmpty()) { arg << sub_font_size + "=" + QString::number(styles.fontsize * 2.5); } if (!sub_bold.isEmpty()) { arg << QString("%1=%2").arg(sub_bold).arg(styles.bold ? "yes" : "no"); } if (!sub_italic.isEmpty()) { arg << QString("%1=%2").arg(sub_italic).arg(styles.italic ? "yes" : "no"); } QString halign; switch (styles.halignment) { case AssStyles::Left: halign = "left"; break; case AssStyles::Right: halign = "right"; break; } QString valign; switch (styles.valignment) { case AssStyles::VCenter: valign = "center"; break; case AssStyles::Top: valign = "top"; break; } if (!sub_align_x.isEmpty() && !halign.isEmpty()) { arg << sub_align_x + "=" + halign; } if (!sub_align_y.isEmpty() && !valign.isEmpty()) { arg << sub_align_y + "=" + valign; } if (!sub_margin_y.isEmpty()) { int marginv = styles.marginv; if (marginv < 0) marginv = 0; arg << sub_margin_y + "=" + QString::number(marginv); } if (!sub_margin_x.isEmpty()) { int marginx = styles.marginl; if (marginx < 0) marginx = 0; arg << sub_margin_x + "=" + QString::number(marginx); } } void MPVProcess::setChannelsFile(const QString & filename) { arg << "--dvbin-file=" + filename; } QString MPVProcess::lavfi(const QString & filter_name, const QVariant & option) { QString f; if (filter_name == "flip") { f = "vflip"; } else if (filter_name == "mirror") { f = "hflip"; } else if (filter_name == "noise") { f = "noise=alls=9:allf=t"; } else if (filter_name == "blur") { f = "unsharp=la=-1.5:ca=-1.5"; } else if (filter_name == "sharpen") { f = "unsharp=la=1.5:ca=1.5"; } else if (filter_name == "deblock") { f = "pp=" + option.toString(); } else if (filter_name == "dering") { f = "pp=dr"; } else if (filter_name == "postprocessing") { f = "pp"; } else if (filter_name == "lb" || filter_name == "l5") { f = "pp=" + filter_name; } else if (filter_name == "yadif") { if (option.toString() == "1") { f = "yadif=mode=send_field"; } else { f = "yadif=mode=send_frame"; } } else if (filter_name == "scale" || filter_name == "gradfun" || filter_name == "hqdn3d" || filter_name == "kerndeint" || filter_name == "phase" || filter_name == "extrastereo" || filter_name == "earwax") { f = filter_name; QString o = option.toString(); if (!o.isEmpty()) f += "=" + o; } else if (filter_name == "letterbox") { QSize desktop_size = option.toSize(); //USE_LETTERBOX: 2 LETTERBOX_OLD: 1 LETTERBOX_PAD_WITH_ASPECT: 3 LETTERBOX_PAD: 2 // #if USE_LETTERBOX == LETTERBOX_PAD_WITH_ASPECT // double aspect = (double) desktop_size.width() / desktop_size.height(); // f = QString("pad=aspect=%1:x=(ow-iw)/2:y=(oh-ih)/2").arg(aspect); // #endif // #if USE_LETTERBOX == LETTERBOX_PAD //f = QString("pad=ih*%1/%2:ih:(ow-iw)/2:(oh-ih)/2").arg(desktop_size.width()).arg(desktop_size.height()); f = QString("pad=iw:iw*sar/%1*%2:0:(oh-ih)/2").arg(desktop_size.width()).arg(desktop_size.height()); // #endif } else if (filter_name == "rotate") { QString o = option.toString(); if (o == "0") { f = "rotate=3*PI/2:ih:iw,vflip"; } else if (o == "1") { f = "rotate=PI/2:ih:iw"; // 90º } else if (o == "2") { f = "rotate=3*PI/2:ih:iw"; // 270º } else if (o == "3") { f = "rotate=PI/2:ih:iw,vflip"; } } else if (filter_name == "volnorm") { f = "acompressor"; QString o = option.toString(); if (!o.isEmpty()) f += "=" + o; } else if (filter_name == "karaoke") { f = "stereotools=mlev=0.015625"; } else if (filter_name == "stereo-mode") { QString o = option.toString(); if (o == "left") f = "pan=mono|c0=c0"; else if (o == "right") f = "pan=mono|c0=c1"; else if (o == "reverse") f = "pan=stereo|c0=c1|c1=c0"; else if (o == "mono") f = "pan=mono|c0=.5*c0+.5*c1"; } if (!f.isEmpty()) f = "lavfi=[" + f + "]"; return f; } QString MPVProcess::audioEqualizerFilter(AudioEqualizerList l) { //USE_EQUALIZER: 2 EQ_FIREQUALIZER:2 EQ_FIREQUALIZER_LIST: 3 EQ_FEQUALIZER: 5 EQ_OLD: 0 EQ_ANEQUALIZER: 1 EQ_SUPEREQUALIZER: 4 QString f; QString values = AudioEqualizerHelper::equalizerListToString(l, AudioEqualizerHelper::Firequalizer); f = "lavfi=[firequalizer=gain='cubic_interpolate(f)':zero_phase=on:wfunc=tukey:delay=0.027:" + values + "]"; return f; } QString MPVProcess::videoEqualizerFilter(SoftVideoEq eq) { QString f; double brightness = (double) eq.brightness / 100; double contrast = (double) (eq.contrast + 100) / 100; double saturation = qMax(0.0, (double) (eq.saturation + 50) / 50); double gamma = qMax(0.1, (double) (eq.gamma + (100/9)) / (100/9)); f = QString("%1:%2:%3:%4").arg(contrast).arg(brightness).arg(saturation).arg(gamma); f += ",hue=h=" + QString::number(eq.hue); f = "lavfi=[eq=" + f + "]"; return f; } void MPVProcess::updateSoftVideoEqualizerFilter() { QString f = videoEqualizerFilter(previous_soft_eq); writeToStdin("vf del \"" + f + "\""); f = videoEqualizerFilter(current_soft_eq); writeToStdin("vf add \"" + f + "\""); previous_soft_eq = current_soft_eq; } kylin-video/src/smplayer/tristatecombo.cpp0000644000175000017500000000661413517016402017744 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "tristatecombo.h" #include TristateCombo::TristateCombo( QWidget * parent ) : QComboBox(parent) { retranslateStrings(); this->setStyleSheet("QComboBox{width:150px;height:24px;border:1px solid #000000;background:#0f0f0f;font-size:12px;font-family:方正黑体_GBK;background-position:center left;padding-left:5px;color:#999999;selection-color:#ffffff;selection-background-color:#1f1f1f;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox::drop-down {width:17px;border:none;background:transparent;}QComboBox::drop-down:hover {background:transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView{border:1px solid #0a9ff5;background:#262626;outline:none;}"); // this->setStyleSheet("QComboBox{width:150px;height:24px;border: 1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:enabled {background:#0f0f0f;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox:enabled:hover, QComboBox:enabled:focus {color: #1f1f1f;}QComboBox::drop-down {width: 17px;border: none;background: transparent;}QComboBox::drop-down:hover {background: transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView {border: 1px solid #0a9ff5;background: #1f1f1f;outline: none;}"); } TristateCombo::~TristateCombo() { } void TristateCombo::retranslateStrings() { int i = currentIndex(); clear(); addItem( tr("Auto"), Preferences::Detect ); addItem( tr("Yes"), Preferences::Enabled ); addItem( tr("No"), Preferences::Disabled ); setCurrentIndex(i); } void TristateCombo::setState( Preferences::OptionState v ) { setCurrentIndex( findData(v) ); } Preferences::OptionState TristateCombo::state() { return (Preferences::OptionState) itemData( currentIndex() ).toInt(); } // Language change stuff void TristateCombo::changeEvent(QEvent *e) { if (e->type() == QEvent::LanguageChange) { retranslateStrings(); } else { QComboBox::changeEvent(e); } } //#include "moc_tristatecombo.cpp" kylin-video/src/smplayer/playlist-org.h0000644000175000017500000001214613517016402017155 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _PLAYLIST_H_ #define _PLAYLIST_H_ #include #include #include #include #include #include #include "../smplayer/mediadata.h" class MyAction; class Core; class QMenu; class QSettings; class QToolButton; class QTimer; class PlayListItem; class PlayListView; class QListWidgetItem; class QPushButton; class QLabel; class QHBoxLayout; class Playlist : public QFrame { Q_OBJECT public: enum AutoGetInfo { NoGetInfo = 0, GetInfo = 1, UserDefined = 2 }; Playlist( Core *c, QWidget * parent = 0, Qt::WindowFlags f = Qt::Window); ~Playlist(); void clear(); int count(); bool isEmpty(); bool isModified() { return modified; }; //0606 void setTransparent(bool transparent); void set_widget_opacity(const float &opacity=0.8); void setViewHeight(); protected: void paintEvent(QPaintEvent *event); public slots: void addOneItem(QString filename, QString name, double duration); // Start playing, from item 0 if shuffle is off, or from // a random item otherwise void startPlayPause(); void playItem(int n); virtual void playNext(); virtual void playPrev(); virtual void resumePlay(); virtual void removeTheSelected(); virtual void removeSelected(QString filename); virtual void removeAll(); virtual void onPlayListItemDeleteBtnClicked(QString filename); virtual void moveItemUp(int); virtual void moveItemDown(int); virtual void popupDialogtoSelectFiles(); virtual void addDirectory(); virtual void addFile(QString file, AutoGetInfo auto_get_info = UserDefined); virtual void addFiles(QStringList files, AutoGetInfo auto_get_info = UserDefined); // Adds a directory, no recursive virtual void addOneDirectory(QString dir); // Adds a directory, maybe with recursion (depends on user config) virtual void addDirectory(QString dir); // EDIT BY NEO --> // virtual void sortBy(int section); // <-- virtual void deleteSelectedFileFromDisk(); virtual void getMediaInfo(); void setModified(bool); void slot_listview_current_item_changed(QListWidgetItem * current, QListWidgetItem * previous); void slot_doubleclicked_resource(QString filename); void doubleclicked(QListWidgetItem *item); signals: void playlistEnded(); void visibilityChanged(bool visible); void sig_playing_title(QString title); void update_playlist_count(int count); void closePlaylist(); void playListFinishedWithError(QString errorStr); void showMessage(QString text); void finish_list(); protected: void updateView(); void setListCurrentItem(int current); void clearPlayedTag(); int chooseRandomItem(); void swapItems(int item1, int item2 ); // EDIT BY NEO --> // void sortBy(int section, bool revert, int count); // <-- QString lastDir(); protected slots: virtual void playCurrent(); virtual void itemDoubleClicked(int row); virtual void showPopupMenu(const QPoint & pos); virtual void upItem(); virtual void downItem(); virtual void editCurrentItem(); virtual void editItem(int item); virtual void saveSettings(); virtual void loadSettings(); virtual void maybeSaveSettings(); void getMediaInfo(const MediaData &); void playerFailed(QProcess::ProcessError); void playerFinishedWithError(int); protected: void createNoVideo(); void createTable(); void createToolbar(); protected: virtual void dragEnterEvent( QDragEnterEvent * ) ; virtual void dropEvent ( QDropEvent * ); virtual void hideEvent ( QHideEvent * ); virtual void showEvent ( QShowEvent * ); virtual void closeEvent( QCloseEvent * e ); protected: QList pl; int current_item; QString playlist_path; QString playlist_load_latest_dir; Core * core; QMenu * popup; QFrame *noVideoFrame; QLabel *novideo_icon; QLabel *novideo_text; QPushButton *add_Btn; PlayListView *listView; QLabel *titleLabel; QFrame *btAddFrame; QPushButton *btDel; QPushButton *btAdd; MyAction * playAct; MyAction * removeSelectedAct; MyAction * deleteSelectedFileFromDiskAct; private: bool modified; QTimer * save_timer; int row_spacing; bool automatically_play_next; QHBoxLayout *title_layout; }; #endif kylin-video/src/smplayer/paths.h0000644000175000017500000000271613517016402015650 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _PATHS_H_ #define _PATHS_H_ #include class Paths { public: static void setAppPath(QString path); static QString appPath(); static QString translationPath(); static QString shortcutsPath(); static QString qtTranslationPath(); //! Forces to use a different path for the config files static void setConfigPath(QString path); //! Return the path where smplayer should save its config files static QString configPath(); //! Obsolete. Just returns configPath() static QString iniPath(); static QString subtitleStyleFile(); private: static QString app_path; static QString config_path; }; #endif kylin-video/src/smplayer/prefperformance.cpp0000644000175000017500000002645113637124037020253 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "prefperformance.h" #include "../smplayer/images.h" #include "../smplayer/global.h" #include "../smplayer/preferences.h" #include using namespace Global; PrefPerformance::PrefPerformance(QWidget * parent, Qt::WindowFlags f) : PrefWidget(parent, f ) { setupUi(this); hwdec_combo->addItem(tr("None"), "no"); hwdec_combo->addItem(tr("Auto"), "auto"); hwdec_combo->addItem("auto-copy", "auto-copy"); hwdec_combo->addItem("vdpau", "vdpau"); hwdec_combo->addItem("vdpau-copy", "vdpau-copy"); hwdec_combo->addItem("vaapi", "vaapi"); hwdec_combo->addItem("vaapi-copy", "vaapi-copy"); //hwdec_combo->addItem("rkmpp-copy", "rkmpp-copy"); hwdec_combo->addItem("cuda", "cuda"); hwdec_combo->addItem("cuda-copy", "cuda-copy"); hwdec_combo->addItem("crystalhd", "crystalhd"); retranslateStrings(); } PrefPerformance::~PrefPerformance() { } void PrefPerformance::setCurrentPage(int index) { } QString PrefPerformance::sectionName() { return tr("Performance"); } QPixmap PrefPerformance::sectionIcon() { return Images::icon("pref_performance", 22); } void PrefPerformance::retranslateStrings() { retranslateUi(this); groupBox_cache->setStyleSheet("QGroupBox{border:none;margin-top:20px;font-size:14px;}QGroupBox:title{subcontrol-origin: margin;subcontrol-position: top left;padding: 0px 1px;color: #999999;font-family: 方正黑体_GBK;font-weight:bold;}"); groupBox_decode->setStyleSheet("QGroupBox{border:none;margin-top:20px;font-size:14px;}QGroupBox:title{subcontrol-origin: margin;subcontrol-position: top left;padding: 0px 1px;color: #999999;font-family: 方正黑体_GBK;font-weight:bold;}"); cache_streams_spin->setStyleSheet("QSpinBox {height: 24px;min-width: 40px;border: 1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QSpinBox:hover {height: 24px;min-width: 40px;background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QSpinBox:enabled {color: #999999;}QSpinBox:enabled:hover, QSpinBox:enabled:focus {color: #999999;}QSpinBox:!enabled {color: #383838;background: transparent;}QSpinBox::up-button {border: none;width: 17px;height: 12px;image: url(:/res/spin_top_arrow_normal.png);}QSpinBox::up-button:hover {image: url(:/res/spin_top_arrow_hover.png);}QSpinBox::up-button:pressed {image: url(:/res/spin_top_arrow_press.png);}QSpinBox::up-button:!enabled {background: transparent;}QSpinBox::up-button:enabled:hover {background: rgb(255, 255, 255, 30);}QSpinBox::down-button {border: none;width: 17px;height: 12px;image: url(:/res/spin_bottom_arrow_normal.png);}QSpinBox::down-button:hover {image: url(:/res/spin_bottom_arrow_hover.png);}QSpinBox::down-button:pressed {image: url(:/res/spin_bottom_arrow_press.png);}QSpinBox::down-button:!enabled {background: transparent;}QSpinBox::down-button:hover{background: #0f0f0f;}"); cache_files_spin->setStyleSheet("QSpinBox {height: 24px;min-width: 40px;border: 1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QSpinBox:hover {height: 24px;min-width: 40px;background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QSpinBox:enabled {color: #999999;}QSpinBox:enabled:hover, QSpinBox:enabled:focus {color: #999999;}QSpinBox:!enabled {color: #383838;background: transparent;}QSpinBox::up-button {border: none;width: 17px;height: 12px;image: url(:/res/spin_top_arrow_normal.png);}QSpinBox::up-button:hover {image: url(:/res/spin_top_arrow_hover.png);}QSpinBox::up-button:pressed {image: url(:/res/spin_top_arrow_press.png);}QSpinBox::up-button:!enabled {background: transparent;}QSpinBox::up-button:enabled:hover {background: rgb(255, 255, 255, 30);}QSpinBox::down-button {border: none;width: 17px;height: 12px;image: url(:/res/spin_bottom_arrow_normal.png);}QSpinBox::down-button:hover {image: url(:/res/spin_bottom_arrow_hover.png);}QSpinBox::down-button:pressed {image: url(:/res/spin_bottom_arrow_press.png);}QSpinBox::down-button:!enabled {background: transparent;}QSpinBox::down-button:hover{background: #0f0f0f;}"); threads_spin->setStyleSheet("QSpinBox {height: 24px;min-width: 40px;border: 1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QSpinBox:hover {height: 24px;min-width: 40px;background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QSpinBox:enabled {color: #999999;}QSpinBox:enabled:hover, QSpinBox:enabled:focus {color: #999999;}QSpinBox:!enabled {color: #383838;background: transparent;}QSpinBox::up-button {border: none;width: 17px;height: 12px;image: url(:/res/spin_top_arrow_normal.png);}QSpinBox::up-button:hover {image: url(:/res/spin_top_arrow_hover.png);}QSpinBox::up-button:pressed {image: url(:/res/spin_top_arrow_press.png);}QSpinBox::up-button:!enabled {background: transparent;}QSpinBox::up-button:enabled:hover {background: rgb(255, 255, 255, 30);}QSpinBox::down-button {border: none;width: 17px;height: 12px;image: url(:/res/spin_bottom_arrow_normal.png);}QSpinBox::down-button:hover {image: url(:/res/spin_bottom_arrow_hover.png);}QSpinBox::down-button:pressed {image: url(:/res/spin_bottom_arrow_press.png);}QSpinBox::down-button:!enabled {background: transparent;}QSpinBox::down-button:hover{background: #0f0f0f;}"); hwdec_combo->setStyleSheet("QComboBox{width:150px;height:24px;border:1px solid #000000;background:#0f0f0f;font-size:12px;font-family:方正黑体_GBK;background-position:center left;padding-left:5px;color:#999999;selection-color:#ffffff;selection-background-color:#1f1f1f;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox::drop-down {width:17px;border:none;background:transparent;}QComboBox::drop-down:hover {background:transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView{border:1px solid #0a9ff5;background:#262626;outline:none;}"); // hwdec_combo->setStyleSheet("QComboBox{width:150px;height:24px;border: 1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:enabled {background:#0f0f0f;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox:enabled:hover, QComboBox:enabled:focus {color: #1f1f1f;}QComboBox::drop-down {width: 17px;border: none;background: transparent;}QComboBox::drop-down:hover {background: transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView {border: 1px solid #0a9ff5;background: #1f1f1f;outline: none;}"); cache_local_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); cache_streams_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); kb_local_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); kb_streams_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); thread_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); hd_decode_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); createHelp(); } void PrefPerformance::setData(Preferences * pref) { setCacheForFiles( pref->cache_for_files ); setCacheForStreams( pref->cache_for_streams ); setThreads(pref->threads); setHwdec(pref->hwdec); } void PrefPerformance::getData(Preferences * pref) { requires_restart = false; TEST_AND_SET(pref->cache_for_files, cacheForFiles()); TEST_AND_SET(pref->cache_for_streams, cacheForStreams()); TEST_AND_SET(pref->threads, threads()); TEST_AND_SET(pref->hwdec, hwdec()); } void PrefPerformance::setCacheForFiles(int n) { cache_files_spin->setValue(n); } int PrefPerformance::cacheForFiles() { return cache_files_spin->value(); } void PrefPerformance::setCacheForStreams(int n) { cache_streams_spin->setValue(n); } int PrefPerformance::cacheForStreams() { return cache_streams_spin->value(); } void PrefPerformance::setThreads(int v) { threads_spin->setValue(v); } int PrefPerformance::threads() { return threads_spin->value(); } void PrefPerformance::setHwdec(const QString & v) { int idx = hwdec_combo->findData(v); if (idx < 0) idx = 0; hwdec_combo->setCurrentIndex(idx); } QString PrefPerformance::hwdec() { int idx = hwdec_combo->currentIndex(); return hwdec_combo->itemData(idx).toString(); } void PrefPerformance::createHelp() { clearHelp(); addSectionTitle(tr("Performance")); setWhatsThis(threads_spin, tr("Threads for decoding"), tr("Sets the number of threads to use for decoding. Only for " "MPEG-1/2 and H.264") ); setWhatsThis(hwdec_combo, tr("Hardware decoding"), tr("Sets the hardware video decoding API. " "If hardware decoding is not possible, software decoding will be used instead.") + " " + tr("Available options:") + "
      " "
    • " + tr("None: only software decoding will be used.") + "
    • " "
    • " + tr("Auto: it tries to automatically enable hardware decoding using the first available method.") + "
    • " #ifdef Q_OS_LINUX "
    • " + tr("vdpau: for the vdpau and opengl video outputs.") + "
    • " "
    • " + tr("vaapi: for the opengl and vaapi video outputs. For Intel GPUs only.") + "
    • " "
    • " + tr("vaapi-copy: it copies video back into system RAM. For Intel GPUs only.") + "
    • " #endif "
    " + tr("This option only works with mpv.")); addSectionTitle(tr("Cache")); setWhatsThis(cache_files_spin, tr("Cache for files"), tr("This option specifies how much memory (in kBytes) to use when " "precaching a file.") ); setWhatsThis(cache_streams_spin, tr("Cache for streams"), tr("This option specifies how much memory (in kBytes) to use when " "precaching a URL.") ); } //#include "moc_prefperformance.cpp" kylin-video/src/smplayer/myprocess.h0000644000175000017500000000441613524205650016557 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MY_PROCESS_H_ #define _MY_PROCESS_H_ #include #include #include //! MyProcess is a specialized QProcess designed to properly work with mplayer. class MyProcess : public QProcess { Q_OBJECT public: MyProcess ( QObject * parent = 0 ); virtual void setExecutable(const QString & p) { program = p; }; QString executable() { return program; }; virtual void addArgument(const QString & a); //!< Add an argument void clearArguments(); //!< Clear the list of arguments QStringList arguments(); //!< Return the list of arguments void start(); //!< Start the process bool isRunning(); //!< Return true if the process is running static QStringList splitArguments(const QString & args); signals: //! Emitted when there's a line available void lineAvailable(QByteArray ba); protected slots: void readStdOut(); //!< Called for reading from standard output // void readTmpFile(); //!< Called for reading from the temp file void procFinished(); //!< Called when the process has finished protected: //! Return true if it's possible to read an entire line. /*! @param from specifies the position to begin. */ int canReadLine(const QByteArray & ba, int from = 0); //! Called from readStdOut() and readTmpFile() to do all the work void genericRead(QByteArray buffer); protected: QString program; QStringList arg; QByteArray remaining_output; // QTemporaryFile temp_file; QTimer timer; }; #endif kylin-video/src/smplayer/prefsubtitles.h0000644000175000017500000000354313517016402017423 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _PREFSUBTITLES_H_ #define _PREFSUBTITLES_H_ #include "ui_prefsubtitles.h" #include "../smplayer/prefwidget.h" class Preferences; class Encodings; class PrefSubtitles : public PrefWidget, public Ui::PrefSubtitles { Q_OBJECT public: PrefSubtitles( QWidget * parent = 0, Qt::WindowFlags f = 0 ); ~PrefSubtitles(); virtual QString sectionName(); virtual QPixmap sectionIcon(); // Pass data to the dialog void setData(Preferences * pref); // Apply changes void getData(Preferences * pref); public slots: void setCurrentPage(int index); protected: virtual void createHelp(); void setFontEncoding(QString s); QString fontEncoding(); void setUseEnca(bool v); bool useEnca(); void setEncaLang(QString s); QString encaLang(); void setFreetypeSupport(bool b); bool freetypeSupport(); protected: virtual void retranslateStrings(); private: Encodings * encodings; QString forced_ass_style; }; #endif kylin-video/src/smplayer/infofile.h0000644000175000017500000000337013517016402016321 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef INFOFILE_H #define INFOFILE_H #include "mediadata.h" #include "tracks.h" #include "subtracks.h" #include #include #define INFO_SIMPLE_LAYOUT class InfoFile/* : public QObject*/ { // Q_OBJECT public: InfoFile(/*QObject * parent = 0*/); ~InfoFile(); QString getInfo(MediaData md, Tracks videos, Tracks audios, SubTracks subs); protected: QString title(QString text, QString icon);//QString title(QString text); QString openPar(QString text); QString closePar(); QString openItem(); QString closeItem(); QString addTrackColumns(QStringList l); QString addItem( QString tag, QString value ); QString addTrack(int n, QString lang, QString name, int ID, QString type = ""); QString defaultStyle(); int row; private: inline QString kylin_tr( const char * sourceText, const char * comment = 0, int n = -1 ); #ifndef INFO_SIMPLE_LAYOUT int row; #endif }; #endif kylin-video/src/smplayer/filedialog.cpp0000644000175000017500000000464613517016402017167 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "filedialog.h" #include bool MyFileDialog::use_native_dialog = true; QString MyFileDialog::getOpenFileName( QWidget * parent, const QString & caption, const QString & dir, const QString & filter, QString * selectedFilter, QFileDialog::Options options ) { if (!use_native_dialog) options |= QFileDialog::DontUseNativeDialog; return QFileDialog::getOpenFileName( parent, caption, dir, filter, selectedFilter, options ); } QString MyFileDialog::getExistingDirectory ( QWidget * parent, const QString & caption, const QString & dir, QFileDialog::Options options ) { if (!use_native_dialog) options |= QFileDialog::DontUseNativeDialog; return QFileDialog::getExistingDirectory( parent, caption, dir, options ); } QString MyFileDialog::getSaveFileName ( QWidget * parent, const QString & caption, const QString & dir, const QString & filter, QString * selectedFilter, QFileDialog::Options options ) { if (!use_native_dialog) options |= QFileDialog::DontUseNativeDialog; return QFileDialog::getSaveFileName( parent, caption, dir, filter, selectedFilter, options ); } QStringList MyFileDialog::getOpenFileNames ( QWidget * parent, const QString & caption, const QString & dir, const QString & filter, QString * selectedFilter, QFileDialog::Options options ) { if (!use_native_dialog) options |= QFileDialog::DontUseNativeDialog; return QFileDialog::getOpenFileNames( parent, caption, dir, filter, selectedFilter, options ); } kylin-video/src/smplayer/screensaver.h0000644000175000017500000000271413517016402017047 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ //! This class disables and restores the windows screensaver #ifndef _WINSCREENSAVER_H_ #define _WINSCREENSAVER_H_ #ifdef Q_OS_OS2 #include #else #undef _WIN32_WINNT #define _WIN32_WINNT 0x0501 #endif class WinScreenSaver { public: WinScreenSaver(); ~WinScreenSaver(); void disable(); void enable(); private: void retrieveState(); void restoreState(); #ifdef Q_OS_OS2 void unload(); #endif private: #ifndef Q_OS_OS2 int lowpower, poweroff, screensaver; #else QLibrary *SSaver; typedef int (*FuncPtr) (void); FuncPtr SSCore_TempDisable; FuncPtr SSCore_TempEnable; #endif bool state_saved, modified; }; #endif kylin-video/src/smplayer/colorutils.h0000644000175000017500000000434313517016402016726 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _COLORUTILS_H_ #define _COLORUTILS_H_ #include class QWidget; class QColor; class ColorUtils { public: //! Returns a string suitable to be used for -ass-color // static QString colorToRRGGBBAA(unsigned int color); // static QString colorToRRGGBB(unsigned int color); //! Returns a string suitable to be used for -colorkey // static QString colorToRGB(unsigned int color); // static QString colorToAABBGGRR(unsigned int color); //! Changes the foreground color of the specified widget static void setForegroundColor(QWidget * w, const QColor & color); //! Changes the background color of the specified widget static void setBackgroundColor(QWidget * w, const QColor & color); /** ** \brief Strip colors and tags from MPlayer output lines ** ** Some MPlayer configurations (configured with --enable-color-console) ** use colored/tagged console output. This function removes those colors ** and tags. ** ** \param s The string to strip colors and tags from ** \return Returns a clean string (no colors, no tags) */ static QString stripColorsTags(QString s); static QString colorToRGB(QColor c); static QString colorToRRGGBBAA(QColor c); static QString colorToRRGGBB(QColor c); static QString colorToAABBGGRR(QColor c); static QString colorToAARRGGBB(QColor c); static QColor AARRGGBBToColor(const QString & s); }; #endif kylin-video/src/smplayer/prefvideo.h0000644000175000017500000000453413517016402016514 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _PREFVIDEO_H_ #define _PREFVIDEO_H_ #include "ui_prefvideo.h" #include "../smplayer/prefwidget.h" #include "../smplayer/inforeader.h" #include "../smplayer/deviceinfo.h" #include "../smplayer/preferences.h" class PrefVideo : public PrefWidget, public Ui::PrefVideo { Q_OBJECT public: PrefVideo(QString arch_type = "", QString snap = "", QWidget * parent = 0, Qt::WindowFlags f = 0 ); ~PrefVideo(); // Pass data to the dialog void setData(Preferences * pref); // Apply changes void getData(Preferences * pref); bool fileSettingsMethodChanged() { return filesettings_method_changed; }; protected: virtual void createHelp(); void setVO( QString vo_driver ); QString VO(); // Tab video and audio void setEq2(bool b); bool eq2(); void setInitialPostprocessing(bool b); bool initialPostprocessing(); void setDirectRendering(bool b); bool directRendering(); void setDoubleBuffer(bool b); bool doubleBuffer(); void setUseSlices(bool b); bool useSlices(); void setAmplification(int n); int amplification(); void setAudioChannels(int ID); int audioChannels(); protected slots: void vo_combo_changed(int); public slots: void update_driver_combobox(); protected: virtual void retranslateStrings(); void updateDriverCombos(); InfoList vo_list; DeviceList alsa_devices; DeviceList xv_adaptors; private: bool filesettings_method_changed; QString arch; QString m_snap; }; #endif kylin-video/src/smplayer/filesettingsbase.h0000644000175000017500000000255413517016402020064 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2018 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef FILESETTINGS_BASE_H #define FILESETTINGS_BASE_H #include class MediaSettings; class FileSettingsBase { public: FileSettingsBase(QString directory) { output_directory = directory; }; virtual ~FileSettingsBase() {}; virtual bool existSettingsFor(QString filename, int type) = 0; virtual void loadSettingsFor(QString filename, int type, MediaSettings & mset, int player) = 0; virtual void saveSettingsFor(QString filename, int type, MediaSettings & mset, int player) = 0; protected: QString output_directory; }; #endif kylin-video/src/smplayer/prefperformance.h0000644000175000017500000000345413517016402017707 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _PREFPERFORMANCE_H_ #define _PREFPERFORMANCE_H_ #include "ui_prefperformance.h" #include "../smplayer/prefwidget.h" #include "../smplayer/preferences.h" class PrefPerformance : public PrefWidget, public Ui::PrefPerformance { Q_OBJECT public: PrefPerformance( QWidget * parent = 0, Qt::WindowFlags f = 0 ); ~PrefPerformance(); virtual QString sectionName(); virtual QPixmap sectionIcon(); // Pass data to the dialog void setData(Preferences * pref); // Apply changes void getData(Preferences * pref); public slots: void setCurrentPage(int index); protected: virtual void createHelp(); void setCacheForFiles(int n); int cacheForFiles(); void setCacheForStreams(int n); int cacheForStreams(); void setThreads(int v); int threads(); void setHwdec(const QString & v); QString hwdec(); protected: virtual void retranslateStrings(); }; #endif kylin-video/src/smplayer/audiodelaydialog.ui0000644000175000017500000000460313637124061020220 0ustar fengfeng AudioDelayDialog 0 0 380 170 380 170 380 170 Audio delay 160 130 91 25 OK 260 130 91 25 Cancel 344 0 36 36 95 10 191 20 Audio delay Qt::AlignCenter 30 50 341 20 Audio delay (in milliseconds): 30 80 320 27 -3600000 3600000 kylin-video/src/smplayer/prefshortcut.ui0000644000175000017500000000425413517016402017446 0ustar fengfeng PrefShortCut 0 0 470 360 9 6 451 51 6 0 0 0 0 0 0 Here you can change any key shortcut. To do it double click or press enter over a shortcut cell. Qt::AlignVCenter true 5 59 460 301 0 0 ActionsEditor QWidget
    ../smplayer/actionseditor.h
    kylin-video/src/smplayer/shortcutgetter.cpp0000644000175000017500000004316713637124061020163 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Note: The ShortcutGetter class is taken from the source code of Edyuk (http://www.edyuk.org/), from file 3rdparty/qcumber/qshortcutdialog.cpp Copyright (C) 2006 FullMetalCoder License: GPL I modified it to support multiple shortcuts and some other few changes. */ /**************************************************************************** ** ** Copyright (C) 2006 FullMetalCoder ** ** This file is part of the Edyuk project (beta version) ** ** This file may be used under the terms of the GNU General Public License ** version 2 as published by the Free Software Foundation and appearing in the ** file GPL.txt included in the packaging of this file. ** ** Notes : Parts of the project are derivative work of Trolltech's QSA library ** or Trolltech's Qt4 framework but, unless notified, every single line of code ** is the work of the Edyuk team or a contributor. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ****************************************************************************/ #include "shortcutgetter.h" #include "images.h" #include #include #include #include #include #include #include #include #include #include #if 1 static QHash keyMap; static void initKeyMap() { if ( !keyMap.isEmpty() ) return; /* I'm a bit unsure about these one... */ keyMap[Qt::Key_Escape] = "Escape"; keyMap[Qt::Key_Return] = "Return"; keyMap[Qt::Key_Enter] = "Enter"; keyMap[Qt::Key_Insert] = "Ins"; keyMap[Qt::Key_Delete] = "Delete"; keyMap[Qt::Key_Home] = "Home"; keyMap[Qt::Key_End] = "End"; keyMap[Qt::Key_Left] = "Left"; keyMap[Qt::Key_Up] = "Up"; keyMap[Qt::Key_Right] = "Right"; keyMap[Qt::Key_Down] = "Down"; keyMap[Qt::Key_PageUp] = "PgUp"; keyMap[Qt::Key_PageDown] = "PgDown"; keyMap[Qt::Key_CapsLock] = "CapsLock"; keyMap[Qt::Key_NumLock] = "NumLock"; keyMap[Qt::Key_ScrollLock] = "ScrollLock"; /* These one are quite sure... */ keyMap[Qt::Key_F1] = "F1"; keyMap[Qt::Key_F2] = "F2"; keyMap[Qt::Key_F3] = "F3"; keyMap[Qt::Key_F4] = "F4"; keyMap[Qt::Key_F5] = "F5"; keyMap[Qt::Key_F6] = "F6"; keyMap[Qt::Key_F7] = "F7"; keyMap[Qt::Key_F8] = "F8"; keyMap[Qt::Key_F9] = "F9"; keyMap[Qt::Key_F10] = "F10"; keyMap[Qt::Key_F11] = "F11"; keyMap[Qt::Key_F12] = "F12"; keyMap[Qt::Key_F13] = "F13"; keyMap[Qt::Key_F14] = "F14"; keyMap[Qt::Key_F15] = "F15"; keyMap[Qt::Key_F16] = "F16"; keyMap[Qt::Key_F17] = "F17"; keyMap[Qt::Key_F18] = "F18"; keyMap[Qt::Key_F19] = "F19"; keyMap[Qt::Key_F20] = "F20"; keyMap[Qt::Key_F21] = "F21"; keyMap[Qt::Key_F22] = "F22"; keyMap[Qt::Key_F23] = "F23"; keyMap[Qt::Key_F24] = "F24"; keyMap[Qt::Key_F25] = "F25"; keyMap[Qt::Key_F26] = "F26"; keyMap[Qt::Key_F27] = "F27"; keyMap[Qt::Key_F28] = "F28"; keyMap[Qt::Key_F29] = "F29"; keyMap[Qt::Key_F30] = "F30"; keyMap[Qt::Key_F31] = "F31"; keyMap[Qt::Key_F32] = "F32"; keyMap[Qt::Key_F33] = "F33"; keyMap[Qt::Key_F34] = "F34"; keyMap[Qt::Key_F35] = "F35"; keyMap[Qt::Key_Exclam] = "!"; keyMap[Qt::Key_QuoteDbl] = "\""; keyMap[Qt::Key_NumberSign] = "-"; keyMap[Qt::Key_Dollar] = "$"; keyMap[Qt::Key_Percent] = "%"; keyMap[Qt::Key_Ampersand] = "&"; keyMap[Qt::Key_Apostrophe] = "\'"; keyMap[Qt::Key_ParenLeft] = "("; keyMap[Qt::Key_ParenRight] = ")"; keyMap[Qt::Key_Asterisk] = "*"; keyMap[Qt::Key_Plus] = "+"; keyMap[Qt::Key_Comma] = ","; keyMap[Qt::Key_Minus] = "-"; keyMap[Qt::Key_Period] = "Period"; keyMap[Qt::Key_Slash] = "/"; keyMap[Qt::Key_0] = "0"; keyMap[Qt::Key_1] = "1"; keyMap[Qt::Key_2] = "2"; keyMap[Qt::Key_3] = "3"; keyMap[Qt::Key_4] = "4"; keyMap[Qt::Key_5] = "5"; keyMap[Qt::Key_6] = "6"; keyMap[Qt::Key_7] = "7"; keyMap[Qt::Key_8] = "8"; keyMap[Qt::Key_9] = "9"; keyMap[Qt::Key_Colon] = ":"; keyMap[Qt::Key_Semicolon] = ";"; keyMap[Qt::Key_Less] = "<"; keyMap[Qt::Key_Equal] = "="; keyMap[Qt::Key_Greater] = ">"; keyMap[Qt::Key_Question] = "?"; keyMap[Qt::Key_At] = "@"; keyMap[Qt::Key_A] = "A"; keyMap[Qt::Key_B] = "B"; keyMap[Qt::Key_C] = "C"; keyMap[Qt::Key_D] = "D"; keyMap[Qt::Key_E] = "E"; keyMap[Qt::Key_F] = "F"; keyMap[Qt::Key_G] = "G"; keyMap[Qt::Key_H] = "H"; keyMap[Qt::Key_I] = "I"; keyMap[Qt::Key_J] = "J"; keyMap[Qt::Key_K] = "K"; keyMap[Qt::Key_L] = "L"; keyMap[Qt::Key_M] = "M"; keyMap[Qt::Key_N] = "N"; keyMap[Qt::Key_O] = "O"; keyMap[Qt::Key_P] = "P"; keyMap[Qt::Key_Q] = "Q"; keyMap[Qt::Key_R] = "R"; keyMap[Qt::Key_S] = "S"; keyMap[Qt::Key_T] = "T"; keyMap[Qt::Key_U] = "U"; keyMap[Qt::Key_V] = "V"; keyMap[Qt::Key_W] = "W"; keyMap[Qt::Key_X] = "X"; keyMap[Qt::Key_Y] = "Y"; keyMap[Qt::Key_Z] = "Z"; keyMap[Qt::Key_BracketLeft] = "["; keyMap[Qt::Key_Backslash] = "\\"; keyMap[Qt::Key_BracketRight] = "]"; keyMap[Qt::Key_Underscore] = "_"; keyMap[Qt::Key_BraceLeft] = "{"; keyMap[Qt::Key_Bar] = "|"; keyMap[Qt::Key_BraceRight] = "}"; keyMap[Qt::Key_AsciiTilde] = "~"; // Added by rvm: keyMap[Qt::Key_Space] = "Space"; keyMap[Qt::Key_Backspace] = "Backspace"; keyMap[Qt::Key_MediaPlay] = "Media Play"; keyMap[Qt::Key_MediaStop] = "Media Stop"; keyMap[Qt::Key_MediaPrevious] = "Media Previous"; keyMap[Qt::Key_MediaNext] = "Media Next"; keyMap[Qt::Key_MediaRecord] = "Media Record"; keyMap[Qt::Key_MediaLast] = "Media Last"; // doesn't work? keyMap[Qt::Key_VolumeUp] = "Volume Up"; keyMap[Qt::Key_VolumeDown] = "Volume Down"; keyMap[Qt::Key_VolumeMute] = "Volume Mute"; keyMap[Qt::Key_Back] = "Back"; keyMap[Qt::Key_Forward] = "Forward"; keyMap[Qt::Key_Stop] = "Stop"; } static QString keyToString(int k) { if ( k == Qt::Key_Shift || k == Qt::Key_Control || k == Qt::Key_Meta || k == Qt::Key_Alt || k == Qt::Key_AltGr ) return QString::null; initKeyMap(); qDebug() << "========keyToString========"; return keyMap[k]; } #else static QString keyToString(int k) { if ( k == Qt::Key_Shift || k == Qt::Key_Control || k == Qt::Key_Meta || k == Qt::Key_Alt || k == Qt::Key_AltGr ) return QString::null; return QKeySequence(k).toString(); } #endif static QStringList modToString(Qt::KeyboardModifiers k) { //qDebug("modToString: k: %x", (int) k); QStringList l; if ( k & Qt::ShiftModifier ) l << "Shift"; if ( k & Qt::ControlModifier ) l << "Ctrl"; if ( k & Qt::AltModifier ) l << "Alt"; if ( k & Qt::MetaModifier ) l << "Meta"; if ( k & Qt::GroupSwitchModifier ) ; if ( k & Qt::KeypadModifier ) ; return l; } ShortcutGetter::ShortcutGetter(/*bool isbtn, */QWidget *parent) : QDialog(parent) , m_dragState(NOT_DRAGGING) , m_startDrag(QPoint(0,0)) { this->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint); this->setFixedSize(438, 320); this->setStyleSheet("QDialog{border: 1px solid #121212;border-radius:1px;background-color:#1f1f1f;}"); this->setWindowIcon(QIcon::fromTheme("kylin-video", QIcon(":/res/kylin-video.png"))); // this->setWindowIcon(QIcon::fromTheme("kylin-video", QIcon(":/res/kylin-video.png")).pixmap(QSize(64, 64)).scaled(64, 64, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); this->setAutoFillBackground(true); this->setMouseTracking(true); setWindowTitle(tr("Modify shortcut")); QVBoxLayout *vbox = new QVBoxLayout(this); vbox->setMargin(2); vbox->setSpacing(10); vbox->setContentsMargins(5,5,5,5); closeBtn = new QPushButton(this); closeBtn->setFixedSize(36, 36); closeBtn->setFocusPolicy(Qt::NoFocus); closeBtn->setStyleSheet("QPushButton{background-image:url(':/res/close_normal.png');border:0px;}QPushButton:hover{background:url(':/res/close_hover.png');}QPushButton:pressed{background:url(':/res/close_press.png');}"); vbox->addWidget(closeBtn, 0, Qt::AlignRight); // List and buttons added by rvm list = new QListWidget(this); list->setObjectName("ShortCutList"); connect(list, SIGNAL(currentRowChanged(int)), this, SLOT(rowChanged(int))); vbox->addWidget(list); QHBoxLayout *hbox = new QHBoxLayout; addItem = new QPushButton(/*Images::icon("plus"), "",*/ this); addItem->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); addItem->setFixedSize(40, 25); addItem->setFocusPolicy(Qt::NoFocus); addItem->setText("+"); addItem->setToolTip(tr("Add shortcut")); connect(addItem, SIGNAL(clicked()), this, SLOT(addItemClicked())); removeItem = new QPushButton(/*Images::icon("delete_normal"), "", */this); removeItem->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); removeItem->setFixedSize(40, 25); removeItem->setFocusPolicy(Qt::NoFocus); removeItem->setText("-"); removeItem->setToolTip(tr("Remove shortcut")); connect(removeItem, SIGNAL(clicked()), this, SLOT(removeItemClicked())); hbox->addSpacerItem(new QSpacerItem(20, 20, QSizePolicy::Expanding)); hbox->addWidget(addItem); hbox->addWidget(removeItem); vbox->addLayout(hbox); // if (isbtn) { // addItem->hide(); // removeItem->hide(); // } // else { // addItem->show(); // removeItem->show(); // } QLabel *l = new QLabel(this); l->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); l->setText(tr("Press the key combination you want to assign")); vbox->addWidget(l); leKey = new QLineEdit(this); leKey->setStyleSheet("QLineEdit {border:1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QLineEdit::hover{border: 1px solid #000000;background: #0a0a0a;font-family:方正黑体_GBK;font-size:12px;color:#ffffff;}QLineEdit:enabled {background: #0a0a0a;color:#999999;}QLineEdit:enabled:hover, QLineEdit:enabled:focus {background: #0a0a0a;color:#ffffff;}QLineEdit:!enabled {color: #383838;}"); // leKey->setStyleSheet("QLineEdit {height: 25px;border: 1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QLineEdit::hover{border: 1px solid #000000;background: #0a0a0a;font-family:方正黑体_GBK;font-size:12px;color:#ffffff;}QLineEdit:enabled {background: #0a0a0a;color:#999999;}QLineEdit:enabled:hover, QLineEdit:enabled:focus {background: #0a0a0a;color:#ffffff;}QLineEdit:!enabled {color: #383838;}"); connect(leKey, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged(const QString &))); leKey->installEventFilter(this); vbox->addWidget(leKey); // Change by rvm: use a QDialogButtonBox instead of QPushButtons // and add a clear button setCaptureKeyboard(true); QDialogButtonBox * buttonbox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Reset ); QPushButton * clearbutton = buttonbox->button(QDialogButtonBox::Reset); clearbutton->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); clearbutton->setFixedSize(91, 25); clearbutton->setText( tr("Clear") ); // clearbutton->setStyleSheet("QPushButton{font-size:12px;background:#ffffff;border:1px solid #0a9ff5;color:#000000;}QPushButton:hover{background-color:#ffffff;border:1px solid #3f96e4;color:#000000;} QPushButton:pressed{background-color:#ffffff;border:1px solid #3f96e4;color:#000000;}"); QPushButton * okbutton = buttonbox->button(QDialogButtonBox::Ok); okbutton->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); okbutton->setFixedSize(91, 25); okbutton->setText( tr("OK") ); QPushButton * cancelbutton = buttonbox->button(QDialogButtonBox::Cancel); cancelbutton->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #000000;color:#999999;}QPushButton:hover{background-color:#1f1f1f;border:1px solid #0f0f0f;color:#ffffff;} QPushButton:pressed{background-color:#0d0d0d;border:1px solid #000000;color:#ffffff;}"); cancelbutton->setFixedSize(91, 25); cancelbutton->setText(tr("Cancel")); QPushButton * captureButton = new QPushButton(tr("Capture"), this); captureButton->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); captureButton->setFixedSize(91, 25); captureButton->setToolTip(tr("Capture keystrokes") ); captureButton->setCheckable( captureKeyboard() ); captureButton->setChecked( captureKeyboard() ); connect(captureButton, SIGNAL(toggled(bool)), this, SLOT(setCaptureKeyboard(bool))); connect(closeBtn, SIGNAL(clicked(bool)), this, SLOT(reject())); buttonbox->addButton(captureButton, QDialogButtonBox::ActionRole); connect( buttonbox, SIGNAL(accepted()), this, SLOT(accept()) ); connect( buttonbox, SIGNAL(rejected()), this, SLOT(reject()) ); connect( clearbutton, SIGNAL(clicked()), leKey, SLOT(clear()) ); vbox->addWidget(buttonbox); } void ShortcutGetter::setCaptureKeyboard(bool b) { capture = b; leKey->setReadOnly(b); leKey->setFocus(); } // Added by rvm void ShortcutGetter::rowChanged(int row) { QString s = list->item(row)->text(); leKey->setText(s); leKey->setFocus(); } // Added by rvm void ShortcutGetter::textChanged(const QString & text) { list->item(list->currentRow())->setText(text); } // Added by rvm void ShortcutGetter::addItemClicked() { qDebug("ShortcutGetter::addItemClicked"); list->addItem(""); list->setCurrentRow( list->count()-1 ); // Select last item } // Added by rvm void ShortcutGetter::removeItemClicked() { qDebug("ShortcutGetter::removeItemClicked"); if (list->count() > 1) { QListWidgetItem * i = list->takeItem( list->currentRow() ); if (i) delete i; } else { list->setCurrentRow(0); leKey->setText(""); } } QString ShortcutGetter::exec(const QString& s) { // Added by rvm QStringList shortcuts = s.split(", "); QString shortcut; foreach(shortcut, shortcuts) { list->addItem(shortcut.trimmed()); } list->setCurrentRow(0); bStop = false; if (QDialog::exec() == QDialog::Accepted) { // Added by rvm QStringList l; for (int n = 0; n < list->count(); n++) { QString shortcut = list->item(n)->text(); if (!shortcut.isEmpty()) { //qDebug("ShortcutGetter::exec: shortcut: '%s'", shortcut.toUtf8().constData()); l << shortcut; } } QString res = l.join(", "); if (res.isNull()) res = ""; return res; } return QString(); } bool ShortcutGetter::event(QEvent *e) { if (!capture) return QDialog::event(e); QString key; QStringList mods; QKeyEvent *k = static_cast(e); switch ( e->type() ) { case QEvent::KeyPress : if ( bStop ) { lKeys.clear(); bStop = false; } key = keyToString(k->key()); mods = modToString(k->modifiers()); //qDebug("event: key.count: %d, mods.count: %d", key.count(), mods.count()); if ( key.count() || mods.count() ) { if ( key.count() && !lKeys.contains(key) ) lKeys << key; foreach ( key, mods ) if ( !lKeys.contains(key) ) lKeys << key; } else { key = k->text(); if ( !lKeys.contains(key) ) lKeys << key; } setText(); break; case QEvent::KeyRelease : bStop = true; break; /* case QEvent::ShortcutOverride : leKey->setText("Shortcut override"); break; */ default: return QDialog::event(e); break; } return true; } bool ShortcutGetter::eventFilter(QObject *o, QEvent *e) { if (!capture) return QDialog::eventFilter(o, e); if ( e->type() == QEvent::KeyPress || e->type() ==QEvent::KeyRelease ) return event(e); else return QDialog::eventFilter(o, e); } void ShortcutGetter::setText() { QStringList seq; if ( lKeys.contains("Shift") ) seq << "Shift"; if ( lKeys.contains("Ctrl") ) seq << "Ctrl"; if ( lKeys.contains("Alt") ) seq << "Alt"; if ( lKeys.contains("Meta") ) seq << "Meta"; foreach ( QString s, lKeys ) { //qDebug("setText: s: '%s'", s.toUtf8().data()); if ( s != "Shift" && s != "Ctrl" && s != "Alt" && s != "Meta" ) seq << s; } leKey->setText(seq.join("+")); //leKey->selectAll(); } kylin-video/src/smplayer/playlist-org.cpp0000644000175000017500000011375413517016402017517 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "playlist.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../smplayer/myaction.h" #include "../smplayer/filedialog.h" #include "../smplayer/helper.h" #include "../smplayer/preferences.h" #include "../smplayer/version.h" #include "../smplayer/global.h" #include "../smplayer/core.h" #include "../smplayer/extensions.h" #include "../kylin/playlistitem.h" #include "../kylin/playlistview.h" #include "../kylin/messagedialog.h" #include #include #include #include "../smplayer/infoprovider.h" using namespace Global; Playlist::Playlist(Core *c, QWidget * parent, Qt::WindowFlags f) : QFrame(parent, Qt::SubWindow) { this->setWindowFlags(Qt::FramelessWindowHint); this->setAutoFillBackground(true); this->setFixedWidth(220); setObjectName("PlaylistWidget"); setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred); setAcceptDrops(true); setAttribute(Qt::WA_NoMousePropagation); automatically_play_next = true; modified = false; core = c; playlist_path = ""; playlist_load_latest_dir = ""; titleLabel = 0; btDel = 0; btAdd = 0; novideo_icon = 0; novideo_text = 0; add_Btn = 0; title_layout = NULL; createNoVideo(); createTable(); createToolbar(); QVBoxLayout *layout = new QVBoxLayout(this); setFocusPolicy(Qt::ClickFocus); layout->setContentsMargins(0, 0, 0, 15); layout->setSpacing(16); btAddFrame = new QFrame; // btAddFrame->setFixedSize(156, 36); btAddFrame->setFixedSize(120, 36); btAddFrame->setObjectName("PlaylistWidgetAddFrame"); btAddFrame->setFocusPolicy(Qt::NoFocus); QHBoxLayout *btAddFameLayout = new QHBoxLayout(btAddFrame); btAddFameLayout->setMargin(0); btAddFameLayout->setSpacing(0); btAddFameLayout->addWidget(btAdd, 0, Qt::AlignVCenter); btAddFameLayout->addWidget(btDel, 0, Qt::AlignVCenter); // btAddFameLayout->addWidget(btClose, 0, Qt::AlignVCenter); title_layout = new QHBoxLayout(); title_layout->setSpacing(0); title_layout->setMargin(0); title_layout->addWidget(titleLabel, 0, Qt::AlignHCenter); // title_layout->addStretch(); title_layout->addWidget(btAddFrame, 0, Qt::AlignHCenter); noVideoFrame = new QFrame(); noVideoFrame->setFocusPolicy(Qt::NoFocus); QVBoxLayout *noVideoFameLayout = new QVBoxLayout(noVideoFrame); noVideoFameLayout->setMargin(0); noVideoFameLayout->setSpacing(30); noVideoFameLayout->addStretch(); noVideoFameLayout->addWidget(novideo_icon, 0, Qt::AlignHCenter); noVideoFameLayout->addWidget(novideo_text, 0, Qt::AlignHCenter); noVideoFameLayout->addWidget(add_Btn, 0, Qt::AlignHCenter); noVideoFameLayout->addStretch(); layout->addLayout(title_layout); layout->addWidget(listView, 0, Qt::AlignHCenter); // layout->addWidget(btAddFrame, 0, Qt::AlignHCenter | Qt::AlignBottom); layout->addWidget(noVideoFrame, 0, Qt::AlignHCenter); layout->addStretch(); setLayout(layout); clear(); connect(core, SIGNAL(mediaFinished()), this, SLOT(playNext()), Qt::QueuedConnection); connect(core, SIGNAL(mplayerFailed(QProcess::ProcessError)), this, SLOT(playerFailed(QProcess::ProcessError)) ); connect(core, SIGNAL(mplayerFinishedWithError(int)), this, SLOT(playerFinishedWithError(int)) ); connect(core, SIGNAL(mediaDataReceived(const MediaData &)), this, SLOT(getMediaInfo(const MediaData &))); connect(core, SIGNAL(mediaLoaded()), this, SLOT(getMediaInfo()) ); // Random seed QTime t; t.start(); srand( t.hour() * 3600 + t.minute() * 60 + t.second() ); loadSettings(); // Ugly hack to avoid to play next item automatically if (!automatically_play_next) { disconnect( core, SIGNAL(mediaFinished()), this, SLOT(playNext()) ); } // Save config every 5 minutes. save_timer = new QTimer(this); connect(save_timer, SIGNAL(timeout()), this, SLOT(maybeSaveSettings())); save_timer->start(5 * 60000); if (this->count() > 0) { noVideoFrame->hide(); listView->show(); } else { noVideoFrame->show(); listView->hide(); } } Playlist::~Playlist() { if (popup) { delete popup; popup = NULL; } if (titleLabel != NULL) { delete titleLabel; titleLabel = NULL; } if (btDel != NULL) { delete btDel; btDel = NULL; } if (btAdd != NULL) { delete btAdd; btAdd = NULL; } if (novideo_icon != NULL) { delete novideo_icon; novideo_icon = NULL; } if (novideo_text != NULL) { delete novideo_text; novideo_text = NULL; } if (add_Btn != NULL) { delete add_Btn; add_Btn = NULL; } if (noVideoFrame != NULL) { delete noVideoFrame; noVideoFrame = NULL; } if (btAddFrame != NULL) { delete btAddFrame; btAddFrame = NULL; } for(int i=0; ichildren()) { // QWidget *widget = static_cast(child); // widget->deleteLater(); // } // if (listView->count() > 0) // listView->clear();//kobe:WTF 会发生段错误 if (listView != NULL) { delete listView; listView = NULL; } if (save_timer != NULL) { disconnect(save_timer, SIGNAL(timeout()), this, SLOT(maybeSaveSettings())); if(save_timer->isActive()) { save_timer->stop(); } delete save_timer; save_timer = NULL; } } void Playlist::setTransparent(bool transparent) { if (transparent) { setAttribute(Qt::WA_TranslucentBackground); setWindowFlags(windowFlags() | Qt::FramelessWindowHint|Qt::X11BypassWindowManagerHint); set_widget_opacity(0.5); } else { setAttribute(Qt::WA_TranslucentBackground,false); setWindowFlags(windowFlags() & ~Qt::FramelessWindowHint); } } void Playlist::set_widget_opacity(const float &opacity) { QGraphicsOpacityEffect* opacityEffect = new QGraphicsOpacityEffect; this->setGraphicsEffect(opacityEffect); opacityEffect->setOpacity(opacity); } void Playlist::setModified(bool mod) { modified = mod; // emit modifiedChanged(modified); } void Playlist::createTable() { listView = new PlayListView(this); // listView->setFixedHeight(430); // QSizePolicy sp(QSizePolicy::Preferred, QSizePolicy::Preferred); // sp.setVerticalStretch(100); // listView->setSizePolicy(sp); connect(listView, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(doubleclicked(QListWidgetItem*))); connect(listView, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(showPopupMenu(const QPoint &)) ); } void Playlist::setViewHeight() { listView->setFixedHeight(this->height()-36-16);//36为顶部按钮和label的高度,16为顶部和列表的间隔 } void Playlist::createNoVideo() { novideo_icon = new QLabel(); novideo_icon->setFixedSize(70, 70); novideo_icon->setPixmap(QPixmap(":/res/no-video.png")); novideo_text = new QLabel(); novideo_text->setObjectName("VideoText"); novideo_text->setText(tr("Playlist is empty")); add_Btn = new QPushButton(); add_Btn->setFocusPolicy(Qt::NoFocus); add_Btn->setFixedSize(140, 38); add_Btn->setObjectName("PlaylistAddButton"); add_Btn->setText(tr("Add File")); connect(add_Btn, SIGNAL(clicked(bool)), SLOT(popupDialogtoSelectFiles())); } void Playlist::createToolbar() { titleLabel = new QLabel(); titleLabel->setAlignment(Qt::AlignCenter); // titleLabel->setFixedSize(220-156, 36); titleLabel->setFixedSize(220-120, 36); titleLabel->setStyleSheet("QLabel{font-size:12px;color:#ffffff;background:transparent;}"); titleLabel->setText(tr("PlayList")); btDel = new QPushButton(); btDel->setFocusPolicy(Qt::NoFocus); btDel->setFixedSize(60, 36); btDel->setText(tr("Clear")); btDel->setObjectName("PlaylistButton"); connect(btDel, SIGNAL(clicked(bool)), SLOT(removeAll())); btAdd = new QPushButton(); btAdd->setFocusPolicy(Qt::NoFocus); btAdd->setFixedSize(60, 36); btAdd->setObjectName("PlaylistButton"); btAdd->setText(tr("Add")); // connect(btAdd, SIGNAL(clicked(bool)), SIGNAL(addPlaylist(bool)));//emit this->addPlaylist(true); connect(btAdd, SIGNAL(clicked(bool)), SLOT(popupDialogtoSelectFiles())); playAct = new MyAction(this, "pl_play", false); connect(playAct, SIGNAL(triggered()), this, SLOT(playCurrent()) ); playAct->change(tr("Play")); playAct->setIcon(QPixmap(":/res/playing_normal.png"));//playAct->setIcon(Images::icon("playing_normal")); // Remove actions removeSelectedAct = new MyAction(this, "pl_remove_selected", false); connect( removeSelectedAct, SIGNAL(triggered()), this, SLOT(removeTheSelected()) ); removeSelectedAct->change(tr("Remove &selected")); removeSelectedAct->setIcon(QPixmap(":/res/delete.png")); deleteSelectedFileFromDiskAct = new MyAction(this, "pl_delete_from_disk"); connect( deleteSelectedFileFromDiskAct, SIGNAL(triggered()), this, SLOT(deleteSelectedFileFromDisk())); deleteSelectedFileFromDiskAct->change(tr("&Delete file from disk") ); deleteSelectedFileFromDiskAct->setIcon(QPixmap(":/res/delete.png")); // Popup menu popup = new QMenu(this); popup->addAction(playAct); popup->addAction(removeSelectedAct); popup->addAction(deleteSelectedFileFromDiskAct); } void Playlist::doubleclicked(QListWidgetItem *item) { // qDebug() << item->text(); } void Playlist::updateView() { QString time; for (int n=0; n < pl.count(); n++) { // name = pl[n]->name(); // if (name.isEmpty()) name = pl[n]->filename(); time = Helper::formatTime( (int) pl[n]->duration()); if (listView) { QListWidgetItem *item = listView->item(n); PlayListItem *playlistItem = qobject_cast(listView->itemWidget(item)); playlistItem->update_time(time);//更新视频的时长 } } setListCurrentItem(current_item); } void Playlist::setListCurrentItem(int current) { listView->setCurrentItem(listView->item(current));//启动加载时设置播放列表的默认选中项 current_item = current; if ((current_item > -1) && (current_item < pl.count())) { pl[current_item]->setPlayed(true); // pl[current_item]->setActive(true); } } void Playlist::clear() { for(int i=0; ireset();//kobe resolve segmentation fault listView->clearSelection(); listView->clearFocus(); listView->clear();//kobe:必须执行该语句,否则切换视频后点击显示播放列表会发生段错误 listView->updateScrollbar(); setListCurrentItem(0); setModified(false); emit this->update_playlist_count(0); noVideoFrame->show(); listView->hide(); } int Playlist::count() { return pl.count(); } bool Playlist::isEmpty() { return pl.isEmpty(); } void Playlist::addOneItem(QString filename, QString name, double duration) { // Test if already is in the list bool exists = false; for (int n = 0; n < pl.count(); n++) { // qDebug() << "pl[n]->filename()=" << pl[n]->filename(); if ( pl[n]->filename() == filename.toUtf8().data()) { exists = true; // int last_item = pl.count()-1; // pl.move(n, last_item); // qDebug("Playlist::addOneItem: item already in list (%d), moved to %d and current_item=%d", n, last_item, current_item); current_item = n;//20170712 // if (current_item > -1) { // if (current_item > n) current_item--; // else // if (current_item == n) current_item = last_item; // } break; } } if (!exists) { if (name.isEmpty()) { QFileInfo fi(filename.toUtf8().data()); // Let's see if it looks like a file (no dvd://1 or something) if (filename.indexOf(QRegExp("^.*://.*")) == -1) { // Local file name = fi.fileName(); //fi.baseName(true); } else { // Stream name = filename; } } QListWidgetItem *item = new QListWidgetItem(listView); item->setSizeHint(QSize(220, 32)); //// item->setText(filename); listView->addItem(item); listView->setItemWidget(item, new PlayListItem("vedio", filename/*.toUtf8().data()*/, name/*.toUtf8().data()*/, duration)); PlayListItem *playlistItem = qobject_cast(listView->itemWidget(item)); pl.append(playlistItem);//?????????????TODO:0518 connect(playlistItem, SIGNAL(remove(QString)), this, SLOT(onPlayListItemDeleteBtnClicked(QString))); connect(playlistItem, SIGNAL(sig_doubleclicked_resource(QString)), this, SLOT(slot_doubleclicked_resource(QString))); setModified(true); // Better set the modified on a higher level listView->setCurrentItem(item); emit this->update_playlist_count(pl.count()); if (pl.count() > 0) { noVideoFrame->hide(); listView->show(); } else { noVideoFrame->show(); listView->hide(); } // current_item = pl.count() - 1;//0526 // this->setListCurrentItem(pl.count() - 1);//0526 } else { this->setListCurrentItem(current_item);//20170712 正播放的文件存在播放列表中时更新播放列表的选择项 // listView->setCurrentItem(listView->item(current_item));//20170712 正播放的文件存在播放列表中时更新播放列表的选择项 qDebug("Playlist::addOneItem: item not added, already in the list current_item=%d", current_item); } } void Playlist::slot_listview_current_item_changed(QListWidgetItem *current, QListWidgetItem *previous) {//kobe:此函数在启动加载配置时,会让配置的最后一个播放文件在列表中被选中 PlayListItem *itemWidget = qobject_cast(listView->itemWidget(previous)); if (itemWidget) { itemWidget->setActive(false); } itemWidget = qobject_cast(listView->itemWidget(current)); if (itemWidget) { itemWidget->setActive(true); } } //双击播放列表的一项时进行播放 void Playlist::slot_doubleclicked_resource(QString filename) { QFileInfo fi(filename); if (fi.exists()) { // Local file QString name = fi.fileName(); emit this->sig_playing_title(name); core->open(filename/*, 0*/);//每次从头开始播放文件 } else { emit this->playListFinishedWithError(filename); } } void Playlist::playCurrent() { int current = listView->currentRow(); if (current > -1) { playItem(current); } // this->slot_doubleclicked_resource(); } void Playlist::itemDoubleClicked(int row) { // qDebug("Playlist::itemDoubleClicked: row: %d", row ); playItem(row); } void Playlist::showPopupMenu(const QPoint & pos) { // qDebug("Playlist::showPopupMenu: x: %d y: %d", pos.x(), pos.y() ); // get select QList items = listView->selectedItems(); if (items.length() != 1) { return; } PlayListItem *item = qobject_cast(listView->itemWidget(items.first())); if (!item) { return; } QString m_data = item->data(); if (m_data.isEmpty()) { return; } // current_item = 1; QPoint itemPos = item->mapFromParent(pos); if (!item->rect().contains(itemPos)) { return; } // QPoint globalPos = this->mapToGlobal(pos); if (!popup->isVisible()) { playAct->setDisabled(0 == m_data.length()); popup->move(listView->viewport()->mapToGlobal(pos) ); popup->show(); } } //kobe:添加多个文件文件夹或拖拽进多个文件文件夹时才会走这里,如果是支持乱序,则乱序选择一个开始播放20170725 void Playlist::startPlayPause() { // Start to play if (pref->play_order == Preferences::RandomPlay) {//随机播放 playItem(chooseRandomItem()); } else {//顺序播放 列表循环 playItem(0); } } void Playlist::playItem( int n ) { // qDebug("Playlist::playItem: %d (count:%d)", n, pl.count()); if ( (n >= pl.count()) || (n < 0) ) { qDebug("Playlist::playItem: out of range"); emit playlistEnded(); emit this->sig_playing_title(""); return; } // qDebug("######playlist_path: '%s'", playlist_path.toUtf8().data() ); QString filename = pl[n]->filename(); // qDebug("######filename: '%s'", filename); // QString filename_with_path = playlist_path + "/" + filename; if (!filename.isEmpty()) { //pl[n].setPlayed(true); // setListCurrentItem(n);//0527 n - 1 QFileInfo fi(filename); if (fi.exists()) { setListCurrentItem(n);//0527 n - 1 // Local file QString name = fi.fileName(); emit this->sig_playing_title(name); core->open(filename/*, 0*/);//每次从头开始播放文件 } else { emit this->playListFinishedWithError(filename); } //0621 kobe: core->open(filename, 0): 每次从头开始播放文件, core->open(filename):每次从上次播放停止位置开始播放文件 // core->open(filename); // if (play_files_from_start) // core->open(filename/*, 0*/);//每次从头开始播放文件 // else // core->open(filename); /* else { // Stream name = filename; //emit this->playListFinishedWithError(filename); }*/ } } //20170725 void Playlist::playNext() { // emit this->sig_playing_title(""); // qDebug("Playlist::playNext pl[current_item]->name()=%s", pl[current_item]->name()); if (pref->play_order == Preferences::RandomPlay) {//随机播放 int chosen_item = chooseRandomItem(); if (chosen_item == -1) { clearPlayedTag(); chosen_item = chooseRandomItem(); if (chosen_item == -1) chosen_item = 0; } playItem(chosen_item); } else if (pref->play_order == Preferences::ListLoopPlay) {//列表循环 bool finished_list = (current_item+1 >= pl.count()); if (finished_list) { clearPlayedTag(); } if (finished_list) { playItem(0); } else { playItem(current_item+1); } } else {//顺序播放 bool finished_list = (current_item+1 >= pl.count()); if (finished_list) { clearPlayedTag(); } if (finished_list) { // emit this->finish_list(); emit this->showMessage(tr("Reached the end of the playlist")); } else { playItem(current_item + 1); } } } void Playlist::playPrev() { if (current_item > 0) { playItem(current_item - 1); } else { if (pl.count() > 1) { playItem(pl.count() - 1); } } } void Playlist::resumePlay() { if (pl.count() > 0) { if (current_item < 0) current_item = 0; // current_item = 0;//20170713 playItem(current_item); } } void Playlist::getMediaInfo() { QString filename = core->mdat.filename; double duration = core->mdat.duration; // QString artist = core->mdat.clip_artist; //kobe:有的rmvb视频的clip_name存在乱码 QString name; //QString name = core->mdat.clip_name; //if (name.isEmpty()) name = core->mdat.stream_title; if (name.isEmpty()) { QFileInfo fi(filename); name = fi.fileName();//20170713 // if (fi.exists()) { // // Local file // name = fi.fileName(); // } else { // // Stream // name = filename; // } } // if (!artist.isEmpty()) name = artist + " - " + name; for (int n = 0; n < pl.count(); n++) { if (pl[n]->filename() == filename) { current_item = n;//kobe 20170712 // Found item if (pl[n]->duration() < 1) { if (!name.isEmpty()) { pl[n]->setName(name.toUtf8().data());//edit by kobe } pl[n]->setDuration(duration); } else // Edited name (sets duration to 1) if (pl[n]->duration() == 1) { pl[n]->setDuration(duration); } } } updateView(); } //0707 void Playlist::popupDialogtoSelectFiles() { //打开一个或多个文件时,此时只是将选择的文件加入播放列表,并不会自动去播放选择的文件 Extensions e; QStringList files = MyFileDialog::getOpenFileNames( this, tr("Select one or more files to open"), lastDir(), tr("Multimedia") + e.multimedia().forFilter() + ";;" + tr("All files") +" (*.*)" ); if (files.count()!=0) addFiles(files); } void Playlist::addFiles(QStringList files, AutoGetInfo auto_get_info) { bool get_info = (auto_get_info == GetInfo); get_info = true; // MediaData data; setCursor(Qt::WaitCursor); QString initial_file; if (pl.count() == 1) { initial_file = pl[0]->filename()/*.toUtf8().data()*/;//0526 qDebug() << "pl[0]->filename()=" << pl[0]->filename(); } int new_current_item = -1; for (int n = 0; n < files.count(); n++) { QString name = ""; double duration = 0; //kobe 0606 如果选择多个文件,此时读取信息会耗时很长,导致界面卡顿,此处暂时不获取视频信息,在双击播放后再在函数updateView中更新视频的时长 // if ( (get_info) && (QFile::exists(files[n])) ) { // data = InfoProvider::getInfo(files[n]); // name = data.displayName(); // duration = data.duration; // } // qDebug() << "USE_INFOPROVIDER name=" << name << " duration=" << duration << " current_item=" << current_item; if (!initial_file.isEmpty() && files[n] == initial_file) { PlayListItem *first_item = pl.takeFirst();//pl.takeFirst(); name = first_item->name(); duration = first_item->duration(); new_current_item = n; } this->addOneItem(files[n], name, duration); if (QFile::exists(files[n])) { playlist_load_latest_dir = QFileInfo(files[n]).absolutePath(); } } unsetCursor(); // if (new_current_item != -1) setListCurrentItem(new_current_item); // else setListCurrentItem(pl.count() - 1);//0526 kobe updateView(); } void Playlist::addFile(QString file, AutoGetInfo auto_get_info) { //打开一个文件时 addFiles( QStringList() << file, auto_get_info ); } void Playlist::addDirectory() { QString s = MyFileDialog::getExistingDirectory( this, tr("Choose a directory"), lastDir() ); if (!s.isEmpty()) { addDirectory(s); playlist_load_latest_dir = s; } } void Playlist::addOneDirectory(QString dir) { QStringList filelist; Extensions e; QRegExp rx_ext(e.multimedia().forRegExp()); rx_ext.setCaseSensitivity(Qt::CaseInsensitive); QStringList dir_list = QDir(dir).entryList(); QString filename; QStringList::Iterator it = dir_list.begin(); while( it != dir_list.end() ) { filename = dir; if (filename.right(1)!="/") filename += "/"; filename += (*it); QFileInfo fi(filename); if (!fi.isDir()) { if (rx_ext.indexIn(fi.suffix()) > -1) { filelist << filename; } } ++it; } addFiles(filelist); } void Playlist::addDirectory(QString dir) { addOneDirectory(dir); // if (recursive_add_directory) {//递归 // QFileInfoList dir_list = QDir(dir).entryInfoList(QStringList() << "*", QDir::AllDirs | QDir::NoDotAndDotDot); // for (int n=0; n < dir_list.count(); n++) { // if (dir_list[n].isDir()) { // qDebug("Playlist::addDirectory: adding directory: %s", dir_list[n].filePath().toUtf8().data()); // addDirectory(dir_list[n].filePath()); // } // } // } } void Playlist::removeTheSelected() { int current = listView->currentRow(); if ( (current >= pl.count()) || (current < 0) ) { qDebug("Playlist::playItem: out of range when remove"); return; } QString filename = pl[current]->filename(); if (!filename.isEmpty()) { MessageDialog msgDialog(0, tr("Confirm remove"), tr("You're about to remove the file '%1' from the playlist.").arg(filename) + "
    "+ tr("Are you sure you want to proceed?"), QMessageBox::Yes | QMessageBox::No); if (msgDialog.exec() != -1) { if (msgDialog.standardButton(msgDialog.clickedButton()) == QMessageBox::Yes) { removeSelected(filename); } } // removeSelected(filename); } } void Playlist::onPlayListItemDeleteBtnClicked(QString filename) { if (!filename.isEmpty()) { MessageDialog msgDialog(0, tr("Confirm remove"), tr("You're about to remove the file '%1' from the playlist.").arg(filename) + "
    "+ tr("Are you sure you want to proceed?"), QMessageBox::Yes | QMessageBox::No); if (msgDialog.exec() != -1) { if (msgDialog.standardButton(msgDialog.clickedButton()) == QMessageBox::Yes) { removeSelected(filename); } } } } // Remove selected item void Playlist::removeSelected(QString filename) { int first_selected = -1; int number_previous_item = 0; for (int i = 0; i < listView->count(); ++i) { QListWidgetItem *item = listView->item(i); PlayListItem *playlistItem = qobject_cast(listView->itemWidget(item)); if (playlistItem->data() == filename) { pl[i]->setMarkForDeletion(true); number_previous_item++; if (first_selected == -1) first_selected = i; // break; listView->removeItemWidget(item); delete listView->takeItem(listView->row(item)); Q_ASSERT(listView->count() > 0); listView->updateScrollbar(); listView->setCurrentItem(listView->item(0)); break; } } QList::Iterator it = pl.begin(), itend = pl.end(); for(;it !=itend;it++) { if ( (*it)->markedForDeletion() ) { qDebug("remove '%s'", (*it)->filename().toUtf8().data()); it = pl.erase(it); // it--; setModified(true); break; } } emit this->update_playlist_count(pl.count()); if (pl.count() > 0) { noVideoFrame->hide(); listView->show(); this->playNext();//Fixed bug: #4915 } else { noVideoFrame->show(); listView->hide(); } if (first_selected < current_item) { current_item -= number_previous_item; } if (isEmpty()) setModified(false); updateView(); if (first_selected >= listView->count()) first_selected = listView->count() - 1; if ( ( first_selected > -1) && ( first_selected < listView->count() ) ) { // listView->clearSelection(); listView->setCurrentRow(first_selected); } } void Playlist::removeAll() { clear(); } void Playlist::clearPlayedTag() { for (int n = 0; n < pl.count(); n++) { pl[n]->setPlayed(false); } updateView(); } int Playlist::chooseRandomItem() { QList fi; //List of not played items (free items) for (int n = 0; n < pl.count(); n++) { if (!pl[n]->played()) fi.append(n); } // qDebug("Playlist::chooseRandomItem: free items: %d", fi.count() ); if (fi.count() == 0) return -1; // none free for (int i = 0; i < fi.count(); i++) { qDebug("Playlist::chooseRandomItem: * item: %d", fi[i]); } int selected = (int) ((double) fi.count() * rand()/(RAND_MAX+1.0)); // qDebug("Playlist::chooseRandomItem: selected item: %d (%d)", selected, fi[selected]); return fi[selected]; } void Playlist::swapItems(int item1, int item2 ) { } void Playlist::upItem() { // qDebug("Playlist::upItem"); int current = listView->currentRow(); qDebug(" currentRow: %d", current ); moveItemUp(current); } void Playlist::downItem() { qDebug("Playlist::downItem"); int current = listView->currentRow(); qDebug(" currentRow: %d", current ); moveItemDown(current); } void Playlist::moveItemUp(int current){ } void Playlist::moveItemDown(int current ){ } void Playlist::editCurrentItem() { // int current = listView->currentRow(); // if (current > -1) editItem(current); } void Playlist::editItem(int item) { } void Playlist::deleteSelectedFileFromDisk() { qDebug("Playlist::deleteSelectedFileFromDisk"); int current = listView->currentRow(); if (current > -1) { // // If more that one row is selected, select only the current one // listView->clearSelection(); // listView->setCurrentCell(current, 0); QString filename = pl[current]->filename(); qDebug() << "Playlist::deleteSelectedFileFromDisk: current file:" << filename; //20170715 QFileInfo fi(filename); if (fi.exists() && fi.isFile() && fi.isWritable()) { // Ask the user for confirmation MessageDialog msgDialog(0, tr("Confirm deletion"), tr("You're about to DELETE the file '%1' from your drive.").arg(filename) + "
    "+ tr("This action cannot be undone. Are you sure you want to proceed?"), QMessageBox::Yes | QMessageBox::No); if (msgDialog.exec() != -1) { if (msgDialog.standardButton(msgDialog.clickedButton()) == QMessageBox::Yes) { // Delete file bool success = QFile::remove(filename); if (success) { // Remove item from the playlist removeSelected(filename); } else { // QMessageBox::warning(this, tr("Deletion failed"), // tr("It wasn't possible to delete '%1'").arg(filename)); MessageDialog warnDialog(0, tr("Deletion failed"), tr("It wasn't possible to delete '%1'").arg(filename), QMessageBox::Ok); warnDialog.exec(); } } } } else { // qDebug("Playlist::deleteSelectedFileFromDisk: file doesn't exists, it's not a file or it's not writable"); MessageDialog infoDialog(0, tr("Error deleting the file"), tr("It's not possible to delete '%1' from the filesystem.").arg(filename), QMessageBox::Ok); infoDialog.exec(); } } } // Drag&drop void Playlist::dragEnterEvent( QDragEnterEvent *e ) { // qDebug("Playlist::dragEnterEvent"); if (e->mimeData()->hasUrls()) { e->acceptProposedAction(); } } void Playlist::dropEvent( QDropEvent *e ) { // qDebug("Playlist::dropEvent"); QStringList files; if (e->mimeData()->hasUrls()) { QList l = e->mimeData()->urls(); QString s; for (int n=0; n < l.count(); n++) { if (l[n].isValid()) { qDebug("Playlist::dropEvent: scheme: '%s'", l[n].scheme().toUtf8().data()); if (l[n].scheme() == "file") s = l[n].toLocalFile(); else s = l[n].toString(); /* qDebug(" * '%s'", l[n].toString().toUtf8().data()); qDebug(" * '%s'", l[n].toLocalFile().toUtf8().data()); */ qDebug("Playlist::dropEvent: file: '%s'", s.toUtf8().data()); files.append(s); } } } files.sort(); QStringList only_files; for (int n = 0; n < files.count(); n++) { if ( QFileInfo( files[n] ).isDir() ) { addDirectory( files[n] ); } else { only_files.append( files[n] ); } } addFiles( only_files ); } void Playlist::hideEvent( QHideEvent * ) { emit visibilityChanged(false); } void Playlist::showEvent( QShowEvent * ) { emit visibilityChanged(true); } void Playlist::closeEvent( QCloseEvent * e ) { saveSettings(); e->accept(); } void Playlist::getMediaInfo(const MediaData & mdat) { /*qDebug("Playlist::getMediaInfo"); QString filename = mdat.filename; double duration = mdat.duration; QString artist = mdat.clip_artist; QString video_url = mdat.stream_path; // #if defined(Q_OS_WIN) || defined(Q_OS_OS2) // filename = Helper::changeSlashes(filename); // #endif QString name; if (change_name) { name = mdat.clip_name; if (name.isEmpty()) name = mdat.stream_title; if (name.isEmpty()) { QFileInfo fi(filename); if (fi.exists()) { // Local file name = fi.fileName(); } else { // Stream name = filename; } } if (!artist.isEmpty()) name = artist + " - " + name; } for (int n = 0; n < count(); n++) { PLItem * i = itemData(n); if (i->filename() == filename) { // Found item bool modified_name = !(i->filename().endsWith(i->name())); if (i->duration() < 1) { if (!modified_name && !name.isEmpty()) { i->setName(name); } i->setDuration(duration); } else // Edited name (sets duration to 1) if (i->duration() == 1) { i->setDuration(duration); } i->setVideoURL(video_url); } }*/ } void Playlist::playerFailed(QProcess::ProcessError e) { qDebug("Playlist::playerFailed"); emit this->sig_playing_title(""); // if (ignore_player_errors) { // if (e != QProcess::FailedToStart) { // playNext(); // } // } } void Playlist::playerFinishedWithError(int e) { emit this->sig_playing_title(""); // qDebug("@@@@@@@@@@@@@@@@@@@Playlist::playerFinishedWithError: %d", e); // if (ignore_player_errors) { // playNext(); // } } void Playlist::maybeSaveSettings() { if (isModified()) saveSettings(); } void Playlist::saveSettings() { QSettings * set = settings; //Save current list set->beginGroup( "playlist_contents"); set->setValue( "playlist_load_latest_dir", playlist_load_latest_dir ); set->setValue("count", (int)pl.count()); for ( int n=0; n < pl.count(); n++ ) { set->setValue(QString("item_%1_filename").arg(n), pl[n]->filename()); set->setValue(QString("item_%1_duration").arg(n), pl[n]->duration()); set->setValue(QString("item_%1_name").arg(n), pl[n]->name()); } set->setValue("current_item", current_item ); set->setValue("play_order", (int) pref->play_order);//20170725 set->endGroup(); } void Playlist::loadSettings() { QSettings * set = settings; //Load latest list set->beginGroup( "playlist_contents"); playlist_load_latest_dir = set->value( "laylist_load_latest_dir", playlist_load_latest_dir ).toString();//latest_dir 0526 pref->play_order = (Preferences::PlayOrder) set->value("play_order", (int) pref->play_order).toInt();//20170725 int count = set->value("count", 0).toInt(); QString filename, name; double duration; for (int n=0; n < count; n++ ) { filename = set->value(QString("item_%1_filename").arg(n), "").toString()/*.toUtf8().data()*/; duration = set->value(QString("item_%1_duration").arg(n), -1).toDouble(); name = set->value( QString("item_%1_name").arg(n), "" ).toString()/*.toUtf8().data()*/; // qDebug() << "===============kobe test filename:" << filename << " name=" << name << " duration=" << duration;//.toUtf8().data(); this->addOneItem(filename, name, duration);//kobe add playlist contents } int index = set->value("current_item", -1).toInt(); setListCurrentItem(index); emit this->update_playlist_count(pl.count()); if (pl.count() > 0) { noVideoFrame->hide(); listView->show(); } else { noVideoFrame->show(); listView->hide(); } updateView(); set->endGroup(); } QString Playlist::lastDir() { QString last_dir = playlist_load_latest_dir; if (last_dir.isEmpty()) last_dir = pref->latest_dir; return last_dir; } void Playlist::paintEvent(QPaintEvent *event) { Q_UNUSED(event); QStyleOption opt; opt.init(this); QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); // QPainter p(this); // p.setCompositionMode(QPainter::CompositionMode_Clear); // p.fillRect(rect(), Qt::SolidPattern);//p.fillRect(0, 0, this->width(), this->height(), Qt::SolidPattern); } //#include "moc_playlist.cpp" kylin-video/src/smplayer/inforeadermplayer.cpp0000644000175000017500000001762613625147453020615 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "inforeadermplayer.h" #include #include #include #include #include "colorutils.h" #include "global.h" #include "preferences.h" #include "mplayerversion.h" using namespace Global; #define NOME 0 #define VO 1 #define AO 2 #define DEMUXER 3 #define VC 4 #define AC 5 InfoReaderMplayer::InfoReaderMplayer( QString mplayer_bin, const QString &snap, QObject * parent ) : QObject(parent) , proc(0) , mplayer_svn(0) , m_snap(snap) // , is_mplayer2(false) { mplayerbin = mplayer_bin; proc = new QProcess(this); proc->setProcessChannelMode( QProcess::MergedChannels ); } InfoReaderMplayer::~InfoReaderMplayer() { } void InfoReaderMplayer::getInfo() { waiting_for_key = true; vo_list.clear(); ao_list.clear(); demuxer_list.clear(); mplayer_svn = -1; run("-identify -vo help -ao help -demuxer help -vc help -ac help"); //list(); } void InfoReaderMplayer::list() { qDebug("InfoReaderMplayer::list"); InfoList::iterator it; qDebug(" vo_list:"); for ( it = vo_list.begin(); it != vo_list.end(); ++it ) { qDebug( "driver: '%s', desc: '%s'", (*it).name().toUtf8().data(), (*it).desc().toUtf8().data()); } qDebug(" ao_list:"); for ( it = ao_list.begin(); it != ao_list.end(); ++it ) { qDebug( "driver: '%s', desc: '%s'", (*it).name().toUtf8().data(), (*it).desc().toUtf8().data()); } qDebug(" demuxer_list:"); for ( it = demuxer_list.begin(); it != demuxer_list.end(); ++it ) { qDebug( "demuxer: '%s', desc: '%s'", (*it).name().toUtf8().data(), (*it).desc().toUtf8().data()); } qDebug(" vc_list:"); for ( it = vc_list.begin(); it != vc_list.end(); ++it ) { qDebug( "codec: '%s', desc: '%s'", (*it).name().toUtf8().data(), (*it).desc().toUtf8().data()); } qDebug(" ac_list:"); for ( it = ac_list.begin(); it != ac_list.end(); ++it ) { qDebug( "codec: '%s', desc: '%s'", (*it).name().toUtf8().data(), (*it).desc().toUtf8().data()); } } static QRegExp rx_vo_key("^ID_VIDEO_OUTPUTS"); static QRegExp rx_ao_key("^ID_AUDIO_OUTPUTS"); static QRegExp rx_demuxer_key("^ID_DEMUXERS"); static QRegExp rx_ac_key("^ID_AUDIO_CODECS"); static QRegExp rx_vc_key("^ID_VIDEO_CODECS"); static QRegExp rx_driver("\\t(.*)\\t(.*)"); static QRegExp rx_demuxer("^\\s+([A-Z,a-z,0-9]+)\\s+(\\d+)\\s+(\\S.*)"); static QRegExp rx_demuxer2("^\\s+([A-Z,a-z,0-9]+)\\s+(\\S.*)"); static QRegExp rx_codec("^([A-Z,a-z,0-9]+)\\s+([A-Z,a-z,0-9]+)\\s+([A-Z,a-z,0-9]+)\\s+(\\S.*)"); void InfoReaderMplayer::readLine(QByteArray ba) { QString line = ColorUtils::stripColorsTags(QString::fromLocal8Bit(ba)); if (line.isEmpty()) return; //qDebug("InfoReaderMplayer::readLine: line: '%s'", line.toUtf8().data()); //qDebug("waiting_for_key: %d", waiting_for_key); if (!waiting_for_key) { if ((reading_type == VO) || (reading_type == AO)) { if ( rx_driver.indexIn(line) > -1 ) { QString name = rx_driver.cap(1); QString desc = rx_driver.cap(2); //("InfoReaderMplayer::readLine: found driver: '%s' '%s'", name.toUtf8().data(), desc.toUtf8().data()); if (reading_type==VO) { vo_list.append( InfoData(name, desc) ); } else if (reading_type==AO) { ao_list.append( InfoData(name, desc) ); } } else { qWarning("InfoReaderMplayer::readLine: can't parse output driver from line '%s'", line.toUtf8().constData()); } } else if (reading_type == DEMUXER) { if ( rx_demuxer.indexIn(line) > -1 ) { QString name = rx_demuxer.cap(1); QString desc = rx_demuxer.cap(3); //qDebug("InfoReaderMplayer::readLine: found demuxer: '%s' '%s'", name.toUtf8().data(), desc.toUtf8().data()); demuxer_list.append( InfoData(name, desc) ); } else if ( rx_demuxer2.indexIn(line) > -1 ) { QString name = rx_demuxer2.cap(1); QString desc = rx_demuxer2.cap(2); //qDebug("InfoReaderMplayer::readLine: found demuxer: '%s' '%s'", name.toUtf8().data(), desc.toUtf8().data()); demuxer_list.append( InfoData(name, desc) ); } else { qWarning("InfoReaderMplayer::readLine: can't parse demuxer from line '%s'", line.toUtf8().constData()); } } else if ((reading_type == VC) || (reading_type == AC)) { if ( rx_codec.indexIn(line) > -1 ) { QString name = rx_codec.cap(1); QString desc = rx_codec.cap(4); //qDebug("InfoReaderMplayer::readLine: found codec: '%s' '%s'", name.toUtf8().data(), desc.toUtf8().data()); if (reading_type==VC) { vc_list.append( InfoData(name, desc) ); } else if (reading_type==AC) { ac_list.append( InfoData(name, desc) ); } } else { qWarning("InfoReaderMplayer::readLine: can't parse codec from line '%s'", line.toUtf8().constData()); } } } if ( rx_vo_key.indexIn(line) > -1 ) { reading_type = VO; waiting_for_key = false; qDebug("InfoReaderMplayer::readLine: found key: vo"); } if ( rx_ao_key.indexIn(line) > -1 ) { reading_type = AO; waiting_for_key = false; qDebug("InfoReaderMplayer::readLine: found key: ao"); } if ( rx_demuxer_key.indexIn(line) > -1 ) { reading_type = DEMUXER; waiting_for_key = false; qDebug("InfoReaderMplayer::readLine: found key: demuxer"); } if ( rx_ac_key.indexIn(line) > -1 ) { reading_type = AC; waiting_for_key = false; qDebug("InfoReaderMplayer::readLine: found key: ac"); } if ( rx_vc_key.indexIn(line) > -1 ) { reading_type = VC; waiting_for_key = false; qDebug("InfoReaderMplayer::readLines: found key: vc"); } if (line.startsWith("MPlayer ") || line.startsWith("MPlayer2 ")) { mplayer_svn = MplayerVersion::mplayerVersion(line); // mplayer2_version = MplayerVersion::mplayer2Version(); // is_mplayer2 = MplayerVersion::isMplayer2(); } } bool InfoReaderMplayer::run(QString options) { //qDebug("InfoReaderMplayer::run: '%s'", options.toUtf8().data()); if (proc->state() == QProcess::Running) { qWarning("InfoReaderMplayer::run: process already running"); return false; } QStringList args = options.split(" "); //edited by kobe 20180623 QString abs_bin; if (!this->m_snap.isEmpty()) { abs_bin = QString("%1%2").arg(this->m_snap).arg(mplayerbin); } else { abs_bin = mplayerbin; } proc->start(abs_bin, args); if (!proc->waitForStarted()) { qWarning("InfoReaderMplayer::run: process can't start!"); return false; } //Wait until finish if (!proc->waitForFinished()) { qWarning("InfoReaderMplayer::run: process didn't finish. Killing it..."); proc->kill(); } qDebug("================InfoReaderMplayer::run : terminating"); QByteArray ba; while (proc->canReadLine()) { ba = proc->readLine(); ba.replace("\n", ""); ba.replace("\r", ""); readLine( ba ); } return true; } //#include "moc_inforeadermplayer.cpp" kylin-video/src/smplayer/reminderdialog.h0000644000175000017500000000252413517016402017513 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef REMINDERDIALOG_H #define REMINDERDIALOG_H #include "ui_reminderdialog.h" class QPushButton; class ReminderDialog : public QDialog, public Ui::ReminderDialog { Q_OBJECT public: enum Button { Donate = 1, Share = 2, Close = 0 }; ReminderDialog( QWidget* parent = 0, Qt::WindowFlags f = 0 ); ~ReminderDialog(); bool isRemindChecked(); protected slots: void button_clicked(QAbstractButton *); private: QPushButton * donate_button; QPushButton * facebook_button; QPushButton * close_button; }; #endif kylin-video/src/smplayer/autohidewidget.cpp0000644000175000017500000001534113517016402020070 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2018 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "autohidewidget.h" #include #include #include #include #include #include #include #if QT_VERSION >= 0x040600 #include #endif #define HANDLE_TAP_EVENT #ifdef HANDLE_TAP_EVENT #include #endif AutohideWidget::AutohideWidget(QWidget * parent) : QWidget(parent) , turned_on(false) , auto_hide(false) , use_animation(false) , spacing(0) , perc_width(100) , activation_area(Anywhere) , internal_widget(0) , timer(0) #if QT_VERSION >= 0x040600 , animation(0) #endif { setBackgroundRole(QPalette::Window); setAutoFillBackground(true); setLayoutDirection(Qt::LeftToRight); QWidget * widget_to_watch = parent; widget_to_watch->installEventFilter(this); installFilter(widget_to_watch); timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(checkUnderMouse())); timer->setInterval(3000); QVBoxLayout *layout = new QVBoxLayout; layout->setSpacing(0); layout->setMargin(0); setLayout(layout); } AutohideWidget::~AutohideWidget() { #if QT_VERSION >= 0x040600 if (animation) delete animation; #endif } void AutohideWidget::setInternalWidget(QWidget * w) { //qDebug() << "AutohideWidget::setInternalWidget:" << w; layout()->addWidget(w); internal_widget = w; } void AutohideWidget::setHideDelay(int ms) { timer->setInterval(ms); } int AutohideWidget::hideDelay() { return timer->interval(); } void AutohideWidget::installFilter(QObject *o) { QObjectList children = o->children(); for (int n=0; n < children.count(); n++) { if (children[n]->isWidgetType()) { qDebug() << "AutohideWidget::installFilter: child name:" << children[n]->objectName(); QWidget *w = static_cast(children[n]); w->setMouseTracking(true); w->installEventFilter(this); installFilter(children[n]); #ifdef HANDLE_TAP_EVENT //w->grabGesture(Qt::TapGesture); #endif } } } bool AutohideWidget::visiblePopups() { //qDebug() << "AutohideWidget::visiblePopups: internal_widget:" << internal_widget; if (!internal_widget) return false; // Check if any of the menus in the internal widget is visible QObjectList children = internal_widget->children(); foreach(QObject * child, children) { if (child->isWidgetType()) { //qDebug() << "AutohideWidget::visiblePopups:" << child << "child name:" << child->objectName(); QWidget *w = static_cast(child); QList actions = w->actions(); foreach(QAction * action, actions) { //qDebug() << "AutohideWidget::visiblePopups: action:" << action; QList aw = action->associatedWidgets(); //qDebug() << "AutohideWidget::visiblePopups: aw:" << aw; QMenu * menu = 0; foreach(QWidget * widget, aw) { //qDebug() << "AutohideWidget::visiblePopups: widget:" << widget; if ((menu = qobject_cast(widget))) { //qDebug() << "AutohideWidget::visiblePopups: menu:" << menu << "visible:" << menu->isVisible(); if (menu->isVisible()) return true; } } menu = action->menu(); if (menu) { //qDebug() << "AutohideWidget::visiblePopups: menu:" << menu << "visible:" << menu->isVisible(); if (menu->isVisible()) return true; } } } } return false; } void AutohideWidget::activate() { turned_on = true; timer->start(); } void AutohideWidget::deactivate() { turned_on = false; timer->stop(); hide(); } void AutohideWidget::show() { qDebug() << "AutohideWidget::show"; resizeAndMove(); if (use_animation) { showAnimated(); } else { QWidget::show(); } // Restart timer if (timer->isActive()) timer->start(); } void AutohideWidget::setAutoHide(bool b) { auto_hide = b; } void AutohideWidget::checkUnderMouse() { if (auto_hide) { //qDebug("AutohideWidget::checkUnderMouse"); if (isVisible() && !underMouse() && !visiblePopups()) { hide(); } } } void AutohideWidget::resizeAndMove() { QWidget * widget = parentWidget(); int w = widget->width() * perc_width / 100; int h = height(); resize(w, h); int x = (widget->width() - width() ) / 2; int y = widget->height() - height() - spacing; move(x, y); } bool AutohideWidget::eventFilter(QObject * obj, QEvent * event) { if (turned_on) { //qDebug() << "AutohideWidget::eventFilter: obj:" << obj << "type:" << event->type(); #ifdef HANDLE_TAP_EVENT if (event->type() == QEvent::Gesture) { qDebug() << "AutohideWidget::eventFilter: obj:" << obj << "gesture:" << event; QGestureEvent * gesture_event = static_cast(event); if (gesture_event->gesture(Qt::TapGesture)) { qDebug() << "AutohideWidget::eventFilter: tap event detected"; if (!isVisible()) show(); //else hide(); event->setAccepted(true); return true; } } else #endif if (event->type() == QEvent::MouseMove) { //qDebug() << "AutohideWidget::eventFilter: mouse move" << obj; if (!isVisible()) { if (activation_area == Anywhere) { show(); } else { QMouseEvent * mouse_event = dynamic_cast(event); QWidget * parent = parentWidget(); QPoint p = parent->mapFromGlobal(mouse_event->globalPos()); //qDebug() << "AutohideWidget::eventFilter: y:" << p.y(); if (p.y() > (parent->height() - height() - spacing)) { show(); } } } } else if (event->type() == QEvent::MouseButtonRelease && obj == this) { event->setAccepted(true); return true; } } return QWidget::eventFilter(obj, event); } void AutohideWidget::showAnimated() { #if QT_VERSION >= 0x040600 if (!animation) { animation = new QPropertyAnimation(this, "pos"); } QPoint initial_position = QPoint(pos().x(), parentWidget()->size().height()); QPoint final_position = pos(); move(initial_position); QWidget::show(); animation->setDuration(300); animation->setEasingCurve(QEasingCurve::OutBounce); animation->setEndValue(final_position); animation->setStartValue(initial_position); animation->start(); #else QWidget::show(); #endif } #include "moc_autohidewidget.cpp" kylin-video/src/smplayer/inforeadermpv.cpp0000644000175000017500000001304513637124037017731 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "inforeadermpv.h" #include "mplayerversion.h" #include #include #include InfoReaderMPV::InfoReaderMPV( QString mplayer_bin, const QString &snap, QObject * parent ) : QObject(parent) , mplayer_svn(0) , m_snap(snap) { mplayerbin = mplayer_bin; } InfoReaderMPV::~InfoReaderMPV() { } void InfoReaderMPV::getInfo() { vo_list.clear(); ao_list.clear(); demuxer_list.clear(); vc_list.clear(); ac_list.clear(); vf_list.clear(); mplayer_svn = -1; // old, 解决20.04上mpv help参数问题 // vo_list = getList(run("--vo help")); // ao_list = getList(run("--ao help")); // demuxer_list = getList(run("--demuxer help")); // vc_list = getList(run("--vd help")); // ac_list = getList(run("--ad help")); vo_list = getList(run("-vo help")); ao_list = getList(run("-ao help")); demuxer_list = getList(run("-demuxer help")); vc_list = getList(run("-vd help")); ac_list = getList(run("-ad help")); { //InfoList list = getList(run("--vf help"));//old InfoList list = getList(run("-vf help")); for (int n = 0; n < list.count(); n++) { vf_list.append(list[n].name()); } } QList lines = run("--version"); QString mpv_version_line; if (lines.count() >= 1) { mpv_version_line = lines[0]; mplayer_svn = MplayerVersion::mplayerVersion(mpv_version_line); mpv_version = MplayerVersion::mpvVersion(); } //qDebug() << "InfoReaderMPV::getInfo: version_line" << mpv_version_line; //qDebug() << "InfoReaderMPV::getInfo: mplayer_svn" << mplayer_svn; option_list = getOptionsList(run("--list-options")); //list(); } void InfoReaderMPV::list() { //qDebug("InfoReaderMPV::list"); InfoList::iterator it; qDebug(" vo_list:"); for ( it = vo_list.begin(); it != vo_list.end(); ++it ) { qDebug( "driver: '%s', desc: '%s'", (*it).name().toUtf8().data(), (*it).desc().toUtf8().data()); } qDebug(" ao_list:"); for ( it = ao_list.begin(); it != ao_list.end(); ++it ) { qDebug( "driver: '%s', desc: '%s'", (*it).name().toUtf8().data(), (*it).desc().toUtf8().data()); } qDebug(" demuxer_list:"); for ( it = demuxer_list.begin(); it != demuxer_list.end(); ++it ) { qDebug( "demuxer: '%s', desc: '%s'", (*it).name().toUtf8().data(), (*it).desc().toUtf8().data()); } qDebug(" vc_list:"); for ( it = vc_list.begin(); it != vc_list.end(); ++it ) { qDebug( "codec: '%s', desc: '%s'", (*it).name().toUtf8().data(), (*it).desc().toUtf8().data()); } qDebug(" ac_list:"); for ( it = ac_list.begin(); it != ac_list.end(); ++it ) { qDebug( "codec: '%s', desc: '%s'", (*it).name().toUtf8().data(), (*it).desc().toUtf8().data()); } } QList InfoReaderMPV::run(QString options) { qDebug("InfoReaderMPV::run: '%s'", options.toUtf8().data()); QList r; QProcess proc(this); proc.setProcessChannelMode( QProcess::MergedChannels ); QStringList args = options.split(" "); //edited by kobe 20180623 QString abs_bin; if (!this->m_snap.isEmpty()) { abs_bin = QString("%1%2").arg(this->m_snap).arg(mplayerbin); } else { abs_bin = mplayerbin; } proc.start(abs_bin, args); if (!proc.waitForStarted()) { qWarning("InfoReaderMPV::run: process can't start!"); return r; } //Wait until finish if (!proc.waitForFinished()) { qWarning("InfoReaderMPV::run: process didn't finish. Killing it..."); proc.kill(); } QByteArray data = proc.readAll().replace("\r", ""); r = data.split('\n'); return r; } InfoList InfoReaderMPV::getList(const QList & lines) { InfoList l; foreach(QByteArray line, lines) { qDebug() << "InfoReaderMPV::getList: line:" << line; line.replace("\n", ""); line = line.simplified(); if (line.startsWith("Available") || line.startsWith("demuxer:") || line.startsWith("Video decoders:") || line.startsWith("Audio decoders:")) { line = QByteArray(); } if (!line.isEmpty()) { int pos = line.indexOf(' '); if (pos > -1) { QString name = line.left(pos); if (name.endsWith(':')) name = name.left(name.count()-1); QString desc = line.mid(pos+1); desc = desc.replace(": ", "").replace("- ", ""); qDebug() << "InfoReaderMPV::getList: name:" << name << "desc:" << desc; l.append(InfoData(name, desc)); } } } return l; } QStringList InfoReaderMPV::getOptionsList(const QList & lines) { QStringList l; foreach(QByteArray line, lines) { //qDebug() << "InfoReaderMPV::getOptionsList: line:" << line; line.replace("\n", ""); line = line.simplified(); if (line.startsWith("--")) { int pos = line.indexOf(' '); if (pos > -1) { QString option_name = line.left(pos); //qDebug() << "InfoReaderMPV::getOptionsList: option:" << option_name; l << option_name; } } } return l; } //#include "moc_inforeadermpv.cpp" kylin-video/src/smplayer/prefperformance.ui0000644000175000017500000001203213517016402020065 0ustar fengfeng PrefPerformance 0 0 470 360 10 20 453 100 Cache 6 0 0 0 0 Cache for local files: cache_files_spin 100000 KB Cache for streams: cache_streams_spin 100000 KB 10 130 453 100 Decode 6 0 0 0 0 Threads for decoding (MPEG-1/2 and H.264 only): 1 16 1 Qt::Horizontal 40 20 Hardware decoding Qt::Horizontal 40 20 kylin-video/src/smplayer/mpvprocess.cpp0000644000175000017500000006060013637124037017270 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "mpvprocess.h" #include #include #include #include #include "global.h" #include "preferences.h" #include "mplayerversion.h" #include "colorutils.h" using namespace Global; #define CUSTOM_STATUS #define TOO_CHAPTERS_WORKAROUND static QRegExp mpv_screenshot("Screenshot: '(.*)'"); MPVProcess::MPVProcess(const QString &snap, QObject * parent) : PlayerProcess(parent) , notified_mplayer_is_running(false) , notified_pause(false) , received_end_of_file(false) , last_sub_id(-1) , mplayer_svn(-1) // Not found yet , verbose(false) , subtitle_info_received(false) , subtitle_info_changed(false) , selected_subtitle(-1) , audio_info_changed(false) , selected_audio(-1) , video_info_changed(false) , selected_video(-1) , chapter_info_changed(false) , dvd_current_title(-1) , br_current_title(-1) { this->m_snap = snap; m_playerId = Utils::MPV; connect( this, SIGNAL(lineAvailable(QByteArray)), this, SLOT(parseLine(QByteArray)) ); connect( this, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(processFinished(int,QProcess::ExitStatus)) ); connect( this, SIGNAL(error(QProcess::ProcessError)), this, SLOT(gotError(QProcess::ProcessError)) ); /* int svn = MplayerVersion::mplayerVersion("mpv unknown version (C)"); */ initializeOptionVars(); initializeRX(); } MPVProcess::~MPVProcess() { } bool MPVProcess::start() { md.reset(); notified_mplayer_is_running = false; notified_pause = false; last_sub_id = -1; mplayer_svn = -1; // Not found yet received_end_of_file = false; subs.clear(); subtitle_info_received = false; subtitle_info_changed = false; selected_subtitle = -1; audios.clear(); audio_info_changed = false; selected_audio = -1; videos.clear(); video_info_changed = false; selected_video = -1; //#if NOTIFY_CHAPTER_CHANGES chapters.clear(); chapter_info_changed = false; //#endif dvd_current_title = -1; br_current_title = -1; MyProcess::start(); return waitForStarted(); } void MPVProcess::initializeRX() { //#ifdef CUSTOM_STATUS rx_av.setPattern("STATUS: ([0-9\\.-]+) / ([0-9\\.-]+) P: (yes|no) B: (yes|no) I: (yes|no) VB: ([0-9\\.-]+) AB: ([0-9\\.-]+)");// new for ubuntukylin 20.04 and 16.04 //rx_av.setPattern("^STATUS: ([0-9\\.-]+) / ([0-9\\.-]+) P: (yes|no) B: (yes|no) I: (yes|no) VB: ([0-9\\.-]+) AB: ([0-9\\.-]+)"); //old, 在ubuntukylin 16.04上正常,但那是在ubuntukylin 20.04上无法获取视频的播放状态,即parseLine中解析会得不到想要的数据 //#else // rx_av.setPattern("(\\((.*)\\) |)(AV|V|A): ([0-9]+):([0-9]+):([0-9]+) / ([0-9]+):([0-9]+):([0-9]+)"); //AV: 00:02:15 / 00:09:56 // //rx_av.setPattern("^(\\((.*)\\) |)(AV|V|A): ([0-9]+):([0-9]+):([0-9]+) / ([0-9]+):([0-9]+):([0-9]+)"); //AV: 00:02:15 / 00:09:56 //old //#endif rx_dsize.setPattern("^INFO_VIDEO_DSIZE=(\\d+)x(\\d+)"); rx_vo.setPattern("^VO: \\[(.*)\\]"); rx_ao.setPattern("^AO: \\[(.*)\\]"); rx_paused.setPattern("^\\(Paused\\)"); rx_endoffile.setPattern("^Exiting... \\(End of file\\)"); rx_audio.setPattern("^.* Audio\\s+--aid=(\\d+)( --alang=([a-zA-Z-]+)|)([ \\(\\)\\*]+)('(.*)'|)"); rx_subs.setPattern("^.* Subs\\s+--sid=(\\d+)( --slang=([a-zA-Z-]+)|)([ \\(\\)\\*]+)('(.*)'|)"); rx_videocodec.setPattern("^INFO_VIDEO_CODEC=(.*)\\s"); rx_videocodec.setMinimal(true); rx_audiocodec.setPattern("^INFO_AUDIO_CODEC=(.*)\\s"); rx_audiocodec.setMinimal(true); //#if !NOTIFY_VIDEO_CHANGES // rx_video.setPattern("^.* Video\\s+--vid=(\\d+)([ \\(\\)\\*]+)('(.*)'|)"); //#endif rx_chaptername.setPattern("^INFO_CHAPTER_(\\d+)_NAME=(.*)"); rx_trackinfo.setPattern("^INFO_TRACK_(\\d+): (audio|video|sub) (\\d+) '(.*)' '(.*)' (yes|no)"); rx_forbidden.setPattern("HTTP error 403 Forbidden"); rx_playing.setPattern("^Playing:.*|^\\[ytdl_hook\\].*"); rx_generic.setPattern("^([A-Z_]+)=(.*)"); rx_stream_title.setPattern("icy-title: (.*)"); rx_debug.setPattern("^(INFO|METADATA)_.*=\\$.*"); } void MPVProcess::parseLine(QByteArray ba) { //qDebug() << "MPVProcess::parseLine:" << ba; if (ba.isEmpty()) return; QString tag; QString value; //COLOR_OUTPUT_SUPPORT for windows //#if COLOR_OUTPUT_SUPPORT // QString line = ColorUtils::stripColorsTags(QString::fromLocal8Bit(ba)); //#else // #ifdef Q_OS_WIN // QString line = QString::fromUtf8(ba); // #else QString line = QString::fromLocal8Bit(ba); // #endif //#endif if (verbose) { line.replace("[statusline] ", ""); line.replace("[cplayer] ", ""); line.replace("[term-msg] ", ""); if (rx_debug.indexIn(line) > -1) { line = "[debug] " + line; } } static double last_sec = -1; // Parse A: V: line //qDebug("MPVProcess::parseLine: %s", line.toUtf8().data()); if (rx_av.indexIn(line) > -1) { // #ifdef CUSTOM_STATUS double sec = rx_av.cap(1).toDouble(); double length = rx_av.cap(2).toDouble(); bool paused = (rx_av.cap(3) == "yes"); bool buffering = (rx_av.cap(4) == "yes"); bool idle = (rx_av.cap(5) == "yes"); int video_bitrate = rx_av.cap(6).toInt(); int audio_bitrate = rx_av.cap(7).toInt(); if (length != md.duration) { md.duration = length; // #if DVDNAV_SUPPORT // emit receivedDuration(length); // #endif } if (paused && notified_pause) { if (last_sec != sec) { last_sec = sec; emit receivedCurrentSec(sec); emit receivedPause(); } return; } if (paused) { notified_pause = true; //qDebug("MPVProcess::parseLine: paused"); emit receivedPause(); return; } else if (buffering) { //qDebug("MPVProcess::parseLine: buffering"); emit receivedBuffering(); return; } else if (idle) { //qDebug("MPVProcess::parseLine: idle"); emit receivedBuffering(); return; } notified_pause = false; if (video_bitrate != md.video_bitrate) { md.video_bitrate = video_bitrate; emit receivedVideoBitrate(video_bitrate); } if (audio_bitrate != md.audio_bitrate) { md.audio_bitrate = audio_bitrate; emit receivedAudioBitrate(audio_bitrate); } /*#else //qDebug() << rx_av.cap(1); //qDebug() << rx_av.cap(2); QString status = rx_av.cap(2).trimmed(); int i = 4; int h = rx_av.cap(i++).toInt(); int m = rx_av.cap(i++).toInt(); int s = rx_av.cap(i++).toInt(); //qDebug("%d:%d:%d", h, m, s); double sec = h * 3600 + m * 60 + s; h = rx_av.cap(i++).toInt(); m = rx_av.cap(i++).toInt(); s = rx_av.cap(i++).toInt(); double length = h * 3600 + m * 60 + s; if (length != md.duration) { md.duration = length; emit receivedDuration(length); } if (status == "Paused") { emit receivedPause(); return; } else if ((status == "...") || (status == "Buffering")) { emit receivedBuffering(); return; } if (!status.isEmpty()) { qDebug() << "MPVProcess::parseLine: status:" << status; } #endif*/ if (notified_mplayer_is_running) { if (subtitle_info_changed && sec > 0.4) { //qDebug("MPVProcess::parseLine: subtitle_info_changed"); subtitle_info_changed = false; subtitle_info_received = false; emit subtitleInfoChanged(subs, selected_subtitle); } if (subtitle_info_received) { //qDebug("MPVProcess::parseLine: subtitle_info_received"); subtitle_info_received = false; emit subtitleInfoReceivedAgain(subs); } } if (notified_mplayer_is_running) { if (audio_info_changed && sec > 0.4) { //qDebug("MPVProcess::parseLine: audio_info_changed"); audio_info_changed = false; emit audioInfoChanged(audios, selected_audio); } } if (notified_mplayer_is_running) { if (video_info_changed) { //qDebug("MPVProcess::parseLine: video_info_changed"); video_info_changed = false; emit videoInfoChanged(videos, selected_video); } } //#if NOTIFY_CHAPTER_CHANGES if (notified_mplayer_is_running) { if (chapter_info_changed) { //qDebug("MPVProcess::parseLine: chapter_info_changed"); chapter_info_changed = false; emit chaptersChanged(chapters); } } //#endif if (!notified_mplayer_is_running) { //qDebug() << "MPVProcess::parseLine: starting sec:" << sec; if (md.video_width == 0 || md.video_height == 0) { md.novideo = true; emit receivedNoVideo(); } emit receivedStartingTime(sec); emit mplayerFullyLoaded(); emit receivedCurrentFrame(0); // Ugly hack: set the frame counter to 0 notified_mplayer_is_running = true; } emit receivedCurrentSec( sec ); } else { emit lineAvailable(line); // Parse other things //qDebug() << "MPVProcess::parseLine:" << line; if (mpv_screenshot.indexIn(line) > -1) {//20170722 QString shot = mpv_screenshot.cap(1); // qDebug() << "shot="< -1) { qDebug("MVPProcess::parseLine: detected end of file"); if (!received_end_of_file) { // In case of playing VCDs or DVDs, maybe the first title // is not playable, so the GUI doesn't get the info about // available titles. So if we received the end of file // first let's pretend the file has started so the GUI can have // the data. if ( !notified_mplayer_is_running) { emit mplayerFullyLoaded(); } // Send signal once the process is finished, not now! received_end_of_file = true; } } else // Window resolution if (rx_dsize.indexIn(line) > -1) { int w = rx_dsize.cap(1).toInt(); int h = rx_dsize.cap(2).toInt(); emit receivedWindowResolution( w, h ); } else // VO if (rx_vo.indexIn(line) > -1) { emit receivedVO( rx_vo.cap(1) ); // Ask for window resolution writeToStdin("print_text INFO_VIDEO_DSIZE=${=dwidth}x${=dheight}"); } else // AO if (rx_ao.indexIn(line) > -1) { emit receivedAO( rx_ao.cap(1) ); } else // Audio if (rx_audio.indexIn(line) > -1) { int ID = rx_audio.cap(1).toInt(); QString lang = rx_audio.cap(3); QString title = rx_audio.cap(6); updateAudioTrack(ID, title, lang, false); } else if (rx_stream_title.indexIn(line) > -1) { QString s = rx_stream_title.cap(1); //qDebug() << "MPVProcess::parseLine: stream_title:" << s; md.stream_title = s; emit receivedStreamTitle(s); } else // Subtitles if (rx_subs.indexIn(line) > -1) { int ID = rx_subs.cap(1).toInt(); QString lang = rx_subs.cap(3); QString title = rx_subs.cap(6); //qDebug() << "MPVProcess::parseLine: sub id:" << ID << "lang:" << lang << "name:" << title; updateSubtitleTrack(ID, title, lang, false); } else // Chapters if (rx_chaptername.indexIn(line) > -1) { int ID = rx_chaptername.cap(1).toInt(); QString title = rx_chaptername.cap(2); if (title.isEmpty()) title = QString::number(ID + 1); chapters.addName(ID, title); chapter_info_changed = true; //qDebug() << "MPVProcess::parseLine: chapter id:" << ID << "title:" << title; } else // Track info if (rx_trackinfo.indexIn(line) > -1) { int ID = rx_trackinfo.cap(3).toInt(); QString type = rx_trackinfo.cap(2); QString name = rx_trackinfo.cap(5); QString lang = rx_trackinfo.cap(4); QString selected = rx_trackinfo.cap(6); //qDebug() << "MPVProcess::parseLine: ID:" << ID << "type:" << type << "name:" << name << "lang:" << lang << "selected:" << selected; /* if (lang == "(unavailable)") lang = ""; if (name == "(unavailable)") name = ""; */ if (type == "video") { updateVideoTrack(ID, name, lang, (selected == "yes")); } else if (type == "audio") { updateAudioTrack(ID, name, lang, (selected == "yes")); } else if (type == "sub") { updateSubtitleTrack(ID, name, lang, (selected == "yes")); } } else //#if DVDNAV_SUPPORT // if (rx_switch_title.indexIn(line) > -1) { // int title = rx_switch_title.cap(1).toInt(); // qDebug("MPVProcess::parseLine: title changed to %d", title); // // Ask for track info // // Wait 10 secs. because it can take a while until the title start to play // QTimer::singleShot(10000, this, SLOT(requestChapterInfo())); // } // else //#endif //Playing if (rx_playing.indexIn(line) > -1) { emit receivedPlaying(); } else if (rx_videocodec.indexIn(line) > -1) { md.video_codec = rx_videocodec.cap(1); //qDebug() << "MPVProcess::parseLine: md.video_codec:" << md.video_codec; } else if (rx_audiocodec.indexIn(line) > -1) { md.audio_codec = rx_audiocodec.cap(1); //qDebug() << "MPVProcess::parseLine: md.audio_codec:" << md.audio_codec; } else if (rx_forbidden.indexIn(line) > -1) { //qDebug("MVPProcess::parseLine: 403 forbidden"); emit receivedForbiddenText(); } //Generic things if (rx_generic.indexIn(line) > -1) { tag = rx_generic.cap(1); value = rx_generic.cap(2); //qDebug("MPVProcess::parseLine: tag: %s", tag.toUtf8().constData()); //qDebug("MPVProcess::parseLine: value: %s", value.toUtf8().constData()); if (tag == "INFO_VIDEO_WIDTH") { md.video_width = value.toInt(); //qDebug("MPVProcess::parseLine: md.video_width set to %d", md.video_width); } else if (tag == "INFO_VIDEO_HEIGHT") { md.video_height = value.toInt(); //qDebug("MPVProcess::parseLine: md.video_height set to %d", md.video_height); } else if (tag == "INFO_VIDEO_ASPECT") { md.video_aspect = value.toDouble(); if ( md.video_aspect == 0.0 ) { // I hope width & height are already set. md.video_aspect = (double) md.video_width / md.video_height; } //qDebug() << "MPVProcess::parseLine: md.video_aspect set to" << md.video_aspect; } if (tag == "INFO_VIDEO_BITRATE") { int bitrate = value.toInt(); emit receivedVideoBitrate(bitrate); } else if (tag == "INFO_LENGTH") { md.duration = value.toDouble(); //qDebug() << "MPVProcess::parseLine: md.duration set to" << md.duration; } else if (tag == "INFO_DEMUXER") { md.demuxer = value; } else if (tag == "INFO_VIDEO_FORMAT") { md.video_format = value; } if (tag == "INFO_VIDEO_FPS") { md.video_fps = value; } else /* if (tag == "INFO_VIDEO_CODEC") { md.video_codec = value; } else if (tag == "INFO_AUDIO_CODEC") { md.audio_codec = value; } else */ if (tag == "INFO_AUDIO_BITRATE") { int bitrate = value.toInt(); emit receivedAudioBitrate(bitrate); } else if (tag == "INFO_AUDIO_RATE") { md.audio_rate = value.toInt(); } else if (tag == "INFO_AUDIO_NCH") { md.audio_nch = value.toInt(); } else if (tag == "INFO_AUDIO_FORMAT") { md.audio_format = value; } else if (tag == "INFO_CHAPTERS") { md.n_chapters = value.toInt(); // #ifdef TOO_CHAPTERS_WORKAROUND if (md.n_chapters > 1000) { //qDebug("MPVProcess::parseLine: warning too many chapters: %d", md.n_chapters); //qDebug(" chapters will be ignored"); md.n_chapters = 0; } // #endif for (int n = 0; n < md.n_chapters; n++) { writeToStdin(QString("print_text INFO_CHAPTER_%1_NAME=${chapter-list/%1/title}").arg(n)); } } else if (tag == "INFO_TITLES") { int n_titles = value.toInt(); for (int ID = 0; ID < n_titles; ID++) { md.titles.addName(ID, QString::number(ID+1)); } } else if (tag == "METADATA_TITLE") { if (!value.isEmpty()) md.clip_name = value; } else if (tag == "METADATA_ARTIST") { if (!value.isEmpty()) md.clip_artist = value; } else if (tag == "METADATA_DATE") { if (!value.isEmpty()) md.clip_date = value; } else if (tag == "METADATA_ALBUM") { if (!value.isEmpty()) md.clip_album = value; } else if (tag == "METADATA_COPYRIGHT") { if (!value.isEmpty()) md.clip_copyright = value; } else if (tag == "METADATA_TRACK") { if (!value.isEmpty()) md.clip_track = value; } else if (tag == "METADATA_GENRE") { if (!value.isEmpty()) md.clip_genre = value; } else if (tag == "INFO_MEDIA_TITLE") { if (!value.isEmpty() && value != "mp4" && !value.startsWith("mp4&") /*&& md.clip_name.isEmpty()*/) { md.clip_name = value; } } else if (tag == "INFO_STREAM_PATH") { QRegExp rx("edl://%\\d+%(.*)"); if (rx.indexIn(line) > -1) { md.stream_path = rx.cap(1); } else { md.stream_path = value; } } else if (tag == "MPV_VERSION") { mpv_version = value; if (mpv_version.startsWith("mpv ")) mpv_version = mpv_version.mid(4); //qDebug() << "MPVProcess::parseLine: mpv version:" << mpv_version; MplayerVersion::mplayerVersion("mpv " + mpv_version + " (C)"); } else if (tag == "INFO_TRACKS_COUNT") { int tracks = value.toInt(); for (int n = 0; n < tracks; n++) { writeToStdin(QString("print_text \"INFO_TRACK_%1: " "${track-list/%1/type} " "${track-list/%1/id} " "'${track-list/%1/lang:}' " "'${track-list/%1/title:}' " "${track-list/%1/selected}\"").arg(n)); } } } } } void MPVProcess::requestChapterInfo() { writeToStdin("print_text \"INFO_CHAPTERS=${=chapters}\""); } //void MPVProcess::requestBitrateInfo() { // writeToStdin("print_text INFO_VIDEO_BITRATE=${=video-bitrate}"); // writeToStdin("print_text INFO_AUDIO_BITRATE=${=audio-bitrate}"); //} void MPVProcess::updateVideoTrack(int ID, const QString & name, const QString & lang, bool selected) { int idx = videos.find(ID); if (idx == -1) { video_info_changed = true; videos.addName(ID, name); videos.addLang(ID, lang); } else { // Track already existed if (videos.itemAt(idx).name() != name) { video_info_changed = true; videos.addName(ID, name); } if (videos.itemAt(idx).lang() != lang) { video_info_changed = true; videos.addLang(ID, lang); } } if (selected && selected_video != ID) { selected_video = ID; video_info_changed = true; } } void MPVProcess::updateAudioTrack(int ID, const QString & name, const QString & lang, bool selected) { //qDebug("MPVProcess::updateAudioTrack: ID: %d", ID); int idx = audios.find(ID); if (idx == -1) { audio_info_changed = true; audios.addName(ID, name); audios.addLang(ID, lang); } else { // Track already existed if (audios.itemAt(idx).name() != name) { audio_info_changed = true; audios.addName(ID, name); } if (audios.itemAt(idx).lang() != lang) { audio_info_changed = true; audios.addLang(ID, lang); } } if (selected && selected_audio != ID) { selected_audio = ID; audio_info_changed = true; } } void MPVProcess::updateSubtitleTrack(int ID, const QString & name, const QString & lang, bool selected) { qDebug("MPVProcess::updateSubtitleTrack: ID: %d", ID); int idx = subs.find(SubData::Sub, ID); if (idx == -1) { subtitle_info_changed = true; subs.add(SubData::Sub, ID); subs.changeName(SubData::Sub, ID, name); subs.changeLang(SubData::Sub, ID, lang); } else { // Track already existed if (subs.itemAt(idx).name() != name) { subtitle_info_changed = true; subs.changeName(SubData::Sub, ID, name); } if (subs.itemAt(idx).lang() != lang) { subtitle_info_changed = true; subs.changeLang(SubData::Sub, ID, lang); } } if (selected && selected_subtitle != ID) { selected_subtitle = ID; subtitle_info_changed = true; } } // Called when the process is finished void MPVProcess::processFinished(int exitCode, QProcess::ExitStatus exitStatus) { qDebug("MPVProcess::processFinished: exitCode: %d, status: %d", exitCode, (int) exitStatus); // Send this signal before the endoffile one, otherwise // the playlist will start to play next file before all // objects are notified that the process has exited. emit processExited(); if (received_end_of_file) emit receivedEndOfFile(); } void MPVProcess::gotError(QProcess::ProcessError error) { qDebug("MPVProcess::gotError: %d", (int) error); } #include "mpvoptions.cpp" //#include "moc_mpvprocess.cpp" kylin-video/src/smplayer/timeslider.cpp0000644000175000017500000002047313637124061017231 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "timeslider.h" #include "../utils.h" #include #include #include #include #include #include #include "../timetip.h" TimeSlider::TimeSlider( QWidget * parent ) : MySlider(parent) , dont_update(false) , position(0) , total_time(0) { setMinimum(0); setMaximum(SEEKBAR_RESOLUTION); setFocusPolicy( Qt::NoFocus ); setSizePolicy( QSizePolicy::Expanding , QSizePolicy::Fixed ); preview = false; connect( this, SIGNAL( sliderPressed() ), this, SLOT( stopUpdate() ) ); connect( this, SIGNAL( sliderReleased() ), this, SLOT( resumeUpdate() ) ); connect( this, SIGNAL( sliderReleased() ), this, SLOT( mouseReleased() ) ); connect( this, SIGNAL( valueChanged(int) ), this, SLOT( valueChanged_slot(int) ) ); connect( this, SIGNAL(draggingPos(int) ), this, SLOT(checkDragging(int)) ); cur_pos = QPoint(0,0); last_pos_to_send = -1; timer = new QTimer(this); connect( timer, SIGNAL(timeout()), this, SLOT(sendDelayedPos()) ); timer->start(200); hintWidget = new TimeTip("00:00:00", this); // hintWidget->setFixedHeight(60); hintWidget->setFixedSize(67,60);//kobe: 如果不设置固定宽度,则宽度初始值默认为100,后续自动变为67,导致第一次使用默认值时显示的时间信息的坐标有偏移 installEventFilter(this); } TimeSlider::~TimeSlider() { } void TimeSlider::hideTip() { this->hintWidget->hide(); } void TimeSlider::stopUpdate() { dont_update = true; } void TimeSlider::resumeUpdate() { dont_update = false; } void TimeSlider::mouseReleased() { emit posChanged( value() ); } void TimeSlider::valueChanged_slot(int v) { // Only to make things clear: bool dragging = dont_update; if (!dragging) { if (v!=position) { emit posChanged(v); } } else { emit draggingPos(v); } } void TimeSlider::setDragDelay(int d) { // qDebug("TimeSlider::setDragDelay: %d", d); timer->setInterval(d); } int TimeSlider::dragDelay() { return timer->interval(); } void TimeSlider::checkDragging(int v) { // qDebug("TimeSlider::checkDragging: %d", v); last_pos_to_send = v; } void TimeSlider::sendDelayedPos() { // qDebug("TimeSlider::sendDelayedPos: %d", last_pos_to_send); if (last_pos_to_send != -1) { emit delayedDraggingPos(last_pos_to_send); last_pos_to_send = -1; } } void TimeSlider::setPos(int v) { if (v!=pos()) { if (!dont_update) { position = v; setValue(v); } } } int TimeSlider::pos() { return position; } void TimeSlider::wheelEvent(QWheelEvent * e) { //e->ignore(); // qDebug("TimeSlider::wheelEvent: delta: %d", e->delta()); e->accept(); if (e->orientation() == Qt::Vertical) { if (e->delta() >= 0) emit wheelUp(); else emit wheelDown(); } else { qDebug("Timeslider::wheelEvent: horizontal event received, doing nothing"); } } void TimeSlider::enterEvent(QEvent *) { emit this->active_status(true); } void TimeSlider::leaveEvent(QEvent *event) { emit this->active_status(false); emit requestHideTip(); event->ignore(); QSlider::leaveEvent(event); } void TimeSlider::show_time_value(int time) { // hintWidget->setFixedHeight(60); hintWidget->setFixedSize(67,60);//kobe: 如果不设置固定宽度,则宽度初始值默认为100,后续自动变为67,导致第一次使用默认值时显示的时间信息的坐标有偏移 hintWidget->setText(Utils::formatTime(time)); QPoint curPos = this->mapToGlobal(cur_pos); QSize sz = this->hintWidget->size(); curPos.setX(curPos.x() - sz.width() / 2); curPos.setY(curPos.y() - sz.height());//- 32 curPos = this->hintWidget->mapFromGlobal(curPos); curPos = this->hintWidget->mapToParent(curPos); this->hintWidget->move(curPos); this->hintWidget->show(); this->setCursor(QCursor(Qt::PointingHandCursor)); } void TimeSlider::set_preview_flag(bool b) { preview = b; if (!preview) { hintWidget->setFixedSize(67,60); } } void TimeSlider::show_save_preview_image(int time, QString filepath) { if (filepath.isEmpty()) { this->show_time_value(time); } else { QPixmapCache::clear(); // QPixmapCache::setCacheLimit(1); QPixmap picture; if (!picture.load(filepath)) { this->show_time_value(time); return; } QPixmap scaled_picture = picture.scaledToWidth(200, Qt::SmoothTransformation); // hintWidget->setFixedHeight(200); hintWidget->setFixedSize(200, scaled_picture.size().height() + 30);//kobe: 如果不设置固定宽度,则宽度初始值默认为100,后续自动变为67,导致第一次使用默认值时显示的时间信息的坐标有偏移 hintWidget->setPixMapAndTime(scaled_picture, Utils::formatTime(time)); QPoint curPos = this->mapToGlobal(cur_pos); QSize sz = this->hintWidget->size(); curPos.setX(curPos.x() - sz.width() / 2); curPos.setY(curPos.y() - sz.height());//- 32 curPos = this->hintWidget->mapFromGlobal(curPos); curPos = this->hintWidget->mapToParent(curPos); this->hintWidget->move(curPos); this->hintWidget->show(); this->setCursor(QCursor(Qt::PointingHandCursor)); } } //kobe:鼠标放在进度条上时显示时间进度,移开鼠标则消失 bool TimeSlider::event(QEvent *event) { if (event->type() == QEvent::ToolTip) { QHelpEvent * help_event = static_cast(event); int pos_in_slider = help_event->x() * maximum() / width(); cur_pos = help_event->pos(); int time = pos_in_slider * total_time / maximum(); if (time >= 0 && time <= total_time) { //QToolTip::showText(help_event->globalPos(), Utils::formatTime(time), this); if (preview) { emit this->requestSavePreviewImage(time, cur_pos); } else { hintWidget->setText(Utils::formatTime(time)); // QPoint centerPos = this->mapToGlobal(this->rect().center()); // QSize sz = this->hintWidget->size(); // centerPos.setX(centerPos.x() - sz.width() / 2); // centerPos.setY(centerPos.y() - 32 - sz.height()); // centerPos = this->hintWidget->mapFromGlobal(centerPos); // centerPos = this->hintWidget->mapToParent(centerPos); // this->hintWidget->move(centerPos); QPoint curPos = this->mapToGlobal(help_event->pos()); QSize sz = this->hintWidget->size(); curPos.setX(curPos.x() - sz.width() / 2); curPos.setY(curPos.y() - sz.height());//- 32 curPos = this->hintWidget->mapFromGlobal(curPos); curPos = this->hintWidget->mapToParent(curPos); this->hintWidget->move(curPos); this->hintWidget->show(); this->setCursor(QCursor(Qt::PointingHandCursor)); } // } else { cur_pos = QPoint(0,0); // QToolTip::hideText(); event->ignore(); } return true; } return QWidget::event(event); } bool TimeSlider::eventFilter(QObject *obj, QEvent *event) { switch (event->type()) { case QEvent::Leave: { if (this->hintWidget) { this->hintWidget->hide(); } this->unsetCursor(); break; } case QEvent::MouseButtonPress: if (this->hintWidget) { this->hintWidget->hide(); } break; default: break; } return QObject::eventFilter(obj, event); } //#include "moc_timeslider.cpp" kylin-video/src/smplayer/chapters.cpp0000644000175000017500000000537413517016402016700 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2018 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "chapters.h" Chapters::Chapters() { clear(); } Chapters::~Chapters() { } void Chapters::clear() { cm.clear(); } void Chapters::addName(int ID, QString name) { cm[ID].setName(name); cm[ID].setID(ID); } void Chapters::addStart(int ID, double start) { cm[ID].setStart(start); cm[ID].setID(ID); } void Chapters::addEnd(int ID, double end) { cm[ID].setEnd(end); cm[ID].setID(ID); } void Chapters::addID(int ID) { cm[ID].setID(ID); } int Chapters::numItems() { return cm.count(); } bool Chapters::existsItemAt(int n) { return ((n > 0) && (n < numItems())); } ChapterData Chapters::itemAt(int n) { return cm.values()[n]; } ChapterData Chapters::item(int ID) { return cm[ID]; } ChapterData Chapters::itemFromTime(double sec) { QMapIterator i(cm); while(i.hasNext()) { i.next(); ChapterData d = i.value(); if(d.start() <= sec && d.end() >= sec) return d; } return cm[-1]; } ChapterData Chapters::itemAfterTime(double sec) { QMapIterator i(cm); int ID = -1; double min_time = 1.7976931348623158e+308; while(i.hasNext()) { i.next(); ChapterData d = i.value(); if(d.start() > sec && d.start() < min_time) { ID = d.ID(); min_time = d.start(); } } return cm[ID]; } ChapterData Chapters::itemBeforeTime(double sec) { QMapIterator i(cm); int ID = -1; double max_time = 0; while(i.hasNext()) { i.next(); ChapterData d = i.value(); if(d.end() < sec && d.end() > max_time) { ID = d.ID(); max_time = d.end(); } } return cm[ID]; } int Chapters::find(int ID) { for (int n=0; n < numItems(); n++) { if (itemAt(n).ID() == ID) return n; } return -1; } void Chapters::list() { QMapIterator i(cm); while (i.hasNext()) { i.next(); ChapterData d = i.value(); qDebug("Chapters::list: item %d: ID: %d name: '%s' start: %g end: %g", i.key(), d.ID(), d.name().toUtf8().constData(), d.start(), d.end() ); } } kylin-video/src/smplayer/mplayerversion.cpp0000644000175000017500000002014113517016402020133 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "mplayerversion.h" #include "global.h" #include "preferences.h" #include using namespace Global; //QString MplayerVersion::mplayer2_version; QString MplayerVersion::mpv_version; //bool MplayerVersion::is_mplayer2 = false; bool MplayerVersion::is_mpv = false; int MplayerVersion::mplayerVersion(QString string) { //static QRegExp rx_mplayer_revision("^MPlayer (\\S+)-SVN-r(\\d+)-(.*)"); static QRegExp rx_mplayer_revision("^MPlayer (.*)[-\\.]r(\\d+)(.*)"); static QRegExp rx_mplayer_version("^MPlayer ([a-z0-9.]+)[-(.*)| (.*)]"); static QRegExp rx_mplayer_git("^MPlayer GIT(.*)", Qt::CaseInsensitive); static QRegExp rx_mplayer_version_final("1.0rc([0-9])"); static QRegExp rx_mplayer2_version("^MPlayer2 (.*) \\(C\\).*", Qt::CaseInsensitive); static QRegExp rx_mpv_version("^mpv (.*) \\(C\\).*", Qt::CaseInsensitive); static QRegExp rx_mplayer_version_ubuntu("^MPlayer (\\d):(\\d)\\.(\\d)~(.*)"); static QRegExp rx_mplayer_revision_ubuntu("^MPlayer svn r(\\d+) (.*)"); static QRegExp rx_mplayer_version_mandriva("^MPlayer ([a-z0-9\\.]+)-\\d+\\.([a-z0-9]+)\\.[\\d\\.]+[a-z]+[\\d\\.]+-(.*)"); int mplayer_svn = 0; // mplayer2_version = QString::null; // is_mplayer2 = false; is_mpv = false; // Hack to recognize mplayer 1.0rc1 from Ubuntu: if (rx_mplayer_version_ubuntu.indexIn(string) > -1) { int v1 = rx_mplayer_version_ubuntu.cap(2).toInt(); int v2 = rx_mplayer_version_ubuntu.cap(3).toInt(); QString rest = rx_mplayer_version_ubuntu.cap(4); //qDebug("%d - %d - %d", rx_mplayer_version_ubuntu.cap(1).toInt(), v1 , v2); string = QString("MPlayer %1.%2%3").arg(v1).arg(v2).arg(rest); //qDebug("MplayerVersion::mplayerVersion: line converted to '%s'", string.toUtf8().data()); } else if (rx_mplayer_revision_ubuntu.indexIn(string) > -1) { int svn = rx_mplayer_revision_ubuntu.cap(1).toInt(); QString rest = rx_mplayer_revision_ubuntu.cap(2); string = QString("MPlayer SVN-r%1-%2").arg(svn).arg(rest); //qDebug("MplayerVersion::mplayerVersion: line converted to '%s'", string.toUtf8().data()); } // Hack to recognize mplayer version from Mandriva: if (rx_mplayer_version_mandriva.indexIn(string) > -1) { QString v1 = rx_mplayer_version_mandriva.cap(1); QString v2 = rx_mplayer_version_mandriva.cap(2); QString rest = rx_mplayer_version_mandriva.cap(3); string = QString("MPlayer %1%2-%3").arg(v1).arg(v2).arg(rest); //qDebug("MplayerVersion::mplayerVersion: line converted to '%s'", string.toUtf8().data()); } if (rx_mplayer_git.indexIn(string) > -1) { //qDebug("MplayerVersion::mplayerVersion: MPlayer from git. Assuming >= 1.0rc3"); mplayer_svn = MPLAYER_1_0_RC3_SVN; } else if (rx_mplayer_revision.indexIn(string) > -1) { mplayer_svn = rx_mplayer_revision.cap(2).toInt(); //qDebug("MplayerVersion::mplayerVersion: MPlayer SVN revision found: %d", mplayer_svn); } else if (rx_mplayer_version.indexIn(string) > -1) { QString version = rx_mplayer_version.cap(1); //qDebug("MplayerVersion::mplayerVersion: MPlayer version found: %s", version.toUtf8().data()); mplayer_svn = 0; if (version == "1.2") mplayer_svn = MPLAYER_1_2; else if (version == "1.1") mplayer_svn = MPLAYER_1_1; else if (version == "1.0rc4") mplayer_svn = MPLAYER_1_0_RC4_SVN; else if (version == "1.0rc3") mplayer_svn = MPLAYER_1_0_RC3_SVN; else if (version == "1.0rc2") mplayer_svn = MPLAYER_1_0_RC2_SVN; else if (version == "1.0rc1") mplayer_svn = MPLAYER_1_0_RC1_SVN; else /* if(rx_mplayer_version_final.indexIn(version) > -1 && rx_mplayer_version_final.cap(1).toInt() > 3) mplayer_svn = MPLAYER_1_0_RC3_SVN; //version is > 1.0rc3, so treat as 1.0rc3 since support for later versions is not yet implemented else qWarning("MplayerVersion::mplayerVersion: unknown MPlayer version"); */ // Assume it's at least mplayer 1.2 mplayer_svn = MPLAYER_1_2; } // else // mplayer_svn = MPLAYER_1_2; // else // if (rx_mplayer2_version.indexIn(string) > -1) { // mplayer2_version = rx_mplayer2_version.cap(1); // qDebug("MplayerVersion::mplayerVersion: MPlayer2 version found: %s", mplayer2_version.toUtf8().data()); // is_mplayer2 = true; // mplayer_svn = MPLAYER_1_0_RC4_SVN; // simulates mplayer 1.0rc4 // } else if (rx_mpv_version.indexIn(string) > -1) { mpv_version = rx_mpv_version.cap(1); //qDebug("MplayerVersion::mplayerVersion: mpv version found: %s", mpv_version.toUtf8().data()); is_mpv = true; // is_mplayer2 = true; mplayer_svn = MPLAYER_1_0_RC4_SVN; // simulates mplayer 1.0rc4 } else mplayer_svn = MPLAYER_1_2; if (pref) { pref->mplayer_detected_version = mplayer_svn; // pref->mplayer_is_mplayer2 = is_mplayer2; // pref->mplayer2_detected_version = mplayer2_version; } //qDebug("MplayerVersion::mplayerVersion: mplayer_svn: %d", mplayer_svn); return mplayer_svn; } bool MplayerVersion::isMplayerAtLeast(int mplayer_svn, int svn_revision) { //qDebug("MplayerVersion::isMplayerAtLeast: comparing %d with %d", svn_revision, mplayer_svn); if (mplayer_svn == -1) { //qWarning("MplayerVersion::isMplayerAtLeast: no version found!"); } else if (mplayer_svn == 0) { //qWarning("MplayerVersion::isMplayerAtLeast: version couldn't be parsed!"); } if (mplayer_svn <= 0) { //qWarning("MplayerVersion::isMplayerAtLeast: assuming that the mplayer version is less than %d", svn_revision); return false; } return (mplayer_svn >= svn_revision); } bool MplayerVersion::isMplayerAtLeast(int svn_revision) { if (pref->mplayer_detected_version >= MPLAYER_1_0_RC1_SVN) { // SVN version seems valid if (pref->mplayer_user_supplied_version != -1) { //qDebug("MplayerVersion::isMplayerAtLeast: using the parsed svn version from mplayer output"); //qDebug("MplayerVersion::isMplayerAtLeast: and clearing the previously user supplied version"); pref->mplayer_user_supplied_version = -1; } return isMplayerAtLeast(pref->mplayer_detected_version, svn_revision); } else if (pref->mplayer_user_supplied_version != -1) { //qDebug("MplayerVersion::isMplayerAtLeast: no parsed version, using user supplied version"); return isMplayerAtLeast(pref->mplayer_user_supplied_version, svn_revision); } else { //qWarning("MplayerVersion::isMplayerAtLeast: there's no parsed version nor user supplied version!"); return isMplayerAtLeast(pref->mplayer_detected_version, svn_revision); } } QString MplayerVersion::toString(int svn_revision) { QString version; switch (svn_revision) { case MPLAYER_1_0_RC1_SVN: version = QString("1.0rc1"); break; case MPLAYER_1_0_RC2_SVN: version = QString("1.0rc2"); break; case MPLAYER_1_0_RC3_SVN: version = QString("1.0rc3"); break; case MPLAYER_1_0_RC4_SVN: version = QString("1.0rc4"); break; case MPLAYER_1_1: version = QString("1.1"); break; default : version = QString("SVN r%1").arg(svn_revision); } return version; } kylin-video/src/smplayer/filters.h0000644000175000017500000000372113517016402016176 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2018 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Default options for the video and audio filters */ #ifndef FILTERS_H #define FILTERS_H #include #include #include class QSettings; class Filter { public: Filter() {}; Filter(QString tr_name, QString name, QString options = QString::null) { _tr_name = tr_name; _name = name; _options = options; }; void setTrName(QString tr_name) { _tr_name = tr_name; }; void setName(QString name) { _name = name; }; void setOptions(QString options) { _options = options; }; QString trName() const { return _tr_name; }; QString name() const { return _name; }; QString options() const { return _options; }; QString filter() { QString s = name(); if (!options().isEmpty()) s += "="+options(); return s; } protected: QString _tr_name, _name, _options; }; typedef QMap FilterMap; class Filters : public QObject { Q_OBJECT public: Filters(QObject * parent = 0); void init(); Filter item(const QString & key); void setFilters(FilterMap filters) { list = filters; }; FilterMap filters() { return list; }; void save(QSettings *set); void load(QSettings *set); protected: FilterMap list; }; #endif kylin-video/src/smplayer/version.h0000644000175000017500000000174013517016402016212 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef VERSION_H #define VERSION_H #include class Version { public: static QString printable(); static QString stable(); }; #endif kylin-video/src/smplayer/mplayerversion.h0000644000175000017500000000355113517016402017606 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MPLAYERVERSION_H_ #define _MPLAYERVERSION_H_ #include #define MPLAYER_1_0_RC1_SVN 20372 #define MPLAYER_1_0_RC2_SVN 24722 #define MPLAYER_1_0_RC3_SVN 31272 #define MPLAYER_1_0_RC4_SVN 33472 #define MPLAYER_1_1 34992 #define MPLAYER_1_2 37540 class MplayerVersion { public: //! Parses the mplayer svn version from the string and returns it. //! If the parsing fails, returns 0 static int mplayerVersion(QString string); //! Returns true if svn_revision is equal or greater than mplayer_svn static bool isMplayerAtLeast(int mplayer_svn, int svn_revision); static bool isMplayerAtLeast(int svn_revision); // static bool isMplayer2() { return is_mplayer2; }; static bool isMPV() { return is_mpv; }; static QString toString(int mplayer_svn); // static QString mplayer2Version() { return mplayer2_version; }; static QString mpvVersion() { return mpv_version; }; protected: // static QString mplayer2_version; static QString mpv_version; // static bool is_mplayer2; static bool is_mpv; }; #endif kylin-video/src/smplayer/subtracks.cpp0000644000175000017500000001610013517016402017055 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "subtracks.h" #include "mediasettings.h" #include #include SubTracks::SubTracks() { index = 0; } SubTracks::~SubTracks() { } void SubTracks::clear() { subs.clear(); } void SubTracks::add( SubData::Type t, int ID ) { SubData d; d.setType(t); d.setID(ID); subs.append(d); } void SubTracks::list() { for (unsigned int n=0; n < subs.count(); n++) { qDebug("SubTracks::list: item %d: type: %d ID: %d lang: '%s' name: '%s' filename: '%s'", n, subs[n].type(), subs[n].ID(), subs[n].lang().toUtf8().data(), subs[n].name().toUtf8().data(), subs[n].filename().toUtf8().data() ); } } void SubTracks::listNames() { for (unsigned int n=0; n < subs.count(); n++) { qDebug("SubTracks::list: item %d: '%s'", n, subs[n].displayName().toUtf8().data() ); } } int SubTracks::numItems() { return subs.count(); } bool SubTracks::existsItemAt(int n) { return ((n >= 0) && (n < numItems())); } int SubTracks::findLang(QString expr) { qDebug( "SubTracks::findLang: '%s'", expr.toUtf8().data()); QRegExp rx( expr ); int res_id = -1; for (int n=0; n < numItems(); n++) { qDebug("SubTracks::findLang: lang #%d '%s'", n, subs[n].lang().toUtf8().data()); if (rx.indexIn( subs[n].lang() ) > -1) { qDebug("SubTracks::findLang: found preferred lang!"); res_id = n; break; } } return res_id; } // Return first subtitle or the user preferred (if found) // or none if there's no subtitles int SubTracks::selectOne(QString preferred_lang, int default_sub) { int sub = MediaSettings::SubNone; if (numItems() > 0) { sub = 0; // First subtitle if (existsItemAt(default_sub)) { sub = default_sub; } // Check if one of the subtitles is the user preferred. if (!preferred_lang.isEmpty()) { int res = findLang( preferred_lang ); if (res != -1) sub = res; } } return sub; } int SubTracks::find( SubData::Type t, int ID ) { for (unsigned int n=0; n < subs.count(); n++) { if ( ( subs[n].type() == t ) && ( subs[n].ID() == ID ) ) { return n; } } qDebug("SubTracks::find: item type: %d, ID: %d doesn't exist", t, ID); return -1; } SubData SubTracks::findItem( SubData::Type t, int ID ) { SubData sub; int n = find(t,ID); if ( n != -1 ) return subs[n]; else return sub; } int SubTracks::IDAt(int n) { if (existsItemAt(n)) { return itemAt(n).ID(); } else { return -1; } } SubData SubTracks::itemAt( int n ) { if (n >= 0 && n < subs.count()) { return subs[n]; } else { qWarning("SubTracks::itemAt: %d out of range!", n); qWarning("SubTracks::itemAt: returning an empty sub to avoid a crash"); qWarning("SubTracks::itemAt: this shouldn't happen, report a bug if you see this"); SubData empty_sub; return empty_sub; } } bool SubTracks::changeLang( SubData::Type t, int ID, QString lang ) { int f = find(t,ID); if (f == -1) return false; subs[f].setLang(lang); return true; } bool SubTracks::changeName( SubData::Type t, int ID, QString name ) { int f = find(t,ID); if (f == -1) return false; subs[f].setName(name); return true; } bool SubTracks::changeFilename( SubData::Type t, int ID, QString filename ) { int f = find(t,ID); if (f == -1) return false; subs[f].setFilename(filename); return true; } SubTracks::ParseResult SubTracks::parse(QString text) { qDebug("SubTracks::parse: '%s'", text.toUtf8().data()); ParseResult result = SubtitleUnchanged; QRegExp rx_subtitle("^ID_(SUBTITLE|FILE_SUB|VOBSUB)_ID=(\\d+)"); QRegExp rx_sid("^ID_(SID|VSID)_(\\d+)_(LANG|NAME)=(.*)"); QRegExp rx_subtitle_file("^ID_FILE_SUB_FILENAME=(.*)"); if (rx_subtitle.indexIn(text) > -1) { int ID = rx_subtitle.cap(2).toInt(); QString type = rx_subtitle.cap(1); SubData::Type t; if (type == "FILE_SUB") t = SubData::File; else if (type == "VOBSUB") t = SubData::Vob; else t = SubData::Sub; if (find(t, ID) > -1) { qWarning("SubTracks::parse: subtitle type: %d, ID: %d already exists!", t, ID); } else { add(t,ID); result = SubtitleAdded; } } else if (rx_sid.indexIn(text) > -1) { int ID = rx_sid.cap(2).toInt(); QString value = rx_sid.cap(4); QString attr = rx_sid.cap(3); QString type = rx_sid.cap(1); SubData::Type t = SubData::Sub; if (type == "VSID") t = SubData::Vob; if (find(t, ID) == -1) { qWarning("SubTracks::parse: subtitle type: %d, ID: %d doesn't exist!", t, ID); } else { if (attr=="NAME") changeName(t,ID, value); else changeLang(t,ID, value); result = SubtitleChanged; } } else if (rx_subtitle_file.indexIn(text) > -1) { QString file = rx_subtitle_file.cap(1); if ( subs.count() > 0 ) { int last = subs.count() -1; if (subs[last].type() == SubData::File) { subs[last].setFilename( file ); result = SubtitleChanged; } } } return result; } void SubTracks::save(QSettings * set, const QString & name) { set->beginWriteArray(name); for (int n = 0; n < numItems(); n++) { set->setArrayIndex(n); SubData d = itemAt(n); set->setValue("id", d.ID()); set->setValue("lang", d.lang()); set->setValue("name", d.name()); set->setValue("type", d.type()); set->setValue("filename", d.filename()); } set->endArray(); } void SubTracks::load(QSettings * set, const QString & name) { clear(); int items = set->beginReadArray(name); for (int n = 0; n < items; n++) { set->setArrayIndex(n); int ID = set->value("id", -1).toInt(); SubData::Type type = (SubData::Type) set->value("type", SubData::None).toInt(); if (ID != -1) { add(type, ID); changeLang(type, ID, set->value("lang", "").toString()); changeName(type, ID, set->value("name", "").toString()); changeFilename(type, ID, set->value("filename", "").toString()); } } set->endArray(); } /* void SubTracks::test() { process("ID_SUBTITLE_ID=0"); process("ID_SID_0_NAME=Arabic"); process("ID_SID_0_LANG=ara"); process("ID_SUBTITLE_ID=1"); process("ID_SID_1_NAME=Catalan"); process("ID_SID_1_LANG=cat"); process("ID_VOBSUB_ID=0"); process("ID_VSID_0_LANG=en"); process("ID_VOBSUB_ID=1"); process("ID_VSID_1_LANG=fr"); process("ID_FILE_SUB_ID=1"); process("ID_FILE_SUB_FILENAME=./lost313_es.sub"); list(); listNames(); } */ kylin-video/src/smplayer/filesettings-org.h0000644000175000017500000000270013517016402020007 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _FILESETTINGS_H_ #define _FILESETTINGS_H_ #include class QSettings; class MediaSettings; class FileSettings { public: FileSettings(QString directory); virtual ~FileSettings(); virtual bool existSettingsFor(QString filename, int type); virtual void loadSettingsFor(QString filename, int type, MediaSettings & mset, int player); virtual void saveSettingsFor(QString filename, int type, MediaSettings & mset, int player); static QString filenameToGroupname(const QString & filename, int type); protected: QString output_directory; private: QSettings * my_settings; }; #endif kylin-video/src/smplayer/preferencesdialog.h0000644000175000017500000000555413517016402020215 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _PREFERENCESDIALOG_H_ #define _PREFERENCESDIALOG_H_ #include "ui_preferencesdialog.h" #include "../utils.h" class QTextBrowser; class QPushButton; class PrefWidget; class PrefGeneral; class PrefVideo; class PrefAudio; class PrefPerformance; class PrefSubtitles; class PrefScreenShot; class PrefShortCut; class Preferences; class TitleButton; class PreferencesDialog : public QDialog, public Ui::PreferencesDialog { Q_OBJECT public: enum Section { General=0, Drives=1, Performance=2, Subtitles=3, Gui=4, Mouse=5, Advanced=6, Associations=7 }; PreferencesDialog(QString arch_type = "", QString snap = "", QWidget * parent = 0, Qt::WindowFlags f = 0 ); ~PreferencesDialog(); PrefShortCut *mod_shortcut_page() { return page_shortcut; } void addSection(PrefWidget *w); // Pass data to the standard dialogs void setData(Preferences * pref); // Apply changes void getData(Preferences * pref); // Return true if the mplayer process should be restarted. bool requiresRestart(); virtual bool eventFilter(QObject *, QEvent *); void moveDialog(QPoint diff); public slots: void showSection(Section s); virtual void accept(); // Reimplemented to send a signal virtual void reject(); signals: void applied(); void generalclicked(int id); void performanceclicked(int id); void subtitlesclicked(int id); protected: virtual void retranslateStrings(); virtual void changeEvent ( QEvent * event ) ; protected slots: void apply(); public slots: void onButtonClicked(int id); void setCurrentID(int id); void switchCurrentIDPage(int id); private: QList m_buttonList; protected: PrefGeneral * page_general; PrefVideo * page_video; PrefAudio * page_audio; PrefPerformance * page_performance; PrefSubtitles * page_subtitles; PrefScreenShot * page_screenshot; PrefShortCut *page_shortcut; private: DragState m_dragState; QPoint m_startDrag; }; #endif kylin-video/src/smplayer/filehash.h0000644000175000017500000000173113517016402016310 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2018 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef FILEHASH_H #define FILEHASH_H #include class FileHash { public: static QString calculateHash(QString filename); }; #endif kylin-video/src/smplayer/eqslider.h0000644000175000017500000000350713517016402016340 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2018 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef EQSLIDER_H #define EQSLIDER_H //#include "ui_eqslider.h" #include #include class QSlider; class QLabel; class VerticalText; class EqSlider : public QWidget/*, public Ui::EqSlider*/ { Q_OBJECT Q_PROPERTY(QPixmap icon READ icon WRITE setIcon) Q_PROPERTY(QString label READ label WRITE setLabel) Q_PROPERTY(int value READ value WRITE setValue) public: EqSlider( QWidget* parent = 0, Qt::WindowFlags f = 0 ); ~EqSlider(); public slots: void setIcon( QPixmap i); void setLabel( QString s); void setValue(int value); public: int value() const; const QPixmap * icon() const; QString label() const; QSlider * sliderWidget() { return _slider; }; VerticalText * labelWidget() { return _label; }; QLabel * iconWidget() { return _icon; }; signals: void valueChanged(int); protected slots: void sliderValueChanged(int); protected: /* virtual void languageChange(); */ private: QLabel *_icon; QLabel *value_label; VerticalText *_label; QSlider *_slider; }; #endif kylin-video/src/smplayer/mplayerprocess.cpp0000644000175000017500000006770513625147453020160 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "mplayerprocess.h" #include #include #include #include "global.h" #include "preferences.h" #include "mplayerversion.h" #include "colorutils.h" #include using namespace Global; #define TOO_CHAPTERS_WORKAROUND MplayerProcess::MplayerProcess(QObject * parent) : PlayerProcess(parent) , notified_mplayer_is_running(false) , received_end_of_file(false) , last_sub_id(-1) , mplayer_svn(-1) // Not found yet , subtitle_info_received(false) , subtitle_info_changed(false) , audio_info_changed(false) , video_info_changed(false) , dvd_current_title(-1) , br_current_title(-1) { m_playerId = Utils::MPLAYER; connect( this, SIGNAL(lineAvailable(QByteArray)), this, SLOT(parseLine(QByteArray)) ); connect( this, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(processFinished(int,QProcess::ExitStatus)) ); connect( this, SIGNAL(error(QProcess::ProcessError)), this, SLOT(gotError(QProcess::ProcessError)) ); initializeOptionVars(); } MplayerProcess::~MplayerProcess() { } bool MplayerProcess::start() { md.reset(); notified_mplayer_is_running = false; last_sub_id = -1; mplayer_svn = -1; // Not found yet received_end_of_file = false; subs.clear(); subtitle_info_received = false; subtitle_info_changed = false; audios.clear(); audio_info_changed = false; videos.clear(); video_info_changed = false; dvd_current_title = -1; br_current_title = -1; MyProcess::start(); return waitForStarted(); } static QRegExp rx_av("^[AV]: *([0-9,:.-]+)"); static QRegExp rx_frame("^[AV]:.* (\\d+)\\/.\\d+");// [0-9,.]+"); static QRegExp rx("^(.*)=(.*)"); static QRegExp rx_title("^ID_(DVD|BLURAY)_TITLE_(\\d+)_(LENGTH|CHAPTERS|ANGLES)=(.*)"); static QRegExp rx_chapters("^ID_CHAPTER_(\\d+)_(START|END|NAME)=(.+)"); static QRegExp rx_winresolution("^VO: \\[(.*)\\] (\\d+)x(\\d+) => (\\d+)x(\\d+)"); static QRegExp rx_ao("^AO: \\[(.*)\\]"); static QRegExp rx_paused("^ID_PAUSED"); static QRegExp rx_cache("^Cache fill:.*"); static QRegExp rx_cache_empty("^Cache empty.*|^Cache not filling.*"); static QRegExp rx_create_index("^Generating Index:.*"); static QRegExp rx_play("^Starting playback..."); static QRegExp rx_connecting("^Connecting to .*"); static QRegExp rx_resolving("^Resolving .*"); static QRegExp rx_screenshot("^\\*\\*\\* screenshot '(.*)'"); static QRegExp rx_endoffile("^Exiting... \\(End of file\\)|^ID_EXIT=EOF"); static QRegExp rx_mkvchapters("\\[mkv\\] Chapter (\\d+) from"); static QRegExp rx_aspect2("^Movie-Aspect is ([0-9,.]+):1"); static QRegExp rx_fontcache("^\\[ass\\] Updating font cache|^\\[ass\\] Init"); static QRegExp rx_scanning_font("Scanning file"); static QRegExp rx_forbidden("Server returned 403: Forbidden"); //#if DVDNAV_SUPPORT //static QRegExp rx_dvdnav_switch_title("^DVDNAV, switched to title: (\\d+)"); //static QRegExp rx_dvdnav_length("^ANS_length=(.*)"); //static QRegExp rx_dvdnav_title_is_menu("^DVDNAV_TITLE_IS_MENU"); //static QRegExp rx_dvdnav_title_is_movie("^DVDNAV_TITLE_IS_MOVIE"); //#endif // VCD static QRegExp rx_vcd("^ID_VCD_TRACK_(\\d+)_MSF=(.*)"); // Audio CD static QRegExp rx_cdda("^ID_CDDA_TRACK_(\\d+)_MSF=(.*)"); //Subtitles static QRegExp rx_subtitle("^ID_(SUBTITLE|FILE_SUB|VOBSUB)_ID=(\\d+)"); static QRegExp rx_sid("^ID_(SID|VSID)_(\\d+)_(LANG|NAME)=(.*)"); static QRegExp rx_subtitle_file("^ID_FILE_SUB_FILENAME=(.*)"); // Audio static QRegExp rx_audio("^ID_AUDIO_ID=(\\d+)"); static QRegExp rx_audio_info("^ID_AID_(\\d+)_(LANG|NAME)=(.*)"); // Video static QRegExp rx_video("^ID_VIDEO_ID=(\\d+)"); static QRegExp rx_video_info("^ID_VID_(\\d+)_(LANG|NAME)=(.*)"); //Clip info static QRegExp rx_clip_name("^ (name|title): (.*)", Qt::CaseInsensitive); static QRegExp rx_clip_artist("^ artist: (.*)", Qt::CaseInsensitive); static QRegExp rx_clip_author("^ author: (.*)", Qt::CaseInsensitive); static QRegExp rx_clip_album("^ album: (.*)", Qt::CaseInsensitive); static QRegExp rx_clip_genre("^ genre: (.*)", Qt::CaseInsensitive); static QRegExp rx_clip_date("^ (creation date|year): (.*)", Qt::CaseInsensitive); static QRegExp rx_clip_track("^ track: (.*)", Qt::CaseInsensitive); static QRegExp rx_clip_copyright("^ copyright: (.*)", Qt::CaseInsensitive); static QRegExp rx_clip_comment("^ comment: (.*)", Qt::CaseInsensitive); static QRegExp rx_clip_software("^ software: (.*)", Qt::CaseInsensitive); static QRegExp rx_stream_title("^.* StreamTitle='(.*)';"); static QRegExp rx_stream_title_and_url("^.* StreamTitle='(.*)';StreamUrl='(.*)';"); void MplayerProcess::parseLine(QByteArray ba) { //qDebug("MplayerProcess::parseLine: '%s'", ba.data() ); QString tag; QString value; //#if COLOR_OUTPUT_SUPPORT // QString line = ColorUtils::stripColorsTags(QString::fromLocal8Bit(ba)); //#else // #ifdef Q_OS_WIN // QString line = QString::fromUtf8(ba); // #else //kobe 有些clip_name clip_author存在乱码,所以需要在此处处理一下 // QTextCodec *str = QTextCodec::codecForName("GBK"); // QString line = ColorUtils::stripColorsTags(str->toUnicode(ba)); QString line = QString::fromLocal8Bit(ba); // #endif //#endif // Parse A: V: line //qDebug("%s", line.toUtf8().data()); if (rx_av.indexIn(line) > -1) { double sec = rx_av.cap(1).toDouble(); //qDebug("cap(1): '%s'", rx_av.cap(1).toUtf8().data() ); if (notified_mplayer_is_running) { if (subtitle_info_changed) { qDebug("MplayerProcess::parseLine: subtitle_info_changed"); subtitle_info_changed = false; subtitle_info_received = false; emit subtitleInfoChanged(subs, -1); } if (subtitle_info_received) { qDebug("MplayerProcess::parseLine: subtitle_info_received"); subtitle_info_received = false; emit subtitleInfoReceivedAgain(subs); } } if (notified_mplayer_is_running) { if (audio_info_changed) { qDebug("MplayerProcess::parseLine: audio_info_changed"); audio_info_changed = false; emit audioInfoChanged(audios, -1); } } if (notified_mplayer_is_running) { if (video_info_changed) { qDebug("MplayerProcess::parseLine: video_info_changed"); video_info_changed = false; emit videoInfoChanged(videos, -1); } } if (!notified_mplayer_is_running) { qDebug("MplayerProcess::parseLine: starting sec: %f", sec); if ( (md.n_chapters <= 0) && (dvd_current_title > 0) && (md.titles.find(dvd_current_title) != -1) ) { int idx = md.titles.find(dvd_current_title); md.n_chapters = md.titles.itemAt(idx).chapters(); qDebug("MplayerProcess::parseLine: setting chapters to %d", md.n_chapters); } // Another way to find out if there's no video, the another way is: static QRegExp rx_novideo("^Video: no video"); if (md.video_codec.isEmpty()) { md.novideo = true; emit receivedNoVideo(); } emit receivedStartingTime(sec); emit mplayerFullyLoaded(); emit receivedCurrentFrame(0); // Ugly hack: set the frame counter to 0 notified_mplayer_is_running = true; } emit receivedCurrentSec( sec ); // Check for frame if (rx_frame.indexIn(line) > -1) { int frame = rx_frame.cap(1).toInt(); //qDebug(" frame: %d", frame); emit receivedCurrentFrame(frame); } } else { // Emulates mplayer version in Ubuntu: //if (line.startsWith("MPlayer 1.0rc1")) line = "MPlayer 2:1.0~rc1-0ubuntu13.1 (C) 2000-2006 MPlayer Team"; //if (line.startsWith("MPlayer2")) line = "mplayer2 d0305da (C) 2000-2012 MPlayer & mplayer2 teams"; //if (line.startsWith("MPlayer SVN")) line = "MPlayer svn r34540 (Ubuntu), built with gcc-4.6 (C) 2000-2012 MPlayer Team"; //if (line.startsWith("MPlayer SVN")) line = "MPlayer 1.2-4.8 (C) 2000-2015 MPlayer Team"; // Emulates unknown version //if (line.startsWith("MPlayer SVN")) line = "MPlayer lalksklsjjakksja"; emit lineAvailable(line); // Parse other things //qDebug("MplayerProcess::parseLine: '%s'", line.toUtf8().data() ); // Screenshot if (rx_screenshot.indexIn(line) > -1) { QString shot = rx_screenshot.cap(1); qDebug("MplayerProcess::parseLine: screenshot: '%s'", shot.toUtf8().data()); emit receivedScreenshot( shot ); } else // End of file if (rx_endoffile.indexIn(line) > -1) { qDebug("MplayerProcess::parseLine: detected end of file"); if (!received_end_of_file) { // In case of playing VCDs or DVDs, maybe the first title // is not playable, so the GUI doesn't get the info about // available titles. So if we received the end of file // first let's pretend the file has started so the GUI can have // the data. if ( !notified_mplayer_is_running) { emit mplayerFullyLoaded(); } //emit receivedEndOfFile(); // Send signal once the process is finished, not now! received_end_of_file = true; } } else // Window resolution if (rx_winresolution.indexIn(line) > -1) { /* md.win_width = rx_winresolution.cap(4).toInt(); md.win_height = rx_winresolution.cap(5).toInt(); md.video_aspect = (double) md.win_width / md.win_height; */ int w = rx_winresolution.cap(4).toInt(); int h = rx_winresolution.cap(5).toInt(); emit receivedVO( rx_winresolution.cap(1) ); emit receivedWindowResolution( w, h ); //emit mplayerFullyLoaded(); } // Pause else if (rx_paused.indexIn(line) > -1) { emit receivedPause(); } // Stream title if (rx_stream_title_and_url.indexIn(line) > -1) { QString s = rx_stream_title_and_url.cap(1); QString url = rx_stream_title_and_url.cap(2); qDebug("MplayerProcess::parseLine: stream_title: '%s'", s.toUtf8().data()); qDebug("MplayerProcess::parseLine: stream_url: '%s'", url.toUtf8().data()); md.stream_title = s; md.stream_url = url; emit receivedStreamTitleAndUrl( s, url ); } else if (rx_stream_title.indexIn(line) > -1) { QString s = rx_stream_title.cap(1); qDebug("MplayerProcess::parseLine: stream_title: '%s'", s.toUtf8().data()); md.stream_title = s; emit receivedStreamTitle( s ); } // Subtitles if ((rx_subtitle.indexIn(line) > -1) || (rx_sid.indexIn(line) > -1) || (rx_subtitle_file.indexIn(line) > -1)) { int r = subs.parse(line); //qDebug("MplayerProcess::parseLine: result of parse: %d", r); subtitle_info_received = true; if ((r == SubTracks::SubtitleAdded) || (r == SubTracks::SubtitleChanged)) subtitle_info_changed = true; } // Audio if (rx_audio.indexIn(line) > -1) { int ID = rx_audio.cap(1).toInt(); qDebug("MplayerProcess::parseLine: ID_AUDIO_ID: %d", ID); if (audios.find(ID) == -1) audio_info_changed = true; audios.addID( ID ); } if (rx_audio_info.indexIn(line) > -1) { int ID = rx_audio_info.cap(1).toInt(); QString lang = rx_audio_info.cap(3); QString t = rx_audio_info.cap(2); qDebug("MplayerProcess::parseLine: Audio: ID: %d, Lang: '%s' Type: '%s'", ID, lang.toUtf8().data(), t.toUtf8().data()); int idx = audios.find(ID); if (idx == -1) { qDebug("MplayerProcess::parseLine: audio %d doesn't exist, adding it", ID); audio_info_changed = true; if ( t == "NAME" ) audios.addName(ID, lang); else audios.addLang(ID, lang); } else { qDebug("MplayerProcess::parseLine: audio %d exists, modifying it", ID); if (t == "NAME") { //qDebug("MplayerProcess::parseLine: name of audio %d: %s", ID, audios.itemAt(idx).name().toUtf8().constData()); if (audios.itemAt(idx).name() != lang) { audio_info_changed = true; audios.addName(ID, lang); } } else { //qDebug("MplayerProcess::parseLine: language of audio %d: %s", ID, audios.itemAt(idx).lang().toUtf8().constData()); if (audios.itemAt(idx).lang() != lang) { audio_info_changed = true; audios.addLang(ID, lang); } } } } // Video if (rx_video.indexIn(line) > -1) { int ID = rx_video.cap(1).toInt(); qDebug("MplayerProcess::parseLine: ID_VIDEO_ID: %d", ID); if (videos.find(ID) == -1) video_info_changed = true; videos.addID( ID ); } //#if DVDNAV_SUPPORT // if (rx_dvdnav_switch_title.indexIn(line) > -1) { // int title = rx_dvdnav_switch_title.cap(1).toInt(); // qDebug("MplayerProcess::parseLine: dvd title: %d", title); // emit receivedDVDTitle(title); // } // if (rx_dvdnav_length.indexIn(line) > -1) { // double length = rx_dvdnav_length.cap(1).toDouble(); // qDebug("MplayerProcess::parseLine: length: %f", length); // if (length != md.duration) { // md.duration = length; // emit receivedDuration(length); // } // } // if (rx_dvdnav_title_is_menu.indexIn(line) > -1) { // emit receivedTitleIsMenu(); // } // if (rx_dvdnav_title_is_movie.indexIn(line) > -1) { // emit receivedTitleIsMovie(); // } //#endif if (rx_cache_empty.indexIn(line) > -1) { emit receivedCacheEmptyMessage(line); } // The following things are not sent when the file has started to play // (or if sent, smplayer will ignore anyway...) // So not process anymore, if video is playing to save some time if (notified_mplayer_is_running) { return; } if ( (mplayer_svn == -1) && ((line.startsWith("MPlayer ")) || (line.startsWith("MPlayer2 ", Qt::CaseInsensitive))) ) { mplayer_svn = MplayerVersion::mplayerVersion(line); qDebug("MplayerProcess::parseLine: MPlayer SVN: %d", mplayer_svn); if (mplayer_svn <= 0) { qWarning("MplayerProcess::parseLine: couldn't parse mplayer version!"); emit failedToParseMplayerVersion(line); } } // AO if (rx_ao.indexIn(line) > -1) { emit receivedAO( rx_ao.cap(1) ); } else // Matroshka chapters if (rx_mkvchapters.indexIn(line)!=-1) { int c = rx_mkvchapters.cap(1).toInt(); qDebug("MplayerProcess::parseLine: mkv chapters: %d", c); if ((c+1) > md.n_chapters) { md.n_chapters = c+1; qDebug("MplayerProcess::parseLine: chapters set to: %d", md.n_chapters); } } else // Chapter info if (rx_chapters.indexIn(line) > -1) { int const chap_ID = rx_chapters.cap(1).toInt(); QString const chap_type = rx_chapters.cap(2); QString const chap_value = rx_chapters.cap(3); double const chap_value_d = chap_value.toDouble(); if(!chap_type.compare("START")) { md.chapters.addStart(chap_ID, chap_value_d/1000); qDebug("MplayerProcess::parseLine: Chapter (ID: %d) starts at: %g",chap_ID, chap_value_d/1000); } else if(!chap_type.compare("END")) { md.chapters.addEnd(chap_ID, chap_value_d/1000); qDebug("MplayerProcess::parseLine: Chapter (ID: %d) ends at: %g",chap_ID, chap_value_d/1000); } else if(!chap_type.compare("NAME")) { md.chapters.addName(chap_ID, chap_value); qDebug("MplayerProcess::parseLine: Chapter (ID: %d) name: %s",chap_ID, chap_value.toUtf8().data()); } } else // VCD titles if (rx_vcd.indexIn(line) > -1 ) { int ID = rx_vcd.cap(1).toInt(); QString length = rx_vcd.cap(2); //md.titles.addID( ID ); md.titles.addName( ID, length ); } else // Audio CD titles if (rx_cdda.indexIn(line) > -1 ) { int ID = rx_cdda.cap(1).toInt(); QString length = rx_cdda.cap(2); double duration = 0; QRegExp r("(\\d+):(\\d+):(\\d+)"); if ( r.indexIn(length) > -1 ) { duration = r.cap(1).toInt() * 60; duration += r.cap(2).toInt(); } md.titles.addID( ID ); /* QString name = QString::number(ID) + " (" + length + ")"; md.titles.addName( ID, name ); */ md.titles.addDuration( ID, duration ); } else // DVD/Bluray titles if (rx_title.indexIn(line) > -1) { int ID = rx_title.cap(2).toInt(); QString t = rx_title.cap(3); if (t=="LENGTH") { double length = rx_title.cap(4).toDouble(); qDebug("MplayerProcess::parseLine: Title: ID: %d, Length: '%f'", ID, length); md.titles.addDuration(ID, length); } else if (t=="CHAPTERS") { int chapters = rx_title.cap(4).toInt(); qDebug("MplayerProcess::parseLine: Title: ID: %d, Chapters: '%d'", ID, chapters); md.titles.addChapters(ID, chapters); } else if (t=="ANGLES") { int angles = rx_title.cap(4).toInt(); qDebug("MplayerProcess::parseLine: Title: ID: %d, Angles: '%d'", ID, angles); md.titles.addAngles(ID, angles); } } else // Catch cache messages if (rx_cache.indexIn(line) > -1) { emit receivedCacheMessage(line); } else // Creating index if (rx_create_index.indexIn(line) > -1) { emit receivedCreatingIndex(line); } else // Catch connecting message if (rx_connecting.indexIn(line) > -1) { emit receivedConnectingToMessage(line); } else // Catch resolving message if (rx_resolving.indexIn(line) > -1) { emit receivedResolvingMessage(line); } else // Aspect ratio for old versions of mplayer if (rx_aspect2.indexIn(line) > -1) { md.video_aspect = rx_aspect2.cap(1).toDouble(); qDebug("MplayerProcess::parseLine: md.video_aspect set to %f", md.video_aspect); } else // Clip info //QString::trimmed() is used for removing leading and trailing whitespaces //Some .mp3 files contain tags with starting and ending whitespaces //Unfortunately MPlayer gives us leading and trailing whitespaces, Winamp for example doesn't show them // Name if (rx_clip_name.indexIn(line) > -1) { QString s = rx_clip_name.cap(2).trimmed(); qDebug("MplayerProcess::parseLine: clip_name: '%s'", s.toUtf8().data()); md.clip_name = s; } else // Artist if (rx_clip_artist.indexIn(line) > -1) { QString s = rx_clip_artist.cap(1).trimmed(); qDebug("MplayerProcess::parseLine: clip_artist: '%s'", s.toUtf8().data()); md.clip_artist = s; } else // Author if (rx_clip_author.indexIn(line) > -1) { QString s = rx_clip_author.cap(1).trimmed(); qDebug("MplayerProcess::parseLine: clip_author: '%s'", s.toUtf8().data()); md.clip_author = s; } else // Album if (rx_clip_album.indexIn(line) > -1) { QString s = rx_clip_album.cap(1).trimmed(); qDebug("MplayerProcess::parseLine: clip_album: '%s'", s.toUtf8().data()); md.clip_album = s; } else // Genre if (rx_clip_genre.indexIn(line) > -1) { QString s = rx_clip_genre.cap(1).trimmed(); qDebug("MplayerProcess::parseLine: clip_genre: '%s'", s.toUtf8().data()); md.clip_genre = s; } else // Date if (rx_clip_date.indexIn(line) > -1) { QString s = rx_clip_date.cap(2).trimmed(); qDebug("MplayerProcess::parseLine: clip_date: '%s'", s.toUtf8().data()); md.clip_date = s; } else // Track if (rx_clip_track.indexIn(line) > -1) { QString s = rx_clip_track.cap(1).trimmed(); qDebug("MplayerProcess::parseLine: clip_track: '%s'", s.toUtf8().data()); md.clip_track = s; } else // Copyright if (rx_clip_copyright.indexIn(line) > -1) { QString s = rx_clip_copyright.cap(1).trimmed(); qDebug("MplayerProcess::parseLine: clip_copyright: '%s'", s.toUtf8().data()); md.clip_copyright = s; } else // Comment if (rx_clip_comment.indexIn(line) > -1) { QString s = rx_clip_comment.cap(1).trimmed(); qDebug("MplayerProcess::parseLine: clip_comment: '%s'", s.toUtf8().data()); md.clip_comment = s; } else // Software if (rx_clip_software.indexIn(line) > -1) { QString s = rx_clip_software.cap(1).trimmed(); qDebug("MplayerProcess::parseLine: clip_software: '%s'", s.toUtf8().data()); md.clip_software = s; } else if (rx_fontcache.indexIn(line) > -1) { //qDebug("MplayerProcess::parseLine: updating font cache"); emit receivedUpdatingFontCache(); } else if (rx_scanning_font.indexIn(line) > -1) { emit receivedScanningFont(line); } else if (rx_forbidden.indexIn(line) > -1) { qDebug("MplayerProcess::parseLine: 403 forbidden"); emit receivedForbiddenText(); } else // Catch starting message /* pos = rx_play.indexIn(line); if (pos > -1) { emit mplayerFullyLoaded(); } */ //Generic things if (rx.indexIn(line) > -1) { tag = rx.cap(1); value = rx.cap(2); //qDebug("MplayerProcess::parseLine: tag: %s, value: %s", tag.toUtf8().data(), value.toUtf8().data()); if (tag == "ID_LENGTH") { md.duration = value.toDouble(); qDebug("MplayerProcess::parseLine: md.duration set to %f", md.duration); // Use the bluray title length if duration is 0 if (md.duration == 0 && br_current_title != -1) { int i = md.titles.find(br_current_title); if (i != -1) { double duration = md.titles.itemAt(i).duration(); qDebug("MplayerProcess::parseLine: using the br title length: %f", duration); md.duration = duration; } } } else if (tag == "ID_VIDEO_WIDTH") { md.video_width = value.toInt(); qDebug("MplayerProcess::parseLine: md.video_width set to %d", md.video_width); } else if (tag == "ID_VIDEO_HEIGHT") { md.video_height = value.toInt(); qDebug("MplayerProcess::parseLine: md.video_height set to %d", md.video_height); } else if (tag == "ID_VIDEO_ASPECT") { md.video_aspect = value.toDouble(); if ( md.video_aspect == 0.0 ) { // I hope width & height are already set. md.video_aspect = (double) md.video_width / md.video_height; } qDebug("MplayerProcess::parseLine: md.video_aspect set to %f", md.video_aspect); } else if (tag == "ID_DVD_DISC_ID") { md.dvd_id = value; qDebug("MplayerProcess::parseLine: md.dvd_id set to '%s'", md.dvd_id.toUtf8().data()); } else if (tag == "ID_DEMUXER") { md.demuxer = value; } else if (tag == "ID_VIDEO_FORMAT") { md.video_format = value; } else if (tag == "ID_AUDIO_FORMAT") { md.audio_format = value; } else if (tag == "ID_VIDEO_BITRATE") { md.video_bitrate = value.toInt(); } else if (tag == "ID_VIDEO_FPS") { md.video_fps = value; } else if (tag == "ID_AUDIO_BITRATE") { md.audio_bitrate = value.toInt(); } else if (tag == "ID_AUDIO_RATE") { md.audio_rate = value.toInt(); } else if (tag == "ID_AUDIO_NCH") { md.audio_nch = value.toInt(); } else if (tag == "ID_VIDEO_CODEC") { md.video_codec = value; } else if (tag == "ID_AUDIO_CODEC") { md.audio_codec = value; } else if (tag == "ID_CHAPTERS") { md.n_chapters = value.toInt(); // #ifdef TOO_CHAPTERS_WORKAROUND if (md.n_chapters > 1000) { qDebug("MplayerProcess::parseLine: warning too many chapters: %d", md.n_chapters); qDebug(" chapters will be ignored"); md.n_chapters = 0; } // #endif } else if (tag == "ID_DVD_CURRENT_TITLE") { dvd_current_title = value.toInt(); } else if (tag == "ID_BLURAY_CURRENT_TITLE") { br_current_title = value.toInt(); } } } } // Called when the process is finished void MplayerProcess::processFinished(int exitCode, QProcess::ExitStatus exitStatus) { qDebug("MplayerProcess::processFinished: exitCode: %d, status: %d", exitCode, (int) exitStatus); // Send this signal before the endoffile one, otherwise // the playlist will start to play next file before all // objects are notified that the process has exited. emit processExited(); if (received_end_of_file) emit receivedEndOfFile(); } void MplayerProcess::gotError(QProcess::ProcessError error) { qDebug("MplayerProcess::gotError: %d", (int) error); } #include "mplayeroptions.cpp" //#include "moc_mplayerprocess.cpp" kylin-video/src/smplayer/urlhistory.h0000644000175000017500000000210613517016402016746 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _URLHISTORY_H_ #define _URLHISTORY_H_ #include "recents.h" class URLHistory : public Recents { public: URLHistory(); virtual ~URLHistory(); virtual void addUrl(QString url); //! Returns the URL virtual QString url(int n); }; #endif kylin-video/src/smplayer/tracks.cpp0000644000175000017500000000620113517016402016344 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "tracks.h" #include #include Tracks::Tracks() { clear(); } Tracks::~Tracks() { } void Tracks::clear() { tm.clear(); } void Tracks::addLang(int ID, QString lang) { tm[ID].setLang(lang); tm[ID].setID(ID); } void Tracks::addName(int ID, QString name) { tm[ID].setName(name); tm[ID].setID(ID); } void Tracks::addID(int ID) { tm[ID].setID(ID); } int Tracks::numItems() { return tm.count(); } bool Tracks::existsItemAt(int n) { return ((n > 0) && (n < numItems())); } TrackData Tracks::itemAt(int n) { return tm.values()[n]; } TrackData Tracks::item(int ID) { return tm[ID]; } int Tracks::find(int ID) { for (int n=0; n < numItems(); n++) { if (itemAt(n).ID() == ID) return n; } return -1; } int Tracks::IDAt(int n) { if (existsItemAt(n)) { return itemAt(n).ID(); } else { return -1; } } int Tracks::findLang(QString expr) { qDebug( "Tracks::findLang: '%s'", expr.toUtf8().data()); QRegExp rx( expr ); int res_id = -1; for (int n=0; n < numItems(); n++) { qDebug("Tracks::findLang: lang #%d '%s'", n, itemAt(n).lang().toUtf8().data()); if (rx.indexIn( itemAt(n).lang() ) > -1) { qDebug("Tracks::findLang: found preferred lang!"); res_id = itemAt(n).ID(); break; } } return res_id; } void Tracks::list() { QMapIterator i(tm); while (i.hasNext()) { i.next(); TrackData d = i.value(); //qDebug("Tracks::list: item %d: ID: %d lang: '%s' name: '%s'", i.key(), d.ID(), d.lang().toUtf8().constData(), d.name().toUtf8().constData() ); } } void Tracks::save(QSettings * set, const QString & name) { set->beginWriteArray(name); for (int n = 0; n < numItems(); n++) { set->setArrayIndex(n); TrackData d = itemAt(n); set->setValue("id", d.ID()); set->setValue("lang", d.lang()); set->setValue("name", d.name()); } set->endArray(); } void Tracks::load(QSettings * set, const QString & name) { clear(); int items = set->beginReadArray(name); for (int n = 0; n < items; n++) { set->setArrayIndex(n); int ID = set->value("id", -1).toInt(); if (ID != -1) { addID(ID); addLang(ID, set->value("lang", "").toString()); addName(ID, set->value("name", "").toString()); } } set->endArray(); } kylin-video/src/smplayer/prefvideo.ui0000644000175000017500000000527413517016402016704 0ustar fengfeng PrefVideo 0 0 470 360 10 20 256 22 Enable postprocessing by default 10 132 448 22 Draw video using slices 10 76 448 22 Direct rendering 10 104 448 22 Double buffering 10 48 448 22 Use software video equalizer 113 170 85 27 0 0 false 10 170 97 27 Output driver: false vo_combo kylin-video/src/smplayer/prefscreenshot.cpp0000644000175000017500000002141613517016402020114 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "prefscreenshot.h" #include "../smplayer/preferences.h" #include "../smplayer/filedialog.h" #include "../smplayer/images.h" #include "../smplayer/mediasettings.h" #include "../smplayer/paths.h" #include "../utils.h" #include #include "../smplayer/deviceinfo.h" //#include //qt4 //#include //qt5 PrefScreenShot::PrefScreenShot(QWidget * parent, Qt::WindowFlags f) : PrefWidget(parent, f ) { setupUi(this); // mplayerbin_edit->setDialogType(FileChooser::GetFileName); screenshot_edit->setDialogType(FileChooser::GetDirectory); retranslateStrings(); } PrefScreenShot::~PrefScreenShot() { } void PrefScreenShot::retranslateStrings() { retranslateUi(this); use_screenshots_check->setFocusPolicy(Qt::NoFocus); groupBox->setStyleSheet("QGroupBox{border:none;margin-top:20px;font-size:14px;}QGroupBox:title{subcontrol-origin: margin;subcontrol-position: top left;padding: 0px 1px;color: #999999;font-family: 方正黑体_GBK;font-weight:bold;}"); screenshot_format_combo->setStyleSheet("QComboBox{width:150px;height:24px;border:1px solid #000000;background:#0f0f0f;font-size:12px;font-family:方正黑体_GBK;background-position:center left;padding-left:5px;color:#999999;selection-color:#ffffff;selection-background-color:#1f1f1f;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox::drop-down {width:17px;border:none;background:transparent;}QComboBox::drop-down:hover {background:transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView{border:1px solid #0a9ff5;background:#262626;outline:none;}"); // screenshot_format_combo->setStyle(new QWindowsStyle);//qt4 // screenshot_format_combo->setStyle(new QCommonStyle);//qt5 // screenshot_format_combo->setStyleSheet("QComboBox{width:150px;height:24px;border: 1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:enabled {background:#0f0f0f;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox:enabled:hover, QComboBox:enabled:focus {color: #1f1f1f;}QComboBox::drop-down {width: 17px;border: none;background: transparent;}QComboBox::drop-down:hover {background: transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView {border: 1px solid #0a9ff5;background: #1f1f1f;outline: none;}"); screenshot_template_edit->setStyleSheet("QLineEdit {height: 25px;border: 1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QLineEdit::hover{border: 1px solid #000000;background: #0a0a0a;font-family:方正黑体_GBK;font-size:12px;color:#ffffff;}QLineEdit:enabled {background: #0a0a0a;color:#999999;}QLineEdit:enabled:hover, QLineEdit:enabled:focus {background: #0a0a0a;color:#ffffff;}QLineEdit:!enabled {color: #383838;}"); screenshots_dir_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); screenshot_format_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); screenshot_template_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); connect(use_screenshots_check, SIGNAL(toggled(bool)), screenshots_dir_label, SLOT(setEnabled(bool))); connect(use_screenshots_check, SIGNAL(toggled(bool)), screenshot_edit, SLOT(setEnabled(bool))); connect(use_screenshots_check, SIGNAL(toggled(bool)), screenshot_template_edit, SLOT(setEnabled(bool))); connect(use_screenshots_check, SIGNAL(toggled(bool)), screenshot_format_label, SLOT(setEnabled(bool))); connect(use_screenshots_check, SIGNAL(toggled(bool)), screenshot_format_combo, SLOT(setEnabled(bool))); connect(use_screenshots_check, SIGNAL(toggled(bool)), screenshot_template_label, SLOT(setEnabled(bool))); screenshot_edit->setCaption(tr("Select a directory")); createHelp(); } void PrefScreenShot::setData(Preferences *pref) { setUseScreenshots(pref->use_screenshot); setScreenshotDir(pref->screenshot_directory); screenshot_format_combo->addItems(QStringList() << "png" << "ppm" << "pgm" << "pgmyuv" << "tga" << "jpg" << "jpeg"); screenshot_template_edit->setText(pref->screenshot_template); setScreenshotFormat(pref->screenshot_format); //edited by kobe 20180623 // QString destPath = Paths::appPath() + "/mpv"; // if (pref->mplayer_bin == destPath) { if (pref->mplayer_bin == "/usr/bin/mpv") { screenshot_template_label->show(); screenshot_template_edit->show(); screenshot_format_label->show(); screenshot_format_combo->show(); } else { screenshot_template_label->hide(); screenshot_template_edit->hide(); screenshot_format_label->hide(); screenshot_format_combo->hide(); } } void PrefScreenShot::getData(Preferences * pref) { requires_restart = false; filesettings_method_changed = false; TEST_AND_SET(pref->use_screenshot, useScreenshots()); TEST_AND_SET(pref->screenshot_directory, screenshotDir()); if (pref->mplayer_bin == "/usr/bin/mpv") { TEST_AND_SET(pref->screenshot_template, screenshot_template_edit->text()); TEST_AND_SET(pref->screenshot_format, screenshotFormat()); } } void PrefScreenShot::setUseScreenshots(bool b) { use_screenshots_check->setChecked(b); } bool PrefScreenShot::useScreenshots() { return use_screenshots_check->isChecked(); } void PrefScreenShot::setScreenshotDir( QString path ) { screenshot_edit->setText( path ); } QString PrefScreenShot::screenshotDir() { return screenshot_edit->text(); } void PrefScreenShot::setScreenshotFormat(const QString format) { int i = screenshot_format_combo->findText(format); if (i < 0) i = 0; screenshot_format_combo->setCurrentIndex(i); } QString PrefScreenShot::screenshotFormat() { return screenshot_format_combo->currentText(); } void PrefScreenShot::createHelp() { clearHelp(); setWhatsThis(use_screenshots_check, tr("Enable screenshots"), tr("You can use this option to enable or disable the possibility to " "take screenshots.") ); setWhatsThis(screenshot_edit, tr("Screenshots folder"), tr("Here you can specify a folder where the screenshots taken by " "Kylin Video will be stored. If the folder is not valid the " "screenshot feature will be disabled.") ); setWhatsThis(screenshot_template_edit, tr("Template for screenshots"), tr("This option specifies the filename template used to save screenshots.") + " " + tr("For example %1 would save the screenshot as 'moviename_0001.png'.").arg("%F_%04n") + "
    " + tr("%1 specifies the filename of the video without the extension, " "%2 adds a 4 digit number padded with zeros.").arg("%F").arg("%04n") + " " + tr("For a full list of the template specifiers visit this link:") + "
    " "http://mpv.io/manual/stable/#options-screenshot-template" + "
    " + tr("This option only works with mpv.") ); setWhatsThis(screenshot_format_combo, tr("Format for screenshots"), tr("This option allows one to choose the image file type used for saving screenshots.") + " " + tr("This option only works with mpv.") ); } //#include "moc_prefscreenshot.cpp" kylin-video/src/smplayer/filepropertiesdialog.ui0000644000175000017500000001550713637124061021141 0ustar fengfeng FilePropertiesDialog 0 0 650 509 Kylin Video - Preferences 0 0 160 509 14 20 32 32 Qt::AlignCenter 0 72 160 437 0 0 QFrame::StyledPanel QFrame::Raised 49 20 101 33 Properties Qt::AlignCenter 181 20 444 441 0 0 0 6 6 444 441 true 5 5 444 17 &Select the demuxer that will be used for this file: false demuxer_listbox 5 30 444 378 352 414 91 25 &Reset demuxer_listbox demuxer_label resetDemuxerButton 5 30 444 378 5 5 444 17 &Select the video codec: false vc_listbox 352 414 91 25 &Reset 5 30 444 378 5 5 444 17 &Select the audio codec: false ac_listbox 352 414 91 25 Reset 331 470 91 25 Apply 432 470 91 25 OK 532 470 91 25 Cancel kylin-video/src/smplayer/audioequalizerlist.h0000644000175000017500000000251313517016402020443 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2018 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef AUDIOEQUALIZERLIST_H #define AUDIOEQUALIZERLIST_H #include #include #include typedef QList AudioEqualizerList; class AudioEqualizerHelper { public: enum AudioEqualizerType { Equalizer = 0, Anequalizer = 1, Firequalizer = 2, Superequalizer = 3, FEqualizer = 4 }; //! Returns a string to be passed to mplayer/mpv with the audio equalizer values. static QString equalizerListToString(AudioEqualizerList values, AudioEqualizerType type = Equalizer); }; #endif kylin-video/src/smplayer/audioequalizerlist.cpp0000644000175000017500000000417713517016402021006 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2018 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "audioequalizerlist.h" #include #define ANEQUALIZER_CHANNELS 2 #define ANEQUALIZER_WIDTH 1000 #define ANEQUALIZER_TYPE 0 #define ANEQUALIZER_SCALE 20 / 240 #define FIREQUALIZER_SCALE 24 / 240 QString AudioEqualizerHelper::equalizerListToString(AudioEqualizerList values, AudioEqualizerType type) { QString s; if (type == Equalizer) { for (int n = 0; n < 10; n++) { double v = (double) values[n].toInt() / 10; s += QString::number(v); if (n < 9) s += ":"; } } else if (type == Anequalizer) { for (int ch = 0; ch < ANEQUALIZER_CHANNELS; ch++) { double freq = 31.25; for (int f = 0; f < 10; f++) { double v = (double) values[f].toInt() * ANEQUALIZER_SCALE; s += QString("c%1 f=%2 w=%4 g=%3 t=%5|").arg(ch).arg(freq).arg(v).arg(ANEQUALIZER_WIDTH).arg(ANEQUALIZER_TYPE); freq = freq * 2; } } } else if (type == Firequalizer) { s = "gain_entry='"; double freq = 31.25; for (int f = 0; f < 10; f++) { double v = (double) values[f].toInt() * FIREQUALIZER_SCALE;//Segmentation fault if (f == 0) { double v1 = (double) values[1].toInt() * FIREQUALIZER_SCALE; s += QString("entry(0,%1)").arg(2 * v - v1); } else { s += QString("entry(%1,%2)").arg(freq).arg(v); } if (f < 9) s += ";"; freq = freq * 2; } s += "'"; } return s; } kylin-video/src/smplayer/myactiongroup.cpp0000644000175000017500000000613613517016402017764 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "myactiongroup.h" #include #include #include MyActionGroupItem::MyActionGroupItem(QObject * parent, MyActionGroup *group, const char * name, int data, bool autoadd) : MyAction(parent, name, autoadd) { setData(data); setCheckable(true); if (group) group->addAction(this); } MyActionGroupItem::MyActionGroupItem(QObject * parent, MyActionGroup *group, const QString & text, const char * name, int data, bool autoadd) : MyAction(parent, name, autoadd) { setData(data); setText(text); setCheckable(true); if (group) group->addAction(this); } MyActionGroup::MyActionGroup( QObject * parent ) : QActionGroup(parent) { setExclusive(true); connect( this, SIGNAL(triggered(QAction *)), this, SLOT(itemTriggered(QAction *)) ); } void MyActionGroup::setChecked(int ID) { //qDebug("MyActionGroup::setChecked: ID: %d", ID); QList l = actions(); for (int n=0; n < l.count(); n++) { if ( (!l[n]->isSeparator()) && (l[n]->data().toInt() == ID) ) { l[n]->setChecked(true); return; } } } int MyActionGroup::checked() { QAction * a = checkedAction(); if (a) return a->data().toInt(); else return -1; } void MyActionGroup::uncheckAll() { QList l = actions(); for (int n=0; n < l.count(); n++) { l[n]->setChecked(false); } } void MyActionGroup::setActionsEnabled(bool b) { QList l = actions(); for (int n=0; n < l.count(); n++) { l[n]->setEnabled(b); } } void MyActionGroup::clear(bool remove) { while (actions().count() > 0) { QAction * a = actions()[0]; if (a) { removeAction(a); if (remove) a->deleteLater(); } } } void MyActionGroup::itemTriggered(QAction *a) { qDebug("MyActionGroup::itemTriggered: '%s'", a->objectName().toUtf8().data()); int value = a->data().toInt(); qDebug("MyActionGroup::itemTriggered: ID: %d", value); emit activated(value); } void MyActionGroup::addTo(QWidget *w) { w->addActions( actions() ); } void MyActionGroup::removeFrom(QWidget *w) { for (int n=0; n < actions().count(); n++) { w->removeAction( actions()[n] ); } } //#include "moc_myactiongroup.cpp" kylin-video/src/smplayer/myactiongroup.h0000644000175000017500000000506713517016402017433 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _MYACTIONGROUP_H_ #define _MYACTIONGROUP_H_ #include #include #include "myaction.h" class MyActionGroup; //! This class makes easy to create actions for MyActionGroup class MyActionGroupItem : public MyAction { public: //! Creates a new item. /*! \a group is the group where the action will be added, \a data is the ID of the item. If \autoadd is true the action will be added to the parent (if it's a QWidget), so the shortcut could work. */ MyActionGroupItem( QObject * parent, MyActionGroup *group, const char * name, int data, bool autoadd = true ); //! Creates a new item. /*! \a text is the text that the item will have. */ MyActionGroupItem( QObject * parent, MyActionGroup *group, const QString & text, const char * name, int data, bool autoadd = true ); }; class QAction; //! MyActionGroup makes easier to create exclusive menus based on items //! with an integer data. class MyActionGroup : public QActionGroup { Q_OBJECT public: MyActionGroup ( QObject * parent ); //! Looks for the item which ID is \a ID and checks it void setChecked(int ID); //! Returns the ID of the item checked or -1 if none //! is checked int checked(); //! Remove all items. If \a remove is true the actions are also deleted. void clear(bool remove); //! Enable or disable all actions in the group void setActionsEnabled(bool); //! Adds all actions to the widget void addTo(QWidget *); //! Remove all actions from the widget void removeFrom(QWidget *); //! unchecks all items void uncheckAll(); signals: //! Emitted when an item has been checked void activated(int); protected slots: void itemTriggered(QAction *); }; #endif kylin-video/src/smplayer/lineedit_with_icon.cpp0000644000175000017500000000557613517016402020733 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "lineedit_with_icon.h" #include #include #include #include LineEditWithIcon::LineEditWithIcon(QWidget *parent) : QLineEdit(parent) { //height: 27px; this->setStyleSheet("QLineEdit {border:1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QLineEdit::hover{border: 1px solid #000000;background: #0a0a0a;font-family:方正黑体_GBK;font-size:12px;color:#ffffff;}QLineEdit:enabled {background: #0a0a0a;color:#999999;}QLineEdit:enabled:hover, QLineEdit:enabled:focus {background: #0a0a0a;color:#ffffff;}QLineEdit:!enabled {color: #383838;}"); button = new QToolButton(this); button->setObjectName("folderToolButton"); button->setCursor(Qt::ArrowCursor); setupButton(); button->setText(tr("Change")); } void LineEditWithIcon::setupButton() { } void LineEditWithIcon::setIcon(const QPixmap & pixmap) { // QPixmap p = pixmap; // //qDebug("height: %d, icon height: %d", height(), p.height()); // int max_height = 16; // if (max_height > height()) max_height = height() - 4; // if (pixmap.height() > max_height) p = pixmap.scaledToHeight(max_height, Qt::SmoothTransformation); // button->setIcon(p); // button->setStyleSheet("QToolButton { border: none; padding: 0px; }"); // int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); // //qDebug("frameWidth: %d", frameWidth); // setStyleSheet(QString("QLineEdit { padding-right: %1px; } ").arg(button->sizeHint().width() + frameWidth + 1)); // /* // QSize msz = minimumSizeHint(); // setMinimumSize(qMax(msz.width(), button->sizeHint().height() + frameWidth * 2 + 2), // qMax(msz.height(), button->sizeHint().height() + frameWidth * 2 + 2)); // */ } void LineEditWithIcon::resizeEvent(QResizeEvent *) { QSize sz = button->sizeHint(); button->setFixedHeight(this->height()); button->move(rect().right() - sz.width() + 1, 0); } //#include "moc_lineedit_with_icon.cpp" kylin-video/src/smplayer/mediasettings.cpp0000644000175000017500000005204313517016402017722 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "mediasettings.h" #include "preferences.h" #include "global.h" #include using namespace Global; MediaSettings::MediaSettings() { reset(); } MediaSettings::~MediaSettings() { } void MediaSettings::reset() { // qDebug("MediaSettings::reset"); current_sec = 0; current_subtitle_track = NoneSelected; //current_sub_id = SubNone; // current_sub_id = NoneSelected; //#ifdef MPV_SUPPORT // current_secondary_sub_id = NoneSelected; current_secondary_subtitle_track = NoneSelected; //#endif current_video_id = NoneSelected; current_audio_id = NoneSelected; current_title_id = NoneSelected; current_chapter_id = NoneSelected; current_angle_id = NoneSelected; aspect_ratio_id = AspectAuto; //fullscreen = false; volume = pref->initial_volume;//40 mute = false; external_subtitles = ""; external_subtitles_fps = SFPS_None; external_audio = ""; sub_delay=0; audio_delay=0; sub_pos = pref->initial_sub_pos; // 100% by default sub_scale = pref->initial_sub_scale; sub_scale_ass = pref->initial_sub_scale_ass; closed_caption_channel = 0; // disabled brightness = pref->initial_brightness; contrast = pref->initial_contrast; gamma = pref->initial_gamma; hue = pref->initial_hue; saturation = pref->initial_saturation; audio_equalizer = pref->initial_audio_equalizer; speed = 1.0; phase_filter = false; deblock_filter = false; dering_filter = false; gradfun_filter = false; noise_filter = false; postprocessing_filter = pref->initial_postprocessing; upscaling_filter = false; current_denoiser = NoDenoise; current_unsharp = 0; stereo3d_in = "none"; stereo3d_out = QString::null; current_deinterlacer = pref->initial_deinterlace;//NoDeinterlace add_letterbox = pref->initial_blackborders;//add_letterbox = false; //#ifdef MPLAYER_SUPPORT karaoke_filter = false; extrastereo_filter = false; //#endif volnorm_filter = pref->initial_volnorm; //#ifdef MPV_SUPPORT earwax_filter = false; //#endif audio_use_channels = pref->initial_audio_channels; //ChDefault; // (0) stereo_mode = pref->initial_stereo_mode; //Stereo; // (0) zoom_factor = pref->initial_zoom_factor; // 1.0; //#ifdef MSET_USE_STARTING_TIME // starting_time = -1; // Not set yet. //#endif rotate = NoRotate; flip = false; mirror = false; loop = false; A_marker = -1; B_marker = -1; //#ifdef BOOKMARKS // // Initialize bookmarks bookmarks.clear(); bookmarks.insert(0, ""); //#endif is264andHD = false; current_demuxer = "unknown"; forced_demuxer=""; if (pref->use_lavf_demuxer) forced_demuxer = "lavf"; forced_video_codec=""; forced_audio_codec=""; original_demuxer=""; original_video_codec=""; original_audio_codec=""; mplayer_additional_options=""; mplayer_additional_video_filters=""; mplayer_additional_audio_filters=""; win_width=400; win_height=300; videos.clear(); audios.clear(); subs.clear(); } double MediaSettings::win_aspect() { return (double) win_width / win_height; } double MediaSettings::aspectToNum(Aspect aspect) { double asp; switch (aspect) { case MediaSettings::AspectNone: asp = 0; break; case MediaSettings::Aspect43: asp = (double) 4 / 3; break; case MediaSettings::Aspect169: asp = (double) 16 / 9; break; case MediaSettings::Aspect149: asp = (double) 14 / 9; break; case MediaSettings::Aspect1610: asp = (double) 16 / 10; break; case MediaSettings::Aspect54: asp = (double) 5 / 4; break; case MediaSettings::Aspect235: asp = 2.35; break; case MediaSettings::Aspect11: asp = 1; break; case MediaSettings::Aspect32: asp = (double) 3 / 2; break; case MediaSettings::Aspect1410: asp = (double) 14 / 10; break; case MediaSettings::Aspect118: asp = (double) 11 / 8; break; case MediaSettings::AspectAuto: asp = win_aspect(); break; default: asp = win_aspect(); qWarning("MediaSettings::aspectToNum: invalid aspect: %d", aspect); } return asp; } QString MediaSettings::aspectToString(Aspect aspect) { QString asp_name; switch (aspect) { case MediaSettings::AspectNone: asp_name = QObject::tr("disabled", "aspect_ratio"); break; case MediaSettings::Aspect43: asp_name = "4:3"; break; case MediaSettings::Aspect169: asp_name = "16:9"; break; case MediaSettings::Aspect149: asp_name = "14:9"; break; case MediaSettings::Aspect1610: asp_name = "16:10"; break; case MediaSettings::Aspect54: asp_name = "5:4"; break; case MediaSettings::Aspect235: asp_name = "2.35:1"; break; case MediaSettings::Aspect11: asp_name = "1:1"; break; case MediaSettings::Aspect32: asp_name = "3:2"; break; case MediaSettings::Aspect1410: asp_name = "14:10"; break; case MediaSettings::Aspect118: asp_name = "11:8"; break; case MediaSettings::AspectAuto: asp_name = QObject::tr("auto", "aspect_ratio"); break; default: asp_name = QObject::tr("unknown", "aspect_ratio"); } return asp_name; } void MediaSettings::list() { // qDebug("MediaSettings::list"); // qDebug(" current_sec: %f", current_sec); // qDebug(" current_sub_id: %d", current_sub_id); ////#ifdef MPV_SUPPORT //// qDebug(" current_secondary_sub_id: %d", current_secondary_sub_id); ////#endif // qDebug(" current_video_id: %d", current_video_id); // qDebug(" current_audio_id: %d", current_audio_id); // qDebug(" current_title_id: %d", current_title_id); // qDebug(" current_chapter_id: %d", current_chapter_id); // qDebug(" current_angle_id: %d", current_angle_id); // qDebug(" aspect_ratio_id: %d", aspect_ratio_id); // //qDebug(" fullscreen: %d", fullscreen); // qDebug(" volume: %d", volume); // qDebug(" mute: %d", mute); // qDebug(" external_subtitles: '%s'", external_subtitles.toUtf8().data()); // qDebug(" external_subtitles_fps: '%d'", external_subtitles_fps); // qDebug(" external_audio: '%s'", external_audio.toUtf8().data()); // qDebug(" sub_delay: %d", sub_delay); // qDebug(" audio_delay: %d", sub_delay); // qDebug(" sub_pos: %d", sub_pos); // qDebug(" sub_scale: %f", sub_scale); // qDebug(" sub_scale_ass: %f", sub_scale_ass); // qDebug(" closed_caption_channel: %d", closed_caption_channel); // qDebug(" brightness: %d", brightness); // qDebug(" contrast: %d", contrast); // qDebug(" gamma: %d", gamma); // qDebug(" hue: %d", hue); // qDebug(" saturation: %d", saturation); // qDebug(" speed: %f", speed); // qDebug(" phase_filter: %d", phase_filter); // qDebug(" deblock_filter: %d", deblock_filter); // qDebug(" dering_filter: %d", dering_filter); // qDebug(" gradfun_filter: %d", gradfun_filter); // qDebug(" noise_filter: %d", noise_filter); // qDebug(" postprocessing_filter: %d", postprocessing_filter); // qDebug(" upscaling_filter: %d", upscaling_filter); // qDebug(" current_denoiser: %d", current_denoiser); // qDebug(" current_unsharp: %d", current_unsharp); // qDebug(" stereo3d_in: %s", stereo3d_in.toUtf8().constData()); // qDebug(" stereo3d_out: %s", stereo3d_out.toUtf8().constData()); // qDebug(" current_deinterlacer: %d", current_deinterlacer); // qDebug(" add_letterbox: %d", add_letterbox); //#ifdef MPLAYER_SUPPORT // qDebug(" karaoke_filter: %d", karaoke_filter); // qDebug(" extrastereo_filter: %d", extrastereo_filter); //#endif // qDebug(" volnorm_filter: %d", volnorm_filter); // qDebug(" audio_use_channels: %d", audio_use_channels); // qDebug(" stereo_mode: %d", stereo_mode); // qDebug(" zoom_factor: %f", zoom_factor); // qDebug(" rotate: %d", rotate); // qDebug(" flip: %d", flip); // qDebug(" mirror: %d", mirror); // qDebug(" loop: %d", loop); // qDebug(" A_marker: %d", A_marker); // qDebug(" B_marker: %d", B_marker); // qDebug(" current_demuxer: '%s'", current_demuxer.toUtf8().data()); // qDebug(" forced_demuxer: '%s'", forced_demuxer.toUtf8().data()); // qDebug(" forced_video_codec: '%s'", forced_video_codec.toUtf8().data()); // qDebug(" forced_audio_codec: '%s'", forced_video_codec.toUtf8().data()); // qDebug(" original_demuxer: '%s'", original_demuxer.toUtf8().data()); // qDebug(" original_video_codec: '%s'", original_video_codec.toUtf8().data()); // qDebug(" original_audio_codec: '%s'", original_video_codec.toUtf8().data()); // qDebug(" mplayer_additional_options: '%s'", mplayer_additional_options.toUtf8().data()); // qDebug(" mplayer_additional_video_filters: '%s'", mplayer_additional_video_filters.toUtf8().data()); // qDebug(" mplayer_additional_audio_filters: '%s'", mplayer_additional_audio_filters.toUtf8().data()); // qDebug(" win_width: %d", win_width); // qDebug(" win_height: %d", win_height); // qDebug(" win_aspect(): %f", win_aspect()); // qDebug(" starting_time: %f", starting_time); // qDebug(" is264andHD: %d", is264andHD); // qDebug(" Videos:"); videos.list(); // qDebug(" Audios:"); audios.list(); // qDebug(" Subtitles:"); subs.list(); } //#ifndef NO_USE_INI_FILES void MediaSettings::save(QSettings * set, int player_id) { // qDebug("MediaSettings::save"); set->beginGroup("player_" + QString::number(player_id)); set->setValue( "current_demuxer", current_demuxer); set->setValue( "forced_demuxer", forced_demuxer); set->setValue( "forced_video_codec", forced_video_codec); set->setValue( "forced_audio_codec", forced_audio_codec); set->setValue( "original_demuxer", original_demuxer); set->setValue( "original_video_codec", original_video_codec); set->setValue( "original_audio_codec", original_audio_codec); // Save the tracks ID in a demuxer section QString demuxer_section = QString("demuxer_%1").arg(current_demuxer); if (!forced_demuxer.isEmpty()) { demuxer_section = QString("demuxer_%1").arg(forced_demuxer); } set->beginGroup(demuxer_section); set->setValue( "current_subtitle_track", current_subtitle_track ); // set->setValue( "current_sub_id", current_sub_id ); // #ifdef MPV_SUPPORT // set->setValue( "current_secondary_sub_id", current_secondary_sub_id ); set->setValue( "current_secondary_subtitle_track", current_secondary_subtitle_track ); // #endif set->setValue( "current_video_id", current_video_id ); set->setValue( "current_audio_id", current_audio_id ); set->endGroup(); set->endGroup(); // player set->setValue( "current_sec", current_sec ); set->setValue( "current_title_id", current_title_id ); set->setValue( "current_chapter_id", current_chapter_id ); set->setValue( "current_angle_id", current_angle_id ); set->setValue( "aspect_ratio", aspect_ratio_id ); //set->setValue( "fullscreen", fullscreen ); set->setValue( "volume", volume ); set->setValue( "mute", mute ); set->setValue( "external_subtitles", external_subtitles ); set->setValue( "external_subtitles_fps", external_subtitles_fps ); set->setValue( "external_audio", external_audio ); set->setValue( "sub_delay", sub_delay); set->setValue( "audio_delay", audio_delay); set->setValue( "sub_pos", sub_pos); set->setValue( "sub_scale", sub_scale); set->setValue( "sub_scale_ass", sub_scale_ass); set->setValue( "closed_caption_channel", closed_caption_channel); set->setValue( "brightness", brightness); set->setValue( "contrast", contrast); set->setValue( "gamma", gamma); set->setValue( "hue", hue); set->setValue( "saturation", saturation); set->setValue("audio_equalizer", audio_equalizer ); set->setValue( "speed", speed); set->setValue( "phase_filter", phase_filter); set->setValue( "deblock_filter", deblock_filter); set->setValue( "dering_filter", dering_filter); set->setValue( "gradfun_filter", gradfun_filter); set->setValue( "noise_filter", noise_filter); set->setValue( "postprocessing_filter", postprocessing_filter); set->setValue( "upscaling_filter", upscaling_filter); set->setValue( "current_denoiser", current_denoiser); set->setValue( "current_unsharp", current_unsharp); set->setValue( "stereo3d_in", stereo3d_in); set->setValue( "stereo3d_out", stereo3d_out); set->setValue( "current_deinterlacer", current_deinterlacer); set->setValue( "add_letterbox", add_letterbox ); //#ifdef MPLAYER_SUPPORT set->setValue( "karaoke_filter", karaoke_filter); set->setValue( "extrastereo_filter", extrastereo_filter); //#endif set->setValue( "volnorm_filter", volnorm_filter); //#ifdef MPV_SUPPORT set->setValue( "earwax_filter", earwax_filter); //#endif set->setValue( "audio_use_channels", audio_use_channels); set->setValue( "stereo_mode", stereo_mode); set->setValue( "zoom_factor", zoom_factor); set->setValue( "rotate", rotate ); set->setValue( "flip", flip); set->setValue( "mirror", mirror); set->setValue( "loop", loop); set->setValue( "A_marker", A_marker); set->setValue( "B_marker", B_marker); //#ifdef BOOKMARKS // Save bookmarks bool save_bookmarks = true; QMap::const_iterator i = bookmarks.constBegin(); if (bookmarks.count() == 1 && i.key() == 0) save_bookmarks = false; if (save_bookmarks) { set->beginWriteArray("bookmarks"); int count = 0; while (i != bookmarks.constEnd()) { set->setArrayIndex(count); set->setValue("time", i.key()); set->setValue("name", i.value()); i++; count++; } set->endArray(); } //#endif set->setValue( "mplayer_additional_options", mplayer_additional_options); set->setValue( "mplayer_additional_video_filters", mplayer_additional_video_filters); set->setValue( "mplayer_additional_audio_filters", mplayer_additional_audio_filters); set->setValue( "win_width", win_width ); set->setValue( "win_height", win_height ); //#ifdef MSET_USE_STARTING_TIME // set->setValue( "starting_time", starting_time ); //#endif set->setValue( "is264andHD", is264andHD ); // Save tracks videos.save(set, "videotracks"); audios.save(set, "audiotracks"); subs.save(set, "subtitletracks"); } void MediaSettings::load(QSettings * set, int player_id) { // qDebug("MediaSettings::load"); set->beginGroup("player_" + QString::number(player_id)); current_demuxer = set->value( "current_demuxer", current_demuxer).toString(); forced_demuxer = set->value( "forced_demuxer", forced_demuxer).toString(); if (pref->use_lavf_demuxer) forced_demuxer = "lavf"; forced_video_codec = set->value( "forced_video_codec", forced_video_codec).toString(); forced_audio_codec = set->value( "forced_audio_codec", forced_audio_codec).toString(); original_demuxer = set->value( "original_demuxer", original_demuxer).toString(); original_video_codec = set->value( "original_video_codec", original_video_codec).toString(); original_audio_codec = set->value( "original_audio_codec", original_audio_codec).toString(); // Load the tracks ID from a demuxer section QString demuxer_section = QString("demuxer_%1").arg(current_demuxer); if (!forced_demuxer.isEmpty()) { demuxer_section = QString("demuxer_%1").arg(forced_demuxer); } // qDebug("MediaSettings::load: demuxer_section: %s", demuxer_section.toUtf8().constData()); set->beginGroup(demuxer_section); current_subtitle_track = set->value( "current_subtitle_track", NoneSelected ).toInt(); // current_sub_id = set->value( "current_sub_id", NoneSelected ).toInt(); // #ifdef MPV_SUPPORT // current_secondary_sub_id = set->value( "current_secondary_sub_id", NoneSelected ).toInt(); current_secondary_subtitle_track = set->value( "current_secondary_subtitle_track", NoneSelected ).toInt(); // #endif current_video_id = set->value( "current_video_id", NoneSelected ).toInt(); current_audio_id = set->value( "current_audio_id", NoneSelected ).toInt(); set->endGroup(); set->endGroup(); // player current_sec = set->value( "current_sec", current_sec).toDouble(); current_title_id = set->value( "current_title_id", current_title_id ).toInt(); current_chapter_id = set->value( "current_chapter_id", current_chapter_id ).toInt(); current_angle_id = set->value( "current_angle_id", current_angle_id ).toInt(); aspect_ratio_id = set->value( "aspect_ratio", aspect_ratio_id ).toInt(); //fullscreen = set->value( "fullscreen", fullscreen ).toBool(); volume = set->value( "volume", volume ).toInt(); mute = set->value( "mute", mute ).toBool(); external_subtitles = set->value( "external_subtitles", external_subtitles ).toString(); external_subtitles_fps = set->value( "external_subtitles_fps", external_subtitles_fps ).toInt(); external_audio = set->value( "external_audio", external_audio ).toString(); sub_delay = set->value( "sub_delay", sub_delay).toInt(); audio_delay = set->value( "audio_delay", audio_delay).toInt(); sub_pos = set->value( "sub_pos", sub_pos).toInt(); sub_scale = set->value( "sub_scale", sub_scale).toDouble(); sub_scale_ass = set->value( "sub_scale_ass", sub_scale_ass).toDouble(); closed_caption_channel = set->value( "closed_caption_channel", closed_caption_channel).toInt(); brightness = set->value( "brightness", brightness).toInt(); contrast = set->value( "contrast", contrast).toInt(); gamma = set->value( "gamma", gamma).toInt(); hue = set->value( "hue", hue).toInt(); saturation = set->value( "saturation", saturation).toInt(); audio_equalizer = set->value("audio_equalizer", audio_equalizer ).toList(); speed = set->value( "speed", speed ).toDouble(); phase_filter = set->value( "phase_filter", phase_filter ).toBool(); deblock_filter = set->value( "deblock_filter", deblock_filter).toBool(); dering_filter = set->value( "dering_filter", dering_filter).toBool(); gradfun_filter = set->value( "gradfun_filter", gradfun_filter).toBool(); noise_filter = set->value( "noise_filter", noise_filter).toBool(); postprocessing_filter = set->value( "postprocessing_filter", postprocessing_filter).toBool(); upscaling_filter = set->value( "upscaling_filter", upscaling_filter).toBool(); current_denoiser = set->value( "current_denoiser", current_denoiser).toInt(); current_unsharp = set->value( "current_unsharp", current_unsharp).toInt(); stereo3d_in = set->value( "stereo3d_in", stereo3d_in).toString(); stereo3d_out = set->value( "stereo3d_out", stereo3d_out).toString(); current_deinterlacer = set->value( "current_deinterlacer", current_deinterlacer ).toInt(); add_letterbox = set->value( "add_letterbox", add_letterbox ).toBool(); //#ifdef MPLAYER_SUPPORT karaoke_filter = set->value( "karaoke_filter", karaoke_filter).toBool(); extrastereo_filter = set->value( "extrastereo_filter", extrastereo_filter).toBool(); //#endif volnorm_filter = set->value( "volnorm_filter", volnorm_filter).toBool(); //#ifdef MPV_SUPPORT earwax_filter = set->value( "earwax_filter", earwax_filter).toBool(); //#endif audio_use_channels = set->value( "audio_use_channels", audio_use_channels).toInt(); stereo_mode = set->value( "stereo_mode", stereo_mode).toInt(); zoom_factor = set->value( "zoom_factor", zoom_factor).toDouble(); rotate = set->value( "rotate", rotate).toInt(); flip = set->value( "flip", flip).toBool(); mirror = set->value( "mirror", mirror).toBool(); loop = set->value( "loop", loop).toBool(); A_marker = set->value( "A_marker", A_marker).toInt(); B_marker = set->value( "B_marker", B_marker).toInt(); //#ifdef BOOKMARKS // Load bookmarks int n_bookmarks = set->beginReadArray("bookmarks"); if (n_bookmarks > 0) { bookmarks.clear(); for (int i = 0; i < n_bookmarks; ++i) { set->setArrayIndex(i); int time = set->value("time").toInt(); QString name = set->value("name").toString(); bookmarks.insert(time, name); } } set->endArray(); //#endif mplayer_additional_options = set->value( "mplayer_additional_options", mplayer_additional_options).toString(); mplayer_additional_video_filters = set->value( "mplayer_additional_video_filters", mplayer_additional_video_filters).toString(); mplayer_additional_audio_filters = set->value( "mplayer_additional_audio_filters", mplayer_additional_audio_filters).toString(); win_width = set->value( "win_width", win_width ).toInt(); win_height = set->value( "win_height", win_height ).toInt(); //#ifdef MSET_USE_STARTING_TIME // starting_time = set->value( "starting_time", starting_time ).toDouble(); //#endif is264andHD = set->value( "is264andHD", is264andHD ).toBool(); // ChDefault not used anymore if (audio_use_channels == ChDefault) audio_use_channels = ChStereo; // Load tracks videos.load(set, "videotracks"); audios.load(set, "audiotracks"); subs.load(set, "subtitletracks"); //qDebug("MediaSettings::load: list of video tracks:"); videos.list(); //qDebug("MediaSettings::load: list of audio tracks:"); audios.list(); //qDebug("MediaSettings::load: list of subtitle tracks:"); subs.list(); } //#endif // NO_USE_INI_FILES kylin-video/src/smplayer/inforeadermpv.h0000644000175000017500000000371113517016402017366 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef INFOREADER_MPV_H #define INFOREADER_MPV_H #include "inforeader.h" #include #include #include class QProcess; class InfoReaderMPV : QObject { Q_OBJECT public: InfoReaderMPV( QString mplayer_bin, const QString &snap, QObject * parent = 0); ~InfoReaderMPV(); void getInfo(); InfoList voList() { return vo_list; }; InfoList aoList() { return ao_list; }; InfoList demuxerList() { return demuxer_list; }; InfoList vcList() { return vc_list; }; InfoList acList() { return ac_list; }; QStringList vfList() { return vf_list; }; QStringList optionList() { return option_list; }; int mplayerSVN() { return mplayer_svn; }; QString mpvVersion() { return mpv_version; }; protected: QList run(QString options); InfoList getList(const QList &); QStringList getOptionsList(const QList &); void list(); protected: QString mplayerbin; InfoList vo_list; InfoList ao_list; InfoList demuxer_list; InfoList vc_list; InfoList ac_list; QStringList vf_list; QStringList option_list; int mplayer_svn; QString mpv_version; QString m_snap; }; #endif kylin-video/src/smplayer/playerprocess.h0000644000175000017500000002017413517016402017422 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef PLAYERPROCESS_H #define PLAYERPROCESS_H #include "myprocess.h" #include "mediadata.h" #include "../utils.h" #include "assstyles.h" #include #include class PlayerProcess : public MyProcess { Q_OBJECT public: enum ScreenshotType { Single = 0, Multiple = 1 }; PlayerProcess(QObject * parent = 0); Utils::PlayerId player() { return m_playerId; } bool isMPlayer() { return (m_playerId == Utils::MPLAYER); } bool isMPV() { return (m_playerId == Utils::MPV); } virtual bool start() = 0; void writeToStdin(QString text); MediaData mediaData() { return md; }; // Command line options virtual void setMedia(const QString & media, bool is_playlist = false) = 0; virtual void setFixedOptions() = 0; virtual void disableInput() = 0; virtual void setOption(const QString & option_name, const QVariant & value = QVariant()) = 0; virtual void addUserOption(const QString & option) = 0; virtual void addVF(const QString & filter_name, const QVariant & value = QVariant()) = 0; virtual void addAF(const QString & filter_name, const QVariant & value = QVariant()) = 0; virtual void addStereo3DFilter(const QString & in, const QString & out) = 0; virtual void setSubStyles(const AssStyles & styles, const QString & assStylesFile = QString::null) = 0; virtual void setSubEncoding(const QString & codepage, const QString & enca_lang) = 0; virtual void setVideoEqualizerOptions(int contrast, int brightness, int hue, int saturation, int gamma, bool soft_eq) = 0; // Slave commands virtual void quit() = 0; virtual void setVolume(int v) = 0; virtual void setOSD(int o) = 0; virtual void setAudio(int ID) = 0; virtual void setVideo(int ID) = 0; virtual void setSubtitle(int type, int ID) = 0; virtual void disableSubtitles() = 0; virtual void setSecondarySubtitle(int ID) = 0; virtual void disableSecondarySubtitles() = 0; virtual void setSubtitlesVisibility(bool b) = 0; virtual void seek(double secs, int mode, bool precise) = 0; virtual void mute(bool b) = 0; virtual void setPause(bool b) = 0; virtual void frameStep() = 0; virtual void frameBackStep() = 0; virtual void showOSDText(const QString & text, int duration, int level) = 0; virtual void showFilenameOnOSD(int duration = 2000) = 0; virtual void showMediaInfoOnOSD() = 0; virtual void showTimeOnOSD() = 0; virtual void setContrast(int value) = 0; virtual void setBrightness(int value) = 0; virtual void setHue(int value) = 0; virtual void setSaturation(int value) = 0; virtual void setGamma(int value) = 0; virtual void setChapter(int ID) = 0; virtual void nextChapter() = 0; virtual void previousChapter() = 0; virtual void setExternalSubtitleFile(const QString & filename) = 0; virtual void setSubPos(int pos) = 0; virtual void setSubScale(double value) = 0; virtual void setSubStep(int value) = 0; //#ifdef MPV_SUPPORT virtual void seekSub(int value) = 0; //#endif virtual void setSubForcedOnly(bool b) = 0; virtual void setSpeed(double value) = 0; //#ifdef MPLAYER_SUPPORT virtual void enableKaraoke(bool b) = 0; virtual void enableExtrastereo(bool b) = 0; //#endif virtual void enableVolnorm(bool b, const QString & option) = 0; //#ifdef MPV_SUPPORT virtual void enableEarwax(bool b) = 0; //#endif // virtual void setAudioEqualizer(const QString & values) = 0; virtual void setAudioEqualizer(AudioEqualizerList) = 0; virtual void setAudioDelay(double delay) = 0; virtual void setSubDelay(double delay) = 0; virtual void setLoop(int v) = 0; virtual void setAMarker(int sec) = 0; virtual void setBMarker(int sec) = 0; virtual void clearABMarkers() = 0; virtual void takeScreenshot(ScreenshotType t, bool include_subtitles = false) = 0; //#ifdef CAPTURE_STREAM // virtual void switchCapturing() = 0; //#endif virtual void setTitle(int ID) = 0; virtual void changeVF(const QString & filter, bool enable, const QVariant & option = QVariant()) = 0; virtual void changeAF(const QString & filter, bool enable, const QVariant & option = QVariant()) = 0; virtual void changeStereo3DFilter(bool enable, const QString & in, const QString & out) = 0; //#if DVDNAV_SUPPORT // virtual void discSetMousePos(int x, int y) = 0; // virtual void discButtonPressed(const QString & button_name) = 0; //#endif virtual void setAspect(double aspect) = 0; virtual void setFullscreen(bool b) = 0; virtual void toggleDeinterlace() = 0; virtual void askForLength() = 0; virtual void setOSDScale(double value) = 0; virtual void setOSDFractions(bool active) = 0; virtual void setChannelsFile(const QString &) = 0; virtual void enableScreenshots(const QString & dir, const QString & templ = QString::null, const QString & format = QString::null) = 0; void setPausingPrefix(const QString & prefix) { pausing_prefix = prefix; // qDebug() << "kobe pausing_prefix=" << pausing_prefix; }; void setOSDMediaInfo(const QString & s) { osd_media_info = s; }; QString OSDMediaInfo() { return osd_media_info; }; void setScreenshotDirectory(const QString & dir) { screenshot_dir = dir; }; QString screenshotDirectory() { return screenshot_dir; }; virtual void enableOSDInCommands(bool b) = 0; virtual bool isOSDInCommandsEnabled() = 0; //#ifdef CAPTURE_STREAM // virtual void setCaptureDirectory(const QString & dir); //#endif static PlayerProcess * createPlayerProcess(const QString & player_bin, const QString & snap, QObject * parent = 0); // Signals signals: void processExited(); void lineAvailable(QString line); void receivedCurrentSec(double sec); void receivedCurrentFrame(int frame); void receivedPause(); void receivedWindowResolution(int,int); void receivedNoVideo(); void receivedVO(QString); void receivedAO(QString); void receivedEndOfFile(); void mplayerFullyLoaded(); void receivedStartingTime(double sec); void receivedCacheMessage(QString); void receivedCacheEmptyMessage(QString); void receivedCreatingIndex(QString); void receivedConnectingToMessage(QString); void receivedResolvingMessage(QString); void receivedBuffering(); void receivedPlaying(); void receivedScreenshot(QString); void receivedUpdatingFontCache(); void receivedScanningFont(QString); void receivedForbiddenText(); void receivedStreamTitle(QString); void receivedStreamTitleAndUrl(QString,QString); void failedToParseMplayerVersion(QString line_with_mplayer_version); //! Emitted if a new subtitle has been added or an old one changed void subtitleInfoChanged(const SubTracks &, int selected_id); //! Emitted when subtitle info has been received but there wasn't anything new void subtitleInfoReceivedAgain(const SubTracks &); //! Emitted if a new audio track been added or an old one changed void audioInfoChanged(const Tracks &, int selected_id); //! Emitted if a new video track been added or an old one changed void videoInfoChanged(const Tracks &, int selected_id); void chaptersChanged(const Chapters &); //#if DVDNAV_SUPPORT // void receivedDVDTitle(int); // void receivedDuration(double); // void receivedTitleIsMenu(); // void receivedTitleIsMovie(); //#endif void receivedVideoBitrate(int); void receivedAudioBitrate(int); protected: virtual void initializeOptionVars() {}; MediaData md; QString pausing_prefix; QString screenshot_dir; //#ifdef CAPTURE_STREAM // QString capture_filename; //#endif Utils::PlayerId m_playerId; QString osd_media_info; }; #endif kylin-video/src/smplayer/eqslider.cpp0000644000175000017500000000454513517016402016676 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2018 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "eqslider.h" #include #include #include #include #include #include "verticaltext.h" EqSlider::EqSlider( QWidget* parent, Qt::WindowFlags f) : QWidget(parent, f) { this->setFixedSize(68, 289); _icon = new QLabel(this); value_label = new QLabel(this); _label = new VerticalText(this); _slider = new QSlider(Qt::Vertical); _icon->setText( QString::null ); _slider->setFocusPolicy( Qt::StrongFocus ); _slider->setTickPosition( QSlider::TicksRight ); _slider->setTickInterval( 10 ); _slider->setSingleStep( 1 ); _slider->setPageStep( 10 ); QHBoxLayout *hlayout = new QHBoxLayout; hlayout->addWidget(_label); hlayout->addWidget(_slider); QVBoxLayout *layout = new QVBoxLayout(this); layout->addWidget(_icon); layout->addLayout(hlayout); layout->addWidget(value_label); connect( _slider, SIGNAL(valueChanged(int)), this, SLOT(sliderValueChanged(int)) ); } EqSlider::~EqSlider() { } /* void EqSlider::languageChange() { } */ void EqSlider::setIcon( QPixmap i) { _icon->setPixmap(i); } const QPixmap * EqSlider::icon() const { return _icon->pixmap(); } void EqSlider::setLabel( QString s) { _label->setText(s); } QString EqSlider::label() const { return _label->text(); } void EqSlider::setValue(int value) { _slider->setValue(value); value_label->setNum(value); } int EqSlider::value() const { return _slider->value(); } void EqSlider::sliderValueChanged(int v) { emit valueChanged( v ); } //#include "moc_eqslider.cpp" kylin-video/src/smplayer/errordialog.ui0000644000175000017500000000756213637124061017240 0ustar fengfeng ErrorDialog 0 0 514 364 0 0 16777215 16777215 MPlayer Error 388 116 91 25 OK 479 0 36 36 162 10 191 20 MPlayer Error Qt::AlignCenter 11 38 60 58 icon Qt::AlignCenter 4 80 37 381 31 0 0 Oops, something wrong happened 81 63 400 41 0 0 400 0 Error true 10 94 494 20 Qt::Horizontal 23 116 91 25 Show log true 10 150 494 207 true kylin-video/src/smplayer/version.cpp0000644000175000017500000000223013517016402016540 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "version.h" #include #define USE_SVN_VERSIONS 0 //#define VERSION "1.1.2" QString Version::printable() { //return QString(VERSION); return QString(qApp->applicationVersion()); } QString Version::stable() { //return QString(VERSION); return QString(qApp->applicationVersion()); } kylin-video/src/kylinvideo.h0000644000175000017500000000371413625147453015064 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 _KYLINVIDEO_H_ #define _KYLINVIDEO_H_ #include #include #include #include "mainwindow.h" class InfoWorker; //class ControllerWorker; class KylinVideo : public QObject { Q_OBJECT public: enum ExitCode { ErrorArgument = -3, NoAction = -2, NoRunningInstance = -1, NoError = 0, NoExit = 1 }; KylinVideo(const QString &arch = QString::null, const QString &snap = QString::null, /*ControllerWorker *controller = nullptr, */QObject * parent = 0); ~KylinVideo(); //! Process arguments. If ExitCode != NoExit the application must be exited. ExitCode processArgs(QStringList args); MainWindow *gui(); private: MainWindow *createGUI(QString arch, QString snap); void deleteGUI(); void showInfo(); void deleteConfig(); static MainWindow *main_window; QStringList m_filesToPlay; QString m_subtitleFile; QString m_mediaTitle; //!< Force a title for the first file // Change position and size bool m_moveGui; QPoint m_guiPosition; bool m_resizeGui; QSize m_guiSize; QString m_arch; QString m_snap; QThread *m_thread = nullptr; InfoWorker *m_infoWorker = nullptr; // ControllerWorker *m_controllerWorker = nullptr; }; #endif kylin-video/src/aboutdialog.ui0000644000175000017500000001001113637124061015344 0ustar fengfeng AboutDialog 0 0 438 320 438 320 438 320 About 0 0 438 81 0 0 402 1 36 36 230 40 85 24 About 320 40 85 24 Contributor 230 70 85 2 5 82 428 190 QFrame::NoFrame QFrame::Plain true 5 82 428 190 QFrame::NoFrame QFrame::Plain <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> true 0 285 428 27 Qt::Horizontal QDialogButtonBox::Ok kylin-video/src/mainwindow.h0000644000175000017500000003414513637124061015056 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 #include #include #include #include #include "smplayer/mediadata.h" #include "smplayer/mediasettings.h" #include "smplayer/preferences.h" #include "smplayer/core.h" class QPushButton; class QWidget; class QMenu; class VideoWindow; class QLabel; class FilePropertiesDialog; class AboutDialog; class HelpDialog; class Playlist; class EscTip; class TipWidget; class MyAction; class MyActionGroup; class PreferencesDialog; class TitleWidget; class BottomWidget; class PlayMask; class VideoPreview; class BottomController; class FilterHandler; //class ShortcutsWidget; class CoverWidget; class InfoWorker; class MaskWidget; //class ControllerWorker; class AudioEqualizer; class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QString arch_type = "", QString snap = "", /*ControllerWorker *controller = NULL, */QWidget *parent = 0, Qt::WindowFlags flags = 0); ~MainWindow(); void initRegisterMeta(); void createPanel(); void createVideoWindow(); void createCore(); void createPlaylist(); void createTopTitleBar(); void createBottomToolBar(); void createAudioEqualizer(); void createActionsAndMenus(); void createOpenActionsAndMenus(); void createRecentsActionsAndMenus(); void createTopActionsAndMenus(); void createPlayCommandActionsAndMenus(); void createPlayOrderActionsAndMenus(); void createVideoAspectActionsAndMenus(); void createVideoRotateActionsAndMenus(); void createAudioActionsAndMenus(); void createScreenshotActionsAndMenus(); void createSubtitleActionsAndMenus(); void createOsdActionsAndMenus(); void createOthersActionsAndMenus(); void createTrayActions(); void createTipWidget(); void createEscWidget(); void createMaskWidget(); void createPreferencesDialog(); void createFilePropertiesDialog(); void setDataToFileProperties(); //void createAboutDialog(); void createHelpDialog(); void initRemoteControllerConnections(); void setStayOnTop(bool b); void setActionsEnabled(bool); void updateRecents(); void updateMuteWidgets(); void updateOnTopWidgets(); void updatePlayOrderWidgets(); void setPlaylistVisible(bool visible); void slideEdgeWidget(QWidget *right, QRect start, QRect end, int delay, bool hide = false); void bindThreadWorker(InfoWorker *worker); Core * getCore() { return m_core; }; public slots: void changeStayOnTop(int); void checkStayOnTop(Core::State); void changePlayOrder(int play_order); void powerOffPC(); void onMediaStoppedByUser(); void onMute(); void onMinWindow(); void onCloseWindow(); void onShowMenu(); void onMaxWindow(bool b); void onFullScreen(); void onShowOrHidePlaylist(); void exitFullscreen(); void exitFullscreenOnStop(); void exitFullscreenIfNeeded(); void toggleFullscreen(bool); void onPlayPause(); void showAboutDialog(); void showHelpDialog(); void showPreferencesDialog(); void showFilePropertiesDialog(); void showGotoDialog(); void showSubDelayDialog(); void showAudioDelayDialog(); void showTipWidget(const QString text); void onShowOrHideEscWidget(bool b); void toggleShowOrHideMainWindow(); void showMainWindow(); void showAudioEqualizer(bool b); void updateWidgets(); void updateAudioEqualizer(); void doOpen(QString file); void openFile(); void openFile(QString file); void openFiles(QStringList files); void openDirectory(); void openDirectory(QString directory); void openURL(); void loadSub(); void setInitialSubtitle(const QString & subtitle_file); void onSavePreviewImage(int time, QPoint pos); // void showShortcuts(); void onMeidaFilesAdded(const VideoPtrList medialist, bool isFileInPlaylist); void setBackgroudPixmap(QString pixmapDir); void trayIconActivated(QSystemTrayIcon::ActivationReason); void setJumpTexts(); void openRecent(); void playlistHasFinished(); void onCleanPlaylistFinished(); void displayState(Core::State state); void displayMessage(QString message); void gotCurrentTime(double, bool); void newMediaLoaded(); void updateMediaInfo(); void displayVideoInfo(int width, int height, double fps); void displayBitrateInfo(int vbitrate, int arbitrate); void gotNoFileToPlay(); void gotForbidden(); void enableActionsOnPlaying(); void disableActionsOnStop(); void togglePlayAction(Core::State); void hideCentralWidget(); void resizeMainWindow(int w, int h); void displayGotoTime(int); void goToPosOnDragging(int); void showPopupMenu(); void showPopupMenu( QPoint p ); void leftClickFunction(); void rightClickFunction(); void doubleClickFunction(); void middleClickFunction(); void xbutton1ClickFunction(); void xbutton2ClickFunction(); void processFunction(QString function); void applyNewPreferences(); void applyFileProperties(); void clearRecentsList(); void moveWindowDiff(QPoint diff); void loadActions(); void saveActions(); void moveWindow(); // Single instance stuff #ifdef SINGLE_INSTANCE void handleMessageFromOtherInstances(const QString& message); #endif void showExitCodeFromMplayer(int exit_code); void showErrorFromMplayer(QProcess::ProcessError); void showErrorFromPlayList(QString errorStr); void clearMplayerLog(); void recordMplayerLog(QString line); signals: void requestActionsEnabled(bool); void requestPlayOrPauseEnabled(bool); void requestUpdatePlaylistBtnQssProperty(bool); void requestGuiChanged(); protected: #if QT_VERSION < 0x050000 void hideEvent(QHideEvent *event) Q_DECL_OVERRIDE; void showEvent(QShowEvent *event) Q_DECL_OVERRIDE; #else bool event(QEvent * event) Q_DECL_OVERRIDE; bool was_minimized; #endif void dragEnterEvent(QDragEnterEvent *event) Q_DECL_OVERRIDE; void dropEvent(QDropEvent *event) Q_DECL_OVERRIDE; void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE; void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE; void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; // void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; private: bool m_isMaximized; QString m_mplayerLogMsg; bool m_ignoreShowHideEvents; QPoint m_windowPos; QString m_arch; QString m_snap; bool m_leftPressed; QPixmap currentBackground; bool m_dragWindow; int m_lastPlayingSeek; bool m_resizeFlag; QPushButton *m_resizeCornerBtn = nullptr; QSystemTrayIcon *m_mainTray = nullptr; PlayMask *m_playMaskWidget = nullptr; EscTip *m_escWidget = nullptr; TipWidget *m_tipWidget = nullptr; QTimer *m_tipTimer = nullptr; VideoPreview *m_videoPreview = nullptr; // ShortcutsWidget *m_shortcutsWidget; FilterHandler *m_mouseFilterHandler = nullptr; // CoverWidget *m_coverWidget = nullptr; MaskWidget *m_maskWidget = nullptr; // ControllerWorker *m_controllerWorker = nullptr; QWidget *m_centralWidget = nullptr; QStackedLayout/*QVBoxLayout*/ *m_centralLayout = nullptr; TitleWidget *m_topToolbar = nullptr; BottomWidget *m_bottomToolbar = nullptr; BottomController *m_bottomController = nullptr; PreferencesDialog *m_prefDialog = nullptr; FilePropertiesDialog *m_propertyDialog = nullptr; //AboutDialog *m_aboutDialog = nullptr; HelpDialog *m_helpDialog = nullptr; Core *m_core = nullptr; VideoWindow *m_mplayerWindow = nullptr; Playlist *m_playlistWidget = nullptr; AudioEqualizer *audio_equalizer = nullptr; // Menu File QMenu *openMenu = nullptr;//打开 MyAction *openFileAct = nullptr;//打开文件 MyAction *openDirectoryAct = nullptr;//打开文件夹 MyAction *openURLAct = nullptr;//打开URL MyAction *clearRecentsAct = nullptr;//清空最近的文件 QMenu *recentfiles_menu = nullptr;//打开最近的文件 QMenu *playMenu = nullptr;//播放控制 QMenu * control_menu = nullptr; MyAction * rewind1Act = nullptr; MyAction * rewind2Act = nullptr; MyAction * rewind3Act = nullptr; MyAction * forward1Act = nullptr; MyAction * forward2Act = nullptr; MyAction * forward3Act = nullptr; QMenu * speed_menu = nullptr; MyAction * gotoAct = nullptr; // Menu Speed MyAction * normalSpeedAct = nullptr; MyAction * halveSpeedAct = nullptr; MyAction * doubleSpeedAct = nullptr; MyAction * decSpeed10Act = nullptr; MyAction * incSpeed10Act = nullptr; MyAction * decSpeed4Act = nullptr; MyAction * incSpeed4Act = nullptr; MyAction * decSpeed1Act = nullptr; MyAction * incSpeed1Act = nullptr; MyAction * playPrevAct = nullptr; MyAction * playNextAct = nullptr; QMenu * aspect_menu = nullptr; // Aspect Action Group MyActionGroup * aspectGroup = nullptr; MyAction * aspectDetectAct = nullptr; MyAction * aspectNoneAct = nullptr; MyAction * aspect11Act = nullptr; // 1:1 MyAction * aspect32Act = nullptr; // 3:2 MyAction * aspect43Act = nullptr; // 4:3 MyAction * aspect118Act = nullptr; // 11:8 MyAction * aspect54Act = nullptr; // 5:4 MyAction * aspect149Act = nullptr; // 14:9 MyAction * aspect1410Act = nullptr; // 14:10 MyAction * aspect169Act = nullptr; // 16:9 MyAction * aspect1610Act = nullptr; // 16:10 MyAction * aspect235Act = nullptr; // 2.35:1 // Rotate Group MyActionGroup * rotateGroup = nullptr; MyAction * rotateNoneAct = nullptr; MyAction * rotateClockwiseFlipAct = nullptr; MyAction * rotateClockwiseAct = nullptr; MyAction * rotateCounterclockwiseAct = nullptr; MyAction * rotateCounterclockwiseFlipAct = nullptr; MyAction * flipAct = nullptr; MyAction * mirrorAct = nullptr; // Rotate menu QMenu * rotate_flip_menu = nullptr; QMenu * rotate_menu = nullptr; // MyAction * shortcutsAct; MyAction * screenshotAct = nullptr; /*MyAction * screenshotsAct; MyAction * screenshotWithSubsAct; MyAction * screenshotWithNoSubsAct;*/ QMenu * ontop_menu = nullptr; // Menu StayOnTop MyActionGroup * onTopActionGroup = nullptr; MyAction * onTopAlwaysAct = nullptr; MyAction * onTopNeverAct = nullptr; MyAction * onTopWhilePlayingAct = nullptr; //play order QMenu * play_order_menu = nullptr; MyActionGroup * playOrderActionGroup = nullptr; MyAction * orderPlaysAct = nullptr; MyAction * randomPlayAct = nullptr; MyAction * listLoopPlayAct = nullptr; QMenu *audioMenu = nullptr;//声音 MyAction * muteAct = nullptr; MyAction * decVolumeAct = nullptr; MyAction * incVolumeAct = nullptr; MyAction * decAudioDelayAct = nullptr; MyAction * incAudioDelayAct = nullptr; MyAction * audioDelayAct = nullptr; // Ask for delay MyAction * loadAudioAct = nullptr; MyAction * unloadAudioAct = nullptr; QMenu * audiofilter_menu = nullptr; MyAction * extrastereoAct = nullptr; MyAction * karaokeAct = nullptr; MyAction * volnormAct = nullptr; MyAction * earwaxAct = nullptr; MyAction * audioEqualizerAct = nullptr; MyAction * resetAudioEqualizerAct = nullptr; // Stereo Mode Action Group MyActionGroup * stereoGroup = nullptr; MyAction * stereoAct = nullptr; MyAction * leftChannelAct = nullptr; MyAction * rightChannelAct = nullptr; MyAction * monoAct = nullptr; MyAction * reverseAct = nullptr; QMenu * stereomode_menu = nullptr; QMenu *subtitlesMenu = nullptr;//字幕 MyAction * loadSubsAct = nullptr; MyAction * subVisibilityAct = nullptr; MyAction *showPreferencesAct = nullptr;//设置 MyAction *showPropertiesAct = nullptr;//信息和属性 MyAction *aboutAct = nullptr; MyAction *helpAct = nullptr; MyAction *quitAct = nullptr; // MyAction *m_poweroffAct = nullptr; //MyAction *openDirAct; //20181120 QMenu * osd_menu = nullptr; //MyAction *showFilenameAct; MyAction *showMediaInfoAct = nullptr; //MyAction *showTimeAct; // OSD MyAction *incOSDScaleAct = nullptr; MyAction *decOSDScaleAct = nullptr; //#ifdef MPV_SUPPORT MyAction *OSDFractionsAct = nullptr; //#endif // OSD Action Group MyActionGroup * osdGroup = nullptr; MyAction * osdNoneAct = nullptr; MyAction * osdSeekAct = nullptr; MyAction * osdTimerAct = nullptr; MyAction * osdTotalAct = nullptr; QMenu *m_mainMenu = nullptr; QMenu *m_toolbarMenu = nullptr; QMenu *audiochannels_menu = nullptr; MyActionGroup *channelsGroup = nullptr; MyAction *channelsStereoAct = nullptr; MyAction *channelsSurroundAct = nullptr; MyAction *channelsFull51Act = nullptr; MyAction *channelsFull61Act = nullptr; MyAction *channelsFull71Act = nullptr; //tray menu and actions QMenu *tray_menu = nullptr; MyAction *action_show = nullptr; MyAction *action_openshotsdir = nullptr; // The actions which are invisible shortcuts MyAction *playlist_action = nullptr; // MyAction *play_pause_aciton = nullptr; MyAction *stopAct = nullptr; MyAction *fullscreenAct = nullptr; }; #endif // _MAINWINDOW_H_ kylin-video/src/titlewidget.h0000644000175000017500000000572013637124061015224 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 TITLEWIDGET_H #define TITLEWIDGET_H #include #include #include #include #include #include #include #include #include #include "systembutton.h" #include "utils.h" class QHBoxLayout; class QProcess; class QMenu; class QPropertyAnimation; class TitleWidget : public QWidget { Q_OBJECT public: explicit TitleWidget(QWidget *parent = 0); ~TitleWidget(); void updateMaxButtonStatus(bool is_maxed); // void showWidget(); signals: void requestMinWindow(); void requestMaxWindow(bool b); void requestShowMenu(); void requestCloseWindow(); void mouseMovedDiff(QPoint); protected: void mouseDoubleClickEvent(QMouseEvent *event) override; private: enum MenuItemId { IdCreateAlbum, IdSwitchTheme, IdSetting, IdImport, IdHelp, IdAbout, IdQuick, IdSeparator }; void initLeftContent(); void initMiddleContent(); void initRightContent(); void initMenu(); void initWidgets(); private: QColor m_coverBrush; QColor m_topBorderColor; QColor m_bottomBorderColor; QPointer m_manualPro; QHBoxLayout *m_layout = nullptr; QHBoxLayout *m_lLayout = nullptr; QHBoxLayout *m_mLayout = nullptr; QHBoxLayout *m_rLayout = nullptr; SystemButton *min_button = nullptr; SystemButton *close_button = nullptr; SystemButton *max_button = nullptr; SystemButton *menu_button = nullptr; public slots: void onSetPlayingTitleName(const QString &name); void cleaTitleName(); // void showSpreadAnimated(); // void showGatherAnimated(); // void spreadAniFinished(); // void gatherAniFinished(); protected: bool eventFilter(QObject * obj, QEvent * event); void paintEvent(QPaintEvent *event); private slots: // void checkUnderMouse(); private: // QPropertyAnimation *m_spreadAnimation = nullptr; // QPropertyAnimation *m_gatherAnimation = nullptr; QLabel *m_logoLabel = nullptr; QLabel *m_softLabel = nullptr; QLabel *m_titleLabel = nullptr; DragState m_dragState; QPoint m_startDrag; }; #endif // TITLEWIDGET_H kylin-video/src/titlewidget.cpp0000644000175000017500000002404413637124061015557 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "titlewidget.h" #include #include #include #include #include #include #include #include #include #include TitleWidget::TitleWidget(QWidget *parent) : QWidget(parent) // , m_spreadAnimation(0) // , m_gatherAnimation(0) , m_dragState(NOT_DRAGGING) , m_startDrag(QPoint(0,0)) { this->setMouseTracking(true); this->setAutoFillBackground(true); this->setFocusPolicy(Qt::StrongFocus); this->setAttribute(Qt::WA_TranslucentBackground, true);//窗体标题栏不透明,背景透明 initWidgets(); this->installEventFilter(this); } TitleWidget::~TitleWidget() { // if (m_spreadAnimation) delete m_spreadAnimation; // if (m_gatherAnimation) delete m_gatherAnimation; if (menu_button) { delete menu_button; menu_button = NULL; } if (min_button) { delete min_button; min_button = NULL; } if (max_button) { delete max_button; max_button = NULL; } if (close_button) { delete close_button; close_button = NULL; } } //void TitleWidget::showWidget() //{ // showSpreadAnimated(); //} void TitleWidget::initWidgets() { m_layout = new QHBoxLayout(this); m_layout->setContentsMargins(0, 0, 0, 0); m_layout->setSpacing(0); initLeftContent(); initMiddleContent(); initRightContent(); } void TitleWidget::mouseDoubleClickEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { if (window()->isMaximized()) { this->updateMaxButtonStatus(false); window()->showNormal(); } else if (! window()->isFullScreen()) {// It would be normal state this->updateMaxButtonStatus(true); window()->showMaximized(); } } QWidget::mouseDoubleClickEvent(event); } void TitleWidget::initLeftContent() { QWidget *w = new QWidget; m_lLayout = new QHBoxLayout(w); m_lLayout->setContentsMargins(5, 0, 0, 0); m_lLayout->setSpacing(5); m_logoLabel = new QLabel(this); // QImage image(":/res/logo.png"); // image = image.scaled(QSize(32, 32), Qt::KeepAspectRatio, Qt::SmoothTransformation); // m_logoLabel->setPixmap(QPixmap::fromImage(image)); m_logoLabel->setPixmap(QPixmap(":/res/logo.png")); // m_logoLabel->setScaledContents(true);//自动缩放,显示图像大小自动调整为Qlabel大小 m_softLabel = new QLabel(this); m_softLabel->setText(tr("Kylin Video")); m_softLabel->setStyleSheet("QLabel{font-size:14px;font-style:italic;color:#ffffff;}");//font-weight:bold; m_lLayout->addWidget(m_logoLabel); m_lLayout->addWidget(m_softLabel); m_layout->addWidget(w, 1, Qt::AlignLeft); } void TitleWidget::initMiddleContent() { QWidget *w = new QWidget; w->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); m_mLayout = new QHBoxLayout(w); m_mLayout->setContentsMargins(0, 0, 0, 0); m_mLayout->setSpacing(0); m_titleLabel = new QLabel(this); m_titleLabel->setMaximumWidth(300); m_titleLabel->setStyleSheet("QLabel{font-size:12px;color:#ffffff;}"); m_mLayout->addWidget(m_titleLabel, 0 , Qt::AlignHCenter); m_layout->addWidget(w); } void TitleWidget::onSetPlayingTitleName(const QString &name) { QFont ft; QFontMetrics fm(ft); QString elided_text = fm.elidedText(name, Qt::ElideRight, this->m_titleLabel->maximumWidth()); this->m_titleLabel->setText(elided_text); if(elided_text.endsWith("…")) this->m_titleLabel->setToolTip(name); } void TitleWidget::cleaTitleName() { m_titleLabel->clear(); } void TitleWidget::initRightContent() { QWidget *w = new QWidget; m_rLayout = new QHBoxLayout(w); m_rLayout->setContentsMargins(0, 0, 0, 0); m_rLayout->setSpacing(0); m_layout->addWidget(w, 1, Qt::AlignRight); menu_button = new SystemButton(); menu_button->setMouseTracking(true); menu_button->loadPixmap(":/res/option.png"); menu_button->setObjectName("menu_button"); min_button = new SystemButton(); min_button->loadPixmap(":/res/min.png"); min_button->setObjectName("min_button"); max_button = new SystemButton(); max_button->loadPixmap(":/res/max.png"); max_button->setObjectName("max_button"); close_button = new SystemButton(); close_button->loadPixmap(":/res/close.png"); close_button->setObjectName("close_button"); menu_button->setFixedSize(36,36); min_button->setFixedSize(36,36); max_button->setFixedSize(36,36); close_button->setFixedSize(36,36); min_button->setObjectName("min_button"); close_button->setObjectName("close_button"); menu_button->setObjectName("menu_button"); max_button->setObjectName("max_button"); min_button->setFocusPolicy(Qt::NoFocus); close_button->setFocusPolicy(Qt::NoFocus); menu_button->setFocusPolicy(Qt::NoFocus); max_button->setFocusPolicy(Qt::NoFocus); m_rLayout->addWidget(menu_button); m_rLayout->addWidget(min_button); m_rLayout->addWidget(max_button); m_rLayout->addWidget(close_button); connect(menu_button, SIGNAL(clicked()), this, SIGNAL(requestShowMenu())); connect(close_button, SIGNAL(clicked()), this, SIGNAL(requestCloseWindow())); connect(max_button, SIGNAL(clicked(bool)), this, SIGNAL(requestMaxWindow(bool))); connect(min_button, &SystemButton::clicked, this, [=] () { max_button->loadPixmap(":/res/max.png"); emit this->requestMinWindow(); }); } void TitleWidget::updateMaxButtonStatus(bool is_maxed) { if (is_maxed) { max_button->loadPixmap(":/res/unmax.png"); } else { max_button->loadPixmap(":/res/max.png"); } } //void TitleWidget::checkUnderMouse() //{ // if ((isVisible()) && (!underMouse())) { // this->showGatherAnimated(); // } //} //void TitleWidget::spreadAniFinished() //{ //} //void TitleWidget::gatherAniFinished() //{ // QWidget::hide(); //} //void TitleWidget::showSpreadAnimated() //{ // if (!m_spreadAnimation) { // m_spreadAnimation = new QPropertyAnimation(this, "pos"); // connect(m_spreadAnimation, SIGNAL(finished()), this, SLOT(spreadAniFinished())); // } // QPoint initial_position = QPoint(pos().x(), -this->height()); // QPoint final_position = QPoint(0, 0); // move(initial_position); // QWidget::show(); // m_spreadAnimation->setDuration(300); // m_spreadAnimation->setEndValue(final_position); // m_spreadAnimation->setStartValue(initial_position); // m_spreadAnimation->start(); //} //void TitleWidget::showGatherAnimated() //{ // if (!m_gatherAnimation) { // m_gatherAnimation = new QPropertyAnimation(this, "pos"); // connect(m_gatherAnimation, SIGNAL(finished()), this, SLOT(gatherAniFinished())); // } // QPoint initial_position = QPoint(0, 0); // QPoint final_position = QPoint(pos().x(), -this->height()); // move(initial_position); // m_gatherAnimation->setDuration(300); // m_gatherAnimation->setStartValue(initial_position); // m_gatherAnimation->setEndValue(final_position); // m_gatherAnimation->start(); //} void TitleWidget::paintEvent(QPaintEvent *event) { Q_UNUSED(event); // QStyleOption opt; // opt.init(this); // QPainter p(this); // style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); QPainter p(this); p.setCompositionMode(QPainter::CompositionMode_Clear); p.fillRect(rect(), Qt::SolidPattern);//p.fillRect(0, 0, this->width(), this->height(), Qt::SolidPattern); } bool TitleWidget::eventFilter(QObject * obj, QEvent * event) { QEvent::Type type = event->type(); if (type != QEvent::MouseButtonPress && type != QEvent::MouseButtonRelease && type != QEvent::MouseMove) return false; QMouseEvent *mouseEvent = dynamic_cast(event); if (!mouseEvent) return false; if (mouseEvent->modifiers() != Qt::NoModifier) { m_dragState = NOT_DRAGGING; return false; } if (event->type() == QEvent::MouseMove) { } if (type == QEvent::MouseButtonPress) { if (mouseEvent->button() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } m_dragState = START_DRAGGING; m_startDrag = mouseEvent->globalPos(); // Don't filter, so others can have a look at it too return false; } if (type == QEvent::MouseButtonRelease) { if (m_dragState != DRAGGING || mouseEvent->button() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } // Stop dragging and eat event m_dragState = NOT_DRAGGING; event->accept(); return true; } // type == QEvent::MouseMove if (m_dragState == NOT_DRAGGING) return false; // buttons() note the s if (mouseEvent->buttons() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } QPoint pos = mouseEvent->globalPos(); QPoint diff = pos - m_startDrag; if (m_dragState == START_DRAGGING) { // Don't start dragging before moving at least DRAG_THRESHOLD pixels if (abs(diff.x()) < 4 && abs(diff.y()) < 4) return false; m_dragState = DRAGGING; } emit mouseMovedDiff(diff); m_startDrag = pos; event->accept(); return true; } kylin-video/src/messagedialog.cpp0000644000175000017500000002306713637124061016042 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "messagedialog.h" #include #include #include #include #include MessageDialog::MessageDialog(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton) : QDialog(parent) , m_dragState(NOT_DRAGGING) , m_startDrag(QPoint(0,0)) { this->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint); this->setStyleSheet("QDialog{border: 1px solid #121212;border-radius:1px;background-color:#1f1f1f;}"); this->setWindowTitle(title); this->setWindowIcon(QIcon::fromTheme("kylin-video", QIcon(":/res/kylin-video.png"))); // this->setWindowIcon(QIcon::fromTheme("kylin-video", QIcon(":/res/kylin-video.png")).pixmap(QSize(64, 64)).scaled(64, 64, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); this->setAutoFillBackground(true); this->setMouseTracking(true); installEventFilter(this); title_label = new QLabel(this); title_label->setAlignment(Qt::AlignCenter); title_label->setStyleSheet("QLabel{background:transparent;font-size:14px;color:#999999;font-family:方正黑体_GBK;}");//font-weight:bold; title_label->setText(title); close_Btn = new QPushButton(this); close_Btn->setFixedSize(36,36); close_Btn->setFocusPolicy(Qt::NoFocus); close_Btn->setStyleSheet("QPushButton{background-image:url(':/res/close_normal.png');border:0px;}QPushButton:hover{background:url(':/res/close_hover.png');}QPushButton:pressed{background:url(':/res/close_press.png');}"); QHBoxLayout *title_layout = new QHBoxLayout(); title_layout->addWidget(title_label); title_layout->addStretch(); title_layout->addWidget(close_Btn); title_layout->setMargin(0); title_layout->setContentsMargins(5,0,0,0); buttonBox = new QDialogButtonBox(this); buttonBox->setStandardButtons(QDialogButtonBox::StandardButtons(int(buttons))); QPushButton *okBtn = buttonBox->button(QDialogButtonBox::Ok); if (okBtn != NULL) { okBtn->setFixedSize(91, 25); okBtn->setText(tr("Ok")); okBtn->setFocusPolicy(Qt::NoFocus); okBtn->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); } QPushButton *cancelBtn = buttonBox->button(QDialogButtonBox::Cancel); if (cancelBtn != NULL) { cancelBtn->setFixedSize(91, 25); cancelBtn->setText(tr("Cancel")); cancelBtn->setFocusPolicy(Qt::NoFocus); cancelBtn->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #000000;color:#999999;}QPushButton:hover{background-color:#1f1f1f;border:1px solid #0f0f0f;color:#ffffff;} QPushButton:pressed{background-color:#0d0d0d;border:1px solid #000000;color:#ffffff;}"); } QPushButton *yesBtn = buttonBox->button(QDialogButtonBox::Yes); if (yesBtn != NULL) { yesBtn->setFixedSize(91, 25); yesBtn->setText(tr("Yes")); yesBtn->setFocusPolicy(Qt::NoFocus); yesBtn->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); } QPushButton *noBtn = buttonBox->button(QDialogButtonBox::No); if (noBtn != NULL) { noBtn->setFixedSize(91, 25); noBtn->setText(tr("No")); noBtn->setFocusPolicy(Qt::NoFocus); noBtn->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #000000;color:#999999;}QPushButton:hover{background-color:#1f1f1f;border:1px solid #0f0f0f;color:#ffffff;} QPushButton:pressed{background-color:#0d0d0d;border:1px solid #000000;color:#ffffff;}"); } icon_label = new QLabel(this); QPixmap pixmap(":/res/warn.png"); icon_label->setPixmap(pixmap); // icon_label->setFixedSize(60, 58); // icon_label->setScaledContents(true); icon_label->adjustSize(); icon_label->setWordWrap(true); msg_label = new QLabel(this); msg_label->setMinimumWidth(100); msg_label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); msg_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}");//font-weight:bold; msg_label->setOpenExternalLinks(true); msg_label->setText(text); QHBoxLayout *hlayout = new QHBoxLayout(); hlayout->setMargin(0); hlayout->setContentsMargins(30,0,30,0); hlayout->setSpacing(30); hlayout->addStretch(); hlayout->addWidget(icon_label); hlayout->addWidget(msg_label); hlayout->addStretch(); QHBoxLayout *blayout = new QHBoxLayout(); blayout->addStretch(); blayout->addWidget(buttonBox); blayout->setContentsMargins(10,0,10,0); main_layout = new QVBoxLayout(this); main_layout->addLayout(title_layout); main_layout->addLayout(hlayout); main_layout->addLayout(blayout); main_layout->setMargin(0); main_layout->setSpacing(10); main_layout->setContentsMargins(0, 0, 0, 10); this->layout()->setSizeConstraint(QLayout::SetFixedSize); this->initConnect(); } MessageDialog::~MessageDialog() { } void MessageDialog::setDialogSize(int w, int h) { this->setFixedSize(w, h); } void MessageDialog::setIcon(const QString &icon) { icon_label->setPixmap(QPixmap(icon)); } QMessageBox::StandardButton MessageDialog::standardButton(QAbstractButton *button) const { return (QMessageBox::StandardButton)buttonBox->standardButton(button); } QAbstractButton *MessageDialog::clickedButton() const { return clickedBtn; } int MessageDialog::returnCodeByRun(QAbstractButton *button) { int ret = buttonBox->standardButton(button); return ret; } void MessageDialog::onButtonClicked(QAbstractButton *button) { clickedBtn = button; done(returnCodeByRun(button)); } //void MessageDialog::setDefaultButton(QPushButton *button) //{ // if (!buttonBox->buttons().contains(button)) // return; // defaultBtn = button; // button->setDefault(true); // button->setFocus(); //} //void MessageDialog::setDefaultButton(QMessageBox::StandardButton button) //{ // setDefaultButton(buttonBox->button(QDialogButtonBox::StandardButton(button))); //} void MessageDialog::initConnect() { connect(close_Btn, SIGNAL(clicked()), this, SLOT(close())); connect(buttonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(onButtonClicked(QAbstractButton*))); } void MessageDialog::moveDialog(QPoint diff) { #if QT_VERSION >= 0x050000 // Move the window with some delay. // Seems to work better with Qt 5 static QPoint d; static int count = 0; d += diff; count++; if (count > 3) { QPoint new_pos = pos() + d; if (new_pos.y() < 0) new_pos.setY(0); if (new_pos.x() < 0) new_pos.setX(0); move(new_pos); count = 0; d = QPoint(0,0); } #else move(pos() + diff); #endif } bool MessageDialog::eventFilter( QObject * object, QEvent * event ) { QEvent::Type type = event->type(); if (type != QEvent::MouseButtonPress && type != QEvent::MouseButtonRelease && type != QEvent::MouseMove) return false; QMouseEvent *mouseEvent = dynamic_cast(event); if (!mouseEvent) return false; if (mouseEvent->modifiers() != Qt::NoModifier) { m_dragState = NOT_DRAGGING; return false; } if (type == QEvent::MouseButtonPress) { if (mouseEvent->button() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } m_dragState = START_DRAGGING; m_startDrag = mouseEvent->globalPos(); // Don't filter, so others can have a look at it too return false; } if (type == QEvent::MouseButtonRelease) { if (m_dragState != DRAGGING || mouseEvent->button() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } // Stop dragging and eat event m_dragState = NOT_DRAGGING; event->accept(); return true; } // type == QEvent::MouseMove if (m_dragState == NOT_DRAGGING) return false; // buttons() note the s if (mouseEvent->buttons() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } QPoint pos = mouseEvent->globalPos(); QPoint diff = pos - m_startDrag; if (m_dragState == START_DRAGGING) { // Don't start dragging before moving at least DRAG_THRESHOLD pixels if (abs(diff.x()) < 4 && abs(diff.y()) < 4) return false; m_dragState = DRAGGING; } this->moveDialog(diff); m_startDrag = pos; event->accept(); return true; } kylin-video/src/helpdialog.cpp0000644000175000017500000001622413637124061015343 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "helpdialog.h" #include #include #include #include #include #include #include "supportformats.h" //#include "supportshortcuts.h" #include "titlebutton.h" #include "../smplayer/preferences.h" HelpDialog::HelpDialog(QWidget * parent, Qt::WindowFlags f) : QDialog(parent, f ) , m_dragState(NOT_DRAGGING) , m_startDrag(QPoint(0,0)) { setupUi(this); this->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint); this->setFixedSize(675, 425); this->setStyleSheet("QDialog{border: 1px solid #121212;border-radius:1px;background-color:#1f1f1f;}"); this->setWindowIcon(QIcon::fromTheme("kylin-video", QIcon(":/res/kylin-video.png"))); // this->setWindowIcon(QIcon::fromTheme("kylin-video", QIcon(":/res/kylin-video.png")).pixmap(QSize(64, 64)).scaled(64, 64, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); this->setAttribute(Qt::WA_DeleteOnClose); this->setAutoFillBackground(true); this->setMouseTracking(true); installEventFilter(this); title_widget->setAutoFillBackground(true); title_widget->setStyleSheet("QWidget{border:none;background-color:#2e2e2e;}"); connect(okButton, SIGNAL(clicked()), this, SLOT(accept())); okButton->setFixedSize(91, 25); okButton->setFocusPolicy(Qt::NoFocus); okButton->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); title_label->setStyleSheet("QLabel{background:transparent;font-family: 方正黑体_GBK;font-size:20px;color:#999999;}"); QVBoxLayout *layout = new QVBoxLayout(this); layout->setContentsMargins(0, 5, 0, 0); layout->setSpacing(0); m_pageFormats = new SupportFormats; addSection(m_pageFormats); pages->setCurrentWidget(m_pageFormats); TitleButton *btn = new TitleButton(0, false, tr("Supported formats")); connect(btn, SIGNAL(clicked(int)), this, SLOT(onButtonClicked(int))); layout->addWidget(btn); m_buttonList << btn; btn->setActived(true); // page_shortcuts = new SupportShortcuts; // addSection(page_shortcuts); // btn = new TitleButton(1, false, tr("Supported shortcuts")); // connect(btn, SIGNAL(clicked(int)), this, SLOT(onButtonClicked(int))); // layout->addWidget(btn); // m_buttonList << btn; layout->addStretch(); sections->setLayout(layout); retranslateStrings(); } HelpDialog::~HelpDialog() { for(int i=0; iid() == id) { button->setActived(true); } else { button->setActived(false); } } } void HelpDialog::onButtonClicked(int id) { setCurrentID(id); if (id == 0) { pages->setCurrentWidget(m_pageFormats); } // else if (id == 1) { // pages->setCurrentWidget(page_shortcuts); // } } void HelpDialog::showSection(Section s) { qDebug("HelpDialog::showSection: %d", s); } void HelpDialog::retranslateStrings() { retranslateUi(this); icon_label->setPixmap(QPixmap(":/res/help.png")); okButton->setText(tr("OK")); } void HelpDialog::accept() { hide(); setResult( QDialog::Accepted ); emit applied(); } void HelpDialog::addSection(QWidget *w) { pages->addWidget(w); } void HelpDialog::setData(Preferences * pref) { m_pageFormats->setData(); // page_shortcuts->setData(pref); } // Language change stuff void HelpDialog::changeEvent(QEvent *e) { if (e->type() == QEvent::LanguageChange) { retranslateStrings(); } else { QDialog::changeEvent(e); } } void HelpDialog::moveDialog(QPoint diff) { #if QT_VERSION >= 0x050000 // Move the window with some delay. // Seems to work better with Qt 5 static QPoint d; static int count = 0; d += diff; count++; if (count > 3) { QPoint new_pos = pos() + d; if (new_pos.y() < 0) new_pos.setY(0); if (new_pos.x() < 0) new_pos.setX(0); move(new_pos); count = 0; d = QPoint(0,0); } #else move(pos() + diff); #endif } bool HelpDialog::eventFilter( QObject * object, QEvent * event ) { QEvent::Type type = event->type(); if (type != QEvent::MouseButtonPress && type != QEvent::MouseButtonRelease && type != QEvent::MouseMove) return false; QMouseEvent *mouseEvent = dynamic_cast(event); if (!mouseEvent) return false; if (mouseEvent->modifiers() != Qt::NoModifier) { m_dragState = NOT_DRAGGING; return false; } if (type == QEvent::MouseButtonPress) { if (mouseEvent->button() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } m_dragState = START_DRAGGING; m_startDrag = mouseEvent->globalPos(); // Don't filter, so others can have a look at it too return false; } if (type == QEvent::MouseButtonRelease) { if (m_dragState != DRAGGING || mouseEvent->button() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } // Stop dragging and eat event m_dragState = NOT_DRAGGING; event->accept(); return true; } // type == QEvent::MouseMove if (m_dragState == NOT_DRAGGING) return false; // buttons() note the s if (mouseEvent->buttons() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } QPoint pos = mouseEvent->globalPos(); QPoint diff = pos - m_startDrag; if (m_dragState == START_DRAGGING) { // Don't start dragging before moving at least DRAG_THRESHOLD pixels if (abs(diff.x()) < 4 && abs(diff.y()) < 4) return false; m_dragState = DRAGGING; } this->moveDialog(diff); m_startDrag = pos; event->accept(); return true; } //#include "moc_helpdialog.cpp" kylin-video/src/supportshortcuts.h0000644000175000017500000000223013517016402016357 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 _SUPPORTSHORTCUTS_H_ #define _SUPPORTSHORTCUTS_H_ #include "ui_supportshortcuts.h" #include "../smplayer/preferences.h" class SupportShortcuts : public QWidget, public Ui::SupportShortcuts { Q_OBJECT public: SupportShortcuts( QWidget * parent = 0, Qt::WindowFlags f = 0 ); ~SupportShortcuts(); void setData(Preferences * pref); protected: virtual void retranslateStrings(); }; #endif kylin-video/src/displaylayercomposer.cpp0000644000175000017500000000421213637124061017477 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Kylin Ltd. * * Authors: * Kobe Lee xiangli@ubuntukylin.com/kobe24_lixiang@126.com * * 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; version 3. * * 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 "displaylayercomposer.h" #include DisplayLayerComposer::DisplayLayerComposer(QWidget* parent, Qt::WindowFlags f) : AutoHideCursorWidget(parent, f) , m_repaintBackground(false) , m_playing(false) { #if QT_VERSION < 0x050000 setAttribute(Qt::WA_OpaquePaintEvent); #if QT_VERSION >= 0x040400 setAttribute(Qt::WA_NativeWindow); #endif setAttribute(Qt::WA_PaintUnclipped); #endif } DisplayLayerComposer::~DisplayLayerComposer() { } void DisplayLayerComposer::setRepaintBackground(bool b) { m_repaintBackground = b; } void DisplayLayerComposer::paintEvent(QPaintEvent * e) { if (!m_playing) {//if m_repaintBackground is true, Qt5 will call "QPainter::begin: Paint device returned engine == 0, type: 1" QPainter painter(this); painter.eraseRect(e->rect());//painter.fillRect(e->rect(), QColor(255,0,0)); } } void DisplayLayerComposer::playingStarted() { repaint(); m_playing = true; // setAttribute(Qt::WA_PaintOnScreen);//WA_PaintOnScreen该属性设置会导致播放音频文件时界面不刷新,此时如果显示或隐藏播放列表,则播放列表重影 setAttribute(Qt::WA_NativeWindow, true); AutoHideCursorWidget::playingStarted(); } void DisplayLayerComposer::playingStopped() { m_playing = false; setAttribute(Qt::WA_NativeWindow, false); repaint(); AutoHideCursorWidget::playingStopped(); } kylin-video/src/timetip.cpp0000644000175000017500000000732313517016402014702 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "timetip.h" #include #include #include #include #include TimeTip::TimeTip(const QString &text, QWidget *parent) : QFrame(parent) { setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint); setAttribute(Qt::WA_TranslucentBackground); setContentsMargins(0, 0, 0, 0); QHBoxLayout *layout = new QHBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); repaint_flag = false; text_frame = new QFrame(); text_frame->setContentsMargins(0, 0, 0, 0); text_frame->adjustSize(); QHBoxLayout *textlayout = new QHBoxLayout(this->text_frame); textlayout->setContentsMargins(10, 2, 10, 0); // textlayout->setContentsMargins(0, 0, 0, 0); textlayout->setSpacing(0); m_textLabel = new QLabel(text); m_textLabel->setObjectName("WhiteTipText"); m_textLabel->setAlignment(Qt::AlignCenter); split_line = new QLabel; split_line->setObjectName("SplitText"); split_line->setFixedWidth(1); // split_line->setFixedSize(1,20); textlayout->addWidget(m_textLabel, 0, Qt::AlignVCenter); QVBoxLayout *vlayout = new QVBoxLayout; vlayout->setContentsMargins(0, 0, 0, 0); vlayout->setSpacing(0); vlayout->addWidget(text_frame, 0, Qt::AlignHCenter); vlayout->addWidget(split_line, 0, Qt::AlignHCenter); layout->addLayout(vlayout); hide(); } TimeTip::~TimeTip() { } void TimeTip::setText(const QString text) { repaint_flag = false; this->m_textLabel->setText(text); } void TimeTip::setPixMapAndTime(QPixmap pixmap, const QString time) { repaint_flag = true; // Add current time text QPainter painter(&pixmap); painter.setPen(Qt::white); painter.drawText(pixmap.rect(), Qt::AlignHCenter | Qt::AlignBottom, time); this->m_textLabel->setPixmap(pixmap); } void TimeTip::paintEvent(QPaintEvent *event) { if (!repaint_flag) { QFrame::paintEvent(event); return; } QPainter painter(this); painter.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing); double w_pen = 2.0; QBrush background(QColor(255, 255, 255, 70)); QColor borderColor = QColor(0, 0, 0, 0.2 * 255); double margin = 9.0; QMarginsF m_shadowMargins = QMarginsF(margin, 0, margin, 26); //background QRectF bg_rect = QRectF(rect()).marginsRemoved(m_shadowMargins); QPainterPath bg_path; bg_path.addRoundedRect(bg_rect, 2, 2); painter.fillPath(bg_path, background); //border QPainterPath border_path; QRectF border_rect = QRectF(rect()); int border_radius = 4; QMarginsF border_margin(w_pen / 2, w_pen / 2, w_pen / 2, w_pen / 2); border_radius += w_pen / 2; border_rect = border_rect.marginsAdded(border_margin).marginsRemoved(m_shadowMargins); border_path.addRoundedRect(border_rect, border_radius, border_radius); QPen border_pen(borderColor); border_pen.setWidthF(w_pen); painter.strokePath(border_path, border_pen); } kylin-video/src/poweroffdialog.cpp0000644000175000017500000001732013625147453016247 0ustar fengfeng #include "poweroffdialog.h" #include "smplayer/images.h" #include #include #include #include PoweroffDialog::PoweroffDialog(QWidget * parent, Qt::WindowFlags f) : QDialog(parent, f) , m_dragState(NOT_DRAGGING) , m_startDrag(QPoint(0,0)) , m_countdown(30) , m_mainLayout(new QVBoxLayout(this)) { this->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint); setMinimumSize(QSize(438, 100)); this->setStyleSheet("QDialog{border: 1px solid #121212;border-radius:1px;background-color: #ffffff;}"); this->setWindowIcon(QIcon::fromTheme("kylin-video", QIcon(":/res/kylin-video.png"))); // this->setWindowIcon(QIcon::fromTheme("kylin-video", QIcon(":/res/kylin-video.png")).pixmap(QSize(64, 64)).scaled(64, 64, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); this->setAutoFillBackground(true); this->setMouseTracking(true); this->installEventFilter(this); m_text = tr("The computer will shut down in %1 seconds.") +"
    "+ tr("Press Cancel to abort shutdown."); m_topWidget = new QWidget(this); m_topWidget->setFixedHeight(39); m_topWidget->setMouseTracking(true); m_topWidget->setAutoFillBackground(true); m_topWidget->setStyleSheet("QWidget{border:none;background-color:#2e2e2e;}"); // QPalette palette; // palette.setBrush(QPalette::Background, QBrush(QPixmap(":/res/about_bg.png"))); // m_topWidget->setPalette(palette); QHBoxLayout *top_layout = new QHBoxLayout(m_topWidget); top_layout->setSpacing(0); top_layout->setMargin(0); m_closeBtn = new QPushButton(m_topWidget); m_closeBtn->setFixedSize(36, 36); m_closeBtn->setFocusPolicy(Qt::NoFocus); m_closeBtn->setStyleSheet("QPushButton{background-image:url(':/res/close_normal.png');border:0px;}QPushButton:hover{background:url(':/res/close_hover.png');}QPushButton:pressed{background:url(':/res/close_press.png');}"); top_layout->addStretch(); top_layout->addWidget(m_closeBtn, 0, Qt::AlignRight | Qt::AlignTop); connect(m_closeBtn, &QPushButton::clicked, this, &PoweroffDialog::close); m_centerFrame = new QFrame(this); m_centerFrame->setFrameShape(QFrame::HLine); m_centerFrame->setFrameShadow(QFrame::Sunken); QHBoxLayout *horizontalLayout = new QHBoxLayout(m_centerFrame); icon_label = new QLabel(this); icon_label->setMinimumSize(QSize(100, 0)); icon_label->setAlignment(Qt::AlignCenter); icon_label->setPixmap(Images::icon("kylin-video")); horizontalLayout->addWidget(icon_label); m_textLabel = new QLabel(this); QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); sizePolicy.setHeightForWidth(m_textLabel->sizePolicy().hasHeightForWidth()); m_textLabel->setSizePolicy(sizePolicy); m_textLabel->setWordWrap(true); m_textLabel->setText(m_text.arg(m_countdown)); horizontalLayout->addWidget(m_textLabel); //QMessageBox::StandardButtons buttons = QMessageBox::Ok | QMessageBox::Cancel; //QMessageBox::StandardButton defaultButton = QMessageBox::Cancel; m_buttonBox = new QDialogButtonBox(this); m_buttonBox->setOrientation(Qt::Horizontal); m_buttonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok);//buttonBox->setStandardButtons(QDialogButtonBox::StandardButtons(int(buttons))); m_buttonBox->setContentsMargins(0, 0, 20, 0); m_mainLayout->setSpacing(0); m_mainLayout->setMargin(0); m_mainLayout->setContentsMargins(0, 0, 0, 20); m_mainLayout->addWidget(m_topWidget, 0, Qt::AlignTop); m_mainLayout->addWidget(m_centerFrame); m_mainLayout->addWidget(m_buttonBox, 0, Qt::AlignBottom); QPushButton *okBtn = m_buttonBox->button(QDialogButtonBox::Ok); if (okBtn != NULL) { okBtn->setFixedSize(91, 25); okBtn->setText(tr("Ok")); okBtn->setFocusPolicy(Qt::NoFocus); okBtn->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); } QPushButton *cancelBtn = m_buttonBox->button(QDialogButtonBox::Cancel); if (cancelBtn != NULL) { cancelBtn->setFixedSize(91, 25); cancelBtn->setText(tr("Cancel")); cancelBtn->setFocusPolicy(Qt::NoFocus); cancelBtn->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #000000;color:#999999;}QPushButton:hover{background-color:#1f1f1f;border:1px solid #0f0f0f;color:#ffffff;} QPushButton:pressed{background-color:#0d0d0d;border:1px solid #000000;color:#ffffff;}"); } if (okBtn) { okBtn->setDefault(false); okBtn->setAutoDefault(false); } if (cancelBtn) { cancelBtn->setDefault(true); cancelBtn->setAutoDefault(true); } QObject::connect(m_buttonBox, SIGNAL(accepted()), this, SLOT(accept())); QObject::connect(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject())); this->adjustSize(); m_timer = new QTimer(this); m_timer->setInterval(1000); connect(m_timer, SIGNAL(timeout()), this, SLOT(updateCountdown())); m_timer->start(); } PoweroffDialog::~PoweroffDialog() { } void PoweroffDialog::updateCountdown() { m_countdown--; m_textLabel->setText(m_text.arg(m_countdown)); if (m_countdown < 1) { this->accept(); } } QSize PoweroffDialog::sizeHint () const { return this->size(); } void PoweroffDialog::moveDialog(QPoint diff) { #if QT_VERSION >= 0x050000 // Move the window with some delay. // Seems to work better with Qt 5 static QPoint d; static int count = 0; d += diff; count++; if (count > 3) { QPoint new_pos = pos() + d; if (new_pos.y() < 0) new_pos.setY(0); if (new_pos.x() < 0) new_pos.setX(0); move(new_pos); count = 0; d = QPoint(0,0); } #else move(pos() + diff); #endif } bool PoweroffDialog::eventFilter( QObject * object, QEvent * event ) { QEvent::Type type = event->type(); if (type != QEvent::MouseButtonPress && type != QEvent::MouseButtonRelease && type != QEvent::MouseMove) return false; QMouseEvent *mouseEvent = dynamic_cast(event); if (!mouseEvent) return false; if (mouseEvent->modifiers() != Qt::NoModifier) { m_dragState = NOT_DRAGGING; return false; } if (type == QEvent::MouseButtonPress) { if (mouseEvent->button() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } m_dragState = START_DRAGGING; m_startDrag = mouseEvent->globalPos(); // Don't filter, so others can have a look at it too return false; } if (type == QEvent::MouseButtonRelease) { if (m_dragState != DRAGGING || mouseEvent->button() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } // Stop dragging and eat event m_dragState = NOT_DRAGGING; event->accept(); return true; } // type == QEvent::MouseMove if (m_dragState == NOT_DRAGGING) return false; // buttons() note the s if (mouseEvent->buttons() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } QPoint pos = mouseEvent->globalPos(); QPoint diff = pos - m_startDrag; if (m_dragState == START_DRAGGING) { // Don't start dragging before moving at least DRAG_THRESHOLD pixels if (abs(diff.x()) < 4 && abs(diff.y()) < 4) return false; m_dragState = DRAGGING; } this->moveDialog(diff); m_startDrag = pos; event->accept(); return true; } kylin-video/src/titlebutton.cpp0000644000175000017500000000605713517016402015607 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "titlebutton.h" #include #include #include #include namespace { const int LEFT_WIDTH = 2; const int TITLE_LM_BIG = 10; const int TITLE_LM_NORMAL = 20; const int FONT_SIZE_BIG = 14; const int FONT_SIZE_NORMAL = 14; const QColor FONT_COLOR_ACTIVED = QColor("#ffffff"); const QColor FONT_COLOR_NORMAL = QColor("#999999"); const QColor LEFT_COLOR_ACTIVED = QColor("#0a9ff5"); const QColor RIGHT_COLOR_ACTIVED = QColor("#1f1f1f"); } TitleButton::TitleButton(int id, bool bigFont, const QString &title, QWidget *parent) : QWidget(parent) , m_bigFont(bigFont) , m_isActived(false) , m_id(id) , m_title(title) { setFixedHeight(45); this->setStyleSheet("QWidget{border:none;}"); } void TitleButton::mousePressEvent(QMouseEvent *e) { if (e->button() == Qt::LeftButton) { emit this->clicked(m_id); e->accept(); } } void TitleButton::paintEvent(QPaintEvent *e) { const QColor lbc = isActived() ? LEFT_COLOR_ACTIVED : QColor("#2e2e2e");//没有选中时,让其左侧2px宽度的区域颜色和title_widget背景颜色一致 const QColor rbc = isActived() ? RIGHT_COLOR_ACTIVED : QColor("#2e2e2e"); const QRect lr(0, 0, LEFT_WIDTH, height()); const QRect rr(LEFT_WIDTH, 0, width() - LEFT_WIDTH, height()); const QRect bfr(TITLE_LM_BIG, (height() - FONT_SIZE_BIG) / 4, width() - TITLE_LM_BIG, height()); const QRect nfr(TITLE_LM_NORMAL, (height() - FONT_SIZE_NORMAL) / 3, width() - TITLE_LM_NORMAL, height()); // background QPainter painter(this); painter.fillRect(lr, lbc); if (isActived()) { painter.fillRect(rr, rbc); } // title QFont f; if (m_bigFont) f.setWeight(700); f.setPixelSize(m_bigFont ? FONT_SIZE_BIG : FONT_SIZE_NORMAL); QPen p(isActived() ? FONT_COLOR_ACTIVED : FONT_COLOR_NORMAL); painter.setFont(f); painter.setPen(p); painter.drawText(m_bigFont ? bfr : nfr, m_title); // painter.drawText(rect(), Qt::AlignCenter, "Kobe"); } bool TitleButton::isActived() const { return m_isActived; } void TitleButton::setActived(bool isActived) { m_isActived = isActived; this->update(); } int TitleButton::id() const { return m_id; } void TitleButton::setId(const int &id) { m_id = id; } kylin-video/src/autohidecursorwidget.cpp0000644000175000017500000000445413517016402017475 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Kylin Ltd. * * Authors: * Kobe Lee xiangli@ubuntukylin.com/kobe24_lixiang@126.com * * 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; version 3. * * 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 "autohidecursorwidget.h" #include #include AutoHideCursorWidget::AutoHideCursorWidget(QWidget* parent, Qt::WindowFlags f) : QWidget(parent, f ) , m_checkMouseTimer(new QTimer(this)) , m_mouseLastPosition(QPoint(0,0)) , m_autohideCursor(false) , autohide_interval(1000) { this->setMouseTracking(true); this->setFocusPolicy(Qt::NoFocus); this->setMinimumSize(QSize(0,0)); this->setAutoHideCursor(false); connect(m_checkMouseTimer, SIGNAL(timeout()), this, SLOT(checkMousePos())); } AutoHideCursorWidget::~AutoHideCursorWidget() { } void AutoHideCursorWidget::setAutoHideCursor(bool b) { m_autohideCursor = b; if (m_autohideCursor) { m_checkMouseTimer->setInterval(autohide_interval); m_checkMouseTimer->start(); } else { m_checkMouseTimer->stop(); } } void AutoHideCursorWidget::checkMousePos() { if (!m_autohideCursor) { setCursor(QCursor(Qt::ArrowCursor)); return; } QPoint pos = mapFromGlobal(QCursor::pos()); if (m_mouseLastPosition != pos) { setCursor(QCursor(Qt::ArrowCursor)); } else { setCursor(QCursor(Qt::BlankCursor)); } m_mouseLastPosition = pos; } void AutoHideCursorWidget::mouseMoveEvent(QMouseEvent * e) { emit mouseMoved(e->pos()); if (cursor().shape() != Qt::ArrowCursor) { setCursor(QCursor(Qt::ArrowCursor)); } } void AutoHideCursorWidget::playingStarted() { setAutoHideCursor(true); } void AutoHideCursorWidget::playingStopped() { setAutoHideCursor(false); } kylin-video/src/soundvolume.h0000644000175000017500000000356113517016402015254 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 class QSlider; #include class SoundVolume : public QWidget { Q_OBJECT Q_PROPERTY(int radius READ radius WRITE setRadius) Q_PROPERTY(QBrush background READ background WRITE setBackground) Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor) public: explicit SoundVolume(QWidget *parent = 0); ~SoundVolume(); int volume() const; int radius() const; QColor borderColor() const; QBrush background() const; signals: void volumeChanged(int vol); public slots: void deleyHide(); void onVolumeChanged(int vol); void setBackground(QBrush m_background); void setRadius(int m_radius); void setBorderColor(QColor m_borderColor); void slot_deley(); virtual void setValue(int); protected: virtual void showEvent(QShowEvent *event); virtual void enterEvent(QEvent *event); virtual void leaveEvent(QEvent *event); virtual void wheelEvent(QWheelEvent *event); private: int tradius; QBrush tbackground; QColor tborderColor; QSlider *m_volSlider = nullptr; bool mouseIn; }; kylin-video/src/helpdialog.h0000644000175000017500000000362713517016402015007 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 _HELPDIALOG_H_ #define _HELPDIALOG_H_ #include "ui_helpdialog.h" #include "utils.h" class QTextBrowser; class QPushButton; class SupportFormats; //class SupportShortcuts; class TitleButton; class Preferences; class HelpDialog : public QDialog, public Ui::HelpDialog { Q_OBJECT public: enum Section { Formats=0, Other=1 }; HelpDialog(QWidget * parent = 0, Qt::WindowFlags f = 0 ); ~HelpDialog(); void addSection(QWidget *w); // Pass data to the standard dialogs void setData(Preferences * pref); virtual bool eventFilter(QObject *, QEvent *); void moveDialog(QPoint diff); public slots: void showSection(Section s); virtual void accept(); // Reimplemented to send a signal signals: void applied(); protected: virtual void retranslateStrings(); virtual void changeEvent ( QEvent * event ) ; public slots: void onButtonClicked(int id); void setCurrentID(int id); void switchCurrentIDPage(int id); private: QList m_buttonList; protected: SupportFormats *m_pageFormats = nullptr; // SupportShortcuts *page_shortcuts; private: DragState m_dragState; QPoint m_startDrag; }; #endif kylin-video/src/utils.h0000644000175000017500000000451113517016402014030 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Kylin Ltd. * * Authors: * Kobe Lee xiangli@ubuntukylin.com/kobe24_lixiang@126.com * * 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; version 3. * * 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 UTILS_H #define UTILS_H #include #include #include #include #include "smplayer/preferences.h" #define PLAYER_NAME "MPlayer/mpv" #define TOP_TOOLBAR_HEIGHT 39 #define BOTTOM_TOOLBAR_HEIGHT 79 #define ANIMATIONDELAY 400 #define WINDOW_MIN_WIDTH 400 #define WINDOW_MIN_HEIGHT 300 // ENABLE_DELAYED_DRAGGING // if 1, sends the dragging position of the time slider // some ms later #define ENABLE_DELAYED_DRAGGING 1 // if SEEKBAR_RESOLUTION is defined, it specified the // maximum value of the time slider #define SEEKBAR_RESOLUTION 1000 // DVDNAV_SUPPORT // if 1, smplayer will be compiled with support for mplayer's dvdnav //#ifdef MPLAYER_SUPPORT //#define DVDNAV_SUPPORT 0 //#endif enum DragState {NOT_DRAGGING, START_DRAGGING, DRAGGING}; class Utils { public: enum PlayerId { MPLAYER = 0, MPV = 1 }; static PlayerId player(const QString &player_bin); static void setWidgetOpacity(QWidget *w, bool transparent, const float &opacity=0.7); // Format a time (hh:mm:ss) static QString formatTime(int secs); static QString timeForJumps(int secs); static bool directoryContainsDVD(QString directory); static QStringList filesForPlaylist(const QString & initial_file, Preferences::AutoAddToPlaylistFilter filter); static QString findExecutable(const QString & name); static void shutdown(); private: static QStringList searchForConsecutiveFiles(const QString & initial_file); static QStringList filesInDirectory(const QString & initial_file, const QStringList & filter); }; #endif // UTILS_H kylin-video/src/aboutdialog.h0000644000175000017500000000334713517016402015170 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "ui_aboutdialog.h" #include "utils.h" #include #include class QParallelAnimationGroup; enum TabState {TAB_ABOUT, TAB_CONTRIBUTOR}; class AboutDialog : public QDialog, public Ui::AboutDialog { Q_OBJECT public: AboutDialog(const QString &snap, QWidget * parent = 0, Qt::WindowFlags f = 0 ); ~AboutDialog(); void initConnect(); void initAnimation(); virtual bool eventFilter(QObject *, QEvent *); void moveDialog(QPoint diff); void setVersions(); virtual QSize sizeHint () const; QString link(const QString & url, QString name = ""); public slots: void onAboutBtnClicked(); void onContributorBtnClicked(); private: QPushButton *m_okBtn = nullptr; QParallelAnimationGroup *m_aboutGroup = nullptr; QParallelAnimationGroup *m_contributorGroup = nullptr; DragState m_dragState; TabState tab_state; QPoint m_startDrag; QString m_snap; }; #endif kylin-video/src/coverwidget.h0000644000175000017500000000167413517016402015221 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 class CoverWidget : public QFrame { Q_OBJECT public: explicit CoverWidget(QWidget *parent = 0); ~CoverWidget(); void updateUI(); }; kylin-video/src/poweroffdialog.h0000644000175000017500000000157613517016402015707 0ustar fengfeng #ifndef _POWEROFFDIALOG_H_ #define _POWEROFFDIALOG_H_ #include #include #include #include #include #include #include "utils.h" class PoweroffDialog : public QDialog { Q_OBJECT public: PoweroffDialog(QWidget * parent = 0, Qt::WindowFlags f = 0 ); ~PoweroffDialog(); void moveDialog(QPoint diff); protected: virtual bool eventFilter(QObject *, QEvent *); virtual QSize sizeHint () const; private slots: void updateCountdown(); private: DragState m_dragState; QPoint m_startDrag; QWidget *m_topWidget; QFrame *m_centerFrame; QDialogButtonBox *m_buttonBox; QPushButton *m_closeBtn; int m_countdown; QTimer *m_timer = nullptr; QString m_text; QVBoxLayout *m_mainLayout; QLabel *icon_label; QLabel *m_textLabel; }; #endif // _POWEROFFDIALOG_H_ kylin-video/src/soundvolume.cpp0000644000175000017500000000674513517016402015616 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "soundvolume.h" #include #include #include #include #include #include #include SoundVolume::SoundVolume(QWidget *parent) : QWidget(parent) { this->setObjectName("SoundVolume"); setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint); setAttribute(Qt::WA_TranslucentBackground); setFixedSize(106, 40);//setFixedSize(40, 106); QHBoxLayout *layout = new QHBoxLayout(this); layout->setContentsMargins(5, 0, 5, 0);//(0, 5, 0, 11);// layout->setSpacing(0); m_volSlider = 0; tborderColor = QColor(0, 0, 0, 255 * 2 / 10); tradius = 4; mouseIn = false; m_volSlider = new QSlider(Qt::Horizontal);//Qt::Vertical m_volSlider->setMinimum(0); m_volSlider->setMaximum(100); m_volSlider->setSingleStep(10);//VolumeStep m_volSlider->setValue(50); m_volSlider->setFocusPolicy(Qt::NoFocus); m_volSlider->setObjectName("VolumeProgress"); layout->addStretch(); layout->addWidget(m_volSlider, 0, Qt::AlignCenter); layout->addStretch(); setFixedSize(106, 24); connect(m_volSlider, SIGNAL(valueChanged(int)), this, SIGNAL(volumeChanged(int))); } SoundVolume::~SoundVolume() { } void SoundVolume::setValue(int vol) { bool was_blocked = m_volSlider->blockSignals(true); m_volSlider->setValue(vol); m_volSlider->blockSignals(was_blocked); } int SoundVolume::volume() const { return m_volSlider->value(); } QBrush SoundVolume::background() const { return tbackground; } int SoundVolume::radius() const { return this->tradius; } QColor SoundVolume::borderColor() const { return this->tborderColor; } void SoundVolume::setBackground(QBrush m_background) { this->tbackground = m_background; } void SoundVolume::setRadius(int m_adius) { this->tradius = m_adius; } void SoundVolume::setBorderColor(QColor m_borderColor) { this->tborderColor = m_borderColor; } void SoundVolume::deleyHide() { this->mouseIn = false; // QTimer::singleShot(1000, this, SLOT(slot_deley())); } void SoundVolume::slot_deley() { if (!this->mouseIn) { hide(); } } void SoundVolume::onVolumeChanged(int vol) { this->m_volSlider->blockSignals(true); this->m_volSlider->setValue(vol); this->m_volSlider->blockSignals(false); } void SoundVolume::showEvent(QShowEvent *event) { this->mouseIn = true; QWidget::showEvent(event); } void SoundVolume::enterEvent(QEvent *event) { this->mouseIn = true; QWidget::enterEvent(event); } void SoundVolume::leaveEvent(QEvent *event) { this->mouseIn = false; deleyHide(); QWidget::leaveEvent(event); } void SoundVolume::wheelEvent(QWheelEvent *event) { QWidget::wheelEvent(event); } kylin-video/src/myapplication.h0000644000175000017500000000313713517016402015544 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 MYAPPLICATION_H #define MYAPPLICATION_H #include #ifdef SINGLE_INSTANCE #include "QtSingleApplication" class MyApplication : public QtSingleApplication { Q_OBJECT public: MyApplication ( const QString & appId, int & argc, char ** argv ) : QtSingleApplication(appId, argc, argv) {}; virtual void commitData ( QSessionManager & /*manager*/ ) { // Nothing to do, let the application to close } inline static MyApplication * instance() { return qobject_cast(QApplication::instance()); } }; #else #include class MyApplication : public QApplication { Q_OBJECT public: MyApplication ( const QString & appId, int & argc, char ** argv ) : QApplication(argc, argv) {}; virtual void commitData ( QSessionManager & /*manager*/ ) { // Nothing to do, let the application to close } }; #endif #endif kylin-video/src/esctip.cpp0000644000175000017500000000721113517016402014512 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "esctip.h" #include #include #include #include #include #include #include EscTip::EscTip(QWidget *parent) : QFrame(parent) { setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint); setAttribute(Qt::WA_TranslucentBackground); setContentsMargins(0, 0, 0, 0); setObjectName("EscTip");//设置背景色 m_radius = 4; m_shadow = 20; m_shadowMargins = QMargins(20, 20, 20, 20); m_borderColor = QColor(0, 0, 0, 0.2 * 255); QVBoxLayout *layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); m_textLabel = new QLabel(this); m_textLabel->adjustSize(); m_textLabel->setStyleSheet("QLabel{font-size: 16px;color: #ffffff;}"); m_textLabel->setAlignment(Qt::AlignCenter); m_textLabel->setText(tr("Press ESC to exit full screen mode")); layout->addStretch(); layout->addWidget(m_textLabel); layout->addStretch(); this->setLayout(layout); hide(); } EscTip::~EscTip() { } QBrush EscTip::background() const { return this->m_background; } int EscTip::radius() const { return this->m_radius; } QColor EscTip::borderColor() const { return this->m_borderColor; } void EscTip::setBackground(QBrush background) { this->m_background = background; } void EscTip::setRadius(int radius) { this->m_radius = radius; } void EscTip::setBorderColor(QColor borderColor) { this->m_borderColor = borderColor; } void EscTip::aniFinished() { this->hide(); } void EscTip::paintEvent(QPaintEvent * e) { Q_UNUSED(e); bool outer = true; QPainter painter(this); painter.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing); int radius = this->m_radius; double w_pen = 1.0; QBrush background = this->m_background; QColor border_color = this->m_borderColor; double margin = 2.0; QMarginsF m_shadowMargins = QMarginsF(margin, margin, margin, margin); //background QRectF bg_rect = QRectF(rect()).marginsRemoved(m_shadowMargins); QPainterPath bg_path; bg_path.addRoundedRect(bg_rect, radius, radius); painter.fillPath(bg_path, background); //border QPainterPath border_path; QRectF border_rect = QRectF(rect()); int border_radius = radius; QMarginsF border_margin(w_pen / 2, w_pen / 2, w_pen / 2, w_pen / 2); if (outer) { border_radius += w_pen / 2; border_rect = border_rect.marginsAdded(border_margin).marginsRemoved(m_shadowMargins); } else { border_radius -= w_pen / 2; border_rect = border_rect.marginsRemoved(border_margin).marginsRemoved(m_shadowMargins); } border_path.addRoundedRect(border_rect, border_radius, border_radius); QPen border_pen(border_color); border_pen.setWidthF(w_pen); painter.strokePath(border_path, border_pen); } kylin-video/src/infoworker.h0000644000175000017500000000223513625147453015071 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 INFO_WORKER_H #define INFO_WORKER_H #include #include #include "datautils.h" class InfoWorker : public QObject { Q_OBJECT public: explicit InfoWorker(QObject *parent = 0); ~InfoWorker(); public slots: void onGetMediaInfo(const QStringList &filepaths); signals: void meidaFilesAdded(VideoPtrList medialist, bool isFileInPlaylist); }; #endif // INFO_WORKER_H kylin-video/src/remotecontroller.h0000644000175000017500000000332213517016402016266 0ustar fengfeng/* * This file was generated by qdbusxml2cpp version 0.8 * Command line was: qdbusxml2cpp remote_controller.xml -a remotecontroller * * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. * * This is an auto-generated file. * This file may have been hand-edited. Look for HAND-EDIT comments * before re-generating it. */ #ifndef REMOTECONTROLLER_H #define REMOTECONTROLLER_H #include #include QT_BEGIN_NAMESPACE class QByteArray; template class QList; template class QMap; class QString; class QStringList; class QVariant; QT_END_NAMESPACE /* * Adaptor class for interface com.kylin.kylinvideo.controller */ class ControllerAdaptor: public QDBusAbstractAdaptor { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "com.kylin.kylinvideo.controller") Q_CLASSINFO("D-Bus Introspection", "" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" "") public: ControllerAdaptor(QObject *parent); virtual ~ControllerAdaptor(); public: // PROPERTIES public Q_SLOTS: // METHODS void playPause(); void quit(); bool seek_forward(int seconds); bool seek_rewind(int seconds); void stop(); Q_SIGNALS: // SIGNALS void aboutToQuit(); }; #endif kylin-video/src/playlistmodel.cpp0000644000175000017500000000547113517016402016113 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "playlistmodel.h" #include "../smplayer/preferences.h" #include "../smplayer/global.h" using namespace Global; #include PlaylistModel::PlaylistModel(QObject *parent) : QStandardItemModel(parent) { m_removeIndex = QModelIndex(); m_hoverIndex = QModelIndex(); } PlaylistModel::~PlaylistModel() { } QString PlaylistModel::findFileNameByRow(int row) { QModelIndex itemIndex = this->index(row, 0); QString filepath = data(itemIndex).toString(); return filepath; } QModelIndex PlaylistModel::findModelIndex(const VideoPtr video) { Q_ASSERT(!video.isNull()); QModelIndex itemIndex; for (int i = 0; i < rowCount(); ++i) { itemIndex = index(i, 0); QString filepath = data(itemIndex).toString();//没有重写model的data函数时 if (filepath == video->m_localpath) { return itemIndex; } } return QModelIndex(); } bool PlaylistModel::setData(const QModelIndex &index, const QVariant &value, int role) { return QStandardItemModel::setData(index, value, role); } QString PlaylistModel::filePathData(const QModelIndex &index, int role) const { QString filepath = this->data(index, role).toString(); return filepath; } VideoPtr PlaylistModel::videoData(const QModelIndex &index, int role) const { QString filepath = this->data(index, role).toString(); auto video = pref->video(filepath); if (video.isNull()) { return VideoPtr(); } return video; } Qt::DropActions PlaylistModel::supportedDropActions() const { return Qt::CopyAction | Qt::MoveAction;//return QAbstractItemModel::supportedDropActions(); } Qt::ItemFlags PlaylistModel::flags(const QModelIndex &index) const { Qt::ItemFlags defaultFlags = QAbstractItemModel::flags(index); if (index.isValid()) { return Qt::ItemIsDragEnabled | defaultFlags;//Qt::ItemIsEditable } else { return Qt::ItemIsDropEnabled | defaultFlags; } } void PlaylistModel::setHoverIndex(const QModelIndex &index) { m_hoverIndex = index; emit dataChanged(m_hoverIndex, m_hoverIndex); } kylin-video/src/src.pro0000644000175000017500000002143513637124061014040 0ustar fengfengTARGET = kylin-video TEMPLATE = app LANGUAGE = C++ CONFIG += c++14 CONFIG += qt warn_on CONFIG += release CONFIG += link_pkgconfig QT += network xml RESOURCES = res.qrc DEFINES += SINGLE_INSTANCE !system($$PWD/translations/generate_translations_pm.sh): error("Failed to generate pm") qm_files.files = translations/*.qm qm_files.path = /usr/share/kylin-video/translations/ inst1.files += res/kylin-video.png inst1.path = /usr/share/pixmaps inst2.files += ../kylin-video.desktop inst2.path = /usr/share/applications target.source += $$TARGET target.path = /usr/bin INSTALLS += inst1 \ inst2 \ qm_files \ target QMAKE_CPPFLAGS *= $(shell dpkg-buildflags --get CPPFLAGS) QMAKE_CFLAGS *= $(shell dpkg-buildflags --get CFLAGS) QMAKE_CXXFLAGS *= $(shell dpkg-buildflags --get CXXFLAGS) QMAKE_LFLAGS *= $(shell dpkg-buildflags --get LDFLAGS) isEqual(QT_MAJOR_VERSION, 5) { QT += widgets gui x11extras } unix { QT += gui-private dbus LIBS += $${QMAKE_LIBS_X11} } LIBS += -lX11 HEADERS += smplayer/mplayerversion.h \ smplayer/mplayerprocess.h \ smplayer/inforeadermplayer.h \ smplayer/mpvprocess.h \ smplayer/inforeadermpv.h \ smplayer/version.h \ smplayer/global.h \ smplayer/paths.h \ smplayer/colorutils.h \ smplayer/subtracks.h \ smplayer/tracks.h \ smplayer/titletracks.h \ smplayer/extensions.h \ smplayer/desktopinfo.h \ smplayer/myprocess.h \ smplayer/playerprocess.h \ smplayer/infoprovider.h \ smplayer/mediadata.h \ smplayer/mediasettings.h \ smplayer/images.h \ smplayer/inforeader.h \ smplayer/deviceinfo.h \ smplayer/recents.h \ smplayer/urlhistory.h \ smplayer/core.h \ smplayer/shortcutgetter.h \ smplayer/actionseditor.h \ smplayer/filechooser.h \ smplayer/mycombobox.h \ smplayer/mylineedit.h \ smplayer/tristatecombo.h \ smplayer/myslider.h \ smplayer/timeslider.h \ smplayer/myaction.h \ smplayer/myactiongroup.h \ smplayer/filedialog.h \ smplayer/timedialog.h \ smplayer/cleanconfig.h \ smplayer/infofile.h \ smplayer/translator.h \ smplayer/languages.h \ smplayer/filesettings.h \ smplayer/filesettingsbase.h \ smplayer/filesettingshash.h \ smplayer/filehash.h \ smplayer/prefwidget.h \ smplayer/scrollermodule.h \ smplayer/filters.h \ smplayer/assstyles.h \ smplayer/audioequalizer.h \ smplayer/audioequalizerlist.h \ smplayer/verticaltext.h \ smplayer/eqslider.h \ smplayer/chapters.h \ smplayer/globalshortcuts/globalshortcuts.h \ smplayer/globalshortcuts/globalshortcutsdialog.h \ smplayer/discname.h \ smplayer/lineedit_with_icon.h \ smplayer/preferencesdialog.h \ smplayer/prefgeneral.h \ smplayer/prefperformance.h \ smplayer/prefsubtitles.h \ smplayer/prefscreenshot.h \ smplayer/prefshortcut.h \ smplayer/prefvideo.h \ smplayer/prefaudio.h \ smplayer/filepropertiesdialog.h \ smplayer/audiodelaydialog.h \ smplayer/inputurl.h \ smplayer/errordialog.h \ smplayer/preferences.h \ smplayer/videopreview.h \ titlewidget.h \ bottomwidget.h \ soundvolume.h \ titlebutton.h \ aboutdialog.h \ playmask.h \ timetip.h \ esctip.h \ tipwidget.h \ messagedialog.h \ helpdialog.h \ supportformats.h \ systembutton.h \ playlist.h \ playlistview.h \ playlistmodel.h \ playlistdelegate.h \ datautils.h \ myapplication.h \ coverwidget.h \ infoworker.h \ kylinvideo.h \ bottomcontroller.h \ filterhandler.h \ maskwidget.h \ mainwindow.h \ autohidecursorwidget.h \ displaylayercomposer.h \ videowindow.h \ poweroffdialog.h \ controllerworker.h \ remotecontroller.h \ utils.h SOURCES += smplayer/version.cpp \ smplayer/mplayerversion.cpp \ smplayer/mplayerprocess.cpp \ smplayer/inforeadermplayer.cpp \ smplayer/mpvprocess.cpp \ smplayer/inforeadermpv.cpp \ smplayer/mpvoptions.cpp \ smplayer/global.cpp \ smplayer/paths.cpp \ smplayer/colorutils.cpp \ smplayer/subtracks.cpp \ smplayer/tracks.cpp \ smplayer/titletracks.cpp \ smplayer/extensions.cpp \ smplayer/desktopinfo.cpp \ smplayer/myprocess.cpp \ smplayer/playerprocess.cpp \ smplayer/mplayeroptions.cpp \ smplayer/infoprovider.cpp \ smplayer/mediadata.cpp \ smplayer/mediasettings.cpp \ smplayer/images.cpp \ smplayer/inforeader.cpp \ smplayer/deviceinfo.cpp \ smplayer/recents.cpp \ smplayer/urlhistory.cpp \ smplayer/core.cpp \ smplayer/shortcutgetter.cpp \ smplayer/actionseditor.cpp \ smplayer/filechooser.cpp \ smplayer/mycombobox.cpp \ smplayer/mylineedit.cpp \ smplayer/tristatecombo.cpp \ smplayer/myslider.cpp \ smplayer/timeslider.cpp \ smplayer/myaction.cpp \ smplayer/myactiongroup.cpp \ smplayer/filedialog.cpp \ smplayer/timedialog.cpp \ smplayer/cleanconfig.cpp \ smplayer/infofile.cpp \ smplayer/translator.cpp \ smplayer/languages.cpp \ smplayer/filesettings.cpp \ smplayer/filesettingsbase.cpp \ smplayer/filesettingshash.cpp \ smplayer/filehash.cpp \ smplayer/prefwidget.cpp \ smplayer/scrollermodule.cpp \ smplayer/filters.cpp \ smplayer/assstyles.cpp \ smplayer/audioequalizer.cpp \ smplayer/audioequalizerlist.cpp \ smplayer/verticaltext.cpp \ smplayer/eqslider.cpp \ smplayer/chapters.cpp \ smplayer/globalshortcuts/globalshortcuts.cpp \ smplayer/globalshortcuts/globalshortcutsdialog.cpp \ smplayer/discname.cpp \ smplayer/lineedit_with_icon.cpp \ smplayer/preferencesdialog.cpp \ smplayer/prefgeneral.cpp \ smplayer/prefperformance.cpp \ smplayer/prefsubtitles.cpp \ smplayer/prefscreenshot.cpp \ smplayer/prefshortcut.cpp \ smplayer/prefvideo.cpp \ smplayer/prefaudio.cpp \ smplayer/filepropertiesdialog.cpp \ smplayer/audiodelaydialog.cpp \ smplayer/inputurl.cpp \ smplayer/errordialog.cpp \ smplayer/preferences.cpp \ smplayer/videopreview.cpp \ titlewidget.cpp \ bottomwidget.cpp \ soundvolume.cpp \ titlebutton.cpp \ aboutdialog.cpp \ playmask.cpp \ timetip.cpp \ esctip.cpp \ tipwidget.cpp \ messagedialog.cpp \ helpdialog.cpp \ supportformats.cpp \ systembutton.cpp \ playlist.cpp \ playlistview.cpp \ playlistmodel.cpp \ playlistdelegate.cpp \ main.cpp \ coverwidget.cpp \ infoworker.cpp \ kylinvideo.cpp \ bottomcontroller.cpp \ filterhandler.cpp \ maskwidget.cpp \ mainwindow.cpp \ autohidecursorwidget.cpp \ displaylayercomposer.cpp \ videowindow.cpp \ poweroffdialog.cpp \ controllerworker.cpp \ remotecontroller.cpp \ utils.cpp FORMS = smplayer/timedialog.ui \ smplayer/preferencesdialog.ui \ smplayer/prefgeneral.ui \ smplayer/prefperformance.ui \ smplayer/prefsubtitles.ui \ smplayer/prefscreenshot.ui \ smplayer/prefshortcut.ui \ smplayer/prefvideo.ui \ smplayer/prefaudio.ui \ smplayer/filepropertiesdialog.ui \ smplayer/inputurl.ui \ smplayer/audiodelaydialog.ui \ smplayer/errordialog.ui \ helpdialog.ui \ supportformats.ui \ aboutdialog.ui \ smplayer/globalshortcuts/globalshortcutsdialog.ui # qtsingleapplication contains( DEFINES, SINGLE_INSTANCE ) { INCLUDEPATH += qtsingleapplication DEPENDPATH += qtsingleapplication SOURCES += qtsingleapplication/qtsingleapplication.cpp qtsingleapplication/qtlocalpeer.cpp HEADERS += qtsingleapplication/qtsingleapplication.h qtsingleapplication/qtlocalpeer.h } #contains( DEFINES, GLOBALSHORTCUTS ) { # lessThan(QT_MAJOR_VERSION, 5) { # DEFINES -= GLOBALSHORTCUTS # message("GLOBALSHORTCUTS requires Qt 5. Disabled.") # } #} unix { UI_DIR = .ui MOC_DIR = .moc OBJECTS_DIR = .obj } #TRANSLATIONS += \ # translation/kylin-video_zh_CN.ts kylin-video/src/supportformats.h0000644000175000017500000000212313517016402015775 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 _SUPPORTFORMATS_H_ #define _SUPPORTFORMATS_H_ #include "ui_supportformats.h" class SupportFormats : public QWidget, public Ui::SupportFormats { Q_OBJECT public: SupportFormats( QWidget * parent = 0, Qt::WindowFlags f = 0 ); ~SupportFormats(); void setData(); protected: virtual void retranslateStrings(); }; #endif kylin-video/src/tipwidget.h0000644000175000017500000000337713517016402014701 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 _TIPWIDGET_H_ #define _TIPWIDGET_H_ #include class QLabel; class TipWidget : public QFrame { Q_OBJECT Q_PROPERTY(int radius READ radius WRITE setRadius) Q_PROPERTY(QBrush background READ background WRITE setBackground) Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor) public: explicit TipWidget(const QString &text, QWidget *parent = 0); ~TipWidget(); void setBackgroundImage(const QPixmap &srcPixmap); int radius() const; QColor borderColor() const; QBrush background() const; void setTransparent(bool transparent); void set_widget_opacity(const float &opacity); public slots: void setText(const QString text); void setBackground(QBrush background); void setRadius(int radius); void setBorderColor(QColor borderColor); void aniFinished(); private: QLabel *m_textLabel = nullptr; QBrush m_background; int m_radius; int m_shadow; QMargins m_shadowMargins; QColor m_borderColor; }; #endif kylin-video/src/utils.cpp0000644000175000017500000002220113517016402014357 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Kylin Ltd. * * Authors: * Kobe Lee xiangli@ubuntukylin.com/kobe24_lixiang@126.com * * 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; version 3. * * 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 "utils.h" #include "smplayer/extensions.h" #include #include #include #include #include #include Utils::PlayerId Utils::player(const QString & player_bin) { PlayerId p; if (player_bin.toLower().contains("mplayer")) { p = MPLAYER; } else { p = MPV; } return p; } void Utils::setWidgetOpacity(QWidget *w, bool transparent, const float &opacity) { if (transparent) { w->setAttribute(Qt::WA_TranslucentBackground); w->setWindowFlags(w->windowFlags() | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint); QGraphicsOpacityEffect* opacityEffect = new QGraphicsOpacityEffect; w->setGraphicsEffect(opacityEffect); opacityEffect->setOpacity(opacity); } else { w->setAttribute(Qt::WA_TranslucentBackground, false); w->setWindowFlags(w->windowFlags() & ~Qt::FramelessWindowHint); } } QString Utils::formatTime(int secs) { bool negative = (secs < 0); secs = qAbs(secs); int t = secs; int hours = (int) t / 3600; t -= hours*3600; int minutes = (int) t / 60; t -= minutes*60; int seconds = t; return QString("%1%2:%3:%4").arg(negative ? "-" : "").arg(hours, 2, 10, QChar('0')).arg(minutes, 2, 10, QChar('0')).arg(seconds, 2, 10, QChar('0')); } QString Utils::timeForJumps(int secs) { int minutes = (int) secs / 60; int seconds = secs % 60; if (minutes == 0) { return QObject::tr("%n second(s)", "", seconds); } else { if (seconds == 0) return QObject::tr("%n minute(s)", "", minutes); else { QString m = QObject::tr("%n minute(s)", "", minutes); QString s = QObject::tr("%n second(s)", "", seconds); return QObject::tr("%1 and %2").arg(m).arg(s); } } } bool Utils::directoryContainsDVD(QString directory) { QDir dir(directory); QStringList l = dir.entryList(); bool valid = false; for (int n=0; n < l.count(); n++) { //qDebug(" * entry %d: '%s'", n, l[n].toUtf8().data()); if (l[n].toLower() == "video_ts") valid = true; } return valid; } QStringList Utils::searchForConsecutiveFiles(const QString & initial_file) { qDebug("Utils::searchForConsecutiveFiles: initial_file: '%s'", initial_file.toUtf8().constData()); QStringList files_to_add; QStringList matching_files; QFileInfo fi(initial_file); QString basename = fi.completeBaseName(); QString extension = fi.suffix(); QString path = fi.absolutePath(); QDir dir(path); dir.setFilter(QDir::Files); dir.setSorting(QDir::Name); QRegExp rx("(\\d+)"); int digits; int current_number; int pos = 0; QString next_name; bool next_found = false; qDebug("Utils::searchForConsecutiveFiles: trying to find consecutive files"); while ( ( pos = rx.indexIn(basename, pos) ) != -1 ) { qDebug("Utils::searchForConsecutiveFiles: captured: %s",rx.cap(1).toUtf8().constData()); digits = rx.cap(1).length(); current_number = rx.cap(1).toInt() + 1; next_name = basename.left(pos) + QString("%1").arg(current_number, digits, 10, QLatin1Char('0')); next_name.replace(QRegExp("([\\[\\]?*])"), "[\\1]"); next_name += "*." + extension; qDebug("Utils::searchForConsecutiveFiles: next name = %s",next_name.toUtf8().constData()); matching_files = dir.entryList((QStringList)next_name); if ( !matching_files.isEmpty() ) { next_found = true; break; } qDebug("Utils::searchForConsecutiveFiles: pos = %d",pos); pos += digits; } if (next_found) { while (!matching_files.isEmpty()) { QString filename = path + "/" + matching_files[0]; files_to_add << filename; current_number++; next_name = basename.left(pos) + QString("%1").arg(current_number, digits, 10, QLatin1Char('0')); next_name.replace(QRegExp("([\\[\\]?*])"), "[\\1]"); next_name += "*." + extension; matching_files = dir.entryList((QStringList)next_name); } } return files_to_add; } QStringList Utils::filesInDirectory(const QString & initial_file, const QStringList & filter) { qDebug("Utils::filesInDirectory: initial_file: %s", initial_file.toUtf8().constData()); //qDebug() << "Utils::filesInDirectory: filter:" << filter; QFileInfo fi(initial_file); QString current_file = fi.fileName(); QString path = fi.absolutePath(); QDir d(path); QStringList all_files = d.entryList(filter, QDir::Files); QStringList r; for (int n = 0; n < all_files.count(); n++) { //if (all_files[n] != current_file) { QString s = path +"/" + all_files[n]; r << s; //} } return r; } QStringList Utils::filesForPlaylist(const QString & initial_file, Preferences::AutoAddToPlaylistFilter filter) { QStringList res; if (filter == Preferences::ConsecutiveFiles) { res = searchForConsecutiveFiles(initial_file); } else { Extensions e; QStringList exts; switch (filter) { case Preferences::VideoFiles: exts = e.video().forDirFilter(); break; case Preferences::AudioFiles: exts = e.audio().forDirFilter(); break; case Preferences::MultimediaFiles: exts = e.multimedia().forDirFilter(); break; default: ; } if (!exts.isEmpty()) res = Utils::filesInDirectory(initial_file, exts); } return res; } QString Utils::findExecutable(const QString & name) { QByteArray env = qgetenv("PATH"); QStringList search_paths = QString::fromLocal8Bit(env.constData()).split(':', QString::SkipEmptyParts); for (int n = 0; n < search_paths.count(); n++) { QString candidate = search_paths[n] + "/" + name; //qDebug("Utils::findExecutable: candidate: %s", candidate.toUtf8().constData()); QFileInfo info(candidate); if (info.isFile() && info.isExecutable()) { //qDebug("Utils::findExecutable: executable found: %s", candidate.toUtf8().constData()); return candidate; } } return QString::null; } void Utils::shutdown() { bool 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) { qDebug() << "Shutdown::shutdown: error:" << response.errorName() << ":" << response.errorMessage(); } else { works = true; } if (!works) { QDBusInterface kdeSessionManager("org.kde.ksmserver", "/KSMServer", "org.kde.KSMServerInterface", QDBusConnection::sessionBus()); response = kdeSessionManager.call("logout", 0, 2, 2); if (response.type() == QDBusMessage::ErrorMessage) { qDebug() << "Shutdown::shutdown: error:" << response.errorName() << ":" << response.errorMessage(); } else { works = true; } } if (!works) { 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) { qDebug() << "Shutdown::shutdown: error:" << response.errorName() << ":" << response.errorMessage(); } else { works = true; } } if (!works) { QDBusInterface powermanagement("org.freedesktop.ConsoleKit", "/org/freedesktop/ConsoleKit/Manager", "org.freedesktop.ConsoleKit.Manager", QDBusConnection::systemBus()); response = powermanagement.call("Stop"); if (response.type() == QDBusMessage::ErrorMessage) { qDebug() << "Shutdown::shutdown: error:" << response.errorName() << ":" << response.errorMessage(); } else { works = true; } } if (!works) { qDebug("Shutdown::shutdown: shutdown failed"); QProcess::startDetached("xmessage", QStringList() << "-buttons" << "Accept:0" << "-center" << "This is a message from Kylin Video\n" "The computer should shut down now.\n" "However shutdown failed."); } } kylin-video/src/filterhandler.h0000644000175000017500000000221713517016402015514 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 _FILTERHANDLER_H_ #define _FILTERHANDLER_H_ #include class MainWindow; class FilterHandler : public QObject { Q_OBJECT public: FilterHandler(MainWindow &gui, QObject &obj); ~FilterHandler(); signals: void mouseMoved(); protected: bool eventFilter(QObject *obj, QEvent *event); private: MainWindow *m_mainWindow = nullptr; }; #endif // _FILTERHANDLER_H_ kylin-video/src/systembutton.cpp0000644000175000017500000000363613517016402016012 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "systembutton.h" #include SystemButton::SystemButton(QWidget *parent) : QPushButton(parent) { this->setMouseTracking(false); status = NORMAL; mouse_press = false; } void SystemButton::loadPixmap(QString pic_name) { pixmap = QPixmap(pic_name); btn_width = pixmap.width()/3; btn_height = pixmap.height(); this->setFixedSize(btn_width, btn_height); } void SystemButton::enterEvent(QEvent *) { status = ENTER; update(); } void SystemButton::mousePressEvent(QMouseEvent *event) { if(event->button() == Qt::LeftButton) { mouse_press = true; status = PRESS; update(); } } void SystemButton::mouseReleaseEvent(QMouseEvent *event) { if(mouse_press && this->rect().contains(event->pos())) { mouse_press = false; status = ENTER; update(); emit clicked(); } } void SystemButton::leaveEvent(QEvent *) { status = NORMAL; update(); } void SystemButton::paintEvent(QPaintEvent *) { QPainter painter; painter.begin(this); painter.drawPixmap(this->rect(), pixmap.copy(btn_width * status, 0, btn_width, btn_height)); painter.end(); } kylin-video/src/titlebutton.h0000644000175000017500000000247213517016402015251 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 TITLEBUTTON_H #define TITLEBUTTON_H #include class TitleButton : public QWidget { Q_OBJECT public: explicit TitleButton(int id, bool bigFont, const QString &title, QWidget *parent = 0); int id() const; void setId(const int &id); bool isActived() const; void setActived(bool isActived); signals: void clicked(int id); protected: void mousePressEvent(QMouseEvent *e); void paintEvent(QPaintEvent *e); private: bool m_bigFont; bool m_isActived; int m_id; QString m_title; }; #endif // TITLEBUTTON_H kylin-video/src/bottomwidget.h0000644000175000017500000001045213637124037015410 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 BOTTOMWIDGET_H #define BOTTOMWIDGET_H #include "utils.h" #include #include #include #include #include #include #include #include #include #include #include #include #include class VideoWindow; class QPropertyAnimation; class TimeSlider; class SoundVolume; class MyAction; class BottomWidget : public QWidget { Q_OBJECT public: explicit BottomWidget(QWidget *parent = 0); ~BottomWidget(); void updateWidgetQssProperty(QWidget *w, const char *name, const QVariant &value); QString getActiveStatus(); void onShowControlWidget(); void setPreviewData(bool preview); void savePreviewImageName(int time, QString filepath); // void showWidget(); signals: void requestVolumeChanged(int volume); void togglePlaylist(); void toggleFullScreen(); void toggleStop(); void togglePrev(); void togglePlayPause(); void toggleNext(); void toggleMute(); void mouseMoving(Qt::MouseButton botton); void start_open_file(); void valueChanged(int); void posChanged(int); void draggingPos(int); void delayedDraggingPos(int); void wheelUp(); void wheelDown(); void mouseMovedDiff(QPoint); // void requestShowOrHideEscWidget(bool b); void resize_bottom_widget_height(bool b); void requestSavePreviewImage(int time, QPoint pos); void requestHideTip(); void mouseEnter(); void mouseLeave(); void requestTemporaryShow(); public slots: void updatePlaylistBtnQssProperty(bool b); void onMusicPlayed(); void onMusicPause(); void onMusicStoped(); void onVolumeChanged(int volume); void onMutedChanged(bool muted, int volumn); void onFullScreen(); void onUnFullScreen(); void displayTime(QString cur_time, QString all_time); void onSetActionsEnabled(bool b); void setPlayOrPauseEnabled(bool b); //progress void setPos(int); int ppos(); void setDuration(double); double duration() { return m_totalTime; }; void setDragDelay(int); int dragDelay(); void onProgressActiveStatus(bool b); // void spreadAniFinished(); // void gatherAniFinished(); void updateLabelCountNumber(int count); protected: virtual bool eventFilter(QObject * obj, QEvent * event); virtual void resizeEvent(QResizeEvent *event); virtual void leaveEvent(QEvent *event); virtual void enterEvent(QEvent *event); virtual void paintEvent(QPaintEvent *event); private slots: // void checkUnderMouse(); // void showSpreadAnimated(); // void showGatherAnimated(); private: // QPropertyAnimation *m_spreadAnimation = nullptr; // QPropertyAnimation *m_gatherAnimation = nullptr; QLabel *m_playtimeLabel = nullptr; QLabel *m_totaltimeLabel = nullptr; QPushButton *m_btnStop = nullptr; QPushButton *m_btnPrev = nullptr; QPushButton *m_btnPlayPause = nullptr; QPushButton *m_btnNext = nullptr; QPushButton *m_btnSound = nullptr; QPushButton *m_btnFullScreen = nullptr; QPushButton *m_btnPlayList = nullptr; QLabel *m_listCountLabel = nullptr; TimeSlider *m_timeProgress = nullptr; QWidget *m_controlWidget = nullptr; SoundVolume *m_volSlider = nullptr; QFrame *m_metaWidget = nullptr; QFrame *m_ctlWidget = nullptr; QWidget *m_actWidget = nullptr; double m_totalTime; int m_dragDelay; DragState m_dragState; QPoint m_startDrag; QVBoxLayout *vboxlayout = nullptr; }; #endif // BOTTOMWIDGET_H kylin-video/src/bottomwidget.cpp0000644000175000017500000004477713637124061015761 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "bottomwidget.h" #include "soundvolume.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../smplayer/timeslider.h" #include "../smplayer/colorutils.h" #include "../smplayer/myaction.h" #include "../smplayer/global.h" #include "../smplayer/preferences.h" using namespace Global; static const QString playStatusPlaying = "playing"; static const QString playStatusPause = "pause"; static const QString playStatusStop = "stop"; static const QString playStatusPlayList = "close"; static const char *property_FullScreen = "fullscreen"; static const char *property_PlayStatus = "playstatus"; static const char *property_PlayListStatus = "playliststatus"; BottomWidget::BottomWidget(QWidget *parent) : QWidget(parent, Qt::SubWindow) // , m_spreadAnimation(0) // , m_gatherAnimation(0) , m_dragState(NOT_DRAGGING) , m_startDrag(QPoint(0,0)) , m_dragDelay(200) { this->setMouseTracking(true); this->setAutoFillBackground(true); this->setFocusPolicy(Qt::StrongFocus); this->setAttribute(Qt::WA_TranslucentBackground, true);//窗体标题栏不透明,背景透明 this->setWindowFlags(windowFlags() | Qt::SubWindow | Qt::WindowStaysOnTopHint); this->installEventFilter(this); m_controlWidget = new QWidget(this); m_controlWidget->setFixedHeight(61); m_timeProgress = new TimeSlider(this); m_timeProgress->setMouseTracking(true); m_timeProgress->setDragDelay(100);//pref->time_slider_drag_delay connect(m_timeProgress, SIGNAL(posChanged(int)), this, SIGNAL(posChanged(int))); connect(m_timeProgress, SIGNAL(draggingPos(int)), this, SIGNAL(draggingPos(int))); connect(m_timeProgress, SIGNAL(delayedDraggingPos(int)), this, SIGNAL(delayedDraggingPos(int))); connect(m_timeProgress, SIGNAL(wheelUp()), this, SIGNAL(wheelUp())); connect(m_timeProgress, SIGNAL(wheelDown()), this, SIGNAL(wheelDown())); connect(m_timeProgress, SIGNAL(requestHideTip()), this, SIGNAL(requestHideTip())); connect(m_timeProgress, SIGNAL(requestSavePreviewImage(int, QPoint)), this, SIGNAL(requestSavePreviewImage(int, QPoint))); m_timeProgress->setObjectName("processProgress"); m_timeProgress->setProperty("status", ""); connect(m_timeProgress, SIGNAL(active_status(bool)), this, SLOT(onProgressActiveStatus(bool))); m_timeProgress->setFixedHeight(24); m_timeProgress->move(0,0); m_playtimeLabel = new QLabel; m_playtimeLabel->setText("00:00:00"); m_playtimeLabel->setFrameShape(QFrame::NoFrame); ColorUtils::setBackgroundColor(m_playtimeLabel, QColor(0,0,0) ); ColorUtils::setForegroundColor(m_playtimeLabel, QColor(255,255,255) ); m_playtimeLabel->setStyleSheet("QLabel{font-size:12px;color:#ffffff;}"); m_playtimeLabel->adjustSize(); m_totaltimeLabel = new QLabel; m_totaltimeLabel->setText(" / 00:00:00"); m_totaltimeLabel->setFrameShape(QFrame::NoFrame); ColorUtils::setBackgroundColor( m_totaltimeLabel, QColor(0,0,0) ); ColorUtils::setForegroundColor( m_totaltimeLabel, QColor(255,255,255) ); m_totaltimeLabel->setStyleSheet("QLabel{font-size:12px;color:#808080;}"); m_totaltimeLabel->adjustSize(); m_btnStop = new QPushButton; m_btnStop->setObjectName("StopBtn"); m_btnStop->setFixedSize(24, 24); m_btnPrev = new QPushButton; m_btnPrev->setObjectName("PrevBtn"); m_btnPrev->setFixedSize(24, 24); m_btnPlayPause = new QPushButton; // m_btnPlayPause->setShortcut(Qt::Key_Space); m_btnPlayPause->setObjectName("PlayBtn"); m_btnPlayPause->setFixedSize(61, 61); m_btnNext = new QPushButton; m_btnNext->setObjectName("NextBtn"); m_btnNext->setFixedSize(24, 24); m_btnSound = new QPushButton; m_btnSound->setObjectName("SoundBtn"); m_btnSound->setFixedSize(24, 24); m_btnSound->setProperty("volume", "mid"); m_btnFullScreen = new QPushButton; // m_btnFullScreen->setShortcut(QKeySequence("Ctrl+Return")); m_btnFullScreen->setObjectName("FullScreenBtn"); m_btnFullScreen->setFixedSize(24, 24); m_btnPlayList = new QPushButton; // m_btnPlayList->setShortcut(QKeySequence("F3")); m_btnPlayList->setObjectName("PlayListBtn"); m_btnPlayList->setFixedSize(24, 24); m_listCountLabel = new QLabel; ColorUtils::setBackgroundColor(m_listCountLabel, QColor("#141414") ); m_listCountLabel->setStyleSheet("QLabel{font-size:12px;color:#ffffff;}"); this->m_listCountLabel->setText("0"); m_volSlider = new SoundVolume(this); m_volSlider->setObjectName("VolumeSlider"); connect(this, SIGNAL(valueChanged(int)), m_volSlider, SLOT(setValue(int))); connect(m_btnStop, SIGNAL(released()), this, SIGNAL(toggleStop())); connect(m_btnPrev, SIGNAL(released()), this, SIGNAL(togglePrev())); connect(m_btnPlayPause, SIGNAL(released()), this, SIGNAL(togglePlayPause())); connect(m_btnNext, SIGNAL(released()), this, SIGNAL(toggleNext())); connect(m_btnSound, SIGNAL(pressed()), this, SIGNAL(toggleMute())); connect(m_btnFullScreen, SIGNAL(pressed()), this, SIGNAL(toggleFullScreen())); connect(m_btnPlayList, SIGNAL(released()), this, SIGNAL(togglePlaylist())); connect(this, SIGNAL(mouseMoving(Qt::MouseButton)), m_timeProgress, SLOT(hideTip())); connect(m_volSlider, &SoundVolume::volumeChanged, this, [=] (int vol) { this->onVolumeChanged(vol); emit this->requestVolumeChanged(vol); }); QHBoxLayout *time_layout = new QHBoxLayout(); time_layout->setMargin(0); time_layout->setSpacing(2); time_layout->addWidget(m_playtimeLabel, 0, Qt::AlignLeft | Qt::AlignVCenter); time_layout->addWidget(m_totaltimeLabel, 0, Qt::AlignLeft | Qt::AlignVCenter); m_metaWidget = new QFrame(this); m_metaWidget->setFixedHeight(61); QHBoxLayout *metaLayout = new QHBoxLayout(m_metaWidget); metaLayout->setMargin(0); metaLayout->setSpacing(10); metaLayout->addWidget(m_btnPlayPause, 0, Qt::AlignVCenter); metaLayout->addLayout(time_layout); m_ctlWidget = new QFrame(this); m_ctlWidget->setFixedHeight(61); QHBoxLayout *ctlLayout = new QHBoxLayout(m_ctlWidget); ctlLayout->setMargin(0); ctlLayout->setSpacing(30); ctlLayout->addWidget(m_btnPrev, 0, Qt::AlignCenter); ctlLayout->addWidget(m_btnStop, 0, Qt::AlignCenter); ctlLayout->addWidget(m_btnNext, 0, Qt::AlignCenter); m_ctlWidget->adjustSize(); QHBoxLayout *volume_layout = new QHBoxLayout(); volume_layout->setMargin(0); volume_layout->setSpacing(2); volume_layout->addWidget(m_btnSound, 0, Qt::AlignRight | Qt::AlignVCenter); volume_layout->addWidget(m_volSlider, 0, Qt::AlignRight | Qt::AlignVCenter); QHBoxLayout *list_layout = new QHBoxLayout(); list_layout->setMargin(0); list_layout->setSpacing(2); list_layout->addWidget(m_btnPlayList, 0, Qt::AlignRight | Qt::AlignVCenter); list_layout->addWidget(m_listCountLabel, 0, Qt::AlignRight | Qt::AlignVCenter); m_actWidget = new QWidget(this); m_actWidget->setFixedHeight(61); QHBoxLayout *actLayout = new QHBoxLayout(m_actWidget); actLayout->setMargin(0); actLayout->setSpacing(20); actLayout->addLayout(volume_layout); actLayout->addWidget(m_btnFullScreen, 0, Qt::AlignRight | Qt::AlignVCenter); actLayout->addLayout(list_layout); QSizePolicy sp(QSizePolicy::Preferred, QSizePolicy::Preferred); sp.setHorizontalStretch(33); m_metaWidget->setSizePolicy(sp); m_actWidget->setSizePolicy(sp); QHBoxLayout *layout = new QHBoxLayout(); layout->setContentsMargins(10, 0, 20, 0); layout->setSpacing(20); layout->addWidget(m_metaWidget, 0, Qt::AlignLeft/* | Qt::AlignVCenter*/); layout->addStretch(); layout->addWidget(m_ctlWidget, 0, Qt::AlignHCenter/*Qt::AlignCenter*/); layout->addStretch(); layout->addWidget(m_actWidget, 0, Qt::AlignRight/* | Qt::AlignVCenter*/); m_controlWidget->setLayout(layout); vboxlayout = new QVBoxLayout(this); vboxlayout->setSpacing(0); vboxlayout->setContentsMargins(0, 18, 0, 2); vboxlayout->addWidget(m_controlWidget); m_btnStop->setFocusPolicy(Qt::NoFocus); m_btnPrev->setFocusPolicy(Qt::NoFocus); m_btnPlayPause->setFocusPolicy(Qt::NoFocus); m_btnNext->setFocusPolicy(Qt::NoFocus); m_btnFullScreen->setFocusPolicy(Qt::NoFocus); m_btnSound->setFocusPolicy(Qt::NoFocus); m_volSlider->setFocusPolicy(Qt::NoFocus); m_btnPlayList->setFocusPolicy(Qt::NoFocus); m_btnStop->setToolTip(tr("Stop")); m_btnPrev->setToolTip(tr("Prev")); m_btnPlayPause->setToolTip(tr("Play / Pause")); m_btnNext->setToolTip(tr("Next")); m_btnSound->setToolTip(tr("Mute")); m_btnPlayList->setToolTip(tr("Play List")); this->updateWidgetQssProperty(m_btnPlayPause, property_PlayStatus, playStatusPause); this->updateWidgetQssProperty(this, property_PlayStatus, playStatusPause); Utils::setWidgetOpacity(this, true, 0.8); } BottomWidget::~BottomWidget() { // if (m_spreadAnimation) delete m_spreadAnimation; // if (m_gatherAnimation) delete m_gatherAnimation; if (m_metaWidget) delete m_metaWidget; if (m_ctlWidget) delete m_ctlWidget; if (m_actWidget) delete m_actWidget; if (m_controlWidget) delete m_controlWidget; } //void BottomWidget::showWidget() //{ // showSpreadAnimated(); //} void BottomWidget::setPreviewData(bool preview) { if (m_timeProgress) { m_timeProgress->set_preview_flag(preview); } } void BottomWidget::savePreviewImageName(int time, QString filepath) { if (m_timeProgress) { m_timeProgress->show_save_preview_image(time, filepath); } } QString BottomWidget::getActiveStatus() { QString status = m_timeProgress->property("active").toString(); return status; } void BottomWidget::updateLabelCountNumber(int count) { this->m_listCountLabel->setText(QString::number(count)); } void BottomWidget::onProgressActiveStatus(bool b) { if (b) { this->updateWidgetQssProperty(m_timeProgress, "status", "active"); } else { this->updateWidgetQssProperty(m_timeProgress, "status", ""); } } void BottomWidget::setPos(int v) { bool was_blocked= m_timeProgress->blockSignals(true); m_timeProgress->setPos(v); m_timeProgress->blockSignals(was_blocked); } int BottomWidget::ppos() { return m_timeProgress->pos(); } void BottomWidget::setDuration(double t) { m_totalTime = t; m_timeProgress->setDuration(t); } void BottomWidget::setDragDelay(int d) { m_dragDelay = d; m_timeProgress->setDragDelay(m_dragDelay); } int BottomWidget::dragDelay() { return m_dragDelay; } void BottomWidget::onSetActionsEnabled(bool b) { m_btnPrev->setEnabled(b); m_btnPlayPause->setEnabled(b); m_btnNext->setEnabled(b); m_btnSound->setEnabled(b); m_btnStop->setEnabled(b); m_timeProgress->setEnabled(b); } void BottomWidget::setPlayOrPauseEnabled(bool b) { m_btnPlayPause->setEnabled(b); } void BottomWidget::displayTime(QString cur_time, QString all_time) { m_playtimeLabel->setText(cur_time); m_totaltimeLabel->setText(all_time); } void BottomWidget::updatePlaylistBtnQssProperty(bool b) { if (b) { this->updateWidgetQssProperty(m_btnPlayList, property_PlayListStatus, playStatusPlayList); } else { this->updateWidgetQssProperty(m_btnPlayList, property_PlayListStatus, ""); } } void BottomWidget::onMusicPlayed() { this->updateWidgetQssProperty(m_btnPlayPause, property_PlayStatus, playStatusPlaying); this->updateWidgetQssProperty(this, property_PlayStatus, playStatusPlaying); } void BottomWidget::onMusicPause() { this->updateWidgetQssProperty(m_btnPlayPause, property_PlayStatus, playStatusPause); this->updateWidgetQssProperty(this, property_PlayStatus, playStatusPause); } void BottomWidget::onMusicStoped() { this->updateWidgetQssProperty(m_btnPlayPause, property_PlayStatus, playStatusStop); this->updateWidgetQssProperty(this, property_PlayStatus, playStatusStop); } void BottomWidget::onFullScreen() { this->updateWidgetQssProperty(m_btnFullScreen, property_FullScreen, true); } void BottomWidget::onUnFullScreen() { this->updateWidgetQssProperty(m_btnFullScreen, property_FullScreen, false); } void BottomWidget::onVolumeChanged(int volume) { QString status = "mid"; if (volume > 77) { status = "high"; } else if (volume > 33) { status = "mid"; } else if (volume > 0) { status = "low"; } else { status = "mute"; } this->updateWidgetQssProperty(m_btnSound, "volume", status); this->m_volSlider->onVolumeChanged(volume); } void BottomWidget::onMutedChanged(bool muted, int volumn) { if (muted) { this->updateWidgetQssProperty(m_btnSound, "volume", "mute"); this->m_volSlider->onVolumeChanged(0); } else { this->onVolumeChanged(volumn); } } void BottomWidget::updateWidgetQssProperty(QWidget *w, const char *name, const QVariant &value) { w->setProperty(name, value); this->style()->unpolish(w); this->style()->polish(w); w->update(); } //void BottomWidget::checkUnderMouse() //{ // if ((m_ctlWidget->isVisible()) && (!underMouse())) { // this->showGatherAnimated(); // //tell mainwindow to hide escwidget // emit this->requestShowOrHideEscWidget(false); // } //} //void BottomWidget::spreadAniFinished() //{ //} //void BottomWidget::gatherAniFinished() //{ // m_controlWidget->hide(); //} void BottomWidget::onShowControlWidget() { m_controlWidget->show(); } //void BottomWidget::showSpreadAnimated() //{ // if (!m_spreadAnimation) { // m_spreadAnimation = new QPropertyAnimation(this, "pos"); // connect(m_spreadAnimation, SIGNAL(finished()), this, SLOT(spreadAniFinished())); // } // QPoint initial_position = QPoint(pos().x(), parentWidget()->size().height()); // QPoint final_position = QPoint(0, parentWidget()->size().height() - this->height()); // move(initial_position); // QWidget::show(); // m_controlWidget->show(); // m_spreadAnimation->setDuration(300); // m_spreadAnimation->setStartValue(initial_position); // m_spreadAnimation->setEndValue(final_position); // m_spreadAnimation->start(); // qDebug() << "BBBBBBBBBBBBBBBBBBB"; // //tell mainwindow to show escwidget // emit this->requestShowOrHideEscWidget(true); //} //void BottomWidget::showGatherAnimated() //{ // if (!m_gatherAnimation) { // m_gatherAnimation = new QPropertyAnimation(this, "pos"); // connect(m_gatherAnimation, SIGNAL(finished()), this, SLOT(gatherAniFinished())); // } // QPoint initial_position = QPoint(0, parentWidget()->size().height() - this->height()); // QPoint final_position = QPoint(pos().x(), parentWidget()->size().height() - 4);//kobe 0616:给最底下的进度条留下空间 // move(initial_position); // m_gatherAnimation->setDuration(300); // m_gatherAnimation->setStartValue(initial_position); // m_gatherAnimation->setEndValue(final_position); // m_gatherAnimation->start(); //} void BottomWidget::resizeEvent(QResizeEvent *event) { QWidget::resizeEvent(event); m_timeProgress->resize(this->width(), 24); } void BottomWidget::enterEvent(QEvent *event) { QWidget::enterEvent(event); emit mouseEnter(); } void BottomWidget::leaveEvent(QEvent *event) { QWidget::leaveEvent(event); emit mouseLeave(); } void BottomWidget::paintEvent(QPaintEvent *event) { Q_UNUSED(event); // QStyleOption opt; // opt.init(this); // QPainter p(this); // style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); QPainter p(this); p.setCompositionMode(QPainter::CompositionMode_Clear); p.fillRect(rect(), Qt::SolidPattern);//p.fillRect(0, 0, this->width(), this->height(), Qt::SolidPattern); } bool BottomWidget::eventFilter(QObject * obj, QEvent * event) { QEvent::Type type = event->type(); if (type != QEvent::MouseButtonPress && type != QEvent::MouseButtonRelease && type != QEvent::MouseMove) return false; QMouseEvent *mouseEvent = dynamic_cast(event); if (!mouseEvent) return false; if (mouseEvent->modifiers() != Qt::NoModifier) { m_dragState = NOT_DRAGGING; return false; } if (event->type() == QEvent::MouseMove) { if (!isVisible()) { emit this->requestTemporaryShow(); } else if (!m_ctlWidget->isVisible()) { emit this->requestTemporaryShow(); } } if (type == QEvent::MouseButtonPress) { if (mouseEvent->button() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } m_dragState = START_DRAGGING; m_startDrag = mouseEvent->globalPos(); // Don't filter, so others can have a look at it too return false; } if (type == QEvent::MouseButtonRelease) { if (m_dragState != DRAGGING || mouseEvent->button() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } // Stop dragging and eat event m_dragState = NOT_DRAGGING; event->accept(); return true; } // type == QEvent::MouseMove if (m_dragState == NOT_DRAGGING) return false; // buttons() note the s if (mouseEvent->buttons() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } QPoint pos = mouseEvent->globalPos(); QPoint diff = pos - m_startDrag; if (m_dragState == START_DRAGGING) { // Don't start dragging before moving at least DRAG_THRESHOLD pixels if (abs(diff.x()) < 4 && abs(diff.y()) < 4) return false; m_dragState = DRAGGING; } emit mouseMovedDiff(diff); m_startDrag = pos; event->accept(); return true; } kylin-video/src/esctip.h0000644000175000017500000000321213517016402014154 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 _ESCTIP_H_ #define _ESCTIP_H_ #include class QLabel; class EscTip : public QFrame { Q_OBJECT Q_PROPERTY(int radius READ radius WRITE setRadius) Q_PROPERTY(QBrush background READ background WRITE setBackground) Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor) public: explicit EscTip(QWidget *parent = 0); ~EscTip(); void setBackgroundImage(const QPixmap &srcPixmap); int radius() const; QColor borderColor() const; QBrush background() const; public slots: void setBackground(QBrush background); void setRadius(int radius); void setBorderColor(QColor borderColor); void aniFinished(); protected: virtual void paintEvent(QPaintEvent *); private: QLabel *m_textLabel = nullptr; QBrush m_background; int m_radius; int m_shadow; QMargins m_shadowMargins; QColor m_borderColor; }; #endif kylin-video/src/bottomcontroller.h0000644000175000017500000000227113517016402016301 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 _BOTTOMCONTROLLER_H_ #define _BOTTOMCONTROLLER_H_ #include class QTimer; class BottomController : public QObject { Q_OBJECT public: BottomController(QObject *parent); ~BottomController(); public slots: void temporaryShow(); void permanentShow(); void onTimeout(); signals: void requestShow(); void requestHide(); private: QTimer *m_timer = nullptr; }; #endif // _BOTTOMCONTROLLER_H_ kylin-video/src/coverwidget.cpp0000644000175000017500000000170413517016402015546 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "coverwidget.h" #include #include CoverWidget::CoverWidget(QWidget *parent) : QFrame(parent) { } CoverWidget::~CoverWidget() { } void CoverWidget::updateUI() { } kylin-video/src/kylinvideo.cpp0000644000175000017500000001776013625147453015425 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "kylinvideo.h" #include "myapplication.h" #include "infoworker.h" //#include "controllerworker.h" #include "../smplayer/global.h" #include "../smplayer/paths.h" #include "../smplayer/translator.h" #include "../smplayer/version.h" #include "../smplayer/cleanconfig.h" #include #include #include #include #include using namespace Global; MainWindow * KylinVideo::main_window = 0; KylinVideo::KylinVideo(const QString &arch, const QString &snap, /*ControllerWorker *controller, */QObject *parent) : QObject(parent) // , m_controllerWorker(controller) , m_moveGui(false) , m_resizeGui(false) , m_arch(arch) , m_snap(snap) { Paths::setAppPath(qApp->applicationDirPath());//snap: /snap/kylin-video/x1/usr/bin deb:/usr/bin global_init(m_arch); translator->load(this->m_snap); m_infoWorker = new InfoWorker; m_thread = new QThread; m_infoWorker->moveToThread(m_thread); connect(m_thread, &QThread::started, this, [=] () { // 托盘启动时显示主界面与否,与配置文件~/.config/kylin-video/kylin-video.ini的变量mainwindow_visible和文件列表变量files_to_play有关,可修改构造函数里面的mainwindow_visible=false让软件第一次使用托盘时显示主界面 gui()->show(); main_window->bindThreadWorker(this->m_infoWorker); if (!m_filesToPlay.isEmpty()) { if (!m_subtitleFile.isEmpty()) gui()->setInitialSubtitle(m_subtitleFile); if (!m_mediaTitle.isEmpty()) gui()->getCore()->addForcedTitle(m_filesToPlay[0], m_mediaTitle); gui()->openFiles(m_filesToPlay); } }); m_thread->start(); showInfo(); } KylinVideo::~KylinVideo() { if (m_infoWorker) { m_infoWorker->deleteLater(); } if (m_thread) { m_thread->quit(); m_thread->wait(2000); } if (main_window != 0) { deleteGUI(); } global_end(); } MainWindow * KylinVideo::gui() { if (main_window == 0) { QDir::setCurrent(Paths::appPath()); main_window = createGUI(this->m_arch, this->m_snap); if (m_moveGui) { main_window->move(m_guiPosition); } if (m_resizeGui) { main_window->resize(m_guiSize); } } return main_window; } MainWindow * KylinVideo::createGUI(QString arch, QString snap) { MainWindow * gui = 0; gui = new MainWindow(arch, snap, /*m_controllerWorker, */0); connect(gui, &MainWindow::requestGuiChanged, this, [=] () { deleteGUI(); main_window = createGUI(this->m_arch, this->m_snap); main_window->show(); }); #if SINGLE_INSTANCE MyApplication * app = MyApplication::instance(); connect(app, SIGNAL(messageReceived(const QString&)), gui, SLOT(handleMessageFromOtherInstances(const QString&))); app->setActivationWindow(gui); #endif return gui; } void KylinVideo::deleteGUI() { delete main_window; main_window = 0; } KylinVideo::ExitCode KylinVideo::processArgs(QStringList args) { QString action; // Action to be passed to running instance bool show_help = false; bool add_to_playlist = false; if (args.contains("-delete-config")) { CleanConfig::clean(Paths::configPath()); return NoError; } for (int n = 1; n < args.count(); n++) { QString argument = args[n]; if (argument == "-send-action") { if (n+1 < args.count()) { n++; action = args[n]; } else { printf("Error: expected parameter for -send-action\r\n"); return ErrorArgument; } } else if (argument == "-sub") { if (n+1 < args.count()) { n++; QString file = args[n]; if (QFile::exists(file)) { m_subtitleFile = QFileInfo(file).absoluteFilePath(); } else { printf("Error: file '%s' doesn't exists\r\n", file.toUtf8().constData()); } } else { printf("Error: expected parameter for -sub\r\n"); return ErrorArgument; } } else if (argument == "-media-title") { if (n+1 < args.count()) { n++; if (m_mediaTitle.isEmpty()) m_mediaTitle = args[n]; } } else if (argument == "-pos") { if (n+2 < args.count()) { bool ok_x, ok_y; n++; m_guiPosition.setX( args[n].toInt(&ok_x) ); n++; m_guiPosition.setY( args[n].toInt(&ok_y) ); if (ok_x && ok_y) m_moveGui = true; } else { printf("Error: expected parameter for -pos\r\n"); return ErrorArgument; } } else if (argument == "-size") { if (n+2 < args.count()) { bool ok_width, ok_height; n++; m_guiSize.setWidth( args[n].toInt(&ok_width) ); n++; m_guiSize.setHeight( args[n].toInt(&ok_height) ); if (ok_width && ok_height) m_resizeGui = true; } else { printf("Error: expected parameter for -resize\r\n"); return ErrorArgument; } } else if ((argument == "--help") || (argument == "-help") || (argument == "-h") || (argument == "-?") ) { show_help = true; } else if (argument == "-add-to-playlist") { add_to_playlist = true; } else if (argument == "-ontop") { pref->stay_on_top = Preferences::AlwaysOnTop; } else if (argument == "-no-ontop") { pref->stay_on_top = Preferences::NeverOnTop; } else { // File #if QT_VERSION >= 0x040600 QUrl fUrl = QUrl::fromUserInput(argument); if (fUrl.isValid() && fUrl.scheme().toLower() == "file") { argument = fUrl.toLocalFile(); } #endif if (QFile::exists( argument )) { argument = QFileInfo(argument).absoluteFilePath(); } m_filesToPlay.append( argument ); } } for (int n=0; n < m_filesToPlay.count(); n++) { qDebug("KylinVideo::processArgs: m_filesToPlay[%d]: '%s'", n, m_filesToPlay[n].toUtf8().data()); } // Single instance MyApplication * a = MyApplication::instance(); if (a->isRunning()) { a->sendMessage("Hello"); if (!action.isEmpty()) { a->sendMessage("action " + action); } else { if (!m_subtitleFile.isEmpty()) { a->sendMessage("load_sub " + m_subtitleFile); } if (!m_mediaTitle.isEmpty()) { a->sendMessage("media_title " + m_filesToPlay[0] + " <> " + m_mediaTitle); } if (!m_filesToPlay.isEmpty()) { QString command = "open_files"; if (add_to_playlist) command = "add_to_playlist"; a->sendMessage(command +" "+ m_filesToPlay.join(" <> ")); } } return NoError; } return KylinVideo::NoExit; } void KylinVideo::showInfo() { QString s = QObject::tr("This is Kylin Vedio v. %1 running on %2") .arg(Version::printable()) #ifdef Q_OS_LINUX .arg("Linux") #else .arg("Other OS") #endif ; qDebug("%s", s.toUtf8().data());//printf("%s\n", s.toLocal8Bit().data()); qDebug("Compiled with Qt v. %s, using %s", QT_VERSION_STR, qVersion()); qDebug(" * application path: '%s'", Paths::appPath().toUtf8().data()); qDebug(" * config path: '%s'", Paths::configPath().toUtf8().data()); qDebug(" * ini path: '%s'", Paths::iniPath().toUtf8().data()); qDebug(" * current path: '%s'", QDir::currentPath().toUtf8().data());//snap:/home/lixiang/work/snap/kylin-video } kylin-video/src/playmask.h0000644000175000017500000000252213517016402014511 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 PLAYMASK_H #define PLAYMASK_H #include #include #include #include #include #include class PlayMask : public QWidget { Q_OBJECT public: PlayMask(QWidget *parent = 0); ~PlayMask(); void setTransparent(bool transparent); void set_widget_opacity(const float &opacity=0.8); protected: void paintEvent(QPaintEvent *event); signals: void signal_play_continue(); private: QPushButton *play_Btn = nullptr; }; #endif // PLAYMASK_H kylin-video/src/playlistview.cpp0000644000175000017500000003725213517016402015767 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "playlistview.h" #include "../smplayer/myaction.h" #include #include #include #include #include #include #include #include #include #include #include "playlistdelegate.h" #include "playlistmodel.h" #include "../smplayer/preferences.h" #include "../smplayer/global.h" using namespace Global; PlayListItem::PlayListItem() : QStandardItem() { setDuration(0); } PlayListItem::PlayListItem(const QString filename, const QString name, double duration) : QStandardItem() { setFilename(filename); setName(name); setDuration(duration); } PlayListItem::~PlayListItem() { } void PlayListItem::setFilename(const QString filename) { m_filename = filename; } void PlayListItem::setName(const QString name) { m_name = name; } void PlayListItem::setDuration(double duration) { m_duration = duration; } QString PlayListItem::filename() { return this->m_filename; } QString PlayListItem::name() { return this->m_name; } double PlayListItem::duration() { return this->m_duration; } PlayListView::PlayListView(QSettings *set, QWidget *parent) : QListView(parent) , m_set(set) { this->setStyleSheet("QListView{background-color: #2e2e2e;}"); m_playingFile = ""; m_scrollBar = new QScrollBar(this); m_scrollBar->setOrientation(Qt::Vertical); m_scrollBar->raise(); connect(m_scrollBar, SIGNAL(valueChanged(int)), this, SLOT(onValueChanged(int))); m_playlistModel = new PlaylistModel(this); m_playlistDelegate = new PlaylistDelegate; this->setItemDelegate(m_playlistDelegate); connect(m_playlistDelegate, &PlaylistDelegate::removeBtnClicked, this, [=] { this->removeSelectionByModelIndex(this->currentHoverIndex()); }); this->setModel(m_playlistModel); this->setSpacing(0); this->setContentsMargins(0, 0, 0, 0); this->setUpdatesEnabled(true); this->setMouseTracking(true); this->setVerticalScrollMode(QAbstractItemView::ScrollPerItem);//QListView::ScrollPerPixel this->setHorizontalScrollMode(QAbstractItemView::ScrollPerItem); this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); this->setEditTriggers(QAbstractItemView::NoEditTriggers); this->setSelectionBehavior(QAbstractItemView::SelectRows); this->setContextMenuPolicy(Qt::CustomContextMenu); this->viewport()->setAcceptDrops(true); this->setDragDropOverwriteMode(false); this->setDropIndicatorShown(true); this->setDragEnabled(true); this->setDefaultDropAction(Qt::MoveAction); this->setDragDropMode(QAbstractItemView::InternalMove/*QAbstractItemView::DragOnly*/); this->setMovement(QListView::Free); this->setSelectionMode(QListView::ExtendedSelection);//QListView::SingleSelection connect(this, &PlayListView::currentHoverChanged, this, &PlayListView::onCurrentHoverChanged); connect(this, &PlayListView::entered, this, &PlayListView::onItemEntered); connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint))); connect(this, SIGNAL(doubleClicked(QModelIndex)), SLOT(onDoubleClicked(QModelIndex))); } PlayListView::~PlayListView() { if (m_playlistDelegate) { delete m_playlistDelegate; m_playlistDelegate = nullptr; } } void PlayListView::onPlayListChanged(/*const VideoPtrList medialist*/) { //清空原来的列表 this->m_playlistModel->removeRows(0, this->m_playlistModel->rowCount()); //重新加载新的列表 for (auto video : pref->m_videoMap) { this->addPlayListItem(video->localpath(), video->name(), video->duration()); } // for (auto &media : medialist) { // this->addPlayListItem(media->localpath(), media->name(), media->duration()); // } this->updateScrollbarSize(); } void PlayListView::onValueChanged(int value) { verticalScrollBar()->setValue(value); } const QModelIndex &PlayListView::currentHoverIndex() const { return m_indexCurrent; } void PlayListView::enterEvent(QEvent *event) { if (m_indexCurrent.isValid()) { openPersistentEditor(m_indexCurrent); } QWidget::enterEvent(event); } void PlayListView::leaveEvent(QEvent *event) { if (m_indexCurrent.isValid()) { closePersistentEditor(m_indexCurrent); static_cast(this->m_playlistModel)->setHoverIndex(QModelIndex()); } QWidget::leaveEvent(event); } void PlayListView::onCurrentHoverChanged(const QModelIndex &previous, const QModelIndex ¤t) { if (previous.isValid()) { closePersistentEditor(previous); } openPersistentEditor(current); } void PlayListView::onItemEntered(const QModelIndex &index) { m_indexCurrent = index; static_cast(this->m_playlistModel)->setHoverIndex(m_indexCurrent); if (m_indexPrevious != m_indexCurrent) { emit currentHoverChanged(m_indexPrevious, m_indexCurrent); m_indexPrevious = m_indexCurrent; } m_playlistDelegate->setItemHover(m_indexCurrent); } void PlayListView::updateScrollbarSize() { //Attentions: 48 is playlistitem's height, 12 is VerticalScrollBar's width QSize totalSize = this->size(); int vscrollBarWidth = 12; m_scrollBar->setMinimum(0); m_scrollBar->setSingleStep(1); m_scrollBar->resize(vscrollBarWidth, totalSize.height() - 2); m_scrollBar->move(totalSize.width() - vscrollBarWidth - 2, 0); m_scrollBar->setPageStep(totalSize.height() / 48); if (this->m_playlistModel->rowCount() > totalSize.height() / 48) { m_scrollBar->setVisible(true); m_scrollBar->setMaximum(this->m_playlistModel->rowCount() - totalSize.height() / 48); } else { m_scrollBar->setVisible(false); m_scrollBar->setMaximum(0); } } void PlayListView::wheelEvent(QWheelEvent *event) { /*event->accept(); if (event->orientation() == Qt::Vertical) { if (event->delta() >= 0) emit wheelUp(); else emit wheelDown(); }*/ QListView::wheelEvent(event); this->m_scrollBar->setSliderPosition(verticalScrollBar()->sliderPosition()); } void PlayListView::resizeEvent(QResizeEvent *event) { QListView::resizeEvent(event); this->updateScrollbarSize(); } int PlayListView::getModelRowCount() { return this->m_playlistModel->rowCount(); } QStandardItem * PlayListView::getItemByRow(int row) { QStandardItem *item = this->m_playlistModel->item(row, 0); return item; // PlayListItem *playItem = static_cast(item); // return playItem; } QString PlayListView::getFileNameByRow(int row) { return this->m_playlistModel->findFileNameByRow(row); /*for (int i = 0; i < this->m_playlistModel->rowCount(); ++i) { auto index = this->m_playlistModel->index(i, 0); auto filepath = this->m_playlistModel->data(index).toString();//没有重写model的data函数时 Q_ASSERT(!filepath.isEmpty()); return filepath; }*/ } void PlayListView::setPlayingInfo(const QString &filepath, int row) { this->m_playingFile = filepath; if (row <= this->m_playlistModel->rowCount()) { QModelIndex index = this->m_playlistModel->index(row, 0); this->setCurrentIndex(index); } } QString PlayListView::getPlayingFile() { return this->m_playingFile; } void PlayListView::onDoubleClicked(const QModelIndex & index) { /*int row = this->currentIndex().row(); if (row != -1 && row != 0) { QList curRow; curRow = this->m_playlistModel->takeRow(row); this->m_playlistModel->insertRow(row-1, curRow); this->selectRow(row-1); }*/ m_indexCurrent = index; // m_playlistDelegate->setItemHover(index); //没有重写model的data函数时 QString filepath = this->m_playlistModel->filePathData(index); emit requestPlayVideo(this->currentIndex().row(), filepath); m_playingFile = filepath; } QModelIndex PlayListView::findModelIndex(const VideoPtr video) { Q_ASSERT(!video.isNull()); return this->m_playlistModel->findModelIndex(video); } void PlayListView::removeFilesFromPlayList(const QStringList &filelist) { setAutoScroll(false); foreach (QString filepath, filelist) { if (filepath.isEmpty()) continue; for (int i = 0; i < this->m_playlistModel->rowCount(); ++i) { auto index = this->m_playlistModel->index(i, 0); QString fileName = this->m_playlistModel->data(index).toString();//没有重写model的data函数时 if (fileName == filepath) { this->m_playlistModel->removeRow(i); } } } updateScrollbarSize(); setAutoScroll(true); /*QStandardItemModel *m_playlistModel = dynamic_cast(this->m_playlistModel); m_playlistModel->removeRow(this->currentIndex().row());*/ } void PlayListView::keyPressEvent(QKeyEvent *event) { switch (event->modifiers()) { case Qt::NoModifier: switch (event->key()) { case Qt::Key_Delete: QItemSelectionModel *selection = this->selectionModel(); this->removeSelectionBySelctionModel(selection); break; } break; case Qt::ShiftModifier: switch (event->key()) { case Qt::Key_Delete: break; } break; default: break; } QAbstractItemView::keyPressEvent(event); } void PlayListView::addPlayListItem(const QString &filepath, const QString &name, double duration) { //PlayListItem *newItem = new PlayListItem(filepath, name, duration); //m_playlistModel->appendRow(static_cast(newItem)); QStandardItem *newItem = new QStandardItem; m_playlistModel->appendRow(newItem); int row = m_playlistModel->rowCount() - 1; QModelIndex index = m_playlistModel->index(row, 0, QModelIndex()); m_playlistModel->setData(index, filepath);//TODO: kobe for data(hash), 如果Model中重写的了data()函数,则该设置的值被覆盖,由data()重新设置值 } void PlayListView::removeSelectionBySelctionModel(QItemSelectionModel *selection) { Q_ASSERT(selection != NULL); QStringList filePathList; for (const QModelIndex &index : selection->selectedRows()) { QString filepath = this->m_playlistModel->filePathData(index); filePathList.append(filepath); } emit this->requestRemoveFiles(filePathList); } void PlayListView::removeSelectionByModelIndex(const QModelIndex &index) { if (!index.isValid()) { return; } QStringList filePathList; QString filepath = this->m_playlistModel->filePathData(index); filePathList.append(filepath); // if (this->m_playingFile == filepath) { // } emit this->requestRemoveFiles(filePathList); } void PlayListView::showContextMenu(const QPoint &pos) { QItemSelectionModel *selection = this->selectionModel(); if (selection->selectedRows().length() <= 0) { return; } QPoint globalPos = this->mapToGlobal(pos); bool singleSelect = (1 == selection->selectedRows().length()); QMenu myMenu; MyAction *playAct = NULL; if (singleSelect) { playAct = new MyAction(this, "pl_play", false); connect(playAct, SIGNAL(triggered()), this, SLOT(onPlayActionTriggered())); playAct->change(tr("Play")); playAct->setIcon(QPixmap(":/res/playing_normal.png"));//playAct->setIcon(Images::icon("playing_normal")); } // Remove actions auto removeSelectedAct = new MyAction(this, "pl_remove_selected", false); connect( removeSelectedAct, SIGNAL(triggered()), this, SLOT(onRemoveAcionTriggered())); removeSelectedAct->change(tr("Remove &selected")); removeSelectedAct->setIcon(QPixmap(":/res/delete.png")); auto deleteSelectedFileFromDiskAct = new MyAction(this, "pl_delete_from_disk"); connect( deleteSelectedFileFromDiskAct, SIGNAL(triggered()), this, SLOT(onDeleteActionTriggered())); deleteSelectedFileFromDiskAct->change(tr("&Delete file from disk") ); deleteSelectedFileFromDiskAct->setIcon(QPixmap(":/res/delete.png")); auto index = selection->selectedRows().first(); m_selectedModelIndex = index; if (playAct) { myMenu.addAction(playAct); } if (removeSelectedAct) { myMenu.addAction(removeSelectedAct); } if (deleteSelectedFileFromDiskAct) { myMenu.addAction(deleteSelectedFileFromDiskAct); } myMenu.exec(globalPos); } void PlayListView::onPlayActionTriggered() { QString filepath = this->m_playlistModel->filePathData(m_selectedModelIndex);//TODO: m_selectedModelIndex emit requestPlayVideo(this->currentIndex().row(), filepath);//TODO: currentIndex is right??? } void PlayListView::onRemoveAcionTriggered() { this->removeSelectionBySelctionModel(this->selectionModel()); } void PlayListView::onDeleteActionTriggered() { QItemSelectionModel *selection = this->selectionModel(); Q_ASSERT(selection != NULL); QStringList fileList; for (auto index : selection->selectedRows()) { QString filepath = this->m_playlistModel->filePathData(index); fileList.append(filepath); } emit this->requestDeleteVideos(fileList); } void PlayListView::dragEnterEvent(QDragEnterEvent *event) { QListView::dragEnterEvent(event); } void PlayListView::startDrag(Qt::DropActions supportedActions) { // QModelIndex index = this->currentIndex(); // save selected list // VideoPtrList selectedMediaList; // for (QModelIndex index : this->selectionModel()->selectedIndexes()) { // selectedMediaList << this->m_playlistModel->videoData(index); // } setAutoScroll(false); QListView::startDrag(supportedActions); setAutoScroll(true); QMap maps; int newCurrentIndex = -1; QStringList newSortList; for (int i = 0; i < this->m_playlistModel->rowCount(); ++i) { auto index = this->m_playlistModel->index(i, 0); auto filepath = this->m_playlistModel->data(index).toString();//没有重写model的data函数时 Q_ASSERT(!filepath.isEmpty()); maps.insert(filepath, i); if (this->m_playingFile == filepath) { newCurrentIndex = i; } // newSortList.append(filepath); } QMap sortMaps; for (QString filepath : maps.keys()) { sortMaps.insert(maps.value(filepath), filepath); } for (int i = 0; i < sortMaps.size(); ++i) { newSortList.append(sortMaps.value(i)); } //qDebug() << "newSortList=" << newSortList; if (!newSortList.isEmpty()) { emit requestResortVideos(newSortList, newCurrentIndex); } // restore selected list // QItemSelection selections; // for (VideoPtr media : selectedMediaList) { // if (!media.isNull()) { // QModelIndex index = this->findModelIndex(media); // selections.append(QItemSelectionRange(index)); // } // } // if (!selections.isEmpty()) { // this->selectionModel()->select(selections, QItemSelectionModel::Select); // } } kylin-video/src/supportshortcuts.cpp0000644000175000017500000001345113517016402016721 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "supportshortcuts.h" #include #include #include "../smplayer/extensions.h" #include "../smplayer/helper.h" #include "../smplayer/global.h" #include "../smplayer/preferences.h" using namespace Global; SupportShortcuts::SupportShortcuts(QWidget * parent, Qt::WindowFlags f) : QWidget(parent, f ) { setupUi(this); // groupBox_play->setParent(this); // groupBox_other->setParent(this); retranslateStrings(); } SupportShortcuts::~SupportShortcuts() { } void SupportShortcuts::retranslateStrings() { retranslateUi(this); groupBox_play->setStyleSheet("QGroupBox{border:none;margin-top:20px;font-size:14px;}QGroupBox:title{subcontrol-origin: margin;subcontrol-position: top left;padding: 0px 1px;color: #999999;font-family: 方正黑体_GBK;font-weight:bold;}"); groupBox_other->setStyleSheet("QGroupBox{border:none;margin-top:20px;font-size:14px;}QGroupBox:title{subcontrol-origin: margin;subcontrol-position: top left;padding: 0px 1px;color: #999999;font-family: 方正黑体_GBK;font-weight:bold;}"); play_edit->setStyleSheet("QTextEdit {border: 1px solid #000000;color: #999999;background: #0f0f0f;font-family:方正黑体_GBK;font-size: 12px;}"); play_edit->verticalScrollBar()->setStyleSheet("QScrollBar:vertical {width: 12px;background: #141414;margin:0px 0px 0px 0px;border:1px solid #141414;}QScrollBar::handle:vertical {width: 12px;min-height: 45px;background: #292929;margin-left: 0px;margin-right: 0px;}QScrollBar::handle:vertical:hover {background: #3e3e3e;}QScrollBar::handle:vertical:pressed {background: #272727;}QScrollBar::sub-line:vertical {height: 6px;background: transparent;subcontrol-position: top;}QScrollBar::add-line:vertical {height: 6px;background: transparent;subcontrol-position: bottom;}QScrollBar::sub-line:vertical:hover {background: #292929;}QScrollBar::add-line:vertical:hover {background: #292929;}QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: transparent;}"); other_edit->setStyleSheet("QTextEdit {border: 1px solid #000000;color: #999999;background: #0f0f0f;font-family:方正黑体_GBK;font-size: 12px;}"); other_edit->verticalScrollBar()->setStyleSheet("QScrollBar:vertical {width: 12px;background: #141414;margin:0px 0px 0px 0px;border:1px solid #141414;}QScrollBar::handle:vertical {width: 12px;min-height: 45px;background: #292929;margin-left: 0px;margin-right: 0px;}QScrollBar::handle:vertical:hover {background: #3e3e3e;}QScrollBar::handle:vertical:pressed {background: #272727;}QScrollBar::sub-line:vertical {height: 6px;background: transparent;subcontrol-position: top;}QScrollBar::add-line:vertical {height: 6px;background: transparent;subcontrol-position: bottom;}QScrollBar::sub-line:vertical:hover {background: #292929;}QScrollBar::add-line:vertical:hover {background: #292929;}QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: transparent;}"); } void SupportShortcuts::setData(Preferences * pref) { play_edit->clear(); other_edit->clear(); play_edit->append(tr("Play/Pause: Space")); // play_edit->append(tr("Previous: <, Media Previous")); // play_edit->append(tr("Next: >, Media Next")); play_edit->append(tr("Previous: %1").arg(pref->prev_key)); play_edit->append(tr("Next: %1").arg(pref->next_key)); QString line = QString(tr("Forward %1: Right(→)").arg(Helper::timeForJumps(pref->seeking1))); play_edit->append(line); line = QString(tr("Forward %1: Up(↑)").arg(Helper::timeForJumps(pref->seeking2))); play_edit->append(line); line = QString(tr("Forward %1: PgUp").arg(Helper::timeForJumps(pref->seeking3))); play_edit->append(line); line = QString(tr("Rewind %1: Left(←)").arg(Helper::timeForJumps(pref->seeking1))); play_edit->append(line); line = QString(tr("Rewind %1: Down(↓)").arg(Helper::timeForJumps(pref->seeking2))); play_edit->append(line); line = QString(tr("Rewind %1: PgDn").arg(Helper::timeForJumps(pref->seeking3))); play_edit->append(line); play_edit->append(tr("Jump to...: Ctrl + J")); play_edit->append(tr("Mute: M")); play_edit->append(tr("Volume +: 9")); play_edit->append(tr("Volume -: 0")); play_edit->append(tr("Set audio delay: Y")); play_edit->append(tr("Increase or decrease audio delay: + / - / =")); other_edit->append(tr("Playlist: %1").arg(pref->playlist_key));//F3 other_edit->append(tr("Open File: Ctrl + F")); other_edit->append(tr("Screenshot: S")); other_edit->append(tr("Preferences: Ctrl + P")); other_edit->append(tr("View info and properties...: Ctrl + I")); other_edit->append(tr("About: Ctrl + A")); other_edit->append(tr("Quit: Ctrl + Q")); other_edit->append(tr("FullScreen/Cancel fullScreen: Ctrl + Enter")); play_edit->verticalScrollBar()->setValue(0);//滚动到最顶层 无效?????????????????????? // play_edit->verticalScrollBar()->setValue(play_edit->verticalScrollBar()->maximum());//滚动到最底层 other_edit->verticalScrollBar()->setValue(0); } //#include "moc_supportshortcuts.cpp" kylin-video/src/supportshortcuts.ui0000644000175000017500000000302013517016402016543 0ustar fengfeng SupportShortcuts 0 0 470 360 20 9 431 201 Play control shortcuts 10 24 411 170 true 20 213 431 141 Other control shortcuts 10 24 411 111 true kylin-video/src/videowindow.cpp0000644000175000017500000002736613637124061015602 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Kylin Ltd. * * Authors: * Kobe Lee xiangli@ubuntukylin.com/kobe24_lixiang@126.com * * 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; version 3. * * 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 "videowindow.h" #include "displaylayercomposer.h" #include "smplayer/global.h" #include "smplayer/desktopinfo.h" #include "smplayer/colorutils.h" #include "smplayer/images.h" #include #include #include #include #include #include #include VideoWindow::VideoWindow(QWidget* parent, Qt::WindowFlags f) : AutoHideCursorWidget(parent, f) , m_videoWidth(0) , m_videoHeight(0) , m_aspect((double) 4/3) , m_monitorAspect(0) , m_offsetX(0) , m_offsetY(0) , m_zoomFactor(1.0) , m_origX(0) , m_origY(0) , m_origWidth(0) , m_origHeight(0) , m_allowVideoMovement(false) , m_animatedLogo(false) , m_doubleClicked(false) , m_dragState(NOT_DRAGGING) , m_startDrag(QPoint(0,0)) , m_mouseDragTracking(false) , m_stoped(true) { this->setMouseTracking(true); this->setMinimumSize(QSize(0,0)); this->setAutoFillBackground(true); this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); this->setFocusPolicy(Qt::StrongFocus); ColorUtils::setBackgroundColor( this, QColor(0,0,0) ); m_displayLayer = new DisplayLayerComposer(this); m_displayLayer->setObjectName("m_displayLayer"); m_displayLayer->setAutoFillBackground(true); m_logoLabel = new QLabel(m_displayLayer); m_logoLabel->setAutoFillBackground(true); ColorUtils::setBackgroundColor(m_logoLabel, QColor(0,0,0) ); QVBoxLayout * mplayerlayerLayout = new QVBoxLayout(m_displayLayer); mplayerlayerLayout->addWidget(m_logoLabel, 0, Qt::AlignHCenter | Qt::AlignVCenter); this->installEventFilter(this); m_displayLayer->installEventFilter(this); //为了避免双击时触发单击事件,在单击处理函数clicked()中启动一timer,延时 qApp->doubleClickInterval(),而在此timer的timeout()中处理单击事件,在双击处理函数停止此timer m_leftClickTimer = new QTimer(this); m_leftClickTimer->setSingleShot(true); m_leftClickTimer->setInterval(qApp->doubleClickInterval()+10);//1 connect(m_leftClickTimer, SIGNAL(timeout()), this, SIGNAL(leftClicked())); m_logoLabel->setPixmap(Images::icon("background") );//kobe:设置显示区域的背景图 :/default-theme/background.png } VideoWindow::~VideoWindow() { if (m_leftClickTimer != NULL) { disconnect(m_leftClickTimer, SIGNAL(timeout()), this, SIGNAL(leftClicked())); if(m_leftClickTimer->isActive()) { m_leftClickTimer->stop(); } delete m_leftClickTimer; m_leftClickTimer = NULL; } } void VideoWindow::setCornerWidget(QWidget * w) { m_cornerWidget = w; QHBoxLayout * blayout = new QHBoxLayout; blayout->addStretch(); blayout->addWidget(m_cornerWidget); blayout->addStretch(); this->setLayout(blayout); } void VideoWindow::setColorKey( QColor c ) { ColorUtils::setBackgroundColor(m_displayLayer, c); } void VideoWindow::setLogoVisible(bool b) { if (b) m_displayLayer->setUpdatesEnabled(true); /*if (m_cornerWidget) {// m_cornerWidget is playmask widget m_cornerWidget->setVisible(b); }*/ if (b) { m_displayLayer->move(0,0); m_displayLayer->resize(this->size()); } m_stoped = b; m_logoLabel->setVisible(b); /*if (b) { m_logoLabel->show(); QPropertyAnimation * animation = new QPropertyAnimation(m_logoLabel, "pos"); animation->setDuration(200); animation->setEasingCurve(QEasingCurve::OutBounce); animation->setStartValue(QPoint(m_logoLabel->x(), 0 - m_logoLabel->y())); animation->setEndValue(m_logoLabel->pos()); animation->start(); } else { QPropertyAnimation * animation = new QPropertyAnimation(m_logoLabel, "pos"); animation->setDuration(200); animation->setEasingCurve(QEasingCurve::OutBounce); animation->setEndValue(QPoint(width(), m_logoLabel->y())); animation->setStartValue(m_logoLabel->pos()); animation->start(); connect(animation, SIGNAL(finished()), m_logoLabel, SLOT(hide())); }*/ } void VideoWindow::setResolution( int w, int h) { m_videoWidth = w; m_videoHeight = h; updateVideoWindow(); } void VideoWindow::resizeEvent( QResizeEvent *e) { m_offsetX = 0; m_offsetY = 0; updateVideoWindow(); setZoom(m_zoomFactor); } void VideoWindow::hideLogoForTemporary() { m_logoLabel->setVisible(false); } void VideoWindow::updateLogoPosition() { if (m_stoped) { m_displayLayer->move(0,0); m_displayLayer->resize(this->size()); m_logoLabel->show(); QPropertyAnimation * animation = new QPropertyAnimation(m_logoLabel, "pos"); animation->setDuration(500); animation->setEasingCurve(QEasingCurve::OutBounce); animation->setStartValue(QPoint(m_logoLabel->x(), 0 - m_logoLabel->y()/2)); animation->setEndValue(m_logoLabel->pos()); animation->start(); } } void VideoWindow::setMonitorAspect(double asp) { m_monitorAspect = asp; } void VideoWindow::setAspect( double asp) { m_aspect = asp; if (m_monitorAspect!=0) { m_aspect = m_aspect / m_monitorAspect * DesktopInfo::desktop_aspectRatio(this); } updateVideoWindow(); } void VideoWindow::updateVideoWindow() { int w_width = size().width(); int w_height = size().height(); int w = w_width; int h = w_height; int x = 0; int y = 0; if (m_aspect != 0) { int pos1_w = w_width; int pos1_h = w_width / m_aspect + 0.5; int pos2_h = w_height; int pos2_w = w_height * m_aspect + 0.5; if (pos1_h <= w_height) { w = pos1_w; h = pos1_h; y = (w_height - h) /2; } else { w = pos2_w; h = pos2_h; x = (w_width - w) /2; } } m_displayLayer->move(x,y); m_displayLayer->resize(w, h); m_origX = x; m_origY = y; m_origWidth = w; m_origHeight = h; } void VideoWindow::mouseReleaseEvent(QMouseEvent * e) { if (e->button() == Qt::LeftButton) { e->accept(); if (!m_doubleClicked) m_leftClickTimer->start(); m_doubleClicked = false; } else if (e->button() == Qt::MidButton) { e->accept(); emit middleClicked(); } else if (e->button() == Qt::XButton1) { e->accept(); emit xbutton1Clicked(); } else if (e->button() == Qt::XButton2) { e->accept(); emit xbutton2Clicked(); } else if (e->button() == Qt::RightButton) { e->accept(); emit rightClicked(); } else { e->ignore(); } } void VideoWindow::mouseDoubleClickEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { event->accept(); m_leftClickTimer->stop(); m_doubleClicked = true; emit doubleClicked(); } else { event->ignore(); } } void VideoWindow::wheelEvent(QWheelEvent *e) { e->accept(); if (e->orientation() == Qt::Vertical) { if (e->delta() >= 0) emit wheelUp(); else emit wheelDown(); } else { qDebug("VideoWindow::wheelEvent: horizontal event received, doing nothing"); } } QSize VideoWindow::sizeHint() const { return QSize(m_videoWidth, m_videoHeight); } QSize VideoWindow::minimumSizeHint () const { return QSize(0,0); } void VideoWindow::setOffsetX( int d) { m_offsetX = d; m_displayLayer->move(m_origX + m_offsetX, m_displayLayer->y()); } int VideoWindow::offsetX() { return m_offsetX; } void VideoWindow::setOffsetY(int d) { m_offsetY = d; m_displayLayer->move(m_displayLayer->x(), m_origY + m_offsetY); } int VideoWindow::offsetY() { return m_offsetY; } void VideoWindow::setZoom(double d) { m_zoomFactor = d; m_offsetX = 0; m_offsetY = 0; int x = m_origX; int y = m_origY; int w = m_origWidth; int h = m_origHeight; if (m_zoomFactor != 1.0) { w = w * m_zoomFactor; h = h * m_zoomFactor; // Center x = (width() - w) / 2; y = (height() -h) / 2; } m_displayLayer->move(x,y); m_displayLayer->resize(w,h); } double VideoWindow::zoom() { return m_zoomFactor; } void VideoWindow::moveDisplayLayer(int m_offsetX, int m_offsetY) { int x = m_displayLayer->x(); int y = m_displayLayer->y(); m_displayLayer->move(x + m_offsetX, y + m_offsetY); } void VideoWindow::moveLeft() { if ((m_allowVideoMovement) || (m_displayLayer->x()+m_displayLayer->width() > width())) moveDisplayLayer(-16, 0); } void VideoWindow::moveRight() { if ((m_allowVideoMovement) || ( m_displayLayer->x() < 0)) moveDisplayLayer(+16, 0); } void VideoWindow::moveUp() { if ((m_allowVideoMovement) || (m_displayLayer->y()+m_displayLayer->height() > height())) moveDisplayLayer(0, -16); } void VideoWindow::moveDown() { if ((m_allowVideoMovement) || ( m_displayLayer->y() < 0)) moveDisplayLayer(0, +16); } void VideoWindow::incZoom() { setZoom(m_zoomFactor + ZOOM_STEP); } void VideoWindow::decZoom() { double zoom = m_zoomFactor - ZOOM_STEP; if (zoom < ZOOM_MIN) zoom = ZOOM_MIN; setZoom(zoom); } bool VideoWindow::eventFilter(QObject *object, QEvent *event) { if (!m_mouseDragTracking) return false; QEvent::Type type = event->type(); if (type != QEvent::MouseButtonPress && type != QEvent::MouseButtonRelease && type != QEvent::MouseMove) return false; QMouseEvent *mouseEvent = dynamic_cast(event); if (!mouseEvent) return false; if (mouseEvent->modifiers() != Qt::NoModifier) { m_dragState = NOT_DRAGGING; return false; } if (type == QEvent::MouseButtonPress) { if (mouseEvent->button() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } m_dragState = START_DRAGGING; m_startDrag = mouseEvent->globalPos(); // Don't filter, so others can have a look at it too return false; } if (type == QEvent::MouseButtonRelease) { if (m_dragState != DRAGGING || mouseEvent->button() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } // Stop dragging and eat event m_dragState = NOT_DRAGGING; event->accept(); return true; } // type == QEvent::MouseMove if (m_dragState == NOT_DRAGGING) return false; // buttons() note the s if (mouseEvent->buttons() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } QPoint pos = mouseEvent->globalPos(); QPoint diff = pos - m_startDrag; if (m_dragState == START_DRAGGING) { // Don't start dragging before moving at least DRAG_THRESHOLD pixels if (abs(diff.x()) < DRAG_THRESHOLD && abs(diff.y()) < DRAG_THRESHOLD) return false; m_dragState = DRAGGING; } emit mouseMovedDiff(diff); m_startDrag = pos; event->accept(); return true; } kylin-video/src/playlist.cpp0000644000175000017500000016705713637124061015107 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "playlist.h" #include "../smplayer/paths.h" #include "../playlistmodel.h" #include "../playlistview.h" #include "../smplayer/myaction.h" #include "../smplayer/filedialog.h" #include "../smplayer/preferences.h" #include "../smplayer/version.h" #include "../smplayer/global.h" #include "../smplayer/core.h" #include "../smplayer/extensions.h" #include "../messagedialog.h" #include "../smplayer/infoprovider.h" #include "../smplayer/cleanconfig.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace Global; Playlist::Playlist(Core *c, QWidget * parent, Qt::WindowFlags f) : QFrame(parent, Qt::SubWindow) , set(0) , modified(false) , recursive_add_directory(false) , automatically_get_info(false) , play_files_from_start(true) , start_play_on_load(true) , automatically_play_next(true) , ignore_player_errors(false) , allow_delete_from_disk(true) { this->setWindowFlags(Qt::FramelessWindowHint); this->setAutoFillBackground(true); this->setFixedWidth(220); setObjectName("PlaylistWidget"); setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred); setAcceptDrops(true); setAttribute(Qt::WA_NoMousePropagation); m_core = c; playlist_path = ""; latest_dir = QDir::homePath(); titleLabel = 0; btDel = 0; btAdd = 0; novideo_icon = 0; novideo_text = 0; add_Btn = 0; title_layout = NULL; setConfigPath(Paths::configPath()); createNoVideo(); createTable(); createToolbar(); QVBoxLayout *layout = new QVBoxLayout(this); setFocusPolicy(Qt::ClickFocus); layout->setContentsMargins(0, 0, 0, 15); layout->setSpacing(16); btAddFrame = new QFrame; btAddFrame->setFixedSize(120, 36); btAddFrame->setObjectName("PlaylistWidgetAddFrame"); btAddFrame->setFocusPolicy(Qt::NoFocus); QHBoxLayout *btAddFameLayout = new QHBoxLayout(btAddFrame); btAddFameLayout->setMargin(0); btAddFameLayout->setSpacing(0); btAddFameLayout->addWidget(btAdd, 0, Qt::AlignVCenter); btAddFameLayout->addWidget(btDel, 0, Qt::AlignVCenter); title_layout = new QHBoxLayout(); title_layout->setSpacing(0); title_layout->setMargin(0); title_layout->addWidget(titleLabel, 0, Qt::AlignHCenter); title_layout->addWidget(btAddFrame, 0, Qt::AlignHCenter); noVideoFrame = new QFrame(); noVideoFrame->setFocusPolicy(Qt::NoFocus); QVBoxLayout *noVideoFameLayout = new QVBoxLayout(noVideoFrame); noVideoFameLayout->setMargin(0); noVideoFameLayout->setSpacing(30); noVideoFameLayout->addStretch(); noVideoFameLayout->addWidget(novideo_icon, 0, Qt::AlignHCenter); noVideoFameLayout->addWidget(novideo_text, 0, Qt::AlignHCenter); noVideoFameLayout->addWidget(add_Btn, 0, Qt::AlignHCenter); noVideoFameLayout->addStretch(); layout->addLayout(title_layout); layout->addWidget(m_playlistView, 0, Qt::AlignHCenter); layout->addWidget(noVideoFrame, 0, Qt::AlignHCenter); layout->addStretch(); setLayout(layout); clear(); connect(m_core, SIGNAL(mediaFinished()), this, SLOT(playNextAuto()), Qt::QueuedConnection); connect(m_core, SIGNAL(mplayerFailed(QProcess::ProcessError)), this, SLOT(playerFailed(QProcess::ProcessError)) ); connect(m_core, SIGNAL(mplayerFinishedWithError(int)), this, SLOT(playerFinishedWithError(int)) ); connect(m_core, SIGNAL(mediaDataReceived(const MediaData &)), this, SLOT(getMediaInfo(const MediaData &))); // connect(playlist, SIGNAL(requestToPlayFile(const QString &, int)), // m_core, SLOT(open(const QString &, int))); // connect(playlist, SIGNAL(requestToPlayStream(const QString &, QStringList)), // m_core, SLOT(openStream(const QString &, QStringList))); // connect(playlist, SIGNAL(requestToAddCurrentFile()), this, SLOT(addToPlaylistCurrentFile())); // Ugly hack to avoid to play next item automatically /*if (!automatically_play_next) { disconnect( m_core, SIGNAL(mediaFinished()), this, SLOT(playNext()) ); }*/ // Save config every 5 minutes. save_timer = new QTimer(this); connect(save_timer, SIGNAL(timeout()), this, SLOT(maybeSaveSettings())); save_timer->start(5 * 60000); if (this->count() > 0) { noVideoFrame->hide(); m_playlistView->show(); } else { noVideoFrame->show(); m_playlistView->hide(); } loadSettings(); } Playlist::~Playlist() { saveSettings(); if (set) { delete set; set = 0; } if (titleLabel != NULL) { delete titleLabel; titleLabel = NULL; } if (btDel != NULL) { delete btDel; btDel = NULL; } if (btAdd != NULL) { delete btAdd; btAdd = NULL; } if (novideo_icon != NULL) { delete novideo_icon; novideo_icon = NULL; } if (novideo_text != NULL) { delete novideo_text; novideo_text = NULL; } if (add_Btn != NULL) { delete add_Btn; add_Btn = NULL; } if (noVideoFrame != NULL) { delete noVideoFrame; noVideoFrame = NULL; } if (btAddFrame != NULL) { delete btAddFrame; btAddFrame = NULL; } if (title_layout) { delete title_layout; title_layout = NULL; } if (m_playlistView != NULL) { delete m_playlistView; m_playlistView = NULL; } if (save_timer != NULL) { disconnect(save_timer, SIGNAL(timeout()), this, SLOT(maybeSaveSettings())); if(save_timer->isActive()) { save_timer->stop(); } delete save_timer; save_timer = NULL; } } void Playlist::setConfigPath(const QString & config_path) { if (set) { delete set; set = 0; } if (!config_path.isEmpty()) { QString inifile = config_path + "/kylin-video-playlist.ini"; //qDebug() << "Playlist::setConfigPath: ini file:" << inifile; set = new QSettings(inifile, QSettings::IniFormat); set->setIniCodec("UTF-8"); } } void Playlist::updateWindowTitle() { /* QString title; title = playlist_filename; if (title.isEmpty()) title = tr("Untitled playlist"); if (modified) title += " (*)"; emit requestSetPlayingTitle(title);//emit windowTitleChanged(title); */ } void Playlist::setPlaylistFilename(const QString & f) { //playlist_filename = f; //updateWindowTitle(); } void Playlist::setModified(bool mod) { modified = mod; emit modifiedChanged(modified); updateWindowTitle(); } void Playlist::createTable() { m_playlistView = new PlayListView(set, this); // m_playlistView->setFixedHeight(430); // QSizePolicy sp(QSizePolicy::Preferred, QSizePolicy::Preferred); // sp.setVerticalStretch(100); // m_playlistView->setSizePolicy(sp); connect(m_playlistView, SIGNAL(activated(QModelIndex)), this, SLOT(itemActivated(QModelIndex))); connect(m_playlistView, SIGNAL(requestResortVideos(QStringList, int)), this, SLOT(onResortVideos(QStringList, int))); connect(m_playlistView, SIGNAL(requestPlayVideo(int, QString)), this, SLOT(onPlayListItemDoubleClicked(int,QString))); connect(m_playlistView, SIGNAL(requestRemoveFiles(QStringList)), this, SLOT(onPlayListItemDeleteBtnClicked(QStringList))); connect(m_playlistView, SIGNAL(requestDeleteVideos(QStringList)), this, SLOT(deleteSelectedFileFromDisk(QStringList))); } void Playlist::setViewHeight() { m_playlistView->setFixedHeight(this->height()-36-16);//36为顶部按钮和label的高度,16为顶部和列表的间隔 } void Playlist::createNoVideo() { novideo_icon = new QLabel(); novideo_icon->setFixedSize(70, 70); novideo_icon->setPixmap(QPixmap(":/res/no-video.png")); novideo_text = new QLabel(); novideo_text->setObjectName("VideoText"); novideo_text->setText(tr("Playlist is empty")); add_Btn = new QPushButton(); add_Btn->setFocusPolicy(Qt::NoFocus); add_Btn->setFixedSize(140, 38); add_Btn->setObjectName("PlaylistAddButton"); add_Btn->setText(tr("Add File")); connect(add_Btn, SIGNAL(clicked(bool)), SLOT(popupDialogtoSelectFiles())); } void Playlist::createToolbar() { titleLabel = new QLabel(); titleLabel->setAlignment(Qt::AlignCenter); titleLabel->setFixedSize(220-120, 36); titleLabel->setStyleSheet("QLabel{font-size:12px;color:#ffffff;background:transparent;}"); titleLabel->setText(tr("PlayList")); btDel = new QPushButton(); btDel->setFocusPolicy(Qt::NoFocus); btDel->setFixedSize(60, 36); btDel->setText(tr("Clear")); btDel->setObjectName("PlaylistButton"); connect(btDel, SIGNAL(clicked(bool)), SLOT(removeAll())); btAdd = new QPushButton(); btAdd->setFocusPolicy(Qt::NoFocus); btAdd->setFixedSize(60, 36); btAdd->setObjectName("PlaylistButton"); btAdd->setText(tr("Add")); connect(btAdd, SIGNAL(clicked(bool)), SLOT(popupDialogtoSelectFiles())); } void Playlist::clear() { this->m_playlistView->reset(); this->m_playlistView->clearSelection(); this->m_playlistView->clearFocus(); this->m_playlistView->updateScrollbarSize(); emit this->update_playlist_count(0); this->setPlaying("", 0); noVideoFrame->show(); m_playlistView->hide(); setModified(false); } int Playlist::count() { return m_playlistView->getModelRowCount(); } bool Playlist::isEmpty() { return (this->m_playlistView->getModelRowCount() == 0); } bool Playlist::rowIsEmpty() { return pref->m_videoMap.isEmpty(); } void Playlist::loadSingleItem(QString filename, QString name, double duration) { //Attention: maybe name is empty when adding a new local file if (name.isEmpty()) { QFileInfo fi(filename); // Let's see if it looks like a file (no dvd://1 or something) if (filename.indexOf(QRegExp("^.*://.*")) == -1) { // Local file name = fi.fileName(); } else { // Stream name = filename; } } auto video = pref->generateVedioData(filename, name, duration); bool exists = false; foreach (VideoPtr videoPtr, pref->m_videoMap) {//for (auto video : m_videoMap) if (videoPtr->m_localpath == filename.toUtf8().data()) { exists = true; break; } } if (!exists) { pref->m_videoMap.insert(video->m_localpath, video); setModified(true); m_playlistView->addPlayListItem(filename, name, duration); emit this->update_playlist_count(this->count()); } } void Playlist::loadItemWithoutUI(QString filename, QString name, double duration) { if (name.isEmpty()) { QFileInfo fi(filename); // Let's see if it looks like a file (no dvd://1 or something) if (filename.indexOf(QRegExp("^.*://.*")) == -1) { // Local file name = fi.fileName(); } else { // Stream name = filename; } } auto video = pref->generateVedioData(filename, name, duration); bool exists = false; foreach (VideoPtr videoPtr, pref->m_videoMap) {//for (auto video : m_videoMap) if (videoPtr->m_localpath == filename.toUtf8().data()) { exists = true; break; } } if (!exists) { pref->m_videoMap.insert(video->m_localpath, video); } } void Playlist::load_m3u(QString file, M3UFormat format) { /*bool utf8 = false; if (format == DetectFormat) { utf8 = (QFileInfo(file).suffix().toLower() == "m3u8"); } else { utf8 = (format == M3U8); } qDebug() << "Playlist::load_m3u: utf8:" << utf8; QRegExp m3u_id("^#EXTM3U|^#M3U"); QRegExp rx_info("^#EXTINF:([.\\d]+).*tvg-logo=\"(.*)\",(.*)"); QFile f( file ); if ( f.open( QIODevice::ReadOnly ) ) { playlist_path = QFileInfo(file).path(); clear(); QString filename=""; QString name=""; double duration=0; QStringList extra_params; QString icon_url; QTextStream stream( &f ); if (utf8) stream.setCodec("UTF-8"); else stream.setCodec(QTextCodec::codecForLocale()); QString line; while ( !stream.atEnd() ) { line = stream.readLine().trimmed(); if (line.isEmpty()) continue; // Ignore empty lines qDebug() << "Playlist::load_m3u: line:" << line; if (m3u_id.indexIn(line)!=-1) { //#EXTM3U // Ignore line } else if (rx_info.indexIn(line) != -1) { duration = rx_info.cap(1).toDouble(); name = rx_info.cap(3); icon_url = rx_info.cap(2); qDebug() << "Playlist::load_m3u: name:" << name << "duration:" << duration << "icon_url:" << icon_url; } else if (line.startsWith("#EXTINF:")) { QStringList fields = line.mid(8).split(","); //qDebug() << "Playlist::load_m3u: fields:" << fields; if (fields.count() >= 1) duration = fields[0].toDouble(); if (fields.count() >= 2) name = fields[1]; } else if (line.startsWith("#EXTVLCOPT:")) { QString par = line.mid(11); qDebug() << "Playlist::load_m3u: EXTVLCOPT:" << par; extra_params << par; } else if (line.startsWith("#")) { // Comment // Ignore } else { filename = line; QFileInfo fi(filename); if (fi.exists()) { filename = fi.absoluteFilePath(); } if (!fi.exists()) { if (QFileInfo( playlist_path + "/" + filename).exists() ) { filename = playlist_path + "/" + filename; } } name.replace(",", ","); //qDebug() << "Playlist::load_m3u: extra_params:" << extra_params; addItem( filename, name, duration, extra_params, "", icon_url ); name = ""; duration = 0; extra_params.clear(); icon_url = ""; } } f.close(); //list(); setPlaylistFilename(file); setModified(false); if (start_play_on_load) startPlayPause(); }*/ } void Playlist::load_pls(QString file) { qDebug("Playlist::load_pls"); /*if (!QFile::exists(file)) { qDebug("Playlist::load_pls: '%s' doesn't exist, doing nothing", file.toUtf8().constData()); return; } playlist_path = QFileInfo(file).path(); QSettings set(file, QSettings::IniFormat); set.beginGroup("playlist"); if (set.status() == QSettings::NoError) { clear(); QString filename; QString name; double duration; int num_items = set.value("NumberOfEntries", 0).toInt(); #if QT_VERSION >= 0x050000 // It seems Qt 5 is case sensitive if (num_items == 0) num_items = set.value("numberofentries", 0).toInt(); #endif for (int n=0; n < num_items; n++) { filename = set.value("File"+QString::number(n+1), "").toString(); name = set.value("Title"+QString::number(n+1), "").toString(); duration = (double) set.value("Length"+QString::number(n+1), 0).toInt(); QFileInfo fi(filename); if (fi.exists()) { filename = fi.absoluteFilePath(); } if (!fi.exists()) { if (QFileInfo( playlist_path + "/" + filename).exists() ) { filename = playlist_path + "/" + filename; } } addItem( filename, name, duration ); } } set.endGroup(); //list(); setPlaylistFilename(file); setModified(false); if (set.status() == QSettings::NoError && start_play_on_load) startPlayPause();*/ } void Playlist::loadXSPF(const QString & filename) { qDebug() << "Playlist::loadXSPF:" << filename; /*QFile f(filename); if (!f.open(QIODevice::ReadOnly)) { return; } QDomDocument dom_document; bool ok = dom_document.setContent(f.readAll()); qDebug() << "Playlist::loadXSPF: success:" << ok; if (!ok) return; QDomNode root = dom_document.documentElement(); qDebug() << "Playlist::loadXSPF: tagname:" << root.toElement().tagName(); QDomNode child = root.firstChildElement("trackList"); if (!child.isNull()) { clear(); qDebug() << "Playlist::loadXSPF: child:" << child.nodeName(); QDomNode track = child.firstChildElement("track"); while (!track.isNull()) { QString location = QUrl::fromPercentEncoding(track.firstChildElement("location").text().toLatin1()); QString title = track.firstChildElement("title").text(); int duration = track.firstChildElement("duration").text().toInt(); qDebug() << "Playlist::loadXSPF: location:" << location; qDebug() << "Playlist::loadXSPF: title:" << title; qDebug() << "Playlist::loadXSPF: duration:" << duration; loadSingleItem( location, title, (double) duration / 1000 ); track = track.nextSiblingElement("track"); } //list(); setPlaylistFilename(filename); setModified( false ); if (start_play_on_load) startPlayPause(); }*/ // this->m_playlistView->updateScrollbarSize(); } bool Playlist::save_m3u(QString file) { qDebug() << "Playlist::save_m3u:" << file; return false; /*QString dir_path = QFileInfo(file).path(); if (!dir_path.endsWith("/")) dir_path += "/"; qDebug() << "Playlist::save_m3u: dir_path:" << dir_path; bool utf8 = (QFileInfo(file).suffix().toLower() == "m3u8"); QFile f( file ); if ( f.open( QIODevice::WriteOnly ) ) { QTextStream stream( &f ); if (utf8) stream.setCodec("UTF-8"); else stream.setCodec(QTextCodec::codecForLocale()); QString filename; QString name; stream << "#EXTM3U" << "\n"; stream << "# Playlist created by kylin-video " << Version::printable() << " \n"; for (int n = 0; n < count(); n++) { PlayListItem * i = itemData(n); filename = i->filename(); name = i->name(); name.replace(",", ","); QString icon_url = i->iconURL(); stream << "#EXTINF:"; stream << i->duration(); if (!icon_url.isEmpty()) stream << " tvg-logo=\"" + icon_url + "\""; stream << ","; stream << name << "\n"; // Save extra params QStringList params = i->extraParams(); foreach(QString par, params) { stream << "#EXTVLCOPT:" << par << "\n"; } // Try to save the filename as relative instead of absolute if (filename.startsWith( dir_path )) { filename = filename.mid( dir_path.length() ); } stream << filename << "\n"; } f.close(); setPlaylistFilename(file); setModified( false ); return true; } else { return false; }*/ } bool Playlist::save_pls(QString file) { qDebug() << "Playlist::save_pls:" << file; return false; /* QString dir_path = QFileInfo(file).path(); if (!dir_path.endsWith("/")) dir_path += "/"; qDebug() << "Playlist::save_pls: dir_path:" << dir_path; QSettings set(file, QSettings::IniFormat); set.beginGroup( "playlist"); QString filename; for (int n = 0; n < count(); n++) { PlayListItem * i = itemData(n); filename = i->filename(); // Try to save the filename as relative instead of absolute if (filename.startsWith( dir_path )) { filename = filename.mid( dir_path.length() ); } set.setValue("File"+QString::number(n+1), filename); set.setValue("Title"+QString::number(n+1), i->name()); set.setValue("Length"+QString::number(n+1), (int) i->duration()); } set.setValue("NumberOfEntries", count()); set.setValue("Version", 2); set.endGroup(); set.sync(); bool ok = (set.status() == QSettings::NoError); if (ok) { setPlaylistFilename(file); setModified( false ); } return ok;*/ } bool Playlist::saveXSPF(const QString & filename) { qDebug() << "Playlist::saveXSPF:" << filename; return false; /*QFile f(filename); if (f.open( QIODevice::WriteOnly)) { QTextStream stream(&f); stream.setCodec("UTF-8"); stream << "\n"; stream << "\n"; stream << "\t\n"; for (int n = 0; n < count(); n++) { PlayListItem * i = itemData(n); QString location = i->filename(); qDebug() << "Playlist::saveXSPF:" << location; bool is_local = QFile::exists(location); // #ifdef Q_OS_WIN // if (is_local) { // location.replace("\\", "/"); // } // #endif //qDebug() << "Playlist::saveXSPF:" << location; QUrl url(location); location = url.toEncoded(); //qDebug() << "Playlist::saveXSPF:" << location; if (!location.startsWith("file:") && is_local) { // #ifdef Q_OS_WIN // location = "file:///" + location; // #else location = "file://" + location; // #endif } QString title = i->name(); int duration = i->duration() * 1000; #if QT_VERSION >= 0x050000 location = location.toHtmlEscaped(); title = title.toHtmlEscaped(); #else location = Qt::escape(location); title = Qt::escape(title); #endif stream << "\t\t\n"; stream << "\t\t\t" << location << "\n"; stream << "\t\t\t" << title << "\n"; stream << "\t\t\t" << duration << "\n"; stream << "\t\t\n"; } stream << "\t\n"; stream << "\n"; setPlaylistFilename(filename); setModified(false); return true; } else { return false; }*/ } void Playlist::load() { /*if (maybeSave()) { Extensions e; QString s = MyFileDialog::getOpenFileName( this, tr("Choose a file"), lastDir(), tr("Playlists") + e.playlist().forFilter() + ";;" + tr("All files") +" (*)"); if (!s.isEmpty()) { latest_dir = QFileInfo(s).absolutePath(); QString suffix = QFileInfo(s).suffix().toLower(); if (suffix == "pls") { //load_pls(s); } else if (suffix == "xspf") { //loadXSPF(s); } else { //load_m3u(s); } } }*/ } bool Playlist::saveCurrentPlaylist() { return save(playlistFilename()); } bool Playlist::save(const QString & filename) { QString s = filename; if (s.isEmpty()) { Extensions e; s = MyFileDialog::getSaveFileName( this, tr("Choose a filename"), lastDir(), tr("Playlists") + e.playlist().forFilter() + ";;" + tr("All files") +" (*)"); } if (!s.isEmpty()) { // If filename has no extension, add it if (QFileInfo(s).suffix().isEmpty()) { s = s + ".m3u"; } if (QFileInfo(s).exists()) { int res = QMessageBox::question( this, tr("Confirm overwrite?"), tr("The file %1 already exists.\n" "Do you want to overwrite?").arg(s), QMessageBox::Yes, QMessageBox::No, QMessageBox::NoButton); if (res == QMessageBox::No ) { return false; } } latest_dir = QFileInfo(s).absolutePath(); QString suffix = QFileInfo(s).suffix().toLower(); if (suffix == "pls") { return save_pls(s); } else if (suffix == "xspf") { return saveXSPF(s); } else { return save_m3u(s); } } else { return false; } } bool Playlist::maybeSave() { return false; /*if (!isModified()) return true; int res = QMessageBox::question( this, tr("Playlist modified"), tr("There are unsaved changes, do you want to save the playlist?"), QMessageBox::Yes, QMessageBox::No, QMessageBox::Cancel); switch (res) { case QMessageBox::No : return true; // Discard changes case QMessageBox::Cancel : return false; // Cancel operation default : return save(); }*/ } //双击播放列表的一项时进行播放 void Playlist::onPlayListItemDoubleClicked(int row, const QString &filename) { //playlist_filename = filename; QFileInfo fi(filename); if (fi.exists()) { // Local file if ((row >= this->m_playlistView->getModelRowCount()) || (row < 0)) { emit this->requestSetPlayingTitle(""); return; } QString name = fi.fileName(); emit this->requestSetPlayingTitle(name); //保存当前播放文件的索引和文件路径名 this->setPlaying(filename, row); m_core->open(filename/*, 0*/);//每次从头开始播放文件 } else { emit this->playListFinishedWithError(filename); } } void Playlist::setPlaying(const QString &filepath, int index) { this->m_currentItemIndex = index; this->m_playlistView->setPlayingInfo(filepath, m_currentItemIndex); } void Playlist::itemActivated(const QModelIndex & index ) { // onPlayListItemDoubleClicked //qDebug() << "Playlist::itemActivated: row:" << index.row(); //playItem(index.row()); } //kobe:添加多个文件文件夹或拖拽进多个文件文件夹时才会走这里,如果是支持乱序,则乱序选择一个开始播放 void Playlist::startPlayPause() { // Start to play if (pref->play_order == Preferences::RandomPlay) {//随机播放 playItem(chooseRandomItem()); } else {//顺序播放 列表循环 playItem(0); } } void Playlist::playItem( int n ) { //qDebug() << "Playlist::playItem n=" << n; if ( (n >= this->m_playlistView->getModelRowCount()) || (n < 0) ) { qDebug("Playlist::playItem: out of range"); emit playlistEnded(); emit this->requestSetPlayingTitle(""); return; } QString filename = this->m_playlistView->getFileNameByRow(n); if (!filename.isEmpty()) { QFileInfo fi(filename); if (fi.exists()) { //this->playlist_filename = filename; // Local file QString name = fi.fileName(); emit this->requestSetPlayingTitle(name); //0621 kobe: m_core->open(filename, 0): 每次从头开始播放文件, m_core->open(filename):每次从上次播放停止位置开始播放文件 //保存当前播放文件的索引和文件路径名 this->setPlaying(filename, n); if (play_files_from_start) { emit this->requestSetPlayingTitle(name); m_core->open(filename, 0); } else { emit this->requestSetPlayingTitle(name); m_core->open(filename, 0); } } else { emit this->playListFinishedWithError(filename); } } } void Playlist::playNext() { // emit this->requestSetPlayingTitle(""); // qDebug("Playlist::playNext pl[m_currentItemIndex]->name()=%s", pl[m_currentItemIndex]->name()); //qDebug() << "playNext m_currentItemIndex=" << m_currentItemIndex; if (pref->play_order == Preferences::RandomPlay) {//随机播放 int chosen_item = chooseRandomItem(); if (chosen_item == -1) { clearPlayedTag(); chosen_item = chooseRandomItem(); if (chosen_item == -1) chosen_item = 0; } playItem(chosen_item); } else if (pref->play_order == Preferences::ListLoopPlay) {//列表循环 bool finished_list = (m_currentItemIndex + 1 >= this->m_playlistView->getModelRowCount());//pl.count() if (finished_list) { clearPlayedTag(); } if (finished_list) { playItem(0); } else { playItem(m_currentItemIndex+1); } } else {//顺序播放 bool finished_list = (m_currentItemIndex + 1 >= this->m_playlistView->getModelRowCount());//pl.count() if (finished_list) { clearPlayedTag(); } if (finished_list) { // emit this->finish_list(); emit this->showMessage(tr("Reached the end of the playlist")); } else { playItem(m_currentItemIndex + 1); } } } void Playlist::playPrev() { if (pref->play_order == Preferences::RandomPlay) {//随机播放 int chosen_item = chooseRandomItem(); if (chosen_item == -1) { clearPlayedTag(); chosen_item = chooseRandomItem(); if (chosen_item == -1) chosen_item = 0; } playItem(chosen_item); } else if (pref->play_order == Preferences::ListLoopPlay) {//列表循环 bool top_list = (m_currentItemIndex == 0) ? true : false; if (top_list) { clearPlayedTag(); } if (top_list) { playItem(0); } else { if (m_currentItemIndex > 0) { playItem(m_currentItemIndex - 1); } else { if (this->m_playlistView->getModelRowCount() > 1) { playItem(this->m_playlistView->getModelRowCount() - 1); } } } } else {//顺序播放 bool top_list = (m_currentItemIndex == 0) ? true : false; if (top_list) { clearPlayedTag(); } if (top_list) { emit this->showMessage(tr("Reached the top of the playlist")); } else { if (m_currentItemIndex > 0) { playItem(m_currentItemIndex - 1); } else { if (this->m_playlistView->getModelRowCount() > 1) { playItem(this->m_playlistView->getModelRowCount() - 1); } } } } } void Playlist::playNextAuto() { //qDebug("Playlist::playNextAuto"); if (automatically_play_next) { playNext(); } else { emit playlistEnded(); } } void Playlist::resumePlay() { if (this->m_playlistView->getModelRowCount() > 0) { if (m_currentItemIndex < 0) { this->setPlaying("", 0); } playItem(m_currentItemIndex); } } void Playlist::getMediaInfo(const MediaData & mdat) { QString filename = mdat.m_filename;//20181201 m_filename double duration = mdat.duration; QString artist = mdat.clip_artist; QString video_url = mdat.stream_path; QString name; //name = mdat.clip_name;//有的rmvb视频的clip_name存在乱码 if (name.isEmpty()) name = mdat.stream_title; if (name.isEmpty()) { QFileInfo fi(filename); if (fi.exists()) { // Local file name = fi.fileName(); } else { // Stream name = filename; } } if (!artist.isEmpty()) name = artist + " - " + name; } // Add current file to playlist //void Playlist::addCurrentFile() //{ // emit requestToAddCurrentFile(); //} void Playlist::addFiles() { Extensions e; QStringList files = MyFileDialog::getOpenFileNames( this, tr("Select one or more files to open"), lastDir(), tr("Multimedia") + e.multimedia().forFilter() + ";;" + tr("All files") +" (*.*)" ); if (files.count() != 0) { addFiles(files); setModified(true); } } void Playlist::onPlayListChanged(const VideoPtrList medialist) { setCursor(Qt::WaitCursor); // update pref->m_videoMap for (auto &meta : medialist) { pref->m_videoMap.insert(meta->localpath(), meta); setModified(true); } // update settings set->remove("playlist_contents"); set->beginGroup("playlist_contents"); set->beginWriteArray("items"); int index = 0; QMap::iterator i; for (i = pref->m_videoMap.begin(); i != pref->m_videoMap.end(); ++i) {//for (auto video : pref->remainingMaps) set->setArrayIndex(index); set->setValue(QString("item_%1_filename").arg(index), i.value()->localpath()); set->setValue(QString("item_%1_duration").arg(index), i.value()->duration()); set->setValue(QString("item_%1_name").arg(index), i.value()->name()); latest_dir = QFileInfo(i.value()->localpath()).absolutePath(); index ++; } set->endArray(); set->setValue("current_item", m_currentItemIndex); set->endGroup(); set->sync(); // update ui this->m_playlistView->onPlayListChanged(/*medialist*/); emit this->update_playlist_count(this->count());//emit this->update_playlist_count(pref->m_videoMap.count()); if (this->count() > 0) { noVideoFrame->setVisible(false); m_playlistView->setVisible(true); } else { m_currentItemIndex = 0; noVideoFrame->setVisible(true); m_playlistView->setVisible(false); } unsetCursor(); } void Playlist::popupDialogtoSelectFiles() { //打开一个或多个文件时,此时只是将选择的文件加入播放列表,并不会自动去播放选择的文件 Extensions e; QStringList files = MyFileDialog::getOpenFileNames( this, tr("Select one or more files to open"), lastDir(), tr("Multimedia") + e.multimedia().forFilter() + ";;" + tr("All files") +" (*.*)" ); if (files.count()!=0) addFiles(files); } void Playlist::addFiles(QStringList files, AutoGetInfo auto_get_info) { emit requestGetMediaInfo(files); // bool get_info = (auto_get_info == GetInfo); // get_info = true; //get_info = automatically_get_info; /*MediaData data; setCursor(Qt::WaitCursor); for (int n = 0; n < files.count(); n++) { QString name = ""; double duration = 0; if (pref->m_videoMap.contains(files[n])) { continue; } //TODO: thread //kobe 0606 如果选择多个文件,此时读取信息会耗时很长,导致界面卡顿,此处暂时不获取视频信息,在双击播放后再在函数updateView中更新视频的时长 if ((QFile::exists(files[n])) ) { data = InfoProvider::getInfo(files[n]); name = data.displayName(); duration = data.duration; this->loadSingleItem(files[n], name, duration); latest_dir = QFileInfo(files[n]).absolutePath(); } } unsetCursor(); this->m_playlistView->updateScrollbarSize(); this->saveSettings();*/ } void Playlist::addFile(QString file, AutoGetInfo auto_get_info) { //打开一个文件时 addFiles( QStringList() << file, auto_get_info ); } void Playlist::addDirectory() { QString s = MyFileDialog::getExistingDirectory( this, tr("Choose a directory"), lastDir() ); if (!s.isEmpty()) { addDirectory(s); latest_dir = s; } } void Playlist::addUrls() { /*MultilineInputDialog d(this); if (d.exec() == QDialog::Accepted) { QStringList urls = d.lines(); foreach(QString u, urls) { if (!u.isEmpty()) addItem( u, "", 0 ); } setModified(true); }*/ } void Playlist::addOneDirectory(QString dir) { QStringList filelist; Extensions e; QRegExp rx_ext(e.multimedia().forRegExp()); rx_ext.setCaseSensitivity(Qt::CaseInsensitive); QStringList dir_list = QDir(dir).entryList(); QString filename; QStringList::Iterator it = dir_list.begin(); while( it != dir_list.end() ) { filename = dir; if (filename.right(1)!="/") filename += "/"; filename += (*it); QFileInfo fi(filename); if (!fi.isDir()) { if (rx_ext.indexIn(fi.suffix()) > -1) { filelist << filename; } } ++it; } addFiles(filelist); } void Playlist::addDirectory(QString dir) { addOneDirectory(dir); if (recursive_add_directory) {//递归 QFileInfoList dir_list = QDir(dir).entryInfoList(QStringList() << "*", QDir::AllDirs | QDir::NoDotAndDotDot); for (int n=0; n < dir_list.count(); n++) { if (dir_list[n].isDir()) { qDebug("Playlist::addDirectory: adding directory: %s", dir_list[n].filePath().toUtf8().data()); addDirectory(dir_list[n].filePath()); } } } setModified(true); } void Playlist::onPlayListItemDeleteBtnClicked(const QStringList &filepathlist) { if (!filepathlist.isEmpty()) { // if (!filename.isEmpty()) { // MessageDialog msgDialog(0, tr("Confirm remove"), // tr("You're about to remove the file '%1' from the playlist.").arg(filename) + "
    "+ // tr("Are you sure you want to proceed?"), QMessageBox::Yes | QMessageBox::No); MessageDialog msgDialog(this, tr("Confirm remove"), tr("You're about to remove the file from the playlist.") + "
    "+ tr("Are you sure you want to proceed?"), QMessageBox::Yes | QMessageBox::No); if (msgDialog.exec() != -1) { if (msgDialog.standardButton(msgDialog.clickedButton()) == QMessageBox::Yes) { if (set) { if (filepathlist.contains(this->m_playlistView->getPlayingFile())) { this->setPlaying("", 0); } // Step 1: update pref->m_videoMap for (QString filepath : filepathlist) { foreach (VideoPtr videoPtr, pref->m_videoMap) { if (videoPtr->m_localpath == filepath) { pref->m_videoMap.remove(filepath); break; } } } // Step 2: update settings set->remove("playlist_contents"); set->beginGroup("playlist_contents"); set->beginWriteArray("items"); int index = 0; QMap::iterator i; for (i = pref->m_videoMap.begin(); i != pref->m_videoMap.end(); ++i) {//for (auto video : pref->remainingMaps) set->setArrayIndex(index); set->setValue(QString("item_%1_filename").arg(index), i.value()->localpath()); set->setValue(QString("item_%1_duration").arg(index), i.value()->duration()); set->setValue(QString("item_%1_name").arg(index), i.value()->name()); index ++; } set->endArray(); set->setValue("current_item", m_currentItemIndex); set->endGroup(); set->sync(); // Step3 : update ui this->m_playlistView->removeFilesFromPlayList(filepathlist); if (this->m_currentItemIndex > m_playlistView->getModelRowCount() -1) { this->setPlaying("", 0); } // Step4: update count if (!this->rowIsEmpty()) {//if (m_playlistView->getModelRowCount() > 0) { noVideoFrame->hide(); this->m_playlistView->show(); this->playNext();//Fixed bug: #4915 emit this->update_playlist_count(pref->m_videoMap.count()); } else { this->setPlaying("", 0); noVideoFrame->show(); this->m_playlistView->hide(); emit this->update_playlist_count(0); } // emit this->update_playlist_count(m_playlistView->getModelRowCount()); } //TODO:如果playingFile不存在于pref->m_videoMap中了,则更新current_item } } } } void Playlist::deleteSelectedFileFromDisk(const QStringList &filepathlist) { if (!allow_delete_from_disk) return; if (!filepathlist.isEmpty()) { // Ask the user for confirmation MessageDialog msgDialog(this, tr("Confirm deletion"), tr("You're about to Delete the files from your drive.") + "
    "+ tr("This action cannot be undone. Are you sure you want to proceed?"), QMessageBox::Yes | QMessageBox::No); if (msgDialog.exec() != -1) { if (msgDialog.standardButton(msgDialog.clickedButton()) == QMessageBox::Yes) { if (set) { if (filepathlist.contains(this->m_playlistView->getPlayingFile())) { this->setPlaying("", 0); } // Step 1: delete file from drive && update pref->m_videoMap QStringList deletedList; foreach(QString filepath, filepathlist) { QFileInfo fi(filepath); if (fi.exists() && fi.isFile() && fi.isWritable()) { // Delete file bool success = QFile::remove(filepath); if (success) { deletedList.append(filepath); // Remove item from the playlist if (pref->m_videoMap.contains(filepath)) { pref->m_videoMap.remove(filepath); } } } } // Step 2: update settings set->remove("playlist_contents"); set->beginGroup("playlist_contents"); set->beginWriteArray("items"); int index = 0; QMap::iterator i; for (i = pref->m_videoMap.begin(); i != pref->m_videoMap.end(); ++i) {//for (auto video : pref->remainingMaps) set->setArrayIndex(index); set->setValue(QString("item_%1_filename").arg(index), i.value()->localpath()); set->setValue(QString("item_%1_duration").arg(index), i.value()->duration()); set->setValue(QString("item_%1_name").arg(index), i.value()->name()); index ++; } set->endArray(); set->setValue("current_item", m_currentItemIndex); set->endGroup(); set->sync(); // Step3 : update ui this->m_playlistView->removeFilesFromPlayList(deletedList); if (this->m_currentItemIndex > m_playlistView->getModelRowCount() -1) { this->setPlaying("", 0); } // Step4: update count if (!this->rowIsEmpty()) {//if (m_playlistView->getModelRowCount() > 0) { noVideoFrame->hide(); this->m_playlistView->show(); this->playNext();//Fixed bug: #4915 emit this->update_playlist_count(pref->m_videoMap.count()); } else { this->setPlaying("", 0); noVideoFrame->show(); this->m_playlistView->hide(); emit this->update_playlist_count(0); } // emit this->update_playlist_count(m_playlistView->getModelRowCount()); } //TODO:如果playingFile不存在于pref->m_videoMap中了,则更新current_item } } } } void Playlist::removeAll() { MessageDialog msgDialog(this, tr("Confirm remove all"), tr("You're about to empty the playlist.") + "
    "+ tr("Are you sure you want to proceed?"), QMessageBox::Yes | QMessageBox::No); if (msgDialog.exec() != -1) { if (msgDialog.standardButton(msgDialog.clickedButton()) == QMessageBox::Yes) { if (set) { // stop play emit this->cleanPlaylistFinished(); emit this->requestSetPlayingTitle(""); // Step 1: update pref->m_videoMap pref->m_videoMap.clear(); // Step 2: update settings set->remove("playlist_contents"); // Step3 : update ui && update count clear(); setPlaylistFilename(""); //删除播放列表的时候,将存放视频文件详细信息的其他配置文件删除 CleanConfig::clean(Paths::configPath()); } } } } void Playlist::clearPlayedTag() { } int Playlist::chooseRandomItem() { QList fi; //List of not played items (free items) for (int row = 0; row < this->m_playlistView->getModelRowCount(); row++) { QString filepath = this->m_playlistView->getFileNameByRow(row); //Q_ASSERT(!filepath.isEmpty()); if (filepath.isEmpty()) continue; if (filepath != this->m_playlistView->getPlayingFile()) {//playlist_filename fi.append(row); } } if (fi.count() == 0) return -1; // none free //解决随机播放时,随机数大于播放列表总数时导致上一曲和下一曲按钮功能失效的问题 //int selected = (int) ((double) this->count() * rand()/(RAND_MAX+1.0)); int selected = (int) ((double) fi.count() * rand()/(RAND_MAX+1.0)); return fi[selected]; } void Playlist::upItem() { // qDebug("Playlist::upItem"); /*int current = listView->currentRow(); qDebug(" currentRow: %d", current ); moveItemUp(current);*/ /*QModelIndex index = listView->currentIndex(); QModelIndex s_index = proxy->mapToSource(index); QModelIndex prev = listView->model()->index(index.row()-1, 0); QModelIndex s_prev = proxy->mapToSource(prev); qDebug() << "Playlist::upItem: row:" << index.row() << "source row:" << s_index.row(); qDebug() << "Playlist::upItem: previous row:" << prev.row() << "previous source row:" << s_prev.row(); if (s_index.isValid() && s_prev.isValid()) { int row = s_index.row(); int prev_row = s_prev.row(); int pos_num_current = itemData(row)->position(); int pos_num_prev = itemData(prev_row)->position(); qDebug() << "Playlist::upItem: pos_num_current:" << pos_num_current << "pos_num_prev:" << pos_num_prev; itemData(row)->setPosition(pos_num_prev); itemData(prev_row)->setPosition(pos_num_current); QList cells = table->takeRow(row); table->insertRow(s_prev.row(), cells); listView->selectionModel()->setCurrentIndex(listView->model()->index(index.row()-1, 0), QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); setModified(true); }*/ } void Playlist::downItem() { /*qDebug("Playlist::downItem"); int current = listView->currentRow(); qDebug(" currentRow: %d", current ); moveItemDown(current);*/ /*QModelIndex index = listView->currentIndex(); QModelIndex s_index = proxy->mapToSource(index); QModelIndex next = listView->model()->index(index.row()+1, 0); QModelIndex s_next = proxy->mapToSource(next); qDebug() << "Playlist::downItem: row:" << index.row() << "source row:" << s_index.row(); qDebug() << "Playlist::downItem: next row:" << next.row() << "next source row:" << s_next.row(); if (s_index.isValid() && s_next.isValid()) { int row = s_index.row(); int next_row = s_next.row(); int pos_num_current = itemData(row)->position(); int pos_num_next = itemData(next_row)->position(); qDebug() << "Playlist::downItem: pos_num_current:" << pos_num_current << "pos_num_next:" << pos_num_next; itemData(row)->setPosition(pos_num_next); itemData(next_row)->setPosition(pos_num_current); QList cells = table->takeRow(row); table->insertRow(s_next.row(), cells); listView->selectionModel()->setCurrentIndex(listView->model()->index(index.row()+1, 0), QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); setModified(true); }*/ } void Playlist::moveItemUp(int current) { } void Playlist::moveItemDown(int current ) { } // Drag&drop void Playlist::dragEnterEvent( QDragEnterEvent *e ) { // qDebug("Playlist::dragEnterEvent"); if (e->mimeData()->hasUrls()) { e->acceptProposedAction(); } } //#endif void Playlist::copyURL() { qDebug("Playlist::copyURL"); /*QModelIndexList indexes = listView->selectionModel()->selectedRows(); int count = indexes.count(); QString text; for (int n = 0; n < count; n++) { QModelIndex s_index = proxy->mapToSource(indexes.at(n)); int current = s_index.row(); text += itemData(current)->filename(); if (n < count-1) { #ifdef Q_OS_WIN text += "\r\n"; #else text += "\n"; #endif } } if (!text.isEmpty()) QApplication::clipboard()->setText(text);*/ } void Playlist::openFolder() { qDebug("Playlist::openFolder"); /*QModelIndex index = listView->currentIndex(); if (!index.isValid()) return; QModelIndex s_index = proxy->mapToSource(index); int current = s_index.row(); PlayListItem * i = itemData(current); QString filename = i->filename(); qDebug() << "Playlist::openFolder: filename:" << filename; QFileInfo fi(filename); if (fi.exists()) { QString src_folder = fi.absolutePath(); QDesktopServices::openUrl(QUrl::fromLocalFile(src_folder)); }*/ } void Playlist::dropEvent( QDropEvent *e ) { // qDebug("Playlist::dropEvent"); QStringList files; if (e->mimeData()->hasUrls()) { QList l = e->mimeData()->urls(); QString s; for (int n=0; n < l.count(); n++) { if (l[n].isValid()) { //qDebug("Playlist::dropEvent: scheme: '%s'", l[n].scheme().toUtf8().data()); if (l[n].scheme() == "file") s = l[n].toLocalFile(); else s = l[n].toString(); /* qDebug(" * '%s'", l[n].toString().toUtf8().data()); qDebug(" * '%s'", l[n].toLocalFile().toUtf8().data()); */ //qDebug("Playlist::dropEvent: file: '%s'", s.toUtf8().data()); if (pref->m_videoMap.contains(s)) { continue; } files.append(s); } } } files.sort(); QStringList only_files; for (int n = 0; n < files.count(); n++) { if (QFileInfo(files[n] ).isDir()) { addDirectory(files[n]); } else { only_files.append(files[n]); } } if (only_files.count() == 1) { // Check if the file is a playlist QString filename = only_files[0]; QFileInfo fi(filename); QString extension = fi.suffix().toLower(); if (extension == "m3u8" || extension == "m3u") { load_m3u(filename); return; } else if (extension == "pls") { load_pls(filename); return; } else if (extension == "xspf") { loadXSPF(filename); return; } } addFiles(only_files); setModified(true); } void Playlist::hideEvent( QHideEvent * ) { } void Playlist::showEvent( QShowEvent * ) { } void Playlist::playerFailed(QProcess::ProcessError e) { emit this->requestSetPlayingTitle(""); if (ignore_player_errors) { if (e != QProcess::FailedToStart) { playNext(); } } } void Playlist::playerFinishedWithError(int e) { emit this->requestSetPlayingTitle(""); if (ignore_player_errors) { playNext(); } } void Playlist::maybeSaveSettings() { if (isModified()) { saveSettings(); } } void Playlist::onResortVideos(const QStringList &sortList, int index) { if (!set) return; if (sortList.isEmpty()) return; if (index > -1) { m_currentItemIndex = index; } //rewrite ini file set->remove("playlist_contents"); set->beginGroup("playlist_contents"); set->beginWriteArray("items"); for(int n=0; n < sortList.size(); n++) { QMap::iterator k; for (k = pref->m_videoMap.begin(); k != pref->m_videoMap.end(); ++k) { if (sortList.at(n) == k.key()) { set->setArrayIndex(n); set->setValue(QString("item_%1_filename").arg(n), k.value()->localpath()); set->setValue(QString("item_%1_duration").arg(n), k.value()->duration()); set->setValue(QString("item_%1_name").arg(n), k.value()->name()); break; } } } set->endArray(); set->setValue("current_item", m_currentItemIndex); set->endGroup(); set->sync(); //read form ini file pref->m_videoMap.clear(); set->beginGroup("playlist_contents"); int itemIndex = set->value("current_item", -1).toInt(); this->m_currentItemIndex = itemIndex; int count = set->beginReadArray("items"); // int count = set->value("count", 0).toInt(); QString filename, name; double duration; for (int n = 0; n < count; n++) { set->setArrayIndex(n); filename = set->value( QString("item_%1_filename").arg(n), "" ).toString(); duration = set->value( QString("item_%1_duration").arg(n), -1 ).toDouble(); name = set->value( QString("item_%1_name").arg(n), "" ).toString(); this->loadItemWithoutUI(filename, name, duration);//kobe add playlist contents if (index == n) { this->setPlaying(filename, itemIndex); } } set->endArray(); set->endGroup(); } void Playlist::updatePlayOrderSettings() { if (!set) return; set->beginGroup("playlist_contents"); set->setValue("play_order", (int) pref->play_order); set->endGroup(); set->sync(); } void Playlist::saveSettings() { if (!set) return; set->beginGroup("directories"); set->setValue("latest_dir", latest_dir); set->endGroup(); //Save current list set->remove("playlist_contents"); set->beginGroup("playlist_contents"); // set->setValue("count", (int)pl.count()); set->beginWriteArray("items"); int index = 0; QMap::iterator i; for (i = pref->m_videoMap.begin(); i != pref->m_videoMap.end(); ++i) { set->setArrayIndex(index); set->setValue(QString("item_%1_filename").arg(index), i.value()->localpath()); set->setValue(QString("item_%1_duration").arg(index), i.value()->duration()); set->setValue(QString("item_%1_name").arg(index), i.value()->name()); index ++; } //将会导致切换播放引擎时,播放列表被清空 /* for (int row = 0; row < this->m_playlistView->getModelRowCount(); row++ ) { QString filepath = this->m_playlistView->getFileNameByRow(row); //Q_ASSERT(!filepath.isEmpty()); if (filepath.isEmpty()) continue; QMap::iterator i; for (i = pref->m_videoMap.begin(); i != pref->m_videoMap.end(); ++i) { if (filepath == i.value()->localpath()) { set->setArrayIndex(index); set->setValue(QString("item_%1_filename").arg(index), i.value()->localpath()); set->setValue(QString("item_%1_duration").arg(index), i.value()->duration()); set->setValue(QString("item_%1_name").arg(index), i.value()->name()); index ++; break; } } }*/ set->endArray(); set->setValue("current_item", m_currentItemIndex); set->setValue("play_order", (int) pref->play_order); set->endGroup(); set->sync(); } void Playlist::loadSettings() { if (!set) return; /*QStringList groups = set->childGroups(); foreach (QString group, groups) {//列出所有子组 qDebug() << "group:" << group; }*/ //Load latest list set->beginGroup("playlist_contents"); //playlist_load_latest_dir = set->value("laylist_load_latest_dir", playlist_load_latest_dir).toString();//latest_dir 0526 pref->play_order = (Preferences::PlayOrder) set->value("play_order", (int) pref->play_order).toInt();//20170725 int index = set->value("current_item", -1).toInt(); int count = set->beginReadArray("items"); // int count = set->value("count", 0).toInt(); QString filename, name; double duration; for (int n = 0; n < count; n++) { set->setArrayIndex(n); filename = set->value( QString("item_%1_filename").arg(n), "" ).toString(); duration = set->value( QString("item_%1_duration").arg(n), -1 ).toDouble(); name = set->value(QString("item_%1_name").arg(n), "").toString(); this->loadSingleItem(filename, name, duration);//kobe add playlist contents if (index == n) { this->setPlaying(filename, index); } } set->endArray(); set->endGroup(); this->m_playlistView->updateScrollbarSize(); set->beginGroup("directories"); latest_dir = set->value("latest_dir", latest_dir).toString(); set->endGroup(); //界面播放引擎切换后,播放列表被清空的问题 // update ui this->m_playlistView->onPlayListChanged(); int currentCount = this->count(); emit this->update_playlist_count(currentCount); if (currentCount > 0) { noVideoFrame->setVisible(false); m_playlistView->setVisible(true); } else { m_currentItemIndex = 0; this->setPlaying("", 0); noVideoFrame->setVisible(true); m_playlistView->setVisible(false); } } QString Playlist::lastDir() { QString last_dir = latest_dir; return last_dir; } void Playlist::paintEvent(QPaintEvent *event) { Q_UNUSED(event); QStyleOption opt; opt.init(this); QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); // QPainter p(this); // p.setCompositionMode(QPainter::CompositionMode_Clear); // p.fillRect(rect(), Qt::SolidPattern);//p.fillRect(0, 0, this->width(), this->height(), Qt::SolidPattern); } kylin-video/src/displaylayercomposer.h0000644000175000017500000000252113517016402017141 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Kylin Ltd. * * Authors: * Kobe Lee xiangli@ubuntukylin.com/kobe24_lixiang@126.com * * 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; version 3. * * 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 DISPLAYLAYERCOMPOSER_H #define DISPLAYLAYERCOMPOSER_H #include #include #include "autohidecursorwidget.h" class DisplayLayerComposer : public AutoHideCursorWidget { Q_OBJECT public: DisplayLayerComposer(QWidget* parent = 0, Qt::WindowFlags f = 0); ~DisplayLayerComposer(); void setRepaintBackground(bool b); public slots: virtual void playingStarted(); virtual void playingStopped(); protected: virtual void paintEvent(QPaintEvent *e); private: bool m_repaintBackground; bool m_playing; }; #endif // DISPLAYLAYERCOMPOSER_H kylin-video/src/bottomcontroller.cpp0000644000175000017500000000320213517016402016627 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "bottomcontroller.h" #include BottomController::BottomController(QObject *parent) : QObject(parent) , m_timer(new QTimer(this)) { m_timer->setSingleShot(true); m_timer->setInterval(3 * 1000); connect(m_timer, SIGNAL(timeout()), this, SLOT(onTimeout())); } BottomController::~BottomController() { if (m_timer) { disconnect(m_timer, SIGNAL(timeout()), this, SLOT(onTimeout())); if(m_timer->isActive()) { m_timer->stop(); } delete m_timer; m_timer = nullptr; } } void BottomController::temporaryShow() { if (m_timer->isActive()) { m_timer->start(); return; } m_timer->start(); emit requestShow(); } void BottomController::permanentShow() { m_timer->stop(); emit requestShow(); } void BottomController::onTimeout() { m_timer->stop(); emit requestHide(); } kylin-video/src/autohidecursorwidget.h0000644000175000017500000000301513517016402017132 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Kylin Ltd. * * Authors: * Kobe Lee xiangli@ubuntukylin.com/kobe24_lixiang@126.com * * 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; version 3. * * 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 AUTOHIDECURSORWIDGET_H #define AUTOHIDECURSORWIDGET_H #include //#include #include #include class QLabel; class QTimer; class AutoHideCursorWidget : public QWidget { Q_OBJECT public: AutoHideCursorWidget(QWidget* parent = 0, Qt::WindowFlags f = 0); ~AutoHideCursorWidget(); void setAutoHideCursor(bool b); public slots: virtual void playingStarted(); virtual void playingStopped(); signals: void mouseMoved(QPoint); protected: virtual void mouseMoveEvent(QMouseEvent * e); protected slots: virtual void checkMousePos(); private: QTimer *m_checkMouseTimer = nullptr; QPoint m_mouseLastPosition; bool m_autohideCursor; int autohide_interval; }; #endif // AUTOHIDECURSORWIDGET_H kylin-video/src/remote_controller.xml0000644000175000017500000000123313517016402016775 0ustar fengfeng kylin-video/src/videowindow.h0000644000175000017500000000741313524205650015235 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Kylin Ltd. * * Authors: * Kobe Lee xiangli@ubuntukylin.com/kobe24_lixiang@126.com * * 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; version 3. * * 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 VIDEOWINDOW_H #define VIDEOWINDOW_H #include "autohidecursorwidget.h" #include "utils.h" class DisplayLayerComposer; #define DRAG_THRESHOLD 4 #define ZOOM_STEP 0.05 #define ZOOM_MIN 0.5 class VideoWindow : public AutoHideCursorWidget { Q_OBJECT public: VideoWindow(QWidget* parent = 0, Qt::WindowFlags f = 0); ~VideoWindow(); DisplayLayerComposer * displayLayer() { return m_displayLayer; }; void moveDisplayLayer(int m_offsetX, int m_offsetY); void setResolution( int w, int h); void setAspect( double asp); void setMonitorAspect(double asp); void updateVideoWindow(); void setColorKey(QColor c); void setOffsetX( int ); int offsetX(); void setOffsetY( int ); int offsetY(); void setZoom( double ); double zoom(); void allowVideoMovement(bool b) { m_allowVideoMovement = b; }; bool isVideoMovementAllowed() { return m_allowVideoMovement; }; void delayLeftClick(bool b) { m_delayLeftClick = b; }; bool isLeftClickDelayed() { return m_delayLeftClick; }; virtual QSize sizeHint () const; virtual QSize minimumSizeHint() const; virtual bool eventFilter(QObject *, QEvent *); bool animatedLogo() { return m_animatedLogo; } void setCornerWidget(QWidget * w); QWidget * cornerWidget() { return m_cornerWidget; }; public slots: void setLogoVisible(bool b); void showLogo() { setLogoVisible(true);}; void hideLogo() { setLogoVisible(false); }; void hideLogoForTemporary(); void updateLogoPosition(); void setAnimatedLogo(bool b) { m_animatedLogo = b; }; void moveLeft(); void moveRight(); void moveUp(); void moveDown(); void incZoom(); void decZoom(); void activateMouseDragTracking(bool active) { m_mouseDragTracking = active; } protected: virtual void resizeEvent(QResizeEvent * e); virtual void mouseReleaseEvent(QMouseEvent * e); virtual void mouseDoubleClickEvent(QMouseEvent *event); virtual void wheelEvent(QWheelEvent * e); signals: void doubleClicked(); void leftClicked(); void rightClicked(); void middleClicked(); void xbutton1Clicked(); // first X button void xbutton2Clicked(); // second X button void keyPressed(QKeyEvent * e); void wheelUp(); void wheelDown(); void mouseMovedDiff(QPoint); private: DragState m_dragState; QPoint m_startDrag; bool m_mouseDragTracking; int m_videoWidth, m_videoHeight; double m_aspect; double m_monitorAspect; DisplayLayerComposer *m_displayLayer = nullptr; QLabel *m_logoLabel = nullptr; bool m_stoped; // Zoom and moving int m_offsetX, m_offsetY; double m_zoomFactor; // Original pos and dimensions of the m_displayLayer before zooming or moving int m_origX, m_origY; int m_origWidth, m_origHeight; bool m_allowVideoMovement; // Delay left click event bool m_delayLeftClick; bool m_doubleClicked; bool m_animatedLogo; QTimer *m_leftClickTimer = nullptr; QWidget *m_cornerWidget = nullptr; }; #endif // VIDEOWINDOW_H kylin-video/src/maskwidget.cpp0000644000175000017500000000523613637124061015373 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "maskwidget.h" #include #include #include #include MaskWidget *MaskWidget::self = 0; MaskWidget::MaskWidget(QWidget *parent) : QWidget(parent) { this->resize(0,0); this->setWindowFlags(Qt::FramelessWindowHint); this->setAttribute(Qt::WA_StyledBackground); this->setStyleSheet("QWidget{background:rgba(0,0,0,200);}"); this->setAttribute(Qt::WA_DeleteOnClose); this->setWindowOpacity(0.7); QVBoxLayout *m_hlayout = new QVBoxLayout(this); m_hlayout->setContentsMargins(5, 5, 5, 5); m_hlayout->setSpacing(5); m_iconLabel = new QLabel(this); m_iconLabel->setFixedSize(16, 16); m_iconLabel->setStyleSheet("QLabel{border:none;background-color:transparent;}"); m_textLabel = new QLabel(this); m_textLabel->setStyleSheet("QLabel{border:none;background-color:transparent;color:#ffffff;font-size:14px;}"); m_textLabel->setText(tr("Loading...")); QFont font = m_textLabel->font(); const QFontMetrics fm(font); m_textLabel->setFixedWidth(fm.width(m_textLabel->text())); m_hlayout->addStretch(); m_hlayout->addWidget(m_iconLabel, 0, Qt::AlignHCenter); m_hlayout->addWidget(m_textLabel, 0, Qt::AlignHCenter); m_hlayout->addStretch(); m_movie = new QMovie(":/res/move.gif"); m_iconLabel->setMovie(m_movie); this->hide(); } MaskWidget::~MaskWidget() { if (m_movie) { delete m_movie; } } void MaskWidget::showMask() { if (!parent() || !this->parentWidget()) return; QRect parentRect = this->parentWidget()->window()->geometry(); this->setGeometry(0, 0, parentRect.width(), parentRect.height()); this->show(); } void MaskWidget::showEvent(QShowEvent *event) { QWidget::showEvent(event); if (m_movie) { m_movie->start(); } } void MaskWidget::hideEvent(QHideEvent* event) { QWidget::hideEvent(event); if (m_movie) { m_movie->stop(); } } kylin-video/src/playlistview.h0000644000175000017500000000724113517016402015427 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "datautils.h" class PlaylistModel; class PlaylistDelegate; #include class PlayListItem : public QStandardItem { public: PlayListItem(); PlayListItem(const QString filename, const QString name, double duration); ~PlayListItem(); void setFilename(const QString filename); void setName(const QString name); void setDuration(double duration); QString filename(); QString name(); double duration(); QString m_filename; QString m_name; double m_duration; }; class PlayListView : public QListView { Q_OBJECT public: explicit PlayListView(QSettings *set, QWidget *parent = 0); ~PlayListView(); const QModelIndex ¤tHoverIndex() const; QModelIndex findModelIndex(const VideoPtr video); void addPlayListItem(const QString &filepath, const QString &name, double duration); int getModelRowCount(); QStandardItem *getItemByRow(int row); QString getFileNameByRow(int row); void setPlayingInfo(const QString &filepath, int row); QString getPlayingFile(); void removeFilesFromPlayList(const QStringList &filelist); void updateScrollbarSize(); PlaylistModel *m_playlistModel; void onPlayListChanged(/*const VideoPtrList medialist*/); public slots: void onDoubleClicked(const QModelIndex & index); void onPlayActionTriggered(); void onRemoveAcionTriggered(); void onDeleteActionTriggered(); void removeSelectionBySelctionModel(QItemSelectionModel *selection); void removeSelectionByModelIndex(const QModelIndex &index); void onValueChanged(int value); void onCurrentHoverChanged(const QModelIndex &previous, const QModelIndex ¤t); void onItemEntered(const QModelIndex &index); void showContextMenu(const QPoint &pos); signals: void requestRemoveFiles(const QStringList &filepathlist); void requestDeleteVideos(const QStringList &filepathlist); void requestPlayVideo(int row, const QString filepath); void requestResortVideos(const QStringList &sortList, int index); void currentHoverChanged(const QModelIndex &previous, const QModelIndex ¤t); protected: virtual void dragEnterEvent(QDragEnterEvent *event) Q_DECL_OVERRIDE; virtual void startDrag(Qt::DropActions supportedActions) Q_DECL_OVERRIDE; virtual void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; virtual void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; virtual void enterEvent(QEvent *event) Q_DECL_OVERRIDE; virtual void leaveEvent(QEvent *event) Q_DECL_OVERRIDE; private: QScrollBar *m_scrollBar = nullptr; PlaylistDelegate *m_playlistDelegate = nullptr; QSettings *m_set = nullptr; QModelIndex m_selectedModelIndex; QModelIndex m_indexPrevious; QModelIndex m_indexCurrent; QString m_playingFile; }; kylin-video/src/messagedialog.h0000644000175000017500000000430313637124061015477 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 _MESSAGEDIALOG_H_ #define _MESSAGEDIALOG_H_ #include "utils.h" #include #include #include #include class QPushButton; class QPoint; class MessageDialog : public QDialog { Q_OBJECT public: MessageDialog(QWidget *parent = 0, const QString &title = "", const QString &text = "", QMessageBox::StandardButtons buttons = QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::StandardButton defaultButton = QMessageBox::Ok); ~MessageDialog(); QAbstractButton *clickedButton() const; QMessageBox::StandardButton standardButton(QAbstractButton *button) const; // void setDefaultButton(QPushButton *button); // void setDefaultButton(QMessageBox::StandardButton button); void setIcon(const QString &icon); void setDialogSize(int w, int h); void initConnect(); virtual bool eventFilter(QObject *, QEvent *); void moveDialog(QPoint diff); private slots: void onButtonClicked(QAbstractButton *button); private: int returnCodeByRun(QAbstractButton *button); private: QLabel *title_label = nullptr; QLabel *icon_label = nullptr; QLabel *msg_label = nullptr; QPushButton *close_Btn = nullptr; // QGridLayout *gridLayout; QVBoxLayout *main_layout = nullptr; QDialogButtonBox *buttonBox = nullptr; QAbstractButton *clickedBtn = nullptr; QAbstractButton *defaultBtn = nullptr; DragState m_dragState; QPoint m_startDrag; }; #endif kylin-video/src/aboutdialog.cpp0000644000175000017500000003351313637124061015525 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "aboutdialog.h" #include "../smplayer/images.h" #include "../smplayer/version.h" #include "../smplayer/global.h" #include "../smplayer/preferences.h" #include "../smplayer/paths.h" #include "../smplayer/inforeader.h" #if QT_VERSION >= 0x050000 #include "../smplayer/scrollermodule.h" #endif #include #include #include #include #include #include #include #include #define URL_HOMEPAGE "https://github.com/ukui/kylin-video" using namespace Global; AboutDialog::AboutDialog(const QString &snap, QWidget * parent, Qt::WindowFlags f) : QDialog(parent, f) , m_dragState(NOT_DRAGGING) , tab_state(TAB_ABOUT) , m_startDrag(QPoint(0,0)) , m_snap(snap) { setupUi(this); // this->setModal(true); this->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint); //this->setFixedSize(438, 320); this->setStyleSheet("QDialog{border: 1px solid #121212;border-radius:1px;background-color: #ffffff;}"); this->setWindowIcon(QIcon::fromTheme("kylin-video", QIcon(":/res/kylin-video.png"))); //this->setWindowIcon(QIcon::fromTheme("kylin-video", QIcon(":/res/kylin-video.png")).pixmap(QSize(64, 64)).scaled(64, 64, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); this->setAutoFillBackground(true); this->setMouseTracking(true); installEventFilter(this); #if QT_VERSION >= 0x050000 ScrollerModule::setScroller(aboutText->viewport()); ScrollerModule::setScroller(contributorText->viewport()); #endif // logo->setPixmap( QPixmap(":/default-theme/logo.png").scaledToHeight(64, Qt::SmoothTransformation) );//setPixmap( Images::icon("contributors" ) ); m_aboutGroup = NULL; m_contributorGroup = NULL; baseWidget->setAutoFillBackground(true); QPalette palette; palette.setBrush(QPalette::Background, QBrush(QPixmap(":/res/about_bg.png"))); baseWidget->setPalette(palette); closeBtn->setFocusPolicy(Qt::NoFocus); aboutBtn->setFocusPolicy(Qt::NoFocus); contributorBtn->setFocusPolicy(Qt::NoFocus); closeBtn->setStyleSheet("QPushButton{background-image:url(':/res/close_normal.png');border:0px;}QPushButton:hover{background:url(':/res/close_hover.png');}QPushButton:pressed{background:url(':/res/close_press.png');}"); // indicator->setStyleSheet("QLabel{background-image:url('://res/underline.png');background-position:center;}"); indicator->setStyleSheet("QLabel{background:#0a9ff5;background-position:center;}"); aboutBtn->setStyleSheet("QPushButton{background:transparent;border:none;text-align:center;font-family: 方正黑体_GBK;font-size:14px;color:#ffffff;}"); contributorBtn->setStyleSheet("QPushButton{background:transparent;border:none;text-align:center;font-family: 方正黑体_GBK;font-size:14px;color:#ffffff;}"); m_okBtn = buttonBox->button(QDialogButtonBox::Ok); m_okBtn->setFixedSize(91, 25); m_okBtn->setText(tr("OK")); m_okBtn->setFocusPolicy(Qt::NoFocus); m_okBtn->setStyleSheet("QPushButton{font-size:12px;background:#ffffff;border:1px solid #0a9ff5;color:#000000;}QPushButton:hover{background-color:#ffffff;border:1px solid #3f96e4;color:#000000;} QPushButton:pressed{background-color:#ffffff;border:1px solid #3f96e4;color:#000000;}"); this->initConnect(); this->initAnimation(); // InfoReader * i = InfoReader::obj(pref->mplayer_bin, this->m_snap); // i->getInfo(); // aboutText->setText( // "
    " + // tr("Kylin Video is a graphical interface for MPlayer and MPV.") + "
    " + // "" + tr("Kylin Video") + tr("Version: %1").arg(Version::printable()) + "" + "
    " + // tr("Using Qt %1 (compiled with Qt %2)").arg(qVersion()).arg(QT_VERSION_STR) + "
    " + // tr("Playback engine:") + i->playerVersion() + "

    " // ); // QString AboutDialog::link(const QString & url, QString name) // { // if (name.isEmpty()) name = url; // return QString("" + name +""); // } // SMPlayer contributorText->setText("
    © 2006-2015 Ricardo Villalba <rvm@users.sourceforge.net>
    © 2017-2019 lixiang <lixiang@kylinos.cn>

    "); //contributorText->setText(QString("
    © 2006-2015 Ricardo Villalba <rvm@users.sourceforge.net>
    © 2017-2019 lixiang <lixiang@kylinos.cn> %1

    ").arg("https://eightplus.github.io")); contributorText->hide(); adjustSize(); aboutText->setStyleSheet("QTextBrowser{background-color:transparent;border:none;font-family:方正黑体_GBK;font-size:12px;color:#999999;}"); contributorText->setStyleSheet("QTextBrowser{background-color:transparent;border:none;font-family:方正黑体_GBK;font-size:12px;color:#999999;}"); /*


    */ //QString scrollstyle= "QScrollBar:vertical {width: 12px;background: #141414;margin:0px 0px 0px 0px;border:1px solid #141414;}QScrollBar::handle:vertical {width: 12px;min-height: 45px;background: #292929;margin-left: 0px;margin-right: 0px;}QScrollBar::handle:vertical:hover {background: #3e3e3e;}QScrollBar::handle:vertical:pressed {background: #272727;}QScrollBar::sub-line:vertical {height: 6px;background: transparent;subcontrol-position: top;}QScrollBar::add-line:vertical {height: 6px;background: transparent;subcontrol-position: bottom;}QScrollBar::sub-line:vertical:hover {background: #292929;}QScrollBar::add-line:vertical:hover {background: #292929;}QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: transparent;}"; //aboutText->verticalScrollBar()->setStyleSheet(scrollstyle); aboutText->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); contributorText->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); aboutText->verticalScrollBar()->setStyleSheet("QScrollBar:vertical {width: 12px;background: #141414;margin:0px 0px 0px 0px;border:1px solid #141414;}QScrollBar::handle:vertical {width: 12px;min-height: 45px;background: #292929;margin-left: 0px;margin-right: 0px;}QScrollBar::handle:vertical:hover {background: #3e3e3e;}QScrollBar::handle:vertical:pressed {background: #272727;}QScrollBar::sub-line:vertical {height: 6px;background: transparent;subcontrol-position: top;}QScrollBar::add-line:vertical {height: 6px;background: transparent;subcontrol-position: bottom;}QScrollBar::sub-line:vertical:hover {background: #292929;}QScrollBar::add-line:vertical:hover {background: #292929;}QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: transparent;}"); contributorText->verticalScrollBar()->setStyleSheet("QScrollBar:vertical {width: 12px;background: #141414;margin:0px 0px 0px 0px;border:1px solid #141414;}QScrollBar::handle:vertical {width: 12px;min-height: 45px;background: #292929;margin-left: 0px;margin-right: 0px;}QScrollBar::handle:vertical:hover {background: #3e3e3e;}QScrollBar::handle:vertical:pressed {background: #272727;}QScrollBar::sub-line:vertical {height: 6px;background: transparent;subcontrol-position: top;}QScrollBar::add-line:vertical {height: 6px;background: transparent;subcontrol-position: bottom;}QScrollBar::sub-line:vertical:hover {background: #292929;}QScrollBar::add-line:vertical:hover {background: #292929;}QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: transparent;}"); this->adjustSize(); } AboutDialog::~AboutDialog() { if(m_aboutGroup != NULL) { delete m_aboutGroup; m_aboutGroup = NULL; } if(m_contributorGroup != NULL) { delete m_contributorGroup; m_contributorGroup = NULL; } } void AboutDialog::initConnect() { connect(closeBtn, SIGNAL(clicked()), this, SLOT(accept())); connect(m_okBtn, SIGNAL(clicked()), this, SLOT(accept())); connect(aboutBtn, SIGNAL(clicked()), this, SLOT(onAboutBtnClicked())); connect(contributorBtn, SIGNAL(clicked()), this, SLOT(onContributorBtnClicked())); } void AboutDialog::initAnimation() { QRect mainAcitonRect(230, 70, 85, 2); QRect origAcitonRect(320, 70, 85, 2); QPropertyAnimation *aboutAnimation = new QPropertyAnimation(indicator, "geometry"); aboutAnimation->setDuration(300); aboutAnimation->setStartValue(origAcitonRect); aboutAnimation->setEndValue(mainAcitonRect); m_aboutGroup = new QParallelAnimationGroup(this); m_aboutGroup->addAnimation(aboutAnimation); QPropertyAnimation *contributorAnimation = new QPropertyAnimation(indicator, "geometry"); contributorAnimation->setDuration(300); contributorAnimation->setStartValue(mainAcitonRect); contributorAnimation->setEndValue(origAcitonRect); m_contributorGroup = new QParallelAnimationGroup(this); m_contributorGroup->addAnimation(contributorAnimation); } void AboutDialog::setVersions() { InfoReader * i = InfoReader::obj(this->m_snap, pref->mplayer_bin);//20181212 i->getInfo(); aboutText->setText( "
    " + tr("Kylin Video is developed on the basis of %1, is a graphical interface for %2 and %3.").arg("SMPlayer").arg("MPlayer").arg("mpv") + "
    " + "" + tr("Kylin Video") + tr("Version: %1").arg(Version::printable()) + "" + "
    " + tr("Using Qt %1 (compiled with Qt %2)").arg(qVersion()).arg(QT_VERSION_STR) + "
    " + tr("Playback engine:") + i->playerVersion() + "

    " + ""+ tr("Links:") + "
    " + tr("Code website:") + " " + link(URL_HOMEPAGE) + "
    " + tr("Developer's personal home page:") + " " + link("https://eightplus.github.io") + "
    " ); } QString AboutDialog::link(const QString & url, QString name) { if (name.isEmpty()) name = url; return QString("" + name +""); } void AboutDialog::onAboutBtnClicked() { if (tab_state != TAB_ABOUT) { tab_state = TAB_ABOUT; m_aboutGroup->start(); aboutText->show(); contributorText->hide(); } } void AboutDialog::onContributorBtnClicked() { if (tab_state != TAB_CONTRIBUTOR) { tab_state = TAB_CONTRIBUTOR; m_contributorGroup->start(); contributorText->show(); aboutText->hide(); } } QSize AboutDialog::sizeHint () const { return QSize(438, 320); } void AboutDialog::moveDialog(QPoint diff) { #if QT_VERSION >= 0x050000 // Move the window with some delay. // Seems to work better with Qt 5 static QPoint d; static int count = 0; d += diff; count++; if (count > 3) { QPoint new_pos = pos() + d; if (new_pos.y() < 0) new_pos.setY(0); if (new_pos.x() < 0) new_pos.setX(0); move(new_pos); count = 0; d = QPoint(0,0); } #else move(pos() + diff); #endif } bool AboutDialog::eventFilter( QObject * object, QEvent * event ) { QEvent::Type type = event->type(); if (type != QEvent::MouseButtonPress && type != QEvent::MouseButtonRelease && type != QEvent::MouseMove) return false; QMouseEvent *mouseEvent = dynamic_cast(event); if (!mouseEvent) return false; if (mouseEvent->modifiers() != Qt::NoModifier) { m_dragState = NOT_DRAGGING; return false; } if (type == QEvent::MouseButtonPress) { if (mouseEvent->button() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } m_dragState = START_DRAGGING; m_startDrag = mouseEvent->globalPos(); // Don't filter, so others can have a look at it too return false; } if (type == QEvent::MouseButtonRelease) { if (m_dragState != DRAGGING || mouseEvent->button() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } // Stop dragging and eat event m_dragState = NOT_DRAGGING; event->accept(); return true; } // type == QEvent::MouseMove if (m_dragState == NOT_DRAGGING) return false; // buttons() note the s if (mouseEvent->buttons() != Qt::LeftButton) { m_dragState = NOT_DRAGGING; return false; } QPoint pos = mouseEvent->globalPos(); QPoint diff = pos - m_startDrag; if (m_dragState == START_DRAGGING) { // Don't start dragging before moving at least DRAG_THRESHOLD pixels if (abs(diff.x()) < 4 && abs(diff.y()) < 4) return false; m_dragState = DRAGGING; } this->moveDialog(diff); m_startDrag = pos; event->accept(); return true; } kylin-video/src/controllerworker.cpp0000644000175000017500000000273513517016402016646 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "controllerworker.h" #include #include #include ControllerWorker::ControllerWorker() { } ControllerWorker::~ControllerWorker() { } void ControllerWorker::playPause() { emit this->requestPlayPause(); } bool ControllerWorker::seek_forward(int seconds) { qDebug() << "seek_forward: " << seconds; emit this->requestSeekForward(seconds); return true; } bool ControllerWorker::seek_rewind(int seconds) { qDebug() << "seek_rewind: " << seconds; emit this->requestSeekRewind(seconds); return true; } void ControllerWorker::stop() { emit this->requestStop(); } void ControllerWorker::quit() { QTimer::singleShot(0, QApplication::instance(), SLOT(quit())); } kylin-video/src/systembutton.h0000644000175000017500000000265113517016402015453 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 SYSTEMBUTTON_H #define SYSTEMBUTTON_H #include #include #include class SystemButton : public QPushButton { Q_OBJECT public: explicit SystemButton(QWidget *parent = 0); void loadPixmap(QString pic_name); protected: void enterEvent(QEvent *); void leaveEvent(QEvent *); void mousePressEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); void paintEvent(QPaintEvent *); private: QPixmap pixmap; enum ButtonStatus{NORMAL, ENTER, PRESS}; ButtonStatus status; bool mouse_press; //按钮左键是否按下 int btn_width; int btn_height; }; #endif // SYSTEMBUTTON_H kylin-video/src/maskwidget.h0000644000175000017500000000302113517016402015022 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 MASKWIDGET_H #define MASKWIDGET_H #include #include class QMovie; class QLabel; class MaskWidget : public QWidget { Q_OBJECT public: explicit MaskWidget(QWidget *parent = 0); ~MaskWidget(); static MaskWidget *Instance() { static QMutex mutex; if (!self) { QMutexLocker locker(&mutex); if (!self) { self = new MaskWidget; } } return self; } void showMask(); protected: void showEvent(QShowEvent *event) Q_DECL_OVERRIDE; void hideEvent(QHideEvent* event) Q_DECL_OVERRIDE; private: static MaskWidget *self; QMovie *m_movie = nullptr; QLabel *m_iconLabel = nullptr; QLabel *m_textLabel = nullptr; }; #endif // MASKWIDGET_H kylin-video/src/playlist.h0000644000175000017500000001547313637124061014546 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 _PLAYLIST_H_ #define _PLAYLIST_H_ #include #include #include #include #include #include #include "../smplayer/mediadata.h" class PlayListView; class MyAction; class Core; class QMenu; class QSettings; class QToolButton; class QTimer; class QPushButton; class QLabel; class QHBoxLayout; class Playlist : public QFrame { Q_OBJECT public: enum AutoGetInfo { NoGetInfo = 0, GetInfo = 1, UserDefined = 2 }; enum M3UFormat { M3U = 0, M3U8 = 1, DetectFormat = 2 }; Playlist(Core *c, QWidget * parent = 0, Qt::WindowFlags f = Qt::Window); ~Playlist(); void setConfigPath(const QString & config_path); void clear(); int count(); bool isEmpty(); bool rowIsEmpty(); bool isModified() { return modified; }; void setPlaying(const QString &filepath, int index); void setViewHeight(); void createNoVideo(); void createTable(); void createToolbar(); void clearPlayedTag(); int chooseRandomItem(); // EDIT BY NEO --> // void sortBy(int section, bool revert, int count); // <-- QString lastDir(); void setPlaylistFilename(const QString &); QString playlistFilename() { return playlist_filename; }; void updateWindowTitle(); // Preferences void setDirectoryRecursion(bool b) { recursive_add_directory = b; }; void setAutoGetInfo(bool b) { automatically_get_info = b; }; void setPlayFilesFromStart(bool b) { play_files_from_start = b; }; void setIgnorePlayerErrors(bool b) { ignore_player_errors = b; }; void setStartPlayOnLoad(bool b) { start_play_on_load = b; }; void setAutomaticallyPlayNext(bool b) { automatically_play_next = b; }; bool directoryRecursion() { return recursive_add_directory; }; bool autoGetInfo() { return automatically_get_info; }; bool playFilesFromStart() { return play_files_from_start; }; bool ignorePlayerErrors() { return ignore_player_errors; }; bool startPlayOnLoad() { return start_play_on_load; }; bool automaticallyPlayNext() { return automatically_play_next; }; void allowDeleteFromDisk(bool enabled) { allow_delete_from_disk = enabled; }; bool isDeleteFromDiskAllowed() { return allow_delete_from_disk; }; public slots: void loadSingleItem(QString filename, QString name, double duration); void loadItemWithoutUI(QString filename, QString name, double duration); // Start playing, from item 0 if shuffle is off, or from // a random item otherwise void startPlayPause(); void playItem(int n); virtual void playNext(); virtual void playPrev(); void playNextAuto(); // Called from GUI when a file finished virtual void resumePlay(); virtual void removeAll(); virtual void onPlayListItemDeleteBtnClicked(const QStringList &filepathlist); virtual void moveItemUp(int); virtual void moveItemDown(int); virtual void popupDialogtoSelectFiles(); virtual void addDirectory(); // void addCurrentFile(); void addFiles(); void addUrls(); virtual void addFile(QString file, AutoGetInfo auto_get_info = UserDefined); virtual void addFiles(QStringList files, AutoGetInfo auto_get_info = UserDefined); // Adds a directory, no recursive virtual void addOneDirectory(QString dir); // Adds a directory, maybe with recursion (depends on user config) virtual void addDirectory(QString dir); // EDIT BY NEO --> // virtual void sortBy(int section); // <-- void deleteSelectedFileFromDisk(const QStringList &filelist); bool maybeSave(); void load(); bool saveCurrentPlaylist(); bool save(const QString & filename = QString::null); void load_m3u(QString file, M3UFormat format = DetectFormat); bool save_m3u(QString file); void load_pls(QString file); bool save_pls(QString file); void loadXSPF(const QString & filename); bool saveXSPF(const QString & filename); void setModified(bool); // Slots to connect from basegui void getMediaInfo(const MediaData &); void playerFailed(QProcess::ProcessError); void playerFinishedWithError(int); void itemActivated(const QModelIndex & index ); void upItem(); void downItem(); void copyURL(); void openFolder(); void saveSettings(); void updatePlayOrderSettings(); void loadSettings(); void maybeSaveSettings(); void onResortVideos(const QStringList &sortList, int index); void onPlayListItemDoubleClicked(int row, const QString &filename); void onPlayListChanged(const VideoPtrList medialist); signals: void playlistEnded(); void cleanPlaylistFinished(); void requestSetPlayingTitle(QString title); void update_playlist_count(int count); void closePlaylist(); void playListFinishedWithError(QString errorStr); void showMessage(QString text); void finish_list(); // void requestToAddCurrentFile(); void modifiedChanged(bool); void windowTitleChanged(const QString & title); void requestGetMediaInfo(const QStringList &files); protected: virtual void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; virtual void dragEnterEvent(QDragEnterEvent *) Q_DECL_OVERRIDE; virtual void dropEvent(QDropEvent *) Q_DECL_OVERRIDE; virtual void hideEvent(QHideEvent *) Q_DECL_OVERRIDE; virtual void showEvent(QShowEvent *) Q_DECL_OVERRIDE; private: QString playlist_path; QString playlist_filename; QString latest_dir; Core * m_core = nullptr; QFrame *noVideoFrame = nullptr; QLabel *novideo_icon = nullptr; QLabel *novideo_text = nullptr; QPushButton *add_Btn = nullptr; PlayListView *m_playlistView = nullptr; QLabel *titleLabel = nullptr; QFrame *btAddFrame = nullptr; QPushButton *btDel = nullptr; QPushButton *btAdd = nullptr; QSettings *set = nullptr; bool modified; int m_currentItemIndex; QTimer *save_timer = nullptr; QHBoxLayout *title_layout = nullptr; //Preferences bool recursive_add_directory; bool automatically_get_info; bool play_files_from_start; bool start_play_on_load; bool automatically_play_next; bool ignore_player_errors; bool allow_delete_from_disk; }; #endif kylin-video/src/supportformats.ui0000644000175000017500000000410313517016402016163 0ustar fengfeng SupportFormats 0 0 470 360 20 9 431 141 Video formats 10 24 411 100 true 20 160 431 91 Audio formats 10 24 411 50 true 20 259 431 91 Subtitles formats 10 24 411 50 true kylin-video/src/controllerworker.h0000644000175000017500000000240413517016402016304 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 CONTROLLER_WORKER_H #define CONTROLLER_WORKER_H #include class ControllerWorker : public QObject { Q_OBJECT public: explicit ControllerWorker(); ~ControllerWorker(); public slots: void playPause(); bool seek_forward(int seconds); bool seek_rewind(int seconds); void stop(); void quit(); signals: void requestSeekForward(int seconds); void requestSeekRewind(int seconds); void requestPlayPause(); void requestStop(); }; #endif // CONTROLLER_WORKER_H kylin-video/src/supportformats.cpp0000644000175000017500000001227513517016402016341 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "supportformats.h" #include #include #include "../smplayer/extensions.h" SupportFormats::SupportFormats(QWidget * parent, Qt::WindowFlags f) : QWidget(parent, f ) { setupUi(this); retranslateStrings(); } SupportFormats::~SupportFormats() { } void SupportFormats::retranslateStrings() { retranslateUi(this); groupBox_video->setStyleSheet("QGroupBox{border:none;margin-top:20px;font-size:14px;}QGroupBox:title{subcontrol-origin: margin;subcontrol-position: top left;padding: 0px 1px;color: #999999;font-family: 方正黑体_GBK;font-weight:bold;}"); groupBox_audio->setStyleSheet("QGroupBox{border:none;margin-top:20px;font-size:14px;}QGroupBox:title{subcontrol-origin: margin;subcontrol-position: top left;padding: 0px 1px;color: #999999;font-family: 方正黑体_GBK;font-weight:bold;}"); groupBox_subtitles->setStyleSheet("QGroupBox{border:none;margin-top:20px;font-size:14px;}QGroupBox:title{subcontrol-origin: margin;subcontrol-position: top left;padding: 0px 1px;color: #999999;font-family: 方正黑体_GBK;font-weight:bold;}"); vedio_edit->setStyleSheet("QTextEdit {border: 1px solid #000000;color: #999999;background: #0f0f0f;font-family:方正黑体_GBK;font-size: 12px;}"); vedio_edit->verticalScrollBar()->setStyleSheet("QScrollBar:vertical {width: 12px;background: #141414;margin:0px 0px 0px 0px;border:1px solid #141414;}QScrollBar::handle:vertical {width: 12px;min-height: 45px;background: #292929;margin-left: 0px;margin-right: 0px;}QScrollBar::handle:vertical:hover {background: #3e3e3e;}QScrollBar::handle:vertical:pressed {background: #272727;}QScrollBar::sub-line:vertical {height: 6px;background: transparent;subcontrol-position: top;}QScrollBar::add-line:vertical {height: 6px;background: transparent;subcontrol-position: bottom;}QScrollBar::sub-line:vertical:hover {background: #292929;}QScrollBar::add-line:vertical:hover {background: #292929;}QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: transparent;}"); audio_edit->setStyleSheet("QTextEdit {border: 1px solid #000000;color: #999999;background: #0f0f0f;font-family:方正黑体_GBK;font-size: 12px;}"); audio_edit->verticalScrollBar()->setStyleSheet("QScrollBar:vertical {width: 12px;background: #141414;margin:0px 0px 0px 0px;border:1px solid #141414;}QScrollBar::handle:vertical {width: 12px;min-height: 45px;background: #292929;margin-left: 0px;margin-right: 0px;}QScrollBar::handle:vertical:hover {background: #3e3e3e;}QScrollBar::handle:vertical:pressed {background: #272727;}QScrollBar::sub-line:vertical {height: 6px;background: transparent;subcontrol-position: top;}QScrollBar::add-line:vertical {height: 6px;background: transparent;subcontrol-position: bottom;}QScrollBar::sub-line:vertical:hover {background: #292929;}QScrollBar::add-line:vertical:hover {background: #292929;}QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: transparent;}"); subtitles_edit->setStyleSheet("QTextEdit {border: 1px solid #000000;color: #999999;background: #0f0f0f;font-family:方正黑体_GBK;font-size: 12px;}"); subtitles_edit->verticalScrollBar()->setStyleSheet("QScrollBar:vertical {width: 12px;background: #141414;margin:0px 0px 0px 0px;border:1px solid #141414;}QScrollBar::handle:vertical {width: 12px;min-height: 45px;background: #292929;margin-left: 0px;margin-right: 0px;}QScrollBar::handle:vertical:hover {background: #3e3e3e;}QScrollBar::handle:vertical:pressed {background: #272727;}QScrollBar::sub-line:vertical {height: 6px;background: transparent;subcontrol-position: top;}QScrollBar::add-line:vertical {height: 6px;background: transparent;subcontrol-position: bottom;}QScrollBar::sub-line:vertical:hover {background: #292929;}QScrollBar::add-line:vertical:hover {background: #292929;}QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: transparent;}"); QString video_tip = QString(tr("Some video formats do not support preview and seek by dragging, e.g. the swf.")); vedio_edit->setToolTip(""+ video_tip +""); } void SupportFormats::setData() { vedio_edit->clear(); audio_edit->clear(); subtitles_edit->clear(); Extensions e; vedio_edit->setText(e.video().forFilter()); audio_edit->setText(e.audio().forFilter()); subtitles_edit->setText(e.subtitles().forFilter()); vedio_edit->verticalScrollBar()->setValue(0); audio_edit->verticalScrollBar()->setValue(0); subtitles_edit->verticalScrollBar()->setValue(0); } //#include "moc_supportformats.cpp" kylin-video/src/shortcutswidget.cpp0000644000175000017500000006525513517016402016501 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "shortcutswidget.h" #include #include #include #include #include #include #include #include "../smplayer/helper.h" #include "../smplayer/global.h" #include "../smplayer/preferences.h" using namespace Global; ShortcutsWidget *ShortcutsWidget::self = 0; ShortcutsWidget::ShortcutsWidget(QWidget *parent) : QWidget(parent) { this->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool | Qt::WindowStaysOnTopHint); this->setWindowTitle(tr("Kylin Video - Shortcuts")); timer = NULL; parent_widget = 0; title_label = NULL; control_title_label = NULL; other_title_label = NULL; close_button = NULL; // control_form_layout = NULL; control_grid_layout = NULL; other_grid_layout = NULL; set_widget_opacity(0.7); set_background_color(QColor(0, 0, 0)); this->init_ui(); } ShortcutsWidget::~ShortcutsWidget() { self = 0; if (timer != NULL) { disconnect(timer,SIGNAL(timeout()),this,SLOT(hide_mask_widget())); if(timer->isActive()) { timer->stop(); } delete timer; timer = NULL; } if (title_label != NULL) { delete title_label; title_label = NULL; } if (control_title_label != NULL) { delete control_title_label; control_title_label = NULL; } if (other_title_label != NULL) { delete other_title_label; other_title_label = NULL; } if (close_button != NULL) { delete close_button; close_button = NULL; } while(control_grid_layout != NULL && control_grid_layout->count() > 0) { QWidget *widget = control_grid_layout->itemAt(0)->widget(); control_grid_layout->removeWidget(widget); delete widget; widget = NULL; } // for (int i=0; i < control_label_list.count(); i++) { // control_grid_layout->removeWidget(control_label_list[i]); //// control_form_layout->removeWidget(control_label_list[i]); // delete control_label_list[i]; // control_label_list[i] = NULL; // } // control_label_list.clear(); if (control_grid_layout != NULL) { delete control_grid_layout; control_grid_layout = NULL; } if (other_title_label != NULL) { delete other_title_label; other_title_label = NULL; } // for (int j=0; j < other_label_list.count(); j++) { // other_grid_layout->removeWidget(other_label_list[j]); // delete other_label_list[j]; // other_label_list[j] = NULL; // } // other_label_list.clear(); while(other_grid_layout != NULL && other_grid_layout->count() > 0) { QWidget *widget = other_grid_layout->itemAt(0)->widget(); other_grid_layout->removeWidget(widget); delete widget; widget = NULL; } if (other_grid_layout != NULL) { delete other_grid_layout; other_grid_layout = NULL; } // if(control_form_layout != NULL) // { // delete control_form_layout; // control_form_layout = NULL; // } } void ShortcutsWidget::set_parent_widget(QWidget *widget) { if (this->parent_widget != widget) { this->parent_widget = widget; } } void ShortcutsWidget::setPrefData(Preferences *pref) { forward_10s_title->setText(tr("Forward %1").arg(Helper::timeForJumps(pref->seeking1))); forward_1m_title->setText(tr("Forward %1").arg(Helper::timeForJumps(pref->seeking2))); forward_10m_title->setText(tr("Forward %1").arg(Helper::timeForJumps(pref->seeking3))); back_10s_title->setText(tr("Rewind %1").arg(Helper::timeForJumps(pref->seeking1))); back_1m_title->setText(tr("Rewind %1").arg(Helper::timeForJumps(pref->seeking2))); back_10m_title->setText(tr("Rewind %1").arg(Helper::timeForJumps(pref->seeking3))); } void ShortcutsWidget::init_ui() { control_grid_layout = new QGridLayout; control_grid_layout->setSpacing(10); control_grid_layout->setContentsMargins(0, 0, 0, 0); other_grid_layout = new QGridLayout; other_grid_layout->setSpacing(10); other_grid_layout->setContentsMargins(0, 0, 0, 0); title_label = new QLabel(); title_label->setText(tr("Kylin Video - Shortcuts")); title_label->setFrameShape(QFrame::NoFrame); title_label->setStyleSheet("QLabel{background:transparent;font-size:16px;color:#ffffff;font-family:方正黑体_GBK;}"); title_label->adjustSize(); control_title_label = new QLabel(); control_title_label->setText(tr("Play control")); control_title_label->setFrameShape(QFrame::NoFrame); control_title_label->setStyleSheet("QLabel{background:transparent;font-size:14px;color:#ffffff;font-family:方正黑体_GBK;}"); control_title_label->adjustSize(); other_title_label = new QLabel(); other_title_label->setText(tr("Other control")); other_title_label->setFrameShape(QFrame::NoFrame); other_title_label->setStyleSheet("QLabel{background:transparent;font-size:14px;color:#ffffff;font-family:方正黑体_GBK;}"); other_title_label->adjustSize(); close_button = new QPushButton(); close_button->setFixedSize(91, 25); close_button->setText(tr("Close")); close_button->setFocusPolicy(Qt::NoFocus); close_button->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); connect(close_button, SIGNAL(clicked(bool)), this, SLOT(onCloseButtonClicked())); // close_button->setAutoDefault(true); // close_button->setFocus(); // QWidget::setTabOrder(close_button, title_label); /*control_form_layout = new QFormLayout(); // control_form_layout->setSizeConstraint(QLayout::SetFixedSize);//frame will fixed with content's width control_form_layout->setSpacing(10); control_form_layout->setHorizontalSpacing(10); control_form_layout->setRowWrapPolicy(QFormLayout::DontWrapRows); control_form_layout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);*/ play_title = new QLabel(); play_title->setText(tr("Play/Pause")); play_title->setFrameShape(QFrame::NoFrame); play_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); play_title->adjustSize(); control_grid_layout->addWidget(play_title,0,0); // control_label_list.append(play_title); play_label = new QLabel(); play_label->setText("Space"); play_label->setFrameShape(QFrame::NoFrame); play_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); play_label->adjustSize(); control_grid_layout->addWidget(play_label,0,1); // control_label_list.append(play_label); // control_form_layout->addRow(tr("Play/Pause"), play_label); play_pre_title = new QLabel(); play_pre_title->setText(tr("Previous")); play_pre_title->setFrameShape(QFrame::NoFrame); play_pre_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); play_pre_title->adjustSize(); control_grid_layout->addWidget(play_pre_title,1,0); // control_label_list.append(play_pre_title); play_pre_label = new QLabel(); play_pre_label->setText(pref->prev_key); play_pre_label->setFrameShape(QFrame::NoFrame); play_pre_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); play_pre_label->adjustSize(); control_grid_layout->addWidget(play_pre_label,1,1); // control_label_list.append(play_pre_label); play_next_title = new QLabel(); play_next_title->setText(tr("Next")); play_next_title->setFrameShape(QFrame::NoFrame); play_next_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); play_next_title->adjustSize(); control_grid_layout->addWidget(play_next_title,2,0); // control_label_list.append(play_next_title); play_next_label = new QLabel(); play_next_label->setText(pref->next_key);//">, Media Next" play_next_label->setFrameShape(QFrame::NoFrame); play_next_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); play_next_label->adjustSize(); control_grid_layout->addWidget(play_next_label,2,1); // control_label_list.append(play_next_label); forward_10s_title = new QLabel(); forward_10s_title->setFrameShape(QFrame::NoFrame); forward_10s_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); forward_10s_title->adjustSize(); control_grid_layout->addWidget(forward_10s_title,3,0); // control_label_list.append(forward_10s_title); forward_10s_label = new QLabel(); forward_10s_label->setText("Right(→)"); forward_10s_label->setFrameShape(QFrame::NoFrame); forward_10s_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); forward_10s_label->adjustSize(); control_grid_layout->addWidget(forward_10s_label,3,1); // control_label_list.append(forward_10s_label); forward_1m_title = new QLabel(); forward_1m_title->setFrameShape(QFrame::NoFrame); forward_1m_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); forward_1m_title->adjustSize(); control_grid_layout->addWidget(forward_1m_title,4,0); // control_label_list.append(forward_1m_title); forward_1m_label = new QLabel(); forward_1m_label->setText("Up(↑)"); forward_1m_label->setFrameShape(QFrame::NoFrame); forward_1m_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); forward_1m_label->adjustSize(); control_grid_layout->addWidget(forward_1m_label,4,1); // control_label_list.append(forward_1m_label); forward_10m_title = new QLabel(); forward_10m_title->setFrameShape(QFrame::NoFrame); forward_10m_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); forward_10m_title->adjustSize(); control_grid_layout->addWidget(forward_10m_title,5,0); // control_label_list.append(forward_10m_title); forward_10m_label = new QLabel(); forward_10m_label->setText("PgUp"); forward_10m_label->setFrameShape(QFrame::NoFrame); forward_10m_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); forward_10m_label->adjustSize(); control_grid_layout->addWidget(forward_10m_label,5,1); // control_label_list.append(forward_10m_label); back_10s_title = new QLabel(); back_10s_title->setFrameShape(QFrame::NoFrame); back_10s_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); back_10s_title->adjustSize(); control_grid_layout->addWidget(back_10s_title,6,0); // control_label_list.append(back_10s_title); back_10s_label = new QLabel(); back_10s_label->setText("Left(←)"); back_10s_label->setFrameShape(QFrame::NoFrame); back_10s_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); back_10s_label->adjustSize(); control_grid_layout->addWidget(back_10s_label,6,1); // control_label_list.append(back_10s_label); back_1m_title = new QLabel(); back_1m_title->setFrameShape(QFrame::NoFrame); back_1m_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); back_1m_title->adjustSize(); control_grid_layout->addWidget(back_1m_title,7,0); // control_label_list.append(back_1m_title); back_1m_label = new QLabel(); back_1m_label->setText("Down(↓)"); back_1m_label->setFrameShape(QFrame::NoFrame); back_1m_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); back_1m_label->adjustSize(); control_grid_layout->addWidget(back_1m_label,7,1); // control_label_list.append(back_1m_label); back_10m_title = new QLabel(); back_10m_title->setFrameShape(QFrame::NoFrame); back_10m_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); back_10m_title->adjustSize(); control_grid_layout->addWidget(back_10m_title,8,0); // control_label_list.append(back_10m_title); back_10m_label = new QLabel(); back_10m_label->setText("PgDn"); back_10m_label->setFrameShape(QFrame::NoFrame); back_10m_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); back_10m_label->adjustSize(); control_grid_layout->addWidget(back_10m_label,8,1); // control_label_list.append(back_10m_label); jump_title = new QLabel(); jump_title->setText(tr("Jump to...")); jump_title->setFrameShape(QFrame::NoFrame); jump_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); play_next_title->adjustSize(); control_grid_layout->addWidget(jump_title,9,0); // control_label_list.append(jump_title); jump_label = new QLabel(); jump_label->setText("Ctrl + J"); jump_label->setFrameShape(QFrame::NoFrame); jump_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); jump_label->adjustSize(); control_grid_layout->addWidget(jump_label,9,1); // control_label_list.append(jump_label); mute_title = new QLabel(); mute_title->setText(tr("Mute")); mute_title->setFrameShape(QFrame::NoFrame); mute_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); mute_title->adjustSize(); control_grid_layout->addWidget(mute_title,10,0); // control_label_list.append(mute_title); mute_label = new QLabel(); mute_label->setText("M"); mute_label->setFrameShape(QFrame::NoFrame); mute_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); mute_label->adjustSize(); control_grid_layout->addWidget(mute_label,10,1); // control_label_list.append(mute_label); vol_up_title = new QLabel(); vol_up_title->setText(tr("Volume +")); vol_up_title->setFrameShape(QFrame::NoFrame); vol_up_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); vol_up_title->adjustSize(); control_grid_layout->addWidget(vol_up_title,11,0); // control_label_list.append(vol_up_title); vol_up_label = new QLabel(); vol_up_label->setText("0"); vol_up_label->setFrameShape(QFrame::NoFrame); vol_up_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); vol_up_label->adjustSize(); control_grid_layout->addWidget(vol_up_label,11,1); // control_label_list.append(vol_up_label); vol_down_title = new QLabel(); vol_down_title->setText(tr("Volume -")); vol_down_title->setFrameShape(QFrame::NoFrame); vol_down_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); vol_down_title->adjustSize(); control_grid_layout->addWidget(vol_down_title,12,0); // control_label_list.append(vol_down_title); vol_down_label = new QLabel(); vol_down_label->setText("9"); vol_down_label->setFrameShape(QFrame::NoFrame); vol_down_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); vol_down_label->adjustSize(); control_grid_layout->addWidget(vol_down_label,12,1); // control_label_list.append(vol_down_label); set_audio_delay_title = new QLabel(); set_audio_delay_title->setText(tr("Set audio delay")); set_audio_delay_title->setFrameShape(QFrame::NoFrame); set_audio_delay_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); set_audio_delay_title->adjustSize(); control_grid_layout->addWidget(set_audio_delay_title,13,0); // control_label_list.append(set_audio_delay_title); set_audio_delay_label = new QLabel(); set_audio_delay_label->setText("Y"); set_audio_delay_label->setFrameShape(QFrame::NoFrame); set_audio_delay_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); set_audio_delay_label->adjustSize(); control_grid_layout->addWidget(set_audio_delay_label,13,1); // control_label_list.append(set_audio_delay_label); audio_delay_title = new QLabel(); audio_delay_title->setText(tr("Increase or decrease audio delay")); audio_delay_title->setFrameShape(QFrame::NoFrame); audio_delay_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); audio_delay_title->adjustSize(); control_grid_layout->addWidget(audio_delay_title,14,0); // control_label_list.append(audio_delay_title); audio_delay_label = new QLabel(); audio_delay_label->setText("+ / - / ="); audio_delay_label->setFrameShape(QFrame::NoFrame); audio_delay_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); audio_delay_label->adjustSize(); control_grid_layout->addWidget(audio_delay_label,14,1); // control_label_list.append(audio_delay_label); playlist_title = new QLabel(); playlist_title->setText(tr("Playlist")); playlist_title->setFrameShape(QFrame::NoFrame); playlist_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); playlist_title->adjustSize(); other_grid_layout->addWidget(playlist_title,0,0); playlist_label = new QLabel(); playlist_label->setText(pref->playlist_key);//F3 playlist_label->setFrameShape(QFrame::NoFrame); playlist_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); playlist_label->adjustSize(); other_grid_layout->addWidget(playlist_label,0,1); open_title = new QLabel(); open_title->setText(tr("Open File")); open_title->setFrameShape(QFrame::NoFrame); open_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); open_title->adjustSize(); other_grid_layout->addWidget(open_title,1,0); // other_label_list.append(open_title); open_label = new QLabel(); open_label->setText("Ctrl + F"); open_label->setFrameShape(QFrame::NoFrame); open_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); open_label->adjustSize(); other_grid_layout->addWidget(open_label,1,1); // other_label_list.append(open_label); screenshot_title = new QLabel(); screenshot_title->setText(tr("Screenshot")); screenshot_title->setFrameShape(QFrame::NoFrame); screenshot_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); screenshot_title->adjustSize(); other_grid_layout->addWidget(screenshot_title,2,0); // other_label_list.append(screenshot_title); screenshot_label = new QLabel(); screenshot_label->setText("S"); screenshot_label->setFrameShape(QFrame::NoFrame); screenshot_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); screenshot_label->adjustSize(); other_grid_layout->addWidget(screenshot_label,2,1); // other_label_list.append(screenshot_label); pref_title = new QLabel(); pref_title->setText(tr("Preferences")); pref_title->setFrameShape(QFrame::NoFrame); pref_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); pref_title->adjustSize(); other_grid_layout->addWidget(pref_title,3,0); // other_label_list.append(pref_title); pref_label = new QLabel(); pref_label->setText("Ctrl + P"); pref_label->setFrameShape(QFrame::NoFrame); pref_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); pref_label->adjustSize(); other_grid_layout->addWidget(pref_label,3,1); // other_label_list.append(pref_label); info_title = new QLabel(); info_title->setText(tr("View info and properties...")); info_title->setFrameShape(QFrame::NoFrame); info_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); info_title->adjustSize(); other_grid_layout->addWidget(info_title,4,0); // other_label_list.append(info_title); info_label = new QLabel(); info_label->setText("Ctrl + I"); info_label->setFrameShape(QFrame::NoFrame); info_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); info_label->adjustSize(); other_grid_layout->addWidget(info_label,4,1); // other_label_list.append(info_label); about_title = new QLabel(); about_title->setText(tr("About")); about_title->setFrameShape(QFrame::NoFrame); about_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); about_title->adjustSize(); other_grid_layout->addWidget(about_title,5,0); about_label = new QLabel(); about_label->setText("Ctrl + A"); about_label->setFrameShape(QFrame::NoFrame); about_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); about_label->adjustSize(); other_grid_layout->addWidget(about_label,5,1); quit_title = new QLabel(); quit_title->setText(tr("Quit")); quit_title->setFrameShape(QFrame::NoFrame); quit_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); quit_title->adjustSize(); other_grid_layout->addWidget(quit_title,6,0); quit_label = new QLabel(); quit_label->setText("Ctrl + Q"); quit_label->setFrameShape(QFrame::NoFrame); quit_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); quit_label->adjustSize(); other_grid_layout->addWidget(quit_label,6,1); fullscreen_title = new QLabel(); fullscreen_title->setText(tr("FullScreen/Cancel fullScreen")); fullscreen_title->setFrameShape(QFrame::NoFrame); fullscreen_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); fullscreen_title->adjustSize(); other_grid_layout->addWidget(fullscreen_title,7,0); fullscreen_label = new QLabel(); fullscreen_label->setText("Ctrl + Enter"); fullscreen_label->setFrameShape(QFrame::NoFrame); fullscreen_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); fullscreen_label->adjustSize(); other_grid_layout->addWidget(fullscreen_label,7,1); QVBoxLayout *lhlayout = new QVBoxLayout; lhlayout->setSpacing(10); lhlayout->addWidget(control_title_label); lhlayout->addLayout(control_grid_layout); lhlayout->addStretch(); QVBoxLayout *rhlayout = new QVBoxLayout; rhlayout->setSpacing(10); rhlayout->addWidget(other_title_label); rhlayout->addLayout(other_grid_layout); rhlayout->addStretch(); QHBoxLayout *hlayout = new QHBoxLayout; hlayout->addStretch(); // hlayout->addLayout(control_form_layout); hlayout->addLayout(lhlayout); hlayout->addStretch(); hlayout->addLayout(rhlayout); hlayout->addStretch(); QVBoxLayout *layout = new QVBoxLayout; layout->setContentsMargins(10, 40, 10, 30); layout->setSpacing(20); // layout->setSizeConstraint(QLayout::SetFixedSize); layout->addWidget(title_label); layout->addStretch(); layout->addLayout(hlayout); layout->addStretch(); layout->addWidget(close_button, 0, Qt::AlignHCenter); this->setLayout(layout); } void ShortcutsWidget::onCloseButtonClicked() { if (timer->isActive()) timer->stop(); this->hide_mask_widget(); } void ShortcutsWidget::restart_timer() { if (timer == NULL) { timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(hide_mask_widget())); timer->setInterval(10000); } if (timer->isActive()) timer->stop(); timer->start(); } void ShortcutsWidget::set_widget_opacity(double opacity) { this->setWindowOpacity(opacity); } void ShortcutsWidget::set_background_color(const QColor &bgColor) { QPalette palette = this->palette(); palette.setBrush(QPalette::Background, bgColor); this->setPalette(palette); } void ShortcutsWidget::showEvent(QShowEvent *) { if (parent_widget != 0) { this->setGeometry(parent_widget->geometry()); } } void ShortcutsWidget::hide_mask_widget() { if (this->isVisible()) { this->hide(); } } //void ShortcutsWidget::keyReleaseEvent(QKeyEvent *event) { // if (this->isVisible()) { // this->hide(); // } // QWidget::keyReleaseEvent(event); //} kylin-video/src/res/0000755000175000017500000000000013637124061013313 5ustar fengfengkylin-video/src/res/background.png0000644000175000017500000032313613625147453016157 0ustar fengfengPNG  IHDRZb pHYs  iTXtXML:com.adobe.xmp ~IDATxy%YQ';y{UյRwɎ ."3" Χ "8и  .#  *"ltW^۫z۽'OD8'3~u3g8K:"¬o[uu ˆչmѢݪP3+Y$(eT8N'u'%p,Y!0SLi -\bEg{iS[f9@Cz9KSת gMw1$NQx'rI5Pij>L::f#nZ4/xA;~se*w}0"Ѓ,-^7Yv !o'; Yy& 8{zq4DlYxG$>*e&k6(duV3\ Zשҳ09J{& QfGl׺YH,4x< (Է-pH7^Ћb\7 ;L,xyvosRHY.:i}$QHW:=ާ*"]NAH+̗*kGNSNhO}ץ֜Rʚ61,wuwP3;  hKw'hJ`\)<@1HMvW[[lHxi)[9 :FIѴ5m.d,HVVYSjXL真;EiI >-Ƌ~RtQ1Umq/w ŢݓjN~N{{Sjt$QiƁޔ:w uC#Nc] .".J8>yiRgςĝL obi"[@,zvSnYVYÂW^yYR˧>$OMO2mYƤi/,L fv-:h* =xװ}S(mRcATS_#NǤh{g5G,p$.2U k3a;EyZz Ë`"<#g)O]LE6`U82)\;Lϳ<56Id [[ww(ƩҤv>-OEw:*.< ԵX} w=-O};ڝv Tsc2mibV ''zd)_h9$]누߶e*5L|[w༾2a#ĝY"xϥf'j$,SYAKp NE75w 6 zX''=LH^+겎,4&`q24i_"X58vDi2pyGB} -زR";i}T}68;ץzTmTXeԖ [ԅ4fީeM ,H\$J5t8dт8)2.M`yH4 ]晞 *޾MӐ9Y0J?^3's:H2}~7 :)Y(T<~'u5-$@8yФ鴀av(4[SgVi0mﭣcoDq 87LsA$A$-]W&m\em΂Eb^X/瑟:;qRZSʝ[K]s 9ɼdT<.ʞN7 śz$G#riI vS˞xǡ$@E GabK^ B\p] x$NxEV&q׳n3T]`'ޤT!g#:SA{ע$] W>nN΂RJb1D+"Ņʷnf㼋cr|I.',t$`Z Icڄ٥5Y1gem-s%_l:eZ+Es}_뜜X8v:Cc9:?)7UaslgA,!43eY5֓9X5Mb s\vܜ>,TX)eے$o=Xnd6;zOkՒ衞*qZJ'e,H.3 ͂8O<\~Q4k-}JO9`}pWtؾ03Cm]0mO9Io[@ *k P#4J2k>$e7q},< A0v8VCX ']g˩>rԾv? j5̓Ca9Ɩ>zPcbrN9Twi=ϓ8@jPLzǠ J? Ks7' &]G,: ZxKʦh+W%w Y !۵bw^U'ӶAլf]|g#(3$Ҿt$NrsEDkdz)lZY4lJ9 k4s>m[NѲw KYQ}Ƨi$ZrpIf6Im6Ǥ^,væ)|Y8 J¨PwsdHtK,.R&٥qM!a,ad?$djj\aQ(sv[?eS嵋a#noBz<ΆK,"Ҷ'>͛Y]78ܼiVatкE) OȕYyRӷ 0o) ̌g̅VT2헲Zzrcp-wrWBY\m:2iWOt!Ivŷ%l&FK Ʊ.P< 'A Pi{T$ b@uX+cջJB@fdJ,ɲV>V`%dJii)Tr32qRJt9jcm;BZ~lg JEo;35q o: vf-2tmW0iO/$;Am8c5\ǀU1 ˁ6 cS&r6b}l~9`շ0m OrK[` ;hyF!-10 JT߳&# %)$ȶ2ixg9#(ieuQv:{X̏˖̨&dˊ_ : Yk1~R3nn=M5Oל5`2C+8{֭\-)Y]x{f6ph[sƢ0w\mu;*kc_4Z:y4uNC[,L!sҧݒx8?*}ն6@ZMFu?Qcrӱ|߂CI`@݌3 SDƀ&cJG\, ݮ.JiX ? ~m`+;F ^kMPGqz?],B:8l\!YdvIw_ѿLGz[mqqM}xuNկ~S10A& u;QÓJdzVMxRiKfY}S,[O8}1ef?SbĽ}d=k=b豤~$)R.8Tz:8mi`.:oAMj1vLhjFQfqn`K]C.LxbLEQDȉəD@ sDk>h1.9PkQTPuajRJSȤs+1[ S!-@`O?Ҥ{񎝅Kˑ"n]b Acĕra$:0y'"h0#NsTfP8OvXM#U:Bsʺ2'|b'EPzBitpοy TV6 SaAL5xɪ;r,GqqE91lFR*:Dufң3tt`MO{dLgKgAbԿ=N66ձ P/"j;&v|'zOnQ„\Z8@Zֺ( g4;or2CgN_[[D7GU6QDVO4xzq4ZF(| qx8y- Gp{2JjP]V&O&]X!RtWfZt}~1wp?InӦEICz>Ͷ&.si8.J?]ǸX`6 r|{F<(ǵ:ė{ `[Rd%Qwt,N{cWhQhiP(GXp6ͦX1s>m#^(1<·5QvV#T&ˁw`1MpbN9%^Dw-1t%FN;e' ]3NX(^Z zYַx3UE5Y Oߥin,Ä薤㤁InbT7޻QSdml\2{|ɘOvMуE{ːj[bS5.2Fܹ@E,iVSl?ӆ-m]@80-|+vӋmpV)URv^n0Bx{HKŁVo4ax'S%+AK{*&(-P-3oA+\9ݼ^7b-YQ$csNҦA#G @dS4#GljNDM D Scۧ qrfb`gԓ0 ۩okAŌPzVV&0EB;=oU*<Z%8 K',:|Yۭ5պG. 8Ju [t8%|a2 .VC*$Ksu,"xrm\SNj0`c/5=N :SJ}W%?hWw'd-8Xz@wt$jJW\P$%_W-cfK3o?P[X^Wk*D,"lO"~ ȸ?&׺Dʊ%j_"J Bb샜e.ST>$i j<̻PQHA\)ɇس"Q4rORF-o .(Xp tTnz iCTw wm :Or 9@b@Nٿx:]Q(x;'UpUxl@N׽43Q?Y𙒣<_2N蘺|:&~LDIypهJ@ZnAcJ9v:D^#䱕.t35 eDǓriz0I}cSй b|P6QjWg+'7M*VԐPY F.,;5 @-zuh)ҭ)~OPi${,DZDezpqغ*kA)`utm.4o]g^*!{7W07 }x*e:_-,`'kx]k“K< "TiK5: 0eI;*dUrz^+.[u',q,ws̑< q32y7KFEm pqs;O}._[llMj-?=.3Y@0q]8@I{%`9S-T|Sr B$Z_BJNJļD81kea!!o|\wݍ?#?Ǟ=.1FKf<߽vҏ}ˣOSB}`ͺxАOKc ۆ | nMH s#TqExI^ַGw|9]Poo??|dw[@O4UYyw p+ɶ -AXvd̵Mlʏd'2>P< ::M"&UD IgC3d'ez>o\ `{37~?#e%XP~2sR{^z"6 ,M7|%$[iv(M2_񖢯5JBlaѬtvZ OAɀp[Px-"@ uL*H.d13M N XS5#[m'Sj;m&YH66gƀ353&` fd3Z.}Ԁ8\4΀^YQ%VjtO N'Ϗnk}b.DIҀLїx תm{2?\CQ~3aT7seP@fH?H .ANԊz4z$1Z ]ڍY"ywE$޶kgI bK#wYCz  p{D;_2aɎ6B8R0~a{0腫a4iNKCP-'wϛ,QutyZ'T:xjm,bN^e>(صc!w\qz7دSĸC}͹E8t^.r)րJѺ;ʠ c2_,J1]cDN SԂT$.PKvf$>fs'vos Q.EY#T` ihu7֯1 24l(ğ=TB?~j݃CLN44< cD[]^z ضt/*ٗ_tH6 x:6aFp ]+N·oR_gbH%˖^FUHʏL&z1ّv;@boowZ_)>}|R^2~D@߂% 0귟bNt< v ƬȖ N":i+ jkװSв5y ?,?u%T)TZk}ߣG$Hț1K$7,>},P[9*k* ?(-c,/, 4ٗt{Y!Uzm,[jf%ϸٵS,_Ko\@:%cD()؍ (o |ۜ\հ=o4̓LX_9藞nm?@́iac1(aJ;|ZGK4`ubA^1XOp d٧QwKTyXЮSAݟFu$x`c"8%o/Hkc8R#ٸ`*_` K8RM]6^ 'H5v0C8`i6cD E݀9[s]Sfa64o Y>4e`w) _ک- +ȓxY_atbsŹlG|#5e`乡;Nb.ϔ`IW[VןExCkd}ͅUPi\2̘hsWi|ٶOqAKCZ Tp. )'K9h7Ȣ) 2  Dx3Ȩ1 _>l/"p|'a^+nPCg6 ̴ [?)'}8TnsJ@i>Hf i2s| eqGN;RruXlx]SLs*p$^uQh{С\eG(XyE~Ɏ̟ H!ݺE4اkP,jV:c45OoWn$t x+b[Y\ΝgwcM7ۉm PC+xm1`C O !;[䛑.Q<ͩ{,miNz?XkPMԿֲ6/. yk(Kg[/D̶Hof']'tv,kd=AK f:dGc%xZ mN CE!3&s;6HQ؍8qJT{q6e=.%eU ǎ7GVWXQ}ۼ&K$8H@#7` Or#yJJyvXs+ +nJ&|9Y$ !CߖjVQ{zȍ&+Ϳ:p)W EhD"ir]:E.y0(Rjgqސy ^70H^YRO+315}w˛/Z h"Y 'ulY4Qֹ؊S*Xot{u!Dkw I*y RײnS^R"䫄^O `KN~xojK`/c1}O>ρX 1U!'%q0ݾbu`) sD}j* ڀ8 ahj黒fyP uGɗ2^MS`TX R@.[eUL]|u0>:Xt,,Tx t[[rB;@ȃ9 [huލPYxoO ,Jaj_/)QɁRepzˆ*>@:u? u lURKVz^Ҕ Rf@w\ 6 u4q($I`9矰i #[6^<#;e|KIXʥr8jGu* K(ޯPsM WKc; EǪ_^/Ҏi)V?Mo%K8I :/S?qO`P륗-y{մ~ocSF;"egwUsNE[E.{ƴ3Ab.Ĭ/ַ§$bgmIF4NI[f#Qz&%_:N Qpz4~˺wDHvfL}_#T{Hr'W*_~, XEzOs&A[z>0K]Y'm뮾eDb|1>:񯄂1"V +[|_֛S}6V&HD 3Ab[4yh 8y)s(n~6 ƃ%{Լkl$hh`h w*U U|J_(7>ajd,I_!*odJxVnʥ:%ltzYJ'A}?,GWг>B*Lu(c`yeHE-7na3A".mޫ$n u/L{:ԮvNx ,)lj3_Ò 5lt;'wZP^:?s BI`@o"X6O,식-pOe]avT_ȟy]r*/TJ<c(5hzrCw?r,_\C:yYJlVk!>@Xʋ i9l(-tkUJhu/aLDs|*""@qgDRr0l:WUCtT+;N )hl]s-4ONĘg⊊U]74b)&`/!ozn?1H a}.Z >B77,2uSR$#wlXZPapU7Q:W}a_z5:*ah;2. ʴ,E%puxnKtNdJ$q]hT$ IHpOja ycz5%EuM[AN@ $%?E{hfx9Lp ޑK&M͂ K(׻ׇXnsrDhR]JOLר.s*l hkdMyg,DOA2/#Y j*͗%jH `fX0D W~5$H9e;EÏcn$#E磞Nq0 }2bPm7q4#v_o7:iK <zdY^ t** XLKIuO$skP3`ͨfTɺ 5@:H"|*[hYMTL41i򧵹¼)~ڲ 9|Y#n@\uBgVs& 1yL fQ_rguJw֎)fЏ M|tD  %/_`w,B,ua%}H j9<T n!KM~AayHCk}WO2-v>t瘏IKyAxjIkvX!` PߍX j>Ej)5)@. !nִ{;iN G/Խu$T)bD/QY<olǖ]G-|ھ 1PfҦ{װ}wI GCFvH v(K{ YYCo5z;4?Ǟp@68  ,=bkZars&պsV` jpbSzmI6RN8%TpjZ QՔ]|#ITvOtrʰ7·)"ۧ|W˖o'εr.$-k.4О׼V`"G,:.r "$r9 eun'+ZɁXu]Ȫl[g<]?.%k*{n $i;[ qyy D\f( jǩ/2]@T|XYISBQ=duQL< }d=r3C'S_jrχ/c>UbVvޱeu#xBZX#[]''-?gV&AJhONSU5R+̲XMޓomQcņz{_<qAbT\5n3{Gٜ'~pf! ͮyH{t:lʢҌi t{…4w~yE2|*R'm aY6䑨Ѕ8=X~rŀ&@:$Fpw\+Kۥ%<f 1Ï- IԫPr?v[hi|ZA_110:D͓gɝ9\¯oۍ_ʴ֬%=Q\Tk'@yʁ`jcBtkRatXIi^Wi =/+eN 2~N)ONhÛ/ +IGB;OZޙ;BⓩGeQxHy!- HR'< ?Vs^'Ǻ̵ 2)h=J5:UK,%q/+3+HwӀ \GsשG> dɛ#->HLA ]tMt>+~׃~_ƛ 4myau0) e'EgSo[l0J Lj؃{ 0?z ?Tek& ]+c1-tz?Ԗ'!OS#~W~̇YBN:2Ⲳ X.r%P]G۸Kٿ)ùdmJE\=<%dbFRy*5Jr(C]69Aq 9(GhA=TxR̙tg%|7 FIކj)%U՗*߹bljؘԅsw`ݕfq&"]XҀ tU)c@^g" x?l)d\,:M &>nb{t= Xz`'b~B<=%^aZj'FjO_lqOsFWZ}%$JAW|~q)z\ ήZ"߇dv0ϡG})Q}uH~ s3֨Njq}* +~|Af0hg1R/ލP%CzշI큸/Mb*-quh;j{^N" [,Q>~/e 'k^na{wl3rSީşRqbI/Wݐ\}PEU$q?nmKp/3,~s0w~R&KbU8a>#TcHqgFjY^Hc ĉ9VIJBS<IkHH4VlՖeJGx~3AMӸ9TT"jyҝG4uf\蘾D8jyZ3DJv[<48']D+~yPQ:1%z+8p'hܸDxeb9Ty ȴWt ՅIeWpYyr) 9R)B[m myhE5v1ae5CCk<tH[; [_juH$1Z5wMhEُE`].LxT3QrJD  3H6݈h ^^fYu{'NIa;Gd>vL3 MM` x@-ö bRt8n%SdWrz3ƒ*C ȼҚ- 9/XW4jY~OTHK߭X~VʓpobАRΈ _j~~|f 82<~A;iq`5y4y:^|L|ϣCK %D| P.q:a01]ׄV<8\wDvo"OtGlm7`$y:C<+>Rd) %3%A̐c|aT'Cqq1b}<+g, MFbb8c`Y?>*rcE܅W#ÜwB6Jw! zj txHϥ.O| hmjx$NFu`Ȫci+8`e7x%5 &/M6 %A(X%@#4e|7u4$En_j(ZתB4?Ɛ3)ͫC79]OϢԑ$ I kt9%m*FaZEM0 AaNǚ'Xb!D0* -Ph:ɃdCPsڻkB_9ꑋ4U_ɃsIk L-˜t%r\NFVh-i XI6A7pߥ>윶Y(INNr\TUH@+TܨJhl+KFS_eZ ){>bDQxJoI3ɀØ[  %Km}G]}xGTPGuPwzDs-``UeE2|6d!iwStefahG$t"; PSpe,! Jҟ M`,gPd",16^&Z05VcXaBBZ_kT`ݪkXPO(|}VY%[7)S*4Œ2Fӫܷ(z9t&,VKn0U/D8(4(\WJi -@upvY[j~YM Ka<0L=%!;='?'l\iwd$X[A3!*bY,1B"ޒ:-yؤe2 c}Wa=5~i=ӛx?Ax"qh qħ| й09Gd%u8N 0g}EWGO7j>>Od>xi4񄁧p C$⧗!}Srġs`=t{%:=m*f+ayt:;HxeSmx|e:;hrp>cV$ȓ~ ˞8I8+R_a rX)d,m"?X[Bk NHH> S3 tWM8S>Ze]PH۪o1jjlU cKK@;sY(/]n96~la +u :ʅ'N#5;tU)\u ߔ<:?qv]~_{ʵSڤrsF'nvUhv!6T ԭD["4t7DzKZTnniŧne8j㛀_@Gܧ'ZV<;h(kv iy RdQχ`4wEJ<էdu! uŇ*ꗘ^,>+̇_к Qqمփ4yI(s1G +^ʒ'}<%[8jl26?x tdF僋Tu-²*ijL{D~ac4Kb=9MRiNH?>h pCnOՀlRvغh4Fu 8Tn@ pӍVF0/+gk/FIp`HAM Z<`nUms\_%qC`rٽ閷+'XY8#|>:gg[bJD $'55(M1 N6?N/J((yz%X WHOUsy) hT>|a }yj7%T3 Ĭ:^Q9m)e ;"#T֔|5HH'z9.k,22"iaq62=On5X՘-C 5%\έc?R򄒹)O?%C&WZޘ3[̀=4M#+-nఝOۥ$|l7iO9n`O8M3' 8ʍ3\_%ZwSê ʡQ\fKYPaCՅGq85qm=0z-ouXnͥSv{&n4 O5s,NG{ȁ;zq~3[k(\LC۽u:kЕTLG56 A8%{ ӒY"D =wydv&{%dl^fי!o:G%yKF]%&_45//ȎZ(ύ lҐ YeVr2NYn(^V\/ 3mcθIS{wjUm)eV8 ߈biWrݖ'o-[A[F@-WQ9r(z(,rdzy9g"Gppaƭ5r{hsm{ Q6WGs+lc@s5.uJl eܝ{"%lѤՓK uJP!&>è67Dj?ɸP48mIiM4Z)Jf- pCVroo$TݳB la39 e(ɴ:/` "SԄ>E;f1P U$rJ5}yӓϛ>5,#9v6C <9[ǎՏ%\tWr}]{S@knx&GáіЕkrFk*kX5_*KGgja +7?fJž 8:WPʯ`2=rҁi:$yNn?b0o@UH2 +X(Ox:V5z [R:YK<pf2էmÐ闙-0|!d* "p;uo_r+X(;^QVtսܼTӣ/ݫjqDշQh(QDD9$ uq`xŞj@U@iҊ٧P *2z14s}AZH XODRPK4/.ȅC?3^3ʸ>/+ "8%f5[(<@d:/1w TyWo1s,-_trm(WAkE~4ܬ~GTrc _y`_sf+eލ ?kڢ<5qrs\ AA銂`,K'ުh#l {)z< xRO[S͘lNZ`c +ZNV^ޱZ߯V@X QZG R'#Ɂ[8( GaOxW\R9 ~`X!KTa=A`ҧy8(?zߒ(F,K:Tc⧘Cx'ʀxp_S;bAs]|YX*= T35ܣҶ*>m髽 mO<=}0Kb-7wEqRaʎS`4\h$77o۸S; GkntbxF{+}TUfQnm r{sW1| 42*+Ү ɭ` tRkv kn2Txu`}͍g\/ fe:I뙺D"Sֲ!]dt8 iIJv,5 B4spAl;&p/p*N%8**RmXgk졑ŵUoF q=Ze3rzJ'?r> ӥjx\|'YWma-4<2Tzyl\)pbx&pu}V{噓(ʍaqϿ}Ox;UƒAo1Qy7,@ GM1ET?q%+XtE閖b@+O.V^(&nQx4ߋƍzݓFn ciw7rSb6< t tqQ6pX=>Hdyl[[߅|xxVJ; y&۫ wO>X'71$CH!?v\'R 0CR.PcH;&d>| PM2sYy6n/?Kݧ#B4:{._yAtc!ѢI/FF87>]Y .KBÜ\, TZ-y7+2`qiW%*Ω(\]]@ c/ 2'?&Zsx^<,uQ<eLTqe |9K<L$D@so_3QXٸaԱj kA:S!lj@1#e0~ޝ$ZY]})wvyH2)ܑ8ln_hv7ʒT<xkw'#HZZϵ1es?-|-R8 qAb:rE;Ab,^w)j(?\g n(7NbxV*hU`5Xn.:~9Ozv?\/+sW0WVG+ a@\"PZ~MȲ*+{J^~6b+H a'9o7{ (FhD ƼxOGU"hOwxZӈ6?ez5X,(,?d,=˒qQ]ktOk~d!l܍yp@z)ր. uڲW!DbY` Ia Jfr롒Ǹ1.#kY`{^Z8]"YG@(AL2X1;O$oKa,Kkg>vQ|ιJOjBjk*unpU7 e#~Hpz0Bpkr2"0O$͖tr/nGxy;j!}n9V"_p@ ny0:}|P3K4`t{zi<z#Rmؗt%.Hu<cKXw?s@hp@6FQ9YNZN`gW~@;Ԉ(^>f {hc}Ň#)/=o$,}*Q0ًzMZTlȀ#ڇPqw/ @  \(z5(Nby9B@m{607a\]w Zw` n q_;2ǨW(X[PZPрhVRUҬ!kb@]!uZT-2d- 4oNW4!Ns~R`aݠÐҘ7Z؍&M6 m|լ(|KͯjVu6G'o-@ E8k*b=iv|AUqf1%\myLL=YD<@~o,F'o-3'ۏƙmhs}yO:t]=W܃AѿCըU=~`q VQŴt&TGD+J_**h8 P@1>Rqbw!}A|$~_b\Gwi=$0Lqp@ -aIA&)_L"ރxHKU8@,ԓ."NQ40B0{߃.ܢl1XZjTuf Ԁߊ*+o+D|OTچqI=nh`t<w-Eh( vE=ng̍ǒaILD0Υ߆, #nx g\yd1:}bA z].zo/<Dkz·0 ~$w2.gA(ߤR ~GصsǫdxP9G 72;rKj3=;}/W3G NǃNpţ+nxZ0RmYՃ!_crBq]z*8800 Kr-Kp 0̀? iwr6ChdOD$4 .aK@@2ɣ"n a`VKҗ돼^xo!u'vk[D7H>ŚqAqZh\D+64Ii@4ȸ,ih=Q%e(V yy19Ûp@娠Pl/@uh:M;:`Ġr&*]xrN_Xuց?4TX\D\ӭ̅T7㖥u .46>=X\BۯJ700Po ĉX~O N-74Y_F!]lMHtAKҺX ~S<v!v뚣uu,bx :v ҇^طBP/P=p 2 {rT[9YX\kw[}okP@ӭxSTw^%W:&zO1A [;n9skF-cKw~\ ^h^n|*1 9@ ,QߪgVk= 1.{{ٷz K@QЛ˲V6٧Nh;K%1(M}2RfyˤQ)&u 65!&5]x8a P,Xm*=a/YY9I($"◉SZYݲ{Rӣ 3>f~4y@b]c~VFPVT rH_󮧮s_[eǰ?Dk'^!z%?,pSSpmzzpJ8j\ 4̣|V W' ~U~@9:uk8"ev3;#n3"PtV5N(m_bf'"ZScz~.t 'btwU^DF\wʼnZ@k7s.T,?7[7lc fk$X7"-dƕFy3O ߡ:T>_jQ 4-Xӡu6+yR#lqFv=tqZFpFvp@{Jjk$ED98JQG|DRZWTØ,mzIѸ9a5~76 'ouS <@,7^pGӖ㗁 5J:W?Nm&kh@!(l8#* H(W?V+UgqʵE@ֵ+Qg]"atˆi!lI5dj[ -`錃Gh~ =ra @C_+!GZ{#OV m BlSil  qD`CAVzpo7_爀otSqWvʍ3EvjPnh18W=p霻K}-U?ohel@!U\r? O R=L?#nMT!'jz@"-AlEpNhwVbնƭFɿ2شTR սĂpqaa  u6?l5wROgh#Lj5/qQ-/w3K&.D0qS^v!&N&.TX8n-[K;blH7nvuԦهx7abx \;Ukqcp|ЮKꐊ ,Lˢ~>![5ȪFx{M!l5qEb?(|R:h?R*ԉssϽ_* *3m;}#Eݯ.05h:l8;`1hxY`JdazdD$94nսoXK:-mT4Bu:k'8nP.M.N!Ker.2xe=1dhI1\N} kbi&g3 9TC:`wsFe;_#?,Xͨ=6 =zDڠɂ6`vmv]sW.~̯+{WaDWu1Iz?2Dʢr`66k ևG6f&-8Ԯe) ׇYl d(4oJiS FROws/]m9IS]E=؞@ѡS; 0/_R &&btYf@S8sʗʥ֌^5_<|pйM9j`]l6F,a}[v8zgU!S ᰎ (.FoUt"]DP$}+XWc1 UOtmϞj{p3ш#[q$ Dq,X -ASĪlfgOU׀ջgu.E3pG |`]"a֖CK;)i`Xàfs2I 5`5usr"Ne\VFٿvL!~֯~/"\-bhsa&ڭ| ?![aH]3N&٠3&L8B.3~xqMXRṟgƲ'ΔZװ0DDzC)5 lXEeAր1|Ѽ3էq\>fx>%?#\VN q2hc |0tw.o#o~P]os_`BZIq5D5*).aQ\ e=JuKuF5Y⩰bg^;>P]XE3lē(N7F1dws q (`sߕ^@E*͠u7Z[-hsه!z`lijJ:}eQݩ(\‹xM j* ?t߁hqMSS@'{Ih u8L+;bpQ}-j}-S}GԺ8˵-{FːE6U1)fRO^G?$ӵ!DfA 1ؓi)Dttwq8@[v;8:sm;ZNJrtQn迢XwTeڍ PX ɵ-׽ r{'h驸f:@\o@o-]}tя>0\](GF#GibȧGѡM1Ly< w ,k[{lR :0wyYb6>SFOMr+&M2w6P5Yr DɒePJLGRkUj J'8i7-W'_'|0Ii_ 6n >5ug:i_b:\PLbG#)u[dMzj먧K${/0!Yi>U@u%Cuk h.=Lڊ藙˭ GEy#*ay?Dy[ G` yM}f 4CDƩO퓌&VqR>|櫱 bo<@IKLZ~k&PYQ9,PFXu7a}1{$IJ5 h {QSTf?S%?9ᭁ%E@(ŗ% rkH$̍S dPN W>7JYBUJxǗQ![7%kJ] IaǒBGR9c>*=2He I]:5x E\ػ[UeX*XG@u.Y^ ဍN>܅/;5/4i{̷:y1E7K 7G3 UlpUl y̍XD0gB^a݄sG"|?:*$Oۻ<˨ޟrv^L44t/Ɉ|me/:i//S1TR$ѣc9ZHE:@vVfXKnӤѝ]m=ϓxNv9#uiy~n$b qX/.V3(R qq+C+b;ntM/Yz{DnpGeagBu>IJYh _Nf:MG,QЪsML]?UXRXo Ewŝe:MHb=:w}эf@g:ޝ9am|7׋нjµKE5I2 T{*Є `Fv~??!{`R\@8!Y#~ *6*|,TJ2 dXґDlݖY~QCі ~a4BvtvBOL&#dZKH;yx)|`^S.7M+,^ibX YH!x&JIkoh>nYxm 6 76܁wQ J> _Sز!3$|nqoø'bgT-aepw_}tG߈wZK&$G'7@<(QAeYJ*ngG?ښjέTvx^YWĨ=?·[{j^0 /~뿼? ~2~3W]y夬Jn w߽S?}_m:tՆ[ d}/|JL !X9@8j Im %R4O tXYp+htp @*ӱɻr;عI8o>tkASs<'V|ej$h]bWT<Os“ Xr.(۵ߗ}MH4'Jx6 >*+N+q i{5uACv3DϠjC{B6Dϩw qᇍk~ʚ8"Օ8G?S>Z3;Q'4W^*:N?px{u_b( ,2W%njx6H4{,^ϯ^q3n_X?UK2Q'Y.|o}Ź \| ^}tF gPu.|/^yJgF7<57Ù2wٷ>n_Oyγ~s˒A߿=߿VԮW\C J4uOoNB7 lw\x`!8St]S^:U_9}w(.rqc!񪭂֗ndHadMN=e@0s; HIwj+U'"GW rmrspK+[ފ8"/x^/w]P hgZY>KK~c_@\gM7-PU?r7,+J *T}6qu}X6Q.58kqI aO߹xpYB"iY4$6:tyoxiLȩ~,xʋ~I}V"/tx]?u_eu,CX^^E' x呗\#ƢsmJGK`yXɫ>n_yzps [k{oz}.]yՏ?,~I}\UWod9!_ wb;A8yH۳Ys fhjฌp +hu;EM 8Tɔ(rO0,#*)b;?obw[ΘwB-*_>`OgfBN7Da/bz 3'A[-n:\ ]c֟y%zGއ3j߃畗F}t>@19}a{p+A8elњ_^9X;pV{n=&Őd4Xi/PHcM, ʡ@79ricMl1Nݞ`$]}ۛn^xuw94 7!֔eS< y旍8g\MDt[<X魣KؽJlm䭊r\4C(/1BG,ܼU_{UՠMablLpd$I'pėi{E2W.z /ooߘ|$_#/wVj~?5aW+{_>GVo|W{^~գ@lI _EGvZ^& Tg~"lF_'?gh\FSPhTY@[()_8ן0yYK+pj ц[}.fnx}jo)_aF3.~}݁?xޥ?{麍3& Uhֹ(r} sOv@OjS}x'|?*m0Ij Ne[A 5:;B@!:Hxg,FsaTF:B -k;}Vhe`b 6FE.;qLe\m|@sBT)fqkDۂԌbPl|hܥx!`+7ұo-{m@p/@16>w({G>pQ`łރ#Mo = p'ڟ}/==8>8u7 ?W,aen7> ehv -R/j&gELjcU%:R̘E;<3 |yȿ(Gž}ˡs'h.$`np$u}2mzO~{hx?T^ރw< waIw?wջpT:7=crg\2aUNΪx['VΤ]Rۈ_ >go% 7:[C`ҏ~%ڷŤ-+p_񽻖ꀇ ^«?8$pdvҳ1~x#euKYuGrܞw1y%|wߵ6W {̫ ]cR`t'M}p<_ UJpw?^tŷ_Y~:wX_?MmU,aЕn x™e O]LHS=?4ͷ]{ Zw4rFgj9C 3>2 r!"{ob/_>0l)=.\a(wj:mN&GDE4S\C>[N5=׽. "Ly+/KOݰqw59a(' V}v3ux]? ݂h<\ xۭcV_'E&qV.p*,C1 * VV#P<K_Scuͅh&s+r( $|c8:(Ut+$YQmr͇[jӕr8rk3'͛_rmuxPXXn8yO^$r`$kP~NZl]="ط'o~]8*^CX[TJb\1:y=._D\9|XY|t%Or`Q9r4pG?9.7;4H\.SY0k_~ś`kUX`߱3_ }$N/KWa|7sw}e-=c>9/?<0T˯ :&@}?{W\VC |vW[j>~z?)}+=]+< 毈}s}t΅+08J/n&҇W"FB~Lұ~y7>e"7:u+mwG>zzY6̨ͺ*Avܞޣa_P,ă75qދD5?qO^vܟS>_7}x'AUVTog9{uq<"|9_.;o7MxIO(.0s5+gFo%+/( BC>w wk¯vt6JzQ95gDHjR$H_-şP}su:)_}q $>A> 28$ iA .p}ӕX=KqDmkԧo@r\nKjaMjKӝ2A&3<p0:ykQnmF-wrk}6FTo78  8}c%to.ks闽 'N3ˡ`y(تb~ǏcZ?~(Pyi};'bĿƢ]"r%"e[Z]bZ88x?>¯^Ï<qK>ן];jvF }VN2҃/jk] }忩_y…OOfIZⲟ^/㏮tu/o>{z>+~]#:M{#IvZXˇ#[tO=>G~ ]*딨S*`Nx{|;Ͻ׎|Xurv?vo;n_dA.o7e6b40bӉv0Q%2=pa Bo!9֨*"$V¢g!r}L '\ 'E,d\c!ڢНqOb΀,T}#}g9&m\rþmw6v! ^FnFq?:DyWU2%6]'޲Hu~W/Yx߅ܫX֙ʽ,8Jg'۫q.H_|kAwQID]Y2jYAG)ܣ4K黗Zppw>a|贬ZwsڢcIDp+w>r0; ;Gʯ + Gx돾/wɳ~<\wϾuG~~I?{A /X<]^ wGWyPkK Uqhi~)]~tˋ3"kqu={Y{~wn0d$7EUw^uw]/Og#\9|宕Ky> hm6%1Z>Md*E6ՂDʢC 6h5}ӣa‹]SV]ѩ êHV(Y7*>>g1 )/~T߅=^WUG?}'_6:MQuԁ.hݙEY6`qش?eM}w {ůc?"AxkW?S Sͯ~o~{?9~CMRLw=ɇ,=[',W(w"$~./ғgF~sG']Cp*vސ0nciXk(:'i!ఊ (Xe wV;yER%yvywAR2M?kJLCj碰9#Kq=Դ@)Ge4M8?\v`߹,R> rT`*G\+Xq 9CY*(IM$Ӥv^$?f9,p^k*b߹(wwN>>w1OiRJ-)a#G6?G͕s/V^mwl<t20H%ֶC_KG{I>\~hy, VzD W?GyM:_Fj+e9AvmI%%oSGY9skbK GSQ`= /[ '\~t?}U&pkHq}e8zʻ/ݻ_!D@į[r5Zv#?~~Ld]L'q;6#;"&<"g9ܡ';[ߐ@ب NZ U8^(/ĸڑB x FZ/n6aS}"K^!~q竾,!|=E=NvpR.;Yض"?9h48p[:xa&Q9 wrK[pN͉fgO=#׌>!x~|}O@cy ZIΗR@WfzOGW\! Yrub7CdMs r;dDbHY%9Y [x%x_|+?j/7|T2HLIk}X]/?s@!l rB'ܾ.:칗E%5  B }rsDt ܣz%OV#+YQ}5/6A8V r꓏gP]t D.k_ DF< ׾y nYj5aY&&BQ]~b(;q`ϺȎF`Cs\@hYT zc'O ?҈n,':D]|ڧ1ʛb"οCp^+EEwk[-Nj8Q܀C't. g{gTh$-}v>"oW[Fq\q#w"sb?+|X`SWǿN6ŽM7na~a>hΜz˿ܿ+~𢃃o s~?cv{ۇBϤvg_Gﯯo7=/i$L=B'%Yr)t͕އ[|>(iȘe(vOy,p>X߷lo&pXk!6&qD 9^ݘx@T=bܹ(hhkcph0F[\p/ޕcoα"jy ~_A=0>mף8y[p/ _/5x͑$FU1q}Gm#*% D 0"^]Y'܏&T7.36]-Нw yϱE5 G.yM'F_55` H_u^yu{/~M$4b1}@e"y I:U3G6> /E+/=~zC%q2dK x+Vޝ6VԽE΀ V8Q^M a겫\C 8AϚՖ$]4{&Bufg.NųCuEρzٹ[N=wS#ɴq?Gک ;ɑd>|~xsWϸnus\Ϣt+T֊aRwgZ\d_y*~/㘲*t>7]8.8~K?|^uf8 iC_r-7=]i4Hʰ9Vw98yJٸ6C66*kQǑg Gl!|C*C .3GQY YY̷+=Fz0#Z?1ỷv*HNV\H] FK-hN_C\Q+n 3<wV*ܩ`Q,WY3')t?¤&>FXܒSR9z$ Ɔm{E= |~.n>6(ܕ]Ua{%{CF% Dp6X` T qjC5W;gΤ4AHt>&.WE}C_.~{F@._+-pЦOsj fF[ Dg ),Ñɏj$(#468S7Zbjy#P=u؀\c z P*4xPjNkiF+qїר;bT7o 7]=+Csh[z'R:;#MC's7T,xOo{[ Vхcq( ОpMNj#PgqjƠ .b9(NdW`BsFD'G#}^uCf'GCgʓ w%newD{ YnpL~jo}HGׇm=V~ #ȭZ/) w}`woҧs7:8pJIaKފTDxλ?A5'_VOF"󖟿E퉯n@vo}çqRNzMCwZV-dxmKGD&9%ɔ : @c4ĕ-ʃDJ"3|-CMFp ҌkȬE5Pt>@1ɾߌbx78@n4'`PI(.jƍFUTۮ;Jzw=_+AᎇscNJШ?/pk"WnJvae⪡F®m=u7{>S<_u8܇O~?V'&>k7M%z{'7r`XcH _wܟ?}ohawݵIw?麍U' {V#6|ҩWo Hos|q콊 ۴[w0zGP~q+{o+B\'+D;nUrh'o)λ ̿Нsϯ0N3GxXὃ߿$W#1=W/&RF%N>n&w#?,x@4{ ~XzAԯznoyt[`ϊ{e+Ksvz7<>y{0]:#0:oa\Jc4&j!{V^ڰ}_.G{o=Y~qnvø[-WH~:"r8>8}NM\acDgCv*֨KYJug* X\bwRr(E H k ~hE(6{+et$uG@{ MZ{D]bS!waAS e_^D>$MvTt+J NZ(;Y*F:(MޛOUE:w;4H]{db2W~/7w͟w+#_*иSnR9ɳ E_`;m0?>_6lR= Íݙ8oq :GhkK`/׾ ƃO޳" jG? +p oMTImAޣ^_Ӡyi*i~>_#Fh&r =Υ֡]o\^/ ry%kk6jqu\GoT %pB<:ԡ;Zx"84NkLcݻpg]Y F;$vn';sCzɉqǺ2Tqp_0:myq44ݠyo_-; (\z>߸߿=XL>#XU'_M jI\߇ҢO9SB<<|!v%_ Q˲y䯿'2ˡ0ٞCNz$  ? k8ɡ֌J #X\J9agF9Q&XtUL{1&,`ɗO?'WQŰୁb#i#DNW(@jJ@D۽gNtJ;mI6yV<7.}KPVBe9UT[mIԊ6?/l+YwnRRX:pDg+Zw{?Dࠬ{Ua ZZJ*jC۷! $ 6{zztvWpIȹUrV8TL`M@5@$E]BϢЋ 8!NvZ*\Tҽf6A+HV*t:) B3{<(:A!m7 ,N$~<ҝ"On%nw{-@;$v:F:G픈P%T(s$ GN5~g:b38qz|+"_fϛOEBC\SXQyuIQgya6fD`Q;JW$oB#(FD"*F# $(Ì stUuUws}7}szު?]]{x!2;n^ |.8x;зG nx쮎딄ݝyɃG߫yt={w$}_^:u;plxI.,eU^ڄ4='N~Ի' ~:UDY{7^<{~iXїn#s6v&qG}ҧ-'ۆS);Mdie?{G~cU7/R|*r_ѩ55WLw,7/ދx)rՀ ݅c,Ӓglg J.|eӏ?enkܑhn4 7;ڻߙ^GtJD7&jnxOž?^A#Nޗ\-t;?o{<]׼ 'koFMރ xIwvٝ?ȫ>]~;o{ޛ|g=+;+/ / z>3-@Vu}3Ŏ~^c"%a&+Vti&“ګ^y ns뭐`C2Zñ>>TFXZYBHG-a}3,"\C6E 90]FЂ~pu\h;Lf,z9))Mq:uޥsLk=>SAᆌ/Ws͢}R|׵c/\ѝOJ؋8<e٤Lhi?|"jchxIt쉟%Uj{åLpwN]t]{G܁D3Vk<1}eD]2q|Λ>c/o5Դ'|Z~JJ7[_qOn|/|I׭}?{lvGgW? >vG}40MU6t] /k &kz?x?[7r4qL9O~Eۧ @.S\'[H!!<慆m14.\Ex}?.Kk *2AIwZ{=ulBp'X')|5=IpOHS|c¥ݫ7T-Hthrd-NcF}r f]2U73LN?ar!]ti_IItc7a2m~2ne ;^ K‘O|?w} b[+hgII 2sǫUa"KE齟~ӏ&<Bes~kxn?uW= כ?qЍ+vn6~~7<cw|gˮ[#/w/$ԗ4)gמ?/љ_zZ0+-+V^nt(LA/>f-_͠NSI?Z Nܤ bn$_ϝZAnbI.:IXh#1OO ,U{0|vPLr(=* Vr@1旧aE@aUý<O8ҳ^W @C͞y*iN爫^I_89  JJNʴBC,z.>7}$ wb陖/.m1 W8(5@v{D^]L 1^~QXV/XqWjGNIz,7W7Gwn?->_~<|a+Y虜y3ه{=)3_CJ:@8xr_j+ tKXXQ?{H~_Ǽx#Ks}YI,~?h/˖p0}6]qN`]U?qwT`.xVTa&%o az ,hBe4K@Gz>u<o~̥+'y+n_|Oghl"\pR2Uޟ G_ ?~i~ oɤ௽t%:Qp鎭;o/:6y~?@>i*I^t?_?{>K͌<~{=zUUN'ӏ40GV6H\XGŋabjI uN ^@@cOb^Cܦ Qi*jgAC mնC;ȡ[ EGL@1Oj3NU:><%E j;6\>Q6pFf  쀰OI~tG|a&%Xa=c> DAMt.ӞXp9⪩f>D(@G,e nDYn^`|?{x? ?}9஛NߗlaR  `HH5F?pʟ|-Z;'eOWTWOyۍlx{ӏ= {W\I}oID7^£.|"Mpv?x=ڍ8$$gml;4M+U|ȕ]?o&O;~i7f=G_*%Ko<0.?{+(xm.&L?t<ƍ}̓?8y K=@׿蚧SǦ_x_qH%\f9[G0'8)yCRxP6w0lo!w1\ץ.{`$9>\ ̳8iC3Zn1zϸ[ls'҈c-%qFLhZX &M#i/z^ dJ'zhN3[H|<D{4gJ{y2neS^^ZW{fB?iӳՆhm%Sw\ɟpg:2Y^h^W;M k#/Nptݷ o`ϻb_yz^}D'ڇW=Okhu"抧z_M܏U.96}ߛNۻg{sSu7ǽv:qol쁝uՕuΝz[VR?6e#mO^X[qO\x;>p4֜ q Oï_t^wNxP?x^z+/7;+3GduԽsUi~Vucu ѳg쥵Q.-_@w0ѻmaB;w|*ͤ+҆wAD5^PA,BFYř)LE'5.;3v0 ,7Yz3\L :x)iD7=g5g^|]zppt=歿{|/<}zgđ>r|7o @o'L|fizAv◸H>5:6ʛz;+ z/?p}}uz2|Knx泟zӉ[^~NEH O}c55-^cumS>SƇ/nFW'-p"B =*җEz EGBH+j0qðy8続{v~~O?pv=<{wkwS)~zgWo{_  ЫozƉok:5ǿ٧vy?{N=w[Ο<{_+V_uۯHA8)W GaA82;^$2Gع˵$<{>KD/+wkMݼ<Ͽu2P ws+^wyz};gnClgh f=ޥI{ws:r\n7-|ͻ?s`Y?4x/|Y/ iy=yrgvfo凾b\˰m[O*ez7kt/R_^z};?A>_@|Cwtp󱯾E\he]6@sg[1d"xW=]tl] Y_m+wuaS+S'+dr~xM!}wr YtjҲ'5{'w ,'>ANמoc{9QyA G *=XeTҊB_hsbႃP2 R PJj,bH_<^yTW%`@@wXb> CiZ){xU<q/bˤYX\KvNHrF4-h/qdi:5"*nǵ>s ,:@eG8+ɜģ6ƓK[$KK>Ac\>eg_3n~iK  ւN6qcS3COR;[;[8مi783~`:;a , ʟtSZ]{h&o&?^N9f 46uCk s3wa= 3iMxm3'MnVv'w'kǚ#7|j39( n.7v)NB"܄"P AHggĻE8"/~ha:kGjЂDmf*C YYPGx$0&-SRd˸?>Cm?qz& M≃ d vᜌAS\&S]wo&FMOaX5ˀrn%H "FZOi08fMjH˶|I &Dn h[?asg=N緕~wc{X41;?0gl HROz|݋87i/ YYgǮ}7l!P%J U&h~ F] lUh?N<3Ҹ) EAumGG/yC!vk""C: / u|6H„D  ((r1% :/[C<gn7ఃؾyg(ot{zY½[oً!s gY3/=LA$ɳO<虒E2xVa'ګoA\猛 p=Z "QYyd&~{+z1D5-ǭwg܃g^۟wߊ?G{5=ofzb1;wB_ϐok[;^} 7i&~wGOUH!|B=؋HсC?&8ւзÎ0>Q2ח/.Ă-oĄoo㻿Iz~2Mi*!` m֝L4Mz(i_FPR>9gg e;W!},KE̤ !ݤ̺ɱRyWI$}MЋwMh5f!_I^Md9gݓwieQP'ԂnDK.OIx߁Ĺ9bX 6;NČ\y^ǯpLg1pG_Cr@\RM.Ղ m^\q̝Y1ުO#u?+ ÚN/lgQ&/KŚtsK!$4C>Żܼ{-t:Qī}&"|>!|5XsV(5//q6Y4h-3<8W}W~;~%^ð9ۺ 3Cb] po':#0?-37Mz~o咫ڕ!eCp%0Xh-E[B{CmV6p;GL.>+Ἆr^@Ē+yef F2#͵xwW?=;m݆ˌ;9<l({]ltb]yënZ ܇^7Y?16nҸɊw+kRڣ?QgҷT:vYЄ &Z~A{37C/hF0(>g`K Tƥ2L1wcc|DZɴ| -m>d.ӒK9Dvadt&?مRZr+K2ᅦ <] v\)X05'g^}P69w$4d=ĭKЫ^ SsJqX:7?G nuj h[q#Z;mne7ZȱʏX Dtp?.4ĝs8nM^iپ lvgal+vk= [ߐ^`v~4n2m聕KU>I2>[b9Rx>r5"r Y(@AIӷ~B׉c}P@HU:.Cߔd3fLVaoU6(6LkmC# !xӅ]qY|x41!}o90gz2a{ Z}4,'+4_ jxWھoVLҧ`N_ %.ߕk| b녗yB؆ոNr5Z]x$.A6T!p%VKEqЛ-P5qTsJ, c݅ `LnJ3x ?CnW6.66lp~b'QWt휯sM1[Y?ָ 2wwxMk*=f6;g |kEDB,@kP9^E|zwK]@|djp>F]=9#W^!rRsLOt;nvx6!KZ*zϰp!MsEg~8w{Z7ra9Ti3vؖ8R *ʼD:2{')W+˥W)fk]\ qq=p=f ?^jeTaԢSѡ .#W|.   µXAڒw}KYZWo-ɛt669`L^L/ʯ_}#0%[C#Lmt+VP3A]p+|O_+lv ZD JTXX$G`ʓ`Ĕo׀_֛RSQt G>kBd]rOqWI8Gv&6p{ sWa GxL6v m iHjDi4hMZ_1zU³L~-&jN 0Lh ;sW|7N8jMǷ(Z$ebE y"șLNb27ee' ~a.hVPj'О[E@Ge\z1+wϭZ=N\S,I[iܸ8Gs6G~;uw8$`l.v=f>_qTqc՞N9p]߻v/4c!X'}"駿%؉'=UT3,'QׁX2ȿql A%X|u_:c.?$= ys WA_x 8Zn'hTSԡm.IJg(#)|r&~im_ya{A85j5X1l?yXMnv.j(dQm#IVb:i˰zvZ<;,9|Kxx@bFW@%]p%ZSȮ4dCo聕A1^|qFĮۣ? Zqm?x5>isuH+eѲA#7;i&o{5&Ywv.Ϟ]z"/j0I6 _p!nҗC9X-ɮo"_` NڛJcoC}= GixT!o0͝揂ԅ|i:_W|lj,B0ݛ餸JI8lm@>*oR'9OV PmFʻwtp2UY'(Be.d,+Խі8P{y(4K̻Ÿ*i(}|I+"~A`E/q8j/#o_ v VŽ#n~=t_i+.aDՒNlէ.X Oo&pS<~NO swdM_90l.|ϋS4BI~#gvt(c=3 HΔ̵rBDKl9^L gCgrfX)?hOp흉tUk76XfjL#9CX3raE'QfxP4 IY y lHDhq Ҭ2Ka?F5%Z0yX᝴^( [7Q 0-V}20^ -M= v73#[&a{'Qh!a7eE{`fA\bȖjI/㶟ߌ/s^˛k;3E!oMtė|{mМi?_ v/k?"e#rbU$1Z=c$()$SLObj+~Y<=t!%kHVFs~R\ki2•?:<E `UN9} #ԏ&3M)a{3ߩ.- 8fv0bؐP޽pㅝ/J=S`gRȩk]~t^!_) IJQQ&)a 9 ..8t 3]b@ʻ SjU Ru7lUX'Ӫ8/P wǛk̍w[~8'~>sOn 1qM$L#n7Mf.X$"/^T I"'F09kcRKm_󗖸'?| `s 7uh'"Cʮk r }7x&SNV-fiez h-\4(c8U|_#yC-v+&8{r.p%Jk; 5x@~ZN1 Y9R8Z+nZTIh;SgB{Rt\ؘ܅~l/yzݟ'~)>cpq V|:eyk%k{"'H'./~gYfJ3Y]o&GN5ӣ@"f2% R2O:ҸFɴ%uqex 2P[*ЯB125=[C?|/q'-]fH=xᗂ@!ϛh-g6IkJAS=d묻4G=t&$T 6)Dg$|4R"$uus9ʅۄA| IksiepY t^-޿w JZ 5ъW=5+H \]kI& kjÕL\'r-n'KaD#Z<{[ߊW߃_=p]xf0pLQ}Ũ ;- lD`6}ͫәѭ5ɑ~zU"úCѻ6pqYW/ӓ~:|5NҺi)_>Rcq|2'S_[Izr"C,_> cݯ;B.d 2vj:h&.;h-]:XI RmċBVY:8M[ּ0 Fd"B$iE#^,FN ^gY~ų CN;q A `^iR5aCzB;>˯8W:G:8HT/yxGdd,Q:t/#|;ug'w+{'-xdr.+kZ|F<kqus-N|`m& &3q31mhQƿu"E_ ܟw}{V~a݇8m0zvWDg@"D9qTH!ˆ!|<C4Kq{eQ`RAbgYLqB-|M_N\TԵe|2nS]:az0ێLO a\#|^Ro[[SQiL#.֔_1·0h䴍[9~3ƵP; Wq%2 uŀˋkrQ7TS廏X Dxcg(T%=@uf 4БS.qM [䝎'vZBi\\˶oڥ?2Ĺl6s6mt әćkz[بDtY~ `vÓ<|duGnx\+b,"Y^BZ rxIݩL}%uU3 )'I_T0O` h(A'P^ J3t='FDϩϤ\ۉ'5dXgAvYKA #Ow^&7I ##G8 Ӟ-Bw2 {sxJj#RA,6(q`!9YvoɃI$ꊿ:O ? ݃(<*>rgu^Lnjˣ j;=K+߇'y=204C4lt"'Me8zzX[T6@Etژ L(ֆ;$Z{,Z~ַeUmӛ91<,*)n O‰S~huJdLYZDcJPMX./ǭB) +S#<*9䟝fK [^ߢ[|g E"]+}Nty4LyE ga)9Zp9MWs>7up~D1xC5<Hv@{Yv+.]Gk>d7ʠ/:kݒeCBnuF{NMpM&YRWjQF+"RXt"ii\ۜ_Op mkAV 1[ S z>onqӕM>vp'̤IR=?Zda=ZK1&K >Qmc㝀8Q~.w(.;{@ay\QY8 bNQq6Gt䲅v/y}T?dsZ+G-`if$*N]ZCh{ ó\M\\6l^.f^D mQ5iМw}(D7$@iD\I`VD$$Ɇ$RJ?^ud˦2 ==vƑw.(ҴHxX3 16`gizuP[rS:m%s6eTCh q4 KW= 'uZLv5,iXk2FtUTsDq#p[Z3]@+%KJEԌ$ieQ? $wGIXǓ ܃L0f#JSb;_oĵ~.3w'ʯG{π -ݟc>yd8kJ:ARָ!HQ?AHnbiQ>oWi2ؖ)CWBupEljXRY.u)t;ȋ'{2|K-SxO5 5C#0IrwpN[f#lXZ =Evi祦.J9Ex F tD hr?Ar\l ZjB\WhdwU9&]8v-c I'cFb '%Zq ƀ8*^QS r毺&@x ^%Zo&Ax6-Xl(LE?Ak?݇ө,dIq۹m[\b0&΁r7^MCq I%N앐b$y810lf,wk G zM[=G9p-Fԧ{;~ -Dp)`ʕ^F(F^K'm,*ze`U? &|T8 iXf',hgRu4QwYWev :׆p:fIgwcՁT*e2:7Y]M[]LLm)e;b4y-Xi<vB&$VRM5[R+pG?מ^ɮ&f@D ʷUzVlv=L(dtShEl:zMgڷ˩%=IN&n_{>ۀv,DO[|_*QKۑ͏i9 SƆ6߼t4=+sxmxs$$eb$nK-NR8>LQBpy r"?Ǚ(7GVJV$U3߻SB%1o=,(j,u-7r+^XpMb1~ʪw&+M~sg#KV\X3W^ICE n(iHz4ouS8n&<v [!]b>L֎O.. Χhь@w Y9lP8c 3C<@9e dޥ,%0!F.W? wB'G C'Q b9[)I-zn(m&^IK,kQeB BtZϜ>38.wv5δFǪ8y=|DV@|<t<5ݓH_SX:ttR6k.Rdޭl~ԯߚ@V$cB#t+ETKId:CaSD$vagM/ڵ[-@t57!5Owŗ~kg]F*@"]x?AKkwҪɉR|iy2ɸG\HH\!ٳxI)iv"ʂJ":3"HN"?Arm<_HV,A}ӾIX╞U&]kL7A#}}QbBk=J}ax<` O5^"=_cIGTM$aD@N{VF'/_m/H'XdbDe_څW6CK6~zJtYuv[;l[YiϸOVoɷ[I. *hyҘPh"a _>HL$ԖN5萖͇>{\M&3/Dx͓<aBZp˩oT{-`~Q$cSxp5Vl) lUY5L =@w kOkp' GY̥50OW&a.(qO"}vM>F]]0Y]neO֎4nu neӍ&pG O% 4YQL-E2 IݻWVZK9=:ׯ&fNqzwva jO~4@@4&Pަ)xaKw]^8^sY|D]X~Y秴k@TȮ t081lY> Nhy[=꺟kܑޭ']O&MqF~tR zIiaI=_y).yր"c\ Y+xQOG yOBcjP;j*ϛbmKStQ{)Cip}@Q2=s)@l?H5IQoYve]hA5|۽?{1)o[V=_¢zeJ^./ {ŕ*lrSfmF-h šiCa@YX1i&=DC4@TGJW|`iYMD*H  kTdeqkG[]neջ#pU?Y=Ҹl_; Yߤ*2-.$~1ORl䞟~>րCƼ?|ߜŠ\oi8%7#G[@j@8. .3W^--?Ak++KI;Z}^.yWt˴x^y lf=؅8{zu~u(M^g^ƗTwih5Pt-#QshuS(rRVa6C4ɑhWDJWEd[a=u ]gl/i?,Kś6Ez =A87NrBB{Ehz]ιuV09zݭf2ہ™˿{WN=_fd WZk _@ԼJ,DmVL;'oKw?WҲ&/.9C-Z?bK9v  S9 8#> j.-(wEƔܷ#AHgi;R3 kdqŻn~%{,LuYu*kc ؕL !%m5míL- $hp =CpA3vɁ _*IXMTr<,; OseXdeژn` ʖ й>BҍQ$+L._Oų,(i<̴ٽc-~[O4*д=??gopp/ fXH& 4|ip @ ~F'yrn.LjG\&[h;ij]4h-`1gl?2kP|RK u_Sjd!ddg-ݘ@O;#Oxˉo{-gZ$N É@L環)> Qb,)K'‡Ҵ[J)Voo`1=1;&G75U79uTZai=(M;h"Y~- %֬{׶ko?f*a)@ .-aDPI:G/SS.oN=8rz8+#>ɹ h\OBԒ"|H.|?Ap] 2ʩ5]Gr(׳]?P]j}\%#^bRgQKxMi=VIhw8\E:΄Y@&R07^ʃ?@tm5̵ i8 奬*K7SHw)>xc:x87i/i{dX7Hv_+'n=֡rk#.#@l Z7AΙӫ?G>W{kO0k"|$$ڠoӯWTrYzqPKPlA>T(ÐO# a"N@&/-+":BIHYXQ;6Q7=GK(jޣ%,6&;"߈V} c, ,tŽѠ\1"r(5 Ht%[f"Tx*J?I$-PxKЬӕƭMk.n툛~w5[詉ov=fl8~mg۾MX;lzp7{Yٺۅ}[ ȳ,{j%W-(ڠ题t4IiA?5UNd}.uσdM bڒG.#G/Z٧c"楡#+_/ ']^x-8,PX=dw( fMSJzv&=O$-?[.pIakF@%u"! y dʼ#Cj$`H!ٰW';2OmY %M&]\!mv ߩFOs@0Y;ӵu4ۛmniM87u~w5+pǼٜ-0<߸n}~gꛝ ߴcl7[}\+t1Msv4ڳt|QE3)}+8p VZLn$'=?kBe2"~X%rgHSGq7 ѦCyz҃CSҖNQ>X" vQq[(`7m"LmA-$5O_ y3ym H+.jc>a?jg5WGbjU*im>U2~T^K.m ŷ}Y;ڞjހ[=LV֚fqLlnþjfu;wMgEooylAdمӽ<+1;BxX (P%WyԩҐ#>[%=}.^Zsp9[1(8VSPZ߭ <+#>QbzXZ:8I;俷r16c<_[K>5Mg{a\HYpGG'MؐRounVA̤ع\Oi5AEȬlZвvm0Pb-- /Z<| 6 b3Ҧ\˴i7~K&j/XB%ËA0; '.?/m`;Qv}8ܳκ'#˯Y1@[]Ԅ:;(ŶdxqZTZ&j$lۿZ @ @)_9Tv8a/Vf$O |@<ȜT3ОJekD dK 8Wt:jiQ%> LJU@ 5C|r]_CuzQ.]/m[eRNxtm@,NWFS %W5F 43>(\+(Ŕ;5u10zp ʑȢOR2j~Roz~C(F?;m7<֏:W֏9\z;o+'MPPҍooܓHiIԕu4hO[<\uO(}NH_*\Z쁭?hbG_k?!m]8!-$z8Qհ}Jk! $KZgVJnK t Q/ɮ]96;Vсa`abIB_a_ENy>VD0@w;/Ie+)="?=єTSPI49/s.|J]+!0ݾ篱rٵ1ζ<$G2uFZ!شժZj-CXմ;qϸ\|ɷR#CӉ |m>B"u '(9.ƚth*i{c|` ?#h3>ڀ9kÄ;׺QKcLOcC_~bw6kY$?No ڸ *vS^~VS!':Zl)#i!+ˬ,~}]sDbWdN R[^5* w/sIK[1HA-Z+=+UOy0.hizYpF؛_xSͷ5 KC4[NZ}MĊS^U[tSm2K}# ,FNfjG~wnG-GS؁7h< ^oZRW rF%|6ڪU2.ad3cݣrA!P􂠒ģ[k~"~EcdO=Ȱ(-yKғ#80LThEqNoThF8 <1 ţv C/w cBltBT: |tY$8LM. TVɭDҲW0VV~x*QRc! #8 A&`Ziz1OTx/3o|=}yu0e=OJ=Ea-6>ȶ䐊2(D^.7{5rq# U@9DEAtA"U@5٪`#yh8E89xCg+2KXJ[ʃ++Cm-^|,Җ3$U$cWm_SEbPiMYWHk%mH.106֞i'\zF~ΥS_)Ih4gN[/A==J`I@g/%gNqt@b;S Ͻ+*w?s] qȁa$d Z}燁ʭgA=;?_'Y%m^>C#0!o.T{56- ߒ҇H= yˉF9Uny'hK#CҸ=O{(g!p$@^9zXnt"YEr{J6ZMdm!|J6]yѡr9hY'55UYӚ}:LDĂ+qhLoȣ7X{/(C $~R?[@3iQg7Tl^)q& 8i?Ov=> e`EKДp硑+)kTlj1Lg%j=Skaw,B|ٗ(?-)| tJh@[`,p ?Qe?sȦ;ډ;מkg^VQ8~!@Ft|,O-QyFtJKӤxH$yEl80_H@)bSPcYy8 2 ƀʡ­z|x;v ˟3s }JX A YSPC)\5iAw\ZO%=yDS.RJ'Ed4=\dd%@U]1 ᗣZ5~ @,;:HԩO10ЛḄ4eb'r%XYs@C&-kCN>;Wݒ QU/,GMͺsڽ]_V%e@jx.v8V?О=Z6O/O\|[o[ c] vhbkytuöVkqF{? 2Rإ$Q2`!A;rA2J[T V:t!|Ohx6`8#_.| Q$:XK2/(#|UrF,ծ:<&u̺T埗<;M!_sq,~lX۩e r ";hOUT? !SI\ڛq7ZH`ʐ!8 iV-GĞUhA*飖[f{(ֽZvWЉCI8s, ŝodVJ\Wm*Ys ~Ot4xE?Țr!,QKaf+md̗2M=9dT jd펂\ I`0P-|eA{M5h-Uwb%,7+b9iR;_&G0t86YQ.ECYC$1*]98Zj $4nYI"4@D8y6ËvO?X?M%!Wn.=W-afkr4HQ3hT; XX)i ZƔdN/z*z6EWÁ/שtn^8:vS)qk+嚒_ãm]Z5h6Z+fAw-}˰ `{=t p9%ضŰܮlː KGm/UT^SYQ=IRGȗ.2|rLPi93_C_$4Kbyӿ;.In9r(0x$`ȳ󲦼4咖%sgұbZޏ֢(Z͓x މД ш0=" \´iZ$65lІp݂F|wn% m+"MҶ kIk'ad\>fEr=oX~GIS%qg~.iHۺ\4uFɓĀ06<֊&)ٶ5&L-_t@blsVJ>M>(sح!ZShՓç./֖ h<1u :tP$HZh,΂O'wIY8tGо9Qlqr[K˽,lyO1jWrJ!+K5Q'KxnSO~zղ>ޏkƬs{~WV:;p$nWD hQst@F^*ҼG@^N (POf͈Z9E#[JJQʋYDƵ&j~l{\=Lh꾏i\+'NH]pjQ'Gs>>a8о~ϳTV9j O!dڧXS_;ԫe .KI/:l^2Y.t.6tOt@2ԴfC>24dyaJ";=AP./:閔u5e\}!v@`ړOގUV;/OVTC!q0]Rur))Ϝ. :^;1M/pS9Uk r^4n-?sqzQ7H]ǽqLJb~pf. s8 4~o. B ;~oʚ $fT6Bo9p3\t$&r,;BbM1ä0-``Ϸy4PD ytB ˳9'ޛ{ItJSR:FOm2inQ8ݭ,_˯9Y-_]\)L?MSA-ݗh2eUArA5Pᚪ)\ Q;=,7K,@ʄoNޭF>gĥ|2Oj: S^}\U|mel2YM./Zϥ~ݔ$;MhOXTkv!Y_GOy1y|jڇ⧻oMZᒺ_d唃)7;.OmK;xN`pG=ߒNăŕkZĹa3r%wDSX+ t1e]t2˺ 25ؗ)\iXFp2jKFY9rFۈg.aGkp|)k4׮gX뉄렘R2I-/m%W1شLDv~4|2NGUucmF ¸Mdܴ1MOТdE-<$HP$k:r´ܥ$ޝxdsOz/d ~XhVcH)؉IM4,SJOOLC:[=u`ge$H)$2y0%OL#)1*`+yM֊l#IZck>eG ̪MĿ܆ Zaͤ< 1-,˞ s>j3֬a }WdIS+A$2ZH"~ RN2Ȝр-UPE(x$,7 |]axQڤç5XJ[JNZ%c+,. tQwhndP OKe@,m 2ܫxp&tPAbŜhiY@xZhIZD g݆t~ڿd!-a8Uh8 :,cRY4 x*nM8Gd;ru'0)0~_Z^ς܆%c_҃4!a0),-s2-c4ĵϽIӫFw< Yt%AރK$.j;~~Ϝ5%*xJ060vNksLK[%#-\.e֌VlJ'+ 9,Rc'$ОIĕ. eF(?li)4Guvo\I7cv/KӵҮGQya nb7dW@PrՀ`$WEgv;pb8LPl{ѫ/ƶ,=d~ֈ/3b):l7/ZK–g#q 8眴y TB"]/=B`9 S|:iD˨ G^.K-yʜlQZ j:(>j `׍;+:9S,P+ceS}@&;r:oY>j;uQCG"0P$R cXCe%MԔH)O%^ʰDTPXƽ}b !ϖ'ƍÇq0yQFRȚ}T;ZY>+ruU֓%y)`BuWԂRڏQCF$sD]zO<'QDž.vjgk`ԬospBkYhfa@x߃`ELg84e(r_ZE QJl>xQuiZ;AE"IP}I/X%n]d]{4HnorӢT1d*Lܵ/gBWR{suȩ湔M^B('R6]~6cB2O)cs[OO [ۼM}Jc@w:A@ˇߩջe ;>JkJ}0[-ߜb/2H"C40.<4Z_H.DX[%M4$uReI}Rr i OV Zh--^O5 T&JkKθ4=o/$P]]fyI%cԭğOb@KÁτҀ^Jr1$L1F%O-ǼP֖E!9ײgb{ce4/.QYY"W>W†6j0MheŦ$gh6+Q.;K9?WG֍\e,7) Q/Me<ϼţn} hh_n}i] (VN8ր&Hb/.* oRyhJ:j8뇹xYľ|E>kE#{W 0u_1诖"LMG}U*|;J{EAqښRsʓܮ~d&];!$}HB5~e:ȾYύApHRkxRkBxO X='iw_^qE2znJ5Y# J .~ZH3eS \ %@ZR Or ["!ӲҤ CZj9]N%\ՅkKM?A|תډL_mhY1n< kqC4̘;e{/r5_ɯF*x99OP|:K8d!JYAOWw_HcXiĽ!zC@X0Z`( dN>Z,/r7/zDr)WE(R|Z%IlcԜ6.$ rMÁ.W|*&D9A)[:\ 1Ҽ˚Õ(X+4XZ&؃.0 Ұr";*)-G"hWH雓I jE:锷oi8z9dD_ | i|k\O~㤡Xc[:MJKd3EMRT%YY3ܬ0Zճ!OmOۓt{ZF:D[q=Kz ꃣ?D`y2,Ky(:?ⷷ6|[ Qw_|s՚ȎcكCL9v uYێw%y1c'q2.5֢vy<,"`(Oânn6X:Ћ-,kT&GwnbOi Rei˰PL%(#`_~-Ήnh*϶mܬ]SCeHO7̯,jȮؓ$52?[*,|6:%jGLlPmnY;[ؘ*!p14W>jsꙣ]nޘmg%]WCcZZ~`8:#i zxAH*!T3#꧅QL|DiL]2=mIBKpE@yє}Eeԓ[.%*@áϊDs祏"KBHPV F>-΃ٚZ asJf6괍*q uy_pYpW]J`7ȟ<JC[bj-~y"<ɓ)-2$VX"?Ypw^"pGw6{^ @ Ցޟ.,ƚ/TMyny+g9prbƲMqKvX>ݓea}$.ꝯQi+oO;F7݌ V]bkȰgɃ^RѷABjv\`z2Yr3Z[|f[!_[N !sqhG`Lҽi[NFQn-G Nz-ywdtWYc1@YHkyt7,˽U gXմ V%MiB--;0dn- eFޡ(0q}Yj/ݾ&;ץo%е)^^23]$<ҫEr9钐:L!Z`,]6T \ۿCm6صe6oy> jCR@сJr 9BpM{Q_SEc @@iP1UEn#N?V郖%TĘV4$n@(ScoN2hM~y :o=Wk nUu ӷq/Mu!gA0 DGޭ ڒ.Z+5uϱrr-imjcGUBa,B%abbWiJ(&Ad\^sz-jg%t]ZƷ*cJFE Y.Αx7I6dM0] 1m0SCOcVYBmֳί,ctk-fI-nIKb%`0 5_~:hT贅.X:ҿ?d)+꟡l:Y)LEZd'XFR:G >5tvʝZ&;4nD6zQ-Q|\x{MѿpD-O4q?̐.ݏNkid Zx2/qPv7x,*G`wm+?YwCU+7z QƂ7*ZbbnBaQ(G}C9\Y|r$q;LMz.9H%0_,:| 1P=)#?Odx#rJ# iU_QEETU  Y6唥 Z* @|ٹKӉ`b4s/*[˟ˡu Չ7z=7Y:RYRJHZZBHӢCVI? ir+-8 ^[9kZ-eh(X? h'Vy|RR%LjQCJb 970rE*}i-@<pv9yt8zKKtwcySrwmwn{(R Z P/FM mX6iΌoM24U{#9 VET'Q?ۋQ24+g:!rnKNZJ/9ႤtjtN$5jKsN~dLĽ"𶘔OoCқX*|O*ZQ aB9%۠t?kû4o47 TzWviɒ6Q<5U2 J^iI @=]A>S'YŋKyu勺nt$n%eXv p<@'*j Vd62 8aTe Z@8!aYo9\|fh߉΋Cm #s(g,]_f֨nny*$)|UKve06r4yM͗ b #p=< Q< D?`%SC#̏,RLaP  ުROFv5ɖ=ZuhW;oneIaI١߹J&"цgݲ9d5saebNF u ,ZT -8p-hCִ9>0/Cdl%?ܜ``qP>Zc̻E%0:vfrVʯV}N_?Z (ZS[M@ RѢL9|X\4rӤ%pf嚿-|:sVLqc;O#?m>fd+˵ˀ/@3>"[Lg֧-%j.کcF]j򴀌he4Ͼ"|~شDSCH wED,LJazeM"TŪ֒rޒuζԓ7ڥR Kd[$[~UM!/},ih~>^Q|uY8[%A}0 O'oLX妺<JZJzR*g wPhX m_U C>DGI^!4dTҝ꿷Ceмalb_gTgI K}gOy9IN9HgY1&*RZ hpNHRM[ 7߷`2 )`9Hr<ٳ+2p,/ n9PY&qG۵Gp\Bp([JxhHylBzw ShOA.g^/e2*uCu˃E:.F[. D@ǧ/8j|w-wAQRO@+]R>]cQZj3 Hjjep&Xm*q"[ 9 *u1JHTqգ>{ #X̝PemC9ym*Kku⃙eyn_]1pxxE>$Y]D٪aL8O?nuLiٲd)(Xބl.֎KzV+~&YNBܫ0PI?C&Հ*jePG'ū[bZ'hF!?.i2ggjHmPK<'|Ɖ@ԵTɈ %PyJzp0`4ʬ(Ҁë 7CfxsKeq|4C q 2eIQW>$XaQ,X'R6j0FHg JƲneE*dIF&nWO\H t_y^X~Xv50]1Ya3eUk崫Tۂ[A~V_Ii nTǪ⸌߲j!@y`Q]A049֞;3X{2N,-P0 AHF3#+ƯʠͪhD;A^i咶ڥb}rʊП|HV kcHbt@"]W71槴|KY*bIPbdKWwY~ewպd`r%QޥxրiVE?HRsx_*bSJگ #7qJ:rFAg&-  py<׃,@?KRÚՊ%ҀA)nz*aմ1a1ռdY~32>`wxײDm`>+7_-@B.I9%)}>¿"QJUZ@;)[R挿[vݗcڌg}2ũ l/YzIAj'| 1!deȵB %YpUYҦT  S"+-Oy IިnPT HnXPkڢpnѫ!ZwTqSaqXR'tByϓTZĮ;X3dPɆF͞²@8N$\JZ,8,]ϢO#K ׳Վ+үӨȒ^E}~CpDఘ \GJWԕA˴ز2I̟~_KL} їTVQUƢmCvɱY!N;B*4hiP>r#| (/kфC˘odPʰɖN"l}( jCO1jˤ*}J} (qtH@+-(Zi$:y-FVYt|h8P)ʐ^P]zɗSxsTSpC$&EYkG <,j|tqXCy p?{0+gJ(-z;%^3ظcH+[2YbcBȿ5\1Ze8fn.ā?H\zD΂нB3HmH,W&Rƀ1VH9VNamdŽ= X)/5R;EV^mV[da2 vXqI\!>Hg5s|ue,soo{ϓ~uXq"Z>I{ Qh4vWQPdډ=8,Tn]~BOOxg_iQ2-)bGs*FiIXZoqPMdݩC-ڮfA1$uR,j5Lr)Rl je)!TʂtE}<@P<籾 fa4x\.AydKO4E[6-4$h<iiVȠ1\UŕpL^8KG3w=,e߁tA fic؛u7AtY,mUX:i4SqÊCx]i>,a`P,ft'{5;<@WO3:d wW֯SǪ ƍO1xd`0'^rUv:dXW˽\;"֘!q槽Y4GѲyT/(BYuigk\ kP Ŵ V$ܢbGӔVM5㒔D^~Z*C r1,w:rNNf0)ZȂtc%@ګj~)=y6BD$u*F գ  jni'o285O8CCfCiPc`ُk]0){80 ڴ@1my~z+vWG9`K_sNuP@bN UCZ9WY'*& 43dJ o]%/޺ХNUdD#lU 3mQҵ~_{(}$4J!`QnirimjєZ293W50 *dp+WdTY97*XDPT xPȓ5$h+aJ VlGY WPʮG*nrkOtqĽ=&oWkJKa4nBG%u9*NJjaTPc/^l@BሻZYɣ2oS;U1Rdeˠ J`I㩵Wc&9Ȓc7-;ae6l@i=*c*)If믣>÷T$59,~9; ҇#hoS*)8 YQٸK팊6)˼qU 05%jcQpJ%ssiXk MFۻ5XP.{_ viL2 W15 Ie׳5lKV"PyI;C Lijp`2 FC!w _1 ~0ۭ/{F+1鸑F"PqC 8{V43f+AFUr @WlK2%Z^M#[}.(Ggw.yvm!TsXtRښ1a;ZYW7ft}8&Kӧ͖+Ũ?hVH)^-'ϱ\Ss[f/ҁmɉ7;^7?fͼ+IOcYȖeU` b!~ho]Jg[+.me{28b&NoQ*LrQ < 09iK,5U!S0@j:Hiq lYt'_ dOgN,` g*JY*o 0pL2rvwSfePҚ󼗃3] ^ק SK(9obЇ~u5T!]PV YS@J6(AӲdSxQQ[*sfX,L{*Cv4eH @^lO9@r%r*?9#"RM[m|#|iA}Z92宔&SI,S{HH%2Z :]dоUq2kxv z i?~FT7 qJˢa@wma:rIfpƵqID\Z.خ7 qkI*!(< bM+B.mO}rQ6%bQ&1(-; `%AefJ2[T\Lґ{wua=W㰴mVZ}⟖Y/ STxY"<ؼU M_ĿBX-=ʻBKA$9g'tEVH]jzɤ 2ؔeRkIr(b:/~d!af/QBgǡBy'#u*KH=7Pff닜WmΰKݠ(.q"-,lsnt,Ds:0eV[mM 5|3fda&(-kod|%'c/d)U:[!qS7VPb+Q  'hOZza1Pъo|k1~1tq\XPtXIyT/E/pݡWM(<2Y9:H&'sp9FuaB*n#k>md]4{gY lE^}'"%`.jA%6 o'@CPflZ6~vȤo1 w5"NNVDU h56b{V%kI~(y-<.X*n}r!d;p9"?yEZb g ȯ @|PPŗF峰f;xY1%|Ƀ" @[g䠗ʣ2-BXk\u_Yz2IKWdybYւ' l t@Tq[p'y3b_|>exK$ǒ(ɚ.@~J"{]C[D~\.~3wAP, #qvNα*rI>t97+uy -cOD*ςY2N2q|Erue!0ӫrkɪ(!EkAͲQ~2{ߜ_@;C*$isȪܢ^]<Ġ|2fyE쐓UX"a9T5<[N'7 xY!` fX5hj.:xk"KL07Ҵ4.HJẤSyn^TF\p&|K~ppF;FԱ斫C3\,KlcXCF-ZCvPt5.֍yZ0mTV`8aIENDB`kylin-video/src/res/order_cycle_hover_press.png0000644000175000017500000000223613517016402020731 0ustar fengfengPNG  IHDRp ntEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp <IDATxb? 01 @1VƽBQ0@JFeNv_c,IdOPaH!,N&]c4d 4R t_GhACb']hD'XR5A@? :xx)IENDB`kylin-video/src/res/playlist_delete_button.png0000644000175000017500000000537213517016402020602 0ustar fengfengPNG  IHDR Vu\ pHYs   MiCCPPhotoshop ICC profilexڝSwX>eVBl"#Ya@Ņ VHUĂ H(gAZU\8ܧ}zy&j9R<:OHɽH gyx~t?op.$P&W " R.TSd ly|B" I>ةآ(G$@`UR,@".Y2GvX@`B, 8C L0ҿ_pH˕͗K3w!lBa)f "#HL 8?flŢko">!N_puk[Vh]3 Z zy8@P< %b0>3o~@zq@qanvRB1n#Dž)4\,XP"MyRD!ɕ2 w ONl~Xv@~- g42y@+͗\LD*A aD@ $<B AT:18 \p` Aa!:b""aH4 Q"rBj]H#-r9\@ 2G1Qu@Ơst4]k=Kut}c1fa\E`X&cX5V5cX7va$^lGXLXC%#W 1'"O%zxb:XF&!!%^'_H$ɒN !%2I IkHH-S>iL&m O:ňL $RJ5e?2BQͩ:ZImvP/S4u%͛Cˤ-Кigih/t ݃EЗkw Hb(k{/LӗT02goUX**|:V~TUsU?y TU^V}FUP թU6RwRPQ__c FHTc!2eXBrV,kMb[Lvv/{LSCsfffqƱ9ٜJ! {--?-jf~7zھbrup@,:m:u 6Qu>cy Gm7046l18c̐ckihhI'&g5x>fob4ekVyVV׬I\,mWlPW :˶vm))Sn1 9a%m;t;|rtuvlp4éĩWggs5KvSmnz˕ҵܭm=}M.]=AXq㝧/^v^Y^O&0m[{`:>=e>>z"=#~~~;yN`k5/ >B Yroc3g,Z0&L~oL̶Gli})*2.QStqt,֬Yg񏩌;jrvgjlRlc웸xEt$ =sl3Ttcܢ˞w|/%ҟ3 cHRMz%u0`:o_F'IDATxb?)D05@IC8XHIENDB`kylin-video/src/res/option_normal.png0000644000175000017500000000226413517016402016701 0ustar fengfengPNG  IHDR$$tEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp O$IDATxb?:`bC1v,HlF -benY  Fl'7h!$Ft7n" cS3ښQI`t'' F!"@9 "*5k\X(_aD0k`T+!F4bBJBTw6(?lЕCih4 ԣu=kIENDB`kylin-video/src/res/quit_hover_press.png0000644000175000017500000000206413517016402017420 0ustar fengfengPNG  IHDRhtEXtSoftwareAdobe ImageReadyqe<&iTXtXML:com.adobe.xmp IDATxb?01@b  01«b> 2F 0@L8ہM$DH|?%`@alo0rp0#* "ࡈlC3& "YAM&IENDB`kylin-video/src/res/unmax_normal.png0000644000175000017500000000227313517016402016521 0ustar fengfengPNG  IHDR$$tEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp S*IDATxb?:`bcdī -b"h+abz|C;E4݄Kb1mΠT`q\ÈO! @#>#e~ 5tDgj%٨F4X OZez4 WQ0* O(0l?Q ;|.6KzIENDB`kylin-video/src/res/open_file_normal.png0000644000175000017500000000043013517016402017322 0ustar fengfengPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxb`ޠa>SÌGs?bĦ 9*ftPQZč@.Y/7pH @v"zx)@  @<_qx d8C H *!1H0OBլa`JL@Ibbǐ20/{yA{=IENDB`kylin-video/src/res/list_cycle_normal.png0000644000175000017500000000301413517016402017515 0ustar fengfengPNG  IHDRp ntEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp IDATxb? s`bDQ$#$%V` X#5Od @t0BURP1s@8 dd"dj!P*hĥ@|Y1݇?ڍI ?>`e@+X(A3 CDP* @B>/8 O`ACDJɯp7D.L"5{ AifPJ zuq.@2@h ҀqK|NB`88RNb/ b~v VfpPzę|DHZd8P_r\ -A2Lĝ Y 3XA-`P3(Sl` F:dLH@c9P j?@ ^ĠBPRz R@  GI# 6s1n\,͋ HnnEIENDB`kylin-video/src/res/option.png0000644000175000017500000000301213517016402015321 0ustar fengfengPNG  IHDRl$jZtEXtSoftwareAdobe ImageReadyqe<niTXtXML:com.adobe.xmp 62IDATxb?:>̀"x; 5L dd >?h$ %xj FAlDI6]0&&l I*Ĉ-J5DL2|bDB:\ -Ѥ8G=6Vv">RZ[:XG"R [{ /X84^>)#E 6$It>~)JD<6h#xI5Qk)0CxD0De @N{ܚtBՄT_bQ0 ذ'U]Fv˶{ye[LWd2ث5qt5~2{_+sm]xbmV<1Øa0f3Fp 00Rgقפ{IENDB`kylin-video/src/res/volume_mute_normal.png0000644000175000017500000000063113517016402017726 0ustar fengfengPNG  IHDRw=tEXtSoftwareAdobe ImageReadyqe<;IDATxU0 l <' p@Gp&zHcrW_/cL+ư| A'o$p 5bJă8l{Rq4%[p?s*9|=+_yB.'HN})I,H]OP7hI,e/_HH.SV2zbTd^U떣RQxQwHh7#>7m$ >GS35#&ԇBqwllJL/jma TOR4=fѲ/YIo.tQIENDB`kylin-video/src/res/min_hover.png0000644000175000017500000000216213517016402016004 0ustar fengfengPNG  IHDR$$e?YtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp =IDATxb: 01RĈlN9Ĉ |QC m` |~'AS[\^95aU7 stj#[@QF-ꖱn)>THFȨe edKWIENDB`kylin-video/src/res/fullscreen_hover_press.png0000644000175000017500000000247613517016402020607 0ustar fengfengPNG  IHDRp ntEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp jdPIDATxb? 01 @1(^?VeV, ,0.Fl M @(6"l.G-`gM7P`HsƇqdOu#AT7y(Al Rx3?. P9,>gǃG#: cb#̆ PvF<`ɇ )ٴ0\E ܇/%\,JJ\R   ; *` +H@F4s|[9@c0j[R\H&2 3e* >HrC*}  IENDB`kylin-video/src/res/quit_normal.png0000644000175000017500000000030413517016402016344 0ustar fengfengPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<fIDATxb`00O (WO B0 a a`\y/*@jvr\T04d6T Dd&J@f%]2SIENDB`kylin-video/src/res/spin_bottom_arrow_press.png0000644000175000017500000003555313517016402021013 0ustar fengfengPNG  IHDR |@~ pHYs  9iTXtXML:com.adobe.xmp xmp.did:25d3b678-10bc-fe4d-ba41-689616e973fe xmp.did:4DB9AFCA5AD511E785F9EC65476E1141 xmp.iid:6c5d26b0-8a1f-d547-aa9e-7750d603fad1 xmp.iid:51e652ec-356d-ef43-a124-5fe63f3cb50c xmp.did:25d3b678-10bc-fe4d-ba41-689616e973fe saved xmp.iid:6c5d26b0-8a1f-d547-aa9e-7750d603fad1 2017-06-27T09:11:18+08:00 Adobe Photoshop CC 2017 (Windows) / Adobe Photoshop CC 2017 (Windows) 2017-06-27T09:10:58+08:00 2017-06-27T09:11:18+08:00 2017-06-27T09:11:18+08:00 image/png 3 1 720000/10000 720000/10000 2 65535 17 12  cHRMz%u0`:o_F;IDATxbrppPSSspp`b``^bRSSSSScb`````brppwQSSwqpp"#(1 b VAGl\"9}?0 .bRTyN4TBr먙fJNqG_du|,c8S\%3AsO9w~XBɿ􏓟ߋM6U}àލswi}~ 0C )*?,E ``` `ݕ~IENDB`kylin-video/src/res/cancel_fullscreen_hover_press.png0000644000175000017500000000254013517016402022104 0ustar fengfengPNG  IHDRp ntEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp /JrIDATxb? 01 @1 @ʸaGя{7Y @b$qZL 8N 1~~v½@5ktP6xݟ0Tc$8 SpNņ!cθ~B* z70O'Myx@'*Q-h`#4@L@M(^ac•ذ # ? YNĖOXG(#'@&[!0 g,.RDW`:z 9aYyEf b)> x@L'hD򠓂鄚aB κr)oIIENDB`kylin-video/src/res/playlist_close_normal.png0000644000175000017500000000260113517016402020412 0ustar fengfengPNG  IHDRp ntEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp kIDATxb? F &Ȉ ACC: de@+2`AV @tEg3B9Hj3`b4#.2@ !n. >4 90`FcjZfĦDO@_C6\nN NdAw %yp V /Q5J0  ,$#Mh>'*-AMe k*w,X iq ПE@P@; 9h"9C*J( `e!ŕ!Nrhnĕj>@28*ٞ|, @>P!h݋ɫvH SށIENDB`kylin-video/src/res/trash_hover_press.png0000644000175000017500000000205713517016402017561 0ustar fengfengPNG  IHDRhtEXtSoftwareAdobe ImageReadyqe<&iTXtXML:com.adobe.xmp IDATxb?p/f#@1rʀ @H/H](4 0lAn2Y0 tdᲂOP` ɾL#60b fA2k@1_ G?.21P(6f$ր$,+:y5IENDB`kylin-video/src/res/help.png0000644000175000017500000000115213517016402014744 0ustar fengfengPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe< IDATxWq0 dA:a ` &H6 &h[R&1V\z|AI,e0cl6- SM"Rhh&$_BYi ":Edge1 dDO[v7j'] ވm$eYi} gTǶ}ᐏ8*r88"{X-/c|7j#/pT[?+?һ5y#o;⃁ʙ$J+Xޙ[T23xHꈩG5/~7 ^d6"1NR-Pb!Ȩ𣸲cPѾ >@`]x-']1POi'LE~kX5δCR!5 MKneÄ}ZgJ_౥- F-b PFmnvD(8JW4^LM-w4]rj&%0O.w ٩IENDB`kylin-video/src/res/cancel_fullscreen_normal.png0000644000175000017500000000255613517016402021044 0ustar fengfengPNG  IHDRp ntEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp 77IDATxb? s@1( l@CCZ0~& Ť<d72`3 'DI3U@ :88h?P L^ V.A= CvX >f$qm r$iCHr I1Ph@C2X_+ PWOP|*@@MQ nP (΅+a b?hPj4j9 L!Ac;(`i (ҡ09K А=(__@f,,TT?f,pnIENDB`kylin-video/src/res/dragbar_normal.png0000644000175000017500000000173113517016402016771 0ustar fengfengPNG  IHDRLѥtEXtSoftwareAdobe ImageReadyqe<&iTXtXML:com.adobe.xmp *IIDATxb?01@@1b\@VAX 0 6zI(G5SQ3*BQIENDB`kylin-video/src/res/checkbox_disable.png0000644000175000017500000000233613517016402017272 0ustar fengfengPNG  IHDRhOGtEXtSoftwareAdobe ImageReadyqe<viTXtXML:com.adobe.xmp 3IDATxbL &Č @DZd@p=0YRFiL@=HTQQѐ H”0E0H}H SihJ"V_%T<,0{Au!Hyd<r:P>l 4h(t gYU tč@W`MPM@=SO+`Ѡ JR 4P@/$8ZM%H@GV}1oߞIENDB`kylin-video/src/res/unmax_press.png0000644000175000017500000000245513517016402016367 0ustar fengfengPNG  IHDR$$e?YtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp u?IDATxbT[ 01(f _};<&&#p*: * `~=>6Ie43hȕCs'BL"`=ȮE1 L# o2X%1` 6̤6! @C;6i^@ Zǧ Xv07rTʨ#ĝL = C" mFfG- G,$2ZVȥ e_ܿo4, !(К}Z4`xx{jx90"#GQFeHvT3mIENDB`kylin-video/src/res/checkbox_unchecked.png0000644000175000017500000000210213517016402017607 0ustar fengfengPNG  IHDRhOGtEXtSoftwareAdobe ImageReadyqe<viTXtXML:com.adobe.xmp ηY bIDATxbL @0 #T \-\> (0J$)}@|;i$ `xC3L4BTT>\?IENDB`kylin-video/src/res/spin_bottom_arrow_disable.png0000644000175000017500000000227613517016402021256 0ustar fengfengPNG  IHDR |@~tEXtSoftwareAdobe ImageReadyqe<niTXtXML:com.adobe.xmp k IDATxbvpp`cceb``Ĩ@@@@ *  5`dϟ?!23 %%HKK311I S8 b52`bzzzh Qƭ[sQ!KN(!pESr333hx_~z԰`uݻwx-R3=Y>k#IENDB`kylin-video/src/res/no-video.png0000644000175000017500000000112213517016402015531 0ustar fengfengPNG  IHDRFFq.tEXtSoftwareAdobe ImageReadyqe<IDATx윁m0EbF ` `0Y tݠl@6`6h_UTvO:At:/KfyL ϓ j+GU)(L`F`F`F-aL%87n{:Ci_zrLm0 y8sp/ *Ug  c+ճU|9d 8x=CԳ *_O=S%ax﹬u'SS)f !רf^cGlnj c3/,׆R0~Xk*SٔT{C*Yo2:U%r[6AT*)Q%Yvex -$pTÏRnO9`TVvE'ɘkiqK'o s> %i<ƹLvn IUIENDB`kylin-video/src/res/help_normal.png0000644000175000017500000003467513517016402016334 0ustar fengfengPNG  IHDRa pHYs  8$iTXtXML:com.adobe.xmp Adobe Photoshop CC 2017 (Windows) 2017-07-28T15:55:05+08:00 2017-07-28T15:55:28+08:00 2017-07-28T15:55:28+08:00 image/png 3 xmp.iid:758cd1ed-0b8c-534a-b437-50faf656ee78 xmp.did:758cd1ed-0b8c-534a-b437-50faf656ee78 xmp.did:758cd1ed-0b8c-534a-b437-50faf656ee78 created xmp.iid:758cd1ed-0b8c-534a-b437-50faf656ee78 2017-07-28T15:55:05+08:00 Adobe Photoshop CC 2017 (Windows) 1 720000/10000 720000/10000 2 65535 16 16 ^2# cHRMz%u0`:o_FIDATxڤq@ De(( B*0TTR\ %#:xdW|^Жr ݀k3&j-x[/hՏLPeM:`.7N>gyxeһ3A]gIENDB`kylin-video/src/res/video_normal.png0000644000175000017500000000053313517016402016474 0ustar fengfengPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxڔS 0d  `C a:lȱ^r!{wk} uOViF E 00W@; E} fu9"^Rb&9Y"S@r k"щt\(Vd@҉)8-kzdpɃa㛴 mŖƱ3.5!A|.beT1M'B$˟[8e"ITE{_c4bܩ IENDB`kylin-video/src/res/next_normal.png0000644000175000017500000003636313517016402016356 0ustar fengfengPNG  IHDRp n pHYs  9iTXtXML:com.adobe.xmp xmp.did:24776fe3-5e39-7846-8bf7-7165f60dca4a xmp.did:D16B8C17524511E7918BD55A48746BA2 xmp.iid:b0a3a9f8-6807-fb46-977a-34b6ba3cc8fb xmp.iid:2a7af3b8-43b0-6745-a0f2-048f0ea0e907 adobe:docid:photoshop:772c815a-4f1d-11e7-a29c-ee28c792f004 saved xmp.iid:b0a3a9f8-6807-fb46-977a-34b6ba3cc8fb 2017-06-16T12:25:13+08:00 Adobe Photoshop CC 2017 (Windows) / Adobe Photoshop CC 2017 (Windows) 2017-06-16T11:42:27+08:00 2017-06-16T12:25:13+08:00 2017-06-16T12:25:13+08:00 image/png 3 1 720000/10000 720000/10000 2 65535 24 24 g- cHRMz%u0`:o_FIDATxb? 0000466 000D2bAQȈb?CccsM $` E0 #z(lΫ0T&I+T4& 쾈/Fpq_ $_n$ضDSFn:/58Z: P=3x`d,K䞠0^B0KHY^`x0-l?4{{q@Wc&/WDrm5H}7w-QC]OEX;[Si8S ַ*uU}րjBnw1p^@=v6&0^zQ| p讀o4"uxn>p2zgFID<϶lIENDB`kylin-video/src/res/forward_10_seconds_normal.png0000644000175000017500000000314313517016402021050 0ustar fengfengPNG  IHDR tEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp uIDATxbj fa` p] !|`@|f~ ?TEKE;gb@@r @1 \-0{YlL, @u4 Yg+!@` nt1  j(#d46PqV"F# ) !O%@ NAQ Ѽ/E @38(0 g|04XİFo >b(XA O41 a&yc(^PBxq.Yb~P\ E؜K,*. 8CL3ԉ݃:#:Sab,p@ 5ހ78L `0g]GO8Bb?Rba!1ꈶPOH PG0 f nE[G]3:^r,d@+NOC|0r-.Z#b b> ~ϠYV>a] VCv̈́x U3>.{CQIP*4IIb@*:P ZHj>jHYhq!';h~FnS,Xux1~R]C\IENDB`kylin-video/src/res/spin_top_arrow_hover.png0000644000175000017500000000233213517016402020265 0ustar fengfengPNG  IHDR |@~tEXtSoftwareAdobe ImageReadyqe<viTXtXML:com.adobe.xmp IDATxbtpp`&  F | @@/#\H H#H+, "@ es/n9$ PF,Xu@=O|ځB}+l3f<0KJJ)/ |8 p@ dCILVŵdT<|yML4 ?p= *~hЅUon~zQN=_bIENDB`kylin-video/src/res/playing.png0000644000175000017500000000042413517016402015460 0ustar fengfengPNG  IHDRJLtEXtSoftwareAdobe ImageReadyqe<IDATxb` h #@=,*Ҵt(m=bYon?+"EPq n=O>w4j#"$P,Bza}|GEHLa :$043,͋ 4_IJj/Ӭ*[^- .:tIENDB`kylin-video/src/res/combobox_arrow_press.png0000644000175000017500000000237413517016402020261 0ustar fengfengPNG  IHDRtEXtSoftwareAdobe ImageReadyqe<viTXtXML:com.adobe.xmp dIDATxbtpp`& ~efcc3T @@ %%P0# `DW D =jjjؕK_+\Ά mf`dzH#Or+>"B52`z|-S#$aor_X6d!䘠sWd 6=?͞#( "@qpC?<%9C/)m5oBٞ]5&gT(:,=!}ÍHT<IENDB`kylin-video/src/res/stop_hover_press.png0000644000175000017500000003541013517016402017424 0ustar fengfengPNG  IHDRp n pHYs  9iTXtXML:com.adobe.xmp xmp.did:24776fe3-5e39-7846-8bf7-7165f60dca4a xmp.did:B1B90886524511E7AF37F2B3552750E4 xmp.iid:9194b26d-3322-284e-8ee6-18e5c1dfc9d8 xmp.iid:2a7af3b8-43b0-6745-a0f2-048f0ea0e907 adobe:docid:photoshop:772c815a-4f1d-11e7-a29c-ee28c792f004 saved xmp.iid:9194b26d-3322-284e-8ee6-18e5c1dfc9d8 2017-06-16T12:25:19+08:00 Adobe Photoshop CC 2017 (Windows) / Adobe Photoshop CC 2017 (Windows) 2017-06-16T11:40:52+08:00 2017-06-16T12:25:19+08:00 2017-06-16T12:25:19+08:00 image/png 3 1 720000/10000 720000/10000 2 65535 24 24 p cHRMz%u0`:o_FIDATxb? 0{7LbDQ5+.TBIB0rY5$9.Fd xb`@ "O9*|?ai "Yn4)000|&p1b@_XHp6, IDATxbT[ 01RĈl_ I*C8Ĉ XQh t9W!$}9Hp>dM$ L,BS_O+l\26"moH #髍=)$ "iH h_` w*2{8 =X។MW7Z6x-jHG8ɕ=&T6.q,Cr1C!ЋQFe2IENDB`kylin-video/src/res/close_normal.png0000644000175000017500000000237113517016402016475 0ustar fengfengPNG  IHDR$$tEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp ^c IDATxb?:`boDk L ZOsQdS ںz 1D@G†h|0(f۠26Z\T-mBb_K05 r e;t@!*xDD4GƄFeDιѼ6 0ڨF4 *gוX[-UtP8JVB\ 4Pդ u 1%556h3ڞ7LrC9j`!bF~Au;ΎVm IENDB`kylin-video/src/res/ok.png0000644000175000017500000003456313517016402014441 0ustar fengfengPNG  IHDRa pHYs  8$iTXtXML:com.adobe.xmp Adobe Photoshop CC 2017 (Windows) 2017-06-22T16:14:06+08:00 2017-06-22T16:14:16+08:00 2017-06-22T16:14:16+08:00 image/png 3 xmp.iid:33eaa353-cf74-6f45-9cc4-eeac871f3c63 xmp.did:33eaa353-cf74-6f45-9cc4-eeac871f3c63 xmp.did:33eaa353-cf74-6f45-9cc4-eeac871f3c63 created xmp.iid:33eaa353-cf74-6f45-9cc4-eeac871f3c63 2017-06-22T16:14:06+08:00 Adobe Photoshop CC 2017 (Windows) 1 720000/10000 720000/10000 2 65535 16 16 3e cHRMz%u0`:o_FIDATxԓQ @Dߑ @Bq@@PpXup%%_&3U!`H^@!18LA9P4SI])<@m//``9~@a[[tB =5Qkp*qLbnт8u"[/mYcm>k`UQIENDB`kylin-video/src/res/single_cycle_normal.png0000644000175000017500000003521513517016402020033 0ustar fengfengPNG  IHDRw= pHYs  8$iTXtXML:com.adobe.xmp Adobe Photoshop CC 2017 (Windows) 2017-06-16T12:10:05+08:00 2017-06-19T09:09:50+08:00 2017-06-19T09:09:50+08:00 image/png 3 xmp.iid:1edaa08e-0eb0-ac4c-b6df-58b735adbacf xmp.did:1edaa08e-0eb0-ac4c-b6df-58b735adbacf xmp.did:1edaa08e-0eb0-ac4c-b6df-58b735adbacf created xmp.iid:1edaa08e-0eb0-ac4c-b6df-58b735adbacf 2017-06-16T12:10:05+08:00 Adobe Photoshop CC 2017 (Windows) 1 720000/10000 720000/10000 2 65535 24 24 - cHRMz%u0`:o_FIDATxڴ1KcAQAF,zl bNdAZ,lld[%ͲU၅css0(idf9=cem3q٣@C9p:ګI,Z֎%X?{LFdZ=F0>R%,UuT " l].̗s ?OnH޾?9`^zqh=^1"5߇W?8}%"wČ~?"#"]/^~oJ \E%k UtS{>,5Y*h]w<s2T}W1K-C{~n"5W-f)#rrCΧE.7&>h~#AS1K #"W^$"E7J1}7m9 &)Q+X tӀIےf}p\vƌ~G7.Bv=Eb ʋdg m*$f[֗L?IENDB`kylin-video/src/res/menu_selected.png0000644000175000017500000000212113517016402016625 0ustar fengfengPNG  IHDRtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp ncIDATxb D?@1L Bf@@`E @,$ 90 @F>*D1 iI@AlIbbg\IENDB`kylin-video/src/res/max.png0000644000175000017500000000273113517016402014605 0ustar fengfengPNG  IHDRl$jZtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp 蛐pIDATxb?:>̀"x; 5L d??EF^954Ĉ8-p(kbTyĈ-J5DZj p!0F,ZJ j#I}%|F(eG.2gT/AhXIH3%€w}OdKU1B t @Dejb1@L0Bq&1 *P [Zx G@hRبF=FQ'N7)=Gbڅx?5Z5m {Լc[TqTU nhبdžЮP EͅX߼")3b/ ģy }5 ƂB޹g7>ؙ (nİ3F k1\Eou*ܭ>I7a!J BwIDATxbd L ir<.  @"M@N ӭȨ2&@| b,PW d,LPH `z@U1% 20 ~ A2FX< "@Հ ^(=$;i8A>{lP7$ˡXC I#4́7@vnb1 fDR$)t ė%y+Pq  0oU vH\|2 @J P`;rj4j9$bؚyA ==H@< C$ dXCdtJR@ )YPE/47rPJngIENDB`kylin-video/src/res/open_file_hover_press.png0000644000175000017500000000212513517016402020374 0ustar fengfengPNG  IHDRhtEXtSoftwareAdobe ImageReadyqe<&iTXtXML:com.adobe.xmp IDATxb?01@@1" Yip *iA@f&$v7n.c. HrQ P|R 9x?,Aq̠E% 0#!CDR:l?T 4H磉3@Ca hpp` u4D`aIENDB`kylin-video/src/res/spin_top_arrow_press.png0000644000175000017500000000230413517016402020275 0ustar fengfengPNG  IHDR |@~tEXtSoftwareAdobe ImageReadyqe<viTXtXML:com.adobe.xmp T eIDATxbtpp`& ~ Fl @@ۯs w#\H#H+, "@ eЀ"c$ PF,Xu@=oC&swM7k@FAM|G Xp@ d{%nG_R"k ߄Nd{v$fsvr_\/,7 dEnSDdhIENDB`kylin-video/src/res/max_normal.png0000644000175000017500000000220413517016402016150 0ustar fengfengPNG  IHDR$$tEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp .IDATxb?:`b( Ftj#,@\Osh p)O5ip"*0f۠6?]B H5q@&Q(hm?@-1kA4O|T V" 0ϤIh\h(Y~넱~Nx| 2sa7ֲlJo82JZe'j! QRTs)a ,9(x(iF7q~]go M=@` +dJCI 6p Ǟs+=J$~  tKaL~(eu*&C;Z2 2א!T|'m J=7u hxoB:` eVU٭h-_ƵKu0C@G$53Mi\ 15J)H(M kb=S[:n-H:a (ukؼYɈs9Wj@/z ҳ%֗;p7@Vd7%򝈤 xBK.}|i_È$JM!R<$R=SZ!Po06#@8|QIENDB`kylin-video/src/res/play_hover_press.png0000644000175000017500000000404113517016402017400 0ustar fengfengPNG  IHDR==ieQtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp >͎3IDATxb9À01( ~fP௲%/:)Vmjz˷V 67?)@1R7R__T "h@ߺ0E.*?l Y^iD6l" (Ӏ9}j^,˯^-_PÕ:g4d?Yi'ۧZLϯɓL@IZZNa5ށ8 /0[o ɲlgUrfdzݐ󟜭Who9JWxQ?+3WyXAZh[ԁG6tj<}nhsiЀ9ӈ QG-<`ל3E~@зF ,ta3鷎F2D隸Xw5{~oOT2sWvp5;*}YwgRŻ4蚏˶,? u㝅Z=WB?iJ\e{(b(٣O\"h)GN!R}tw%7XHOp^meZ'vmxr6]foI ~c 📟2EkWӬLʀ6J9YyWJI``dbd0FﰜqxL ];eI 1zHIDATxb: 01()*?4ĈlNqsA8wY݊fPîWN L">r܉m/>RρZ3ѼA;4ࡊX9at FhAtB^V,0@$@ LXIxITₔWh96``q~#} NF&rkЊ!q6#3wՍZH@aI+cH ze@῁ ZbV0C pIDATxbtpp`& ~ F  f -1#RdBAd bbs$a}b52`)qt"~޺㯟?ϟ>"b\%3 %IL!=#c!#:{ҹ&*((|t>W_|x/5~ xY!IENDB`kylin-video/src/res/max_press.png0000644000175000017500000000232213517016402016015 0ustar fengfengPNG  IHDR$$e?YtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp pIDATxbT[ 01RĈl_"8lX#pZv3\\8 hJv@m r,Ȏ0WCnVr @NtOFhLX"[pjLj4T{ih-gK\pT5 Qpm/ mFfG-)X/0ULdZpAkOA 4Z\Z6j>YIENDB`kylin-video/src/res/close_hover.png0000644000175000017500000000262713517016402016334 0ustar fengfengPNG  IHDR$$e?YtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp TIDATxb5w.`b@Po>#yL8M F4s>9]D})Ȉc̎X%C`ȱ\ x? GJ`? bmcga{{GnP3(Έ&Ϗl3Ղ|mDNt3בdi{Ǒ-mwWf W%Vȝ3:K3~VQy~= ~털̦D@6Ś. mFV&66&:hb#.,E DA+0AsPRLˀEɿ7o%X *& Xcggfb?֐g@["?WK*[O++xXX"x"ׂ%ȨeC2;9;IENDB`kylin-video/src/res/volume_mute_hover_press.png0000644000175000017500000000260113517016402020774 0ustar fengfengPNG  IHDRp ntEXtSoftwareAdobe ImageReadyqe<&iTXtXML:com.adobe.xmp IDATxb? 0q/!(H ѕ1`(b5 ?A @ PlD,Pq" 0AdOp@&q@D0`{>&F4$=(!Iq",7t#9IJ7d ӁN@8a Yk!pLHC"~` Hfa1 $"%UA|@{ɠ8q=-  5&X,K!tAhKJHiI)A 6@1-1zcIr46aa@!`AKe HI$mF,6@@h6 w ^q?;YBPχfh6e5bJa\r(<# ]-R1RĔ_H6. ͵86$) a!{94mZ4U {q]IENDB`kylin-video/src/res/clear_left.png0000644000175000017500000000160213517016402016114 0ustar fengfengPNG  IHDR D pHYs  #uPLTE  !!!"""###&&&(((***+++---000111222333555666777:::<<<>>>???AAACCCDDDEEEFFFGGGHHHJJJMMMQQQVVVYYY\\\^^^```cccfffiiimmmrrrtttvvvwwwxxxyyyzzz{.ntRNSM~bKGDf |dfIDATjQΉ 4BB,t6Zل@lEZ[{+[/kX6B,ܙ= @@\ d21 A9SdT)> aNJedFIY6XE)?̣3ٓb+vN!J̚yUv;l뺶n0if$*s\.7/>/`}%$]WB[ %'Ivd=zo9B'@`ٖdIX{&NU y[fϺۧzM7 Q/^Ab8@p~lxqr[Օ$#!QD@b#sK7 OwqIENDB`kylin-video/src/res/screenshot_normal.png0000644000175000017500000000055613517016402017550 0ustar fengfengPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxڬS @  d:200228䝩K^JWg$IIպ+l,w2@Mg kIDATxb&p10 o@ ѕq>)  U b;% M@p@Pf|($D B}'H pADU ;D0ERȌ 5̇:(q>H!Ա݄<?.`b@Neۣk`D DX 6@mi:BlQ @5@=r!{Lh xa@gGbq}k0ġPhr,Qa, 85l!nKz$$AXZai X` "kN:  ;) lE#bPҰ >@ʪa. A%  H@  + f 8r<+4~zwョqG r6<|~f ȓ !B$%AE-9$3ԇ k ;xÒıJ,ݍ#%p:a\M.$ީaS*9"6I'{ D‰Jځ E'UZ9 h#Gofy(vnai&;F/Gg VW(RnIENDB`kylin-video/src/res/delete_hover_press.png0000644000175000017500000010155013517016402017700 0ustar fengfengPNG  IHDR Vu\ pHYs  iTXtXML:com.adobe.xmp Adobe Photoshop CC 2014 (Windows) 2014-12-03T16:31:02+08:00 2014-12-03T16:31:31+08:00 2014-12-03T16:31:31+08:00 image/png 3 069505EF8348FA35AF3BB18BDB09ADFE 07806C65C4910A3DBED1594FDEF99235 0F9DB8F9B3C645EFF27E01C60D3F3432 241ED29BCF42C6B6BBA88600B23F125B 24C1BE3A34E81603B62E933DF8A45E04 257C7629B7F41750316EA19492C65422 298AE66CDDA0676D497FD662CC46E789 2CD3E2E172E32A23791A7458751FD50E 2D49CC94BB3723FCCC22EFB712EAB720 2FBE92DEC98BA5F0C3F3E23C7078B780 33743A05C6E6532EC0B1712581186ECE 358206C7573FC1FFE4A5F9E5999CB595 36760943676D0FFBABD1E11760C9009F 371C9251ADA2EF74EA8EAD34A8EAB242 3B333EB24BC8F5E19741BB267FEC98B4 3B6D44491F9DED4B94BD58F461F37FCB 3F5BC49E27AF78CC3190A749F65E0163 4ABB7175DE4B07BAF86A23279167654A 4BD5C758D3D06A39CBBACFC3CFA34792 4F466871FA7C5D2CBC9EE072C5CA5864 4F89C5CF4A3F2D476B60E939171F684D 504D76B74938B491EB6B067232EFFC41 51BD2AB38F4023E650CC00937FFDE48A 52F09DE3C1E8ACF272BD84B37AB1D87E 53E36C31D071914B7BE4C4F5796F9389 604350187D18A4970E7FC597D2F0A5AA 63087EAEBFC92B4F0A9CEDA020A7618D 6ACCB24275BD1BE78022AE063DA6073E 6EA6F2C20DDFA1CF96272D4DAB888B87 71C29B0895D1963EB7FE853A2CFA684A 73E907B19D895C7623D27D2384D97040 7C3AA90B8556B64CBE9D28EFC5F978D2 7FF4250D27CC1031E2530119C3171AB8 88451B5338AC1BDA3ACE7DA4E8058E11 890B1F3B327CCABD3C7034B167F38F5F 8C3CF085C262AE25F4A0A42D59BDD57A 8E912E694DCD59363B3F4B31DB3BCD35 9127D7520084DF27C836C2028CEB6E44 9BE9A189A40C66D2863CDDA550550285 9E72C6CB84A74DBB76AB0A27FE93F368 A067B8957FADDAD37CC313943DF049D6 A206FA618FBDF04BACAF0165D9621212 A473C2C9FF48C81F2852D3DD7167502B A907F48C2F43385ADC26A7530309EBB0 C237A0DA372A9D9CA8CC8B54B87ADA51 C271AA80C12C938D99C5A935933349F0 C526A4954A8EFB9C3D650E6E0277CCA8 CCEB9531E6B9A8923D10D2CF94B8EFC0 D2A51371CBD3BEF0EB2CA7A3C5B28A7F DB642544BD4335E4970EA86F0215C79F E6AF6CCA6224B98996A12A8A5B81E43E EBB4992A8B3645C35422D58834E532D7 ECE9EE73C1DF76FEE75B006943E411E3 ECFD9E473C1FCA3768337BECF00FD5D2 EE5F6B13980FB69B75DDE567C488B979 EE7580CAA349FD7D681D43075D5A0967 EF70ED6A534AA45A720426BE6A2F997D F590D937E6DD9183BDD272A16DFAC4DE F66863DA2FF0DCC3F1EF5ACA0E1BDE64 F757401DAC87D729C6522CD005D58C01 FDD4CDCD34A4D21D62D693E67B508FF8 adobe:docid:photoshop:042ec86a-52dd-11dc-bb7f-87d1a9f02b07 adobe:docid:photoshop:12edae61-fad8-11dc-a186-e0f9726909ef adobe:docid:photoshop:13ee9aa4-2aef-11dd-8d81-f27eb6d1002b adobe:docid:photoshop:24787f49-1441-11de-9fe4-bb120c50ae92 adobe:docid:photoshop:283bf7e9-2771-11de-a5f7-e5f9c0721d92 adobe:docid:photoshop:3c04fd19-7ab7-11e4-9582-b77f12e67c36 adobe:docid:photoshop:56e07c61-8f58-11dc-b747-dea064cdda7e adobe:docid:photoshop:5bb25fcb-00d5-11dc-8160-fe3baaea4664 adobe:docid:photoshop:6cc72dd4-c122-11da-9ea0-b410217bc604 adobe:docid:photoshop:74161145-7472-11e4-8b3f-d51ff019451e adobe:docid:photoshop:8b1a6435-1e48-11dc-a2d3-f7dac7540843 adobe:docid:photoshop:9d010613-7a9b-11e4-9582-b77f12e67c36 adobe:docid:photoshop:a8c0d594-1c60-11d8-a6cb-cdfe702634db adobe:docid:photoshop:ac3d7b75-e2d1-11de-9b84-fe9a494e706c adobe:docid:photoshop:bf1b42ff-0880-11d7-8913-9a827c8293a3 uuid:029F5456D042DD11AD43D811C1D79D3C uuid:19501508E2EF11DD8BECCB6B4552BEA7 uuid:240F7696E09BDF118943EC7D2E89C0BA uuid:32EB3BAD51E2DC118B9A98C8A0DD8215 uuid:32FF073A8473DE119FF6A9CB3A0D71C3 uuid:40B56E81A826DE11A84EB468E816AF14 uuid:483C8D6A09AEDD119ACB862DDB389351 uuid:4E28CD0BE5B0DE11ACB3A4B3E9D809A9 uuid:57D4D63C0537E011A635EBE38230B841 uuid:5B63012BB648DC11BFB9A185CAE90DF0 uuid:5D0DD3FDB305DF118437EB3D37DD64AD uuid:5D7B3DE51812DF119185DEA6EC2AA3B4 uuid:5EBC258199EAE11189C2DA1478C8C9F2 uuid:6638BA84298FDC119AC3F8EEB4E2F957 uuid:72BAB42AB8F511DBA0B48960EE8E18AC uuid:8418B9F71B19DE11ACD1FD0D79D1C48C uuid:90ADF7D5398A11DF86119436A17CB227 uuid:926b359d-9e47-431d-8750-bf845c6577cd uuid:A9F65486BA09DB11A9D28E7F7AED63E9 uuid:B540613DD2F2DE11B3B3E6BCC2B65928 uuid:B850031313CDDD119358D3EBF934974E uuid:B8D9606773E5DE119A42B7888D73246C uuid:D3A7CD576D58DE1193F18641FDF63895 uuid:D67DE9CEB841DC11A4C59F1431608251 uuid:D840B8FF2B1DDF118724A858B8454A8C uuid:DA1984435469DE11B944F4166779DEBA uuid:DC91D24E8353DE119534A3EB376DEA2D uuid:F4297B0AD6A7E0119054AEDAB6503153 xmp.did:01801174072068118F62EB2ADE46D273 xmp.did:01801174072068119109F305646EB57D xmp.did:018011740720681197A5DAF2583A0A4B xmp.did:0180117407206811A084BF28FE3D9E61 xmp.did:0180117407206811AB08E8E8EE3F0289 xmp.did:0180117407206811B2F4B2F0A10807CB xmp.did:0180117407206811BF9BEF79D798C243 xmp.did:02801174072068118A6DE8CC51352B1F xmp.did:02801174072068119109C65A70401340 xmp.did:03801174072068118A6DD9F43BB7607D xmp.did:038011740720681192B0DD1EFA0D88E6 xmp.did:038011740720681197A5AC1352A6FF54 xmp.did:048011740720681192B0EA0E866BB245 xmp.did:0580117407206811871FDCFA14F2CA87 xmp.did:05801174072068118F62AAC437B0569A xmp.did:058011740720681192B0B61BEB8C9F01 xmp.did:0580117407206811B2F4B2F0A10807CB xmp.did:068011740720681192B0E5094E035523 xmp.did:075DA6E20346E011A104DBD60A09BA11 xmp.did:0796F2FF2720681192B0C5B632F0693B xmp.did:0C6F3843B4FBE11188B1E8BDD53D90A9 xmp.did:0D74CB50B52AE111BCE2DE904F7749CA xmp.did:1354FDEAAC82E111BD62DB4BA1684708 xmp.did:135DA95E51C3E2119485CD76840DA0EC xmp.did:1368CA0A960BE311AE4682675B3E9A53 xmp.did:139A55462279E011B7C7BB0FA8A40C9E xmp.did:1568CA0A960BE311AE4682675B3E9A53 xmp.did:1B23937A3BA3E111A268C964C1959643 xmp.did:1B4CBCBCC095E01189CBD2A609D6972A xmp.did:1BFAE6F7A693E311AB2FAB742EAEDB5A xmp.did:1C8D9B97EDBADF119C55BA856872B7D0 xmp.did:1CC9394224F1E111B9ABE35673A80283 xmp.did:1D13CF493192E311AB2FAB742EAEDB5A xmp.did:23A33346BFA5E311A033D41CADCA8C69 xmp.did:26BFE5D14170DF11B28DA0B9164D66BE xmp.did:26CABB49C55BE2118543DC3ABC338EA4 xmp.did:2ACF258E325DE011A1A5CBD15F1C5D8A xmp.did:2C850DB82F4FE1118594EC5F608593F5 xmp.did:306C746ED2F7E111BD53CF94664BEBEA xmp.did:32013191-910b-f740-8ee4-e119302ccc18 xmp.did:333B092E0D68E1119633ACFF4D03496F xmp.did:375A0B3A38BDE211A0C7EEE8095E5998 xmp.did:3921327295FCE0119420D55B9D0DF2C6 xmp.did:3D21327295FCE0119420D55B9D0DF2C6 xmp.did:3EC156D08B26E311BD3FFBB138CA7E52 xmp.did:3EFA54B0F40FE111AA83ECCF63439026 xmp.did:40B5B13CC0D4E211A0F8A40ED08A7AE6 xmp.did:42D823653257E3118A7FB4DE32CAE3EE xmp.did:43B4CBE681D7E011A526BE08355470F9 xmp.did:4463A16AF341E311AA6AFF46E3A32C35 xmp.did:4476E48D7058E2119E5C9DC2D893986B xmp.did:49629383A75FE211BE5FD8DC69EDD003 xmp.did:4962B478AE93E311AB2FAB742EAEDB5A xmp.did:4B7A12ADF2FFE2119701C3E8E2CBA32A xmp.did:4B7D2A10B996E3119120D50133417628 xmp.did:50B031CCDB98E111BE19B05E1DE1772C xmp.did:51656EC5AD6CE1118573CC62542EF1EF xmp.did:5178A250EF6CE1118573CC62542EF1EF xmp.did:5284CF5C414EE1119A17DD19DF39F556 xmp.did:57A1C52DF060E111AA529252B4C34ED0 xmp.did:5E5CA02C6240E311A887D012E70C1E3F xmp.did:60271FD08F5FE211BE5FD8DC69EDD003 xmp.did:63D21F2E2241E111AEBED233B2B2BBDB xmp.did:6B27B4BD813ADF11BCAAEC6C5DC8AB8A xmp.did:6CF7F57A4588E0118E50D901036E7887 xmp.did:6EE15AA5BFEEE2118F9FEFF9352EDC83 xmp.did:7151EC9085C3E2119485CD76840DA0EC xmp.did:71dc56e5-e055-5b49-b8ac-08fc19339e47 xmp.did:763FC8C77EBAE111BC5594B8606FADF2 xmp.did:76A59B64F891E311AB2FAB742EAEDB5A xmp.did:78A59B64F891E311AB2FAB742EAEDB5A xmp.did:7C80FADD8B3111E2AB5AD75D2661B19B xmp.did:8279DFDDC2F7E111BD53CF94664BEBEA xmp.did:8579DFDDC2F7E111BD53CF94664BEBEA xmp.did:8A947733EA7FE211B026CA3D93CC6880 xmp.did:8B76D4190ACFE11194F189B929F1E3EB xmp.did:8CFA6888BDC9E0118A1894B66E94A91C xmp.did:8D76D4190ACFE11194F189B929F1E3EB xmp.did:90917B61A549E211AAF7D9B03FBC388E xmp.did:94C3EA66E545E3119876F23BD28AAF4A xmp.did:98FC0E0C89A0E111B29BBC3C38868882 xmp.did:99C2BF9AC2D0E011A663A3A0F235368B xmp.did:9C8BE9970400E3119701C3E8E2CBA32A xmp.did:9D1BECD81020681197A5F6F85A622253 xmp.did:9DA8EFF9299DE311B712B7EA38C9FEA8 xmp.did:9c93a680-24f1-c646-aeab-38faf49b228a xmp.did:A0774BA2B769E111A342FC9D7726AB8E xmp.did:A19B51187538E1119063BF48A3C51EAA xmp.did:A2571EBE69B3E11185C7C82D704336BF xmp.did:A51240381845E311B81F8883B98D3C93 xmp.did:A5175DB2056FE111B3D9A81555F1D5A8 xmp.did:A55DB8C3B87211E187B5B933E8DA83E6 xmp.did:A9371036BFF8E1119CC59C0B4EC1EC35 xmp.did:AA12E978F292E311AB2FAB742EAEDB5A xmp.did:AB33C7EFF402E311A629B015FE29A947 xmp.did:AB50521FAFC5E111BC42E26A02820592 xmp.did:ACA7AD64B2AEE1119D79D7B7DE21DF0F xmp.did:AD01ED608B95E111888CF2658EF196E5 xmp.did:AF014875B853E1118EE7E574C350A586 xmp.did:AF7B4A72262068119457B94B0A19120E xmp.did:B28F2993E3FBE1119665ED16B1B03E0D xmp.did:B2B3E4AC3A35E311A3A5CE099DA58CE0 xmp.did:B391F8CD01B511E1A18F97A8D26A3B0F xmp.did:B518C9D19CA7E1118964B3B7AF8C1D56 xmp.did:B6F845E40EC7E1119971B8D30BF0408F xmp.did:BB0F008D11206811BD35B6F06AAF40D7 xmp.did:C28274CEB193E311AB2FAB742EAEDB5A xmp.did:C408B747B4AEE1119D79D7B7DE21DF0F xmp.did:C5CC15B57300E211BB248AC6E3141EFE xmp.did:C79E1726F3CEE11187A5CC8B39C8961F xmp.did:CE153DAB66206811994C9B7F51AE0063 xmp.did:CE9D2C6B6D9EE111A0588B64C21F9F9E xmp.did:D16203B18A55E111AADBA99AFB78CE20 xmp.did:D2E52B51C2D0E111915AB30308CEF0D1 xmp.did:D3258C3318206811B83DC55B43B113F3 xmp.did:D5958034BB27E2118651A73FF7A01E2C xmp.did:D79444774A2068118DBBACDD367EC38B xmp.did:DAFF29841D2068118C14A2A33B576E28 xmp.did:DBD8F5553405E1119D46E5E691047188 xmp.did:DBEECEEDEB2EE111866E89F51FF7D987 xmp.did:DDE729E5E5D9E111B4E6E7878EF63782 xmp.did:E02D6D537529E2119580E8B1B8F1BF12 xmp.did:E15A30AD30F6E111A7FEDB98811DAC38 xmp.did:E15C8DF98B5AE011BBCFC6EA4EB55BFA xmp.did:E1721EF2DB2068119109B10BB0D0BCC2 xmp.did:E2969E558F2FE1119012DA2503D34408 xmp.did:E55A30AD30F6E111A7FEDB98811DAC38 xmp.did:E948F03ED04BE111A679A954F3256CC1 xmp.did:EE58428735206811822AC7D293D6ADD7 xmp.did:EF0E269367B1E1119D8AAF35690FFC21 xmp.did:EF17D91D3220681192B08B72887FDC11 xmp.did:F0EC54C91EF0E011BF318C473C42BF32 xmp.did:F75D918A1120681192B08BEE29C75DD2 xmp.did:F77F117407206811806C9A138DB80561 xmp.did:F77F1174072068119109F8FE27718D5A xmp.did:F77F11740720681192B0B6CBB13A5218 xmp.did:F77F117407206811AAF1F360BEADB6C0 xmp.did:F77F117407206811B04FBAAF7885AEEF xmp.did:F77F117407206811BC5391310951E999 xmp.did:F87F1174072068118AE4FE3FBF51A176 xmp.did:F97F1174072068119A7F833586C6F350 xmp.did:FA7F1174072068119109D4895471EB7A xmp.did:FB7F117407206811871F92CFDFF7440C xmp.did:FB7F1174072068119109C00FC3634517 xmp.did:FBC4D2040A2068119109CC642C44EC0C xmp.did:FC7F1174072068119109C00FC3634517 xmp.did:FD4D6DFF08C0E111A568F02E3B31897D xmp.did:FE7F1174072068119109FEAFD0139520 xmp.did:d56cdb07-1084-41c8-8beb-7032281b987f xmp.did:fb8297f3-4588-8e46-994c-581eb3803745 xmp.iid:dbe71356-5270-f24f-92c1-30ceeb0c7ad0 adobe:docid:photoshop:c4aa85b0-7ac6-11e4-9582-b77f12e67c36 xmp.did:43f19c41-da79-f349-b6cb-07ca22ff4f9e created xmp.iid:43f19c41-da79-f349-b6cb-07ca22ff4f9e 2014-12-03T16:31:02+08:00 Adobe Photoshop CC 2014 (Windows) saved xmp.iid:dbe71356-5270-f24f-92c1-30ceeb0c7ad0 2014-12-03T16:31:31+08:00 Adobe Photoshop CC 2014 (Windows) / 1 720000/10000 720000/10000 2 65535 12 12  cHRMz%u0`:o_F"IDATxڌj0ElS& B3zc֏g:D(K!dHFB) zA}OGOu]K`~' [;1V`Ƙ7 Fmmu.ov}O_F@^ z]E=E4opxBPfH0 ,"?16#0EaY!0Jsh9x5JKǟc=,ˎ.,r.i>I){f)Kk ܀x ZV=hIENDB`kylin-video/src/res/logo.png0000644000175000017500000000424213637124061014763 0ustar fengfengPNG  IHDRc pHYs  iTXtXML:com.adobe.xmp uCIDATHOHQ?oSRAxɃEu+.); t.EFD5Oa7OZdK͢Zn3uPm#?ߛ>_PJZwd]!qP)DuM)f8 0`fpxăI1dU F-2,mzkkM_{A=枦JfdGˁ7=AZ \jGP\Qڢ*9tಹYfROb@PIlbhw # 9֍ry"ʢ~DѫBM9Q%=ʀ_+}A8DMAXhUvV& :Z2 kŷ@箖БC`)v2Np|ӟjhK]/*ta4'+{9Z8C"Z"7e9C4ʢx} S ^"@=P 4PG f94Ycȫ /=$ץ;߽4~Z1RjIENDB`kylin-video/src/res/delete_normal.png0000644000175000017500000000060513517016402016630 0ustar fengfengPNG  IHDR Vu\gAMA a cHRMz&u0`:pQ< pHYs  IDAT(jP{R:D:e ;9dwTcBtv $o▭{g)dʖ&P~?I=|jt]7'i3J~DĽ{:u]/۶}N#&>&F@EѶ( `^A }Kˀ<;h#nDGgv*ϲl-VD'رG8kZ+.IiYLIw?7ʮ~tIENDB`kylin-video/src/res/plus.png0000644000175000017500000003513513517016402015007 0ustar fengfengPNG  IHDR 2Ͻ pHYs  9iTXtXML:com.adobe.xmp xmp.did:6DA91737B5A811DF8B4091CFECE95E79 xmp.iid:34579b01-2447-0447-8016-b72990af1cc5 xmp.did:9c6542e1-9f1d-bf45-95d6-dd43ee6c3218 xmp.did:9c6542e1-9f1d-bf45-95d6-dd43ee6c3218 xmp.did:6DA91737B5A811DF8B4091CFECE95E79 saved xmp.iid:34579b01-2447-0447-8016-b72990af1cc5 2010-09-03T15:26:18+08:00 Adobe Photoshop CC (Windows) / Adobe Photoshop CC (Windows) 2010-09-01T17:08:03+08:00 2010-09-03T15:26:18+08:00 2010-09-03T15:26:18+08:00 image/png 3 1 720000/10000 720000/10000 2 65535 10 10 cHRMz%u0`:o_F;IDATxϡ 0BQcsKMOԔCAzpny+ 7d`7#B@[ IENDB`kylin-video/src/res/play_normal.png0000644000175000017500000000345213517016402016336 0ustar fengfengPNG  IHDR==ieQtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp wH$$$8_xdg8<Dq4Ѩte,FFF CM`?Ì3΃hPH$&&HBba@Wˁ%C G>yn!a9@ Xcq=jţ3 222iii̚5뢑ɓ/O> {'?0ޕy螪7lp˗/4鞝޾}AqOzjYn0gΜOUTTՅgΜynq[nO^|Lɪ-J|,&&IQG-xhZ ]Wm8-)7qCK 8/ *(AmT`MR(%zO'B7 wq9_}4oIf ) A`bk Ü8Sf6hP۶[˲a9:ٶ]6M/iyi 9y R TBUEK=!F)eelS_op}%I LqEu+jAǝ:9""=᫐!(5˲ 4͌ʚFDz,_<υa"OQI:Ou%4b%I*&mTnZ}h "4B#4B#4B#^S2GIENDB`kylin-video/src/res/close_press.png0000644000175000017500000000270513517016402016342 0ustar fengfengPNG  IHDR$$e?YtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp +DIDATxb|]΀POZvĈlNqsAObl,S!,#$yc/sbj,{"+MpALr %0߿腄w]133c=1X` EkS/ȯM!6d$k r$G?ܑ R)6IDATxb?01@bDa   NY\/H$w)3*kYj~d0[TH$t&Ad @0+  ,b4 : ȎC/00lF;)F<tLHCu#e@vzLںA-#{?6ASy|t,Ia=zZ4\-Ci?4.8*pr&odIENDB`kylin-video/src/res/min.png0000644000175000017500000000244013517016402014600 0ustar fengfengPNG  IHDRl$jZtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp < 2IDATxb?:>̀"x; 5L d! =`ݜH?MĈ-J5DkhZ6j0 b2>1aЅM`! -0bG0xHvw1$#!G'|c u` A _!|A! Ehe+sގ-:((@K2 h@@z܅ܦtJj8)C0 -c/o!m=gQ!ބ$! `&rMIENDB`kylin-video/src/res/video_hover_press.png0000644000175000017500000000234513517016402017546 0ustar fengfengPNG  IHDRhtEXtSoftwareAdobe ImageReadyqe<&iTXtXML:com.adobe.xmp ۟UIDATxb3 " @zHdH " Pπ3# 0iUS<@x@s Q A11 ]H|4PWCiC= g=,#y 0`As;@M9btoYwݛBҐ n XA0` U N:>$a; `h3j!H1 >@Ղg*ZEXk@qynpha 03x">pi8I 1B߆ȂQ0I{IENDB`kylin-video/src/res/combobox_arrow_normal.png0000644000175000017500000000235113517016402020410 0ustar fengfengPNG  IHDRtEXtSoftwareAdobe ImageReadyqe<viTXtXML:com.adobe.xmp 2 IDATxbtpp`& eA D!b[0 J@z+ ۑ`q9\Ά]8}HPÕ| ȀF(*dx{Ɩ@Gs gd 6=¢bN>\< xmp.did:24776fe3-5e39-7846-8bf7-7165f60dca4a xmp.did:5B0A2F11524211E785EEB6DD3C6AA44E xmp.iid:247c9624-d7cb-c049-80be-5cac164ea0b6 xmp.iid:2a7af3b8-43b0-6745-a0f2-048f0ea0e907 adobe:docid:photoshop:772c815a-4f1d-11e7-a29c-ee28c792f004 saved xmp.iid:247c9624-d7cb-c049-80be-5cac164ea0b6 2017-07-12T13:45:03+08:00 Adobe Photoshop CC 2017 (Windows) / Adobe Photoshop CC 2017 (Windows) 2017-07-12T13:44:21+08:00 2017-07-12T13:45:03+08:00 2017-07-12T13:45:03+08:00 image/png 3 1 720000/10000 720000/10000 2 65535 24 24 JT cHRMz%u0`:o_FIDATx =D2@6lܩ6L,! Cu뷉SI6]I.)kei ```He``Pb@R. vTα @PEaNB 7 DU/&<@ )_ѠŁ=GL "" 2JT_t;AQčĕQB3Gg1ښ#9ܿޏ2 #yRw s,G[Xb)"c{i/ ^aT DRVhFnїo:օ0 8mTj WP[P)% 6z JDRK*6a3Gs9w_6*cUM@oֱsGSҹMnW"$t/\Us6=jSSKD?s&va]XL4>FksR_R ^+#{q++ ڴŸtf^\p ܦ [~߼ K)VQ\kS(膃(~k{Xq̵FJ. w`0o >TCUU<`udW@{$q̢U`eRme/8!8I`L>B+/&4Qк\gHRRKW_x#ֳT|?x8&ӑIENDB`kylin-video/src/res/open_screen_hover.png0000644000175000017500000000201013517016402017511 0ustar fengfengPNG  IHDRhtEXtSoftwareAdobe ImageReadyqe<&iTXtXML:com.adobe.xmp 7*xIDATxb?01@@1b\@ F "Y^6t  aA F )O{+*`ħ !B|60h0?QHq4H c*IENDB`kylin-video/src/res/checkbox_checked.png0000644000175000017500000000232113517016402017247 0ustar fengfengPNG  IHDRhOGtEXtSoftwareAdobe ImageReadyqe<viTXtXML:com.adobe.xmp ΓXIDATxbL by @E` ]g }@pd{(ǐG 0LEY D-2 &@(NA,8K:l> p/jP} #x"x0WHYqIbA.a"҆~&'S4 H@ @n; BDb7@Y`Oċ+L<=@>rIENDB`kylin-video/src/res/spin_bottom_arrow_normal.png0000644000175000017500000003555513517016402021151 0ustar fengfengPNG  IHDR |@~ pHYs  9iTXtXML:com.adobe.xmp xmp.did:25d3b678-10bc-fe4d-ba41-689616e973fe xmp.did:712C29225AD511E7A804E8AA5585B67F xmp.iid:5606b9fd-ecb7-4d4c-b815-f399c5d27cf3 xmp.iid:51e652ec-356d-ef43-a124-5fe63f3cb50c xmp.did:25d3b678-10bc-fe4d-ba41-689616e973fe saved xmp.iid:5606b9fd-ecb7-4d4c-b815-f399c5d27cf3 2017-06-27T09:11:13+08:00 Adobe Photoshop CC 2017 (Windows) / Adobe Photoshop CC 2017 (Windows) 2017-06-27T09:10:58+08:00 2017-06-27T09:11:13+08:00 2017-06-27T09:11:13+08:00 image/png 3 1 720000/10000 720000/10000 2 65535 17 12 M cHRMz%u0`:o_F=IDATxbrppPSSspp`b``02d``bRSSSSScb`````brppWSSwpp"1000100|O b VA1 1\!w?~_:w.bRT7$ؼf5+?o}{8?sS\%m$$\.&!anc/p!>~`6vv666`^>Gp֙YYn߰ V<)0J_ LIENDB`kylin-video/src/res/play_center_normal.png0000644000175000017500000001614713517016402017703 0ustar fengfengPNG  IHDR6wNtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp KyIDATxb` 0 >ľ<",5A7p|4 L(DECQ3QP؆EX6&@FF3a|bxjMTO8FD N`aaq+11Q(á9Jȱ:~7|\'դׯk0Ӹ =͂Ƨk߿՟?ZWP 4D-|O^^ FAA8kggǵ|ry*iDLB49C"&&FlAf(uP Pe%K@gtvІ,x:9D ^$ˣC%sM4كhhhSMe䡉l8JǏPYj&DАc֭J4p((QRQh[,˗/hPC)v,hZS\\ &` lж)1ސ!סձ&HCc1 I;Bs8TT7Lg b.yM:㸊SL$hHXfC ^tPAA$ xݒ htHVz>́,3<>x|_|< plnPgQd/XGio ]h8 ?4 CitOY)"mR9͏~! ,9Sl %pm >i㮅ͮLHѤF3Xwa?Ȓ- WT]aK݀eSzdp8|b^ l%3n4@|4Ǐ{L[c{y)蔄rsfmF-tO1Y& /m6%z71XHΑ U|^RruT'k8**TzV(!AlWRd?Ma^@ X'`h,HTuЗ84{l;Ag(if+ճ&=XjuA՞ȱXLرP&ijX, ~Ϛ^ x⡧űN&`0t:?x?x&􆂖Kdh|?̚.jaR/ R3,4V*ju_"I٢gT-< qD޺B|TP,&'8bx>2e:bít:= 0BxSVP0tűH4 N08Sh{ıp8BZ#ODKn~ZA~ Z7`Axl0wCО2,= WquTs'slBW^"^[-* HhxT02(!Fj0~p"$~bL0$GM #TbPb2ʣPah=-} 1,̩@lX7a\'~xI,c& LFw@,vK mb1^=ŐX5˔M^['ش`cۤKJ qG"~{ 㵅_-VCk WÄTPd^ F(O;&|1,\4D9na/w 9ΪxH" R&+*p{m! pXI| W !qmzuPDMI 6 h;::GY[[BRrR"/퉊+m6ۡX,rLmauf[V[[e1($"aޫ0sssg9 BΖKKKv!cc{ *XXXWrXuKzbP0Eq߰ ? ڂjU'@!)X,CBj:eoo "}!-fbĐ{$|i^*vee$%%%UoRlee%T66 7*P(D kt=E L&YEElyy!n}? 0W.//X3*Օ666uai*b34v䎥yE:;;W v=/+b"W[]]=::H'9UHtKjf dgg;Wm6s#E}tj :1Ď 3 k$ '}sNa:i I*!SS1V;`wrD {2*c eLkc,,KdqQ2EXOM?iVc2H{M+Hn†=1H$dEed {;EX}\R34Q?2ɬiKZ?RV~b4XF*5<9RBcV?#Ч9Me(+砼![X "6XBk v?*\Ltbʰv `r|iz߿66mzzjWV(}㴩u&9ҍ7nlyӟzd2đ#Gpby2aIRzUݡC|w2p`Ҹbm+]}}} SL6ms }̓5T*xvAtQk` l]\.;;:GGGaYYYIIItwwY U+.ǘ3<<ܾ}{7w}sΝåKcqa),airK r܆њAG,\ǽ"+o#̅yy<.. o}"( 䭬(|Fa,&Yttt + xO,(]ussepz@X.jbTWW5ׯLvJQ0U&|6aQ ˧54dzC7iaqߧQXX8@߂YYY]{|>'4~ ,^Μ9l6.//OBZ[G؍f/4Ngggp8uu%%%}/^TH$L׉Ґ;w[b񨷷7l؏lьe˖ٓ>n`ppjլnTCaisy6}~ʕ**QX Zx=zDخ>̎r/3ر-//鄓'Osrrz &GIZš 68 GTRΝ{AZ0ٙ]\+V8\|9tizzz7LPX9w݁VDfGkީ(ƪjԼnlkkeҺҥK|"hxɒ%}ћD_z:{mTd -{ٙ5ed@au>}zݻY,˗/7o~rWRV`BÞ$|AX(pT H1;F(S}"SȣV&);]nnnWM":%ot_N 99مKJr,??_V0;F O3}]jsT {333я#zK/d//(( Q#)//xc_3P#h){id )j~IENDB`kylin-video/src/res/playlist_close_hover_press.png0000644000175000017500000000255113517016402021465 0ustar fengfengPNG  IHDRp ntEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp I [!Ƃ@ TXD qI@S 3X%DFr"%:D'&a8<kK$G5@c8 |59d-aMޠ GA%l%@4'!?4<bT64 aXEr&T`YQxW:Ğĕ* B!+5SB кW \7=IENDB`kylin-video/src/res/kylin-video.png0000644000175000017500000000740413637124061016260 0ustar fengfengPNG  IHDR@@iq pHYs  ~IDATx[}ͼ. h՚hb?=j Z+6h!T1ڔihDM(Rw {{43̾q4 Ǿ=3/DOO5p XކԊYq.pcMWcaXD9-aH oDa7ǮM=<;+\=Ra%xVw Tu_=cJo ʱrt(8Հ) TX-TUB('25V}^s p,J99+$C^ÅOBA5ھ:^q32NAp ?YnYDҬiҶn x .ԏnX?]Q4mm2 RuB BoԎ & rWvC`F̬,ېEתe~ŧ w/+;E! ⁅`v}O+1DA"à#$O,7!uqt#@;`Y%U)vqa"Nh\[iS)W>IگV`q֕ç ZV }^22j&Hx9H@G}7&9~4 II 2㾲K \a$.crUdIjv;rDFGlr?:ѹ@oz'2{E&;R Bb!>Q"CL0ԄС{a1|`)zDiƒo.P~׍c[sjD(Kp) Ѫ cqPH` hYENsrZ5.H l1JDHʸɐ`B ?C p:Ekr71\P Ln ;%hT'a艄홡 wweyX۟gL 3A5 ZfBēeI+8Yd-`V3S2c{ MxWpwCS"'s 5It*6;.hRwvrd 0//7wyӔI3Z_Vh])^ Th >,&@$m)-Mx!A4M0crbGC%Ahv?FgCDqj^ݷTRoտ6x].!*L ǤX)'$3B2{Q\ H",edmn!3OZh[&ep(Ԫƞ {w|kJkꎋ*/eh1C/=]h, I2x]H79އy}?'ɞ=yT# ˕MєР8RV}9# z n̩#9g /5)Ml4؈ HB>tx}XMQ>L0=_^B./n<zUaNY ڗ,,#`dlϿxz> (w V=qx!Ci>)#nSg+=,Nsf2dC#,6b"\c \G gX*ͽ@z.xZ%X"D.=@ |YaOSLW|Fm'G (=Andpj^Bp# 4۳?b:mbT/ ~Kco*xV<8A;ˆCjM{ $laDfHp 8HG.`*ڷK7õ,Av:AJeq|eZ?#w(Kd=xVY favDBqLDnǷ2[(CA)FLsbD㐽?#<\;ѭȏ0c,|o6 yxr7řbɮ=W/lY)Rۇ{ϐT ~qފ5fp ى^pCFg`m"kP+r`u錾E- 6"?#}݂b),V4jbEN_/1 `d^$['I` v1nǭjZ.!ҼP֪ӗ|%ةT$!ri뺿 _ +^ߨ_tjT`eFk+Ecx8KqA}`)k?$C?{)ڱs-}T7邶X'dPpd\w ^0r7^%#oewq}bij`4|[*5*¸{g} "qWxHW#Y|i=>(G ׄ "c"ZxugI]6 D2 T0Z]mbDG{y>ag&bOg3>M;oX5F*f&/V>-;O k`i&v %z$tO?VU}&76?{Pw lMG,0NYCѐ 8ӄ=e@DbsQ|1ՍT8)j,ӷ|rLc"NFxwm;GLʧmi$IENDB`kylin-video/src/res/volume_mid_normal.png0000644000175000017500000000055613517016402017533 0ustar fengfengPNG  IHDRw=tEXtSoftwareAdobe ImageReadyqe<IDATxU @Db@ t Vv HBtVv` v l3~89fv7EQs5|+x@jך'y6:i Fıa(P,wK10Qj}M% s'6@=F"vc?dW5H$ 81۳2Xg\jJLXrtE/Hɷi*nLP8w`eA<-wqi\Z,V?Ys+LGIENDB`kylin-video/src/res/volume_mid_hover_press.png0000644000175000017500000000251713517016402020601 0ustar fengfengPNG  IHDRp ntEXtSoftwareAdobe ImageReadyqe<&iTXtXML:com.adobe.xmp #IDATxb? p/1}&P FdeL@e @,@?bD &p1T @`+#L@؈ @8u",āp"D6 *H@`ڱY `$?1 {B~\nJDS|A\6;m#ms0'1 `ԖFO \ HSd XIP &H$b)p ' &3o{!SIENDB`kylin-video/src/res/open_window_hover_press.png0000644000175000017500000000205713517016402020770 0ustar fengfengPNG  IHDRhtEXtSoftwareAdobe ImageReadyqe<&iTXtXML:com.adobe.xmp YIDATxb?01@}bDa  01"? `)!iLt@s Bd`b 0 H2Qج`g@ b=A)_bAr3+bc$O0(rpb$2/ IENDB`kylin-video/src/res/warn.png0000644000175000017500000000742113517016402014770 0ustar fengfengPNG  IHDR<::o pHYs   MiCCPPhotoshop ICC profilexڝSwX>eVBl"#Ya@Ņ VHUĂ H(gAZU\8ܧ}zy&j9R<:OHɽH gyx~t?op.$P&W " R.TSd ly|B" I>ةآ(G$@`UR,@".Y2GvX@`B, 8C L0ҿ_pH˕͗K3w!lBa)f "#HL 8?flŢko">!N_puk[Vh]3 Z zy8@P< %b0>3o~@zq@qanvRB1n#Dž)4\,XP"MyRD!ɕ2 w ONl~Xv@~- g42y@+͗\LD*A aD@ $<B AT:18 \p` Aa!:b""aH4 Q"rBj]H#-r9\@ 2G1Qu@Ơst4]k=Kut}c1fa\E`X&cX5V5cX7va$^lGXLXC%#W 1'"O%zxb:XF&!!%^'_H$ɒN !%2I IkHH-S>iL&m O:ňL $RJ5e?2BQͩ:ZImvP/S4u%͛Cˤ-Кigih/t ݃EЗkw Hb(k{/LӗT02goUX**|:V~TUsU?y TU^V}FUP թU6RwRPQ__c FHTc!2eXBrV,kMb[Lvv/{LSCsfffqƱ9ٜJ! {--?-jf~7zھbrup@,:m:u 6Qu>cy Gm7046l18c̐ckihhI'&g5x>fob4ekVyVV׬I\,mWlPW :˶vm))Sn1 9a%m;t;|rtuvlp4éĩWggs5KvSmnz˕ҵܭm=}M.]=AXq㝧/^v^Y^O&0m[{`:>=e>>z"=#~~~;yN`k5/ >B Yroc3g,Z0&L~oL̶Gli})*2.QStqt,֬Yg񏩌;jrvgjlRlc웸xEt$ =sl3Ttcܢ˞w|/%ҟ3 cHRMz%u0`:o_F>IDATx[q@}ɿ܁/>T` L: L `;w>*T{,OvF}{\‰Jͱ.uep|Rlv{>aȂ5ʑ'}LMܴeZoI-Pc/2_]s5 |<"?1FW]& A@d36!1X`t;`L$f`L5+t3`j! .9mrVf4h.x˃0^*v#&/eu* cyd x@² r;(^.wlvYSaa@[3, =KXc~Y  kO\-r.q/r ݟêUuKKs 4ZYiBO]n\ Vj?[|b_ăEzb-b^iKPH uacjXJQ}h(!ҏxf ɝ}7H)g~ %CAҤS\>tᝧMY:}UD?)UZm{o#7PP *UԱZ۳崧%ִ.BŒ#Qw/c]sI+h֘vdŁz:vsϥn4zKC!Yn.=_@fC6(?j-d)k?rx'>۲gF%~!S3xގo3W#~hP 8P^t IENDB`kylin-video/src/res/max_hover.png0000644000175000017500000000232713517016402016011 0ustar fengfengPNG  IHDR$$e?YtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp B|IDATxb: 01RĈlϏn!8rjX#pZZ͠]N8 #Aّ}CP.J}Zu'@;FE<2lc*l!Z© 3 tHP Kt%B/qSD3To-r 3$nlXB"`)X W1Zi=1g&-I`4SZ6T,:8vIENDB`kylin-video/src/res/trash_normal.png0000644000175000017500000000024313517016402016505 0ustar fengfengPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<EIDATxb`0bXQb3$HR?\?4b0 fd-xRIENDB`kylin-video/src/res/spin_bottom_arrow_hover.png0000644000175000017500000003555313517016402021002 0ustar fengfengPNG  IHDR |@~ pHYs  9iTXtXML:com.adobe.xmp xmp.did:25d3b678-10bc-fe4d-ba41-689616e973fe xmp.did:5F8BEA435AD511E7AD2DFE8D367DFF0E xmp.iid:09066481-876a-7b4e-8c9d-997610446247 xmp.iid:51e652ec-356d-ef43-a124-5fe63f3cb50c xmp.did:25d3b678-10bc-fe4d-ba41-689616e973fe saved xmp.iid:09066481-876a-7b4e-8c9d-997610446247 2017-06-27T09:11:08+08:00 Adobe Photoshop CC 2017 (Windows) / Adobe Photoshop CC 2017 (Windows) 2017-06-27T09:10:58+08:00 2017-06-27T09:11:08+08:00 2017-06-27T09:11:08+08:00 image/png 3 1 720000/10000 720000/10000 2 65535 17 12  cHRMz%u0`:o_F;IDATxbrpp022rpp`b``xPb222222bb`````brppK122Kqpp"/ ' b VAk"9c3~=6.b2TN:4TBe~У'B_fsr,c8S\%~6Ds7ignXR ދ[/;クv5 pe.w6 xmp.did:24776fe3-5e39-7846-8bf7-7165f60dca4a xmp.did:A160CEA9524511E7A7EA93AB15BEB749 xmp.iid:544bb771-b22d-a94d-bc34-a7c410cc4683 xmp.iid:2a7af3b8-43b0-6745-a0f2-048f0ea0e907 adobe:docid:photoshop:772c815a-4f1d-11e7-a29c-ee28c792f004 saved xmp.iid:544bb771-b22d-a94d-bc34-a7c410cc4683 2017-06-16T12:25:32+08:00 Adobe Photoshop CC 2017 (Windows) / Adobe Photoshop CC 2017 (Windows) 2017-06-16T11:40:31+08:00 2017-06-16T12:25:32+08:00 2017-06-16T12:25:32+08:00 image/png 3 1 720000/10000 720000/10000 2 65535 24 24 cHRMz%u0`:o_FIDATxb? 0000p/vA*0bAQƽ.$b?LC C0 1dc|{l͡ 0SpL` D2҉p Jڀ8<>l[jBAÜyE:>D…*B :Pc``5{75,8>*/[ X`k/ln=0=.7;J 300lf``:.+l`-L1 \a06Q:i(zHV4AHIp&$h]Gؚb/ Z[ fI`;̝jvUI!oU\ )j!#j?Tjc3 )"l,;G\ׅ_3w k\W*R C'B}ոMu#wmlC{aY0?͢џ`L-E 1)L1-`Q &X w6{|bG?TB=OTdshX αz\\W%0;̠3Y a辰IDATxbd L b}b9UL@a@ @&_ـx"4 b +z2@H&W H `z@U1% 20 ~ A2FX< "@Հ `{@| d PdC,[S /(2AIB'{(v `}@Ij3"A!% J/ F3TNlpIENDB`kylin-video/src/res/backoff_10_seconds_normal.png0000644000175000017500000000313213517016402020775 0ustar fengfengPNG  IHDR tEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp qlIDATxb?h` (҇M$ @ Hb DRDѹ #@8 ;7> ğ`b f#p %0W 9> Ā>Cd1lA 9&[ر' Pg >EBaF;d1"ulbDUXV0_ ДREW)R" DX#̩Ls8S )~tL9p5xF&3ŀ+)ɤPXlTTbZ4" 2(6<@,Td@ 񥜕He;H*&bM,0 1Ȑk8J tuɵ\CD#";huO -{ -Z@3VaV%1f4@E4+r[J"q,AMLh-" ϠZ.f@Cq uIHL$֤t[4bv"NjTex!>uBhb!#E9< r@8DN uZ^1}&" i o҈(uIENDB`kylin-video/src/res/progress_pointer_normal.png0000644000175000017500000003600013517016402020770 0ustar fengfengPNG  IHDRp n pHYs  9iTXtXML:com.adobe.xmp xmp.did:24776fe3-5e39-7846-8bf7-7165f60dca4a xmp.did:F2088D53524111E79321CAE5FEC76BAB xmp.iid:ec89375f-25a4-8948-bd68-b9f5249e6143 xmp.iid:2a7af3b8-43b0-6745-a0f2-048f0ea0e907 adobe:docid:photoshop:772c815a-4f1d-11e7-a29c-ee28c792f004 saved xmp.iid:ec89375f-25a4-8948-bd68-b9f5249e6143 2017-07-12T13:44:56+08:00 Adobe Photoshop CC 2017 (Windows) / Adobe Photoshop CC 2017 (Windows) 2017-07-12T13:44:21+08:00 2017-07-12T13:44:56+08:00 2017-07-12T13:44:56+08:00 image/png 3 1 720000/10000 720000/10000 2 65535 24 24 k cHRMz%u0`:o_FIDATxb? 31@0bBW&U BV&&e``x` 3B#6300d-Gr@63000*b\P ^4̀ - l05Lz P`Ħt 8H d100\f`` AH : DYK-f x9R5Ŧ?+6% ]b"/"9-````x-}e.=*GQF6 רIENDB`kylin-video/src/res/combobox_arrow_hover.png0000644000175000017500000000236213517016402020245 0ustar fengfengPNG  IHDRtEXtSoftwareAdobe ImageReadyqe<viTXtXML:com.adobe.xmp !IDATxbtpp`& eA D!b[0 J^r 122® PlGX\UjBp6TNjW3#ӝ @Ć8a* V3lo҆h /Aٿ|y ʡxSʦ'>@̖J?cF0q k0|1 \Q29AҿklxP=aZ-zl?6Y2˙d}n,@Tjd (IENDB`kylin-video/src/res/volume_low_hover_press.png0000644000175000017500000000230713517016402020626 0ustar fengfengPNG  IHDRp ntEXtSoftwareAdobe ImageReadyqe<&iTXtXML:com.adobe.xmp dP7IDATxb? 0q/11 bDQ"J0d PLFf@1C]c0aW G6Qhtk9M !و$c3bODlHkA+=+1zqi`a<6a=N %8,%%#YWrQE6瓒 a4W.G@P)`@MD|hD *C}BZAʯ@lHv*BNATKEhHREN>@>yQ0W IENDB`kylin-video/src/res/next_hover_press.png0000644000175000017500000003632213517016402017420 0ustar fengfengPNG  IHDRp n pHYs  9iTXtXML:com.adobe.xmp xmp.did:24776fe3-5e39-7846-8bf7-7165f60dca4a xmp.did:D7F1B4E5524511E7842DB2F90C2259E2 xmp.iid:906bdb84-5bce-534d-be6c-6d18a4a04c54 xmp.iid:2a7af3b8-43b0-6745-a0f2-048f0ea0e907 adobe:docid:photoshop:772c815a-4f1d-11e7-a29c-ee28c792f004 saved xmp.iid:906bdb84-5bce-534d-be6c-6d18a4a04c54 2017-06-16T12:25:45+08:00 Adobe Photoshop CC 2017 (Windows) / Adobe Photoshop CC 2017 (Windows) 2017-06-16T11:42:38+08:00 2017-06-16T12:25:45+08:00 2017-06-16T12:25:45+08:00 image/png 3 1 720000/10000 720000/10000 2 65535 24 24 =^1 cHRMz%u0`:o_FIDATxb? 31000p/&t&bBQƽo b?ϹkW P/Ԧ"?C!̘ \}Bvߘ|{so̖d``Ѓ\^Ļ \;`0000Ty Pfy((=m 7報1000r/l` 6 R ;ػl߯ \O5a``xvfw?ojД̆4l$ЂS&4|~r/Ɔ/Ё2CoDG&Uj^.1b4000|M2ch q;+4[\)G!eP <$hN3hF>L8$dt(l(}ەޮ/߹M&#;uZH?ed[55'WW@=]S94Vn79JWww#Y'E ܙJ dIHmCa*ݢ/`tLT&-**`*!ׁo ө;xN;pJT.MT2ɌE\MoIENDB`kylin-video/src/res/about_hover_press.png0000644000175000017500000000225113517016402017546 0ustar fengfengPNG  IHDRhtEXtSoftwareAdobe ImageReadyqe<&iTXtXML:com.adobe.xmp tIDATxb?01@bDa $08J t`" eP`- b>@1 B w@܏ Y P&U;G0q:| (8 5#|ЬDvqxq?̄@$xc`3(H0&,s@Sx=uYh8*%ͭb v*hH6)tpDrR@6WEOp@9', A1' L€oIENDB`kylin-video/src/res/forward_10_seconds_hover_press.png0000644000175000017500000000350013517016402022114 0ustar fengfengPNG  IHDR tEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp e4{RIDATxbm53B0Ai!!\ F~(\: 2ML? H$#7L $ ? @ NU@rO@Hq(T7 ~h,< G@.Pp& yRШ$@ `!y CO@@Š@N"ty01󀚧 ffb gB Y47SD*݃FgS13K 51K"yŏR@,fH4PH AM!XB;K )<^@K[6ub#.0dg7#ǵK|Fߋ'~gxf{蔜YAO(& hNZ@譼%x4J?w\y +SdjVs#Ԕ).q7x1 zcwq9rd8f"KEorn2-5#`Ha0_ uס58&)>aaJQPC$RA A@m@)AhD"(9Qhܹ@|hAy u~5b! Pa-4(@ ×h`A@P--R3 ` &A5=M Ϡl p] U|yX ىnA@Y d7/>Ձ -%ױf! -se  d *vڊxEð ظE^-/[|[MNY r %V^o%c.?IENDB`kylin-video/src/res/progress_pointer_hover.png0000644000175000017500000003667013517016402020640 0ustar fengfengPNG  IHDRp n pHYs  9iTXtXML:com.adobe.xmp xmp.did:24776fe3-5e39-7846-8bf7-7165f60dca4a xmp.did:FAFE9C98524111E78EE6AFF41394CF28 xmp.iid:7735c375-c239-7a4b-be7c-9f9c2616719e xmp.iid:2a7af3b8-43b0-6745-a0f2-048f0ea0e907 adobe:docid:photoshop:772c815a-4f1d-11e7-a29c-ee28c792f004 saved xmp.iid:7735c375-c239-7a4b-be7c-9f9c2616719e 2017-07-12T13:45:08+08:00 Adobe Photoshop CC 2017 (Windows) / Adobe Photoshop CC 2017 (Windows) 2017-07-12T13:44:21+08:00 2017-07-12T13:45:08+08:00 2017-07-12T13:45:08+08:00 image/png 3 1 720000/10000 720000/10000 2 65535 24 24 -*tn cHRMz%u0`:o_FzIDATx! &{?`Nq`,! } (:i@0mT^I.Dˡ @kuݢ0 K ?^$4T\GDd|xu8'Tͱ `D+FpK0S0!JXR${ɽ] 뿡$qŀ/^KGIL_t=~ǂ *t! agd^I fT<3;ţ 6E2ooc%ЕYd½58a%FUD`h6bkZteiaw5>|-KDaeEMF`X4 ?_—jl3Y55" Ye.\89gf*zKS0ޚ@/;q'25%"ְ_ss,D.>p喑`:Lg[]8WF8ۨ`=sS"3"G 3sC+\>d,&o4`0t0UyE?JP4D).: E]|Wǂ>[)8) ( i]~B jMps?TyENKaNM/iZŽJ3AS90*׬^8>\NPV`/л0gG]ipvAR}augi;1 pi7q0# nvm | G !auT;qk&Nd,j&v={gNb@%`ϕsb'4yV䦋|"px/L=0y*=]/!IENDB`kylin-video/src/res/prefs_hover_press.png0000644000175000017500000000251513517016402017556 0ustar fengfengPNG  IHDRhtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp  }M_IDATxb?01@@1L E0%3\ 0!C$P!g@<PK@$@0[/T#+ˠ& ~ 0@ 5=T d<@@01b_X(G \x;>9jBs!d_< /^(9/:`n `a. N įK@ŗbjTຐlG(ɽr(M4(4 JOX\Hrˁx34>e Y( Br a#|N=es@ܑrL#3IENDB`kylin-video/src/res/unmax.png0000644000175000017500000000332213517016402015145 0ustar fengfengPNG  IHDRl$jZtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp +IDATxb?:>̀"x; 5L dd ).U##!+QTbD8L XjJ&3Iׄ#TB(`RU\ '|aKL XH[ jxz~3^95j$3j 2rS#.pl#o _ @@=U'PGOd#F"*Έd|b1à a<# DP%-^>B=&@JC.CAlF&^Yr9 b3aPi Hn(=+xyy1R։jp4ZA&QzlcTTC|`cCNߤ4`Rth@#Y +]##C[:1!##yٚ[ɑ9"@u 5#?FJK]nh=Q 9`TAS P'N-@hJ`4F#lF(a`hDcJf АFfj (2,#IjGa"]s; Ta4Ŀ~p/ߘAiY0FH a]G'"W1%*eXJ9Gߪ?=԰\e=E0 QG {0(!;:4EMQ0a`4F#l ~#,I IENDB`kylin-video/src/res/prefs.png0000644000175000017500000000267213517016402015143 0ustar fengfengPNG  IHDRhtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp ՜IDATxb?01@@1466N f##"ҵ Y  @p=07 "D3rpp=@,Р 2E%f # T=3P.L_( eW<=`W@ .bY"As  |:`H]@ 4z3PHA  ȥ@+@@t @A@%y H=NPh~H/ibO  04u] *1 .@@ـb[ qt=GC?v ď`~C@< % <Ӡj& {襥Ha*U @* q "`IDATxb? _RĈvO>I3C d=N!2Zd @t0BURP1Y@p[ P#IG@K,gj!@@`WKLZ|@j;P/ U~0ub@(o)"+4| O߇id  q@ ݁x%? ~IDATxb? F Y 9` EP ! XU#.`s ŌP (:`@:͈*@ !n. >4 90`FcjZfĦD@m@OG t7A'P"w'Nx*%Jؒ 4сp b<8 #7BIDATx}yEslٓlA@e r "^ +$n "%HW $($&dYQ]U}f|s}`ҧyKUam6 UjWDT$YU jv'G$o'^M(q$A$dqU f&{"~Y6{2> 0(>Jp@JHvt5fCUȐa_@ss ~T QbQxp63_p8+xo[).9"J)j6ֱYRٺ"J Y9.AC]C=Tg9~!ҏx+O$u2?4yWkdhM9QyҦzCq%%n VQ%lޤ )iπl 4dXpwtAZX8 .>5Cz~`6X5[ 7G Tp1)Xa" )Z5$3˸3CFD6Xg M1T*IdؚQ8Dž2fi1$akl"f ,uث"Z 2[. }0\2!MhJb3-a~LeIX "ȶJX 1KŘDatIUH$U8:r@xe@&LJ6U d8%v(H|͈i3Bg&b3 g}#4dapRd|LVSPll"d'&,Tge`>JcW^RԦ3CҔj:YoF،A'C}#QNCs! B2TR!g(a2N%S)5bI\釓KTK%( fߐҐ$T-fFو JȘ*T&a&ccQdj1ɸ2>em$#[Sz3jap'Z,Mh=j%mzþ99y`HdYC FO<+A'"n1 ऌm8mĒ}O_n%PX2þ 3b*~I6(%)h8ч1\,6+}"̞I!o6 x :BDsu~v\nW0 2'H@ Qg6vTc 1`"3a'3dVx?h Y#`F̙džXXWn idQ]h'A$'Cb⏈7E.Kr2HG&'3eVXӱ:!(O(Y<0*vQˊ`Rcjα$䷧ Up!+ Xaxs. g4 :XB-pu+|6Ѩeq-uq12=SA0}oX4 79(3(S&UYՖ0AgdIS%%&}_M|F>Sѷ9/4GaЭ1%Dx ȁ]$+&TV} B*0YѯpƩ~_su !E#ž!~a+)5 6a"@uQSgAjOP3x%f,'AFfQRBjD``Iek &Yđ"H!P_UR"30H-(WVٙ %MfdBfȰo0S8TVջblALrF s̻=D @YͥdkYQ';&ɶu",y`7`e^FYLG>ٷ ^Rj 7m3` 5Z(Rq@ha{ s`s< Ϭ 2'H2k8ΘQMFf5!h!|8>!AY_AOuK=>pJ֘:nHX4V2Kb-0^jGlTx& YLb:)<>xԛUjwevqvpe ޤ`99 |ᠱ玭?iLG­‘BcF<'9䣟6w:nؚͭ_ 9PZrɜ5__a9r`eSBS)1nfb] p 7J4s4&%nh5:[*h2QaE(m3@$r'4Ss AH-  Dt(;sQl?("ۺҶѩt~Tҏr`{%9sm`0Jc}Is5Q Ƶ)=toaPc\ I)q@JEѕiud,a_E(klWXѓN ]*- QhQ 19X>u8>;29ĐbKw_!Y#Ur VNUK;&Ć0S9Pz\;@W2gx{%Z/lbxufg/L4_=3Qcֹ! ~kԋrB#$ &` !Ñp$3NB.M*5y}naRFN$$13>J$( 'S`ҘL7 ScƟ9{kXMC J1a+)ujȌ#C} MMMoQjZ42;&|afC 9L  GD)d@ ^I]m뙂Q9^8($2\W,1@c$5)I-rDڡܝDgޚIfgFF: 9NPSRH8Z$ D32h" S $jRh"j`4 ^pYzWSpu3ș8Wf7QY.Lhk<ʵ Jt K\䕜t0Y߀icw}3}",[` X"#.39+KPA{lrV2>,3DdefuXDp$f&ʲj0c+du'K}f ղ u- -RLAȁ8K6YId <~4Bɸr 2w:vmTDO $Qdh,镹[d$Ǭ |Z4whŸӟ0tmMǸRS|DXruxRE0&9H``jd/y ^ygUOi]oE_I8 0|XI4s2fG6yZJE p ޳>wkWZ56"1do"7"rt^PG1Qs"MןZֺcYaq#`E"赆jPQh|XmT0g3䄮TD,}BDF.Z|%3ۈsLDo̓mY 7p`Ձ`uг/ܹ>;D T a뢾vП;)Pdy`(?Z?A$AF \~Ar7{c?Y53CO.mMu;b1Y.`(~H"ɉѢfx%s}Ɍ"3HFM FQNNP.1 roXZq5҄&\猯s(˲+h쥭e% 'XW* TJ4gn r4(R)U K{:@շi'09X=!?/kNd~Ls&,W!+, p%W!=c.$ȁ~^Y{^̲#3(aUkhf>dϺ@}V w| /ܸg5 !r\crzG;N;npr,M~*IhFH;p \1-d5CS c.lmHD'X,O{X%A 'G*>id <-ӧN'%d^(lNwÑ2/B2=hx #?J "HIp$HB:`~T|ZíyT'IQKN}ëƶctQvseH2.ƽ늿lx6"$E̥YN/fw?inx{#gD-˗{ҩ2yvogllEMѹM`yNj]/؊3}'?iMiX$Z_ +r U T!왣"~K?=L`,;D^}ȩ#r| IAN;f?Opxwsc~]x2 D'99dDB3#xy+9Gi:uC k4Ott +V=ձkΛ!otg/~ࡨe"mqWaK}S'5 W\u/3ZnS. ᇽC?=lذsk|>'VyQyuF666̟wj<ێ:ګ^uZ`b`g^{m<_Xgrj{Gl޼yOwE'f4͒f0bEi{5t*mw߃¨$2TQw7wMWl3/45orPh;0ǘ_r For[85}yԪ(P9%z}bmw|o3|7fV\ Ӗ?+M|K~o 탋-\z{W\fv7^֮msOS?q6gC``l"I8+}\J J_b6"FƙO?N=#p̩LFe+WQǎ m?=@k E@۶op¨2KUr֑G;܎׻0+su^$ ߻s?I}gɍ7*4Mʐᭇeo=:G)@HY+80wyڱxڻ|G8 o|AAMݘ׀*RD*Z*ѕ9.K=D{1hll;U卯yŔLr49ݻۗ!Umo.k^t_x}nMi6Xe_BooI;(+7̗|m=[n3*ٟyhl$ bm'詬)RM#]-E ˟3߾Ͽ{굆 vY κ^X6_0ʛO#vWr/K_Ǡ@v564p|Akˤ]HYa'@8 RƂa,og Lz9g_w͋{0Z4b^w͋ "?3fl6+.ϋqp==|$Bl*Q lݿrՓf9 3 `Ui/Z^ %L%RAAWm&`CxlșJB~Jz rB$m19T1~GcM@vۗ=ؾl]|#rG:bޙ1UvwǞ붣g^{«z'D*!nٿ7rp0F5ة BƒWGJg:L?!I}P\-)=Nţ8Mh4Oxwn zkKK #38}lf͚2`Sxf?{+6~?/_zc] =M^Bũr`1YE38X)7e#r(̬.]J ꉇڗ7n ֬]X `Θ$^۫!%E* H/X7(e5En  |fv8!P/y=vxD{큵;{+[=(%$dF@&cS6 @#7l|kgGyGde+hJ#'NNJUO566?}.}l6E9cs&{hrK{ ~%1_;^4;WD+?Cn!~7G@Ds8q+ 㲗neOmWZ۹˗UߍneE(oD7mRʽw`W^٤UjtGUTnH7V=9gv[g˞-̙v衇մa+ soxUkS'X@s5k?ߧmx@Ka ۻ/׶a3Nyضb{e oa (pu7.5kOri*X߿-혙#8=6倻~rUW}wÏX7ė/N3kkal턣3('J^>(2ͰcgAzNq H%|>i@}_>6y}Gtqĕvׇ=Po`90c "S>0}JuW/+TeO=ʋ:zWX i[Òi[0\tewW`tlTϝ3KƸ~KRŗ\zݵW|ݳ 6rL;jYRNfq2؛ ґCc'Ƽ4I.pyG=u*MvyK~tOjuY/&Pg`dB_' =t6 ֖9Ƿ-͗]͓&k/9++s=fp]wQN9pcf8]ٍK~q?<?+$ݰߤ]b5NL"Hkz~ ϴ西g6Yf42dH rՂ4CZ 0;񠁯olԧ^z<70hџ$n٫PȾJi9&PbJ Nx z~yfecssێ>mo; %Ǿk ?_92]/>j2Xy.'7?f鿮6e]w_m?ESN~w9~A֖ /Yh$0s _?vӧN^pEr 鵉6tqUC&'3F;k8}"\O ^OvQXH"JK]@WQx.]03–+~}MmRZǠmG/XvԚgz=ai=ή폜nnx+ymGÎ9IU8%m̼ҋ>炎.#=i/{}_C= P\\ՋN={!O|e_ Dl_?o$C<ږs9 TVfA+]q8`=)J\KbWWV{r< 1&'Ԣ~ʢHpzr-_P! At`k; .gL\{qAlP6p<(6yg֥Cjv @~Ol)Scja0e1J,2[---#ͣ j0Lo0i=< H/}P`,wI{ڷ268)Ep@{B@xnKPRz00 pGV;؂1a<Zǖmє"`~p2%@,uI^bԴd D$.ԣ%ޜ S3?n*f: ZUTQtUtyH?J@@fcQڟ_F[Sa~1qִds=ǰ!0Q gEei3lS*G$Xr(\v,&p2VȂ9vlctђ "+X9rL]΋?t^t^(9$ PS1~#'))vpV~7dl{Es"X2 K`zzѡf4|L.D ŒHoojzv}62h >Ą )oDBW `li-UOOP/ypxn1/:[DՄCA ЖpxN`J6WIX10&PcUA3I{? $>{Ef-{lߗ~Sdp@^q7l‚b%s/T75XRc '+@*s*a1|T`Y #&n.2C:q:evw 51B$DMǤ Q*RLefHyc3niХi+Rnpz 1|ÿgL KQsvDmFuLfP8/~[Igʦ`^? U` o_ư>7ՊneȐAcHeܢ \xg-z&9 ]w}.!&,u@,fq=$,"ݡ2nk\[M=!ccW+["4j6HX9!H\+rH/׎`g`'c o!īCв*</>JGNiX W;k`|,uNT`}Q"dŚ{ 6 Z(} [ҌV)]ɞ AnYnaC'T$1%4-f`Q.qnH2dH2Ƙ >J#T̐!CD6;DNmp\"`8&vե #taca`,%()1˰}Ġ`}zg,:4k"NO:OrM4x '&9 Z} 3\,&v cXFNPm,ųq6C(wՠ!i>iZ'Ÿ, ه8%=hv@τ2fmW+>2dR2mA0 >F7%KKnD~ǡڡ1N3UؓX`]NU"H/ UJ|L-\Y{aB7ԓk"&ꝂxTib6hILNhl\,pq'*Ӹ,L}M%ƽ,isF {`[?28įSR \9X`!}91LSC#c oQ}t NQmwԸ TM&=Uq02Ch+ハ;kW@!E2CVsbH  yU> NÁ\%;6CNaZUːa?VYogW+d0YD6vcsyMN%Fǁ̒``۲ Vv%)q-44mŢ7D^MJ)+_n] #ƛdzA;m}@-Q-ɾ.rrUXVK8arω~ f9'2rǢޗġ5m]2!`?%Ⱥ4i8rdJe۽XY>&&fȰxSkQx$ɕ>ӉⱚA.;17^ZB&B@4iJHzKb +`i؞Cre<\aw2g'*o2HH_ 3Aİ_Ԩ1$8ЄbF0`ҍO9#Qv)c5D`m4 ) `UpUJkJ  }G%3dr83~SĨE2SQKX`C'VZ;"gfi\ihN o7;L!#P&ig@ƒ2&WZH6RǪw#3c,mH'يCi3Nn佌UwgqUCxM ):2dGf(8N>ln5)hD&y䂤oXH02/;8 YR<+lC ]ٰ 1 :2͐!M<<DTEƴ[wclԱAp5۷cG$ȁ Y ?Éʵƒŵg F ksNIENDB`kylin-video/src/res/order_cycle_normal.png0000644000175000017500000000227213517016402017662 0ustar fengfengPNG  IHDRp ntEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp bIDATxb? s@1( ne$p@$"Z.S "= =&탈Uȵ;84JE'l###5}deAj,>IENDB`kylin-video/src/res/list_cycle_hover_press.png0000644000175000017500000000300013517016402020557 0ustar fengfengPNG  IHDRp ntEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp K1IDATxb? 01 8{7bĪ (#$%WX.EXmbN,PT*Th)_߃t!c ,&.ER c ❸O9P+} ݇?.ڍIK K _~ @z @`bD^(X7UI7/:) . @,'8w1O1&pa%D8ii"{a=AifX>G(>8Obl} bX4_@8Xs.'!c#9- k4p C?;+C38(=oLPİE@%ǵdX,Òȵy@JKa9e}, V<%2Lx [A9^'̂ɠAn "v5A%@ h]a) k>) T 1HQ @RAp}L@\x))oIENDB`kylin-video/src/res/min_press.png0000644000175000017500000000216413517016402016017 0ustar fengfengPNG  IHDR$$e?YtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp 'IDATxbT[ 01RĈlN9Ĉ |QC m` |~'AS\6IeaU7 stj#[@QF-ꖱfYiƍ&QF-h!8IENDB`kylin-video/src/res/volume_low_normal.png0000644000175000017500000000042713517016402017560 0ustar fengfengPNG  IHDRw=tEXtSoftwareAdobe ImageReadyqe<IDATxb`֠a>f00<&P8-n a pwR,jf$Bm>SP%b "?M,`8(x.*EFZ A=|PFRȂK9`?gE,R0hRPG$PG, ::ȞOt"R\)1chBa`Q0D8Fh"uX. >8IENDB`kylin-video/src/res/close.png0000644000175000017500000000412613517016402015125 0ustar fengfengPNG  IHDRl$jZtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp ?4/hIDATxb?:=os001 5&Vmyr#z a4PPl J9d D4 FlP$,J9L|-1_bK @C/`XH-c̎80Hihhϲ/_202ݿo3p3|e 㳌=,pbBe XdGp B3@D#1&&/~=*8l5 =b!hE\‹ _pM +)1UnCs:\xA< #9EgVq)$QbYR߾0s ȳz Ȟ 9S2ǰ- hPU O^SIqcT11615Zg_IQ'cFh;8.B/`SputRHKJd{AR!A "" wf``z!.l@Rq _} 01i+$Gi'3pPe5N Kq#9}1X7IsdIrw@}sdINj%դB裂wcwSл1X8. M|R:1بc_lv[u# փZυ=q*09Uzr3'M(A0,*,Q=úra`HGhߊ*zx4Q`O =I* V&A1w=) r0@h 4nQwra ɿ7oC_QXXāŠK[[Dh!_#Q%As,"Qb%0;vvIf&&SQĬD`("Ƞ l4|gZp(^@@1n`5ej]G.0G5pq1b\\ ?UT:>hB^F|^U? `9vJ|Ka] Y #B.*їҳHnN$CS(G`4F#lF(@+F#lLIENDB`kylin-video/src/res/backoff_10_seconds_hover_press.png0000644000175000017500000000345113517016402022050 0ustar fengfengPNG  IHDR tEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp E;IDATxb x.s~arCiF& &z F@ Hz3 le a bfM(m ST TU@ s tcN*Eq8Jb/ f @,נƢ1` @ a :,M##Ի&A! ߲ i E`j@T5jOt'5a1Ami g!$^r65ہcR C01!7Pt*04f! si1 Z$ ЃA84A&` PIF4X"l#+id&%aGX"ƽ@M0 gWR52@"K#4= nESwFXJ{?E UX2PS\SJYZǧAlVjA\b65U*+uZ3ؙw* [KgXqfXgOpacou$^<†܆~y= |$D=d ji]y3BC$jCU%|8K>ߒ qMH1N dR?]˱ۤ3S&Jc|%}pE~eu^vU4KvH2>a`Y9 S:g!tUC}`^ XY >CSʀ7Tz2I^ΟmmVP n6؅V]s-IENDB`kylin-video/src/res/osd.png0000644000175000017500000000474013517016402014607 0ustar fengfengPNG  IHDR00WsRGB pHYs a aJ%tIME1jn7bKGD `IDATxZ[hU皓I[4ѱ02XA<0D|h R|J0xE)]Wk!P$BL$ԣIȱm5Oaph1 8kJ?xpI ETT&`V:Mgd]^)`zzR 9JOBh3GPϢu ҫ4J/ E)8&`b0 quW>=i'2@? 1q"iSf:%ra7l{9^> 4ݲ*tH;0˪w"}"2Ap}!0 Bz[Mt`8S5!5S "02X@+}>ATf--dcBbD `@gΰ7,@Q A@u+@`CKϳ7; d_f"ﷵo A48UY&61PeJ9*X]ש=z-.+!?`x6r̓7r/.0<=IM%mmرc^Ѧ, k B nsq=ޚ!Ӭ,K4M2zV`choooD'#Ɠ'D)h@'hmăA2  ɬ4 p\4qy <OMMѣGhkE- !F]xwRMM a4q32ljH/ȋ$=?~LOh~J'vmjjA9v?q?! ?{-9:sxkCCC={7nxm ˹/i'otac~cǎ?߻wJNE Qɭ[l Vp" #}d8ybHQ*'s&RΝ;O"%9 *5eVZPWGeH,BT,]@98t?Q6OE"%tAR- -g4H!+OD U__?P[[;X}ɤ g=y;/\4,l`&4;MHG@RakKa!PpqI> "/xjw-b>>U{ 6+c I4c8&:$'3/Nv.e P!.]ڃr 8/E Iy[lTabK!>ޓBeʸC\R$! ?},XeKN3)~zI!OLL,d !_sdƳ, ع??)<)<, 7#r?A!ya24g]1:OMC 6k^]ywg;V+Pnָhi  FĨ`YoYHq"z~#lc#gQ\&#2E"6M9AXHY}Xd^@a9"5)"cq/zk\Y"5Bߵp}z H*~Y]]BUUh@4! $nߦn40>><|GC۲9A@@x&_/ TV.»r"9G3,$sG=Zcy h * 4oC8.iTg"cc@,i@D877o7f!e֭@/EʙO? 8$oK3n3 ^쌨܊l8Ú*HRu r8`x6`;gQXrԩp˞g|_QQAϟo""&> x%@-:ݽc߾};;;߯&x^EaŊgν{r[D оc7o7|XȹJJemՔH$lm1Da~>?G1+}s=|ŧW1B~gl!d+-tdpl!k `1 -S<(#RI}AђhJSH}Vež-HlB>7a)lIENDB`kylin-video/src/res/volume_high_normal.png0000644000175000017500000000075613517016402017703 0ustar fengfengPNG  IHDRw=tEXtSoftwareAdobe ImageReadyqe<IDATxڴVq0 _`&ht!N@2Aݠl@Q?Tw:޳dI& u]y%m?sʱ1 y#r<-4InRNZQ?[$^[jҭ@~84_pO/d/8K}/7f_IS+(,# 3Q.Ц* Ι+FX;"H2i/H d2:3 GCn kقYB 6\Wl9ṬZ##q݊\0l s{K.0H{W惁4Nбjߓ!s\zS+g"F`ȋR%=2Dh|=8GTwVٞ7SO?dPqGɴ 1IENDB`kylin-video/src/res/pause_normal.png0000644000175000017500000000231613517016402016504 0ustar fengfengPNG  IHDR==ieQtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp xIDATxb9À01)1 b0@4b7-R "/0 G5jՌEҀFqj`||@@vaDud& S(5 v`p^ڱco-`c/a.2 @CCCCCCCM ާO#NرDIENDB`kylin-video/src/res/open_screen.png0000644000175000017500000000022713517016402016316 0ustar fengfengPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<9IDATxb`򀑐xiL- gd &Jq*BL kIENDB`kylin-video/src/res/stop_normal.png0000644000175000017500000003545713517016402016370 0ustar fengfengPNG  IHDRp n pHYs  9iTXtXML:com.adobe.xmp xmp.did:24776fe3-5e39-7846-8bf7-7165f60dca4a xmp.did:BE419F56524511E7A191DF328D946EBD xmp.iid:6d1e5c5d-0826-2544-86f0-1df23726026c xmp.iid:2a7af3b8-43b0-6745-a0f2-048f0ea0e907 adobe:docid:photoshop:772c815a-4f1d-11e7-a29c-ee28c792f004 saved xmp.iid:6d1e5c5d-0826-2544-86f0-1df23726026c 2017-06-16T12:25:26+08:00 Adobe Photoshop CC 2017 (Windows) / Adobe Photoshop CC 2017 (Windows) 2017-06-16T11:41:55+08:00 2017-06-16T12:25:26+08:00 2017-06-16T12:25:26+08:00 image/png 3 1 720000/10000 720000/10000 2 65535 24 24 uR cHRMz%u0`:o_FIDATxb? 0000022"80bAQS b?,VUDIBECC%'%b?Ccc"@}}=#$tЀjJ] Diwxm 'X>S🎡4ȴ􁈴"9-hS```Hs3b ,1Hy,Z0jA #aZyKB[DyIENDB`kylin-video/src/res/about_normal.png0000644000175000017500000000050413517016402016476 0ustar fengfengPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxڬSQ0 H@:s0pPO8X% a8=z]V8[45iScF~v8,(cD0 0* '*pa#R¿Mon>"*AjC|13 ֩w$rfCl tl,pbB HJr@ X^QA2ƒc޷ZI0~H[ڨ;.c=_W ^IENDB`kylin-video/src/res/spin_top_arrow_disable.png0000644000175000017500000000231013517016402020541 0ustar fengfengPNG  IHDR |@~tEXtSoftwareAdobe ImageReadyqe<viTXtXML:com.adobe.xmp 2`IIDATxbtpp`& ~ F ;;; f ϟ?R$@ACRRRLpD8\'! PF,XmB1M : Ç.}5Bϟ@?~@1h S\%P\$''${SHZZΝ;***_~})N//ޛ7onݺ? dEʨUIENDB`kylin-video/src/res/min_normal.png0000644000175000017500000000216213517016402016151 0ustar fengfengPNG  IHDR$$tEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp ?IDATxb?:`b( Ftj#,@\Osh ""*0f4<d$ f9jАI,6 0guШF4Q:hA4pw^2IENDB`kylin-video/src/res/play_center_hover_press.png0000644000175000017500000001557713517016402020760 0ustar fengfengPNG  IHDR6wNtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp .IDATxb WX3x.94J?b fHqif!xR(4"1QPh(6eb £psىv54Rdpb&WHg?A5ȉ1p` 5g}97,|l0iOt|e((<TPj|P26Ð@1YK7q=bBi* Xswbd#7㬕^#S)ݢT/Q yqT3V~0q0Rץ   ah1b Psfgr?QPbɆS12QuH \]&j\R|Cu*RY ҿPð2DlmJJHber2)! &ZS"%1HcH|CC7#6Aq;p σF?(ڝv`#6d{qsLBghp&1 nǮw`VAı庬 B+`"RݱVb 9`v tB 12, 5{aT *3|!O$%C)vٖLS[^, At Vl 1 ujFdP_& nGd0lZo?CMw@Mf)\πXV-fRPQӱ4@Fk>!UPtf?1O@l'I 'P8+asl, ]4Hapw0[`;TV93v X 9rV PԻM!3e^j{dwf"̱2ԁf#T_L ! -wY`R1Ӽ=LQcap`(Ntð_C[P(/agag#?pPczȓA |:Hn]q+X @Rb1l1}-yٽ? @cJ[&NG_e2a2/Y!ز3|ev@m`:TZ!n =s T;C*vݓ> ˭A[09t'TS Ͽgc4S,6: QaxutX|Ma;f`L #a? NhR Yͳk7R ;` Ls]Ͱa,l(ƨ/2E5D!G8g聟p,z& g:FqǏAHvHG)3n>h L->`Ae&l|`Р Xv&h>h샮UP ngF =a.`jEl2LZw<;d[&PAX @ FX!V,aD2c4áH^- PF2ƬGS,2%XHb@@a#9łָҤ7Rl9a bA7-Y [ `Lc8og:JK!1"AKU )&j4F .(L1}h%DLL#ئ*-F-R$nty{*Y:޽w?y )sE(d ntFmͦq󐃊Kβ焑 0.ײ|k.رNe=kG͞/P,B%=_QV;"*{HRqI^TK WtS&Y1;Opln .c$+ 2) t&"X~7(I4u`a?{ ~ Aގ :NH덳./g0ORMQ(-6(lsx^+-X2ayMD` u02.„tRgR]R +ٹЫ 9S2٥s5qP@S!%>4U{TMj0?YF\RmN]GTbOpu^kנF,iݟl#[?׿oʥ EV0}QTʣOn`4hɶsJR<7DjZCxm(Y&`kD_|Y{_,F =Oamީc*1M V}H~bbEhL챲4+|Ěu / EtBFZ/*bakHD A0O"|6nMȈ6߃.<B@vt` 4YM'~a 쳕ExlO1H)Wm`-!dF͢5&-"/}G-`i]dg:r [[ @͞JH)RMOũCluE݁4e:S5bndmc/5q/(Mj d.2=+r"&|K?̗ojo%E>8xË_zAS(VVBU)b鋳=GS#@{gUٶo( E* Rh%(hRA$99<(j0"@HQJ  (G9 rYvwnJ-{UCiwoƈS>h=]Y'if$B7ApM.Ru<9)F-z]UUkі- f,5mW4>D?6GRItIl`إ8 wN@? WaF Eqɨґ&}㒾*K`вI:Րz dRMҷ,`e]]C1GW ,{и;SJgϽ$ fE헿4F0;r-*dX]=tV!F&_lqZ6]#Y Qv[ZV$hyݣt'ښFd -t$ɵ-km/se"m\hl}rDl)5P肥稌9`87WU?Sͮ0`kTM̗ZM-ee8׃A2Mhi\3A""X sL-L%DF#~4 -f[ l<*X9Z Mu,d! (WcwT,_X#ښKɮQjwsMyh tߧC>,TE >O<5dim3`EnzmSH {ϕüޚxV8 iR{ v,CVͳ$޾˝p#F\1,#,Ǿm-fBeKp^ l, N²^x@mHzYVEO uiэbxi:mۡBb~@J)DQj3l9ܛióp[r,l7Al@k5xRu)ACS`n~I t'+]A _' [IO6X#/גQY6UAi \7|s ]5R#sfl#Oozn)Ӯ ª,l"_ie}k<sx90}˜#+`7)gGeI*˃B]خ( ^ :M"WkW`peJp~ ^bwj{+{aVκXUl&8¼vH"P &Evu($1]RwmwbB`۲4Nykba2Con@[O[,|2V{b2.MQ8+2mΐHuzKttE"MczAI&ҁzcF(Mv!eblOxyڄP!6Pak\plyOHѽ%aMF1F߷ft*\PMQ`M@:6:7DJku)l4v z'ksM'h꽭|lQWk|';B)%^0X,XCE AkDETj8 c1)r րV԰6qbk}7>M ^AH8@>ԭnLd?X:ӷY,@M h _p[;F\Ntk;ۡiM|r'aF',ѡ|ӵGT)oj Bl q҆~Z#mC? Oq{U_X!M}5nXX]Y! yk7<F|d AG[i.XW,WN!@E` oN.O][5^i_, q0)czaibͩ6h|CLI=.;U;q(+>G4tV ɡmGXLbUcZfu/e\#:m?Mď$Y(/#m0]\'!b>:0W5T- b]wkEeg:De2]8z"?d)lbϔѕhw\,uw Hq3ZIm7`"*˄ehAXL88M~ )0Fg]`P ;Z`mN >F/[L%Ga$b,/4`P?z|,X&6靦}79, zZѾ1LH,wQ,Xks- I ӜXchte6hV9{?͑i`h A2`N[j13Xᇮ9Цt;vDVE2R3#𺜚IENDB`kylin-video/src/res/dragbar_hover_press.png0000644000175000017500000000174213517016402020042 0ustar fengfengPNG  IHDR;֕JtEXtSoftwareAdobe ImageReadyqe<!iTXtXML:com.adobe.xmp 2VhWIDATxb?@ W'K{Oe3$iFhl$J3.ajlk@fblĪX14b# 0X0t+#病IENDB`kylin-video/src/res/combobox_arrow_disable.png0000644000175000017500000000233413517016402020524 0ustar fengfengPNG  IHDRtEXtSoftwareAdobe ImageReadyqe<viTXtXML:com.adobe.xmp r!IDATxbtpp`& eA D!b[0 JG @ʀXKJRR.gC?$lt޽ϧ P| XidKpqq1lll`d@]>| -- d<}EY,@${,)$HuRg)x/p)c, 03TAcDvbfDXfnl/ƪQub&wMfIENDB`kylin-video/src/res/playlist_open_hover_press.png0000644000175000017500000000253513517016402021323 0ustar fengfengPNG  IHDRp ntEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp ^!$oIDATxb? GFdB0!)C u7|_AlTUH]h.X%@Sd!DR?'#%.LfU|l DMBkV0 kfb dЖ(NBw3tV @@;\A KJmy" FhEJt ,Na8k#oJrA'Y-ٳj .9d%S"fqF -!۲/IENDB`kylin-video/src/res/option_hover.png0000644000175000017500000000235313517016402016533 0ustar fengfengPNG  IHDR$$e?YtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp 풸#IDATxb: 01RĈlϏn ʩA8Ĉ -5EXQh t9W!$}9Hp>dM$ L,B؋>Ƨ h5fd6ۀW&Hdj!Hjc!#AbO@Eɂl8o-l6~Cvbp'e#3wՍ ^ˀR%Nre 9K"6U#F|(8zq6jH AIuIENDB`kylin-video/src/res/pause_hover_press.png0000644000175000017500000000231613517016402017553 0ustar fengfengPNG  IHDR==ieQtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp IDATxb9À01)ИV0R bs8` D8p 7tH5 @ 4`N-U#㫩G}nحca!o\n0N`0!xhǎM@8A6G0 :6)d{>? :*-@fUŞIENDB`kylin-video/src/res/screenshot_hover_press.png0000644000175000017500000000231613517016402020613 0ustar fengfengPNG  IHDRhtEXtSoftwareAdobe ImageReadyqe<&iTXtXML:com.adobe.xmp .=>IDATxb?01@}bDa `p%0@ P|,R4\E  d0UP|l>0W @@qYCt hP_xs57aB40+}= P r#P2q4@+~4† Ѓ=>adO0!ACgvjELoȡIY.g&@C0Բ 91b$9(E/:Pu@$~RRaH@d1X,GdBJYIENDB`kylin-video/src/res/fullscreen_normal.png0000644000175000017500000000247113517016402017533 0ustar fengfengPNG  IHDRp ntEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp 3KIDATxb? s@1(khhU@566g@,HZe`~Hh~.g!@!@1\A[qhfʃ4N%Oz< G@ bθX 9He3œrP3M  )h,a6d+>|`Nb!` p)3dY 7ȹ ?(JwT+(60m$ QhPG-:@h"sr.$zͅP i$!FܛAIENDB`kylin-video/src/res/poweroff.png0000644000175000017500000000037113517016402015645 0ustar fengfengPNG  IHDR(-S-PLTE۹&tRNS 0P`p{mIDATx]OD!E_6ykjXWD7c!ZY:K!sG@J4>)5J~Q8 3IENDB`kylin-video/src/res/previous_normal.png0000644000175000017500000003644713517016402017257 0ustar fengfengPNG  IHDRp n pHYs  9iTXtXML:com.adobe.xmp xmp.did:24776fe3-5e39-7846-8bf7-7165f60dca4a xmp.did:A792F0EC524511E78266808D4B6162B4 xmp.iid:1aabfc52-2e34-d449-bafa-250edc218ba0 xmp.iid:2a7af3b8-43b0-6745-a0f2-048f0ea0e907 adobe:docid:photoshop:772c815a-4f1d-11e7-a29c-ee28c792f004 saved xmp.iid:1aabfc52-2e34-d449-bafa-250edc218ba0 2017-06-16T12:25:38+08:00 Adobe Photoshop CC 2017 (Windows) / Adobe Photoshop CC 2017 (Windows) 2017-06-16T11:40:14+08:00 2017-06-16T12:25:38+08:00 2017-06-16T12:25:38+08:00 image/png 3 1 720000/10000 720000/10000 2 65535 24 24 w- cHRMz%u0`:o_FIDATxb? 0000466e``Pb 000bAQȈb?L*𪡡ALB ٘wl1 0@OPDL SҹcЀ5tuܨ xtϱ @P#e H)S05cd*v  z*"'ͷ%^ l1ʇdĂZz1g욀○w\p' MҾm6LE8U pGh4&̂&fA61Y{ A AZ&,wrq $[2`>,~h*pS#>RƯ+@ mHV^X5Qȡ0)\F6 PAjթfq-:PSOj٣4DQ` ll,m\`)(jEF1d>!V6XYQq n ^r33;St:Gkz!L]n3` DfI`5zQ;I9ZJ6DeNPov<#<ܩWi+M$O1ct,HrZG蝫{bO%1jOm>Ǖ#U} Q;>Gm4Bc_zRJc)Av7=?%=3IENDB`kylin-video/src/playlistmodel.h0000644000175000017500000000316313517016402015554 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "datautils.h" class PlaylistModel : public QStandardItemModel { Q_OBJECT public: explicit PlaylistModel(QObject *parent = 0); ~PlaylistModel(); QModelIndex findModelIndex(const VideoPtr video); QString findFileNameByRow(int row); QString filePathData(const QModelIndex &index, int role = Qt::DisplayRole) const; VideoPtr videoData(const QModelIndex &index, int role = Qt::DisplayRole) const; virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) Q_DECL_OVERRIDE; public slots: void setHoverIndex(const QModelIndex &index); protected: virtual Qt::DropActions supportedDropActions() const Q_DECL_OVERRIDE; virtual Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE; private: QModelIndex m_removeIndex; QModelIndex m_hoverIndex; }; kylin-video/src/main.cpp0000644000175000017500000000667213637124061014165 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "myapplication.h" #include "kylinvideo.h" //#include "remotecontroller.h" //#include "controllerworker.h" #include #include #include #include #include #define CONTROL_DBUS_SERVICE_NAME "com.kylin.kylinvideo.controller" int main(int argc, char **argv) { signal(SIGINT, [](int) { QApplication::quit(); });// 设置退出信号 MyApplication a("kylin-video", argc, argv ); a.setQuitOnLastWindowClosed(false); a.setOrganizationName("kylin"); a.setApplicationName("kylin-video"); a.setApplicationVersion("2.1.0"); #if QT_VERSION >= 0x040400 // Enable icons in menus QCoreApplication::setAttribute(Qt::AA_DontShowIconsInMenus, false); #endif /* //----------------register controller dbus service---------------- QDBusConnection connection = QDBusConnection::sessionBus(); if (!connection.isConnected()) { fprintf(stderr, "Cannot connect to the D-Bus session bus.\n" "To start it, run:\n" "\teval `dbus-launch --auto-syntax`\n"); return 1; } //registerService在FT arm上将导致麒麟影音在播放视频时,如果在其他视频文件上右键选择麒麟影音进行播放,麒麟影音无反应,即无法调用handleMessageFromOtherInstances(),而在x86上无此问题 if (!connection.registerService(CONTROL_DBUS_SERVICE_NAME)) { fprintf(stderr, "%s\n", qPrintable(connection.lastError().message())); exit(1); } ControllerWorker *controller = new ControllerWorker; ControllerAdaptor *adaptor = new ControllerAdaptor(controller); // connection(&a, &QApplication::aboutToQuit, adaptor, &ControllerAdaptor::aboutToQuit); QDBusConnection::sessionBus().registerObject("/", controller); //------------------------------------------------------------------- */ QStringList args = a.arguments(); QFile qss(":/qss/res/style.qss"); if (!qss.open(QIODevice::ReadOnly)) { qWarning("Can't open the style sheet file: :/qss/res/style.qss."); } else { qApp->setStyleSheet(qss.readAll()); qss.close(); } QString arch = ""; #ifdef __x86_64__ arch = "x86_64"; #elif __i386__ arch = "i386"; #elif __aarch64__ arch = "aarch64"; #endif const char *snap; if ((snap = getenv("SNAP")) != NULL) {///snap/kylin-video/x1/ QString snap_path = QString::fromStdString(std::string(snap)); qDebug() << "SNAP: " << snap_path; } KylinVideo *player = new KylinVideo(arch, snap/*, controller*/); KylinVideo::ExitCode c = player->processArgs(args); if (c != KylinVideo::NoExit) { return c; } int r = a.exec(); delete player; return r; } kylin-video/src/tipwidget.cpp0000644000175000017500000000650213625147453015240 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "tipwidget.h" #include #include #include #include #include #include #include TipWidget::TipWidget(const QString &text, QWidget *parent) : QFrame(parent)//: QWidget(parent, Qt::SubWindow) //: QWidget(parent, Qt::Window) { setWindowFlags(windowFlags() | Qt::SubWindow); setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); // setTransparent(true); setWindowFlags(/*Qt::ToolTip | */Qt::FramelessWindowHint); setAttribute(Qt::WA_TranslucentBackground); setContentsMargins(0, 0, 0, 0); setObjectName("TipWidget");//kobe:设置背景色 m_radius = 4; m_shadow = 20; m_shadowMargins = QMargins(20, 20, 20, 20); m_borderColor = QColor(0, 0, 0, 0.2 * 255); QVBoxLayout *layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); m_textLabel = new QLabel(text); m_textLabel->adjustSize(); m_textLabel->setStyleSheet("QLabel{font-size: 16px;color: #ffffff;}"); m_textLabel->setAlignment(Qt::AlignCenter); layout->addStretch(); layout->addWidget(m_textLabel); layout->addStretch(); this->setLayout(layout); layout->setSizeConstraint(QLayout::SetFixedSize); hide(); } TipWidget::~TipWidget() { } void TipWidget::setTransparent(bool transparent) { if (transparent) { setAttribute(Qt::WA_TranslucentBackground); setWindowFlags(windowFlags() | Qt::FramelessWindowHint|Qt::X11BypassWindowManagerHint); set_widget_opacity(0.5); } else { setAttribute(Qt::WA_TranslucentBackground,false); setWindowFlags(windowFlags() & ~Qt::FramelessWindowHint); } } void TipWidget::set_widget_opacity(const float &opacity) { QGraphicsOpacityEffect* opacityEffect = new QGraphicsOpacityEffect; this->setGraphicsEffect(opacityEffect); opacityEffect->setOpacity(opacity); } void TipWidget::setText(const QString text) { this->m_textLabel->setText(text); } QBrush TipWidget::background() const { return this->m_background; } int TipWidget::radius() const { return this->m_radius; } QColor TipWidget::borderColor() const { return this->m_borderColor; } void TipWidget::setBackground(QBrush background) { this->m_background = background; } void TipWidget::setRadius(int radius) { this->m_radius = radius; } void TipWidget::setBorderColor(QColor borderColor) { this->m_borderColor = borderColor; } void TipWidget::aniFinished() { this->hide(); } kylin-video/src/timetip.h0000644000175000017500000000242113517016402014341 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 _TIMETIP_H_ #define _TIMETIP_H_ #include class QLabel; class TimeTip : public QFrame { Q_OBJECT public: explicit TimeTip(const QString &text, QWidget *parent = 0); ~TimeTip(); public slots: void setText(const QString text); void setPixMapAndTime(QPixmap pixmap, const QString time); protected: virtual void paintEvent(QPaintEvent *event); private: QFrame *text_frame = nullptr; QLabel *m_textLabel = nullptr; QLabel *split_line = nullptr; bool repaint_flag; }; #endif kylin-video/src/mainwindow.cpp0000644000175000017500000034531013637124061015410 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "playlist.h" #include "titlewidget.h" #include "bottomwidget.h" #include "playmask.h" #include "aboutdialog.h" #include "esctip.h" #include "tipwidget.h" #include "messagedialog.h" //#include "shortcutswidget.h" #include "helpdialog.h" #include "bottomcontroller.h" #include "filterhandler.h" #include "coverwidget.h" #include "datautils.h" #include "infoworker.h" #include "maskwidget.h" #include "videowindow.h" #include "poweroffdialog.h" //#include "controllerworker.h" #include "smplayer/desktopinfo.h" #include "smplayer/paths.h" #include "smplayer/colorutils.h" #include "smplayer/global.h" #include "smplayer/translator.h" #include "smplayer/images.h" #include "smplayer/preferences.h" #include "smplayer/filepropertiesdialog.h" #include "smplayer/recents.h" #include "smplayer/urlhistory.h" #include "smplayer/errordialog.h" #include "smplayer/timedialog.h" #include "smplayer/audiodelaydialog.h" #include "smplayer/filedialog.h" #include "smplayer/mplayerversion.h" #include "smplayer/actionseditor.h" #include "smplayer/preferencesdialog.h" #include "smplayer/prefshortcut.h" #include "smplayer/myaction.h" #include "smplayer/myactiongroup.h" #include "smplayer/extensions.h" #include "smplayer/version.h" #include "smplayer/videopreview.h" #include "smplayer/inputurl.h" #include "smplayer/audioequalizer.h" #include "smplayer/eqslider.h" //注意: x11的头文件需要放置在QJson/QDbus的后面 //#include using namespace Global; QDataStream &operator<<(QDataStream &dataStream, const VideoPtr &objectA) { auto ptr = objectA.data(); auto ptrval = reinterpret_cast(ptr); auto var = QVariant::fromValue(ptrval); dataStream << var; return dataStream; } QDataStream &operator>>(QDataStream &dataStream, VideoPtr &objectA) { QVariant var; dataStream >> var; qulonglong ptrval = var.toULongLong(); auto ptr = reinterpret_cast(ptrval); objectA = VideoPtr(ptr); return dataStream; } MainWindow::MainWindow(QString arch_type, QString snap, /*ControllerWorker *controller, */QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, flags) #if QT_VERSION >= 0x050000 , was_minimized(false) #endif , m_bottomController(new BottomController(this)) , m_mouseFilterHandler(new FilterHandler(*this, *qApp)) , m_leftPressed(false) , m_resizeFlag(false) , m_ignoreShowHideEvents(false) , m_arch(arch_type) , m_snap(snap) , m_maskWidget(new MaskWidget(this)) // , m_controllerWorker(controller) , m_dragWindow(false) , m_lastPlayingSeek(0) { this->setWindowFlags(Qt::FramelessWindowHint/* | Qt::WindowStaysOnTopHint*/);//设置窗体标题栏隐藏并设置位于顶层 this->setMouseTracking(true);//可获取鼠标跟踪效果,界面拉伸需要这个属性 this->setAutoFillBackground(true); this->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); this->setMinimumSize(WINDOW_MIN_WIDTH, WINDOW_MIN_HEIGHT); this->resize(900, 600); this->setWindowTitle(tr("Kylin Video")); this->setWindowIcon(QIcon::fromTheme("kylin-video", QIcon(":/res/kylin-video.png"))); // this->setWindowIcon(QIcon::fromTheme("kylin-video", QIcon(":/res/kylin-video.png")).pixmap(QSize(64, 64)).scaled(64, 64, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); this->setAcceptDrops(true); // this->setFocusPolicy(Qt::ClickFocus); this->setFocusPolicy(Qt::StrongFocus);//让空格等按钮事件可以在keyPressEvent函数中获取 installEventFilter(this);//add event filter m_windowPos = pos(); this->initRegisterMeta(); //遮罩 // m_shortcutsWidget = ShortcutsWidget::Instance(); // m_shortcutsWidget->set_parent_widget(this); createPanel(); createVideoWindow(); createCore(); createPlaylist(); createTopTitleBar(); createBottomToolBar(); createAudioEqualizer(); createActionsAndMenus(); createTrayActions(); createTipWidget(); createEscWidget(); createMaskWidget(); initRemoteControllerConnections(); // m_coverWidget = new CoverWidget(this); // m_coverWidget->setContentsMargins(0, 0, 0, 0); m_centralLayout = new /*QVBoxLayout*/QStackedLayout(m_centralWidget); m_centralLayout->setContentsMargins(20, 20, 20, 20); m_centralLayout->setMargin(1); m_centralLayout->setSpacing(0); m_centralLayout->addWidget(m_topToolbar); m_centralLayout->addWidget(m_mplayerWindow); // m_centralLayout->addWidget(m_coverWidget); m_centralLayout->addWidget(m_bottomToolbar); m_topToolbar->show(); m_mplayerWindow->show(); m_bottomToolbar->show(); m_bottomToolbar->setFocus(); this->setActionsEnabled(false); if (m_playlistWidget->count() > 0) { emit this->requestPlayOrPauseEnabled(true); m_bottomToolbar->updateLabelCountNumber(m_playlistWidget->count()); } else { m_bottomToolbar->updateLabelCountNumber(0); } QTimer::singleShot(20, this, SLOT(loadActions())); this->move((QApplication::desktop()->screenGeometry(0).width() - this->width()) / 2, (QApplication::desktop()->screenGeometry(0).height() - this->height()) / 2); this->changeStayOnTop(pref->stay_on_top); this->changePlayOrder(pref->play_order); // QGraphicsDropShadowEffect *effect = new QGraphicsDropShadowEffect(this); // effect->setBlurRadius(50); // effect->setColor(Qt::red); // effect->setOffset(0); // this->setGraphicsEffect(effect); } MainWindow::~MainWindow() { this->clearMplayerLog(); if (m_tipTimer) { disconnect(m_tipTimer, SIGNAL(timeout()), m_tipWidget, SLOT(hide())); if(m_tipTimer->isActive()) { m_tipTimer->stop(); } delete m_tipTimer; m_tipTimer = nullptr; } if (m_core) { delete m_core; // delete before m_mplayerWindow, otherwise, segfault... m_core = nullptr; } if (m_playMaskWidget) { delete m_playMaskWidget; m_playMaskWidget = nullptr; } if (m_escWidget) { delete m_escWidget; m_escWidget = nullptr; } if (m_tipWidget) { delete m_tipWidget; m_tipWidget = nullptr; } if (m_mplayerWindow) { delete m_mplayerWindow; m_mplayerWindow = nullptr; } if (m_playlistWidget) { delete m_playlistWidget; m_playlistWidget = nullptr; } if (m_videoPreview) { delete m_videoPreview; m_videoPreview = nullptr; } // if (m_shortcutsWidget) { // delete m_shortcutsWidget; // m_shortcutsWidget = nullptr; // } if (m_prefDialog) { delete m_prefDialog; m_prefDialog = nullptr; } if (m_propertyDialog) { delete m_propertyDialog; m_propertyDialog = nullptr; } // if (m_aboutDialog) { // delete m_aboutDialog; // m_aboutDialog = nullptr; // } if (m_helpDialog) { delete m_helpDialog; m_helpDialog = nullptr; } if (m_mainTray) { delete m_mainTray; m_mainTray = nullptr; } if (m_mainMenu) { delete m_mainMenu; m_mainMenu = nullptr; } if (m_toolbarMenu) { delete m_toolbarMenu; m_toolbarMenu = nullptr; } if (m_resizeCornerBtn) { delete m_resizeCornerBtn; m_resizeCornerBtn = nullptr; } if (m_topToolbar) { delete m_topToolbar; m_topToolbar = nullptr; } if (m_bottomToolbar) { delete m_bottomToolbar; m_bottomToolbar = nullptr; } if (m_centralLayout) { delete m_centralLayout; m_centralLayout = nullptr; } if (m_centralWidget) { delete m_centralWidget; m_centralWidget = nullptr; } } void MainWindow::initRegisterMeta() { qRegisterMetaType(); qRegisterMetaTypeStreamOperators(); qRegisterMetaType(); qRegisterMetaType>(); } void MainWindow::createPanel() { m_centralWidget = new QWidget(this); m_centralWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); m_centralWidget->setMinimumSize(QSize(1,1)); m_centralWidget->setFocusPolicy(Qt::StrongFocus); this->setCentralWidget(m_centralWidget); m_centralWidget->setFocus(); } void MainWindow::createVideoWindow() { m_mplayerWindow = new VideoWindow(m_centralWidget); m_mplayerWindow->setColorKey("121212");//视频显示区域背景色设置为黑色 m_mplayerWindow->setContentsMargins(0, 0, 0, 0); m_mplayerWindow->allowVideoMovement(pref->allow_video_movement); m_mplayerWindow->delayLeftClick(pref->delay_left_click); m_mplayerWindow->setAnimatedLogo(pref->animated_logo); // QVBoxLayout * layout = new QVBoxLayout; // layout->setSpacing(0); // layout->setMargin(0); // layout->addWidget(m_mplayerWindow); // m_centralWidget->setLayout(layout); connect(m_mplayerWindow, SIGNAL(doubleClicked()), this, SLOT(doubleClickFunction())); connect(m_mplayerWindow, SIGNAL(leftClicked()), this, SLOT(leftClickFunction())); connect(m_mplayerWindow, SIGNAL(rightClicked()), this, SLOT(rightClickFunction())); connect(m_mplayerWindow, SIGNAL(middleClicked()), this, SLOT(middleClickFunction())); connect(m_mplayerWindow, SIGNAL(xbutton1Clicked()), this, SLOT(xbutton1ClickFunction())); connect(m_mplayerWindow, SIGNAL(xbutton2Clicked()), this, SLOT(xbutton2ClickFunction())); connect(m_mplayerWindow, SIGNAL(mouseMovedDiff(QPoint)), this, SLOT(moveWindowDiff(QPoint)), Qt::QueuedConnection); m_mplayerWindow->activateMouseDragTracking(true); } void MainWindow::createCore() { m_core = new Core(m_mplayerWindow, this->m_snap, this); connect(m_core, SIGNAL(widgetsNeedUpdate()), this, SLOT(updateWidgets())); connect(m_core, SIGNAL(audioEqualizerNeedsUpdate()), this, SLOT(updateAudioEqualizer())); connect(m_core, &Core::showFrame, this, [=] (int frame) { //qDebug() << "Frame changed: " << frame; }); connect(m_core, &Core::ABMarkersChanged, this, [=] (int secs_a, int secs_b) { QString s; if (secs_a > -1) s = tr("A:%1").arg(Utils::formatTime(secs_a)); if (secs_b > -1) { if (!s.isEmpty()) s += " "; s += tr("B:%1").arg(Utils::formatTime(secs_b)); } qDebug() << "ABMarkersChanged: " << s; }); connect(m_core, SIGNAL(showTime(double, bool)), this, SLOT(gotCurrentTime(double, bool))); connect(m_core, SIGNAL(needResize(int, int)), this, SLOT(resizeMainWindow(int,int))); connect(m_core, SIGNAL(showMessage(QString)), this, SLOT(displayMessage(QString))); connect(m_core, SIGNAL(stateChanged(Core::State)), this, SLOT(displayState(Core::State))); connect(m_core, SIGNAL(stateChanged(Core::State)), this, SLOT(checkStayOnTop(Core::State)), Qt::QueuedConnection); connect(m_core, &Core::mediaStartPlay, this, [=] () { if ((pref->mplayer_detected_version > 0) && (!MplayerVersion::isMplayerAtLeast(25158))) { QTimer::singleShot(1000, this, [=] { if (!pref->reported_mplayer_is_old) { QMessageBox::warning(this, tr("Warning - Using old MPlayer"), tr("The version of MPlayer (%1) installed on your system " "is obsolete. kylin-video can't work well with it: some " "options won't work, subtitle selection may fail...") .arg(MplayerVersion::toString(pref->mplayer_detected_version)) + "

    " + tr("Please, update your MPlayer.") + "

    " + tr("(This warning won't be displayed anymore)") ); pref->reported_mplayer_is_old = true; } }); } }, Qt::QueuedConnection); connect(m_core, SIGNAL(mediaStoppedByUser()), this, SLOT(onMediaStoppedByUser())); connect(m_core, SIGNAL(requestShowLogo(bool)), m_mplayerWindow, SLOT(setLogoVisible(bool))); connect(m_core, SIGNAL(mediaLoaded()), this, SLOT(enableActionsOnPlaying())); connect(m_core, SIGNAL(noFileToPlay()), this, SLOT(gotNoFileToPlay())); connect(m_core, SIGNAL(audioTracksInitialized()), this, SLOT(enableActionsOnPlaying())); connect(m_core, &Core::mediaFinished, this, [=] () { m_lastPlayingSeek = 0; this->disableActionsOnStop(); }); connect(m_core, SIGNAL(stateChanged(Core::State)), this, SLOT(togglePlayAction(Core::State))); connect(m_core, SIGNAL(mediaStartPlay()), this, SLOT(newMediaLoaded()), Qt::QueuedConnection); connect(m_core, SIGNAL(mediaInfoChanged()), this, SLOT(updateMediaInfo())); connect(m_core, &Core::failedToParseMplayerVersion, this, [=] (QString line) { qDebug() << "failedToParseMplayerVersion: " << line; }); connect(m_core, SIGNAL(mplayerFailed(QProcess::ProcessError)), this, SLOT(showErrorFromMplayer(QProcess::ProcessError))); connect(m_core, SIGNAL(mplayerFinishedWithError(int)), this, SLOT(showExitCodeFromMplayer(int))); connect(m_core, SIGNAL(noVideo()), m_mplayerWindow, SLOT(showLogo()));//hideCentralWidget(): connect(m_core, SIGNAL(aboutToStartPlaying()), this, SLOT(clearMplayerLog())); connect(m_core, SIGNAL(logLineAvailable(QString)), this, SLOT(recordMplayerLog(QString))); connect(m_core, SIGNAL(receivedForbidden()), this, SLOT(gotForbidden())); connect(m_core, SIGNAL(bitrateChanged(int,int)), this, SLOT(displayBitrateInfo(int,int))); connect(m_mplayerWindow, SIGNAL(wheelUp()), m_core, SLOT(wheelUp())); connect(m_mplayerWindow, SIGNAL(wheelDown()), m_core, SLOT(wheelDown())); } void MainWindow::createPlaylist() { m_playlistWidget = new Playlist(m_core, this, 0); m_playlistWidget->setFixedSize(220, this->height() - TOP_TOOLBAR_HEIGHT - BOTTOM_TOOLBAR_HEIGHT); m_playlistWidget->setViewHeight(); m_playlistWidget->move(this->width()-220, TOP_TOOLBAR_HEIGHT); m_playlistWidget->hide(); connect(m_playlistWidget, SIGNAL(cleanPlaylistFinished()), this, SLOT(onCleanPlaylistFinished())); connect(m_playlistWidget, SIGNAL(playlistEnded()), this, SLOT(playlistHasFinished())); connect(m_playlistWidget, SIGNAL(playlistEnded()), m_mplayerWindow, SLOT(showLogo())); connect(m_playlistWidget, SIGNAL(closePlaylist()), this, SLOT(onShowOrHidePlaylist())); connect(m_playlistWidget, SIGNAL(playListFinishedWithError(QString)), this, SLOT(showErrorFromPlayList(QString))); connect(m_playlistWidget, SIGNAL(showMessage(QString)), this, SLOT(displayMessage(QString))); } void MainWindow::createTopTitleBar() { m_topToolbar = new TitleWidget(this); m_topToolbar->setFixedHeight(TOP_TOOLBAR_HEIGHT); this->setMenuWidget(m_topToolbar); m_topToolbar->setMouseTracking(true); //m_topToolbar->setAttribute(Qt::WA_X11DoNotAcceptFocus, true); connect(m_topToolbar, SIGNAL(requestShowMenu()), this, SLOT(onShowMenu())); connect(m_topToolbar, SIGNAL(requestMinWindow()), this, SLOT(onMinWindow())); connect(m_topToolbar, SIGNAL(requestCloseWindow()), this, SLOT(onCloseWindow())); connect(m_topToolbar, SIGNAL(requestMaxWindow(bool)), this, SLOT(onMaxWindow(bool))); connect(m_topToolbar, SIGNAL(mouseMovedDiff(QPoint)), this, SLOT(moveWindowDiff(QPoint)), Qt::QueuedConnection ); connect(m_playlistWidget, SIGNAL(requestSetPlayingTitle(QString)), m_topToolbar, SLOT(onSetPlayingTitleName(QString))); } void MainWindow::createBottomToolBar() { m_bottomToolbar = new BottomWidget(this); m_bottomToolbar->setFixedHeight(BOTTOM_TOOLBAR_HEIGHT); m_bottomToolbar->setLayoutDirection(Qt::LeftToRight); connect(m_bottomToolbar, SIGNAL(requestVolumeChanged(int)), m_core, SLOT(setVolume(int))); connect(m_core, SIGNAL(volumeChanged(int)), m_bottomToolbar, SIGNAL(valueChanged(int))); connect(m_bottomToolbar, SIGNAL(toggleFullScreen()), this, SLOT(onFullScreen())); connect(m_bottomToolbar, SIGNAL(togglePlaylist()), this, SLOT(onShowOrHidePlaylist())); connect(m_bottomToolbar, &BottomWidget::toggleStop, this, [=] { m_lastPlayingSeek = (int) m_core->mset.current_sec; m_core->stop(); disconnect(m_mouseFilterHandler, SIGNAL(mouseMoved()), m_bottomController, SLOT(temporaryShow())); m_bottomController->permanentShow(); }); connect(m_bottomToolbar, SIGNAL(togglePrev()), m_playlistWidget, SLOT(playPrev())); connect(m_bottomToolbar, &BottomWidget::togglePlayPause, this, &MainWindow::onPlayPause); connect(m_bottomToolbar, &BottomWidget::requestTemporaryShow, this, [=] { m_bottomController->temporaryShow(); }); connect(m_bottomToolbar, SIGNAL(toggleNext()), m_playlistWidget, SLOT(playNext())); connect(m_bottomToolbar, SIGNAL(toggleMute()), this, SLOT(onMute())); connect(this, SIGNAL(requestActionsEnabled(bool)), m_bottomToolbar, SLOT(onSetActionsEnabled(bool))); connect(this, SIGNAL(requestPlayOrPauseEnabled(bool)), m_bottomToolbar, SLOT(setPlayOrPauseEnabled(bool))); connect(this, SIGNAL(requestUpdatePlaylistBtnQssProperty(bool)), m_bottomToolbar, SLOT(updatePlaylistBtnQssProperty(bool))); connect(m_bottomToolbar, SIGNAL(posChanged(int)), m_core, SLOT(goToPosition(int))); connect(m_bottomToolbar, SIGNAL(delayedDraggingPos(int)), this, SLOT(goToPosOnDragging(int))); connect(m_core, SIGNAL(positionChanged(int)), m_bottomToolbar, SLOT(setPos(int))); connect(m_bottomToolbar, SIGNAL(draggingPos(int)), this, SLOT(displayGotoTime(int))); connect(m_bottomToolbar, SIGNAL(wheelUp()), m_core, SLOT(wheelUp())); connect(m_bottomToolbar, SIGNAL(wheelDown()), m_core, SLOT(wheelDown())); connect(m_bottomToolbar, SIGNAL(mouseMovedDiff(QPoint)), this, SLOT(moveWindowDiff(QPoint)), Qt::QueuedConnection ); connect(m_core, SIGNAL(newDuration(double)), m_bottomToolbar, SLOT(setDuration(double))); connect(m_playlistWidget, &Playlist::update_playlist_count, this, [=] (int count) { m_bottomToolbar->updateLabelCountNumber(count); if (count == 0) { this->setActionsEnabled(false); emit this->requestPlayOrPauseEnabled(false); } else { this->enableActionsOnPlaying(); } }); //connect(m_playlistWidget, SIGNAL(update_playlist_count(int)), m_bottomToolbar, SLOT(updateLabelCountNumber(int))); connect(m_bottomToolbar, SIGNAL(requestSavePreviewImage(int, QPoint)), this, SLOT(onSavePreviewImage(int, QPoint))); connect(m_bottomToolbar, &BottomWidget::requestHideTip, [=] () { }); m_resizeCornerBtn = new QPushButton(m_bottomToolbar); m_resizeCornerBtn->setFocusPolicy(Qt::NoFocus); m_resizeCornerBtn->setStyleSheet("QPushButton{background-image:url(':/res/dragbar_normal.png');border:0px;}QPushButton:hover{background-image:url(':/res/dragbar_normal.png')}QPushButton:pressed{background-image:url(':/res/dragbar_normal.png')}"); m_resizeCornerBtn->setFixedSize(15, 15); m_resizeCornerBtn->setCursor(Qt::SizeFDiagCursor); m_resizeCornerBtn->move(m_bottomToolbar->width()-15, m_bottomToolbar->height()-15); m_resizeCornerBtn->installEventFilter(this); m_resizeCornerBtn->raise(); connect(m_bottomController, &BottomController::requestShow, this, [=] { m_bottomToolbar->show(); m_topToolbar->show(); if (this->isFullScreen()) { this->onShowOrHideEscWidget(true); } }); connect(m_bottomController, &BottomController::requestHide, this, [=] { m_bottomToolbar->hide(); m_topToolbar->hide(); this->onShowOrHideEscWidget(false); }); } void MainWindow::createAudioEqualizer() { // Audio Equalizer audio_equalizer = new AudioEqualizer(this); audio_equalizer->setVisible(false); connect(audio_equalizer->eq[0], SIGNAL(valueChanged(int)), m_core, SLOT(setAudioEq0(int))); connect(audio_equalizer->eq[1], SIGNAL(valueChanged(int)), m_core, SLOT(setAudioEq1(int))); connect(audio_equalizer->eq[2], SIGNAL(valueChanged(int)), m_core, SLOT(setAudioEq2(int))); connect(audio_equalizer->eq[3], SIGNAL(valueChanged(int)), m_core, SLOT(setAudioEq3(int))); connect(audio_equalizer->eq[4], SIGNAL(valueChanged(int)), m_core, SLOT(setAudioEq4(int))); connect(audio_equalizer->eq[5], SIGNAL(valueChanged(int)), m_core, SLOT(setAudioEq5(int))); connect(audio_equalizer->eq[6], SIGNAL(valueChanged(int)), m_core, SLOT(setAudioEq6(int))); connect(audio_equalizer->eq[7], SIGNAL(valueChanged(int)), m_core, SLOT(setAudioEq7(int))); connect(audio_equalizer->eq[8], SIGNAL(valueChanged(int)), m_core, SLOT(setAudioEq8(int))); connect(audio_equalizer->eq[9], SIGNAL(valueChanged(int)), m_core, SLOT(setAudioEq9(int))); connect(audio_equalizer, SIGNAL(applyClicked(AudioEqualizerList)), m_core, SLOT(setAudioAudioEqualizerRestart(AudioEqualizerList))); connect(audio_equalizer, SIGNAL(valuesChanged(AudioEqualizerList)), m_core, SLOT(setAudioEqualizer(AudioEqualizerList))); connect(audio_equalizer, SIGNAL(visibilityChanged()), this, SLOT(updateWidgets())); } void MainWindow::createActionsAndMenus() { if (!m_mainMenu) m_mainMenu = new QMenu(this); else m_mainMenu->clear(); this->createOpenActionsAndMenus(); this->createRecentsActionsAndMenus(); this->createTopActionsAndMenus(); this->createPlayCommandActionsAndMenus(); this->createPlayOrderActionsAndMenus(); this->createVideoAspectActionsAndMenus(); this->createVideoRotateActionsAndMenus(); this->createAudioActionsAndMenus(); this->createScreenshotActionsAndMenus(); this->createSubtitleActionsAndMenus(); this->createOsdActionsAndMenus(); this->createOthersActionsAndMenus(); m_mainMenu->addMenu(openMenu); m_mainMenu->addMenu(recentfiles_menu); m_mainMenu->addMenu(ontop_menu); m_mainMenu->addMenu(playMenu); m_mainMenu->addMenu(play_order_menu); m_mainMenu->addMenu(aspect_menu); m_mainMenu->addMenu(rotate_flip_menu); m_mainMenu->addMenu(audioMenu); m_mainMenu->addMenu(subtitlesMenu); m_mainMenu->addMenu(osd_menu); // m_mainMenu->addAction(shortcutsAct); m_mainMenu->addAction(screenshotAct); m_mainMenu->addAction(showPreferencesAct); m_mainMenu->addAction(showPropertiesAct); m_mainMenu->addAction(aboutAct); if (!m_toolbarMenu) m_toolbarMenu = new QMenu(this); else m_toolbarMenu->clear(); m_toolbarMenu->addAction(openFileAct); m_toolbarMenu->addAction(screenshotAct); m_toolbarMenu->addAction(showPreferencesAct); m_toolbarMenu->addAction(helpAct); m_toolbarMenu->addAction(aboutAct); m_toolbarMenu->addSeparator(); m_toolbarMenu->addAction(quitAct); } void MainWindow::createOpenActionsAndMenus() { openMenu = new QMenu(this); openMenu->menuAction()->setText(tr("Open")); openMenu->setIcon(Images::icon("open_file_normal")); // Menu File openFileAct = new MyAction(QKeySequence("Ctrl+F"), this, "open_file"); connect(openFileAct, SIGNAL(triggered()), this, SLOT(openFile())); openFileAct->change(QPixmap(":/res/open_file_normal.png"), tr("Open &File...")); openDirectoryAct = new MyAction( this, "open_directory"); connect(openDirectoryAct, SIGNAL(triggered()), this, SLOT(openDirectory())); openDirectoryAct->change(/*QPixmap(":/res/openfolder.png"), */tr("Directory...")); openURLAct = new MyAction(QKeySequence("Ctrl+U"), this, "open_url" ); connect(openURLAct, SIGNAL(triggered()), this, SLOT(openURL()) ); openURLAct->change(tr("&URL...")); openMenu->addAction(openFileAct); openMenu->addAction(openDirectoryAct); openMenu->addAction(openURLAct); } void MainWindow::createRecentsActionsAndMenus() { clearRecentsAct = new MyAction(this, "clear_recents"); connect(clearRecentsAct, SIGNAL(triggered()), this, SLOT(clearRecentsList())); clearRecentsAct->change(QPixmap(":/res/delete_normal.png"), tr("&Clear")); recentfiles_menu = new QMenu(this); recentfiles_menu->addSeparator(); recentfiles_menu->addAction(clearRecentsAct); recentfiles_menu->menuAction()->setText(tr("Recent files")); // recentfiles_menu->menuAction()->setIcon(QPixmap(":/res/delete.png")); this->updateRecents(); } void MainWindow::createTopActionsAndMenus() { // On Top : 在FT上有时候设置置顶无效,在X86下正常` onTopActionGroup = new MyActionGroup(this); onTopAlwaysAct = new MyActionGroupItem(this,onTopActionGroup,"on_top_always",Preferences::AlwaysOnTop); onTopNeverAct = new MyActionGroupItem(this,onTopActionGroup,"on_top_never",Preferences::NeverOnTop); onTopWhilePlayingAct = new MyActionGroupItem(this,onTopActionGroup,"on_top_playing",Preferences::WhilePlayingOnTop); onTopAlwaysAct->change(tr("&Always")); onTopNeverAct->change(tr("&Never")); onTopWhilePlayingAct->change(tr("While &playing")); connect(onTopActionGroup, SIGNAL(activated(int)), this, SLOT(changeStayOnTop(int))); // Ontop submenu ontop_menu = new QMenu(this); ontop_menu->menuAction()->setObjectName("ontop_menu"); ontop_menu->addActions(onTopActionGroup->actions()); ontop_menu->menuAction()->setText(tr("S&tay on top")); // ontop_menu->menuAction()->setIcon(Images::icon("ontop")); } void MainWindow::createPlayCommandActionsAndMenus() { playMenu = new QMenu(this); playMenu->menuAction()->setText(tr("Play control")); control_menu = new QMenu(this); control_menu->menuAction()->setText(tr("Forward and rewind"));//快进快退 // control_menu->menuAction()->setIcon(QPixmap(":/res/speed.png")); control_menu->menuAction()->setObjectName("control_menu"); rewind1Act = new MyAction( Qt::Key_Left, this, "rewind1"); rewind1Act->addShortcut(QKeySequence("Shift+Ctrl+B")); // MCE remote key connect(rewind1Act, SIGNAL(triggered()), m_core, SLOT(srewind())); rewind2Act = new MyAction( Qt::Key_Down, this, "rewind2"); connect(rewind2Act, SIGNAL(triggered()), m_core, SLOT(rewind())); rewind3Act = new MyAction( Qt::Key_PageDown, this, "rewind3"); connect(rewind3Act, SIGNAL(triggered()), m_core, SLOT(fastrewind())); forward1Act = new MyAction( Qt::Key_Right, this, "forward1"); forward1Act->addShortcut(QKeySequence("Shift+Ctrl+F")); // MCE remote key connect(forward1Act, SIGNAL(triggered()), m_core, SLOT(sforward())); forward2Act = new MyAction( Qt::Key_Up, this, "forward2"); connect(forward2Act, SIGNAL(triggered()), m_core, SLOT(forward())); forward3Act = new MyAction( Qt::Key_PageUp, this, "forward3" ); connect(forward3Act, SIGNAL(triggered()), m_core, SLOT(fastforward())); // setAMarkerAct = new MyAction( this, "set_a_marker" ); // connect( setAMarkerAct, SIGNAL(triggered()), // m_core, SLOT(setAMarker()) ); // setBMarkerAct = new MyAction( this, "set_b_marker" ); // connect( setBMarkerAct, SIGNAL(triggered()), // m_core, SLOT(setBMarker()) ); // clearABMarkersAct = new MyAction( this, "clear_ab_markers" ); // connect( clearABMarkersAct, SIGNAL(triggered()), // m_core, SLOT(clearABMarkers()) ); // repeatAct = new MyAction( this, "repeat" ); // repeatAct->setCheckable( true ); // connect( repeatAct, SIGNAL(toggled(bool)), // m_core, SLOT(toggleRepeat(bool)) ); gotoAct = new MyAction( QKeySequence("Ctrl+J"), this, "jump_to"); connect(gotoAct, SIGNAL(triggered()), this, SLOT(showGotoDialog())); // gotoAct->change( Images::icon("jumpto"), tr("&Jump to...")); gotoAct->change(tr("&Jump to...")); control_menu->addAction(rewind1Act); control_menu->addAction(forward1Act); control_menu->addSeparator(); control_menu->addAction(rewind2Act); control_menu->addAction(forward2Act); control_menu->addSeparator(); control_menu->addAction(rewind3Act); control_menu->addAction(forward3Act); playMenu->addMenu(control_menu); // Speed submenu speed_menu = new QMenu(this); speed_menu->menuAction()->setText(tr("Play Speed")); // speed_menu->menuAction()->setIcon(QPixmap(":/res/speed.png")); speed_menu->menuAction()->setObjectName("speed_menu"); normalSpeedAct = new MyAction(Qt::Key_Backspace, this, "normal_speed"); connect(normalSpeedAct, SIGNAL(triggered()), m_core, SLOT(normalSpeed())); halveSpeedAct = new MyAction(Qt::Key_BraceLeft, this, "halve_speed"); connect(halveSpeedAct, SIGNAL(triggered()), m_core, SLOT(halveSpeed())); doubleSpeedAct = new MyAction(Qt::Key_BraceRight, this, "double_speed"); connect(doubleSpeedAct, SIGNAL(triggered()), m_core, SLOT(doubleSpeed())); decSpeed10Act = new MyAction(Qt::Key_BracketLeft, this, "dec_speed"); connect(decSpeed10Act, SIGNAL(triggered()), m_core, SLOT(decSpeed10())); incSpeed10Act = new MyAction(Qt::Key_BracketRight, this, "inc_speed"); connect(incSpeed10Act, SIGNAL(triggered()), m_core, SLOT(incSpeed10())); decSpeed4Act = new MyAction(this, "dec_speed_4"); connect(decSpeed4Act, SIGNAL(triggered()), m_core, SLOT(decSpeed4())); incSpeed4Act = new MyAction(this, "inc_speed_4"); connect(incSpeed4Act, SIGNAL(triggered()), m_core, SLOT(incSpeed4())); decSpeed1Act = new MyAction(this, "dec_speed_1"); connect(decSpeed1Act, SIGNAL(triggered()), m_core, SLOT(decSpeed1())); incSpeed1Act = new MyAction(this, "inc_speed_1"); connect(incSpeed1Act, SIGNAL(triggered()), m_core, SLOT(incSpeed1())); normalSpeedAct->change( tr("Normal speed")); halveSpeedAct->change(tr("Half speed") ); doubleSpeedAct->change(tr("Double speed")); decSpeed10Act->change(tr("Speed -10%")); incSpeed10Act->change(tr("Speed +10%")); decSpeed4Act->change(tr("Speed -4%")); incSpeed4Act->change(tr("Speed +4%")); decSpeed1Act->change(tr("Speed -1%")); incSpeed1Act->change(tr("Speed +1%")); speed_menu->addAction(normalSpeedAct);//正常速度 1 speed_menu->addSeparator(); speed_menu->addAction(halveSpeedAct);//半速 0.5 speed_menu->addAction(doubleSpeedAct);//双倍速度 2 speed_menu->addSeparator(); speed_menu->addAction(decSpeed10Act);//速度-10% speed_menu->addAction(incSpeed10Act);//速度+10% speed_menu->addSeparator(); speed_menu->addAction(decSpeed4Act);//速度-4% speed_menu->addAction(incSpeed4Act);//速度+4% speed_menu->addSeparator(); speed_menu->addAction(decSpeed1Act);//速度-1% speed_menu->addAction(incSpeed1Act);//速度+1% playMenu->addMenu(speed_menu); playMenu->addSeparator(); playMenu->addAction(gotoAct); playMenu->addSeparator(); playPrevAct = new MyAction(Qt::Key_Less, this, "play_prev"); playPrevAct->addShortcut(Qt::Key_MediaPrevious); // MCE remote key connect(playPrevAct, SIGNAL(triggered()), m_playlistWidget, SLOT(playPrev())); playNextAct = new MyAction(Qt::Key_Greater, this, "play_next"); playNextAct->addShortcut(Qt::Key_MediaNext); // MCE remote key connect(playNextAct, SIGNAL(triggered()), m_playlistWidget, SLOT(playNext())); playNextAct->change(tr("Next") ); playPrevAct->change(tr("Previous")); playNextAct->setIcon(QPixmap(":/res/next_normal.png")); playPrevAct->setIcon(QPixmap(":/res/previous_normal.png")); playMenu->addAction(playPrevAct); playMenu->addAction(playNextAct); this->setJumpTexts(); } void MainWindow::createPlayOrderActionsAndMenus() { //play order playOrderActionGroup = new MyActionGroup(this); orderPlaysAct = new MyActionGroupItem(this,playOrderActionGroup,"order_play",Preferences::OrderPlay); randomPlayAct = new MyActionGroupItem(this,playOrderActionGroup,"random_play",Preferences::RandomPlay); listLoopPlayAct = new MyActionGroupItem(this,playOrderActionGroup,"list_loop_play",Preferences::ListLoopPlay); orderPlaysAct->change(tr("Order play")); randomPlayAct->change(tr("Random play")); listLoopPlayAct->change(tr("List loop play")); connect(playOrderActionGroup, SIGNAL(activated(int)), this, SLOT(changePlayOrder(int))); play_order_menu = new QMenu(this); play_order_menu->menuAction()->setObjectName("play_order_menu"); play_order_menu->addActions(playOrderActionGroup->actions()); play_order_menu->menuAction()->setText(tr("Play order")); // play_order_menu->menuAction()->setIcon(Images::icon("list_cycle_normal")); } void MainWindow::createVideoAspectActionsAndMenus() { // Video aspect aspectGroup = new MyActionGroup(this); aspectDetectAct = new MyActionGroupItem(this, aspectGroup, "aspect_detect", MediaSettings::AspectAuto); aspect11Act = new MyActionGroupItem(this, aspectGroup, "aspect_1:1", MediaSettings::Aspect11 ); aspect54Act = new MyActionGroupItem(this, aspectGroup, "aspect_5:4", MediaSettings::Aspect54 ); aspect43Act = new MyActionGroupItem(this, aspectGroup, "aspect_4:3", MediaSettings::Aspect43); aspect118Act = new MyActionGroupItem(this, aspectGroup, "aspect_11:8", MediaSettings::Aspect118 ); aspect1410Act = new MyActionGroupItem(this, aspectGroup, "aspect_14:10", MediaSettings::Aspect1410 ); aspect32Act = new MyActionGroupItem(this, aspectGroup, "aspect_3:2", MediaSettings::Aspect32); aspect149Act = new MyActionGroupItem(this, aspectGroup, "aspect_14:9", MediaSettings::Aspect149 ); aspect1610Act = new MyActionGroupItem(this, aspectGroup, "aspect_16:10", MediaSettings::Aspect1610 ); aspect169Act = new MyActionGroupItem(this, aspectGroup, "aspect_16:9", MediaSettings::Aspect169 ); aspect235Act = new MyActionGroupItem(this, aspectGroup, "aspect_2.35:1", MediaSettings::Aspect235); QAction * sep = new QAction(aspectGroup); sep->setSeparator(true); aspectNoneAct = new MyActionGroupItem(this, aspectGroup, "aspect_none", MediaSettings::AspectNone); connect(aspectGroup, SIGNAL(activated(int)), m_core, SLOT(changeAspectRatio(int))); aspectDetectAct->change(tr("&Auto")); aspect11Act->change("1&:1"); aspect32Act->change("&3:2"); aspect43Act->change("&4:3"); aspect118Act->change("11:&8"); aspect54Act->change("&5:4"); aspect149Act->change("&14:9"); aspect1410Act->change("1&4:10"); aspect169Act->change("16:&9"); aspect1610Act->change("1&6:10"); aspect235Act->change("&2.35:1"); aspectNoneAct->change(tr("&Disabled")); // Aspect submenu aspect_menu = new QMenu(this); aspect_menu->menuAction()->setObjectName("aspect_menu"); aspect_menu->addActions(aspectGroup->actions()); aspect_menu->menuAction()->setText(tr("Aspect ratio"));//宽高比 画面比例 } void MainWindow::createVideoRotateActionsAndMenus() { // Rotate rotateGroup = new MyActionGroup(this); rotateNoneAct = new MyActionGroupItem(this, rotateGroup, "rotate_none", MediaSettings::NoRotate); rotateClockwiseFlipAct = new MyActionGroupItem(this, rotateGroup, "rotate_clockwise_flip", MediaSettings::Clockwise_flip); rotateClockwiseAct = new MyActionGroupItem(this, rotateGroup, "rotate_clockwise", MediaSettings::Clockwise); rotateCounterclockwiseAct = new MyActionGroupItem(this, rotateGroup, "rotate_counterclockwise", MediaSettings::Counterclockwise); rotateCounterclockwiseFlipAct = new MyActionGroupItem(this, rotateGroup, "rotate_counterclockwise_flip", MediaSettings::Counterclockwise_flip); connect(rotateGroup, SIGNAL(activated(int)), m_core, SLOT(changeRotate(int))); rotateNoneAct->change(tr("&Off")); rotateClockwiseFlipAct->change(tr("&Rotate by 90 degrees clockwise and flip")); rotateClockwiseAct->change(tr("Rotate by 90 degrees &clockwise")); rotateCounterclockwiseAct->change(tr("Rotate by 90 degrees counterclock&wise")); rotateCounterclockwiseFlipAct->change(tr("Rotate by 90 degrees counterclockwise and &flip")); flipAct = new MyAction(this, "flip"); flipAct->setCheckable(true); connect(flipAct, SIGNAL(toggled(bool)), m_core, SLOT(toggleFlip(bool))); flipAct->change(tr("Fli&p image")); mirrorAct = new MyAction(this, "mirror"); mirrorAct->setCheckable(true); connect(mirrorAct, SIGNAL(toggled(bool)), m_core, SLOT(toggleMirror(bool))); mirrorAct->change(tr("Mirr&or image")); // Rotate menu rotate_flip_menu = new QMenu(this); rotate_flip_menu->menuAction()->setText(tr("Frame rotation"));//画面旋转 // Rotate submenu rotate_menu = new QMenu(this); rotate_menu->menuAction()->setObjectName("rotate_menu"); rotate_menu->addActions(rotateGroup->actions()); rotate_menu->menuAction()->setText(tr("&Rotate") ); rotate_flip_menu->addMenu(rotate_menu); rotate_flip_menu->addAction(flipAct); rotate_flip_menu->addAction(mirrorAct); } void MainWindow::createAudioActionsAndMenus() { // Menu Audio // Audio channels // channelsDefaultAct = new MyActionGroupItem(this, channelsGroup, "channels_default", MediaSettings::ChDefault); channelsGroup = new MyActionGroup(this); channelsStereoAct = new MyActionGroupItem(this, channelsGroup, "channels_stereo", MediaSettings::ChStereo); channelsSurroundAct = new MyActionGroupItem(this, channelsGroup, "channels_surround", MediaSettings::ChSurround); channelsFull51Act = new MyActionGroupItem(this, channelsGroup, "channels_ful51", MediaSettings::ChFull51); channelsFull61Act = new MyActionGroupItem(this, channelsGroup, "channels_ful61", MediaSettings::ChFull61); channelsFull71Act = new MyActionGroupItem(this, channelsGroup, "channels_ful71", MediaSettings::ChFull71); connect(channelsGroup, SIGNAL(activated(int)), m_core, SLOT(setAudioChannels(int))); channelsStereoAct->change(tr("&Stereo")); channelsSurroundAct->change(tr("&4.0 Surround")); channelsFull51Act->change(tr("&5.1 Surround")); channelsFull61Act->change(tr("&6.1 Surround")); channelsFull71Act->change(tr("&7.1 Surround")); // Audio channels submenu audiochannels_menu = new QMenu(this); audiochannels_menu->menuAction()->setObjectName("audiochannels_menu"); audiochannels_menu->addActions(channelsGroup->actions()); audiochannels_menu->menuAction()->setText(tr("&Channels")); audioMenu = new QMenu(this); audioMenu->menuAction()->setText(tr("Audio")); // audioMenuAct->setIcon(Images::icon("audio_menu")); muteAct = new MyAction(Qt::Key_M, this, "mute" );//kobe:音频菜单里面的静音 muteAct->addShortcut(Qt::Key_VolumeMute); // MCE remote key muteAct->setCheckable(true); connect(muteAct, SIGNAL(toggled(bool)), m_core, SLOT(mute(bool))); QIcon icset(Images::icon("volume_low_normal")); icset.addPixmap(Images::icon("volume_mute_normal"), QIcon::Normal, QIcon::On); muteAct->change(icset, tr("&Mute")); // Submenu Filters extrastereoAct = new MyAction(this, "extrastereo_filter"); extrastereoAct->setCheckable(true); connect(extrastereoAct, SIGNAL(toggled(bool)), m_core, SLOT(toggleExtrastereo(bool))); karaokeAct = new MyAction(this, "karaoke_filter"); karaokeAct->setCheckable(true); connect(karaokeAct, SIGNAL(toggled(bool)), m_core, SLOT(toggleKaraoke(bool))); volnormAct = new MyAction(this, "volnorm_filter"); volnormAct->setCheckable(true); connect(volnormAct, SIGNAL(toggled(bool)), m_core, SLOT(toggleVolnorm(bool))); earwaxAct = new MyAction(this, "earwax_filter"); earwaxAct->setCheckable(true); connect(earwaxAct, SIGNAL(toggled(bool)), m_core, SLOT(toggleEarwax(bool))); extrastereoAct->change(tr("&Extrastereo")); karaokeAct->change(tr("&Karaoke")); volnormAct->change(tr("Volume &normalization") ); earwaxAct->change(tr("&Headphone optimization") + " (earwax)"); // Audio filter submenu audiofilter_menu = new QMenu(this); audiofilter_menu->menuAction()->setObjectName("audiofilter_menu"); audiofilter_menu->addAction(extrastereoAct); audiofilter_menu->addAction(karaokeAct); audiofilter_menu->addAction(earwaxAct); audiofilter_menu->addAction(volnormAct); audiofilter_menu->menuAction()->setText(tr("&Filters")); audiofilter_menu->menuAction()->setIcon(Images::icon("audio_filters")); decVolumeAct = new MyAction(Qt::Key_9, this, "dec_volume"); connect(decVolumeAct, SIGNAL(triggered()), m_core, SLOT(decVolume())); decVolumeAct->change(tr("Volume -")); incVolumeAct = new MyAction(Qt::Key_0, this, "inc_volume"); connect(incVolumeAct, SIGNAL(triggered()), m_core, SLOT(incVolume())); incVolumeAct->change(tr("Volume +") ); decAudioDelayAct = new MyAction(Qt::Key_Minus, this, "dec_audio_delay"); connect( decAudioDelayAct, SIGNAL(triggered()), m_core, SLOT(decAudioDelay())); decAudioDelayAct->change(tr("Delay -")); incAudioDelayAct = new MyAction(Qt::Key_Plus, this, "inc_audio_delay"); connect(incAudioDelayAct, SIGNAL(triggered()), m_core, SLOT(incAudioDelay())); incAudioDelayAct->change(tr("Delay +")); audioDelayAct = new MyAction(Qt::Key_Y, this, "audio_delay"); connect(audioDelayAct, SIGNAL(triggered()), this, SLOT(showAudioDelayDialog())); audioDelayAct->change(tr("Set dela&y...")); loadAudioAct = new MyAction( this, "load_audio_file"); connect(loadAudioAct, &MyAction::triggered, this, [=] () { exitFullscreenIfNeeded(); Extensions e; QString s = MyFileDialog::getOpenFileName( this, tr("Choose a file"), pref->latest_dir, tr("Audio") + e.audio().forFilter()+";;" + tr("All files") +" (*.*)" ); if (!s.isEmpty()) m_core->loadAudioFile(s); }); loadAudioAct->change(tr("&Load external file...")); unloadAudioAct = new MyAction(this, "unload_audio_file"); connect(unloadAudioAct, SIGNAL(triggered()), m_core, SLOT(unloadAudioFile())); unloadAudioAct->change(tr("U&nload")); audioEqualizerAct = new MyAction(this, "audio_equalizer"); audioEqualizerAct->setCheckable(true); audioEqualizerAct->change(tr("E&qualizer")); connect(audioEqualizerAct, SIGNAL(toggled(bool)),this, SLOT(showAudioEqualizer(bool))); resetAudioEqualizerAct = new MyAction(this, "reset_audio_equalizer"); connect(resetAudioEqualizerAct, SIGNAL(triggered()), audio_equalizer, SLOT(reset())); resetAudioEqualizerAct->change(tr("Reset audio equalizer")); // Stereo mode stereoGroup = new MyActionGroup(this); stereoAct = new MyActionGroupItem(this, stereoGroup, "stereo", MediaSettings::Stereo); leftChannelAct = new MyActionGroupItem(this, stereoGroup, "left_channel", MediaSettings::Left); rightChannelAct = new MyActionGroupItem(this, stereoGroup, "right_channel", MediaSettings::Right); monoAct = new MyActionGroupItem(this, stereoGroup, "mono", MediaSettings::Mono); reverseAct = new MyActionGroupItem(this, stereoGroup, "reverse_channels", MediaSettings::Reverse); connect(stereoGroup, SIGNAL(activated(int)), m_core, SLOT(setStereoMode(int))); stereoAct->change(tr("&Stereo")); leftChannelAct->change(tr("&Left channel")); rightChannelAct->change(tr("&Right channel")); monoAct->change(tr("&Mono")); reverseAct->change(tr("Re&verse")); // Stereo mode submenu stereomode_menu = new QMenu(this); stereomode_menu->menuAction()->setObjectName("stereomode_menu"); stereomode_menu->addActions(stereoGroup->actions()); stereomode_menu->menuAction()->setText(tr("&Stereo mode")); // stereomode_menu->menuAction()->setIcon(Images::icon("stereo_mode")); audioMenu->addAction(muteAct); audioMenu->addSeparator(); audioMenu->addAction(loadAudioAct); audioMenu->addAction(unloadAudioAct); audioMenu->addSeparator(); audioMenu->addMenu(audiofilter_menu); audioMenu->addAction(audioEqualizerAct); audioMenu->addSeparator(); audioMenu->addMenu(audiochannels_menu); audioMenu->addMenu(stereomode_menu); audioMenu->addSeparator(); audioMenu->addAction(decVolumeAct); audioMenu->addAction(incVolumeAct); audioMenu->addSeparator(); audioMenu->addAction(decAudioDelayAct); audioMenu->addAction(incAudioDelayAct); audioMenu->addSeparator(); audioMenu->addAction(audioDelayAct); } void MainWindow::createScreenshotActionsAndMenus() { // shortcutsAct = new MyAction(QKeySequence("Shift+?"), this, "Shortcuts");//快捷键 Qt::Key_Question //// shortcutsAct->addShortcut(QKeySequence("Shift+Ctrl+?")); // connect(shortcutsAct, SIGNAL(triggered()), this, SLOT(showShortcuts())); // shortcutsAct->change(tr("Shortcuts")); // Single screenshot screenshotAct = new MyAction(Qt::Key_S, this, "screenshot");//屏幕截图 connect(screenshotAct, SIGNAL(triggered()), m_core, SLOT(screenshot())); screenshotAct->change(Images::icon("screenshot_normal"), tr("&Screenshot")); /*screenshotWithSubsAct = new MyAction( QKeySequence("Ctrl+Shift+S"), this, "screenshot_with_subtitles" ); connect( screenshotWithSubsAct, SIGNAL(triggered()), m_core, SLOT(screenshotWithSubtitles()) ); screenshotWithNoSubsAct = new MyAction( QKeySequence("Ctrl+Alt+S"), this, "screenshot_without_subtitles" ); connect( screenshotWithNoSubsAct, SIGNAL(triggered()), m_core, SLOT(screenshotWithoutSubtitles()) ); // Multiple screenshots screenshotsAct = new MyAction( QKeySequence("Shift+D"), this, "multiple_screenshots" ); connect( screenshotsAct, SIGNAL(triggered()), m_core, SLOT(screenshots()) );*/ } void MainWindow::createSubtitleActionsAndMenus() { subtitlesMenu = new QMenu(this); subtitlesMenu->menuAction()->setText( tr("Subtitles") ); // subtitlesMenuAct->setIcon(Images::icon("subtitles_menu")); loadSubsAct = new MyAction(this, "load_subs" ); connect(loadSubsAct, SIGNAL(triggered()), this, SLOT(loadSub())); loadSubsAct->change(tr("Load...")); // subVisibilityAct = new MyAction(Qt::Key_V, this, "subtitle_visibility"); subVisibilityAct = new MyAction(this, "sub_visibility"); subVisibilityAct->setCheckable(true); connect(subVisibilityAct, SIGNAL(toggled(bool)), m_core, SLOT(changeSubVisibility(bool))); subVisibilityAct->change(tr("Subtitle &visibility")); subtitlesMenu->addAction(loadSubsAct); subtitlesMenu->addAction(subVisibilityAct); } void MainWindow::createOsdActionsAndMenus() { showMediaInfoAct = new MyAction(Qt::SHIFT | Qt::Key_I, this, "show_info_osd"); connect( showMediaInfoAct, SIGNAL(triggered()), m_core, SLOT(showMediaInfoOnOSD()) ); showMediaInfoAct->change( tr("Show &info on OSD") ); // showTimeAct = new MyAction(Qt::Key_I, this, "show_time"); // connect( showTimeAct, SIGNAL(triggered()), m_core, SLOT(showTimeOnOSD()) ); // showTimeAct->change( tr("Show playback time on OSD") );//在 OSD 上显示播放时间 // OSD incOSDScaleAct = new MyAction(Qt::SHIFT | Qt::Key_U, this, "inc_osd_scale"); connect(incOSDScaleAct, SIGNAL(triggered()), m_core, SLOT(incOSDScale())); incOSDScaleAct->change(tr("Size &+")); decOSDScaleAct = new MyAction(Qt::SHIFT | Qt::Key_Y, this, "dec_osd_scale"); connect(decOSDScaleAct, SIGNAL(triggered()), m_core, SLOT(decOSDScale())); decOSDScaleAct->change(tr("Size &-")); //#ifdef MPV_SUPPORT OSDFractionsAct = new MyAction(this, "osd_fractions"); OSDFractionsAct->change(tr("Show times with &milliseconds")); OSDFractionsAct->setCheckable(true); connect(OSDFractionsAct, SIGNAL(toggled(bool)), m_core, SLOT(setOSDFractions(bool))); //#endif osdGroup = new MyActionGroup(this); osdNoneAct = new MyActionGroupItem(this, osdGroup, "osd_none", Preferences::NoneOsd); osdSeekAct = new MyActionGroupItem(this, osdGroup, "osd_seek", Preferences::Seek); osdTimerAct = new MyActionGroupItem(this, osdGroup, "osd_timer", Preferences::SeekTimer); osdTotalAct = new MyActionGroupItem(this, osdGroup, "osd_total", Preferences::SeekTimerTotal); connect( osdGroup, SIGNAL(activated(int)), m_core, SLOT(changeOSD(int)) ); // Action groups osdNoneAct->change( tr("Subtitles onl&y") ); osdSeekAct->change( tr("Volume + &Seek") ); osdTimerAct->change( tr("Volume + Seek + &Timer") ); osdTotalAct->change( tr("Volume + Seek + Timer + T&otal time") ); // OSD submenu osd_menu = new QMenu(this); osd_menu->menuAction()->setObjectName("osd_menu"); osd_menu->addActions(osdGroup->actions()); osd_menu->addSeparator(); osd_menu->addAction(showMediaInfoAct); osd_menu->addSeparator(); osd_menu->addAction(decOSDScaleAct); osd_menu->addAction(incOSDScaleAct); osd_menu->addSeparator(); osd_menu->addAction(OSDFractionsAct); // Menu Options osd_menu->menuAction()->setText( tr("&OSD") ); osd_menu->menuAction()->setIcon( Images::icon("osd") ); } void MainWindow::createOthersActionsAndMenus() { showPreferencesAct = new MyAction(QKeySequence("Ctrl+P"), this, "show_preferences"); connect(showPreferencesAct, SIGNAL(triggered()), this, SLOT(showPreferencesDialog())); showPreferencesAct->change(QPixmap(":/res/prefs.png"), tr("Preferences"));//首选项 showPropertiesAct = new MyAction(QKeySequence("Ctrl+I"), this, "show_file_properties"); connect(showPropertiesAct, SIGNAL(triggered()), this, SLOT(showFilePropertiesDialog())); showPropertiesAct->change(QPixmap(":/res/info.png"), tr("View &info and properties..."));//查看信息和属性 helpAct = new MyAction(QKeySequence("Ctrl+H"), this, "show_help" ); connect(helpAct, SIGNAL(triggered()), this, SLOT(showHelpDialog())); helpAct->change(QPixmap(":/res/help_normal.png"), tr("Help")); aboutAct = new MyAction(QKeySequence("Ctrl+A"), this, "about_kylin_video"); connect(aboutAct, SIGNAL(triggered()), this, SLOT(showAboutDialog())); aboutAct->change(Images::icon("about_normal"), tr("About &Kylin Video")); quitAct = new MyAction(QKeySequence("Ctrl+Q"), this, "quit"); quitAct->change(Images::icon("quit_normal"), tr("Quit")); connect(quitAct, SIGNAL(triggered()), this, SLOT(onCloseWindow())); /*m_poweroffAct = new MyAction(this, "poweroff"); m_poweroffAct->change(Images::icon("poweroff"), tr("PowerOff")); connect(m_poweroffAct, SIGNAL(triggered()), this, SLOT(powerOffPC()));*/ //20181120 //showFilenameAct = new MyAction(Qt::SHIFT | Qt::Key_O, this, "show_filename_osd"); //connect( showFilenameAct, SIGNAL(triggered()), m_core, SLOT(showFilenameOnOSD()) ); // showFilenameAct->change( tr("Show filename on OSD") );//在OSD中显示文件名 // The invisible shortcuts: playlist_action, play_pause_aciton, stopAct and fullscreenAct playlist_action = new MyAction(QKeySequence("F3"), this, "playlist_open_close"); playlist_action->change(tr("PlayList")); connect(playlist_action, SIGNAL(triggered()), this, SLOT(onShowOrHidePlaylist())); //这里设置快捷键后,则在keyPressEvent中无法获取到该快捷键的QKeySequence /*play_pause_aciton = new MyAction(Qt::Key_Space, this, "play_pause"); //play_pause_aciton = new MyAction(QKeySequence(Qt::Key_Space), this, "play_pause"); play_pause_aciton->change(tr("Play/Pause")); connect(playlist_action, &MyAction::triggered, this, &MainWindow::onPlayPause);*/ stopAct = new MyAction(Qt::Key_MediaStop, this, "stop"); stopAct->change(tr("Stop")); connect(stopAct, SIGNAL(triggered()), m_core, SLOT(stop())); fullscreenAct = new MyAction(QKeySequence("Ctrl+Return")/*Qt::Key_F*/, this, "fullscreen"); fullscreenAct->change(tr("Fullscreen")); fullscreenAct->setCheckable(true); connect(fullscreenAct, SIGNAL(toggled(bool)), this, SLOT(toggleFullscreen(bool))); } void MainWindow::createTrayActions() { m_mainTray = new QSystemTrayIcon(Images::icon("logo", 22), this); m_mainTray->setToolTip(tr("Kylin Video")); m_mainTray->show(); connect(m_mainTray, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason))); m_mainTray->setIcon(Images::icon("logo", 22)); tray_menu = new QMenu(this); action_show = new MyAction(this, "open_window"); action_show->change(Images::icon("open_window_normal"), tr("Open Homepage")); action_openshotsdir = new MyAction(this, "open_shots_dir"); action_openshotsdir->change(Images::icon("open_screen"), tr("Open screenshots folder")); connect(action_show, SIGNAL(triggered()), this, SLOT(showMainWindow())); connect(action_openshotsdir, &MyAction::toggled, this, [=] () { bool open_enabled = ((!pref->screenshot_directory.isEmpty()) && (QFileInfo(pref->screenshot_directory).isDir())); if (open_enabled) { QDesktopServices::openUrl(QUrl(QString("file:%1").arg(pref->screenshot_directory), QUrl::TolerantMode)); } else { m_mainTray->showMessage(tr("Information"), tr("The screenshot folder does not exist!"), QSystemTrayIcon::Information, 2000);//QSystemTrayIcon::Warning } }); tray_menu->setFixedWidth(250); //添加菜单项 tray_menu->addAction(action_show); tray_menu->addAction(action_openshotsdir); tray_menu->addSeparator(); tray_menu->addAction(aboutAct); tray_menu->addAction(helpAct); tray_menu->addSeparator(); tray_menu->addAction(showPreferencesAct); tray_menu->addAction(quitAct); // tray_menu->addAction(m_poweroffAct); m_mainTray->setContextMenu(tray_menu); } void MainWindow::createTipWidget() { m_tipWidget = new TipWidget("Hello, Kylin!", this); m_tipWidget->setFixedHeight(30); m_tipWidget->move(10, TOP_TOOLBAR_HEIGHT); m_tipWidget->hide(); m_tipTimer = new QTimer(this); connect(m_tipTimer, SIGNAL(timeout()), m_tipWidget, SLOT(hide())); m_tipTimer->setInterval(2000); } void MainWindow::createEscWidget() { m_escWidget = new EscTip(this); m_escWidget->setFixedSize(440, 64); int windowWidth = QApplication::desktop()->screenGeometry(0).width(); int windowHeight = QApplication::desktop()->screenGeometry(0).height(); m_escWidget->move((windowWidth - m_escWidget->width()) / 2,(windowHeight - m_escWidget->height()) / 2); m_escWidget->hide(); } void MainWindow::createMaskWidget() { m_playMaskWidget = new PlayMask(m_mplayerWindow); m_mplayerWindow->setCornerWidget(m_playMaskWidget); m_playMaskWidget->hide(); connect(m_playMaskWidget, &PlayMask::signal_play_continue, this, &MainWindow::onPlayPause); } void MainWindow::changeStayOnTop(int stay_on_top) { switch (stay_on_top) { case Preferences::AlwaysOnTop : setStayOnTop(true); break; case Preferences::NeverOnTop : setStayOnTop(false); break; case Preferences::WhilePlayingOnTop : setStayOnTop((m_core->state() == Core::Playing)); break; } pref->stay_on_top = (Preferences::OnTop) stay_on_top; this->updateOnTopWidgets(); } void MainWindow::checkStayOnTop(Core::State state) { if ((!pref->fullscreen) && (pref->stay_on_top == Preferences::WhilePlayingOnTop)) { setStayOnTop((state == Core::Playing)); } } void MainWindow::changePlayOrder(int play_order) { pref->play_order = (Preferences::PlayOrder) play_order; this->updatePlayOrderWidgets(); if (m_playlistWidget) { m_playlistWidget->updatePlayOrderSettings(); } } void MainWindow::bindThreadWorker(InfoWorker *worker) { connect(m_playlistWidget, SIGNAL(requestGetMediaInfo(QStringList)), worker, SLOT(onGetMediaInfo(QStringList))); connect(worker, SIGNAL(meidaFilesAdded(VideoPtrList,bool)), this, SLOT(onMeidaFilesAdded(VideoPtrList,bool))); } void MainWindow::onMeidaFilesAdded(const VideoPtrList medialist, bool isFileInPlaylist) { if (medialist.length() == 0) { if (!isFileInPlaylist) {//当执行了新加文件操作,而得到的新加文件结果为0时,此时如果isFileInPlaylist为true,表示新增加的文件在播放列表中早已存在,故不再次添加,此时不显示添加失败信息 QString message = QString(tr("Failed to add files!")); this->displayMessage(message); } } else { this->m_playlistWidget->onPlayListChanged(medialist); } } void MainWindow::onPlayPause() { m_topToolbar->show(); m_bottomToolbar->show(); connect(m_mouseFilterHandler, SIGNAL(mouseMoved()), m_bottomController, SLOT(temporaryShow())); // if (m_playlistWidget && m_playlistWidget->count() > 0) { m_core->playOrPause(m_lastPlayingSeek); // } } //void MainWindow::showShortcuts() //{ // m_shortcutsWidget->setPrefData(pref); // m_shortcutsWidget->show(); // m_shortcutsWidget->restart_timer(); //} void MainWindow::keyPressEvent(QKeyEvent *event) { // if (event->key() == Qt::Key_Up) { // } // if (event->key() == Qt::Key_Down) { // } if (event->key() == Qt::Key_Space) { this->leftClickFunction(); } if (event->key() == Qt::Key_Escape) { if (pref->fullscreen) { toggleFullscreen(false); } } // if (event->key() == Qt::Key_Question) { // this->showShortcuts(); // } // QWidget::keyPressEvent(event); QMainWindow::keyPressEvent(event); } void MainWindow::onMediaStoppedByUser() { this->exitFullscreenOnStop(); m_mplayerWindow->showLogo(); this->disableActionsOnStop(); } void MainWindow::onMute() { bool muted = pref->global_volume ? pref->mute : m_core->mset.mute; m_core->mute(!muted); if (muted && pref->volume <= 0) { m_core->setVolume(50, true); } this->updateMuteWidgets(); } void MainWindow::onMaxWindow(bool b) { this->onShowOrHideEscWidget(false); pref->fullscreen = false; m_bottomToolbar->onUnFullScreen();//让全屏/取消全屏的按钮更换图片为全屏 if (!this->isMaximized()) { m_topToolbar->updateMaxButtonStatus(true); this->showMaximized(); } else { m_topToolbar->updateMaxButtonStatus(false); this->showNormal(); } } void MainWindow::onMinWindow() { /*if( windowState() != Qt::WindowMinimized ){ setWindowState( Qt::WindowMinimized ); }*/ this->onShowOrHideEscWidget(false); pref->fullscreen = false; this->showMinimized(); } void MainWindow::onShowMenu() { QPoint p = rect().topRight(); p.setX(p.x() - 38*4); p.setY(p.y() + 36); m_toolbarMenu->exec(this->mapToGlobal(p)); } void MainWindow::onCloseWindow() { if (m_core->state() != Core::Stopped) { m_lastPlayingSeek = 0; m_core->stop(); } m_playlistWidget->close(); qApp->quit(); } void MainWindow::onFullScreen() { if (pref->fullscreen) { toggleFullscreen(false); } else { toggleFullscreen(true); } } void MainWindow::onShowOrHidePlaylist() { setPlaylistVisible(!m_playlistWidget->isVisible()); } void MainWindow::setPlaylistVisible(bool visible) { m_playlistWidget->setProperty("moving", true); int titleBarHeight = TOP_TOOLBAR_HEIGHT; double factor = 0.6; QRect start(this->width(), titleBarHeight, m_playlistWidget->width(), m_playlistWidget->height()); QRect end(this->width() - m_playlistWidget->width(), titleBarHeight, m_playlistWidget->width(), m_playlistWidget->height()); if (!visible) { this->slideEdgeWidget(m_playlistWidget, end, start, ANIMATIONDELAY * factor, true); emit this->requestUpdatePlaylistBtnQssProperty(false); } else { m_playlistWidget->setFocus(); this->slideEdgeWidget(m_playlistWidget, start, end, ANIMATIONDELAY * factor); emit this->requestUpdatePlaylistBtnQssProperty(true); } QTimer::singleShot(ANIMATIONDELAY * factor, this, [=] { m_playlistWidget->setEnabled(true); }); m_topToolbar->raise(); QTimer::singleShot(ANIMATIONDELAY * factor * 1, this, [=] { m_playlistWidget->setProperty("moving", false); }); } void MainWindow::exitFullscreen() { if (pref->fullscreen) { toggleFullscreen(false); } } void MainWindow::exitFullscreenOnStop() { if (pref->fullscreen) { toggleFullscreen(false); } if (m_topToolbar) { m_topToolbar->cleaTitleName(); } } void MainWindow::exitFullscreenIfNeeded() { if (pref->fullscreen) { toggleFullscreen(false); } } void MainWindow::toggleFullscreen(bool b) { if (b == pref->fullscreen) { // Nothing to do qDebug("MainWindow::toggleFullscreen: nothing to do, returning"); return; } pref->fullscreen = b; if (!m_centralWidget->isVisible()) { return; } m_mplayerWindow->hideLogoForTemporary(); if (pref->fullscreen) { if (m_bottomController) m_bottomController->permanentShow(); m_isMaximized = isMaximized(); if (pref->stay_on_top == Preferences::WhilePlayingOnTop && m_core->state() == Core::Playing) { setStayOnTop(false); } showFullScreen(); m_bottomToolbar->onFullScreen();//让全屏/取消全屏的按钮更换图片为取消全屏 this->m_resizeCornerBtn->hide(); m_topToolbar->updateMaxButtonStatus(true); QString state = m_core->stateToString().toUtf8().data(); if (state == "Playing" || state == "Paused") {//全屏的时候如果不是正在播放或暂停,则显示标题栏和控制栏 } this->onShowOrHideEscWidget(true); } else { if (m_bottomController) m_bottomController->permanentShow(); m_topToolbar->updateMaxButtonStatus(false); this->showNormal(); if (m_isMaximized) { m_topToolbar->updateMaxButtonStatus(true); this->showMaximized(); // It has to be called after showNormal() } m_bottomToolbar->onUnFullScreen();//让全屏/取消全屏的按钮更换图片为全屏 this->m_resizeCornerBtn->show(); if (this->m_escWidget->isVisible()) {//For Esc Key:不能用this->onShowOrHideEscWidget(false) this->m_escWidget->hide(); } QString state = m_core->stateToString().toUtf8().data(); if (state == "Playing" || state == "Paused") {// Stopped Playing Paused } } updateWidgets(); setFocus(); QTimer::singleShot(100, m_mplayerWindow, SLOT(updateLogoPosition())); } #ifdef SINGLE_INSTANCE //单实例情况下,麒麟影音正在运行时,此时如果对其他视频文件进行右键选择使用麒麟影音播放,则会走这里打开文件进行播放 void MainWindow::handleMessageFromOtherInstances(const QString& message) { int pos = message.indexOf(' '); if (pos > -1) { QString command = message.left(pos); QString arg = message.mid(pos+1); if (command == "open_file") { this->showMainWindow(); doOpen(arg); } else if (command == "open_files") { QStringList file_list = arg.split(" <> "); this->showMainWindow(); openFiles(file_list); } else if (command == "add_to_playlist") { // QStringList file_list = arg.split(" <> "); /* if (m_core->state() == Core::Stopped) { this->showMainWindow(); } */ // playlist->addFiles(file_list); } else if (command == "media_title") { QStringList list = arg.split(" <> "); m_core->addForcedTitle(list[0], list[1]); } else if (command == "action") { processFunction(arg); } else if (command == "load_sub") { setInitialSubtitle(arg); if (m_core->state() != Core::Stopped) { m_core->loadSub(arg); } } } } #endif void MainWindow::enableActionsOnPlaying() { this->setActionsEnabled(true); // Screenshot option bool screenshots_enabled = ((pref->use_screenshot) && (!pref->screenshot_directory.isEmpty()) && (QFileInfo(pref->screenshot_directory).isDir())); screenshotAct->setEnabled(screenshots_enabled); // Enable or disable the audio equalizer audioEqualizerAct->setEnabled(pref->use_audio_equalizer); // Disable audio actions if there's not audio track // if ((m_core->mdat.audios.numItems()==0) && (m_core->mset.external_audio.isEmpty())) { if ((m_core->mset.audios.numItems()==0) && (m_core->mset.external_audio.isEmpty())) { audioEqualizerAct->setEnabled(false); muteAct->setEnabled(false); decVolumeAct->setEnabled(false); incVolumeAct->setEnabled(false); decAudioDelayAct->setEnabled(false); incAudioDelayAct->setEnabled(false); audioDelayAct->setEnabled(false); extrastereoAct->setEnabled(false); karaokeAct->setEnabled(false); volnormAct->setEnabled(false); earwaxAct->setEnabled(false); channelsGroup->setActionsEnabled(false); stereoGroup->setActionsEnabled(false); } // Disable video actions if it's an audio file if (m_core->mdat.novideo) { screenshotAct->setEnabled(false); flipAct->setEnabled(false); mirrorAct->setEnabled(false); aspectGroup->setActionsEnabled(false); rotateGroup->setActionsEnabled(false); } // if (pref->hwdec.startsWith("vdpau") && pref->mplayer_bin.contains("/usr/bin/mpv")) { // screenshotAct->setEnabled(false); // } // Disable video filters if using vdpau if ((pref->vdpau.disable_video_filters) && (pref->vo.startsWith("vdpau"))) { // screenshotAct->setEnabled(false); flipAct->setEnabled(false); mirrorAct->setEnabled(false); rotateGroup->setActionsEnabled(false); displayMessage(tr("Video filters are disabled when using vdpau"));//使用 VDPAU 时将禁用视频过滤器 } } void MainWindow::disableActionsOnStop() { this->setActionsEnabled(false); emit this->requestPlayOrPauseEnabled(true); // if (m_bottomController) // m_bottomController->permanentShow(); } void MainWindow::togglePlayAction(Core::State state) { if (state == Core::Playing) {//Stopped = 0, Playing = 1, Paused = 2 m_bottomToolbar->onMusicPlayed(); m_playMaskWidget->hide(); } else if (state == Core::Stopped) { m_bottomToolbar->onMusicPause(); m_playMaskWidget->hide(); } else if (state == Core::Paused) { m_bottomToolbar->onMusicPause(); if (m_mplayerWindow) { m_mplayerWindow->hideLogo(); } m_playMaskWidget->show(); } else {//Core::Buffering 缓冲的时候不改变m_playMaskWidget的显示隐藏状态 // do nothing /*m_bottomToolbar->onMusicPause(); if (m_mplayerWindow) { m_mplayerWindow->hideLogo(); }*/ } } void MainWindow::setJumpTexts() { rewind1Act->change(tr("-%1").arg(Utils::timeForJumps(pref->seeking1))); rewind2Act->change(tr("-%1").arg(Utils::timeForJumps(pref->seeking2))); rewind3Act->change(tr("-%1").arg(Utils::timeForJumps(pref->seeking3))); forward1Act->change(tr("+%1").arg(Utils::timeForJumps(pref->seeking1))); forward2Act->change(tr("+%1").arg(Utils::timeForJumps(pref->seeking2))); forward3Act->change(tr("+%1").arg(Utils::timeForJumps(pref->seeking3))); } void MainWindow::createPreferencesDialog() { QApplication::setOverrideCursor(Qt::WaitCursor); m_prefDialog = new PreferencesDialog(m_arch, this->m_snap, this); m_prefDialog->setModal(false); connect(m_prefDialog, SIGNAL(applied()), this, SLOT(applyNewPreferences())); QApplication::restoreOverrideCursor(); } void MainWindow::createFilePropertiesDialog() { QApplication::setOverrideCursor(Qt::WaitCursor); m_propertyDialog = new FilePropertiesDialog(this); m_propertyDialog->setModal(false); connect( m_propertyDialog, SIGNAL(applied()), this, SLOT(applyFileProperties()) ); QApplication::restoreOverrideCursor(); } void MainWindow::setDataToFileProperties() { InfoReader *i = InfoReader::obj(this->m_snap); i->getInfo(); m_propertyDialog->setCodecs(i->vcList(), i->acList(), i->demuxerList()); // Save a copy of the original values if (m_core->mset.original_demuxer.isEmpty()) m_core->mset.original_demuxer = m_core->mdat.demuxer; if (m_core->mset.original_video_codec.isEmpty()) m_core->mset.original_video_codec = m_core->mdat.video_codec; if (m_core->mset.original_audio_codec.isEmpty()) m_core->mset.original_audio_codec = m_core->mdat.audio_codec; QString demuxer = m_core->mset.forced_demuxer; if (demuxer.isEmpty()) demuxer = m_core->mdat.demuxer; QString ac = m_core->mset.forced_audio_codec; if (ac.isEmpty()) ac = m_core->mdat.audio_codec; QString vc = m_core->mset.forced_video_codec; if (vc.isEmpty()) vc = m_core->mdat.video_codec; m_propertyDialog->setDemuxer(demuxer, m_core->mset.original_demuxer); m_propertyDialog->setAudioCodec(ac, m_core->mset.original_audio_codec); m_propertyDialog->setVideoCodec(vc, m_core->mset.original_video_codec); //m_propertyDialog->setMediaData(m_core->mdat); m_propertyDialog->setMediaData(m_core->mdat, m_core->mset.videos, m_core->mset.audios, m_core->mset.subs); } //void MainWindow::createAboutDialog() //{ // QApplication::setOverrideCursor(Qt::WaitCursor); // m_aboutDialog = new AboutDialog(this->m_snap); // m_aboutDialog->setModal(false); // QApplication::restoreOverrideCursor(); //} void MainWindow::createHelpDialog() { QApplication::setOverrideCursor(Qt::WaitCursor); m_helpDialog = new HelpDialog(this); m_helpDialog->setModal(false); QApplication::restoreOverrideCursor(); } void MainWindow::initRemoteControllerConnections() { // connect(m_controllerWorker, SIGNAL(requestSeekForward(int)), m_core, SLOT(forward(int))); // connect(m_controllerWorker, SIGNAL(requestSeekRewind(int)), m_core, SLOT(rewind(int))); // connect(m_controllerWorker, &ControllerWorker::requestPlayPause, this, [=] () { // m_core->playOrPause(m_lastPlayingSeek); // }); // connect(m_controllerWorker, &ControllerWorker::requestStop, m_core, &Core::stop); } void MainWindow::setStayOnTop(bool b) { if ((b && (windowFlags() & Qt::WindowStaysOnTopHint)) || (!b && (!(windowFlags() & Qt::WindowStaysOnTopHint)))) { return; } m_ignoreShowHideEvents = true; bool visible = isVisible(); QPoint old_pos = pos(); if (b) { //TODO:在Mate系列桌面环境上,Qt5编写的程序在启动时设置置顶有效,程序运行过程中动态切换到置顶无效。后续可根据libwnck-dev中x11的接口去实现:./libwnck/window-action-menu.c:wnck_window_make_above (window)------->libwnck/window.c:_wnck_change_state setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); } else { setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint); } move(old_pos); if (visible) { show(); } m_ignoreShowHideEvents = false; } void MainWindow::setActionsEnabled(bool b) { emit this->requestActionsEnabled(b); rewind1Act->setEnabled(b); rewind2Act->setEnabled(b); rewind3Act->setEnabled(b); forward1Act->setEnabled(b); forward2Act->setEnabled(b); forward3Act->setEnabled(b); gotoAct->setEnabled(b); // Menu Speed normalSpeedAct->setEnabled(b); halveSpeedAct->setEnabled(b); doubleSpeedAct->setEnabled(b); decSpeed10Act->setEnabled(b); incSpeed10Act->setEnabled(b); decSpeed4Act->setEnabled(b); incSpeed4Act->setEnabled(b); decSpeed1Act->setEnabled(b); incSpeed1Act->setEnabled(b); screenshotAct->setEnabled(b); showPropertiesAct->setEnabled(b); // Menu Audio audioEqualizerAct->setEnabled(b); muteAct->setEnabled(b); decVolumeAct->setEnabled(b); incVolumeAct->setEnabled(b); decAudioDelayAct->setEnabled(b); incAudioDelayAct->setEnabled(b); audioDelayAct->setEnabled(b); extrastereoAct->setEnabled(b); karaokeAct->setEnabled(b); volnormAct->setEnabled(b); earwaxAct->setEnabled(b); loadAudioAct->setEnabled(b); flipAct->setEnabled(b); mirrorAct->setEnabled(b); // Menu Subtitles loadSubsAct->setEnabled(b); aspectGroup->setActionsEnabled(b); rotateGroup->setActionsEnabled(b); channelsGroup->setActionsEnabled(b); stereoGroup->setActionsEnabled(b); } void MainWindow::updateRecents() { recentfiles_menu->clear(); int cur_items = 0; if (pref->history_recents == NULL) { return; } if (pref->history_recents->count() > 0) { for (int n=0; n < pref->history_recents->count(); n++) { QString i = QString::number( n+1 ); QString fullname = pref->history_recents->item(n); QString filename = fullname; QFileInfo fi(fullname); //if (fi.exists()) filename = fi.fileName(); // Can be slow // Let's see if it looks like a file (no dvd://1 or something) if (fullname.indexOf(QRegExp("^.*://.*")) == -1) filename = fi.fileName(); if (filename.size() > 85) { filename = filename.left(80) + "..."; } QString show_name = filename; QString title = pref->history_recents->title(n); if (!title.isEmpty()) show_name = title; // qDebug() << "kobe recents=" << QString("%1. " + show_name ).arg( i.insert( i.size()-1, '&' ), 3, ' ' ); QAction * a = recentfiles_menu->addAction( QString("%1. " + show_name ).arg( i.insert( i.size()-1, '&' ), 3, ' ' )); a->setStatusTip(fullname); a->setData(n); connect(a, SIGNAL(triggered()), this, SLOT(openRecent())); cur_items++; } } else { QAction * a = recentfiles_menu->addAction( tr("") ); a->setEnabled(false); } recentfiles_menu->menuAction()->setVisible( cur_items > 0 ); if (cur_items > 0) { recentfiles_menu->addSeparator(); recentfiles_menu->addAction( clearRecentsAct ); } } void MainWindow::updateMuteWidgets() { muteAct->setChecked((pref->global_volume ? pref->mute : m_core->mset.mute)); bool muted = pref->global_volume ? pref->mute : m_core->mset.mute; m_bottomToolbar->onMutedChanged(muted, pref->volume); } void MainWindow::updateOnTopWidgets() { // Stay on top onTopActionGroup->setChecked((int)pref->stay_on_top); } void MainWindow::updatePlayOrderWidgets() { playOrderActionGroup->setChecked((int)pref->play_order); } void MainWindow::updateWidgets() { m_centralWidget->setFocus(); this->updateMuteWidgets(); this->updateOnTopWidgets(); m_bottomToolbar->setPreviewData(pref->preview_when_playing); // // Aspect ratio aspectGroup->setChecked(m_core->mset.aspect_ratio_id); // Rotate rotateGroup->setChecked(m_core->mset.rotate); // Flip flipAct->setChecked(m_core->mset.flip); // Mirror mirrorAct->setChecked(m_core->mset.mirror); // Audio menu stereoGroup->setChecked(m_core->mset.stereo_mode); channelsGroup->setChecked(m_core->mset.audio_use_channels); unloadAudioAct->setEnabled(!m_core->mset.external_audio.isEmpty()); // Karaoke menu option karaokeAct->setChecked(m_core->mset.karaoke_filter); // Extrastereo menu option extrastereoAct->setChecked(m_core->mset.extrastereo_filter); // Volnorm menu option volnormAct->setChecked(m_core->mset.volnorm_filter); // Earwax menu option earwaxAct->setChecked(m_core->mset.earwax_filter); // Audio equalizer audioEqualizerAct->setChecked(audio_equalizer->isVisible()); // Subtitle visibility subVisibilityAct->setChecked(pref->sub_visibility); // OSD osdGroup->setChecked(pref->osd); OSDFractionsAct->setChecked(pref->osd_fractions); if (Utils::player(pref->mplayer_bin) == Utils::MPLAYER) { //secondary_subtitles_track_menu->setEnabled(false); //frameBackStepAct->setEnabled(false); OSDFractionsAct->setEnabled(false); earwaxAct->setEnabled(false); } else { //karaokeAct->setEnabled(false); } } void MainWindow::updateAudioEqualizer() { // Audio Equalizer AudioEqualizerList l = pref->global_audio_equalizer ? pref->audio_equalizer : m_core->mset.audio_equalizer; audio_equalizer->blockSignals(true); audio_equalizer->setEqualizer(l); audio_equalizer->blockSignals(false); } void MainWindow::slideEdgeWidget(QWidget *right, QRect start, QRect end, int delay, bool hide) { right->show(); QPropertyAnimation *animation = new QPropertyAnimation(right, "geometry"); animation->setEasingCurve(QEasingCurve::InCurve); animation->setDuration(delay); animation->setStartValue(start); animation->setEndValue(end); animation->start(); connect(animation, SIGNAL(finished()), animation, SLOT(deleteLater())); if (hide) { connect(animation, SIGNAL(finished()), right, SLOT(hide())); } } void MainWindow::hideCentralWidget() { if (m_centralWidget->isVisible()) { if (isMaximized()) { m_topToolbar->updateMaxButtonStatus(false); this->onShowOrHideEscWidget(false); this->showNormal(); } // Exit from fullscreen mode if (pref->fullscreen) { toggleFullscreen(false); update(); } int width = size().width(); if (width > pref->default_size.width()) width = pref->default_size.width(); resize( width, size().height() - m_centralWidget->size().height() ); m_centralWidget->hide(); } } void MainWindow::showAudioEqualizer(bool b) { if (!b) { audio_equalizer->hide(); } else { // Exit fullscreen, otherwise dialog is not visible exitFullscreenIfNeeded(); audio_equalizer->show(); } updateWidgets(); } void MainWindow::showPreferencesDialog() { exitFullscreenIfNeeded(); if (!m_prefDialog) { createPreferencesDialog(); } m_prefDialog->setData(pref); //从最新的配置文件读取快捷键并进行设置 m_prefDialog->mod_shortcut_page()->actions_editor->clear(); m_prefDialog->mod_shortcut_page()->actions_editor->addActions(this); m_prefDialog->move((width() - m_prefDialog->width()) / 2 + mapToGlobal(QPoint(0, 0)).x(), (window()->height() - m_prefDialog->height()) / 2 + mapToGlobal(QPoint(0, 0)).y()); m_prefDialog->show(); } // The user has pressed OK in preferences dialog void MainWindow::applyNewPreferences() { Utils::PlayerId old_player_type = Utils::player(pref->mplayer_bin); m_prefDialog->getData(pref); m_bottomToolbar->setPreviewData(pref->preview_when_playing); m_mplayerWindow->activateMouseDragTracking(true/*pref->move_when_dragging*/); //#ifndef MOUSE_GESTURES // m_mplayerWindow->activateMouseDragTracking(pref->drag_function == Preferences::MoveWindow); //#endif // m_mplayerWindow->delayLeftClick(pref->delay_left_click); setJumpTexts(); // Update texts in menus updateWidgets(); // Update the screenshot action // Restart the video if needed if (m_prefDialog->requiresRestart()) m_core->restart(); // Update actions m_prefDialog->mod_shortcut_page()->actions_editor->applyChanges(); saveActions(); pref->save(); if (old_player_type != Utils::player(pref->mplayer_bin)) { // Hack, simulate a change of GUI to restart the interface // FIXME: try to create a new Core::proc in the future m_lastPlayingSeek = 0; m_core->stop(); if (m_prefDialog && m_prefDialog->isVisible()) {//add by kobe to hide the m_prefDialog m_prefDialog->accept(); } emit requestGuiChanged(); } } void MainWindow::showFilePropertiesDialog() { exitFullscreenIfNeeded(); if (!m_propertyDialog) { createFilePropertiesDialog(); } setDataToFileProperties(); m_propertyDialog->show(); } void MainWindow::applyFileProperties() { bool need_restart = false; #undef TEST_AND_SET #define TEST_AND_SET( Pref, Dialog ) \ if ( Pref != Dialog ) { Pref = Dialog; need_restart = true; } bool demuxer_changed = false; QString prev_demuxer = m_core->mset.forced_demuxer; if (prev_demuxer != m_core->mset.forced_demuxer) { // Demuxer changed demuxer_changed = true; m_core->mset.current_audio_id = MediaSettings::NoneSelected; m_core->mset.current_subtitle_track = MediaSettings::NoneSelected; } // Restart the video to apply if (need_restart) { if (demuxer_changed) { m_core->reload(); } else { m_core->restart(); } } } void MainWindow::updateMediaInfo() { m_mainTray->setToolTip(windowTitle()); this->displayVideoInfo(m_core->mdat.video_width, m_core->mdat.video_height, m_core->mdat.video_fps.toDouble()); } void MainWindow::displayVideoInfo(int width, int height, double fps) { if ((width != 0) && (height != 0)) { // video_info_display->setText(tr("%1x%2 %3 fps", "width + height + fps").arg(width).arg(height).arg(fps)); } else { // video_info_display->setText(" "); } // QString format = m_core->mdat.video_format; // if (!format.isEmpty() && !m_core->mdat.audio_format.isEmpty()) format += " / "; // format += m_core->mdat.audio_format; // format_info_display->setText(format.toUpper()); } void MainWindow::displayBitrateInfo(int vbitrate, int arbitrate) { // bitrate_info_display->setText(tr("V: %1 kbps A: %2 kbps").arg(vbitrate/1000).arg(arbitrate/1000)); } void MainWindow::newMediaLoaded() { QString stream_title = m_core->mdat.stream_title; // qDebug("MainWindow::newMediaLoaded: mdat.stream_title: %s", stream_title.toUtf8().constData()); if (!stream_title.isEmpty()) { pref->history_recents->addItem( m_core->mdat.m_filename, stream_title );//20181201 m_filename //pref->history_recents->list(); } else { pref->history_recents->addItem( m_core->mdat.m_filename ); } updateRecents(); QFileInfo fi(m_core->mdat.m_filename);//20181201 m_filename if (fi.exists()) { QString name = fi.fileName(); m_topToolbar->onSetPlayingTitleName(name); } // Automatically add files to playlist if ((m_core->mdat.type == TYPE_FILE) /*&& (pref->auto_add_to_playlist)*/) { //qDebug("MainWindow::newMediaLoaded: playlist count: %d", playlist->count()); QStringList files_to_add; if (m_playlistWidget->count() == 1) { files_to_add = Utils::filesForPlaylist(m_core->mdat.m_filename, pref->media_to_add_to_playlist);//20181201 m_filename } if (!files_to_add.empty()) m_playlistWidget->addFiles(files_to_add); } } void MainWindow::gotNoFileToPlay() { m_playlistWidget->resumePlay();//当前播放的文件不存在时,去播放下一个 } void MainWindow::clearMplayerLog() { m_mplayerLogMsg.clear(); } void MainWindow::recordMplayerLog(QString line) { if ((line.indexOf("A:") == -1) && (line.indexOf("V:") == -1)) { line.append("\n"); m_mplayerLogMsg.append(line); } } void MainWindow::clearRecentsList() { MessageDialog msgDialog(this, tr("Confirm deletion - Kylin Video"), tr("Delete the list of recent files?")); if (msgDialog.exec() != -1) { if (msgDialog.standardButton(msgDialog.clickedButton()) == QMessageBox::Ok) { // Delete items in menu pref->history_recents->clear(); updateRecents(); } } } void MainWindow::openRecent() { QAction *a = qobject_cast (sender()); if (a) { int item = a->data().toInt(); QString file = pref->history_recents->item(item); if (file.startsWith("file:")) { file = QUrl(file).toLocalFile(); } QFileInfo fi(file); if (fi.exists() && (!fi.isDir())) { file = QFileInfo(file).absoluteFilePath(); m_playlistWidget->addFile(file, Playlist::NoGetInfo); doOpen(file); } else if ((file.toLower().startsWith("http:")) || (file.toLower().startsWith("https:"))) { m_core->openStream(file); } else { this->showErrorFromPlayList(file); } } } void MainWindow::doOpen(QString file) { // If file is a playlist, open that playlist QString extension = QFileInfo(file).suffix().toLower(); if (((extension == "m3u") || (extension== "m3u8")) && (QFile::exists(file))) { //playlist->load_m3u(file); } else if (extension=="pls") { //playlist->load_pls(file); } else if (QFileInfo(file).isDir()) { openDirectory(file); } else { // Let the m_core to open it, autodetecting the file type this->m_playlistWidget->setPlaying(file, 0); m_core->open(file/*, 0*/); } if (QFile::exists(file)) { pref->latest_dir = QFileInfo(file).absolutePath(); } } void MainWindow::openFiles(QStringList files) { if (files.empty()) return; if (files.count() == 1) { m_playlistWidget->addFile(files[0], Playlist::NoGetInfo); doOpen(files[0]); } else { m_playlistWidget->addFiles(files); doOpen(files[0]); } } void MainWindow::openFile() { exitFullscreenIfNeeded(); Extensions e; QString s = MyFileDialog::getOpenFileName( this, tr("Choose a file"), pref->latest_dir, tr("Multimedia") + e.allPlayable().forFilter()+";;" + tr("Video") + e.video().forFilter()+";;" + tr("Audio") + e.audio().forFilter()+";;" + tr("Playlists") + e.playlist().forFilter()+";;" + tr("All files") +" (*.*)" ); if (!s.isEmpty()) { openFile(s); } } void MainWindow::openFile(QString file) { if (!file.isEmpty()) { // If file is a playlist, open that playlist QString extension = QFileInfo(file).suffix().toLower(); if ((extension == "m3u") || (extension == "m3u8")) { //playlist->load_m3u(file); } else if (extension == "pls") { //playlist->load_pls(file); } else if (extension == "iso") { this->m_playlistWidget->setPlaying(file, 0); m_core->open(file/*, 0*/);//每次从头开始播放文件 } else if (QFileInfo(file).isDir()) { openDirectory(file); } else {//打开一个本地视频文件 this->m_playlistWidget->setPlaying(file, 0); m_core->openFile(file);//开始播放新打开的本地视频文件 m_core->open(file/*, 0*/); m_playlistWidget->addFile(file, Playlist::NoGetInfo);//将新打开的本地视频文件加入到播放列表中 } if (QFile::exists(file)) pref->latest_dir = QFileInfo(file).absolutePath(); } } void MainWindow::openDirectory() { QString s = MyFileDialog::getExistingDirectory( this, tr("Choose a directory"), pref->latest_dir ); if (!s.isEmpty()) { openDirectory(s); } } void MainWindow::openDirectory(QString directory) { if (Utils::directoryContainsDVD(directory)) { m_core->open(directory); } else { QFileInfo fi(directory); if ((fi.exists()) && (fi.isDir())) { m_playlistWidget->addDirectory(fi.absoluteFilePath()); m_playlistWidget->startPlayPause(); } else { qDebug("MainWindow::openDirectory: directory is not valid"); } } } void MainWindow::openURL() { exitFullscreenIfNeeded(); InputURL d(this); // Get url from clipboard QString clipboard_text = QApplication::clipboard()->text(); if ((!clipboard_text.isEmpty()) && (clipboard_text.contains("://")) /*&& (QUrl(clipboard_text).isValid())*/) { d.setURL(clipboard_text); } for (int n=0; n < pref->history_urls->count(); n++) { d.setURL(pref->history_urls->url(n) ); } // int w_x = this->frameGeometry().topLeft().x() + (this->width() / 2) - (400 / 2); // int w_y = this->frameGeometry().topLeft().y() + (this->height() /2) - (170 / 2); // d.move(w_x, w_y); if (d.exec() == QDialog::Accepted ) { QString url = d.url(); if (!url.isEmpty()) { pref->history_urls->addUrl(url); m_core->openStream(url); } } } void MainWindow::loadSub() { exitFullscreenIfNeeded(); Extensions e; QString s = MyFileDialog::getOpenFileName( this, tr("Choose a file"), pref->latest_dir, tr("Subtitles") + e.subtitles().forFilter()+ ";;" + tr("All files") +" (*.*)" ); if (!s.isEmpty()) m_core->loadSub(s); } void MainWindow::setInitialSubtitle(const QString & subtitle_file) { m_core->setInitialSubtitle(subtitle_file); } void MainWindow::onSavePreviewImage(int time, QPoint pos) { // QString state = m_core->stateToString().toUtf8().data(); // if (state == "Playing" || state == "Paused") { // } if (m_core) { if (m_core->state() == Core::Playing || m_core->state() == Core::Paused) { if (m_videoPreview == 0) { m_videoPreview = new VideoPreview(pref->mplayer_bin, 0); } if (!m_core->mdat.m_filename.isEmpty()) {//20181201 m_filename m_videoPreview->setVideoFile(m_core->mdat.m_filename); // DVD /*if (m_core->mdat.type==TYPE_DVD) { QString file = m_core->mdat.filename; DiscData disc_data = DiscName::split(file); QString dvd_folder = disc_data.device; if (dvd_folder.isEmpty()) dvd_folder = pref->dvd_device; int dvd_title = disc_data.title; file = disc_data.protocol + "://" + QString::number(dvd_title); m_videoPreview->setVideoFile(file); m_videoPreview->setDVDDevice(dvd_folder); } else { m_videoPreview->setDVDDevice(""); }*/ } m_videoPreview->setMplayerPath(pref->mplayer_bin); bool res = m_videoPreview->createPreThumbnail(time); if (res) { if (m_bottomToolbar) { m_bottomToolbar->savePreviewImageName(time, m_videoPreview->getCurrentPicture()); } } else { if (m_bottomToolbar) { m_bottomToolbar->savePreviewImageName(time, ""); } } } else { if (m_bottomToolbar) { m_bottomToolbar->savePreviewImageName(time, ""); } } } } void MainWindow::showAboutDialog() { // if (!m_aboutDialog) { // createAboutDialog(); // } // m_aboutDialog->setVersions(); // int w_x = this->frameGeometry().topLeft().x() + (this->width() / 2) - (438 / 2); // int w_y = this->frameGeometry().topLeft().y() + (this->height() /2) - (320 / 2); // m_aboutDialog->move(w_x, w_y); // m_aboutDialog->show(); AboutDialog d(this->m_snap, this); //d.setWindowModality(Qt::ApplicationModal); d.setVersions(); d.exec(); } void MainWindow::showHelpDialog() { if (!m_helpDialog) { createHelpDialog(); } m_helpDialog->setData(pref); m_helpDialog->move((width() - m_helpDialog->width()) / 2 + mapToGlobal(QPoint(0, 0)).x(), (window()->height() - m_helpDialog->height()) / 2 + mapToGlobal(QPoint(0, 0)).y()); m_helpDialog->show(); } void MainWindow::showGotoDialog() { TimeDialog d(this); d.setLabel(tr("&Jump to:")); d.setWindowTitle(tr("Kylin Video - Seek")); d.setMaximumTime((int) m_core->mdat.duration); d.setTime((int) m_core->mset.current_sec); // int w_x = this->frameGeometry().topLeft().x() + (this->width() / 2) - (380 / 2); // int w_y = this->frameGeometry().topLeft().y() + (this->height() /2) - (170 / 2); // d.move(w_x, w_y); if (d.exec() == QDialog::Accepted) { m_core->goToSec(d.time()); } } void MainWindow::showAudioDelayDialog() { AudioDelayDialog dlg(this); dlg.setDefaultValue(m_core->mset.audio_delay); // int w_x = this->frameGeometry().topLeft().x() + (this->width() / 2) - (380 / 2); // int w_y = this->frameGeometry().topLeft().y() + (this->height() /2) - (170 / 2); // dlg.move(w_x, w_y); if (dlg.exec() == QDialog::Accepted) { int delay = dlg.getCurrentValue(); m_core->setAudioDelay(delay); } } void MainWindow::showSubDelayDialog() { bool ok; #if QT_VERSION >= 0x050000 int delay = QInputDialog::getInt(this, tr("Kylin Video - Subtitle delay"), tr("Subtitle delay (in milliseconds):"), m_core->mset.sub_delay, -3600000, 3600000, 1, &ok); #else int delay = QInputDialog::getInteger(this, tr("Kylin Video - Subtitle delay"), tr("Subtitle delay (in milliseconds):"), m_core->mset.sub_delay, -3600000, 3600000, 1, &ok); #endif if (ok) { m_core->setSubDelay(delay); } } void MainWindow::leftClickFunction() { if (m_playlistWidget->isVisible()) { setPlaylistVisible(false); } QString state = m_core->stateToString().toUtf8().data(); if (state == "Playing" || state == "Paused") {//Stopped Playing Paused this->onPlayPause(); } // if (!pref->mouse_left_click_function.isEmpty()) { // processFunction(pref->mouse_left_click_function); // } } void MainWindow::rightClickFunction() { showPopupMenu(); // if (!pref->mouse_right_click_function.isEmpty()) { // processFunction(pref->mouse_right_click_function); // } } void MainWindow::doubleClickFunction() { this->onFullScreen(); } void MainWindow::middleClickFunction() { processFunction("mute"); // if (!pref->mouse_middle_click_function.isEmpty()) { // processFunction(pref->mouse_middle_click_function); // } } void MainWindow::xbutton1ClickFunction() { qDebug("MainWindow::xbutton1ClickFunction"); // if (!pref->mouse_xbutton1_click_function.isEmpty()) { // processFunction(pref->mouse_xbutton1_click_function); // } } void MainWindow::xbutton2ClickFunction() { qDebug("MainWindow::xbutton2ClickFunction"); // if (!pref->mouse_xbutton2_click_function.isEmpty()) { // processFunction(pref->mouse_xbutton2_click_function); // } } void MainWindow::processFunction(QString function) { //parse args for checkable actions QRegExp func_rx("(.*) (true|false)"); bool value = false; bool checkableFunction = false; if(func_rx.indexIn(function) > -1){ function = func_rx.cap(1); value = (func_rx.cap(2) == "true"); checkableFunction = true; } //end if //用QAction关联各个事件,比如全屏,创建全屏菜单项的时候设置了objectName为fullscreen, //然后如果双击屏幕,因为代码设置了mouse_double_click_function = "fullscreen",所以在调用processFunction时,传递的是fullscreen, //后续会在ActionsEditor::findAction中寻找是否有fullscreen,如果有,则调用绑定fullscreen的菜单项的槽函数。 QAction * action = ActionsEditor::findAction(this, function); if (!action) action = ActionsEditor::findAction(m_playlistWidget, function); if (action) { qDebug("MainWindow::processFunction: action found"); if (!action->isEnabled()) { qDebug("MainWindow::processFunction: action is disabled, doing nothing"); return; } if (action->isCheckable()){ if(checkableFunction) action->setChecked(value); else //action->toggle(); action->trigger(); }else{ action->trigger(); } } else { qDebug("MainWindow::processFunction: action not found"); } } void MainWindow::gotForbidden() { static bool busy = false; if (busy) return; busy = true; QMessageBox::warning(this, tr("Error detected"), tr("Unfortunately this video can't be played.") +"
    "+ tr("The server returned '%1'").arg("403: Forbidden")); busy = false; } void MainWindow::dragEnterEvent(QDragEnterEvent *event) { if (event->mimeData()->hasUrls()) { event->acceptProposedAction(); } /*if (event->mimeData()->hasFormat("text/uri-list")) { event->setDropAction(Qt::CopyAction); event->acceptProposedAction(); return; } QMainWindow::dragEnterEvent(event);*/ } void MainWindow::dropEvent(QDropEvent *e) { QStringList files; if (e->mimeData()->hasUrls()) { QList l = e->mimeData()->urls(); QString s; for (int n=0; n < l.count(); n++) { if (l[n].isValid()) { qDebug("MainWindow::dropEvent: scheme: '%s'", l[n].scheme().toUtf8().data()); if (l[n].scheme() == "file") s = l[n].toLocalFile(); else s = l[n].toString(); /* qDebug(" * '%s'", l[n].toString().toUtf8().data()); qDebug(" * '%s'", l[n].toLocalFile().toUtf8().data()); */ //qDebug("MainWindow::dropEvent: file: '%s'", s.toUtf8().data()); if (pref->m_videoMap.contains(s)) { continue; } files.append(s); } } } QStringList file_list; QStringList dir_list; QString sub_file; if (files.count() > 0) { files.sort(); Extensions ext; QRegExp ext_sub(ext.subtitles().forRegExp()); ext_sub.setCaseSensitivity(Qt::CaseInsensitive); foreach (QString file, files) { QFileInfo fi(file); if (fi.isDir()) { // Folder dir_list << file; } else if (ext_sub.indexIn(fi.suffix()) > -1) { // Subtitle file if (sub_file.isEmpty()) sub_file = file; } else { // File (or something else) file_list << file; } } /* If only one file is dropped and it's not a folder nor a subtitle, open it with openFile so that it remembers the position */ if (dir_list.isEmpty() && sub_file.isEmpty() && file_list.count() == 1 && QFile::exists(file_list[0])) { openFile(file_list[0]); return; } if (!sub_file.isEmpty()) { m_core->loadSub(sub_file); return; } if (file_list.isEmpty() && dir_list.isEmpty()) { return; } if (dir_list.count() == 1 && file_list.isEmpty()) { openDirectory(dir_list[0]); return; } if (pref->auto_add_to_playlist) {//true if (!dir_list.isEmpty()) { // Add directories to the playlist foreach(QString dir, dir_list) m_playlistWidget->addDirectory(dir); } if (!file_list.isEmpty()) { // Add files to the playlist m_playlistWidget->addFiles(files); } // All files are in the playlist, let's start to play m_playlistWidget->startPlayPause(); } else { // It wasn't possible to add files to the list // Let's open the first directory or file if (!dir_list.isEmpty()) openDirectory(dir_list[0]); // Bug? This actually modifies the playlist... else if (!file_list.isEmpty()) doOpen(file_list[0]); } } // if (files.count() == 1) { // QFileInfo fi( files[0] ); // Extensions e; // QRegExp ext_sub(e.subtitles().forRegExp()); // ext_sub.setCaseSensitivity(Qt::CaseInsensitive); // if (ext_sub.indexIn(fi.suffix()) > -1) { // qDebug( "MainWindow::dropEvent: loading sub: '%s'", files[0].toUtf8().data()); // m_core->loadSub( files[0] ); // } // else // if (fi.isDir()) { // openDirectory( files[0] ); // } else { // m_playlistWidget->addFile(files[0], Playlist::NoGetInfo);//20170712 // doOpen(files[0]); // } // } else { // // More than one file // qDebug("MainWindow::dropEvent: adding files to playlist"); //// m_playlistWidget->clear(); // m_playlistWidget->addFiles(files); // //openFile( files[0] ); // m_playlistWidget->startPlayPause(); // } // } } void MainWindow::showPopupMenu() { showPopupMenu(QCursor::pos()); } void MainWindow::showPopupMenu(QPoint p) { m_mainMenu->move(p); m_mainMenu->show(); } void MainWindow::playlistHasFinished() { m_lastPlayingSeek = 0; m_core->stop(); this->disableActionsOnStop(); exitFullscreenOnStop(); } void MainWindow::onCleanPlaylistFinished() { //if (m_core->state() != Core::Stopped) { m_lastPlayingSeek = 0; m_core->stop(); this->disableActionsOnStop(); //} exitFullscreenOnStop(); } void MainWindow::powerOffPC() { PoweroffDialog d(this); if (d.exec() == QDialog::Accepted) { Utils::shutdown(); } } void MainWindow::displayState(Core::State state) { switch (state) { case Core::Playing://播放时开启自动隐藏标题栏和控制栏的定时器 break; case Core::Paused://暂停时显示标题栏和控制栏 if (m_bottomController) m_bottomController->permanentShow(); break; case Core::Stopped: if (m_bottomController) m_bottomController->permanentShow(); m_topToolbar->onSetPlayingTitleName(""); break; } } void MainWindow::displayMessage(QString message) { this->showTipWidget(message); } void MainWindow::gotCurrentTime(double sec, bool flag) { //qDebug( "DefaultGui::displayTime: %f", sec); QString time; QString all_time; if (flag) { time = "00:00:00"; all_time = " / 00:00:00"; } else { static int last_second = 0; // if (floor(sec)==last_second) return; // Update only once per second // last_second = (int) floor(sec); if (qFloor(sec) == last_second) return; // Update only once per second last_second = qFloor(sec); // time = Utils::formatTime( (int) sec ) + " / " + Utils::formatTime( (int) m_core->mdat.duration ); time = Utils::formatTime((int) sec); all_time = " / " + Utils::formatTime((int) m_core->mdat.duration); //qDebug( " duration: %f, current_sec: %f", m_core->mdat.duration, m_core->mset.current_sec); } if (m_bottomToolbar) { m_bottomToolbar->displayTime(time, all_time); } } void MainWindow::resizeMainWindow(int w, int h) { // If fullscreen, don't resize! if (pref->fullscreen) return; if ((pref->resize_method==Preferences::Never) && (m_centralWidget->isVisible()) ) { return; } if (!m_centralWidget->isVisible()) { m_centralWidget->show(); } QSize video_size(w,h); if (video_size == m_centralWidget->size()) { qDebug("MainWindow::resizeMainWindow: the m_centralWidget size is already the required size. Doing nothing."); return; } int diff_width = this->width() - m_centralWidget->width(); int diff_height = this->height() - m_centralWidget->height(); int new_width = w + diff_width; int new_height = h + diff_height; int minimum_width = minimumSizeHint().width(); if (new_width < minimum_width) { qDebug("MainWindow::resizeMainWindow: width is too small, setting width to %d", minimum_width); new_width = minimum_width; } resize(new_width, new_height); } void MainWindow::displayGotoTime(int t) { int jump_time = (int)m_core->mdat.duration * t / SEEKBAR_RESOLUTION; QString s = tr("Jump to %1").arg(Utils::formatTime(jump_time)); if (pref->fullscreen) { m_core->displayTextOnOSD( s ); } } void MainWindow::goToPosOnDragging(int t) { // m_core->goToPosition(t);//m_core->goToPos(t); } void MainWindow::loadActions() { ActionsEditor::loadFromConfig(this, settings); // actions_list = ActionsEditor::actionsNames(this); } void MainWindow::saveActions() { ActionsEditor::saveToConfig(this, settings); } void MainWindow::moveWindow() { // Display *display = QX11Info::display(); // Atom netMoveResize = XInternAtom(display, "_NET_WM_MOVERESIZE", False); // XEvent xEvent; // const auto pos = QCursor::pos(); // memset(&xEvent, 0, sizeof(XEvent)); // xEvent.xclient.type = ClientMessage; // xEvent.xclient.message_type = netMoveResize; // xEvent.xclient.display = display; // xEvent.xclient.window = this->winId(); // xEvent.xclient.format = 32; // xEvent.xclient.data.l[0] = pos.x(); // xEvent.xclient.data.l[1] = pos.y(); // xEvent.xclient.data.l[2] = 8; // xEvent.xclient.data.l[3] = Button1; // xEvent.xclient.data.l[4] = 0; // XUngrabPointer(display, CurrentTime); // XSendEvent(display, QX11Info::appRootWindow(QX11Info::appScreen()), // False, SubstructureNotifyMask | SubstructureRedirectMask, // &xEvent); // XFlush(display); } void MainWindow::moveWindowDiff(QPoint diff) { if (pref->fullscreen || isMaximized()) { return; } #if QT_VERSION >= 0x050000 // Move the window with some delay. // Seems to work better with Qt 5 static QPoint d; static int count = 0; d += diff; count++; if (count > 3) { QPoint new_pos = pos() + d; if (new_pos.y() < 0) new_pos.setY(0); if (new_pos.x() < 0) new_pos.setX(0); move(new_pos); count = 0; d = QPoint(0,0); //TODO:将会导致标题栏和播放控制栏失去焦点 /*Display *display = QX11Info::display(); Atom netMoveResize = XInternAtom(display, "_NET_WM_MOVERESIZE", False); XEvent xEvent; const auto pos = QCursor::pos(); memset(&xEvent, 0, sizeof(XEvent)); xEvent.xclient.type = ClientMessage; xEvent.xclient.message_type = netMoveResize; xEvent.xclient.display = display; xEvent.xclient.window = this->winId(); xEvent.xclient.format = 32; xEvent.xclient.data.l[0] = pos.x(); xEvent.xclient.data.l[1] = pos.y(); xEvent.xclient.data.l[2] = 8; xEvent.xclient.data.l[3] = Button1; xEvent.xclient.data.l[4] = 0; XUngrabPointer(display, CurrentTime); XSendEvent(display, QX11Info::appRootWindow(QX11Info::appScreen()), False, SubstructureNotifyMask | SubstructureRedirectMask, &xEvent); XFlush(display); count = 0; d = QPoint(0,0);*/ } #else move(pos() + diff); #endif } #if QT_VERSION < 0x050000 void MainWindow::showEvent( QShowEvent * ) { qDebug("MainWindow::showEvent"); if (m_ignoreShowHideEvents) return; //qDebug("MainWindow::showEvent: pref->pause_when_hidden: %d", pref->pause_when_hidden); if ((pref->pause_when_hidden) && (m_core->state() == Core::Paused)) { qDebug("MainWindow::showEvent: unpausing"); m_core->pause(); // Unpauses } } void MainWindow::hideEvent( QHideEvent * ) { qDebug("MainWindow::hideEvent"); if (m_ignoreShowHideEvents) return; //qDebug("MainWindow::hideEvent: pref->pause_when_hidden: %d", pref->pause_when_hidden); if ((pref->pause_when_hidden) && (m_core->state() == Core::Playing)) { qDebug("MainWindow::hideEvent: pausing"); m_core->pause(); } } #else // Qt 5 doesn't call showEvent / hideEvent when the window is minimized or unminimized bool MainWindow::event(QEvent * e) { bool result = QWidget::event(e); if ((m_ignoreShowHideEvents) || (!pref->pause_when_hidden)) { return result; } if (e->type() == QEvent::WindowStateChange) {//窗口的状态(最小化、最大化或全屏)发生改变(QWindowStateChangeEvent) if (isMinimized()) { was_minimized = true; if (m_core->state() == Core::Playing) { m_core->pause(); } } else if (isMaximized()) { this->m_isMaximized = true; } } if ((e->type() == QEvent::ActivationChange) && (isActiveWindow())) {//Widget 的顶层窗口激活状态发生了变化 m_isMaximized = isMaximized(); if ((!isMinimized()) && (was_minimized)) { was_minimized = false; if (this->m_isMaximized) { m_topToolbar->updateMaxButtonStatus(true); } else { m_topToolbar->updateMaxButtonStatus(false); } if (m_core->state() == Core::Paused) { qDebug("MainWindow::showEvent: unpausing"); m_core->pause(); // Unpauses } } } return result; } #endif void MainWindow::trayIconActivated(QSystemTrayIcon::ActivationReason reason) { switch(reason) { case QSystemTrayIcon::Trigger: toggleShowOrHideMainWindow(); break; case QSystemTrayIcon::DoubleClick: toggleShowOrHideMainWindow(); break; case QSystemTrayIcon::MiddleClick: m_core->pause(); break; default: break; } } void MainWindow::toggleShowOrHideMainWindow() { if (m_mainTray->isVisible()) { if (this->isVisible()) { m_windowPos = pos(); this->hide(); } else { this->move(m_windowPos); this->show(); } } } void MainWindow::showMainWindow() { if (!this->isVisible()) { this->move(m_windowPos); this->show(); } } void MainWindow::showErrorFromPlayList(QString errorStr) { ErrorDialog d(this); d.setWindowTitle(tr("%1 Error").arg(PLAYER_NAME)); d.setTitleText(tr("%1 Error").arg(PLAYER_NAME)); d.setText(tr("'%1' was not found!").arg(errorStr)); d.hideDetailBtn(); d.exec(); } void MainWindow::showExitCodeFromMplayer(int exit_code) { if (exit_code != 255 ) { ErrorDialog d(this); d.setWindowTitle(tr("%1 Error").arg(PLAYER_NAME)); d.setTitleText(tr("%1 Error").arg(PLAYER_NAME)); d.setText(tr("%1 has finished unexpectedly.").arg(PLAYER_NAME) + " " + tr("Exit code: %1").arg(exit_code)); d.setLog(m_mplayerLogMsg); d.exec(); } this->clearMplayerLog(); } void MainWindow::showErrorFromMplayer(QProcess::ProcessError e) { if ((e == QProcess::FailedToStart) || (e == QProcess::Crashed)) { ErrorDialog d(this); d.setWindowTitle(tr("%1 Error").arg(PLAYER_NAME)); d.setTitleText(tr("%1 Error").arg(PLAYER_NAME)); if (e == QProcess::FailedToStart) { d.setText(tr("%1 failed to start.").arg(PLAYER_NAME) + " " + tr("Please check the %1 path in preferences.").arg(PLAYER_NAME)); } else { d.setText(tr("%1 has crashed.").arg(PLAYER_NAME) + " " + tr("See the log for more info.")); } d.setLog(m_mplayerLogMsg); d.exec(); } this->clearMplayerLog(); } void MainWindow::showTipWidget(const QString text) { //注意:这里不能将m_tipWidget先hide,然后再show,这样会导致按快捷键时视频刷>新会闪烁以下,如按快进键 this->m_tipWidget->setText(text); this->m_tipWidget->show(); if (m_tipTimer->isActive()) m_tipTimer->stop(); m_tipTimer->start(); } void MainWindow::onShowOrHideEscWidget(bool b) { if (m_escWidget) { if (b) { if (!m_escWidget->isVisible() && this->isFullScreen()) { this->m_escWidget->show(); QTimer::singleShot(5000, this, [=] { this->m_escWidget->hide(); }); m_maskWidget->showMask(); } } else { if (m_escWidget->isVisible() && this->isFullScreen()) { this->m_escWidget->hide(); m_maskWidget->hide(); } } } } bool MainWindow::eventFilter(QObject *obj, QEvent *event) { if (obj == this->m_resizeCornerBtn) { if (!this->isMaximized()) { if (event->type() == QEvent::MouseButtonPress) { this->m_resizeFlag = true; } else if (event->type() == QEvent::MouseButtonRelease) { this->m_resizeFlag = false; } } } /*else { if (event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast(event); if (keyEvent->key() == Qt::Key_Space) { this->leftClickFunction(); } } return false; }*/ return qApp->eventFilter(obj, event); } void MainWindow::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) m_dragWindow = true; } void MainWindow::mouseReleaseEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) m_dragWindow = false; } void MainWindow::mouseMoveEvent(QMouseEvent *event) { QMainWindow::mouseMoveEvent(event); if (this->isMaximized()) { return; } if (event->buttons() == Qt::LeftButton) { if (m_dragWindow) { moveWindow(); } if (this->m_resizeFlag) { int targetWidth = event->globalX() - this->frameGeometry().topLeft().x(); int targetHeight = event->globalY() - this->frameGeometry().topLeft().y(); if(targetWidth < WINDOW_MIN_WIDTH) { if(targetHeight < WINDOW_MIN_HEIGHT) resize(WINDOW_MIN_WIDTH, WINDOW_MIN_HEIGHT); else resize(WINDOW_MIN_WIDTH, targetHeight); } else { if(targetHeight < WINDOW_MIN_HEIGHT) { resize(targetWidth, WINDOW_MIN_HEIGHT); } else { resize(targetWidth, targetHeight); } } event->accept(); } } } void MainWindow::resizeEvent(QResizeEvent *e) { QMainWindow::resizeEvent(e); QSize newSize = QMainWindow::size(); int titleBarHeight = this->m_topToolbar->height(); this->m_topToolbar->raise(); this->m_topToolbar->move(0, 0); this->m_topToolbar->resize(newSize.width(), titleBarHeight); this->m_mplayerWindow->resize(newSize); this->m_playlistWidget->setFixedSize(220, newSize.height() - BOTTOM_TOOLBAR_HEIGHT - titleBarHeight); this->m_playlistWidget->setViewHeight(); if (this->m_playlistWidget->isVisible()) { this->m_playlistWidget->hide(); emit this->requestUpdatePlaylistBtnQssProperty(false); } this->m_bottomToolbar->raise(); this->m_bottomToolbar->resize(newSize.width(), BOTTOM_TOOLBAR_HEIGHT); this->m_bottomToolbar->move(0, newSize.height() - BOTTOM_TOOLBAR_HEIGHT); this->m_bottomToolbar->onShowControlWidget(); m_resizeCornerBtn->move(this->m_bottomToolbar->width()- 15, this->m_bottomToolbar->height() - 15); } void MainWindow::closeEvent(QCloseEvent * e) { this->onCloseWindow(); e->accept(); } //void MainWindow::paintEvent(QPaintEvent *) //{ // QPainter painter(this); // painter.drawPixmap(rect(), currentBackground); ////QPalette palette; ////palette.setBrush(QPalette::Background, image); ////setPalette(palette); //} void MainWindow::setBackgroudPixmap(QString pixmapDir) { try { if (!pixmapDir.isEmpty()) { currentBackground = QPixmap(pixmapDir); this->update(); } } catch (QString e) { } } kylin-video/src/playlistdelegate.cpp0000644000175000017500000002305013524205650016561 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "playlistdelegate.h" #include "playlistview.h" #include "playlistmodel.h" #include "utils.h" #include "../smplayer/preferences.h" #include "../smplayer/global.h" using namespace Global; #include #include #include static inline QFlags cellAlignmentFlag(int column) { PlaylistDelegate::PlayListColumn p_column = static_cast(column); switch (p_column) { case PlaylistDelegate::Icon: return (Qt::AlignLeft | Qt::AlignVCenter); case PlaylistDelegate::Name: return (Qt::AlignLeft | Qt::AlignVCenter); case PlaylistDelegate::Length: return (Qt::AlignRight | Qt::AlignVCenter); case PlaylistDelegate::Invalid: break; } return (Qt::AlignLeft | Qt::AlignVCenter); } static inline QRect cellRect(int column, const QStyleOptionViewItem &option) { const int leftRightMargin = 15; QFont font(option.font); QFontMetrics fm(font); static int iconWidth = 20; static int timeWidth = fm.width("00:00:00") + leftRightMargin; static int delWidth = 20; int w = option.rect.width() - timeWidth - delWidth - leftRightMargin - iconWidth; PlaylistDelegate::PlayListColumn p_column = static_cast(column); switch (p_column) { case PlaylistDelegate::Icon: return QRect(leftRightMargin, option.rect.y(), iconWidth, option.rect.height()); case PlaylistDelegate::Name: return QRect(leftRightMargin + iconWidth, option.rect.y(), w - 2, option.rect.height()); case PlaylistDelegate::Length: return QRect(leftRightMargin + iconWidth + w, option.rect.y(), timeWidth - leftRightMargin, option.rect.height()); case PlaylistDelegate::Invalid: break; } return option.rect.marginsRemoved(QMargins(0, 0, 0, 0)); } PlaylistDelegate::PlaylistDelegate(QWidget *parent) : QStyledItemDelegate(parent) { m_background = QColor("#2e2e2e"); m_normalTextColor = QColor("#ffffff"); m_activeTextColor = QColor("#009aff"); m_hoverTextColor = QColor("#0da4f6"); m_timeColor = QColor("#ffffff"); } PlaylistDelegate::~PlaylistDelegate() { } QColor PlaylistDelegate::foregroundColor(int column, const QStyleOptionViewItem &option) const { if (option.state & QStyle::State_Selected) { return m_hoverTextColor; } PlaylistDelegate::PlayListColumn p_column = static_cast(column); switch (p_column) { case PlaylistDelegate::Icon: break; case PlaylistDelegate::Name: return m_normalTextColor; case PlaylistDelegate::Length: return m_timeColor; case PlaylistDelegate::Invalid: break; } return m_normalTextColor; } void PlaylistDelegate::setItemHover(const QModelIndex &index) { // m_hoverIndex = index; } void PlaylistDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { if (!index.isValid()) { return; } painter->save(); QFont m_font = option.font; m_font.setPixelSize(11); painter->setRenderHint(QPainter::Antialiasing); painter->setRenderHint(QPainter::HighQualityAntialiasing); QColor background = m_background; // if (option.state & QStyle::State_Selected) { // } // else if (option.state & QStyle::State_HasFocus) { // } if(option.state.testFlag(QStyle::State_Selected)) {//选中状态 QRect mRect = option.rect; QPoint start_point(mRect.topLeft()); QPoint end_point(mRect.topRight()); QLinearGradient gradient(start_point, end_point); gradient.setColorAt(0, QColor("#0da4f5")); gradient.setColorAt(0.015, QColor("#2aa6f8")); gradient.setColorAt(0.0155, QColor("rgba(42, 166, 248, 20%)")); gradient.setColorAt(1, QColor("rgba(42, 166, 248, 20%)")); painter->fillRect(mRect, QBrush(gradient)); // painter->setCompositionMode(QPainter::CompositionMode_SourceIn); } else if(option.state.testFlag(QStyle::State_MouseOver)) {//鼠标划过状态 background = QColor("rgba(42, 166, 248, 20%)");//QColor("#242424");//2aa6f8 painter->fillRect(option.rect, background); } else { painter->fillRect(option.rect, background); } /*if (m_hoverIndex == index) { // draw hover background QRect mRect = option.rect; QPoint start_point(mRect.topLeft()); QPoint end_point(mRect.topRight()); QLinearGradient gradient(start_point, end_point); gradient.setColorAt(0, QColor("#0da4f5")); gradient.setColorAt(0.015, QColor("#2aa6f8")); gradient.setColorAt(0.0155, QColor("rgba(42, 166, 248, 20%)")); gradient.setColorAt(1, QColor("rgba(42, 166, 248, 20%)")); painter->fillRect(mRect, QBrush(gradient)); painter->setCompositionMode(QPainter::CompositionMode_SourceIn); }*/ QString filepath = index.data().toString();//TODO: kobe for data(filepath) auto video = pref->video(filepath); if (video.isNull()) { painter->restore(); return; } for (int column = 0; column < Invalid; ++column) { auto textColor = this->foregroundColor(column, option); auto flag = cellAlignmentFlag(column); auto rect = cellRect(column, option); painter->setPen(textColor); switch (column) { case Icon: { auto listview = qobject_cast(const_cast(option.widget)); QString playingFile = listview->getPlayingFile(); if (playingFile == video->m_localpath) { QString iconPath = ":/res/video_normal.png"; if (option.state & QStyle::State_Selected) { iconPath = ":/res/video_hover_press.png"; } QPixmap icon = QPixmap(iconPath); auto centerF = QRectF(rect).center(); auto iconRect = QRectF(centerF.x() - icon.width() / 2, centerF.y() - icon.height() / 2, icon.width(), icon.height()); painter->drawPixmap(iconRect.toRect(), icon); } break; } case Name: { painter->setFont(m_font); QFontMetrics fm(m_font); QString text = fm.elidedText(video->m_name, Qt::ElideMiddle, rect.width()); painter->drawText(rect, flag, text); break; } case Length: painter->setFont(m_font); painter->drawText(rect, flag, Utils::formatTime((int)video->m_duration)); break; default: break; } } painter->restore(); } QSize PlaylistDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { QSize totalSize = QStyledItemDelegate::sizeHint(option, index); totalSize.setHeight(48);//设置行高,也可以使用Model中通过Qt::SizeHintRole设置 int iconWidth = 15 + 20; int delWidth = 15 + 20; const int timeWidth = 100; int w = option.widget->width() - iconWidth - delWidth - timeWidth; switch (index.column()) { case 0: return QSize(iconWidth, totalSize.height()); case 1: return QSize(w, totalSize.height()); case 2: return QSize(timeWidth, totalSize.height()); case 3: return QSize(delWidth, totalSize.height()); } return totalSize; } void PlaylistDelegate::initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const { QStyledItemDelegate::initStyleOption(option, index); option->state = option->state & ~QStyle::State_HasFocus; } QWidget *PlaylistDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(option) Q_UNUSED(index) QPushButton *m_removeBtn = new QPushButton(parent); m_removeBtn->setFixedSize(16,16); m_removeBtn->setFocusPolicy(Qt::NoFocus); m_removeBtn->setObjectName("PlayListDelete"); connect(m_removeBtn, &QPushButton::clicked, this, &PlaylistDelegate::removeBtnClicked); return m_removeBtn; } void PlaylistDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(index) QPushButton *m_removeBtn = static_cast(editor); QRect btnRect = option.rect; editor->setGeometry(btnRect.x() + btnRect.width() - m_removeBtn->width() - 10, btnRect.y() + (btnRect.height()-m_removeBtn->height())/2, m_removeBtn->width(), m_removeBtn->height()); } void PlaylistDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { QStyledItemDelegate::setEditorData(editor, index); } void PlaylistDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { QStyledItemDelegate::setModelData(editor, model, index); } kylin-video/src/playlistitem.cpp0000644000175000017500000000732413517016402015750 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "playlistitem.h" #include #include #include #include #include #include #include #include #include #include #include #include "../smplayer/helper.h" PlayListItem::PlayListItem(QString mtype, QString filename, QString name, double duration, QWidget *parent) : QFrame(parent) { m_filename = filename; if (name.isDetached()) m_name = "lixiang"; m_name = name; m_duration = duration; m_played = false; m_deleted = false; m_data = filename; this->setFixedSize(220, 32); this->setToolTip(filename); icon_label = new QLabel(this); icon_label->setObjectName("PlayListIcon");//0616 icon_label->setGeometry(8,8,16,16); icon_label->setProperty("iconName", mtype); m_titleedit = new QLineEdit(this); m_titleedit->setObjectName("PlayListTitle");//0616 m_titleedit->setDisabled(true); m_titleedit->setReadOnly(true); m_titleedit->setAlignment(Qt::AlignLeft); m_titleedit->setGeometry(30,0,105,32); time_label = new QLabel(this); time_label->setStyleSheet("QLabel{color: #ffffff;font-size: 12px;background: transparent;}"); time_label->setText(Helper::formatTime((int)duration)); time_label->setGeometry(140,0,50,32); delete_btn = new QPushButton(this); delete_btn->setGeometry(192,8,16,16); delete_btn->setFocusPolicy(Qt::NoFocus); delete_btn->setObjectName("PlayListDelete"); connect(delete_btn, SIGNAL(clicked(bool)), this, SLOT(onDelete())); QFont font(m_titleedit->font()); font.setPixelSize(12); QFontMetrics fm(font); // m_titleedit->setText(fm.elidedText(QString(m_name), Qt::ElideMiddle, m_titleedit->maximumWidth())); m_titleedit->setText(fm.elidedText(QString(m_name), Qt::ElideMiddle, 105)); } void PlayListItem::update_widget_qss_property(QWidget *w, const char *name, const QVariant &value) { w->setProperty(name, value); this->style()->unpolish(w); this->style()->polish(w); w->update(); } void PlayListItem::setActive(bool active) { if (active) { this->update_widget_qss_property(m_titleedit, "status", "active"); this->update_widget_qss_property(delete_btn, "status", "active"); } else { this->update_widget_qss_property(m_titleedit, "status", ""); this->update_widget_qss_property(delete_btn, "status", ""); } } void PlayListItem::mouseDoubleClickEvent(QMouseEvent *event) { // QFrame::mouseDoubleClickEvent(event); emit this->sig_doubleclicked_resource(this->m_filename); QPoint lineeditMousePos = m_titleedit->mapFromParent(event->pos()); if (!m_titleedit->rect().contains(lineeditMousePos)) { return; } if (m_titleedit->isReadOnly()) { return; } } void PlayListItem::onDelete() { emit this->remove(m_data); } //kobe:更新视频的时长 void PlayListItem::update_time(QString duration) { time_label->setText(duration); } kylin-video/src/helpdialog.ui0000644000175000017500000000514313637124061015174 0ustar fengfeng HelpDialog 0 0 675 425 Kylin Video - Help 0 0 160 425 49 20 101 33 Help Qt::AlignCenter 0 72 160 353 0 0 QFrame::StyledPanel QFrame::Raised 14 20 32 32 Qt::AlignCenter 181 20 470 360 0 0 -1 570 390 91 25 OK kylin-video/src/res.qrc0000644000175000017500000001264413637124061014031 0ustar fengfeng res/background.png res/delete_hover_press.png res/delete_normal.png res/logo.png res/playlist_delete_button.png res/trash_normal.png res/ok.png res/info.png res/prefs.png res/clear_left.png res/backoff_10_seconds_hover_press.png res/backoff_10_seconds_normal.png res/cancel_fullscreen_hover_press.png res/cancel_fullscreen_normal.png res/close_hover.png res/close_normal.png res/close_press.png res/dragbar_hover_press.png res/dragbar_normal.png res/forward_10_seconds_hover_press.png res/forward_10_seconds_normal.png res/fullscreen_hover_press.png res/fullscreen_normal.png res/list_cycle_hover_press.png res/list_cycle_normal.png res/max_hover.png res/max_normal.png res/max_press.png res/min_hover.png res/min_normal.png res/min_press.png res/next_hover_press.png res/next_normal.png res/option_hover.png res/option_normal.png res/option_press.png res/order_cycle_hover_press.png res/order_cycle_normal.png res/pause_hover_press.png res/pause_normal.png res/play_center_hover_press.png res/play_center_normal.png res/play_hover_press.png res/play_normal.png res/playlist_close_hover_press.png res/playlist_close_normal.png res/playlist_open_hover_press.png res/playlist_open_normal.png res/previous_hover_press.png res/previous_normal.png res/progress_pointer_hover.png res/progress_pointer_normal.png res/progress_pointer_press.png res/single_cycle_hover_press.png res/single_cycle_normal.png res/stop_hover_press.png res/stop_normal.png res/unmax_hover.png res/unmax_normal.png res/unmax_press.png res/volume_high_hover_press.png res/volume_high_normal.png res/volume_low_hover_press.png res/volume_low_normal.png res/volume_mid_hover_press.png res/volume_mid_normal.png res/volume_mute_hover_press.png res/volume_mute_normal.png res/open_file_normal.png res/open_file_hover_press.png res/no-video.png res/about_hover_press.png res/about_normal.png res/screenshot_hover_press.png res/screenshot_normal.png res/trash_hover_press.png res/video_hover_press.png res/video_normal.png res/open_window_hover_press.png res/open_window_normal.png res/quit_normal.png res/quit_hover_press.png res/about_bg.png res/menu_selected.png res/radiobutton_disable.png res/checkbox_disable.png res/spin_bottom_arrow_disable.png res/spin_bottom_arrow_hover.png res/spin_bottom_arrow_normal.png res/spin_bottom_arrow_press.png res/spin_top_arrow_disable.png res/spin_top_arrow_hover.png res/spin_top_arrow_normal.png res/spin_top_arrow_press.png res/combobox_arrow_disable.png res/combobox_arrow_hover.png res/combobox_arrow_normal.png res/combobox_arrow_press.png res/radiobutton_unchecked.png res/radiobutton_checked.png res/checkbox_unchecked.png res/checkbox_checked.png res/settings.png res/warn.png res/kylin-video.png res/open_screen.png res/open_screen_hover.png res/help.png res/help_hover_press.png res/help_normal.png res/close.png res/unmax.png res/option.png res/min.png res/max.png res/plus.png res/osd.png res/poweroff.png res/style.qss kylin-video/src/remotecontroller.cpp0000644000175000017500000000333713517016402016627 0ustar fengfeng/* * This file was generated by qdbusxml2cpp version 0.8 * Command line was: qdbusxml2cpp remote_controller.xml -a remotecontroller * * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. * * This is an auto-generated file. * Do not edit! All changes made to it will be lost. */ #include "remotecontroller.h" #include #include #include #include #include #include #include /* * Implementation of adaptor class ControllerAdaptor */ ControllerAdaptor::ControllerAdaptor(QObject *parent) : QDBusAbstractAdaptor(parent) { // constructor setAutoRelaySignals(true); } ControllerAdaptor::~ControllerAdaptor() { // destructor } void ControllerAdaptor::playPause() { // handle method call com.kylin.kylinvideo.controller.playPause QMetaObject::invokeMethod(parent(), "playPause"); } void ControllerAdaptor::quit() { // handle method call com.kylin.kylinvideo.controller.quit QMetaObject::invokeMethod(parent(), "quit"); } bool ControllerAdaptor::seek_forward(int seconds) { // handle method call com.kylin.kylinvideo.controller.seek_forward bool out0; QMetaObject::invokeMethod(parent(), "seek_forward", Q_RETURN_ARG(bool, out0), Q_ARG(int, seconds)); return out0; } bool ControllerAdaptor::seek_rewind(int seconds) { // handle method call com.kylin.kylinvideo.controller.seek_rewind bool out0; QMetaObject::invokeMethod(parent(), "seek_rewind", Q_RETURN_ARG(bool, out0), Q_ARG(int, seconds)); return out0; } void ControllerAdaptor::stop() { // handle method call com.kylin.kylinvideo.controller.stop QMetaObject::invokeMethod(parent(), "stop"); } kylin-video/src/playlistitem.h0000644000175000017500000000552313517016402015414 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 PLAYLISTITEM_H #define PLAYLISTITEM_H #include class QLineEdit; class QLabel; class QPushButton; class PlayListItem : public QFrame { Q_OBJECT Q_PROPERTY(QString animationPrefix READ animationPrefix WRITE setAnimationPrefix) Q_PROPERTY(QString highlightAnimationPrefix READ highlightAnimationPrefix WRITE setHighlightAnimationPrefix) public: explicit PlayListItem(QString mtype, QString filename, QString name, double duration, QWidget *parent = 0); void setName(QString name) { m_name = name; }; void setDuration(double duration) { m_duration = duration; }; void setPlayed(bool b) { m_played = b; }; void setMarkForDeletion(bool b) { m_deleted = b; }; QString filename() { return m_filename; }; QString name() { return m_name; }; double duration() { return m_duration; }; bool played() { return m_played; }; bool markedForDeletion() { return m_deleted; }; inline QString data() {return m_data;} void setActive(bool active); void mouseDoubleClickEvent(QMouseEvent *event); QString animationPrefix() const { return m_animationPrefix; } QString highlightAnimationPrefix() const { return m_highlightAnimationPrefix; } QString m_filename, m_name; double m_duration; bool m_played, m_deleted; void update_widget_qss_property(QWidget *w, const char *name, const QVariant &value); signals: void rename(const QString &newNameA); void remove(QString filename); void sig_doubleclicked_resource(QString filename); public slots: void onDelete(); void setAnimationPrefix(QString animationPrefix) { m_animationPrefix = animationPrefix; } void setHighlightAnimationPrefix(QString highlightAnimationPrefix) { m_highlightAnimationPrefix = highlightAnimationPrefix; } void update_time(QString duration); private: QLabel *icon_label; QLineEdit *m_titleedit; QLabel *time_label; QPushButton *delete_btn; QString m_data; QString m_animationPrefix; QString m_highlightAnimationPrefix; }; #endif // PLAYLISTITEM_H kylin-video/src/datautils.h0000644000175000017500000000331413517016402014662 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 DATA_UTILS_H #define DATA_UTILS_H #include #include #include #include class VideoData { public: QString m_localpath; QString m_name; double m_duration; // bool m_active; void setLocalpath(QString localpath) { m_localpath = localpath; }; void setName(QString name) { m_name = name; }; void setDuration(double duration) { m_duration = duration; }; QString localpath() const { return m_localpath; }; QString name() const { return m_name; }; double duration() const { return m_duration; }; //public: // void setActive(bool b) { active = b; } }; //inline bool operator ==(const VideoData &data, const VideoData &other) { // return data.localpath == other.localpath; //} typedef QSharedPointer VideoPtr; typedef QList VideoPtrList; Q_DECLARE_METATYPE(VideoData) Q_DECLARE_METATYPE(VideoPtr) Q_DECLARE_METATYPE(VideoPtrList) #endif // DATA_UTILS_H kylin-video/src/playmask.cpp0000644000175000017500000000516413517016402015051 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "playmask.h" #include #include #include #define WAIT_TIME_TO_MAXIMIZE_OVERLAY_MS 300 #include #include #include PlayMask::PlayMask(QWidget *parent) : QWidget(parent, Qt::SubWindow) { setWindowFlags(windowFlags() | Qt::SubWindow); setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); // setTransparent(true); setFixedSize(172, 172); play_Btn = new QPushButton(this); play_Btn->setObjectName("PlayMaskBtn"); play_Btn->setFocusPolicy(Qt::NoFocus); play_Btn->setFixedSize(172, 172); QHBoxLayout *layout = new QHBoxLayout; layout->addWidget(play_Btn); layout->setMargin(0); this->setLayout(layout); connect(play_Btn, SIGNAL(released()), this, SIGNAL(signal_play_continue())); } PlayMask::~PlayMask() { } void PlayMask::setTransparent(bool transparent) { if (transparent) { setAttribute(Qt::WA_TranslucentBackground); setWindowFlags(windowFlags() | Qt::FramelessWindowHint|Qt::X11BypassWindowManagerHint); set_widget_opacity(0.5); } else { setAttribute(Qt::WA_TranslucentBackground,false); setWindowFlags(windowFlags() & ~Qt::FramelessWindowHint); } } void PlayMask::set_widget_opacity(const float &opacity) { QGraphicsOpacityEffect* opacityEffect = new QGraphicsOpacityEffect; this->setGraphicsEffect(opacityEffect); opacityEffect->setOpacity(opacity); } void PlayMask::paintEvent(QPaintEvent *event) { Q_UNUSED(event); // QStyleOption opt; // opt.init(this); // QPainter p(this); // style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); QPainter p(this); p.setCompositionMode(QPainter::CompositionMode_Clear); p.fillRect(rect(), Qt::SolidPattern);//p.fillRect(0, 0, this->width(), this->height(), Qt::SolidPattern); } kylin-video/src/input.conf0000644000175000017500000000245713517016402014534 0ustar fengfeng## prevent mplayer from messing up our shortcuts RIGHT invalid_command LEFT invalid_command DOWN invalid_command UP invalid_command PGUP invalid_command PGDWN invalid_command - invalid_command + invalid_command ESC invalid_command ENTER invalid_command SPACE pausing_keep invalid_command HOME invalid_command END invalid_command > invalid_command < invalid_command INS invalid_command DEL invalid_command [ invalid_command ] invalid_command { invalid_command } invalid_command BS invalid_command TAB invalid_command . invalid_command # invalid_command @ invalid_command ! invalid_command 9 invalid_command / invalid_command 0 invalid_command * invalid_command 1 invalid_command 2 invalid_command 3 invalid_command 4 invalid_command 5 invalid_command 6 invalid_command 7 invalid_command 8 invalid_command a invalid_command b invalid_command c invalid_command d invalid_command e invalid_command F invalid_command f invalid_command g invalid_command h invalid_command i invalid_command j invalid_command k invalid_command l invalid_command m invalid_command n invalid_command o invalid_command p invalid_command q invalid_command r invalid_command s invalid_command t invalid_command T invalid_command u invalid_command v invalid_command w invalid_command x invalid_command y invalid_command z invalid_command S invalid_command kylin-video/src/qtsingleapplication/0000755000175000017500000000000013517016402016570 5ustar fengfengkylin-video/src/qtsingleapplication/qtsinglecoreapplication.pri0000644000175000017500000000050413517016402024226 0ustar fengfengINCLUDEPATH += $$PWD DEPENDPATH += $$PWD HEADERS += $$PWD/qtsinglecoreapplication.h $$PWD/qtlocalpeer.h SOURCES += $$PWD/qtsinglecoreapplication.cpp $$PWD/qtlocalpeer.cpp QT *= network win32:contains(TEMPLATE, lib):contains(CONFIG, shared) { DEFINES += QT_QTSINGLECOREAPPLICATION_EXPORT=__declspec(dllexport) } kylin-video/src/qtsingleapplication/qtsingleapplication.h0000644000175000017500000000761713517016402023026 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef QTSINGLEAPPLICATION_H #define QTSINGLEAPPLICATION_H #include class QtLocalPeer; #if defined(Q_OS_WIN) # if !defined(QT_QTSINGLEAPPLICATION_EXPORT) && !defined(QT_QTSINGLEAPPLICATION_IMPORT) # define QT_QTSINGLEAPPLICATION_EXPORT # elif defined(QT_QTSINGLEAPPLICATION_IMPORT) # if defined(QT_QTSINGLEAPPLICATION_EXPORT) # undef QT_QTSINGLEAPPLICATION_EXPORT # endif # define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllimport) # elif defined(QT_QTSINGLEAPPLICATION_EXPORT) # undef QT_QTSINGLEAPPLICATION_EXPORT # define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllexport) # endif #else # define QT_QTSINGLEAPPLICATION_EXPORT #endif class QT_QTSINGLEAPPLICATION_EXPORT QtSingleApplication : public QApplication { Q_OBJECT public: QtSingleApplication(int &argc, char **argv, bool GUIenabled = true); QtSingleApplication(const QString &id, int &argc, char **argv); #if QT_VERSION < 0x050000 QtSingleApplication(int &argc, char **argv, Type type); # if defined(Q_WS_X11) QtSingleApplication(Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0); QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap= 0); QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0); # endif // Q_WS_X11 #endif // QT_VERSION < 0x050000 bool isRunning(); QString id() const; void setActivationWindow(QWidget* aw, bool activateOnMessage = true); QWidget* activationWindow() const; // Obsolete: void initialize(bool dummy = true) { isRunning(); Q_UNUSED(dummy) } public Q_SLOTS: bool sendMessage(const QString &message, int timeout = 5000); void activateWindow(); Q_SIGNALS: void messageReceived(const QString &message); private: void sysInit(const QString &appId = QString()); QtLocalPeer *peer; QWidget *actWin; }; #endif // QTSINGLEAPPLICATION_H kylin-video/src/qtsingleapplication/qtsinglecoreapplication.h0000644000175000017500000000502513517016402023666 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef QTSINGLECOREAPPLICATION_H #define QTSINGLECOREAPPLICATION_H #include class QtLocalPeer; class QtSingleCoreApplication : public QCoreApplication { Q_OBJECT public: QtSingleCoreApplication(int &argc, char **argv); QtSingleCoreApplication(const QString &id, int &argc, char **argv); bool isRunning(); QString id() const; public Q_SLOTS: bool sendMessage(const QString &message, int timeout = 5000); Q_SIGNALS: void messageReceived(const QString &message); private: QtLocalPeer* peer; }; #endif // QTSINGLECOREAPPLICATION_H kylin-video/src/qtsingleapplication/qtsingleapplication.pri0000644000175000017500000000111013517016402023347 0ustar fengfenginclude(../common.pri) INCLUDEPATH += $$PWD DEPENDPATH += $$PWD QT *= network greaterThan(QT_MAJOR_VERSION, 4): QT *= widgets qtsingleapplication-uselib:!qtsingleapplication-buildlib { LIBS += -L$$QTSINGLEAPPLICATION_LIBDIR -l$$QTSINGLEAPPLICATION_LIBNAME } else { SOURCES += $$PWD/qtsingleapplication.cpp $$PWD/qtlocalpeer.cpp HEADERS += $$PWD/qtsingleapplication.h $$PWD/qtlocalpeer.h } win32 { contains(TEMPLATE, lib):contains(CONFIG, shared):DEFINES += QT_QTSINGLEAPPLICATION_EXPORT else:qtsingleapplication-uselib:DEFINES += QT_QTSINGLEAPPLICATION_IMPORT } kylin-video/src/qtsingleapplication/qtlockedfile_win.cpp0000644000175000017500000001466113517016402022627 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qtlockedfile.h" #include #include #define MUTEX_PREFIX "QtLockedFile mutex " // Maximum number of concurrent read locks. Must not be greater than MAXIMUM_WAIT_OBJECTS #define MAX_READERS MAXIMUM_WAIT_OBJECTS #if QT_VERSION >= 0x050000 #define QT_WA(unicode, ansi) unicode #endif Qt::HANDLE QtLockedFile::getMutexHandle(int idx, bool doCreate) { if (mutexname.isEmpty()) { QFileInfo fi(*this); mutexname = QString::fromLatin1(MUTEX_PREFIX) + fi.absoluteFilePath().toLower(); } QString mname(mutexname); if (idx >= 0) mname += QString::number(idx); Qt::HANDLE mutex; if (doCreate) { QT_WA( { mutex = CreateMutexW(NULL, FALSE, (TCHAR*)mname.utf16()); }, { mutex = CreateMutexA(NULL, FALSE, mname.toLocal8Bit().constData()); } ); if (!mutex) { qErrnoWarning("QtLockedFile::lock(): CreateMutex failed"); return 0; } } else { QT_WA( { mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, (TCHAR*)mname.utf16()); }, { mutex = OpenMutexA(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, mname.toLocal8Bit().constData()); } ); if (!mutex) { if (GetLastError() != ERROR_FILE_NOT_FOUND) qErrnoWarning("QtLockedFile::lock(): OpenMutex failed"); return 0; } } return mutex; } bool QtLockedFile::waitMutex(Qt::HANDLE mutex, bool doBlock) { Q_ASSERT(mutex); DWORD res = WaitForSingleObject(mutex, doBlock ? INFINITE : 0); switch (res) { case WAIT_OBJECT_0: case WAIT_ABANDONED: return true; break; case WAIT_TIMEOUT: break; default: qErrnoWarning("QtLockedFile::lock(): WaitForSingleObject failed"); } return false; } bool QtLockedFile::lock(LockMode mode, bool block) { if (!isOpen()) { qWarning("QtLockedFile::lock(): file is not opened"); return false; } if (mode == NoLock) return unlock(); if (mode == m_lock_mode) return true; if (m_lock_mode != NoLock) unlock(); if (!wmutex && !(wmutex = getMutexHandle(-1, true))) return false; if (!waitMutex(wmutex, block)) return false; if (mode == ReadLock) { int idx = 0; for (; idx < MAX_READERS; idx++) { rmutex = getMutexHandle(idx, false); if (!rmutex || waitMutex(rmutex, false)) break; CloseHandle(rmutex); } bool ok = true; if (idx >= MAX_READERS) { qWarning("QtLockedFile::lock(): too many readers"); rmutex = 0; ok = false; } else if (!rmutex) { rmutex = getMutexHandle(idx, true); if (!rmutex || !waitMutex(rmutex, false)) ok = false; } if (!ok && rmutex) { CloseHandle(rmutex); rmutex = 0; } ReleaseMutex(wmutex); if (!ok) return false; } else { Q_ASSERT(rmutexes.isEmpty()); for (int i = 0; i < MAX_READERS; i++) { Qt::HANDLE mutex = getMutexHandle(i, false); if (mutex) rmutexes.append(mutex); } if (rmutexes.size()) { DWORD res = WaitForMultipleObjects(rmutexes.size(), rmutexes.constData(), TRUE, block ? INFINITE : 0); if (res != WAIT_OBJECT_0 && res != WAIT_ABANDONED) { if (res != WAIT_TIMEOUT) qErrnoWarning("QtLockedFile::lock(): WaitForMultipleObjects failed"); m_lock_mode = WriteLock; // trick unlock() to clean up - semiyucky unlock(); return false; } } } m_lock_mode = mode; return true; } bool QtLockedFile::unlock() { if (!isOpen()) { qWarning("QtLockedFile::unlock(): file is not opened"); return false; } if (!isLocked()) return true; if (m_lock_mode == ReadLock) { ReleaseMutex(rmutex); CloseHandle(rmutex); rmutex = 0; } else { foreach(Qt::HANDLE mutex, rmutexes) { ReleaseMutex(mutex); CloseHandle(mutex); } rmutexes.clear(); ReleaseMutex(wmutex); } m_lock_mode = QtLockedFile::NoLock; return true; } QtLockedFile::~QtLockedFile() { if (isOpen()) unlock(); if (wmutex) CloseHandle(wmutex); } kylin-video/src/qtsingleapplication/qtlocalpeer.h0000644000175000017500000000520513517016402021256 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef QTLOCALPEER_H #define QTLOCALPEER_H #include #include #include #include "qtlockedfile.h" class QtLocalPeer : public QObject { Q_OBJECT public: QtLocalPeer(QObject *parent = 0, const QString &appId = QString()); bool isClient(); bool sendMessage(const QString &message, int timeout); QString applicationId() const { return id; } Q_SIGNALS: void messageReceived(const QString &message); protected Q_SLOTS: void receiveConnection(); protected: QString id; QString socketName; QLocalServer* server; QtLP_Private::QtLockedFile lockFile; private: static const char* ack; }; #endif // QTLOCALPEER_H kylin-video/src/qtsingleapplication/qtlocalpeer.cpp0000644000175000017500000001507013517016402021612 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qtlocalpeer.h" #include #include #include #if defined(Q_OS_WIN) #include #include typedef BOOL(WINAPI*PProcessIdToSessionId)(DWORD,DWORD*); static PProcessIdToSessionId pProcessIdToSessionId = 0; #endif #if defined(Q_OS_UNIX) #include #include #include #endif namespace QtLP_Private { #include "qtlockedfile.cpp" #if defined(Q_OS_WIN) #include "qtlockedfile_win.cpp" #else #include "qtlockedfile_unix.cpp" #endif } const char* QtLocalPeer::ack = "ack"; QtLocalPeer::QtLocalPeer(QObject* parent, const QString &appId) : QObject(parent), id(appId) { QString prefix = id; if (id.isEmpty()) { id = QCoreApplication::applicationFilePath(); #if defined(Q_OS_WIN) id = id.toLower(); #endif prefix = id.section(QLatin1Char('/'), -1); } prefix.remove(QRegExp("[^a-zA-Z]")); prefix.truncate(6); QByteArray idc = id.toUtf8(); quint16 idNum = qChecksum(idc.constData(), idc.size()); socketName = QLatin1String("qtsingleapp-") + prefix + QLatin1Char('-') + QString::number(idNum, 16); #if defined(Q_OS_WIN) if (!pProcessIdToSessionId) { QLibrary lib("kernel32"); pProcessIdToSessionId = (PProcessIdToSessionId)lib.resolve("ProcessIdToSessionId"); } if (pProcessIdToSessionId) { DWORD sessionId = 0; pProcessIdToSessionId(GetCurrentProcessId(), &sessionId); socketName += QLatin1Char('-') + QString::number(sessionId, 16); } #else socketName += QLatin1Char('-') + QString::number(::getuid(), 16); #endif server = new QLocalServer(this); QString lockName = QDir(QDir::tempPath()).absolutePath() + QLatin1Char('/') + socketName + QLatin1String("-lockfile"); lockFile.setFileName(lockName); lockFile.open(QIODevice::ReadWrite); } bool QtLocalPeer::isClient() { if (lockFile.isLocked()) return false; if (!lockFile.lock(QtLP_Private::QtLockedFile::WriteLock, false)) return true; bool res = server->listen(socketName); #if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(4,5,0)) // ### Workaround if (!res && server->serverError() == QAbstractSocket::AddressInUseError) { QFile::remove(QDir::cleanPath(QDir::tempPath())+QLatin1Char('/')+socketName); res = server->listen(socketName); } #endif if (!res) qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString())); QObject::connect(server, SIGNAL(newConnection()), SLOT(receiveConnection())); return false; } bool QtLocalPeer::sendMessage(const QString &message, int timeout) { if (!isClient()) return false; QLocalSocket socket; bool connOk = false; for(int i = 0; i < 2; i++) { // Try twice, in case the other instance is just starting up socket.connectToServer(socketName); connOk = socket.waitForConnected(timeout/2); if (connOk || i) break; int ms = 250; #if defined(Q_OS_WIN) Sleep(DWORD(ms)); #else struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 }; nanosleep(&ts, NULL); #endif } if (!connOk) return false; QByteArray uMsg(message.toUtf8()); QDataStream ds(&socket); ds.writeBytes(uMsg.constData(), uMsg.size()); bool res = socket.waitForBytesWritten(timeout); if (res) { res &= socket.waitForReadyRead(timeout); // wait for ack if (res) res &= (socket.read(qstrlen(ack)) == ack); } return res; } void QtLocalPeer::receiveConnection() { QLocalSocket* socket = server->nextPendingConnection(); if (!socket) return; while (socket->bytesAvailable() < (int)sizeof(quint32)) socket->waitForReadyRead(); QDataStream ds(socket); QByteArray uMsg; quint32 remaining; ds >> remaining; uMsg.resize(remaining); int got = 0; char* uMsgBuf = uMsg.data(); do { got = ds.readRawData(uMsgBuf, remaining); remaining -= got; uMsgBuf += got; } while (remaining && got >= 0 && socket->waitForReadyRead(2000)); if (got < 0) { qWarning("QtLocalPeer: Message reception failed %s", socket->errorString().toLatin1().constData()); delete socket; return; } QString message(QString::fromUtf8(uMsg)); socket->write(ack, qstrlen(ack)); socket->waitForBytesWritten(1000); socket->waitForDisconnected(1000); // make sure client reads ack delete socket; emit messageReceived(message); //### (might take a long time to return) } kylin-video/src/qtsingleapplication/qtlockedfile.h0000644000175000017500000000630713517016402021415 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef QTLOCKEDFILE_H #define QTLOCKEDFILE_H #include #ifdef Q_OS_WIN #include #endif #if defined(Q_OS_WIN) # if !defined(QT_QTLOCKEDFILE_EXPORT) && !defined(QT_QTLOCKEDFILE_IMPORT) # define QT_QTLOCKEDFILE_EXPORT # elif defined(QT_QTLOCKEDFILE_IMPORT) # if defined(QT_QTLOCKEDFILE_EXPORT) # undef QT_QTLOCKEDFILE_EXPORT # endif # define QT_QTLOCKEDFILE_EXPORT __declspec(dllimport) # elif defined(QT_QTLOCKEDFILE_EXPORT) # undef QT_QTLOCKEDFILE_EXPORT # define QT_QTLOCKEDFILE_EXPORT __declspec(dllexport) # endif #else # define QT_QTLOCKEDFILE_EXPORT #endif namespace QtLP_Private { class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile { public: enum LockMode { NoLock = 0, ReadLock, WriteLock }; QtLockedFile(); QtLockedFile(const QString &name); ~QtLockedFile(); bool open(OpenMode mode); bool lock(LockMode mode, bool block = true); bool unlock(); bool isLocked() const; LockMode lockMode() const; private: #ifdef Q_OS_WIN Qt::HANDLE wmutex; Qt::HANDLE rmutex; QVector rmutexes; QString mutexname; Qt::HANDLE getMutexHandle(int idx, bool doCreate); bool waitMutex(Qt::HANDLE mutex, bool doBlock); #endif LockMode m_lock_mode; }; } #endif kylin-video/src/qtsingleapplication/QtSingleApplication0000644000175000017500000000004113517016402022420 0ustar fengfeng#include "qtsingleapplication.h" kylin-video/src/qtsingleapplication/qtlockedfile.cpp0000644000175000017500000001374213517016402021751 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qtlockedfile.h" /*! \class QtLockedFile \brief The QtLockedFile class extends QFile with advisory locking functions. A file may be locked in read or write mode. Multiple instances of \e QtLockedFile, created in multiple processes running on the same machine, may have a file locked in read mode. Exactly one instance may have it locked in write mode. A read and a write lock cannot exist simultaneously on the same file. The file locks are advisory. This means that nothing prevents another process from manipulating a locked file using QFile or file system functions offered by the OS. Serialization is only guaranteed if all processes that access the file use QLockedFile. Also, while holding a lock on a file, a process must not open the same file again (through any API), or locks can be unexpectedly lost. The lock provided by an instance of \e QtLockedFile is released whenever the program terminates. This is true even when the program crashes and no destructors are called. */ /*! \enum QtLockedFile::LockMode This enum describes the available lock modes. \value ReadLock A read lock. \value WriteLock A write lock. \value NoLock Neither a read lock nor a write lock. */ /*! Constructs an unlocked \e QtLockedFile object. This constructor behaves in the same way as \e QFile::QFile(). \sa QFile::QFile() */ QtLockedFile::QtLockedFile() : QFile() { #ifdef Q_OS_WIN wmutex = 0; rmutex = 0; #endif m_lock_mode = NoLock; } /*! Constructs an unlocked QtLockedFile object with file \a name. This constructor behaves in the same way as \e QFile::QFile(const QString&). \sa QFile::QFile() */ QtLockedFile::QtLockedFile(const QString &name) : QFile(name) { #ifdef Q_OS_WIN wmutex = 0; rmutex = 0; #endif m_lock_mode = NoLock; } /*! Opens the file in OpenMode \a mode. This is identical to QFile::open(), with the one exception that the Truncate mode flag is disallowed. Truncation would conflict with the advisory file locking, since the file would be modified before the write lock is obtained. If truncation is required, use resize(0) after obtaining the write lock. Returns true if successful; otherwise false. \sa QFile::open(), QFile::resize() */ bool QtLockedFile::open(OpenMode mode) { if (mode & QIODevice::Truncate) { qWarning("QtLockedFile::open(): Truncate mode not allowed."); return false; } return QFile::open(mode); } /*! Returns \e true if this object has a in read or write lock; otherwise returns \e false. \sa lockMode() */ bool QtLockedFile::isLocked() const { return m_lock_mode != NoLock; } /*! Returns the type of lock currently held by this object, or \e QtLockedFile::NoLock. \sa isLocked() */ QtLockedFile::LockMode QtLockedFile::lockMode() const { return m_lock_mode; } /*! \fn bool QtLockedFile::lock(LockMode mode, bool block = true) Obtains a lock of type \a mode. The file must be opened before it can be locked. If \a block is true, this function will block until the lock is aquired. If \a block is false, this function returns \e false immediately if the lock cannot be aquired. If this object already has a lock of type \a mode, this function returns \e true immediately. If this object has a lock of a different type than \a mode, the lock is first released and then a new lock is obtained. This function returns \e true if, after it executes, the file is locked by this object, and \e false otherwise. \sa unlock(), isLocked(), lockMode() */ /*! \fn bool QtLockedFile::unlock() Releases a lock. If the object has no lock, this function returns immediately. This function returns \e true if, after it executes, the file is not locked by this object, and \e false otherwise. \sa lock(), isLocked(), lockMode() */ /*! \fn QtLockedFile::~QtLockedFile() Destroys the \e QtLockedFile object. If any locks were held, they are released. */ kylin-video/src/qtsingleapplication/qtsingleapplication.cpp0000644000175000017500000002701013517016402023346 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qtsingleapplication.h" #include "qtlocalpeer.h" #include /*! \class QtSingleApplication qtsingleapplication.h \brief The QtSingleApplication class provides an API to detect and communicate with running instances of an application. This class allows you to create applications where only one instance should be running at a time. I.e., if the user tries to launch another instance, the already running instance will be activated instead. Another usecase is a client-server system, where the first started instance will assume the role of server, and the later instances will act as clients of that server. By default, the full path of the executable file is used to determine whether two processes are instances of the same application. You can also provide an explicit identifier string that will be compared instead. The application should create the QtSingleApplication object early in the startup phase, and call isRunning() to find out if another instance of this application is already running. If isRunning() returns false, it means that no other instance is running, and this instance has assumed the role as the running instance. In this case, the application should continue with the initialization of the application user interface before entering the event loop with exec(), as normal. The messageReceived() signal will be emitted when the running application receives messages from another instance of the same application. When a message is received it might be helpful to the user to raise the application so that it becomes visible. To facilitate this, QtSingleApplication provides the setActivationWindow() function and the activateWindow() slot. If isRunning() returns true, another instance is already running. It may be alerted to the fact that another instance has started by using the sendMessage() function. Also data such as startup parameters (e.g. the name of the file the user wanted this new instance to open) can be passed to the running instance with this function. Then, the application should terminate (or enter client mode). If isRunning() returns true, but sendMessage() fails, that is an indication that the running instance is frozen. Here's an example that shows how to convert an existing application to use QtSingleApplication. It is very simple and does not make use of all QtSingleApplication's functionality (see the examples for that). \code // Original int main(int argc, char **argv) { QApplication app(argc, argv); MyMainWidget mmw; mmw.show(); return app.exec(); } // Single instance int main(int argc, char **argv) { QtSingleApplication app(argc, argv); if (app.isRunning()) return !app.sendMessage(someDataString); MyMainWidget mmw; app.setActivationWindow(&mmw); mmw.show(); return app.exec(); } \endcode Once this QtSingleApplication instance is destroyed (normally when the process exits or crashes), when the user next attempts to run the application this instance will not, of course, be encountered. The next instance to call isRunning() or sendMessage() will assume the role as the new running instance. For console (non-GUI) applications, QtSingleCoreApplication may be used instead of this class, to avoid the dependency on the QtGui library. \sa QtSingleCoreApplication */ void QtSingleApplication::sysInit(const QString &appId) { actWin = 0; peer = new QtLocalPeer(this, appId); connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&))); } /*! Creates a QtSingleApplication object. The application identifier will be QCoreApplication::applicationFilePath(). \a argc, \a argv, and \a GUIenabled are passed on to the QAppliation constructor. If you are creating a console application (i.e. setting \a GUIenabled to false), you may consider using QtSingleCoreApplication instead. */ QtSingleApplication::QtSingleApplication(int &argc, char **argv, bool GUIenabled) : QApplication(argc, argv, GUIenabled) { sysInit(); } /*! Creates a QtSingleApplication object with the application identifier \a appId. \a argc and \a argv are passed on to the QAppliation constructor. */ QtSingleApplication::QtSingleApplication(const QString &appId, int &argc, char **argv) : QApplication(argc, argv) { sysInit(appId); } #if QT_VERSION < 0x050000 /*! Creates a QtSingleApplication object. The application identifier will be QCoreApplication::applicationFilePath(). \a argc, \a argv, and \a type are passed on to the QAppliation constructor. */ QtSingleApplication::QtSingleApplication(int &argc, char **argv, Type type) : QApplication(argc, argv, type) { sysInit(); } # if defined(Q_WS_X11) /*! Special constructor for X11, ref. the documentation of QApplication's corresponding constructor. The application identifier will be QCoreApplication::applicationFilePath(). \a dpy, \a visual, and \a cmap are passed on to the QApplication constructor. */ QtSingleApplication::QtSingleApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE cmap) : QApplication(dpy, visual, cmap) { sysInit(); } /*! Special constructor for X11, ref. the documentation of QApplication's corresponding constructor. The application identifier will be QCoreApplication::applicationFilePath(). \a dpy, \a argc, \a argv, \a visual, and \a cmap are passed on to the QApplication constructor. */ QtSingleApplication::QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap) : QApplication(dpy, argc, argv, visual, cmap) { sysInit(); } /*! Special constructor for X11, ref. the documentation of QApplication's corresponding constructor. The application identifier will be \a appId. \a dpy, \a argc, \a argv, \a visual, and \a cmap are passed on to the QApplication constructor. */ QtSingleApplication::QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap) : QApplication(dpy, argc, argv, visual, cmap) { sysInit(appId); } # endif // Q_WS_X11 #endif // QT_VERSION < 0x050000 /*! Returns true if another instance of this application is running; otherwise false. This function does not find instances of this application that are being run by a different user (on Windows: that are running in another session). \sa sendMessage() */ bool QtSingleApplication::isRunning() { return peer->isClient(); } /*! Tries to send the text \a message to the currently running instance. The QtSingleApplication object in the running instance will emit the messageReceived() signal when it receives the message. This function returns true if the message has been sent to, and processed by, the current instance. If there is no instance currently running, or if the running instance fails to process the message within \a timeout milliseconds, this function return false. \sa isRunning(), messageReceived() */ bool QtSingleApplication::sendMessage(const QString &message, int timeout) { return peer->sendMessage(message, timeout); } /*! Returns the application identifier. Two processes with the same identifier will be regarded as instances of the same application. */ QString QtSingleApplication::id() const { return peer->applicationId(); } /*! Sets the activation window of this application to \a aw. The activation window is the widget that will be activated by activateWindow(). This is typically the application's main window. If \a activateOnMessage is true (the default), the window will be activated automatically every time a message is received, just prior to the messageReceived() signal being emitted. \sa activateWindow(), messageReceived() */ void QtSingleApplication::setActivationWindow(QWidget* aw, bool activateOnMessage) { actWin = aw; if (activateOnMessage) connect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow())); else disconnect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow())); } /*! Returns the applications activation window if one has been set by calling setActivationWindow(), otherwise returns 0. \sa setActivationWindow() */ QWidget* QtSingleApplication::activationWindow() const { return actWin; } /*! De-minimizes, raises, and activates this application's activation window. This function does nothing if no activation window has been set. This is a convenience function to show the user that this application instance has been activated when he has tried to start another instance. This function should typically be called in response to the messageReceived() signal. By default, that will happen automatically, if an activation window has been set. \sa setActivationWindow(), messageReceived(), initialize() */ void QtSingleApplication::activateWindow() { if (actWin) { actWin->setWindowState(actWin->windowState() & ~Qt::WindowMinimized); actWin->raise(); actWin->activateWindow(); } } /*! \fn void QtSingleApplication::messageReceived(const QString& message) This signal is emitted when the current instance receives a \a message from another instance of this application. \sa sendMessage(), setActivationWindow(), activateWindow() */ /*! \fn void QtSingleApplication::initialize(bool dummy = true) \obsolete */ kylin-video/src/qtsingleapplication/qtsinglecoreapplication.cpp0000644000175000017500000001235513517016402024225 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qtsinglecoreapplication.h" #include "qtlocalpeer.h" /*! \class QtSingleCoreApplication qtsinglecoreapplication.h \brief A variant of the QtSingleApplication class for non-GUI applications. This class is a variant of QtSingleApplication suited for use in console (non-GUI) applications. It is an extension of QCoreApplication (instead of QApplication). It does not require the QtGui library. The API and usage is identical to QtSingleApplication, except that functions relating to the "activation window" are not present, for obvious reasons. Please refer to the QtSingleApplication documentation for explanation of the usage. A QtSingleCoreApplication instance can communicate to a QtSingleApplication instance if they share the same application id. Hence, this class can be used to create a light-weight command-line tool that sends commands to a GUI application. \sa QtSingleApplication */ /*! Creates a QtSingleCoreApplication object. The application identifier will be QCoreApplication::applicationFilePath(). \a argc and \a argv are passed on to the QCoreAppliation constructor. */ QtSingleCoreApplication::QtSingleCoreApplication(int &argc, char **argv) : QCoreApplication(argc, argv) { peer = new QtLocalPeer(this); connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&))); } /*! Creates a QtSingleCoreApplication object with the application identifier \a appId. \a argc and \a argv are passed on to the QCoreAppliation constructor. */ QtSingleCoreApplication::QtSingleCoreApplication(const QString &appId, int &argc, char **argv) : QCoreApplication(argc, argv) { peer = new QtLocalPeer(this, appId); connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&))); } /*! Returns true if another instance of this application is running; otherwise false. This function does not find instances of this application that are being run by a different user (on Windows: that are running in another session). \sa sendMessage() */ bool QtSingleCoreApplication::isRunning() { return peer->isClient(); } /*! Tries to send the text \a message to the currently running instance. The QtSingleCoreApplication object in the running instance will emit the messageReceived() signal when it receives the message. This function returns true if the message has been sent to, and processed by, the current instance. If there is no instance currently running, or if the running instance fails to process the message within \a timeout milliseconds, this function return false. \sa isRunning(), messageReceived() */ bool QtSingleCoreApplication::sendMessage(const QString &message, int timeout) { return peer->sendMessage(message, timeout); } /*! Returns the application identifier. Two processes with the same identifier will be regarded as instances of the same application. */ QString QtSingleCoreApplication::id() const { return peer->applicationId(); } /*! \fn void QtSingleCoreApplication::messageReceived(const QString& message) This signal is emitted when the current instance receives a \a message from another instance of this application. \sa sendMessage() */ kylin-video/src/qtsingleapplication/QtLockedFile0000644000175000017500000000003213517016402021014 0ustar fengfeng#include "qtlockedfile.h" kylin-video/src/qtsingleapplication/qtlockedfile_unix.cpp0000644000175000017500000000661413517016402023014 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include #include #include #include "qtlockedfile.h" bool QtLockedFile::lock(LockMode mode, bool block) { if (!isOpen()) { qWarning("QtLockedFile::lock(): file is not opened"); return false; } if (mode == NoLock) return unlock(); if (mode == m_lock_mode) return true; if (m_lock_mode != NoLock) unlock(); struct flock fl; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; fl.l_type = (mode == ReadLock) ? F_RDLCK : F_WRLCK; int cmd = block ? F_SETLKW : F_SETLK; int ret = fcntl(handle(), cmd, &fl); if (ret == -1) { if (errno != EINTR && errno != EAGAIN) qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno)); return false; } m_lock_mode = mode; return true; } bool QtLockedFile::unlock() { if (!isOpen()) { qWarning("QtLockedFile::unlock(): file is not opened"); return false; } if (!isLocked()) return true; struct flock fl; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; fl.l_type = F_UNLCK; int ret = fcntl(handle(), F_SETLKW, &fl); if (ret == -1) { qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno)); return false; } m_lock_mode = NoLock; return true; } QtLockedFile::~QtLockedFile() { if (isOpen()) unlock(); } kylin-video/src/shortcutswidget.h0000644000175000017500000000707413517016402016141 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 SHORTCUTSWIDGET_H #define SHORTCUTSWIDGET_H #include #include #include #include "../smplayer/preferences.h" class QTimer; class QLabel; class QPushButton; class QGridLayout; class QFormLayout; class ShortcutsWidget : public QWidget { Q_OBJECT public: explicit ShortcutsWidget(QWidget *parent = 0); ~ShortcutsWidget(); static ShortcutsWidget *Instance() { static QMutex mutex; if (!self) { QMutexLocker locker(&mutex); if (!self) { self = new ShortcutsWidget; } } return self; } void restart_timer(); void init_ui(); void setPrefData(Preferences * pref); protected: void showEvent(QShowEvent *); // virtual void keyReleaseEvent(QKeyEvent *event); public slots: void set_parent_widget(QWidget *idget); void set_background_color(const QColor &bgColor); void set_widget_opacity(double opacity); void hide_mask_widget(); void onCloseButtonClicked(); private: static ShortcutsWidget *self; QWidget *parent_widget; QTimer *timer; QLabel *title_label; QLabel *control_title_label; QLabel *other_title_label; QPushButton *close_button; // QFormLayout *control_form_layout; // QList control_label_list; QGridLayout *control_grid_layout; // QList other_label_list; QGridLayout *other_grid_layout; QLabel *play_title; QLabel *play_label; QLabel *play_pre_title; QLabel *play_pre_label; QLabel *play_next_title; QLabel *play_next_label; QLabel *forward_10s_title; QLabel *forward_10s_label; QLabel *forward_1m_title; QLabel *forward_1m_label; QLabel *forward_10m_title; QLabel *forward_10m_label; QLabel *back_10s_title; QLabel *back_10s_label; QLabel *back_1m_title; QLabel *back_1m_label; QLabel *back_10m_title; QLabel *back_10m_label; QLabel *jump_title; QLabel *jump_label; QLabel *mute_title; QLabel *mute_label; QLabel *vol_up_title; QLabel *vol_up_label; QLabel *vol_down_title; QLabel *vol_down_label; QLabel *set_audio_delay_title; QLabel *set_audio_delay_label; QLabel *audio_delay_title; QLabel *audio_delay_label; QLabel *playlist_title; QLabel *playlist_label; QLabel *open_title; QLabel *open_label; QLabel *screenshot_title; QLabel *screenshot_label; QLabel *pref_title; QLabel *pref_label; QLabel *info_title; QLabel *info_label; QLabel *about_title; QLabel *about_label; QLabel *quit_title; QLabel *quit_label; QLabel *fullscreen_title; QLabel *fullscreen_label; }; #endif // SHORTCUTSWIDGET_H kylin-video/src/infoworker.cpp0000644000175000017500000000473613625147453015434 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "infoworker.h" #include "../smplayer/preferences.h" #include "../smplayer/global.h" #include #include #include using namespace Global; #include "../smplayer/infoprovider.h" InfoWorker::InfoWorker(QObject *parent) :QObject(parent) { //qDebug()<<"InfoWorker init"<<"线程id:" << QThread::currentThreadId(); } InfoWorker::~InfoWorker() { } void InfoWorker::onGetMediaInfo(const QStringList &filepaths) { bool fileInPlaylist = false; VideoPtrList medialist; for (int n = 0; n < filepaths.count(); n++) { QFileInfo fileInfo(filepaths[n]); if (fileInfo.isDir()) { continue; } if (pref->m_videoMap.contains(filepaths[n])) { fileInPlaylist = true; continue; } if ((QFile::exists(filepaths[n]))) { MediaData data = InfoProvider::getInfo(filepaths[n]); QString name = ""; double duration = 0; name = data.displayName(); if (name.isEmpty()) { QFileInfo fi(filepaths[n]); // Let's see if it looks like a file (no dvd://1 or something) if (filepaths[n].indexOf(QRegExp("^.*://.*")) == -1) { // Local file name = fi.fileName(); } else { // Stream name = filepaths[n]; } } duration = data.duration; auto video = pref->generateVedioData(filepaths[n], name, duration); if (video.isNull()) { continue; } medialist << video; } } emit meidaFilesAdded(medialist, fileInPlaylist); medialist.clear(); } kylin-video/controllertest/0000755000175000017500000000000013517016402015012 5ustar fengfengkylin-video/controllertest/application.cpp0000644000175000017500000000205313517016402020021 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "application.h" #include "signalmanager.h" Application::Application(int& argc, char** argv) : QCoreApplication(argc, argv) { setOrganizationName("TianJin Kylin"); setApplicationName("controllertest"); setApplicationVersion("1.0.0"); signalM = SignalManager::Instance(); } kylin-video/controllertest/application.h0000644000175000017500000000224413517016402017470 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 APPLICATION_H #define APPLICATION_H #include #include class SignalManager; #if defined(mycontroller) #undef mycontroller #endif #define mycontroller (static_cast(QCoreApplication::instance())) class Application : public QCoreApplication { Q_OBJECT public: Application(int& argc, char** argv); SignalManager *signalM = nullptr; }; #endif // APPLICATION_H kylin-video/controllertest/controller.cpp0000644000175000017500000001303213517016402017700 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "controller.h" #include "application.h" #include "signalmanager.h" #include #include #include #include #include #define CONTROL_DBUS_SERVICE_NAME "com.kylin.kylinvideo.controller" static void* request_controller_thread(void* arg) { //开始循环,接收用户输入选择,并响应回复信息 char buff[256]; while (fgets(buff, sizeof(buff), stdin) != NULL) { int iCmdType = 0; if(sscanf(buff, "%d", &iCmdType) == -1) { fprintf(stderr, "Input error: %s(errno: %d) And please input again\n", strerror(errno), errno); continue; } int op = 0; switch(iCmdType) { case 0: printf("request for thread to exit!\n"); op = 1; break; case 1: emit mycontroller->signalM->testControl("forward"); break; case 2: emit mycontroller->signalM->testControl("rewind"); break; case 3: emit mycontroller->signalM->testControl("playPause"); break; case 4: emit mycontroller->signalM->testControl("stop"); break; case 5: emit mycontroller->signalM->testControl("quit"); break; default: printf("unrecognized command!\n"); break; } if(op == 1) break; } return (void*)0; } Controller::Controller(QObject *parent) : QObject(parent) , m_iface(0) { qDebug() << "test cmd: 1 -> forward; 2 -> rewind; 3 -> playPause; 4 -> stop; 5 -> quit;"; pthread_t tid; pthread_create(&tid, NULL, request_controller_thread, NULL); QObject::connect(mycontroller->signalM, &SignalManager::testControl, this, [=] (const QString &cmd) { if (cmd == "forward") { this->seek_forward(10); } else if (cmd == "rewind") { this->seek_rewind(10); } else if (cmd == "playPause") { this->playPause(); } else if (cmd == "stop") { this->stop(); } else if (cmd == "quit") { this->quit(); } }); #if QT_VERSION >= 0x050000 m_iface = new QDBusInterface(CONTROL_DBUS_SERVICE_NAME, "/", CONTROL_DBUS_SERVICE_NAME, QDBusConnection::sessionBus(), this); //m_iface = new QDBusInterface(CONTROL_DBUS_SERVICE_NAME, "/com/kylin/kylinvideo/controller", CONTROL_DBUS_SERVICE_NAME, QDBusConnection::sessionBus(), this); if (!m_iface->isValid()) { fprintf(stderr, "%s\n", qPrintable(QDBusConnection::sessionBus().lastError().message())); QCoreApplication::instance()->quit(); } #endif } Controller::~Controller() { if (m_iface) { delete m_iface; m_iface = 0; } } void Controller::start(const QString &name, const QString &oldValue, const QString &newValue) { Q_UNUSED(oldValue); if (name != CONTROL_DBUS_SERVICE_NAME || newValue.isEmpty()) return; if (m_iface) { delete m_iface; m_iface = 0; } m_iface = new QDBusInterface(CONTROL_DBUS_SERVICE_NAME, "/", CONTROL_DBUS_SERVICE_NAME, QDBusConnection::sessionBus(), this); if (!m_iface->isValid()) { fprintf(stderr, "%s\n", qPrintable(QDBusConnection::sessionBus().lastError().message())); QCoreApplication::instance()->quit(); } //QDBusConnection::sessionBus().connect(CONTROL_DBUS_SERVICE_NAME, QString("/"), CONTROL_DBUS_SERVICE_NAME, QString("aboutToQuit"), this, SLOT(quit(QString))); connect(m_iface, SIGNAL(aboutToQuit()), QCoreApplication::instance(), SLOT(quit())); } void Controller::playPause() { m_iface->call("playPause"); } bool Controller::seek_forward(int seconds) { QDBusReply reply = m_iface->call("seek_forward", seconds); if (reply.isValid()) { qDebug() << "Reply was:" << reply.value().variant().toBool(); return reply.value().variant().toBool(); } else { if (m_iface->lastError().isValid()) fprintf(stderr, "Call failed: %s\n", qPrintable(m_iface->lastError().message())); } return false; } bool Controller::seek_rewind(int seconds) { QDBusReply reply = m_iface->call("seek_rewind", seconds); if (reply.isValid()) { qDebug() << "Reply was:" << reply.value().variant().toBool(); return reply.value().variant().toBool(); } else { if (m_iface->lastError().isValid()) fprintf(stderr, "Call failed: %s\n", qPrintable(m_iface->lastError().message())); } return false; } void Controller::stop() { m_iface->call("stop"); } void Controller::quit() { m_iface->call("quit"); } kylin-video/controllertest/controllertest.pro0000644000175000017500000000233113517016402020616 0ustar fengfengQT -= gui QT += core dbus network CONFIG += c++11 console CONFIG -= app_bundle # The following define makes your compiler emit warnings if you use # any feature of Qt which as been marked deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS # You can also make your code fail to compile if you use deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 target.source += $$TARGET target.path = /usr/bin INSTALLS += target QMAKE_CPPFLAGS *= $(shell dpkg-buildflags --get CPPFLAGS) QMAKE_CFLAGS *= $(shell dpkg-buildflags --get CFLAGS) QMAKE_CXXFLAGS *= $(shell dpkg-buildflags --get CXXFLAGS) QMAKE_LFLAGS *= $(shell dpkg-buildflags --get LDFLAGS) LIBS += -lpthread HEADERS += controller.h \ application.h \ signalmanager.h SOURCES += \ main.cpp \ controller.cpp \ application.cpp \ signalmanager.cpp unix { MOC_DIR = .moc OBJECTS_DIR = .obj } kylin-video/controllertest/controller.h0000644000175000017500000000236513517016402017354 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 CONTROLLER_H #define CONTROLLER_H #include #include class Controller: public QObject { Q_OBJECT public: explicit Controller(QObject *parent = 0); ~Controller(); public slots: void start(const QString &name, const QString &oldValue, const QString &newValue); void playPause(); bool seek_forward(int seconds); bool seek_rewind(int seconds); void stop(); void quit(); public: QDBusInterface *m_iface; }; #endif // CONTROLLER_H kylin-video/controllertest/main.cpp0000644000175000017500000000263513517016402016450 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "application.h" #include "controller.h" #include #include #include int main(int argc, char *argv[]) { Application a(argc, argv); if (!QDBusConnection::sessionBus().isConnected()) { fprintf(stderr, "Cannot connect to the D-Bus session bus.\n" "To start it, run:\n" "\teval `dbus-launch --auto-syntax`\n"); return 1; } Controller controller; #if QT_VERSION < 0x050000 QObject::connect(QDBusConnection::sessionBus().interface(), SIGNAL(serviceOwnerChanged(QString,QString,QString)), &controller, SLOT(start(QString,QString,QString))); #endif return a.exec(); } kylin-video/controllertest/signalmanager.h0000644000175000017500000000214513517016402017775 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 SIGNALMANAGER_H #define SIGNALMANAGER_H #include class SignalManager : public QObject { Q_OBJECT public: static SignalManager *Instance(); signals: void testControl(const QString &cmd); private: explicit SignalManager(QObject *parent = 0); private: static SignalManager *m_signalManager; }; #endif // SIGNALMANAGER_H kylin-video/controllertest/signalmanager.cpp0000644000175000017500000000206613517016402020332 0ustar fengfeng/* * Copyright (C) 2013 ~ 2019 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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 "signalmanager.h" SignalManager * SignalManager::m_signalManager = NULL; SignalManager *SignalManager::Instance() { if (m_signalManager == NULL) { m_signalManager = new SignalManager; } return m_signalManager; } SignalManager::SignalManager(QObject *parent) : QObject(parent) { } kylin-video/README.md0000644000175000017500000000361113637124061013213 0ustar fengfengkylin-video =========== Kylin Video utilizes MPV and MPlayer as background play engine (use MPV by default). Its GUI front end is written by Qt5. Plus, it supports both x86 and ARM platform. As a powerful video player, Kylin Video supports most of the audio and video formats. Functions of shortcut keys/ preview/ screenshot/ sound settings/ subtitles and so on are provided. Users can even customize settings as they like. ![image](./doc/appearence.png) Author's Home Page ============ [Eight Plus →](https://eightplus.github.io/) Installation ============ + qmake + make + sudo make install How to report bugs ================== Bugs should be report to the kylin-video bug tracking system: https://github.com/ukui/kylin-video/issues Snap ================== * snapcraft * snapcraft clean * sudo snap install kylin-video_1.1.6_amd64.snap --devmode * sudo snap install kylin-video_1.1.6_amd64.snap --classic --dangerous * sudo snap install kylin-video_1.1.6_amd64.snap --stable --dangerous * sudo snap remove kylin-video * unsquashfs -l kylin-video_1.1.6_amd64.snap | less * unsquashfs kylin-video_1.1.6_amd64.snap * 查看已经存在的plug及slot * snap interfaces * snapcraft plugins * snapcraft list-plugins * 处在snapcraft中最核心的是parts。parts是一些软件或数据被用来构造snap包的,或是用来编译其它软件的,每个part是由一个plugin来管理的,并且通常是互相独立的。 Git ================== 分支1.1.6 + 新建分支:git branch 1.1.6 + 切换分支:git checkout 1.1.6 (上述新建和切换分支的两条命令可合并成一条命令: git checkout -b 1.1.6) + 上传分支:git push origin 1.1.6 ts2po ================== 1. sudo apt install translate-toolkit 2. ts2po -i kylin-video_fr.ts -o kylin-video.pot 3. po2ts -i kylin-video_fr.po kylin-video_fr.ts TODO ================== + playlist: load_m3u load_pls loadXSPF VCD DVD kylin-video/NEWS0000644000175000017500000000566313524212777012453 0ustar fengfeng============== Version 2.0.0 ============== - Updated these modules: preferences, core, mplayerprocess and mpvprocess. - Rewrote playlist with model and delegate. - Added OSD info. - Optimized partial parameters for mpv and mplayer. - Supported Interface Size Tension. - Added new files, such as videowindow.cpp, autohidecursorwidget.cpp and displaylayercomposer.cpp. - Add remote controller dbus. ============== Version 1.1.0 ============== - Add Stereo mode for audio. - Add frame rotation for video. - Show logo normal(LP: #4979). - Display the correct shortcut key of increase volume or decrease volume(LP: #4916). - When the playing video file is removed from the playlist, then stop playing it(LP: #4915). - Solved the mouse drag problem for playlist items(LP: #4907). - Add Shortcut for the button of setting audio delay(LP: #4917). ============== Version 1.0.9 ============== - Support URL. - Optimize the aboutdialog. - Solved the problem that clicking on some buttons causes the interface to move sometimes. ============== Version 1.0.8 ============== - Solve the background problem of pause button. - Optimize the scrollbar for playlist. - if the state is pause in unfullscreen, then show title bar and control bar. - if the state is not pause and playing in fullscreen, then show title bar and control bar. - Show normal window size when the icon on the taskbar is clicked, because of the bug of Qt5. ============== Version 1.0.7 ============== - Set windown stay on top. - Add play order swither. - Add help page. - Add more shortcuts, such as full screen, playlist, about and exit. - Resolve the problem that text color settings is invalid of QComboBox. - Deal with the log records. ============== Version 1.0.6 ============== - Add open screenshots action into systemtray. - Make the seek position work properly when using Mplayer. - Rewrite mainwindow with QStackedLayout. - Show detail info when the file does not exist(LP: #4372). - Resize TipWidget depending on the length of the tip text. - Show screenshot's information when it is saved successfully. - Add shortcut key notes. - Add Preview. ============== Version 1.0.5 ============== - Add slot function for some actions. - Resolved the problem of selecting item is inaccurate when open files in different ways. - Modify progressbar. - Add error tip for the file has been removed from disk which double click play. - Add MessageDialog. - Modify QComboBox qss. - Remove Qt::ToolTip from TipWidget, make it be inside the mainwindow, but it's not transparent at this time. - Add tip when remove file from playlist. - Fixed some bugs. ============== Version 1.0.4 ============== - Support MPV. - Support auto restart when the playback engine changed. ============== Version 1.0.3 ============== - Update sub interfaces. - Update menu qss. ============== Version 1.0.2 ============== - Update the main interface. ============== Version 1.0.0 ============== - A great MPlayer front-end with Qt5. kylin-video/autogen.sh0000755000175000017500000000013413524205650013731 0ustar fengfeng#! /bin/sh # Run this to generate all the initial makefiles, etc. lrelease kylin-video.pro