pax_global_header00006660000000000000000000000064135112541410014507gustar00rootroot0000000000000052 comment=95f7b623a43b5064f416f2cf5b1514386e0306ac deepin-movie-reborn-5.0.0/000077500000000000000000000000001351125414100153575ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/.clog.toml000066400000000000000000000001731351125414100172570ustar00rootroot00000000000000[clog] repository = "https://github.com/linuxdeepin/deepin-movie-reborn" from-latest-tag = true changelog = "CHANGELOG.md" deepin-movie-reborn-5.0.0/.gitignore000066400000000000000000000003231351125414100173450ustar00rootroot00000000000000.vim-undo *~ *.qm *.swp .*~ build .zcache debian/debhelper-build-stamp debian/deepin-movie-reborn.debhelper.log debian/deepin-movie-reborn.substvars debian/deepin-movie-reborn/ debian/files CMakeLists.txt.user deepin-movie-reborn-5.0.0/.tx/000077500000000000000000000000001351125414100160705ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/.tx/config000066400000000000000000000006261351125414100172640ustar00rootroot00000000000000[main] host = https://www.transifex.com minimum_perc = 80 mode = developer [deepin-movie.deepin-movie_v3] file_filter = src/translations/deepin-movie_.ts source_file = src/translations/deepin-movie.ts source_lang = en type = QT [deepin-movie.deepin-movie-desktop] file_filter = src/translations/desktop/desktop_.ts source_file = src/translations/desktop/desktop.ts source_lang = en type = QT deepin-movie-reborn-5.0.0/.tx/ts2desktop000066400000000000000000000002571351125414100201210ustar00rootroot00000000000000DESKTOP_TEMP_FILE=src/deepin-movie.desktop.tmp DESKTOP_SOURCE_FILE=src/deepin-movie.desktop DESKTOP_DEST_FILE=src/deepin-movie.desktop DESKTOP_TS_DIR=src/translations/desktop deepin-movie-reborn-5.0.0/.ycm_extra_conf.py000066400000000000000000000107751351125414100210210ustar00rootroot00000000000000import os import ycm_core # These are the compilation flags that will be used in case there's no # compilation database set (by default, one is not set). # CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR. flags = [ '-Wall', '-DNDEBUG', # THIS IS IMPORTANT! Without a "-std=" flag, clang won't know which # language to use when compiling headers. So it will guess. Badly. So C++ # headers will be compiled as C headers. You don't want that so ALWAYS specify # a "-std=". # For a C project, you would set this to something like 'c99' instead of # 'c++11'. '-std=c++11', # ...and the same thing goes for the magic -x option which specifies the # language that the files to be compiled are written in. This is mostly # relevant for c++ headers. # For a C project, you would set this to 'c' instead of 'c++'. '-x', 'c++', '-isystem', '/usr/include/c++/6', '-isystem', '/usr/include/x86_64-linux-gnu/c++/6', '-isystem', '/usr/include/c++/6/backward', '-isystem', '/usr/lib/gcc/x86_64-linux-gnu/6/include', '-isystem', '/usr/local/include', '-isystem', '/usr/lib/gcc/x86_64-linux-gnu/6/include-fixed', '-isystem', '/usr/include/x86_64-linux-gnu', '-isystem', '/usr/include' ] # Set this to the absolute path to the folder (NOT the file!) containing the # compile_commands.json file to use that instead of 'flags'. See here for # more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html # # Most projects will NOT need to set this to anything; you can just change the # 'flags' list of compilation flags. Notice that YCM itself uses that approach. compilation_database_folder = '/home/sonald/stage/deepin-movie-reborn/build' #compilation_database_folder = '' if os.path.exists( compilation_database_folder ): database = ycm_core.CompilationDatabase( compilation_database_folder ) else: database = None SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ] def DirectoryOfThisScript(): return os.path.dirname( os.path.abspath( __file__ ) ) def MakeRelativePathsInFlagsAbsolute( flags, working_directory ): if not working_directory: return list( flags ) new_flags = [] make_next_absolute = False path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ] for flag in flags: new_flag = flag if make_next_absolute: make_next_absolute = False if not flag.startswith( '/' ): new_flag = os.path.join( working_directory, flag ) for path_flag in path_flags: if flag == path_flag: make_next_absolute = True break if flag.startswith( path_flag ): path = flag[ len( path_flag ): ] new_flag = path_flag + os.path.join( working_directory, path ) break if new_flag: new_flags.append( new_flag ) return new_flags def IsHeaderFile( filename ): extension = os.path.splitext( filename )[ 1 ] return extension in [ '.h', '.hxx', '.hpp', '.hh' ] def GetCompilationInfoForFile( filename ): # The compilation_commands.json file generated by CMake does not have entries # for header files. So we do our best by asking the db for flags for a # corresponding source file, if any. If one exists, the flags for that file # should be good enough. if IsHeaderFile( filename ): basename = os.path.splitext( filename )[ 0 ] for extension in SOURCE_EXTENSIONS: replacement_file = basename + extension if os.path.exists( replacement_file ): compilation_info = database.GetCompilationInfoForFile( replacement_file ) if compilation_info.compiler_flags_: return compilation_info return None return database.GetCompilationInfoForFile( filename ) def FlagsForFile( filename, **kwargs ): if database: # Bear in mind that compilation_info.compiler_flags_ does NOT return a # python list, but a "list-like" StringVec object compilation_info = GetCompilationInfoForFile( filename ) if not compilation_info: return None final_flags = MakeRelativePathsInFlagsAbsolute( compilation_info.compiler_flags_, compilation_info.compiler_working_dir_ ) # NOTE: This is just for YouCompleteMe; it's highly likely that your project # does NOT need to remove the stdlib flag. DO NOT USE THIS IN YOUR # ycm_extra_conf IF YOU'RE NOT 100% SURE YOU NEED IT. #try: #final_flags.remove( '-stdlib=libc++' ) #except ValueError: #pass else: relative_to = DirectoryOfThisScript() final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to ) return { 'flags': final_flags, 'do_cache': True } deepin-movie-reborn-5.0.0/CHANGELOG.md000066400000000000000000000311241351125414100171710ustar00rootroot00000000000000 ## 3.2.24 (2019-06-20) #### Bug Fixes * card0 may not enabled/usable ([d71a0a60](https://github.com/linuxdeepin/deepin-movie-reborn/commit/d71a0a606a3f7c9ac27cbe2c05698b9adba39cec)) ## 3.2.23.2 (2019-06-01) #### Bug Fixes * Should free xcb_query_pointer_reply return pointer ([5541d969](https://github.com/linuxdeepin/deepin-movie-reborn/commit/5541d96916fe8fbb04835e507f935718f2530d08)) ## 3.2.23.1 (2019-06-01) #### Bug Fixes * workaround for QTBUG-76114. ([bfeb745f](https://github.com/linuxdeepin/deepin-movie-reborn/commit/bfeb745f3832e64b29488db9cad884348dd5b531)) * missing settings item added. Fixes crash on file open. ([c2ed22ce](https://github.com/linuxdeepin/deepin-movie-reborn/commit/c2ed22ce85e7b8a4b7e225bf84ca3c5c6862a4a3)) ## 3.2.23 (2019-05-23) #### Bug Fixes * thumbnail previewer caused dock show up ([b4e511dc](https://github.com/linuxdeepin/deepin-movie-reborn/commit/b4e511dcef19f2d614939eb9914f23d6a4ee69e9)) #### Features * Drag and drop to load subtitle ([13b8166d](https://github.com/linuxdeepin/deepin-movie-reborn/commit/13b8166d36e04216e302e44fd69bf3d7f7c93b9f)) * remember last opened path ([46a7c66e](https://github.com/linuxdeepin/deepin-movie-reborn/commit/46a7c66e1676a1f24e385590fd58065efb64c9d3)) ## 3.2.22.1 (2019-04-19) ## 3.2.22 (2019-04-10) ## 3.2.21 (2019-03-27) ## 3.2.20 (2019-02-25) #### Bug Fixes * buttons not shwon in mini mode on arm64 platform ([572d7b37](https://github.com/linuxdeepin/deepin-movie-reborn/commit/572d7b37034ec8940160692755cfbe6f56cb6802)) ## 3.2.19 (2019-01-25) #### Bug Fixes * can not toggle mini mode when window maximized ([b70157f9](https://github.com/linuxdeepin/deepin-movie-reborn/commit/b70157f952108f712499b61e33d65931fac3d263)) ## 3.2.18 (2019-01-03) #### Bug Fixes * don't sleep while playing. ([0f478021](https://github.com/linuxdeepin/deepin-movie-reborn/commit/0f478021e4830a0fc88f671f8e12015d68bcc292)) #### Features * new subtitle font style. ([ebf1a19b](https://github.com/linuxdeepin/deepin-movie-reborn/commit/ebf1a19bc08c1499dcb59d2fcf0e28c9fa5f7e31)) ## 3.2.17 (2018-12-13) #### Bug Fixes * the window point not follow touch point on touch screen and enable hi-DPI ([ec17cf18](https://github.com/linuxdeepin/deepin-movie-reborn/commit/ec17cf18464727df3d31ab404ca1e169bc8fe046)) ## 3.2.16.1 (2018-12-07) #### Bug Fixes * remove application name in titlebar ([5c290d6c](https://github.com/linuxdeepin/deepin-movie-reborn/commit/5c290d6c85a2810f0437e4fc5ab01a09eb6fa91b)) ## 3.2.16 (2018-11-27) #### Bug Fixes * set the generic name to "Movie" ([704c7a78](https://github.com/linuxdeepin/deepin-movie-reborn/commit/704c7a78e7efe505d511704a158f20c38ee534cb)) #### Features * support auto translate the dekstop file ([2b8a971a](https://github.com/linuxdeepin/deepin-movie-reborn/commit/2b8a971ad4c46853b3b24da92a1c6432a4cd04b1)) ## 3.2.15 (2018-11-26) #### Features * Deepin vendor support ([7c0e2088](https://github.com/linuxdeepin/deepin-movie-reborn/commit/7c0e208832624d27cb340c6cebfefc0dbbc4c064)) * support the recent file spec. ([b278820e](https://github.com/linuxdeepin/deepin-movie-reborn/commit/b278820eef209d1fe485304d31f00766e0fdc0e8)) * support touch move window ([e443a7b6](https://github.com/linuxdeepin/deepin-movie-reborn/commit/e443a7b6f4e5f9c5828f05786d6fa4ff5b680e18)) ## 3.2.14 (2018-11-01) #### Bug Fixes * no transifex ([dbfe0115](dbfe0115)) * build error with libavresample deprecated ([9797db07](9797db07)) ## 3.2.13 (2018-10-30) #### Bug Fixes * crash when press F1 ([407dbb54](407dbb54)) ## 3.2.12 (2018-10-26) * refactor: use DApplication::handleHelpAction to open help document ## 3.2.11 (2018-10-25) #### Bug Fixes * remove the TitleBar right margin ([17de875f](17de875f)) ## 3.2.10 (2018-09-14) * maintainance tag ## 3.2.9 (2018-08-08) * fix(libdmr): bypass sub saving and compilation ## 3.2.8 (2018-07-20) #### Features * add frame-by-frame navigation support ([57e07793](57e07793)) ## 3.2.7 (2018-06-07) #### Features * run async append job conditionally ([d2d9528a](d2d9528a)) * **libdmr:** support pause on start ([518d453f](518d453f)) ## 3.2.5 (2018-05-04) #### Bug Fixes * check texture existence ([883f1897](883f1897)) ## 3.2.4 (2018-05-04) #### Features * expose setProperty from player engine ([6258d3a7](6258d3a7)) * do not show filter details ([3f16112f](3f16112f)) * **engine:** disable rounding for libdmr ([6b0f9e83](6b0f9e83)) * **libdmr:** * allow replay if keep-open and eof reached ([4bbbf829](4bbbf829)) * set interop from variable ([6ddcebee](6ddcebee)) * disable rounding by default ([ac925cb3](ac925cb3)) #### Bug Fixes * release gl resources ([be91122c](be91122c)) * handle drag back to normal resizing ([d5d8511a](d5d8511a)) * update fbo correctly ([28e84e43](28e84e43)) * do resize by constraints properly ([78609381](78609381)) * restore size correctly after quitting fs ([8c802ef8](8c802ef8)) * remove Build-Depends ([568d26ce](568d26ce)) ## 3.2.3 (2018-03-14) #### Bug Fixes * keep pending url until related signal received ([4a720619](4a720619)) * hide cursor only main window is focused ([f9714f2a](f9714f2a)) * movieinfo style ([64f6d4d7](64f6d4d7)) ## 3.2.2 (2018-03-09) ## 3.2.1 (2018-03-07) #### Bug Fixes * the close button is invisible of the settings dialog ([f581a3fd](f581a3fd)) * update dtkcore build depends ([d3751cff](d3751cff)) #### Features * add manual id ([8ab9f188](8ab9f188)) ## 3.2.0.3 (2018-01-16) #### Features * use hidpi pixmaps ([d18fc7cf](d18fc7cf)) ## 3.2.0.2 (2018-01-04) #### Features * provide better interop support ([78cb8159](78cb8159)) ## 3.2.0.1 (2018-01-02) #### Bug Fixes * load from cached thumb stream ([b437995e](b437995e)) ## 3.2.0 (2017-12-28) #### Bug Fixes * minor changes ([dc9306ab](dc9306ab)) * to leave progress bar when preview hide ([27b4c9a9](27b4c9a9)) * url comparison and signleloop mode ([1bc0f553](1bc0f553)) * handle context menu event correctly ([40b2e9ae](40b2e9ae)) * optimize drag to resize process ([0e85688f](0e85688f)) * use correct font to do text eliding ([172a3537](172a3537)) * optimize drop handling ([d4a6bcac](d4a6bcac)) * optimize _lastRectInNormalMode tracking ([b97246c9](b97246c9)) * should init debug level before instantiation ([78d432e2](78d432e2)) * make play state animation smooth ([d4f08feb](d4f08feb)) * adjust process of toggleUIMode ([bded982f](bded982f)) * check and emit an enter when necessary ([71ba3b88](71ba3b88)) * remove over-detailed CMakeLists options ([ee9fad4e](ee9fad4e)) * sliderMoved occasionally isn't signalled ([9b0d1047](9b0d1047)) * potential conflict with kwin ([bd43d2df](bd43d2df)) * Adapt lintian ([128cc039](128cc039)) #### Features * update shadow with focus change ([dac097c6](dac097c6)) * support dxcb mode ([3c97643e](3c97643e)) * quit fs to maximized state if it was ([fcf13d3f](fcf13d3f)) * remember playlist position when quit ([c7d8fe1b](c7d8fe1b)) * play state animation ([d2f68123](d2f68123)) * dynamic slider expansion animation ([e89450f7](e89450f7)) * **dxcb:** * smooth resizing ([d68be4e7](d68be4e7)) * better dxcb support ([b7171b1c](b7171b1c)) ## 3.1.1 (2017-12-13) #### Features * use better ElideText for movie info ([544ccc94](544ccc94)) * improve preview and progress bar design ([f0c70499](f0c70499)) * set debug log level for backend ([0315115b](0315115b)) * disable maximization in mini mode ([0ebc63f2](0ebc63f2)) * drag to restore ([06f20bfe](06f20bfe)) #### Bug Fixes * PreviewOnMouseover does not affect indicator ([8a685cc3](8a685cc3)) * allow suspendToolsWindow on title area in fs ([804a52e5](804a52e5)) * disable indicator on idle ([865a230e](865a230e)) * external sub loading and titlbar state ([f2d85d2f](f2d85d2f)) * reduce resize request ([8bb48f72](8bb48f72)) * allow resumeToolsWindow when playlist opened ([f69873a2](f69873a2)) * try fully encoded url first ([8fbde1fd](8fbde1fd)) * do not restore to idle size in mini mode ([3b4cd454](3b4cd454)) * make url dialog centered around main window ([20ded42e](20ded42e)) * db and cache info init ([62fe66f5](62fe66f5)) * **workaround:** bypass mouse event from other source ([077c110f](077c110f)) ## 3.0.2 (2017-12-11) #### Bug Fixes * switchPosition: reset _last if _current changed ([7448c66b](7448c66b)) * sync to save global state ([a99f2003](a99f2003)) * do not popup context menu from titlebar ([ab8bea72](ab8bea72)) * update _current after position switch ([892c2e75](892c2e75)) * workaround a drop indicator issue ([abf87d9e](abf87d9e)) * disable panscan in fs or maximized state ([3e04bd11](3e04bd11)) * take care filename input format ([6605e277](6605e277)) * on restore to default in normal state ([4d2377bd](4d2377bd)) * wrong conditional compilation ([5e69c0cc](5e69c0cc)) * use two variables to track mouse state ([27087d03](27087d03)) * adjust popup according to TOOLBOX_TOP_EXTENT ([179b5ae2](179b5ae2)) * delay toggling playlist when return to fs ([bd30d9b6](bd30d9b6)) * expand playlist into invisble extent of toolbox ([76216161](76216161)) * correct drag to maximize behaviour ([96d74eed](96d74eed)) * a few minor changes ([eb7bd68f](eb7bd68f)) #### Features * primitive caching scheme for playlist items ([30161b36](30161b36)) * show unique icon for different kinds of urls ([53586c03](53586c03)) * support playlist item repositioning ([1fcd1c26](1fcd1c26)) * reset last valid size when new vidoe loaded ([e6eaa49b](e6eaa49b)) * honor video metadata for rotation ([71f5d4e5](71f5d4e5)) * adjust playlist geometry when toggling fs ([f6d10a90](f6d10a90)) * remember both size and pos of last spot ([5d62d0f4](5d62d0f4)) * only show size notif for manual resizing ([ec7bf9f3](ec7bf9f3)) * sync above state with wm ([db49fa40](db49fa40)) * hide popup when turn to inactive state ([1f294ef7](1f294ef7)) * expand slider response area even wider ([f703dce2](f703dce2)) * restore to default size when idle ([fce147c2](fce147c2)) * make response area of slider look wider ([aca6eefd](aca6eefd)) * expand progress response area ([bb6f3f92](bb6f3f92)) * support libdmr.pc ([e16a3944](e16a3944)) * enable libdmr to override composite mode ([cfd1058e](cfd1058e)) * make video full the whole framebuffer ([1fcb45f3](1fcb45f3)) * libdmr interface usage demo ([88d9654b](88d9654b)) * split core function into libdmr ([c37f3dc1](c37f3dc1)) ## 3.0.1 (2017-11-27) #### Bug Fixes * potential crash when closing a smb shared video ([0318ec7e](0318ec7e)) #### Features * update playlist geometry under flatpak env ([ecf257c9](ecf257c9)) ## 3.0 (2017-11-21) #### Features * make sub font size approximate pixel size ([977f6733](977f6733)) ## 2.9.98 (2017-11-21) #### Bug Fixes * improve 4k playback by disable opengl-hq ([d3f222a7](d3f222a7)) * update svgs and more QImageReader migration ([93fa0caa](93fa0caa)) #### Features * make play state button clickable ([26b25be8](26b25be8)) * hide titlebar in fullscreen playback ([1a86fbd3](1a86fbd3)) * render HiDPI texture by QImageReader ([2dfe3c0d](2dfe3c0d)) * use QImageReader to render HiDPI images ([a8afaa64](a8afaa64)) ## 2.9.97 (2017-11-16) #### Bug Fixes * correct shape mask in non-composited mode ([86397bf2](86397bf2)) #### Features * use vaapi_egl opengl interop when possible ([632afdf9](632afdf9)) * support build with DTK_DMAN_PORTAL ([05a19b86](05a19b86)) * support dman activation from flatpak env ([eb548afc](eb548afc)) ## 2.9.96 (2017-11-09) #### Bug Fixes * check cookie before inhibit ([573ba280](573ba280)) * cookie should be unsigned int ([220231a6](220231a6)) * check and do UnInhibit when window closed ([81110c29](81110c29)) ## 2.9.95 (2017-11-02) #### Bug Fixes * pixmap take device ratio into account ([f6b851e4](f6b851e4)) * make toolbox more transparent ([06174b58](06174b58)) #### Features * scale fbo according to devicePixelRatio ([03307290](03307290)) * honor devicePixelRatio for pixmap rendering ([e0390a35](e0390a35)) * basic hdpi texture adaption ([86e09a82](86e09a82)) * support flatpak ([842b8a7b](842b8a7b)) * respect devicePixelRatio when move ([373f48ce](373f48ce)) deepin-movie-reborn-5.0.0/CMakeLists.txt000066400000000000000000000015661351125414100201270ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.0) project(deepin-movie-reborn VERSION 3.2.7) option(USE_DXCB "integration with dxcb platform plugin" OFF) option(DMR_DEBUG "turn on debug output" off) option(DTK_DMAN_PORTAL "turn on dman portal support" off) execute_process(COMMAND uname -m OUTPUT_VARIABLE MACH ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) if (CMAKE_BUILD_TYPE STREQUAL "Debug") set(DMR_DEBUG on) endif() if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") endif() set(CMAKE_EXPORT_COMPILE_COMMANDS on) find_package(PkgConfig REQUIRED) # Find includes in corresponding build directories set(CMAKE_INCLUDE_CURRENT_DIR ON) include_directories(${PROJECT_BINARY_DIR}) include_directories(${PROJECT_SOURCE_DIR}) configure_file(${PROJECT_SOURCE_DIR}/config.h.in ${PROJECT_BINARY_DIR}/config.h @ONLY) add_subdirectory(src) deepin-movie-reborn-5.0.0/HACKING.md000066400000000000000000000003631351125414100167470ustar00rootroot00000000000000# HACKING guide for Deepin Movie ## Project layout ### Coding layout Deepin Movie developed by Qt(QWidget). ### Others ## Core Design ## List of TODO (It’s the good way for contributing) None. ## List of Workaround None. ## Others deepin-movie-reborn-5.0.0/LICENSE000066400000000000000000001060421351125414100163670ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . In addition, as a special exception, the copyright holders give permission to link the code of portions of this program with the OpenSSL library under certain conditions as described in each individual source file, and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than OpenSSL. If you modify file(s) with this exception, you may extend this exception to your version of the file(s), but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. If you delete this exception statement from all source files in the program, then also delete it here. deepin-movie-reborn-5.0.0/LICENSE.OpenSSL000066400000000000000000000152421351125414100176520ustar00rootroot00000000000000Certain source files in this program permit linking with the OpenSSL library (http://www.openssl.org), which otherwise wouldn't be allowed under the GPL. For purposes of identifying OpenSSL, most source files giving this permission limit it to versions of OpenSSL having a license identical to that listed in this file (LICENSE.OpenSSL). It is not necessary for the copyright years to match between this file and the OpenSSL version in question. However, note that because this file is an extension of the license statements of these source files, this file may not be changed except with permission from all copyright holders of source files in this program which reference this file. LICENSE ISSUES ============== The OpenSSL toolkit stays under a double license, i.e. both the conditions of the OpenSSL License and the original SSLeay license apply to the toolkit. See below for the actual license texts. OpenSSL License --------------- /* ==================================================================== * Copyright (c) 1998-2017 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. 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. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" * * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * openssl-core@openssl.org. * * 5. Products derived from this software may not be called "OpenSSL" * nor may "OpenSSL" appear in their names without prior written * permission of the OpenSSL Project. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit (http://www.openssl.org/)" * * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY * EXPRESSED 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 OpenSSL PROJECT OR * ITS 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. * ==================================================================== * * This product includes cryptographic software written by Eric Young * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). * */ Original SSLeay License ----------------------- /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written * by Eric Young (eay@cryptsoft.com). * The implementation was written so as to conform with Netscapes SSL. * * This library is free for commercial and non-commercial use as long as * the following conditions are adhered to. The following conditions * apply to all code found in this distribution, be it the RC4, RSA, * lhash, DES, etc., code; not just the SSL code. The SSL documentation * included with this distribution is covered by the same copyright terms * except that the holder is Tim Hudson (tjh@cryptsoft.com). * * Copyright remains Eric Young's, and as such any Copyright notices in * the code are not to be removed. * If this package is used in a product, Eric Young should be given attribution * as the author of the parts of the library used. * This can be in the form of a textual message at program startup or * in documentation (online or textual) provided with the package. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * "This product includes cryptographic software written by * Eric Young (eay@cryptsoft.com)" * The word 'cryptographic' can be left out if the routines from the library * being used are not cryptographic related :-). * 4. If you include any Windows specific code (or a derivative thereof) from * the apps directory (application code) you must include an acknowledgement: * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" * * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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. * * The licence and distribution terms for any publicly available version or * derivative of this code cannot be changed. i.e. this code cannot simply be * copied and put under another distribution licence * [including the GNU Public Licence.] */ deepin-movie-reborn-5.0.0/README.md000066400000000000000000000024661351125414100166460ustar00rootroot00000000000000# Deepin movie Deepin movie is Deepin Desktop Environment Movie Player. ## Dependencies ### Build dependencies * cmake * qt5 * ffmpeg * mpv ### Runtime dependencies * Qt5 (>= 5.3) * Qt5-X11extras * mpv ## Installation ### Build from source code 1. Make sure you have installed all dependencies. 2. Build: ``` $ cd deepin-movie-reborn $ mkdir Build $ cd Build $ cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=/usr .. $ make ``` 3. Install: ``` $ sudo make install ``` When install complete, the executable binary file is placed into `/usr/bin/deepin-movie`. ## Getting help Any usage issues can ask for help via * [Gitter](https://gitter.im/orgs/linuxdeepin/rooms) * [IRC Channel](https://webchat.freenode.net/?channels=deepin) * [Official Forum](https://bbs.deepin.org/) * [Wiki](https://wiki.deepin.org/) ## Getting involved We encourage you to report issues and contribute changes * [Contribution guide for developers](https://github.com/linuxdeepin/developer-center/wiki/Contribution-Guidelines-for-Developers-en). (English) * [å¼€å‘者代ç è´¡çŒ®æŒ‡å—](https://github.com/linuxdeepin/developer-center/wiki/Contribution-Guidelines-for-Developers) (中文) ## License Deepin Movie is licensed under [GPLv3](LICENSE) with [OpenSSL exception](https://lists.debian.org/debian-legal/2004/05/msg00595.html). deepin-movie-reborn-5.0.0/config.h.in000066400000000000000000000004411351125414100174010ustar00rootroot00000000000000#ifndef __CONFIG_H__ #define __CONFIG_H__ /* configured by cmake, do not edit */ #define DMR_VERSION "@PROJECT_VERSION@" #cmakedefine USE_DXCB 1 #cmakedefine DMR_DEBUG /* only defined when build with flatpak */ #cmakedefine DTK_DMAN_PORTAL #define RADIUS 4 #endif /* __CONFIG_H__ */ deepin-movie-reborn-5.0.0/debian/000077500000000000000000000000001351125414100166015ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/debian/changelog000066400000000000000000000002161351125414100204520ustar00rootroot00000000000000deepin-movie-reborn (3.0.0-1) unstable; urgency=low * First release. -- Sian Cao Wed, 15 Mar 2017 16:40:00 +0800 deepin-movie-reborn-5.0.0/debian/compat000066400000000000000000000000021351125414100177770ustar00rootroot000000000000009 deepin-movie-reborn-5.0.0/debian/control000066400000000000000000000024331351125414100202060ustar00rootroot00000000000000Source: deepin-movie-reborn Section: libdevel Priority: extra Maintainer: Deepin Packages Builder Build-Depends: debhelper, cmake, pkg-config, qttools5-dev-tools, libqt5svg5-dev, qtmultimedia5-dev, qttools5-dev, libqt5x11extras5-dev, libdtkcore-bin, libdtkwidget-dev, libqt5sql5-sqlite, libmpv-dev, libxcb1-dev, libxcb-util0-dev, libffmpegthumbnailer-dev, libxcb-shape0-dev,libxcb-ewmh-dev, xcb-proto, x11proto-record-dev, libxtst-dev, libavcodec-dev, libavformat-dev,libavutil-dev, libpulse-dev, libssl-dev, libdvdnav-dev Standards-Version: 3.9.8 Homepage: https://www.deepin.org/ Package: deepin-movie Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: movie player movie player for deepin desktop environment. Package: libdmr Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Multi-Arch: same Description: movie player widget library deepin movie player widget library Package: libdmr-dev Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, libdmr(=${binary:Version}) Description: movie player widget library development headers deepin movie player widget library development headers deepin-movie-reborn-5.0.0/debian/copyright000066400000000000000000000035641351125414100205440ustar00rootroot00000000000000Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: deepin-movie-reborn Source: https://github.com/linuxdeepin/deepin-movie-reborn Files: * Copyright: 2012 huoshaohui@linuxdeepin.com 2011-2012 wangyong@deepin.com 2012-2017, Deepin Technology Co., Ltd. License: GPL-3+ with OpenSSL exception Files: debian/* Copyright: Deepin Sysdev 2017 Boyuan Yang <073plan@gmail.com> License: GPL-3+ with OpenSSL exception License: GPL-3+ with OpenSSL exception This package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. . In addition, as a special exception, the author of this program gives permission to link the code of its release with the OpenSSL project's "OpenSSL" library (or with modified versions of it that use the same license as the "OpenSSL" library), and distribute the linked executables. You must obey the GNU General Public License in all respects for all of the code used other than "OpenSSL". If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. . This package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. . You should have received a copy of the GNU General Public License along with this program. If not, see . On Debian systems, the complete text of the GNU General Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". deepin-movie-reborn-5.0.0/debian/deepin-movie.install000066400000000000000000000001741351125414100225540ustar00rootroot00000000000000usr/bin/deepin-movie usr/share/applications/deepin-movie.desktop usr/share/deepin-movie/translations/*.qm usr/share/icons/* deepin-movie-reborn-5.0.0/debian/libdmr-dev.install000066400000000000000000000001111351125414100222070ustar00rootroot00000000000000usr/include/libdmr/*.h usr/lib/*/libdmr.so usr/lib/*/pkgconfig/libdmr.pc deepin-movie-reborn-5.0.0/debian/libdmr.install000066400000000000000000000000261351125414100214400ustar00rootroot00000000000000usr/lib/*/libdmr.so.* deepin-movie-reborn-5.0.0/debian/rules000077500000000000000000000003701351125414100176610ustar00rootroot00000000000000#!/usr/bin/make -f export QT_SELECT=5 DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) %: dh $@ override_dh_auto_configure: dh_auto_configure -- -DCMAKE_INSTALL_PREFIX=/usr -DUSE_DXCB=off -DCMAKE_BUILD_TYPE=ReLWithDebInfo deepin-movie-reborn-5.0.0/debian/source/000077500000000000000000000000001351125414100201015ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/debian/source/format000066400000000000000000000000151351125414100213100ustar00rootroot000000000000003.0 (native) deepin-movie-reborn-5.0.0/src/000077500000000000000000000000001351125414100161465ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/src/CMakeLists.txt000066400000000000000000000055021351125414100207100ustar00rootroot00000000000000set(CMAKE_AUTOMOC ON) set(CMD_NAME deepin-movie) set(PROJECT_INCLUDE ${PROJECT_SOURCE_DIR}/src/widgets ${PROJECT_SOURCE_DIR}/src/common ${PROJECT_SOURCE_DIR}/src/libdmr) include_directories(${CMAKE_INCLUDE_CURRENT_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR}) find_package(Qt5Widgets) find_package(Qt5DBus) find_package(Qt5X11Extras) find_package(Qt5LinguistTools) find_package(Qt5Network) find_package(Qt5Concurrent) find_package(Qt5Sql) pkg_check_modules(Dtk REQUIRED IMPORTED_TARGET dtkwidget) pkg_check_modules(Dtk REQUIRED IMPORTED_TARGET dtkcore) pkg_check_modules(Mpv REQUIRED IMPORTED_TARGET mpv) pkg_check_modules(Xcb REQUIRED IMPORTED_TARGET xcb xcb-aux xcb-proto xcb-ewmh xcb-shape) pkg_check_modules(AV REQUIRED IMPORTED_TARGET libavformat libavutil libavcodec) # IMPORTED_TARGET failed to work for some of libs under flatpak env pkg_check_modules(Other REQUIRED libffmpegthumbnailer libpulse libpulse-simple openssl dvdnav) qt5_add_resources(RCS resources.qrc) if (${Dtk_VERSION} LESS 2.0.6.1) qt5_add_resources(RCS theme.qrc) endif() file(GLOB_RECURSE SRCS LIST_DIRECTORIES false common/*.cpp widgets/*.cpp libdmr/*.cpp) list(APPEND SRCS main.cpp) # mpv backend file(GLOB_RECURSE MPV_SRCS LIST_DIRECTORIES false backends/mpv/*.cpp) list(APPEND SRCS ${MPV_SRCS}) list(APPEND PROJECT_INCLUDE ${PROJECT_SOURCE_DIR}/src/backends/mpv) #~ add_custom_target(json_i18n ALL /usr/lib/dtk2/dtk-settings resources/data/settings.json -o common/settings_translation.cpp COMMAND sed -i "s,#include .*,#include ," common/settings_translation.cpp VERBATIM SOURCES resources/data/settings.json WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/) ## translations file(GLOB TS LIST_DIRECTORIES false translations/${CMD_NAME}*.ts) set_source_files_properties(${TS} PROPERTIES OUTPUT_LOCATION ${PROJECT_SOURCE_DIR}/src/translations) if (NOT (${CMAKE_BUILD_TYPE} MATCHES "Debug")) qt5_create_translation(QM ${SRCS} ${TS}) endif () # ~ add_executable(${CMD_NAME} ${SRCS} ${RCS} ${QM}) add_dependencies(${CMD_NAME} json_i18n) target_include_directories(${CMD_NAME} PUBLIC ${PROJECT_INCLUDE}) set(TARGET_LIBS X11 Xext Xtst PkgConfig::Xcb Qt5::Widgets Qt5::X11Extras Qt5::Network Qt5::Concurrent Qt5::DBus Qt5::Sql PkgConfig::Dtk PkgConfig::Mpv PkgConfig::AV pthread GL) target_link_libraries(${CMD_NAME} ${TARGET_LIBS} ${Other_LIBRARIES}) install(TARGETS ${CMD_NAME} DESTINATION bin) install(DIRECTORY ${PROJECT_SOURCE_DIR}/src/translations DESTINATION share/${CMD_NAME} FILES_MATCHING PATTERN "*.qm") install(FILES ${PROJECT_SOURCE_DIR}/src/deepin-movie.desktop DESTINATION share/applications) install(FILES ${PROJECT_SOURCE_DIR}/src/resources/icons/logo-big.svg DESTINATION share/icons/hicolor/scalable/apps RENAME deepin-movie.svg) add_subdirectory(libdmr) add_subdirectory(test) deepin-movie-reborn-5.0.0/src/backends/000077500000000000000000000000001351125414100177205ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/src/backends/mpv/000077500000000000000000000000001351125414100205225ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/src/backends/mpv/mpv_glwidget.cpp000066400000000000000000000551551351125414100237310ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "config.h" #include "mpv_proxy.h" #include "mpv_glwidget.h" #include #include #include DWIDGET_USE_NAMESPACE static const char* vs_blend = R"( attribute vec2 position; attribute vec2 vTexCoord; varying vec2 texCoord; void main() { gl_Position = vec4(position, 0.0, 1.0); texCoord = vTexCoord; } )"; static const char* fs_blend = R"( varying vec2 texCoord; uniform sampler2D movie; void main() { gl_FragColor = texture2D(movie, texCoord); } )"; static const char* vs_blend_corner = R"( attribute vec2 position; attribute vec2 maskTexCoord; attribute vec2 vTexCoord; varying vec2 maskCoord; varying vec2 texCoord; void main() { gl_Position = vec4(position, 0.0, 1.0); texCoord = vTexCoord; maskCoord = maskTexCoord; } )"; static const char* fs_blend_corner = R"( varying vec2 maskCoord; varying vec2 texCoord; uniform sampler2D movie; uniform sampler2D mask; void main() { gl_FragColor = texture2D(movie, texCoord) * texture2D(mask, maskCoord).a; } )"; static const char* vs_code = R"( attribute vec2 position; attribute vec2 vTexCoord; varying vec2 texCoord; void main() { gl_Position = vec4(position, 0.0, 1.0); texCoord = vTexCoord; } )"; static const char* fs_code = R"( varying vec2 texCoord; uniform sampler2D sampler; uniform vec4 bg; void main() { vec4 s = texture2D(sampler, texCoord); gl_FragColor = vec4(s.rgb * s.a + bg.rgb * (1.0 - s.a), 1.0); } )"; static const char* fs_corner_code = R"( varying vec2 texCoord; uniform sampler2D corner; uniform vec4 bg; void main() { vec4 s = texture2D(corner, texCoord); gl_FragColor = s.a * bg; } )"; namespace dmr { static void* GLAPIENTRY glMPGetNativeDisplay(const char* name) { qWarning() << __func__ << name; if (!strcmp(name, "x11") || !strcmp(name, "X11")) { return (void*)QX11Info::display(); } return NULL; } static void *get_proc_address(void *ctx, const char *name) { Q_UNUSED(ctx); QOpenGLContext *glctx = QOpenGLContext::currentContext(); if (!glctx) return NULL; if (!strcmp(name, "glMPGetNativeDisplay")) { return (void*)glMPGetNativeDisplay; } return (void *)glctx->getProcAddress(QByteArray(name)); } static void gl_update_callback(void *cb_ctx) { MpvGLWidget *w = static_cast(cb_ctx); QMetaObject::invokeMethod(w, "onNewFrame"); } void MpvGLWidget::onNewFrame() { //qDebug() << __func__; if (window()->isMinimized()) { makeCurrent(); paintGL(); context()->swapBuffers(context()->surface()); doneCurrent(); } else { update(); } } void MpvGLWidget::onFrameSwapped() { //qDebug() << "frame swapped"; mpv_opengl_cb_report_flip(_gl_ctx, 0); } MpvGLWidget::MpvGLWidget(QWidget *parent, mpv::qt::Handle h) :QOpenGLWidget(parent), _handle(h) { setUpdateBehavior(QOpenGLWidget::NoPartialUpdate); _gl_ctx = (mpv_opengl_cb_context*) mpv_get_sub_api(h, MPV_SUB_API_OPENGL_CB); if (!_gl_ctx) { std::runtime_error("can not init mpv gl"); } mpv_opengl_cb_set_update_callback(_gl_ctx, gl_update_callback, this); connect(this, &QOpenGLWidget::frameSwapped, this, &MpvGLWidget::onFrameSwapped, Qt::DirectConnection); //auto fmt = QSurfaceFormat::defaultFormat(); //fmt.setAlphaBufferSize(8); //this->setFormat(fmt); } MpvGLWidget::~MpvGLWidget() { makeCurrent(); if (_darkTex) { _darkTex->destroy(); delete _darkTex; } if (_lightTex) { _lightTex->destroy(); delete _lightTex; } for (auto mask: _cornerMasks) { if (mask) mask->destroy(); } _vbo.destroy(); for (int i = 0; i < 4; i++) { _vboCorners[i].destroy(); } _vao.destroy(); _vaoBlend.destroy(); _vaoCorner.destroy(); if (_fbo) delete _fbo; if (_gl_ctx) mpv_opengl_cb_set_update_callback(_gl_ctx, NULL, NULL); // Until this call is done, we need to make sure the player remains // alive. This is done implicitly with the mpv::qt::Handle instance // in this class. mpv_opengl_cb_uninit_gl(_gl_ctx); doneCurrent(); } void MpvGLWidget::setupBlendPipe() { updateMovieFbo(); _vaoBlend.create(); _vaoBlend.bind(); updateVboBlend(); _glProgBlend = new QOpenGLShaderProgram(); _glProgBlend->addShaderFromSourceCode(QOpenGLShader::Vertex, vs_blend); _glProgBlend->addShaderFromSourceCode(QOpenGLShader::Fragment, fs_blend); if (!_glProgBlend->link()) { qDebug() << "link failed"; } _glProgBlend->bind(); _vboBlend.bind(); int vLocBlend = _glProgBlend->attributeLocation("position"); int coordLocBlend = _glProgBlend->attributeLocation("vTexCoord"); _glProgBlend->enableAttributeArray(vLocBlend); _glProgBlend->setAttributeBuffer(vLocBlend, GL_FLOAT, 0, 2, 6*sizeof(GLfloat)); _glProgBlend->enableAttributeArray(coordLocBlend); _glProgBlend->setAttributeBuffer(coordLocBlend, GL_FLOAT, 2*sizeof(GLfloat), 2, 6*sizeof(GLfloat)); _glProgBlend->setUniformValue("movie", 0); _glProgBlend->release(); _vaoBlend.release(); _glProgBlendCorners = new QOpenGLShaderProgram(); _glProgBlendCorners->addShaderFromSourceCode(QOpenGLShader::Vertex, vs_blend_corner); _glProgBlendCorners->addShaderFromSourceCode(QOpenGLShader::Fragment, fs_blend_corner); if (!_glProgBlendCorners->link()) { qDebug() << "link failed"; } } void MpvGLWidget::setupIdlePipe() { _vao.create(); _vao.bind(); _darkTex = new QOpenGLTexture(bg_dark, QOpenGLTexture::DontGenerateMipMaps); _darkTex->setMinificationFilter(QOpenGLTexture::Linear); _lightTex = new QOpenGLTexture(bg_light, QOpenGLTexture::DontGenerateMipMaps); _lightTex->setMinificationFilter(QOpenGLTexture::Linear); updateVbo(); _vbo.bind(); _glProg = new QOpenGLShaderProgram(); _glProg->addShaderFromSourceCode(QOpenGLShader::Vertex, vs_code); _glProg->addShaderFromSourceCode(QOpenGLShader::Fragment, fs_code); if (!_glProg->link()) { qDebug() << "link failed"; } _glProg->bind(); int vertexLoc = _glProg->attributeLocation("position"); int coordLoc = _glProg->attributeLocation("vTexCoord"); _glProg->enableAttributeArray(vertexLoc); _glProg->setAttributeBuffer(vertexLoc, GL_FLOAT, 0, 2, 4*sizeof(GLfloat)); _glProg->enableAttributeArray(coordLoc); _glProg->setAttributeBuffer(coordLoc, GL_FLOAT, 2*sizeof(GLfloat), 2, 4*sizeof(GLfloat)); _glProg->setUniformValue("sampler", 0); _glProg->release(); _vao.release(); { _vaoCorner.create(); _vaoCorner.bind(); // setting up corners updateVboCorners(); updateCornerMasks(); _glProgCorner = new QOpenGLShaderProgram(); _glProgCorner->addShaderFromSourceCode(QOpenGLShader::Vertex, vs_code); _glProgCorner->addShaderFromSourceCode(QOpenGLShader::Fragment, fs_corner_code); if (!_glProgCorner->link()) { qDebug() << "link failed"; } _vaoCorner.release(); } } void MpvGLWidget::prepareSplashImages() { bg_dark = utils::LoadHiDPIImage(":/resources/icons/dark/init-splash.svg"); bg_light = utils::LoadHiDPIImage(":/resources/icons/light/init-splash.svg"); } void MpvGLWidget::initializeGL() { QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); //f->glEnable(GL_BLEND); //f->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); float a = 16.0 / 255.0; if (qApp->theme() != "dark") a = 252.0 / 255.0; f->glClearColor(a, a, a, 1.0); prepareSplashImages(); setupIdlePipe(); setupBlendPipe(); #ifdef _LIBDMR_ toggleRoundedClip(false); #else #ifndef USE_DXCB connect(window()->windowHandle(), &QWindow::windowStateChanged, [=]() { auto top = this->topLevelWidget(); bool rounded = !top->isFullScreen() && !top->isMaximized(); toggleRoundedClip(rounded); }); #endif #endif if (mpv_opengl_cb_init_gl(_gl_ctx, "GL_MP_MPGetNativeDisplay", get_proc_address, NULL) < 0) throw std::runtime_error("could not initialize OpenGL"); } void MpvGLWidget::updateMovieFbo() { if (!_doRoundedClipping) return; auto desiredSize = size() * qApp->devicePixelRatio(); if (_fbo) { if (_fbo->size() == desiredSize) { return; } _fbo->release(); delete _fbo; } _fbo = new QOpenGLFramebufferObject(desiredSize); } void MpvGLWidget::updateCornerMasks() { if (!_doRoundedClipping) return; for (int i = 0; i < 4; i++) { QSize sz(RADIUS, RADIUS); QImage img(sz, QImage::Format_ARGB32); img.fill(Qt::transparent); QPainter p; p.begin(&img); p.setRenderHint(QPainter::Antialiasing); QPainterPath pp; switch (i) { case 0: pp.moveTo({0, (qreal)sz.height()}); pp.arcTo(QRectF(0, 0, RADIUS*2, RADIUS*2), 180.0, -90.0); pp.lineTo(RADIUS, RADIUS); pp.closeSubpath(); break; case 1: pp.moveTo({0, 0}); pp.arcTo(QRectF(-RADIUS, 0, RADIUS*2, RADIUS*2), 90.0, -90.0); pp.lineTo(0, RADIUS); pp.closeSubpath(); break; case 2: pp.moveTo({(qreal)sz.width(), 0}); pp.arcTo(QRectF(-RADIUS, -RADIUS, RADIUS*2, RADIUS*2), 0.0, -90.0); pp.lineTo(0, 0); pp.closeSubpath(); break; case 3: pp.moveTo({(qreal)sz.width(), (qreal)sz.height()}); pp.arcTo(QRectF(0, -RADIUS, RADIUS*2, RADIUS*2), 270.0, -90.0); pp.lineTo(RADIUS, 0); pp.closeSubpath(); break; default: return; } p.setPen(Qt::red); p.setBrush(Qt::red); p.drawPath(pp); p.end(); if (_cornerMasks[i] == nullptr) { _cornerMasks[i] = new QOpenGLTexture(img, QOpenGLTexture::DontGenerateMipMaps); _cornerMasks[i]->setMinificationFilter(QOpenGLTexture::Linear); _cornerMasks[i]->setWrapMode(QOpenGLTexture::ClampToEdge); } } } void MpvGLWidget::updateVboBlend() { if (!_vboBlend.isCreated()) { _vboBlend.create(); } GLfloat x1 = -1.0f; GLfloat x2 = 1.0f; GLfloat y1 = 1.0f; GLfloat y2 = -1.0f; GLfloat s1 = 0.0f; GLfloat t1 = 1.0f; GLfloat s2 = 1.0f; GLfloat t2 = 0.0f; GLfloat vdata[] = { x1, y1, s1, t1, 0.0f, 1.0f, x2, y1, s2, t1, 1.0f, 1.0f, x2, y2, s2, t2, 1.0f, 0.0f, x1, y1, s1, t1, 0.0f, 1.0f, x2, y2, s2, t2, 1.0f, 0.0f, x1, y2, s1, t2, 0.0f, 0.0f }; _vboBlend.bind(); _vboBlend.allocate(vdata, sizeof(vdata)); _vboBlend.release(); } void MpvGLWidget::updateVboCorners() { auto vp = rect().size(); auto tex_sz = QSize(RADIUS, RADIUS); auto r = QRect(0, 0, vp.width(), vp.height()); QPoint pos[4] = { {0, r.height() - tex_sz.height()}, //top left {r.width() - tex_sz.width(), r.height() - tex_sz.height()}, //top right {r.width() - tex_sz.width(), 0}, //bottom right {0, 0}, //bottom left }; for (int i = 0; i < 4; i++) { if (!_vboCorners[i].isCreated()) { _vboCorners[i].create(); } auto r2 = QRect(pos[i], tex_sz); GLfloat x1 = (float)r2.left() / r.width(); GLfloat x2 = (float)(r2.right()+1) / r.width(); GLfloat y1 = (float)r2.top() / r.height(); GLfloat y2 = (float)(r2.bottom()+1) / r.height(); x1 = x1 * 2.0 - 1.0; x2 = x2 * 2.0 - 1.0; y1 = y1 * 2.0 - 1.0; y2 = y2 * 2.0 - 1.0; // for video tex coord GLfloat s1 = (float)r2.left() / r.width(); GLfloat s2 = (float)(r2.right()+1) / r.width(); GLfloat t2 = (float)(r2.top()) / r.height(); GLfloat t1 = (float)(r2.bottom()+1) / r.height(); // corner(and video) coord, corner-tex-coord, and video-as-tex-coord GLfloat vdata[] = { x1, y1, 0.0f, 1.0f, s1, t2, x2, y1, 1.0f, 1.0f, s2, t2, x2, y2, 1.0f, 0.0f, s2, t1, x1, y1, 0.0f, 1.0f, s1, t2, x2, y2, 1.0f, 0.0f, s2, t1, x1, y2, 0.0f, 0.0f, s1, t1, }; _vboCorners[i].bind(); _vboCorners[i].allocate(vdata, sizeof(vdata)); _vboCorners[i].release(); } } void MpvGLWidget::updateVbo() { if (!_vbo.isCreated()) { _vbo.create(); } //HACK: we assume if any of width or height is 380, then we are in mini mode auto vp = rect().size(); auto bg_size = QSizeF(bg_dark.size()) / devicePixelRatioF(); _inMiniMode = vp.width() <= 380 || vp.height() <= 380; auto tex_sz = _inMiniMode ? bg_size/2 : bg_size; auto r = QRectF(0, 0, vp.width(), vp.height()); auto r2 = QRectF(r.center() - QPointF(tex_sz.width()/2, tex_sz.height()/2), tex_sz); GLfloat x1 = (float)r2.left() / r.width(); GLfloat x2 = (float)(r2.right()+1) / r.width(); GLfloat y1 = (float)r2.top() / r.height(); GLfloat y2 = (float)(r2.bottom()+1) / r.height(); x1 = x1 * 2.0 - 1.0; x2 = x2 * 2.0 - 1.0; y1 = y1 * 2.0 - 1.0; y2 = y2 * 2.0 - 1.0; GLfloat vdata[] = { x1, y1, 0.0f, 1.0f, x2, y1, 1.0f, 1.0f, x2, y2, 1.0f, 0.0f, x1, y1, 0.0f, 1.0f, x2, y2, 1.0f, 0.0f, x1, y2, 0.0f, 0.0f }; _vbo.bind(); _vbo.allocate(vdata, sizeof(vdata)); _vbo.release(); } void MpvGLWidget::resizeGL(int w, int h) { QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); updateMovieFbo(); updateVbo(); if (_doRoundedClipping) updateVboCorners(); qDebug() << "GL resize" << w << h; QOpenGLWidget::resizeGL(w, h); } void MpvGLWidget::toggleRoundedClip(bool val) { _doRoundedClipping = val; makeCurrent(); updateMovieFbo(); update(); } void MpvGLWidget::paintGL() { QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); if (_playing) { auto dpr = qApp->devicePixelRatio(); QSize scaled = size() * dpr; if (!_doRoundedClipping) { mpv_opengl_cb_draw(_gl_ctx, defaultFramebufferObject(), scaled.width(), -scaled.height()); } else { f->glEnable(GL_BLEND); f->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); _fbo->bind(); mpv_opengl_cb_draw(_gl_ctx, _fbo->handle(), scaled.width(), -scaled.height()); _fbo->release(); { QOpenGLVertexArrayObject::Binder vaoBind(&_vaoBlend); _glProgBlend->bind(); f->glActiveTexture(GL_TEXTURE0); f->glBindTexture(GL_TEXTURE_2D, _fbo->texture()); f->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); f->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); f->glDrawArrays(GL_TRIANGLES, 0, 6); _glProgBlend->release(); } { f->glBlendFunc(GL_SRC_ALPHA, GL_ZERO); // blend corners //QOpenGLVertexArrayObject::Binder vaoBind(&_vaoCorner); for (int i = 0; i < 4; i++) { _glProgBlendCorners->bind(); _vboCorners[i].bind(); int vertexLoc = _glProgBlendCorners->attributeLocation("position"); int maskLoc = _glProgBlendCorners->attributeLocation("maskTexCoord"); int coordLoc = _glProgBlendCorners->attributeLocation("vTexCoord"); _glProgBlendCorners->enableAttributeArray(vertexLoc); _glProgBlendCorners->setAttributeBuffer(vertexLoc, GL_FLOAT, 0, 2, 6*sizeof(GLfloat)); _glProgBlendCorners->enableAttributeArray(maskLoc); _glProgBlendCorners->setAttributeBuffer(maskLoc, GL_FLOAT, 2*sizeof(GLfloat), 2, 6*sizeof(GLfloat)); _glProgBlendCorners->enableAttributeArray(coordLoc); _glProgBlendCorners->setAttributeBuffer(coordLoc, GL_FLOAT, 4*sizeof(GLfloat), 2, 6*sizeof(GLfloat)); _glProgBlendCorners->setUniformValue("movie", 0); _glProgBlendCorners->setUniformValue("mask", 1); f->glActiveTexture(GL_TEXTURE0); f->glBindTexture(GL_TEXTURE_2D, _fbo->texture()); f->glActiveTexture(GL_TEXTURE1); _cornerMasks[i]->bind(); f->glDrawArrays(GL_TRIANGLES, 0, 6); _cornerMasks[i]->release(); _glProgBlendCorners->release(); _vboCorners[i].release(); } } f->glDisable(GL_BLEND); } } else { f->glEnable(GL_BLEND); f->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); auto clr = QColor(16, 16, 16, 255); float a = 16.0 / 255.0; if (qApp->theme() != "dark") { clr = QColor(252, 252, 252, 255); a = 252.0 / 255.0; } f->glClearColor(a, a, a, 1.0); f->glClear(GL_COLOR_BUFFER_BIT); { QOpenGLVertexArrayObject::Binder vaoBind(&_vao); _vbo.bind(); _glProg->bind(); _glProg->setUniformValue("bg", clr); QOpenGLTexture *tex = _lightTex; if (qApp->theme() == "dark") { tex = _darkTex; } f->glActiveTexture(GL_TEXTURE0); tex->bind(); f->glDrawArrays(GL_TRIANGLES, 0, 6); tex->release(); _glProg->release(); _vbo.release(); } if (_doRoundedClipping) { f->glBlendFunc(GL_SRC_ALPHA, GL_ZERO); // blend corners QOpenGLVertexArrayObject::Binder vaoBind(&_vaoCorner); for (int i = 0; i < 4; i++) { _glProgCorner->bind(); _vboCorners[i].bind(); int vertexLoc = _glProgCorner->attributeLocation("position"); int coordLoc = _glProgCorner->attributeLocation("vTexCoord"); _glProgCorner->enableAttributeArray(vertexLoc); _glProgCorner->setAttributeBuffer(vertexLoc, GL_FLOAT, 0, 2, 6*sizeof(GLfloat)); _glProgCorner->enableAttributeArray(coordLoc); _glProgCorner->setAttributeBuffer(coordLoc, GL_FLOAT, 2*sizeof(GLfloat), 2, 6*sizeof(GLfloat)); _glProgCorner->setUniformValue("bg", clr); f->glActiveTexture(GL_TEXTURE0); _cornerMasks[i]->bind(); f->glDrawArrays(GL_TRIANGLES, 0, 6); _cornerMasks[i]->release(); _glProgCorner->release(); _vboCorners[i].release(); } } f->glDisable(GL_BLEND); } } void MpvGLWidget::setPlaying(bool val) { if (_playing != val) { _playing = val; } updateVbo(); updateVboCorners(); updateMovieFbo(); update(); } void MpvGLWidget::setMiniMode(bool val) { if (_inMiniMode != val) { _inMiniMode = val; updateVbo(); updateVboCorners(); update(); } } } deepin-movie-reborn-5.0.0/src/backends/mpv/mpv_glwidget.h000066400000000000000000000063621351125414100233720ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_MPV_GLWIDGET_H #define _DMR_MPV_GLWIDGET_H #include #include #undef Bool #include namespace dmr { class MpvGLWidget : public QOpenGLWidget { Q_OBJECT public: friend class MpvProxy; MpvGLWidget(QWidget *parent, mpv::qt::Handle h); virtual ~MpvGLWidget(); /* * rounded clipping consumes a lot of resources, and performs bad on 4K video */ void toggleRoundedClip(bool val); protected: void initializeGL() override; void resizeGL(int w, int h) override; void paintGL() override; void setPlaying(bool); void setMiniMode(bool); protected slots: void onNewFrame(); void onFrameSwapped(); private: mpv::qt::Handle _handle; mpv_opengl_cb_context *_gl_ctx {nullptr}; bool _playing {false}; bool _inMiniMode {false}; bool _doRoundedClipping {true}; QOpenGLVertexArrayObject _vao; QOpenGLBuffer _vbo; QOpenGLTexture *_darkTex {nullptr}; QOpenGLTexture *_lightTex {nullptr}; QOpenGLShaderProgram *_glProg {nullptr}; QOpenGLVertexArrayObject _vaoBlend; QOpenGLBuffer _vboBlend; QOpenGLShaderProgram *_glProgBlend {nullptr}; QOpenGLFramebufferObject *_fbo {nullptr}; QOpenGLShaderProgram *_glProgBlendCorners {nullptr}; //textures for corner QOpenGLVertexArrayObject _vaoCorner; QOpenGLTexture *_cornerMasks[4] {nullptr,}; QOpenGLBuffer _vboCorners[4]; QOpenGLShaderProgram *_glProgCorner {nullptr}; QImage bg_dark; QImage bg_light; void updateVbo(); void updateVboCorners(); void updateVboBlend(); void updateMovieFbo(); void updateCornerMasks(); void setupBlendPipe(); void setupIdlePipe(); void prepareSplashImages(); }; } #endif /* ifndef _DMR_MPV_GLWIDGET_H */ deepin-movie-reborn-5.0.0/src/backends/mpv/mpv_proxy.cpp000066400000000000000000000750571351125414100233070ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "config.h" #include "mpv_proxy.h" #include "mpv_glwidget.h" #include "compositing_manager.h" #include "utility.h" #include "player_engine.h" #ifndef _LIBDMR_ #include "dmr_settings.h" #include "movie_configuration.h" #endif #include #include #include #include #include #include #include namespace dmr { using namespace mpv::qt; enum AsyncReplyTag { SEEK, CHANNEL, SPEED }; static inline bool command_async(mpv_handle *ctx, const QVariant &args, uint64_t tag) { node_builder node(args); int err = mpv_command_node_async(ctx, tag, node.node()); return err == 0; } static inline int set_property_async(mpv_handle *ctx, const QString &name, const QVariant &v, uint64_t tag) { node_builder node(v); return mpv_set_property_async(ctx, tag, name.toUtf8().data(), MPV_FORMAT_NODE, node.node()); } static void mpv_callback(void *d) { MpvProxy *mpv = static_cast(d); QMetaObject::invokeMethod(mpv, "has_mpv_events", Qt::QueuedConnection); } MpvProxy::MpvProxy(QWidget *parent) :Backend(parent) { if (!CompositingManager::get().composited()) { setWindowFlags(Qt::FramelessWindowHint); setAttribute(Qt::WA_NativeWindow); qDebug() << "proxy hook winId " << this->winId(); } _handle = Handle::FromRawHandle(mpv_init()); if (CompositingManager::get().composited()) { _gl_widget = new MpvGLWidget(this, _handle); connect(this, &MpvProxy::stateChanged, [=]() { _gl_widget->setPlaying(state() != Backend::PlayState::Stopped); _gl_widget->update(); }); #if defined(USE_DXCB) || defined(_LIBDMR_) _gl_widget->toggleRoundedClip(false); #endif auto *layout = new QHBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(_gl_widget); setLayout(layout); } } MpvProxy::~MpvProxy() { disconnect(this, &MpvProxy::has_mpv_events, this, &MpvProxy::handle_mpv_events); _connectStateChange = false; disconnect(window()->windowHandle(), &QWindow::windowStateChanged, 0, 0); if (CompositingManager::get().composited()) { disconnect(this, &MpvProxy::stateChanged, 0, 0); delete _gl_widget; } } mpv_handle* MpvProxy::mpv_init() { mpv_handle *h = mpv_create(); bool composited = CompositingManager::get().composited(); switch(_debugLevel) { case DebugLevel::Info: mpv_request_log_messages(h, "info"); break; case DebugLevel::Debug: case DebugLevel::Verbose: set_property(h, "terminal", "yes"); if (_debugLevel == DebugLevel::Verbose) { set_property(h, "msg-level", "all=status"); mpv_request_log_messages(h, "info"); } else { set_property(h, "msg-level", "all=v"); mpv_request_log_messages(h, "v"); } break; } #ifdef _LIBDMR_ if (composited) { auto interop = QString::fromUtf8("vaapi-glx"); if (!qEnvironmentVariableIsEmpty("QT_XCB_GL_INTERGRATION")) { auto gl_int = qgetenv("QT_XCB_GL_INTERGRATION"); if (gl_int == "xcb_egl") { interop = "vaapi-egl"; } else { interop = "vaapi-glx"; } } set_property(h, "opengl-hwdec-interop", interop.toUtf8().constData()); qDebug() << "set opengl-hwdec-interop = " << interop; } set_property(h, "hwdec", "auto"); #else if (Settings::get().isSet(Settings::HWAccel)) { if (composited) { auto disable = Settings::get().disableInterop(); auto forced = Settings::get().forcedInterop(); auto interop = QString::fromUtf8("auto"); switch (CompositingManager::get().interopKind()) { case OpenGLInteropKind::INTEROP_VAAPI_EGL: interop = QString::fromUtf8("vaapi-egl"); break; case OpenGLInteropKind::INTEROP_VAAPI_GLX: interop = QString::fromUtf8("vaapi-glx"); break; case OpenGLInteropKind::INTEROP_VDPAU_GLX: interop = QString::fromUtf8("vdpau-glx"); break; default: break; } if (!forced.isEmpty()) { QStringList valids {"vaapi-egl", "vaapi-glx", "vdpau-glx", "auto"}; if (valids.contains(forced)) { interop = forced; } } if (!disable) { set_property(h, "opengl-hwdec-interop", interop.toUtf8().constData()); qDebug() << "-------- set opengl-hwdec-interop = " << interop << (forced.isEmpty() ? "[detected]" : "[forced]"); } else { qDebug() << "-------- opengl-hwdec-interop is disabled by user"; } } set_property(h, "hwdec", "auto"); } else { set_property(h, "hwdec", "off"); } #endif set_property(h, "panscan", 1.0); //set_property(h, "no-keepaspect", "true"); if (composited) { set_property(h, "vo", "opengl-cb"); } else { set_property(h, "vo", "opengl,xv,x11"); set_property(h, "wid", this->winId()); } set_property(h, "volume-max", 200.0); set_property(h, "input-cursor", "no"); set_property(h, "cursor-autohide", "no"); //set_property(h, "sub-ass-override", "yes"); //set_property(h, "sub-ass-style-override", "yes"); set_property(h, "sub-auto", "fuzzy"); set_property(h, "sub-visibility", "true"); //set_property(h, "sub-scale-with-window", "no"); //set_property(h, "sub-scale-by-window", "no"); set_property(h, "sub-pos", 100); set_property(h, "sub-margin-y", 36); set_property(h, "sub-border-size", 0); set_property(h, "screenshot-template", "deepin-movie-shot%n"); set_property(h, "screenshot-directory", "/tmp"); #ifndef _LIBDMR_ if (Settings::get().isSet(Settings::ResumeFromLast)) { set_property(h, "save-position-on-quit", true); } #endif //only to get notification without data mpv_observe_property(h, 0, "time-pos", MPV_FORMAT_NONE); //playback-time ? mpv_observe_property(h, 0, "pause", MPV_FORMAT_NONE); mpv_observe_property(h, 0, "mute", MPV_FORMAT_NONE); mpv_observe_property(h, 0, "volume", MPV_FORMAT_NONE); //ao-volume ? mpv_observe_property(h, 0, "sid", MPV_FORMAT_NONE); mpv_observe_property(h, 0, "aid", MPV_FORMAT_NODE); mpv_observe_property(h, 0, "dwidth", MPV_FORMAT_NODE); mpv_observe_property(h, 0, "dheight", MPV_FORMAT_NODE); // because of vpu, we need to implement playlist w/o mpv //mpv_observe_property(h, 0, "playlist-pos", MPV_FORMAT_NONE); //mpv_observe_property(h, 0, "playlist-count", MPV_FORMAT_NONE); mpv_observe_property(h, 0, "core-idle", MPV_FORMAT_NODE); mpv_set_wakeup_callback(h, mpv_callback, this); connect(this, &MpvProxy::has_mpv_events, this, &MpvProxy::handle_mpv_events, Qt::DirectConnection); if (mpv_initialize(h) < 0) { std::runtime_error("mpv init failed"); } //load profile auto ol = CompositingManager::get().getBestProfile(); auto p = ol.begin(); while (p != ol.end()) { if (!p->first.startsWith("#")) { set_property(h, p->first.toUtf8().constData(), p->second.toUtf8().constData()); qDebug() << "apply" << p->first << "=" << p->second; } else { qDebug() << "ignore(commented out)" << p->first << "=" << p->second; } ++p; } return h; } void MpvProxy::setState(PlayState s) { if (_state != s) { _state = s; if (_gl_widget) { _gl_widget->setPlaying(s != PlayState::Stopped); } emit stateChanged(); } } void MpvProxy::pollingEndOfPlayback() { if (_state != Backend::Stopped) { _polling = true; blockSignals(true); stop(); auto idle = get_property(_handle, "idle-active").toBool(); if (idle) { blockSignals(false); setState(Backend::Stopped); _polling = false; return; } while (_state != Backend::Stopped) { mpv_event* ev = mpv_wait_event(_handle, 0.005); if (ev->event_id == MPV_EVENT_NONE) continue; if (ev->event_id == MPV_EVENT_END_FILE) { qDebug() << "end of playback"; blockSignals(false); setState(Backend::Stopped); break; } } _polling = false; } } void MpvProxy::pollingStartOfPlayback() { if (_state == Backend::PlayState::Stopped) { _polling = true; while (_state == Backend::Stopped) { mpv_event* ev = mpv_wait_event(_handle, 0.005); if (ev->event_id == MPV_EVENT_NONE) continue; if (ev->event_id == MPV_EVENT_FILE_LOADED) { qDebug() << "start of playback"; setState(Backend::Playing); break; } } _polling = false; } } const PlayingMovieInfo& MpvProxy::playingMovieInfo() { return _pmf; } void MpvProxy::handle_mpv_events() { while (1) { mpv_event* ev = mpv_wait_event(_handle, 0.0005); if (ev->event_id == MPV_EVENT_NONE) break; switch (ev->event_id) { case MPV_EVENT_LOG_MESSAGE: processLogMessage((mpv_event_log_message*)ev->data); break; case MPV_EVENT_PROPERTY_CHANGE: processPropertyChange((mpv_event_property*)ev->data); break; case MPV_EVENT_COMMAND_REPLY: if (ev->error < 0) { qDebug() << "command error"; } if (ev->reply_userdata == AsyncReplyTag::SEEK) { this->_pendingSeek = false; } break; case MPV_EVENT_PLAYBACK_RESTART: // caused by seek or just playing break; case MPV_EVENT_TRACKS_CHANGED: qDebug() << mpv_event_name(ev->event_id); updatePlayingMovieInfo(); emit tracksChanged(); break; case MPV_EVENT_FILE_LOADED: qDebug() << mpv_event_name(ev->event_id); if (_gl_widget) { auto w = get_property(_handle, "width").toInt(); auto h = get_property(_handle, "height").toInt(); qDebug() << "hwdec-interop" << get_property(_handle, "hwdec-interop"); } setState(PlayState::Playing); //might paused immediately emit fileLoaded(); qDebug() << QString("rotate metadata: dec %1, out %2") .arg(get_property(_handle, "video-dec-params/rotate").toInt()) .arg(get_property(_handle, "video-params/rotate").toInt()); break; case MPV_EVENT_VIDEO_RECONFIG: { auto sz = videoSize(); if (!sz.isEmpty()) emit videoSizeChanged(); qDebug() << "videoSize " << sz; break; } case MPV_EVENT_END_FILE: { #ifndef _LIBDMR_ MovieConfiguration::get().updateUrl(this->_file, ConfigKnownKey::StartPos, 0); #endif mpv_event_end_file *ev_ef = (mpv_event_end_file*)ev->data; qDebug() << mpv_event_name(ev->event_id) << "reason " << ev_ef->reason; setState(PlayState::Stopped); break; } case MPV_EVENT_IDLE: qDebug() << mpv_event_name(ev->event_id); setState(PlayState::Stopped); emit elapsedChanged(); break; default: qDebug() << mpv_event_name(ev->event_id); break; } } } void MpvProxy::processLogMessage(mpv_event_log_message* ev) { switch (ev->log_level) { case MPV_LOG_LEVEL_WARN: qWarning() << QString("%1: %2").arg(ev->prefix).arg(ev->text); break; case MPV_LOG_LEVEL_ERROR: case MPV_LOG_LEVEL_FATAL: qCritical() << QString("%1: %2").arg(ev->prefix).arg(ev->text); break; case MPV_LOG_LEVEL_INFO: qInfo() << QString("%1: %2").arg(ev->prefix).arg(ev->text); break; default: qDebug() << QString("%1: %2").arg(ev->prefix).arg(ev->text); break; } } void MpvProxy::processPropertyChange(mpv_event_property* ev) { //if (ev->data == NULL) return; QString name = QString::fromUtf8(ev->name); if (name != "time-pos") qDebug() << name; if (name == "time-pos") { emit elapsedChanged(); } else if (name == "volume") { emit volumeChanged(); } else if (name == "dwidth" || name == "dheight") { auto sz = videoSize(); if (!sz.isEmpty()) emit videoSizeChanged(); qDebug() << "update videoSize " << sz; } else if (name == "aid") { emit aidChanged(); } else if (name == "sid") { if (_externalSubJustLoaded) { #ifndef _LIBDMR_ MovieConfiguration::get().updateUrl(this->_file, ConfigKnownKey::SubId, sid()); #endif _externalSubJustLoaded = false; } emit sidChanged(); } else if (name == "mute") { emit muteChanged(); } else if (name == "sub-visibility") { //_hideSub = get_property(_handle, "sub-visibility") } else if (name == "pause") { auto idle = get_property(_handle, "idle-active").toBool(); if (get_property(_handle, "pause").toBool()) { if (!idle) setState(PlayState::Paused); else set_property(_handle, "pause", false); } else { if (state() != PlayState::Stopped) setState(PlayState::Playing); } } else if (name == "core-idle") { } } bool MpvProxy::loadSubtitle(const QFileInfo& fi) { //movie could be in an inner state that marked as Stopped when loadfile executes //if (state() == PlayState::Stopped) { return true; } if (!fi.exists()) return false; QList args = { "sub-add", fi.absoluteFilePath(), "select" }; qDebug () << args; QVariant id = command(_handle, args); if (id.canConvert()) { return false; } // by settings this flag, we can match the corresponding sid change and save it // in the movie database _externalSubJustLoaded = true; return true; } bool MpvProxy::isSubVisible() { return get_property(_handle, "sub-visibility").toBool(); } void MpvProxy::setSubDelay(double secs) { set_property(_handle, "sub-delay", secs); #ifndef _LIBDMR_ MovieConfiguration::get().updateUrl(_file, ConfigKnownKey::SubDelay, subDelay()); #endif } double MpvProxy::subDelay() const { return get_property(_handle, "sub-delay").toDouble(); } QString MpvProxy::subCodepage() { auto cp = get_property(_handle, "sub-codepage").toString(); if (cp.startsWith("+")) { cp.remove(0, 1); } return cp; } void MpvProxy::addSubSearchPath(const QString& path) { set_property(_handle, "sub-paths", path); set_property(_handle, "sub-file-paths", path); } void MpvProxy::setSubCodepage(const QString& cp) { auto cp2 = cp; if (!cp.startsWith("+") && cp != "auto") cp2.prepend('+'); set_property(_handle, "sub-codepage", cp2); command(_handle, {"sub-reload"}); #ifndef _LIBDMR_ if (_file.isValid()) MovieConfiguration::get().updateUrl(_file, ConfigKnownKey::SubCodepage, subCodepage()); #endif } void MpvProxy::updateSubStyle(const QString& font, int sz) { set_property(_handle, "sub-font", font); set_property(_handle, "sub-font-size", sz); set_property(_handle, "sub-color", "#FFFFFF"); set_property(_handle, "sub-border-size", 1); set_property(_handle, "sub-border-color", "0.0/0.0/0.0/0.50"); set_property(_handle, "sub-shadow-offset", 1); set_property(_handle, "sub-shadow-color", "0.0/0.0/0.0/0.50"); } void MpvProxy::showEvent(QShowEvent *re) { if (!_connectStateChange) { connect(window()->windowHandle(), &QWindow::windowStateChanged, [=](Qt::WindowState ws) { set_property(_handle, "panscan", (ws != Qt::WindowMaximized && ws != Qt::WindowFullScreen) ? 1.0 : 0.0); }); _connectStateChange = true; } } void MpvProxy::resizeEvent(QResizeEvent *re) { if (state() == PlayState::Stopped) { return; } } void MpvProxy::savePlaybackPosition() { if (state() == PlayState::Stopped) { return; } #ifndef _LIBDMR_ MovieConfiguration::get().updateUrl(this->_file, ConfigKnownKey::SubId, sid()); MovieConfiguration::get().updateUrl(this->_file, ConfigKnownKey::StartPos, elapsed()); #endif } void MpvProxy::setPlaySpeed(double times) { //set_property(_handle, "speed", times); set_property_async(_handle, "speed", times, AsyncReplyTag::SPEED); } void MpvProxy::selectSubtitle(int id) { if (id > _pmf.subs.size()) { id = _pmf.subs.size() == 0? -1: _pmf.subs[0]["id"].toInt(); } set_property(_handle, "sid", id); #ifndef _LIBDMR_ MovieConfiguration::get().updateUrl(_file, ConfigKnownKey::SubId, sid()); #endif } void MpvProxy::toggleSubtitle() { if (state() == PlayState::Stopped) { return; } set_property(_handle, "sub-visibility", !isSubVisible()); } int MpvProxy::aid() const { return get_property(_handle, "aid").toInt(); } int MpvProxy::sid() const { return get_property(_handle, "sid").toInt(); } void MpvProxy::selectTrack(int id) { if (id >= _pmf.audios.size()) return; auto sid = _pmf.audios[id]["id"]; set_property(_handle, "aid", sid); } void MpvProxy::changeSoundMode(SoundMode sm) { QList args; switch(sm) { case SoundMode::Stereo: args << "af" << "del" << "@sm"; break; case SoundMode::Left: args << "af" << "add" << "@sm:channels=2:[0-0:1-0]"; break; case SoundMode::Right: args << "af" << "add" << "@sm:channels=2:[0-1:1-1]"; break; } command_async(_handle, args, AsyncReplyTag::CHANNEL); } void MpvProxy::volumeUp() { QList args = { "add", "volume", 8 }; qDebug () << args; command(_handle, args); } void MpvProxy::changeVolume(int val) { val = qMin(qMax(val, 0), 200); set_property(_handle, "volume", val); } void MpvProxy::volumeDown() { QList args = { "add", "volume", -8 }; qDebug () << args; command(_handle, args); } int MpvProxy::volume() const { return get_property(_handle, "volume").toInt(); } int MpvProxy::videoRotation() const { auto vr = get_property(_handle, "video-rotate").toInt(); return (vr + 360) % 360; } void MpvProxy::setVideoRotation(int degree) { set_property(_handle, "video-rotate", degree); } void MpvProxy::setVideoAspect(double r) { set_property(_handle, "video-aspect", r); } double MpvProxy::videoAspect() const { return get_property(_handle, "video-aspect").toDouble(); } bool MpvProxy::muted() const { return get_property(_handle, "mute").toBool(); } void MpvProxy::toggleMute() { QList args = { "cycle", "mute" }; qDebug () << args; command(_handle, args); } void MpvProxy::play() { QList args = { "loadfile" }; QStringList opts = { }; if (_file.isLocalFile()) { args << QFileInfo(_file.toLocalFile()).absoluteFilePath(); } else { args << _file.url(); } #ifndef _LIBDMR_ auto cfg = MovieConfiguration::get().queryByUrl(_file); auto key = MovieConfiguration::knownKey2String(ConfigKnownKey::StartPos); if (Settings::get().isSet(Settings::ResumeFromLast) && cfg.contains(key)) { opts << QString("start=%1").arg(cfg[key].toInt()); } key = MovieConfiguration::knownKey2String(ConfigKnownKey::SubCodepage); if (cfg.contains(key)) { opts << QString("sub-codepage=%1").arg(cfg[key].toString()); } key = MovieConfiguration::knownKey2String(ConfigKnownKey::SubDelay); if (cfg.contains(key)) { opts << QString("sub-delay=%1").arg(cfg[key].toDouble()); } if (!_dvdDevice.isEmpty()) { opts << QString("dvd-device=%1").arg(_dvdDevice); } #endif if (opts.size()) { //opts << "sub-auto=fuzzy"; args << "replace" << opts.join(','); } qDebug () << args; command(_handle, args); set_property(_handle, "pause", _pauseOnStart); #ifndef _LIBDMR_ // by giving a period of time, movie will be loaded and auto-loaded subs are // all ready, then load extra subs from db // this keeps order of subs QTimer::singleShot(100, [this]() { auto cfg = MovieConfiguration::get().queryByUrl(_file); auto ext_subs = MovieConfiguration::get().getListByUrl(_file, ConfigKnownKey::ExternalSubs); for(const auto& sub: ext_subs) { if (!QFile::exists(sub)) { MovieConfiguration::get().removeFromListUrl(_file, ConfigKnownKey::ExternalSubs, sub); } else { loadSubtitle(sub); } } auto key = MovieConfiguration::knownKey2String(ConfigKnownKey::SubId); if (cfg.contains(key)) { selectSubtitle(cfg[key].toInt()); } }); #endif } void MpvProxy::pauseResume() { if (_state == PlayState::Stopped) return; set_property(_handle, "pause", !paused()); } void MpvProxy::stop() { QList args = { "stop" }; qDebug () << args; command(_handle, args); } QImage MpvProxy::takeScreenshot() { return takeOneScreenshot(); } void MpvProxy::burstScreenshot() { if (_inBurstShotting) { qWarning() << "already in burst screenshotting mode"; return; } if (state() == PlayState::Stopped) return; //command(_handle, QList {"revert-seek", "mark"}); _posBeforeBurst = get_property(_handle, "time-pos"); int d = duration() / 15; std::random_device rd; std::mt19937 g(rd()); std::uniform_int_distribution uniform_dist(0, d); _burstPoints.clear(); for (int i = 0; i < 15; i++) { _burstPoints.append(d*i + uniform_dist(g)); } _burstStart = 0; if (duration() < 35) { emit notifyScreenshot(QImage(), 0); stopBurstScreenshot(); return; } qDebug() << "burst span " << _burstPoints; if (!paused()) pauseResume(); _inBurstShotting = true; QTimer::singleShot(0, this, &MpvProxy::stepBurstScreenshot); } qint64 MpvProxy::nextBurstShootPoint() { auto next = _burstPoints[_burstStart++]; if (next >= duration()) { next = duration() - 5; } return next; } QImage MpvProxy::takeOneScreenshot() { if (state() == PlayState::Stopped) return QImage(); QList args = {"screenshot-raw"}; node_builder node(args); mpv_node res; int err = mpv_command_node(_handle, node.node(), &res); if (err < 0) { qWarning() << "screenshot raw failed"; return QImage(); } node_autofree f(&res); Q_ASSERT(res.format == MPV_FORMAT_NODE_MAP); int w,h,stride; mpv_node_list *list = res.u.list; uchar *data = NULL; for (int n = 0; n < list->num; n++) { auto key = QString::fromUtf8(list->keys[n]); if (key == "w") { w = list->values[n].u.int64; } else if (key == "h") { h = list->values[n].u.int64; } else if (key == "stride") { stride = list->values[n].u.int64; } else if (key == "format") { auto format = QString::fromUtf8(list->values[n].u.string); qDebug() << "format" << format; } else if (key == "data") { data = (uchar*)list->values[n].u.ba->data; } } if (data) { //alpha should be ignored auto img = QImage((const uchar*)data, w, h, stride, QImage::Format_RGB32); img.bits(); return img; } qDebug() << "failed"; return QImage(); } void MpvProxy::stepBurstScreenshot() { if (!_inBurstShotting) { return; } auto pos = nextBurstShootPoint(); command(_handle, QList {"seek", pos, "absolute"}); int tries = 10; while (tries) { mpv_event* ev = mpv_wait_event(_handle, 0.005); if (ev->event_id == MPV_EVENT_NONE) continue; if (ev->event_id == MPV_EVENT_PLAYBACK_RESTART) { qDebug() << "seek finished" << elapsed(); break; } if (ev->event_id == MPV_EVENT_END_FILE) { qDebug() << "seek finished (end of file)" << elapsed(); break; } } QImage img = takeOneScreenshot(); if (img.isNull()) { emit notifyScreenshot(img, elapsed()); stopBurstScreenshot(); return; } emit notifyScreenshot(img, elapsed()); QTimer::singleShot(0, this, &MpvProxy::stepBurstScreenshot); } void MpvProxy::stopBurstScreenshot() { _inBurstShotting = false; //command(_handle, QList {"revert-seek", "mark"}); set_property(_handle, "time-pos", _posBeforeBurst); } void MpvProxy::seekForward(int secs) { if (state() == PlayState::Stopped) return; //if (_pendingSeek) return; QList args = { "seek", QVariant(secs), "relative+keyframes" }; qDebug () << args; command_async(_handle, args, AsyncReplyTag::SEEK); _pendingSeek = true; } void MpvProxy::seekBackward(int secs) { if (state() == PlayState::Stopped) return; //if (_pendingSeek) return; if (secs > 0) secs = -secs; QList args = { "seek", QVariant(secs), "relative+keyframes" }; qDebug () << args; command_async(_handle, args, AsyncReplyTag::SEEK); _pendingSeek = true; } void MpvProxy::seekAbsolute(int pos) { if (state() == PlayState::Stopped) return; if (_pendingSeek) return; QList args = { "seek", QVariant(pos), "absolute" }; qDebug () << args; //command(_handle, args); _pendingSeek = true; command_async(_handle, args, AsyncReplyTag::SEEK); } QSize MpvProxy::videoSize() const { if (state() == PlayState::Stopped) return QSize(-1, -1); auto sz = QSize(get_property(_handle, "dwidth").toInt(), get_property(_handle, "dheight").toInt()); auto r = get_property(_handle, "video-out-params/rotate").toInt(); if (r == 90 || r == 270) { sz.transpose(); } return sz; } qint64 MpvProxy::duration() const { return get_property(_handle, "duration").value(); } qint64 MpvProxy::elapsed() const { if (state() == PlayState::Stopped) return 0; return get_property(_handle, "time-pos").value(); } void MpvProxy::changeProperty(const QString& name, const QVariant& v) { } void MpvProxy::updatePlayingMovieInfo() { _pmf.subs.clear(); _pmf.audios.clear(); auto v = get_property(_handle, "track-list").toList(); auto p = v.begin(); while (p != v.end()) { const auto& t = p->toMap(); if (t["type"] == "audio") { AudioInfo ai; ai["type"] = t["type"]; ai["id"] = t["id"]; ai["lang"] = t["lang"]; ai["external"] = t["external"]; ai["external-filename"] = t["external-filename"]; ai["selected"] = t["selected"]; ai["title"] = t["title"]; if (t["title"].toString().size() == 0) { if (t["lang"].isValid() && t["lang"].toString().size() && t["lang"].toString() != "und") ai["title"] = t["lang"]; else if (!t["external"].toBool()) ai["title"] = tr("[internal]"); } _pmf.audios.append(ai); } else if (t["type"] == "sub") { SubtitleInfo si; si["type"] = t["type"]; si["id"] = t["id"]; si["lang"] = t["lang"]; si["external"] = t["external"]; si["external-filename"] = t["external-filename"]; si["selected"] = t["selected"]; si["title"] = t["title"]; if (t["title"].toString().size() == 0) { if (t["lang"].isValid() && t["lang"].toString().size() && t["lang"].toString() != "und") si["title"] = t["lang"]; else if (!t["external"].toBool()) si["title"] = tr("[internal]"); } _pmf.subs.append(si); } ++p; } qDebug() << _pmf.subs; qDebug() << _pmf.audios; } void MpvProxy::nextFrame() { if (state() == PlayState::Stopped) return; QList args = { "frame-step"}; command(_handle, args); } void MpvProxy::previousFrame() { if (state() == PlayState::Stopped) return; QList args = { "frame-back-step"}; command(_handle, args); } QVariant MpvProxy::getProperty(const QString& name) { return get_property(_handle, name.toUtf8().data()); } void MpvProxy::setProperty(const QString& name, const QVariant& val) { if (name == "pause-on-start") { _pauseOnStart = val.toBool(); } else { set_property(_handle, name.toUtf8().data(), val); } } } // end of namespace dmr deepin-movie-reborn-5.0.0/src/backends/mpv/mpv_proxy.h000066400000000000000000000115241351125414100227410ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_MPV_PROXY_H #define _DMR_MPV_PROXY_H #include #include #include #undef Bool #include namespace dmr { using namespace mpv::qt; class MpvGLWidget; class MpvProxy: public Backend { Q_OBJECT public: MpvProxy(QWidget *parent = 0); virtual ~MpvProxy(); const PlayingMovieInfo& playingMovieInfo() override; // mpv plays all files by default (I hope) bool isPlayable() const override { return true; } // polling until current playback ended void pollingEndOfPlayback(); // polling until current playback started void pollingStartOfPlayback(); qint64 duration() const override; qint64 elapsed() const override; QSize videoSize() const override; void setPlaySpeed(double times) override; void savePlaybackPosition() override; bool loadSubtitle(const QFileInfo& fi) override; void toggleSubtitle() override; bool isSubVisible() override; void selectSubtitle(int id) override; int sid() const override; void setSubDelay(double secs) override; double subDelay() const override; void updateSubStyle(const QString& font, int sz) override; void setSubCodepage(const QString& cp) override; QString subCodepage() override; void addSubSearchPath(const QString& path) override; void selectTrack(int id) override; int aid() const override; void changeSoundMode(SoundMode sm) override; int volume() const override; bool muted() const override; void setVideoAspect(double r) override; double videoAspect() const override; int videoRotation() const override; void setVideoRotation(int degree) override; QImage takeScreenshot() override; void burstScreenshot() override; //initial the start of burst screenshotting void stopBurstScreenshot() override; QVariant getProperty(const QString&) override; void setProperty(const QString&, const QVariant&) override; void nextFrame() override; void previousFrame() override; public slots: void play() override; void pauseResume() override; void stop() override; void seekForward(int secs) override; void seekBackward(int secs) override; void seekAbsolute(int pos) override; void volumeUp() override; void volumeDown() override; void changeVolume(int val) override; void toggleMute() override; protected: void resizeEvent(QResizeEvent *re) override; void showEvent(QShowEvent *re) override; protected slots: void handle_mpv_events(); void stepBurstScreenshot(); signals: void has_mpv_events(); private: Handle _handle; MpvGLWidget *_gl_widget{nullptr}; bool _inBurstShotting {false}; QVariant _posBeforeBurst; qint64 _burstStart {0}; QList _burstPoints; bool _pendingSeek {false}; PlayingMovieInfo _pmf; int _videoRotation {0}; bool _polling {false}; bool _externalSubJustLoaded {false}; bool _connectStateChange {false}; bool _pauseOnStart {false}; mpv_handle* mpv_init(); void processPropertyChange(mpv_event_property* ev); void processLogMessage(mpv_event_log_message* ev); QImage takeOneScreenshot(); void changeProperty(const QString& name, const QVariant& v); void updatePlayingMovieInfo(); void setState(PlayState s); qint64 nextBurstShootPoint(); }; } #endif /* ifndef _DMR_MPV_PROXY_H */ deepin-movie-reborn-5.0.0/src/common/000077500000000000000000000000001351125414100174365ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/src/common/actions.cpp000066400000000000000000000317031351125414100216060ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "config.h" #include "actions.h" #include "player_engine.h" namespace dmr { static ActionFactory* _factory = nullptr; ActionFactory& ActionFactory::get() { if (_factory == nullptr) { _factory = new ActionFactory(); } return *_factory; } #define DEF_ACTION(NAME, KD) do { \ auto *act = menu->addAction((NAME)); \ act->setProperty("kind", KD); \ _contextMenuActions.append(act); \ connect(act, &QObject::destroyed, [=](QObject* o) { \ _contextMenuActions.removeOne((QAction*)o); \ }); \ } while (0) #define DEF_ACTION_CHECKED(NAME, KD) do { \ auto *act = menu->addAction((NAME)); \ act->setCheckable(true); \ act->setProperty("kind", KD); \ _contextMenuActions.append(act); \ connect(act, &QObject::destroyed, [=](QObject* o) { \ _contextMenuActions.removeOne((QAction*)o); \ }); \ } while (0) #define DEF_ACTION_CHECKED_GROUP(NAME, KD, GROUP) do { \ auto *act = menu->addAction((NAME)); \ act->setCheckable(true); \ act->setProperty("kind", KD); \ act->setActionGroup(GROUP); \ _contextMenuActions.append(act); \ connect(act, &QObject::destroyed, [=](QObject* o) { \ _contextMenuActions.removeOne((QAction*)o); \ }); \ } while (0) QMenu* ActionFactory::titlebarMenu() { if (!_titlebarMenu) { auto *menu = new QMenu(); DEF_ACTION(tr("Open file"), ActionKind::OpenFileList); DEF_ACTION(tr("Open folder"), ActionKind::OpenDirectory); DEF_ACTION(tr("Settings"), ActionKind::Settings); DEF_ACTION_CHECKED(tr("Light theme"), ActionKind::LightTheme); menu->addSeparator(); // these seems added by titlebar itself //DEF_ACTION("About", ActionKind::About); //DEF_ACTION("Help", ActionKind::Help); //DEF_ACTION("Exit", ActionKind::Exit); _titlebarMenu = menu; } return _titlebarMenu; } QMenu* ActionFactory::mainContextMenu() { if (!_contextMenu) { auto *menu = new QMenu(); DEF_ACTION(tr("Open file"), ActionKind::OpenFileList); DEF_ACTION(tr("Open folder"), ActionKind::OpenDirectory); DEF_ACTION(tr("Open URL"), ActionKind::OpenUrl); DEF_ACTION(tr("Open CD/DVD"), ActionKind::OpenCdrom); menu->addSeparator(); DEF_ACTION_CHECKED(tr("Fullscreen"), ActionKind::ToggleFullscreen); DEF_ACTION_CHECKED(tr("Mini Mode"), ActionKind::ToggleMiniMode); DEF_ACTION_CHECKED(tr("Always on Top"), ActionKind::WindowAbove); menu->addSeparator(); { //sub menu auto *parent = menu; auto *menu = new QMenu(tr("Play Mode")); auto group = new QActionGroup(menu); DEF_ACTION_CHECKED_GROUP(tr("Order Play"), ActionKind::OrderPlay, group); DEF_ACTION_CHECKED_GROUP(tr("Shuffle Play"), ActionKind::ShufflePlay, group); DEF_ACTION_CHECKED_GROUP(tr("Single Play"), ActionKind::SinglePlay, group); DEF_ACTION_CHECKED_GROUP(tr("Single Loop"), ActionKind::SingleLoop, group); DEF_ACTION_CHECKED_GROUP(tr("List Loop"), ActionKind::ListLoop, group); parent->addMenu(menu); } { //sub menu auto *parent = menu; auto *menu = new QMenu(tr("Frame")); auto group = new QActionGroup(menu); DEF_ACTION_CHECKED_GROUP(tr("Default"), ActionKind::DefaultFrame, group); DEF_ACTION_CHECKED_GROUP(("4:3"), ActionKind::Ratio4x3Frame, group); DEF_ACTION_CHECKED_GROUP(("16:9"), ActionKind::Ratio16x9Frame, group); DEF_ACTION_CHECKED_GROUP(("16:10"), ActionKind::Ratio16x10Frame, group); DEF_ACTION_CHECKED_GROUP(("1.85:1"), ActionKind::Ratio185x1Frame, group); DEF_ACTION_CHECKED_GROUP(("2.35:1"), ActionKind::Ratio235x1Frame, group); menu->addSeparator(); DEF_ACTION(tr("Clockwise"), ActionKind::ClockwiseFrame); DEF_ACTION(tr("Counterclockwise"), ActionKind::CounterclockwiseFrame); menu->addSeparator(); DEF_ACTION(tr("Next frame"), ActionKind::NextFrame); DEF_ACTION(tr("Previous frame"), ActionKind::PreviousFrame); parent->addMenu(menu); } { //sub menu auto *parent = menu; auto *menu = new QMenu(tr("Sound")); { auto *parent = menu; auto *menu = new QMenu(tr("Channel")); auto group = new QActionGroup(menu); DEF_ACTION_CHECKED_GROUP(tr("Stereo"), ActionKind::Stereo, group); DEF_ACTION_CHECKED_GROUP(tr("Left channel"), ActionKind::LeftChannel, group); DEF_ACTION_CHECKED_GROUP(tr("Right channel"), ActionKind::RightChannel, group); parent->addMenu(menu); } { auto *parent = menu; auto *menu = new QMenu(tr("Track")); _tracksMenu = menu; //DEF_ACTION(tr("Select Track"), ActionKind::SelectTrack); parent->addMenu(menu); } parent->addMenu(menu); } { //sub menu auto *parent = menu; auto *menu = new QMenu(tr("Subtitle")); DEF_ACTION(tr("Load"), ActionKind::LoadSubtitle); DEF_ACTION(tr("Online Search"), ActionKind::MatchOnlineSubtitle); //DEF_ACTION(tr("Select"), ActionKind::SelectSubtitle); { auto *parent = menu; auto *menu = new QMenu(tr("Select")); _subtitleMenu = menu; parent->addMenu(menu); } DEF_ACTION_CHECKED(tr("Hide"), ActionKind::HideSubtitle); { auto *parent = menu; auto *menu = new QMenu(tr("Encodings")); auto group = new QActionGroup(menu); //title <-> codepage static QVector> list = { {"Auto", "auto"}, {"Universal (UTF-8)", "UTF-8"}, {"Universal (UTF-16)", "UTF-16"}, {"Universal (UTF-16BE)", "UTF-16BE"}, {"Universal (UTF-16LE)", "UTF-16LE"}, {"Arabic (ISO-8859-6)", "ISO-8859-6"}, {"Arabic (WINDOWS-1256)", "WINDOWS-1256"}, {"Baltic (LATIN7)", "LATIN7"}, {"Baltic (WINDOWS-1257)", "WINDOWS-1257"}, {"Celtic (LATIN8)", "LATIN8"}, {"Central European (WINDOWS-1250)", "WINDOWS-1250"}, {"Cyrillic (ISO-8859-5)", "ISO-8859-5"}, {"Cyrillic (WINDOWS-1251)", "WINDOWS-1251"}, {"Eastern European (ISO-8859-2)", "ISO-8859-2"}, {"Western Languages (WINDOWS-1252)", "WINDOWS-1252"}, {"Greek (ISO-8859-7)", "ISO-8859-7"}, {"Greek (WINDOWS-1253)", "WINDOWS-1253"}, {"Hebrew (ISO-8859-8)", "ISO-8859-8"}, {"Hebrew (WINDOWS-1255)", "WINDOWS-1255"}, {"Japanese (SHIFT-JIS)", "SHIFT-JIS"}, {"Japanese (ISO-2022-JP-2)", "ISO-2022-JP-2"}, {"Korean (EUC-KR)", "EUC-KR"}, {"Korean (CP949)", "CP949"}, {"Korean (ISO-2022-KR)", "ISO-2022-KR"}, {"Nordic (LATIN6)", "LATIN6"}, {"North European (LATIN4)", "LATIN4"}, {"Russian (KOI8-R)", "KOI8-R"}, {"Simplified Chinese (GBK)", "GBK"}, {"Simplified Chinese (GB18030)", "GB18030"}, {"Simplified Chinese (ISO-2022-CN-EXT)", "ISO-2022-CN-EXT"}, {"South European (LATIN3)", "LATIN3"}, {"South-Eastern European (LATIN10)", "LATIN10"}, {"Thai (TIS-620)", "TIS-620"}, {"Thai (WINDOWS-874)", "WINDOWS-874"}, {"Traditional Chinese (EUC-TW)", "EUC-TW"}, {"Traditional Chinese (BIG5)", "BIG5"}, {"Traditional Chinese (BIG5-HKSCS)", "BIG5-HKSCS"}, {"Turkish (LATIN5)", "LATIN5"}, {"Turkish (WINDOWS-1254)", "WINDOWS-1254"}, {"Ukrainian (KOI8-U)", "KOI8-U"}, {"Vietnamese (WINDOWS-1258)", "WINDOWS-1258"}, {"Vietnamese (VISCII)", "VISCII"}, {"Western European (LATIN1)", "LATIN1"}, {"Western European (LATIN-9)", "LATIN-9"} }; auto p = list.begin(); while (p != list.end()) { DEF_ACTION_CHECKED_GROUP(p->first, ActionKind::ChangeSubCodepage, group); auto act = menu->actions().last(); act->setProperty("args", QList() << p->second); if (p->second == "auto") menu->addSeparator(); p++; } parent->addMenu(menu); } parent->addMenu(menu); } { //sub menu auto *parent = menu; auto *menu = new QMenu(tr("Screenshot")); DEF_ACTION(tr("Film Screenshot"), ActionKind::Screenshot); DEF_ACTION(tr("Burst Shooting"), ActionKind::BurstScreenshot); parent->addMenu(menu); } menu->addSeparator(); DEF_ACTION_CHECKED(tr("Playlist"), ActionKind::TogglePlaylist); DEF_ACTION(tr("Film Info"), ActionKind::MovieInfo); DEF_ACTION(tr("Settings"), ActionKind::Settings); _contextMenu = menu; } return _contextMenu; } QMenu* ActionFactory::playlistContextMenu() { if (!_playlistMenu) { auto *menu = new QMenu(); DEF_ACTION(tr("Clear playlist"), ActionKind::EmptyPlaylist); DEF_ACTION(tr("Display in file manager"), ActionKind::PlaylistOpenItemInFM); DEF_ACTION(tr("Film info"), ActionKind::PlaylistItemInfo); _playlistMenu = menu; } return _playlistMenu; } QList ActionFactory::findActionsByKind(ActionKind target_kd) { QList res; auto p = _contextMenuActions.begin(); while (p != _contextMenuActions.end()) { #if QT_VERSION < QT_VERSION_CHECK(5, 7, 0) auto kd = (ActionKind)(*p)->property("kind").value(); #else auto kd = (*p)->property("kind").value(); #endif if (kd == target_kd) { res.append(*p); } ++p; } return res; } void ActionFactory::updateMainActionsForMovie(const PlayingMovieInfo& pmf) { qDebug() << __func__; if (_subtitleMenu) { auto menu = _subtitleMenu; menu->clear(); auto group = new QActionGroup(menu); // mem leak ? for (int i = 0; i < pmf.subs.size(); i++) { DEF_ACTION_CHECKED_GROUP(pmf.subs[i]["title"].toString(), ActionKind::SelectSubtitle, group); auto act = menu->actions().last(); act->setProperty("args", QList() << i); } _subtitleMenu->setEnabled(pmf.subs.size() > 0); } if (_subtitleMenu) { auto menu = _tracksMenu; menu->clear(); auto group = new QActionGroup(menu); // mem leak ? for (int i = 0; i < pmf.audios.size(); i++) { DEF_ACTION_CHECKED_GROUP(pmf.audios[i]["title"].toString(), ActionKind::SelectTrack, group); auto act = menu->actions().last(); act->setProperty("args", QList() << i); } _tracksMenu->setEnabled(pmf.audios.size() > 0); } } #undef DEF_ACTION #undef DEF_ACTION_CHECKED } deepin-movie-reborn-5.0.0/src/common/actions.h000066400000000000000000000107351351125414100212550ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_ACTIONS_H #define _DMR_ACTIONS_H #include namespace dmr { class PlayingMovieInfo; class ActionFactory: public QObject { Q_OBJECT public: enum ActionKind { Invalid = 0, OpenFile = 1, OpenFileList, OpenDirectory, StartPlay, Settings, LightTheme, About, Help, Exit, TogglePlaylist, EmptyPlaylist, PlaylistRemoveItem, PlaylistOpenItemInFM, PlaylistItemInfo, MovieInfo, OpenUrl, OpenCdrom, ToggleFullscreen, QuitFullscreen, ToggleMiniMode, WindowAbove, LoadSubtitle, SelectSubtitle, // stub for subs loaded from movie HideSubtitle, MatchOnlineSubtitle, ChangeSubCodepage, Screenshot, BurstScreenshot, SeekForward, SeekForwardLarge, SeekBackward, SeekBackwardLarge, SeekAbsolute, TogglePause, Stop, AccelPlayback, DecelPlayback, ResetPlayback, SubDelay, //backward SubForward, //play mode OrderPlay, ShufflePlay, SinglePlay, SingleLoop, ListLoop, //frame DefaultFrame, Ratio4x3Frame, Ratio16x9Frame, Ratio16x10Frame, Ratio185x1Frame, Ratio235x1Frame, ClockwiseFrame, CounterclockwiseFrame, NextFrame, PreviousFrame, //sound Stereo, LeftChannel, RightChannel, LoadTrack, SelectTrack, // stub for tracks loaded from movie GotoPlaylistNext, GotoPlaylistPrev, GotoPlaylistSelected, VolumeUp, VolumeDown, ToggleMute, ChangeVolume, ViewShortcut, }; Q_ENUM(ActionKind) static ActionFactory& get(); QMenu* titlebarMenu(); QMenu* mainContextMenu(); template void forEachInMainMenu(UnaryFunction f); QMenu* playlistContextMenu(); QList findActionsByKind(ActionKind kd); void updateMainActionsForMovie(const PlayingMovieInfo& pmf); static bool actionHasArgs(QAction* act) { return act->property("args").isValid(); } static QList actionArgs(QAction* act) { return act->property("args").toList(); } static ActionKind actionKind(QAction* act) { #if QT_VERSION < QT_VERSION_CHECK(5, 6, 2) auto kd = (ActionKind)act->property("kind").value(); #else auto kd = act->property("kind").value(); #endif return kd; } static bool isActionFromShortcut(QAction* act) { auto s = act->property("origin"); return s.toString() == "shortcut"; } private: ActionFactory() {} QMenu *_titlebarMenu {nullptr}; QMenu *_contextMenu {nullptr}; QMenu *_subtitleMenu {nullptr}; QMenu *_tracksMenu {nullptr}; QMenu *_playlistMenu {nullptr}; QList _contextMenuActions; }; template void ActionFactory::forEachInMainMenu(UnaryFunction f) { auto p = _contextMenuActions.begin(); while (p != _contextMenuActions.end()) { if (strcmp((*p)->metaObject()->className(), "QAction") == 0) f(*p); ++p; } } } #endif /* ifndef _DMR_ACTIONS_H */ deepin-movie-reborn-5.0.0/src/common/dbus_adpator.cpp000066400000000000000000000036551351125414100226220ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "dbus_adpator.h" ApplicationAdaptor::ApplicationAdaptor(MainWindow* mw) :QDBusAbstractAdaptor(mw), _mw(mw) { } void ApplicationAdaptor::openFiles(const QStringList& list) { _mw->playList(list); } void ApplicationAdaptor::openFile(const QString& file) { QRegExp url_re("\\w+://"); QUrl url; if (url_re.indexIn(file) == 0) { url = QUrl(file); } else { url = QUrl::fromLocalFile(file); } _mw->play(url); } deepin-movie-reborn-5.0.0/src/common/dbus_adpator.h000066400000000000000000000036661351125414100222710ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_DBUS_ADAPTOR #define _DMR_DBUS_ADAPTOR #include #include "mainwindow.h" using namespace dmr; class ApplicationAdaptor: public QDBusAbstractAdaptor { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "com.deepin.movie") public: ApplicationAdaptor(MainWindow* mw); public slots: void openFile(const QString& url); void openFiles(const QStringList& list); private: MainWindow *_mw {nullptr}; }; #endif /* ifndef _DMR_DBUS_ADAPTOR */ deepin-movie-reborn-5.0.0/src/common/dmr_settings.cpp000066400000000000000000000141251351125414100226470ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include #include #include "dmr_settings.h" #include namespace dmr { using namespace Dtk::Core; static Settings* _theSettings = nullptr; Settings& Settings::get() { if (!_theSettings) { _theSettings = new Settings; } return *_theSettings; } Settings::Settings() : QObject(0) { _configPath = QString("%1/%2/%3/config.conf") .arg(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)) .arg(qApp->organizationName()) .arg(qApp->applicationName()); qDebug() << "configPath" << _configPath; auto backend = new QSettingBackend(_configPath); _settings = DSettings::fromJsonFile(":/resources/data/settings.json"); _settings->setBackend(backend); connect(_settings, &DSettings::valueChanged, [=](const QString& key, const QVariant& value) { if (key.startsWith("shortcuts.")) emit shortcutsChanged(key, value); else if (key.startsWith("base.")) emit baseChanged(key, value); else if (key.startsWith("subtitle.")) emit subtitleChanged(key, value); }); //qDebug() << "keys" << _settings->keys(); QFontDatabase fontDatabase; auto fontFamliy = _settings->option("subtitle.font.family"); fontFamliy->setData("items", fontDatabase.families()); //fontFamliy->setValue(0); } static QString flag2key(Settings::Flag f) { switch(f) { case Settings::Flag::ClearWhenQuit: return "emptylist"; case Settings::Flag::ResumeFromLast: return "resumelast"; case Settings::Flag::AutoSearchSimilar: return "addsimilar"; case Settings::Flag::PreviewOnMouseover: return "mousepreview"; case Settings::Flag::MultipleInstance: return "multiinstance"; case Settings::Flag::PauseOnMinimize: return "pauseonmin"; case Settings::Flag::HWAccel: return "hwaccel"; } return ""; } bool Settings::isSet(Flag f) const { auto subgroups = _settings->group("base")->childGroups(); auto grp = std::find_if(subgroups.begin(), subgroups.end(), [=](GroupPtr grp) { return grp->key() == "base.play"; }); if (grp != subgroups.end()) { auto sub = (*grp)->childOptions(); auto key = flag2key(f); auto p = std::find_if(sub.begin(), sub.end(), [=](OptionPtr opt) { auto sk = opt->key(); sk.remove(0, sk.lastIndexOf('.') + 1); return sk == key; }); return p != sub.end() && (*p)->value().toBool(); } return false; } QStringList Settings::commonPlayableProtocols() const { //from mpv and combined with stream media protocols return { "http", "https", "bd", "ytdl", "smb", "dvd", "dvdread", "tv", "pvr", "dvb", "cdda", "lavf", "av", "avdevice", "fd", "fdclose", "edl", "mf", "null", "memory", "hex", "rtmp", "rtsp", "hls", "mms", "rtp", "rtcp" }; } bool Settings::iscommonPlayableProtocol(const QString& scheme) const { for (auto pro: commonPlayableProtocols()) { if (pro == scheme) return true; } return false; } QString Settings::screenshotLocation() { QString save_path = settings()->value("base.screenshot.location").toString(); if (save_path.size() && save_path[0] == '~') { save_path.replace(0, 1, QDir::homePath()); } if (!QFileInfo(save_path).exists()) { QDir d; d.mkpath(save_path); } return save_path; } QString Settings::screenshotNameTemplate() { return tr("%1/DMovie%2.jpg").arg(screenshotLocation()) .arg(QDateTime::currentDateTime().toString("yyyyMMddhhmmss")); } QString Settings::screenshotNameSeqTemplate() { return tr("%1/DMovie%2(%3).jpg").arg(screenshotLocation()) .arg(QDateTime::currentDateTime().toString("yyyyMMddhhmmss")); } void Settings::setGeneralOption(const QString &opt, const QVariant &v) { settings()->setOption(QString("base.general.%1").arg(opt), v); settings()->sync(); } QVariant Settings::generalOption(const QString &opt) { return settings()->getOption(QString("base.general.%1").arg(opt)); } QVariant Settings::internalOption(const QString& opt) { return settings()->getOption(QString("base.play.%1").arg(opt)); } void Settings::setInternalOption(const QString& opt, const QVariant& v) { settings()->setOption(QString("base.play.%1").arg(opt), v); settings()->sync(); } QString Settings::forcedInterop() { return internalOption("forced_interop").toString(); } bool Settings::disableInterop() { return internalOption("disable_interop").toBool(); } } deepin-movie-reborn-5.0.0/src/common/dmr_settings.h000066400000000000000000000067251351125414100223230ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_SETTINGS_H #define _DMR_SETTINGS_H #include #include #include #include #include namespace dmr { using namespace Dtk::Core; class Settings: public QObject { Q_OBJECT public: enum Flag { ClearWhenQuit, ResumeFromLast, AutoSearchSimilar, PreviewOnMouseover, MultipleInstance, PauseOnMinimize, HWAccel, }; static Settings& get(); QString configPath() const { return _configPath; } QPointer settings() { return _settings; } QPointer group(const QString& name) { return settings()->group(name); } QPointer shortcuts() { return group("shortcuts"); } QPointer base() { return group("base"); } QPointer subtitle() { return group("subtitle"); } void setGeneralOption(const QString& opt, const QVariant& v); QVariant generalOption(const QString& opt); void setInternalOption(const QString& opt, const QVariant& v); QVariant internalOption(const QString& opt); // user override for mpv opengl interop QString forcedInterop(); // disable interop at all bool disableInterop(); // convient helpers bool isSet(Flag f) const; QStringList commonPlayableProtocols() const; bool iscommonPlayableProtocol(const QString& scheme) const; QString screenshotLocation(); QString screenshotNameTemplate(); QString screenshotNameSeqTemplate(); signals: void shortcutsChanged(const QString&, const QVariant&); void baseChanged(const QString&, const QVariant&); void subtitleChanged(const QString&, const QVariant&); private: Settings(); QPointer _settings; QString _configPath; }; } #endif /* ifndef _DMR_SETTINGS_H */ deepin-movie-reborn-5.0.0/src/common/event_monitor.cpp000066400000000000000000000113711351125414100230350ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #undef Bool #include #include "event_monitor.h" #define Bool int #include #include #include #undef Bool void callback(XPointer ptr, XRecordInterceptData* data) { ((dmr::EventMonitor *) ptr)->handleRecordEvent(data); } namespace dmr { EventMonitor::EventMonitor(QObject *parent) : QThread(parent) { isPress = false; } void EventMonitor::run() { Display* display = XOpenDisplay(0); if (display == 0) { fprintf(stderr, "unable to open display\n"); return; } // Receive from ALL clients, including future clients. //XRecordClientSpec clients = XRecordAllClients; XRecordClientSpec clients = XRecordCurrentClients; XRecordRange* range = XRecordAllocRange(); if (range == 0) { fprintf(stderr, "unable to allocate XRecordRange\n"); return; } memset(range, 0, sizeof(XRecordRange)); range->device_events.first = ButtonPress; range->device_events.last = MotionNotify; // And create the XRECORD context. XRecordContext context = XRecordCreateContext (display, 0, &clients, 1, &range, 1); if (context == 0) { fprintf(stderr, "XRecordCreateContext failed\n"); return; } XFree(range); XSync(display, True); Display* display_datalink = XOpenDisplay(0); if (display_datalink == 0) { fprintf(stderr, "unable to open second display\n"); return; } if (!XRecordEnableContext(display_datalink, context, callback, (XPointer) this)) { fprintf(stderr, "XRecordEnableContext() failed\n"); return; } } void EventMonitor::handleRecordEvent(void* dat) { XRecordInterceptData* data = (XRecordInterceptData*)dat; if (!_recording) { XRecordFreeData(data); return; } if (data->category == XRecordFromServer) { xEvent * event = (xEvent *)data->data; switch (event->u.u.type) { case ButtonPress: if (event->u.u.detail != WheelUp && event->u.u.detail != WheelDown && event->u.u.detail != WheelLeft && event->u.u.detail != WheelRight) { isPress = true; emit buttonedPress(event->u.keyButtonPointer.rootX, event->u.keyButtonPointer.rootY); } break; case MotionNotify: if (isPress) { emit buttonedDrag(event->u.keyButtonPointer.rootX, event->u.keyButtonPointer.rootY); } break; case ButtonRelease: if (event->u.u.detail != WheelUp && event->u.u.detail != WheelDown && event->u.u.detail != WheelLeft && event->u.u.detail != WheelRight) { isPress = false; emit buttonedRelease(event->u.keyButtonPointer.rootX, event->u.keyButtonPointer.rootY); } break; default: break; } } XRecordFreeData(data); } void EventMonitor::resumeRecording() { if (!_recording) { _recording = 1; } } void EventMonitor::suspendRecording() { if (_recording) { if (isPress) { isPress = false; auto p = QCursor::pos(); emit buttonedRelease(p.x(), p.y()); } _recording = 0; } } } deepin-movie-reborn-5.0.0/src/common/event_monitor.h000066400000000000000000000043061351125414100225020ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef EVENTMONITOR_H #define EVENTMONITOR_H #include namespace dmr { // Virtual button codes that are not defined by X11. #define Button1 1 #define Button2 2 #define Button3 3 #define WheelUp 4 #define WheelDown 5 #define WheelLeft 6 #define WheelRight 7 #define XButton1 8 #define XButton2 9 class EventMonitor : public QThread { Q_OBJECT public: EventMonitor(QObject *parent = 0); void handleRecordEvent(void *); void resumeRecording(); void suspendRecording(); signals: void buttonedPress(int x, int y); void buttonedDrag(int x, int y); void buttonedRelease(int x, int y); protected: void run(); private: bool isPress; QAtomicInt _recording {1}; }; } #endif deepin-movie-reborn-5.0.0/src/common/event_relayer.cpp000066400000000000000000000063511351125414100230130ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include #include #include #include #include "event_relayer.h" namespace dmr { EventRelayer::EventRelayer(QWindow* src, QWindow *dest) :QObject(), QAbstractNativeEventFilter(), _source(src), _target(dest) { #if 0 int screen = 0; xcb_screen_t *s = xcb_aux_get_screen (QX11Info::connection(), screen); const uint32_t data[] = { XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_EXPOSURE }; xcb_change_window_attributes (QX11Info::connection(), _source->winId(), XCB_CW_EVENT_MASK, data); #endif qApp->installNativeEventFilter(this); } EventRelayer::~EventRelayer() { qApp->removeNativeEventFilter(this); } bool EventRelayer::nativeEventFilter(const QByteArray &eventType, void *message, long *) { if(Q_LIKELY(eventType == "xcb_generic_event_t")) { xcb_generic_event_t* event = static_cast(message); switch (event->response_type & ~0x80) { case XCB_CONFIGURE_NOTIFY: { xcb_configure_notify_event_t *cne = (xcb_configure_notify_event_t*)event; if (cne->window == _source->winId()) { QPoint p(cne->x, cne->y); if (p != _target->framePosition()) { //qDebug() << "cne: " << QRect(cne->x, cne->y, cne->width, cne->height) //<< "origin: " << _source->framePosition() //<< "dest: " << _target->framePosition(); emit targetNeedsUpdatePosition(QPoint(cne->x, cne->y)); } } break; } default: break; } } return false; } } deepin-movie-reborn-5.0.0/src/common/event_relayer.h000066400000000000000000000040741351125414100224600ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_EVENT_RELAYER_H #define _DMR_EVENT_RELAYER_H #include #include #include #include #include namespace dmr { class EventRelayer: public QObject, public QAbstractNativeEventFilter { Q_OBJECT public: EventRelayer(QWindow* src, QWindow *dest); ~EventRelayer(); signals: void targetNeedsUpdatePosition(const QPoint& p); protected: bool nativeEventFilter(const QByteArray &eventType, void *message, long *) override; private: QWindow *_source, *_target; }; } #endif /* ifndef _DMR_EVENT_RELAYER_H */ deepin-movie-reborn-5.0.0/src/common/mainwindow.cpp000066400000000000000000002641071351125414100223300ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "config.h" #include "mainwindow.h" #include "toolbox_proxy.h" #include "actions.h" #include "event_monitor.h" #include "compositing_manager.h" #include "shortcut_manager.h" #include "dmr_settings.h" #include "utility.h" #include "movieinfo_dialog.h" #include "burst_screenshots_dialog.h" #include "playlist_widget.h" #include "notification_widget.h" #include "player_engine.h" #include "url_dialog.h" #include "movie_progress_indicator.h" #include "options.h" #include "titlebar.h" #include "utils.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define AUTOHIDE_TIMEOUT 2000 DWIDGET_USE_NAMESPACE using namespace dmr; #define MOUSE_MARGINS 6 static void workaround_updateStyle(QWidget *parent, const QString &theme) { parent->setStyle(QStyleFactory::create(theme)); for (auto obj : parent->children()) { auto w = qobject_cast(obj); if (w) { workaround_updateStyle(w, theme); } } } static QWidget *createSelectableLineEditOptionHandle(QObject *opt) { auto option = qobject_cast(opt); auto le = new DLineEdit(); le->setFixedHeight(24); le->setObjectName("OptionSelectableLineEdit"); le->setText(option->value().toString()); le->setMaxLength(255); le->setIconVisible(true); le->setNormalIcon(":resources/icons/select-normal.svg"); le->setHoverIcon(":resources/icons/select-hover.svg"); le->setPressIcon(":resources/icons/select-press.svg"); auto optionWidget = DSettingsWidgetFactory::createTwoColumWidget(option, le); workaround_updateStyle(optionWidget, "dlight"); auto validate = [=](QString name, bool alert = true) -> bool { name = name.trimmed(); if (name.isEmpty()) return false; if (name.size() && name[0] == '~') { name.replace(0, 1, QDir::homePath()); } QFileInfo fi(name); if (fi.exists()) { if (!fi.isDir()) { if (alert) le->showAlertMessage(QObject::tr("Invalid folder")); return false; } if (!fi.isReadable() || !fi.isWritable()) { if (alert) le->showAlertMessage(QObject::tr("You don't have permission to operate this folder")); return false; } } return true; }; option->connect(le, &DLineEdit::iconClicked, [=]() { QString name = QFileDialog::getExistingDirectory(0, QObject::tr("Open folder"), MainWindow::lastOpenedPath(), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); if (validate(name, false)) { option->setValue(name); } }); option->connect(le, &QLineEdit::editingFinished, option, [=]() { if (validate(le->text(), false)) { option->setValue(le->text()); } else { option->setValue(option->defaultValue()); le->setText(option->defaultValue().toString()); } }); option->connect(le, &DLineEdit::textEdited, option, [=](const QString& newStr) { validate(newStr); }); option->connect(option, &DTK_CORE_NAMESPACE::DSettingsOption::valueChanged, le, [ = ](const QVariant & value) { le->setText(value.toString()); le->update(); }); return optionWidget; } class MainWindowFocusMonitor: public QAbstractNativeEventFilter { public: MainWindowFocusMonitor(MainWindow* src) :QAbstractNativeEventFilter(), _source(src) { qApp->installNativeEventFilter(this); } ~MainWindowFocusMonitor() { qApp->removeNativeEventFilter(this); } bool nativeEventFilter(const QByteArray &eventType, void *message, long *) { if(Q_LIKELY(eventType == "xcb_generic_event_t")) { xcb_generic_event_t* event = static_cast(message); switch (event->response_type & ~0x80) { case XCB_LEAVE_NOTIFY: { xcb_leave_notify_event_t *dne = (xcb_leave_notify_event_t*)event; auto w = _source->windowHandle(); if (dne->event == w->winId()) { //qDebug() << "--------- leave " << dne->event << dne->child; emit _source->windowLeaved(); } break; } case XCB_ENTER_NOTIFY: { xcb_enter_notify_event_t *dne = (xcb_enter_notify_event_t*)event; auto w = _source->windowHandle(); if (dne->event == w->winId()) { //qDebug() << "--------- enter " << dne->event << dne->child; emit _source->windowEntered(); } break; } default: break; } } return false; } MainWindow *_source; }; class MainWindowPropertyMonitor: public QAbstractNativeEventFilter { public: MainWindowPropertyMonitor(MainWindow *src) :QAbstractNativeEventFilter(), _mw(src), _source(src->windowHandle()) { qApp->installNativeEventFilter(this); _atomWMState = Utility::internAtom("_NET_WM_STATE"); } ~MainWindowPropertyMonitor() { qApp->removeNativeEventFilter(this); } bool nativeEventFilter(const QByteArray &eventType, void *message, long *) { if(Q_LIKELY(eventType == "xcb_generic_event_t")) { xcb_generic_event_t* event = static_cast(message); switch (event->response_type & ~0x80) { case XCB_PROPERTY_NOTIFY: { xcb_property_notify_event_t *pne = (xcb_property_notify_event_t*)(event); if (pne->atom == _atomWMState && pne->window == (xcb_window_t)_source->winId()) { _mw->syncStaysOnTop(); } break; } default: break; } } return false; } MainWindow *_mw {nullptr}; QWindow* _source {nullptr}; xcb_atom_t _atomWMState; }; class MainWindowEventListener : public QObject { Q_OBJECT public: explicit MainWindowEventListener(QWidget *target) : QObject(target), _window(target->windowHandle()) { } ~MainWindowEventListener() { } void setEnabled(bool v) { enabled = v; } protected: bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE { QWindow *window = qobject_cast(obj); if (!window) return false; switch ((int)event->type()) { case QEvent::MouseButtonPress: { if (!enabled) return false; QMouseEvent *e = static_cast(event); setLeftButtonPressed(true); auto mw = static_cast(parent()); if (mw->insideResizeArea(e->globalPos()) && lastCornerEdge != Utility::NoneEdge) startResizing = true; mw->capturedMousePressEvent(e); if (startResizing) { return true; } break; } case QEvent::MouseButtonRelease: { if (!enabled) return false; QMouseEvent *e = static_cast(event); setLeftButtonPressed(false); qApp->setOverrideCursor(window->cursor()); auto mw = static_cast(parent()); mw->capturedMouseReleaseEvent(e); if (startResizing) { startResizing = false; return true; } startResizing = false; break; } case QEvent::MouseMove: { QMouseEvent *e = static_cast(event); auto mw = static_cast(parent()); mw->resumeToolsWindow(); if (!enabled) return false; const QRect window_visible_rect = _window->frameGeometry() - mw->dragMargins(); if (!leftButtonPressed) { if (mw->insideResizeArea(e->globalPos())) { Utility::CornerEdge mouseCorner = Utility::NoneEdge; QRect cornerRect; /// begin set cursor corner type cornerRect.setSize(QSize(MOUSE_MARGINS * 2, MOUSE_MARGINS * 2)); cornerRect.moveTopLeft(_window->frameGeometry().topLeft()); if (cornerRect.contains(e->globalPos())) { mouseCorner = Utility::TopLeftCorner; goto set_cursor; } cornerRect.moveTopRight(_window->frameGeometry().topRight()); if (cornerRect.contains(e->globalPos())) { mouseCorner = Utility::TopRightCorner; goto set_cursor; } cornerRect.moveBottomRight(_window->frameGeometry().bottomRight()); if (cornerRect.contains(e->globalPos())) { mouseCorner = Utility::BottomRightCorner; goto set_cursor; } cornerRect.moveBottomLeft(_window->frameGeometry().bottomLeft()); if (cornerRect.contains(e->globalPos())) { mouseCorner = Utility::BottomLeftCorner; goto set_cursor; } goto skip_set_cursor; // disable edges /// begin set cursor edge type if (e->globalX() <= window_visible_rect.x()) { mouseCorner = Utility::LeftEdge; } else if (e->globalX() < window_visible_rect.right()) { if (e->globalY() <= window_visible_rect.y()) { mouseCorner = Utility::TopEdge; } else if (e->globalY() >= window_visible_rect.bottom()) { mouseCorner = Utility::BottomEdge; } else { goto skip_set_cursor; } } else if (e->globalX() >= window_visible_rect.right()) { mouseCorner = Utility::RightEdge; } else { goto skip_set_cursor; } set_cursor: if (window->property("_d_real_winId").isValid()) { auto real_wid = window->property("_d_real_winId").toUInt(); Utility::setWindowCursor(real_wid, mouseCorner); } else { Utility::setWindowCursor(window->winId(), mouseCorner); } if (qApp->mouseButtons() == Qt::LeftButton) { updateGeometry(mouseCorner, e); } lastCornerEdge = mouseCorner; return true; skip_set_cursor: lastCornerEdge = mouseCorner = Utility::NoneEdge; return false; } else { qApp->setOverrideCursor(window->cursor()); } } else { if (startResizing) { updateGeometry(lastCornerEdge, e); return true; } } break; } default: break; } return false; } private: void setLeftButtonPressed(bool pressed) { if (leftButtonPressed == pressed) return; if (!pressed) Utility::cancelWindowMoveResize(_window->winId()); leftButtonPressed = pressed; } void updateGeometry(Utility::CornerEdge edge, QMouseEvent* e) { auto mw = static_cast(parent()); bool keep_ratio = mw->engine()->state() != PlayerEngine::CoreState::Idle; auto old_geom = mw->frameGeometry(); auto geom = mw->frameGeometry(); qreal ratio = (qreal)geom.width() / geom.height(); // disable edges switch (edge) { case Utility::BottomEdge: case Utility::TopEdge: case Utility::LeftEdge: case Utility::RightEdge: case Utility::NoneEdge: return; default: break; } if (keep_ratio) { auto sz = mw->engine()->videoSize(); if (sz.isEmpty()) { const auto& mi = mw->engine()->playlist().currentInfo().mi; sz = QSize(mi.width, mi.height); } ratio = sz.width() / (qreal)sz.height(); switch (edge) { case Utility::TopLeftCorner: geom.setLeft(e->globalX()); geom.setTop(geom.bottom() - geom.width() / ratio); break; case Utility::BottomLeftCorner: case Utility::LeftEdge: geom.setLeft(e->globalX()); geom.setHeight(geom.width() / ratio); break; case Utility::BottomRightCorner: case Utility::RightEdge: geom.setRight(e->globalX()); geom.setHeight(geom.width() / ratio); break; case Utility::TopRightCorner: case Utility::TopEdge: geom.setTop(e->globalY()); geom.setWidth(geom.height() * ratio); break; case Utility::BottomEdge: geom.setBottom(e->globalY()); geom.setWidth(geom.height() * ratio); break; default: break; } } else { switch (edge) { case Utility::BottomLeftCorner: geom.setBottomLeft(e->globalPos()); break; case Utility::TopLeftCorner: geom.setTopLeft(e->globalPos()); break; case Utility::LeftEdge: geom.setLeft(e->globalX()); break; case Utility::BottomRightCorner: geom.setBottomRight(e->globalPos()); break; case Utility::RightEdge: geom.setRight(e->globalX()); break; case Utility::TopRightCorner: geom.setTopRight(e->globalPos()); break; case Utility::TopEdge: geom.setTop(e->globalY()); break; case Utility::BottomEdge: geom.setBottom(e->globalY()); break; default: break; } } auto min = mw->minimumSize(); if (old_geom.width() <= min.width() && geom.left() > old_geom.left()) { geom.setLeft(old_geom.left()); } if (old_geom.height() <= min.height() && geom.top() > old_geom.top()) { geom.setTop(old_geom.top()); } geom.setWidth(qMax(geom.width(), min.width())); geom.setHeight(qMax(geom.height(), min.height())); mw->updateContentGeometry(geom); mw->updateGeometryNotification(geom.size()); } bool leftButtonPressed {false}; bool startResizing {false}; bool enabled {true}; Utility::CornerEdge lastCornerEdge; QWindow* _window; }; #ifdef USE_DXCB /// shadow #define SHADOW_COLOR_NORMAL QColor(0, 0, 0, 255 * 0.35) #define SHADOW_COLOR_ACTIVE QColor(0, 0, 0, 255 * 0.6) #endif MainWindow::MainWindow(QWidget *parent) : QFrame(NULL) { bool composited = CompositingManager::get().composited(); #ifdef USE_DXCB setWindowFlags(Qt::FramelessWindowHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); #else setWindowFlags(Qt::FramelessWindowHint); #endif setAcceptDrops(true); if (composited) { setAttribute(Qt::WA_TranslucentBackground, true); //setAttribute(Qt::WA_NoSystemBackground, false); } DThemeManager::instance()->registerWidget(this); setFrameShape(QFrame::NoFrame); #ifdef USE_DXCB if (DApplication::isDXcbPlatform()) { _handle = new DPlatformWindowHandle(this, this); //setAttribute(Qt::WA_TranslucentBackground, true); //if (composited) //_handle->setTranslucentBackground(true); _handle->setEnableSystemResize(false); _handle->setEnableSystemMove(false); _handle->setWindowRadius(4); connect(qApp, &QGuiApplication::focusWindowChanged, this, &MainWindow::updateShadow); updateShadow(); } #else winId(); #endif QSizePolicy sp(QSizePolicy::Preferred, QSizePolicy::Preferred); sp.setHeightForWidth(true); setSizePolicy(sp); qDebug() << "composited = " << composited; setContentsMargins(0, 0, 0, 0); setupTitlebar(); auto& clm = dmr::CommandLineManager::get(); if (clm.debug()) { Backend::setDebugLevel(Backend::DebugLevel::Debug); } else if (clm.verbose()) { Backend::setDebugLevel(Backend::DebugLevel::Verbose); } _engine = new PlayerEngine(this); #ifndef USE_DXCB _engine->move(1, 1); #endif int volume = Settings::get().internalOption("global_volume").toInt(); _engine->changeVolume(volume); _toolbox = new ToolboxProxy(this, _engine); _toolbox->setFocusPolicy(Qt::NoFocus); connect(_engine, &PlayerEngine::stateChanged, [=]() { setInit(_engine->state() != PlayerEngine::Idle); resumeToolsWindow(); updateWindowTitle(); // delayed checking if engine is still idle, in case other videos are schedulered (next/prev req) // and another resize event will happen after that QTimer::singleShot(100, [=]() { if (_engine->state() == PlayerEngine::Idle && !_miniMode && windowState() == Qt::WindowNoState) { this->setMinimumSize(QSize(528, 400)); this->resize(850, 600); } }); }); connect(ActionFactory::get().mainContextMenu(), &QMenu::triggered, this, &MainWindow::menuItemInvoked); connect(ActionFactory::get().playlistContextMenu(), &QMenu::triggered, this, &MainWindow::menuItemInvoked); connect(qApp, &QGuiApplication::focusWindowChanged, [=]() { if (qApp->focusWindow() != windowHandle()) suspendToolsWindow(); else resumeToolsWindow(); }); _playlist = new PlaylistWidget(this, _engine); _playlist->hide(); _playState = new DImageButton(this); _playState->setScaledContents(true); _playState->setObjectName("PlayState"); //_playState->setFixedSize(128, 128); _playState->setVisible(false); connect(_playState, &DImageButton::clicked, [=]() { requestAction(ActionFactory::TogglePause, false, {}, true); }); _progIndicator = new MovieProgressIndicator(this); _progIndicator->setVisible(false); connect(_engine, &PlayerEngine::elapsedChanged, [=]() { _progIndicator->updateMovieProgress(_engine->duration(), _engine->elapsed()); }); // mini ui auto *signalMapper = new QSignalMapper(this); connect(signalMapper, static_cast(&QSignalMapper::mapped), this, &MainWindow::miniButtonClicked); _miniPlayBtn = new DImageButton(this); _miniPlayBtn->setObjectName("MiniPlayBtn"); connect(_miniPlayBtn, SIGNAL(clicked()), signalMapper, SLOT(map())); signalMapper->setMapping(_miniPlayBtn, "play"); connect(_engine, &PlayerEngine::stateChanged, [=]() { qDebug() << __func__ << _engine->state(); if (_engine->state() == PlayerEngine::CoreState::Playing) { _miniPlayBtn->setObjectName("MiniPauseBtn"); if (_lastCookie > 0) { utils::UnInhibitStandby(_lastCookie); qDebug() << "uninhibit cookie" << _lastCookie; _lastCookie = 0; } if (_powerCookie > 0) { utils::UnInhibitPower(_powerCookie); _powerCookie = 0; } _lastCookie = utils::InhibitStandby(); _powerCookie = utils::InhibitPower(); } else { _miniPlayBtn->setObjectName("MiniPlayBtn"); if (_lastCookie > 0) { utils::UnInhibitStandby(_lastCookie); qDebug() << "uninhibit cookie" << _lastCookie; _lastCookie = 0; } if (_powerCookie > 0) { utils::UnInhibitPower(_powerCookie); _powerCookie = 0; } } _miniPlayBtn->setStyleSheet(_miniPlayBtn->styleSheet()); }); _miniCloseBtn = new DImageButton(this); _miniCloseBtn->setObjectName("MiniCloseBtn"); connect(_miniCloseBtn, SIGNAL(clicked()), signalMapper, SLOT(map())); signalMapper->setMapping(_miniCloseBtn, "close"); _miniQuitMiniBtn = new DImageButton(this); _miniQuitMiniBtn->setObjectName("MiniQuitMiniBtn"); connect(_miniQuitMiniBtn, SIGNAL(clicked()), signalMapper, SLOT(map())); signalMapper->setMapping(_miniQuitMiniBtn, "quit_mini"); _miniPlayBtn->setVisible(_miniMode); _miniCloseBtn->setVisible(_miniMode); _miniQuitMiniBtn->setVisible(_miniMode); // ~ updateProxyGeometry(); connect(&ShortcutManager::get(), &ShortcutManager::bindingsChanged, this, &MainWindow::onBindingsChanged); ShortcutManager::get().buildBindings(); connect(_engine, &PlayerEngine::tracksChanged, this, &MainWindow::updateActionsState); connect(_engine, &PlayerEngine::stateChanged, this, &MainWindow::updateActionsState); updateActionsState(); reflectActionToUI(ActionFactory::DefaultFrame); reflectActionToUI(ActionFactory::OrderPlay); reflectActionToUI(ActionFactory::Stereo); requestAction(ActionFactory::ChangeSubCodepage, false, {"auto"}); _lightTheme = Settings::get().internalOption("light_theme").toBool(); if (_lightTheme) reflectActionToUI(ActionFactory::LightTheme); prepareSplashImages(); connect(_engine, &PlayerEngine::sidChanged, [=]() { reflectActionToUI(ActionFactory::ActionKind::SelectSubtitle); }); //NOTE: mpv does not always send a aid-change signal the first time movie is loaded. connect(_engine, &PlayerEngine::aidChanged, [=]() { reflectActionToUI(ActionFactory::ActionKind::SelectTrack); }); connect(_engine, &PlayerEngine::subCodepageChanged, [=]() { reflectActionToUI(ActionFactory::ActionKind::ChangeSubCodepage); }); connect(_engine, &PlayerEngine::fileLoaded, [=]() { if (windowState() == Qt::WindowNoState && _lastRectInNormalMode.isValid()) { const auto& mi = _engine->playlist().currentInfo().mi; _lastRectInNormalMode.setSize({mi.width, mi.height}); } this->resizeByConstraints(); }); connect(_engine, &PlayerEngine::videoSizeChanged, [=]() { this->resizeByConstraints(); }); connect(_engine, &PlayerEngine::stateChanged, this, &MainWindow::animatePlayState); syncPlayState(); connect(_engine, &PlayerEngine::loadOnlineSubtitlesFinished, [this](const QUrl& url, bool success) { _nwComm->updateWithMessage(success?tr("Load successfully"):tr("Load failed")); }); connect(&_autoHideTimer, &QTimer::timeout, this, &MainWindow::suspendToolsWindow); _autoHideTimer.setSingleShot(true); connect(&_delayedMouseReleaseTimer, &QTimer::timeout, this, &MainWindow::delayedMouseReleaseHandler); _delayedMouseReleaseTimer.setSingleShot(true); _nwComm = new NotificationWidget(this); _nwComm->setFixedHeight(30); _nwComm->setAnchor(NotificationWidget::AnchorNorthWest); _nwComm->setAnchorPoint(QPoint(30, 38)); _nwComm->hide(); #ifdef USE_DXCB if (!composited) { connect(qApp, &QGuiApplication::applicationStateChanged, this, &MainWindow::onApplicationStateChanged); _evm = new EventMonitor(this); connect(_evm, &EventMonitor::buttonedPress, this, &MainWindow::onMonitorButtonPressed); connect(_evm, &EventMonitor::buttonedDrag, this, &MainWindow::onMonitorMotionNotify); connect(_evm, &EventMonitor::buttonedRelease, this, &MainWindow::onMonitorButtonReleased); _evm->start(); } _listener = new MainWindowEventListener(this); this->windowHandle()->installEventFilter(_listener); //auto mwfm = new MainWindowFocusMonitor(this); auto mwpm = new MainWindowPropertyMonitor(this); connect(this, &MainWindow::windowEntered, &MainWindow::resumeToolsWindow); connect(this, &MainWindow::windowLeaved, &MainWindow::suspendToolsWindow); #else _listener = new MainWindowEventListener(this); this->windowHandle()->installEventFilter(_listener); //auto mwfm = new MainWindowFocusMonitor(this); auto mwpm = new MainWindowPropertyMonitor(this); connect(this, &MainWindow::windowEntered, &MainWindow::resumeToolsWindow); connect(this, &MainWindow::windowLeaved, &MainWindow::suspendToolsWindow); if (!composited) { if (_engine->windowHandle()) _engine->windowHandle()->installEventFilter(_listener); _titlebar->windowHandle()->installEventFilter(_listener); _toolbox->windowHandle()->installEventFilter(_listener); } qDebug() << "event listener"; #endif } void MainWindow::setupTitlebar() { _titlebar = new Titlebar(this); #ifdef USE_DXCB _titlebar->move(0, 0); #else _titlebar->move(1, 1); #endif _titlebar->setFixedHeight(30); _titlebar->layout()->setContentsMargins(0, 0, 0, 0); _titlebar->setFocusPolicy(Qt::NoFocus); if (!CompositingManager::get().composited()) { _titlebar->setAttribute(Qt::WA_NativeWindow); _titlebar->winId(); } _titlebar->setMenu(ActionFactory::get().titlebarMenu()); { auto dpr = qApp->devicePixelRatio(); int w2 = 24 * dpr; int w = 16 * dpr; //hack: titlebar fixed icon size to (24x24), but we need (16x16) auto logo = QPixmap(":/resources/icons/logo.svg") .scaled(w, w, Qt::KeepAspectRatio, Qt::SmoothTransformation); logo.setDevicePixelRatio(dpr); QPixmap pm(w2, w2); pm.setDevicePixelRatio(dpr); pm.fill(Qt::transparent); QPainter p(&pm); p.drawPixmap((w2-w)/2, (w2-w)/2, logo); p.end(); _titlebar->setIcon(pm); _titlebar->setTitle(QString()); } { auto help = new QShortcut(QKeySequence(Qt::Key_F1), this); help->setContext(Qt::ApplicationShortcut); connect(help, &QShortcut::activated, this, &MainWindow::handleHelpAction); } connect(_titlebar->menu(), &QMenu::triggered, this, &MainWindow::menuItemInvoked); } void MainWindow::updateContentGeometry(const QRect& rect) { #ifdef USE_DXCB auto frame = QWindow::fromWinId(windowHandle()->winId()); QRect frame_rect = rect; if (_handle) { frame_rect += _handle->frameMargins(); } const uint32_t values[] = { (uint32_t)frame_rect.x(), (uint32_t)frame_rect.y(), (uint32_t)frame_rect.width(), (uint32_t)frame_rect.height() }; // manually configure frame window which will in turn update content window xcb_configure_window(QX11Info::connection(), windowHandle()->winId(), XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_X, values); #else setGeometry(rect); #endif } #ifdef USE_DXCB void MainWindow::updateShadow() { if (isActiveWindow()) { _handle->setShadowRadius(60); _handle->setShadowColor(SHADOW_COLOR_ACTIVE); } else { _handle->setShadowRadius(60); _handle->setShadowColor(SHADOW_COLOR_NORMAL); } } #endif bool MainWindow::event(QEvent *ev) { if (ev->type() == QEvent::WindowStateChange) { auto wse = dynamic_cast(ev); _lastWindowState = wse->oldState(); qDebug() << "------------ _lastWindowState" << _lastWindowState << "current " << windowState(); //NOTE: windowStateChanged won't be emitted if by draggint to restore. so we need to //check window state here. //connect(windowHandle(), &QWindow::windowStateChanged, this, &MainWindow::onWindowStateChanged); onWindowStateChanged(); } return QFrame::event(ev); } void MainWindow::onWindowStateChanged() { qDebug() << windowState(); // if (!isFullScreen()) { // qApp->restoreOverrideCursor(); // if (_lastCookie > 0) { // utils::UnInhibitStandby(_lastCookie); // qDebug() << "uninhibit cookie" << _lastCookie; // _lastCookie = 0; // } // if (_listener) _listener->setEnabled(!isMaximized() && !_miniMode); // } else { // qApp->setOverrideCursor(Qt::BlankCursor); // if (_lastCookie > 0) { // utils::UnInhibitStandby(_lastCookie); // qDebug() << "uninhibit cookie" << _lastCookie; // _lastCookie = 0; // } // _lastCookie = utils::InhibitStandby(); // qDebug() << "inhibit cookie" << _lastCookie; // if (_listener) _listener->setEnabled(false); // } if (!_miniMode && !isFullScreen()) { _titlebar->setVisible(_toolbox->isVisible()); } else { _titlebar->setVisible(false); } //WTF: this->geometry() is not size of fullscreen ! //_progIndicator->move(geometry().width() - _progIndicator->width() - 18, 14); _progIndicator->setVisible(isFullScreen()); toggleShapeMask(); #ifndef USE_DXCB if (isFullScreen()) { _titlebar->move(0, 0); _engine->move(0, 0); } else { _titlebar->move(1, 1); _engine->move(1, 1); } #endif if (!isFullScreen() && !isMaximized()) { if (_movieSwitchedInFsOrMaxed || !_lastRectInNormalMode.isValid()) { if (_mousePressed || _mouseMoved) { _delayedResizeByConstraint = true; } else { setMinimumSize({0, 0}); resizeByConstraints(true); } } _movieSwitchedInFsOrMaxed = false; } update(); if (isMinimized()) { if (_playlist->state() == PlaylistWidget::Opened) { _playlist->togglePopup(); } } } void MainWindow::handleHelpAction() { class _DApplication : public DApplication { public: inline void showHelp() { DApplication::handleHelpAction(); } }; DApplication *dapp = qApp; reinterpret_cast<_DApplication*>(dapp)->_DApplication::showHelp(); } #ifdef USE_DXCB static QPoint last_engine_pos; static QPoint last_wm_pos; static bool clicked = false; void MainWindow::onMonitorButtonPressed(int x, int y) { QPoint p(x, y); int d = 2; QMargins m(d, d, d, d); if (geometry().marginsRemoved(m).contains(p)) { auto w = qApp->topLevelAt(p); if (w && w == this) { qDebug() << __func__ << "click inside main window"; last_wm_pos = QPoint(x, y); last_engine_pos = windowHandle()->framePosition(); clicked = true; } } } void MainWindow::onMonitorButtonReleased(int x, int y) { if (clicked) { qDebug() << __func__; clicked = false; } } void MainWindow::onMonitorMotionNotify(int x, int y) { if (clicked) { QPoint d = QPoint(x, y) - last_wm_pos; windowHandle()->setFramePosition(last_engine_pos + d); } } #endif MainWindow::~MainWindow() { qDebug() << __func__; disconnect(_engine, 0, 0, 0); disconnect(&_engine->playlist(), 0, 0, 0); if (_lastCookie > 0) { utils::UnInhibitStandby(_lastCookie); qDebug() << "uninhibit cookie" << _lastCookie; _lastCookie = 0; } if (_powerCookie > 0) { utils::UnInhibitPower(_powerCookie); _powerCookie = 0; } #ifdef USE_DXCB if (_evm) { disconnect(_evm, 0, 0, 0); delete _evm; } #endif } void MainWindow::onApplicationStateChanged(Qt::ApplicationState e) { switch (e) { case Qt::ApplicationActive: if (qApp->focusWindow()) qDebug() << QString("focus window 0x%1").arg(qApp->focusWindow()->winId(), 0, 16); qApp->setActiveWindow(this); _evm->resumeRecording(); resumeToolsWindow(); break; case Qt::ApplicationInactive: _evm->suspendRecording(); suspendToolsWindow(); break; default: break; } } void MainWindow::startPlayStateAnimation(bool play) { auto r = QRect(QPoint(0, 0), QSize(128, 128)); r.moveCenter(rect().center()); if (!_playState->graphicsEffect()) { auto *effect = new QGraphicsOpacityEffect(_playState); effect->setOpacity(1.0); _playState->setGraphicsEffect(effect); } auto duration = 160; auto curve = QEasingCurve::InOutCubic; auto pa = new QPropertyAnimation(_playState, "geometry"); if (play) { QRect r2 = r; pa->setStartValue(r); r2.setSize({r.width() * 2, r.height() * 2}); r2.moveCenter(r.center()); pa->setEndValue(r2); } else { pa->setEndValue(r); pa->setStartValue(QRect{r.center(), QSize{0, 0}}); } pa->setDuration(duration); pa->setEasingCurve(curve); auto va = new QVariantAnimation(_playState); va->setStartValue(0.0); va->setEndValue(1.0); va->setDuration(duration); va->setEasingCurve(curve); connect(va, &QVariantAnimation::valueChanged, [=](const QVariant& v) { if (!play) _playState->setVisible(true); auto d = v.toFloat(); auto effect = dynamic_cast(_playState->graphicsEffect()); effect->setOpacity(play ? 1.0 - d: d); _playState->update(); }); if (play) { connect(va, &QVariantAnimation::stateChanged, [=]() { if (va->state() == QVariantAnimation::Stopped) { _playState->setVisible(false); } }); } auto pag = new QParallelAnimationGroup; pag->addAnimation(va); pag->addAnimation(pa); pag->start(QVariantAnimation::DeleteWhenStopped); } void MainWindow::animatePlayState() { if (_miniMode) { return; } if (!_inBurstShootMode && _engine->state() == PlayerEngine::CoreState::Paused) { startPlayStateAnimation(false); _playState->raise(); } else if (_engine->state() == PlayerEngine::CoreState::Idle) { _playState->setVisible(false); } else { //do nothing here, startPlayStateAnimation(true) should be started before playback //is restored, or animation will get slow } } void MainWindow::syncPlayState() { auto r = QRect(QPoint(0, 0), QSize(128, 128)); r.moveCenter(rect().center()); _playState->move(r.topLeft()); if (_miniMode) { _playState->setVisible(false); return; } if (!_inBurstShootMode && _engine->state() == PlayerEngine::CoreState::Paused) { _playState->setGeometry(r); _playState->setVisible(true); auto effect = dynamic_cast(_playState->graphicsEffect()); if (effect) effect->setOpacity(1.0); } else { _playState->setVisible(false); } } void MainWindow::onBindingsChanged() { qDebug() << __func__; { auto actions = this->actions(); this->actions().clear(); for (auto* act: actions) { delete act; } } auto& scmgr = ShortcutManager::get(); auto actions = scmgr.actionsForBindings(); for (auto* act: actions) { this->addAction(act); connect(act, &QAction::triggered, [=]() { this->menuItemInvoked(act); }); } } void MainWindow::updateActionsState() { auto pmf = _engine->playingMovieInfo(); auto update = [=](QAction* act) { auto kd = ActionFactory::actionKind(act); bool v = true; switch(kd) { case ActionFactory::ActionKind::Screenshot: case ActionFactory::ActionKind::MatchOnlineSubtitle: case ActionFactory::ActionKind::BurstScreenshot: case ActionFactory::ActionKind::ToggleMiniMode: case ActionFactory::ActionKind::WindowAbove: v = _engine->state() != PlayerEngine::Idle; break; case ActionFactory::ActionKind::MovieInfo: v = _engine->state() != PlayerEngine::Idle; if (v) { v = v && _engine->playlist().count(); if (v) { auto pif =_engine->playlist().currentInfo(); v = v && pif.loaded && pif.url.isLocalFile(); } } break; case ActionFactory::ActionKind::HideSubtitle: case ActionFactory::ActionKind::SelectSubtitle: v = pmf.subs.size() > 0; default: break; } act->setEnabled(v); }; ActionFactory::get().updateMainActionsForMovie(pmf); ActionFactory::get().forEachInMainMenu(update); //NOTE: mpv does not always send a aid-change signal the first time movie is loaded. //so we need to workaround it. reflectActionToUI(ActionFactory::ActionKind::SelectTrack); reflectActionToUI(ActionFactory::ActionKind::SelectSubtitle); } void MainWindow::syncStaysOnTop() { static xcb_atom_t atomStateAbove = Utility::internAtom("_NET_WM_STATE_ABOVE"); auto atoms = Utility::windowNetWMState(windowHandle()->winId()); bool window_is_above = atoms.contains(atomStateAbove); if (window_is_above != _windowAbove) { qDebug() << "syncStaysOnTop: window_is_above" << window_is_above; requestAction(ActionFactory::WindowAbove); } } void MainWindow::reflectActionToUI(ActionFactory::ActionKind kd) { QList acts; switch(kd) { case ActionFactory::ActionKind::WindowAbove: case ActionFactory::ActionKind::ToggleFullscreen: case ActionFactory::ActionKind::LightTheme: case ActionFactory::ActionKind::ToggleMiniMode: case ActionFactory::ActionKind::TogglePlaylist: case ActionFactory::ActionKind::HideSubtitle: { qDebug() << __func__ << kd; acts = ActionFactory::get().findActionsByKind(kd); auto p = acts.begin(); while (p != acts.end()) { auto old = (*p)->isEnabled(); (*p)->setEnabled(false); if (kd == ActionFactory::TogglePlaylist) { // here what we read is the last state of playlist (*p)->setChecked(_playlist->state() != PlaylistWidget::Opened); } else { (*p)->setChecked(!(*p)->isChecked()); } (*p)->setEnabled(old); ++p; } break; } case ActionFactory::ActionKind::ChangeSubCodepage: { auto cp = _engine->subCodepage(); qDebug() << "codepage" << cp; acts = ActionFactory::get().findActionsByKind(kd); auto p = acts.begin(); while (p != acts.end()) { auto args = ActionFactory::actionArgs(*p); if (args[0].toString() == cp) { (*p)->setEnabled(false); if (!(*p)->isChecked()) (*p)->setChecked(true); (*p)->setEnabled(true); break; } ++p; } break; } case ActionFactory::ActionKind::SelectTrack: case ActionFactory::ActionKind::SelectSubtitle: { if (_engine->state() == PlayerEngine::Idle) break; auto pmf = _engine->playingMovieInfo(); int id = -1; int idx = -1; if (kd == ActionFactory::ActionKind::SelectTrack) { id = _engine->aid(); for (idx = 0; idx < pmf.audios.size(); idx++) { if (id == pmf.audios[idx]["id"].toInt()) { break; } } } else if (kd == ActionFactory::ActionKind::SelectSubtitle) { id = _engine->sid(); for (idx = 0; idx < pmf.subs.size(); idx++) { if (id == pmf.subs[idx]["id"].toInt()) { break; } } } qDebug() << __func__ << kd << "idx = " << idx; acts = ActionFactory::get().findActionsByKind(kd); auto p = acts.begin(); while (p != acts.end()) { auto args = ActionFactory::actionArgs(*p); (*p)->setEnabled(false); if (args[0].toInt() == idx) { if (!(*p)->isChecked()) (*p)->setChecked(true); } else { (*p)->setChecked(false); } (*p)->setEnabled(true); ++p; } break; } case ActionFactory::ActionKind::Stereo: case ActionFactory::ActionKind::OrderPlay: case ActionFactory::ActionKind::DefaultFrame: { qDebug() << __func__ << kd; acts = ActionFactory::get().findActionsByKind(kd); auto p = acts.begin(); auto old = (*p)->isEnabled(); (*p)->setEnabled(false); (*p)->setChecked(!(*p)->isChecked()); (*p)->setEnabled(old); break; } default: break; } } void MainWindow::menuItemInvoked(QAction *action) { auto kd = ActionFactory::actionKind(action); auto isShortcut = ActionFactory::isActionFromShortcut(action); if (ActionFactory::actionHasArgs(action)) { requestAction(kd, !isShortcut, ActionFactory::actionArgs(action), isShortcut); } else { requestAction(kd, !isShortcut, {}, isShortcut); } if (!isShortcut) { suspendToolsWindow(); } } void MainWindow::switchTheme() { _lightTheme = !_lightTheme; qApp->setTheme(_lightTheme? "light":"dark"); Settings::get().setInternalOption("light_theme", _lightTheme); } bool MainWindow::isActionAllowed(ActionFactory::ActionKind kd, bool fromUI, bool isShortcut) { if (_inBurstShootMode) { return false; } if (_miniMode) { if (fromUI || isShortcut) { switch (kd) { case ActionFactory::ToggleFullscreen: case ActionFactory::TogglePlaylist: case ActionFactory::BurstScreenshot: return false; case ActionFactory::ToggleMiniMode: return true; default: break; } } } if (isMaximized()) { switch(kd) { case ActionFactory::ToggleMiniMode: return true; default: break; } } if (isShortcut) { auto pmf = _engine->playingMovieInfo(); bool v = true; switch(kd) { case ActionFactory::Screenshot: case ActionFactory::ToggleMiniMode: case ActionFactory::MatchOnlineSubtitle: case ActionFactory::BurstScreenshot: v = _engine->state() != PlayerEngine::Idle; break; case ActionFactory::MovieInfo: v = _engine->state() != PlayerEngine::Idle; if (v) { v = v && _engine->playlist().count(); if (v) { auto pif =_engine->playlist().currentInfo(); v = v && pif.loaded && pif.url.isLocalFile(); } } break; case ActionFactory::HideSubtitle: case ActionFactory::SelectSubtitle: v = pmf.subs.size() > 0; default: break; } if (!v) return v; } return true; } void MainWindow::requestAction(ActionFactory::ActionKind kd, bool fromUI, QList args, bool isShortcut) { qDebug() << "kd = " << kd << "fromUI " << fromUI << (isShortcut ? "shortcut":""); if (!isActionAllowed(kd, fromUI, isShortcut)) { qDebug() << kd << "disallowed"; return; } switch (kd) { case ActionFactory::ActionKind::Exit: qApp->quit(); break; case ActionFactory::ActionKind::LightTheme: if (fromUI) switchTheme(); break; case ActionFactory::ActionKind::OpenCdrom: { auto dev = dmr::CommandLineManager::get().dvdDevice(); if (dev.isEmpty()) { dev = probeCdromDevice(); } if (dev.isEmpty()) { _nwComm->updateWithMessage(tr("No device found")); break; } _engine->setDVDDevice(dev); //FIXME: how to tell if it's bluray QUrl url(QString("dvdread:///%1").arg(dev)); //QUrl url(QString("dvdnav://")); play(url); break; } case ActionFactory::ActionKind::OpenUrl: { UrlDialog dlg(this); if (dlg.exec() == QDialog::Accepted) { auto url = dlg.url(); if (url.isValid()) { play(url); } else { _nwComm->updateWithMessage(tr("Parse Failed")); } } break; } case ActionFactory::ActionKind::OpenDirectory: { QString name = QFileDialog::getExistingDirectory(this, tr("Open folder"), lastOpenedPath(), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); QFileInfo fi(name); if (fi.isDir() && fi.exists()) { Settings::get().setGeneralOption("last_open_path", fi.path()); const auto& urls = _engine->addPlayDir(name); if (urls.size()) { _engine->playByName(QUrl("playlist://0")); } } break; } case ActionFactory::ActionKind::OpenFileList: { QStringList filenames = QFileDialog::getOpenFileNames(this, tr("Open file"), lastOpenedPath(), tr("All videos (%1)").arg(_engine->video_filetypes.join(" ")), 0, QFileDialog::HideNameFilterDetails); QList urls; if (filenames.size()) { QFileInfo fileInfo(filenames[0]); if (fileInfo.exists()) { Settings::get().setGeneralOption("last_open_path", fileInfo.path()); } for (const auto& filename: filenames) { urls.append(QUrl::fromLocalFile(filename)); } const auto& valids = _engine->addPlayFiles(urls); _engine->playByName(valids[0]); } break; } case ActionFactory::ActionKind::OpenFile: { QString filename = QFileDialog::getOpenFileName(this, tr("Open file"), lastOpenedPath(), tr("All videos (%1)").arg(_engine->video_filetypes.join(" ")), 0, QFileDialog::HideNameFilterDetails); QFileInfo fileInfo(filename); if (fileInfo.exists()) { Settings::get().setGeneralOption("last_open_path", fileInfo.path()); play(QUrl::fromLocalFile(filename)); } break; } case ActionFactory::ActionKind::StartPlay: { if (_engine->playlist().count() == 0) { requestAction(ActionFactory::ActionKind::OpenFileList); } else { if (_engine->state() == PlayerEngine::CoreState::Idle) { if (Settings::get().isSet(Settings::ResumeFromLast)) { int restore_pos = Settings::get().internalOption("playlist_pos").toInt(); restore_pos = qMax(qMin(restore_pos, _engine->playlist().count()-1), 0); requestAction(ActionFactory::ActionKind::GotoPlaylistSelected, false, {restore_pos}); } else { _engine->play(); } } } break; } case ActionFactory::ActionKind::EmptyPlaylist: { _engine->clearPlaylist(); break; } case ActionFactory::ActionKind::TogglePlaylist: { _playlist->togglePopup(); if (!fromUI) { reflectActionToUI(kd); } this->resumeToolsWindow(); break; } case ActionFactory::ActionKind::ToggleMiniMode: { if (!fromUI) { reflectActionToUI(kd); } toggleUIMode(); break; } case ActionFactory::ActionKind::MovieInfo: { if (_engine->state() != PlayerEngine::CoreState::Idle) { MovieInfoDialog mid(_engine->playlist().currentInfo()); mid.exec(); } break; } case ActionFactory::ActionKind::WindowAbove: _windowAbove = !_windowAbove; /** * switch above state by change windowFlags is unacceptable, since it'll * toggle visibility of window. * ``` auto flags = windowFlags(); if (_windowAbove) { flags |= Qt::WindowStaysOnTopHint; } else { flags &= ~Qt::WindowStaysOnTopHint; } setWindowFlags(flags); show(); ``` */ Utility::setStayOnTop(this, _windowAbove); if (!fromUI) { reflectActionToUI(kd); } break; case ActionFactory::ActionKind::QuitFullscreen: { if (isFullScreen()) { if (_lastWindowState == Qt::WindowMaximized) { showMaximized(); } else { showNormal(); } if (!fromUI) { reflectActionToUI(ActionFactory::ToggleFullscreen); } } break; } case ActionFactory::ActionKind::ToggleFullscreen: { if (isFullScreen()) { if (_lastWindowState == Qt::WindowMaximized) { showMaximized(); } else { setWindowState(windowState() & ~Qt::WindowFullScreen); if (_lastRectInNormalMode.isValid() && !_miniMode && !isMaximized()) { setGeometry(_lastRectInNormalMode); } } } else { if (!_miniMode && (fromUI || isShortcut)) { _lastRectInNormalMode = geometry(); } showFullScreen(); } if (!fromUI) { reflectActionToUI(kd); } break; } case ActionFactory::ActionKind::PlaylistRemoveItem: { _playlist->removeClickedItem(); break; } case ActionFactory::ActionKind::PlaylistOpenItemInFM: { _playlist->openItemInFM(); break; } case ActionFactory::ActionKind::PlaylistItemInfo: { _playlist->showItemInfo(); break; } case ActionFactory::ActionKind::ClockwiseFrame: { auto old = _engine->videoRotation(); _engine->setVideoRotation((old + 90) % 360); break; } case ActionFactory::ActionKind::CounterclockwiseFrame: { auto old = _engine->videoRotation(); _engine->setVideoRotation(((old - 90) + 360) % 360); break; } case ActionFactory::ActionKind::OrderPlay: { _engine->playlist().setPlayMode(PlaylistModel::OrderPlay); break; } case ActionFactory::ActionKind::ShufflePlay: { _engine->playlist().setPlayMode(PlaylistModel::ShufflePlay); break; } case ActionFactory::ActionKind::SinglePlay: { _engine->playlist().setPlayMode(PlaylistModel::SinglePlay); break; } case ActionFactory::ActionKind::SingleLoop: { _engine->playlist().setPlayMode(PlaylistModel::SingleLoop); break; } case ActionFactory::ActionKind::ListLoop: { _engine->playlist().setPlayMode(PlaylistModel::ListLoop); break; } case ActionFactory::ActionKind::Stereo: { _engine->changeSoundMode(Backend::SoundMode::Stereo); break; } case ActionFactory::ActionKind::LeftChannel: { _engine->changeSoundMode(Backend::SoundMode::Left); break; } case ActionFactory::ActionKind::RightChannel: { _engine->changeSoundMode(Backend::SoundMode::Right); break; } case ActionFactory::ActionKind::DefaultFrame: { _engine->setVideoAspect(-1.0); break; } case ActionFactory::ActionKind::Ratio4x3Frame: { _engine->setVideoAspect(4.0 / 3.0); break; } case ActionFactory::ActionKind::Ratio16x9Frame: { _engine->setVideoAspect(16.0 / 9.0); break; } case ActionFactory::ActionKind::Ratio16x10Frame: { _engine->setVideoAspect(16.0 / 10.0); break; } case ActionFactory::ActionKind::Ratio185x1Frame: { _engine->setVideoAspect(1.85); break; } case ActionFactory::ActionKind::Ratio235x1Frame: { _engine->setVideoAspect(2.35); break; } case ActionFactory::ActionKind::ToggleMute: { _engine->toggleMute(); if (_engine->muted()) { _nwComm->updateWithMessage(tr("Muted")); } else { double pert = _engine->volume(); _nwComm->updateWithMessage(tr("Volume: %1%").arg(pert)); } break; } case ActionFactory::ActionKind::ChangeVolume: { if (_engine->muted()) { _engine->toggleMute(); } _engine->changeVolume(args[0].toInt()); Settings::get().setInternalOption("global_volume", qMin(_engine->volume(), 100)); double pert = _engine->volume(); _nwComm->updateWithMessage(tr("Volume: %1%").arg(pert)); break; } case ActionFactory::ActionKind::VolumeUp: { if (_engine->muted()) { _engine->toggleMute(); } _engine->volumeUp(); double pert = _engine->volume(); _nwComm->updateWithMessage(tr("Volume: %1%").arg(pert)); break; } case ActionFactory::ActionKind::VolumeDown: { _engine->volumeDown(); double pert = _engine->volume(); _nwComm->updateWithMessage(tr("Volume: %1%").arg(pert)); break; } case ActionFactory::ActionKind::GotoPlaylistSelected: { _engine->playSelected(args[0].toInt()); break; } case ActionFactory::ActionKind::GotoPlaylistNext: { if (isFullScreen() || isMaximized()) { _movieSwitchedInFsOrMaxed = true; } _engine->next(); break; } case ActionFactory::ActionKind::GotoPlaylistPrev: { if (isFullScreen() || isMaximized()) { _movieSwitchedInFsOrMaxed = true; } _engine->prev(); break; } case ActionFactory::ActionKind::SelectTrack: { Q_ASSERT(args.size() == 1); _engine->selectTrack(args[0].toInt()); if (!fromUI) { reflectActionToUI(kd); } break; } case ActionFactory::ActionKind::MatchOnlineSubtitle: { _engine->loadOnlineSubtitle(_engine->playlist().currentInfo().url); break; } case ActionFactory::ActionKind::SelectSubtitle: { Q_ASSERT(args.size() == 1); _engine->selectSubtitle(args[0].toInt()); if (!fromUI) { reflectActionToUI(kd); } break; } case ActionFactory::ActionKind::ChangeSubCodepage: { Q_ASSERT(args.size() == 1); _engine->setSubCodepage(args[0].toString()); if (!fromUI) { reflectActionToUI(kd); } break; } case ActionFactory::ActionKind::HideSubtitle: { _engine->toggleSubtitle(); break; } case ActionFactory::ActionKind::SubDelay: { _engine->setSubDelay(0.5); auto d = _engine->subDelay(); _nwComm->updateWithMessage(tr("Subtitle %1: %2s") .arg(d > 0.0?tr("delayed"):tr("advanced")).arg(d>0.0?d:-d)); break; } case ActionFactory::ActionKind::SubForward: { _engine->setSubDelay(-0.5); auto d = _engine->subDelay(); _nwComm->updateWithMessage(tr("Subtitle %1: %2s") .arg(d > 0.0?tr("delayed"):tr("advanced")).arg(d>0.0?d:-d)); break; } case ActionFactory::ActionKind::AccelPlayback: { _playSpeed = qMin(2.0, _playSpeed + 0.1); _engine->setPlaySpeed(_playSpeed); _nwComm->updateWithMessage(tr("Speed: %1x").arg(_playSpeed)); break; } case ActionFactory::ActionKind::DecelPlayback: { _playSpeed = qMax(0.1, _playSpeed - 0.1); _engine->setPlaySpeed(_playSpeed); _nwComm->updateWithMessage(tr("Speed: %1x").arg(_playSpeed)); break; } case ActionFactory::ActionKind::ResetPlayback: { _playSpeed = 1.0; _engine->setPlaySpeed(_playSpeed); _nwComm->updateWithMessage(tr("Speed: %1x").arg(_playSpeed)); break; } case ActionFactory::ActionKind::LoadSubtitle: { QString filename = QFileDialog::getOpenFileName(this, tr("Open file"), lastOpenedPath(), tr("Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx)")); if (QFileInfo(filename).exists()) { auto success = _engine->loadSubtitle(QFileInfo(filename)); _nwComm->updateWithMessage(success?tr("Load successfully"):tr("Load failed")); } break; break; } case ActionFactory::ActionKind::TogglePause: { if (_engine->state() == PlayerEngine::Idle && isShortcut) { requestAction(ActionFactory::StartPlay); } else { if (_engine->state() == PlayerEngine::Paused && _playState->isVisible()) { startPlayStateAnimation(true); QTimer::singleShot(160, [=]() { _engine->pauseResume(); }); } else { _engine->pauseResume(); } } break; } case ActionFactory::ActionKind::SeekBackward: { _engine->seekBackward(5); break; } case ActionFactory::ActionKind::SeekForward: { _engine->seekForward(5); break; } case ActionFactory::ActionKind::SeekAbsolute: { Q_ASSERT(args.size() == 1); _engine->seekAbsolute(args[0].toInt()); break; } case ActionFactory::ActionKind::Settings: { handleSettings(); break; } case ActionFactory::ActionKind::Screenshot: { auto img = _engine->takeScreenshot(); QString filePath = Settings::get().screenshotNameTemplate(); bool success = false; if (img.isNull()) qDebug()<< __func__ << "pixmap is null"; else success = img.save(filePath); #ifdef USE_SYSTEM_NOTIFY // Popup notify. QDBusInterface notification("org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications", QDBusConnection::sessionBus()); QStringList actions; actions << "_open" << tr("View"); QVariantMap hints; hints["x-deepin-action-_open"] = QString("xdg-open,%1").arg(filePath); QList arg; arg << (QCoreApplication::applicationName()) // appname << ((unsigned int) 0) // id << QString("deepin-movie") // icon << tr("Movie Screenshot") // summary << QString("%1 %2").arg(tr("Saved to")).arg(filePath) // body << actions // actions << hints // hints << (int) -1; // timeout notification.callWithArgumentList(QDBus::AutoDetect, "Notify", arg); #else if (!_nwShot) { _nwShot = new NotificationWidget(this); _nwShot->setAnchor(NotificationWidget::AnchorNorthWest); _nwShot->setAnchorPoint(QPoint(30, 38)); } auto pm = utils::LoadHiDPIPixmap(QString(":/resources/icons/%1.svg").arg(success?"success":"fail")); auto msg = success?tr("The screenshot is saved"):tr("Failed to save the screenshot"); _nwShot->popupWithIcon(msg, pm); #endif break; } case ActionFactory::ActionKind::BurstScreenshot: { startBurstShooting(); break; } case ActionFactory::ActionKind::ViewShortcut: { QRect rect = window()->geometry(); QPoint pos(rect.x() + rect.width()/2 , rect.y() + rect.height()/2); QStringList shortcutString; QString param1 = "-j=" + ShortcutManager::get().toJson(); QString param2 = "-p=" + QString::number(pos.x()) + "," + QString::number(pos.y()); shortcutString << param1 << param2; QProcess* shortcutViewProcess = new QProcess(); shortcutViewProcess->startDetached("deepin-shortcut-viewer", shortcutString); connect(shortcutViewProcess, SIGNAL(finished(int)), shortcutViewProcess, SLOT(deleteLater())); break; } case ActionFactory::ActionKind::NextFrame: { _engine->nextFrame(); break; } case ActionFactory::ActionKind::PreviousFrame: { _engine->previousFrame(); break; } default: break; } } void MainWindow::onBurstScreenshot(const QImage& frame, qint64 timestamp) { qDebug() << _burstShoots.size(); if (!frame.isNull()) { _burstShoots.append(qMakePair(frame, timestamp)); } if (_burstShoots.size() >= 15 || frame.isNull()) { disconnect(_engine, &PlayerEngine::notifyScreenshot, this, &MainWindow::onBurstScreenshot); _engine->stopBurstScreenshot(); _inBurstShootMode = false; _toolbox->setEnabled(true); if (_listener) _listener->setEnabled(!_miniMode); if (frame.isNull()) { _burstShoots.clear(); if (!_pausedBeforeBurst) _engine->pauseResume(); return; } BurstScreenshotsDialog bsd(_engine->playlist().currentInfo()); bsd.updateWithFrames(_burstShoots); auto ret = bsd.exec(); qDebug() << "BurstScreenshot done"; _burstShoots.clear(); if (!_pausedBeforeBurst) _engine->pauseResume(); if (ret == QDialog::Accepted) { auto poster_path = bsd.savedPosterPath(); if (!_nwShot) { _nwShot = new NotificationWidget(this); _nwShot->setAnchor(NotificationWidget::AnchorNorthWest); _nwShot->setAnchorPoint(QPoint(30, 38)); } auto pm = utils::LoadHiDPIPixmap(QString(":/resources/icons/%1.svg").arg(QFileInfo::exists(poster_path)?"success":"fail")); _nwShot->popupWithIcon(tr("The screenshot is saved"), pm); } } } void MainWindow::startBurstShooting() { _inBurstShootMode = true; _toolbox->setEnabled(false); if (_listener) _listener->setEnabled(false); _pausedBeforeBurst = _engine->paused(); connect(_engine, &PlayerEngine::notifyScreenshot, this, &MainWindow::onBurstScreenshot); _engine->burstScreenshot(); } void MainWindow::handleSettings() { auto dsd = new DSettingsDialog(this); dsd->widgetFactory()->registerWidget("selectableEdit", createSelectableLineEditOptionHandle); dsd->setProperty("_d_QSSThemename", "dark"); dsd->setProperty("_d_QSSFilename", "DSettingsDialog"); dsd->updateSettings(Settings::get().settings()); #if DTK_VERSION > DTK_VERSION_CHECK(2, 0, 6, 0) DThemeManager::instance()->setTheme(dsd, "light"); #else DThemeManager::instance()->registerWidget(dsd); workaround_updateStyle(dsd, "dlight"); #endif //hack: auto subft = dsd->findChild("OptionDSpinBox"); if (subft) { subft->setMinimum(8); } // hack: reset is set to default by QDialog, which makes lineedit's enter // press is responded by reset button auto reset = dsd->findChild("SettingsContentReset"); reset->setDefault(false); reset->setAutoDefault(false); dsd->exec(); delete dsd; Settings::get().settings()->sync(); } void MainWindow::playList(const QList& l) { static QRegExp url_re("\\w+://"); QList urls; for (const auto& filename: l) { qDebug() << filename; QUrl url; if (url_re.indexIn(filename) == 0) { url = QUrl::fromPercentEncoding(filename.toUtf8()); if (!url.isValid()) url = QUrl(filename); } else { url = QUrl::fromLocalFile(filename); } if (url.isValid()) urls.append(url); } const auto& valids = _engine->addPlayFiles(urls); if (valids.size()) { if (!isHidden()) { activateWindow(); } _engine->playByName(valids[0]); } } void MainWindow::play(const QUrl& url) { if (!url.isValid()) return; if (!isHidden()) { activateWindow(); } if (!_engine->addPlayFile(url)) { auto msg = QString(tr("Invalid file: %1").arg(url.fileName())); _nwComm->updateWithMessage(msg); return; } _engine->playByName(url); } void MainWindow::toggleShapeMask() { if (CompositingManager::get().composited()) { return; } #ifndef USE_DXCB if (isFullScreen() || isMaximized()) { clearMask(); } else { QPixmap shape(size()); shape.setDevicePixelRatio(windowHandle()->devicePixelRatio()); shape.fill(Qt::transparent); QPainter p(&shape); p.setRenderHint(QPainter::Antialiasing); QPainterPath pp; pp.addRoundedRect(rect(), RADIUS, RADIUS); p.fillPath(pp, QBrush(Qt::white)); p.end(); setMask(shape.mask()); } #endif } void MainWindow::updateProxyGeometry() { toggleShapeMask(); #ifdef USE_DXCB // border is drawn by dxcb auto view_rect = rect(); #else // leave one pixel for border auto view_rect = rect().marginsRemoved(QMargins(1, 1, 1, 1)); if (isFullScreen()) view_rect = rect(); #endif _engine->resize(view_rect.size()); if (!_miniMode) { if (_titlebar) { _titlebar->setFixedWidth(view_rect.width()); } if (_toolbox) { QRect r(view_rect.left(), height() - TOOLBOX_HEIGHT_EXT - view_rect.top(), view_rect.width(), TOOLBOX_HEIGHT_EXT); if (isFullScreen()) { r.moveTopLeft({0, height() - TOOLBOX_HEIGHT_EXT}); } _toolbox->setGeometry(r); } if (_playlist && !_playlist->toggling()) { int off = isFullScreen()? 0: titlebar()->geometry().bottom(); QRect fixed = { 0, off, 220, toolbox()->geometry().top() + TOOLBOX_TOP_EXTENT - off }; fixed.moveRight(view_rect.right()); _playlist->setGeometry(fixed); } } syncPlayState(); if (_playState) { auto r = QRect(QPoint(0, 0), QSize(128, 128)); r.moveCenter(rect().center()); _playState->move(r.topLeft()); } } void MainWindow::suspendToolsWindow() { if (!_miniMode) { if (_playlist && _playlist->state() == PlaylistWidget::Opened) return; if (qApp->applicationState() == Qt::ApplicationInactive) { } else { // menus are popped up // NOTE: menu keeps focus while hidden, so focusWindow is not used if (ActionFactory::get().mainContextMenu()->isVisible() || ActionFactory::get().titlebarMenu()->isVisible()) return; //if (qApp->focusWindow() != windowHandle()) //return; if (_titlebar->isVisible()) { if (insideToolsArea(mapFromGlobal(QCursor::pos()))) return; } else { if (_toolbox->geometry().contains(mapFromGlobal(QCursor::pos()))) { return; } } } if (_toolbox->anyPopupShown()) return; if (_engine->state() == PlayerEngine::Idle) return; if (_autoHideTimer.isActive()) return; if (isFullScreen()) { if (qApp->focusWindow() == this->windowHandle()) qApp->setOverrideCursor(Qt::BlankCursor); } _titlebar->hide(); _toolbox->hide(); } else { if (_autoHideTimer.isActive()) return; _miniPlayBtn->hide(); _miniCloseBtn->hide(); _miniQuitMiniBtn->hide(); } } void MainWindow::resumeToolsWindow() { if (_engine->state() != PlayerEngine::Idle && qApp->applicationState() == Qt::ApplicationActive) { // playlist's previous state was Opened if (_playlist->state() != PlaylistWidget::Closed && !frameGeometry().contains(QCursor::pos())) { goto _finish; } } qApp->restoreOverrideCursor(); setCursor(Qt::ArrowCursor); if (!_miniMode) { _titlebar->setVisible(!isFullScreen()); _toolbox->show(); } else { _miniPlayBtn->show(); _miniCloseBtn->show(); _miniQuitMiniBtn->show(); } _finish: _autoHideTimer.start(AUTOHIDE_TIMEOUT); } void MainWindow::hideEvent(QHideEvent *event) { if (Settings::get().isSet(Settings::PauseOnMinimize)) { if (_engine && _engine->state() == PlayerEngine::Playing) { _pausedOnHide = true; requestAction(ActionFactory::TogglePause); } } } void MainWindow::closeEvent(QCloseEvent *ev) { qDebug() << __func__; if (_lastCookie > 0) { utils::UnInhibitStandby(_lastCookie); qDebug() << "uninhibit cookie" << _lastCookie; _lastCookie = 0; } int cur = 0; if (Settings::get().isSet(Settings::ResumeFromLast)) { cur = _engine->playlist().current(); if (cur >= 0) { Settings::get().setInternalOption("playlist_pos", cur); } } _engine->savePlaybackPosition(); ev->accept(); } void MainWindow::wheelEvent(QWheelEvent* we) { if (insideToolsArea(we->pos()) || insideResizeArea(we->globalPos())) return; if (_playlist->state() == PlaylistWidget::Opened) { we->ignore(); return; } if (we->buttons() == Qt::NoButton && we->modifiers() == Qt::NoModifier) { requestAction(we->angleDelta().y() > 0 ? ActionFactory::VolumeUp: ActionFactory::VolumeDown); } } void MainWindow::focusInEvent(QFocusEvent *fe) { resumeToolsWindow(); } void MainWindow::showEvent(QShowEvent *event) { qDebug() << __func__; if (_pausedOnHide || Settings::get().isSet(Settings::PauseOnMinimize)) { if (_pausedOnHide && _engine && _engine->state() != PlayerEngine::Playing) { requestAction(ActionFactory::TogglePause); _pausedOnHide = false; } } _titlebar->raise(); _toolbox->raise(); resumeToolsWindow(); if (!qgetenv("FLATPAK_APPID").isEmpty()) { qDebug() << "workaround for flatpak"; if (_playlist->isVisible()) updateProxyGeometry(); } } void MainWindow::resizeByConstraints(bool forceCentered) { if (_engine->state() == PlayerEngine::Idle || _engine->playlist().count() == 0) { _titlebar->setTitle(QString()); return; } if (_miniMode || isFullScreen() || isMaximized()) { return; } qDebug() << __func__; updateWindowTitle(); const auto& mi = _engine->playlist().currentInfo().mi; auto sz = _engine->videoSize(); if (sz.isEmpty()) { sz = QSize(mi.width, mi.height); qDebug() << mi.width << mi.height; } auto geom = qApp->desktop()->availableGeometry(this); if (sz.width() > geom.width() || sz.height() > geom.height()) { sz.scale(geom.width(), geom.height(), Qt::KeepAspectRatio); } qDebug() << "original: " << size() << "requested: " << sz; if (size() == sz) return; if (forceCentered) { QRect r; r.setSize(sz); r.moveTopLeft({(geom.width() - r.width()) /2, (geom.height() - r.height())/2}); this->setGeometry(r); } else { QRect r = this->geometry(); r.setSize(sz); this->setGeometry(r); } } // 若长≥高,则长≤528pxă€€ă€€ă€€è‹¥é•¿â‰¤é«˜,则高≤528px. // 简而言之,åªçœ‹æœ€é•¿ç„那个最大为528px. void MainWindow::updateSizeConstraints() { auto m = size(); if (_miniMode) { m = QSize(40, 40); } else { if (_engine->state() != PlayerEngine::CoreState::Idle) { auto sz = _engine->videoSize(); qreal ratio = (qreal)sz.width() / sz.height(); if (sz.width() > sz.height()) { int h = 528 / ratio; m = QSize(528, h); } else { int w = 528 * ratio; m = QSize(w, 528); } } else { m = QSize(630, 386); } } qDebug() << __func__ << m; this->setMinimumSize(m); } void MainWindow::updateGeometryNotification(const QSize& sz) { auto msg = QString("%1x%2").arg(sz.width()).arg(sz.height()); _nwComm->updateWithMessage(msg); if (windowState() == Qt::WindowNoState && !_miniMode) { _lastRectInNormalMode = geometry(); } } void MainWindow::resizeEvent(QResizeEvent *ev) { qDebug() << __func__ << geometry(); if (isFullScreen()) { _progIndicator->move(geometry().width() - _progIndicator->width() - 18, 8); } updateSizeConstraints(); updateProxyGeometry(); QTimer::singleShot(0, [=]() { updateWindowTitle(); }); } void MainWindow::updateWindowTitle() { if (_engine->state() != PlayerEngine::Idle) { const auto& mi = _engine->playlist().currentInfo().mi; auto title = _titlebar->fontMetrics().elidedText(mi.title, Qt::ElideMiddle, _titlebar->contentsRect().width() - 300); _titlebar->setTitle(title); } else { _titlebar->setTitle(QString()); } _titlebar->setProperty("idle", _engine->state() == PlayerEngine::Idle); _titlebar->setStyleSheet(styleSheet()); } void MainWindow::moveEvent(QMoveEvent *ev) { } void MainWindow::keyPressEvent(QKeyEvent *ev) { QWidget::keyPressEvent(ev); } void MainWindow::keyReleaseEvent(QKeyEvent *ev) { QWidget::keyReleaseEvent(ev); } void MainWindow::capturedMousePressEvent(QMouseEvent* me) { _mouseMoved = false; if (qApp->focusWindow() == 0) return; if (me->buttons() == Qt::LeftButton) { _mousePressed = true; } } void MainWindow::capturedMouseReleaseEvent(QMouseEvent* me) { if (_delayedResizeByConstraint) { _delayedResizeByConstraint = false; QTimer::singleShot(0, [=]() { this->setMinimumSize({0, 0}); this->resizeByConstraints(true); }); } } static bool _afterDblClick = false; void MainWindow::mousePressEvent(QMouseEvent *ev) { _mouseMoved = false; if (qApp->focusWindow() == 0) return; if (ev->buttons() == Qt::LeftButton) { _mousePressed = true; if (_playState->isVisible()) { //_playState->setState(DImageButton::Press); QMouseEvent me(QEvent::MouseButtonPress, {}, ev->button(), ev->buttons(), ev->modifiers()); qApp->sendEvent(_playState, &me); } } } void MainWindow::mouseDoubleClickEvent(QMouseEvent *ev) { if (!_miniMode && !_inBurstShootMode) { _delayedMouseReleaseTimer.stop(); if (_engine->state() == PlayerEngine::Idle) { requestAction(ActionFactory::StartPlay); } else { requestAction(ActionFactory::ToggleFullscreen, false, {}, true); } ev->accept(); _afterDblClick = true; } } bool MainWindow::insideToolsArea(const QPoint& p) { return _titlebar->geometry().contains(p) || _toolbox->geometry().contains(p); } QMargins MainWindow::dragMargins() const { return QMargins {MOUSE_MARGINS, MOUSE_MARGINS, MOUSE_MARGINS, MOUSE_MARGINS}; } bool MainWindow::insideResizeArea(const QPoint& global_p) { const QRect window_visible_rect = frameGeometry() - dragMargins(); return !window_visible_rect.contains(global_p); } void MainWindow::mouseReleaseEvent(QMouseEvent *ev) { if (!_mousePressed) { _afterDblClick = false; _mouseMoved = false; } if (qApp->focusWindow() == 0 || !_mousePressed) return; _mousePressed = false; if (_playState->isVisible()) { //QMouseEvent me(QEvent::MouseButtonRelease, {}, ev->button(), ev->buttons(), ev->modifiers()); //qApp->sendEvent(_playState, &me); _playState->setState(DImageButton::Normal); } // dtk has a bug, DImageButton propagates mouseReleaseEvent event when it responded to. if (!insideResizeArea(ev->globalPos()) && !_mouseMoved && !insideToolsArea(ev->pos())) { if (_playlist->state() != PlaylistWidget::Opened) _delayedMouseReleaseTimer.start(120); } Utility::cancelWindowMoveResize(winId()); _mouseMoved = false; } void MainWindow::delayedMouseReleaseHandler() { if (!_afterDblClick) requestAction(ActionFactory::TogglePause, false, {}, true); _afterDblClick = false; } void MainWindow::mouseMoveEvent(QMouseEvent *ev) { if (_mouseMoved) { return Utility::updateMousePointForWindowMove(this->winId(), ev->globalPos() * devicePixelRatioF()); } _mouseMoved = true; if (windowState() == Qt::WindowNoState || isMaximized()) { Utility::startWindowSystemMove(this->winId()); } QWidget::mouseMoveEvent(ev); } void MainWindow::contextMenuEvent(QContextMenuEvent *cme) { if (_miniMode || _inBurstShootMode) return; if (insideToolsArea(cme->pos())) return; resumeToolsWindow(); QTimer::singleShot(0, [=]() { qApp->restoreOverrideCursor(); ActionFactory::get().mainContextMenu()->popup(QCursor::pos()); }); cme->accept(); } void MainWindow::prepareSplashImages() { bg_dark = utils::LoadHiDPIImage(":/resources/icons/dark/init-splash.svg"); bg_light = utils::LoadHiDPIImage(":/resources/icons/light/init-splash.svg"); } QString MainWindow::lastOpenedPath() { QString lastPath = Settings::get().generalOption("last_open_path").toString(); QDir lastDir(lastPath); if (lastPath.isEmpty() || !lastDir.exists()) { lastPath = QStandardPaths::writableLocation(QStandardPaths::MoviesLocation); QDir newLastDir(lastPath); if (!newLastDir.exists()) { lastPath = QDir::currentPath(); } } return lastPath; } void MainWindow::paintEvent(QPaintEvent* pe) { QPainter p(this); p.setRenderHint(QPainter::Antialiasing); bool light = ("light" == qApp->theme()); auto bg_clr = QColor(16, 16, 16); QImage& bg = bg_dark; if (light) { bg = bg_light; bg_clr = QColor(252, 252, 252); } #ifdef USE_DXCB QPainterPath pp; pp.addRect(rect()); p.fillPath(pp, bg_clr); #else bool rounded = !isFullScreen() && !isMaximized(); p.fillRect(rect(), Qt::transparent); if (rounded) { QPainterPath pp; pp.addRoundedRect(rect(), RADIUS, RADIUS); p.fillPath(pp, QColor(0, 0, 0, light ? 255 * 0.1: 255)); { /* we supposed to draw by qss background-color here, but it's conflict with * border area (border has alpha, which blends with background-color. */ auto view_rect = rect().marginsRemoved(QMargins(1, 1, 1, 1)); QPainterPath pp; pp.addRoundedRect(view_rect, RADIUS, RADIUS); p.fillPath(pp, bg_clr); } } else { QPainterPath pp; pp.addRect(rect()); p.fillPath(pp, bg_clr); } #endif auto pt = rect().center() - QPoint(bg.width()/2, bg.height()/2)/devicePixelRatioF(); p.drawImage(pt, bg); } void MainWindow::toggleUIMode() { _miniMode = !_miniMode; qDebug() << __func__ << _miniMode; if (_miniMode) _titlebar->setDisableFlags(Qt::WindowMaximizeButtonHint); else _titlebar->setDisableFlags(0); if (_listener) _listener->setEnabled(!_miniMode); updateSizeConstraints(); _titlebar->setVisible(!_miniMode); _toolbox->setVisible(!_miniMode); _miniPlayBtn->setVisible(_miniMode); _miniCloseBtn->setVisible(_miniMode); _miniQuitMiniBtn->setVisible(_miniMode); _miniPlayBtn->setEnabled(_miniMode); _miniCloseBtn->setEnabled(_miniMode); _miniQuitMiniBtn->setEnabled(_miniMode); resumeToolsWindow(); if (_miniMode) { syncPlayState(); _stateBeforeMiniMode = SBEM_None; if (!_windowAbove) { _stateBeforeMiniMode |= SBEM_Above; requestAction(ActionFactory::WindowAbove); } if (_playlist->state() == PlaylistWidget::Opened) { _stateBeforeMiniMode |= SBEM_PlaylistOpened; requestAction(ActionFactory::TogglePlaylist); } if (isFullScreen()) { _stateBeforeMiniMode |= SBEM_Fullscreen; requestAction(ActionFactory::QuitFullscreen); } else if (isMaximized()) { _stateBeforeMiniMode |= SBEM_Maximized; showNormal(); } else { _lastRectInNormalMode = geometry(); } auto sz = QSize(380, 380); if (_engine->state() != PlayerEngine::CoreState::Idle) { auto vid_size = _engine->videoSize(); qreal ratio = vid_size.width() / (qreal)vid_size.height(); if (vid_size.width() > vid_size.height()) { sz = QSize(380, 380 / ratio); } else { sz = QSize(380 * ratio, 380); } } QRect geom = {0, 0, 0, 0}; if (_lastRectInNormalMode.isValid()) { geom = _lastRectInNormalMode; } geom.setSize(sz); setGeometry(geom); _miniQuitMiniBtn->move(sz.width() - 14 - _miniQuitMiniBtn->width(), sz.height() - 10 - _miniQuitMiniBtn->height()); _miniCloseBtn->move(sz.width() - 4 - _miniCloseBtn->width(), 4); _miniPlayBtn->move(14, sz.height() - 10 - _miniPlayBtn->height()); } else { if (_stateBeforeMiniMode & SBEM_Above) { requestAction(ActionFactory::WindowAbove); } if (_stateBeforeMiniMode & SBEM_Maximized) { showMaximized(); } else if (_stateBeforeMiniMode & SBEM_Fullscreen) { requestAction(ActionFactory::ToggleFullscreen); } else { if (_engine->state() == PlayerEngine::Idle && windowState() == Qt::WindowNoState) { this->setMinimumSize(QSize(528, 400)); this->resize(850, 600); } else { if (_lastRectInNormalMode.isValid()) { resize(_lastRectInNormalMode.size()); } else { resizeByConstraints(); } } } syncPlayState(); if (_stateBeforeMiniMode & SBEM_PlaylistOpened && _playlist->state() == PlaylistWidget::Closed) { if (_stateBeforeMiniMode & SBEM_Fullscreen) { QTimer::singleShot(100, [=]() { requestAction(ActionFactory::TogglePlaylist); }); } } _stateBeforeMiniMode = SBEM_None; } } void MainWindow::miniButtonClicked(QString id) { qDebug() << id; if (id == "play") { if (_engine->state() == PlayerEngine::CoreState::Idle) { requestAction(ActionFactory::ActionKind::StartPlay); } else { requestAction(ActionFactory::ActionKind::TogglePause); } } else if (id == "close") { close(); } else if (id == "quit_mini") { requestAction(ActionFactory::ActionKind::ToggleMiniMode); } } void MainWindow::dragEnterEvent(QDragEnterEvent *ev) { if (ev->mimeData()->hasUrls()) { ev->acceptProposedAction(); } } void MainWindow::dragMoveEvent(QDragMoveEvent *ev) { if (ev->mimeData()->hasUrls()) { ev->acceptProposedAction(); } } void MainWindow::dropEvent(QDropEvent *ev) { qDebug() << ev->mimeData()->formats(); if (!ev->mimeData()->hasUrls()) { return; } QList urls = ev->mimeData()->urls(); QList valids = _engine->addPlayFiles(urls); if (urls.count() == 1 && valids.count() == 0) { // check if the dropped file is a subtitle. QFileInfo fileInfo(urls.first().toLocalFile()); if (_engine->subtitle_suffixs.contains(fileInfo.suffix())) { bool succ = _engine->loadSubtitle(fileInfo); // notice that the file loaded but won't automatically selected. const PlayingMovieInfo& pmf = _engine->playingMovieInfo(); for (const SubtitleInfo& sub: pmf.subs) { if (sub["external"].toBool()) { QString path = sub["external-filename"].toString(); if (path == fileInfo.canonicalFilePath()) { _engine->selectSubtitle(pmf.subs.indexOf(sub)); break; } } } QPixmap icon = utils::LoadHiDPIPixmap(QString(":/resources/icons/%1.svg").arg(succ ? "success" : "fail")); _nwComm->popupWithIcon(succ ? tr("Load successfully") : tr("Load failed"), icon); } return; } { auto all = urls.toSet(); auto accepted = valids.toSet(); auto invalids = all.subtract(accepted).toList(); int ms = 0; for (const auto& url: invalids) { QTimer::singleShot(ms, [=]() { auto msg = QString(tr("Invalid file: %1").arg(url.fileName())); _nwComm->updateWithMessage(msg); }); ms += 1000; } } if (valids.size()) { if (valids.size() == 1) { _engine->playByName(valids[0]); } else { _engine->playByName(QUrl("playlist://0")); } } ev->acceptProposedAction(); } void MainWindow::setInit(bool v) { if (_inited != v) { _inited = v; emit initChanged(); } } QString MainWindow::probeCdromDevice() { QStringList cands = { "/dev/sr0", "/dev/cdrom" }; for (auto d: cands) { if (QFile::exists(d)) { return d; } } return QString(); } #include "mainwindow.moc" deepin-movie-reborn-5.0.0/src/common/mainwindow.h000066400000000000000000000160341351125414100217670ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_MAIN_WINDOW_H #define _DMR_MAIN_WINDOW_H #include #include #include #include #include #include "actions.h" namespace Dtk { namespace Widget { class DImageButton; } } DWIDGET_USE_NAMESPACE class MainWindowEventListener; namespace dmr { class ToolboxProxy; class EventMonitor; class PlaylistWidget; class PlayerEngine; class NotificationWidget; class MovieProgressIndicator; class MainWindow: public QFrame { Q_OBJECT Q_PROPERTY(bool inited READ inited WRITE setInit NOTIFY initChanged) public: MainWindow(QWidget *parent = 0); ~MainWindow(); bool inited() const { return _inited; } PlayerEngine* engine() { return _engine; } DTitlebar* titlebar() { return _titlebar; } ToolboxProxy* toolbox() { return _toolbox; } PlaylistWidget* playlist() { return _playlist; } void requestAction(ActionFactory::ActionKind, bool fromUI = false, QList args = {}, bool shortcut = false); bool insideResizeArea(const QPoint& global_p); QMargins dragMargins() const; void capturedMousePressEvent(QMouseEvent* me); void capturedMouseReleaseEvent(QMouseEvent* me); void syncStaysOnTop(); void updateGeometryNotification(const QSize& sz); void updateContentGeometry(const QRect& rect); static QString lastOpenedPath(); signals: void windowEntered(); void windowLeaved(); void initChanged(); public slots: void play(const QUrl& url); void playList(const QList& l); void updateProxyGeometry(); void suspendToolsWindow(); void resumeToolsWindow(); protected: void showEvent(QShowEvent *event) override; void hideEvent(QHideEvent *event) override; void closeEvent(QCloseEvent *ev) override; void resizeEvent(QResizeEvent *ev) override; void mouseMoveEvent(QMouseEvent *ev) override; void mousePressEvent(QMouseEvent *ev) override; void mouseDoubleClickEvent(QMouseEvent *ev) override; void mouseReleaseEvent(QMouseEvent *ev) override; void focusInEvent(QFocusEvent *fe) override; void wheelEvent(QWheelEvent* we) override; void keyPressEvent(QKeyEvent *ev) override; void keyReleaseEvent(QKeyEvent *ev) override; void moveEvent(QMoveEvent *ev) override; void contextMenuEvent(QContextMenuEvent *cme) override; void paintEvent(QPaintEvent*) override; void dragEnterEvent(QDragEnterEvent *event) override; void dragMoveEvent(QDragMoveEvent *event) override; void dropEvent(QDropEvent *event) override; bool event(QEvent *event) override; protected slots: void setInit(bool v); void menuItemInvoked(QAction *action); void onApplicationStateChanged(Qt::ApplicationState e); void onBindingsChanged(); void updateActionsState(); void syncPlayState(); void animatePlayState(); void resizeByConstraints(bool forceCentered = false); void onWindowStateChanged(); void miniButtonClicked(QString id); void startBurstShooting(); void onBurstScreenshot(const QImage& frame, qint64 timestamp); void delayedMouseReleaseHandler(); #ifdef USE_DXCB void onMonitorButtonPressed(int x, int y); void onMonitorMotionNotify(int x, int y); void onMonitorButtonReleased(int x, int y); void updateShadow(); #endif void handleHelpAction(); private: void setupTitlebar(); void startPlayStateAnimation(bool play); void handleSettings(); void updateSizeConstraints(); void toggleUIMode(); void reflectActionToUI(ActionFactory::ActionKind); bool insideToolsArea(const QPoint& p); void switchTheme(); bool isActionAllowed(ActionFactory::ActionKind kd, bool fromUI, bool isShortcut); QString probeCdromDevice(); void updateWindowTitle(); void toggleShapeMask(); void prepareSplashImages(); private: DTitlebar *_titlebar {nullptr}; ToolboxProxy *_toolbox {nullptr}; PlaylistWidget *_playlist {nullptr}; PlayerEngine *_engine {nullptr}; DImageButton *_playState {nullptr}; MovieProgressIndicator *_progIndicator {nullptr}; QList> _burstShoots; bool _inBurstShootMode {false}; bool _pausedBeforeBurst {false}; DImageButton *_miniPlayBtn {nullptr}; DImageButton *_miniCloseBtn {nullptr}; DImageButton *_miniQuitMiniBtn {nullptr}; QImage bg_dark; QImage bg_light; bool _miniMode {false}; /// used to restore to recent geometry when quit fullscreen or mini mode QRect _lastRectInNormalMode; // the first time a play happens, we consider it inited. bool _inited {false}; DPlatformWindowHandle *_handle {nullptr}; EventMonitor *_evm {nullptr}; bool _pausedOnHide {false}; // track if next/prev is triggered in fs/maximized mode bool _movieSwitchedInFsOrMaxed {false}; bool _delayedResizeByConstraint {false}; //toggle-able states bool _lightTheme {false}; bool _windowAbove {false}; bool _mouseMoved {false}; bool _mousePressed {false}; double _playSpeed {1.0}; enum StateBeforeEnterMiniMode { SBEM_None = 0x0, SBEM_Above = 0x01, SBEM_Fullscreen = 0x02, SBEM_PlaylistOpened = 0x04, SBEM_Maximized = 0x08, }; int _stateBeforeMiniMode {0}; Qt::WindowStates _lastWindowState {Qt::WindowNoState}; uint32_t _lastCookie {0}; uint32_t _powerCookie {0}; MainWindowEventListener *_listener {nullptr}; NotificationWidget *_nwShot {nullptr}; NotificationWidget *_nwComm {nullptr}; QTimer _autoHideTimer; QTimer _delayedMouseReleaseTimer; }; }; #endif /* ifndef _MAIN_WINDOW_H */ deepin-movie-reborn-5.0.0/src/common/options.cpp000066400000000000000000000053361351125414100216440ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "config.h" #include "options.h" namespace dmr { static CommandLineManager* _instance = nullptr; CommandLineManager& CommandLineManager::get() { if (!_instance) { _instance = new CommandLineManager(); } return *_instance; } CommandLineManager::CommandLineManager() { addHelpOption(); addVersionOption(); addPositionalArgument("path", ("Movie file path or directory")); addOptions({ {{"V", "verbose"}, ("show detail log message")}, {"VV", ("dump all debug message")}, {{"c", "opengl-cb"}, ("use opengl-cb interface [on/off/auto]"), "bool", "auto"}, {{"o", "override-config"}, ("override config for libmpv"), "file", ""}, {"dvd-device", ("specify dvd playing device or file"), "device", "/dev/sr0"}, }); } bool CommandLineManager::verbose() const { return this->isSet("verbose"); } bool CommandLineManager::debug() const { return this->isSet("VV"); } QString CommandLineManager::openglMode() const { return this->value("c"); } QString CommandLineManager::overrideConfig() const { return this->value("o"); } QString CommandLineManager::dvdDevice() const { if (this->isSet("dvd-device")) { return this->value("dvd-device").trimmed(); } return ""; } } deepin-movie-reborn-5.0.0/src/common/options.h000066400000000000000000000035701351125414100213070ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_OPTIONS_H #define _DMR_OPTIONS_H #include namespace dmr { class CommandLineManager: public QCommandLineParser { public: static CommandLineManager& get(); bool verbose() const; bool debug() const; QString openglMode() const; QString overrideConfig() const; QString dvdDevice() const; private: CommandLineManager(); }; } #endif /* ifndef _DMR_OPTIONS_H */ deepin-movie-reborn-5.0.0/src/common/settings_translation.cpp000066400000000000000000000055451351125414100244310ustar00rootroot00000000000000#include void GenerateSettingTranslate() { auto base_play_addsimilarText = QObject::tr("Auto add similar files to play"); auto base_play_emptylistText = QObject::tr("Clear playlist when exit"); auto base_play_mousepreviewText = QObject::tr("Show video preview on mouseover"); auto base_play_multiinstanceText = QObject::tr("Open a new player for each file played"); auto base_play_pauseonminText = QObject::tr("Pause when minimized"); auto base_play_resumelastText = QObject::tr("Remember playback position"); auto base_screenshot_locationName = QObject::tr("Path"); auto group_baseName = QObject::tr("Basic"); auto group_base_playName = QObject::tr("Play"); auto group_base_screenshotName = QObject::tr("Screenshot"); auto group_shortcutsName = QObject::tr("Shortcuts"); auto group_shortcuts_fileName = QObject::tr("File"); auto group_shortcuts_frame_soundName = QObject::tr("Frame/Sound"); auto group_shortcuts_playName = QObject::tr("Playback"); auto group_shortcuts_screenshotName = QObject::tr("Screenshot"); auto group_shortcuts_subName = QObject::tr("Subtitle"); auto group_subtitleName = QObject::tr("Subtitle"); auto group_subtitle_fontName = QObject::tr("Font Style"); auto reset_button_name = QObject::tr("Restore Defaults"); auto shortcuts_file_open_fileName = QObject::tr("Open file"); auto shortcuts_file_playlist_nextName = QObject::tr("Open next"); auto shortcuts_file_playlist_prevName = QObject::tr("Open previous"); auto shortcuts_frame_sound_miniName = QObject::tr("Mini mode"); auto shortcuts_frame_sound_muteName = QObject::tr("Mute"); auto shortcuts_frame_sound_next_frameName = QObject::tr("Next frame"); auto shortcuts_frame_sound_previous_frameName = QObject::tr("Previous frame"); auto shortcuts_frame_sound_vol_downName = QObject::tr("Volume down"); auto shortcuts_frame_sound_vol_upName = QObject::tr("Volume up"); auto shortcuts_play_accelName = QObject::tr("Speed up"); auto shortcuts_play_decelName = QObject::tr("Speed down"); auto shortcuts_play_fullscreenName = QObject::tr("Fullscreen"); auto shortcuts_play_pause_playName = QObject::tr("Pause/Play"); auto shortcuts_play_playlistName = QObject::tr("Playlist"); auto shortcuts_play_resetName = QObject::tr("Reset speed"); auto shortcuts_play_seek_backwardName = QObject::tr("Rewind"); auto shortcuts_play_seek_forwardName = QObject::tr("Forward"); auto shortcuts_screenshot_burst_screenshotName = QObject::tr("Burst screenshot"); auto shortcuts_screenshot_screenshotName = QObject::tr("Film screenshot"); auto shortcuts_sub_sub_backwardName = QObject::tr("0.5s backward"); auto shortcuts_sub_sub_forwardName = QObject::tr("0.5s forward"); auto subtitle_font_familyName = QObject::tr("Font"); auto subtitle_font_sizeName = QObject::tr("Font Size"); } deepin-movie-reborn-5.0.0/src/common/shortcut_manager.cpp000066400000000000000000000224121351125414100235100ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "shortcut_manager.h" #include "dmr_settings.h" #include #include #include namespace dmr { using namespace Dtk::Core; static ShortcutManager* _shortcutManager = nullptr; ShortcutManager& ShortcutManager::get() { if (!_shortcutManager) { _shortcutManager = new ShortcutManager(); } return *_shortcutManager; } ShortcutManager::~ShortcutManager() { } ShortcutManager::ShortcutManager() :QObject(0) { _keyToAction = { {"pause_play", ActionFactory::ActionKind::TogglePause}, {"seek_forward", ActionFactory::ActionKind::SeekForward}, {"seek_forward_large", ActionFactory::ActionKind::SeekForwardLarge}, {"seek_backward", ActionFactory::ActionKind::SeekBackward}, {"seek_backward_large", ActionFactory::ActionKind::SeekBackwardLarge}, {"fullscreen", ActionFactory::ActionKind::ToggleFullscreen}, {"playlist", ActionFactory::ActionKind::TogglePlaylist}, {"accel", ActionFactory::ActionKind::AccelPlayback}, {"decel", ActionFactory::ActionKind::DecelPlayback}, {"reset", ActionFactory::ActionKind::ResetPlayback}, {"mini", ActionFactory::ActionKind::ToggleMiniMode}, {"vol_up", ActionFactory::ActionKind::VolumeUp}, {"vol_down", ActionFactory::ActionKind::VolumeDown}, {"mute", ActionFactory::ActionKind::ToggleMute}, {"open_file", ActionFactory::ActionKind::OpenFileList}, {"playlist_next", ActionFactory::ActionKind::GotoPlaylistNext}, {"playlist_prev", ActionFactory::ActionKind::GotoPlaylistPrev}, {"sub_forward", ActionFactory::ActionKind::SubForward}, {"sub_backward", ActionFactory::ActionKind::SubDelay}, {"screenshot", ActionFactory::ActionKind::Screenshot}, {"burst_screenshot", ActionFactory::ActionKind::BurstScreenshot}, {"next_frame", ActionFactory::ActionKind::NextFrame}, {"previous_frame", ActionFactory::ActionKind::PreviousFrame}, }; connect(&Settings::get(), &Settings::shortcutsChanged, [=](QString sk, const QVariant& val) { if (sk.endsWith(".enable")) { auto grp_key = sk.left(sk.lastIndexOf('.')); qDebug() << "update group binding" << grp_key; QPointer shortcuts = Settings::get().shortcuts(); auto grps = shortcuts->childGroups(); auto grp_ptr = std::find_if(grps.begin(), grps.end(), [=](GroupPtr grp) { return grp->key() == grp_key; }); toggleGroupShortcuts(*grp_ptr, val.toBool()); emit bindingsChanged(); return; } sk.remove(0, sk.lastIndexOf('.') + 1); QStringList keyseqs = val.toStringList(); Q_ASSERT (keyseqs.length() == 2); auto modifier = static_cast(keyseqs.value(0).toInt()); auto key = static_cast(keyseqs.value(1).toInt()); qDebug() << "update binding" << sk << QKeySequence(modifier + key); _map.remove(_map.key(_keyToAction[sk])); _map[QKeySequence(modifier + key)] = _keyToAction[sk]; emit bindingsChanged(); }); } void ShortcutManager::buildBindings() { buildBindingsFromSettings(); emit bindingsChanged(); } void ShortcutManager::toggleGroupShortcuts(GroupPtr grp, bool on) { auto sub = grp->childOptions(); std::for_each(sub.begin(), sub.end(), [=](OptionPtr opt) { if (opt->viewType() != "shortcut") return; QStringList keyseqs = opt->value().toStringList(); Q_ASSERT (keyseqs.length() == 2); auto modifier = static_cast(keyseqs.value(0).toInt()); auto key = static_cast(keyseqs.value(1).toInt()); QString sk = opt->key(); sk.remove(0, sk.lastIndexOf('.') + 1); qDebug() << opt->name() << QKeySequence(modifier + key); if (on) { _map[QKeySequence(modifier + key)] = _keyToAction[sk]; } else { _map.remove(QKeySequence(modifier + key)); } }); } void ShortcutManager::buildBindingsFromSettings() { _map.clear(); // default builtins _map.insert(QKeySequence(Qt::Key_Left), ActionFactory::SeekBackward); _map.insert(QKeySequence(Qt::Key_Left + Qt::SHIFT), ActionFactory::SeekBackwardLarge); _map.insert(QKeySequence(Qt::Key_Right), ActionFactory::SeekForward); _map.insert(QKeySequence(Qt::Key_Right + Qt::SHIFT), ActionFactory::SeekForwardLarge); _map.insert(QKeySequence(Qt::Key_Space), ActionFactory::TogglePause); _map.insert(QKeySequence(Qt::Key_Escape), ActionFactory::QuitFullscreen); _map.insert(QKeySequence(Qt::Key_Slash + Qt::CTRL + Qt::SHIFT), ActionFactory::ViewShortcut); QPointer shortcuts = Settings::get().shortcuts(); auto subgroups = shortcuts->childGroups(); std::for_each(subgroups.begin(), subgroups.end(), [=](GroupPtr grp) { auto enabled = Settings::get().settings()->option(grp->key() + ".enable"); qDebug() << grp->name() << enabled->value(); Q_ASSERT(enabled && enabled->viewType() == "checkbox"); if (!enabled->value().toBool()) return; toggleGroupShortcuts(grp, true); }); } QString ShortcutManager::toJson() { QJsonObject shortcutObj; QJsonArray jsonGroups; QPointer shortcuts = Settings::get().shortcuts(); auto subgroups = shortcuts->childGroups(); std::for_each(subgroups.begin(), subgroups.end(), [&](GroupPtr grp) { qDebug() << grp->name(); QJsonObject jsonGroup; jsonGroup.insert("groupName", qApp->translate("QObject", grp->name().toUtf8().data())); QJsonArray jsonItems; auto sub = grp->childOptions(); std::for_each(sub.begin(), sub.end(), [&](OptionPtr opt) { if (opt->viewType() != "shortcut") return; QStringList keyseqs = opt->value().toStringList(); Q_ASSERT (keyseqs.length() == 2); auto modifier = static_cast(keyseqs.value(0).toInt()); auto key = static_cast(keyseqs.value(1).toInt()); QJsonObject jsonItem; jsonItem.insert("name", qApp->translate("QObject", opt->name().toUtf8().data())); jsonItem.insert("value", QKeySequence(modifier + key).toString(QKeySequence::PortableText)); jsonItems.append(jsonItem); }); jsonGroup.insert("groupItems", jsonItems); jsonGroups.append(jsonGroup); }); shortcutObj.insert("shortcut", jsonGroups); QJsonDocument doc(shortcutObj); return doc.toJson().data(); } vector ShortcutManager::actionsForBindings() { vector actions; auto p = _map.constBegin(); while (p != _map.constEnd()) { auto *act = new QAction(this); switch (p.value()) { case ActionFactory::ActionKind::SeekForward: case ActionFactory::ActionKind::SeekForwardLarge: case ActionFactory::ActionKind::SeekBackward: case ActionFactory::ActionKind::SeekBackwardLarge: case ActionFactory::ActionKind::VolumeUp: case ActionFactory::ActionKind::VolumeDown: case ActionFactory::ActionKind::AccelPlayback: case ActionFactory::ActionKind::DecelPlayback: act->setAutoRepeat(true); break; default: act->setAutoRepeat(false); break; } act->setShortcut(p.key()); //act->setShortcutContext(Qt::ApplicationShortcut); act->setProperty("kind", p.value()); act->setProperty("origin", "shortcut"); actions.push_back(act); qDebug() << "action " << p.key() << p.value(); ++p; } return actions; } } deepin-movie-reborn-5.0.0/src/common/shortcut_manager.h000066400000000000000000000050531351125414100231570ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_SHORTCUT_MANAGER #define _DMR_SHORTCUT_MANAGER #include #include #include #include "actions.h" #include #include #include namespace dmr { using namespace std; using BindingMap = QHash; using ActionMap = QHash; // keys comes from profiles, user configurations etc class ShortcutManager: public QObject { Q_OBJECT public: static ShortcutManager& get(); virtual ~ShortcutManager(); BindingMap& map() { return _map; } const BindingMap& map() const { return _map; } vector actionsForBindings(); void buildBindingsFromSettings(); QString toJson(); public slots: void buildBindings(); signals: void bindingsChanged(); private: ShortcutManager(); BindingMap _map; ActionMap _keyToAction; void toggleGroupShortcuts(Dtk::Core::GroupPtr grp, bool on); }; } #endif /* ifndef _DMR_SHORTCUT_MANAGER */ deepin-movie-reborn-5.0.0/src/common/thumbnail_worker.cpp000066400000000000000000000114421351125414100235200ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "thumbnail_worker.h" #include #include #define SIZE_THRESHOLD (10 * 1<<20) namespace dmr { static std::atomic _instance { nullptr }; static QMutex _instLock; static QMutex _thumbLock; static QWaitCondition cond; ThumbnailWorker& ThumbnailWorker::get() { if (_instance == nullptr) { QMutexLocker lock(&_instLock); if (_instance == nullptr) { _instance = new ThumbnailWorker; (*_instance).start(); } } return *_instance; } bool ThumbnailWorker::isThumbGenerated(const QUrl& url, int secs) { QMutexLocker lock(&_thumbLock); if (!_cache.contains(url)) return false; const auto& l = _cache[url]; return l.contains(secs); } QPixmap ThumbnailWorker::getThumb(const QUrl& url, int secs) { QMutexLocker lock(&_thumbLock); QPixmap pm; if (_cache.contains(url)) { auto p = _cache[url].find(secs); pm = *p; } return pm; } void ThumbnailWorker::requestThumb(const QUrl& url, int secs) { if (_thumbLock.tryLock()) { _wq.push_front(qMakePair(url, secs)); cond.wakeOne(); _thumbLock.unlock(); } } ThumbnailWorker::ThumbnailWorker() { thumber.setThumbnailSize(thumbSize().width() * qApp->devicePixelRatio()); thumber.setMaintainAspectRatio(true); } QPixmap ThumbnailWorker::genThumb(const QUrl& url, int secs) { auto dpr = qApp->devicePixelRatio(); QPixmap pm; pm.setDevicePixelRatio(dpr); QTime d(0, 0, 0); d = d.addSecs(secs); thumber.setSeekTime(d.toString("hh:mm:ss").toStdString()); auto file = QFileInfo(url.toLocalFile()).absoluteFilePath(); try { std::vector buf; thumber.generateThumbnail(file.toUtf8().toStdString(), ThumbnailerImageType::Png, buf); auto img = QImage::fromData(buf.data(), buf.size(), "png"); pm = QPixmap::fromImage(img.scaled(thumbSize() * dpr, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation)); pm.setDevicePixelRatio(dpr); } catch (const std::logic_error&) { } return pm; } void ThumbnailWorker::run() { setPriority(QThread::IdlePriority); while (!_quit.load()) { QPair w; { QMutexLocker lock(&_thumbLock); while (_wq.isEmpty() && !_quit.load()) { cond.wait(lock.mutex(), 40); } if (!_wq.isEmpty()) { w = _wq.takeFirst(); _wq.clear(); } } if (_quit.load()) break; { QMutexLocker lock(&_thumbLock); //TODO: optimize: need a lru map if (_cacheSize > SIZE_THRESHOLD) { qDebug() << "thumb cache size exceeds maximum, clean up"; _cache.clear(); _cacheSize = 0; } } if (!isThumbGenerated(w.first, w.second)) { auto pm = genThumb(w.first, w.second); QMutexLocker lock(&_thumbLock); _cache[w.first].insert(w.second, pm); _cacheSize += pm.width() * pm.height() * (pm.hasAlpha() ? 4 : 3); QTime d(0, 0, 0); d = d.addSecs(w.second); qDebug() << "thumb for " << w.first << d.toString("hh:mm:ss"); } emit thumbGenerated(w.first, w.second); } _wq.clear(); } } deepin-movie-reborn-5.0.0/src/common/thumbnail_worker.h000066400000000000000000000046331351125414100231710ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_THUMBNAIL_WORKER_H #define _DMR_THUMBNAIL_WORKER_H #include #include namespace dmr { using namespace ffmpegthumbnailer; class ThumbnailWorker: public QThread { Q_OBJECT public: static ThumbnailWorker& get(); // expected size for ui static QSize thumbSize() { return {158, 89}; } bool isThumbGenerated(const QUrl& url, int secs); QPixmap getThumb(const QUrl& url, int secs); void stop() { _quit.store(1); quit(); } public slots: void requestThumb(const QUrl& url, int secs); signals: void thumbGenerated(const QUrl& url, int secs); private: QList> _wq; QHash> _cache; VideoThumbnailer thumber; QAtomicInt _quit{0}; qint64 _cacheSize {0}; ThumbnailWorker(); void run() override; QPixmap genThumb(const QUrl& url, int secs); }; } #endif /* ifndef _DMR_THUMBNAIL_WORKER_H */ deepin-movie-reborn-5.0.0/src/common/utility.h000066400000000000000000000072371351125414100213230ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_UTILITY_H #define _DMR_UTILITY_H #include #include #include QT_BEGIN_NAMESPACE class QXcbWindow; QT_END_NAMESPACE typedef uint32_t xcb_atom_t; class Utility { public: enum CornerEdge { TopLeftCorner = 0, TopEdge = 1, TopRightCorner = 2, RightEdge = 3, BottomRightCorner = 4, BottomEdge = 5, BottomLeftCorner = 6, LeftEdge = 7, NoneEdge = -1 }; static xcb_atom_t internAtom(const char *name); static void startWindowSystemMove(quint32 WId); static void cancelWindowMoveResize(quint32 WId); // 在触摸å±ä¸‹ç§»å¨çª—壿—¶ï¼Œè°ƒç”¨ startWindowSystemMoveå,窗管无法grab触摸å±ç„touch update事件 // å¯¼è‡´çª—å£æ— æ³•ç§»å¨ă€‚此处跟deepin-wmé…åˆï¼Œä½¿ç”¨å…¶å®ƒæ–¹å¼é€çŸ¥çª—管鼠标ä½ç½®æ›´æ–°äº† static void updateMousePointForWindowMove(quint32 WId, const QPoint &globalPos); static void setFrameExtents(quint32 WId, const QMargins &margins); static void setRectangles(quint32 WId, const QRegion ®ion, bool onlyInput = true); static void setRectangles(quint32 WId, const QVector &rectangles, bool onlyInput = true); static void setShapePath(quint32 WId, const QPainterPath &path, bool onlyInput = true); static void startWindowSystemResize(quint32 WId, CornerEdge cornerEdge, const QPoint &globalPos = QPoint()); static bool setWindowCursor(quint32 WId, CornerEdge ce); static QRegion regionAddMargins(const QRegion ®ion, const QMargins &margins, const QPoint &offset = QPoint(0, 0)); static QByteArray windowProperty(quint32 WId, xcb_atom_t propAtom, xcb_atom_t typeAtom, quint32 len); static QList windowNetWMState(quint32 WId); static void setWindowProperty(quint32 WId, xcb_atom_t propAtom, xcb_atom_t typeAtom, const void *data, quint32 len, uint8_t format = 8); static void setStayOnTop(const QWidget *widget, bool on); private: static void sendMoveResizeMessage(quint32 WId, uint32_t action, QPoint globalPos = QPoint(), Qt::MouseButton qbutton = Qt::LeftButton); static QVector qregion2XcbRectangles(const QRegion ®ion); }; #endif // _DMR_UTILITY_H deepin-movie-reborn-5.0.0/src/common/utility_x11.cpp000066400000000000000000000307151351125414100223440ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "utility.h" #include #include #include #include #include #include #define _NET_WM_MOVERESIZE_MOVE 8 /* movement only */ #define _NET_WM_MOVERESIZE_CANCEL 11 /* cancel operation */ #define XATOM_MOVE_RESIZE "_NET_WM_MOVERESIZE" #define XDEEPIN_BLUR_REGION "_NET_WM_DEEPIN_BLUR_REGION" #define XDEEPIN_BLUR_REGION_ROUNDED "_NET_WM_DEEPIN_BLUR_REGION_ROUNDED" #define _NET_WM_STATE_REMOVE 0 /* remove/unset property */ #define _NET_WM_STATE_ADD 1 /* add/set property */ #define _NET_WM_STATE_TOGGLE 2 /* toggle property */ const char kAtomNameHidden[] = "_NET_WM_STATE_HIDDEN"; const char kAtomNameFullscreen[] = "_NET_WM_STATE_FULLSCREEN"; const char kAtomNameMaximizedHorz[] = "_NET_WM_STATE_MAXIMIZED_HORZ"; const char kAtomNameMaximizedVert[] = "_NET_WM_STATE_MAXIMIZED_VERT"; const char kAtomNameMoveResize[] = "_NET_WM_MOVERESIZE"; const char kAtomNameWmState[] = "_NET_WM_STATE"; const char kAtomNameWmStateAbove[] = "_NET_WM_STATE_ABOVE"; const char kAtomNameWmStateStaysOnTop[] = "_NET_WM_STATE_STAYS_ON_TOP"; const char kAtomNameWmSkipTaskbar[] = "_NET_WM_STATE_SKIP_TASKBAR"; const char kAtomNameWmSkipPager[] = "_NET_WM_STATE_SKIP_PAGER"; xcb_atom_t Utility::internAtom(const char *name) { if (!name || *name == 0) return XCB_NONE; xcb_intern_atom_cookie_t cookie = xcb_intern_atom(QX11Info::connection(), true, strlen(name), name); xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(QX11Info::connection(), cookie, 0); if (!reply) return XCB_NONE; xcb_atom_t atom = reply->atom; free(reply); return atom; } void Utility::startWindowSystemMove(quint32 WId) { sendMoveResizeMessage(WId, _NET_WM_MOVERESIZE_MOVE); } void Utility::cancelWindowMoveResize(quint32 WId) { sendMoveResizeMessage(WId, _NET_WM_MOVERESIZE_CANCEL); } void Utility::updateMousePointForWindowMove(quint32 WId, const QPoint &globalPos) { xcb_client_message_event_t xev; xev.response_type = XCB_CLIENT_MESSAGE; xev.type = internAtom("_DEEPIN_MOVE_UPDATE"); xev.window = WId; xev.format = 32; xev.data.data32[0] = globalPos.x(); xev.data.data32[1] = globalPos.y(); xev.data.data32[2] = 0; xev.data.data32[3] = 0; xev.data.data32[4] = 0; xcb_send_event(QX11Info::connection(), false, QX11Info::appRootWindow(), XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY, (const char *)&xev); xcb_flush(QX11Info::connection()); } void Utility::setFrameExtents(quint32 WId, const QMargins &margins) { xcb_atom_t frameExtents = internAtom("_GTK_FRAME_EXTENTS"); if (frameExtents == XCB_NONE) { qWarning() << "Failed to create atom with name _GTK_FRAME_EXTENTS"; return; } uint32_t value[4] = { (uint32_t)margins.left(), (uint32_t)margins.right(), (uint32_t)margins.top(), (uint32_t)margins.bottom() }; xcb_change_property(QX11Info::connection(), XCB_PROP_MODE_REPLACE, WId, frameExtents, XCB_ATOM_CARDINAL, 32, 4, value); } void Utility::setRectangles(quint32 WId, const QRegion ®ion, bool onlyInput) { setRectangles(WId, qregion2XcbRectangles(region), onlyInput); } void Utility::setRectangles(quint32 WId, const QVector &rectangles, bool onlyInput) { if (rectangles.isEmpty()) { xcb_shape_mask(QX11Info::connection(), XCB_SHAPE_SO_SET, onlyInput ? XCB_SHAPE_SK_INPUT : XCB_SHAPE_SK_BOUNDING, WId, 0, 0, XCB_NONE); return; } xcb_shape_rectangles(QX11Info::connection(), XCB_SHAPE_SO_SET, onlyInput ? XCB_SHAPE_SK_INPUT : XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_YX_BANDED, WId, 0, 0, rectangles.size(), rectangles.constData()); } void Utility::setShapePath(quint32 WId, const QPainterPath &path, bool onlyInput) { if (path.isEmpty()) { return setRectangles(WId, QVector(), onlyInput); } QVector rectangles; foreach(const QPolygonF &polygon, path.toFillPolygons()) { foreach(const QRect &area, QRegion(polygon.toPolygon()).rects()) { xcb_rectangle_t rectangle; rectangle.x = area.x(); rectangle.y = area.y(); rectangle.width = area.width(); rectangle.height = area.height(); rectangles.append(std::move(rectangle)); } } setRectangles(WId, rectangles, onlyInput); } void Utility::sendMoveResizeMessage(quint32 WId, uint32_t action, QPoint globalPos, Qt::MouseButton qbutton) { int xbtn = qbutton == Qt::LeftButton ? XCB_BUTTON_INDEX_1 : qbutton == Qt::RightButton ? XCB_BUTTON_INDEX_3 : XCB_BUTTON_INDEX_ANY; if (globalPos.isNull()) { //QTBUG-76114 //globalPos = QCursor::pos(); xcb_generic_error_t** err = nullptr; xcb_query_pointer_reply_t* p = xcb_query_pointer_reply(QX11Info::connection(), xcb_query_pointer(QX11Info::connection(), QX11Info::appRootWindow(QX11Info::appScreen())), err); if (p && err == nullptr) { globalPos = QPoint(p->root_x, p->root_y); } if (p) { free(p); } } xcb_client_message_event_t xev; xev.response_type = XCB_CLIENT_MESSAGE; xev.type = internAtom(XATOM_MOVE_RESIZE); xev.window = WId; xev.format = 32; xev.data.data32[0] = globalPos.x(); xev.data.data32[1] = globalPos.y(); xev.data.data32[2] = action; xev.data.data32[3] = xbtn; xev.data.data32[4] = 0; xcb_ungrab_pointer(QX11Info::connection(), QX11Info::appTime()); xcb_send_event(QX11Info::connection(), false, QX11Info::appRootWindow(QX11Info::appScreen()), XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY, (const char *)&xev); xcb_flush(QX11Info::connection()); } QVector Utility::qregion2XcbRectangles(const QRegion ®ion) { QVector rectangles; rectangles.reserve(region.rectCount()); for (const QRect &rect : region.rects()) { xcb_rectangle_t r; r.x = rect.x(); r.y = rect.y(); r.width = rect.width(); r.height = rect.height(); rectangles << r; } return rectangles; } void Utility::startWindowSystemResize(quint32 WId, CornerEdge cornerEdge, const QPoint &globalPos) { sendMoveResizeMessage(WId, cornerEdge, globalPos); } static xcb_cursor_t CornerEdge2Xcb_cursor_t(Utility::CornerEdge ce) { switch (ce) { case Utility::TopEdge: return XC_top_side; case Utility::TopRightCorner: return XC_top_right_corner; case Utility::RightEdge: return XC_right_side; case Utility::BottomRightCorner: return XC_bottom_right_corner; case Utility::BottomEdge: return XC_bottom_side; case Utility::BottomLeftCorner: return XC_bottom_left_corner; case Utility::LeftEdge: return XC_left_side; case Utility::TopLeftCorner: return XC_top_left_corner; default: return XCB_CURSOR_NONE; } } bool Utility::setWindowCursor(quint32 WId, Utility::CornerEdge ce) { const auto display = QX11Info::display(); Cursor cursor = XCreateFontCursor(display, CornerEdge2Xcb_cursor_t(ce)); if (!cursor) { qWarning() << "[ui]::setWindowCursor() call XCreateFontCursor() failed"; return false; } const int result = XDefineCursor(display, WId, cursor); XFlush(display); return result == Success; } QRegion Utility::regionAddMargins(const QRegion ®ion, const QMargins &margins, const QPoint &offset) { QRegion tmp; for (const QRect &rect : region.rects()) { tmp += rect.translated(offset) + margins; } return tmp; } QByteArray Utility::windowProperty(quint32 WId, xcb_atom_t propAtom, xcb_atom_t typeAtom, quint32 len) { QByteArray data; xcb_connection_t* conn = QX11Info::connection(); xcb_get_property_cookie_t cookie = xcb_get_property(conn, false, WId, propAtom, typeAtom, 0, len); xcb_generic_error_t* err = nullptr; xcb_get_property_reply_t* reply = xcb_get_property_reply(conn, cookie, &err); if (reply != nullptr) { len = xcb_get_property_value_length(reply); const char* buf = static_cast(xcb_get_property_value(reply)); data.append(buf, len); free(reply); } if (err != nullptr) { qDebug() << "get property error"; free(err); } return data; } QList Utility::windowNetWMState(quint32 WId) { QList res; const auto wmStateAtom = XInternAtom(QX11Info::display(), kAtomNameWmState, false); xcb_connection_t* conn = QX11Info::connection(); xcb_get_property_cookie_t cookie = xcb_get_property(conn, false, WId, wmStateAtom, XCB_ATOM_ATOM, 0, 1); xcb_generic_error_t* err = nullptr; xcb_get_property_reply_t* reply = xcb_get_property_reply(conn, cookie, &err); if (reply != nullptr) { auto len = xcb_get_property_value_length(reply); uint32_t *data = static_cast(xcb_get_property_value(reply)); for (int i = 0; i < len; i++) { res.append(data[i]); } free(reply); } if (err != nullptr) { qDebug() << "get property error"; free(err); } return res; } void Utility::setWindowProperty(quint32 WId, xcb_atom_t propAtom, xcb_atom_t typeAtom, const void *data, quint32 len, uint8_t format) { xcb_connection_t* conn = QX11Info::connection(); xcb_change_property(conn, XCB_PROP_MODE_REPLACE, WId, propAtom, typeAtom, format, len, data); xcb_flush(conn); } void Utility::setStayOnTop(const QWidget *widget, bool on) { Q_ASSERT(widget); const auto display = QX11Info::display(); const auto screen = QX11Info::appScreen(); const auto wmStateAtom = XInternAtom(display, kAtomNameWmState, false); const auto stateAboveAtom = XInternAtom(display, kAtomNameWmStateAbove, false); const auto stateStaysOnTopAtom = XInternAtom(display, kAtomNameWmStateStaysOnTop, false); XEvent xev; memset(&xev, 0, sizeof(xev)); xev.xclient.type = ClientMessage; xev.xclient.message_type = wmStateAtom; xev.xclient.display = display; xev.xclient.window = widget->winId(); xev.xclient.format = 32; xev.xclient.data.l[0] = on ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; xev.xclient.data.l[1] = stateAboveAtom; xev.xclient.data.l[2] = stateStaysOnTopAtom; xev.xclient.data.l[3] = 1; XSendEvent(display, QX11Info::appRootWindow(screen), false, SubstructureRedirectMask | SubstructureNotifyMask, &xev); XFlush(display); } deepin-movie-reborn-5.0.0/src/deepin-movie.desktop000066400000000000000000000172271351125414100221330ustar00rootroot00000000000000[Desktop Entry] Categories=AudioVideo;Player; Comment=Play your video collection Exec=deepin-movie %U GenericName=Movie Icon=deepin-movie Keywords=Player;Movie;Theater;Theatre;Video; MimeType=application/ogg;application/vnd.apple.mpegurl;application/vnd.rn-realmedia;application/x-extension-mp4;application/x-flac;application/x-matroska;application/x-ogg;application/xspf+xml;image/vnd.rn-realpix;misc/ultravox;video/3gpp;video/dv;video/mp2t;video/mp4;video/mp4v-es;video/mpeg;video/msvideo;video/ogg;video/quicktime;video/vnd.rn-realvideo;video/webm;video/x-anim;video/x-avi;video/x-flc;video/x-fli;video/x-flv;video/x-m4v;video/x-matroska;video/x-mpeg;video/x-mpeg2;video/x-ms-afs;video/x-ms-asf;video/x-msvideo;video/x-ms-wmv;video/x-ms-wmx;video/x-ms-wvxvideo;video/x-nsv;video/x-ogm+ogg;video/x-theora;video/x-theora+ogg;x-content/video-dvd;x-content/video-svcd;x-content/video-vcd;x-scheme-handler/mms;x-scheme-handler/rtmp;x-scheme-handler/rtsp; Name=Deepin Movie StartupNotify=true Type=Application X-Deepin-ManualID=deepin-movie X-Deepin-Vendor=deepin # Translations: # Do not manually modify! Comment[am_ET]=የ á¥áˆ­áˆµá‹á• የ ቪዲዮ ስብስብ ያጫá‹á‰± Comment[ar]=شغل مجموعة الÙÙØ¯ÙÙˆ الخاصة بك Comment[ast]=Reproduz la to videoteca Comment[az]=Video kolleksiyavı oynat Comment[bg]=ĐŸÑ€ĐµĐ³Đ»ĐµĐ´ Đ½Đ° Đ²Đ°ÑˆĐ°Ñ‚Đ° Đ²Đ¸Đ´ĐµĐ¾ ĐºĐ¾Đ»ĐµĐºÑ†Đ¸Ñ Comment[bn]=আপনার ভিডিও কালেকশন à¦à¦¾à¦²à§ করà§à¦¨ Comment[ca]=ReproduĂ¯u la col·lecciĂ³ de mĂºsica Comment[cs]=PÅ™ehrĂ¡vejte svoji sbĂ­rku obrazovĂ½ch zĂ¡znamů Comment[da]=Afspil din videosamling Comment[de]=Der elegante Video-Player! Comment[el]=Παίξτε τη βίντεο συλλογή σας Comment[en_AU]=Play your video Comment[eo]=Ludi vian videojn kolekton Comment[es]=Reproducir tu colecciĂ³n de vĂ­deos Comment[es_419]=Reproduce tu colecciĂ³n de videos Comment[fa]=مجموعه ویدیویی خود را اجرا کنید Comment[fi]=Toistaa videokokoelmasi Comment[fil]=Manood ng mga video Comment[fr]=Lire votre collection de vidĂ©os Comment[gl_ES]=Reproduce a tĂºa colecciĂ³n de vĂ­deo Comment[he]=נגן ×ת ×וסף הויד×ו ×©×œ× Comment[hi_IN]=अपने वीडियो संगà¥à¤°à¤¹ à¤à¤²à¤¾à¤“ Comment[hr]=Izvodite vaÅ¡u video kolekciju Comment[hu]=VideĂ³gyűjtemĂ©ny lejĂ¡tszĂ¡sa Comment[hy]=Ơ†Ơ¾Ơ¡Ơ£Ơ¥Ơ¬ Ơ±Ơ¥Ö€ Ơ¾Ơ«Ơ¤Ơ¥Ơ¸ Ơ°Ơ¡Ơ¾Ơ¡Ö„Ơ¡Ơ®Ơ¸Ö‚Ơ¶ Comment[id]=Mainkan koleksi video Comment[it]=Esegui la tua raccolta video Comment[ja]=ăƒ“ăƒ‡ă‚ªă‚³ăƒ¬ă‚¯ă‚·ăƒ§ăƒ³ă®å†ç”Ÿ Comment[ko]=ë™́˜́ƒ ́»¬ë ‰́…˜ ́¬́ƒ Comment[ku_IQ]=Li koleksiyona xwe ya vĂ®dyoyĂª bixe Comment[lt]=Groti savo vaizdo kolekcijÄ… Comment[ms]=Main koleksi video Comment[nb]=Spill av videosamlingen din Comment[ne]=आफà¥à¤¨à¥‹ भिडियो संगà¥à¤°à¤¹ पà¥à¤²à¥‡ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥ Comment[nl]=Speel je videoverzameling af Comment[pl]=OdtwĂ³rz kolekcjÄ™ filmĂ³w Comment[pt]=Reproduzir a sua coleĂ§Ă£o de vĂ­deos Comment[pt_BR]=Reproduza sua coleĂ§Ă£o de vĂ­deos Comment[ro]=Redă colecÈ›ia ta video Comment[ru]=ĐŸÑ€Đ¾ÑĐ¼Đ¾Ñ‚Ñ€ Đ²Đ°ÑˆĐµĐ¹ Đ²Đ¸Đ´ĐµĐ¾-ĐºĐ¾Đ»Đ»ĐµĐºÑ†Đ¸Đ¸ Comment[sk]=PrehrĂ¡vajte svoju zbierku video zĂ¡znamov Comment[sl]=Predvajajte svojo video zbirko Comment[sr]=Đ“Đ»ĐµĐ´Đ°Ñ˜Ñ‚Đµ Đ²Đ°ÑˆÑƒ Đ²Đ¸Đ´ĐµĐ¾ ĐºĐ¾Đ»ĐµĐºÑ†Đ¸Ñ˜Ñƒ Comment[sv]=Spela din filmsamling Comment[ta]=பà¯à®¤à¯à®à¯ à®à®¾à®³à®°à®®à¯ Comment[tr]=Video koleksiyonunuzu oynatın Comment[uk]=Đ’Ñ–Đ´Ñ‚Đ²Đ¾Ñ€Đ¸Ñ‚Đ¸ ĐºĐ¾Đ»ĐµĐºÑ†Ñ–Ñ Đ²Ñ–Đ´ĐµĐ¾ Comment[zh_CN]=为您播放本地å网络视频 Comment[zh_HK]=播放你收è—ç„影片 Comment[zh_TW]=播放您ç„å½±ç‰‡é›†åˆ GenericName[ar]=الأÙلام GenericName[ast]=PelĂ­cula GenericName[bg]=Đ¤Đ¸Đ»Đ¼ GenericName[bn]=মà§à¦­à¦¿ GenericName[ca]=Pel·lĂ­cula GenericName[cs]=Film GenericName[da]=Film GenericName[de]=Film GenericName[es]=PelĂ­culas GenericName[es_419]=PelĂ­culas GenericName[fa]=Ùیلم GenericName[fi]=Elokuvat GenericName[fr]=VidĂ©o GenericName[hu]=Film GenericName[id]=Film GenericName[it]=Movie GenericName[ko]=ë™́˜́ƒ GenericName[lt]=Filmas GenericName[ms]=Cereka GenericName[ne]=à¤à¤²à¤à¤¿à¤¤à¥à¤° GenericName[nl]=Video GenericName[pl]=Filmy GenericName[pt]=Filme GenericName[pt_BR]=VĂ­deo GenericName[ru]=ĐĐ¸Đ½Đ¾Ñ‚ĐµĐ°Ñ‚Ñ€ GenericName[sk]=Film GenericName[sr]=Đ¤Đ¸Đ»Đ¼ GenericName[tr]=Sinema GenericName[uk]=Đ’Ñ–Đ´ĐµĐ¾ GenericName[zh_CN]=影院 GenericName[zh_TW]=電影 Keywords[ar]=Player;Movie;Theater;Theatre;Video; Keywords[ast]=reproductor;pelĂ­cula;videu;pelĂ­cules;vĂ­deos;theater Keywords[bg]=Player;Movie;Theater;Theatre;Video; Keywords[bn]=পà§à¦²à§‡à§Ÿà¦¾à¦°;মà§à¦­à¦¿;থিয়েটার;থিয়েটার;ভিডিও; Keywords[ca]=Reproductor;Pel·lĂ­cula;Teatre;Cinema;VĂ­deo Keywords[cs]=PÅ™ehrĂ¡vaÄ;Film;Divadlo;Video; Keywords[da]=Afspiller;Film;Biograf;Video; Keywords[de]=Player;Filme; Theater;Theatre;Movie;Video; Keywords[es]=Reproductor;VĂ­deos;PelĂ­culas; Teatro en casa. Keywords[es_419]=Reproductor; PelĂ­culas; Teatro;Videos; Keywords[fa]=پخش کننده؛ Ùیلم؛ تئاتر؛ تئاتر؛ ویدئو؛ Keywords[fi]=Soitin;Elokuva;Teatteri;Video; Keywords[fr]=Lecteur;Film;Theatre;Video; Keywords[hu]=LejĂ¡tszĂ³;Film;Mozi;Mozi;VideĂ³ Keywords[id]=Pemutar;Film;Theater;Theater;Video; Keywords[it]=Player;Movie;Theater;Theatre;Video; Keywords[ko]=Player;Movie;Theater;Theatre;Video;플레́´́–´;ë™́˜́ƒ;́˜í™”;ê·¹́¥;́˜í™”ê´€;비디́˜¤; Keywords[lt]=Grotuvas;LeistuvÄ—;Filmas;Kinoteatras;Kinas;Teatras;;Vaizdas;Video; Keywords[ms]=Pemain;Cereka;Wayang;Filem;Video; Keywords[ne]=पà¥à¤²à¥‡à¤¯à¤°; मूवी; थिà¤à¤Ÿà¤°; थियेटर; भिडियो; Keywords[nl]=Speler;Film;Theater;Bioscoop;Video; Keywords[pl]=Player;Movie;Theater;Theatre;Video;Odtwarzacz;Filmy;Kino;Teatr;Wideo; Keywords[pt]=Reprodutor;Filme;Teatro;Anfiteatro;VĂ­deo; Keywords[pt_BR]=Player;Movie;Theater;Theatre;Video; Keywords[ru]=Player;Movie;Theater;Theatre;Video; Keywords[sk]=Player;Movie;Theater;Theatre;Video; Keywords[sr]=ĐŸÑƒÑˆÑ‚Đ°Ñ‡;Đ¤Đ¸Đ»Đ¼;Đ¡Ñ†ĐµĐ½Đ°;Đ‘Đ¸Đ¾ÑĐºĐ¾Đ¿;Đ’Đ¸Đ´ĐµĐ¾; Keywords[tr]=Player;Movie;Theater;Theatre;Video;Sinema;GörĂ¼ntĂ¼;Tiyatro; Keywords[uk]=Player;Movie;Theater;Theatre;Video;Đ¿Ñ€Đ¾Đ³Ñ€Đ°Đ²Đ°Ñ‡;Đ²Ñ–Đ´ĐµĐ¾;Ñ„Ñ–Đ»ÑŒĐ¼;ĐºÑ–Đ½Đ¾Ñ‚ĐµĐ°Ñ‚Ñ€;ĐºÑ–Đ½Đ¾; Keywords[zh_CN]=播放器;电影;电影院;视频; Keywords[zh_TW]=Player;Movie;Theater;Theatre;Video;播放器;電影;å‡é™¢;影片 Name[am_ET]=ሙቪ Name[ar]=Ø£Ùلام دÙÙØ¨Ù† Name[ast]=Deepin Movie Name[az]=Deepin Film Name[bg]=Deepin Đ¤Đ¸Đ»Đ¼Đ¸ Name[bn]=ডিপিন মà§à¦­à¦¿ Name[ca]=Pel·lĂ­cula del Deepin Name[cs]=Filmy Name[da]=Deepin film Name[de]=Deepin Film Name[el]=Ταινίες Deepin Name[en_AU]=Deepin Movie Name[eo]=Deepin Filmujo Name[es]=PelĂ­culas Deepin Name[es_419]=PelĂ­culas Deepin Name[fa]=Deepin Movie (نرم Ø§ÙØ²Ø§Ø± تماشای Ùیلم دیپین) Name[fi]=Deepin Elokuvat Name[fil]=Deepin Music Name[fr]=Deepin Movie Name[gl_ES]=Filmes Name[he]=נגן ×”×¡×¨×˜×™× ×©×œ Deepin Name[hi_IN]=डीपइन à¤à¤²à¤à¤¿à¤¤à¥à¤° Name[hr]=Deepin filmski reproduktor Name[hu]=Deepin Film Name[hy]=Deepin Ơ–Ơ«Ơ¬Ơ´Ơ¥Ö€ Name[id]=Pemutar Video Deepin Name[it]=Deepin Movie Name[ja]=Deepinăƒ“ăƒ‡ă‚ªăƒ—ăƒ¬ă‚¤ăƒ¤ăƒ¼ Name[ko]=Deepin ë™́˜́ƒ Name[ku_IQ]=Deepin FĂ®lm Name[lt]=Deepin filmas Name[mn]=Đ”ÑÑĐ¿Đ¸Đ½ ĐĐ¸Đ½Đ¾ Name[ms]=Wayang Deepin Name[nb]=Deepin film Name[ne]=डिपिन à¤à¤²à¤à¤¿à¤¤à¥à¤° Name[nl]=Deepin Video's Name[pl]=Filmy Deepin Name[pt]=Deepin Movie Name[pt_BR]=VĂ­deos Deepin Name[ro]=Player-ul video Deepin Name[ru]=ĐĐ¸Đ½Đ¾Ñ‚ĐµĐ°Ñ‚Ñ€ Deepin Name[sk]=Deepin Filmy Name[sl]=Deepin Filmi Name[sr]=Đ”Đ¸Đ¿Đ¸Đ½ Đ¤Đ¸Đ»Đ¼ Name[sv]=Deepin-film Name[tr]=Deepin Sinema Name[uk]=Đ’Ñ–Đ´ĐµĐ¾ Deepin Name[vi]=Trình xem phim Deepin Name[zh_CN]=深度影院 Name[zh_HK]=Deepin 電影 Name[zh_TW]=Deepin 電影 deepin-movie-reborn-5.0.0/src/libdmr/000077500000000000000000000000001351125414100174175ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/src/libdmr/CMakeLists.txt000066400000000000000000000024171351125414100221630ustar00rootroot00000000000000project(libdmr VERSION 0.1.0) set(CMAKE_AUTOMOC ON) set(CMD_NAME dmr) add_definitions(-D_LIBDMR_) pkg_check_modules(FFTHUMB REQUIRED libffmpegthumbnailer) include_directories(${CMAKE_INCLUDE_CURRENT_DIR}) file(GLOB_RECURSE SRCS LIST_DIRECTORIES false *.cpp) file(GLOB_RECURSE MPV_SRCS LIST_DIRECTORIES false ../backends/mpv/*.cpp) list(APPEND SRCS player_widget.cpp ${MPV_SRCS}) add_library(${CMD_NAME} SHARED ${SRCS}) set_target_properties(${CMD_NAME} PROPERTIES VERSION 0.1.0 SOVERSION 0.1) target_include_directories(${CMD_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/../common ${PROJECT_SOURCE_DIR}/../backends/mpv) target_link_libraries(${CMD_NAME} PkgConfig::Dtk Qt5::Widgets Qt5::Concurrent Qt5::Network Qt5::X11Extras Qt5::Sql Qt5::DBus PkgConfig::Mpv PkgConfig::AV ${FFTHUMB_LIBRARIES} pthread GL) include(GNUInstallDirs) configure_file(libdmr.pc.in ${PROJECT_BINARY_DIR}/libdmr.pc @ONLY) install(TARGETS ${CMD_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(FILES player_widget.h player_backend.h player_engine.h playlist_model.h movie_configuration.h compositing_manager.h dvd_utils.h utils.h online_sub.h DESTINATION include/libdmr) install(FILES ${PROJECT_BINARY_DIR}/libdmr.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) deepin-movie-reborn-5.0.0/src/libdmr/compositing_manager.cpp000066400000000000000000000276361351125414100241660ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "config.h" #include "compositing_manager.h" #ifndef _LIBDMR_ #include "options.h" #endif #include #include #include #include #include #define GLX_GLXEXT_PROTOTYPES #include #include #undef Bool #include typedef const char * glXGetScreenDriver_t (Display *dpy, int scrNum); static glXGetScreenDriver_t *GetScreenDriver; //TODO: override by user setting namespace dmr { using namespace std; static CompositingManager* _compManager = nullptr; #define C2Q(cs) (QString::fromUtf8((cs).c_str())) class PlatformChecker { public: Platform check() { QProcess uname; uname.start("uname -m"); if (uname.waitForStarted()) { if (uname.waitForFinished()) { auto data = uname.readAllStandardOutput(); string machine(data.trimmed().constData()); qDebug() << QString("machine: %1").arg(machine.c_str()); QRegExp re("x86.*|i?86|ia64", Qt::CaseInsensitive); if (re.indexIn(C2Q(machine)) != -1) { qDebug() << "match x86"; _pf = Platform::X86; } else if (machine.find("alpha") != string::npos || machine.find("sw_64") != string::npos) { // shenwei qDebug() << "match shenwei"; _pf = Platform::Alpha; } else if (machine.find("mips") != string::npos) { // loongson qDebug() << "match loongson"; _pf = Platform::Alpha; } else if (machine.find("aarch64") != string::npos) { // ARM64 qDebug() << "match arm"; _pf = Platform::Arm64; } } } return _pf; } private: Platform _pf {Platform::Unknown}; }; CompositingManager& CompositingManager::get() { if(!_compManager) { _compManager = new CompositingManager(); } return *_compManager; } //void compositingChanged(bool); CompositingManager::CompositingManager() { _platform = PlatformChecker().check(); _composited = false; if (QProcessEnvironment::systemEnvironment().value("SANDBOX") == "flatpak") { _composited = QFile::exists("/dev/dri/card0"); } else if (isProprietaryDriver()) { _composited = true; } else { GetScreenDriver = (glXGetScreenDriver_t *)glXGetProcAddressARB ((const GLubyte *)"glXGetScreenDriver"); if (GetScreenDriver) { const char *name = (*GetScreenDriver) (QX11Info::display(), QX11Info::appScreen()); qDebug() << "dri driver: " << name; _composited = name != nullptr; } else { if (isDriverLoadedCorrectly() && isDirectRendered()) { _composited = true; } } } #ifndef _LIBDMR_ auto v = CommandLineManager::get().openglMode(); if (v == "off") { _composited = false; } else if (v == "on") { _composited = true; } #endif qDebug() << "composited:" << _composited; } CompositingManager::~CompositingManager() { } // Attempt to reuse mpv's code for detecting whether we want GLX or EGL (which // is tricky to do because of hardware decoding concerns). This is not pretty, // but quite effective and without having to duplicate too much GLX/EGL code. static QString probeHwdecInterop() { auto mpv = mpv::qt::Handle::FromRawHandle(mpv_create()); if (!mpv) return ""; mpv::qt::set_property(mpv, "hwdec-preload", "auto"); // Actually creating a window is required. There is currently no way to keep // this window hidden or invisible. mpv::qt::set_property(mpv, "force-window", true); // As a mitigation, put the window in the top/right corner, and make it as // small as possible by forcing 1x1 size and removing window borders. mpv::qt::set_property(mpv, "geometry", "1x1+0+0"); mpv::qt::set_property(mpv, "border", false); if (mpv_initialize(mpv) < 0) return ""; return mpv::qt::get_property(mpv, "hwdec-interop").toString(); } static OpenGLInteropKind _interopKind = OpenGLInteropKind::INTEROP_NONE; void CompositingManager::detectOpenGLEarly() { static bool detect_run = false; if (detect_run) return; auto probed = probeHwdecInterop(); qDebug() << "probeHwdecInterop" << probed << qgetenv("QT_XCB_GL_INTERGRATION"); if (probed == "vaapi-egl") { _interopKind = INTEROP_VAAPI_EGL; } else if (probed == "vaapi-glx") { _interopKind = INTEROP_VAAPI_GLX; } else if (probed == "vdpau-glx") { _interopKind = INTEROP_VDPAU_GLX; } //NOTE: probed seems to be vaapi-egl, but qt use xcb_glx by default //dxcb is not compatible with egl yet. so when USE_DXCB activated, we //should use vaapi-glx for mpv instead. #ifndef USE_DXCB // The putenv call must happen before Qt initializes its platform stuff. if (_interopKind == INTEROP_VAAPI_EGL) { qInfo() << "set QT_XCB_GL_INTERGRATION to xcb_egl"; fprintf(stderr, "set QT_XCB_GL_INTERGRATION to xcb_egl\n"); qputenv("QT_XCB_GL_INTEGRATION", "xcb_egl"); } else { //do nothing, this is default //qputenv("QT_XCB_GL_INTEGRATION", "xcb_glx"); } #else if (_interopKind == INTEROP_VAAPI_EGL) { _interopKind = INTEROP_VAAPI_GLX; } #endif detect_run = true; } OpenGLInteropKind CompositingManager::interopKind() { return _interopKind; } bool CompositingManager::isDriverLoadedCorrectly() { static QRegExp aiglx_err("\\(EE\\)\\s+AIGLX error"); static QRegExp dri_ok("direct rendering: DRI\\d+ enabled"); static QRegExp swrast("GLX: Initialized DRISWRAST"); QString xorglog = QString("/var/log/Xorg.%1.log").arg(QX11Info::appScreen()); qDebug() << "check " << xorglog; QFile f(xorglog); if (!f.open(QFile::ReadOnly)) { qWarning() << "can not open " << xorglog; return false; } QTextStream ts(&f); while (!ts.atEnd()) { QString ln = ts.readLine(); if (aiglx_err.indexIn(ln) != -1) { qDebug() << "found aiglx error"; return false; } if (dri_ok.indexIn(ln) != -1) { qDebug() << "dri enabled successfully"; return true; } if (swrast.indexIn(ln) != -1) { qDebug() << "swrast driver used"; return false; } } return true; } void CompositingManager::overrideCompositeMode(bool useCompositing) { if (_composited != useCompositing) { qInfo() << "override composited = " << useCompositing; _composited = useCompositing; } } using namespace std; bool CompositingManager::is_card_exists(int id, const vector& drivers) { char buf[1024] = {0}; snprintf(buf, sizeof buf, "/sys/class/drm/card%d/device/driver", id); char buf2[1024] = {0}; if (readlink(buf, buf2, sizeof buf2) < 0) { return false; } string driver = basename(buf2); qDebug() << "drm driver " << driver.c_str(); if (std::any_of(drivers.cbegin(), drivers.cend(), [=](string s) { return s == driver; })) { return true; } return false; } bool CompositingManager::is_device_viable(int id) { char path[128]; snprintf(path, sizeof path, "/sys/class/drm/card%d", id); if (access(path, F_OK) != 0) { return false; } //OK, on shenwei, this file may have no read permission for group/other. char buf[512]; snprintf(buf, sizeof buf, "%s/device/enable", path); if (access(buf, R_OK) == 0) { FILE* fp = fopen(buf, "r"); if (!fp) { return false; } int enabled = 0; fscanf(fp, "%d", &enabled); fclose(fp); // nouveau may write 2, others 1 return enabled > 0; } return false; } bool CompositingManager::isProprietaryDriver() { for (int id = 0; id <= 10; id++) { if (!QFile::exists(QString("/sys/class/drm/card%1").arg(id))) break; if (is_device_viable(id)) { vector drivers = {"nvidia", "fglrx", "hibmc-drm"}; return is_card_exists(id, drivers); } } return false; } //this is not accurate when proprietary driver used bool CompositingManager::isDirectRendered() { QProcess xdriinfo; xdriinfo.start("xdriinfo driver 0"); if (xdriinfo.waitForStarted() && xdriinfo.waitForFinished()) { QString drv = QString::fromUtf8(xdriinfo.readAllStandardOutput().trimmed().constData()); qDebug() << "xdriinfo: " << drv; return !drv.contains("is not direct rendering capable"); } return true; } //FIXME: what about merge options from both config PlayerOptionList CompositingManager::getProfile(const QString& name) { auto localPath = QString("%1/%2/%3/%4.profile") .arg(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)) .arg(qApp->organizationName()) .arg(qApp->applicationName()) .arg(name); auto defaultPath = QString(":/resources/profiles/%1.profile").arg(name); #ifdef _LIBDMR_ QString oc; #else auto oc = CommandLineManager::get().overrideConfig(); #endif PlayerOptionList ol; QList files = {oc, localPath, defaultPath}; auto p = files.begin(); while (p != files.end()) { QFileInfo fi(*p); if (fi.exists()) { qDebug() << "load" << fi.absoluteFilePath(); QFile f(fi.absoluteFilePath()); f.open(QIODevice::ReadOnly); QTextStream ts(&f); while (!ts.atEnd()) { auto l = ts.readLine().trimmed(); if (l.isEmpty()) continue; auto kv = l.split("="); qDebug() << l << kv; if (kv.size() == 1) { ol.push_back(qMakePair(kv[0], QString::fromUtf8(""))); } else { ol.push_back(qMakePair(kv[0], kv[1])); } } return ol; } ++p; } return ol; } PlayerOptionList CompositingManager::getBestProfile() { QString profile_name = "default"; switch (_platform) { case Platform::Alpha: case Platform::Mips: case Platform::Arm64: profile_name = _composited ? "composited" : "failsafe"; break; case Platform::X86: profile_name = _composited ? "composited" : "default"; break; case Platform::Unknown: break; } return getProfile(profile_name); } #undef C2Q } deepin-movie-reborn-5.0.0/src/libdmr/compositing_manager.h000066400000000000000000000064741351125414100236300ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_COMPOSITING_MANAGER #define _DMR_COMPOSITING_MANAGER #include #include #include namespace dmr { enum Platform { Unknown, X86, // intel & amd Mips, // loongson Alpha, // sunway Arm64 }; enum OpenGLInteropKind { INTEROP_NONE, INTEROP_VAAPI_EGL, INTEROP_VAAPI_GLX, INTEROP_VDPAU_GLX, }; using PlayerOption = QPair; using PlayerOptionList = QList; class CompositingManager: public QObject { public: static CompositingManager& get(); virtual ~CompositingManager(); /** * should call this before any other qt functions get exec'ed. * this makes sure mpv openglcb-interop to work correctly */ static void detectOpenGLEarly(); /** * get detectOpenGLEarly result */ static OpenGLInteropKind interopKind(); /** * override auto-detected compositing state. * should call this right before player engine gets instantiated. */ void overrideCompositeMode(bool useCompositing); // this actually means opengl rendering is capable bool composited() const { return _composited; } Platform platform() const { return _platform; } PlayerOptionList getProfile(const QString& name); PlayerOptionList getBestProfile(); // best for current platform and env signals: void compositingChanged(bool); private: CompositingManager(); bool isDriverLoadedCorrectly(); bool isDirectRendered(); bool isProprietaryDriver(); bool is_device_viable(int id); bool is_card_exists(int id, const std::vector& drivers); bool _composited {false}; Platform _platform {Platform::Unknown}; }; } #endif /* ifndef _DMR_COMPOSITING_MANAGER */ deepin-movie-reborn-5.0.0/src/libdmr/dvd_utils.cpp000066400000000000000000000054161351125414100221260ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "dvd_utils.h" #include namespace dmr { namespace dvd { QString RetrieveDVDTitle(const QString& device) { qDebug() << "device" << device; const char *title = NULL; dvdnav_t *handle = NULL; auto res = dvdnav_open(&handle, device.toUtf8().constData()); if (res == DVDNAV_STATUS_ERR) { qWarning() << "dvdnav open " << device << "failed"; return ""; } int32_t nr_titles = 0; res = dvdnav_get_number_of_titles(handle, &nr_titles); if (res == DVDNAV_STATUS_ERR) { goto on_error; } res = dvdnav_get_title_string(handle, &title); if (res == DVDNAV_STATUS_ERR) { goto on_error; } #if 0 uint64_t max_duration = -1; QString title = ""; //uint32_t dvdnav_describe_title_chapters(dvdnav_t *self, int32_t title, uint64_t **times, uint64_t *duration); for (int i = 0; i < nr_titles; i++) { uint64_t duration = 0; auto n = dvdnav_describe_title_chapters(handle, i, NULL, &duration); if (max_duration < duration) { max_duration = duration; //title } } #endif if (handle) dvdnav_close(handle); return QString::fromUtf8(title); on_error: qWarning() << dvdnav_err_to_string(handle); if (handle) dvdnav_close(handle); return ""; } } } deepin-movie-reborn-5.0.0/src/libdmr/dvd_utils.h000066400000000000000000000033211351125414100215640ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_DVD_UTILS_H #define _DMR_DVD_UTILS_H #include namespace dmr { namespace dvd { // device could be a dev node or a iso file QString RetrieveDVDTitle(const QString& device); } } #endif /* ifndef _DMR_DVD_UTILS_H */ deepin-movie-reborn-5.0.0/src/libdmr/libdmr.pc.in000066400000000000000000000005021351125414100216160ustar00rootroot00000000000000prefix=/usr exec_prefix=${prefix} libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ includedir=${prefix}/include/libdmr Name: dmr Description: deepin movie player widget development file Version: @PROJECT_VERSION@ Libs: -ldmr Cflags: -I${includedir} Requires: Qt5Widgets Qt5X11Extras Qt5Concurrent Qt5Network gl dtkcore dtkwidget deepin-movie-reborn-5.0.0/src/libdmr/movie_configuration.cpp000066400000000000000000000223561351125414100242010ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "config.h" #include "movie_configuration.h" #include "utils.h" #include #include namespace dmr { static std::atomic _instance { nullptr }; static QMutex _instLock; #define CHECKED_EXEC(q) do { \ if (!(q).exec()) { \ qCritical() << (q).lastError(); \ } \ } while (0) // storage as a database: // table 1: urls // url md5 timestamp // md5 is local file's md5, if url is networked, md5 == 0 // table 2: infos (stores info about every url) // url key value class MovieConfigurationBackend: public QObject { public: MovieConfigurationBackend(MovieConfiguration* cfg): QObject(cfg) { auto db_dir = QString("%1/%2/%3") .arg(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)) .arg(qApp->organizationName()) .arg(qApp->applicationName()); QDir d; d.mkpath(db_dir); auto db_path = QString("%1/movies.db").arg(db_dir); _db = QSqlDatabase::addDatabase("QSQLITE"); _db.setDatabaseName(db_path); _db.open(); auto ts = _db.tables(QSql::Tables); if (!ts.contains("urls") || !ts.contains("infos")) { QSqlQuery q(_db); if (!q.exec("create table if not exists urls (url TEXT primary key, " "md5 TEXT, timestamp DATETIME)")) { qCritical() << q.lastError(); } if (!q.exec("create table if not exists infos (url TEXT, " "key TEXT, value BLOB, primary key (url, key))")) { qCritical() << q.lastError(); } } } void deleteUrl(const QUrl& url) { _db.transaction(); QSqlQuery q(_db); q.prepare("delete from infos where url = ?"); q.addBindValue(url); if (!q.exec()) { _db.commit(); return; } if (q.numRowsAffected() > 0) { QSqlQuery q(_db); q.prepare("delete from urls where url = ?"); q.addBindValue(url); CHECKED_EXEC(q); } } bool urlExists(const QUrl& url) { QSqlQuery q(_db); q.prepare("select url from urls where url = ? limit 1"); q.addBindValue(url); CHECKED_EXEC(q); return q.first(); } void clear() { _db.transaction(); QSqlQuery q(_db); if (q.exec("delete from infos")) { if (q.exec("delete from urls")) { _db.commit(); return; } } _db.rollback(); } void updateUrl(const QUrl& url, const QString& key, const QVariant& val) { qDebug() << url << key << val; _db.transaction(); if (!urlExists(url)) { QString md5; if (url.isLocalFile()) { md5 = utils::FastFileHash(QFileInfo(url.toLocalFile())); } else { md5 = QString(QCryptographicHash::hash(url.toString().toUtf8(), QCryptographicHash::Md5).toHex()); } QSqlQuery q(_db); q.prepare("insert into urls (url, md5, timestamp) values (?, ?, ?)"); q.addBindValue(url); q.addBindValue(md5); q.addBindValue(QDateTime::currentDateTimeUtc()); if (!q.exec()) { _db.rollback(); return; } } QSqlQuery q(_db); q.prepare("replace into infos (url, key, value) values (?, ?, ?)"); q.addBindValue(url); q.addBindValue(key); q.addBindValue(val); CHECKED_EXEC(q); _db.commit(); } QVariant queryValueByUrlKey(const QUrl& url, const QString& key) { if (!urlExists(url)) return {}; QSqlQuery q(_db); q.prepare("select value from infos where url = ? and key = ?"); q.addBindValue(url); q.addBindValue(key); CHECKED_EXEC(q); if (q.next()) { return q.value(0); } return QVariant(); } QMap queryByUrl(const QUrl& url) { if (!urlExists(url)) return {}; QSqlQuery q(_db); q.prepare("select key, value from infos where url = ?"); q.addBindValue(url); CHECKED_EXEC(q); QMap res; while (q.next()) { res.insert(q.value(0).toString(), q.value(1)); } return res; } ~MovieConfigurationBackend() { _db.close(); QSqlDatabase::removeDatabase(_db.connectionName()); } private: QSqlDatabase _db; }; MovieConfiguration& MovieConfiguration::get() { if (_instance == nullptr) { QMutexLocker lock(&_instLock); if (_instance == nullptr) { _instance = new MovieConfiguration; } } return *_instance; } void MovieConfiguration::removeUrl(const QUrl& url) { _backend->deleteUrl(url); } bool MovieConfiguration::urlExists(const QUrl& url) { return _backend->urlExists(url); } void MovieConfiguration::clear() { _backend->clear(); } void MovieConfiguration::updateUrl(const QUrl& url, const QString& key, const QVariant& val) { _backend->updateUrl(url, key, val); } void MovieConfiguration::updateUrl(const QUrl& url, KnownKey key, const QVariant& val) { updateUrl(url, knownKey2String(key), val); } void MovieConfiguration::append2ListUrl(const QUrl& url, KnownKey key, const QString& val) { auto list = getByUrl(url, knownKey2String(key)).toString().split(';', QString::SkipEmptyParts); auto bytes = val.toUtf8().toBase64(); list.append(bytes); updateUrl(url, key, list.join(';')); } void MovieConfiguration::removeFromListUrl(const QUrl& url, KnownKey key, const QString& val) { auto list = getListByUrl(url, key); } QString MovieConfiguration::knownKey2String(KnownKey kk) { switch (kk) { case KnownKey::SubDelay: return "sub-delay"; case KnownKey::SubCodepage: return "sub-codepage"; case KnownKey::SubId: return "sid"; case KnownKey::StartPos: return "start"; case KnownKey::ExternalSubs: return "external-subs"; default: return ""; } } QStringList MovieConfiguration::getListByUrl(const QUrl& url, KnownKey key) { return decodeList(getByUrl(url, knownKey2String(key))); } QStringList MovieConfiguration::decodeList(const QVariant& val) { auto list = val.toString().split(';', QString::SkipEmptyParts); std::transform(list.begin(), list.end(), list.begin(), [](const QString& s) { return QByteArray::fromBase64(s.toUtf8()); }); return list; } QVariant MovieConfiguration::getByUrl(const QUrl& url, const QString& key) { return _backend->queryValueByUrlKey(url, key); } QVariant MovieConfiguration::getByUrl(const QUrl& url, KnownKey key) { return getByUrl(url, knownKey2String(key)); } QMap MovieConfiguration::queryByUrl(const QUrl& url) { return _backend->queryByUrl(url); } MovieConfiguration::~MovieConfiguration() { delete _backend; } MovieConfiguration::MovieConfiguration() :QObject(0) { } static void _backend_test() { auto& mc = MovieConfiguration::get(); mc.updateUrl(QUrl("movie1"), "sub-delay", -2.5); mc.updateUrl(QUrl("movie1"), "sub-delay", 1.5); mc.updateUrl(QUrl("movie2"), "sub-delay", 1.0); mc.updateUrl(QUrl("movie1"), "volume", 20); //mc.clear(); auto res = mc.queryByUrl(QUrl("movie1")); Q_ASSERT (res.size() == 2); qDebug() << res; mc.removeUrl(QUrl("movie1")); mc.updateUrl(QUrl("movie1"), "volume", 30); mc.updateUrl(QUrl("movie2"), "volume", 40); res = mc.queryByUrl(QUrl("movie1")); Q_ASSERT (res.size() == 1); qDebug() << res; mc.clear(); } void MovieConfiguration::init() { _backend = new MovieConfigurationBackend(this); #ifdef SQL_TEST _backend_test(); #endif } } deepin-movie-reborn-5.0.0/src/libdmr/movie_configuration.h000066400000000000000000000056401351125414100236430ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_MOVIE_CONFIGURATION_H #define _DMR_MOVIE_CONFIGURATION_H #include namespace dmr { class MovieConfigurationBackend; class MovieConfiguration: public QObject { Q_OBJECT public: enum KnownKey { SubDelay, SubCodepage, SubId, StartPos, ExternalSubs }; static MovieConfiguration& get(); void init(); // call once void removeUrl(const QUrl& url); void clear(); bool urlExists(const QUrl& url); void updateUrl(const QUrl& url, const QString& key, const QVariant& val); void updateUrl(const QUrl& url, KnownKey key, const QVariant& val); //helper for update list type entries void append2ListUrl(const QUrl& url, KnownKey key, const QString& val); void removeFromListUrl(const QUrl& url, KnownKey key, const QString& val); //list all settings for url QMap queryByUrl(const QUrl& url); QVariant getByUrl(const QUrl& url, const QString& key); QVariant getByUrl(const QUrl& url, KnownKey key); //helper for get list type entries QStringList getListByUrl(const QUrl& url, KnownKey key); //helper QStringList decodeList(const QVariant& val); ~MovieConfiguration(); static QString knownKey2String(KnownKey kk); private: MovieConfiguration(); MovieConfigurationBackend* _backend {nullptr}; }; using ConfigKnownKey = MovieConfiguration::KnownKey; } #endif /* ifndef _DMR_MOVIE_CONFIGURATION_H */ deepin-movie-reborn-5.0.0/src/libdmr/online_sub.cpp000066400000000000000000000240241351125414100222620ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "online_sub.h" #include "dmr_settings.h" #include "utils.h" #include #include namespace dmr { static OnlineSubtitle *_instance = nullptr; using RequestFunc = QString (const QFileInfo& fi); struct SubtitleProvider { QString apiurl; std::function reqfn; }; static SubtitleProvider shooter; static QString hash_file(const QFileInfo& fi) { auto sz = fi.size(); QList offsets = { 4096, sz / 3 * 2, sz / 3, sz - 8192 }; QStringList mds; QFile f(fi.absoluteFilePath()); if (!f.open(QFile::ReadOnly)) { return QString(); } std::for_each(offsets.begin(), offsets.end(), [&f, &mds](qint64 v) { f.seek(v); auto bytes = f.read(4096); #if 1 auto h = QString(QCryptographicHash::hash(bytes, QCryptographicHash::Md5).toHex()); mds.append(h); #else unsigned char out[16]; MD5_CTX ctx; MD5_Init(&ctx); MD5_Update(&ctx, bytes.data(), bytes.size()); MD5_Final(out, &ctx); char hex[] = "0123456789ABCDEF"; char md5[32]; for (int i = 0; i < 16; i++) { md5[i*2] = hex[out[i] >> 4]; md5[i*2+1] = hex[out[i] & 0xf]; } mds.append(QString::fromLatin1((const char*)md5, 32)); #endif }); qDebug() << mds.join(";"); //Qt seems has a bug that ; will not be encoded as %3B in url query return mds.join("%3B"); } OnlineSubtitle& OnlineSubtitle::get() { if (_instance == nullptr) { _instance = new OnlineSubtitle; } return *_instance; } OnlineSubtitle::OnlineSubtitle() { shooter.apiurl = "http://www.shooter.cn/api/subapi.php"; shooter.reqfn = [](const QFileInfo& fi) { if (!fi.exists()) return ""; return ""; }; _defaultLocation = QString("%1/%2/%3/subtitles") .arg(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)) .arg(qApp->organizationName()) .arg(qApp->applicationName()); QDir d; d.mkpath(_defaultLocation); _nam = new QNetworkAccessManager(this); connect(_nam, &QNetworkAccessManager::finished, this, &OnlineSubtitle::replyReceived); } void OnlineSubtitle::subtitlesDownloadComplete() { QList files; for (auto& sub: _subs) { if (!sub.local.isEmpty()) files.append(sub.local); // filter out some index files (idx e.g.) } emit subtitlesDownloadedFor(QUrl::fromLocalFile(_lastReqVideo.absoluteFilePath()), files, _lastReason); _subs.clear(); _lastReqVideo = QFileInfo(); _lastReason = FailReason::NoError; } QString OnlineSubtitle::findAvailableName(const QString& tmpl, int id) { QString name_tmpl = tmpl; int i = tmpl.lastIndexOf('.'); if (i >= 0) { name_tmpl.replace(i, 1, "[%1]."); } else { name_tmpl = name_tmpl.append("[%1]"); } auto c = id; do { auto name = name_tmpl.arg(c); auto path = QString("%1/%2").arg(storeLocation()).arg(name); if (!QFile::exists(path)) { return path; } c++; } while (c < (1<<16)); return tmpl; } void OnlineSubtitle::replyReceived(QNetworkReply* reply) { reply->deleteLater(); if (reply->error() != QNetworkReply::NoError) { if (reply->property("type") == "sub") { _pendingDownloads--; if (_pendingDownloads <= 0) { _lastReason = FailReason::NetworkError; subtitlesDownloadComplete(); } } qDebug() << reply->errorString(); return; } if (reply->property("type") == "meta") { auto data = reply->readAll(); qDebug() << "data size " << data.size() << (int)data[0]; if (data.size() == 1 && (int)data[0] == -1) { qDebug() << "no subtitle found"; _lastReason = FailReason::NoSubFound; subtitlesDownloadComplete(); return; } auto json = QJsonDocument::fromJson(data); if (json.isArray()) { qDebug() << json; _subs.clear(); for (auto v: json.array()) { if (v.isObject()) { auto obj = v.toObject(); for (auto f: obj["Files"].toArray()) { auto fi = f.toObject(); ShooterSubtitleMeta meta; meta.id = _subs.size(); meta.desc = obj["Desc"].toString(); meta.delay = obj["Delay"].toInt(); meta.ext = fi["Ext"].toString(); meta.link = fi["Link"].toString(); _subs.append(meta); } } } downloadSubtitles(); } reply->close(); } else if (reply->property("type") == "sub") { QString path; QString name_tmpl; auto data = reply->readAll(); auto disposition = reply->header(QNetworkRequest::ContentDispositionHeader); if (disposition.isValid()) { //set name to disposition filename qDebug() << disposition; } else if (reply->hasRawHeader("Content-Disposition")) { QByteArray name; auto bytes = reply->rawHeader("Content-Disposition"); for (auto h: bytes.split(';')) { auto kv = h.split('='); if (kv.size() == 2 && kv[0].trimmed() == "filename") { name = kv[1].trimmed(); break; } } if (!name.isEmpty()) { auto codec = QTextCodec::codecForName("UTF-8"); name_tmpl = codec->toUnicode(name); } } else { int id = reply->property("id").toInt(); name_tmpl = QString("%1.%2").arg(_lastReqVideo.completeBaseName()) .arg(_subs[id].ext); } reply->close(); int id = reply->property("id").toInt(); path = findAvailableName(name_tmpl, id); { QFile f(path); if (f.open(QFile::WriteOnly)) { f.write(data); } f.flush(); } _pendingDownloads--; if (hasHashConflict(path, name_tmpl)) { _lastReason = FailReason::Duplicated; QFile::remove(path); } else { _subs[id].local = path; qDebug() << "save to " << path; } if (_pendingDownloads <= 0) { subtitlesDownloadComplete(); } } } bool OnlineSubtitle::hasHashConflict(const QString& path, const QString& tmpl) { QFileInfo fi(path); auto md5 = utils::FullFileHash(fi); QDirIterator di(fi.path()); while (di.hasNext()) { di.next(); auto s = di.fileName(); if (fi.fileName() == di.fileName()) continue; s = s.replace(QRegExp("\\[\\d+\\]"), ""); if (tmpl == s) { auto h = utils::FullFileHash(di.fileInfo()); qDebug() << "found " << di.fileName() << h; if (h == md5) { return true; } } } return false; } void OnlineSubtitle::downloadSubtitles() { _pendingDownloads = _subs.size(); for (auto& sub: _subs) { QNetworkRequest req; //QUrl url(sub.link.toUtf8()); auto s = sub.link; s.replace("https://", "http://"); QUrl url(s); url.setScheme("http"); req.setUrl(url); auto *reply = _nam->get(req); //qDebug() << __func__ << sub.link << url; reply->setProperty("type", "sub"); reply->setProperty("id", sub.id); } } QString OnlineSubtitle::storeLocation() { return _defaultLocation; } void OnlineSubtitle::requestSubtitle(const QUrl& url) { QFileInfo fi(url.toLocalFile()); QString h = hash_file(fi); _lastReqVideo = fi; QUrl req_url; req_url.setUrl(shooter.apiurl); QUrlQuery q; q.addQueryItem("filehash", h); //q.addQueryItem("pathinfo", fi.absoluteFilePath()); q.addQueryItem("pathinfo", fi.fileName()); q.addQueryItem("format", "json"); //q.addQueryItem("lang", "chn"); QUrl params; params.setQuery(q); auto data = params.query(QUrl::FullyEncoded).toUtf8(); //qDebug() << req_url << params.query(QUrl::FullyEncoded); QNetworkRequest req; req.setUrl(shooter.apiurl); req.setHeader(QNetworkRequest::ContentLengthHeader, data.length()); req.setRawHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8"); auto reply = _nam->post(req, data); reply->setProperty("type", "meta"); } } deepin-movie-reborn-5.0.0/src/libdmr/online_sub.h000066400000000000000000000055031351125414100217300ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_ONLINE_SUB_H #define _DMR_ONLINE_SUB_H #include #include #include #include namespace dmr { struct ShooterSubtitleMeta { int id; int delay; QString desc; QString ext; QString link; // url to download QString local; // saved position when downloaded }; class OnlineSubtitle: public QObject { Q_OBJECT public: enum FailReason { NoError, NetworkError, NoSubFound, Duplicated, // the same hash with local cache }; static OnlineSubtitle& get(); QString storeLocation(); public slots: void requestSubtitle(const QUrl& url); private slots: void replyReceived(QNetworkReply*); void downloadSubtitles(); signals: void subtitlesDownloadedFor(const QUrl& url, const QList& filenames, FailReason r); private: QString _defaultLocation; QNetworkAccessManager *_nam {nullptr}; int _pendingDownloads {0}; // this should equal to _subs.size() basically QList _subs; QFileInfo _lastReqVideo; FailReason _lastReason {NoError}; OnlineSubtitle(); void subtitlesDownloadComplete(); QString findAvailableName(const QString& tmpl, int id); bool hasHashConflict(const QString& path, const QString& tmpl); }; } #endif /* ifndef _DMR_ONLINE_SUB_H */ deepin-movie-reborn-5.0.0/src/libdmr/player_backend.cpp000066400000000000000000000031171351125414100230700ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "player_backend.h" namespace dmr { Backend::DebugLevel Backend::_debugLevel = Backend::DebugLevel::Info; } deepin-movie-reborn-5.0.0/src/libdmr/player_backend.h000066400000000000000000000127551351125414100225450ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_PLAYER_BACKEND_H #define _DMR_PLAYER_BACKEND_H #include namespace dmr { class PlayingMovieInfo; // Player backend base class // There are only two backends: mpv and vpu // mpv is the only and default on all platform except Sunway // vpu is default for Sunway if media file can be hardware-decoded by coda vpu class Backend: public QWidget { Q_OBJECT Q_PROPERTY(qint64 duration READ duration) Q_PROPERTY(qint64 elapsed READ elapsed NOTIFY elapsedChanged) Q_PROPERTY(QSize videoSize READ videoSize NOTIFY videoSizeChanged) Q_PROPERTY(bool paused READ paused) Q_PROPERTY(PlayState state READ state NOTIFY stateChanged) public: enum PlayState { Playing, Paused, Stopped }; Q_ENUM(PlayState) enum SoundMode { Stereo, Left, Right }; Q_ENUM(SoundMode) enum DebugLevel { Info, Debug, // some normal debug info Verbose // very verbosed output from backend }; Q_ENUM(DebugLevel) Backend(QWidget *parent = 0) {} virtual ~Backend() {} virtual void setPlayFile(const QUrl& url) { _file = url; } virtual void setDVDDevice(const QString& path) { _dvdDevice = path; } // NOTE: need to check if file is playable by this backend, // this is important especially for vpu virtual bool isPlayable() const = 0; virtual qint64 duration() const { return 0; } virtual qint64 elapsed() const { return 0; } virtual QSize videoSize() const = 0; virtual bool paused() { return _state == PlayState::Paused; } virtual PlayState state() const { return _state; } virtual const PlayingMovieInfo& playingMovieInfo() = 0; virtual void setPlaySpeed(double times) = 0; virtual void savePlaybackPosition() = 0; virtual void updateSubStyle(const QString& font, int sz) = 0; virtual void setSubCodepage(const QString& cp) = 0; virtual QString subCodepage() = 0; virtual void addSubSearchPath(const QString& path) = 0; virtual bool loadSubtitle(const QFileInfo& fi) = 0; virtual void toggleSubtitle() = 0; virtual bool isSubVisible() = 0; virtual void selectSubtitle(int id) = 0; virtual void selectTrack(int id) = 0; virtual void setSubDelay(double secs) = 0; virtual double subDelay() const = 0; virtual int aid() const = 0; virtual int sid() const = 0; virtual void changeSoundMode(SoundMode sm) {} virtual int volume() const = 0; virtual bool muted() const = 0; virtual void setVideoAspect(double r) = 0; virtual double videoAspect() const = 0; virtual int videoRotation() const = 0; virtual void setVideoRotation(int degree) = 0; virtual QImage takeScreenshot() = 0; virtual void burstScreenshot() = 0; //initial the start of burst screenshotting virtual void stopBurstScreenshot() = 0; // hack: used to access backend internal states virtual QVariant getProperty(const QString&) = 0; virtual void setProperty(const QString&, const QVariant&) = 0; virtual void nextFrame() = 0; virtual void previousFrame() = 0; static void setDebugLevel(DebugLevel lvl) { _debugLevel = lvl; } Q_SIGNALS: void tracksChanged(); void elapsedChanged(); void videoSizeChanged(); void stateChanged(); void fileLoaded(); void muteChanged(); void volumeChanged(); void sidChanged(); void aidChanged(); //emit during burst screenshotting void notifyScreenshot(const QImage& frame, qint64 time); public slots: virtual void play() = 0; virtual void pauseResume() = 0; virtual void stop() = 0; virtual void seekForward(int secs) = 0; virtual void seekBackward(int secs) = 0; virtual void seekAbsolute(int) = 0; virtual void volumeUp() = 0; virtual void volumeDown() = 0; virtual void changeVolume(int val) = 0; virtual void toggleMute() = 0; protected: PlayState _state { PlayState::Stopped }; QString _dvdDevice {"/dev/sr0"}; QUrl _file; static DebugLevel _debugLevel; }; } #endif /* ifndef _DMR_PLAYER_BACKEND_H */ deepin-movie-reborn-5.0.0/src/libdmr/player_engine.cpp000066400000000000000000000441271351125414100227540ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "config.h" #include "player_engine.h" #include "playlist_model.h" #include "movie_configuration.h" #include "online_sub.h" #include "mpv_proxy.h" #ifndef _LIBDMR_ #include "dmr_settings.h" #endif #include "drecentmanager.h" DCORE_USE_NAMESPACE namespace dmr { PlayerEngine::PlayerEngine(QWidget *parent) :QWidget(parent) { auto *l = new QVBoxLayout(this); l->setContentsMargins(0, 0, 0, 0); _current = new MpvProxy(this); if (_current) { connect(_current, &Backend::stateChanged, this, &PlayerEngine::onBackendStateChanged); connect(_current, &Backend::tracksChanged, this, &PlayerEngine::tracksChanged); connect(_current, &Backend::elapsedChanged, this, &PlayerEngine::elapsedChanged); connect(_current, &Backend::fileLoaded, this, &PlayerEngine::fileLoaded); connect(_current, &Backend::muteChanged, this, &PlayerEngine::muteChanged); connect(_current, &Backend::volumeChanged, this, &PlayerEngine::volumeChanged); connect(_current, &Backend::sidChanged, this, &PlayerEngine::sidChanged); connect(_current, &Backend::aidChanged, this, &PlayerEngine::aidChanged); connect(_current, &Backend::videoSizeChanged, this, &PlayerEngine::videoSizeChanged); connect(_current, &Backend::notifyScreenshot, this, &PlayerEngine::notifyScreenshot); l->addWidget(_current); } setLayout(l); #ifndef _LIBDMR_ connect(&Settings::get(), &Settings::subtitleChanged, this, &PlayerEngine::updateSubStyles); #endif connect(&OnlineSubtitle::get(), &OnlineSubtitle::subtitlesDownloadedFor, this, &PlayerEngine::onSubtitlesDownloaded); addSubSearchPath(OnlineSubtitle::get().storeLocation()); _playlist = new PlaylistModel(this); connect(_playlist, &PlaylistModel::asyncAppendFinished, this, &PlayerEngine::onPlaylistAsyncAppendFinished); } PlayerEngine::~PlayerEngine() { disconnect(_playlist, 0, 0, 0); delete _playlist; _playlist = nullptr; if (_current) { disconnect(_current, 0, 0, 0); delete _current; _current = nullptr; } qDebug() << __func__; } bool PlayerEngine::isPlayableFile(const QUrl& url) { if (url.isLocalFile()) { return isPlayableFile(url.path()); } else { // for a networked url, there is no way to know if it's playable right now return true; } } static QStringList suffixes; static const QStringList& buildPlayableDatabase() { static QStringList mimeTypes = { "application/ogg", "application/vnd.apple.mpegurl", "application/vnd.rn-realmedia", "application/x-extension-mp4", "application/x-flac", "application/x-matroska", "application/x-ogg", "application/xspf+xml", "image/vnd.rn-realpix", "misc/ultravox", "video/3gpp", "video/dv", "video/mp2t", "video/mp4", "video/mp4v-es", "video/mpeg", "video/msvideo", "video/ogg", "video/quicktime", "video/vnd.rn-realvideo", "video/webm", "video/x-anim", "video/x-avi", "video/x-flc", "video/x-fli", "video/x-flv", "video/x-m4v", "video/x-matroska", "video/x-mpeg", "video/x-mpeg2", "video/x-ms-afs", "video/x-ms-asf", "video/x-msvideo", "video/x-ms-wmv", "video/x-ms-wmx", "video/x-ms-wvxvideo", "video/x-nsv", "video/x-ogm+ogg", "video/x-theora", "video/x-theora+ogg", "x-content/video-dvd", "x-content/video-svcd", "x-content/video-vcd", "x-scheme-handler/mms", "x-scheme-handler/rtmp", "x-scheme-handler/rtsp", }; if (suffixes.isEmpty()) { } return suffixes; } bool PlayerEngine::isPlayableFile(const QString& name) { auto suffix = QString("*") + name.mid(name.lastIndexOf('.')); return video_filetypes.contains(suffix, Qt::CaseInsensitive); } void PlayerEngine::updateSubStyles() { #ifndef _LIBDMR_ auto font_opt = Settings::get().settings()->option("subtitle.font.family"); auto font_id = font_opt->value().toInt(); auto font = font_opt->data("items").toStringList()[font_id]; auto sz = Settings::get().settings()->option("subtitle.font.size")->value().toInt(); if (_state != CoreState::Idle) { if (_playlist->current() < 0) return; auto vh = videoSize().height(); if (vh <= 0) { vh = _playlist->currentInfo().mi.height; } double scale = vh / 720.0; sz /= scale; /* magic scale number 2.0 comes from my mind, test with my eyes... */ sz *= 2.0; qDebug() << "update sub " << font << sz; updateSubStyle(font, sz); } #endif } void PlayerEngine::waitLastEnd() { if (auto *mpv = dynamic_cast(_current)) { mpv->pollingEndOfPlayback(); } } void PlayerEngine::onBackendStateChanged() { if (!_current) return; auto old = _state; switch (_current->state()) { case Backend::PlayState::Playing: _state = CoreState::Playing; break; case Backend::PlayState::Paused: _state = CoreState::Paused; break; case Backend::PlayState::Stopped: _state = CoreState::Idle; break; } updateSubStyles(); if (old != _state) emit stateChanged(); } PlayerEngine::CoreState PlayerEngine::state() { auto old = _state; switch (_current->state()) { case Backend::PlayState::Playing: _state = CoreState::Playing; break; case Backend::PlayState::Paused: _state = CoreState::Paused; break; case Backend::PlayState::Stopped: _state = CoreState::Idle; break; } if (old != _state) { qWarning() << "###### state mismatch" << old << _state; emit stateChanged(); } return _state; } const PlayingMovieInfo& PlayerEngine::playingMovieInfo() { static PlayingMovieInfo empty; if (!_current) return empty; return _current->playingMovieInfo(); } int PlayerEngine::aid() { if (state() == CoreState::Idle) { return 0; } if (!_current) return 0; return _current->aid(); } int PlayerEngine::sid() { if (state() == CoreState::Idle) { return 0; } if (!_current) return 0; return _current->sid(); } void PlayerEngine::onSubtitlesDownloaded(const QUrl& url, const QList& filenames, OnlineSubtitle::FailReason reason) { if (state() == CoreState::Idle) { return; } if (!_current) return; if (playlist().currentInfo().url != url) return; emit loadOnlineSubtitlesFinished(url, filenames.size() > 0 || reason == OnlineSubtitle::Duplicated); for (auto& filename: filenames) _current->loadSubtitle(filename); } bool PlayerEngine::loadSubtitle(const QFileInfo& fi) { if (state() == CoreState::Idle) { return true; } if (!_current) return true; const auto& pmf = _current->playingMovieInfo(); auto pif = playlist().currentInfo(); for (const auto& sub: pmf.subs) { if (sub["external"].toBool()) { auto path = sub["external-filename"].toString(); if (path == fi.canonicalFilePath()) { return true; } } } if (_current->loadSubtitle(fi)) { #ifndef _LIBDMR_ MovieConfiguration::get().append2ListUrl(pif.url, ConfigKnownKey::ExternalSubs, fi.canonicalFilePath()); #endif return true; } return false; } void PlayerEngine::loadOnlineSubtitle(const QUrl& url) { if (state() == CoreState::Idle) { return; } if (!_current) return; OnlineSubtitle::get().requestSubtitle(url); } void PlayerEngine::setPlaySpeed(double times) { if (!_current) return; _current->setPlaySpeed(times); } void PlayerEngine::setSubDelay(double secs) { if (!_current) return; _current->setSubDelay(secs + _current->subDelay()); } double PlayerEngine::subDelay() const { if (!_current) return 0.0; return _current->subDelay(); } QString PlayerEngine::subCodepage() { return _current->subCodepage(); } void PlayerEngine::setSubCodepage(const QString& cp) { if (!_current) return; _current->setSubCodepage(cp); emit subCodepageChanged(); } void PlayerEngine::addSubSearchPath(const QString& path) { if (!_current) return; _current->addSubSearchPath(path); } void PlayerEngine::updateSubStyle(const QString& font, int sz) { if (!_current) return; _current->updateSubStyle(font, sz); } void PlayerEngine::selectSubtitle(int id) { if (!_current) return; if (state() != CoreState::Idle) { const auto& pmf = _current->playingMovieInfo(); if (id >= pmf.subs.size()) return; auto sid = pmf.subs[id]["id"].toInt(); _current->selectSubtitle(sid); } } bool PlayerEngine::isSubVisible() { if (state() == CoreState::Idle) { return false; } if (!_current) return false; return _current->isSubVisible(); } void PlayerEngine::toggleSubtitle() { if (!_current) return; _current->toggleSubtitle(); } void PlayerEngine::selectTrack(int id) { if (!_current) return; _current->selectTrack(id); } void PlayerEngine::volumeUp() { if (!_current) return; _current->volumeUp(); } void PlayerEngine::changeVolume(int val) { if (!_current) return; _current->changeVolume(val); } void PlayerEngine::volumeDown() { if (!_current) return; _current->volumeDown(); } int PlayerEngine::volume() const { if (!_current) return 100; return _current->volume(); } bool PlayerEngine::muted() const { if (!_current) return false; return _current->muted(); } void PlayerEngine::toggleMute() { if (!_current) return; _current->toggleMute(); } void PlayerEngine::savePreviousMovieState() { savePlaybackPosition(); } //FIXME: TODO: update _current according to file void PlayerEngine::requestPlay(int id) { if (!_current) return; if (id >= _playlist->count()) return; const auto& item = _playlist->items()[id]; _current->setPlayFile(item.url); DRecentData data; data.appName = "Deepin Movie"; data.appExec = "deepin-movie"; DRecentManager::addItem(item.url.toLocalFile(), data); if (_current->isPlayable()) { _current->play(); } else { // TODO: delete and try next backend? } } void PlayerEngine::savePlaybackPosition() { if (!_current) return; _current->savePlaybackPosition(); } void PlayerEngine::nextFrame() { if (!_current) return; _current->nextFrame(); } void PlayerEngine::previousFrame() { if (!_current) return; _current->previousFrame(); } void PlayerEngine::play() { if (!_current || !_playlist->count()) return; if (state() == CoreState::Paused && getBackendProperty("keep-open").toBool() && getBackendProperty("eof-reached").toBool()) { stop(); next(); } else if (state() == CoreState::Idle) { next(); } } void PlayerEngine::prev() { if (_playingRequest) return; _playingRequest = true; savePreviousMovieState(); _playlist->playPrev(true); _playingRequest = false; } void PlayerEngine::next() { if (_playingRequest) return; _playingRequest = true; savePreviousMovieState(); _playlist->playNext(true); _playingRequest = false; } void PlayerEngine::onPlaylistAsyncAppendFinished(const QList& pil) { if (_pendingPlayReq.isValid()) { auto id = _playlist->indexOf(_pendingPlayReq); if (pil.size() && _pendingPlayReq.scheme() == "playlist") { id = _playlist->indexOf(pil[0].url); } if (id >= 0) { _playlist->changeCurrent(id); _pendingPlayReq = QUrl(); } // else, wait for another signal } } void PlayerEngine::playByName(const QUrl& url) { savePreviousMovieState(); auto id = _playlist->indexOf(url); if (id >= 0) { _playlist->changeCurrent(id); } else { _pendingPlayReq = url; } } void PlayerEngine::playSelected(int id) { savePreviousMovieState(); _playlist->changeCurrent(id); } void PlayerEngine::clearPlaylist() { _playlist->clear(); } void PlayerEngine::pauseResume() { if (!_current) return; if (_state == CoreState::Idle) return; _current->pauseResume(); } void PlayerEngine::stop() { if (!_current) return; _current->stop(); } bool PlayerEngine::paused() { return _state == CoreState::Paused; } QImage PlayerEngine::takeScreenshot() { return _current->takeScreenshot(); } void PlayerEngine::burstScreenshot() { _current->burstScreenshot(); } void PlayerEngine::stopBurstScreenshot() { _current->stopBurstScreenshot(); } void PlayerEngine::seekForward(int secs) { if (state() == CoreState::Idle) return; _current->seekForward(secs); } void PlayerEngine::seekBackward(int secs) { if (state() == CoreState::Idle) return; _current->seekBackward(secs); } void PlayerEngine::seekAbsolute(int pos) { if (state() == CoreState::Idle) return; _current->seekAbsolute(pos); } void PlayerEngine::setDVDDevice(const QString& path) { if (!_current) { return; } _current->setDVDDevice(path); } bool PlayerEngine::addPlayFile(const QUrl& url) { if (isPlayableFile(url)) { if (url.isLocalFile()) _playlist->appendAsync({url}); else _playlist->append(url); return true; } return false; } QList PlayerEngine::collectPlayDir(const QDir& dir) { QList urls; QDirIterator di(dir, QDirIterator::Subdirectories); while (di.hasNext()) { di.next(); if (di.fileInfo().isFile() && isPlayableFile(di.fileName())) { urls.append(QUrl::fromLocalFile(di.filePath())); } } return urls; } QList PlayerEngine::addPlayDir(const QDir& dir) { auto valids = collectPlayDir(dir); _playlist->appendAsync(valids); return valids; } QList PlayerEngine::addPlayFiles(const QList& urls) { QList valids = collectPlayFiles(urls); _playlist->appendAsync(valids); return valids; } QList PlayerEngine::collectPlayFiles(const QList& urls) { qDebug() << urls; //NOTE: take care of loop, we don't recursive, it seems safe now QList valids; for (const auto& url: urls) { if (url.isLocalFile()) { QFileInfo fi(url.toLocalFile()); if (!fi.exists()) { qDebug() << url << "don't exist"; continue; } if (fi.isDir()) { auto subs = collectPlayDir(fi.absoluteFilePath()); valids += subs; valids += url; continue; } if (!url.isValid() || !isPlayableFile(url)) { qDebug() << url << "not valid or playable"; continue; } valids.append(url); } } return valids; } qint64 PlayerEngine::duration() const { if (!_current) return 0; return _current->duration(); } QSize PlayerEngine::videoSize() const { if (!_current) return {0, 0}; return _current->videoSize(); } qint64 PlayerEngine::elapsed() const { if (!_current) return 0; return _current->elapsed(); } void PlayerEngine::setVideoAspect(double r) { if (_current) _current->setVideoAspect(r); } double PlayerEngine::videoAspect() const { if (!_current) return 0.0; return _current->videoAspect(); } int PlayerEngine::videoRotation() const { if (!_current) return 0; return _current->videoRotation(); } void PlayerEngine::setVideoRotation(int degree) { if (_current) _current->setVideoRotation(degree); } void PlayerEngine::changeSoundMode(Backend::SoundMode sm) { if (_current) _current->changeSoundMode(sm); } void PlayerEngine::resizeEvent(QResizeEvent* re) { bool rounded = !window()->isFullScreen() && !window()->isMaximized(); #if !defined(USE_DXCB) && !defined(_LIBDMR_) if (rounded) { QPixmap shape(size()); shape.fill(Qt::transparent); QPainter p(&shape); QPainterPath pp; pp.addRoundedRect(rect(), RADIUS, RADIUS); p.fillPath(pp, QBrush(Qt::white)); p.end(); setMask(shape.mask()); } else { clearMask(); } #endif } void PlayerEngine::setBackendProperty(const QString& name, const QVariant& val) { if (_current) { _current->setProperty(name, val); } } QVariant PlayerEngine::getBackendProperty(const QString& name) { if (_current) { return _current->getProperty(name); } return QVariant(); } } // end of namespace dmr deepin-movie-reborn-5.0.0/src/libdmr/player_engine.h000066400000000000000000000163611351125414100224200ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_PLAYER_ENINE_H #define _DMR_PLAYER_ENINE_H #include #include #include #include namespace dmr { class PlaylistModel; using SubtitleInfo = QMap; using AudioInfo = QMap; struct PlayingMovieInfo { QList subs; QList audios; }; class PlayerEngine: public QWidget { Q_OBJECT Q_PROPERTY(qint64 duration READ duration) Q_PROPERTY(qint64 elapsed READ elapsed NOTIFY elapsedChanged) Q_PROPERTY(QSize videoSize READ videoSize NOTIFY videoSizeChanged) Q_PROPERTY(bool paused READ paused) Q_PROPERTY(CoreState state READ state NOTIFY stateChanged) public: enum CoreState { Idle, Playing, Paused, }; Q_ENUM(CoreState) // filetypes supported by mpv: https://github.com/mpv-player/mpv/blob/master/player/external_files.c const QStringList audio_filetypes {"*.mp3","*.ogg","*.wav","*.wma","*.m4a","*.aac","*.ac3","*.ape","*.flac","*.ra","*.mka","*.dts","*.opus"}; const QStringList video_filetypes { "*.3g2","*.3ga","*.3gp","*.3gp2","*.3gpp","*.amv","*.asf","*.asx","*.avf","*.avi","*.bdm","*.bdmv","*.bik","*.clpi", "*.cpi","*.dat","*.divx","*.drc","*.dv","*.dvr-ms","*.f4v","*.flv","*.gvi","*.gxf","*.hdmov","*.hlv","*.iso","*.letv", "*.lrv","*.m1v","*.m2p","*.m2t","*.m2ts","*.m2v","*.m3u","*.m3u8","*.m4v","*.mkv","*.moov", "*.mov","*.mov","*.mp2","*.mp2v","*.mp4","*.mp4v","*.mpe","*.mpeg","*.mpeg1","*.mpeg2","*.mpeg4","*.mpg","*.mpl","*.mpls","*.mpv","*.mpv2","*.mqv", "*.mts","*.mts","*.mtv","*.mxf","*.mxg","*.nsv","*.nuv","*.ogg","*.ogm","*.ogv","*.ogx","*.ps","*.qt","*.qtvr","*.ram","*.rec", "*.rm","*.rm","*.rmj","*.rmm","*.rms","*.rmvb","*.rmx","*.rp","*.rpl","*.rv","*.rvx","*.thp","*.tod","*.tp","*.trp","*.ts","*.tts","*.txd","*.vcd", "*.vdr","*.vob","*.vp8","*.vro","*.webm","*.wm","*.wmv","*.wtv","*.xesc" ,"*.xspf" }; const QStringList subtitle_suffixs {"ass", "sub", "srt", "aqt", "jss", "gsub", "ssf", "ssa", "smi", "usf", "idx"}; /* backend like mpv will asynchronously report end of playback. * there are situations when we need to see the end-event before * proceed (e.g playlist next) */ void waitLastEnd(); friend class PlaylistModel; PlayerEngine(QWidget *parent = 0); virtual ~PlayerEngine(); // only the last dvd device set void setDVDDevice(const QString& path); bool addPlayFile(const QUrl& url); QList addPlayDir(const QDir& dir); // return collected valid urls //returned list contains only accepted valid items QList addPlayFiles(const QList& urls); bool isPlayableFile(const QUrl& url); bool isPlayableFile(const QString& name); // only supports (+/-) 0, 90, 180, 270 int videoRotation() const; void setVideoRotation(int degree); void setVideoAspect(double r); double videoAspect() const; qint64 duration() const; qint64 elapsed() const; QSize videoSize() const; const struct MovieInfo& movieInfo(); bool paused(); CoreState state(); const PlayingMovieInfo& playingMovieInfo(); void setPlaySpeed(double times); void loadOnlineSubtitle(const QUrl& url); bool loadSubtitle(const QFileInfo& fi); void toggleSubtitle(); bool isSubVisible(); void selectSubtitle(int id); // id into PlayingMovieInfo.subs int sid(); void setSubDelay(double secs); double subDelay() const; void updateSubStyle(const QString& font, int sz); void setSubCodepage(const QString& cp); QString subCodepage(); void addSubSearchPath(const QString& path); void selectTrack(int id); // id into PlayingMovieInfo.audios int aid(); void changeSoundMode(Backend::SoundMode sm); int volume() const; bool muted() const; PlaylistModel& playlist() const { return *_playlist; } QImage takeScreenshot(); void burstScreenshot(); //initial the start of burst screenshotting void stopBurstScreenshot(); void savePlaybackPosition(); void nextFrame(); void previousFrame(); // use with caution void setBackendProperty(const QString&, const QVariant&); QVariant getBackendProperty(const QString&); signals: void tracksChanged(); void elapsedChanged(); void videoSizeChanged(); void stateChanged(); void fileLoaded(); void muteChanged(); void volumeChanged(); void sidChanged(); void aidChanged(); void subCodepageChanged(); void loadOnlineSubtitlesFinished(const QUrl& url, bool success); //emit during burst screenshotting void notifyScreenshot(const QImage& frame, qint64 time); void playlistChanged(); public slots: void play(); void pauseResume(); void stop(); void prev(); void next(); void playSelected(int id); // id as in playlist indexes void playByName(const QUrl& url); void clearPlaylist(); void seekForward(int secs); void seekBackward(int secs); void seekAbsolute(int pos); void volumeUp(); void volumeDown(); void changeVolume(int val); void toggleMute(); protected slots: void onBackendStateChanged(); void requestPlay(int id); void updateSubStyles(); void onSubtitlesDownloaded(const QUrl& url, const QList& filenames, OnlineSubtitle::FailReason); void onPlaylistAsyncAppendFinished(const QList&); protected: PlaylistModel *_playlist {nullptr}; CoreState _state { CoreState::Idle }; Backend *_current {nullptr}; QUrl _pendingPlayReq; bool _playingRequest {false}; QList collectPlayFiles(const QList& urls); QList collectPlayDir(const QDir& dir); void resizeEvent(QResizeEvent* re) override; void savePreviousMovieState(); }; } #endif /* ifndef _DMR_PLAYER_ENINE_H */ deepin-movie-reborn-5.0.0/src/libdmr/player_widget.cpp000066400000000000000000000040031351125414100227570ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "player_widget.h" #include namespace dmr { PlayerWidget::PlayerWidget(QWidget *parent) { _engine = new PlayerEngine(this); auto *l = new QVBoxLayout; l->setContentsMargins(0, 0, 0, 0); l->addWidget(_engine); setLayout(l); } PlayerWidget::~PlayerWidget() { } PlayerEngine& PlayerWidget::engine() { return *_engine; } void PlayerWidget::play(const QUrl& url) { if (!url.isValid()) return; if (!_engine->addPlayFile(url)) { return; } _engine->playByName(url); } } deepin-movie-reborn-5.0.0/src/libdmr/player_widget.h000066400000000000000000000036001351125414100224260ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #pragma once #include namespace dmr { class PlayerEngine; class PlayerWidget: public QWidget { Q_OBJECT public: PlayerWidget(QWidget *parent = 0); virtual ~PlayerWidget(); /** * engine is instantiated in constructor, and all interaction comes from * engine */ PlayerEngine& engine(); void play(const QUrl& url); protected: PlayerEngine *_engine {nullptr}; }; } deepin-movie-reborn-5.0.0/src/libdmr/playlist_model.cpp000066400000000000000000000737571351125414100231670ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "playlist_model.h" #include "player_engine.h" #include "utils.h" #ifndef _LIBDMR_ #include "dmr_settings.h" #endif #include "dvd_utils.h" #include extern "C" { #include #include #include } #include static int open_codec_context(int *stream_idx, AVCodecContext **dec_ctx, AVFormatContext *fmt_ctx, enum AVMediaType type) { int ret, stream_index; AVStream *st; AVCodec *dec = NULL; AVDictionary *opts = NULL; ret = av_find_best_stream(fmt_ctx, type, -1, -1, NULL, 0); if (ret < 0) { qWarning() << "Could not find " << av_get_media_type_string(type) << " stream in input file"; return ret; } stream_index = ret; st = fmt_ctx->streams[stream_index]; #if LIBAVFORMAT_VERSION_MAJOR >= 57 && LIBAVFORMAT_VERSION_MINOR <= 25 *dec_ctx = st->codec; dec = avcodec_find_decoder((*dec_ctx)->codec_id); #else /* find decoder for the stream */ dec = avcodec_find_decoder(st->codecpar->codec_id); if (!dec) { fprintf(stderr, "Failed to find %s codec\n", av_get_media_type_string(type)); return AVERROR(EINVAL); } /* Allocate a codec context for the decoder */ *dec_ctx = avcodec_alloc_context3(dec); if (!*dec_ctx) { fprintf(stderr, "Failed to allocate the %s codec context\n", av_get_media_type_string(type)); return AVERROR(ENOMEM); } /* Copy codec parameters from input stream to output codec context */ if ((ret = avcodec_parameters_to_context(*dec_ctx, st->codecpar)) < 0) { fprintf(stderr, "Failed to copy %s codec parameters to decoder context\n", av_get_media_type_string(type)); return ret; } #endif *stream_idx = stream_index; return 0; } namespace dmr { QDebug operator<<(QDebug debug, const struct MovieInfo& mi) { debug << "MovieInfo{" << mi.valid << mi.title << mi.fileType << mi.resolution << mi.filePath << mi.creation << mi.raw_rotate << mi.fileSize << mi.duration << mi.width << mi.height << "}"; return debug; } QDataStream& operator<< (QDataStream& st, const MovieInfo& mi) { st << mi.valid; st << mi.title; st << mi.fileType; st << mi.resolution; st << mi.filePath; st << mi.creation; st << mi.raw_rotate; st << mi.fileSize; st << mi.duration; st << mi.width; st << mi.height; return st; } QDataStream& operator>> (QDataStream& st, MovieInfo& mi) { st >> mi.valid; st >> mi.title; st >> mi.fileType; st >> mi.resolution; st >> mi.filePath; st >> mi.creation; st >> mi.raw_rotate; st >> mi.fileSize; st >> mi.duration; st >> mi.width; st >> mi.height; return st; } static class PersistentManager* _persistentManager = nullptr; static QString hashUrl(const QUrl& url) { return QString(QCryptographicHash::hash(url.toEncoded(), QCryptographicHash::Sha256).toHex()); } //TODO: clean cache periodically class PersistentManager: public QObject { Q_OBJECT public: static PersistentManager& get() { if (!_persistentManager) { _persistentManager = new PersistentManager; } return *_persistentManager; } struct CacheInfo { struct MovieInfo mi; QPixmap thumb; bool mi_valid {false}; bool thumb_valid {false}; }; CacheInfo loadFromCache(const QUrl& url) { auto h = hashUrl(url); CacheInfo ci; { auto filename = QString("%1/%2").arg(_cacheInfoPath).arg(h); QFile f(filename); if (!f.exists()) return ci; if (f.open(QIODevice::ReadOnly)) { QDataStream ds(&f); ds >> ci.mi; ci.mi_valid = ci.mi.valid; } else { qWarning() << f.errorString(); } } if (ci.mi_valid) { auto filename = QString("%1/%2").arg(_pixmapCachePath).arg(h); QFile f(filename); if (!f.exists()) return ci; if (f.open(QIODevice::ReadOnly)) { QDataStream ds(&f); ds >> ci.thumb; ci.thumb.setDevicePixelRatio(qApp->devicePixelRatio()); ci.thumb_valid = !ci.thumb.isNull(); } else { qWarning() << f.errorString(); } } return ci; } void save(const PlayItemInfo& pif) { auto h = hashUrl(pif.url); bool mi_saved = false; { auto filename = QString("%1/%2").arg(_cacheInfoPath).arg(h); QFile f(filename); if (f.open(QIODevice::WriteOnly)) { QDataStream ds(&f); ds << pif.mi; mi_saved = true; qDebug() << "cache" << pif.url << "->" << h; } else { qWarning() << f.errorString(); } } if (mi_saved) { auto filename = QString("%1/%2").arg(_pixmapCachePath).arg(h); QFile f(filename); if (f.open(QIODevice::WriteOnly)) { QDataStream ds(&f); ds << pif.thumbnail; } else { qWarning() << f.errorString(); } } } bool cacheExists(const QUrl& url) { auto h = hashUrl(url); auto filename = QString("%1/%2").arg(_cacheInfoPath).arg(h); return QFile::exists(filename); } private: PersistentManager() { auto tmpl = QString("%1/%2/%3/%4") .arg(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)) .arg(qApp->organizationName()) .arg(qApp->applicationName()); { _cacheInfoPath = tmpl.arg("cacheinfo"); QDir d; d.mkpath(_cacheInfoPath); } { _pixmapCachePath = tmpl.arg("thumbs"); QDir d; d.mkpath(_pixmapCachePath); } } QString _pixmapCachePath; QString _cacheInfoPath; }; struct MovieInfo MovieInfo::parseFromFile(const QFileInfo& fi, bool *ok) { struct MovieInfo mi; mi.valid = false; AVFormatContext *av_ctx = NULL; int stream_id = -1; AVCodecContext *dec_ctx = NULL; if (!fi.exists()) { if (ok) *ok = false; return mi; } auto ret = avformat_open_input(&av_ctx, fi.filePath().toUtf8().constData(), NULL, NULL); if (ret < 0) { qWarning() << "avformat: could not open input"; if (ok) *ok = false; return mi; } if (avformat_find_stream_info(av_ctx, NULL) < 0) { qWarning() << "av_find_stream_info failed"; if (ok) *ok = false; return mi; } if (av_ctx->nb_streams == 0) { if (ok) *ok = false; return mi; } if (open_codec_context(&stream_id, &dec_ctx, av_ctx, AVMEDIA_TYPE_VIDEO) < 0) { if (ok) *ok = false; return mi; } av_dump_format(av_ctx, 0, fi.fileName().toUtf8().constData(), 0); mi.width = dec_ctx->width; mi.height = dec_ctx->height; auto duration = av_ctx->duration == AV_NOPTS_VALUE ? 0 : av_ctx->duration; duration = duration + (duration <= INT64_MAX - 5000 ? 5000 : 0); mi.duration = duration / AV_TIME_BASE; mi.resolution = QString("%1x%2").arg(mi.width).arg(mi.height); mi.title = fi.fileName(); //FIXME this mi.filePath = fi.canonicalFilePath(); mi.creation = fi.created().toString(); mi.fileSize = fi.size(); mi.fileType = fi.suffix(); AVDictionaryEntry *tag = NULL; while ((tag = av_dict_get(av_ctx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)) != NULL) { if (tag->key && strcmp(tag->key, "creation_time") == 0) { auto dt = QDateTime::fromString(tag->value, Qt::ISODate); mi.creation = dt.toString(); qDebug() << __func__ << dt.toString(); break; } qDebug() << "tag:" << tag->key << tag->value; } tag = NULL; AVStream *st = av_ctx->streams[stream_id]; while ((tag = av_dict_get(st->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)) != NULL) { if (tag->key && strcmp(tag->key, "rotate") == 0) { mi.raw_rotate = QString(tag->value).toInt(); auto vr = (mi.raw_rotate + 360) % 360; if (vr == 90 || vr == 270) { auto tmp = mi.height; mi.height = mi.width; mi.width = tmp; } break; } qDebug() << "tag:" << tag->key << tag->value; } avformat_close_input(&av_ctx); mi.valid = true; if (ok) *ok = true; return mi; } bool PlayItemInfo::refresh() { if (url.isLocalFile()) { //FIXME: it seems that info.exists always gets refreshed auto o = this->info.exists(); auto sz = this->info.size(); this->info.refresh(); this->valid = this->info.exists(); return (o != this->info.exists()) || sz != this->info.size(); } return false; } PlaylistModel::PlaylistModel(PlayerEngine *e) :_engine(e) { _thumbnailer.setThumbnailSize(400 * qApp->devicePixelRatio()); av_register_all(); _playlistFile = QString("%1/%2/%3/playlist") .arg(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)) .arg(qApp->organizationName()) .arg(qApp->applicationName()); connect(e, &PlayerEngine::stateChanged, [=]() { qDebug() << "model" << "_userRequestingItem" << _userRequestingItem << "state" << e->state(); switch (e->state()) { case PlayerEngine::Playing: { auto& pif = currentInfo(); if (!pif.url.isLocalFile() && !pif.loaded) { pif.mi.width = e->videoSize().width(); pif.mi.height = e->videoSize().height(); pif.mi.duration = e->duration(); pif.loaded = true; emit itemInfoUpdated(_current); } break; } case PlayerEngine::Paused: break; case PlayerEngine::Idle: if (!_userRequestingItem) { stop(); playNext(false); } break; } }); _jobWatcher = new QFutureWatcher(); connect(_jobWatcher, &QFutureWatcher::finished, this, &PlaylistModel::onAsyncAppendFinished); stop(); loadPlaylist(); } PlaylistModel::~PlaylistModel() { qDebug() << __func__; delete _jobWatcher; #ifndef _LIBDMR_ if (Settings::get().isSet(Settings::ClearWhenQuit)) { clearPlaylist(); } else { //persistently save current playlist savePlaylist(); } #endif } void PlaylistModel::clearPlaylist() { QSettings cfg(_playlistFile, QSettings::NativeFormat); cfg.beginGroup("playlist"); cfg.remove(""); cfg.endGroup(); } void PlaylistModel::savePlaylist() { QSettings cfg(_playlistFile, QSettings::NativeFormat); cfg.beginGroup("playlist"); cfg.remove(""); for (int i = 0; i < count(); ++i) { const auto& pif = _infos[i]; cfg.setValue(QString::number(i), pif.url); qDebug() << "save " << pif.url; } cfg.endGroup(); cfg.sync(); } void PlaylistModel::loadPlaylist() { QList urls; QSettings cfg(_playlistFile, QSettings::NativeFormat); cfg.beginGroup("playlist"); auto keys = cfg.childKeys(); for (int i = 0; i < keys.size(); ++i) { auto url = cfg.value(QString::number(i)).toUrl(); if (indexOf(url) >= 0) continue; if (url.isLocalFile()) { urls.append(url); } else { auto pif = calculatePlayInfo(url, QFileInfo()); _infos.append(pif); } } cfg.endGroup(); if (urls.size() == 0) { _firstLoad = false; reshuffle(); emit countChanged(); return; } QTimer::singleShot(0, [=]() { delayedAppendAsync(urls); }); } PlaylistModel::PlayMode PlaylistModel::playMode() const { return _playMode; } void PlaylistModel::setPlayMode(PlaylistModel::PlayMode pm) { if (_playMode != pm) { _playMode = pm; reshuffle(); emit playModeChanged(pm); } } void PlaylistModel::reshuffle() { if (_playMode != PlayMode::ShufflePlay || _infos.size() == 0) { return; } _shufflePlayed = 0; _playOrder.clear(); for (int i = 0, sz = _infos.size(); i < sz; ++i) { _playOrder.append(i); } std::random_device rd; std::mt19937 g(rd()); std::shuffle(_playOrder.begin(), _playOrder.end(), g); qDebug() << _playOrder; } void PlaylistModel::clear() { _infos.clear(); _engine->waitLastEnd(); _current = -1; _last = -1; emit emptied(); emit currentChanged(); emit countChanged(); } void PlaylistModel::remove(int pos) { if (pos < 0 || pos >= count()) return; _userRequestingItem = true; _infos.removeAt(pos); reshuffle(); _last = _current; if (_engine->state() != PlayerEngine::Idle) { if (_current == pos) { _last = _current; _current = -1; _engine->waitLastEnd(); } else if (pos < _current) { _current--; _last = _current; } } if (_last >= count()) _last = -1; emit itemRemoved(pos); if (_last != _current) emit currentChanged(); emit countChanged(); qDebug() << _last << _current; _userRequestingItem = false; } void PlaylistModel::stop() { _current = -1; emit currentChanged(); } void PlaylistModel::tryPlayCurrent(bool next) { auto& pif = _infos[_current]; if (pif.refresh()) { qDebug() << pif.url.fileName() << "changed"; } emit itemInfoUpdated(_current); if (pif.valid) { _engine->requestPlay(_current); emit currentChanged(); } else { _current = -1; emit currentChanged(); if (next) playNext(false); else playPrev(false); } } void PlaylistModel::playNext(bool fromUser) { if (count() == 0) return; qDebug() << "playmode" << _playMode << "fromUser" << fromUser << "last" << _last << "current" << _current; _userRequestingItem = fromUser; switch (_playMode) { case SinglePlay: if (fromUser) { if (_last + 1 >= count()) { _last = -1; } _engine->waitLastEnd(); _current = _last + 1; _last = _current; tryPlayCurrent(true); } break; case SingleLoop: if (fromUser) { if (_engine->state() == PlayerEngine::Idle) { _last = _last == -1 ? 0: _last; _current = _last; tryPlayCurrent(true); } else { if (_last + 1 >= count()) { _last = -1; } _engine->waitLastEnd(); _current = _last + 1; _last = _current; tryPlayCurrent(true); } } else { if (_engine->state() == PlayerEngine::Idle) { _last = _last < 0 ? 0 : _last; _current = _last; tryPlayCurrent(true); } else { // replay current tryPlayCurrent(true); } } break; case ShufflePlay: { if (_shufflePlayed >= _playOrder.size()) { _shufflePlayed = 0; reshuffle(); } _shufflePlayed++; qDebug() << "shuffle next " << _shufflePlayed-1; _engine->waitLastEnd(); _last = _current = _playOrder[_shufflePlayed-1]; tryPlayCurrent(true); break; } case OrderPlay: _last++; if (_last == count()) { if (fromUser) _last = 0; else { _last--; break; } } _engine->waitLastEnd(); _current = _last; tryPlayCurrent(true); break; case ListLoop: _last++; if (_last == count()) { _loopCount++; _last = 0; } _engine->waitLastEnd(); _current = _last; tryPlayCurrent(true); break; } _userRequestingItem = false; } void PlaylistModel::playPrev(bool fromUser) { if (count() == 0) return; qDebug() << "playmode" << _playMode << "fromUser" << fromUser << "last" << _last << "current" << _current; _userRequestingItem = fromUser; switch (_playMode) { case SinglePlay: if (fromUser) { if (_last - 1 < 0) { _last = count(); } _engine->waitLastEnd(); _current = _last - 1; _last = _current; tryPlayCurrent(false); } break; case SingleLoop: if (fromUser) { if (_engine->state() == PlayerEngine::Idle) { _last = _last == -1 ? 0: _last; _current = _last; tryPlayCurrent(false); } else { if (_last - 1 < 0) { _last = count(); } _engine->waitLastEnd(); _current = _last - 1; _last = _current; tryPlayCurrent(false); } } else { if (_engine->state() == PlayerEngine::Idle) { _last = _last < 0 ? 0 : _last; _current = _last; tryPlayCurrent(false); } else { // replay current tryPlayCurrent(false); } } break; case ShufflePlay: { // this must comes from user if (_shufflePlayed <= 1) { reshuffle(); _shufflePlayed = _playOrder.size(); } _shufflePlayed--; qDebug() << "shuffle prev " << _shufflePlayed-1; _engine->waitLastEnd(); _last = _current = _playOrder[_shufflePlayed-1]; tryPlayCurrent(false); break; } case OrderPlay: _last--; if (_last < 0) { _last = count()-1; } _engine->waitLastEnd(); _current = _last; tryPlayCurrent(false); break; case ListLoop: _last--; if (_last < 0) { _loopCount++; _last = count()-1; } _engine->waitLastEnd(); _current = _last; tryPlayCurrent(false); break; } _userRequestingItem = false; } static QDebug operator<<(QDebug s, const QFileInfoList& v) { std::for_each(v.begin(), v.end(), [&](const QFileInfo& fi) {s << fi.fileName();}); return s; } void PlaylistModel::appendSingle(const QUrl& url) { if (indexOf(url) >= 0) return; if (url.isLocalFile()) { QFileInfo fi(url.toLocalFile()); if (!fi.exists()) return; auto pif = calculatePlayInfo(url, fi); if (!pif.valid) return; _infos.append(pif); #ifndef _LIBDMR_ if (Settings::get().isSet(Settings::AutoSearchSimilar)) { auto fil = utils::FindSimilarFiles(fi); qDebug() << "auto search similar files" << fil; std::for_each(fil.begin(), fil.end(), [=](const QFileInfo& fi) { auto url = QUrl::fromLocalFile(fi.absoluteFilePath()); if (indexOf(url) < 0 && _engine->isPlayableFile(fi.fileName())) { auto pif = calculatePlayInfo(url, fi); if (pif.valid) _infos.append(pif); } }); } #endif } else { auto pif = calculatePlayInfo(url, QFileInfo()); _infos.append(pif); } } void PlaylistModel::collectionJob(const QList& urls) { for (const auto& url: urls) { if (!url.isValid() || indexOf(url) >= 0 || !url.isLocalFile() || _urlsInJob.contains(url.toLocalFile())) continue; QFileInfo fi(url.toLocalFile()); if (!_firstLoad && (!fi.exists() || !fi.isFile())) continue; _pendingJob.append(qMakePair(url, fi)); _urlsInJob.insert(url.toLocalFile()); qDebug() << "append " << url.fileName(); #ifndef _LIBDMR_ if (!_firstLoad && Settings::get().isSet(Settings::AutoSearchSimilar)) { auto fil = utils::FindSimilarFiles(fi); qDebug() << "auto search similar files" << fil; std::for_each(fil.begin(), fil.end(), [=](const QFileInfo& fi) { if (fi.isFile()) { auto url = QUrl::fromLocalFile(fi.absoluteFilePath()); if (!_urlsInJob.contains(url.toLocalFile()) && indexOf(url) < 0 && _engine->isPlayableFile(fi.fileName())) { _pendingJob.append(qMakePair(url, fi)); _urlsInJob.insert(url.toLocalFile()); } } }); } #endif } qDebug() << "input size" << urls.size() << "output size" << _urlsInJob.size() << "_pendingJob: " << _pendingJob.size(); } void PlaylistModel::appendAsync(const QList& urls) { QTimer::singleShot(10, [=]() { delayedAppendAsync(urls); }); } void PlaylistModel::delayedAppendAsync(const QList& urls) { if (_pendingJob.size() > 0) { //TODO: may be automatically schedule later qWarning() << "there is a pending append going on, enqueue"; _pendingAppendReq.enqueue(urls); return; } collectionJob(urls); if (!_pendingJob.size()) return; struct MapFunctor { PlaylistModel *_model = 0; using result_type = PlayItemInfo; MapFunctor(PlaylistModel* model): _model(model) {} struct PlayItemInfo operator()(const AppendJob& a) { qDebug() << "mapping " << a.first.fileName(); return _model->calculatePlayInfo(a.first, a.second); }; }; if (QThread::idealThreadCount() > 1) { auto future = QtConcurrent::mapped(_pendingJob, MapFunctor(this)); _jobWatcher->setFuture(future); } else { PlayItemInfoList pil; for (const auto& a: _pendingJob) { qDebug() << "sync mapping " << a.first.fileName(); pil.append(calculatePlayInfo(a.first, a.second)); } _pendingJob.clear(); _urlsInJob.clear(); handleAsyncAppendResults(pil); } } static QList& SortSimilarFiles(QList& fil) { //sort names by digits inside, take care of such a possible: //S01N04, S02N05, S01N12, S02N04, etc... struct { bool operator()(const PlayItemInfo& fi1, const PlayItemInfo& fi2) const { if (!fi1.valid) return true; if (!fi2.valid) return false; QString fileName1 = fi1.url.fileName(); QString fileName2 = fi2.url.fileName(); if (utils::IsNamesSimilar(fileName1, fileName2)) { return utils::CompareNames(fileName1, fileName2); } return fileName1.localeAwareCompare(fileName2) < 0; } } SortByDigits; std::sort(fil.begin(), fil.end(), SortByDigits); return fil; } void PlaylistModel::onAsyncAppendFinished() { qDebug() << __func__; auto f = _jobWatcher->future(); _pendingJob.clear(); _urlsInJob.clear(); auto fil = f.results(); handleAsyncAppendResults(fil); } void PlaylistModel::handleAsyncAppendResults(QList& fil) { qDebug() << __func__ << fil.size(); if (!_firstLoad) { //since _infos are modified only at the same thread, the lock is not necessary auto last = std::remove_if(fil.begin(), fil.end(), [](const PlayItemInfo& pif) { return !pif.mi.valid; }); fil.erase(last, fil.end()); } qDebug() << "collected items" << fil.count(); if (fil.size()) { if (!_firstLoad) _infos += SortSimilarFiles(fil); else _infos += fil; reshuffle(); _firstLoad = false; emit itemsAppended(); emit countChanged(); } _firstLoad = false; emit asyncAppendFinished(fil); QTimer::singleShot(0, [&]() { if (_pendingAppendReq.size()) { auto job = _pendingAppendReq.dequeue(); delayedAppendAsync(job); } }); } bool PlaylistModel::hasPendingAppends() { return _pendingAppendReq.size() > 0 || _pendingJob.size() > 0; } //TODO: what if loadfile failed void PlaylistModel::append(const QUrl& url) { if (!url.isValid()) return; appendSingle(url); reshuffle(); emit itemsAppended(); emit countChanged(); } void PlaylistModel::changeCurrent(int pos) { if (pos < 0 || pos >= count() || _current == pos) return; _userRequestingItem = true; _engine->waitLastEnd(); _current = pos; _last = _current; tryPlayCurrent(true); _userRequestingItem = false; } void PlaylistModel::switchPosition(int src, int target) { //Q_ASSERT_X(0, "playlist", "not implemented"); Q_ASSERT (src < _infos.size() && target < _infos.size()); _infos.move(src, target); int min = qMin(src, target); int max = qMax(src, target); if (_current >= min && _current <= max) { if (_current == src) { _current = target; _last = _current; } else { if (src < target) { _current--; _last = _current; } else if (src > target) { _current++; _last = _current; } } emit currentChanged(); } } PlayItemInfo& PlaylistModel::currentInfo() { //Q_ASSERT (_infos.size() > 0 && _current >= 0); Q_ASSERT (_infos.size() > 0); if (_current >= 0) return _infos[_current]; if (_last >= 0) return _infos[_last]; return _infos[0]; } const PlayItemInfo& PlaylistModel::currentInfo() const { Q_ASSERT (_infos.size() > 0 && _current >= 0); return _infos[_current]; } int PlaylistModel::count() const { return _infos.count(); } int PlaylistModel::current() const { return _current; } struct PlayItemInfo PlaylistModel::calculatePlayInfo(const QUrl& url, const QFileInfo& fi) { bool ok = false; struct MovieInfo mi; auto ci = PersistentManager::get().loadFromCache(url); if (ci.mi_valid) { mi = ci.mi; ok = true; qDebug() << "load cached MovieInfo" << mi; } else { mi = MovieInfo::parseFromFile(fi, &ok); if (url.scheme().startsWith("dvd")) { QString dev = url.path(); if (dev.isEmpty()) dev = "/dev/sr0"; mi.title = dmr::dvd::RetrieveDVDTitle(dev); if (mi.title.isEmpty()) { mi.title = "DVD"; } mi.valid = true; } else if (!url.isLocalFile()) { QString msg = url.fileName(); if (msg.isEmpty()) msg = url.path(); mi.title = msg; mi.valid = true; } else { mi.title = fi.fileName(); } } QPixmap pm; if (ci.thumb_valid) { pm = ci.thumb; qDebug() << "load cached thumb" << url; } else if (ok) { try { std::vector buf; _thumbnailer.generateThumbnail(fi.canonicalFilePath().toUtf8().toStdString(), ThumbnailerImageType::Png, buf); auto img = QImage::fromData(buf.data(), buf.size(), "png"); pm = QPixmap::fromImage(img); pm.setDevicePixelRatio(qApp->devicePixelRatio()); } catch (const std::logic_error&) { } } PlayItemInfo pif { fi.exists() || !url.isLocalFile(), ok, url, fi, pm, mi }; if (ok && url.isLocalFile() && (!ci.mi_valid || !ci.thumb_valid)) { PersistentManager::get().save(pif); } return pif; } int PlaylistModel::indexOf(const QUrl& url) { auto p = std::find_if(_infos.begin(), _infos.end(), [&](const PlayItemInfo& pif) { return pif.url == url; }); if (p == _infos.end()) return -1; return std::distance(_infos.begin(), p); } } #include "playlist_model.moc" deepin-movie-reborn-5.0.0/src/libdmr/playlist_model.h000066400000000000000000000130461351125414100226150ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_PLAYLIST_MODEL_H #define _DMR_PLAYLIST_MODEL_H #include #include #include #include "utils.h" namespace dmr { using namespace ffmpegthumbnailer; class PlayerEngine; struct MovieInfo { bool valid; QString title; QString fileType; QString resolution; QString filePath; QString creation; // rotation in metadata, this affects width/height int raw_rotate; qint64 fileSize; qint64 duration; int width, height; static struct MovieInfo parseFromFile(const QFileInfo& fi, bool *ok = nullptr); QString durationStr() const { return utils::Time2str(duration); } QString sizeStr() const { auto K = 1024; auto M = 1024 * K; auto G = 1024 * M; if (fileSize > G) { return QString(QT_TR_NOOP("%1G")).arg((double)fileSize / G, 0, 'f', 1); } else if (fileSize > M) { return QString(QT_TR_NOOP("%1M")).arg((double)fileSize / M, 0, 'f', 1); } else if (fileSize > K) { return QString(QT_TR_NOOP("%1K")).arg((double)fileSize / K, 0, 'f', 1); } return QString(QT_TR_NOOP("%1")).arg(fileSize); } }; struct PlayItemInfo { bool valid; bool loaded; // if url is network, this is false until playback started QUrl url; QFileInfo info; QPixmap thumbnail; struct MovieInfo mi; bool refresh(); }; using AppendJob = QPair; // async job using PlayItemInfoList = QList; using UrlList = QList; class PlaylistModel: public QObject { Q_OBJECT Q_PROPERTY(int count READ count NOTIFY countChanged) Q_PROPERTY(int current READ current WRITE changeCurrent NOTIFY currentChanged) public: friend class PlayerEngine; enum PlayMode { OrderPlay, ShufflePlay, SinglePlay, SingleLoop, ListLoop, }; void stop(); PlayMode playMode() const; void setPlayMode(PlayMode pm); PlaylistModel(PlayerEngine* engine); ~PlaylistModel(); void clear(); void remove(int pos); void append(const QUrl&); void appendAsync(const QList&); void collectionJob(const QList&); void playNext(bool fromUser); void playPrev(bool fromUser); int count() const; const QList& items() const { return _infos; } QList& items() { return _infos; } int current() const; const PlayItemInfo& currentInfo() const; PlayItemInfo& currentInfo(); int indexOf(const QUrl& url); void switchPosition(int p1, int p2); bool hasPendingAppends(); public slots: void changeCurrent(int); private slots: void onAsyncAppendFinished(); void delayedAppendAsync(const QList&); signals: void countChanged(); void currentChanged(); void itemRemoved(int); void itemsAppended(); void emptied(); void playModeChanged(PlayMode); void asyncAppendFinished(const QList&); void itemInfoUpdated(int id); private: // when app starts, and the first time to load playlist bool _firstLoad {true}; int _count {0}; int _current {-1}; int _last {-1}; PlayMode _playMode {PlayMode::OrderPlay}; QList _infos; QList _playOrder; // for shuffle mode int _shufflePlayed {0}; // count currently played items in shuffle mode int _loopCount {0}; // loop count QList _pendingJob; // async job QSet _urlsInJob; // url list QFutureWatcher *_jobWatcher {nullptr}; QQueue _pendingAppendReq; bool _userRequestingItem {false}; VideoThumbnailer _thumbnailer; PlayerEngine *_engine {nullptr}; QString _playlistFile; struct PlayItemInfo calculatePlayInfo(const QUrl&, const QFileInfo& fi); void reshuffle(); void savePlaylist(); void loadPlaylist(); void clearPlaylist(); void appendSingle(const QUrl&); void tryPlayCurrent(bool next); void handleAsyncAppendResults(QList& pil); }; } #endif /* ifndef _DMR_PLAYLIST_MODEL_H */ deepin-movie-reborn-5.0.0/src/libdmr/utils.cpp000066400000000000000000000303521351125414100212660ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "utils.h" #include #include namespace dmr { namespace utils { using namespace std; void ShowInFileManager(const QString &path) { if (path.isEmpty() || !QFile::exists(path)) { return; } QUrl url = QUrl::fromLocalFile(QFileInfo(path).dir().absolutePath()); QUrlQuery query; query.addQueryItem("selectUrl", QUrl::fromLocalFile(path).toString()); url.setQuery(query); qDebug() << __func__ << url.toString(); // Try dde-file-manager QProcess *fp = new QProcess(); QObject::connect(fp, SIGNAL(finished(int)), fp, SLOT(deleteLater())); fp->start("dde-file-manager", QStringList(url.toString())); fp->waitForStarted(3000); if (fp->error() == QProcess::FailedToStart) { // Start dde-file-manager failed, try nautilus QDBusInterface iface("org.freedesktop.FileManager1", "/org/freedesktop/FileManager1", "org.freedesktop.FileManager1", QDBusConnection::sessionBus()); if (iface.isValid()) { // Convert filepath to URI first. const QStringList uris = { QUrl::fromLocalFile(path).toString() }; qDebug() << "freedesktop.FileManager"; // StartupId is empty here. QDBusPendingCall call = iface.asyncCall("ShowItems", uris, ""); Q_UNUSED(call); } // Try to launch other file manager if nautilus is invalid else { qDebug() << "desktopService::openUrl"; QDesktopServices::openUrl(QUrl::fromLocalFile(QFileInfo(path).dir().absolutePath())); } fp->deleteLater(); } } static int min(int v1, int v2, int v3) { return std::min(v1, std::min(v2, v3)); } static int stringDistance(const QString& s1, const QString& s2) { int n = s1.size(), m = s2.size(); if (!n || !m) return max(n, m); vector dp(n+1); for (int i = 0; i < n+1; i++) dp[i] = i; int pred = 0; int curr = 0; for (int i = 0; i < m; i++) { dp[0] = i; pred = i+1; for (int j = 0; j < n; j++) { if (s1[j] == s2[i]) { curr = dp[j]; } else { curr = min(dp[j], dp[j+1], pred) + 1; } dp[j] = pred; pred = curr; } dp[n] = pred; } return curr; } bool IsNamesSimilar(const QString& s1, const QString& s2) { auto dist = stringDistance(s1, s2); return (dist >= 0 && dist <= 4); //TODO: check ext. } QFileInfoList FindSimilarFiles(const QFileInfo& fi) { QFileInfoList fil; QDirIterator it(fi.absolutePath()); while (it.hasNext()) { it.next(); if (!it.fileInfo().isFile()) { continue; } if (IsNamesSimilar(fi.fileName(), it.fileInfo().fileName())) { fil.append(it.fileInfo()); } } //struct { //bool operator()(const QFileInfo& fi1, const QFileInfo& fi2) const { //return CompareNames(fi1.fileName(), fi2.fileName()); //} //} SortByDigits; //std::sort(fil.begin(), fil.end(), SortByDigits); return fil; } bool CompareNames(const QString& fileName1, const QString& fileName2) { static QRegExp rd("\\d+"); int pos = 0; while ((pos = rd.indexIn(fileName1, pos)) != -1) { auto inc = rd.matchedLength(); auto id1 = fileName1.midRef(pos, inc); auto pos2 = rd.indexIn(fileName2, pos); if (pos == pos2) { auto id2 = fileName2.midRef(pos, rd.matchedLength()); //qDebug() << "id compare " << id1 << id2; if (id1 != id2) { bool ok1, ok2; bool v = id1.toInt(&ok1) < id2.toInt(&ok2); if (ok1 && ok2) return v; return id1.localeAwareCompare(id2) < 0; } } pos += inc; } return fileName1.localeAwareCompare(fileName2) < 0; } // hash the whole file takes amount of time, so just pick some areas to be hashed QString FastFileHash(const QFileInfo& fi) { auto sz = fi.size(); QList offsets = { 4096, sz - 8192 }; QFile f(fi.absoluteFilePath()); if (!f.open(QFile::ReadOnly)) { return QString(); } if (fi.size() < 8192) { auto bytes = f.readAll(); return QString(QCryptographicHash::hash(bytes, QCryptographicHash::Md5).toHex()); } QByteArray bytes; std::for_each(offsets.begin(), offsets.end(), [&bytes, &f](qint64 v) { f.seek(v); bytes += f.read(4096); }); return QString(QCryptographicHash::hash(bytes, QCryptographicHash::Md5).toHex()); } // hash the entire file (hope file is small) QString FullFileHash(const QFileInfo& fi) { auto sz = fi.size(); QFile f(fi.absoluteFilePath()); if (!f.open(QFile::ReadOnly)) { return QString(); } auto bytes = f.readAll(); return QString(QCryptographicHash::hash(bytes, QCryptographicHash::Md5).toHex()); } QPixmap MakeRoundedPixmap(QPixmap pm, qreal rx, qreal ry, int rotation) { auto dpr = pm.devicePixelRatio(); QPixmap dest(pm.size()); dest.setDevicePixelRatio(dpr); auto scaled_rect = QRectF({0, 0}, QSizeF(dest.size() / dpr)); dest.fill(Qt::transparent); QPainter p(&dest); p.setRenderHints(QPainter::Antialiasing|QPainter::SmoothPixmapTransform); QPainterPath path; path.addRoundedRect(QRect(QPoint(), scaled_rect.size().toSize()), rx, ry); p.setClipPath(path); QTransform transform; transform.translate(scaled_rect.width()/2, scaled_rect.height()/2); transform.rotate(rotation); transform.translate(-scaled_rect.width()/2, -scaled_rect.height()/2); p.setTransform(transform); p.drawPixmap(scaled_rect.toRect(), pm); return dest; } QPixmap MakeRoundedPixmap(QSize sz, QPixmap pm, qreal rx, qreal ry, qint64 time) { auto dpr = pm.devicePixelRatio(); QPixmap dest(sz); dest.setDevicePixelRatio(dpr); dest.fill(Qt::transparent); auto scaled_rect = QRectF({0, 0}, QSizeF(dest.size() / dpr)); QPainter p(&dest); p.setRenderHints(QPainter::Antialiasing|QPainter::SmoothPixmapTransform); p.setPen(QColor(0, 0, 0, 255 / 10)); p.drawRoundedRect(scaled_rect, rx, ry); QPainterPath path; auto r = scaled_rect.marginsRemoved({1, 1, 1, 1}); path.addRoundedRect(r, rx, ry); p.setClipPath(path); p.drawPixmap(1, 1, pm); p.setCompositionMode(QPainter::CompositionMode_SourceOver); QFont ft; ft.setPixelSize(12); ft.setWeight(QFont::Medium); p.setFont(ft); auto tm_str = QTime(0, 0, 0).addSecs(time).toString("hh:mm:ss"); QRect bounding = QFontMetrics(ft).boundingRect(tm_str); bounding.moveTopLeft({((int)(dest.width() / dpr)) - 5 - bounding.width(), ((int)(dest.height() / dpr)) - 5 - bounding.height()}); { QPainterPath pp; pp.addText(bounding.bottomLeft() + QPoint{0, 1}, ft, tm_str); QPen pen(QColor(0, 0, 0, 50)); pen.setWidth(2); p.setBrush(QColor(0, 0, 0, 50)); p.setPen(pen); p.drawPath(pp); } { QPainterPath pp; pp.addText(bounding.bottomLeft(), ft, tm_str); p.fillPath(pp, QColor(Qt::white)); } return dest; } uint32_t InhibitStandby() { QDBusInterface iface("org.freedesktop.ScreenSaver", "/org/freedesktop/ScreenSaver", "org.freedesktop.ScreenSaver"); QDBusReply reply = iface.call("Inhibit", "deepin-movie", "playing in fullscreen"); if (reply.isValid()) { return reply.value(); } qDebug() << reply.error().message(); return 0; } void UnInhibitStandby(uint32_t cookie) { QDBusInterface iface("org.freedesktop.ScreenSaver", "/org/freedesktop/ScreenSaver", "org.freedesktop.ScreenSaver"); iface.call("UnInhibit", cookie); } uint32_t InhibitPower() { QDBusInterface iface("org.freedesktop.PowerManagement", "/org/freedesktop/PowerManagement", "org.freedesktop.PowerManagement"); QDBusReply reply = iface.call("Inhibit", "deepin-movie", "playing in fullscreen"); if (reply.isValid()) { return reply.value(); } qDebug() << reply.error().message(); return 0; } void UnInhibitPower(uint32_t cookie) { QDBusInterface iface("org.freedesktop.PowerManagement", "/org/freedesktop/PowerManagement", "org.freedesktop.PowerManagement"); iface.call("UnInhibit", cookie); } void MoveToCenter(QWidget* w) { QDesktopWidget *dw = QApplication::desktop(); QRect r = dw->availableGeometry(w); w->move(r.center() - w->rect().center()); } QString Time2str(qint64 seconds) { QTime d(0, 0, 0); d = d.addSecs(seconds); return d.toString("hh:mm:ss"); } bool ValidateScreenshotPath(const QString& path) { auto name = path.trimmed(); if (name.isEmpty()) return false; if (name.size() && name[0] == '~') { name.replace(0, 1, QDir::homePath()); } QFileInfo fi(name); if (fi.exists()) { if (!fi.isDir()) { return false; } if (!fi.isReadable() || !fi.isWritable()) { return false; } } return true; } QImage LoadHiDPIImage(const QString& filename) { QImageReader reader(filename); reader.setScaledSize(reader.size() * qApp->devicePixelRatio()); auto img = reader.read(); img.setDevicePixelRatio(qApp->devicePixelRatio()); return img; } QPixmap LoadHiDPIPixmap(const QString& filename) { return QPixmap::fromImage(LoadHiDPIImage(filename)); } QString ElideText(const QString &text, const QSize &size, QTextOption::WrapMode wordWrap, const QFont &font, Qt::TextElideMode mode, int lineHeight, int lastLineWidth) { int height = 0; QTextLayout textLayout(text); QString str; QFontMetrics fontMetrics(font); textLayout.setFont(font); const_cast(&textLayout.textOption())->setWrapMode(wordWrap); textLayout.beginLayout(); QTextLine line = textLayout.createLine(); while (line.isValid()) { height += lineHeight; if(height + lineHeight >= size.height()) { str += fontMetrics.elidedText(text.mid(line.textStart() + line.textLength() + 1), mode, lastLineWidth); break; } line.setLineWidth(size.width()); const QString &tmp_str = text.mid(line.textStart(), line.textLength()); if (tmp_str.indexOf('\n')) height += lineHeight; str += tmp_str; line = textLayout.createLine(); if(line.isValid()) str.append("\n"); } textLayout.endLayout(); if (textLayout.lineCount() == 1) { str = fontMetrics.elidedText(str, mode, lastLineWidth); } return str; } } } deepin-movie-reborn-5.0.0/src/libdmr/utils.h000066400000000000000000000052411351125414100207320ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_UTILS_H #define _DMR_UTILS_H #include namespace dmr { namespace utils { void ShowInFileManager(const QString &path); bool CompareNames(const QString& fileName1, const QString& fileName2); bool IsNamesSimilar(const QString& s1, const QString& s2); QFileInfoList FindSimilarFiles(const QFileInfo& fi); QString FastFileHash(const QFileInfo& fi); QString FullFileHash(const QFileInfo& fi); QPixmap MakeRoundedPixmap(QPixmap pm, qreal rx, qreal ry, int rotation = 0); QPixmap MakeRoundedPixmap(QSize sz, QPixmap pm, qreal rx, qreal ry, qint64 time); QImage LoadHiDPIImage(const QString& filename); QPixmap LoadHiDPIPixmap(const QString& filename); uint32_t InhibitStandby(); void UnInhibitStandby(uint32_t cookie); uint32_t InhibitPower(); void UnInhibitPower(uint32_t cookie); void MoveToCenter(QWidget* w); QString Time2str(qint64 seconds); bool ValidateScreenshotPath(const QString& path); QString ElideText(const QString &text, const QSize &size, QTextOption::WrapMode wordWrap, const QFont &font, Qt::TextElideMode mode, int lineHeight, int lastLineWidth); } } #endif /* ifndef _DMR_UTILS_H */ deepin-movie-reborn-5.0.0/src/main.cpp000066400000000000000000000115441351125414100176030ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include #include #include #include #include #include #include #include "config.h" #include "options.h" #include "dmr_settings.h" #include "mainwindow.h" #include "dbus_adpator.h" #include "compositing_manager.h" #include "utils.h" #include "movie_configuration.h" DWIDGET_USE_NAMESPACE int main(int argc, char *argv[]) { CompositingManager::detectOpenGLEarly(); DApplication::loadDXcbPlugin(); #if defined(STATIC_LIB) DWIDGET_INIT_RESOURCE(); #endif DApplication app(argc, argv); // required by mpv setlocale(LC_NUMERIC, "C"); app.setAttribute(Qt::AA_UseHighDpiPixmaps); // overwrite DApplication default value app.setAttribute(Qt::AA_ForceRasterWidgets, false); app.setOrganizationName("deepin"); app.setApplicationName("deepin-movie"); app.setApplicationVersion(DMR_VERSION); app.setProductIcon(QPixmap(":/resources/icons/logo-big.svg")); app.setWindowIcon(QIcon(":/resources/icons/logo-big.svg")); QString acknowledgementLink = "https://www.deepin.org/acknowledgments/deepin-movie"; app.setApplicationAcknowledgementPage(acknowledgementLink); auto& clm = dmr::CommandLineManager::get(); clm.process(app); QStringList toOpenFiles; if (clm.positionalArguments().length() > 0) { toOpenFiles = clm.positionalArguments(); } app.loadTranslator(); app.setApplicationDisplayName(QObject::tr("Deepin Movie")); app.setApplicationDescription(QObject::tr( "Deepin Movie is a well-designed and full-featured" " video player with simple borderless design. It supports local and" " streaming media play with multiple video formats.")); auto light_theme = dmr::Settings::get().internalOption("light_theme").toBool(); app.setTheme(light_theme ? "light": "dark"); if (clm.debug()) { Dtk::Core::DLogManager::registerConsoleAppender(); } Dtk::Core::DLogManager::registerFileAppender(); qDebug() << "log path: " << Dtk::Core::DLogManager::getlogFilePath(); bool singleton = !dmr::Settings::get().isSet(dmr::Settings::MultipleInstance); if (singleton && !app.setSingleInstance("deepinmovie")) { qDebug() << "another deepin movie instance has started"; if (!toOpenFiles.isEmpty()) { QDBusInterface iface("com.deepin.movie", "/", "com.deepin.movie"); if (toOpenFiles.size() == 1) { iface.asyncCall("openFile", toOpenFiles[0]); } else { iface.asyncCall("openFiles", toOpenFiles); } } exit(0); } app.setWindowIcon(QIcon(":/resources/icons/logo.svg")); app.setApplicationDisplayName(QObject::tr("Deepin Movie")); app.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings, true); MovieConfiguration::get().init(); QRegExp url_re("\\w+://"); dmr::MainWindow mw; mw.setMinimumSize(QSize(528, 400)); mw.resize(850, 600); utils::MoveToCenter(&mw); mw.show(); if (!QDBusConnection::sessionBus().isConnected()) { qWarning() << "dbus disconnected"; } ApplicationAdaptor adaptor(&mw); QDBusConnection::sessionBus().registerService("com.deepin.movie"); QDBusConnection::sessionBus().registerObject("/", &mw); if (!toOpenFiles.isEmpty()) { mw.playList(toOpenFiles); } return app.exec(); } deepin-movie-reborn-5.0.0/src/resources.qrc000066400000000000000000000304071351125414100206730ustar00rootroot00000000000000 resources/data/settings.json resources/profiles/default.profile resources/profiles/failsafe.profile resources/profiles/composited.profile resources/qss/dark/dmr--NotificationWidget.theme resources/qss/dark/dmr--VolumeSlider.theme resources/qss/dark/dmr--SubtitlesView.theme resources/qss/dark/dmr--SubtitleItemWidget.theme resources/qss/dark/dmr--PlayItemWidget.theme resources/qss/dark/dmr--PlaylistWidget.theme resources/qss/dark/dmr--MainWindow.theme resources/qss/dark/dmr--ToolboxProxy.theme resources/qss/dark/dmr--MovieInfoDialog.theme resources/qss/dark/dmr--Tip.theme resources/qss/light/dmr--NotificationWidget.theme resources/qss/light/dmr--VolumeSlider.theme resources/qss/light/dmr--SubtitlesView.theme resources/qss/light/dmr--SubtitleItemWidget.theme resources/qss/light/dmr--PlayItemWidget.theme resources/qss/light/dmr--PlaylistWidget.theme resources/qss/light/dmr--MainWindow.theme resources/qss/light/dmr--ToolboxProxy.theme resources/qss/light/dmr--MovieInfoDialog.theme resources/qss/light/dmr--Tip.theme resources/icons/select-hover.svg resources/icons/select-normal.svg resources/icons/select-press.svg resources/icons/input_clear_hover.svg resources/icons/input_clear_normal.svg resources/icons/input_clear_press.svg resources/icons/dark/subtitle-selected.svg resources/icons/light/subtitle-selected.svg resources/icons/logo.svg resources/icons/logo-big.svg resources/icons/light/mini-init-splash.svg resources/icons/dark/mini-init-splash.svg resources/icons/light/init-splash.svg resources/icons/dark/init-splash.svg resources/icons/light/mini/restore-normal-mini.svg resources/icons/light/mini/play-normal-mini.svg resources/icons/light/mini/play-press-mini.svg resources/icons/light/mini/pause-normal-mini.svg resources/icons/light/mini/restore-hover-mini.svg resources/icons/light/mini/pause-press-mini.svg resources/icons/light/mini/play-hover-mini.svg resources/icons/light/mini/pause-hover-mini.svg resources/icons/light/mini/restore-press-mini.svg resources/icons/light/mini/close-hover.svg resources/icons/light/mini/close-press.svg resources/icons/light/mini/close-normal.svg resources/icons/light/normal/audio-volume-medium-hover.svg resources/icons/light/normal/film-top.svg resources/icons/light/normal/film-bg.svg resources/icons/light/normal/dvd.svg resources/icons/light/normal/url.svg resources/icons/light/normal/previous-normal.svg resources/icons/light/normal/Subtitle-press.svg resources/icons/light/normal/play-normal.svg resources/icons/light/normal/audio-volume-low-hover.svg resources/icons/light/normal/audio-volume-muted-blocked-panel-hover.svg resources/icons/light/normal/exit-fullscreen-hover.svg resources/icons/light/normal/exit-fullscreen-press.svg resources/icons/light/normal/audio-volume-medium-normal.svg resources/icons/light/normal/audio-volume-muted-blocked-panel-press.svg resources/icons/light/normal/close-hover.svg resources/icons/light/normal/list-hover.svg resources/icons/light/normal/next-normal.svg resources/icons/light/normal/previous-press.svg resources/icons/light/normal/pause-big.svg resources/icons/light/normal/pause-big_normal.svg resources/icons/light/normal/pause-big_hover.svg resources/icons/light/normal/pause-big_press.svg resources/icons/light/normal/exit-fullscreen-normal.svg resources/icons/light/normal/audio-volume-low-normal.svg resources/icons/light/normal/Subtitle-normal.svg resources/icons/light/normal/audio-volume-high-normal.svg resources/icons/light/normal/audio-volume-muted-blocked-panel-normal.svg resources/icons/light/normal/previous-hover.svg resources/icons/light/normal/play-big.svg resources/icons/light/normal/play-big_normal.svg resources/icons/light/normal/play-big_hover.svg resources/icons/light/normal/play-big_press.svg resources/icons/light/normal/next-press.svg resources/icons/light/normal/audio-volume-high-press.svg resources/icons/light/normal/pause-press.svg resources/icons/light/normal/list-normal.svg resources/icons/light/normal/pause-hover.svg resources/icons/light/normal/audio-volume-low-press.svg resources/icons/light/normal/audio-volume-off-press.svg resources/icons/light/normal/list-press.svg resources/icons/light/normal/play-press.svg resources/icons/light/normal/audio-volume-high-hover.svg resources/icons/light/normal/audio-volume-off-normal.svg resources/icons/light/normal/fullscreen-press.svg resources/icons/light/normal/close-press.svg resources/icons/light/normal/fullscreen-hover.svg resources/icons/light/normal/audio-volume-medium-press.svg resources/icons/light/normal/fullscreen-normal.svg resources/icons/light/normal/Subtitle-hover.svg resources/icons/light/normal/pause-normal.svg resources/icons/light/normal/audio-volume-off-hover.svg resources/icons/light/normal/next-hover.svg resources/icons/light/normal/play-hover.svg resources/icons/light/normal/close-normal.svg resources/icons/dark/mini/restore-normal-mini.svg resources/icons/dark/mini/play-normal-mini.svg resources/icons/dark/mini/play-press-mini.svg resources/icons/dark/mini/pause-normal-mini.svg resources/icons/dark/mini/restore-hover-mini.svg resources/icons/dark/mini/pause-press-mini.svg resources/icons/dark/mini/play-hover-mini.svg resources/icons/dark/mini/pause-hover-mini.svg resources/icons/dark/mini/restore-press-mini.svg resources/icons/dark/mini/close-hover.svg resources/icons/dark/mini/close-press.svg resources/icons/dark/mini/close-normal.svg resources/icons/dark/normal/audio-volume-medium-hover.svg resources/icons/dark/normal/film-top.svg resources/icons/dark/normal/film-bg.svg resources/icons/dark/normal/dvd.svg resources/icons/dark/normal/url.svg resources/icons/dark/normal/previous-normal.svg resources/icons/dark/normal/Subtitle-press.svg resources/icons/dark/normal/play-normal.svg resources/icons/dark/normal/audio-volume-low-hover.svg resources/icons/dark/normal/audio-volume-muted-blocked-panel-hover.svg resources/icons/dark/normal/exit-fullscreen-hover.svg resources/icons/dark/normal/exit-fullscreen-press.svg resources/icons/dark/normal/audio-volume-medium-normal.svg resources/icons/dark/normal/audio-volume-muted-blocked-panel-press.svg resources/icons/dark/normal/close-hover.svg resources/icons/dark/normal/list-hover.svg resources/icons/dark/normal/next-normal.svg resources/icons/dark/normal/previous-press.svg resources/icons/dark/normal/pause-big.svg resources/icons/dark/normal/pause-big_normal.svg resources/icons/dark/normal/pause-big_hover.svg resources/icons/dark/normal/pause-big_press.svg resources/icons/dark/normal/exit-fullscreen-normal.svg resources/icons/dark/normal/audio-volume-low-normal.svg resources/icons/dark/normal/Subtitle-normal.svg resources/icons/dark/normal/audio-volume-high-normal.svg resources/icons/dark/normal/audio-volume-muted-blocked-panel-normal.svg resources/icons/dark/normal/previous-hover.svg resources/icons/dark/normal/play-big.svg resources/icons/dark/normal/play-big_normal.svg resources/icons/dark/normal/play-big_hover.svg resources/icons/dark/normal/play-big_press.svg resources/icons/dark/normal/next-press.svg resources/icons/dark/normal/audio-volume-high-press.svg resources/icons/dark/normal/pause-press.svg resources/icons/dark/normal/list-normal.svg resources/icons/dark/normal/pause-hover.svg resources/icons/dark/normal/audio-volume-low-press.svg resources/icons/dark/normal/audio-volume-off-press.svg resources/icons/dark/normal/list-press.svg resources/icons/dark/normal/play-press.svg resources/icons/dark/normal/audio-volume-high-hover.svg resources/icons/dark/normal/audio-volume-off-normal.svg resources/icons/dark/normal/fullscreen-press.svg resources/icons/dark/normal/close-press.svg resources/icons/dark/normal/fullscreen-hover.svg resources/icons/dark/normal/audio-volume-medium-press.svg resources/icons/dark/normal/fullscreen-normal.svg resources/icons/dark/normal/Subtitle-hover.svg resources/icons/dark/normal/pause-normal.svg resources/icons/dark/normal/audio-volume-off-hover.svg resources/icons/dark/normal/next-hover.svg resources/icons/dark/normal/play-hover.svg resources/icons/dark/normal/close-normal.svg resources/icons/success.svg resources/icons/fail.svg deepin-movie-reborn-5.0.0/src/resources/000077500000000000000000000000001351125414100201605ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/src/resources/data/000077500000000000000000000000001351125414100210715ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/src/resources/data/settings.json000066400000000000000000000313631351125414100236320ustar00rootroot00000000000000{ "groups": [ { "key": "base", "name": "Basic", "groups": [ { "key": "play", "name": "Play", "options": [ { "key": "light_theme", "name": "", "hide": true, "reset": false, "type": "checkbox", "default": false }, { "key": "global_volume", "name": "", "hide": true, "reset": false, "type": "spinbutton", "default": 100 }, { "key": "playlist_pos", "name": "", "hide": true, "reset": false, "type": "spinbutton", "default": 0 }, { "key": "forced_interop", "name": "", "hide": true, "reset": false, "type": "lineedit", "default": "" }, { "key": "disable_interop", "name": "", "hide": true, "reset": false, "type": "checkbox", "default": false }, { "key": "emptylist", "name": "", "type": "checkbox", "text": "Clear playlist when exit", "default": "" }, { "key": "resumelast", "name": "", "type": "checkbox", "text": "Remember playback position", "default": true }, { "key": "addsimilar", "name": "", "type": "checkbox", "text": "Auto add similar files to play", "default": true }, { "key": "mousepreview", "name": "", "text": "Show video preview on mouseover", "type": "checkbox", "default": true }, { "key": "multiinstance", "text": "Open a new player for each file played", "type": "checkbox", "default": "" }, { "key": "pauseonmin", "text": "Pause when minimized", "type": "checkbox", "default": true }, { "key": "hwaccel", "type": "checkbox", "hide": true, "default": true } ] }, { "key": "screenshot", "name": "Screenshot", "options": [ { "key": "location", "name": "Path", "type": "selectableEdit", "default": "~/Pictures/DMovie" } ] }, { "key": "general", "name": "", "hide": true, "options": [ { "key": "last_open_path", "name": "", "type": "selectableEdit", "default": "" } ] } ] }, { "key": "shortcuts", "name": "Shortcuts", "groups": [ { "key": "play", "name": "Playback", "options": [ { "key": "enable", "type": "checkbox", "hide": true, "default": "true" }, { "key": "pause_play", "name": "Pause/Play", "type": "shortcut", "default": ["0", "32"] }, { "key": "seek_forward", "name": "Forward", "type": "shortcut", "default": ["0", "16777236"] }, { "key": "seek_backward", "name": "Rewind", "type": "shortcut", "default": ["0", "16777234"] }, { "key": "fullscreen", "name": "Fullscreen", "type": "shortcut", "default": ["0", "16777220"] }, { "key": "playlist", "name": "Playlist", "type": "shortcut", "default": ["0", "16777266"] }, { "key": "accel", "name": "Speed up", "type": "shortcut", "default": ["67108864", "16777236"] }, { "key": "decel", "name": "Speed down", "type": "shortcut", "default": ["67108864", "16777234"] }, { "key": "reset", "name": "Reset speed", "type": "shortcut", "default": ["0", "82"] } ] }, { "key": "frame_sound", "name": "Frame/Sound", "options": [ { "key": "enable", "type": "checkbox", "hide": true, "default": "true" }, { "key": "mini", "name": "Mini mode", "type": "shortcut", "default": ["0", "16777265"] }, { "key": "vol_up", "name": "Volume up", "type": "shortcut", "default": ["0", "16777235"] }, { "key": "vol_down", "name": "Volume down", "type": "shortcut", "default": ["0", "16777237"] }, { "key": "mute", "name": "Mute", "type": "shortcut", "default": ["0", "77"] }, { "key": "next_frame", "name": "Next frame", "type": "shortcut", "default": ["0", "78"] }, { "key": "previous_frame", "name": "Previous frame", "type": "shortcut", "default": ["0", "66"] } ] }, { "key": "file", "name": "File", "options": [ { "key": "enable", "type": "checkbox", "hide": true, "default": "true" }, { "key": "open_file", "name": "Open file", "type": "shortcut", "default": ["67108864", "79"] }, { "key": "playlist_prev", "name": "Open previous", "type": "shortcut", "default": ["0", "16777238"] }, { "key": "playlist_next", "name": "Open next", "type": "shortcut", "default": ["0", "16777239"] } ] }, { "key": "sub", "name": "Subtitle", "options": [ { "key": "enable", "type": "checkbox", "hide": true, "default": "true" }, { "key": "sub_forward", "name": "0.5s forward", "type": "shortcut", "default": ["33554432", "16777236"] }, { "key": "sub_backward", "name": "0.5s backward", "type": "shortcut", "default": ["33554432", "16777234"] } ] }, { "key": "screenshot", "name": "Screenshot", "options": [ { "key": "enable", "type": "checkbox", "hide": true, "default": "true" }, { "key": "screenshot", "name": "Film screenshot", "type": "shortcut", "default": ["134217728", "65"] }, { "key": "burst_screenshot", "name": "Burst screenshot", "type": "shortcut", "default": ["134217728", "83"] } ] } ] }, { "key": "subtitle", "name": "Subtitle", "groups": [ { "key": "font", "name": "Font Style", "options": [ { "key": "family", "name": "Font", "type": "combobox", "default": 0 }, { "key": "size", "name": "Font Size", "type": "spinbutton", "default": 38 } ] } ] } ] } deepin-movie-reborn-5.0.0/src/resources/icons/000077500000000000000000000000001351125414100212735ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/src/resources/icons/dark/000077500000000000000000000000001351125414100222145ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/src/resources/icons/dark/init-splash.svg000066400000000000000000001512751351125414100252030ustar00rootroot00000000000000 init-splash Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/mini-init-splash.svg000066400000000000000000000411261351125414100261260ustar00rootroot00000000000000‰PNG  IHDR<|ô* ̃sRGB®Îé@IDATxí[ŒdIz×OfVeUuUơm¦ç¶³»½Ë́®Ư 60kÀ°%#đ²ŒBŒ_@2 ºZH ˆx°¼ ²‘™\‹06c.¦›ơîbơîÎvÏlÏL_ªºª²̣Æÿÿ}ñÅå\̣VƠ×èÎß÷ÅwNFüƠçœ,œräÈ={ ÷@îܹ^¬h½Xo'¿›êy΋ñ í3»É=đØ{ ưØ÷wđ¢ô!8_”÷ßÇ Ôè½ä·r¼0 YÎ?†|ñ‘üêÏüËƠÏŒ>ß¹sçx{Ê­s<¥È±ŸRÇ?C»ÏÜkï|ơü¹ÏưÈŸ-­ü踻üCÅJçrÑm¿ÔêƯ3«Å¨sç·¿ü[ÿ‡₫̃Ă/ió°öú@ó¡4÷ÀR³*kNY´Îÿä/ov>ûßø₫¨ựѰhëÅærQ¬áƠEy ù½1"¾‹¯ü8úæ^¼½¨>3)q\~f0È“í ¼'ÛßỊ̈̃Úç?ơ‡¿r·h_ú‰‹Ùpf í…AíH$˜‹”¡.÷¬%ƒÍ¢P;FÓY=秨2đNч=á­’cíÖà“ưñ̉«E H Æ -¥œăÖÎ]øÙ¯ü»̃϶ ă_ËxbÇ RG±ÈÜE†²É´Îè¬ Í錨r©Ü̃äu9ßÂntÿîGßù©¯ÿôç~6C¼Ü;ªk‘e§¡2đNç<Û{l÷?~8dÜæ’É0AöđơưƯNñûûL€ÜlÇQ¹¢§½%kË:ÛpöĐ’•/A¢Ù3g²:‹V6ÊZŸ^m_¸ộg~éëEñ)ˆè†ĐËé÷€Z§¸ ̣[·è}̣ơ‡$‚pƒxpñ‡U¨ë”ÏÈ-´60Óölăôc .½T÷åÛ¹ö¶Oæ̣²´óËăŸ¨Çû¦́»‡œƒlŸ‡Æ†ß¹ƒœN[äï´}ẫïĂ¿|oø¹¿*ä‡D^‘=iAÖ1¢"P 6¡₫̣½È8*~tÉÙ¢ÁËD¨ø1c0èéûâw"ET¼÷yµ!Ø.|+RDÅû?è*đă@ˆRÁó\=2ÍÅSØx§đCozËn}µ°Œ” X l®Ê¬è@izNÂNEñ½Ø"º¸zKiçSg|Gü b©Î†₫ØÀR uññÔÚ¸c±71f!Ă}z /ŸI,<¶k—2C™FÀqˆjđ±hu€ê‘ZDçWĐCUTl¬}dVkcÑ% Ulüq¹¼G;Tm™·§²2đNåÇ̃ü¦ÛXxÅ<^KN °‚ ’(Î5icCX“K]dÓGƠ€§´á–¸Ñ EƠ†R¦ª ô¶ßF*Ü~hËyC¤È­Ôóæ”öç5rÊ=À &Æ8!FŒđ ¢pa™èEO h+d¶˜´dœäN¤YØJ{ØMơ°™h̀5<̀Ñ(˜äÍ©îáê¿úæ3ehA`È‹—¤ÈM„-ÂĂœƯÙZ.Cài64GÚj’g¶†+¼ ¦Êù)î ¼Süá×¼uDxă!î*Đ‘?|ÉF :û/"–iLÀt^E‘Ă]E¡#êh„Ạ̊g;yœ‹ äl·üVÚ^Ú²9f́¤)6+\eÅ^4b™³zrEsx´Èé”÷@̃)?Êo¿3.<ÀĐˆY"ÈMÆÜÀ"9ª0¶ƒBxÍóÉ!B·wa;GÚÎ|̃‹é/†¨×}´a|ÅmD‡}ºUZ©æMî ¼|$=ĐnC̃.á9%‰¼.|ÊP‘0¢˜r8¡˘:óâ4dÖöL¶VÅ…ôe —›¯x?¢2;çOüBfbl_tSî ¼|°ˆ ya‘ÀsаJƒ̀ÇEP1ÈHk# =1±Î2sBÏôÈ¥©[6ƒẦQ;³‰åÁ́¡0À™ß<¤eïåd=g=‘sévÑ:’UZR%"‹„F Wj‡bC‹rm>¦—FÜ8 Ñ–vx‰97$”Kâ'=>2kÛơ¢ƒ/iï|é’³«ä́Ô÷O¥œrX`Ñb8°9¼r°0¸0Ê[₫TÊđ6&ácu—‹ hrúă^Í–̣H'í­^cöÖ^¢GçËV„Å—´3'4Èé´÷@̃i?Jïéq.c†DNP0ï̉€r@L,ă%`£O§“¢³ùÛ¤(₫9úÚ™`+>£vΟøDÙïĂù¦¼h‡dí ”̀ùÊ—áiÿä­ö@^>’Xz¼–ɱDçÆT$Â6Î$£¡{ ˜âHÎ9!|¶ÿø¸økJ₫ëEñ·¾ î́s&âĂƒÍ YgÔF ±?ÎSê´³ơΖEï‹•œr 2đ̣i`= ØÀux=‹l+Đ `P!¼ÚüiFỶʹ@™uÓ9r̃¯3xXÓ?Ø*ÿùÓEñ§ú±6l®-ưÉ>¸ ʘ9™È]Ù·Ge_^´`gäd=g=‘séÜhqÈ9¼8j"XdÂơ,–Ü™c 1Y;“§°Â°Á ¾>‡'Ơ½ûg‹âW₫\Q|éö$—K[Â’ÉÚ¹HOl#{9FÖ#™´ 7ysº{ ït₫Ơw?.\@&:‰–œ•/*KX´x@¨[™¦R†Ĺ ¾\6‚’/₫³üO|n\üÆ_¿đcEÁb{¶‰÷çP…}̀ƯQ {ÊØFdô”#<퇼ƠÈÀËgBÜX¥Èux6ä†G ăệÔc*Ư‹6bÉ<”œLîz`¨ˆ—è\Î2OÄŸy{\üo sỵ̈£B¨9̣Z©î÷eÇ#Ç`:î ‰:{©$osä9¼|”z 5íÇOK°Đ 9{.\˜LÀG]:1 Å=yY™¹¼è®U\\ÿ́O‹_ÿKEñGßThÉpÚÁOvOÿî%Ç„²A‘û±•cF9“Ë×9Â˧BÜg"Â3 A‚²+đ¤‘9<êi€dàa)G€¢ e :ơ©ƒZ–ơŸÜ®†2s¾~ï+ăâ«~\üâŸÁïR`ø,íéÓùµưèü₫y0HÔë …œr¸ÈÀ˧‚ơ€¡Ơ>’RFVX‚ Wñw?°N‚ˆE–È#½+¿r™D“fÜ'ˬ ÿÉ/‹w¾äêbÀ½ ÅXu: :íÍH£¼9í=]/Ú»"¿ö@k4Úóë€$ÉA…%í—ËÑsCè9{‘ĂPVSÙrÆrzO3$˜ÿ‡ß¿ôWƠƠ¿Í6îSvª>9{x—ÆIæ µ˜·¹¢ßÈ‘{€8 xä á"€‰zÆÈ¼¬3“‹Ø@È"SøÉî w\RƒhûÛï‹¿ûî øơÛƯ˸è/‚©À ůs.‘•©så<‡uj.fàås íñ¨¿Ë‡¨7¼!Çëđø¢‘€¹Ø;¥(B«¨¸ĐPÊF&:Fùă½qñó¿2,~ñ7đp‚óË€¢;:sÉ K™41r“‰Èém¨™åâ)î<¤=ž{ëÄ’¥q{8ă¡Á7ÎPáàRrƒ ëx1 „` `‚̣xÈ)Ffå„́¿₫Ú ø…ÿ8.îuqZ¾'ø/í±oŸs稻Ă…́>Êc9jă÷™ §¾2đNư)à;@̉:|(×áQLh4xIîd̀Xư5üímƠSæ“£m |„QÑ ²è|\üÚ×ÇÅϽ;,¾±Û)Æ›¾º³R.hvNéRÁ|³%ư»¡®˜©;ׂ 0ÎwZ„₫È%;µrOäĐ ÷Ä‹Â%@F8c°Hx+íK¼ï W¼^ ä%±9™ÄD̃ú¸(₫̃¿¿ú;ÓÙåb|V‡¯ID;¿"́Ú'¸( Q‹eØdà±'r²ÈơDÎ¥F‡Ö¹~!¨ f„ WiW0Åv÷Ẵ¿u ¡—— $ªàôQ¯(₫ɯµ3*zg–ñG-×.än®-}Nœ» ux‰<̃Ÿ©s„÷Ö©/gàúS é€ñá'¿ó`pñÇ„3e¸Xœ¹]ṇ¸Fî7ß+)EûJtF1!ÿG_ÓñŸFÅAQ]WAEĐñÅö ÄXgsÊBÁÙ@È!-ơÜœ¥½kÄræ;('ërÊ=à{à£o₫›{‰Æ€§ 0¶ựà‘O™’ Dö´%₫ñ¯µŸû ƒÛƯb´ÚQ¤_Q2xÙ₫D/¥~ ¶¢·ö.—y?gKư8/êÙ\̀^>̉øÿ­9QúqZH HÑà¡íûÑ¢x€ß„åđö[ÿ—” â#ƒ:(£ĐÑù ’zKMRÀ—›‡cQÚ3÷˜¸†‘ÈJ(Ä• ÁE°\,:Á\ÀĂf,¸ŒEFxö¬<^:H™ s$s£5·WAJ¦§/©Öœ̉2gC_´Ë«´Ö19gä/ŸåăÉü’‚$AÙ@b2«„8cf?đă!I! Ísv{lŸ$Â)ÔØ°½́Ḯl¸¯tŸ‰kkóÓ×x§ï3ŸúÛ£ÑÑhŒƠNb‚„aær)‹D7!èDOĐ  ›u°pÁÛËAÿ©Ïa¥b¹ªÙ©Ùöήîº7ÀÙ lûg~Ça’sŸ₫}8>È$!·ư߆&Ụ̀ÑÈE9̣ÈÀ;å'@íÛo{á(Ä^>:3’¸†C‰Ë¹Â»ºV{ÔHàæt·L`–bÙmÜk ”ÙFƒ6©q:Ô-I;8¢¨óèa1lwøđ*¾wf™óÓØx§ñSo~Ï„ÂëaƠÂĂ…ô @"®$e©D8!đVÚß+öö¸ˆÚLv¤Íđ¤!'öaEǹѹ<ÑÀˆ˜Ê¬Úˆ¨Ơ·–—îïư¿ˆ:ÇAnt”b•7§¬2đNÙ>ĂÛcH{ÿñCRBGÀÂKL€ >ƒØ`YD_B(É}µ?øĂûă¿₫üUqA¹KÖ"¦G©Lλ”Hʦ³Üt–›Qtâ+½xܨ¬øfàY/â<ïø5o-=üæ?}xîê|ïak è,­´ÚnÑÆ-c­.̉e¾Â(eL¥-3Ë̀1oׯ ?!;º÷ßw₫ |âU†RÍnO\Ä}̣ÅYD¾>/§S̃ñ_ÄS̃§₫íó\à‹³b/Ü+?_Á(Í 2ZửZ~ư÷ÿÔÙå×>¿Ù=÷̣¹ÖæÙsk›+g[«ëËë˽ïƯüÏ¿ù7ü·ÑÆ@ó¤¡gÇÊœ ‹£»'},Ø}NÏJdà=+ŸÄÓ?;7B±‡éÊGirË©'\8gFØ1ºaƒêI1ÔÊOä@̣N­ˆOÔgëẸ̀Ñ<àù`/‚ÏÊåó$®[™9á—EU_ TŸXzZû}bo0ïh₫°“u₫–¹Å‹Úñ9—íưN“h˜ÇekŸóܹräÈ={ ÷@îܹräÈ={ ÷@îܹräÈ={ ÷@îܹräÈ={ ÷@îܹr¼H=€kªävđÙß“]Y5{‹‰–twưúởµ]×&¶™¨DÓï¾ù{'1¿{s'̉Qµ•èYÙ½ư·yûmJ̃.îƯ¹éeEq…BI{¿å埼̣e§av¹è=  éÓx¦ùĂQ~CªÜ¼´‡g¿ ù£Ơ¦¸$º₫₫'¨¿T ÎÜwr/›¨_Àí ‡̣La±åÆêĂƠ ööĐvS₫TZ1́=r>7á Ëâgx´ï÷5êêsHÖE£ÛD?8„-~m›?¸$< iÔ§₫dR{yƠqúäïuŸ¥}ÜàkzÜ̉=ălœaûHltT́̃:lơ{•ơ±{Œ|àgˆ¤²[tV6œ?ø>äÏá”UÍYf’ú=œ3kç¡ÿD…”ï³₫q±|æ¢óqWtƯơ—ÆÅ‡ĐlÄ~nƯ³¯‹ïjó•so¢Í-­ÈöV±v‘2MŸ¼åËEqÓÄŅׯ@₫^ñ̃{^Tl¾ñvdḳ+H~éÊVÉæ]¯¿úÎ;ă⺯.PH_»vmNà̀°Ë9Î6₫pÁæaḉ¡*¨¨¿Œæ(Ư¸H¥lr­UX•9ß’B )Ó|₫ßuïíª‰$ßû¸«̣/à—bR¦¾,…̃ƒ;®Ư§#@Ê1ª¿G0½†€Ô>n™EÛơ÷ïA₫r1 $½D^¡₫ >ƒ^§Uœ'˜#)ŒÎ‰¥AjxDø( ÎôÚ­aß´^ »­Q?Àl´Üj‘5£Ê0gÖh”B£åĂ–éy[́Ê 'ûf[Ù1d#ÊpḈxpoÅưdC§ÇƯ´*çmµØ×6(S.e» o¹¥MßùfMe,;±œ’æÔ.G_>₫́…¦vÇäAFM«ÓËóP°Á\Û^ÑZ29îqë(ôø,‘ă‘í¥Ø̣Ù(Sb/–-Æí¾Á`%x÷4gèÙö°o¾ùà<6ơh rÅmgù̀xôl®h—y€'Gă¡º´‡jáÉ}K+Ă1øY,­ƒ—H²A¿ø‹Ïç̀É‹ï£‡Ï ÆPX|P,o¤L·!_<=Wν®̣â–¨¹x~S«/9½©oHáwo¾$ÇÙéá¹cÆIÀ€é ºzđœ;]¯m±(8k·]‰¸Êû¼V4Öd¦­ÚƯ›—¢/‰ÆùVqQsxïw[WXđÓẪÇß|}¡8ØEtu™†zîBÿ¦TBTơºÔûg-ÊB,µï€McÙûàµÔø…h· fx.kuB¤Ô'đDÎ'B† #Â@(PŒàÓ–ƒ—#eÖ–:²£€T("Ú (DÿmzúîÉ£Ơ1Q‘¦ë,ˆ2‘ïíím™‡ŒR GV; ư-2Úä³L¡]Ù÷îÈ%} ueB±?&™>9€¶üĐA±¸#:‰6¥ô~±rî’o_Ü7Q:*Âfă¥Ï:½±@ÆØrơB F…â4Íé̉•»a_f ZŒ×­Ym¾ˆ2V´¶··yÏä„tm‚NU Ồ:‚ÛƯ›ñpđ+f‘ä»·¿á¾o{¹%n8U>̃đ_¬ƒ]™.ûѤ‚M„ˆĐÖ¼-%ư³W¦ư­Kb¦Û₫!€ö2†’6m?¡á…bx´×:ảÀ ‡Gˆ̣ÎRrzÈ däÛèHÁ·F¸E ́Đl}]¢²Uƒ‚3…£17<\Ö²€hƠEeĐ­n„£3Fi!€‹¶Ä×x Đ8B ‘5ØÏ’rF` ­åNY{6<.Ư÷e½ˆáÑQđG¸-K Á£$¨ă3 4Å€Äïpè‰í€×̣!>ó¡EaG™EĐÀä Âö€PƠ¨¯µ4›K€’IàJĐ1z„]O ˆ¨Đ;º ­Œ4VâQÏøßéjÄ·„á8u÷ï߇ŒP$ĂP\@ø†Ö«Ä»Å]ú:ƒCk¦åµEÖ»ëîøĐoQ#À¤¦—ö´|Ă$u |O”›o|Ñ· Ö,}ÍW/]á°Ü¥‚& †×ͼ’7ïZÅеp£̣µHáf­¾bÉÜLü¶Dm¬Iäfbä{¯}à¿dEñ¢6œá#7MG8¼dzC3lû”½Z 7ˆNñùáÔë¥Yôæ"µ£å– ›AO#=(‡ÿVVÈqwÅh…‘tưNKfǰayÔ' @4$J9S¬º¹°‘@r9hŒÖFËŒ˜ø VØ̀v,6:%Ĉ³t( ŸÖÁNAÇ#ê ôº¤R+́F#Q–‚Ö*_&ä¤y º‘́h;[jW"=@ ë{y€=đơ‹v@sĐSîÔT؉̉ƒ/†Øzm5ö#[ G ‹ûÁ§Ñ\ÏÙ_„ư|ư"[Âpßæ÷9ipä°™åG˜_\ÅPPZÖè®ƯÓˆ~4:|¨đøH?‹—VÙ!ÄÈPF đÓùÅ¥G.¯öDOø‘€U\^sCfÊ9>Fê®ÙÊ=F‚·Dnà·¬Zl|đø6#A&~*á0¹ Á¯™Êç‚5¤Ñd^÷~X(ïZ¢´J#ähĐƠCÎZE UÈá¯Ư=Ε]©@ RĐá´ÙƯ„mzÖ[n„HÎ@§6ưƒÙ  ´KÅ%Gº¾Ô 1R/¢n Ó‰ưóœxC¬Å°ƒàlÑ…!ï`ăÀ“öŸ" W0—ÖG$(éŒÂåQ·-óp„  Q]$G3‰È˜ÇÀc´®­ÈĐ̉EvÈ„wí­]™“£§àkEtæ¿XQĐ©%A§Ñ¹5"=Ơ#r$ø”‰-Ẵ†©æÁrƠyS3§̀±œ²RR$ÈR¸™©B.èÚ‚M#1oƒÈ.ø²h~aÛSM€ä.â‹e¼C ]TÇP‡Åˆè|¤JägûPàñ8‚/üpDtø©$±èiØ^Œ <Ê÷?Fƒ _ÛẠ́βÂL@÷P¨ w ºûnøkó† >@O¹*đ–W€wù:®Îư,¯…Hu¾÷q®?’c¤Ü̉Úæn"+ƒv ¿›€ŸÍ-Zë~_ ÂRIà×>6Ăïºx¼‰ Có»Wă¡ªø+m¾‚ù7ª•‚NëeÜíí¹ˆî-ỚrÅ’é³aÛ3¸½ióqeØq® cV$…pçhg°£.̃ æí¸€ ¨Ă¼‡ªX_"Úc&‰è617'«‘nnÎ S‡À ¬#đ†ÁnŒî€£s ¹3Xh`’ˆàs‘£:KsƒYˆèÚ-ç"™ŸÏ ²n8Ù‡‹ ăy=]d@'`Ể̃†¹ä’”]ôG¥ÑˆÀƒ\ Ña$4åB¹Ef®±pê‘\Í|Ÿ‹âe¥vh.órÂDÎáiäGFúù:Ùé¾ €.’Sؤ4ç¸Ơd2—Ç0 qéM‡¹!¢Û爋îÚKÉ1ºkiÄ×Á| Çÿ%¾êđ—̃0ÇGî2gô§I¢:üH̉’̀ỵ̈íé°wiC×đØ2@O¨‡hÏæñÙPX÷ ê!­DÑ_Q|[dk›neÚ}iÄǴ…¨¯ |__M›K7¢¡oQ|×Åz¬MSaw°ÛAÓ­ÚæNȃ~}’Áñtï£Óô¦9º‹?a½`ËOĂXfë\ăª& 88Øà·'Qç\Á”B'Ùpw·ƠÙÜÄ÷[‡ĂíåÍ1çæxr¶öÈ·¥b¼Àñ$u5jl/­¹Á'}‹{ø Ûoµûgkø2à— GCÚ!?hăǸđ¥"øÔđ;+sv¸D‚đñ›ØW ¶ù:0ñäœ̃:Ñï€CÔ•¢-ß3<ºgGÂ₫(g©[éá)xÿ2”ä#îü¤D uÆË8Fỳ§bÇ}y '‘ppüE!&7™×¬†ŕ6?/×åéŒbIq±·ipèyÑÆéÚ]>¨z~Qöœk£;Ftök̃ê9ƒ;L†¶¹â³Ña.aÇ„PȾWØtL ;N.«Ơà€„æïÜe7 ;™Ô›;ú¨Ă'T;wÂÓÔ'~?̉ôaZkü̃#́]|­YEÍ‚­âfë̉¥fè‘_Uèñ+™¤ë¨]K$Mî́.¡ẃÄ·_¹ƒˆ̃•Ï€U|”›¸2ÿ*ơ8×÷ªüµ²(sË—6Çq”§₫E„øëăA‘â9Iô2₫µ<”¢?@¯Xăđá¬́%…WTqù‡̃* ‡áñúNXùfâË ˆ |„ˆ‚¿ëÁ‡)='ƒ¼¯ĂÜökˆH øä~ƯbuU¡`đc¤Ơ.đE#—–ÆGÂU‡ÀX×À¾:ÂiˆèQØ)0S/Đƒn:hE_!åÜs·øy5%HC”G»r"(ËIÁU–²îaÆ 290צl$8wÓă1n;¾Dv8ºQ¹C\"ÂÈ rmÀ… ÀĐAˆñcˆæĐ‘è;7¤M@h è 7Đ-tC̀ÛÁ¯ê:F¨üp\T‡o¢êèØÉ*Æ-đ|es&ƒ2l„áÇ´bᢻˆu!ºă6î\ŸƠEw^Éïom»Úf%á$Ø•LQ½îE¥!­É¯Ia¦(–[b̃¸Ù½ưºœ#±A:¬¥&@Ïk)ô°–‚Ïr†µR{³8ºk)îËj++Üœ˜bĂHÏ g+®₫r“uÄ>ƒÛmÛ" ×XVđÙ‚Åp5 yy ­Äʰàă†q±2Ë(NÖ/â+&C_'GđóCX빬¶C»F}ÑutœÓ[Åj.“ÊY"è¢è êT§«º…»4EÚz{Ö@ȤNQ ®̉>N z“”ư$@3#•ùjTđCQÊÜ<œ©Ơ—Ft”ŶŒ̃˜l₫e™ƒ“pÍtŒöD :ä°Há¯ï‹ 'íu(KºùK_tú‡ÑÖ%$¥EqT÷¨8p‘\èØ¢ƒ‹₫$÷ĂX.X`HË?ÆǾ±́’ Ăß»G:¤5ØÙÊ.‡²åÈN§Ñ]xƯ{\¼xßí§€Î~ÛËd8Á.Ά¡,ÔÏăƯñïÁ; ;Z™¼4º»î=t¶¶¶đå-§-L‹àÖ×/!:Á é-˜_–&µ›£]Îă½‘è–Ö6q!®.đ̀%Y,¿$6ƯîF/ªăˆsye si:ü“ñ%–ºknMđƒËkaNœ`£scükzÑ­\ªfgaçÜù̉ă¤Ç|aÀ?ƠœX>‡(ŒuKÎú/úQg¹èyL«¸œ“̣Ë#†…cŒØjcØƠ^ĂÏÜ$αŒ¡(ÆEí!#‰ưÖ`+³m~Đ×qïi—^@Ʊ«ÈÛ£âđá• Ạ̊AÑuđBÀ…;&ZBh_´đEDÊ‹ÁÀÛ´±ƒÁà°¢Íp8@>.–Q¦¼½Ä†h‡qq»è[Ă!Ê)ăèÇ#xD6CÈFB`C˜«Ă†x+x!êiwà‹?Ô8Äû€N}ŒEF¹¾‚³©³‹u¡ µ°Ÿ¢_̣‰«äƯ₫°¦¢ÇÁcéÀn€È :®àiq́Gc¾¾ÆmØ x̀}×^ư·FèÛvĐÀ¾Đ7-G=ô ûl8FzêZ˜ßg?k¿A.Ÿ"7́[tCô/ZˆṂ£ÎøŸ]_†¸Ø£w—:È V÷Ñÿă©w ßçgψûäùÂÄÅ LÏ/)ǰ;à„ƠÓ`Ç9߀Ÿ»ŒEæí0Œu<]guûˆ‘́x—È æÆÓj¦ÁV¯¼rU£è‚†ªkÜ3Gy4̃â¦>í̃¾ „ḱhGy¬kŒ§Û$ʃîàU[¼ %ÓgemxƯ믋Ü6åimxxÇÖm‹₫¦ÎÁ…Hz¬Ø̣Î7¥7äÖ%.f(|Ïéâ…z¥h‹Ñg«´¶ˆÁ% wIÄGÿơÔÅÙꮪtñƒór&„wŒđdåVëAç¢<ê´xÛe/Ä6„I¤'a£ûÖmƯp|Éökrkü&ë ­̀2Ê5Đ̣‚RUäñ…Æ̃½†Î$iË– 3Ú"»CÍQûå%%j¢=†Drˆ®Ôâ%æicx´m¡!££O‹ôdø*lq··ù¹:] ĐưóBd]± ‹˜VÁ­?à₫±Î7k‹ iÜ-Éüa§ÉĂn‘¦?Ö˰ăuÊƯƠ°*[Ù±åÚ‡vú Ñ]ÙQ[î̃Ă%*o¸~×öÉv'Ô¦/Dw×C#W熛íhÛăÀ¦&צFy´J†¿[”Ô§cA.O¤đm|H)ô(A´çæơôBc½`…×c)öXà“KW„yÀ‡k+!ñ̉K œ]¶B‘‚ÈơU?X‚m»iDf‘#ưhÂe/:éÊÔ¦`“Üé‘út$+ÏÏ]ê+ÈëJ†¥TW4³Đˆ-×LĂ<ƒs®pé~< \Óö‘Eyi$'Ư¥#j g+±ñ8Ñ"=ÚôâèÍ`—‚wWÈ%'°×(® :úçë¸.ks}b©«×ØÑÉ"»â£ûÑ]Ô= °ăq̀ƯMƒưhtwÅÚ4å¶2¶¹>áb¾ZŸ3ßk´  B)6ö×øxá·}É ̣éâđ(Åazü!{œ L₫äđ tî×TaN:ܾŒ wṇϰ Aôz):ÓK ô¯8ÿº‡K¨å—Á_o%Ă!K —+́Ăʾ\Zf»C^Ë%U «•è—_R³PçW¿³%½´FôÂy9¼x-À»ä™óÂÿ)a®Œóeñ«À…¹\%”ê_˜ß°r¶W½úç~âư²̀ăáqñ“/·¼¸¢Êá)Ä|ö^Ơ¦́#ßgREŸá ôu‰+¬Ư¡‡]ơókè(–Ĺc?×vŒêô³v\}•Ơ ÆÚ^æỰ1`ö—~ßÊ‹Áî¦u¤iI90 ́̉vơµi°c«"=̉›/Ê£ß0§W?ŸG›+¸Å0¾½Œ2œ5szñ|m¦Ïéqá[MçƯÅËx̣‰Œ’i9w‡;30¯g÷ÍîNŒ!TÎ9³aßÍ÷é´†¸aơ¶>Úă\^ÑÁ#ºuÜgˤÑK®.1³N]ÜN£>‰ø¨”ÈÑ&ù¢4²9:'N‡®e[¶/Eg¨†(0ŕ‹%{/×B¬%fKÍ–²‚ZQsÁÉ"4Ûƒ£>ª6́ Ä₫R3¢½ƒ—üQ§™‡Å:Ñë)»îî—µ²¨±ñÔxá°$ü!Œ¢:́N ưÊ?jKÜɪ¬´Ó?¼ÙƠDu4‘?̃øCNĐÅCX^ÅÖYµ•ÛêE`!Æ̉×ÊúCw¼¬i*ÏÙQªóvơ°K‡²óÁnZt7 ́x|s Wđ˜œôªÀÓăê=:›ă“‚º¶’¬w`8â!‹ïÈĐ2Œe„ËËW8·§© ¾5WgÁ†¹,{đÁu:´ PÓá,êAä†̀vD̀ƒ̉½:Æ—a*̣–Ç*há̉ó”R.\€­Ë€“È-b°CYÄÑ-_ºW‹°µÖ:>àÀƯE¡–t¬k”¯ cƯ€æï HF »tqbvØÑ ¼“ư–Ăú8º{œ°ă¾®^½Y2åå4đØøY‚§|µĐ£q´‚›®̃ÚµwíqÛŸíÉíf ơj¢½0¯g ›>à7#A‚ÎEtTKÄÇŸ®":V˜¢(Đñ®<ÇG+ÎƯÅ8œ @¶`R¦ jª[…bˆUËE%hNM¾pbl›ÚÇ€Û·È.qA^ˆØ4£©È9J‚Ü ¯Í{`Á9Kơ SÚ™.Dua*Å¢:y2´”zµ¨µt¾Nc¼ÆÈÎM-Ù}âƒÇ1́vØ"¤i‘-g…mç=èÑóÛÜ4\®"* o/úˆH%MĐă“Q>m&:¼eMpu·z4RđMââ>[Po¸ÎÜc½° á#:‘~>â£ÀîÇåà#Äâá,ÛG0LàG]À¦µ¤B ÇH%½ Ư $̣`ƒDøÄ+zùH€@ÜdZF± K#@7ơQ! Äs¥î5•°æè@¹“}́Âq»G|NUÛŰ Q]̀ÖĂsƯnº;…Ưw1ŒåT̉Tê¨ƯØ8!ØÑÙ7NvôºđØđÆø’¿ĂbcJ†·´Úª7Ơ•[Ó-½\§wÙ|„<ödxk*¾zT -ÚcíRá¡Ç*._ôÂSX(̉h¥2øà s~an/ ]…zøây>zb­2ʳËXX¶¢:-Áv¥<¤-„«Fj½@úÈlƠÖvW¡*ü\ ÙMÈ›ï¨6ï¨jSIuîÍé#Æp£6œ£™k&‹D¶èàỔºƯÓ¹Á:ÈÑ.DtX8$$Ódós5 æüøƠƒN£ºt¥µă@GoeØÅ £^#»zĐQïđ¢…½vuóuÅ-œku×ÙƯ¤KI¡¤ơÙé|¥ ;ÚÆ¶Óa÷."»«•₫µöMùÂÀ3‡Ó¢½ă@ûˆ3®ØN]^ö¡w‚Ñö=ØL¡ÇĂY|rñ±̀çÙØUÜ{T𱂧#'ĂYÊBT—Â:Kvr¥ËUh£‰÷đV³|ØbG…RiPhhƠX ª1‰`VÖÆŒ¸å"¸XZ†!­ê}d'&NAb¶y!)èôÚº2è r´îpN.@NdÉ¢Ä́ cÛ¥Ưđ§0„­‡Cº9¢ºzØÍƠĐñXO vó a¹ß8xt67ôØh‹›4¥‘uóG{=6½̀MH½GúđOæ.íÑ[ñ 6y»ÛE¿“=¯óß©IsÄG=®Ư[ Q`¼ĐA­̀ƯiÀÇ*àVEP?ÂËHX @¶Œ ©.ƯV!”¡¤ơP›@ÁÄû¤J•ne¦‹æÛÊn¡-´ªǨ&7¬ƠCNïm•]uéü{„“;yAWÜç¥N¶’[êđH÷Ưpß,w1[T@Ç6!ªû.«Ơ!́-×DvÏ'́ønZñ¾­ïëXÛiCÜJ¤Ç½mUwY…møDd>,4¤+¡ˆy=₫Å" æơ&F{4ÅôđV´8Ơ sÓ!®Ÿ†µ̃Y!̀›>>t@§öÄÁđèC]…a:ǧ₫‡\Ú’D}”‡ÈÏ/\8jäÑÖj³îyGn^è ˜èôĐ>#,ÎÙXV׺3dÍvÖ\‘Yµ6U5NX¥ú̉"´w†F´H§¢ê%%zí¤¦j0W÷áA…ίŸK“é຺N7@MŸÙ9t|”Ù’¿Ÿ–  í¥:W—‚v »ĐÑàVu[à7.6́Ç‚`r“vQ̉!lƠQ]ÙíD ]q̣0v±!ly/<n[aÁ\¡ÇÆï4z8øq {™>íñh.s£)D{¬/>ÎçaZO’€¥~qÄG•‡›‹ü>Ê}¼[#Dx”3éư¶˜đïR½ĐĂÆ`^öÖF̣q[ *RAM£Tm;…SÔâ:‚U´«¨˜xE&®˜À.‚Y²mk)Đh©T“᪥ÁDsI &U\7gO>1%r…§Éƒ‘“APµqDÂá?“î#–Otô™,LÜ¢DS:_@W†œÙ¯^¸]ûIûXd¾Îù¶«œ(đèóqCo¶hG">¾Ë”‡4 øú|BÊ«¾Q}ÄÇUÚ—Äfđ±¡F}º›aß=z^«² @u“·®•áˆkúJs|CYøˆœ¸EJb[C`bq[” S»YHÖ×Èư$xEf®ÀçÛzUÍ!Q»đ{µ4 àb-"j̉‚ƒÚÀ±…Bî!‹’êA§srºGsóƒ?Ùx…«´i#:j–×p£?‚º8Åå è(¸ÅM9ªû¦ÈfTÇ8.́èc›¤đ3¥ŸfÜơâ›Ç>.h4G|:̀µăWøyđQ|Ùt|¶ÍïQVñAÚ??|<J#¾ÙàW"?‹úx$Œü¦Â6§›já)/"ÀF"À[†‡1Ị́̃5ỲˆÂ?S<39‡ qÔ–˜+…X@VVC›vÍP”ÚÎa:D­BwFè°7‰æ\$g{ˆ#º°êZæ9è¦c¿~­̀öÓ]}2Ư-³A§£f2èªÛ̃v¾K ó|qÔWñ±ÅyÀO[âg£'¨ØÇàHV`̃«đcÔ§‘y ?»<CÜ(%ÑäC ? Y—4:Ku~œ“æ£Ê"I¢¶àĐľO8Y7%ˆđ¢E„̣18ÖUá†ËGÜNÊMø³‰’®plW…"»pùœ¸!GÁR÷Pa䆬"“ù¹Å¾.£"DtüÍ @®ÍÑæqßh\H~ÅŒûbt´m«{—êèÄ!7î÷iC„ç5(øè ?ÔÍ…8]ÖJñ|¼6/}€)-5êcI‡¼uđcÔG ‹üøQ9?½%ík’*đ3ù™0ÔƠèÏHƒÁZ:2ÑW[RjàAèÛF…’H#ŪϲÅôz#ˆ¬iMÀfª¶Ô¨âP‹ÓdÀEĂWDqÁ±}g?½œÄ|¦ăĂX]G;›ÓHNꇭëºh?«Øî‘¥¡ènI3¿Ñ9ºÍQa]Ư<]ƯÛT@·Ci}ªB-;tƯ®Ûmù‡¸ñ€ÚôKoô¸ëFđmÙi^=jæ‹øØb^đ±M ?¹ ÍOóñ‘̣ñÅË´×¢>@N¢>ú~.øqOB?]ï ÑŸ÷†‚B° @ZH›², $›ZƠËcÊNO¾̃™ɹƯ¥`ÔR®‰Un†.À͹”(N!‡-₫§03«²¼r´^Z憋Æ!+uÍ)äøĂÙå'øß=ĐqUØƠGt´vơ £‡“ƒ½ms§́΅đ’‘~Ôª>j¶#ơ"Å0̀µÖ‹G|“ÁGÿơĂƯtOăàà¥*ü/«®>ê£nü–ĂªO´J#¿iä~.pS³X!â w¤tĂƠ&̃ʼ_,påZÖØÅpœŒu.‘9‚Ơ€¬́·l´©»dÄÚî¹y8!›RnÀƯ“æuQçââUV.ƠDr”wV÷·ñ GŸkkŸ 5Gt7D_7t¥"Ư˜ÖnêA ÇFO"ªó‡obI+Ưâ%đm›ư1̣“cøÙ<_=øøØ÷ËƠwQ3øh¾8ü^ö†½i(råXûƠ;>̀M2,…ƒØÖG‚Ö‘Ÿ “ơ²— Ñ̉̀@,7|Œơ& Ù3Ăđ¶ù :ˇ:Dup£eS§ºèú7pÎ`ö óp±ü#(g…ư¤ÑÜmïºvØzË«£Â-€Î~c6ˆëA§£Ơó:ç67qª‰èDo³¥*đLĂ¼~%đÑl››c¤*øè,ú‡ºñ~·´2|´ ‘ßBđƒ‡̃¥xu׿úôt蟾B†¿ĂC[Ôx%nà#? ‚€”&rBZt•3›D)a$éµÂ, â1RWŒU$¨‡fd0¥¸;Q? ÈÔÁ¹™«Í¨-9Ÿ6\Ú+CY³µ‡ÁÆ côfÉä„›¥*ä¾/ªÎ*V^Ưh•‚&ÀQ÷¬CÇXè̉h6O,¢‹ ÇưZ <³|Ûf{Œ¼|tàẉࣅßtđÑö27iº<-̣3s`3ühWÀzø™_æ Âfm= ›@ÈVÄŸ\ ¢9tùtH–,P­¡½¸é6°ÁBöƠ ¶°œj«­664ˆÅ`‡nczƒ\àh̃ ¹Á™ïy Ç6³Es!’c›ăFsô‘‚® 9Útô±ÍMœê"ºĐY3ªIỜ,Êë̀JQßvd¾hñéÁG|ƠßÁQ7ä¥ÅÁ₫ÚËe–#?ZèJ/KåôFxöS ÏYôÛ*mîÏ4a9SDù Ÿ₫Z›©†6|5IœWÁ8 qËYʼæ/½đw–VÍ6ơ0 +·́́UŸdB(Û[p3°y™Ÿ‹ÓÈÍä̀;̉ëç4«Â¶eÀQ¶r·üˆ¦[Kª²†Å‡pÔO…Ü­&§ç rá´v5L¬£Zh&¥:“' >…F~3E}4ßâf–¹>µÓí1á×ð÷ÍØß$øñÁ£| _̣•†̣HùK©­-Aó6… 76¡Ë%ª«r¯dUW]¨Q#È¡ƠĐ@4w±jê$=ˆ¢¹Q¢·*ÜøË‡₫Çt¼k\+·’̃èïU(T ÷> ·²äèWA÷ô Çc8n4·M'å´@4§.R¼±–JÊ;ªÈ+•áW­·KM©6G}ô6?üæúèM/oa)MW¢¹¿ºè/ü¬íe+à¹Ư¼_ÁæèO›5BêZr8]>$ö‡˜ˆ‰(ªTA釾‘Ơq‹ơđÂJAChÖ¼lÔ-­D«¥f̀`cnl3p·h–¤ºHÎhx×¥¦H¶²̉ºSת* Ñ\ưp•- 9úØæ¦œÊ ›B+m̃l4đâ#(“-Ö¹rÙä©ÀÇ̣Nó5}5‡Íè¯ €Mđ£÷»êØRu\@Ú]c@Ö§¦ A–,áú¿£̉P¸†ñ}¸†Â¦Eóü|<ç…Ô¬GS³0(]Z‰îo:¨QÀ­0@>)r3WpˆÜ,…î–‰’¼p4PÈƯ¨¹V.4o‚Ü<€£7…\3àhó́@®p<Î8Í ¼¸)Ëeº•ôeơSƒ/h¾:{¯àḿ~ñv£ưă ö]¯w!Ưï± hŸG M5͘¹2`rúbÜú¸eưl…Ŕ¿f4€fml)ÔL·(ÜØ~eå^ù›`n%€£ăù!wcâq̉çó9·¥cÏÜ0Ÿ̉WeơS„v.n-ưq?aå—x‹¢$5G€Á¬'?©Bu–H¦Ơh̉ èg¦Ôƒ^5Zƒ“ÍçXºw%œ,SªôµYÀFc‰Ü¢¨M¼¸…Ÿ?ôNK…fÀ} ß’°àPjˆjSGËÍo¼Q₫–UD’K—¦æÏ;䢷ܴh›§<¥ÿM]?îuû8»vm'Ïû…ܽ{@Ú ‚)¥Ư]D€o×M­A¸·G2¥ œ‚l¥ d‰)âÑno —ªÉ„í4(ÆM céÓ)OX|T³ÂLÚ`!µÛ-Ă+n°ÑOnß÷ÑJªˆj7€{€Ûœp;¦^²o\í¾LøØÇØœœ;ómŸƠ|ªAµÉ z}<+;Ÿ̉×±º€Ûó æƒưoͼ““ w ÈÚb dˆ”0(Î Dm¶ó2´:Ù̉\+ﺴ33j´ou„s¦IÑơ' 8ú{’ă₫¶¹‰“²©¤™j{^¨l{°|!'‹7̣çA½ S× ¶ë[Í%‚t¿5Ó>‚fY Î ²y C˳F…Öy=c‹P>:*Í-Usi3qR™ZbRWév'Ï•Åm晵 PÓ(Íä–ϵѾlˆÚ,ͽíX“' ·m¿×RÁ7•(S JO¦Z·×:ÙÉ́mª#\ƒ¡©KÜn0_D<+é[‡Á¶—-+L̀O‚¶£4*4iœ¿UºP:ÖÍV³yµµí,+«¤>O´f*p‹ÀF›Ùà¶cî|₫Ô£7ÉL€{HṆ̃̃Ÿé¬G2«ÿ0N¶à·ê–ªc£í¸²`yqÚ·¬Đ˜' 4«RT8kDhÍ-ÿŒŸ+4Is~pÀ Ÿăt9®<'å[Éq®­5_ø›¢̣høYÖMª'P+ÍÚ=n°q?u₫;ؾ6áËHƒ̉éCÑ“MoÑ£[´Ư ½ơ ïÉT5Ü>¡½ÓÍñ!h³e…Æ|²ñ¢@dÛt5™’'-••ß}4*†ÚNÙµ¯Ï±Yƒ“€›ùÚ¶Bœ3z›øMŸ¨Œ==β}ăgÚÇIñIúéà›úà:~´¨¹5SÔ“Iuó›IDATC;ÍY:46iS¾U«¨…b­%„.r< ›\?/r°pƠ½æm§Î¼Vö´ ¶]{4N(ʦÈíúZO½öm̉›TƯă~7Ûÿôwè- ƒm€°&m×È#zü0Œn+®ø̣\`ô­\ᄆØe·‹Ô=°¬ñà²&̀›!Fí7s¥yfÎO2Z£Ïms\·¤µ_rë'UŸđe=̃!<Íwù4÷=¡×Ê}í`¸ƯÜd‚ª¹Qƒf(«ù"EkµH¾å  ̃Ë|…R;ó5^ĐzQqwOföæÊÑÚ3úU;ˆÍ̃ñ¬ù³ØÏâ1¹₫œ†Û³~ ÚŒå]>9P–÷üäëÇWƯÑ4̀ÊûØn”¡FĂgö«S₫â”ßƠ«?³=4¥£ă¶Ïº4l̃®‡ âzăcHO˜Ç8Œ§ÚôqĂ*~sÛqÅÊa ±çæ·Ü̃Ơ3?7½º`/>§ïÏΡ$Ù Ûơ=Ñ ®7Î̉…z ±k¯çô| ĂÍ…>”9=·ŸÆœïsVó¸?¶«ïm{Ön™lwBn&ïÚÙO­/´¿4ØÛ ™^ô÷7ơC«~ ¦6ÉSz ÷é”Êê¹{àÔƒjîkh¿œ óˆóg{ü1ƒæø}˜=äÈ={ ÷@îܹräxŒ=đÿff‚7ÈXˆIEND®B`‚deepin-movie-reborn-5.0.0/src/resources/icons/dark/mini/000077500000000000000000000000001351125414100231505ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/src/resources/icons/dark/mini/close-hover.svg000066400000000000000000000024761351125414100261300ustar00rootroot00000000000000 close-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/mini/close-normal.svg000066400000000000000000000025231351125414100262660ustar00rootroot00000000000000 close-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/mini/close-press.svg000066400000000000000000000024761351125414100261410ustar00rootroot00000000000000 close-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/mini/pause-hover-mini.svg000066400000000000000000000022431351125414100270620ustar00rootroot00000000000000 pause-hover-mini Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/mini/pause-normal-mini.svg000066400000000000000000000024451351125414100272330ustar00rootroot00000000000000 pause-normal-mini Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/mini/pause-press-mini.svg000066400000000000000000000022431351125414100270730ustar00rootroot00000000000000 pause-press-mini Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/mini/play-hover-mini.svg000066400000000000000000000021171351125414100267120ustar00rootroot00000000000000 play-hover-mini Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/mini/play-normal-mini.svg000066400000000000000000000021461351125414100270610ustar00rootroot00000000000000 play-normal-mini Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/mini/play-press-mini.svg000066400000000000000000000021171351125414100267230ustar00rootroot00000000000000 play-press-mini Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/mini/restore-hover-mini.svg000066400000000000000000000017351351125414100274350ustar00rootroot00000000000000 restore-hover-mini Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/mini/restore-normal-mini.svg000066400000000000000000000021111351125414100275670ustar00rootroot00000000000000 restore-normal-mini Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/mini/restore-press-mini.svg000066400000000000000000000017351351125414100274460ustar00rootroot00000000000000 restore-press-mini Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/000077500000000000000000000000001351125414100235045ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/Subtitle-hover.svg000066400000000000000000000016001351125414100271360ustar00rootroot00000000000000 Subtitle-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/Subtitle-normal.svg000066400000000000000000000017701351125414100273130ustar00rootroot00000000000000 Subtitle-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/Subtitle-press.svg000066400000000000000000000027431351125414100271600ustar00rootroot00000000000000 Subtitle-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/audio-volume-high-hover.svg000066400000000000000000000015671351125414100307020ustar00rootroot00000000000000 audio-volume-high-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/audio-volume-high-normal.svg000066400000000000000000000016161351125414100310420ustar00rootroot00000000000000 audio-volume-high-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/audio-volume-high-press.svg000066400000000000000000000016061351125414100307050ustar00rootroot00000000000000 audio-volume-high-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/audio-volume-low-hover.svg000066400000000000000000000013671351125414100305620ustar00rootroot00000000000000 audio-volume-low-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/audio-volume-low-normal.svg000066400000000000000000000014161351125414100307220ustar00rootroot00000000000000 audio-volume-low-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/audio-volume-low-press.svg000066400000000000000000000014061351125414100305650ustar00rootroot00000000000000 audio-volume-low-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/audio-volume-medium-hover.svg000066400000000000000000000014741351125414100312400ustar00rootroot00000000000000 audio-volume-medium-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/audio-volume-medium-normal.svg000066400000000000000000000016651351125414100314070ustar00rootroot00000000000000 audio-volume-medium-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/audio-volume-medium-press.svg000066400000000000000000000015131351125414100312430ustar00rootroot00000000000000 audio-volume-medium-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/audio-volume-muted-blocked-panel-hover.svg000066400000000000000000000016701351125414100335720ustar00rootroot00000000000000 audio-volume-muted-blocked-panel-hover Created with Sketch. audio-volume-muted-blocked-panel-normal.svg000066400000000000000000000030261351125414100336550ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal audio-volume-muted-blocked-panel-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/audio-volume-muted-blocked-panel-press.svg000066400000000000000000000017071351125414100336040ustar00rootroot00000000000000 audio-volume-muted-blocked-panel-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/audio-volume-off-hover.svg000066400000000000000000000012701351125414100305240ustar00rootroot00000000000000 audio-volume-off-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/audio-volume-off-normal.svg000066400000000000000000000013171351125414100306730ustar00rootroot00000000000000 audio-volume-off-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/audio-volume-off-press.svg000066400000000000000000000013071351125414100305360ustar00rootroot00000000000000 audio-volume-off-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/close-hover.svg000066400000000000000000000024761351125414100264640ustar00rootroot00000000000000 close-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/close-normal.svg000066400000000000000000000030531351125414100266210ustar00rootroot00000000000000 close-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/close-press.svg000066400000000000000000000026701351125414100264710ustar00rootroot00000000000000 close-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/dvd.svg000066400000000000000000000115621351125414100250070ustar00rootroot00000000000000 dvd Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/exit-fullscreen-hover.svg000066400000000000000000000020261351125414100304570ustar00rootroot00000000000000 exit-fullscreen-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/exit-fullscreen-normal.svg000066400000000000000000000026341351125414100306310ustar00rootroot00000000000000 exit-fullscreen-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/exit-fullscreen-press.svg000066400000000000000000000020261351125414100304700ustar00rootroot00000000000000 exit-fullscreen-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/film-bg.svg000066400000000000000000000025221351125414100255430ustar00rootroot00000000000000 film Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/film-top.svg000066400000000000000000000014621351125414100257570ustar00rootroot00000000000000 polygon1151-1 Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/fullscreen-hover.svg000066400000000000000000000014241351125414100275110ustar00rootroot00000000000000 fullscreen-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/fullscreen-normal.svg000066400000000000000000000020571351125414100276610ustar00rootroot00000000000000 fullscreen-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/fullscreen-press.svg000066400000000000000000000014241351125414100275220ustar00rootroot00000000000000 fullscreen-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/list-hover.svg000066400000000000000000000016311351125414100263220ustar00rootroot00000000000000 list-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/list-normal.svg000066400000000000000000000021541351125414100264700ustar00rootroot00000000000000 list-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/list-press.svg000066400000000000000000000016311351125414100263330ustar00rootroot00000000000000 list-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/next-hover.svg000066400000000000000000000021241351125414100263230ustar00rootroot00000000000000 next-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/next-normal.svg000066400000000000000000000021511351125414100264700ustar00rootroot00000000000000 next-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/next-press.svg000066400000000000000000000021241351125414100263340ustar00rootroot00000000000000 next-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/pause-big.svg000066400000000000000000000033161351125414100261040ustar00rootroot00000000000000 pause-big Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/pause-big_hover.svg000066400000000000000000000033321351125414100273050ustar00rootroot00000000000000 pause-big_hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/pause-big_normal.svg000066400000000000000000000037151351125414100274570ustar00rootroot00000000000000 pause-big_normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/pause-big_press.svg000066400000000000000000000037361351125414100273260ustar00rootroot00000000000000 pause-big_press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/pause-hover.svg000066400000000000000000000026111351125414100264630ustar00rootroot00000000000000 pause-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/pause-normal.svg000066400000000000000000000022221351125414100266260ustar00rootroot00000000000000 pause-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/pause-press.svg000066400000000000000000000020731351125414100264760ustar00rootroot00000000000000 pause-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/play-big.svg000066400000000000000000000036751351125414100257440ustar00rootroot00000000000000 play-big Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/play-big_hover.svg000066400000000000000000000037111351125414100271360ustar00rootroot00000000000000 play-big_hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/play-big_normal.svg000066400000000000000000000037131351125414100273050ustar00rootroot00000000000000 play-big_normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/play-big_press.svg000066400000000000000000000037341351125414100271540ustar00rootroot00000000000000 play-big_press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/play-hover.svg000066400000000000000000000030021351125414100263060ustar00rootroot00000000000000 play-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/play-normal.svg000066400000000000000000000024121351125414100264570ustar00rootroot00000000000000 play-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/play-press.svg000066400000000000000000000022641351125414100263300ustar00rootroot00000000000000 play-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/previous-hover.svg000066400000000000000000000021621351125414100272230ustar00rootroot00000000000000 previous-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/previous-normal.svg000066400000000000000000000022071351125414100273700ustar00rootroot00000000000000 previous-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/previous-press.svg000066400000000000000000000021621351125414100272340ustar00rootroot00000000000000 previous-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/normal/url.svg000066400000000000000000000217471351125414100250420ustar00rootroot00000000000000 url Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/dark/subtitle-selected.svg000066400000000000000000000014311351125414100263550ustar00rootroot00000000000000 subtitle-selected Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/fail.svg000066400000000000000000000021061351125414100227260ustar00rootroot00000000000000 fail Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/input_clear_hover.svg000066400000000000000000000026411351125414100255270ustar00rootroot00000000000000 input_clear_hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/input_clear_normal.svg000066400000000000000000000026051351125414100256740ustar00rootroot00000000000000 input_clear_normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/input_clear_press.svg000066400000000000000000000026161351125414100255420ustar00rootroot00000000000000 input_clear_press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/000077500000000000000000000000001351125414100224025ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/src/resources/icons/light/init-splash.svg000066400000000000000000000356241351125414100253700ustar00rootroot00000000000000 init-splash Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/mini-init-splash.svg000066400000000000000000000124461351125414100263170ustar00rootroot00000000000000‰PNG  IHDR<|ô* ̃sRGB®ÎéàIDATxí[ŒeÇU†ëœÓ·±=׌GăÆ8!p‘p€@PÉ"‚!A(/  PBBH @<đÀC$àÅ(F~0 $ œ‡›pâD O›Äö̀ô\<=Óçl₫ÿ¯µö©Ó}ÚÅiÍ₫k¦vU­Zµjïïlư]{ïs)ÅÉLÀLÀLÀLàæ"0º¹ÇGó x9çE÷ Íé0&đª¿ê3x‚›…EđåáÍrÜ>›ˆÀä&:Ê7G -K₫1dæ9¢̣-úó»gÿ×mnn~s3y´ Ü ₫‹}ƒÀ iÛs@"wç:vôôÛß=[YG·¶úÖ²>ùÖ²6~Íh­¬Ư²Qf“ÍÇî{ôw̃úĂ ™—´¾¬=@/¨we+ûw¹g`FÇ̃÷ÀáÉ·¼÷Ë_ŸO^–ÑѵR¯–ry ơ”g;¬øNÜñ°ù"̣2E¯M4Lj…¸­˜ô\_¼ëËû Ï6>vễù2¾ư½'°dĂ™1ÍŒ‹Ú)$m É ²AóàQ ºÔ¥à´”âÆ}ËUhîcöeÛå€Xđôb¿À¡RÇÆ£ç.w+¯-#HU¡ iU•ë×q‡ÿđ;ÿfûĂ#ttø7ü¸Á@öÑ,[L,êi«mNR'È1tgLù±+̉îñi_Ṿ.\›ûÆ3O¾ÿñ~>Sä8¢e#l ̃^å—vŒ£ị̂³[S®Û"¥0¥LP{˜¿~aR<‡e_P¦o×Ô÷ôÓ?Se›cx÷0SÖ#–$1ưY2e›Ơ¬g_µ^¿1>~ûÉ»?ñx)§`bÓ€ ä©5`>ô$°ưÜă[Téå!ÖC6Qaßd÷Y{®s Üêx‰₫—½ŸöÎƠ‹ñ9'Kå¼€¸ÜÅD»›¶ÿ¹Â{ăcèÉËïF9ÓĐx…7´Wüw닜₫%yP?´̣jü©Ô:®¨(()6Z¡}̣lăÜTŸ¹=|1àäÓMGS}–k0ô3ö‰'›¦zöêCa;₫•¦£©{s4'„µÂó\»̃¸º:@¼¾èụ̂¥¯=´>iU‚Â’ÂMe‚Î́×å$üª¡”§~DéâÓ[Z'§~³ÛT42-óa<È´̀‡}í₫,ơ‰}ɃèX±Ø‘Xđ|,X̣äÓØ\qUͨFă%j˜„͹Z=æƠêÑœ_ó~t•=>9¾q[ê“«KAÚăÓïẂØlÖG̀]­#½$ ̃ _öưzŒ¯¸7̉‰­ iCƸ‡ÆKØ´«D_ăs ͼª6ÜRnj •²×‡VÎŲ¦½>èÏy÷ơaG̀C_̃7DjªíÍ@ đ¾†“ e¢Ă 1ă /EC! ¬S: ê§ ÔQ(̣aÂÂH€!üT†©ó­ÆĂïEằ‡°Öî™z2{¸›³Ù|ÇäàÍ  x…7è—ïÁC̀ªF@-(ÊÜDR•›FjXÍîÙ]Lß,u üb>tV :ê…â¤p.ó©£*¯Đ́r9`¼¿øK+¼nO•Iè¨?̀Ú¨Rï₫Ë‚Â:)0“×¢ÊË](RG´/Ñ «w£ {[Êv[ưöÅñËá¸c§¡Ø¬ói,™éÄ:ïêijÑÜĂ£‡ÓÀ Xđ~́>üIW x ˆF«%jÀ6–),*Ñ|k;tHoû|zCHˆĐ™ piƒ(P—17'WŒŒ×hî׿eŒajbµcÔ‡9ă)­̃˜€ÏçÀñ¨Û™̣㑨SJ¬ STøàS—#i“Ú±[g½ñ6l9₫L9 ›C#ceG”«G]éñ¶4³’s1´“ Xđ|%Ci!x!Y¢3EH÷ăQI‘ÑèTFbb›u–½́G©*ú²{Á—ĂĐ‘îhÊ/}Zû<üÑ‘—q}IKzNIÀ‚—$\À¸Œ®ê)-U¥Q–:QXø¤v"&1¤xQ¤bŒÄ'û5ˆ›$ú̉YîÜP¡")N³bäê1û7yç|́Wbi|Īœ£ábđx*9™@ÀC‹éÑĂ[9x¤¸p•·Úü©Ôåm«DŸlG) `Ú³¦/íMŸÆg{‰Çæx­#V>V,Ë tp: ̃ĐÏ€]ÇÙæ=ºA ÍĐÊ ,×è@;DLUÖ‘%lŒ}ª†Ïoü`)¯½ó–¹¯b6ăzñŒx‰z?GĦŸ2ưr\ %Kf¿ ¯̣ñ¶°àùLX aÙæa™BKê½±j’qŒ³fa…GÇȦv%A(>¿û#]ùåïÁW%ÿJ)¿~bÄÙ.Ñ [Ùæª‚ÆzûujÓ/3ûĂ—Ơ>N&<ŸI@²÷ámçª(/aå€^ ¯1Ú‡«,¨³Ư Mö…̣¾ó-ø²¦ßûÑR>ÿÁR~âÛjœÓ [Œe<ÍÁ)hc6Ù£̃G›ơ>?´ §$`ÁK.E´¸Â{xíª‰Â¢‡Áˆ,VầI¡I1Êqi_+<N±B¬Óø¦ºûª”º”{cô)E©±K¦+=ù6₫ÚG¶›Æ̀¿<@a¼6 ̃°_ÿ½Gß•çcA¦>­–«¯CTVđĐBâEB;ëtU6ùS€˜£˜¡“™ÿ²ü±Ó]ù́/våcï*…?ÄñÓÎ×`æLƯ»c'üiăÙÉ+¼ÊÁÛJÀ‚ç3¡%€§´³çơ>¼PêF D&ÚúÖcvF¦ü[/JaÓ§¸TDV_”¬óDüĐ÷uåßq™û oCƒ¢Ê›%¬u>œ+÷Gû}œ ‰}™«Å[đ=<Ÿ»ŒºÙåöÛR$,ô€HĐŸ.̉&aiW]!:­Ê(zÊYg©̀p£râPW₫äÇ»̣đÏ—̣CwUÑ̉åtˆŸ¦güÈÚ'ÔS9O>9æÊÓ+<ó&x…çS¡%€ëL¬đ̉B!A½º¨đ¤Ñ=<öÓ)…‡To>´U¡«1ëE-ëơŸ>®†:Kæï¼£+ưLW>₫“ø] \>k"VYÙ›₫¨*̃î:MĂ8'ël |ß»̣{£-΂Ô`3úRk0ècŒy3tÍûå‡ÂÇO£Ù́b¿Âc¢C R Qá_Éüå2 ú¹¡è…¿́pÔÓT†k¹ú™2^B‚ûß=:+Ÿx_WµVÿ6KØ8§&­1(rùå½>LºoX«̃@ó›†a”£ÙzBq‘À4dRYîî“[Ú>0²Ê4ÿÉî¹=t©:4ÛÇ₫·+¿uÿNyø „î$̃ô׈©Ä7‚ke—uöEƯ÷đ¨®Zđ|,èf×.đKR¨B7z'߇ÇL' Jù‡ÎªÊ˜êÓ¯¸0PơT&FưÙ‹]ùèƒỌ́ñÏâË ­B́°ºc°H)²´iHv L›LÑŸ—Ú›«&àKÚ¿øq蔥LƯxº£ă–¢Á 7áEQáťʶ‘™$Bp0ÁH{{É)§tlJ́_₫ÓNùØßwǻNË;ÿ5s÷%'G;vGư*ơfL?§+ƒ'`Áü)Ш2º²¥÷áÑLÑ ̉ «  ¶_w'~‡öLí§­O¡FôIá£-¬è$Y ̃•O=̃•Ü?-_¾0)Ưa\¾ÆY©74GP†Ô>dldü¸Ô•[ #8WÂ₫¤Åœ‡kyj™„ T;Ó‹çÛ‡̉%ˆŒt&ÅBẨ¾æï)éJß/‘CŸÊ]bÄáÔ$& á×-å·ÿvZ>ù%Ó‘Ở©—¯ +BøơO„cÜ< ± ähU+@Í$œ’€WxIÂ¥̀®lmÍn­â¡ƠYp¡P¥˜Q\ø”v·Øáó°çÎ5đèˆ~¥¶NAb‚^Ú.å>9+ñéYÙ¾e¥tÇCµb\»’“¸ÅXÆTŸ‚dž}Ȳ·óe·Wx-­Á×-xƒ?tWû̉ùï’Î́ K¸çÛM̃„÷È}î‘RvđRôß³:£1¡üƒ‡få8ÄôÏ₫aV6w&XƠ­U¡¢Đ1s|-$bls8móJøÀÈKZös“â¬ñ1ˆuë9%^8™@Oà™'₫ê,¯D[‘A=$.Ñ%pm{ßÛñ•O²ªL( ñ§/é?5*y—Áăµ2Û˜ÔxT%æ&¥xå|ê×NƠ8)¶êÏñQê¾_ø²¿³â5d]ơ ÏçÀ"¯~æ Ô‰]?N k(P …è*Ä…—¶?üRÎă7ayyû•ÿÂ[J°â£ItP¡hÎÖ¡ƒ́ϤƠ$ ̀qUgÙWàSï¨1è<Àsê Xđz®$ ƒOjÇRªA¶™Ø`BÉ*¿OêyÈäm·•̣†ÛñMÆÀÿxºÁ)E†|¡0ÙÇU ̀9«?{Ú;cƠ ăÆ-HÍ) Xđ’„Ë$Đá·i»)d - Iôôul½ˆ¡N|¢7Áµ¿Y‘âEáé…Ik@Ú™²Oun4 ́M›vúæ§.46́h®èTñ¤¯¯h Đ) ø^’pỈ\xö #­°‚M/0Ö©=J¨R`Ö!zºGá¡#rÆIaÊqm_ú²~y/¥êa×X9ƠZÆÖ>Ä|×—´=-W@À‚çÓ`œú’ ÈƠl ¢Ơ†Ǿ ¯à[‹S%bô¡€!ÓăUfßqdÇ¥QôöŒG¿bS³Î’ e¯ÜƠâíÀ ø’và'À’ĂÇ%m™̣Uº.#w9¶¶^¡F\áñÍR̀ä§@5Àôé…·5÷Q'wñ­̀5Mÿ{¹ÏÊ=ø$Eó\{b¹ÏÚwDœ˜3÷#c»6 ̃°_ÿ¥G̃N~¼Lºâ¡•F¨„-Å„%m̀<<´`vù !Q„Mé¯WN¡Äs\iê¤ǘÎfU×ỳ²ŸgZâ£KßôA9ă‡tL Xđ|*́! Á «´#$N]°…¹zFƒë.ưÀWbD­L¿|r ̃ÀR®"³{~¶Î/àÓ́Ç̉8œ>Y¢éd"0?Ù dè(7ÊømÚä‚¢!qÉ(H—́R”¹°ĐÆU₫„£|"è‚̣áæ,‘2LmÅV¡æ=óZöÓ‚œBZ[Ñ™Eø0ưü”6Á¸$¯đ|́&ĐáÉ®ö( HÔSH̉–í!̃1ËøéE’F8¦îÙ]äø…Dqj K|8^ó¥ß~>œkqÎ…Đ9ÜåđXđ†÷¿èg³«³O;)TQª.KƯH„Ч~ ÆpØ.øñ²Cÿ©Óx̉ ³̃ƠƯ»y¡Nž»̃>¨çü,7C&y/đơß…ưƒM eÎq˜4Ê٬ߜNÀ‚7đ`éáºm­đ((” ä~u–J%4)%Q̣ ïÆ¡R.¯N·è;6‰U#Tô” lgđyÜ|àA{#Çh?è³ÅèC;“Æ!M“K[e:đË«x8±éérˆ,xC|Ơ÷?fBÛÆS‹^\¨FWêj4rBÁ[?U.^äCÔư•f„‰ê0|S”s¤‚¢̀̀4Ñ¥¾Ñ vD®!ÇU™Făn´ºrnzöß~m /r›½”—7#`ÁØ ₫·Ă%í¹Kˆó¸$¥èHXøÈ¿ƒ²Áºª”æ!Ôô¹Ú7¿ị́¯₫ËGßø A{¤Ѫ¯R™"ºêaR=û²̀¾,Ó©Ù …ç“^|Ư¨øZđ’̉€K ̃€_ü%‡N™­l=ñÇ[Gß̣½láË&+ë£ñd­Œñ‘±Ñ$då:Wq¨ăVÚ df•%îÛ‘ñ²³³ÿúéF¬+È»EiÉ´¯¸‰s2ó."3…‚ç4pí_Ä£üáó\`æAÈYÙ@Ƨbơó\¥¥ˆ̀6îư₫Ơ×}÷û¬̃yÏáµ£'9zèđú‘ÑÆ­·­̃ºzÛöSÿùŸûµ÷<†1)4×[ôr_YRèÚƠƯỡLïtPXđÊ+qă÷#ÏEkµ^́²o÷^¦=KöS\xÏŒbÇƠU+6h^—ÔÚ~ơë²#ä`hOÔƒµg̃›A€çCf _ÖwŸ'm;ë,).̀¹ª¢đµ‚ƒæuK7j̃ëv€èåÈ“ơåôˆ›•@{N´ơ<̃³¥Đ°lë9̃¥ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜€ ˜À«Kàÿ$Æ· close-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/mini/close-normal.svg000066400000000000000000000030531351125414100264530ustar00rootroot00000000000000 close-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/mini/close-press.svg000066400000000000000000000026701351125414100263230ustar00rootroot00000000000000 close-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/mini/pause-hover-mini.svg000066400000000000000000000022431351125414100272500ustar00rootroot00000000000000 pause-hover-mini Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/mini/pause-normal-mini.svg000066400000000000000000000022721351125414100274170ustar00rootroot00000000000000 pause-normal-mini Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/mini/pause-press-mini.svg000066400000000000000000000022431351125414100272610ustar00rootroot00000000000000 pause-press-mini Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/mini/play-hover-mini.svg000066400000000000000000000021171351125414100271000ustar00rootroot00000000000000 play-hover-mini Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/mini/play-normal-mini.svg000066400000000000000000000021461351125414100272470ustar00rootroot00000000000000 play-normal-mini Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/mini/play-press-mini.svg000066400000000000000000000021171351125414100271110ustar00rootroot00000000000000 play-press-mini Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/mini/restore-hover-mini.svg000066400000000000000000000017351351125414100276230ustar00rootroot00000000000000 restore-hover-mini Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/mini/restore-normal-mini.svg000066400000000000000000000020111351125414100277540ustar00rootroot00000000000000 restore-normal-mini Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/mini/restore-press-mini.svg000066400000000000000000000017351351125414100276340ustar00rootroot00000000000000 restore-press-mini Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/000077500000000000000000000000001351125414100236725ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/Subtitle-hover.svg000066400000000000000000000016001351125414100273240ustar00rootroot00000000000000 Subtitle-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/Subtitle-normal.svg000066400000000000000000000016271351125414100275020ustar00rootroot00000000000000 Subtitle-noraml Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/Subtitle-press.svg000066400000000000000000000027431351125414100273460ustar00rootroot00000000000000 Subtitle-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/audio-volume-high-hover.svg000066400000000000000000000015671351125414100310700ustar00rootroot00000000000000 audio-volume-high-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/audio-volume-high-normal.svg000066400000000000000000000016161351125414100312300ustar00rootroot00000000000000 audio-volume-high-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/audio-volume-high-press.svg000066400000000000000000000016061351125414100310730ustar00rootroot00000000000000 audio-volume-high-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/audio-volume-low-hover.svg000066400000000000000000000013671351125414100307500ustar00rootroot00000000000000 audio-volume-low-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/audio-volume-low-normal.svg000066400000000000000000000014161351125414100311100ustar00rootroot00000000000000 audio-volume-low-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/audio-volume-low-press.svg000066400000000000000000000014061351125414100307530ustar00rootroot00000000000000 audio-volume-low-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/audio-volume-medium-hover.svg000066400000000000000000000014741351125414100314260ustar00rootroot00000000000000 audio-volume-medium-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/audio-volume-medium-normal.svg000066400000000000000000000016651351125414100315750ustar00rootroot00000000000000 audio-volume-medium-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/audio-volume-medium-press.svg000066400000000000000000000015131351125414100314310ustar00rootroot00000000000000 audio-volume-medium-press Created with Sketch. audio-volume-muted-blocked-panel-hover.svg000066400000000000000000000016701351125414100337010ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/src/resources/icons/light/normal audio-volume-muted-blocked-panel-hover Created with Sketch. audio-volume-muted-blocked-panel-normal.svg000066400000000000000000000030261351125414100340430ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/src/resources/icons/light/normal audio-volume-muted-blocked-panel-normal Created with Sketch. audio-volume-muted-blocked-panel-press.svg000066400000000000000000000017071351125414100337130ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/src/resources/icons/light/normal audio-volume-muted-blocked-panel-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/audio-volume-off-hover.svg000066400000000000000000000012701351125414100307120ustar00rootroot00000000000000 audio-volume-off-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/audio-volume-off-normal.svg000066400000000000000000000013171351125414100310610ustar00rootroot00000000000000 audio-volume-off-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/audio-volume-off-press.svg000066400000000000000000000013071351125414100307240ustar00rootroot00000000000000 audio-volume-off-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/close-hover.svg000066400000000000000000000024761351125414100266520ustar00rootroot00000000000000 close-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/close-normal.svg000066400000000000000000000025231351125414100270100ustar00rootroot00000000000000 close-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/close-press.svg000066400000000000000000000024761351125414100266630ustar00rootroot00000000000000 close-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/dvd.svg000066400000000000000000000115751351125414100252010ustar00rootroot00000000000000 dvd Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/exit-fullscreen-hover.svg000066400000000000000000000020261351125414100306450ustar00rootroot00000000000000 exit-fullscreen-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/exit-fullscreen-normal.svg000066400000000000000000000026341351125414100310170ustar00rootroot00000000000000 exit-fullscreen-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/exit-fullscreen-press.svg000066400000000000000000000020261351125414100306560ustar00rootroot00000000000000 exit-fullscreen-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/film-bg.svg000066400000000000000000000025221351125414100257310ustar00rootroot00000000000000 film Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/film-top.svg000066400000000000000000000014621351125414100261450ustar00rootroot00000000000000 polygon1151-1 Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/film.svg000066400000000000000000000025221351125414100253430ustar00rootroot00000000000000 film Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/fullscreen-hover.svg000066400000000000000000000014241351125414100276770ustar00rootroot00000000000000 fullscreen-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/fullscreen-normal.svg000066400000000000000000000020761351125414100300500ustar00rootroot00000000000000 fullscreen-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/fullscreen-press.svg000066400000000000000000000014241351125414100277100ustar00rootroot00000000000000 fullscreen-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/list-hover.svg000066400000000000000000000016311351125414100265100ustar00rootroot00000000000000 list-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/list-normal.svg000066400000000000000000000020361351125414100266550ustar00rootroot00000000000000 list-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/list-press.svg000066400000000000000000000016311351125414100265210ustar00rootroot00000000000000 list-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/next-hover.svg000066400000000000000000000021241351125414100265110ustar00rootroot00000000000000 next-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/next-normal.svg000066400000000000000000000021511351125414100266560ustar00rootroot00000000000000 next-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/next-press.svg000066400000000000000000000021241351125414100265220ustar00rootroot00000000000000 next-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/pause-big.svg000066400000000000000000000037611351125414100262760ustar00rootroot00000000000000 pause-big Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/pause-big_hover.svg000066400000000000000000000045001351125414100274710ustar00rootroot00000000000000 pause-big_hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/pause-big_normal.svg000066400000000000000000000037771351125414100276550ustar00rootroot00000000000000 pause-big_normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/pause-big_press.svg000066400000000000000000000045231351125414100275070ustar00rootroot00000000000000 pause-big_press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/pause-hover.svg000066400000000000000000000020711351125414100266510ustar00rootroot00000000000000 pause-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/pause-normal.svg000066400000000000000000000021201351125414100270110ustar00rootroot00000000000000 pause-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/pause-press.svg000066400000000000000000000020731351125414100266640ustar00rootroot00000000000000 pause-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/play-big.svg000066400000000000000000000043251351125414100261230ustar00rootroot00000000000000 play-big Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/play-big_hover.svg000066400000000000000000000043161351125414100273260ustar00rootroot00000000000000 play-big_hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/play-big_normal.svg000066400000000000000000000043431351125414100274730ustar00rootroot00000000000000 play-big_normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/play-big_press.svg000066400000000000000000000043411351125414100273350ustar00rootroot00000000000000 play-big_press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/play-hover.svg000066400000000000000000000022621351125414100265030ustar00rootroot00000000000000 play-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/play-normal.svg000066400000000000000000000023111351125414100266430ustar00rootroot00000000000000 play-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/play-press.svg000066400000000000000000000022641351125414100265160ustar00rootroot00000000000000 play-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/previous-hover.svg000066400000000000000000000021621351125414100274110ustar00rootroot00000000000000 previous-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/previous-normal.svg000066400000000000000000000022071351125414100275560ustar00rootroot00000000000000 previous-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/previous-press.svg000066400000000000000000000021621351125414100274220ustar00rootroot00000000000000 previous-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/normal/url.svg000066400000000000000000000217471351125414100252300ustar00rootroot00000000000000 url Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/light/subtitle-selected.svg000066400000000000000000000014311351125414100265430ustar00rootroot00000000000000 subtitle-selected Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/logo-big.svg000066400000000000000000000441121351125414100235150ustar00rootroot00000000000000 deepin-movie Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/logo.svg000066400000000000000000000110121351125414100227470ustar00rootroot00000000000000 deepin-movie Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/select-hover.png000066400000000000000000000002211351125414100243740ustar00rootroot00000000000000‰PNG  IHDR‰ sRGB®ÎéKIDAT8cü TLT4 lÔ¨”‡èhBÂĐÛÛ›„a€¦Dă CFFFdu „ø0ÅŒ£YdÓ8#…\G $7äú£G n¹÷„CIEND®B`‚deepin-movie-reborn-5.0.0/src/resources/icons/select-hover.svg000066400000000000000000000024331351125414100244160ustar00rootroot00000000000000 select-hover Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/select-normal.png000066400000000000000000000002061351125414100245440ustar00rootroot00000000000000‰PNG  IHDR‰ sRGB®Îé@IDAT8cü TLT4 lÔ¨”‡èhBÂ0//„a€¦DS= G³rø’Ŧz¤ŒHV< h·Û¦}„ÉIEND®B`‚deepin-movie-reborn-5.0.0/src/resources/icons/select-normal.svg000066400000000000000000000023541351125414100245650ustar00rootroot00000000000000 select-normal Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/select-press.png000066400000000000000000000002201351125414100244040ustar00rootroot00000000000000‰PNG  IHDR‰ sRGB®ÎéJIDAT8cü TLT4 lÔ¨”‡èhBÂ0ûІB|˜:3 ‘UÙ„ø0匣YdÓ8#…\G $7äúz†„½ÂIEND®B`‚deepin-movie-reborn-5.0.0/src/resources/icons/select-press.svg000066400000000000000000000024361351125414100244320ustar00rootroot00000000000000 select-press Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/icons/success.svg000066400000000000000000000016401351125414100234650ustar00rootroot00000000000000 success Created with Sketch. deepin-movie-reborn-5.0.0/src/resources/profiles/000077500000000000000000000000001351125414100220035ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/src/resources/profiles/composited.profile000066400000000000000000000002521351125414100255320ustar00rootroot00000000000000#disabled temporary, slow for 4k videos #scale=spline36 #cscale=spline36 #dscale=mitchell #dither-depth=auto #correct-downscaling=yes #sigmoid-upscaling=yes #deband=yes deepin-movie-reborn-5.0.0/src/resources/profiles/default.profile000066400000000000000000000000211351125414100250020ustar00rootroot00000000000000vo=opengl,xv,x11 deepin-movie-reborn-5.0.0/src/resources/profiles/failsafe.profile000066400000000000000000000000241351125414100251330ustar00rootroot00000000000000vo=x11,xv hwdec=off deepin-movie-reborn-5.0.0/src/resources/qss/000077500000000000000000000000001351125414100207665ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/src/resources/qss/dark/000077500000000000000000000000001351125414100217075ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/src/resources/qss/dark/DSettingsDialog.theme000066400000000000000000000060661351125414100257670ustar00rootroot00000000000000#DSettingsDialog{ qproperty-backgroundColor: white; qproperty-borderColor: rgba(0, 0, 0, 0.2); } #Navigation{ border: none; border-right: 1px solid rgba(0,0,0,0.1); } #NavigationBar{ border: none; } #ButtonGroupSingle { border: 1px solid rgba(0, 0, 0, 0.08); border-radius: 4.0px; } #ButtonGroupBegin { border: 1px solid rgba(0, 0, 0, 0.08); border-top-left-radius: 4.0px; border-bottom-left-radius: 4.0px; } #ButtonGroupBegin:checked { background-color: #2ca7f8; border: solid 1px rgba(0, 90, 224, 0.22); } #ButtonGroupMiddle { border-top: 1px solid rgba(0, 0, 0, 0.08); border-bottom: 1px solid rgba(0, 0, 0, 0.08); border-right: 1px solid rgba(0, 0, 0, 0.08); } #ButtonGroupMiddle:checked { background-color: #2ca7f8; border: solid 1px rgba(0, 90, 224, 0.22); } #ButtonGroupEnd { border: 1px solid rgba(0, 0, 0, 0.08); border-left: none; border-top-right-radius: 4.0px; border-bottom-right-radius: 4.0px; } #ButtonGroupEnd:checked { background-color: #2ca7f8; border: solid 1px rgba(0, 90, 224, 0.22); } #SettingsContentReset { background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFFF, stop:1 #FBFBFB); border-color: rgba(0, 131, 255, 0.4); border-radius: 4; border-style: solid; border-width: 1; outline: none; padding: 3px 24px 4px 24px; color: #0699ff; font-size: 14px; } #SettingsContentReset:hover { background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #8ccfff, stop:1 #4bb8ff); color: #FFFFFF; border-color: rgba(0, 117, 243, 0.2); } #SettingsContentReset:pressed { background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #0b8cff, stop:1 #0aa1ff); color: #FFFFFF; border-color: rgba(29, 129, 255, 0.3); } Dtk--Widget--DWindowCloseButton { border-image: url(:/images/light/images/window_close_normal.svg); } Dtk--Widget--DWindowCloseButton:hover { border-image: url(:/images/light/images/window_close_hover.svg); } Dtk--Widget--DWindowCloseButton:pressed { border-image: url(:/images/light/images/window_close_press.svg); } Dtk--Widget--DLineEdit { color: black; border-radius: 3; background-color: rgba(255, 255, 255, 26);/*use as outside border*/ } Dtk--Widget--DLineEdit[alert="true"] QFrame#LineEditInsideFrame{ border-color: #FF8F00; } QFrame#LineEditInsideFrame {/*outside frame*/ background-color: rgba(255, 255, 255, 20%); border: 1px solid; border-radius: 3; border-color: rgba(0, 0, 0, 20%); } Dtk--Widget--DLineEdit #IconButton { border: 0px solid; border-left: 1px solid rgba(0, 0, 0, 20%); margin: 1px 2px 2px 0px; } Dtk--Widget--DLineEdit[alert="true"] #IconButton{ border-color: #FF8F00; } Dtk--Widget--DLineEdit #ClearButton { qproperty-normalPic: ":/images/light/images/clear_content_normal.svg"; qproperty-hoverPic: ":/images/light/images/clear_content_hover.svg"; qproperty-pressPic: "/images/light/images/clear_content_press.svg"; margin-right: 4px; } #AlertTooltip QLabel { color: #FF8F00; } deepin-movie-reborn-5.0.0/src/resources/qss/dark/dmr--MainWindow.theme000066400000000000000000000042461351125414100256520ustar00rootroot00000000000000dmr--MainWindow { background: transparent; border: 1px solid rgba(0, 0, 0, 100%); border-radius: 4px; } dmr--Titlebar { background: transparent; qproperty-borderBottom: rgba(0,0,0,100%); qproperty-borderShadowTop: rgba(255,255,255,5%); border-radius: 4px; } dmr--Titlebar[idle="true"] { qproperty-background: rgba(16,16,16,0.6); } dmr--Titlebar[idle="false"] { qproperty-background: rgba(16,16,16,0.8); } dmr--PlayerEngine, dmr--PlayerEngine * { background: transparent; } /* ---------- Mini Mode ----------------------------- */ Dtk--Widget--DImageButton#MiniPlayBtn { background: transparent; border: none; qproperty-normalPic: url(:/resources/icons/dark/mini/play-normal-mini.svg); qproperty-hoverPic: url(:/resources/icons/dark/mini/play-hover-mini.svg); qproperty-pressPic: url(:/resources/icons/dark/mini/play-press-mini.svg); } Dtk--Widget--DImageButton#MiniPauseBtn { background: transparent; border: none; qproperty-normalPic: url(:/resources/icons/dark/mini/pause-normal-mini.svg); qproperty-hoverPic: url(:/resources/icons/dark/mini/pause-hover-mini.svg); qproperty-pressPic: url(:/resources/icons/dark/mini/pause-press-mini.svg); } Dtk--Widget--DImageButton#MiniQuitMiniBtn { background: transparent; border: none; qproperty-normalPic: url(:/resources/icons/dark/mini/restore-normal-mini.svg); qproperty-hoverPic: url(:/resources/icons/dark/mini/restore-hover-mini.svg); qproperty-pressPic: url(:/resources/icons/dark/mini/restore-press-mini.svg); } Dtk--Widget--DImageButton#MiniCloseBtn { background: transparent; border: none; qproperty-normalPic: url(:/resources/icons/dark/mini/close-normal.svg); qproperty-hoverPic: url(:/resources/icons/dark/mini/close-hover.svg); qproperty-pressPic: url(:/resources/icons/dark/mini/close-press.svg); } Dtk--Widget--DImageButton#PlayState { background: transparent; border: none; qproperty-normalPic: url(:/resources/icons/dark/normal/play-big_normal.svg); qproperty-hoverPic: url(:/resources/icons/dark/normal/play-big_hover.svg); qproperty-pressPic: url(:/resources/icons/dark/normal/play-big_press.svg); } deepin-movie-reborn-5.0.0/src/resources/qss/dark/dmr--MovieInfoDialog.theme000066400000000000000000000010351351125414100266020ustar00rootroot00000000000000dmr--MovieInfoDialog { qproperty-backgroundColor: white; qproperty-borderColor: rgba(0, 0, 0, 0.2); } #MovieInfoTitle { qproperty-alignment: AlignCenter; color: black; font-size: 12px; } #MovieInfoSplit { border-top: 1px solid rgba(0, 0, 0, 0.1); } #MovieInfoKey { border: 1px solid transparent; qproperty-alignment: AlignRight; font-size: 11px; color: #606060; } #MovieInfoValue { border: 1px solid transparent; qproperty-alignment: AlignLeft; font-size: 11px; color: #000000; } deepin-movie-reborn-5.0.0/src/resources/qss/dark/dmr--NotificationWidget.theme000066400000000000000000000004401351125414100273600ustar00rootroot00000000000000#NotificationFrame { background: transparent; /* background: rgba(23, 23, 23, 0.8); border-radius: 4px; border: 1px outset rgba(255, 255, 255, 0.1); background-clip: padding; margin: 0; */ } #NotificationFrame QLabel { font-size: 12px; color: #ffffff; } deepin-movie-reborn-5.0.0/src/resources/qss/dark/dmr--PlayItemWidget.theme000066400000000000000000000023311351125414100264570ustar00rootroot00000000000000*[PlayItemThumb="true"] { margin-bottom: 2px; } *[PlayItemThumb="true"][ItemKind="local"] { qproperty-bg: url(:/resources/icons/dark/normal/film-bg.svg); } *[PlayItemThumb="true"][ItemKind="dvd"] { qproperty-bg: url(:/resources/icons/dark/normal/dvd.svg); } *[PlayItemThumb="true"][ItemKind="network"] { qproperty-bg: url(:/resources/icons/dark/normal/url.svg); } /* state Playing */ *[PlayItemThumb="true"][ItemState="1"] *[Name="true"] { font-size: 12px; color: #01bdff; } *[PlayItemThumb="true"][ItemState="1"] *[Time="true"] { font-size: 10px; color: rgba(1, 189, 255, 0.6); } /* state Normal */ *[PlayItemThumb="true"][ItemState="0"] *[Name="true"] { font-size: 12px; color: #ffffff; } *[PlayItemThumb="true"][ItemState="0"] *[Time="true"] { font-size: 10px; color: rgba(255, 255, 255, 0.6); } /* state Invalid */ *[PlayItemThumb="true"][ItemState="2"] *[Name="true"] { font-size: 12px; color: rgba(255, 255, 255, 0.5); } *[PlayItemThumb="true"][ItemState="2"] *[Time="true"] { font-size: 10px; font-weight: 500; color: rgba(249, 112, 79, 0.6); } /* when hovered */ *[PlayItemThumb="true"][hovered="true"] { background-color: rgba(255, 255, 255, 0.1); } deepin-movie-reborn-5.0.0/src/resources/qss/dark/dmr--PlaylistWidget.theme000066400000000000000000000007711351125414100265420ustar00rootroot00000000000000dmr--PlaylistWidget { background-color: rgba(20, 20, 20, 0.80); selection-color: transparent; selection-background-color: transparent; border-left: 1px outset rgba(255, 255, 255, 0.04); background-clip: padding; } Dtk--Widget--DImageButton#CloseBtn { qproperty-normalPic: url(:/resources/icons/dark/normal/close-normal.svg); qproperty-hoverPic: url(:/resources/icons/dark/normal/close-hover.svg); qproperty-pressPic: url(:/resources/icons/dark/normal/close-press.svg); } deepin-movie-reborn-5.0.0/src/resources/qss/dark/dmr--SubtitleItemWidget.theme000066400000000000000000000003031351125414100273420ustar00rootroot00000000000000dmr--SubtitleItemWidget[current="false"] * { color: rgba(255, 255, 255, 0.6); font-size: 12px; } dmr--SubtitleItemWidget[current="true"] * { color: #ffffff; font-size: 12px; } deepin-movie-reborn-5.0.0/src/resources/qss/dark/dmr--SubtitlesView.theme000066400000000000000000000004401351125414100263770ustar00rootroot00000000000000dmr--SubtitlesView QListWidget { selection-color: transparent; selection-background-color: transparent; } dmr--SubtitlesView QListWidget::item:selected * { color: #ffffff; } dmr--SubtitlesView QListWidget::item { color: rgba(255, 255, 255, 0.6); font-size: 12px; } deepin-movie-reborn-5.0.0/src/resources/qss/dark/dmr--Tip.theme000066400000000000000000000003221351125414100243210ustar00rootroot00000000000000#Tip { qproperty-background: rgba(49,49,49, 100%); qproperty-borderColor: rgba(0,0,0,10%); qproperty-radius: 4.0; } #TipIcon{ } #TipText { font-size: 12px; color: rgba(255,255,255,70%); } deepin-movie-reborn-5.0.0/src/resources/qss/dark/dmr--ToolboxProxy.theme000066400000000000000000000155101351125414100262620ustar00rootroot00000000000000dmr--ToolboxProxy[idle="false"] * { background: transparent; background-color: qlineargradient(x1:0 y1:0, x2:0 y2:1, stop:0.00000 transparent, stop:0.16666 transparent, stop:0.16667 rgba(16, 16, 16, 0.8), stop:1.00000 rgba(16, 16, 16, 0.8) ); border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; } dmr--ToolboxProxy[idle="true"] * { background-color: qlineargradient(x1:0 y1:0, x2:0 y2:1, stop:0.00000 transparent, stop:0.16666 transparent, stop:0.16667 rgba(16, 16, 16, 0.6), stop:1.00000 rgba(16, 16, 16, 0.6) ); border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; } dmr--ToolboxProxy[idle="false"] Dtk--Widget--DImageButton, dmr--ToolboxProxy[idle="false"] QLabel { background: transparent; } dmr--ToolboxProxy[idle="true"] Dtk--Widget--DImageButton, dmr--ToolboxProxy[idle="true"] QLabel { background: transparent; } Dtk--Widget--DImageButton#ListBtn { qproperty-normalPic: url(:/resources/icons/dark/normal/list-normal.svg); qproperty-hoverPic: url(:/resources/icons/dark/normal/list-hover.svg); qproperty-pressPic: url(:/resources/icons/dark/normal/list-press.svg); } Dtk--Widget--DImageButton#SubtitleBtn { qproperty-normalPic: url(:/resources/icons/dark/normal/Subtitle-normal.svg); qproperty-hoverPic: url(:/resources/icons/dark/normal/Subtitle-hover.svg); qproperty-pressPic: url(:/resources/icons/dark/normal/Subtitle-press.svg); } Dtk--Widget--DImageButton#PrevBtn { qproperty-normalPic: url(:/resources/icons/dark/normal/previous-normal.svg); qproperty-hoverPic: url(:/resources/icons/dark/normal/previous-hover.svg); qproperty-pressPic: url(:/resources/icons/dark/normal/previous-press.svg); } Dtk--Widget--DImageButton#NextBtn { qproperty-normalPic: url(:/resources/icons/dark/normal/next-normal.svg); qproperty-hoverPic: url(:/resources/icons/dark/normal/next-hover.svg); qproperty-pressPic: url(:/resources/icons/dark/normal/next-press.svg); } Dtk--Widget--DImageButton#PlayBtn { qproperty-normalPic: url(:/resources/icons/dark/normal/play-normal.svg); qproperty-hoverPic: url(:/resources/icons/dark/normal/play-hover.svg); qproperty-pressPic: url(:/resources/icons/dark/normal/play-press.svg); } Dtk--Widget--DImageButton#PauseBtn { qproperty-normalPic: url(:/resources/icons/dark/normal/pause-normal.svg); qproperty-hoverPic: url(:/resources/icons/dark/normal/pause-hover.svg); qproperty-pressPic: url(:/resources/icons/dark/normal/pause-press.svg); } Dtk--Widget--DImageButton#FsBtn { qproperty-normalPic: url(:/resources/icons/dark/normal/fullscreen-normal.svg); qproperty-hoverPic: url(:/resources/icons/dark/normal/fullscreen-hover.svg); qproperty-pressPic: url(:/resources/icons/dark/normal/fullscreen-press.svg); } Dtk--Widget--DImageButton#UnfsBtn { qproperty-normalPic: url(:/resources/icons/dark/normal/exit-fullscreen-normal.svg); qproperty-hoverPic: url(:/resources/icons/dark/normal/exit-fullscreen-hover.svg); qproperty-pressPic: url(:/resources/icons/dark/normal/exit-fullscreen-press.svg); } dmr--VolumeButton#VolHigh { qproperty-normalPic: url(:/resources/icons/dark/normal/audio-volume-high-normal.svg); qproperty-hoverPic: url(:/resources/icons/dark/normal/audio-volume-high-hover.svg); qproperty-pressPic: url(:/resources/icons/dark/normal/audio-volume-high-press.svg); } dmr--VolumeButton#VolMid { qproperty-normalPic: url(:/resources/icons/dark/normal/audio-volume-medium-normal.svg); qproperty-hoverPic: url(:/resources/icons/dark/normal/audio-volume-medium-hover.svg); qproperty-pressPic: url(:/resources/icons/dark/normal/audio-volume-medium-press.svg); } dmr--VolumeButton#VolLow { qproperty-normalPic: url(:/resources/icons/dark/normal/audio-volume-low-normal.svg); qproperty-hoverPic: url(:/resources/icons/dark/normal/audio-volume-low-hover.svg); qproperty-pressPic: url(:/resources/icons/dark/normal/audio-volume-low-press.svg); } dmr--VolumeButton#VolOff { qproperty-normalPic: url(:/resources/icons/dark/normal/audio-volume-off-normal.svg); qproperty-hoverPic: url(:/resources/icons/dark/normal/audio-volume-off-hover.svg); qproperty-pressPic: url(:/resources/icons/dark/normal/audio-volume-off-press.svg); } dmr--VolumeButton#VolMute { qproperty-normalPic: url(:/resources/icons/dark/normal/audio-volume-muted-blocked-panel-normal.svg); qproperty-hoverPic: url(:/resources/icons/dark/normal/audio-volume-muted-blocked-panel-hover.svg); qproperty-pressPic: url(:/resources/icons/dark/normal/audio-volume-muted-blocked-panel-press.svg); } #MovieProgress { background: transparent; } /* simulate dynamic expanding of tool proxy background */ /*#MovieProgress[Hover="true"]::groove:horizontal {*/ /*background-color: qlineargradient(x1:0 y1:0, x2:0 y2:1,*/ /*stop:0.00000 transparent, stop:0.33333 transparent,*/ /*stop:0.33334 rgba(16, 16, 16, 0.8), stop:0.50000 rgba(16, 16, 16, 0.8),*/ /*stop:0.50001 rgba(0, 0, 0, 0.0), stop:1 rgba(0, 0, 0, 0.0)*/ /*);*/ /*position: absolute;*/ /*left: 0px; right: 0px;*/ /*}*/ #MovieProgress[Hover="false"]::groove:horizontal { background: transparent; position: absolute; left: 0px; right: 0px; } #MovieProgress::handle:horizontal { background:transparent; margin: 5px -5px; } /*#MovieProgress[Hover="true"]::add-page:horizontal {*/ /*background-color: qlineargradient(x1:0 y1:0, x2:0 y2:1,*/ /*stop:0.00000 transparent, stop:0.33333 transparent,*/ /*stop:0.33334 rgba(0, 0, 0, 0.5), stop:0.37500 rgba(0, 0, 0, 0.5),*/ /*stop:0.37501 rgba(0, 0, 0, 0.03), stop:0.41666 rgba(0, 0, 0, 0.03),*/ /*stop:0.41667 rgba(0, 0, 0, 0.0), stop:1 rgba(0, 0, 0, 0.0)*/ /*);*/ /*}*/ /*#MovieProgress[Hover="true"]::sub-page:horizontal {*/ /*background-color: qlineargradient(x1:0 y1:0, x2:0 y2:1,*/ /*stop:0.00000 transparent, stop:0.33333 transparent,*/ /*stop:0.33334 #2eacff, stop:0.58333 #2eacff,*/ /*stop:0.58334 rgba(0, 0, 0, 0.0), stop:1 rgba(0, 0, 0, 0.0)*/ /*);*/ /*}*/ #MovieProgress[Hover="false"]::add-page:horizontal { background-color: qlineargradient(x1:0 y1:0, x2:0 y2:1, stop:0.00000 transparent, stop:0.50000 transparent, stop:0.50001 rgba(0, 0, 0, 0.5), stop:0.54166 rgba(0, 0, 0, 0.5), stop:0.54167 rgba(0, 0, 0, 0.03), stop:0.58333 rgba(0, 0, 0, 0.03), stop:0.58334 rgba(0, 0, 0, 0.0), stop:1 rgba(0, 0, 0, 0.0) ); } #MovieProgress[Hover="false"]::sub-page:horizontal { background-color: qlineargradient(x1:0 y1:0, x2:0 y2:1, stop:0.00000 transparent, stop:0.50000 transparent, stop:0.50001 #2eacff, stop:0.58333 #2eacff, stop:0.58334 rgba(0, 0, 0, 0.0), stop:1 rgba(0, 0, 0, 0.0) ); } deepin-movie-reborn-5.0.0/src/resources/qss/dark/dmr--VolumeSlider.theme000066400000000000000000000000001351125414100261700ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/src/resources/qss/light/000077500000000000000000000000001351125414100220755ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/src/resources/qss/light/DSettingsDialog.theme000066400000000000000000000060671351125414100261560ustar00rootroot00000000000000#DSettingsDialog{ qproperty-backgroundColor: white; qproperty-borderColor: rgba(0, 0, 0, 0.2); } #Navigation{ border: none; border-right: 1px solid rgba(0,0,0,0.1); } #NavigationBar{ border: none; } #ButtonGroupSingle { border: 1px solid rgba(0, 0, 0, 0.08); border-radius: 4.0px; } #ButtonGroupBegin { border: 1px solid rgba(0, 0, 0, 0.08); border-top-left-radius: 4.0px; border-bottom-left-radius: 4.0px; } #ButtonGroupBegin:checked { background-color: #2ca7f8; border: solid 1px rgba(0, 90, 224, 0.22); } #ButtonGroupMiddle { border-top: 1px solid rgba(0, 0, 0, 0.08); border-bottom: 1px solid rgba(0, 0, 0, 0.08); border-right: 1px solid rgba(0, 0, 0, 0.08); } #ButtonGroupMiddle:checked { background-color: #2ca7f8; border: solid 1px rgba(0, 90, 224, 0.22); } #ButtonGroupEnd { border: 1px solid rgba(0, 0, 0, 0.08); border-left: none; border-top-right-radius: 4.0px; border-bottom-right-radius: 4.0px; } #ButtonGroupEnd:checked { background-color: #2ca7f8; border: solid 1px rgba(0, 90, 224, 0.22); } #SettingsContentReset { background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #FFFFFF, stop:1 #FBFBFB); border-color: rgba(0, 131, 255, 0.4); border-radius: 4; border-style: solid; border-width: 1; outline: none; padding: 3px 24px 4px 24px; color: #0699ff; font-size: 14px; } #SettingsContentReset:hover { background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #8ccfff, stop:1 #4bb8ff); color: #FFFFFF; border-color: rgba(0, 117, 243, 0.2); } #SettingsContentReset:pressed { background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #0b8cff, stop:1 #0aa1ff); color: #FFFFFF; border-color: rgba(29, 129, 255, 0.3); } Dtk--Widget--DWindowCloseButton { border-image: url(:/images/light/images/window_close_normal.svg); } Dtk--Widget--DWindowCloseButton:hover { border-image: url(:/images/light/images/window_close_hover.svg); } Dtk--Widget--DWindowCloseButton:pressed { border-image: url(:/images/light/images/window_close_press.svg); } Dtk--Widget--DLineEdit { color: black; border-radius: 3; background-color: rgba(255, 255, 255, 26);/*use as outside border*/ } Dtk--Widget--DLineEdit[alert="true"] QFrame#LineEditInsideFrame{ border-color: #FF8F00; } QFrame#LineEditInsideFrame {/*outside frame*/ background-color: rgba(255, 255, 255, 20%); border: 1px solid; border-radius: 3; border-color: rgba(0, 0, 0, 20%); } Dtk--Widget--DLineEdit #IconButton { border: 0px solid; border-left: 1px solid rgba(0, 0, 0, 20%); margin: 1px 2px 2px 0px; } Dtk--Widget--DLineEdit[alert="true"] #IconButton{ border-color: #FF8F00; } Dtk--Widget--DLineEdit #ClearButton { qproperty-normalPic: ":/images/light/images/clear_content_normal.svg"; qproperty-hoverPic: ":/images/light/images/clear_content_hover.svg"; qproperty-pressPic: "/images/light/images/clear_content_press.svg"; margin-right: 4px; } #AlertTooltip QLabel { color: #FF8F00; } deepin-movie-reborn-5.0.0/src/resources/qss/light/dmr--MainWindow.theme000066400000000000000000000043061351125414100260350ustar00rootroot00000000000000 dmr--MainWindow { background: transparent; /* border: 1px solid rgba(0, 0, 0, 10%); border-radius: 4px; */ } dmr--Titlebar { /*background: transparent;*/ qproperty-background: qlineargradient(x1:0 y1:0, x2:0 y2:1, stop:0 rgba(255,255,255,100%), stop:1 rgba(248,248,248,100%) ); qproperty-borderBottom: rgba(0,0,0,10%); qproperty-borderShadowTop: rgba(255,255,255,5%); /*border-radius: 4px; */ } dmr--PlayerEngine, dmr--PlayerEngine * { background: transparent; } /* ---------- Mini Mode ----------------------------- */ Dtk--Widget--DImageButton#MiniPlayBtn { background: transparent; border: none; qproperty-normalPic: url(:/resources/icons/light/mini/play-normal-mini.svg); qproperty-hoverPic: url(:/resources/icons/light/mini/play-hover-mini.svg); qproperty-pressPic: url(:/resources/icons/light/mini/play-press-mini.svg); } Dtk--Widget--DImageButton#MiniPauseBtn { background: transparent; border: none; qproperty-normalPic: url(:/resources/icons/light/mini/pause-normal-mini.svg); qproperty-hoverPic: url(:/resources/icons/light/mini/pause-hover-mini.svg); qproperty-pressPic: url(:/resources/icons/light/mini/pause-press-mini.svg); } Dtk--Widget--DImageButton#MiniQuitMiniBtn { background: transparent; border: none; qproperty-normalPic: url(:/resources/icons/light/mini/restore-normal-mini.svg); qproperty-hoverPic: url(:/resources/icons/light/mini/restore-hover-mini.svg); qproperty-pressPic: url(:/resources/icons/light/mini/restore-press-mini.svg); } Dtk--Widget--DImageButton#MiniCloseBtn { background: transparent; border: none; qproperty-normalPic: url(:/resources/icons/light/mini/close-normal.svg); qproperty-hoverPic: url(:/resources/icons/light/mini/close-hover.svg); qproperty-pressPic: url(:/resources/icons/light/mini/close-press.svg); } Dtk--Widget--DImageButton#PlayState { background: transparent; border: none; qproperty-normalPic: url(:/resources/icons/light/normal/play-big_normal.svg); qproperty-hoverPic: url(:/resources/icons/light/normal/play-big_hover.svg); qproperty-pressPic: url(:/resources/icons/light/normal/play-big_press.svg); } deepin-movie-reborn-5.0.0/src/resources/qss/light/dmr--MovieInfoDialog.theme000066400000000000000000000010361351125414100267710ustar00rootroot00000000000000dmr--MovieInfoDialog { qproperty-backgroundColor: white; qproperty-borderColor: rgba(0, 0, 0, 0.2); } #MovieInfoTitle { qproperty-alignment: AlignCenter; color: black; font-size: 12px; } #MovieInfoSplit { border-top: 1px solid rgba(0, 0, 0, 0.1); } #MovieInfoKey { border: 1px solid transparent; qproperty-alignment: AlignRight; font-size: 11px; color: #606060; } #MovieInfoValue { border: 1px solid transparent; qproperty-alignment: AlignLeft; font-size: 11px; color: #000000; } deepin-movie-reborn-5.0.0/src/resources/qss/light/dmr--NotificationWidget.theme000066400000000000000000000005021351125414100275450ustar00rootroot00000000000000#NotificationFrame { background: transparent; /* border: 1px solid rgba(0, 0, 0, 0.1); border-radius: 4px; background-color: rgba(252, 252, 252, 0.8); */ } #NotificationFrame * { background: transparent; } #NotificationFrame QLabel { font-size: 12px; background: transparent; color: 0; } deepin-movie-reborn-5.0.0/src/resources/qss/light/dmr--PlayItemWidget.theme000066400000000000000000000023471351125414100266540ustar00rootroot00000000000000*[PlayItemThumb="true"] { margin-bottom: 2px; } *[PlayItemThumb="true"][ItemKind="local"] { qproperty-bg: url(:/resources/icons/light/normal/film-bg.svg); } *[PlayItemThumb="true"][ItemKind="dvd"] { qproperty-bg: url(:/resources/icons/light/normal/dvd.svg); } *[PlayItemThumb="true"][ItemKind="network"] { qproperty-bg: url(:/resources/icons/light/normal/url.svg); } /* state Playing */ *[PlayItemThumb="true"][ItemState="1"] *[Name="true"] { font-size: 12px; color: #2ca7f8; } *[PlayItemThumb="true"][ItemState="1"] *[Time="true"] { font-size: 10px; color: rgba(44, 167, 248, 0.6); } /* state Normal */ *[PlayItemThumb="true"][ItemState="0"] *[Name="true"] { font-size: 12px; color: #303030; } *[PlayItemThumb="true"][ItemState="0"] *[Time="true"] { font-size: 10px; color: rgba(48, 48, 48, 0.6); } /* state Invalid */ *[PlayItemThumb="true"][ItemState="2"] *[Name="true"] { font-size: 12px; color: #303030; color: rgba(48, 48, 48, 0.5); } *[PlayItemThumb="true"][ItemState="2"] *[Time="true"] { font-size: 10px; font-weight: 500; color: rgba(249, 112, 79, 0.8); } /* when hovered */ *[PlayItemThumb="true"][hovered="true"] { background-color: rgba(0, 0, 0, 0.1); } deepin-movie-reborn-5.0.0/src/resources/qss/light/dmr--PlaylistWidget.theme000066400000000000000000000007701351125414100267270ustar00rootroot00000000000000dmr--PlaylistWidget { background-color: rgba(252, 252, 252, 0.80); selection-color: transparent; selection-background-color: transparent; border-left: 1px outset rgba(0, 0, 0, 0.1); background-clip: padding; } Dtk--Widget--DImageButton#CloseBtn { qproperty-normalPic: url(:/resources/icons/light/normal/close-normal.svg); qproperty-hoverPic: url(:/resources/icons/light/normal/close-hover.svg); qproperty-pressPic: url(:/resources/icons/light/normal/close-press.svg); } deepin-movie-reborn-5.0.0/src/resources/qss/light/dmr--SubtitleItemWidget.theme000066400000000000000000000003101351125414100275260ustar00rootroot00000000000000dmr--SubtitleItemWidget[current="false"] * { color: rgba(23, 23, 23, 0.6); font-size: 12px; } dmr--SubtitleItemWidget[current="true"] * { color: rgb(23, 23, 23); font-size: 12px; } deepin-movie-reborn-5.0.0/src/resources/qss/light/dmr--SubtitlesView.theme000066400000000000000000000004321351125414100265660ustar00rootroot00000000000000dmr--SubtitlesView QListWidget { selection-color: transparent; selection-background-color: transparent; } dmr--SubtitlesView QListWidget::item { color: rgba(23, 23, 23, 0.6); font-size: 12px; } dmr--SubtitlesView QListWidget::item:selected { color: #ffffff; } deepin-movie-reborn-5.0.0/src/resources/qss/light/dmr--Tip.theme000066400000000000000000000003061351125414100245110ustar00rootroot00000000000000#Tip { qproperty-background: rgba(255,255,255,100%); qproperty-borderColor: rgba(0,0,0,10%); qproperty-radius: 4.0px; } #TipIcon{ } #TipText { font-size: 12px; color: black; } deepin-movie-reborn-5.0.0/src/resources/qss/light/dmr--ToolboxProxy.theme000066400000000000000000000147661351125414100264640ustar00rootroot00000000000000dmr--ToolboxProxy, dmr--ToolboxProxy * { background: transparent; background-color: qlineargradient(x1:0 y1:0, x2:0 y2:1, stop:0.00000 transparent, stop:0.16666 transparent, stop:0.16667 rgba(252, 252, 252, 0.88), stop:1.00000 rgba(252, 252, 252, 0.88) ); border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; } QLabel, Dtk--Widget--DImageButton { background: transparent; } Dtk--Widget--DImageButton#ListBtn { qproperty-normalPic: url(:/resources/icons/light/normal/list-normal.svg); qproperty-hoverPic: url(:/resources/icons/light/normal/list-hover.svg); qproperty-pressPic: url(:/resources/icons/light/normal/list-press.svg); } Dtk--Widget--DImageButton#SubtitleBtn { qproperty-normalPic: url(:/resources/icons/light/normal/Subtitle-normal.svg); qproperty-hoverPic: url(:/resources/icons/light/normal/Subtitle-hover.svg); qproperty-pressPic: url(:/resources/icons/light/normal/Subtitle-press.svg); } Dtk--Widget--DImageButton#PrevBtn { qproperty-normalPic: url(:/resources/icons/light/normal/previous-normal.svg); qproperty-hoverPic: url(:/resources/icons/light/normal/previous-hover.svg); qproperty-pressPic: url(:/resources/icons/light/normal/previous-press.svg); } Dtk--Widget--DImageButton#NextBtn { qproperty-normalPic: url(:/resources/icons/light/normal/next-normal.svg); qproperty-hoverPic: url(:/resources/icons/light/normal/next-hover.svg); qproperty-pressPic: url(:/resources/icons/light/normal/next-press.svg); } Dtk--Widget--DImageButton#PlayBtn { qproperty-normalPic: url(:/resources/icons/light/normal/play-normal.svg); qproperty-hoverPic: url(:/resources/icons/light/normal/play-hover.svg); qproperty-pressPic: url(:/resources/icons/light/normal/play-press.svg); } Dtk--Widget--DImageButton#PauseBtn { qproperty-normalPic: url(:/resources/icons/light/normal/pause-normal.svg); qproperty-hoverPic: url(:/resources/icons/light/normal/pause-hover.svg); qproperty-pressPic: url(:/resources/icons/light/normal/pause-press.svg); } Dtk--Widget--DImageButton#FsBtn { qproperty-normalPic: url(:/resources/icons/light/normal/fullscreen-normal.svg); qproperty-hoverPic: url(:/resources/icons/light/normal/fullscreen-hover.svg); qproperty-pressPic: url(:/resources/icons/light/normal/fullscreen-press.svg); } Dtk--Widget--DImageButton#UnfsBtn { qproperty-normalPic: url(:/resources/icons/light/normal/exit-fullscreen-normal.svg); qproperty-hoverPic: url(:/resources/icons/light/normal/exit-fullscreen-hover.svg); qproperty-pressPic: url(:/resources/icons/light/normal/exit-fullscreen-press.svg); } dmr--VolumeButton#VolHigh { qproperty-normalPic: url(:/resources/icons/light/normal/audio-volume-high-normal.svg); qproperty-hoverPic: url(:/resources/icons/light/normal/audio-volume-high-hover.svg); qproperty-pressPic: url(:/resources/icons/light/normal/audio-volume-high-press.svg); } dmr--VolumeButton#VolMid { qproperty-normalPic: url(:/resources/icons/light/normal/audio-volume-medium-normal.svg); qproperty-hoverPic: url(:/resources/icons/light/normal/audio-volume-medium-hover.svg); qproperty-pressPic: url(:/resources/icons/light/normal/audio-volume-medium-press.svg); } dmr--VolumeButton#VolLow { qproperty-normalPic: url(:/resources/icons/light/normal/audio-volume-low-normal.svg); qproperty-hoverPic: url(:/resources/icons/light/normal/audio-volume-low-hover.svg); qproperty-pressPic: url(:/resources/icons/light/normal/audio-volume-low-press.svg); } dmr--VolumeButton#VolOff { qproperty-normalPic: url(:/resources/icons/light/normal/audio-volume-off-normal.svg); qproperty-hoverPic: url(:/resources/icons/light/normal/audio-volume-off-hover.svg); qproperty-pressPic: url(:/resources/icons/light/normal/audio-volume-off-press.svg); } dmr--VolumeButton#VolMute { qproperty-normalPic: url(:/resources/icons/light/normal/audio-volume-muted-blocked-panel-normal.svg); qproperty-hoverPic: url(:/resources/icons/light/normal/audio-volume-muted-blocked-panel-hover.svg); qproperty-pressPic: url(:/resources/icons/light/normal/audio-volume-muted-blocked-panel-press.svg); } #MovieProgress { background: transparent; } /* simulate dynamic expanding of tool proxy background */ /*#MovieProgress[Hover="true"]::groove:horizontal {*/ /*background: transparent;*/ /*background-color: qlineargradient(x1:0 y1:0, x2:0 y2:1,*/ /*stop:0.00000 transparent, stop:0.33333 transparent,*/ /*stop:0.33334 rgba(252, 252, 252, 0.88), stop:0.50000 rgba(252, 252, 252, 0.88),*/ /*stop:0.50001 rgba(0, 0, 0, 0.0), stop:1 rgba(0, 0, 0, 0.0)*/ /*);*/ /*position: absolute;*/ /*left: 0px; right: 0px;*/ /*}*/ #MovieProgress[Hover="false"]::groove:horizontal { background: transparent; position: absolute; left: 0px; right: 0px; } #MovieProgress::handle:horizontal { background:transparent; margin: 5px -5px; } /*#MovieProgress[Hover="true"]::add-page:horizontal {*/ /*background: transparent;*/ /*background-color: qlineargradient(x1:0 y1:0, x2:0 y2:1,*/ /*stop:0.00000 transparent, stop:0.33333 transparent,*/ /*stop:0.33334 rgba(0, 0, 0, 0.1), stop:0.37500 rgba(0, 0, 0, 0.1),*/ /*stop:0.37501 rgba(255, 255, 255, 0.08), stop:0.41666 rgba(255, 255, 255, 0.08),*/ /*stop:0.41667 rgba(0, 0, 0, 0.0), stop:1 rgba(0, 0, 0, 0.0)*/ /*);*/ /*}*/ /*#MovieProgress[Hover="true"]::sub-page:horizontal {*/ /*background-color: qlineargradient(x1:0 y1:0, x2:0 y2:1,*/ /*stop:0.00000 transparent, stop:0.33333 transparent,*/ /*stop:0.33334 #2eacff, stop:0.58333 #2eacff,*/ /*stop:0.58334 rgba(0, 0, 0, 0.0), stop:1 rgba(0, 0, 0, 0.0)*/ /*);*/ /*}*/ #MovieProgress[Hover="false"]::add-page:horizontal { background: transparent; background-color: qlineargradient(x1:0 y1:0, x2:0 y2:1, stop:0.00000 transparent, stop:0.50000 transparent, stop:0.50001 rgba(0, 0, 0, 0.1), stop:0.54166 rgba(0, 0, 0, 0.1), stop:0.54167 rgba(255, 255, 255, 0.08), stop:0.58333 rgba(255, 255, 255, 0.08), stop:0.58334 rgba(0, 0, 0, 0.0), stop:1 rgba(0, 0, 0, 0.0) ); } #MovieProgress[Hover="false"]::sub-page:horizontal { background-color: qlineargradient(x1:0 y1:0, x2:0 y2:1, stop:0.00000 transparent, stop:0.50000 transparent, stop:0.50001 #2eacff, stop:0.58333 #2eacff, stop:0.58334 rgba(0, 0, 0, 0.0), stop:1 rgba(0, 0, 0, 0.0) ); } deepin-movie-reborn-5.0.0/src/resources/qss/light/dmr--VolumeSlider.theme000066400000000000000000000000001351125414100263560ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/src/test/000077500000000000000000000000001351125414100171255ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/src/test/CMakeLists.txt000066400000000000000000000006221351125414100216650ustar00rootroot00000000000000project(libdmr_test) set(CMAKE_AUTOMOC ON) set(CMD_NAME dmr_test) set(CMAKE_CXX_FLAGS "-std=c++1y -fpermissive -Wno-error") include_directories(${CMAKE_INCLUDE_CURRENT_DIR}) set(SRCS dmr_test.cpp) add_executable(${CMD_NAME} ${SRCS}) target_include_directories(${CMD_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/../libdmr ${PROJECT_SOURCE_DIR}) target_link_libraries(${CMD_NAME} Qt5::Widgets dmr) deepin-movie-reborn-5.0.0/src/test/dmr_test.cpp000066400000000000000000000103131351125414100214500ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include #include #include #include class Window: public QWidget { Q_OBJECT public: Window() { auto l = new QVBoxLayout(this); //if (dmr::CompositingManager::get().composited()) { //dmr::CompositingManager::get().overrideCompositeMode(false); //} player = new dmr::PlayerWidget; l->addWidget(player); QObject::connect(&player->engine(), &dmr::PlayerEngine::stateChanged, [=]() { qDebug() << "----------------new state: " << player->engine().state(); }); player->engine().changeVolume(120); auto h = new QHBoxLayout(this); auto play = new QPushButton("Play"); connect(play, &QPushButton::clicked, &player->engine(), &dmr::PlayerEngine::play); h->addWidget(play); auto pause = new QPushButton("Pause"); connect(pause, &QPushButton::clicked, &player->engine(), &dmr::PlayerEngine::pauseResume); h->addWidget(pause); auto stop = new QPushButton("stop"); connect(stop, &QPushButton::clicked, &player->engine(), &dmr::PlayerEngine::stop); h->addWidget(stop); auto forward = new QPushButton("forward"); connect(forward, &QPushButton::clicked, [=]() { player->engine().seekForward(60); }); h->addWidget(forward); auto volumeUp = new QPushButton("volUp"); connect(volumeUp, &QPushButton::clicked, &player->engine(), &dmr::PlayerEngine::volumeUp); h->addWidget(volumeUp); auto volumeDown = new QPushButton("volDown"); connect(volumeDown, &QPushButton::clicked, &player->engine(), &dmr::PlayerEngine::volumeDown); h->addWidget(volumeDown); auto keep = new QPushButton("KeepOpen"); connect(keep, &QPushButton::clicked, &player->engine(), [this]() { this->player->engine().setBackendProperty("keep-open", "yes"); }); this->player->engine().setBackendProperty("pause-on-start", "true"); h->addWidget(keep); l->addLayout(h); setLayout(l); } void play(const QUrl& url) { if (player->engine().isPlayableFile(url)) player->play(url); } private: dmr::PlayerWidget *player {nullptr}; }; int main(int argc, char *argv[]) { //dmr::CompositingManager::detectOpenGLEarly(); QApplication app(argc, argv); // required by mpv setlocale(LC_NUMERIC, "C"); dmr::Backend::setDebugLevel(dmr::Backend::DebugLevel::Debug); auto mw = new Window; mw->resize(400, 300); mw->show(); if (argc == 2) mw->play(QString::fromUtf8(argv[1])); app.exec(); delete mw; return 0; } #include "dmr_test.moc" deepin-movie-reborn-5.0.0/src/theme.qrc000066400000000000000000000005011351125414100177530ustar00rootroot00000000000000 resources/qss/dark/DSettingsDialog.theme resources/qss/light/DSettingsDialog.theme deepin-movie-reborn-5.0.0/src/translations/000077500000000000000000000000001351125414100206675ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/src/translations/deepin-movie.qm000066400000000000000000000000201351125414100235770ustar00rootroot00000000000000<¸dÊÍ!¿`¡½Ưdeepin-movie-reborn-5.0.0/src/translations/deepin-movie.ts000066400000000000000000000700041351125414100236210ustar00rootroot00000000000000 QObject Deepin Movie Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Invalid folder Open folder You don't have permission to operate this folder Auto add similar files to play Clear playlist when exit Show video preview on mouseover Open a new player for each file played Pause when minimized Remember playback position Path Basic Play Screenshot Shortcuts File Frame/Sound Playback Subtitle Font Style Restore Defaults Open file Open next Open previous Mini mode Mute Next frame Previous frame Volume down Volume up Speed up Speed down Fullscreen Pause/Play Playlist Reset speed Rewind Forward Burst screenshot Film screenshot 0.5s backward 0.5s forward Font Font Size UrlDialog Cancel Confirm Please enter the URL: dmr::ActionFactory Settings Fullscreen Always on Top Film info Open file Open folder Light theme Open URL Open CD/DVD Mini Mode Play Mode Order Play Shuffle Play Single Play Single Loop List Loop Frame Default Clockwise Counterclockwise Next frame Previous frame Sound Channel Stereo Left channel Right channel Track Subtitle Load Online Search Select Hide Encodings Screenshot Film Screenshot Burst Shooting Playlist Film Info Clear playlist Display in file manager dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save dmr::MainWindow Load successfully Load failed No device found Parse Failed Open folder Open file All videos (%1) Muted Volume: %1% Subtitle %1: %2s delayed advanced Speed: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Movie Screenshot Saved to The screenshot is saved Failed to save the screenshot Invalid file: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Resolution: File Size: Duration: File Path: dmr::MpvProxy [internal] dmr::PlayItemWidget File does not exist dmr::Settings %1/DMovie%2.jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Previous Next Subtitles Playlist Fullscreen Play/Pause Exit fullscreen Pause deepin-movie-reborn-5.0.0/src/translations/deepin-movie_af.ts000066400000000000000000000645271351125414100243040ustar00rootroot00000000000000 QObject Deepin Movie Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Invalid folder Open folder You don't have permission to operate this folder Auto add similar files to play Clear playlist when exit Show video preview on mouseover Open a new player for each file played Pause when minimized Remember playback position Path Basic Play Screenshot Skermkiekie Shortcuts File Frame/Sound Playback Subtitle Font Style Restore Defaults Open file Open next Open previous Mini mode Mute Demp Next frame Previous frame Volume down Volume af Volume up Volume op Speed up Speed down Fullscreen Volskerm Pause/Play Playlist Reset speed Rewind Forward Burst screenshot Film screenshot 0.5s backward 0.5s forward Font Font Size UrlDialog Cancel Kanselleer Confirm Bevestig Please enter the URL: dmr::ActionFactory Settings Fullscreen Volskerm Always on Top Film info Open file Open folder Light theme Open URL Open CD/DVD Mini Mode Play Mode Order Play Shuffle Play Single Play Single Loop List Loop Frame Default Standaard Clockwise Counterclockwise Next frame Previous frame Sound Klank Channel Kanaal Stereo Left channel Right channel Track Subtitle Load Online Search Select Hide Encodings Screenshot Skermkiekie Film Screenshot Burst Shooting Playlist Film Info Clear playlist Display in file manager dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save Stoor dmr::MainWindow Load successfully Load failed No device found Parse Failed Open folder Open file All videos (%1) Muted Volume: %1% Subtitle %1: %2s delayed advanced Speed: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Movie Screenshot Saved to The screenshot is saved Failed to save the screenshot Invalid file: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Resolution: File Size: Duration: File Path: dmr::MpvProxy [internal] dmr::PlayItemWidget File does not exist dmr::Settings %1/DMovie%2.jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Previous Vorige Next Volgende Subtitles Playlist Fullscreen Volskerm Play/Pause Speel/Pouse Exit fullscreen Pause Pouse deepin-movie-reborn-5.0.0/src/translations/deepin-movie_am_ET.ts000066400000000000000000000716771351125414100247070ustar00rootroot00000000000000 QObject Deepin Movie ሙቪ Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. ዲá•á¢á• ሙቪ በ ጥሩ-የ ተዘጋጀ á¥á“ የ ሙሉ-ገጽታ ቪዲዮ ማጫወቻ áá‹: ድá•በሮቹ በ ቀላሉ የ ተዘጋጠá“ቸá‹: የ á á«á‰£á‰¢ á¥á“ በርá«á‰³ የ ቪዲዮ á á‰€áˆ«áˆ¨á‰¦á‰½á• á‹­á‹°áŒá‹áˆ Invalid folder ዋጋ የሌለዠááˆá‹°áˆ­ Open folder You don't have permission to operate this folder á¥áˆ­áˆµá‹ ይህᕠááˆá‹°áˆ­ ለ መጠቀሠበቂ áቃድ የለá‹á‰µáˆ Auto add similar files to play በራሱ ተመሳሳይ á‹á‹­áˆá‰½ ለ ማጫወቻ መጨመሪያ Clear playlist when exit በáˆá‹ˆáŒ£ áŒá‹œ የ ማጫወቻá‹á• á‹áˆ­á‹áˆ­ ማጽጃ Show video preview on mouseover á á‹­áŒ¥ በላዩ ላይ ሲá•ሳáˆá የ ቪዲዮ ቅድመ á¥á‹­á‰³ ማሳያ Open a new player for each file played ለáˆáŒ«á‹ˆá‰°á‹ á¥á‹«á•ዳá•ዱ á‹á‹­áˆ á á‹²áˆµ ማጫወቻ መá­áˆá‰» Pause when minimized በáˆá‹«á•ስ áŒá‹œ ማስቆáˆá‹« Remember playback position የ መáˆáˆ¶ ማጫወቻ ቦታ á áˆµá‰³á‹áˆµ Path መá•ገድ Basic መሰረታዠPlay ማጫወቻ Screenshot መመáˆá¨á‰»á‹á• áቶ ማá•ሻ Shortcuts á á‰‹áˆ«áŒ­ File á‹á‹­áˆ Frame/Sound á­áˆá/ዽáˆá… Playback በድጋሠማጫወቻ Subtitle á•ዑስ á áˆ­á¥áˆµá‰µ Font Style የ áደሠዘዴ Restore Defaults áባር á¥á•á‹° áበር መመለሻ Open file á‹á‹­áˆ መá­áˆá‰» Open next የáˆá‰€áŒ¥áˆˆá‹á• መá­áˆá‰» Open previous ቀደሠያለá‹á• መá­áˆá‰» Mini mode በትá•ሽ ዘዴ Mute መቀáሻ Next frame Previous frame Volume down መጠᕠመቀáሻ Volume up መጠᕠመጨመሪያ Speed up áጥáት መጨመሪያ Speed down áጥáት መቀáሻ Fullscreen በሙሉ መመáˆá¨á‰» ዘዴ Pause/Play ማጫወቻ/ማስቆáˆá‹« Playlist የማጫወቻ á‹áˆ­á‹áˆ­ Reset speed áጥáት á¥á•á‹° áበር መመለሻ Rewind ወደ á‹áˆ‹ ማጠá•ጠᛠForward ወደ áት Burst screenshot áá•ዳታ የ መመáˆá¨á‰» áቶ Film screenshot የ ááˆáˆ መመáˆá¨á‰» áቶ ማá•ሻ 0.5s backward 0.5s ወደ á‹áˆ‹ 0.5s forward 0.5s ወደ áት Font áደሠFont Size የ áደሠመጠá•: UrlDialog Cancel መሰረዣ Confirm ማረጋገጫ Please enter the URL: á¥á‰£á­á‹á• ያስገቡ URL: dmr::ActionFactory Settings ማሰá“ጃá‹á‰½ Fullscreen በሙሉ መመáˆá¨á‰» ዘዴ Always on Top áˆáˆ áŒá‹œ ᨠላይ Film info የ ááˆáˆ መረጃ Open file á‹á‹­áˆ መá­áˆá‰» Open folder Light theme Open URL URL መá­áˆá‰» Open CD/DVD ሲዲ/ዲቪዲ መá­áˆá‰» Mini Mode በ ትá•ሽ ዘዴ Play Mode ማጫወቻ ዘዴ Order Play በ ተራ ማጫወቻ Shuffle Play መበወዣ Single Play áጠላ ማጫወቻ Single Loop áጠላ ዙር List Loop á‹áˆ­á‹áˆ­ ዙር Frame á­áˆá Default áባር Clockwise ᨠáŒáˆ« ወደ ቀá Counterclockwise ᨠቀá ወደ áŒáˆ« Next frame Previous frame Sound ድáˆá… Channel ጣቢያ Stereo ስቴሪዮ Left channel የ áŒáˆ« ጣቢያ Right channel የ ቀá ጣቢያ Track ተረᛠSubtitle á•ዑስ á áˆ­á¥áˆµá‰µ Load መጫᛠOnline Search በ መስመር ላይ መáˆáˆˆáŒá‹« Select á‹­áˆáˆ¨áŒ¡ Hide መደበቂያ Encodings መቀየሪያ Screenshot መመáˆá¨á‰»á‹á• áቶ ማá•ሻ Film Screenshot የ ááˆáˆ መመáˆá¨á‰» áቶ ማá•ሻ Burst Shooting áá•ዳታ áቶ ማá•ሻ Playlist የማጫወቻ á‹áˆ­á‹áˆ­ Film Info የ ááˆáˆ መረጃ Clear playlist á‹áˆ­á‹áˆ­ ማጫወቻ ማጽጃ Display in file manager በ á‹á‹­áˆ á áˆµá‰°á‹³á‹³áˆª á¥áˆµáŒ¥ ማሳያ dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save ማስቀመጫ dmr::MainWindow Load successfully ተሳá­á‰¶ ተጭá—ሠLoad failed መጫᕠá áˆá‰°á‰»áˆˆáˆ No device found áˆá•ሠá á«áˆ á áˆá‰°áŒˆá˜áˆ Parse Failed መተá•ተᕠá áˆá‰°á‰»áˆˆáˆ Open folder Open file á‹á‹­áˆ መá­áˆá‰» All videos (%1) áˆáˆ‰á•ሠቪዲዮá‹á‰½ (*) Muted መቀáሻ Volume: %1% መጠá•: %1 Subtitle %1: %2s á•ዑስ á áˆ­á¥áˆµá‰µ %1: %2s delayed ዘáŒá‹­á‰·áˆ advanced የረቀቀ Speed: %1x áጥáት: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View መመáˆá¨á‰» Movie Screenshot የ ሙቪ መመáˆá¨á‰» áቶ ማá•ሻ Saved to ተቀáˆáŒ§áˆ ወደ The screenshot is saved የ መመáˆá¨á‰»á‹ áቶ ተቀáˆáŒ§áˆ Failed to save the screenshot Invalid file: %1 ዋጋ የሌለዠá‹á‹­áˆ: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: የá‹á‹­áˆ á á‹­áት: Resolution: ሪá‹áˆáˆ½á•: File Size: የ áደሠመጠá•: Duration: የáˆáˆáŒ€á‹ áŒá‹œ File Path: የ á‹á‹­áˆ መá•ገድ dmr::MpvProxy [internal] [የ á‹áˆµáŒ¥] dmr::PlayItemWidget File does not exist á‹á‹­áˆ‰ ቀደሠብሠá áˆáበረሠdmr::Settings %1/DMovie%2.jpg %1/DMovie%2.jpg %1/DMovie%2(%3).jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play ማጫወቻ Previous ቀደሠያለዠNext ይቀጥሉ Subtitles á•ዑስ á áˆ­á¥áˆµá‰¶á‰½ Playlist የማጫወቻ á‹áˆ­á‹áˆ­ Fullscreen በሙሉ መመáˆá¨á‰» ዘዴ Play/Pause ማጫወቻ/ማስቆáˆá‹« Exit fullscreen ᨠሙሉ መመáˆá¨á‰»á‹ ዘዴ መá‹áŒ« Pause ማስቆáˆá‹« deepin-movie-reborn-5.0.0/src/translations/deepin-movie_ar.ts000066400000000000000000000710741351125414100243130ustar00rootroot00000000000000 QObject Deepin Movie Ø£Ùلام دÙÙØ¨Ù† Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. مشغل Ø£Ùلام Ø¯ÙØ¨ÙÙ† : مشغل ÙÙØ¯ÙÙˆ مصمم بشكل Ø¬ÙØ¯ وكامل Ø§Ù„Ù…ÙˆØ§ØµÙØ§Øª مع تصمÙÙ… Ø¨Ø³ÙØ· بلا حدود. وهو ÙØ¯Ø¹Ù… تشغÙÙ„ الوسائط المتعددة Ø§Ù„Ù…Ø­Ù„ÙØ© والمتدÙقة مع ØµÙØº الÙÙØ¯ÙÙˆ المتنوعة. Invalid folder مجلد ØºÙØ± صالح Open folder ÙØªØ­ مجلد You don't have permission to operate this folder Ù„ÙØ³ لدÙÙƒ إذن لتنÙÙØ° Ø¹Ù…Ù„ÙØ© Ù٠هذا المجلد Auto add similar files to play Ø¥Ø¶Ø§ÙØ© Ø§Ù„Ù…Ù„ÙØ§Øª المشابهة ØªÙ„Ù‚Ø§Ø¦ÙØ§Ù‹ للتشغÙÙ„ Clear playlist when exit مسح قائمة التشغÙÙ„ عند الخروج Show video preview on mouseover عرض معاÙنة الÙÙØ¯ÙÙˆ على ØªÙ…Ø±ÙØ± مؤشر Ø§Ù„ÙØ£Ø±Ø© Open a new player for each file played ÙØªØ­ مشغل Ø¬Ø¯ÙØ¯ لكل Ù…Ù„Ù Ù‚ÙØ¯ التشغÙÙ„ Pause when minimized Ø¥Ùقا٠مؤقت عند Ø§Ù„ØªØµØºÙØ± Remember playback position تذكر وضع التشغÙÙ„ Path مسار Basic أساس٠Play تشغÙÙ„ Screenshot لقطة للشاشة Shortcuts الإختصارات File المل٠Frame/Sound الإطار / الصوت Playback التشغÙÙ„ Subtitle الترجمة Font Style نمط الخط Restore Defaults استعادة Ø§Ù„Ø§ÙØªØ±Ø§Ø¶Ùات Open file ÙØªØ­ مل٠Open next ÙØªØ­ التال٠Open previous ÙØªØ­ السابق Mini mode وضع مصغر Mute صامت Next frame الإطار التال٠Previous frame الإطار السابق Volume down Ø®ÙØ¶ الصوت Volume up Ø±ÙØ¹ الصوت Speed up ØªØ³Ø±ÙØ¹ Speed down ØªØ¨Ø·ÙØ¦ Fullscreen ملء الشاشة Pause/Play Ø¥Ùقا٠/ تشغÙÙ„ Playlist قائمة التشغÙÙ„ Reset speed إعادة تعÙÙÙ† السرعة Rewind رجوع Forward للأمام Burst screenshot Ø§Ù†Ø¯ÙØ§Ø¹ لقطة الشاشة Film screenshot لقطة شاشة للÙلم 0.5s backward ØªØ£Ø®ÙØ± 0.5 Ø«Ø§Ù†ÙØ© 0.5s forward تقدÙÙ… 0.5 Ø«Ø§Ù†ÙØ© Font الخط Font Size حجم الخط: UrlDialog Cancel إلغاء Confirm ØªØ£ÙƒÙØ¯ Please enter the URL: ÙØ±Ø¬Ù‰ إدخال الرابط : dmr::ActionFactory Settings إعدادات Fullscreen ملء الشاشة Always on Top دائماً Ù٠المقدمة Film info معلومات الÙلم Open file ÙØªØ­ مل٠Open folder ÙØªØ­ مجلد Light theme السمة Ø§Ù„ÙØ§ØªØ­Ø© Open URL ÙØªØ­ رابط Open CD/DVD ÙØªØ­ قرص CD/DVD Mini Mode الوضع المصغر Play Mode وضع التشغÙÙ„ Order Play ØªØ±ØªÙØ¨ التشغÙÙ„ Shuffle Play خلط التشغÙÙ„ Single Play تشغÙÙ„ Ù…ÙØ±Ø¯ Single Loop تكرار Ù…ÙØ±Ø¯ List Loop تكرار القائمة Frame إطار Default Ø§ÙØªØ±Ø§Ø¶Ù Clockwise بإتجاه عقارب الساعة Counterclockwise عكس عقارب الساعة Next frame الإطار التال٠Previous frame الإطار السابق Sound الصوت Channel القناة Stereo استرÙÙˆ Left channel القناة Ø§Ù„ÙØ³Ø±Ù‰ Right channel القناة الÙمنى Track المسار Subtitle الترجمة Load تحمÙÙ„ Online Search بحث Ù٠الانترنت Select ØªØ­Ø¯ÙØ¯ Hide Ø¥Ø®ÙØ§Ø¡ Encodings Ø§Ù„ØªØ±Ù…ÙØ² Screenshot لقطة للشاشة Film Screenshot لقطة شاشة للÙلم Burst Shooting إطلاق التدÙÙ‚ Playlist قائمة التشغÙÙ„ Film Info معلومات الÙلم Clear playlist مسح قائمة التشغÙÙ„ Display in file manager عرض ÙÙ Ù…Ø¯ÙØ± Ø§Ù„Ù…Ù„ÙØ§Øª dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save Ø­ÙØ¸ dmr::MainWindow Load successfully تم التحمÙÙ„ بنجاح Load failed ÙØ´Ù„ التحمÙÙ„ No device found لم ÙØªÙ… العثور على جهاز Parse Failed ÙØ´Ù„ التحلÙÙ„ Open folder ÙØªØ­ مجلد Open file ÙØªØ­ مل٠All videos (%1) ÙƒØ§ÙØ© الÙÙØ¯Ùوهات (%1) Muted صامت Volume: %1% الصوت: %1% Subtitle %1: %2s ترجمة %1 : %2s delayed مؤخر advanced متقدم Speed: %1x السرعة: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View عرض Movie Screenshot لقطة شاشة للÙÙلم Saved to Ø­ÙØ¸ ÙÙ The screenshot is saved تم Ø­ÙØ¸ لقطة الشاشة Failed to save the screenshot Invalid file: %1 Ù…Ù„Ù ØºÙØ± صالح : %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: نوع الملÙ: Resolution: الدقة : File Size: حجم الملÙ: Duration: المدة: File Path: مسار الملÙ: dmr::MpvProxy [internal] [داخلÙ] dmr::PlayItemWidget File does not exist Ø§Ù„Ù…Ù„Ù ØºÙØ± موجود dmr::Settings %1/DMovie%2.jpg %1/DMovie%2.jpg %1/DMovie%2(%3).jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play تشغÙÙ„ Previous السابق Next التال٠Subtitles الترجمات Playlist قائمة التشغÙÙ„ Fullscreen ملء الشاشة Play/Pause تشغÙÙ„/Ø¥Ùقا٠مؤقت Exit fullscreen خروج من ملء الشاشة Pause Ø¥Ùقا٠مؤقت deepin-movie-reborn-5.0.0/src/translations/deepin-movie_ast.ts000066400000000000000000000666631351125414100245100ustar00rootroot00000000000000 QObject Deepin Movie Deepin Movie Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. PelĂ­cules Deepin ye un reproductor de videu bien diseĂ±Ă¡u y completu con un diseñu cenciellu ensin berbesos. Sofita la reproducciĂ³n llocal y remota de contenĂ­u con formatos de videu mĂºltiples. Invalid folder La carpeta nun ye vĂ¡lida Open folder You don't have permission to operate this folder Nun tienes permisu pa operar nesta carpeta Auto add similar files to play Clear playlist when exit Show video preview on mouseover Open a new player for each file played Abrir una ventana nueva por cada ficheru que se reproduza Pause when minimized Posar al minimizar Remember playback position Recordar posiciĂ³n de reproducciĂ³n Path CamĂ­n Basic BĂ¡sicu Play Reproducir Screenshot Capturar pantalla Shortcuts Atayos File Ficheru Frame/Sound Cuadros/SonĂ­u Playback ReproducciĂ³n Subtitle Font Style Estilu de la fonte Restore Defaults Reafitar valores Open file Abrir un ficheru Open next Abrir siguiente Open previous Abrir previu Mini mode Mou mini Mute Silenciar Next frame Previous frame Volume down Baxar volume Volume up Xubir volume Speed up Acelerar Speed down Fullscreen Panatalla completa Pause/Play Posar/Reproducir Playlist Llista de reproducciĂ³n Reset speed Refitar velocidĂ¡ Rewind Rebobinar Forward Avanzar Burst screenshot Film screenshot 0.5s backward 0.5s forward Font Fonte Font Size Tamañu de la fonte UrlDialog Cancel Encaboxar Confirm Confirmar Please enter the URL: dmr::ActionFactory Settings Axustes Fullscreen Panatalla completa Always on Top Siempres enriba Film info InformaciĂ³n de pelĂ­cula Open file Abrir un ficheru Open folder Light theme Open URL Abrir una URL Open CD/DVD Abrir un CD/DVD Mini Mode Mou mini Play Mode Mou de reproducciĂ³n Order Play Shuffle Play ReproducciĂ³n al debalu Single Play Single Loop Una repiticiĂ³n List Loop RepiticiĂ³n del llistĂ¡u Frame Marcu Default Por defeutu Clockwise Counterclockwise Next frame Previous frame Sound SonĂ­u Channel Canal Stereo Estereu Left channel Canal esquierda Right channel Canal drecha Track Pista Subtitle Load Cargar Online Search Gueta en llinia Select Esbillar Hide Anubrir Encodings Codificaciones Screenshot Capturar pantalla Film Screenshot Captura de pelĂ­cula Burst Shooting Playlist Llista de reproducciĂ³n Film Info InformaciĂ³n de pelĂ­cula Clear playlist Llimpiar llista de reproducciĂ³n Display in file manager Amosar nel xestor de ficheros dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save Guardar dmr::MainWindow Load successfully Load failed No device found Nun s'alcontraron preseos Parse Failed FallĂ³ l'analĂ­s Open folder Open file Abrir un ficheru All videos (%1) Tolos vĂ­deos (%1) Muted SIlenciĂ¡u Volume: %1% Volume: %1% Subtitle %1: %2s delayed advanced Speed: %1x VelocidĂ¡: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Ver Movie Screenshot Saved to GuardĂ³se en The screenshot is saved GuardĂ³se la captura de pantalla Failed to save the screenshot Invalid file: %1 Ficheru non vĂ¡lidu: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Triba de ficheru: Resolution: ResoluciĂ³n: File Size: Tamañu de ficheru: Duration: DuraciĂ³n: File Path: CamĂ­n de ficheru: dmr::MpvProxy [internal] dmr::PlayItemWidget File does not exist Nun esiste'l ficheru dmr::Settings %1/DMovie%2.jpg %1/DMovie%2.jpg %1/DMovie%2(%3).jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Reproducir Previous Previo Next Siguiente Subtitles SotĂ­tulos Playlist Llista de reproducciĂ³n Fullscreen Panatalla completa Play/Pause Reproducir/Posar Exit fullscreen Colar de pantalla completa Pause Posar deepin-movie-reborn-5.0.0/src/translations/deepin-movie_az.ts000066400000000000000000000651611351125414100243230ustar00rootroot00000000000000 QObject Deepin Movie Deepin Film Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Invalid folder Open folder QovluÄŸu aç You don't have permission to operate this folder Auto add similar files to play Clear playlist when exit Show video preview on mouseover Open a new player for each file played Pause when minimized Remember playback position Path Basic Play Oxut Screenshot Ekran görĂ¼ntĂ¼sĂ¼ çəkmÉ™k Shortcuts Qısayollar File Fayl Frame/Sound ÇərçivÉ™/SÉ™s Playback Oynatma Subtitle Font Style Restore Defaults Open file Fayl aç Open next Sonrakını aç Open previous ÆvvÉ™lkini aç Mini mode Mini forma Mute SÉ™ssiz Next frame Previous frame Volume down SÉ™si azalt Volume up SÉ™si çoxalt Speed up Speed down Fullscreen Tam ekran Pause/Play FasilÉ™/Oynat Playlist Oxunma siyahısı Reset speed Rewind Forward İrÉ™li Burst screenshot Film screenshot 0.5s backward 0.5s forward Font Årift Font Size UrlDialog Cancel İmtina Confirm TÉ™sdiqlÉ™ Please enter the URL: dmr::ActionFactory Settings TÉ™nzimlÉ™mÉ™lÉ™r Fullscreen Tam ekran Always on Top Film info Open file Fayl aç Open folder QovluÄŸu aç Light theme Open URL URL aç Open CD/DVD Mini Mode Play Mode Order Play Shuffle Play Single Play Single Loop List Loop Frame ÇərçivÉ™ Default Varsayılan Clockwise Counterclockwise Next frame Previous frame Sound SÉ™s Channel Kanal Stereo Stereo Left channel Right channel Track Subtitle Load Online Search Select Hide Encodings Screenshot Ekran görĂ¼ntĂ¼sĂ¼ çəkmÉ™k Film Screenshot Burst Shooting Playlist Oxunma siyahısı Film Info Clear playlist Oynatma siyahısını tÉ™mizlÉ™ Display in file manager dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save Saxla dmr::MainWindow Load successfully Load failed No device found Parse Failed Open folder QovluÄŸu aç Open file Fayl aç All videos (%1) Muted SÉ™ssiz Volume: %1% Subtitle %1: %2s delayed advanced Speed: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Movie Screenshot Filmin ekran görĂ¼ntĂ¼sĂ¼nĂ¼ çəkmÉ™k Saved to The screenshot is saved Failed to save the screenshot Invalid file: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Resolution: File Size: Duration: File Path: dmr::MpvProxy [internal] dmr::PlayItemWidget File does not exist dmr::Settings %1/DMovie%2.jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Oxut Previous ÆvvÉ™lki Next Sonrakı Subtitles Alt yazılar Playlist Oxunma siyahısı Fullscreen Tam ekran Play/Pause Oxut/FasilÉ™ Exit fullscreen Tam ekrandan çıx Pause Dayandır deepin-movie-reborn-5.0.0/src/translations/deepin-movie_bg.ts000066400000000000000000000726601351125414100243030ustar00rootroot00000000000000 QObject Deepin Movie Deepin Đ¤Đ¸Đ»Đ¼Đ¸ Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Deepin Đ’Đ¸Đ´ĐµĐ¾ е ĐºÑ€Đ°ÑĐ¸Đ² и Đ²Đ¸ÑĐ¾ĐºĐ¾-Ñ„ÑƒĐ½ĐºÑ†Đ¸Đ¾Đ½Đ°Đ»ĐµĐ½ Đ²Đ¸Đ´ĐµĐ¾ Đ¿Đ»ĐµÑÑ€ Ñ Đ¸Đ·ĐºĐ»ÑÑ‡Đ¸Ñ‚ĐµĐ»Đ½Đ¾ Đ¾Đ¿Ñ€Đ¾ÑÑ‚ĐµĐ½ Đ´Đ¸Đ·Đ°Đ¹Đ½. Đ¢Đ¾Đ¹ Đ¿Đ¾Đ´Đ´ÑÑ€Đ¶Đ° Đ¸Đ·Đ¿ÑĐ»Đ½ĐµĐ½Đ¸ĐµÑ‚Đ¾ Đ½Đ° Đ»Đ¾ĐºĐ°Đ»Đ½Đ¸ и Đ¸Đ½Ñ‚ĐµÑ€Đ½ĐµÑ‚ Đ¼ÑƒĐ»Ñ‚Đ¸Đ¼ĐµĐ´Đ¸Đ¹Đ½Đ¸ Đ¿Đ¾Ñ‚Đ¾Ñ†Đ¸, ĐºĐ°ĐºÑ‚Đ¾ и Đ¼Đ½Đ¾Đ¶ĐµÑÑ‚Đ²Đ¾ Đ²Đ¸Đ´ĐµĐ¾ Ñ„Đ¾Ñ€Đ¼Đ°Ñ‚Đ¸. Invalid folder ĐĐµĐ²Đ°Đ»Đ¸Đ´Đ½Đ° Đ¿Đ°Đ¿ĐºĐ° Open folder ĐÑ‚Đ²Đ°Ñ€ÑĐ½Đµ Đ½Đ° Đ¿Đ°Đ¿ĐºĐ° You don't have permission to operate this folder ĐÑĐ¼Đ°Ñ‚Đ° Đ¿Ñ€Đ°Đ²Đ° да Ñ€Đ°Đ±Đ¾Ñ‚Đ¸Ñ‚Đµ Đ² Ñ‚Đ°Đ·Đ¸ Đ¿Đ°Đ¿ĐºĐ° Auto add similar files to play ĐÑ‚Đ¾Đ¼Đ°Ñ‚Đ¾Ñ‡Đ½Đ¾ Đ´Đ¾Đ±Đ°Đ²Đ¸ Đ½Đ° Đ¿Đ¾Đ´Đ¾Đ±Đ½Đ¸ Ñ„Đ°Đ¹Đ»Đ¾Đ²Đµ Clear playlist when exit Đ˜Đ·Ñ‡Đ¸ÑÑ‚Đ²Đ°Đ½Đµ Đ½Đ° ÑĐ¿Đ¸ÑÑĐºĐ° Đ¿Ñ€Đ¸ Đ¸Đ·Ñ…Đ¾Đ´ Show video preview on mouseover ĐŸĐ¾ĐºĐ°Đ¶Đ¸ Đ¿Ñ€ĐµĐ³Đ»ĐµĐ´ Đ¿Ñ€Đ¸ Đ¿Đ¾ÑĐ¾Ñ‡Đ²Đ°Đ½Đµ Ñ Đ¼Đ¸ÑˆĐºĐ°Ñ‚Đ° Open a new player for each file played ĐĐ¾Đ² Đ¿Đ»ĐµÑÑ€ за Đ²ÑĐµĐºĐ¸ Đ¿Ñ€Đ¾ÑĐ²Đ¸Ñ€Đ²Đ°Đ½ Ñ„Đ°Đ¹Đ» Pause when minimized ĐŸĐ°ÑƒĐ·Đ° Đ¿Ñ€Đ¸ Đ¼Đ¸Đ½Đ¸Đ¼Đ¸Đ·Đ¸Ñ€Đ°Đ½Đµ Remember playback position Đ—Đ°Đ¿Đ¾Đ¼Đ½Đ¸ Đ¼ĐµÑÑ‚Đ¾Đ¿Đ¾Đ»Đ¾Đ¶ĐµĐ½Đ¸ĐµÑ‚Đ¾ Đ½Đ° Đ·Đ°Đ¿Đ¸Ñа Path ĐŸÑÑ‚ Basic ĐÑĐ½Đ¾Đ²ĐµĐ½ Play Đ˜Đ·Đ¿ÑĐ»Đ½ĐµĐ½Đ¸Đµ Screenshot Đ¡Đ½Đ¸Đ¼ĐºĐ° Đ½Đ° ĐµĐºÑ€Đ°Đ½Đ° Shortcuts Đ‘ÑÑ€Đ·Đ¸ ĐºĐ»Đ°Đ²Đ¸ÑˆĐ¸ File Đ¤Đ°Đ¹Đ» Frame/Sound ĐадÑÑ€/Đ—Đ²ÑƒĐº Playback Đ˜Đ·Đ¿ÑĐ»Đ½ĐµĐ½Đ¸Đµ Subtitle Đ¡ÑƒĐ±Ñ‚Đ¸Ñ‚Ñ€Đ¸ Font Style Đ¡Ñ‚Đ¸Đ» Đ½Đ° ÑˆÑ€Đ¸Ñ„Ñ‚Đ°: Restore Defaults Đ’ÑĐ·ÑÑ‚Đ°Đ½Đ¾Đ²Đ¸ ÑÑ‚Đ°Đ½Đ´Đ°Ñ€Ñ‚Đ½Đ¸Ñ‚Đµ Đ½Đ°ÑÑ‚Ñ€Đ¾Đ¹ĐºĐ¸ Open file ĐÑ‚Đ²Đ¾Ñ€Đ¸ Ñ„Đ°Đ¹Đ» Open next ĐÑ‚Đ²Đ¾Ñ€Đ¸ ÑĐ»ĐµĐ´Đ²Đ°Ñ‰Đ¾Ñ‚Đ¾ Open previous ĐÑ‚Đ²Đ¾Ñ€Đ¸ Đ¿Ñ€ĐµĐ´Đ¸ÑˆĐ½Đ¾Ñ‚Đ¾ Mini mode ĐœĐ¸Đ½Đ¸Đ¼Đ°Đ»Đ¸ÑÑ‚Đ¸Ñ‡ĐµĐ½ Ñ€ĐµĐ¶Đ¸Đ¼ Mute Đ—Đ°Đ³Đ»ÑƒÑˆĐ°Đ²Đ°Đ½Đµ Next frame Đ¡Đ»ĐµĐ´Đ²Đ°Ñˆ ĐºĐ°Đ´ÑÑ€ Previous frame ĐŸÑ€ĐµĐ´Đ¸ÑˆĐµĐ½ ĐºĐ°Đ´ÑÑ€ Volume down ĐĐ°Đ¼Đ°Đ»ÑĐ²Đ°Đ½Đµ Volume up Đ£Đ²ĐµĐ»Đ¸Ñ‡Đ°Đ²Đ°Đ½Đµ Speed up Đ¿Đ¾-бÑÑ€Đ·Đ¾ Speed down Đ¿Đ¾-Đ±Đ°Đ²Đ½Đ¾ Fullscreen ЦÑĐ» ĐµĐºÑ€Đ°Đ½ Pause/Play ĐŸĐ°ÑƒĐ·Đ°/Đ˜Đ·Đ¿ÑĐ»Đ½ĐµĐ½Đ¸Đµ Playlist Đ¡Đ¿Đ¸ÑÑĐº Reset speed ĐĐ¾Ñ€Đ¼Đ°Đ»Đ½Đ° ÑĐºĐ¾Ñ€Đ¾ÑÑ‚ Rewind Đ’Ñ€ÑÑ‰Đ°Đ½Đµ Forward ĐĐ°Đ¿Ñ€ĐµĐ´ Burst screenshot Burst screenshot Film screenshot ĐадÑÑ€ Đ¾Ñ‚ Ñ„Đ¸Đ»Đ¼Đ° 0.5s backward Đазад Ñ 0.5s 0.5s forward ĐĐ°Đ¿Ñ€ĐµĐ´ Ñ 0.5s Font Đ¨Ñ€Đ¸Ñ„Ñ‚ Font Size Đ Đ°Đ·Đ¼ĐµÑ€ Đ½Đ° ÑˆÑ€Đ¸Ñ„Ñ‚Đ° UrlDialog Cancel ĐÑ‚ĐºĐ°Đ· Confirm ĐŸĐ¾Ñ‚Đ²ÑÑ€Đ¶Đ´ĐµĐ½Đ¸Đµ Please enter the URL: ĐœĐ¾Đ»Ñ Đ²ÑĐ²ĐµĐ´ĐµÑ‚Đµ URL: dmr::ActionFactory Settings ĐаÑÑ‚Ñ€Đ¾Đ¹ĐºĐ¸ Fullscreen ЦÑĐ» ĐµĐºÑ€Đ°Đ½ Always on Top Đ’Đ¸Đ½Đ°Đ³Đ¸ Đ¾Ñ‚Đ³Đ¾Ñ€Đµ Film info Đ˜Đ½Ñ„Đ¾Ñ€Đ¼Đ°Ñ†Đ¸Ñ Đ·Đ° Ñ„Đ¸Đ»Đ¼ Open file ĐÑ‚Đ²Đ¾Ñ€Đ¸ Ñ„Đ°Đ¹Đ» Open folder ĐÑ‚Đ²Đ°Ñ€ÑĐ½Đµ Đ½Đ° Đ¿Đ°Đ¿ĐºĐ° Light theme Đ¡Đ²ĐµÑ‚Đ»Đ° Ñ‚ĐµĐ¼Đ° Open URL ĐÑ‚Đ²Đ¾Ñ€Đ¸ URL Open CD/DVD ĐÑ‚Đ²Đ¾Ñ€Đ¸ CD/DVD Mini Mode ĐœĐ¸Đ½Đ¸Đ¼Đ°Đ»Đ¸ÑÑ‚Đ¸Ñ‡ĐµĐ½ Ñ€ĐµĐ¶Đ¸Đ¼ Play Mode Đ ĐµĐ¶Đ¸Đ¼ Đ½Đ° Đ²ÑĐ·Đ¿Ñ€Đ¾Đ¸Đ·Đ²ĐµĐ¶Đ´Đ°Đ½Đµ Order Play Ред Đ½Đ° Đ¸Đ·Đ¿ÑĐ»Đ½ĐµĐ½Đ¸Đµ Shuffle Play РазбÑÑ€ĐºĐ°Đ½Đ¾ Đ¸Đ·Đ¿ÑĐ»Đ½ĐµĐ½Đ¸Đµ Single Play ĐŸĐ¾Đ²Ñ‚Đ¾Ñ€ĐµĐ½Đ¸Đµ Đ½Đ° Đ¸Đ·Đ¿ÑĐ»Đ½ĐµĐ½Đ¸ĐµÑ‚Đ¾ Single Loop Đ•Đ´Đ½Đ¾ĐºÑ€Đ°Ñ‚Đ½Đ¾ Đ¿Đ¾Đ²Ñ‚Đ¾Ñ€ĐµĐ½Đ¸Đµ List Loop ĐŸĐ¾Đ²Ñ‚Đ¾Ñ€ĐµĐ½Đ¸Đµ Đ½Đ° ÑĐ¿Đ¸ÑÑĐºĐ° Frame ĐадÑÑ€ Default ĐŸĐ¾ Đ¿Đ¾Đ´Ñ€Đ°Đ·Đ±Đ¸Ñ€Đ°Đ½Đµ Clockwise ĐŸĐ¾ Ñ‡Đ°ÑĐ¾Đ²Đ½Đ¸ĐºĐ¾Đ²Đ°Ñ‚Đ° Counterclockwise ĐĐ±Ñ€Đ°Ñ‚Đ½Đ¾ Đ½Đ° Ñ‡Đ°ÑĐ¾Đ²Đ½Đ¸ĐºĐ¾Đ²Đ°Ñ‚Đ° Next frame Đ¡Đ»ĐµĐ´Đ²Đ°Ñˆ ĐºĐ°Đ´ÑÑ€ Previous frame ĐŸÑ€ĐµĐ´Đ¸ÑˆĐµĐ½ ĐºĐ°Đ´ÑÑ€ Sound Đ—Đ²ÑƒĐº Channel ĐĐ°Đ½Đ°Đ» Stereo Đ¡Ñ‚ĐµÑ€ĐµĐ¾ Left channel Đ›ÑĐ² ĐºĐ°Đ½Đ°Đ» Right channel ДеÑĐµĐ½ ĐºĐ°Đ½Đ°Đ» Track Đ¢Ñ€Đ°Đº Subtitle Đ¡ÑƒĐ±Ñ‚Đ¸Ñ‚Ñ€Đ¸ Load Đ—Đ°Ñ€ĐµĐ´Đ¸ Online Search Đ¢ÑÑ€ÑĐµĐ½Đµ Đ¾Đ½Đ»Đ°Đ¹Đ½ Select Đ˜Đ·Đ±ĐµÑ€Đ¸ Hide Đ¡ĐºÑ€Đ¸Đ²Đ°Đ½Đµ Encodings ĐĐ¾Đ´Đ¸Ñ€Đ°Đ½Đµ Screenshot Đ¡Đ½Đ¸Đ¼ĐºĐ° Đ½Đ° ĐµĐºÑ€Đ°Đ½Đ° Film Screenshot ĐадÑÑ€ Đ¾Ñ‚ Ñ„Đ¸Đ»Đ¼Đ° Burst Shooting ĐŸĐ¾ÑĐ»ĐµĐ´Đ¾Đ²Đ°Ñ‚ĐµĐ»Đ½Đ¾ ÑĐ½Đ¸Đ¼Đ°Đ½Đµ Playlist ĐŸĐ»ĐµĐ¹Đ»Đ¸ÑÑ‚ Film Info Đ˜Đ½Ñ„Đ¾Ñ€Đ¼Đ°Ñ†Đ¸Ñ Đ·Đ° Ñ„Đ¸Đ»Đ¼ Clear playlist Đ˜Đ·Ñ‡Đ¸ÑÑ‚Đ²Đ°Đ½Đµ Đ½Đ° ÑĐ¿Đ¸ÑÑĐºĐ° Display in file manager ĐŸĐ¾ĐºĐ°Đ¶Đ¸ Đ²ÑĐ² Ñ„Đ°Đ¹Đ»Đ¾Đ²Đ¸Ñ Đ¼ĐµĐ½Đ¸Đ´Đ¶ÑÑ€ dmr::BurstScreenshotsDialog Duration: %1 ĐŸÑ€Đ¾Đ´ÑĐ»Đ¶Đ¸Ñ‚ĐµĐ»Đ½Đ¾ÑÑ‚: %1 Resolution: %1 Đ ĐµĐ·Đ¾Đ»ÑÑ†Đ¸Ñ: %1 Size: %1 Đ Đ°Đ·Đ¼ĐµÑ€: %1 Save Đ—Đ°Đ¿Đ°Đ·Đ²Đ°Đ½Đµ dmr::MainWindow Load successfully Đ£ÑĐ¿ĐµÑˆĐ½Đ¾ Đ·Đ°Ñ€ĐµĐ¶Đ´Đ°Đ½Đµ Load failed ĐĐµÑƒÑĐ¿ĐµÑˆĐ½Đ¾ Đ·Đ°Ñ€ĐµĐ¶Đ´Đ°Đ½Đµ No device found Đе е Đ¾Ñ‚ĐºÑ€Đ¸Ñ‚Đ¾ уÑÑ‚Ñ€Đ¾Đ¹ÑÑ‚Đ²Đ¾ Parse Failed Đ Đ°Đ·Đ±Đ¾Ñ€ÑÑ‚ е Đ½ĐµÑƒÑĐ¿ĐµÑˆĐµĐ½ Open folder ĐÑ‚Đ²Đ°Ñ€ÑĐ½Đµ Đ½Đ° Đ¿Đ°Đ¿ĐºĐ° Open file ĐÑ‚Đ²Đ¾Ñ€Đ¸ Ñ„Đ°Đ¹Đ» All videos (%1) Đ’ÑĐ¸Ñ‡ĐºĐ¸ Đ²Đ¸Đ´ĐµĐ° (%1) Muted Đ—Đ°Đ³Đ»ÑƒÑˆĐ°Đ²Đ°Đ½Đµ Volume: %1% Đ¡Đ¸Đ»Đ° Đ½Đ° Đ·Đ²ÑƒĐºĐ°: %1 Subtitle %1: %2s Đ¡ÑƒĐ±Ñ‚Đ¸Ñ‚Ñ€Đ¸ %1: %2s delayed Đ·Đ°Đ±Đ°Đ²ĐµĐ½ advanced Ñ€Đ°Đ·ÑˆĐ¸Ñ€ĐµĐ½ Speed: %1x Đ¡ĐºĐ¾Ñ€Đ¾ÑÑ‚: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) Đ¡ÑƒĐ±Ñ‚Đ¸Ñ‚Ñ€Đ¸ (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Đ˜Đ·Đ³Đ»ĐµĐ´ Movie Screenshot Đ¡Đ½Đ¸Đ¼ĐºĐ° Đ½Đ° Ñ„Đ¸Đ»Đ¼Đ° Saved to Đ—Đ°Đ¿Đ°Đ·Đ¸ Đ² The screenshot is saved Đ¡Đ½Đ¸Đ¼ĐºĐ° Đ½Đ° ĐµĐºÑ€Đ°Đ½Đ° е Đ·Đ°Đ¿Đ°Đ·ĐµĐ½Đ°. Failed to save the screenshot Đе Đ¼Đ¾Đ¶Đµ да Ñе Đ·Đ°Đ¿Đ°Đ·Đ¸ ÑĐ½Đ¸Đ¼ĐºĐ° Đ½Đ° ĐºĐ°Đ´ÑÑ€Đ° Invalid file: %1 ĐĐµĐ²Đ°Đ»Đ¸Đ´ĐµĐ½ Ñ„Đ°Đ¹Đ»: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Đ¢Đ¸Đ¿ Đ½Đ° Ñ„Đ°Đ¹Đ»: Resolution: Đ ĐµĐ·Đ¾Đ»ÑÑ†Đ¸Ñ: File Size: Đ Đ°Đ·Đ¼ĐµÑ€ Đ½Đ° Ñ„Đ°Đ¹Đ»: Duration: Đ’Ñ€ĐµĐ¼ĐµÑ‚Ñ€Đ°ĐµĐ½Đµ: File Path: ĐŸÑÑ‚ Đ´Đ¾ Ñ„Đ°Đ¹Đ»Đ°: dmr::MpvProxy [internal] [Đ²ÑÑ‚Ñ€ĐµÑˆĐµĐ½] dmr::PlayItemWidget File does not exist Đ¤Đ°Đ¹Đ»Đ° Đ½Đµ ÑÑÑ‰ĐµÑÑ‚Đ²ÑƒĐ²Đ° dmr::Settings %1/DMovie%2.jpg %1/DMovie%2.jpg %1/DMovie%2(%3).jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Đ˜Đ·Đ¿ÑĐ»Đ½ĐµĐ½Đ¸Đµ Previous ĐŸÑ€ĐµĐ´Đ¸ÑˆĐ½Đ¾ Next Đ¡Đ»ĐµĐ´Đ²Đ°Ñ‰ Subtitles Đ¡ÑƒĐ±Ñ‚Đ¸Ñ‚Ñ€Đ¸ Playlist Đ¡Đ¿Đ¸ÑÑĐº Fullscreen ЦÑĐ» ĐµĐºÑ€Đ°Đ½ Play/Pause Đ˜Đ·Đ¿ÑĐ»Đ½ĐµĐ½Đ¸Đµ/ĐŸĐ°ÑƒĐ·Đ° Exit fullscreen Đ˜Đ·Ñ…Đ¾Đ´ Đ¾Ñ‚ цÑĐ» ĐµĐºÑ€Đ°Đ½ Pause ЗадÑÑ€Đ¶Đ°Đ½Đµ deepin-movie-reborn-5.0.0/src/translations/deepin-movie_bn.ts000066400000000000000000000757271351125414100243210ustar00rootroot00000000000000 QObject Deepin Movie ডিপিন মà§à¦­à¦¿ Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. ডিপিন মà§à¦­à¦¿ à¦à¦•টি বরà§à¦¡à¦¾à¦° বিহীন সà§à¦¨à§à¦¦à¦° ডিজাইনের à¦à¦¬à¦‚ পরিপূরà§à¦£ বৈশিষà§à¦Ÿà¦¯à§à¦•à§à¦¤ ভিডিও পà§à¦²à§‡à§Ÿà¦¾à¦°à¥¤ à¦à¦Ÿà¦¾ দিয়ে বিভিনà§à¦¨ ফরমà§à¦¯à¦¾à¦Ÿà§‡à¦° ভিডিও সà§à¦¥à¦¾à¦¨à§€à§Ÿà¦­à¦¾à¦¬à§‡ à¦à¦¬à¦‚ সà§à¦Ÿà§à¦°à¦¿à¦®à¦¿à¦‚ করে à¦à¦¾à¦²à¦¾à¦¨à§‹ যায়। Invalid folder ফোলà§à¦¡à¦¾à¦°à¦Ÿà¦¿ অবৈধ Open folder ফোলà§à¦¡à¦¾à¦° খà§à¦²à§à¦¨ You don't have permission to operate this folder আপনার কাছে à¦à¦‡ ফোলà§à¦¡à¦¾à¦°à¦Ÿà¦¿ পরিà¦à¦¾à¦²à¦¨à¦¾ করার অনà§à¦®à¦¤à¦¿ নেই Auto add similar files to play à¦à¦•ই ধরণের ফাইলগà§à¦²à§‹ অটোমেটিক à¦à¦²à¦¾à¦° জনà§à¦¯ যà§à¦•à§à¦¤ করà§à¦¨ Clear playlist when exit বের হয়ে যাবার সময় à¦à¦²à¦¾à¦° তালিকা মà§à¦›à§‡ ফেলà§à¦¨ Show video preview on mouseover মাউস নেওয়ার সাথে সাথেই ভিডিওর পà§à¦°à¦¿à¦­à¦¿à¦‰ দেখান। Open a new player for each file played পà§à¦°à¦¤à§à¦¯à§‡à¦•টি ফাইল à¦à¦²à¦¤à§‡ নতà§à¦¨ পà§à¦²à§‡à§Ÿà¦¾à¦° খà§à¦²à§à¦¨ Pause when minimized মিনিমাইজ করলে থেমে যান Remember playback position সরà§à¦¬à¦¶à§‡à¦· à¦à¦¾à¦²à¦¾à¦¨à§‹ অবসà§à¦¥à¦¾ মনে রাখà§à¦¨ Path পথ Basic পà§à¦°à¦¾à¦¥à¦®à¦¿à¦• Play à¦à¦¾à¦²à§ করà§à¦¨ Screenshot সà§à¦•à§à¦°à¦¿à¦¨à¦¶à¦Ÿ Shortcuts শরà§à¦Ÿà¦•াট File ফাইল Frame/Sound ফà§à¦°à§‡à¦®/শবà§à¦¦ Playback à¦à¦¾à¦²à¦¾à¦¨ Subtitle সাবটাইটেল Font Style ফনà§à¦Ÿ সà§à¦Ÿà¦¾à¦‡à¦² Restore Defaults পূরà§à¦¬à¦¨à¦¿à¦°à§à¦§à¦¾à¦°à¦¿à¦¤ জিনিসে ফিরে যান Open file ফাইল খà§à¦²à§à¦¨ Open next পরবরà§à¦¤à§€à¦Ÿà¦¿ খà§à¦²à§à¦¨ Open previous পূরà§à¦¬à¦¬à¦°à§à¦¤à§€à¦Ÿà¦¿ খà§à¦²à§à¦¨ Mini mode ছোট রূপ Mute নীরব Next frame পরবরà§à¦¤à§€ ফà§à¦°à§‡à¦® Previous frame পূরà§à¦¬à§‡à¦° ফà§à¦°à§‡à¦® Volume down শবà§à¦¦ কমান Volume up শবà§à¦¦ বাড়ান Speed up গতি বাড়ান Speed down গতি কমান Fullscreen সমà§à¦ªà§‚রà§à¦£ পরà§à¦¦à¦¾ Pause/Play থামà§à¦¨/à¦à¦¾à¦²à¦¾à¦¨ Playlist à¦à¦¾à¦²à¦¾à¦¨à§‹à¦° তালিকা Reset speed গতি পà§à¦¨à¦°à¦¾à¦¯à¦¼ সেট করà§à¦¨ Rewind আবার গà§à¦Ÿà¦¿à¦¯à¦¼à§‡ নিন Forward সামনে Burst screenshot à¦à¦•সাথে অনেকগà§à¦²à§‹ সà§à¦•à§à¦°à¦¿à¦¨à¦¶à¦Ÿ Film screenshot ফিলà§à¦® সà§à¦•à§à¦°à¦¿à¦¨à¦¶à¦Ÿ 0.5s backward 0.5s পিছনে 0.5s forward 0.5s সামনে Font ফনà§à¦Ÿ Font Size ফনà§à¦Ÿà§‡à¦° আকার UrlDialog Cancel বাতিল Confirm নিশà§à¦à¦¿à¦¤ করà§à¦¨ Please enter the URL: দয়াকরে URL পà§à¦°à¦¬à§‡à¦¶ করান dmr::ActionFactory Settings সেটিংস Fullscreen সমà§à¦ªà§‚রà§à¦£ পরà§à¦¦à¦¾ Always on Top সবসময় উপরে Film info ফিলà§à¦®à§‡à¦° তথà§à¦¯ Open file ফাইল খà§à¦²à§à¦¨ Open folder ফোলà§à¦¡à¦¾à¦° খà§à¦²à§à¦¨ Light theme হালকা থিম Open URL URL খà§à¦²à§à¦¨ Open CD/DVD CD/DVD খà§à¦²à§à¦¨ Mini Mode ছোট রূপ Play Mode à¦à¦¾à¦²à¦¾à¦¨à§‹à¦° ধরণ Order Play ধারাবাহিকভাবে à¦à¦¾à¦²à¦¾à¦¨ Shuffle Play অদলবদল করে à¦à¦¾à¦²à¦¾à¦¨ Single Play à¦à¦•টিমাতà§à¦° à¦à¦¾à¦²à¦¾à¦¨ Single Loop à¦à¦•বার ঘà§à§œà§à¦¨ List Loop সমà§à¦ªà§‚রà§à¦£ তালিকা বার বার ঘà§à§œà§à¦¨ Frame ফà§à¦°à§‡à¦® Default পূরà§à¦¬à¦¨à¦¿à¦°à§à¦§à¦¾à¦°à¦¿à¦¤ Clockwise ঘড়ির কাটার দিকে Counterclockwise ঘড়ির কাটার বিপরীত দিকে Next frame পরের ফà§à¦°à§‡à¦® Previous frame পূরà§à¦¬à§‡à¦° ফà§à¦°à§‡à¦® Sound শবà§à¦¦ Channel à¦à§à¦¯à¦¾à¦¨à§‡à¦² Stereo সà§à¦Ÿà§‡à¦°à¦¿à¦“ Left channel বামদিকের à¦à§à¦¯à¦¾à¦¨à§‡à¦² Right channel ডানদিকের à¦à§à¦¯à¦¾à¦¨à§‡à¦² Track রেকরà§à¦¡ করা শবà§à¦¦ Subtitle সাবটাইটেল Load লোড করà§à¦¨ Online Search অনলাইনে খà§à¦œà§à¦¨ Select নিরà§à¦¬à¦¾à¦à¦¨ করà§à¦¨ Hide লà§à¦•ান Encodings à¦à¦¨à¦•োডিং Screenshot সà§à¦•à§à¦°à¦¿à¦¨à¦¶à¦Ÿ Film Screenshot ফিলà§à¦® সà§à¦•à§à¦°à¦¿à¦¨à¦¶à¦Ÿ Burst Shooting অনেকগà§à¦²à¦¿ সà§à¦•à§à¦°à¦¿à¦¨à¦¶à¦Ÿ Playlist à¦à¦²à¦¾à¦° তালিকা Film Info ফিলà§à¦®à§‡à¦° তথà§à¦¯ Clear playlist à¦à¦²à¦¾à¦° তালিকা মà§à¦›à§‡ ফেলà§à¦¨ Display in file manager ফাইল মà§à¦¯à¦¾à¦¨à§‡à¦œà¦¾à¦° দেখান dmr::BurstScreenshotsDialog Duration: %1 সময়কাল: %1 Resolution: %1 রেজূূলিউশন: %1 Size: %1 আকার: %1 Save সংরকà§à¦·à¦£ করà§à¦¨ dmr::MainWindow Load successfully সফলভাবে লোড হয়েছে Load failed লোড করতে বারà§à¦¥ হয়েছে No device found কোনো ডিভাইস পাওয়া যায়নি Parse Failed শবà§à¦¦à¦¬à¦¿à¦¶à§à¦²à§‡à¦·à¦£ করতে বà§à¦¯à¦°à§à¦¥ হয়েছে Open folder ফোলà§à¦¡à¦¾à¦° খà§à¦²à§à¦¨ Open file ফাইল খà§à¦²à§à¦¨ All videos (%1) সকল ভিডিওসমূহ(%1) Muted নীরব করা হয়েছে Volume: %1% শবà§à¦¦: %1% Subtitle %1: %2s সাবটাইটেল %1: %2s delayed বিলমà§à¦¬ করা হয়েছে advanced অà§à¦¯à¦¾à¦¡à¦­à¦¾à¦¨à§à¦¸à¦¡ Speed: %1x গতি: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) সাবটাইটেল (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View দেখà§à¦¨ Movie Screenshot মà§à¦­à¦¿ সà§à¦•à§à¦°à¦¿à¦¨à¦¶à¦Ÿ Saved to à¦à¦–ানে সংরকà§à¦·à¦£ করà§à¦¨ The screenshot is saved সà§à¦•à§à¦°à¦¿à¦¨à¦¶à¦Ÿà¦Ÿà¦¿ সংরকà§à¦·à¦£ করা হয়েছে Failed to save the screenshot সà§à¦•à§à¦°à¦¿à¦¨à¦¶à¦Ÿ সংরকà§à¦·à¦£ করতে বারà§à¦¥ হয়েছে Invalid file: %1 অবধৈ ফাইল: %1 dmr::MovieInfo %1G %1G %1M %1M %1K %1K %1 %1 dmr::MovieInfoDialog File Type: ফাইলের ধরণ: Resolution: রেজোলিউশন: File Size: ফাইলের আকার: Duration: সময়কালঃ File Path: ফাইলের পথ: dmr::MpvProxy [internal] [অভà§à¦¯à¦¨à§à¦¤à¦°à§€à¦£] dmr::PlayItemWidget File does not exist ফাইল নেই dmr::Settings %1/DMovie%2.jpg %1/DMovie%2.jpg %1/DMovie%2(%3).jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play à¦à¦¾à¦²à§ করà§à¦¨ Previous পূরà§à¦¬à¦¬à¦°à§à¦¤à§€ Next পরবরà§à¦¤à§€ Subtitles সাবটাইটেল সমূহ Playlist à¦à¦²à¦¾à¦° তালিকা Fullscreen সমà§à¦ªà§‚রà§à¦£ পরà§à¦¦à¦¾ Play/Pause à¦à¦¾à¦²à¦¾à¦¨/থামà§à¦¨ Exit fullscreen সমà§à¦ªà§‚রà§à¦£ পরà§à¦¦à¦¾ থেকে বের হয়ে যান Pause থামà§à¦¨ deepin-movie-reborn-5.0.0/src/translations/deepin-movie_ca.ts000066400000000000000000000701201351125414100242630ustar00rootroot00000000000000 QObject Deepin Movie Pel·lĂ­cula del Deepin Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. La Pel·lĂ­cula del Deepin Ă©s un reproductor de vĂ­deo ben dissenyat i ple de funcionalitats amb un disseny simple sense vores. Admet la reproducciĂ³ local i remota de diversos formats de vĂ­deo. Invalid folder Carpeta no vĂ lida Open folder Obre una carpeta You don't have permission to operate this folder No teniu permĂ­s per usar aquesta carpeta. Auto add similar files to play Afegeix automĂ ticament fitxers semblants per reproduir. Clear playlist when exit Neteja la llista de reproducciĂ³ en sortir. Show video preview on mouseover Mostra una previsualitzaciĂ³ en passar-hi el ratolĂ­. Open a new player for each file played Obre un reproductor nou per a cada fitxer reproduĂ¯t. Pause when minimized Pausa quan estigui minimitzat. Remember playback position Recorda el punt de reproducciĂ³. Path CamĂ­ Basic BĂ sic Play Reprodueix Screenshot Captura de pantalla Shortcuts Dreceres File Fitxer Frame/Sound Fotograma / So Playback ReproducciĂ³ Subtitle SubtĂ­tol Font Style Tipus de lletra Restore Defaults Restaura els valors per defecte Open file Obre un fitxer Open next Obre el segĂ¼ent Open previous Obre l'anterior Mini mode Mode mini Mute Silencia Next frame Fotograma segĂ¼ent Previous frame Fotograma anterior Volume down Volum avall Volume up Volum amunt Speed up Accelera Speed down Frena Fullscreen Pantalla completa Pause/Play Pausa / Reprodueix Playlist Llista de reproducciĂ³ Reset speed Restableix la velocitat Rewind Rebobina Forward Avança Burst screenshot Captura de pantalla d'esclat Film screenshot Captura de pantalla de la pel·lĂ­cula 0.5s backward 0.5 s enrere 0.5s forward 0.5 s endavant Font Lletra Font Size Mida de la lletra UrlDialog Cancel Cancel·la Confirm Confirmeu-ho Please enter the URL: IntroduĂ¯u l'URL: dmr::ActionFactory Settings ConfiguraciĂ³ Fullscreen Pantalla completa Always on Top Sempre a dalt Film info InformaciĂ³ de la pel·lĂ­cula Open file Obre un fitxer Open folder Obre una carpeta Light theme Tema clar Open URL Obre un URL Open CD/DVD Obre un CD / DVD Mini Mode Mode mini Play Mode Mode de reproducciĂ³ Order Play ReproducciĂ³ ordenada Shuffle Play ReproducciĂ³ aleatĂ²ria Single Play ReproducciĂ³ simple Single Loop RepeticiĂ³ simple List Loop RepeticiĂ³ de la llista Frame Fotograma Default Per defecte Clockwise Cap a la dreta Counterclockwise Cap a l'esquerra Next frame Fotograma segĂ¼ent Previous frame Fotograma anterior Sound So Channel Canal Stereo Estèreo Left channel Canal de l'esquerra Right channel Canal de la dreta Track Pista Subtitle SubtĂ­tol Load Carrega Online Search Cerca en lĂ­nia Select Selecciona Hide Oculta Encodings Codificacions Screenshot Captura de pantalla Film Screenshot Captura de pantalla de la pel·lĂ­cula Burst Shooting Esclat de rĂ fegues Playlist Llista de reproducciĂ³ Film Info InformaciĂ³ de la pel·lĂ­cula Clear playlist Neteja la llista de reproducciĂ³ Display in file manager Mostra al gestor de fitxers dmr::BurstScreenshotsDialog Duration: %1 Durada: %1 Resolution: %1 ResoluciĂ³: %1 Size: %1 Mida: %1 Save Desa dmr::MainWindow Load successfully CĂ rrega correcta Load failed Ha fallat la cĂ rrega. No device found No s'ha trobat cap dispositiu. Parse Failed Ha fallat l'anĂ lisi Open folder Obre una carpeta Open file Obre un fitxer All videos (%1) Tots els vĂ­deos (%1) Muted Silenciat Volume: %1% Volum: %1% Subtitle %1: %2s SubtĂ­tol %1: %2s delayed ajornat advanced avançat Speed: %1x Velocitat: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) SubtĂ­tols (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View VisualitzaciĂ³ Movie Screenshot Captura de pantalla de la pel·lĂ­cula Saved to Desada a The screenshot is saved La captura s'ha desat. Failed to save the screenshot Ha fallat desar la captura de pantalla. Invalid file: %1 Fitxer no vĂ lid: %1 dmr::MovieInfo %1G %1 G %1M %1 M %1K %1 K %1 %1 dmr::MovieInfoDialog File Type: Tipus de fitxer: Resolution: ResoluciĂ³: File Size: Mida del fitxer: Duration: Durada: File Path: CamĂ­ del fitxer: dmr::MpvProxy [internal] [intern] dmr::PlayItemWidget File does not exist El fitxer no existeix. dmr::Settings %1/DMovie%2.jpg %1/DMovie%2.jpg %1/DMovie%2(%3).jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Reprodueix Previous Anterior Next SegĂ¼ent Subtitles SubtĂ­tols Playlist Llista de reproducciĂ³ Fullscreen Pantalla completa Play/Pause Reprodueix / Pausa Exit fullscreen Surt de la pantalla completa Pause Pausa deepin-movie-reborn-5.0.0/src/translations/deepin-movie_cs.ts000066400000000000000000000701011351125414100243040ustar00rootroot00000000000000 QObject Deepin Movie Filmy Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Deepin Movie je dobÅ™e navrženĂ½ a funkcemi vybavenĂ½ pÅ™ehrĂ¡vaÄ obrazovĂ½ch zĂ¡znamů s jednoduchĂ½m bezokrajovĂ½m vzhledem. Podporuje pÅ™ehrĂ¡vĂ¡nĂ­ mĂ­stnĂ­ch a pÅ™enĂ¡Å¡enĂ½ch zĂ¡znamů nahranĂ½ch v mnoha obrazovĂ½ch formĂ¡tech. Invalid folder NeplatnĂ¡ složka Open folder OtevÅ™Ă­t složku You don't have permission to operate this folder NemĂ¡te oprĂ¡vnÄ›nĂ­ k prĂ¡ci s touto složkou Auto add similar files to play PÅ™idat podobnĂ© soubory do pÅ™ehrĂ¡vĂ¡nĂ­ automaticky Clear playlist when exit VyprĂ¡zdnit seznam skladeb pÅ™i ukonÄenĂ­ Show video preview on mouseover UkĂ¡zat nĂ¡hled na obraz pÅ™i pÅ™ejetĂ­ ukazovĂ¡tka myÅ¡i Open a new player for each file played OtevÅ™Ă­t novĂ½ pÅ™ehrĂ¡vaÄ pro každĂ½ pÅ™ehrĂ¡vanĂ½ soubor Pause when minimized Pozastavit pÅ™i zmenÅ¡enĂ­ Remember playback position Zapamatovat si polohu pÅ™ehrĂ¡vĂ¡nĂ­ Path Cesta Basic ZĂ¡kladnĂ­ Play PÅ™ehrĂ¡t Screenshot SnĂ­mek obrazovky Shortcuts KlĂ¡vesovĂ© zkratky File Soubor Frame/Sound SnĂ­mek/Zvuk Playback PÅ™ehrĂ¡vĂ¡nĂ­ Subtitle Titulky Font Style Styl pĂ­sma Restore Defaults Obnovit vĂ½chozĂ­ Open file OtevÅ™Ă­t soubor Open next OtevÅ™Ă­t dalÅ¡Ă­ Open previous OtevÅ™Ă­t pÅ™edchozĂ­ Mini mode MalĂ½ režim Mute Ztlumit Next frame DalÅ¡Ă­ snĂ­mek Previous frame PÅ™edchozĂ­ snĂ­mek Volume down TiÅ¡eji Volume up HlasitÄ›ji Speed up Zrychlit Speed down SnĂ­Å¾it rychlost Fullscreen CelĂ¡ obrazovka Pause/Play PÅ™ehrĂ¡t/Pozastavit Playlist Seznam skladeb Reset speed VrĂ¡tit rychlost na vĂ½chozĂ­ Rewind PÅ™etoÄit zpÄ›t Forward PÅ™etoÄit vpÅ™ed Burst screenshot Sled snĂ­mků obrazovky Film screenshot SnĂ­mek obrazovky filmu 0.5s backward O 0,5 s zpÄ›t 0.5s forward O 0,5 s vpÅ™ed Font PĂ­smo Font Size Velikost pĂ­sma UrlDialog Cancel ZruÅ¡it Confirm Potvrdit Please enter the URL: Zadejte, prosĂ­m, adresu (URL): dmr::ActionFactory Settings NastavenĂ­ Fullscreen CelĂ¡ obrazovka Always on Top Vždy navrchu Film info Ădaje o filmu Open file OtevÅ™Ă­t soubor Open folder OtevÅ™Ă­t složku Light theme SvÄ›tlĂ½ vzhled Open URL OtevÅ™Ă­t adresu (URL) Open CD/DVD OtevÅ™Ă­t CD/DVD Mini Mode MalĂ½ režim Play Mode Režim pÅ™ehrĂ¡vĂ¡nĂ­ Order Play SeÅ™adit pÅ™ehrĂ¡vĂ¡nĂ­ Shuffle Play ZamĂ­chat pÅ™ehrĂ¡vĂ¡nĂ­ Single Play Jedno pÅ™ehrĂ¡nĂ­ Single Loop JednoduchĂ¡ smyÄka List Loop SmyÄka seznamu Frame SnĂ­mek Default VĂ½chozĂ­ Clockwise Po smÄ›ru hodinovĂ½ch ruÄiÄek Counterclockwise Proti smÄ›ru hodinovĂ½ch ruÄiÄek Next frame DalÅ¡Ă­ snĂ­mek Previous frame PÅ™edchozĂ­ snĂ­mek Sound Zvuk Channel KanĂ¡l Stereo Stereo Left channel LevĂ½ kanĂ¡l Right channel PravĂ½ kanĂ¡l Track Skladba Subtitle Titulky Load NahrĂ¡t Online Search Hledat na internetu Select Vybrat Hide SkrĂ½t Encodings KĂ³dovĂ¡nĂ­ Screenshot SnĂ­mek obrazovky Film Screenshot SnĂ­mek obrazovky filmu Burst Shooting PostupnĂ© snĂ­mĂ¡nĂ­ Playlist Seznam skladeb Film Info Ădaje o filmu Clear playlist VyprĂ¡zdnit seznam skladeb Display in file manager Zobrazit ve sprĂ¡vci souborů dmr::BurstScreenshotsDialog Duration: %1 Doba trvĂ¡nĂ­: %1 Resolution: %1 RozliÅ¡enĂ­: %1 Size: %1 Velikost: %1 Save Uložit dmr::MainWindow Load successfully NahrĂ¡no ĂºspěšnÄ›! Load failed NepodaÅ™ilo se nahrĂ¡t No device found Nenalezeno Å¾Ă¡dnĂ© zaÅ™Ă­zenĂ­ Parse Failed NepodaÅ™ilo se zpracovat Open folder OtevÅ™Ă­t složku Open file OtevÅ™Ă­t soubor All videos (%1) VÅ¡echna videa (%1) Muted Ztlumeno Volume: %1% Hlasitost: %1% Subtitle %1: %2s Titulky %1: %2s delayed ZpoždÄ›no advanced PokroÄeno Speed: %1x Rychlost: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) Titulky (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Pohled Movie Screenshot SnĂ­mek filmovĂ©ho zĂ¡bÄ›ru Saved to Uloženo do The screenshot is saved SnĂ­mek obrazovky je uložen Failed to save the screenshot SnĂ­mek obrazovky se nepodaÅ™ilo uložit Invalid file: %1 NeplatnĂ½ soubor: %1 dmr::MovieInfo %1G %1 G %1M %1 M %1K %1 K %1 %1 dmr::MovieInfoDialog File Type: Typ souboru: Resolution: RozliÅ¡enĂ­: File Size: Velikost souboru: Duration: Doba trvĂ¡nĂ­: File Path: Cesta k souboru: dmr::MpvProxy [internal] [vnitÅ™nĂ­] dmr::PlayItemWidget File does not exist Soubor neexistuje dmr::Settings %1/DMovie%2.jpg %1/DMovie%2.jpg %1/DMovie%2(%3).jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play PÅ™ehrĂ¡t Previous PÅ™edchozĂ­ Next DalÅ¡Ă­ Subtitles Titulky Playlist Seznam skladeb Fullscreen CelĂ¡ obrazovka Play/Pause PÅ™ehrĂ¡t/Pozastavit Exit fullscreen Opustit celou obrazovku Pause Pozastavit deepin-movie-reborn-5.0.0/src/translations/deepin-movie_da.ts000066400000000000000000000671231351125414100242750ustar00rootroot00000000000000 QObject Deepin Movie Deepin film Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Deepin film er veldesignet og har alle funktioner der kræves af en videoafspiller med et enkelt design uden rammer. Det understøtter lokal og strømning medieafspilning med flere videoformater. Invalid folder Ugyldig mappe Open folder Ă…bn mappe You don't have permission to operate this folder Du har ikke tilladelse til at hĂ¥ndtere denne mappe Auto add similar files to play Tilføj automatisk lignende filer, der skal afspilles Clear playlist when exit Ryd afspilningsliste ved afslutning Show video preview on mouseover Vis forhĂ¥ndsvisning af video nĂ¥r musen holdes over Open a new player for each file played Ă…bn en ny afspiller for hver fil som afspilles Pause when minimized Pause nĂ¥r minimeret Remember playback position Husk afspilningsposition Path Sti Basic Grundlæggende Play Afspil Screenshot Skærmbillede Shortcuts Genveje File Fil Frame/Sound Billede/lyd Playback Afspilning Subtitle Undertekst Font Style Skriftstil Restore Defaults Gendan standarder Open file Ă…bn fil Open next Ă…bn næste Open previous Ă…bn forrige Mini mode Minitilstand Mute Lydløs Next frame Næste billede Previous frame Forrige billede Volume down Lavere Volume up Højere Speed up Hurtigere Speed down Langsommere Fullscreen Fuldskærm Pause/Play Pause/afspil Playlist Afspilningsliste Reset speed Nulstil hastighed Rewind Bagud Forward Fremad Burst screenshot Burst skærmbillede Film screenshot Film skærmbillede 0.5s backward 0,5 s baglæns 0.5s forward 0,5 s fremad Font Skrifttype Font Size Skriftstørrelse UrlDialog Cancel Annuller Confirm Bekræft Please enter the URL: Indtast venligst URL'en: dmr::ActionFactory Settings Indstillinger Fullscreen Fuldskærm Always on Top Altid øverst Film info Filminfo Open file Ă…bn fil Open folder Ă…bn mappe Light theme Lyst tema Open URL Ă…bn URL Open CD/DVD Ă…bn CD/DVD Mini Mode Minitilstand Play Mode Afspilningstilstand Order Play Fortløbende afspilning Shuffle Play Bland afspilning Single Play Én afspilning Single Loop Én løkke List Loop Listeløkke Frame Billede Default Standard Clockwise Med uret Counterclockwise Mod uret Next frame Næste billede Previous frame Forrige billede Sound Lyd Channel Kanal Stereo Stereo Left channel Venstre kanal Right channel Højre kanal Track Spor Subtitle Undertekst Load Indlæs Online Search Onlinesøgning Select Vælg Hide Skjul Encodings Kodninger Screenshot Skærmbillede Film Screenshot Film-skærmbillede Burst Shooting Burst-skydning Playlist Afspilningsliste Film Info Filminfo Clear playlist Ryd afspilningsliste Display in file manager Vis i filhĂ¥ndtering dmr::BurstScreenshotsDialog Duration: %1 Varighed: %1 Resolution: %1 Opløsning: %1 Size: %1 Størrelse: %1 Save Gem dmr::MainWindow Load successfully Indlæsning lykkedes Load failed Indlæsning mislykkedes No device found Ingen enhed fundet Parse Failed Fortolkning mislykkedes Open folder Ă…bn mappe Open file Ă…bn fil All videos (%1) Alle videoer (%1) Muted Lydløst Volume: %1% Lydstyrke: %1% Subtitle %1: %2s Undertekst %1: %2s delayed forsinket advanced fremskudt Speed: %1x Hastighed: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) Undertekst (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Vis Movie Screenshot film skærmbillede Saved to Gemt til The screenshot is saved Skærmbilledet er gemt Failed to save the screenshot Kunne ikke gemme skærmbilledet Invalid file: %1 Ugyldig fil: %1 dmr::MovieInfo %1G %1G %1M %1M %1K %1K %1 %1 dmr::MovieInfoDialog File Type: Filtype: Resolution: Opløsning: File Size: Filstørrelse: Duration: Varighed: File Path: Filsti: dmr::MpvProxy [internal] [intern] dmr::PlayItemWidget File does not exist Filen findes ikke dmr::Settings %1/DMovie%2.jpg %1/DFilm%2.jpg %1/DMovie%2(%3).jpg %1/DFilm%2(%3).jpg dmr::ToolboxProxy Play Afspil Previous Forrige Next Næste Subtitles Undertekster Playlist Afspilningsliste Fullscreen Fuldskærm Play/Pause Afspil/pause Exit fullscreen Forlad fuldskærm Pause Pause deepin-movie-reborn-5.0.0/src/translations/deepin-movie_de.ts000066400000000000000000000676031351125414100243040ustar00rootroot00000000000000 QObject Deepin Movie Deepin Film Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Deepin Film ist ein gut gestalteter und voll ausgestatteter Videoabspieler mit einem einfachen, randlosen Design. Er unterstĂ¼tzt lokale und gestreamte Medien mit vielen Videoformaten. Invalid folder UngĂ¼ltiger Ordner Open folder Ordner öffnen You don't have permission to operate this folder Sie haben keine Berechtigung diesen Ordner zu nutzen Auto add similar files to play Ă„hnliche Dateien automatisch zur Wiedergabe hinzufĂ¼gen Clear playlist when exit Wiedergabeliste beim Beenden leeren Show video preview on mouseover Videovorschau beim Ăœberfahren mit der Maus anzeigen Open a new player for each file played Ă–ffne einen neuen Player fĂ¼r jede abgespielte Datei Pause when minimized Beim Minimieren pausieren Remember playback position Wiedergabeposition merken Path Pfad Basic Basis Play Wiedergeben Screenshot Bildschirmfoto Shortcuts TastenkĂ¼rzel File Datei Frame/Sound Bild/Ton Playback Wiedergabe Subtitle Untertitel Font Style Schriftstil Restore Defaults Standardeinstellungen wiederherstellen Open file Ă–ffne Datei Open next Nächstes öffnen Open previous Vorheriges öffnen Mini mode Mini-Modus Mute Stummschalten Next frame Ein Bild vorwärts Previous frame Ein Bild zurĂ¼ck Volume down Lautstärke verringern Volume up Lautstärke erhöhen Speed up Geschwindigkeit erhöhen Speed down Geschwindigkeit verringern Fullscreen Vollbild Pause/Play Pause/Wiedergabe Playlist Wiedergabeliste Reset speed Geschwindigkeit zurĂ¼cksetzen Rewind ZurĂ¼ckspulen Forward Vorspulen Burst screenshot Serienbildaufnahmen-Screenshot Film screenshot Film-Bildschirmfoto 0.5s backward 0,5 s zurĂ¼ckspulen 0.5s forward 0,5 s vorspulen Font Schriftart Font Size SchriftgrĂ¶ĂŸe UrlDialog Cancel Abbrechen Confirm Bestätigen Please enter the URL: Bitte geben Sie die URL ein: dmr::ActionFactory Settings Einstellungen Fullscreen Vollbild Always on Top Immer im Vordergrund Film info Filminfo Open file Ă–ffne Datei Open folder Ordner öffnen Light theme Helles Thema Open URL URL öffnen Open CD/DVD CD/DVD öffnen Mini Mode Mini-Modus Play Mode Wiedergabemodus Order Play Geordnete Wiedergabe Shuffle Play Zufallswiedergabe Single Play Einzelwiedergabe Single Loop Einzelne Schleife List Loop Liste wiederholen Frame Bild Default Standard Clockwise Im Uhrzeigersinn Counterclockwise Gegen den Uhrzeigersinn Next frame Ein Bild vorwärts Previous frame Ein Bild zurĂ¼ck Sound Ton Channel Kanal Stereo Stereo Left channel Linker Kanal Right channel Rechter Kanal Track Musiktitel Subtitle Untertitel Load Laden Online Search Online-Suche Select Auswählen Hide Ausblenden Encodings Kodierungen Screenshot Bildschirmfoto Film Screenshot Film-Bildschirmfoto Burst Shooting Screenshot Playlist Wiedergabeliste Film Info Filminfo Clear playlist Wiedergabeliste leeren Display in file manager In Dateiverwaltung anzeigen dmr::BurstScreenshotsDialog Duration: %1 Dauer: %1 Resolution: %1 Auflösung: %1 Size: %1 GrĂ¶ĂŸe: %1 Save Speichern dmr::MainWindow Load successfully Erfolgreich geladen Load failed Laden fehlgeschlagen No device found Kein Gerät gefunden Parse Failed Auslesen fehlgeschlagen Open folder Ordner öffnen Open file Ă–ffne Datei All videos (%1) Alle Filme (%1) Muted Stumm Volume: %1% Lautstärke: %1% Subtitle %1: %2s Untertitel %1: %2s delayed verzögert advanced vorgerĂ¼ckt Speed: %1x Geschwindigkeit: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) Untertitel (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Ansicht Movie Screenshot Film-Screenshot Saved to Gespeichert in The screenshot is saved Screenshot gespeichert Failed to save the screenshot Bild konnte nicht gespeichert werden Invalid file: %1 UngĂ¼ltige Datei: %1 dmr::MovieInfo %1G %1G %1M %1M %1K %1K %1 %1 dmr::MovieInfoDialog File Type: Dateityp: Resolution: Auflösung: File Size: DateigrĂ¶ĂŸe: Duration: Dauer: File Path: Dateipfad: dmr::MpvProxy [internal] [intern] dmr::PlayItemWidget File does not exist Datei ist nicht vorhanden dmr::Settings %1/DMovie%2.jpg %1/DMovie%2.jpg %1/DMovie%2(%3).jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Wiedergeben Previous Vorherige Next Nächster Titel Subtitles Untertitel Playlist Wiedergabeliste Fullscreen Vollbild Play/Pause Wiedergeben/Pausieren Exit fullscreen Vollbild beenden Pause Pausieren deepin-movie-reborn-5.0.0/src/translations/deepin-movie_el.ts000066400000000000000000000677531351125414100243220ustar00rootroot00000000000000 QObject Deepin Movie Ταινίες Deepin Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Το Deepin Movie είναι ένα καλοσχεδιασμένο Ï€ÏόγÏαμμα αναπαÏαγωγής βίντεο με πολλαπλές δυνατότητες και με απλό σχεδιασμό. ΥποστηÏίζει την αναπαÏαγωγή τοπικÏν πολυμέσων αλλά και πολυμέσων Ïοής και παίζει σε Ï€Ïαγματικό χÏόνο αÏχεία και πολλαπλές μοÏφές βÏντεο. Invalid folder Open folder Άνοιγμα φακέλου You don't have permission to operate this folder Auto add similar files to play Clear playlist when exit Show video preview on mouseover Open a new player for each file played Pause when minimized ΠαÏση κατά την ελαχιστοποίηση Remember playback position Path ΔιαδÏομή Basic Βασικές Play ΑναπαÏαγωγή Screenshot Στιγμιότυπο οθόνης Shortcuts ΣυντομεÏσεις File ΑÏχείο Frame/Sound ÎάδÏο/Ήχος Playback ΑναπαÏαγωγή Subtitle Font Style Restore Defaults Ανάκτηση ΠÏοεπιλογÏν Open file Άνοιγμα αÏχείου Open next Άνοιγμα επόμενου Open previous Άνοιγμα Ï€ÏοηγοÏμενου Mini mode ΛειτουÏγία mini Mute Σίγαση Next frame Previous frame Volume down Μείωση έντασης Volume up ΑÏξηση έντασης Speed up Speed down Fullscreen ΠλήÏης οθόνη Pause/Play ΠαÏση/ΑναπαÏαγωγή Playlist Λίστα αναπαÏαγωγής Reset speed Rewind Πίσω Forward ΕμπÏός Burst screenshot Συνεχόμενο στιγμιότυπο οθόνης Film screenshot 0.5s backward 0.5s forward Font ΓÏαμματοσειÏά Font Size UrlDialog Cancel ΑκÏÏωση Confirm Επιβεβαίωση Please enter the URL: dmr::ActionFactory Settings Ρυθμίσεις Fullscreen ΠλήÏης οθόνη Always on Top Film info Open file Άνοιγμα αÏχείου Open folder Άνοιγμα φακέλου Light theme Open URL Άνοιγμα URL Open CD/DVD Mini Mode ΛειτουÏγία Mini Play Mode ΛειτουÏγία αναπαÏαγωγής Order Play Shuffle Play Single Play Single Loop List Loop Frame ÎάδÏο Default ΠÏοεπιλογή Clockwise Counterclockwise Next frame Previous frame Sound Ήχος Channel Kανάλι Stereo ΣτέÏεο Left channel Right channel Track Îομμάτι Subtitle Load Online Search Select Επιλογή Hide Encodings Screenshot Στιγμιότυπο οθόνης Film Screenshot Burst Shooting Playlist Λίστα αναπαÏαγωγής Film Info Clear playlist ΕκκαθάÏιση λίστας αναπαÏαγωγής Display in file manager ΠÏοβολή στη διαχείÏιση αÏχείων dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save Αποθήκευση dmr::MainWindow Load successfully Load failed No device found Parse Failed Open folder Άνοιγμα φακέλου Open file Άνοιγμα αÏχείου All videos (%1) Muted Σε σίγαση Volume: %1% Subtitle %1: %2s delayed advanced Speed: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Εμφάνιση Movie Screenshot Στιγμιότυπο οθόνης Ταινίας Saved to The screenshot is saved Failed to save the screenshot Invalid file: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Resolution: File Size: Duration: ΔιάÏκεια: File Path: dmr::MpvProxy [internal] dmr::PlayItemWidget File does not exist dmr::Settings %1/DMovie%2.jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play ΑναπαÏαγωγή Previous ΠÏοηγοÏμενο Next Επόμενο Subtitles Υπότιτλοι Playlist Λίστα αναπαÏαγωγής Fullscreen ΠλήÏης οθόνη Play/Pause ΑναπαÏαγωγή/ΠαÏση Exit fullscreen Έξοδος από πλήÏη οθόνη Pause ΠαÏση deepin-movie-reborn-5.0.0/src/translations/deepin-movie_en_AU.ts000066400000000000000000000645721351125414100247050ustar00rootroot00000000000000 QObject Deepin Movie Deepin Movie Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Invalid folder Open folder You don't have permission to operate this folder Auto add similar files to play Clear playlist when exit Show video preview on mouseover Open a new player for each file played Pause when minimized Remember playback position Path Basic Play Screenshot Screenshot Shortcuts File Frame/Sound Playback Subtitle Font Style Restore Defaults Open file Open file Open next Open previous Mini mode Mute Mute Next frame Previous frame Volume down Volume down Volume up Volume up Speed up Speed down Fullscreen Fullscreen Pause/Play Playlist Reset speed Rewind Forward Burst screenshot Film screenshot 0.5s backward 0.5s forward Font Font Size UrlDialog Cancel Cancel Confirm Confirm Please enter the URL: dmr::ActionFactory Settings Settings Fullscreen Fullscreen Always on Top Film info Open file Open file Open folder Light theme Open URL Open URL Open CD/DVD Mini Mode Play Mode Order Play Shuffle Play Single Play Single Loop List Loop Frame Default Default Clockwise Counterclockwise Next frame Previous frame Sound Sound Channel Channel Stereo Left channel Right channel Track Subtitle Load Online Search Select Select Hide Encodings Screenshot Screenshot Film Screenshot Burst Shooting Playlist Film Info Clear playlist Display in file manager dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save Save dmr::MainWindow Load successfully Load failed No device found Parse Failed Open folder Open file Open file All videos (%1) Muted Volume: %1% Subtitle %1: %2s delayed advanced Speed: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Movie Screenshot Saved to The screenshot is saved Failed to save the screenshot Invalid file: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Resolution: File Size: Duration: File Path: dmr::MpvProxy [internal] dmr::PlayItemWidget File does not exist dmr::Settings %1/DMovie%2.jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Previous Previous Next Next Subtitles Playlist Fullscreen Fullscreen Play/Pause Play/Pause Exit fullscreen Exit fullscreen Pause Pause deepin-movie-reborn-5.0.0/src/translations/deepin-movie_eo.ts000066400000000000000000000646121351125414100243140ustar00rootroot00000000000000 QObject Deepin Movie Deepin Filmujo Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Invalid folder Open folder You don't have permission to operate this folder Auto add similar files to play Clear playlist when exit Show video preview on mouseover Open a new player for each file played Pause when minimized Remember playback position Path Basic Play Ludi Screenshot Ekranbildo Shortcuts Fulmoklavoj File Frame/Sound Playback Subtitle Font Style Restore Defaults Open file Open next Open previous Mini mode Minimuma maniero Mute Muta Next frame Previous frame Volume down Volume up Speed up Speed down Fullscreen Tutekrana Pause/Play Playlist Ludilisto Reset speed Rewind Forward AntaÅ­en Burst screenshot Kreva ekranbildo Film screenshot 0.5s backward 0.5s forward Font Preslitero Font Size UrlDialog Cancel Nuligi Confirm Konfirmi Please enter the URL: dmr::ActionFactory Settings Agordoj Fullscreen Tutekrana Always on Top Film info Open file Open folder Light theme Open URL Malfermi URL Open CD/DVD Mini Mode Play Mode Order Play Shuffle Play Single Play Single Loop List Loop Frame Kadro Default DefaÅ­lta Clockwise Counterclockwise Next frame Previous frame Sound Sono Channel Kanalo Stereo Stereo Left channel Right channel Track Subtitle Load Online Search Select Hide Encodings Screenshot Ekranbildo Film Screenshot Burst Shooting Playlist Ludilisto Film Info Clear playlist Display in file manager dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save Gardi dmr::MainWindow Load successfully Load failed No device found Parse Failed Open folder Open file All videos (%1) Muted Volume: %1% Subtitle %1: %2s delayed advanced Speed: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Movie Screenshot Saved to The screenshot is saved Failed to save the screenshot Invalid file: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Resolution: File Size: Duration: File Path: dmr::MpvProxy [internal] dmr::PlayItemWidget File does not exist dmr::Settings %1/DMovie%2.jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Ludi Previous AntaÅ­a Next Sekva Subtitles Subtitoloj Playlist Ludilisto Fullscreen Tutekrana Play/Pause Exit fullscreen Pause PaÅ­zo deepin-movie-reborn-5.0.0/src/translations/deepin-movie_es.ts000066400000000000000000000700241351125414100243120ustar00rootroot00000000000000 QObject Deepin Movie PelĂ­culas Deepin Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Cinema Deepin es un reproductor de vĂ­deo de altas prestaciones, posee un diseño elegante sin bordes. Es compatible con la reproducciĂ³n de medios locales y streaming soportando mĂºltiples formatos de vĂ­deo. Invalid folder Carpeta no vĂ¡lida Open folder Abrir carpeta You don't have permission to operate this folder No tiene permiso para operar en esta carpeta Auto add similar files to play Agregar automĂ¡ticamente archivos similares para reproducir Clear playlist when exit Borrar lista de reproducciĂ³n al salir Show video preview on mouseover Mostrar vista previa del vĂ­deo con el puntero Open a new player for each file played Abrir un nuevo reproductor para cada archivo reproducido Pause when minimized Pausar al minimizar Remember playback position Recordar la posiciĂ³n de reproducciĂ³n Path Ruta de acceso Basic BĂ¡sico Play Reproducir Screenshot Captura de pantalla Shortcuts Atajos File Archivo Frame/Sound Cuadro/Sonido Playback ReproducciĂ³n Subtitle SubtĂ­tulos Font Style Estilo de fuente Restore Defaults Restaurar los valores predeterminados Open file Abrir archivo Open next Abrir siguiente Open previous Abrir anterior Mini mode Modo miniatura Mute Silenciar Next frame Siguiente fotograma Previous frame Anterior fotograma Volume down Bajar volumen Volume up Subir volumen Speed up Acelerar Speed down Ralentizar Fullscreen Pantalla completa Pause/Play Pausar/Reproducir Playlist Lista de reproducciĂ³n Reset speed Normalizar velocidad Rewind Retroceder Forward Adelantar Burst screenshot Captura de pantalla en rĂ¡faga Film screenshot Captura de pantalla de vĂ­deo 0.5s backward Avanzar 0.5s 0.5s forward Retroceder 0.5s Font Fuente Font Size Tamaño de la fuente UrlDialog Cancel Cancelar Confirm Confirmar Please enter the URL: Por favor, ingrese la URL: dmr::ActionFactory Settings ConfiguraciĂ³n Fullscreen Pantalla completa Always on Top Siempre al frente Film info InformaciĂ³n del vĂ­deo Open file Abrir archivo Open folder Abrir carpeta Light theme Tema Claro Open URL Abrir URL Open CD/DVD Abrir CD/DVD Mini Mode Modo Miniatura Play Mode Modo reproducciĂ³n Order Play Reproducir en orden Shuffle Play Reproducir al azar Single Play Reproducir una vez Single Loop RepeticiĂ³n simple List Loop RepeticiĂ³n en lista Frame Cuadro Default Predeterminado Clockwise Giro horario Counterclockwise Giro antihorario Next frame Siguiente fotograma Previous frame Anterior fotograma Sound Sonido Channel Canal Stereo EstĂ©reo Left channel Canal izquierdo Right channel Canal derecho Track Pista Subtitle SubtĂ­tulo Load Cargar Online Search BĂºsqueda en lĂ­nea Select Seleccionar Hide Esconder Encodings CodificaciĂ³n de datos Screenshot Captura de pantalla Film Screenshot Captura de vĂ­deo Burst Shooting Captura en rĂ¡faga Playlist Lista de reproducciĂ³n Film Info InformaciĂ³n del vĂ­deo Clear playlist Borrar lista de reproducciĂ³n Display in file manager Mostrar en administrador de archivos dmr::BurstScreenshotsDialog Duration: %1 duraciĂ³n: %1 Resolution: %1 resoluciĂ³n: %1 Size: %1 tamaño: %1 Save Guardar dmr::MainWindow Load successfully Carga exitosa Load failed Carga fallida No device found Dispositivo no encontrado Parse Failed Pase fallido Open folder Abrir carpeta Open file Abrir archivo All videos (%1) Todos los vĂ­deos (%1) Muted Silenciado Volume: %1% Volumen: %1% Subtitle %1: %2s SubtĂ­tulo %1: %2s delayed retrasado advanced avanzado Speed: %1x Velocidad: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) SubtĂ­tulo (* .ass * .aqt * .jss * .gsub * .ssf * .srt * .sub * .ssa * .smi * .usf * .idx) View Ver Movie Screenshot Captura de pantalla de vĂ­deo Saved to Guardado a The screenshot is saved La captura de pantalla fue guardada Failed to save the screenshot FallĂ³ al guardar la captura Invalid file: %1 Archivo invĂ¡lido: %1 dmr::MovieInfo %1G %1G %1M %1M %1K %1K %1 %1 dmr::MovieInfoDialog File Type: Tipo de archivo: Resolution: ResoluciĂ³n: File Size: Tamaño archivo: Duration: DuraciĂ³n: File Path: Ruta del archivo: dmr::MpvProxy [internal] [interno] dmr::PlayItemWidget File does not exist El archivo no existe dmr::Settings %1/DMovie%2.jpg %1/DMovie%2.jpg %1/DMovie%2(%3).jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Reproducir Previous Anterior Next Siguiente Subtitles Subtitulos Playlist Lista de reproducciĂ³n Fullscreen Pantalla completa Play/Pause Reproducir/Pausar Exit fullscreen Salir de pantalla completa Pause Pausar deepin-movie-reborn-5.0.0/src/translations/deepin-movie_es_419.ts000066400000000000000000000700121351125414100247040ustar00rootroot00000000000000 QObject Deepin Movie PelĂ­culas Deepin Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Cinema Deepin es un reproductor de vĂ­deo de altas prestaciones, posee un diseño elegante sin bordes. Es compatible con la reproducciĂ³n de medios locales y streaming soportando mĂºltiples formatos de vĂ­deo. Invalid folder Carpeta no vĂ¡lida Open folder Abrir Carpeta You don't have permission to operate this folder No tiene permiso para operar esta carpeta Auto add similar files to play Agregar automĂ¡ticamente archivos similares para reproducir Clear playlist when exit Borrar lista de reproducciĂ³n al salir Show video preview on mouseover Mostrar vista previa del vĂ­deo con el puntero Open a new player for each file played Abrir un nuevo reproductor para cada archivo reproducido Pause when minimized Pausar al minimizar Remember playback position Recordar la posiciĂ³n de reproducciĂ³n Path Ruta de acceso Basic BĂ¡sico Play Reproducir Screenshot Captura de pantalla Shortcuts Atajos File Archivo Frame/Sound Cuadro/Sonido Playback ReproducciĂ³n Subtitle SubtĂ­tulos Font Style Estilo de fuente Restore Defaults Restaurar los valores predeterminados Open file Abrir archivo Open next Abrir siguiente Open previous Abrir anterior Mini mode Modo miniatura Mute Silenciar Next frame Siguiente fotograma Previous frame Anterior fotograma Volume down Bajar volumen Volume up Subir volumen Speed up Acelerar Speed down Ralentizar Fullscreen Pantalla completa Pause/Play Pausar/Reproducir Playlist Lista de reproducciĂ³n Reset speed Normalizar velocidad Rewind Retroceder Forward Adelantar Burst screenshot Captura de pantalla de rĂ¡faga Film screenshot Captura de pantalla de vĂ­deo 0.5s backward Avanzar 0.5s 0.5s forward Retroceder 0.5s Font Fuente Font Size Tamaño de la fuente UrlDialog Cancel Cancelar Confirm Confirmar Please enter the URL: Por favor, ingrese la URL: dmr::ActionFactory Settings ConfiguraciĂ³n Fullscreen Pantalla completa Always on Top Siempre al frente Film info Detalle del vĂ­deo Open file Abrir archivo Open folder Abrir Carpeta Light theme Tema Claro Open URL Abrir URL Open CD/DVD Abrir CD/DVD Mini Mode Modo Miniatura Play Mode Modo reproducciĂ³n Order Play Reproducir en orden Shuffle Play Reproducir al azar Single Play Reproducir una vez Single Loop RepeticiĂ³n simple List Loop RepeticiĂ³n en lista Frame Cuadro Default Predeterminado Clockwise Giro horario Counterclockwise Giro antihorario Next frame Siguiente fotograma Previous frame Anterior fotograma Sound Sonido Channel Canal Stereo EstĂ©reo Left channel Canal izquierdo Right channel Canal derecho Track Pista Subtitle SubtĂ­tulo Load Cargar Online Search BĂºsqueda en lĂ­nea Select Seleccionar Hide Esconder Encodings CodificaciĂ³n de datos Screenshot Captura de pantalla Film Screenshot Captura de vĂ­deo Burst Shooting Captura de movimiento Playlist Lista de reproducciĂ³n Film Info Detalle del vĂ­deo Clear playlist Borrar lista de reproducciĂ³n Display in file manager Mostrar en administrador de archivos dmr::BurstScreenshotsDialog Duration: %1 DuraciĂ³n %1 Resolution: %1 ResoluciĂ³n %1 Size: %1 Tamaño %1 Save Guardar dmr::MainWindow Load successfully Carga exitosa Load failed Carga fallida No device found Dispositivo no encontrado Parse Failed Pase fallido Open folder Abrir Carpeta Open file Abrir archivo All videos (%1) Todos los videos (%1) Muted Silenciado Volume: %1% Volumen: %1% Subtitle %1: %2s SubtĂ­tulo %1: %2s delayed retrasado advanced avanzado Speed: %1x Velocidad: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) Subtitulos (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Ver Movie Screenshot Captura de pantalla de vĂ­deo Saved to Guardado a The screenshot is saved La captura de pantalla fue guardada Failed to save the screenshot Error al guardar la captura de pantalla Invalid file: %1 Archivo invĂ¡lido: %1 dmr::MovieInfo %1G %1G %1M %1M %1K %1K %1 %1 dmr::MovieInfoDialog File Type: Tipo de archivo: Resolution: ResoluciĂ³n: File Size: Tamaño archivo: Duration: DuraciĂ³n: File Path: Ruta del archivo: dmr::MpvProxy [internal] [interno] dmr::PlayItemWidget File does not exist El archivo no existe dmr::Settings %1/DMovie%2.jpg %1/DMovie%2.jpg %1/DMovie%2(%3).jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Reproducir Previous Anterior Next Siguiente Subtitles Subtitulos Playlist Lista de reproducciĂ³n Fullscreen Pantalla completa Play/Pause Reproducir/Pausar Exit fullscreen Salir de pantalla completa Pause Pausar deepin-movie-reborn-5.0.0/src/translations/deepin-movie_fa.ts000066400000000000000000000712521351125414100242750ustar00rootroot00000000000000 QObject Deepin Movie Deepin Movie (نرم Ø§ÙØ²Ø§Ø± تماشای Ùیلم دیپین) Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. دیپین مووی یک پخش کننده ویدئویی با طراحی خوب Ùˆ کامل با طراحی ساده Ùˆ بدون محدودیت است. این برنامه از پخش رسانه های محلی Ùˆ استریم با ÙØ±Ù…ت های مختل٠ویدیویی پشتیبانی Ù…ÛŒ کند. Invalid folder پوشه نامعتبر Open folder باز کردن پوشه You don't have permission to operate this folder شما مجوز کار با این پوشه را ندارید Auto add similar files to play به صورت خودکار ÙØ§ÛŒÙ„ های مشابه را برای اجرا اضاÙÙ‡ Ú©Ù† Clear playlist when exit پاک کردن لیست پخش هنگام خروج Show video preview on mouseover نمایش پیش نمایش ویدیو با اشاره ماوس Open a new player for each file played باز کردن یک پلیر جدید برای هر ÙØ§ÛŒÙ„ اجرا شده Pause when minimized توق٠در هنگام کمینه Remember playback position بازیابی موقعیت پخش Path مسیر Basic پایه ای Play پخش Screenshot تصویر از ØµÙØ­Ù‡ Shortcuts میانبر File ÙØ§ÛŒÙ„ Frame/Sound ÙØ±ÛŒÙ…/صدا Playback بازنواخت Subtitle زیرنویس Font Style سبک Ùونت Restore Defaults بازگرداندن پیش ÙØ±Ø¶ ها Open file باز کردن ÙØ§ÛŒÙ„ Open next باز کردن بعدی Open previous باز کردن قبلی Mini mode حالت Ú©ÙˆÚ†Ú© Mute بی صدا Next frame ÙØ±ÛŒÙ… بعدی Previous frame ÙØ±ÛŒÙ… قبلی Volume down کاهش صدا Volume up Ø§ÙØ²Ø§ÛŒØ´ صدا Speed up Ø§ÙØ²Ø§ÛŒØ´ سرعت Speed down کاهش سرعت Fullscreen تمام ØµÙØ­Ù‡ Pause/Play وقÙÙ‡/اجرا Playlist لیست پخش Reset speed برگرداندن سرعت Rewind به عقب Forward به جلو Burst screenshot عکس Ú¯Ø±ÙØªÙ† Film screenshot عکس Ú¯Ø±ÙØªÙ† از Ùیلم 0.5s backward 0.5s رو به عقب 0.5s forward 0.5s رو به جلو Font Ùونت Font Size سایز Ùونت UrlDialog Cancel انصرا٠Confirm تایید Please enter the URL: Ù„Ø·ÙØ§ URL را وارد نمایید dmr::ActionFactory Settings تنظیمات Fullscreen تمام ØµÙØ­Ù‡ Always on Top همیشه رو باشد Film info دریاره Ùیلم Open file باز کردن ÙØ§ÛŒÙ„ Open folder باز کردن پوشه Light theme تم روشن Open URL باز کردن URL Open CD/DVD باز کردن CD/DVF Mini Mode حالت Ú©ÙˆÚ†Ú© Play Mode حالت پخش Order Play اجرای Ø³ÙØ§Ø±Ø´ÛŒ Shuffle Play اجرای درهم Single Play اجرای تک Single Loop تکرار یک مورد List Loop لیست تکرار Frame ÙØ±ÛŒÙ… Default پیش ÙØ±Ø¶ Clockwise ساعت گرد Counterclockwise پاد ساعتگرد Next frame ÙØ±ÛŒÙ… بعدی Previous frame ÙØ±ÛŒÙ… قبلی Sound صدا Channel کانال Stereo استریو Left channel کانال Ú†Ù¾ Right channel کانال راست Track ترک Subtitle زیرنویس Load بارگذاری Online Search جستجوی آنلاین Select انتخاب Hide مخÙÛŒ Encodings رمزگذاری Screenshot تصویر از ØµÙØ­Ù‡ Film Screenshot عکس از Ùیلم Burst Shooting عکس متوالی Playlist لیست پخش Film Info درباره Ùیلم Clear playlist پاک کردن لیست اجرا Display in file manager نمایش درمدیریت ÙØ§ÛŒÙ„ dmr::BurstScreenshotsDialog Duration: %1 مدت زمان 1% Resolution: %1 وضوح 1% Size: %1 سایز 1% Save ذخیره dmr::MainWindow Load successfully با موÙقیت بازگذاری شد Load failed بارگذاری ناموÙÙ‚ بود No device found دستگاهی پیدا نشد Parse Failed تجزیه شکست خورد Open folder باز کردن پوشه Open file باز کردن ÙØ§ÛŒÙ„ All videos (%1) همه ویدیو ها (1%) Muted بی صدا شده Volume: %1% صدا %1% Subtitle %1: %2s زیرنویس %1:s2% delayed تعویق Ø§ÙØªØ§Ø¯Ù‡ advanced Ù¾ÛŒØ´Ø±ÙØªÙ‡ Speed: %1x سرعت: x1% Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) زیرنویس (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View نما Movie Screenshot اسکرین شات از Ùیلم Saved to ذخیره شده در The screenshot is saved اسکرین شات ذخیره شد Failed to save the screenshot اسکرین شات نتوانست ذخیره شود Invalid file: %1 ÙØ§Ø¨Ù„ نامعتبر : 1% dmr::MovieInfo %1G %1G %1M %1M %1K %1K %1 %1 dmr::MovieInfoDialog File Type: نوع ÙØ§ÛŒÙ„ : Resolution: وضوح : File Size: حجم ÙØ§ÛŒÙ„ : Duration: مدت: File Path: مسیر ÙØ§ÛŒÙ„ : dmr::MpvProxy [internal] [داخلی] dmr::PlayItemWidget File does not exist ÙØ§ÛŒÙ„ وجود ندارد dmr::Settings %1/DMovie%2.jpg %1/DMovie%2.jpg %1/DMovie%2(%3).jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play پخش Previous پیشین Next بعدی Subtitles زیرنویس ها Playlist لیست پخش Fullscreen تمام ØµÙØ­Ù‡ Play/Pause پخش/Ù…Ú©Ø« Exit fullscreen خروج از تمام ØµÙØ­Ù‡ Pause Ù…Ú©Ø« deepin-movie-reborn-5.0.0/src/translations/deepin-movie_fi.ts000066400000000000000000000673771351125414100243220ustar00rootroot00000000000000 QObject Deepin Movie Deepin Elokuvat Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Deepin Elokuva on erinomaisesti suunniteltu ja kattavilla ominaisuuksilla varusteltu yksinkertainen ja tyylikäs videosoitin. Se tukee useiden eri videoformaattien paikallis- ja suoratoistosoittoa. Invalid folder Virheellinen kansio Open folder Avaa kansio You don't have permission to operate this folder Sinulla ei ole lupaa käyttää tätä kansiota Auto add similar files to play Lisää samankaltaisia tiedostoja automaattisesti Clear playlist when exit Tyhjennä soittolista lopettaessasi Show video preview on mouseover Näytä videon esikatselukuva hiirellä Open a new player for each file played Avaa uusi soitin jokaiselle toistetulle tiedostolle Pause when minimized Keskeytä toisto pienennettäessä Remember playback position Muista toiston sijainti Path Polku Basic Perusasetukset Play Toista Screenshot Kuvakaappaus Shortcuts Pikanäppäimet File Tiedosto Frame/Sound Kuvaruudut/Ääni Playback Toisto Subtitle Tekstitys Font Style Fonttityyli Restore Defaults Palauta oletukset Open file Avaa tiedosto Open next Avaa seuraava Open previous Avaa edellinen Mini mode Minitila Mute Vaienna Next frame Seuraava kuvaruutu Previous frame Edellinen kuvaruutu Volume down Äänitaso alas Volume up Äänitaso ylös Speed up Nopeuta Speed down Hidasta Fullscreen Koko näytön tila Pause/Play Keskeytä/Soita Playlist Soittolista Reset speed Nollaa nopeus Rewind Taaksepäin Forward Eteenpäin Burst screenshot Kuvakaappaus sarja Film screenshot Filmin kuvakaappaus 0.5s backward 0.5s taaksepäin 0.5s forward 0.5s eteenpäin Font Fontti Font Size Fonttikoko UrlDialog Cancel Peruuta Confirm Vahvista Please enter the URL: Syötä URL: dmr::ActionFactory Settings Asetukset Fullscreen Koko näytön tila Always on Top Aina päällimmäisenä Film info Tiedoston info Open file Avaa tiedosto Open folder Avaa kansio Light theme Vaalea teema Open URL Avaa URL Open CD/DVD Avaa CD/DVD Mini Mode Minitila Play Mode Toistotila Order Play Soittojärjestys Shuffle Play Sekoita soittojärjestys Single Play Toista yksi Single Loop Yhden jatkuva toisto List Loop Listan jatkuva toisto Frame Kuvasuhde Default Oletus Clockwise Myötäpäivään Counterclockwise Vastapäivään Next frame Seuraava kuvaruutu Previous frame Edellinen kuvaruutu Sound Ääni Channel Kanava Stereo Stereo Left channel Vasen kanava Right channel Oikea kanava Track Ääniraita Subtitle Tekstitys Load Lataa Online Search Online-haku Select Valitse Hide Piilota Encodings Koodaukset Screenshot Kuvakaappaus Film Screenshot Filmin kuvakaappaus Burst Shooting Sarjakuvaus Playlist Soittolista Film Info Tiedoston info Clear playlist Tyhjennä soittolista Display in file manager Näytä tiedostonhallinnassa dmr::BurstScreenshotsDialog Duration: %1 Kesto: %1 Resolution: %1 Resoluutio: %1 Size: %1 Koko: %1 Save Tallenna dmr::MainWindow Load successfully Lataus onnistui Load failed Lataus epäonnistui No device found Laitetta ei löytynyt Parse Failed Jäsentely epäonnistui Open folder Avaa kansio Open file Avaa tiedosto All videos (%1) Kaikki videot (%1) Muted Vaiennettu Volume: %1% Äänitaso: %1% Subtitle %1: %2s Tekstitys %1: %2s delayed myöhässä advanced edistynyt Speed: %1x Nopeus: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) Tekstitys (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Näytä Movie Screenshot Elokuvan kuvakaappaus Saved to Tallenna nimellä The screenshot is saved Kuvakaappaus tallennettu Failed to save the screenshot Kuvakaappauksen tallentaminen epäonnistui Invalid file: %1 Virheellinen tiedosto: %1 dmr::MovieInfo %1G %1G %1M %1M %1K %1K %1 %1 dmr::MovieInfoDialog File Type: Tiedostotyyppi: Resolution: Resoluutio: File Size: Tiedoston koko: Duration: Kesto: File Path: Tiedoston polku: dmr::MpvProxy [internal] [sisäinen] dmr::PlayItemWidget File does not exist Tiedostoa ei ole dmr::Settings %1/DMovie%2.jpg %1/DMovie%2.jpg %1/DMovie%2(%3).jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Toista Previous Edellinen Next Seuraava Subtitles Tekstitys Playlist Soittolista Fullscreen Kokoruutu Play/Pause Toista/Keskeytä Exit fullscreen Poistu kokoruudusta Pause Pysäytä deepin-movie-reborn-5.0.0/src/translations/deepin-movie_fil.ts000066400000000000000000000666171351125414100244720ustar00rootroot00000000000000 QObject Deepin Movie Deepin Music Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Invalid folder Open Folder You don't have permission to operate this folder Auto add similar files to play Clear playlist when exit Show video preview on mouseover Open a new player for each file played Pause when minimized Remember playback position Path Basic Play Screenshot Shortcuts File Frame/Sound Playback Subtitle Font Style Restore Defaults Open file Open next Open previous Mini mode Mute Next frame Previous frame volume down Volume up Speed up Speed down Fullscreen Pause/Play Playlist Reset speed Rewind Forward Burst screenshot Film screenshot 0.5s backward 0.5s forward Font Font Size UrlDialog Cancel Confirm Please enter the URL: dmr::ActionFactory Open File Settings Light Theme Fullscreen Always on Top Film info Open Folder Open URL Open CD/DVD Mini Mode Play Mode Order Play Shuffle Play Single Play Single Loop List Loop Frame Default Clockwise Counterclockwise Next frame Previous frame Sound Channel Stereo Left channel Right channel Track Subtitle Load Online Search Select Hide Encodings Screenshot Film Screenshot Burst Shooting Playlist Film Info Clear playlist Display in file manager dmr::BurstScreenshotsDialog duration: %1 resolution: %1 size: %1 save dmr::MainWindow Deepin Movie Deepin Music Load successfully Load failed No device found Parse Failed Open Folder Open File All videos (%1) Muted Volume: %1% Subtitle %1: %2s delayed advanced Speed: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Movie Screenshot Saved to The screenshot is saved The screenshot is failed to save Invalid file: %1 dmr::MovieInfoDialog File Type: Resolution: File Size: Duration: File Path: dmr::MpvProxy [internal] dmr::PlayItemWidget File does not exist dmr::Settings %1/DMovie%2.jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Previous Next Subtitles Playlist Fullscreen Play/Pause Exit fullscreen Pause deepin-movie-reborn-5.0.0/src/translations/deepin-movie_fr.ts000066400000000000000000000700201351125414100243060ustar00rootroot00000000000000 QObject Deepin Movie Deepin Movie Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Deepin Movie est un lecteur vidĂ©o visuellement agrĂ©able et très complet. Il prend en charge la lecture ainsi que le « streaming » de fichiers en diffĂ©rents formats. Invalid folder Dossier non valide Open folder Ouvrir un dossier You don't have permission to operate this folder Vous n'avez pas la permission d'agir sur ce dossier Auto add similar files to play Ajouter automatiquement des fichiers similaires Ă  la liste de lecture Clear playlist when exit Vider la liste de lecture en quittant Show video preview on mouseover PrĂ©visualiser au passage de la souris Open a new player for each file played Ouvrir un nouveau lecteur pour chaque fichier jouĂ© Pause when minimized Mettre en pause lorsque rĂ©duit Remember playback position MĂ©moriser la position de lecture Path Chemin Basic Simple Play Lecture Screenshot Capture d'Ă©cran Shortcuts Raccourcis File Fichier Frame/Sound Image/Son Playback Lecture Subtitle Sous-titre Font Style Style de police Restore Defaults Restaurer les valeurs par dĂ©faut Open file Ouvrir le fichier Open next Ouvrir suivant Open previous Ouvrir prĂ©cĂ©dent Mini mode Mode minimal Mute Muet Next frame Image suivante Previous frame Image prĂ©cĂ©dente Volume down Diminuer le volume Volume up Augmenter le volume Speed up AccĂ©lerer Speed down Ralentir Fullscreen Plein Ă©cran Pause/Play Pause/Lecture Playlist Liste de lecture Reset speed RĂ©initialiser la vitesse Rewind Reculer Forward Avancer Burst screenshot Capture d'Ă©cran en rafale Film screenshot Capture d'Ă©cran du film 0.5s backward 0,5 s en arrière 0.5s forward 0,5 s en avant Font Police Font Size Taille de police UrlDialog Cancel Annuler Confirm Confirmer Please enter the URL: Veuillez entrer l'URL : dmr::ActionFactory Settings Paramètres Fullscreen Plein Ă©cran Always on Top Toujours au premier plan Film info Infos du film Open file Ouvrir un fichier Open folder Ouvrir un dossier Light theme Thème clair Open URL Ouvrir un lien Open CD/DVD Ouvrir un CD/DVD Mini Mode Mode miniature Play Mode Mode de lecture Order Play Ordre de lecture Shuffle Play Lecture alĂ©atoire Single Play Lecture seule Single Loop RĂ©pĂ©ter le morceau List Loop RĂ©pĂ©ter la liste Frame Image Default Par dĂ©faut Clockwise Dans le sens horaire Counterclockwise Sens antihoraire Next frame Image suivante Previous frame Image prĂ©cĂ©dente Sound Son Channel Canal Stereo StĂ©rĂ©o Left channel Canal gauche Right channel Canal droit Track Piste Subtitle Sous-titre Load Charger Online Search Recherche en ligne Select Choisir Hide Cacher Encodings Encodages Screenshot Capture d'Ă©cran Film Screenshot Capture d'Ă©cran du film Burst Shooting Mode rafale Playlist Liste de lecture Film Info Infos du film Clear playlist Vider la liste de lecture Display in file manager Afficher dans le gestionnaire de fichiers dmr::BurstScreenshotsDialog Duration: %1 DurĂ©e : %1 Resolution: %1 RĂ©solution : %1 Size: %1 Taille : %1 Save Sauvegarder dmr::MainWindow Load successfully Chargement rĂ©ussi Load failed Échec du chargement No device found Aucun pĂ©riphĂ©rique trouvĂ© Parse Failed Échec de l'analyse Open folder Ouvrir un dossier Open file Ouvrir un fichier All videos (%1) Toutes les vidĂ©os (%1) Muted Sourdine Volume: %1% Volume : %1% Subtitle %1: %2s Sous-titre %1 : %2s delayed RetardĂ© advanced avancĂ© Speed: %1x Vitesse : %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) Sous-titres (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Vue Movie Screenshot Capture d'Ă©cran du film Saved to SauvegardĂ© dans The screenshot is saved Capture d'Ă©cran enregistrĂ©e Failed to save the screenshot Échec de la sauvegarde de la capture d'Ă©cran Invalid file: %1 Fichier non valide : %1 dmr::MovieInfo %1G %1 GO %1M %1 MO %1K %1 KO %1 %1 dmr::MovieInfoDialog File Type: Type de fichier : Resolution: RĂ©solution : File Size: Taille du fichier : Duration: DurĂ©e : File Path: Emplacement du fichier : dmr::MpvProxy [internal] [interne] dmr::PlayItemWidget File does not exist Le fichier n'existe pas dmr::Settings %1/DMovie%2.jpg %1/DMovie%2.jpg %1/DMovie%2(%3).jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Lecture Previous PrĂ©cĂ©dent Next Suivant Subtitles Sous-titres Playlist Liste de lecture Fullscreen Plein Ă©cran Play/Pause Lecture / Pause Exit fullscreen Quitter le mode plein Ă©cran Pause Pause deepin-movie-reborn-5.0.0/src/translations/deepin-movie_gl_ES.ts000066400000000000000000000674451351125414100247110ustar00rootroot00000000000000 QObject Deepin Movie Filmes Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Filmes Ă© un reprodutor de vĂ­deo cun bo deseño e cheo de funciĂ³ns, cun deseño de bordos sinxelos. É compatible con todo tipo de formatos de vĂ­deo tanto de medios locais como de transmisiĂ³n remota. Invalid folder O cartafol non Ă© vĂ¡lido Open folder Abrir cartafol You don't have permission to operate this folder Non ten permisos para acceder a este cartafol Auto add similar files to play Engadir automĂ¡ticamente ficheiros similares para reproducir Clear playlist when exit Baleirar a listaxe de reproduciĂ³n cando saia Show video preview on mouseover Amosar vista previa ao por o rato enriba Open a new player for each file played Abrir un reprodutor por cada ficheiro Pause when minimized Pausar cando estĂ¡ minimizado Remember playback position Lembrar a posiciĂ³n de reproduciĂ³n Path Ruta Basic BĂ¡sico Play Reproducir Screenshot Captura de pantalla Shortcuts Atallos File Ficheiro Frame/Sound Cadro/Son Playback Reproducir Subtitle SubtĂ­tulos Font Style Estilo da fonte Restore Defaults Restablecer o predefinido Open file Abrir ficheiro Open next Abrir seguinte Open previous Abrir anterior Mini mode Modo reducido Mute Silenciar Next frame Previous frame Volume down Baixar o volume Volume up Subir o volume Speed up Aumentar a velocidade Speed down DiminuĂ­r a velocidade Fullscreen Pantalla completa Pause/Play Pausar/Reproducir Playlist Lista de reproduciĂ³n Reset speed Restabelecer a velocidade Rewind Retroceder Forward Adiantar Burst screenshot Captura de pantalla Film screenshot Captura do filme 0.5s backward Retroceder 0,5s 0.5s forward Adiantar 0,5s Font Fonte Font Size Tamaño da fonte UrlDialog Cancel Cancelar Confirm Confirmar Please enter the URL: Por favor, introduce o URL: dmr::ActionFactory Settings Axustes Fullscreen Pantalla completa Always on Top Sempre visible Film info InformaciĂ³n do filme Open file Abrir ficheiro Open folder Abrir cartafol Light theme Open URL Abrir URL Open CD/DVD Abrir CD/DVD Mini Mode Modo reducido Play Mode Modo de reproduciĂ³n Order Play Orde de reproduciĂ³n Shuffle Play ReproduciĂ³n aleatoria Single Play Reproducir unha vez Single Loop Un sĂ³ bucle List Loop Lista en bucle Frame Fotograma Default Predefinido Clockwise Sentido do reloxo Counterclockwise Conta atrĂ¡s Next frame Previous frame Sound Son Channel Canle Stereo EstĂ©reo Left channel Canle esquerda Right channel Canle dereita Track Pista Subtitle SubtĂ­tulos Load Cargar Online Search Buscar na rede Select Seleccionar Hide Ocultar Encodings CodificaciĂ³ns Screenshot Captura de pantalla Film Screenshot Captura do filme Burst Shooting Captura en RĂ¡faga Playlist Lista de reproduciĂ³n Film Info InformaciĂ³n do filme Clear playlist Baleirar a listaxe de reproduciĂ³n Display in file manager Amosar no xestor de ficheiros dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save Gardar dmr::MainWindow Load successfully Cargado/a con Ă©xito Load failed Produciuse un erro ao cargar No device found Non se atopou ningĂºn dispositivo Parse Failed A anĂ¡lise fallou Open folder Abrir cartafol Open file Abrir ficheiro All videos (%1) Todos os vĂ­deos (%1) Muted Silenciar Volume: %1% Volume: %1% Subtitle %1: %2s SubtĂ­tulos %1: %2s delayed atrasado advanced avanzado Speed: %1x Velocidade: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Ver Movie Screenshot Captura do filme Saved to Gardar en The screenshot is saved A captura da pantalla foi gardada Failed to save the screenshot Invalid file: %1 Ficheiro non vĂ¡lido: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Tipo de ficheiro: Resolution: ResoluciĂ³n: File Size: Tamaño do ficheiro: Duration: DuraciĂ³n: File Path: Ruta do ficheiro: dmr::MpvProxy [internal] [internal] dmr::PlayItemWidget File does not exist O ficheiro non existe dmr::Settings %1/DMovie%2.jpg %1/DMovie%2.jpg %1/DMovie%2(%3).jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Reproducir Previous Anterior Next Seguinte Subtitles SubtĂ­tulos Playlist Lista de reproduciĂ³n Fullscreen Pantalla completa Play/Pause Rep./Pausar Exit fullscreen SaĂ­r da pantalla completa Pause Pausar deepin-movie-reborn-5.0.0/src/translations/deepin-movie_he.ts000066400000000000000000000657671351125414100243210ustar00rootroot00000000000000 QObject Deepin Movie נגן ×”×¡×¨×˜×™× ×©×œ Deepin Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Deepin Movie ×”×•× × ×’×Ÿ ויד×ו עשיר ו×עוצב, התו×× ×‘× ×™×’×•×Ÿ ×§×‘×¦×™× ×קו××™×™× ×•×וזר××™× ×‘×¤×•×¨××˜×™× ×©×•× ×™× Invalid folder Open folder פתח תיקייה You don't have permission to operate this folder Auto add similar files to play Clear playlist when exit Show video preview on mouseover Open a new player for each file played Pause when minimized השהה ניגון ×›×שר ××וזער Remember playback position Path Basic בסיסי Play × ×’×™× ×” Screenshot ×¦×™×œ×•× ××¡× Shortcuts קיצורי ××§×©×™× File קובץ Frame/Sound פריי×/ש××¢ Playback הש××¢×” Subtitle Font Style Restore Defaults Open file פתח קובץ Open next פתח ×ת ×”×‘× Open previous פתח ×ת ×”×§×•×“× Mini mode ×צב ×וקטן Mute השתקה Next frame Previous frame Volume down ×”× ××›×” Volume up הגברה Speed up העלה ×הירות Speed down Fullscreen ××¡× ××œ× Pause/Play השהה/נגן Playlist רשי×ת × ×’×™× ×” Reset speed Rewind ×חורה Forward קדי××” Burst screenshot Film screenshot 0.5s backward 0.5s forward Font גופן Font Size UrlDialog Cancel ביטול Confirm ××™×ות Please enter the URL: dmr::ActionFactory Settings הגדרות Fullscreen ××¡× ××œ× Always on Top Film info Open file פתח קובץ Open folder פתח תיקייה Light theme Open URL פתח קישור Open CD/DVD Mini Mode ×צג ×וקטן Play Mode ×צב × ×’×™× ×” Order Play Shuffle Play Single Play Single Loop List Loop Frame ×¤×¨×™×™× Default ברירת ×חדל Clockwise Counterclockwise Next frame Previous frame Sound ש××¢ Channel ערוץ Stereo Left channel Right channel Track קטע Subtitle Load Online Search Select בחר Hide Encodings Screenshot ×¦×™×œ×•× ××¡× Film Screenshot Burst Shooting Playlist רשי×ת × ×’×™× ×” Film Info Clear playlist × ×§×” רשי×ת הש××¢×” Display in file manager הצגה ב×נהל ×”×§×‘×¦×™× dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save ש×ור dmr::MainWindow Load successfully Load failed No device found Parse Failed Open folder פתח תיקייה Open file פתח קובץ All videos (%1) Muted ×ושתק Volume: %1% Subtitle %1: %2s delayed advanced Speed: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View תצוגה Movie Screenshot Saved to The screenshot is saved Failed to save the screenshot Invalid file: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Resolution: File Size: Duration: ×ש×: File Path: dmr::MpvProxy [internal] dmr::PlayItemWidget File does not exist dmr::Settings %1/DMovie%2.jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play × ×’×™× ×” Previous ×”×§×•×“× Next ×”×‘× Subtitles כתוביות Playlist רשי×ת × ×’×™× ×” Fullscreen ××¡× ××œ× Play/Pause × ×’×™× ×”/השהיה Exit fullscreen ×¦× ×××¡× ××œ× Pause השהיה deepin-movie-reborn-5.0.0/src/translations/deepin-movie_hi_IN.ts000066400000000000000000000677121351125414100247030ustar00rootroot00000000000000 QObject Deepin Movie डीपइन à¤à¤²à¤à¤¿à¤¤à¥à¤° Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. डीपइन मूवी अà¤à¥à¤›à¥€ तरह से बनाया हà¥à¤† पूरी तरह से à¤à¤• वीडियो पà¥à¤²à¥‡à¤¯à¤° है। जो सà¥à¤¥à¤¾à¤¨à¥€à¤¯ और इंटरनेट मीडिया à¥à¤¾à¤‡à¤² के कई पà¥à¤°à¤¾à¤°à¥‚प में कारà¥à¤¯ करता है। Invalid folder Open folder You don't have permission to operate this folder Auto add similar files to play Clear playlist when exit Show video preview on mouseover Open a new player for each file played Pause when minimized नीà¤à¥‡ करने पर रोकें Remember playback position पà¥à¤²à¥‡à¤¬à¥ˆà¤• सà¥à¤¥à¤¿à¤¤à¤¿ याद रखें Path Basic मौलिक Play à¤à¤²à¤¾à¤¯à¥‡à¤‚ Screenshot सà¥à¤•à¥à¤°à¥€à¤¨à¤¶à¥‰à¤Ÿ Shortcuts शॉरà¥à¤Ÿà¤•ट File à¥à¤¾à¤‡à¤² Frame/Sound ढांà¤à¤¾ / धà¥à¤µà¤¨à¤¿ Playback पà¥à¤¨à¤°à¥à¤à¤²à¤¨ Subtitle Font Style Restore Defaults डिफॉलà¥à¤Ÿà¥à¤¸ पà¥à¤¨à¤ƒà¤¸à¥à¤¥à¤¾à¤ªà¤¿à¤¤ करें Open file à¥à¤¾à¤‡à¤² खोलें Open next अगला खोलें Open previous पिछला खोलें Mini mode छोटा विधा Mute मूक Next frame Previous frame Volume down आवाज घटाà¤à¤ Volume up आवाज बà¥à¤¾à¤à¤ Speed up Speed down Fullscreen पूरà¥à¤£ पटल Pause/Play विराम/शà¥à¤°à¥‚ Playlist à¤à¤²à¤¾à¤¨à¥‡ की सूà¤à¥€ Reset speed Rewind रिवाइंड Forward आगे Burst screenshot बरà¥à¤¸à¥à¤Ÿ सà¥à¤•à¥à¤°à¥€à¤¨à¤¶à¥‰à¤Ÿ Film screenshot 0.5s backward 0.5s forward Font फॉनà¥à¤Ÿ Font Size UrlDialog Cancel रदà¥à¤¦ करो Confirm पà¥à¤·à¥à¤Ÿà¤¿ Please enter the URL: dmr::ActionFactory Settings वà¥à¤¯à¤µà¤¸à¥à¤¥à¤¾ Fullscreen पूरà¥à¤£ पटल Always on Top Film info Open file à¥à¤¾à¤‡à¤² खोलें Open folder Light theme Open URL पता खोलें Open CD/DVD Mini Mode मिनी मोड Play Mode पà¥à¤²à¥‡ मोड Order Play Shuffle Play Single Play Single Loop सिंगल लूप List Loop लिसà¥à¤Ÿ लूप Frame ढांà¤à¤¾ Default मूल Clockwise Counterclockwise Next frame Previous frame Sound धà¥à¤µà¤¨à¤¿ Channel à¤à¥ˆà¤¨à¤² Stereo सà¥à¤Ÿà¥€à¤°à¤¿à¤¯à¥‹ Left channel Right channel Track गाना Subtitle Load Online Search Select à¤à¥à¤¨à¥‹ Hide Encodings Screenshot सà¥à¤•à¥à¤°à¥€à¤¨à¤¶à¥‰à¤Ÿ Film Screenshot Burst Shooting Playlist à¤à¤²à¤¾à¤¨à¥‡ की सूà¤à¥€ Film Info Clear playlist à¤à¤²à¤¾à¤¨à¥‡ की सूà¤à¥€ साफ करें Display in file manager फ़ाइल मैनेजर में पà¥à¤°à¤¦à¤°à¥à¤¶à¤¿à¤¤ करें dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save संà¤à¤¿à¤¤ करें dmr::MainWindow Load successfully Load failed No device found Parse Failed Open folder Open file à¥à¤¾à¤‡à¤² खोलें All videos (%1) Muted मूक Volume: %1% Subtitle %1: %2s delayed advanced Speed: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View देखें Movie Screenshot मूवी सà¥à¤•à¥à¤°à¥€à¤¨à¤¶à¥‰à¤Ÿ Saved to The screenshot is saved Failed to save the screenshot Invalid file: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Resolution: File Size: Duration: अवधि: File Path: dmr::MpvProxy [internal] dmr::PlayItemWidget File does not exist dmr::Settings %1/DMovie%2.jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play à¤à¤²à¤¾à¤¯à¥‡à¤‚ Previous पिछला Next आगे Subtitles उपशीरà¥à¤·à¤• Playlist à¤à¤²à¤¾à¤¨à¥‡ की सूà¤à¥€ Fullscreen पूरà¥à¤£ पटल Play/Pause बजाà¤à¤‚/रोकें Exit fullscreen पूरà¥à¤£ सà¥à¤•à¥à¤°à¥€à¤¨ से बाहर आयें Pause विराम deepin-movie-reborn-5.0.0/src/translations/deepin-movie_hr.ts000066400000000000000000000665541351125414100243310ustar00rootroot00000000000000 QObject Deepin Movie Deepin film Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Deepin Movie dobro je dizajnirani video player sa svim znaÄajkama i jednostavnim dizajnom bez okvira. Podržava lokalnu reprodukciju medija i streaming s viÅ¡e videoformata. Invalid folder Neispravna mapa Open folder Otvori mapu You don't have permission to operate this folder Auto add similar files to play Dodaj sliÄne datoteke za izvoÄ‘enje Clear playlist when exit OÄisti listu izvoÄ‘enja prilikom izlaska Show video preview on mouseover Open a new player for each file played Pause when minimized Pauziraj pri minimiziranju Remember playback position Zapamti poziciju reprodukcije Path Putanja Basic Osnovno Play Reprodukcija Screenshot Snimak zaslona Shortcuts PreÄaci File Datoteka Frame/Sound Okvir/zvuk Playback Reprodukcija Subtitle Podnapis Font Style Stil fonta Restore Defaults Obnovi zadano Open file Otvori datoteku Open next Otvori sljedeće Open previous Otvori prijaÅ¡nje Mini mode Mini prikaz Mute UtiÅ¡aj Next frame Previous frame Volume down Smanji glasnoću zvuka Volume up PojaÄaj glasnoću zvuka Speed up Ubrzaj Speed down Uspori Fullscreen Cijeli zaslon Pause/Play Pauza/Reprodukcija Playlist Popis izvoÄ‘enja Reset speed Rewind Premotaj natrag Forward Premotaj naprijed Burst screenshot Snimka zaslona u nizu Film screenshot 0.5s backward 0.5s unatrag 0.5s forward 0.5s naprijed Font Font Font Size VeliÄina fonta UrlDialog Cancel Otkaži Confirm Potvrdi Please enter the URL: Molim unesite URL: dmr::ActionFactory Settings Postavke Fullscreen Cijeli zaslon Always on Top Uvijek na vrhu Film info Informacije o filmu Open file Otvori datoteku Open folder Otvori mapu Light theme Open URL Otvori URL Open CD/DVD Otvori CD/DVD Mini Mode Mini naÄin Play Mode NaÄin reprodukcije Order Play Redoslijed izvoÄ‘enja Shuffle Play Single Play Single Loop List Loop Frame SliÄica Default UobiÄajeno Clockwise U smjeru kazaljke na satu Counterclockwise Suprotno od smjera kazaljke na satu Next frame Previous frame Sound Zvuk Channel Kanal Stereo Stereo Left channel Lijevi kanal Right channel Desni kanal Track Zapis Subtitle Podnapis Load UÄitaj Online Search Mrežna pretraga Select Odaberi Hide Sakrij Encodings Screenshot Snimak zaslona Film Screenshot Burst Shooting Playlist Popis izvoÄ‘enja Film Info Informacije o filmu Clear playlist ObriÅ¡i popis izvoÄ‘enja Display in file manager Prikaži u upravitelju datotekama dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save Spremi dmr::MainWindow Load successfully UspjeÅ¡no uÄitano Load failed Neuspjelo uÄitavanje No device found NIje pronaÄ‘en ureÄ‘aj Parse Failed Open folder Otvori mapu Open file Otvori datoteku All videos (%1) Muted UtiÅ¡ano Volume: %1% Glasnoća: %1% Subtitle %1: %2s Podnapis %1: %2s delayed odgoÄ‘eno advanced napredno Speed: %1x Brzina: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Pogled Movie Screenshot Snimka zaslona filma Saved to Spremljeno u The screenshot is saved Failed to save the screenshot Invalid file: %1 Neispravna datoteka: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Vrsta datoteke: Resolution: RazluÄivost: File Size: VeliÄina datoteke: Duration: Trajanje: File Path: Putanja datoteke: dmr::MpvProxy [internal] dmr::PlayItemWidget File does not exist Datoteka ne postoji dmr::Settings %1/DMovie%2.jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Reprodukcija Previous PrijaÅ¡nje Next Slijedeće Subtitles Podnapisi Playlist Popis izvoÄ‘enja Fullscreen Cijeli zaslon Play/Pause Reprodukcija/Pauza Exit fullscreen IzaÄ‘i iz cijelog zaslona Pause Pauziraj deepin-movie-reborn-5.0.0/src/translations/deepin-movie_hu.ts000066400000000000000000000700471351125414100243240ustar00rootroot00000000000000 QObject Deepin Movie Deepin Film Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. A Deepin Film egy jĂ³l megtervezett Ă©s funkciĂ³kban gazdag lejĂ¡tszĂ³, keret nĂ©lkĂ¼li megjelenĂ©ssel. SzĂ¡mos videĂ³ formĂ¡tum lejĂ¡tszĂ¡sĂ¡t tĂ¡mogatja helyi lejĂ¡tszĂ¡s Ă©s streaming formĂ¡jĂ¡ban is. Invalid folder ÉrvĂ©nytelen könyvtĂ¡r Open folder KönytĂ¡r megnyitĂ¡sa You don't have permission to operate this folder Nincs jogosultsĂ¡god a mappa hasznĂ¡latĂ¡hoz Auto add similar files to play Automatikus hozzĂ¡adĂ¡s a lejĂ¡tszĂ¡si listĂ¡hoz Clear playlist when exit KilĂ©pĂ©skor törölje a lejĂ¡tszĂ¡si listĂ¡t Show video preview on mouseover VideĂ³ elÅ‘nĂ©zet megjelenĂ­tĂ©se az egĂ©rmutatĂ³ alatt Open a new player for each file played Minden lejĂ¡tszĂ¡s Ăºj ablakban Pause when minimized MinimalizĂ¡lĂ¡skor szĂ¼netel a lejĂ¡tszĂ¡s Remember playback position LejĂ¡tszĂ¡si pozĂ­ciĂ³ megjegyzĂ©se Path ElĂ©rĂ©si Ăºtvonal Basic Alap Play LejĂ¡tszĂ¡s Screenshot KĂ©pernyÅ‘kĂ©p Shortcuts Gyorsbillentyűk File FĂ¡jl Frame/Sound KĂ©pkocka/Hang Playback VisszajĂ¡tszĂ¡s Subtitle Felirat Font Style BetűtĂ­pus Restore Defaults Alaphelyzetbe Ă¡llĂ­tĂ¡s Open file FĂ¡jl megnyitĂ¡s Open next KövetkezÅ‘ megnyitĂ¡sa Open previous ElÅ‘zÅ‘ megnyitĂ¡sa Mini mode Mini mĂ³d Mute NĂ©mĂ­tĂ¡s Next frame KövetkezÅ‘ kĂ©pkocka Previous frame ElÅ‘zÅ‘ kĂ©pkocka Volume down HangerÅ‘ csökkentĂ©se Volume up HangerÅ‘ növelĂ©se Speed up FelgyorsĂ­tĂ¡s Speed down SebessĂ©g csökkentĂ©se Fullscreen Teljes kĂ©pernyÅ‘ Pause/Play SzĂ¼net/LejĂ¡tszĂ¡s Playlist LejĂ¡tszĂ¡si lista Reset speed LejĂ¡tszĂ¡si sebessĂ©g alaphelyzetbe Ă¡llĂ­tĂ¡s Rewind HĂ¡tra Forward ElÅ‘re Burst screenshot Sorozat kĂ©pernyÅ‘tartalom Ă¡llĂ³kĂ©p Film screenshot Film pillanatkĂ©p kĂ©szĂ­tĂ©se 0.5s backward 0,5 mĂ¡sodperccel visza 0.5s forward 0,5 mĂ¡sodperccel elÅ‘re Font BetűtĂ­pus Font Size Betű mĂ©ret UrlDialog Cancel MĂ©gse Confirm MegerÅ‘sĂ­tĂ©s Please enter the URL: KĂ©rem Ă­rja be a web-cĂ­met: dmr::ActionFactory Settings BeĂ¡llĂ­tĂ¡sok Fullscreen Teljes kĂ©pernyÅ‘ Always on Top Mindig lĂ¡tsszon Film info Film informĂ¡ciĂ³ Open file FĂ¡jl megnyitĂ¡s Open folder KönytĂ¡r megnyitĂ¡sa Light theme Open URL URL megnyitĂ¡s Open CD/DVD CD/DVD lejĂ¡tszĂ¡sa Mini Mode Mini mĂ³d Play Mode LejĂ¡tszĂ¡si mĂ³d Order Play LejĂ¡tszĂ¡s elrendezĂ©se Shuffle Play LejĂ¡tszĂ¡s rĂ©szletekben Single Play LejĂ¡tszĂ¡s egyesĂ©vel Single Loop Ăjra jĂ¡tszĂ¡s List Loop ĂjrajĂ¡tszĂ¡s listĂ¡rĂ³l Frame KĂ©pkocka Default AlapĂ©rtelmezett Clockwise Ă“ra jĂ¡rĂ¡sĂ¡val megegyezÅ‘en Counterclockwise Ă“ra jĂ¡rĂ¡sĂ¡val ellentĂ©tesen Next frame KövetkezÅ‘ kĂ©pkocka Previous frame ElÅ‘zÅ‘ kĂ©pkocka Sound Hang Channel Csatorna Stereo SztereĂ³ Left channel Bal csatorna Right channel Jobb csatorna Track SzĂ¡m Subtitle Felirat Load BetöltĂ©s Online Search KeresĂ©s online Select KivĂ¡lasztĂ¡s Hide Rejtett Encodings KĂ³dolĂ¡s Screenshot KĂ©pernyÅ‘kĂ©p Film Screenshot KĂ©pernyÅ‘kĂ©p a filmrÅ‘l Burst Shooting SorozatfelvĂ©tel Playlist LejĂ¡tszĂ¡si lista Film Info InformĂ¡ciĂ³ a filmrÅ‘l Clear playlist LejĂ¡tszĂ¡si lista Ă¼rĂ­tĂ©se Display in file manager MegjelenĂ­tĂ©s fĂ¡jlkezelÅ‘ben dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save Ment dmr::MainWindow Load successfully Sikeres betöltĂ©s Load failed Sikertelen betöltĂ©s No device found Nem talĂ¡lhatĂ³ az eszköz Parse Failed Sikertelen elemzĂ©s Open folder KönytĂ¡r megnyitĂ¡sa Open file FĂ¡jl megnyitĂ¡s All videos (%1) Ă–sszes videĂ³ (%1) Muted NĂ©mĂ­tva Volume: %1% HangerÅ‘: %1% Subtitle %1: %2s Felirat %1: %2s delayed idÅ‘zĂ­tve advanced KibÅ‘vĂ­tett Speed: %1x SebessĂ©g: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View MegtekintĂ©s Movie Screenshot Film pillanatkĂ©p Saved to Elmentve The screenshot is saved A kĂ©pernyÅ‘kĂ©p mentĂ©se sikeres Failed to save the screenshot Invalid file: %1 ÉrvĂ©nytelen fĂ¡jl: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: FĂ¡jl tĂ­pus Resolution: FelbontĂ¡s: File Size: FĂ¡jl mĂ©ret: Duration: IdÅ‘tartam: File Path: FĂ¡jl Ăºtvonala dmr::MpvProxy [internal] [belsÅ‘] dmr::PlayItemWidget File does not exist A fĂ¡jl nem lĂ©tezik dmr::Settings %1/DMovie%2.jpg %1/DVideo%2.jpg %1/DMovie%2(%3).jpg %1/DVideo%2(%3).jpg dmr::ToolboxProxy Play LejĂ¡tszĂ¡s Previous ElÅ‘zÅ‘ Next KövetkezÅ‘ Subtitles Feliratok Playlist LejĂ¡tszĂ¡si lista Fullscreen Teljes kĂ©pernyÅ‘ Play/Pause LejĂ¡tszĂ¡s/SzĂ¼net Exit fullscreen KilĂ©pĂ©s a teljes kĂ©pernyÅ‘böl Pause SzĂ¼net deepin-movie-reborn-5.0.0/src/translations/deepin-movie_hy.ts000066400000000000000000000652321351125414100243300ustar00rootroot00000000000000 QObject Deepin Movie Deepin Ơ–Ơ«Ơ¬Ơ´Ơ¥Ö€ Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Invalid folder Open folder You don't have permission to operate this folder Auto add similar files to play Clear playlist when exit Show video preview on mouseover Open a new player for each file played Pause when minimized Remember playback position Path Basic Play ƠƠ¯Ơ½Ơ¥Ơ¬ Screenshot ƠƠ¡ƠµÖ€Ơ¯Ơ¥Ơ¶Ơ¡ƠºƠ¡Ơ¿Ơ¯Ơ¥Ö€ Shortcuts File Ơ†Ơ«Ơ·Ö„ Frame/Sound Playback Ơ†Ơ¾Ơ¡Ơ£Ơ¡Ö€Ơ¯Ơ¥Ơ¬ Subtitle Font Style Restore Defaults Open file Ô²Ơ¡ÖƠ¥Ơ¬ Ơ¶Ơ«Ơ·Ö„Ơ¨ Open next Open previous Mini mode Mute Ô±Ơ¶Ơ»Ơ¡Ơ¿Ơ¥Ơ¬ Ơ±Ơ¡ƠµƠ¶Ơ¨ Next frame Previous frame Volume down Volume up Speed up Speed down Fullscreen Pause/Play Ô¸Ơ¶Ơ¤Ơ°Ơ¡Ơ¿Ơ¥Ơ¬/Ơ‡Ơ¡Ö€Ơ¸Ö‚Ơ¶Ơ¡Ơ¯Ơ¥Ơ¬ Playlist Ơ‘Ơ¡Ơ¶Ơ¯ Reset speed Rewind ÔµƠ¿ Forward Ô±Ơ¼Ơ¡Ơ» Burst screenshot Film screenshot 0.5s backward 0.5s forward Font ƠƠ¡Ơ¼Ơ¡Ơ¿Ơ¥Ơ½Ơ¡Ơ¯ Font Size UrlDialog Cancel Ơ‰Ơ¥Ơ²Ơ¡Ö€Ơ¯Ơ¥Ơ¬ Confirm Please enter the URL: dmr::ActionFactory Settings Ô¿Ơ¡Ö€Ơ£Ơ¡Ơ¾Ơ¸Ö€Ơ¸Ö‚Ơ´Ơ¶Ơ¥Ö€ Fullscreen Always on Top Film info Open file Ô²Ơ¡ÖƠ¥Ơ¬ Ơ¶Ơ«Ơ·Ö„Ơ¨ Open folder Light theme Open URL Ô²Ơ¡ÖƠ¥Ơ¬ Ơ°Ơ¡Ơ½ÖƠ¥Ơ¶ Open CD/DVD Mini Mode Ơ“Ơ¸Ö„Ö€Ơ¡ÖƠ¾Ơ¡Ơ® Play Mode Order Play Shuffle Play Single Play Single Loop List Loop Frame Default ƠƠ¸Ơ¾Ơ¸Ö€Ơ¡Ơ¯Ơ¡Ơ¶ Clockwise Counterclockwise Next frame Previous frame Sound Channel Stereo Left channel Right channel Track ƠƠ¡ƠµƠ¶Ơ¡Ơ¶Ơ·Ơ¸Ö Subtitle Load Online Search Select Hide Encodings Screenshot ƠƠ¡ƠµÖ€Ơ¯Ơ¥Ơ¶Ơ¡ƠºƠ¡Ơ¿Ơ¯Ơ¥Ö€ Film Screenshot Burst Shooting Playlist Ơ‘Ơ¡Ơ¶Ơ¯ Film Info Clear playlist Display in file manager dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save ƠƠ¡Ơ°Ơ¥Ơ¬ dmr::MainWindow Load successfully Load failed No device found Parse Failed Open folder Open file Ô²Ơ¡ÖƠ¥Ơ¬ Ơ¶Ơ«Ơ·Ö„Ơ¨ All videos (%1) Muted Volume: %1% Subtitle %1: %2s delayed advanced Speed: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Movie Screenshot Saved to The screenshot is saved Failed to save the screenshot Invalid file: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Resolution: File Size: Duration: File Path: dmr::MpvProxy [internal] dmr::PlayItemWidget File does not exist dmr::Settings %1/DMovie%2.jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play ƠƠ¯Ơ½Ơ¥Ơ¬ Previous Ơ†Ơ¡Ơ­Ơ¸Ö€Ơ¤ Next Ơ€Ơ¡Ơ»Ơ¸Ö€Ơ¤ Subtitles ƠƠ¡Ơ¯Ơ¡Ơ£Ö€Ơ¥Ö€ Playlist Ơ‘Ơ¡Ơ¶Ơ¯ Fullscreen Play/Pause Ơ‡Ơ¡Ö€Ơ¸Ö‚Ơ¶Ơ¡Ơ¯Ơ¥Ơ¬/Ô¸Ơ¶Ơ¤Ơ°Ơ¡Ơ¿Ơ¥Ơ¬ Exit fullscreen Pause Ô¸Ơ¶Ơ¤Ơ°Ơ¡Ơ¿Ơ¥Ơ¬ deepin-movie-reborn-5.0.0/src/translations/deepin-movie_id.ts000066400000000000000000000665501351125414100243100ustar00rootroot00000000000000 QObject Deepin Movie Pemutar FIlm Deepin Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Deepin Movie adalah pemutar video yang luar biasa, kaya akan fitur, dengan desain tanpa bingkai yang sederhana. Deepin Movie mendukung pemutaran media lokal dan streaming dengan bermacam-macam format video. Invalid folder Folder tidak valid Open folder Buka Folder You don't have permission to operate this folder Anda tidak mempunyai ijin untuk beroperasi di folder ini Auto add similar files to play Otomatis tambah berkas yang sama untuk dimainkan Clear playlist when exit Bersih playlist ketika keluar Show video preview on mouseover Tampilkan pratinjau video di atas tetikus Open a new player for each file played Buka pemutar baru untuk setiap berkas yang dimainkan Pause when minimized Jeda ketika diminimalkan Remember playback position Mengingat posisi playback Path Jejak Basic Dasar Play Putar Screenshot Tangkapan Layar Shortcuts Pintasan File File Frame/Sound Bingkai/Suara Playback Pemutaran Subtitle Subtitle Font Style Jenis Huruf Restore Defaults Pulihkan baku Open file Buka berkas Open next Buka selanjutnya Open previous Buka sebelumnya Mini mode Mode Mini Mute Senyap Next frame Frame sesudah Previous frame Frame sebelum Volume down Turunkan Volume Volume up Naikkan Volume Speed up Percepat Speed down Turun cepat Fullscreen Layar Penuh Pause/Play Jeda/Putar Playlist Daftar Putar Reset speed Atur ulang kecepatan Rewind Mundur Forward Maju Burst screenshot Rentetan cuplikan layar Film screenshot Tangkapan layar Film 0.5s backward Putar awal 0.5s 0.5s forward Putar maju 0.5s Font Fon Font Size Ukuran Huruf UrlDialog Cancel Batal Confirm Konfirmasi Please enter the URL: Mohon masukan URL: dmr::ActionFactory Settings Pengaturan Fullscreen Layar Penuh Always on Top Selalu di atas Film info Info Film Open file Buka berkas Open folder Buka Folder Light theme Open URL Buka URL Open CD/DVD Buka CD/DVD Mini Mode Mode Mini Play Mode Mode main Order Play Shuffle Play Single Play Single Loop Putar sekali List Loop Daftar putar Frame Bingkai Default Bawaan Clockwise Searah jarum jam Counterclockwise Searah jarum jam Next frame Frame sesudah Previous frame Frame sebelum Sound Suara Channel Kanal Stereo Stereo Left channel Right channel Track Lagu Subtitle Subtitle Load Online Search Cari Online Select Pilih Hide Sembunyi Encodings Screenshot Tangkapan Layar Film Screenshot Tangkapan layar Film Burst Shooting Playlist Daftar Putar Film Info Info Film Clear playlist Bersihkan daftar putar Display in file manager Tampilkan dalam manajer berkas dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save Simpan dmr::MainWindow Load successfully Load failed No device found Alat tidak di temukan Parse Failed Open folder Buka Folder Open file Buka berkas All videos (%1) Semua video (%1) Muted Senyapkan Volume: %1% Subtitle %1: %2s delayed Penundaan advanced Terkini Speed: %1x Cepat: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Lihat Movie Screenshot Cuplikan Layar Film Saved to Disimpan ke The screenshot is saved Tangkapan layar di simpan Failed to save the screenshot Invalid file: %1 Berkas tidak valid: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Jenis Berkas: Resolution: Resolusi: File Size: Ukuran Berkas: Duration: Durasi: File Path: dmr::MpvProxy [internal] dmr::PlayItemWidget File does not exist Berkas tidak ada dmr::Settings %1/DMovie%2.jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Putar Previous Sebelumnya Next Selanjutnya Subtitles Terjemahan Playlist Daftar Putar Fullscreen Layar Penuh Play/Pause Mainkan/Jeda Exit fullscreen Keluar layar penuh Pause Jeda deepin-movie-reborn-5.0.0/src/translations/deepin-movie_it.ts000066400000000000000000000674751351125414100243370ustar00rootroot00000000000000 QObject Deepin Movie Deepin Movie Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Deepin Movie è un meraviglioso e funzionale player video dal design borderless. Offre il supporto per riproduzioni video locali e streaming, inoltre riconosce diversi formati video. Localizzazione italiana a cura di Carofano Massimo Antonio. Invalid folder Cartella non valida Open folder Apri cartella You don't have permission to operate this folder Non hai i permessi per utilizzare questa cartella Auto add similar files to play Aggiungi file simili da riprodurre Clear playlist when exit Cancella la playlist all'uscita Show video preview on mouseover Mostra la preview video al passaggio del mouse Open a new player for each file played Apri una nuova finestra per ciascun file riprodotto Pause when minimized Metti in pausa se minimizzato Remember playback position Ricorda l'avanzamento della riproduzione Path Percorso Basic Base Play Play Screenshot Screenshot Shortcuts Scorciatoie File File Frame/Sound Frame/Suono Playback Playback Subtitle Sottotitoli Font Style Stile dei font Restore Defaults Ripristina i valori di default Open file Apri file Open next Apri il prossimo Open previous Apri il precedente Mini mode ModalitĂ  mini Mute Muto Next frame Prossimo frame Previous frame Frame precedente Volume down Diminuisci Volume Volume up Aumenta Volume Speed up Aumenta velocitĂ  Speed down VelocitĂ  inferiore Fullscreen Schermo intero Pause/Play Pausa/Play Playlist Playlist Reset speed Resetta velocitĂ  Rewind Indietro Forward Avanti Burst screenshot Burst screenshot Film screenshot Screenshot del video 0.5s backward Indietro di 0.5s 0.5s forward Avanti di 0.5s Font Font Font Size Dimensione font UrlDialog Cancel Annulla Confirm Conferma Please enter the URL: Inserisci l'indirizzo URL: dmr::ActionFactory Settings Impostazioni Fullscreen Schermo intero Always on Top Sempre in primo piano Film info Info video Open file Apri file Open folder Apri cartella Light theme Tema chiaro Open URL Apri un URL Open CD/DVD Apri CD/DVD Mini Mode ModalitĂ  minimizzata Play Mode ModalitĂ  di riproduzione Order Play Ordine di riproduzione Shuffle Play Riproduzione casuale Single Play Riproduzione singola Single Loop Ripetizione singola List Loop Ripetizione di Gruppo Frame Frame Default Default Clockwise Orario Counterclockwise Antiorario Next frame Prossimo frame Previous frame Frame precedente Sound Audio Channel Canale Stereo Stereo Left channel Canale sinistro Right channel Canale destro Track Traccia Subtitle Sottototoli Load Carica Online Search Ricerca online Select Seleziona Hide Nascondi Encodings Codifica Screenshot Screenshot Film Screenshot Screenshot del video Burst Shooting Screen dilazionati Playlist Playlist Film Info Info del video Clear playlist Pulisci playlist Display in file manager Visualizza nel file manager dmr::BurstScreenshotsDialog Duration: %1 Durata: %1 Resolution: %1 Risoluzione %1 Size: %1 Dimensione: %1 Save Salva dmr::MainWindow Load successfully Caricamento riuscito Load failed Caricamento fallito No device found Nessun dispositivo trovato Parse Failed Analisi fallita Open folder Apri cartella Open file Apri file All videos (%1) Tutti i video (%1) Muted Muto Volume: %1% Volume: %1% Subtitle %1: %2s Sottotitoli: %1: %2s delayed ritardato advanced posticipare Speed: %1x VelocitĂ : %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) Sottotitoli (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Visualizza Movie Screenshot Screenshot film Saved to Salva in The screenshot is saved Lo screenshot è stato salvato Failed to save the screenshot Salvataggio screenshot fallito Invalid file: %1 File non valido: %1 dmr::MovieInfo %1G %1G %1M %1M %1K %1K %1 %1 dmr::MovieInfoDialog File Type: Tipo file: Resolution: Risoluzione: File Size: Dimensioni file: Duration: Durata: File Path: Percorso file: dmr::MpvProxy [internal] [interno] dmr::PlayItemWidget File does not exist Il file non esiste dmr::Settings %1/DMovie%2.jpg %1/DMovie%2.jpg %1/DMovie%2(%3).jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Play Previous Precedente Next Avanti Subtitles Sottotitoli Playlist Playlist Fullscreen Schermo intero Play/Pause Play/Pausa Exit fullscreen Esci dalla modalitĂ  fullscreen Pause Pausa deepin-movie-reborn-5.0.0/src/translations/deepin-movie_ja.ts000066400000000000000000000662171351125414100243060ustar00rootroot00000000000000 QObject Deepin Movie Deepinăƒ“ăƒ‡ă‚ªăƒ—ăƒ¬ă‚¤ăƒ¤ăƒ¼ Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Deepin Movie ă¯ă‚·ăƒ³ăƒ—ăƒ«ă§ăƒœăƒ¼ăƒ€ăƒ¬ă‚¹ăªăƒ‡ă‚¶ă‚¤ăƒ³ă‚’æŒă¤ă€é©åˆ‡ă«ç­–å®ă•ă‚ŒăŸăƒ•ăƒ«è£…å‚™ă®ăƒ“ăƒ‡ă‚ªăƒ—ăƒ¬ăƒ¼ăƒ¤ăƒ¼ă§ă™ă€‚ăă‚Œă¯è¤‡æ•°ă®ăƒ“ăƒ‡ă‚ªå½¢å¼ă§ăƒ­ăƒ¼ă‚«ăƒ«ă‚„ă‚¹ăƒˆăƒªăƒ¼ăƒŸăƒ³ă‚°ă®ăƒ¡ăƒ‡ă‚£ă‚¢å†ç”Ÿă‚’サăƒăƒ¼ăƒˆă—ă¾ă™ă€‚ Invalid folder Open folder You don't have permission to operate this folder Auto add similar files to play Clear playlist when exit Show video preview on mouseover Open a new player for each file played Pause when minimized 最å°åŒ–時ă«ä¸€æ™‚åœæ­¢ Remember playback position Path ăƒ‘ă‚¹ Basic ăƒ™ăƒ¼ă‚·ăƒƒă‚¯ Play å†ç”Ÿ Screenshot ă‚¹ă‚¯ăƒªăƒ¼ăƒ³ă‚·ăƒ§ăƒƒăƒˆ Shortcuts ă‚·ăƒ§ăƒ¼ăƒˆă‚«ăƒƒăƒˆ File ăƒ•ă‚¡ă‚¤ăƒ« Frame/Sound ăƒ•ăƒ¬ăƒ¼ăƒ /音 Playback ăƒ—ăƒ¬ă‚¤ăƒăƒƒă‚¯ Subtitle Font Style Restore Defaults Open file ăƒ•ă‚¡ă‚¤ăƒ«ă‚’é–‹ă Open next æ¬¡ă‚’é–‹ă Open previous å‰ă‚’é–‹ă Mini mode ăƒŸăƒ‹ăƒ¢ăƒ¼ăƒ‰ Mute 消音 Next frame Previous frame Volume down 音é‡ă‚’下ă’ă‚‹ Volume up 音é‡ă‚’ä¸ă’ă‚‹ Speed up Speed down Fullscreen ăƒ•ăƒ«ă‚¹ă‚¯ăƒªăƒ¼ăƒ³ă«ă™ă‚‹ Pause/Play ä¸€æ™‚åœæ­¢ăƒ»å†ç”Ÿ Playlist ăƒ—ăƒ¬ă‚¤ăƒªă‚¹ăƒˆ Reset speed Rewind å·»ăæˆ»ă— Forward è»¢é€ Burst screenshot ă‚¹ă‚¯ăƒªăƒ¼ăƒ³ă‚·ăƒ§ăƒƒăƒˆă‚’é€£ç¶æ’®å½± Film screenshot 0.5s backward 0.5s forward Font ăƒ•ă‚©ăƒ³ăƒˆ Font Size UrlDialog Cancel ă‚­ăƒ£ăƒ³ă‚»ăƒ« Confirm ç¢ºèª Please enter the URL: dmr::ActionFactory Settings è¨­å® Fullscreen ăƒ•ăƒ«ă‚¹ă‚¯ăƒªăƒ¼ăƒ³ă«ă™ă‚‹ Always on Top Film info Open file ăƒ•ă‚¡ă‚¤ăƒ«ă‚’é–‹ă Open folder Light theme Open URL URL ă‚’é–‹ă Open CD/DVD Mini Mode 最å°åŒ–ăƒ¢ăƒ¼ăƒ‰ Play Mode Order Play Shuffle Play Single Play Single Loop List Loop Frame ăƒ•ăƒ¬ăƒ¼ăƒ  Default ăƒ‡ăƒ•ă‚©ăƒ«ăƒˆ Clockwise Counterclockwise Next frame Previous frame Sound ă‚µă‚¦ăƒ³ăƒ‰ Channel ăƒăƒ£ăƒ³ăƒăƒ« Stereo ă‚¹ăƒ†ăƒ¬ă‚ª Left channel Right channel Track 曲 Subtitle Load Online Search Select 鏿 Hide Encodings Screenshot ă‚¹ă‚¯ăƒªăƒ¼ăƒ³ă‚·ăƒ§ăƒƒăƒˆ Film Screenshot Burst Shooting Playlist ăƒ—ăƒ¬ă‚¤ăƒªă‚¹ăƒˆ Film Info Clear playlist ăƒ—ăƒ¬ă‚¤ăƒªă‚¹ăƒˆă®ă‚¯ăƒªă‚¢ Display in file manager dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save ä¿å­˜ dmr::MainWindow Load successfully Load failed No device found Parse Failed Open folder Open file ăƒ•ă‚¡ă‚¤ăƒ«ă‚’é–‹ă All videos (%1) Muted 消音 Volume: %1% Subtitle %1: %2s delayed advanced Speed: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View 表示 Movie Screenshot 映画ă®ă‚¹ă‚¯ăƒªăƒ¼ăƒ³ă‚·ăƒ§ăƒƒăƒˆ Saved to The screenshot is saved Failed to save the screenshot Invalid file: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Resolution: File Size: Duration: File Path: dmr::MpvProxy [internal] dmr::PlayItemWidget File does not exist dmr::Settings %1/DMovie%2.jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play å†ç”Ÿ Previous å‰ă¸ Next æ¬¡ă¸ Subtitles 字幕 Playlist ăƒ—ăƒ¬ă‚¤ăƒªă‚¹ăƒˆ Fullscreen ăƒ•ăƒ«ă‚¹ă‚¯ăƒªăƒ¼ăƒ³ă«ă™ă‚‹ Play/Pause å†ç”Ÿăƒ»ä¸€æ™‚åœæ­¢ Exit fullscreen ăƒ•ăƒ«ă‚¹ă‚¯ăƒªăƒ¼ăƒ³ă‚’è§£é™¤ Pause ä¸€æ™‚åœæ­¢ deepin-movie-reborn-5.0.0/src/translations/deepin-movie_ko.ts000066400000000000000000000675451351125414100243320ustar00rootroot00000000000000 QObject Deepin Movie Deepin ë™́˜́ƒ Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Deepin ë™́˜́ƒ́€ 단́ˆœí•œ í…Œë‘리 ́—†ë” ë””́́¸́œ¼ë¡œ ë””́́¸ë„ ́˜ ë˜́–´ ́ˆê³ , 모든 기ë¥́„ ê°–́¶˜ 비디́˜¤ 플레́´́–´́…니다. ́—¬ëŸ¬ 비디́˜¤ 형́‹́œ¼ë¡œ 로́»¬ ë° ́¤í¸ë¦¬ë° 미디́–´ ́¬́ƒ́„ ́§€́›í•©ë‹ˆë‹¤. Invalid folder ́˜ëª»ëœ í´ë” Open folder í´ë” ́—´ê¸° You don't have permission to operate this folder ́´ í´ë”를 ́¡°́‘í•  ́ˆ˜ ́ˆë” 권한́´ ́—†́µë‹ˆë‹¤ Auto add similar files to play ́¬́ƒí•  ́œ ́‚¬í•œ 파́¼ ́ë™ ́¶”ê°€ Clear playlist when exit ́¢…료́‹œ ́¬́ƒ ëª©ë¡ ́§€́°ê¸° Show video preview on mouseover 마́°́¤ ́˜¤ë²„́‹œ 비디́˜¤ 미리보기 표́‹œ Open a new player for each file played ́¬́ƒë˜ë” ê° íŒŒ́¼́— 대해 ́ƒˆ 플레́´́–´ ́—´ê¸° Pause when minimized ́µœ́†Œí™”ëœ ê²½́° ́¼́‹œ ́¤‘́§€ Remember playback position ́¬́ƒ ́œ„́¹˜ 기́–µ Path 경로 Basic 기본 Play ́¬́ƒ Screenshot ́¤í¬ë¦°́ƒ· Shortcuts 단́¶•키 File 파́¼ Frame/Sound 프레́„/́‚¬́´ë“œ Playback ́¬́ƒ Subtitle ́막 Font Style 글꼴 ́¤íƒ€́¼ Restore Defaults 기본값 ë³µ́› Open file 파́¼ ́—´ê¸° Open next 다́Œ ́—´ê¸° Open previous ́´́ „ ́—´ê¸° Mini mode 미니 모드 Mute ́Œ́†Œê±° Next frame 다́Œ 프레́„ Previous frame ́´́ „ 프레́„ Volume down 볼륨 ë‚®́¶”기 Volume up 볼륨 키́°ê¸° Speed up ́†ë„ ́˜¬ë¦¬ê¸° Speed down ́†ë„ ë‚®́¶”기 Fullscreen ́ „́²´ 화면 Pause/Play 멈́¶¤/́¬́ƒ Playlist ́¬́ƒëª©ë¡ Reset speed ́†ë„ ́¬́„¤́ • Rewind ë˜ê°ê¸° Forward ́•́œ¼ë¡œ Burst screenshot 버́¤í¸ ́¤í¬ë¦°́ƒ· Film screenshot 필름 ́¤í¬ë¦°́ƒ· 0.5s backward 0.5́´ˆ 뒤로 0.5s forward 0.5́´ˆ ́•́œ¼ë¡œ Font 글꼴 Font Size 글꼴 í¬ê¸°: UrlDialog Cancel ́·΅†Œ Confirm 확́¸ Please enter the URL: URĹ„ ́…력해 ́£¼́„¸́”. dmr::ActionFactory Settings ́„¤́ • Fullscreen ́ „́²´í™”ë©´ Always on Top í•­́ƒ ́œ„́— Film info 필름 ́ •ë³´ Open file 파́¼ ́—´ê¸° Open folder í´ë” ́—´ê¸° Light theme ë°́€ 테마 Open URL ́˜¤í”ˆ URL Open CD/DVD CD/DVD ́—´ê¸° Mini Mode 미니 모드 Play Mode ́¬́ƒ 모드 Order Play ́¬́ƒ 명령 Shuffle Play ́…”플 ́¬́ƒ Single Play 한곡 ́¬́ƒ Single Loop 한곡 반복 List Loop ëª©ë¡ ë°˜ë³µ Frame 프레́„ Default 기본값 Clockwise ́‹œê³„ ë°©í–¥́œ¼ë¡œ Counterclockwise ë°˜́‹œê³„ ë°©í–¥́œ¼ë¡œ Next frame 다́Œ 프레́„ Previous frame ́´́ „ 프레́„ Sound ́‚¬́´ë“œ Channel ́±„ë„ Stereo ́¤í…Œë ˆ́˜¤ Left channel ́™¼́ª½ ́±„ë„ Right channel ́˜¤ë¥¸́ª½ ́±„ë„ Track í¸ë™ Subtitle ́막 Load 불러́˜¤ê¸° Online Search ́˜¨ë¼́¸ ê²€́ƒ‰ Select ́„ íƒ Hide ́ˆ¨ê¸°ê¸° Encodings ́¸́½”딩 Screenshot ́¤í¬ë¦°́ƒ· Film Screenshot 필름 ́¤í¬ë¦°́ƒ· Burst Shooting 버́¤í¸ ́ˆíŒ… Playlist ́¬́ƒëª©ë¡ Film Info 필름 ́ •ë³´ Clear playlist ́¬́ƒëª©ë¡ ́§€́°ê¸° Display in file manager 파́¼ 관리́́— 표́‹œ dmr::BurstScreenshotsDialog Duration: %1 ́¬́ƒ ́‹œê°„: %1 Resolution: %1 í•´́ƒë„: %1 Size: %1 í¬ê¸°: %1 Save ́ €́¥ dmr::MainWindow Load successfully 불러́˜¤ê¸° ́„±ê³µ Load failed 불러́˜¤ê¸° ́‹¤íŒ¨ No device found ́¥́¹˜ë¥¼ ́°¾́„ ́ˆ˜ ́—†́Œ Parse Failed 구문분́„ ́‹¤íŒ¨ Open folder í´ë” ́—´ê¸° Open file 파́¼ ́—´ê¸° All videos (%1) 모든 ë™́˜́ƒ (%1) Muted ́Œ́†Œê±°ë¨ Volume: %1% 볼륨: %1% Subtitle %1: %2s ́막 %1: %2́´ˆ delayed ́§€́—°ë¨ advanced 고급 Speed: %1x ́†ë„: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) ́막 (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View ă…‚ă…—ê¸° Movie Screenshot ë™́˜́ƒ ́¤í¬ë¦°́ƒ· Saved to ́ €́¥ë¨: The screenshot is saved ́¤í¬ë¦°́ƒ·́´ ́ €́¥ ë˜́—ˆ́µë‹ˆë‹¤ Failed to save the screenshot ́¤í¬ë¦°́ƒ·́„ ́ €́¥í•˜́§€ 못했́µë‹ˆë‹¤ Invalid file: %1 ́˜ëª»ëœ 파́¼: %1 dmr::MovieInfo %1G %1G %1M %1M %1K %1K %1 %1 dmr::MovieInfoDialog File Type: 파́¼ ́œ í˜•: Resolution: í•´́ƒë„: File Size: 파́¼ í¬ê¸°: Duration: ́¬́ƒ ́‹œê°„: File Path: 파́¼ 경로: dmr::MpvProxy [internal] [ë‚´ë¶€] dmr::PlayItemWidget File does not exist 파́¼́´ ́—†́µë‹ˆë‹¤ dmr::Settings %1/DMovie%2.jpg %1/DMovie%2.jpg %1/DMovie%2(%3).jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play ́¬́ƒ Previous ́´́ „ Next 다́Œ Subtitles ́막 Playlist ́¬́ƒ ëª©ë¡ Fullscreen ́ „́²´í™”ë©´ Play/Pause ́¬́ƒ / ́¼́‹œ́ •́§€ Exit fullscreen ́ „́²´í™”ë©´ ́¢…료 Pause ́¼́‹œ́ •́§€ deepin-movie-reborn-5.0.0/src/translations/deepin-movie_ku_IQ.ts000066400000000000000000000674251351125414100247260ustar00rootroot00000000000000 QObject Deepin Movie Deepin FĂ®lm Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Sepana Deepin FĂ®lm, lĂªderek tĂªrtaybetĂ® ya dĂ®menĂª ye Ă» bi sĂªwira xwe ya sade ya bĂªĂ§arçoveyĂª baÅŸ hatiye sĂªwirandin. PiÅŸtevaniya gelek cureyĂªn medyayĂª yĂªn xwecihĂ® Ă» weÅŸaniyĂª dike. Invalid folder Peldanka nederbasdar Open folder You don't have permission to operate this folder DestĂ»ra te tune ye ku di peldankĂª de guherĂ®nĂª bike Auto add similar files to play Ji bo lĂªdanĂª pelĂªn wekhev bira jixweber bĂªne tevlĂ®kirin Clear playlist when exit Dema derketinĂª lĂ®steya lĂªdanĂª jĂª bibe Show video preview on mouseover Dema miÅŸk li ser wĂª be, bira pĂªÅŸdĂ®tina vĂ®dyo bĂª lĂ®stin Open a new player for each file played Bira her pel di lĂªderekĂ® din bĂª lĂ®stin Pause when minimized Di biçûkkirinĂª de bisekinĂ®ne Remember playback position CihĂª lĂªdanĂª bi bĂ®r bĂ®ne Path RĂª Basic BingehĂ®n Play LĂª Bide Screenshot DĂ®mena dĂ®menderĂª Shortcuts KurtebirĂ® File Pel Frame/Sound Sehne/Deng Playback LĂ®stin Subtitle BinnivĂ®s Font Style ÅĂªwaza TĂ®pa NivĂ®sĂª Restore Defaults MĂ®hengĂªn DestpĂªkĂª DĂ®sa BĂ®ne Open file PelĂª veke Open next Ya pĂªÅŸve veke Open previous Ya paÅŸve veke Mini mode Moda biçûk Mute BĂªdeng Next frame Sehneya pĂªÅŸve Previous frame Sehneya paÅŸve Volume down Deng dĂ®ne Volume up Deng rake Speed up LezĂª zĂªde bike Speed down LezĂª kĂªm bike Fullscreen DĂ®mentĂªr Pause/Play BisekinĂ®ne/LĂª Bide Playlist LĂ®steya LĂªxistinĂª Reset speed LezĂª sifir bike Rewind PaÅŸve bibe Forward PĂªÅŸve bibe Burst screenshot RĂªzedĂ®mena dĂ®menderĂª Film screenshot DĂ®mena dĂ®menderĂª ya fĂ®lmĂª 0.5s backward 0.5s paÅŸve 0.5s forward 0.5s pĂªÅŸve Font TĂ®pa NivĂ®sĂª Font Size Mezinahiya TĂ®pa NivĂ®sĂª UrlDialog Cancel Betal Bike Confirm BipejirĂ®ne Please enter the URL: Ji kerema xwe pĂª li URLym bike: dmr::ActionFactory Settings MĂ®heng Fullscreen DĂ®mentĂªr Always on Top Her tim li ser Film info Agahiya FĂ®lmĂª Open file PelĂª veke Open folder Light theme Open URL URLyĂª Veke Open CD/DVD CD/DVDyĂª veke Mini Mode Moda Biçûk Play Mode Moda LĂªxistinĂª Order Play Dora LĂªdanĂª Shuffle Play LĂªdana Tevlihev Single Play Bi TenĂª LĂª Bide Single Loop Çerxa StranĂª List Loop Çerxa LĂ®steyĂª Frame Sehne Default DestpĂªkĂ® Clockwise Ber bi hĂªla saetĂª ve Counterclockwise Ber bi berevajiya hĂªla saetĂª ve Next frame Sehneya pĂªÅŸve Previous frame Sehneya paÅŸve Sound Deng Channel Kanal Stereo Cotekanal Left channel Kanala çep Right channel Kanala rast Track Stran Subtitle BinnivĂ®s Load Bar Bike Online Search LĂªgerĂ®na Serxet Select HilbijĂªre Hide VeÅŸĂªre Encodings KodkirĂ® Screenshot DĂ®mena dĂ®menderĂª Film Screenshot DĂ®mendera FĂ®lmĂª Burst Shooting RĂªzegirtin Playlist LĂ®steya LĂªxistinĂª Film Info Agahiya FĂ®lmĂª Clear playlist LĂ®steya lĂªdanĂª jĂª bibe Display in file manager Di rĂªvebira dosyeyĂª de rĂª bide dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save dmr::MainWindow Load successfully Barkirin bi ser ket Load failed Barkirin bi ser neket No device found AmĂ»r nehat dĂ®tin Parse Failed GuherĂ®n bi ser neket Open folder Open file PelĂª veke All videos (%1) HemĂ» vĂ®dyo (%1) Muted Hat bĂªdengkirin Volume: %1% Deng: %1% Subtitle %1: %2s BinnivĂ®s %1: %2s delayed derengman advanced pĂªÅŸketĂ® Speed: %1x Lez: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View DĂ®tin Movie Screenshot DĂ®mena DĂ®menderĂª ya SĂ®nemayĂª Saved to Hat qeydkirin li The screenshot is saved DĂ®mena dĂ®menderĂª hat qeydkirin Failed to save the screenshot Invalid file: %1 PelĂª nederbasdar: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: TĂ®pa PelĂª: Resolution: HĂ»rbĂ®nĂ®: File Size: Mezinahiya PelĂª: Duration: DirĂ®jahĂ®: File Path: Riya PelĂª: dmr::MpvProxy [internal] [nav] dmr::PlayItemWidget File does not exist Pel nehat dĂ®tin dmr::Settings %1/DMovie%2.jpg %1/DSĂ®nema%2.jpg %1/DMovie%2(%3).jpg %1/DSĂ®nema%2(%3).jpg dmr::ToolboxProxy Play LĂª Bide Previous PaÅŸve Next PĂªÅŸve Subtitles BinnivĂ®s Playlist LĂ®steya LĂªxistinĂª Fullscreen DĂ®mentĂªr Play/Pause LĂªxe/BisekinĂ®ne Exit fullscreen Ji dĂ®mentĂªrĂª derkeve Pause Bisekine deepin-movie-reborn-5.0.0/src/translations/deepin-movie_lt.ts000066400000000000000000000675441351125414100243370ustar00rootroot00000000000000 QObject Deepin Movie Deepin filmas Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Deepin filmas yra protingai sukurtas ir visiÅ¡kai parengtas vaizdo įrašų grotuvas su paprastu dizainu be rÄ—melio. Jis palaiko vietinį ir transliuojamÄ… medijos atkÅ«rimÄ… bei daugelį vaizdo formatų. Invalid folder Neteisingas aplankas Open folder Atverti aplankÄ… You don't have permission to operate this folder JÅ«s neturite leidimo dirbti su Å¡iuo aplanku Auto add similar files to play AutomatiÅ¡kai pridÄ—ti panaÅ¡ius failus į atkÅ«rimÄ… Clear playlist when exit IÅ¡einant, iÅ¡valyti grojaraÅ¡tį Show video preview on mouseover Užvedus pelÄ™, rodyti vaizdo įraÅ¡o peržiÅ«rÄ… Open a new player for each file played Kiekvienam atkuriamam failui atverti naujÄ… grotuvÄ… Pause when minimized Pristabdyti, kai suskleidžiama Remember playback position Prisiminti atkÅ«rimo vietÄ… Path Kelias Basic Pagrindiniai Play Groti Screenshot Ekrano kopija Shortcuts Trumpiniai File Failas Frame/Sound Kadras/Garsas Playback AtkÅ«rimas Subtitle Subtitrai Font Style Å rifto stilius Restore Defaults Atkurti numatytuosius Open file Atverti failÄ… Open next Atverti kitÄ… Open previous Atverti ankstesnį Mini mode Minimali veiksena Mute Nutildyti Next frame Kitas kadras Previous frame Ankstesnis kadras Volume down Tildyti Volume up Garsinti Speed up Pagreitinti Speed down SulÄ—tinti Fullscreen Visas ekranas Pause/Play Groti/Pristabdyti Playlist GrojaraÅ¡tis Reset speed Atstatyti greitį Rewind Atsukti Forward Pirmyn Burst screenshot PliÅ«psnis ekrano kopijų Film screenshot Filmo ekrano kopija 0.5s backward 0.5 sek. atgal 0.5s forward 0.5 sek. pirmyn Font Å riftas Font Size Å rifto dydis UrlDialog Cancel Atsisakyti Confirm Patvirtinti Please enter the URL: Ä®veskite URL: dmr::ActionFactory Settings Nustatymai Fullscreen Visas ekranas Always on Top Visada virÅ¡uje Film info Filmo informacija Open file Atverti failÄ… Open folder Atverti aplankÄ… Light theme Å viesi tema Open URL Atverti URL Open CD/DVD Atverti CD/DVD Mini Mode Minimali veiksena Play Mode AtkÅ«rimo veiksena Order Play Tvarkingas atkÅ«rimas Shuffle Play MaiÅ¡ytas atkÅ«rimas Single Play Pavienis atkÅ«rimas Single Loop Pavienio kartojimas List Loop SÄ…raÅ¡o kartojimas Frame Kadras Default Numatytasis Clockwise Pagal laikrodžio rodyklÄ™ Counterclockwise PrieÅ¡ laikrodžio rodyklÄ™ Next frame Kitas kadras Previous frame Ankstesnis kadras Sound Garsas Channel Kanalas Stereo Stereo Left channel Kairysis kanalas Right channel DeÅ¡inysis kanalas Track Takelis Subtitle Subtitrai Load Ä®kelti Online Search IeÅ¡koti internete Select Pasirinkti Hide SlÄ—pti Encodings KoduotÄ—s Screenshot Ekrano kopija Film Screenshot Filmo ekrano kopija Burst Shooting PliÅ«psnis ekrano kopijų Playlist GrojaraÅ¡tis Film Info Filmo informacija Clear playlist IÅ¡valyti grojaraÅ¡tį Display in file manager Rodyti failų tvarkytuvÄ—je dmr::BurstScreenshotsDialog Duration: %1 TrukmÄ—: %1 Resolution: %1 RaiÅ¡ka: %1 Size: %1 Dydis: %1 Save Ä®raÅ¡yti dmr::MainWindow Load successfully Ä®kÄ—limas sÄ—kmingas Load failed Ä®kÄ—limas nepavyko No device found Nerasta jokio įrenginio Parse Failed NagrinÄ—jimas nepavyko Open folder Atverti aplankÄ… Open file Atverti failÄ… All videos (%1) Visi vaizdo įraÅ¡ai (%1) Muted Nutildyta Volume: %1% Garsis: %1% Subtitle %1: %2s Subtitrai %1: %2s delayed vÄ—luoja advanced skuba Speed: %1x Greitis: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) Subtitrai (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View ŽiÅ«rÄ—ti Movie Screenshot Filmo ekrano kopija Saved to Ä®raÅ¡yta į The screenshot is saved Ekrano kopija įraÅ¡yta Failed to save the screenshot Nepavyko įraÅ¡yti ekrano kopijos Invalid file: %1 Neteisingas failas: %1 dmr::MovieInfo %1G %1G %1M %1M %1K %1K %1 %1 dmr::MovieInfoDialog File Type: Failo tipas: Resolution: RaiÅ¡ka: File Size: Failo dydis: Duration: TrukmÄ—: File Path: Failo kelias: dmr::MpvProxy [internal] [vidinis] dmr::PlayItemWidget File does not exist Failo nÄ—ra dmr::Settings %1/DMovie%2.jpg %1/DFilmas%2.jpg %1/DMovie%2(%3).jpg %1/DFilmas%2(%3).jpg dmr::ToolboxProxy Play Groti Previous Ankstesnis Next Kitas Subtitles Subtitrai Playlist GrojaraÅ¡tis Fullscreen Visas ekranas Play/Pause Groti/Pristabdyti Exit fullscreen IÅ¡eiti iÅ¡ viso ekrano Pause Pristabdyti deepin-movie-reborn-5.0.0/src/translations/deepin-movie_ml.ts000066400000000000000000000646101351125414100243170ustar00rootroot00000000000000 QObject Deepin Movie Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Invalid folder Open folder You don't have permission to operate this folder Auto add similar files to play Clear playlist when exit Show video preview on mouseover Open a new player for each file played Pause when minimized Remember playback position Path Basic Play Screenshot Shortcuts File Frame/Sound Playback Subtitle Font Style Restore Defaults Open file Open next Open previous Mini mode Mute Next frame Previous frame Volume down Volume up Speed up Speed down Fullscreen Pause/Play Playlist Reset speed Rewind Forward Burst screenshot Film screenshot 0.5s backward 0.5s forward Font Font Size UrlDialog Cancel റദàµà´¦à´¾à´•àµà´•àµà´• Confirm ഉറപàµà´ªà´¾à´•àµà´•àµà´• Please enter the URL: dmr::ActionFactory Settings Fullscreen Always on Top Film info Open file Open folder Light theme Open URL Open CD/DVD Mini Mode Play Mode Order Play Shuffle Play Single Play Single Loop List Loop Frame Default Clockwise Counterclockwise Next frame Previous frame Sound Channel Stereo Left channel Right channel Track Subtitle Load Online Search Select Hide Encodings Screenshot Film Screenshot Burst Shooting Playlist Film Info Clear playlist Display in file manager dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save സൂകàµà´·à´¿à´•àµà´•àµà´• dmr::MainWindow Load successfully Load failed No device found Parse Failed Open folder Open file All videos (%1) Muted Volume: %1% Subtitle %1: %2s delayed advanced Speed: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Movie Screenshot Saved to The screenshot is saved Failed to save the screenshot Invalid file: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Resolution: File Size: Duration: File Path: dmr::MpvProxy [internal] dmr::PlayItemWidget File does not exist dmr::Settings %1/DMovie%2.jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Previous Next à´…à´Ÿàµà´¤àµà´¤à´¤àµ Subtitles Playlist Fullscreen Play/Pause Exit fullscreen Pause deepin-movie-reborn-5.0.0/src/translations/deepin-movie_mn.ts000066400000000000000000000670631351125414100243260ustar00rootroot00000000000000 QObject Deepin Movie Đ”ÑÑĐ¿Đ¸Đ½ ĐĐ¸Đ½Đ¾ Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Đ”ÑÑĐ¿Đ¸Đ½ ĐºĐ¸Đ½Đ¾ Đ½ÑŒ Đ¼Đ°Ñˆ ÑĐ°Đ¹Đ½ Đ´Đ¸Đ·Đ°Đ¹Đ½ Đ±Đ¾Đ»Đ¾Đ½ Đ¾Đ½Ñ†Đ¾Đ³ Ñ‡Đ°Đ½Đ°Ñ€ÑƒÑƒĐ´Ñ‹Đ³ ÑˆĐ¸Đ½Đ³ÑÑÑÑĐ½ Đ²Đ¸Đ´ĐµĐ¾ Ñ‚Đ¾Đ³Đ»ÑƒÑƒĐ»Đ°Đ³Ñ‡ Đ±Ó©Đ³Ó©Ó©Đ´ Ñ…̉¯Ñ€ÑÑĐ³̉¯Đ¹ Đ´Đ¸Đ·Đ°Đ¹Đ½ Đ´Đ¾Ñ‚Đ¾Đ¾Đ´ Đ±Đ¾Đ»Đ¾Đ½ ÑˆÑƒÑƒĐ´ уурÑĐ³Đ°Đ»Ñ‹Đ½ Đ¼ĐµĐ´Đ¸Đ° Ñ„Đ°Đ¹Đ»ÑƒÑƒĐ´Ñ‹Đ³ Ñ‚Đ¾Đ³Đ»ÑƒÑƒĐ»Đ°Ñ…Đ°Đ°Ñ Đ³Đ°Đ´Đ½Đ° Đ¾Đ»Đ¾Đ½ Ñ‚Ó©Ñ€Ó©Đ»Đ¸Đ¹Đ½ Đ²Đ¸Đ´ĐµĐ¾ Ñ„Đ¾Ñ€Đ¼Đ°Ñ‚Ñ‹Đ³ Đ´ÑĐ¼Đ¶Đ´ÑĐ³. Invalid folder Đ‘ÑƒÑ€ÑƒÑƒ Ñ…Đ°Đ²Ñ‚Đ°Ñ Open folder You don't have permission to operate this folder Đ¢Đ°Đ½Đ´ ÑĐ½Ñ Ñ…Đ°Đ²Ñ‚Đ°ÑÑ‚Đ°Đ¹ Đ°Đ¶Đ¸Đ»Đ»Đ°Ñ…Đ°Đ´ Đ·Ó©Đ²ÑˆÓ©Ó©Ñ€Ó©Đ» Đ±Đ°Đ¹Ñ…Đ³̉¯Đ¹ Đ±Đ°Đ¹Đ½Đ° Auto add similar files to play Đ˜Đ¶Đ¸Đ» Ñ‚Ó©Ñ€Ó©Đ»Đ¸Đ¹Đ½ Ñ„Đ°Đ¹Đ»ÑƒÑƒĐ´Ñ‹Đ³ Đ°Đ²Ñ‚Đ¾Đ¼Đ°Ñ‚Đ°Đ°Ñ€ Đ½ÑĐ¼Đ¶ Ñ‚Đ¾Đ³Đ»ÑƒÑƒĐ»Đ°Ñ… Clear playlist when exit Đ“Đ°Ñ€Đ°Ñ… ̉¯ĐµĐ´ Ñ‚Đ¾Đ³Đ»ÑƒÑƒĐ»Đ°Ñ… Đ¶Đ°Đ³ÑĐ°Đ°Đ»Ñ‚Ñ‹Đ³ цÑĐ²ÑÑ€Đ»ÑÑ… Show video preview on mouseover Đ¥ÑƒĐ»Đ³Đ°Đ½Ñ‹ Đ·Đ°Đ°Đ³Ñ‡Đ°Đ°Ñ€ Đ´ÑÑĐ³̉¯̉¯Ñ€ Đ³̉¯Đ¹Đ»Đ³ÑÑ…ÑĐ´ Đ²Đ¸Đ´ĐµĐ¾Đ³ ÑƒÑ€ÑŒĐ´Ñ‡Đ¸Đ»Đ°Đ½ Ñ…Đ°Ñ€Đ°Ñ… Open a new player for each file played Pause when minimized Remember playback position Đ¢Đ¾Đ³Đ»ÑƒÑƒĐ»Đ°Ñ… Đ±Đ°Đ¹Ñ€Đ»Đ°Đ»Ñ‹Đ³ ÑĐ°Đ½Đ°Ñ… Path Đ—Đ°Đ¼ Basic Đ­Đ½Đ³Đ¸Đ¹Đ½ Play Đ¢Đ¾Đ³Đ»ÑƒÑƒĐ»Đ°Ñ… Screenshot Đ”ÑĐ»Đ³ÑÑ†Đ¸Đ¹Đ½ Đ·ÑƒÑ€Đ°Đ³ Shortcuts Đ¢Đ¾Đ²Ñ‡Đ½ÑƒÑƒĐ´ File Frame/Sound Playback Subtitle Font Style Restore Defaults ĐĐ½Ñ…Đ´Đ°Đ³Ñ‡ ÑƒÑ‚Đ³Đ° ÑÑÑ€Đ³ÑÑÑ… Open file Open next Open previous Mini mode Mute Đ”ÑƒÑƒ Ñ…Đ°Đ°Ñ… Next frame Previous frame Volume down Đ”ÑƒÑƒ Đ½Đ°Đ¼ÑĐ³Đ°Ñ… Volume up Đ”ÑƒÑƒ Ñ‡Đ°Đ½Đ³Đ°Đ»Đ°Ñ… Speed up Speed down Fullscreen Đ”ÑĐ»Đ³Ñц Đ´̉¯̉¯Ñ€ÑĐ½ Pause/Play Playlist Đ–Đ°Đ³ÑĐ°Đ°Đ»Ñ‚ Reset speed Rewind Forward Burst screenshot Film screenshot 0.5s backward 0.5s forward Font Đ¤Đ¾Đ½Ñ‚ Font Size UrlDialog Cancel Đ¦ÑƒÑ†Đ»Đ°Ñ… Confirm Đ‘Đ°Ñ‚Đ»Đ°Ñ… Please enter the URL: dmr::ActionFactory Settings Đ¢Đ¾Ñ…Đ¸Ñ€Đ³Đ¾Đ¾ Fullscreen Đ”ÑĐ»Đ³Ñц Đ´̉¯̉¯Ñ€ÑĐ½ Always on Top Film info Open file Open folder Light theme Open URL Open CD/DVD Mini Mode Play Mode Đ¢Đ¾Đ³Đ»Đ¾Ñ… Đ³Đ¾Ñ€Đ¸Đ¼ Order Play Shuffle Play Single Play Single Loop ĐÑĐ³Đ¸Đ¹Đ³ Đ´Đ°Đ²Ñ‚ List Loop Đ–Đ°Đ³ÑĐ°Đ°Đ»Ñ‚Ñ‹Đ³ Đ´Đ°Đ²Ñ‚ Frame Default ̉®Đ½Đ´ÑÑĐ½ Clockwise Counterclockwise Next frame Previous frame Sound Đ”ÑƒÑƒ Channel Đ¡ÑƒĐ²Đ°Đ³ Stereo Left channel Right channel Track Subtitle Load Online Search Select Đ¡Đ¾Đ½Đ³Đ¾Ñ… Hide Encodings Screenshot Đ”ÑĐ»Đ³ÑÑ†Đ¸Đ¹Đ½ Đ·ÑƒÑ€Đ°Đ³ Film Screenshot Burst Shooting Playlist Đ–Đ°Đ³ÑĐ°Đ°Đ»Ñ‚ Film Info Clear playlist Display in file manager Đ¤Đ°Đ¹Đ» Đ¼ĐµĐ½ĐµĐ¶ĐµÑ€Ñ‚ Ñ…Đ°Ñ€Đ°Ñ… dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save Đ¥Đ°Đ´Đ³Đ°Đ»Đ°Ñ… dmr::MainWindow Load successfully Load failed No device found Parse Failed Open folder Open file All videos (%1) Muted Volume: %1% Subtitle %1: %2s delayed advanced Speed: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Movie Screenshot Saved to The screenshot is saved Failed to save the screenshot Invalid file: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Resolution: File Size: Duration: Đ£Ñ€Ñ‚: File Path: dmr::MpvProxy [internal] dmr::PlayItemWidget File does not exist dmr::Settings %1/DMovie%2.jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Đ¢Đ¾Đ³Đ»ÑƒÑƒĐ»Đ°Ñ… Previous Ñ²Đ¼Đ½Ñ³Ñ… Next Đ”Đ°Ñ€Đ°Đ°Ñ… Subtitles Playlist Đ–Đ°Đ³ÑĐ°Đ°Đ»Ñ‚ Fullscreen Đ”ÑĐ»Đ³Ñц Đ´̉¯̉¯Ñ€ÑĐ½ Play/Pause Đ¢Đ¾Đ³Đ»ÑƒÑƒĐ»Đ°Ñ…/Đ—Đ¾Đ³ÑĐ¾Đ¾Ñ… Exit fullscreen Đ”̉¯̉¯Ñ€ÑĐ½ Đ´ÑĐ»Đ³ÑцÑÑÑ Đ³Đ°Ñ€Đ°Ñ… Pause deepin-movie-reborn-5.0.0/src/translations/deepin-movie_ms.ts000066400000000000000000000671041351125414100243270ustar00rootroot00000000000000 QObject Deepin Movie Wayang Deepin Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Cereka Deepin adalah pemain video berfitur-penuh dengan rekabentuk tanpa-sempadan yang ringkas dan menarik. Ia dapat memainkan media setempat dan strim dengan sokongan format video berbilang. Invalid folder Folder tidak sah Open folder Buka folder You don't have permission to operate this folder Anda tidak mendapat keizinan untuk mengoperasi folder ini Auto add similar files to play Auto tambah fail serupa yang hendak dimainkan Clear playlist when exit Kosongkan senarai main bila keluar Show video preview on mouseover Tunjuk pratonton video jika penuding tetikus berada di atas Open a new player for each file played Buka satu pemain baharu bagi setiap fail yang dimainkan Pause when minimized Jeda bila diminimumkan Remember playback position Ingat kedudukan main balik Path Laluan Basic Asas Play Main Screenshot Cekupan skrin Shortcuts Pintasan File Fail Frame/Sound Bingkai/Bunyi Playback Main balik Subtitle Sarikata Font Style Gaya Fon Restore Defaults Pulih ke Lalai Open file Buka fail Open next Buka berikutnya Open previous Buka terdahulu Mini mode Mod mini Mute Senyap Next frame Bingkai berikutnya Previous frame Bingkai terdahulu Volume down Volum turun Volume up Volum naik Speed up Kelajuan naik Speed down Kelajuan turun Fullscreen Skrin Penuh Pause/Play Jeda/Main Playlist Senarai Main Reset speed Tetap semula kelajuan Rewind Mandir Forward Maju Burst screenshot Cekupan skrin ledakan Film screenshot Cekupan skrin filem 0.5s backward 0.5s mengundur 0.5s forward 0.5s dimajukan Font Fon Font Size Saiz Fon UrlDialog Cancel Batal Confirm Sahkan Please enter the URL: Sila masukkan URL: dmr::ActionFactory Settings Tetapan Fullscreen Skrin Penuh Always on Top Sentiasa di Atas Film info Maklumat filem Open file Buka fail Open folder Buka folder Light theme Tema cerah Open URL Buka URL Open CD/DVD Buka CD/DVD Mini Mode Mod Mini Play Mode Mod Main Order Play Tertib Main Shuffle Play Kocok Main Single Play Sekali Main Single Loop Ulang Tunggal List Loop Ulang Senarai Frame Bingkai Default Lalai Clockwise Ikut Jam Counterclockwise Lawan Jam Next frame Bingkai berikutnya Previous frame Bingkai terdahulu Sound Bunyi Channel Saluran Stereo Stereo Left channel Saluran kiri Right channel Saluran kanan Track Trek Subtitle Sarikata Load Muat Online Search Gelintar Atas Talian Select Pilih Hide Sembunyi Encodings Pengekodan Screenshot Cekupan skrin Film Screenshot Cekupan Skrin Filem Burst Shooting Cekupan Ledakan Playlist Senarai Main Film Info Maklumat Filem Clear playlist Kosongkan senarai main Display in file manager Papar dalam pengurus fail dmr::BurstScreenshotsDialog Duration: %1 Tempoh: %1 Resolution: %1 Resolusi: %1 Size: %1 Saiz: %1 Save Simpan dmr::MainWindow Load successfully Berjaya dimuatkan Load failed Gagal dimuatkan No device found Tiada peranti ditemui Parse Failed Gagal Dihuraikan Open folder Buka folder Open file Buka fail All videos (%1) Semua video (%1) Muted Disenyapkan Volume: %1% Volum: %1% Subtitle %1: %2s Sarikata %1: %2s delayed lengah advanced lanjutan Speed: %1x Kelajuan: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) Sarikata (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Lihat Movie Screenshot Cekupan Skrin Cereka Saved to Disimpan ke The screenshot is saved Cekupan skrin telah disimpan Failed to save the screenshot Gagal menyimpan cekupan skrin Invalid file: %1 Fail tidak sah: %1 dmr::MovieInfo %1G %1G %1M %1M %1K %1K %1 %1 dmr::MovieInfoDialog File Type: Jenis Fail: Resolution: Resolusi: File Size: Saiz Fail: Duration: Tempoh: File Path: Laluan Fail: dmr::MpvProxy [internal] [dalaman] dmr::PlayItemWidget File does not exist Fail tidak wujud dmr::Settings %1/DMovie%2.jpg %1/DMovie%2.jpg %1/DMovie%2(%3).jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Main Previous Terdahulu Next Berikutnya Subtitles Sarikata Playlist Senarai Main Fullscreen Skrin Penuh Play/Pause Main/Jeda Exit fullscreen Keluar dari skrin penuh Pause Jeda deepin-movie-reborn-5.0.0/src/translations/deepin-movie_nb.ts000066400000000000000000000654751351125414100243200ustar00rootroot00000000000000 QObject Deepin Movie Deepin film Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Deepin Film er en vell-designet og fullverdig video spiller med et enkelt grenseløst design. Den støtter lokal og strømming av media innhold, i forskjellige video formater. Invalid folder Ugyldig mappe Open folder Ă…pne mappe You don't have permission to operate this folder Auto add similar files to play Clear playlist when exit Show video preview on mouseover Open a new player for each file played Pause when minimized Pause nĂ¥r minimert Remember playback position Husk avspillingsposisjon Path Sti Basic Grunnleggende Play Spill av Screenshot Skjermskudd Shortcuts Hurtigtaster File Fil Frame/Sound Ramme/Lyd Playback Avspilling Subtitle Undertekst Font Style Skrifttype Restore Defaults Gjenopprett Standard Open file Ă…pne fil Open next Ă…pne neste Open previous Ă…pne forrige Mini mode Mini modus Mute Demp Next frame Previous frame Volume down Lyd ned Volume up Lyd opp Speed up Ă˜k hastighet Speed down Senk hastighet Fullscreen Fullskjerm Pause/Play Pause/Spill av Playlist Spilleliste Reset speed Rewind Tilbake Forward Fremover Burst screenshot En salve skermskudd Film screenshot 0.5s backward 0.5s forward Font Skrifttype Font Size Skriftstørrelse UrlDialog Cancel Avbryt Confirm Bekreft Please enter the URL: dmr::ActionFactory Settings Instillinger Fullscreen Fullskjerm Always on Top Alltid øverst Film info Open file Ă…pne fil Open folder Ă…pne mappe Light theme Open URL Ă…pne URL Open CD/DVD Mini Mode Minimodus Play Mode Avspillingsmodus Order Play Shuffle Play Single Play Single Loop List Loop Frame Ramme Default Standard Clockwise Klokkeretning Counterclockwise Next frame Previous frame Sound Lyd Channel Kanal Stereo Stereo Left channel Right channel Track Spor Subtitle Undertekst Load Online Search Select Velg Hide Encodings Screenshot Skjermskudd Film Screenshot Burst Shooting Playlist Spilleliste Film Info Clear playlist Tøm spilleliste Display in file manager Vis i filutforsker dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save Lagre dmr::MainWindow Load successfully Load failed No device found Parse Failed Open folder Ă…pne mappe Open file Ă…pne fil All videos (%1) Muted Stille Volume: %1% Subtitle %1: %2s delayed advanced Speed: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Vis Movie Screenshot Skjermskudd Saved to The screenshot is saved Failed to save the screenshot Invalid file: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Resolution: File Size: Duration: Lengde: File Path: dmr::MpvProxy [internal] dmr::PlayItemWidget File does not exist dmr::Settings %1/DMovie%2.jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Spill av Previous Forrige Next Neste Subtitles Undertekster Playlist Spilleliste Fullscreen Fullskjerm Play/Pause Spill/Pause Exit fullscreen Lukk fullskjerm Pause Pause deepin-movie-reborn-5.0.0/src/translations/deepin-movie_ne.ts000066400000000000000000000650231351125414100243100ustar00rootroot00000000000000 QObject Deepin Movie डिपिन à¤à¤²à¤à¤¿à¤¤à¥à¤° Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Invalid folder Open folder You don't have permission to operate this folder Auto add similar files to play Clear playlist when exit Show video preview on mouseover Open a new player for each file played Pause when minimized Remember playback position Path Basic Play Screenshot Shortcuts सरà¥à¤Ÿà¤•टहरू File Frame/Sound Playback Subtitle Font Style Restore Defaults Open file Open next Open previous Mini mode Mute मà¥à¤¯à¥‚ट गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥ Next frame Previous frame Volume down Volume up Speed up Speed down Fullscreen Pause/Play Playlist Reset speed Rewind Forward Burst screenshot Film screenshot 0.5s backward 0.5s forward Font Font Size UrlDialog Cancel रदà¥à¤¦ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥ Confirm पकà¥à¤•ा गरà¥à¤¨à¥ Please enter the URL: dmr::ActionFactory Settings सेटिंगà¥à¤¸ Fullscreen Always on Top Film info Open file Open folder Light theme Open URL Open CD/DVD Mini Mode Play Mode Order Play Shuffle Play Single Play Single Loop List Loop Frame Default Clockwise Counterclockwise Next frame Previous frame Sound धà¥à¤µà¤¨à¤¿ Channel Stereo Left channel Right channel Track Subtitle Load Online Search Select Hide Encodings Screenshot Film Screenshot Burst Shooting Playlist Film Info Clear playlist Display in file manager dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥ dmr::MainWindow Load successfully Load failed No device found Parse Failed Open folder Open file All videos (%1) Muted Volume: %1% Subtitle %1: %2s delayed advanced Speed: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Movie Screenshot Saved to The screenshot is saved Failed to save the screenshot Invalid file: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Resolution: File Size: Duration: File Path: dmr::MpvProxy [internal] dmr::PlayItemWidget File does not exist dmr::Settings %1/DMovie%2.jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Previous Next अरà¥à¤•ो Subtitles Playlist Fullscreen Play/Pause Exit fullscreen Pause deepin-movie-reborn-5.0.0/src/translations/deepin-movie_nl.ts000066400000000000000000000673721351125414100243300ustar00rootroot00000000000000 QObject Deepin Movie Deepin Video's Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Deepin Video's is een goed ontworpen, complete mediaspeler met een eenvoudig, randloos ontwerp. Deepin Video's ondersteunt het afspelen van lokale video's en streams in allerlei formaten. Invalid folder Ongeldige map Open folder Map openen You don't have permission to operate this folder Je bent niet gemachtigd om deze map te gebruiken Auto add similar files to play Voeg soortgelijke bestanden automatisch toe om af te spelen Clear playlist when exit Afspeellijst wissen na afsluiten Show video preview on mouseover Videovoorvertoning tonen bij overheen slepen van cursor Open a new player for each file played Nieuwe speler openen voor elk afgespeeld bestand Pause when minimized Pauzeren bij minimaliseren Remember playback position Afspeelpositie onthouden Path Pad Basic Basis Play Afspelen Screenshot Schermafdruk Shortcuts Sneltoetsen File Bestand Frame/Sound Frame/Geluid Playback Afspelen Subtitle Ondertitel Font Style Lettertypestijl Restore Defaults Standaardwaarden herstellen Open file Bestand openen Open next Volgende openen Open previous Vorige openen Mini mode Mini-modus Mute Dempen Next frame Volgend frame Previous frame Vorig frame Volume down Volume omlaag Volume up Volume omhoog Speed up Versnellen Speed down Vertragen Fullscreen Volledig scherm Pause/Play Pauzeren/Afspelen Playlist Afspeellijst Reset speed Standaardsnelheid Rewind Terugspoelen Forward Vooruitspoelen Burst screenshot Schermafdruk barsten Film screenshot Schermafdruk van film 0.5s backward 0.5s terugspoelen 0.5s forward 0.5s vooruitspoelen Font Lettertype Font Size Lettertypegrootte UrlDialog Cancel Annuleren Confirm Bevestigen Please enter the URL: Voer de URL in: dmr::ActionFactory Settings Instellingen Fullscreen Volledig scherm Always on Top Altijd bovenaan Film info Filminformatie Open file Bestand openen Open folder Map openen Light theme Licht thema Open URL URL openen Open CD/DVD CD/DVD openen Mini Mode Mini-modus Play Mode Afspeelmodus Order Play Afspeelvolgorde Shuffle Play Willekeurig afspelen Single Play Enkel afspelen Single Loop Enkele herhaling List Loop Lijst herhalen Frame Frame Default Standaard Clockwise Naar rechts Counterclockwise Naar links Next frame Volgend frame Previous frame Vorig frame Sound Geluid Channel Kanaal Stereo Stereo Left channel Linkerkanaal Right channel Rechterkanaal Track Nummer Subtitle Ondertitel Load Laden Online Search Zoeken op internet Select Kiezen Hide Verbergen Encodings Versleutelingen Screenshot Schermafdruk Film Screenshot Schermafdruk van film Burst Shooting Burstopname Playlist Afspeellijst Film Info Filminformatie Clear playlist Afspeellijst wissen Display in file manager Tonen in bestandsbeheerder dmr::BurstScreenshotsDialog Duration: %1 Duur: %1 Resolution: %1 Resolutie: %1 Size: %1 Grootte: %1 Save Bewaren dmr::MainWindow Load successfully Laden voltooid Load failed Laden mislukt No device found Geen apparaat gevonden Parse Failed Verwerken mislukt Open folder Map openen Open file Bestand openen All videos (%1) Alle video's (%1) Muted Gedempt Volume: %1% Volume: %1% Subtitle %1: %2s Ondertitel %1: %2s delayed vertraagd advanced geavanceerd Speed: %1x Snelheid: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) Ondertitel (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Bekijken Movie Screenshot Schermafdruk van film Saved to Opgeslagen naar The screenshot is saved De schermafdruk is opgelagen Failed to save the screenshot Kan schermafdruk niet opslaan Invalid file: %1 Ongeldig bestand: %1 dmr::MovieInfo %1G %1G %1M %1M %1K %1K %1 %1 dmr::MovieInfoDialog File Type: Bestandstype: Resolution: Resolutie: File Size: Bestandsgrootte: Duration: Duur: File Path: Bestandspad: dmr::MpvProxy [internal] [intern] dmr::PlayItemWidget File does not exist Bestand bestaat niet dmr::Settings %1/DMovie%2.jpg %1/DMovie%2.jpg %1/DMovie%2(%3).jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Afspelen Previous Vorige Next Volgende Subtitles Ondertiteling Playlist Afspeellijst Fullscreen Beeldvullend Play/Pause Afspelen/pauzeren Exit fullscreen Beeldvullende modus verlaten Pause Pauzeren deepin-movie-reborn-5.0.0/src/translations/deepin-movie_pam.ts000066400000000000000000000645541351125414100244730ustar00rootroot00000000000000 QObject Deepin Movie Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Invalid folder Open folder You don't have permission to operate this folder Auto add similar files to play Clear playlist when exit Show video preview on mouseover Open a new player for each file played Pause when minimized Remember playback position Path Basic Play Screenshot Shortcuts File Frame/Sound Playback Subtitle Font Style Restore Defaults Open file Ibuklat file Open next Open previous Mini mode Mute I-mute Next frame Previous frame Volume down Volume up Speed up Speed down Fullscreen I-fullscreen Pause/Play Playlist Reset speed Rewind Forward Burst screenshot Film screenshot 0.5s backward 0.5s forward Font Font Size UrlDialog Cancel I-cancel Confirm Kumpirman Please enter the URL: dmr::ActionFactory Settings Fullscreen I-fullscreen Always on Top Film info Open file Ibuklat file Open folder Light theme Open URL Ibuklat URL Open CD/DVD Mini Mode Play Mode Order Play Shuffle Play Single Play Single Loop List Loop Frame Default Clockwise Counterclockwise Next frame Previous frame Sound Channel Stereo Left channel Right channel Track Subtitle Load Online Search Select Hide Encodings Screenshot Film Screenshot Burst Shooting Playlist Film Info Clear playlist Display in file manager dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save Isinup dmr::MainWindow Load successfully Load failed No device found Parse Failed Open folder Open file Ibuklat file All videos (%1) Muted Volume: %1% Subtitle %1: %2s delayed advanced Speed: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Movie Screenshot Saved to The screenshot is saved Failed to save the screenshot Invalid file: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Resolution: File Size: Duration: File Path: dmr::MpvProxy [internal] dmr::PlayItemWidget File does not exist dmr::Settings %1/DMovie%2.jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Previous Next Subtitles Playlist Fullscreen I-fullscreen Play/Pause Exit fullscreen Lumwal fullscreen Pause I-pause deepin-movie-reborn-5.0.0/src/translations/deepin-movie_pl.ts000066400000000000000000000677351351125414100243350ustar00rootroot00000000000000 QObject Deepin Movie Filmy Deepin Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Program Filmy Deepin to dobrze zaprojektowany i peÅ‚en możliwoÅ›ci odtwarzacz filmĂ³w o prostym, pozbawionym obramowania stylu. ObsÅ‚uguje zarĂ³wno lokalne, jak i sieciowe pliki mediĂ³w w najrĂ³Å¼niejszych formatach wideo. Invalid folder NieprawidÅ‚owy katalog Open folder OtwĂ³rz katalog You don't have permission to operate this folder Nie masz uprawnieÅ„ do dziaÅ‚aÅ„ na tym katalogu Auto add similar files to play Automatycznie dodaj podobne pliki do odtwarzania Clear playlist when exit Wyczyść listÄ™ odtwarzania przy wyjÅ›ciu Show video preview on mouseover WyÅ›wietl podglÄ…d filmu przy najeżdżeniu myszkÄ… Open a new player for each file played OtwĂ³rz nowe okno odtwarzacza dla każdego odtwarzanego pliku Pause when minimized Wstrzymaj przy minimalizacji Remember playback position ZapamiÄ™taj pozycjÄ™ odtwarzania Path Åcieżka Basic Podstawowe Play OdtwĂ³rz Screenshot Zrzut ekranu Shortcuts SkrĂ³ty File Plik Frame/Sound Ramka/DźwiÄ™k Playback Odtwarzanie Subtitle Napisy Font Style Styl czcionki Restore Defaults PrzywrĂ³Ä‡ domyÅ›lne Open file OtwĂ³rz plik Open next OtwĂ³rz nastÄ™pny Open previous OtwĂ³rz poprzedni Mini mode Tryb mini Mute Wycisz Next frame NastÄ™pna klatka Previous frame Poprzednia klatka Volume down Przycisz Volume up PogÅ‚oÅ›nij Speed up Przyspiesz Speed down Spowolnij Fullscreen PeÅ‚ny ekran Pause/Play Wstrzymaj/OdtwĂ³rz Playlist Lista odtwarzania Reset speed PrzywrĂ³Ä‡ prÄ™dkość Rewind PrzewiÅ„ do tyÅ‚u Forward PrzewiÅ„ do przodu Burst screenshot Seria zrzutĂ³w ekranu Film screenshot Zrzut ekranu z filmu 0.5s backward 0,5 s do tyÅ‚u 0.5s forward 0,5 s do przodu Font Czcionka Font Size Rozmiar czcionki UrlDialog Cancel Anuluj Confirm Potwierdź Please enter the URL: Prosimy wpisać adres URL: dmr::ActionFactory Settings Ustawienia Fullscreen PeÅ‚ny ekran Always on Top Zawsze na wierzchu Film info Informacje o filmie Open file OtwĂ³rz plik Open folder OtwĂ³rz katalog Light theme Jasny motyw Open URL OtwĂ³rz URL Open CD/DVD OtwĂ³rz CD/DVD Mini Mode Tryb mini Play Mode Tryb odtwarzania Order Play PorzÄ…dek odtwarzania Shuffle Play Dowolne odtwarzanie Single Play Pojedyncze odtworzenie Single Loop Pojedyncza pÄ™tla List Loop PÄ™tla listy Frame Ramka Default DomyÅ›lny Clockwise Zgodnie z ruchem wskazĂ³wek zegara Counterclockwise Przeciwnie do ruchu wskazĂ³wek zegara Next frame NastÄ™pna klatka Previous frame Poprzednia klatka Sound DźwiÄ™k Channel KanaÅ‚ Stereo Stereo Left channel Lewy kanaÅ‚ Right channel Prawy kanaÅ‚ Track Åcieżka Subtitle Napisy Load Wczytaj Online Search Wyszukiwanie online Select Wybierz Hide Ukryj Encodings Kodowanie Screenshot Zrzut ekranu Film Screenshot Zrzut ekranu z filmu Burst Shooting Seria ujęć Playlist Lista odtwarzania Film Info Informacje o filmie Clear playlist Wyczyść listÄ™ odtwarzania Display in file manager WyÅ›wietl w menedżerze plikĂ³w dmr::BurstScreenshotsDialog Duration: %1 Czas trwania: %1 Resolution: %1 Rozdzielczość: %1 Size: %1 Rozmiar: %1 Save Zapisz dmr::MainWindow Load successfully PomyÅ›lnie wczytano Load failed Błąd wczytywania No device found Nie odnaleziono urzÄ…dzenia Parse Failed Błąd przetwarzania Open folder OtwĂ³rz katalog Open file OtwĂ³rz plik All videos (%1) Wszystkie filmy (%1) Muted Wyciszony Volume: %1% GÅ‚oÅ›ność: %1% Subtitle %1: %2s Napisy %1: %2s delayed opĂ³Åºnione advanced zaawansowane Speed: %1x PrÄ™dkość: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) Napisy (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View PodglÄ…d Movie Screenshot Zrzut ekranu z filmu Saved to Zapisano do The screenshot is saved Zrzut ekranu zostaÅ‚ zapisany Failed to save the screenshot Nie udaÅ‚o siÄ™ zapisać zrzutu ekranu Invalid file: %1 NieprawidÅ‚owy plik: %1 dmr::MovieInfo %1G %1G %1M %1M %1K %1K %1 %1 dmr::MovieInfoDialog File Type: Rodzaj pliku: Resolution: Rozdzielczość: File Size: Rozmiar pliku: Duration: Czas trwania: File Path: Åcieżka pliku: dmr::MpvProxy [internal] [wewnÄ™trzny] dmr::PlayItemWidget File does not exist Plik nie istnieje dmr::Settings %1/DMovie%2.jpg %1/DMovie%2.jpg %1/DMovie%2(%3).jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play OdtwĂ³rz Previous Poprzedni Next NastÄ™pny Subtitles Napisy Playlist Lista odtwarzania Fullscreen PeÅ‚ny ekran Play/Pause OdtwĂ³rz/Wstrzymaj Exit fullscreen Opuść tryb peÅ‚noekranowy Pause Wstrzymaj deepin-movie-reborn-5.0.0/src/translations/deepin-movie_pt.ts000066400000000000000000000676571351125414100243500ustar00rootroot00000000000000 QObject Deepin Movie Deepin Movie Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. O Deepin Movie Ă© um reprodutor de vĂ­deo completo e bem concebido, com um design simples e sem rebordo. Suporta reproduĂ§Ă£o local e remota de mĂ©dia em mĂºltiplos formatos de vĂ­deo. Invalid folder Pasta invĂ¡lida Open folder Abrir pasta You don't have permission to operate this folder NĂ£o tem permissĂ£o para interagir com esta pasta Auto add similar files to play Adicionar automaticamente ficheiros semelhantes para reproduzir Clear playlist when exit Limpar lista de reproduĂ§Ă£o ao sair Show video preview on mouseover Mostrar prĂ©-visualizaĂ§Ă£o do vĂ­deo Ă  passagem do rato Open a new player for each file played Abra um novo reprodutor para cada ficheiro reproduzido Pause when minimized Pausar quando minimizado Remember playback position Memorizar posiĂ§Ă£o da reproduĂ§Ă£o Path Caminho Basic BĂ¡sico Play Reproduzir Screenshot Capturar EcrĂ£ Shortcuts Atalhos File Ficheiro Frame/Sound Imagem/Som Playback ReproduĂ§Ă£o Subtitle Legendas Font Style Estilo de letra Restore Defaults Restaurar Predefinições Open file Abrir ficheiro Open next Abrir seguinte Open previous Abrir anterior Mini mode Modo mĂ­ni Mute Silenciar Next frame Frame seguinte Previous frame Frame anterior Volume down Diminuir volume Volume up Aumentar volume Speed up Aumentar velocidade Speed down Diminuir velocidade Fullscreen EcrĂ£ completo Pause/Play Pausar/Reproduzir Playlist Lista de ReproduĂ§Ă£o Reset speed Repor velocidade Rewind Recuar Forward Avançar Burst screenshot Captura de ecrĂ£ de rajada Film screenshot Captura de ecrĂ£ do filme 0.5s backward Recuar 0.5s 0.5s forward Avançar 0.5s Font Tipo de Letra Font Size Tamanho da Letra UrlDialog Cancel Cancelar Confirm Confirmar Please enter the URL: Por favor, insira o URL: dmr::ActionFactory Settings Definições Fullscreen EcrĂ£ completo Always on Top Sempre no Topo Film info InformaĂ§Ă£o do Filme Open file Abrir ficheiro Open folder Abrir pasta Light theme Tema claro Open URL Abrir URL Open CD/DVD Abrir CD/DVD Mini Mode Modo MĂ­ni Play Mode Modo de ReproduĂ§Ă£o Order Play ReproduĂ§Ă£o Ordenada Shuffle Play ReproduĂ§Ă£o AleatĂ³ria Single Play ReproduĂ§Ă£o Ănica Single Loop Ciclo Ănico List Loop Ciclo de lista Frame Imagem Default PredefiniĂ§Ă£o Clockwise Sentido horĂ¡rio Counterclockwise Sentido anti-horĂ¡rio Next frame Frame seguinte Previous frame Frame anterior Sound Som Channel Canal Stereo EstĂ©reo Left channel Canal esquerdo Right channel Canal direito Track Faixa Subtitle Legenda Load Carregar Online Search Pesquisa On-line Select Selecionar Hide Ocultar Encodings Codificadores Screenshot Capturar EcrĂ£ Film Screenshot Captura de ecrĂ£ do filme Burst Shooting Captura de ecrĂ£ em rajada Playlist Lista de ReproduĂ§Ă£o Film Info InformaĂ§Ă£o do Filme Clear playlist Limpar lista de reproduĂ§Ă£o Display in file manager Exibir no gestor de ficheiros dmr::BurstScreenshotsDialog Duration: %1 DuraĂ§Ă£o: %1 Resolution: %1 ResoluĂ§Ă£o: %1 Size: %1 Tamanho: %1 Save Guardar dmr::MainWindow Load successfully Carregado com sucesso Load failed Carregamento falhou No device found Nenhum dispositivo encontrado Parse Failed AnĂ¡lise falhou Open folder Abrir pasta Open file Abrir ficheiro All videos (%1) Todos os vĂ­deos (%1) Muted Silenciada Volume: %1% Volume: %1% Subtitle %1: %2s Legendas %1: %2s delayed Atrasado advanced Avançado Speed: %1x Velocidade: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) Legenda (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Ver Movie Screenshot Captura de ecrĂ£ do filme Saved to Guardado em The screenshot is saved A captura de ecrĂ£ foi guardada. Failed to save the screenshot Falha ao guardar a imagem Invalid file: %1 Ficheiro invĂ¡lido: %1 dmr::MovieInfo %1G %1G %1M %1M %1K %1K %1 %1 dmr::MovieInfoDialog File Type: Tipo de ficheiro: Resolution: ResoluĂ§Ă£o: File Size: Tamanho do ficheiro: Duration: DuraĂ§Ă£o: File Path: Caminho do ficheiro: dmr::MpvProxy [internal] [interno] dmr::PlayItemWidget File does not exist O ficheiro nĂ£o existe dmr::Settings %1/DMovie%2.jpg %1/DMovie%2.jpg %1/DMovie%2(%3).jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Reproduzir Previous Anterior Next Seguinte Subtitles Legendas Playlist Lista de ReproduĂ§Ă£o Fullscreen EcrĂ£ completo Play/Pause Reproduzir/Pausar Exit fullscreen Sair de ecrĂ£ completo Pause Pausar deepin-movie-reborn-5.0.0/src/translations/deepin-movie_pt_BR.ts000066400000000000000000000675101351125414100247170ustar00rootroot00000000000000 QObject Deepin Movie Deepin Movie Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Deepin Movie Ă© um reprodutor de vĂ­deo bem desenhado cheio de recursos com um design simples sem bordas. Ele suporta a reproduĂ§Ă£o de mĂ­dia local e via streaming para vĂ¡rios formatos de vĂ­deo. Invalid folder Pasta invĂ¡lida Open folder Abrir pasta You don't have permission to operate this folder VocĂª nĂ£o tem permissĂ£o para manipular esta pasta Auto add similar files to play Auto adicionar arquivos semelhantes para a reproduĂ§Ă£o Clear playlist when exit Limpar a lista de reproduĂ§Ă£o quando sair Show video preview on mouseover Mostrar visualizaĂ§Ă£o de vĂ­deo no mouseover Open a new player for each file played Abrir um novo player para cada arquivo que for reproduzido Pause when minimized Pausar quando minimizado Remember playback position Lembrar da posiĂ§Ă£o de reproduĂ§Ă£o Path Caminho Basic BĂ¡sico Play Play Screenshot Captura de tela Shortcuts Atalhos File Arquivo Frame/Sound Quadro/Som Playback ReproduĂ§Ă£o Subtitle Legendas Font Style Estilo da fonte Restore Defaults Restaurar padrões Open file Abrir arquivo Open next Abrir o prĂ³ximo Open previous Abrir anterior Mini mode Modo mini Mute Mudo Next frame PrĂ³ximo quadro Previous frame Quadro anterior Volume down Diminuir volume Volume up Aumentar volume Speed up Aumentar velocidade Speed down Diminuir velocidade Fullscreen Tela cheia Pause/Play Play/Pause Playlist Playlist Reset speed Reconfigurar velocidade Rewind Voltar Forward Avançar Burst screenshot Captura de tela de explosĂ£o Film screenshot Captura de tela do filme 0.5s backward 0.5s para trĂ¡s 0.5s forward 0.5s para frente Font Fonte Font Size Tamanho da fonte UrlDialog Cancel Cancelar Confirm Confirmar Please enter the URL: Digite a URL: dmr::ActionFactory Settings Configurações Fullscreen Tela cheia Always on Top Sempre em cima Film info Informações do filme Open file Abrir arquivo Open folder Abrir pasta Light theme Tema claro Open URL Abrir URL Open CD/DVD Abrir CD/DVD Mini Mode Modo Mini Play Mode Modo de reproduĂ§Ă£o Order Play Ordenar reproduĂ§Ă£o Shuffle Play ReproduĂ§Ă£o aleatĂ³ria Single Play Repetir reproduĂ§Ă£o Single Loop Repetir uma vez List Loop Repetir lista Frame Quadro Default PadrĂ£o Clockwise Sentido horĂ¡rio Counterclockwise Sentido anti-horĂ¡rio Next frame PrĂ³ximo quadro Previous frame Quadro anterior Sound Som Channel Canal Stereo EstĂ©reo Left channel Canal esquerdo Right channel Canal direito Track Trilha Subtitle Legenda Load Carregar Online Search Pesquisa online Select Selecionar Hide Ocultar Encodings Codificações Screenshot Captura de tela Film Screenshot Captura de tela do filme Burst Shooting ExplosĂ£o de tiros Playlist Playlist Film Info Informações do filme Clear playlist Limpar lista de reproduĂ§Ă£o Display in file manager Exibir no gerenciador de arquivos dmr::BurstScreenshotsDialog Duration: %1 DuraĂ§Ă£o: %1 Resolution: %1 ResoluĂ§Ă£o: %1 Size: %1 Tamanho: %1 Save Salvar dmr::MainWindow Load successfully Carregado com sucesso Load failed Falha no carregamento No device found Nenhum dispositivo encontrado Parse Failed A anĂ¡lise falhou Open folder Abrir pasta Open file Abrir arquivo All videos (%1) Todos os vĂ­deos (%1) Muted Mudo Volume: %1% Volume: %1% Subtitle %1: %2s Legenda %1: %2s delayed atrasado advanced avançado Speed: %1x Velocidade: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) Legenda (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Visualizar Movie Screenshot Imagem do filme Saved to Salvo para The screenshot is saved A captura de tela foi salva  Failed to save the screenshot Falha ao salvar a cĂ³pia da tela Invalid file: %1 Arquivo invĂ¡lido: %1 dmr::MovieInfo %1G %1G %1M %1M %1K %1K %1 %1 dmr::MovieInfoDialog File Type: Tipo do arquivo Resolution: ResoluĂ§Ă£o: File Size: Tamanho do arquivo Duration: DuraĂ§Ă£o: File Path: Caminho do arquivo dmr::MpvProxy [internal] [interno] dmr::PlayItemWidget File does not exist Arquivo nĂ£o existe dmr::Settings %1/DMovie%2.jpg %1/DMovie%2.jpg %1/DMovie%2(%3).jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Play Previous Anterior Next PrĂ³xima Subtitles Legendas Playlist Playlist Fullscreen Tela cheia Play/Pause Play/Pause Exit fullscreen Sair da tela cheia Pause Pause deepin-movie-reborn-5.0.0/src/translations/deepin-movie_ro.ts000066400000000000000000000675131351125414100243340ustar00rootroot00000000000000 QObject Deepin Movie Player-ul video Deepin Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Player-ul video Deepin este un player video bine proiectat, cu o suită completă de opÈ›iuni È™i un design simplu fără margini. Suportă redarea fiÅŸierelor media de diferite formate video, atĂ¢t locale cĂ¢t ÅŸi din reÈ›ea. Invalid folder Dosar invalid Open folder You don't have permission to operate this folder Nu aveÈ›i permisiunea necesară pentru a efectua operaÈ›iuni Ă®n acest dosar. Auto add similar files to play Adaugă automat fiÈ™iere similare Ă®n lista de redare Clear playlist when exit Golire lista de redare la ieÈ™ire Show video preview on mouseover Arată o previzualizare a video-ului cĂ¢nd se trece cu mouse-ul peste Open a new player for each file played Deschide o fereastră nouă pentru fiecare fiÈ™ier redat Pause when minimized Pauză la minimizare Remember playback position Memorare poziÈ›ie redare Path Cale fiÈ™ier Basic Simplu Play Redare Screenshot Captură ecran Shortcuts Scurtături File FiÅŸier Frame/Sound Cadru/Sunet Playback Redare Subtitle Subtitrări Font Style Stil font Restore Defaults Restaurare setări implicite Open file Deschide fiÈ™ierul Open next Deschide următor Open previous Deschide precedent Mini mode Minimalizare fereastră Mute Mute Next frame Previous frame Volume down Scade volumul Volume up CreÈ™te volumul Speed up MăreÈ™te viteza de redare Speed down Scade viteza de redare Fullscreen Redare ecran complet Pause/Play Pauză/Redare Playlist Lista de redare Reset speed Resetează viteza de redare Rewind Ănapoi Forward Ănainte Burst screenshot Captură ecran rafală Film screenshot Captură ecran video 0.5s backward 0.5s Ă®napoi 0.5s forward 0.5s Ă®nainte Font Fontul Font Size Mărime font UrlDialog Cancel Anulare Confirm Confirmare Please enter the URL: IntroduceÈ›i adresă URL dmr::ActionFactory Settings Setări Fullscreen Redare ecran complet Always on Top Mereu deasupra programelor Film info InformaÈ›ie video Open file Deschide fiÈ™ierul Open folder Light theme Open URL Deschide URL Open CD/DVD Deschide CD/DVD Mini Mode Mod Mini Play Mode Mod redare Order Play Redare Ă®n ordine Shuffle Play Redare aleatorie Single Play Redă un singur fisier Single Loop Redă video-ul fără pauză List Loop Redă lista fără pauză Frame Cadru Default Implicit Clockwise Rotire la dreapta Counterclockwise Rotire la stĂ¢nga Next frame Previous frame Sound Sunet Channel Canal Stereo Stereo Left channel Canal audio stanga Right channel Canal audio dreapta Track Piesa Subtitle Subtitrări Load Ăncarcare Online Search Căutare online Select Selectare Hide Ascundere Encodings Compresie Screenshot Captură ecran Film Screenshot Captură ecran video Burst Shooting Captură ecran rafală Playlist Lista de redare Film Info InformaÈ›ie video Clear playlist Golire listă de redare Display in file manager Deschide Ă®n managerul de fiÈ™iere dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save Salvare dmr::MainWindow Load successfully Ăncărcare efectuată cu succes Load failed Ăncărcare eÈ™uată No device found Nu s-a găsit un dispozitiv Parse Failed Analizarea a eÈ™uat Open folder Open file Deschide fiÈ™ierul All videos (%1) Muted Mute Volume: %1% Volum: %1% Subtitle %1: %2s Subtitrare %1 %2s delayed Ă®ntĂ¢rziere advanced avansare Speed: %1x Viteză: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Aspect Movie Screenshot Captură de ecran film Saved to Salvare la The screenshot is saved Salvare captura de ecran efectuată Failed to save the screenshot Invalid file: %1 FiÈ™ier invalid: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Tip fiÈ™ier: Resolution: RezoluÈ›ie: File Size: Mărime fiÈ™ier: Duration: Durată: File Path: Cale fiÈ™ier: dmr::MpvProxy [internal] [intern] dmr::PlayItemWidget File does not exist FiÈ™ierul nu există dmr::Settings %1/DMovie%2.jpg %1/DMovie%2.jpg %1/DMovie%2(%3).jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Redare Previous Precedent Next Următorul Subtitles Subtitrări Playlist Lista de redare Fullscreen Redare ecran complet Play/Pause Redare/Pauză Exit fullscreen IeÈ™ire redare ecran complet Pause Pauză deepin-movie-reborn-5.0.0/src/translations/deepin-movie_ru.ts000066400000000000000000000734621351125414100243420ustar00rootroot00000000000000 QObject Deepin Movie Đ’Đ¸Đ´ĐµĐ¾Đ¿Ñ€Đ¾Đ¸Đ³Ñ€Ñ‹Đ²Đ°Ñ‚ĐµĐ»ÑŒ Deepin Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Đ’Đ¸Đ´ĐµĐ¾Đ¿Ñ€Đ¾Đ¸Đ³Ñ€Ñ‹Đ²Đ°Ñ‚ĐµĐ»ÑŒ Deepin - ÑÑ‚Đ¾ Đ¿Đ¾Đ»Đ½Đ¾Ñ„ÑƒĐ½ĐºÑ†Đ¸Đ¾Đ½Đ°Đ»ÑŒĐ½Ñ‹Đ¹ и Ñ…Đ¾Ñ€Đ¾ÑˆĐ¾ Đ¿Ñ€Đ¾Đ´ÑƒĐ¼Đ°Đ½Đ½Ñ‹Đ¹ Đ²Đ¸Đ´ĐµĐ¾-Đ¿Đ»ĐµĐµÑ€ Ñ Đ½ĐµĐ²ĐµÑ€Đ¾ÑÑ‚Đ½Đ¾ Đ¿Ñ€Đ¾ÑÑ‚Ñ‹Đ¼ Đ´Đ¸Đ·Đ°Đ¹Đ½Đ¾Đ¼. ĐĐ½ Đ¿Đ¾Đ´Đ´ĐµÑ€Đ¶Đ¸Đ²Đ°ĐµÑ‚ Đ»Đ¾ĐºĐ°Đ»ÑŒĐ½Đ¾Đµ и Đ¿Đ¾Ñ‚Đ¾ĐºĐ¾Đ²Đ¾Đµ Đ²Đ¾ÑĐ¿Ñ€Đ¾Đ¸Đ·Đ²ĐµĐ´ĐµĐ½Đ¸Đµ Đ¼Đ½Đ¾Đ³Đ¸Ñ… Đ²Đ¸Đ´ĐµĐ¾ Ñ„Đ¾Ñ€Đ¼Đ°Ñ‚Đ¾Đ². Invalid folder ĐĐµĐ²ĐµÑ€Đ½Đ°Ñ Đ¿Đ°Đ¿ĐºĐ° Open folder ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ Đ¿Đ°Đ¿ĐºÑƒ You don't have permission to operate this folder Đ£ Đ²Đ°Ñ Đ½ĐµÑ‚ Ñ€Đ°Đ·Ñ€ĐµÑˆĐµĐ½Đ¸Ñ Đ½Đ° иÑĐ¿Đ¾Đ»ÑŒĐ·Đ¾Đ²Đ°Đ½Đ¸Đµ ÑÑ‚Đ¾Đ¹ Đ¿Đ°Đ¿ĐºĐ¸ Auto add similar files to play ĐĐ²Ñ‚Đ¾Đ¼Đ°Ñ‚Đ¸Ñ‡ĐµÑĐºĐ¸ Đ´Đ¾Đ±Đ°Đ²Đ¸Ñ‚ÑŒ Đ¿Đ¾Ñ…Đ¾Đ¶Đ¸Đµ Ñ„Đ°Đ¹Đ»Ñ‹ Đ´Đ»Ñ Đ²Đ¾ÑĐ¿Ñ€Đ¾Đ¸Đ·Đ²ĐµĐ´ĐµĐ½Đ¸Ñ Clear playlist when exit ĐÑ‡Đ¸ÑÑ‚Đ¸Ñ‚ÑŒ Đ¿Đ»ĐµĐ¹Đ»Đ¸ÑÑ‚ Đ¿Ñ€Đ¸ Đ²Ñ‹Ñ…Đ¾Đ´Đµ Show video preview on mouseover ĐŸĐ¾ĐºĐ°Đ·Đ°Ñ‚ÑŒ Đ¿Ñ€ĐµĐ´Đ²Đ°Ñ€Đ¸Ñ‚ĐµĐ»ÑŒĐ½Ñ‹Đ¹ Đ¿Ñ€Đ¾ÑĐ¼Đ¾Ñ‚Ñ€ Đ²Đ¸Đ´ĐµĐ¾ Ñ Đ¿Đ¾Đ¼Đ¾Ñ‰ÑŒÑ Đ¼Ñ‹ÑˆĐ¸ Open a new player for each file played ĐÑ‚ĐºÑ€Ñ‹Đ²Đ°Ñ‚ÑŒ Đ½Đ¾Đ²Ñ‹Đ¹ Đ¿Đ»ĐµĐµÑ€ Đ´Đ»Ñ ĐºĐ°Đ¶Đ´Đ¾Đ³Đ¾ Đ²Đ¾ÑĐ¿Ñ€Đ¾Đ¸Đ·Đ²Đ¾Đ´Đ¸Đ¼Đ¾Đ³Đ¾ Ñ„Đ°Đ¹Đ»Đ° Pause when minimized ĐŸĐ°ÑƒĐ·Đ° Đ¿Ñ€Đ¸ ÑĐ²Đ¾Ñ€Đ°Ñ‡Đ¸Đ²Đ°Đ½Đ¸Đ¸ Remember playback position Đ—Đ°Đ¿Đ¾Đ¼Đ½Đ¸Ñ‚ÑŒ Đ²Đ¾ÑĐ¿Ñ€Đ¾Đ¸Đ·Đ²Đ¾Đ´Đ¸Đ¼ÑƒÑ Đ¿Đ¾Đ·Đ¸Ñ†Đ¸Ñ Path ĐŸÑƒÑ‚ÑŒ Basic ĐÑĐ½Đ¾Đ²Đ½Đ¾Đ¹ Play Đ’Đ¾ÑĐ¿Ñ€Đ¾Đ¸Đ·Đ²ĐµĐ´ĐµĐ½Đ¸Đµ Screenshot Đ¡ĐºÑ€Đ¸Đ½ÑˆĐ¾Ñ‚ Shortcuts Đ¡Đ¾Ñ‡ĐµÑ‚Đ°Đ½Đ¸Đµ ĐºĐ»Đ°Đ²Đ¸Ñˆ File Đ¤Đ°Đ¹Đ» Frame/Sound ĐĐ°Đ´Ñ€/Đ—Đ²ÑƒĐº Playback Đ’Đ¾ÑĐ¿Ñ€Đ¾Đ¸Đ·Đ²ĐµĐ´ĐµĐ½Đ¸Đµ Subtitle Đ¡ÑƒĐ±Ñ‚Đ¸Ñ‚Ñ€Ñ‹ Font Style Đ¡Ñ‚Đ¸Đ»ÑŒ Đ¨Ñ€Đ¸Ñ„Ñ‚Đ° Restore Defaults Đ’Đ¾ÑÑÑ‚Đ°Đ½Đ¾Đ²Đ¸Ñ‚ÑŒ Đ—Đ½Đ°Ñ‡ĐµĐ½Đ¸Ñ Đ¿Đ¾ ÑƒĐ¼Đ¾Đ»Ñ‡Đ°Đ½Đ¸Ñ Open file ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ Ñ„Đ°Đ¹Đ» Open next ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ ÑĐ»ĐµĐ´ÑƒÑÑ‰Đ¸Đ¹ Open previous ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ Đ¿Ñ€ĐµĐ´Ñ‹Đ´ÑƒÑ‰Đ¸Đ¹ Mini mode ĐĐ¾Đ¼Đ¿Đ°ĐºÑ‚Đ½Ñ‹Đ¹ Đ²Đ¸Đ´ Mute ĐŸÑ€Đ¸Đ³Đ»ÑƒÑˆĐ¸Ñ‚ÑŒ Next frame Đ¡Đ»ĐµĐ´ÑƒÑÑ‰Đ¸Đ¹ ĐºĐ°Đ´Ñ€ Previous frame ĐŸÑ€ĐµĐ´Ñ‹Đ´ÑƒÑ‰Đ¸Đ¹ ĐºĐ°Đ´Ñ€ Volume down Đ¢Đ¸ÑˆĐµ Volume up Đ“Ñ€Đ¾Đ¼Ñ‡Đµ Speed up Đ£ÑĐºĐ¾Ñ€Đ¸Ñ‚ÑŒ Speed down Đ—Đ°Đ¼ĐµĐ´Đ»Đ¸Ñ‚ÑŒ Fullscreen ĐŸĐ¾Đ»Đ½Đ¾ÑĐºÑ€Đ°Đ½Đ½Ñ‹Đ¹ Ñ€ĐµĐ¶Đ¸Đ¼ Pause/Play ĐŸĐ°ÑƒĐ·Đ°/Đ’Đ¾ÑĐ¿Ñ€Đ¾Đ¸Đ·Đ²ĐµĐ´ĐµĐ½Đ¸Đµ Playlist Đ¡Đ¿Đ¸ÑĐ¾Đº Đ²Đ¾ÑĐ¿Ñ€Đ¾Đ¸Đ·Đ²ĐµĐ´ĐµĐ½Đ¸Ñ Reset speed Đ¡Đ±Ñ€Đ¾ÑĐ¸Ñ‚ÑŒ ÑĐºĐ¾Ñ€Đ¾Ñть Rewind ĐŸĐµÑ€ĐµĐ¼Đ¾Ñ‚ĐºĐ° Đ½Đ°Đ·Đ°Đ´ Forward ĐŸĐµÑ€ĐµĐ¼Đ¾Ñ‚ĐºĐ° Đ²Đ¿ĐµÑ€ĐµĐ´ Burst screenshot Đ¡ĐµÑ€Đ¸Ñ ÑĐºÑ€Đ¸Đ½ÑˆĐ¾Ñ‚Đ¾Đ² Film screenshot Đ¡ĐºÑ€Đ¸Đ½ÑˆĐ¾Ñ‚ Ñ„Đ¸Đ»ÑŒĐ¼Đ° 0.5s backward ĐŸĐµÑ€ĐµĐ¼Đ¾Ñ‚ĐºĐ° Đ½Đ°Đ·Đ°Đ´ 0.5Ñ 0.5s forward ĐŸĐµÑ€ĐµĐ¼Đ¾Ñ‚ĐºĐ° Đ²Đ¿ĐµÑ€ĐµĐ´ 0.5Ñ Font Đ¨Ñ€Đ¸Ñ„Ñ‚ Font Size Đ Đ°Đ·Đ¼ĐµÑ€ Đ¨Ñ€Đ¸Ñ„Ñ‚Đ° UrlDialog Cancel ĐÑ‚Đ¼ĐµĐ½Đ° Confirm ĐŸĐ¾Đ´Ñ‚Đ²ĐµÑ€Đ´Đ¸Ñ‚ÑŒ Please enter the URL: ĐŸĐ¾Đ¶Đ°Đ»ÑƒĐ¹ÑÑ‚Đ°, Đ²Đ²ĐµĐ´Đ¸Ñ‚Đµ Đ°Đ´Ñ€ĐµÑ Đ² Đ¸Đ½Ñ‚ĐµÑ€Đ½ĐµÑ‚Đµ: dmr::ActionFactory Settings ĐаÑÑ‚Ñ€Đ¾Đ¹ĐºĐ¸ Fullscreen ĐŸĐ¾Đ»Đ½Đ¾ÑĐºÑ€Đ°Đ½Đ½Ñ‹Đ¹ Ñ€ĐµĐ¶Đ¸Đ¼ Always on Top Đ’ÑĐµĐ³Đ´Đ° ĐŸĐ¾Đ²ĐµÑ€Ñ… ĐĐºĐ¾Đ½ Film info Đ˜Đ½Ñ„Đ¾Ñ€Đ¼Đ°Ñ†Đ¸Ñ Đ¾ Ñ„Đ¸Đ»ÑŒĐ¼Đµ Open file ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ Ñ„Đ°Đ¹Đ» Open folder ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ Đ¿Đ°Đ¿ĐºÑƒ Light theme Đ¡Đ²ĐµÑ‚Đ»Đ°Ñ Ñ‚ĐµĐ¼Đ° Open URL ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ URL Open CD/DVD ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ CD/DVD Mini Mode ĐĐ¾Đ¼Đ¿Đ°ĐºÑ‚Đ½Ñ‹Đ¹ Вид Play Mode Đ ĐµĐ¶Đ¸Đ¼ Đ’Đ¾ÑĐ¿Ñ€Đ¾Đ¸Đ·Đ²ĐµĐ´ĐµĐ½Đ¸Ñ Order Play ĐŸĐ¾Ñ€ÑĐ´Đ¾Đº ĐŸÑ€Đ¾Đ¸Đ³Ñ€Ñ‹Đ²Đ°Đ½Đ¸Ñ Shuffle Play ĐŸĐµÑ€ĐµĐ¼ĐµÑˆĐ°Ñ‚ÑŒ Single Play ĐĐ´Đ¸Đ½Đ¾Ñ‡Đ½Ñ‹Đ¹ Single Loop ĐĐ´Đ¸Đ½Đ¾Ñ‡Đ½Ñ‹Đ¹ Đ¦Đ¸ĐºĐ» List Loop ĐĐµĐ¿Ñ€ĐµÑ€Ñ‹Đ²Đ½Đ¾ Frame ĐĐ°Đ´Ñ€ Default ĐŸĐ¾ ÑƒĐ¼Đ¾Đ»Ñ‡Đ°Đ½Đ¸Ñ Clockwise ĐŸĐ¾ Ñ‡Đ°ÑĐ¾Đ²Đ¾Đ¹ ÑÑ‚Ñ€ĐµĐ»ĐºĐµ Counterclockwise ĐŸÑ€Đ¾Ñ‚Đ¸Đ² Ñ‡Đ°ÑĐ¾Đ²Đ¾Đ¹ ÑÑ‚Ñ€ĐµĐ»ĐºĐ¸ Next frame Đ¡Đ»ĐµĐ´ÑƒÑÑ‰Đ¸Đ¹ ĐºĐ°Đ´Ñ€ Previous frame ĐŸÑ€ĐµĐ´Ñ‹Đ´ÑƒÑ‰Đ¸Đ¹ ĐºĐ°Đ´Ñ€ Sound Đ—Đ²ÑƒĐº Channel ĐĐ°Đ½Đ°Đ» Stereo Đ¡Ñ‚ĐµÑ€ĐµĐ¾ Left channel Đ›ĐµĐ²Ñ‹Đ¹ ĐºĐ°Đ½Đ°Đ» Right channel ĐŸÑ€Đ°Đ²Ñ‹Đ¹ ĐºĐ°Đ½Đ°Đ» Track Đ”Đ¾Ñ€Đ¾Đ¶ĐºĐ° Subtitle Đ¡ÑƒĐ±Ñ‚Đ¸Ñ‚Ñ€Ñ‹ Load Đ—Đ°Đ³Ñ€ÑƒĐ·ĐºĐ° Online Search ĐŸĐ¾Đ¸ÑĐº ĐĐ½Đ»Đ°Đ¹Đ½ Select Đ’Ñ‹Đ±Ñ€Đ°Ñ‚ÑŒ Hide Đ¡ĐºÑ€Ñ‹Ñ‚ÑŒ Encodings ĐĐ¾Đ´Đ¸Ñ€Đ¾Đ²ĐºĐ° Screenshot Đ¡ĐºÑ€Đ¸Đ½ÑˆĐ¾Ñ‚ Film Screenshot Đ¡ĐºÑ€Đ¸Đ½ÑˆĐ¾Ñ‚ Đ¤Đ¸Đ»ÑŒĐ¼Đ° Burst Shooting Đ¡ĐµÑ€Đ¸Ñ Đ¡Đ½Đ¸Đ¼ĐºĐ¾Đ² Playlist Đ¡Đ¿Đ¸ÑĐ¾Đº Đ²Đ¾ÑĐ¿Ñ€Đ¾Đ¸Đ·Đ²ĐµĐ´ĐµĐ½Đ¸Ñ Film Info Đ˜Đ½Ñ„Đ¾Ñ€Đ¼Đ°Ñ†Đ¸Ñ Đ¾ Đ¤Đ¸Đ»ÑŒĐ¼Đµ Clear playlist ĐÑ‡Đ¸ÑÑ‚Đ¸Ñ‚ÑŒ ÑĐ¿Đ¸ÑĐ¾Đº Đ²Đ¾ÑĐ¿Ñ€Đ¾Đ¸Đ·Đ²ĐµĐ´ĐµĐ½Đ¸Ñ Display in file manager ĐÑ‚Đ¾Đ±Ñ€Đ°Đ·Đ¸Ñ‚ÑŒ Đ² Đ¼ĐµĐ½ĐµĐ´Đ¶ĐµÑ€Đµ Ñ„Đ°Đ¹Đ»Đ¾Đ² dmr::BurstScreenshotsDialog Duration: %1 ĐŸÑ€Đ¾Đ´Đ¾Đ»Đ¶Đ¸Ñ‚ĐµĐ»ÑŒĐ½Đ¾Ñть: %1 Resolution: %1 Đ Đ°Đ·Ñ€ĐµÑˆĐµĐ½Đ¸Đµ: %1 Size: %1 Đ Đ°Đ·Đ¼ĐµÑ€: %1 Save Đ¡Đ¾Ñ…Ñ€Đ°Đ½Đ¸Ñ‚ÑŒ dmr::MainWindow Load successfully Đ—Đ°Đ³Ñ€ÑƒĐ·ĐºĐ° уÑĐ¿ĐµÑˆĐ½Đ¾ Đ·Đ°Đ²ĐµÑ€ÑˆĐµĐ½Đ° Load failed ĐÑˆĐ¸Đ±ĐºĐ° Đ·Đ°Đ³Ñ€ÑƒĐ·ĐºĐ¸ No device found Đ£ÑÑ‚Ñ€Đ¾Đ¹ÑÑ‚Đ²Đ¾ Đ½Đµ Đ½Đ°Đ¹Đ´ĐµĐ½Đ¾ Parse Failed ĐÑˆĐ¸Đ±ĐºĐ° ĐĐ½Đ°Đ»Đ¸Đ·Đ° Open folder ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ Đ¿Đ°Đ¿ĐºÑƒ Open file ĐÑ‚ĐºÑ€Ñ‹Ñ‚ÑŒ Ñ„Đ°Đ¹Đ» All videos (%1) Đ’Ñе Đ²Đ¸Đ´ĐµĐ¾ (%1) Muted Đ—Đ°Đ³Đ»ÑƒÑˆĐµĐ½Đ½Ñ‹Đ¹ Volume: %1% Đ“Ñ€Đ¾Đ¼ĐºĐ¾Ñть: %1% Subtitle %1: %2s Đ¡ÑƒĐ±Ñ‚Đ¸Ñ‚Ñ€Ñ‹: %1: %2s delayed Đ·Đ°Đ´ĐµÑ€Đ¶ĐºĐ° advanced Ñ€Đ°ÑÑˆĐ¸Ñ€ĐµĐ½Đ½Ñ‹Đ¹ Speed: %1x Đ¡ĐºĐ¾Ñ€Đ¾Ñть: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) РаÑÑˆĐ¸Ñ€ĐµĐ½Đ¸Đµ (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View ĐŸÑ€Đ¾ÑĐ¼Đ¾Ñ‚Ñ€ Movie Screenshot Đ¡ĐºÑ€Đ¸Đ½ÑˆĐ¾Ñ‚ Đ¤Đ¸Đ»ÑŒĐ¼Đ° Saved to Đ¡Đ¾Ñ…Ñ€Đ°Đ½Đ¸Ñ‚ÑŒ Đ² The screenshot is saved Đ¡Đ½Đ¸Đ¼Đ¾Đº ÑĐºÑ€Đ°Đ½Đ° ÑĐ¾Ñ…Ñ€Đ°Đ½ĐµĐ½ Failed to save the screenshot Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ ÑĐ¾Ñ…Ñ€Đ°Đ½Đ¸Ñ‚ÑŒ ÑĐ½Đ¸Đ¼Đ¾Đº ÑĐºÑ€Đ°Đ½Đ° Invalid file: %1 ĐĐµĐ²ĐµÑ€Đ½Ñ‹Đ¹ Ñ„Đ°Đ¹Đ»: %1 dmr::MovieInfo %1G %1G %1M %1M %1K %1K %1 %1 dmr::MovieInfoDialog File Type: Đ¢Đ¸Đ¿ Đ¤Đ°Đ¹Đ»Đ°: Resolution: Đ Đ°Đ·Ñ€ĐµÑˆĐµĐ½Đ¸Đµ: File Size: Đ Đ°Đ·Đ¼ĐµÑ€ Đ¤Đ°Đ¹Đ»Đ°: Duration: ĐŸÑ€Đ¾Đ´Đ¾Đ»Đ¶Đ¸Ñ‚ĐµĐ»ÑŒĐ½Đ¾Ñть: File Path: ĐŸÑƒÑ‚ÑŒ Đº Đ¤Đ°Đ¹Đ»Ñƒ: dmr::MpvProxy [internal] [Đ²Đ½ÑƒÑ‚Ñ€ĐµĐ½Đ½Đ¸Đ¹] dmr::PlayItemWidget File does not exist Đ¤Đ°Đ¹Đ» Đ¾Ñ‚ÑутÑÑ‚Đ²ÑƒĐµÑ‚ dmr::Settings %1/DMovie%2.jpg %1/DMovie%2.jpg %1/DMovie%2(%3).jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Đ’Đ¾ÑĐ¿Ñ€Đ¾Đ¸Đ·Đ²ĐµĐ´ĐµĐ½Đ¸Đµ Previous ĐŸÑ€ĐµĐ´Ñ‹Đ´ÑƒÑ‰Đ¸Đ¹ Next Đ¡Đ»ĐµĐ´ÑƒÑÑ‰Đ¸Đ¹ Subtitles Đ¡ÑƒĐ±Ñ‚Đ¸Ñ‚Ñ€Ñ‹ Playlist Đ¡Đ¿Đ¸ÑĐ¾Đº Đ²Đ¾ÑĐ¿Ñ€Đ¾Đ¸Đ·Đ²ĐµĐ´ĐµĐ½Đ¸Ñ Fullscreen ĐŸĐ¾Đ»Đ½Đ¾ÑĐºÑ€Đ°Đ½Đ½Ñ‹Đ¹ Ñ€ĐµĐ¶Đ¸Đ¼ Play/Pause Đ’Đ¾ÑĐ¿Ñ€Đ¾Đ¸Đ·Đ²ĐµĐ´ĐµĐ½Đ¸Đµ / ĐŸĐ°ÑƒĐ·Đ° Exit fullscreen Đ’Ñ‹Đ¹Ñ‚Đ¸ из Đ¿Đ¾Đ»Đ½Đ¾ÑĐºÑ€Đ°Đ½Đ½Đ¾Đ³Đ¾ Ñ€ĐµĐ¶Đ¸Đ¼Đ° Pause ĐŸĐ°ÑƒĐ·Đ° deepin-movie-reborn-5.0.0/src/translations/deepin-movie_sk.ts000066400000000000000000000700111351125414100243140ustar00rootroot00000000000000 QObject Deepin Movie Deepin Filmy Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Deepin Filmy je dobre navrhnutĂ½ prepracovanĂ½ video prehrĂ¡vaÄ s jednoduchĂ½m bezrĂ¡movĂ½m dizajnom. Podporuje lokĂ¡lne a streamovanĂ© prehrĂ¡vanie mĂ©diĂ­ v rĂ´znych video formĂ¡toch. Invalid folder NeplatnĂ½ prieÄinok Open folder OtvoriÅ¥ prieÄinok You don't have permission to operate this folder NemĂ¡te povolenie na pouÅ¾Ă­vanie tohto prieÄinka Auto add similar files to play AutomatickĂ© pridanie podobnĂ½ch sĂºborov na prehrĂ¡vanie Clear playlist when exit Vymazanie zoznamu skladieb pri ukonÄenĂ­ Show video preview on mouseover ZobraziÅ¥ nĂ¡hľad videa po prechode myÅ¡ou Open a new player for each file played OtvoriÅ¥ novĂ½ prehrĂ¡vaÄ pre každĂ½ prehrĂ¡vanĂ½ sĂºbor Pause when minimized PozastaviÅ¥ pri minimalizĂ¡cii Remember playback position ZapamätaÅ¥ pozĂ­ciu prehrĂ¡vania Path Cesta Basic ZĂ¡kladnĂ© Play SpustiÅ¥ Screenshot SnĂ­mok obrazovky Shortcuts Odkazy File SĂºbor Frame/Sound RĂ¡mec/Zvuk Playback PrehrĂ¡vanie Subtitle Titulky Font Style Å tĂ½l pĂ­sma Restore Defaults ObnoviÅ¥ predvolenĂ© nastavenia Open file OtvoriÅ¥ sĂºbor Open next OtvoriÅ¥ ÄalÅ¡ie Open previous OtvoriÅ¥ predoÅ¡lĂ© Mini mode Mini režim Mute StlmiÅ¥ Next frame ÄalÅ¡Ă­ snĂ­mok Previous frame PredchĂ¡dzajĂºci snĂ­mok Volume down TichÅ¡ie Volume up HlasnejÅ¡ie Speed up ZvĂ½Å¡iÅ¥ rĂ½chlosÅ¥ Speed down ZnĂ­Å¾iÅ¥ rĂ½chlosÅ¥ Fullscreen CelĂ¡ obrazovka Pause/Play PozastaviÅ¥/SpustiÅ¥ Playlist Zoznam skladieb Reset speed ResetovaÅ¥ rĂ½chlosÅ¥ Rewind Dozadu Forward Dopredu Burst screenshot Sekvencia snĂ­mkov obrazovky Film screenshot SnĂ­mka filmu 0.5s backward 0,5 s dozadu 0.5s forward 0,5 s dopredu Font PĂ­smo Font Size VeľkosÅ¥ pĂ­sma UrlDialog Cancel ZruÅ¡iÅ¥ Confirm PotvrdiÅ¥ Please enter the URL: ProsĂ­m zadajte URL adresu: dmr::ActionFactory Settings Nastavenia Fullscreen CelĂ¡ obrazovka Always on Top Vždy navrchu Film info InformĂ¡cie o filme Open file OtvoriÅ¥ sĂºbor Open folder OtvoriÅ¥ prieÄinok Light theme SvetlĂ¡ tĂ©ma Open URL OtvoriÅ¥ URL Open CD/DVD OtvoriÅ¥ CD/DVD Mini Mode MalĂ½ režim Play Mode Režim prehrĂ¡vania Order Play PrehrĂ¡vanie podľa poradia Shuffle Play Shuffle prehrĂ¡vanie Single Play JednoduchĂ© prehrĂ¡vanie Single Loop Jedna sluÄka List Loop Zoznam sluÄiek Frame RĂ¡mec Default PredvolenĂ© Clockwise V smere hodinovĂ½ch ruÄiÄiek Counterclockwise Proti smeru hodinovĂ½ch ruÄiÄiek Next frame ÄalÅ¡Ă­ snĂ­mok Previous frame PredchĂ¡dzajĂºci snĂ­mok Sound Zvuk Channel KanĂ¡l Stereo Stereo Left channel ĽavĂ½ kanĂ¡l Right channel PravĂ½ kanĂ¡l Track Skladba Subtitle Titulky Load NahraÅ¥ Online Search Online vyhľadĂ¡vanie Select VybraÅ¥ Hide SkryÅ¥ Encodings KĂ³dovanie Screenshot SnĂ­mok obrazovky Film Screenshot SnĂ­mka filmu Burst Shooting SekvenÄnĂ© snĂ­manie Playlist Zoznam skladieb Film Info InformĂ¡cie o filme Clear playlist VymazaÅ¥ zoznam skladieb Display in file manager ZobraziÅ¥ v sprĂ¡vcovi sĂºborov dmr::BurstScreenshotsDialog Duration: %1 Doba trvania: %1 Resolution: %1 RozlĂ­Å¡enie: %1 Size: %1 VeľkosÅ¥: %1 Save UložiÅ¥ dmr::MainWindow Load successfully NahrĂ¡vanie ĂºspeÅ¡nĂ© Load failed NahrĂ¡vanie zlyhalo No device found Nebolo nĂ¡jdenĂ© žiadne zariadenie Parse Failed Spracovanie zlyhalo Open folder OtvoriÅ¥ prieÄinok Open file OtvoriÅ¥ sĂºbor All videos (%1) VÅ¡etky videĂ¡ (%1) Muted StlmenĂ© Volume: %1% HlasitosÅ¥: %1% Subtitle %1: %2s Titulky %1: %2s delayed oneskorenĂ© advanced pokroÄilĂ© Speed: %1x RĂ½chlosÅ¥: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) Titulky (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View NĂ¡hľad Movie Screenshot SnĂ­mka obrazovky filmu Saved to UloženĂ© na The screenshot is saved SnĂ­mok obrazovky sa uložil Failed to save the screenshot Nepodarilo sa uložiÅ¥ snĂ­mku obrazovky Invalid file: %1 NeplatnĂ½ sĂºbor: %1 dmr::MovieInfo %1G %1G %1M %1M %1K %1K %1 %1 dmr::MovieInfoDialog File Type: Typ sĂºboru: Resolution: RozlĂ­Å¡enie: File Size: VeľkosÅ¥ sĂºboru: Duration: Doba trvania: File Path: Cesta sĂºboru: dmr::MpvProxy [internal] [vnĂºtornĂ©] dmr::PlayItemWidget File does not exist SĂºbor neexistuje dmr::Settings %1/DMovie%2.jpg %1/DMovie%2.jpg %1/DMovie%2(%3).jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play SpustiÅ¥ Previous PredchĂ¡dzajĂºce Next ÄalÅ¡ie Subtitles Titulky Playlist Zoznam skladieb Fullscreen CelĂ¡ obrazovka Play/Pause PrehraÅ¥/pozastaviÅ¥ Exit fullscreen ZruÅ¡iÅ¥ celĂº obrazovku Pause PozastaviÅ¥ deepin-movie-reborn-5.0.0/src/translations/deepin-movie_sl.ts000066400000000000000000000671411351125414100243270ustar00rootroot00000000000000 QObject Deepin Movie Deepin Filmi Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Filmi Deepin je natanÄno oblikovan in dopolnjen video predvajalnik s preprostim, a moÄnim dizajnom. Podpira predvajanje lokalne in pretoÄne vsebine razliÄnih video formatov. Invalid folder Neveljavna mapa Open folder Odpri mapo You don't have permission to operate this folder Nimate dovoljenja za upravljanje te mape Auto add similar files to play Samodejno dodaj podobne datoteke na seznam Clear playlist when exit Ob izhodu izprazni seznam predvajanja Show video preview on mouseover Ob primiku z miÅ¡ko pokaži predogled posnetka Open a new player for each file played Odpri nov predvajalnik za vsako datoteko Pause when minimized Ustavi, ko se pomanjÅ¡a Remember playback position Zapomni si položaj predvajane vsebine Path Pot Basic Osnove Play Predvajaj Screenshot Slika zaslona Shortcuts Bližnjice File Datoteka Frame/Sound Slika/zvok Playback Predvajanje Subtitle Podnapisi Font Style Stil pisave Restore Defaults Obnovi privzeto Open file Odpri datoteko Open next Odpri naslednje Open previous Odpri prejÅ¡nje Mini mode PomanjÅ¡ano Mute UtiÅ¡aj Next frame Previous frame Volume down TiÅ¡je Volume up Glasneje Speed up PospeÅ¡i Speed down PoÄasneje Fullscreen Celozaslonski naÄin Pause/Play Premor/predvajaj Playlist Seznam predvajanja Reset speed Ponastavi hitrost Rewind Prevrti nazaj Forward Previj naprej Burst screenshot Zaslonski posnetek Burst Film screenshot Slika filma 0.5s backward 0,5 s nazaj 0.5s forward 0,5 s naprej Font Pisava Font Size Velikost pisave UrlDialog Cancel PrekliÄi Confirm Potrdi Please enter the URL: Prosim, vnesite URL-naslov: dmr::ActionFactory Settings Nastavitve Fullscreen Celozaslonski naÄin Always on Top Vedno na vrhu Film info Podatki o filmu Open file Odpri datoteko Open folder Odpri mapo Light theme Open URL Odpri URL naslov Open CD/DVD Odpri CD/DVD Mini Mode PomanjÅ¡ano Play Mode NaÄin predvajanja Order Play Vrstni red predvajanja Shuffle Play MeÅ¡anje predvajanja Single Play Enojno predvajanje Single Loop Enojna zanka List Loop Zanka seznamov Frame Slika Default Privzeto Clockwise V smeri urinega kazalca Counterclockwise Proti urinemu kazalcu Next frame Previous frame Sound Zvok Channel Kanal Stereo Stereo Left channel Levi kanal Right channel Desni kanal Track Skladba Subtitle Podnapisi Load Naloži Online Search Spletno brskanje Select Izberi Hide Skrij Encodings Encodings Screenshot Slika zaslona Film Screenshot Slika filma Burst Shooting Intervalno slikanje Playlist Seznam predvajanja Film Info Podatki o filmu Clear playlist PoÄisti seznam predvajanja Display in file manager Prikaži v upravitelju datotek dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save Shrani dmr::MainWindow Load successfully UspeÅ¡no naloženo Load failed Nalaganje neuspeÅ¡no No device found Ne najdem naprave Parse Failed RazÄlenjevanje ni uspelo Open folder Odpri mapo Open file Odpri datoteko All videos (%1) Vsi posnetki (%1) Muted UtiÅ¡ano Volume: %1% Glasnost: %1% Subtitle %1: %2s Podnapisi %1: %2s delayed zamaknjeno advanced napredno Speed: %1x Hitrost: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Prikaži Movie Screenshot Zaslonski posnetek filma Saved to Shranjeno v The screenshot is saved Slika je shranjena Failed to save the screenshot Invalid file: %1 Neveljavna datoteka: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Tip datoteke: Resolution: LoÄljivost: File Size: Velikost datoteke: Duration: ÄŒas trajanja: File Path: Pot datoteke: dmr::MpvProxy [internal] [internal] dmr::PlayItemWidget File does not exist Datoteka ne obstaja dmr::Settings %1/DMovie%2.jpg %1/DFilm%2.jpg %1/DMovie%2(%3).jpg %1/DFilm%2(%3).jpg dmr::ToolboxProxy Play Predvajaj Previous Predhodni Next Naslednji Subtitles Podnapisi Playlist Seznam predvajanja Fullscreen Celozaslonski naÄin Play/Pause Predvajaj/premor Exit fullscreen Izhod iz celozaslonskega naÄina Pause Premor deepin-movie-reborn-5.0.0/src/translations/deepin-movie_sq.ts000066400000000000000000000644531351125414100243370ustar00rootroot00000000000000 QObject Deepin Movie Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Invalid folder Open folder You don't have permission to operate this folder Auto add similar files to play Clear playlist when exit Show video preview on mouseover Open a new player for each file played Pause when minimized Remember playback position Path Basic Play Screenshot Shortcuts File Frame/Sound Playback Subtitle Font Style Restore Defaults Open file Open next Open previous Mini mode Mute Next frame Previous frame Volume down Volume up Speed up Speed down Fullscreen Pause/Play Playlist Reset speed Rewind Forward Burst screenshot Film screenshot 0.5s backward 0.5s forward Font Font Size UrlDialog Cancel Anuloje Confirm Ripohojeni Please enter the URL: dmr::ActionFactory Settings Fullscreen Always on Top Film info Open file Open folder Light theme Open URL Open CD/DVD Mini Mode Play Mode Order Play Shuffle Play Single Play Single Loop List Loop Frame Default Clockwise Counterclockwise Next frame Previous frame Sound Channel Stereo Left channel Right channel Track Subtitle Load Online Search Select Hide Encodings Screenshot Film Screenshot Burst Shooting Playlist Film Info Clear playlist Display in file manager dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save dmr::MainWindow Load successfully Load failed No device found Parse Failed Open folder Open file All videos (%1) Muted Volume: %1% Subtitle %1: %2s delayed advanced Speed: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Movie Screenshot Saved to The screenshot is saved Failed to save the screenshot Invalid file: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Resolution: File Size: Duration: File Path: dmr::MpvProxy [internal] dmr::PlayItemWidget File does not exist dmr::Settings %1/DMovie%2.jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Previous Next Subtitles Playlist Fullscreen Play/Pause Exit fullscreen Pause deepin-movie-reborn-5.0.0/src/translations/deepin-movie_sr.ts000066400000000000000000000723621351125414100243360ustar00rootroot00000000000000 QObject Deepin Movie Đ”Đ¸Đ¿Đ¸Đ½ Đ¤Đ¸Đ»Đ¼ Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Đ”Đ¸Đ¿Đ¸Đ½ Đ¤Đ¸Đ»Đ¼ Ñ˜Đµ ĐºĐ²Đ°Đ»Đ¸Ñ‚ĐµÑ‚Đ½Đ¾ Đ´Đ¸Đ·Đ°Ñ˜Đ½Đ¸Ñ€Đ°Đ½ и Đ¿Đ¾Ñ‚Đ¿ÑƒĐ½Đ¾ Đ¾Đ¿Ñ€ĐµĐ¼Ñ™ĐµĐ½ Đ¿ÑƒÑˆÑ‚Đ°Ñ‡ Đ²Đ¸Đ´ĐµĐ° Ñа Ñ˜ĐµĐ´Đ½Đ¾ÑÑ‚Đ°Đ²Đ½Đ¸Đ¼ Đ±ĐµĐ·Ñ€ÑƒĐ±Đ½Đ¸Đ¼ Đ¸Đ·Đ³Đ»ĐµĐ´Đ¾Đ¼. ĐŸĐ¾Đ´Ñ€Đ¶Đ°Đ²Đ° Đ¿ÑƒÑˆÑ‚Đ°Ñе Đ»Đ¾ĐºĐ°Đ»Đ½Đ¾Đ³ ÑĐ°Đ´Ñ€Đ¶Đ°Ñ˜Đ° ĐºĐ°Đ¾ и ÑĐ°Đ´Ñ€Đ¶Đ°Ñ˜Đ° из Ñ‚Đ¾ĐºĐ¾Đ²Đ° Ñ€Đ°Đ·Đ½Đ¸Ñ… Đ²Đ¸Đ´ĐµĐ¾ Ñ„Đ¾Ñ€Đ¼Đ°Ñ‚Đ°. Invalid folder ĐеиÑĐ¿Ñ€Đ°Đ²Đ½Đ° Ñ„Đ°ÑÑ†Đ¸ĐºĐ»Đ° Open folder ĐÑ‚Đ²Đ¾Ñ€Đ¸ Ñ„Đ°ÑÑ†Đ¸ĐºĐ»Ñƒ You don't have permission to operate this folder ĐĐµĐ¼Đ°Ñ‚Đµ Đ´Đ¾Đ·Đ²Đ¾Đ»Ñƒ да ĐºĐ¾Ñ€Đ¸ÑÑ‚Đ¸Ñ‚Đµ Đ¾Đ²Ñƒ Ñ„Đ°ÑÑ†Đ¸ĐºĐ»Ñƒ Auto add similar files to play ĐÑƒÑ‚Đ¾Đ¼Đ°Ñ‚ÑĐºĐ¸ Đ´Đ¾Đ´Đ°Ñ˜ ÑĐ»Đ¸Ñ‡Đ½Đµ Đ´Đ°Ñ‚Đ¾Ñ‚ĐµĐºĐµ за Đ¿ÑƒÑˆÑ‚Đ°Ñе Clear playlist when exit ĐÑ‡Đ¸ÑÑ‚Đ¸ лиÑту Đ¿ÑƒÑˆÑ‚Đ°Ñа ĐºĐ°Đ´ Đ¸Đ·Đ°Ñ’ĐµĐ¼ Show video preview on mouseover ĐŸÑ€ĐµĐ³Đ»ĐµĐ´ Đ²Đ¸Đ´ĐµĐ° Đ¿Ñ€ĐµĐ»Đ°ÑĐºĐ¾Đ¼ Đ¿Đ¾ĐºĐ°Đ·Đ¸Đ²Đ°Ñ‡Đ° Open a new player for each file played ĐÑ‚Đ²Đ¾Ñ€Đ¸ Đ½Đ¾Đ²Đ¸ Đ¿ÑƒÑˆÑ‚Đ°Ñ‡ за ÑĐ²Đ°ĐºÑƒ Đ´Đ°Ñ‚Đ¾Ñ‚ĐµĐºÑƒ ĐºĐ¾Ñ˜Đ° Ñе Đ¿ÑƒÑˆÑ‚Đ° Pause when minimized ĐŸĐ°ÑƒĐ·Đ° ĐºĐ°Đ´ Đ¼Đ¸Đ½Đ¸Đ¼Đ°Đ»Đ¸Đ·ÑƒÑ˜ĐµĐ¼ Remember playback position Đ—Đ°Đ¿Đ°Đ¼Ñ‚Đ¸ Đ¿Đ¾Đ·Đ¸Ñ†Đ¸Ñ˜Ñƒ Ñ€ĐµĐ¿Ñ€Đ¾Đ´ÑƒĐºÑ†Đ¸Ñ˜Đµ Path ĐŸÑƒÑ‚Đ°Ñа Basic ĐÑĐ½Đ¾Đ²Đ½Đ¾ Play Đ ĐµĐ¿Ñ€Đ¾Đ´ÑƒĐºÑ†Đ¸Ñ˜Đ° Screenshot Đ¡Đ»Đ¸ĐºĐ° ĐµĐºÑ€Đ°Đ½Đ° Shortcuts ĐŸÑ€ĐµÑ‡Đ¸Ñ†Đµ File Đ”Đ°Ñ‚Đ¾Ñ‚ĐµĐºĐ° Frame/Sound ĐĐ°Đ´Đ°Ñ€/Đ—Đ²ÑƒĐº Playback Đ ĐµĐ¿Ñ€Đ¾Đ´ÑƒĐºÑ†Đ¸Ñ˜Đ° Subtitle Đ¢Đ¸Ñ‚Đ» Font Style Đ¡Ñ‚Đ¸Đ» Ñ„Đ¾Đ½Ñ‚Đ° Restore Defaults Đ’Ñ€Đ°Ñ‚Đ¸ ĐŸĐ¾Đ´Ñ€Đ°Đ·ÑƒĐ¼ĐµĐ²Đ°Đ½Đ¾ Open file ĐÑ‚Đ²Đ¾Ñ€Đ¸ Đ´Đ°Ñ‚Đ¾Ñ‚ĐµĐºÑƒ Open next ĐÑ‚Đ²Đ¾Ñ€Đ¸ ÑĐ»ĐµĐ´ĐµÑ›Đµ Open previous ĐÑ‚Đ²Đ¾Ñ€Đ¸ Đ¿Ñ€ĐµÑ‚Ñ…Đ¾Đ´Đ½Đ¾ Mini mode ĐœĐ¸Đ½Đ¸ Ñ€ĐµĐ¶Đ¸Đ¼ Mute Đ£Ñ›ÑƒÑ‚ĐºĐ°Ñ˜ Next frame Đ¡Đ»ĐµĐ´ĐµÑ›Đ¸ ĐºĐ°Đ´Đ°Ñ€ Previous frame ĐŸÑ€ĐµÑ‚Ñ…Đ¾Đ´Đ½Đ¸ ĐºĐ°Đ´Đ°Ñ€ Volume down Đ£Ñ‚Đ¸ÑˆĐ°Ñ˜ Volume up ĐŸĐ¾Ñ˜Đ°Ñ‡Đ°Ñ˜ Speed up Đ£Đ±Ñ€Đ·Đ°Ñ˜ Speed down Đ£ÑĐ¿Đ¾Ñ€Đ¸ Fullscreen Đ¦ĐµĐ¾ ĐµĐºÑ€Đ°Đ½ Pause/Play ĐŸĐ°ÑƒĐ·Đ¸Ñ€Đ°Ñ˜/ĐŸÑƒÑÑ‚Đ¸ Playlist ЛиÑÑ‚Đ° Đ¿ÑƒÑˆÑ‚Đ°Ñа Reset speed Đ’Ñ€Đ°Ñ‚Đ¸ Đ¿Đ¾Ñ‡ĐµÑ‚Đ½Ñƒ Đ±Ñ€Đ·Đ¸Đ½Ñƒ Rewind ĐŸÑ€ĐµĐ¼Đ¾Ñ‚Đ°Ñ˜ Forward ĐĐ°Đ¿Ñ€ĐµĐ´ Burst screenshot Đ Đ°Ñ„Đ°Đ»Đ½Đ¾ уÑĐ»Đ¸ĐºĐ°Đ²Đ°Ñе Film screenshot Đ£ÑĐ»Đ¸ĐºĐ°Ñ˜ Đ²Đ¸Đ´ĐµĐ¾ 0.5s backward 0.5s ÑƒĐ½Đ°Đ·Đ°Đ´ 0.5s forward 0.5s ÑƒĐ½Đ°Đ¿Ñ€ĐµĐ´ Font Đ¤Đ¾Đ½Ñ‚ Font Size Đ’ĐµĐ»Đ¸Ñ‡Đ¸Đ½Đ° Ñ„Đ¾Đ½Ñ‚Đ° UrlDialog Cancel ĐÑ‚ĐºĐ°Đ¶Đ¸ Confirm ĐŸĐ¾Ñ‚Đ²Ñ€Đ´Đ¸ Please enter the URL: ĐœĐ¾Đ»Đ¸Đ¼Đ¾ ÑƒĐ½ĐµÑĐ¸Ñ‚Đµ Đ£Đ Đ›: dmr::ActionFactory Settings ĐŸĐ¾Đ´ĐµÑˆĐ°Đ²Đ°Ñа Fullscreen Đ¦ĐµĐ¾ ĐµĐºÑ€Đ°Đ½ Always on Top Đ£Đ²ĐµĐº Đ½Đ° Đ²Ñ€Ñ…Ñƒ Film info Đ¡Đ²Đ¾Ñ˜ÑÑ‚Đ²Đ° Đ²Đ¸Đ´ĐµĐ° Open file ĐÑ‚Đ²Đ¾Ñ€Đ¸ Đ´Đ°Ñ‚Đ¾Ñ‚ĐµĐºÑƒ Open folder ĐÑ‚Đ²Đ¾Ñ€Đ¸ Ñ„Đ°ÑÑ†Đ¸ĐºĐ»Ñƒ Light theme Đ¡Đ²ĐµÑ‚Đ»Đ° Ñ‚ĐµĐ¼Đ° Open URL ĐÑ‚Đ²Đ¾Ñ€Đ¸ Đ£Đ Đ› Open CD/DVD ĐÑ‚Đ²Đ¾Ñ€Đ¸ ЦД/ДВД Mini Mode ĐœĐ¸Đ½Đ¸ Ñ€ĐµĐ¶Đ¸Đ¼ Play Mode Đ ĐµĐ¶Đ¸Đ¼ Đ¿ÑƒÑˆÑ‚Đ°Ñа Order Play ĐŸÑƒÑˆÑ‚Đ°Ñ˜ Đ¿Đ¾ Ñ€ĐµĐ´Ñƒ Shuffle Play ĐŸÑƒÑˆÑ‚Đ°Ñ˜ Đ½Đ°ÑÑƒĐ¼Đ¸Ñ‡Đ½Đ¾ Single Play ĐŸÑƒÑÑ‚Đ¸ Ñ˜ĐµĐ´Đ°Đ½ Single Loop ĐŸĐ¾Đ½Đ°Đ²Ñ™Đ°Ñ˜ Đ²Đ¸Đ´ĐµĐ¾ List Loop ĐŸĐ¾Đ½Đ°Đ²Ñ™Đ°Ñ˜ лиÑту Frame ĐĐ°Đ´Đ°Ñ€ Default ĐŸĐ¾Đ´Ñ€Đ°Đ·ÑƒĐ¼ĐµĐ²Đ°Đ½Đ¾ Clockwise Đ Đ¾Ñ‚Đ¸Ñ€Đ°Ñ˜ ÑƒĐ´ĐµÑĐ½Đ¾ Counterclockwise Đ Đ¾Ñ‚Đ¸Ñ€Đ°Ñ˜ ÑƒĐ»ĐµĐ²Đ¾ Next frame Đ¡Đ»ĐµĐ´ĐµÑ›Đ¸ ĐºĐ°Đ´Đ°Ñ€ Previous frame ĐŸÑ€ĐµÑ‚Ñ…Đ¾Đ´Đ½Đ¸ ĐºĐ°Đ´Đ°Ñ€ Sound Đ—Đ²ÑƒĐº Channel ĐĐ°Đ½Đ°Đ» Stereo Đ¡Ñ‚ĐµÑ€ĐµĐ¾ Left channel Đ›ĐµĐ²Đ¸ ĐºĐ°Đ½Đ°Đ» Right channel ДеÑĐ½Đ¸ ĐºĐ°Đ½Đ°Đ» Track Đ¡Đ½Đ¸Đ¼Đ°Đº Subtitle Đ¢Đ¸Ñ‚Đ» Load Đ£Ñ‡Đ¸Ñ‚Đ°Ñ˜ Online Search Đ¢Ñ€Đ°Đ¶Đ¸ Đ½Đ° Đ¼Ñ€ĐµĐ¶Đ¸ Select Đ˜Đ·Đ°Đ±ĐµÑ€Đ¸ Hide Đ¡Đ°ĐºÑ€Đ¸Ñ˜ Encodings ĐĐ¾Đ´Đ¸Ñ€Đ°Ñа Screenshot Đ¡Đ»Đ¸ĐºĐ° ĐµĐºÑ€Đ°Đ½Đ° Film Screenshot Đ£ÑĐ»Đ¸ĐºĐ°Ñ˜ Đ²Đ¸Đ´ĐµĐ¾ Burst Shooting Đ Đ°Ñ„Đ°Đ»Đ½Đ¾ уÑĐ»Đ¸ĐºĐ°Đ²Đ°Ñе Playlist ЛиÑÑ‚Đ° Đ¿ÑƒÑˆÑ‚Đ°Ñа Film Info Đ¡Đ²Đ¾Ñ˜ÑÑ‚Đ²Đ° Đ²Đ¸Đ´ĐµĐ° Clear playlist ĐÑ‡Đ¸ÑÑ‚Đ¸ лиÑту Đ¿ÑƒÑˆÑ‚Đ°Ñа Display in file manager ĐŸÑ€Đ¸ĐºĐ°Đ¶Đ¸ у ÑƒĐ¿Ñ€Đ°Đ²Đ½Đ¸ĐºÑƒ Đ¿Đ¾Đ´Đ°Ñ‚Đ°ĐºĐ° dmr::BurstScreenshotsDialog Duration: %1 Đ¢Ñ€Đ°Ñ˜Đ°Ñе: %1 Resolution: %1 Đ ĐµĐ·Đ¾Đ»ÑƒÑ†Đ¸Ñ˜Đ°: %1 Size: %1 Đ’ĐµĐ»Đ¸Ñ‡Đ¸Đ½Đ°: %1 Save Đ¡Đ°Ñ‡ÑƒĐ²Đ°Ñ˜ dmr::MainWindow Load successfully Đ£ÑĐ¿ĐµÑˆĐ½Đ¾ ÑƒÑ‡Đ¸Ñ‚Đ°Đ²Đ°Ñе Load failed ĐĐµÑƒÑĐ¿ĐµÑˆĐ½Đ¾ ÑƒÑ‡Đ¸Ñ‚Đ°Đ²Đ°Ñе No device found ĐĐ¸Ñ˜Đµ Đ¿Ñ€Đ¾Đ½Đ°Ñ’ĐµĐ½ Đ½Đ¸Ñ˜ĐµĐ´Đ°Đ½ ÑƒÑ€ĐµÑ’Đ°Ñ˜ Parse Failed ĐĐµÑƒÑĐ¿ĐµÑˆĐ½Đ¾ Đ°Đ½Đ°Đ»Đ¸Đ·Đ¸Ñ€Đ°Ñе Open folder ĐÑ‚Đ²Đ¾Ñ€Đ¸ Ñ„Đ°ÑÑ†Đ¸ĐºĐ»Ñƒ Open file ĐÑ‚Đ²Đ¾Ñ€Đ¸ Đ´Đ°Ñ‚Đ¾Ñ‚ĐµĐºÑƒ All videos (%1) Đ¡Đ²Đ¸ Đ²Đ¸Đ´ĐµĐ¾ ÑĐ½Đ¸Đ¼Ñ†Đ¸ (%1) Muted Đ£Ñ›ÑƒÑ‚ĐºĐ°Đ½Đ¾ Volume: %1% ĐˆĐ°Ñ‡Đ¸Đ½Đ°: %1% Subtitle %1: %2s Đ¢Đ¸Ñ‚Đ» %1: %2s delayed Đ¾Đ´Đ»Đ¾Đ¶ĐµĐ½Đ¾ advanced Đ½Đ°Đ¿Ñ€ĐµĐ´Đ½Đ¾ Speed: %1x Đ‘Ñ€Đ·Đ¸Đ½Đ°: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) Đ¢Đ¸Ñ‚Đ» (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View ĐŸÑ€ĐµĐ³Đ»ĐµĐ´Đ°Ñ˜ Movie Screenshot Đ£ÑĐ»Đ¸ĐºĐ°Ñ˜ Đ²Đ¸Đ´ĐµĐ¾ Saved to Đ¡Đ°Ñ‡ÑƒĐ²Đ°Đ½Đ¾ у The screenshot is saved Đ¡Đ»Đ¸ĐºĐ° ĐµĐºÑ€Đ°Đ½Đ° Ñ˜Đµ ÑĐ°Ñ‡ÑƒĐ²Đ°Đ½Đ° Failed to save the screenshot ĐĐµÑƒÑĐ¿ĐµĐ»Đ¾ Ñ‡ÑƒĐ²Đ°Ñе ÑĐ»Đ¸ĐºĐµ ĐµĐºÑ€Đ°Đ½Đ° Invalid file: %1 ĐеиÑĐ¿Ñ€Đ°Đ²Đ½Đ° Đ´Đ°Ñ‚Đ¾Ñ‚ĐµĐºĐ°: %1 dmr::MovieInfo %1G %1G %1M %1M %1K %1K %1 %1 dmr::MovieInfoDialog File Type: Đ¢Đ¸Đ¿ Đ´Đ°Ñ‚Đ¾Ñ‚ĐµĐºĐµ: Resolution: Đ ĐµĐ·Đ¾Đ»ÑƒÑ†Đ¸Ñ˜Đ°: File Size: Đ’ĐµĐ»Đ¸Ñ‡Đ¸Đ½Đ° Đ´Đ°Ñ‚Đ¾Ñ‚ĐµĐºĐµ: Duration: Đ¢Ñ€Đ°Ñ˜Đ°Ñе: File Path: ĐŸÑƒÑ‚Đ°Ñа Đ´Đ°Ñ‚Đ¾Ñ‚ĐµĐºĐµ: dmr::MpvProxy [internal] [ÑƒĐ½ÑƒÑ‚Ñ€Đ°ÑˆÑи] dmr::PlayItemWidget File does not exist Đ”Đ°Ñ‚Đ¾Ñ‚ĐµĐºĐ° Đ½Đµ Đ¿Đ¾ÑÑ‚Đ¾Ñ˜Đ¸ dmr::Settings %1/DMovie%2.jpg %1/Đ”Đ¤Đ¸Đ»Đ¼%2.jpg %1/DMovie%2(%3).jpg %1/Đ”Đ¤Đ¸Đ»Đ¼%2(%3).jpg dmr::ToolboxProxy Play ĐŸÑƒÑÑ‚Đ¸ Previous ĐŸÑ€ĐµÑ‚Ñ…Đ¾Đ´Đ½Đ¾ Next Đ¡Đ»ĐµĐ´ĐµÑ›Đµ Subtitles Đ¢Đ¸Ñ‚Đ»Đ¾Đ²Đ¸ Playlist ЛиÑÑ‚Đ° Đ¿ÑƒÑˆÑ‚Đ°Ñа Fullscreen Đ¦ĐµĐ¾ ĐµĐºÑ€Đ°Đ½ Play/Pause ĐŸÑƒÑÑ‚Đ¸/ĐŸĐ°ÑƒĐ·Đ¸Ñ€Đ°Ñ˜ Exit fullscreen ĐĐ°Đ¿ÑƒÑÑ‚Đ¸ Ñ†ĐµĐ¾ ĐµĐºÑ€Đ°Đ½ Pause ĐŸĐ°ÑƒĐ·Đ¸Ñ€Đ°Ñ˜ deepin-movie-reborn-5.0.0/src/translations/deepin-movie_sv.ts000066400000000000000000000652461351125414100243450ustar00rootroot00000000000000 QObject Deepin Movie Deepin-film Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Deepin Film är en väl utformad och fullfjädrad videospelare med enkel gränslös design. Den stöder lokal och strömmand media uppspelning med flera videoformat. Invalid folder Open folder You don't have permission to operate this folder Auto add similar files to play Clear playlist when exit Show video preview on mouseover Open a new player for each file played Pause when minimized Pausa när minimerad Remember playback position Path Basic Play Spela Screenshot Skärmdump Shortcuts Genvägar File Fil Frame/Sound Ram/Ljud Playback Uppspelning Subtitle Font Style Restore Defaults Open file Ă–ppna fil Open next Ă–ppna nästa Open previous Ă–ppna föregĂ¥ende Mini mode Miniläge Mute Tysta Next frame Previous frame Volume down Volym ner Volume up Volym upp Speed up Speed down Fullscreen Fullskärm Pause/Play Pausa/Spela Playlist Spellista Reset speed Rewind Spola tillbaka Forward FramĂ¥t Burst screenshot Burst skärmdump Film screenshot 0.5s backward 0.5s forward Font Font Font Size UrlDialog Cancel Avbryt Confirm Bekräfta Please enter the URL: dmr::ActionFactory Settings Inställningar Fullscreen Fullskärm Always on Top Film info Open file Ă–ppna fil Open folder Light theme Open URL Ă–ppna länk Open CD/DVD Mini Mode Miniläge Play Mode Order Play Shuffle Play Single Play Single Loop List Loop Frame Bildruta Default Förval Clockwise Counterclockwise Next frame Previous frame Sound Ljud Channel Kanal Stereo Stereo Left channel Right channel Track SpĂ¥r Subtitle Load Online Search Select Välj Hide Encodings Screenshot Skärmdump Film Screenshot Burst Shooting Playlist Spellista Film Info Clear playlist Rensa spellista Display in file manager dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save Spara dmr::MainWindow Load successfully Load failed No device found Parse Failed Open folder Open file Ă–ppna fil All videos (%1) Muted Tystad Volume: %1% Subtitle %1: %2s delayed advanced Speed: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Visa Movie Screenshot Filmskärmdump Saved to The screenshot is saved Failed to save the screenshot Invalid file: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Resolution: File Size: Duration: File Path: dmr::MpvProxy [internal] dmr::PlayItemWidget File does not exist dmr::Settings %1/DMovie%2.jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Spela Previous FöregĂ¥ende Next Nästa Subtitles Undertexter Playlist Spellista Fullscreen Fullskärm Play/Pause Spela/Pausa Exit fullscreen Stäng fullskärm Pause Pausa deepin-movie-reborn-5.0.0/src/translations/deepin-movie_ta.ts000066400000000000000000000652571351125414100243230ustar00rootroot00000000000000 QObject Deepin Movie Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Invalid folder Open folder You don't have permission to operate this folder Auto add similar files to play Clear playlist when exit Show video preview on mouseover Open a new player for each file played Pause when minimized Remember playback position Path Basic Play Screenshot திரைபà¯à®ªà®¿à®Ÿà®¿à®ªà¯à®ªà¯ Shortcuts File Frame/Sound Playback Subtitle Font Style Restore Defaults Open file Open next Open previous Mini mode Mute ஒலியடகà¯à®•௠Next frame Previous frame Volume down ஒலி கà¯à®±à¯ˆà®•à¯à®• Volume up ஒலி அதிகரிகà¯à®• Speed up Speed down Fullscreen Pause/Play Playlist Reset speed Rewind Forward Burst screenshot Film screenshot 0.5s backward 0.5s forward Font Font Size UrlDialog Cancel நிறà¯à®¤à¯à®¤à¯ Confirm உறà¯à®¤à®¿à®ªà¯à®ªà®Ÿà¯à®¤à¯à®¤à¯ Please enter the URL: dmr::ActionFactory Settings அமைவà¯à®•ள௠Fullscreen Always on Top Film info Open file Open folder Light theme Open URL Open CD/DVD Mini Mode Play Mode Order Play Shuffle Play Single Play Single Loop List Loop Frame Default இயலà¯à®ªà¯à®¨à®¿à®²à¯ˆ Clockwise Counterclockwise Next frame Previous frame Sound ஒலி Channel à®à¯‡à®©à®²à¯ Stereo Left channel Right channel Track Subtitle Load Online Search Select தேரà¯à®µà¯ Hide Encodings Screenshot திரைபà¯à®ªà®¿à®Ÿà®¿à®ªà¯à®ªà¯ Film Screenshot Burst Shooting Playlist Film Info Clear playlist Display in file manager dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save à®à¯‡à®®à®¿ dmr::MainWindow Load successfully Load failed No device found Parse Failed Open folder Open file All videos (%1) Muted Volume: %1% Subtitle %1: %2s delayed advanced Speed: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Movie Screenshot Saved to The screenshot is saved Failed to save the screenshot Invalid file: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Resolution: File Size: Duration: File Path: dmr::MpvProxy [internal] dmr::PlayItemWidget File does not exist dmr::Settings %1/DMovie%2.jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Previous à®®à¯à®¨à¯à®¤à¯ˆà®¯ Next அடà¯à®¤à¯à®¤à¯ Subtitles Playlist Fullscreen Play/Pause இயகà¯à®•à¯/இடைநிறà¯à®¤à¯à®¤à¯ Exit fullscreen Pause இடைநிறà¯à®¤à¯à®¤à¯ deepin-movie-reborn-5.0.0/src/translations/deepin-movie_tr.ts000066400000000000000000000672771351125414100243500ustar00rootroot00000000000000 QObject Deepin Movie Deepin Sinema Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Deepin Sinema uygulaması basit çerçevesiz tasarımı ile iyi tasarlanmış, tam özellikli bir görĂ¼ntĂ¼ oynatıcısıdır. Pek çok yerel ve akış görĂ¼ntĂ¼ biçimini destekler. Invalid folder Geçersiz klasör Open folder KlasörĂ¼ aç You don't have permission to operate this folder Bu klasörde iÅŸlem yapma izniniz yok Auto add similar files to play Benzer dosyalar oynatılmak Ă¼zere otomatik olarak eklensin Clear playlist when exit Çıkışta oynatma listesi temizlensin Show video preview on mouseover Fare ile Ă¼zerine gelindiÄŸinde ön izleme görĂ¼ntĂ¼lensin Open a new player for each file played Oynatılan her dosya için yeni bir oynatıcı açılsın Pause when minimized KĂ¼Ă§Ă¼ltĂ¼ldĂ¼ÄŸĂ¼nde duraklatılsın Remember playback position Oynatma konumu hatırlansın Path Yol Basic Temel Play Oynat Screenshot Ekran GörĂ¼ntĂ¼sĂ¼ Shortcuts Kısayollar File Dosya Frame/Sound Kare/Ses Playback Oynatma Subtitle Alt yazı Font Style Yazı Biçemi Restore Defaults Varsayılanları Geri YĂ¼kle Open file Dosya aç Open next Sonrakini aç Open previous Ă–ncekini aç Mini mode Mini kip Mute Sessiz Next frame Sonraki kare Previous frame Ă–nceki kare Volume down Sesi azalt Volume up Sesi arttır Speed up Hızı arttır Speed down Hızı azalt Fullscreen Tam ekran Pause/Play Duraklat/Oynat Playlist Oynatma listesi Reset speed Hızı sıfırla Rewind Geri sar Forward İleri sar Burst screenshot Seri ekran görĂ¼ntĂ¼sĂ¼ Film screenshot Film ekran görĂ¼ntĂ¼sĂ¼ 0.5s backward 0.5s geri 0.5s forward 0.5s ileri Font Yazı tipi Font Size Yazı boyutu UrlDialog Cancel İptal Confirm Onayla Please enter the URL: LĂ¼tfen adresi yazınız: dmr::ActionFactory Settings Ayarlar Fullscreen Tam ekran Always on Top Her Zaman Ăœstte Film info Film bilgileri Open file Dosya aç Open folder KlasörĂ¼ aç Light theme Açık tema Open URL Adres Aç Open CD/DVD CD/DVD Aç Mini Mode Mini Kip Play Mode Oynatma Kipi Order Play Oynatma Sırası Shuffle Play Karışık Oynat Single Play Tek Oynat Single Loop Tek DöngĂ¼ List Loop Liste DöngĂ¼sĂ¼ Frame Kare Default Varsayılan Clockwise Saat yönĂ¼nde Counterclockwise Saat yönĂ¼nĂ¼n tersine Next frame Sonraki kare Previous frame Ă–nceki kare Sound Ses Channel Kanal Stereo Çift Kanal Left channel Sol kanal Right channel SaÄŸ kanal Track Parça Subtitle Alt yazı Load YĂ¼kle Online Search Çevrimiçi Ara Select Seçin Hide Gizle Encodings Kodlamalar Screenshot Ekran GörĂ¼ntĂ¼sĂ¼ Film Screenshot Film Ekran GörĂ¼ntĂ¼sĂ¼ Burst Shooting Seri Çekim Playlist Oynatma listesi Film Info Film bilgileri Clear playlist Oynatma listesini temizle Display in file manager Dosya yöneticisinde görĂ¼ntĂ¼le dmr::BurstScreenshotsDialog Duration: %1 SĂ¼re: %1 Resolution: %1 ÇözĂ¼nĂ¼rlĂ¼k: %1 Size: %1 Boyut: %1 Save Kaydet dmr::MainWindow Load successfully YĂ¼klendi Load failed YĂ¼klenemedi No device found Aygıt bulunamadı Parse Failed İşlenemedi Open folder KlasörĂ¼ aç Open file Dosya aç All videos (%1) TĂ¼m görĂ¼ntĂ¼ler (%1) Muted Sessiz Volume: %1% Ses: %1% Subtitle %1: %2s Alt yazı %1: %2s delayed gecikme advanced geliÅŸmiÅŸ Speed: %1x Hız: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) Alt yazı (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View GörĂ¼nĂ¼m Movie Screenshot Sinema Ekran GörĂ¼ntĂ¼sĂ¼ Saved to Åuraya kaydedildi The screenshot is saved Ekran görĂ¼ntĂ¼sĂ¼ kaydedildi Failed to save the screenshot Ekran görĂ¼ntĂ¼sĂ¼ kaydedilemedi Invalid file: %1 Dosya geçersiz: %1 dmr::MovieInfo %1G %1G %1M %1M %1K %1K %1 %1 dmr::MovieInfoDialog File Type: Dosya TĂ¼rĂ¼: Resolution: ÇözĂ¼nĂ¼rlĂ¼k: File Size: Dosya Boyutu: Duration: SĂ¼re: File Path: Dosya Yolu: dmr::MpvProxy [internal] [dahili] dmr::PlayItemWidget File does not exist Dosya bulunamadı dmr::Settings %1/DMovie%2.jpg %1/DSinema%2.jpg %1/DMovie%2(%3).jpg %1/DSinema%2(%3).jpg dmr::ToolboxProxy Play Oynat Previous Ă–nceki Next Sonraki Subtitles Alt yazılar Playlist Oynatma listesi Fullscreen Tam ekran Play/Pause Oynat/Duraklat Exit fullscreen Tam ekrandan çık Pause Duraklat deepin-movie-reborn-5.0.0/src/translations/deepin-movie_ug.ts000066400000000000000000000652131351125414100243220ustar00rootroot00000000000000 QObject Deepin Movie Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Invalid folder Open folder You don't have permission to operate this folder Auto add similar files to play Clear playlist when exit Show video preview on mouseover Open a new player for each file played Pause when minimized Remember playback position Path Basic Play Screenshot ئÛكران رەسىمگە تۇتۇش Shortcuts تىزلەتمە كۇنۇپكىلار File Frame/Sound Playback Subtitle Font Style Restore Defaults سۈكۈتتىكى ھالىتىگە Ù‚Ø§ÙØªÛ‡Ø±Û‡Ø´ Open file Open next Open previous Mini mode Mute Next frame Previous frame Volume down Volume up Speed up Speed down Fullscreen تولۇق ئÛكران Pause/Play Playlist تىزىملىك Reset speed Rewind Forward Burst screenshot Film screenshot 0.5s backward 0.5s forward Font خەت نۇسخىسى Font Size UrlDialog Cancel بىكار قىلىش Confirm جەزملەشتۈرۈش Please enter the URL: dmr::ActionFactory Settings Fullscreen تولۇق ئÛكران Always on Top Film info Open file Open folder Light theme Open URL Open CD/DVD Mini Mode Play Mode ھالىتى Order Play Shuffle Play Single Play Single Loop List Loop Frame Default سۈكۈتتىكى Clockwise Counterclockwise Next frame Previous frame Sound ئاۋاز Channel قانال Stereo Left channel Right channel Track Subtitle Load Online Search Select تاللاش Hide Encodings Screenshot ئÛكران رەسىمگە تۇتۇش Film Screenshot Burst Shooting Playlist تىزىملىك Film Info Clear playlist Display in file manager dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save ساقلاش dmr::MainWindow Load successfully Load failed No device found Parse Failed Open folder Open file All videos (%1) Muted Volume: %1% Subtitle %1: %2s delayed advanced Speed: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Movie Screenshot Saved to The screenshot is saved Failed to save the screenshot Invalid file: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Resolution: File Size: Duration: File Path: dmr::MpvProxy [internal] dmr::PlayItemWidget File does not exist dmr::Settings %1/DMovie%2.jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Previous Next ÙƒÛÙىنكى Subtitles Playlist تىزىملىك Fullscreen تولۇق ئÛكران Play/Pause قوÙۇش\توختۇتۇش Exit fullscreen Pause deepin-movie-reborn-5.0.0/src/translations/deepin-movie_uk.ts000066400000000000000000000732201351125414100243230ustar00rootroot00000000000000 QObject Deepin Movie Đ’Ñ–Đ´ĐµĐ¾ Deepin Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Deepin Movie Ñ†Đµ Đ´Đ¾Đ±Ñ€Đµ ÑĐ¿Ñ€Đ¾ĐµĐºÑ‚Đ¾Đ²Đ°Đ½Đ¸Đ¹ Đ¿Đ¾Đ²Đ½Ñ–ÑÑ‚Ñ Đ¾ÑĐ½Đ°Ñ‰ĐµĐ½Đ¸Đ¹ Đ²Ñ–Đ´ĐµĐ¾ Đ¿Ñ€Đ¾Đ³Ñ€Đ°Đ²Đ°Ñ‡ Đ· Đ¿Ñ€Đ¾ÑÑ‚Đ¸Đ¼ Đ±ĐµĐ·Đ¼ĐµĐ¶Đ½Đ¸Đ¼ Đ´Đ¸Đ·Đ°Đ¹Đ½Đ¾Đ¼. Đ’Ñ–Đ½ Đ¿Ñ–Đ´Ñ‚Ñ€Đ¸Đ¼ÑƒÑ” Đ»Đ¾ĐºĐ°Đ»ÑŒĐ½Đµ Ñ‚Đ° Đ¿Đ¾Ñ‚Đ¾ĐºĐ¾Đ²Đµ Đ²Ñ–Đ´Ñ‚Đ²Đ¾Ñ€ĐµĐ½Đ½Ñ Đ¼ÑƒĐ»ÑŒÑ‚Đ¸Đ¼ĐµĐ´Ñ–Đ° у ĐºÑ–Đ»ÑŒĐºĐ¾Ñ… Đ²Ñ–Đ´ĐµĐ¾ Ñ„Đ¾Ñ€Đ¼Đ°Ñ‚Đ°Ñ…. Invalid folder ĐĐµĐ´Ñ–Đ¹ÑĐ½Đ° Ñ‚ĐµĐºĐ° Open folder Đ’Ñ–Đ´ĐºÑ€Đ¸Ñ‚Đ¸ Ñ‚ĐµĐºÑƒ You don't have permission to operate this folder Ви Đ½Đµ Đ¼Đ°Ñ”Ñ‚Đµ Đ¿Ñ€Đ°Đ²Đ° ĐºĐµÑ€ÑƒĐ²Đ°Ñ‚Đ¸ Ñ†Ñ–Ñ”Ñ Ñ‚ĐµĐºĐ¾Ñ Auto add similar files to play ĐĐ²Ñ‚Đ¾Đ¼Đ°Ñ‚Đ¸Ñ‡Đ½Đ¾ Đ´Đ¾Đ´Đ°Đ²Đ°Ñ‚Đ¸ ÑÑ…Đ¾Đ¶Ñ– Ñ„Đ°Đ¹Đ»Đ¸ Đ´Đ»Ñ Đ²Ñ–Đ´Ñ‚Đ²Đ¾Ñ€ĐµĐ½Đ½Ñ Clear playlist when exit ĐÑ‡Đ¸ÑÑ‚Đ¸Ñ‚Đ¸ ÑĐ¿Đ¸ÑĐ¾Đº Đ²Ñ–Đ´Ñ‚Đ²Đ¾Ñ€ĐµĐ½Đ½Ñ Đ¿Ñ€Đ¸ Đ²Đ¸Ñ…Đ¾Đ´Ñ– Show video preview on mouseover ĐŸĐ¾ĐºĐ°Đ·ÑƒĐ²Đ°Ñ‚Đ¸ Đ¿Đ¾Đ¿ĐµÑ€ĐµĐ´Đ½Ñ–Đ¹ Đ¿ĐµÑ€ĐµĐ³Đ»ÑĐ´ Đ²Ñ–Đ´ĐµĐ¾ Đ¿Ñ€Đ¸ Đ½Đ°Đ²ĐµĐ´ĐµĐ½Đ½Ñ– ĐºÑƒÑ€ÑĐ¾Ñ€Ñƒ Đ¼Đ¸ÑˆÑ– Open a new player for each file played Đ’Ñ–Đ´ĐºÑ€Đ¸Đ¹Ñ‚Đ¸ Đ½Đ¾Đ²Đ¸Đ¹ Đ¿Ñ€Đ¾Đ³Ñ€Đ°Đ²Đ°Ñ‡ Đ´Đ»Ñ ĐºĐ¾Đ¶Đ½Đ¾Đ³Đ¾ Đ²Ñ–Đ´Ñ‚Đ²Đ¾Ñ€ĐµĐ½Đ¾Đ³Đ¾ Ñ„Đ°Đ¹Đ»Ñƒ Pause when minimized ĐŸĐ°ÑƒĐ·Đ° Đ¿Ñ€Đ¸ Đ·Đ³Đ¾Ñ€Ñ‚Đ°Đ½Đ½Ñ– Remember playback position Đ—Đ°Đ¿Đ°Đ¼'ÑÑ‚Đ°Ñ‚Đ¸ Đ¿Đ¾Đ·Đ¸Ñ†Ñ–Ñ Đ²Ñ–Đ´Ñ‚Đ²Đ¾Ñ€ĐµĐ½Đ½Ñ Path ШлÑÑ… Basic ĐÑĐ½Đ¾Đ²Đ½Đ¸Đ¹ Play Đ’Ñ–Đ´Ñ‚Đ²Đ¾Ñ€Đ¸Ñ‚Đ¸ Screenshot Đ—Đ½Ñ–Đ¼Đ¾Đº ĐµĐºÑ€Đ°Đ½Ñƒ Shortcuts Đ“Đ°Ñ€Ñчі ĐºĐ»Đ°Đ²Ñ–ÑˆÑ– File Đ¤Đ°Đ¹Đ» Frame/Sound ĐĐ°Đ´Ñ€/Đ—Đ²ÑƒĐº Playback Đ’Ñ–Đ´Ñ‚Đ²Đ¾Ñ€ĐµĐ½Đ½Ñ Subtitle Đ¡ÑƒĐ±Ñ‚Đ¸Ñ‚Ñ€Đ¸ Font Style Đ¡Ñ‚Đ¸Đ»ÑŒ ÑˆÑ€Đ¸Ñ„Ñ‚Ñƒ Restore Defaults Đ’Ñ–Đ´Đ½Đ¾Đ²Đ¸Ñ‚Đ¸ за Đ·Đ°Đ¼Đ¾Đ²Ñ‡ÑƒĐ²Đ°Đ½Đ½ÑĐ¼ Open file Đ’Ñ–Đ´ĐºÑ€Đ¸Ñ‚Đ¸ Ñ„Đ°Đ¹Đ» Open next Đ’Ñ–Đ´ĐºÑ€Đ¸Ñ‚Đ¸ Đ½Đ°ÑÑ‚ÑƒĐ¿Đ½Đµ Open previous Đ’Ñ–Đ´ĐºÑ€Đ¸Ñ‚Đ¸ Đ¿Đ¾Đ¿ĐµÑ€ĐµĐ´Đ½Ñ” Mini mode Đ ĐµĐ¶Đ¸Đ¼ Đ¼Ñ–Đ½Ñ– Mute Đ’Đ¸Đ¼ĐºĐ½ÑƒÑ‚Đ¸ Đ·Đ²ÑƒĐº Next frame ĐаÑÑ‚ÑƒĐ¿Đ½Đ¸Đ¹ ĐºĐ°Đ´Ñ€ Previous frame ĐŸĐ¾Đ¿ĐµÑ€ĐµĐ´Đ½Ñ–Đ¹ ĐºĐ°Đ´Ñ€ Volume down Đ¢Đ¸Ñ…Ñ–ÑˆĐµ Volume up Đ—Đ±Ñ–Đ»ÑŒÑˆĐ¸Ñ‚Đ¸ Đ³ÑƒÑ‡Đ½Ñ–Ñть Speed up ĐŸÑ€Đ¸ÑĐºĐ¾Ñ€Đ¸Ñ‚Đ¸ Speed down Đ£Đ¿Đ¾Đ²Ñ–Đ»ÑŒĐ½Đ¸Ñ‚Đ¸ Fullscreen Đа Đ²ĐµÑÑŒ ĐµĐºÑ€Đ°Đ½ Pause/Play ĐŸĐ°ÑƒĐ·Đ°/Đ’Ñ–Đ´Ñ‚Đ²Đ¾Ñ€Đ¸Ñ‚Đ¸ Playlist ĐŸĐ»ĐµĐ¹Đ»Đ¸ÑÑ‚ Reset speed Đ¡ĐºĐ¸Đ´Đ°Đ½Đ½Ñ ÑˆĐ²Đ¸Đ´ĐºĐ¾Ñті Rewind ĐŸĐµÑ€ĐµĐ¼Đ¾Ñ‚Đ°Ñ‚Đ¸ Forward Đ’Đ¿ĐµÑ€ĐµĐ´ Burst screenshot Đ Đ¾Đ·Đ±Đ¸Ñ‚Đ¸ Đ·Đ½Ñ–Đ¼Đ¾Đº ĐµĐºÑ€Đ°Đ½Ñƒ Film screenshot Đ—Đ½Ñ–Đ¼Đ¾Đº ĐºĐ°Đ´Ñ€Ñƒ 0.5s backward 0,5Ñ. Đ½Đ°Đ·Đ°Đ´ 0.5s forward 0.5Ñ. Đ²Đ¿ĐµÑ€ĐµĐ´ Font Đ¨Ñ€Đ¸Ñ„Ñ‚ Font Size Đ Đ¾Đ·Đ¼Ñ–Ñ€ ÑˆÑ€Đ¸Ñ„Ñ‚Ñƒ UrlDialog Cancel Đ¡ĐºĐ°ÑÑƒĐ²Đ°Ñ‚Đ¸ Confirm ĐŸÑ–Đ´Ñ‚Đ²ĐµÑ€Đ´Đ¸Ñ‚Đ¸ Please enter the URL: Đ‘ÑƒĐ´ÑŒ-лаÑĐºĐ°, Đ²Đ²ĐµĐ´Ñ–Ñ‚ÑŒ URL-Đ°Đ´Ñ€ĐµÑу: dmr::ActionFactory Settings ĐĐ°Đ»Đ°ÑˆÑ‚ÑƒĐ²Đ°Đ½Đ½Ñ Fullscreen Đа Đ²ĐµÑÑŒ ĐµĐºÑ€Đ°Đ½ Always on Top Đ—Đ°Đ²Đ¶Đ´Đ¸ Đ·Đ³Đ¾Ñ€Đ¸ Film info Đ†Đ½Ñ„Đ¾Ñ€Đ¼Đ°Ñ†Ñ–Ñ Đ¿Ñ€Đ¾ Ñ„Ñ–Đ»ÑŒĐ¼ Open file Đ’Ñ–Đ´ĐºÑ€Đ¸Ñ‚Đ¸ Ñ„Đ°Đ¹Đ» Open folder Đ’Ñ–Đ´ĐºÑ€Đ¸Ñ‚Đ¸ Ñ‚ĐµĐºÑƒ Light theme Đ¡Đ²Ñ–Ñ‚Đ»Đ° Ñ‚ĐµĐ¼Đ° Open URL Đ’Ñ–Đ´ĐºÑ€Đ¸Ñ‚Đ¸ URL Open CD/DVD Đ’Ñ–Đ´ĐºÑ€Đ¸Ñ‚Đ¸ CD/DVD Mini Mode Đ ĐµĐ¶Đ¸Đ¼ Đ¼Ñ–Đ½Ñ– Play Mode Đ ĐµĐ¶Đ¸Đ¼ Đ²Ñ–Đ´Ñ‚Đ²Đ¾Ñ€ĐµĐ½Đ½Ñ Order Play ĐŸĐ¾Ñ€ÑĐ´Đ¾Đº Đ²Ñ–Đ´Ñ‚Đ²Đ¾Ñ€ĐµĐ½Đ½Ñ Shuffle Play Đ’Ñ–Đ´Ñ‚Đ²Đ¾Ñ€ĐµĐ½Đ½Ñ Ñƒ Đ²Đ¸Đ¿Đ°Đ´ĐºĐ¾Đ²Đ¾Đ¼Ñƒ Đ¿Đ¾Ñ€ÑĐ´ĐºÑƒ Single Play Đ’Ñ–Đ´Ñ‚Đ²Đ¾Ñ€Đ¸Ñ‚Đ¸ Đ¾Đ´Đ¸Đ½ Ñ€Đ°Đ· Single Loop Đ—Đ°Ñ†Đ¸ĐºĐ»Đ¸Ñ‚Đ¸ List Loop Đ—Đ°Ñ†Đ¸ĐºĐ»Đ¸Ñ‚Đ¸ ÑĐ¿Đ¸ÑĐ¾Đº Frame ĐĐ°Đ´Ñ€ Default Đ¢Đ¸Đ¿Đ¾Đ²Đ¾ Clockwise За Đ³Đ¾Đ´Đ¸Đ½Đ½Đ¸ĐºĐ¾Đ²Đ¾Ñ ÑÑ‚Ñ€Ñ–Đ»ĐºĐ¾Ñ Counterclockwise ĐŸÑ€Đ¾Ñ‚Đ¸ Đ³Đ¾Đ´Đ¸Đ½Đ½Đ¸ĐºĐ¾Đ²Đ¾Ñ— ÑÑ‚Ñ€Ñ–Đ»ĐºĐ¸ Next frame ĐаÑÑ‚ÑƒĐ¿Đ½Đ¸Đ¹ ĐºĐ°Đ´Ñ€ Previous frame ĐŸĐ¾Đ¿ĐµÑ€ĐµĐ´Đ½Ñ–Đ¹ ĐºĐ°Đ´Ñ€ Sound Đ—Đ²ÑƒĐº Channel ĐĐ°Đ½Đ°Đ» Stereo Đ¡Ñ‚ĐµÑ€ĐµĐ¾ Left channel Đ›Ñ–Đ²Đ¸Đ¹ ĐºĐ°Đ½Đ°Đ» Right channel ĐŸÑ€Đ°Đ²Đ¸Đ¹ ĐºĐ°Đ½Đ°Đ» Track Đ”Đ¾Ñ€Ñ–Đ¶ĐºĐ° Subtitle Đ¡ÑƒĐ±Ñ‚Đ¸Ñ‚Ñ€Đ¸ Load Đ—Đ°Đ²Đ°Đ½Ñ‚Đ°Đ¶ĐµĐ½Đ½Ñ Online Search ĐĐ½Đ»Đ°Đ¹Đ½-Đ¿Đ¾ÑˆÑƒĐº Select ĐĐ±Ñ€Đ°Ñ‚Đ¸ Hide Đ¡Ñ…Đ¾Đ²Đ°Ñ‚Đ¸ Encodings ĐĐ¾Đ´ÑƒĐ²Đ°Đ½Đ½Ñ Screenshot Đ—Đ½Ñ–Đ¼Đ¾Đº ĐµĐºÑ€Đ°Đ½Ñƒ Film Screenshot Đ—Đ½Ñ–Đ¼Đ¾Đº ĐºĐ°Đ´Ñ€Ñƒ Burst Shooting Đ¡ĐµÑ€Ñ–Đ¹Đ½Đ¸Đ¹ Đ·Đ½Ñ–Đ¼Đ¾Đº Playlist ĐŸĐ»ĐµĐ¹Đ»Đ¸ÑÑ‚ Film Info Đ†Đ½Ñ„Đ¾Ñ€Đ¼Đ°Ñ†Ñ–Ñ Đ¿Ñ€Đ¾ Ñ„Ñ–Đ»ÑŒĐ¼ Clear playlist ĐÑ‡Đ¸ÑÑ‚Đ¸Ñ‚Đ¸ ÑĐ¿Đ¸ÑĐ¾Đº Đ²Ñ–Đ´Ñ‚Đ²Đ¾Ñ€ĐµĐ½Đ½Ñ Display in file manager Đ’Ñ–Đ´Đ¾Đ±Ñ€Đ°Đ·Đ¸Ñ‚Đ¸ у Ñ„Đ°Đ¹Đ»Đ¾Đ²Đ¾Đ¼Ñƒ Đ¼ĐµĐ½ĐµĐ´Đ¶ĐµÑ€Ñ– dmr::BurstScreenshotsDialog Duration: %1 Đ¢Ñ€Đ¸Đ²Đ°Đ»Ñ–Ñть: %1 Resolution: %1 Đ Đ¾Đ·Đ´Ñ–Đ»ÑŒĐ½Đ° Đ·Đ´Đ°Ñ‚Đ½Ñ–Ñть: %1 Size: %1 Đ Đ¾Đ·Đ¼Ñ–Ñ€: %1 Save Đ—Đ±ĐµÑ€ĐµĐ³Ñ‚Đ¸ dmr::MainWindow Load successfully Đ£ÑĐ¿Ñ–ÑˆĐ½Đ¾ Đ·Đ°Đ²Đ°Đ½Ñ‚Đ°Đ¶ĐµĐ½Đ¾ Load failed Đе Đ²Đ´Đ°Đ»Đ¾ÑÑ Đ·Đ°Đ²Đ°Đ½Ñ‚Đ°Đ¶Đ¸Ñ‚Đ¸. No device found Đе Đ·Đ½Đ°Đ¹Đ´ĐµĐ½Đ¾ Đ¶Đ¾Đ´Đ½Đ¾Đ³Đ¾ Đ¿Ñ€Đ¸ÑÑ‚Ñ€Đ¾Ñ Parse Failed Đе Đ²Đ´Đ°Đ»Đ¾ÑÑ Đ¿Ñ€Đ¾Đ°Đ½Đ°Đ»Ñ–Đ·ÑƒĐ²Đ°Ñ‚Đ¸ Open folder Đ’Ñ–Đ´ĐºÑ€Đ¸Ñ‚Đ¸ Ñ‚ĐµĐºÑƒ Open file Đ’Ñ–Đ´ĐºÑ€Đ¸Ñ‚Đ¸ Ñ„Đ°Đ¹Đ» All videos (%1) Đ£ÑÑ– Đ²Ñ–Đ´ĐµĐ¾ (%1) Muted ĐŸÑ€Đ¸Đ³Đ»ÑƒÑˆĐµĐ½Đ¾ Volume: %1% Đ“ÑƒÑ‡Đ½Ñ–Ñть: %1% Subtitle %1: %2s Đ¡ÑƒĐ±Ñ‚Đ¸Ñ‚Ñ€Đ¸ %1: %2s delayed Đ·Đ°Ñ‚Ñ€Đ¸Đ¼ĐºĐ° advanced Đ´Đ¾Đ´Đ°Ñ‚ĐºĐ¾Đ²Đ¾ Speed: %1x Đ¨Đ²Đ¸Đ´ĐºÑ–Ñть: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) Đ¡ÑƒĐ±Ñ‚Đ¸Ñ‚Ñ€Đ¸ (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View ĐŸĐµÑ€ĐµĐ³Đ»ÑĐ½ÑƒÑ‚Đ¸ Movie Screenshot Đ¡ĐºÑ€Ñ–Đ½ÑˆĐ¾Ñ‚ Ñ„Ñ–Đ»ÑŒĐ¼Ñƒ Saved to Đ—Đ±ĐµÑ€ĐµĐ³Ñ‚Đ¸ Đ´Đ¾ The screenshot is saved Đ—Đ½Ñ–Đ¼Đ¾Đº Đ²Ñ–ĐºĐ½Đ° Đ·Đ±ĐµÑ€ĐµĐ¶ĐµĐ½Đ¾ Failed to save the screenshot Đе Đ²Đ´Đ°Đ»Đ¾ÑÑ Đ·Đ±ĐµÑ€ĐµĐ³Ñ‚Đ¸ Đ·Đ½Ñ–Đ¼Đ¾Đº ĐµĐºÑ€Đ°Đ½Đ° Invalid file: %1 ĐĐµĐ¿Ñ€Đ¸Đ¿ÑƒÑÑ‚Đ¸Đ¼Đ¸Đ¹ Ñ„Đ°Đ¹Đ»: %1 dmr::MovieInfo %1G %1G %1M %1M %1K %1K %1 %1 dmr::MovieInfoDialog File Type: Đ¢Đ¸Đ¿ Ñ„Đ°Đ¹Đ»Ñƒ: Resolution: Đ Đ¾Đ·Đ´Ñ–Đ»ÑŒĐ½Đ° Đ·Đ´Đ°Ñ‚Đ½Ñ–Ñть: File Size: Đ Đ¾Đ·Đ¼Ñ–Ñ€ Ñ„Đ°Đ¹Đ»Ñƒ: Duration: Đ¢Ñ€Đ¸Đ²Đ°Đ»Ñ–Ñть: File Path: ШлÑÑ… Đ´Đ¾ Ñ„Đ°Đ¹Đ»Ñƒ: dmr::MpvProxy [internal] [Đ²Đ½ÑƒÑ‚Ñ€Ñ–ÑˆĐ½Ñ–Đ¹] dmr::PlayItemWidget File does not exist Đ¤Đ°Đ¹Đ» Đ½Đµ Ñ–ÑĐ½ÑƒÑ” dmr::Settings %1/DMovie%2.jpg %1/DMovie%2.jpg %1/DMovie%2(%3).jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Đ’Ñ–Đ´Ñ‚Đ²Đ¾Ñ€Đ¸Ñ‚Đ¸ Previous ĐŸĐ¾Đ¿ĐµÑ€ĐµĐ´Đ½Ñ–Đ¹ Next ĐаÑÑ‚ÑƒĐ¿Đ½Đ¸Đ¹ Subtitles Đ¡ÑƒĐ±Ñ‚Đ¸Ñ‚Ñ€Đ¸ Playlist ĐŸĐ»ĐµĐ¹Đ»Đ¸ÑÑ‚ Fullscreen Đа Đ²ĐµÑÑŒ ĐµĐºÑ€Đ°Đ½ Play/Pause Đ’Ñ–Đ´Ñ‚Đ²Đ¾Ñ€ĐµĐ½Đ½Ñ/ĐŸĐ°ÑƒĐ·Đ° Exit fullscreen Đ’Đ¸Đ¹Ñ‚Đ¸ Đ· Đ¿Đ¾Đ²Đ½Đ¾ĐµĐºÑ€Đ°Đ½Đ½Đ¾Đ³Đ¾ Ñ€ĐµĐ¶Đ¸Đ¼Ñƒ Pause ĐŸĐ°ÑƒĐ·Đ° deepin-movie-reborn-5.0.0/src/translations/deepin-movie_vi.ts000066400000000000000000000650031351125414100243220ustar00rootroot00000000000000 QObject Deepin Movie Trình xem phim Deepin Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Invalid folder Open folder You don't have permission to operate this folder Auto add similar files to play Clear playlist when exit Show video preview on mouseover Open a new player for each file played Pause when minimized Remember playback position Path Basic Play Screenshot Ảnh chụp mĂ n hình Shortcuts CĂ¡c PhĂ­m tắt File Frame/Sound Playback Subtitle Font Style Restore Defaults Open file Mở tệp tin Open next Open previous Mini mode Mute CĂ¢m Next frame Previous frame Volume down Giảm Ă¢m thanh Volume up Tăng Ă¢m thanh Speed up Speed down Fullscreen Äầy mĂ n hình Pause/Play Playlist Reset speed Rewind Forward Burst screenshot Film screenshot 0.5s backward 0.5s forward Font PhĂ´ng chữ Font Size UrlDialog Cancel Há»§y Confirm XĂ¡c nhận Please enter the URL: dmr::ActionFactory Settings CĂ i đặt Fullscreen Äầy mĂ n hình Always on Top Film info Open file Mở tệp tin Open folder Light theme Open URL Mở URL Open CD/DVD Mini Mode Play Mode Order Play Shuffle Play Single Play Single Loop List Loop Frame Default Mặc định Clockwise Counterclockwise Next frame Previous frame Sound Ă‚m thanh Channel KĂªnh Stereo Left channel Right channel Track Subtitle Load Online Search Select Chá»n Hide Encodings Screenshot Ảnh chụp mĂ n hình Film Screenshot Burst Shooting Playlist Film Info Clear playlist Display in file manager dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save Lưu dmr::MainWindow Load successfully Load failed No device found Parse Failed Open folder Open file Mở tệp tin All videos (%1) Muted Volume: %1% Subtitle %1: %2s delayed advanced Speed: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View Movie Screenshot Saved to The screenshot is saved Failed to save the screenshot Invalid file: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Resolution: File Size: Duration: File Path: dmr::MpvProxy [internal] dmr::PlayItemWidget File does not exist dmr::Settings %1/DMovie%2.jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play Previous Trước Next Kế tiếp Subtitles Playlist Fullscreen Äầy mĂ n hình Play/Pause Chạy/Tạm dừng Exit fullscreen ThoĂ¡t toĂ n mĂ n hình Pause Dừng deepin-movie-reborn-5.0.0/src/translations/deepin-movie_zh_CN.ts000066400000000000000000000667741351125414100247250ustar00rootroot00000000000000 QObject Deepin Movie 深度影院 Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. 深度影院是一款设计精良ă€åŸèƒ½å…¨é¢ç„视频播放器,无边框简æ´è®¾è®¡ï¼Œæ”¯æŒå¤ç§è§†é¢‘æ ¼å¼æœ¬åœ°æ’­æ”¾å’Œæµåª’ä½“æ’­æ”¾ă€‚ Invalid folder 此文件夹无效 Open folder 打开文件夹 You don't have permission to operate this folder 此文件夹没有æ“作æƒé™ Auto add similar files to play è‡ªå¨æŸ¥æ‰¾ç›¸ä¼¼æ–‡ä»¶è¿ç»­æ’­æ”¾ Clear playlist when exit 退出深度影院时清空播放列表 Show video preview on mouseover 鼠标悬åœè¿›åº¦æ¡æ—¶æ˜¾ç¤ºé¢„览 Open a new player for each file played å…è®¸åŒæ—¶è¿è¡Œå¤ä¸ªæ·±åº¦å½±é™¢ Pause when minimized 最å°åŒ–æ—¶æ‚åœ Remember playback position 自å¨ä»ä¸æ¬¡åœæ­¢ä½ç½®æ’­æ”¾ Path ä¿å­˜è·¯å¾„ Basic 基础设置 Play 播放 Screenshot 截图 Shortcuts å¿«æ·é”® File 文件 Frame/Sound ç”»é¢/声音 Playback 播放 Subtitle 字幕 Font Style å­—ä½“æ ·å¼ Restore Defaults æ¢å¤é»˜è®¤ Open file 打开文件 Open next 打开下一个 Open previous 打开ä¸ä¸€ä¸ª Mini mode è¿·ä½ æ¨¡å¼ Mute é™éŸ³ Next frame 下一帧 Previous frame ä¸ä¸€å¸§ Volume down å‡å°éŸ³é‡ Volume up å¢å¤§éŸ³é‡ Speed up å é€Ÿæ’­æ”¾ Speed down å‡é€Ÿæ’­æ”¾ Fullscreen å…¨å± Pause/Play æ‚åœ/播放 Playlist 播放列表 Reset speed è¿˜åŸæ’­æ”¾é€Ÿåº¦ Rewind 快退 Forward å¿«è¿› Burst screenshot è¿æ‹æˆªå›¾ Film screenshot 影片截图 0.5s backward 字幕延迟0.5ç§’ 0.5s forward 字幕æå‰0.5ç§’ Font 字体 Font Size å­—å· UrlDialog Cancel å–æ¶ˆ Confirm 确认 Please enter the URL: è¯·è¾“å…¥æ‚¨è¦æ’­æ”¾æ–‡ä»¶ç„网络地å€ï¼ dmr::ActionFactory Settings 设置 Fullscreen å…¨å± Always on Top ç½®é¡¶çª—å£ Film info ç”µå½±ä¿¡æ¯ Open file 打开文件 Open folder 打开文件夹 Light theme 浅色主题 Open URL 打开URL Open CD/DVD 播放光盘 Mini Mode è¿·ä½ æ¨¡å¼ Play Mode æ’­æ”¾æ¨¡å¼ Order Play é¡ºåºæ’­æ”¾ Shuffle Play éæœºæ’­æ”¾ Single Play å•个播放 Single Loop å•ä¸ªå¾ªç¯ List Loop åˆ—è¡¨å¾ªç¯ Frame ç”»é¢ Default 默认 Clockwise 顺时针旋转 Counterclockwise 逆时针旋转 Next frame 下一帧 Previous frame ä¸ä¸€å¸§ Sound 声音 Channel å£°é“ Stereo 立体声 Left channel å·¦å£°é“ Right channel å³å£°é“ Track 音轨 Subtitle 字幕 Load 载入字幕 Online Search 查找在线字幕 Select 选择字幕 Hide éè—字幕 Encodings ç¼–ç  Screenshot 截图 Film Screenshot 截图 Burst Shooting è¿æ‹æˆªå›¾ Playlist 播放列表 Film Info ç”µå½±ä¿¡æ¯ Clear playlist 清空播放列表 Display in file manager 在文件管ç†å™¨ä¸­æ˜¾ç¤º dmr::BurstScreenshotsDialog Duration: %1 æ—¶é•¿ï¼%1 Resolution: %1 分辨ç‡ï¼%1 Size: %1 影片大å°ï¼%1 Save ä¿å­˜ dmr::MainWindow Load successfully 载入字幕æˆåŸ Load failed 载入字幕失败 No device found 没有å‘ç°å¯æ’­æ”¾è®¾å¤‡ Parse Failed è§£æå¤±è´¥ Open folder 打开文件夹 Open file 打开文件 All videos (%1) 所有视频(%1) Muted é™éŸ³ Volume: %1% 音é‡ï¼%1% Subtitle %1: %2s 字幕%1ï¼%2ç§’ delayed 延迟 advanced æå‰ Speed: %1x 播放速度ï¼%1å€ Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) 字幕文件 (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View 查看 Movie Screenshot 视频截图 Saved to ä¿å­˜åˆ° The screenshot is saved 截图已ä¿å­˜ Failed to save the screenshot 截图ä¿å­˜å¤±è´¥ Invalid file: %1 无效文件ï¼%1 dmr::MovieInfo %1G %1G %1M %1M %1K %1K %1 %1 dmr::MovieInfoDialog File Type: 文件类å‹ï¼ Resolution: 分辨ç‡ï¼ File Size: 文件大å°ï¼ Duration: åª’ä½“æ—¶é•¿ï¼ File Path: æ–‡ä»¶è·¯å¾„ï¼ dmr::MpvProxy [internal] ă€å†…éƒ¨ă€‘ dmr::PlayItemWidget File does not exist 文件ä¸å­˜åœ¨ dmr::Settings %1/DMovie%2.jpg %1/深度影院%2.jpg %1/DMovie%2(%3).jpg %1/深度影院%2(%3).jpg dmr::ToolboxProxy Play 播放 Previous ä¸ä¸€ä¸ª Next 下一个 Subtitles 字幕 Playlist 播放列表 Fullscreen å…¨å± Play/Pause 播放/æ‚åœ Exit fullscreen é€€å‡ºå…¨å± Pause æ‚åœ deepin-movie-reborn-5.0.0/src/translations/deepin-movie_zh_HK.ts000066400000000000000000000651601351125414100247130ustar00rootroot00000000000000 QObject Deepin Movie Depein 電影 Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Invalid folder Open folder 開啟資料夾 You don't have permission to operate this folder Auto add similar files to play Clear playlist when exit Show video preview on mouseover Open a new player for each file played Pause when minimized 最å°åŒ–時æ«åœ Remember playback position 記錄播放時間 Path Basic 基本 Play 播放 Screenshot æˆªåœ–è¨­å® Shortcuts æ·å¾‘ File 檔 Frame/Sound 影格/è²éŸ³ Playback æ’­æ”¾è¨­å® Subtitle Font Style Restore Defaults æ¢å¾©é è¨­å€¼ Open file 開啟檔案 Open next 開啟下一個 Open previous 開啟ä¸ä¸€å€‹ Mini mode ç²¾ç°¡æ¨¡å¼ Mute éœéŸ³ Next frame Previous frame Volume down 調ä½éŸ³é‡ Volume up èª¿é«˜éŸ³é‡ Speed up Speed down Fullscreen å…¨è¢å¹• Pause/Play æ«åœ/播放 Playlist 播放清單 Reset speed Rewind 後退 Forward 快進 Burst screenshot 連續截圖 Film screenshot 0.5s backward 0.5s forward Font å­—é«” Font Size UrlDialog Cancel å–æ¶ˆ Confirm ç¢ºå® Please enter the URL: dmr::ActionFactory Settings 設置 Fullscreen å…¨è¢å¹• Always on Top Film info Open file 開啟檔案 Open folder 開啟資料夾 Light theme Open URL æ‰“é–‹ç¶²å€ Open CD/DVD Mini Mode è¿·ä½ æ¨¡å¼ Play Mode æ’­æ”¾æ¨¡å¼ Order Play Shuffle Play Single Play Single Loop List Loop Frame 影格 Default é è¨­ Clockwise Counterclockwise Next frame Previous frame Sound 音效 Channel Stereo ç«‹é«”è² Left channel Right channel Track 歌曲 Subtitle Load Online Search Select 鏿“‡ Hide Encodings Screenshot æˆªåœ–è¨­å® Film Screenshot Burst Shooting Playlist 播放清單 Film Info Clear playlist 清除播放清單 Display in file manager 於檔案管ç†å“¡é¡¯ç¤º dmr::BurstScreenshotsDialog Duration: %1 Resolution: %1 Size: %1 Save 儲存 dmr::MainWindow Load successfully Load failed No device found Parse Failed Open folder 開啟資料夾 Open file 開啟檔案 All videos (%1) Muted å·²éœéŸ³ Volume: %1% Subtitle %1: %2s delayed advanced Speed: %1x Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View 檢視 Movie Screenshot 電影截圖 Saved to The screenshot is saved Failed to save the screenshot Invalid file: %1 dmr::MovieInfo %1G %1M %1K %1 dmr::MovieInfoDialog File Type: Resolution: File Size: Duration: é•·åº¦ï¼ File Path: dmr::MpvProxy [internal] dmr::PlayItemWidget File does not exist dmr::Settings %1/DMovie%2.jpg %1/DMovie%2(%3).jpg dmr::ToolboxProxy Play 播放 Previous ä¸ä¸€é¦– Next 下一步 Subtitles 字幕 Playlist 播放清單 Fullscreen å…¨è¢å¹• Play/Pause æ«åœ/繼續 Exit fullscreen 離開全è¢å¹• Pause æ«åœ deepin-movie-reborn-5.0.0/src/translations/deepin-movie_zh_TW.ts000066400000000000000000000665531351125414100247520ustar00rootroot00000000000000 QObject Deepin Movie Deepin 電影 Deepin Movie is a well-designed and full-featured video player with simple borderless design. It supports local and streaming media play with multiple video formats. Deepin 電影æ¡ç”¨ç²¾ç¾ç„ç„¡é‚æ¡†ä»‹é¢è¨­è¨ˆä¸¦ä¸”åŸèƒ½å…¨é¢ï¼Œå®Œæ•´æ”¯æ´å¤ç¨®å½±ç‰‡æ ¼å¼ä»¥åç·ä¸åª’體串æµă€‚ Invalid folder 無效資料夾 Open folder 開啟資料夾 You don't have permission to operate this folder ç„¡æ¬æ›´å‹•資料夾 Auto add similar files to play 自動播放相似檔案 Clear playlist when exit 離開後清除播放列表 Show video preview on mouseover æ»‘é¼ æ”¾åˆ°é€²åº¦æ¢æ™‚顯示é è¦½åœ– Open a new player for each file played 於新視窗開啟檔案 Pause when minimized 最å°åŒ–時æ«åœ Remember playback position è¨˜ä½æ’­æ”¾ä½ç½® Path ä½ç½® Basic 基本 Play 播放 Screenshot 截圖 Shortcuts å¿«é€Ÿéµ File 檔案 Frame/Sound ç•«æ ¼ï¼è²éŸ³ Playback 播放æ§åˆ¶ Subtitle 字幕 Font Style 字勿¨£å¼ Restore Defaults é‚„åŸé è¨­å€¼ Open file 開啟檔案 Open next 開啟下一部 Open previous 開啟ä¸ä¸€éƒ¨ Mini mode è¿·ä½ æ¨¡å¼ Mute éœéŸ³ Next frame 下一畫格 Previous frame ä¸ä¸€ç•«æ ¼ Volume down 減å°éŸ³é‡ Volume up 音é‡å¢ Speed up å é€Ÿ Speed down 減速 Fullscreen å…¨è¢å¹• Pause/Play æ«åœï¼æ’­æ”¾ Playlist 播放列表 Reset speed åŸé€Ÿ Rewind 後退 Forward å‰é€² Burst screenshot 影片é è¦½åœ– Film screenshot 影片截圖 0.5s backward 後退 0.5 ç§’ 0.5s forward å‰é€² 0.5 ç§’ Font å­—å‹ Font Size å­—å‹å¤§å° UrlDialog Cancel å–æ¶ˆ Confirm ç¢ºå® Please enter the URL: 輸入 URLï¼ dmr::ActionFactory Settings è¨­å® Fullscreen å…¨è¢å¹• Always on Top æ°¸é ç½®é ‚ Film info å½±ç‰‡è³‡è¨ Open file 開啟檔案 Open folder 開啟資料夾 Light theme 亮色主題 Open URL é–‹å•Ÿç¶²å€ Open CD/DVD 開啟 CD/DVD Mini Mode è¿·ä½ æ¨¡å¼ Play Mode æ’­æ”¾æ¨¡å¼ Order Play é †åºæ’­æ”¾ Shuffle Play 鍿©Ÿæ’­æ”¾ Single Play å–®ç¨æ’­æ”¾ Single Loop å–®ç¨å¾ªç’° List Loop 列表循環 Frame ç•«æ ¼ Default é è¨­ Clockwise é †æ™‚é‡æ—‹è½‰ Counterclockwise é€†æ™‚é‡æ—‹è½‰ Next frame 下一畫格 Previous frame ä¸ä¸€ç•«æ ¼ Sound è²éŸ³ Channel è²é“ Stereo ç«‹é«”è² Left channel å·¦è²é“ Right channel å³è²é“ Track 音軌 Subtitle 字幕 Load 載入 Online Search ç·ä¸æœå°‹ Select 鏿“‡ Hide é±è— Encodings 編碼 Screenshot 截圖 Film Screenshot 影片截圖 Burst Shooting 影片é è¦½åœ– Playlist 播放列表 Film Info å½±ç‰‡è³‡è¨ Clear playlist 清除播放列表 Display in file manager 在檔案管ç†å™¨ä¸­é¡¯ç¤º dmr::BurstScreenshotsDialog Duration: %1 長度ï¼%1 Resolution: %1 è§£æåº¦ï¼%1 Size: %1 大å°ï¼%1 Save 儲存 dmr::MainWindow Load successfully 載入æˆåŸ Load failed 載入失敗 No device found 找ä¸åˆ°è£ç½® Parse Failed è§£æå¤±æ•— Open folder 開啟資料夾 Open file 開啟檔案 All videos (%1) 所有影片 (%1) Muted éœéŸ³ Volume: %1% 音é‡ï¼%1% Subtitle %1: %2s 字幕 %1ï¼%2 ç§’ delayed 後退 advanced å‰é€² Speed: %1x 速度ï¼%1 å€ Subtitle (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) 字幕 (*.ass *.aqt *.jss *.gsub *.ssf *.srt *.sub *.ssa *.smi *.usf *.idx) View ç€è¦½ Movie Screenshot 影片截圖 Saved to 儲存到 The screenshot is saved 截圖已儲存 Failed to save the screenshot 無法儲存è¢å¹•截圖 Invalid file: %1 檔案無效ï¼%1 dmr::MovieInfo %1G %1 G %1M %1 M %1K %1 K %1 %1 dmr::MovieInfoDialog File Type: 檔案é¡å‹ï¼ Resolution: è§£æåº¦ï¼ File Size: 檔案大å°ï¼ Duration: å½±ç‰‡é•·åº¦ï¼ File Path: 檔案ä½ç½®ï¼ dmr::MpvProxy [internal] [內嵌] dmr::PlayItemWidget File does not exist 檔案ä¸å­˜åœ¨ dmr::Settings %1/DMovie%2.jpg %1/Deepin 電影截圖_%2.jpg %1/DMovie%2(%3).jpg %1/Deepin 電影截圖_%2(%3).jpg dmr::ToolboxProxy Play 播放 Previous ä¸ä¸€éƒ¨ Next 下一部 Subtitles 字幕 Playlist 播放列表 Fullscreen å…¨è¢å¹• Play/Pause æ’­æ”¾ï¼æ«åœ Exit fullscreen çµæŸå…¨è¢å¹• Pause æ«åœ deepin-movie-reborn-5.0.0/src/translations/desktop/000077500000000000000000000000001351125414100223405ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/src/translations/desktop/desktop.ts000066400000000000000000000012501351125414100243570ustar00rootroot00000000000000 desktopDeepin MovieMoviePlay your video collectionPlayer;Movie;Theater;Theatre;Video; deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_am_ET.ts000066400000000000000000000013351351125414100254300ustar00rootroot00000000000000desktopDeepin MovieሙቪMoviePlay your video collectionየ á¥áˆ­áˆµá‹á• የ ቪዲዮ ስብስብ ያጫá‹á‰±Player;Movie;Theater;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_ar.ts000066400000000000000000000014111351125414100250400ustar00rootroot00000000000000desktopDeepin MovieØ£Ùلام دÙÙØ¨Ù†MovieالأÙلامPlay your video collectionشغل مجموعة الÙÙØ¯ÙÙˆ الخاصة بكPlayer;Movie;Theater;Theatre;Video;Player;Movie;Theater;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_ast.ts000066400000000000000000000013631351125414100252330ustar00rootroot00000000000000desktopDeepin MovieDeepin MovieMoviePelĂ­culaPlay your video collectionReproduz la to videotecaPlayer;Movie;Theater;Theatre;Video;reproductor;pelĂ­cula;videu;pelĂ­cules;vĂ­deos;theaterdeepin-movie-reborn-5.0.0/src/translations/desktop/desktop_az.ts000066400000000000000000000012751351125414100250600ustar00rootroot00000000000000desktopDeepin MovieDeepin FilmMoviePlay your video collectionVideo kolleksiyavı oynatPlayer;Movie;Theater;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_bg.ts000066400000000000000000000014071351125414100250330ustar00rootroot00000000000000desktopDeepin MovieDeepin Đ¤Đ¸Đ»Đ¼Đ¸MovieĐ¤Đ¸Đ»Đ¼Play your video collectionĐŸÑ€ĐµĐ³Đ»ĐµĐ´ Đ½Đ° Đ²Đ°ÑˆĐ°Ñ‚Đ° Đ²Đ¸Đ´ĐµĐ¾ ĐºĐ¾Đ»ĐµĐºÑ†Đ¸ÑPlayer;Movie;Theater;Theatre;Video;Player;Movie;Theater;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_bn.ts000066400000000000000000000015451351125414100250450ustar00rootroot00000000000000desktopDeepin Movieডিপিন মà§à¦­à¦¿Movieমà§à¦­à¦¿Play your video collectionআপনার ভিডিও কালেকশন à¦à¦¾à¦²à§ করà§à¦¨Player;Movie;Theater;Theatre;Video;পà§à¦²à§‡à§Ÿà¦¾à¦°;মà§à¦­à¦¿;থিয়েটার;থিয়েটার;ভিডিও;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_ca.ts000066400000000000000000000014041351125414100250230ustar00rootroot00000000000000desktopDeepin MoviePel·lĂ­cula del DeepinMoviePel·lĂ­culaPlay your video collectionReproduĂ¯u la col·lecciĂ³ de mĂºsicaPlayer;Movie;Theater;Theatre;Video;Reproductor;Pel·lĂ­cula;Teatre;Cinema;VĂ­deodeepin-movie-reborn-5.0.0/src/translations/desktop/desktop_cs.ts000066400000000000000000000013511351125414100250460ustar00rootroot00000000000000desktopDeepin MovieFilmyMovieFilmPlay your video collectionPÅ™ehrĂ¡vejte svoji sbĂ­rku obrazovĂ½ch zĂ¡znamůPlayer;Movie;Theater;Theatre;Video;PÅ™ehrĂ¡vaÄ;Film;Divadlo;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_da.ts000066400000000000000000000013221351125414100250230ustar00rootroot00000000000000desktopDeepin MovieDeepin filmMovieFilmPlay your video collectionAfspil din videosamlingPlayer;Movie;Theater;Theatre;Video;Afspiller;Film;Biograf;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_de.ts000066400000000000000000000013421351125414100250310ustar00rootroot00000000000000desktopDeepin MovieDeepin FilmMovieFilmPlay your video collectionDer elegante Video-Player!Player;Movie;Theater;Theatre;Video;Player;Filme; Theater;Theatre;Movie;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_el.ts000066400000000000000000000013421351125414100250410ustar00rootroot00000000000000desktopDeepin MovieΤαινίες DeepinMoviePlay your video collectionΠαίξτε τη βίντεο συλλογή σαςPlayer;Movie;Theater;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_en_AU.ts000066400000000000000000000012671351125414100254360ustar00rootroot00000000000000desktopDeepin MovieDeepin MovieMoviePlay your video collectionPlay your videoPlayer;Movie;Theater;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_eo.ts000066400000000000000000000013011351125414100250370ustar00rootroot00000000000000desktopDeepin MovieDeepin FilmujoMoviePlay your video collectionLudi vian videojn kolektonPlayer;Movie;Theater;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_es.ts000066400000000000000000000013741351125414100250550ustar00rootroot00000000000000desktopDeepin MoviePelĂ­culas DeepinMoviePelĂ­culasPlay your video collectionReproducir tu colecciĂ³n de vĂ­deosPlayer;Movie;Theater;Theatre;Video;Reproductor;VĂ­deos;PelĂ­culas; Teatro en casa.deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_es_419.ts000066400000000000000000000013661351125414100254530ustar00rootroot00000000000000desktopDeepin MoviePelĂ­culas DeepinMoviePelĂ­culasPlay your video collectionReproduce tu colecciĂ³n de videosPlayer;Movie;Theater;Theatre;Video;Reproductor; PelĂ­culas; Teatro;Videos;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_fa.ts000066400000000000000000000015261351125414100250330ustar00rootroot00000000000000desktopDeepin MovieDeepin Movie (نرم Ø§ÙØ²Ø§Ø± تماشای Ùیلم دیپین)MovieÙیلمPlay your video collectionمجموعه ویدیویی خود را اجرا کنیدPlayer;Movie;Theater;Theatre;Video;پخش کننده؛ Ùیلم؛ تئاتر؛ تئاتر؛ ویدئو؛deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_fi.ts000066400000000000000000000013331351125414100250370ustar00rootroot00000000000000desktopDeepin MovieDeepin ElokuvatMovieElokuvatPlay your video collectionToistaa videokokoelmasiPlayer;Movie;Theater;Theatre;Video;Soitin;Elokuva;Teatteri;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_fil.ts000066400000000000000000000012711351125414100252140ustar00rootroot00000000000000desktopDeepin MovieDeepin MusicMoviePlay your video collectionManood ng mga videoPlayer;Movie;Theater;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_fr.ts000066400000000000000000000013341351125414100250510ustar00rootroot00000000000000desktopDeepin MovieDeepin MovieMovieVidĂ©oPlay your video collectionLire votre collection de vidĂ©osPlayer;Movie;Theater;Theatre;Video;Lecteur;Film;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_gl_ES.ts000066400000000000000000000013071351125414100254330ustar00rootroot00000000000000desktopDeepin MovieFilmesMoviePlay your video collectionReproduce a tĂºa colecciĂ³n de vĂ­deoPlayer;Movie;Theater;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_he.ts000066400000000000000000000013401351125414100250330ustar00rootroot00000000000000desktopDeepin Movieנגן ×”×¡×¨×˜×™× ×©×œ DeepinMoviePlay your video collectionנגן ×ת ×וסף הויד×ו של×Player;Movie;Theater;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_hi_IN.ts000066400000000000000000000014001351125414100254220ustar00rootroot00000000000000desktopDeepin Movieडीपइन à¤à¤²à¤à¤¿à¤¤à¥à¤°MoviePlay your video collectionअपने वीडियो संगà¥à¤°à¤¹ à¤à¤²à¤¾à¤“Player;Movie;Theater;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_hr.ts000066400000000000000000000013211351125414100250470ustar00rootroot00000000000000desktopDeepin MovieDeepin filmski reproduktorMoviePlay your video collectionIzvodite vaÅ¡u video kolekcijuPlayer;Movie;Theater;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_hu.ts000066400000000000000000000013351351125414100250570ustar00rootroot00000000000000desktopDeepin MovieDeepin FilmMovieFilmPlay your video collectionVideĂ³gyűjtemĂ©ny lejĂ¡tszĂ¡saPlayer;Movie;Theater;Theatre;Video;LejĂ¡tszĂ³;Film;Mozi;Mozi;VideĂ³deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_hy.ts000066400000000000000000000013371351125414100250650ustar00rootroot00000000000000desktopDeepin MovieDeepin Ơ–Ơ«Ơ¬Ơ´Ơ¥Ö€MoviePlay your video collectionƠ†Ơ¾Ơ¡Ơ£Ơ¥Ơ¬ Ơ±Ơ¥Ö€ Ơ¾Ơ«Ơ¤Ơ¥Ơ¸ Ơ°Ơ¡Ơ¾Ơ¡Ö„Ơ¡Ơ®Ơ¸Ö‚Ơ¶Player;Movie;Theater;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_id.ts000066400000000000000000000013371351125414100250410ustar00rootroot00000000000000desktopDeepin MoviePemutar Video DeepinMovieFilmPlay your video collectionMainkan koleksi videoPlayer;Movie;Theater;Theatre;Video;Pemutar;Film;Theater;Theater;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_it.ts000066400000000000000000000013371351125414100250610ustar00rootroot00000000000000desktopDeepin MovieDeepin MovieMovieMoviePlay your video collectionEsegui la tua raccolta videoPlayer;Movie;Theater;Theatre;Video;Player;Movie;Theater;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_ja.ts000066400000000000000000000013331351125414100250330ustar00rootroot00000000000000desktopDeepin MovieDeepinăƒ“ăƒ‡ă‚ªăƒ—ăƒ¬ă‚¤ăƒ¤ăƒ¼MoviePlay your video collectionăƒ“ăƒ‡ă‚ªă‚³ăƒ¬ă‚¯ă‚·ăƒ§ăƒ³ă®å†ç”ŸPlayer;Movie;Theater;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_ko.ts000066400000000000000000000014371351125414100250570ustar00rootroot00000000000000desktopDeepin MovieDeepin ë™́˜́ƒ Movieë™́˜́ƒPlay your video collectionë™́˜́ƒ ́»¬ë ‰́…˜ ́¬́ƒPlayer;Movie;Theater;Theatre;Video;Player;Movie;Theater;Theatre;Video;플레́´́–´;ë™́˜́ƒ;́˜í™”;ê·¹́¥;́˜í™”ê´€;비디́˜¤;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_ku_IQ.ts000066400000000000000000000013141351125414100254500ustar00rootroot00000000000000desktopDeepin MovieDeepin FĂ®lmMoviePlay your video collectionLi koleksiyona xwe ya vĂ®dyoyĂª bixePlayer;Movie;Theater;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_lt.ts000066400000000000000000000014011351125414100250540ustar00rootroot00000000000000desktopDeepin MovieDeepin filmasMovieFilmasPlay your video collectionGroti savo vaizdo kolekcijÄ…Player;Movie;Theater;Theatre;Video;Grotuvas;LeistuvÄ—;Filmas;Kinoteatras;Kinas;Teatras;;Vaizdas;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_mn.ts000066400000000000000000000012631351125414100250550ustar00rootroot00000000000000desktopDeepin MovieĐ”ÑÑĐ¿Đ¸Đ½ ĐĐ¸Đ½Đ¾MoviePlay your video collectionPlayer;Movie;Theater;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_ms.ts000066400000000000000000000013251351125414100250610ustar00rootroot00000000000000desktopDeepin MovieWayang DeepinMovieCerekaPlay your video collectionMain koleksi videoPlayer;Movie;Theater;Theatre;Video;Pemain;Cereka;Wayang;Filem;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_nb.ts000066400000000000000000000012771351125414100250470ustar00rootroot00000000000000desktopDeepin MovieDeepin filmMoviePlay your video collectionSpill av videosamlingen dinPlayer;Movie;Theater;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_ne.ts000066400000000000000000000016011351125414100250410ustar00rootroot00000000000000desktopDeepin Movieडिपिन à¤à¤²à¤à¤¿à¤¤à¥à¤°Movieà¤à¤²à¤à¤¿à¤¤à¥à¤°Play your video collectionआफà¥à¤¨à¥‹ भिडियो संगà¥à¤°à¤¹ पà¥à¤²à¥‡ गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥Player;Movie;Theater;Theatre;Video;पà¥à¤²à¥‡à¤¯à¤°; मूवी; थिà¤à¤Ÿà¤°; थियेटर; भिडियो;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_nl.ts000066400000000000000000000013461351125414100250560ustar00rootroot00000000000000desktopDeepin MovieDeepin Video'sMovieVideoPlay your video collectionSpeel je videoverzameling afPlayer;Movie;Theater;Theatre;Video;Speler;Film;Theater;Bioscoop;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_pl.ts000066400000000000000000000013771351125414100250640ustar00rootroot00000000000000desktopDeepin MovieFilmy DeepinMovieFilmyPlay your video collectionOdtwĂ³rz kolekcjÄ™ filmĂ³wPlayer;Movie;Theater;Theatre;Video;Player;Movie;Theater;Theatre;Video;Odtwarzacz;Filmy;Kino;Teatr;Wideo;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_pt.ts000066400000000000000000000013571351125414100250720ustar00rootroot00000000000000desktopDeepin MovieDeepin MovieMovieFilmePlay your video collectionReproduzir a sua coleĂ§Ă£o de vĂ­deosPlayer;Movie;Theater;Theatre;Video;Reprodutor;Filme;Teatro;Anfiteatro;VĂ­deo;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_pt_BR.ts000066400000000000000000000013531351125414100254510ustar00rootroot00000000000000desktopDeepin MovieVĂ­deos DeepinMovieVĂ­deoPlay your video collectionReproduza sua coleĂ§Ă£o de vĂ­deosPlayer;Movie;Theater;Theatre;Video;Player;Movie;Theater;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_ro.ts000066400000000000000000000013071351125414100250620ustar00rootroot00000000000000desktopDeepin MoviePlayer-ul video DeepinMoviePlay your video collectionRedă colecÈ›ia ta videoPlayer;Movie;Theater;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_ru.ts000066400000000000000000000014261351125414100250720ustar00rootroot00000000000000desktopDeepin MovieĐĐ¸Đ½Đ¾Ñ‚ĐµĐ°Ñ‚Ñ€ DeepinMovieĐĐ¸Đ½Đ¾Ñ‚ĐµĐ°Ñ‚Ñ€Play your video collectionĐŸÑ€Đ¾ÑĐ¼Đ¾Ñ‚Ñ€ Đ²Đ°ÑˆĐµĐ¹ Đ²Đ¸Đ´ĐµĐ¾-ĐºĐ¾Đ»Đ»ĐµĐºÑ†Đ¸Đ¸Player;Movie;Theater;Theatre;Video;Player;Movie;Theater;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_sk.ts000066400000000000000000000013541351125414100250610ustar00rootroot00000000000000desktopDeepin MovieDeepin FilmyMovieFilmPlay your video collectionPrehrĂ¡vajte svoju zbierku video zĂ¡znamovPlayer;Movie;Theater;Theatre;Video;Player;Movie;Theater;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_sl.ts000066400000000000000000000013031351125414100250540ustar00rootroot00000000000000desktopDeepin MovieDeepin FilmiMoviePlay your video collectionPredvajajte svojo video zbirkoPlayer;Movie;Theater;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_sr.ts000066400000000000000000000014341351125414100250670ustar00rootroot00000000000000desktopDeepin MovieĐ”Đ¸Đ¿Đ¸Đ½ Đ¤Đ¸Đ»Đ¼MovieĐ¤Đ¸Đ»Đ¼Play your video collectionĐ“Đ»ĐµĐ´Đ°Ñ˜Ñ‚Đµ Đ²Đ°ÑˆÑƒ Đ²Đ¸Đ´ĐµĐ¾ ĐºĐ¾Đ»ĐµĐºÑ†Đ¸Ñ˜ÑƒPlayer;Movie;Theater;Theatre;Video;ĐŸÑƒÑˆÑ‚Đ°Ñ‡;Đ¤Đ¸Đ»Đ¼;Đ¡Ñ†ĐµĐ½Đ°;Đ‘Đ¸Đ¾ÑĐºĐ¾Đ¿;Đ’Đ¸Đ´ĐµĐ¾;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_sv.ts000066400000000000000000000012711351125414100250720ustar00rootroot00000000000000desktopDeepin MovieDeepin-filmMoviePlay your video collectionSpela din filmsamlingPlayer;Movie;Theater;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_ta.ts000066400000000000000000000013031351125414100250420ustar00rootroot00000000000000desktopDeepin MovieMoviePlay your video collectionபà¯à®¤à¯à®à¯ à®à®¾à®³à®°à®®à¯Player;Movie;Theater;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_tr.ts000066400000000000000000000013751351125414100250740ustar00rootroot00000000000000desktopDeepin MovieDeepin SinemaMovieSinemaPlay your video collectionVideo koleksiyonunuzu oynatınPlayer;Movie;Theater;Theatre;Video;Player;Movie;Theater;Theatre;Video;Sinema;GörĂ¼ntĂ¼;Tiyatro;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_uk.ts000066400000000000000000000015021351125414100250560ustar00rootroot00000000000000desktopDeepin MovieĐ’Ñ–Đ´ĐµĐ¾ DeepinMovieĐ’Ñ–Đ´ĐµĐ¾Play your video collectionĐ’Ñ–Đ´Ñ‚Đ²Đ¾Ñ€Đ¸Ñ‚Đ¸ ĐºĐ¾Đ»ĐµĐºÑ†Ñ–Ñ Đ²Ñ–Đ´ĐµĐ¾Player;Movie;Theater;Theatre;Video;Player;Movie;Theater;Theatre;Video;Đ¿Ñ€Đ¾Đ³Ñ€Đ°Đ²Đ°Ñ‡;Đ²Ñ–Đ´ĐµĐ¾;Ñ„Ñ–Đ»ÑŒĐ¼;ĐºÑ–Đ½Đ¾Ñ‚ĐµĐ°Ñ‚Ñ€;ĐºÑ–Đ½Đ¾;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_vi.ts000066400000000000000000000012641351125414100250620ustar00rootroot00000000000000desktopDeepin MovieTrình xem phim DeepinMoviePlay your video collectionPlayer;Movie;Theater;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_zh_CN.ts000066400000000000000000000013471351125414100254470ustar00rootroot00000000000000desktopDeepin Movie深度影院Movie影院Play your video collection为您播放本地å网络视频Player;Movie;Theater;Theatre;Video;播放器;电影;电影院;视频;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_zh_HK.ts000066400000000000000000000013011351125414100254370ustar00rootroot00000000000000desktopDeepin MovieDeepin 電影MoviePlay your video collection播放你收è—ç„影片Player;Movie;Theater;Theatre;Video;deepin-movie-reborn-5.0.0/src/translations/desktop/desktop_zh_TW.ts000066400000000000000000000013761351125414100255030ustar00rootroot00000000000000desktopDeepin MovieDeepin 電影Movie電影Play your video collection播放您ç„影片集åˆPlayer;Movie;Theater;Theatre;Video;Player;Movie;Theater;Theatre;Video;播放器;電影;å‡é™¢;影片deepin-movie-reborn-5.0.0/src/widgets/000077500000000000000000000000001351125414100176145ustar00rootroot00000000000000deepin-movie-reborn-5.0.0/src/widgets/burst_screenshots_dialog.cpp000066400000000000000000000152231351125414100254210ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "player_engine.h" #include "burst_screenshots_dialog.h" #include "dmr_settings.h" #include "utils.h" #include DWIDGET_USE_NAMESPACE namespace dmr { BurstScreenshotsDialog::BurstScreenshotsDialog(const PlayItemInfo& pif) :DDialog(nullptr) { auto mi = pif.mi; auto *ml = new QVBoxLayout; ml->setContentsMargins(0, 10, 0, 0); ml->setSpacing(0); setFixedSize(600, 704); // top auto *hl = new QHBoxLayout(); hl->setContentsMargins(0, 0, 0, 0); ml->addLayout(hl); auto *pm = new QLabel(this); auto dpr = qApp->devicePixelRatio(); pm->setFixedSize(44, 44); pm->setScaledContents(true); QPixmap img = QPixmap::fromImage(utils::LoadHiDPIImage(":/resources/icons/logo-big.svg")); pm->setPixmap(img); hl->setAlignment(pm, Qt::AlignCenter); hl->addWidget(pm); hl->addSpacing(16); // top right up auto *trl = new QVBoxLayout; trl->setSpacing(0); hl->setContentsMargins(0, 0, 0, 0); hl->addLayout(trl, 1); QFont ft; ft.setPixelSize(14); QFontMetrics fm(ft); auto *nm = new QLabel(this); nm->setStyleSheet("color: #303030; font-size: 14px;"); nm->setText(fm.elidedText(mi.title, Qt::ElideMiddle, 480)); trl->addWidget(nm); //top right bottom auto *trb = new QHBoxLayout; trb->setContentsMargins(0, 0, 0, 0); trb->setSpacing(0); { auto lb = new QLabel(tr("Duration: %1").arg(mi.durationStr()), this); lb->setStyleSheet("color: rgba(48, 48, 48, 60%); font-size: 12px;"); trb->addWidget(lb); trb->addSpacing(36); } { auto lb = new QLabel(tr("Resolution: %1").arg(mi.resolution), this); lb->setStyleSheet("color: rgba(48, 48, 48, 60%); font-size: 12px;"); trb->addWidget(lb); trb->addSpacing(36); } { auto lb = new QLabel(tr("Size: %1").arg(mi.sizeStr()), this); lb->setStyleSheet("color: rgba(48, 48, 48, 60%); font-size: 12px;"); trb->addWidget(lb); trb->addSpacing(36); } trb->addStretch(1); trl->addLayout(trb); ml->addSpacing(20); _grid = new QGridLayout(); _grid->setHorizontalSpacing(12); _grid->setVerticalSpacing(15); _grid->setContentsMargins(0, 0, 0, 0); ml->addLayout(_grid); _grid->setColumnMinimumWidth(0, 160); _grid->setColumnMinimumWidth(1, 160); _grid->setColumnMinimumWidth(2, 160); auto *bl = new QHBoxLayout; bl->setContentsMargins(0, 13, 0, 0); bl->addStretch(1); _saveBtn = new QPushButton(tr("Save")); _saveBtn->setObjectName("SaveBtn"); connect(_saveBtn, &QPushButton::clicked, this, &BurstScreenshotsDialog::savePoster); _saveBtn->setFixedSize(61, 24); QString addition = R"( QPushButton#SaveBtn { font-size: 12px; color: #2ca7f8; border: 1px solid #2ca7f8; border-radius: 4px; background: qlineargradient(x1: 0, y1: 0 x2: 0, y2: 1, stop:0 rgba(255, 255, 255, 0.4), stop:1 rgba(253, 253, 253, 0.4)); } QPushButton#SaveBtn:hover { background: qlineargradient(x1: 0, y1: 0 x2: 0, y2: 1, stop:0 "#8ccfff", stop:1 "#4bb8ff"); color: "#fff"; border: 1px solid rgba(0, 117, 243, 0.2); } QPushButton#SaveBtn:pressed { background: qlineargradient(x1: 0, y1: 0 x2: 0, y2: 1, stop:0 "#0b8cff", stop:1 "#0aa1ff"); color: "#fff"; border: 1px solid rgba(29, 129, 255, 0.3); } QPushButton#SaveBtn:disabled { background: qlineargradient(x1: 0, y1: 0 x2: 0, y2: 1, stop:0 rgba(255, 255, 255, 0.4), stop:1 rgba(253, 253, 253, 0.4)); color: "#AEAEAE"; border: 1px solid rgba(0,0,0,0.04); } )"; _saveBtn->setDefault(true); _saveBtn->setStyleSheet(addition); bl->addWidget(_saveBtn); ml->addLayout(bl); QWidget *mainContent = new QWidget; mainContent->setLayout(ml); addContent(mainContent, Qt::AlignCenter); } void BurstScreenshotsDialog::updateWithFrames(const QList>& frames) { auto dpr = qApp->devicePixelRatio(); QSize sz(178 * dpr, 100 * dpr); int count = 0; for (auto frame: frames) { auto scaled = frame.first.scaled(sz.width()-2, sz.height()-2, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); auto *l = new ThumbnailFrame(this); int r = count / 3; int c = count % 3; auto pm = QPixmap::fromImage(scaled); pm.setDevicePixelRatio(dpr); pm = utils::MakeRoundedPixmap(sz, pm, 2, 2, frame.second); l->setPixmap(pm); _grid->addWidget(l, r, c); count++; } _thumbs = frames; } int BurstScreenshotsDialog::exec() { return DDialog::exec(); } void BurstScreenshotsDialog::savePoster() { auto img = this->grab(rect().marginsRemoved(QMargins(10, 20, 10, 42))); _posterPath = Settings::get().screenshotNameTemplate(); img.save(_posterPath); DDialog::accept(); } void BurstScreenshotsDialog::saveShootings() { int i = 1; for (auto& img: _thumbs) { auto file_path = Settings::get().screenshotNameSeqTemplate().arg(i++); img.first.save(file_path); } DDialog::accept(); } QString BurstScreenshotsDialog::savedPosterPath() { return _posterPath; } } deepin-movie-reborn-5.0.0/src/widgets/burst_screenshots_dialog.h000066400000000000000000000050451351125414100250670ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_BURST_SCREENSHOTS_DIALOG_H #define _DMR_BURST_SCREENSHOTS_DIALOG_H #include #include #include DWIDGET_USE_NAMESPACE namespace dmr { class PlayerEngine; class PlayItemInfo; class ThumbnailFrame: public QLabel { Q_OBJECT public: ThumbnailFrame(QWidget* parent) :QLabel(parent) { setFixedSize(178, 100); auto e = new QGraphicsDropShadowEffect(this); e->setColor(QColor(0, 0, 0, 255 * 2 / 10)); e->setOffset(0, 2); e->setBlurRadius(4); setGraphicsEffect(e); } }; class BurstScreenshotsDialog: public DDialog { Q_OBJECT public: BurstScreenshotsDialog(const PlayItemInfo& pif); void updateWithFrames(const QList>& frames); QString savedPosterPath(); public slots: int exec() override; void saveShootings(); void savePoster(); private: QGridLayout *_grid {nullptr}; QPushButton *_saveBtn {nullptr}; QList> _thumbs; QString _posterPath; }; } #endif /* ifndef _DMR_BURST_SCREENSHOTS_DIALOG_H */ deepin-movie-reborn-5.0.0/src/widgets/dmr_lineedit.cpp000066400000000000000000000047511351125414100227660ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "dmr_lineedit.h" namespace dmr { LineEdit::LineEdit(QWidget* parent) :QLineEdit(parent) { setFixedHeight(20); setStyleSheet(R"( QLineEdit { font-size: 11px; border-radius: 3px; background-color: #ffffff; border: 1px solid rgba(0, 0, 0, 0.08); color: #303030; } )"); QIcon icon; icon.addFile(":/resources/icons/input_clear_normal.svg", QSize(), QIcon::Normal); icon.addFile(":/resources/icons/input_clear_press.svg", QSize(), QIcon::Selected); icon.addFile(":/resources/icons/input_clear_hover.svg", QSize(), QIcon::Active); _clearAct = new QAction(icon, "", this); connect(_clearAct, &QAction::triggered, this, &QLineEdit::clear); connect(this, &QLineEdit::textChanged, [=](const QString& s) { if (s.isEmpty()) { removeAction(_clearAct); } else { addAction(_clearAct, QLineEdit::TrailingPosition); } }); } void LineEdit::showEvent(QShowEvent* se) { } void LineEdit::resizeEvent(QResizeEvent* re) { } } deepin-movie-reborn-5.0.0/src/widgets/dmr_lineedit.h000066400000000000000000000034741351125414100224340ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #pragma once #include #include #include DWIDGET_USE_NAMESPACE namespace dmr { class LineEdit: public QLineEdit { public: LineEdit(QWidget* p = 0); protected: void showEvent(QShowEvent* se) override; void resizeEvent(QResizeEvent* re) override; private: QAction *_clearAct {nullptr}; }; } deepin-movie-reborn-5.0.0/src/widgets/movie_progress_indicator.cpp000066400000000000000000000053211351125414100254200ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "movie_progress_indicator.h" namespace dmr { MovieProgressIndicator::MovieProgressIndicator(QWidget* parent) :QFrame(parent) { QFont ft; ft.setPixelSize(14); QFontMetrics fm(ft); this->setFont(ft); _fixedSize = QSize(qMax(52, fm.width("999:99")), fm.height() + 10); this->setFixedSize(_fixedSize); } void MovieProgressIndicator::paintEvent(QPaintEvent* pe) { auto time_text = QTime::currentTime().toString("hh:mm"); QPainter p(this); p.setFont(font()); p.setPen(QColor(255, 255, 255, 255 * .4)); QFontMetrics fm(font()); auto fr = fm.boundingRect(time_text); fr.moveCenter(QPoint(rect().center().x(), fr.height()/2)); p.drawText(fr, time_text); QPoint pos((_fixedSize.width() - 48)/2, rect().height() - 5); int pert = qMin(_pert * 10, 10.0); for (int i = 0; i < 10; i++) { if (i >= pert) { p.fillRect(QRect(pos, QSize(3, 3)), QColor(255, 255, 255, 255 * .25)); } else { p.fillRect(QRect(pos, QSize(3, 3)), QColor(255, 255, 255, 255 * .5)); } pos.rx() += 5; } } void MovieProgressIndicator::updateMovieProgress(qint64 duration, qint64 pos) { _elapsed = pos; _pert = (qreal)pos / duration; update(); } } deepin-movie-reborn-5.0.0/src/widgets/movie_progress_indicator.h000066400000000000000000000037221351125414100250700ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_MOVIE_PROGRESS_INDICATOR_H #define _DMR_MOVIE_PROGRESS_INDICATOR_H #include namespace dmr { class MovieProgressIndicator: public QFrame { Q_OBJECT public: MovieProgressIndicator(QWidget* parent); public slots: void updateMovieProgress(qint64 duration, qint64 pos); protected: void paintEvent(QPaintEvent* pe) override; private: qint64 _elapsed {0}; qreal _pert {0.0}; QSize _fixedSize; }; } #endif /* ifndef _DMR_MOVIE_PROGRESS_INDICATOR_H */ deepin-movie-reborn-5.0.0/src/widgets/movieinfo_dialog.cpp000066400000000000000000000114631351125414100236370ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "movieinfo_dialog.h" #include "mpv_proxy.h" #include "playlist_model.h" #include "utils.h" #include #include DWIDGET_USE_NAMESPACE namespace dmr { MovieInfoDialog::MovieInfoDialog(const struct PlayItemInfo& pif) :DAbstractDialog(nullptr) { setFixedWidth(320); setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); auto layout = new QVBoxLayout(this); layout->setSpacing(0); layout->setContentsMargins(0, 0, 0, 10); setLayout(layout); auto closeBt = new DWindowCloseButton; closeBt->setFixedSize(27, 23); layout->addWidget(closeBt, 0, Qt::AlignTop | Qt::AlignRight); layout->addSpacing(26); connect(closeBt, &DWindowCloseButton::clicked, this, &DAbstractDialog::hide); const auto& mi = pif.mi; auto *ml = new QVBoxLayout; ml->setContentsMargins(10, 0, 10, 0); ml->setSpacing(0); layout->addLayout(ml); auto *pm = new PosterFrame(this); pm->setFixedSize(176, 118); auto dpr = qApp->devicePixelRatio(); QPixmap cover; if (pif.thumbnail.isNull()) { cover = (utils::LoadHiDPIPixmap(":/resources/icons/logo-big.svg")); } else { QSize sz(176, 118); sz *= dpr; auto img = pif.thumbnail.scaledToWidth(sz.width(), Qt::SmoothTransformation); cover = img.copy(0, (img.height()-sz.height())/2, sz.width(), sz.height()); cover.setDevicePixelRatio(dpr); } cover = utils::MakeRoundedPixmap(cover, 4, 4); pm->setPixmap(cover); pm->ensurePolished(); ml->addWidget(pm); ml->setAlignment(pm, Qt::AlignHCenter); ml->addSpacing(19); auto *nm = new QLabel(this); nm->setObjectName("MovieInfoTitle"); nm->setText(nm->fontMetrics().elidedText(QFileInfo(mi.filePath).fileName(), Qt::ElideMiddle, 260)); ml->addWidget(nm); ml->setAlignment(nm, Qt::AlignHCenter); ml->addSpacing(19); auto *sp = new QFrame(this); sp->setObjectName("MovieInfoSplit"); sp->setFixedHeight(1); ml->addWidget(sp); ml->addSpacing(10); auto *form = new QFormLayout(); form->setContentsMargins(25, 0, 25, 0); ml->addLayout(form); ml->setAlignment(ml, Qt::AlignHCenter); form->setVerticalSpacing(10); form->setHorizontalSpacing(10); form->setLabelAlignment(Qt::AlignRight); form->setFormAlignment(Qt::AlignCenter); #define ADD_ROW(title, field) do { \ auto f = new QLabel(field, this); \ f->setObjectName("MovieInfoValue"); \ f->setWordWrap(true); \ auto t = new QLabel((title), this); \ t->setObjectName("MovieInfoKey"); \ form->addRow(t, f); \ } while (0) ADD_ROW(tr("File Type:"), mi.fileType); ADD_ROW(tr("Resolution:"), mi.resolution); ADD_ROW(tr("File Size:"), mi.sizeStr()); ADD_ROW(tr("Duration:"), mi.durationStr()); auto fm = nm->fontMetrics(); auto fp = utils::ElideText(mi.filePath, {160, 40}, QTextOption::WrapAnywhere, nm->font(), Qt::ElideMiddle, fm.height(), 150); ADD_ROW(tr("File Path:"), fp); #undef ADD_ROW ml->addSpacing(16); #if DTK_VERSION > DTK_VERSION_CHECK(2, 0, 6, 0) DThemeManager::instance()->setTheme(this, "light"); DThemeManager::instance()->setTheme(closeBt, "light"); #else DThemeManager::instance()->registerWidget(this); closeBt->setStyleSheet(DThemeManager::instance()->getQssForWidget("DWindowCloseButton", "light")); #endif } } deepin-movie-reborn-5.0.0/src/widgets/movieinfo_dialog.h000066400000000000000000000041321351125414100232770ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_MOVIE_INFO_DIALOG_H #define _DMR_MOVIE_INFO_DIALOG_H #include #include DWIDGET_USE_NAMESPACE namespace dmr { struct PlayItemInfo; class PosterFrame: public QLabel { Q_OBJECT public: PosterFrame(QWidget* parent) :QLabel(parent) { auto e = new QGraphicsDropShadowEffect(this); e->setColor(QColor(0, 0, 0, 76)); e->setOffset(0, 3); e->setBlurRadius(6); setGraphicsEffect(e); } }; class MovieInfoDialog: public DAbstractDialog { Q_OBJECT public: MovieInfoDialog(const struct PlayItemInfo&); }; } #endif /* ifndef _DMR_MOVIE_INFO_DIALOG_H */ deepin-movie-reborn-5.0.0/src/widgets/notification_widget.cpp000066400000000000000000000121251351125414100243520ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "notification_widget.h" #include "utility.h" #include "event_relayer.h" #include #include #include namespace dmr { NotificationWidget::NotificationWidget(QWidget *parent) :QFrame(parent), _mw(parent) { DThemeManager::instance()->registerWidget(this); //setFrameShape(QFrame::NoFrame); setObjectName("NotificationFrame"); _layout = new QHBoxLayout; _layout->setContentsMargins(0, 0, 0, 0); setLayout(_layout); _msgLabel = new QLabel(); _msgLabel->setFrameShape(QFrame::NoFrame); _timer = new QTimer(this); _timer->setInterval(2000); _timer->setSingleShot(true); connect(_timer, &QTimer::timeout, [=]() {this->hide();}); } void NotificationWidget::showEvent(QShowEvent *event) { ensurePolished(); if (_layout->indexOf(_icon) == -1) { resize(_msgLabel->sizeHint().width() + _layout->contentsMargins().left() + _layout->contentsMargins().right(), height()); adjustSize(); } syncPosition(); } void NotificationWidget::resizeEvent(QResizeEvent *re) { } void NotificationWidget::syncPosition() { auto geom = _mw->geometry(); switch (_anchor) { case AnchorBottom: move(geom.center().x() - size().width()/2, geom.bottom() - _anchorDist - height()); break; case AnchorNorthWest: move(_anchorPoint); break; case AnchorNone: move(geom.center().x() - size().width()/2, geom.center().y() - size().height()/2); break; } } void NotificationWidget::popupWithIcon(const QString& msg, const QPixmap& pm) { if (!_icon) { _icon = new QLabel; _icon->setFrameShape(QFrame::NoFrame); } _icon->setPixmap(pm); _layout->setContentsMargins(12, 6, 12, 6); if (_layout->indexOf(_icon) == -1) _layout->addWidget(_icon); if (_layout->indexOf(_msgLabel) == -1) _layout->addWidget(_msgLabel, 1); setFixedHeight(40); _layout->update(); _msgLabel->setText(msg); show(); raise(); _timer->start(); } void NotificationWidget::popup(const QString& msg) { _layout->setContentsMargins(14, 4, 14, 4); if (_layout->indexOf(_msgLabel) == -1) { _layout->addWidget(_msgLabel); } setFixedHeight(30); _msgLabel->setText(msg); show(); raise(); _timer->start(); } void NotificationWidget::updateWithMessage(const QString& newMsg) { QFont ft; ft.setPixelSize(12); QFontMetrics fm(ft); auto msg = fm.elidedText(newMsg, Qt::ElideMiddle, _mw->width() - 12 - 12 - 60); if (isVisible()) { _msgLabel->setText(msg); resize(_msgLabel->sizeHint().width() + _layout->contentsMargins().left() + _layout->contentsMargins().right(), height()); adjustSize(); _timer->start(); } else { popup(msg); } } void NotificationWidget::paintEvent(QPaintEvent* pe) { float RADIUS = 4; QPainter p(this); p.setRenderHint(QPainter::Antialiasing); bool light = ("light" == qApp->theme()); auto bg_clr = QColor(23, 23, 23, 255 * 8 / 10); auto border_clr = QColor(255, 255, 255, 25); if (light) { bg_clr = QColor(252, 252, 252, 255 * 8 / 10); border_clr = QColor(0, 0, 0, 25); } p.fillRect(rect(), Qt::transparent); { QPainterPath pp; pp.addRoundedRect(rect(), RADIUS, RADIUS); p.setPen(border_clr); p.drawPath(pp); } auto view_rect = rect().marginsRemoved(QMargins(1, 1, 1, 1)); QPainterPath pp; pp.addRoundedRect(view_rect, RADIUS, RADIUS); p.fillPath(pp, bg_clr); } } deepin-movie-reborn-5.0.0/src/widgets/notification_widget.h000066400000000000000000000052461351125414100240250ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_NOTIFICATION_WIDGET_H #define _DMR_NOTIFICATION_WIDGET_H #include #include DWIDGET_USE_NAMESPACE namespace dmr { class NotificationWidget: public QFrame { Q_OBJECT public: enum MessageAnchor { AnchorNone, AnchorBottom, AnchorNorthWest }; NotificationWidget(QWidget *parent = 0); void setAnchor(MessageAnchor ma) { _anchor = ma; } void setAnchorDistance(int v) { _anchorDist = v; } void setAnchorPoint(const QPoint& p) { _anchorPoint = p; } public slots: void popupWithIcon(const QString& msg, const QPixmap&); void popup(const QString& msg); void updateWithMessage(const QString& newMsg); protected: void showEvent(QShowEvent *event) override; void resizeEvent(QResizeEvent *re) override; void paintEvent(QPaintEvent* pe) override; private: QWidget *_mw {nullptr}; QLabel *_msgLabel {nullptr}; QLabel *_icon {nullptr}; QTimer *_timer {nullptr}; QFrame *_frame {nullptr}; QHBoxLayout *_layout {nullptr}; MessageAnchor _anchor {AnchorNone}; int _anchorDist {10}; QPoint _anchorPoint; void syncPosition(); }; } #endif /* ifndef _DMR_NOTIFICATION_WIDGET_H */ deepin-movie-reborn-5.0.0/src/widgets/playlist_widget.cpp000066400000000000000000000621331351125414100235310ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "playlist_widget.h" #include "playlist_model.h" #include "compositing_manager.h" #include "player_engine.h" #include "toolbox_proxy.h" #include "actions.h" #include "mainwindow.h" #include "utils.h" #include "movieinfo_dialog.h" #include "tip.h" #include #include #include #include #define PLAYLIST_FIXED_WIDTH 220 #define POPUP_DURATION 200 namespace dmr { QString splitText(const QString &text, int width, QTextOption::WrapMode wordWrap, const QFont& font, int lineHeight) { int height = 0; QTextLayout textLayout(text); QString str; textLayout.setFont(font); const_cast(&textLayout.textOption())->setWrapMode(wordWrap); textLayout.beginLayout(); QTextLine line = textLayout.createLine(); while (line.isValid()) { height += lineHeight; line.setLineWidth(width); const QString &tmp_str = text.mid(line.textStart(), line.textLength()); if (tmp_str.indexOf('\n')) height += lineHeight; str += tmp_str; line = textLayout.createLine(); if(line.isValid()) str.append("\n"); } textLayout.endLayout(); return str; } class PlayItemTooltipHandler: public QObject { public: PlayItemTooltipHandler(QObject *parent): QObject(parent) {} protected: bool eventFilter(QObject *obj, QEvent *event) { switch (event->type()) { case QEvent::ToolTip: { QHelpEvent *he = static_cast(event); auto tip = obj->property("HintWidget").value(); auto item = tip->property("for").value(); auto lb = tip->findChild("TipText"); lb->setAlignment(Qt::AlignLeft); auto msg = splitText(item->toolTip(), 200, QTextOption::WordWrap, lb->font(), lb->fontMetrics().height()); lb->setText(msg); tip->show(); tip->adjustSize(); tip->raise(); auto pos = he->globalPos() + QPoint{0, 10}; auto dw = qApp->desktop()->availableGeometry(item).width(); if (pos.x() + tip->width() > dw) { pos.rx() = dw - tip->width(); } tip->move(pos); return true; } case QEvent::Leave: { auto tip = obj->property("HintWidget").value(); tip->hide(); event->ignore(); } default: break; } // standard event processing return QObject::eventFilter(obj, event); } }; enum ItemState { Normal, Playing, Invalid, // gets deleted or similar }; class PlayItemWidget: public QFrame { Q_OBJECT Q_PROPERTY(QString bg READ getBg WRITE setBg DESIGNABLE true) public: friend class PlaylistWidget; PlayItemWidget(const PlayItemInfo& pif, QListWidget* list = 0) : QFrame(), _pif {pif}, _listWidget {list} { DThemeManager::instance()->registerWidget(this, QStringList() << "PlayItemThumb"); setProperty("PlayItemThumb", "true"); setState(ItemState::Normal); setFrameShape(QFrame::NoFrame); auto kd = "local"; if (!_pif.url.isLocalFile()) { if (_pif.url.scheme().startsWith("dvd")) { kd = "dvd"; } else { kd = "network"; } } setProperty("ItemKind", kd); // it's the same for all themes _play = QPixmap(":/resources/icons/dark/normal/film-top.svg"); _play.setDevicePixelRatio(qApp->devicePixelRatio()); setFixedSize(PLAYLIST_FIXED_WIDTH, 68); auto *l = new QHBoxLayout(this); l->setContentsMargins(10, 0, 16, 0); l->setSpacing(10); setLayout(l); _thumb = new QLabel(this); l->addWidget(_thumb); auto *vl = new QVBoxLayout; vl->setContentsMargins(0, 0, 0, 0); vl->setSpacing(0); l->addLayout(vl, 10); vl->addStretch(); _name = new QTextEdit(this); _name->setProperty("Name", true); _name->setReadOnly(true); _name->setAcceptRichText(false); _name->setWordWrapMode(QTextOption::WrapAnywhere); _name->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); _name->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); _name->setFrameShape(QFrame::NoFrame); _name->setTextInteractionFlags(Qt::NoTextInteraction); _name->installEventFilter(this); vl->addWidget(_name); _time = new QLabel(this); _time->setProperty("Time", true); _time->setText(_pif.mi.durationStr()); if (!_pif.valid) { setState(ItemState::Invalid); _time->setText(tr("File does not exist")); } vl->addWidget(_time); vl->addStretch(); setBg(QString(":/resources/icons/%1/normal/film-bg.svg").arg(qApp->theme())); _closeBtn = new DImageButton(this); _closeBtn->setFixedSize(20, 20); _closeBtn->setObjectName("CloseBtn"); _closeBtn->hide(); connect(_closeBtn, &DImageButton::clicked, this, &PlayItemWidget::closeButtonClicked); setToolTip(_pif.mi.title); auto th = new PlayItemTooltipHandler(this); auto t = new Tip(QPixmap(), _pif.mi.title, NULL); t->setWindowFlags(Qt::ToolTip|Qt::CustomizeWindowHint); t->setAttribute(Qt::WA_TranslucentBackground); t->setMaximumWidth(200); t->setProperty("for", QVariant::fromValue(this)); t->layout()->setContentsMargins(0, 7, 0, 7); t->hide(); setProperty("HintWidget", QVariant::fromValue(t)); installEventFilter(th); } void updateInfo(const PlayItemInfo& pif) { _pif = pif; _time->setText(_pif.mi.durationStr()); setToolTip(_pif.mi.title); updateNameText(); if (!_pif.valid) { setState(ItemState::Invalid); _time->setText(tr("File does not exist")); } setStyleSheet(styleSheet()); } void setState(ItemState is) { setProperty("ItemState", is); } ItemState state() const { return (ItemState)property("ItemState").toInt(); } QString getBg() const { return _bg; } void setBg(const QString& s) { _bg = s; auto dpr = qApp->devicePixelRatio(); QPixmap pm = QPixmap::fromImage(utils::LoadHiDPIImage(s)); QPixmap dest(pm.size()); dest.setDevicePixelRatio(dpr); dest.fill(Qt::transparent); QPainter p(&dest); if (state() == ItemState::Invalid) { p.setOpacity(0.5); } // thumb size QSize sz(22, 40); sz *= dpr; p.drawPixmap(0, 0, pm); if (!_pif.thumbnail.isNull()) { auto img = _pif.thumbnail.scaledToHeight(sz.height(), Qt::SmoothTransformation); img.setDevicePixelRatio(dpr); QPointF target_pos((pm.width() - sz.width())/2, (pm.height() - sz.height())/2); target_pos /= dpr; QRectF src_rect((img.width()-sz.width())/2, (img.height()-sz.height())/2, sz.width(), sz.height()); p.drawPixmap(target_pos, img, src_rect); } if (state() == ItemState::Playing) { QPointF pos((pm.width() - _play.width())/2, (pm.height() - _play.height())/2); pos /= dpr; p.drawPixmap(pos, _play); } p.end(); _thumb->setPixmap(dest); } void setHovered(bool v) { if (_hovered != v) { _hovered = v; setProperty("hovered", v); setStyleSheet(styleSheet()); } } signals: void closeButtonClicked(); void doubleClicked(); protected: void updateClosePosition() { auto margin = 4; auto pl = dynamic_cast(parentWidget()->parentWidget()); if (pl->verticalScrollBar()->isVisible()) margin = 10; _closeBtn->move(PLAYLIST_FIXED_WIDTH - _closeBtn->width() - margin, (height() - _closeBtn->height())/2); } void leaveEvent(QEvent* e) override { _closeBtn->hide(); setHovered(false); } void enterEvent(QEvent* e) override { _closeBtn->show(); _closeBtn->raise(); updateClosePosition(); setHovered(true); } bool eventFilter(QObject *obj, QEvent *e) override { if (e->type() == QEvent::MouseButtonDblClick) { doDoubleClick(); return true; } return QWidget::eventFilter(obj, e); } void resizeEvent(QResizeEvent* re) override { updateClosePosition(); } bool event(QEvent *ee) override { if(ee->type() == QEvent::Resize) { int text_height = _name->document()->size().height(); _name->setFixedHeight(text_height); } if (ee->type() == QEvent::Move) { _closeBtn->hide(); if (isVisible()) { auto pos = _listWidget->mapFromGlobal(QCursor::pos()); auto r = QRect(mapTo(_listWidget, QPoint()), size()); if (r.contains(pos)) { _closeBtn->show(); _closeBtn->raise(); } } } return QFrame::event(ee); } void updateNameText() { _name->setText(utils::ElideText(_pif.mi.title, {136, 40}, QTextOption::WrapAnywhere, _name->font(), Qt::ElideMiddle, 18, 136-10)); _name->viewport()->setCursor(Qt::ArrowCursor); _name->setCursor(Qt::ArrowCursor); _name->document()->setDocumentMargin(0.0); int text_height = _name->document()->size().height(); _name->setFixedHeight(text_height); } void showEvent(QShowEvent *se) override { updateNameText(); QTimer::singleShot(0, [=]() { auto pos = _listWidget->mapFromGlobal(QCursor::pos()); auto r = QRect(mapTo(_listWidget, QPoint()), size()); if (r.contains(pos)) { _closeBtn->show(); _closeBtn->raise(); updateClosePosition(); } }); } void mouseDoubleClickEvent(QMouseEvent* me) override { doDoubleClick(); } void doDoubleClick() { //FIXME: there is an potential inconsistency with model if pif did changed //(i.e gets deleted). _pif.refresh(); _time->setText(_pif.mi.durationStr()); if (!_pif.valid) { setState(ItemState::Invalid); _time->setText(tr("File does not exist")); } setStyleSheet(styleSheet()); if (!_pif.url.isLocalFile() || _pif.info.exists()) { emit doubleClicked(); } } private: QString _bg; QLabel *_thumb; QTextEdit *_name; QLabel *_time; QPixmap _play; PlayItemInfo _pif; DImageButton *_closeBtn; QListWidget *_listWidget {nullptr}; bool _hovered {false}; }; class MainWindowListener: public QObject { public: MainWindowListener(QObject *parent): QObject(parent) {} protected: bool eventFilter(QObject *obj, QEvent *event) { if (event->type() == QEvent::MouseButtonPress) { QMouseEvent *me = static_cast(event); if (me->buttons() == Qt::LeftButton) { auto *plw = dynamic_cast(parent()); auto *mw = dynamic_cast(plw->parent()); if (mw->insideResizeArea(me->globalPos())) return false; if (plw->state() == PlaylistWidget::Opened && !plw->underMouse()) { mw->requestAction(ActionFactory::ActionKind::TogglePlaylist); } } return false; } else { // standard event processing return QObject::eventFilter(obj, event); } } }; PlaylistWidget::PlaylistWidget(QWidget *mw, PlayerEngine *mpv) :QListWidget(mw), _engine(mpv), _mw(static_cast(mw)) { DThemeManager::instance()->registerWidget(this); bool composited = CompositingManager::get().composited(); setAttribute(Qt::WA_TranslucentBackground, false); //NOTE: set fixed will affect geometry animation //setFixedWidth(220); setFrameShape(QFrame::NoFrame); setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred)); setSelectionMode(QListView::SingleSelection); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setResizeMode(QListView::Adjust); setDragDropMode(QListView::InternalMove); setSpacing(0); //setAcceptDrops(true); viewport()->setAcceptDrops(true); setDragEnabled(true); setContentsMargins(0, 0, 0, 0); if (!composited) { setWindowFlags(Qt::FramelessWindowHint|Qt::BypassWindowManagerHint); setAttribute(Qt::WA_NativeWindow); } #ifndef USE_DXCB auto *mwl = new MainWindowListener(this); mw->installEventFilter(mwl); #endif if (!_closeMapper) { _closeMapper = new QSignalMapper(this); connect(_closeMapper, static_cast(&QSignalMapper::mapped), [=](QWidget* w) { qDebug() << "item close clicked"; _clickedItem = w; _mw->requestAction(ActionFactory::ActionKind::PlaylistRemoveItem); }); } if (!_activateMapper) { _activateMapper = new QSignalMapper(this); connect(_activateMapper, static_cast(&QSignalMapper::mapped), [=](QWidget* w) { qDebug() << "item double clicked"; QList args; for (int i = 0; i < count(); i++) { if (w == itemWidget(item(i))) { args << i; _mw->requestAction(ActionFactory::ActionKind::GotoPlaylistSelected, false, args); break; } } }); } connect(&_engine->playlist(), &PlaylistModel::emptied, this, &PlaylistWidget::clear); connect(&_engine->playlist(), &PlaylistModel::itemsAppended, this, &PlaylistWidget::appendItems); connect(&_engine->playlist(), &PlaylistModel::itemRemoved, this, &PlaylistWidget::removeItem); connect(&_engine->playlist(), &PlaylistModel::currentChanged, this, &PlaylistWidget::updateItemStates); connect(&_engine->playlist(), &PlaylistModel::itemInfoUpdated, this, &PlaylistWidget::updateItemInfo); QTimer::singleShot(10, this, &PlaylistWidget::loadPlaylist); connect(ActionFactory::get().playlistContextMenu(), &QMenu::aboutToShow, [=]() { QTimer::singleShot(20, [=]() { if (_mouseItem) { ((PlayItemWidget*)_mouseItem)->setHovered(true); } }); }); connect(ActionFactory::get().playlistContextMenu(), &QMenu::aboutToHide, [=]() { if (_mouseItem) { ((PlayItemWidget*)_mouseItem)->setHovered(false); } }); connect(model(), &QAbstractItemModel::rowsMoved, [=]() { if (_lastDragged.first >= 0) { int target = -1; for (int i = 0; i < count(); i++) { auto piw = dynamic_cast(itemWidget(item(i))); if (piw == _lastDragged.second) { target = i; break; } } qDebug() << "swap " << _lastDragged.first << target; if (target >= 0 && _lastDragged.first != target) { _engine->playlist().switchPosition(_lastDragged.first, target); _lastDragged = {-1, nullptr}; } } }); } PlaylistWidget::~PlaylistWidget() { } void PlaylistWidget::updateItemInfo(int id) { auto piw = dynamic_cast(itemWidget(item(id))); piw->updateInfo(_engine->playlist().items()[id]); } void PlaylistWidget::updateItemStates() { qDebug() << __func__ << count() << "current = " << _engine->playlist().current(); for (int i = 0; i < count(); i++) { auto piw = dynamic_cast(itemWidget(item(i))); auto old = piw->state(); piw->setState(ItemState::Normal); if (!piw->_pif.valid) { piw->setState(ItemState::Invalid); } if (i == _engine->playlist().current()) { if (piw->state() != ItemState::Playing) { scrollToItem(item(i)); piw->setState(ItemState::Playing); } } if (old != piw->state()) { piw->setStyleSheet(piw->styleSheet()); } } } void PlaylistWidget::showItemInfo() { if (!_mouseItem) return; auto item = dynamic_cast(_mouseItem); if (item) { MovieInfoDialog mid(item->_pif); mid.exec(); } } void PlaylistWidget::openItemInFM() { if (!_mouseItem) return; auto item = dynamic_cast(_mouseItem); if (item) { utils::ShowInFileManager(item->_pif.mi.filePath); } } void PlaylistWidget::removeClickedItem() { if (!_clickedItem) return; auto piw = dynamic_cast(_clickedItem); if (piw) { qDebug() << __func__; for (int i = 0; i < count(); i++) { if (_clickedItem == itemWidget(item(i))) { _engine->playlist().remove(i); break; } } } } void PlaylistWidget::dragEnterEvent(QDragEnterEvent *ev) { auto md = ev->mimeData(); qDebug() << md->formats(); if (md->formats().contains("application/x-qabstractitemmodeldatalist")) { if (!selectedItems().contains(itemAt(ev->pos()))) { setDropIndicatorShown(true); } QListWidget::dragEnterEvent(ev); return; } if (ev->mimeData()->hasUrls()) { ev->acceptProposedAction(); } } void PlaylistWidget::dragMoveEvent(QDragMoveEvent *ev) { auto md = ev->mimeData(); if (md->formats().contains("application/x-qabstractitemmodeldatalist")) { if (!selectedItems().contains(itemAt(ev->pos()))) { setDropIndicatorShown(true); } QListWidget::dragMoveEvent(ev); return; } if (ev->mimeData()->hasUrls()) { ev->acceptProposedAction(); } } void PlaylistWidget::dropEvent(QDropEvent *ev) { auto md = ev->mimeData(); if (md->formats().contains("application/x-qabstractitemmodeldatalist")) { setDropIndicatorShown(false); auto encoded = md->data("application/x-qabstractitemmodeldatalist"); QDataStream stream(&encoded, QIODevice::ReadOnly); QList l; while (!stream.atEnd()) { int row, col; QMap roleDataMap; stream >> row >> col >> roleDataMap; auto piw = dynamic_cast(itemWidget(item(row))); _lastDragged = qMakePair(row, piw); qDebug() << "drag to move " << row << piw->_pif.url; } QListWidget::dropEvent(ev); return; } if (!ev->mimeData()->hasUrls()) { return; } auto urls = ev->mimeData()->urls(); _engine->addPlayFiles(urls); ev->acceptProposedAction(); } void PlaylistWidget::contextMenuEvent(QContextMenuEvent *cme) { bool on_item = false; _mouseItem = nullptr; if (itemAt(cme->pos())) { _mouseItem = itemWidget(itemAt(cme->pos())); on_item = true; } auto piw = dynamic_cast(_mouseItem); auto menu = ActionFactory::get().playlistContextMenu(); for (auto act: menu->actions()) { auto prop = (ActionFactory::ActionKind)act->property("kind").toInt(); bool on = true; if (prop == ActionFactory::ActionKind::PlaylistOpenItemInFM || prop == ActionFactory::ActionKind::PlaylistItemInfo) { on = on_item && piw->_pif.valid && piw->_pif.url.isLocalFile(); } act->setEnabled(on); } ActionFactory::get().playlistContextMenu()->popup(cme->globalPos()); } void PlaylistWidget::showEvent(QShowEvent *se) { batchUpdateSizeHints(); adjustSize(); } void PlaylistWidget::removeItem(int idx) { qDebug() << "idx = " << idx; auto item = this->takeItem(idx); if (item) { delete item; } } void PlaylistWidget::appendItems() { qDebug() << __func__; auto items = _engine->playlist().items(); auto p = items.begin() + this->count(); while (p != items.end()) { auto w = new PlayItemWidget(*p, this); auto item = new QListWidgetItem; addItem(item); setItemWidget(item, w); connect(w, SIGNAL(closeButtonClicked()), _closeMapper, SLOT(map())); connect(w, SIGNAL(doubleClicked()), _activateMapper, SLOT(map())); _closeMapper->setMapping(w, w); _activateMapper->setMapping(w, w); ++p; } batchUpdateSizeHints(); updateItemStates(); setStyleSheet(styleSheet()); } void PlaylistWidget::loadPlaylist() { qDebug() << __func__; clear(); auto items = _engine->playlist().items(); auto p = items.begin(); while (p != items.end()) { auto w = new PlayItemWidget(*p, this); auto item = new QListWidgetItem; addItem(item); setItemWidget(item, w); connect(w, SIGNAL(closeButtonClicked()), _closeMapper, SLOT(map())); connect(w, SIGNAL(doubleClicked()), _activateMapper, SLOT(map())); _closeMapper->setMapping(w, w); _activateMapper->setMapping(w, w); ++p; } batchUpdateSizeHints(); updateItemStates(); setStyleSheet(styleSheet()); } void PlaylistWidget::batchUpdateSizeHints() { if (isVisible()) { for (int i = 0; i < this->count(); i++) { auto item = this->item(i); auto w = this->itemWidget(item); item->setSizeHint(w->size()); } } } void PlaylistWidget::togglePopup() { auto main_rect = _mw->rect(); #ifdef USE_DXCB auto view_rect = main_rect; #else auto view_rect = main_rect.marginsRemoved(QMargins(1, 1, 1, 1)); #endif int off = _mw->isFullScreen()? 0: _mw->titlebar()->geometry().bottom(); QRect fixed(0, off, PLAYLIST_FIXED_WIDTH, _mw->toolbox()->geometry().top() + TOOLBOX_TOP_EXTENT - off); fixed.moveRight(view_rect.right()); QRect shrunk = fixed; shrunk.setWidth(0); shrunk.moveRight(fixed.right()); if (_toggling) return; if (_state == State::Opened) { Q_ASSERT(isVisible()); _toggling = true; QPropertyAnimation *pa = new QPropertyAnimation(this, "geometry"); pa->setEasingCurve(QEasingCurve::InOutCubic); pa->setDuration(POPUP_DURATION); pa->setStartValue(fixed); pa->setEndValue(shrunk);; pa->start(); connect(pa, &QPropertyAnimation::finished, [=]() { pa->deleteLater(); setVisible(!isVisible()); _toggling = false; _state = State::Closed; }); } else { setVisible(!isVisible()); _toggling = true; QPropertyAnimation *pa = new QPropertyAnimation(this, "geometry"); pa->setEasingCurve(QEasingCurve::InOutCubic); pa->setDuration(POPUP_DURATION); pa->setStartValue(shrunk); pa->setEndValue(fixed); pa->start(); connect(pa, &QPropertyAnimation::finished, [=]() { pa->deleteLater(); _toggling = false; _state = State::Opened; }); } } } #include "playlist_widget.moc" deepin-movie-reborn-5.0.0/src/widgets/playlist_widget.h000066400000000000000000000060211351125414100231700ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_PLAYLIST_WIDGET_H #define _DMR_PLAYLIST_WIDGET_H #include #include namespace Dtk { namespace Widget { class DImageButton; } } DWIDGET_USE_NAMESPACE namespace dmr { class PlayerEngine; class MainWindow; class PlayItemWidget; class PlaylistWidget: public QListWidget { Q_OBJECT public: enum State { Opened, Closed, }; PlaylistWidget(QWidget *, PlayerEngine*); virtual ~PlaylistWidget(); State state() const { return _state; } bool toggling() const { return _toggling; } public slots: void togglePopup(); void loadPlaylist(); void openItemInFM(); void showItemInfo(); void removeClickedItem(); protected: void contextMenuEvent(QContextMenuEvent *cme) override; void dragEnterEvent(QDragEnterEvent *event) override; void dragMoveEvent(QDragMoveEvent *event) override; void dropEvent(QDropEvent *event) override; void showEvent(QShowEvent *se) override; protected slots: void updateItemStates(); void updateItemInfo(int); void appendItems(); void removeItem(int); private: PlayerEngine *_engine {nullptr}; MainWindow *_mw {nullptr}; QWidget *_mouseItem {nullptr}; QWidget *_clickedItem {nullptr}; QSignalMapper *_closeMapper {nullptr}; QSignalMapper *_activateMapper {nullptr}; State _state {Closed}; bool _toggling {false}; /// < original row, data> QPair _lastDragged {-1, nullptr}; void batchUpdateSizeHints(); }; } #endif /* ifndef _DMR_PLAYLIST_WIDGET_H */ deepin-movie-reborn-5.0.0/src/widgets/slider.cpp000066400000000000000000000226221351125414100216060ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "slider.h" #include #include #define TOOLBOX_TOP_EXTENT 12 DWIDGET_USE_NAMESPACE namespace dmr { static auto light_style = R"( #MovieProgress[Hover="true"]::groove:horizontal { background-color: qlineargradient(x1:0 y1:0, x2:0 y2:1, stop:0.00000 transparent, stop:%1 transparent, stop:%2 rgba(252, 252, 252, 0.88), stop:0.50000 rgba(252, 252, 252, 0.88), stop:0.50001 rgba(0, 0, 0, 0.0), stop:1 rgba(0, 0, 0, 0.0) ); position: absolute; left: 0px; right: 0px; } #MovieProgress[Hover="true"]::add-page:horizontal { background-color: qlineargradient(x1:0 y1:0, x2:0 y2:1, stop:0.00000 transparent, stop:%3 transparent, stop:%4 rgba(0, 0, 0, 0.1), stop:%5 rgba(0, 0, 0, 0.1), stop:%6 rgba(252, 252, 252, 0.08), stop:%7 rgba(252, 252, 252, 0.08), stop:%8 rgba(0, 0, 0, 0.0), stop:1 rgba(0, 0, 0, 0.0) ); } #MovieProgress[Hover="true"]::sub-page:horizontal { background-color: qlineargradient(x1:0 y1:0, x2:0 y2:1, stop:0.00000 transparent, stop:%1 transparent, stop:%2 #2eacff, stop:0.58333 #2eacff, stop:0.58334 rgba(0, 0, 0, 0.0), stop:1 rgba(0, 0, 0, 0.0) ); } )"; static auto dark_style = R"( #MovieProgress[Hover="true"]::groove:horizontal { background-color: qlineargradient(x1:0 y1:0, x2:0 y2:1, stop:0.00000 transparent, stop:%1 transparent, stop:%2 rgba(16, 16, 16, 0.8), stop:0.50000 rgba(16, 16, 16, 0.8), stop:0.50001 rgba(0, 0, 0, 0.0), stop:1 rgba(0, 0, 0, 0.0) ); position: absolute; left: 0px; right: 0px; } #MovieProgress[Hover="true"]::add-page:horizontal { background-color: qlineargradient(x1:0 y1:0, x2:0 y2:1, stop:0.00000 transparent, stop:%3 transparent, stop:%4 rgba(0, 0, 0, 0.5), stop:%5 rgba(0, 0, 0, 0.5), stop:%6 rgba(0, 0, 0, 0.03), stop:%7 rgba(0, 0, 0, 0.03), stop:%8 rgba(0, 0, 0, 0.0), stop:1 rgba(0, 0, 0, 0.0) ); } #MovieProgress[Hover="true"]::sub-page:horizontal { background-color: qlineargradient(x1:0 y1:0, x2:0 y2:1, stop:0.00000 transparent, stop:%1 transparent, stop:%2 #2eacff, stop:0.58333 #2eacff, stop:0.58334 rgba(0, 0, 0, 0.0), stop:1 rgba(0, 0, 0, 0.0) ); } )"; DMRSlider::DMRSlider(QWidget *parent): QSlider(parent) { setTracking(false); setMouseTracking(true); auto updateTheme = [=]() { if (qApp->theme() == "dark") { _indicatorColor = QColor("#ffffff"); _style_tmpl = dark_style; } else { _indicatorColor = QColor("#303030"); _style_tmpl = light_style; } }; connect(DThemeManager::instance(), &DThemeManager::themeChanged, updateTheme); updateTheme(); setProperty("Hover", "false"); setStyleSheet(styleSheet()); } void DMRSlider::setEnableIndication(bool on) { if (_indicatorEnabled != on) { _indicatorEnabled = on; update(); } } DMRSlider::~DMRSlider() { } void DMRSlider::mouseReleaseEvent(QMouseEvent *e) { if (_down) { //emit sliderMoved(sliderPosition()); _down = false; QSlider::mouseReleaseEvent(e); } } int DMRSlider::position2progress(const QPoint& p) { auto total = (maximum() - minimum()); if (orientation() == Qt::Horizontal) { qreal span = (qreal)total / contentsRect().width(); return span * (p.x()) + minimum(); } else { qreal span = (qreal)total / contentsRect().height(); return span * (height() - p.y()) + minimum(); } } void DMRSlider::mousePressEvent(QMouseEvent *e) { if (e->buttons() == Qt::LeftButton && isEnabled()) { QSlider::mousePressEvent(e); int v = position2progress(e->pos());; setSliderPosition(v); emit sliderMoved(v); _down = true; } } void DMRSlider::mouseMoveEvent(QMouseEvent *e) { if (!isEnabled()) return; int v = position2progress(e->pos());; if (_down) { setSliderPosition(v); if (_showIndicator) { _indicatorPos = {e->x(), pos().y()+TOOLBOX_TOP_EXTENT-4}; update(); } } else { // a mouse enter from previewer happens if (_indicatorEnabled && !property("Hover").toBool()) { setProperty("Hover", "true"); startAnimation(false); _showIndicator = true; update(); } emit enter(); if (_lastHoverValue != v) { if (_showIndicator) { _indicatorPos = {e->x(), pos().y()+TOOLBOX_TOP_EXTENT-4}; update(); } emit hoverChanged(v); } _lastHoverValue = v; } e->accept(); } void DMRSlider::leaveEvent(QEvent *e) { if (_indicatorEnabled) { startAnimation(true); _showIndicator = false; update(); } //HACK: workaround problem that preview will make slider leave auto pos = mapFromGlobal(QCursor::pos()); if (pos.y() > 0 && pos.y() < 6) { // preview may popup return; } _lastHoverValue = 0; if (_down) _down = false; emit leave(); if (e) e->accept(); } void DMRSlider::forceLeave() { leaveEvent(NULL); } void DMRSlider::onAnimationStopped() { // need to clear stylesheet when leave slider, since the generated sheet is a // little weird. if (_hoverAni && _hoverAni->state() == QVariantAnimation::Stopped) { setProperty("Hover", "false"); setStyleSheet(""); update(); } } void DMRSlider::onValueChanged(const QVariant& v) { // see dmr--ToolProxy.theme to find out the meaning of these values // v1 is for groove and sub-page // v2 is for add-page float v1 = (1.0 - v.toFloat()) * 0.500000 + v.toFloat() * (1 / 3.0); float v2 = (1.0 - v.toFloat()) * 0.500000 + v.toFloat() * (1 / 3.0); float v3 = v2 + (1.0 / 24.0); float v4 = v2 + (2.0 / 24.0); auto s = QString::fromUtf8(_style_tmpl) .arg(v1).arg(v1+0.000001) .arg(v2).arg(v2+0.000001) .arg(v3).arg(v3+0.000001) .arg(v4).arg(v4+0.000001); //qDebug() << "-------- interpolate " << v1 << v2 << v3 << v4; setStyleSheet(s); update(); } void DMRSlider::startAnimation(bool reverse) { if (_hoverAni) { _hoverAni->stop(); _hoverAni.clear(); } _hoverAni = new QVariantAnimation(this); if (reverse) { _hoverAni->setStartValue(1.0); _hoverAni->setEndValue(0.0); _hoverAni->setEasingCurve(QEasingCurve::InCubic); connect(_hoverAni, &QVariantAnimation::stateChanged, this, &DMRSlider::onAnimationStopped); } else { _hoverAni->setStartValue(0.0); _hoverAni->setEndValue(1.0); _hoverAni->setEasingCurve(QEasingCurve::OutCubic); } connect(_hoverAni, &QVariantAnimation::valueChanged, this, &DMRSlider::onValueChanged); _hoverAni->setDuration(150); _hoverAni->start(QVariantAnimation::DeleteWhenStopped); } void DMRSlider::enterEvent(QEvent *e) { if (_indicatorEnabled) { if (property("Hover") != "true") { setProperty("Hover", "true"); startAnimation(false); _showIndicator = true; update(); } } emit enter(); e->accept(); } void DMRSlider::wheelEvent(QWheelEvent *e) { if (e->buttons() == Qt::MiddleButton && e->modifiers() == Qt::NoModifier) { qDebug() << "angleDelta" << e->angleDelta(); } e->accept(); } void DMRSlider::paintEvent(QPaintEvent *e) { QSlider::paintEvent(e); if (_indicatorEnabled && _showIndicator) { QPainter p(this); QRect r(_indicatorPos, QSize{1, 6}); p.fillRect(r, QBrush(_indicatorColor)); } } } deepin-movie-reborn-5.0.0/src/widgets/slider.h000066400000000000000000000052021351125414100212460ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_SLIDER_H #define _DMR_SLIDER_H #include namespace dmr { class DMRSlider: public QSlider { Q_OBJECT public: DMRSlider(QWidget *parent = 0); virtual ~DMRSlider(); void setEnableIndication(bool on); //workaround void forceLeave(); signals: void hoverChanged(int); void leave(); void enter(); protected: void onValueChanged(const QVariant& v); void onAnimationStopped(); protected: void mouseReleaseEvent(QMouseEvent *e) override; void mousePressEvent(QMouseEvent *e) override; void mouseMoveEvent(QMouseEvent *e) override; void leaveEvent(QEvent *e) override; void enterEvent(QEvent *e) override; void wheelEvent(QWheelEvent *e) override; void paintEvent(QPaintEvent *e) override; private: bool _down {false}; bool _indicatorEnabled {false}; bool _showIndicator {false}; int _lastHoverValue {0}; QPoint _indicatorPos {0, 0}; QColor _indicatorColor; QPointer _hoverAni {nullptr}; const char* _style_tmpl {nullptr}; int position2progress(const QPoint& p); void startAnimation(bool reverse); }; } #endif /* ifndef _DMR_SLIDER_H */ deepin-movie-reborn-5.0.0/src/widgets/tip.cpp000066400000000000000000000156201351125414100211200ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "tip.h" #include #include #include #include #include #include #include #include #include DWIDGET_USE_NAMESPACE namespace dmr { class TipPrivate { public: TipPrivate(Tip *parent) : q_ptr(parent) {} void setBackgroundImage(const QPixmap &srcPixmap); QBrush background; int radius = 4; int shadowWidth = 20; QMargins shadowMargins = QMargins(20, 20, 20, 20); QColor borderColor = QColor(0, 0, 0, 0.2 * 255); QLabel *textLable = nullptr; QFrame *m_interFrame = nullptr; Tip *q_ptr; Q_DECLARE_PUBLIC(Tip) }; Tip::Tip(const QPixmap &icon, const QString &text, QWidget *parent) : QFrame(parent), d_ptr(new TipPrivate(this)) { DThemeManager::instance()->registerWidget(this); Q_D(Tip); // setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint); // setAttribute(Qt::WA_TranslucentBackground); setObjectName("Tip"); setContentsMargins(0, 0, 0, 0); auto layout = new QHBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); d->m_interFrame = new QFrame(this); d->m_interFrame->setContentsMargins(0, 0, 0, 0); auto interlayout = new QHBoxLayout(d->m_interFrame); interlayout->setContentsMargins(10, 0, 10, 0); interlayout->setSpacing(5); auto iconLabel = new QLabel; iconLabel->setObjectName("TipIcon"); iconLabel->setFixedSize(icon.size()); if (icon.isNull()) { iconLabel->hide(); } else { iconLabel->setPixmap(icon); } d->textLable = new QLabel(text); d->textLable->setObjectName("TipText"); d->textLable->setAlignment(Qt::AlignCenter); interlayout->addWidget(iconLabel, 0, Qt::AlignVCenter); interlayout->addWidget(d->textLable, 0, Qt::AlignVCenter); layout->addWidget(d->m_interFrame, 0, Qt::AlignVCenter); adjustSize(); auto *bodyShadow = new QGraphicsDropShadowEffect; bodyShadow->setBlurRadius(10.0); bodyShadow->setColor(QColor(0, 0, 0, 0.1 * 255)); bodyShadow->setOffset(0, 2.0); this->setGraphicsEffect(bodyShadow); hide(); //setFixedHeight(32); } Tip::~Tip() { } void Tip::enterEvent(QEvent* e) { hide(); } QBrush Tip::background() const { Q_D(const Tip); return d->background; } void Tip::setText(const QString text) { Q_D(const Tip); d->textLable->setText(text); } int Tip::radius() const { Q_D(const Tip); return d->radius; } QColor Tip::borderColor() const { Q_D(const Tip); return d->borderColor; } void Tip::setBackground(QBrush background) { Q_D(Tip); d->background = background; } void Tip::setRadius(int radius) { Q_D(Tip); d->radius = radius; } void Tip::setBorderColor(QColor borderColor) { Q_D(Tip); d->borderColor = borderColor; } void Tip::pop(QPoint center) { Q_D(Tip); this->show(); center = center - QPoint(width() / 2, height() / 2); this->move(center); auto topOpacity = new QGraphicsOpacityEffect(d->m_interFrame); topOpacity->setOpacity(1); d->m_interFrame->setGraphicsEffect(topOpacity); QPropertyAnimation *animation4 = new QPropertyAnimation(topOpacity, "opacity"); // animation4->setEasingCurve(QEasingCurve::InCubic); animation4->setDuration(2000); animation4->setStartValue(0); animation4->setKeyValueAt(0.25, 1); animation4->setKeyValueAt(0.5, 1); animation4->setKeyValueAt(0.75, 1); animation4->setEndValue(0); animation4->start(); animation4->connect(animation4, &QPropertyAnimation::finished, animation4, &QPropertyAnimation::deleteLater); animation4->connect(animation4, &QPropertyAnimation::finished, this, [ = ]() { d->m_interFrame->setGraphicsEffect(nullptr); this->hide(); }); } void Tip::paintEvent(QPaintEvent *) { Q_D(Tip); // QFrame::paintEvent(e); // return; bool outer = true; QPainter painter(this); painter.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing); auto radius = d->radius; auto penWidthf = 1.0; auto background = d->background; auto borderColor = d->borderColor; auto margin = 2.0; auto shadowMargins = QMarginsF(margin, margin, margin, margin); // QPainterPath frame; // frame.addRect(rect().marginsRemoved(QMargins(1, 1, 1, 1))); // painter.strokePath(frame, QPen(Qt::red)); // draw background auto backgroundRect = QRectF(rect()).marginsRemoved(shadowMargins); QPainterPath backgroundPath; backgroundPath.addRoundedRect(backgroundRect, radius, radius); painter.fillPath(backgroundPath, background); // draw border QPainterPath borderPath; QRectF borderRect = QRectF(rect()); auto borderRadius = radius; QMarginsF borderMargin(penWidthf / 2, penWidthf / 2, penWidthf / 2, penWidthf / 2); if (outer) { borderRadius += penWidthf / 2; borderRect = borderRect.marginsAdded(borderMargin).marginsRemoved(shadowMargins); } else { borderRadius -= penWidthf / 2; borderRect = borderRect.marginsRemoved(borderMargin).marginsRemoved(shadowMargins); } borderPath.addRoundedRect(borderRect, borderRadius, borderRadius); QPen borderPen(borderColor); borderPen.setWidthF(penWidthf); painter.strokePath(borderPath, borderPen); } } deepin-movie-reborn-5.0.0/src/widgets/tip.h000066400000000000000000000047071351125414100205710ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_TIP_H #define _DMR_TIP_H #include namespace dmr { class TipPrivate; class Tip : 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 Tip(const QPixmap &icon, const QString &text, QWidget *parent = 0); ~Tip(); void pop(QPoint center); int radius() const; QColor borderColor() const; QBrush background() const; public slots: void setText(const QString text); void setBackground(QBrush background); void setRadius(int radius); void setBorderColor(QColor borderColor); protected: virtual void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE; void enterEvent(QEvent* e) override; private: QScopedPointer d_ptr; Q_DECLARE_PRIVATE_D(qGetPtrHelper(d_ptr), Tip) }; } #endif /* ifndef _DMR_TIP_H */ deepin-movie-reborn-5.0.0/src/widgets/titlebar.cpp000066400000000000000000000107061351125414100221320ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "config.h" #include "titlebar.h" #include #include DWIDGET_USE_NAMESPACE namespace dmr { class TitlebarPrivate { public: TitlebarPrivate(Titlebar *parent) : q_ptr(parent) { QLinearGradient linearGradient(QPointF(0.0, 0.0), QPointF(0.0, 1.0)); linearGradient.setColorAt(0.0, QColor(255, 255, 255, 255)); linearGradient.setColorAt(1.0, QColor(0xf8, 0xf8, 0xf8, 255)); titleBackground = QBrush(linearGradient); borderShadowTop = QColor(0.05 * 255, 0.05 * 255, 0.05 * 255); borderBottom = QColor(255, 0, 0); } QBrush titleBackground; QColor borderBottom; QColor borderShadowTop; QString viewname; Titlebar *q_ptr; Q_DECLARE_PUBLIC(Titlebar) }; Titlebar::Titlebar(QWidget *parent) : DTitlebar(parent), d_ptr(new TitlebarPrivate(this)) { Q_D(Titlebar); DThemeManager::instance()->registerWidget(this); } Titlebar::~Titlebar() { } QBrush Titlebar::background() const { Q_D(const Titlebar); return d->titleBackground; } QColor Titlebar::borderBottom() const { Q_D(const Titlebar); return d->borderBottom; } QColor Titlebar::borderShadowTop() const { Q_D(const Titlebar); return d->borderShadowTop; } void Titlebar::setBackground(QBrush titleBackground) { Q_D(Titlebar); d->titleBackground = titleBackground; } void Titlebar::setBorderBottom(QColor borderBottom) { Q_D(Titlebar); d->borderBottom = borderBottom; } void Titlebar::setBorderShadowTop(QColor borderShadowTop) { Q_D(Titlebar); d->borderShadowTop = borderShadowTop; } void Titlebar::paintEvent(QPaintEvent *pe) { Q_D(const Titlebar); auto radius = RADIUS; QPainter p(this); p.setRenderHint(QPainter::Antialiasing); auto titleBarHeight = this->height(); QRectF r = rect(); p.fillRect(r, Qt::transparent); QRectF topLeftRect(r.topLeft(), QSize(2 * radius, 2 * radius)); QRectF topRightRect(QPoint(r.right() - 2 * radius, r.y()), QSize(2 * radius, 2 * radius)); QPainterPath titleBorder; titleBorder.moveTo(r.x() + radius, r.y()); titleBorder.lineTo(r.x() + r.width() - radius, r.y()); titleBorder.arcTo(topRightRect, 90.0, -90.0); titleBorder.lineTo(r.x() + r.width(), r.y() + radius); titleBorder.lineTo(r.x() + r.width(), r.y() + titleBarHeight); titleBorder.lineTo(r.x(), r.y() + titleBarHeight); titleBorder.lineTo(r.x() , r.y() + radius); titleBorder.arcTo(topLeftRect, 180.0, -90.0); titleBorder.closeSubpath(); p.setClipPath(titleBorder); p.fillPath(titleBorder, QBrush(d->titleBackground)); QLine line(r.topLeft().x(), r.y() + titleBarHeight, r.x() + r.width(), r.y() + titleBarHeight); p.setPen(QPen(d->borderBottom, 1.0)); p.drawLine(line); QLine lineOut(r.topLeft().x()+radius, r.y(), r.x() + r.width()-radius, r.y()); p.setPen(QPen(d->borderShadowTop, 1.0)); p.drawLine(lineOut); } } deepin-movie-reborn-5.0.0/src/widgets/titlebar.h000066400000000000000000000047421351125414100216020ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef DMR_TITLEBAR_H #define DMR_TITLEBAR_H #include #include namespace dmr { class TitlebarPrivate; class Titlebar : public Dtk::Widget::DTitlebar { Q_OBJECT Q_PROPERTY(QBrush background READ background WRITE setBackground) Q_PROPERTY(QColor borderBottom READ borderBottom WRITE setBorderBottom) Q_PROPERTY(QColor borderShadowTop READ borderShadowTop WRITE setBorderShadowTop) public: explicit Titlebar(QWidget *parent = 0); ~Titlebar(); QString viewname() const; QBrush background() const; QColor borderBottom() const; QColor borderShadowTop() const; public slots: void setBackground(QBrush background); void setBorderBottom(QColor borderBottom); void setBorderShadowTop(QColor borderShadowTop); protected: virtual void paintEvent(QPaintEvent *e) override; private: QScopedPointer d_ptr; Q_DECLARE_PRIVATE_D(qGetPtrHelper(d_ptr), Titlebar) QColor m_borderBottom; }; } #endif /* ifndef DMR_TITLEBAR_H */ deepin-movie-reborn-5.0.0/src/widgets/toolbox_proxy.cpp000066400000000000000000000741601351125414100232570ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "config.h" #include "toolbox_proxy.h" #include "mainwindow.h" #include "event_relayer.h" #include "compositing_manager.h" #include "player_engine.h" #include "toolbutton.h" #include "dmr_settings.h" #include "actions.h" #include "slider.h" #include "thumbnail_worker.h" #include "tip.h" #include "utils.h" #include #include #include #include #include static const int LEFT_MARGIN = 15; static const int RIGHT_MARGIN = 10; DWIDGET_USE_NAMESPACE namespace dmr { class KeyPressBubbler: public QObject { public: KeyPressBubbler(QObject *parent): QObject(parent) {} protected: bool eventFilter(QObject *obj, QEvent *event) { if (event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast(event); event->setAccepted(false); return false; } else { // standard event processing return QObject::eventFilter(obj, event); } } }; class TooltipHandler: public QObject { public: TooltipHandler(QObject *parent): QObject(parent) {} protected: bool eventFilter(QObject *obj, QEvent *event) { switch (event->type()) { case QEvent::ToolTip: { QHelpEvent *he = static_cast(event); auto tip = obj->property("HintWidget").value(); auto btn = tip->property("for").value(); tip->setText(btn->toolTip()); tip->show(); tip->raise(); tip->adjustSize(); auto mw = tip->parentWidget(); auto sz = tip->size(); QPoint pos = btn->parentWidget()->mapToParent(btn->pos()); pos.ry() = mw->rect().bottom() - 65 - sz.height(); pos.rx() = pos.x() - sz.width()/2 + btn->width()/2; tip->move(pos); return true; } case QEvent::Leave: { auto parent = obj->property("HintWidget").value(); parent->hide(); event->ignore(); } default: break; } // standard event processing return QObject::eventFilter(obj, event); } }; class SubtitlesView; class SubtitleItemWidget: public QWidget { Q_OBJECT public: friend class SubtitlesView; SubtitleItemWidget(QWidget *parent, SubtitleInfo si): QWidget() { _sid = si["id"].toInt(); DThemeManager::instance()->registerWidget(this, QStringList() << "current"); setFixedWidth(200); auto *l = new QHBoxLayout(this); setLayout(l); l->setContentsMargins(0, 0, 0, 0); _msg = si["title"].toString(); auto shorted = fontMetrics().elidedText(_msg, Qt::ElideMiddle, 140*2); _title = new QLabel(shorted); _title->setWordWrap(true); l->addWidget(_title, 1); _selectedLabel = new QLabel(this); l->addWidget(_selectedLabel); connect(DThemeManager::instance(), &DThemeManager::themeChanged, this, &SubtitleItemWidget::onThemeChanged); onThemeChanged(); } int sid() const { return _sid; } void setCurrent(bool v) { if (v) { auto name = QString(":/resources/icons/%1/subtitle-selected.svg").arg(qApp->theme()); _selectedLabel->setPixmap(QPixmap(name)); } else { _selectedLabel->clear(); } setProperty("current", v?"true":"false"); setStyleSheet(this->styleSheet()); style()->unpolish(_title); style()->polish(_title); } protected: void showEvent(QShowEvent *se) override { auto fm = _title->fontMetrics(); auto shorted = fm.elidedText(_msg, Qt::ElideMiddle, 140*2); int h = fm.height(); if (fm.width(shorted) > 140) { h *= 2; } else { } _title->setFixedHeight(h); _title->setText(shorted); } private slots: void onThemeChanged() { if (property("current").toBool()) { auto name = QString(":/resources/icons/%1/subtitle-selected.svg").arg(qApp->theme()); _selectedLabel->setPixmap(QPixmap(name)); } } private: QLabel *_selectedLabel {nullptr}; QLabel *_title {nullptr}; int _sid {-1}; QString _msg; }; class SubtitlesView: public DArrowRectangle { Q_OBJECT public: SubtitlesView(QWidget *p, PlayerEngine* e) : DArrowRectangle(DArrowRectangle::ArrowBottom, p), _engine{e} { setWindowFlags(Qt::Popup); DThemeManager::instance()->registerWidget(this); setMinimumHeight(20); setShadowBlurRadius(4); setRadius(4); setShadowYOffset(3); setShadowXOffset(0); setArrowWidth(8); setArrowHeight(6); QSizePolicy sz_policy(QSizePolicy::Fixed, QSizePolicy::Preferred); setSizePolicy(sz_policy); setFixedWidth(220); auto *l = new QHBoxLayout(this); l->setContentsMargins(8, 2, 8, 2); l->setSpacing(0); setLayout(l); _subsView = new QListWidget(this); _subsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); _subsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); _subsView->setResizeMode(QListView::Adjust); _subsView->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents); _subsView->setSelectionMode(QListWidget::SingleSelection); _subsView->setSelectionBehavior(QListWidget::SelectItems); l->addWidget(_subsView); connect(_subsView, &QListWidget::itemClicked, this, &SubtitlesView::onItemClicked); connect(_engine, &PlayerEngine::tracksChanged, this, &SubtitlesView::populateSubtitles); connect(_engine, &PlayerEngine::sidChanged, this, &SubtitlesView::onSidChanged); connect(DThemeManager::instance(), &DThemeManager::themeChanged, this, &SubtitlesView::onThemeChanged); onThemeChanged(); } protected: void showEvent(QShowEvent *se) override { ensurePolished(); populateSubtitles(); setFixedHeight(_subsView->height() + 4); } protected slots: void onThemeChanged() { if (qApp->theme() == "dark") { setBackgroundColor(DBlurEffectWidget::DarkColor); } else { setBackgroundColor(DBlurEffectWidget::LightColor); } } void batchUpdateSizeHints() { QSize sz(0, 0); if (isVisible()) { for (int i = 0; i < _subsView->count(); i++) { auto item = _subsView->item(i); auto w = _subsView->itemWidget(item); item->setSizeHint(w->sizeHint()); sz += w->sizeHint(); sz += QSize(0, 2); } } sz += QSize(0, 2); _subsView->setFixedHeight(sz.height()); } void populateSubtitles() { _subsView->clear(); _subsView->adjustSize(); adjustSize(); auto pmf = _engine->playingMovieInfo(); auto sid = _engine->sid(); qDebug() << "sid" << sid; for (const auto& sub: pmf.subs) { auto item = new QListWidgetItem(); auto siw = new SubtitleItemWidget(this, sub); _subsView->addItem(item); _subsView->setItemWidget(item, siw); auto v = (sid == sub["id"].toInt()); siw->setCurrent(v); if (v) { _subsView->setCurrentItem(item); } } batchUpdateSizeHints(); } void onSidChanged() { auto sid = _engine->sid(); for (int i = 0; i < _subsView->count(); ++i) { auto siw = static_cast(_subsView->itemWidget(_subsView->item(i))); siw->setCurrent(siw->sid() == sid); } qDebug() << "current " << _subsView->currentRow(); } void onItemClicked(QListWidgetItem* item) { auto id = _subsView->row(item); _engine->selectSubtitle(id); } private: PlayerEngine *_engine {nullptr}; QListWidget *_subsView {nullptr}; }; class ThumbnailPreview: public DArrowRectangle { Q_OBJECT public: ThumbnailPreview(): DArrowRectangle(DArrowRectangle::ArrowBottom) { setAttribute(Qt::WA_DeleteOnClose); // FIXME(hualet): Qt::Tooltip will cause Dock to show up even // the player is in fullscreen mode. setWindowFlags(Qt::Tool); setObjectName("ThumbnailPreview"); setFixedSize(162, 103); setShadowBlurRadius(6); setRadius(6); setShadowYOffset(4); setShadowXOffset(0); setArrowWidth(18); setArrowHeight(10); auto *l = new QVBoxLayout; l->setContentsMargins(2, 2, 2, 2+10); setLayout(l); _thumb = new QLabel(this); _thumb->setFixedSize(ThumbnailWorker::thumbSize()); l->addWidget(_thumb); _time = new QLabel(this); _time->setAlignment(Qt::AlignCenter); _time->setFixedSize(64, 18); connect(DThemeManager::instance(), &DThemeManager::themeChanged, this, &ThumbnailPreview::updateTheme); updateTheme(); winId(); // force backed window to be created } void updateWithPreview(const QPixmap& pm, qint64 secs, int rotation) { auto rounded = utils::MakeRoundedPixmap(pm, 4, 4, rotation); _thumb->setPixmap(rounded); QTime t(0, 0, 0); t = t.addSecs(secs); _time->setText(t.toString("hh:mm:ss")); _time->move((width() - _time->width())/2, 69); if (isVisible()) { move(QCursor::pos().x(), frameGeometry().y() + height()); } } void updateWithPreview(const QPoint& pos) { resizeWithContent(); move(pos.x(), pos.y()); show(pos.x(), pos.y()); } signals: void leavePreview(); protected slots: void updateTheme() { if (qApp->theme() == "dark") { setBackgroundColor(QColor(23, 23, 23, 255 * 8 / 10)); setBorderColor(QColor(255, 255 ,255, 25)); _time->setStyleSheet(R"( border-radius: 3px; background-color: rgba(23, 23, 23, 0.8); font-size: 12px; color: #ffffff; )"); } else { setBackgroundColor(QColor(255, 255, 255, 255 * 8 / 10)); setBorderColor(QColor(0, 0 ,0, 25)); _time->setStyleSheet(R"( border-radius: 3px; background-color: rgba(255, 255, 255, 0.8); font-size: 12px; color: #303030; )"); } } protected: void leaveEvent(QEvent *e) override { emit leavePreview(); } void showEvent(QShowEvent *se) override { _time->move((width() - _time->width())/2, 69); } private: QLabel *_thumb; QLabel *_time; }; class VolumeSlider: public DArrowRectangle { Q_OBJECT public: VolumeSlider(PlayerEngine* eng, MainWindow* mw) :DArrowRectangle(DArrowRectangle::ArrowBottom), _engine(eng), _mw(mw) { setFixedSize(QSize(24, 105)); setWindowFlags(Qt::Tool); setShadowBlurRadius(4); setRadius(4); setShadowYOffset(3); setShadowXOffset(0); setArrowWidth(8); setArrowHeight(6); connect(DThemeManager::instance(), &DThemeManager::themeChanged, this, &VolumeSlider::updateBg); updateBg(); auto *l = new QVBoxLayout; l->setContentsMargins(0, 4, 0, 10); setLayout(l); _slider = new QSlider(this); _slider->installEventFilter(this); _slider->show(); _slider->setRange(0, 100); _slider->setOrientation(Qt::Vertical); _slider->setValue(_engine->volume()); l->addWidget(_slider); connect(_slider, &QSlider::valueChanged, [=]() { _mw->requestAction(ActionFactory::ChangeVolume, false, QList() << _slider->value()); }); _autoHideTimer.setSingleShot(true); connect(&_autoHideTimer, &QTimer::timeout, this, &VolumeSlider::hide); connect(_engine, &PlayerEngine::volumeChanged, [=]() { _slider->setValue(_engine->volume()); }); } ~VolumeSlider() { disconnect(DThemeManager::instance(), &DThemeManager::themeChanged, this, &VolumeSlider::updateBg); } void stopTimer() { _autoHideTimer.stop(); } public slots: void delayedHide() { _autoHideTimer.start(500); } protected: void enterEvent(QEvent* e) { _autoHideTimer.stop(); } void showEvent(QShowEvent* se) { _autoHideTimer.stop(); } void leaveEvent(QEvent* e) { _autoHideTimer.start(500); } private slots: void updateBg() { if (qApp->theme() == "dark") { setBackgroundColor(QColor(49, 49, 49, 255 * 9 / 10)); } else { setBackgroundColor(QColor(255, 255, 255, 255 * 9 / 10)); } } bool eventFilter(QObject *obj, QEvent *e) { if (e->type() == QEvent::Wheel) { QWheelEvent *we = static_cast(e); qDebug() << we->angleDelta() << we->modifiers() << we->buttons(); if (we->buttons() == Qt::NoButton && we->modifiers() == Qt::NoModifier) { if (_slider->value() == _slider->maximum() && we->angleDelta().y() > 0) { //keep increasing volume _mw->requestAction(ActionFactory::VolumeUp); } } return false; } else { return QObject::eventFilter(obj, e); } } private: PlayerEngine *_engine; QSlider *_slider; MainWindow *_mw; QTimer _autoHideTimer; }; ToolboxProxy::ToolboxProxy(QWidget *mainWindow, PlayerEngine *proxy) :QFrame(mainWindow), _mainWindow(static_cast(mainWindow)), _engine(proxy) { bool composited = CompositingManager::get().composited(); setFrameShape(QFrame::NoFrame); setAutoFillBackground(false); setAttribute(Qt::WA_TranslucentBackground); if (!composited) { setWindowFlags(Qt::FramelessWindowHint|Qt::BypassWindowManagerHint); setContentsMargins(0, 0, 0, 0); setAttribute(Qt::WA_NativeWindow); } DThemeManager::instance()->registerWidget(this); _previewer = new ThumbnailPreview; _previewer->hide(); _subView = new SubtitlesView(0, _engine); _subView->hide(); setup(); } ToolboxProxy::~ToolboxProxy() { ThumbnailWorker::get().stop(); delete _subView; delete _previewer; } void ToolboxProxy::setup() { auto *stacked = new QStackedLayout(this); stacked->setContentsMargins(0, 0, 0, 0); stacked->setStackingMode(QStackedLayout::StackAll); setLayout(stacked); _progBar = new DMRSlider(); _progBar->setObjectName("MovieProgress"); _progBar->setOrientation(Qt::Horizontal); _progBar->setFixedHeight(12+TOOLBOX_TOP_EXTENT); _progBar->setRange(0, 100); _progBar->setValue(0); _progBar->setEnableIndication(_engine->state() != PlayerEngine::Idle); connect(_previewer, &ThumbnailPreview::leavePreview, [=]() { auto pos = _progBar->mapFromGlobal(QCursor::pos()); if (!_progBar->geometry().contains(pos)) { _previewer->hide(); _progBar->forceLeave(); } }); connect(_progBar, &QSlider::sliderMoved, this, &ToolboxProxy::setProgress); connect(_progBar, &DMRSlider::hoverChanged, this, &ToolboxProxy::progressHoverChanged); connect(_progBar, &DMRSlider::leave, [=]() { _previewer->hide(); }); connect(&Settings::get(), &Settings::baseChanged, [=](QString sk, const QVariant& val) { if (sk == "base.play.mousepreview") { _progBar->setEnableIndication(_engine->state() != PlayerEngine::Idle); } }); stacked->addWidget(_progBar); auto *bot_widget = new QWidget; auto *bot = new QHBoxLayout(); bot->setContentsMargins(LEFT_MARGIN, TOOLBOX_TOP_EXTENT, RIGHT_MARGIN, 0); bot_widget->setLayout(bot); stacked->addWidget(bot_widget); _timeLabel = new QLabel(""); _timeLabel->setFixedWidth(_timeLabel->fontMetrics().width("99:99:99/99:99:99")); bot->addWidget(_timeLabel); auto *signalMapper = new QSignalMapper(this); connect(signalMapper, static_cast(&QSignalMapper::mapped), this, &ToolboxProxy::buttonClicked); bot->addStretch(); _mid = new QHBoxLayout(); _mid->setContentsMargins(0, 0, 0, 0); _mid->setSpacing(14); bot->addLayout(_mid); _prevBtn = new DImageButton(); _prevBtn->setFixedSize(48, TOOLBOX_HEIGHT); _prevBtn->setObjectName("PrevBtn"); connect(_prevBtn, SIGNAL(clicked()), signalMapper, SLOT(map())); signalMapper->setMapping(_prevBtn, "prev"); _mid->addWidget(_prevBtn); _playBtn = new DImageButton(); _playBtn->setFixedSize(48, TOOLBOX_HEIGHT); connect(_playBtn, SIGNAL(clicked()), signalMapper, SLOT(map())); signalMapper->setMapping(_playBtn, "play"); _mid->addWidget(_playBtn); _nextBtn = new DImageButton(); _nextBtn->setFixedSize(48, TOOLBOX_HEIGHT); _nextBtn->setObjectName("NextBtn"); connect(_nextBtn, SIGNAL(clicked()), signalMapper, SLOT(map())); signalMapper->setMapping(_nextBtn, "next"); _mid->addWidget(_nextBtn); bot->addStretch(); _right = new QHBoxLayout(); _right->setContentsMargins(0, 0, 0, 0); _right->setSizeConstraint(QLayout::SetFixedSize); _right->setSpacing(0); bot->addLayout(_right); _subBtn = new DImageButton(); _subBtn->setFixedSize(48, TOOLBOX_HEIGHT); _subBtn->setObjectName("SubtitleBtn"); connect(_subBtn, SIGNAL(clicked()), signalMapper, SLOT(map())); signalMapper->setMapping(_subBtn, "sub"); _right->addWidget(_subBtn); _subBtn->hide(); _volBtn = new VolumeButton(); _volBtn->setFixedSize(48, TOOLBOX_HEIGHT); connect(_volBtn, SIGNAL(clicked()), signalMapper, SLOT(map())); signalMapper->setMapping(_volBtn, "vol"); _right->addWidget(_volBtn); _volSlider = new VolumeSlider(_engine, _mainWindow); connect(_volBtn, &VolumeButton::entered, [=]() { _volSlider->stopTimer(); QPoint pos = _volBtn->parentWidget()->mapToGlobal(_volBtn->pos()); pos.ry() = parentWidget()->mapToGlobal(this->pos()).y(); _volSlider->show(pos.x() + _volSlider->width(), pos.y() - 5 + TOOLBOX_TOP_EXTENT); }); connect(_volBtn, &VolumeButton::leaved, _volSlider, &VolumeSlider::delayedHide); connect(_volBtn, &VolumeButton::requestVolumeUp, [=]() { _mainWindow->requestAction(ActionFactory::ActionKind::VolumeUp); }); connect(_volBtn, &VolumeButton::requestVolumeDown, [=]() { _mainWindow->requestAction(ActionFactory::ActionKind::VolumeDown); }); _fsBtn = new DImageButton(); _fsBtn->setFixedSize(48, TOOLBOX_HEIGHT); connect(_fsBtn, SIGNAL(clicked()), signalMapper, SLOT(map())); signalMapper->setMapping(_fsBtn, "fs"); _right->addWidget(_fsBtn); _listBtn = new DImageButton(); _listBtn->setFixedSize(48, TOOLBOX_HEIGHT); _listBtn->setObjectName("ListBtn"); connect(_listBtn, SIGNAL(clicked()), signalMapper, SLOT(map())); signalMapper->setMapping(_listBtn, "list"); _right->addWidget(_listBtn); // these tooltips is not used due to deepin ui design _playBtn->setToolTip(tr("Play/Pause")); //_volBtn->setToolTip(tr("Volume")); _prevBtn->setToolTip(tr("Previous")); _nextBtn->setToolTip(tr("Next")); _subBtn->setToolTip(tr("Subtitles")); _listBtn->setToolTip(tr("Playlist")); _fsBtn->setToolTip(tr("Fullscreen")); auto th = new TooltipHandler(this); QWidget* btns[] = { _playBtn, _prevBtn, _nextBtn, _subBtn, _listBtn, _fsBtn, }; QString hints[] = { tr("Play/Pause"), tr("Previous"), tr("Next"), tr("Subtitles"), tr("Playlist"), tr("Fullscreen"), }; for (int i = 0; i < sizeof(btns)/sizeof(btns[0]); i++) { auto t = new Tip(QPixmap(), hints[i], parentWidget()); t->setFixedHeight(32); t->setProperty("for", QVariant::fromValue(btns[i])); btns[i]->setProperty("HintWidget", QVariant::fromValue(t)); btns[i]->installEventFilter(th); } connect(_engine, &PlayerEngine::stateChanged, this, &ToolboxProxy::updatePlayState); connect(_engine, &PlayerEngine::fileLoaded, [=]() { _progBar->setRange(0, _engine->duration()); }); connect(_engine, &PlayerEngine::elapsedChanged, [=]() { updateTimeInfo(_engine->duration(), _engine->elapsed()); updateMovieProgress(); }); connect(window()->windowHandle(), &QWindow::windowStateChanged, this, &ToolboxProxy::updateFullState); connect(_engine, &PlayerEngine::muteChanged, this, &ToolboxProxy::updateVolumeState); connect(_engine, &PlayerEngine::volumeChanged, this, &ToolboxProxy::updateVolumeState); connect(_engine, &PlayerEngine::tracksChanged, this, &ToolboxProxy::updateButtonStates); connect(_engine, &PlayerEngine::fileLoaded, this, &ToolboxProxy::updateButtonStates); connect(&_engine->playlist(), &PlaylistModel::countChanged, this, &ToolboxProxy::updateButtonStates); connect(_mainWindow, &MainWindow::initChanged, this, &ToolboxProxy::updateButtonStates); updatePlayState(); updateFullState(); updateButtonStates(); connect(&ThumbnailWorker::get(), &ThumbnailWorker::thumbGenerated, this, &ToolboxProxy::updateHoverPreview); auto bubbler = new KeyPressBubbler(this); this->installEventFilter(bubbler); _playBtn->installEventFilter(bubbler); connect(qApp, &QGuiApplication::applicationStateChanged, [=](Qt::ApplicationState e) { if (e == Qt::ApplicationInactive && anyPopupShown()) { closeAnyPopup(); } }); } void ToolboxProxy::closeAnyPopup() { if (_previewer->isVisible()) { _previewer->hide(); } if (_subView->isVisible()) { _subView->hide(); } if (_volSlider->isVisible()) { _volSlider->stopTimer(); _volSlider->hide(); } } bool ToolboxProxy::anyPopupShown() const { return _previewer->isVisible() || _subView->isVisible() || _volSlider->isVisible(); } void ToolboxProxy::updateHoverPreview(const QUrl& url, int secs) { if (_engine->state() == PlayerEngine::CoreState::Idle) return; if (_engine->playlist().currentInfo().url != url) return; QPixmap pm = ThumbnailWorker::get().getThumb(url, secs); _previewer->updateWithPreview(pm, secs, _engine->videoRotation()); } void ToolboxProxy::progressHoverChanged(int v) { if (_engine->state() == PlayerEngine::CoreState::Idle) return; if (!Settings::get().isSet(Settings::PreviewOnMouseover)) return; if (_volSlider->isVisible()) return; const auto& pif = _engine->playlist().currentInfo(); if (!pif.url.isLocalFile()) return; const auto& absPath = pif.info.canonicalFilePath(); if (!QFile::exists(absPath)) { _previewer->hide(); return; } _lastHoverValue = v; ThumbnailWorker::get().requestThumb(pif.url, v); auto pos = _progBar->mapToGlobal(QPoint(0, TOOLBOX_TOP_EXTENT - 10)); QPoint p { QCursor::pos().x(), pos.y() }; _previewer->updateWithPreview(p); } void ToolboxProxy::setProgress() { if (_engine->state() == PlayerEngine::CoreState::Idle) return; _engine->seekAbsolute(_progBar->sliderPosition()); if (_progBar->sliderPosition() != _lastHoverValue) { progressHoverChanged(_progBar->sliderPosition()); } } void ToolboxProxy::updateMovieProgress() { if (_progBar->signalsBlocked()) return; auto d = _engine->duration(); auto e = _engine->elapsed(); int v = 0; if (d != 0 && e != 0) { v = _progBar->maximum() * ((double)e / d); } _progBar->blockSignals(true); _progBar->setValue(v); _progBar->blockSignals(false); } void ToolboxProxy::updateButtonStates() { qDebug() << _engine->playingMovieInfo().subs.size(); bool vis = _engine->playlist().count() > 1 && _mainWindow->inited(); _prevBtn->setVisible(vis); _nextBtn->setVisible(vis); vis = _engine->state() != PlayerEngine::CoreState::Idle; if (vis) { vis = _engine->playingMovieInfo().subs.size() > 0; } //_subBtn->setVisible(vis); } void ToolboxProxy::updateVolumeState() { if (_engine->muted()) { _volBtn->changeLevel(VolumeButton::Mute); //_volBtn->setToolTip(tr("Mute")); } else { auto v = _engine->volume(); //_volBtn->setToolTip(tr("Volume")); if (v >= 80) _volBtn->changeLevel(VolumeButton::High); else if (v >= 40) _volBtn->changeLevel(VolumeButton::Mid); else if (v == 0) _volBtn->changeLevel(VolumeButton::Off); else _volBtn->changeLevel(VolumeButton::Low); } } void ToolboxProxy::updateFullState() { bool isFullscreen = window()->isFullScreen(); if (isFullscreen) { _fsBtn->setObjectName("UnfsBtn"); _fsBtn->setToolTip(tr("Exit fullscreen")); } else { _fsBtn->setObjectName("FsBtn"); _fsBtn->setToolTip(tr("Fullscreen")); } _fsBtn->setStyleSheet(_playBtn->styleSheet()); } void ToolboxProxy::updatePlayState() { qDebug() << __func__ << _engine->state(); if (_engine->state() == PlayerEngine::CoreState::Playing) { _playBtn->setObjectName("PauseBtn"); _playBtn->setToolTip(tr("Pause")); } else { _playBtn->setObjectName("PlayBtn"); _playBtn->setToolTip(tr("Play")); } if (_engine->state() == PlayerEngine::CoreState::Idle) { if (_subView->isVisible()) _subView->hide(); if (_previewer->isVisible()) { _previewer->hide(); } setProperty("idle", true); } else { setProperty("idle", false); } auto on = (_engine->state() != PlayerEngine::CoreState::Idle); _progBar->setEnabled(on); _progBar->setEnableIndication(on); setStyleSheet(styleSheet()); } void ToolboxProxy::updateTimeInfo(qint64 duration, qint64 pos) { if (_engine->state() == PlayerEngine::CoreState::Idle) { _timeLabel->setText(""); } else { //mpv returns a slightly different duration from movieinfo.duration //_timeLabel->setText(QString("%2/%1").arg(utils::Time2str(duration)) //.arg(utils::Time2str(pos))); _timeLabel->setText(QString("%2/%1") .arg(_engine->playlist().currentInfo().mi.durationStr()) .arg(utils::Time2str(pos))); } } void ToolboxProxy::buttonClicked(QString id) { if (!isVisible()) return; qDebug() << __func__ << id; if (id == "play") { if (_engine->state() == PlayerEngine::CoreState::Idle) { _mainWindow->requestAction(ActionFactory::ActionKind::StartPlay); } else { _mainWindow->requestAction(ActionFactory::ActionKind::TogglePause); } } else if (id == "fs") { _mainWindow->requestAction(ActionFactory::ActionKind::ToggleFullscreen); } else if (id == "vol") { _mainWindow->requestAction(ActionFactory::ActionKind::ToggleMute); } else if (id == "prev") { _mainWindow->requestAction(ActionFactory::ActionKind::GotoPlaylistPrev); } else if (id == "next") { _mainWindow->requestAction(ActionFactory::ActionKind::GotoPlaylistNext); } else if (id == "list") { _mainWindow->requestAction(ActionFactory::ActionKind::TogglePlaylist); } else if (id == "sub") { _subView->setVisible(true); QPoint pos = _subBtn->parentWidget()->mapToGlobal(_subBtn->pos()); pos.ry() = parentWidget()->mapToGlobal(this->pos()).y(); _subView->show(pos.x() + _subBtn->width()/2, pos.y() - 5 + TOOLBOX_TOP_EXTENT); } } void ToolboxProxy::updatePosition(const QPoint& p) { QPoint pos(p); pos.ry() += _mainWindow->height() - height(); windowHandle()->setFramePosition(pos); } void ToolboxProxy::paintEvent(QPaintEvent *pe) { QWidget::paintEvent(pe); } void ToolboxProxy::showEvent(QShowEvent *event) { updateTimeLabel(); } void ToolboxProxy::resizeEvent(QResizeEvent *event) { updateTimeLabel(); } void ToolboxProxy::updateTimeLabel() { // to keep left and right of the same width. which makes play button centered _listBtn->setVisible(width() > 280); _timeLabel->setVisible(width() > 350); if (width() > 350) { auto right_geom = _right->geometry(); int left_w = _timeLabel->fontMetrics().width("99:99:99/99:99:99"); _timeLabel->show(); int w = qMax(left_w, right_geom.width()); _timeLabel->setFixedWidth(w + RIGHT_MARGIN - LEFT_MARGIN); right_geom.setWidth(w); _right->setGeometry(right_geom); } } } #include "toolbox_proxy.moc" deepin-movie-reborn-5.0.0/src/widgets/toolbox_proxy.h000066400000000000000000000071331351125414100227200ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_TOOLBOX_PROXY_H #define _DMR_TOOLBOX_PROXY_H #include #include namespace Dtk { namespace Widget { class DImageButton; } } DWIDGET_USE_NAMESPACE namespace dmr { class PlayerEngine; class VolumeButton; class MainWindow; class DMRSlider; class ThumbnailPreview; class SubtitlesView; class VolumeSlider; class ToolboxProxy: public QFrame { Q_OBJECT public: ToolboxProxy(QWidget *mainWindow, PlayerEngine*); virtual ~ToolboxProxy(); void updateTimeInfo(qint64 duration, qint64 pos); bool anyPopupShown() const; void closeAnyPopup(); signals: void requestPlay(); void requestPause(); void requestNextInList(); void requesstPrevInList(); protected slots: void updatePosition(const QPoint& p); void buttonClicked(QString id); void updatePlayState(); void updateFullState(); void updateVolumeState(); void updateMovieProgress(); void updateButtonStates(); void setProgress(); void progressHoverChanged(int v); void updateHoverPreview(const QUrl& url, int secs); protected: void paintEvent(QPaintEvent *pe) override; void showEvent(QShowEvent *event) override; void resizeEvent(QResizeEvent *event) override; private: void setup(); void updateTimeLabel(); MainWindow *_mainWindow {nullptr}; PlayerEngine *_engine {nullptr}; QLabel *_timeLabel {nullptr}; VolumeSlider *_volSlider {nullptr}; DImageButton *_playBtn {nullptr}; DImageButton *_prevBtn {nullptr}; DImageButton *_nextBtn {nullptr}; DImageButton *_subBtn {nullptr}; VolumeButton *_volBtn {nullptr}; DImageButton *_listBtn {nullptr}; DImageButton *_fsBtn {nullptr}; QHBoxLayout *_mid{nullptr}; QHBoxLayout *_right{nullptr}; DMRSlider *_progBar {nullptr}; ThumbnailPreview *_previewer {nullptr}; SubtitlesView *_subView {nullptr}; int _lastHoverValue {0}; QTimer _previewTimer; }; } //HACK: extent area for progress slider #define TOOLBOX_TOP_EXTENT 12 #define TOOLBOX_HEIGHT 60 #define TOOLBOX_HEIGHT_EXT (TOOLBOX_HEIGHT + TOOLBOX_TOP_EXTENT) #endif /* ifndef _DMR_TOOLBOX_PROXY_H */ deepin-movie-reborn-5.0.0/src/widgets/toolbutton.cpp000066400000000000000000000052531351125414100225360ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "toolbutton.h" #include #include namespace dmr { VolumeButton::VolumeButton(QWidget* parent) : DImageButton(parent) { changeLevel(Level::High); } void VolumeButton::changeLevel(Level lv) { if (_lv != lv) { switch (lv) { case Level::Off: setObjectName("VolOff"); break; case Level::Mute: setObjectName("VolMute"); break; case Level::Low: setObjectName("VolLow"); break; case Level::Mid: setObjectName("VolMid"); break; case Level::High: setObjectName("VolHigh"); break; } setStyleSheet(styleSheet()); _lv = lv; } } void VolumeButton::enterEvent(QEvent *ev) { emit entered(); } void VolumeButton::leaveEvent(QEvent *ev) { emit leaved(); } void VolumeButton::wheelEvent(QWheelEvent* we) { //qDebug() << we->angleDelta() << we->modifiers() << we->buttons(); if (we->buttons() == Qt::NoButton && we->modifiers() == Qt::NoModifier) { if (we->angleDelta().y() > 0) { emit requestVolumeUp(); } else { emit requestVolumeDown(); } } } } deepin-movie-reborn-5.0.0/src/widgets/toolbutton.h000066400000000000000000000042451351125414100222030ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #ifndef _DMR_TOOLBUTTON_H #define _DMR_TOOLBUTTON_H #include #include DWIDGET_USE_NAMESPACE namespace dmr { class VolumeButton: public DImageButton { Q_OBJECT public: enum Level { Off, Low, Mid, High, Mute }; VolumeButton(QWidget* parent = 0); void changeLevel(Level lv); signals: void entered(); void leaved(); void requestVolumeUp(); void requestVolumeDown(); protected: void enterEvent(QEvent *ev) override; void leaveEvent(QEvent *ev) override; void wheelEvent(QWheelEvent* wev) override; private: QString _name; Level _lv {Mute}; }; } #endif /* ifndef _DMR_TOOLBUTTON_H */ deepin-movie-reborn-5.0.0/src/widgets/url_dialog.cpp000066400000000000000000000052131351125414100224420ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #include "url_dialog.h" #include "dmr_lineedit.h" #include "dmr_settings.h" DWIDGET_USE_NAMESPACE namespace dmr { UrlDialog::UrlDialog(QWidget *parent) :DDialog(parent) { addButtons(QStringList() << QApplication::translate("UrlDialog", "Cancel") << QApplication::translate("UrlDialog", "Confirm")); setOnButtonClickedClose(false); setDefaultButton(1); setIcon(QIcon(":/resources/icons/logo-big.svg")); setMessage(QApplication::translate("UrlDialog", "Please enter the URL:")); _le = new LineEdit; addContent(_le); connect(getButton(0), &QAbstractButton::clicked, this, [=] { done(QDialog::Rejected); }); connect(getButton(1), &QAbstractButton::clicked, this, [=] { done(QDialog::Accepted); }); _le->setFocusPolicy(Qt::StrongFocus); this->setFocusProxy(_le); } QUrl UrlDialog::url() const { auto u = QUrl(_le->text(), QUrl::StrictMode); if (u.isLocalFile() || u.scheme().isEmpty()) return QUrl(); if (!Settings::get().iscommonPlayableProtocol(u.scheme())) return QUrl(); return u; } void UrlDialog::showEvent(QShowEvent* se) { _le->setFocus(); } } deepin-movie-reborn-5.0.0/src/widgets/url_dialog.h000066400000000000000000000035061351125414100221120ustar00rootroot00000000000000/* * (c) 2017, Deepin Technology Co., 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 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and * NON-INFRINGEMENT. See the GNU 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 . * * In addition, as a special exception, the copyright holders give * permission to link the code of portions of this program with the * OpenSSL library under certain conditions as described in each * individual source file, and distribute linked combinations * including the two. * You must obey the GNU General Public License in all respects * for all of the code used other than OpenSSL. If you modify * file(s) with this exception, you may extend this exception to your * version of the file(s), but you are not obligated to do so. If you * do not wish to do so, delete this exception statement from your * version. If you delete this exception statement from all source * files in the program, then also delete it here. */ #pragma once #include #include #include #include DWIDGET_USE_NAMESPACE namespace dmr { class LineEdit; class UrlDialog: public DDialog { public: UrlDialog(QWidget* parent = 0); QUrl url() const; protected: void showEvent(QShowEvent* se) override; private: LineEdit *_le {nullptr}; }; }