version 0.6 prepared, changed "Win (Unofficial)" to "Desktop", photo loader animation, custom context menu, default Downloads folder, cyclic logs

This commit is contained in:
John Preston 2014-09-30 07:11:09 -07:00
parent 0d85f91453
commit 311292c3a3
38 changed files with 526 additions and 144 deletions

View File

@ -1,5 +1,5 @@
AppVersionStr=0.5.21
AppVersion=5021
AppVersionStr=0.6.0
AppVersion=6000
if [ -d "./../Linux/Release/deploy/$AppVersionStr" ]; then
echo "Deploy folder for version $AppVersionStr already exists!"

View File

@ -1,5 +1,5 @@
AppVersionStr=0.5.21
AppVersion=5021
AppVersionStr=0.6.0
AppVersion=6000
if [ -d "./../Linux/Release/deploy/$AppVersionStr" ]; then
echo "Deploy folder for version $AppVersionStr already exists!"

View File

@ -1,5 +1,5 @@
AppVersionStr=0.5.21
AppVersion=5021
AppVersionStr=0.6.0
AppVersion=6000
if [ -d "./../Mac/Release/deploy/$AppVersionStr" ]; then
echo "Deploy folder for version $AppVersionStr already exists!"

View File

@ -177,8 +177,10 @@ lng_settings_cats_and_dogs: "Allow cats and dogs";
lng_download_path_dont_ask: "Don't ask download path for each file";
lng_download_path_label: "Download path: ";
lng_download_path_temp: "temp folder";
lng_download_path_default: "default folder";
lng_download_path_clear: "Clear All";
lng_download_path_header: "Choose download path";
lng_download_path_default_radio: "Telegram folder in system «Downloads»";
lng_download_path_temp_radio: "Temp folder, cleared on logout or uninstall";
lng_download_path_dir_radio: "Custom folder, cleared only manually";
lng_download_path_choose: "Choose download path";
@ -359,6 +361,7 @@ lng_context_copy_text: "Copy Message Text";
lng_context_to_msg: "Go To Message";
lng_context_forward_msg: "Forward Message";
lng_context_delete_msg: "Delete Message";
lng_context_select_msg: "Select Message";
lng_context_cancel_upload: "Cancel Upload";
lng_context_copy_selected: "Copy Selected Text";
lng_context_forward_selected: "Forward Selected";

View File

@ -1531,3 +1531,25 @@ btnContext: iconedButton(btnDefIconed) {
textPos: point(16px, 7px);
downTextPos: point(16px, 8px);
}
photoLoader: size(52px, 22px);
photoLoaderBg: #00000054;
photoLoaderCnt: 3;
photoLoaderPoint: size(6px, 6px);
photoLoaderSkip: 6px;
photoLoaderPeriod: 600; // ms full period
photoLoaderDelta: 150; // ms between points
photoLoaderDuration1: 150; // ms fade in
photoLoaderDuration2: 150; // ms fade out
photoLoaderAlphaMin: 0.1; // not less than that
overviewLoader: size(34px, 14px);
overviewLoaderPoint: size(4px, 4px);
overviewLoaderSkip: 4px;
mediaviewLoader: size(78px, 33px);
mediaviewLoaderPoint: size(9px, 9px);
mediaviewLoaderSkip: 9px;
minPhotoWidth: 90px;
minPhotoHeight: 90px;

View File

@ -2,11 +2,11 @@
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppShortName "Telegram"
#define MyAppName "Telegram Win (Unofficial)"
#define MyAppVersion "0.5.21"
#define MyAppVersionZero "0.5.21"
#define MyAppFullVersion "0.5.21.0"
#define MyAppPublisher "Telegram (Unofficial)"
#define MyAppName "Telegram Desktop"
#define MyAppVersion "0.6"
#define MyAppVersionZero "0.6.0"
#define MyAppFullVersion "0.6.0.0"
#define MyAppPublisher "Telegram Messenger LLP"
#define MyAppURL "https://tdesktop.com"
#define MyAppExeName "Telegram.exe"
#define MyAppId "53F49750-6209-4FBF-9CA8-7A333C87D1ED"

View File

@ -1,3 +1,3 @@
cd ..\Win32\Deploy
call ..\..\..\TelegramPrivate\Sign.bat tsetup.0.5.21.exe
call ..\..\..\TelegramPrivate\Sign.bat tsetup.0.6.0.exe
cd ..\..\Telegram

View File

@ -271,12 +271,16 @@ void updateRegistry() {
if (GetFullPathName(L".", bufSize, exp, 0) < bufSize) {
wstring installpath = locationStr, mypath = exp;
if (installpath == mypath + L"\\" || true) { // always update reg info, if we found it
WCHAR nameStr[bufSize], dateStr[bufSize];
WCHAR nameStr[bufSize], dateStr[bufSize], publisherStr[bufSize], icongroupStr[bufSize];
SYSTEMTIME stLocalTime;
GetLocalTime(&stLocalTime);
RegSetValueEx(rkey, L"DisplayVersion", 0, REG_SZ, (BYTE*)versionStr, ((versionLen / 2) + 1) * sizeof(WCHAR));
wsprintf(nameStr, L"Telegram Win (Unofficial) version %s", versionStr);
wsprintf(nameStr, L"Telegram Desktop version %s", versionStr);
RegSetValueEx(rkey, L"DisplayName", 0, REG_SZ, (BYTE*)nameStr, (wcslen(nameStr) + 1) * sizeof(WCHAR));
wsprintf(publisherStr, L"Telegram Messenger LLP");
RegSetValueEx(rkey, L"Publisher", 0, REG_SZ, (BYTE*)publisherStr, (wcslen(publisherStr) + 1) * sizeof(WCHAR));
wsprintf(icongroupStr, L"Telegram Desktop");
RegSetValueEx(rkey, L"Inno Setup: Icon Group", 0, REG_SZ, (BYTE*)icongroupStr, (wcslen(icongroupStr) + 1) * sizeof(WCHAR));
wsprintf(dateStr, L"%04d%02d%02d", stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay);
RegSetValueEx(rkey, L"InstallDate", 0, REG_SZ, (BYTE*)dateStr, (wcslen(dateStr) + 1) * sizeof(WCHAR));
@ -358,7 +362,7 @@ int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdParama
}
#ifdef _NEED_WIN_GENERATE_DUMP
static const WCHAR *_programName = L"Telegram Win (Unofficial)"; // folder in APPDATA, if current path is unavailable for writing
static const WCHAR *_programName = L"Telegram Desktop"; // folder in APPDATA, if current path is unavailable for writing
static const WCHAR *_exeName = L"Updater.exe";
LPTOP_LEVEL_EXCEPTION_FILTER _oldWndExceptionFilter = 0;

View File

@ -348,6 +348,11 @@ void Application::onEnableDebugMode() {
if (!cDebug()) {
logsInitDebug();
cSetDebug(true);
QFile f(cWorkingDir() + qsl("tdata/withdebug"));
if (f.open(QIODevice::WriteOnly)) {
f.write("1");
f.close();
}
}
App::wnd()->hideLayer();
}

View File

@ -23,9 +23,10 @@ Copyright (c) 2014 John Preston, https://tdesktop.com
DownloadPathBox::DownloadPathBox() :
_path(cDownloadPath()),
_tempRadio(this, qsl("dir_type"), 0, lang(lng_download_path_temp_radio), _path.isEmpty()),
_dirRadio(this, qsl("dir_type"), 1, lang(lng_download_path_dir_radio), !_path.isEmpty()),
_dirInput(this, st::inpDownloadDir, QString(), QDir::toNativeSeparators(_path)),
_defaultRadio(this, qsl("dir_type"), 0, lang(lng_download_path_default_radio), _path.isEmpty()),
_tempRadio(this, qsl("dir_type"), 1, lang(lng_download_path_temp_radio), _path == qsl("tmp")),
_dirRadio(this, qsl("dir_type"), 2, lang(lng_download_path_dir_radio), !_path.isEmpty() && _path != qsl("tmp")),
_dirInput(this, st::inpDownloadDir, QString(), (_path.isEmpty() || _path == qsl("tmp")) ? QString() : QDir::toNativeSeparators(_path)),
_saveButton(this, lang(lng_connection_save), st::btnSelectDone),
_cancelButton(this, lang(lng_cancel), st::btnSelectCancel),
a_opacity(0, 1), _hiding(false) {
@ -35,6 +36,7 @@ DownloadPathBox::DownloadPathBox() :
connect(&_saveButton, SIGNAL(clicked()), this, SLOT(onSave()));
connect(&_cancelButton, SIGNAL(clicked()), this, SLOT(onCancel()));
connect(&_defaultRadio, SIGNAL(changed()), this, SLOT(onChange()));
connect(&_tempRadio, SIGNAL(changed()), this, SLOT(onChange()));
connect(&_dirRadio, SIGNAL(changed()), this, SLOT(onChange()));
@ -47,6 +49,7 @@ DownloadPathBox::DownloadPathBox() :
}
void DownloadPathBox::hideAll() {
_defaultRadio.hide();
_tempRadio.hide();
_dirRadio.hide();
@ -57,6 +60,7 @@ void DownloadPathBox::hideAll() {
}
void DownloadPathBox::showAll() {
_defaultRadio.show();
_tempRadio.show();
_dirRadio.show();
@ -69,7 +73,8 @@ void DownloadPathBox::showAll() {
_saveButton.show();
_cancelButton.show();
_tempRadio.move(st::boxPadding.left(), st::addContactTitleHeight + st::downloadSkip);
_defaultRadio.move(st::boxPadding.left(), st::addContactTitleHeight + st::downloadSkip);
_tempRadio.move(st::boxPadding.left(), _defaultRadio.y() + _defaultRadio.height() + st::downloadSkip);
_dirRadio.move(st::boxPadding.left(), _tempRadio.y() + _tempRadio.height() + st::downloadSkip);
int32 inputy = _dirRadio.y() + _dirRadio.height() + st::boxPadding.top();
@ -137,16 +142,20 @@ void DownloadPathBox::animStep(float64 dt) {
void DownloadPathBox::onChange() {
if (_dirRadio.checked()) {
if (_path.isEmpty()) {
_tempRadio.setChecked(true);
if (_path.isEmpty() || _path == qsl("tmp")) {
(_path.isEmpty() ? _defaultRadio : _tempRadio).setChecked(true);
onEditPath();
if (!_path.isEmpty()) {
if (!_path.isEmpty() && _path != qsl("tmp")) {
_dirRadio.setChecked(true);
}
} else {
_dirInput.setText(QDir::toNativeSeparators(_path));
_dirInput.setCursorPosition(0);
}
} else if (_tempRadio.checked()) {
_path = qsl("tmp");
} else {
_path = QString();
}
showAll();
update();
@ -171,7 +180,7 @@ void DownloadPathBox::onEditPath() {
}
void DownloadPathBox::onSave() {
cSetDownloadPath(_tempRadio.checked() ? QString() : _path);
cSetDownloadPath(_defaultRadio.checked() ? QString() : (_tempRadio.checked() ? qsl("tmp") : _path));
App::writeUserConfig();
emit closed();
}

View File

@ -47,7 +47,7 @@ private:
QString _path;
FlatRadiobutton _tempRadio, _dirRadio;
FlatRadiobutton _defaultRadio, _tempRadio, _dirRadio;
FlatInput _dirInput;
FlatButton _saveButton, _cancelButton;

View File

@ -17,13 +17,10 @@ Copyright (c) 2014 John Preston, https://tdesktop.com
*/
#pragma once
static const int32 AppVersion = 5021;
static const wchar_t *AppVersionStr = L"0.5.21";
#ifdef Q_OS_WIN
static const wchar_t *AppName = L"Telegram Win (Unofficial)";
#else
static const int32 AppVersion = 6000;
static const wchar_t *AppVersionStr = L"0.6";
static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)";
static const wchar_t *AppName = L"Telegram Desktop";
#endif
static const wchar_t *AppId = L"{53F49750-6209-4FBF-9CA8-7A333C87D1ED}";
static const wchar_t *AppFile = L"Telegram";

View File

@ -29,6 +29,9 @@ public:
virtual bool loaded() const {
return true;
}
virtual bool loading() const {
return false;
}
const QPixmap &pix(int32 w = 0, int32 h = 0) const;
const QPixmap &pixBlurred(int32 w = 0, int32 h = 0) const;
QPixmap pixNoCache(int32 w = 0, int32 h = 0, bool smooth = false) const;
@ -110,6 +113,9 @@ public:
int32 width() const;
int32 height() const;
bool loaded() const;
bool loading() const {
return loader ? loader->loading() : false;
}
void setData(QByteArray &bytes, const QByteArray &format = "JPG");
void load(bool loadFirst = false, bool prior = true) {

View File

@ -247,7 +247,14 @@ QString saveFileName(const QString &title, const QString &filter, const QString
return filedialogGetSaveFile(name, title, filter, name) ? name : QString();
}
QString path = cDownloadPath().isEmpty() ? cTempDir() : cDownloadPath();
QString path;
if (cDownloadPath().isEmpty()) {
path = psDownloadPath();
} else if (cDownloadPath() == qsl("tmp")) {
path = cTempDir();
} else {
path = cDownloadPath();
}
if (name.isEmpty()) name = qsl(".unknown");
if (name.at(0) == QChar::fromLatin1('.')) {
if (!QDir().exists(path)) QDir().mkpath(path);
@ -1126,7 +1133,7 @@ void History::newItemAdded(HistoryItem *item) {
}
}
if (item->out()) {
inboxRead(false);
// inboxRead(false);
if (unreadBar) unreadBar->destroy();
} else if (item->unread()) {
notifies.push_back(item);
@ -1716,6 +1723,42 @@ void HistoryBlock::removeItem(HistoryItem *item) {
}
}
bool ItemAnimations::animStep(float64 ms) {
for (Animations::iterator i = _animations.begin(); i != _animations.end();) {
const HistoryItem *item = i.key();
if (item->animating()) {
App::main()->msgUpdated(item->history()->peer->id, item);
++i;
} else {
i = _animations.erase(i);
}
}
return !_animations.isEmpty();
}
uint64 ItemAnimations::animate(const HistoryItem *item, uint64 ms) {
if (_animations.isEmpty()) {
_animations.insert(item, ms);
anim::start(this);
return 0;
}
Animations::const_iterator i = _animations.constFind(item);
if (i == _animations.cend()) i = _animations.insert(item, ms);
return ms - i.value();
}
void ItemAnimations::remove(const HistoryItem *item) {
_animations.remove(item);
}
namespace {
ItemAnimations _itemAnimations;
}
ItemAnimations &itemAnimations() {
return _itemAnimations;
}
HistoryItem::HistoryItem(History *history, HistoryBlock *block, MsgId msgId, bool out, bool unread, QDateTime msgDate, int32 from) : y(0)
, id(msgId)
, date(msgDate)
@ -1795,6 +1838,7 @@ void HistoryItem::detachFast() {
}
HistoryItem::~HistoryItem() {
itemAnimations().remove(this);
App::historyUnregItem(this);
if (id < 0) {
App::app()->uploader()->cancel(id);
@ -1830,7 +1874,7 @@ void HistoryPhoto::init() {
}
int32 thumbw = st::msgMinWidth + st::msgPadding.left() + st::msgPadding.right() - 2, maxthumbh = qRound(1.5 * thumbw);
if (data->full->width() < thumbw) {
thumbw = (data->full->width() > 20) ? data->full->width() : 20;
thumbw = (data->full->width() > st::minPhotoWidth) ? data->full->width() : st::minPhotoWidth;
}
if (!w) {
w = thumbw;
@ -1839,10 +1883,13 @@ void HistoryPhoto::init() {
if (thumbh > maxthumbh) {
w = qRound(w * float64(maxthumbh) / thumbh);
thumbh = maxthumbh;
if (w < 10) {
w = 10;
if (w < st::minPhotoWidth) {
w = st::minPhotoWidth;
}
}
if (thumbh < st::minPhotoHeight) {
thumbh = st::minPhotoHeight;
}
_maxw = w;
_height = _minh = thumbh;
data->thumb->load();
@ -1888,10 +1935,38 @@ void HistoryPhoto::draw(QPainter &p, const HistoryItem *parent, bool selected, i
data->full->load(false, false);
bool out = parent->out();
if (parent != App::contextItem() || /*App::wnd()->photoShown() != data*/ true) {
if (data->full->loaded()) {
p.drawPixmap(0, 0, data->full->pix(width, _height));
bool full = data->full->loaded();
QPixmap pix;
if (full) {
pix = data->full->pix(width);
} else {
p.drawPixmap(0, 0, data->thumb->pixBlurred(width, _height));
pix = data->thumb->pixBlurred(width);
}
if (pix.height() >= _height) {
p.drawPixmap(QPoint(0, 0), pix, QRect(0, (pix.height() - _height) / 2, width, _height));
} else {
int32 usewidth = (width * pix.height()) / _height;
p.drawPixmap(QRect(0, 0, width, _height), pix, QRect((width - usewidth) / 2, 0, usewidth, pix.height()));
}
if (!full) {
uint64 dt = itemAnimations().animate(parent, getms());
int32 cnt = int32(st::photoLoaderCnt), period = int32(st::photoLoaderPeriod), t = dt % period, delta = int32(st::photoLoaderDelta);
int32 x = (width - st::photoLoader.width()) / 2, y = (_height - st::photoLoader.height()) / 2;
p.fillRect(x, y, st::photoLoader.width(), st::photoLoader.height(), st::photoLoaderBg->b);
x += (st::photoLoader.width() - cnt * st::photoLoaderPoint.width() - (cnt - 1) * st::photoLoaderSkip) / 2;
y += (st::photoLoader.height() - st::photoLoaderPoint.height()) / 2;
QColor c(st::white->c);
QBrush b(c);
for (int32 i = 0; i < cnt; ++i) {
t -= delta;
while (t < 0) t += period;
float64 alpha = (t >= st::photoLoaderDuration1 + st::photoLoaderDuration2) ? 0 : ((t > st::photoLoaderDuration1 ? ((st::photoLoaderDuration1 + st::photoLoaderDuration2 - t) / st::photoLoaderDuration2) : (t / st::photoLoaderDuration1)));
c.setAlphaF(st::photoLoaderAlphaMin + alpha * (1 - st::photoLoaderAlphaMin));
b.setColor(c);
p.fillRect(x + i * (st::photoLoaderPoint.width() + st::photoLoaderSkip), y, st::photoLoaderPoint.width(), st::photoLoaderPoint.height(), b);
}
}
if (selected) {

View File

@ -564,7 +564,6 @@ struct Histories : public QHash<PeerId, History*> {
};
struct HistoryBlock;
class HistoryItem;
struct DialogRow {
DialogRow(History *history = 0, DialogRow *prev = 0, DialogRow *next = 0, int32 pos = 0) : prev(prev), next(next), history(history), pos(pos), attached(0) {
@ -1055,7 +1054,6 @@ struct DialogsIndexed {
DialogsIndex index;
};
class HistoryItem;
struct HistoryBlock : public QVector<HistoryItem*> {
HistoryBlock(History *hist) : y(0), height(0), history(hist) {
}
@ -1097,6 +1095,20 @@ protected:
};
class ItemAnimations : public Animated {
public:
bool animStep(float64 ms);
uint64 animate(const HistoryItem *item, uint64 ms);
void remove(const HistoryItem *item);
private:
typedef QMap<const HistoryItem*, uint64> Animations;
Animations _animations;
};
ItemAnimations &itemAnimations();
class HistoryMedia;
class HistoryItem : public HistoryElem {
public:
@ -1197,6 +1209,9 @@ public:
virtual int32 timeWidth() const {
return 0;
}
virtual bool animating() const {
return false;
}
virtual ~HistoryItem();
@ -1242,6 +1257,10 @@ public:
virtual void updateFrom(const MTPMessageMedia &media) {
}
virtual bool animating() const {
return false;
}
};
@ -1272,6 +1291,11 @@ public:
return openl;
}
virtual bool animating() const {
if (data->full->loaded()) return false;
return data->full->loading() ? true : !data->medium->loaded();
}
private:
PhotoData *data;
TextLinkPtr openl;
@ -1464,6 +1488,9 @@ public:
int32 timeWidth() const {
return _timeWidth;
}
virtual bool animating() const {
return _media ? _media->animating() : false;
}
~HistoryMessage();
@ -1542,6 +1569,10 @@ public:
HistoryMedia *getMedia(bool inOverview = false) const;
virtual bool animating() const {
return _media ? _media->animating() : false;
}
~HistoryServiceMsg();
protected:

View File

@ -76,7 +76,7 @@ void HistoryList::messagesReceivedDown(const QVector<MTPMessage> &messages) {
hist->addToBack(messages);
}
void HistoryList::updateMsg(HistoryItem *msg) {
void HistoryList::updateMsg(const HistoryItem *msg) {
if (!msg || msg->detached() || !hist || hist != msg->history()) return;
update(0, height() - hist->height - st::historyPadding + msg->block()->y + msg->y, width(), msg->height());
}
@ -666,11 +666,14 @@ void HistoryList::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
_menu->addAction(lang(lng_context_forward_selected), historyWidget, SLOT(onForwardSelected()));
_menu->addAction(lang(lng_context_delete_selected), historyWidget, SLOT(onDeleteSelected()));
_menu->addAction(lang(lng_context_clear_selection), historyWidget, SLOT(onClearSelected()));
} else if (isUponSelected != -2 && App::hoveredLinkItem()) {
if (dynamic_cast<HistoryMessage*>(App::hoveredLinkItem())) {
_menu->addAction(lang(lng_context_forward_msg), historyWidget, SLOT(forwardMessage()))->setEnabled(true);
} else if (App::hoveredLinkItem()) {
if (isUponSelected != -2) {
if (dynamic_cast<HistoryMessage*>(App::hoveredLinkItem())) {
_menu->addAction(lang(lng_context_forward_msg), historyWidget, SLOT(forwardMessage()))->setEnabled(true);
}
_menu->addAction(lang(lng_context_delete_msg), historyWidget, SLOT(deleteMessage()))->setEnabled(true);
}
_menu->addAction(lang(lng_context_delete_msg), historyWidget, SLOT(deleteMessage()))->setEnabled(true);
_menu->addAction(lang(lng_context_select_msg), historyWidget, SLOT(selectMessage()))->setEnabled(true);
App::contextItem(App::hoveredLinkItem());
}
} else { // maybe cursor on some text history item?
@ -697,16 +700,18 @@ void HistoryList::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
_menu->addAction(lang(lng_context_forward_selected), historyWidget, SLOT(onForwardSelected()));
_menu->addAction(lang(lng_context_delete_selected), historyWidget, SLOT(onDeleteSelected()));
_menu->addAction(lang(lng_context_clear_selection), historyWidget, SLOT(onClearSelected()));
} else if (isUponSelected != -2) {
if (canForward) {
if (!_menu) _menu = new ContextMenu(this);
_menu->addAction(lang(lng_context_forward_msg), historyWidget, SLOT(forwardMessage()))->setEnabled(true);
}
} else {
if (!_menu) _menu = new ContextMenu(this);
if (isUponSelected != -2) {
if (canForward) {
_menu->addAction(lang(lng_context_forward_msg), historyWidget, SLOT(forwardMessage()))->setEnabled(true);
}
if (canDelete) {
if (!_menu) _menu = new ContextMenu(this);
_menu->addAction(lang((msg && msg->uploading()) ? lng_context_cancel_upload : lng_context_delete_msg), historyWidget, SLOT(deleteMessage()))->setEnabled(true);
if (canDelete) {
_menu->addAction(lang((msg && msg->uploading()) ? lng_context_cancel_upload : lng_context_delete_msg), historyWidget, SLOT(deleteMessage()))->setEnabled(true);
}
}
_menu->addAction(lang(lng_context_select_msg), historyWidget, SLOT(selectMessage()))->setEnabled(true);
}
App::contextItem(item);
}
@ -1006,6 +1011,17 @@ void HistoryList::fillSelectedItems(SelectedItemSet &sel, bool forDelete) {
}
}
void HistoryList::selectItem(HistoryItem *item) {
if (!_selected.isEmpty() && _selected.cbegin().value() != FullItemSel) {
_selected.clear();
} else if (_selected.size() == MaxSelectedItems && _selected.constFind(item) == _selected.cend()) {
return;
}
_selected.insert(item, FullItemSel);
historyWidget->updateTopBarSelection();
historyWidget->update();
}
void HistoryList::onTouchSelect() {
_touchSelect = true;
dragActionStart(_touchPos);
@ -2178,6 +2194,8 @@ void HistoryWidget::onSend() {
QString text = prepareMessage(_field.getText());
if (!text.isEmpty()) {
App::main()->readServerHistory(hist, false);
MsgId newId = clientMsgId();
uint64 randomId = MTP::nonce<uint64>();
@ -2217,6 +2235,8 @@ mtpRequestId HistoryWidget::onForward(const PeerId &peer, SelectedItemSet toForw
hist->loadAround(0);
if (item->id > 0 && msg) {
App::main()->readServerHistory(item->history(), false);
newId = clientMsgId();
hist->addToBackForwarded(newId, msg);
MTP::send(MTPmessages_ForwardMessage(histPeer->input, MTP_int(item->id), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentFullDataReceived, randomId));
@ -2224,6 +2244,8 @@ mtpRequestId HistoryWidget::onForward(const PeerId &peer, SelectedItemSet toForw
// newId = clientMsgId();
// MTP::send(MTPmessages_ForwardMessage(histPeer->input, MTP_int(item->id), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentFullDataReceived, randomId));
} else if (msg) {
App::main()->readServerHistory(item->history(), false);
newId = clientMsgId();
MTPstring msgText(MTP_string(msg->selectedText(FullItemSel)));
@ -2244,6 +2266,8 @@ mtpRequestId HistoryWidget::onForward(const PeerId &peer, SelectedItemSet toForw
PeerData *toPeer = App::peerLoaded(peer);
if (!toPeer) return 0;
App::main()->readServerHistory(App::history(toPeer->id), false);
QVector<MTPint> ids;
ids.reserve(toForward.size());
for (SelectedItemSet::const_iterator i = toForward.cbegin(), e = toForward.cend(); i != e; ++i) {
@ -2262,6 +2286,8 @@ void HistoryWidget::onShareContact(const PeerId &peer, UserData *contact) {
}
void HistoryWidget::shareContact(const QString &phone, const QString &fname, const QString &lname, int32 userId) {
App::main()->readServerHistory(hist, false);
uint64 randomId = MTP::nonce<uint64>();
MsgId newId = clientMsgId();
@ -2574,6 +2600,13 @@ void HistoryWidget::forwardMessage() {
App::main()->forwardLayer();
}
void HistoryWidget::selectMessage() {
HistoryItem *item = App::contextItem();
if (!item || item->itemType() != HistoryItem::MsgType) return;
if (_list) _list->selectItem(item);
}
void HistoryWidget::paintTopBar(QPainter &p, float64 over, int32 decreaseWidth) {
if (animating()) {
p.setOpacity(a_bgAlpha.current());
@ -2801,6 +2834,8 @@ void HistoryWidget::onPhotoUploaded(MsgId newId, const MTPInputFile &file) {
if (!MTP::authedId()) return;
HistoryItem *item = App::histItemById(newId);
if (item) {
//App::main()->readServerHistory(item->history(), false);
uint64 randomId = MTP::nonce<uint64>();
App::historyRegRandom(randomId, newId);
MTP::send(MTPmessages_SendMedia(item->history()->peer->input, MTP_inputMediaUploadedPhoto(file), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentFullDataReceived, randomId));
@ -2813,6 +2848,8 @@ void HistoryWidget::onDocumentUploaded(MsgId newId, const MTPInputFile &file) {
if (item) {
HistoryDocument *media = dynamic_cast<HistoryDocument*>(item->getMedia());
if (media) {
//App::main()->readServerHistory(item->history(), false);
uint64 randomId = MTP::nonce<uint64>();
App::historyRegRandom(randomId, newId);
DocumentData *document = media->document();
@ -2827,6 +2864,8 @@ void HistoryWidget::onThumbDocumentUploaded(MsgId newId, const MTPInputFile &fil
if (item) {
HistoryDocument *media = dynamic_cast<HistoryDocument*>(item->getMedia());
if (media) {
//App::main()->readServerHistory(item->history(), false);
uint64 randomId = MTP::nonce<uint64>();
App::historyRegRandom(randomId, newId);
DocumentData *document = media->document();
@ -2861,7 +2900,7 @@ void HistoryWidget::peerMessagesUpdated() {
if (_list) updateListSize();
}
void HistoryWidget::msgUpdated(PeerId peer, HistoryItem *msg) {
void HistoryWidget::msgUpdated(PeerId peer, const HistoryItem *msg) {
if (histPeer && _list && peer == histPeer->id) {
_list->updateMsg(msg);
}

View File

@ -66,7 +66,7 @@ public:
int32 recountHeight();
void updateSize();
void updateMsg(HistoryItem *msg);
void updateMsg(const HistoryItem *msg);
bool getPhotoCoords(PhotoData *photo, int32 &x, int32 &y, int32 &w) const;
bool getVideoCoords(VideoData *video, int32 &x, int32 &y, int32 &w) const;
@ -74,6 +74,7 @@ public:
void getSelectionState(int32 &selectedForForward, int32 &selectedForDelete) const;
void clearSelectedItems(bool onlyTextSelection = false);
void fillSelectedItems(SelectedItemSet &sel, bool forDelete = true);
void selectItem(HistoryItem *item);
~HistoryList();
@ -276,7 +277,7 @@ public:
void peerMessagesUpdated(PeerId peer);
void peerMessagesUpdated();
void msgUpdated(PeerId peer, HistoryItem *msg);
void msgUpdated(PeerId peer, const HistoryItem *msg);
void newUnreadMsg(History *history, MsgId msgId);
void historyToDown(History *history);
void historyWasRead(bool force = true);
@ -372,8 +373,9 @@ public slots:
void onVisibleChanged();
void forwardMessage();
void deleteMessage();
void forwardMessage();
void selectMessage();
void onFieldFocused();
void onFieldResize();

View File

@ -22,6 +22,7 @@ Copyright (c) 2014 John Preston, https://tdesktop.com
namespace {
QFile debugLog, tcpLog, mtpLog, mainLog;
QTextStream *debugLogStream = 0, *tcpLogStream = 0, *mtpLogStream = 0, *mainLogStream = 0;
int32 part = -1;
QChar zero('0');
QMutex debugLogMutex, mainLogMutex;
@ -65,6 +66,9 @@ void debugLogWrite(const char *file, int32 line, const QString &v) {
{
QMutexLocker lock(&debugLogMutex);
logsInitDebug(); // maybe need to reopen new file
QString msg(QString("%1 %2 (%3 : %4)\n").arg(debugLogEntryStart()).arg(v).arg(file).arg(line));
(*debugLogStream) << msg;
debugLogStream->flush();
@ -83,6 +87,9 @@ void tcpLogWrite(const QString &v) {
{
QMutexLocker lock(&debugLogMutex);
logsInitDebug(); // maybe need to reopen new file
(*tcpLogStream) << QString("%1 %2\n").arg(debugLogEntryStart()).arg(v);
tcpLogStream->flush();
}
@ -93,6 +100,9 @@ void mtpLogWrite(int32 dc, const QString &v) {
{
QMutexLocker lock(&debugLogMutex);
logsInitDebug(); // maybe need to reopen new file
(*mtpLogStream) << QString("%1 (dc:%2) %3\n").arg(debugLogEntryStart()).arg(dc).arg(v);
mtpLogStream->flush();
}
@ -115,6 +125,52 @@ void logWrite(const QString &v) {
if (cDebug()) debugLogWrite("logs", 0, v);
}
void moveOldDataFiles(const QString &wasDir) {
QFile data(wasDir + "data"), dataConfig(wasDir + "data_config"), tdataConfig(wasDir + "tdata/config");
if (data.exists() && dataConfig.exists() && !QFileInfo(cWorkingDir() + "data").exists() && !QFileInfo(cWorkingDir() + "data_config").exists()) { // move to home dir
LOG(("Copying data to home dir '%1' from '%2'").arg(cWorkingDir()).arg(wasDir));
if (data.copy(cWorkingDir() + "data")) {
LOG(("Copied 'data' to home dir"));
if (dataConfig.copy(cWorkingDir() + "data_config")) {
LOG(("Copied 'data_config' to home dir"));
bool tdataGood = true;
if (tdataConfig.exists()) {
tdataGood = false;
QDir().mkpath(cWorkingDir() + "tdata");
if (tdataConfig.copy(cWorkingDir() + "tdata/config")) {
LOG(("Copied 'tdata/config' to home dir"));
tdataGood = true;
} else {
LOG(("Copied 'data' and 'data_config', but could not copy 'tdata/config'!"));
}
}
if (tdataGood) {
if (data.remove()) {
LOG(("Removed 'data'"));
} else {
LOG(("Could not remove 'data'"));
}
if (dataConfig.remove()) {
LOG(("Removed 'data_config'"));
} else {
LOG(("Could not remove 'data_config'"));
}
if (!tdataConfig.exists() || tdataConfig.remove()) {
LOG(("Removed 'tdata/config'"));
LOG(("Could not remove 'tdata/config'"));
} else {
}
QDir().rmdir(wasDir + "tdata");
}
} else {
LOG(("Copied 'data', but could not copy 'data_config'!!"));
}
} else {
LOG(("Could not copy 'data'!"));
}
}
}
void logsInit() {
static _StreamCreator streamCreator;
if (mainLogStream) return;
@ -129,51 +185,7 @@ void logsInit() {
#endif
#if (defined Q_OS_LINUX && !defined _DEBUG) // fix first version
{
QFile data(wasDir + "data"), dataConfig(wasDir + "data_config"), tdataConfig(wasDir + "tdata/config");
if (data.exists() && dataConfig.exists() && !QFileInfo(cWorkingDir() + "data").exists() && !QFileInfo(cWorkingDir() + "data_config").exists()) { // move to home dir
LOG(("Copying data to home dir '%1' from '%2'").arg(cWorkingDir()).arg(wasDir));
if (data.copy(cWorkingDir() + "data")) {
LOG(("Copied 'data' to home dir"));
if (dataConfig.copy(cWorkingDir() + "data_config")) {
LOG(("Copied 'data_config' to home dir"));
bool tdataGood = true;
if (tdataConfig.exists()) {
tdataGood = false;
QDir().mkpath(cWorkingDir() + "tdata");
if (tdataConfig.copy(cWorkingDir() + "tdata/config")) {
LOG(("Copied 'tdata/config' to home dir"));
tdataGood = true;
} else {
LOG(("Copied 'data' and 'data_config', but could not copy 'tdata/config'!"));
}
}
if (tdataGood) {
if (data.remove()) {
LOG(("Removed 'data'"));
} else {
LOG(("Could not remove 'data'"));
}
if (dataConfig.remove()) {
LOG(("Removed 'data_config'"));
} else {
LOG(("Could not remove 'data_config'"));
}
if (!tdataConfig.exists() || tdataConfig.remove()) {
LOG(("Removed 'tdata/config'"));
LOG(("Could not remove 'tdata/config'"));
} else {
}
QDir().rmdir(wasDir + "tdata");
}
} else {
LOG(("Copied 'data', but could not copy 'data_config'!!"));
}
} else {
LOG(("Could not copy 'data'!"));
}
}
}
moveOldDataFiles(wasDir);
#endif
#endif
@ -199,40 +211,103 @@ void logsInit() {
cForceWorkingDir(rightDir);
}
cForceWorkingDir(QDir(cWorkingDir()).absolutePath() + '/');
if (cDebug()) logsInitDebug();
#ifdef Q_OS_WIN
if (cWorkingDir() == psAppDataPath()) { // fix old "Telegram Win (Unofficial)" version
moveOldDataFiles(psAppDataPathOld());
}
#endif
if (cDebug()) {
logsInitDebug();
} else if (QFile(cWorkingDir() + qsl("tdata/withdebug")).exists()) {
logsInitDebug();
cSetDebug(true);
}
}
void logsInitDebug() {
if (debugLogStream) return;
time_t t = time(NULL);
struct tm tm;
mylocaltime(&tm, &t);
mylocaltime(&tm, &t);
QString logPrefix = QString("%1%2%3_%4%5%6_").arg(tm.tm_year + 1900).arg(tm.tm_mon + 1, 2, 10, zero).arg(tm.tm_mday, 2, 10, zero).arg(tm.tm_hour, 2, 10, zero).arg(tm.tm_min, 2, 10, zero).arg(tm.tm_sec, 2, 10, zero);
static const int switchEach = 15; // minutes
int32 newPart = (tm.tm_min + tm.tm_hour * 60) / switchEach;
if (newPart == part) return;
debugLog.setFileName(cWorkingDir() + "DebugLogs/" + logPrefix + "log.txt");
if (!debugLog.open(QIODevice::WriteOnly | QIODevice::Text)) {
part = newPart;
int32 dayIndex = (tm.tm_year + 1900) * 10000 + (tm.tm_mon + 1) * 100 + tm.tm_mday;
QString logPostfix = QString("_%4_%5").arg((part * switchEach) / 60, 2, 10, zero).arg((part * switchEach) % 60, 2, 10, zero);
if (debugLogStream) {
delete debugLogStream;
debugLogStream = 0;
debugLog.close();
}
debugLog.setFileName(cWorkingDir() + qsl("DebugLogs/log") + logPostfix + qsl(".txt"));
QIODevice::OpenMode debugLogMode = QIODevice::WriteOnly | QIODevice::Text;
if (debugLog.exists()) {
if (debugLog.open(QIODevice::ReadOnly | QIODevice::Text)) {
if (QString::fromUtf8(debugLog.readLine()).toInt() == dayIndex) {
debugLogMode |= QIODevice::Append;
}
debugLog.close();
}
}
if (!debugLog.open(debugLogMode)) {
QDir dir(QDir::current());
dir.mkdir(cWorkingDir() + "DebugLogs");
debugLog.open(QIODevice::WriteOnly | QIODevice::Text);
dir.mkdir(cWorkingDir() + qsl("DebugLogs"));
debugLog.open(debugLogMode);
}
if (debugLog.isOpen()) {
debugLogStream = new QTextStream();
debugLogStream->setDevice(&debugLog);
debugLogStream->setCodec("UTF-8");
(*debugLogStream) << ((debugLogMode & QIODevice::Append) ? qsl("----------------------------------------------------------------\nNEW LOGGING INSTANCE STARTED!!!\n----------------------------------------------------------------\n") : qsl("%1\n").arg(dayIndex));
debugLogStream->flush();
}
tcpLog.setFileName(cWorkingDir() + "DebugLogs/" + logPrefix + "tcp.txt");
if (tcpLog.open(QIODevice::WriteOnly | QIODevice::Text)) {
if (tcpLogStream) {
delete tcpLogStream;
tcpLogStream = 0;
tcpLog.close();
}
tcpLog.setFileName(cWorkingDir() + qsl("DebugLogs/tcp") + logPostfix + qsl(".txt"));
QIODevice::OpenMode tcpLogMode = QIODevice::WriteOnly | QIODevice::Text;
if (tcpLog.exists()) {
if (tcpLog.open(QIODevice::ReadOnly | QIODevice::Text)) {
if (QString::fromUtf8(tcpLog.readLine()).toInt() == dayIndex) {
tcpLogMode |= QIODevice::Append;
}
tcpLog.close();
}
}
if (tcpLog.open(tcpLogMode)) {
tcpLogStream = new QTextStream();
tcpLogStream->setDevice(&tcpLog);
tcpLogStream->setCodec("UTF-8");
(*tcpLogStream) << ((tcpLogMode & QIODevice::Append) ? qsl("----------------------------------------------------------------\nNEW LOGGING INSTANCE STARTED!!!\n----------------------------------------------------------------\n") : qsl("%1\n").arg(dayIndex));
tcpLogStream->flush();
}
mtpLog.setFileName(cWorkingDir() + "DebugLogs/" + logPrefix + "mtp.txt");
if (mtpLog.open(QIODevice::WriteOnly | QIODevice::Text)) {
if (mtpLogStream) {
delete mtpLogStream;
mtpLogStream = 0;
mtpLog.close();
}
mtpLog.setFileName(cWorkingDir() + qsl("DebugLogs/mtp") + logPostfix + qsl(".txt"));
QIODevice::OpenMode mtpLogMode = QIODevice::WriteOnly | QIODevice::Text;
if (mtpLog.exists()) {
if (mtpLog.open(QIODevice::ReadOnly | QIODevice::Text)) {
if (QString::fromUtf8(mtpLog.readLine()).toInt() == dayIndex) {
mtpLogMode |= QIODevice::Append;
}
mtpLog.close();
}
}
if (mtpLog.open(mtpLogMode)) {
mtpLogStream = new QTextStream();
mtpLogStream->setDevice(&mtpLog);
mtpLogStream->setCodec("UTF-8");
(*mtpLogStream) << ((mtpLogMode & QIODevice::Append) ? qsl("----------------------------------------------------------------\nNEW LOGGING INSTANCE STARTED!!!\n----------------------------------------------------------------\n") : qsl("%1\n").arg(dayIndex));
mtpLogStream->flush();
}
}

View File

@ -548,7 +548,7 @@ DialogsIndexed &MainWidget::contactsList() {
}
void MainWidget::sendMessage(History *hist, const QString &text) {
readServerHistory(hist);
readServerHistory(hist, false);
QString msg = history.prepareMessage(text);
if (!msg.isEmpty()) {
MsgId newId = clientMsgId();
@ -1360,7 +1360,7 @@ void MainWidget::forwardDone(PeerId peer, const MTPmessages_StatedMessages &resu
history.onClearSelected();
}
void MainWidget::msgUpdated(PeerId peer, HistoryItem *msg) {
void MainWidget::msgUpdated(PeerId peer, const HistoryItem *msg) {
if (!msg) return;
history.msgUpdated(peer, msg);
if (!msg->history()->dialogs.isEmpty()) dialogs.dlgUpdated(msg->history()->dialogs[0]);

View File

@ -193,7 +193,7 @@ public:
void sentFullDataReceived(uint64 randomId, const MTPmessages_StatedMessage &result); // randomId = 0 - new message, <> 0 - already added new message
void sentFullDatasReceived(const MTPmessages_StatedMessages &result);
void forwardDone(PeerId peer, const MTPmessages_StatedMessages &result);
void msgUpdated(PeerId peer, HistoryItem *msg);
void msgUpdated(PeerId peer, const HistoryItem *msg);
void historyToDown(History *hist);
void dialogsToUp();
void dialogsClear(); // after showing peer history

View File

@ -25,7 +25,7 @@ Copyright (c) 2014 John Preston, https://tdesktop.com
#include "gui/filedialog.h"
MediaView::MediaView() : TWidget(App::wnd()),
_photo(0), _leftNavVisible(false), _rightNavVisible(false), _maxWidth(0), _maxHeight(0), _x(0), _y(0), _w(0), _full(-1),
_photo(0), _leftNavVisible(false), _rightNavVisible(false), _animStarted(getms()), _maxWidth(0), _maxHeight(0), _x(0), _y(0), _w(0), _full(-1),
_history(0), _peer(0), _user(0), _from(0), _index(-1), _msgid(0), _loadRequest(0), _over(OverNone), _down(OverNone), _lastAction(-st::medviewDeltaFromLastAction, -st::medviewDeltaFromLastAction),
_close(this, lang(lng_mediaview_close), st::medviewButton),
_save(this, lang(lng_mediaview_save), st::medviewButton),
@ -422,8 +422,30 @@ void MediaView::paintEvent(QPaintEvent *e) {
_current = _photo->thumb->pixBlurredNoCache(_w * cIntRetinaFactor());
if (cRetina()) _current.setDevicePixelRatio(cRetinaFactor());
}
if (QRect(_x, _y, _current.width() / cIntRetinaFactor(), _current.height() / cIntRetinaFactor()).intersects(r)) {
int32 h = _current.height() / cIntRetinaFactor();
if (QRect(_x, _y, _w, h).intersects(r)) {
p.drawPixmap(_x, _y, _current);
if (_full < 1) {
uint64 dt = getms() - _animStarted;
int32 cnt = int32(st::photoLoaderCnt), period = int32(st::photoLoaderPeriod), t = dt % period, delta = int32(st::photoLoaderDelta);
int32 x = _x + (_w - st::mediaviewLoader.width()) / 2, y = _y + (h - st::mediaviewLoader.height()) / 2;
p.fillRect(x, y, st::mediaviewLoader.width(), st::mediaviewLoader.height(), st::photoLoaderBg->b);
x += (st::mediaviewLoader.width() - cnt * st::mediaviewLoaderPoint.width() - (cnt - 1) * st::mediaviewLoaderSkip) / 2;
y += (st::mediaviewLoader.height() - st::mediaviewLoaderPoint.height()) / 2;
QColor c(st::white->c);
QBrush b(c);
for (int32 i = 0; i < cnt; ++i) {
t -= delta;
while (t < 0) t += period;
float64 alpha = (t >= st::photoLoaderDuration1 + st::photoLoaderDuration2) ? 0 : ((t > st::photoLoaderDuration1 ? ((st::photoLoaderDuration1 + st::photoLoaderDuration2 - t) / st::photoLoaderDuration2) : (t / st::photoLoaderDuration1)));
c.setAlphaF(st::photoLoaderAlphaMin + alpha * (1 - st::photoLoaderAlphaMin));
b.setColor(c);
p.fillRect(x + i * (st::mediaviewLoaderPoint.width() + st::mediaviewLoaderSkip), y, st::mediaviewLoaderPoint.width(), st::mediaviewLoaderPoint.height(), b);
}
QTimer::singleShot(AnimationTimerDelta, this, SLOT(updateImage()));
}
}
}
@ -632,7 +654,7 @@ void MediaView::mouseReleaseEvent(QMouseEvent *e) {
}
void MediaView::contextMenuEvent(QContextMenuEvent *e) {
if (_photo && _photo->full->loaded() && (e->reason() != QContextMenuEvent::Mouse || QRect(_x, _y, _current.width() / cIntRetinaFactor(), _current.height() / cIntRetinaFactor()).contains(e->pos()))) {
if (_photo && _photo->full->loaded() && (e->reason() != QContextMenuEvent::Mouse || QRect(_x, _y, _w, _current.height() / cIntRetinaFactor()).contains(e->pos()))) {
if (_menu) {
_menu->deleteLater();
@ -754,6 +776,12 @@ void MediaView::onTouchTimer() {
_touchRightButton = true;
}
void MediaView::updateImage() {
if (_current.isNull()) return;
update(_x, _y, _w, _current.height() / cIntRetinaFactor());
}
void MediaView::loadPhotosBack() {
if (_loadRequest || _index < 0) return;

View File

@ -66,6 +66,8 @@ public slots:
void onCheckActive();
void onTouchTimer();
void updateImage();
private:
void showPhoto(PhotoData *photo);
@ -82,6 +84,8 @@ private:
bool _leftNavVisible, _rightNavVisible;
QString _dateText;
uint64 _animStarted;
int32 _maxWidth, _maxHeight, _x, _y, _w;
QPixmap _current;
int32 _full; // -1 - thumb, 0 - medium, 1 - full

View File

@ -636,6 +636,27 @@ void OverviewInner::paintEvent(QPaintEvent *e) {
size = w;
}
if (!quality) {
uint64 dt = itemAnimations().animate(item, getms());
int32 cnt = int32(st::photoLoaderCnt), period = int32(st::photoLoaderPeriod), t = dt % period, delta = int32(st::photoLoaderDelta);
int32 x = pos.x() + (size - st::overviewLoader.width()) / 2, y = pos.y() + (size - st::overviewLoader.height()) / 2;
p.fillRect(x, y, st::overviewLoader.width(), st::overviewLoader.height(), st::photoLoaderBg->b);
x += (st::overviewLoader.width() - cnt * st::overviewLoaderPoint.width() - (cnt - 1) * st::overviewLoaderSkip) / 2;
y += (st::overviewLoader.height() - st::overviewLoaderPoint.height()) / 2;
QColor c(st::white->c);
QBrush b(c);
for (int32 i = 0; i < cnt; ++i) {
t -= delta;
while (t < 0) t += period;
float64 alpha = (t >= st::photoLoaderDuration1 + st::photoLoaderDuration2) ? 0 : ((t > st::photoLoaderDuration1 ? ((st::photoLoaderDuration1 + st::photoLoaderDuration2 - t) / st::photoLoaderDuration2) : (t / st::photoLoaderDuration1)));
c.setAlphaF(st::photoLoaderAlphaMin + alpha * (1 - st::photoLoaderAlphaMin));
b.setColor(c);
p.fillRect(x + i * (st::overviewLoaderPoint.width() + st::overviewLoaderSkip), y, st::overviewLoaderPoint.width(), st::overviewLoaderPoint.height(), b);
}
}
uint32 sel = 0;
if (index >= selfrom && index <= selto) {
sel = (_dragSelecting && item->id > 0) ? FullItemSel : 0;
@ -1059,11 +1080,14 @@ void OverviewInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
_menu->addAction(lang(lng_context_forward_selected), _overview, SLOT(onForwardSelected()));
_menu->addAction(lang(lng_context_delete_selected), _overview, SLOT(onDeleteSelected()));
_menu->addAction(lang(lng_context_clear_selection), _overview, SLOT(onClearSelected()));
} else if (isUponSelected != -2 && App::hoveredLinkItem()) {
if (dynamic_cast<HistoryMessage*>(App::hoveredLinkItem())) {
_menu->addAction(lang(lng_context_forward_msg), this, SLOT(forwardMessage()))->setEnabled(true);
} else if (App::hoveredLinkItem()) {
if (isUponSelected != -2) {
if (dynamic_cast<HistoryMessage*>(App::hoveredLinkItem())) {
_menu->addAction(lang(lng_context_forward_msg), this, SLOT(forwardMessage()))->setEnabled(true);
}
_menu->addAction(lang(lng_context_delete_msg), this, SLOT(deleteMessage()))->setEnabled(true);
}
_menu->addAction(lang(lng_context_delete_msg), this, SLOT(deleteMessage()))->setEnabled(true);
_menu->addAction(lang(lng_context_select_msg), this, SLOT(selectMessage()))->setEnabled(true);
}
App::contextItem(App::hoveredLinkItem());
}
@ -1146,6 +1170,20 @@ void OverviewInner::deleteMessage() {
App::main()->deleteLayer((msg && msg->uploading()) ? -2 : -1);
}
void OverviewInner::selectMessage() {
HistoryItem *item = App::contextItem();
if (!item || item->itemType() != HistoryItem::MsgType) return;
if (!_selected.isEmpty() && _selected.cbegin().value() != FullItemSel) {
_selected.clear();
} else if (_selected.size() == MaxSelectedItems && _selected.constFind(item->id) == _selected.cend()) {
return;
}
_selected.insert(item->id, FullItemSel);
_overview->updateTopBarSelection();
_overview->update();
}
void OverviewInner::cancelContextDownload() {
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
AudioLink *lnkAudio = dynamic_cast<AudioLink*>(_contextMenuLnk.data());
@ -1381,7 +1419,7 @@ void OverviewInner::itemRemoved(HistoryItem *item) {
parentWidget()->update();
}
void OverviewInner::msgUpdated(HistoryItem *msg) {
void OverviewInner::msgUpdated(const HistoryItem *msg) {
if (!msg || _hist != msg->history()) return;
MsgId msgid = msg->id;
if (_hist->_overviewIds[_type].constFind(msgid) != _hist->_overviewIds[_type].cend()) {
@ -1648,7 +1686,7 @@ void OverviewWidget::changingMsgId(HistoryItem *row, MsgId newId) {
}
}
void OverviewWidget::msgUpdated(PeerId p, HistoryItem *msg) {
void OverviewWidget::msgUpdated(PeerId p, const HistoryItem *msg) {
if (peer()->id == p) {
_inner.msgUpdated(msg);
}

View File

@ -57,7 +57,7 @@ public:
void mediaOverviewUpdated();
void changingMsgId(HistoryItem *row, MsgId newId);
void msgUpdated(HistoryItem *msg);
void msgUpdated(const HistoryItem *msg);
void getSelectionState(int32 &selectedForForward, int32 &selectedForDelete) const;
void clearSelectedItems(bool onlyTextSelection = false);
@ -78,6 +78,7 @@ public slots:
void goToMessage();
void deleteMessage();
void forwardMessage();
void selectMessage();
void onMenuDestroy(QObject *obj);
void onTouchSelect();
@ -212,7 +213,7 @@ public:
void mediaOverviewUpdated(PeerData *peer);
void changingMsgId(HistoryItem *row, MsgId newId);
void msgUpdated(PeerId peer, HistoryItem *msg);
void msgUpdated(PeerId peer, const HistoryItem *msg);
QPoint clampMousePosition(QPoint point);

View File

@ -781,6 +781,10 @@ QString psAppDataPath() {
return QString();
}
QString psDownloadPath() {
return QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + '/' + QString::fromWCharArray(AppName) + '/';
}
QString psCurrentExeDirectory(int argc, char *argv[]) {
QString first = argc ? QString::fromLocal8Bit(argv[0]) : QString();
if (!first.isEmpty()) {

View File

@ -164,6 +164,7 @@ QString psLocalServerPrefix();
QString psCurrentCountry();
QString psCurrentLanguage();
QString psAppDataPath();
QString psDownloadPath();
QString psCurrentExeDirectory(int argc, char *argv[]);
void psAutoStart(bool start, bool silent = false);
void psSendToMenu(bool send, bool silent = false);

View File

@ -841,6 +841,10 @@ QString psAppDataPath() {
return objc_appDataPath();
}
QString psDownloadPath() {
return objc_downloadPath();
}
QString psCurrentExeDirectory(int argc, char *argv[]) {
QString first = argc ? QString::fromLocal8Bit(argv[0]) : QString();
if (!first.isEmpty()) {

View File

@ -180,6 +180,7 @@ QString psLocalServerPrefix();
QString psCurrentCountry();
QString psCurrentLanguage();
QString psAppDataPath();
QString psDownloadPath();
QString psCurrentExeDirectory(int argc, char *argv[]);
void psAutoStart(bool start, bool silent = false);
void psSendToMenu(bool send, bool silent = false);

View File

@ -66,5 +66,6 @@ bool objc_moveFile(const QString &from, const QString &to);
void objc_deleteDir(const QString &dir);
QString objc_appDataPath();
QString objc_downloadPath();
QString objc_currentCountry();
QString objc_currentLang();

View File

@ -681,6 +681,14 @@ QString objc_appDataPath() {
return QString();
}
QString objc_downloadPath() {
NSURL *url = [[NSFileManager defaultManager] URLForDirectory:NSDownloadsDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:nil];
if (url) {
return QString::fromUtf8([[url path] fileSystemRepresentation]) + '/' + QString::fromWCharArray(AppName) + '/';
}
return QString();
}
QString objc_currentCountry() {
NSLocale *currentLocale = [NSLocale currentLocale]; // get the current locale.
NSString *countryCode = [currentLocale objectForKey:NSLocaleCountryCode];

View File

@ -1933,6 +1933,20 @@ QString psAppDataPath() {
return QString();
}
QString psAppDataPathOld() {
static const int maxFileLen = MAX_PATH * 10;
WCHAR wstrPath[maxFileLen];
if (GetEnvironmentVariable(L"APPDATA", wstrPath, maxFileLen)) {
QDir appData(QString::fromStdWString(std::wstring(wstrPath)));
return appData.absolutePath() + '/' + QString::fromWCharArray(AppNameOld) + '/';
}
return QString();
}
QString psDownloadPath() {
return QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + '/' + QString::fromWCharArray(AppName) + '/';
}
QString psCurrentExeDirectory(int argc, char *argv[]) {
LPWSTR *args;
int argsCount;

View File

@ -174,6 +174,8 @@ QString psLocalServerPrefix();
QString psCurrentCountry();
QString psCurrentLanguage();
QString psAppDataPath();
QString psAppDataPathOld();
QString psDownloadPath();
QString psCurrentExeDirectory(int argc, char *argv[]);
void psAutoStart(bool start, bool silent = false);
void psSendToMenu(bool send, bool silent = false);

View File

@ -60,7 +60,7 @@ DeclareSetting(QString, WorkingDir);
inline void cForceWorkingDir(const QString &newDir) {
cSetWorkingDir(newDir);
QDir dir;
dir.mkpath(gWorkingDir);
if (!gWorkingDir.isEmpty()) dir.mkpath(gWorkingDir);
}
DeclareReadSetting(QString, ExeDir);
DeclareSetting(QString, DialogLastPath);

View File

@ -138,7 +138,7 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : QWidget(parent),
_dontAskDownloadPath(this, lang(lng_download_path_dont_ask), !cAskDownloadPath()),
_downloadPathWidth(st::linkFont->m.width(lang(lng_download_path_label))),
_downloadPathEdit(this, cDownloadPath().isEmpty() ? lang(lng_download_path_temp) : st::linkFont->m.elidedText(QDir::toNativeSeparators(cDownloadPath()), Qt::ElideRight, st::setWidth - st::setVersionLeft - _downloadPathWidth)),
_downloadPathEdit(this, cDownloadPath().isEmpty() ? lang(lng_download_path_default) : ((cDownloadPath() == qsl("tmp")) ? lang(lng_download_path_temp) : st::linkFont->m.elidedText(QDir::toNativeSeparators(cDownloadPath()), Qt::ElideRight, st::setWidth - st::setVersionLeft - _downloadPathWidth))),
_downloadPathClear(this, lang(lng_download_path_clear)),
_tempDirClearingWidth(st::linkFont->m.width(lang(lng_download_path_clearing))),
_tempDirClearedWidth(st::linkFont->m.width(lang(lng_download_path_cleared))),
@ -406,7 +406,7 @@ void SettingsInner::paintEvent(QPaintEvent *e) {
p.setFont(st::linkFont->f);
p.setPen(st::black->p);
p.drawText(_left + st::setVersionLeft, top + st::linkFont->ascent, lang(lng_download_path_label));
if (cDownloadPath().isEmpty()) {
if (cDownloadPath() == qsl("tmp")) {
QString clearText;
int32 clearWidth = 0;
switch (_tempDirClearState) {
@ -495,7 +495,7 @@ void SettingsInner::resizeEvent(QResizeEvent *e) {
if (!cAskDownloadPath()) {
top += st::setLittleSkip;
_downloadPathEdit.move(_left + st::setVersionLeft + _downloadPathWidth, top);
if (cDownloadPath().isEmpty()) {
if (cDownloadPath() == qsl("tmp")) {
_downloadPathClear.move(_left + st::setWidth - _downloadPathClear.width(), top);
}
top += _downloadPathEdit.height();
@ -689,7 +689,7 @@ void SettingsInner::showAll() {
_downloadPathClear.hide();
} else {
_downloadPathEdit.show();
if (cDownloadPath().isEmpty() && _tempDirClearState == TempDirExists) { // dir exists, not clearing right now
if (cDownloadPath() == qsl("tmp") && _tempDirClearState == TempDirExists) { // dir exists, not clearing right now
_downloadPathClear.show();
} else {
_downloadPathClear.hide();
@ -1022,7 +1022,15 @@ void SettingsInner::onDownloadPathEdit() {
}
void SettingsInner::onDownloadPathEdited() {
_downloadPathEdit.setText(cDownloadPath().isEmpty() ? lang(lng_download_path_temp) : st::linkFont->m.elidedText(QDir::toNativeSeparators(cDownloadPath()), Qt::ElideRight, st::setWidth - st::setVersionLeft - _downloadPathWidth));
QString path;
if (cDownloadPath().isEmpty()) {
path = lang(lng_download_path_default);
} else if (cDownloadPath() == qsl("tmp")) {
path = lang(lng_download_path_temp);
} else {
path = st::linkFont->m.elidedText(QDir::toNativeSeparators(cDownloadPath()), Qt::ElideRight, st::setWidth - st::setVersionLeft - _downloadPathWidth);
}
_downloadPathEdit.setText(path);
showAll();
}

View File

@ -11,7 +11,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.5.21</string>
<string>0.6.0</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.5.21;
CURRENT_PROJECT_VERSION = 0.6.0;
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.5.21;
CURRENT_PROJECT_VERSION = 0.6.0;
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.5.21;
CURRENT_PROJECT_VERSION = 0.6.0;
DEBUG_INFORMATION_FORMAT = dwarf;
DYLIB_COMPATIBILITY_VERSION = 0.5;
DYLIB_CURRENT_VERSION = 0.5.21;
DYLIB_COMPATIBILITY_VERSION = 0.6;
DYLIB_CURRENT_VERSION = 0.6.0;
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.5.21;
CURRENT_PROJECT_VERSION = 0.6.0;
DEBUG_INFORMATION_FORMAT = dwarf;
DYLIB_COMPATIBILITY_VERSION = 0.5;
DYLIB_CURRENT_VERSION = 0.5.21;
DYLIB_COMPATIBILITY_VERSION = 0.6;
DYLIB_CURRENT_VERSION = 0.6.0;
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = "";
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;

Binary file not shown.