inline gif view done, some design improvements, version 0.6.3

This commit is contained in:
John Preston 2014-10-10 16:46:20 +04:00
parent 3009200b76
commit 09e2fbaa6b
29 changed files with 548 additions and 195 deletions

View File

@ -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!"

View File

@ -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!"

View File

@ -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!"

View File

@ -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;

View File

@ -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"

View File

@ -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

View File

@ -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() {

View File

@ -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

View File

@ -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<MTPDialog> &dialogs) {
for (QVector<MTPDialog>::const_iterator i = dialogs.cbegin(), e = dialogs.cend(); i != e; ++i) {
const MTPDdialog &d(i->c_dialog());

View File

@ -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);

View File

@ -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) {

View File

@ -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);

View File

@ -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<QPixmap> frames;
QVector<int64> 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 &currentTex
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;
}

View File

@ -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<int32, HistoryItem*> SelectedItemSet;
@ -692,7 +698,7 @@ struct History : public QList<HistoryBlock*> {
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<HistoryItem*> {
}
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 &currentText);
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;

View File

@ -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();
}

View File

@ -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<MTPMessage> &messages);
void addMessagesToBack(const QVector<MTPMessage> &messages);
void chatLoaded(const MTPmessages_ChatFull &res);

View File

@ -57,6 +57,7 @@ void BackgroundWidget::keyPressEvent(QKeyEvent *e) {
}
void BackgroundWidget::mousePressEvent(QMouseEvent *e) {
onClose();
}
void BackgroundWidget::onClose() {

View File

@ -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);
}

View File

@ -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:

View File

@ -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;

View File

@ -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);

View File

@ -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);
}

View File

@ -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 &current, 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);

View File

@ -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();

View File

@ -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();
}

View File

@ -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();

View File

@ -11,7 +11,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.6.2</string>
<string>0.6.3</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>NOTE</key>

Binary file not shown.

View File

@ -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;