mirror of https://github.com/procxx/kepka.git
trying to optimize ClipReader
This commit is contained in:
parent
30452289e5
commit
ff481c810f
|
@ -1303,7 +1303,7 @@ void StickerPanInner::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickerPanInner::paintInlineItems(Painter &p, const QRect &r) {
|
void StickerPanInner::paintInlineItems(Painter &p, const QRect &r) {
|
||||||
InlinePaintContext context(getms(), false, _previewShown, false);
|
InlinePaintContext context(getms(), false, Ui::isLayerShown() || Ui::isMediaViewShown() || _previewShown, false);
|
||||||
|
|
||||||
int32 top = st::emojiPanHeader;
|
int32 top = st::emojiPanHeader;
|
||||||
int32 fromx = rtl() ? (width() - r.x() - r.width()) : r.x(), tox = rtl() ? (width() - r.x()) : (r.x() + r.width());
|
int32 fromx = rtl() ? (width() - r.x() - r.width()) : r.x(), tox = rtl() ? (width() - r.x()) : (r.x() + r.width());
|
||||||
|
|
|
@ -184,7 +184,7 @@ void AnimationManager::clipCallback(ClipReader *reader, qint32 threadIndex, qint
|
||||||
ClipReader::callback(reader, threadIndex, ClipReaderNotification(notification));
|
ClipReader::callback(reader, threadIndex, ClipReaderNotification(notification));
|
||||||
}
|
}
|
||||||
|
|
||||||
QPixmap _prepareFrame(const ClipFrameRequest &request, const QImage &original, QImage &cache, bool hasAlpha) {
|
QPixmap _prepareFrame(const ClipFrameRequest &request, const QImage &original, bool hasAlpha, QImage &cache) {
|
||||||
bool badSize = (original.width() != request.framew) || (original.height() != request.frameh);
|
bool badSize = (original.width() != request.framew) || (original.height() != request.frameh);
|
||||||
bool needOuter = (request.outerw != request.framew) || (request.outerh != request.frameh);
|
bool needOuter = (request.outerw != request.framew) || (request.outerh != request.frameh);
|
||||||
if (badSize || needOuter || hasAlpha || request.rounded) {
|
if (badSize || needOuter || hasAlpha || request.rounded) {
|
||||||
|
@ -258,14 +258,16 @@ ClipReader::Frame *ClipReader::frameToShow() const { // 0 means not ready
|
||||||
return _frames + (((step + 1) / 2) % 3);
|
return _frames + (((step + 1) / 2) % 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClipReader::Frame *ClipReader::frameToWrite() const { // 0 means not ready
|
ClipReader::Frame *ClipReader::frameToWrite(int32 *index) const { // 0 means not ready
|
||||||
int32 step = _step.loadAcquire();
|
int32 step = _step.loadAcquire(), i = 0;
|
||||||
if (step == FirstFrameNotReadStep) {
|
if (step == WaitingForRequestStep) {
|
||||||
return _frames;
|
if (index) *index = 0;
|
||||||
} else if (step == WaitingForRequestStep) {
|
|
||||||
return 0;
|
return 0;
|
||||||
|
} else if (step != FirstFrameNotReadStep) {
|
||||||
|
i = (((step + 3) / 2) % 3);
|
||||||
}
|
}
|
||||||
return _frames + (((step + 3) / 2) % 3);
|
if (index) *index = i;
|
||||||
|
return _frames + i;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClipReader::Frame *ClipReader::frameToRequestOther(bool check) const {
|
ClipReader::Frame *ClipReader::frameToRequestOther(bool check) const {
|
||||||
|
@ -342,10 +344,10 @@ QPixmap ClipReader::current(int32 framew, int32 frameh, int32 outerw, int32 oute
|
||||||
frame->request.frameh = frameh * factor;
|
frame->request.frameh = frameh * factor;
|
||||||
frame->request.outerw = outerw * factor;
|
frame->request.outerw = outerw * factor;
|
||||||
frame->request.outerh = outerh * factor;
|
frame->request.outerh = outerh * factor;
|
||||||
frame->pix = QPixmap();
|
|
||||||
|
|
||||||
QImage cache;
|
QImage cacheForResize;
|
||||||
frame->pix = _prepareFrame(frame->request, frame->original, cache, true);
|
frame->pix = QPixmap();
|
||||||
|
frame->pix = _prepareFrame(frame->request, frame->original, true, cacheForResize);
|
||||||
|
|
||||||
Frame *other = frameToRequestOther(true);
|
Frame *other = frameToRequestOther(true);
|
||||||
if (other) other->request = frame->request;
|
if (other) other->request = frame->request;
|
||||||
|
@ -830,8 +832,7 @@ public:
|
||||||
, _location(_data.isEmpty() ? new FileLocation(location) : 0)
|
, _location(_data.isEmpty() ? new FileLocation(location) : 0)
|
||||||
, _accessed(false)
|
, _accessed(false)
|
||||||
, _implementation(0)
|
, _implementation(0)
|
||||||
, _currentHasAlpha(true)
|
, _frame(_frames)
|
||||||
, _nextHasAlpha(true)
|
|
||||||
, _width(0)
|
, _width(0)
|
||||||
, _height(0)
|
, _height(0)
|
||||||
, _previousMs(0)
|
, _previousMs(0)
|
||||||
|
@ -850,12 +851,12 @@ public:
|
||||||
if (!_implementation && !init()) {
|
if (!_implementation && !init()) {
|
||||||
return error();
|
return error();
|
||||||
}
|
}
|
||||||
if (_currentOriginal.isNull()) {
|
if (_frame->original.isNull()) {
|
||||||
if (!_implementation->readNextFrame(_currentOriginal, _currentHasAlpha, QSize())) {
|
if (!_implementation->readNextFrame(_frame->original, _frame->alpha, QSize())) {
|
||||||
return error();
|
return error();
|
||||||
}
|
}
|
||||||
_width = _currentOriginal.width();
|
_width = _frame->original.width();
|
||||||
_height = _currentOriginal.height();
|
_height = _frame->original.height();
|
||||||
return ClipProcessReinit;
|
return ClipProcessReinit;
|
||||||
}
|
}
|
||||||
return ClipProcessWait;
|
return ClipProcessWait;
|
||||||
|
@ -868,12 +869,12 @@ public:
|
||||||
return start(ms);
|
return start(ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_current.isNull()) { // first frame read, but not yet prepared
|
if (_frame->pix.isNull()) { // first frame read, but not yet prepared
|
||||||
_currentOriginal.setDevicePixelRatio(_request.factor);
|
_frame->original.setDevicePixelRatio(_request.factor);
|
||||||
|
|
||||||
_previousMs = _currentMs;
|
_previousMs = _currentMs;
|
||||||
_currentMs = ms;
|
_currentMs = ms;
|
||||||
_current = _prepareFrame(_request, _currentOriginal, _currentCache, _currentHasAlpha);
|
_frame->pix = _prepareFrame(_request, _frame->original, _frame->alpha, _frame->cache);
|
||||||
|
|
||||||
if (!prepareNextFrame()) {
|
if (!prepareNextFrame()) {
|
||||||
return error();
|
return error();
|
||||||
|
@ -906,20 +907,16 @@ public:
|
||||||
void swapBuffers(uint64 ms = 0) {
|
void swapBuffers(uint64 ms = 0) {
|
||||||
_previousMs = _currentMs;
|
_previousMs = _currentMs;
|
||||||
_currentMs = qMax(ms, _nextUpdateMs);
|
_currentMs = qMax(ms, _nextUpdateMs);
|
||||||
qSwap(_currentOriginal, _nextOriginal);
|
|
||||||
qSwap(_current, _next);
|
|
||||||
qSwap(_currentCache, _nextCache);
|
|
||||||
qSwap(_currentHasAlpha, _nextHasAlpha);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool prepareNextFrame() {
|
bool prepareNextFrame() {
|
||||||
if (!_implementation->readNextFrame(_nextOriginal, _nextHasAlpha, QSize(_request.framew, _request.frameh))) {
|
if (!_implementation->readNextFrame(_frame->original, _frame->alpha, QSize(_request.framew, _request.frameh))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_nextUpdateMs = _currentMs + nextFrameDelay();
|
_nextUpdateMs = _currentMs + nextFrameDelay();
|
||||||
_nextOriginal.setDevicePixelRatio(_request.factor);
|
_frame->original.setDevicePixelRatio(_request.factor);
|
||||||
_next = QPixmap();
|
_frame->pix = QPixmap();
|
||||||
_next = _prepareFrame(_request, _nextOriginal, _nextCache, _nextHasAlpha);
|
_frame->pix = _prepareFrame(_request, _frame->original, _frame->alpha, _frame->cache);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -979,9 +976,16 @@ private:
|
||||||
ClipReaderImplementation *_implementation;
|
ClipReaderImplementation *_implementation;
|
||||||
|
|
||||||
ClipFrameRequest _request;
|
ClipFrameRequest _request;
|
||||||
QPixmap _current, _next;
|
struct Frame {
|
||||||
QImage _currentOriginal, _nextOriginal, _currentCache, _nextCache;
|
Frame() : alpha(true) {
|
||||||
bool _currentHasAlpha, _nextHasAlpha;
|
}
|
||||||
|
QPixmap pix;
|
||||||
|
QImage original, cache;
|
||||||
|
bool alpha;
|
||||||
|
};
|
||||||
|
Frame _frames[3];
|
||||||
|
Frame *_frame;
|
||||||
|
|
||||||
int32 _width, _height;
|
int32 _width, _height;
|
||||||
|
|
||||||
uint64 _previousMs, _currentMs, _nextUpdateMs;
|
uint64 _previousMs, _currentMs, _nextUpdateMs;
|
||||||
|
@ -1016,34 +1020,58 @@ void ClipReadManager::start(ClipReader *reader) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClipReadManager::update(ClipReader *reader) {
|
void ClipReadManager::update(ClipReader *reader) {
|
||||||
QMutexLocker lock(&_readerPointersMutex);
|
QReadLocker lock(&_readerPointersMutex);
|
||||||
_readerPointers.insert(reader, reader->_private);
|
ReaderPointers::const_iterator i = _readerPointers.constFind(reader);
|
||||||
|
if (i == _readerPointers.cend()) {
|
||||||
|
lock.unlock();
|
||||||
|
|
||||||
|
QWriteLocker lock(&_readerPointersMutex);
|
||||||
|
_readerPointers.insert(reader, MutableAtomicInt(1));
|
||||||
|
} else {
|
||||||
|
i->v.storeRelease(1);
|
||||||
|
}
|
||||||
emit processDelayed();
|
emit processDelayed();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClipReadManager::stop(ClipReader *reader) {
|
void ClipReadManager::stop(ClipReader *reader) {
|
||||||
QMutexLocker lock(&_readerPointersMutex);
|
if (!carries(reader)) return;
|
||||||
|
|
||||||
|
QWriteLocker lock(&_readerPointersMutex);
|
||||||
_readerPointers.remove(reader);
|
_readerPointers.remove(reader);
|
||||||
emit processDelayed();
|
emit processDelayed();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClipReadManager::carries(ClipReader *reader) const {
|
bool ClipReadManager::carries(ClipReader *reader) const {
|
||||||
QMutexLocker lock(&_readerPointersMutex);
|
QReadLocker lock(&_readerPointersMutex);
|
||||||
return _readerPointers.contains(reader);
|
return _readerPointers.contains(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClipReadManager::handleProcessResult(ClipReaderPrivate *reader, ClipProcessResult result, uint64 ms) {
|
ClipReadManager::ReaderPointers::iterator ClipReadManager::unsafeFindReaderPointer(ClipReaderPrivate *reader) {
|
||||||
QMutexLocker lock(&_readerPointersMutex);
|
|
||||||
ReaderPointers::iterator it = _readerPointers.find(reader->_interface);
|
ReaderPointers::iterator it = _readerPointers.find(reader->_interface);
|
||||||
if (it != _readerPointers.cend() && it.key()->_private != reader) {
|
|
||||||
it = _readerPointers.end(); // it is a new reader which was realloced in the same address
|
// could be a new reader which was realloced in the same address
|
||||||
}
|
return (it == _readerPointers.cend() || it.key()->_private == reader) ? it : _readerPointers.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
ClipReadManager::ReaderPointers::const_iterator ClipReadManager::constUnsafeFindReaderPointer(ClipReaderPrivate *reader) const {
|
||||||
|
ReaderPointers::const_iterator it = _readerPointers.constFind(reader->_interface);
|
||||||
|
|
||||||
|
// could be a new reader which was realloced in the same address
|
||||||
|
return (it == _readerPointers.cend() || it.key()->_private == reader) ? it : _readerPointers.cend();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClipReadManager::handleProcessResult(ClipReaderPrivate *reader, ClipProcessResult result, uint64 ms) {
|
||||||
|
QReadLocker lock(&_readerPointersMutex);
|
||||||
|
ReaderPointers::const_iterator it = constUnsafeFindReaderPointer(reader);
|
||||||
if (result == ClipProcessError) {
|
if (result == ClipProcessError) {
|
||||||
if (it != _readerPointers.cend()) {
|
if (it != _readerPointers.cend()) {
|
||||||
it.key()->error();
|
it.key()->error();
|
||||||
emit callback(it.key(), it.key()->threadIndex(), ClipReaderReinit);
|
emit callback(it.key(), it.key()->threadIndex(), ClipReaderReinit);
|
||||||
|
|
||||||
_readerPointers.erase(it);
|
lock.unlock();
|
||||||
|
QWriteLocker lock(&_readerPointersMutex);
|
||||||
|
ReaderPointers::iterator i = unsafeFindReaderPointer(reader);
|
||||||
|
if (i != _readerPointers.cend()) _readerPointers.erase(i);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1066,9 +1094,9 @@ bool ClipReadManager::handleProcessResult(ClipReaderPrivate *reader, ClipProcess
|
||||||
if (result == ClipProcessReinit || result == ClipProcessRepaint || result == ClipProcessStarted) {
|
if (result == ClipProcessReinit || result == ClipProcessRepaint || result == ClipProcessStarted) {
|
||||||
ClipReader::Frame *frame = it.key()->frameToWrite();
|
ClipReader::Frame *frame = it.key()->frameToWrite();
|
||||||
t_assert(frame != 0);
|
t_assert(frame != 0);
|
||||||
frame->pix = QPixmap();
|
frame->clear();
|
||||||
frame->pix = reader->_current;
|
frame->pix = reader->_frame->pix;
|
||||||
frame->original = reader->_currentOriginal;
|
frame->original = reader->_frame->original;
|
||||||
frame->displayed = false;
|
frame->displayed = false;
|
||||||
it.key()->moveToNextWrite();
|
it.key()->moveToNextWrite();
|
||||||
if (result == ClipProcessReinit) {
|
if (result == ClipProcessReinit) {
|
||||||
|
@ -1082,7 +1110,7 @@ bool ClipReadManager::handleProcessResult(ClipReaderPrivate *reader, ClipProcess
|
||||||
|
|
||||||
ClipReadManager::ResultHandleState ClipReadManager::handleResult(ClipReaderPrivate *reader, ClipProcessResult result, uint64 ms) {
|
ClipReadManager::ResultHandleState ClipReadManager::handleResult(ClipReaderPrivate *reader, ClipProcessResult result, uint64 ms) {
|
||||||
if (!handleProcessResult(reader, result, ms)) {
|
if (!handleProcessResult(reader, result, ms)) {
|
||||||
_loadLevel.fetchAndAddRelaxed(-1 * (reader->_currentOriginal.isNull() ? AverageGifSize : reader->_width * reader->_height));
|
_loadLevel.fetchAndAddRelaxed(-1 * (reader->_frame->original.isNull() ? AverageGifSize : reader->_width * reader->_height));
|
||||||
delete reader;
|
delete reader;
|
||||||
return ResultHandleRemove;
|
return ResultHandleRemove;
|
||||||
}
|
}
|
||||||
|
@ -1110,27 +1138,37 @@ void ClipReadManager::process() {
|
||||||
|
|
||||||
uint64 ms = getms(), minms = ms + 86400 * 1000ULL;
|
uint64 ms = getms(), minms = ms + 86400 * 1000ULL;
|
||||||
{
|
{
|
||||||
QMutexLocker lock(&_readerPointersMutex);
|
QReadLocker lock(&_readerPointersMutex);
|
||||||
for (ReaderPointers::iterator i = _readerPointers.begin(), e = _readerPointers.end(); i != e; ++i) {
|
for (ReaderPointers::iterator it = _readerPointers.begin(), e = _readerPointers.end(); it != e; ++it) {
|
||||||
if (i.value()) {
|
if (it->v.loadAcquire()) {
|
||||||
Readers::iterator it = _readers.find(i.value());
|
Readers::iterator i = _readers.find(it.key()->_private);
|
||||||
if (it == _readers.cend()) {
|
if (i == _readers.cend()) {
|
||||||
_readers.insert(i.value(), 0);
|
_readers.insert(it.key()->_private, 0);
|
||||||
} else {
|
} else {
|
||||||
it.value() = ms;
|
i.value() = ms;
|
||||||
if (it.key()->_paused && !i.key()->_paused.loadAcquire()) {
|
if (i.key()->_paused && !it.key()->_paused.loadAcquire()) {
|
||||||
it.key()->_paused = false;
|
i.key()->_paused = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ClipReader::Frame *frame = i.key()->frameToWrite();
|
ClipReader::Frame *frame = it.key()->frameToWrite();
|
||||||
if (frame) i.value()->_request = frame->request;
|
if (frame) it.key()->_private->_request = frame->request;
|
||||||
i.value() = 0;
|
it->v.storeRelease(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Readers::iterator i = _readers.begin(), e = _readers.end(); i != e;) {
|
for (Readers::iterator i = _readers.begin(), e = _readers.end(); i != e;) {
|
||||||
if (i.value() <= ms) {
|
if (i.value() <= ms) {
|
||||||
|
{
|
||||||
|
QReadLocker lock(&_readerPointersMutex);
|
||||||
|
ReaderPointers::const_iterator it = constUnsafeFindReaderPointer(i.key());
|
||||||
|
if (it != _readerPointers.cend()) {
|
||||||
|
int32 index = 0;
|
||||||
|
ClipReader::Frame *frame = it.key()->frameToWrite(&index);
|
||||||
|
if (frame) frame->clear();
|
||||||
|
i.key()->_frame = i.key()->_frames + index;
|
||||||
|
}
|
||||||
|
}
|
||||||
ClipProcessResult result = i.key()->process(ms);
|
ClipProcessResult result = i.key()->process(ms);
|
||||||
|
|
||||||
ResultHandleState state = handleResult(i.key(), result, ms);
|
ResultHandleState state = handleResult(i.key(), result, ms);
|
||||||
|
@ -1167,13 +1205,13 @@ void ClipReadManager::finish() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClipReadManager::clear() {
|
void ClipReadManager::clear() {
|
||||||
QMutexLocker lock(&_readerPointersMutex);
|
{
|
||||||
for (ReaderPointers::iterator i = _readerPointers.begin(), e = _readerPointers.end(); i != e; ++i) {
|
QWriteLocker lock(&_readerPointersMutex);
|
||||||
if (i.value()) {
|
for (ReaderPointers::iterator it = _readerPointers.begin(), e = _readerPointers.end(); it != e; ++it) {
|
||||||
i.key()->_private = 0;
|
it.key()->_private = 0;
|
||||||
}
|
}
|
||||||
}
|
_readerPointers.clear();
|
||||||
_readerPointers.clear();
|
}
|
||||||
|
|
||||||
for (Readers::iterator i = _readers.begin(), e = _readers.end(); i != e; ++i) {
|
for (Readers::iterator i = _readers.begin(), e = _readers.end(); i != e; ++i) {
|
||||||
delete i.key();
|
delete i.key();
|
||||||
|
@ -1195,12 +1233,12 @@ MTPDocumentAttribute clipReadAnimatedAttributes(const QString &fname, const QByt
|
||||||
if (reader->readNextFrame(cover, hasAlpha, QSize())) {
|
if (reader->readNextFrame(cover, hasAlpha, QSize())) {
|
||||||
if (cover.width() > 0 && cover.height() > 0 && cover.width() < cover.height() * 10 && cover.height() < cover.width() * 10) {
|
if (cover.width() > 0 && cover.height() > 0 && cover.width() < cover.height() * 10 && cover.height() < cover.width() * 10) {
|
||||||
if (hasAlpha) {
|
if (hasAlpha) {
|
||||||
QImage cache;
|
QImage cacheForResize;
|
||||||
ClipFrameRequest request;
|
ClipFrameRequest request;
|
||||||
request.framew = request.outerw = cover.width();
|
request.framew = request.outerw = cover.width();
|
||||||
request.frameh = request.outerh = cover.height();
|
request.frameh = request.outerh = cover.height();
|
||||||
request.factor = 1;
|
request.factor = 1;
|
||||||
cover = _prepareFrame(request, cover, cache, hasAlpha).toImage();
|
cover = _prepareFrame(request, cover, hasAlpha, cacheForResize).toImage();
|
||||||
}
|
}
|
||||||
int32 duration = reader->duration();
|
int32 duration = reader->duration();
|
||||||
delete reader;
|
delete reader;
|
||||||
|
|
|
@ -563,6 +563,10 @@ private:
|
||||||
struct Frame {
|
struct Frame {
|
||||||
Frame() : displayed(false), when(0) {
|
Frame() : displayed(false), when(0) {
|
||||||
}
|
}
|
||||||
|
void clear() {
|
||||||
|
pix = QPixmap();
|
||||||
|
original = QImage();
|
||||||
|
}
|
||||||
QPixmap pix;
|
QPixmap pix;
|
||||||
QImage original;
|
QImage original;
|
||||||
ClipFrameRequest request;
|
ClipFrameRequest request;
|
||||||
|
@ -571,7 +575,7 @@ private:
|
||||||
};
|
};
|
||||||
mutable Frame _frames[3];
|
mutable Frame _frames[3];
|
||||||
Frame *frameToShow() const; // 0 means not ready
|
Frame *frameToShow() const; // 0 means not ready
|
||||||
Frame *frameToWrite() const; // 0 means not ready
|
Frame *frameToWrite(int32 *index = 0) const; // 0 means not ready
|
||||||
Frame *frameToRequestOther(bool check) const;
|
Frame *frameToRequestOther(bool check) const;
|
||||||
void moveToNextShow() const;
|
void moveToNextShow() const;
|
||||||
void moveToNextWrite() const;
|
void moveToNextWrite() const;
|
||||||
|
@ -629,9 +633,17 @@ private:
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
QAtomicInt _loadLevel;
|
QAtomicInt _loadLevel;
|
||||||
typedef QMap<ClipReader*, ClipReaderPrivate*> ReaderPointers;
|
struct MutableAtomicInt {
|
||||||
|
MutableAtomicInt(int value) : v(value) {
|
||||||
|
}
|
||||||
|
mutable QAtomicInt v;
|
||||||
|
};
|
||||||
|
typedef QMap<ClipReader*, MutableAtomicInt> ReaderPointers;
|
||||||
ReaderPointers _readerPointers;
|
ReaderPointers _readerPointers;
|
||||||
mutable QMutex _readerPointersMutex;
|
mutable QReadWriteLock _readerPointersMutex;
|
||||||
|
|
||||||
|
ReaderPointers::const_iterator constUnsafeFindReaderPointer(ClipReaderPrivate *reader) const;
|
||||||
|
ReaderPointers::iterator unsafeFindReaderPointer(ClipReaderPrivate *reader);
|
||||||
|
|
||||||
bool handleProcessResult(ClipReaderPrivate *reader, ClipProcessResult result, uint64 ms);
|
bool handleProcessResult(ClipReaderPrivate *reader, ClipProcessResult result, uint64 ms);
|
||||||
|
|
||||||
|
|
|
@ -3594,6 +3594,7 @@ namespace Local {
|
||||||
struct ClearManagerData {
|
struct ClearManagerData {
|
||||||
QThread *thread;
|
QThread *thread;
|
||||||
StorageMap images, stickers, audios;
|
StorageMap images, stickers, audios;
|
||||||
|
WebFilesMap webFiles;
|
||||||
QMutex mutex;
|
QMutex mutex;
|
||||||
QList<int> tasks;
|
QList<int> tasks;
|
||||||
bool working;
|
bool working;
|
||||||
|
@ -3693,6 +3694,22 @@ namespace Local {
|
||||||
_storageStickersSize = 0;
|
_storageStickersSize = 0;
|
||||||
_mapChanged = true;
|
_mapChanged = true;
|
||||||
}
|
}
|
||||||
|
if (data->webFiles.isEmpty()) {
|
||||||
|
data->webFiles = _webFilesMap;
|
||||||
|
} else {
|
||||||
|
for (WebFilesMap::const_iterator i = _webFilesMap.cbegin(), e = _webFilesMap.cend(); i != e; ++i) {
|
||||||
|
QString k = i.key();
|
||||||
|
while (data->webFiles.constFind(k) != data->webFiles.cend()) {
|
||||||
|
k += '#';
|
||||||
|
}
|
||||||
|
data->webFiles.insert(k, i.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!_webFilesMap.isEmpty()) {
|
||||||
|
_webFilesMap.clear();
|
||||||
|
_storageWebFilesSize = 0;
|
||||||
|
_writeLocations();
|
||||||
|
}
|
||||||
if (data->audios.isEmpty()) {
|
if (data->audios.isEmpty()) {
|
||||||
data->audios = _audiosMap;
|
data->audios = _audiosMap;
|
||||||
} else {
|
} else {
|
||||||
|
@ -3745,6 +3762,7 @@ namespace Local {
|
||||||
int task = 0;
|
int task = 0;
|
||||||
bool result = false;
|
bool result = false;
|
||||||
StorageMap images, stickers, audios;
|
StorageMap images, stickers, audios;
|
||||||
|
WebFilesMap webFiles;
|
||||||
{
|
{
|
||||||
QMutexLocker lock(&data->mutex);
|
QMutexLocker lock(&data->mutex);
|
||||||
if (data->tasks.isEmpty()) {
|
if (data->tasks.isEmpty()) {
|
||||||
|
@ -3755,6 +3773,7 @@ namespace Local {
|
||||||
images = data->images;
|
images = data->images;
|
||||||
stickers = data->stickers;
|
stickers = data->stickers;
|
||||||
audios = data->audios;
|
audios = data->audios;
|
||||||
|
webFiles = data->webFiles;
|
||||||
}
|
}
|
||||||
switch (task) {
|
switch (task) {
|
||||||
case ClearManagerAll: {
|
case ClearManagerAll: {
|
||||||
|
@ -3786,6 +3805,9 @@ namespace Local {
|
||||||
for (StorageMap::const_iterator i = audios.cbegin(), e = audios.cend(); i != e; ++i) {
|
for (StorageMap::const_iterator i = audios.cbegin(), e = audios.cend(); i != e; ++i) {
|
||||||
clearKey(i.value().first, UserPath);
|
clearKey(i.value().first, UserPath);
|
||||||
}
|
}
|
||||||
|
for (WebFilesMap::const_iterator i = webFiles.cbegin(), e = webFiles.cend(); i != e; ++i) {
|
||||||
|
clearKey(i.value().first, UserPath);
|
||||||
|
}
|
||||||
result = true;
|
result = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -462,7 +462,7 @@ void SettingsInner::paintEvent(QPaintEvent *e) {
|
||||||
top += st::setHeaderSkip;
|
top += st::setHeaderSkip;
|
||||||
|
|
||||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||||
top += _autoUpdate.height();
|
top += _autoUpdate.height();
|
||||||
QString textToDraw;
|
QString textToDraw;
|
||||||
if (cAutoUpdate()) {
|
if (cAutoUpdate()) {
|
||||||
switch (_updatingState) {
|
switch (_updatingState) {
|
||||||
|
@ -485,7 +485,7 @@ void SettingsInner::paintEvent(QPaintEvent *e) {
|
||||||
if (cPlatform() == dbipWindows) {
|
if (cPlatform() == dbipWindows) {
|
||||||
top += _workmodeTray.height() + st::setLittleSkip;
|
top += _workmodeTray.height() + st::setLittleSkip;
|
||||||
top += _workmodeWindow.height() + st::setSectionSkip;
|
top += _workmodeWindow.height() + st::setSectionSkip;
|
||||||
|
|
||||||
top += _autoStart.height() + st::setLittleSkip;
|
top += _autoStart.height() + st::setLittleSkip;
|
||||||
top += _startMinimized.height() + st::setSectionSkip;
|
top += _startMinimized.height() + st::setSectionSkip;
|
||||||
|
|
||||||
|
@ -500,12 +500,12 @@ void SettingsInner::paintEvent(QPaintEvent *e) {
|
||||||
p.drawText(_left + st::setHeaderLeft, top + st::setHeaderTop + st::setHeaderFont->ascent, lang(lng_settings_scale_label));
|
p.drawText(_left + st::setHeaderLeft, top + st::setHeaderTop + st::setHeaderFont->ascent, lang(lng_settings_scale_label));
|
||||||
top += st::setHeaderSkip;
|
top += st::setHeaderSkip;
|
||||||
top += _dpiAutoScale.height() + st::setLittleSkip;
|
top += _dpiAutoScale.height() + st::setLittleSkip;
|
||||||
|
|
||||||
top += _dpiSlider.height() + st::dpiFont4->height;
|
top += _dpiSlider.height() + st::dpiFont4->height;
|
||||||
int32 sLeft = _dpiSlider.x() + _dpiWidth1 / 2, sWidth = _dpiSlider.width();
|
int32 sLeft = _dpiSlider.x() + _dpiWidth1 / 2, sWidth = _dpiSlider.width();
|
||||||
float64 sStep = (sWidth - _dpiWidth1 / 2 - _dpiWidth4 / 2) / float64(dbisScaleCount - 2);
|
float64 sStep = (sWidth - _dpiWidth1 / 2 - _dpiWidth4 / 2) / float64(dbisScaleCount - 2);
|
||||||
p.setFont(st::dpiFont1->f);
|
p.setFont(st::dpiFont1->f);
|
||||||
|
|
||||||
p.setPen((scaleIs(dbisOne) ? st::dpiActive : st::dpiInactive)->p);
|
p.setPen((scaleIs(dbisOne) ? st::dpiActive : st::dpiInactive)->p);
|
||||||
p.drawText(sLeft + qRound(0 * sStep) - _dpiWidth1 / 2, top - (st::dpiFont4->height - st::dpiFont1->height) / 2 - st::dpiFont1->descent, scaleLabel(dbisOne));
|
p.drawText(sLeft + qRound(0 * sStep) - _dpiWidth1 / 2, top - (st::dpiFont4->height - st::dpiFont1->height) / 2 - st::dpiFont1->descent, scaleLabel(dbisOne));
|
||||||
p.setFont(st::dpiFont2->f);
|
p.setFont(st::dpiFont2->f);
|
||||||
|
@ -519,7 +519,7 @@ void SettingsInner::paintEvent(QPaintEvent *e) {
|
||||||
p.drawText(sLeft + qRound(3 * sStep) - _dpiWidth4 / 2, top - (st::dpiFont4->height - st::dpiFont4->height) / 2 - st::dpiFont4->descent, scaleLabel(dbisTwo));
|
p.drawText(sLeft + qRound(3 * sStep) - _dpiWidth4 / 2, top - (st::dpiFont4->height - st::dpiFont4->height) / 2 - st::dpiFont4->descent, scaleLabel(dbisTwo));
|
||||||
p.setFont(st::linkFont->f);
|
p.setFont(st::linkFont->f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self()) {
|
if (self()) {
|
||||||
// chat options
|
// chat options
|
||||||
p.setFont(st::setHeaderFont->f);
|
p.setFont(st::setHeaderFont->f);
|
||||||
|
@ -575,7 +575,7 @@ void SettingsInner::paintEvent(QPaintEvent *e) {
|
||||||
|
|
||||||
top += st::setHeaderSkip;
|
top += st::setHeaderSkip;
|
||||||
|
|
||||||
int32 cntImages = Local::hasImages() + Local::hasStickers(), cntAudios = Local::hasAudios();
|
int32 cntImages = Local::hasImages() + Local::hasStickers() + Local::hasWebFiles(), cntAudios = Local::hasAudios();
|
||||||
if (cntImages > 0 && cntAudios > 0) {
|
if (cntImages > 0 && cntAudios > 0) {
|
||||||
if (_localStorageHeight != 2) {
|
if (_localStorageHeight != 2) {
|
||||||
cntAudios = 0;
|
cntAudios = 0;
|
||||||
|
@ -587,7 +587,7 @@ void SettingsInner::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cntImages > 0) {
|
if (cntImages > 0) {
|
||||||
QString cnt = lng_settings_images_cached(lt_count, cntImages, lt_size, formatSizeText(Local::storageImagesSize() + Local::storageStickersSize()));
|
QString cnt = lng_settings_images_cached(lt_count, cntImages, lt_size, formatSizeText(Local::storageImagesSize() + Local::storageStickersSize() + Local::storageWebFilesSize()));
|
||||||
p.drawText(_left + st::setHeaderLeft, top + st::linkFont->ascent, cnt);
|
p.drawText(_left + st::setHeaderLeft, top + st::linkFont->ascent, cnt);
|
||||||
}
|
}
|
||||||
if (_localStorageHeight == 2) top += _localStorageClear.height() + st::setLittleSkip;
|
if (_localStorageHeight == 2) top += _localStorageClear.height() + st::setLittleSkip;
|
||||||
|
@ -644,7 +644,7 @@ void SettingsInner::paintEvent(QPaintEvent *e) {
|
||||||
p.setPen(st::setHeaderColor->p);
|
p.setPen(st::setHeaderColor->p);
|
||||||
p.drawText(_left + st::setHeaderLeft, top + st::setHeaderTop + st::setHeaderFont->ascent, lang(lng_settings_section_advanced));
|
p.drawText(_left + st::setHeaderLeft, top + st::setHeaderTop + st::setHeaderFont->ascent, lang(lng_settings_section_advanced));
|
||||||
top += st::setHeaderSkip;
|
top += st::setHeaderSkip;
|
||||||
|
|
||||||
p.setFont(st::linkFont->f);
|
p.setFont(st::linkFont->f);
|
||||||
p.setPen(st::black->p);
|
p.setPen(st::black->p);
|
||||||
if (self()) {
|
if (self()) {
|
||||||
|
@ -702,7 +702,7 @@ void SettingsInner::resizeEvent(QResizeEvent *e) {
|
||||||
if (cPlatform() == dbipWindows) {
|
if (cPlatform() == dbipWindows) {
|
||||||
_workmodeTray.move(_left, top); top += _workmodeTray.height() + st::setLittleSkip;
|
_workmodeTray.move(_left, top); top += _workmodeTray.height() + st::setLittleSkip;
|
||||||
_workmodeWindow.move(_left, top); top += _workmodeWindow.height() + st::setSectionSkip;
|
_workmodeWindow.move(_left, top); top += _workmodeWindow.height() + st::setSectionSkip;
|
||||||
|
|
||||||
_autoStart.move(_left, top); top += _autoStart.height() + st::setLittleSkip;
|
_autoStart.move(_left, top); top += _autoStart.height() + st::setLittleSkip;
|
||||||
_startMinimized.move(_left, top); top += _startMinimized.height() + st::setSectionSkip;
|
_startMinimized.move(_left, top); top += _startMinimized.height() + st::setSectionSkip;
|
||||||
|
|
||||||
|
@ -715,7 +715,7 @@ void SettingsInner::resizeEvent(QResizeEvent *e) {
|
||||||
_dpiAutoScale.move(_left, top); top += _dpiAutoScale.height() + st::setLittleSkip;
|
_dpiAutoScale.move(_left, top); top += _dpiAutoScale.height() + st::setLittleSkip;
|
||||||
_dpiSlider.move(_left, top); top += _dpiSlider.height() + st::dpiFont4->height;
|
_dpiSlider.move(_left, top); top += _dpiSlider.height() + st::dpiFont4->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
// chat options
|
// chat options
|
||||||
if (self()) {
|
if (self()) {
|
||||||
top += st::setHeaderSkip;
|
top += st::setHeaderSkip;
|
||||||
|
@ -739,7 +739,7 @@ void SettingsInner::resizeEvent(QResizeEvent *e) {
|
||||||
// local storage
|
// local storage
|
||||||
_localStorageClear.move(_left + st::setWidth - _localStorageClear.width(), top + st::setHeaderTop + st::setHeaderFont->ascent - st::linkFont->ascent);
|
_localStorageClear.move(_left + st::setWidth - _localStorageClear.width(), top + st::setHeaderTop + st::setHeaderFont->ascent - st::linkFont->ascent);
|
||||||
top += st::setHeaderSkip;
|
top += st::setHeaderSkip;
|
||||||
if ((Local::hasImages() || Local::hasStickers()) && Local::hasAudios()) {
|
if ((Local::hasImages() || Local::hasStickers() || Local::hasWebFiles()) && Local::hasAudios()) {
|
||||||
_localStorageHeight = 2;
|
_localStorageHeight = 2;
|
||||||
top += _localStorageClear.height() + st::setLittleSkip;
|
top += _localStorageClear.height() + st::setLittleSkip;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1031,7 +1031,7 @@ void SettingsInner::showAll() {
|
||||||
_workmodeTray.hide();
|
_workmodeTray.hide();
|
||||||
}
|
}
|
||||||
_workmodeWindow.hide();
|
_workmodeWindow.hide();
|
||||||
|
|
||||||
_autoStart.hide();
|
_autoStart.hide();
|
||||||
_startMinimized.hide();
|
_startMinimized.hide();
|
||||||
|
|
||||||
|
@ -1163,7 +1163,7 @@ void SettingsInner::onUpdatePhotoCancel() {
|
||||||
void SettingsInner::onUpdatePhoto() {
|
void SettingsInner::onUpdatePhoto() {
|
||||||
saveError();
|
saveError();
|
||||||
|
|
||||||
QStringList imgExtensions(cImgExtensions());
|
QStringList imgExtensions(cImgExtensions());
|
||||||
QString filter(qsl("Image files (*") + imgExtensions.join(qsl(" *")) + qsl(");;All files (*.*)"));
|
QString filter(qsl("Image files (*") + imgExtensions.join(qsl(" *")) + qsl(");;All files (*.*)"));
|
||||||
|
|
||||||
QImage img;
|
QImage img;
|
||||||
|
|
|
@ -453,9 +453,9 @@ void Window::firstShow() {
|
||||||
trayIconMenu = new QMenu(this);
|
trayIconMenu = new QMenu(this);
|
||||||
trayIconMenu->setFont(QFont("Tahoma"));
|
trayIconMenu->setFont(QFont("Tahoma"));
|
||||||
#endif
|
#endif
|
||||||
QString notificationItem = lang(cDesktopNotify()
|
QString notificationItem = lang(cDesktopNotify()
|
||||||
? lng_disable_notifications_from_tray : lng_enable_notifications_from_tray);
|
? lng_disable_notifications_from_tray : lng_enable_notifications_from_tray);
|
||||||
|
|
||||||
if (cPlatform() == dbipWindows || cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
|
if (cPlatform() == dbipWindows || cPlatform() == dbipMac || cPlatform() == dbipMacOld) {
|
||||||
trayIconMenu->addAction(lang(lng_minimize_to_tray), this, SLOT(minimizeToTray()))->setEnabled(true);
|
trayIconMenu->addAction(lang(lng_minimize_to_tray), this, SLOT(minimizeToTray()))->setEnabled(true);
|
||||||
trayIconMenu->addAction(notificationItem, this, SLOT(toggleDisplayNotifyFromTray()))->setEnabled(true);
|
trayIconMenu->addAction(notificationItem, this, SLOT(toggleDisplayNotifyFromTray()))->setEnabled(true);
|
||||||
|
@ -940,7 +940,7 @@ void Window::paintEvent(QPaintEvent *e) {
|
||||||
|
|
||||||
HitTestType Window::hitTest(const QPoint &p) const {
|
HitTestType Window::hitTest(const QPoint &p) const {
|
||||||
int x(p.x()), y(p.y()), w(width()), h(height());
|
int x(p.x()), y(p.y()), w(width()), h(height());
|
||||||
|
|
||||||
const int32 raw = psResizeRowWidth();
|
const int32 raw = psResizeRowWidth();
|
||||||
if (!windowState().testFlag(Qt::WindowMaximized)) {
|
if (!windowState().testFlag(Qt::WindowMaximized)) {
|
||||||
if (y < raw) {
|
if (y < raw) {
|
||||||
|
@ -1019,7 +1019,7 @@ void Window::mouseMoveEvent(QMouseEvent *e) {
|
||||||
if (dragging) {
|
if (dragging) {
|
||||||
if (windowState().testFlag(Qt::WindowMaximized)) {
|
if (windowState().testFlag(Qt::WindowMaximized)) {
|
||||||
setWindowState(windowState() & ~Qt::WindowMaximized);
|
setWindowState(windowState() & ~Qt::WindowMaximized);
|
||||||
|
|
||||||
dragStart = e->globalPos() - frameGeometry().topLeft();
|
dragStart = e->globalPos() - frameGeometry().topLeft();
|
||||||
} else {
|
} else {
|
||||||
move(e->globalPos() - dragStart);
|
move(e->globalPos() - dragStart);
|
||||||
|
@ -1260,7 +1260,7 @@ Window::TempDirState Window::localStorageState() {
|
||||||
if (_clearManager && _clearManager->hasTask(Local::ClearManagerStorage)) {
|
if (_clearManager && _clearManager->hasTask(Local::ClearManagerStorage)) {
|
||||||
return TempDirRemoving;
|
return TempDirRemoving;
|
||||||
}
|
}
|
||||||
return (Local::hasImages() || Local::hasStickers() || Local::hasAudios()) ? TempDirExists : TempDirEmpty;
|
return (Local::hasImages() || Local::hasStickers() || Local::hasWebFiles() || Local::hasAudios()) ? TempDirExists : TempDirEmpty;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::tempDirDelete(int task) {
|
void Window::tempDirDelete(int task) {
|
||||||
|
|
Loading…
Reference in New Issue