initial commit for 0.4.18 version of Telegram Desktop
14
.gitignore
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
Telegram/GeneratedFiles/
|
||||
Telegram/*.user
|
||||
Telegram.*.suo
|
||||
Telegram.sdf
|
||||
Telegram.opensdf
|
||||
Win32/
|
||||
ipch/
|
||||
|
||||
Telegram/log.txt
|
||||
Telegram/data
|
||||
Telegram/data_config
|
||||
Telegram/DebugLogs/
|
||||
Telegram/tdata/
|
||||
Telegram/tdumps/
|
200
README.md
|
@ -1,4 +1,198 @@
|
|||
tdesktop
|
||||
========
|
||||
## [Telegram D](https://tdesktop.com) – Unofficial Telegram Desktop App
|
||||
|
||||
Telegram Desktop messaging app
|
||||
This is complete source code and build instructions for alpha version of unofficial desktop client for [Telegram](https://telegram.org) messenger, based on [Telegram API](https://core.telegram.org/) and [MTProto](https://core.telegram.org/mtproto) secure protocol.
|
||||
|
||||
###Supported systems
|
||||
|
||||
Only Windows systems are supported at this moment, OS X and Linux builds are on their way.
|
||||
|
||||
* Windows XP
|
||||
* Windows Vista
|
||||
* Windows 7
|
||||
* Windows 8 (**not** RT)
|
||||
* Windows 8.1 (**not** RT)
|
||||
|
||||
###Third-party libraries
|
||||
|
||||
* Qt 5.3.0, slightly patched
|
||||
* OpenSSL 1.0.1g
|
||||
* zlib 1.2.8
|
||||
* libexif 0.6.20
|
||||
* LZMA SDK 9.20
|
||||
|
||||
##Build instructions for Visual Studio 2013
|
||||
|
||||
###Prepare folder
|
||||
|
||||
Choose a folder for the future build, for example **D:\TBuild\**. There you will have two folders, **Libraries** for third-party libs and **tdesktop** (or **tdesktop-master**) for the app.
|
||||
|
||||
###Clone source code
|
||||
|
||||
By git – in [Git Bash](http://git-scm.com/downloads) go to **/d/tbuild** and run
|
||||
|
||||
git clone https://github.com/telegramdesktop/tdesktop.git
|
||||
|
||||
or download in ZIP and extract to **D:\TBuild\**, rename **tdesktop-master** to **tdesktop** to have **D:\TBuild\tdesktop\Telegram.sln** solution
|
||||
|
||||
###Prepare libraries
|
||||
|
||||
####OpenSSL 1.0.1g
|
||||
|
||||
https://www.openssl.org/related/binaries.html > **OpenSSL for Windows** > Download [**Win32 OpenSSL v1.0.1g** (16 Mb)](http://slproweb.com/download/Win32OpenSSL-1_0_1g.exe)
|
||||
|
||||
Install to **D:\TBuild\Libraries\OpenSSL-Win32**, while installing **Copy OpenSSL DLLs to** choose **The OpenSSL binaries (/bin) directory**
|
||||
|
||||
####LZMA SDK 9.20
|
||||
|
||||
http://www.7-zip.org/sdk.html > Download [**LZMA SDK (C, C++, C#, Java)** 9.20](http://downloads.sourceforge.net/sevenzip/lzma920.tar.bz2)
|
||||
|
||||
Extract to **D:\TBuild\Libraries**
|
||||
|
||||
#####Building library
|
||||
|
||||
* Open in VS2013 **D:\TBuild\Libraries\lzma\C\Util\LzmaLib\LzmaLib.dsw** > One-way upgrade – **OK**
|
||||
* For **Debug** and **Release** configurations
|
||||
* LzmaLib Properties > General > Configuration Type = **Static library (.lib)** – **OK**
|
||||
* LzmaLib Properties > Librarian > General > Target Machine = **MachineX86 (/MACHINE:X86)** – **OK**
|
||||
* Build Debug configuration
|
||||
* Build Release configuration
|
||||
|
||||
####zlib 1.2.8
|
||||
|
||||
http://www.zlib.net/ > Download [**zlib source code, version 1.2.8, zipfile format**](http://zlib.net/zlib128.zip)
|
||||
|
||||
Extract to **D:\TBuild\Libraries\**
|
||||
|
||||
#####Building library
|
||||
|
||||
* Open in VS2013 **D:\TBuild\Libraries\zlib-1.2.8\contrib\vstudio\vc11\zlibvc.sln** > One-way upgrade – **OK**
|
||||
* We are interested only in **zlibstat** project, but it depends on some custom pre-build step, so build all
|
||||
* For **Debug** configuration
|
||||
* zlibstat Properties > C/C++ > Code Generation > Runtime Library = **Multi-threaded Debug (/MTd)** – **OK**
|
||||
* For **Release** configuration
|
||||
* zlibstat Properties > C/C++ > Code Generation > Runtime Library = **Multi-threaded (/MT)** – **OK**
|
||||
* Build Solution for Debug configuration – only **zlibstat** project builds successfully
|
||||
* Build Solution for Release configuration – only **zlibstat** project builds successfully
|
||||
|
||||
####libexif 0.6.20
|
||||
|
||||
Get sources from https://github.com/telegramdesktop/libexif-0.6.20, by git – in [Git Bash](http://git-scm.com/downloads) go to **/d/tbuild/libraries** and run
|
||||
|
||||
git clone https://github.com/telegramdesktop/libexif-0.6.20.git
|
||||
|
||||
or download in ZIP and extract to **D:\TBuild\Libraries\**, rename **libexif-0.6.20-master** to **libexif-0.6.20** to have **D:\TBuild\Libraries\libexif-0.6.20\win32\lib_exif.sln** solution
|
||||
|
||||
#####Building library
|
||||
|
||||
* Open in VS2013 **D:\TBuild\Libraries\libexif-0.6.20\win32\lib_exif.sln**
|
||||
* Build Debug configuration
|
||||
* Build Release configuration
|
||||
|
||||
####Qt 5.3.0, slightly patched
|
||||
|
||||
http://download.qt-project.org/official_releases/qt/5.3/5.3.0/single/qt-everywhere-opensource-src-5.3.0.zip
|
||||
|
||||
Extract to **D:\TBuild\Libraries\**, rename **qt-everywhere-opensource-src-5.3.0** to **QtStatic** to have **D:\TBuild\Libraries\QtStatic\qtbase\** folder
|
||||
|
||||
Apply patch – copy (with overwrite!) everything from **D:\TBuild\tdesktop\\\_qt\_5\_3\_0\_patch\** to **D:\TBuild\Libraries\QtStatic\**
|
||||
|
||||
#####Building library
|
||||
|
||||
* Install Python 3.3.2 from https://www.python.org/download/releases/3.3.2 > [**Windows x86 MSI Installer (3.3.2)**](https://www.python.org/ftp/python/3.3.2/python-3.3.2.msi)
|
||||
* Open **VS2013 x86 Native Tools Command Prompt.bat** (should be in **\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\Shortcuts\** folder)
|
||||
|
||||
There go to Qt directory
|
||||
|
||||
D:
|
||||
cd TBuild\Libraries\QtStatic
|
||||
|
||||
and after that run configure
|
||||
|
||||
configure -debug-and-release -opensource -static -opengl desktop -mp -nomake examples -platform win32-msvc2013
|
||||
y
|
||||
|
||||
to configure Qt build. After configuration is complete run
|
||||
|
||||
nmake
|
||||
nmake install
|
||||
|
||||
building (**nmake** command) will take really long time.
|
||||
|
||||
####Qt Visual Studio Addin 1.2.3
|
||||
|
||||
http://download.qt-project.org/official_releases/vsaddin/qt-vs-addin-1.2.3-opensource.exe
|
||||
|
||||
Close all VS2013 instances and install to default location
|
||||
|
||||
###Building Telegram Desktop
|
||||
|
||||
* Launch VS2013 for configuring Qt Addin
|
||||
* QT5 > Qt Options > Add
|
||||
* Version name: **QtStatic.5.3.0**
|
||||
* Path: **D:\TBuild\Libraries\QtStatic\qtbase**
|
||||
* Default Qt/Win version: **QtStatic.5.3.0** – **OK**
|
||||
* File > Open > Project/Solution > **D:\TBuild\tdesktop\Telegram.sln**
|
||||
* Build \ Build Solution (Debug and Release configurations)
|
||||
|
||||
##Projects in Telegram solution
|
||||
|
||||
####Telegram
|
||||
|
||||
tdesktop messenger
|
||||
|
||||
####Updater
|
||||
|
||||
little app, that is launched by Telegram when update is ready, replaces all files and launches it back
|
||||
|
||||
####Packer
|
||||
|
||||
compiles given files to single update file, compresses it with lzma and signs with a private key, it was not included to Telegram solution, because private key is inaccessible
|
||||
|
||||
####Prepare
|
||||
|
||||
prepares a release for deployment, puts all files to deploy/{version} folder
|
||||
* current tsetup{version}exe installer
|
||||
* current Telegram.exe
|
||||
* current Telegram.pdb (debug info for crash minidumps view)
|
||||
* current tupdate{updversion} binary lzma update archive
|
||||
|
||||
####MetaEmoji
|
||||
|
||||
from two folders
|
||||
* SourceFiles/art/Emoji
|
||||
* SourceFiles/art/Emoji_200x
|
||||
|
||||
and some inner config creates four sprites and text2emoji replace code
|
||||
* SourceFiles/art/emoji.png
|
||||
* SourceFiles/art/emoji_125x.png
|
||||
* SourceFiles/art/emoji_150x.png
|
||||
* SourceFiles/art/emoji_200x.png
|
||||
* SourceFiles/gui/emoji_config.cpp
|
||||
|
||||
####MetaStyle
|
||||
|
||||
from two files and two sprites
|
||||
* Resources/style_classes.txt
|
||||
* Resources/style.txt
|
||||
* SourceFiles/art/sprite.png
|
||||
* SourceFiles/art/sprite_200x.png
|
||||
|
||||
creates two other sprites, four sprite grids and style constants code
|
||||
* SourceFiles/art/sprite_125x.png
|
||||
* SourceFiles/art/sprite_150x.png
|
||||
* SourceFiles/art/grid.png
|
||||
* SourceFiles/art/grid_125x.png
|
||||
* SourceFiles/art/grid_150x.png
|
||||
* SourceFiles/art/grid_200x.png
|
||||
* GeneratedFiles/style_classes.h
|
||||
* GeneratedFiles/style_auto.h
|
||||
* GeneratedFiles/style_auto.cpp
|
||||
|
||||
####MetaLang
|
||||
|
||||
from langpack file
|
||||
* Resources/lang.txt
|
||||
|
||||
creates lang constants code and lang file parse code
|
||||
* GeneratedFiles/lang.h
|
||||
* GeneratedFiles/lang.cpp
|
72
Telegram.sln
Normal file
|
@ -0,0 +1,72 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.30110.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Telegram", "Telegram\Telegram.vcxproj", "{B12702AD-ABFB-343A-A199-8E24837244A3}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{6F483617-7C84-4E7E-91D8-1FF28A4CE3A0} = {6F483617-7C84-4E7E-91D8-1FF28A4CE3A0}
|
||||
{E417CAA4-259B-4C99-88E3-805F1300E8EB} = {E417CAA4-259B-4C99-88E3-805F1300E8EB}
|
||||
{EB7D16AC-EACF-4577-B05A-F28E5F356794} = {EB7D16AC-EACF-4577-B05A-F28E5F356794}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MetaStyle", "Telegram\MetaStyle.vcxproj", "{6F483617-7C84-4E7E-91D8-1FF28A4CE3A0}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MetaEmoji", "Telegram\MetaEmoji.vcxproj", "{EB7D16AC-EACF-4577-B05A-F28E5F356794}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Updater", "Telegram\Updater.vcxproj", "{6B4BA3BE-7B15-4B4C-B200-81ABFDEF2C76}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Prepare", "Telegram\Prepare.vcxproj", "{88AB1138-143A-4CFB-A0E6-79B646B5E1B0}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MetaLang", "Telegram\MetaLang.vcxproj", "{E417CAA4-259B-4C99-88E3-805F1300E8EB}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|Win32.Deploy.0 = Debug|Win32
|
||||
{B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{B12702AD-ABFB-343A-A199-8E24837244A3}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{B12702AD-ABFB-343A-A199-8E24837244A3}.Release|Win32.Build.0 = Release|Win32
|
||||
{B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x64.ActiveCfg = Release|Win32
|
||||
{6F483617-7C84-4E7E-91D8-1FF28A4CE3A0}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{6F483617-7C84-4E7E-91D8-1FF28A4CE3A0}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{6F483617-7C84-4E7E-91D8-1FF28A4CE3A0}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{6F483617-7C84-4E7E-91D8-1FF28A4CE3A0}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{6F483617-7C84-4E7E-91D8-1FF28A4CE3A0}.Release|Win32.Build.0 = Release|Win32
|
||||
{6F483617-7C84-4E7E-91D8-1FF28A4CE3A0}.Release|x64.ActiveCfg = Release|Win32
|
||||
{EB7D16AC-EACF-4577-B05A-F28E5F356794}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{EB7D16AC-EACF-4577-B05A-F28E5F356794}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{EB7D16AC-EACF-4577-B05A-F28E5F356794}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{EB7D16AC-EACF-4577-B05A-F28E5F356794}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{EB7D16AC-EACF-4577-B05A-F28E5F356794}.Release|Win32.Build.0 = Release|Win32
|
||||
{EB7D16AC-EACF-4577-B05A-F28E5F356794}.Release|x64.ActiveCfg = Release|Win32
|
||||
{6B4BA3BE-7B15-4B4C-B200-81ABFDEF2C76}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{6B4BA3BE-7B15-4B4C-B200-81ABFDEF2C76}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{6B4BA3BE-7B15-4B4C-B200-81ABFDEF2C76}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{6B4BA3BE-7B15-4B4C-B200-81ABFDEF2C76}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{6B4BA3BE-7B15-4B4C-B200-81ABFDEF2C76}.Release|Win32.Build.0 = Release|Win32
|
||||
{6B4BA3BE-7B15-4B4C-B200-81ABFDEF2C76}.Release|x64.ActiveCfg = Release|Win32
|
||||
{88AB1138-143A-4CFB-A0E6-79B646B5E1B0}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{88AB1138-143A-4CFB-A0E6-79B646B5E1B0}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{88AB1138-143A-4CFB-A0E6-79B646B5E1B0}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{88AB1138-143A-4CFB-A0E6-79B646B5E1B0}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{88AB1138-143A-4CFB-A0E6-79B646B5E1B0}.Release|Win32.Build.0 = Release|Win32
|
||||
{88AB1138-143A-4CFB-A0E6-79B646B5E1B0}.Release|x64.ActiveCfg = Release|Win32
|
||||
{E417CAA4-259B-4C99-88E3-805F1300E8EB}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{E417CAA4-259B-4C99-88E3-805F1300E8EB}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{E417CAA4-259B-4C99-88E3-805F1300E8EB}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{E417CAA4-259B-4C99-88E3-805F1300E8EB}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{E417CAA4-259B-4C99-88E3-805F1300E8EB}.Release|Win32.Build.0 = Release|Win32
|
||||
{E417CAA4-259B-4C99-88E3-805F1300E8EB}.Release|x64.ActiveCfg = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
115
Telegram/MetaEmoji.vcxproj
Normal file
|
@ -0,0 +1,115 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="GeneratedFiles\Debug\moc_genemoji.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Release\moc_genemoji.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SourceFiles\_other\genemoji.cpp" />
|
||||
<ClCompile Include="SourceFiles\_other\memain.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="SourceFiles\_other\genemoji.h">
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Moc%27ing genemoji.h...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Moc%27ing genemoji.h...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -DQT_NO_DEBUG -DNDEBUG "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
</CustomBuild>
|
||||
<ClInclude Include="SourceFiles\_other\memain.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{EB7D16AC-EACF-4577-B05A-F28E5F356794}</ProjectGuid>
|
||||
<Keyword>Qt4VSv1.0</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v120_xp</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v120_xp</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>11.0.60610.1</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)Emoji\</OutDir>
|
||||
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)IntermediateEmoji\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)Emoji\</OutDir>
|
||||
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)IntermediateEmoji\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>UNICODE;WIN32;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;imm32.lib;winmm.lib;qtmaind.lib;glu32.lib;opengl32.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5PlatformSupportd.lib;platforms\qwindowsd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<ProfileGuidedDatabase>$(IntDir)$(TargetName).pgd</ProfileGuidedDatabase>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>UNICODE;WIN32;WIN64;QT_NO_DEBUG;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DebugInformationFormat />
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;glu32.lib;opengl32.lib;imm32.lib;winmm.lib;Qt5Core.lib;Qt5Gui.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<ProfileGuidedDatabase>$(IntDir)$(TargetName).pgd</ProfileGuidedDatabase>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties UicDir=".\GeneratedFiles" MocDir=".\GeneratedFiles\$(ConfigurationName)" MocOptions="" RccDir=".\GeneratedFiles" lupdateOnBuild="1" lupdateOptions="" lreleaseOptions="" Qt5Version_x0020_Win32="$(DefaultQtVersion)" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
57
Telegram/MetaEmoji.vcxproj.filters
Normal file
|
@ -0,0 +1,57 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;cxx;c;def</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
|
||||
<Extensions>qrc;*</Extensions>
|
||||
<ParseFiles>false</ParseFiles>
|
||||
</Filter>
|
||||
<Filter Include="Generated Files">
|
||||
<UniqueIdentifier>{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}</UniqueIdentifier>
|
||||
<Extensions>moc;h;cpp</Extensions>
|
||||
<SourceControlFiles>False</SourceControlFiles>
|
||||
</Filter>
|
||||
<Filter Include="Generated Files\Debug">
|
||||
<UniqueIdentifier>{d43dc9f2-202b-4a47-b396-e7e2882cd611}</UniqueIdentifier>
|
||||
<Extensions>cpp;moc</Extensions>
|
||||
<SourceControlFiles>False</SourceControlFiles>
|
||||
</Filter>
|
||||
<Filter Include="Generated Files\Release">
|
||||
<UniqueIdentifier>{6a90eef7-d2c6-46bd-8158-a8c5185190a7}</UniqueIdentifier>
|
||||
<Extensions>cpp;moc</Extensions>
|
||||
<SourceControlFiles>False</SourceControlFiles>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="SourceFiles\_other\memain.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SourceFiles\_other\genemoji.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Debug\moc_genemoji.cpp">
|
||||
<Filter>Generated Files\Debug</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Release\moc_genemoji.cpp">
|
||||
<Filter>Generated Files\Release</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="SourceFiles\_other\memain.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="SourceFiles\_other\genemoji.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
</Project>
|
113
Telegram/MetaLang.vcxproj
Normal file
|
@ -0,0 +1,113 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="GeneratedFiles\Debug\moc_genlang.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Release\moc_genlang.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SourceFiles\_other\genlang.cpp" />
|
||||
<ClCompile Include="SourceFiles\_other\mlmain.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="SourceFiles\_other\genlang.h">
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Moc%27ing genlang.h...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Moc%27ing genlang.h...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -DQT_NO_DEBUG -DNDEBUG "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
|
||||
</CustomBuild>
|
||||
<ClInclude Include="SourceFiles\_other\mlmain.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{E417CAA4-259B-4C99-88E3-805F1300E8EB}</ProjectGuid>
|
||||
<Keyword>Qt4VSv1.0</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v120_xp</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v120_xp</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>12.0.21005.1</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)Lang\</OutDir>
|
||||
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)IntermediateLang\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)Lang\</OutDir>
|
||||
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)IntermediateLang\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>UNICODE;WIN32;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;imm32.lib;winmm.lib;qtmaind.lib;glu32.lib;opengl32.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5Widgetsd.lib;Qt5Networkd.lib;Qt5PlatformSupportd.lib;platforms\qwindowsd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<ProfileGuidedDatabase>$(IntDir)$(TargetName).pgd</ProfileGuidedDatabase>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>UNICODE;WIN32;WIN64;QT_NO_DEBUG;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DebugInformationFormat />
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;opengl32.lib;imm32.lib;winmm.lib;Qt5Core.lib;Qt5Gui.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties MocDir=".\GeneratedFiles\$(ConfigurationName)" UicDir=".\GeneratedFiles" RccDir=".\GeneratedFiles" lupdateOptions="" lupdateOnBuild="0" lreleaseOptions="" Qt5Version_x0020_Win32="$(DefaultQtVersion)" MocOptions="" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
57
Telegram/MetaLang.vcxproj.filters
Normal file
|
@ -0,0 +1,57 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;cxx;c;def</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
|
||||
<Extensions>qrc;*</Extensions>
|
||||
<ParseFiles>false</ParseFiles>
|
||||
</Filter>
|
||||
<Filter Include="Generated Files">
|
||||
<UniqueIdentifier>{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}</UniqueIdentifier>
|
||||
<Extensions>moc;h;cpp</Extensions>
|
||||
<SourceControlFiles>False</SourceControlFiles>
|
||||
</Filter>
|
||||
<Filter Include="Generated Files\Debug">
|
||||
<UniqueIdentifier>{3c9f729e-b8c7-4b14-b2df-4a3eda27c074}</UniqueIdentifier>
|
||||
<Extensions>cpp;moc</Extensions>
|
||||
<SourceControlFiles>False</SourceControlFiles>
|
||||
</Filter>
|
||||
<Filter Include="Generated Files\Release">
|
||||
<UniqueIdentifier>{3e5a3edb-4328-4310-aec6-a3c6449e1aab}</UniqueIdentifier>
|
||||
<Extensions>cpp;moc</Extensions>
|
||||
<SourceControlFiles>False</SourceControlFiles>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="SourceFiles\_other\mlmain.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Debug\moc_genlang.cpp">
|
||||
<Filter>Generated Files\Debug</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SourceFiles\_other\genlang.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Release\moc_genlang.cpp">
|
||||
<Filter>Generated Files\Release</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="SourceFiles\_other\mlmain.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="SourceFiles\_other\genlang.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
</Project>
|
129
Telegram/MetaStyle.vcxproj
Normal file
|
@ -0,0 +1,129 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\Telegram\SourceFiles\_other\genstyles.cpp" />
|
||||
<ClCompile Include="GeneratedFiles\Debug\moc_genstyles.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Release\moc_genstyles.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SourceFiles\_other\msmain.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="SourceFiles\_other\msmain.h">
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</Command>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</Command>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="..\Telegram\SourceFiles\_other\genstyles.h">
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Moc%27ing genstyles.h...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Moc%27ing genstyles.h...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DWIN64 -DQT_NO_DEBUG -DNDEBUG "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\."</Command>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{6F483617-7C84-4E7E-91D8-1FF28A4CE3A0}</ProjectGuid>
|
||||
<Keyword>Qt4VSv1.0</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v120_xp</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v120_xp</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>11.0.60610.1</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)IntermediateMeta\</IntDir>
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)Meta\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)Meta\</OutDir>
|
||||
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)IntermediateMeta\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>UNICODE;WIN32;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;imm32.lib;winmm.lib;qtmaind.lib;glu32.lib;opengl32.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5Widgetsd.lib;Qt5Networkd.lib;Qt5PlatformSupportd.lib;platforms\qwindowsd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<ProfileGuidedDatabase>$(IntDir)$(TargetName).pgd</ProfileGuidedDatabase>
|
||||
</Link>
|
||||
<ProjectReference />
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>UNICODE;WIN32;WIN64;QT_NO_DEBUG;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DebugInformationFormat />
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;opengl32.lib;imm32.lib;winmm.lib;Qt5Core.lib;Qt5Gui.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties UicDir=".\GeneratedFiles" MocDir=".\GeneratedFiles\$(ConfigurationName)" MocOptions="" RccDir=".\GeneratedFiles" lupdateOnBuild="1" lupdateOptions="" lreleaseOptions="" Qt5Version_x0020_Win32="$(DefaultQtVersion)" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
55
Telegram/MetaStyle.vcxproj.filters
Normal file
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;cxx;c;def</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
|
||||
<Extensions>qrc;*</Extensions>
|
||||
<ParseFiles>false</ParseFiles>
|
||||
</Filter>
|
||||
<Filter Include="Generated Files">
|
||||
<UniqueIdentifier>{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}</UniqueIdentifier>
|
||||
<Extensions>moc;h;cpp</Extensions>
|
||||
<SourceControlFiles>False</SourceControlFiles>
|
||||
</Filter>
|
||||
<Filter Include="Generated Files\Debug">
|
||||
<UniqueIdentifier>{1ace0630-c46a-4299-a4c3-d155a4cb04bb}</UniqueIdentifier>
|
||||
<Extensions>cpp;moc</Extensions>
|
||||
<SourceControlFiles>False</SourceControlFiles>
|
||||
</Filter>
|
||||
<Filter Include="Generated Files\Release">
|
||||
<UniqueIdentifier>{2473bf06-b2ba-4f68-9bfe-72a58da61f94}</UniqueIdentifier>
|
||||
<Extensions>cpp;moc</Extensions>
|
||||
<SourceControlFiles>False</SourceControlFiles>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\Telegram\SourceFiles\_other\genstyles.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SourceFiles\_other\msmain.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Debug\moc_genstyles.cpp">
|
||||
<Filter>Generated Files\Debug</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Release\moc_genstyles.cpp">
|
||||
<Filter>Generated Files\Release</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="..\Telegram\SourceFiles\_other\genstyles.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="SourceFiles\_other\msmain.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
</Project>
|
96
Telegram/Packer.vcxproj
Normal file
|
@ -0,0 +1,96 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="SourceFiles\_other\packer.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="SourceFiles\_other\packer.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{56A9A4B2-21E5-4360-AFA8-85B43AC43B08}</ProjectGuid>
|
||||
<Keyword>Qt4VSv1.0</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v120_xp</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v120_xp</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>11.0.61030.0</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)IntermediatePacker\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)IntermediatePacker\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>UNICODE;WIN32;WIN64;QT_CORE_LIB;ZLIB_WINAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>.\..\..\Libraries\lzma\C;.;$(QTDIR)\include;.\..\..\Libraries\zlib-1.2.8;.\..\..\Libraries\OpenSSL-32-Debug\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>.\..\..\Libraries\lzma\C\Util\LzmaLib\Debug;$(QTDIR)\lib;.\..\..\Libraries\zlib-1.2.8\contrib\vstudio\vc11\x86\ZlibStatQtDebug;.\..\..\Libraries\OpenSSL-32-Debug\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmaind.lib;zlibstat_qt.lib;libeay32.lib;Qt5Cored.lib;LzmaLib.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ImageHasSafeExceptionHandlers />
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>UNICODE;WIN32;WIN64;QT_NO_DEBUG;ZLIB_WINAPI;NDEBUG;QT_CORE_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DebugInformationFormat />
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>.\..\..\Libraries\lzma\C;.;$(QTDIR)\include;.\..\..\Libraries\zlib-1.2.8;.\..\..\Libraries\OpenSSL-32\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>.\..\..\Libraries\lzma\C\Util\LzmaLib\Release;$(QTDIR)\lib;.\..\..\Libraries\zlib-1.2.8\contrib\vstudio\vc11\x86\ZlibStatQtRelease;.\..\..\Libraries\OpenSSL-32\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;zlibstat_qt.lib;libeay32.lib;Qt5Core.lib;LzmaLib.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<ImageHasSafeExceptionHandlers />
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties UicDir=".\GeneratedFiles" MocDir=".\GeneratedFiles\$(ConfigurationName)" MocOptions="" RccDir=".\GeneratedFiles" lupdateOnBuild="0" lupdateOptions="" lreleaseOptions="" Qt5Version_x0020_Win32="$(DefaultQtVersion)" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
16
Telegram/Packer.vcxproj.filters
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Generated Files">
|
||||
<UniqueIdentifier>{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}</UniqueIdentifier>
|
||||
<Extensions>moc;h;cpp</Extensions>
|
||||
<SourceControlFiles>False</SourceControlFiles>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="SourceFiles\_other\packer.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="SourceFiles\_other\packer.cpp" />
|
||||
</ItemGroup>
|
||||
</Project>
|
1
Telegram/Prepare.bat
Normal file
|
@ -0,0 +1 @@
|
|||
Prepare.exe -path Telegram.exe -path Updater.exe
|
94
Telegram/Prepare.vcxproj
Normal file
|
@ -0,0 +1,94 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="SourceFiles\_other\prepare.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="SourceFiles\_other\prepare.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{88AB1138-143A-4CFB-A0E6-79B646B5E1B0}</ProjectGuid>
|
||||
<Keyword>Qt4VSv1.0</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v120_xp</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v120_xp</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>11.0.61030.0</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)IntermediatePrepare\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)IntermediatePrepare\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>UNICODE;WIN32;WIN64;QT_CORE_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(QTDIR)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmaind.lib;Qt5Cored.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>UNICODE;WIN32;WIN64;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DebugInformationFormat />
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(QTDIR)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;qtmain.lib;Qt5Core.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties UicDir=".\GeneratedFiles" MocDir=".\GeneratedFiles\$(ConfigurationName)" MocOptions="" RccDir=".\GeneratedFiles" lupdateOnBuild="0" lupdateOptions="" lreleaseOptions="" Qt5Version_x0020_Win32="$(DefaultQtVersion)" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
33
Telegram/Prepare.vcxproj.filters
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;cxx;c;def</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
|
||||
<Extensions>qrc;*</Extensions>
|
||||
<ParseFiles>false</ParseFiles>
|
||||
</Filter>
|
||||
<Filter Include="Generated Files">
|
||||
<UniqueIdentifier>{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}</UniqueIdentifier>
|
||||
<Extensions>moc;h;cpp</Extensions>
|
||||
<SourceControlFiles>False</SourceControlFiles>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="SourceFiles\_other\prepare.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="SourceFiles\_other\prepare.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
379
Telegram/Resources/lang.txt
Normal file
|
@ -0,0 +1,379 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
an unofficial desktop messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://tdesktop.com
|
||||
*/
|
||||
direction: "LTR";
|
||||
|
||||
lng_maintitle: "Telegram D";
|
||||
|
||||
lng_menu_contacts: "Contacts";
|
||||
lng_menu_settings: "Settings";
|
||||
lng_menu_about: "About";
|
||||
|
||||
lng_open_from_tray: "Open Telegram";
|
||||
lng_quit_from_tray: "Quit Telegram";
|
||||
lng_tray_icon_text: "Telegram is still running here,
|
||||
you can change this from settings page.
|
||||
|
||||
If this icon disappears from tray menu,
|
||||
you can drag it back here from hidden icons.";
|
||||
|
||||
lng_month1: "January";
|
||||
lng_month2: "February";
|
||||
lng_month3: "March";
|
||||
lng_month4: "April";
|
||||
lng_month5: "May";
|
||||
lng_month6: "June";
|
||||
lng_month7: "July";
|
||||
lng_month8: "August";
|
||||
lng_month9: "September";
|
||||
lng_month10: "October";
|
||||
lng_month11: "November";
|
||||
lng_month12: "December";
|
||||
|
||||
lng_weekday1: "Mon";
|
||||
lng_weekday2: "Tue";
|
||||
lng_weekday3: "Wed";
|
||||
lng_weekday4: "Thu";
|
||||
lng_weekday5: "Fri";
|
||||
lng_weekday6: "Sat";
|
||||
lng_weekday7: "Sun";
|
||||
|
||||
lng_month_day: "{month} {day}";
|
||||
|
||||
lng_cancel: "Cancel";
|
||||
lng_continue: "Continue";
|
||||
lng_connecting: "Connecting...";
|
||||
lng_reconnecting: "Reconnect in %1 s...";
|
||||
lng_reconnecting_try_now: "Try now";
|
||||
|
||||
lng_status_offline: "offline";
|
||||
lng_status_invisible: "invisible";
|
||||
lng_status_lastseen: "last seen {when}";
|
||||
lng_status_lastseen_now: "just now";
|
||||
lng_status_lastseen_minute: "%1 minute ago";
|
||||
lng_status_lastseen_minutes: "%1 minutes ago";
|
||||
lng_status_lastseen_hour: "%1 hour ago";
|
||||
lng_status_lastseen_hours: "%1 hours ago";
|
||||
lng_status_lastseen_today: "today at {time}";
|
||||
lng_status_lastseen_yesterday: "yesterday at {time}";
|
||||
lng_status_lastseen_date: "{date}";
|
||||
lng_status_online: "online";
|
||||
|
||||
lng_chat_no_members: "Group is unaccessible";
|
||||
lng_chat_members: "%1 members";
|
||||
lng_chat_members_online: "%1 members, %2 online";
|
||||
|
||||
lng_server_error: "Internal server error.";
|
||||
lng_flood_error: "Too much tries. Please try again later.";
|
||||
lng_deleted: "Unknown";
|
||||
|
||||
lng_intro1: "Welcome to an unofficial [b]desktop[/b] client
|
||||
of [b]Telegram[/b] mobile messenger.";
|
||||
lng_intro2: "Visit [a href=\"https://telegram.org/\"]telegram.org[/a] to learn more.";
|
||||
lng_start_msgs: "Start Messaging";
|
||||
|
||||
lng_intro_back: "Back";
|
||||
lng_intro_next: "Next";
|
||||
lng_intro_finish: "Finish";
|
||||
|
||||
lng_phone_ph: "Your phone number";
|
||||
lng_phone_title: "Your Phone";
|
||||
lng_phone_desc: "Please confirm your country code and
|
||||
enter your phone number.";
|
||||
lng_phone_notreg: "Note: if you don't have a Telegram account yet,
|
||||
please [b]sign up[/b] with your [a href=\"https://telegram.org/\"]iOS / Android[/a] or {signup}here »{/signup}";
|
||||
lng_country_code: "Country Code";
|
||||
lng_bad_country_code: "Invalid Country Code";
|
||||
lng_country_ph: "Search";
|
||||
lng_country_done: "Done";
|
||||
lng_country_none: "Country not found";
|
||||
lng_country_select: "Select Country";
|
||||
|
||||
lng_code_ph: "Your code";
|
||||
lng_code_desc: "We have sent you an SMS with activation
|
||||
code to your phone. Please enter it below.";
|
||||
lng_code_call: "Telegram will dial your number in %1:%2";
|
||||
lng_code_calling: "Requesting a call from Telegram...";
|
||||
lng_code_called: "Telegram dialed your number";
|
||||
|
||||
lng_bad_phone: "Invalid phone number. Please try again.";
|
||||
lng_bad_phone_noreg: "Phone number not registered.";
|
||||
lng_bad_code: "You have entered an invalid code. Please try again.";
|
||||
lng_bad_name: "Please enter your first and last name.";
|
||||
lng_bad_chat_title: "Please enter new chat title.";
|
||||
lng_bad_photo: "Bad image selected.";
|
||||
|
||||
lng_signup_title: "Information and photo";
|
||||
lng_signup_firstname: "First Name";
|
||||
lng_signup_lastname: "Last Name";
|
||||
|
||||
lng_dlg_filter: "Search";
|
||||
lng_dlg_new_group_name: "Group name";
|
||||
lng_dlg_create_group: "Create";
|
||||
|
||||
lng_settings_profile: "Profile";
|
||||
lng_settings_edit: "Edit";
|
||||
lng_settings_save: "Save";
|
||||
lng_settings_cancel: "Cancel";
|
||||
lng_settings_upload: "Set Profile Photo";
|
||||
lng_settings_badsize: "This image has bad size, please try other.";
|
||||
lng_settings_crop_profile: "Select square area for your profile photo";
|
||||
lng_settings_uploading_photo: "Uploading photo...";
|
||||
|
||||
lng_settings_section_notify: "Notifications";
|
||||
lng_settings_desktop_notify: "Desktop notifications";
|
||||
lng_settings_sound_notify: "Sound";
|
||||
|
||||
lng_settings_section_general: "General";
|
||||
lng_settings_auto_update: "Update automatically";
|
||||
lng_settings_current_version: "Version {version}";
|
||||
lng_settings_check_now: "Check for updates";
|
||||
lng_settings_update_checking: "Checking for updates...";
|
||||
lng_settings_latest_installed: "Latest version is installed";
|
||||
lng_settings_downloading: "Downloading update {ready} / {total} Mb...";
|
||||
lng_settings_update_ready: "New version is ready";
|
||||
lng_settings_update_now: "Restart Now";
|
||||
lng_settings_update_fail: "Update check failed :(";
|
||||
lng_settings_workmode_tray: "Show tray icon";
|
||||
lng_settings_workmode_window: "Show taskbar icon";
|
||||
lng_settings_auto_start: "Launch Telegram when system starts";
|
||||
lng_settings_start_min: "Launch minimized";
|
||||
lng_settings_scale_label: "Interface scale";
|
||||
lng_settings_scale_auto: "Auto ({cur})";
|
||||
|
||||
lng_settings_section_chat: "Chat options";
|
||||
lng_settings_replace_emojis: "Replace emojis";
|
||||
lng_settings_view_emojis: "View list";
|
||||
lng_settings_emoji_list: "List of supported emojis";
|
||||
lng_settings_send_enter: "Send by Enter";
|
||||
lng_settings_send_ctrlenter: "Send by Ctrl+Enter";
|
||||
lng_settings_cats_and_dogs: "Allow cats and dogs";
|
||||
|
||||
lng_download_path_dont_ask: "Don't ask download path for each file";
|
||||
lng_download_path_label: "Download path: ";
|
||||
lng_download_path_temp: "temp folder";
|
||||
lng_download_path_clear: "Clear All";
|
||||
lng_download_path_header: "Choose download path";
|
||||
lng_download_path_temp_radio: "Temp folder, cleared on logout or uninstall";
|
||||
lng_download_path_dir_radio: "Custom folder, cleared only manually";
|
||||
lng_download_path_choose: "Choose download path";
|
||||
lng_sure_clear_downloads: "Do you want to remove all downloaded files from temp folder? It is done automatically on logout or program uninstall.";
|
||||
lng_download_path_failed: "File download could not be started. It could happen because of a bad download location.
|
||||
|
||||
You can change download path in Settings.";
|
||||
lng_download_path_settings: "Go to Settings";
|
||||
lng_download_finish_failed: "File download could not be finished.
|
||||
|
||||
Would you like to try again?";
|
||||
lng_download_path_clearing: "Clearing...";
|
||||
lng_download_path_cleared: "Cleared!";
|
||||
lng_download_path_clear_failed: "Clear failed :(";
|
||||
|
||||
lng_settings_section_advanced: "Advanced";
|
||||
lng_connection_type: "Connection type:";
|
||||
lng_connection_auto_connecting: "Default (connecting..)";
|
||||
lng_connection_auto: "Default ({type} used)";
|
||||
lng_connection_http_proxy: "HTTP with proxy";
|
||||
lng_connection_tcp_proxy: "TCP with proxy";
|
||||
lng_connection_header: "Connection type";
|
||||
lng_connection_auto_rb: "Auto (TCP if available or HTTP)";
|
||||
lng_connection_http_proxy_rb: "HTTP with custom http-proxy";
|
||||
lng_connection_tcp_proxy_rb: "TCP with custom socks5-proxy";
|
||||
lng_connection_host_ph: "Hostname";
|
||||
lng_connection_port_ph: "Port";
|
||||
lng_connection_user_ph: "Username";
|
||||
lng_connection_password_ph: "Password";
|
||||
lng_connection_save: "Save";
|
||||
lng_settings_reset: "Reset other sessions";
|
||||
lng_settings_reset_done: "Sessions reset done";
|
||||
lng_settings_logout: "Log Out";
|
||||
|
||||
lng_settings_need_restart: "You need to restart for applying
|
||||
some of the new settings. Restart now?";
|
||||
lng_settings_restart_now: "Restart";
|
||||
lng_settings_restart_later: "Later";
|
||||
|
||||
lng_profile_settings_section: "Settings";
|
||||
lng_profile_participants_section: "Participants";
|
||||
lng_profile_info: "Contact info";
|
||||
lng_profile_group_info: "Group info";
|
||||
lng_profile_add_contact: "Add Contact";
|
||||
lng_profile_edit_contact: "Edit";
|
||||
lng_profile_edit_group: "Edit";
|
||||
lng_profile_phone: "Phone number: {phone}";
|
||||
lng_profile_enable_notifications: "Notifications";
|
||||
lng_profile_clear_history: "Clear history";
|
||||
lng_profile_send_message: "Send Message";
|
||||
lng_profile_share_contact: "Share Contact";
|
||||
lng_profile_delete_contact: "Delete";
|
||||
lng_profile_set_group_photo: "Set Photo";
|
||||
lng_profile_add_participant: "Add Member";
|
||||
lng_profile_delete_and_exit: "Leave";
|
||||
lng_profile_kick: "Kick";
|
||||
lng_profile_sure_kick: "Kick {user} from the group?";
|
||||
lng_profile_loading: "Loading...";
|
||||
|
||||
lng_participant_filter: "Search";
|
||||
lng_participant_invite: "Invite";
|
||||
lng_create_new_group: "New Group";
|
||||
lng_create_group_next: "Next";
|
||||
lng_create_group_title: "New Group";
|
||||
|
||||
lng_sure_delete_contact: "Are you sure, you want to delete {contact} from your contact list?";
|
||||
lng_sure_delete_history: "Are you sure, you want to delete all message history with {contact}?
|
||||
|
||||
This action cannot be undone.";
|
||||
|
||||
lng_sure_delete_and_exit: "Are you sure, you want to delete all message history and leave «{group}»?
|
||||
|
||||
This action cannot be undone.";
|
||||
|
||||
lng_sure_enable_debug: "Do you want to enable DEBUG mode?
|
||||
|
||||
All network events will be logged.";
|
||||
|
||||
lng_message_empty: "(empty)";
|
||||
|
||||
lng_action_add_user: "{from} added {user}";
|
||||
lng_action_kick_user: "{from} kicked {user}";
|
||||
lng_action_user_left: "{from} left the group";
|
||||
lng_action_user_joined: "{from} joined the group";
|
||||
lng_action_user_photo: "{from} added a new profile photo";
|
||||
lng_action_user_registered: "{from} just joined Telegram";
|
||||
lng_action_removed_photo: "{from} removed group photo";
|
||||
lng_action_changed_photo: "{from} changed group photo";
|
||||
lng_action_changed_title: "{from} changed group name to «{title}»";
|
||||
lng_action_created_chat: "{from} created group «{title}»";
|
||||
lng_action_checked_in: "{from} checked in";
|
||||
|
||||
lng_forwarded_from: "Forwarded from ";
|
||||
|
||||
lng_attach_failed: "Failed";
|
||||
lng_attach_file: "File";
|
||||
lng_attach_photo: "Photo";
|
||||
|
||||
lng_media_open_with: "Open With";
|
||||
lng_media_download: "Download";
|
||||
lng_media_cancel: "Cancel";
|
||||
lng_media_video: "Video";
|
||||
lng_media_audio: "Audio";
|
||||
|
||||
lng_in_dlg_photo: "Photo";
|
||||
lng_in_dlg_video: "Video";
|
||||
lng_in_dlg_geo: "Map";
|
||||
lng_in_dlg_contact: "Contact";
|
||||
lng_in_dlg_audio: "Audio";
|
||||
lng_in_dlg_document: "File";
|
||||
|
||||
lng_send_button: "Send";
|
||||
lng_message_ph: "Write a message...";
|
||||
lng_empty_history: "";
|
||||
lng_willbe_history: "Please select chat to start messaging";
|
||||
lng_message_with_from: "[c]{from}:[/c] {message}";
|
||||
lng_from_you: "You";
|
||||
|
||||
lng_typing: "typing";
|
||||
lng_user_typing: "{user} is typing";
|
||||
lng_users_typing: "{user1} and {user2} are typing";
|
||||
lng_many_typing: "{n} are typing";
|
||||
lng_unread_bar: "%1 unread messages";
|
||||
|
||||
lng_maps_point: "Location";
|
||||
lng_save_photo: "Save image";
|
||||
lng_save_video: "Save video";
|
||||
lng_save_audio: "Save audio";
|
||||
lng_save_document: "Save document";
|
||||
lng_save_downloaded: "{ready} / {total} {mb}";
|
||||
lng_duration_and_size: "{duration}, {size}";
|
||||
lng_choose_images: "Choose images";
|
||||
|
||||
lng_context_open_link: "Open Link";
|
||||
lng_context_copy_link: "Copy Link";
|
||||
lng_context_open_email: "Write to this address";
|
||||
lng_context_copy_email: "Copy email address";
|
||||
lng_context_open_image: "Open Image";
|
||||
lng_context_save_image: "Save Image As...";
|
||||
lng_context_forward_image: "Forward Image";
|
||||
lng_context_delete_image: "Delete Image";
|
||||
lng_context_copy_image: "Copy Image";
|
||||
lng_context_close_image: "Close Image";
|
||||
lng_context_cancel_download: "Cancel Download";
|
||||
lng_context_show_in_folder: "Show in Folder";
|
||||
lng_context_open_video: "Open Video";
|
||||
lng_context_save_video: "Save Video As...";
|
||||
lng_context_open_audio: "Open Audio";
|
||||
lng_context_save_audio: "Save Audio As...";
|
||||
lng_context_open_document: "Open File";
|
||||
lng_context_save_document: "Save File As...";
|
||||
lng_context_copy_text: "Copy Message Text";
|
||||
lng_context_forward_msg: "Forward Message";
|
||||
lng_context_delete_msg: "Delete Message";
|
||||
lng_context_cancel_upload: "Cancel Upload";
|
||||
lng_context_copy_selected: "Copy Selected Text";
|
||||
lng_context_forward_selected: "Forward Selected";
|
||||
lng_context_delete_selected: "Delete Selected";
|
||||
lng_context_clear_selection: "Clear Selection";
|
||||
lng_really_send_image: "Do you want to send this image?";
|
||||
|
||||
lng_forward_choose: "Choose recipient...";
|
||||
lng_forward_confirm: "Forward to {recipient}?";
|
||||
lng_forward_share_contact: "Share contact to {recipient}?";
|
||||
lng_forward: "Forward";
|
||||
|
||||
lng_contact_phone: "Phone number";
|
||||
lng_enter_contact_data: "New Contact";
|
||||
lng_edit_group_title: "Edit group name";
|
||||
lng_edit_contact_title: "Edit contact name";
|
||||
lng_edit_self_title: "Edit your name";
|
||||
lng_confirm_contact_data: "New Contact";
|
||||
lng_add_contact: "Create";
|
||||
lng_add_contact_button: "Add Contact";
|
||||
lng_contacts_header: "Contacts";
|
||||
lng_contact_not_joined: "Unfortunately {name} did not join Telegram yet, but you can send your friend an invitation.
|
||||
|
||||
We will notify you about any of your contacts who is joining Telegram.";
|
||||
lng_try_other_contact: "Try other";
|
||||
lng_contacts_done: "Cancel";
|
||||
|
||||
lng_drag_images_here: "Drop images here";
|
||||
lng_drag_photos_here: "Drop photos here";
|
||||
lng_drag_files_here: "Drop files here";
|
||||
|
||||
lng_drag_to_send_quick: "to send them in a quick way";
|
||||
lng_drag_to_send_no_compression: "to send them without compression";
|
||||
lng_drag_to_send_documents: "to send them as documents";
|
||||
|
||||
lng_selected_clear: "Cancel";
|
||||
lng_selected_delete: "Delete";
|
||||
lng_selected_forward: "Forward";
|
||||
lng_selected_count_1: "%1 message";
|
||||
lng_selected_count_5: "%1 messages";
|
||||
lng_selected_cancel_sure_this: "Do you want to cancel this upload?";
|
||||
lng_selected_delete_sure_this: "Do you want to delete this message?";
|
||||
lng_selected_delete_sure_1: "Do you want to delete %1 message?";
|
||||
lng_selected_delete_sure_5: "Do you want to delete %1 messages?";
|
||||
lng_selected_delete_confirm: "Delete";
|
||||
|
||||
lng_emoji_no_recent: "Recent emojis will be here";
|
||||
|
||||
lng_about_version: "Version {version}";
|
||||
lng_about_text: "Unofficial free messaging app based on [a href=\"https://core.telegram.org/mtproto\"]MTProto[/a] and
|
||||
[a href=\"https://core.telegram.org/api\"]Telegram API[/a] for speed and security
|
||||
|
||||
This software is licensed under [a href=\"https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE\"]GNU GPL[/a] version 3,
|
||||
source code is available on [a href=\"https://github.com/telegramdesktop/tdesktop\"]GitHub[/a].";
|
||||
lng_about_done: "Done";
|
1388
Telegram/Resources/style.txt
Normal file
231
Telegram/Resources/style_classes.txt
Normal file
|
@ -0,0 +1,231 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
an unofficial desktop messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://tdesktop.com
|
||||
*/
|
||||
textStyle {
|
||||
lnkFlags: font;
|
||||
lnkOverFlags: font;
|
||||
lnkColor: color;
|
||||
lnkDownColor: color;
|
||||
selectBG: color;
|
||||
selectOverlay: color;
|
||||
lineHeight: number;
|
||||
}
|
||||
|
||||
linkButton {
|
||||
color: color;
|
||||
overColor: color;
|
||||
downColor: color;
|
||||
font: font;
|
||||
overFont: font;
|
||||
}
|
||||
|
||||
sysButton {
|
||||
size: size;
|
||||
img: sprite;
|
||||
color: color;
|
||||
overColor: color;
|
||||
duration: number;
|
||||
}
|
||||
|
||||
flatButton {
|
||||
color: color;
|
||||
overColor: color;
|
||||
downColor: color;
|
||||
|
||||
bgColor: color;
|
||||
overBgColor: color;
|
||||
downBgColor: color;
|
||||
|
||||
width: number;
|
||||
height: number;
|
||||
|
||||
textTop: number;
|
||||
overTextTop: number;
|
||||
downTextTop: number;
|
||||
|
||||
font: font;
|
||||
overFont: font;
|
||||
duration: number;
|
||||
cursor: cursor;
|
||||
}
|
||||
|
||||
iconedButton {
|
||||
icon: sprite;
|
||||
iconPos: point;
|
||||
downIcon: sprite;
|
||||
downIconPos: point;
|
||||
|
||||
color: color;
|
||||
bgColor: color;
|
||||
overBgColor: color;
|
||||
width: number;
|
||||
height: number;
|
||||
font: font;
|
||||
|
||||
opacity: number;
|
||||
overOpacity: number;
|
||||
|
||||
textPos: point;
|
||||
downTextPos: point;
|
||||
|
||||
duration: number;
|
||||
cursor: cursor;
|
||||
}
|
||||
|
||||
flatCheckbox {
|
||||
textColor: color;
|
||||
bgColor: color;
|
||||
disColor: color;
|
||||
|
||||
width: number;
|
||||
height: number;
|
||||
textTop: number;
|
||||
textLeft: number;
|
||||
font: font;
|
||||
duration: number;
|
||||
bgFunc: transition;
|
||||
cursor: cursor;
|
||||
|
||||
disabledCursor: cursor;
|
||||
|
||||
imageRect: sprite;
|
||||
chkImageRect: sprite;
|
||||
overImageRect: sprite;
|
||||
chkOverImageRect: sprite;
|
||||
disImageRect: sprite;
|
||||
chkDisImageRect: sprite;
|
||||
|
||||
imagePos: point;
|
||||
}
|
||||
|
||||
flatInput {
|
||||
textColor: color;
|
||||
bgColor: color;
|
||||
bgActive: color;
|
||||
width: number;
|
||||
height: number;
|
||||
textMrg: margins;
|
||||
align: align;
|
||||
font: font;
|
||||
cursor: cursor;
|
||||
|
||||
imgRect: sprite;
|
||||
imgPos: point;
|
||||
|
||||
borderWidth: number;
|
||||
borderColor: color;
|
||||
borderActive: color;
|
||||
borderError: color;
|
||||
|
||||
phColor: color;
|
||||
phFocusColor: color;
|
||||
phPos: point;
|
||||
phAlign: align;
|
||||
phShift: number;
|
||||
phDuration: number;
|
||||
phLeftFunc: transition;
|
||||
phAlphaFunc: transition;
|
||||
phColorFunc: transition;
|
||||
}
|
||||
|
||||
flatTextarea {
|
||||
textColor: color;
|
||||
bgColor: color;
|
||||
width: number;
|
||||
textMrg: margins;
|
||||
align: align;
|
||||
font: font;
|
||||
cursor: cursor;
|
||||
|
||||
phColor: color;
|
||||
phFocusColor: color;
|
||||
phPos: point;
|
||||
phAlign: align;
|
||||
phShift: number;
|
||||
phDuration: number;
|
||||
phLeftFunc: transition;
|
||||
phAlphaFunc: transition;
|
||||
phColorFunc: transition;
|
||||
}
|
||||
|
||||
flatScroll {
|
||||
barColor: color;
|
||||
bgColor: color;
|
||||
barOverColor: color;
|
||||
bgOverColor: color;
|
||||
|
||||
round: number;
|
||||
|
||||
width: number;
|
||||
minHeight: number;
|
||||
deltax: number;
|
||||
deltay: number;
|
||||
|
||||
topsh: number;
|
||||
bottomsh: number;
|
||||
shColor: color;
|
||||
|
||||
duration: number;
|
||||
hiding: number;
|
||||
}
|
||||
|
||||
countryInput {
|
||||
width: number;
|
||||
height: number;
|
||||
top: number;
|
||||
bgColor: color;
|
||||
ptrSize: size;
|
||||
textMrg: margins;
|
||||
font: font;
|
||||
align: align;
|
||||
}
|
||||
|
||||
countryList {
|
||||
notFoundColor: color;
|
||||
notFoundFont: font;
|
||||
|
||||
verticalMargin: number;
|
||||
|
||||
font: font;
|
||||
codeFont: font;
|
||||
rowHeight: number;
|
||||
color: color;
|
||||
codeColor: color;
|
||||
bgColor: color;
|
||||
bgHovered: color;
|
||||
margin: number;
|
||||
codeWidth: number;
|
||||
|
||||
borderMargin: number;
|
||||
borderColor: color;
|
||||
borderWidth: number;
|
||||
}
|
||||
|
||||
slider {
|
||||
color: color;
|
||||
thikness: number;
|
||||
|
||||
width: number;
|
||||
bar: sprite;
|
||||
}
|
||||
|
||||
flatLabel {
|
||||
font: font;
|
||||
minWidth: number;
|
||||
width: number;
|
||||
align: align;
|
||||
}
|
116
Telegram/Setup.iss
Normal file
|
@ -0,0 +1,116 @@
|
|||
; Script generated by the Inno Setup Script Wizard.
|
||||
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
|
||||
|
||||
#define MyAppShortName "Telegram"
|
||||
#define MyAppName "Telegram Win (Unofficial)"
|
||||
#define MyAppVersion "0.4.18"
|
||||
#define MyAppVersionZero "0.4.18"
|
||||
#define MyAppFullVersion "0.4.18.0"
|
||||
#define MyAppPublisher "Telegram (Unofficial)"
|
||||
#define MyAppURL "https://tdesktop.com"
|
||||
#define MyAppExeName "Telegram.exe"
|
||||
#define MyAppId "53F49750-6209-4FBF-9CA8-7A333C87D1ED"
|
||||
|
||||
[Setup]
|
||||
; NOTE: The value of AppId uniquely identifies this application.
|
||||
; Do not use the same AppId value in installers for other applications.
|
||||
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
|
||||
AppId={{{#MyAppId}}
|
||||
AppName={#MyAppName}
|
||||
AppVersion={#MyAppVersion}
|
||||
;AppVerName={#MyAppName} {#MyAppVersion}
|
||||
AppPublisher={#MyAppPublisher}
|
||||
AppPublisherURL={#MyAppURL}
|
||||
AppSupportURL={#MyAppURL}
|
||||
AppUpdatesURL={#MyAppURL}
|
||||
DefaultDirName={userappdata}\{#MyAppName}
|
||||
DefaultGroupName={#MyAppName}
|
||||
AllowNoIcons=yes
|
||||
OutputDir=.\..\Win32\Release
|
||||
OutputBaseFilename=tsetup.{#MyAppVersionZero}
|
||||
SetupIconFile=.\SourceFiles\art\iconround256.ico
|
||||
UninstallDisplayIcon={app}\Telegram.exe
|
||||
Compression=lzma
|
||||
SolidCompression=yes
|
||||
DisableStartupPrompt=yes
|
||||
PrivilegesRequired=lowest
|
||||
VersionInfoVersion={#MyAppFullVersion}
|
||||
|
||||
[Languages]
|
||||
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||
|
||||
[Tasks]
|
||||
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"
|
||||
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; OnlyBelowVersion: 0,6.1
|
||||
|
||||
[Files]
|
||||
Source: ".\..\Win32\Release\Telegram.exe"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: ".\..\Win32\Release\Updater.exe"; DestDir: "{app}"; Flags: ignoreversion
|
||||
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
|
||||
|
||||
[Icons]
|
||||
Name: "{group}\{#MyAppShortName}"; Filename: "{app}\{#MyAppExeName}"
|
||||
Name: "{group}\{cm:UninstallProgram,{#MyAppShortName}}"; Filename: "{uninstallexe}"
|
||||
Name: "{userdesktop}\{#MyAppShortName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
|
||||
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppShortName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: quicklaunchicon
|
||||
|
||||
[Run]
|
||||
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppShortName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
|
||||
|
||||
[UninstallDelete]
|
||||
Type: files; Name: "{app}\data"
|
||||
Type: files; Name: "{app}\data_config"
|
||||
Type: files; Name: "{app}\log.txt"
|
||||
Type: filesandordirs; Name: "{app}\DebugLogs"
|
||||
Type: filesandordirs; Name: "{app}\tupdates"
|
||||
Type: filesandordirs; Name: "{app}\tdata"
|
||||
Type: filesandordirs; Name: "{app}\tdumps"
|
||||
Type: dirifempty; Name: "{app}"
|
||||
Type: files; Name: "{userappdata}\{#MyAppName}\data"
|
||||
Type: files; Name: "{userappdata}\{#MyAppName}\data_config"
|
||||
Type: files; Name: "{userappdata}\{#MyAppName}\log.txt"
|
||||
Type: filesandordirs; Name: "{userappdata}\{#MyAppName}\DebugLogs"
|
||||
Type: filesandordirs; Name: "{userappdata}\{#MyAppName}\tupdates"
|
||||
Type: filesandordirs; Name: "{userappdata}\{#MyAppName}\tdata"
|
||||
Type: filesandordirs; Name: "{userappdata}\{#MyAppName}\tdumps"
|
||||
Type: dirifempty; Name: "{userappdata}\{#MyAppName}"
|
||||
|
||||
[Code]
|
||||
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
|
||||
var ResultCode: Integer;
|
||||
begin
|
||||
if CurUninstallStep = usUninstall then
|
||||
begin
|
||||
ShellExec('', ExpandConstant('{app}\{#MyAppExeName}'), '-cleanup', '', SW_SHOW, ewWaitUntilTerminated, ResultCode);
|
||||
end;
|
||||
end;
|
||||
|
||||
const CSIDL_DESKTOPDIRECTORY = $0010;
|
||||
CSIDL_COMMON_DESKTOPDIRECTORY = $0019;
|
||||
|
||||
procedure CurStepChanged(CurStep: TSetupStep);
|
||||
var ResultCode: Integer;
|
||||
HasOldKey: Boolean;
|
||||
HasNewKey: Boolean;
|
||||
HasOldLnk: Boolean;
|
||||
HasNewLnk: Boolean;
|
||||
UserDesktopLnk: String;
|
||||
CommonDesktopLnk: String;
|
||||
begin
|
||||
if CurStep = ssPostInstall then
|
||||
begin
|
||||
HasNewKey := RegKeyExists(HKEY_CURRENT_USER, 'Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{{#MyAppId}}_is1') or RegKeyExists(HKEY_CURRENT_USER, 'Software\Microsoft\Windows\CurrentVersion\Uninstall\{{#MyAppId}}_is1');
|
||||
HasOldKey := RegKeyExists(HKEY_LOCAL_MACHINE, 'SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{{#MyAppId}}_is1') or RegKeyExists(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{{#MyAppId}}_is1');
|
||||
UserDesktopLnk := ExpandFileName(GetShellFolderByCSIDL(CSIDL_DESKTOPDIRECTORY, False) + '\{#MyAppShortName}.lnk');
|
||||
CommonDesktopLnk := ExpandFileName(GetShellFolderByCSIDL(CSIDL_COMMON_DESKTOPDIRECTORY, False) + '\{#MyAppShortName}.lnk');
|
||||
HasNewLnk := FileExists(UserDesktopLnk);
|
||||
HasOldLnk := FileExists(CommonDesktopLnk) and (UserDesktopLnk <> CommonDesktopLnk);
|
||||
if (HasOldKey and HasNewKey) or (HasOldLnk and HasNewLnk) then
|
||||
begin
|
||||
if (GetWindowsVersion >= $06000000) then // Vista or later
|
||||
ShellExec('runas', ExpandConstant('{app}\{#MyAppExeName}'), '-fixprevious', '', SW_SHOW, ewWaitUntilTerminated, ResultCode)
|
||||
else
|
||||
ShellExec('', ExpandConstant('{app}\{#MyAppExeName}'), '-fixprevious', '', SW_SHOW, ewWaitUntilTerminated, ResultCode);
|
||||
end;
|
||||
end;
|
||||
end;
|
0
Telegram/SetupFiles/data
Normal file
0
Telegram/SetupFiles/log.txt
Normal file
1280
Telegram/SourceFiles/_other/genemoji.cpp
Normal file
63
Telegram/SourceFiles/_other/genemoji.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
an unofficial desktop messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://tdesktop.com
|
||||
*/
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QVector>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QBuffer>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QRegularExpression>
|
||||
#include <QtGui/QImage>
|
||||
#include <QtGui/QPixmap>
|
||||
#include <QtGui/QPainter>
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <QtCore/QTextStream>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtGui/QGuiApplication>
|
||||
|
||||
using std::string;
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::exception;
|
||||
|
||||
bool genEmoji(QString emoji_in, const QString &emoji_out);
|
||||
|
||||
class GenEmoji : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GenEmoji(const QString &emoji_in, const QString &emoji_out) : QObject(0),
|
||||
_emoji_in(emoji_in), _emoji_out(emoji_out) {
|
||||
}
|
||||
|
||||
public slots :
|
||||
void run() {
|
||||
if (genEmoji(_emoji_in, _emoji_out)) {
|
||||
emit finished();
|
||||
}
|
||||
}
|
||||
|
||||
signals:
|
||||
void finished();
|
||||
|
||||
private:
|
||||
|
||||
QString _emoji_in, _emoji_out;
|
||||
};
|
454
Telegram/SourceFiles/_other/genlang.cpp
Normal file
|
@ -0,0 +1,454 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
an unofficial desktop messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://tdesktop.com
|
||||
*/
|
||||
#include "genlang.h"
|
||||
|
||||
#include <QtCore/QtPlugin>
|
||||
Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)
|
||||
|
||||
typedef unsigned int uint32;
|
||||
|
||||
QString layoutDirection;
|
||||
typedef QMap<QString, QString> LangKeys;
|
||||
LangKeys keys;
|
||||
typedef QVector<QString> KeysOrder;
|
||||
KeysOrder keysOrder;
|
||||
|
||||
bool skipWhitespaces(const char *&from, const char *end) {
|
||||
while (from < end && (*from == ' ' || *from == '\n' || *from == '\t' || *from == '\r')) {
|
||||
++from;
|
||||
}
|
||||
return (from < end);
|
||||
}
|
||||
|
||||
bool skipComment(const char *&from, const char *end) {
|
||||
if (from >= end) return false;
|
||||
if (*from == '/') {
|
||||
if (from + 1 >= end) return true;
|
||||
if (*(from + 1) == '*') {
|
||||
from += 2;
|
||||
while (from + 1 < end && (*from != '*' || *(from + 1) != '/')) {
|
||||
++from;
|
||||
}
|
||||
from += 2;
|
||||
return (from < end);
|
||||
} else if (*(from + 1) == '/') {
|
||||
from += 2;
|
||||
while (from < end && *from != '\n' && *from != '\r') {
|
||||
++from;
|
||||
}
|
||||
++from;
|
||||
return (from < end);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool skipJunk(const char *&from, const char *end) {
|
||||
const char *start;
|
||||
do {
|
||||
start = from;
|
||||
if (!skipWhitespaces(from, end)) return false;
|
||||
if (!skipComment(from, end)) throw exception("Unexpected end of comment!");
|
||||
} while (start != from);
|
||||
return true;
|
||||
}
|
||||
|
||||
void readKeyValue(const char *&from, const char *end) {
|
||||
if (!skipJunk(from, end)) return;
|
||||
|
||||
const char *nameStart = from;
|
||||
while (from < end && (*from >= 'a' && *from <= 'z' || *from >= 'A' && *from <= 'Z' || *from == '_' || *from >= '0' && *from <= '9')) {
|
||||
++from;
|
||||
}
|
||||
|
||||
QString varName = QString::fromUtf8(nameStart, from - nameStart);
|
||||
|
||||
if (!skipJunk(from, end)) throw exception("Unexpected end of file!");
|
||||
if (*from != ':') throw exception(QString("':' expected after '%1'").arg(varName).toUtf8().constData());
|
||||
|
||||
if (!skipJunk(++from, end)) throw exception("Unexpected end of file!");
|
||||
if (*from != '"') throw exception(QString("Expected string after '%1:'").arg(varName).toUtf8().constData());
|
||||
|
||||
QByteArray varValue;
|
||||
const char *start = ++from;
|
||||
while (from < end && *from != '"') {
|
||||
if (*from == '\\') {
|
||||
if (from + 1 >= end) throw exception("Unexpected end of file!");
|
||||
if (*(from + 1) == '"' || *(from + 1) == '\\') {
|
||||
if (from > start) varValue.append(start, from - start);
|
||||
start = ++from;
|
||||
}
|
||||
}
|
||||
++from;
|
||||
}
|
||||
if (from >= end) throw exception("Unexpected end of file!");
|
||||
if (from > start) varValue.append(start, from - start);
|
||||
|
||||
if (!skipJunk(++from, end)) throw exception("Unexpected end of file!");
|
||||
if (*from != ';') throw exception(QString("';' expected after '%1: \"value\"'").arg(varName).toUtf8().constData());
|
||||
|
||||
skipJunk(++from, end);
|
||||
|
||||
if (varName == "direction") {
|
||||
if (varValue == "LTR" || varValue == "RTL") {
|
||||
layoutDirection = QString::fromUtf8(varValue);
|
||||
} else {
|
||||
throw exception(QString("Unexpected value for 'direction' key: '%1'").arg(QString::fromUtf8(varValue)).toUtf8().constData());
|
||||
}
|
||||
} else if (varName.midRef(0, 4) != "lng_") {
|
||||
throw exception(QString("Bad key '%1'").arg(varName).toUtf8().constData());
|
||||
} else if (keys.constFind(varName) != keys.cend()) {
|
||||
throw exception(QString("Key doubled '%1'").arg(varName).toUtf8().constData());
|
||||
} else {
|
||||
keys.insert(varName, QString::fromUtf8(varValue));
|
||||
keysOrder.push_back(varName);
|
||||
}
|
||||
}
|
||||
|
||||
QString escapeCpp(const QString &key, QString value, bool wideChar) {
|
||||
if (value.isEmpty()) return "QString()";
|
||||
value = value.replace('\\', "\\\\").replace('\n', "\\n").replace('\r', "").replace('"', "\\\"");
|
||||
QString res;
|
||||
res.reserve(value.size() * 10);
|
||||
bool instr = false;
|
||||
for (const QChar *ch = value.constData(), *e = value.constData() + value.size(); ch != e; ++ch) {
|
||||
if (ch->unicode() < 32) {
|
||||
throw exception(QString("Bad value for key '%1'").arg(key).toUtf8().constData());
|
||||
} else if (ch->unicode() > 127) {
|
||||
if (instr) {
|
||||
res.append('"');
|
||||
instr = false;
|
||||
}
|
||||
res.append(' ');
|
||||
if (wideChar) {
|
||||
res.append('L').append('"').append('\\').append('x').append(QString("%1").arg(ch->unicode(), 4, 16, QChar('0'))).append('"');
|
||||
} else {
|
||||
res.append('"');
|
||||
QByteArray utf(QString(*ch).toUtf8());
|
||||
for (const unsigned char *uch = (const unsigned char *)utf.constData(), *ue = (const unsigned char *)utf.constData() + utf.size(); uch != ue; ++uch) {
|
||||
res.append('\\').append('x').append(QString("%1").arg(ushort(*uch), 2, 16, QChar('0')));
|
||||
}
|
||||
res.append('"');
|
||||
}
|
||||
} else {
|
||||
if (!instr) {
|
||||
res.append(' ');
|
||||
if (wideChar) res.append('L');
|
||||
res.append('"');
|
||||
instr = true;
|
||||
}
|
||||
res.append(*ch);
|
||||
}
|
||||
}
|
||||
if (instr) res.append('"');
|
||||
return (wideChar ? "qsl(" : "QString::fromUtf8(") + res.mid(wideChar ? 2 : 1) + ")";
|
||||
}
|
||||
|
||||
void writeCppKey(QTextStream &tcpp, const QString &key, const QString &val) {
|
||||
QString wide = escapeCpp(key, val, true), utf = escapeCpp(key, val, false);
|
||||
if (wide.indexOf(" L\"") < 0) {
|
||||
tcpp << "\t\t\tset(" << key << ", " << wide << ");\n";
|
||||
} else {
|
||||
tcpp << "#ifdef Q_OS_WIN\n";
|
||||
tcpp << "\t\t\tset(" << key << ", " << wide << ");\n";
|
||||
tcpp << "#else\n";
|
||||
tcpp << "\t\t\tset(" << key << ", " << utf << ");\n";
|
||||
tcpp << "#endif\n";
|
||||
}
|
||||
}
|
||||
|
||||
bool genLang(const QString &lang_in, const QString &lang_out) {
|
||||
QString lang_cpp = lang_out + ".cpp", lang_h = lang_out + ".h";
|
||||
QFile f(lang_in);
|
||||
if (!f.open(QIODevice::ReadOnly)) {
|
||||
cout << "Could not open styles input file '" << lang_in.toUtf8().constData() << "'!\n";
|
||||
QCoreApplication::exit(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray blob = f.readAll();
|
||||
const char *text = blob.constData(), *end = blob.constData() + blob.size();
|
||||
f.close();
|
||||
|
||||
try {
|
||||
while (text != end) {
|
||||
readKeyValue(text, end);
|
||||
}
|
||||
|
||||
QByteArray cppText, hText;
|
||||
{
|
||||
QTextStream tcpp(&cppText), th(&hText);
|
||||
tcpp.setCodec("ISO 8859-1");
|
||||
th.setCodec("ISO 8859-1");
|
||||
th << "\
|
||||
/*\n\
|
||||
Created from \'/Resources/lang.txt\' by \'/MetaLang\' project\n\
|
||||
\n\
|
||||
WARNING! All changes made in this file will be lost!\n\
|
||||
\n\
|
||||
This file is part of Telegram Desktop,\n\
|
||||
an unofficial desktop messaging app, see https://telegram.org\n\
|
||||
\n\
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify\n\
|
||||
it under the terms of the GNU General Public License as published by\n\
|
||||
the Free Software Foundation, either version 3 of the License, or\n\
|
||||
(at your option) any later version.\n\
|
||||
\n\
|
||||
It is distributed in the hope that it will be useful,\n\
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\
|
||||
GNU General Public License for more details.\n\
|
||||
\n\
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE\n\
|
||||
Copyright (c) 2014 John Preston, https://tdesktop.com\n\
|
||||
*/\n";
|
||||
th << "#pragma once\n\n";
|
||||
th << "enum LangKey {\n";
|
||||
for (int i = 0, l = keysOrder.size(); i < l; ++i) {
|
||||
th << "\t" << keysOrder[i] << (i ? "" : " = 0") << ",\n";
|
||||
}
|
||||
th << "\n\tlng_keys_cnt\n";
|
||||
th << "};\n\n";
|
||||
th << "QString lang(LangKey key);\n";
|
||||
th << "inline QString langDayOfMonth(const QDate &date) {\n";
|
||||
th << "\tint32 month = date.month(), day = date.day();\n";
|
||||
th << "\treturn (month > 0 && month <= 12) ? lang(lng_month_day).replace(qsl(\"{month}\"), lang(LangKey(lng_month1 + month - 1))).replace(qsl(\"{day}\"), QString::number(day)) : qsl(\"{err}\");\n";
|
||||
th << "}\n\n";
|
||||
th << "inline QString langDayOfWeek(const QDate &date) {\n";
|
||||
th << "\tint32 day = date.dayOfWeek();\n";
|
||||
th << "\treturn (day > 0 && day <= 7) ? lang(LangKey(lng_weekday1 + day - 1)) : qsl(\"{err}\");\n";
|
||||
th << "}\n\n";
|
||||
th << "Qt::LayoutDirection langDir();\n\n";
|
||||
th << "class LangLoader {\n";
|
||||
th << "public:\n";
|
||||
th << "\tconst QString &errors() const;\n";
|
||||
th << "\tconst QString &warnings() const;\n\n";
|
||||
th << "protected:\n";
|
||||
th << "\tLangLoader() : _checked(false) {\n";
|
||||
th << "\t\tmemset(_found, 0, sizeof(_found));\n";
|
||||
th << "\t}\n\n";
|
||||
th << "\tbool feedKeyValue(const QString &key, const QString &value);\n\n";
|
||||
th << "\tvoid error(const QString &text) {\n";
|
||||
th << "\t\t_err.push_back(text);\n";
|
||||
th << "\t}\n";
|
||||
th << "\tvoid warning(const QString &text) {\n";
|
||||
th << "\t\t_warn.push_back(text);\n";
|
||||
th << "\t}\n\n";
|
||||
th << "private:\n";
|
||||
th << "\tmutable QStringList _err, _warn;\n";
|
||||
th << "\tmutable QString _errors, _warnings;\n";
|
||||
th << "\tmutable bool _checked;\n";
|
||||
th << "\tbool _found[lng_keys_cnt];\n\n";
|
||||
th << "\tLangLoader(const LangLoader &);\n";
|
||||
th << "\tLangLoader &operator=(const LangLoader &);\n";
|
||||
th << "};\n";
|
||||
|
||||
tcpp << "\
|
||||
/*\n\
|
||||
Created from \'/Resources/lang.txt\' by \'/MetaLang\' project\n\
|
||||
\n\
|
||||
WARNING! All changes made in this file will be lost!\n\
|
||||
\n\
|
||||
This file is part of Telegram Desktop,\n\
|
||||
an unofficial desktop messaging app, see https://telegram.org\n\
|
||||
\n\
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify\n\
|
||||
it under the terms of the GNU General Public License as published by\n\
|
||||
the Free Software Foundation, either version 3 of the License, or\n\
|
||||
(at your option) any later version.\n\
|
||||
\n\
|
||||
It is distributed in the hope that it will be useful,\n\
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\
|
||||
GNU General Public License for more details.\n\
|
||||
\n\
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE\n\
|
||||
Copyright (c) 2014 John Preston, https://tdesktop.com\n\
|
||||
*/\n";
|
||||
tcpp << "#include \"stdafx.h\"\n#include \"lang.h\"\n\n";
|
||||
tcpp << "namespace {\n";
|
||||
tcpp << "\tQt::LayoutDirection _langDir = Qt::" << (layoutDirection == "LTR" ? "LeftToRight" : "RightToLeft") << ";\n";
|
||||
tcpp << "\tconst char *_langKeyNames[lng_keys_cnt + 1] = {\n";
|
||||
for (int i = 0, l = keysOrder.size(); i < l; ++i) {
|
||||
tcpp << "\t\t\"" << keysOrder[i] << "\",\n";
|
||||
}
|
||||
tcpp << "\t\t\"lng_keys_cnt\"\n";
|
||||
tcpp << "\t};\n\n";
|
||||
tcpp << "\tQString _langValues[lng_keys_cnt + 1];\n\n";
|
||||
tcpp << "\tvoid set(LangKey key, const QString &val) {\n";
|
||||
tcpp << "\t\t_langValues[key] = val;\n";
|
||||
tcpp << "\t}\n\n";
|
||||
tcpp << "\tclass LangInit {\n";
|
||||
tcpp << "\tpublic:\n";
|
||||
tcpp << "\t\tLangInit() {\n";
|
||||
for (int i = 0, l = keysOrder.size(); i < l; ++i) {
|
||||
writeCppKey(tcpp, keysOrder[i], keys[keysOrder[i]]);
|
||||
}
|
||||
tcpp << "\t\t\tset(lng_keys_cnt, QString());\n";
|
||||
tcpp << "\t\t}\n";
|
||||
tcpp << "\t};\n\n";
|
||||
tcpp << "\tLangInit _langInit;\n";
|
||||
tcpp << "}\n\n";
|
||||
|
||||
tcpp << "QString lang(LangKey key) {\n";
|
||||
tcpp << "\treturn _langValues[(key < 0 || key > lng_keys_cnt) ? lng_keys_cnt : key];\n";
|
||||
tcpp << "}\n\n";
|
||||
|
||||
tcpp << "Qt::LayoutDirection langDir() {\n";
|
||||
tcpp << "\treturn _langDir;\n";
|
||||
tcpp << "}\n\n";
|
||||
|
||||
tcpp << "bool LangLoader::feedKeyValue(const QString &key, const QString &value) {\n";
|
||||
tcpp << "\tif (key == qsl(\"direction\")) {\n";
|
||||
tcpp << "\t\tif (value == qsl(\"LTR\")) {\n";
|
||||
tcpp << "\t\t\t_langDir = Qt::LeftToRight;\n";
|
||||
tcpp << "\t\t\treturn true;\n";
|
||||
tcpp << "\t\t} else if (value == qsl(\"RTL\")) {\n";
|
||||
tcpp << "\t\t\t_langDir = Qt::RightToLeft;\n";
|
||||
tcpp << "\t\t\treturn true;\n";
|
||||
tcpp << "\t\t} else {\n";
|
||||
tcpp << "\t\t\t_err.push_back(qsl(\"Bad value for 'direction' key.\"));\n";
|
||||
tcpp << "\t\t\treturn false;\n";
|
||||
tcpp << "\t\t}\n";
|
||||
tcpp << "\t}\n";
|
||||
tcpp << "\tif (key.size() < 5 || key.midRef(0, 4) != qsl(\"lng_\")) {\n";
|
||||
tcpp << "\t\t_err.push_back(qsl(\"Bad key name '%1'\").arg(key));\n";
|
||||
tcpp << "\t\treturn false;\n";
|
||||
tcpp << "\t}\n\n";
|
||||
if (!keys.isEmpty()) {
|
||||
QString tab("\t");
|
||||
tcpp << "\tLangKey keyIndex = lng_keys_cnt;\n";
|
||||
tcpp << "\tconst QChar *ch = key.constData(), *e = key.constData() + key.size();\n";
|
||||
QString current("lng_");
|
||||
int depth = current.size();
|
||||
tcpp << "\tswitch ((ch + " << depth << ")->unicode()) {\n";
|
||||
for (LangKeys::const_iterator i = keys.cbegin(), j = i + 1, e = keys.cend(); i != e; ++i) {
|
||||
QString key = i.key();
|
||||
while (key.midRef(0, depth) != current) {
|
||||
tcpp << tab.repeated(depth - 3) << "}\n";
|
||||
current.chop(1);
|
||||
--depth;
|
||||
tcpp << tab.repeated(depth - 3) << "break;\n";
|
||||
}
|
||||
do {
|
||||
if (key == current) break;
|
||||
|
||||
QChar ich = i.key().at(current.size());
|
||||
tcpp << tab.repeated(current.size() - 3) << "case '" << ich << "':\n";
|
||||
if (j == e || ich != ((j.key().size() > depth) ? j.key().at(depth) : 0)) {
|
||||
if (key == current + ich) {
|
||||
tcpp << tab.repeated(depth - 3) << "\tif (ch + " << (depth + 1) << " == e) keyIndex = " << key << ";\n";
|
||||
} else {
|
||||
tcpp << tab.repeated(depth - 3) << "\tif (key.midRef(" << (depth + 1) << ") == qsl(\"" << i.key().mid(depth + 1) << "\")) keyIndex = " << key << ";\n";
|
||||
}
|
||||
tcpp << tab.repeated(depth - 3) << "break;\n";
|
||||
break;
|
||||
}
|
||||
|
||||
++depth;
|
||||
current += ich;
|
||||
|
||||
if (key == current) {
|
||||
tcpp << tab.repeated(depth - 3) << "if (ch + " << depth << " == e) {\n";
|
||||
tcpp << tab.repeated(depth - 3) << "\tkeyIndex = " << key << ";\n";
|
||||
tcpp << tab.repeated(depth - 3) << "}\n";
|
||||
}
|
||||
|
||||
tcpp << tab.repeated(depth - 3) << "if (ch + " << depth << " < e) switch ((ch + " << depth << ")->unicode()) {\n";
|
||||
} while (true);
|
||||
++j;
|
||||
}
|
||||
while (QString("lng_") != current) {
|
||||
tcpp << tab.repeated(depth - 3) << "}\n";
|
||||
current.chop(1);
|
||||
--depth;
|
||||
tcpp << tab.repeated(depth - 3) << "break;\n";
|
||||
}
|
||||
tcpp << "\t}\n\n";
|
||||
tcpp << "\tif (keyIndex < lng_keys_cnt) {\n";
|
||||
tcpp << "\t\t_found[keyIndex] = 1;\n";
|
||||
tcpp << "\t\t_langValues[keyIndex] = value;\n";
|
||||
tcpp << "\t\treturn true;\n";
|
||||
tcpp << "\t}\n\n";
|
||||
}
|
||||
tcpp << "\t_err.push_back(qsl(\"Unknown key name '%1'\").arg(key));\n";
|
||||
tcpp << "\treturn false;\n";
|
||||
tcpp << "}\n\n";
|
||||
|
||||
tcpp << "const QString &LangLoader::errors() const {\n";
|
||||
tcpp << "\tif (_errors.isEmpty() && !_err.isEmpty()) {\n";
|
||||
tcpp << "\t\t_errors = _err.join('\\n');\n";
|
||||
tcpp << "\t}\n";
|
||||
tcpp << "\treturn _errors;\n";
|
||||
tcpp << "}\n\n";
|
||||
|
||||
tcpp << "const QString &LangLoader::warnings() const {\n";
|
||||
tcpp << "\tif (!_checked) {\n";
|
||||
tcpp << "\t\tfor (int32 i = 0; i < lng_keys_cnt; ++i) {\n";
|
||||
tcpp << "\t\t\tif (!_found[i]) {\n";
|
||||
tcpp << "\t\t\t\t_warn.push_back(qsl(\"No value found for key '%1'\").arg(_langKeyNames[i]));\n";
|
||||
tcpp << "\t\t\t}\n";
|
||||
tcpp << "\t\t}\n";
|
||||
tcpp << "\t\t_checked = true;\n";
|
||||
tcpp << "\t}\n";
|
||||
tcpp << "\tif (_warnings.isEmpty() && !_warn.isEmpty()) {\n";
|
||||
tcpp << "\t\t_warnings = _warn.join('\\n');\n";
|
||||
tcpp << "\t}\n";
|
||||
tcpp << "\treturn _warnings;\n";
|
||||
tcpp << "}\n";
|
||||
}
|
||||
|
||||
QFile cpp(lang_cpp), h(lang_h);
|
||||
bool write_cpp = true, write_h = true;
|
||||
if (cpp.open(QIODevice::ReadOnly)) {
|
||||
QByteArray wasCpp = cpp.readAll();
|
||||
if (wasCpp.size() == cppText.size()) {
|
||||
if (!memcmp(wasCpp.constData(), cppText.constData(), cppText.size())) {
|
||||
write_cpp = false;
|
||||
}
|
||||
}
|
||||
cpp.close();
|
||||
}
|
||||
if (write_cpp) {
|
||||
cout << "lang.cpp updated, writing " << keysOrder.size() << " rows.\n";
|
||||
if (!cpp.open(QIODevice::WriteOnly)) throw exception("Could not open lang.cpp for writing!");
|
||||
if (cpp.write(cppText) != cppText.size()) throw exception("Could not open lang.cpp for writing!");
|
||||
}
|
||||
if (h.open(QIODevice::ReadOnly)) {
|
||||
QByteArray wasH = h.readAll();
|
||||
if (wasH.size() == hText.size()) {
|
||||
if (!memcmp(wasH.constData(), hText.constData(), hText.size())) {
|
||||
write_h = false;
|
||||
}
|
||||
}
|
||||
h.close();
|
||||
}
|
||||
if (write_h) {
|
||||
cout << "lang.h updated, writing " << keysOrder.size() << " rows.\n";
|
||||
if (!h.open(QIODevice::WriteOnly)) throw exception("Could not open lang.h for writing!");
|
||||
if (h.write(hText) != hText.size()) throw exception("Could not open lang.h for writing!");
|
||||
}
|
||||
} catch (exception &e) {
|
||||
cout << e.what() << "\n";
|
||||
QCoreApplication::exit(1);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
61
Telegram/SourceFiles/_other/genlang.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
an unofficial desktop messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://tdesktop.com
|
||||
*/
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QVector>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QRegularExpression>
|
||||
#include <QtGui/QImage>
|
||||
#include <QtGui/QPixmap>
|
||||
#include <QtGui/QPainter>
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <QtCore/QTextStream>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtGui/QGuiApplication>
|
||||
|
||||
using std::string;
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::exception;
|
||||
|
||||
bool genLang(const QString &lang_in, const QString &lang_out);
|
||||
|
||||
class GenLang : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GenLang(const QString &lang_in, const QString &lang_out) : QObject(0),
|
||||
_lang_in(lang_in), _lang_out(lang_out) {
|
||||
}
|
||||
|
||||
public slots :
|
||||
void run() {
|
||||
if (genLang(_lang_in, _lang_out)) {
|
||||
emit finished();
|
||||
}
|
||||
}
|
||||
|
||||
signals:
|
||||
void finished();
|
||||
|
||||
private:
|
||||
|
||||
QString _lang_in, _lang_out;
|
||||
};
|
1817
Telegram/SourceFiles/_other/genstyles.cpp
Normal file
60
Telegram/SourceFiles/_other/genstyles.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
an unofficial desktop messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://tdesktop.com
|
||||
*/
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QVector>
|
||||
#include <QtGui/QBitmap>
|
||||
#include <QtCore/QBuffer>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QFile>
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
#include <QtCore/QTextStream>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtGui/QPainter>
|
||||
|
||||
using std::string;
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::exception;
|
||||
|
||||
bool genStyles(const QString &classes_in, const QString &classes_out, const QString &styles_in, const QString &styles_out);
|
||||
|
||||
class GenStyles : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GenStyles(const QString &classes_in, const QString &classes_out, const QString &styles_in, const QString styles_out) : QObject(0),
|
||||
_classes_in(classes_in), _classes_out(classes_out), _styles_in(styles_in), _styles_out(styles_out) {
|
||||
}
|
||||
|
||||
public slots:
|
||||
void run() {
|
||||
if (genStyles(_classes_in, _classes_out, _styles_in, _styles_out)) {
|
||||
emit finished();
|
||||
}
|
||||
}
|
||||
|
||||
signals:
|
||||
void finished();
|
||||
|
||||
private:
|
||||
|
||||
QString _classes_in, _classes_out, _styles_in, _styles_out;
|
||||
};
|
37
Telegram/SourceFiles/_other/memain.cpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
an unofficial desktop messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://tdesktop.com
|
||||
*/
|
||||
#include "memain.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
QString emoji_in("."), emoji_out("emoji_config.cpp");
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
if (string("-emoji_in") == argv[i]) {
|
||||
if (++i < argc) emoji_in = argv[i];
|
||||
} else if (string("-emoji_out") == argv[i]) {
|
||||
if (++i < argc) emoji_out = argv[i];
|
||||
}
|
||||
}
|
||||
QObject *taskImpl = new GenEmoji(emoji_in, emoji_out);
|
||||
|
||||
QGuiApplication a(argc, argv);
|
||||
|
||||
QObject::connect(taskImpl, SIGNAL(finished()), &a, SLOT(quit()));
|
||||
QTimer::singleShot(0, taskImpl, SLOT(run()));
|
||||
|
||||
return a.exec();
|
||||
}
|
20
Telegram/SourceFiles/_other/memain.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
an unofficial desktop messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://tdesktop.com
|
||||
*/
|
||||
#include <QtCore/QTimer>
|
||||
|
||||
#include "genemoji.h"
|
37
Telegram/SourceFiles/_other/mlmain.cpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
an unofficial desktop messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://tdesktop.com
|
||||
*/
|
||||
#include "mlmain.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
QString lang_in("lang.txt"), lang_out("lang");
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
if (string("-lang_in") == argv[i]) {
|
||||
if (++i < argc) lang_in = argv[i];
|
||||
} else if (string("-lang_out") == argv[i]) {
|
||||
if (++i < argc) lang_out = argv[i];
|
||||
}
|
||||
}
|
||||
QObject *taskImpl = new GenLang(lang_in, lang_out);
|
||||
|
||||
QCoreApplication a(argc, argv);
|
||||
|
||||
QObject::connect(taskImpl, SIGNAL(finished()), &a, SLOT(quit()));
|
||||
QTimer::singleShot(0, taskImpl, SLOT(run()));
|
||||
|
||||
return a.exec();
|
||||
}
|
20
Telegram/SourceFiles/_other/mlmain.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
an unofficial desktop messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://tdesktop.com
|
||||
*/
|
||||
#include <QtCore/QTimer>
|
||||
|
||||
#include "genlang.h"
|
41
Telegram/SourceFiles/_other/msmain.cpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
an unofficial desktop messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://tdesktop.com
|
||||
*/
|
||||
#include "msmain.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
QString classes_in("style_classes.txt"), classes_out("style_classes.h"), styles_in("style.txt"), styles_out("style_auto.h");
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
if (string("-classes_in") == argv[i]) {
|
||||
if (++i < argc) classes_in = argv[i];
|
||||
} else if (string("-classes_out") == argv[i]) {
|
||||
if (++i < argc) classes_out = argv[i];
|
||||
} else if (string("-styles_in") == argv[i]) {
|
||||
if (++i < argc) styles_in = argv[i];
|
||||
} else if (string("-styles_out") == argv[i]) {
|
||||
if (++i < argc) styles_out = argv[i];
|
||||
}
|
||||
}
|
||||
QObject *taskImpl = new GenStyles(classes_in, classes_out, styles_in, styles_out);
|
||||
|
||||
QGuiApplication a(argc, argv);
|
||||
|
||||
QObject::connect(taskImpl, SIGNAL(finished()), &a, SLOT(quit()));
|
||||
QTimer::singleShot(0, taskImpl, SLOT(run()));
|
||||
|
||||
return a.exec();
|
||||
}
|
20
Telegram/SourceFiles/_other/msmain.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
an unofficial desktop messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://tdesktop.com
|
||||
*/
|
||||
#include <QtCore/QTimer>
|
||||
|
||||
#include "genstyles.h"
|
298
Telegram/SourceFiles/_other/packer.cpp
Normal file
|
@ -0,0 +1,298 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
an unofficial desktop messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://tdesktop.com
|
||||
*/
|
||||
#include "packer.h"
|
||||
|
||||
const char *publicKey = "\
|
||||
-----BEGIN RSA PUBLIC KEY-----\n\
|
||||
MIGJAoGBAMA4ViQrjkPZ9xj0lrer3r23JvxOnrtE8nI69XLGSr+sRERz9YnUptnU\n\
|
||||
BZpkIfKaRcl6XzNJiN28cVwO1Ui5JSa814UAiDHzWUqCaXUiUEQ6NmNTneiGx2sQ\n\
|
||||
+9PKKlb8mmr3BB9A45ZNwLT6G9AK3+qkZLHojeSA+m84/a6GP4svAgMBAAE=\n\
|
||||
-----END RSA PUBLIC KEY-----\
|
||||
";
|
||||
|
||||
extern const char *privateKey;
|
||||
#include "../../../../TelegramPrivate/packer_private.h" // RSA PRIVATE KEY for update signing
|
||||
|
||||
// sha1 hash
|
||||
typedef unsigned char uchar;
|
||||
typedef unsigned int uint32;
|
||||
typedef signed int int32;
|
||||
namespace{
|
||||
inline uint32 sha1Shift(uint32 v, uint32 shift) {
|
||||
return ((v << shift) | (v >> (32 - shift)));
|
||||
}
|
||||
void sha1PartHash(uint32 *sha, uint32 *temp)
|
||||
{
|
||||
uint32 a = sha[0], b = sha[1], c = sha[2], d = sha[3], e = sha[4], round = 0;
|
||||
|
||||
#define _shiftswap(f, v) { \
|
||||
uint32 t = sha1Shift(a, 5) + (f) + e + v + temp[round]; \
|
||||
e = d; \
|
||||
d = c; \
|
||||
c = sha1Shift(b, 30); \
|
||||
b = a; \
|
||||
a = t; \
|
||||
++round; \
|
||||
}
|
||||
#define _shiftshiftswap(f, v) { \
|
||||
temp[round] = sha1Shift((temp[round - 3] ^ temp[round - 8] ^ temp[round - 14] ^ temp[round - 16]), 1); \
|
||||
_shiftswap(f, v) \
|
||||
}
|
||||
|
||||
while (round < 16) _shiftswap((b & c) | (~b & d), 0x5a827999)
|
||||
while (round < 20) _shiftshiftswap((b & c) | (~b & d), 0x5a827999)
|
||||
while (round < 40) _shiftshiftswap(b ^ c ^ d, 0x6ed9eba1)
|
||||
while (round < 60) _shiftshiftswap((b & c) | (b & d) | (c & d), 0x8f1bbcdc)
|
||||
while (round < 80) _shiftshiftswap(b ^ c ^ d, 0xca62c1d6)
|
||||
|
||||
#undef _shiftshiftswap
|
||||
#undef _shiftswap
|
||||
|
||||
sha[0] += a;
|
||||
sha[1] += b;
|
||||
sha[2] += c;
|
||||
sha[3] += d;
|
||||
sha[4] += e;
|
||||
}
|
||||
}
|
||||
|
||||
int32 *hashSha1(const void *data, uint32 len, void *dest) {
|
||||
const uchar *buf = (const uchar *)data;
|
||||
|
||||
uint32 temp[80], block = 0, end;
|
||||
uint32 sha[5] = {0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0};
|
||||
for (end = block + 64; block + 64 <= len; end = block + 64) {
|
||||
for (uint32 i = 0; block < end; block += 4) {
|
||||
temp[i++] = (uint32) buf[block + 3]
|
||||
| (((uint32) buf[block + 2]) << 8)
|
||||
| (((uint32) buf[block + 1]) << 16)
|
||||
| (((uint32) buf[block]) << 24);
|
||||
}
|
||||
sha1PartHash(sha, temp);
|
||||
}
|
||||
|
||||
end = len - block;
|
||||
memset(temp, 0, sizeof(uint32) * 16);
|
||||
uint32 last = 0;
|
||||
for (; last < end; ++last) {
|
||||
temp[last >> 2] |= (uint32)buf[last + block] << ((3 - (last & 0x03)) << 3);
|
||||
}
|
||||
temp[last >> 2] |= 0x80 << ((3 - (last & 3)) << 3);
|
||||
if (end >= 56) {
|
||||
sha1PartHash(sha, temp);
|
||||
memset(temp, 0, sizeof(uint32) * 16);
|
||||
}
|
||||
temp[15] = len << 3;
|
||||
sha1PartHash(sha, temp);
|
||||
|
||||
uchar *sha1To = (uchar*)dest;
|
||||
|
||||
for (int32 i = 19; i >= 0; --i) {
|
||||
sha1To[i] = (sha[i >> 2] >> (((3 - i) & 0x03) << 3)) & 0xFF;
|
||||
}
|
||||
|
||||
return (int32*)sha1To;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QString remove;
|
||||
int version = 0;
|
||||
QFileInfoList files;
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
if (string("-path") == argv[i] && i + 1 < argc) {
|
||||
QString path = QString(argv[i + 1]);
|
||||
QFileInfo info(path);
|
||||
files.push_back(info);
|
||||
if (remove.isEmpty()) remove = info.canonicalPath() + "/";
|
||||
} else if (string("-version") == argv[i] && i + 1 < argc) {
|
||||
version = QString(argv[i + 1]).toInt();
|
||||
}
|
||||
}
|
||||
|
||||
if (files.isEmpty() || remove.isEmpty() || version <= 1016 || version > 999999) { // not for release =)
|
||||
cout << "Usage: Packer.exe -path {file} -version {version} OR Packer.exe -path {dir} -version {version}\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool hasDirs = true;
|
||||
while (hasDirs) {
|
||||
hasDirs = false;
|
||||
for (QFileInfoList::iterator i = files.begin(); i != files.end(); ++i) {
|
||||
QFileInfo info(*i);
|
||||
QString fullPath = info.canonicalFilePath();
|
||||
if (info.isDir()) {
|
||||
hasDirs = true;
|
||||
files.erase(i);
|
||||
QDir d = QDir(info.absoluteFilePath());
|
||||
QString fullDir = d.canonicalPath();
|
||||
QStringList entries = d.entryList(QDir::Files | QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot);
|
||||
files.append(d.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot));
|
||||
break;
|
||||
} else if (!info.isReadable()) {
|
||||
cout << "Can't read: " << info.absoluteFilePath().toUtf8().constData() << "\n";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (QFileInfoList::iterator i = files.begin(); i != files.end(); ++i) {
|
||||
QFileInfo info(*i);
|
||||
if (info.canonicalFilePath().indexOf(remove) != 0) {
|
||||
cout << "Can't find '" << remove.toUtf8().constData() << "' in file '" << info.canonicalFilePath().toUtf8().constData() << "' :(\n";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray result;
|
||||
{
|
||||
QBuffer buffer(&result);
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
QDataStream stream(&buffer);
|
||||
stream.setVersion(QDataStream::Qt_5_1);
|
||||
|
||||
stream << quint32(version);
|
||||
|
||||
stream << quint32(files.size());
|
||||
cout << "Found " << files.size() << " file" << (files.size() == 1 ? "" : "s") << "..\n";
|
||||
for (QFileInfoList::iterator i = files.begin(); i != files.end(); ++i) {
|
||||
QFileInfo info(*i);
|
||||
QString fullName = info.canonicalFilePath();
|
||||
QString name = fullName.mid(remove.length());
|
||||
cout << name.toUtf8().constData() << " (" << info.size() << ")\n";
|
||||
|
||||
QFile f(fullName);
|
||||
if (!f.open(QIODevice::ReadOnly)) {
|
||||
cout << "Can't open '" << fullName.toUtf8().constData() << "' for read..\n";
|
||||
return -1;
|
||||
}
|
||||
QByteArray inner = f.readAll();
|
||||
stream << name << quint32(inner.size()) << inner;
|
||||
}
|
||||
if (stream.status() != QDataStream::Ok) {
|
||||
cout << "Stream status is bad: " << stream.status() << "\n";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int32 resultSize = result.size();
|
||||
cout << "Compression start, size: " << resultSize << "\n";
|
||||
|
||||
QByteArray compressed, resultCheck;
|
||||
|
||||
const int32 hSigLen = 128, hShaLen = 20, hPropsLen = LZMA_PROPS_SIZE, hOriginalSizeLen = sizeof(int32), hSize = hSigLen + hShaLen + hPropsLen + hOriginalSizeLen; // header
|
||||
|
||||
compressed.resize(hSize + resultSize + 1024 * 1024); // rsa signature + sha1 + lzma props + max compressed size
|
||||
|
||||
size_t compressedLen = compressed.size() - hSize;
|
||||
uchar outProps[LZMA_PROPS_SIZE];
|
||||
size_t outPropsSize = LZMA_PROPS_SIZE;
|
||||
int res = LzmaCompress((uchar*)(compressed.data() + hSize), &compressedLen, (const uchar*)(result.constData()), result.size(), (uchar*)(compressed.data() + hSigLen + hShaLen), &outPropsSize, 9, 64 * 1024 * 1024, 0, 0, 0, 0, 0);
|
||||
if (res != SZ_OK) {
|
||||
cout << "Error in compression: " << res << "\n";
|
||||
return -1;
|
||||
}
|
||||
compressed.resize(hSize + compressedLen);
|
||||
memcpy(compressed.data() + hSigLen + hShaLen + hPropsLen, &resultSize, hOriginalSizeLen);
|
||||
|
||||
cout << "Compressed to size: " << compressedLen << "\n";
|
||||
|
||||
cout << "Checking uncompressed..\n";
|
||||
|
||||
int32 resultCheckLen;
|
||||
memcpy(&resultCheckLen, compressed.constData() + hSigLen + hShaLen + hPropsLen, hOriginalSizeLen);
|
||||
if (resultCheckLen <= 0 || resultCheckLen > 1024 * 1024 * 1024) {
|
||||
cout << "Bad result len: " << resultCheckLen << "\n";
|
||||
return -1;
|
||||
}
|
||||
resultCheck.resize(resultCheckLen);
|
||||
|
||||
size_t resultLen = resultCheck.size();
|
||||
SizeT srcLen = compressedLen;
|
||||
int uncompressRes = LzmaUncompress((uchar*)resultCheck.data(), &resultLen, (const uchar*)(compressed.constData() + hSize), &srcLen, (const uchar*)(compressed.constData() + hSigLen + hShaLen), LZMA_PROPS_SIZE);
|
||||
if (uncompressRes != SZ_OK) {
|
||||
cout << "Uncompress failed: " << uncompressRes << "\n";
|
||||
return -1;
|
||||
}
|
||||
if (resultLen != result.size()) {
|
||||
cout << "Uncompress bad size: " << resultLen << ", was: " << result.size() << "\n";
|
||||
return -1;
|
||||
}
|
||||
if (memcmp(result.constData(), resultCheck.constData(), resultLen)) {
|
||||
cout << "Data differ :(\n";
|
||||
return -1;
|
||||
}
|
||||
/**/
|
||||
result = resultCheck = QByteArray();
|
||||
|
||||
cout << "Counting SHA1 hash..\n";
|
||||
|
||||
uchar sha1Buffer[20];
|
||||
memcpy(compressed.data() + hSigLen, hashSha1(compressed.constData() + hSigLen + hShaLen, compressedLen + hPropsLen + hOriginalSizeLen, sha1Buffer), hShaLen); // count sha1
|
||||
|
||||
uint32 siglen = 0;
|
||||
|
||||
cout << "Signing..\n";
|
||||
RSA *prKey = PEM_read_bio_RSAPrivateKey(BIO_new_mem_buf(const_cast<char*>(privateKey), -1), 0, 0, 0);
|
||||
if (!prKey) {
|
||||
cout << "Could not read RSA private key!\n";
|
||||
return -1;
|
||||
}
|
||||
if (RSA_size(prKey) != hSigLen) {
|
||||
RSA_free(prKey);
|
||||
cout << "Bad private key, size: " << RSA_size(prKey) << "\n";
|
||||
return -1;
|
||||
}
|
||||
if (RSA_sign(NID_sha1, (const uchar*)(compressed.constData() + hSigLen), hShaLen, (uchar*)(compressed.data()), &siglen, prKey) != 1) { // count signature
|
||||
RSA_free(prKey);
|
||||
cout << "Signing failed!\n";
|
||||
return -1;
|
||||
}
|
||||
RSA_free(prKey);
|
||||
|
||||
if (siglen != hSigLen) {
|
||||
cout << "Bad signature length: " << siglen << "\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
cout << "Checking signature..\n";
|
||||
RSA *pbKey = PEM_read_bio_RSAPublicKey(BIO_new_mem_buf(const_cast<char*>(publicKey), -1), 0, 0, 0);
|
||||
if (!pbKey) {
|
||||
cout << "Could not read RSA public key!\n";
|
||||
return -1;
|
||||
}
|
||||
if (RSA_verify(NID_sha1, (const uchar*)(compressed.constData() + hSigLen), hShaLen, (const uchar*)(compressed.constData()), siglen, pbKey) != 1) { // verify signature
|
||||
RSA_free(pbKey);
|
||||
cout << "Signature verification failed!\n";
|
||||
return -1;
|
||||
}
|
||||
cout << "Signature verified!\n";
|
||||
RSA_free(pbKey);
|
||||
|
||||
QString outName(QString("tupdate%1").arg(version));
|
||||
QFile out(outName);
|
||||
if (!out.open(QIODevice::WriteOnly)) {
|
||||
cout << "Can't open '" << outName.toUtf8().constData() << "' for write..\n";
|
||||
return -1;
|
||||
}
|
||||
out.write(compressed);
|
||||
out.close();
|
||||
|
||||
cout << "Update file '" << outName.toUtf8().constData() << "' written successfully!\n";
|
||||
|
||||
return 0;
|
||||
}
|
44
Telegram/SourceFiles/_other/packer.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
an unofficial desktop messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://tdesktop.com
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QBuffer>
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include <LzmaLib.h>
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
using std::string;
|
||||
using std::wstring;
|
||||
using std::cout;
|
99
Telegram/SourceFiles/_other/prepare.cpp
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
an unofficial desktop messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://tdesktop.com
|
||||
*/
|
||||
#include "prepare.h"
|
||||
|
||||
int prepare(QFileInfo f, QStringList paths) {
|
||||
if (paths.isEmpty()) {
|
||||
cout << "No -path args were passed :(\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
int lastVersion = 0;
|
||||
QString lastVersionStr;
|
||||
QFileInfo last;
|
||||
QFileInfoList l = f.absoluteDir().entryInfoList(QDir::Files);
|
||||
for (QFileInfoList::iterator i = l.begin(), e = l.end(); i != e; ++i) {
|
||||
QRegularExpressionMatch m = QRegularExpression("/tsetup.((\\d+).(\\d+).(\\d+)).exe$").match(i->absoluteFilePath());
|
||||
if (!m.hasMatch()) continue;
|
||||
|
||||
int version = m.captured(2).toInt() * 1000000 + m.captured(3).toInt() * 1000 + m.captured(4).toInt();
|
||||
if (version > lastVersion) {
|
||||
lastVersion = version;
|
||||
lastVersionStr = m.captured(1);
|
||||
last = *i;
|
||||
}
|
||||
}
|
||||
|
||||
if (!lastVersion) {
|
||||
cout << "No tsetup.X.Y.Z.exe found :(\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
cout << "Last version: " << lastVersionStr.toUtf8().constData() << " (" << lastVersion << "), executing packer..\n";
|
||||
|
||||
QDir dir("deploy/" + lastVersionStr);
|
||||
if (dir.exists()) {
|
||||
cout << "Version " << lastVersionStr.toUtf8().constData() << " already exists in /deploy..\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
QString packer = QString("Packer.exe -version %1").arg(lastVersion);
|
||||
for (QStringList::iterator i = paths.begin(), e = paths.end(); i != e; ++i) {
|
||||
packer += " -path " + *i;
|
||||
}
|
||||
|
||||
int res = system(packer.toUtf8().constData());
|
||||
|
||||
if (res) return res;
|
||||
|
||||
dir.mkpath(".");
|
||||
|
||||
paths.push_back("Telegram.pdb");
|
||||
paths.push_back("Updater.pdb");
|
||||
paths.push_back("tsetup." + lastVersionStr + ".exe");
|
||||
paths.push_back(QString("tupdate%1").arg(lastVersion));
|
||||
for (QStringList::iterator i = paths.begin(), e = paths.end(); i != e; ++i) {
|
||||
if (!QFile::copy(*i, "deploy/" + lastVersionStr + "/" + *i)) {
|
||||
cout << "Could not copy " << i->toUtf8().constData() << " to deploy/" << lastVersionStr.toUtf8().constData() << "\n";
|
||||
return -1;
|
||||
}
|
||||
cout << "Copied " << i->toUtf8().constData() << "..\n";
|
||||
}
|
||||
for (QStringList::iterator i = paths.begin(), e = paths.end(); i != e; ++i) {
|
||||
QFile::remove(*i);
|
||||
}
|
||||
|
||||
cout << "Update created in deploy/" << lastVersionStr.toUtf8().constData() << "\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QFileInfo f(argv[0]);
|
||||
|
||||
QStringList paths;
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
if (string(argv[i]) == "-path" && i + 1 < argc) {
|
||||
paths.push_back(QString(argv[i + 1]));
|
||||
}
|
||||
}
|
||||
int res = prepare(f, paths);
|
||||
system("PAUSE");
|
||||
return res;
|
||||
}
|
37
Telegram/SourceFiles/_other/prepare.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
an unofficial desktop messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://tdesktop.com
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QBuffer>
|
||||
#include <QtCore/QRegularExpression>
|
||||
#include <QtCore/QVector>
|
||||
|
||||
#include <process.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <exception>
|
||||
using std::string;
|
||||
using std::wstring;
|
||||
using std::cout;
|
459
Telegram/SourceFiles/_other/updater.cpp
Normal file
|
@ -0,0 +1,459 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
an unofficial desktop messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://tdesktop.com
|
||||
*/
|
||||
#include "updater.h"
|
||||
|
||||
bool _debug = false;
|
||||
|
||||
wstring exeName, exeDir;
|
||||
|
||||
bool equal(const wstring &a, const wstring &b) {
|
||||
return !_wcsicmp(a.c_str(), b.c_str());
|
||||
}
|
||||
|
||||
void updateError(const WCHAR *msg, DWORD errorCode) {
|
||||
WCHAR errMsg[2048];
|
||||
LPTSTR errorText = NULL, errorTextDefault = L"(Unknown error)";
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&errorText, 0, 0);
|
||||
if (!errorText) {
|
||||
errorText = errorTextDefault;
|
||||
}
|
||||
wsprintf(errMsg, L"%s, error code: %d\nError message: %s", msg, errorCode, errorText);
|
||||
|
||||
MessageBox(0, errMsg, L"Update error!", MB_ICONERROR);
|
||||
|
||||
if (errorText != errorTextDefault) {
|
||||
LocalFree(errorText);
|
||||
}
|
||||
}
|
||||
|
||||
HANDLE _logFile = 0;
|
||||
void openLog() {
|
||||
if (!_debug || _logFile) return;
|
||||
wstring logPath = L"DebugLogs";
|
||||
if (!CreateDirectory(logPath.c_str(), NULL)) {
|
||||
DWORD errorCode = GetLastError();
|
||||
if (errorCode && errorCode != ERROR_ALREADY_EXISTS) {
|
||||
updateError(L"Failed to create log directory", errorCode);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SYSTEMTIME stLocalTime;
|
||||
|
||||
GetLocalTime(&stLocalTime);
|
||||
|
||||
static const int maxFileLen = MAX_PATH * 10;
|
||||
WCHAR logName[maxFileLen];
|
||||
wsprintf(logName, L"DebugLogs\\%04d%02d%02d_%02d%02d%02d_upd.txt",
|
||||
stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,
|
||||
stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond);
|
||||
_logFile = CreateFile(logName, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if (_logFile == INVALID_HANDLE_VALUE) { // :(
|
||||
updateError(L"Failed to create log file", GetLastError());
|
||||
_logFile = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void closeLog() {
|
||||
if (!_logFile) return;
|
||||
|
||||
CloseHandle(_logFile);
|
||||
_logFile = 0;
|
||||
}
|
||||
|
||||
void writeLog(const wstring &msg) {
|
||||
if (!_logFile) return;
|
||||
|
||||
wstring full = msg + L'\n';
|
||||
DWORD written = 0;
|
||||
BOOL result = WriteFile(_logFile, full.c_str(), full.size() * sizeof(wchar_t), &written, 0);
|
||||
if (!result) {
|
||||
updateError((L"Failed to write log entry '" + msg + L"'").c_str(), GetLastError());
|
||||
closeLog();
|
||||
return;
|
||||
}
|
||||
BOOL flushr = FlushFileBuffers(_logFile);
|
||||
if (!flushr) {
|
||||
updateError((L"Failed to flush log on entry '" + msg + L"'").c_str(), GetLastError());
|
||||
closeLog();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void delFolder() {
|
||||
wstring delPath = L"tupdates\\ready", delFolder = L"tupdates";
|
||||
WCHAR path[4096];
|
||||
memcpy(path, delPath.c_str(), (delPath.size() + 1) * sizeof(WCHAR));
|
||||
path[delPath.size() + 1] = 0;
|
||||
writeLog(L"Fully clearing path '" + delPath + L"'..");
|
||||
SHFILEOPSTRUCT file_op = {
|
||||
NULL,
|
||||
FO_DELETE,
|
||||
path,
|
||||
L"",
|
||||
FOF_NOCONFIRMATION |
|
||||
FOF_NOERRORUI |
|
||||
FOF_SILENT,
|
||||
false,
|
||||
0,
|
||||
L""
|
||||
};
|
||||
int res = SHFileOperation(&file_op);
|
||||
if (res) writeLog(L"Error: failed to clear path! :(");
|
||||
RemoveDirectory(delFolder.c_str());
|
||||
}
|
||||
|
||||
bool update() {
|
||||
writeLog(L"Update started..");
|
||||
|
||||
wstring updDir = L"tupdates\\ready";
|
||||
|
||||
deque<wstring> dirs;
|
||||
dirs.push_back(updDir);
|
||||
|
||||
deque<wstring> from, to, forcedirs;
|
||||
|
||||
do {
|
||||
wstring dir = dirs.front();
|
||||
dirs.pop_front();
|
||||
|
||||
wstring toDir = exeDir;
|
||||
if (dir.size() > updDir.size() + 1) {
|
||||
toDir += (dir.substr(updDir.size() + 1) + L"\\");
|
||||
forcedirs.push_back(toDir);
|
||||
writeLog(L"Parsing dir '" + toDir + L"' in update tree..");
|
||||
}
|
||||
|
||||
WIN32_FIND_DATA findData;
|
||||
HANDLE findHandle = FindFirstFileEx((dir + L"\\*").c_str(), FindExInfoStandard, &findData, FindExSearchNameMatch, 0, 0);
|
||||
if (findHandle == INVALID_HANDLE_VALUE) {
|
||||
DWORD errorCode = GetLastError();
|
||||
if (errorCode == ERROR_PATH_NOT_FOUND) { // no update is ready
|
||||
return true;
|
||||
}
|
||||
writeLog(L"Error: failed to find update files :(");
|
||||
updateError(L"Failed to find update files", errorCode);
|
||||
delFolder();
|
||||
return false;
|
||||
}
|
||||
|
||||
do {
|
||||
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
if (findData.cFileName != wstring(L".") && findData.cFileName != wstring(L"..")) {
|
||||
dirs.push_back(dir + L"\\" + findData.cFileName);
|
||||
writeLog(L"Added dir '" + dir + L"\\" + findData.cFileName + L"' in update tree..");
|
||||
}
|
||||
} else {
|
||||
wstring fname = dir + L"\\" + findData.cFileName;
|
||||
wstring tofname = exeDir + fname.substr(updDir.size() + 1);
|
||||
if (equal(tofname, exeName)) { // bad update - has Updater.exe - delete all dir
|
||||
writeLog(L"Error: bad update, has Updater.exe! '" + tofname + L"' equal '" + exeName + L"'");
|
||||
delFolder();
|
||||
return false;
|
||||
}
|
||||
from.push_back(fname);
|
||||
to.push_back(tofname);
|
||||
writeLog(L"Added file '" + fname + L"' to be copied to '" + tofname + L"'");
|
||||
}
|
||||
} while (FindNextFile(findHandle, &findData));
|
||||
DWORD errorCode = GetLastError();
|
||||
if (errorCode && errorCode != ERROR_NO_MORE_FILES) { // everything is found
|
||||
writeLog(L"Error: failed to find next update file :(");
|
||||
updateError(L"Failed to find next update file", errorCode);
|
||||
delFolder();
|
||||
return false;
|
||||
}
|
||||
FindClose(findHandle);
|
||||
} while (!dirs.empty());
|
||||
|
||||
for (size_t i = 0; i < forcedirs.size(); ++i) {
|
||||
wstring forcedir = forcedirs[i];
|
||||
writeLog(L"Forcing dir '" + forcedir + L"'..");
|
||||
if (!forcedir.empty() && !CreateDirectory(forcedir.c_str(), NULL)) {
|
||||
DWORD errorCode = GetLastError();
|
||||
if (errorCode && errorCode != ERROR_ALREADY_EXISTS) {
|
||||
writeLog(L"Error: failed to create dir '" + forcedir + L"'..");
|
||||
updateError(L"Failed to create directory", errorCode);
|
||||
delFolder();
|
||||
return false;
|
||||
}
|
||||
writeLog(L"Already exists!");
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < from.size(); ++i) {
|
||||
wstring fname = from[i], tofname = to[i];
|
||||
BOOL copyResult;
|
||||
do {
|
||||
writeLog(L"Copying file '" + fname + L"' to '" + tofname + L"'..");
|
||||
int copyTries = 0;
|
||||
do {
|
||||
copyResult = CopyFile(fname.c_str(), tofname.c_str(), FALSE);
|
||||
if (copyResult == FALSE) {
|
||||
++copyTries;
|
||||
Sleep(100);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while (copyTries < 30);
|
||||
if (copyResult == FALSE) {
|
||||
writeLog(L"Error: failed to copy, asking to retry..");
|
||||
WCHAR errMsg[2048];
|
||||
wsprintf(errMsg, L"Failed to update Telegram :(\n%s is not accessible.", tofname);
|
||||
if (MessageBox(0, errMsg, L"Update error!", MB_ICONERROR | MB_RETRYCANCEL) != IDRETRY) {
|
||||
delFolder();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} while (copyResult == FALSE);
|
||||
}
|
||||
|
||||
writeLog(L"Update succeed! Clearing folder..");
|
||||
delFolder();
|
||||
return true;
|
||||
}
|
||||
|
||||
void updateRegistry() {
|
||||
writeLog(L"Updating registry..");
|
||||
|
||||
HANDLE versionFile = CreateFile(L"tdata\\version", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if (versionFile != INVALID_HANDLE_VALUE) {
|
||||
DWORD versionNum = 0, versionLen = 0, readLen = 0;
|
||||
WCHAR versionStr[32];
|
||||
if (ReadFile(versionFile, &versionNum, sizeof(DWORD), &readLen, NULL) != TRUE || readLen != sizeof(DWORD)) {
|
||||
versionNum = 0;
|
||||
} else if (ReadFile(versionFile, &versionLen, sizeof(DWORD), &readLen, NULL) != TRUE || readLen != sizeof(DWORD) || versionLen > 63) {
|
||||
versionNum = 0;
|
||||
} else if (ReadFile(versionFile, versionStr, versionLen, &readLen, NULL) != TRUE || readLen != versionLen) {
|
||||
versionNum = 0;
|
||||
}
|
||||
CloseHandle(versionFile);
|
||||
writeLog(L"Version file read.");
|
||||
if (versionNum) {
|
||||
versionStr[versionLen / 2] = 0;
|
||||
HKEY rkey;
|
||||
LSTATUS status = RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{53F49750-6209-4FBF-9CA8-7A333C87D1ED}_is1", 0, KEY_QUERY_VALUE | KEY_SET_VALUE, &rkey);
|
||||
if (status == ERROR_SUCCESS) {
|
||||
writeLog(L"Checking registry install location..");
|
||||
static const int bufSize = 4096;
|
||||
DWORD locationType, locationSize = bufSize * 2;
|
||||
WCHAR locationStr[bufSize], exp[bufSize];
|
||||
if (RegQueryValueEx(rkey, L"InstallLocation", 0, &locationType, (BYTE*)locationStr, &locationSize) == ERROR_SUCCESS) {
|
||||
locationSize /= 2;
|
||||
if (locationStr[locationSize - 1]) {
|
||||
locationStr[locationSize++] = 0;
|
||||
}
|
||||
if (locationType == REG_EXPAND_SZ) {
|
||||
DWORD copy = ExpandEnvironmentStrings(locationStr, exp, bufSize);
|
||||
if (copy <= bufSize) {
|
||||
memcpy(locationStr, exp, copy * sizeof(WCHAR));
|
||||
}
|
||||
}
|
||||
if (locationType == REG_EXPAND_SZ || locationType == REG_SZ) {
|
||||
if (PathCanonicalize(exp, locationStr) == TRUE) {
|
||||
memcpy(locationStr, exp, bufSize * sizeof(WCHAR));
|
||||
if (GetFullPathName(L".", bufSize, exp, 0) < bufSize) {
|
||||
wstring installpath = locationStr, mypath = exp;
|
||||
if (installpath == mypath + L"\\" || true) { // always update reg info, if we found it
|
||||
WCHAR nameStr[bufSize], dateStr[bufSize];
|
||||
SYSTEMTIME stLocalTime;
|
||||
GetLocalTime(&stLocalTime);
|
||||
RegSetValueEx(rkey, L"DisplayVersion", 0, REG_SZ, (BYTE*)versionStr, ((versionLen / 2) + 1) * sizeof(WCHAR));
|
||||
wsprintf(nameStr, L"Telegram Win (Unofficial) version %s", versionStr);
|
||||
RegSetValueEx(rkey, L"DisplayName", 0, REG_SZ, (BYTE*)nameStr, (wcslen(nameStr) + 1) * sizeof(WCHAR));
|
||||
wsprintf(dateStr, L"%04d%02d%02d", stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay);
|
||||
RegSetValueEx(rkey, L"InstallDate", 0, REG_SZ, (BYTE*)dateStr, (wcslen(dateStr) + 1) * sizeof(WCHAR));
|
||||
|
||||
WCHAR *appURL = L"https://tdesktop.com";
|
||||
RegSetValueEx(rkey, L"HelpLink", 0, REG_SZ, (BYTE*)appURL, (wcslen(appURL) + 1) * sizeof(WCHAR));
|
||||
RegSetValueEx(rkey, L"URLInfoAbout", 0, REG_SZ, (BYTE*)appURL, (wcslen(appURL) + 1) * sizeof(WCHAR));
|
||||
RegSetValueEx(rkey, L"URLUpdateInfo", 0, REG_SZ, (BYTE*)appURL, (wcslen(appURL) + 1) * sizeof(WCHAR));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RegCloseKey(rkey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include <ShlObj.h>
|
||||
|
||||
int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdParamarg, int cmdShow) {
|
||||
openLog();
|
||||
|
||||
#ifdef _NEED_WIN_GENERATE_DUMP
|
||||
_oldWndExceptionFilter = SetUnhandledExceptionFilter(_exceptionFilter);
|
||||
#endif
|
||||
|
||||
writeLog(L"Updaters started..");
|
||||
|
||||
LPWSTR *args;
|
||||
int argsCount;
|
||||
|
||||
bool needupdate = false, autostart = false, debug = false;
|
||||
args = CommandLineToArgvW(GetCommandLine(), &argsCount);
|
||||
if (args) {
|
||||
for (int i = 1; i < argsCount; ++i) {
|
||||
if (equal(args[i], L"-update")) {
|
||||
needupdate = true;
|
||||
} else if (equal(args[i], L"-autostart")) {
|
||||
autostart = true;
|
||||
} else if (equal(args[i], L"-debug")) {
|
||||
debug = _debug = true;
|
||||
openLog();
|
||||
}
|
||||
}
|
||||
if (needupdate) writeLog(L"Need to update!");
|
||||
if (autostart) writeLog(L"From autostart!");
|
||||
|
||||
exeName = args[0];
|
||||
writeLog(L"Exe name is: " + exeName);
|
||||
if (exeName.size() > 11) {
|
||||
if (equal(exeName.substr(exeName.size() - 11), L"Updater.exe")) {
|
||||
exeDir = exeName.substr(0, exeName.size() - 11);
|
||||
writeLog(L"Exe dir is: " + exeDir);
|
||||
if (needupdate && update()) {
|
||||
updateRegistry();
|
||||
}
|
||||
} else {
|
||||
writeLog(L"Error: bad exe name!");
|
||||
}
|
||||
} else {
|
||||
writeLog(L"Error: short exe name!");
|
||||
}
|
||||
LocalFree(args);
|
||||
} else {
|
||||
writeLog(L"Error: No command line arguments!");
|
||||
}
|
||||
|
||||
wstring targs = L"-noupdate";
|
||||
if (autostart) targs += L" -autostart";
|
||||
if (debug) targs += L" -debug";
|
||||
|
||||
ShellExecute(0, 0, (exeDir + L"Telegram.exe").c_str(), targs.c_str(), 0, SW_SHOWNORMAL);
|
||||
|
||||
writeLog(L"Executed Telegram.exe, closing log and quiting..");
|
||||
closeLog();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef _NEED_WIN_GENERATE_DUMP
|
||||
static const WCHAR *_programName = L"Telegram Win (Unofficial)"; // folder in APPDATA, if current path is unavailable for writing
|
||||
static const WCHAR *_exeName = L"Updater.exe";
|
||||
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER _oldWndExceptionFilter = 0;
|
||||
|
||||
typedef BOOL (FAR STDAPICALLTYPE *t_miniDumpWriteDump)(
|
||||
_In_ HANDLE hProcess,
|
||||
_In_ DWORD ProcessId,
|
||||
_In_ HANDLE hFile,
|
||||
_In_ MINIDUMP_TYPE DumpType,
|
||||
_In_opt_ PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
|
||||
_In_opt_ PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
|
||||
_In_opt_ PMINIDUMP_CALLBACK_INFORMATION CallbackParam
|
||||
);
|
||||
t_miniDumpWriteDump miniDumpWriteDump = 0;
|
||||
|
||||
HANDLE _generateDumpFileAtPath(const WCHAR *path) {
|
||||
static const int maxFileLen = MAX_PATH * 10;
|
||||
|
||||
WCHAR szPath[maxFileLen];
|
||||
wsprintf(szPath, L"%stdumps\\", path);
|
||||
|
||||
if (!CreateDirectory(szPath, NULL)) {
|
||||
if (GetLastError() != ERROR_ALREADY_EXISTS) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
WCHAR szFileName[maxFileLen];
|
||||
WCHAR szExeName[maxFileLen];
|
||||
|
||||
wcscpy_s(szExeName, _exeName);
|
||||
WCHAR *dotFrom = wcschr(szExeName, WCHAR(L'.'));
|
||||
if (dotFrom) {
|
||||
wsprintf(dotFrom, L"");
|
||||
}
|
||||
|
||||
SYSTEMTIME stLocalTime;
|
||||
|
||||
GetLocalTime(&stLocalTime);
|
||||
|
||||
wsprintf(szFileName, L"%s%s-%s-%04d%02d%02d-%02d%02d%02d-%ld-%ld.dmp",
|
||||
szPath, szExeName, updaterVersionStr,
|
||||
stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,
|
||||
stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond,
|
||||
GetCurrentProcessId(), GetCurrentThreadId());
|
||||
return CreateFile(szFileName, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
|
||||
}
|
||||
|
||||
void _generateDump(EXCEPTION_POINTERS* pExceptionPointers) {
|
||||
static const int maxFileLen = MAX_PATH * 10;
|
||||
|
||||
closeLog();
|
||||
|
||||
HMODULE hDll = LoadLibrary(L"DBGHELP.DLL");
|
||||
if (!hDll) return;
|
||||
|
||||
miniDumpWriteDump = (t_miniDumpWriteDump)GetProcAddress(hDll, "MiniDumpWriteDump");
|
||||
if (!miniDumpWriteDump) return;
|
||||
|
||||
HANDLE hDumpFile = 0;
|
||||
|
||||
WCHAR szPath[maxFileLen];
|
||||
DWORD len = GetModuleFileName(GetModuleHandle(0), szPath, maxFileLen);
|
||||
if (!len) return;
|
||||
|
||||
WCHAR *pathEnd = szPath + len;
|
||||
|
||||
if (!_wcsicmp(pathEnd - wcslen(_exeName), _exeName)) {
|
||||
wsprintf(pathEnd - wcslen(_exeName), L"");
|
||||
hDumpFile = _generateDumpFileAtPath(szPath);
|
||||
}
|
||||
if (!hDumpFile || hDumpFile == INVALID_HANDLE_VALUE) {
|
||||
WCHAR wstrPath[maxFileLen];
|
||||
DWORD wstrPathLen;
|
||||
if (wstrPathLen = GetEnvironmentVariable(L"APPDATA", wstrPath, maxFileLen)) {
|
||||
wsprintf(wstrPath + wstrPathLen, L"\\%s\\", _programName);
|
||||
hDumpFile = _generateDumpFileAtPath(wstrPath);
|
||||
}
|
||||
}
|
||||
|
||||
if (!hDumpFile || hDumpFile == INVALID_HANDLE_VALUE) {
|
||||
return;
|
||||
}
|
||||
|
||||
MINIDUMP_EXCEPTION_INFORMATION ExpParam = {0};
|
||||
ExpParam.ThreadId = GetCurrentThreadId();
|
||||
ExpParam.ExceptionPointers = pExceptionPointers;
|
||||
ExpParam.ClientPointers = TRUE;
|
||||
|
||||
miniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpWithDataSegs, &ExpParam, NULL, NULL);
|
||||
}
|
||||
|
||||
LONG CALLBACK _exceptionFilter(EXCEPTION_POINTERS* pExceptionPointers) {
|
||||
_generateDump(pExceptionPointers);
|
||||
return _oldWndExceptionFilter ? (*_oldWndExceptionFilter)(pExceptionPointers) : EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
#endif
|
40
Telegram/SourceFiles/_other/updater.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
an unofficial desktop messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://tdesktop.com
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
#include <DbgHelp.h>
|
||||
#include <Shellapi.h>
|
||||
#include <Shlwapi.h>
|
||||
|
||||
#include <deque>
|
||||
#include <string>
|
||||
|
||||
using std::deque;
|
||||
using std::wstring;
|
||||
|
||||
#define _NEED_WIN_GENERATE_DUMP
|
||||
|
||||
#ifdef _NEED_WIN_GENERATE_DUMP
|
||||
extern LPTOP_LEVEL_EXCEPTION_FILTER _oldWndExceptionFilter;
|
||||
LONG CALLBACK _exceptionFilter(EXCEPTION_POINTERS* pExceptionPointers);
|
||||
#endif _NEED_WIN_GENERATE_DUMP
|
||||
|
||||
static int updaterVersion = 1000;
|
||||
static const WCHAR *updaterVersionStr = L"0.1.0";
|
1925
Telegram/SourceFiles/app.cpp
Normal file
187
Telegram/SourceFiles/app.h
Normal file
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
an unofficial desktop messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://tdesktop.com
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
|
||||
class Application;
|
||||
class Window;
|
||||
class MainWidget;
|
||||
class Settings;
|
||||
class Font;
|
||||
class Color;
|
||||
class FileUploader;
|
||||
|
||||
#include "history.h"
|
||||
|
||||
typedef QMap<HistoryItem*, bool> HistoryItemsMap;
|
||||
typedef QHash<VideoData*, HistoryItemsMap> VideoItems;
|
||||
typedef QHash<AudioData*, HistoryItemsMap> AudioItems;
|
||||
typedef QHash<DocumentData*, HistoryItemsMap> DocumentItems;
|
||||
|
||||
namespace App {
|
||||
Application *app();
|
||||
Window *wnd();
|
||||
MainWidget *main();
|
||||
Settings *settings();
|
||||
FileUploader *uploader();
|
||||
|
||||
void showSettings();
|
||||
void logOut();
|
||||
bool loggedOut();
|
||||
|
||||
QString formatPhone(QString phone);
|
||||
|
||||
inline bool isChat(const PeerId &peer) {
|
||||
return peer & 0x100000000L;
|
||||
}
|
||||
PeerId peerFromMTP(const MTPPeer &peer_id);
|
||||
PeerId peerFromChat(int32 chat_id);
|
||||
inline PeerId peerFromChat(const MTPint &chat_id) {
|
||||
return peerFromChat(chat_id.v);
|
||||
}
|
||||
PeerId peerFromUser(int32 user_id);
|
||||
inline PeerId peerFromUser(const MTPint &user_id) {
|
||||
return peerFromUser(user_id.v);
|
||||
}
|
||||
MTPpeer peerToMTP(const PeerId &peer_id);
|
||||
|
||||
int32 onlineWillChangeIn(int32 onlineOnServer, int32 nowOnServer);
|
||||
QString onlineText(int32 onlineOnServer, int32 nowOnServer);
|
||||
|
||||
void feedUsers(const MTPVector<MTPUser> &users);
|
||||
void feedChats(const MTPVector<MTPChat> &chats);
|
||||
void feedParticipants(const MTPChatParticipants &p);
|
||||
void feedParticipantAdd(const MTPDupdateChatParticipantAdd &d);
|
||||
void feedParticipantDelete(const MTPDupdateChatParticipantDelete &d);
|
||||
void feedMsgs(const MTPVector<MTPMessage> &msgs, bool newMsgs = false);
|
||||
void feedWereRead(const QVector<MTPint> &msgsIds);
|
||||
void feedWereDeleted(const QVector<MTPint> &msgsIds);
|
||||
void feedUserLinks(const MTPVector<MTPcontacts_Link> &links);
|
||||
void feedUserLink(MTPint userId, const MTPcontacts_MyLink &myLink, const MTPcontacts_ForeignLink &foreignLink);
|
||||
void feedMessageMedia(MsgId msgId, const MTPMessage &msg);
|
||||
int32 maxMsgId();
|
||||
|
||||
PhotoData *feedPhoto(const MTPPhoto &photo, const PreparedPhotoThumbs &thumbs);
|
||||
PhotoData *feedPhoto(const MTPPhoto &photo, PhotoData *convert = 0);
|
||||
PhotoData *feedPhoto(const MTPDphoto &photo, PhotoData *convert = 0);
|
||||
VideoData *feedVideo(const MTPDvideo &video, VideoData *convert = 0);
|
||||
AudioData *feedAudio(const MTPDaudio &audio, AudioData *convert = 0);
|
||||
DocumentData *feedDocument(const MTPdocument &document, const QPixmap &thumb);
|
||||
DocumentData *feedDocument(const MTPdocument &document, DocumentData *convert = 0);
|
||||
DocumentData *feedDocument(const MTPDdocument &document, DocumentData *convert = 0);
|
||||
|
||||
UserData *userLoaded(const PeerId &user);
|
||||
ChatData *chatLoaded(const PeerId &chat);
|
||||
PeerData *peerLoaded(const PeerId &peer);
|
||||
UserData *userLoaded(int32 user);
|
||||
ChatData *chatLoaded(int32 chat);
|
||||
|
||||
PeerData *peer(const PeerId &peer);
|
||||
UserData *user(const PeerId &peer);
|
||||
UserData *user(int32 user);
|
||||
UserData *self();
|
||||
ChatData *chat(const PeerId &peer);
|
||||
ChatData *chat(int32 chat);
|
||||
QString peerName(const PeerData *peer, bool forDialogs = false);
|
||||
PhotoData *photo(const PhotoId &photo, PhotoData *convert = 0, const uint64 &access = 0, int32 user = 0, int32 date = 0, const ImagePtr &thumb = ImagePtr(), const ImagePtr &full = ImagePtr());
|
||||
void forgetPhotos();
|
||||
VideoData *video(const VideoId &video, VideoData *convert = 0, const uint64 &access = 0, int32 user = 0, int32 date = 0, int32 duration = 0, int32 w = 0, int32 h = 0, const ImagePtr &thumb = ImagePtr(), int32 dc = 0, int32 size = 0);
|
||||
void forgetVideos();
|
||||
AudioData *audio(const AudioId &audio, AudioData *convert = 0, const uint64 &access = 0, int32 user = 0, int32 date = 0, int32 duration = 0, int32 dc = 0, int32 size = 0);
|
||||
void forgetAudios();
|
||||
DocumentData *document(const DocumentId &document, DocumentData *convert = 0, const uint64 &access = 0, int32 user = 0, int32 date = 0, const QString &name = QString(), const QString &mime = QString(), const ImagePtr &thumb = ImagePtr(), int32 dc = 0, int32 size = 0);
|
||||
void forgetDocuments();
|
||||
|
||||
MTPPhoto photoFromUserPhoto(MTPint userId, MTPint date, const MTPUserProfilePhoto &photo);
|
||||
|
||||
Histories &histories();
|
||||
History *history(const PeerId &peer, int32 unreadCnt = 0);
|
||||
History *historyLoaded(const PeerId &peer);
|
||||
HistoryItem *histItemById(MsgId itemId);
|
||||
bool historyRegItem(HistoryItem *item);
|
||||
void historyUnregItem(HistoryItem *item);
|
||||
void historyClearMsgs();
|
||||
void historyClearItems();
|
||||
// void deleteHistory(const PeerId &peer);
|
||||
|
||||
void historyRegRandom(uint64 randomId, MsgId itemId);
|
||||
void historyUnregRandom(uint64 randomId);
|
||||
MsgId histItemByRandom(uint64 randomId);
|
||||
|
||||
void hoveredItem(HistoryItem *item);
|
||||
HistoryItem *hoveredItem();
|
||||
void pressedItem(HistoryItem *item);
|
||||
HistoryItem *pressedItem();
|
||||
void hoveredLinkItem(HistoryItem *item);
|
||||
HistoryItem *hoveredLinkItem();
|
||||
void pressedLinkItem(HistoryItem *item);
|
||||
HistoryItem *pressedLinkItem();
|
||||
void contextItem(HistoryItem *item);
|
||||
HistoryItem *contextItem();
|
||||
void mousedItem(HistoryItem *item);
|
||||
HistoryItem *mousedItem();
|
||||
|
||||
QPixmap &sprite();
|
||||
QPixmap &emojis();
|
||||
const QPixmap &emojiSingle(const EmojiData *emoji, int32 fontHeight);
|
||||
|
||||
void initMedia();
|
||||
void deinitMedia(bool completely = true);
|
||||
void playSound();
|
||||
|
||||
void writeConfig();
|
||||
void readConfig();
|
||||
void writeUserConfig();
|
||||
void readUserConfig();
|
||||
|
||||
void muteHistory(History *history);
|
||||
void unmuteHistory(History *history);
|
||||
void writeAllMuted(QDataStream &stream);
|
||||
void readAllMuted(QDataStream &stream);
|
||||
void readOneMuted(QDataStream &stream);
|
||||
bool isPeerMuted(const PeerId &peer);
|
||||
|
||||
void checkImageCacheSize();
|
||||
|
||||
bool isValidPhone(QString phone);
|
||||
|
||||
void quit();
|
||||
bool quiting();
|
||||
void setQuiting();
|
||||
|
||||
|
||||
QImage readImage(QByteArray data, QByteArray *format = 0);
|
||||
QImage readImage(const QString &file, QByteArray *format = 0);
|
||||
|
||||
void regVideoItem(VideoData *data, HistoryItem *item);
|
||||
void unregVideoItem(VideoData *data, HistoryItem *item);
|
||||
const VideoItems &videoItems();
|
||||
|
||||
void regAudioItem(AudioData *data, HistoryItem *item);
|
||||
void unregAudioItem(AudioData*data, HistoryItem *item);
|
||||
const AudioItems &audioItems();
|
||||
|
||||
void regDocumentItem(DocumentData *data, HistoryItem *item);
|
||||
void unregDocumentItem(DocumentData *data, HistoryItem *item);
|
||||
const DocumentItems &documentItems();
|
||||
|
||||
void setProxySettings(QNetworkAccessManager &manager);
|
||||
void setProxySettings(QTcpSocket &socket);
|
||||
|
||||
};
|
644
Telegram/SourceFiles/application.cpp
Normal file
|
@ -0,0 +1,644 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
an unofficial desktop messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://tdesktop.com
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "application.h"
|
||||
#include "style.h"
|
||||
|
||||
#include "pspecific.h"
|
||||
#include "fileuploader.h"
|
||||
#include "mainwidget.h"
|
||||
#include "supporttl.h"
|
||||
|
||||
#include "lang.h"
|
||||
#include "boxes/confirmbox.h"
|
||||
#include "langloaderplain.h"
|
||||
|
||||
namespace {
|
||||
Application *mainApp = 0;
|
||||
FileUploader *uploader = 0;
|
||||
QString lng;
|
||||
|
||||
void mtpStateChanged(int32 dc, int32 state) {
|
||||
if (App::wnd()) {
|
||||
App::wnd()->mtpStateChanged(dc, state);
|
||||
}
|
||||
}
|
||||
|
||||
class _DebugWaiter : public QObject {
|
||||
public:
|
||||
|
||||
_DebugWaiter(QObject *parent) : QObject(parent), _debugState(0) {
|
||||
|
||||
}
|
||||
bool eventFilter(QObject *o, QEvent *e) {
|
||||
if (e->type() == QEvent::KeyPress) {
|
||||
QKeyEvent *ev = static_cast<QKeyEvent*>(e);
|
||||
switch (_debugState) {
|
||||
case 0: if (ev->key() == Qt::Key_F12) _debugState = 1; break;
|
||||
case 1: if (ev->key() == Qt::Key_F11) _debugState = 2; else if (ev->key() != Qt::Key_F12) _debugState = 0; break;
|
||||
case 2: if (ev->key() == Qt::Key_F10) _debugState = 3; else if (ev->key() != Qt::Key_F11) _debugState = 0; break;
|
||||
case 3: if (ev->key() == Qt::Key_F11) _debugState = 4; else if (ev->key() != Qt::Key_F10) _debugState = 0; break;
|
||||
case 4: if (ev->key() == Qt::Key_F12) offerDebug(); if (ev->key() != Qt::Key_F11) _debugState = 0; break;
|
||||
}
|
||||
}
|
||||
return QObject::eventFilter(o, e);
|
||||
}
|
||||
void offerDebug() {
|
||||
ConfirmBox *box = new ConfirmBox(lang(lng_sure_enable_debug));
|
||||
connect(box, SIGNAL(confirmed()), App::app(), SLOT(onEnableDebugMode()));
|
||||
App::wnd()->showLayer(box);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
int _debugState;
|
||||
};
|
||||
}
|
||||
|
||||
Application::Application(int argc, char *argv[]) : PsApplication(argc, argv),
|
||||
serverName(psServerPrefix() + cGUIDStr()), closing(false),
|
||||
updateRequestId(0), updateThread(0), updateDownloader(0), updateReply(0) {
|
||||
if (mainApp) {
|
||||
DEBUG_LOG(("Application Error: another Application was created, terminating.."));
|
||||
exit(0);
|
||||
}
|
||||
mainApp = this;
|
||||
|
||||
installEventFilter(new _DebugWaiter(this));
|
||||
|
||||
QFontDatabase::addApplicationFont(qsl(":/gui/art/segoe_ui.ttf"));
|
||||
QFontDatabase::addApplicationFont(qsl(":/gui/art/segoe_ui_semibold.ttf"));
|
||||
QFontDatabase::addApplicationFont(qsl(":/gui/art/segoe_wp_semibold.ttf"));
|
||||
QFontDatabase::addApplicationFont(qsl(":/gui/art/ThoolikaTrditionalUnicode.ttf"));
|
||||
|
||||
float64 dpi = primaryScreen()->logicalDotsPerInch();
|
||||
if (dpi <= 108) { // 0-96-108
|
||||
cSetScreenScale(dbisOne);
|
||||
} else if (dpi <= 132) { // 108-120-132
|
||||
cSetScreenScale(dbisOneAndQuarter);
|
||||
} else if (dpi <= 168) { // 132-144-168
|
||||
cSetScreenScale(dbisOneAndHalf);
|
||||
} else { // 168-192-inf
|
||||
cSetScreenScale(dbisTwo);
|
||||
}
|
||||
|
||||
if (!cLangFile().isEmpty()) {
|
||||
LangLoaderPlain loader(cLangFile());
|
||||
if (!loader.errors().isEmpty()) {
|
||||
LOG(("Lang load errors: %1").arg(loader.errors()));
|
||||
} else if (!loader.warnings().isEmpty()) {
|
||||
LOG(("Lang load warnings: %1").arg(loader.warnings()));
|
||||
}
|
||||
}
|
||||
|
||||
style::startManager();
|
||||
anim::startManager();
|
||||
historyInit();
|
||||
|
||||
window = new Window();
|
||||
|
||||
psInstallEventFilter();
|
||||
|
||||
updateCheckTimer.setSingleShot(true);
|
||||
|
||||
connect(&socket, SIGNAL(connected()), this, SLOT(socketConnected()));
|
||||
connect(&socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));
|
||||
connect(&socket, SIGNAL(error(QLocalSocket::LocalSocketError)), this, SLOT(socketError(QLocalSocket::LocalSocketError)));
|
||||
connect(&socket, SIGNAL(bytesWritten(qint64)), this, SLOT(socketWritten(qint64)));
|
||||
connect(&socket, SIGNAL(readyRead()), this, SLOT(socketReading()));
|
||||
connect(&server, SIGNAL(newConnection()), this, SLOT(newInstanceConnected()));
|
||||
connect(this, SIGNAL(aboutToQuit()), this, SLOT(closeApplication()));
|
||||
connect(&updateCheckTimer, SIGNAL(timeout()), this, SLOT(startUpdateCheck()));
|
||||
connect(this, SIGNAL(updateFailed()), this, SLOT(onUpdateFailed()));
|
||||
connect(this, SIGNAL(updateReady()), this, SLOT(onUpdateReady()));
|
||||
connect(&writeUserConfigTimer, SIGNAL(timeout()), this, SLOT(onWriteUserConfig()));
|
||||
writeUserConfigTimer.setSingleShot(true);
|
||||
|
||||
if (cManyInstance()) {
|
||||
startApp();
|
||||
} else {
|
||||
DEBUG_LOG(("Application Info: connecting local socket to %1..").arg(serverName));
|
||||
socket.connectToServer(serverName);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::onAppUpdate(const MTPhelp_AppUpdate &response) {
|
||||
updateRequestId = 0;
|
||||
cSetLastUpdateCheck(unixtime());
|
||||
App::writeConfig();
|
||||
if (response.type() == mtpc_help_noAppUpdate) {
|
||||
startUpdateCheck();
|
||||
} else {
|
||||
updateThread = new QThread();
|
||||
updateDownloader = new PsUpdateDownloader(updateThread, response.c_help_appUpdate());
|
||||
updateThread->start();
|
||||
}
|
||||
}
|
||||
|
||||
bool Application::onAppUpdateFail() {
|
||||
updateRequestId = 0;
|
||||
cSetLastUpdateCheck(unixtime());
|
||||
App::writeConfig();
|
||||
startUpdateCheck();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Application::updateGotCurrent() {
|
||||
if (!updateReply || updateThread) return;
|
||||
|
||||
cSetLastUpdateCheck(unixtime());
|
||||
QRegularExpressionMatch m = QRegularExpression(qsl("^\\s*(\\d+)\\s*:\\s*([\\x21-\\x7f]+)\\s*$")).match(QString::fromUtf8(updateReply->readAll()));
|
||||
if (m.hasMatch()) {
|
||||
int32 currentVersion = m.captured(1).toInt();
|
||||
if (currentVersion > AppVersion) {
|
||||
updateThread = new QThread();
|
||||
updateDownloader = new PsUpdateDownloader(updateThread, m.captured(2));
|
||||
updateThread->start();
|
||||
}
|
||||
}
|
||||
if (updateReply) updateReply->deleteLater();
|
||||
updateReply = 0;
|
||||
if (!updateThread) {
|
||||
QDir updates(cWorkingDir() + "tupdates");
|
||||
if (updates.exists()) {
|
||||
QFileInfoList list = updates.entryInfoList(QDir::Files);
|
||||
for (QFileInfoList::iterator i = list.begin(), e = list.end(); i != e; ++i) {
|
||||
if (QRegularExpression("^tupdate\\d+$", QRegularExpression::CaseInsensitiveOption).match(i->fileName()).hasMatch()) {
|
||||
QFile(i->absoluteFilePath()).remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
emit updateLatest();
|
||||
}
|
||||
startUpdateCheck(true);
|
||||
}
|
||||
|
||||
void Application::updateFailedCurrent(QNetworkReply::NetworkError e) {
|
||||
LOG(("App Error: could not get current version (update check): %1").arg(e));
|
||||
if (updateReply) updateReply->deleteLater();
|
||||
updateReply = 0;
|
||||
|
||||
emit updateFailed();
|
||||
startUpdateCheck(true);
|
||||
}
|
||||
|
||||
void Application::onUpdateReady() {
|
||||
if (updateDownloader) {
|
||||
updateDownloader->deleteLater();
|
||||
updateDownloader = 0;
|
||||
}
|
||||
updateCheckTimer.stop();
|
||||
|
||||
cSetLastUpdateCheck(unixtime());
|
||||
App::writeConfig();
|
||||
}
|
||||
|
||||
void Application::onUpdateFailed() {
|
||||
if (updateDownloader) {
|
||||
updateDownloader->deleteLater();
|
||||
updateDownloader = 0;
|
||||
if (updateThread) updateThread->deleteLater();
|
||||
updateThread = 0;
|
||||
}
|
||||
|
||||
cSetLastUpdateCheck(unixtime());
|
||||
App::writeConfig();
|
||||
}
|
||||
|
||||
void Application::regPhotoUpdate(const PeerId &peer, MsgId msgId) {
|
||||
photoUpdates.insert(msgId, peer);
|
||||
}
|
||||
|
||||
void Application::clearPhotoUpdates() {
|
||||
photoUpdates.clear();
|
||||
}
|
||||
|
||||
bool Application::isPhotoUpdating(const PeerId &peer) {
|
||||
for (QMap<MsgId, PeerId>::iterator i = photoUpdates.begin(), e = photoUpdates.end(); i != e; ++i) {
|
||||
if (i.value() == peer) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Application::cancelPhotoUpdate(const PeerId &peer) {
|
||||
for (QMap<MsgId, PeerId>::iterator i = photoUpdates.begin(), e = photoUpdates.end(); i != e;) {
|
||||
if (i.value() == peer) {
|
||||
i = photoUpdates.erase(i);
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Application::selfPhotoCleared(const MTPUserProfilePhoto &result) {
|
||||
if (!App::self()) return;
|
||||
App::self()->setPhoto(result);
|
||||
emit peerPhotoDone(App::self()->id);
|
||||
}
|
||||
|
||||
void Application::chatPhotoCleared(PeerId peer, const MTPmessages_StatedMessage &result) {
|
||||
if (App::main()) {
|
||||
App::main()->sentFullDataReceived(0, result);
|
||||
}
|
||||
cancelPhotoUpdate(peer);
|
||||
emit peerPhotoDone(peer);
|
||||
}
|
||||
|
||||
void Application::selfPhotoDone(const MTPphotos_Photo &result) {
|
||||
if (!App::self()) return;
|
||||
const MTPDphotos_photo &photo(result.c_photos_photo());
|
||||
App::feedPhoto(photo.vphoto);
|
||||
App::feedUsers(photo.vusers);
|
||||
cancelPhotoUpdate(App::self()->id);
|
||||
emit peerPhotoDone(App::self()->id);
|
||||
}
|
||||
|
||||
void Application::chatPhotoDone(PeerId peer, const MTPmessages_StatedMessage &result) {
|
||||
if (App::main()) {
|
||||
App::main()->sentFullDataReceived(0, result);
|
||||
}
|
||||
cancelPhotoUpdate(peer);
|
||||
emit peerPhotoDone(peer);
|
||||
}
|
||||
|
||||
bool Application::peerPhotoFail(PeerId peer, const RPCError &e) {
|
||||
LOG(("Application Error: update photo failed %1: %2").arg(e.type()).arg(e.description()));
|
||||
cancelPhotoUpdate(peer);
|
||||
emit peerPhotoFail(peer);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Application::peerClearPhoto(PeerId peer) {
|
||||
if (App::self() && App::self()->id == peer) {
|
||||
MTP::send(MTPphotos_UpdateProfilePhoto(MTP_inputPhotoEmpty(), MTP_inputPhotoCropAuto()), rpcDone(&Application::selfPhotoCleared), rpcFail(&Application::peerPhotoFail, peer));
|
||||
} else {
|
||||
MTP::send(MTPmessages_EditChatPhoto(MTP_int(int32(peer & 0xFFFFFFFF)), MTP_inputChatPhotoEmpty()), rpcDone(&Application::chatPhotoCleared, peer), rpcFail(&Application::peerPhotoFail, peer));
|
||||
}
|
||||
}
|
||||
|
||||
void Application::writeUserConfigIn(uint64 ms) {
|
||||
if (!writeUserConfigTimer.isActive()) {
|
||||
writeUserConfigTimer.start(ms);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::onWriteUserConfig() {
|
||||
App::writeUserConfig();
|
||||
}
|
||||
|
||||
void Application::photoUpdated(MsgId msgId, const MTPInputFile &file) {
|
||||
if (!App::self()) return;
|
||||
|
||||
QMap<MsgId, PeerId>::iterator i = photoUpdates.find(msgId);
|
||||
if (i != photoUpdates.end()) {
|
||||
PeerId peer = i.value();
|
||||
if (peer == App::self()->id) {
|
||||
MTP::send(MTPphotos_UploadProfilePhoto(file, MTP_string(""), MTP_inputGeoPointEmpty(), MTP_inputPhotoCrop(MTP_double(0), MTP_double(0), MTP_double(100))), rpcDone(&Application::selfPhotoDone), rpcFail(&Application::peerPhotoFail, peer));
|
||||
} else {
|
||||
MTP::send(MTPmessages_EditChatPhoto(MTP_int(peer & 0xFFFFFFFF), MTP_inputChatUploadedPhoto(file, MTP_inputPhotoCrop(MTP_double(0), MTP_double(0), MTP_double(100)))), rpcDone(&Application::chatPhotoDone, peer), rpcFail(&Application::peerPhotoFail, peer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Application::onEnableDebugMode() {
|
||||
if (!cDebug()) {
|
||||
logsInitDebug();
|
||||
cSetDebug(true);
|
||||
}
|
||||
App::wnd()->hideLayer();
|
||||
}
|
||||
|
||||
Application::UpdatingState Application::updatingState() {
|
||||
if (!updateThread) return Application::UpdatingNone;
|
||||
if (!updateDownloader) return Application::UpdatingReady;
|
||||
return Application::UpdatingDownload;
|
||||
}
|
||||
|
||||
int32 Application::updatingSize() {
|
||||
if (!updateDownloader) return 0;
|
||||
return updateDownloader->size();
|
||||
}
|
||||
|
||||
int32 Application::updatingReady() {
|
||||
if (!updateDownloader) return 0;
|
||||
return updateDownloader->ready();
|
||||
}
|
||||
|
||||
FileUploader *Application::uploader() {
|
||||
if (!::uploader) ::uploader = new FileUploader();
|
||||
return ::uploader;
|
||||
}
|
||||
|
||||
void Application::uploadProfilePhoto(const QImage &tosend, const PeerId &peerId) {
|
||||
PreparedPhotoThumbs photoThumbs;
|
||||
QVector<MTPPhotoSize> photoSizes;
|
||||
|
||||
QPixmap thumb = QPixmap::fromImage(tosend.scaled(160, 160, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||||
photoThumbs.insert('a', thumb);
|
||||
photoSizes.push_back(MTP_photoSize(MTP_string("a"), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(thumb.width()), MTP_int(thumb.height()), MTP_int(0)));
|
||||
|
||||
QPixmap full = QPixmap::fromImage(tosend);
|
||||
photoThumbs.insert('c', full);
|
||||
photoSizes.push_back(MTP_photoSize(MTP_string("c"), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(full.width()), MTP_int(full.height()), MTP_int(0)));
|
||||
|
||||
QByteArray jpeg;
|
||||
QBuffer jpegBuffer(&jpeg);
|
||||
full.save(&jpegBuffer, "JPG", 87);
|
||||
|
||||
PhotoId id = MTP::nonce<PhotoId>();
|
||||
|
||||
MTPPhoto photo(MTP_photo(MTP_long(id), MTP_long(0), MTP_int(MTP::authedId()), MTP_int(unixtime()), MTP_string(""), MTP_geoPointEmpty(), MTP_vector<MTPPhotoSize>(photoSizes)));
|
||||
|
||||
QString file, filename;
|
||||
int32 filesize = 0;
|
||||
QByteArray data;
|
||||
|
||||
ReadyLocalMedia ready(ToPreparePhoto, file, filename, filesize, data, id, id, peerId, photo, photoThumbs, MTP_documentEmpty(MTP_long(0)), jpeg);
|
||||
|
||||
connect(App::uploader(), SIGNAL(photoReady(MsgId, const MTPInputFile &)), App::app(), SLOT(photoUpdated(MsgId, const MTPInputFile &)), Qt::UniqueConnection);
|
||||
|
||||
MsgId newId = clientMsgId();
|
||||
App::app()->regPhotoUpdate(peerId, newId);
|
||||
App::uploader()->uploadMedia(newId, ready);
|
||||
}
|
||||
|
||||
void Application::stopUpdate() {
|
||||
if (updateReply) {
|
||||
updateReply->abort();
|
||||
updateReply->deleteLater();
|
||||
updateReply = 0;
|
||||
}
|
||||
if (updateDownloader) {
|
||||
updateDownloader->deleteLater();
|
||||
updateDownloader = 0;
|
||||
if (updateThread) updateThread->deleteLater();
|
||||
updateThread = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Application::startUpdateCheck(bool forceWait) {
|
||||
updateCheckTimer.stop();
|
||||
if (updateRequestId || updateThread || updateReply || !cAutoUpdate()) return;
|
||||
|
||||
int32 updateInSecs = cLastUpdateCheck() + 3600 + (rand() % 3600) - unixtime();
|
||||
bool sendRequest = (updateInSecs <= 0 || updateInSecs > 7200);
|
||||
if (!sendRequest && !forceWait) {
|
||||
QDir updates(cWorkingDir() + "tupdates");
|
||||
if (updates.exists()) {
|
||||
QFileInfoList list = updates.entryInfoList(QDir::Files);
|
||||
for (QFileInfoList::iterator i = list.begin(), e = list.end(); i != e; ++i) {
|
||||
if (QRegularExpression("^tupdate\\d+$", QRegularExpression::CaseInsensitiveOption).match(i->fileName()).hasMatch()) {
|
||||
sendRequest = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cManyInstance() && !cDebug()) return; // only main instance is updating
|
||||
|
||||
if (sendRequest) {
|
||||
QNetworkRequest checkVersion(QUrl(qsl("http://tdesktop.com/win/tupdates/current")));
|
||||
if (updateReply) updateReply->deleteLater();
|
||||
|
||||
App::setProxySettings(updateManager);
|
||||
updateReply = updateManager.get(checkVersion);
|
||||
connect(updateReply, SIGNAL(finished()), this, SLOT(updateGotCurrent()));
|
||||
connect(updateReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(updateFailedCurrent(QNetworkReply::NetworkError)));
|
||||
// updateRequestId = MTP::send(MTPhelp_GetAppUpdate(MTP_string(cApiDeviceModel()), MTP_string(cApiSystemVersion()), MTP_string(cApiAppVersion()), MTP_string(cApiLang())), rpcDone(&Application::onAppUpdate), rpcFail(&Application::onAppUpdateFail);
|
||||
emit updateChecking();
|
||||
} else {
|
||||
updateCheckTimer.start((updateInSecs + 5) * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::socketConnected() {
|
||||
DEBUG_LOG(("Application Info: socket connected, this is not the first application instance, sending show command.."));
|
||||
closing = true;
|
||||
socket.write("CMD:show;");
|
||||
}
|
||||
|
||||
void Application::socketWritten(qint64/* bytes*/) {
|
||||
if (socket.state() != QLocalSocket::ConnectedState) {
|
||||
DEBUG_LOG(("Application Error: socket is not connected %1").arg(socket.state()));
|
||||
return;
|
||||
}
|
||||
if (socket.bytesToWrite()) {
|
||||
return;
|
||||
}
|
||||
DEBUG_LOG(("Application Info: show command written, waiting response.."));
|
||||
}
|
||||
|
||||
void Application::socketReading() {
|
||||
if (socket.state() != QLocalSocket::ConnectedState) {
|
||||
DEBUG_LOG(("Application Error: socket is not connected %1").arg(socket.state()));
|
||||
return;
|
||||
}
|
||||
socketRead.append(socket.readAll());
|
||||
if (QRegularExpression("RES:(\\d+);").match(socketRead).hasMatch()) {
|
||||
uint64 pid = socketRead.mid(4, socketRead.length() - 5).toULongLong();
|
||||
psActivateProcess(pid);
|
||||
DEBUG_LOG(("Application Info: show command response received, pid = %1, activating and quiting..").arg(pid));
|
||||
return App::quit();
|
||||
}
|
||||
}
|
||||
|
||||
void Application::socketError(QLocalSocket::LocalSocketError e) {
|
||||
if (closing) {
|
||||
DEBUG_LOG(("Application Error: could not write show command, error %1, quiting..").arg(e));
|
||||
return App::quit();
|
||||
}
|
||||
|
||||
if (e == QLocalSocket::ServerNotFoundError) {
|
||||
DEBUG_LOG(("Application Info: this is the only instance of Telegram, starting server and app.."));
|
||||
} else {
|
||||
DEBUG_LOG(("Application Info: socket connect error %1, starting server and app..").arg(e));
|
||||
}
|
||||
socket.close();
|
||||
|
||||
psCheckLocalSocket(serverName);
|
||||
|
||||
if (!server.listen(serverName)) {
|
||||
DEBUG_LOG(("Application Error: failed to start listening to %1 server").arg(serverName));
|
||||
return App::quit();
|
||||
}
|
||||
|
||||
if (!cNoStartUpdate() && psCheckReadyUpdate()) {
|
||||
cSetRestartingUpdate(true);
|
||||
DEBUG_LOG(("Application Info: installing update instead of starting app.."));
|
||||
return App::quit();
|
||||
}
|
||||
|
||||
startApp();
|
||||
}
|
||||
|
||||
void Application::startApp() {
|
||||
App::readUserConfig();
|
||||
if (!MTP::localKey().created()) {
|
||||
MTP::createLocalKey(QByteArray());
|
||||
cSetNeedConfigResave(true);
|
||||
}
|
||||
if (cNeedConfigResave()) {
|
||||
App::writeConfig();
|
||||
App::writeUserConfig();
|
||||
cSetNeedConfigResave(false);
|
||||
}
|
||||
|
||||
window->createWinId();
|
||||
window->init();
|
||||
|
||||
readSupportTemplates();
|
||||
|
||||
MTP::setLayer(mtpLayerMax);
|
||||
MTP::start();
|
||||
|
||||
MTP::setStateChangedHandler(mtpStateChanged);
|
||||
|
||||
App::initMedia();
|
||||
|
||||
if (MTP::authedId()) {
|
||||
window->setupMain(false);
|
||||
} else {
|
||||
window->setupIntro(false);
|
||||
}
|
||||
|
||||
window->psFirstShow();
|
||||
|
||||
if (cStartToSettings()) {
|
||||
window->showSettings();
|
||||
}
|
||||
|
||||
QNetworkProxyFactory::setUseSystemConfiguration(true);
|
||||
}
|
||||
|
||||
void Application::socketDisconnected() {
|
||||
if (closing) {
|
||||
DEBUG_LOG(("Application Error: socket disconnected before command response received, quiting.."));
|
||||
return App::quit();
|
||||
}
|
||||
}
|
||||
|
||||
void Application::newInstanceConnected() {
|
||||
DEBUG_LOG(("Application Info: new local socket connected"));
|
||||
for (QLocalSocket *client = server.nextPendingConnection(); client; client = server.nextPendingConnection()) {
|
||||
clients.push_back(ClientSocket(client, QByteArray()));
|
||||
connect(client, SIGNAL(readyRead()), this, SLOT(readClients()));
|
||||
connect(client, SIGNAL(disconnected()), this, SLOT(removeClients()));
|
||||
}
|
||||
}
|
||||
|
||||
void Application::readClients() {
|
||||
for (ClientSockets::iterator i = clients.begin(), e = clients.end(); i != e; ++i) {
|
||||
i->second.append(i->first->readAll());
|
||||
if (i->second.size()) {
|
||||
QString cmds(i->second);
|
||||
int32 from = 0, l = cmds.length();
|
||||
for (int32 to = cmds.indexOf(QChar(';'), from); to >= from; to = (from < l) ? cmds.indexOf(QChar(';'), from) : -1) {
|
||||
QStringRef cmd(&cmds, from, to - from);
|
||||
if (cmd.indexOf("CMD:") == 0) {
|
||||
execExternal(cmds.mid(from + 4, to - from - 4));
|
||||
QByteArray response(QString("RES:%1;").arg(QCoreApplication::applicationPid()).toUtf8());
|
||||
i->first->write(response.data(), response.size());
|
||||
} else {
|
||||
LOG(("Application Error: unknown command %1 passed in local socket").arg(QString(cmd.constData(), cmd.length())));
|
||||
}
|
||||
from = to + 1;
|
||||
}
|
||||
if (from > 0) {
|
||||
i->second = i->second.mid(from);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Application::removeClients() {
|
||||
DEBUG_LOG(("Application Info: remove clients slot called, clients %1").arg(clients.size()));
|
||||
for (ClientSockets::iterator i = clients.begin(), e = clients.end(); i != e;) {
|
||||
if (i->first->state() != QLocalSocket::ConnectedState) {
|
||||
DEBUG_LOG(("Application Info: removing client"));
|
||||
i = clients.erase(i);
|
||||
e = clients.end();
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Application::execExternal(const QString &cmd) {
|
||||
DEBUG_LOG(("Application Info: executing external command '%1'").arg(cmd));
|
||||
if (cmd == "show") {
|
||||
window->activate();
|
||||
}
|
||||
}
|
||||
|
||||
void Application::closeApplication() {
|
||||
// close server
|
||||
server.close();
|
||||
for (ClientSockets::iterator i = clients.begin(), e = clients.end(); i != e; ++i) {
|
||||
disconnect(i->first, SIGNAL(disconnected()), this, SLOT(removeClients()));
|
||||
i->first->close();
|
||||
}
|
||||
clients.clear();
|
||||
|
||||
MTP::stop();
|
||||
}
|
||||
|
||||
Application::~Application() {
|
||||
App::setQuiting();
|
||||
window->setParent(0);
|
||||
|
||||
anim::stopManager();
|
||||
|
||||
socket.close();
|
||||
closeApplication();
|
||||
App::deinitMedia();
|
||||
mainApp = 0;
|
||||
delete updateReply;
|
||||
delete ::uploader;
|
||||
updateReply = 0;
|
||||
delete updateDownloader;
|
||||
updateDownloader = 0;
|
||||
delete updateThread;
|
||||
updateThread = 0;
|
||||
|
||||
delete window;
|
||||
|
||||
style::stopManager();
|
||||
}
|
||||
|
||||
Application *Application::app() {
|
||||
return mainApp;
|
||||
}
|
||||
|
||||
Window *Application::wnd() {
|
||||
return mainApp ? mainApp->window : 0;
|
||||
}
|
||||
|
||||
QString Application::lang() {
|
||||
if (!lng.length()) {
|
||||
lng = psCurrentLanguage();
|
||||
}
|
||||
if (!lng.length()) {
|
||||
lng = "en";
|
||||
}
|
||||
return lng;
|
||||
}
|
||||
|
||||
MainWidget *Application::main() {
|
||||
return mainApp ? mainApp->window->mainWidget() : 0;
|
||||
}
|
132
Telegram/SourceFiles/application.h
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
an unofficial desktop messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://tdesktop.com
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <QtNetwork/QLocalSocket>
|
||||
#include <QtNetwork/QLocalServer>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
|
||||
#include "window.h"
|
||||
#include "pspecific.h"
|
||||
|
||||
class MainWidget;
|
||||
class FileUploader;
|
||||
|
||||
class Application : public PsApplication, public RPCSender {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
Application(int argc, char *argv[]);
|
||||
~Application();
|
||||
|
||||
static Application *app();
|
||||
static Window *wnd();
|
||||
static QString lang();
|
||||
static MainWidget *main();
|
||||
|
||||
void onAppUpdate(const MTPhelp_AppUpdate &response);
|
||||
bool onAppUpdateFail();
|
||||
|
||||
enum UpdatingState {
|
||||
UpdatingNone,
|
||||
UpdatingDownload,
|
||||
UpdatingReady,
|
||||
};
|
||||
UpdatingState updatingState();
|
||||
int32 updatingSize();
|
||||
int32 updatingReady();
|
||||
|
||||
FileUploader *uploader();
|
||||
void uploadProfilePhoto(const QImage &tosend, const PeerId &peerId);
|
||||
void regPhotoUpdate(const PeerId &peer, MsgId msgId);
|
||||
void clearPhotoUpdates();
|
||||
bool isPhotoUpdating(const PeerId &peer);
|
||||
void cancelPhotoUpdate(const PeerId &peer);
|
||||
|
||||
void stopUpdate();
|
||||
|
||||
void selfPhotoCleared(const MTPUserProfilePhoto &result);
|
||||
void chatPhotoCleared(PeerId peer, const MTPmessages_StatedMessage &result);
|
||||
void selfPhotoDone(const MTPphotos_Photo &result);
|
||||
void chatPhotoDone(PeerId peerId, const MTPmessages_StatedMessage &rersult);
|
||||
bool peerPhotoFail(PeerId peerId, const RPCError &e);
|
||||
void peerClearPhoto(PeerId peer);
|
||||
|
||||
void writeUserConfigIn(uint64 ms);
|
||||
|
||||
signals:
|
||||
|
||||
void peerPhotoDone(PeerId peer);
|
||||
void peerPhotoFail(PeerId peer);
|
||||
|
||||
public slots:
|
||||
|
||||
void startUpdateCheck(bool forceWait = false);
|
||||
void socketConnected();
|
||||
void socketError(QLocalSocket::LocalSocketError e);
|
||||
void socketDisconnected();
|
||||
void socketWritten(qint64 bytes);
|
||||
void socketReading();
|
||||
void newInstanceConnected();
|
||||
void closeApplication();
|
||||
|
||||
void readClients();
|
||||
void removeClients();
|
||||
|
||||
void updateGotCurrent();
|
||||
void updateFailedCurrent(QNetworkReply::NetworkError e);
|
||||
|
||||
void onUpdateReady();
|
||||
void onUpdateFailed();
|
||||
|
||||
void photoUpdated(MsgId msgId, const MTPInputFile &file);
|
||||
|
||||
void onEnableDebugMode();
|
||||
void onWriteUserConfig();
|
||||
|
||||
private:
|
||||
|
||||
QMap<MsgId, PeerId> photoUpdates;
|
||||
|
||||
void startApp();
|
||||
|
||||
typedef QPair<QLocalSocket*, QByteArray> ClientSocket;
|
||||
typedef QVector<ClientSocket> ClientSockets;
|
||||
|
||||
QString serverName;
|
||||
QLocalSocket socket;
|
||||
QString socketRead;
|
||||
QLocalServer server;
|
||||
ClientSockets clients;
|
||||
bool closing;
|
||||
|
||||
void execExternal(const QString &cmd);
|
||||
|
||||
Window *window;
|
||||
|
||||
mtpRequestId updateRequestId;
|
||||
QNetworkAccessManager updateManager;
|
||||
QNetworkReply *updateReply;
|
||||
QTimer updateCheckTimer;
|
||||
QThread *updateThread;
|
||||
PsUpdateDownloader *updateDownloader;
|
||||
|
||||
QTimer writeUserConfigTimer;
|
||||
|
||||
};
|
BIN
Telegram/SourceFiles/art/Emoji/002320E3.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/SourceFiles/art/Emoji/003020E3.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/SourceFiles/art/Emoji/003120E3.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Telegram/SourceFiles/art/Emoji/003220E3.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/SourceFiles/art/Emoji/003320E3.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/SourceFiles/art/Emoji/003420E3.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Telegram/SourceFiles/art/Emoji/003520E3.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/SourceFiles/art/Emoji/003620E3.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/SourceFiles/art/Emoji/003720E3.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Telegram/SourceFiles/art/Emoji/003820E3.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/SourceFiles/art/Emoji/003920E3.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/SourceFiles/art/Emoji/00A9.png
Normal file
After Width: | Height: | Size: 706 B |
BIN
Telegram/SourceFiles/art/Emoji/00AE.png
Normal file
After Width: | Height: | Size: 688 B |
BIN
Telegram/SourceFiles/art/Emoji/203C.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Telegram/SourceFiles/art/Emoji/2049.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/SourceFiles/art/Emoji/2122.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Telegram/SourceFiles/art/Emoji/2139.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/SourceFiles/art/Emoji/2194.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Telegram/SourceFiles/art/Emoji/2195.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/SourceFiles/art/Emoji/2196.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/SourceFiles/art/Emoji/2197.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/SourceFiles/art/Emoji/2198.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/SourceFiles/art/Emoji/2199.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/SourceFiles/art/Emoji/21A9.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/SourceFiles/art/Emoji/21AA.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/SourceFiles/art/Emoji/231A.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Telegram/SourceFiles/art/Emoji/231B.png
Normal file
After Width: | Height: | Size: 856 B |
BIN
Telegram/SourceFiles/art/Emoji/23E9.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/SourceFiles/art/Emoji/23EA.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Telegram/SourceFiles/art/Emoji/23EB.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/SourceFiles/art/Emoji/23EC.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/SourceFiles/art/Emoji/23F0.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
Telegram/SourceFiles/art/Emoji/23F3.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Telegram/SourceFiles/art/Emoji/24C2.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
Telegram/SourceFiles/art/Emoji/25AA.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Telegram/SourceFiles/art/Emoji/25AB.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Telegram/SourceFiles/art/Emoji/25B6.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Telegram/SourceFiles/art/Emoji/25C0.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Telegram/SourceFiles/art/Emoji/25FB.png
Normal file
After Width: | Height: | Size: 515 B |
BIN
Telegram/SourceFiles/art/Emoji/25FC.png
Normal file
After Width: | Height: | Size: 560 B |
BIN
Telegram/SourceFiles/art/Emoji/25FD.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Telegram/SourceFiles/art/Emoji/25FE.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Telegram/SourceFiles/art/Emoji/2600.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Telegram/SourceFiles/art/Emoji/2601.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/SourceFiles/art/Emoji/260E.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Telegram/SourceFiles/art/Emoji/2611.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/SourceFiles/art/Emoji/2614.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
Telegram/SourceFiles/art/Emoji/2615.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
Telegram/SourceFiles/art/Emoji/261D.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Telegram/SourceFiles/art/Emoji/263A.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
Telegram/SourceFiles/art/Emoji/2648.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Telegram/SourceFiles/art/Emoji/2649.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Telegram/SourceFiles/art/Emoji/264A.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/SourceFiles/art/Emoji/264B.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
Telegram/SourceFiles/art/Emoji/264C.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Telegram/SourceFiles/art/Emoji/264D.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/SourceFiles/art/Emoji/264E.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/SourceFiles/art/Emoji/264F.png
Normal file
After Width: | Height: | Size: 1.3 KiB |