From 09e2fbaa6b1db84a85e327567bc7cfe1e38b6865 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 10 Oct 2014 16:46:20 +0400 Subject: [PATCH] inline gif view done, some design improvements, version 0.6.3 --- Telegram/PrepareLinux.sh | 4 +- Telegram/PrepareLinux32.sh | 4 +- Telegram/PrepareMac.sh | 4 +- Telegram/Resources/style.txt | 22 +- Telegram/Setup.iss | 6 +- Telegram/SignWinSetup.bat | 2 +- Telegram/SourceFiles/app.cpp | 26 +- Telegram/SourceFiles/config.h | 6 +- Telegram/SourceFiles/dialogswidget.cpp | 14 +- Telegram/SourceFiles/dialogswidget.h | 8 +- Telegram/SourceFiles/gui/countryinput.cpp | 8 +- Telegram/SourceFiles/gui/countryinput.h | 1 + Telegram/SourceFiles/history.cpp | 355 +++++++++++++++----- Telegram/SourceFiles/history.h | 59 ++-- Telegram/SourceFiles/historywidget.cpp | 52 ++- Telegram/SourceFiles/historywidget.h | 12 +- Telegram/SourceFiles/layerwidget.cpp | 1 + Telegram/SourceFiles/mainwidget.cpp | 45 ++- Telegram/SourceFiles/mainwidget.h | 5 +- Telegram/SourceFiles/mediaview.cpp | 4 +- Telegram/SourceFiles/mediaview.h | 2 +- Telegram/SourceFiles/overviewwidget.cpp | 72 +++- Telegram/SourceFiles/overviewwidget.h | 10 +- Telegram/SourceFiles/profilewidget.cpp | 1 + Telegram/SourceFiles/window.cpp | 4 +- Telegram/SourceFiles/window.h | 2 +- Telegram/Telegram.plist | 2 +- Telegram/Telegram.rc | Bin 5542 -> 5542 bytes Telegram/Telegram.xcodeproj/project.pbxproj | 12 +- 29 files changed, 548 insertions(+), 195 deletions(-) diff --git a/Telegram/PrepareLinux.sh b/Telegram/PrepareLinux.sh index 11ee7c41b..80fbf5fb1 100755 --- a/Telegram/PrepareLinux.sh +++ b/Telegram/PrepareLinux.sh @@ -1,5 +1,5 @@ -AppVersionStr=0.6.2 -AppVersion=6002 +AppVersionStr=0.6.3 +AppVersion=6003 if [ -d "./../Linux/Release/deploy/$AppVersionStr" ]; then echo "Deploy folder for version $AppVersionStr already exists!" diff --git a/Telegram/PrepareLinux32.sh b/Telegram/PrepareLinux32.sh index 1901f4041..5f7fd9fe5 100755 --- a/Telegram/PrepareLinux32.sh +++ b/Telegram/PrepareLinux32.sh @@ -1,5 +1,5 @@ -AppVersionStr=0.6.2 -AppVersion=6002 +AppVersionStr=0.6.3 +AppVersion=6003 if [ -d "./../Linux/Release/deploy/$AppVersionStr" ]; then echo "Deploy folder for version $AppVersionStr already exists!" diff --git a/Telegram/PrepareMac.sh b/Telegram/PrepareMac.sh index 0520b7d0f..0f7bc7a5a 100755 --- a/Telegram/PrepareMac.sh +++ b/Telegram/PrepareMac.sh @@ -1,5 +1,5 @@ -AppVersionStr=0.6.2 -AppVersion=6002 +AppVersionStr=0.6.3 +AppVersion=6003 if [ -d "./../Mac/Release/deploy/$AppVersionStr" ]; then echo "Deploy folder for version $AppVersionStr already exists!" diff --git a/Telegram/Resources/style.txt b/Telegram/Resources/style.txt index 326e6560f..33aec4a8c 100644 --- a/Telegram/Resources/style.txt +++ b/Telegram/Resources/style.txt @@ -244,9 +244,9 @@ inpDefFlat: flatInput { } inpDefGray: flatInput(inpDefFlat) { - bgColor: #ebebeb; + bgColor: #f2f2f2; borderWidth: 2px; - borderColor: #ebebeb; + borderColor: #f2f2f2; borderActive: #80cff9; borderError: #ed8080; phColor: #808080; @@ -374,7 +374,7 @@ introCountry: countryInput { width: 300px; height: 41px; top: 24px; - bgColor: #ebebeb; + bgColor: #f2f2f2; ptrSize: size(15px, 8px); textMrg: margins(16px, 5px, 16px, 15px); font: inpDefFont; @@ -446,7 +446,7 @@ countryList: countryList { color: #000; codeColor: #aaaaaa;//rgb(20, 136, 210); bgColor: #FFF; - bgHovered: #f1f1f1; + bgHovered: #f5f5f5; margin: 13px; codeWidth: 60px; @@ -873,13 +873,13 @@ mediaInSelectColor: msgInSelectDateColor; mediaOutSelectColor: msgOutSelectDateColor; mediaSaveDelta: 14px; // between bubble and download mediaSaveButton: flatButton(btnDefFlat) { - color: btnYesColor; - overColor: btnYesHover; - downColor: btnYesHover; + color: #507da2; + overColor: #507da2; + downColor: #507da2; bgColor: white; - overBgColor: btnWhiteHover; - downBgColor: btnWhiteHover; + overBgColor: #f5f8fa; + downBgColor: #f5f8fa; width: -28px; height: 34px; @@ -1074,7 +1074,7 @@ profileListPhotoSize: 46px; profileListPadding: size(12px, 6px); profileListNameTop: 8px; profileListStatusBottom: 6px; -profileHoverBG: #f1f1f1; +profileHoverBG: #f5f5f5; profileActiveBG: #6294b9; profileSubFont: font(fsize); profileCheckRect: sprite(88px, 108px, 24px, 24px); @@ -1223,7 +1223,7 @@ contactsClose: flatButton { overColor: btnYesHover; downColor: btnYesHover; - bgColor: #fffe; + bgColor: white; overBgColor: white; downBgColor: white; diff --git a/Telegram/Setup.iss b/Telegram/Setup.iss index 1175cca78..b247dac2b 100644 --- a/Telegram/Setup.iss +++ b/Telegram/Setup.iss @@ -3,9 +3,9 @@ #define MyAppShortName "Telegram" #define MyAppName "Telegram Desktop" -#define MyAppVersion "0.6.2" -#define MyAppVersionZero "0.6.2" -#define MyAppFullVersion "0.6.2.0" +#define MyAppVersion "0.6.3" +#define MyAppVersionZero "0.6.3" +#define MyAppFullVersion "0.6.3.0" #define MyAppPublisher "Telegram Messenger LLP" #define MyAppURL "https://tdesktop.com" #define MyAppExeName "Telegram.exe" diff --git a/Telegram/SignWinSetup.bat b/Telegram/SignWinSetup.bat index 052489e9e..c33f8c607 100644 --- a/Telegram/SignWinSetup.bat +++ b/Telegram/SignWinSetup.bat @@ -1,3 +1,3 @@ cd ..\Win32\Deploy -call ..\..\..\TelegramPrivate\Sign.bat tsetup.0.6.2.exe +call ..\..\..\TelegramPrivate\Sign.bat tsetup.0.6.3.exe cd ..\..\Telegram diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index 92fffe790..6a903027d 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -1116,6 +1116,17 @@ namespace App { return 0; } + void itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) { + newItem->history()->itemReplaced(oldItem, newItem); + if (App::main()) App::main()->itemReplaced(oldItem, newItem); + if (App::hoveredItem() == oldItem) App::hoveredItem(newItem); + if (App::pressedItem() == oldItem) App::pressedItem(newItem); + if (App::hoveredLinkItem() == oldItem) App::hoveredLinkItem(newItem); + if (App::pressedLinkItem() == oldItem) App::pressedLinkItem(newItem); + if (App::contextItem() == oldItem) App::contextItem(newItem); + if (App::mousedItem() == oldItem) App::mousedItem(newItem); + } + HistoryItem *historyRegItem(HistoryItem *item) { MsgsData::const_iterator i = msgsData.constFind(item->id); if (i == msgsData.cend()) { @@ -1124,10 +1135,7 @@ namespace App { return 0; } if (i.value() != item && !i.value()->block() && item->block()) { // replace search item - item->history()->itemReplaced(i.value(), item); - if (App::main()) { - emit App::main()->historyItemReplaced(i.value(), item); - } + itemReplaced(i.value(), item); delete i.value(); msgsData.insert(item->id, item); return 0; @@ -1167,9 +1175,7 @@ namespace App { } } historyItemDetached(item); - if (App::main()) { - emit App::main()->historyItemDeleted(item); - } + if (App::main()) App::main()->itemRemoved(item); } void historyClearMsgs() { @@ -1261,10 +1267,6 @@ namespace App { textlnkOver(TextLinkPtr()); textlnkDown(TextLinkPtr()); - if (completely && App::main()) { - App::main()->disconnect(SIGNAL(historyItemDeleted(HistoryItem *))); - } - histories().clear(); if (completely) { @@ -1860,7 +1862,7 @@ namespace App { bool isValidPhone(QString phone) { phone = phone.replace(QRegularExpression(qsl("[^\\d]")), QString()); - return phone.length() >= 8 || phone == qsl("777") || phone == qsl("333") || phone == qsl("42") || phone == qsl("111"); + return phone.length() >= 8 || phone == qsl("777") || phone == qsl("333") || phone == qsl("111") || (phone.startsWith(qsl("42")) && (phone.length() == 2 || phone.length() == 5)); } void quit() { diff --git a/Telegram/SourceFiles/config.h b/Telegram/SourceFiles/config.h index 43261f129..5b5758459 100644 --- a/Telegram/SourceFiles/config.h +++ b/Telegram/SourceFiles/config.h @@ -17,8 +17,8 @@ Copyright (c) 2014 John Preston, https://tdesktop.com */ #pragma once -static const int32 AppVersion = 6002; -static const wchar_t *AppVersionStr = L"0.6.2"; +static const int32 AppVersion = 6003; +static const wchar_t *AppVersionStr = L"0.6.3"; static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)"; static const wchar_t *AppName = L"Telegram Desktop"; @@ -80,7 +80,7 @@ enum { AudioVoiceMsgBufferSize = 1024 * 1024, // 1 Mb buffers AudioVoiceMsgInMemory = 1024 * 1024, // 1 Mb audio is hold in memory and auto loaded - MediaViewImageSizeLimit = 10 * 1024 * 1024, // show up to 10mb jpg/png docs in mediaview + MediaViewImageSizeLimit = 100 * 1024 * 1024, // show up to 100mb jpg/png/gif docs in app MaxZoomLevel = 7, // x8 PreloadHeightsCount = 3, // when 3 screens to scroll left make a preload request diff --git a/Telegram/SourceFiles/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp index 686179596..c95880dcb 100644 --- a/Telegram/SourceFiles/dialogswidget.cpp +++ b/Telegram/SourceFiles/dialogswidget.cpp @@ -31,8 +31,6 @@ dialogs(false), contactsNoDialogs(true), contacts(true), sel(0), contactSel(fals connect(main, SIGNAL(peerNameChanged(PeerData *, const PeerData::Names &, const PeerData::NameFirstChars &)), this, SLOT(onPeerNameChanged(PeerData *, const PeerData::Names &, const PeerData::NameFirstChars &))); connect(main, SIGNAL(peerPhotoChanged(PeerData *)), this, SLOT(onPeerPhotoChanged(PeerData *))); connect(main, SIGNAL(dialogRowReplaced(DialogRow *, DialogRow *)), this, SLOT(onDialogRowReplaced(DialogRow *, DialogRow *))); - connect(main, SIGNAL(historyItemReplaced(HistoryItem *, HistoryItem *)), this, SLOT(onItemReplaced(HistoryItem *, HistoryItem *))); - connect(main, SIGNAL(historyItemDeleted(HistoryItem *)), this, SLOT(onItemRemoved(HistoryItem *))); } void DialogsListWidget::paintEvent(QPaintEvent *e) { @@ -453,7 +451,7 @@ void DialogsListWidget::clearSearchResults() { _lastSearchId = 0; } -void DialogsListWidget::onItemReplaced(HistoryItem *oldItem, HistoryItem *newItem) { +void DialogsListWidget::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) { for (int i = 0; i < searchResults.size(); ++i) { if (searchResults[i]->_item == oldItem) { searchResults[i]->_item = newItem; @@ -461,7 +459,7 @@ void DialogsListWidget::onItemReplaced(HistoryItem *oldItem, HistoryItem *newIte } } -void DialogsListWidget::onItemRemoved(HistoryItem *item) { +void DialogsListWidget::itemRemoved(HistoryItem *item) { int wasCount = searchResults.size(); for (int i = 0; i < searchResults.size();) { if (searchResults[i]->_item == item) { @@ -1088,6 +1086,14 @@ void DialogsWidget::clearFiltered() { onCancel(); } +void DialogsWidget::itemRemoved(HistoryItem *item) { + list.itemRemoved(item); +} + +void DialogsWidget::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) { + list.itemReplaced(oldItem, newItem); +} + void DialogsWidget::unreadCountsReceived(const QVector &dialogs) { for (QVector::const_iterator i = dialogs.cbegin(), e = dialogs.cend(); i != e; ++i) { const MTPDdialog &d(i->c_dialog()); diff --git a/Telegram/SourceFiles/dialogswidget.h b/Telegram/SourceFiles/dialogswidget.h index 45b7a22ea..59d7e3b86 100644 --- a/Telegram/SourceFiles/dialogswidget.h +++ b/Telegram/SourceFiles/dialogswidget.h @@ -80,6 +80,8 @@ public: State state() const; void onFilterUpdate(QString newFilter, bool force = false); + void itemRemoved(HistoryItem *item); + void itemReplaced(HistoryItem *oldItem, HistoryItem *newItem); ~DialogsListWidget(); @@ -92,9 +94,6 @@ public slots: void onPeerPhotoChanged(PeerData *peer); void onDialogRowReplaced(DialogRow *oldRow, DialogRow *newRow); - void onItemRemoved(HistoryItem *item); - void onItemReplaced(HistoryItem *oldItem, HistoryItem *newItem); - signals: void peerChosen(const PeerId &, MsgId); @@ -177,6 +176,9 @@ public: void onSearchMore(MsgId minMsgId); void clearFiltered(); + void itemRemoved(HistoryItem *item); + void itemReplaced(HistoryItem *oldItem, HistoryItem *newItem); + signals: void peerChosen(const PeerId &, MsgId); diff --git a/Telegram/SourceFiles/gui/countryinput.cpp b/Telegram/SourceFiles/gui/countryinput.cpp index 92fb1afc3..876f6c776 100644 --- a/Telegram/SourceFiles/gui/countryinput.cpp +++ b/Telegram/SourceFiles/gui/countryinput.cpp @@ -302,7 +302,7 @@ void CountryList::paintEvent(QPaintEvent *e) { int l = countriesNow->size(); if (l) { - int from = (r.top() > _st.verticalMargin) ? (r.top() - _st.verticalMargin) / _st.rowHeight : 0, to = from + r.height() / _st.rowHeight + 1; + int from = (r.top() > _st.verticalMargin) ? (r.top() - _st.verticalMargin) / _st.rowHeight : 0, to = from + (r.height() / _st.rowHeight) + 2; if (to >= l) { if (from >= l) return; to = l; @@ -518,6 +518,12 @@ void CountrySelect::keyPressEvent(QKeyEvent *e) { } } +void CountrySelect::mousePressEvent(QMouseEvent *e) { + if (!QRect(_innerLeft, _innerTop, _innerWidth, _innerHeight).contains(e->pos())) { + onCountryCancel(); + } +} + void CountrySelect::onFilterUpdate() { QString newFilter(_filter.text().trimmed().toLower()); if (newFilter != lastFilter) { diff --git a/Telegram/SourceFiles/gui/countryinput.h b/Telegram/SourceFiles/gui/countryinput.h index a2c51a095..2bef3c789 100644 --- a/Telegram/SourceFiles/gui/countryinput.h +++ b/Telegram/SourceFiles/gui/countryinput.h @@ -121,6 +121,7 @@ public: void paintEvent(QPaintEvent *e); void keyPressEvent(QKeyEvent *e); + void mousePressEvent(QMouseEvent *e); void resizeEvent(QResizeEvent *e); bool animStep(float64 ms); diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index fe00b4f29..499f766ca 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -112,12 +112,159 @@ namespace { _historySrvOptions.dir = _textNameOptions.dir = _textDlgOptions.dir = langDir(); _textDlgOptions.maxw = st::dlgMaxWidth * 2; } + + class AnimatedGif : public Animated { + public: + + AnimatedGif() : msg(0), reader(0), w(0), h(0), frame(0), framesCount(0), duration(0) { + } + + bool animStep(float64 ms) { + int32 f = frame; + while (f < frames.size() && ms > delays[f]) { + ++f; + if (f == frames.size() && frames.size() < framesCount) { + if (reader->read(&img)) { + int64 d = reader->nextImageDelay(), delay = delays[f - 1]; + if (!d) d = 1; + delay += d; + frames.push_back(QPixmap::fromImage(img.size() == QSize(w, h) ? img : img.scaled(w, h, Qt::IgnoreAspectRatio, Qt::SmoothTransformation))); + delays.push_back(delay); + for (int32 i = 0; i < frames.size(); ++i) { + if (!frames[i].isNull()) { + frames[i] = QPixmap(); + break; + } + } + } else { + framesCount = frames.size(); + } + } + if (f == frames.size()) { + if (!duration) { + duration = delays.isEmpty() ? 1 : delays.back(); + } + + f = 0; + for (int32 i = 0, s = delays.size() - 1; i <= s; ++i) { + delays[i] += duration; + } + if (frames[f].isNull()) { + QString fname = reader->fileName(); + delete reader; + reader = new QImageReader(fname); + } + } + if (frames[f].isNull() && reader->read(&img)) { + frames[f] = QPixmap::fromImage(img.size() == QSize(w, h) ? img : img.scaled(w, h, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + } + } + if (frame != f) { + frame = f; + if (App::main()) App::main()->msgUpdated(msg->history()->peer->id, msg); + } + return true; + } + + void start(HistoryItem *row, const QString &file) { + if (reader) { + stop(); + } + reader = new QImageReader(file); + if (!reader->canRead() || !reader->supportsAnimation()) { + stop(); + return; + } + + QSize s = reader->size(); + w = s.width(); + h = s.height(); + framesCount = reader->imageCount(); + if (!w || !h || !framesCount) { + stop(); + return; + } + + frames.reserve(framesCount); + delays.reserve(framesCount); + + int32 sizeLeft = MediaViewImageSizeLimit, delay = 0; + for (bool read = reader->read(&img); read; read = reader->read(&img)) { + sizeLeft -= w * h * 4; + frames.push_back(QPixmap::fromImage(img.size() == s ? img : img.scaled(w, h, Qt::IgnoreAspectRatio, Qt::SmoothTransformation))); + int32 d = reader->nextImageDelay(); + if (!d) d = 1; + delay += d; + delays.push_back(delay); + if (sizeLeft < 0) break; + } + + msg = row; + + anim::start(this); + msg->initDimensions(); + App::main()->itemResized(msg); + } + + void stop(bool onItemRemoved = false) { + delete reader; + reader = 0; + HistoryItem *row = msg; + msg = 0; + frames.clear(); + delays.clear(); + w = h = frame = framesCount = duration = 0; + + anim::stop(this); + if (row && !onItemRemoved) { + row->initDimensions(); + if (App::main()) App::main()->itemResized(row); + } + } + + ~AnimatedGif() { + stop(); + } + + HistoryItem *msg; + QImage img; + QImageReader *reader; + QVector frames; + QVector delays; + int32 w, h, frame, framesCount, duration; + }; + + AnimatedGif animated; } void historyInit() { _initTextOptions(); } +void startGif(HistoryItem *row, const QString &file) { + if (row == animated.msg) { + stopGif(); + } else { + animated.start(row, file); + } +} + +void itemReplacedGif(HistoryItem *oldItem, HistoryItem *newItem) { + if (oldItem == animated.msg) { + animated.msg = newItem; + } +} + +void itemRemovedGif(HistoryItem *item) { + if (item == animated.msg) { + animated.stop(true); + } +} + +void stopGif() { + animated.stop(); +} + NotifySettings globalNotifyAll, globalNotifyUsers, globalNotifyChats; NotifySettingsPtr globalNotifyAllPtr = UnknownNotifySettings, globalNotifyUsersPtr = UnknownNotifySettings, globalNotifyChatsPtr = UnknownNotifySettings; @@ -428,18 +575,17 @@ void DocumentOpenLink::onClick(Qt::MouseButton button) const { QString already = data->already(true); if (!already.isEmpty()) { - bool showInMediaView = false; if (data->size < MediaViewImageSizeLimit) { - QMimeType mime = QMimeDatabase().mimeTypeForName(data->mime); - QString name = mime.name().toLower(), fname = already.toLower(); - if (name == qsl("image/jpeg") || name == qsl("image/jpg") || name == qsl("image/png")) { - showInMediaView = true; - } else if (fname.endsWith(qsl(".jpeg")) || fname.endsWith(qsl(".jpg")) || fname.endsWith(qsl(".png"))) { - showInMediaView = name.isEmpty(); + QImageReader reader(already); + if (reader.canRead()) { + if (reader.supportsAnimation() && reader.imageCount() > 1 && App::hoveredLinkItem()) { + startGif(App::hoveredLinkItem(), already); + } else { + App::wnd()->showDocument(data, QPixmap::fromImage(reader.read()), App::hoveredLinkItem()); + } + } else { + psOpenFile(already); } - } - if (showInMediaView) { - App::wnd()->showDocument(data, App::hoveredLinkItem()); } else { psOpenFile(already); } @@ -1543,8 +1689,8 @@ MsgId History::maxMsgId() const { return 0; } -int32 History::geomResize(int32 newWidth, int32 *ytransform) { - if (width != newWidth) { +int32 History::geomResize(int32 newWidth, int32 *ytransform, bool dontRecountText) { + if (width != newWidth || dontRecountText) { int32 y = 0; for (iterator i = begin(), e = end(); i != e; ++i) { HistoryBlock *block = *i; @@ -1553,7 +1699,7 @@ int32 History::geomResize(int32 newWidth, int32 *ytransform) { if (block->y != y) { block->y = y; } - y += block->geomResize(newWidth, ytransform); + y += block->geomResize(newWidth, ytransform, dontRecountText); if (updTransform) { *ytransform += block->y; ytransform = 0; @@ -1627,14 +1773,14 @@ void History::removeBlock(HistoryBlock *block) { delete block; } -int32 HistoryBlock::geomResize(int32 newWidth, int32 *ytransform) { +int32 HistoryBlock::geomResize(int32 newWidth, int32 *ytransform, bool dontRecountText) { int32 y = 0; for (iterator i = begin(), e = end(); i != e; ++i) { HistoryItem *item = *i; bool updTransform = ytransform && (*ytransform >= item->y) && (*ytransform < item->y + item->height()); if (updTransform) *ytransform -= item->y; item->y = y; - y += item->resize(newWidth); + y += item->resize(newWidth, dontRecountText); if (updTransform) { *ytransform += item->y; ytransform = 0; @@ -1894,6 +2040,10 @@ HistoryPhoto::HistoryPhoto(PeerData *chat, const MTPDphoto &photo, int32 width) } void HistoryPhoto::init() { + data->thumb->load(); +} + +void HistoryPhoto::initDimensions(const HistoryItem *parent) { int32 tw = data->full->width(), th = data->full->height(); if (!tw || !th) { tw = th = 1; @@ -1918,10 +2068,9 @@ void HistoryPhoto::init() { } _maxw = w; _height = _minh = thumbh; - data->thumb->load(); } -int32 HistoryPhoto::resize(int32 nwidth) { +int32 HistoryPhoto::resize(int32 nwidth, bool dontRecountText, const HistoryItem *parent) { return _height; } @@ -1929,7 +2078,7 @@ const QString HistoryPhoto::inDialogsText() const { return lang(lng_in_dlg_photo); } -bool HistoryPhoto::hasPoint(int32 x, int32 y, int32 width) const { +bool HistoryPhoto::hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width) const { if (width < 0) width = _maxw; return (x >= 0 && y >= 0 && x < width && y < _height); } @@ -2077,12 +2226,8 @@ HistoryVideo::HistoryVideo(const MTPDvideo &video, int32 width) : data(App::feed , _dldDone(0) , _uplDone(0) { - _maxw = st::mediaMaxWidth; - _size = formatDurationAndSizeText(data->duration, data->size); - _height = st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom(); - if (!_openWithWidth) { _downloadWidth = st::mediaSaveButton.font->m.width(lang(lng_media_download)); _openWithWidth = st::mediaSaveButton.font->m.width(lang(lng_media_open_with)); @@ -2106,15 +2251,13 @@ HistoryVideo::HistoryVideo(const MTPDvideo &video, int32 width) : data(App::feed } } -void HistoryVideo::reinit() { - _maxw = st::mediaMaxWidth; -} - void HistoryVideo::initDimensions(const HistoryItem *parent) { + _maxw = st::mediaMaxWidth; int32 tleft = st::mediaPadding.left() + st::mediaThumbSize + st::mediaPadding.right(); if (!parent->out()) { // add Download / Save As button _maxw += st::mediaSaveDelta + _buttonWidth; } + _height = _minh = st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom(); } void HistoryVideo::regItem(HistoryItem *item) { @@ -2125,7 +2268,7 @@ void HistoryVideo::unregItem(HistoryItem *item) { App::unregVideoItem(data, item); } -int32 HistoryVideo::resize(int32 nwidth) { +int32 HistoryVideo::resize(int32 nwidth, bool dontRecountText, const HistoryItem *parent) { w = nwidth; return _height; } @@ -2134,7 +2277,7 @@ const QString HistoryVideo::inDialogsText() const { return lang(lng_in_dlg_video); } -bool HistoryVideo::hasPoint(int32 x, int32 y, int32 width) const { +bool HistoryVideo::hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width) const { if (width < 0) width = w; if (width >= _maxw) { width = _maxw; @@ -2176,9 +2319,7 @@ bool HistoryVideo::getVideoCoords(VideoData *video, int32 &x, int32 &y, int32 &w } HistoryMedia *HistoryVideo::clone() const { - HistoryVideo *n = new HistoryVideo(*this); - n->reinit(); - return n; + return new HistoryVideo(*this); } void HistoryVideo::draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width) const { @@ -2292,12 +2433,8 @@ HistoryAudio::HistoryAudio(const MTPDaudio &audio, int32 width) : data(App::feed , _dldDone(0) , _uplDone(0) { - _maxw = st::mediaMaxWidth; - _size = formatDurationAndSizeText(data->duration, data->size); - _height = st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom(); - if (!_openWithWidth) { _downloadWidth = st::mediaSaveButton.font->m.width(lang(lng_media_download)); _openWithWidth = st::mediaSaveButton.font->m.width(lang(lng_media_open_with)); @@ -2306,15 +2443,14 @@ HistoryAudio::HistoryAudio(const MTPDaudio &audio, int32 width) : data(App::feed } } -void HistoryAudio::reinit() { - _maxw = st::mediaMaxWidth; -} - void HistoryAudio::initDimensions(const HistoryItem *parent) { + _maxw = st::mediaMaxWidth; int32 tleft = st::mediaPadding.left() + st::mediaThumbSize + st::mediaPadding.right(); if (!parent->out()) { // add Download / Save As button _maxw += st::mediaSaveDelta + _buttonWidth; } + + _height = _minh = st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom(); } void HistoryAudio::draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width) const { @@ -2444,7 +2580,7 @@ void HistoryAudio::unregItem(HistoryItem *item) { App::unregAudioItem(data, item); } -int32 HistoryAudio::resize(int32 nwidth) { +int32 HistoryAudio::resize(int32 nwidth, bool dontRecountText, const HistoryItem *parent) { w = nwidth; return _height; } @@ -2453,7 +2589,7 @@ const QString HistoryAudio::inDialogsText() const { return lang(lng_in_dlg_audio); } -bool HistoryAudio::hasPoint(int32 x, int32 y, int32 width) const { +bool HistoryAudio::hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width) const { if (width < 0) width = w; if (width >= _maxw) { width = _maxw; @@ -2485,9 +2621,7 @@ TextLinkPtr HistoryAudio::getLink(int32 x, int32 y, const HistoryItem *parent, i } HistoryMedia *HistoryAudio::clone() const { - HistoryAudio *n = new HistoryAudio(*this); - n->reinit(); - return n; + return new HistoryAudio(*this); } HistoryDocument::HistoryDocument(const MTPDdocument &document, int32 width) : data(App::feedDocument(document)) @@ -2499,12 +2633,11 @@ HistoryDocument::HistoryDocument(const MTPDdocument &document, int32 width) : da , _dldDone(0) , _uplDone(0) { - _maxw = st::mediaMaxWidth; _namew = st::mediaFont->m.width(_name.isEmpty() ? qsl("Document") : _name); _size = formatSizeText(data->size); - _height = st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom(); + _height = _minh = st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom(); if (!_openWithWidth) { _downloadWidth = st::mediaSaveButton.font->m.width(lang(lng_media_download)); @@ -2529,17 +2662,21 @@ HistoryDocument::HistoryDocument(const MTPDdocument &document, int32 width) : da } } -void HistoryDocument::reinit() { - _maxw = st::mediaMaxWidth; -} - void HistoryDocument::initDimensions(const HistoryItem *parent) { - int32 tleft = st::mediaPadding.left() + st::mediaThumbSize + st::mediaPadding.right(); - if (_namew + tleft + st::mediaPadding.right() > _maxw) { - _maxw = _namew + tleft + st::mediaPadding.right(); - } - if (!parent->out()) { // add Download / Save As button - _maxw += st::mediaSaveDelta + _buttonWidth; + if (parent == animated.msg) { + _maxw = animated.w; + _minh = animated.h; + _height = resize(w, true, parent); + } else { + _maxw = st::mediaMaxWidth; + int32 tleft = st::mediaPadding.left() + st::mediaThumbSize + st::mediaPadding.right(); + if (_namew + tleft + st::mediaPadding.right() > _maxw) { + _maxw = _namew + tleft + st::mediaPadding.right(); + } + if (!parent->out()) { // add Download / Save As button + _maxw += st::mediaSaveDelta + _buttonWidth; + } + _height = _minh = st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom(); } } @@ -2547,9 +2684,29 @@ void HistoryDocument::draw(QPainter &p, const HistoryItem *parent, bool selected if (width < 0) width = w; if (width < 1) return; + bool out = parent->out(), hovered, pressed; + if (parent == animated.msg) { + if (width >= animated.w) { + p.drawPixmap(0, 0, animated.frames[animated.frame]); + if (selected) { + p.fillRect(0, 0, animated.w, animated.h, (out ? st::msgOutSelectOverlay : st::msgInSelectOverlay)->b); + } + } else { + bool s = p.renderHints().testFlag(QPainter::SmoothPixmapTransform); + if (!s) p.setRenderHint(QPainter::SmoothPixmapTransform); + int32 h = (width == w) ? _height : (width * animated.h / animated.w); + if (h < 1) h = 1; + p.drawPixmap(QRect(0, 0, width, h), animated.frames[animated.frame]); + if (!s) p.setRenderHint(QPainter::SmoothPixmapTransform, false); + if (selected) { + p.fillRect(0, 0, width, h, (out ? st::msgOutSelectOverlay : st::msgInSelectOverlay)->b); + } + } + return; + } + data->thumb->checkload(); - bool out = parent->out(), hovered, pressed; if (width >= _maxw) { width = _maxw; } @@ -2664,8 +2821,15 @@ void HistoryDocument::updateFrom(const MTPMessageMedia &media) { } } -int32 HistoryDocument::resize(int32 width) { +int32 HistoryDocument::resize(int32 width, bool dontRecountText, const HistoryItem *parent) { w = width; + if (parent == animated.msg) { + _height = animated.h; + if (animated.w > w) { + _height = (w * _height / animated.w); + if (_height <= 0) _height = 1; + } + } return _height; } @@ -2673,14 +2837,32 @@ const QString HistoryDocument::inDialogsText() const { return data->name.isEmpty() ? lang(lng_in_dlg_document) : data->name; } -bool HistoryDocument::hasPoint(int32 x, int32 y, int32 width) const { +bool HistoryDocument::hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width) const { if (width < 0) width = w; if (width >= _maxw) { width = _maxw; } + if (parent == animated.msg) { + int32 h = (width == w) ? _height : (width * animated.h / animated.w); + if (h < 1) h = 1; + return (x >= 0 && y >= 0 && x < width && y < h); + } return (x >= 0 && y >= 0 && x < width && y < _height); } +int32 HistoryDocument::countHeight(const HistoryItem *parent, int32 width) const { + if (width < 0) width = w; + if (width >= _maxw) { + width = _maxw; + } + if (parent == animated.msg) { + int32 h = (width == w) ? _height : (width * animated.h / animated.w); + if (h < 1) h = 1; + return h; + } + return _height; +} + TextLinkPtr HistoryDocument::getLink(int32 x, int32 y, const HistoryItem *parent, int32 width) const { if (width < 0) width = w; if (width < 1) return TextLinkPtr(); @@ -2689,6 +2871,11 @@ TextLinkPtr HistoryDocument::getLink(int32 x, int32 y, const HistoryItem *parent if (width >= _maxw) { width = _maxw; } + if (parent == animated.msg) { + int32 h = (width == w) ? _height : (width * animated.h / animated.w); + if (h < 1) h = 1; + return (x >= 0 && y >= 0 && x < width && y < h) ? _openl : TextLinkPtr(); + } if (!out) { // draw Download / Save As button int32 btnw = _buttonWidth, btnh = st::mediaSaveButton.height, btnx = width - _buttonWidth, btny = (_height - btnh) / 2; @@ -2705,9 +2892,7 @@ TextLinkPtr HistoryDocument::getLink(int32 x, int32 y, const HistoryItem *parent } HistoryMedia *HistoryDocument::clone() const { - HistoryDocument *n = new HistoryDocument(*this); - n->reinit(); - return n; + return new HistoryDocument(*this); } HistoryContact::HistoryContact(int32 userId, const QString &first, const QString &last, const QString &phone) : userId(userId) @@ -2743,7 +2928,7 @@ void HistoryContact::initDimensions(const HistoryItem *parent) { } } -int32 HistoryContact::resize(int32 nwidth) { +int32 HistoryContact::resize(int32 nwidth, bool dontRecountText, const HistoryItem *parent) { w = nwidth; return _height; } @@ -2752,7 +2937,7 @@ const QString HistoryContact::inDialogsText() const { return lang(lng_in_dlg_contact); } -bool HistoryContact::hasPoint(int32 x, int32 y, int32 width) const { +bool HistoryContact::hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width) const { if (width < 0) width = w; return (x >= 0 && y <= 0 && x < w && y < _height); } @@ -2948,13 +3133,19 @@ void HistoryMessage::initMedia(const MTPMessageMedia &media, QString ¤tTex void HistoryMessage::initDimensions(const QString &text) { _time = date.toString(qsl("hh:mm")); _timeWidth = st::msgDateFont->m.width(_time); + if (!_media) { + _timeWidth += st::msgDateSpace + (out() ? st::msgDateCheckSpace + st::msgCheckRect.pxWidth() : 0) - st::msgDateDelta.x(); + _text.setText(st::msgFont, text + textcmdSkipBlock(_timeWidth, st::msgDateFont->height - st::msgDateDelta.y()), _historyTextOptions); + } + initDimensions(); +} + +void HistoryMessage::initDimensions(const HistoryItem *parent) { if (_media) { _media->initDimensions(this); _maxw = _media->maxWidth(); _minh = _media->height(); } else { - _timeWidth += st::msgDateSpace + (out() ? st::msgDateCheckSpace + st::msgCheckRect.pxWidth() : 0) - st::msgDateDelta.x(); - _text.setText(st::msgFont, text + textcmdSkipBlock(_timeWidth, st::msgDateFont->height - st::msgDateDelta.y()), _historyTextOptions); _maxw = _text.maxWidth(); _minh = _text.minHeight(); _maxw += st::msgPadding.left() + st::msgPadding.right(); @@ -3081,11 +3272,13 @@ void HistoryMessage::drawMessageText(QPainter &p, const QRect &trect, uint32 sel textstyleRestore(); } -int32 HistoryMessage::resize(int32 width) { +int32 HistoryMessage::resize(int32 width, bool dontRecountText, const HistoryItem *parent) { width -= st::msgMargin.left() + st::msgMargin.right(); if (_media) { - _height = _media->resize(width); + _height = _media->resize(width, dontRecountText, this); } else { + if (dontRecountText) return _height; + if (width < st::msgPadding.left() + st::msgPadding.right() + 1) { width = st::msgPadding.left() + st::msgPadding.right() + 1; } else if (width > st::msgMaxWidth) { @@ -3127,7 +3320,7 @@ bool HistoryMessage::hasPoint(int32 x, int32 y) const { width = _maxw; } if (_media) { - return _media->hasPoint(x - left, y - st::msgMargin.top()); + return _media->hasPoint(x - left, y - st::msgMargin.top(), this); } QRect r(left, st::msgMargin.top(), width, _height - st::msgMargin.top() - st::msgMargin.bottom()); return r.contains(x, y); @@ -3365,9 +3558,9 @@ void HistoryForwarded::drawMessageText(QPainter &p, const QRect &trect, uint32 s HistoryMessage::drawMessageText(p, realtrect, selection); } -int32 HistoryForwarded::resize(int32 width) { - HistoryMessage::resize(width); - if (!_media) { +int32 HistoryForwarded::resize(int32 width, bool dontRecountText, const HistoryItem *parent) { + HistoryMessage::resize(width, dontRecountText, parent); + if (!_media && !dontRecountText) { int32 h1 = 0, h2 = st::msgServiceNameFont->height; _height += h1 + (h1 > h2 ? h1 : h2); } @@ -3558,8 +3751,7 @@ HistoryServiceMsg::HistoryServiceMsg(History *history, HistoryBlock *block, cons if (second) { _text.setLink(2, second); } - _maxw = _text.maxWidth() + st::msgServicePadding.left() + st::msgServicePadding.right(); - _minh = _text.minHeight(); + initDimensions(); } /* HistoryServiceMsg::HistoryServiceMsg(History *history, HistoryBlock *block, const MTPDgeoChatMessageService &msg) : @@ -3577,8 +3769,13 @@ HistoryServiceMsg::HistoryServiceMsg(History *history, HistoryBlock *block, MsgI , _text(st::msgServiceFont, msg, _historySrvOptions, st::dlgMinWidth) , _media(media) { + initDimensions(); +} + +void HistoryServiceMsg::initDimensions(const HistoryItem *parent) { _maxw = _text.maxWidth() + st::msgServicePadding.left() + st::msgServicePadding.right(); _minh = _text.minHeight(); + if (_media) _media->initDimensions(); } QString HistoryServiceMsg::selectedText(uint32 selection) const { @@ -3626,7 +3823,9 @@ void HistoryServiceMsg::draw(QPainter &p, uint32 selection) const { textstyleRestore(); } -int32 HistoryServiceMsg::resize(int32 width) { +int32 HistoryServiceMsg::resize(int32 width, bool dontRecountText, const HistoryItem *parent) { + if (dontRecountText) return _height; + width -= st::msgServiceMargin.left() + st::msgServiceMargin.left(); // two small margins if (width < st::msgServicePadding.left() + st::msgServicePadding.right() + 1) width = st::msgServicePadding.left() + st::msgServicePadding.right() + 1; @@ -3741,6 +3940,10 @@ HistoryItem *createDayServiceMsg(History *history, HistoryBlock *block, QDateTim HistoryUnreadBar::HistoryUnreadBar(History *history, HistoryBlock *block, int32 count, const QDateTime &date) : HistoryItem(history, block, clientMsgId(), false, false, date, 0), freezed(false) { setCount(count); + initDimensions(); +} + +void HistoryUnreadBar::initDimensions(const HistoryItem *parent) { _maxw = st::msgPadding.left() + st::msgPadding.right() + 1; _minh = st::unreadBarHeight; } @@ -3759,7 +3962,7 @@ void HistoryUnreadBar::draw(QPainter &p, uint32 selection) const { p.drawText(QRect(0, 0, _history->width, st::unreadBarHeight - st::lineWidth), text, style::al_center); } -int32 HistoryUnreadBar::resize(int32 width) { +int32 HistoryUnreadBar::resize(int32 width, bool dontRecountText, const HistoryItem *parent) { _height = st::unreadBarHeight; return _height; } diff --git a/Telegram/SourceFiles/history.h b/Telegram/SourceFiles/history.h index 1c6f9af8a..7f53a0e5a 100644 --- a/Telegram/SourceFiles/history.h +++ b/Telegram/SourceFiles/history.h @@ -27,6 +27,12 @@ typedef int32 MsgId; void historyInit(); class HistoryItem; + +void startGif(HistoryItem *row, const QString &file); +void itemRemovedGif(HistoryItem *item); +void itemReplacedGif(HistoryItem *oldItem, HistoryItem *newItem); +void stopGif(); + static const uint32 FullItemSel = 0xFFFFFFFF; typedef QMap SelectedItemSet; @@ -692,7 +698,7 @@ struct History : public QList { MsgId minMsgId() const; MsgId maxMsgId() const; - int32 geomResize(int32 newWidth, int32 *ytransform = 0); // return new size + int32 geomResize(int32 newWidth, int32 *ytransform = 0, bool dontRecountText = false); // return new size int32 width, height, msgCount, unreadCount; int32 inboxReadTill, outboxReadTill; HistoryItem *showFrom; @@ -1066,7 +1072,7 @@ struct HistoryBlock : public QVector { } void removeItem(HistoryItem *item); - int32 geomResize(int32 newWidth, int32 *ytransform); // return new size + int32 geomResize(int32 newWidth, int32 *ytransform, bool dontRecountText); // return new size int32 y, height; History *history; }; @@ -1077,7 +1083,8 @@ public: HistoryElem() : _height(0), _maxw(0) { } - virtual int32 resize(int32 width) = 0; // return new height + virtual void initDimensions(const HistoryItem *parent = 0) = 0; + virtual int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0) = 0; // return new height int32 height() const { return _height; @@ -1230,12 +1237,12 @@ HistoryItem *regItem(HistoryItem *item, bool returnExisting = false); class HistoryMedia : public HistoryElem { public: - virtual void initDimensions(const HistoryItem *parent) { - } - virtual HistoryMediaType type() const = 0; virtual const QString inDialogsText() const = 0; - virtual bool hasPoint(int32 x, int32 y, int32 width = -1) const = 0; + virtual bool hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const = 0; + virtual int32 countHeight(const HistoryItem *parent, int32 width = -1) const { + return height(); + } virtual TextLinkPtr getLink(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const = 0; virtual void draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width = -1) const = 0; virtual bool getPhotoCoords(PhotoData *photo, int32 &x, int32 &y, int32 &w) const { @@ -1271,14 +1278,15 @@ public: HistoryPhoto(PeerData *chat, const MTPDphoto &photo, int32 width = 0); void init(); + void initDimensions(const HistoryItem *parent); void draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width = -1) const; - int32 resize(int32 width); + int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0); HistoryMediaType type() const { return MediaTypePhoto; } const QString inDialogsText() const; - bool hasPoint(int32 x, int32 y, int32 width = -1) 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; bool getPhotoCoords(PhotoData *photo, int32 &x, int32 &y, int32 &w) const; HistoryMedia *clone() const; @@ -1308,16 +1316,15 @@ class HistoryVideo : public HistoryMedia { public: HistoryVideo(const MTPDvideo &video, int32 width = 0); - void reinit(); void initDimensions(const HistoryItem *parent); void draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width = -1) const; - int32 resize(int32 width); + int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0); HistoryMediaType type() const { return MediaTypeVideo; } const QString inDialogsText() const; - bool hasPoint(int32 x, int32 y, int32 width = -1) 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; bool getVideoCoords(VideoData *video, int32 &x, int32 &y, int32 &w) const; bool uploading() const { @@ -1344,16 +1351,15 @@ class HistoryAudio : public HistoryMedia { public: HistoryAudio(const MTPDaudio &audio, int32 width = 0); - void reinit(); void initDimensions(const HistoryItem *parent); void draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width = -1) const; - int32 resize(int32 width); + int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0); HistoryMediaType type() const { return MediaTypeAudio; } const QString inDialogsText() const; - bool hasPoint(int32 x, int32 y, int32 width = -1) 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; bool uploading() const { return (data->status == FileUploading); @@ -1378,16 +1384,16 @@ class HistoryDocument : public HistoryMedia { public: HistoryDocument(const MTPDdocument &document, int32 width = 0); - void reinit(); void initDimensions(const HistoryItem *parent); void draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width = -1) const; - int32 resize(int32 width); + int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0); HistoryMediaType type() const { return MediaTypeDocument; } const QString inDialogsText() const; - bool hasPoint(int32 x, int32 y, int32 width = -1) const; + bool hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const; + int32 countHeight(const HistoryItem *parent, int32 width = -1) const; bool uploading() const { return (data->status == FileUploading); } @@ -1424,12 +1430,12 @@ public: void initDimensions(const HistoryItem *parent); void draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width) const; - int32 resize(int32 width); + int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0); HistoryMediaType type() const { return MediaTypeContact; } const QString inDialogsText() const; - bool hasPoint(int32 x, int32 y, int32 width) const; + bool hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width) const; TextLinkPtr getLink(int32 x, int32 y, const HistoryItem *parent, int32 width) const; HistoryMedia *clone() const; @@ -1453,6 +1459,7 @@ public: HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, bool out, bool unread, QDateTime date, int32 from, const QString &msg, HistoryMedia *media); void initMedia(const MTPMessageMedia &media, QString ¤tText); + void initDimensions(const HistoryItem *parent = 0); void initDimensions(const QString &text); void fromNameUpdated() const; @@ -1461,7 +1468,7 @@ public: void draw(QPainter &p, uint32 selection) const; virtual void drawMessageText(QPainter &p, const QRect &trect, uint32 selection) const; - int32 resize(int32 width); + int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0); bool hasPoint(int32 x, int32 y) const; void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y) const; void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const; @@ -1516,7 +1523,7 @@ public: void draw(QPainter &p, uint32 selection) const; void drawMessageText(QPainter &p, const QRect &trect, uint32 selection) const; - int32 resize(int32 width); + int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0); bool hasPoint(int32 x, int32 y) const; void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y) const; void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const; @@ -1546,8 +1553,10 @@ public: // HistoryServiceMsg(History *history, HistoryBlock *block, const MTPDgeoChatMessageService &msg); HistoryServiceMsg(History *history, HistoryBlock *block, MsgId msgId, QDateTime date, const QString &msg, bool out = false, bool unread = false, HistoryMedia *media = 0); + void initDimensions(const HistoryItem *parent = 0); + void draw(QPainter &p, uint32 selection) const; - int32 resize(int32 width); + int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0); bool hasPoint(int32 x, int32 y) const; void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y) const; void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const; @@ -1613,10 +1622,12 @@ public: HistoryUnreadBar(History *history, HistoryBlock *block, int32 count, const QDateTime &date); + void initDimensions(const HistoryItem *parent = 0); + void setCount(int32 count); void draw(QPainter &p, uint32 selection) const; - int32 resize(int32 width); + int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0); void drawInDialog(QPainter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const; QString notificationText() const; diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 260334756..1ba5b1d46 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -451,8 +451,6 @@ void HistoryList::dragActionStart(const QPoint &screenPos, Qt::MouseButton butto _dragAction = NoDrag; } else if (_dragAction == NoDrag) { _dragItem = 0; - } else { - connect(App::main(), SIGNAL(historyItemDeleted(HistoryItem*)), this, SLOT(itemRemoved(HistoryItem*)), Qt::UniqueConnection); } } @@ -460,6 +458,7 @@ void HistoryList::dragActionCancel() { _dragItem = 0; _dragAction = NoDrag; _dragStartPos = QPoint(0, 0); + _dragSelFrom = _dragSelTo = 0; historyWidget->noSelectingScroll(); } @@ -481,6 +480,20 @@ void HistoryList::itemRemoved(HistoryItem *item) { updateDragSelection(_dragSelFrom, _dragSelTo, _dragSelecting, true); } +void HistoryList::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) { + if (_dragItem == oldItem) _dragItem = newItem; + + SelectedItems::iterator i = _selected.find(oldItem); + if (i != _selected.cend()) { + uint32 v = i.value(); + _selected.erase(i); + _selected.insert(newItem, v); + } + + if (_dragSelFrom == oldItem) _dragSelFrom = newItem; + if (_dragSelTo == oldItem) _dragSelTo = newItem; +} + void HistoryList::dragActionFinish(const QPoint &screenPos, Qt::MouseButton button) { TextLinkPtr needClick; @@ -506,6 +519,8 @@ void HistoryList::dragActionFinish(const QPoint &screenPos, Qt::MouseButton butt } if (needClick) { needClick->onClick(button); + dragActionCancel(); + return; } if (_dragAction == PrepareSelect && !needClick && !_dragWasInactive && !_selected.isEmpty() && _selected.cbegin().value() == FullItemSel) { SelectedItems::iterator i = _selected.find(_dragItem); @@ -882,9 +897,9 @@ void HistoryList::keyPressEvent(QKeyEvent *e) { } } -int32 HistoryList::recountHeight() { +int32 HistoryList::recountHeight(bool dontRecountText) { int32 st = hist->lastScrollTop; - hist->geomResize(scrollArea->width(), &st); + hist->geomResize(scrollArea->width(), &st, dontRecountText); return st; } @@ -1006,7 +1021,7 @@ void HistoryList::fillSelectedItems(SelectedItemSet &sel, bool forDelete) { for (SelectedItems::const_iterator i = _selected.cbegin(), e = _selected.cend(); i != e; ++i) { HistoryItem *item = i.key(); if (item->itemType() == HistoryItem::MsgType && ((item->id > 0 && !item->serviceMsg()) || forDelete)) { - sel.insert(item->y + item->block()->y, item); + sel.insert(item->id, item); } } } @@ -1685,6 +1700,7 @@ void HistoryWidget::showPeer(const PeerId &peer, MsgId msgId, bool force, bool l } updateTyping(false); } + stopGif(); clearLoadingAround(); if (_list) { @@ -2944,7 +2960,19 @@ void HistoryWidget::resizeEvent(QResizeEvent *e) { } } -void HistoryWidget::updateListSize(int32 addToY, bool initial, bool loadedDown) { +void HistoryWidget::itemRemoved(HistoryItem *item) { + if (_list) _list->itemRemoved(item); +} + +void HistoryWidget::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) { + if (_list) _list->itemReplaced(oldItem, newItem); +} + +void HistoryWidget::itemResized(HistoryItem *row) { + updateListSize(0, false, false, row); +} + +void HistoryWidget::updateListSize(int32 addToY, bool initial, bool loadedDown, HistoryItem *resizedItem) { if (!hist || (!_histInited && !initial)) return; if (!App::wnd()->isVisible()) return; // scrollTopMax etc are not working after recountHeight() @@ -2959,12 +2987,22 @@ void HistoryWidget::updateListSize(int32 addToY, bool initial, bool loadedDown) if (!initial) { hist->lastScrollTop = _scroll.scrollTop(); } - int32 newSt = _list->recountHeight(); + int32 newSt = _list->recountHeight(!!resizedItem); bool washidden = _scroll.isHidden(); if (washidden) { _scroll.show(); } _list->updateSize(); + if (resizedItem && !resizedItem->detached()) { + int32 firstItemY = _list->height() - hist->height - st::historyPadding; + if (newSt + _scroll.height() < firstItemY + resizedItem->block()->y + resizedItem->y + resizedItem->height()) { + newSt = firstItemY + resizedItem->block()->y + resizedItem->y + resizedItem->height() - _scroll.height(); + } + if (newSt > firstItemY + resizedItem->block()->y + resizedItem->y) { + newSt = firstItemY + resizedItem->block()->y + resizedItem->y; + } + wasAtBottom = false; + } if (washidden) { _scroll.hide(); } diff --git a/Telegram/SourceFiles/historywidget.h b/Telegram/SourceFiles/historywidget.h index e8f042f1f..86581e335 100644 --- a/Telegram/SourceFiles/historywidget.h +++ b/Telegram/SourceFiles/historywidget.h @@ -63,7 +63,7 @@ public: void touchScrollUpdated(const QPoint &screenPos); QPoint mapMouseToItem(QPoint p, HistoryItem *item); - int32 recountHeight(); + int32 recountHeight(bool dontRecountText); void updateSize(); void updateMsg(const HistoryItem *msg); @@ -76,6 +76,9 @@ public: void fillSelectedItems(SelectedItemSet &sel, bool forDelete = true); void selectItem(HistoryItem *item); + void itemRemoved(HistoryItem *item); + void itemReplaced(HistoryItem *oldItem, HistoryItem *newItem); + ~HistoryList(); public slots: @@ -85,8 +88,6 @@ public slots: void showLinkTip(); - void itemRemoved(HistoryItem *item); - void openContextUrl(); void copyContextUrl(); void saveContextImage(); @@ -333,6 +334,9 @@ public: void stopAnimActive(); void fillSelectedItems(SelectedItemSet &sel, bool forDelete = true); + void itemRemoved(HistoryItem *item); + void itemReplaced(HistoryItem *oldItem, HistoryItem *newItem); + void itemResized(HistoryItem *item); ~HistoryWidget(); @@ -392,7 +396,7 @@ public slots: private: bool messagesFailed(const RPCError &error, mtpRequestId requestId); - void updateListSize(int32 addToY = 0, bool initial = false, bool loadedDown = false); + void updateListSize(int32 addToY = 0, bool initial = false, bool loadedDown = false, HistoryItem *resizedItem = 0); void addMessagesToFront(const QVector &messages); void addMessagesToBack(const QVector &messages); void chatLoaded(const MTPmessages_ChatFull &res); diff --git a/Telegram/SourceFiles/layerwidget.cpp b/Telegram/SourceFiles/layerwidget.cpp index d44fca34d..e969f4d4a 100644 --- a/Telegram/SourceFiles/layerwidget.cpp +++ b/Telegram/SourceFiles/layerwidget.cpp @@ -57,6 +57,7 @@ void BackgroundWidget::keyPressEvent(QKeyEvent *e) { } void BackgroundWidget::mousePressEvent(QMouseEvent *e) { + onClose(); } void BackgroundWidget::onClose() { diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index ac648b70e..0b88d5cd4 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -698,6 +698,31 @@ void MainWidget::changingMsgId(HistoryItem *row, MsgId newId) { if (overview) overview->changingMsgId(row, newId); } +void MainWidget::itemRemoved(HistoryItem *item) { + dialogs.itemRemoved(item); + if (history.peer() == item->history()->peer) { + history.itemRemoved(item); + } + itemRemovedGif(item); +} + +void MainWidget::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) { + dialogs.itemReplaced(oldItem, newItem); + if (history.peer() == newItem->history()->peer) { + history.itemReplaced(oldItem, newItem); + } + itemReplacedGif(oldItem, newItem); +} + +void MainWidget::itemResized(HistoryItem *row) { + if (history.peer() == row->history()->peer && !row->detached()) { + history.itemResized(row); + } + if (overview) { + overview->itemResized(row); + } +} + bool MainWidget::overviewFailed(PeerData *peer, const RPCError &error, mtpRequestId req) { MediaOverviewType type = OverviewCount; for (int32 i = 0; i < OverviewCount; ++i) { @@ -907,18 +932,18 @@ void MainWidget::documentLoadProgress(mtpFileLoader *loader) { document->finish(); QString already = document->already(); if (!already.isEmpty() && document->openOnSave) { - bool showInMediaView = false; if (document->openOnSave > 0 && document->size < MediaViewImageSizeLimit) { - QMimeType mime = QMimeDatabase().mimeTypeForName(document->mime); - QString name = mime.name().toLower(), fname = already.toLower();; - if (name == qsl("image/jpeg") || name == qsl("image/png")) { - showInMediaView = true; - } else if (fname.endsWith(qsl(".jpeg")) || fname.endsWith(qsl(".jpg")) || fname.endsWith(qsl(".png"))) { - showInMediaView = name.isEmpty(); + QImageReader reader(already); + if (reader.canRead()) { + HistoryItem *item = App::histItemById(document->openOnSaveMsgId); + if (reader.supportsAnimation() && reader.imageCount() > 1 && item) { + startGif(item, already); + } else { + App::wnd()->showDocument(document, QPixmap::fromImage(reader.read()), item); + } + } else { + psOpenFile(already); } - } - if (showInMediaView) { - App::wnd()->showDocument(document, App::histItemById(document->openOnSaveMsgId)); } else { psOpenFile(already, document->openOnSave < 0); } diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 25e2cff20..1a147fbf8 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -277,6 +277,9 @@ public: void preloadOverviews(PeerData *peer); void mediaOverviewUpdated(PeerData *peer); void changingMsgId(HistoryItem *row, MsgId newId); + void itemRemoved(HistoryItem *item); + void itemReplaced(HistoryItem *oldItem, HistoryItem *newItem); + void itemResized(HistoryItem *row); void loadMediaBack(PeerData *peer, MediaOverviewType type, bool many = false); @@ -288,10 +291,8 @@ signals: void peerNameChanged(PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars); void peerPhotoChanged(PeerData *peer); void dialogRowReplaced(DialogRow *oldRow, DialogRow *newRow); - void historyItemReplaced(HistoryItem *oldItem, HistoryItem *newItem); void dialogToTop(const History::DialogLinks &links); void dialogsUpdated(); - void historyItemDeleted(HistoryItem *item); public slots: diff --git a/Telegram/SourceFiles/mediaview.cpp b/Telegram/SourceFiles/mediaview.cpp index 8f7f841b7..aa62c1a57 100644 --- a/Telegram/SourceFiles/mediaview.cpp +++ b/Telegram/SourceFiles/mediaview.cpp @@ -329,7 +329,7 @@ void MediaView::showPhoto(PhotoData *photo, PeerData *context) { preloadPhotos(0); } -void MediaView::showDocument(DocumentData *doc, HistoryItem *context) { +void MediaView::showDocument(DocumentData *doc, QPixmap pix, HistoryItem *context) { _photo = 0; _history = context ? context->history() : 0; _peer = 0; @@ -350,7 +350,7 @@ void MediaView::showDocument(DocumentData *doc, HistoryItem *context) { setCursor(style::cur_default); QString name = doc->already(); - _current = name.isEmpty() ? QPixmap() : QPixmap(name); + _current = pix; _current.setDevicePixelRatio(cRetinaFactor()); _doc = doc; _down = OverNone; diff --git a/Telegram/SourceFiles/mediaview.h b/Telegram/SourceFiles/mediaview.h index 8e4c81317..cdf3c221b 100644 --- a/Telegram/SourceFiles/mediaview.h +++ b/Telegram/SourceFiles/mediaview.h @@ -41,7 +41,7 @@ public: void showPhoto(PhotoData *photo, HistoryItem *context); void showPhoto(PhotoData *photo, PeerData *context); - void showDocument(DocumentData *doc, HistoryItem *context); + void showDocument(DocumentData *doc, QPixmap pix, HistoryItem *context); void moveToScreen(); void moveToPhoto(int32 delta); void preloadPhotos(int32 delta); diff --git a/Telegram/SourceFiles/overviewwidget.cpp b/Telegram/SourceFiles/overviewwidget.cpp index 0e6d44ec2..3c78540c1 100644 --- a/Telegram/SourceFiles/overviewwidget.cpp +++ b/Telegram/SourceFiles/overviewwidget.cpp @@ -174,7 +174,7 @@ bool OverviewInner::itemHasPoint(MsgId msgId, int32 index, int32 x, int32 y) con if (!out && _hist->peer->chat) { left += st::msgPhotoSkip; } - return media->hasPoint(x - left, y - st::msgMargin.top(), w); + return media->hasPoint(x - left, y - st::msgMargin.top(), item, w); } } return false; @@ -235,7 +235,8 @@ void OverviewInner::updateMsg(MsgId itemId, int32 itemIndex) { } else { HistoryItem *item = App::histItemById(itemId); HistoryMedia *media = item ? item->getMedia(true) : 0; - if (media) update(0, _addToY + _height - _items[itemIndex].y, _width, media->height() + st::msgMargin.top() + st::msgMargin.bottom()); + int32 w = _width - st::msgMargin.left() - st::msgMargin.right(); + if (media) update(0, _addToY + _height - _items[itemIndex].y, _width, media->countHeight(item, w) + st::msgMargin.top() + st::msgMargin.bottom()); } } } @@ -405,8 +406,6 @@ void OverviewInner::dragActionStart(const QPoint &screenPos, Qt::MouseButton but _dragAction = NoDrag; } else if (_dragAction == NoDrag) { _dragItem = 0; - } else { - connect(App::main(), SIGNAL(historyItemDeleted(HistoryItem*)), this, SLOT(itemRemoved(HistoryItem*)), Qt::UniqueConnection); } } @@ -414,6 +413,8 @@ void OverviewInner::dragActionCancel() { _dragItem = 0; _dragItemIndex = -1; _dragAction = NoDrag; + _dragSelFrom = _dragSelTo = 0; + _dragSelFromIndex = _dragSelToIndex = -1; _dragStartPos = QPoint(0, 0); _overview->noSelectingScroll(); } @@ -439,6 +440,8 @@ void OverviewInner::dragActionFinish(const QPoint &screenPos, Qt::MouseButton bu } if (needClick) { needClick->onClick(button); + dragActionCancel(); + return; } if (_dragAction == PrepareSelect && !needClick && !_dragWasInactive && !_selected.isEmpty() && _selected.cbegin().value() == FullItemSel) { SelectedItems::iterator i = _selected.find(_dragItem); @@ -691,7 +694,7 @@ void OverviewInner::paintEvent(QPaintEvent *e) { bool out = item->out(); int32 mw = media->maxWidth(), left = (out ? st::msgMargin.right() : st::msgMargin.left()) + (out && mw < w ? (w - mw) : 0); if (!out && _hist->peer->chat) { - p.drawPixmap(left, media->height() - st::msgPhotoSize, item->from()->photo->pix(st::msgPhotoSize)); + p.drawPixmap(left, media->countHeight(item, w) - st::msgPhotoSize, item->from()->photo->pix(st::msgPhotoSize)); left += st::msgPhotoSkip; } @@ -823,7 +826,7 @@ void OverviewInner::onUpdateSelected() { bool out = item->out(); int32 mw = media->maxWidth(), left = (out ? st::msgMargin.right() : st::msgMargin.left()) + (out && mw < w ? (w - mw) : 0); if (!out && _hist->peer->chat) { - if (QRect(left, y + st::msgMargin.top() + media->height() - st::msgPhotoSize, st::msgPhotoSize, st::msgPhotoSize).contains(m)) { + if (QRect(left, y + st::msgMargin.top() + media->countHeight(item, w) - st::msgPhotoSize, st::msgPhotoSize, st::msgPhotoSize).contains(m)) { lnk = item->from()->lnk; } left += st::msgPhotoSkip; @@ -1334,7 +1337,8 @@ void OverviewInner::mediaOverviewUpdated() { } else { prevDate = date; } - y += media->height() + st::msgMargin.top() + st::msgMargin.bottom(); // item height + int32 w = _width - st::msgMargin.left() - st::msgMargin.right(); + y += media->countHeight(item, w) + st::msgMargin.top() + st::msgMargin.bottom(); // item height if (_items.size() > in) { _items[in].msgid = msgid; _items[in].date = date; @@ -1420,6 +1424,40 @@ void OverviewInner::itemRemoved(HistoryItem *item) { parentWidget()->update(); } +void OverviewInner::itemResized(HistoryItem *item) { + if (_type != OverviewPhotos) { + HistoryMedia *media = item ? item->getMedia(true) : 0; + if (!media) return; + + for (int32 i = 0, l = _items.size(); i < l; ++i) { + if (_items[i].msgid == item->id) { + int32 from = 0; + if (i > 0) from = _items[i - 1].y; + + int32 oldh = _items[i].y - from; + int32 w = _width - st::msgMargin.left() - st::msgMargin.right(); + int32 newh = media->countHeight(item, w) + st::msgMargin.top() + st::msgMargin.bottom(); // item height + if (oldh != newh) { + newh -= oldh; + for (int32 j = i; j < l; ++j) { + _items[j].y += newh; + } + _height = _items[l - 1].y; + _addToY = (_height < _minHeight) ? (_minHeight - _height) : 0; + resize(width(), _minHeight > _height ? _minHeight : _height); + if (_addToY + _height - from > _scroll->scrollTop() + _scroll->height()) { + _scroll->scrollToY(_addToY + _height - from - _scroll->height()); + } + if (_addToY + _height - _items[i].y < _scroll->scrollTop()) { + _scroll->scrollToY(_addToY + _height - _items[i].y); + } + } + break; + } + } + } +} + void OverviewInner::msgUpdated(const HistoryItem *msg) { if (!msg || _hist != msg->history()) return; MsgId msgid = msg->id; @@ -1436,7 +1474,8 @@ void OverviewInner::msgUpdated(const HistoryItem *msg) { for (int32 i = 0, l = _items.size(); i != l; ++i) { if (_items[i].msgid == msgid) { HistoryMedia *media = msg->getMedia(true); - if (media) update(0, _addToY + _height - _items[i].y, _width, media->height() + st::msgMargin.top() + st::msgMargin.bottom()); + int32 w = _width - st::msgMargin.left() - st::msgMargin.right(); + if (media) update(0, _addToY + _height - _items[i].y, _width, media->countHeight(msg, w) + st::msgMargin.top() + st::msgMargin.bottom()); break; } } @@ -1534,7 +1573,9 @@ void OverviewWidget::paintEvent(QPaintEvent *e) { } QRect r(e->rect()); - if (cCatsAndDogs()) { + if (type() == OverviewPhotos) { + p.fillRect(r, st::white->b); + } else if (cCatsAndDogs()) { int32 i_from = r.left() / _bg.width(), i_to = (r.left() + r.width() - 1) / _bg.width() + 1; int32 j_from = r.top() / _bg.height(), j_to = (r.top() + r.height() - 1) / _bg.height() + 1; for (int32 i = i_from; i < i_to; ++i) { @@ -1625,6 +1666,7 @@ int32 OverviewWidget::lastScrollTop() const { } void OverviewWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTopBarCache, bool back, int32 lastScrollTop) { + stopGif(); _bgAnimCache = bgAnimCache; _bgAnimTopBarCache = bgAnimTopBarCache; resizeEvent(0); @@ -1693,6 +1735,18 @@ void OverviewWidget::msgUpdated(PeerId p, const HistoryItem *msg) { } } +void OverviewWidget::itemRemoved(HistoryItem *row) { + if (row->history()->peer == peer()) { + _inner.itemRemoved(row); + } +} + +void OverviewWidget::itemResized(HistoryItem *row) { + if (row->history()->peer == peer()) { + _inner.itemResized(row); + } +} + void OverviewWidget::fillSelectedItems(SelectedItemSet &sel, bool forDelete) { _inner.fillSelectedItems(sel, forDelete); } diff --git a/Telegram/SourceFiles/overviewwidget.h b/Telegram/SourceFiles/overviewwidget.h index 8db9220b4..377de7bf5 100644 --- a/Telegram/SourceFiles/overviewwidget.h +++ b/Telegram/SourceFiles/overviewwidget.h @@ -58,6 +58,8 @@ public: void mediaOverviewUpdated(); void changingMsgId(HistoryItem *row, MsgId newId); void msgUpdated(const HistoryItem *msg); + void itemRemoved(HistoryItem *item); + void itemResized(HistoryItem *item); void getSelectionState(int32 &selectedForForward, int32 &selectedForDelete) const; void clearSelectedItems(bool onlyTextSelection = false); @@ -84,8 +86,6 @@ public slots: void onTouchSelect(); void onTouchScrollTimer(); - void itemRemoved(HistoryItem *item); - private: void fixItemIndex(int32 ¤t, MsgId msgId) const; @@ -102,10 +102,6 @@ private: void touchUpdateSpeed(); void touchDeaccelerate(int32 elapsed); - //void adjustCurrent(int32 y); - //HistoryItem *prevItem(HistoryItem *item); - //HistoryItem *nextItem(HistoryItem *item); - //void updateDragSelection(HistoryItem *dragSelFrom, HistoryItem *dragSelTo, bool dragSelecting, bool force = false); void applyDragSelection(); QPixmap genPix(PhotoData *photo, int32 size); @@ -214,6 +210,8 @@ public: void mediaOverviewUpdated(PeerData *peer); void changingMsgId(HistoryItem *row, MsgId newId); void msgUpdated(PeerId peer, const HistoryItem *msg); + void itemRemoved(HistoryItem *item); + void itemResized(HistoryItem *row); QPoint clampMousePosition(QPoint point); diff --git a/Telegram/SourceFiles/profilewidget.cpp b/Telegram/SourceFiles/profilewidget.cpp index 3e87fa013..0dce59895 100644 --- a/Telegram/SourceFiles/profilewidget.cpp +++ b/Telegram/SourceFiles/profilewidget.cpp @@ -950,6 +950,7 @@ bool ProfileWidget::allMediaShown() const { } void ProfileWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTopBarCache, bool back, int32 lastScrollTop, bool allMediaShown) { + stopGif(); _bgAnimCache = bgAnimCache; _bgAnimTopBarCache = bgAnimTopBarCache; if (allMediaShown) _inner.onMediaShowAll(); diff --git a/Telegram/SourceFiles/window.cpp b/Telegram/SourceFiles/window.cpp index 8e4a25833..dce9b69f0 100644 --- a/Telegram/SourceFiles/window.cpp +++ b/Telegram/SourceFiles/window.cpp @@ -588,9 +588,9 @@ void Window::showPhoto(PhotoData *photo, PeerData *peer) { _mediaView->setFocus(); } -void Window::showDocument(DocumentData *doc, HistoryItem *item) { +void Window::showDocument(DocumentData *doc, QPixmap pix, HistoryItem *item) { layerHidden(); - _mediaView->showDocument(doc, item); + _mediaView->showDocument(doc, pix, item); _mediaView->activateWindow(); _mediaView->setFocus(); } diff --git a/Telegram/SourceFiles/window.h b/Telegram/SourceFiles/window.h index 92bb07491..defab1ba2 100644 --- a/Telegram/SourceFiles/window.h +++ b/Telegram/SourceFiles/window.h @@ -177,7 +177,7 @@ public: void showPhoto(const PhotoLink *lnk, HistoryItem *item = 0); void showPhoto(PhotoData *photo, HistoryItem *item); void showPhoto(PhotoData *photo, PeerData *item); - void showDocument(DocumentData *doc, HistoryItem *item); + void showDocument(DocumentData *doc, QPixmap pix, HistoryItem *item); void showLayer(LayeredWidget *w); void replaceLayer(LayeredWidget *w); void hideLayer(); diff --git a/Telegram/Telegram.plist b/Telegram/Telegram.plist index 652da986c..377e61ec3 100644 --- a/Telegram/Telegram.plist +++ b/Telegram/Telegram.plist @@ -11,7 +11,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.6.2 + 0.6.3 CFBundleSignature ???? NOTE diff --git a/Telegram/Telegram.rc b/Telegram/Telegram.rc index b19b8f96099a6241bd5ff7a99c6e58802d61b8be..1fde9fabbd6dbc1b5658437f28ddcf6968ee8918 100644 GIT binary patch delta 42 vcmZ3cy-a(94mYFmWL<7UM&r%#-2F^I>OHSDBT(!;uk_>yexc0~{C;cz3cm~! delta 42 vcmZ3cy-a(94mYFGWL<7UMx)K~-2F^I>OHSDBT(!;uk_>yexc0~{C;cz3SJBk diff --git a/Telegram/Telegram.xcodeproj/project.pbxproj b/Telegram/Telegram.xcodeproj/project.pbxproj index bfb2bd2f3..d5c68c341 100644 --- a/Telegram/Telegram.xcodeproj/project.pbxproj +++ b/Telegram/Telegram.xcodeproj/project.pbxproj @@ -1497,7 +1497,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0.6.2; + CURRENT_PROJECT_VERSION = 0.6.3; DEBUG_INFORMATION_FORMAT = dwarf; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; @@ -1515,7 +1515,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 0.6.2; + CURRENT_PROJECT_VERSION = 0.6.3; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_OPTIMIZATION_LEVEL = fast; GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h; @@ -1541,10 +1541,10 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = ""; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0.6.2; + CURRENT_PROJECT_VERSION = 0.6.3; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 0.6; - DYLIB_CURRENT_VERSION = 0.6.2; + DYLIB_CURRENT_VERSION = 0.6.3; ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; @@ -1683,10 +1683,10 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = ""; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0.6.2; + CURRENT_PROJECT_VERSION = 0.6.3; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 0.6; - DYLIB_CURRENT_VERSION = 0.6.2; + DYLIB_CURRENT_VERSION = 0.6.3; ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_GENERATE_DEBUGGING_SYMBOLS = YES;