mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 10:11:41 -05:00
Merge branch 'groupadmins' of https://bitbucket.org/johnprestonmail/telegram-desktop
This commit is contained in:
commit
57b2efa6a5
32 changed files with 591 additions and 206 deletions
|
@ -1632,8 +1632,9 @@ namespace App {
|
|||
convert->sticker()->loc = thumbLocation;
|
||||
}
|
||||
|
||||
if (convert->location.check()) {
|
||||
Local::writeFileLocation(mediaKey(DocumentFileLocation, convert->dc, convert->id), convert->location);
|
||||
const FileLocation &loc(convert->location(true));
|
||||
if (!loc.isEmpty()) {
|
||||
Local::writeFileLocation(mediaKey(DocumentFileLocation, convert->dc, convert->id), loc);
|
||||
}
|
||||
}
|
||||
DocumentsData::const_iterator i = documentsData.constFind(document);
|
||||
|
|
|
@ -709,6 +709,9 @@ void Application::checkMapVersion() {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (cNeedConfigResave()) {
|
||||
Local::writeUserSettings();
|
||||
}
|
||||
}
|
||||
|
||||
void Application::startApp() {
|
||||
|
|
|
@ -270,7 +270,7 @@ void audioFinish() {
|
|||
}
|
||||
|
||||
void AudioPlayer::Msg::clearData() {
|
||||
fname = QString();
|
||||
file = FileLocation();
|
||||
data = QByteArray();
|
||||
position = duration = 0;
|
||||
frequency = AudioVoiceMsgFrequency;
|
||||
|
@ -463,9 +463,9 @@ void AudioPlayer::play(const AudioMsgId &audio, int64 position) {
|
|||
current = &_audioData[_audioCurrent];
|
||||
}
|
||||
current->audio = audio;
|
||||
current->fname = audio.audio->already(true);
|
||||
current->file = audio.audio->location(true);
|
||||
current->data = audio.audio->data;
|
||||
if (current->fname.isEmpty() && current->data.isEmpty()) {
|
||||
if (current->file.isEmpty() && current->data.isEmpty()) {
|
||||
setStoppedState(current, AudioPlayerStoppedAtError);
|
||||
onError(audio);
|
||||
} else {
|
||||
|
@ -507,9 +507,9 @@ void AudioPlayer::play(const SongMsgId &song, int64 position) {
|
|||
current = &_songData[_songCurrent];
|
||||
}
|
||||
current->song = song;
|
||||
current->fname = song.song->already(true);
|
||||
current->file = song.song->location(true);
|
||||
current->data = song.song->data;
|
||||
if (current->fname.isEmpty() && current->data.isEmpty()) {
|
||||
if (current->file.isEmpty() && current->data.isEmpty()) {
|
||||
setStoppedState(current);
|
||||
if (!song.song->loader) {
|
||||
DocumentOpenLink::doOpen(song.song);
|
||||
|
@ -1076,13 +1076,17 @@ void AudioPlayerFader::resumeDevice() {
|
|||
|
||||
class AudioPlayerLoader {
|
||||
public:
|
||||
AudioPlayerLoader(const QString &fname, const QByteArray &data) : fname(fname), data(data), dataPos(0) {
|
||||
AudioPlayerLoader(const FileLocation &file, const QByteArray &data) : file(file), access(false), data(data), dataPos(0) {
|
||||
}
|
||||
virtual ~AudioPlayerLoader() {
|
||||
if (access) {
|
||||
file.accessDisable();
|
||||
access = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool check(const QString &fname, const QByteArray &data) {
|
||||
return this->fname == fname && this->data.size() == data.size();
|
||||
bool check(const FileLocation &file, const QByteArray &data) {
|
||||
return this->file == file && this->data.size() == data.size();
|
||||
}
|
||||
|
||||
virtual bool open(qint64 position = 0) = 0;
|
||||
|
@ -1093,7 +1097,8 @@ public:
|
|||
|
||||
protected:
|
||||
|
||||
QString fname;
|
||||
FileLocation file;
|
||||
bool access;
|
||||
QByteArray data;
|
||||
|
||||
QFile f;
|
||||
|
@ -1102,9 +1107,16 @@ protected:
|
|||
bool openFile() {
|
||||
if (data.isEmpty()) {
|
||||
if (f.isOpen()) f.close();
|
||||
f.setFileName(fname);
|
||||
if (!access) {
|
||||
if (!file.accessEnable()) {
|
||||
LOG(("Audio Error: could not open file access '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(f.error()).arg(f.errorString()));
|
||||
return false;
|
||||
}
|
||||
access = true;
|
||||
}
|
||||
f.setFileName(file.name());
|
||||
if (!f.open(QIODevice::ReadOnly)) {
|
||||
LOG(("Audio Error: could not open file '%1', data size '%2', error %3, %4").arg(fname).arg(data.size()).arg(f.error()).arg(f.errorString()));
|
||||
LOG(("Audio Error: could not open file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(f.error()).arg(f.errorString()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1121,7 +1133,7 @@ static const int32 _toChannels = 2;
|
|||
class FFMpegLoader : public AudioPlayerLoader {
|
||||
public:
|
||||
|
||||
FFMpegLoader(const QString &fname, const QByteArray &data) : AudioPlayerLoader(fname, data),
|
||||
FFMpegLoader(const FileLocation &file, const QByteArray &data) : AudioPlayerLoader(file, data),
|
||||
freq(AudioVoiceMsgFrequency), fmt(AL_FORMAT_STEREO16),
|
||||
sampleSize(2 * sizeof(short)), srcRate(AudioVoiceMsgFrequency), dstRate(AudioVoiceMsgFrequency),
|
||||
maxResampleSamples(1024), dstSamplesData(0), len(0),
|
||||
|
@ -1143,7 +1155,7 @@ public:
|
|||
}
|
||||
fmtContext = avformat_alloc_context();
|
||||
if (!fmtContext) {
|
||||
LOG(("Audio Error: Unable to avformat_alloc_context for file '%1', data size '%2'").arg(fname).arg(data.size()));
|
||||
LOG(("Audio Error: Unable to avformat_alloc_context for file '%1', data size '%2'").arg(file.name()).arg(data.size()));
|
||||
return false;
|
||||
}
|
||||
fmtContext->pb = ioContext;
|
||||
|
@ -1153,19 +1165,19 @@ public:
|
|||
if ((res = avformat_open_input(&fmtContext, 0, 0, 0)) < 0) {
|
||||
ioBuffer = 0;
|
||||
|
||||
LOG(("Audio Error: Unable to avformat_open_input for file '%1', data size '%2', error %3, %4").arg(fname).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||
LOG(("Audio Error: Unable to avformat_open_input for file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||
return false;
|
||||
}
|
||||
_opened = true;
|
||||
|
||||
if ((res = avformat_find_stream_info(fmtContext, 0)) < 0) {
|
||||
LOG(("Audio Error: Unable to avformat_find_stream_info for file '%1', data size '%2', error %3, %4").arg(fname).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||
LOG(("Audio Error: Unable to avformat_find_stream_info for file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||
return false;
|
||||
}
|
||||
|
||||
streamId = av_find_best_stream(fmtContext, AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0);
|
||||
if (streamId < 0) {
|
||||
LOG(("Audio Error: Unable to av_find_best_stream for file '%1', data size '%2', error %3, %4").arg(fname).arg(data.size()).arg(streamId).arg(av_make_error_string(err, sizeof(err), streamId)));
|
||||
LOG(("Audio Error: Unable to av_find_best_stream for file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(streamId).arg(av_make_error_string(err, sizeof(err), streamId)));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1173,7 +1185,7 @@ public:
|
|||
codecContext = fmtContext->streams[streamId]->codec;
|
||||
av_opt_set_int(codecContext, "refcounted_frames", 1, 0);
|
||||
if ((res = avcodec_open2(codecContext, codec, 0)) < 0) {
|
||||
LOG(("Audio Error: Unable to avcodec_open2 for file '%1', data size '%2', error %3, %4").arg(fname).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||
LOG(("Audio Error: Unable to avcodec_open2 for file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1217,7 +1229,7 @@ public:
|
|||
if (sampleSize < 0) {
|
||||
swrContext = swr_alloc();
|
||||
if (!swrContext) {
|
||||
LOG(("Audio Error: Unable to swr_alloc for file '%1', data size '%2'").arg(fname).arg(data.size()));
|
||||
LOG(("Audio Error: Unable to swr_alloc for file '%1', data size '%2'").arg(file.name()).arg(data.size()));
|
||||
return false;
|
||||
}
|
||||
int64_t src_ch_layout = layout, dst_ch_layout = _toChannelLayout;
|
||||
|
@ -1233,7 +1245,7 @@ public:
|
|||
av_opt_set_sample_fmt(swrContext, "out_sample_fmt", dst_sample_fmt, 0);
|
||||
|
||||
if ((res = swr_init(swrContext)) < 0) {
|
||||
LOG(("Audio Error: Unable to swr_init for file '%1', data size '%2', error %3, %4").arg(fname).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||
LOG(("Audio Error: Unable to swr_init for file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1244,7 +1256,7 @@ public:
|
|||
|
||||
maxResampleSamples = av_rescale_rnd(AVBlockSize / sampleSize, dstRate, srcRate, AV_ROUND_UP);
|
||||
if ((res = av_samples_alloc_array_and_samples(&dstSamplesData, 0, _toChannels, maxResampleSamples, _toFormat, 0)) < 0) {
|
||||
LOG(("Audio Error: Unable to av_samples_alloc for file '%1', data size '%2', error %3, %4").arg(fname).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||
LOG(("Audio Error: Unable to av_samples_alloc for file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1279,7 +1291,7 @@ public:
|
|||
if ((res = av_read_frame(fmtContext, &avpkt)) < 0) {
|
||||
if (res != AVERROR_EOF) {
|
||||
char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
|
||||
LOG(("Audio Error: Unable to av_read_frame() file '%1', data size '%2', error %3, %4").arg(fname).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||
LOG(("Audio Error: Unable to av_read_frame() file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -1288,7 +1300,7 @@ public:
|
|||
int got_frame = 0;
|
||||
if ((res = avcodec_decode_audio4(codecContext, frame, &got_frame, &avpkt)) < 0) {
|
||||
char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
|
||||
LOG(("Audio Error: Unable to avcodec_decode_audio4() file '%1', data size '%2', error %3, %4").arg(fname).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||
LOG(("Audio Error: Unable to avcodec_decode_audio4() file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||
|
||||
av_free_packet(&avpkt);
|
||||
if (res == AVERROR_INVALIDDATA) return 0; // try to skip bad packet
|
||||
|
@ -1305,7 +1317,7 @@ public:
|
|||
if ((res = av_samples_alloc(dstSamplesData, 0, _toChannels, maxResampleSamples, _toFormat, 1)) < 0) {
|
||||
dstSamplesData[0] = 0;
|
||||
char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
|
||||
LOG(("Audio Error: Unable to av_samples_alloc for file '%1', data size '%2', error %3, %4").arg(fname).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||
LOG(("Audio Error: Unable to av_samples_alloc for file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||
|
||||
av_free_packet(&avpkt);
|
||||
return -1;
|
||||
|
@ -1313,7 +1325,7 @@ public:
|
|||
}
|
||||
if ((res = swr_convert(swrContext, dstSamplesData, dstSamples, (const uint8_t**)frame->extended_data, frame->nb_samples)) < 0) {
|
||||
char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
|
||||
LOG(("Audio Error: Unable to swr_convert for file '%1', data size '%2', error %3, %4").arg(fname).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||
LOG(("Audio Error: Unable to swr_convert for file '%1', data size '%2', error %3, %4").arg(file.name()).arg(data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||
|
||||
av_free_packet(&avpkt);
|
||||
return -1;
|
||||
|
@ -1678,7 +1690,7 @@ AudioPlayerLoader *AudioPlayerLoaders::setupLoader(MediaOverviewType type, const
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (*l && (!isGoodId || !(*l)->check(m->fname, m->data))) {
|
||||
if (*l && (!isGoodId || !(*l)->check(m->file, m->data))) {
|
||||
delete *l;
|
||||
*l = 0;
|
||||
switch (type) {
|
||||
|
@ -1693,23 +1705,23 @@ AudioPlayerLoader *AudioPlayerLoaders::setupLoader(MediaOverviewType type, const
|
|||
case OverviewDocuments: _song = *static_cast<const SongMsgId*>(objId); break;
|
||||
}
|
||||
|
||||
QByteArray header = m->data.mid(0, 8);
|
||||
if (header.isEmpty()) {
|
||||
QFile f(m->fname);
|
||||
if (!f.open(QIODevice::ReadOnly)) {
|
||||
LOG(("Audio Error: could not open file '%1'").arg(m->fname));
|
||||
m->state = AudioPlayerStoppedAtStart;
|
||||
return 0;
|
||||
}
|
||||
header = f.read(8);
|
||||
}
|
||||
if (header.size() < 8) {
|
||||
LOG(("Audio Error: could not read header from file '%1', data size %2").arg(m->fname).arg(m->data.isEmpty() ? QFileInfo(m->fname).size() : m->data.size()));
|
||||
m->state = AudioPlayerStoppedAtStart;
|
||||
return 0;
|
||||
}
|
||||
// QByteArray header = m->data.mid(0, 8);
|
||||
// if (header.isEmpty()) {
|
||||
// QFile f(m->fname);
|
||||
// if (!f.open(QIODevice::ReadOnly)) {
|
||||
// LOG(("Audio Error: could not open file '%1'").arg(m->fname));
|
||||
// m->state = AudioPlayerStoppedAtStart;
|
||||
// return 0;
|
||||
// }
|
||||
// header = f.read(8);
|
||||
// }
|
||||
// if (header.size() < 8) {
|
||||
// LOG(("Audio Error: could not read header from file '%1', data size %2").arg(m->fname).arg(m->data.isEmpty() ? QFileInfo(m->fname).size() : m->data.size()));
|
||||
// m->state = AudioPlayerStoppedAtStart;
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
*l = new FFMpegLoader(m->fname, m->data);
|
||||
*l = new FFMpegLoader(m->file, m->data);
|
||||
|
||||
int ret;
|
||||
if (!(*l)->open(position)) {
|
||||
|
@ -1758,7 +1770,7 @@ AudioPlayer::Msg *AudioPlayerLoaders::checkLoader(MediaOverviewType type) {
|
|||
}
|
||||
if (!l || !m) return 0;
|
||||
|
||||
if (!isGoodId || !m->loading || !(*l)->check(m->fname, m->data)) {
|
||||
if (!isGoodId || !m->loading || !(*l)->check(m->file, m->data)) {
|
||||
LOG(("Audio Error: playing changed while loading"));
|
||||
return 0;
|
||||
}
|
||||
|
@ -2278,7 +2290,7 @@ void AudioCaptureInner::writeFrame(int32 offset, int32 framesize) {
|
|||
class FFMpegAttributesReader : public AudioPlayerLoader {
|
||||
public:
|
||||
|
||||
FFMpegAttributesReader(const QString &fname, const QByteArray &data) : AudioPlayerLoader(fname, data),
|
||||
FFMpegAttributesReader(const FileLocation &file, const QByteArray &data) : AudioPlayerLoader(file, data),
|
||||
ioBuffer(0), ioContext(0), fmtContext(0), codec(0), streamId(0),
|
||||
_opened(false) {
|
||||
}
|
||||
|
@ -2488,7 +2500,7 @@ private:
|
|||
};
|
||||
|
||||
MTPDocumentAttribute audioReadSongAttributes(const QString &fname, const QByteArray &data, QImage &cover, QByteArray &coverBytes, QByteArray &coverFormat) {
|
||||
FFMpegAttributesReader reader(fname, data);
|
||||
FFMpegAttributesReader reader(FileLocation(StorageFilePartial, fname), data);
|
||||
if (reader.open()) {
|
||||
int32 duration = reader.duration() / reader.frequency();
|
||||
if (reader.duration() > 0) {
|
||||
|
|
|
@ -127,7 +127,7 @@ private:
|
|||
|
||||
void clearData();
|
||||
|
||||
QString fname;
|
||||
FileLocation file;
|
||||
QByteArray data;
|
||||
int64 position, duration;
|
||||
int32 frequency;
|
||||
|
|
|
@ -25,15 +25,17 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
|||
|
||||
#include "downloadpathbox.h"
|
||||
#include "gui/filedialog.h"
|
||||
#include "pspecific.h"
|
||||
|
||||
DownloadPathBox::DownloadPathBox() :
|
||||
_path(cDownloadPath()),
|
||||
_default(this, qsl("dir_type"), 0, lang(lng_download_path_default_radio), _path.isEmpty()),
|
||||
_temp(this, qsl("dir_type"), 1, lang(lng_download_path_temp_radio), _path == qsl("tmp")),
|
||||
_dir(this, qsl("dir_type"), 2, lang(lng_download_path_dir_radio), !_path.isEmpty() && _path != qsl("tmp")),
|
||||
_pathLink(this, QString(), st::defaultBoxLinkButton),
|
||||
_save(this, lang(lng_connection_save), st::defaultBoxButton),
|
||||
_cancel(this, lang(lng_cancel), st::cancelBoxButton) {
|
||||
DownloadPathBox::DownloadPathBox() : AbstractBox()
|
||||
, _path(cDownloadPath())
|
||||
, _pathBookmark(cDownloadPathBookmark())
|
||||
, _default(this, qsl("dir_type"), 0, lang(lng_download_path_default_radio), _path.isEmpty())
|
||||
, _temp(this, qsl("dir_type"), 1, lang(lng_download_path_temp_radio), _path == qsl("tmp"))
|
||||
, _dir(this, qsl("dir_type"), 2, lang(lng_download_path_dir_radio), !_path.isEmpty() && _path != qsl("tmp"))
|
||||
, _pathLink(this, QString(), st::defaultBoxLinkButton)
|
||||
, _save(this, lang(lng_connection_save), st::defaultBoxButton)
|
||||
, _cancel(this, lang(lng_cancel), st::cancelBoxButton) {
|
||||
|
||||
connect(&_save, SIGNAL(clicked()), this, SLOT(onSave()));
|
||||
connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
|
||||
|
@ -124,12 +126,13 @@ void DownloadPathBox::onChange() {
|
|||
void DownloadPathBox::onEditPath() {
|
||||
filedialogInit();
|
||||
QString path, lastPath = cDialogLastPath();
|
||||
if (!cDownloadPath().isEmpty()) {
|
||||
cSetDialogLastPath(cDownloadPath());
|
||||
if (!cDownloadPath().isEmpty() && cDownloadPath() != qstr("tmp")) {
|
||||
cSetDialogLastPath(cDownloadPath().left(cDownloadPath().size() - (cDownloadPath().endsWith('/') ? 1 : 0)));
|
||||
}
|
||||
if (filedialogGetDir(path, lang(lng_download_path_choose))) {
|
||||
if (!path.isEmpty()) {
|
||||
_path = path + '/';
|
||||
_pathBookmark = psDownloadPathBookmark(_path);
|
||||
setPathText(QDir::toNativeSeparators(_path));
|
||||
}
|
||||
}
|
||||
|
@ -138,6 +141,7 @@ void DownloadPathBox::onEditPath() {
|
|||
|
||||
void DownloadPathBox::onSave() {
|
||||
cSetDownloadPath(_default.checked() ? QString() : (_temp.checked() ? qsl("tmp") : _path));
|
||||
cSetDownloadPathBookmark((_default.checked() || _temp.checked()) ? QByteArray() : _pathBookmark);
|
||||
Local::writeUserSettings();
|
||||
emit closed();
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ private:
|
|||
void setPathText(const QString &text);
|
||||
|
||||
QString _path;
|
||||
QByteArray _pathBookmark;
|
||||
|
||||
Radiobutton _default, _temp, _dir;
|
||||
LinkButton _pathLink;
|
||||
|
|
|
@ -20,9 +20,9 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
static const int32 AppVersion = 9013;
|
||||
static const wchar_t *AppVersionStr = L"0.9.13";
|
||||
static const bool DevVersion = false;
|
||||
static const int32 AppVersion = 9014;
|
||||
static const wchar_t *AppVersionStr = L"0.9.14";
|
||||
static const bool DevVersion = true;
|
||||
|
||||
static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)";
|
||||
static const wchar_t *AppName = L"Telegram Desktop";
|
||||
|
|
|
@ -41,7 +41,7 @@ void FileUploader::uploadMedia(const FullMsgId &msgId, const ReadyLocalMedia &me
|
|||
}
|
||||
document->status = FileUploading;
|
||||
if (!media.file.isEmpty()) {
|
||||
document->location = FileLocation(StorageFilePartial, media.file);
|
||||
document->setLocation(FileLocation(StorageFilePartial, media.file));
|
||||
}
|
||||
} else if (media.type == PrepareAudio) {
|
||||
AudioData *audio = App::feedAudio(media.audio);
|
||||
|
@ -64,7 +64,7 @@ void FileUploader::upload(const FullMsgId &msgId, const FileLoadResultPtr &file)
|
|||
}
|
||||
document->status = FileUploading;
|
||||
if (!file->filepath.isEmpty()) {
|
||||
document->location = FileLocation(StorageFilePartial, file->filepath);
|
||||
document->setLocation(FileLocation(StorageFilePartial, file->filepath));
|
||||
}
|
||||
} else if (file->type == PrepareAudio) {
|
||||
AudioData *audio = App::feedAudio(file->audio);
|
||||
|
|
|
@ -161,10 +161,17 @@ bool AnimatedGif::animStep(float64 ms) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void AnimatedGif::start(HistoryItem *row, const QString &file) {
|
||||
void AnimatedGif::start(HistoryItem *row, const FileLocation &f) {
|
||||
stop();
|
||||
|
||||
reader = new QImageReader(file);
|
||||
file = new FileLocation(f);
|
||||
if (!file->accessEnable()) {
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
access = true;
|
||||
|
||||
reader = new QImageReader(file->name());
|
||||
if (!reader->canRead() || !reader->supportsAnimation()) {
|
||||
stop();
|
||||
return;
|
||||
|
@ -206,6 +213,15 @@ void AnimatedGif::start(HistoryItem *row, const QString &file) {
|
|||
}
|
||||
|
||||
void AnimatedGif::stop(bool onItemRemoved) {
|
||||
if (file) {
|
||||
if (access) {
|
||||
file->accessDisable();
|
||||
}
|
||||
delete file;
|
||||
file = 0;
|
||||
}
|
||||
access = false;
|
||||
|
||||
if (isNull()) return;
|
||||
|
||||
delete reader;
|
||||
|
|
|
@ -387,17 +387,18 @@ private:
|
|||
};
|
||||
|
||||
class HistoryItem;
|
||||
class FileLocation;
|
||||
class AnimatedGif : public QObject, public Animated {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
AnimatedGif() : msg(0), reader(0), w(0), h(0), frame(0), framesCount(0), duration(0) {
|
||||
AnimatedGif() : msg(0), file(0), access(false), reader(0), w(0), h(0), frame(0), framesCount(0), duration(0) {
|
||||
}
|
||||
|
||||
bool animStep(float64 ms);
|
||||
|
||||
void start(HistoryItem *row, const QString &file);
|
||||
void start(HistoryItem *row, const FileLocation &file);
|
||||
void stop(bool onItemRemoved = false);
|
||||
|
||||
bool isNull() const {
|
||||
|
@ -418,6 +419,8 @@ public:
|
|||
|
||||
HistoryItem *msg;
|
||||
QImage img;
|
||||
FileLocation *file;
|
||||
bool access;
|
||||
QImageReader *reader;
|
||||
int32 w, h, frame;
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ bool _filedialogGetFiles(QStringList &files, QByteArray &remoteContent, const QS
|
|||
}
|
||||
return !files.isEmpty();
|
||||
} else if (multipleFiles < -1) {
|
||||
file = QFileDialog::getExistingDirectory(App::wnd() ? App::wnd()->filedialogParent() : 0, caption);
|
||||
file = QFileDialog::getExistingDirectory(App::wnd() ? App::wnd()->filedialogParent() : 0, caption, startFile);
|
||||
} else if (multipleFiles < 0) {
|
||||
file = QFileDialog::getSaveFileName(App::wnd() ? App::wnd()->filedialogParent() : 0, caption, startFile, filter);
|
||||
} else {
|
||||
|
|
|
@ -24,6 +24,8 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
|||
#include "mainwidget.h"
|
||||
#include "localstorage.h"
|
||||
|
||||
#include "pspecific.h"
|
||||
|
||||
namespace {
|
||||
typedef QMap<QString, LocalImage*> LocalImages;
|
||||
LocalImages localImages;
|
||||
|
@ -712,3 +714,82 @@ StorageImage *getImage(const StorageImageLocation &location, const QByteArray &b
|
|||
}
|
||||
return i.value();
|
||||
}
|
||||
|
||||
ReadAccessEnabler::ReadAccessEnabler(const PsFileBookmark *bookmark) : _bookmark(bookmark), _failed(_bookmark ? !_bookmark->enable() : false) {
|
||||
}
|
||||
|
||||
ReadAccessEnabler::ReadAccessEnabler(const QSharedPointer<PsFileBookmark> &bookmark) : _bookmark(bookmark.data()), _failed(_bookmark ? !_bookmark->enable() : false) {
|
||||
}
|
||||
|
||||
ReadAccessEnabler::~ReadAccessEnabler() {
|
||||
if (_bookmark && !_failed) _bookmark->disable();
|
||||
}
|
||||
|
||||
FileLocation::FileLocation(StorageFileType type, const QString &name) : type(type), fname(name) {
|
||||
if (fname.isEmpty()) {
|
||||
size = 0;
|
||||
type = StorageFileUnknown;
|
||||
} else {
|
||||
setBookmark(psPathBookmark(name));
|
||||
|
||||
QFileInfo f(name);
|
||||
if (f.exists()) {
|
||||
qint64 s = f.size();
|
||||
if (s > INT_MAX) {
|
||||
fname = QString();
|
||||
_bookmark.reset(0);
|
||||
size = 0;
|
||||
type = StorageFileUnknown;
|
||||
} else {
|
||||
modified = f.lastModified();
|
||||
size = qint32(s);
|
||||
}
|
||||
} else {
|
||||
fname = QString();
|
||||
_bookmark.reset(0);
|
||||
size = 0;
|
||||
type = StorageFileUnknown;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool FileLocation::check() const {
|
||||
if (fname.isEmpty()) return false;
|
||||
|
||||
ReadAccessEnabler enabler(_bookmark);
|
||||
if (enabler.failed()) {
|
||||
const_cast<FileLocation*>(this)->_bookmark.reset(0);
|
||||
}
|
||||
|
||||
QFileInfo f(name());
|
||||
if (!f.exists() || !f.isReadable()) return false;
|
||||
|
||||
quint64 s = f.size();
|
||||
if (s > INT_MAX) return false;
|
||||
|
||||
return (f.lastModified() == modified) && (qint32(s) == size);
|
||||
}
|
||||
|
||||
const QString &FileLocation::name() const {
|
||||
return _bookmark ? _bookmark->name(fname) : fname;
|
||||
}
|
||||
|
||||
QByteArray FileLocation::bookmark() const {
|
||||
return _bookmark ? _bookmark->bookmark() : QByteArray();
|
||||
}
|
||||
|
||||
void FileLocation::setBookmark(const QByteArray &bm) {
|
||||
if (bm.isEmpty()) {
|
||||
_bookmark.reset(0);
|
||||
} else {
|
||||
_bookmark.reset(new PsFileBookmark(bm));
|
||||
}
|
||||
}
|
||||
|
||||
bool FileLocation::accessEnable() const {
|
||||
return isEmpty() ? false : (_bookmark ? _bookmark->enable() : true);
|
||||
}
|
||||
|
||||
void FileLocation::accessDisable() const {
|
||||
return _bookmark ? _bookmark->disable() : (void)0;
|
||||
}
|
||||
|
|
|
@ -240,46 +240,50 @@ void clearStorageImages();
|
|||
void clearAllImages();
|
||||
int64 imageCacheSize();
|
||||
|
||||
struct FileLocation {
|
||||
FileLocation(StorageFileType type, const QString &name, const QDateTime &modified, qint32 size) : type(type), name(name), modified(modified), size(size) {
|
||||
}
|
||||
FileLocation(StorageFileType type, const QString &name) : type(type), name(name) {
|
||||
QFileInfo f(name);
|
||||
if (f.exists()) {
|
||||
qint64 s = f.size();
|
||||
if (s > INT_MAX) {
|
||||
this->name = QString();
|
||||
size = 0;
|
||||
type = StorageFileUnknown;
|
||||
} else {
|
||||
modified = f.lastModified();
|
||||
size = qint32(s);
|
||||
}
|
||||
} else {
|
||||
this->name = QString();
|
||||
size = 0;
|
||||
type = StorageFileUnknown;
|
||||
}
|
||||
class PsFileBookmark;
|
||||
class ReadAccessEnabler {
|
||||
public:
|
||||
ReadAccessEnabler(const PsFileBookmark *bookmark);
|
||||
ReadAccessEnabler(const QSharedPointer<PsFileBookmark> &bookmark);
|
||||
bool failed() const {
|
||||
return _failed;
|
||||
}
|
||||
~ReadAccessEnabler();
|
||||
|
||||
private:
|
||||
const PsFileBookmark *_bookmark;
|
||||
bool _failed;
|
||||
|
||||
};
|
||||
|
||||
class FileLocation {
|
||||
public:
|
||||
FileLocation(StorageFileType type, const QString &name);
|
||||
FileLocation() : size(0) {
|
||||
}
|
||||
bool check() const {
|
||||
if (name.isEmpty()) return false;
|
||||
QFileInfo f(name);
|
||||
if (!f.exists()) return false;
|
||||
|
||||
quint64 s = f.size();
|
||||
if (s > INT_MAX) return false;
|
||||
|
||||
return (f.lastModified() == modified) && (qint32(s) == size);
|
||||
bool check() const;
|
||||
const QString &name() const;
|
||||
void setBookmark(const QByteArray &bookmark);
|
||||
QByteArray bookmark() const;
|
||||
bool isEmpty() const {
|
||||
return name().isEmpty();
|
||||
}
|
||||
|
||||
bool accessEnable() const;
|
||||
void accessDisable() const;
|
||||
|
||||
StorageFileType type;
|
||||
QString name;
|
||||
QString fname;
|
||||
QDateTime modified;
|
||||
qint32 size;
|
||||
|
||||
private:
|
||||
QSharedPointer<PsFileBookmark> _bookmark;
|
||||
|
||||
};
|
||||
inline bool operator==(const FileLocation &a, const FileLocation &b) {
|
||||
return a.type == b.type && a.name == b.name && a.modified == b.modified && a.size == b.size;
|
||||
return a.type == b.type && a.name() == b.name() && a.modified == b.modified && a.size == b.size;
|
||||
}
|
||||
inline bool operator!=(const FileLocation &a, const FileLocation &b) {
|
||||
return !(a == b);
|
||||
|
|
|
@ -150,7 +150,7 @@ void historyInit() {
|
|||
_initTextOptions();
|
||||
}
|
||||
|
||||
void startGif(HistoryItem *row, const QString &file) {
|
||||
void startGif(HistoryItem *row, const FileLocation &file) {
|
||||
if (row == animated.msg) {
|
||||
stopGif();
|
||||
} else {
|
||||
|
|
|
@ -24,7 +24,7 @@ void historyInit();
|
|||
|
||||
class HistoryItem;
|
||||
|
||||
void startGif(HistoryItem *row, const QString &file);
|
||||
void startGif(HistoryItem *row, const FileLocation &file);
|
||||
void itemRemovedGif(HistoryItem *item);
|
||||
void itemReplacedGif(HistoryItem *oldItem, HistoryItem *newItem);
|
||||
void stopGif();
|
||||
|
|
|
@ -579,11 +579,23 @@ namespace {
|
|||
}
|
||||
quint32 size = 0;
|
||||
for (FileLocations::const_iterator i = _fileLocations.cbegin(), e = _fileLocations.cend(); i != e; ++i) {
|
||||
// location + type + namelen + name + date + size
|
||||
size += sizeof(quint64) * 2 + sizeof(quint32) + _stringSize(i.value().name) + _dateTimeSize() + sizeof(quint32);
|
||||
// location + type + namelen + name
|
||||
size += sizeof(quint64) * 2 + sizeof(quint32) + _stringSize(i.value().name());
|
||||
if (AppVersion > 9013) {
|
||||
// bookmark
|
||||
size += _bytearraySize(i.value().bookmark());
|
||||
}
|
||||
// date + size
|
||||
size += _dateTimeSize() + sizeof(quint32);
|
||||
}
|
||||
|
||||
//end mark
|
||||
size += sizeof(quint64) * 2 + sizeof(quint32) + _stringSize(QString()) + _dateTimeSize() + sizeof(quint32);
|
||||
size += sizeof(quint64) * 2 + sizeof(quint32) + _stringSize(QString());
|
||||
if (AppVersion > 9013) {
|
||||
size += _bytearraySize(QByteArray());
|
||||
}
|
||||
size += _dateTimeSize() + sizeof(quint32);
|
||||
|
||||
size += sizeof(quint32); // aliases count
|
||||
for (FileLocationAliases::const_iterator i = _fileLocationAliases.cbegin(), e = _fileLocationAliases.cend(); i != e; ++i) {
|
||||
// alias + location
|
||||
|
@ -592,9 +604,19 @@ namespace {
|
|||
|
||||
EncryptedDescriptor data(size);
|
||||
for (FileLocations::const_iterator i = _fileLocations.cbegin(); i != _fileLocations.cend(); ++i) {
|
||||
data.stream << quint64(i.key().first) << quint64(i.key().second) << quint32(i.value().type) << i.value().name << i.value().modified << quint32(i.value().size);
|
||||
data.stream << quint64(i.key().first) << quint64(i.key().second) << quint32(i.value().type) << i.value().name();
|
||||
if (AppVersion > 9013) {
|
||||
data.stream << i.value().bookmark();
|
||||
}
|
||||
data.stream << i.value().modified << quint32(i.value().size);
|
||||
}
|
||||
data.stream << quint64(0) << quint64(0) << quint32(0) << QString() << QDateTime::currentDateTime() << quint32(0);
|
||||
|
||||
data.stream << quint64(0) << quint64(0) << quint32(0) << QString();
|
||||
if (AppVersion > 9013) {
|
||||
data.stream << QByteArray();
|
||||
}
|
||||
data.stream << QDateTime::currentDateTime() << quint32(0);
|
||||
|
||||
data.stream << quint32(_fileLocationAliases.size());
|
||||
for (FileLocationAliases::const_iterator i = _fileLocationAliases.cbegin(), e = _fileLocationAliases.cend(); i != e; ++i) {
|
||||
data.stream << quint64(i.key().first) << quint64(i.key().second) << quint64(i.value().first) << quint64(i.value().second);
|
||||
|
@ -617,11 +639,17 @@ namespace {
|
|||
bool endMarkFound = false;
|
||||
while (!locations.stream.atEnd()) {
|
||||
quint64 first, second;
|
||||
QByteArray bookmark;
|
||||
FileLocation loc;
|
||||
quint32 type;
|
||||
locations.stream >> first >> second >> type >> loc.name >> loc.modified >> loc.size;
|
||||
locations.stream >> first >> second >> type >> loc.fname;
|
||||
if (locations.version > 9013) {
|
||||
locations.stream >> bookmark;
|
||||
}
|
||||
locations.stream >> loc.modified >> loc.size;
|
||||
loc.setBookmark(bookmark);
|
||||
|
||||
if (!first && !second && !type && loc.name.isEmpty() && !loc.size) { // end mark
|
||||
if (!first && !second && !type && loc.fname.isEmpty() && !loc.size) { // end mark
|
||||
endMarkFound = true;
|
||||
break;
|
||||
}
|
||||
|
@ -629,12 +657,8 @@ namespace {
|
|||
MediaKey key(first, second);
|
||||
loc.type = StorageFileType(type);
|
||||
|
||||
if (loc.check()) {
|
||||
_fileLocations.insert(key, loc);
|
||||
_fileLocationPairs.insert(loc.name, FileLocationPair(key, loc));
|
||||
} else {
|
||||
_writeLocations();
|
||||
}
|
||||
_fileLocations.insert(key, loc);
|
||||
_fileLocationPairs.insert(loc.fname, FileLocationPair(key, loc));
|
||||
}
|
||||
|
||||
if (endMarkFound) {
|
||||
|
@ -1038,12 +1062,26 @@ namespace {
|
|||
cSetAskDownloadPath(v == 1);
|
||||
} break;
|
||||
|
||||
case dbiDownloadPath: {
|
||||
case dbiDownloadPathOld: {
|
||||
QString v;
|
||||
stream >> v;
|
||||
if (!_checkStreamStatus(stream)) return false;
|
||||
|
||||
if (!v.isEmpty() && v != qstr("tmp") && !v.endsWith('/')) v += '/';
|
||||
cSetDownloadPath(v);
|
||||
cSetDownloadPathBookmark(QByteArray());
|
||||
} break;
|
||||
|
||||
case dbiDownloadPath: {
|
||||
QString v;
|
||||
QByteArray bookmark;
|
||||
stream >> v >> bookmark;
|
||||
if (!_checkStreamStatus(stream)) return false;
|
||||
|
||||
if (!v.isEmpty() && v != qstr("tmp") && !v.endsWith('/')) v += '/';
|
||||
cSetDownloadPath(v);
|
||||
cSetDownloadPathBookmark(bookmark);
|
||||
psDownloadPathEnableAccess();
|
||||
} break;
|
||||
|
||||
case dbiCompressPastedImage: {
|
||||
|
@ -1362,7 +1400,7 @@ namespace {
|
|||
}
|
||||
|
||||
uint32 size = 14 * (sizeof(quint32) + sizeof(qint32));
|
||||
size += sizeof(quint32) + _stringSize(cAskDownloadPath() ? QString() : cDownloadPath());
|
||||
size += sizeof(quint32) + _stringSize(cAskDownloadPath() ? QString() : cDownloadPath()) + _bytearraySize(cAskDownloadPath() ? QByteArray() : cDownloadPathBookmark());
|
||||
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));
|
||||
size += sizeof(quint32) + sizeof(qint32) + (cRecentStickersPreload().isEmpty() ? cGetRecentStickers().size() : cRecentStickersPreload().size()) * (sizeof(uint64) + sizeof(ushort));
|
||||
|
@ -1380,7 +1418,7 @@ namespace {
|
|||
data.stream << quint32(dbiNotifyView) << qint32(cNotifyView());
|
||||
data.stream << quint32(dbiWindowsNotifications) << qint32(cWindowsNotifications());
|
||||
data.stream << quint32(dbiAskDownloadPath) << qint32(cAskDownloadPath());
|
||||
data.stream << quint32(dbiDownloadPath) << (cAskDownloadPath() ? QString() : cDownloadPath());
|
||||
data.stream << quint32(dbiDownloadPath) << (cAskDownloadPath() ? QString() : cDownloadPath()) << (cAskDownloadPath() ? QByteArray() : cDownloadPathBookmark());
|
||||
data.stream << quint32(dbiCompressPastedImage) << qint32(cCompressPastedImage());
|
||||
data.stream << quint32(dbiEmojiTab) << qint32(cEmojiTab());
|
||||
data.stream << quint32(dbiDialogLastPath) << cDialogLastPath();
|
||||
|
@ -2178,14 +2216,14 @@ namespace Local {
|
|||
}
|
||||
|
||||
void writeFileLocation(MediaKey location, const FileLocation &local) {
|
||||
if (local.name.isEmpty()) return;
|
||||
if (local.fname.isEmpty()) return;
|
||||
|
||||
FileLocationAliases::const_iterator aliasIt = _fileLocationAliases.constFind(location);
|
||||
if (aliasIt != _fileLocationAliases.cend()) {
|
||||
location = aliasIt.value();
|
||||
}
|
||||
|
||||
FileLocationPairs::iterator i = _fileLocationPairs.find(local.name);
|
||||
FileLocationPairs::iterator i = _fileLocationPairs.find(local.fname);
|
||||
if (i != _fileLocationPairs.cend()) {
|
||||
if (i.value().second == local) {
|
||||
if (i.value().first != location) {
|
||||
|
@ -2205,7 +2243,7 @@ namespace Local {
|
|||
}
|
||||
}
|
||||
_fileLocations.insert(location, local);
|
||||
_fileLocationPairs.insert(local.name, FileLocationPair(location, local));
|
||||
_fileLocationPairs.insert(local.fname, FileLocationPair(location, local));
|
||||
_writeLocations(WriteMapFast);
|
||||
}
|
||||
|
||||
|
@ -2218,9 +2256,8 @@ namespace Local {
|
|||
FileLocations::iterator i = _fileLocations.find(location);
|
||||
for (FileLocations::iterator i = _fileLocations.find(location); (i != _fileLocations.end()) && (i.key() == location);) {
|
||||
if (check) {
|
||||
QFileInfo info(i.value().name);
|
||||
if (!info.exists() || info.lastModified() != i.value().modified || info.size() != i.value().size) {
|
||||
_fileLocationPairs.remove(i.value().name);
|
||||
if (!i.value().check()) {
|
||||
_fileLocationPairs.remove(i.value().fname);
|
||||
i = _fileLocations.erase(i);
|
||||
_writeLocations();
|
||||
continue;
|
||||
|
|
|
@ -30,6 +30,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
|||
#include "boxes/confirmbox.h"
|
||||
#include "boxes/stickersetbox.h"
|
||||
#include "boxes/contactsbox.h"
|
||||
#include "boxes/downloadpathbox.h"
|
||||
|
||||
#include "localstorage.h"
|
||||
|
||||
|
@ -1585,6 +1586,7 @@ void MainWidget::messagesAffected(PeerData *peer, const MTPmessages_AffectedMess
|
|||
void MainWidget::videoLoadProgress(mtpFileLoader *loader) {
|
||||
VideoData *video = App::video(loader->objId());
|
||||
if (video->loader) {
|
||||
video->status = FileReady;
|
||||
if (video->loader->done()) {
|
||||
video->finish();
|
||||
QString already = video->already();
|
||||
|
@ -1614,7 +1616,17 @@ void MainWidget::loadFailed(mtpFileLoader *loader, bool started, const char *ret
|
|||
if (started) {
|
||||
connect(box, SIGNAL(confirmed()), this, retrySlot);
|
||||
} else {
|
||||
connect(box, SIGNAL(confirmed()), App::wnd(), SLOT(showSettings()));
|
||||
connect(box, SIGNAL(confirmed()), this, SLOT(onDownloadPathSettings()));
|
||||
}
|
||||
App::wnd()->showLayer(box);
|
||||
}
|
||||
|
||||
void MainWidget::onDownloadPathSettings() {
|
||||
cSetDownloadPath(QString());
|
||||
cSetDownloadPathBookmark(QByteArray());
|
||||
DownloadPathBox *box = new DownloadPathBox();
|
||||
if (App::wnd() && App::wnd()->settingsWidget()) {
|
||||
connect(box, SIGNAL(closed()), App::wnd()->settingsWidget(), SLOT(onDownloadPathEdited()));
|
||||
}
|
||||
App::wnd()->showLayer(box);
|
||||
}
|
||||
|
@ -1634,6 +1646,7 @@ void MainWidget::videoLoadRetry() {
|
|||
void MainWidget::audioLoadProgress(mtpFileLoader *loader) {
|
||||
AudioData *audio = App::audio(loader->objId());
|
||||
if (audio->loader) {
|
||||
audio->status = FileReady;
|
||||
if (audio->loader->done()) {
|
||||
audio->finish();
|
||||
QString already = audio->already();
|
||||
|
@ -1688,7 +1701,7 @@ void MainWidget::audioPlayProgress(const AudioMsgId &audioId) {
|
|||
if (f.write(audio->data) == audio->data.size()) {
|
||||
f.close();
|
||||
already = filename;
|
||||
audio->location = FileLocation(mtpToStorageType(mtpc_storage_filePartial), filename);
|
||||
audio->setLocation(FileLocation(StorageFilePartial, filename));
|
||||
Local::writeFileLocation(mediaKey(mtpToLocationType(mtpc_inputAudioFileLocation), audio->dc, audio->id), FileLocation(mtpToStorageType(mtpc_storage_filePartial), filename));
|
||||
}
|
||||
}
|
||||
|
@ -1736,7 +1749,7 @@ void MainWidget::documentPlayProgress(const SongMsgId &songId) {
|
|||
if (f.write(document->data) == document->data.size()) {
|
||||
f.close();
|
||||
already = filename;
|
||||
document->location = FileLocation(mtpToStorageType(mtpc_storage_filePartial), filename);
|
||||
document->setLocation(FileLocation(StorageFilePartial, filename));
|
||||
Local::writeFileLocation(mediaKey(mtpToLocationType(mtpc_inputDocumentFileLocation), document->dc, document->id), FileLocation(mtpToStorageType(mtpc_storage_filePartial), filename));
|
||||
}
|
||||
}
|
||||
|
@ -1793,6 +1806,7 @@ void MainWidget::documentLoadProgress(mtpFileLoader *loader) {
|
|||
bool songPlayActivated = false;
|
||||
DocumentData *document = App::document(loader->objId());
|
||||
if (document->loader) {
|
||||
document->status = FileReady;
|
||||
if (document->loader->done()) {
|
||||
document->finish();
|
||||
QString already = document->already();
|
||||
|
@ -1813,16 +1827,22 @@ void MainWidget::documentLoadProgress(mtpFileLoader *loader) {
|
|||
}
|
||||
|
||||
songPlayActivated = true;
|
||||
} else if(document->openOnSave > 0 && document->size < MediaViewImageSizeLimit) {
|
||||
QImageReader reader(already);
|
||||
if (reader.canRead()) {
|
||||
if (reader.supportsAnimation() && reader.imageCount() > 1 && item) {
|
||||
startGif(item, already);
|
||||
} else if (item) {
|
||||
App::wnd()->showDocument(document, item);
|
||||
} else if (document->openOnSave > 0 && document->size < MediaViewImageSizeLimit) {
|
||||
const FileLocation &location(document->location(true));
|
||||
if (location.accessEnable()) {
|
||||
QImageReader reader(location.name());
|
||||
if (reader.canRead()) {
|
||||
if (reader.supportsAnimation() && reader.imageCount() > 1 && item) {
|
||||
startGif(item, location);
|
||||
} else if (item) {
|
||||
App::wnd()->showDocument(document, item);
|
||||
} else {
|
||||
psOpenFile(already);
|
||||
}
|
||||
} else {
|
||||
psOpenFile(already);
|
||||
}
|
||||
location.accessDisable();
|
||||
} else {
|
||||
psOpenFile(already);
|
||||
}
|
||||
|
|
|
@ -482,6 +482,8 @@ public slots:
|
|||
void onViewsIncrement();
|
||||
void onActiveChannelUpdateFull();
|
||||
|
||||
void onDownloadPathSettings();
|
||||
|
||||
private:
|
||||
|
||||
void sendReadRequest(PeerData *peer, MsgId upTo);
|
||||
|
|
|
@ -453,10 +453,13 @@ bool MediaView::animStep(float64 msp) {
|
|||
_docRadialFirst = _docRadialLast = _docRadialStart = 0;
|
||||
a_docRadial = anim::fvalue(0, 0);
|
||||
if (!_doc->already().isEmpty() && _doc->size < MediaViewImageSizeLimit) {
|
||||
QString fname(_doc->already(true));
|
||||
QImageReader reader(fname);
|
||||
if (reader.canRead()) {
|
||||
displayDocument(_doc, App::histItemById(_msgmigrated ? 0 : _channel, _msgid));
|
||||
const FileLocation &location(_doc->location(true));
|
||||
if (location.accessEnable()) {
|
||||
QImageReader reader(location.name());
|
||||
if (reader.canRead()) {
|
||||
displayDocument(_doc, App::histItemById(_msgmigrated ? 0 : _channel, _msgid));
|
||||
}
|
||||
location.accessDisable();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -529,8 +532,33 @@ void MediaView::onToMessage() {
|
|||
void MediaView::onSaveAs() {
|
||||
QString file;
|
||||
if (_doc) {
|
||||
QString cur = _doc->already(true);
|
||||
if (cur.isEmpty()) {
|
||||
const FileLocation &location(_doc->location(true));
|
||||
if (location.accessEnable()) {
|
||||
QFileInfo alreadyInfo(location.name());
|
||||
QDir alreadyDir(alreadyInfo.dir());
|
||||
QString name = alreadyInfo.fileName(), filter;
|
||||
MimeType mimeType = mimeTypeForName(_doc->mime);
|
||||
QStringList p = mimeType.globPatterns();
|
||||
QString pattern = p.isEmpty() ? QString() : p.front();
|
||||
if (name.isEmpty()) {
|
||||
name = pattern.isEmpty() ? qsl(".unknown") : pattern.replace('*', QString());
|
||||
}
|
||||
|
||||
if (pattern.isEmpty()) {
|
||||
filter = QString();
|
||||
} else {
|
||||
filter = mimeType.filterString() + qsl(";;All files (*.*)");
|
||||
}
|
||||
|
||||
psBringToBack(this);
|
||||
file = saveFileName(lang(lng_save_file), filter, qsl("doc"), name, true, alreadyDir);
|
||||
psShowOverAll(this);
|
||||
if (!file.isEmpty() && file != location.name()) {
|
||||
QFile(location.name()).copy(file);
|
||||
}
|
||||
|
||||
location.accessDisable();
|
||||
} else {
|
||||
if (_current.isNull() && _currentGif.isNull()) {
|
||||
DocumentSaveLink::doSave(_doc, true);
|
||||
updateControls();
|
||||
|
@ -539,30 +567,6 @@ void MediaView::onSaveAs() {
|
|||
update(_saveNav);
|
||||
}
|
||||
updateOver(_lastMouseMovePos);
|
||||
return;
|
||||
}
|
||||
|
||||
QFileInfo alreadyInfo(cur);
|
||||
QDir alreadyDir(alreadyInfo.dir());
|
||||
QString name = alreadyInfo.fileName(), filter;
|
||||
MimeType mimeType = mimeTypeForName(_doc->mime);
|
||||
QStringList p = mimeType.globPatterns();
|
||||
QString pattern = p.isEmpty() ? QString() : p.front();
|
||||
if (name.isEmpty()) {
|
||||
name = pattern.isEmpty() ? qsl(".unknown") : pattern.replace('*', QString());
|
||||
}
|
||||
|
||||
if (pattern.isEmpty()) {
|
||||
filter = QString();
|
||||
} else {
|
||||
filter = mimeType.filterString() + qsl(";;All files (*.*)");
|
||||
}
|
||||
|
||||
psBringToBack(this);
|
||||
file = saveFileName(lang(lng_save_file), filter, qsl("doc"), name, true, alreadyDir);
|
||||
psShowOverAll(this);
|
||||
if (!file.isEmpty() && file != cur) {
|
||||
QFile(cur).copy(file);
|
||||
}
|
||||
} else {
|
||||
if (!_photo || !_photo->full->loaded()) return;
|
||||
|
@ -609,8 +613,15 @@ void MediaView::onDownload() {
|
|||
}
|
||||
QString toName;
|
||||
if (_doc) {
|
||||
QString cur = _doc->already(true);
|
||||
if (cur.isEmpty()) {
|
||||
const FileLocation &location(_doc->location(true));
|
||||
if (location.accessEnable()) {
|
||||
if (!QDir().exists(path)) QDir().mkpath(path);
|
||||
toName = filedialogNextFilename(_doc->name, location.name(), path);
|
||||
if (toName != location.name() && !QFile(location.name()).copy(toName)) {
|
||||
toName = QString();
|
||||
}
|
||||
location.accessDisable();
|
||||
} else {
|
||||
if (_current.isNull() && _currentGif.isNull()) {
|
||||
DocumentSaveLink::doSave(_doc);
|
||||
updateControls();
|
||||
|
@ -619,12 +630,6 @@ void MediaView::onDownload() {
|
|||
update(_saveNav);
|
||||
}
|
||||
updateOver(_lastMouseMovePos);
|
||||
} else {
|
||||
if (!QDir().exists(path)) QDir().mkpath(path);
|
||||
toName = filedialogNextFilename(_doc->name, cur, path);
|
||||
if (toName != cur && !QFile(cur).copy(toName)) {
|
||||
toName = QString();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!_photo || !_photo->full->loaded()) {
|
||||
|
@ -902,25 +907,26 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty
|
|||
|
||||
_caption = Text();
|
||||
if (_doc) {
|
||||
QString already = _doc->already(true);
|
||||
const FileLocation &location(_doc->location(true));
|
||||
if (_doc->sticker() && !_doc->sticker()->img->isNull() && _doc->sticker()->img->loaded()) {
|
||||
_currentGif.stop();
|
||||
_current = _doc->sticker()->img->pix();
|
||||
} else if (!already.isEmpty()) {
|
||||
QImageReader reader(already);
|
||||
} else if (location.accessEnable()) {
|
||||
QImageReader reader(location.name());
|
||||
if (reader.canRead()) {
|
||||
if (reader.supportsAnimation() && reader.imageCount() > 1) {
|
||||
_currentGif.start(0, already);
|
||||
_currentGif.start(0, location);
|
||||
_current = QPixmap();
|
||||
} else {
|
||||
_currentGif.stop();
|
||||
QPixmap pix = QPixmap::fromImage(App::readImage(already, 0, false), Qt::ColorOnly);
|
||||
QPixmap pix = QPixmap::fromImage(App::readImage(location.name(), 0, false), Qt::ColorOnly);
|
||||
_current = pix;
|
||||
}
|
||||
} else {
|
||||
_currentGif.stop();
|
||||
_current = QPixmap();
|
||||
}
|
||||
location.accessDisable();
|
||||
} else {
|
||||
_currentGif.stop();
|
||||
_current = QPixmap();
|
||||
|
|
|
@ -78,7 +78,6 @@ void PasscodeWidget::onSubmit() {
|
|||
} else {
|
||||
if (Local::readMap(_passcode.text().toUtf8()) != Local::ReadMapPassNeeded) {
|
||||
cSetPasscodeBadTries(0);
|
||||
App::app()->checkMapVersion();
|
||||
|
||||
MTP::start();
|
||||
if (MTP::authedId()) {
|
||||
|
@ -86,6 +85,8 @@ void PasscodeWidget::onSubmit() {
|
|||
} else {
|
||||
App::wnd()->setupIntro(true);
|
||||
}
|
||||
|
||||
App::app()->checkMapVersion();
|
||||
} else {
|
||||
cSetPasscodeBadTries(cPasscodeBadTries() + 1);
|
||||
cSetPasscodeLastTry(getms(true));
|
||||
|
|
|
@ -323,7 +323,7 @@ void PlayerWidget::preloadNext() {
|
|||
}
|
||||
if (next) {
|
||||
if (HistoryDocument *document = static_cast<HistoryDocument*>(next->getMedia())) {
|
||||
if (document->document()->already(true).isEmpty() && document->document()->data.isEmpty()) {
|
||||
if (document->document()->location(true).isEmpty() && document->document()->data.isEmpty()) {
|
||||
if (!document->document()->loader) {
|
||||
DocumentOpenLink::doOpen(document->document());
|
||||
document->document()->openOnSave = 0;
|
||||
|
|
|
@ -175,5 +175,34 @@ void psUpdateOverlayed(QWidget *widget);
|
|||
inline QString psConvertFileUrl(const QString &url) {
|
||||
return url;
|
||||
}
|
||||
inline QByteArray psDownloadPathBookmark(const QString &path) {
|
||||
return QByteArray();
|
||||
}
|
||||
inline QByteArray psPathBookmark(const QString &path) {
|
||||
return QByteArray();
|
||||
}
|
||||
inline void psDownloadPathEnableAccess() {
|
||||
}
|
||||
|
||||
class PsFileBookmark {
|
||||
public:
|
||||
PsFileBookmark(const QByteArray &bookmark) {
|
||||
}
|
||||
bool check() const {
|
||||
return true;
|
||||
}
|
||||
bool enable() const {
|
||||
return true;
|
||||
}
|
||||
void disable() const {
|
||||
}
|
||||
const QString &name(const QString &original) const {
|
||||
return original;
|
||||
}
|
||||
QByteArray bookmark() const {
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
bool linuxMoveFile(const char *from, const char *to);
|
||||
|
|
|
@ -684,6 +684,18 @@ QString psConvertFileUrl(const QString &url) {
|
|||
return objc_convertFileUrl(url);
|
||||
}
|
||||
|
||||
void psDownloadPathEnableAccess() {
|
||||
objc_downloadPathEnableAccess(cDownloadPathBookmark());
|
||||
}
|
||||
|
||||
QByteArray psDownloadPathBookmark(const QString &path) {
|
||||
return objc_downloadPathBookmark(path);
|
||||
}
|
||||
|
||||
QByteArray psPathBookmark(const QString &path) {
|
||||
return objc_pathBookmark(path);
|
||||
}
|
||||
|
||||
QString strNotificationAboutThemeChange() {
|
||||
const uint32 letters[] = { 0xE9005541, 0x5600DC70, 0x88001570, 0xF500D86C, 0x8100E165, 0xEE005949, 0x2900526E, 0xAE00FB74, 0x96000865, 0x7000CD72, 0x3B001566, 0x5F007361, 0xAE00B663, 0x74009A65, 0x29003054, 0xC6002668, 0x98003865, 0xFA00336D, 0xA3007A65, 0x93001443, 0xBB007868, 0xE100E561, 0x3500366E, 0xC0007A67, 0x200CA65, 0xBE00DF64, 0xE300BB4E, 0x2900D26F, 0xD500D374, 0xE900E269, 0x86008F66, 0xC4006669, 0x1C00A863, 0xE600A761, 0x8E00EE74, 0xB300B169, 0xCF00B36F, 0xE600D36E };
|
||||
return strMakeFromLetters(letters, sizeof(letters) / sizeof(letters[0]));
|
||||
|
|
|
@ -198,6 +198,35 @@ void psNewVersion();
|
|||
void psUpdateOverlayed(QWidget *widget);
|
||||
QString psConvertFileUrl(const QString &url);
|
||||
|
||||
void psDownloadPathEnableAccess();
|
||||
QByteArray psDownloadPathBookmark(const QString &path);
|
||||
QByteArray psPathBookmark(const QString &path);
|
||||
|
||||
class PsFileBookmark {
|
||||
public:
|
||||
PsFileBookmark(const QByteArray &bookmark) : _inner(bookmark) {
|
||||
}
|
||||
bool check() const {
|
||||
return _inner.valid();
|
||||
}
|
||||
bool enable() const {
|
||||
return _inner.enable();
|
||||
}
|
||||
void disable() const {
|
||||
return _inner.disable();
|
||||
}
|
||||
const QString &name(const QString &original) const {
|
||||
return _inner.name(original);
|
||||
}
|
||||
QByteArray bookmark() const {
|
||||
return _inner.bookmark();
|
||||
}
|
||||
|
||||
private:
|
||||
objc_FileBookmark _inner;
|
||||
|
||||
};
|
||||
|
||||
QString strNotificationAboutThemeChange();
|
||||
QString strStyleOfInterface();
|
||||
QString strNeedToReload();
|
||||
|
|
|
@ -82,3 +82,20 @@ QString objc_downloadPath();
|
|||
QString objc_currentCountry();
|
||||
QString objc_currentLang();
|
||||
QString objc_convertFileUrl(const QString &url);
|
||||
QByteArray objc_downloadPathBookmark(const QString &path);
|
||||
QByteArray objc_pathBookmark(const QString &path);
|
||||
void objc_downloadPathEnableAccess(const QByteArray &bookmark);
|
||||
|
||||
class objc_FileBookmark {
|
||||
public:
|
||||
objc_FileBookmark(const QByteArray &bookmark);
|
||||
bool valid() const;
|
||||
bool enable() const;
|
||||
void disable() const;
|
||||
|
||||
const QString &name(const QString &original) const;
|
||||
QByteArray bookmark() const;
|
||||
|
||||
~objc_FileBookmark();
|
||||
|
||||
};
|
||||
|
|
|
@ -931,8 +931,16 @@ void objc_start() {
|
|||
name: NSWorkspaceDidWakeNotification object: NULL];
|
||||
}
|
||||
|
||||
namespace {
|
||||
NSURL *_downloadPathUrl = nil;
|
||||
}
|
||||
|
||||
void objc_finish() {
|
||||
[_sharedDelegate release];
|
||||
if (_downloadPathUrl) {
|
||||
[_downloadPathUrl stopAccessingSecurityScopedResource];
|
||||
_downloadPathUrl = nil;
|
||||
}
|
||||
}
|
||||
|
||||
void objc_registerCustomScheme() {
|
||||
|
@ -1054,3 +1062,38 @@ QString objc_convertFileUrl(const QString &url) {
|
|||
return objcString(nsurl);
|
||||
}
|
||||
|
||||
QByteArray objc_downloadPathBookmark(const QString &path) {
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
QByteArray objc_pathBookmark(const QString &path) {
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
void objc_downloadPathEnableAccess(const QByteArray &bookmark) {
|
||||
}
|
||||
|
||||
objc_FileBookmark::objc_FileBookmark(const QByteArray &bookmark) {
|
||||
}
|
||||
|
||||
bool objc_FileBookmark::valid() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool objc_FileBookmark::enable() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void objc_FileBookmark::disable() const {
|
||||
}
|
||||
|
||||
const QString &objc_FileBookmark::name(const QString &original) const {
|
||||
return original;
|
||||
}
|
||||
|
||||
QByteArray objc_FileBookmark::bookmark() const {
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
objc_FileBookmark::~objc_FileBookmark() {
|
||||
}
|
||||
|
|
|
@ -177,3 +177,32 @@ void psUpdateOverlayed(TWidget *widget);
|
|||
inline QString psConvertFileUrl(const QString &url) {
|
||||
return url;
|
||||
}
|
||||
inline QByteArray psDownloadPathBookmark(const QString &path) {
|
||||
return QByteArray();
|
||||
}
|
||||
inline QByteArray psPathBookmark(const QString &path) {
|
||||
return QByteArray();
|
||||
}
|
||||
inline void psDownloadPathEnableAccess() {
|
||||
}
|
||||
|
||||
class PsFileBookmark {
|
||||
public:
|
||||
PsFileBookmark(const QByteArray &bookmark) {
|
||||
}
|
||||
bool check() const {
|
||||
return true;
|
||||
}
|
||||
bool enable() const {
|
||||
return true;
|
||||
}
|
||||
void disable() const {
|
||||
}
|
||||
const QString &name(const QString &original) const {
|
||||
return original;
|
||||
}
|
||||
QByteArray bookmark() const {
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -74,6 +74,7 @@ DBIDefaultAttach gDefaultAttach = dbidaDocument;
|
|||
bool gReplaceEmojis = true;
|
||||
bool gAskDownloadPath = false;
|
||||
QString gDownloadPath;
|
||||
QByteArray gDownloadPathBookmark;
|
||||
|
||||
bool gNeedConfigResave = false;
|
||||
|
||||
|
|
|
@ -134,6 +134,7 @@ DeclareSetting(bool, ReplaceEmojis);
|
|||
DeclareReadSetting(bool, ManyInstance);
|
||||
DeclareSetting(bool, AskDownloadPath);
|
||||
DeclareSetting(QString, DownloadPath);
|
||||
DeclareSetting(QByteArray, DownloadPathBookmark);
|
||||
DeclareSetting(QByteArray, LocalSalt);
|
||||
DeclareSetting(DBIScale, RealScale);
|
||||
DeclareSetting(DBIScale, ScreenScale);
|
||||
|
|
|
@ -710,7 +710,7 @@ void VideoCancelLink::onClick(Qt::MouseButton button) const {
|
|||
|
||||
VideoData::VideoData(const VideoId &id, const uint64 &access, int32 date, int32 duration, int32 w, int32 h, const ImagePtr &thumb, int32 dc, int32 size) :
|
||||
id(id), access(access), date(date), duration(duration), w(w), h(h), thumb(thumb), dc(dc), size(size), status(FileReady), uploadOffset(0), fileType(0), openOnSave(0), loader(0) {
|
||||
location = Local::readFileLocation(mediaKey(VideoFileLocation, dc, id));
|
||||
_location = Local::readFileLocation(mediaKey(VideoFileLocation, dc, id));
|
||||
}
|
||||
|
||||
void VideoData::save(const QString &toFile) {
|
||||
|
@ -722,9 +722,12 @@ void VideoData::save(const QString &toFile) {
|
|||
}
|
||||
|
||||
QString VideoData::already(bool check) {
|
||||
if (!check) return location.name;
|
||||
if (!location.check()) location = Local::readFileLocation(mediaKey(VideoFileLocation, dc, id));
|
||||
return location.name;
|
||||
return location(check).name();
|
||||
}
|
||||
|
||||
const FileLocation &VideoData::location(bool check) {
|
||||
if (check && !_location.check()) _location = Local::readFileLocation(mediaKey(VideoFileLocation, dc, id));
|
||||
return _location;
|
||||
}
|
||||
|
||||
void AudioOpenLink::onClick(Qt::MouseButton button) const {
|
||||
|
@ -818,7 +821,7 @@ bool StickerData::setInstalled() const {
|
|||
|
||||
AudioData::AudioData(const AudioId &id, const uint64 &access, int32 date, const QString &mime, int32 duration, int32 dc, int32 size) :
|
||||
id(id), access(access), date(date), mime(mime), duration(duration), dc(dc), size(size), status(FileReady), uploadOffset(0), openOnSave(0), loader(0) {
|
||||
location = Local::readFileLocation(mediaKey(AudioFileLocation, dc, id));
|
||||
_location = Local::readFileLocation(mediaKey(AudioFileLocation, dc, id));
|
||||
}
|
||||
|
||||
void AudioData::save(const QString &toFile) {
|
||||
|
@ -830,17 +833,20 @@ void AudioData::save(const QString &toFile) {
|
|||
}
|
||||
|
||||
QString AudioData::already(bool check) {
|
||||
if (!check) return location.name;
|
||||
if (!location.check()) location = Local::readFileLocation(mediaKey(AudioFileLocation, dc, id));
|
||||
return location.name;
|
||||
return location(check).name();
|
||||
}
|
||||
|
||||
const FileLocation &AudioData::location(bool check) {
|
||||
if (check && !_location.check()) _location = Local::readFileLocation(mediaKey(AudioFileLocation, dc, id));
|
||||
return _location;
|
||||
}
|
||||
|
||||
void DocumentOpenLink::doOpen(DocumentData *data) {
|
||||
if (!data->date) return;
|
||||
|
||||
bool play = data->song() && App::hoveredLinkItem() && audioPlayer();
|
||||
QString already = data->already(true);
|
||||
if (!already.isEmpty() || (!data->data.isEmpty() && play)) {
|
||||
const FileLocation &location(data->location(true));
|
||||
if (!location.isEmpty() || (!data->data.isEmpty() && play)) {
|
||||
if (play) {
|
||||
SongMsgId playing;
|
||||
AudioPlayerState playingState = AudioPlayerStopped;
|
||||
|
@ -852,21 +858,22 @@ void DocumentOpenLink::doOpen(DocumentData *data) {
|
|||
audioPlayer()->play(song);
|
||||
if (App::main()) App::main()->documentPlayProgress(song);
|
||||
}
|
||||
} else if (data->size < MediaViewImageSizeLimit) {
|
||||
QImageReader reader(already);
|
||||
} else if (data->size < MediaViewImageSizeLimit && location.accessEnable()) {
|
||||
QImageReader reader(location.name());
|
||||
if (reader.canRead()) {
|
||||
if (reader.supportsAnimation() && reader.imageCount() > 1 && App::hoveredLinkItem()) {
|
||||
startGif(App::hoveredLinkItem(), already);
|
||||
startGif(App::hoveredLinkItem(), location);
|
||||
} else if (App::hoveredLinkItem() || App::contextItem()) {
|
||||
App::wnd()->showDocument(data, App::hoveredLinkItem() ? App::hoveredLinkItem() : App::contextItem());
|
||||
} else {
|
||||
psOpenFile(already);
|
||||
psOpenFile(location.name());
|
||||
}
|
||||
} else {
|
||||
psOpenFile(already);
|
||||
psOpenFile(location.name());
|
||||
}
|
||||
location.accessDisable();
|
||||
} else {
|
||||
psOpenFile(already);
|
||||
psOpenFile(location.name());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -954,7 +961,7 @@ void DocumentCancelLink::onClick(Qt::MouseButton button) const {
|
|||
DocumentData::DocumentData(const DocumentId &id, const uint64 &access, int32 date, const QVector<MTPDocumentAttribute> &attributes, const QString &mime, const ImagePtr &thumb, int32 dc, int32 size) :
|
||||
id(id), type(FileDocument), access(access), date(date), mime(mime), thumb(thumb), dc(dc), size(size), status(FileReady), uploadOffset(0), openOnSave(0), loader(0), _additional(0) {
|
||||
setattributes(attributes);
|
||||
location = Local::readFileLocation(mediaKey(DocumentFileLocation, dc, id));
|
||||
_location = Local::readFileLocation(mediaKey(DocumentFileLocation, dc, id));
|
||||
}
|
||||
|
||||
void DocumentData::setattributes(const QVector<MTPDocumentAttribute> &attributes) {
|
||||
|
@ -1016,9 +1023,12 @@ void DocumentData::save(const QString &toFile) {
|
|||
}
|
||||
|
||||
QString DocumentData::already(bool check) {
|
||||
if (!check) return location.name;
|
||||
if (!location.check()) location = Local::readFileLocation(mediaKey(DocumentFileLocation, dc, id));
|
||||
return location.name;
|
||||
return location(check).name();
|
||||
}
|
||||
|
||||
const FileLocation &DocumentData::location(bool check) {
|
||||
if (check && !_location.check()) _location = Local::readFileLocation(mediaKey(DocumentFileLocation, dc, id));
|
||||
return _location;
|
||||
}
|
||||
|
||||
WebPageData::WebPageData(const WebPageId &id, WebPageType type, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const QString &description, PhotoData *photo, DocumentData *doc, int32 duration, const QString &author, int32 pendingTill) :
|
||||
|
|
|
@ -807,7 +807,7 @@ struct VideoData {
|
|||
l->deleteLater();
|
||||
l->rpcInvalidate();
|
||||
}
|
||||
location = FileLocation();
|
||||
_location = FileLocation();
|
||||
if (!beforeDownload) {
|
||||
openOnSave = 0;
|
||||
openOnSaveMsgId = FullMsgId();
|
||||
|
@ -816,7 +816,7 @@ struct VideoData {
|
|||
|
||||
void finish() {
|
||||
if (loader->done()) {
|
||||
location = FileLocation(mtpToStorageType(loader->fileType()), loader->fileName());
|
||||
_location = FileLocation(mtpToStorageType(loader->fileType()), loader->fileName());
|
||||
}
|
||||
loader->deleteLater();
|
||||
loader->rpcInvalidate();
|
||||
|
@ -824,6 +824,7 @@ struct VideoData {
|
|||
}
|
||||
|
||||
QString already(bool check = false);
|
||||
const FileLocation &location(bool check = false);
|
||||
|
||||
VideoId id;
|
||||
uint64 access;
|
||||
|
@ -841,7 +842,10 @@ struct VideoData {
|
|||
int32 openOnSave;
|
||||
FullMsgId openOnSaveMsgId;
|
||||
mtpFileLoader *loader;
|
||||
FileLocation location;
|
||||
|
||||
private:
|
||||
FileLocation _location;
|
||||
|
||||
};
|
||||
|
||||
class VideoLink : public ITextLink {
|
||||
|
@ -902,7 +906,7 @@ struct AudioData {
|
|||
l->deleteLater();
|
||||
l->rpcInvalidate();
|
||||
}
|
||||
location = FileLocation();
|
||||
_location = FileLocation();
|
||||
if (!beforeDownload) {
|
||||
openOnSave = 0;
|
||||
openOnSaveMsgId = FullMsgId();
|
||||
|
@ -911,7 +915,7 @@ struct AudioData {
|
|||
|
||||
void finish() {
|
||||
if (loader->done()) {
|
||||
location = FileLocation(mtpToStorageType(loader->fileType()), loader->fileName());
|
||||
_location = FileLocation(mtpToStorageType(loader->fileType()), loader->fileName());
|
||||
data = loader->bytes();
|
||||
}
|
||||
loader->deleteLater();
|
||||
|
@ -920,6 +924,12 @@ struct AudioData {
|
|||
}
|
||||
|
||||
QString already(bool check = false);
|
||||
const FileLocation &location(bool check = false);
|
||||
void setLocation(const FileLocation &loc) {
|
||||
if (loc.check()) {
|
||||
_location = loc;
|
||||
}
|
||||
}
|
||||
|
||||
AudioId id;
|
||||
uint64 access;
|
||||
|
@ -935,9 +945,12 @@ struct AudioData {
|
|||
int32 openOnSave;
|
||||
FullMsgId openOnSaveMsgId;
|
||||
mtpFileLoader *loader;
|
||||
FileLocation location;
|
||||
QByteArray data;
|
||||
int32 md5[8];
|
||||
|
||||
private:
|
||||
FileLocation _location;
|
||||
|
||||
};
|
||||
|
||||
struct AudioMsgId {
|
||||
|
@ -1068,7 +1081,7 @@ struct DocumentData {
|
|||
l->deleteLater();
|
||||
l->rpcInvalidate();
|
||||
}
|
||||
location = FileLocation();
|
||||
_location = FileLocation();
|
||||
if (!beforeDownload) {
|
||||
openOnSave = 0;
|
||||
openOnSaveMsgId = FullMsgId();
|
||||
|
@ -1077,7 +1090,7 @@ struct DocumentData {
|
|||
|
||||
void finish() {
|
||||
if (loader->done()) {
|
||||
location = FileLocation(mtpToStorageType(loader->fileType()), loader->fileName());
|
||||
_location = FileLocation(mtpToStorageType(loader->fileType()), loader->fileName());
|
||||
data = loader->bytes();
|
||||
if (sticker() && !loader->imagePixmap().isNull()) {
|
||||
sticker()->img = ImagePtr(data, loader->imageFormat(), loader->imagePixmap());
|
||||
|
@ -1092,6 +1105,12 @@ struct DocumentData {
|
|||
}
|
||||
|
||||
QString already(bool check = false);
|
||||
const FileLocation &location(bool check = false);
|
||||
void setLocation(const FileLocation &loc) {
|
||||
if (loc.check()) {
|
||||
_location = loc;
|
||||
}
|
||||
}
|
||||
StickerData *sticker() {
|
||||
return (type == StickerDocument) ? static_cast<StickerData*>(_additional) : 0;
|
||||
}
|
||||
|
@ -1115,12 +1134,15 @@ struct DocumentData {
|
|||
int32 openOnSave;
|
||||
FullMsgId openOnSaveMsgId;
|
||||
mtpFileLoader *loader;
|
||||
FileLocation location;
|
||||
|
||||
QByteArray data;
|
||||
DocumentAdditionalData *_additional;
|
||||
|
||||
int32 md5[8];
|
||||
|
||||
private:
|
||||
|
||||
FileLocation _location;
|
||||
};
|
||||
|
||||
struct SongMsgId {
|
||||
|
|
|
@ -258,7 +258,7 @@ enum DataBlockId {
|
|||
dbiCatsAndDogs = 0x12,
|
||||
dbiReplaceEmojis = 0x13,
|
||||
dbiAskDownloadPath = 0x14,
|
||||
dbiDownloadPath = 0x15,
|
||||
dbiDownloadPathOld = 0x15,
|
||||
dbiScale = 0x16,
|
||||
dbiEmojiTab = 0x17,
|
||||
dbiRecentEmojisOld = 0x18,
|
||||
|
@ -282,6 +282,7 @@ enum DataBlockId {
|
|||
dbiWindowsNotifications = 0x30,
|
||||
dbiIncludeMuted = 0x31,
|
||||
dbiMaxMegaGroupCount = 0x32,
|
||||
dbiDownloadPath = 0x33,
|
||||
|
||||
dbiEncryptedWithSalt = 333,
|
||||
dbiEncrypted = 444,
|
||||
|
|
Loading…
Add table
Reference in a new issue