mirror of
https://github.com/telegramdesktop/tdesktop
synced 2024-12-15 02:44:45 +00:00
youtube and instagram preview display added (instead of messages with only one such link)
This commit is contained in:
parent
e0ef1d434d
commit
a75f57beb8
2
MSVC.md
2
MSVC.md
@ -137,7 +137,7 @@ There go to Qt directory
|
||||
|
||||
and after that run configure
|
||||
|
||||
configure -debug-and-release -opensource -confirm-license -static -opengl desktop -mp -nomake examples -platform win32-msvc2013
|
||||
configure -debug-and-release -opensource -confirm-license -static -I "D:\TBuild\Libraries\OpenSSL-Win32\include" -L "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Lib" -l Gdi32 -opengl desktop -openssl-linked OPENSSL_LIBS_DEBUG="D:\TBuild\Libraries\OpenSSL-Win32\lib\VC\static\ssleay32MTd.lib D:\TBuild\Libraries\OpenSSL-Win32\lib\VC\static\libeay32MTd.lib" OPENSSL_LIBS_RELEASE="D:\TBuild\Libraries\OpenSSL-Win32\lib\VC\static\ssleay32MT.lib D:\TBuild\Libraries\OpenSSL-Win32\lib\VC\static\libeay32MT.lib" -mp -nomake examples -platform win32-msvc2013
|
||||
|
||||
to configure Qt build. After configuration is complete run
|
||||
|
||||
|
@ -1,6 +1,46 @@
|
||||
@echo OFF
|
||||
|
||||
set "AppVersionStr=0.6.7"
|
||||
echo.
|
||||
echo Preparing version %AppVersionStr%..
|
||||
echo.
|
||||
|
||||
set "PATH=%PATH%;C:\Program Files\7-Zip;C:\Program Files (x86)\Inno Setup 5"
|
||||
cd ..\Win32\Deploy
|
||||
call ..\..\..\TelegramPrivate\Sign.bat tsetup.0.6.7.exe
|
||||
|
||||
call ..\..\..\TelegramPrivate\Sign.bat Telegram.exe
|
||||
if %errorlevel% neq 0 goto error1
|
||||
|
||||
call ..\..\..\TelegramPrivate\Sign.bat Updater.exe
|
||||
if %errorlevel% neq 0 goto error1
|
||||
|
||||
iscc ..\..\Telegram\Setup.iss
|
||||
if %errorlevel% neq 0 goto error1
|
||||
|
||||
call ..\..\..\TelegramPrivate\Sign.bat tsetup.%AppVersionStr%.exe
|
||||
if %errorlevel% neq 0 goto error1
|
||||
|
||||
call Prepare.exe -path Telegram.exe -path Updater.exe
|
||||
mkdir deploy\0.6.7\Telegram
|
||||
move deploy\0.6.7\Telegram.exe deploy\0.6.7\Telegram\
|
||||
if %errorlevel% neq 0 goto error1
|
||||
|
||||
cd deploy\%AppVersionStr%
|
||||
mkdir Telegram
|
||||
move Telegram.exe Telegram\
|
||||
7z a -mx9 tportable.%AppVersionStr%.zip Telegram\
|
||||
if %errorlevel% neq 0 goto error2
|
||||
|
||||
echo .
|
||||
echo Version %AppVersionStr% is ready for deploy!
|
||||
echo .
|
||||
|
||||
cd ..\..\..\..\Telegram
|
||||
goto eof
|
||||
|
||||
:error2
|
||||
cd ..\..
|
||||
:error1
|
||||
cd ..\..\Telegram
|
||||
echo ERROR occured!
|
||||
exit /b %errorlevel%
|
||||
|
||||
:eof
|
||||
|
@ -1635,3 +1635,6 @@ usernameDone: flatButton(btnSelectDone) {
|
||||
usernameCancel: flatButton(btnSelectCancel) {
|
||||
width: 167px;
|
||||
}
|
||||
|
||||
youtubeIcon: sprite(336px, 221px, 60px, 60px);
|
||||
instagramIcon: sprite(336px, 283px, 60px, 60px);
|
||||
|
@ -1,4 +0,0 @@
|
||||
cd ..\Win32\Deploy
|
||||
call ..\..\..\TelegramPrivate\Sign.bat Telegram.exe
|
||||
call ..\..\..\TelegramPrivate\Sign.bat Updater.exe
|
||||
cd ..\..\Telegram
|
@ -94,6 +94,5 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
int res = prepare(f, paths);
|
||||
system("PAUSE");
|
||||
return res;
|
||||
}
|
||||
|
@ -43,6 +43,9 @@ namespace {
|
||||
typedef QHash<AudioId, AudioData*> AudiosData;
|
||||
AudiosData audiosData;
|
||||
|
||||
typedef QHash<QString, ImageLinkData*> ImageLinksData;
|
||||
ImageLinksData imageLinksData;
|
||||
|
||||
typedef QHash<DocumentId, DocumentData*> DocumentsData;
|
||||
DocumentsData documentsData;
|
||||
|
||||
@ -561,13 +564,20 @@ namespace App {
|
||||
}
|
||||
|
||||
void feedWereDeleted(const QVector<MTPint> &msgsIds) {
|
||||
bool resized = false;
|
||||
for (QVector<MTPint>::const_iterator i = msgsIds.cbegin(), e = msgsIds.cend(); i != e; ++i) {
|
||||
MsgsData::const_iterator j = msgsData.constFind(i->v);
|
||||
if (j != msgsData.cend()) {
|
||||
History *h = (*j)->history();
|
||||
(*j)->destroy();
|
||||
if (App::main() && h->peer == App::main()->peer()) {
|
||||
resized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (resized) {
|
||||
App::main()->itemResized(0);
|
||||
}
|
||||
}
|
||||
|
||||
void feedUserLinks(const MTPVector<MTPcontacts_Link> &links) {
|
||||
@ -911,14 +921,6 @@ namespace App {
|
||||
return result;
|
||||
}
|
||||
|
||||
void forgetPhotos() {
|
||||
lastPhotos.clear();
|
||||
lastPhotosMap.clear();
|
||||
for (PhotosData::const_iterator i = photosData.cbegin(), e = photosData.cend(); i != e; ++i) {
|
||||
i.value()->forget();
|
||||
}
|
||||
}
|
||||
|
||||
VideoData *video(const VideoId &video, VideoData *convert, const uint64 &access, int32 user, int32 date, int32 duration, int32 w, int32 h, const ImagePtr &thumb, int32 dc, int32 size) {
|
||||
if (convert) {
|
||||
if (convert->id != video) {
|
||||
@ -967,12 +969,6 @@ namespace App {
|
||||
return result;
|
||||
}
|
||||
|
||||
void forgetVideos() {
|
||||
for (VideosData::const_iterator i = videosData.cbegin(), e = videosData.cend(); i != e; ++i) {
|
||||
i.value()->forget();
|
||||
}
|
||||
}
|
||||
|
||||
AudioData *audio(const AudioId &audio, AudioData *convert, const uint64 &access, int32 user, int32 date, int32 duration, int32 dc, int32 size) {
|
||||
if (convert) {
|
||||
if (convert->id != audio) {
|
||||
@ -1015,12 +1011,6 @@ namespace App {
|
||||
return result;
|
||||
}
|
||||
|
||||
void forgetAudios() {
|
||||
for (AudiosData::const_iterator i = audiosData.cbegin(), e = audiosData.cend(); i != e; ++i) {
|
||||
i.value()->forget();
|
||||
}
|
||||
}
|
||||
|
||||
DocumentData *document(const DocumentId &document, DocumentData *convert, const uint64 &access, int32 user, int32 date, const QString &name, const QString &mime, const ImagePtr &thumb, int32 dc, int32 size) {
|
||||
if (convert) {
|
||||
if (convert->id != document) {
|
||||
@ -1067,10 +1057,38 @@ namespace App {
|
||||
return result;
|
||||
}
|
||||
|
||||
void forgetDocuments() {
|
||||
ImageLinkData *imageLink(const QString &imageLink, ImageLinkType type, const QString &url) {
|
||||
ImageLinksData::const_iterator i = imageLinksData.constFind(imageLink);
|
||||
ImageLinkData *result;
|
||||
if (i == imageLinksData.cend()) {
|
||||
result = new ImageLinkData(imageLink);
|
||||
imageLinksData.insert(imageLink, result);
|
||||
result->type = type;
|
||||
result->openl = TextLinkPtr(new TextLink(url));
|
||||
} else {
|
||||
result = i.value();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void forgetMedia() {
|
||||
lastPhotos.clear();
|
||||
lastPhotosMap.clear();
|
||||
for (PhotosData::const_iterator i = photosData.cbegin(), e = photosData.cend(); i != e; ++i) {
|
||||
i.value()->forget();
|
||||
}
|
||||
for (VideosData::const_iterator i = videosData.cbegin(), e = videosData.cend(); i != e; ++i) {
|
||||
i.value()->forget();
|
||||
}
|
||||
for (AudiosData::const_iterator i = audiosData.cbegin(), e = audiosData.cend(); i != e; ++i) {
|
||||
i.value()->forget();
|
||||
}
|
||||
for (DocumentsData::const_iterator i = documentsData.cbegin(), e = documentsData.cend(); i != e; ++i) {
|
||||
i.value()->forget();
|
||||
}
|
||||
for (ImageLinksData::const_iterator i = imageLinksData.cbegin(), e = imageLinksData.cend(); i != e; ++i) {
|
||||
i.value()->thumb->forget();
|
||||
}
|
||||
}
|
||||
|
||||
MTPPhoto photoFromUserPhoto(MTPint userId, MTPint date, const MTPUserProfilePhoto &photo) {
|
||||
@ -1854,10 +1872,7 @@ namespace App {
|
||||
void checkImageCacheSize() {
|
||||
int64 nowImageCacheSize = imageCacheSize();
|
||||
if (nowImageCacheSize > serviceImageCacheSize + MemoryForImageCache) {
|
||||
App::forgetPhotos();
|
||||
App::forgetVideos();
|
||||
App::forgetAudios();
|
||||
App::forgetDocuments();
|
||||
App::forgetMedia();
|
||||
serviceImageCacheSize = imageCacheSize();
|
||||
}
|
||||
}
|
||||
|
@ -102,13 +102,11 @@ namespace App {
|
||||
ChatData *chat(int32 chat);
|
||||
QString peerName(const PeerData *peer, bool forDialogs = false);
|
||||
PhotoData *photo(const PhotoId &photo, PhotoData *convert = 0, const uint64 &access = 0, int32 user = 0, int32 date = 0, const ImagePtr &thumb = ImagePtr(), const ImagePtr &medium = ImagePtr(), const ImagePtr &full = ImagePtr());
|
||||
void forgetPhotos();
|
||||
VideoData *video(const VideoId &video, VideoData *convert = 0, const uint64 &access = 0, int32 user = 0, int32 date = 0, int32 duration = 0, int32 w = 0, int32 h = 0, const ImagePtr &thumb = ImagePtr(), int32 dc = 0, int32 size = 0);
|
||||
void forgetVideos();
|
||||
AudioData *audio(const AudioId &audio, AudioData *convert = 0, const uint64 &access = 0, int32 user = 0, int32 date = 0, int32 duration = 0, int32 dc = 0, int32 size = 0);
|
||||
void forgetAudios();
|
||||
DocumentData *document(const DocumentId &document, DocumentData *convert = 0, const uint64 &access = 0, int32 user = 0, int32 date = 0, const QString &name = QString(), const QString &mime = QString(), const ImagePtr &thumb = ImagePtr(), int32 dc = 0, int32 size = 0);
|
||||
void forgetDocuments();
|
||||
ImageLinkData *imageLink(const QString &imageLink, ImageLinkType type = InvalidImageLink, const QString &url = QString());
|
||||
void forgetMedia();
|
||||
|
||||
MTPPhoto photoFromUserPhoto(MTPint userId, MTPint date, const MTPUserProfilePhoto &photo);
|
||||
|
||||
|
@ -633,6 +633,7 @@ void Application::startApp() {
|
||||
MTP::setStateChangedHandler(mtpStateChanged);
|
||||
MTP::setSessionResetHandler(mtpSessionReset);
|
||||
|
||||
initImageLinkManager();
|
||||
App::initMedia();
|
||||
|
||||
if (MTP::authedId()) {
|
||||
@ -746,6 +747,7 @@ Application::~Application() {
|
||||
socket.close();
|
||||
closeApplication();
|
||||
App::deinitMedia();
|
||||
deinitImageLinkManager();
|
||||
mainApp = 0;
|
||||
delete updateReply;
|
||||
delete ::uploader;
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 55 KiB |
Binary file not shown.
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 96 KiB |
@ -205,6 +205,7 @@ void ConnectionBox::onSave() {
|
||||
}
|
||||
App::writeConfig();
|
||||
MTP::restart();
|
||||
reinitImageLinkManager();
|
||||
emit closed();
|
||||
}
|
||||
|
||||
|
@ -100,6 +100,7 @@ enum {
|
||||
UsernameCheckTimeout = 200,
|
||||
|
||||
MaxMessageSize = 4096,
|
||||
MaxHttpRedirects = 5, // when getting external data/images
|
||||
};
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
|
@ -199,7 +199,7 @@ QString FlatTextarea::getText(int32 start, int32 end) const {
|
||||
QString t(fragment.text());
|
||||
if (!full) {
|
||||
if (p < start) {
|
||||
t = t.mid(start - p, end - start - p);
|
||||
t = t.mid(start - p, end - start);
|
||||
} else if (e > end) {
|
||||
t = t.mid(0, end - p);
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ const QPixmap &Image::pixBlurred(int32 w, int32 h) const {
|
||||
w *= cIntRetinaFactor();
|
||||
h *= cIntRetinaFactor();
|
||||
}
|
||||
uint64 k = 0x8000000000000000L | (uint64(w) << 32) | uint64(h);
|
||||
uint64 k = 0x8000000000000000LL | (uint64(w) << 32) | uint64(h);
|
||||
Sizes::const_iterator i = _sizesCache.constFind(k);
|
||||
if (i == _sizesCache.cend()) {
|
||||
QPixmap p(pixBlurredNoCache(w, h));
|
||||
@ -101,6 +101,58 @@ const QPixmap &Image::pixBlurred(int32 w, int32 h) const {
|
||||
return i.value();
|
||||
}
|
||||
|
||||
const QPixmap &Image::pixSingle(int32 w, int32 h) const {
|
||||
restore();
|
||||
checkload();
|
||||
|
||||
if (w <= 0 || !width() || !height()) {
|
||||
w = width() * cIntRetinaFactor();
|
||||
} else if (cRetina()) {
|
||||
w *= cIntRetinaFactor();
|
||||
h *= cIntRetinaFactor();
|
||||
}
|
||||
uint64 k = 0LL;
|
||||
Sizes::const_iterator i = _sizesCache.constFind(k);
|
||||
if (i == _sizesCache.cend() || i->width() != w || h && i->height() != h) {
|
||||
if (i != _sizesCache.cend()) {
|
||||
globalAquiredSize -= int64(i->width()) * i->height() * 4;
|
||||
}
|
||||
QPixmap p(pixNoCache(w, h, true));
|
||||
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
|
||||
i = _sizesCache.insert(k, p);
|
||||
if (!p.isNull()) {
|
||||
globalAquiredSize += int64(p.width()) * p.height() * 4;
|
||||
}
|
||||
}
|
||||
return i.value();
|
||||
}
|
||||
|
||||
const QPixmap &Image::pixBlurredSingle(int32 w, int32 h) const {
|
||||
restore();
|
||||
checkload();
|
||||
|
||||
if (w <= 0 || !width() || !height()) {
|
||||
w = width() * cIntRetinaFactor();
|
||||
} else if (cRetina()) {
|
||||
w *= cIntRetinaFactor();
|
||||
h *= cIntRetinaFactor();
|
||||
}
|
||||
uint64 k = 0x8000000000000000LL | 0LL;
|
||||
Sizes::const_iterator i = _sizesCache.constFind(k);
|
||||
if (i == _sizesCache.cend() || i->width() != w || h && i->height() != h) {
|
||||
if (i != _sizesCache.cend()) {
|
||||
globalAquiredSize -= int64(i->width()) * i->height() * 4;
|
||||
}
|
||||
QPixmap p(pixBlurredNoCache(w, h));
|
||||
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
|
||||
i = _sizesCache.insert(k, p);
|
||||
if (!p.isNull()) {
|
||||
globalAquiredSize += int64(p.width()) * p.height() * 4;
|
||||
}
|
||||
}
|
||||
return i.value();
|
||||
}
|
||||
|
||||
namespace {
|
||||
static inline uint64 _blurGetColors(const uchar *p) {
|
||||
return p[0] + (p[1] << 16) + ((uint64)p[2] << 32);
|
||||
|
@ -34,6 +34,8 @@ public:
|
||||
}
|
||||
const QPixmap &pix(int32 w = 0, int32 h = 0) const;
|
||||
const QPixmap &pixBlurred(int32 w = 0, int32 h = 0) const;
|
||||
const QPixmap &pixSingle(int32 w = 0, int32 h = 0) const;
|
||||
const QPixmap &pixBlurredSingle(int32 w = 0, int32 h = 0) const;
|
||||
QPixmap pixNoCache(int32 w = 0, int32 h = 0, bool smooth = false) const;
|
||||
QPixmap pixBlurredNoCache(int32 w, int32 h = 0) const;
|
||||
|
||||
|
@ -2076,33 +2076,49 @@ void HistoryPhoto::init() {
|
||||
}
|
||||
|
||||
void HistoryPhoto::initDimensions(const HistoryItem *parent) {
|
||||
int32 tw = data->full->width(), th = data->full->height();
|
||||
int32 tw = convertScale(data->full->width()), th = convertScale(data->full->height());
|
||||
if (!tw || !th) {
|
||||
tw = th = 1;
|
||||
}
|
||||
int32 thumbw = st::msgMinWidth + st::msgPadding.left() + st::msgPadding.right() - 2, maxthumbh = qRound(1.5 * thumbw);
|
||||
if (data->full->width() < thumbw) {
|
||||
thumbw = (data->full->width() > st::minPhotoWidth) ? data->full->width() : st::minPhotoWidth;
|
||||
}
|
||||
if (!w) {
|
||||
w = thumbw;
|
||||
}
|
||||
int32 thumbh = qRound(th * float64(w) / tw);
|
||||
int32 thumbw = qMax(tw, int32(st::minPhotoWidth)), maxthumbh = thumbw;
|
||||
int32 thumbh = qRound(th * float64(thumbw) / tw);
|
||||
if (thumbh > maxthumbh) {
|
||||
w = qRound(w * float64(maxthumbh) / thumbh);
|
||||
thumbw = qRound(thumbw * float64(maxthumbh) / thumbh);
|
||||
thumbh = maxthumbh;
|
||||
if (w < st::minPhotoWidth) {
|
||||
w = st::minPhotoWidth;
|
||||
if (thumbw < st::minPhotoWidth) {
|
||||
thumbw = st::minPhotoWidth;
|
||||
}
|
||||
}
|
||||
if (thumbh < st::minPhotoHeight) {
|
||||
thumbh = st::minPhotoHeight;
|
||||
}
|
||||
if (!w) {
|
||||
w = thumbw;
|
||||
}
|
||||
_maxw = w;
|
||||
_height = _minh = thumbh;
|
||||
}
|
||||
|
||||
int32 HistoryPhoto::resize(int32 nwidth, bool dontRecountText, const HistoryItem *parent) {
|
||||
int32 HistoryPhoto::resize(int32 width, bool dontRecountText, const HistoryItem *parent) {
|
||||
w = width;
|
||||
|
||||
int32 tw = convertScale(data->full->width()), th = convertScale(data->full->height());
|
||||
_height = th;
|
||||
if (tw > w) {
|
||||
_height = (w * _height / tw);
|
||||
} else {
|
||||
w = tw;
|
||||
}
|
||||
if (_height > width) {
|
||||
w = (w * width) / _height;
|
||||
_height = width;
|
||||
}
|
||||
if (w < st::minPhotoWidth) {
|
||||
w = st::minPhotoWidth;
|
||||
}
|
||||
if (_height < st::minPhotoHeight) {
|
||||
_height = st::minPhotoHeight;
|
||||
}
|
||||
return _height;
|
||||
}
|
||||
|
||||
@ -2111,12 +2127,12 @@ const QString HistoryPhoto::inDialogsText() const {
|
||||
}
|
||||
|
||||
bool HistoryPhoto::hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width) const {
|
||||
if (width < 0) width = _maxw;
|
||||
if (width < 0) width = w;
|
||||
return (x >= 0 && y >= 0 && x < width && y < _height);
|
||||
}
|
||||
|
||||
TextLinkPtr HistoryPhoto::getLink(int32 x, int32 y, const HistoryItem *parent, int32 width) const {
|
||||
if (width < 0) width = _maxw;
|
||||
if (width < 0) width = w;
|
||||
if (x >= 0 && y >= 0 && x < width && y < _height) {
|
||||
return openl;
|
||||
}
|
||||
@ -2128,50 +2144,48 @@ HistoryMedia *HistoryPhoto::clone() const {
|
||||
}
|
||||
|
||||
void HistoryPhoto::draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width) const {
|
||||
if (width < 0) width = _maxw;
|
||||
if (width < 0) width = w;
|
||||
data->full->load(false, false);
|
||||
bool out = parent->out();
|
||||
if (parent != App::contextItem() || /*App::wnd()->photoShown() != data*/ true) {
|
||||
bool full = data->full->loaded();
|
||||
QPixmap pix;
|
||||
if (full) {
|
||||
pix = data->full->pix(width);
|
||||
} else {
|
||||
pix = data->thumb->pixBlurred(width);
|
||||
}
|
||||
if (pix.height() >= _height * cIntRetinaFactor()) {
|
||||
p.drawPixmap(QPoint(0, 0), pix, QRect(0, (pix.height() - _height * cIntRetinaFactor()) / 2, width * cIntRetinaFactor(), _height * cIntRetinaFactor()));
|
||||
} else {
|
||||
int32 usewidth = (width * pix.height()) / (_height * cIntRetinaFactor());
|
||||
p.drawPixmap(QRect(0, 0, width, _height), pix, QRect((width - usewidth) * cIntRetinaFactor() / 2, 0, usewidth * cIntRetinaFactor(), pix.height()));
|
||||
}
|
||||
if (!full) {
|
||||
uint64 dt = itemAnimations().animate(parent, getms());
|
||||
int32 cnt = int32(st::photoLoaderCnt), period = int32(st::photoLoaderPeriod), t = dt % period, delta = int32(st::photoLoaderDelta);
|
||||
|
||||
int32 x = (width - st::photoLoader.width()) / 2, y = (_height - st::photoLoader.height()) / 2;
|
||||
p.fillRect(x, y, st::photoLoader.width(), st::photoLoader.height(), st::photoLoaderBg->b);
|
||||
x += (st::photoLoader.width() - cnt * st::photoLoaderPoint.width() - (cnt - 1) * st::photoLoaderSkip) / 2;
|
||||
y += (st::photoLoader.height() - st::photoLoaderPoint.height()) / 2;
|
||||
QColor c(st::white->c);
|
||||
QBrush b(c);
|
||||
for (int32 i = 0; i < cnt; ++i) {
|
||||
t -= delta;
|
||||
while (t < 0) t += period;
|
||||
|
||||
float64 alpha = (t >= st::photoLoaderDuration1 + st::photoLoaderDuration2) ? 0 : ((t > st::photoLoaderDuration1 ? ((st::photoLoaderDuration1 + st::photoLoaderDuration2 - t) / st::photoLoaderDuration2) : (t / st::photoLoaderDuration1)));
|
||||
c.setAlphaF(st::photoLoaderAlphaMin + alpha * (1 - st::photoLoaderAlphaMin));
|
||||
b.setColor(c);
|
||||
p.fillRect(x + i * (st::photoLoaderPoint.width() + st::photoLoaderSkip), y, st::photoLoaderPoint.width(), st::photoLoaderPoint.height(), b);
|
||||
}
|
||||
}
|
||||
|
||||
if (selected) {
|
||||
p.fillRect(0, 0, width, _height, textstyleCurrent()->selectOverlay->b);
|
||||
}
|
||||
style::color shadow(selected ? st::msgInSelectShadow : st::msgInShadow);
|
||||
p.fillRect(0, _height, width, st::msgShadow, shadow->b);
|
||||
bool full = data->full->loaded();
|
||||
QPixmap pix;
|
||||
if (full) {
|
||||
pix = data->full->pixSingle(width);
|
||||
} else {
|
||||
pix = data->thumb->pixBlurredSingle(width);
|
||||
}
|
||||
if (pix.height() >= _height * cIntRetinaFactor()) {
|
||||
p.drawPixmap(QPoint(0, 0), pix, QRect(0, (pix.height() - _height * cIntRetinaFactor()) / 2, width * cIntRetinaFactor(), _height * cIntRetinaFactor()));
|
||||
} else {
|
||||
int32 usewidth = (width * pix.height()) / (_height * cIntRetinaFactor());
|
||||
p.drawPixmap(QRect(0, 0, width, _height), pix, QRect((width - usewidth) * cIntRetinaFactor() / 2, 0, usewidth * cIntRetinaFactor(), pix.height()));
|
||||
}
|
||||
if (!full) {
|
||||
uint64 dt = itemAnimations().animate(parent, getms());
|
||||
int32 cnt = int32(st::photoLoaderCnt), period = int32(st::photoLoaderPeriod), t = dt % period, delta = int32(st::photoLoaderDelta);
|
||||
|
||||
int32 x = (width - st::photoLoader.width()) / 2, y = (_height - st::photoLoader.height()) / 2;
|
||||
p.fillRect(x, y, st::photoLoader.width(), st::photoLoader.height(), st::photoLoaderBg->b);
|
||||
x += (st::photoLoader.width() - cnt * st::photoLoaderPoint.width() - (cnt - 1) * st::photoLoaderSkip) / 2;
|
||||
y += (st::photoLoader.height() - st::photoLoaderPoint.height()) / 2;
|
||||
QColor c(st::white->c);
|
||||
QBrush b(c);
|
||||
for (int32 i = 0; i < cnt; ++i) {
|
||||
t -= delta;
|
||||
while (t < 0) t += period;
|
||||
|
||||
float64 alpha = (t >= st::photoLoaderDuration1 + st::photoLoaderDuration2) ? 0 : ((t > st::photoLoaderDuration1 ? ((st::photoLoaderDuration1 + st::photoLoaderDuration2 - t) / st::photoLoaderDuration2) : (t / st::photoLoaderDuration1)));
|
||||
c.setAlphaF(st::photoLoaderAlphaMin + alpha * (1 - st::photoLoaderAlphaMin));
|
||||
b.setColor(c);
|
||||
p.fillRect(x + i * (st::photoLoaderPoint.width() + st::photoLoaderSkip), y, st::photoLoaderPoint.width(), st::photoLoaderPoint.height(), b);
|
||||
}
|
||||
}
|
||||
|
||||
if (selected) {
|
||||
p.fillRect(0, 0, width, _height, textstyleCurrent()->selectOverlay->b);
|
||||
}
|
||||
style::color shadow(selected ? st::msgInSelectShadow : st::msgInShadow);
|
||||
p.fillRect(0, _height, width, st::msgShadow, shadow->b);
|
||||
|
||||
// date
|
||||
QString time(parent->time());
|
||||
@ -2290,8 +2304,8 @@ void HistoryVideo::unregItem(HistoryItem *item) {
|
||||
App::unregVideoItem(data, item);
|
||||
}
|
||||
|
||||
int32 HistoryVideo::resize(int32 nwidth, bool dontRecountText, const HistoryItem *parent) {
|
||||
w = nwidth;
|
||||
int32 HistoryVideo::resize(int32 width, bool dontRecountText, const HistoryItem *parent) {
|
||||
w = width;
|
||||
return _height;
|
||||
}
|
||||
|
||||
@ -2592,8 +2606,8 @@ void HistoryAudio::unregItem(HistoryItem *item) {
|
||||
App::unregAudioItem(data, item);
|
||||
}
|
||||
|
||||
int32 HistoryAudio::resize(int32 nwidth, bool dontRecountText, const HistoryItem *parent) {
|
||||
w = nwidth;
|
||||
int32 HistoryAudio::resize(int32 width, bool dontRecountText, const HistoryItem *parent) {
|
||||
w = width;
|
||||
return _height;
|
||||
}
|
||||
|
||||
@ -2940,8 +2954,8 @@ void HistoryContact::initDimensions(const HistoryItem *parent) {
|
||||
}
|
||||
}
|
||||
|
||||
int32 HistoryContact::resize(int32 nwidth, bool dontRecountText, const HistoryItem *parent) {
|
||||
w = nwidth;
|
||||
int32 HistoryContact::resize(int32 width, bool dontRecountText, const HistoryItem *parent) {
|
||||
w = width;
|
||||
return _height;
|
||||
}
|
||||
|
||||
@ -3046,6 +3060,498 @@ void HistoryContact::updateFrom(const MTPMessageMedia &media) {
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
QRegularExpression reYouTube1(qsl("^(https?://)?(www\\.)?youtube\\.com/watch\\?v=([a-z0-9_-]+)(&|$)"), QRegularExpression::CaseInsensitiveOption);
|
||||
QRegularExpression reYouTube2(qsl("^(https?://)?(www\\.)?youtu\\.be/([a-z0-9_-]+)(\\?|$)"), QRegularExpression::CaseInsensitiveOption);
|
||||
QRegularExpression reInstagram(qsl("^(https?://)?(www\\.)?instagram\\.com/p/([a-z0-9_-]+)(/|$)"), QRegularExpression::CaseInsensitiveOption);
|
||||
|
||||
ImageLinkManager manager;
|
||||
}
|
||||
|
||||
void ImageLinkManager::init() {
|
||||
if (manager) delete manager;
|
||||
manager = new QNetworkAccessManager();
|
||||
App::setProxySettings(*manager);
|
||||
void onFinished(QNetworkReply *reply);
|
||||
void onFailed(QNetworkReply *reply);
|
||||
connect(manager, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)), this, SLOT(onFailed(QNetworkReply*)));
|
||||
connect(manager, SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError>&errors)), this, SLOT(onFailed(QNetworkReply*)));
|
||||
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(onFinished(QNetworkReply*)));
|
||||
|
||||
if (black) delete black;
|
||||
QImage b(cIntRetinaFactor(), cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
|
||||
{
|
||||
QPainter p(&b);
|
||||
p.fillRect(QRect(0, 0, cIntRetinaFactor(), cIntRetinaFactor()), st::white->b);
|
||||
}
|
||||
QPixmap p = QPixmap::fromImage(b);
|
||||
p.setDevicePixelRatio(cRetinaFactor());
|
||||
black = new ImagePtr(p, "PNG");
|
||||
}
|
||||
|
||||
void ImageLinkManager::reinit() {
|
||||
if (manager) App::setProxySettings(*manager);
|
||||
}
|
||||
|
||||
void ImageLinkManager::deinit() {
|
||||
if (manager) {
|
||||
delete manager;
|
||||
manager = 0;
|
||||
}
|
||||
if (black) {
|
||||
delete black;
|
||||
black = 0;
|
||||
}
|
||||
dataLoadings.clear();
|
||||
imageLoadings.clear();
|
||||
}
|
||||
|
||||
void initImageLinkManager() {
|
||||
manager.init();
|
||||
}
|
||||
|
||||
void reinitImageLinkManager() {
|
||||
manager.reinit();
|
||||
}
|
||||
|
||||
void deinitImageLinkManager() {
|
||||
manager.deinit();
|
||||
}
|
||||
|
||||
void ImageLinkManager::getData(ImageLinkData *data) {
|
||||
if (!manager) {
|
||||
DEBUG_LOG(("App Error: getting image link data without manager init!"));
|
||||
return failed(data);
|
||||
}
|
||||
|
||||
QString url;
|
||||
switch (data->type) {
|
||||
case YouTubeLink: {
|
||||
url = qsl("https://gdata.youtube.com/feeds/api/videos/") + data->id.mid(8) + qsl("?v=2&alt=json");
|
||||
QNetworkReply *reply = manager->get(QNetworkRequest(QUrl(url)));
|
||||
dataLoadings[reply] = data;
|
||||
} break;
|
||||
case InstagramLink: {
|
||||
//url = qsl("https://api.instagram.com/oembed?url=http://instagr.am/p/") + data->id.mid(10) + '/';
|
||||
url = qsl("https://instagram.com/p/") + data->id.mid(10) + qsl("/media/?size=l");
|
||||
QNetworkReply *reply = manager->get(QNetworkRequest(QUrl(url)));
|
||||
imageLoadings[reply] = data;
|
||||
} break;
|
||||
default: {
|
||||
data->loading = false;
|
||||
data->thumb = *black;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void ImageLinkManager::onFinished(QNetworkReply *reply) {
|
||||
if (!manager) return;
|
||||
if (reply->error() != QNetworkReply::NoError) return onFailed(reply);
|
||||
|
||||
QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
|
||||
if (statusCode.isValid()) {
|
||||
int status = statusCode.toInt();
|
||||
if (status == 301 || status == 302) {
|
||||
QString loc = reply->header(QNetworkRequest::LocationHeader).toString();
|
||||
if (!loc.isEmpty()) {
|
||||
QMap<QNetworkReply*, ImageLinkData*>::iterator i = dataLoadings.find(reply);
|
||||
if (i != dataLoadings.cend()) {
|
||||
ImageLinkData *d = i.value();
|
||||
if (serverRedirects.constFind(d) == serverRedirects.cend()) {
|
||||
serverRedirects.insert(d, 1);
|
||||
} else if (++serverRedirects[d] > MaxHttpRedirects) {
|
||||
DEBUG_LOG(("Network Error: Too many HTTP redirects in onFinished() for image link: %1").arg(loc));
|
||||
return onFailed(reply);
|
||||
}
|
||||
dataLoadings.erase(i);
|
||||
dataLoadings.insert(manager->get(QNetworkRequest(loc)), d);
|
||||
return;
|
||||
} else if ((i = imageLoadings.find(reply)) != imageLoadings.cend()) {
|
||||
ImageLinkData *d = i.value();
|
||||
if (serverRedirects.constFind(d) == serverRedirects.cend()) {
|
||||
serverRedirects.insert(d, 1);
|
||||
} else if (++serverRedirects[d] > MaxHttpRedirects) {
|
||||
DEBUG_LOG(("Network Error: Too many HTTP redirects in onFinished() for image link: %1").arg(loc));
|
||||
return onFailed(reply);
|
||||
}
|
||||
imageLoadings.erase(i);
|
||||
imageLoadings.insert(manager->get(QNetworkRequest(loc)), d);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (status != 200) {
|
||||
DEBUG_LOG(("Network Error: Bad HTTP status received in onFinished() for image link: %1").arg(status));
|
||||
return onFailed(reply);
|
||||
}
|
||||
}
|
||||
|
||||
ImageLinkData *d = 0;
|
||||
QMap<QNetworkReply*, ImageLinkData*>::iterator i = dataLoadings.find(reply);
|
||||
if (i != dataLoadings.cend()) {
|
||||
d = i.value();
|
||||
dataLoadings.erase(i);
|
||||
|
||||
QJsonParseError e;
|
||||
QJsonDocument doc = QJsonDocument::fromJson(reply->readAll(), &e);
|
||||
if (e.error != QJsonParseError::NoError) {
|
||||
DEBUG_LOG(("JSON Error: Bad json received in onFinished() for image link"));
|
||||
return onFailed(reply);
|
||||
}
|
||||
QJsonObject obj = doc.object();
|
||||
switch (d->type) {
|
||||
case YouTubeLink: {
|
||||
QString thumb;
|
||||
int32 seconds = 0;
|
||||
QJsonObject::const_iterator entryIt = obj.constFind(qsl("entry"));
|
||||
if (entryIt != obj.constEnd() && entryIt.value().isObject()) {
|
||||
QJsonObject entry = entryIt.value().toObject();
|
||||
QJsonObject::const_iterator mediaIt = entry.constFind(qsl("media$group"));
|
||||
if (mediaIt != entry.constEnd() && mediaIt.value().isObject()) {
|
||||
QJsonObject media = mediaIt.value().toObject();
|
||||
|
||||
// title from media
|
||||
QJsonObject::const_iterator titleIt = media.constFind(qsl("media$title"));
|
||||
if (titleIt != media.constEnd() && titleIt.value().isObject()) {
|
||||
QJsonObject title = titleIt.value().toObject();
|
||||
QJsonObject::const_iterator tIt = title.constFind(qsl("$t"));
|
||||
if (tIt != title.constEnd() && tIt.value().isString()) {
|
||||
d->title = tIt.value().toString();
|
||||
}
|
||||
}
|
||||
|
||||
// thumb
|
||||
QJsonObject::const_iterator thumbnailsIt = media.constFind(qsl("media$thumbnail"));
|
||||
int32 bestLevel = 0;
|
||||
if (thumbnailsIt != media.constEnd() && thumbnailsIt.value().isArray()) {
|
||||
QJsonArray thumbnails = thumbnailsIt.value().toArray();
|
||||
for (int32 i = 0, l = thumbnails.size(); i < l; ++i) {
|
||||
QJsonValue thumbnailVal = thumbnails.at(i);
|
||||
if (!thumbnailVal.isObject()) continue;
|
||||
|
||||
QJsonObject thumbnail = thumbnailVal.toObject();
|
||||
QJsonObject::const_iterator urlIt = thumbnail.constFind(qsl("url"));
|
||||
if (urlIt == thumbnail.constEnd() || !urlIt.value().isString()) continue;
|
||||
|
||||
int32 level = 0;
|
||||
if (thumbnail.constFind(qsl("time")) == thumbnail.constEnd()) {
|
||||
level += 10;
|
||||
}
|
||||
QJsonObject::const_iterator wIt = thumbnail.constFind(qsl("width"));
|
||||
if (wIt != thumbnail.constEnd()) {
|
||||
int32 w = 0;
|
||||
if (wIt.value().isDouble()) {
|
||||
w = qMax(qRound(wIt.value().toDouble()), 0);
|
||||
} else if (wIt.value().isString()) {
|
||||
w = qMax(qRound(wIt.value().toString().toDouble()), 0);
|
||||
}
|
||||
switch (w) {
|
||||
case 640: level += 4; break;
|
||||
case 480: level += 3; break;
|
||||
case 320: level += 2; break;
|
||||
case 120: level += 1; break;
|
||||
}
|
||||
}
|
||||
if (level > bestLevel) {
|
||||
thumb = urlIt.value().toString();
|
||||
bestLevel = level;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// duration
|
||||
QJsonObject::const_iterator durationIt = media.constFind(qsl("yt$duration"));
|
||||
if (durationIt != media.constEnd() && durationIt.value().isObject()) {
|
||||
QJsonObject duration = durationIt.value().toObject();
|
||||
QJsonObject::const_iterator secondsIt = duration.constFind(qsl("seconds"));
|
||||
if (secondsIt != duration.constEnd()) {
|
||||
if (secondsIt.value().isDouble()) {
|
||||
seconds = qRound(secondsIt.value().toDouble());
|
||||
} else if (secondsIt.value().isString()) {
|
||||
seconds = qRound(secondsIt.value().toString().toDouble());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// title field
|
||||
if (d->title.isEmpty()) {
|
||||
QJsonObject::const_iterator titleIt = entry.constFind(qsl("title"));
|
||||
if (titleIt != entry.constEnd() && titleIt.value().isObject()) {
|
||||
QJsonObject title = titleIt.value().toObject();
|
||||
QJsonObject::const_iterator tIt = title.constFind(qsl("$t"));
|
||||
if (tIt != title.constEnd() && tIt.value().isString()) {
|
||||
d->title = tIt.value().toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (seconds > 0) {
|
||||
d->duration = formatDurationText(seconds);
|
||||
}
|
||||
if (thumb.isEmpty()) {
|
||||
d->loading = false;
|
||||
d->thumb = *black;
|
||||
serverRedirects.remove(d);
|
||||
} else {
|
||||
imageLoadings.insert(manager->get(QNetworkRequest(thumb)), d);
|
||||
}
|
||||
} break;
|
||||
|
||||
case InstagramLink: {
|
||||
d->loading = false;
|
||||
d->thumb = *black;
|
||||
serverRedirects.remove(d);
|
||||
} break;
|
||||
}
|
||||
|
||||
if (App::main()) App::main()->update();
|
||||
} else {
|
||||
i = imageLoadings.find(reply);
|
||||
if (i != imageLoadings.cend()) {
|
||||
d = i.value();
|
||||
imageLoadings.erase(i);
|
||||
|
||||
QPixmap thumb;
|
||||
QByteArray format;
|
||||
QByteArray data(reply->readAll());
|
||||
{
|
||||
QBuffer buffer(&data);
|
||||
QImageReader reader(&buffer);
|
||||
thumb = QPixmap::fromImageReader(&reader, Qt::ColorOnly);
|
||||
format = reader.format();
|
||||
if (format.isEmpty()) format = QByteArray("JPG");
|
||||
}
|
||||
d->loading = false;
|
||||
d->thumb = thumb.isNull() ? (*black) : ImagePtr(thumb, format);
|
||||
serverRedirects.remove(d);
|
||||
if (App::main()) App::main()->update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ImageLinkManager::onFailed(QNetworkReply *reply) {
|
||||
if (!manager) return;
|
||||
|
||||
ImageLinkData *d = 0;
|
||||
QMap<QNetworkReply*, ImageLinkData*>::iterator i = dataLoadings.find(reply);
|
||||
if (i != dataLoadings.cend()) {
|
||||
d = i.value();
|
||||
dataLoadings.erase(i);
|
||||
} else {
|
||||
i = imageLoadings.find(reply);
|
||||
if (i != imageLoadings.cend()) {
|
||||
d = i.value();
|
||||
imageLoadings.erase(i);
|
||||
}
|
||||
}
|
||||
DEBUG_LOG(("Network Error: failed to get data for image link %1, error %2").arg(d ? d->id : 0).arg(reply->errorString()));
|
||||
if (d) {
|
||||
d->loading = false;
|
||||
d->thumb = *black;
|
||||
serverRedirects.remove(d);
|
||||
}
|
||||
}
|
||||
|
||||
void ImageLinkManager::failed(ImageLinkData *data) {
|
||||
|
||||
}
|
||||
|
||||
void ImageLinkData::load() {
|
||||
if (!thumb->isNull()) return thumb->load(false, false);
|
||||
if (loading) return;
|
||||
|
||||
loading = true;
|
||||
manager.getData(this);
|
||||
}
|
||||
|
||||
HistoryImageLink::HistoryImageLink(const QString &url, int32 width) : w(width) {
|
||||
QRegularExpressionMatch m = reYouTube1.match(url);
|
||||
if (!m.hasMatch()) m = reYouTube2.match(url);
|
||||
if (m.hasMatch()) {
|
||||
data = App::imageLink(qsl("youtube:") + m.captured(3), YouTubeLink, url);
|
||||
} else {
|
||||
m = reInstagram.match(url);
|
||||
if (m.hasMatch()) {
|
||||
data = App::imageLink(qsl("instagram:") + m.captured(3), InstagramLink, url);
|
||||
} else {
|
||||
data = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32 HistoryImageLink::fullWidth() const {
|
||||
if (data) {
|
||||
switch (data->type) {
|
||||
case YouTubeLink: return 640;
|
||||
case InstagramLink: return 640;
|
||||
}
|
||||
}
|
||||
return st::minPhotoWidth;
|
||||
}
|
||||
|
||||
int32 HistoryImageLink::fullHeight() const {
|
||||
if (data) {
|
||||
switch (data->type) {
|
||||
case YouTubeLink: return 480;
|
||||
case InstagramLink: return 640;
|
||||
}
|
||||
}
|
||||
return st::minPhotoHeight;
|
||||
}
|
||||
|
||||
void HistoryImageLink::initDimensions(const HistoryItem *parent) {
|
||||
int32 tw = convertScale(fullWidth()), th = convertScale(fullHeight());
|
||||
int32 thumbw = qMax(tw, int32(st::minPhotoWidth)), maxthumbh = thumbw;
|
||||
int32 thumbh = qRound(th * float64(thumbw) / tw);
|
||||
if (thumbh > maxthumbh) {
|
||||
thumbw = qRound(thumbw * float64(maxthumbh) / thumbh);
|
||||
thumbh = maxthumbh;
|
||||
if (thumbw < st::minPhotoWidth) {
|
||||
thumbw = st::minPhotoWidth;
|
||||
}
|
||||
}
|
||||
if (thumbh < st::minPhotoHeight) {
|
||||
thumbh = st::minPhotoHeight;
|
||||
}
|
||||
if (!w) {
|
||||
w = thumbw;
|
||||
}
|
||||
_maxw = w;
|
||||
_height = _minh = thumbh;
|
||||
}
|
||||
|
||||
void HistoryImageLink::draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width) const {
|
||||
if (width < 0) width = w;
|
||||
|
||||
data->load();
|
||||
bool out = parent->out();
|
||||
QPixmap toDraw;
|
||||
if (data && !data->thumb->isNull()) {
|
||||
int32 w = data->thumb->width(), h = data->thumb->height();
|
||||
if (width * h == _height * w) {
|
||||
p.drawPixmap(QPoint(0, 0), data->thumb->pixSingle(width));
|
||||
} else {
|
||||
p.fillRect(QRect(0, 0, width, _height), st::black->b);
|
||||
if (width * h > _height * w) {
|
||||
int32 nw = _height * w / h;
|
||||
p.drawPixmap(QPoint((width - nw) / 2, 0), data->thumb->pixSingle(nw, _height));
|
||||
} else {
|
||||
int32 nh = width * h / w;
|
||||
p.drawPixmap(QPoint(0, (_height - nh) / 2), data->thumb->pixSingle(width, nh));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
p.fillRect(QRect(0, 0, width, _height), st::black->b);
|
||||
}
|
||||
if (data) {
|
||||
switch (data->type) {
|
||||
case YouTubeLink: p.drawPixmap(QPoint((width - st::youtubeIcon.pxWidth()) / 2, (_height - st::youtubeIcon.pxHeight()) / 2), App::sprite(), st::youtubeIcon); break;
|
||||
case InstagramLink: p.drawPixmap(QPoint((width - st::instagramIcon.pxWidth()) / 2, (_height - st::instagramIcon.pxHeight()) / 2), App::sprite(), st::instagramIcon); break;
|
||||
}
|
||||
if (!data->title.isEmpty() || !data->duration.isEmpty()) {
|
||||
p.fillRect(0, 0, width, st::msgDateFont->height + 2 * st::msgDateImgPadding.y(), st::msgDateImgBg->b);
|
||||
p.setFont(st::msgDateFont->f);
|
||||
p.setPen(st::msgDateImgColor->p);
|
||||
int32 titleWidth = width - 2 * st::msgDateImgPadding.x();
|
||||
if (!data->duration.isEmpty()) {
|
||||
int32 durationWidth = st::msgDateFont->m.width(data->duration);
|
||||
p.drawText(width - st::msgDateImgPadding.x() - durationWidth, st::msgDateImgPadding.y() + st::msgDateFont->ascent, data->duration);
|
||||
titleWidth -= durationWidth + st::msgDateImgPadding.x();
|
||||
}
|
||||
if (!data->title.isEmpty()) {
|
||||
p.drawText(st::msgDateImgPadding.x(), st::msgDateImgPadding.y() + st::msgDateFont->ascent, st::msgDateFont->m.elidedText(data->title, Qt::ElideRight, titleWidth));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (selected) {
|
||||
p.fillRect(0, 0, width, _height, textstyleCurrent()->selectOverlay->b);
|
||||
}
|
||||
style::color shadow(selected ? st::msgInSelectShadow : st::msgInShadow);
|
||||
p.fillRect(0, _height, width, st::msgShadow, shadow->b);
|
||||
|
||||
// date
|
||||
QString time(parent->time());
|
||||
if (time.isEmpty()) return;
|
||||
int32 dateX = width - parent->timeWidth() - st::msgDateImgDelta - 2 * st::msgDateImgPadding.x();
|
||||
int32 dateY = _height - st::msgDateFont->height - 2 * st::msgDateImgPadding.y() - st::msgDateImgDelta;
|
||||
if (parent->out()) {
|
||||
dateX -= st::msgCheckRect.pxWidth() + st::msgDateImgCheckSpace;
|
||||
}
|
||||
int32 dateW = width - dateX - st::msgDateImgDelta;
|
||||
int32 dateH = _height - dateY - st::msgDateImgDelta;
|
||||
|
||||
p.fillRect(dateX, dateY, dateW, dateH, st::msgDateImgBg->b);
|
||||
p.setFont(st::msgDateFont->f);
|
||||
p.setPen(st::msgDateImgColor->p);
|
||||
p.drawText(dateX + st::msgDateImgPadding.x(), dateY + st::msgDateImgPadding.y() + st::msgDateFont->ascent, time);
|
||||
if (out) {
|
||||
QPoint iconPos(dateX - 2 + dateW - st::msgDateImgCheckSpace - st::msgCheckRect.pxWidth(), dateY + (dateH - st::msgCheckRect.pxHeight()) / 2);
|
||||
const QRect *iconRect;
|
||||
if (parent->id > 0) {
|
||||
if (parent->unread()) {
|
||||
iconRect = &st::msgImgCheckRect;
|
||||
} else {
|
||||
iconRect = &st::msgImgDblCheckRect;
|
||||
}
|
||||
} else {
|
||||
iconRect = &st::msgImgSendingRect;
|
||||
}
|
||||
p.drawPixmap(iconPos, App::sprite(), *iconRect);
|
||||
}
|
||||
}
|
||||
|
||||
int32 HistoryImageLink::resize(int32 width, bool dontRecountText, const HistoryItem *parent) {
|
||||
w = width;
|
||||
|
||||
int32 tw = convertScale(fullWidth()), th = convertScale(fullHeight());
|
||||
_height = th;
|
||||
if (tw > w) {
|
||||
_height = (w * _height / tw);
|
||||
} else {
|
||||
w = tw;
|
||||
}
|
||||
if (_height > width) {
|
||||
w = (w * width) / _height;
|
||||
_height = width;
|
||||
}
|
||||
if (w < st::minPhotoWidth) {
|
||||
w = st::minPhotoWidth;
|
||||
}
|
||||
if (_height < st::minPhotoHeight) {
|
||||
_height = st::minPhotoHeight;
|
||||
}
|
||||
return _height;
|
||||
}
|
||||
|
||||
const QString HistoryImageLink::inDialogsText() const {
|
||||
if (data) {
|
||||
switch (data->type) {
|
||||
case YouTubeLink: return qsl("YouTube Video");
|
||||
case InstagramLink: return qsl("Instagram Link");
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
bool HistoryImageLink::hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width) const {
|
||||
if (width < 0) width = w;
|
||||
return (x >= 0 && y >= 0 && x < width && y < _height);
|
||||
}
|
||||
|
||||
TextLinkPtr HistoryImageLink::getLink(int32 x, int32 y, const HistoryItem *parent, int32 width) const {
|
||||
if (width < 0) width = w;
|
||||
if (x >= 0 && y >= 0 && x < width && y < _height && data) {
|
||||
return data->openl;
|
||||
}
|
||||
return TextLinkPtr();
|
||||
}
|
||||
|
||||
HistoryMedia *HistoryImageLink::clone() const {
|
||||
return new HistoryImageLink(*this);
|
||||
}
|
||||
|
||||
HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, const MTPDmessage &msg) :
|
||||
HistoryItem(history, block, msg.vid.v, (msg.vflags.v & 0x02), (msg.vflags.v & 0x01), ::date(msg.vdate), msg.vfrom_id.v)
|
||||
, _text(st::msgMinWidth)
|
||||
@ -3099,7 +3605,13 @@ HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, MsgId msgI
|
||||
|
||||
void HistoryMessage::initMedia(const MTPMessageMedia &media, QString ¤tText) {
|
||||
switch (media.type()) {
|
||||
case mtpc_messageMediaEmpty: break;
|
||||
case mtpc_messageMediaEmpty: {
|
||||
QString lnk = currentText.trimmed();
|
||||
if (reYouTube1.match(currentText).hasMatch() || reYouTube2.match(currentText).hasMatch() || reInstagram.match(currentText).hasMatch()) {
|
||||
_media = new HistoryImageLink(lnk);
|
||||
currentText = QString();
|
||||
}
|
||||
} break;
|
||||
case mtpc_messageMediaContact: {
|
||||
const MTPDmessageMediaContact &d(media.c_messageMediaContact());
|
||||
_media = new HistoryContact(d.vuser_id.v, qs(d.vfirst_name), qs(d.vlast_name), qs(d.vphone_number));
|
||||
|
@ -188,6 +188,9 @@ struct PhotoData {
|
||||
ImagePtr full;
|
||||
ChatData *chat; // for chat photos connection
|
||||
// geo, caption
|
||||
|
||||
int32 cachew;
|
||||
QPixmap cache;
|
||||
};
|
||||
|
||||
class PhotoLink : public ITextLink {
|
||||
@ -581,6 +584,7 @@ enum HistoryMediaType {
|
||||
MediaTypeContact,
|
||||
MediaTypeAudio,
|
||||
MediaTypeDocument,
|
||||
MediaTypeImageLink,
|
||||
|
||||
MediaTypeCount
|
||||
};
|
||||
@ -1418,6 +1422,80 @@ private:
|
||||
UserData *contact;
|
||||
};
|
||||
|
||||
void initImageLinkManager();
|
||||
void reinitImageLinkManager();
|
||||
void deinitImageLinkManager();
|
||||
|
||||
enum ImageLinkType {
|
||||
InvalidImageLink = 0,
|
||||
YouTubeLink,
|
||||
InstagramLink
|
||||
};
|
||||
struct ImageLinkData {
|
||||
ImageLinkData(const QString &id) : id(id), type(InvalidImageLink), loading(false) {
|
||||
}
|
||||
|
||||
QString id;
|
||||
QString title, duration;
|
||||
ImagePtr thumb;
|
||||
TextLinkPtr openl;
|
||||
ImageLinkType type;
|
||||
bool loading;
|
||||
|
||||
void load();
|
||||
};
|
||||
|
||||
class ImageLinkManager : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ImageLinkManager() : manager(0), black(0) {
|
||||
}
|
||||
void init();
|
||||
void reinit();
|
||||
void deinit();
|
||||
|
||||
void getData(ImageLinkData *data);
|
||||
|
||||
~ImageLinkManager() {
|
||||
deinit();
|
||||
}
|
||||
|
||||
public slots:
|
||||
void onFinished(QNetworkReply *reply);
|
||||
void onFailed(QNetworkReply *reply);
|
||||
|
||||
private:
|
||||
void failed(ImageLinkData *data);
|
||||
|
||||
QNetworkAccessManager *manager;
|
||||
QMap<QNetworkReply*, ImageLinkData*> dataLoadings, imageLoadings;
|
||||
QMap<ImageLinkData*, int32> serverRedirects;
|
||||
ImagePtr *black;
|
||||
};
|
||||
|
||||
class HistoryImageLink : public HistoryMedia {
|
||||
public:
|
||||
|
||||
HistoryImageLink(const QString &url, int32 width = 0);
|
||||
int32 fullWidth() const;
|
||||
int32 fullHeight() const;
|
||||
void initDimensions(const HistoryItem *parent);
|
||||
|
||||
void draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width = -1) const;
|
||||
int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0);
|
||||
HistoryMediaType type() const {
|
||||
return MediaTypeImageLink;
|
||||
}
|
||||
const QString inDialogsText() const;
|
||||
bool hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
|
||||
TextLinkPtr getLink(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
|
||||
HistoryMedia *clone() const;
|
||||
|
||||
private:
|
||||
ImageLinkData *data;
|
||||
int32 w;
|
||||
};
|
||||
|
||||
class HistoryMessage : public HistoryItem {
|
||||
public:
|
||||
|
||||
|
@ -1765,10 +1765,7 @@ void HistoryWidget::showPeer(const PeerId &peer, MsgId msgId, bool force, bool l
|
||||
App::mousedItem(0);
|
||||
|
||||
if (peer) {
|
||||
App::forgetPhotos();
|
||||
App::forgetVideos();
|
||||
App::forgetAudios();
|
||||
App::forgetDocuments();
|
||||
App::forgetMedia();
|
||||
serviceImageCacheSize = imageCacheSize();
|
||||
MTP::clearLoaderPriorities();
|
||||
histInputPeer = histPeer->input;
|
||||
@ -3213,6 +3210,9 @@ void HistoryWidget::onDeleteSelectedSure() {
|
||||
for (SelectedItemSet::const_iterator i = sel.cbegin(), e = sel.cend(); i != e; ++i) {
|
||||
i.value()->destroy();
|
||||
}
|
||||
if (App::main() && App::main()->peer() == peer()) {
|
||||
App::main()->itemResized(0);
|
||||
}
|
||||
App::wnd()->hideLayer();
|
||||
}
|
||||
|
||||
@ -3226,6 +3226,9 @@ void HistoryWidget::onDeleteContextSure() {
|
||||
MTP::send(MTPmessages_DeleteMessages(MTP_vector<MTPint>(1, MTP_int(item->id))));
|
||||
}
|
||||
item->destroy();
|
||||
if (App::main() && App::main()->peer() == peer()) {
|
||||
App::main()->itemResized(0);
|
||||
}
|
||||
App::wnd()->hideLayer();
|
||||
}
|
||||
|
||||
|
@ -722,7 +722,7 @@ void MainWidget::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) {
|
||||
}
|
||||
|
||||
void MainWidget::itemResized(HistoryItem *row) {
|
||||
if (history.peer() == row->history()->peer && !row->detached()) {
|
||||
if (!row || history.peer() == row->history()->peer && !row->detached()) {
|
||||
history.itemResized(row);
|
||||
}
|
||||
if (overview) {
|
||||
@ -1117,7 +1117,7 @@ void MainWidget::peerAfter(const PeerData *inPeer, MsgId inMsg, PeerData *&outPe
|
||||
}
|
||||
|
||||
PeerData *MainWidget::peer() {
|
||||
return history.peer();
|
||||
return overview ? overview->peer() : history.peer();
|
||||
}
|
||||
|
||||
PeerData *MainWidget::activePeer() {
|
||||
|
@ -472,13 +472,8 @@ void MediaView::showPhoto(PhotoData *photo) {
|
||||
_full = -1;
|
||||
_current = QPixmap();
|
||||
_down = OverNone;
|
||||
_w = photo->full->width();
|
||||
_h = photo->full->height();
|
||||
switch (cScale()) {
|
||||
case dbisOneAndQuarter: _w = qRound(float64(_w) * 1.25 - 0.01); _h = qRound(float64(_h) * 1.25 - 0.01); break;
|
||||
case dbisOneAndHalf: _w = qRound(float64(_w) * 1.5 - 0.01); _h = qRound(float64(_h) * 1.5 - 0.01); break;
|
||||
case dbisTwo: _w *= 2; _h *= 2; break;
|
||||
}
|
||||
_w = convertScale(photo->full->width());
|
||||
_h = convertScale(photo->full->height());
|
||||
if (isHidden()) {
|
||||
moveToScreen();
|
||||
}
|
||||
|
@ -1451,6 +1451,7 @@ void OverviewInner::itemResized(HistoryItem *item) {
|
||||
if (_addToY + _height - _items[i].y < _scroll->scrollTop()) {
|
||||
_scroll->scrollToY(_addToY + _height - _items[i].y);
|
||||
}
|
||||
parentWidget()->update();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1742,7 +1743,7 @@ void OverviewWidget::itemRemoved(HistoryItem *row) {
|
||||
}
|
||||
|
||||
void OverviewWidget::itemResized(HistoryItem *row) {
|
||||
if (row->history()->peer == peer()) {
|
||||
if (!row || row->history()->peer == peer()) {
|
||||
_inner.itemResized(row);
|
||||
}
|
||||
}
|
||||
@ -1838,6 +1839,9 @@ void OverviewWidget::onDeleteSelectedSure() {
|
||||
for (SelectedItemSet::const_iterator i = sel.cbegin(), e = sel.cend(); i != e; ++i) {
|
||||
i.value()->destroy();
|
||||
}
|
||||
if (App::main() && App::main()->peer() == peer()) {
|
||||
App::main()->itemResized(0);
|
||||
}
|
||||
App::wnd()->hideLayer();
|
||||
}
|
||||
|
||||
@ -1851,6 +1855,9 @@ void OverviewWidget::onDeleteContextSure() {
|
||||
MTP::send(MTPmessages_DeleteMessages(MTP_vector<MTPint>(1, MTP_int(item->id))));
|
||||
}
|
||||
item->destroy();
|
||||
if (App::main() && App::main()->peer() == peer()) {
|
||||
App::main()->itemResized(0);
|
||||
}
|
||||
App::wnd()->hideLayer();
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
an unofficial desktop messaging app, see https://telegram.org
|
||||
@ -230,7 +229,7 @@ namespace {
|
||||
destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
hwnds[i] = CreateWindowEx(WS_EX_LAYERED | WS_EX_TOOLWINDOW, _cn, 0, WS_POPUP, 0, 0, 0, 0, 0, 0, appinst, 0);
|
||||
if (!hwnds[i]) {
|
||||
DEBUG_LOG(("Application Error: could not create shadow window class %1, error: %2").arg(i).arg(GetLastError()));
|
||||
|
@ -104,6 +104,17 @@ DeclareSetting(DBIScale, ScreenScale);
|
||||
DeclareSetting(DBIScale, ConfigScale);
|
||||
DeclareSetting(bool, CompressPastedImage);
|
||||
|
||||
template <typename T>
|
||||
T convertScale(T v) {
|
||||
switch (cScale()) {
|
||||
case dbisOneAndQuarter: return qRound(float64(v) * 1.25 - 0.01);
|
||||
case dbisOneAndHalf: return qRound(float64(v) * 1.5 - 0.01);
|
||||
case dbisTwo: return v * 2;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
inline DBIScale cEvalScale(DBIScale scale) {
|
||||
return (scale == dbisAuto) ? cScreenScale() : scale;
|
||||
}
|
||||
|
@ -79,7 +79,7 @@
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OutputFile>$(OutDir)$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>.\..\..\Libraries\lzma\C\Util\LzmaLib\Debug;.\..\..\Libraries\libexif-0.6.20\win32\Debug;.\..\..\Libraries\libogg-1.3.2\win32\VS2010\Win32\Debug;.\..\..\Libraries\opus\win32\VS2010\Win32\Debug;.\..\..\Libraries\opusfile\win32\VS2010\Win32\Debug;.\..\..\Libraries\openal-soft\build\Debug;.\..\..\Libraries\zlib-1.2.8\contrib\vstudio\vc11\x86\ZlibStatDebug;.\..\..\Libraries\OpenSSL-Win32\lib\VC\static;$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;gdi32.lib;comdlg32.lib;oleaut32.lib;imm32.lib;winmm.lib;qtmaind.lib;glu32.lib;opengl32.lib;Strmiids.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5Widgetsd.lib;Qt5Networkd.lib;Qt5PlatformSupportd.lib;platforms\qwindowsd.lib;accessible\qtaccessiblewidgetsd.lib;libeay32MTd.lib;zlibstat.lib;LzmaLib.lib;lib_exif.lib;UxTheme.lib;DbgHelp.lib;OpenAL32.lib;common.lib;opusfile.lib;opus.lib;libogg_static.lib;celt.lib;silk_common.lib;silk_float.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;gdi32.lib;comdlg32.lib;oleaut32.lib;imm32.lib;winmm.lib;qtmaind.lib;glu32.lib;opengl32.lib;Strmiids.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5Widgetsd.lib;Qt5Networkd.lib;Qt5PlatformSupportd.lib;platforms\qwindowsd.lib;accessible\qtaccessiblewidgetsd.lib;libeay32MTd.lib;ssleay32MTd.lib;Crypt32.lib;zlibstat.lib;LzmaLib.lib;lib_exif.lib;UxTheme.lib;DbgHelp.lib;OpenAL32.lib;common.lib;opusfile.lib;opus.lib;libogg_static.lib;celt.lib;silk_common.lib;silk_float.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ImageHasSafeExceptionHandlers />
|
||||
<IgnoreSpecificDefaultLibraries>
|
||||
@ -108,7 +108,7 @@
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OutputFile>$(OutDir)$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>.\..\..\Libraries\lzma\C\Util\LzmaLib\Release;.\..\..\Libraries\libexif-0.6.20\win32\Release;.\..\..\Libraries\libogg-1.3.2\win32\VS2010\Win32\Release;.\..\..\Libraries\opus\win32\VS2010\Win32\Release;.\..\..\Libraries\opusfile\win32\VS2010\Win32\Release;.\..\..\Libraries\openal-soft\build\Release;.\..\..\Libraries\zlib-1.2.8\contrib\vstudio\vc11\x86\ZlibStatRelease;.\..\..\Libraries\OpenSSL-Win32\lib\VC\static;$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;gdi32.lib;comdlg32.lib;oleaut32.lib;imm32.lib;winmm.lib;qtmain.lib;glu32.lib;opengl32.lib;Strmiids.lib;Qt5Core.lib;Qt5Gui.lib;Qt5Widgets.lib;Qt5Network.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;accessible\qtaccessiblewidgets.lib;libeay32MT.lib;zlibstat.lib;lib_exif.lib;UxTheme.lib;DbgHelp.lib;LzmaLib.lib;OpenAL32.lib;common.lib;opusfile.lib;opus.lib;libogg_static.lib;celt.lib;silk_common.lib;silk_float.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;gdi32.lib;comdlg32.lib;oleaut32.lib;imm32.lib;winmm.lib;qtmain.lib;glu32.lib;opengl32.lib;Strmiids.lib;Qt5Core.lib;Qt5Gui.lib;Qt5Widgets.lib;Qt5Network.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;accessible\qtaccessiblewidgets.lib;libeay32MT.lib;ssleay32MT.lib;Crypt32.lib;zlibstat.lib;lib_exif.lib;UxTheme.lib;DbgHelp.lib;LzmaLib.lib;OpenAL32.lib;common.lib;opusfile.lib;opus.lib;libogg_static.lib;celt.lib;silk_common.lib;silk_float.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ImageHasSafeExceptionHandlers />
|
||||
<ImportLibrary>$(SolutionDir)$(Platform)\$(Configuration)Intermediate\$(TargetName).lib</ImportLibrary>
|
||||
<ProfileGuidedDatabase>$(IntDir)$(TargetName).pgd</ProfileGuidedDatabase>
|
||||
@ -135,7 +135,7 @@
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OutputFile>$(OutDir)$(ProjectName).exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>.\..\..\Libraries\lzma\C\Util\LzmaLib\Release;.\..\..\Libraries\libexif-0.6.20\win32\Release;.\..\..\Libraries\libogg-1.3.2\win32\VS2010\Win32\Release;.\..\..\Libraries\opus\win32\VS2010\Win32\Release;.\..\..\Libraries\opusfile\win32\VS2010\Win32\Release;.\..\..\Libraries\openal-soft\build\Release;.\..\..\Libraries\zlib-1.2.8\contrib\vstudio\vc11\x86\ZlibStatRelease;.\..\..\Libraries\OpenSSL-Win32\lib\VC\static;$(QTDIR)\lib;$(QTDIR)\plugins;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;gdi32.lib;comdlg32.lib;oleaut32.lib;imm32.lib;winmm.lib;qtmain.lib;glu32.lib;opengl32.lib;Strmiids.lib;Qt5Core.lib;Qt5Gui.lib;Qt5Widgets.lib;Qt5Network.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;accessible\qtaccessiblewidgets.lib;libeay32MT.lib;zlibstat.lib;lib_exif.lib;UxTheme.lib;DbgHelp.lib;LzmaLib.lib;OpenAL32.lib;common.lib;opusfile.lib;opus.lib;libogg_static.lib;celt.lib;silk_common.lib;silk_float.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;shell32.lib;uuid.lib;ole32.lib;advapi32.lib;ws2_32.lib;gdi32.lib;comdlg32.lib;oleaut32.lib;imm32.lib;winmm.lib;qtmain.lib;glu32.lib;opengl32.lib;Strmiids.lib;Qt5Core.lib;Qt5Gui.lib;Qt5Widgets.lib;Qt5Network.lib;Qt5PlatformSupport.lib;platforms\qwindows.lib;accessible\qtaccessiblewidgets.lib;libeay32MT.lib;ssleay32MT.lib;Crypt32.lib;zlibstat.lib;lib_exif.lib;UxTheme.lib;DbgHelp.lib;LzmaLib.lib;OpenAL32.lib;common.lib;opusfile.lib;opus.lib;libogg_static.lib;celt.lib;silk_common.lib;silk_float.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ImageHasSafeExceptionHandlers>
|
||||
</ImageHasSafeExceptionHandlers>
|
||||
<ImportLibrary>$(SolutionDir)$(Platform)\$(Configuration)Intermediate\$(TargetName).lib</ImportLibrary>
|
||||
@ -238,6 +238,10 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Debug\moc_history.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Debug\moc_historywidget.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
@ -446,6 +450,10 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Deploy\moc_history.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Deploy\moc_historywidget.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
@ -663,6 +671,10 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Release\moc_history.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Release\moc_historywidget.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
@ -1350,7 +1362,20 @@
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DAL_LIBTYPE_STATIC -DUNICODE -D_WITH_DEBUG -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.3.1\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.3.1\QtGui" "-fstdafx.h" "-f../../SourceFiles/gui/switcher.h"</Command>
|
||||
</CustomBuild>
|
||||
<ClInclude Include="SourceFiles\gui\text.h" />
|
||||
<ClInclude Include="SourceFiles\history.h" />
|
||||
<CustomBuild Include="SourceFiles\history.h">
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">Moc%27ing history.h...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/history.h" -DAL_LIBTYPE_STATIC -DCUSTOM_API_ID -DUNICODE -D_WITH_DEBUG -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.3.1\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.3.1\QtGui"</Command>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Moc%27ing history.h...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/history.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.3.1\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.3.1\QtGui"</Command>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Moc%27ing history.h...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/history.h" -DAL_LIBTYPE_STATIC -DUNICODE -D_WITH_DEBUG -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.3.1\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.3.1\QtGui"</Command>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="SourceFiles\historywidget.h">
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Moc%27ing historywidget.h...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
|
@ -734,6 +734,15 @@
|
||||
<ClCompile Include="GeneratedFiles\Release\moc_usernamebox.cpp">
|
||||
<Filter>Generated Files\Release</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Deploy\moc_history.cpp">
|
||||
<Filter>Generated Files\Deploy</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Debug\moc_history.cpp">
|
||||
<Filter>Generated Files\Debug</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeneratedFiles\Release\moc_history.cpp">
|
||||
<Filter>Generated Files\Release</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="SourceFiles\stdafx.h">
|
||||
@ -778,9 +787,6 @@
|
||||
<ClInclude Include="SourceFiles\app.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SourceFiles\history.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SourceFiles\gui\emoji_config.h">
|
||||
<Filter>gui</Filter>
|
||||
</ClInclude>
|
||||
@ -987,6 +993,9 @@
|
||||
<CustomBuild Include="SourceFiles\boxes\usernamebox.h">
|
||||
<Filter>boxes</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="SourceFiles\history.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="SourceFiles\art\iconround256.ico" />
|
||||
|
Loading…
Reference in New Issue
Block a user