mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-29 15:01:03 +00:00
fixed mail links in Win10, include muted chats in the unread badge setting, shared links overview and search, version 0.8.53.dev
This commit is contained in:
parent
bfde1d2143
commit
9a51e2c7e3
@ -1,11 +1,11 @@
|
||||
@echo OFF
|
||||
|
||||
set "AppVersionStrMajor=0.8"
|
||||
set "AppVersion=8052"
|
||||
set "AppVersionStrSmall=0.8.52"
|
||||
set "AppVersionStr=0.8.52"
|
||||
set "AppVersionStrFull=0.8.52.0"
|
||||
set "DevChannel=0"
|
||||
set "AppVersion=8053"
|
||||
set "AppVersionStrSmall=0.8.53"
|
||||
set "AppVersionStr=0.8.53"
|
||||
set "AppVersionStrFull=0.8.53.0"
|
||||
set "DevChannel=1"
|
||||
|
||||
if %DevChannel% neq 0 goto preparedev
|
||||
|
||||
|
@ -188,6 +188,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_settings_show_preview" = "Show message preview";
|
||||
"lng_settings_use_windows" = "Use Windows notifications";
|
||||
"lng_settings_sound_notify" = "Play sound";
|
||||
"lng_settings_include_muted" = "Include muted chats in the unread badge";
|
||||
|
||||
"lng_notification_preview" = "You have a new message";
|
||||
|
||||
@ -386,6 +387,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_files_header" = "Files overview";
|
||||
"lng_profile_audios" = "{count:_not_used_|# voice message|# voice messages} »";
|
||||
"lng_profile_audios_header" = "Voice messages overview";
|
||||
"lng_profile_shared_links" = "{count:_not_used_|# shared link|# shared links} »";
|
||||
"lng_profile_shared_links_header" = "Shared links overview";
|
||||
"lng_profile_audio_files_header" = "Playlist";
|
||||
"lng_profile_show_all_types" = "Show all types";
|
||||
"lng_profile_copy_phone" = "Copy phone number";
|
||||
@ -443,6 +446,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_media_type_videos" = "Video files";
|
||||
"lng_media_type_files" = "Files";
|
||||
"lng_media_type_audios" = "Voice messages";
|
||||
"lng_media_type_links" = "Shared links";
|
||||
|
||||
"lng_media_open_with" = "Open With";
|
||||
"lng_media_download" = "Download";
|
||||
|
@ -1451,6 +1451,10 @@ dropdownMediaAudios: iconedButton(dropdownMediaDocuments) {
|
||||
icon: sprite(62px, 348px, 24px, 24px);
|
||||
downIcon: sprite(62px, 348px, 24px, 24px);
|
||||
}
|
||||
dropdownMediaLinks: iconedButton(dropdownMediaDocuments) {
|
||||
icon: sprite(372px, 414px, 24px, 24px);
|
||||
downIcon: sprite(62px, 348px, 24px, 24px);
|
||||
}
|
||||
|
||||
dragFont: font(28px semibold);
|
||||
dragSubfont: font(20px semibold);
|
||||
@ -2002,3 +2006,15 @@ playerDuration: 200;
|
||||
|
||||
playlistHoverBg: #f2f2f2;
|
||||
playlistPadding: 10px;
|
||||
|
||||
linksSearchMargin: margins(20px, 20px, 20px, 0px);
|
||||
linksMaxWidth: 520px;
|
||||
linksLetterFont: font(24px);
|
||||
linksMargin: 5px;
|
||||
linksBorder: 1px;
|
||||
linksBorderColor: #eaeaea;
|
||||
linksDateColor: #000;
|
||||
linksDateMargin: 15px;
|
||||
|
||||
linksPhotoCheck: sprite(184px, 196px, 16px, 16px);
|
||||
linksPhotoChecked: sprite(168px, 196px, 16px, 16px);
|
||||
|
@ -1843,6 +1843,12 @@ namespace App {
|
||||
prepareCorners(BotKeyboardCorners, st::msgRadius, st::botKbBg);
|
||||
prepareCorners(BotKeyboardOverCorners, st::msgRadius, st::botKbOverBg);
|
||||
prepareCorners(BotKeyboardDownCorners, st::msgRadius, st::botKbDownBg);
|
||||
prepareCorners(PhotoSelectOverlayCorners, st::msgRadius, st::overviewPhotoSelectOverlay);
|
||||
|
||||
prepareCorners(DocRedCorners, st::msgRadius, st::mvDocRedColor);
|
||||
prepareCorners(DocYellowCorners, st::msgRadius, st::mvDocYellowColor);
|
||||
prepareCorners(DocGreenCorners, st::msgRadius, st::mvDocGreenColor);
|
||||
prepareCorners(DocBlueCorners, st::msgRadius, st::mvDocBlueColor);
|
||||
|
||||
prepareCorners(MessageInCorners, st::msgRadius, st::msgInBg, &st::msgInShadow);
|
||||
prepareCorners(MessageInSelectedCorners, st::msgRadius, st::msgInSelectBg, &st::msgInSelectShadow);
|
||||
|
@ -58,6 +58,12 @@ enum RoundCorners {
|
||||
BotKeyboardCorners,
|
||||
BotKeyboardOverCorners,
|
||||
BotKeyboardDownCorners,
|
||||
PhotoSelectOverlayCorners,
|
||||
|
||||
DocRedCorners,
|
||||
DocYellowCorners,
|
||||
DocGreenCorners,
|
||||
DocBlueCorners,
|
||||
|
||||
InShadowCorners, // for photos without bg
|
||||
InSelectedShadowCorners,
|
||||
|
@ -673,8 +673,8 @@ void Application::checkMapVersion() {
|
||||
if (Local::oldMapVersion() < AppVersion) {
|
||||
if (Local::oldMapVersion()) {
|
||||
QString versionFeatures;
|
||||
if (cDevVersion() && Local::oldMapVersion() < 8050) {
|
||||
versionFeatures = QString::fromUtf8("\xe2\x80\x94 Bug fixes in Windows notifications\n\xe2\x80\x94 Fixed input methods on Linux (Fcitx and IBus)");// .replace('@', qsl("@") + QChar(0x200D));
|
||||
if (cDevVersion() && Local::oldMapVersion() < 8053) {
|
||||
versionFeatures = QString::fromUtf8("\xe2\x80\x94 Include muted chats in the unread badge setting\n\xe2\x80\x94 Shared links overview and search in shared media");// .replace('@', qsl("@") + QChar(0x200D));
|
||||
} else if (!cDevVersion() && Local::oldMapVersion() < 8052) {
|
||||
versionFeatures = lang(lng_new_version_minor).trimmed();
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 167 KiB After Width: | Height: | Size: 168 KiB |
Binary file not shown.
Before Width: | Height: | Size: 220 KiB After Width: | Height: | Size: 222 KiB |
@ -16,13 +16,13 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "application.h"
|
||||
#include "pspecific.h"
|
||||
#include "autoupdater.h"
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
typedef DWORD VerInt;
|
||||
typedef WCHAR VerChar;
|
||||
|
@ -17,9 +17,9 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
static const int32 AppVersion = 8052;
|
||||
static const wchar_t *AppVersionStr = L"0.8.52";
|
||||
static const bool DevVersion = false;
|
||||
static const int32 AppVersion = 8053;
|
||||
static const wchar_t *AppVersionStr = L"0.8.53";
|
||||
static const bool DevVersion = true;
|
||||
|
||||
static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)";
|
||||
static const wchar_t *AppName = L"Telegram Desktop";
|
||||
@ -81,6 +81,7 @@ enum {
|
||||
AutoSearchTimeout = 900, // 0.9 secs
|
||||
SearchPerPage = 50,
|
||||
SearchManyPerPage = 100,
|
||||
LinksOverviewPerPage = 12,
|
||||
MediaOverviewStartPerPage = 5,
|
||||
MediaOverviewPreloadCount = 4,
|
||||
|
||||
|
@ -1700,7 +1700,6 @@ bool DialogsWidget::onSearchMessages(bool searchCache) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void DialogsWidget::onNeedSearchMessages() {
|
||||
if (!onSearchMessages(true)) {
|
||||
_searchTimer.start(AutoSearchTimeout);
|
||||
|
@ -20,6 +20,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
#include "lang.h"
|
||||
|
||||
#include "pspecific.h"
|
||||
|
||||
#include <private/qharfbuzz_p.h>
|
||||
|
||||
namespace {
|
||||
@ -788,6 +790,15 @@ void TextLink::onClick(Qt::MouseButton button) const {
|
||||
}
|
||||
}
|
||||
|
||||
void EmailLink::onClick(Qt::MouseButton button) const {
|
||||
if (button == Qt::LeftButton || button == Qt::MiddleButton) {
|
||||
QUrl url(qstr("mailto:") + _email);
|
||||
if (!QDesktopServices::openUrl(url)) {
|
||||
psOpenFile(url.toString(QUrl::FullyEncoded), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MentionLink::onClick(Qt::MouseButton button) const {
|
||||
if (button == Qt::LeftButton || button == Qt::MiddleButton) {
|
||||
App::openUserByName(_tag.mid(1), true);
|
||||
|
@ -369,11 +369,7 @@ public:
|
||||
return _email;
|
||||
}
|
||||
|
||||
void onClick(Qt::MouseButton button) const {
|
||||
if (button == Qt::LeftButton || button == Qt::MiddleButton) {
|
||||
QDesktopServices::openUrl(qsl("mailto:") + _email);
|
||||
}
|
||||
}
|
||||
void onClick(Qt::MouseButton button) const;
|
||||
|
||||
const QString &readable() const {
|
||||
return _email;
|
||||
|
@ -644,12 +644,24 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPmessage &msg, boo
|
||||
}
|
||||
|
||||
const MTPMessageMedia *media = 0;
|
||||
const QVector<MTPMessageEntity> *entities = 0;
|
||||
switch (msg.type()) {
|
||||
case mtpc_message: media = &msg.c_message().vmedia; break;
|
||||
case mtpc_message:
|
||||
media = &msg.c_message().vmedia;
|
||||
entities = msg.c_message().has_entities() ? (&msg.c_message().ventities.c_vector().v) : 0;
|
||||
break;
|
||||
}
|
||||
if (media) {
|
||||
existing->updateMedia(*media);
|
||||
}
|
||||
if (entities && !existing->hasTextLinks()) { // index forwarded messages to links overview
|
||||
existing->setText(qs(msg.c_message().vmessage), linksFromMTP(*entities));
|
||||
existing->initDimensions(0);
|
||||
if (App::main()) App::main()->itemResized(existing);
|
||||
if (existing->hasTextLinks()) {
|
||||
existing->history()->addToOverview(existing, OverviewLinks);
|
||||
}
|
||||
}
|
||||
return (returnExisting || regged) ? existing : 0;
|
||||
}
|
||||
|
||||
@ -888,6 +900,24 @@ void History::createInitialDateBlock(const QDateTime &date) {
|
||||
push_front(dateBlock); // date block
|
||||
}
|
||||
|
||||
void History::addToOverview(HistoryItem *item, MediaOverviewType type) {
|
||||
if (_overviewIds[type].constFind(item->id) == _overviewIds[type].cend()) {
|
||||
_overview[type].push_back(item->id);
|
||||
_overviewIds[type].insert(item->id, NullType());
|
||||
if (_overviewCount[type] > 0) ++_overviewCount[type];
|
||||
if (App::wnd()) App::wnd()->mediaOverviewUpdated(peer, type);
|
||||
}
|
||||
}
|
||||
|
||||
bool History::addToOverviewFront(HistoryItem *item, MediaOverviewType type) {
|
||||
if (_overviewIds[type].constFind(item->id) == _overviewIds[type].cend()) {
|
||||
_overview[type].push_front(item->id);
|
||||
_overviewIds[type].insert(item->id, NullType());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
HistoryItem *History::doAddToBack(HistoryBlock *to, bool newBlock, HistoryItem *adding, bool newMsg) {
|
||||
if (!adding) {
|
||||
if (newBlock) delete to;
|
||||
@ -928,31 +958,14 @@ HistoryItem *History::doAddToBack(HistoryBlock *to, bool newBlock, HistoryItem *
|
||||
HistoryMediaType mt = media->type();
|
||||
MediaOverviewType t = mediaToOverviewType(mt);
|
||||
if (t != OverviewCount) {
|
||||
if (_overviewIds[t].constFind(adding->id) == _overviewIds[t].cend()) {
|
||||
_overview[t].push_back(adding->id);
|
||||
_overviewIds[t].insert(adding->id, NullType());
|
||||
if (_overviewCount[t] > 0) ++_overviewCount[t];
|
||||
if (App::wnd()) App::wnd()->mediaOverviewUpdated(peer, t);
|
||||
}
|
||||
addToOverview(adding, t);
|
||||
if (mt == MediaTypeDocument && static_cast<HistoryDocument*>(media)->document()->song()) {
|
||||
t = OverviewAudioDocuments;
|
||||
if (_overviewIds[t].constFind(adding->id) == _overviewIds[t].cend()) {
|
||||
_overview[t].push_back(adding->id);
|
||||
_overviewIds[t].insert(adding->id, NullType());
|
||||
if (_overviewCount[t] > 0) ++_overviewCount[t];
|
||||
if (App::wnd()) App::wnd()->mediaOverviewUpdated(peer, t);
|
||||
}
|
||||
addToOverview(adding, OverviewAudioDocuments);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (adding->hasTextLinks()) {
|
||||
MediaOverviewType t = OverviewLinks;
|
||||
if (_overviewIds[t].constFind(adding->id) == _overviewIds[t].cend()) {
|
||||
_overview[t].push_back(adding->id);
|
||||
_overviewIds[t].insert(adding->id, NullType());
|
||||
if (_overviewCount[t] > 0) ++_overviewCount[t];
|
||||
if (App::wnd()) App::wnd()->mediaOverviewUpdated(peer, t);
|
||||
}
|
||||
addToOverview(adding, OverviewLinks);
|
||||
}
|
||||
if (adding->from()->id) {
|
||||
if (peer->chat) {
|
||||
@ -1102,28 +1115,14 @@ void History::addToFront(const QVector<MTPMessage> &slice) {
|
||||
HistoryMediaType mt = media->type();
|
||||
MediaOverviewType t = mediaToOverviewType(mt);
|
||||
if (t != OverviewCount) {
|
||||
if (_overviewIds[t].constFind(item->id) == _overviewIds[t].cend()) {
|
||||
_overview[t].push_front(item->id);
|
||||
_overviewIds[t].insert(item->id, NullType());
|
||||
mask |= (1 << t);
|
||||
}
|
||||
if (addToOverviewFront(item, t)) mask |= (1 << t);
|
||||
if (mt == MediaTypeDocument && static_cast<HistoryDocument*>(media)->document()->song()) {
|
||||
t = OverviewAudioDocuments;
|
||||
if (_overviewIds[t].constFind(item->id) == _overviewIds[t].cend()) {
|
||||
_overview[t].push_front(item->id);
|
||||
_overviewIds[t].insert(item->id, NullType());
|
||||
mask |= (1 << t);
|
||||
}
|
||||
if (addToOverviewFront(item, OverviewAudioDocuments)) mask |= (1 << OverviewAudioDocuments);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (item->hasTextLinks()) {
|
||||
MediaOverviewType t = OverviewLinks;
|
||||
if (_overviewIds[t].constFind(item->id) == _overviewIds[t].cend()) {
|
||||
_overview[t].push_front(item->id);
|
||||
_overviewIds[t].insert(item->id, NullType());
|
||||
mask |= (1 << t);
|
||||
}
|
||||
if (addToOverviewFront(item, OverviewLinks)) mask |= (1 << OverviewLinks);
|
||||
}
|
||||
if (item->from()->id) {
|
||||
if (lastAuthors) { // chats
|
||||
@ -1348,7 +1347,7 @@ void History::setUnreadCount(int32 newUnreadCount, bool psUpdate) {
|
||||
App::histories().unreadFull += newUnreadCount - unreadCount;
|
||||
if (mute) App::histories().unreadMuted += newUnreadCount - unreadCount;
|
||||
unreadCount = newUnreadCount;
|
||||
if (psUpdate) App::wnd()->updateCounter();
|
||||
if (psUpdate && (!mute || cIncludeMuted())) App::wnd()->updateCounter();
|
||||
if (unreadBar) unreadBar->setCount(unreadCount);
|
||||
}
|
||||
}
|
||||
@ -5273,6 +5272,12 @@ void HistoryMessage::setText(const QString &text, const LinksInText &links) {
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryMessage::getTextWithLinks(QString &text, LinksInText &links) {
|
||||
if (_text.isEmpty()) return;
|
||||
links = _text.calcLinksInText();
|
||||
text = _text.original();
|
||||
}
|
||||
|
||||
void HistoryMessage::draw(QPainter &p, uint32 selection) const {
|
||||
textstyleSet(&(out() ? st::outTextStyle : st::inTextStyle));
|
||||
|
||||
|
@ -185,6 +185,8 @@ struct History : public QList<HistoryBlock*> {
|
||||
void addToBack(const QVector<MTPMessage> &slice);
|
||||
void createInitialDateBlock(const QDateTime &date);
|
||||
HistoryItem *doAddToBack(HistoryBlock *to, bool newBlock, HistoryItem *adding, bool newMsg);
|
||||
void addToOverview(HistoryItem *item, MediaOverviewType type);
|
||||
bool addToOverviewFront(HistoryItem *item, MediaOverviewType type);
|
||||
|
||||
void newItemAdded(HistoryItem *item);
|
||||
void unregTyping(UserData *from);
|
||||
@ -782,6 +784,8 @@ public:
|
||||
}
|
||||
virtual void setText(const QString &text, const LinksInText &links) {
|
||||
}
|
||||
virtual void getTextWithLinks(QString &text, LinksInText &links) {
|
||||
}
|
||||
virtual QString time() const {
|
||||
return QString();
|
||||
}
|
||||
@ -1181,6 +1185,10 @@ public:
|
||||
}
|
||||
ImagePtr replyPreview();
|
||||
|
||||
WebPageData *webpage() {
|
||||
return data;
|
||||
}
|
||||
|
||||
private:
|
||||
WebPageData *data;
|
||||
TextLinkPtr _openl, _photol;
|
||||
@ -1328,6 +1336,7 @@ public:
|
||||
HistoryMedia *getMedia(bool inOverview = false) const;
|
||||
void setMedia(const MTPmessageMedia &media);
|
||||
void setText(const QString &text, const LinksInText &links);
|
||||
void getTextWithLinks(QString &text, LinksInText &links);
|
||||
|
||||
QString time() const {
|
||||
return _time;
|
||||
|
@ -730,6 +730,14 @@ namespace {
|
||||
cSetSoundNotify(v == 1);
|
||||
} break;
|
||||
|
||||
case dbiIncludeMuted: {
|
||||
qint32 v;
|
||||
stream >> v;
|
||||
if (!_checkStreamStatus(stream)) return false;
|
||||
|
||||
cSetIncludeMuted(v == 1);
|
||||
} break;
|
||||
|
||||
case dbiDesktopNotify: {
|
||||
qint32 v;
|
||||
stream >> v;
|
||||
@ -1281,7 +1289,7 @@ namespace {
|
||||
_writeMap(WriteMapFast);
|
||||
}
|
||||
|
||||
uint32 size = 13 * (sizeof(quint32) + sizeof(qint32));
|
||||
uint32 size = 14 * (sizeof(quint32) + sizeof(qint32));
|
||||
size += sizeof(quint32) + _stringSize(cAskDownloadPath() ? QString() : cDownloadPath());
|
||||
size += sizeof(quint32) + sizeof(qint32) + (cRecentEmojisPreload().isEmpty() ? cGetRecentEmojis().size() : cRecentEmojisPreload().size()) * (sizeof(uint64) + sizeof(ushort));
|
||||
size += sizeof(quint32) + sizeof(qint32) + cEmojiVariants().size() * (sizeof(uint32) + sizeof(uint64));
|
||||
@ -1295,6 +1303,7 @@ namespace {
|
||||
data.stream << quint32(dbiReplaceEmojis) << qint32(cReplaceEmojis() ? 1 : 0);
|
||||
data.stream << quint32(dbiDefaultAttach) << qint32(cDefaultAttach());
|
||||
data.stream << quint32(dbiSoundNotify) << qint32(cSoundNotify());
|
||||
data.stream << quint32(dbiIncludeMuted) << qint32(cIncludeMuted());
|
||||
data.stream << quint32(dbiDesktopNotify) << qint32(cDesktopNotify());
|
||||
data.stream << quint32(dbiNotifyView) << qint32(cNotifyView());
|
||||
data.stream << quint32(dbiWindowsNotifications) << qint32(cWindowsNotifications());
|
||||
|
@ -1183,6 +1183,7 @@ void MainWidget::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type) {
|
||||
case OverviewVideos: connect(_mediaType.addButton(new IconedButton(this, st::dropdownMediaVideos, lang(lng_media_type_videos))), SIGNAL(clicked()), this, SLOT(onVideosSelect())); break;
|
||||
case OverviewDocuments: connect(_mediaType.addButton(new IconedButton(this, st::dropdownMediaDocuments, lang(lng_media_type_files))), SIGNAL(clicked()), this, SLOT(onDocumentsSelect())); break;
|
||||
case OverviewAudios: connect(_mediaType.addButton(new IconedButton(this, st::dropdownMediaAudios, lang(lng_media_type_audios))), SIGNAL(clicked()), this, SLOT(onAudiosSelect())); break;
|
||||
case OverviewLinks: connect(_mediaType.addButton(new IconedButton(this, st::dropdownMediaLinks, lang(lng_media_type_links))), SIGNAL(clicked()), this, SLOT(onLinksSelect())); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1203,6 +1204,9 @@ void MainWidget::itemRemoved(HistoryItem *item) {
|
||||
if (history.peer() == item->history()->peer) {
|
||||
history.itemRemoved(item);
|
||||
}
|
||||
if (overview && overview->peer() == item->history()->peer) {
|
||||
overview->itemRemoved(item);
|
||||
}
|
||||
itemRemovedGif(item);
|
||||
if (!_toForward.isEmpty()) {
|
||||
SelectedItemSet::iterator i = _toForward.find(item->id);
|
||||
@ -2240,9 +2244,13 @@ void MainWidget::sentDataReceived(uint64 randomId, const MTPmessages_SentMessage
|
||||
if (!text.isEmpty() && !links.isEmpty()) {
|
||||
item = App::histItemById(d.vid.v);
|
||||
if (item) {
|
||||
bool was = item->hasTextLinks();
|
||||
item->setText(text, links);
|
||||
item->initDimensions(0);
|
||||
itemResized(item);
|
||||
if (!was && item->hasTextLinks()) {
|
||||
item->history()->addToOverview(item, OverviewLinks);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2273,9 +2281,13 @@ void MainWidget::sentDataReceived(uint64 randomId, const MTPmessages_SentMessage
|
||||
//if (!text.isEmpty() && !links.isEmpty()) {
|
||||
// item = App::histItemById(d.vid.v);
|
||||
// if (item) {
|
||||
// bool was = item->hasTextLinks();
|
||||
// item->setText(text, links);
|
||||
// item->initDimensions(0);
|
||||
// itemResized(item);
|
||||
// if (!was && item->hasTextLinks()) {
|
||||
// item->history()->addToOverview(item, OverviewLinks);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
@ -2544,6 +2556,11 @@ void MainWidget::onAudiosSelect() {
|
||||
_mediaType.hideStart();
|
||||
}
|
||||
|
||||
void MainWidget::onLinksSelect() {
|
||||
if (overview) overview->switchType(OverviewLinks);
|
||||
_mediaType.hideStart();
|
||||
}
|
||||
|
||||
TopBarWidget *MainWidget::topBar() {
|
||||
return &_topBar;
|
||||
}
|
||||
@ -3389,7 +3406,7 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) {
|
||||
return;
|
||||
}
|
||||
bool out = (d.vflags.v & MTPDmessage_flag_out);
|
||||
HistoryItem *item = App::histories().addToBack(MTP_message(d.vflags, d.vid, out ? MTP_int(MTP::authedId()) : d.vuser_id, MTP_peerUser(out ? d.vuser_id : MTP_int(MTP::authedId())), d.vfwd_from_id, d.vfwd_date, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup, MTPnullEntities));
|
||||
HistoryItem *item = App::histories().addToBack(MTP_message(d.vflags, d.vid, out ? MTP_int(MTP::authedId()) : d.vuser_id, MTP_peerUser(out ? d.vuser_id : MTP_int(MTP::authedId())), d.vfwd_from_id, d.vfwd_date, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup, d.has_entities() ? d.ventities : MTPnullEntities));
|
||||
if (item) {
|
||||
history.peerMessagesUpdated(item->history()->peer->id);
|
||||
}
|
||||
@ -3409,7 +3426,7 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) {
|
||||
_byPtsUpdates.insert(ptsKey(SkippedUpdates), updates);
|
||||
return;
|
||||
}
|
||||
HistoryItem *item = App::histories().addToBack(MTP_message(d.vflags, d.vid, d.vfrom_id, MTP_peerChat(d.vchat_id), d.vfwd_from_id, d.vfwd_date, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup, MTPnullEntities));
|
||||
HistoryItem *item = App::histories().addToBack(MTP_message(d.vflags, d.vid, d.vfrom_id, MTP_peerChat(d.vchat_id), d.vfwd_from_id, d.vfwd_date, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup, d.has_entities() ? d.ventities : MTPnullEntities));
|
||||
if (item) {
|
||||
history.peerMessagesUpdated(item->history()->peer->id);
|
||||
}
|
||||
|
@ -429,6 +429,7 @@ public slots:
|
||||
void onVideosSelect();
|
||||
void onDocumentsSelect();
|
||||
void onAudiosSelect();
|
||||
void onLinksSelect();
|
||||
|
||||
void onForwardCancel(QObject *obj = 0);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -25,9 +25,14 @@ public:
|
||||
|
||||
OverviewInner(OverviewWidget *overview, ScrollArea *scroll, const PeerData *peer, MediaOverviewType type);
|
||||
|
||||
void activate();
|
||||
|
||||
void clear();
|
||||
int32 itemTop(MsgId msgId) const;
|
||||
|
||||
bool preloadLocal();
|
||||
void preloadMore();
|
||||
|
||||
bool event(QEvent *e);
|
||||
void touchEvent(QTouchEvent *e);
|
||||
void paintEvent(QPaintEvent *e);
|
||||
@ -75,6 +80,7 @@ public slots:
|
||||
void onUpdateSelected();
|
||||
|
||||
void openContextUrl();
|
||||
void copyContextUrl();
|
||||
void cancelContextDownload();
|
||||
void showContextInFolder();
|
||||
void saveContextFile();
|
||||
@ -85,12 +91,19 @@ public slots:
|
||||
void forwardMessage();
|
||||
void selectMessage();
|
||||
|
||||
void onSearchUpdate();
|
||||
void onCancel();
|
||||
bool onCancelSearch();
|
||||
|
||||
void onMenuDestroy(QObject *obj);
|
||||
void onTouchSelect();
|
||||
void onTouchScrollTimer();
|
||||
|
||||
void onDragExec();
|
||||
|
||||
bool onSearchMessages(bool searchCache = false);
|
||||
void onNeedSearchMessages();
|
||||
|
||||
private:
|
||||
|
||||
void fixItemIndex(int32 ¤t, MsgId msgId) const;
|
||||
@ -122,11 +135,11 @@ private:
|
||||
|
||||
// photos
|
||||
int32 _photosInRow, _photosToAdd, _vsize;
|
||||
typedef struct {
|
||||
struct CachedSize {
|
||||
int32 vsize;
|
||||
bool medium;
|
||||
QPixmap pix;
|
||||
} CachedSize;
|
||||
};
|
||||
typedef QMap<PhotoData*, CachedSize> CachedSizes;
|
||||
CachedSizes _cached;
|
||||
bool _selMode;
|
||||
@ -134,16 +147,65 @@ private:
|
||||
// audio documents
|
||||
int32 _audioLeft, _audioWidth, _audioHeight;
|
||||
|
||||
// other
|
||||
typedef struct _CachedItem {
|
||||
_CachedItem() : msgid(0), y(0) {
|
||||
// shared links
|
||||
int32 _linksLeft, _linksWidth;
|
||||
struct Link {
|
||||
Link() : width(0) {
|
||||
}
|
||||
_CachedItem(MsgId msgid, const QDate &date, int32 y) : msgid(msgid), date(date), y(y) {
|
||||
Link(const QString &url, const QString &text) : url(url), text(text), width(st::msgFont->m.width(text)) {
|
||||
}
|
||||
QString url, text;
|
||||
int32 width;
|
||||
};
|
||||
struct CachedLink {
|
||||
CachedLink() : titleWidth(0), page(0), pixw(0), pixh(0), text(st::msgMinWidth) {
|
||||
}
|
||||
CachedLink(HistoryItem *item);
|
||||
int32 countHeight(int32 w);
|
||||
|
||||
QString title, letter;
|
||||
int32 titleWidth;
|
||||
WebPageData *page;
|
||||
int32 pixw, pixh;
|
||||
Text text;
|
||||
QVector<Link> urls;
|
||||
};
|
||||
typedef QMap<MsgId, CachedLink*> CachedLinks;
|
||||
CachedLinks _links;
|
||||
FlatInput _search;
|
||||
IconedButton _cancelSearch;
|
||||
QVector<MsgId> _results;
|
||||
int32 _itemsToBeLoaded;
|
||||
|
||||
QTimer _searchTimer;
|
||||
QString _searchQuery;
|
||||
bool _inSearch, _searchFull;
|
||||
mtpRequestId _searchRequest;
|
||||
History::MediaOverview _searchResults;
|
||||
MsgId _lastSearchId;
|
||||
int32 _searchedCount;
|
||||
void searchReceived(bool fromStart, const MTPmessages_Messages &result, mtpRequestId req);
|
||||
bool searchFailed(const RPCError &error, mtpRequestId req);
|
||||
|
||||
typedef QMap<QString, MTPmessages_Messages> SearchCache;
|
||||
SearchCache _searchCache;
|
||||
|
||||
typedef QMap<mtpRequestId, QString> SearchQueries;
|
||||
SearchQueries _searchQueries;
|
||||
|
||||
CachedLink *cachedLink(HistoryItem *item);
|
||||
|
||||
// other
|
||||
struct CachedItem {
|
||||
CachedItem() : msgid(0), y(0) {
|
||||
}
|
||||
CachedItem(MsgId msgid, const QDate &date, int32 y) : msgid(msgid), date(date), y(y) {
|
||||
}
|
||||
MsgId msgid;
|
||||
QDate date;
|
||||
int32 y;
|
||||
} CachedItem;
|
||||
CachedLink *link;
|
||||
};
|
||||
typedef QVector<CachedItem> CachedItems;
|
||||
CachedItems _items;
|
||||
|
||||
@ -166,9 +228,14 @@ private:
|
||||
int32 _dragItemIndex;
|
||||
MsgId _mousedItem;
|
||||
int32 _mousedItemIndex;
|
||||
int32 _lnkOverIndex, _lnkDownIndex; // for OverviewLinks, 0 - none, -1 - photo or title, > 0 - lnk index
|
||||
uint16 _dragSymbol;
|
||||
bool _dragWasInactive;
|
||||
|
||||
QString urlByIndex(MsgId msgid, int32 index, int32 lnkIndex) const;
|
||||
bool urlIsEmail(const QString &url) const;
|
||||
|
||||
QString _contextMenuUrl;
|
||||
TextLinkPtr _contextMenuLnk;
|
||||
|
||||
MsgId _dragSelFrom, _dragSelTo;
|
||||
@ -202,6 +269,7 @@ public:
|
||||
void contextMenuEvent(QContextMenuEvent *e);
|
||||
|
||||
void scrollBy(int32 add);
|
||||
void scrollReset();
|
||||
|
||||
void paintTopBar(QPainter &p, float64 over, int32 decreaseWidth);
|
||||
void topBarShadowParams(int32 &x, float64 &o);
|
||||
|
@ -59,10 +59,6 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const Pee
|
||||
// shared media
|
||||
_allMediaTypes(false),
|
||||
_mediaShowAll(this, lang(lng_profile_show_all_types)),
|
||||
_mediaPhotos(this, QString()),
|
||||
_mediaVideos(this, QString()),
|
||||
_mediaDocuments(this, QString()),
|
||||
_mediaAudios(this, QString()),
|
||||
|
||||
// actions
|
||||
_searchInPeer(this, lang(lng_profile_search_messages)),
|
||||
@ -161,14 +157,11 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const Pee
|
||||
|
||||
// shared media
|
||||
connect(&_mediaShowAll, SIGNAL(clicked()), this, SLOT(onMediaShowAll()));
|
||||
connect(&_mediaPhotos, SIGNAL(clicked()), this, SLOT(onMediaPhotos()));
|
||||
connect(&_mediaVideos, SIGNAL(clicked()), this, SLOT(onMediaVideos()));
|
||||
connect(&_mediaDocuments, SIGNAL(clicked()), this, SLOT(onMediaDocuments()));
|
||||
connect(&_mediaAudios, SIGNAL(clicked()), this, SLOT(onMediaAudios()));
|
||||
_mediaLinks[OverviewPhotos] = &_mediaPhotos;
|
||||
_mediaLinks[OverviewVideos] = &_mediaVideos;
|
||||
_mediaLinks[OverviewDocuments] = &_mediaDocuments;
|
||||
_mediaLinks[OverviewAudios] = &_mediaAudios;
|
||||
connect((_mediaButtons[OverviewPhotos] = new LinkButton(this, QString())), SIGNAL(clicked()), this, SLOT(onMediaPhotos()));
|
||||
connect((_mediaButtons[OverviewVideos] = new LinkButton(this, QString())), SIGNAL(clicked()), this, SLOT(onMediaVideos()));
|
||||
connect((_mediaButtons[OverviewDocuments] = new LinkButton(this, QString())), SIGNAL(clicked()), this, SLOT(onMediaDocuments()));
|
||||
connect((_mediaButtons[OverviewAudios] = new LinkButton(this, QString())), SIGNAL(clicked()), this, SLOT(onMediaAudios()));
|
||||
connect((_mediaButtons[OverviewLinks] = new LinkButton(this, QString())), SIGNAL(clicked()), this, SLOT(onMediaLinks()));
|
||||
App::main()->preloadOverviews(_peer);
|
||||
|
||||
// actions
|
||||
@ -216,7 +209,7 @@ void ProfileInner::loadProfilePhotos(int32 yFrom) {
|
||||
int32 yTo = yFrom + (parentWidget() ? parentWidget()->height() : App::wnd()->height()) * 5;
|
||||
MTP::clearLoaderPriorities();
|
||||
|
||||
int32 partfrom = _mediaAudios.y() + _mediaAudios.height() + st::profileHeaderSkip;
|
||||
int32 partfrom = _mediaButtons[OverviewAudios]->y() + _mediaButtons[OverviewAudios]->height() + st::profileHeaderSkip;
|
||||
yFrom -= partfrom;
|
||||
yTo -= partfrom;
|
||||
|
||||
@ -361,6 +354,10 @@ void ProfileInner::onMediaAudios() {
|
||||
App::main()->showMediaOverview(_peer, OverviewAudios);
|
||||
}
|
||||
|
||||
void ProfileInner::onMediaLinks() {
|
||||
App::main()->showMediaOverview(_peer, OverviewLinks);
|
||||
}
|
||||
|
||||
void ProfileInner::onInvitationLink() {
|
||||
QApplication::clipboard()->setText(_peerChat->invitationUrl);
|
||||
App::wnd()->showLayer(new ConfirmBox(lang(lng_group_invite_copied), true));
|
||||
@ -652,7 +649,7 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
|
||||
if (!_allMediaTypes) {
|
||||
break;
|
||||
}
|
||||
top += _mediaLinks[i]->height() + st::setLittleSkip;
|
||||
top += _mediaButtons[i]->height() + st::setLittleSkip;
|
||||
}
|
||||
}
|
||||
if (_allMediaTypes) {
|
||||
@ -660,13 +657,13 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
|
||||
top -= st::setLittleSkip;
|
||||
} else {
|
||||
p.drawText(_left, top + st::linkFont->ascent, lang(oneState < 0 ? lng_profile_loading : lng_profile_no_media));
|
||||
top += _mediaLinks[OverviewPhotos]->height();
|
||||
top += _mediaButtons[OverviewPhotos]->height();
|
||||
}
|
||||
} else {
|
||||
if (!oneState) {
|
||||
p.drawText(_left, top + st::linkFont->ascent, lang(lng_profile_no_media));
|
||||
}
|
||||
top += _mediaLinks[OverviewPhotos]->height();
|
||||
top += _mediaButtons[OverviewPhotos]->height();
|
||||
}
|
||||
|
||||
// actions
|
||||
@ -934,13 +931,13 @@ void ProfileInner::resizeEvent(QResizeEvent *e) {
|
||||
if (_allMediaTypes) {
|
||||
int32 count = (_hist->_overviewCount[i] > 0) ? _hist->_overviewCount[i] : (_hist->_overviewCount[i] == 0 ? _hist->_overview[i].size() : -1);
|
||||
if (count > 0) {
|
||||
if (wasCount) top += _mediaLinks[i]->height() + st::setLittleSkip;
|
||||
if (wasCount) top += _mediaButtons[i]->height() + st::setLittleSkip;
|
||||
wasCount = count;
|
||||
}
|
||||
}
|
||||
_mediaLinks[i]->move(_left, top);
|
||||
_mediaButtons[i]->move(_left, top);
|
||||
}
|
||||
top += _mediaLinks[OverviewPhotos]->height();
|
||||
top += _mediaButtons[OverviewPhotos]->height();
|
||||
|
||||
// actions
|
||||
top += st::profileHeaderSkip;
|
||||
@ -1131,17 +1128,17 @@ void ProfileInner::showAll() {
|
||||
if (count > 0 || count < 0) {
|
||||
first = true;
|
||||
} else if (!_allMediaTypes) {
|
||||
_mediaLinks[i]->hide();
|
||||
_mediaButtons[i]->hide();
|
||||
continue;
|
||||
}
|
||||
if (count > 0) {
|
||||
_mediaLinks[i]->setText(overviewLinkText(i, count));
|
||||
_mediaLinks[i]->show();
|
||||
_mediaButtons[i]->setText(overviewLinkText(i, count));
|
||||
_mediaButtons[i]->show();
|
||||
} else {
|
||||
_mediaLinks[i]->hide();
|
||||
_mediaButtons[i]->hide();
|
||||
}
|
||||
} else {
|
||||
_mediaLinks[i]->hide();
|
||||
_mediaButtons[i]->hide();
|
||||
}
|
||||
}
|
||||
if (_allMediaTypes || !manyCounts) {
|
||||
@ -1208,6 +1205,7 @@ QString ProfileInner::overviewLinkText(int32 type, int32 count) {
|
||||
case OverviewVideos: return lng_profile_videos(lt_count, count);
|
||||
case OverviewDocuments: return lng_profile_files(lt_count, count);
|
||||
case OverviewAudios: return lng_profile_audios(lt_count, count);
|
||||
case OverviewLinks: return lng_profile_shared_links(lt_count, count);
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
@ -92,6 +92,7 @@ public slots:
|
||||
void onMediaVideos();
|
||||
void onMediaDocuments();
|
||||
void onMediaAudios();
|
||||
void onMediaLinks();
|
||||
|
||||
void onMenuDestroy(QObject *obj);
|
||||
void onCopyPhone();
|
||||
@ -149,8 +150,8 @@ private:
|
||||
|
||||
// shared media
|
||||
bool _allMediaTypes;
|
||||
LinkButton _mediaShowAll, _mediaPhotos, _mediaVideos, _mediaDocuments, _mediaAudios;
|
||||
LinkButton *_mediaLinks[OverviewCount];
|
||||
LinkButton _mediaShowAll;
|
||||
LinkButton *_mediaButtons[OverviewCount];
|
||||
QString overviewLinkText(int32 type, int32 count);
|
||||
|
||||
// actions
|
||||
|
@ -252,8 +252,8 @@ namespace {
|
||||
#define GTK_ALPHA 3
|
||||
|
||||
QImage _trayIconImageGen() {
|
||||
int32 counter = App::histories().unreadFull, counterSlice = (counter >= 1000) ? (1000 + (counter % 100)) : counter;
|
||||
bool muted = (App::histories().unreadMuted >= counter);
|
||||
int32 counter = App::histories().unreadFull - (cIncludeMuted() ? 0 : App::histories().unreadMuted), counterSlice = (counter >= 1000) ? (1000 + (counter % 100)) : counter;
|
||||
bool muted = cIncludeMuted() ? (App::histories().unreadMuted >= counter) : false;
|
||||
if (_trayIconImage.isNull() || _trayIconImage.width() != _trayIconSize || muted != _trayIconMuted || counterSlice != _trayIconCount) {
|
||||
if (_trayIconImageBack.isNull() || _trayIconImageBack.width() != _trayIconSize) {
|
||||
_trayIconImageBack = App::wnd()->iconLarge().scaled(_trayIconSize, _trayIconSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
@ -288,8 +288,8 @@ namespace {
|
||||
}
|
||||
|
||||
QString _trayIconImageFile() {
|
||||
int32 counter = App::histories().unreadFull, counterSlice = (counter >= 1000) ? (1000 + (counter % 100)) : counter;
|
||||
bool muted = (App::histories().unreadMuted >= counter);
|
||||
int32 counter = App::histories().unreadFull - (cIncludeMuted() ? 0 : App::histories().unreadMuted), counterSlice = (counter >= 1000) ? (1000 + (counter % 100)) : counter;
|
||||
bool muted = cIncludeMuted() ? (App::histories().unreadMuted >= counter) : false;
|
||||
|
||||
QString name = cWorkingDir() + qsl("tdata/ticons/ico%1_%2_%3.png").arg(muted ? "mute" : "").arg(_trayIconSize).arg(counterSlice);
|
||||
QFileInfo info(name);
|
||||
@ -641,7 +641,7 @@ void PsMainWindow::psUpdateIndicator() {
|
||||
void PsMainWindow::psUpdateCounter() {
|
||||
setWindowIcon(wndIcon);
|
||||
|
||||
int32 counter = App::histories().unreadFull;
|
||||
int32 counter = App::histories().unreadFull - (cIncludeMuted() ? 0 : App::histories().unreadMuted);
|
||||
|
||||
setWindowTitle((counter > 0) ? qsl("Telegram (%1)").arg(counter) : qsl("Telegram"));
|
||||
if (_psUnityLauncherEntry) {
|
||||
@ -665,8 +665,10 @@ void PsMainWindow::psUpdateCounter() {
|
||||
ps_gtk_status_icon_set_from_pixbuf(_trayIcon, _trayPixbuf);
|
||||
}
|
||||
} else if (trayIcon) {
|
||||
int32 counter = App::histories().unreadFull;
|
||||
style::color bg = (App::histories().unreadMuted < counter) ? st::counterBG : st::counterMuteBG;
|
||||
int32 counter = App::histories().unreadFull - (cIncludeMuted() ? 0 : App::histories().unreadMuted);
|
||||
bool muted = cIncludeMuted() ? (App::histories().unreadMuted >= counter) : false;
|
||||
|
||||
style::color bg = muted ? st::counterMuteBG : st::counterBG;
|
||||
QIcon iconSmall;
|
||||
iconSmall.addPixmap(QPixmap::fromImage(iconWithCounter(16, counter, bg, true), Qt::ColorOnly));
|
||||
iconSmall.addPixmap(QPixmap::fromImage(iconWithCounter(32, counter, bg, true), Qt::ColorOnly));
|
||||
|
@ -174,7 +174,7 @@ void _placeCounter(QImage &img, int size, int count, style::color bg, style::col
|
||||
}
|
||||
|
||||
void PsMainWindow::psUpdateCounter() {
|
||||
int32 counter = App::histories().unreadFull;
|
||||
int32 counter = App::histories().unreadFull - (cIncludeMuted() ? 0 : App::histories().unreadMuted);
|
||||
|
||||
setWindowTitle((counter > 0) ? qsl("Telegram (%1)").arg(counter) : qsl("Telegram"));
|
||||
setWindowIcon(wndIcon);
|
||||
@ -183,14 +183,16 @@ void PsMainWindow::psUpdateCounter() {
|
||||
_private.setWindowBadge(counter ? cnt : QString());
|
||||
|
||||
if (trayIcon) {
|
||||
bool dm = objc_darkMode(), important = (App::histories().unreadMuted < counter);
|
||||
style::color bg = important ? st::counterBG : st::counterMuteBG;
|
||||
bool muted = cIncludeMuted() ? (App::histories().unreadMuted >= counter) : false;
|
||||
bool dm = objc_darkMode();
|
||||
|
||||
style::color bg = muted ? st::counterMuteBG : st::counterBG;
|
||||
QIcon icon;
|
||||
QImage img(psTrayIcon(dm)), imgsel(psTrayIcon(true));
|
||||
img.detach();
|
||||
imgsel.detach();
|
||||
int32 size = cRetina() ? 44 : 22;
|
||||
_placeCounter(img, size, counter, bg, (dm && !important) ? st::counterMacInvColor : st::counterColor);
|
||||
_placeCounter(img, size, counter, bg, (dm && muted) ? st::counterMacInvColor : st::counterColor);
|
||||
_placeCounter(imgsel, size, counter, st::white, st::counterMacInvColor);
|
||||
icon.addPixmap(QPixmap::fromImage(img, Qt::ColorOnly));
|
||||
icon.addPixmap(QPixmap::fromImage(imgsel, Qt::ColorOnly), QIcon::Selected);
|
||||
|
@ -1117,8 +1117,10 @@ static HICON _qt_createHIcon(const QIcon &icon, int xSize, int ySize) {
|
||||
}
|
||||
|
||||
void PsMainWindow::psUpdateCounter() {
|
||||
int32 counter = App::histories().unreadFull;
|
||||
style::color bg = (App::histories().unreadMuted < counter) ? st::counterBG : st::counterMuteBG;
|
||||
int32 counter = App::histories().unreadFull - (cIncludeMuted() ? 0 : App::histories().unreadMuted);
|
||||
bool muted = cIncludeMuted() ? (App::histories().unreadMuted >= counter) : false;
|
||||
|
||||
style::color bg = muted ? st::counterMuteBG : st::counterBG;
|
||||
QIcon iconSmall, iconBig;
|
||||
iconSmall.addPixmap(QPixmap::fromImage(iconWithCounter(16, counter, bg, true), Qt::ColorOnly));
|
||||
iconSmall.addPixmap(QPixmap::fromImage(iconWithCounter(32, counter, bg, true), Qt::ColorOnly));
|
||||
@ -2123,12 +2125,14 @@ bool psShowOpenWithMenu(int x, int y, const QString &file) {
|
||||
}
|
||||
|
||||
void psOpenFile(const QString &name, bool openWith) {
|
||||
std::wstring wname = QDir::toNativeSeparators(name).toStdWString();
|
||||
bool mailtoScheme = name.startsWith(qstr("mailto:"));
|
||||
std::wstring wname = mailtoScheme ? name.toStdWString() : QDir::toNativeSeparators(name).toStdWString();
|
||||
|
||||
if (openWith && useOpenAs) {
|
||||
if (shOpenWithDialog) {
|
||||
OPENASINFO info;
|
||||
info.oaifInFlags = OAIF_ALLOW_REGISTRATION | OAIF_REGISTER_EXT | OAIF_EXEC;
|
||||
if (mailtoScheme) info.oaifInFlags |= OAIF_FILE_IS_URI | OAIF_URL_PROTOCOL;
|
||||
info.pcszClass = NULL;
|
||||
info.pcszFile = wname.c_str();
|
||||
shOpenWithDialog(0, &info);
|
||||
|
@ -40,6 +40,7 @@ QString gLangErrors;
|
||||
QString gDialogLastPath, gDialogHelperPath; // optimize QFileDialog
|
||||
|
||||
bool gSoundNotify = true;
|
||||
bool gIncludeMuted = true;
|
||||
bool gDesktopNotify = true;
|
||||
DBINotifyView gNotifyView = dbinvShowPreview;
|
||||
bool gWindowsNotifications = true;
|
||||
|
@ -96,6 +96,7 @@ DeclareSetting(QPixmapPointer, ChatDogImage);
|
||||
DeclareSetting(bool, TileBackground);
|
||||
|
||||
DeclareSetting(bool, SoundNotify);
|
||||
DeclareSetting(bool, IncludeMuted);
|
||||
DeclareSetting(bool, NeedConfigResave);
|
||||
DeclareSetting(bool, DesktopNotify);
|
||||
DeclareSetting(DBINotifyView, NotifyView);
|
||||
|
@ -124,6 +124,7 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : QWidget(parent),
|
||||
_messagePreview(this, lang(lng_settings_show_preview), cNotifyView() <= dbinvShowPreview),
|
||||
_windowsNotifications(this, lang(lng_settings_use_windows), cWindowsNotifications()),
|
||||
_soundNotify(this, lang(lng_settings_sound_notify), cSoundNotify()),
|
||||
_includeMuted(this, lang(lng_settings_include_muted), cIncludeMuted()),
|
||||
|
||||
// general
|
||||
_changeLanguage(this, lang(lng_settings_change_lang)),
|
||||
@ -225,6 +226,7 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : QWidget(parent),
|
||||
connect(&_messagePreview, SIGNAL(changed()), this, SLOT(onMessagePreview()));
|
||||
connect(&_windowsNotifications, SIGNAL(changed()), this, SLOT(onWindowsNotifications()));
|
||||
connect(&_soundNotify, SIGNAL(changed()), this, SLOT(onSoundNotify()));
|
||||
connect(&_includeMuted, SIGNAL(changed()), this, SLOT(onIncludeMuted()));
|
||||
|
||||
// general
|
||||
connect(&_changeLanguage, SIGNAL(clicked()), this, SLOT(onChangeLanguage()));
|
||||
@ -431,7 +433,8 @@ void SettingsInner::paintEvent(QPaintEvent *e) {
|
||||
if (App::wnd()->psHasNativeNotifications() && cPlatform() == dbipWindows) {
|
||||
top += _windowsNotifications.height() + st::setSectionSkip;
|
||||
}
|
||||
top += _soundNotify.height();
|
||||
top += _soundNotify.height() + st::setSectionSkip;
|
||||
top += _includeMuted.height();
|
||||
}
|
||||
|
||||
// general
|
||||
@ -662,7 +665,8 @@ void SettingsInner::resizeEvent(QResizeEvent *e) {
|
||||
if (App::wnd()->psHasNativeNotifications() && cPlatform() == dbipWindows) {
|
||||
_windowsNotifications.move(_left, top); top += _windowsNotifications.height() + st::setSectionSkip;
|
||||
}
|
||||
_soundNotify.move(_left, top); top += _soundNotify.height();
|
||||
_soundNotify.move(_left, top); top += _soundNotify.height() + st::setSectionSkip;
|
||||
_includeMuted.move(_left, top); top += _includeMuted.height();
|
||||
}
|
||||
|
||||
// general
|
||||
@ -976,12 +980,14 @@ void SettingsInner::showAll() {
|
||||
_windowsNotifications.hide();
|
||||
}
|
||||
_soundNotify.show();
|
||||
_includeMuted.show();
|
||||
} else {
|
||||
_desktopNotify.hide();
|
||||
_senderName.hide();
|
||||
_messagePreview.hide();
|
||||
_windowsNotifications.hide();
|
||||
_soundNotify.hide();
|
||||
_includeMuted.hide();
|
||||
}
|
||||
|
||||
// general
|
||||
@ -1443,6 +1449,12 @@ void SettingsInner::onSoundNotify() {
|
||||
Local::writeUserSettings();
|
||||
}
|
||||
|
||||
void SettingsInner::onIncludeMuted() {
|
||||
cSetIncludeMuted(_includeMuted.checked());
|
||||
if (App::wnd()) App::wnd()->updateCounter();
|
||||
Local::writeUserSettings();
|
||||
}
|
||||
|
||||
void SettingsInner::onWindowsNotifications() {
|
||||
cSetWindowsNotifications(!cWindowsNotifications());
|
||||
App::wnd()->notifyClearFast();
|
||||
|
@ -125,6 +125,7 @@ public slots:
|
||||
void onScaleChange();
|
||||
|
||||
void onSoundNotify();
|
||||
void onIncludeMuted();
|
||||
void onDesktopNotify();
|
||||
void onSenderName();
|
||||
void onMessagePreview();
|
||||
@ -206,7 +207,7 @@ private:
|
||||
LinkButton _chooseUsername;
|
||||
|
||||
// notifications
|
||||
FlatCheckbox _desktopNotify, _senderName, _messagePreview, _windowsNotifications, _soundNotify;
|
||||
FlatCheckbox _desktopNotify, _senderName, _messagePreview, _windowsNotifications, _soundNotify, _includeMuted;
|
||||
|
||||
// general
|
||||
LinkButton _changeLanguage;
|
||||
|
@ -258,8 +258,10 @@ void TitleWidget::updateWideMode() {
|
||||
void TitleWidget::updateCounter() {
|
||||
if (cWideMode() || !MTP::authedId()) return;
|
||||
|
||||
int32 counter = App::histories().unreadFull;
|
||||
style::color bg = (App::histories().unreadMuted < counter) ? st::counterBG : st::counterMuteBG;
|
||||
int32 counter = App::histories().unreadFull - (cIncludeMuted() ? 0 : App::histories().unreadMuted);
|
||||
bool muted = cIncludeMuted() ? (App::histories().unreadMuted >= counter) : false;
|
||||
|
||||
style::color bg = muted ? st::counterMuteBG : st::counterBG;
|
||||
|
||||
if (counter > 0) {
|
||||
int32 size = cRetina() ? -32 : -16;
|
||||
|
@ -275,6 +275,7 @@ enum DataBlockId {
|
||||
dbiTryIPv6 = 0x28,
|
||||
dbiSongVolume = 0x29,
|
||||
dbiWindowsNotifications = 0x30,
|
||||
dbiIncludeMuted = 0x31,
|
||||
|
||||
dbiEncryptedWithSalt = 333,
|
||||
dbiEncrypted = 444,
|
||||
|
@ -11,7 +11,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.8.52</string>
|
||||
<string>0.8.53</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>CFBundleSignature</key>
|
||||
|
Binary file not shown.
@ -1707,7 +1707,7 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 0.8.52;
|
||||
CURRENT_PROJECT_VERSION = 0.8.53;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
@ -1725,7 +1725,7 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
CURRENT_PROJECT_VERSION = 0.8.52;
|
||||
CURRENT_PROJECT_VERSION = 0.8.53;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = fast;
|
||||
GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h;
|
||||
@ -1751,10 +1751,10 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 0.8.52;
|
||||
CURRENT_PROJECT_VERSION = 0.8.53;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DYLIB_COMPATIBILITY_VERSION = 0.8;
|
||||
DYLIB_CURRENT_VERSION = 0.8.52;
|
||||
DYLIB_CURRENT_VERSION = 0.8.53;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = "";
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
@ -1885,10 +1885,10 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 0.8.52;
|
||||
CURRENT_PROJECT_VERSION = 0.8.53;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DYLIB_COMPATIBILITY_VERSION = 0.8;
|
||||
DYLIB_CURRENT_VERSION = 0.8.52;
|
||||
DYLIB_CURRENT_VERSION = 0.8.53;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = "";
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
|
@ -1,2 +1,2 @@
|
||||
echo 0.8 8052 0.8.52 0
|
||||
echo 0.8 8053 0.8.53 1
|
||||
# AppVersionStrMajor AppVersion AppVersionStr DevChannel
|
||||
|
@ -11566,6 +11566,22 @@ index da0ba27..1d42b79 100644
|
||||
void QWindowsXpFileDialogHelper::selectNameFilter(const QString &f)
|
||||
{
|
||||
m_data.setSelectedNameFilter(f); // Dialog cannot be updated at run-time.
|
||||
diff --git a/qtbase/src/plugins/platforms/windows/qwindowsservices.cpp b/qtbase/src/plugins/platforms/windows/qwindowsservices.cpp
|
||||
index cc697ba..8e15e86 100644
|
||||
--- a/qtbase/src/plugins/platforms/windows/qwindowsservices.cpp
|
||||
+++ b/qtbase/src/plugins/platforms/windows/qwindowsservices.cpp
|
||||
@@ -125,8 +125,9 @@ static inline bool launchMail(const QUrl &url)
|
||||
}
|
||||
// Pass the url as the parameter. Should use QProcess::startDetached(),
|
||||
// but that cannot handle a Windows command line [yet].
|
||||
- command.replace(QStringLiteral("%1"), url.toString(QUrl::FullyEncoded));
|
||||
- if (debug)
|
||||
+ if (command.indexOf(QStringLiteral("%1")) < 0) return false;
|
||||
+ command.replace(QStringLiteral("%1"), url.toString(QUrl::FullyEncoded));
|
||||
+ if (debug)
|
||||
qDebug() << __FUNCTION__ << "Launching" << command;
|
||||
//start the process
|
||||
PROCESS_INFORMATION pi;
|
||||
diff --git a/qtbase/src/plugins/platforms/windows/qwindowswindow.cpp b/qtbase/src/plugins/platforms/windows/qwindowswindow.cpp
|
||||
index 543c081..d80429b 100644
|
||||
--- a/qtbase/src/plugins/platforms/windows/qwindowswindow.cpp
|
||||
|
@ -0,0 +1,160 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL21$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#define QT_NO_URL_CAST_FROM_STRING
|
||||
#include "qwindowsservices.h"
|
||||
#include "qtwindows_additional.h"
|
||||
|
||||
#include <QtCore/QUrl>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QDir>
|
||||
|
||||
#include <shlobj.h>
|
||||
#ifndef Q_OS_WINCE
|
||||
# include <intshcut.h>
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
enum { debug = 0 };
|
||||
|
||||
static inline bool shellExecute(const QUrl &url)
|
||||
{
|
||||
#ifndef Q_OS_WINCE
|
||||
const QString nativeFilePath =
|
||||
url.isLocalFile() ? QDir::toNativeSeparators(url.toLocalFile()) : url.toString(QUrl::FullyEncoded);
|
||||
const quintptr result = (quintptr)ShellExecute(0, 0, (wchar_t*)nativeFilePath.utf16(), 0, 0, SW_SHOWNORMAL);
|
||||
// ShellExecute returns a value greater than 32 if successful
|
||||
if (result <= 32) {
|
||||
qWarning("ShellExecute '%s' failed (error %s).", qPrintable(url.toString()), qPrintable(QString::number(result)));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
Q_UNUSED(url);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Retrieve the commandline for the default mail client. It contains a
|
||||
// placeholder %1 for the URL. The default key used below is the
|
||||
// command line for the mailto: shell command.
|
||||
static inline QString mailCommand()
|
||||
{
|
||||
enum { BufferSize = sizeof(wchar_t) * MAX_PATH };
|
||||
|
||||
const wchar_t mailUserKey[] = L"Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\mailto\\UserChoice";
|
||||
|
||||
wchar_t command[MAX_PATH] = {0};
|
||||
// Check if user has set preference, otherwise use default.
|
||||
HKEY handle;
|
||||
QString keyName;
|
||||
if (!RegOpenKeyEx(HKEY_CURRENT_USER, mailUserKey, 0, KEY_READ, &handle)) {
|
||||
DWORD bufferSize = BufferSize;
|
||||
if (!RegQueryValueEx(handle, L"Progid", 0, 0, reinterpret_cast<unsigned char*>(command), &bufferSize))
|
||||
keyName = QString::fromWCharArray(command);
|
||||
RegCloseKey(handle);
|
||||
}
|
||||
if (keyName.isEmpty())
|
||||
keyName = QStringLiteral("mailto");
|
||||
keyName += QStringLiteral("\\Shell\\Open\\Command");
|
||||
if (debug)
|
||||
qDebug() << __FUNCTION__ << "keyName=" << keyName;
|
||||
command[0] = 0;
|
||||
if (!RegOpenKeyExW(HKEY_CLASSES_ROOT, (const wchar_t*)keyName.utf16(), 0, KEY_READ, &handle)) {
|
||||
DWORD bufferSize = BufferSize;
|
||||
RegQueryValueEx(handle, L"", 0, 0, reinterpret_cast<unsigned char*>(command), &bufferSize);
|
||||
RegCloseKey(handle);
|
||||
}
|
||||
if (!command[0])
|
||||
return QString();
|
||||
#ifndef Q_OS_WINCE
|
||||
wchar_t expandedCommand[MAX_PATH] = {0};
|
||||
return ExpandEnvironmentStrings(command, expandedCommand, MAX_PATH) ?
|
||||
QString::fromWCharArray(expandedCommand) : QString::fromWCharArray(command);
|
||||
#else
|
||||
return QString();
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool launchMail(const QUrl &url)
|
||||
{
|
||||
QString command = mailCommand();
|
||||
if (command.isEmpty()) {
|
||||
qWarning("Cannot launch '%s': There is no mail program installed.", qPrintable(url.toString()));
|
||||
return false;
|
||||
}
|
||||
//Make sure the path for the process is in quotes
|
||||
const QChar doubleQuote = QLatin1Char('"');
|
||||
if (!command.startsWith(doubleQuote)) {
|
||||
const int exeIndex = command.indexOf(QStringLiteral(".exe "), 0, Qt::CaseInsensitive);
|
||||
if (exeIndex != -1) {
|
||||
command.insert(exeIndex + 4, doubleQuote);
|
||||
command.prepend(doubleQuote);
|
||||
}
|
||||
}
|
||||
// Pass the url as the parameter. Should use QProcess::startDetached(),
|
||||
// but that cannot handle a Windows command line [yet].
|
||||
if (command.indexOf(QStringLiteral("%1")) < 0) return false;
|
||||
command.replace(QStringLiteral("%1"), url.toString(QUrl::FullyEncoded));
|
||||
if (debug)
|
||||
qDebug() << __FUNCTION__ << "Launching" << command;
|
||||
//start the process
|
||||
PROCESS_INFORMATION pi;
|
||||
ZeroMemory(&pi, sizeof(pi));
|
||||
STARTUPINFO si;
|
||||
ZeroMemory(&si, sizeof(si));
|
||||
si.cb = sizeof(si);
|
||||
if (!CreateProcess(NULL, (wchar_t*)command.utf16(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
|
||||
qErrnoWarning("Unable to launch '%s'", qPrintable(command));
|
||||
return false;
|
||||
}
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QWindowsServices::openUrl(const QUrl &url)
|
||||
{
|
||||
const QString scheme = url.scheme();
|
||||
if (scheme == QLatin1String("mailto") && launchMail(url))
|
||||
return true;
|
||||
return shellExecute(url);
|
||||
}
|
||||
|
||||
bool QWindowsServices::openDocument(const QUrl &url)
|
||||
{
|
||||
return shellExecute(url);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
Loading…
Reference in New Issue
Block a user