├── .gitignore ├── Binaries_x64.qrc ├── Binaries_x86.qrc ├── Copying.txt ├── MediaInfoXP.ico ├── MediaInfoXP.png ├── MediaInfoXP.props ├── MediaInfoXP.qrc ├── MediaInfoXP.rcx ├── MediaInfoXP.sln ├── MediaInfoXP.vcxproj ├── MediaInfoXP.vcxproj.filters ├── ReadMe.txt ├── doc ├── Changelog.txt ├── License.MediaInfo.html ├── License.Qt.html ├── License.html ├── README.html └── README.svg ├── gui └── Dialog.ui ├── res ├── bin │ ├── MediaInfo.x64-avx2.exe │ ├── MediaInfo.x64-sse2.exe │ ├── MediaInfo.x86-i686.exe │ └── MediaInfo.x86-sse2.exe ├── ico_clear.png ├── ico_discard.png ├── ico_disk.png ├── ico_folder.png ├── ico_info.png ├── ico_link.png ├── ico_options.png ├── ico_paste.png ├── ico_qt.png ├── ico_quit.png ├── ico_shellext.png ├── loading.png └── logo.png ├── src ├── Config.cpp ├── Config.h ├── IPC.cpp ├── IPC.h ├── Main.cpp ├── MainWindow.cpp ├── MainWindow.h ├── ShellExtension.cpp ├── ShellExtension.h └── Version.h └── z_build.bat /.gitignore: -------------------------------------------------------------------------------- 1 | /**/.old 2 | /**/.vs 3 | /tmp/ 4 | /obj/ 5 | /bin/ 6 | /ipch/ 7 | /out 8 | *.sdf 9 | *.suo 10 | *.user 11 | *.opensdf 12 | *.db 13 | *.local.* 14 | -------------------------------------------------------------------------------- /Binaries_x64.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | res/bin/MediaInfo.x64-sse2.exe 5 | res/bin/MediaInfo.x64-avx2.exe 6 | 7 | 8 | -------------------------------------------------------------------------------- /Binaries_x86.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | res/bin/MediaInfo.x86-i686.exe 5 | res/bin/MediaInfo.x86-sse2.exe 6 | 7 | 8 | -------------------------------------------------------------------------------- /Copying.txt: -------------------------------------------------------------------------------- 1 | MediaInfoXP (minimal GUI for MediaInfo) was created from the scratch by LoRd_MuldeR . 2 | You may use, distribute and copy the MediaInfoXP software under the terms of the GNU General Public License (see 'License.html'). 3 | 4 | The Qt GUI Toolkit is Copyright (C) 2012 Digia Finland Ltd and/or its subsidiary(-ies). 5 | You may use, distribute and copy the Qt GUI Toolkit under the terms of GNU General Public License version 3. 6 | 7 | MediaInfo(Lib) is Copyright (C) 2002-2024 MediaArea.net SARL. 8 | Redistribution and use in source and binary forms, with or without modification, are permitted according to the BSD-2-Clause license. 9 | -------------------------------------------------------------------------------- /MediaInfoXP.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lordmulder/mediainfo-gui/4e87987fe97b5017f821b3f3816c87173e53d7be/MediaInfoXP.ico -------------------------------------------------------------------------------- /MediaInfoXP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lordmulder/mediainfo-gui/4e87987fe97b5017f821b3f3816c87173e53d7be/MediaInfoXP.png -------------------------------------------------------------------------------- /MediaInfoXP.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | 9 | 10 | 11 | $(XPDeprecationWarning) 12 | 13 | 14 | -------------------------------------------------------------------------------- /MediaInfoXP.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | MediaInfoXP.ico 5 | MediaInfoXP.png 6 | res/ico_clear.png 7 | res/ico_discard.png 8 | res/ico_disk.png 9 | res/ico_folder.png 10 | res/ico_info.png 11 | res/ico_link.png 12 | res/ico_options.png 13 | res/ico_paste.png 14 | res/ico_qt.png 15 | res/ico_quit.png 16 | res/ico_shellext.png 17 | res/loading.png 18 | res/logo.png 19 | 20 | 21 | -------------------------------------------------------------------------------- /MediaInfoXP.rcx: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #include "WinResrc.h" //"afxres.h" 4 | #include "src/Version.h" 5 | 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Neutral resources 9 | // 10 | LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | // 14 | // C macro preprocessor 15 | // 16 | #define VERSION_STRING_GLUE_HELPER_STAGE2(X) #X 17 | #define VERSION_STRING_GLUE_HELPER(W,X,Y,Z) VERSION_STRING_GLUE_HELPER_STAGE2(W.X##Y.Z) 18 | #define VERSION_STRING_GLUE(W,X,Y,Z) VERSION_STRING_GLUE_HELPER(W,X,Y,Z) 19 | #define VERSION_STRING VERSION_STRING_GLUE(MIXP_VERSION_MAJOR,MIXP_VERSION_MINOR_HI,MIXP_VERSION_MINOR_LO,MIXP_VERSION_PATCH) 20 | 21 | ///////////////////////////////////////////////////////////////////////////// 22 | // 23 | // Icon 24 | // 25 | 26 | IDI_ICON1 ICON "MediaInfoXP.ico" 27 | 28 | ///////////////////////////////////////////////////////////////////////////// 29 | // 30 | // Version 31 | // 32 | 33 | VS_VERSION_INFO VERSIONINFO 34 | FILEVERSION MIXP_VERSION_MAJOR,MIXP_VERSION_MINOR_HI,MIXP_VERSION_MINOR_LO,MIXP_VERSION_PATCH 35 | PRODUCTVERSION MIXP_VERSION_MAJOR,MIXP_VERSION_MINOR_HI,MIXP_VERSION_MINOR_LO,MIXP_VERSION_PATCH 36 | FILEFLAGSMASK 0x17L 37 | #ifdef _DEBUG 38 | FILEFLAGS 0x3L 39 | #else 40 | FILEFLAGS 0x2L 41 | #endif 42 | FILEOS 0x40004L 43 | FILETYPE 0x1L 44 | FILESUBTYPE 0x0L 45 | BEGIN 46 | BLOCK "StringFileInfo" 47 | BEGIN 48 | BLOCK "000004b0" 49 | BEGIN 50 | VALUE "Author", "LoRd_MuldeR " 51 | VALUE "Comments", "This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY" 52 | VALUE "CompanyName", "Free Software Foundation" 53 | VALUE "FileDescription", "MediaInfoXP - GUI for MediaInfo" 54 | VALUE "FileVersion", VERSION_STRING 55 | VALUE "InternalName", "MediaInfoXP_Qt" 56 | VALUE "LegalCopyright", "Copyright (C) 2004-2024 LoRd_MuldeR " 57 | VALUE "LegalTrademarks", "This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License " 58 | VALUE "OriginalFilename", "MediaInfoXP.exe" 59 | VALUE "ProductName", "MediaInfoXP - GUI for MediaInfo" 60 | VALUE "ProductVersion", VERSION_STRING 61 | VALUE "Website" "http://muldersoft.com/" 62 | END 63 | END 64 | BLOCK "VarFileInfo" 65 | BEGIN 66 | VALUE "Translation", 0x0, 1200 67 | END 68 | END 69 | -------------------------------------------------------------------------------- /MediaInfoXP.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27004.2002 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MediaInfoXP", "MediaInfoXP.vcxproj", "{DCDCCABB-970A-4337-B5BB-7838EE72FE80}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MUtilities", "..\MUtilities\MUtilities_VS2017.vcxproj", "{55405FE1-149F-434C-9D72-4B64348D2A08}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Win32 = Debug|Win32 13 | Release_Static|Win32 = Release_Static|Win32 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {DCDCCABB-970A-4337-B5BB-7838EE72FE80}.Debug|Win32.ActiveCfg = Debug|Win32 17 | {DCDCCABB-970A-4337-B5BB-7838EE72FE80}.Debug|Win32.Build.0 = Debug|Win32 18 | {DCDCCABB-970A-4337-B5BB-7838EE72FE80}.Release_Static|Win32.ActiveCfg = Release_Static|Win32 19 | {DCDCCABB-970A-4337-B5BB-7838EE72FE80}.Release_Static|Win32.Build.0 = Release_Static|Win32 20 | {55405FE1-149F-434C-9D72-4B64348D2A08}.Debug|Win32.ActiveCfg = Debug|Win32 21 | {55405FE1-149F-434C-9D72-4B64348D2A08}.Debug|Win32.Build.0 = Debug|Win32 22 | {55405FE1-149F-434C-9D72-4B64348D2A08}.Release_Static|Win32.ActiveCfg = Release_Static|Win32 23 | {55405FE1-149F-434C-9D72-4B64348D2A08}.Release_Static|Win32.Build.0 = Release_Static|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {BF895B9B-4204-4DFD-ABD4-F3A9EA3A44A5} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /MediaInfoXP.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release_Static 10 | Win32 11 | 12 | 13 | 14 | {DCDCCABB-970A-4337-B5BB-7838EE72FE80} 15 | Win32Proj 16 | QtTestApp 17 | 10.0.14393.0 18 | 19 | 20 | 21 | Application 22 | true 23 | v141 24 | Unicode 25 | 26 | 27 | Application 28 | false 29 | v141 30 | true 31 | Unicode 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | true 47 | $(SolutionDir)\bin\$(Platform)\$(Configuration)\ 48 | $(SolutionDir)\obj\$(Platform)\$(Configuration)\$(ProjectName)\ 49 | 50 | 51 | false 52 | $(SolutionDir)\bin\$(Platform)\$(Configuration)\ 53 | $(SolutionDir)\obj\$(Platform)\$(Configuration)\$(ProjectName)\ 54 | 55 | 56 | 57 | 58 | 59 | Level3 60 | Disabled 61 | WIN32;_DEBUG;_CONSOLE;QT_GUI_LIB;QT_CORE_LIB;QT_THREAD_SUPPORT;QT_DLL;QT_DEBUG;%(PreprocessorDefinitions) 62 | $(QTDIR)\include;$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(SolutionDir)\..\MUtilities\include;$(SolutionDir)\tmp\$(ProjectName);%(AdditionalIncludeDirectories) 63 | NoExtensions 64 | 65 | 66 | Windows 67 | true 68 | $(SolutionDir)\..\Prerequisites\Qt4\v141_xp\Debug\lib;$(SolutionDir)\..\Prerequisites\Qt4\v141_xp\Debug\plugins\imageformats;$(SolutionDir)\..\Prerequisites\EncodePointer\lib;%(AdditionalLibraryDirectories) 69 | QtCored4.lib;QtGuid4.lib;QtSvgd4.lib;Winmm.lib;imm32.lib;ws2_32.lib;Shlwapi.lib;Wininet.lib;PowrProf.lib;psapi.lib;Sensapi.lib;%(AdditionalDependencies) 70 | mxp_entry_point 71 | 5.1 72 | LinkVerboseLib 73 | 74 | 75 | 76 | 77 | Level3 78 | NotUsing 79 | MaxSpeed 80 | true 81 | true 82 | WIN32;NDEBUG;_CONSOLE;MUTILS_STATIC_LIB;QT_GUI_LIB;QT_CORE_LIB;QT_THREAD_SUPPORT;QT_NO_DEBUG;QT_NODLL;%(PreprocessorDefinitions) 83 | $(QTDIR)\include;$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(SolutionDir)\..\MUtilities\include;$(SolutionDir)\tmp\$(ProjectName);%(AdditionalIncludeDirectories) 84 | MultiThreaded 85 | NoExtensions 86 | AnySuitable 87 | Speed 88 | true 89 | Fast 90 | false 91 | false 92 | false 93 | true 94 | true 95 | false 96 | true 97 | 98 | 99 | Windows 100 | false 101 | true 102 | true 103 | $(SolutionDir)\..\Prerequisites\Qt4\v141_xp\Static\lib;$(SolutionDir)\..\Prerequisites\Qt4\v141_xp\Static\plugins\imageformats;$(SolutionDir)\..\Prerequisites\EncodePointer\lib;%(AdditionalLibraryDirectories) 104 | EncodePointer.lib;QtCore.lib;QtGui.lib;QtSvg.lib;qsvg.lib;qico.lib;qtga.lib;Winmm.lib;imm32.lib;ws2_32.lib;Shlwapi.lib;Wininet.lib;PowrProf.lib;psapi.lib;Sensapi.lib;Version.lib;%(AdditionalDependencies) 105 | false 106 | LinkVerboseLib 107 | true 108 | true 109 | "/MANIFESTDEPENDENCY:type=%27win32%27 name=%27Microsoft.Windows.Common-Controls%27 version=%276.0.0.0%27 publicKeyToken=%276595b64144ccf1df%27 language=%27*%27 processorArchitecture=%27*%27" %(AdditionalOptions) 110 | UseLinkTimeCodeGeneration 111 | mxp_entry_point 112 | 5.1 113 | 114 | 115 | 116 | 117 | Document 118 | "$(QTDIR)\bin\uic.exe" -o "$(SolutionDir)tmp\$(ProjectName)\UIC_%(Filename).h" "%(FullPath)" 119 | UIC "$(SolutionDir)\tmp\Common\uic\%(Filename).h" 120 | $(SolutionDir)tmp\$(ProjectName)\UIC_%(Filename).h;%(Outputs) 121 | "$(QTDIR)\bin\uic.exe" -o "$(SolutionDir)tmp\$(ProjectName)\UIC_%(Filename).h" "%(FullPath)" 122 | UIC "$(SolutionDir)\tmp\Common\uic\%(Filename).h" 123 | $(SolutionDir)tmp\$(ProjectName)\UIC_%(Filename).h;%(Outputs) 124 | 125 | 126 | 127 | 128 | Document 129 | "$(QTDIR)\bin\rcc.exe" -o "$(SolutionDir)tmp\$(ProjectName)\QRC_%(Filename).cpp" -name "%(Filename)" "%(FullPath)" 130 | "$(QTDIR)\bin\rcc.exe" -o "$(SolutionDir)tmp\$(ProjectName)\QRC_%(Filename).cpp" -name "%(Filename)" "%(FullPath)" 131 | RCC "$(SolutionDir)tmp\$(ProjectName)\QRC_%(Filename).cpp" 132 | RCC "$(SolutionDir)tmp\$(ProjectName)\QRC_%(Filename).cpp" 133 | $(SolutionDir)tmp\$(ProjectName)\QRC_%(Filename).cpp;%(Outputs) 134 | $(SolutionDir)tmp\$(ProjectName)\QRC_%(Filename).cpp;%(Outputs) 135 | Designer 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | "$(QTDIR)\bin\moc.exe" -o "$(SolutionDir)\tmp\$(ProjectName)\MOC_%(Filename).cpp" "%(FullPath)" 153 | "$(QTDIR)\bin\moc.exe" -o "$(SolutionDir)\tmp\$(ProjectName)\MOC_%(Filename).cpp" "%(FullPath)" 154 | MOC "$(SolutionDir)\tmp\$(ProjectName)\MOC_%(Filename).cpp" 155 | MOC "$(SolutionDir)\tmp\$(ProjectName)\MOC_%(Filename).cpp" 156 | $(SolutionDir)\tmp\$(ProjectName)\MOC_%(Filename).cpp;%(Outputs) 157 | $(SolutionDir)\tmp\$(ProjectName)\MOC_%(Filename).cpp;%(Outputs) 158 | "$(QTDIR)\bin\moc.exe" -o "$(SolutionDir)\tmp\$(ProjectName)\MOC_%(Filename).cpp" "%(FullPath)" 159 | MOC "$(SolutionDir)\tmp\$(ProjectName)\MOC_%(Filename).cpp" 160 | $(SolutionDir)\$(ProjectName)\moc\MOC_%(Filename).cpp;%(Outputs) 161 | 162 | 163 | 164 | 165 | 166 | 167 | "$(QTDIR)\bin\moc.exe" -o "$(SolutionDir)\tmp\$(ProjectName)\MOC_%(Filename).cpp" "%(FullPath)" 168 | "$(QTDIR)\bin\moc.exe" -o "$(SolutionDir)\tmp\$(ProjectName)\MOC_%(Filename).cpp" "%(FullPath)" 169 | MOC "$(SolutionDir)\tmp\$(ProjectName)\MOC_%(Filename).cpp" 170 | MOC "$(SolutionDir)\tmp\$(ProjectName)\MOC_%(Filename).cpp" 171 | $(SolutionDir)\tmp\$(ProjectName)\MOC_%(Filename).cpp;%(Outputs) 172 | $(SolutionDir)\tmp\$(ProjectName)\MOC_%(Filename).cpp;%(Outputs) 173 | "$(QTDIR)\bin\moc.exe" -o "$(SolutionDir)\tmp\$(ProjectName)\MOC_%(Filename).cpp" "%(FullPath)" 174 | MOC "$(SolutionDir)\tmp\$(ProjectName)\MOC_%(Filename).cpp" 175 | $(SolutionDir)\$(ProjectName)\moc\MOC_%(Filename).cpp;%(Outputs) 176 | 177 | 178 | 179 | 180 | 181 | Document 182 | 183 | 184 | 185 | 186 | {55405fe1-149f-434c-9d72-4b64348d2a08} 187 | 188 | 189 | 190 | 191 | Document 192 | "$(QTDIR)\bin\rcc.exe" -o "$(SolutionDir)tmp\$(ProjectName)\QRC_%(Filename).cpp" -name "%(Filename)" "%(FullPath)" 193 | "$(QTDIR)\bin\rcc.exe" -o "$(SolutionDir)tmp\$(ProjectName)\QRC_%(Filename).cpp" -name "%(Filename)" "%(FullPath)" 194 | RCC "$(SolutionDir)tmp\$(ProjectName)\QRC_%(Filename).cpp" 195 | RCC "$(SolutionDir)tmp\$(ProjectName)\QRC_%(Filename).cpp" 196 | $(SolutionDir)tmp\$(ProjectName)\QRC_%(Filename).cpp;%(Outputs) 197 | $(SolutionDir)tmp\$(ProjectName)\QRC_%(Filename).cpp;%(Outputs) 198 | 199 | 200 | Document 201 | "$(QTDIR)\bin\rcc.exe" -o "$(SolutionDir)tmp\$(ProjectName)\QRC_%(Filename).cpp" -name "%(Filename)" "%(FullPath)" 202 | "$(QTDIR)\bin\rcc.exe" -o "$(SolutionDir)tmp\$(ProjectName)\QRC_%(Filename).cpp" -name "%(Filename)" "%(FullPath)" 203 | RCC "$(SolutionDir)tmp\$(ProjectName)\QRC_%(Filename).cpp" 204 | RCC "$(SolutionDir)tmp\$(ProjectName)\QRC_%(Filename).cpp" 205 | $(SolutionDir)tmp\$(ProjectName)\QRC_%(Filename).cpp;%(Outputs) 206 | $(SolutionDir)tmp\$(ProjectName)\QRC_%(Filename).cpp;%(Outputs) 207 | 208 | 209 | 210 | 211 | 212 | -------------------------------------------------------------------------------- /MediaInfoXP.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {662311f2-44ab-48a8-8b5b-640453b3422f} 18 | 19 | 20 | {4cc9136e-0434-4027-ae2c-d4c148dd8ed9} 21 | 22 | 23 | {e066a4c2-fc34-4e1b-948e-1a3eea8e277f} 24 | 25 | 26 | 27 | 28 | Dialogs 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Resources 38 | 39 | 40 | Resources 41 | 42 | 43 | Resources 44 | 45 | 46 | 47 | 48 | Source Files 49 | 50 | 51 | Source Files 52 | 53 | 54 | Source Files 55 | 56 | 57 | Source Files 58 | 59 | 60 | Source Files\Generated 61 | 62 | 63 | Source Files\Generated 64 | 65 | 66 | Source Files\Generated 67 | 68 | 69 | Source Files 70 | 71 | 72 | Source Files\Generated 73 | 74 | 75 | Source Files\Generated 76 | 77 | 78 | 79 | 80 | Header Files 81 | 82 | 83 | Header Files 84 | 85 | 86 | Header Files 87 | 88 | 89 | 90 | 91 | Resources 92 | 93 | 94 | -------------------------------------------------------------------------------- /ReadMe.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lordmulder/mediainfo-gui/4e87987fe97b5017f821b3f3816c87173e53d7be/ReadMe.txt -------------------------------------------------------------------------------- /doc/License.MediaInfo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | MediaInfo(Lib) License 6 | 7 | 8 | 9 |
10 |

MediaInfo(Lib) License

11 | 12 |

Copyright (c) 2002-2024 MediaArea.net SARL. All rights reserved.

13 | 14 |

Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions are 16 | met:

17 | 18 |
    19 |
  • Redistributions of source code must retain the above copyright 20 | notice, this list of conditions and the following disclaimer.
  • 21 | 22 |
  • Redistributions in binary form must reproduce the above copyright 23 | notice, this list of conditions and the following disclaimer in 24 | the documentation and/or other materials provided with the 25 | distribution.
  • 26 |
27 | 28 |

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 |

40 |
41 | 42 |
43 |
44 |

Third party libraries

45 |

46 | The software relies on third party libraries. Such libraries have their own license: 47 |

    48 |
  • C++ standard library: libstdc++, libc++, Visual C++ library or any other C++ standard library.
  • 49 |
  • Base classes library: ZenLib, (c) MediaArea.net SARL, zlib license.
  • 50 |
  • GUI (optional): Qt.
  • 51 |
  • GUI (optional): WxWidgets.
  • 52 |
  • XML parser (optional): TinyXML-2.
  • 53 |
  • gzip decompression routine (optional): zlib.
  • 54 |
  • FTP, FTPS, SFTP, HTTP, HTTPS (optional): libcurl.
  • 55 |
  • MMS (optional): libmms.
  • 56 |
57 |

58 |
59 | 60 |
61 |
62 |

Contributors

63 |

64 |

    65 |
  • Jérôme Martinez (main developper)
  • 66 |
  • Lionel Duchateau (odd formats support)
  • 67 |
  • MPC-HC team (tests)
  • 68 |
  • FlylinkDC++ team (tests)
  • 69 |
  • Max Pozdeev (former native Mac GUI developper)
  • 70 |
71 |

72 |
73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /doc/License.Qt.html: -------------------------------------------------------------------------------- 1 | 2 | Qt LICENSE AGREEMENT
  3 | Qt LICENSE AGREEMENT
  4 | Agreement version 3.9.2
  5 | 
  6 | This  License Agreement for Qt ("Agreement") is a legal agreement between Digia Finland Ltd ("Digia"), with its registered office at Valimotie 21, FI-00380 Helsinki, Finland and you (either an individual or a legal entity) ("Licensee") for the Licensed Software (as defined below).
  7 | 
  8 | 1. DEFINITIONS
  9 | "Affiliate" of a Party shall mean an entity (i) which is directly or indirectly controlling such Party; (ii) which is under the same direct or indirect ownership or control as such Party; or (iii) which is directly or indirectly owned or controlled by such Party.  For these purposes, an entity shall be treated as being controlled by another if that other entity has fifty percent (50 %) or more of the votes in such entity, is able to direct its affairs and/or to control the composition of its board of directors or equivalent body.  
 10 | "Applications" shall mean Licensee's software products created using the Licensed Software which may include portions of the Licensed Software.
 11 | "Designated User(s)" shall mean the employee(s) of Licensee acting within the scope of their employment or Licensee's consultant(s) or contractor(s) acting within the scope of their services for Licensee and on behalf of Licensee.
 12 | "Initial Term" shall mean the period of time one (1) year from the later of (a) the Effective Date; or (b) the date the Licensed Software was initially delivered to Licensee by Digia.  If no specific Effective Date is set forth in the Agreement, the Effective Date shall be deemed to be the date the Licensed Software was initially delivered to Licensee.
 13 | "License Certificate" shall mean the document accompanying the Licensed Software which specifies the modules which are licensed under the Agreement, Platforms and Designated Users.  
 14 | "Licensed Software" shall mean the computer software, "online" or electronic documentation, associated media and printed materials, including the source code, example programs and the documentation delivered by Digia to Licensee in conjunction with this Agreement.  Licensed Software does not include Third Party Software (as defined in Section 7).
 15 | "Modified Software" shall mean modifications made to the Licensed Software by Licensee.
 16 | "Nokia" shall mean Digia Plc, a corporation incorporated under the laws of Finland, having its registered office at PO box 226, 00045 Nokia Group, Finland (visiting address Keilalahdentie 4, 02150 Espoo, Finland) and registered with the Finnish Trade Register under business ID 0112038-9 and acting on behalf of its respective Affiliates.
 17 | "Party or Parties" shall mean Licensee and/or Digia.
 18 | "Platforms" shall mean the operating systems listed in the License Certificate. 
 19 | "Redistributables" shall mean the portions of the Licensed Software set forth in Appendix 1, Section 1 that may be distributed with or as part of Applications in object code form.
 20 | "Support" shall mean standard developer support that is provided by Digia to assist eligible Designated Users in using the Licensed Software in accordance with its established standard support procedures listed at:  http://qt.digia.com/
 21 | "Updates" shall mean a release or version of the Licensed Software containing enhancement, new features, bug fixes, error corrections and other changes that are generally made available to users of the Licensed Software that have contracted for maintenance and support.
 22 | 
 23 | 2. OWNERSHIP
 24 | The Licensed Software is protected by copyright laws and international copyright treaties, as well as other intellectual property laws and treaties. The Licensed Software is licensed, not sold.  
 25 | To the extent Licensee submits bug fixes or error corrections, including information related thereto, Licensee hereby grants to Digia a sublicensable, irrevocable, perpetual, worldwide, non-exclusive, royalty-free and fully paid-up copyright and trade secret license to reproduce, adapt, translate, modify, and prepare derivative works of, publicly display, publicly perform, sublicense, make available and distribute error corrections and bug fixes, including derivative works thereof.  All Digia's and/or its licensors' trademarks, service marks, trade names, logos or other words or symbols are and shall remain the exclusive property of Digia or its licensors respectively.
 26 | 
 27 | 3. MODULES
 28 | Some of the files in the Licensed Software have been grouped into modules. These files contain specific notices defining the module of which they are a part. The modules licensed to Licensee are specified in the License Certificate. The terms of the License Certificate are considered part of the Agreement. In the event of inconsistency or conflict between the language of this Agreement and the License Certificate, the provisions of this Agreement shall govern.
 29 |  
 30 | 4. VALIDITY OF THE AGREEMENT
 31 | By installing, copying, or otherwise using the Licensed Software, Licensee agrees to be bound by the terms of this Agreement. If Licensee does not agree to the terms of this Agreement, Licensee may not install, copy, or otherwise use the Licensed Software.  In addition, by installing, copying, or otherwise using any Updates or other components of the Licensed Software that Licensee receives separately as part of the Licensed Software, Licensee agrees to be bound by any additional license terms that accompany such Updates, if any. If Licensee does not agree to the additional license terms that accompany such Updates, Licensee may not install, copy, or otherwise use such Updates.
 32 | Upon Licensee's acceptance of the terms and conditions of this Agreement, Digia grants Licensee the right to use the Licensed Software in the manner provided below.
 33 | 
 34 | 5. LICENSES
 35 | 5.1 Using, modifying and copying
 36 | Digia grants to Licensee a non-exclusive, non-transferable, perpetual license to use, modify and copy the Licensed Software for the Designated User(s) specified in the License Certificate for the sole purposes of designing, developing, and testing Application(s). 
 37 | Licensee may install copies of the Licensed Software on an unlimited number of computers provided that only the Designated Users use the Licensed Software. Licensee may at any time designate another Designated User to replace a then-current Designated User by notifying Digia, provided that a) the then-current Designated User has not been designated as a replacement during the last six (6) months; and b) there is no more than the specified number of Designated Users at any given time. 
 38 | 
 39 | 5.2	Redistribution
 40 | a) Digia grants Licensee a non-exclusive, royalty-free right to reproduce and distribute the object code form of Redistributables for execution on the specified Platforms. Copies of Redistributables may only be distributed with and for the sole purpose of executing Applications permitted under this Agreement that Licensee has created using the Licensed Software. Under no circumstances may any copies of Redistributables be distributed separately. This Agreement does not give Licensee any rights to distribute any of the parts of the Licensed Software listed in Appendix 1, Section 2, neither as a whole nor as parts or snippets of code. 
 41 | b) Licensee may not distribute, transfer, assign or otherwise dispose of Applications and/or Redistributables, in binary/compiled form, or in any other form, if such action is part of a joint software and hardware distribution, except as provided by a separate runtime distribution license with Digia or one of its authorized distributors.  A joint hardware and software distribution shall be defined as either:  
 42 | (i) 	distribution of a hardware device where, in its final end user configuration, the main user interface of the device is provided by Application(s) created by Licensee or others, using the Licensed Software, and depends on the Licensed Software or any Qt or Qt-based software product; or 
 43 | (ii) 	distribution of the Licensed Software with a device designed to facilitate the installation of the Licensed Software onto the same device where the main user interface of such device is provided by Application(s) created by Licensee or others, using the Licensed Software or any Qt or a Qt-based product, and depends on the Licensed Software.
 44 | 
 45 | 5.3	Further Requirements
 46 | It is expressly acknowledged and understood by Licensee, that Licensee is strictly prohibited from using Licensed Software for creation of mobile phones or tablet computers targeted for consumer end users. 
 47 | The aforementioned shall not prohibit Licensee from using Licensed Software for the purpose of creating of applications for any devices, including mobile phone and tablet computers.
 48 | Notwithstanding anything contrary to this Agreement, it is expressly acknowledged and understood by Licensee, that Nokia shall hereby be named as a third party beneficiary under this Agreement with respect to this Section 5.3. Therefore, Nokia shall have the same rights as Digia under this Agreement with respect to this Section 5.3, and shall be entitled to exercise such rights independent from Digia. 
 49 | The licenses granted in this Section 5 by Digia to Licensee and Licensee Affiliates are subject to Licensee and Licensee Affiliate's compliance with Section 8 of this Agreement.
 50 | 6. VERIFICATION
 51 | Digia or a certified auditor on Digia's behalf, may, upon its reasonable request and at its expense, audit Licensee with respect to the use of the Licensed Software. Such audit may be conducted by mail, electronic means or through an in-person visit to Licensee's place of business.  Any such in-person audit shall be conducted during regular business hours at Licensee's facilities and shall not unreasonably interfere with Licensee's business activities. Digia shall not remove, copy, or redistribute any electronic material during the course of an audit. If an audit reveals that Licensee is using the Licensed Software in a way that is in material violation of the terms of the Agreement, then Licensee shall pay Digia's reasonable costs of conducting the audit. In the case of a material violation, Licensee agrees to pay Digia any amounts owing that are attributable to the unauthorized use. In the alternative, Digia reserves the right, at Digia's sole option, to terminate the licenses for the Licensed Software.
 52 | 
 53 | 7. THIRD PARTY SOFTWARE
 54 | The Licensed Software may provide links to third party libraries or code (collectively "Third Party Software") to implement various functions.  Third Party Software does not comprise part of the Licensed Software. In some cases, access to Third Party Software may be included along with the Licensed Software delivery as a convenience for development and testing only. Such source code and libraries may be listed in the ".../src/3rdparty" source tree delivered with the Licensed Software or documented in the Licensed Software where the Third Party Software is used, as may be amended from time to time, do not comprise the Licensed Software.  Licensee acknowledges (1) that some part of Third Party Software may require additional licensing of copyright and patents from the owners of such, and (2) that distribution of any of the Licensed Software referencing any portion of a Third Party Software may require appropriate licensing from such third parties.  
 55 | 
 56 | 8. CONDITIONS FOR CREATING APPLICATIONS AND DISTRIBUTING REDISTRIBUTABLES
 57 | The licenses granted in this Agreement for Licensee to create Applications and distribute them and the Redistributables (if any) to Licensee's customers is subject to all of the following conditions: (i) all copies of the Applications which Licensee creates must bear a valid copyright notice, either Licensee's own or the copyright notice that appears on the Licensed Software; (ii) Licensee may not remove or alter any copyright, trademark or other proprietary rights notice contained in any portion of the Licensed Software, including but not limited to the About Boxes in "Qt Assistant" and "Qt Linguist" as defined in Appendix 1; (iii) Redistributables, if any, shall be licensed to Licensee's customer "as is"; (iv) Licensee shall indemnify and hold Digia, its Affiliates, contractors, licensors, and  suppliers, harmless from and against any claims or liabilities arising out of the use, reproduction or distribution of Applications; (v) Applications must be developed using a licensed, registered copy of the Licensed Software; (vi) Applications must add primary and substantial functionality to the Licensed Software; (vii) Applications may not pass on functionality which in any way makes it possible for others to create software with the Licensed Software, however Licensee may use the Licensed Software's scripting and QML ("Qt Quick") functionality solely in order to enable scripting, themes and styles that augment the functionality and appearance of the Application(s) without adding primary and substantial functionality to the Application(s); (viii) Applications may not compete with the Licensed Software; (ix) Licensee may not use Digia's or any of its suppliers' names, logos, or trademarks to market Application(s), except to state that Application was developed using the Licensed Software.
 58 | NOTE:  The Open Source Editions of Qt products and the Qt, Qtopia and Qt Extended versions licensed by Digia and previously licensed by Nokia and Trolltech (collectively referred to as "Open- source Qt Products") are licensed under the terms of the GNU Lesser General Public License version 2.1 ("LGPL") and/or the GNU General Public License versions 2.0 and 3.0 ("GPL") (as applicable) and not under this Agreement.  If Licensee, or another third party, has, at any time, developed all (or any portions of) the Application(s) using a version of one of these Open-source Qt Products licensed under the LGPL or the GPL, Licensee may not combine such development work with the Licensed Software and must license such Application(s) (or any portions derived there from) under the terms of the GNU Lesser General Public License version 2.1 (Qt only) or GNU General Public License version 2.0 (Qt, Qtopia and Qt Extended) or version 3 (Qt only) copies of which are located at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html, http://www.fsf.org/licensing/licenses/info/GPLv2.html, and http://www.gnu.org/copyleft/gpl.html.
 59 | 
 60 | 9. LIMITED WARRANTY AND WARRANTY DISCLAIMER
 61 | Digia hereby represents and warrants with respect to the Licensed Software that it has the power and authority to grant the rights and licenses granted to Licensee under this Agreement. Except as set forth above, the Licensed Software is licensed to Licensee "as is". To the maximum extent permitted by applicable law, Digia on behalf of itself,  suppliers, and licensors disclaims all warranties and conditions, either express or implied, including, but not limited to, implied warranties of merchantability, fitness for a particular purpose, title and non-infringement with regard to the Licensed Software.
 62 | 
 63 | 10. LIMITATION OF LIABILITY 
 64 | If, Digia's warranty disclaimer notwithstanding, Digia is held liable to Licensee, whether in contract, tort or any other legal theory, based on the Licensed Software, Digia's entire liability to Licensee and Licensee's exclusive remedy shall be, at Digia's option, either (A) return of the price Licensee paid for the Licensed Software, or (B) repair or replacement of the Licensed Software, provided Licensee returns to Digia all copies of the Licensed Software as originally delivered to Licensee. Digia shall not under any circumstances be liable to Licensee based on failure of the Licensed Software if the failure resulted from accident, abuse or misapplication, nor shall Digia under any circumstances be liable for special damages, punitive or exemplary damages, damages for loss of profits or interruption of business or for loss or corruption of data. Any award of damages from Digia to Licensee shall not exceed the total amount Licensee has paid to Digia in connection with this Agreement. 
 65 | 
 66 | 11. SUPPORT AND UPDATES 
 67 | Licensee shall be eligible to receive Support and Updates during the Initial Term, in accordance with Digia's then current policies and procedures, if any. Such policies and procedures may be changed from time to time. Following the Initial Term, Digia shall no longer make the Licensed Software available to Licensee unless Licensee purchases additional Support and Updates according to this Section 11 below.
 68 | Licensee may purchase additional Support and Updates following the Initial Term at Digia's terms and conditions applicable at the time of renewal. 
 69 | 
 70 | 12. CONFIDENTIALITY
 71 | Each party acknowledges that during the Initial Term of this Agreement it shall have access to information about the other party's business, business methods, business plans, customers, business relations, technology, and other information, including the terms of this Agreement, that is confidential and of great value to the other party, and the value of which would be significantly reduced if disclosed to third parties (the "Confidential Information"). Accordingly, when a party (the "Receiving Party") receives Confidential Information from another party (the "Disclosing Party"), the Receiving Party shall, and shall obligate its employees and agents and employees and agents of its affiliates to: (i) maintain the Confidential Information in strict confidence; (ii) not disclose the Confidential Information to a third party without the Disclosing Party's prior written approval; and (iii) not, directly or indirectly, use the Confidential Information for any purpose other than for exercising its rights and fulfilling its responsibilities pursuant to this Agreement. Each party shall take reasonable measures to protect the Confidential Information of the other party, which measures shall not be less than the measures taken by such party to protect its own confidential and proprietary information. 
 72 | "Confidential Information" shall not include information that (a) is or becomes generally known to the public through no act or omission of the Receiving Party; (b) was in the Receiving Party's lawful possession prior to the disclosure hereunder and was not subject to limitations on disclosure or use; (c) is developed by employees of the Receiving Party or other persons working for the Receiving Party who have not had access to the Confidential Information of the Disclosing Party, as proven by the written records of the Receiving Party or by persons who have not had access to the Confidential Information of the Disclosing Party as proven by the written records of the Receiving Party; (d) is lawfully disclosed to the Receiving Party without restrictions, by a third party not under an obligation of confidentiality; or (e) the Receiving Party is legally compelled to disclose the information, in which case the Receiving Party shall assert the privileged and confidential nature of the information and cooperate fully with the Disclosing Party to protect against and prevent disclosure of any Confidential Information and to limit the scope of disclosure and the dissemination of disclosed Confidential Information by all legally available means. 
 73 | The obligations of the Receiving Party under this Section shall continue during the Initial Term and for a period of five (5) years after expiration or termination of this Agreement.  To the extent that the terms of the Non-Disclosure Agreement between Digia and Licensee conflict with the terms of this Section 12, this Section 12 shall be controlling over the terms of the Non-Disclosure Agreement.
 74 | 
 75 | 13. GENERAL PROVISIONS
 76 | 13.1	Marketing
 77 | Digia may include Licensee's company name and logo in a publicly available list of Digia customers and in its public communications.
 78 | 
 79 | 13.2	No Assignment
 80 | Licensee shall not be entitled to assign or transfer all or any of its rights, benefits and obligations under this Agreement without the prior written consent of Digia, which shall not be unreasonably withheld. Digia shall be entitled to assign or transfer any of its rights, benefits or obligations under this Agreement on an unrestricted basis.
 81 | 
 82 | 13.3 	Termination
 83 | Digia may terminate the Agreement at any time immediately upon written notice by Digia to Licensee if Licensee breaches this Agreement.  
 84 | Either party shall have the right to terminate this Agreement immediately upon written notice in the event that the other party becomes insolvent, files for any form of bankruptcy, makes any assignment for the benefit of creditors, has a receiver, administrative receiver or officer appointed over the whole or a substantial part of its assets, ceases to conduct business, or an act equivalent to any of the above occurs under the laws of the jurisdiction of the other party.
 85 | Upon termination of this Agreement, Licensee shall return to Digia all copies of Licensed Software that were supplied by Digia. All other copies of Licensed Software in the possession or control of Licensee must be erased or destroyed. An officer of Licensee must promptly deliver to Digia a written confirmation that this has occurred.
 86 | 
 87 | 13.4	Surviving Sections 
 88 | Any terms and conditions that by their nature or otherwise reasonably should survive a cancellation or termination of this Agreement shall also be deemed to survive.  Such terms and conditions include, but are not limited to the following Sections: 2, 5.1, 6, 7, 8(iv), 10, 12, 13.5, 13.6, 13.9, 13.10 and 13.11 of this Agreement.  Notwithstanding the foregoing, Section 5.1 shall not survive if the Agreement is terminated for material breach.
 89 | 
 90 | 13.5	Entire Agreement 
 91 | This Agreement constitutes the complete agreement between the parties and supersedes all prior or contemporaneous discussions, representations, and proposals, written or oral, with respect to the subject matters discussed herein, with the exception of the non-disclosure agreement executed by the parties in connection with this Agreement ("Non-Disclosure Agreement"), if any, shall be subject to Section 12. No modification of this Agreement shall be effective unless contained in a writing executed by an authorized representative of each party. No term or condition contained in Licensee's purchase order shall apply unless expressly accepted by Digia in writing. If any provision of the Agreement is found void or unenforceable, the remainder shall remain valid and enforceable according to its terms. If any remedy provided is determined to have failed for its essential purpose, all limitations of liability and exclusions of damages set forth in this Agreement shall remain in effect.
 92 | 
 93 | 13.6	Payment and Taxes 
 94 | If credit has been extended to Licensee by Digia, all payments under this Agreement are due within thirty (30) days of the date Digia mails its invoice to Licensee.  If Digia has not extended credit to Licensee, Licensee shall be required to make payment concurrent with the delivery of the Licensed Software by Digia.  All amounts payable are gross amounts but exclusive of any value added tax, use tax, sales tax or similar tax. Licensee shall be entitled to withhold from payments any applicable withholding taxes and comply with all applicable tax and employment legislation.  Each party shall pay all taxes (including, but not limited to, taxes based upon its income) or levies imposed on it under applicable laws, regulations and tax treaties as a result of this Agreement and any payments made hereunder (including those required to be withheld or deducted from payments).  Each party shall furnish evidence of such paid taxes as is sufficient to enable the other party to obtain any credits available to it, including original withholding tax certificates. 
 95 | 
 96 | 13.7	Force Majeure  
 97 | Neither party shall be liable to the other for any delay or non-performance of its obligations hereunder other than the obligation of paying the license fees in the event and to the extent that such delay or non-performance is due to an event of Force Majeure (as defined below).  If any event of Force Majeure results in a delay or non-performance of a party for a period of three (3) months or longer, then either party shall have the right to terminate this Agreement with immediate effect without any liability (except for the obligations of payment arising prior to the event of Force Majeure) towards the other party.  A "Force Majeure" event shall mean an act of God, terrorist attack or other catastrophic event of nature that prevents either party for fulfilling its obligations under this Agreement.
 98 | 
 99 | 13.8	Notices
100 | Any notice given by one party to the other shall be deemed properly given and deemed received if specifically acknowledged by the receiving party in writing or when successfully delivered to the recipient by hand, fax, or special courier during normal business hours on a business day to the addresses specified below.  Each communication and document made or delivered by one party to the other party pursuant to this Agreement shall be in the English language or accompanied by a translation thereof.
101 | 
102 | Notices to Digia shall be given to: 
103 | Digia Finland Ltd
104 |     Attn: Qt / Legal
105 | Valimotie 21
106 | FI-00380 Helsinki
107 | Finland
108 | Fax: +358 10 313 3700
109 | 
110 | 13.9	Export Control
111 | Licensee acknowledges that the Licensed Software may be subject to export control restrictions of various countries.  Licensee shall fully comply with all applicable export license restrictions and requirements as well as with all laws and regulations relating to the importation of the Licensed Software and/or Modified Software and/or Applications and shall procure all necessary governmental authorizations, including without limitation, all necessary licenses, approvals, permissions or consents, where necessary for the re-exportation of the Licensed Software, Modified Software or Applications.
112 | 
113 | 13.10	Governing Law and Legal Venue
114 | This Agreement shall be construed and interpreted in accordance with the laws of Finland, excluding its choice of law provisions. Any disputes, controversy or claim  arising out of or relating to this Agreement, or the breach, termination or validity thereof shall be shall be finally settled by arbitration in accordance with the Arbitration Rules of the Central Chamber of Commerce of Finland.   The arbitration tribunal shall consist of one (1), or if either Party so requires, of three (3), arbitrators. The award shall be final and binding and enforceable in any court of competent jurisdiction. The arbitration shall be held in Helsinki, Finland and the process shall be conducted in the English language.
115 | 
116 | 13.11 No Implied License
117 | There are no implied licenses or other implied rights granted under this Agreement, and all rights, save for those expressly granted hereunder, shall remain with Digia and its licensors.  In addition, no licenses or immunities are granted to the combination of the Licensed Software and/or Modified Software, as applicable, with any other software or hardware not delivered by Digia under this Agreement.
118 | 
119 | 
120 |  
121 | Appendix 1
122 | 
123 | 1. Parts of the Licensed Software that are permitted for distribution ("Redistributables"):
124 | - The Licensed Software's main and plug-in libraries in object code form
125 | - The Licensed Software's configuration tool ("qtconfig")
126 | - The Licensed Software's help tool in object code/executable form ("Qt Assistant")
127 | - The Licensed Software's internationalization tools in object code/executable form ("Qt Linguist", "lupdate", "lrelease")
128 | - The Licensed Software's designer tool ("Qt Designer")
129 | - The Licensed Software's IDE tool ("Qt Creator")
130 | - The Licensed Software's QML ("Qt Quick") launcher tool in object code/executable form
131 | 
132 | 
133 | 2. Parts of the Licensed Software that are not permitted for distribution include, but are not limited to: 
134 | - The Licensed Software's source code and header files
135 | - The Licensed Software's documentation
136 | - The Licensed Software's tool for writing makefiles ("qmake")
137 | - The Licensed Software's Meta Object Compiler ("moc")
138 | - The Licensed Software's User Interface Compiler ("uic" or in the case of Qt Jambi: "juic")
139 | - The Licensed Software's Resource Compiler ("rcc")
140 | - The Licensed Software's generator (only in the case of Qt Jambi if applicable)
141 | - The Licensed Software's Qt SDK and its components
142 | 
143 | QT COMMERCIAL LICENSE AGREEMENT
144 | 
145 | 
146 | DIGIA FINLAND LTD | VALIMOTIE 21 | FI-00380 HELSINKI FINLAND | TEL +358 (0) 10
147 | 313 3000 | FAX +358 (0) 10 313 3700
148 | PLACE OF REGISTERED OFFICE: HELSINKI | VAT REG. | BUSINESS ID 1091248-4 |
149 | WWW.DIGIA.COM
150 | 
-------------------------------------------------------------------------------- /doc/License.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | MediaInfo(Lib) License 6 | 7 | 8 | 9 |
10 |

MediaInfo(Lib) License

11 |

12 | Copyright (c) 2002-2024 MediaArea.net SARL. All rights reserved. 13 |

14 |

15 | Redistribution and use in source and binary forms, with or without modification, 16 | are permitted provided that the following conditions are met: 17 |

18 |
    19 |
  • Redistributions of source code must retain the above copyright notice, 20 | this list of conditions and the following disclaimer.
  • 21 |
  • Redistributions in binary form must reproduce the above copyright notice, 22 | this list of conditions and the following disclaimer in the documentation and/or 23 | other materials provided with the distribution.
  • 24 |
25 |

26 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” 27 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 28 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 29 | COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 30 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 31 | GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 32 | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 34 | OF THE POSSIBILITY OF SUCH DAMAGE. 35 |

36 |
37 | 38 |
39 |
40 |

Alternate license for redistributions of the library in binary form:
41 | Redistributions in binary form must reproduce the following sentence (including the link to the website) in the documentation and/or other materials provided with the distribution.
42 | This product uses MediaInfo library, Copyright (c) 2002-2024 MediaArea.net SARL.

43 |
44 | 45 |
46 |
47 |

Third party libraries

48 |

49 | The software relies on third party libraries. Such libraries have their own license: 50 |

51 |
    52 |
  • C++ standard library: libstdc++, 53 | libc++, 54 | Visual C++ library or any other C++ standard library. 55 |
  • 56 |
  • Base classes library: ZenLib, (c) MediaArea.net SARL, zlib license.
  • 57 |
  • GUI (optional): Qt.
  • 58 |
  • GUI (optional): WxWidgets.
  • 59 |
  • XML parser (optional): TinyXML-2.
  • 60 |
  • gzip decompression routine (optional): zlib.
  • 61 |
  • FTP, FTPS, SFTP, HTTP, HTTPS (optional): libcurl.
  • 62 |
  • MMS (optional): libmms.
  • 63 |
64 |
65 | 66 |
67 |
68 |

Contributors

69 |
    70 |
  • Jérôme Martinez (main developper)
  • 71 |
  • Lionel Duchateau (odd formats support)
  • 72 |
  • XhmikosR from MPC-HC Team (tests)
  • 73 |
  • FlylinkDC++ team (tests, crash corrections)
  • 74 |
  • Max Pozdeev (former native Mac GUI developper)
  • 75 |
76 |
77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /doc/README.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | README 4 | 5 | 205 | 206 | 207 | 208 |

MediaInfoLib README

209 |

MediaInfo(Lib) is a convenient unified display of the most relevant technical and tag data for video and audio files.

210 |

Build Status

211 |

MediaInfoLib - https://github.com/MediaArea/MediaInfoLib
212 | Copyright (c) MediaArea.net SARL. All Rights Reserved.

213 |

This program is freeware under BSD-2-Clause license conditions.
214 | See License.html for more information

215 | 216 | 217 | 218 | 219 | 220 | -------------------------------------------------------------------------------- /doc/README.svg: -------------------------------------------------------------------------------- 1 | buildbuildpassingpassing -------------------------------------------------------------------------------- /gui/Dialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 800 10 | 384 11 | 12 | 13 | 14 | MediaInfoXP - Minimalist GUI for MediaInfo 15 | 16 | 17 | 18 | :/MediaInfoXP.png:/MediaInfoXP.png 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | Qt::ScrollBarAlwaysOff 28 | 29 | 30 | QTextEdit::NoWrap 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 170 43 | 0 44 | 0 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 170 54 | 0 55 | 0 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 120 65 | 120 66 | 120 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 75 76 | true 77 | 78 | 79 | 80 | QFrame::StyledPanel 81 | 82 | 83 | (UPDATE_INFO) 84 | 85 | 86 | Qt::AlignCenter 87 | 88 | 89 | 2 90 | 91 | 92 | true 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 150 103 | 25 104 | 105 | 106 | 107 | Analyze File.... 108 | 109 | 110 | 111 | :/MediaInfoXP.png:/MediaInfoXP.png 112 | 113 | 114 | 115 | 116 | 117 | 118 | Qt::Horizontal 119 | 120 | 121 | 122 | 40 123 | 20 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 0 133 | 0 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 91 143 | 70 144 | 70 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 91 154 | 70 155 | 70 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 120 165 | 120 166 | 120 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | PointingHandCursor 175 | 176 | 177 | (VERSION_INFO) 178 | 179 | 180 | Qt::AlignCenter 181 | 182 | 183 | 184 | 185 | 186 | 187 | Qt::Horizontal 188 | 189 | 190 | 191 | 40 192 | 20 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 150 202 | 25 203 | 204 | 205 | 206 | Exit Program 207 | 208 | 209 | 210 | :/res/ico_quit.png:/res/ico_quit.png 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 0 224 | 0 225 | 800 226 | 21 227 | 228 | 229 | 230 | 231 | Application 232 | 233 | 234 | 235 | Preferences 236 | 237 | 238 | 239 | :/res/ico_options.png:/res/ico_options.png 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | Help 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | :/res/ico_quit.png:/res/ico_quit.png 273 | 274 | 275 | Exit 276 | 277 | 278 | 279 | 280 | 281 | :/res/ico_info.png:/res/ico_info.png 282 | 283 | 284 | About... 285 | 286 | 287 | 288 | 289 | 290 | :/res/ico_folder.png:/res/ico_folder.png 291 | 292 | 293 | Open Media File... 294 | 295 | 296 | 297 | 298 | 299 | :/res/ico_link.png:/res/ico_link.png 300 | 301 | 302 | MuldeR's OpenSource Projects 303 | 304 | 305 | 306 | 307 | 308 | :/res/ico_link.png:/res/ico_link.png 309 | 310 | 311 | Official MediaInfo Web-Site 312 | 313 | 314 | 315 | 316 | false 317 | 318 | 319 | 320 | :/res/ico_clear.png:/res/ico_clear.png 321 | 322 | 323 | Clear Display 324 | 325 | 326 | 327 | 328 | 329 | :/res/ico_link.png:/res/ico_link.png 330 | 331 | 332 | MediaInfo Discussion (Doom9) 333 | 334 | 335 | 336 | 337 | false 338 | 339 | 340 | 341 | :/res/ico_paste.png:/res/ico_paste.png 342 | 343 | 344 | Copy to Clipboard 345 | 346 | 347 | 348 | 349 | false 350 | 351 | 352 | 353 | :/res/ico_disk.png:/res/ico_disk.png 354 | 355 | 356 | Save to File... 357 | 358 | 359 | 360 | 361 | true 362 | 363 | 364 | false 365 | 366 | 367 | Enable the Shell Integration 368 | 369 | 370 | 371 | 372 | true 373 | 374 | 375 | Enable Verbose/Debug Output 376 | 377 | 378 | 379 | 380 | true 381 | 382 | 383 | Enable Line Wrapping 384 | 385 | 386 | 387 | 388 | true 389 | 390 | 391 | Enable XML-style Output 392 | 393 | 394 | 395 | 396 | analyzeButton 397 | exitButton 398 | textBrowser 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | actionExit 407 | triggered() 408 | MainWindow 409 | close() 410 | 411 | 412 | -1 413 | -1 414 | 415 | 416 | 399 417 | 299 418 | 419 | 420 | 421 | 422 | exitButton 423 | clicked() 424 | MainWindow 425 | close() 426 | 427 | 428 | 546 429 | 466 430 | 431 | 432 | 316 433 | 244 434 | 435 | 436 | 437 | 438 | 439 | -------------------------------------------------------------------------------- /res/bin/MediaInfo.x64-avx2.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lordmulder/mediainfo-gui/4e87987fe97b5017f821b3f3816c87173e53d7be/res/bin/MediaInfo.x64-avx2.exe -------------------------------------------------------------------------------- /res/bin/MediaInfo.x64-sse2.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lordmulder/mediainfo-gui/4e87987fe97b5017f821b3f3816c87173e53d7be/res/bin/MediaInfo.x64-sse2.exe -------------------------------------------------------------------------------- /res/bin/MediaInfo.x86-i686.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lordmulder/mediainfo-gui/4e87987fe97b5017f821b3f3816c87173e53d7be/res/bin/MediaInfo.x86-i686.exe -------------------------------------------------------------------------------- /res/bin/MediaInfo.x86-sse2.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lordmulder/mediainfo-gui/4e87987fe97b5017f821b3f3816c87173e53d7be/res/bin/MediaInfo.x86-sse2.exe -------------------------------------------------------------------------------- /res/ico_clear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lordmulder/mediainfo-gui/4e87987fe97b5017f821b3f3816c87173e53d7be/res/ico_clear.png -------------------------------------------------------------------------------- /res/ico_discard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lordmulder/mediainfo-gui/4e87987fe97b5017f821b3f3816c87173e53d7be/res/ico_discard.png -------------------------------------------------------------------------------- /res/ico_disk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lordmulder/mediainfo-gui/4e87987fe97b5017f821b3f3816c87173e53d7be/res/ico_disk.png -------------------------------------------------------------------------------- /res/ico_folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lordmulder/mediainfo-gui/4e87987fe97b5017f821b3f3816c87173e53d7be/res/ico_folder.png -------------------------------------------------------------------------------- /res/ico_info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lordmulder/mediainfo-gui/4e87987fe97b5017f821b3f3816c87173e53d7be/res/ico_info.png -------------------------------------------------------------------------------- /res/ico_link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lordmulder/mediainfo-gui/4e87987fe97b5017f821b3f3816c87173e53d7be/res/ico_link.png -------------------------------------------------------------------------------- /res/ico_options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lordmulder/mediainfo-gui/4e87987fe97b5017f821b3f3816c87173e53d7be/res/ico_options.png -------------------------------------------------------------------------------- /res/ico_paste.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lordmulder/mediainfo-gui/4e87987fe97b5017f821b3f3816c87173e53d7be/res/ico_paste.png -------------------------------------------------------------------------------- /res/ico_qt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lordmulder/mediainfo-gui/4e87987fe97b5017f821b3f3816c87173e53d7be/res/ico_qt.png -------------------------------------------------------------------------------- /res/ico_quit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lordmulder/mediainfo-gui/4e87987fe97b5017f821b3f3816c87173e53d7be/res/ico_quit.png -------------------------------------------------------------------------------- /res/ico_shellext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lordmulder/mediainfo-gui/4e87987fe97b5017f821b3f3816c87173e53d7be/res/ico_shellext.png -------------------------------------------------------------------------------- /res/loading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lordmulder/mediainfo-gui/4e87987fe97b5017f821b3f3816c87173e53d7be/res/loading.png -------------------------------------------------------------------------------- /res/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lordmulder/mediainfo-gui/4e87987fe97b5017f821b3f3816c87173e53d7be/res/logo.png -------------------------------------------------------------------------------- /src/Config.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // MediaInfoXP 3 | // Copyright (C) 2004-2024 LoRd_MuldeR 4 | // 5 | // This program is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 2 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License along 16 | // with this program; if not, write to the Free Software Foundation, Inc., 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | // http://www.gnu.org/licenses/gpl-2.0.txt 20 | /////////////////////////////////////////////////////////////////////////////// 21 | 22 | //Internal 23 | #include "Config.h" 24 | #include "Version.h" 25 | 26 | #define MIXP_CONF_DEFINE(X,Y,Z) extern const X g_##Y = Z; 27 | 28 | #define MIXP_VERSION_GLUE_HELPER(X,Y) X##Y 29 | #define MIXP_VERSION_GLUE(X,Y) MIXP_VERSION_GLUE_HELPER(X,Y) 30 | #define MIXP_VERSION_MINOR MIXP_VERSION_GLUE(MIXP_VERSION_MINOR_HI,MIXP_VERSION_MINOR_LO) 31 | 32 | //Version 33 | MIXP_CONF_DEFINE(unsigned int, mixp_versionMajor, MIXP_VERSION_MAJOR) 34 | MIXP_CONF_DEFINE(unsigned int, mixp_versionMinor, MIXP_VERSION_MINOR) 35 | MIXP_CONF_DEFINE(unsigned int, mixp_versionPatch, MIXP_VERSION_PATCH) 36 | 37 | //MediaInfo Version 38 | MIXP_CONF_DEFINE(unsigned int, mixp_mediaInfoVerMajor, 23) 39 | MIXP_CONF_DEFINE(unsigned int, mixp_mediaInfoVerMinor, 11) 40 | MIXP_CONF_DEFINE(unsigned int, mixp_mediaInfoVerPatch, 0) 41 | 42 | //MediaInfo Checksum 43 | MIXP_CONF_DEFINE(char*, mixp_checksum_x86_i686, "39620b62dede4834f93bfa0ef6d39473c2d8b0632e176ce42f25bd6e5cfed32867a3c47026a05c7610af3da9839044dd1740534636b28aaf8d8966f8384ce3b9") 44 | MIXP_CONF_DEFINE(char*, mixp_checksum_x86_sse2, "bc3283aeb07255d5465594fe149d61af4b07dbca85a844454a06340dcc3292eeef502a3641c3e299209144fa60a180fed40c79d4dc904ec8f6349d2f4140de95") 45 | MIXP_CONF_DEFINE(char*, mixp_checksum_x64_sse2, "69d4208d7125505e35472773facfb64b138f7d9595e4c2338dda9f420697661c8271e7ef449eeeeaf8134b06fab9452760887577fbb2b387af49e44fe928fc98") 46 | MIXP_CONF_DEFINE(char*, mixp_checksum_x64_avx2, "75c0fd7d3fe9223a9ccf26c74ccae144c62b29c3e2ac0023655b22cc0f2196e22af9d27c005fb7c29573e527c36f0126faea666e0b995bf6e10a019e6aabc61f") 47 | 48 | //Build date 49 | MIXP_CONF_DEFINE(char*, mixp_buildDate, __DATE__) 50 | MIXP_CONF_DEFINE(char*, mixp_buildTime, __TIME__) 51 | -------------------------------------------------------------------------------- /src/Config.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // MediaInfoXP 3 | // Copyright (C) 2004-2024 LoRd_MuldeR 4 | // 5 | // This program is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 2 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License along 16 | // with this program; if not, write to the Free Software Foundation, Inc., 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | // http://www.gnu.org/licenses/gpl-2.0.txt 20 | /////////////////////////////////////////////////////////////////////////////// 21 | 22 | #pragma once 23 | 24 | #define MIXP_CONF_DECLARE(X,Y) extern const X g_##Y; 25 | 26 | //Version 27 | MIXP_CONF_DECLARE(unsigned int, mixp_versionMajor) 28 | MIXP_CONF_DECLARE(unsigned int, mixp_versionMinor) 29 | MIXP_CONF_DECLARE(unsigned int, mixp_versionPatch) 30 | 31 | //MediaInfo Version 32 | MIXP_CONF_DECLARE(unsigned int, mixp_mediaInfoVerMajor) 33 | MIXP_CONF_DECLARE(unsigned int, mixp_mediaInfoVerMinor) 34 | MIXP_CONF_DECLARE(unsigned int, mixp_mediaInfoVerPatch) 35 | 36 | //MediaInfo Checksum 37 | MIXP_CONF_DECLARE(char*, mixp_checksum_x86_i686) 38 | MIXP_CONF_DECLARE(char*, mixp_checksum_x86_sse2) 39 | MIXP_CONF_DECLARE(char*, mixp_checksum_x64_sse2) 40 | MIXP_CONF_DECLARE(char*, mixp_checksum_x64_avx2) 41 | 42 | //Build date 43 | MIXP_CONF_DECLARE(char*, mixp_buildDate) 44 | MIXP_CONF_DECLARE(char*, mixp_buildTime) 45 | 46 | //Show console 47 | #define MIXP_CONSOLE (0) 48 | 49 | //Debug build 50 | #if defined(_DEBUG) && defined(QT_DEBUG) && !defined(NDEBUG) && !defined(QT_NO_DEBUG) 51 | #define MIXP_DEBUG (1) 52 | #else 53 | #define MIXP_DEBUG (0) 54 | #endif 55 | 56 | //Undefine 57 | #undef MIXP_CONF_DECLARE 58 | -------------------------------------------------------------------------------- /src/IPC.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // MediaInfoXP 3 | // Copyright (C) 2004-2024 LoRd_MuldeR 4 | // 5 | // This program is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 2 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License along 16 | // with this program; if not, write to the Free Software Foundation, Inc., 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | // http://www.gnu.org/licenses/gpl-2.0.txt 20 | /////////////////////////////////////////////////////////////////////////////// 21 | 22 | #include "IPC.h" 23 | 24 | //MUtils 25 | #include "MUtils/Global.h" 26 | #include "MUtils/IPCChannel.h" 27 | 28 | //Qt 29 | #include 30 | #include 31 | 32 | static const size_t MAX_STR_LEN = 1024; 33 | static const size_t MAX_ENTRIES = 16; 34 | 35 | static const char *s_key_smemory = "{35DE4BDD-F88C-41E1-8080-2EDC503757F2}"; 36 | static const char *s_key_sema_wr = "{C638D990-7553-4D4D-95E8-9B040BA6AE87}"; 37 | static const char *s_key_sema_rd = "{0C30B0B2-0B03-49D7-8DB3-A7D0DDDEA2B0}"; 38 | 39 | typedef struct 40 | { 41 | wchar_t data[MAX_ENTRIES][MAX_STR_LEN]; 42 | size_t posRd; 43 | size_t posWr; 44 | size_t counter; 45 | } 46 | mixp_ipc_t; 47 | 48 | /////////////////////////////////////////////////////////////////////////////// 49 | // Send Thread 50 | /////////////////////////////////////////////////////////////////////////////// 51 | 52 | IPCSendThread::IPCSendThread(MUtils::IPCChannel *const ipc, const quint32 &command, const QString &message) 53 | : 54 | m_ipc(ipc), m_command(command), m_message(message) 55 | { 56 | } 57 | 58 | void IPCSendThread::run(void) 59 | { 60 | try 61 | { 62 | m_result.fetchAndStoreOrdered(m_ipc->send(m_command, 0, QStringList() << m_message) ? 1 : 0); 63 | } 64 | catch(...) 65 | { 66 | qWarning("Exception in IPC receive thread!"); 67 | m_result.fetchAndStoreOrdered(0); 68 | } 69 | } 70 | 71 | 72 | /////////////////////////////////////////////////////////////////////////////// 73 | // Receive Thread 74 | /////////////////////////////////////////////////////////////////////////////// 75 | 76 | IPCReceiveThread::IPCReceiveThread(MUtils::IPCChannel *const ipc) 77 | : 78 | m_ipc(ipc) 79 | { 80 | } 81 | 82 | void IPCReceiveThread::run(void) 83 | { 84 | try 85 | { 86 | receiveLoop(); 87 | } 88 | catch(...) 89 | { 90 | qWarning("Exception in IPC receive thread!"); 91 | } 92 | } 93 | 94 | void IPCReceiveThread::receiveLoop(void) 95 | { 96 | while(!m_stopped) 97 | { 98 | quint32 command, flags; 99 | QStringList params; 100 | if(m_ipc->read(command, flags, params)) 101 | { 102 | if((command != IPC::COMMAND_NONE) && (!params.isEmpty())) 103 | { 104 | emit received(command, params.first()); 105 | } 106 | } 107 | } 108 | } 109 | 110 | void IPCReceiveThread::stop(void) 111 | { 112 | if(m_stopped.testAndSetOrdered(0, 1)) 113 | { 114 | IPC::sendAsync(m_ipc, IPC::COMMAND_NONE, "exit"); 115 | } 116 | } 117 | 118 | /////////////////////////////////////////////////////////////////////////////// 119 | // IPC Class 120 | /////////////////////////////////////////////////////////////////////////////// 121 | 122 | bool IPC::sendAsync(MUtils::IPCChannel *const ipc, const quint32 &command, const QString &message, const quint32 &timeout) 123 | { 124 | IPCSendThread sendThread(ipc, command, message); 125 | sendThread.start(); 126 | 127 | if(!sendThread.wait(timeout)) 128 | { 129 | qWarning("IPC send operation encountered timeout!"); 130 | sendThread.terminate(); 131 | sendThread.wait(); 132 | return false; 133 | } 134 | 135 | return sendThread.result(); 136 | } 137 | -------------------------------------------------------------------------------- /src/IPC.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // MediaInfoXP 3 | // Copyright (C) 2004-2024 LoRd_MuldeR 4 | // 5 | // This program is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 2 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License along 16 | // with this program; if not, write to the Free Software Foundation, Inc., 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | // http://www.gnu.org/licenses/gpl-2.0.txt 20 | /////////////////////////////////////////////////////////////////////////////// 21 | 22 | #pragma once 23 | 24 | #include 25 | 26 | namespace MUtils 27 | { 28 | class IPCChannel; 29 | } 30 | 31 | /////////////////////////////////////////////////////////////////////////////// 32 | 33 | class IPCSendThread : public QThread 34 | { 35 | Q_OBJECT 36 | 37 | public: 38 | IPCSendThread(MUtils::IPCChannel *const ipc, const quint32 &command, const QString &message); 39 | inline bool result(void) { return m_result; } 40 | 41 | virtual void run(void); 42 | 43 | private: 44 | QAtomicInt m_result; 45 | MUtils::IPCChannel *const m_ipc; 46 | const quint32 m_command; 47 | const QString m_message; 48 | }; 49 | 50 | class IPCReceiveThread : public QThread 51 | { 52 | Q_OBJECT 53 | 54 | public: 55 | IPCReceiveThread(MUtils::IPCChannel *const ipc); 56 | void stop(void); 57 | 58 | protected: 59 | virtual void run(void); 60 | 61 | signals: 62 | void received(const quint32 &command, const QString &message); 63 | 64 | private: 65 | void receiveLoop(void); 66 | QAtomicInt m_stopped; 67 | MUtils::IPCChannel *const m_ipc; 68 | }; 69 | 70 | class IPC 71 | { 72 | public: 73 | enum 74 | { 75 | COMMAND_NONE = 0, 76 | COMMAND_PING = 1, 77 | COMMAND_OPEN = 2 78 | } 79 | ipc_command_t; 80 | 81 | static bool sendAsync(MUtils::IPCChannel *const ipc, const quint32 &command, const QString &message, const quint32 &timeout = 5000); 82 | 83 | private: 84 | IPC(void) { throw 666; } 85 | }; 86 | -------------------------------------------------------------------------------- /src/Main.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // MediaInfoXP 3 | // Copyright (C) 2004-2024 LoRd_MuldeR 4 | // 5 | // This program is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 2 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License along 16 | // with this program; if not, write to the Free Software Foundation, Inc., 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | // http://www.gnu.org/licenses/gpl-2.0.txt 20 | /////////////////////////////////////////////////////////////////////////////// 21 | 22 | //MUTils 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | //Qt 29 | #include 30 | #include 31 | #include 32 | 33 | #ifdef QT_NODLL 34 | #include 35 | Q_IMPORT_PLUGIN(qico) 36 | Q_IMPORT_PLUGIN(qsvg) 37 | Q_IMPORT_PLUGIN(qtga) 38 | #endif 39 | 40 | //Internal 41 | #include "Config.h" 42 | #include "MainWindow.h" 43 | #include "IPC.h" 44 | 45 | /////////////////////////////////////////////////////////////////////////////// 46 | // Multi-instance handling 47 | /////////////////////////////////////////////////////////////////////////////// 48 | 49 | static void mixp_handle_multi_instance(MUtils::IPCChannel *const ipcChannel) 50 | { 51 | bool bHaveFile = false; 52 | 53 | //We are *not* the first instance -> pass all file names to the running instance 54 | const MUtils::OS::ArgumentMap arguments = MUtils::OS::arguments(); 55 | const QStringList files = arguments.values("open"); 56 | for(QStringList::ConstIterator iter = files.constBegin(); iter != files.constEnd(); iter++) 57 | { 58 | if(IPC::sendAsync(ipcChannel, IPC::COMMAND_OPEN, *iter)) 59 | { 60 | bHaveFile = true; 61 | } 62 | } 63 | 64 | //If no file was sent, we will at least try to bring the other instance to front 65 | if(!bHaveFile) 66 | { 67 | IPC::sendAsync(ipcChannel, IPC::COMMAND_PING, "?"); 68 | } 69 | } 70 | 71 | /////////////////////////////////////////////////////////////////////////////// 72 | // MAIN function 73 | /////////////////////////////////////////////////////////////////////////////// 74 | 75 | static int mixp_main(int &argc, char **argv) 76 | { 77 | //Print the logo 78 | qDebug("MediaInfoXP v%u.%02u, built on %s at %s.", g_mixp_versionMajor, g_mixp_versionMinor, g_mixp_buildDate, g_mixp_buildTime); 79 | qDebug("Copyright (c) 2004-%s LoRd_MuldeR . Some rights reserved.", &g_mixp_buildDate[7]); 80 | qDebug("Built with Qt v%s, running with Qt v%s.\n", QT_VERSION_STR, qVersion()); 81 | 82 | //Print library version 83 | qDebug("This application is powerd by MUtils library v%u.%02u (%s, %s).\n", MUtils::Version::lib_version_major(), MUtils::Version::lib_version_minor(), MUTILS_UTF8(MUtils::Version::lib_build_date().toString(Qt::ISODate)), MUTILS_UTF8(MUtils::Version::lib_build_time().toString(Qt::ISODate))); 84 | 85 | //Create application 86 | QScopedPointer application(new QApplication(argc, argv)); 87 | 88 | //Create IPC 89 | QScopedPointer ipcChannel(new MUtils::IPCChannel("mediainfo-xp", qHash(QString("%0@%1").arg(QString::fromLatin1(g_mixp_buildDate), QString::fromLatin1(g_mixp_buildTime))), "instance")); 90 | const int ipcMode = ipcChannel->initialize(); 91 | if((ipcMode != MUtils::IPCChannel::RET_SUCCESS_MASTER) && (ipcMode != MUtils::IPCChannel::RET_SUCCESS_SLAVE)) 92 | { 93 | qFatal("The IPC initialization has failed!"); 94 | return EXIT_FAILURE; 95 | } 96 | 97 | //Handle multiple instances 98 | if(ipcMode == MUtils::IPCChannel::RET_SUCCESS_SLAVE) 99 | { 100 | mixp_handle_multi_instance(ipcChannel.data()); 101 | return EXIT_SUCCESS; 102 | } 103 | 104 | const QString baseFolder = QDir(QCoreApplication::applicationDirPath()).canonicalPath(); 105 | qDebug("Base directory is:\n%s\n", MUTILS_UTF8(QDir::toNativeSeparators(baseFolder))); 106 | 107 | //Get temp folder 108 | const QString tempFolder = MUtils::temp_folder(); 109 | qDebug("Temp directory is:\n%s\n", MUTILS_UTF8(QDir::toNativeSeparators(tempFolder))); 110 | 111 | //Create main window 112 | QScopedPointer mainWindow(new CMainWindow(baseFolder, tempFolder, ipcChannel.data())); 113 | mainWindow->show(); 114 | 115 | //Run application 116 | const int exit_code = application->exec(); 117 | qDebug("\nTime to say goodbye... (%d)\n", exit_code); 118 | 119 | return exit_code; 120 | } 121 | 122 | /////////////////////////////////////////////////////////////////////////////// 123 | // Applicaton entry point 124 | /////////////////////////////////////////////////////////////////////////////// 125 | 126 | int main(int argc, char* argv[]) 127 | { 128 | MUtils::Startup::startup(argc, argv, mixp_main, "MediaInfoXP", MIXP_DEBUG); 129 | } 130 | 131 | extern "C" 132 | { 133 | int mainCRTStartup(void); 134 | 135 | int mxp_entry_point(void) 136 | { 137 | return mainCRTStartup(); 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/MainWindow.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // MediaInfoXP 3 | // Copyright (C) 2004-2024 LoRd_MuldeR 4 | // 5 | // This program is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 2 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License along 16 | // with this program; if not, write to the Free Software Foundation, Inc., 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | // http://www.gnu.org/licenses/gpl-2.0.txt 20 | /////////////////////////////////////////////////////////////////////////////// 21 | 22 | #include "MainWindow.h" 23 | 24 | //UIC includes 25 | #include "UIC_Dialog.h" 26 | 27 | //MUtils 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | //Qt includes 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | 51 | //CRT 52 | #include 53 | 54 | //Internal 55 | #include "Config.h" 56 | #include "ShellExtension.h" 57 | #include "IPC.h" 58 | 59 | //Macros 60 | #define MIXP_VERSION_STR (QString().sprintf((g_mixp_versionPatch > 0) ? "%u.%02u.%u" : "%u.%02u", g_mixp_versionMajor, g_mixp_versionMinor, g_mixp_versionPatch)) 61 | #define MI_VERSION_STR (QString().sprintf((g_mixp_mediaInfoVerPatch > 0) ? "%u.%02u.%u" : "%u.%02u", g_mixp_mediaInfoVerMajor, g_mixp_mediaInfoVerMinor, g_mixp_mediaInfoVerPatch)) 62 | #define UTIL_VERSION_STR (QString().sprintf("%u.%02u", MUtils::Version::lib_version_major(), MUtils::Version::lib_version_minor())) 63 | #define SET_FONT_BOLD(WIDGET,BOLD) { QFont _font = WIDGET->font(); _font.setBold(BOLD); WIDGET->setFont(_font); } 64 | #define SET_TEXT_COLOR(WIDGET,COLOR) { QPalette _palette = WIDGET->palette(); _palette.setColor(QPalette::WindowText, (COLOR)); _palette.setColor(QPalette::Text, (COLOR)); WIDGET->setPalette(_palette); } 65 | #define APPLICATION_IS_IDLE (m_status == APP_STATUS_IDLE) 66 | #define HAVE_SSE2(X) ((X).features & MUtils::CPUFetaures::FLAG_SSE2) 67 | #define HAVE_AVX2(X) ((X).features & MUtils::CPUFetaures::FLAG_AVX2) 68 | 69 | //Text 70 | const char *STATUS_BLNK = ">> You can drop any type of media files here <<"; 71 | const char *STATUS_WORK = "Analyzing file(s), this may take a moment or two...



"; 72 | 73 | //Links 74 | const char *LINK_MULDER = "http://muldersoft.com/"; 75 | const char *LINK_MEDIAINFO = "http://mediaarea.net/en/MediaInfo"; /*"http://mediainfo.sourceforge.net/en"*/ 76 | const char *LINK_DISCUSS = "http://forum.doom9.org/showthread.php?t=96516"; 77 | 78 | //MediaInfo 79 | static const struct 80 | { 81 | const char *const arch; 82 | const char *const checksum; 83 | const bool require_x64; 84 | const bool require_sse2; 85 | const bool require_avx2; 86 | } 87 | MEDIAINFO_BIN[] = 88 | { 89 | { "x64-avx2", g_mixp_checksum_x64_avx2, bool(1), bool(1), bool(1) }, 90 | { "x64-sse2", g_mixp_checksum_x64_sse2, bool(1), bool(1), bool(0) }, 91 | { "x86-sse2", g_mixp_checksum_x86_sse2, bool(0), bool(1), bool(0) }, 92 | { "x86-i686", g_mixp_checksum_x86_i686, bool(0), bool(0), bool(0) }, 93 | { NULL, NULL, false, false } 94 | }; 95 | 96 | //Const 97 | static const int UPDATE_TIMEOUT = 9; 98 | static const int FILE_RECEIVE_DELAY = 1750; 99 | 100 | //////////////////////////////////////////////////////////// 101 | // Constructor 102 | //////////////////////////////////////////////////////////// 103 | 104 | CMainWindow::CMainWindow(const QString &baseFolder, const QString &tempFolder, MUtils::IPCChannel *const ipc, QWidget *parent) 105 | : 106 | QMainWindow(parent), 107 | m_baseFolder(baseFolder), 108 | m_tempFolder(tempFolder), 109 | m_ipcThread(new IPCReceiveThread(ipc)), 110 | m_status(APP_STATUS_STARTING), 111 | ui(new Ui::MainWindow) 112 | { 113 | //Init UI 114 | qApp->setStyle(QStyleFactory::create("plastique")); 115 | ui->setupUi(this); 116 | setMinimumSize(this->size()); 117 | 118 | //Setup Icon 119 | MUtils::GUI::set_window_icon(this, QIcon(":/res/logo.png"), true); 120 | 121 | //Adjust size to DPI settings and re-center 122 | MUtils::GUI::scale_widget(this); 123 | 124 | //Setup links 125 | ui->actionLink_MuldeR ->setData(QVariant(QString::fromLatin1(LINK_MULDER))); 126 | ui->actionLink_MediaInfo->setData(QVariant(QString::fromLatin1(LINK_MEDIAINFO))); 127 | ui->actionLink_Discuss ->setData(QVariant(QString::fromLatin1(LINK_DISCUSS))); 128 | 129 | //Setup connections 130 | connect(ui->analyzeButton, SIGNAL(clicked()), this, SLOT(analyzeButtonClicked())); 131 | connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(analyzeButtonClicked())); 132 | connect(ui->actionSave, SIGNAL(triggered()), this, SLOT(saveButtonClicked())); 133 | connect(ui->actionCopyToClipboard, SIGNAL(triggered()), this, SLOT(copyToClipboardButtonClicked())); 134 | connect(ui->actionClear, SIGNAL(triggered()), this, SLOT(clearButtonClicked())); 135 | connect(ui->actionLink_MuldeR, SIGNAL(triggered()), this, SLOT(linkTriggered())); 136 | connect(ui->actionLink_MediaInfo, SIGNAL(triggered()), this, SLOT(linkTriggered())); 137 | connect(ui->actionLink_Discuss, SIGNAL(triggered()), this, SLOT(linkTriggered())); 138 | connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(showAboutScreen())); 139 | connect(ui->actionShellExtension, SIGNAL(toggled(bool)), this, SLOT(updateShellExtension(bool))); 140 | connect(ui->actionLineWrapping, SIGNAL(toggled(bool)), this, SLOT(updateLineWrapping(bool))); 141 | connect(ui->actionVerboseOutput, SIGNAL(toggled(bool)), this, SLOT(toggleOutputOption(bool))); 142 | connect(ui->actionXmlOutput, SIGNAL(toggled(bool)), this, SLOT(toggleOutputOption(bool))); 143 | connect(m_ipcThread.data(), SIGNAL(received(quint32, QString)), this, SLOT(received(quint32, QString))); 144 | ui->versionLabel->installEventFilter(this); 145 | 146 | //Context menu 147 | ui->textBrowser->setContextMenuPolicy(Qt::ActionsContextMenu); 148 | ui->textBrowser->insertActions(0, ui->menuFile->actions()); 149 | 150 | //Create label 151 | m_floatingLabel.reset(new QLabel(ui->textBrowser)); 152 | m_floatingLabel->setText(QString::fromLatin1(STATUS_BLNK)); 153 | m_floatingLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); 154 | m_floatingLabel->show(); 155 | SET_TEXT_COLOR(m_floatingLabel, Qt::darkGray); 156 | SET_FONT_BOLD(m_floatingLabel, true); 157 | m_floatingLabel->setContextMenuPolicy(Qt::ActionsContextMenu); 158 | m_floatingLabel->insertActions(0, ui->textBrowser->actions()); 159 | 160 | //Randomize 161 | qsrand((uint) time(NULL)); 162 | 163 | //Selftest 164 | if (MUTILS_DEBUG) 165 | { 166 | selfTest(); 167 | } 168 | } 169 | 170 | //////////////////////////////////////////////////////////// 171 | // Destructor 172 | //////////////////////////////////////////////////////////// 173 | 174 | CMainWindow::~CMainWindow(void) 175 | { 176 | if(!m_ipcThread.isNull()) 177 | { 178 | m_ipcThread->stop(); 179 | if(!m_ipcThread->wait(5000)) 180 | { 181 | qWarning("IPC thread doesn't respond -> terminating!"); 182 | m_ipcThread->terminate(); 183 | m_ipcThread->wait(); 184 | } 185 | } 186 | 187 | if(!m_mediaInfoHandle.isNull()) 188 | { 189 | m_mediaInfoHandle->remove(); 190 | } 191 | } 192 | 193 | //////////////////////////////////////////////////////////// 194 | // EVENTS 195 | //////////////////////////////////////////////////////////// 196 | 197 | void CMainWindow::showEvent(QShowEvent *event) 198 | { 199 | QMainWindow::showEvent(event); 200 | 201 | //Init test 202 | ui->versionLabel->setText(QString("v%1 / v%2 (%3)").arg(MIXP_VERSION_STR, MI_VERSION_STR, MUtils::Version::app_build_date().toString(Qt::ISODate))); 203 | ui->updateLabel->setText(tr("This version is more than %1 month old and probably outdated. Please check %2 for updates!").arg(QString::number(UPDATE_TIMEOUT), LINK_MULDER)); 204 | 205 | //Show update hint? 206 | ui->updateLabel->setVisible(MUtils::Version::app_build_date().addMonths(UPDATE_TIMEOUT) < MUtils::OS::current_date()); 207 | 208 | //Force resize event 209 | resizeEvent(NULL); 210 | QTimer::singleShot(0, this, SLOT(updateSize())); 211 | 212 | if(m_status == APP_STATUS_STARTING) 213 | { 214 | const MUtils::OS::ArgumentMap arguments = MUtils::OS::arguments(); 215 | const QStringList files = arguments.values("open"); 216 | for(QStringList::ConstIterator iter = files.constBegin(); iter != files.constEnd(); iter++) 217 | { 218 | QFileInfo currentFile = QFileInfo(*iter); 219 | if(currentFile.exists() && currentFile.isFile()) 220 | { 221 | m_pendingFiles << currentFile.canonicalFilePath(); 222 | } 223 | } 224 | if(!m_pendingFiles.empty()) 225 | { 226 | m_status = APP_STATUS_AWAITING; 227 | QTimer::singleShot(FILE_RECEIVE_DELAY, this, SLOT(analyzeFiles())); 228 | } 229 | 230 | QTimer::singleShot(250, this, SLOT(initShellExtension())); 231 | m_ipcThread->start(); 232 | 233 | if(m_status == APP_STATUS_STARTING) 234 | { 235 | m_status = APP_STATUS_IDLE; 236 | } 237 | } 238 | 239 | //Enable drag & drop support 240 | setAcceptDrops(true); 241 | } 242 | 243 | void CMainWindow::closeEvent(QCloseEvent *event) 244 | { 245 | if(!APPLICATION_IS_IDLE) 246 | { 247 | qWarning("Cannot exit program at this time!"); 248 | event->ignore(); 249 | } 250 | } 251 | 252 | void CMainWindow::resizeEvent(QResizeEvent *event) 253 | { 254 | if(event) 255 | { 256 | QMainWindow::resizeEvent(event); 257 | } 258 | updateSize(); 259 | } 260 | 261 | void CMainWindow::dragEnterEvent(QDragEnterEvent *event) 262 | { 263 | bool accept[2] = {false, false}; 264 | 265 | foreach(const QString &fmt, event->mimeData()->formats()) 266 | { 267 | accept[0] = accept[0] || fmt.contains("text/uri-list", Qt::CaseInsensitive); 268 | accept[1] = accept[1] || fmt.contains("FileNameW", Qt::CaseInsensitive); 269 | } 270 | 271 | if(accept[0] && accept[1]) 272 | { 273 | event->acceptProposedAction(); 274 | } 275 | } 276 | 277 | void CMainWindow::dropEvent(QDropEvent *event) 278 | { 279 | if(!APPLICATION_IS_IDLE) 280 | { 281 | qWarning("Cannot process files at this time!\n"); 282 | return; 283 | } 284 | 285 | m_pendingFiles.clear(); 286 | QList urls = event->mimeData()->urls(); 287 | 288 | while(!urls.isEmpty()) 289 | { 290 | QUrl currentUrl = urls.takeFirst(); 291 | QFileInfo file(currentUrl.toLocalFile()); 292 | if(file.exists() && file.isFile()) 293 | { 294 | m_pendingFiles << file.canonicalFilePath(); 295 | } 296 | } 297 | 298 | if(!m_pendingFiles.isEmpty()) 299 | { 300 | m_status = APP_STATUS_WORKING; 301 | QTimer::singleShot(0, this, SLOT(analyzeFiles())); 302 | } 303 | } 304 | 305 | void CMainWindow::keyPressEvent(QKeyEvent *e) 306 | { 307 | if(e->key() == Qt::Key_Escape) 308 | { 309 | if(m_process && (m_process->state() != QProcess::NotRunning)) 310 | { 311 | MUtils::Sound::beep(MUtils::Sound::BEEP_ERR); 312 | qWarning("Escape pressed, terminated process!"); 313 | m_process->kill(); 314 | } 315 | } 316 | } 317 | 318 | bool CMainWindow::eventFilter(QObject *o, QEvent *e) 319 | { 320 | if((o == ui->versionLabel) && (e->type() == QEvent::MouseButtonPress)) 321 | { 322 | QTimer::singleShot(0, this, SLOT(showAboutScreen())); 323 | return true; 324 | } 325 | return QMainWindow::eventFilter(o, e); 326 | } 327 | 328 | //////////////////////////////////////////////////////////// 329 | // SLOTS 330 | //////////////////////////////////////////////////////////// 331 | 332 | void CMainWindow::analyzeFiles(void) 333 | { 334 | //Any files pending? 335 | if(m_pendingFiles.isEmpty()) 336 | { 337 | qDebug("No pending files, nothing to do!\n"); 338 | return; 339 | } 340 | 341 | //Create process, if not done yet 342 | if(m_process.isNull()) 343 | { 344 | m_process.reset(new QProcess()); 345 | m_process->setProcessChannelMode(QProcess::MergedChannels); 346 | m_process->setReadChannel(QProcess::StandardOutput); 347 | connect(m_process.data(), SIGNAL(readyReadStandardError()), this, SLOT(outputAvailable())); 348 | connect(m_process.data(), SIGNAL(readyReadStandardOutput()), this, SLOT(outputAvailable())); 349 | connect(m_process.data(), SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(processFinished())); 350 | connect(m_process.data(), SIGNAL(error(QProcess::ProcessError)), this, SLOT(processFinished())); 351 | } 352 | 353 | //Still running? 354 | if(m_process->state() != QProcess::NotRunning) 355 | { 356 | qWarning("Process is still running!\n"); 357 | return; 358 | } 359 | 360 | m_status = APP_STATUS_WORKING; 361 | 362 | //Clear data 363 | ui->textBrowser->clear(); 364 | m_outputLines.clear(); 365 | 366 | //Disable buttons 367 | ui->analyzeButton->setEnabled(false); 368 | ui->exitButton->setEnabled(false); 369 | ui->actionClear->setEnabled(false); 370 | ui->actionCopyToClipboard->setEnabled(false); 371 | ui->actionSave->setEnabled(false); 372 | ui->actionOpen->setEnabled(false); 373 | ui->menuPreferences->setEnabled(false); 374 | 375 | //Show banner 376 | m_floatingLabel->show(); 377 | m_floatingLabel->setText(QString::fromLatin1(STATUS_WORK)); 378 | m_floatingLabel->setCursor(Qt::WaitCursor); 379 | 380 | //Give it a go! 381 | QTimer::singleShot(0, this, SLOT(analyzeNextFile())); 382 | } 383 | 384 | void CMainWindow::analyzeNextFile(void) 385 | { 386 | if(m_pendingFiles.isEmpty()) 387 | { 388 | qWarning("Oups, no pending files!"); 389 | return; 390 | } 391 | 392 | //Still running? 393 | if(m_process->state() != QProcess::NotRunning) 394 | { 395 | qWarning("Process is still running!\n"); 396 | return; 397 | } 398 | 399 | m_status = APP_STATUS_WORKING; 400 | 401 | //Lookup MediaInfo path 402 | const QString mediaInfoPath = getMediaInfoPath(); 403 | if(mediaInfoPath.isEmpty()) 404 | { 405 | ui->textBrowser->setHtml(QString("
%1
").arg(tr("Oups, failed to extract MediaInfo binary!"))); 406 | QMessageBox::critical(this, tr("Failure"), tr("Fatal Error: Failed to extract the MediaInfo binary!"), QMessageBox::Ok); 407 | m_floatingLabel->hide(); 408 | ui->actionOpen->setEnabled(true); 409 | ui->analyzeButton->setEnabled(true); 410 | ui->exitButton->setEnabled(true); 411 | ui->menuPreferences->setEnabled(true); 412 | m_status = APP_STATUS_IDLE; 413 | return; 414 | } 415 | 416 | const QString filePath = m_pendingFiles.takeFirst(); 417 | 418 | //Generate the command line 419 | QStringList commandLine; 420 | if(ui->actionVerboseOutput->isChecked()) commandLine << "--Full"; 421 | if(ui->actionXmlOutput->isChecked()) commandLine << "--Output=XML"; 422 | commandLine << QDir::toNativeSeparators(filePath); 423 | 424 | //Start analyziation 425 | qDebug("Analyzing media file:\n%s\n", filePath.toUtf8().constData()); 426 | m_process->start(mediaInfoPath, commandLine); 427 | 428 | //Wait for process to start 429 | if(!m_process->waitForStarted()) 430 | { 431 | qWarning("Process failed to start:\n%s\n", m_process->errorString().toLatin1().constData()); 432 | ui->textBrowser->setHtml(QString("
%1
").arg(tr("Oups, failed to create MediaInfo process!"))); 433 | QMessageBox::critical(this, tr("Failure"), tr("Error: Failed to create MediaInfo process!"), QMessageBox::Ok); 434 | m_floatingLabel->hide(); 435 | ui->actionOpen->setEnabled(true); 436 | ui->analyzeButton->setEnabled(true); 437 | ui->exitButton->setEnabled(true); 438 | ui->menuPreferences->setEnabled(true); 439 | m_status = APP_STATUS_IDLE; 440 | return; 441 | } 442 | 443 | qDebug("Process started successfully (PID: %u)", MUtils::OS::process_id(m_process.data())); 444 | } 445 | 446 | void CMainWindow::analyzeButtonClicked(void) 447 | { 448 | if(!APPLICATION_IS_IDLE) 449 | { 450 | qWarning("Cannot open files at this time!\n"); 451 | return; 452 | } 453 | 454 | m_status = APP_STATUS_BLOCKED; 455 | const QStringList selectedFiles = QFileDialog::getOpenFileNames(this, tr("Select file to analyze..."), QString(), tr("All supported media files (*.*)")); 456 | m_status = APP_STATUS_IDLE; 457 | 458 | if(!selectedFiles.isEmpty()) 459 | { 460 | m_pendingFiles.clear(); 461 | m_pendingFiles << selectedFiles; 462 | m_status = APP_STATUS_WORKING; 463 | analyzeFiles(); 464 | } 465 | } 466 | 467 | void CMainWindow::saveButtonClicked(void) 468 | { 469 | if(!APPLICATION_IS_IDLE) 470 | { 471 | qWarning("Cannot process files at this time!\n"); 472 | return; 473 | } 474 | 475 | m_status = APP_STATUS_BLOCKED; 476 | const QString selectedFile = QFileDialog::getSaveFileName(this, tr("Select file to save..."), QString(), tr("Plain Text (*.txt)")); 477 | m_status = APP_STATUS_IDLE; 478 | 479 | if(!selectedFile.isEmpty()) 480 | { 481 | QFile file(selectedFile); 482 | if(file.open(QIODevice::WriteOnly | QIODevice::WriteOnly)) 483 | { 484 | file.write(m_outputLines.join("\r\n").toUtf8()); 485 | file.close(); 486 | MUtils::Sound::beep(MUtils::Sound::BEEP_NFO); 487 | } 488 | else 489 | { 490 | QMessageBox::critical(this, tr("Failure"), tr("Error: Failed to open the file writing!"), QMessageBox::Ok); 491 | } 492 | } 493 | } 494 | 495 | void CMainWindow::copyToClipboardButtonClicked(void) 496 | { 497 | if(!APPLICATION_IS_IDLE) 498 | { 499 | qWarning("Cannot process files at this time!\n"); 500 | return; 501 | } 502 | 503 | if(QClipboard *clipboard = QApplication::clipboard()) 504 | { 505 | clipboard->setText(m_outputLines.join("\n")); 506 | MUtils::Sound::beep(MUtils::Sound::BEEP_NFO); 507 | } 508 | } 509 | 510 | void CMainWindow::clearButtonClicked(void) 511 | { 512 | if(!APPLICATION_IS_IDLE) 513 | { 514 | qWarning("Cannot process files at this time!\n"); 515 | return; 516 | } 517 | 518 | //Clear data and re-show banner 519 | ui->textBrowser->clear(); 520 | m_floatingLabel->setText(QString::fromLatin1(STATUS_BLNK)); 521 | m_floatingLabel->setCursor(Qt::ArrowCursor); 522 | m_floatingLabel->show(); 523 | 524 | //Disable actions 525 | ui->actionClear->setEnabled(false); 526 | ui->actionCopyToClipboard->setEnabled(false); 527 | ui->actionSave->setEnabled(false); 528 | } 529 | 530 | void CMainWindow::outputAvailable(void) 531 | { 532 | if(m_process) 533 | { 534 | //Update lines 535 | while(m_process->canReadLine()) 536 | { 537 | QString line = QString::fromUtf8(m_process->readLine()).trimmed(); 538 | if(!(line.isEmpty() && m_outputLines.empty())) 539 | { 540 | m_outputLines << line; 541 | } 542 | } 543 | } 544 | } 545 | 546 | void CMainWindow::processFinished(void) 547 | { 548 | //Fetch any remaining data 549 | outputAvailable(); 550 | 551 | //Remove trailing blank lines 552 | while((!m_outputLines.isEmpty()) && m_outputLines.last().trimmed().isEmpty()) 553 | { 554 | m_outputLines.takeLast(); 555 | } 556 | 557 | //Remove leading "E:" lines 558 | /*while ((!m_outputLines.isEmpty()) && m_outputLines.first().trimmed().startsWith(QLatin1String("E: "))) 559 | //{ 560 | // qWarning("E: line has been removed!"); 561 | // m_outputLines.takeFirst(); 562 | }*/ 563 | 564 | //Failed? 565 | if(m_outputLines.empty()) 566 | { 567 | m_outputLines << tr("Oups, apparently MediaInfo encountered a problem!"); 568 | } 569 | 570 | //Append one last linebreak 571 | m_outputLines << ""; 572 | 573 | //Scroll up 574 | ui->textBrowser->verticalScrollBar()->setValue(0); 575 | ui->textBrowser->horizontalScrollBar()->setValue(0); 576 | 577 | //Check exit code 578 | const int exitCode = m_process->exitCode(); 579 | qDebug("Process has finished (Code: %d)\n", exitCode); 580 | 581 | //More files left? 582 | if(!m_pendingFiles.isEmpty() && (exitCode == 0)) 583 | { 584 | if(!m_outputLines.empty()) 585 | { 586 | m_outputLines << QString().fill('-', 104) << ""; 587 | } 588 | QTimer::singleShot(0, this, SLOT(analyzeNextFile())); 589 | return; 590 | } 591 | 592 | //Hide banner 593 | if(m_floatingLabel->isVisible()) m_floatingLabel->hide(); 594 | 595 | //Update document 596 | if (!ui->actionXmlOutput->isChecked()) 597 | { 598 | QStringList htmlData = escapeHtmlLines(m_outputLines); 599 | htmlData.replaceInStrings(QRegExp("^(-+)$"), "\\1"); 600 | htmlData.replaceInStrings(QRegExp("^([^:<>]+):(.+)$"), "\\1:\\2"); 601 | htmlData.replaceInStrings(QRegExp("^([^:<>]+)$"), "\\1"); 602 | ui->textBrowser->setHtml(QString("
%1
").arg(htmlData.join("
"))); 603 | } 604 | else 605 | { 606 | const QString xmlData = Qt::escape(reformatXml(m_outputLines.join(QLatin1String("\n")))); 607 | ui->textBrowser->setHtml(QString("
%1
").arg(xmlData)); 608 | } 609 | 610 | //Enable actions 611 | if(!m_outputLines.empty()) 612 | { 613 | ui->actionClear->setEnabled(true); 614 | ui->actionCopyToClipboard->setEnabled(true); 615 | ui->actionSave->setEnabled(true); 616 | } 617 | ui->actionOpen->setEnabled(true); 618 | ui->analyzeButton->setEnabled(true); 619 | ui->exitButton->setEnabled(true); 620 | ui->menuPreferences->setEnabled(true); 621 | 622 | m_status = APP_STATUS_IDLE; 623 | } 624 | 625 | void CMainWindow::initShellExtension(void) 626 | { 627 | const bool isEnabled = ShellExtension::getEnabled(); 628 | 629 | if(isEnabled) 630 | { 631 | ShellExtension::setEnabled(true); 632 | } 633 | 634 | ui->actionShellExtension->blockSignals(true); 635 | ui->actionShellExtension->setChecked(isEnabled); 636 | ui->actionShellExtension->setEnabled(true); 637 | ui->actionShellExtension->blockSignals(false); 638 | } 639 | 640 | void CMainWindow::updateShellExtension(bool checked) 641 | { 642 | ShellExtension::setEnabled(checked); 643 | } 644 | 645 | void CMainWindow::updateLineWrapping(bool checked) 646 | { 647 | ui->textBrowser->setLineWrapMode(checked ? QTextEdit::WidgetWidth : QTextEdit::NoWrap); 648 | } 649 | 650 | void CMainWindow::toggleOutputOption(bool checked) 651 | { 652 | QMessageBox::information(this, this->windowTitle(), tr("Changes will take effect the next time that you open a file!")); 653 | } 654 | 655 | void CMainWindow::linkTriggered(void) 656 | { 657 | QObject *obj = QObject::sender(); 658 | if(QAction *action = dynamic_cast(obj)) 659 | { 660 | QDesktopServices::openUrl(QUrl(action->data().toString())); 661 | } 662 | } 663 | 664 | void CMainWindow::showAboutScreen(void) 665 | { 666 | if(!APPLICATION_IS_IDLE) 667 | { 668 | qWarning("Cannot show about box at this time!\n"); 669 | return; 670 | } 671 | 672 | const QDate buildDate = MUtils::Version::app_build_date(); 673 | const QDate curntDate = MUtils::OS::current_date(); 674 | const int year = qMax(buildDate.year(), curntDate.year()); 675 | 676 | QString text; 677 | 678 | text += QString("MediaInfoXP v%1 - Simple GUI for MediaInfo
").arg(MIXP_VERSION_STR); 679 | text += QString("Copyright (c) 2004-%1 LoRd_MuldeR <mulder2@gmx.de>. Some rights reserved.
").arg(QString().sprintf("%04d", year)); 680 | text += QString("Built on %1 at %2, using Qt Framework v%3.
").arg(buildDate.toString(Qt::ISODate), QString::fromLatin1(g_mixp_buildTime), QString::fromLatin1(qVersion())); 681 | text += QString("Linked against MUtilities library v%1, built on %2 at %3.

").arg(UTIL_VERSION_STR, MUtils::Version::lib_build_date().toString(Qt::ISODate), MUtils::Version::lib_build_time().toString(Qt::ISODate)); 682 | text += QString("This program is free software: you can redistribute it and/or modify
"); 683 | text += QString("it under the terms of the GNU General Public License <http://www.gnu.org/>.
"); 684 | text += QString("Note that this program is distributed with ABSOLUTELY NO WARRANTY.

"); 685 | text += QString("Please check the web-site at %1 for updates !!!
").arg(QString::fromLatin1(LINK_MULDER)); 686 | text += QString("

"); 687 | text += QString("This application is powered by MediaInfo v%1
").arg(MI_VERSION_STR); 688 | text += QString("Free and OpenSource tool for displaying technical information about media files.
"); 689 | text += QString("Copyright (c) 2002-%1 MediaArea.net SARL. All rights reserved.

").arg(QString().sprintf("%04d", year)); 690 | text += QString("Redistribution and use is permitted according to the (2-Clause) BSD License.
"); 691 | text += QString("Please see %1 for more information.
").arg(QString::fromLatin1(LINK_MEDIAINFO)); 692 | 693 | QMessageBox aboutBox(this); 694 | aboutBox.setIconPixmap(QIcon(":/res/logo.png").pixmap(64,64)); 695 | aboutBox.setWindowTitle(tr("About...")); 696 | aboutBox.setText(text.replace("-", "−")); 697 | if(QPushButton *btn = aboutBox.addButton(tr("About Qt"), QMessageBox::NoRole)) 698 | { 699 | btn->setIcon(QIcon(":/res/ico_qt.png")); 700 | btn->setMinimumWidth(120); 701 | } 702 | if(QPushButton *btn = aboutBox.addButton(tr("Discard"), QMessageBox::NoRole)) 703 | { 704 | btn->setIcon(QIcon(":/res/ico_discard.png")); 705 | btn->setMinimumWidth(104); 706 | aboutBox.setEscapeButton(btn); 707 | } 708 | 709 | m_status = APP_STATUS_BLOCKED; 710 | 711 | forever 712 | { 713 | const int ret = aboutBox.exec(); 714 | if(ret == 0) 715 | { 716 | QMessageBox::aboutQt(this); 717 | continue; 718 | } 719 | break; 720 | } 721 | 722 | m_status = APP_STATUS_IDLE; 723 | } 724 | 725 | void CMainWindow::updateSize(void) 726 | { 727 | if(const QWidget *const viewPort = ui->textBrowser->viewport()) 728 | { 729 | m_floatingLabel->setGeometry(viewPort->x(), viewPort->y(), viewPort->width(), viewPort->height()); 730 | } 731 | } 732 | 733 | void CMainWindow::received(const quint32 &command, const QString &message) 734 | { 735 | if((command == IPC::COMMAND_PING) || (command == IPC::COMMAND_OPEN)) 736 | { 737 | MUtils::GUI::bring_to_front(this); 738 | } 739 | 740 | if((command == IPC::COMMAND_OPEN) && (!message.isEmpty())) 741 | { 742 | qDebug("Received file: %s", message.toUtf8().constData()); 743 | 744 | if((m_status != APP_STATUS_IDLE) && (m_status != APP_STATUS_AWAITING)) 745 | { 746 | qWarning("Cannot process files at this time!\n"); 747 | return; 748 | } 749 | 750 | const QString absPath = QFileInfo(QDir::fromNativeSeparators(message)).absoluteFilePath(); 751 | QFileInfo fileInfo(absPath); 752 | if(fileInfo.exists() && fileInfo.isFile()) 753 | { 754 | m_pendingFiles << fileInfo.canonicalFilePath(); 755 | if(m_status == APP_STATUS_IDLE) 756 | { 757 | m_status = APP_STATUS_AWAITING; 758 | QTimer::singleShot(FILE_RECEIVE_DELAY, this, SLOT(analyzeFiles())); 759 | } 760 | } 761 | } 762 | } 763 | 764 | //////////////////////////////////////////////////////////// 765 | // PRIVATE FUNCTIONS 766 | //////////////////////////////////////////////////////////// 767 | 768 | static const char *const HASH_SEED = "+A`~}vPe9'~#n+c1Wq/MPo;1XwY\\;Pb."; 769 | 770 | static bool VALIDATE_MEDIAINFO(QFile *const handle, const char *const expected_checksum) 771 | { 772 | if(!handle->reset()) 773 | { 774 | qWarning("Failed to rewind file to be checked!\n"); 775 | return false; 776 | } 777 | 778 | //Compute Hash 779 | QScopedPointer hash(MUtils::Hash::create(MUtils::Hash::HASH_BLAKE2_512, HASH_SEED)); 780 | hash->update(handle->readAll()); 781 | const QByteArray checksum = hash->digest(true); 782 | 783 | //Compare Hash 784 | if(qstricmp(checksum.constData(), expected_checksum) != 0) 785 | { 786 | qWarning("MediaInfo binary is corrupted!"); 787 | qWarning("Expected checksum: %s", expected_checksum); 788 | qWarning("Computed checksum: %s\n", checksum.constData()); 789 | return false; 790 | } 791 | 792 | qDebug("MediaInfo checksum: %s\n", checksum.constData()); 793 | return true; 794 | } 795 | 796 | QPair CMainWindow::getMediaInfoArch(void) 797 | { 798 | const MUtils::CPUFetaures::cpu_info_t cpu_features = MUtils::CPUFetaures::detect(); 799 | for (size_t i = 0; MEDIAINFO_BIN[i].arch; ++i) 800 | { 801 | if (cpu_features.x64 || (!MEDIAINFO_BIN[i].require_x64)) 802 | { 803 | if ((HAVE_SSE2(cpu_features) || (!MEDIAINFO_BIN[i].require_sse2)) && (HAVE_AVX2(cpu_features) || (!MEDIAINFO_BIN[i].require_avx2))) 804 | { 805 | return qMakePair(QString::fromLatin1(MEDIAINFO_BIN[i].arch), MEDIAINFO_BIN[i].checksum); 806 | } 807 | } 808 | } 809 | MUTILS_THROW("This is not supposed to happen!"); 810 | } 811 | 812 | void CMainWindow::selfTest(void) 813 | { 814 | qWarning("[Self-Test]"); 815 | for (size_t i = 0; MEDIAINFO_BIN[i].arch; ++i) 816 | { 817 | qWarning("%s: %s", MEDIAINFO_BIN[i].arch, MEDIAINFO_BIN[i].checksum); 818 | const QResource mediaInfoRes(QString(":/res/bin/MediaInfo.%1.exe").arg(QString::fromLatin1(MEDIAINFO_BIN[i].arch))); 819 | if (mediaInfoRes.isValid()) 820 | { 821 | QScopedPointer hash(MUtils::Hash::create(MUtils::Hash::HASH_BLAKE2_512, HASH_SEED)); 822 | hash->update(mediaInfoRes.data(), mediaInfoRes.size()); 823 | const QByteArray checksum = hash->digest(true); 824 | if (qstricmp(MEDIAINFO_BIN[i].checksum, checksum.constData()) != 0) 825 | { 826 | qWarning("\nComputed checksum: %s\n", checksum.constData()); 827 | qFatal("MediaInfo checksum mismatch detected!"); 828 | } 829 | } 830 | else 831 | { 832 | qFatal("MediaInfo resource could not be found!"); 833 | } 834 | } 835 | qWarning("Success.\n"); 836 | } 837 | 838 | QString CMainWindow::getMediaInfoPath(void) 839 | { 840 | //Detect MediaInfo arch 841 | const QPair arch = getMediaInfoArch(); 842 | const QString fileName(QString("MediaInfo.%1.exe").arg(arch.first)); 843 | 844 | //Setup resource 845 | const QResource mediaInfoRes(QString(":/res/bin/%1").arg(fileName)); 846 | if((!mediaInfoRes.isValid()) || (!mediaInfoRes.data())) 847 | { 848 | qFatal("MediaInfo resource could not be initialized!"); 849 | return QString(); 850 | } 851 | 852 | //Validate file content, if already extracted 853 | if(!m_mediaInfoHandle.isNull()) 854 | { 855 | if(VALIDATE_MEDIAINFO(m_mediaInfoHandle.data(), arch.second)) 856 | { 857 | return m_mediaInfoHandle->fileName(); 858 | } 859 | m_mediaInfoHandle->close(); 860 | m_mediaInfoHandle.reset(); 861 | } 862 | 863 | //Try to re-use file from cache first 864 | const QFileInfo cachedFile(QString("%1/cache/%2").arg(m_baseFolder, fileName)); 865 | if (cachedFile.exists() && cachedFile.isFile()) 866 | { 867 | qDebug("MediaInfo binary exists in cache, re-using existing binary...\n"); 868 | m_mediaInfoHandle.reset(new QFile(cachedFile.absoluteFilePath())); 869 | qDebug("MediaInfo path is:\n%s\n", m_mediaInfoHandle->fileName().toUtf8().constData()); 870 | if (m_mediaInfoHandle->open(QIODevice::ReadOnly)) 871 | { 872 | if (VALIDATE_MEDIAINFO(m_mediaInfoHandle.data(), arch.second)) 873 | { 874 | return m_mediaInfoHandle->fileName(); 875 | } 876 | } 877 | else 878 | { 879 | qWarning("Failed to open MediaInfo binary for reading!\n"); 880 | } 881 | m_mediaInfoHandle->close(); 882 | m_mediaInfoHandle.reset(); 883 | } 884 | 885 | //Generate temporary file name 886 | qDebug("MediaInfo binary not existing yet, going to extract now...\n"); 887 | const QString filePath = MUtils::make_unique_file(m_tempFolder, "MediaInfo", arch.first + QLatin1String(".exe")); 888 | if (filePath.isEmpty()) 889 | { 890 | qWarning("Failed to gemerate MediaInfo outout path!\n"); 891 | return QString(); 892 | } 893 | 894 | //Extract the MediaInfo binary now! 895 | m_mediaInfoHandle.reset(new QFile(filePath)); 896 | if (m_mediaInfoHandle->open(QIODevice::ReadWrite | QIODevice::Truncate)) 897 | { 898 | qDebug("MediaInfo path is:\n%s\n", MUTILS_UTF8(m_mediaInfoHandle->fileName())); 899 | const qint64 bytesWritten = m_mediaInfoHandle->write(reinterpret_cast(mediaInfoRes.data()), mediaInfoRes.size()); 900 | m_mediaInfoHandle->close(); 901 | if (bytesWritten != mediaInfoRes.size()) 902 | { 903 | qWarning("Failed to write data to MediaInfo binary file!\n"); 904 | m_mediaInfoHandle->remove(); 905 | m_mediaInfoHandle.reset(); 906 | return QString(); 907 | } 908 | } 909 | else 910 | { 911 | qWarning("Failed to open MediaInfo binary for writing!\n"); 912 | m_mediaInfoHandle.reset(); 913 | return QString(); 914 | } 915 | 916 | //Validate file's content, after it has been extracted 917 | if (m_mediaInfoHandle->open(QIODevice::ReadOnly)) 918 | { 919 | if (VALIDATE_MEDIAINFO(m_mediaInfoHandle.data(), arch.second)) 920 | { 921 | return m_mediaInfoHandle->fileName(); 922 | } 923 | m_mediaInfoHandle->close(); 924 | } 925 | else 926 | { 927 | qWarning("Failed to open MediaInfo binary for reading!\n"); 928 | } 929 | 930 | m_mediaInfoHandle->remove(); 931 | m_mediaInfoHandle.reset(); 932 | return QString(); 933 | } 934 | 935 | QStringList CMainWindow::escapeHtmlLines(const QStringList &strings) 936 | { 937 | QStringList output; 938 | for (QStringList::const_iterator iter = strings.constBegin(); iter != strings.constEnd(); ++iter) 939 | { 940 | output << Qt::escape(*iter); 941 | } 942 | return output; 943 | } 944 | 945 | QString CMainWindow::reformatXml(const QString &input) 946 | { 947 | QString output; 948 | QXmlStreamReader reader(input); 949 | QXmlStreamWriter writer(&output); 950 | writer.setAutoFormatting(true); 951 | while (!reader.atEnd()) 952 | { 953 | reader.readNext(); 954 | if (!reader.isWhitespace()) 955 | { 956 | writer.writeCurrentToken(reader); 957 | } 958 | } 959 | return output; 960 | } 961 | -------------------------------------------------------------------------------- /src/MainWindow.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // MediaInfoXP 3 | // Copyright (C) 2004-2024 LoRd_MuldeR 4 | // 5 | // This program is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 2 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License along 16 | // with this program; if not, write to the Free Software Foundation, Inc., 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | // http://www.gnu.org/licenses/gpl-2.0.txt 20 | /////////////////////////////////////////////////////////////////////////////// 21 | 22 | #pragma once 23 | 24 | #include 25 | #include 26 | 27 | //UIC forward declartion 28 | namespace Ui 29 | { 30 | class MainWindow; 31 | } 32 | namespace MUtils 33 | { 34 | class IPCChannel; 35 | } 36 | class QProcess; 37 | class QLabel; 38 | class QFile; 39 | class IPCReceiveThread; 40 | 41 | //MainWindow class 42 | class CMainWindow: public QMainWindow 43 | { 44 | Q_OBJECT 45 | 46 | public: 47 | CMainWindow(const QString &baseFolder, const QString &tempFolder, MUtils::IPCChannel *const ipc, QWidget *parent = 0); 48 | ~CMainWindow(void); 49 | 50 | private slots: 51 | void analyzeFiles(void); 52 | void analyzeNextFile(void); 53 | void analyzeButtonClicked(void); 54 | void saveButtonClicked(void); 55 | void copyToClipboardButtonClicked(void); 56 | void clearButtonClicked(void); 57 | void outputAvailable(void); 58 | void processFinished(void); 59 | void linkTriggered(void); 60 | void showAboutScreen(void); 61 | void updateSize(void); 62 | void initShellExtension(void); 63 | void updateShellExtension(bool checked); 64 | void updateLineWrapping(bool checked); 65 | void toggleOutputOption(bool checked); 66 | void received(const quint32 &command, const QString &message); 67 | 68 | protected: 69 | virtual void showEvent(QShowEvent *event); 70 | virtual void closeEvent(QCloseEvent *event); 71 | virtual void resizeEvent(QResizeEvent *event); 72 | virtual void dragEnterEvent(QDragEnterEvent *event); 73 | virtual void dropEvent(QDropEvent *event); 74 | virtual bool eventFilter(QObject *o, QEvent *e); 75 | virtual void keyPressEvent(QKeyEvent *e); 76 | 77 | private: 78 | enum 79 | { 80 | APP_STATUS_STARTING = 0, 81 | APP_STATUS_IDLE = 1, 82 | APP_STATUS_AWAITING = 2, 83 | APP_STATUS_WORKING = 3, 84 | APP_STATUS_BLOCKED = 4 85 | } 86 | status_t; 87 | 88 | Ui::MainWindow *ui; //for Qt UIC 89 | 90 | int m_status; 91 | const QString &m_baseFolder; 92 | const QString &m_tempFolder; 93 | 94 | QScopedPointer m_ipcThread; 95 | QScopedPointer m_mediaInfoHandle; 96 | QScopedPointer m_process; 97 | QScopedPointer m_floatingLabel; 98 | QStringList m_pendingFiles; 99 | QStringList m_outputLines; 100 | 101 | QPair getMediaInfoArch(void); 102 | void selfTest(void); 103 | QString getMediaInfoPath(void); 104 | 105 | static QStringList escapeHtmlLines(const QStringList &strings); 106 | static QString reformatXml(const QString &input); 107 | }; 108 | -------------------------------------------------------------------------------- /src/ShellExtension.cpp: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // MediaInfoXP 3 | // Copyright (C) 2004-2024 LoRd_MuldeR 4 | // 5 | // This program is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 2 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License along 16 | // with this program; if not, write to the Free Software Foundation, Inc., 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | // http://www.gnu.org/licenses/gpl-2.0.txt 20 | /////////////////////////////////////////////////////////////////////////////// 21 | 22 | #pragma once 23 | 24 | #include "ShellExtension.h" 25 | 26 | //MUtils 27 | #include "MUtils/Registry.h" 28 | #include "MUtils/OSSupport.h" 29 | 30 | //Qt 31 | #include 32 | #include 33 | 34 | #define MIXP_REGISTRY_KEY "Software\\Classes\\*\\shell\\MediaInfoXP" 35 | #define MIXP_REGISTRY_VAL "_shellExtEnabled" 36 | 37 | bool ShellExtension::getEnabled(void) 38 | { 39 | quint32 value = 0; 40 | if(MUtils::Registry::reg_value_read(MUtils::Registry::root_user, MIXP_REGISTRY_KEY, MIXP_REGISTRY_VAL, value)) 41 | { 42 | return value; 43 | } 44 | return false; 45 | } 46 | 47 | bool ShellExtension::setEnabled(bool enabled) 48 | { 49 | if(enabled) 50 | { 51 | qDebug("Installing the shell extension..."); 52 | if(MUtils::Registry::reg_value_write(MUtils::Registry::root_user, MIXP_REGISTRY_KEY, QString(), tr("Analyze file with MediaInfoXP"))) 53 | { 54 | const QString appPath = QDir::toNativeSeparators(QApplication::applicationFilePath()); 55 | const QString command = QString().sprintf("\"%ls\" --open=\"%%1\"", appPath.utf16()); 56 | if(MUtils::Registry::reg_value_write(MUtils::Registry::root_user, MIXP_REGISTRY_KEY"\\command", QString(), command)) 57 | { 58 | if(MUtils::Registry::reg_value_write(MUtils::Registry::root_user, MIXP_REGISTRY_KEY, MIXP_REGISTRY_VAL, 1)) 59 | { 60 | qDebug("Success.\n"); 61 | MUtils::OS::shell_change_notification(); 62 | return true; 63 | } 64 | } 65 | } 66 | qWarning("Failed to install the shell extension!\n"); 67 | MUtils::Registry::reg_key_delete(MUtils::Registry::root_user, MIXP_REGISTRY_KEY); 68 | return false; 69 | } 70 | else 71 | { 72 | qDebug("Un-installing the shell extension..."); 73 | if(!MUtils::Registry::reg_key_delete(MUtils::Registry::root_user, MIXP_REGISTRY_KEY)) 74 | { 75 | qWarning("Failed to un-install the shell extension!\n"); 76 | return false; 77 | } 78 | qDebug("Success.\n"); 79 | MUtils::OS::shell_change_notification(); 80 | return true; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/ShellExtension.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // MediaInfoXP 3 | // Copyright (C) 2004-2024 LoRd_MuldeR 4 | // 5 | // This program is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 2 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License along 16 | // with this program; if not, write to the Free Software Foundation, Inc., 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | // http://www.gnu.org/licenses/gpl-2.0.txt 20 | /////////////////////////////////////////////////////////////////////////////// 21 | 22 | #pragma once 23 | 24 | #include 25 | 26 | class ShellExtension : public QObject 27 | { 28 | public: 29 | static bool getEnabled(void); 30 | static bool setEnabled(bool enabled); 31 | 32 | private: 33 | ShellExtension(void) {} 34 | ~ShellExtension(void) {} 35 | }; 36 | -------------------------------------------------------------------------------- /src/Version.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // MediaInfoXP 3 | // Copyright (C) 2004-2024 LoRd_MuldeR 4 | // 5 | // This program is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation; either version 2 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License along 16 | // with this program; if not, write to the Free Software Foundation, Inc., 17 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | // 19 | // http://www.gnu.org/licenses/gpl-2.0.txt 20 | /////////////////////////////////////////////////////////////////////////////// 21 | 22 | #pragma once 23 | 24 | #define MIXP_VERSION_MAJOR 2 25 | #define MIXP_VERSION_MINOR_HI 4 26 | #define MIXP_VERSION_MINOR_LO 7 27 | #define MIXP_VERSION_PATCH 0 28 | -------------------------------------------------------------------------------- /z_build.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | REM /////////////////////////////////////////////////////////////////////////// 3 | REM // Set Paths 4 | REM /////////////////////////////////////////////////////////////////////////// 5 | set "MSVC_PATH=C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build" 6 | 7 | REM ############################################### 8 | REM # DO NOT MODIFY ANY LINES BELOW THIS LINE !!! # 9 | REM ############################################### 10 | 11 | REM /////////////////////////////////////////////////////////////////////////// 12 | REM // Setup environment 13 | REM /////////////////////////////////////////////////////////////////////////// 14 | if exist "%QTVC_PATH%\bin\qtvars.bat" ( call "%QTVC_PATH%\bin\qtvars.bat" ) 15 | if exist "%QTVC_PATH%\bin\qtenv2.bat" ( call "%QTVC_PATH%\bin\qtenv2.bat" ) 16 | call "%MSVC_PATH%\vcvarsall.bat" x86 17 | 18 | REM /////////////////////////////////////////////////////////////////////////// 19 | REM // Check environment 20 | REM /////////////////////////////////////////////////////////////////////////// 21 | if "%VCINSTALLDIR%"=="" ( 22 | echo %%VCINSTALLDIR%% not specified. Please check your MSVC_PATH var! 23 | goto BuildError 24 | ) 25 | if "%QTDIR%"=="" ( 26 | echo %%QTDIR%% not specified. Please check your MSVC_PATH var! 27 | goto BuildError 28 | ) 29 | if not exist "%VCToolsInstallDir%\bin\HostX86\x86\cl.exe" ( 30 | echo C++ compiler not found. Please check your MSVC_PATH var! 31 | goto BuildError 32 | ) 33 | if not exist "%QTDIR%\bin\moc.exe" ( 34 | echo Qt meta compiler not found. Please check your QTDIR var! 35 | goto BuildError 36 | ) 37 | if not exist "%QTDIR%\include\QtCore\qglobal.h" ( 38 | echo %%QTDIR%% header files not found. Please check your QTDIR var! 39 | goto BuildError 40 | ) 41 | 42 | REM /////////////////////////////////////////////////////////////////////////// 43 | REM // Get current date and time (in ISO format) 44 | REM /////////////////////////////////////////////////////////////////////////// 45 | set "ISO_DATE=" 46 | set "ISO_TIME=" 47 | if not exist "%~dp0\..\Prerequisites\MSYS\1.0\bin\date.exe" BuildError 48 | for /F "tokens=1,2 delims=:" %%a in ('"%~dp0\..\Prerequisites\MSYS\1.0\bin\date.exe" +ISODATE:%%Y-%%m-%%d') do ( 49 | if "%%a"=="ISODATE" set "ISO_DATE=%%b" 50 | ) 51 | for /F "tokens=1,2,3,4 delims=:" %%a in ('"%~dp0\..\Prerequisites\MSYS\1.0\bin\date.exe" +ISOTIME:%%T') do ( 52 | if "%%a"=="ISOTIME" set "ISO_TIME=%%b:%%c:%%d" 53 | ) 54 | if "%ISO_DATE%"=="" goto BuildError 55 | if "%ISO_TIME%"=="" goto BuildError 56 | 57 | REM /////////////////////////////////////////////////////////////////////////// 58 | REM // Build the binaries 59 | REM /////////////////////////////////////////////////////////////////////////// 60 | echo --------------------------------------------------------------------- 61 | echo BEGIN BUILD 62 | echo --------------------------------------------------------------------- 63 | MSBuild.exe /property:Configuration=release_static /property:Platform=Win32 /target:clean "%~dp0\MediaInfoXP.sln" 64 | if not "%ERRORLEVEL%"=="0" goto BuildError 65 | MSBuild.exe /property:Configuration=release_static /property:Platform=Win32 /target:rebuild "%~dp0\MediaInfoXP.sln" 66 | if not "%ERRORLEVEL%"=="0" goto BuildError 67 | MSBuild.exe /property:Configuration=release_static /property:Platform=Win32 /target:build "%~dp0\MediaInfoXP.sln" 68 | if not "%ERRORLEVEL%"=="0" goto BuildError 69 | 70 | REM /////////////////////////////////////////////////////////////////////////// 71 | REM // Copy base files 72 | REM /////////////////////////////////////////////////////////////////////////// 73 | echo --------------------------------------------------------------------- 74 | echo BEGIN PACKAGING 75 | echo --------------------------------------------------------------------- 76 | set "PACK_PATH=%TMP%\~%RANDOM%%RANDOM%.tmp" 77 | mkdir "%PACK_PATH%" 78 | copy "%~dp0\bin\Win32\Release_Static\*.exe" "%PACK_PATH%" 79 | copy "%~dp0\Copying.txt" "%PACK_PATH%" 80 | copy "%~dp0\doc\*.txt" "%PACK_PATH%" 81 | copy "%~dp0\doc\*.html" "%PACK_PATH%" 82 | copy "%~dp0\doc\*.svg" "%PACK_PATH%" 83 | 84 | REM /////////////////////////////////////////////////////////////////////////// 85 | REM // Compress 86 | REM /////////////////////////////////////////////////////////////////////////// 87 | ::"%~dp0\..\Prerequisites\UPX\upx.exe" --best "%PACK_PATH%\*.exe" 88 | 89 | REM /////////////////////////////////////////////////////////////////////////// 90 | REM // Attributes 91 | REM /////////////////////////////////////////////////////////////////////////// 92 | attrib +R "%PACK_PATH%\*.exe" 93 | attrib +R "%PACK_PATH%\*.html" 94 | attrib +R "%PACK_PATH%\*.txt" 95 | attrib +R "%PACK_PATH%\*.svg" 96 | 97 | REM /////////////////////////////////////////////////////////////////////////// 98 | REM // Generate outfile name 99 | REM /////////////////////////////////////////////////////////////////////////// 100 | set "OUT_NAME=MediaInfo-GUI.%ISO_DATE%" 101 | :CheckOutName 102 | if exist "%~dp0\out\%OUT_NAME%.zip" ( 103 | set "OUT_NAME=%OUT_NAME%.new" 104 | goto CheckOutName 105 | ) 106 | 107 | REM /////////////////////////////////////////////////////////////////////////// 108 | REM // Create version tag 109 | REM /////////////////////////////////////////////////////////////////////////// 110 | echo MediaInfoXP - Simple GUI for MediaInfo > "%~dp0\out\%OUT_NAME%.txt" 111 | echo Built %ISO_DATE%, %TIME% >> "%~dp0\out\%OUT_NAME%.txt" 112 | echo Copyright (C) 2004-2024 LoRd_MuldeR ^ >> "%~dp0\out\%OUT_NAME%.txt" 113 | echo. >> "%~dp0\out\%OUT_NAME%.txt" 114 | echo This program is free software; you can redistribute it and/or modify >> "%~dp0\out\%OUT_NAME%.txt" 115 | echo it under the terms of the GNU General Public License as published by >> "%~dp0\out\%OUT_NAME%.txt" 116 | echo the Free Software Foundation; either version 2 of the License, or >> "%~dp0\out\%OUT_NAME%.txt" 117 | echo (at your option) any later version. >> "%~dp0\out\%OUT_NAME%.txt" 118 | echo. >> "%~dp0\out\%OUT_NAME%.txt" 119 | echo ------------------------------------------------------------------->> "%~dp0\out\%OUT_NAME%.txt" 120 | echo. >> "%~dp0\out\%OUT_NAME%.txt" 121 | echo MediaInfo(Lib) is Copyright (C) 2002-2024 MediaArea.net SARL. >> "%~dp0\out\%OUT_NAME%.txt" 122 | echo. >> "%~dp0\out\%OUT_NAME%.txt" 123 | echo Redistribution and use in source and binary forms, with or without >> "%~dp0\out\%OUT_NAME%.txt" 124 | echo modification, are permitted according to the BSD-2-Clause license. >> "%~dp0\out\%OUT_NAME%.txt" 125 | echo. >> "%~dp0\out\%OUT_NAME%.txt" 126 | 127 | REM /////////////////////////////////////////////////////////////////////////// 128 | REM // Build the package 129 | REM /////////////////////////////////////////////////////////////////////////// 130 | pushd "%PACK_PATH% 131 | "%~dp0\..\Prerequisites\InfoZip\zip.exe" -9 -r -z "%~dp0\out\%OUT_NAME%.zip" "*.*" < "%~dp0\out\%OUT_NAME%.txt" 132 | popd 133 | rmdir /Q /S "%PACK_PATH%" 134 | attrib +R "%~dp0\out\%OUT_NAME%.zip" 135 | del "%~dp0\out\%OUT_NAME%.txt" 136 | 137 | REM /////////////////////////////////////////////////////////////////////////// 138 | REM // COMPLETE 139 | REM /////////////////////////////////////////////////////////////////////////// 140 | echo. 141 | echo Build completed. 142 | echo. 143 | pause 144 | goto:eof 145 | 146 | REM /////////////////////////////////////////////////////////////////////////// 147 | REM // FAILED 148 | REM /////////////////////////////////////////////////////////////////////////// 149 | :BuildError 150 | echo. 151 | echo Build has failed !!! 152 | echo. 153 | pause 154 | --------------------------------------------------------------------------------