mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-11 08:48:14 +00:00
context bots started, all callbacks done by pointers
This commit is contained in:
parent
43e173567f
commit
77228d358d
@ -1430,9 +1430,10 @@ namespace App {
|
||||
return ::self;
|
||||
}
|
||||
|
||||
PeerData *peerByName(const QString &username) {
|
||||
PeerData *peerByName(const QStringRef &username) {
|
||||
QStringRef uname(username.trimmed());
|
||||
for (PeersData::const_iterator i = peersData.cbegin(), e = peersData.cend(); i != e; ++i) {
|
||||
if (!i.value()->userName().compare(username.trimmed(), Qt::CaseInsensitive)) {
|
||||
if (!i.value()->userName().compare(uname, Qt::CaseInsensitive)) {
|
||||
return i.value()->asUser();
|
||||
}
|
||||
}
|
||||
@ -2471,10 +2472,6 @@ namespace App {
|
||||
::gifItems.remove(reader);
|
||||
}
|
||||
|
||||
const GifItems &gifItems() {
|
||||
return ::gifItems;
|
||||
}
|
||||
|
||||
void stopGifItems() {
|
||||
if (!::gifItems.isEmpty()) {
|
||||
GifItems gifs = ::gifItems;
|
||||
|
@ -132,7 +132,10 @@ namespace App {
|
||||
ChatData *chat(int32 chat_id);
|
||||
ChannelData *channel(int32 channel_id);
|
||||
UserData *self();
|
||||
PeerData *peerByName(const QString &username);
|
||||
PeerData *peerByName(const QStringRef &username);
|
||||
inline PeerData *peerByName(const QString &username) {
|
||||
return peerByName(username.midRef(0));
|
||||
}
|
||||
QString peerName(const PeerData *peer, bool forDialogs = false);
|
||||
PhotoData *photo(const PhotoId &photo);
|
||||
PhotoData *photoSet(const PhotoId &photo, PhotoData *convert, const uint64 &access, int32 date, const ImagePtr &thumb, const ImagePtr &medium, const ImagePtr &full);
|
||||
@ -240,7 +243,6 @@ namespace App {
|
||||
|
||||
void regGifItem(ClipReader *reader, HistoryItem *item);
|
||||
void unregGifItem(ClipReader *reader);
|
||||
const GifItems &gifItems();
|
||||
void stopGifItems();
|
||||
|
||||
void regMuted(PeerData *peer, int32 changeIn);
|
||||
|
@ -107,18 +107,6 @@ namespace Ui {
|
||||
return false;
|
||||
}
|
||||
|
||||
void clipRepaint(ClipReader *reader) {
|
||||
const GifItems &items(App::gifItems());
|
||||
GifItems::const_iterator it = items.constFind(reader);
|
||||
if (it != items.cend()) {
|
||||
if (reader->currentDisplayed()) {
|
||||
return;
|
||||
}
|
||||
Ui::repaintHistoryItem(it.value());
|
||||
}
|
||||
if (Window *w = App::wnd()) w->ui_clipRepaint(reader);
|
||||
}
|
||||
|
||||
void repaintHistoryItem(const HistoryItem *item) {
|
||||
if (!item) return;
|
||||
if (MainWidget *m = App::main()) m->ui_repaintHistoryItem(item);
|
||||
@ -168,35 +156,6 @@ namespace Notify {
|
||||
if (MainWidget *m = App::main()) m->notify_clipStopperHidden(type);
|
||||
}
|
||||
|
||||
void clipReinit(ClipReader *reader) {
|
||||
const GifItems &items(App::gifItems());
|
||||
GifItems::const_iterator it = items.constFind(reader);
|
||||
if (it != items.cend()) {
|
||||
HistoryItem *item = it.value();
|
||||
|
||||
bool stopped = false;
|
||||
if (reader->paused()) {
|
||||
if (MainWidget *m = App::main()) {
|
||||
if (!m->isItemVisible(item)) { // stop animation if it is not visible
|
||||
if (HistoryMedia *media = item->getMedia()) {
|
||||
media->stopInline(item);
|
||||
if (DocumentData *document = media->getDocument()) { // forget data from memory
|
||||
document->forget();
|
||||
}
|
||||
stopped = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!stopped) {
|
||||
item->initDimensions(); // can delete reader and items entry it
|
||||
Notify::historyItemResized(item);
|
||||
Notify::historyItemLayoutChanged(item);
|
||||
}
|
||||
}
|
||||
if (Window *w = App::wnd()) w->notify_clipReinit(reader);
|
||||
}
|
||||
|
||||
void historyItemResized(const HistoryItem *item, bool scrollToIt) {
|
||||
if (MainWidget *m = App::main()) m->notify_historyItemResized(item, scrollToIt);
|
||||
}
|
||||
|
@ -48,8 +48,6 @@ namespace Ui { // openssl doesn't allow me to use UI :(
|
||||
bool isMediaViewShown();
|
||||
bool isGifBeingChosen();
|
||||
|
||||
void clipRepaint(ClipReader *reader);
|
||||
|
||||
void repaintHistoryItem(const HistoryItem *item);
|
||||
void repaintSavedGif(const LayoutSavedGif *layout);
|
||||
bool isSavedGifVisible(const LayoutSavedGif *reader);
|
||||
@ -86,8 +84,6 @@ namespace Notify {
|
||||
|
||||
void clipStopperHidden(ClipStopperType type);
|
||||
|
||||
void clipReinit(ClipReader *reader);
|
||||
|
||||
void historyItemResized(const HistoryItem *item, bool scrollToIt = false);
|
||||
inline void historyItemsResized() {
|
||||
historyItemResized(0);
|
||||
|
@ -106,7 +106,7 @@ namespace anim {
|
||||
void Animation::start() {
|
||||
if (!_manager) return;
|
||||
|
||||
_cb->start();
|
||||
_cb.start();
|
||||
_manager->start(this);
|
||||
_animating = true;
|
||||
}
|
||||
@ -179,14 +179,8 @@ void AnimationManager::timeout() {
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationManager::clipReinit(ClipReader *reader, qint32 threadIndex) {
|
||||
ClipReader::callback(reader, threadIndex, ClipReaderReinit);
|
||||
Notify::clipReinit(reader);
|
||||
}
|
||||
|
||||
void AnimationManager::clipRepaint(ClipReader *reader, qint32 threadIndex) {
|
||||
ClipReader::callback(reader, threadIndex, ClipReaderRepaint);
|
||||
Ui::clipRepaint(reader);
|
||||
void AnimationManager::clipCallback(ClipReader *reader, qint32 threadIndex, qint32 notification) {
|
||||
ClipReader::callback(reader, threadIndex, ClipReaderNotification(notification));
|
||||
}
|
||||
|
||||
QPixmap _prepareFrame(const ClipFrameRequest &request, const QImage &original, QImage &cache, bool hasAlpha) {
|
||||
@ -225,7 +219,7 @@ QPixmap _prepareFrame(const ClipFrameRequest &request, const QImage &original, Q
|
||||
return QPixmap::fromImage(original, Qt::ColorOnly);
|
||||
}
|
||||
|
||||
ClipReader::ClipReader(const FileLocation &location, const QByteArray &data, Callback *cb)
|
||||
ClipReader::ClipReader(const FileLocation &location, const QByteArray &data, Callback::Creator cb)
|
||||
: _cb(cb)
|
||||
, _state(ClipReading)
|
||||
, _width(0)
|
||||
@ -257,7 +251,7 @@ ClipReader::ClipReader(const FileLocation &location, const QByteArray &data, Cal
|
||||
void ClipReader::callback(ClipReader *reader, int32 threadIndex, ClipReaderNotification notification) {
|
||||
// check if reader is not deleted already
|
||||
if (_clipManagers.size() > threadIndex && _clipManagers.at(threadIndex)->carries(reader)) {
|
||||
if (reader->_cb) reader->_cb->call(notification);
|
||||
reader->_cb.call(notification);
|
||||
}
|
||||
}
|
||||
|
||||
@ -351,8 +345,6 @@ void ClipReader::error() {
|
||||
|
||||
ClipReader::~ClipReader() {
|
||||
stop();
|
||||
delete _cb;
|
||||
setBadPointer(_cb);
|
||||
}
|
||||
|
||||
class ClipReaderImplementation {
|
||||
@ -448,8 +440,7 @@ public:
|
||||
}
|
||||
|
||||
~QtGifReaderImplementation() {
|
||||
delete _reader;
|
||||
setBadPointer(_reader);
|
||||
deleteAndMark(_reader);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -917,8 +908,8 @@ public:
|
||||
|
||||
~ClipReaderPrivate() {
|
||||
stop();
|
||||
setBadPointer(_location);
|
||||
setBadPointer(_implementation);
|
||||
deleteAndMark(_location);
|
||||
deleteAndMark(_implementation);
|
||||
_data.clear();
|
||||
}
|
||||
|
||||
@ -958,8 +949,7 @@ ClipReadManager::ClipReadManager(QThread *thread) : _processingInThread(0), _nee
|
||||
_timer.moveToThread(thread);
|
||||
connect(&_timer, SIGNAL(timeout()), this, SLOT(process()));
|
||||
|
||||
connect(this, SIGNAL(reinit(ClipReader*,qint32)), _manager, SLOT(clipReinit(ClipReader*,qint32)));
|
||||
connect(this, SIGNAL(repaint(ClipReader*,qint32)), _manager, SLOT(clipRepaint(ClipReader*,qint32)));
|
||||
connect(this, SIGNAL(callback(ClipReader*,qint32,qint32)), _manager, SLOT(clipCallback(ClipReader*,qint32,qint32)));
|
||||
}
|
||||
|
||||
void ClipReadManager::append(ClipReader *reader, const FileLocation &location, const QByteArray &data) {
|
||||
@ -995,7 +985,7 @@ bool ClipReadManager::handleProcessResult(ClipReaderPrivate *reader, ClipProcess
|
||||
if (result == ClipProcessError) {
|
||||
if (it != _readerPointers.cend()) {
|
||||
it.key()->error();
|
||||
emit reinit(it.key(), it.key()->threadIndex());
|
||||
emit callback(it.key(), it.key()->threadIndex(), ClipReaderReinit);
|
||||
|
||||
_readerPointers.erase(it);
|
||||
it = _readerPointers.end();
|
||||
@ -1025,9 +1015,9 @@ bool ClipReadManager::handleProcessResult(ClipReaderPrivate *reader, ClipProcess
|
||||
it.key()->_currentOriginal = reader->_currentOriginal;
|
||||
it.key()->_currentDisplayed.set(false);
|
||||
if (result == ClipProcessReinit) {
|
||||
emit reinit(it.key(), it.key()->threadIndex());
|
||||
emit callback(it.key(), it.key()->threadIndex(), ClipReaderReinit);
|
||||
} else if (result == ClipProcessRepaint) {
|
||||
emit repaint(it.key(), it.key()->threadIndex());
|
||||
emit callback(it.key(), it.key()->threadIndex(), ClipReaderRepaint);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -198,28 +198,44 @@ namespace anim {
|
||||
|
||||
class Animation;
|
||||
|
||||
class AnimationImplementation {
|
||||
public:
|
||||
virtual void start() {}
|
||||
virtual void step(Animation *a, uint64 ms, bool timer) = 0;
|
||||
virtual ~AnimationImplementation() {}
|
||||
};
|
||||
class AnimationCreator {
|
||||
public:
|
||||
AnimationCreator(AnimationImplementation *ptr) : _ptr(ptr) {}
|
||||
AnimationCreator(const AnimationCreator &other) : _ptr(other.create()) {}
|
||||
AnimationImplementation *create() const { return exchange(_ptr); }
|
||||
~AnimationCreator() { deleteAndMark(_ptr); }
|
||||
private:
|
||||
AnimationCreator &operator=(const AnimationCreator &other);
|
||||
mutable AnimationImplementation *_ptr;
|
||||
};
|
||||
class AnimationCallbacks {
|
||||
public:
|
||||
virtual void start() {
|
||||
}
|
||||
|
||||
virtual void step(Animation *a, uint64 ms, bool timer) = 0;
|
||||
|
||||
virtual ~AnimationCallbacks() {
|
||||
}
|
||||
AnimationCallbacks(const AnimationCreator &creator) : _implementation(creator.create()) {}
|
||||
void start() { _implementation->start(); }
|
||||
void step(Animation *a, uint64 ms, bool timer) { _implementation->step(a, ms, timer); }
|
||||
~AnimationCallbacks() { deleteAndMark(_implementation); }
|
||||
private:
|
||||
AnimationCallbacks(const AnimationCallbacks &other);
|
||||
AnimationCallbacks &operator=(const AnimationCallbacks &other);
|
||||
AnimationImplementation *_implementation;
|
||||
};
|
||||
|
||||
class Animation {
|
||||
public:
|
||||
|
||||
Animation(AnimationCallbacks *cb) : _cb(cb), _animating(false) {
|
||||
Animation(AnimationCreator cb) : _cb(cb), _animating(false) {
|
||||
}
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
void step(uint64 ms, bool timer = false) {
|
||||
_cb->step(this, ms, timer);
|
||||
_cb.step(this, ms, timer);
|
||||
}
|
||||
|
||||
void step() {
|
||||
@ -232,20 +248,16 @@ public:
|
||||
|
||||
~Animation() {
|
||||
if (_animating) stop();
|
||||
delete _cb;
|
||||
}
|
||||
|
||||
private:
|
||||
Animation(const Animation &);
|
||||
Animation &operator=(const Animation &);
|
||||
|
||||
AnimationCallbacks *_cb;
|
||||
AnimationCallbacks _cb;
|
||||
bool _animating;
|
||||
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
class AnimationCallbacksRelative : public AnimationCallbacks {
|
||||
class AnimationCallbacksRelative : public AnimationImplementation {
|
||||
public:
|
||||
typedef void (Type::*Method)(float64, bool);
|
||||
|
||||
@ -267,12 +279,12 @@ private:
|
||||
|
||||
};
|
||||
template <typename Type>
|
||||
AnimationCallbacks *animation(Type *obj, typename AnimationCallbacksRelative<Type>::Method method) {
|
||||
return new AnimationCallbacksRelative<Type>(obj, method);
|
||||
AnimationCreator animation(Type *obj, typename AnimationCallbacksRelative<Type>::Method method) {
|
||||
return AnimationCreator(new AnimationCallbacksRelative<Type>(obj, method));
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
class AnimationCallbacksAbsolute : public AnimationCallbacks {
|
||||
class AnimationCallbacksAbsolute : public AnimationImplementation {
|
||||
public:
|
||||
typedef void (Type::*Method)(uint64, bool);
|
||||
|
||||
@ -289,12 +301,12 @@ private:
|
||||
|
||||
};
|
||||
template <typename Type>
|
||||
AnimationCallbacks *animation(Type *obj, typename AnimationCallbacksAbsolute<Type>::Method method) {
|
||||
return new AnimationCallbacksAbsolute<Type>(obj, method);
|
||||
AnimationCreator animation(Type *obj, typename AnimationCallbacksAbsolute<Type>::Method method) {
|
||||
return AnimationCreator(new AnimationCallbacksAbsolute<Type>(obj, method));
|
||||
}
|
||||
|
||||
template <typename Type, typename Param>
|
||||
class AnimationCallbacksRelativeWithParam : public AnimationCallbacks {
|
||||
class AnimationCallbacksRelativeWithParam : public AnimationImplementation {
|
||||
public:
|
||||
typedef void (Type::*Method)(Param, float64, bool);
|
||||
|
||||
@ -317,12 +329,12 @@ private:
|
||||
|
||||
};
|
||||
template <typename Type, typename Param>
|
||||
AnimationCallbacks *animation(Param param, Type *obj, typename AnimationCallbacksRelativeWithParam<Type, Param>::Method method) {
|
||||
return new AnimationCallbacksRelativeWithParam<Type, Param>(param, obj, method);
|
||||
AnimationCreator animation(Param param, Type *obj, typename AnimationCallbacksRelativeWithParam<Type, Param>::Method method) {
|
||||
return AnimationCreator(new AnimationCallbacksRelativeWithParam<Type, Param>(param, obj, method));
|
||||
}
|
||||
|
||||
template <typename Type, typename Param>
|
||||
class AnimationCallbacksAbsoluteWithParam : public AnimationCallbacks {
|
||||
class AnimationCallbacksAbsoluteWithParam : public AnimationImplementation {
|
||||
public:
|
||||
typedef void (Type::*Method)(Param, uint64, bool);
|
||||
|
||||
@ -340,15 +352,15 @@ private:
|
||||
|
||||
};
|
||||
template <typename Type, typename Param>
|
||||
AnimationCallbacks *animation(Param param, Type *obj, typename AnimationCallbacksAbsoluteWithParam<Type, Param>::Method method) {
|
||||
return new AnimationCallbacksAbsoluteWithParam<Type, Param>(param, obj, method);
|
||||
AnimationCreator animation(Param param, Type *obj, typename AnimationCallbacksAbsoluteWithParam<Type, Param>::Method method) {
|
||||
return AnimationCreator(new AnimationCallbacksAbsoluteWithParam<Type, Param>(param, obj, method));
|
||||
}
|
||||
|
||||
template <typename AnimType>
|
||||
class SimpleAnimation {
|
||||
public:
|
||||
|
||||
typedef Function<void> Callbacks;
|
||||
typedef Function<void> Callback;
|
||||
|
||||
SimpleAnimation() : _data(0) {
|
||||
}
|
||||
@ -373,11 +385,10 @@ public:
|
||||
return animating(ms) ? current() : def;
|
||||
}
|
||||
|
||||
void setup(const typename AnimType::Type &from, Callbacks *update) {
|
||||
void setup(const typename AnimType::Type &from, Callback::Creator update) {
|
||||
if (!_data) {
|
||||
_data = new Data(from, update, animation(this, &SimpleAnimation<AnimType>::step));
|
||||
} else {
|
||||
delete update;
|
||||
_data->a = AnimType(from, from);
|
||||
}
|
||||
}
|
||||
@ -392,26 +403,21 @@ public:
|
||||
}
|
||||
|
||||
~SimpleAnimation() {
|
||||
delete _data;
|
||||
setBadPointer(_data);
|
||||
deleteAndMark(_data);
|
||||
}
|
||||
|
||||
private:
|
||||
typedef struct _Data {
|
||||
_Data(const typename AnimType::Type &from, Callbacks *update, AnimationCallbacks *acb)
|
||||
_Data(const typename AnimType::Type &from, Callback::Creator update, AnimationCreator acb)
|
||||
: a(from, from)
|
||||
, _a(acb)
|
||||
, update(update)
|
||||
, duration(0)
|
||||
, transition(anim::linear) {
|
||||
}
|
||||
~_Data() {
|
||||
delete update;
|
||||
setBadPointer(update);
|
||||
}
|
||||
AnimType a;
|
||||
Animation _a;
|
||||
Callbacks *update;
|
||||
Callback update;
|
||||
float64 duration;
|
||||
anim::transition transition;
|
||||
} Data;
|
||||
@ -426,7 +432,7 @@ private:
|
||||
_data->a.update(dt, _data->transition);
|
||||
}
|
||||
if (timer) {
|
||||
_data->update->call();
|
||||
_data->update.call();
|
||||
}
|
||||
if (!_data->_a.animating()) {
|
||||
delete _data;
|
||||
@ -456,8 +462,7 @@ public:
|
||||
public slots:
|
||||
void timeout();
|
||||
|
||||
void clipReinit(ClipReader *reader, qint32 threadIndex);
|
||||
void clipRepaint(ClipReader *reader, qint32 threadIndex);
|
||||
void clipCallback(ClipReader *reader, qint32 threadIndex, qint32 notification);
|
||||
|
||||
private:
|
||||
typedef QMap<Animation*, NullType> AnimatingObjects;
|
||||
@ -519,7 +524,7 @@ public:
|
||||
|
||||
typedef Function1<void, ClipReaderNotification> Callback;
|
||||
|
||||
ClipReader(const FileLocation &location, const QByteArray &data, Callback *cb = 0);
|
||||
ClipReader(const FileLocation &location, const QByteArray &data, Callback::Creator cb);
|
||||
static void callback(ClipReader *reader, int32 threadIndex, ClipReaderNotification notification); // reader can be deleted
|
||||
|
||||
void setAutoplay() {
|
||||
@ -560,7 +565,7 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
Callback *_cb;
|
||||
Callback _cb;
|
||||
|
||||
ClipState _state;
|
||||
|
||||
@ -612,8 +617,7 @@ signals:
|
||||
|
||||
void processDelayed();
|
||||
|
||||
void reinit(ClipReader *reader, qint32 threadIndex);
|
||||
void repaint(ClipReader *reader, qint32 threadIndex);
|
||||
void callback(ClipReader *reader, qint32 threadIndex, qint32 notification);
|
||||
|
||||
public slots:
|
||||
|
||||
|
@ -252,10 +252,43 @@ EmojiPtr FlatTextarea::getSingleEmoji() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FlatTextarea::getMentionHashtagBotCommandStart(QString &start) const {
|
||||
void FlatTextarea::getMentionHashtagBotCommandStart(QString &start, UserData *&contextBot, QString &lookedUpUsername) const {
|
||||
int32 pos = textCursor().position();
|
||||
if (textCursor().anchor() != pos) return;
|
||||
|
||||
// check context bot query
|
||||
const QString &text(getLastText());
|
||||
int32 size = text.size();
|
||||
if (size > 2 && text.at(0) == '@' && text.at(1).isLetter()) {
|
||||
int32 usernameStart = 1, usernameLength = 1;
|
||||
for (int32 i = usernameStart + 1, l = text.size(); i < l; ++i) {
|
||||
if (text.at(i).isLetterOrNumber() || text.at(i).unicode() == '_') {
|
||||
++usernameLength;
|
||||
continue;
|
||||
}
|
||||
if (!text.at(i).isSpace()) {
|
||||
usernameLength = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (usernameLength) {
|
||||
UserData *bot = 0;
|
||||
if (contextBot && !contextBot->username.compare(text.midRef(1, usernameLength))) {
|
||||
bot = contextBot;
|
||||
} else {
|
||||
PeerData *peer = App::peerByName(text.midRef(1, usernameLength));
|
||||
if (peer) {
|
||||
if (peer->isUser()) {
|
||||
bot = peer->asUser();
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check mention / hashtag / bot command
|
||||
QTextDocument *doc(document());
|
||||
QTextBlock block = doc->findBlock(pos);
|
||||
for (QTextBlock::Iterator iter = block.begin(); !iter.atEnd(); ++iter) {
|
||||
|
@ -24,6 +24,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||
#include "style.h"
|
||||
#include "animation.h"
|
||||
|
||||
class UserData;
|
||||
class FlatTextarea : public QTextEdit {
|
||||
Q_OBJECT
|
||||
T_WIDGET
|
||||
@ -62,7 +63,7 @@ public:
|
||||
QSize minimumSizeHint() const;
|
||||
|
||||
EmojiPtr getSingleEmoji() const;
|
||||
void getMentionHashtagBotCommandStart(QString &start) const;
|
||||
void getMentionHashtagBotCommandStart(QString &start, UserData *&contextBot, QString &lookedUpUsername) const;
|
||||
void removeSingleEmoji();
|
||||
bool hasText() const;
|
||||
|
||||
|
@ -2966,6 +2966,42 @@ void HistoryItem::setId(MsgId newId) {
|
||||
id = newId;
|
||||
}
|
||||
|
||||
void HistoryItem::clipCallback(ClipReaderNotification notification) {
|
||||
HistoryMedia *media = getMedia();
|
||||
if (!media) return;
|
||||
|
||||
ClipReader *reader = media ? media->getClipReader() : 0;
|
||||
if (!reader) return;
|
||||
|
||||
switch (notification) {
|
||||
case ClipReaderReinit: {
|
||||
bool stopped = false;
|
||||
if (reader->paused()) {
|
||||
if (MainWidget *m = App::main()) {
|
||||
if (!m->isItemVisible(this)) { // stop animation if it is not visible
|
||||
media->stopInline(this);
|
||||
if (DocumentData *document = media->getDocument()) { // forget data from memory
|
||||
document->forget();
|
||||
}
|
||||
stopped = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!stopped) {
|
||||
initDimensions();
|
||||
Notify::historyItemResized(this);
|
||||
Notify::historyItemLayoutChanged(this);
|
||||
}
|
||||
} break;
|
||||
|
||||
case ClipReaderRepaint: {
|
||||
if (!reader->currentDisplayed()) {
|
||||
Ui::repaintHistoryItem(this);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
HistoryItem::~HistoryItem() {
|
||||
App::historyUnregItem(this);
|
||||
if (id < 0 && App::uploader()) {
|
||||
@ -2981,14 +3017,14 @@ HistoryItem *regItem(HistoryItem *item) {
|
||||
return item;
|
||||
}
|
||||
|
||||
RadialAnimation::RadialAnimation(AnimationCallbacks *callbacks)
|
||||
RadialAnimation::RadialAnimation(AnimationCreator creator)
|
||||
: _firstStart(0)
|
||||
, _lastStart(0)
|
||||
, _lastTime(0)
|
||||
, _opacity(0)
|
||||
, a_arcEnd(0, 0)
|
||||
, a_arcStart(0, FullArcLength)
|
||||
, _animation(callbacks) {
|
||||
, _animation(creator) {
|
||||
|
||||
}
|
||||
|
||||
@ -3171,10 +3207,7 @@ void HistoryFileMedia::checkAnimationFinished() {
|
||||
}
|
||||
|
||||
HistoryFileMedia::~HistoryFileMedia() {
|
||||
if (_animation) {
|
||||
delete _animation;
|
||||
setBadPointer(_animation);
|
||||
}
|
||||
deleteAndMark(_animation);
|
||||
}
|
||||
|
||||
HistoryPhoto::HistoryPhoto(const MTPDphoto &photo, const QString &caption, HistoryItem *parent) : HistoryFileMedia()
|
||||
@ -4713,7 +4746,7 @@ bool HistoryGif::playInline(HistoryItem *parent) {
|
||||
if (!cAutoPlayGif()) {
|
||||
App::stopGifItems();
|
||||
}
|
||||
_gif = new ClipReader(_data->location(), _data->data());
|
||||
_gif = new ClipReader(_data->location(), _data->data(), func(parent, &HistoryItem::clipCallback));
|
||||
App::regGifItem(_gif, parent);
|
||||
}
|
||||
return true;
|
||||
@ -4734,8 +4767,7 @@ void HistoryGif::stopInline(HistoryItem *parent) {
|
||||
HistoryGif::~HistoryGif() {
|
||||
if (gif()) {
|
||||
App::unregGifItem(_gif);
|
||||
delete _gif;
|
||||
setBadPointer(_gif);
|
||||
deleteAndMark(_gif);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5518,8 +5550,7 @@ ImagePtr HistoryWebPage::replyPreview() {
|
||||
}
|
||||
|
||||
HistoryWebPage::~HistoryWebPage() {
|
||||
delete _attach;
|
||||
setBadPointer(_attach);
|
||||
deleteAndMark(_attach);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@ -1022,6 +1022,8 @@ public:
|
||||
return !out() && !history()->peer->isUser() && !fromChannel();
|
||||
}
|
||||
|
||||
void clipCallback(ClipReaderNotification notification);
|
||||
|
||||
virtual ~HistoryItem();
|
||||
|
||||
protected:
|
||||
@ -1072,7 +1074,7 @@ HistoryItem *regItem(HistoryItem *item);
|
||||
class RadialAnimation {
|
||||
public:
|
||||
|
||||
RadialAnimation(AnimationCallbacks *callbacks);
|
||||
RadialAnimation(AnimationCreator creator);
|
||||
|
||||
float64 opacity() const {
|
||||
return _opacity;
|
||||
@ -1141,6 +1143,9 @@ public:
|
||||
virtual DocumentData *getDocument() {
|
||||
return 0;
|
||||
}
|
||||
virtual ClipReader *getClipReader() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual bool playInline(HistoryItem *item) {
|
||||
return false;
|
||||
@ -1246,7 +1251,7 @@ protected:
|
||||
virtual bool dataLoaded() const = 0;
|
||||
|
||||
struct AnimationData {
|
||||
AnimationData(AnimationCallbacks *thumbOverCallbacks, AnimationCallbacks *radialCallbacks) : a_thumbOver(0, 0)
|
||||
AnimationData(AnimationCreator thumbOverCallbacks, AnimationCreator radialCallbacks) : a_thumbOver(0, 0)
|
||||
, _a_thumbOver(thumbOverCallbacks)
|
||||
, radial(radialCallbacks) {
|
||||
}
|
||||
@ -1589,6 +1594,9 @@ public:
|
||||
DocumentData *getDocument() {
|
||||
return _data;
|
||||
}
|
||||
ClipReader *getClipReader() {
|
||||
return gif();
|
||||
}
|
||||
|
||||
bool playInline(HistoryItem *item);
|
||||
void stopInline(HistoryItem *item);
|
||||
|
@ -5288,7 +5288,7 @@ void HistoryWidget::checkMentionDropdown() {
|
||||
if (!_history || _a_show.animating()) return;
|
||||
|
||||
QString start;
|
||||
_field.getMentionHashtagBotCommandStart(start);
|
||||
_field.getMentionHashtagBotCommandStart(start, _contextBot, _contextBotUsername);
|
||||
if (!start.isEmpty()) {
|
||||
if (start.at(0) == '#' && cRecentWriteHashtags().isEmpty() && cRecentSearchHashtags().isEmpty()) Local::readRecentHashtags();
|
||||
if (start.at(0) == '@' && _peer->isUser()) return;
|
||||
|
@ -761,6 +761,8 @@ private:
|
||||
CollapseButton _collapseComments;
|
||||
|
||||
MentionsDropdown _attachMention;
|
||||
UserData *_contextBot;
|
||||
QString _contextBotUsername;
|
||||
|
||||
bool isBotStart() const;
|
||||
bool isBlocked() const;
|
||||
|
@ -338,7 +338,11 @@ void StickerPreviewWidget::clipCallback(ClipReaderNotification notification) {
|
||||
update();
|
||||
} break;
|
||||
|
||||
case ClipReaderRepaint: update(); break;
|
||||
case ClipReaderRepaint: {
|
||||
if (gif() && !_gif->currentDisplayed()) {
|
||||
update();
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -260,10 +260,7 @@ void LayoutRadialProgressItem::checkRadialFinished() {
|
||||
}
|
||||
|
||||
LayoutRadialProgressItem::~LayoutRadialProgressItem() {
|
||||
if (_radial) {
|
||||
delete _radial;
|
||||
setBadPointer(_radial);
|
||||
}
|
||||
deleteAndMark(_radial);
|
||||
}
|
||||
|
||||
void LayoutAbstractFileItem::setStatusSize(int32 newSize, int32 fullSize, int32 duration, qint64 realDuration) const {
|
||||
@ -1318,7 +1315,7 @@ void LayoutSavedGif::notify_over(bool over) {
|
||||
if (!_data->loaded()) {
|
||||
ensureAnimation();
|
||||
if (over == !(_state & StateOver)) {
|
||||
EnsureAnimation(_animation->_a_over, (_state & StateOver) ? 1 : 0, (func(this, &LayoutSavedGif::update)));
|
||||
EnsureAnimation(_animation->_a_over, (_state & StateOver) ? 1 : 0, func(this, &LayoutSavedGif::update));
|
||||
_animation->_a_over.start(over ? 1 : 0, st::stickersRowDuration);
|
||||
}
|
||||
}
|
||||
@ -1450,8 +1447,7 @@ void LayoutSavedGif::preload() {
|
||||
}
|
||||
|
||||
LayoutSavedGif::~LayoutSavedGif() {
|
||||
delete _animation;
|
||||
setBadPointer(_animation);
|
||||
deleteAndMark(_animation);
|
||||
}
|
||||
|
||||
void LayoutSavedGif::ensureAnimation() const {
|
||||
@ -1501,7 +1497,11 @@ void LayoutSavedGif::clipCallback(ClipReaderNotification notification) {
|
||||
update();
|
||||
} break;
|
||||
|
||||
case ClipReaderRepaint: update(); break;
|
||||
case ClipReaderRepaint: {
|
||||
if (gif() && !_gif->currentDisplayed()) {
|
||||
update();
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -517,9 +517,9 @@ private:
|
||||
void update();
|
||||
|
||||
struct AnimationData {
|
||||
AnimationData(AnimationCallbacks *radialCallbacks)
|
||||
AnimationData(AnimationCreator creator)
|
||||
: over(false)
|
||||
, radial(radialCallbacks) {
|
||||
, radial(creator) {
|
||||
}
|
||||
bool over;
|
||||
FloatAnimation _a_over;
|
||||
|
@ -2454,8 +2454,7 @@ namespace Local {
|
||||
virtual void readFromStream(QDataStream &stream, quint64 &first, quint64 &second, quint32 &type, QByteArray &data) = 0;
|
||||
virtual void clearInMap() = 0;
|
||||
virtual ~AbstractCachedLoadTask() {
|
||||
delete _result;
|
||||
setBadPointer(_result);
|
||||
deleteAndMark(_result);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -474,10 +474,8 @@ void MediaView::step_radial(uint64 ms, bool timer) {
|
||||
}
|
||||
|
||||
MediaView::~MediaView() {
|
||||
delete _gif;
|
||||
setBadPointer(_gif);
|
||||
delete _menu;
|
||||
setBadPointer(_menu);
|
||||
deleteAndMark(_gif);
|
||||
deleteAndMark(_menu);
|
||||
}
|
||||
|
||||
void MediaView::showSaveMsgFile() {
|
||||
@ -603,14 +601,11 @@ void MediaView::onDocClick() {
|
||||
}
|
||||
}
|
||||
|
||||
void MediaView::ui_clipRepaint(ClipReader *reader) {
|
||||
if (reader == _gif) {
|
||||
update(_x, _y, _w, _h);
|
||||
}
|
||||
}
|
||||
void MediaView::clipCallback(ClipReaderNotification notification) {
|
||||
if (!_gif) return;
|
||||
|
||||
void MediaView::notify_clipReinit(ClipReader *reader) {
|
||||
if (reader == _gif) {
|
||||
switch (notification) {
|
||||
case ClipReaderReinit: {
|
||||
if (HistoryItem *item = App::histItemById(_msgmigrated ? 0 : _channel, _msgid)) {
|
||||
if (_gif->state() == ClipError) {
|
||||
_current = QPixmap();
|
||||
@ -619,6 +614,13 @@ void MediaView::notify_clipReinit(ClipReader *reader) {
|
||||
} else {
|
||||
stopGif();
|
||||
}
|
||||
} break;
|
||||
|
||||
case ClipReaderRepaint: {
|
||||
if (!_gif->currentDisplayed()) {
|
||||
update(_x, _y, _w, _h);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -953,7 +955,7 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty
|
||||
if (_doc->dimensions.width() && _doc->dimensions.height()) {
|
||||
_current = _doc->thumb->pixNoCache(_doc->dimensions.width(), _doc->dimensions.height(), true, true, false, _doc->dimensions.width(), _doc->dimensions.height());
|
||||
}
|
||||
_gif = new ClipReader(location, _doc->data());
|
||||
_gif = new ClipReader(location, _doc->data(), func(this, &MediaView::clipCallback));
|
||||
}
|
||||
} else if (location.accessEnable()) {
|
||||
if (_doc->isAnimation()) {
|
||||
@ -961,7 +963,7 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty
|
||||
if (_doc->dimensions.width() && _doc->dimensions.height()) {
|
||||
_current = _doc->thumb->pixNoCache(_doc->dimensions.width(), _doc->dimensions.height(), true, true, false, _doc->dimensions.width(), _doc->dimensions.height());
|
||||
}
|
||||
_gif = new ClipReader(location, _doc->data());
|
||||
_gif = new ClipReader(location, _doc->data(), func(this, &MediaView::clipCallback));
|
||||
}
|
||||
} else {
|
||||
if (QImageReader(location.name()).canRead()) {
|
||||
|
@ -71,9 +71,7 @@ public:
|
||||
void activateControls();
|
||||
void onDocClick();
|
||||
|
||||
void ui_clipRepaint(ClipReader *reader);
|
||||
|
||||
void notify_clipReinit(ClipReader *reader);
|
||||
void clipCallback(ClipReaderNotification notification);
|
||||
|
||||
~MediaView();
|
||||
|
||||
|
@ -661,8 +661,7 @@ ImagePtr PhotoData::makeReplyPreview() {
|
||||
}
|
||||
|
||||
PhotoData::~PhotoData() {
|
||||
delete uploadingData;
|
||||
setBadPointer(uploadingData);
|
||||
deleteAndMark(uploadingData);
|
||||
}
|
||||
|
||||
void PhotoLink::onClick(Qt::MouseButton button) const {
|
||||
|
@ -20,14 +20,32 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
template <typename Type>
|
||||
void setBadPointer(Type *&link) {
|
||||
link = reinterpret_cast<Type*>(0x00000bad);
|
||||
template <typename T>
|
||||
void deleteAndMark(T *&link) {
|
||||
delete link;
|
||||
link = reinterpret_cast<T*>(0x00000BAD);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *exchange(T *&ptr) {
|
||||
T *result = 0;
|
||||
qSwap(result, ptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
struct NullType {
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class OrderedSet : public QMap<T, NullType> {
|
||||
public:
|
||||
|
||||
void insert(const T &v) {
|
||||
QMap<T, NullType>::insert(v, NullType());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//typedef unsigned char uchar; // Qt has uchar
|
||||
typedef qint16 int16;
|
||||
typedef quint16 uint16;
|
||||
@ -473,68 +491,219 @@ static int32 QuarterArcLength = (FullArcLength / 4);
|
||||
static int32 MinArcLength = (FullArcLength / 360);
|
||||
static int32 AlmostFullArcLength = (FullArcLength - MinArcLength);
|
||||
|
||||
template <typename ReturnType>
|
||||
template <typename I>
|
||||
inline void destroyImplementation(I *&ptr) {
|
||||
if (ptr) {
|
||||
ptr->destroy();
|
||||
ptr = 0;
|
||||
}
|
||||
deleteAndMark(ptr);
|
||||
}
|
||||
|
||||
template <typename R>
|
||||
class FunctionImplementation {
|
||||
public:
|
||||
virtual R call() = 0;
|
||||
virtual void destroy() { delete this; }
|
||||
virtual ~FunctionImplementation() {}
|
||||
};
|
||||
template <typename R>
|
||||
class NullFunctionImplementation : public FunctionImplementation<R> {
|
||||
public:
|
||||
virtual R call() { return R(); }
|
||||
virtual void destroy() {}
|
||||
static NullFunctionImplementation<R> SharedInstance;
|
||||
};
|
||||
template <typename R>
|
||||
NullFunctionImplementation<R> NullFunctionImplementation<R>::SharedInstance;
|
||||
template <typename R>
|
||||
class FunctionCreator {
|
||||
public:
|
||||
FunctionCreator(FunctionImplementation<R> *ptr) : _ptr(ptr) {}
|
||||
FunctionCreator(const FunctionCreator<R> &other) : _ptr(other.create()) {}
|
||||
FunctionImplementation<R> *create() const { return exchange(_ptr); }
|
||||
~FunctionCreator() { destroyImplementation(_ptr); }
|
||||
private:
|
||||
FunctionCreator<R> &operator=(const FunctionCreator<R> &other);
|
||||
mutable FunctionImplementation<R> *_ptr;
|
||||
};
|
||||
template <typename R>
|
||||
class Function {
|
||||
public:
|
||||
|
||||
virtual ReturnType call() = 0;
|
||||
virtual ~Function() {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename Object, typename ReturnType>
|
||||
class ObjectFunction : public Function<ReturnType> {
|
||||
public:
|
||||
typedef ReturnType (Object::*Method)();
|
||||
|
||||
ObjectFunction(Object *obj, Method method) : _obj(obj), _method(method) {
|
||||
}
|
||||
|
||||
virtual ReturnType call() {
|
||||
return (_obj->*_method)();
|
||||
}
|
||||
|
||||
typedef FunctionCreator<R> Creator;
|
||||
static Creator Null() { return Creator(&NullFunctionImplementation<R>::SharedInstance); }
|
||||
Function(const Creator &creator) : _implementation(creator.create()) {}
|
||||
R call() { return _implementation->call(); }
|
||||
~Function() { destroyImplementation(_implementation); }
|
||||
private:
|
||||
Object *_obj;
|
||||
Method _method;
|
||||
|
||||
Function(const Function<R> &other);
|
||||
Function<R> &operator=(const Function<R> &other);
|
||||
FunctionImplementation<R> *_implementation;
|
||||
};
|
||||
|
||||
template <typename Object, typename ReturnType>
|
||||
Function<ReturnType> *func(Object *obj, ReturnType (Object::*method)()) {
|
||||
return new ObjectFunction<Object, ReturnType>(obj, method);
|
||||
template <typename R>
|
||||
class WrappedFunction : public FunctionImplementation<R> {
|
||||
public:
|
||||
typedef R(*Method)();
|
||||
WrappedFunction(Method method) : _method(method) {}
|
||||
virtual R call() { return (*_method)(); }
|
||||
private:
|
||||
Method _method;
|
||||
};
|
||||
template <typename R>
|
||||
inline FunctionCreator<R> func(R(*method)()) {
|
||||
return FunctionCreator<R>(new WrappedFunction<R>(method));
|
||||
}
|
||||
template <typename O, typename R>
|
||||
class ObjectFunction : public FunctionImplementation<R> {
|
||||
public:
|
||||
typedef R(O::*Method)();
|
||||
ObjectFunction(O *obj, Method method) : _obj(obj), _method(method) {}
|
||||
virtual R call() { return (_obj->*_method)(); }
|
||||
private:
|
||||
O *_obj;
|
||||
Method _method;
|
||||
};
|
||||
template <typename O, typename R>
|
||||
inline FunctionCreator<R> func(O *obj, R(O::*method)()) {
|
||||
return FunctionCreator<R>(new ObjectFunction<O, R>(obj, method));
|
||||
}
|
||||
|
||||
template <typename ReturnType, typename ArgumentType1>
|
||||
template <typename R, typename A1>
|
||||
class Function1Implementation {
|
||||
public:
|
||||
virtual R call(A1 a1) = 0;
|
||||
virtual void destroy() { delete this; }
|
||||
virtual ~Function1Implementation() {}
|
||||
};
|
||||
template <typename R, typename A1>
|
||||
class NullFunction1Implementation : public Function1Implementation<R, A1> {
|
||||
public:
|
||||
virtual R call(A1 a1) { return R(); }
|
||||
virtual void destroy() {}
|
||||
static NullFunction1Implementation<R, A1> SharedInstance;
|
||||
};
|
||||
template <typename R, typename A1>
|
||||
NullFunction1Implementation<R, A1> NullFunction1Implementation<R, A1>::SharedInstance;
|
||||
template <typename R, typename A1>
|
||||
class Function1Creator {
|
||||
public:
|
||||
Function1Creator(Function1Implementation<R, A1> *ptr) : _ptr(ptr) {}
|
||||
Function1Creator(const Function1Creator<R, A1> &other) : _ptr(other.create()) {}
|
||||
Function1Implementation<R, A1> *create() const { return exchange(_ptr); }
|
||||
~Function1Creator() { destroyImplementation(_ptr); }
|
||||
private:
|
||||
Function1Creator<R, A1> &operator=(const Function1Creator<R, A1> &other);
|
||||
mutable Function1Implementation<R, A1> *_ptr;
|
||||
};
|
||||
template <typename R, typename A1>
|
||||
class Function1 {
|
||||
public:
|
||||
|
||||
virtual ReturnType call(ArgumentType1 arg1) = 0;
|
||||
virtual ~Function1() {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename Object, typename ReturnType, typename ArgumentType1>
|
||||
class ObjectFunction1 : public Function1<ReturnType, ArgumentType1> {
|
||||
public:
|
||||
typedef ReturnType (Object::*Method)(ArgumentType1);
|
||||
|
||||
ObjectFunction1(Object *obj, Method method) : _obj(obj), _method(method) {
|
||||
}
|
||||
|
||||
virtual ReturnType call(ArgumentType1 arg1) {
|
||||
return (_obj->*_method)(arg1);
|
||||
}
|
||||
|
||||
typedef Function1Creator<R, A1> Creator;
|
||||
static Creator Null() { return Creator(&NullFunction1Implementation<R, A1>::SharedInstance); }
|
||||
Function1(const Creator &creator) : _implementation(creator.create()) {}
|
||||
R call(A1 a1) { return _implementation->call(a1); }
|
||||
~Function1() { _implementation->destroy(); }
|
||||
private:
|
||||
Object *_obj;
|
||||
Method _method;
|
||||
|
||||
Function1(const Function1<R, A1> &other);
|
||||
Function1<R, A1> &operator=(const Function1<R, A1> &other);
|
||||
Function1Implementation<R, A1> *_implementation;
|
||||
};
|
||||
|
||||
template <typename Object, typename ReturnType, typename ArgumentType1>
|
||||
Function1<ReturnType, ArgumentType1> *func(Object *obj, ReturnType (Object::*method)(ArgumentType1)) {
|
||||
return new ObjectFunction1<Object, ReturnType, ArgumentType1>(obj, method);
|
||||
template <typename R, typename A1>
|
||||
class WrappedFunction1 : public Function1Implementation<R, A1> {
|
||||
public:
|
||||
typedef R(*Method)(A1);
|
||||
WrappedFunction1(Method method) : _method(method) {}
|
||||
virtual R call(A1 a1) { return (*_method)(a1); }
|
||||
private:
|
||||
Method _method;
|
||||
};
|
||||
template <typename R, typename A1>
|
||||
inline Function1Creator<R, A1> func(R(*method)(A1)) {
|
||||
return Function1Creator<R, A1>(new WrappedFunction1<R, A1>(method));
|
||||
}
|
||||
template <typename O, typename R, typename A1>
|
||||
class ObjectFunction1 : public Function1Implementation<R, A1> {
|
||||
public:
|
||||
typedef R(O::*Method)(A1);
|
||||
ObjectFunction1(O *obj, Method method) : _obj(obj), _method(method) {}
|
||||
virtual R call(A1 a1) { return (_obj->*_method)(a1); }
|
||||
private:
|
||||
O *_obj;
|
||||
Method _method;
|
||||
};
|
||||
template <typename O, typename R, typename A1>
|
||||
Function1Creator<R, A1> func(O *obj, R(O::*method)(A1)) {
|
||||
return Function1Creator<R, A1>(new ObjectFunction1<O, R, A1>(obj, method));
|
||||
}
|
||||
|
||||
template <typename R, typename A1, typename A2>
|
||||
class Function2Implementation {
|
||||
public:
|
||||
virtual R call(A1 a1, A2 a2) = 0;
|
||||
virtual void destroy() { delete this; }
|
||||
virtual ~Function2Implementation() {}
|
||||
};
|
||||
template <typename R, typename A1, typename A2>
|
||||
class NullFunction2Implementation : public Function2Implementation<R, A1, A2> {
|
||||
public:
|
||||
virtual R call(A1 a1, A2 a2) { return R(); }
|
||||
virtual void destroy() {}
|
||||
static NullFunction2Implementation<R, A1, A2> SharedInstance;
|
||||
};
|
||||
template <typename R, typename A1, typename A2>
|
||||
NullFunction2Implementation<R, A1, A2> NullFunction2Implementation<R, A1, A2>::SharedInstance;
|
||||
template <typename R, typename A1, typename A2>
|
||||
class Function2Creator {
|
||||
public:
|
||||
Function2Creator(Function2Implementation<R, A1, A2> *ptr) : _ptr(ptr) {}
|
||||
Function2Creator(const Function2Creator<R, A1, A2> &other) : _ptr(other.create()) {}
|
||||
Function2Implementation<R, A1, A2> *create() const { return exchange(_ptr); }
|
||||
~Function2Creator() { destroyImplementation(_ptr); }
|
||||
private:
|
||||
Function2Creator<R, A1, A2> &operator=(const Function2Creator<R, A1, A2> &other);
|
||||
mutable Function2Implementation<R, A1, A2> *_ptr;
|
||||
};
|
||||
template <typename R, typename A1, typename A2>
|
||||
class Function2 {
|
||||
public:
|
||||
typedef Function2Creator<R, A1, A2> Creator;
|
||||
static Creator Null() { return Creator(&NullFunction2Implementation<R, A1, A2>::SharedInstance); }
|
||||
Function2(const Creator &creator) : _implementation(creator.create()) {}
|
||||
R call(A1 a1, A2 a2) { return _implementation->call(a1, a2); }
|
||||
~Function2() { destroyImplementation(_implementation); }
|
||||
private:
|
||||
Function2(const Function2<R, A1, A2> &other);
|
||||
Function2<R, A1, A2> &operator=(const Function2<R, A1, A2> &other);
|
||||
Function2Implementation<R, A1, A2> *_implementation;
|
||||
};
|
||||
|
||||
template <typename R, typename A1, typename A2>
|
||||
class WrappedFunction2 : public Function2Implementation<R, A1, A2> {
|
||||
public:
|
||||
typedef R(*Method)(A1, A2);
|
||||
WrappedFunction2(Method method) : _method(method) {}
|
||||
virtual R call(A1 a1, A2 a2) { return (*_method)(a1, a2); }
|
||||
private:
|
||||
Method _method;
|
||||
};
|
||||
template <typename R, typename A1, typename A2>
|
||||
Function2Creator<R, A1, A2> func(R(*method)(A1, A2)) {
|
||||
return Function2Creator<R, A1, A2>(new WrappedFunction2<R, A1, A2>(method));
|
||||
}
|
||||
|
||||
template <typename O, typename R, typename A1, typename A2>
|
||||
class ObjectFunction2 : public Function2Implementation<R, A1, A2> {
|
||||
public:
|
||||
typedef R(O::*Method)(A1, A2);
|
||||
ObjectFunction2(O *obj, Method method) : _obj(obj), _method(method) {}
|
||||
virtual R call(A1 a1, A2 a2) { return (_obj->*_method)(a1, a2); }
|
||||
private:
|
||||
O *_obj;
|
||||
Method _method;
|
||||
};
|
||||
template <typename O, typename R, typename A1, typename A2>
|
||||
Function2Creator<R, A1, A2> func(O *obj, R(O::*method)(A1, A2)) {
|
||||
return Function2Creator<R, A1, A2>(new ObjectFunction2<O, R, A1, A2>(obj, method));
|
||||
}
|
||||
|
@ -795,12 +795,6 @@ void Window::showDocument(DocumentData *doc, HistoryItem *item) {
|
||||
_mediaView->setFocus();
|
||||
}
|
||||
|
||||
void Window::ui_clipRepaint(ClipReader *reader) {
|
||||
if (_mediaView && !_mediaView->isHidden()) {
|
||||
_mediaView->ui_clipRepaint(reader);
|
||||
}
|
||||
}
|
||||
|
||||
void Window::ui_showLayer(LayeredWidget *box, ShowLayerOptions options) {
|
||||
if (box) {
|
||||
bool fast = (options.testFlag(ForceFastShowLayer)) || Ui::isLayerShown();
|
||||
@ -846,12 +840,6 @@ bool Window::ui_isMediaViewShown() {
|
||||
return _mediaView && !_mediaView->isHidden();
|
||||
}
|
||||
|
||||
void Window::notify_clipReinit(ClipReader *reader) {
|
||||
if (_mediaView && !_mediaView->isHidden()) {
|
||||
_mediaView->notify_clipReinit(reader);
|
||||
}
|
||||
}
|
||||
|
||||
void Window::showConnecting(const QString &text, const QString &reconnect) {
|
||||
if (_connecting) {
|
||||
_connecting->set(text, reconnect);
|
||||
|
@ -237,13 +237,10 @@ public:
|
||||
return contentOverlapped(QRect(w->mapToGlobal(r.boundingRect().topLeft()), r.boundingRect().size()));
|
||||
}
|
||||
|
||||
void ui_clipRepaint(ClipReader *reader);
|
||||
void ui_showLayer(LayeredWidget *box, ShowLayerOptions options);
|
||||
bool ui_isLayerShown();
|
||||
bool ui_isMediaViewShown();
|
||||
|
||||
void notify_clipReinit(ClipReader *reader);
|
||||
|
||||
public slots:
|
||||
|
||||
void updateIsActive(int timeout = 0);
|
||||
|
Loading…
Reference in New Issue
Block a user