diff --git a/Telegram/Resources/lang.strings b/Telegram/Resources/lang.strings index b42d09f74..edf3ff2c6 100644 --- a/Telegram/Resources/lang.strings +++ b/Telegram/Resources/lang.strings @@ -576,6 +576,13 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org "lng_media_video" = "Video file"; "lng_media_audio" = "Voice message"; +"lng_media_auto_settings" = "Automatic media download settings"; +"lng_media_auto_photo" = "Automatic photo download"; +"lng_media_auto_audio" = "Automatic audio download"; +"lng_media_auto_gif" = "Automatic GIF download"; +"lng_media_auto_private_chats" = "Private chats"; +"lng_media_auto_groups" = "Groups and channels"; + "lng_emoji_category0" = "Frequently used"; "lng_emoji_category1" = "People"; "lng_emoji_category2" = "Nature"; diff --git a/Telegram/SourceFiles/boxes/connectionbox.cpp b/Telegram/SourceFiles/boxes/connectionbox.cpp index 23ac63af9..78fb0dd03 100644 --- a/Telegram/SourceFiles/boxes/connectionbox.cpp +++ b/Telegram/SourceFiles/boxes/connectionbox.cpp @@ -27,17 +27,17 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org #include "mainwidget.h" #include "window.h" -ConnectionBox::ConnectionBox() : AbstractBox(st::boxWidth), -_hostInput(this, st::connectionHostInputField, lang(lng_connection_host_ph), cConnectionProxy().host), -_portInput(this, st::connectionPortInputField, lang(lng_connection_port_ph), QString::number(cConnectionProxy().port)), -_userInput(this, st::connectionUserInputField, lang(lng_connection_user_ph), cConnectionProxy().user), -_passwordInput(this, st::connectionPasswordInputField, lang(lng_connection_password_ph), cConnectionProxy().password), -_autoRadio(this, qsl("conn_type"), dbictAuto, lang(lng_connection_auto_rb), (cConnectionType() == dbictAuto)), -_httpProxyRadio(this, qsl("conn_type"), dbictHttpProxy, lang(lng_connection_http_proxy_rb), (cConnectionType() == dbictHttpProxy)), -_tcpProxyRadio(this, qsl("conn_type"), dbictTcpProxy, lang(lng_connection_tcp_proxy_rb), (cConnectionType() == dbictTcpProxy)), -_tryIPv6(this, lang(lng_connection_try_ipv6), cTryIPv6()), -_save(this, lang(lng_connection_save), st::defaultBoxButton), -_cancel(this, lang(lng_cancel), st::cancelBoxButton) { +ConnectionBox::ConnectionBox() : AbstractBox(st::boxWidth) +, _hostInput(this, st::connectionHostInputField, lang(lng_connection_host_ph), cConnectionProxy().host) +, _portInput(this, st::connectionPortInputField, lang(lng_connection_port_ph), QString::number(cConnectionProxy().port)) +, _userInput(this, st::connectionUserInputField, lang(lng_connection_user_ph), cConnectionProxy().user) +, _passwordInput(this, st::connectionPasswordInputField, lang(lng_connection_password_ph), cConnectionProxy().password) +, _autoRadio(this, qsl("conn_type"), dbictAuto, lang(lng_connection_auto_rb), (cConnectionType() == dbictAuto)) +, _httpProxyRadio(this, qsl("conn_type"), dbictHttpProxy, lang(lng_connection_http_proxy_rb), (cConnectionType() == dbictHttpProxy)) +, _tcpProxyRadio(this, qsl("conn_type"), dbictTcpProxy, lang(lng_connection_tcp_proxy_rb), (cConnectionType() == dbictTcpProxy)) +, _tryIPv6(this, lang(lng_connection_try_ipv6), cTryIPv6()) +, _save(this, lang(lng_connection_save), st::defaultBoxButton) +, _cancel(this, lang(lng_cancel), st::cancelBoxButton) { connect(&_save, SIGNAL(clicked()), this, SLOT(onSave())); connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose())); @@ -218,3 +218,79 @@ void ConnectionBox::onSave() { emit closed(); } } + +AutoDownloadBox::AutoDownloadBox() : AbstractBox(st::boxWidth) +, _photoPrivate(this, lang(lng_media_auto_private_chats), !(cAutoDownloadPhoto() & dbiadNoPrivate)) +, _photoGroups(this, lang(lng_media_auto_groups), !(cAutoDownloadPhoto() & dbiadNoGroups)) +, _audioPrivate(this, lang(lng_media_auto_private_chats), !(cAutoDownloadAudio() & dbiadNoPrivate)) +, _audioGroups(this, lang(lng_media_auto_groups), !(cAutoDownloadAudio() & dbiadNoGroups)) +, _gifPrivate(this, lang(lng_media_auto_private_chats), !(cAutoDownloadGif() & dbiadNoPrivate)) +, _gifGroups(this, lang(lng_media_auto_groups), !(cAutoDownloadGif() & dbiadNoGroups)) +, _sectionHeight(st::boxTitleHeight + 2 * (st::defaultCheckbox.height + st::setLittleSkip)) +, _save(this, lang(lng_connection_save), st::defaultBoxButton) +, _cancel(this, lang(lng_cancel), st::cancelBoxButton) { + + setMaxHeight(3 * _sectionHeight + st::boxButtonPadding.top() + _save.height() + st::boxButtonPadding.bottom()); + + connect(&_save, SIGNAL(clicked()), this, SLOT(onSave())); + connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose())); + + prepare(); +} + +void AutoDownloadBox::hideAll() { + _photoPrivate.hide(); + _photoGroups.hide(); + _audioPrivate.hide(); + _audioGroups.hide(); + _gifPrivate.hide(); + _gifGroups.hide(); + + _save.hide(); + _cancel.hide(); +} + +void AutoDownloadBox::showAll() { + _photoPrivate.show(); + _photoGroups.show(); + _audioPrivate.show(); + _audioGroups.show(); + _gifPrivate.show(); + _gifGroups.show(); + + _save.show(); + _cancel.show(); +} + +void AutoDownloadBox::paintEvent(QPaintEvent *e) { + Painter p(this); + if (paint(p)) return; + + p.setPen(st::black); + p.setFont(st::semiboldFont); + p.drawTextLeft(st::boxTitlePosition.x(), st::boxTitlePosition.y(), width(), lang(lng_media_auto_photo)); + p.drawTextLeft(st::boxTitlePosition.x(), _sectionHeight + st::boxTitlePosition.y(), width(), lang(lng_media_auto_audio)); + p.drawTextLeft(st::boxTitlePosition.x(), 2 * _sectionHeight + st::boxTitlePosition.y(), width(), lang(lng_media_auto_gif)); +} + +void AutoDownloadBox::resizeEvent(QResizeEvent *e) { + _photoPrivate.moveToLeft(st::boxTitlePosition.x(), st::boxTitleHeight + st::setLittleSkip); + _photoGroups.moveToLeft(st::boxTitlePosition.x(), _photoPrivate.y() + _photoPrivate.height() + st::setLittleSkip); + + _audioPrivate.moveToLeft(st::boxTitlePosition.x(), _sectionHeight + st::boxTitleHeight + st::setLittleSkip); + _audioGroups.moveToLeft(st::boxTitlePosition.x(), _audioPrivate.y() + _audioPrivate.height() + st::setLittleSkip); + + _gifPrivate.moveToLeft(st::boxTitlePosition.x(), 2 * _sectionHeight + st::boxTitleHeight + st::setLittleSkip); + _gifGroups.moveToLeft(st::boxTitlePosition.x(), _gifPrivate.y() + _gifPrivate.height() + st::setLittleSkip); + + _save.moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _save.height()); + _cancel.moveToRight(st::boxButtonPadding.right() + _save.width() + st::boxButtonPadding.left(), _save.y()); +} + +void AutoDownloadBox::onSave() { + cSetAutoDownloadPhoto((_photoPrivate.checked() ? 0 : dbiadNoPrivate) | (_photoGroups.checked() ? 0 : dbiadNoGroups)); + cSetAutoDownloadAudio((_audioPrivate.checked() ? 0 : dbiadNoPrivate) | (_audioGroups.checked() ? 0 : dbiadNoGroups)); + cSetAutoDownloadGif((_gifPrivate.checked() ? 0 : dbiadNoPrivate) | (_gifGroups.checked() ? 0 : dbiadNoGroups)); + Local::writeUserSettings(); + onClose(); +} diff --git a/Telegram/SourceFiles/boxes/connectionbox.h b/Telegram/SourceFiles/boxes/connectionbox.h index f8bbce5ab..bd54f178d 100644 --- a/Telegram/SourceFiles/boxes/connectionbox.h +++ b/Telegram/SourceFiles/boxes/connectionbox.h @@ -54,3 +54,32 @@ private: BoxButton _save, _cancel; }; + +class AutoDownloadBox : public AbstractBox { + Q_OBJECT + +public: + + AutoDownloadBox(); + void paintEvent(QPaintEvent *e); + void resizeEvent(QResizeEvent *e); + +public slots: + + void onSave(); + +protected: + + void hideAll(); + void showAll(); + +private: + + Checkbox _photoPrivate, _photoGroups; + Checkbox _audioPrivate, _audioGroups; + Checkbox _gifPrivate, _gifGroups; + + int32 _sectionHeight; + + BoxButton _save, _cancel; +}; diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp index 07c50614c..00f38e7ed 100644 --- a/Telegram/SourceFiles/facades.cpp +++ b/Telegram/SourceFiles/facades.cpp @@ -154,9 +154,8 @@ namespace Notify { if (HistoryMedia *media = item->getMedia()) { media->stopInline(item); if (DocumentData *document = media->getDocument()) { // forget data from memory - if (!document->data.isEmpty()) { + if (!document->data.isEmpty() && document->prepareAutoLoader(item)) { document->data.clear(); - document->prepareAutoLoader(); } } stopped = true; diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index 26e28337d..c3c5ca16d 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -3741,19 +3741,21 @@ ImagePtr HistoryVideo::replyPreview() { HistoryAudio::HistoryAudio(const MTPDaudio &audio) : HistoryFileMedia() , _data(App::feedAudio(audio)) { - setLinks(new AudioOpenLink(_data), new AudioSaveLink(_data), new AudioCancelLink(_data)); + setLinks(new AudioOpenLink(_data), new AudioOpenLink(_data), new AudioCancelLink(_data)); setStatusSize(FileStatusSizeReady); } HistoryAudio::HistoryAudio(const HistoryAudio &other) : HistoryFileMedia() , _data(other._data) { - setLinks(new AudioOpenLink(_data), new AudioSaveLink(_data), new AudioCancelLink(_data)); + setLinks(new AudioOpenLink(_data), new AudioOpenLink(_data), new AudioCancelLink(_data)); setStatusSize(other._statusSize); } void HistoryAudio::initDimensions(const HistoryItem *parent) { + _data->prepareAutoLoader(parent); + _maxw = st::msgFileMinWidth; int32 tleft = 0, tright = 0; @@ -3974,6 +3976,8 @@ HistoryDocument::HistoryDocument(const HistoryDocument &other) : HistoryFileMedi } void HistoryDocument::initDimensions(const HistoryItem *parent) { + _data->prepareAutoLoader(parent); + _maxw = st::msgFileMinWidth; int32 tleft = 0, tright = 0; @@ -4291,6 +4295,8 @@ HistoryGif::HistoryGif(const HistoryGif &other) : HistoryFileMedia() } void HistoryGif::initDimensions(const HistoryItem *parent) { + _data->prepareAutoLoader(parent); + bool bubble = parent->hasBubble(); int32 tw = 0, th = 0; if (_gif && _gif->state() == ClipError) { @@ -4614,6 +4620,8 @@ HistorySticker::HistorySticker(DocumentData *document) : HistoryMedia() } void HistorySticker::initDimensions(const HistoryItem *parent) { + _data->prepareAutoLoader(parent); + _pixw = _data->dimensions.width(); _pixh = _data->dimensions.height(); if (_pixw > st::maxStickerSize) { diff --git a/Telegram/SourceFiles/layout.cpp b/Telegram/SourceFiles/layout.cpp index e9c86a429..ac251ba18 100644 --- a/Telegram/SourceFiles/layout.cpp +++ b/Telegram/SourceFiles/layout.cpp @@ -536,7 +536,9 @@ void LayoutOverviewVideo::updateStatusText() const { LayoutOverviewAudio::LayoutOverviewAudio(AudioData *audio, HistoryItem *parent) : LayoutAbstractFileItem(parent) , _data(audio) { - setLinks(new AudioOpenLink(_data), new AudioSaveLink(_data), new AudioCancelLink(_data)); + _data->prepareAutoLoader(_parent); + + setLinks(new AudioOpenLink(_data), new AudioOpenLink(_data), new AudioCancelLink(_data)); updateName(); QString d = textcmdLink(1, textRichPrepare(langDateTime(date(_data->date)))); TextParseOptions opts = { TextParseRichText, 0, 0, Qt::LayoutDirectionAuto }; @@ -705,7 +707,7 @@ bool LayoutOverviewAudio::updateStatusText() const { } return showPause; } - + LayoutOverviewDocument::LayoutOverviewDocument(DocumentData *document, HistoryItem *parent) : LayoutAbstractFileItem(parent) , _data(document) , _msgl(new MessageLink(parent)) @@ -715,6 +717,8 @@ LayoutOverviewDocument::LayoutOverviewDocument(DocumentData *document, HistoryIt , _namew(st::semiboldFont->width(_name)) , _datew(st::normalFont->width(_date)) , _colorIndex(documentColorIndex(_data, _ext)) { + _data->prepareAutoLoader(_parent); + setLinks(new DocumentOpenLink(_data), new DocumentSaveLink(_data), new DocumentCancelLink(_data)); setStatusSize(FileStatusSizeReady, _data->size, _data->song() ? _data->song()->duration : -1, 0); diff --git a/Telegram/SourceFiles/localstorage.cpp b/Telegram/SourceFiles/localstorage.cpp index 79158f11d..c39db257b 100644 --- a/Telegram/SourceFiles/localstorage.cpp +++ b/Telegram/SourceFiles/localstorage.cpp @@ -329,6 +329,45 @@ namespace { } }; + bool fileExists(const QString &name, int options = UserPath | SafePath) { + if (options & UserPath) { + if (!_userWorking()) return false; + } else { + if (!_working()) return false; + } + + // detect order of read attempts + QString toTry[2]; + toTry[0] = ((options & UserPath) ? _userBasePath : _basePath) + name + '0'; + if (options & SafePath) { + QFileInfo toTry0(toTry[0]); + if (toTry0.exists()) { + toTry[1] = ((options & UserPath) ? _userBasePath : _basePath) + name + '1'; + QFileInfo toTry1(toTry[1]); + if (toTry1.exists()) { + QDateTime mod0 = toTry0.lastModified(), mod1 = toTry1.lastModified(); + if (mod0 < mod1) { + qSwap(toTry[0], toTry[1]); + } + } else { + toTry[1] = QString(); + } + } else { + toTry[0][toTry[0].size() - 1] = '1'; + } + } + for (int32 i = 0; i < 2; ++i) { + QString fname(toTry[i]); + if (fname.isEmpty()) break; + if (QFileInfo(fname).exists()) return true; + } + return false; + } + + bool fileExists(const FileKey &fkey, int options = UserPath | SafePath) { + return fileExists(toFilePart(fkey), options); + } + bool readFile(FileReadDescriptor &result, const QString &name, int options = UserPath | SafePath) { if (options & UserPath) { if (!_userWorking()) return false; @@ -824,6 +863,16 @@ namespace { cSetSoundNotify(v == 1); } break; + case dbiAutoDownload: { + qint32 photo, audio, gif; + stream >> photo >> audio >> gif; + if (!_checkStreamStatus(stream)) return false; + + cSetAutoDownloadPhoto(photo); + cSetAutoDownloadAudio(audio); + cSetAutoDownloadGif(gif); + } break; + case dbiIncludeMuted: { qint32 v; stream >> v; @@ -1395,6 +1444,7 @@ namespace { size += sizeof(quint32) + sizeof(qint32) + cEmojiVariants().size() * (sizeof(uint32) + sizeof(uint64)); size += sizeof(quint32) + sizeof(qint32) + (cRecentStickersPreload().isEmpty() ? cGetRecentStickers().size() : cRecentStickersPreload().size()) * (sizeof(uint64) + sizeof(ushort)); size += sizeof(quint32) + _stringSize(cDialogLastPath()); + size += sizeof(quint32) + 3 * sizeof(qint32); EncryptedDescriptor data(size); data.stream << quint32(dbiSendKey) << qint32(cCtrlEnter() ? dbiskCtrlEnter : dbiskEnter); @@ -1412,6 +1462,7 @@ namespace { data.stream << quint32(dbiCompressPastedImage) << qint32(cCompressPastedImage()); data.stream << quint32(dbiDialogLastPath) << cDialogLastPath(); data.stream << quint32(dbiSongVolume) << qint32(qRound(cSongVolume() * 1e6)); + data.stream << quint32(dbiAutoDownload) << qint32(cAutoDownloadPhoto()) << qint32(cAutoDownloadAudio()) << qint32(cAutoDownloadGif()); { RecentEmojisPreload v(cRecentEmojisPreload()); @@ -2418,8 +2469,11 @@ namespace Local { return _localLoader->addTask(new ImageLoadTask(j->first, location, loader)); } - bool willImageLoad(const StorageKey &location) { - return (_imagesMap.constFind(location) != _imagesMap.cend()); + bool willImageLoad(const StorageKey &location, bool check) { + StorageMap::const_iterator j = _imagesMap.constFind(location); + if (j == _imagesMap.cend()) return false; + if (check && !fileExists(j->first, UserPath)) return false; + return true; } int32 hasImages() { @@ -2481,8 +2535,11 @@ namespace Local { return _localLoader->addTask(new StickerImageLoadTask(j->first, location, loader)); } - bool willStickerImageLoad(const StorageKey &location) { - return (_stickerImagesMap.constFind(location) != _stickerImagesMap.cend()); + bool willStickerImageLoad(const StorageKey &location, bool check) { + StorageMap::const_iterator j = _stickerImagesMap.constFind(location); + if (j == _stickerImagesMap.cend()) return false; + if (check && !fileExists(j->first, UserPath)) return false; + return true; } int32 hasStickers() { @@ -2544,8 +2601,11 @@ namespace Local { return _localLoader->addTask(new AudioLoadTask(j->first, location, loader)); } - bool willAudioLoad(const StorageKey &location) { - return (_audiosMap.constFind(location) != _audiosMap.cend()); + bool willAudioLoad(const StorageKey &location, bool check) { + StorageMap::const_iterator j = _audiosMap.constFind(location); + if (j == _audiosMap.cend()) return false; + if (check && !fileExists(j->first, UserPath)) return false; + return true; } int32 hasAudios() { diff --git a/Telegram/SourceFiles/localstorage.h b/Telegram/SourceFiles/localstorage.h index 6e946f055..6d06f0659 100644 --- a/Telegram/SourceFiles/localstorage.h +++ b/Telegram/SourceFiles/localstorage.h @@ -124,19 +124,19 @@ namespace Local { void writeImage(const StorageKey &location, const ImagePtr &img); void writeImage(const StorageKey &location, const StorageImageSaved &jpeg, bool overwrite = true); TaskId startImageLoad(const StorageKey &location, mtpFileLoader *loader); - bool willImageLoad(const StorageKey &location); + bool willImageLoad(const StorageKey &location, bool check = false); int32 hasImages(); qint64 storageImagesSize(); void writeStickerImage(const StorageKey &location, const QByteArray &data, bool overwrite = true); TaskId startStickerImageLoad(const StorageKey &location, mtpFileLoader *loader); - bool willStickerImageLoad(const StorageKey &location); + bool willStickerImageLoad(const StorageKey &location, bool check = false); int32 hasStickers(); qint64 storageStickersSize(); void writeAudio(const StorageKey &location, const QByteArray &data, bool overwrite = true); TaskId startAudioLoad(const StorageKey &location, mtpFileLoader *loader); - bool willAudioLoad(const StorageKey &location); + bool willAudioLoad(const StorageKey &location, bool check = false); int32 hasAudios(); qint64 storageAudiosSize(); diff --git a/Telegram/SourceFiles/mediaview.cpp b/Telegram/SourceFiles/mediaview.cpp index 9c5499f02..960c99c8c 100644 --- a/Telegram/SourceFiles/mediaview.cpp +++ b/Telegram/SourceFiles/mediaview.cpp @@ -615,15 +615,10 @@ void MediaView::onSaveAs() { } void MediaView::onDocClick() { - QString fname = _doc->already(true); - if (fname.isEmpty()) { - if (_doc->loader) { - onSaveCancel(); - } else { - onDownload(); - } + if (_doc->loader && _doc->loader->started()) { + onSaveCancel(); } else { - psOpenFile(fname); + DocumentOpenLink::doOpen(_doc); } } @@ -1585,9 +1580,8 @@ void MediaView::preloadData(int32 delta) { case MediaTypeSticker: DocumentData *doc = media->getDocument(); doc->forget(); - if (!doc->data.isEmpty()) { + if (!doc->data.isEmpty() && doc->prepareAutoLoader(item)) { doc->data.clear(); - doc->prepareAutoLoader(); } break; } diff --git a/Telegram/SourceFiles/settings.cpp b/Telegram/SourceFiles/settings.cpp index 65387d7df..a3f59cff3 100644 --- a/Telegram/SourceFiles/settings.cpp +++ b/Telegram/SourceFiles/settings.cpp @@ -171,6 +171,10 @@ SavedPeersByTime gSavedPeersByTime; ReportSpamStatuses gReportSpamStatuses; +int32 gAutoDownloadPhoto = 0; // all auto download +int32 gAutoDownloadAudio = 0; +int32 gAutoDownloadGif = 0; + void settingsParseArgs(int argc, char *argv[]) { #ifdef Q_OS_MAC gIsElCapitan = (QSysInfo::macVersion() >= QSysInfo::MV_10_11); diff --git a/Telegram/SourceFiles/settings.h b/Telegram/SourceFiles/settings.h index 18ee47753..eb69cd000 100644 --- a/Telegram/SourceFiles/settings.h +++ b/Telegram/SourceFiles/settings.h @@ -327,4 +327,13 @@ DeclareRefSetting(SavedPeersByTime, SavedPeersByTime); typedef QMap ReportSpamStatuses; DeclareRefSetting(ReportSpamStatuses, ReportSpamStatuses); +enum DBIAutoDownloadFlags { + dbiadNoPrivate = 0x01, + dbiadNoGroups = 0x02, +}; + +DeclareSetting(int32, AutoDownloadPhoto); +DeclareSetting(int32, AutoDownloadAudio); +DeclareSetting(int32, AutoDownloadGif); + void settingsParseArgs(int argc, char *argv[]); diff --git a/Telegram/SourceFiles/settingswidget.cpp b/Telegram/SourceFiles/settingswidget.cpp index b5ef77c74..f4d32485c 100644 --- a/Telegram/SourceFiles/settingswidget.cpp +++ b/Telegram/SourceFiles/settingswidget.cpp @@ -168,12 +168,14 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : TWidget(parent) , _dontAskDownloadPath(this, lang(lng_download_path_dont_ask), !cAskDownloadPath()) , _downloadPathWidth(st::linkFont->width(lang(lng_download_path_label)) + st::linkFont->spacew) -, _downloadPathEdit(this, cDownloadPath().isEmpty() ? lang(lng_download_path_default) : ((cDownloadPath() == qsl("tmp")) ? lang(lng_download_path_temp) : st::linkFont->elided(QDir::toNativeSeparators(cDownloadPath()), st::setWidth - st::setVersionLeft - _downloadPathWidth))) +, _downloadPathEdit(this, cDownloadPath().isEmpty() ? lang(lng_download_path_default) : ((cDownloadPath() == qsl("tmp")) ? lang(lng_download_path_temp) : st::linkFont->elided(QDir::toNativeSeparators(cDownloadPath()), st::setWidth - st::cbDefFlat.textLeft - _downloadPathWidth))) , _downloadPathClear(this, lang(lng_download_path_clear)) , _tempDirClearingWidth(st::linkFont->width(lang(lng_download_path_clearing))) , _tempDirClearedWidth(st::linkFont->width(lang(lng_download_path_cleared))) , _tempDirClearFailedWidth(st::linkFont->width(lang(lng_download_path_clear_failed))) +, _autoDownload(this, lang(lng_media_auto_settings)) + // chat background , _backFromGallery(this, lang(lng_settings_bg_from_gallery)) , _backFromFile(this, lang(lng_settings_bg_from_file)) @@ -290,6 +292,7 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : TWidget(parent) } connect(App::wnd(), SIGNAL(tempDirCleared(int)), this, SLOT(onTempDirCleared(int))); connect(App::wnd(), SIGNAL(tempDirClearFailed(int)), this, SLOT(onTempDirClearFailed(int))); + connect(&_autoDownload, SIGNAL(clicked()), this, SLOT(onAutoDownload())); // chat background if (!cChatBackground()) App::initBackground(); @@ -471,8 +474,8 @@ void SettingsInner::paintEvent(QPaintEvent *e) { } else { textToDraw = _curVersionText; } - p.setFont(st::linkFont->f); - p.setPen(st::setVersionColor->p); + p.setFont(st::linkFont); + p.setPen(st::setVersionColor); p.drawText(_left + st::setVersionLeft, top + st::setVersionTop + st::linkFont->ascent, textToDraw); top += st::setVersionHeight; #endif @@ -532,7 +535,7 @@ void SettingsInner::paintEvent(QPaintEvent *e) { top += st::setLittleSkip; p.setFont(st::linkFont->f); p.setPen(st::black->p); - p.drawText(_left + st::setVersionLeft, top + st::linkFont->ascent, lang(lng_download_path_label)); + p.drawText(_left + st::cbDefFlat.textLeft, top + st::linkFont->ascent, lang(lng_download_path_label)); if (cDownloadPath() == qsl("tmp")) { QString clearText; int32 clearWidth = 0; @@ -547,7 +550,8 @@ void SettingsInner::paintEvent(QPaintEvent *e) { } top += _downloadPathEdit.height(); } - top += st::setSectionSkip; + top += st::setLittleSkip; + top += _autoDownload.height(); // chat background p.setFont(st::setHeaderFont->f); @@ -721,13 +725,14 @@ void SettingsInner::resizeEvent(QResizeEvent *e) { _dontAskDownloadPath.move(_left, top); top += _dontAskDownloadPath.height(); if (!cAskDownloadPath()) { top += st::setLittleSkip; - _downloadPathEdit.move(_left + st::setVersionLeft + _downloadPathWidth, top); + _downloadPathEdit.move(_left + st::cbDefFlat.textLeft + _downloadPathWidth, top); if (cDownloadPath() == qsl("tmp")) { _downloadPathClear.move(_left + st::setWidth - _downloadPathClear.width(), top); } top += _downloadPathEdit.height(); } - top += st::setSectionSkip; + top += st::setLittleSkip; + _autoDownload.move(_left + st::cbDefFlat.textLeft, top); top += _autoDownload.height(); // chat background top += st::setHeaderSkip; @@ -1061,7 +1066,7 @@ void SettingsInner::showAll() { _downloadPathClear.hide(); } } - + _autoDownload.show(); } else { _replaceEmojis.hide(); _viewEmojis.hide(); @@ -1071,6 +1076,7 @@ void SettingsInner::showAll() { _dontAskDownloadPath.hide(); _downloadPathEdit.hide(); _downloadPathClear.hide(); + _autoDownload.hide(); } // chat background @@ -1689,6 +1695,10 @@ void SettingsInner::onTempDirClearFailed(int task) { update(); } +void SettingsInner::onAutoDownload() { + Ui::showLayer(new AutoDownloadBox()); +} + #ifndef TDESKTOP_DISABLE_AUTOUPDATE void SettingsInner::setUpdatingState(UpdatingState state, bool force) { if (_updatingState != state || force) { diff --git a/Telegram/SourceFiles/settingswidget.h b/Telegram/SourceFiles/settingswidget.h index 52f8ff153..f30537818 100644 --- a/Telegram/SourceFiles/settingswidget.h +++ b/Telegram/SourceFiles/settingswidget.h @@ -151,6 +151,8 @@ public slots: void onTempDirCleared(int task); void onTempDirClearFailed(int task); + void onAutoDownload(); + void onBackFromGallery(); void onBackFromFile(); void onTileBackground(); @@ -258,6 +260,7 @@ private: TempDirCleared = 4, }; TempDirClearState _tempDirClearState; + LinkButton _autoDownload; // chat background QPixmap _background; diff --git a/Telegram/SourceFiles/structs.cpp b/Telegram/SourceFiles/structs.cpp index 95130ec3a..6460e59d7 100644 --- a/Telegram/SourceFiles/structs.cpp +++ b/Telegram/SourceFiles/structs.cpp @@ -775,10 +775,14 @@ void AudioOpenLink::onClick(Qt::MouseButton button) const { if (data->status != FileReady) return; - if (data->loader && !data->loader->started()) { + if (data->prepareAutoLoader(App::hoveredLinkItem(), true)) { data->openOnSave = 1; data->openOnSaveMsgId = App::hoveredLinkItem() ? App::hoveredLinkItem()->fullId() : (App::contextItem() ? App::contextItem()->fullId() : FullMsgId()); - data->save(QString()); + if (!data->loader->started()) { + data->save(QString()); + } else { + data->loader->start(); + } return; } @@ -851,9 +855,23 @@ bool StickerData::setInstalled() const { AudioData::AudioData(const AudioId &id, const uint64 &access, int32 date, const QString &mime, int32 duration, int32 dc, int32 size) : id(id), access(access), date(date), mime(mime), duration(duration), dc(dc), size(size), status(FileReady), uploadOffset(0), openOnSave(0), loader(0) { _location = Local::readFileLocation(mediaKey(AudioFileLocation, dc, id)); - if (!loaded() && size < AudioVoiceMsgInMemory) { - loader = new mtpFileLoader(dc, id, access, AudioFileLocation, QString(), size, true); +} + +bool AudioData::prepareAutoLoader(const HistoryItem *item, bool force) { + if (!loader && !loaded(true) && size < AudioVoiceMsgInMemory) { + bool load = force; + if (!force) { + if (item->history()->peer->isUser()) { + load = !(cAutoDownloadAudio() & dbiadNoPrivate); + } else { + load = !(cAutoDownloadAudio() & dbiadNoGroups); + } + } + if (load || Local::willAudioLoad(mediaKey(AudioFileLocation, dc, id), true)) { + loader = new mtpFileLoader(dc, id, access, AudioFileLocation, QString(), size, true); + } } + return loader; } void AudioData::save(const QString &toFile) { @@ -932,10 +950,14 @@ void DocumentOpenLink::doOpen(DocumentData *data, int32 openOnSave) { if (data->status != FileReady) return; - if (data->loader && !data->loader->started()) { + if (data->prepareAutoLoader(App::hoveredLinkItem(), true)) { data->openOnSave = openOnSave; data->openOnSaveMsgId = App::hoveredLinkItem() ? App::hoveredLinkItem()->fullId() : (App::contextItem() ? App::contextItem()->fullId() : FullMsgId()); - data->save(QString()); + if (!data->loader->started()) { + data->save(QString()); + } else { + data->loader->start(); + } return; } @@ -1103,29 +1125,40 @@ void DocumentData::setattributes(const QVector &attributes case mtpc_documentAttributeFilename: name = qs(attributes[i].c_documentAttributeFilename().vfile_name); break; } } - prepareAutoLoader(); -} - -void DocumentData::prepareAutoLoader() { if (type == StickerDocument) { if (dimensions.width() <= 0 || dimensions.height() <= 0 || dimensions.width() > StickerMaxSize || dimensions.height() > StickerMaxSize || size > StickerInMemory) { type = FileDocument; delete _additional; _additional = 0; - } else if (!loader && !loaded(true)) { - loader = new mtpFileLoader(dc, id, access, DocumentFileLocation, QString(), size, true); - } - } else if (isAnimation()) { - if (size <= AnimationInMemory && !loader && !loaded(true)) { - loader = new mtpFileLoader(dc, id, access, DocumentFileLocation, QString(), size, true); } } } +bool DocumentData::prepareAutoLoader(const HistoryItem *item, bool force) { + if (!loader && !loaded(true)) { + if (type == StickerDocument) { + loader = new mtpFileLoader(dc, id, access, DocumentFileLocation, QString(), size, true); + } else if (isAnimation() && item && size <= AnimationInMemory) { + bool load = force; + if (!load) { + if (item->history()->peer->isUser()) { + load = !(cAutoDownloadGif() & dbiadNoPrivate); + } else { + load = !(cAutoDownloadGif() & dbiadNoGroups); + } + } + if (load || Local::willStickerImageLoad(mediaKey(DocumentFileLocation, dc, id), true)) { + loader = new mtpFileLoader(dc, id, access, DocumentFileLocation, QString(), size, true); + } + } + } + return loader; +} + void DocumentData::save(const QString &toFile) { if (loader && loader->fileName().isEmpty()) { loader->setFileName(toFile); - } else { + } else if (!loader || !toFile.isEmpty()) { cancel(true); loader = new mtpFileLoader(dc, id, access, DocumentFileLocation, toFile, size, (type == StickerDocument)); } diff --git a/Telegram/SourceFiles/structs.h b/Telegram/SourceFiles/structs.h index 618496865..34cba1b60 100644 --- a/Telegram/SourceFiles/structs.h +++ b/Telegram/SourceFiles/structs.h @@ -903,6 +903,7 @@ struct AudioData { void forget() { } + bool prepareAutoLoader(const HistoryItem *item, bool force = false); void save(const QString &toFile); void cancel(bool beforeDownload = false) { @@ -1147,7 +1148,7 @@ struct DocumentData { bool loadingStarted() { return loader && loader->started(); } - void prepareAutoLoader(); + bool prepareAutoLoader(const HistoryItem *item, bool force = false); StickerData *sticker() { return (type == StickerDocument) ? static_cast(_additional) : 0; } diff --git a/Telegram/SourceFiles/types.h b/Telegram/SourceFiles/types.h index 010e6d43c..8f18d992f 100644 --- a/Telegram/SourceFiles/types.h +++ b/Telegram/SourceFiles/types.h @@ -288,6 +288,7 @@ enum DataBlockId { dbiIncludeMuted = 0x31, dbiMaxMegaGroupCount = 0x32, dbiDownloadPath = 0x33, + dbiAutoDownload = 0x34, dbiEncryptedWithSalt = 333, dbiEncrypted = 444,