Merge branch 'master' into dev

Conflicts:
	Telegram/SourceFiles/history/history.style
This commit is contained in:
John Preston 2016-07-08 13:26:28 +03:00
commit 2aa35af909
63 changed files with 2063 additions and 660 deletions

View file

@ -4,9 +4,9 @@ Thanks for reporting issues of Telegram Desktop!
To make it easier for us to help you please enter detailed information below. To make it easier for us to help you please enter detailed information below.
--> -->
### Steps to reproduce ### Steps to reproduce
1. 1.
2. 2.
3. 3.
### Expected behaviour ### Expected behaviour
Tell us what should happen Tell us what should happen
@ -22,5 +22,5 @@ Tell us what happens instead
### Logs ### Logs
Insert logs here (if necessary) Insert logs here (if necessary)
You can type "debugmode" in settings and then see ~/.TelegramDesktop/DebugLogs/log_...txt for log files. You can type `debugmode` in settings and then see ~/.TelegramDesktop/DebugLogs/log_...txt for log files.
Type "debugmode" in settings again to disable logs. Type `debugmode` in settings again to disable logs.

View file

@ -3,14 +3,24 @@ sudo: required
language: cpp language: cpp
env: env:
- BUILD_VERSION="" global:
- BUILD_VERSION="disable_autoupdate" # GitHub auth token (GH_AUTH_TOKEN)
- BUILD_VERSION="disable_register_custom_scheme" - secure: "QBbD9VXAx3Mn0vFmHZtm6/sq+twMyR7ilQh7TQm8gBy2TrjhHKDKQ4wRQ5sa2MUFUbzrUOvPlPGq1WuY1mAUt8UE6jZDJNyyDWb6iIlcEmNRsd39XAhYHvJ+uI9JsD+U3OctZ+7Bo4fno0RLv1D5lzh5bpohmjgWxx9TiSZItbsRU+m0XM0Tahx335aXF8NFoVjheGXCOcLAXDt6OmaKPmlrXreuta5nOoRKeOg5vHlt/KNU1pYb8MFvWJc14DKxq3jNqrYlo9vHFv5tVhR1aqvVFWTD/4Z88OSxx3POzyVWdMso0lFov9uxs8qHoqLsGhDMElggyz/jnqZIHpwQMaYIGQ0LLYDv21jGgOuCOWKYlfjDY+tuESXmVPzerTlYBWLZDPrpE8BnXVYo8B/sF4WN6oCuBRjawlqYhqTH+tDDORc9Uc9pamhcuh6OsLMx3PHoyg8joN3t8yUnwhySXyfQ36hqlZ+Y4bBDRZBH/SB/EPmedyLGwdhzQFsUnOBotYeOym7LUdnGraGcj1iTPLdo5TMlBYlAiB12J5mHTNuzUKXh+PBV4REg4Mm2xYX+Pue5Qo1JcOWJteIX4BdPv526DXB3yaNWS1pZgGvYqtBwQlCeOfwOYupS0PksvmV7aX7c4qJSyW3dmEd03cxmebD0b2SbqyPxGFuUajJ7B60="
- BUILD_VERSION="disable_crash_reports" matrix:
- BUILD_VERSION="disable_network_proxy" - BUILD_VERSION=""
- BUILD_VERSION="disable_desktop_file_generation" - BUILD_VERSION="disable_autoupdate"
- BUILD_VERSION="disable_register_custom_scheme"
- BUILD_VERSION="disable_crash_reports"
- BUILD_VERSION="disable_network_proxy"
- BUILD_VERSION="disable_desktop_file_generation"
- BUILD_VERSION="disable_unity_integration"
matrix:
fast_finish: true
arch: arch:
repos:
- home_ItachiSan_archlinux_Arch_Extra=http://download.opensuse.org/repositories/home:/ItachiSan:/archlinux/Arch_Extra/$arch
packages: packages:
- bzr - bzr
- wget - wget
@ -18,7 +28,7 @@ arch:
- git - git
- patch - patch
- dee-fixed - home_ItachiSan_archlinux_Arch_Extra/dee # Use fixed dee version (See #2005)
- libunity - libunity
- libappindicator-gtk2 - libappindicator-gtk2

View file

@ -83,6 +83,10 @@ prepare() {
options+="\nDEFINES += TDESKTOP_DISABLE_DESKTOP_FILE_GENERATION" options+="\nDEFINES += TDESKTOP_DISABLE_DESKTOP_FILE_GENERATION"
fi fi
if [[ $BUILD_VERSION == *"disable_unity_integration"* ]]; then
options+="\nDEFINES += TDESKTOP_DISABLE_UNITY_INTEGRATION"
fi
options+='\nINCLUDEPATH += "/usr/lib/glib-2.0/include"' options+='\nINCLUDEPATH += "/usr/lib/glib-2.0/include"'
options+='\nINCLUDEPATH += "/usr/lib/gtk-2.0/include"' options+='\nINCLUDEPATH += "/usr/lib/gtk-2.0/include"'
options+='\nINCLUDEPATH += "/usr/include/opus"' options+='\nINCLUDEPATH += "/usr/include/opus"'
@ -104,7 +108,7 @@ build() {
cd "$srcdir/Libraries/qt${_qtver}" cd "$srcdir/Libraries/qt${_qtver}"
./configure -prefix "$srcdir/qt" -release -opensource -confirm-license -qt-zlib \ ./configure -prefix "$srcdir/qt" -release -opensource -confirm-license -qt-zlib \
-qt-libpng -qt-libjpeg -qt-freetype -qt-harfbuzz -qt-pcre -qt-xcb \ -qt-libpng -qt-libjpeg -qt-freetype -qt-harfbuzz -qt-pcre -qt-xcb \
-qt-xkbcommon-x11 -no-opengl -static -nomake examples -nomake tests -qt-xkbcommon-x11 -no-opengl -no-gtkstyle -static -nomake examples -nomake tests
make --silent -j4 make --silent -j4
make --silent -j4 install make --silent -j4 install

View file

@ -13,6 +13,7 @@ checkCommitMessage() {
if [[ $TRAVIS_COMMIT_MSG != *"Signed-off-by: "* ]];then if [[ $TRAVIS_COMMIT_MSG != *"Signed-off-by: "* ]];then
error_msg "The commit message does not contain the signature!" error_msg "The commit message does not contain the signature!"
error_msg "More information: https://github.com/telegramdesktop/tdesktop/blob/master/.github/CONTRIBUTING.md#sign-your-work" error_msg "More information: https://github.com/telegramdesktop/tdesktop/blob/master/.github/CONTRIBUTING.md#sign-your-work"
addMissingSignatureInfos
exit 1 exit 1
else else
success_msg "Commit message contains signature" success_msg "Commit message contains signature"
@ -20,6 +21,37 @@ checkCommitMessage() {
fi fi
} }
addMissingSignatureInfos() {
if [[ $BUILD_VERSION == "" ]]; then
local TEXT="Hi,\n\
thanks for the pull request!\n\
\n\
Please read our [contributing policy](https://github.com/telegramdesktop/tdesktop/blob/master/.github/CONTRIBUTING.md). You'll need to make a pull request with the \\\"Signed-off-by:\\\" signature being the last line of your commit message, like it is described in [sign your work](https://github.com/telegramdesktop/tdesktop/blob/master/.github/CONTRIBUTING.md#sign-your-work) section. That will grant your work into the public domain.\n\
\n\
(See [travis build](https://travis-ci.org/telegramdesktop/tdesktop/jobs/${TRAVIS_JOB_ID}))"
addCommentToGitHub "${TEXT}"
addLabelToGitHub "missing signature"
info_msg "Added missing signature info on github"
fi
}
addCommentToGitHub() {
local BODY=$1
sendGitHubRequest "POST" "{\"body\": \"${BODY}\"}" "repos/${TRAVIS_REPO_SLUG}/issues/${TRAVIS_PULL_REQUEST}/comments"
}
addLabelToGitHub() {
local LABEL=$1
sendGitHubRequest "PATCH" "{\"labels\": [\"${LABEL}\"]}" "repos/${TRAVIS_REPO_SLUG}/issues/${TRAVIS_PULL_REQUEST}"
}
sendGitHubRequest() {
local METHOD=$1
local BODY=$2
local URI=$3
curl -H "Authorization: token ${GH_AUTH_TOKEN}" --request "${METHOD}" --data "${BODY}" --silent "https://api.github.com/${URI}" > /dev/null
}
source ./.travis/common.sh source ./.travis/common.sh
run run

View file

@ -123,6 +123,7 @@ defaultBoxButton: RoundButton {
padding: margins(0px, 0px, 0px, 0px); padding: margins(0px, 0px, 0px, 0px);
textTop: 8px; textTop: 8px;
downTextTop: 9px;
font: boxButtonFont; font: boxButtonFont;
duration: 200; duration: 200;
@ -284,9 +285,9 @@ solidScroll: flatScroll {
barOverColor: #3f729734; barOverColor: #3f729734;
bgOverColor: #214f751a; bgOverColor: #214f751a;
round: 0px;
minHeight: 20px; minHeight: 20px;
round: 2px;
deltax: 5px; deltax: 5px;
width: 14px; width: 14px;
deltat: 6px; deltat: 6px;
@ -345,6 +346,7 @@ defaultTooltip: Tooltip {
almostTransparent: #ffffff0d; almostTransparent: #ffffff0d;
boxScroll: flatScroll(solidScroll) { boxScroll: flatScroll(solidScroll) {
round: 3px;
width: 18px; width: 18px;
deltax: 6px; deltax: 6px;
} }
@ -647,7 +649,7 @@ scrollDef: flatScroll {
barOverColor: rgba(0, 0, 0, 122); barOverColor: rgba(0, 0, 0, 122);
bgOverColor: rgba(0, 0, 0, 44); bgOverColor: rgba(0, 0, 0, 44);
round: 0px; round: 2px;
width: 10px; width: 10px;
minHeight: 20px; minHeight: 20px;
@ -663,7 +665,9 @@ scrollDef: flatScroll {
hiding: 1000; hiding: 1000;
} }
msgRadius: 3px; msgRadius: 16px;
dateRadius: 10px;
buttonRadius: 3px;
scrollCountries: flatScroll(scrollDef) { scrollCountries: flatScroll(scrollDef) {
topsh: 0px; topsh: 0px;
@ -732,7 +736,7 @@ btnIntroNext: flatButton(btnDefNext, btnDefBig) {
overFont: font(17px); overFont: font(17px);
width: 300px; width: 300px;
radius: msgRadius; radius: buttonRadius;
} }
boxShadow: sprite(363px, 50px, 15px, 15px); boxShadow: sprite(363px, 50px, 15px, 15px);
@ -999,6 +1003,7 @@ topBarButton: RoundButton {
padding: margins(0px, 14px, 12px, 12px); padding: margins(0px, 14px, 12px, 12px);
textTop: 6px; textTop: 6px;
downTextTop: 7px;
font: font(fsize); font: font(fsize);
duration: 200; duration: 200;
@ -1009,7 +1014,7 @@ defaultActiveButton: RoundButton {
secondaryTextFg: #cceeff; secondaryTextFg: #cceeff;
secondaryTextFgOver: #cceeff; secondaryTextFgOver: #cceeff;
textBg: windowActiveBg; textBg: windowActiveBg;
textBgOver: windowActiveBg; textBgOver: #46b4eb;
secondarySkip: 7px; secondarySkip: 7px;
@ -1018,6 +1023,7 @@ defaultActiveButton: RoundButton {
padding: margins(0px, 0px, 0px, 0px); padding: margins(0px, 0px, 0px, 0px);
textTop: 8px; textTop: 8px;
downTextTop: 9px;
font: semiboldFont; font: semiboldFont;
duration: 200; duration: 200;
@ -1486,7 +1492,7 @@ historyScroll: flatScroll(scrollDef) {
barOverColor: #89a0b4bc; barOverColor: #89a0b4bc;
bgOverColor: #89a0b46b; bgOverColor: #89a0b46b;
round: 0px; round: 3px;
width: 12px; width: 12px;
deltax: 3px; deltax: 3px;
@ -1829,6 +1835,7 @@ stickersMaxHeight: 440px;
stickersPadding: margins(19px, 17px, 19px, 17px); stickersPadding: margins(19px, 17px, 19px, 17px);
stickersSize: size(64px, 64px); stickersSize: size(64px, 64px);
stickersScroll: flatScroll(boxScroll) { stickersScroll: flatScroll(boxScroll) {
round: 2px;
deltax: 7px; deltax: 7px;
deltat: 23px; deltat: 23px;
deltab: 9px; deltab: 9px;
@ -2033,6 +2040,7 @@ switchPmButton: RoundButton(defaultBoxButton) {
width: 320px; width: 320px;
height: 34px; height: 34px;
textTop: 7px; textTop: 7px;
downTextTop: 8px;
} }
minPhotoSize: 100px; minPhotoSize: 100px;
@ -2224,6 +2232,7 @@ langsButton: Radiobutton(defaultRadiobutton) {
backgroundPadding: 10px; backgroundPadding: 10px;
backgroundSize: size(108px, 193px); backgroundSize: size(108px, 193px);
backgroundScroll: flatScroll(boxScroll) { backgroundScroll: flatScroll(boxScroll) {
round: 2px;
width: 10px; width: 10px;
deltax: 3px; deltax: 3px;
deltat: 10px; deltat: 10px;
@ -2262,6 +2271,7 @@ mentionFgActive: #0080c0;
mentionFgOverActive: #0077b3; mentionFgOverActive: #0077b3;
sessionsScroll: flatScroll(boxScroll) { sessionsScroll: flatScroll(boxScroll) {
round: 2px;
deltax: 5px; deltax: 5px;
width: 14px; width: 14px;
} }

View file

@ -326,6 +326,7 @@ RoundButton {
padding: margins; padding: margins;
textTop: pixels; textTop: pixels;
downTextTop: pixels;
icon: icon; icon: icon;

View file

@ -680,6 +680,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_stickers_add_pack" = "Add stickers"; "lng_stickers_add_pack" = "Add stickers";
"lng_stickers_share_pack" = "Share Stickers"; "lng_stickers_share_pack" = "Share Stickers";
"lng_stickers_not_found" = "Sticker pack not found."; "lng_stickers_not_found" = "Sticker pack not found.";
"lng_stickers_too_many_packs" = "You have too many sticker packs. Please remove some first.";
"lng_stickers_copied" = "Sticker pack link copied to clipboard."; "lng_stickers_copied" = "Sticker pack link copied to clipboard.";
"lng_stickers_default_set" = "Great Minds"; "lng_stickers_default_set" = "Great Minds";
"lng_stickers_you_have" = "Manage and reorder sticker packs"; "lng_stickers_you_have" = "Manage and reorder sticker packs";

View file

@ -103,7 +103,7 @@ namespace {
CornersPixmaps corners[RoundCornersCount]; CornersPixmaps corners[RoundCornersCount];
typedef QMap<uint32, CornersPixmaps> CornersMap; typedef QMap<uint32, CornersPixmaps> CornersMap;
CornersMap cornersMap; CornersMap cornersMap;
QImage *cornersMask[4] = { 0 }; QImage *cornersMaskLarge[4] = { 0 }, *cornersMaskSmall[4] = { 0 };
typedef QMap<uint64, QPixmap> EmojiMap; typedef QMap<uint64, QPixmap> EmojiMap;
EmojiMap mainEmojiMap; EmojiMap mainEmojiMap;
@ -2065,7 +2065,7 @@ namespace {
cors[1] = rect.copy(r * 2, 0, r, r); cors[1] = rect.copy(r * 2, 0, r, r);
cors[2] = rect.copy(0, r * 2, r, r + (shadow ? s : 0)); cors[2] = rect.copy(0, r * 2, r, r + (shadow ? s : 0));
cors[3] = rect.copy(r * 2, r * 2, r, r + (shadow ? s : 0)); cors[3] = rect.copy(r * 2, r * 2, r, r + (shadow ? s : 0));
if (index != NoneCorners) { if (index != SmallMaskCorners && index != LargeMaskCorners) {
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
::corners[index].p[i] = new QPixmap(QPixmap::fromImage(cors[i], Qt::ColorOnly)); ::corners[index].p[i] = new QPixmap(QPixmap::fromImage(cors[i], Qt::ColorOnly));
::corners[index].p[i]->setDevicePixelRatio(cRetinaFactor()); ::corners[index].p[i]->setDevicePixelRatio(cRetinaFactor());
@ -2104,33 +2104,38 @@ namespace {
} }
QImage mask[4]; QImage mask[4];
prepareCorners(NoneCorners, st::msgRadius, st::white, 0, mask); prepareCorners(LargeMaskCorners, st::msgRadius, st::white, 0, mask);
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
::cornersMask[i] = new QImage(mask[i].convertToFormat(QImage::Format_ARGB32_Premultiplied)); ::cornersMaskLarge[i] = new QImage(mask[i].convertToFormat(QImage::Format_ARGB32_Premultiplied));
::cornersMask[i]->setDevicePixelRatio(cRetinaFactor()); ::cornersMaskLarge[i]->setDevicePixelRatio(cRetinaFactor());
} }
prepareCorners(BlackCorners, st::msgRadius, st::black); prepareCorners(SmallMaskCorners, st::buttonRadius, st::white, 0, mask);
prepareCorners(WhiteCorners, st::msgRadius, st::white); for (int i = 0; i < 4; ++i) {
prepareCorners(ServiceCorners, st::msgRadius, st::msgServiceBg); ::cornersMaskSmall[i] = new QImage(mask[i].convertToFormat(QImage::Format_ARGB32_Premultiplied));
prepareCorners(ServiceSelectedCorners, st::msgRadius, st::msgServiceSelectBg); ::cornersMaskSmall[i]->setDevicePixelRatio(cRetinaFactor());
prepareCorners(SelectedOverlayCorners, st::msgRadius, st::msgSelectOverlay); }
prepareCorners(DateCorners, st::msgRadius, st::msgDateImgBg); prepareCorners(WhiteCorners, st::buttonRadius, st::white);
prepareCorners(DateSelectedCorners, st::msgRadius, st::msgDateImgBgSelected); prepareCorners(StickerCorners, st::dateRadius, st::msgServiceBg);
prepareCorners(StickerSelectedCorners, st::dateRadius, st::msgServiceSelectBg);
prepareCorners(SelectedOverlaySmallCorners, st::buttonRadius, st::msgSelectOverlay);
prepareCorners(SelectedOverlayLargeCorners, st::msgRadius, st::msgSelectOverlay);
prepareCorners(DateCorners, st::dateRadius, st::msgDateImgBg);
prepareCorners(DateSelectedCorners, st::dateRadius, st::msgDateImgBgSelected);
prepareCorners(InShadowCorners, st::msgRadius, st::msgInShadow); prepareCorners(InShadowCorners, st::msgRadius, st::msgInShadow);
prepareCorners(InSelectedShadowCorners, st::msgRadius, st::msgInShadowSelected); prepareCorners(InSelectedShadowCorners, st::msgRadius, st::msgInShadowSelected);
prepareCorners(ForwardCorners, st::msgRadius, st::forwardBg); prepareCorners(ForwardCorners, st::msgRadius, st::forwardBg);
prepareCorners(MediaviewSaveCorners, st::msgRadius, st::medviewSaveMsg); prepareCorners(MediaviewSaveCorners, st::msgRadius, st::medviewSaveMsg);
prepareCorners(EmojiHoverCorners, st::msgRadius, st::emojiPanHover); prepareCorners(EmojiHoverCorners, st::buttonRadius, st::emojiPanHover);
prepareCorners(StickerHoverCorners, st::msgRadius, st::emojiPanHover); prepareCorners(StickerHoverCorners, st::buttonRadius, st::emojiPanHover);
prepareCorners(BotKeyboardCorners, st::msgRadius, st::botKbBg); prepareCorners(BotKeyboardCorners, st::buttonRadius, st::botKbBg);
prepareCorners(BotKeyboardOverCorners, st::msgRadius, st::botKbOverBg); prepareCorners(BotKeyboardOverCorners, st::buttonRadius, st::botKbOverBg);
prepareCorners(BotKeyboardDownCorners, st::msgRadius, st::botKbDownBg); prepareCorners(BotKeyboardDownCorners, st::buttonRadius, st::botKbDownBg);
prepareCorners(PhotoSelectOverlayCorners, st::msgRadius, st::overviewPhotoSelectOverlay); prepareCorners(PhotoSelectOverlayCorners, st::buttonRadius, st::overviewPhotoSelectOverlay);
prepareCorners(DocBlueCorners, st::msgRadius, st::msgFileBlueColor); prepareCorners(DocBlueCorners, st::buttonRadius, st::msgFileBlueColor);
prepareCorners(DocGreenCorners, st::msgRadius, st::msgFileGreenColor); prepareCorners(DocGreenCorners, st::buttonRadius, st::msgFileGreenColor);
prepareCorners(DocRedCorners, st::msgRadius, st::msgFileRedColor); prepareCorners(DocRedCorners, st::buttonRadius, st::msgFileRedColor);
prepareCorners(DocYellowCorners, st::msgRadius, st::msgFileYellowColor); prepareCorners(DocYellowCorners, st::buttonRadius, st::msgFileYellowColor);
prepareCorners(MessageInCorners, st::msgRadius, st::msgInBg, &st::msgInShadow); prepareCorners(MessageInCorners, st::msgRadius, st::msgInBg, &st::msgInShadow);
prepareCorners(MessageInSelectedCorners, st::msgRadius, st::msgInBgSelected, &st::msgInShadowSelected); prepareCorners(MessageInSelectedCorners, st::msgRadius, st::msgInBgSelected, &st::msgInShadowSelected);
@ -2159,9 +2164,10 @@ namespace {
::emojiLarge = 0; ::emojiLarge = 0;
for (int32 j = 0; j < 4; ++j) { for (int32 j = 0; j < 4; ++j) {
for (int32 i = 0; i < RoundCornersCount; ++i) { for (int32 i = 0; i < RoundCornersCount; ++i) {
delete ::corners[i].p[j]; ::corners[i].p[j] = 0; delete ::corners[i].p[j]; ::corners[i].p[j] = nullptr;
} }
delete ::cornersMask[j]; ::cornersMask[j] = 0; delete ::cornersMaskSmall[j]; ::cornersMaskSmall[j] = nullptr;
delete ::cornersMaskLarge[j]; ::cornersMaskLarge[j] = nullptr;
} }
for (CornersMap::const_iterator i = ::cornersMap.cbegin(), e = ::cornersMap.cend(); i != e; ++i) { for (CornersMap::const_iterator i = ::cornersMap.cbegin(), e = ::cornersMap.cend(); i != e; ++i) {
for (int32 j = 0; j < 4; ++j) { for (int32 j = 0; j < 4; ++j) {
@ -2555,8 +2561,13 @@ namespace {
#endif #endif
} }
QImage **cornersMask() { QImage **cornersMask(ImageRoundRadius radius) {
return ::cornersMask; switch (radius) {
case ImageRoundRadius::Large: return ::cornersMaskLarge;
case ImageRoundRadius::Small:
default: break;
}
return ::cornersMaskSmall;
} }
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, const style::color &bg, const CornersPixmaps &c, const style::color *sh) { void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, const style::color &bg, const CornersPixmaps &c, const style::color *sh) {
int32 cw = c.p[0]->width() / cIntRetinaFactor(), ch = c.p[0]->height() / cIntRetinaFactor(); int32 cw = c.p[0]->width() / cIntRetinaFactor(), ch = c.p[0]->height() / cIntRetinaFactor();
@ -2589,12 +2600,15 @@ namespace {
p.drawPixmap(x + w - cw, y + h - ch + st::msgShadow, *c.p[3]); p.drawPixmap(x + w - cw, y + h - ch + st::msgShadow, *c.p[3]);
} }
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, const style::color &bg) { void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, const style::color &bg, ImageRoundRadius radius) {
uint32 colorKey = ((uint32(bg->c.alpha()) & 0xFF) << 24) | ((uint32(bg->c.red()) & 0xFF) << 16) | ((uint32(bg->c.green()) & 0xFF) << 8) | ((uint32(bg->c.blue()) & 0xFF) << 24); uint32 colorKey = ((uint32(bg->c.alpha()) & 0xFF) << 24) | ((uint32(bg->c.red()) & 0xFF) << 16) | ((uint32(bg->c.green()) & 0xFF) << 8) | ((uint32(bg->c.blue()) & 0xFF) << 24);
CornersMap::const_iterator i = cornersMap.find(colorKey); CornersMap::const_iterator i = cornersMap.find(colorKey);
if (i == cornersMap.cend()) { if (i == cornersMap.cend()) {
QImage images[4]; QImage images[4];
prepareCorners(NoneCorners, st::msgRadius, bg, 0, images); switch (radius) {
case ImageRoundRadius::Small: prepareCorners(SmallMaskCorners, st::buttonRadius, bg, 0, images); break;
case ImageRoundRadius::Large: prepareCorners(LargeMaskCorners, st::msgRadius, bg, 0, images); break;
}
CornersPixmaps pixmaps; CornersPixmaps pixmaps;
for (int j = 0; j < 4; ++j) { for (int j = 0; j < 4; ++j) {
@ -2757,8 +2771,8 @@ namespace {
uchar bsel = snap(qRound(((1. - alphaSel) * b + addSel) / alphaSel), 0, 0xFF); uchar bsel = snap(qRound(((1. - alphaSel) * b + addSel) / alphaSel), 0, 0xFF);
_msgServiceSelectBg = style::color(r, g, b, qRound(alphaSel * 0xFF)); _msgServiceSelectBg = style::color(r, g, b, qRound(alphaSel * 0xFF));
prepareCorners(ServiceCorners, st::msgRadius, _msgServiceBg); prepareCorners(StickerCorners, st::dateRadius, _msgServiceBg);
prepareCorners(ServiceSelectedCorners, st::msgRadius, _msgServiceSelectBg); prepareCorners(StickerSelectedCorners, st::dateRadius, _msgServiceSelectBg);
uchar rScroll = uchar(componentsScroll[0]), gScroll = uchar(componentsScroll[1]), bScroll = uchar(componentsScroll[2]); uchar rScroll = uchar(componentsScroll[0]), gScroll = uchar(componentsScroll[1]), bScroll = uchar(componentsScroll[2]);
_historyScrollBarColor = style::color(rScroll, gScroll, bScroll, qRound(st::historyScroll.barColor->c.alphaF() * 0xFF)); _historyScrollBarColor = style::color(rScroll, gScroll, bScroll, qRound(st::historyScroll.barColor->c.alphaF() * 0xFF));

View file

@ -27,8 +27,6 @@ class MainWindow;
class MainWidget; class MainWidget;
class SettingsWidget; class SettingsWidget;
class ApiWrap; class ApiWrap;
class Font;
class Color;
class FileUploader; class FileUploader;
#include "history.h" #include "history.h"
@ -271,7 +269,7 @@ namespace App {
#endif #endif
void setProxySettings(QTcpSocket &socket); void setProxySettings(QTcpSocket &socket);
QImage **cornersMask(); QImage **cornersMask(ImageRoundRadius radius);
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, const style::color &bg, RoundCorners index, const style::color *sh = 0); void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, const style::color &bg, RoundCorners index, const style::color *sh = 0);
inline void roundRect(Painter &p, const QRect &rect, const style::color &bg, RoundCorners index, const style::color *sh = 0) { inline void roundRect(Painter &p, const QRect &rect, const style::color &bg, RoundCorners index, const style::color *sh = 0) {
return roundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, index, sh); return roundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, index, sh);
@ -280,9 +278,9 @@ namespace App {
inline void roundShadow(Painter &p, const QRect &rect, const style::color &sh, RoundCorners index) { inline void roundShadow(Painter &p, const QRect &rect, const style::color &sh, RoundCorners index) {
return roundShadow(p, rect.x(), rect.y(), rect.width(), rect.height(), sh, index); return roundShadow(p, rect.x(), rect.y(), rect.width(), rect.height(), sh, index);
} }
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, const style::color &bg); void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, const style::color &bg, ImageRoundRadius radius);
inline void roundRect(Painter &p, const QRect &rect, const style::color &bg) { inline void roundRect(Painter &p, const QRect &rect, const style::color &bg, ImageRoundRadius radius) {
return roundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg); return roundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, radius);
} }
void initBackground(int32 id = DefaultChatBackground, const QImage &p = QImage(), bool nowrite = false); void initBackground(int32 id = DefaultChatBackground, const QImage &p = QImage(), bool nowrite = false);

View file

@ -1045,8 +1045,12 @@ void AppClass::checkMapVersion() {
if (Local::oldMapVersion() < AppVersion) { if (Local::oldMapVersion() < AppVersion) {
if (Local::oldMapVersion()) { if (Local::oldMapVersion()) {
QString versionFeatures; QString versionFeatures;
if ((cAlphaVersion() || cBetaVersion()) && Local::oldMapVersion() < 9055) { if ((cAlphaVersion() || cBetaVersion()) && Local::oldMapVersion() < 9057) {
versionFeatures = QString::fromUtf8("\xe2\x80\x94 Main window position and size are saved between the launches in Windows\n\xe2\x80\x94 Dock and top bar hiding fixed in OS X\n\xe2\x80\x94 Various design improvements and other bug fixes"); #if defined Q_OS_LINUX32 || defined Q_OS_LINUX64
versionFeatures = QString::fromUtf8("\xe2\x80\x94 Design improvements\n\xe2\x80\x94 Linux : trying to use GTK file chooser when it is available");
#else // Q_OS_LINUX32 || Q_OS_LINUX64
versionFeatures = QString::fromUtf8("\xe2\x80\x94 Design improvements");
#endif // Q_OS_LINUX32 || Q_OS_LINUX64
// versionFeatures = langNewVersionText(); // versionFeatures = langNewVersionText();
} else if (Local::oldMapVersion() < 9056) { } else if (Local::oldMapVersion() < 9056) {
versionFeatures = langNewVersionText(); versionFeatures = langNewVersionText();

View file

@ -123,7 +123,7 @@ PhotoSendBox::PhotoSendBox(const FileLoadResultPtr &file) : AbstractBox(st::boxW
} else { } else {
_thumbw = st::msgFileThumbSize; _thumbw = st::msgFileThumbSize;
} }
_thumb = imagePix(_thumb.toImage(), _thumbw * cIntRetinaFactor(), 0, ImagePixSmooth | ImagePixRounded, st::msgFileThumbSize, st::msgFileThumbSize); _thumb = imagePix(_thumb.toImage(), _thumbw * cIntRetinaFactor(), 0, ImagePixSmooth | ImagePixRoundedSmall, st::msgFileThumbSize, st::msgFileThumbSize);
} }
_name.setText(st::semiboldFont, _file->filename, _textNameOptions); _name.setText(st::semiboldFont, _file->filename, _textNameOptions);
@ -427,7 +427,7 @@ EditCaptionBox::EditCaptionBox(HistoryItem *msg) : AbstractBox(st::boxWideWidth)
} else { } else {
_thumbw = st::msgFileThumbSize; _thumbw = st::msgFileThumbSize;
} }
_thumb = imagePix(image->pix().toImage(), _thumbw * cIntRetinaFactor(), 0, ImagePixSmooth | ImagePixRounded, st::msgFileThumbSize, st::msgFileThumbSize); _thumb = imagePix(image->pix().toImage(), _thumbw * cIntRetinaFactor(), 0, ImagePixSmooth | ImagePixRoundedSmall, st::msgFileThumbSize, st::msgFileThumbSize);
} }
if (doc) { if (doc) {
@ -462,7 +462,7 @@ EditCaptionBox::EditCaptionBox(HistoryItem *msg) : AbstractBox(st::boxWideWidth)
} else { } else {
maxW = dimensions.width(); maxW = dimensions.width();
maxH = dimensions.height(); maxH = dimensions.height();
_thumb = image->pixNoCache(maxW * cIntRetinaFactor(), maxH * cIntRetinaFactor(), ImagePixSmooth | ImagePixRounded, maxW, maxH); _thumb = image->pixNoCache(maxW * cIntRetinaFactor(), maxH * cIntRetinaFactor(), ImagePixSmooth, maxW, maxH);
} }
int32 tw = _thumb.width(), th = _thumb.height(); int32 tw = _thumb.width(), th = _thumb.height();
if (!tw || !th) { if (!tw || !th) {

View file

@ -158,7 +158,11 @@ void StickerSetInner::installDone(const MTPBool &result) {
bool StickerSetInner::installFailed(const RPCError &error) { bool StickerSetInner::installFailed(const RPCError &error) {
if (MTP::isDefaultHandledError(error)) return false; if (MTP::isDefaultHandledError(error)) return false;
Ui::showLayer(new InformBox(lang(lng_stickers_not_found))); if (error.type() == qstr("STICKERSETS_TOO_MUCH")) {
Ui::showLayer(new InformBox(lang(lng_stickers_too_many_packs)));
} else {
Ui::showLayer(new InformBox(lang(lng_stickers_not_found)));
}
return true; return true;
} }
@ -233,7 +237,7 @@ void StickerSetInner::paintEvent(QPaintEvent *e) {
} }
} }
float64 coef = qMin((st::stickersSize.width() - st::msgRadius * 2) / float64(doc->dimensions.width()), (st::stickersSize.height() - st::msgRadius * 2) / float64(doc->dimensions.height())); float64 coef = qMin((st::stickersSize.width() - st::buttonRadius * 2) / float64(doc->dimensions.width()), (st::stickersSize.height() - st::buttonRadius * 2) / float64(doc->dimensions.height()));
if (coef > 1) coef = 1; if (coef > 1) coef = 1;
int32 w = qRound(coef * doc->dimensions.width()), h = qRound(coef * doc->dimensions.height()); int32 w = qRound(coef * doc->dimensions.width()), h = qRound(coef * doc->dimensions.height());
if (w < 1) w = 1; if (w < 1) w = 1;

View file

@ -777,7 +777,7 @@ inline QString strMakeFromLetters(const uint32 *letters, int32 len) {
QString result; QString result;
result.reserve(len); result.reserve(len);
for (int32 i = 0; i < len; ++i) { for (int32 i = 0; i < len; ++i) {
result.push_back(QChar((((letters[i] << 16) & 0xFF) >> 8) | (letters[i] & 0xFF))); result.push_back(QChar((((letters[i] >> 16) & 0xFF) << 8) | (letters[i] & 0xFF)));
} }
return result; return result;
} }

View file

@ -84,6 +84,10 @@ dialogsTextStyleActive: textStyle(dialogsTextStyle) {
linkFg: dialogsTextFgActive; linkFg: dialogsTextFgActive;
linkFgDown: dialogsTextFgActive; linkFgDown: dialogsTextFgActive;
} }
dialogsTextStyleDraftActive: textStyle(dialogsTextStyle) {
linkFg: #ffd6d6;
linkFgDown: #ffd6d6;
}
dialogsNewChatIcon: icon { dialogsNewChatIcon: icon {
{ "dialogs_new_chat", #b7b7b7, point(9px, 10px) } { "dialogs_new_chat", #b7b7b7, point(9px, 10px) }
@ -93,6 +97,9 @@ dialogsNewChatButton: RoundButton {
height: 36px; height: 36px;
icon: dialogsNewChatIcon; icon: dialogsNewChatIcon;
textTop: 5px;
downTextTop: 6px;
textFg: transparent; textFg: transparent;
textFgOver: transparent; textFgOver: transparent;
secondaryTextFg: transparent; secondaryTextFg: transparent;

View file

@ -92,7 +92,7 @@ void paintRow(Painter &p, History *history, HistoryItem *item, Data::Draft *draf
auto draftText = lng_dialogs_text_with_from(lt_from_part, draftWrapped, lt_message, textClean(draft->textWithTags.text)); auto draftText = lng_dialogs_text_with_from(lt_from_part, draftWrapped, lt_message, textClean(draft->textWithTags.text));
history->cloudDraftTextCache.setText(st::dialogsTextFont, draftText, _textDlgOptions); history->cloudDraftTextCache.setText(st::dialogsTextFont, draftText, _textDlgOptions);
} }
textstyleSet(&(active ? st::dialogsTextStyleActive : st::dialogsTextStyleDraft)); textstyleSet(&(active ? st::dialogsTextStyleDraftActive : st::dialogsTextStyleDraft));
p.setFont(st::dialogsTextFont); p.setFont(st::dialogsTextFont);
p.setPen(active ? st::dialogsTextFgActive : st::dialogsTextFg); p.setPen(active ? st::dialogsTextFgActive : st::dialogsTextFg);
history->cloudDraftTextCache.drawElided(p, nameleft, texttop, namewidth, 1); history->cloudDraftTextCache.drawElided(p, nameleft, texttop, namewidth, 1);

View file

@ -949,9 +949,9 @@ void EmojiPanInner::onShowPicker() {
int32 size = (c == tab) ? (sel - (sel % EmojiPanPerRow)) : _counts[c], rows = (size / EmojiPanPerRow) + ((size % EmojiPanPerRow) ? 1 : 0); int32 size = (c == tab) ? (sel - (sel % EmojiPanPerRow)) : _counts[c], rows = (size / EmojiPanPerRow) + ((size % EmojiPanPerRow) ? 1 : 0);
y += st::emojiPanHeader + (rows * st::emojiPanSize.height()); y += st::emojiPanHeader + (rows * st::emojiPanSize.height());
} }
y -= _picker.height() - st::msgRadius + _top; y -= _picker.height() - st::buttonRadius + _top;
if (y < 0) { if (y < 0) {
y += _picker.height() - st::msgRadius + st::emojiPanSize.height() - st::msgRadius; y += _picker.height() - st::buttonRadius + st::emojiPanSize.height() - st::buttonRadius;
} }
int xmax = width() - _picker.width(); int xmax = width() - _picker.width();
float64 coef = float64(sel % EmojiPanPerRow) / float64(EmojiPanPerRow - 1); float64 coef = float64(sel % EmojiPanPerRow) / float64(EmojiPanPerRow - 1);
@ -1407,7 +1407,7 @@ void StickerPanInner::paintStickers(Painter &p, const QRect &r) {
sticker->checkSticker(); sticker->checkSticker();
} }
float64 coef = qMin((st::stickerPanSize.width() - st::msgRadius * 2) / float64(sticker->dimensions.width()), (st::stickerPanSize.height() - st::msgRadius * 2) / float64(sticker->dimensions.height())); float64 coef = qMin((st::stickerPanSize.width() - st::buttonRadius * 2) / float64(sticker->dimensions.width()), (st::stickerPanSize.height() - st::buttonRadius * 2) / float64(sticker->dimensions.height()));
if (coef > 1) coef = 1; if (coef > 1) coef = 1;
int32 w = qRound(coef * sticker->dimensions.width()), h = qRound(coef * sticker->dimensions.height()); int32 w = qRound(coef * sticker->dimensions.width()), h = qRound(coef * sticker->dimensions.height());
if (w < 1) w = 1; if (w < 1) w = 1;

View file

@ -536,6 +536,8 @@ struct Data {
Dialogs::Mode DialogsMode = Dialogs::Mode::All; Dialogs::Mode DialogsMode = Dialogs::Mode::All;
bool ModerateModeEnabled = false; bool ModerateModeEnabled = false;
bool ScreenIsLocked = false;
int32 DebugLoggingFlags = 0; int32 DebugLoggingFlags = 0;
// config // config
@ -605,6 +607,8 @@ DefineVar(Global, bool, DialogsModeEnabled);
DefineVar(Global, Dialogs::Mode, DialogsMode); DefineVar(Global, Dialogs::Mode, DialogsMode);
DefineVar(Global, bool, ModerateModeEnabled); DefineVar(Global, bool, ModerateModeEnabled);
DefineVar(Global, bool, ScreenIsLocked);
DefineVar(Global, int32, DebugLoggingFlags); DefineVar(Global, int32, DebugLoggingFlags);
// config // config

View file

@ -232,6 +232,8 @@ DeclareVar(bool, DialogsModeEnabled);
DeclareVar(Dialogs::Mode, DialogsMode); DeclareVar(Dialogs::Mode, DialogsMode);
DeclareVar(bool, ModerateModeEnabled); DeclareVar(bool, ModerateModeEnabled);
DeclareVar(bool, ScreenIsLocked);
DeclareVar(int32, DebugLoggingFlags); DeclareVar(int32, DebugLoggingFlags);
// config // config

View file

@ -3409,14 +3409,14 @@ void HistoryPhoto::draw(Painter &p, const QRect &r, TextSelection selection, uin
QPixmap pix; QPixmap pix;
if (loaded) { if (loaded) {
pix = _data->full->pixSingle(_pixw, _pixh, width, height); pix = _data->full->pixSingle(ImageRoundRadius::Large, _pixw, _pixh, width, height);
} else { } else {
pix = _data->thumb->pixBlurredSingle(_pixw, _pixh, width, height); pix = _data->thumb->pixBlurredSingle(ImageRoundRadius::Large, _pixw, _pixh, width, height);
} }
QRect rthumb(rtlrect(skipx, skipy, width, height, _width)); QRect rthumb(rtlrect(skipx, skipy, width, height, _width));
p.drawPixmap(rthumb.topLeft(), pix); p.drawPixmap(rthumb.topLeft(), pix);
if (selected) { if (selected) {
App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlayCorners); App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlayLargeCorners);
} }
if (notChild && (radial || (!loaded && !_data->loading()))) { if (notChild && (radial || (!loaded && !_data->loading()))) {
@ -3738,9 +3738,9 @@ void HistoryVideo::draw(Painter &p, const QRect &r, TextSelection selection, uin
} }
QRect rthumb(rtlrect(skipx, skipy, width, height, _width)); QRect rthumb(rtlrect(skipx, skipy, width, height, _width));
p.drawPixmap(rthumb.topLeft(), _data->thumb->pixBlurredSingle(_thumbw, 0, width, height)); p.drawPixmap(rthumb.topLeft(), _data->thumb->pixBlurredSingle(ImageRoundRadius::Large, _thumbw, 0, width, height));
if (selected) { if (selected) {
App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlayCorners); App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlayLargeCorners);
} }
QRect inner(rthumb.x() + (rthumb.width() - st::msgFileSize) / 2, rthumb.y() + (rthumb.height() - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize); QRect inner(rthumb.x() + (rthumb.width() - st::msgFileSize) / 2, rthumb.y() + (rthumb.height() - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize);
@ -4076,10 +4076,10 @@ void HistoryDocument::draw(Painter &p, const QRect &r, TextSelection selection,
bottom = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom(); bottom = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom();
QRect rthumb(rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, _width)); QRect rthumb(rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, _width));
QPixmap thumb = loaded ? _data->thumb->pixSingle(thumbed->_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize) : _data->thumb->pixBlurredSingle(thumbed->_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize); QPixmap thumb = loaded ? _data->thumb->pixSingle(ImageRoundRadius::Small, thumbed->_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize) : _data->thumb->pixBlurredSingle(ImageRoundRadius::Small, thumbed->_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize);
p.drawPixmap(rthumb.topLeft(), thumb); p.drawPixmap(rthumb.topLeft(), thumb);
if (selected) { if (selected) {
App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlayCorners); App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlaySmallCorners);
} }
if (radial || (!loaded && !_data->loading())) { if (radial || (!loaded && !_data->loading())) {
@ -4697,10 +4697,10 @@ void HistoryGif::draw(Painter &p, const QRect &r, TextSelection selection, uint6
if (animating) { if (animating) {
p.drawPixmap(rthumb.topLeft(), _gif->current(_thumbw, _thumbh, width, height, (Ui::isLayerShown() || Ui::isMediaViewShown() || Ui::isInlineItemBeingChosen()) ? 0 : ms)); p.drawPixmap(rthumb.topLeft(), _gif->current(_thumbw, _thumbh, width, height, (Ui::isLayerShown() || Ui::isMediaViewShown() || Ui::isInlineItemBeingChosen()) ? 0 : ms));
} else { } else {
p.drawPixmap(rthumb.topLeft(), _data->thumb->pixBlurredSingle(_thumbw, _thumbh, width, height)); p.drawPixmap(rthumb.topLeft(), _data->thumb->pixBlurredSingle(ImageRoundRadius::Large, _thumbw, _thumbh, width, height));
} }
if (selected) { if (selected) {
App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlayCorners); App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlayLargeCorners);
} }
if (radial || (!_gif && ((!loaded && !_data->loading()) || !cAutoPlayGif())) || (_gif == BadClipReader)) { if (radial || (!_gif && ((!loaded && !_data->loading()) || !cAutoPlayGif())) || (_gif == BadClipReader)) {
@ -5045,7 +5045,7 @@ void HistorySticker::draw(Painter &p, const QRect &r, TextSelection selection, u
// Make the bottom of the rect at the same level as the bottom of the info rect. // Make the bottom of the rect at the same level as the bottom of the info rect.
recty -= st::msgDateImgDelta; recty -= st::msgDateImgDelta;
App::roundRect(p, rectx, recty, rectw, recth, selected ? App::msgServiceSelectBg() : App::msgServiceBg(), selected ? ServiceSelectedCorners : ServiceCorners); App::roundRect(p, rectx, recty, rectw, recth, selected ? App::msgServiceSelectBg() : App::msgServiceBg(), selected ? StickerSelectedCorners : StickerCorners);
rectx += st::msgReplyPadding.left(); rectx += st::msgReplyPadding.left();
rectw -= st::msgReplyPadding.left() + st::msgReplyPadding.right(); rectw -= st::msgReplyPadding.left() + st::msgReplyPadding.right();
if (via) { if (via) {
@ -5274,7 +5274,7 @@ void HistoryContact::draw(Painter &p, const QRect &r, TextSelection selection, u
p.drawPixmap(rthumb.topLeft(), userDefPhoto(qAbs(_userId) % UserColorsCount)->pixCircled(st::msgFileThumbSize, st::msgFileThumbSize)); p.drawPixmap(rthumb.topLeft(), userDefPhoto(qAbs(_userId) % UserColorsCount)->pixCircled(st::msgFileThumbSize, st::msgFileThumbSize));
} }
if (selected) { if (selected) {
App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlayCorners); App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlaySmallCorners);
} }
bool over = ClickHandler::showAsActive(_linkl); bool over = ClickHandler::showAsActive(_linkl);
@ -5666,13 +5666,13 @@ void HistoryWebPage::draw(Painter &p, const QRect &r, TextSelection selection, u
pixw = qRound(pixw * coef); pixw = qRound(pixw * coef);
} }
if (full) { if (full) {
pix = _data->photo->medium->pixSingle(pixw, pixh, pw, ph); pix = _data->photo->medium->pixSingle(ImageRoundRadius::Small, pixw, pixh, pw, ph);
} else { } else {
pix = _data->photo->thumb->pixBlurredSingle(pixw, pixh, pw, ph); pix = _data->photo->thumb->pixBlurredSingle(ImageRoundRadius::Small, pixw, pixh, pw, ph);
} }
p.drawPixmapLeft(lshift + width - pw, 0, _width, pix); p.drawPixmapLeft(lshift + width - pw, 0, _width, pix);
if (selected) { if (selected) {
App::roundRect(p, rtlrect(lshift + width - pw, 0, pw, _pixh, _width), textstyleCurrent()->selectOverlay, SelectedOverlayCorners); App::roundRect(p, rtlrect(lshift + width - pw, 0, pw, _pixh, _width), textstyleCurrent()->selectOverlay, SelectedOverlaySmallCorners);
} }
width -= pw + st::webPagePhotoDelta; width -= pw + st::webPagePhotoDelta;
} }
@ -6196,20 +6196,20 @@ void HistoryLocation::draw(Painter &p, const QRect &r, TextSelection selection,
int32 w = _data->thumb->width(), h = _data->thumb->height(); int32 w = _data->thumb->width(), h = _data->thumb->height();
QPixmap pix; QPixmap pix;
if (width * h == height * w || (w == fullWidth() && h == fullHeight())) { if (width * h == height * w || (w == fullWidth() && h == fullHeight())) {
pix = _data->thumb->pixSingle(width, height, width, height); pix = _data->thumb->pixSingle(ImageRoundRadius::Large, width, height, width, height);
} else if (width * h > height * w) { } else if (width * h > height * w) {
int32 nw = height * w / h; int32 nw = height * w / h;
pix = _data->thumb->pixSingle(nw, height, width, height); pix = _data->thumb->pixSingle(ImageRoundRadius::Large, nw, height, width, height);
} else { } else {
int32 nh = width * h / w; int32 nh = width * h / w;
pix = _data->thumb->pixSingle(width, nh, width, height); pix = _data->thumb->pixSingle(ImageRoundRadius::Large, width, nh, width, height);
} }
p.drawPixmap(QPoint(skipx, skipy), pix); p.drawPixmap(QPoint(skipx, skipy), pix);
} else { } else {
App::roundRect(p, skipx, skipy, width, height, st::white, MessageInCorners); App::roundRect(p, skipx, skipy, width, height, st::white, MessageInCorners);
} }
if (selected) { if (selected) {
App::roundRect(p, skipx, skipy, width, height, textstyleCurrent()->selectOverlay, SelectedOverlayCorners); App::roundRect(p, skipx, skipy, width, height, textstyleCurrent()->selectOverlay, SelectedOverlayLargeCorners);
} }
if (_parent->getMedia() == this) { if (_parent->getMedia() == this) {
@ -6513,9 +6513,9 @@ void HistoryMessageReply::paint(Painter &p, const HistoryItem *holder, int x, in
ImagePtr replyPreview = replyToMsg->getMedia()->replyPreview(); ImagePtr replyPreview = replyToMsg->getMedia()->replyPreview();
if (!replyPreview->isNull()) { if (!replyPreview->isNull()) {
QRect to(rtlrect(x + st::msgReplyBarSkip, y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height(), w + 2 * x)); QRect to(rtlrect(x + st::msgReplyBarSkip, y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height(), w + 2 * x));
p.drawPixmap(to.x(), to.y(), replyPreview->pixSingle(replyPreview->width() / cIntRetinaFactor(), replyPreview->height() / cIntRetinaFactor(), to.width(), to.height())); p.drawPixmap(to.x(), to.y(), replyPreview->pixSingle(ImageRoundRadius::Small, replyPreview->width() / cIntRetinaFactor(), replyPreview->height() / cIntRetinaFactor(), to.width(), to.height()));
if (selected) { if (selected) {
App::roundRect(p, to, textstyleCurrent()->selectOverlay, SelectedOverlayCorners); App::roundRect(p, to, textstyleCurrent()->selectOverlay, SelectedOverlaySmallCorners);
} }
} }
} }
@ -6563,7 +6563,7 @@ void HistoryMessage::KeyboardStyle::repaint(const HistoryItem *item) const {
} }
void HistoryMessage::KeyboardStyle::paintButtonBg(Painter &p, const QRect &rect, bool down, float64 howMuchOver) const { void HistoryMessage::KeyboardStyle::paintButtonBg(Painter &p, const QRect &rect, bool down, float64 howMuchOver) const {
App::roundRect(p, rect, App::msgServiceBg(), ServiceCorners); App::roundRect(p, rect, App::msgServiceBg(), StickerCorners);
if (down) { if (down) {
howMuchOver = 1.; howMuchOver = 1.;
} }
@ -7291,7 +7291,7 @@ void HistoryMessage::drawInfo(Painter &p, int32 right, int32 bottom, int32 width
App::roundRect(p, dateX - st::msgDateImgPadding.x(), dateY - st::msgDateImgPadding.y(), dateW, dateH, selected ? st::msgDateImgBgSelected : st::msgDateImgBg, selected ? DateSelectedCorners : DateCorners); App::roundRect(p, dateX - st::msgDateImgPadding.x(), dateY - st::msgDateImgPadding.y(), dateW, dateH, selected ? st::msgDateImgBgSelected : st::msgDateImgBg, selected ? DateSelectedCorners : DateCorners);
} else if (type == InfoDisplayOverBackground) { } else if (type == InfoDisplayOverBackground) {
int32 dateW = infoW + 2 * st::msgDateImgPadding.x(), dateH = st::msgDateFont->height + 2 * st::msgDateImgPadding.y(); int32 dateW = infoW + 2 * st::msgDateImgPadding.x(), dateH = st::msgDateFont->height + 2 * st::msgDateImgPadding.y();
App::roundRect(p, dateX - st::msgDateImgPadding.x(), dateY - st::msgDateImgPadding.y(), dateW, dateH, selected ? App::msgServiceSelectBg() : App::msgServiceBg(), selected ? ServiceSelectedCorners : ServiceCorners); App::roundRect(p, dateX - st::msgDateImgPadding.x(), dateY - st::msgDateImgPadding.y(), dateW, dateH, selected ? App::msgServiceSelectBg() : App::msgServiceBg(), selected ? StickerSelectedCorners : StickerCorners);
} }
dateX += HistoryMessage::timeLeft(); dateX += HistoryMessage::timeLeft();

View file

@ -104,7 +104,7 @@ void FieldAutocomplete::showFiltered(PeerData *peer, QString query, bool addInli
bool resetScroll = (_type != type || _filter != plainQuery); bool resetScroll = (_type != type || _filter != plainQuery);
if (resetScroll) { if (resetScroll) {
_type = type; _type = type;
_filter = plainQuery.toString(); _filter = textAccentFold(plainQuery.toString());
} }
_addInlineBots = addInlineBots; _addInlineBots = addInlineBots;
@ -259,7 +259,9 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) {
auto &recent(cRecentWriteHashtags()); auto &recent(cRecentWriteHashtags());
hrows.reserve(recent.size()); hrows.reserve(recent.size());
for (auto i = recent.cbegin(), e = recent.cend(); i != e; ++i) { for (auto i = recent.cbegin(), e = recent.cend(); i != e; ++i) {
if (!listAllSuggestions && (!i->first.startsWith(_filter, Qt::CaseInsensitive) || i->first.size() == _filter.size())) continue; if (!listAllSuggestions && (!i->first.startsWith(_filter, Qt::CaseInsensitive) || i->first.size() == _filter.size())) {
continue;
}
hrows.push_back(i->first); hrows.push_back(i->first);
} }
} else if (_type == Type::BotCommands) { } else if (_type == Type::BotCommands) {
@ -578,7 +580,7 @@ void FieldAutocompleteInner::paintEvent(QPaintEvent *e) {
sticker->checkSticker(); sticker->checkSticker();
} }
float64 coef = qMin((st::stickerPanSize.width() - st::msgRadius * 2) / float64(sticker->dimensions.width()), (st::stickerPanSize.height() - st::msgRadius * 2) / float64(sticker->dimensions.height())); float64 coef = qMin((st::stickerPanSize.width() - st::buttonRadius * 2) / float64(sticker->dimensions.width()), (st::stickerPanSize.height() - st::buttonRadius * 2) / float64(sticker->dimensions.height()));
if (coef > 1) coef = 1; if (coef > 1) coef = 1;
int32 w = qRound(coef * sticker->dimensions.width()), h = qRound(coef * sticker->dimensions.height()); int32 w = qRound(coef * sticker->dimensions.width()), h = qRound(coef * sticker->dimensions.height());
if (w < 1) w = 1; if (w < 1) w = 1;

View file

@ -35,6 +35,7 @@ historyToDownBadgeSize: 22px;
membersInnerScroll: flatScroll(solidScroll) { membersInnerScroll: flatScroll(solidScroll) {
deltat: 3px; deltat: 3px;
deltab: 3px; deltab: 3px;
round: 1px;
width: 8px; width: 8px;
deltax: 3px; deltax: 3px;
} }
@ -44,3 +45,7 @@ membersInnerDropdown: InnerDropdown(defaultInnerDropdown) {
scrollMargin: margins(0px, 5px, 0px, 5px); scrollMargin: margins(0px, 5px, 0px, 5px);
scrollPadding: margins(0px, 3px, 8px, 3px); scrollPadding: margins(0px, 3px, 8px, 3px);
} }
historyServiceMsgRadius: 12px;
historyServiceMsgInvertedRadius: 6px;
historyServiceMsgInvertedShrink: 4px;

View file

@ -22,6 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "history/history_service_layout.h" #include "history/history_service_layout.h"
#include "data/data_abstract_structure.h" #include "data/data_abstract_structure.h"
#include "styles/style_history.h"
#include "mainwidget.h" #include "mainwidget.h"
#include "lang.h" #include "lang.h"
@ -58,14 +59,17 @@ void createCircleMasks() {
serviceMessageStyle.createIfNull(); serviceMessageStyle.createIfNull();
if (!serviceMessageStyle->circle[NormalMask].isNull()) return; if (!serviceMessageStyle->circle[NormalMask].isNull()) return;
int size = st::msgRadius * 2; int size = st::historyServiceMsgRadius * 2;
serviceMessageStyle->circle[NormalMask] = style::createCircleMask(size); serviceMessageStyle->circle[NormalMask] = style::createCircleMask(size);
serviceMessageStyle->circle[InvertedMask] = style::createInvertedCircleMask(size); int sizeInverted = st::historyServiceMsgInvertedRadius * 2;
serviceMessageStyle->circle[InvertedMask] = style::createInvertedCircleMask(sizeInverted);
} }
QPixmap circleCorner(int corner) { QPixmap circleCorner(int corner) {
if (serviceMessageStyle->corners[corner].isNull()) { if (serviceMessageStyle->corners[corner].isNull()) {
int size = st::msgRadius * cIntRetinaFactor(); int maskType = corner / MaskMultiplier;
int radius = (maskType == NormalMask ? st::historyServiceMsgRadius : st::historyServiceMsgInvertedRadius);
int size = radius * cIntRetinaFactor();
int xoffset = 0, yoffset = 0; int xoffset = 0, yoffset = 0;
if (corner & CornerRight) { if (corner & CornerRight) {
@ -74,7 +78,6 @@ QPixmap circleCorner(int corner) {
if (corner & CornerBottom) { if (corner & CornerBottom) {
yoffset = size; yoffset = size;
} }
int maskType = corner / MaskMultiplier;
auto part = QRect(xoffset, yoffset, size, size); auto part = QRect(xoffset, yoffset, size, size);
auto result = style::colorizeImage(serviceMessageStyle->circle[maskType], App::msgServiceBg(), part); auto result = style::colorizeImage(serviceMessageStyle->circle[maskType], App::msgServiceBg(), part);
result.setDevicePixelRatio(cRetinaFactor()); result.setDevicePixelRatio(cRetinaFactor());
@ -116,11 +119,22 @@ int paintBubbleSide(Painter &p, int x, int y, int width, SideStyle style, Corner
} }
void paintBubblePart(Painter &p, int x, int y, int width, int height, SideStyle topStyle, SideStyle bottomStyle) { void paintBubblePart(Painter &p, int x, int y, int width, int height, SideStyle topStyle, SideStyle bottomStyle) {
if (topStyle == SideStyle::Inverted || bottomStyle == SideStyle::Inverted) {
width -= st::historyServiceMsgInvertedShrink * 2;
x += st::historyServiceMsgInvertedShrink;
}
if (int skip = paintBubbleSide(p, x, y, width, topStyle, CornerTop)) { if (int skip = paintBubbleSide(p, x, y, width, topStyle, CornerTop)) {
y += skip; y += skip;
height -= skip; height -= skip;
} }
if (int skip = paintBubbleSide(p, x, y + height - st::msgRadius, width, bottomStyle, CornerBottom)) { int bottomSize = 0;
if (bottomStyle == SideStyle::Rounded) {
bottomSize = st::historyServiceMsgRadius;
} else if (bottomStyle == SideStyle::Inverted) {
bottomSize = st::historyServiceMsgInvertedRadius;
}
if (int skip = paintBubbleSide(p, x, y + height - bottomSize, width, bottomStyle, CornerBottom)) {
height -= skip; height -= skip;
} }
@ -137,7 +151,7 @@ void paintPreparedDate(Painter &p, const QString &dateText, int dateTextWidth, i
left += (w - dateTextWidth - st::msgServicePadding.left() - st::msgServicePadding.right()) / 2; left += (w - dateTextWidth - st::msgServicePadding.left() - st::msgServicePadding.right()) / 2;
int height = st::msgServicePadding.top() + st::msgServiceFont->height + st::msgServicePadding.bottom(); int height = st::msgServicePadding.top() + st::msgServiceFont->height + st::msgServicePadding.bottom();
App::roundRect(p, left, y + st::msgServiceMargin.top(), dateTextWidth + st::msgServicePadding.left() + st::msgServicePadding.left(), height, App::msgServiceBg(), ServiceCorners); ServiceMessagePainter::paintBubble(p, left, y + st::msgServiceMargin.top(), dateTextWidth + st::msgServicePadding.left() + st::msgServicePadding.left(), height);
p.setFont(st::msgServiceFont); p.setFont(st::msgServiceFont);
p.setPen(st::msgServiceColor); p.setPen(st::msgServiceColor);
@ -180,7 +194,7 @@ void ServiceMessagePainter::paint(Painter &p, const HistoryService *message, con
QRect trect(QRect(left, st::msgServiceMargin.top(), width, height).marginsAdded(-st::msgServicePadding)); QRect trect(QRect(left, st::msgServiceMargin.top(), width, height).marginsAdded(-st::msgServicePadding));
paintBubble(p, left, width, message->_text, trect); paintComplexBubble(p, left, width, message->_text, trect);
if (width > message->maxWidth()) { if (width > message->maxWidth()) {
left += (width - message->maxWidth()) / 2; left += (width - message->maxWidth()) / 2;
@ -205,7 +219,13 @@ void ServiceMessagePainter::paintDate(Painter &p, const QString &dateText, int d
paintPreparedDate(p, dateText, dateTextWidth, y, w); paintPreparedDate(p, dateText, dateTextWidth, y, w);
} }
void ServiceMessagePainter::paintBubble(Painter &p, int left, int width, const Text &text, const QRect &textRect) { void ServiceMessagePainter::paintBubble(Painter &p, int x, int y, int w, int h) {
createCircleMasks();
paintBubblePart(p, x, y, w, h, SideStyle::Rounded, SideStyle::Rounded);
}
void ServiceMessagePainter::paintComplexBubble(Painter &p, int left, int width, const Text &text, const QRect &textRect) {
createCircleMasks(); createCircleMasks();
auto lineWidths = countLineWidths(text, textRect); auto lineWidths = countLineWidths(text, textRect);
@ -258,7 +278,7 @@ QVector<int> ServiceMessagePainter::countLineWidths(const Text &text, const QRec
lineWidths.reserve(linesCount); lineWidths.reserve(linesCount);
text.countLineWidths(textRect.width(), &lineWidths); text.countLineWidths(textRect.width(), &lineWidths);
int minDelta = 4 * st::msgRadius; int minDelta = 2 * (st::historyServiceMsgRadius + st::historyServiceMsgInvertedRadius - st::historyServiceMsgInvertedShrink);
for (int i = 0, count = lineWidths.size(); i < count; ++i) { for (int i = 0, count = lineWidths.size(); i < count; ++i) {
int width = qMax(lineWidths.at(i), 0); int width = qMax(lineWidths.at(i), 0);
if (i > 0) { if (i > 0) {

View file

@ -40,8 +40,10 @@ public:
static void paintDate(Painter &p, const QDateTime &date, int y, int w); static void paintDate(Painter &p, const QDateTime &date, int y, int w);
static void paintDate(Painter &p, const QString &dateText, int dateTextWidth, int y, int w); static void paintDate(Painter &p, const QString &dateText, int dateTextWidth, int y, int w);
static void paintBubble(Painter &p, int x, int y, int w, int h);
private: private:
static void paintBubble(Painter &p, int left, int width, const Text &text, const QRect &textRect); static void paintComplexBubble(Painter &p, int left, int width, const Text &text, const QRect &textRect);
static QVector<int> countLineWidths(const Text &text, const QRect &textRect); static QVector<int> countLineWidths(const Text &text, const QRect &textRect);
}; };

View file

@ -1472,6 +1472,10 @@ void HistoryInner::keyPressEvent(QKeyEvent *e) {
_widget->onListEscapePressed(); _widget->onListEscapePressed();
} else if (e == QKeySequence::Copy && !_selected.isEmpty()) { } else if (e == QKeySequence::Copy && !_selected.isEmpty()) {
copySelectedText(); copySelectedText();
#ifdef Q_OS_MAC
} else if (e->key() == Qt::Key_E && e->modifiers().testFlag(Qt::ControlModifier)) {
setToClipboard(getSelectedText(), QClipboard::FindBuffer);
#endif // Q_OS_MAC
} else if (e == QKeySequence::Delete) { } else if (e == QKeySequence::Delete) {
int32 selectedForForward, selectedForDelete; int32 selectedForForward, selectedForDelete;
getSelectionState(selectedForForward, selectedForDelete); getSelectionState(selectedForForward, selectedForDelete);
@ -8377,7 +8381,7 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
ImagePtr replyPreview = drawMsgText->getMedia()->replyPreview(); ImagePtr replyPreview = drawMsgText->getMedia()->replyPreview();
if (!replyPreview->isNull()) { if (!replyPreview->isNull()) {
QRect to(replyLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height()); QRect to(replyLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
p.drawPixmap(to.x(), to.y(), replyPreview->pixSingle(replyPreview->width() / cIntRetinaFactor(), replyPreview->height() / cIntRetinaFactor(), to.width(), to.height())); p.drawPixmap(to.x(), to.y(), replyPreview->pixSingle(ImageRoundRadius::Small, replyPreview->width() / cIntRetinaFactor(), replyPreview->height() / cIntRetinaFactor(), to.width(), to.height()));
} }
replyLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x(); replyLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
} }
@ -8538,7 +8542,7 @@ void HistoryWidget::drawPinnedBar(Painter &p) {
ImagePtr replyPreview = _pinnedBar->msg->getMedia()->replyPreview(); ImagePtr replyPreview = _pinnedBar->msg->getMedia()->replyPreview();
if (!replyPreview->isNull()) { if (!replyPreview->isNull()) {
QRect to(left, st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height()); QRect to(left, st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
p.drawPixmap(to.x(), to.y(), replyPreview->pixSingle(replyPreview->width() / cIntRetinaFactor(), replyPreview->height() / cIntRetinaFactor(), to.width(), to.height())); p.drawPixmap(to.x(), to.y(), replyPreview->pixSingle(ImageRoundRadius::Small, replyPreview->width() / cIntRetinaFactor(), replyPreview->height() / cIntRetinaFactor(), to.width(), to.height()));
} }
left += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x(); left += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
} }
@ -8634,7 +8638,7 @@ void HistoryWidget::paintEvent(QPaintEvent *e) {
style::font font(st::msgServiceFont); style::font font(st::msgServiceFont);
int32 w = font->width(lang(lng_willbe_history)) + st::msgPadding.left() + st::msgPadding.right(), h = font->height + st::msgServicePadding.top() + st::msgServicePadding.bottom() + 2; int32 w = font->width(lang(lng_willbe_history)) + st::msgPadding.left() + st::msgPadding.right(), h = font->height + st::msgServicePadding.top() + st::msgServicePadding.bottom() + 2;
QRect tr((width() - w) / 2, (height() - _field.height() - 2 * st::sendPadding - h) / 2, w, h); QRect tr((width() - w) / 2, (height() - _field.height() - 2 * st::sendPadding - h) / 2, w, h);
App::roundRect(p, tr, App::msgServiceBg(), ServiceCorners); HistoryLayout::ServiceMessagePainter::paintBubble(p, tr.x(), tr.y(), tr.width(), tr.height());
p.setPen(st::msgServiceColor->p); p.setPen(st::msgServiceColor->p);
p.setFont(font->f); p.setFont(font->f);

View file

@ -420,8 +420,8 @@ void Sticker::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) {
QSize Sticker::getThumbSize() const { QSize Sticker::getThumbSize() const {
int width = qMax(content_width(), 1), height = qMax(content_height(), 1); int width = qMax(content_width(), 1), height = qMax(content_height(), 1);
float64 coefw = (st::stickerPanSize.width() - st::msgRadius * 2) / float64(width); float64 coefw = (st::stickerPanSize.width() - st::buttonRadius * 2) / float64(width);
float64 coefh = (st::stickerPanSize.height() - st::msgRadius * 2) / float64(height); float64 coefh = (st::stickerPanSize.height() - st::buttonRadius * 2) / float64(height);
float64 coef = qMin(qMin(coefw, coefh), 1.); float64 coef = qMin(qMin(coefw, coefh), 1.);
int w = qRound(coef * content_width()), h = qRound(coef * content_height()); int w = qRound(coef * content_width()), h = qRound(coef * content_height());
return QSize(qMax(w, 1), qMax(h, 1)); return QSize(qMax(w, 1), qMax(h, 1));

View file

@ -215,3 +215,23 @@ style::sprite documentCorner(int32 colorIndex) {
RoundCorners documentCorners(int32 colorIndex) { RoundCorners documentCorners(int32 colorIndex) {
return RoundCorners(DocBlueCorners + (colorIndex & 3)); return RoundCorners(DocBlueCorners + (colorIndex & 3));
} }
bool documentIsValidMediaFile(const QString &filepath) {
static StaticNeverFreedPointer<QList<QString>> validMediaTypes(([] {
std_::unique_ptr<QList<QString>> result = std_::make_unique<QList<QString>>();
*result = qsl("\
webm mkv flv vob ogv ogg drc gif gifv mng avi mov qt wmv yuv rm rmvb asf amv mp4 m4p \
m4v mpg mp2 mpeg mpe mpv m2v svi 3gp 3g2 mxf roq nsv f4v f4p f4a f4b wma divx evo mk3d \
mka mks mcf m2p ps ts m2ts ifo aaf avchd cam dat dsh dvr-ms m1v fla flr sol wrap smi swf \
wtv 8svx 16svx iff aiff aif aifc au bwf cdda raw wav flac la pac m4a ape ofr ofs off rka \
shn tak tta wv brstm dts dtshd dtsma ast amr mp3 spx gsm aac mpc vqf ra ots swa vox voc \
dwd smp aup cust mid mus sib sid ly gym vgm psf nsf mod ptb s3m xm it mt2 minipsf psflib \
2sf dsf gsf psf2 qsf ssf usf rmj spc niff mxl xml txm ym jam mp1 mscz \
").split(' ');
return result.release();
})());
QFileInfo info(filepath);
auto parts = info.fileName().split('.', QString::SkipEmptyParts);
return !parts.isEmpty() && (validMediaTypes->indexOf(parts.back().toLower()) >= 0);
}

View file

@ -29,12 +29,14 @@ const TextParseOptions &itemTextOptions(History *h, PeerData *f);
const TextParseOptions &itemTextNoMonoOptions(History *h, PeerData *f); const TextParseOptions &itemTextNoMonoOptions(History *h, PeerData *f);
enum RoundCorners { enum RoundCorners {
NoneCorners = 0x00, // for images SmallMaskCorners = 0x00, // for images
BlackCorners, LargeMaskCorners,
WhiteCorners, WhiteCorners,
ServiceCorners, StickerCorners,
ServiceSelectedCorners, StickerSelectedCorners,
SelectedOverlayCorners, SelectedOverlaySmallCorners,
SelectedOverlayLargeCorners,
DateCorners, DateCorners,
DateSelectedCorners, DateSelectedCorners,
ForwardCorners, ForwardCorners,
@ -81,6 +83,7 @@ style::color documentOverColor(int32 colorIndex);
style::color documentSelectedColor(int32 colorIndex); style::color documentSelectedColor(int32 colorIndex);
style::sprite documentCorner(int32 colorIndex); style::sprite documentCorner(int32 colorIndex);
RoundCorners documentCorners(int32 colorIndex); RoundCorners documentCorners(int32 colorIndex);
bool documentIsValidMediaFile(const QString &filepath);
class PaintContextBase { class PaintContextBase {
public: public:

View file

@ -44,21 +44,9 @@ int main(int argc, char *argv[]) {
Logs::start(); // must be started before Platform is started Logs::start(); // must be started before Platform is started
Platform::start(); // must be started before QApplication is created Platform::start(); // must be started before QApplication is created
// prepare fake args to disable QT_STYLE_OVERRIDE env variable
// currently this is required in some desktop environments, including Xubuntu 15.10
// when we don't default style to "none" Qt dynamically loads GTK somehow internally and
// our own GTK dynamic load and usage leads GTK errors and freeze of the current main thread
// we can't disable our own GTK loading because it is required by libappindicator, which
// provides the tray icon for this system, because Qt tray icon is broken there
// see https://github.com/telegramdesktop/tdesktop/issues/1774
QByteArray args[] = { "-style=0" };
static const int a_cnt = sizeof(args) / sizeof(args[0]);
int a_argc = a_cnt + 1;
char *a_argv[a_cnt + 1] = { argv[0], args[0].data() };
int result = 0; int result = 0;
{ {
Application app(a_argc, a_argv); Application app(argc, argv);
result = app.exec(); result = app.exec();
} }

View file

@ -1541,7 +1541,9 @@ void MainWidget::audioPlayProgress(const AudioMsgId &audioId) {
DocumentData *audio = audioId.audio; DocumentData *audio = audioId.audio;
QString filepath = audio->filepath(DocumentData::FilePathResolveSaveFromData); QString filepath = audio->filepath(DocumentData::FilePathResolveSaveFromData);
if (!filepath.isEmpty()) { if (!filepath.isEmpty()) {
psOpenFile(filepath); if (documentIsValidMediaFile(filepath)) {
psOpenFile(filepath);
}
} }
} }
@ -1568,7 +1570,9 @@ void MainWidget::documentPlayProgress(const SongMsgId &songId) {
DocumentData *document = songId.song; DocumentData *document = songId.song;
QString filepath = document->filepath(DocumentData::FilePathResolveSaveFromData); QString filepath = document->filepath(DocumentData::FilePathResolveSaveFromData);
if (!filepath.isEmpty()) { if (!filepath.isEmpty()) {
psOpenFile(filepath); if (documentIsValidMediaFile(filepath)) {
psOpenFile(filepath);
}
} }
} }

View file

@ -505,9 +505,7 @@ void MainWindow::clearWidgets() {
intro = 0; intro = 0;
} }
if (_mediaView) { if (_mediaView) {
if (!_mediaView->isHidden()) { hideMediaview();
_mediaView->hide();
}
_mediaView->rpcClear(); _mediaView->rpcClear();
} }
title->updateBackButton(); title->updateBackButton();

View file

@ -1051,15 +1051,15 @@ void Link::paint(Painter &p, const QRect &clip, TextSelection selection, const P
if (_page && _page->photo) { if (_page && _page->photo) {
QPixmap pix; QPixmap pix;
if (_page->photo->medium->loaded()) { if (_page->photo->medium->loaded()) {
pix = _page->photo->medium->pixSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize); pix = _page->photo->medium->pixSingle(ImageRoundRadius::Small, _pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize);
} else if (_page->photo->loaded()) { } else if (_page->photo->loaded()) {
pix = _page->photo->full->pixSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize); pix = _page->photo->full->pixSingle(ImageRoundRadius::Small, _pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize);
} else { } else {
pix = _page->photo->thumb->pixSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize); pix = _page->photo->thumb->pixSingle(ImageRoundRadius::Small, _pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize);
} }
p.drawPixmapLeft(0, top, _width, pix); p.drawPixmapLeft(0, top, _width, pix);
} else if (_page && _page->document && !_page->document->thumb->isNull()) { } else if (_page && _page->document && !_page->document->thumb->isNull()) {
p.drawPixmapLeft(0, top, _width, _page->document->thumb->pixSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize)); p.drawPixmapLeft(0, top, _width, _page->document->thumb->pixSingle(ImageRoundRadius::Small, _pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize));
} else { } else {
int32 index = _letter.isEmpty() ? 0 : (_letter.at(0).unicode() % 4); int32 index = _letter.isEmpty() ? 0 : (_letter.at(0).unicode() % 4);
switch (index) { switch (index) {

View file

@ -0,0 +1,497 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram 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.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/
#include "stdafx.h"
#include "platform/linux/file_dialog_linux.h"
#include <private/qguiapplication_p.h>
#include "platform/linux/linux_libs.h"
#include "platform/linux/linux_gdk_helper.h"
#include "mainwindow.h"
#include "localstorage.h"
QStringList qt_make_filter_list(const QString &filter);
namespace Platform {
namespace FileDialog {
using Type = ::FileDialog::internal::Type;
bool Supported() {
return Platform::internal::GdkHelperLoaded()
&& (Libs::gtk_widget_hide_on_delete != nullptr)
&& (Libs::gtk_clipboard_store != nullptr)
&& (Libs::gtk_clipboard_get != nullptr)
&& (Libs::gtk_widget_destroy != nullptr)
&& (Libs::gtk_dialog_get_type != nullptr)
&& (Libs::gtk_dialog_run != nullptr)
&& (Libs::gtk_widget_realize != nullptr)
&& (Libs::gdk_window_set_modal_hint != nullptr)
&& (Libs::gtk_widget_show != nullptr)
&& (Libs::gdk_window_focus != nullptr)
&& (Libs::gtk_widget_hide != nullptr)
&& (Libs::gtk_widget_hide_on_delete != nullptr)
&& (Libs::gtk_file_chooser_dialog_new != nullptr)
&& (Libs::gtk_file_chooser_get_type != nullptr)
&& (Libs::gtk_file_chooser_set_current_folder != nullptr)
&& (Libs::gtk_file_chooser_get_current_folder != nullptr)
&& (Libs::gtk_file_chooser_set_current_name != nullptr)
&& (Libs::gtk_file_chooser_select_filename != nullptr)
&& (Libs::gtk_file_chooser_get_filenames != nullptr)
&& (Libs::gtk_file_chooser_set_filter != nullptr)
&& (Libs::gtk_file_chooser_get_filter != nullptr)
&& (Libs::gtk_window_get_type != nullptr)
&& (Libs::gtk_window_set_title != nullptr)
&& (Libs::gtk_file_chooser_set_local_only != nullptr)
&& (Libs::gtk_file_chooser_set_action != nullptr)
&& (Libs::gtk_file_chooser_set_select_multiple != nullptr)
&& (Libs::gtk_file_chooser_set_do_overwrite_confirmation != nullptr)
&& (Libs::gtk_file_chooser_remove_filter != nullptr)
&& (Libs::gtk_file_filter_set_name != nullptr)
&& (Libs::gtk_file_filter_add_pattern != nullptr)
&& (Libs::gtk_file_chooser_add_filter != nullptr)
&& (Libs::gtk_file_filter_new != nullptr);
}
bool Get(QStringList &files, QByteArray &remoteContent, const QString &caption, const QString &filter, Type type, QString startFile) {
auto parent = App::wnd() ? App::wnd()->filedialogParent() : nullptr;
internal::GtkFileDialog dialog(parent, caption, QString(), filter);
dialog.setModal(true);
if (type == Type::ReadFile || type == Type::ReadFiles) {
dialog.setFileMode((type == Type::ReadFiles) ? QFileDialog::ExistingFiles : QFileDialog::ExistingFile);
dialog.setAcceptMode(QFileDialog::AcceptOpen);
} else if (type == Type::ReadFolder) {
dialog.setAcceptMode(QFileDialog::AcceptOpen);
dialog.setFileMode(QFileDialog::Directory);
dialog.setOption(QFileDialog::ShowDirsOnly);
} else {
dialog.setFileMode(QFileDialog::AnyFile);
dialog.setAcceptMode(QFileDialog::AcceptSave);
}
if (startFile.isEmpty() || startFile.at(0) != '/') {
startFile = cDialogLastPath() + '/' + startFile;
}
dialog.selectFile(startFile);
int res = dialog.exec();
QString path = dialog.directory().absolutePath();
if (path != cDialogLastPath()) {
cSetDialogLastPath(path);
Local::writeUserSettings();
}
if (res == QDialog::Accepted) {
if (type == Type::ReadFiles) {
files = dialog.selectedFiles();
} else {
files = dialog.selectedFiles().mid(0, 1);
}
return true;
}
files = QStringList();
remoteContent = QByteArray();
return false;
}
namespace internal {
QGtkDialog::QGtkDialog(GtkWidget *gtkWidget) : gtkWidget(gtkWidget) {
Libs::g_signal_connect_swapped_helper(Libs::g_object_cast(gtkWidget), "response", GCallback(onResponse), this);
Libs::g_signal_connect_helper(Libs::g_object_cast(gtkWidget), "delete-event", GCallback(Libs::gtk_widget_hide_on_delete), NULL);
}
QGtkDialog::~QGtkDialog() {
Libs::gtk_clipboard_store(Libs::gtk_clipboard_get(GDK_SELECTION_CLIPBOARD));
Libs::gtk_widget_destroy(gtkWidget);
}
GtkDialog *QGtkDialog::gtkDialog() const {
return Libs::gtk_dialog_cast(gtkWidget);
}
void QGtkDialog::exec() {
if (auto w = App::wnd()) {
w->onReActivate();
QTimer::singleShot(200, w, SLOT(onReActivate()));
}
if (modality() == Qt::ApplicationModal) {
// block input to the whole app, including other GTK dialogs
Libs::gtk_dialog_run(gtkDialog());
} else {
// block input to the window, allow input to other GTK dialogs
QEventLoop loop;
connect(this, SIGNAL(accept()), &loop, SLOT(quit()));
connect(this, SIGNAL(reject()), &loop, SLOT(quit()));
loop.exec();
}
}
void QGtkDialog::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) {
connect(parent, &QWindow::destroyed, this, &QGtkDialog::onParentWindowDestroyed,
Qt::UniqueConnection);
setParent(parent);
setFlags(flags);
setModality(modality);
Libs::gtk_widget_realize(gtkWidget); // creates X window
if (parent) {
Platform::internal::XSetTransientForHint(Libs::gtk_widget_get_window(gtkWidget), parent->winId());
}
if (modality != Qt::NonModal) {
Libs::gdk_window_set_modal_hint(Libs::gtk_widget_get_window(gtkWidget), true);
QGuiApplicationPrivate::showModalWindow(this);
}
Libs::gtk_widget_show(gtkWidget);
Libs::gdk_window_focus(Libs::gtk_widget_get_window(gtkWidget), 0);
}
void QGtkDialog::hide() {
QGuiApplicationPrivate::hideModalWindow(this);
Libs::gtk_widget_hide(gtkWidget);
}
void QGtkDialog::onResponse(QGtkDialog *dialog, int response) {
if (response == GTK_RESPONSE_OK)
emit dialog->accept();
else
emit dialog->reject();
}
void QGtkDialog::onParentWindowDestroyed() {
// The Gtk*DialogHelper classes own this object. Make sure the parent doesn't delete it.
setParent(nullptr);
}
namespace {
const char *filterRegExp =
"^(.*)\\(([a-zA-Z0-9_.,*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$";
// Makes a list of filters from a normal filter string "Image Files (*.png *.jpg)"
QStringList cleanFilterList(const QString &filter) {
QRegExp regexp(QString::fromLatin1(filterRegExp));
Q_ASSERT(regexp.isValid());
QString f = filter;
int i = regexp.indexIn(f);
if (i >= 0)
f = regexp.cap(2);
return f.split(QLatin1Char(' '), QString::SkipEmptyParts);
}
} // namespace
GtkFileDialog::GtkFileDialog(QWidget *parent, const QString &caption, const QString &directory, const QString &filter) : QDialog(parent)
, _windowTitle(caption)
, _initialDirectory(directory) {
auto filters = qt_make_filter_list(filter);
const int numFilters = filters.count();
_nameFilters.reserve(numFilters);
for (int i = 0; i < numFilters; ++i) {
_nameFilters << filters[i].simplified();
}
d.reset(new QGtkDialog(Libs::gtk_file_chooser_dialog_new("", nullptr,
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OK, GTK_RESPONSE_OK, NULL)));
connect(d.data(), SIGNAL(accept()), this, SLOT(onAccepted()));
connect(d.data(), SIGNAL(reject()), this, SLOT(onRejected()));
Libs::g_signal_connect_helper(Libs::gtk_file_chooser_cast(d->gtkDialog()), "selection-changed", G_CALLBACK(onSelectionChanged), this);
Libs::g_signal_connect_swapped_helper(Libs::gtk_file_chooser_cast(d->gtkDialog()), "current-folder-changed", G_CALLBACK(onCurrentFolderChanged), this);
}
GtkFileDialog::~GtkFileDialog() {
}
void GtkFileDialog::showHelper(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) {
_dir.clear();
_selection.clear();
applyOptions();
return d->show(flags, modality, parent);
}
void GtkFileDialog::setVisible(bool visible) {
if (visible) {
if (testAttribute(Qt::WA_WState_ExplicitShowHide) && !testAttribute(Qt::WA_WState_Hidden)) {
return;
}
} else if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden)) {
return;
}
if (visible) {
showHelper(windowFlags(), windowModality(), parentWidget() ? parentWidget()->windowHandle() : nullptr);
} else {
hideHelper();
}
// Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below
// updates the state correctly, but skips showing the non-native version:
setAttribute(Qt::WA_DontShowOnScreen);
QDialog::setVisible(visible);
}
int GtkFileDialog::exec() {
d->setModality(windowModality());
bool deleteOnClose = testAttribute(Qt::WA_DeleteOnClose);
setAttribute(Qt::WA_DeleteOnClose, false);
bool wasShowModal = testAttribute(Qt::WA_ShowModal);
setAttribute(Qt::WA_ShowModal, true);
setResult(0);
show();
QPointer<QDialog> guard = this;
d->exec();
if (guard.isNull())
return QDialog::Rejected;
setAttribute(Qt::WA_ShowModal, wasShowModal);
return result();
}
void GtkFileDialog::hideHelper() {
// After GtkFileChooserDialog has been hidden, gtk_file_chooser_get_current_folder()
// & gtk_file_chooser_get_filenames() will return bogus values -> cache the actual
// values before hiding the dialog
_dir = directory().absolutePath();
_selection = selectedFiles();
d->hide();
}
bool GtkFileDialog::defaultNameFilterDisables() const {
return false;
}
void GtkFileDialog::setDirectory(const QString &directory) {
GtkDialog *gtkDialog = d->gtkDialog();
Libs::gtk_file_chooser_set_current_folder(Libs::gtk_file_chooser_cast(gtkDialog), directory.toUtf8());
}
QDir GtkFileDialog::directory() const {
// While GtkFileChooserDialog is hidden, gtk_file_chooser_get_current_folder()
// returns a bogus value -> return the cached value before hiding
if (!_dir.isEmpty())
return _dir;
QString ret;
GtkDialog *gtkDialog = d->gtkDialog();
gchar *folder = Libs::gtk_file_chooser_get_current_folder(Libs::gtk_file_chooser_cast(gtkDialog));
if (folder) {
ret = QString::fromUtf8(folder);
Libs::g_free(folder);
}
return QDir(ret);
}
void GtkFileDialog::selectFile(const QString &filename) {
_initialFiles.clear();
_initialFiles.append(filename);
}
QStringList GtkFileDialog::selectedFiles() const {
// While GtkFileChooserDialog is hidden, gtk_file_chooser_get_filenames()
// returns a bogus value -> return the cached value before hiding
if (!_selection.isEmpty())
return _selection;
QStringList selection;
GtkDialog *gtkDialog = d->gtkDialog();
GSList *filenames = Libs::gtk_file_chooser_get_filenames(Libs::gtk_file_chooser_cast(gtkDialog));
for (GSList *it = filenames; it; it = it->next)
selection += QString::fromUtf8((const char*)it->data);
Libs::g_slist_free(filenames);
return selection;
}
void GtkFileDialog::setFilter() {
applyOptions();
}
void GtkFileDialog::selectNameFilter(const QString &filter) {
GtkFileFilter *gtkFilter = _filters.value(filter);
if (gtkFilter) {
GtkDialog *gtkDialog = d->gtkDialog();
Libs::gtk_file_chooser_set_filter(Libs::gtk_file_chooser_cast(gtkDialog), gtkFilter);
}
}
QString GtkFileDialog::selectedNameFilter() const {
GtkDialog *gtkDialog = d->gtkDialog();
GtkFileFilter *gtkFilter = Libs::gtk_file_chooser_get_filter(Libs::gtk_file_chooser_cast(gtkDialog));
return _filterNames.value(gtkFilter);
}
void GtkFileDialog::onAccepted() {
emit accept();
// QString filter = selectedNameFilter();
// if (filter.isEmpty())
// emit filterSelected(filter);
// QList<QUrl> files = selectedFiles();
// emit filesSelected(files);
// if (files.count() == 1)
// emit fileSelected(files.first());
}
void GtkFileDialog::onRejected() {
emit reject();
//
}
void GtkFileDialog::onSelectionChanged(GtkDialog *gtkDialog, GtkFileDialog *helper) {
// QString selection;
// gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(gtkDialog));
// if (filename) {
// selection = QString::fromUtf8(filename);
// g_free(filename);
// }
// emit helper->currentChanged(QUrl::fromLocalFile(selection));
}
void GtkFileDialog::onCurrentFolderChanged(GtkFileDialog *dialog) {
// emit dialog->directoryEntered(dialog->directory());
}
GtkFileChooserAction gtkFileChooserAction(QFileDialog::FileMode fileMode, QFileDialog::AcceptMode acceptMode) {
switch (fileMode) {
case QFileDialog::AnyFile:
case QFileDialog::ExistingFile:
case QFileDialog::ExistingFiles:
if (acceptMode == QFileDialog::AcceptOpen)
return GTK_FILE_CHOOSER_ACTION_OPEN;
else
return GTK_FILE_CHOOSER_ACTION_SAVE;
case QFileDialog::Directory:
case QFileDialog::DirectoryOnly:
default:
if (acceptMode == QFileDialog::AcceptOpen)
return GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
else
return GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER;
}
}
bool CustomButtonsSupported() {
return (Libs::gtk_dialog_get_widget_for_response != nullptr)
&& (Libs::gtk_button_set_label != nullptr)
&& (Libs::gtk_button_get_type != nullptr);
}
void GtkFileDialog::applyOptions() {
GtkDialog *gtkDialog = d->gtkDialog();
Libs::gtk_window_set_title(Libs::gtk_window_cast(gtkDialog), _windowTitle.toUtf8());
Libs::gtk_file_chooser_set_local_only(Libs::gtk_file_chooser_cast(gtkDialog), true);
const GtkFileChooserAction action = gtkFileChooserAction(_fileMode, _acceptMode);
Libs::gtk_file_chooser_set_action(Libs::gtk_file_chooser_cast(gtkDialog), action);
const bool selectMultiple = (_fileMode == QFileDialog::ExistingFiles);
Libs::gtk_file_chooser_set_select_multiple(Libs::gtk_file_chooser_cast(gtkDialog), selectMultiple);
const bool confirmOverwrite = !_options.testFlag(QFileDialog::DontConfirmOverwrite);
Libs::gtk_file_chooser_set_do_overwrite_confirmation(Libs::gtk_file_chooser_cast(gtkDialog), confirmOverwrite);
if (!_nameFilters.isEmpty())
setNameFilters(_nameFilters);
if (!_initialDirectory.isEmpty())
setDirectory(_initialDirectory);
for_const (const auto &filename, _initialFiles) {
if (_acceptMode == QFileDialog::AcceptSave) {
QFileInfo fi(filename);
Libs::gtk_file_chooser_set_current_folder(Libs::gtk_file_chooser_cast(gtkDialog), fi.path().toUtf8());
Libs::gtk_file_chooser_set_current_name(Libs::gtk_file_chooser_cast(gtkDialog), fi.fileName().toUtf8());
} else if (filename.endsWith('/')) {
Libs::gtk_file_chooser_set_current_folder(Libs::gtk_file_chooser_cast(gtkDialog), filename.toUtf8());
} else {
Libs::gtk_file_chooser_select_filename(Libs::gtk_file_chooser_cast(gtkDialog), filename.toUtf8());
}
}
const QString initialNameFilter = _nameFilters.isEmpty() ? QString() : _nameFilters.front();
if (!initialNameFilter.isEmpty())
selectNameFilter(initialNameFilter);
if (CustomButtonsSupported()) {
GtkWidget *acceptButton = Libs::gtk_dialog_get_widget_for_response(gtkDialog, GTK_RESPONSE_OK);
if (acceptButton) {
/*if (opts->isLabelExplicitlySet(QFileDialogOptions::Accept))
Libs::gtk_button_set_label(Libs::gtk_button_cast(acceptButton), opts->labelText(QFileDialogOptions::Accept).toUtf8());
else*/ if (_acceptMode == QFileDialog::AcceptOpen)
Libs::gtk_button_set_label(Libs::gtk_button_cast(acceptButton), GTK_STOCK_OPEN);
else
Libs::gtk_button_set_label(Libs::gtk_button_cast(acceptButton), GTK_STOCK_SAVE);
}
GtkWidget *rejectButton = Libs::gtk_dialog_get_widget_for_response(gtkDialog, GTK_RESPONSE_CANCEL);
if (rejectButton) {
/*if (opts->isLabelExplicitlySet(QFileDialogOptions::Reject))
Libs::gtk_button_set_label(Libs::gtk_button_cast(rejectButton), opts->labelText(QFileDialogOptions::Reject).toUtf8());
else*/
Libs::gtk_button_set_label(Libs::gtk_button_cast(rejectButton), GTK_STOCK_CANCEL);
}
}
}
void GtkFileDialog::setNameFilters(const QStringList &filters) {
GtkDialog *gtkDialog = d->gtkDialog();
foreach (GtkFileFilter *filter, _filters)
Libs::gtk_file_chooser_remove_filter(Libs::gtk_file_chooser_cast(gtkDialog), filter);
_filters.clear();
_filterNames.clear();
foreach (const QString &filter, filters) {
GtkFileFilter *gtkFilter = Libs::gtk_file_filter_new();
const QString name = filter.left(filter.indexOf(QLatin1Char('(')));
const QStringList extensions = cleanFilterList(filter);
Libs::gtk_file_filter_set_name(gtkFilter, name.isEmpty() ? extensions.join(QStringLiteral(", ")).toUtf8() : name.toUtf8());
foreach (const QString &ext, extensions)
Libs::gtk_file_filter_add_pattern(gtkFilter, ext.toUtf8());
Libs::gtk_file_chooser_add_filter(Libs::gtk_file_chooser_cast(gtkDialog), gtkFilter);
_filters.insert(filter, gtkFilter);
_filterNames.insert(gtkFilter, filter);
}
}
} // namespace internal
} // namespace FileDialog
} // namespace Platform

View file

@ -0,0 +1,145 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram 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.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/
#pragma once
#include "ui/filedialog.h"
extern "C" {
#undef signals
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#define signals public
} // extern "C"
namespace Platform {
namespace FileDialog {
bool Supported();
bool Get(QStringList &files, QByteArray &remoteContent, const QString &caption, const QString &filter, ::FileDialog::internal::Type type, QString startFile);
namespace internal {
// This is a patched copy of qgtk2 theme plugin.
// We need to use our own gtk file dialog instead of
// styling Qt file dialog, because Qt only works with gtk2.
// We need to be able to work with gtk2 and gtk3, because
// we use gtk3 to work with appindicator3.
class QGtkDialog : public QWindow {
Q_OBJECT
public:
QGtkDialog(GtkWidget *gtkWidget);
~QGtkDialog();
GtkDialog *gtkDialog() const;
void exec();
void show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent);
void hide();
signals:
void accept();
void reject();
protected:
static void onResponse(QGtkDialog *dialog, int response);
private slots:
void onParentWindowDestroyed();
private:
GtkWidget *gtkWidget;
};
class GtkFileDialog : public QDialog {
Q_OBJECT
public:
GtkFileDialog(QWidget *parent = Q_NULLPTR,
const QString &caption = QString(),
const QString &directory = QString(),
const QString &filter = QString());
~GtkFileDialog();
void setVisible(bool visible) override;
void setWindowTitle(const QString &windowTitle) {
_windowTitle = windowTitle;
}
void setAcceptMode(QFileDialog::AcceptMode acceptMode) {
_acceptMode = acceptMode;
}
void setFileMode(QFileDialog::FileMode fileMode) {
_fileMode = fileMode;
}
void setOption(QFileDialog::Option option, bool on = true) {
if (on) {
_options |= option;
} else {
_options &= ~option;
}
}
int exec() override;
bool defaultNameFilterDisables() const;
void setDirectory(const QString &directory);
QDir directory() const;
void selectFile(const QString &filename);
QStringList selectedFiles() const;
void setFilter();
void selectNameFilter(const QString &filter);
QString selectedNameFilter() const;
private slots:
void onAccepted();
void onRejected();
private:
static void onSelectionChanged(GtkDialog *dialog, GtkFileDialog *helper);
static void onCurrentFolderChanged(GtkFileDialog *helper);
void applyOptions();
void setNameFilters(const QStringList &filters);
void showHelper(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent);
void hideHelper();
// Options
QFileDialog::Options _options = { 0 };
QString _windowTitle = "Choose file";
QString _initialDirectory;
QStringList _initialFiles;
QStringList _nameFilters;
QFileDialog::AcceptMode _acceptMode = QFileDialog::AcceptOpen;
QFileDialog::FileMode _fileMode = QFileDialog::ExistingFile;
QString _dir;
QStringList _selection;
QHash<QString, GtkFileFilter*> _filters;
QHash<GtkFileFilter*, QString> _filterNames;
QScopedPointer<QGtkDialog> d;
};
} // namespace internal
} // namespace FileDialog
} // namespace Platform

View file

@ -0,0 +1,114 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram 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.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/
#include "stdafx.h"
#include "platform/linux/linux_gdk_helper.h"
#include "platform/linux/linux_libs.h"
extern "C" {
#undef signals
#include <gdk/gdkx.h>
#define signals public
} // extern "C"
namespace Platform {
namespace internal {
enum class GtkLoaded {
GtkNone,
Gtk2,
Gtk3,
};
GtkLoaded gdk_helper_loaded = GtkLoaded::GtkNone;
// To be able to compile with gtk-3.0 headers as well
#define GdkDrawable GdkWindow
// Gtk 2
using f_gdk_x11_drawable_get_xdisplay = Display*(*)(GdkDrawable*);
f_gdk_x11_drawable_get_xdisplay gdk_x11_drawable_get_xdisplay = nullptr;
using f_gdk_x11_drawable_get_xid = XID(*)(GdkDrawable*);
f_gdk_x11_drawable_get_xid gdk_x11_drawable_get_xid = nullptr;
// Gtk 3
using f_gdk_x11_window_get_type = GType (*)(void);
f_gdk_x11_window_get_type gdk_x11_window_get_type = nullptr;
// To be able to compile with gtk-2.0 headers as well
template <typename Object>
inline bool gdk_is_x11_window_check(Object *obj) {
return Libs::g_type_cit_helper(obj, gdk_x11_window_get_type());
}
using f_gdk_window_get_display = GdkDisplay*(*)(GdkWindow *window);
f_gdk_window_get_display gdk_window_get_display = nullptr;
using f_gdk_x11_display_get_xdisplay = Display*(*)(GdkDisplay *display);
f_gdk_x11_display_get_xdisplay gdk_x11_display_get_xdisplay = nullptr;
using f_gdk_x11_window_get_xid = Window(*)(GdkWindow *window);
f_gdk_x11_window_get_xid gdk_x11_window_get_xid = nullptr;
bool GdkHelperLoadGtk2(QLibrary &lib) {
if (!Libs::load(lib, "gdk_x11_drawable_get_xdisplay", gdk_x11_drawable_get_xdisplay)) return false;
if (!Libs::load(lib, "gdk_x11_drawable_get_xid", gdk_x11_drawable_get_xid)) return false;
return true;
}
bool GdkHelperLoadGtk3(QLibrary &lib) {
if (!Libs::load(lib, "gdk_x11_window_get_type", gdk_x11_window_get_type)) return false;
if (!Libs::load(lib, "gdk_window_get_display", gdk_window_get_display)) return false;
if (!Libs::load(lib, "gdk_x11_display_get_xdisplay", gdk_x11_display_get_xdisplay)) return false;
if (!Libs::load(lib, "gdk_x11_window_get_xid", gdk_x11_window_get_xid)) return false;
return true;
}
void GdkHelperLoad(QLibrary &lib) {
gdk_helper_loaded = GtkLoaded::GtkNone;
if (GdkHelperLoadGtk2(lib)) {
gdk_helper_loaded = GtkLoaded::Gtk2;
} else if (GdkHelperLoadGtk3(lib)) {
gdk_helper_loaded = GtkLoaded::Gtk3;
}
}
bool GdkHelperLoaded() {
return gdk_helper_loaded != GtkLoaded::GtkNone;
}
void XSetTransientForHint(GdkWindow *window, quintptr winId) {
if (gdk_helper_loaded == GtkLoaded::Gtk2) {
::XSetTransientForHint(gdk_x11_drawable_get_xdisplay(window),
gdk_x11_drawable_get_xid(window),
winId);
} else if (gdk_helper_loaded == GtkLoaded::Gtk3) {
if (gdk_is_x11_window_check(window)) {
::XSetTransientForHint(gdk_x11_display_get_xdisplay(gdk_window_get_display(window)),
gdk_x11_window_get_xid(window),
winId);
}
}
}
} // namespace internal
} // namespace Platform

View file

@ -0,0 +1,40 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram 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.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/
#pragma once
#include <QtCore/QObject>
extern "C" {
#undef signals
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#define signals public
} // extern "C"
namespace Platform {
namespace internal {
void GdkHelperLoad(QLibrary &lib);
bool GdkHelperLoaded();
void XSetTransientForHint(GdkWindow *window, quintptr winId);
} // namespace internal
} // namespace Platform

View file

@ -21,6 +21,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "stdafx.h" #include "stdafx.h"
#include "platform/linux/linux_libs.h" #include "platform/linux/linux_libs.h"
#include "platform/linux/linux_gdk_helper.h"
namespace Platform { namespace Platform {
namespace Libs { namespace Libs {
namespace { namespace {
@ -42,27 +44,62 @@ bool loadLibrary(QLibrary &lib, const char *name, int version) {
} }
bool setupGtkBase(QLibrary &lib_gtk) { bool setupGtkBase(QLibrary &lib_gtk) {
if (!load(lib_gtk, "gtk_init_check", gtk_init_check)) return false; if (!load(lib_gtk, "gtk_init_check", gtk_init_check)) return false;
if (!load(lib_gtk, "gtk_menu_new", gtk_menu_new)) return false; if (!load(lib_gtk, "gtk_menu_new", gtk_menu_new)) return false;
if (!load(lib_gtk, "gtk_menu_get_type", gtk_menu_get_type)) return false; if (!load(lib_gtk, "gtk_menu_get_type", gtk_menu_get_type)) return false;
if (!load(lib_gtk, "gtk_menu_item_new_with_label", gtk_menu_item_new_with_label)) return false; if (!load(lib_gtk, "gtk_menu_item_new_with_label", gtk_menu_item_new_with_label)) return false;
if (!load(lib_gtk, "gtk_menu_item_set_label", gtk_menu_item_set_label)) return false; if (!load(lib_gtk, "gtk_menu_item_set_label", gtk_menu_item_set_label)) return false;
if (!load(lib_gtk, "gtk_menu_shell_append", gtk_menu_shell_append)) return false; if (!load(lib_gtk, "gtk_menu_shell_append", gtk_menu_shell_append)) return false;
if (!load(lib_gtk, "gtk_menu_shell_get_type", gtk_menu_shell_get_type)) return false; if (!load(lib_gtk, "gtk_menu_shell_get_type", gtk_menu_shell_get_type)) return false;
if (!load(lib_gtk, "gtk_widget_show", gtk_widget_show)) return false; if (!load(lib_gtk, "gtk_widget_show", gtk_widget_show)) return false;
if (!load(lib_gtk, "gtk_widget_get_toplevel", gtk_widget_get_toplevel)) return false; if (!load(lib_gtk, "gtk_widget_hide", gtk_widget_hide)) return false;
if (!load(lib_gtk, "gtk_widget_get_visible", gtk_widget_get_visible)) return false; if (!load(lib_gtk, "gtk_widget_get_toplevel", gtk_widget_get_toplevel)) return false;
if (!load(lib_gtk, "gtk_widget_set_sensitive", gtk_widget_set_sensitive)) return false; if (!load(lib_gtk, "gtk_widget_get_visible", gtk_widget_get_visible)) return false;
if (!load(lib_gtk, "gtk_widget_get_window", gtk_widget_get_window)) return false;
if (!load(lib_gtk, "gtk_widget_set_sensitive", gtk_widget_set_sensitive)) return false;
if (!load(lib_gtk, "gtk_widget_realize", gtk_widget_realize)) return false;
if (!load(lib_gtk, "gtk_widget_hide_on_delete", gtk_widget_hide_on_delete)) return false;
if (!load(lib_gtk, "gtk_widget_destroy", gtk_widget_destroy)) return false;
if (!load(lib_gtk, "gtk_clipboard_get", gtk_clipboard_get)) return false;
if (!load(lib_gtk, "gtk_clipboard_store", gtk_clipboard_store)) return false;
if (!load(lib_gtk, "gtk_file_chooser_dialog_new", gtk_file_chooser_dialog_new)) return false;
if (!load(lib_gtk, "gtk_file_chooser_get_type", gtk_file_chooser_get_type)) return false;
if (!load(lib_gtk, "gtk_file_chooser_set_current_folder", gtk_file_chooser_set_current_folder)) return false;
if (!load(lib_gtk, "gtk_file_chooser_get_current_folder", gtk_file_chooser_get_current_folder)) return false;
if (!load(lib_gtk, "gtk_file_chooser_set_current_name", gtk_file_chooser_set_current_name)) return false;
if (!load(lib_gtk, "gtk_file_chooser_select_filename", gtk_file_chooser_select_filename)) return false;
if (!load(lib_gtk, "gtk_file_chooser_get_filenames", gtk_file_chooser_get_filenames)) return false;
if (!load(lib_gtk, "gtk_file_chooser_set_filter", gtk_file_chooser_set_filter)) return false;
if (!load(lib_gtk, "gtk_file_chooser_get_filter", gtk_file_chooser_get_filter)) return false;
if (!load(lib_gtk, "gtk_window_get_type", gtk_window_get_type)) return false;
if (!load(lib_gtk, "gtk_window_set_title", gtk_window_set_title)) return false;
if (!load(lib_gtk, "gtk_file_chooser_set_local_only", gtk_file_chooser_set_local_only)) return false;
if (!load(lib_gtk, "gtk_file_chooser_set_action", gtk_file_chooser_set_action)) return false;
if (!load(lib_gtk, "gtk_file_chooser_set_select_multiple", gtk_file_chooser_set_select_multiple)) return false;
if (!load(lib_gtk, "gtk_file_chooser_set_do_overwrite_confirmation", gtk_file_chooser_set_do_overwrite_confirmation)) return false;
if (!load(lib_gtk, "gtk_file_chooser_remove_filter", gtk_file_chooser_remove_filter)) return false;
if (!load(lib_gtk, "gtk_file_filter_set_name", gtk_file_filter_set_name)) return false;
if (!load(lib_gtk, "gtk_file_filter_add_pattern", gtk_file_filter_add_pattern)) return false;
if (!load(lib_gtk, "gtk_file_chooser_add_filter", gtk_file_chooser_add_filter)) return false;
if (!load(lib_gtk, "gtk_file_filter_new", gtk_file_filter_new)) return false;
if (!load(lib_gtk, "g_type_check_instance_cast", g_type_check_instance_cast)) return false; if (!load(lib_gtk, "gdk_window_set_modal_hint", gdk_window_set_modal_hint)) return false;
if (!load(lib_gtk, "g_signal_connect_data", g_signal_connect_data)) return false; if (!load(lib_gtk, "gdk_window_focus", gdk_window_focus)) return false;
if (!load(lib_gtk, "gtk_dialog_get_type", gtk_dialog_get_type)) return false;
if (!load(lib_gtk, "gtk_dialog_run", gtk_dialog_run)) return false;
if (!load(lib_gtk, "g_object_ref_sink", g_object_ref_sink)) return false; if (!load(lib_gtk, "g_type_check_instance_cast", g_type_check_instance_cast)) return false;
if (!load(lib_gtk, "g_object_unref", g_object_unref)) return false; if (!load(lib_gtk, "g_type_check_instance_is_a", g_type_check_instance_is_a)) return false;
if (!load(lib_gtk, "g_signal_connect_data", g_signal_connect_data)) return false;
DEBUG_LOG(("Library gtk functions loaded!")); if (!load(lib_gtk, "g_object_ref_sink", g_object_ref_sink)) return false;
if (!gtk_init_check(0, 0)) { if (!load(lib_gtk, "g_object_unref", g_object_unref)) return false;
if (!load(lib_gtk, "g_free", g_free)) return false;
if (!load(lib_gtk, "g_slist_free", g_slist_free)) return false;
DEBUG_LOG(("Library gtk functions loaded!"));
if (!gtk_init_check(0, 0)) {
gtk_init_check = nullptr; gtk_init_check = nullptr;
DEBUG_LOG(("Failed to gtk_init_check(0, 0)!")); DEBUG_LOG(("Failed to gtk_init_check(0, 0)!"));
return false; return false;
@ -73,12 +110,12 @@ bool setupGtkBase(QLibrary &lib_gtk) {
} }
bool setupAppIndicator(QLibrary &lib_indicator) { bool setupAppIndicator(QLibrary &lib_indicator) {
if (!load(lib_indicator, "app_indicator_new", app_indicator_new)) return false; if (!load(lib_indicator, "app_indicator_new", app_indicator_new)) return false;
if (!load(lib_indicator, "app_indicator_set_status", app_indicator_set_status)) return false; if (!load(lib_indicator, "app_indicator_set_status", app_indicator_set_status)) return false;
if (!load(lib_indicator, "app_indicator_set_menu", app_indicator_set_menu)) return false; if (!load(lib_indicator, "app_indicator_set_menu", app_indicator_set_menu)) return false;
if (!load(lib_indicator, "app_indicator_set_icon_full", app_indicator_set_icon_full)) return false; if (!load(lib_indicator, "app_indicator_set_icon_full", app_indicator_set_icon_full)) return false;
DEBUG_LOG(("Library appindicator functions loaded!")); DEBUG_LOG(("Library appindicator functions loaded!"));
return true; return true;
} }
@ -92,10 +129,45 @@ f_gtk_menu_item_set_label gtk_menu_item_set_label = nullptr;
f_gtk_menu_shell_append gtk_menu_shell_append = nullptr; f_gtk_menu_shell_append gtk_menu_shell_append = nullptr;
f_gtk_menu_shell_get_type gtk_menu_shell_get_type = nullptr; f_gtk_menu_shell_get_type gtk_menu_shell_get_type = nullptr;
f_gtk_widget_show gtk_widget_show = nullptr; f_gtk_widget_show gtk_widget_show = nullptr;
f_gtk_widget_hide gtk_widget_hide = nullptr;
f_gtk_widget_get_toplevel gtk_widget_get_toplevel = nullptr; f_gtk_widget_get_toplevel gtk_widget_get_toplevel = nullptr;
f_gtk_widget_get_visible gtk_widget_get_visible = nullptr; f_gtk_widget_get_visible gtk_widget_get_visible = nullptr;
f_gtk_widget_get_window gtk_widget_get_window = nullptr;
f_gtk_widget_set_sensitive gtk_widget_set_sensitive = nullptr; f_gtk_widget_set_sensitive gtk_widget_set_sensitive = nullptr;
f_gtk_widget_realize gtk_widget_realize = nullptr;
f_gtk_widget_hide_on_delete gtk_widget_hide_on_delete = nullptr;
f_gtk_widget_destroy gtk_widget_destroy = nullptr;
f_gtk_clipboard_get gtk_clipboard_get = nullptr;
f_gtk_clipboard_store gtk_clipboard_store = nullptr;
f_gtk_file_chooser_dialog_new gtk_file_chooser_dialog_new = nullptr;
f_gtk_file_chooser_get_type gtk_file_chooser_get_type = nullptr;
f_gtk_file_chooser_set_current_folder gtk_file_chooser_set_current_folder = nullptr;
f_gtk_file_chooser_get_current_folder gtk_file_chooser_get_current_folder = nullptr;
f_gtk_file_chooser_set_current_name gtk_file_chooser_set_current_name = nullptr;
f_gtk_file_chooser_select_filename gtk_file_chooser_select_filename = nullptr;
f_gtk_file_chooser_get_filenames gtk_file_chooser_get_filenames = nullptr;
f_gtk_file_chooser_set_filter gtk_file_chooser_set_filter = nullptr;
f_gtk_file_chooser_get_filter gtk_file_chooser_get_filter = nullptr;
f_gtk_window_get_type gtk_window_get_type = nullptr;
f_gtk_window_set_title gtk_window_set_title = nullptr;
f_gtk_file_chooser_set_local_only gtk_file_chooser_set_local_only = nullptr;
f_gtk_file_chooser_set_action gtk_file_chooser_set_action = nullptr;
f_gtk_file_chooser_set_select_multiple gtk_file_chooser_set_select_multiple = nullptr;
f_gtk_file_chooser_set_do_overwrite_confirmation gtk_file_chooser_set_do_overwrite_confirmation = nullptr;
f_gtk_file_chooser_remove_filter gtk_file_chooser_remove_filter = nullptr;
f_gtk_file_filter_set_name gtk_file_filter_set_name = nullptr;
f_gtk_file_filter_add_pattern gtk_file_filter_add_pattern = nullptr;
f_gtk_file_chooser_add_filter gtk_file_chooser_add_filter = nullptr;
f_gtk_file_filter_new gtk_file_filter_new = nullptr;
f_gtk_dialog_get_widget_for_response gtk_dialog_get_widget_for_response = nullptr;
f_gtk_button_set_label gtk_button_set_label = nullptr;
f_gtk_button_get_type gtk_button_get_type = nullptr;
f_gdk_window_set_modal_hint gdk_window_set_modal_hint = nullptr;
f_gdk_window_focus gdk_window_focus = nullptr;
f_gtk_dialog_get_type gtk_dialog_get_type = nullptr;
f_gtk_dialog_run gtk_dialog_run = nullptr;
f_g_type_check_instance_cast g_type_check_instance_cast = nullptr; f_g_type_check_instance_cast g_type_check_instance_cast = nullptr;
f_g_type_check_instance_is_a g_type_check_instance_is_a = nullptr;
f_g_signal_connect_data g_signal_connect_data = nullptr; f_g_signal_connect_data g_signal_connect_data = nullptr;
f_app_indicator_new app_indicator_new = nullptr; f_app_indicator_new app_indicator_new = nullptr;
f_app_indicator_set_status app_indicator_set_status = nullptr; f_app_indicator_set_status app_indicator_set_status = nullptr;
@ -118,9 +190,13 @@ f_gtk_get_current_event_time gtk_get_current_event_time = nullptr;
f_g_object_ref_sink g_object_ref_sink = nullptr; f_g_object_ref_sink g_object_ref_sink = nullptr;
f_g_object_unref g_object_unref = nullptr; f_g_object_unref g_object_unref = nullptr;
f_g_idle_add g_idle_add = nullptr; f_g_idle_add g_idle_add = nullptr;
f_g_free g_free = nullptr;
f_g_slist_free g_slist_free = nullptr;
#ifndef TDESKTOP_DISABLE_UNITY_INTEGRATION
f_unity_launcher_entry_set_count unity_launcher_entry_set_count = nullptr; f_unity_launcher_entry_set_count unity_launcher_entry_set_count = nullptr;
f_unity_launcher_entry_set_count_visible unity_launcher_entry_set_count_visible = nullptr; f_unity_launcher_entry_set_count_visible unity_launcher_entry_set_count_visible = nullptr;
f_unity_launcher_entry_get_for_desktop_id unity_launcher_entry_get_for_desktop_id = nullptr; f_unity_launcher_entry_get_for_desktop_id unity_launcher_entry_get_for_desktop_id = nullptr;
#endif // TDESKTOP_DISABLE_UNITY_INTEGRATION
void start() { void start() {
DEBUG_LOG(("Loading libraries")); DEBUG_LOG(("Loading libraries"));
@ -170,10 +246,17 @@ void start() {
load(lib_gtk, "gtk_menu_popup", gtk_menu_popup); load(lib_gtk, "gtk_menu_popup", gtk_menu_popup);
load(lib_gtk, "gtk_get_current_event_time", gtk_get_current_event_time); load(lib_gtk, "gtk_get_current_event_time", gtk_get_current_event_time);
load(lib_gtk, "g_idle_add", g_idle_add); load(lib_gtk, "g_idle_add", g_idle_add);
internal::GdkHelperLoad(lib_gtk);
load(lib_gtk, "gtk_dialog_get_widget_for_response", gtk_dialog_get_widget_for_response);
load(lib_gtk, "gtk_button_set_label", gtk_button_set_label);
load(lib_gtk, "gtk_button_get_type", gtk_button_get_type);
} else { } else {
LOG(("Could not load gtk-x11-2.0!")); LOG(("Could not load gtk-x11-2.0!"));
} }
#ifndef TDESKTOP_DISABLE_UNITY_INTEGRATION
if (QString(getenv("XDG_CURRENT_DESKTOP")).toLower() == qstr("unity")) { if (QString(getenv("XDG_CURRENT_DESKTOP")).toLower() == qstr("unity")) {
QLibrary lib_unity(qstr("unity"), 9, 0); QLibrary lib_unity(qstr("unity"), 9, 0);
loadLibrary(lib_unity, "unity", 9); loadLibrary(lib_unity, "unity", 9);
@ -182,6 +265,7 @@ void start() {
load(lib_unity, "unity_launcher_entry_set_count", unity_launcher_entry_set_count); load(lib_unity, "unity_launcher_entry_set_count", unity_launcher_entry_set_count);
load(lib_unity, "unity_launcher_entry_set_count_visible", unity_launcher_entry_set_count_visible); load(lib_unity, "unity_launcher_entry_set_count_visible", unity_launcher_entry_set_count_visible);
} }
#endif // TDESKTOP_DISABLE_UNITY_INTEGRATION
} }
} // namespace Libs } // namespace Libs

View file

@ -24,10 +24,13 @@ extern "C" {
#undef signals #undef signals
#include <libappindicator/app-indicator.h> #include <libappindicator/app-indicator.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <gdk/gdk.h>
#define signals public #define signals public
} // extern "C" } // extern "C"
#ifndef TDESKTOP_DISABLE_UNITY_INTEGRATION
#include <unity/unity/unity.h> #include <unity/unity/unity.h>
#endif // TDESKTOP_DISABLE_UNITY_INTEGRATION
namespace Platform { namespace Platform {
namespace Libs { namespace Libs {
@ -73,15 +76,102 @@ extern f_gtk_menu_shell_get_type gtk_menu_shell_get_type;
typedef void (*f_gtk_widget_show)(GtkWidget *widget); typedef void (*f_gtk_widget_show)(GtkWidget *widget);
extern f_gtk_widget_show gtk_widget_show; extern f_gtk_widget_show gtk_widget_show;
typedef void (*f_gtk_widget_hide)(GtkWidget *widget);
extern f_gtk_widget_hide gtk_widget_hide;
typedef GtkWidget* (*f_gtk_widget_get_toplevel)(GtkWidget *widget); typedef GtkWidget* (*f_gtk_widget_get_toplevel)(GtkWidget *widget);
extern f_gtk_widget_get_toplevel gtk_widget_get_toplevel; extern f_gtk_widget_get_toplevel gtk_widget_get_toplevel;
typedef gboolean (*f_gtk_widget_get_visible)(GtkWidget *widget); typedef gboolean (*f_gtk_widget_get_visible)(GtkWidget *widget);
extern f_gtk_widget_get_visible gtk_widget_get_visible; extern f_gtk_widget_get_visible gtk_widget_get_visible;
typedef GdkWindow* (*f_gtk_widget_get_window)(GtkWidget *widget);
extern f_gtk_widget_get_window gtk_widget_get_window;
typedef void (*f_gtk_widget_set_sensitive)(GtkWidget *widget, gboolean sensitive); typedef void (*f_gtk_widget_set_sensitive)(GtkWidget *widget, gboolean sensitive);
extern f_gtk_widget_set_sensitive gtk_widget_set_sensitive; extern f_gtk_widget_set_sensitive gtk_widget_set_sensitive;
typedef void (*f_gtk_widget_realize)(GtkWidget *widget);
extern f_gtk_widget_realize gtk_widget_realize;
typedef gboolean (*f_gtk_widget_hide_on_delete)(GtkWidget *widget);
extern f_gtk_widget_hide_on_delete gtk_widget_hide_on_delete;
typedef void (*f_gtk_widget_destroy)(GtkWidget *widget);
extern f_gtk_widget_destroy gtk_widget_destroy;
typedef GtkClipboard* (*f_gtk_clipboard_get)(GdkAtom selection);
extern f_gtk_clipboard_get gtk_clipboard_get;
typedef void (*f_gtk_clipboard_store)(GtkClipboard *clipboard);
extern f_gtk_clipboard_store gtk_clipboard_store;
typedef GtkWidget* (*f_gtk_file_chooser_dialog_new)(const gchar *title, GtkWindow *parent, GtkFileChooserAction action, const gchar *first_button_text, ...) G_GNUC_NULL_TERMINATED;
extern f_gtk_file_chooser_dialog_new gtk_file_chooser_dialog_new;
typedef gboolean (*f_gtk_file_chooser_set_current_folder)(GtkFileChooser *chooser, const gchar *filename);
extern f_gtk_file_chooser_set_current_folder gtk_file_chooser_set_current_folder;
typedef gchar *(*f_gtk_file_chooser_get_current_folder)(GtkFileChooser *chooser);
extern f_gtk_file_chooser_get_current_folder gtk_file_chooser_get_current_folder;
typedef void (*f_gtk_file_chooser_set_current_name)(GtkFileChooser *chooser, const gchar *name);
extern f_gtk_file_chooser_set_current_name gtk_file_chooser_set_current_name;
typedef gboolean (*f_gtk_file_chooser_select_filename)(GtkFileChooser *chooser, const char *filename);
extern f_gtk_file_chooser_select_filename gtk_file_chooser_select_filename;
typedef GSList* (*f_gtk_file_chooser_get_filenames)(GtkFileChooser *chooser);
extern f_gtk_file_chooser_get_filenames gtk_file_chooser_get_filenames;
typedef void (*f_gtk_file_chooser_set_filter)(GtkFileChooser *chooser, GtkFileFilter *filter);
extern f_gtk_file_chooser_set_filter gtk_file_chooser_set_filter;
typedef GtkFileFilter* (*f_gtk_file_chooser_get_filter)(GtkFileChooser *chooser);
extern f_gtk_file_chooser_get_filter gtk_file_chooser_get_filter;
typedef void (*f_gtk_window_set_title)(GtkWindow *window, const gchar *title);
extern f_gtk_window_set_title gtk_window_set_title;
typedef void (*f_gtk_file_chooser_set_local_only)(GtkFileChooser *chooser, gboolean local_only);
extern f_gtk_file_chooser_set_local_only gtk_file_chooser_set_local_only;
typedef void (*f_gtk_file_chooser_set_action)(GtkFileChooser *chooser, GtkFileChooserAction action);
extern f_gtk_file_chooser_set_action gtk_file_chooser_set_action;
typedef void (*f_gtk_file_chooser_set_select_multiple)(GtkFileChooser *chooser, gboolean select_multiple);
extern f_gtk_file_chooser_set_select_multiple gtk_file_chooser_set_select_multiple;
typedef void (*f_gtk_file_chooser_set_do_overwrite_confirmation)(GtkFileChooser *chooser, gboolean do_overwrite_confirmation);
extern f_gtk_file_chooser_set_do_overwrite_confirmation gtk_file_chooser_set_do_overwrite_confirmation;
typedef GtkWidget* (*f_gtk_dialog_get_widget_for_response)(GtkDialog *dialog, gint response_id);
extern f_gtk_dialog_get_widget_for_response gtk_dialog_get_widget_for_response;
typedef void (*f_gtk_button_set_label)(GtkButton *button, const gchar *label);
extern f_gtk_button_set_label gtk_button_set_label;
typedef void (*f_gtk_file_chooser_remove_filter)(GtkFileChooser *chooser, GtkFileFilter *filter);
extern f_gtk_file_chooser_remove_filter gtk_file_chooser_remove_filter;
typedef void (*f_gtk_file_filter_set_name)(GtkFileFilter *filter, const gchar *name);
extern f_gtk_file_filter_set_name gtk_file_filter_set_name;
typedef void (*f_gtk_file_filter_add_pattern)(GtkFileFilter *filter, const gchar *pattern);
extern f_gtk_file_filter_add_pattern gtk_file_filter_add_pattern;
typedef void (*f_gtk_file_chooser_add_filter)(GtkFileChooser *chooser, GtkFileFilter *filter);
extern f_gtk_file_chooser_add_filter gtk_file_chooser_add_filter;
typedef GtkFileFilter* (*f_gtk_file_filter_new)(void);
extern f_gtk_file_filter_new gtk_file_filter_new;
typedef void (*f_gdk_window_set_modal_hint)(GdkWindow *window, gboolean modal);
extern f_gdk_window_set_modal_hint gdk_window_set_modal_hint;
typedef void (*f_gdk_window_focus)(GdkWindow *window, guint32 timestamp);
extern f_gdk_window_focus gdk_window_focus;
typedef GTypeInstance* (*f_g_type_check_instance_cast)(GTypeInstance *instance, GType iface_type); typedef GTypeInstance* (*f_g_type_check_instance_cast)(GTypeInstance *instance, GType iface_type);
extern f_g_type_check_instance_cast g_type_check_instance_cast; extern f_g_type_check_instance_cast g_type_check_instance_cast;
@ -89,21 +179,82 @@ template <typename Result, typename Object>
inline Result *g_type_cic_helper(Object *instance, GType iface_type) { inline Result *g_type_cic_helper(Object *instance, GType iface_type) {
return reinterpret_cast<Result*>(g_type_check_instance_cast(reinterpret_cast<GTypeInstance*>(instance), iface_type)); return reinterpret_cast<Result*>(g_type_check_instance_cast(reinterpret_cast<GTypeInstance*>(instance), iface_type));
} }
template <typename Object> template <typename Object>
inline GtkMenu *gtk_menu_cast(Object *obj) { inline GtkMenu *gtk_menu_cast(Object *obj) {
return g_type_cic_helper<GtkMenu, Object>(obj, gtk_menu_get_type()); return g_type_cic_helper<GtkMenu, Object>(obj, gtk_menu_get_type());
} }
template <typename Object> template <typename Object>
inline GtkMenuShell *gtk_menu_shell_cast(Object *obj) { inline GtkMenuShell *gtk_menu_shell_cast(Object *obj) {
return g_type_cic_helper<GtkMenuShell, Object>(obj, gtk_menu_get_type()); return g_type_cic_helper<GtkMenuShell, Object>(obj, gtk_menu_get_type());
} }
typedef GType (*f_gtk_dialog_get_type)(void) G_GNUC_CONST;
extern f_gtk_dialog_get_type gtk_dialog_get_type;
template <typename Object>
inline GtkDialog *gtk_dialog_cast(Object *obj) {
return g_type_cic_helper<GtkDialog, Object>(obj, gtk_dialog_get_type());
}
template <typename Object>
inline GObject *g_object_cast(Object *obj) {
return g_type_cic_helper<GObject, Object>(obj, G_TYPE_OBJECT);
}
typedef GType (*f_gtk_file_chooser_get_type)(void) G_GNUC_CONST;
extern f_gtk_file_chooser_get_type gtk_file_chooser_get_type;
template <typename Object>
inline GtkFileChooser *gtk_file_chooser_cast(Object *obj) {
return g_type_cic_helper<GtkFileChooser, Object>(obj, gtk_file_chooser_get_type());
}
typedef GType (*f_gtk_button_get_type)(void) G_GNUC_CONST;
extern f_gtk_button_get_type gtk_button_get_type;
template <typename Object>
inline GtkButton *gtk_button_cast(Object *obj) {
return g_type_cic_helper<GtkButton, Object>(obj, gtk_button_get_type());
}
typedef GType (*f_gtk_window_get_type)(void) G_GNUC_CONST;
extern f_gtk_window_get_type gtk_window_get_type;
template <typename Object>
inline GtkWindow *gtk_window_cast(Object *obj) {
return g_type_cic_helper<GtkWindow, Object>(obj, gtk_window_get_type());
}
typedef gboolean (*f_g_type_check_instance_is_a)(GTypeInstance *instance, GType iface_type) G_GNUC_PURE;
extern f_g_type_check_instance_is_a g_type_check_instance_is_a;
template <typename Object>
inline bool g_type_cit_helper(Object *instance, GType iface_type) {
if (!instance) return false;
auto ginstance = reinterpret_cast<GTypeInstance*>(instance);
if (ginstance->g_class && ginstance->g_class->g_type == iface_type) {
return true;
}
return g_type_check_instance_is_a(ginstance, iface_type);
}
typedef gint (*f_gtk_dialog_run)(GtkDialog *dialog);
extern f_gtk_dialog_run gtk_dialog_run;
typedef gulong (*f_g_signal_connect_data)(gpointer instance, const gchar *detailed_signal, GCallback c_handler, gpointer data, GClosureNotify destroy_data, GConnectFlags connect_flags); typedef gulong (*f_g_signal_connect_data)(gpointer instance, const gchar *detailed_signal, GCallback c_handler, gpointer data, GClosureNotify destroy_data, GConnectFlags connect_flags);
extern f_g_signal_connect_data g_signal_connect_data; extern f_g_signal_connect_data g_signal_connect_data;
inline gulong g_signal_connect_helper(gpointer instance, const gchar *detailed_signal, GCallback c_handler, gpointer data) { inline gulong g_signal_connect_helper(gpointer instance, const gchar *detailed_signal, GCallback c_handler, gpointer data) {
return g_signal_connect_data(instance, detailed_signal, c_handler, data, NULL, (GConnectFlags)0); return g_signal_connect_data(instance, detailed_signal, c_handler, data, NULL, (GConnectFlags)0);
} }
inline gulong g_signal_connect_swapped_helper(gpointer instance, const gchar *detailed_signal, GCallback c_handler, gpointer data) {
return g_signal_connect_data(instance, detailed_signal, c_handler, data, NULL, G_CONNECT_SWAPPED);
}
typedef AppIndicator* (*f_app_indicator_new)(const gchar *id, const gchar *icon_name, AppIndicatorCategory category); typedef AppIndicator* (*f_app_indicator_new)(const gchar *id, const gchar *icon_name, AppIndicatorCategory category);
extern f_app_indicator_new app_indicator_new; extern f_app_indicator_new app_indicator_new;
@ -167,6 +318,13 @@ extern f_g_object_unref g_object_unref;
typedef guint (*f_g_idle_add)(GSourceFunc function, gpointer data); typedef guint (*f_g_idle_add)(GSourceFunc function, gpointer data);
extern f_g_idle_add g_idle_add; extern f_g_idle_add g_idle_add;
typedef void (*f_g_free)(gpointer mem);
extern f_g_free g_free;
typedef void (*f_g_slist_free)(GSList *list);
extern f_g_slist_free g_slist_free;
#ifndef TDESKTOP_DISABLE_UNITY_INTEGRATION
typedef void (*f_unity_launcher_entry_set_count)(UnityLauncherEntry* self, gint64 value); typedef void (*f_unity_launcher_entry_set_count)(UnityLauncherEntry* self, gint64 value);
extern f_unity_launcher_entry_set_count unity_launcher_entry_set_count; extern f_unity_launcher_entry_set_count unity_launcher_entry_set_count;
@ -175,6 +333,7 @@ extern f_unity_launcher_entry_set_count_visible unity_launcher_entry_set_count_v
typedef UnityLauncherEntry* (*f_unity_launcher_entry_get_for_desktop_id)(const gchar* desktop_id); typedef UnityLauncherEntry* (*f_unity_launcher_entry_get_for_desktop_id)(const gchar* desktop_id);
extern f_unity_launcher_entry_get_for_desktop_id unity_launcher_entry_get_for_desktop_id; extern f_unity_launcher_entry_get_for_desktop_id unity_launcher_entry_get_for_desktop_id;
#endif // TDESKTOP_DISABLE_UNITY_INTEGRATION
} // namespace Libs } // namespace Libs
} // namespace Platform } // namespace Platform

View file

@ -181,7 +181,9 @@ static gboolean _trayIconCheck(gpointer/* pIn*/) {
return FALSE; return FALSE;
} }
#ifndef TDESKTOP_DISABLE_UNITY_INTEGRATION
UnityLauncherEntry *_psUnityLauncherEntry = nullptr; UnityLauncherEntry *_psUnityLauncherEntry = nullptr;
#endif // TDESKTOP_DISABLE_UNITY_INTEGRATION
} // namespace } // namespace
@ -319,6 +321,7 @@ void MainWindow::psUpdateCounter() {
int32 counter = App::histories().unreadBadge(); int32 counter = App::histories().unreadBadge();
setWindowTitle((counter > 0) ? qsl("Telegram (%1)").arg(counter) : qsl("Telegram")); setWindowTitle((counter > 0) ? qsl("Telegram (%1)").arg(counter) : qsl("Telegram"));
#ifndef TDESKTOP_DISABLE_UNITY_INTEGRATION
if (_psUnityLauncherEntry) { if (_psUnityLauncherEntry) {
if (counter > 0) { if (counter > 0) {
Libs::unity_launcher_entry_set_count(_psUnityLauncherEntry, (counter > 9999) ? 9999 : counter); Libs::unity_launcher_entry_set_count(_psUnityLauncherEntry, (counter > 9999) ? 9999 : counter);
@ -327,6 +330,7 @@ void MainWindow::psUpdateCounter() {
Libs::unity_launcher_entry_set_count_visible(_psUnityLauncherEntry, FALSE); Libs::unity_launcher_entry_set_count_visible(_psUnityLauncherEntry, FALSE);
} }
} }
#endif // TDESKTOP_DISABLE_UNITY_INTEGRATION
if (noQtTrayIcon) { if (noQtTrayIcon) {
if (useAppIndicator) { if (useAppIndicator) {
@ -416,12 +420,14 @@ void MainWindow::LibsLoaded() {
DEBUG_LOG(("Status icon api loaded!")); DEBUG_LOG(("Status icon api loaded!"));
} }
#ifndef TDESKTOP_DISABLE_UNITY_INTEGRATION
useUnityCount = (Libs::unity_launcher_entry_get_for_desktop_id != nullptr) useUnityCount = (Libs::unity_launcher_entry_get_for_desktop_id != nullptr)
&& (Libs::unity_launcher_entry_set_count != nullptr) && (Libs::unity_launcher_entry_set_count != nullptr)
&& (Libs::unity_launcher_entry_set_count_visible != nullptr); && (Libs::unity_launcher_entry_set_count_visible != nullptr);
if (useUnityCount) { if (useUnityCount) {
DEBUG_LOG(("Unity count api loaded!")); DEBUG_LOG(("Unity count api loaded!"));
} }
#endif // TDESKTOP_DISABLE_UNITY_INTEGRATION
} }
void MainWindow::psUpdateDelegate() { void MainWindow::psUpdateDelegate() {
@ -598,6 +604,7 @@ void MainWindow::psCreateTrayIcon() {
void MainWindow::psFirstShow() { void MainWindow::psFirstShow() {
psCreateTrayIcon(); psCreateTrayIcon();
#ifndef TDESKTOP_DISABLE_UNITY_INTEGRATION
if (useUnityCount) { if (useUnityCount) {
_psUnityLauncherEntry = Libs::unity_launcher_entry_get_for_desktop_id("telegramdesktop.desktop"); _psUnityLauncherEntry = Libs::unity_launcher_entry_get_for_desktop_id("telegramdesktop.desktop");
if (_psUnityLauncherEntry) { if (_psUnityLauncherEntry) {
@ -613,6 +620,7 @@ void MainWindow::psFirstShow() {
} else { } else {
LOG(("Not using Unity Launcher count.")); LOG(("Not using Unity Launcher count."));
} }
#endif // TDESKTOP_DISABLE_UNITY_INTEGRATION
psUpdateMargins(); psUpdateMargins();

View file

@ -484,12 +484,12 @@ void MainWindow::psNotifyShown(NotifyWindow *w) {
} }
void MainWindow::psPlatformNotify(HistoryItem *item, int32 fwdCount) { void MainWindow::psPlatformNotify(HistoryItem *item, int32 fwdCount) {
QString title = (!App::passcoded() && cNotifyView() <= dbinvShowName) ? item->history()->peer->name : qsl("Telegram Desktop"); QString title = (!App::passcoded() && cNotifyView() <= dbinvShowName && !Global::ScreenIsLocked()) ? item->history()->peer->name : qsl("Telegram Desktop");
QString subtitle = (!App::passcoded() && cNotifyView() <= dbinvShowName) ? item->notificationHeader() : QString(); QString subtitle = (!App::passcoded() && cNotifyView() <= dbinvShowName && !Global::ScreenIsLocked()) ? item->notificationHeader() : QString();
QPixmap pix = (!App::passcoded() && cNotifyView() <= dbinvShowName) ? item->history()->peer->genUserpic(st::notifyMacPhotoSize) : QPixmap(); QPixmap pix = (!App::passcoded() && cNotifyView() <= dbinvShowName && !Global::ScreenIsLocked()) ? item->history()->peer->genUserpic(st::notifyMacPhotoSize) : QPixmap();
QString msg = (!App::passcoded() && cNotifyView() <= dbinvShowPreview) ? (fwdCount < 2 ? item->notificationText() : lng_forward_messages(lt_count, fwdCount)) : lang(lng_notification_preview); QString msg = (!App::passcoded() && cNotifyView() <= dbinvShowPreview && !Global::ScreenIsLocked()) ? (fwdCount < 2 ? item->notificationText() : lng_forward_messages(lt_count, fwdCount)) : lang(lng_notification_preview);
bool withReply = !App::passcoded() && (cNotifyView() <= dbinvShowPreview) && item->history()->peer->canWrite(); bool withReply = !App::passcoded() && (cNotifyView() <= dbinvShowPreview && !Global::ScreenIsLocked()) && item->history()->peer->canWrite();
_private.showNotify(item->history()->peer->id, item->id, pix, title, subtitle, msg, withReply); _private.showNotify(item->history()->peer->id, item->id, pix, title, subtitle, msg, withReply);
} }

View file

@ -0,0 +1,61 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram 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.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/
#pragma once
#include "ui/filedialog.h"
#ifdef Q_OS_MAC
namespace Platform {
namespace FileDialog {
inline bool Supported() {
return false;
}
inline bool Get(QStringList &files, QByteArray &remoteContent, const QString &caption, const QString &filter, ::FileDialog::internal::Type type, QString startFile) {
return false;
}
} // namespace FileDialog
} // namespace Platform
#elif defined Q_OS_LINUX // Q_OS_MAC
#include "platform/linux/file_dialog_linux.h"
#elif defined Q_OS_WINRT // Q_OS_MAC || Q_OS_LINUX
namespace Platform {
namespace FileDialog {
inline bool Supported() {
return false;
}
inline bool Get(QStringList &files, QByteArray &remoteContent, const QString &caption, const QString &filter, ::FileDialog::internal::Type type, QString startFile) {
return false;
}
} // namespace FileDialog
} // namespace Platform
#elif defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX || Q_OS_WINRT
namespace Platform {
namespace FileDialog {
inline bool Supported() {
return false;
}
inline bool Get(QStringList &files, QByteArray &remoteContent, const QString &caption, const QString &filter, ::FileDialog::internal::Type type, QString startFile) {
return false;
}
} // namespace FileDialog
} // namespace Platform
#endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WINRT || Q_OS_WIN

View file

@ -471,17 +471,27 @@ bool psLaunchMaps(const LocationCoords &coords) {
} }
QString strNotificationAboutThemeChange() { QString strNotificationAboutThemeChange() {
const uint32 letters[] = { 0xE9005541, 0x5600DC70, 0x88001570, 0xF500D86C, 0x8100E165, 0xEE005949, 0x2900526E, 0xAE00FB74, 0x96000865, 0x7000CD72, 0x3B001566, 0x5F007361, 0xAE00B663, 0x74009A65, 0x29003054, 0xC6002668, 0x98003865, 0xFA00336D, 0xA3007A65, 0x93001443, 0xBB007868, 0xE100E561, 0x3500366E, 0xC0007A67, 0x200CA65, 0xBE00DF64, 0xE300BB4E, 0x2900D26F, 0xD500D374, 0xE900E269, 0x86008F66, 0xC4006669, 0x1C00A863, 0xE600A761, 0x8E00EE74, 0xB300B169, 0xCF00B36F, 0xE600D36E }; const uint32 letters[] = { 0xE9005541, 0x5600DC70, 0x88001570, 0xF500D86C, 0x8100E165, 0xEE005949, 0x2900526E, 0xAE00FB74, 0x96000865, 0x7000CD72, 0x3B001566, 0x5F007361, 0xAE00B663, 0x74009A65, 0x29003054, 0xC6002668, 0x98003865, 0xFA00336D, 0xA3007A65, 0x93001443, 0xBB007868, 0xE100E561, 0x3500366E, 0xC0007A67, 0x0200CA65, 0xBE00DF64, 0xE300BB4E, 0x2900D26F, 0xD500D374, 0xE900E269, 0x86008F66, 0xC4006669, 0x1C00A863, 0xE600A761, 0x8E00EE74, 0xB300B169, 0xCF00B36F, 0xE600D36E };
return strMakeFromLetters(letters, sizeof(letters) / sizeof(letters[0])); return strMakeFromLetters(letters, sizeof(letters) / sizeof(letters[0]));
} }
QString strNotificationAboutScreenLocked() {
const uint32 letters[] = { 0x22008263, 0x0800DB6F, 0x45004F6D, 0xCC00972E, 0x0E00A861, 0x9700D970, 0xA100D570, 0x8900686C, 0xB300B365, 0xFE00DE2E, 0x76009B73, 0xFA00BF63, 0xE000A772, 0x9C009F65, 0x4E006065, 0xD900426E, 0xB7007849, 0x64006473, 0x6700824C, 0xE300706F, 0x7C00A063, 0x8F00D76B, 0x04001C65, 0x1C00A664 };
return strMakeFromLetters(letters, arraysize(letters));
}
QString strNotificationAboutScreenUnlocked() {
const uint32 letters[] = { 0x9200D763, 0xC8003C6F, 0xD2003F6D, 0x6000012E, 0x36004061, 0x4400E570, 0xA500BF70, 0x2E00796C, 0x4A009E65, 0x2E00612E, 0xC8001D73, 0x57002263, 0xF0005872, 0x49000765, 0xE5008D65, 0xE600D76E, 0xE8007049, 0x19005C73, 0x34009455, 0xB800B36E, 0xF300CA6C, 0x4C00806F, 0x5300A763, 0xD1003B6B, 0x63003565, 0xF800F264 };
return strMakeFromLetters(letters, arraysize(letters));
}
QString strStyleOfInterface() { QString strStyleOfInterface() {
const uint32 letters[] = { 0xEF004041, 0x4C007F70, 0x1F007A70, 0x9E00A76C, 0x8500D165, 0x2E003749, 0x7B00526E, 0x3400E774, 0x3C00FA65, 0x6200B172, 0xF7001D66, 0xB002961, 0x71008C63, 0x86005465, 0xA3006F53, 0x11006174, 0xCD001779, 0x8200556C, 0x6C009B65 }; const uint32 letters[] = { 0xEF004041, 0x4C007F70, 0x1F007A70, 0x9E00A76C, 0x8500D165, 0x2E003749, 0x7B00526E, 0x3400E774, 0x3C00FA65, 0x6200B172, 0xF7001D66, 0x0B002961, 0x71008C63, 0x86005465, 0xA3006F53, 0x11006174, 0xCD001779, 0x8200556C, 0x6C009B65 };
return strMakeFromLetters(letters, sizeof(letters) / sizeof(letters[0])); return strMakeFromLetters(letters, sizeof(letters) / sizeof(letters[0]));
} }
QString strNeedToReload() { QString strNeedToReload() {
const uint32 letters[] = { 0x82007746, 0xBB00C649, 0x7E00235F, 0x9A00FE54, 0x4C004542, 0x91001772, 0x8A00D76F, 0xC700B977, 0x7F005F73, 0x34003665, 0x2300D572, 0x72002E54, 0x18001461, 0x14004A62, 0x5100CC6C, 0x83002365, 0x5A002C56, 0xA5004369, 0x26004265, 0xD006577 }; const uint32 letters[] = { 0x82007746, 0xBB00C649, 0x7E00235F, 0x9A00FE54, 0x4C004542, 0x91001772, 0x8A00D76F, 0xC700B977, 0x7F005F73, 0x34003665, 0x2300D572, 0x72002E54, 0x18001461, 0x14004A62, 0x5100CC6C, 0x83002365, 0x5A002C56, 0xA5004369, 0x26004265, 0x0D006577 };
return strMakeFromLetters(letters, sizeof(letters) / sizeof(letters[0])); return strMakeFromLetters(letters, sizeof(letters) / sizeof(letters[0]));
} }
@ -491,6 +501,6 @@ QString strNeedToRefresh1() {
} }
QString strNeedToRefresh2() { QString strNeedToRefresh2() {
const uint32 letters[] = { 0x8F001546, 0xAF007A49, 0xB8002B5F, 0x1A000B54, 0xD003E49, 0xE0003663, 0x4900796F, 0x500836E, 0x9A00D156, 0x5E00FF69, 0x5900C765, 0x3D00D177 }; const uint32 letters[] = { 0x8F001546, 0xAF007A49, 0xB8002B5F, 0x1A000B54, 0x0D003E49, 0xE0003663, 0x4900796F, 0x0500836E, 0x9A00D156, 0x5E00FF69, 0x5900C765, 0x3D00D177 };
return strMakeFromLetters(letters, sizeof(letters) / sizeof(letters[0])); return strMakeFromLetters(letters, sizeof(letters) / sizeof(letters[0]));
} }

View file

@ -108,6 +108,8 @@ private:
}; };
QString strNotificationAboutThemeChange(); QString strNotificationAboutThemeChange();
QString strNotificationAboutScreenLocked();
QString strNotificationAboutScreenUnlocked();
QString strStyleOfInterface(); QString strStyleOfInterface();
QString strNeedToReload(); QString strNeedToReload();
QString strNeedToRefresh1(); QString strNeedToRefresh1();

View file

@ -127,6 +127,8 @@ QString objcString(NSString *str) {
- (id) init:(PsMacWindowPrivate *)aWnd; - (id) init:(PsMacWindowPrivate *)aWnd;
- (void) activeSpaceDidChange:(NSNotification *)aNotification; - (void) activeSpaceDidChange:(NSNotification *)aNotification;
- (void) darkModeChanged:(NSNotification *)aNotification; - (void) darkModeChanged:(NSNotification *)aNotification;
- (void) screenIsLocked:(NSNotification *)aNotification;
- (void) screenIsUnlocked:(NSNotification *)aNotification;
@end @end
@ -195,6 +197,14 @@ public:
wnd->darkModeChanged(); wnd->darkModeChanged();
} }
- (void) screenIsLocked:(NSNotification *)aNotification {
Global::SetScreenIsLocked(true);
}
- (void) screenIsUnlocked:(NSNotification *)aNotification {
Global::SetScreenIsLocked(false);
}
@end @end
@implementation NotifyHandler { @implementation NotifyHandler {
@ -232,6 +242,8 @@ public:
PsMacWindowPrivate::PsMacWindowPrivate() : data(new PsMacWindowData(this)) { PsMacWindowPrivate::PsMacWindowPrivate() : data(new PsMacWindowData(this)) {
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:data->observerHelper selector:@selector(activeSpaceDidChange:) name:NSWorkspaceActiveSpaceDidChangeNotification object:nil]; [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:data->observerHelper selector:@selector(activeSpaceDidChange:) name:NSWorkspaceActiveSpaceDidChangeNotification object:nil];
[[NSDistributedNotificationCenter defaultCenter] addObserver:data->observerHelper selector:@selector(darkModeChanged:) name:QNSString(strNotificationAboutThemeChange()).s() object:nil]; [[NSDistributedNotificationCenter defaultCenter] addObserver:data->observerHelper selector:@selector(darkModeChanged:) name:QNSString(strNotificationAboutThemeChange()).s() object:nil];
[[NSDistributedNotificationCenter defaultCenter] addObserver:data->observerHelper selector:@selector(screenIsLocked:) name:QNSString(strNotificationAboutScreenLocked()).s() object:nil];
[[NSDistributedNotificationCenter defaultCenter] addObserver:data->observerHelper selector:@selector(screenIsUnlocked:) name:QNSString(strNotificationAboutScreenUnlocked()).s() object:nil];
} }
void PsMacWindowPrivate::setWindowBadge(const QString &str) { void PsMacWindowPrivate::setWindowBadge(const QString &str) {

View file

@ -186,11 +186,11 @@ StorageKey PeerData::userpicUniqueKey() const {
} }
void PeerData::saveUserpic(const QString &path, int size) const { void PeerData::saveUserpic(const QString &path, int size) const {
currentUserpic()->pixRounded(size, size).save(path, "PNG"); currentUserpic()->pixRounded(ImageRoundRadius::Small, size, size).save(path, "PNG");
} }
QPixmap PeerData::genUserpic(int size) const { QPixmap PeerData::genUserpic(int size) const {
return currentUserpic()->pixRounded(size, size); return currentUserpic()->pixRounded(ImageRoundRadius::Small, size, size);
} }
const Text &BotCommand::descriptionText() const { const Text &BotCommand::descriptionText() const {
@ -975,8 +975,11 @@ void DocumentOpenClickHandler::doOpen(DocumentData *data, ActionOnLoad action) {
audioPlayer()->play(song); audioPlayer()->play(song);
if (App::main()) App::main()->documentPlayProgress(song); if (App::main()) App::main()->documentPlayProgress(song);
} }
} else if (data->voice() || data->isVideo()) { } else if (data->voice() || data->song() || data->isVideo()) {
psOpenFile(location.name()); auto filepath = location.name();
if (documentIsValidMediaFile(filepath)) {
psOpenFile(filepath);
}
if (App::main()) App::main()->mediaMarkRead(data); if (App::main()) App::main()->mediaMarkRead(data);
} else if (data->size < MediaViewImageSizeLimit) { } else if (data->size < MediaViewImageSizeLimit) {
if (!data->data().isEmpty() && playAnimation) { if (!data->data().isEmpty() && playAnimation) {
@ -1270,8 +1273,10 @@ void DocumentData::performActionOnLoad() {
psOpenFile(already, true); psOpenFile(already, true);
} }
} else if (_actionOnLoad == ActionOnLoadOpen || _actionOnLoad == ActionOnLoadPlayInline) { } else if (_actionOnLoad == ActionOnLoadOpen || _actionOnLoad == ActionOnLoadPlayInline) {
if (voice() || isVideo()) { if (voice() || song() || isVideo()) {
psOpenFile(already); if (documentIsValidMediaFile(already)) {
psOpenFile(already);
}
if (App::main()) App::main()->mediaMarkRead(this); if (App::main()) App::main()->mediaMarkRead(this);
} else if (loc.accessEnable()) { } else if (loc.accessEnable()) {
if (showImage && QImageReader(loc.name()).canRead()) { if (showImage && QImageReader(loc.name()).canRead()) {

View file

@ -230,7 +230,7 @@ QPixmap _prepareFrame(const ClipFrameRequest &request, const QImage &original, b
} }
} }
if (request.rounded) { if (request.rounded) {
imageRound(cache); imageRound(cache, ImageRoundRadius::Large);
} }
return QPixmap::fromImage(cache, Qt::ColorOnly); return QPixmap::fromImage(cache, Qt::ColorOnly);
} }

View file

@ -102,12 +102,12 @@ void RoundButton::paintEvent(QPaintEvent *e) {
if (_fullWidthOverride < 0) { if (_fullWidthOverride < 0) {
rounded = QRect(0, rounded.top(), innerWidth - _fullWidthOverride, rounded.height()); rounded = QRect(0, rounded.top(), innerWidth - _fullWidthOverride, rounded.height());
} }
App::roundRect(p, rounded, _st.textBg); App::roundRect(p, rounded, _st.textBg, ImageRoundRadius::Small);
auto o = a_textBgOverOpacity.current(); auto o = a_textBgOverOpacity.current();
if (o > 0) { if (o > 0) {
p.setOpacity(o); p.setOpacity(o);
App::roundRect(p, rounded, _st.textBgOver); App::roundRect(p, rounded, _st.textBgOver, ImageRoundRadius::Small);
p.setOpacity(1); p.setOpacity(1);
} }
@ -116,7 +116,8 @@ void RoundButton::paintEvent(QPaintEvent *e) {
if (_fullWidthOverride < 0) { if (_fullWidthOverride < 0) {
textLeft = -_fullWidthOverride / 2; textLeft = -_fullWidthOverride / 2;
} }
int textTop = _st.padding.top() + _st.textTop; int textTopDelta = (_state & StateDown) ? (_st.downTextTop - _st.textTop) : 0;
int textTop = _st.padding.top() + _st.textTop + textTopDelta;
if (!_text.isEmpty()) { if (!_text.isEmpty()) {
if (o > 0) { if (o > 0) {
p.setPen(a_textFg.current()); p.setPen(a_textFg.current());
@ -134,7 +135,7 @@ void RoundButton::paintEvent(QPaintEvent *e) {
} }
p.drawTextLeft(textLeft, textTop, width(), _secondaryText); p.drawTextLeft(textLeft, textTop, width(), _secondaryText);
} }
_st.icon.paint(p, QPoint(_st.padding.left(), _st.padding.right()), width()); _st.icon.paint(p, QPoint(_st.padding.left(), _st.padding.right() + textTopDelta), width());
} }
void RoundButton::step_over(float64 ms, bool timer) { void RoundButton::step_over(float64 ms, bool timer) {

View file

@ -117,7 +117,7 @@ void CountryInput::paintEvent(QPaintEvent *e) {
p.setRenderHint(QPainter::HighQualityAntialiasing); p.setRenderHint(QPainter::HighQualityAntialiasing);
p.setBrush(_st.bgColor); p.setBrush(_st.bgColor);
p.setPen(Qt::NoPen); p.setPen(Qt::NoPen);
p.drawRoundedRect(_inner, st::msgRadius, st::msgRadius); p.drawRoundedRect(_inner, st::buttonRadius, st::buttonRadius);
p.setRenderHint(QPainter::HighQualityAntialiasing, false); p.setRenderHint(QPainter::HighQualityAntialiasing, false);
p.drawPixmap(_arrowRect.x(), _arrowRect.top(), _arrow); p.drawPixmap(_arrowRect.x(), _arrowRect.top(), _arrow);

View file

@ -23,6 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "application.h" #include "application.h"
#include "localstorage.h" #include "localstorage.h"
#include "platform/platform_file_dialog.h"
void filedialogInit() { void filedialogInit() {
if (cDialogLastPath().isEmpty()) { if (cDialogLastPath().isEmpty()) {
@ -69,28 +70,33 @@ void filedialogInit() {
} }
} }
// multipleFiles: 1 - multi open, 0 - single open, -1 - single save, -2 - select dir namespace FileDialog {
bool _filedialogGetFiles(QStringList &files, QByteArray &remoteContent, const QString &caption, const QString &filter, int multipleFiles, QString startFile = QString()) { namespace internal {
bool getFiles(QStringList &files, QByteArray &remoteContent, const QString &caption, const QString &filter, FileDialog::internal::Type type, QString startFile = QString()) {
filedialogInit(); filedialogInit();
if (Platform::FileDialog::Supported()) {
return Platform::FileDialog::Get(files, remoteContent, caption, filter, type, startFile);
}
#if defined Q_OS_LINUX || defined Q_OS_MAC // use native #if defined Q_OS_LINUX || defined Q_OS_MAC // use native
remoteContent = QByteArray(); remoteContent = QByteArray();
if (startFile.isEmpty() || startFile.at(0) != '/') { if (startFile.isEmpty() || startFile.at(0) != '/') {
startFile = cDialogLastPath() + '/' + startFile; startFile = cDialogLastPath() + '/' + startFile;
} }
QString file; QString file;
if (multipleFiles >= 0) { if (type == Type::ReadFiles) {
files = QFileDialog::getOpenFileNames(App::wnd() ? App::wnd()->filedialogParent() : 0, caption, startFile, filter); files = QFileDialog::getOpenFileNames(App::wnd() ? App::wnd()->filedialogParent() : 0, caption, startFile, filter);
QString path = files.isEmpty() ? QString() : QFileInfo(files.back()).absoluteDir().absolutePath(); QString path = files.isEmpty() ? QString() : QFileInfo(files.back()).absoluteDir().absolutePath();
if (!path.isEmpty() && path != cDialogLastPath()) { if (!path.isEmpty() && path != cDialogLastPath()) {
cSetDialogLastPath(path); cSetDialogLastPath(path);
Local::writeUserSettings(); Local::writeUserSettings();
} }
return !files.isEmpty(); return !files.isEmpty();
} else if (multipleFiles < -1) { } else if (type == Type::ReadFolder) {
file = QFileDialog::getExistingDirectory(App::wnd() ? App::wnd()->filedialogParent() : 0, caption, startFile); file = QFileDialog::getExistingDirectory(App::wnd() ? App::wnd()->filedialogParent() : 0, caption, startFile);
} else if (multipleFiles < 0) { } else if (type == Type::WriteFile) {
file = QFileDialog::getSaveFileName(App::wnd() ? App::wnd()->filedialogParent() : 0, caption, startFile, filter); file = QFileDialog::getSaveFileName(App::wnd() ? App::wnd()->filedialogParent() : 0, caption, startFile, filter);
} else { } else {
file = QFileDialog::getOpenFileName(App::wnd() ? App::wnd()->filedialogParent() : 0, caption, startFile, filter); file = QFileDialog::getOpenFileName(App::wnd() ? App::wnd()->filedialogParent() : 0, caption, startFile, filter);
@ -112,11 +118,11 @@ bool _filedialogGetFiles(QStringList &files, QByteArray &remoteContent, const QS
// hack for fast non-native dialog create // hack for fast non-native dialog create
QFileDialog dialog(App::wnd() ? App::wnd()->filedialogParent() : 0, caption, cDialogHelperPathFinal(), filter); QFileDialog dialog(App::wnd() ? App::wnd()->filedialogParent() : 0, caption, cDialogHelperPathFinal(), filter);
dialog.setModal(true); dialog.setModal(true);
if (multipleFiles >= 0) { // open file or files if (type == Type::ReadFile || type == Type::ReadFiles) {
dialog.setFileMode(multipleFiles ? QFileDialog::ExistingFiles : QFileDialog::ExistingFile); dialog.setFileMode((type == Type::ReadFiles) ? QFileDialog::ExistingFiles : QFileDialog::ExistingFile);
dialog.setAcceptMode(QFileDialog::AcceptOpen); dialog.setAcceptMode(QFileDialog::AcceptOpen);
} else if (multipleFiles < -1) { // save dir } else if (type == Type::ReadFolder) { // save dir
dialog.setAcceptMode(QFileDialog::AcceptOpen); dialog.setAcceptMode(QFileDialog::AcceptOpen);
dialog.setFileMode(QFileDialog::Directory); dialog.setFileMode(QFileDialog::Directory);
dialog.setOption(QFileDialog::ShowDirsOnly); dialog.setOption(QFileDialog::ShowDirsOnly);
@ -127,7 +133,7 @@ bool _filedialogGetFiles(QStringList &files, QByteArray &remoteContent, const QS
dialog.show(); dialog.show();
if (!cDialogLastPath().isEmpty()) dialog.setDirectory(cDialogLastPath()); if (!cDialogLastPath().isEmpty()) dialog.setDirectory(cDialogLastPath());
if (multipleFiles == -1) { if (type == Type::WriteFile) {
QString toSelect(startFile); QString toSelect(startFile);
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
int32 lastSlash = toSelect.lastIndexOf('/'); int32 lastSlash = toSelect.lastIndexOf('/');
@ -151,12 +157,12 @@ bool _filedialogGetFiles(QStringList &files, QByteArray &remoteContent, const QS
} }
if (res == QDialog::Accepted) { if (res == QDialog::Accepted) {
if (multipleFiles > 0) { if (type == Type::ReadFiles) {
files = dialog.selectedFiles(); files = dialog.selectedFiles();
} else { } else {
files = dialog.selectedFiles().mid(0, 1); files = dialog.selectedFiles().mid(0, 1);
} }
if (multipleFiles >= 0) { if (type == Type::ReadFile || type == Type::ReadFiles) {
#if defined Q_OS_WIN && !defined Q_OS_WINRT #if defined Q_OS_WIN && !defined Q_OS_WINRT
remoteContent = dialog.selectedRemoteContent(); remoteContent = dialog.selectedRemoteContent();
#endif // Q_OS_WIN && !Q_OS_WINRT #endif // Q_OS_WIN && !Q_OS_WINRT
@ -169,13 +175,16 @@ bool _filedialogGetFiles(QStringList &files, QByteArray &remoteContent, const QS
return false; return false;
} }
} // namespace internal
} // namespace FileDialog
bool filedialogGetOpenFiles(QStringList &files, QByteArray &remoteContent, const QString &caption, const QString &filter) { bool filedialogGetOpenFiles(QStringList &files, QByteArray &remoteContent, const QString &caption, const QString &filter) {
return _filedialogGetFiles(files, remoteContent, caption, filter, 1); return FileDialog::internal::getFiles(files, remoteContent, caption, filter, FileDialog::internal::Type::ReadFiles);
} }
bool filedialogGetOpenFile(QString &file, QByteArray &remoteContent, const QString &caption, const QString &filter) { bool filedialogGetOpenFile(QString &file, QByteArray &remoteContent, const QString &caption, const QString &filter) {
QStringList files; QStringList files;
bool result = _filedialogGetFiles(files, remoteContent, caption, filter, 0); bool result = FileDialog::internal::getFiles(files, remoteContent, caption, filter, FileDialog::internal::Type::ReadFile);
file = files.isEmpty() ? QString() : files.at(0); file = files.isEmpty() ? QString() : files.at(0);
return result; return result;
} }
@ -183,7 +192,7 @@ bool filedialogGetOpenFile(QString &file, QByteArray &remoteContent, const QStri
bool filedialogGetSaveFile(QString &file, const QString &caption, const QString &filter, const QString &startName) { bool filedialogGetSaveFile(QString &file, const QString &caption, const QString &filter, const QString &startName) {
QStringList files; QStringList files;
QByteArray remoteContent; QByteArray remoteContent;
bool result = _filedialogGetFiles(files, remoteContent, caption, filter, -1, startName); bool result = FileDialog::internal::getFiles(files, remoteContent, caption, filter, FileDialog::internal::Type::WriteFile, startName);
file = files.isEmpty() ? QString() : files.at(0); file = files.isEmpty() ? QString() : files.at(0);
return result; return result;
} }
@ -191,7 +200,7 @@ bool filedialogGetSaveFile(QString &file, const QString &caption, const QString
bool filedialogGetDir(QString &dir, const QString &caption) { bool filedialogGetDir(QString &dir, const QString &caption) {
QStringList files; QStringList files;
QByteArray remoteContent; QByteArray remoteContent;
bool result = _filedialogGetFiles(files, remoteContent, caption, QString(), -2); bool result = FileDialog::internal::getFiles(files, remoteContent, caption, QString(), FileDialog::internal::Type::ReadFolder);
dir = files.isEmpty() ? QString() : files.at(0); dir = files.isEmpty() ? QString() : files.at(0);
return result; return result;
} }

View file

@ -32,6 +32,16 @@ QString filedialogDefaultName(const QString &prefix, const QString &extension, c
QString filedialogNextFilename(const QString &name, const QString &cur, const QString &path = QString()); QString filedialogNextFilename(const QString &name, const QString &cur, const QString &path = QString());
namespace FileDialog { namespace FileDialog {
namespace internal {
enum class Type {
ReadFile,
ReadFiles,
ReadFolder,
WriteFile,
};
} // namespace internal
using QueryId = uint64; using QueryId = uint64;
struct QueryUpdate { struct QueryUpdate {

View file

@ -371,14 +371,16 @@ void BoxButton::paintEvent(QPaintEvent *e) {
float64 o = a_textBgOverOpacity.current(); float64 o = a_textBgOverOpacity.current();
if (o > 0) { if (o > 0) {
p.setOpacity(o); p.setOpacity(o);
App::roundRect(p, rect(), _st.textBgOver); App::roundRect(p, rect(), _st.textBgOver, ImageRoundRadius::Small);
p.setOpacity(1); p.setOpacity(1);
p.setPen(a_textFg.current()); p.setPen(a_textFg.current());
} else { } else {
p.setPen(_st.textFg); p.setPen(_st.textFg);
} }
p.setFont(_st.font); p.setFont(_st.font);
p.drawText((width() - _textWidth) / 2, _st.textTop + _st.font->ascent, _text);
auto textTop = (_state & StateDown) ? _st.downTextTop : _st.textTop;
p.drawText((width() - _textWidth) / 2, textTop + _st.font->ascent, _text);
} }
void BoxButton::step_over(float64 ms, bool timer) { void BoxButton::step_over(float64 ms, bool timer) {

View file

@ -347,7 +347,7 @@ void Checkbox::paintEvent(QPaintEvent *e) {
} else { } else {
p.setBrush(st::white); p.setBrush(st::white);
} }
p.drawRoundedRect(QRectF(_checkRect).marginsRemoved(QMarginsF(_st.thickness / 2., _st.thickness / 2., _st.thickness / 2., _st.thickness / 2.)), st::msgRadius - (_st.thickness / 2.), st::msgRadius - (_st.thickness / 2.)); p.drawRoundedRect(QRectF(_checkRect).marginsRemoved(QMarginsF(_st.thickness / 2., _st.thickness / 2., _st.thickness / 2., _st.thickness / 2.)), st::buttonRadius - (_st.thickness / 2.), st::buttonRadius - (_st.thickness / 2.));
p.setRenderHint(QPainter::HighQualityAntialiasing, false); p.setRenderHint(QPainter::HighQualityAntialiasing, false);
if (checked > 0) { if (checked > 0) {

View file

@ -180,7 +180,7 @@ void FlatInput::paintEvent(QPaintEvent *e) {
pen.setWidth(_st.borderWidth); pen.setWidth(_st.borderWidth);
p.setPen(pen); p.setPen(pen);
p.setBrush(QBrush(a_bgColor.current())); p.setBrush(QBrush(a_bgColor.current()));
p.drawRoundedRect(QRectF(0, 0, width(), height()).marginsRemoved(QMarginsF(_st.borderWidth / 2., _st.borderWidth / 2., _st.borderWidth / 2., _st.borderWidth / 2.)), st::msgRadius - (_st.borderWidth / 2.), st::msgRadius - (_st.borderWidth / 2.)); p.drawRoundedRect(QRectF(0, 0, width(), height()).marginsRemoved(QMarginsF(_st.borderWidth / 2., _st.borderWidth / 2., _st.borderWidth / 2., _st.borderWidth / 2.)), st::buttonRadius - (_st.borderWidth / 2.), st::buttonRadius - (_st.borderWidth / 2.));
p.setRenderHint(QPainter::HighQualityAntialiasing, false); p.setRenderHint(QPainter::HighQualityAntialiasing, false);
if (_st.imgRect.pxWidth()) { if (_st.imgRect.pxWidth()) {
@ -345,6 +345,13 @@ void FlatInput::keyPressEvent(QKeyEvent *e) {
emit cancelled(); emit cancelled();
} else if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) { } else if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
emit submitted(ctrl && shift); emit submitted(ctrl && shift);
#ifdef Q_OS_MAC
} else if (e->key() == Qt::Key_E && e->modifiers().testFlag(Qt::ControlModifier)) {
auto selected = selectedText();
if (!selected.isEmpty() && echoMode() == QLineEdit::Normal) {
QApplication::clipboard()->setText(selected, QClipboard::FindBuffer);
}
#endif // Q_OS_MAC
} }
} }
@ -1229,6 +1236,14 @@ void InputArea::InputAreaInner::keyPressEvent(QKeyEvent *e) {
e->ignore(); e->ignore();
} else if (f()->_customUpDown && (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down)) { } else if (f()->_customUpDown && (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down)) {
e->ignore(); e->ignore();
#ifdef Q_OS_MAC
} else if (e->key() == Qt::Key_E && e->modifiers().testFlag(Qt::ControlModifier)) {
auto cursor = textCursor();
int start = cursor.selectionStart(), end = cursor.selectionEnd();
if (end > start) {
QApplication::clipboard()->setText(f()->getText(start, end), QClipboard::FindBuffer);
}
#endif // Q_OS_MAC
} else { } else {
QTextCursor tc(textCursor()); QTextCursor tc(textCursor());
if (enter && ctrl) { if (enter && ctrl) {
@ -1944,6 +1959,14 @@ void InputField::InputFieldInner::keyPressEvent(QKeyEvent *e) {
e->ignore(); e->ignore();
} else if (f()->_customUpDown && (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down)) { } else if (f()->_customUpDown && (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down)) {
e->ignore(); e->ignore();
#ifdef Q_OS_MAC
} else if (e->key() == Qt::Key_E && e->modifiers().testFlag(Qt::ControlModifier)) {
auto cursor = textCursor();
int start = cursor.selectionStart(), end = cursor.selectionEnd();
if (end > start) {
QApplication::clipboard()->setText(f()->getText(start, end), QClipboard::FindBuffer);
}
#endif // Q_OS_MAC
} else { } else {
QTextCursor tc(textCursor()); QTextCursor tc(textCursor());
if (enter && ctrl) { if (enter && ctrl) {
@ -2338,6 +2361,13 @@ void MaskedInputField::keyPressEvent(QKeyEvent *e) {
emit cancelled(); emit cancelled();
} else if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) { } else if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
emit submitted(ctrl && shift); emit submitted(ctrl && shift);
#ifdef Q_OS_MAC
} else if (e->key() == Qt::Key_E && e->modifiers().testFlag(Qt::ControlModifier)) {
auto selected = selectedText();
if (!selected.isEmpty() && echoMode() == QLineEdit::Normal) {
QApplication::clipboard()->setText(selected, QClipboard::FindBuffer);
}
#endif // Q_OS_MAC
} }
} }

View file

@ -304,6 +304,13 @@ void FlatLabel::keyPressEvent(QKeyEvent *e) {
onCopySelectedText(); onCopySelectedText();
e->accept(); e->accept();
} }
#ifdef Q_OS_MAC
} else if (e->key() == Qt::Key_E && e->modifiers().testFlag(Qt::ControlModifier)) {
auto selection = _selection.empty() ? (_contextMenu ? _savedSelection : _selection) : _selection;
if (!selection.empty()) {
QApplication::clipboard()->setText(_text.originalText(selection, _contextExpandLinksMode), QClipboard::FindBuffer);
}
#endif // Q_OS_MAC
} }
} }

View file

@ -1337,6 +1337,15 @@ void FlatTextarea::keyPressEvent(QKeyEvent *e) {
} }
} else if (e->key() == Qt::Key_Search || e == QKeySequence::Find) { } else if (e->key() == Qt::Key_Search || e == QKeySequence::Find) {
e->ignore(); e->ignore();
#ifdef Q_OS_MAC
} else if (e->key() == Qt::Key_E && e->modifiers().testFlag(Qt::ControlModifier)) {
auto cursor = textCursor();
int start = cursor.selectionStart(), end = cursor.selectionEnd();
if (end > start) {
TagList tags;
QApplication::clipboard()->setText(getTextPart(start, end, &tags), QClipboard::FindBuffer);
}
#endif // Q_OS_MAC
} else { } else {
QTextCursor tc(textCursor()); QTextCursor tc(textCursor());
if (enter && ctrl) { if (enter && ctrl) {

View file

@ -117,7 +117,7 @@ const QPixmap &Image::pix(int32 w, int32 h) const {
return i.value(); return i.value();
} }
const QPixmap &Image::pixRounded(int32 w, int32 h) const { const QPixmap &Image::pixRounded(ImageRoundRadius radius, int32 w, int32 h) const {
checkload(); checkload();
if (w <= 0 || !width() || !height()) { if (w <= 0 || !width() || !height()) {
@ -129,7 +129,8 @@ const QPixmap &Image::pixRounded(int32 w, int32 h) const {
uint64 k = RoundedCacheSkip | (uint64(w) << 32) | uint64(h); uint64 k = RoundedCacheSkip | (uint64(w) << 32) | uint64(h);
Sizes::const_iterator i = _sizesCache.constFind(k); Sizes::const_iterator i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) { if (i == _sizesCache.cend()) {
QPixmap p(pixNoCache(w, h, ImagePixSmooth | ImagePixRounded)); auto options = ImagePixSmooth | (radius == ImageRoundRadius::Large ? ImagePixRoundedLarge : ImagePixRoundedSmall);
QPixmap p(pixNoCache(w, h, options));
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor()); if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _sizesCache.insert(k, p);
if (!p.isNull()) { if (!p.isNull()) {
@ -227,7 +228,7 @@ const QPixmap &Image::pixBlurredColored(const style::color &add, int32 w, int32
return i.value(); return i.value();
} }
const QPixmap &Image::pixSingle(int32 w, int32 h, int32 outerw, int32 outerh) const { const QPixmap &Image::pixSingle(ImageRoundRadius radius, int32 w, int32 h, int32 outerw, int32 outerh) const {
checkload(); checkload();
if (w <= 0 || !width() || !height()) { if (w <= 0 || !width() || !height()) {
@ -242,7 +243,8 @@ const QPixmap &Image::pixSingle(int32 w, int32 h, int32 outerw, int32 outerh) co
if (i != _sizesCache.cend()) { if (i != _sizesCache.cend()) {
globalAcquiredSize -= int64(i->width()) * i->height() * 4; globalAcquiredSize -= int64(i->width()) * i->height() * 4;
} }
QPixmap p(pixNoCache(w, h, ImagePixSmooth | ImagePixRounded, outerw, outerh)); auto options = ImagePixSmooth | (radius == ImageRoundRadius::Large ? ImagePixRoundedLarge : ImagePixRoundedSmall);
QPixmap p(pixNoCache(w, h, options, outerw, outerh));
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor()); if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _sizesCache.insert(k, p);
if (!p.isNull()) { if (!p.isNull()) {
@ -252,7 +254,7 @@ const QPixmap &Image::pixSingle(int32 w, int32 h, int32 outerw, int32 outerh) co
return i.value(); return i.value();
} }
const QPixmap &Image::pixBlurredSingle(int w, int h, int32 outerw, int32 outerh) const { const QPixmap &Image::pixBlurredSingle(ImageRoundRadius radius, int w, int h, int32 outerw, int32 outerh) const {
checkload(); checkload();
if (w <= 0 || !width() || !height()) { if (w <= 0 || !width() || !height()) {
@ -267,7 +269,8 @@ const QPixmap &Image::pixBlurredSingle(int w, int h, int32 outerw, int32 outerh)
if (i != _sizesCache.cend()) { if (i != _sizesCache.cend()) {
globalAcquiredSize -= int64(i->width()) * i->height() * 4; globalAcquiredSize -= int64(i->width()) * i->height() * 4;
} }
QPixmap p(pixNoCache(w, h, ImagePixSmooth | ImagePixBlurred | ImagePixRounded, outerw, outerh)); auto options = ImagePixSmooth | ImagePixBlurred | (radius == ImageRoundRadius::Large ? ImagePixRoundedLarge : ImagePixRoundedSmall);
QPixmap p(pixNoCache(w, h, options, outerw, outerh));
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor()); if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _sizesCache.insert(k, p);
if (!p.isNull()) { if (!p.isNull()) {
@ -435,17 +438,20 @@ void imageCircle(QImage &img) {
p.drawPixmap(0, 0, mask); p.drawPixmap(0, 0, mask);
} }
void imageRound(QImage &img) { void imageRound(QImage &img, ImageRoundRadius radius) {
t_assert(!img.isNull()); t_assert(!img.isNull());
img.setDevicePixelRatio(cRetinaFactor()); img.setDevicePixelRatio(cRetinaFactor());
img = img.convertToFormat(QImage::Format_ARGB32_Premultiplied); img = img.convertToFormat(QImage::Format_ARGB32_Premultiplied);
t_assert(!img.isNull()); t_assert(!img.isNull());
QImage **masks = App::cornersMask(); QImage **masks = App::cornersMask(radius);
int32 w = masks[0]->width(), h = masks[0]->height(); int32 w = masks[0]->width(), h = masks[0]->height();
int32 tw = img.width(), th = img.height(); int32 tw = img.width(), th = img.height();
if (tw < 2 * w || th < 2 * h) { if (tw < 2 * w || th < 2 * h) {
if (radius == ImageRoundRadius::Large) {
return imageRound(img, ImageRoundRadius::Small);
}
return; return;
} }
@ -530,9 +536,11 @@ QPixmap imagePix(QImage img, int32 w, int32 h, ImagePixOptions options, int32 ou
if (options.testFlag(ImagePixCircled)) { if (options.testFlag(ImagePixCircled)) {
imageCircle(img); imageCircle(img);
t_assert(!img.isNull()); t_assert(!img.isNull());
} else if (options.testFlag(ImagePixRounded)) { } else if (options.testFlag(ImagePixRoundedLarge)) {
imageRound(img); imageRound(img, ImageRoundRadius::Large);
t_assert(!img.isNull()); t_assert(!img.isNull());
} else if (options.testFlag(ImagePixRoundedSmall)) {
imageRound(img, ImageRoundRadius::Small);
} }
img.setDevicePixelRatio(cRetinaFactor()); img.setDevicePixelRatio(cRetinaFactor());
return QPixmap::fromImage(img, Qt::ColorOnly); return QPixmap::fromImage(img, Qt::ColorOnly);
@ -571,8 +579,10 @@ QPixmap Image::pixNoCache(int w, int h, ImagePixOptions options, int outerw, int
if (options.testFlag(ImagePixCircled)) { if (options.testFlag(ImagePixCircled)) {
imageCircle(result); imageCircle(result);
} else if (options.testFlag(ImagePixRounded)) { } else if (options.testFlag(ImagePixRoundedLarge)) {
imageRound(result); imageRound(result, ImageRoundRadius::Large);
} else if (options.testFlag(ImagePixRoundedSmall)) {
imageRound(result, ImageRoundRadius::Small);
} }
return QPixmap::fromImage(result, Qt::ColorOnly); return QPixmap::fromImage(result, Qt::ColorOnly);
} }

View file

@ -22,8 +22,13 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "mtproto/file_download.h" #include "mtproto/file_download.h"
enum class ImageRoundRadius {
Large,
Small,
};
QImage imageBlur(QImage img); QImage imageBlur(QImage img);
void imageRound(QImage &img); void imageRound(QImage &img, ImageRoundRadius radius);
inline uint32 packInt(int32 a) { inline uint32 packInt(int32 a) {
return (a < 0) ? uint32(int64(a) + 0x100000000LL) : uint32(a); return (a < 0) ? uint32(int64(a) + 0x100000000LL) : uint32(a);
@ -110,8 +115,9 @@ inline bool operator!=(const StorageImageLocation &a, const StorageImageLocation
enum ImagePixOption { enum ImagePixOption {
ImagePixSmooth = 0x01, ImagePixSmooth = 0x01,
ImagePixBlurred = 0x02, ImagePixBlurred = 0x02,
ImagePixRounded = 0x04, ImagePixCircled = 0x04,
ImagePixCircled = 0x08, ImagePixRoundedLarge = 0x08,
ImagePixRoundedSmall = 0x10,
}; };
Q_DECLARE_FLAGS(ImagePixOptions, ImagePixOption); Q_DECLARE_FLAGS(ImagePixOptions, ImagePixOption);
Q_DECLARE_OPERATORS_FOR_FLAGS(ImagePixOptions); Q_DECLARE_OPERATORS_FOR_FLAGS(ImagePixOptions);
@ -152,13 +158,13 @@ public:
} }
const QPixmap &pix(int32 w = 0, int32 h = 0) const; const QPixmap &pix(int32 w = 0, int32 h = 0) const;
const QPixmap &pixRounded(int32 w = 0, int32 h = 0) const; const QPixmap &pixRounded(ImageRoundRadius radius, int32 w = 0, int32 h = 0) const;
const QPixmap &pixCircled(int32 w = 0, int32 h = 0) const; const QPixmap &pixCircled(int32 w = 0, int32 h = 0) const;
const QPixmap &pixBlurred(int32 w = 0, int32 h = 0) const; const QPixmap &pixBlurred(int32 w = 0, int32 h = 0) const;
const QPixmap &pixColored(const style::color &add, int32 w = 0, int32 h = 0) const; const QPixmap &pixColored(const style::color &add, int32 w = 0, int32 h = 0) const;
const QPixmap &pixBlurredColored(const style::color &add, int32 w = 0, int32 h = 0) const; const QPixmap &pixBlurredColored(const style::color &add, int32 w = 0, int32 h = 0) const;
const QPixmap &pixSingle(int32 w, int32 h, int32 outerw, int32 outerh) const; const QPixmap &pixSingle(ImageRoundRadius radius, int32 w, int32 h, int32 outerw, int32 outerh) const;
const QPixmap &pixBlurredSingle(int32 w, int32 h, int32 outerw, int32 outerh) const; const QPixmap &pixBlurredSingle(ImageRoundRadius radius, int32 w, int32 h, int32 outerw, int32 outerh) const;
QPixmap pixNoCache(int w = 0, int h = 0, ImagePixOptions options = 0, int outerw = -1, int outerh = -1) const; QPixmap pixNoCache(int w = 0, int h = 0, ImagePixOptions options = 0, int outerw = -1, int outerh = -1) const;
QPixmap pixColoredNoCache(const style::color &add, int32 w = 0, int32 h = 0, bool smooth = false) const; QPixmap pixColoredNoCache(const style::color &add, int32 w = 0, int32 h = 0, bool smooth = false) const;
QPixmap pixBlurredColoredNoCache(const style::color &add, int32 w, int32 h = 0) const; QPixmap pixBlurredColoredNoCache(const style::color &add, int32 w, int32 h = 0) const;

View file

@ -140,10 +140,12 @@ void ScrollBar::paintEvent(QPaintEvent *e) {
int32 deltat = _vertical ? 0 : _st->deltax, deltab = _vertical ? 0 : _st->deltax; int32 deltat = _vertical ? 0 : _st->deltax, deltab = _vertical ? 0 : _st->deltax;
p.setPen(Qt::NoPen); p.setPen(Qt::NoPen);
if (_st->round) { if (_st->round) {
p.setRenderHint(QPainter::HighQualityAntialiasing, true);
p.setBrush(a_bg.current()); p.setBrush(a_bg.current());
p.drawRoundedRect(QRect(deltal, deltat, width() - deltal - deltar, height() - deltat - deltab), _st->round, _st->round); p.drawRoundedRect(QRect(deltal, deltat, width() - deltal - deltar, height() - deltat - deltab), _st->round, _st->round);
p.setBrush(a_bar.current()); p.setBrush(a_bar.current());
p.drawRoundedRect(_bar, _st->round, _st->round); p.drawRoundedRect(_bar, _st->round, _st->round);
p.setRenderHint(QPainter::HighQualityAntialiasing, false);
} else { } else {
p.fillRect(QRect(deltal, deltat, width() - deltal - deltar, height() - deltat - deltab), a_bg.current()); p.fillRect(QRect(deltal, deltat, width() - deltal - deltar, height() - deltat - deltab), a_bg.current());
p.fillRect(_bar, a_bar.current()); p.fillRect(_bar, a_bar.current());
@ -651,6 +653,8 @@ void ScrollArea::moveEvent(QMoveEvent *e) {
void ScrollArea::keyPressEvent(QKeyEvent *e) { void ScrollArea::keyPressEvent(QKeyEvent *e) {
if ((e->key() == Qt::Key_Up || e->key() == Qt::Key_Down) && e->modifiers().testFlag(Qt::AltModifier)) { if ((e->key() == Qt::Key_Up || e->key() == Qt::Key_Down) && e->modifiers().testFlag(Qt::AltModifier)) {
e->ignore(); e->ignore();
} else if(e->key() == Qt::Key_Escape || e->key() == Qt::Key_Back) {
((QObject*)widget())->event(e);
} else { } else {
QScrollArea::keyPressEvent(e); QScrollArea::keyPressEvent(e);
} }

View file

@ -51,7 +51,7 @@ void Widget::paintEvent(QPaintEvent *e) {
Painter p(this); Painter p(this);
p.setOpacity(_shownLevel); p.setOpacity(_shownLevel);
App::roundRect(p, rect(), st::toastBg); App::roundRect(p, rect(), st::toastBg, ImageRoundRadius::Large);
p.setPen(st::toastFg); p.setPen(st::toastFg);
textstyleSet(&st::defaultTextStyle); textstyleSet(&st::defaultTextStyle);

View file

@ -3,60 +3,60 @@ QT += core gui network widgets
CONFIG += plugin static c++14 CONFIG += plugin static c++14
CONFIG(debug, debug|release) { CONFIG(debug, debug|release) {
DEFINES += _DEBUG DEFINES += _DEBUG
OBJECTS_DIR = ./../DebugIntermediate OBJECTS_DIR = ./../DebugIntermediate
MOC_DIR = ./GeneratedFiles/Debug MOC_DIR = ./GeneratedFiles/Debug
RCC_DIR = ./GeneratedFiles RCC_DIR = ./GeneratedFiles
DESTDIR = ./../Debug DESTDIR = ./../Debug
} }
CONFIG(release, debug|release) { CONFIG(release, debug|release) {
DEFINES += CUSTOM_API_ID DEFINES += CUSTOM_API_ID
OBJECTS_DIR = ./../ReleaseIntermediate OBJECTS_DIR = ./../ReleaseIntermediate
MOC_DIR = ./GeneratedFiles/Release MOC_DIR = ./GeneratedFiles/Release
RCC_DIR = ./GeneratedFiles RCC_DIR = ./GeneratedFiles
DESTDIR = ./../Release DESTDIR = ./../Release
} }
macx { macx {
QMAKE_INFO_PLIST = ./SourceFiles/Telegram.plist QMAKE_INFO_PLIST = ./SourceFiles/Telegram.plist
QMAKE_LFLAGS += -framework Cocoa QMAKE_LFLAGS += -framework Cocoa
} }
linux { linux {
SOURCES += ./SourceFiles/pspecific_linux.cpp SOURCES += ./SourceFiles/pspecific_linux.cpp
HEADERS += ./SourceFiles/pspecific_linux.h HEADERS += ./SourceFiles/pspecific_linux.h
} }
CONFIG(debug, debug|release) { CONFIG(debug, debug|release) {
codegen_style.target = style_target codegen_style.target = style_target
codegen_style.depends = FORCE codegen_style.depends = FORCE
codegen_style.commands = ./../codegen/Debug/codegen_style "-I./../../Telegram/Resources" "-I./../../Telegram/SourceFiles" "-o./GeneratedFiles/styles" all_files.style --rebuild codegen_style.commands = ./../codegen/Debug/codegen_style "-I./../../Telegram/Resources" "-I./../../Telegram/SourceFiles" "-o./GeneratedFiles/styles" all_files.style --rebuild
codegen_numbers.target = numbers_target codegen_numbers.target = numbers_target
codegen_numbers.depends = ./../../Telegram/Resources/numbers.txt codegen_numbers.depends = ./../../Telegram/Resources/numbers.txt
codegen_numbers.commands = ./../codegen/Debug/codegen_numbers "-o./GeneratedFiles" "./../../Telegram/Resources/numbers.txt" codegen_numbers.commands = ./../codegen/Debug/codegen_numbers "-o./GeneratedFiles" "./../../Telegram/Resources/numbers.txt"
codegen_numbers.commands = cd ../../Telegram && ./../Linux/codegen/Debug/codegen_numbers "-o./../Linux/DebugIntermediate/GeneratedFiles" "./Resources/numbers.txt" && cd ../Linux/DebugIntermediate codegen_numbers.commands = cd ../../Telegram && ./../Linux/codegen/Debug/codegen_numbers "-o./../Linux/DebugIntermediate/GeneratedFiles" "./Resources/numbers.txt" && cd ../Linux/DebugIntermediate
codegen_lang.target = lang_target codegen_lang.target = lang_target
codegen_lang.depends = ./../../Telegram/Resources/langs/lang.strings codegen_lang.depends = ./../../Telegram/Resources/langs/lang.strings
codegen_lang.commands = mkdir -p ./GeneratedFiles && ./../DebugLang/MetaLang -lang_in ./../../Telegram/Resources/langs/lang.strings -lang_out ./GeneratedFiles/lang_auto codegen_lang.commands = mkdir -p ./GeneratedFiles && ./../DebugLang/MetaLang -lang_in ./../../Telegram/Resources/langs/lang.strings -lang_out ./GeneratedFiles/lang_auto
} }
CONFIG(release, debug|release) { CONFIG(release, debug|release) {
codegen_style.target = style_target codegen_style.target = style_target
codegen_style.depends = FORCE codegen_style.depends = FORCE
codegen_style.commands = ./../codegen/Release/codegen_style "-I./../../Telegram/Resources" "-I./../../Telegram/SourceFiles" "-o./GeneratedFiles/styles" all_files.style --rebuild codegen_style.commands = ./../codegen/Release/codegen_style "-I./../../Telegram/Resources" "-I./../../Telegram/SourceFiles" "-o./GeneratedFiles/styles" all_files.style --rebuild
codegen_numbers.target = numbers_target codegen_numbers.target = numbers_target
codegen_numbers.depends = ./../../Telegram/Resources/numbers.txt codegen_numbers.depends = ./../../Telegram/Resources/numbers.txt
codegen_numbers.commands = ./../codegen/Release/codegen_numbers "-o./GeneratedFiles" "./../../Telegram/Resources/numbers.txt" codegen_numbers.commands = ./../codegen/Release/codegen_numbers "-o./GeneratedFiles" "./../../Telegram/Resources/numbers.txt"
codegen_numbers.commands = cd ../../Telegram && ./../Linux/codegen/Release/codegen_numbers "-o./../Linux/ReleaseIntermediate/GeneratedFiles" "./Resources/numbers.txt" && cd ../Linux/ReleaseIntermediate codegen_numbers.commands = cd ../../Telegram && ./../Linux/codegen/Release/codegen_numbers "-o./../Linux/ReleaseIntermediate/GeneratedFiles" "./Resources/numbers.txt" && cd ../Linux/ReleaseIntermediate
codegen_lang.target = lang_target codegen_lang.target = lang_target
codegen_lang.depends = ./../../Telegram/Resources/langs/lang.strings codegen_lang.depends = ./../../Telegram/Resources/langs/lang.strings
codegen_lang.commands = mkdir -p ./GeneratedFiles && ./../ReleaseLang/MetaLang -lang_in ./../../Telegram/Resources/langs/lang.strings -lang_out ./GeneratedFiles/lang_auto codegen_lang.commands = mkdir -p ./GeneratedFiles && ./../ReleaseLang/MetaLang -lang_in ./../../Telegram/Resources/langs/lang.strings -lang_out ./GeneratedFiles/lang_auto
} }
file_style_basic.target = GeneratedFiles/styles/style_basic.cpp file_style_basic.target = GeneratedFiles/styles/style_basic.cpp
@ -73,374 +73,379 @@ file_style_profile.target = GeneratedFiles/styles/style_profile.cpp
file_style_profile.depends = style_target file_style_profile.depends = style_target
QMAKE_EXTRA_TARGETS += codegen_style codegen_numbers codegen_lang \ QMAKE_EXTRA_TARGETS += codegen_style codegen_numbers codegen_lang \
file_style_basic file_style_basic_types file_style_overview \ file_style_basic file_style_basic_types file_style_overview \
file_style_dialogs file_style_history file_style_profile file_style_dialogs file_style_history file_style_profile
PRE_TARGETDEPS += style_target numbers_target lang_target PRE_TARGETDEPS += style_target numbers_target lang_target
unix { unix {
linux-g++:QMAKE_TARGET.arch = $$QMAKE_HOST.arch linux-g++:QMAKE_TARGET.arch = $$QMAKE_HOST.arch
linux-g++-32:QMAKE_TARGET.arch = x86 linux-g++-32:QMAKE_TARGET.arch = x86
linux-g++-64:QMAKE_TARGET.arch = x86_64 linux-g++-64:QMAKE_TARGET.arch = x86_64
contains(QMAKE_TARGET.arch, x86_64) { contains(QMAKE_TARGET.arch, x86_64) {
DEFINES += Q_OS_LINUX64 DEFINES += Q_OS_LINUX64
} else { } else {
DEFINES += Q_OS_LINUX32 DEFINES += Q_OS_LINUX32
} }
} }
SOURCES += \ SOURCES += \
./GeneratedFiles/lang_auto.cpp \ ./GeneratedFiles/lang_auto.cpp \
./GeneratedFiles/numbers.cpp \ ./GeneratedFiles/numbers.cpp \
./GeneratedFiles/styles/style_basic.cpp \ ./GeneratedFiles/styles/style_basic.cpp \
./GeneratedFiles/styles/style_basic_types.cpp \ ./GeneratedFiles/styles/style_basic_types.cpp \
./GeneratedFiles/styles/style_dialogs.cpp \ ./GeneratedFiles/styles/style_dialogs.cpp \
./GeneratedFiles/styles/style_history.cpp \ ./GeneratedFiles/styles/style_history.cpp \
./GeneratedFiles/styles/style_overview.cpp \ ./GeneratedFiles/styles/style_overview.cpp \
./GeneratedFiles/styles/style_profile.cpp \ ./GeneratedFiles/styles/style_profile.cpp \
./SourceFiles/main.cpp \ ./SourceFiles/main.cpp \
./SourceFiles/stdafx.cpp \ ./SourceFiles/stdafx.cpp \
./SourceFiles/apiwrap.cpp \ ./SourceFiles/apiwrap.cpp \
./SourceFiles/app.cpp \ ./SourceFiles/app.cpp \
./SourceFiles/application.cpp \ ./SourceFiles/application.cpp \
./SourceFiles/audio.cpp \ ./SourceFiles/audio.cpp \
./SourceFiles/autoupdater.cpp \ ./SourceFiles/autoupdater.cpp \
./SourceFiles/dialogswidget.cpp \ ./SourceFiles/dialogswidget.cpp \
./SourceFiles/dropdown.cpp \ ./SourceFiles/dropdown.cpp \
./SourceFiles/facades.cpp \ ./SourceFiles/facades.cpp \
./SourceFiles/fileuploader.cpp \ ./SourceFiles/fileuploader.cpp \
./SourceFiles/history.cpp \ ./SourceFiles/history.cpp \
./SourceFiles/historywidget.cpp \ ./SourceFiles/historywidget.cpp \
./SourceFiles/lang.cpp \ ./SourceFiles/lang.cpp \
./SourceFiles/langloaderplain.cpp \ ./SourceFiles/langloaderplain.cpp \
./SourceFiles/layerwidget.cpp \ ./SourceFiles/layerwidget.cpp \
./SourceFiles/layout.cpp \ ./SourceFiles/layout.cpp \
./SourceFiles/mediaview.cpp \ ./SourceFiles/mediaview.cpp \
./SourceFiles/observer_peer.cpp \ ./SourceFiles/observer_peer.cpp \
./SourceFiles/overviewwidget.cpp \ ./SourceFiles/overviewwidget.cpp \
./SourceFiles/passcodewidget.cpp \ ./SourceFiles/passcodewidget.cpp \
./SourceFiles/playerwidget.cpp \ ./SourceFiles/playerwidget.cpp \
./SourceFiles/localimageloader.cpp \ ./SourceFiles/localimageloader.cpp \
./SourceFiles/localstorage.cpp \ ./SourceFiles/localstorage.cpp \
./SourceFiles/logs.cpp \ ./SourceFiles/logs.cpp \
./SourceFiles/mainwidget.cpp \ ./SourceFiles/mainwidget.cpp \
./SourceFiles/settings.cpp \ ./SourceFiles/settings.cpp \
./SourceFiles/settingswidget.cpp \ ./SourceFiles/settingswidget.cpp \
./SourceFiles/shortcuts.cpp \ ./SourceFiles/shortcuts.cpp \
./SourceFiles/structs.cpp \ ./SourceFiles/structs.cpp \
./SourceFiles/sysbuttons.cpp \ ./SourceFiles/sysbuttons.cpp \
./SourceFiles/title.cpp \ ./SourceFiles/title.cpp \
./SourceFiles/mainwindow.cpp \ ./SourceFiles/mainwindow.cpp \
./SourceFiles/boxes/aboutbox.cpp \ ./SourceFiles/boxes/aboutbox.cpp \
./SourceFiles/boxes/abstractbox.cpp \ ./SourceFiles/boxes/abstractbox.cpp \
./SourceFiles/boxes/addcontactbox.cpp \ ./SourceFiles/boxes/addcontactbox.cpp \
./SourceFiles/boxes/autolockbox.cpp \ ./SourceFiles/boxes/autolockbox.cpp \
./SourceFiles/boxes/backgroundbox.cpp \ ./SourceFiles/boxes/backgroundbox.cpp \
./SourceFiles/boxes/confirmbox.cpp \ ./SourceFiles/boxes/confirmbox.cpp \
./SourceFiles/boxes/connectionbox.cpp \ ./SourceFiles/boxes/connectionbox.cpp \
./SourceFiles/boxes/contactsbox.cpp \ ./SourceFiles/boxes/contactsbox.cpp \
./SourceFiles/boxes/downloadpathbox.cpp \ ./SourceFiles/boxes/downloadpathbox.cpp \
./SourceFiles/boxes/emojibox.cpp \ ./SourceFiles/boxes/emojibox.cpp \
./SourceFiles/boxes/languagebox.cpp \ ./SourceFiles/boxes/languagebox.cpp \
./SourceFiles/boxes/passcodebox.cpp \ ./SourceFiles/boxes/passcodebox.cpp \
./SourceFiles/boxes/photocropbox.cpp \ ./SourceFiles/boxes/photocropbox.cpp \
./SourceFiles/boxes/photosendbox.cpp \ ./SourceFiles/boxes/photosendbox.cpp \
./SourceFiles/boxes/report_box.cpp \ ./SourceFiles/boxes/report_box.cpp \
./SourceFiles/boxes/sessionsbox.cpp \ ./SourceFiles/boxes/sessionsbox.cpp \
./SourceFiles/boxes/stickersetbox.cpp \ ./SourceFiles/boxes/stickersetbox.cpp \
./SourceFiles/boxes/usernamebox.cpp \ ./SourceFiles/boxes/usernamebox.cpp \
./SourceFiles/core/basic_types.cpp \ ./SourceFiles/core/basic_types.cpp \
./SourceFiles/core/click_handler.cpp \ ./SourceFiles/core/click_handler.cpp \
./SourceFiles/core/click_handler_types.cpp \ ./SourceFiles/core/click_handler_types.cpp \
./SourceFiles/core/observer.cpp \ ./SourceFiles/core/observer.cpp \
./SourceFiles/data/data_abstract_structure.cpp \ ./SourceFiles/data/data_abstract_structure.cpp \
./SourceFiles/data/data_drafts.cpp \ ./SourceFiles/data/data_drafts.cpp \
./SourceFiles/dialogs/dialogs_indexed_list.cpp \ ./SourceFiles/dialogs/dialogs_indexed_list.cpp \
./SourceFiles/dialogs/dialogs_layout.cpp \ ./SourceFiles/dialogs/dialogs_layout.cpp \
./SourceFiles/dialogs/dialogs_list.cpp \ ./SourceFiles/dialogs/dialogs_list.cpp \
./SourceFiles/dialogs/dialogs_row.cpp \ ./SourceFiles/dialogs/dialogs_row.cpp \
./SourceFiles/history/field_autocomplete.cpp \ ./SourceFiles/history/field_autocomplete.cpp \
./SourceFiles/history/history_service_layout.cpp \ ./SourceFiles/history/history_service_layout.cpp \
./SourceFiles/inline_bots/inline_bot_layout_internal.cpp \ ./SourceFiles/inline_bots/inline_bot_layout_internal.cpp \
./SourceFiles/inline_bots/inline_bot_layout_item.cpp \ ./SourceFiles/inline_bots/inline_bot_layout_item.cpp \
./SourceFiles/inline_bots/inline_bot_result.cpp \ ./SourceFiles/inline_bots/inline_bot_result.cpp \
./SourceFiles/inline_bots/inline_bot_send_data.cpp \ ./SourceFiles/inline_bots/inline_bot_send_data.cpp \
./SourceFiles/intro/introwidget.cpp \ ./SourceFiles/intro/introwidget.cpp \
./SourceFiles/intro/introcode.cpp \ ./SourceFiles/intro/introcode.cpp \
./SourceFiles/intro/introphone.cpp \ ./SourceFiles/intro/introphone.cpp \
./SourceFiles/intro/intropwdcheck.cpp \ ./SourceFiles/intro/intropwdcheck.cpp \
./SourceFiles/intro/introsignup.cpp \ ./SourceFiles/intro/introsignup.cpp \
./SourceFiles/intro/introstart.cpp \ ./SourceFiles/intro/introstart.cpp \
./SourceFiles/mtproto/facade.cpp \ ./SourceFiles/mtproto/facade.cpp \
./SourceFiles/mtproto/auth_key.cpp \ ./SourceFiles/mtproto/auth_key.cpp \
./SourceFiles/mtproto/connection.cpp \ ./SourceFiles/mtproto/connection.cpp \
./SourceFiles/mtproto/connection_abstract.cpp \ ./SourceFiles/mtproto/connection_abstract.cpp \
./SourceFiles/mtproto/connection_auto.cpp \ ./SourceFiles/mtproto/connection_auto.cpp \
./SourceFiles/mtproto/connection_http.cpp \ ./SourceFiles/mtproto/connection_http.cpp \
./SourceFiles/mtproto/connection_tcp.cpp \ ./SourceFiles/mtproto/connection_tcp.cpp \
./SourceFiles/mtproto/core_types.cpp \ ./SourceFiles/mtproto/core_types.cpp \
./SourceFiles/mtproto/dcenter.cpp \ ./SourceFiles/mtproto/dcenter.cpp \
./SourceFiles/mtproto/file_download.cpp \ ./SourceFiles/mtproto/file_download.cpp \
./SourceFiles/mtproto/rsa_public_key.cpp \ ./SourceFiles/mtproto/rsa_public_key.cpp \
./SourceFiles/mtproto/rpc_sender.cpp \ ./SourceFiles/mtproto/rpc_sender.cpp \
./SourceFiles/mtproto/scheme_auto.cpp \ ./SourceFiles/mtproto/scheme_auto.cpp \
./SourceFiles/mtproto/session.cpp \ ./SourceFiles/mtproto/session.cpp \
./SourceFiles/overview/overview_layout.cpp \ ./SourceFiles/overview/overview_layout.cpp \
./SourceFiles/platform/linux/linux_gdk_helper.cpp \
./SourceFiles/platform/linux/linux_libs.cpp \ ./SourceFiles/platform/linux/linux_libs.cpp \
./SourceFiles/platform/linux/main_window_linux.cpp \ ./SourceFiles/platform/linux/file_dialog_linux.cpp \
./SourceFiles/profile/profile_actions_widget.cpp \ ./SourceFiles/platform/linux/main_window_linux.cpp \
./SourceFiles/profile/profile_block_widget.cpp \ ./SourceFiles/profile/profile_actions_widget.cpp \
./SourceFiles/profile/profile_cover_drop_area.cpp \ ./SourceFiles/profile/profile_block_widget.cpp \
./SourceFiles/profile/profile_cover.cpp \ ./SourceFiles/profile/profile_cover_drop_area.cpp \
./SourceFiles/profile/profile_fixed_bar.cpp \ ./SourceFiles/profile/profile_cover.cpp \
./SourceFiles/profile/profile_info_widget.cpp \ ./SourceFiles/profile/profile_fixed_bar.cpp \
./SourceFiles/profile/profile_inner_widget.cpp \ ./SourceFiles/profile/profile_info_widget.cpp \
./SourceFiles/profile/profile_invite_link_widget.cpp \ ./SourceFiles/profile/profile_inner_widget.cpp \
./SourceFiles/profile/profile_members_widget.cpp \ ./SourceFiles/profile/profile_invite_link_widget.cpp \
./SourceFiles/profile/profile_section_memento.cpp \ ./SourceFiles/profile/profile_members_widget.cpp \
./SourceFiles/profile/profile_settings_widget.cpp \ ./SourceFiles/profile/profile_section_memento.cpp \
./SourceFiles/profile/profile_shared_media_widget.cpp \ ./SourceFiles/profile/profile_settings_widget.cpp \
./SourceFiles/profile/profile_userpic_button.cpp \ ./SourceFiles/profile/profile_shared_media_widget.cpp \
./SourceFiles/profile/profile_widget.cpp \ ./SourceFiles/profile/profile_userpic_button.cpp \
./SourceFiles/serialize/serialize_common.cpp \ ./SourceFiles/profile/profile_widget.cpp \
./SourceFiles/serialize/serialize_document.cpp \ ./SourceFiles/serialize/serialize_common.cpp \
./SourceFiles/ui/buttons/history_down_button.cpp \ ./SourceFiles/serialize/serialize_document.cpp \
./SourceFiles/ui/buttons/left_outline_button.cpp \ ./SourceFiles/ui/buttons/history_down_button.cpp \
./SourceFiles/ui/buttons/peer_avatar_button.cpp \ ./SourceFiles/ui/buttons/left_outline_button.cpp \
./SourceFiles/ui/buttons/round_button.cpp \ ./SourceFiles/ui/buttons/peer_avatar_button.cpp \
./SourceFiles/ui/style/style_core.cpp \ ./SourceFiles/ui/buttons/round_button.cpp \
./SourceFiles/ui/style/style_core_color.cpp \ ./SourceFiles/ui/style/style_core.cpp \
./SourceFiles/ui/style/style_core_font.cpp \ ./SourceFiles/ui/style/style_core_color.cpp \
./SourceFiles/ui/style/style_core_icon.cpp \ ./SourceFiles/ui/style/style_core_font.cpp \
./SourceFiles/ui/style/style_core_types.cpp \ ./SourceFiles/ui/style/style_core_icon.cpp \
./SourceFiles/ui/text/text.cpp \ ./SourceFiles/ui/style/style_core_types.cpp \
./SourceFiles/ui/text/text_block.cpp \ ./SourceFiles/ui/text/text.cpp \
./SourceFiles/ui/text/text_entity.cpp \ ./SourceFiles/ui/text/text_block.cpp \
./SourceFiles/ui/toast/toast.cpp \ ./SourceFiles/ui/text/text_entity.cpp \
./SourceFiles/ui/toast/toast_manager.cpp \ ./SourceFiles/ui/toast/toast.cpp \
./SourceFiles/ui/toast/toast_widget.cpp \ ./SourceFiles/ui/toast/toast_manager.cpp \
./SourceFiles/ui/animation.cpp \ ./SourceFiles/ui/toast/toast_widget.cpp \
./SourceFiles/ui/boxshadow.cpp \ ./SourceFiles/ui/animation.cpp \
./SourceFiles/ui/button.cpp \ ./SourceFiles/ui/boxshadow.cpp \
./SourceFiles/ui/popupmenu.cpp \ ./SourceFiles/ui/button.cpp \
./SourceFiles/ui/countryinput.cpp \ ./SourceFiles/ui/popupmenu.cpp \
./SourceFiles/ui/emoji_config.cpp \ ./SourceFiles/ui/countryinput.cpp \
./SourceFiles/ui/filedialog.cpp \ ./SourceFiles/ui/emoji_config.cpp \
./SourceFiles/ui/flatbutton.cpp \ ./SourceFiles/ui/filedialog.cpp \
./SourceFiles/ui/flatcheckbox.cpp \ ./SourceFiles/ui/flatbutton.cpp \
./SourceFiles/ui/flatinput.cpp \ ./SourceFiles/ui/flatcheckbox.cpp \
./SourceFiles/ui/flatlabel.cpp \ ./SourceFiles/ui/flatinput.cpp \
./SourceFiles/ui/flattextarea.cpp \ ./SourceFiles/ui/flatlabel.cpp \
./SourceFiles/ui/images.cpp \ ./SourceFiles/ui/flattextarea.cpp \
./SourceFiles/ui/inner_dropdown.cpp \ ./SourceFiles/ui/images.cpp \
./SourceFiles/ui/scrollarea.cpp \ ./SourceFiles/ui/inner_dropdown.cpp \
./SourceFiles/ui/twidget.cpp \ ./SourceFiles/ui/scrollarea.cpp \
./SourceFiles/window/main_window.cpp \ ./SourceFiles/ui/twidget.cpp \
./SourceFiles/window/section_widget.cpp \ ./SourceFiles/window/main_window.cpp \
./SourceFiles/window/slide_animation.cpp \ ./SourceFiles/window/section_widget.cpp \
./SourceFiles/window/top_bar_widget.cpp ./SourceFiles/window/slide_animation.cpp \
./SourceFiles/window/top_bar_widget.cpp
HEADERS += \ HEADERS += \
./GeneratedFiles/lang_auto.h \ ./GeneratedFiles/lang_auto.h \
./GeneratedFiles/numbers.h \ ./GeneratedFiles/numbers.h \
./GeneratedFiles/styles/style_basic.h \ ./GeneratedFiles/styles/style_basic.h \
./GeneratedFiles/styles/style_basic_types.h \ ./GeneratedFiles/styles/style_basic_types.h \
./GeneratedFiles/styles/style_dialogs.h \ ./GeneratedFiles/styles/style_dialogs.h \
./GeneratedFiles/styles/style_history.h \ ./GeneratedFiles/styles/style_history.h \
./GeneratedFiles/styles/style_overview.h \ ./GeneratedFiles/styles/style_overview.h \
./GeneratedFiles/styles/style_profile.h \ ./GeneratedFiles/styles/style_profile.h \
./SourceFiles/stdafx.h \ ./SourceFiles/stdafx.h \
./SourceFiles/apiwrap.h \ ./SourceFiles/apiwrap.h \
./SourceFiles/app.h \ ./SourceFiles/app.h \
./SourceFiles/application.h \ ./SourceFiles/application.h \
./SourceFiles/audio.h \ ./SourceFiles/audio.h \
./SourceFiles/autoupdater.h \ ./SourceFiles/autoupdater.h \
./SourceFiles/config.h \ ./SourceFiles/config.h \
./SourceFiles/countries.h \ ./SourceFiles/countries.h \
./SourceFiles/dialogswidget.h \ ./SourceFiles/dialogswidget.h \
./SourceFiles/dropdown.h \ ./SourceFiles/dropdown.h \
./SourceFiles/facades.h \ ./SourceFiles/facades.h \
./SourceFiles/fileuploader.h \ ./SourceFiles/fileuploader.h \
./SourceFiles/history.h \ ./SourceFiles/history.h \
./SourceFiles/historywidget.h \ ./SourceFiles/historywidget.h \
./SourceFiles/lang.h \ ./SourceFiles/lang.h \
./SourceFiles/langloaderplain.h \ ./SourceFiles/langloaderplain.h \
./SourceFiles/layerwidget.h \ ./SourceFiles/layerwidget.h \
./SourceFiles/layout.h \ ./SourceFiles/layout.h \
./SourceFiles/mediaview.h \ ./SourceFiles/mediaview.h \
./SourceFiles/observer_peer.h \ ./SourceFiles/observer_peer.h \
./SourceFiles/overviewwidget.h \ ./SourceFiles/overviewwidget.h \
./SourceFiles/passcodewidget.h \ ./SourceFiles/passcodewidget.h \
./SourceFiles/playerwidget.h \ ./SourceFiles/playerwidget.h \
./SourceFiles/localimageloader.h \ ./SourceFiles/localimageloader.h \
./SourceFiles/localstorage.h \ ./SourceFiles/localstorage.h \
./SourceFiles/logs.h \ ./SourceFiles/logs.h \
./SourceFiles/mainwidget.h \ ./SourceFiles/mainwidget.h \
./SourceFiles/settings.h \ ./SourceFiles/settings.h \
./SourceFiles/settingswidget.h \ ./SourceFiles/settingswidget.h \
./SourceFiles/shortcuts.h \ ./SourceFiles/shortcuts.h \
./SourceFiles/structs.h \ ./SourceFiles/structs.h \
./SourceFiles/sysbuttons.h \ ./SourceFiles/sysbuttons.h \
./SourceFiles/title.h \ ./SourceFiles/title.h \
./SourceFiles/mainwindow.h \ ./SourceFiles/mainwindow.h \
./SourceFiles/boxes/aboutbox.h \ ./SourceFiles/boxes/aboutbox.h \
./SourceFiles/boxes/abstractbox.h \ ./SourceFiles/boxes/abstractbox.h \
./SourceFiles/boxes/addcontactbox.h \ ./SourceFiles/boxes/addcontactbox.h \
./SourceFiles/boxes/autolockbox.h \ ./SourceFiles/boxes/autolockbox.h \
./SourceFiles/boxes/backgroundbox.h \ ./SourceFiles/boxes/backgroundbox.h \
./SourceFiles/boxes/confirmbox.h \ ./SourceFiles/boxes/confirmbox.h \
./SourceFiles/boxes/connectionbox.h \ ./SourceFiles/boxes/connectionbox.h \
./SourceFiles/boxes/contactsbox.h \ ./SourceFiles/boxes/contactsbox.h \
./SourceFiles/boxes/downloadpathbox.h \ ./SourceFiles/boxes/downloadpathbox.h \
./SourceFiles/boxes/emojibox.h \ ./SourceFiles/boxes/emojibox.h \
./SourceFiles/boxes/languagebox.h \ ./SourceFiles/boxes/languagebox.h \
./SourceFiles/boxes/passcodebox.h \ ./SourceFiles/boxes/passcodebox.h \
./SourceFiles/boxes/photocropbox.h \ ./SourceFiles/boxes/photocropbox.h \
./SourceFiles/boxes/photosendbox.h \ ./SourceFiles/boxes/photosendbox.h \
./SourceFiles/boxes/report_box.h \ ./SourceFiles/boxes/report_box.h \
./SourceFiles/boxes/sessionsbox.h \ ./SourceFiles/boxes/sessionsbox.h \
./SourceFiles/boxes/stickersetbox.h \ ./SourceFiles/boxes/stickersetbox.h \
./SourceFiles/boxes/usernamebox.h \ ./SourceFiles/boxes/usernamebox.h \
./SourceFiles/core/basic_types.h \ ./SourceFiles/core/basic_types.h \
./SourceFiles/core/click_handler.h \ ./SourceFiles/core/click_handler.h \
./SourceFiles/core/click_handler_types.h \ ./SourceFiles/core/click_handler_types.h \
./SourceFiles/core/observer.h \ ./SourceFiles/core/observer.h \
./SourceFiles/core/vector_of_moveable.h \ ./SourceFiles/core/vector_of_moveable.h \
./SourceFiles/core/version.h \ ./SourceFiles/core/version.h \
./SourceFiles/data/data_abstract_structure.h \ ./SourceFiles/data/data_abstract_structure.h \
./SourceFiles/data/data_drafts.h \ ./SourceFiles/data/data_drafts.h \
./SourceFiles/dialogs/dialogs_common.h \ ./SourceFiles/dialogs/dialogs_common.h \
./SourceFiles/dialogs/dialogs_indexed_list.h \ ./SourceFiles/dialogs/dialogs_indexed_list.h \
./SourceFiles/dialogs/dialogs_layout.h \ ./SourceFiles/dialogs/dialogs_layout.h \
./SourceFiles/dialogs/dialogs_list.h \ ./SourceFiles/dialogs/dialogs_list.h \
./SourceFiles/dialogs/dialogs_row.h \ ./SourceFiles/dialogs/dialogs_row.h \
./SourceFiles/history/field_autocomplete.h \ ./SourceFiles/history/field_autocomplete.h \
./SourceFiles/history/history_common.h \ ./SourceFiles/history/history_common.h \
./SourceFiles/history/history_service_layout.h \ ./SourceFiles/history/history_service_layout.h \
./SourceFiles/inline_bots/inline_bot_layout_internal.h \ ./SourceFiles/inline_bots/inline_bot_layout_internal.h \
./SourceFiles/inline_bots/inline_bot_layout_item.h \ ./SourceFiles/inline_bots/inline_bot_layout_item.h \
./SourceFiles/inline_bots/inline_bot_result.h \ ./SourceFiles/inline_bots/inline_bot_result.h \
./SourceFiles/inline_bots/inline_bot_send_data.h \ ./SourceFiles/inline_bots/inline_bot_send_data.h \
./SourceFiles/intro/introwidget.h \ ./SourceFiles/intro/introwidget.h \
./SourceFiles/intro/introcode.h \ ./SourceFiles/intro/introcode.h \
./SourceFiles/intro/introphone.h \ ./SourceFiles/intro/introphone.h \
./SourceFiles/intro/intropwdcheck.h \ ./SourceFiles/intro/intropwdcheck.h \
./SourceFiles/intro/introsignup.h \ ./SourceFiles/intro/introsignup.h \
./SourceFiles/intro/introstart.h \ ./SourceFiles/intro/introstart.h \
./SourceFiles/mtproto/facade.h \ ./SourceFiles/mtproto/facade.h \
./SourceFiles/mtproto/auth_key.h \ ./SourceFiles/mtproto/auth_key.h \
./SourceFiles/mtproto/connection.h \ ./SourceFiles/mtproto/connection.h \
./SourceFiles/mtproto/connection_abstract.h \ ./SourceFiles/mtproto/connection_abstract.h \
./SourceFiles/mtproto/connection_auto.h \ ./SourceFiles/mtproto/connection_auto.h \
./SourceFiles/mtproto/connection_http.h \ ./SourceFiles/mtproto/connection_http.h \
./SourceFiles/mtproto/connection_tcp.h \ ./SourceFiles/mtproto/connection_tcp.h \
./SourceFiles/mtproto/core_types.h \ ./SourceFiles/mtproto/core_types.h \
./SourceFiles/mtproto/dcenter.h \ ./SourceFiles/mtproto/dcenter.h \
./SourceFiles/mtproto/file_download.h \ ./SourceFiles/mtproto/file_download.h \
./SourceFiles/mtproto/rsa_public_key.h \ ./SourceFiles/mtproto/rsa_public_key.h \
./SourceFiles/mtproto/rpc_sender.h \ ./SourceFiles/mtproto/rpc_sender.h \
./SourceFiles/mtproto/scheme_auto.h \ ./SourceFiles/mtproto/scheme_auto.h \
./SourceFiles/mtproto/session.h \ ./SourceFiles/mtproto/session.h \
./SourceFiles/overview/overview_layout.h \ ./SourceFiles/overview/overview_layout.h \
./SourceFiles/platform/platform_main_window.h \ ./SourceFiles/platform/platform_file_dialog.h \
./SourceFiles/platform/platform_main_window.h \
./SourceFiles/platform/linux/linux_gdk_helper.h \
./SourceFiles/platform/linux/linux_libs.h \ ./SourceFiles/platform/linux/linux_libs.h \
./SourceFiles/platform/linux/main_window_linux.h \ ./SourceFiles/platform/linux/file_dialog_linux.h \
./SourceFiles/profile/profile_actions_widget.h \ ./SourceFiles/platform/linux/main_window_linux.h \
./SourceFiles/profile/profile_block_widget.h \ ./SourceFiles/profile/profile_actions_widget.h \
./SourceFiles/profile/profile_cover_drop_area.h \ ./SourceFiles/profile/profile_block_widget.h \
./SourceFiles/profile/profile_cover.h \ ./SourceFiles/profile/profile_cover_drop_area.h \
./SourceFiles/profile/profile_fixed_bar.h \ ./SourceFiles/profile/profile_cover.h \
./SourceFiles/profile/profile_info_widget.h \ ./SourceFiles/profile/profile_fixed_bar.h \
./SourceFiles/profile/profile_inner_widget.h \ ./SourceFiles/profile/profile_info_widget.h \
./SourceFiles/profile/profile_invite_link_widget.h \ ./SourceFiles/profile/profile_inner_widget.h \
./SourceFiles/profile/profile_members_widget.h \ ./SourceFiles/profile/profile_invite_link_widget.h \
./SourceFiles/profile/profile_section_memento.h \ ./SourceFiles/profile/profile_members_widget.h \
./SourceFiles/profile/profile_settings_widget.h \ ./SourceFiles/profile/profile_section_memento.h \
./SourceFiles/profile/profile_shared_media_widget.h \ ./SourceFiles/profile/profile_settings_widget.h \
./SourceFiles/profile/profile_userpic_button.h \ ./SourceFiles/profile/profile_shared_media_widget.h \
./SourceFiles/profile/profile_widget.h \ ./SourceFiles/profile/profile_userpic_button.h \
./SourceFiles/pspecific.h \ ./SourceFiles/profile/profile_widget.h \
./SourceFiles/serialize/serialize_common.h \ ./SourceFiles/pspecific.h \
./SourceFiles/serialize/serialize_document.h \ ./SourceFiles/serialize/serialize_common.h \
./SourceFiles/ui/buttons/history_down_button.h \ ./SourceFiles/serialize/serialize_document.h \
./SourceFiles/ui/buttons/left_outline_button.h \ ./SourceFiles/ui/buttons/history_down_button.h \
./SourceFiles/ui/buttons/peer_avatar_button.h \ ./SourceFiles/ui/buttons/left_outline_button.h \
./SourceFiles/ui/buttons/round_button.h \ ./SourceFiles/ui/buttons/peer_avatar_button.h \
./SourceFiles/ui/style/style_core.h \ ./SourceFiles/ui/buttons/round_button.h \
./SourceFiles/ui/style/style_core_color.h \ ./SourceFiles/ui/style/style_core.h \
./SourceFiles/ui/style/style_core_font.h \ ./SourceFiles/ui/style/style_core_color.h \
./SourceFiles/ui/style/style_core_icon.h \ ./SourceFiles/ui/style/style_core_font.h \
./SourceFiles/ui/style/style_core_types.h \ ./SourceFiles/ui/style/style_core_icon.h \
./SourceFiles/ui/text/text.h \ ./SourceFiles/ui/style/style_core_types.h \
./SourceFiles/ui/text/text_block.h \ ./SourceFiles/ui/text/text.h \
./SourceFiles/ui/text/text_entity.h \ ./SourceFiles/ui/text/text_block.h \
./SourceFiles/ui/toast/toast.h \ ./SourceFiles/ui/text/text_entity.h \
./SourceFiles/ui/toast/toast_manager.h \ ./SourceFiles/ui/toast/toast.h \
./SourceFiles/ui/toast/toast_widget.h \ ./SourceFiles/ui/toast/toast_manager.h \
./SourceFiles/ui/animation.h \ ./SourceFiles/ui/toast/toast_widget.h \
./SourceFiles/ui/boxshadow.h \ ./SourceFiles/ui/animation.h \
./SourceFiles/ui/button.h \ ./SourceFiles/ui/boxshadow.h \
./SourceFiles/ui/popupmenu.h \ ./SourceFiles/ui/button.h \
./SourceFiles/ui/countryinput.h \ ./SourceFiles/ui/popupmenu.h \
./SourceFiles/ui/emoji_config.h \ ./SourceFiles/ui/countryinput.h \
./SourceFiles/ui/filedialog.h \ ./SourceFiles/ui/emoji_config.h \
./SourceFiles/ui/flatbutton.h \ ./SourceFiles/ui/filedialog.h \
./SourceFiles/ui/flatcheckbox.h \ ./SourceFiles/ui/flatbutton.h \
./SourceFiles/ui/flatinput.h \ ./SourceFiles/ui/flatcheckbox.h \
./SourceFiles/ui/flatlabel.h \ ./SourceFiles/ui/flatinput.h \
./SourceFiles/ui/flattextarea.h \ ./SourceFiles/ui/flatlabel.h \
./SourceFiles/ui/images.h \ ./SourceFiles/ui/flattextarea.h \
./SourceFiles/ui/inner_dropdown.h \ ./SourceFiles/ui/images.h \
./SourceFiles/ui/scrollarea.h \ ./SourceFiles/ui/inner_dropdown.h \
./SourceFiles/ui/twidget.h \ ./SourceFiles/ui/scrollarea.h \
./SourceFiles/window/main_window.h \ ./SourceFiles/ui/twidget.h \
./SourceFiles/window/section_memento.h \ ./SourceFiles/window/main_window.h \
./SourceFiles/window/section_widget.h \ ./SourceFiles/window/section_memento.h \
./SourceFiles/window/slide_animation.h \ ./SourceFiles/window/section_widget.h \
./SourceFiles/window/top_bar_widget.h ./SourceFiles/window/slide_animation.h \
./SourceFiles/window/top_bar_widget.h
win32 { win32 {
SOURCES += \ SOURCES += \
./SourceFiles/pspecific_win.cpp \ ./SourceFiles/pspecific_win.cpp \
./SourceFiles/platform/win/windows_app_user_model_id.cpp \ ./SourceFiles/platform/win/windows_app_user_model_id.cpp \
./SourceFiles/platform/win/windows_dlls.cpp \ ./SourceFiles/platform/win/windows_dlls.cpp \
./SourceFiles/platform/win/windows_event_filter.cpp \ ./SourceFiles/platform/win/windows_event_filter.cpp \
./SourceFiles/platform/win/windows_toasts.cpp ./SourceFiles/platform/win/windows_toasts.cpp
HEADERS += \ HEADERS += \
./SourceFiles/pspecific_win.h \ ./SourceFiles/pspecific_win.h \
./SourceFiles/platform/win/windows_app_user_model_id.h \ ./SourceFiles/platform/win/windows_app_user_model_id.h \
./SourceFiles/platform/win/windows_dlls.h \ ./SourceFiles/platform/win/windows_dlls.h \
./SourceFiles/platform/win/windows_event_filter.h \ ./SourceFiles/platform/win/windows_event_filter.h \
./SourceFiles/platform/win/windows_toasts.h ./SourceFiles/platform/win/windows_toasts.h
} }
winrt { winrt {
SOURCES += \ SOURCES += \
./SourceFiles/pspecific_winrt.cpp \ ./SourceFiles/pspecific_winrt.cpp \
./SourceFiles/platform/winrt/main_window_winrt.cpp ./SourceFiles/platform/winrt/main_window_winrt.cpp
HEADERS += \ HEADERS += \
./SourceFiles/pspecific_winrt.h \ ./SourceFiles/pspecific_winrt.h \
./Sourcefiles/platform/winrt/main_window_winrt.h ./Sourcefiles/platform/winrt/main_window_winrt.h
} }
macx { macx {
SOURCES += \ SOURCES += \
./SourceFiles/pspecific_mac.cpp ./SourceFiles/pspecific_mac.cpp
HEADERS += \ HEADERS += \
./SourceFiles/pspecific_mac.h ./SourceFiles/pspecific_mac.h
OBJECTIVE_SOURCES += \ OBJECTIVE_SOURCES += \
./SourceFiles/pspecific_mac_p.mm \ ./SourceFiles/pspecific_mac_p.mm \
./SourceFiles/platform/mac/main_window_mac.mm ./SourceFiles/platform/mac/main_window_mac.mm
HEADERS += \ HEADERS += \
./SourceFiles/pspecific_mac_p.h \ ./SourceFiles/pspecific_mac_p.h \
./SourceFiles/platform/mac/main_window_mac.h ./SourceFiles/platform/mac/main_window_mac.h
} }
SOURCES += \ SOURCES += \
./ThirdParty/minizip/zip.c \ ./ThirdParty/minizip/zip.c \
./ThirdParty/minizip/ioapi.c ./ThirdParty/minizip/ioapi.c
CONFIG += precompile_header CONFIG += precompile_header
@ -450,19 +455,19 @@ QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-result -Wno-unused-parameter -Wno-unused-v
QMAKE_CFLAGS_WARN_ON += -Wno-unused-result -Wno-unused-parameter -Wno-unused-variable -Wno-switch -Wno-comment -Wno-unused-but-set-variable QMAKE_CFLAGS_WARN_ON += -Wno-unused-result -Wno-unused-parameter -Wno-unused-variable -Wno-switch -Wno-comment -Wno-unused-but-set-variable
CONFIG(release, debug|release) { CONFIG(release, debug|release) {
QMAKE_CXXFLAGS_RELEASE -= -O2 QMAKE_CXXFLAGS_RELEASE -= -O2
QMAKE_CXXFLAGS_RELEASE += -Ofast -flto -fno-strict-aliasing -g QMAKE_CXXFLAGS_RELEASE += -Ofast -flto -fno-strict-aliasing -g
QMAKE_LFLAGS_RELEASE -= -O1 QMAKE_LFLAGS_RELEASE -= -O1
QMAKE_LFLAGS_RELEASE += -Ofast -flto -g -rdynamic -static-libstdc++ QMAKE_LFLAGS_RELEASE += -Ofast -flto -g -rdynamic -static-libstdc++
} }
# Linux 32bit fails Release link with Link-Time Optimization: virtual memory exhausted # Linux 32bit fails Release link with Link-Time Optimization: virtual memory exhausted
unix { unix {
!contains(QMAKE_TARGET.arch, x86_64) { !contains(QMAKE_TARGET.arch, x86_64) {
CONFIG(release, debug|release) { CONFIG(release, debug|release) {
QMAKE_CXXFLAGS_RELEASE -= -flto QMAKE_CXXFLAGS_RELEASE -= -flto
QMAKE_LFLAGS_RELEASE -= -flto QMAKE_LFLAGS_RELEASE -= -flto
} }
} }
} }
CONFIG(debug, debug|release) { CONFIG(debug, debug|release) {
QMAKE_LFLAGS_DEBUG += -g -rdynamic -static-libstdc++ QMAKE_LFLAGS_DEBUG += -g -rdynamic -static-libstdc++
@ -471,22 +476,23 @@ CONFIG(debug, debug|release) {
include(qt_static.pri) include(qt_static.pri)
INCLUDEPATH += \ INCLUDEPATH += \
/usr/local/include\ /usr/local/include\
/usr/local/include/opus\ /usr/local/include/opus\
./SourceFiles\ ./SourceFiles\
./GeneratedFiles\ ./GeneratedFiles\
./ThirdParty/minizip\ ./ThirdParty/minizip\
./../../Libraries/breakpad/src ./../../Libraries/breakpad/src
INCLUDEPATH += "/usr/include/libappindicator-0.1" INCLUDEPATH += "/usr/include/libappindicator-0.1"
#INCLUDEPATH += "/usr/include/gtk-3.0"
INCLUDEPATH += "/usr/include/gtk-2.0" INCLUDEPATH += "/usr/include/gtk-2.0"
INCLUDEPATH += "/usr/lib/x86_64-linux-gnu/gtk-2.0/include"
INCLUDEPATH += "/usr/lib/i386-linux-gnu/gtk-2.0/include"
INCLUDEPATH += "/usr/include/glib-2.0" INCLUDEPATH += "/usr/include/glib-2.0"
INCLUDEPATH += "/usr/lib/x86_64-linux-gnu/glib-2.0/include" INCLUDEPATH += "/usr/lib/x86_64-linux-gnu/glib-2.0/include"
INCLUDEPATH += "/usr/lib/i386-linux-gnu/glib-2.0/include" INCLUDEPATH += "/usr/lib/i386-linux-gnu/glib-2.0/include"
INCLUDEPATH += "/usr/include/cairo" INCLUDEPATH += "/usr/include/cairo"
INCLUDEPATH += "/usr/include/pango-1.0" INCLUDEPATH += "/usr/include/pango-1.0"
INCLUDEPATH += "/usr/lib/x86_64-linux-gnu/gtk-2.0/include"
INCLUDEPATH += "/usr/lib/i386-linux-gnu/gtk-2.0/include"
INCLUDEPATH += "/usr/include/gdk-pixbuf-2.0" INCLUDEPATH += "/usr/include/gdk-pixbuf-2.0"
INCLUDEPATH += "/usr/include/atk-1.0" INCLUDEPATH += "/usr/include/atk-1.0"
@ -502,21 +508,21 @@ LIBS += /usr/local/lib/libxkbcommon.a
LIBS += ./../../../Libraries/breakpad/src/client/linux/libbreakpad_client.a LIBS += ./../../../Libraries/breakpad/src/client/linux/libbreakpad_client.a
RESOURCES += \ RESOURCES += \
./Resources/telegram.qrc \ ./Resources/telegram.qrc \
./Resources/telegram_linux.qrc \ ./Resources/telegram_linux.qrc \
./Resources/telegram_emojis.qrc ./Resources/telegram_emojis.qrc
OTHER_FILES += \ OTHER_FILES += \
./Resources/basic_types.style \ ./Resources/basic_types.style \
./Resources/basic.style \ ./Resources/basic.style \
./Resources/all_files.style \ ./Resources/all_files.style \
./Resources/langs/lang.strings \ ./Resources/langs/lang.strings \
./Resources/langs/lang_it.strings \ ./Resources/langs/lang_it.strings \
./Resources/langs/lang_es.strings \ ./Resources/langs/lang_es.strings \
./Resources/langs/lang_de.strings \ ./Resources/langs/lang_de.strings \
./Resources/langs/lang_nl.strings \ ./Resources/langs/lang_nl.strings \
./Resources/langs/lang_pt_BR.strings \ ./Resources/langs/lang_pt_BR.strings \
./SourceFiles/dialogs/dialogs.style \ ./SourceFiles/dialogs/dialogs.style \
./SourceFiles/history/history.style \ ./SourceFiles/history/history.style \
./SourceFiles/overview/overview.style \ ./SourceFiles/overview/overview.style \
./SourceFiles/profile/profile.style ./SourceFiles/profile/profile.style

View file

@ -1,20 +1,26 @@
QT_TDESKTOP_VERSION_DEFAULT = 5.6.0 QT_TDESKTOP_VERSION_DEFAULT = 5.6.0
QT_TDESKTOP_PATH_DEFAULT = /usr/local/tdesktop/Qt-$${QT_TDESKTOP_VERSION_DEFAULT} QT_TDESKTOP_PATH_DEFAULT = /usr/local/tdesktop/Qt-$${QT_TDESKTOP_VERSION_DEFAULT}
QT_TDESKTOP_VERSION = $${QT_TDESKTOP_VERSION}
QT_TDESKTOP_PATH = $${QT_TDESKTOP_PATH} QT_TDESKTOP_PATH = $${QT_TDESKTOP_PATH}
isEmpty(QT_TDESKTOP_PATH) { isEmpty(QT_TDESKTOP_PATH) {
message(QT_TDESKTOP_PATH is not set. Using default value $${QT_TDESKTOP_PATH_DEFAULT}) QT_TDESKTOP_PATH = $$(QT_TDESKTOP_PATH)
QT_TDESKTOP_PATH = $${QT_TDESKTOP_PATH_DEFAULT} isEmpty(QT_TDESKTOP_PATH) {
message(QT_TDESKTOP_PATH is not set. Using default value $${QT_TDESKTOP_PATH_DEFAULT})
QT_TDESKTOP_PATH = $${QT_TDESKTOP_PATH_DEFAULT}
}
} }
QT_TDESKTOP_VERSION = $${QT_TDESKTOP_VERSION}
isEmpty(QT_TDESKTOP_VERSION) { isEmpty(QT_TDESKTOP_VERSION) {
message(QT_TDESKTOP_VERSION is not set. Using default value $${QT_TDESKTOP_VERSION_DEFAULT}) QT_TDESKTOP_VERSION = $$(QT_TDESKTOP_VERSION)
QT_TDESKTOP_VERSION = $${QT_TDESKTOP_VERSION_DEFAULT} isEmpty(QT_TDESKTOP_VERSION) {
message(QT_TDESKTOP_VERSION is not set. Using default value $${QT_TDESKTOP_VERSION_DEFAULT})
QT_TDESKTOP_VERSION = $${QT_TDESKTOP_VERSION_DEFAULT}
}
} }
INCLUDEPATH += $${QT_TDESKTOP_PATH}/include/QtGui/$${QT_TDESKTOP_VERSION}/QtGui \ INCLUDEPATH += $${QT_TDESKTOP_PATH}/include/QtGui/$${QT_TDESKTOP_VERSION}/QtGui \
$${QT_TDESKTOP_PATH}/include/QtCore/$${QT_TDESKTOP_VERSION}/QtCore \ $${QT_TDESKTOP_PATH}/include/QtCore/$${QT_TDESKTOP_VERSION}/QtCore \
$${QT_TDESKTOP_PATH}/include/QtCore/$${QT_TDESKTOP_VERSION} \
$${QT_TDESKTOP_PATH}/include $${QT_TDESKTOP_PATH}/include

View file

@ -1,10 +1,36 @@
##Build instructions for Visual Studio 2015 # Build instructions for Visual Studio 2015
###Prepare folder * [Prepare folder](#prepare-folder)
* [Clone source code](#clone-source-code)
* [Prepare libraries](#prepare-libraries)
+ [OpenSSL](#openssl)
+ [LZMA SDK 9.20](#lzma-sdk-920)
- [Building library](#building-library)
+ [zlib 1.2.8](#zlib-128)
- [Building library](#building-library-1)
+ [libexif 0.6.20](#libexif-0620)
- [Building library](#building-library-2)
+ [OpenAL Soft, slightly patched](#openal-soft-slightly-patched)
- [Building library](#building-library-3)
+ [Opus codec](#opus-codec)
- [Building libraries](#building-libraries)
+ [FFmpeg](#ffmpeg)
- [Building libraries](#building-libraries-1)
+ [Qt 5.6.0, slightly patched](#qt-560-slightly-patched)
- [Apply the patch](#apply-the-patch)
- [Install Windows SDKs](#install-windows-sdks)
- [Building library](#building-library-4)
+ [Qt5Package](#qt5package)
+ [Google Breakpad](#google-breakpad)
- [Install](#install)
- [Build](#build)
* [Building Telegram Desktop](#building-telegram-desktop)
## 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. 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 ## Clone source code
By git in [Git Bash](http://git-scm.com/downloads) go to **/d/tbuild** and run By git in [Git Bash](http://git-scm.com/downloads) go to **/d/tbuild** and run
@ -12,9 +38,9 @@ By git in [Git Bash](http://git-scm.com/downloads) go to **/d/tbuild** and r
or download in ZIP and extract to **D:\TBuild\**, rename **tdesktop-master** to **tdesktop** to have **D:\TBuild\tdesktop\Telegram.sln** solution or download in ZIP and extract to **D:\TBuild\**, rename **tdesktop-master** to **tdesktop** to have **D:\TBuild\tdesktop\Telegram.sln** solution
###Prepare libraries ## Prepare libraries
####OpenSSL ### OpenSSL
Open **VS2015 x86 Native Tools Command Prompt.bat** (should be in **Start Menu > Programs > Visual Studio 2015** menu folder), go to **D:\\TBuild\\Libraries** and run Open **VS2015 x86 Native Tools Command Prompt.bat** (should be in **Start Menu > Programs > Visual Studio 2015** menu folder), go to **D:\\TBuild\\Libraries** and run
@ -35,13 +61,13 @@ Open **VS2015 x86 Native Tools Command Prompt.bat** (should be in **Start Menu >
nmake -f ms\nt.mak install nmake -f ms\nt.mak install
####LZMA SDK 9.20 ### 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) 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** Extract to **D:\TBuild\Libraries**
#####Building library #### Building library
* Open in VS2015 **D:\TBuild\Libraries\lzma\C\Util\LzmaLib\LzmaLib.dsw** > One-way upgrade **OK** * Open in VS2015 **D:\TBuild\Libraries\lzma\C\Util\LzmaLib\LzmaLib.dsw** > One-way upgrade **OK**
* For **Debug** and **Release** configurations * For **Debug** and **Release** configurations
@ -53,13 +79,13 @@ Extract to **D:\TBuild\Libraries**
* Build Debug configuration * Build Debug configuration
* Build Release configuration * Build Release configuration
####zlib 1.2.8 ### zlib 1.2.8
http://www.zlib.net/ > Download [**zlib source code, version 1.2.8, zipfile format**](http://zlib.net/zlib128.zip) http://www.zlib.net/ > Download [**zlib source code, version 1.2.8, zipfile format**](http://zlib.net/zlib128.zip)
Extract to **D:\\TBuild\\Libraries\\** Extract to **D:\\TBuild\\Libraries\\**
#####Building library #### Building library
* Open in VS2015 **D:\TBuild\Libraries\zlib-1.2.8\contrib\vstudio\vc11\zlibvc.sln** > One-way upgrade **OK** * Open in VS2015 **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 * We are interested only in **zlibstat** project, but it depends on some custom pre-build step, so build all
@ -70,7 +96,7 @@ Extract to **D:\\TBuild\\Libraries\\**
* Build Solution for Debug configuration only **zlibstat** project builds successfully * Build Solution for Debug configuration only **zlibstat** project builds successfully
* Build Solution for Release configuration only **zlibstat** project builds successfully * Build Solution for Release configuration only **zlibstat** project builds successfully
####libexif 0.6.20 ### 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 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
@ -78,13 +104,13 @@ Get sources from https://github.com/telegramdesktop/libexif-0.6.20, by git i
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 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 #### Building library
* Open in VS2015 **D:\TBuild\Libraries\libexif-0.6.20\win32\lib_exif.sln** * Open in VS2015 **D:\TBuild\Libraries\libexif-0.6.20\win32\lib_exif.sln**
* Build Debug configuration * Build Debug configuration
* Build Release configuration * Build Release configuration
####OpenAL Soft, slightly patched ### OpenAL Soft, slightly patched
Open **VS2015 x86 Native Tools Command Prompt.bat** (should be in **Start Menu > Programs > Visual Studio 2015** menu folder), go to **D:\\TBuild\\Libraries** and run Open **VS2015 x86 Native Tools Command Prompt.bat** (should be in **Start Menu > Programs > Visual Studio 2015** menu folder), go to **D:\\TBuild\\Libraries** and run
@ -93,7 +119,7 @@ Open **VS2015 x86 Native Tools Command Prompt.bat** (should be in **Start Menu >
git checkout 90349b38 git checkout 90349b38
git apply ./../../tdesktop/Telegram/Patches/openal.diff git apply ./../../tdesktop/Telegram/Patches/openal.diff
#####Building library #### Building library
* Install [CMake](http://www.cmake.org/) * Install [CMake](http://www.cmake.org/)
* Open **VS2015 x86 Native Tools Command Prompt.bat** (should be in **Start Menu > Programs > Visual Studio 2015** menu folder), go to **D:\TBuild\Libraries\openal-soft\build\** and run * Open **VS2015 x86 Native Tools Command Prompt.bat** (should be in **Start Menu > Programs > Visual Studio 2015** menu folder), go to **D:\TBuild\Libraries\openal-soft\build\** and run
@ -102,7 +128,7 @@ Open **VS2015 x86 Native Tools Command Prompt.bat** (should be in **Start Menu >
* Open in VS2015 **D:\TBuild\Libraries\openal-soft\build\OpenAL.sln** and build Debug and Release configurations * Open in VS2015 **D:\TBuild\Libraries\openal-soft\build\OpenAL.sln** and build Debug and Release configurations
####Opus codec ### Opus codec
Get sources by git in [Git Bash](http://git-scm.com/downloads) go to **/d/tbuild/libraries** and run Get sources by git in [Git Bash](http://git-scm.com/downloads) go to **/d/tbuild/libraries** and run
@ -110,13 +136,13 @@ Get sources by git in [Git Bash](http://git-scm.com/downloads) go to **/d/tb
to have **D:\TBuild\Libraries\opus\win32** to have **D:\TBuild\Libraries\opus\win32**
#####Building libraries #### Building libraries
* Open in VS2015 **D:\TBuild\Libraries\opus\win32\VS2010\opus.sln** * Open in VS2015 **D:\TBuild\Libraries\opus\win32\VS2010\opus.sln**
* Build Debug configuration * Build Debug configuration
* Build Release configuration (it will be required in **FFmpeg** build!) * Build Release configuration (it will be required in **FFmpeg** build!)
####FFmpeg ### FFmpeg
Open **VS2015 x86 Native Tools Command Prompt.bat** (should be in **Start Menu > Programs > Visual Studio 2015** menu folder) and run Open **VS2015 x86 Native Tools Command Prompt.bat** (should be in **Start Menu > Programs > Visual Studio 2015** menu folder) and run
@ -126,7 +152,7 @@ Open **VS2015 x86 Native Tools Command Prompt.bat** (should be in **Start Menu >
http://msys2.github.io/ > Download [msys2-x86_64-20150512.exe](http://sourceforge.net/projects/msys2/files/Base/x86_64/msys2-x86_64-20150512.exe/download) and install to **D:\\msys64** http://msys2.github.io/ > Download [msys2-x86_64-20150512.exe](http://sourceforge.net/projects/msys2/files/Base/x86_64/msys2-x86_64-20150512.exe/download) and install to **D:\\msys64**
#####Building libraries #### Building libraries
Download [yasm for Win64](http://www.tortall.net/projects/yasm/releases/yasm-1.3.0-win64.exe) from http://yasm.tortall.net/Download.html, rename **yasm-1.3.0-win64.exe** to **yasm.exe** and place it to your Visual C++ **bin** directory, like **\\Program Files (x86)\\Microsoft Visual Studio 14\\VC\\bin\\** Download [yasm for Win64](http://www.tortall.net/projects/yasm/releases/yasm-1.3.0-win64.exe) from http://yasm.tortall.net/Download.html, rename **yasm-1.3.0-win64.exe** to **yasm.exe** and place it to your Visual C++ **bin** directory, like **\\Program Files (x86)\\Microsoft Visual Studio 14\\VC\\bin\\**
@ -148,7 +174,7 @@ Open **VS2015 x86 Native Tools Command Prompt.bat** (should be in **Start Menu >
make make
make install make install
####Qt 5.6.0, slightly patched ### Qt 5.6.0, slightly patched
* 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) * 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 **VS2015 x86 Native Tools Command Prompt.bat** (should be in **Start Menu > Programs > Visual Studio 2015** menu folder) * Open **VS2015 x86 Native Tools Command Prompt.bat** (should be in **Start Menu > Programs > Visual Studio 2015** menu folder)
@ -168,17 +194,17 @@ and run
cd qtimageformats && git checkout v5.6.0 && cd .. cd qtimageformats && git checkout v5.6.0 && cd ..
cd qtbase && git checkout v5.6.0 && cd .. cd qtbase && git checkout v5.6.0 && cd ..
#####Apply the patch #### Apply the patch
cd qtbase && git apply ../../../tdesktop/Telegram/Patches/qtbase_5_6_0.diff && cd .. cd qtbase && git apply ../../../tdesktop/Telegram/Patches/qtbase_5_6_0.diff && cd ..
#####Install Windows SDKs #### Install Windows SDKs
If you didn't install Windows SDKs before, you need to install them now. To install the SDKs just open Telegram solution at **D:\TBuild\tdesktop\Telegram.sln** and on startup Visual Studio 2015 will popup dialog box and ask to download and install extra components (including Windows 7 SDK). If you didn't install Windows SDKs before, you need to install them now. To install the SDKs just open Telegram solution at **D:\TBuild\tdesktop\Telegram.sln** and on startup Visual Studio 2015 will popup dialog box and ask to download and install extra components (including Windows 7 SDK).
If you already have Windows SDKs then find the library folder and correct it at configure's command below (like **C:\Program Files (x86)\Windows Kits\8.0\Lib\win8\um\x86**). If you already have Windows SDKs then find the library folder and correct it at configure's command below (like **C:\Program Files (x86)\Windows Kits\8.0\Lib\win8\um\x86**).
#####Building library #### Building library
configure -debug-and-release -force-debug-info -opensource -confirm-license -static -I "D:\TBuild\Libraries\openssl\Release\include" -L "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Lib" -l Gdi32 -no-opengl -openssl-linked OPENSSL_LIBS_DEBUG="D:\TBuild\Libraries\openssl_debug\Debug\lib\ssleay32.lib D:\TBuild\Libraries\openssl_debug\Debug\lib\libeay32.lib" OPENSSL_LIBS_RELEASE="D:\TBuild\Libraries\openssl\Release\lib\ssleay32.lib D:\TBuild\Libraries\openssl\Release\lib\libeay32.lib" -mp -nomake examples -nomake tests -platform win32-msvc2015 configure -debug-and-release -force-debug-info -opensource -confirm-license -static -I "D:\TBuild\Libraries\openssl\Release\include" -L "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Lib" -l Gdi32 -no-opengl -openssl-linked OPENSSL_LIBS_DEBUG="D:\TBuild\Libraries\openssl_debug\Debug\lib\ssleay32.lib D:\TBuild\Libraries\openssl_debug\Debug\lib\libeay32.lib" OPENSSL_LIBS_RELEASE="D:\TBuild\Libraries\openssl\Release\lib\ssleay32.lib D:\TBuild\Libraries\openssl\Release\lib\libeay32.lib" -mp -nomake examples -nomake tests -platform win32-msvc2015
nmake nmake
@ -186,15 +212,19 @@ If you already have Windows SDKs then find the library folder and correct it at
building (**nmake** command) will take really long time. building (**nmake** command) will take really long time.
####Qt5Package ### Qt5Package
https://visualstudiogallery.msdn.microsoft.com/c89ff880-8509-47a4-a262-e4fa07168408 https://visualstudiogallery.msdn.microsoft.com/c89ff880-8509-47a4-a262-e4fa07168408
Download, close all VS2015 instances and install for VS2015 Download, close all VS2015 instances and install for VS2015
####Google Breakpad ### Google Breakpad
* Install Python 2.7.11 from https://www.python.org/downloads/release/python-2711/ > [**Windows x86 MSI installer**](https://www.python.org/ftp/python/2.7.11/python-2.7.11.msi) Breakpad is a set of client and server components which implement a crash-reporting system.
#### Install
* Install Python 2.7.12 from https://www.python.org/downloads/release/python-2712/ > [**Windows x86 MSI installer**](https://www.python.org/ftp/python/2.7.12/python-2.7.12.msi). Make sure that python is added to your `PATH` (there is an option for this in the python installer).
* Open **VS2015 x86 Native Tools Command Prompt.bat** (should be in **Start Menu > Programs > Visual Studio 2015** menu folder) * Open **VS2015 x86 Native Tools Command Prompt.bat** (should be in **Start Menu > Programs > Visual Studio 2015** menu folder)
There go to Libraries directory There go to Libraries directory
@ -204,19 +234,18 @@ There go to Libraries directory
and run and run
set PATH=C:\Python27;%PATH%
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
cd depot_tools cd depot_tools
gclient config "https://chromium.googlesource.com/breakpad/breakpad.git"
gclient sync gclient sync
cd .. cd ..
md breakpad md breakpad && cd breakpad
cd breakpad
..\depot_tools\fetch breakpad ..\depot_tools\fetch breakpad
..\depot_tools\gclient sync ..\depot_tools\gclient sync
xcopy src\src\* src /s /i
There's now a src folder within a src folder: D:\TBuild\Libraries\breakpad\src\src. Telegram only expects one src folder. Either via the command line or File Explorer, rename the top-level src folder and move the inner src folder one level up. This way, what was once breakpad\src\src\client is now breakpad\src\client, etc.
#####Building library #### Build
* Open in VS2015 **D:\TBuild\Libraries\breakpad\src\client\windows\breakpad_client.sln** * Open in VS2015 **D:\TBuild\Libraries\breakpad\src\client\windows\breakpad_client.sln**
* Change "Treat WChar_t As Built in Type" to "No" in all projects & configurations * Change "Treat WChar_t As Built in Type" to "No" in all projects & configurations
@ -224,7 +253,7 @@ There's now a src folder within a src folder: D:\TBuild\Libraries\breakpad\src\s
* Build Debug configuration * Build Debug configuration
* Build Release configuration * Build Release configuration
###Building Telegram Desktop ## Building Telegram Desktop
* Launch VS2015 for configuring Qt5Package * Launch VS2015 for configuring Qt5Package
* QT5 > Qt Options > Add * QT5 > Qt Options > Add

View file

@ -72,7 +72,7 @@ Building
cd "$srcdir/Libraries/QtStatic" cd "$srcdir/Libraries/QtStatic"
./configure -prefix "$srcdir/qt" -release -opensource -confirm-license -qt-zlib \ ./configure -prefix "$srcdir/qt" -release -opensource -confirm-license -qt-zlib \
-qt-libpng -qt-libjpeg -qt-freetype -qt-harfbuzz -qt-pcre -qt-xcb \ -qt-libpng -qt-libjpeg -qt-freetype -qt-harfbuzz -qt-pcre -qt-xcb \
-qt-xkbcommon-x11 -no-opengl -static -nomake examples -nomake tests -qt-xkbcommon-x11 -no-opengl -no-gtkstyle -static -nomake examples -nomake tests
make module-qtbase module-qtimageformats make module-qtbase module-qtimageformats
make module-qtbase-install_subtargets module-qtimageformats-install_subtargets make module-qtbase-install_subtargets module-qtimageformats-install_subtargets

View file

@ -147,7 +147,7 @@ Install some packages for Qt (see **/home/user/TBuild/Libraries/qt5_6_0/qtbase/s
In Terminal go to **/home/user/TBuild/Libraries/qt5_6_0** and there run In Terminal go to **/home/user/TBuild/Libraries/qt5_6_0** and there run
OPENSSL_LIBS='-L/usr/local/ssl/lib -lssl -lcrypto' ./configure -prefix "/usr/local/tdesktop/Qt-5.6.0" -release -force-debug-info -opensource -confirm-license -qt-zlib -qt-libpng -qt-libjpeg -qt-freetype -qt-harfbuzz -qt-pcre -qt-xcb -qt-xkbcommon-x11 -no-opengl -static -openssl-linked -nomake examples -nomake tests OPENSSL_LIBS='-L/usr/local/ssl/lib -lssl -lcrypto' ./configure -prefix "/usr/local/tdesktop/Qt-5.6.0" -release -force-debug-info -opensource -confirm-license -qt-zlib -qt-libpng -qt-libjpeg -qt-freetype -qt-harfbuzz -qt-pcre -qt-xcb -qt-xkbcommon-x11 -no-opengl -no-gtkstyle -static -openssl-linked -nomake examples -nomake tests
make -j4 make -j4
sudo make install sudo make install