Remove history_item and layout from pch.

Also move some code to separate modules.
Also create history item views by Window::Controller.
This commit is contained in:
John Preston 2018-01-11 22:33:26 +03:00
parent 4740d44159
commit bee474f6e9
78 changed files with 794 additions and 525 deletions

View file

@ -1617,7 +1617,7 @@ void ApiWrap::resolveWebPages() {
if (i.value() > 0) continue;
if (i.key()->pendingTill <= t) {
auto j = items.constFind(i.key());
if (j != items.cend() && !j.value().isEmpty()) {
if (j != items.cend() && !j.value().empty()) {
for_const (auto item, j.value()) {
if (item->id > 0) {
if (item->channelId() == NoChannel) {

View file

@ -89,7 +89,7 @@ namespace {
using SentData = QMap<uint64, QPair<PeerId, QString>>;
SentData sentData;
HistoryView::Message *hoveredItem = nullptr,
HistoryView::Element *hoveredItem = nullptr,
*pressedItem = nullptr,
*hoveredLinkItem = nullptr,
*pressedLinkItem = nullptr,
@ -1835,7 +1835,7 @@ namespace {
}
}
void messageViewDestroyed(not_null<HistoryView::Message*> view) {
void messageViewDestroyed(not_null<HistoryView::Element*> view) {
if (::hoveredItem == view) {
hoveredItem(nullptr);
}
@ -2182,43 +2182,43 @@ namespace {
clearAllImages();
}
void hoveredItem(HistoryView::Message *item) {
void hoveredItem(HistoryView::Element *item) {
::hoveredItem = item;
}
HistoryView::Message *hoveredItem() {
HistoryView::Element *hoveredItem() {
return ::hoveredItem;
}
void pressedItem(HistoryView::Message *item) {
void pressedItem(HistoryView::Element *item) {
::pressedItem = item;
}
HistoryView::Message *pressedItem() {
HistoryView::Element *pressedItem() {
return ::pressedItem;
}
void hoveredLinkItem(HistoryView::Message *item) {
void hoveredLinkItem(HistoryView::Element *item) {
::hoveredLinkItem = item;
}
HistoryView::Message *hoveredLinkItem() {
HistoryView::Element *hoveredLinkItem() {
return ::hoveredLinkItem;
}
void pressedLinkItem(HistoryView::Message *item) {
void pressedLinkItem(HistoryView::Element *item) {
::pressedLinkItem = item;
}
HistoryView::Message *pressedLinkItem() {
HistoryView::Element *pressedLinkItem() {
return ::pressedLinkItem;
}
void mousedItem(HistoryView::Message *item) {
void mousedItem(HistoryView::Element *item) {
::mousedItem = item;
}
HistoryView::Message *mousedItem() {
HistoryView::Element *mousedItem() {
return ::mousedItem;
}
@ -2484,7 +2484,7 @@ namespace {
QString phoneFromSharedContact(int32 userId) {
auto i = ::sharedContactItems.constFind(userId);
if (i != ::sharedContactItems.cend() && !i->isEmpty()) {
if (i != ::sharedContactItems.cend() && !i->empty()) {
if (auto media = (*i->cbegin())->getMedia()) {
if (media->type() == MediaTypeContact) {
return static_cast<HistoryContact*>(media)->phone();

View file

@ -9,20 +9,19 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/basic_types.h"
#include "history/history.h"
#include "history/history_item.h"
#include "layout.h"
class Messenger;
class MainWindow;
class MainWidget;
class LocationCoords;
struct LocationData;
class HistoryItem;
namespace HistoryView {
class Message;
} // namespace HistoryView
using HistoryItemsMap = OrderedSet<HistoryItem*>;
using HistoryItemsMap = base::flat_set<not_null<HistoryItem*>>;
using PhotoItems = QHash<PhotoData*, HistoryItemsMap>;
using DocumentItems = QHash<DocumentData*, HistoryItemsMap>;
using WebPageItems = QHash<WebPageData*, HistoryItemsMap>;
@ -33,6 +32,42 @@ using GifItems = QHash<Media::Clip::Reader*, HistoryItem*>;
using PhotosData = QHash<PhotoId, PhotoData*>;
using DocumentsData = QHash<DocumentId, DocumentData*>;
enum RoundCorners {
SmallMaskCorners = 0x00, // for images
LargeMaskCorners,
BoxCorners,
MenuCorners,
BotKbOverCorners,
StickerCorners,
StickerSelectedCorners,
SelectedOverlaySmallCorners,
SelectedOverlayLargeCorners,
DateCorners,
DateSelectedCorners,
ForwardCorners,
MediaviewSaveCorners,
EmojiHoverCorners,
StickerHoverCorners,
BotKeyboardCorners,
PhotoSelectOverlayCorners,
Doc1Corners,
Doc2Corners,
Doc3Corners,
Doc4Corners,
InShadowCorners, // for photos without bg
InSelectedShadowCorners,
MessageInCorners, // with shadow
MessageInSelectedCorners,
MessageOutCorners,
MessageOutSelectedCorners,
RoundCornersCount
};
namespace App {
MainWindow *wnd();
MainWidget *main();
@ -199,7 +234,7 @@ namespace App {
void historyClearItems();
void historyRegDependency(HistoryItem *dependent, HistoryItem *dependency);
void historyUnregDependency(HistoryItem *dependent, HistoryItem *dependency);
void messageViewDestroyed(not_null<HistoryView::Message*> view);
void messageViewDestroyed(not_null<HistoryView::Element*> view);
void historyRegRandom(uint64 randomId, const FullMsgId &itemId);
void historyUnregRandom(uint64 randomId);
@ -208,16 +243,16 @@ namespace App {
void historyUnregSentData(uint64 randomId);
void histSentDataByItem(uint64 randomId, PeerId &peerId, QString &text);
void hoveredItem(HistoryView::Message *item);
HistoryView::Message *hoveredItem();
void pressedItem(HistoryView::Message *item);
HistoryView::Message *pressedItem();
void hoveredLinkItem(HistoryView::Message *item);
HistoryView::Message *hoveredLinkItem();
void pressedLinkItem(HistoryView::Message *item);
HistoryView::Message *pressedLinkItem();
void mousedItem(HistoryView::Message *item);
HistoryView::Message *mousedItem();
void hoveredItem(HistoryView::Element *item);
HistoryView::Element *hoveredItem();
void pressedItem(HistoryView::Element *item);
HistoryView::Element *pressedItem();
void hoveredLinkItem(HistoryView::Element *item);
HistoryView::Element *hoveredLinkItem();
void pressedLinkItem(HistoryView::Element *item);
HistoryView::Element *pressedLinkItem();
void mousedItem(HistoryView::Element *item);
HistoryView::Element *mousedItem();
void clearMousedItems();
const style::font &monofont();

View file

@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mainwindow.h"
#include "apiwrap.h"
#include "application.h"
#include "history/history_item.h"
#include "ui/widgets/checkbox.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/labels.h"

View file

@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h"
#include "window/window_controller.h"
#include "mainwidget.h"
#include "layout.h"
#include "styles/style_history.h"
#include "styles/style_boxes.h"

View file

@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h"
#include "mainwindow.h"
#include "auth_session.h"
#include "layout.h"
LocalStorageBox::LocalStorageBox(QWidget *parent)
: _clear(this, lang(lng_local_storage_clear), st::boxLinkButton) {

View file

@ -24,6 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/window_controller.h"
#include "styles/style_history.h"
#include "styles/style_boxes.h"
#include "layout.h"
namespace {

View file

@ -25,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "observer_peer.h"
#include "platform/platform_specific.h"
#include "window/main_window.h"
#include "layout.h"
namespace Calls {
namespace {

View file

@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "observer_peer.h"
#include "boxes/abstract_box.h"
#include "base/timer.h"
#include "layout.h"
namespace Calls {
namespace {

View file

@ -9,14 +9,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/tooltip.h"
namespace style {
struct BotKeyboardButton;
} // namespace style
class ReplyKeyboard;
class BotKeyboard
: public TWidget
, public Ui::AbstractTooltipShower
, public ClickHandlerHost {
Q_OBJECT
public:
BotKeyboard(QWidget *parent);

View file

@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h"
#include "mainwindow.h"
#include "window/window_controller.h"
#include "history/view/history_view_cursor_state.h"
namespace ChatHelpers {
namespace {

View file

@ -17,6 +17,7 @@ class Controller;
namespace Ui {
class LinkButton;
class RippleAnimation;
} // namespace Ui
namespace ChatHelpers {

View file

@ -10,7 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h"
#include "messenger.h"
#include "platform/platform_specific.h"
#include "history/view/history_view_message.h"
#include "history/view/history_view_element.h"
#include "history/history_item.h"
#include "boxes/confirm_box.h"
#include "base/qthelp_regex.h"
#include "base/qthelp_url.h"

View file

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_feed.h"
#include "dialogs/dialogs_key.h"
#include "history/history_item.h"
namespace Data {

View file

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "auth_session.h"
#include "data/data_session.h"
#include "data/data_messages.h"
#include "history/history_item.h"
namespace Api {
namespace {

View file

@ -10,6 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "chat_helpers/stickers.h"
#include "dialogs/dialogs_key.h"
struct HistoryMessageGroup;
namespace Data {
class Feed;

View file

@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "dialogs/dialogs_indexed_list.h"
#include "mainwidget.h"
#include "styles/style_dialogs.h"
#include "history/history_item.h"
namespace Dialogs {
namespace {

View file

@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "dialogs/dialogs_layout.h"
#include "dialogs/dialogs_search_from_controllers.h"
#include "history/feed/history_feed_section.h"
#include "history/history_item.h"
#include "styles/style_dialogs.h"
#include "styles/style_chat_helpers.h"
#include "styles/style_window.h"

View file

@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/empty_userpic.h"
#include "ui/text_options.h"
#include "lang/lang_keys.h"
#include "history/history_item.h"
namespace Dialogs {
namespace Layout {

View file

@ -22,13 +22,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/layer_widget.h"
#include "lang/lang_keys.h"
#include "base/observer.h"
#include "history/history_item.h"
#include "history/history_media.h"
#include "styles/style_history.h"
#include "data/data_session.h"
Q_DECLARE_METATYPE(ClickHandlerPtr);
Q_DECLARE_METATYPE(Qt::MouseButton);
namespace App {
namespace internal {
@ -175,11 +173,9 @@ void showSettings() {
}
void activateClickHandler(ClickHandlerPtr handler, Qt::MouseButton button) {
if (auto w = wnd()) {
qRegisterMetaType<ClickHandlerPtr>();
qRegisterMetaType<Qt::MouseButton>();
QMetaObject::invokeMethod(w, "app_activateClickHandler", Qt::QueuedConnection, Q_ARG(ClickHandlerPtr, handler), Q_ARG(Qt::MouseButton, button));
}
crl::on_main(wnd(), [handler, button] {
handler->onClick(button);
});
}
void logOutDelayed() {
@ -266,14 +262,16 @@ void showPeerHistory(
const PeerId &peer,
MsgId msgId) {
auto ms = getms();
LOG(("Show Peer Start"));
if (auto m = App::main()) {
m->ui_showPeerHistory(
peer,
Window::SectionShow::Way::ClearStack,
msgId);
}
LOG(("Show Peer End: %1").arg(getms() - ms));
}
void showPeerHistoryAtItem(not_null<const HistoryItem*> item) {
showPeerHistory(item->history()->peer->id, item->id);
}
PeerData *getPeerForMouseAction() {

View file

@ -189,6 +189,7 @@ inline void showPeerProfile(const History *history) {
}
void showPeerHistory(const PeerId &peer, MsgId msgId);
void showPeerHistoryAtItem(not_null<const HistoryItem*> item);
inline void showPeerHistory(const PeerData *peer, MsgId msgId) {
showPeerHistory(peer->id, msgId);
@ -198,9 +199,6 @@ inline void showPeerHistory(
MsgId msgId) {
showPeerHistory(history->peer->id, msgId);
}
inline void showPeerHistoryAtItem(const HistoryItem *item) {
showPeerHistory(item->history()->peer->id, item->id);
}
inline void showChatsList() {
showPeerHistory(PeerId(0), 0);
}

View file

@ -14,12 +14,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/admin_log/history_admin_log_section.h"
#include "history/admin_log/history_admin_log_filter.h"
#include "history/view/history_view_service_message.h"
#include "history/view/history_view_message.h"
#include "history/view/history_view_element.h"
#include "chat_helpers/message_field.h"
#include "mainwindow.h"
#include "mainwidget.h"
#include "messenger.h"
#include "apiwrap.h"
#include "layout.h"
#include "window/window_controller.h"
#include "auth_session.h"
#include "ui/widgets/popup_menu.h"
@ -115,7 +116,7 @@ void InnerWidget::enumerateUserpics(Method method) {
// -1 means we didn't find an attached to next message yet.
int lowestAttachedItemTop = -1;
auto userpicCallback = [&](not_null<Message*> view, int itemtop, int itembottom) {
auto userpicCallback = [&](not_null<Element*> view, int itemtop, int itembottom) {
// Skip all service messages.
const auto message = view->data()->toHistoryMessage();
if (!message) return true;
@ -161,7 +162,7 @@ void InnerWidget::enumerateDates(Method method) {
// -1 means we didn't find a same-day with previous message yet.
auto lowestInOneDayItemBottom = -1;
auto dateCallback = [&](not_null<Message*> view, int itemtop, int itembottom) {
auto dateCallback = [&](not_null<Element*> view, int itemtop, int itembottom) {
const auto item = view->data();
if (lowestInOneDayItemBottom < 0 && item->isInOneDayWithPrevious()) {
lowestInOneDayItemBottom = itembottom - item->marginBottom();
@ -527,18 +528,25 @@ void InnerWidget::addEvents(Direction direction, const QVector<MTPChannelAdminLo
addToItems.reserve(oldItemsCount + events.size() * 2);
for_const (auto &event, events) {
Assert(event.type() == mtpc_channelAdminLogEvent);
auto &data = event.c_channelAdminLogEvent();
if (_itemsByIds.find(data.vid.v) != _itemsByIds.cend()) {
const auto &data = event.c_channelAdminLogEvent();
const auto id = data.vid.v;
if (_itemsByIds.find(id) != _itemsByIds.cend()) {
continue;
}
auto count = 0;
GenerateItems(_history, _idManager, data, [this, id = data.vid.v, &addToItems, &count](OwnedItem item) {
const auto addOne = [&](OwnedItem item) {
_itemsByIds.emplace(id, item.get());
_itemsByData.emplace(item->data(), item.get());
addToItems.push_back(std::move(item));
++count;
});
};
GenerateItems(
_controller,
_history,
_idManager,
data,
addOne);
if (count > 1) {
// Reverse the inner order of the added messages, because we load events
// from bottom to top but inside one event they go from top to bottom.
@ -659,7 +667,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
}
p.translate(0, -top);
enumerateUserpics([&](not_null<Message*> view, int userpicTop) {
enumerateUserpics([&](not_null<Element*> view, int userpicTop) {
// stop the enumeration if the userpic is below the painted rect
if (userpicTop >= clip.top() + clip.height()) {
return false;
@ -677,7 +685,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
auto dateHeight = st::msgServicePadding.bottom() + st::msgServiceFont->height + st::msgServicePadding.top();
auto scrollDateOpacity = _scrollDateOpacity.current(ms, _scrollDateShown ? 1. : 0.);
enumerateDates([&](not_null<Message*> view, int itemtop, int dateTop) {
enumerateDates([&](not_null<Element*> view, int itemtop, int dateTop) {
// stop the enumeration if the date is above the painted rect
if (dateTop + dateHeight <= clip.top()) {
return false;
@ -737,7 +745,7 @@ void InnerWidget::clearAfterFilterChange() {
updateSize();
}
auto InnerWidget::viewForItem(const HistoryItem *item) -> Message* {
auto InnerWidget::viewForItem(const HistoryItem *item) -> Element* {
if (item) {
const auto i = _itemsByData.find(item);
if (i != _itemsByData.end()) {
@ -1359,7 +1367,7 @@ void InnerWidget::updateSelected() {
if (!dragState.link && itemPoint.x() >= st::historyPhotoLeft && itemPoint.x() < st::historyPhotoLeft + st::msgPhotoSize) {
if (auto message = item->toHistoryMessage()) {
if (message->hasFromPhoto()) {
enumerateUserpics([&](not_null<Message*> view, int userpicTop) {
enumerateUserpics([&](not_null<Element*> view, int userpicTop) {
// stop enumeration if the userpic is below our point
if (userpicTop > point.y()) {
return false;
@ -1541,18 +1549,18 @@ void InnerWidget::performDrag() {
//} // TODO
}
int InnerWidget::itemTop(not_null<const Message*> item) const {
return _itemsTop + item->y();
int InnerWidget::itemTop(not_null<const Element*> view) const {
return _itemsTop + view->y();
}
void InnerWidget::repaintItem(const Message *item) {
if (!item) {
void InnerWidget::repaintItem(const Element *view) {
if (!view) {
return;
}
update(0, itemTop(item), width(), item->data()->height());
update(0, itemTop(view), width(), view->data()->height());
}
QPoint InnerWidget::mapPointToItem(QPoint point, const Message *view) const {
QPoint InnerWidget::mapPointToItem(QPoint point, const Element *view) const {
if (!view) {
return QPoint();
}

View file

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "history/view/history_view_cursor_state.h"
#include "history/admin_log/history_admin_log_item.h"
#include "history/admin_log/history_admin_log_section.h"
#include "ui/widgets/tooltip.h"
@ -23,7 +24,7 @@ class Controller;
} // namespace Window
namespace HistoryView {
class Message;
class Element;
} // namespace HistoryView
namespace AdminLog {
@ -90,7 +91,7 @@ protected:
int resizeGetHeight(int newWidth) override;
private:
using Message = HistoryView::Message;
using Element = HistoryView::Element;
enum class Direction {
Up,
Down,
@ -112,9 +113,9 @@ private:
void mouseActionCancel();
void updateSelected();
void performDrag();
int itemTop(not_null<const Message*> item) const;
void repaintItem(const Message *item);
QPoint mapPointToItem(QPoint point, const Message *item) const;
int itemTop(not_null<const Element*> view) const;
void repaintItem(const Element *view);
QPoint mapPointToItem(QPoint point, const Element *view) const;
void handlePendingHistoryResize();
void showContextMenu(QContextMenuEvent *e, bool showFromTouch = false);
@ -146,7 +147,7 @@ private:
void clearAfterFilterChange();
void clearAndRequestLog();
void addEvents(Direction direction, const QVector<MTPChannelAdminLogEvent> &events);
Message *viewForItem(const HistoryItem *item);
Element *viewForItem(const HistoryItem *item);
void toggleScrollDateShown();
void repaintScrollDateCallback();
@ -158,7 +159,7 @@ private:
// This function finds all history items that are displayed and calls template method
// for each found message (in given direction) in the passed history with passed top offset.
//
// Method has "bool (*Method)(Message *item, int itemtop, int itembottom)" signature
// Method has "bool (*Method)(not_null<Element*> view, int itemtop, int itembottom)" signature
// if it returns false the enumeration stops immidiately.
template <EnumItemsDirection direction, typename Method>
void enumerateItems(Method method);
@ -166,7 +167,7 @@ private:
// This function finds all userpics on the left that are displayed and calls template method
// for each found userpic (from the top to the bottom) using enumerateItems() method.
//
// Method has "bool (*Method)(not_null<HistoryMessage*> message, int userpicTop)" signature
// Method has "bool (*Method)(not_null<Element*> view, int userpicTop)" signature
// if it returns false the enumeration stops immidiately.
template <typename Method>
void enumerateUserpics(Method method);
@ -183,8 +184,8 @@ private:
not_null<ChannelData*> _channel;
not_null<History*> _history;
std::vector<OwnedItem> _items;
std::map<uint64, not_null<Message*>> _itemsByIds;
std::map<not_null<HistoryItem*>, not_null<Message*>, std::less<>> _itemsByData;
std::map<uint64, not_null<Element*>> _itemsByIds;
std::map<not_null<HistoryItem*>, not_null<Element*>, std::less<>> _itemsByData;
int _itemsTop = 0;
int _itemsHeight = 0;
@ -192,14 +193,14 @@ private:
int _minHeight = 0;
int _visibleTop = 0;
int _visibleBottom = 0;
Message *_visibleTopItem = nullptr;
Element *_visibleTopItem = nullptr;
int _visibleTopFromItem = 0;
bool _scrollDateShown = false;
Animation _scrollDateOpacity;
SingleQueuedInvokation _scrollDateCheck;
base::Timer _scrollDateHideTimer;
Message *_scrollDateLastItem = nullptr;
Element *_scrollDateLastItem = nullptr;
int _scrollDateLastItemTop = 0;
// Up - max, Down - min.
@ -218,12 +219,12 @@ private:
TextSelectType _mouseSelectType = TextSelectType::Letters;
QPoint _dragStartPosition;
QPoint _mousePosition;
Message *_mouseActionItem = nullptr;
Element *_mouseActionItem = nullptr;
HistoryCursorState _mouseCursorState = HistoryDefaultCursorState;
uint16 _mouseTextSymbol = 0;
bool _pressWasInactive = false;
Message *_selectedItem = nullptr;
Element *_selectedItem = nullptr;
TextSelection _selectedText;
bool _wasSelectedText = false; // was some text selected in current drag action
Qt::CursorShape _cursor = style::cur_default;

View file

@ -8,7 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/admin_log/history_admin_log_item.h"
#include "history/admin_log/history_admin_log_inner.h"
#include "history/view/history_view_message.h"
#include "history/view/history_view_element.h"
#include "history/history_service.h"
#include "history/history_message.h"
#include "lang/lang_keys.h"
@ -282,11 +282,11 @@ TextWithEntities GenerateParticipantChangeText(not_null<ChannelData*> channel, c
} // namespace
OwnedItem::OwnedItem(not_null<HistoryItem*> data)
OwnedItem::OwnedItem(
not_null<Window::Controller*> controller,
not_null<HistoryItem*> data)
: _data(data)
, _view(std::make_unique<HistoryView::Message>(
data,
HistoryView::Context::AdminLog)) {
, _view(_data->createView(controller, HistoryView::Context::AdminLog)) {
}
OwnedItem::OwnedItem(OwnedItem &&other)
@ -307,7 +307,12 @@ OwnedItem::~OwnedItem() {
}
}
void GenerateItems(not_null<History*> history, LocalIdManager &idManager, const MTPDchannelAdminLogEvent &event, base::lambda<void(OwnedItem item)> callback) {
void GenerateItems(
not_null<Window::Controller*> controller,
not_null<History*> history,
LocalIdManager &idManager,
const MTPDchannelAdminLogEvent &event,
base::lambda<void(OwnedItem item)> callback) {
Expects(history->peer->isChannel());
auto id = event.vid.v;
@ -315,8 +320,8 @@ void GenerateItems(not_null<History*> history, LocalIdManager &idManager, const
auto channel = history->peer->asChannel();
auto &action = event.vaction;
auto date = event.vdate;
auto addPart = [&callback](not_null<HistoryItem*> item) {
return callback(OwnedItem(item));
auto addPart = [&](not_null<HistoryItem*> item) {
return callback(OwnedItem(controller, item));
};
using Flag = MTPDmessage::Flag;

View file

@ -7,36 +7,51 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
namespace Window {
class Controller;
} // namespace Window
namespace HistoryView {
class Element;
} // namespace HistoryView
namespace AdminLog {
class OwnedItem;
class LocalIdManager;
void GenerateItems(not_null<History*> history, LocalIdManager &idManager, const MTPDchannelAdminLogEvent &event, base::lambda<void(OwnedItem item)> callback);
void GenerateItems(
not_null<Window::Controller*> controller,
not_null<History*> history,
LocalIdManager &idManager,
const MTPDchannelAdminLogEvent &event,
base::lambda<void(OwnedItem item)> callback);
// Smart pointer wrapper for HistoryItem* that destroys the owned item.
class OwnedItem {
public:
explicit OwnedItem(not_null<HistoryItem*> data);
OwnedItem(
not_null<Window::Controller*> controller,
not_null<HistoryItem*> data);
OwnedItem(const OwnedItem &other) = delete;
OwnedItem &operator=(const OwnedItem &other) = delete;
OwnedItem(OwnedItem &&other);
OwnedItem &operator=(OwnedItem &&other);
~OwnedItem();
HistoryView::Message *get() const {
HistoryView::Element *get() const {
return _view.get();
}
HistoryView::Message *operator->() const {
HistoryView::Element *operator->() const {
return get();
}
operator HistoryView::Message*() const {
operator HistoryView::Element*() const {
return get();
}
private:
HistoryItem *_data = nullptr;
std::unique_ptr<HistoryView::Message> _view;
std::unique_ptr<HistoryView::Element> _view;
};

View file

@ -123,7 +123,7 @@ private:
class SectionMemento : public Window::SectionMemento {
public:
using Message = HistoryView::Message;
using Element = HistoryView::Element;
SectionMemento(not_null<ChannelData*> channel) : _channel(channel) {
}
@ -159,7 +159,7 @@ public:
void setItems(
std::vector<OwnedItem> &&items,
std::map<uint64, not_null<Message*>> &&itemsByIds,
std::map<uint64, not_null<Element*>> &&itemsByIds,
bool upLoaded,
bool downLoaded) {
_items = std::move(items);
@ -179,7 +179,7 @@ public:
std::vector<OwnedItem> takeItems() {
return std::move(_items);
}
std::map<uint64, not_null<Message*>> takeItemsByIds() {
std::map<uint64, not_null<Element*>> takeItemsByIds() {
return std::move(_itemsByIds);
}
LocalIdManager takeIdManager() {
@ -204,7 +204,7 @@ private:
std::vector<not_null<UserData*>> _admins;
std::vector<not_null<UserData*>> _adminsCanEdit;
std::vector<OwnedItem> _items;
std::map<uint64, not_null<Message*>> _itemsByIds;
std::map<uint64, not_null<Element*>> _itemsByIds;
bool _upLoaded = false;
bool _downLoaded = true;
LocalIdManager _idManager;

View file

@ -9,7 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/history_view_top_bar_widget.h"
#include "history/view/history_view_list_widget.h"
#include "history/view/history_view_message.h"
#include "history/view/history_view_element.h"
#include "lang/lang_keys.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/shadow.h"

View file

@ -7,7 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "history/history.h"
#include "history/view/history_view_message.h"
#include "history/view/history_view_element.h"
#include "history/history_message.h"
#include "history/history_media_types.h"
#include "history/history_service.h"
@ -1388,8 +1388,8 @@ void History::addItemToBlock(not_null<HistoryItem*> item) {
auto block = prepareBlockForAddingItem();
block->messages.push_back(std::make_unique<HistoryView::Message>(
item,
block->messages.push_back(item->createView(
App::wnd()->controller(),
HistoryView::Context::History));
block->messages.back()->attachToBlock(block, block->messages.size() - 1);
item->previousItemChanged();
@ -1965,8 +1965,8 @@ not_null<HistoryItem*> History::addNewInTheMiddle(
const auto it = block->messages.insert(
block->messages.begin() + itemIndex,
std::make_unique<HistoryView::Message>(
newItem,
newItem->createView(
App::wnd()->controller(),
HistoryView::Context::History));
(*it)->attachToBlock(block.get(), itemIndex);
newItem->previousItemChanged();
@ -2566,7 +2566,7 @@ void HistoryBlock::clear(bool leaveItems) {
// #TODO feeds delete all items in history
}
void HistoryBlock::remove(not_null<Message*> view) {
void HistoryBlock::remove(not_null<Element*> view) {
Expects(view->block() == this);
const auto item = view->data();

View file

@ -28,7 +28,7 @@ enum NewMessageType {
};
namespace HistoryView {
class Message;
class Element;
} // namespace HistoryView
class Histories {
@ -397,7 +397,7 @@ public:
// we save a pointer of the history item at the top of the displayed window
// together with an offset from the window top to the top of this message
// resulting scrollTop = top(scrollTopItem) + scrollTopOffset
HistoryView::Message *scrollTopItem = nullptr;
HistoryView::Element *scrollTopItem = nullptr;
int scrollTopOffset = 0;
void forgetScrollState() {
scrollTopItem = nullptr;
@ -579,17 +579,17 @@ private:
class HistoryBlock {
public:
using Message = HistoryView::Message;
using Element = HistoryView::Element;
HistoryBlock(not_null<History*> history);
HistoryBlock(const HistoryBlock &) = delete;
HistoryBlock &operator=(const HistoryBlock &) = delete;
~HistoryBlock();
std::vector<std::unique_ptr<Message>> messages;
std::vector<std::unique_ptr<Element>> messages;
void clear(bool leaveItems = false);
void remove(not_null<Message*> view);
void remove(not_null<Element*> view);
int resizeGetHeight(int newWidth, bool resizeAllItems);
int y() const {

View file

@ -14,7 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_media_types.h"
#include "history/history_item_components.h"
#include "history/view/history_view_service_message.h"
#include "history/view/history_view_message.h"
#include "history/view/history_view_element.h"
#include "ui/text_options.h"
#include "ui/widgets/popup_menu.h"
#include "window/window_controller.h"
@ -25,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_widget.h"
#include "mainwindow.h"
#include "mainwidget.h"
#include "layout.h"
#include "auth_session.h"
#include "messenger.h"
#include "apiwrap.h"
@ -193,7 +194,7 @@ void HistoryInner::repaintItem(const HistoryItem *item) {
}
}
void HistoryInner::repaintItem(const Message *view) {
void HistoryInner::repaintItem(const Element *view) {
if (view) {
const auto top = itemTop(view);
if (top >= 0) {
@ -303,7 +304,7 @@ void HistoryInner::enumerateUserpics(Method method) {
// -1 means we didn't find an attached to next message yet.
int lowestAttachedItemTop = -1;
auto userpicCallback = [&](not_null<Message*> view, int itemtop, int itembottom) {
auto userpicCallback = [&](not_null<Element*> view, int itemtop, int itembottom) {
// Skip all service messages.
const auto item = view->data();
const auto message = item->toHistoryMessage();
@ -352,7 +353,7 @@ void HistoryInner::enumerateDates(Method method) {
// -1 means we didn't find a same-day with previous message yet.
auto lowestInOneDayItemBottom = -1;
auto dateCallback = [&](not_null<Message*> view, int itemtop, int itembottom) {
auto dateCallback = [&](not_null<Element*> view, int itemtop, int itembottom) {
const auto item = view->data();
if (lowestInOneDayItemBottom < 0 && item->isInOneDayWithPrevious()) {
lowestInOneDayItemBottom = itembottom - item->marginBottom();
@ -440,7 +441,7 @@ TextSelection HistoryInner::computeRenderSelection(
}
TextSelection HistoryInner::itemRenderSelection(
not_null<Message*> view,
not_null<Element*> view,
int selfromy,
int seltoy) const {
const auto item = view->data();
@ -598,7 +599,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
}
if (mtop >= 0 || htop >= 0) {
enumerateUserpics([&](not_null<Message*> view, int userpicTop) {
enumerateUserpics([&](not_null<Element*> view, int userpicTop) {
// stop the enumeration if the userpic is below the painted rect
if (userpicTop >= clip.top() + clip.height()) {
return false;
@ -627,7 +628,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
//int showFloatingBefore = height() - 2 * (_visibleAreaBottom - _visibleAreaTop) - dateHeight;
auto scrollDateOpacity = _scrollDateOpacity.current(ms, _scrollDateShown ? 1. : 0.);
enumerateDates([&](not_null<Message*> view, int itemtop, int dateTop) {
enumerateDates([&](not_null<Element*> view, int itemtop, int dateTop) {
// stop the enumeration if the date is above the painted rect
if (dateTop + dateHeight <= clip.top()) {
return false;
@ -883,7 +884,7 @@ void HistoryInner::touchScrollUpdated(const QPoint &screenPos) {
touchUpdateSpeed();
}
QPoint HistoryInner::mapPointToItem(QPoint p, const Message *view) {
QPoint HistoryInner::mapPointToItem(QPoint p, const Element *view) {
if (view) {
const auto top = itemTop(view);
p.setY(p.y() - top);
@ -2109,7 +2110,7 @@ void HistoryInner::adjustCurrent(int32 y, History *history) const {
}
}
HistoryView::Message *HistoryInner::prevItem(Message *view) {
auto HistoryInner::prevItem(Element *view) -> Element* {
if (!view) {
return nullptr;
} else if (const auto result = view->previousInBlocks()) {
@ -2124,7 +2125,7 @@ HistoryView::Message *HistoryInner::prevItem(Message *view) {
return nullptr;
}
HistoryView::Message *HistoryInner::nextItem(Message *view) {
auto HistoryInner::nextItem(Element *view) -> Element* {
if (!view) {
return nullptr;
} else if (const auto result = view->nextInBlocks()) {
@ -2225,7 +2226,7 @@ void HistoryInner::onUpdateSelected() {
auto block = (HistoryBlock*)nullptr;
auto item = (HistoryItem*)nullptr;
auto view = (Message*)nullptr;
auto view = (Element*)nullptr;
QPoint m;
adjustCurrent(point.y());
@ -2277,7 +2278,7 @@ void HistoryInner::onUpdateSelected() {
auto dateHeight = st::msgServicePadding.bottom() + st::msgServiceFont->height + st::msgServicePadding.top();
auto scrollDateOpacity = _scrollDateOpacity.current(_scrollDateShown ? 1. : 0.);
enumerateDates([&](not_null<Message*> view, int itemtop, int dateTop) {
enumerateDates([&](not_null<Element*> view, int itemtop, int dateTop) {
// stop enumeration if the date is above our point
if (dateTop + dateHeight <= point.y()) {
return false;
@ -2341,7 +2342,7 @@ void HistoryInner::onUpdateSelected() {
if (!dragState.link && m.x() >= st::historyPhotoLeft && m.x() < st::historyPhotoLeft + st::msgPhotoSize) {
if (auto msg = item->toHistoryMessage()) {
if (msg->hasFromPhoto()) {
enumerateUserpics([&](not_null<Message*> view, int userpicTop) -> bool {
enumerateUserpics([&](not_null<Element*> view, int userpicTop) -> bool {
// stop enumeration if the userpic is below our point
if (userpicTop > point.y()) {
return false;
@ -2490,7 +2491,7 @@ void HistoryInner::onUpdateSelected() {
}
}
void HistoryInner::updateDragSelection(Message *dragSelFrom, Message *dragSelTo, bool dragSelecting) {
void HistoryInner::updateDragSelection(Element *dragSelFrom, Element *dragSelTo, bool dragSelecting) {
if (_dragSelFrom == dragSelFrom && _dragSelTo == dragSelTo && _dragSelecting == dragSelecting) {
return;
}
@ -2552,7 +2553,7 @@ int HistoryInner::itemTop(const HistoryItem *item) const {
return itemTop(item->mainView());
}
int HistoryInner::itemTop(const Message *view) const {
int HistoryInner::itemTop(const Element *view) const {
if (!view) {
return -1;
}

View file

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/rp_widget.h"
#include "ui/widgets/tooltip.h"
#include "ui/widgets/scroll_area.h"
#include "history/view/history_view_cursor_state.h"
#include "history/view/history_view_top_bar_widget.h"
namespace Window {
@ -28,7 +29,7 @@ class HistoryInner
Q_OBJECT
public:
using Message = HistoryView::Message;
using Element = HistoryView::Element;
HistoryInner(
not_null<HistoryWidget*> historyWidget,
@ -47,7 +48,7 @@ public:
void updateSize();
void repaintItem(const HistoryItem *item);
void repaintItem(const Message *view);
void repaintItem(const Element *view);
bool canCopySelected() const;
bool canDeleteSelected() const;
@ -73,7 +74,7 @@ public:
// -1 if should not be visible, -2 if bad history()
int itemTop(const HistoryItem *item) const;
int itemTop(const Message *view) const;
int itemTop(const Element *view) const;
void notifyIsBotChanged();
void notifyMigrateUpdated();
@ -140,7 +141,7 @@ private:
// This function finds all history items that are displayed and calls template method
// for each found message (in given direction) in the passed history with passed top offset.
//
// Method has "bool (*Method)(not_null<Message*> view, int itemtop, int itembottom)" signature
// Method has "bool (*Method)(not_null<Element*> view, int itemtop, int itembottom)" signature
// if it returns false the enumeration stops immidiately.
template <bool TopToBottom, typename Method>
void enumerateItemsInHistory(History *history, int historytop, Method method);
@ -160,7 +161,7 @@ private:
// This function finds all userpics on the left that are displayed and calls template method
// for each found userpic (from the top to the bottom) using enumerateItems() method.
//
// Method has "bool (*Method)(not_null<Message*> view, int userpicTop)" signature
// Method has "bool (*Method)(not_null<Element*> view, int userpicTop)" signature
// if it returns false the enumeration stops immidiately.
template <typename Method>
void enumerateUserpics(Method method);
@ -168,7 +169,7 @@ private:
// This function finds all date elements that are displayed and calls template method
// for each found date element (from the bottom to the top) using enumerateItems() method.
//
// Method has "bool (*Method)(not_null<Message*> view, int itemtop, int dateTop)" signature
// Method has "bool (*Method)(not_null<Element*> view, int itemtop, int dateTop)" signature
// if it returns false the enumeration stops immidiately.
template <typename Method>
void enumerateDates(Method method);
@ -179,7 +180,7 @@ private:
void mouseActionCancel();
void performDrag();
QPoint mapPointToItem(QPoint p, const Message *view);
QPoint mapPointToItem(QPoint p, const Element *view);
QPoint mapPointToItem(QPoint p, const HistoryItem *item);
void showContextMenu(QContextMenuEvent *e, bool showFromTouch = false);
@ -202,11 +203,11 @@ private:
void adjustCurrent(int32 y) const;
void adjustCurrent(int32 y, History *history) const;
Message *prevItem(Message *item);
Message *nextItem(Message *item);
void updateDragSelection(Message *dragSelFrom, Message *dragSelTo, bool dragSelecting);
Element *prevItem(Element *item);
Element *nextItem(Element *item);
void updateDragSelection(Element *dragSelFrom, Element *dragSelTo, bool dragSelecting);
TextSelection itemRenderSelection(
not_null<Message*> view,
not_null<Element*> view,
int selfromy,
int seltoy) const;
TextSelection computeRenderSelection(
@ -305,8 +306,8 @@ private:
ClickHandlerPtr _contextMenuLink;
Message *_dragSelFrom = nullptr;
Message *_dragSelTo = nullptr;
Element *_dragSelFrom = nullptr;
Element *_dragSelTo = nullptr;
bool _dragSelecting = false;
bool _wasSelectedText = false; // was some text selected in current drag action
@ -336,7 +337,7 @@ private:
Animation _scrollDateOpacity;
SingleQueuedInvokation _scrollDateCheck;
SingleTimer _scrollDateHideTimer;
Message *_scrollDateLastItem = nullptr;
Element *_scrollDateLastItem = nullptr;
int _scrollDateLastItemTop = 0;
ClickHandlerPtr _scrollDateLink;

View file

@ -9,7 +9,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h"
#include "mainwidget.h"
#include "history/view/history_view_message.h"
#include "layout.h"
#include "history/view/history_view_element.h"
#include "history/view/history_view_service_message.h"
#include "history/history_item_components.h"
#include "history/history_media_types.h"
@ -41,57 +42,6 @@ constexpr int kAttachMessageToPreviousSecondsDelta = 900;
} // namespace
HistoryTextState::HistoryTextState(not_null<const HistoryItem*> item)
: itemId(item->fullId()) {
}
HistoryTextState::HistoryTextState(
not_null<const HistoryItem*> item,
const Text::StateResult &state)
: itemId(item->fullId())
, cursor(state.uponSymbol
? HistoryInTextCursorState
: HistoryDefaultCursorState)
, link(state.link)
, afterSymbol(state.afterSymbol)
, symbol(state.symbol) {
}
HistoryTextState::HistoryTextState(
not_null<const HistoryItem*> item,
ClickHandlerPtr link)
: itemId(item->fullId())
, link(link) {
}
HistoryMediaPtr::HistoryMediaPtr() = default;
HistoryMediaPtr::HistoryMediaPtr(std::unique_ptr<HistoryMedia> pointer)
: _pointer(std::move(pointer)) {
if (_pointer) {
_pointer->attachToParent();
}
}
void HistoryMediaPtr::reset(std::unique_ptr<HistoryMedia> pointer) {
*this = std::move(pointer);
}
HistoryMediaPtr &HistoryMediaPtr::operator=(std::unique_ptr<HistoryMedia> pointer) {
if (_pointer) {
_pointer->detachFromParent();
}
_pointer = std::move(pointer);
if (_pointer) {
_pointer->attachToParent();
}
return *this;
}
HistoryMediaPtr::~HistoryMediaPtr() {
reset();
}
namespace internal {
TextSelection unshiftSelection(TextSelection selection, uint16 byLength) {

View file

@ -10,6 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/runtime_composer.h"
#include "base/flags.h"
#include "base/value_ordering.h"
#include "history/history_media_pointer.h"
#include "history/view/history_view_cursor_state.h"
struct MessageGroupId;
struct HistoryMessageGroup;
@ -41,6 +43,14 @@ namespace Data {
struct MessagePosition;
} // namespace Data
namespace Window {
class Controller;
} // namespace Window
namespace HistoryView {
enum class Context : char;
} // namespace HistoryView
class HistoryElement {
public:
HistoryElement() = default;
@ -70,94 +80,6 @@ protected:
};
enum HistoryCursorState {
HistoryDefaultCursorState,
HistoryInTextCursorState,
HistoryInDateCursorState,
HistoryInForwardedCursorState,
};
struct HistoryTextState {
HistoryTextState() = default;
HistoryTextState(not_null<const HistoryItem*> item);
HistoryTextState(
not_null<const HistoryItem*> item,
const Text::StateResult &state);
HistoryTextState(
not_null<const HistoryItem*> item,
ClickHandlerPtr link);
HistoryTextState(
std::nullptr_t,
const Text::StateResult &state)
: cursor(state.uponSymbol
? HistoryInTextCursorState
: HistoryDefaultCursorState)
, link(state.link)
, afterSymbol(state.afterSymbol)
, symbol(state.symbol) {
}
HistoryTextState(std::nullptr_t, ClickHandlerPtr link)
: link(link) {
}
FullMsgId itemId;
HistoryCursorState cursor = HistoryDefaultCursorState;
ClickHandlerPtr link;
bool afterSymbol = false;
uint16 symbol = 0;
};
struct HistoryStateRequest {
Text::StateRequest::Flags flags = Text::StateRequest::Flag::LookupLink;
Text::StateRequest forText() const {
Text::StateRequest result;
result.flags = flags;
return result;
}
};
enum InfoDisplayType {
InfoDisplayDefault,
InfoDisplayOverImage,
InfoDisplayOverBackground,
};
// HistoryMedia has a special owning smart pointer
// which regs/unregs this media to the holding HistoryItem
class HistoryMediaPtr {
public:
HistoryMediaPtr();
HistoryMediaPtr(const HistoryMediaPtr &other) = delete;
HistoryMediaPtr &operator=(const HistoryMediaPtr &other) = delete;
HistoryMediaPtr(std::unique_ptr<HistoryMedia> other);
HistoryMediaPtr &operator=(std::unique_ptr<HistoryMedia> other);
HistoryMedia *get() const {
return _pointer.get();
}
void reset(std::unique_ptr<HistoryMedia> pointer = nullptr);
bool isNull() const {
return !_pointer;
}
HistoryMedia *operator->() const {
return get();
}
HistoryMedia &operator*() const {
Expects(!isNull());
return *get();
}
explicit operator bool() const {
return !isNull();
}
~HistoryMediaPtr();
private:
std::unique_ptr<HistoryMedia> _pointer;
};
namespace internal {
TextSelection unshiftSelection(TextSelection selection, uint16 byLength);
@ -229,10 +151,10 @@ public:
PeerData *from() const {
return _from;
}
HistoryView::Message *mainView() const {
HistoryView::Element *mainView() const {
return _mainView;
}
void setMainView(HistoryView::Message *view) {
void setMainView(HistoryView::Element *view) {
_mainView = view;
}
void clearMainView();
@ -536,6 +458,10 @@ public:
HistoryItem *previousItem() const;
HistoryItem *nextItem() const;
virtual std::unique_ptr<HistoryView::Element> createView(
not_null<Window::Controller*> controller,
HistoryView::Context context) = 0;
~HistoryItem();
protected:
@ -616,7 +542,7 @@ protected:
private:
void resetGroupMedia(const std::vector<not_null<HistoryItem*>> &others);
HistoryView::Message *_mainView = nullptr;
HistoryView::Element *_mainView = nullptr;
};

View file

@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "history/history_item.h"
struct HistoryMessageEdited;
namespace base {

View file

@ -10,12 +10,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_item_components.h"
#include "history/history_media_types.h"
#include "history/history_message.h"
#include "history/view/history_view_message.h"
#include "history/view/history_view_element.h"
#include "storage/storage_shared_media.h"
#include "lang/lang_keys.h"
#include "ui/grouped_layout.h"
#include "ui/text_options.h"
#include "styles/style_history.h"
#include "layout.h"
HistoryGroupedMedia::Element::Element(not_null<HistoryItem*> item)
: item(item) {

View file

@ -0,0 +1,38 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "history/history_media_pointer.h"
#include "history/history_media.h"
HistoryMediaPtr::HistoryMediaPtr() = default;
HistoryMediaPtr::HistoryMediaPtr(std::unique_ptr<HistoryMedia> pointer)
: _pointer(std::move(pointer)) {
if (_pointer) {
_pointer->attachToParent();
}
}
void HistoryMediaPtr::reset(std::unique_ptr<HistoryMedia> pointer) {
*this = std::move(pointer);
}
HistoryMediaPtr &HistoryMediaPtr::operator=(std::unique_ptr<HistoryMedia> pointer) {
if (_pointer) {
_pointer->detachFromParent();
}
_pointer = std::move(pointer);
if (_pointer) {
_pointer->attachToParent();
}
return *this;
}
HistoryMediaPtr::~HistoryMediaPtr() {
reset();
}

View file

@ -0,0 +1,45 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
class HistoryMedia;
// HistoryMedia has a special owning smart pointer
// which regs/unregs this media to the holding HistoryItem
class HistoryMediaPtr {
public:
HistoryMediaPtr();
HistoryMediaPtr(const HistoryMediaPtr &other) = delete;
HistoryMediaPtr &operator=(const HistoryMediaPtr &other) = delete;
HistoryMediaPtr(std::unique_ptr<HistoryMedia> other);
HistoryMediaPtr &operator=(std::unique_ptr<HistoryMedia> other);
HistoryMedia *get() const {
return _pointer.get();
}
void reset(std::unique_ptr<HistoryMedia> pointer = nullptr);
bool isNull() const {
return !_pointer;
}
HistoryMedia *operator->() const {
return get();
}
HistoryMedia &operator*() const {
Expects(!isNull());
return *get();
}
explicit operator bool() const {
return !isNull();
}
~HistoryMediaPtr();
private:
std::unique_ptr<HistoryMedia> _pointer;
};

View file

@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h"
#include "mainwidget.h"
#include "layout.h"
#include "mainwindow.h"
#include "storage/localstorage.h"
#include "storage/storage_shared_media.h"

View file

@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/toast/toast.h"
#include "ui/text_options.h"
#include "messenger.h"
#include "layout.h"
#include "styles/style_dialogs.h"
#include "styles/style_widgets.h"
#include "styles/style_history.h"
@ -2407,7 +2408,7 @@ bool HistoryMessage::getStateForwardedInfo(
QPoint point,
QRect &trect,
not_null<HistoryTextState*> outResult,
const HistoryStateRequest &request) const {
HistoryStateRequest request) const {
if (displayForwardedFrom()) {
auto forwarded = Get<HistoryMessageForwarded>();
auto fwdheight = ((forwarded->text.maxWidth() > trect.width()) ? 2 : 1) * st::semiboldFont->height;
@ -2472,7 +2473,7 @@ bool HistoryMessage::getStateText(
QPoint point,
QRect &trect,
not_null<HistoryTextState*> outResult,
const HistoryStateRequest &request) const {
HistoryStateRequest request) const {
if (trect.contains(point)) {
*outResult = HistoryTextState(this, _text.getState(
point - trect.topLeft(),
@ -2537,6 +2538,12 @@ bool HistoryMessage::hasFromPhoto() const {
return !out() && !history()->peer->isUser();
}
std::unique_ptr<HistoryView::Element> HistoryMessage::createView(
not_null<Window::Controller*> controller,
HistoryView::Context context) {
return controller->createMessageView(this, context);
}
HistoryMessage::~HistoryMessage() {
_media.reset();
if (auto reply = Get<HistoryMessageReply>()) {

View file

@ -228,6 +228,10 @@ public:
bool displayFromPhoto() const;
bool hasFromPhoto() const;
std::unique_ptr<HistoryView::Element> createView(
not_null<Window::Controller*> controller,
HistoryView::Context context) override;
~HistoryMessage();
protected:
@ -324,7 +328,7 @@ private:
QPoint point,
QRect &trect,
not_null<HistoryTextState*> outResult,
const HistoryStateRequest &request) const;
HistoryStateRequest request) const;
bool getStateReplyInfo(
QPoint point,
QRect &trect,
@ -337,7 +341,7 @@ private:
QPoint point,
QRect &trect,
not_null<HistoryTextState*> outResult,
const HistoryStateRequest &request) const;
HistoryStateRequest request) const;
void setMedia(const MTPMessageMedia *media);
void setReplyMarkup(const MTPReplyMarkup *markup);

View file

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h"
#include "mainwidget.h"
#include "apiwrap.h"
#include "layout.h"
#include "history/history_media_types.h"
#include "history/history_message.h"
#include "history/history_item_components.h"
@ -17,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_feed.h"
#include "auth_session.h"
#include "window/notifications_manager.h"
#include "window/window_controller.h"
#include "storage/storage_shared_media.h"
#include "ui/text_options.h"
@ -476,6 +478,12 @@ QString HistoryService::inReplyText() const {
return result.trimmed().startsWith(author()->name) ? result.trimmed().mid(author()->name.size()).trimmed() : result;
}
std::unique_ptr<HistoryView::Element> HistoryService::createView(
not_null<Window::Controller*> controller,
HistoryView::Context context) {
return controller->createMessageView(this, context);
}
void HistoryService::setServiceText(const PreparedText &prepared) {
_text.setText(
st::serviceTextStyle,

View file

@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "history/history_item.h"
struct HistoryServiceDependentData {
MsgId msgId = 0;
HistoryItem *msg = nullptr;
@ -103,6 +105,10 @@ public:
QString inDialogsText(DrawInDialog way) const override;
QString inReplyText() const override;
std::unique_ptr<HistoryView::Element> createView(
not_null<Window::Controller*> controller,
HistoryView::Context context) override;
~HistoryService();
protected:

View file

@ -29,7 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_inner_widget.h"
#include "history/history_item_components.h"
#include "history/view/history_view_service_message.h"
#include "history/view/history_view_message.h"
#include "history/view/history_view_element.h"
#include "profile/profile_block_group_members.h"
#include "info/info_memento.h"
#include "core/click_handler_types.h"

View file

@ -0,0 +1,33 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "history/view/history_view_cursor_state.h"
#include "history/history_item.h"
HistoryTextState::HistoryTextState(not_null<const HistoryItem*> item)
: itemId(item->fullId()) {
}
HistoryTextState::HistoryTextState(
not_null<const HistoryItem*> item,
const Text::StateResult &state)
: itemId(item->fullId())
, cursor(state.uponSymbol
? HistoryInTextCursorState
: HistoryDefaultCursorState)
, link(state.link)
, afterSymbol(state.afterSymbol)
, symbol(state.symbol) {
}
HistoryTextState::HistoryTextState(
not_null<const HistoryItem*> item,
ClickHandlerPtr link)
: itemId(item->fullId())
, link(link) {
}

View file

@ -0,0 +1,63 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
class HistoryItem;
enum HistoryCursorState {
HistoryDefaultCursorState,
HistoryInTextCursorState,
HistoryInDateCursorState,
HistoryInForwardedCursorState,
};
struct HistoryTextState {
HistoryTextState() = default;
HistoryTextState(not_null<const HistoryItem*> item);
HistoryTextState(
not_null<const HistoryItem*> item,
const Text::StateResult &state);
HistoryTextState(
not_null<const HistoryItem*> item,
ClickHandlerPtr link);
HistoryTextState(
std::nullptr_t,
const Text::StateResult &state)
: cursor(state.uponSymbol
? HistoryInTextCursorState
: HistoryDefaultCursorState)
, link(state.link)
, afterSymbol(state.afterSymbol)
, symbol(state.symbol) {
}
HistoryTextState(std::nullptr_t, ClickHandlerPtr link)
: link(link) {
}
FullMsgId itemId;
HistoryCursorState cursor = HistoryDefaultCursorState;
ClickHandlerPtr link;
bool afterSymbol = false;
uint16 symbol = 0;
};
struct HistoryStateRequest {
Text::StateRequest::Flags flags = Text::StateRequest::Flag::LookupLink;
Text::StateRequest forText() const {
Text::StateRequest result;
result.flags = flags;
return result;
}
};
enum InfoDisplayType {
InfoDisplayDefault,
InfoDisplayOverImage,
InfoDisplayOverBackground,
};

View file

@ -0,0 +1,104 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "history/view/history_view_element.h"
#include "history/history_item_components.h"
#include "history/history_media.h"
#include "data/data_session.h"
#include "auth_session.h"
namespace HistoryView {
Element::Element(not_null<HistoryItem*> data, Context context)
: _data(data)
, _context(context) {
}
not_null<HistoryItem*> Element::data() const {
return _data;
}
void Element::attachToBlock(not_null<HistoryBlock*> block, int index) {
Expects(!_data->isLogEntry());
Expects(_block == nullptr);
Expects(_indexInBlock < 0);
Expects(index >= 0);
_block = block;
_indexInBlock = index;
_data->setMainView(this);
_data->setPendingResize();
}
void Element::removeFromBlock() {
Expects(_block != nullptr);
_block->remove(this);
}
Element *Element::previousInBlocks() const {
if (_block && _indexInBlock >= 0) {
if (_indexInBlock > 0) {
return _block->messages[_indexInBlock - 1].get();
}
if (auto previous = _block->previousBlock()) {
Assert(!previous->messages.empty());
return previous->messages.back().get();
}
}
return nullptr;
}
Element *Element::nextInBlocks() const {
if (_block && _indexInBlock >= 0) {
if (_indexInBlock + 1 < _block->messages.size()) {
return _block->messages[_indexInBlock + 1].get();
}
if (auto next = _block->nextBlock()) {
Assert(!next->messages.empty());
return next->messages.front().get();
}
}
return nullptr;
}
void Element::clickHandlerActiveChanged(
const ClickHandlerPtr &handler,
bool active) {
if (const auto markup = _data->Get<HistoryMessageReplyMarkup>()) {
if (const auto keyboard = markup->inlineKeyboard.get()) {
keyboard->clickHandlerActiveChanged(handler, active);
}
}
App::hoveredLinkItem(active ? this : nullptr);
Auth().data().requestItemRepaint(_data);
if (const auto media = _data->getMedia()) {
media->clickHandlerActiveChanged(handler, active);
}
}
void Element::clickHandlerPressedChanged(
const ClickHandlerPtr &handler,
bool pressed) {
if (const auto markup = _data->Get<HistoryMessageReplyMarkup>()) {
if (const auto keyboard = markup->inlineKeyboard.get()) {
keyboard->clickHandlerPressedChanged(handler, pressed);
}
}
App::pressedLinkItem(pressed ? this : nullptr);
Auth().data().requestItemRepaint(_data);
if (const auto media = _data->getMedia()) {
media->clickHandlerPressedChanged(handler, pressed);
}
}
Element::~Element() {
App::messageViewDestroyed(this);
}
} // namespace HistoryView

View file

@ -0,0 +1,80 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "base/runtime_composer.h"
class HistoryItem;
namespace HistoryView {
enum class Context : char {
History,
Feed,
AdminLog
};
class Element
: public RuntimeComposer
, public ClickHandlerHost {
public:
Element(not_null<HistoryItem*> data, Context context);
not_null<HistoryItem*> data() const;
int y() const {
return _y;
}
void setY(int y) {
_y = y;
}
HistoryBlock *block() {
return _block;
}
const HistoryBlock *block() const {
return _block;
}
void attachToBlock(not_null<HistoryBlock*> block, int index);
void removeFromBlock();
void setIndexInBlock(int index) {
Expects(_block != nullptr);
Expects(index >= 0);
_indexInBlock = index;
}
int indexInBlock() const {
Expects((_indexInBlock >= 0) == (_block != nullptr));
Expects((_block == nullptr) || (_block->messages[_indexInBlock].get() == this));
return _indexInBlock;
}
Element *previousInBlocks() const;
Element *nextInBlocks() const;
// ClickHandlerHost interface
void clickHandlerActiveChanged(
const ClickHandlerPtr &handler,
bool active) override;
void clickHandlerPressedChanged(
const ClickHandlerPtr &handler,
bool pressed) override;
virtual ~Element();
private:
const not_null<HistoryItem*> _data;
int _y = 0;
Context _context;
HistoryBlock *_block = nullptr;
int _indexInBlock = -1;
};
} // namespace HistoryView

View file

@ -10,13 +10,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_media_types.h"
#include "history/history_message.h"
#include "history/history_item_components.h"
#include "history/view/history_view_message.h"
#include "history/view/history_view_element.h"
#include "history/view/history_view_service_message.h"
#include "chat_helpers/message_field.h"
#include "mainwindow.h"
#include "mainwidget.h"
#include "messenger.h"
#include "apiwrap.h"
#include "layout.h"
#include "window/window_controller.h"
#include "auth_session.h"
#include "ui/widgets/popup_menu.h"
@ -125,7 +126,7 @@ void ListWidget::enumerateUserpics(Method method) {
// -1 means we didn't find an attached to next message yet.
int lowestAttachedItemTop = -1;
auto userpicCallback = [&](not_null<Message*> view, int itemtop, int itembottom) {
auto userpicCallback = [&](not_null<Element*> view, int itemtop, int itembottom) {
// Skip all service messages.
auto message = view->data()->toHistoryMessage();
if (!message) return true;
@ -171,7 +172,7 @@ void ListWidget::enumerateDates(Method method) {
// -1 means we didn't find a same-day with previous message yet.
auto lowestInOneDayItemBottom = -1;
auto dateCallback = [&](not_null<Message*> view, int itemtop, int itembottom) {
auto dateCallback = [&](not_null<Element*> view, int itemtop, int itembottom) {
const auto item = view->data();
if (lowestInOneDayItemBottom < 0 && item->isInOneDayWithPrevious()) {
lowestInOneDayItemBottom = itembottom - item->marginBottom();
@ -288,7 +289,7 @@ void ListWidget::restoreScrollState() {
_scrollTopState = ScrollTopState();
}
Message *ListWidget::viewForItem(const HistoryItem *item) const {
Element *ListWidget::viewForItem(const HistoryItem *item) const {
if (item) {
if (const auto i = _views.find(item); i != _views.end()) {
return i->second.get();
@ -297,14 +298,14 @@ Message *ListWidget::viewForItem(const HistoryItem *item) const {
return nullptr;
}
not_null<Message*> ListWidget::enforceViewForItem(
not_null<Element*> ListWidget::enforceViewForItem(
not_null<HistoryItem*> item) {
if (const auto view = viewForItem(item)) {
return view;
}
const auto [i, ok] = _views.emplace(
item,
std::make_unique<Message>(item, _context));
item->createView(_controller, _context));
return i->second.get();
}
@ -321,7 +322,7 @@ int ListWidget::findNearestItem(Data::MessagePosition position) const {
}
const auto after = ranges::find_if(
_items,
[&](not_null<Message*> view) {
[&](not_null<Element*> view) {
return (view->data()->position() >= position);
});
return (after == end(_items))
@ -435,7 +436,7 @@ void ListWidget::checkMoveToOtherViewer() {
- kPreloadIfLessThanScreens;
auto minUniversalIdDelta = (minScreenDelta * visibleHeight)
/ minItemHeight;
auto preloadAroundMessage = [&](not_null<Message*> view) {
auto preloadAroundMessage = [&](not_null<Element*> view) {
auto preloadRequired = false;
auto itemPosition = view->data()->position();
auto itemIndex = ranges::find(_items, view) - begin(_items);
@ -586,7 +587,7 @@ void ListWidget::paintEvent(QPaintEvent *e) {
}
p.translate(0, -top);
enumerateUserpics([&](not_null<Message*> view, int userpicTop) {
enumerateUserpics([&](not_null<Element*> view, int userpicTop) {
// stop the enumeration if the userpic is below the painted rect
if (userpicTop >= clip.top() + clip.height()) {
return false;
@ -609,7 +610,7 @@ void ListWidget::paintEvent(QPaintEvent *e) {
auto dateHeight = st::msgServicePadding.bottom() + st::msgServiceFont->height + st::msgServicePadding.top();
auto scrollDateOpacity = _scrollDateOpacity.current(ms, _scrollDateShown ? 1. : 0.);
enumerateDates([&](not_null<Message*> view, int itemtop, int dateTop) {
enumerateDates([&](not_null<Element*> view, int itemtop, int dateTop) {
// stop the enumeration if the date is above the painted rect
if (dateTop + dateHeight <= clip.top()) {
return false;
@ -655,7 +656,7 @@ TextWithEntities ListWidget::getSelectedText() const {
: TextWithEntities();
}
not_null<Message*> ListWidget::findItemByY(int y) const {
not_null<Element*> ListWidget::findItemByY(int y) const {
Expects(!_items.empty());
if (y < _itemsTop) {
@ -671,7 +672,7 @@ not_null<Message*> ListWidget::findItemByY(int y) const {
return (i != end(_items)) ? i->get() : _items.back().get();
}
Message *ListWidget::strictFindItemByY(int y) const {
Element *ListWidget::strictFindItemByY(int y) const {
if (_items.empty()) {
return nullptr;
}
@ -1191,7 +1192,7 @@ void ListWidget::updateSelected() {
if (!dragState.link && itemPoint.x() >= st::historyPhotoLeft && itemPoint.x() < st::historyPhotoLeft + st::msgPhotoSize) {
if (auto message = item->toHistoryMessage()) {
if (message->hasFromPhoto()) {
enumerateUserpics([&](not_null<Message*> view, int userpicTop) -> bool {
enumerateUserpics([&](not_null<Element*> view, int userpicTop) -> bool {
// stop enumeration if the userpic is below our point
if (userpicTop > point.y()) {
return false;
@ -1371,11 +1372,11 @@ void ListWidget::performDrag() {
//} // #TODO drag
}
int ListWidget::itemTop(not_null<const Message*> view) const {
int ListWidget::itemTop(not_null<const Element*> view) const {
return _itemsTop + view->y();
}
void ListWidget::repaintItem(const Message *view) {
void ListWidget::repaintItem(const Element *view) {
if (!view) {
return;
}
@ -1384,7 +1385,7 @@ void ListWidget::repaintItem(const Message *view) {
QPoint ListWidget::mapPointToItem(
QPoint point,
const Message *view) const {
const Element *view) const {
if (!view) {
return QPoint();
}

View file

@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mtproto/sender.h"
#include "base/timer.h"
#include "data/data_messages.h"
#include "history/view/history_view_cursor_state.h"
namespace Ui {
class PopupMenu;
@ -24,7 +25,7 @@ class Controller;
namespace HistoryView {
enum class Context : char;
class Message;
class Element;
class ListDelegate {
public:
@ -142,8 +143,8 @@ private:
void saveScrollState();
void restoreScrollState();
Message *viewForItem(const HistoryItem *item) const;
not_null<Message*> enforceViewForItem(not_null<HistoryItem*> item);
Element *viewForItem(const HistoryItem *item) const;
not_null<Element*> enforceViewForItem(not_null<HistoryItem*> item);
void mouseActionStart(const QPoint &screenPos, Qt::MouseButton button);
void mouseActionUpdate(const QPoint &screenPos);
@ -151,9 +152,9 @@ private:
void mouseActionCancel();
void updateSelected();
void performDrag();
int itemTop(not_null<const Message*> view) const;
void repaintItem(const Message *view);
QPoint mapPointToItem(QPoint point, const Message *view) const;
int itemTop(not_null<const Element*> view) const;
void repaintItem(const Element *view);
QPoint mapPointToItem(QPoint point, const Element *view) const;
void handlePendingHistoryResize();
void showContextMenu(QContextMenuEvent *e, bool showFromTouch = false);
@ -172,8 +173,8 @@ private:
const TextWithEntities &forClipboard,
QClipboard::Mode mode = QClipboard::Clipboard);
not_null<Message*> findItemByY(int y) const;
Message *strictFindItemByY(int y) const;
not_null<Element*> findItemByY(int y) const;
Element *strictFindItemByY(int y) const;
int findNearestItem(Data::MessagePosition position) const;
void checkMoveToOtherViewer();
@ -191,7 +192,7 @@ private:
// This function finds all history items that are displayed and calls template method
// for each found message (in given direction) in the passed history with passed top offset.
//
// Method has "bool (*Method)(Message *view, int itemtop, int itembottom)" signature
// Method has "bool (*Method)(not_null<Element*> view, int itemtop, int itembottom)" signature
// if it returns false the enumeration stops immediately.
template <EnumItemsDirection direction, typename Method>
void enumerateItems(Method method);
@ -199,7 +200,7 @@ private:
// This function finds all userpics on the left that are displayed and calls template method
// for each found userpic (from the top to the bottom) using enumerateItems() method.
//
// Method has "bool (*Method)(not_null<HistoryMessage*> message, int userpicTop)" signature
// Method has "bool (*Method)(not_null<Element*> view, int userpicTop)" signature
// if it returns false the enumeration stops immediately.
template <typename Method>
void enumerateUserpics(Method method);
@ -221,15 +222,15 @@ private:
int _aroundIndex = -1;
int _idsLimit = kMinimalIdsLimit;
Data::MessagesSlice _slice;
std::vector<not_null<Message*>> _items;
std::map<not_null<HistoryItem*>, std::unique_ptr<Message>, std::less<>> _views;
std::vector<not_null<Element*>> _items;
std::map<not_null<HistoryItem*>, std::unique_ptr<Element>, std::less<>> _views;
int _itemsTop = 0;
int _itemsHeight = 0;
int _minHeight = 0;
int _visibleTop = 0;
int _visibleBottom = 0;
Message *_visibleTopItem = nullptr;
Element *_visibleTopItem = nullptr;
int _visibleTopFromItem = 0;
ScrollTopState _scrollTopState;
@ -237,19 +238,19 @@ private:
Animation _scrollDateOpacity;
SingleQueuedInvokation _scrollDateCheck;
base::Timer _scrollDateHideTimer;
Message *_scrollDateLastItem = nullptr;
Element *_scrollDateLastItem = nullptr;
int _scrollDateLastItemTop = 0;
MouseAction _mouseAction = MouseAction::None;
TextSelectType _mouseSelectType = TextSelectType::Letters;
QPoint _dragStartPosition;
QPoint _mousePosition;
Message *_mouseActionItem = nullptr;
Element *_mouseActionItem = nullptr;
HistoryCursorState _mouseCursorState = HistoryDefaultCursorState;
uint16 _mouseTextSymbol = 0;
bool _pressWasInactive = false;
Message *_selectedItem = nullptr;
Element *_selectedItem = nullptr;
TextSelection _selectedText;
bool _wasSelectedText = false; // was some text selected in current drag action
Qt::CursorShape _cursor = style::cur_default;

View file

@ -7,98 +7,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "history/view/history_view_message.h"
#include "history/history_item_components.h"
#include "history/history_media.h"
#include "data/data_session.h"
#include "auth_session.h"
#include "history/history_message.h"
namespace HistoryView {
Message::Message(not_null<HistoryItem*> data, Context context)
: _data(data)
, _context(context) {
Message::Message(not_null<HistoryMessage*> data, Context context)
: Element(data, context) {
}
not_null<HistoryItem*> Message::data() const {
return _data;
}
void Message::attachToBlock(not_null<HistoryBlock*> block, int index) {
Expects(!_data->isLogEntry());
Expects(_block == nullptr);
Expects(_indexInBlock < 0);
Expects(index >= 0);
_block = block;
_indexInBlock = index;
_data->setMainView(this);
_data->setPendingResize();
}
void Message::removeFromBlock() {
Expects(_block != nullptr);
_block->remove(this);
}
Message *Message::previousInBlocks() const {
if (_block && _indexInBlock >= 0) {
if (_indexInBlock > 0) {
return _block->messages[_indexInBlock - 1].get();
}
if (auto previous = _block->previousBlock()) {
Assert(!previous->messages.empty());
return previous->messages.back().get();
}
}
return nullptr;
}
Message *Message::nextInBlocks() const {
if (_block && _indexInBlock >= 0) {
if (_indexInBlock + 1 < _block->messages.size()) {
return _block->messages[_indexInBlock + 1].get();
}
if (auto next = _block->nextBlock()) {
Assert(!next->messages.empty());
return next->messages.front().get();
}
}
return nullptr;
}
void Message::clickHandlerActiveChanged(
const ClickHandlerPtr &handler,
bool active) {
if (const auto markup = _data->Get<HistoryMessageReplyMarkup>()) {
if (const auto keyboard = markup->inlineKeyboard.get()) {
keyboard->clickHandlerActiveChanged(handler, active);
}
}
App::hoveredLinkItem(active ? this : nullptr);
Auth().data().requestItemRepaint(_data);
if (const auto media = _data->getMedia()) {
media->clickHandlerActiveChanged(handler, active);
}
}
void Message::clickHandlerPressedChanged(
const ClickHandlerPtr &handler,
bool pressed) {
if (const auto markup = _data->Get<HistoryMessageReplyMarkup>()) {
if (const auto keyboard = markup->inlineKeyboard.get()) {
keyboard->clickHandlerPressedChanged(handler, pressed);
}
}
App::pressedLinkItem(pressed ? this : nullptr);
Auth().data().requestItemRepaint(_data);
if (const auto media = _data->getMedia()) {
media->clickHandlerPressedChanged(handler, pressed);
}
}
Message::~Message() {
App::messageViewDestroyed(this);
not_null<HistoryMessage*> Message::message() const {
return static_cast<HistoryMessage*>(data().get());
}
} // namespace HistoryView

View file

@ -7,71 +7,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
class HistoryItem;
#include "history/view/history_view_element.h"
class HistoryMessage;
namespace HistoryView {
enum class Context : char {
History,
Feed,
AdminLog
};
class Message
: public RuntimeComposer
, public ClickHandlerHost {
class Message : public Element {
public:
Message(not_null<HistoryItem*> data, Context context);
not_null<HistoryItem*> data() const;
int y() const {
return _y;
}
void setY(int y) {
_y = y;
}
HistoryBlock *block() {
return _block;
}
const HistoryBlock *block() const {
return _block;
}
void attachToBlock(not_null<HistoryBlock*> block, int index);
void removeFromBlock();
void setIndexInBlock(int index) {
Expects(_block != nullptr);
Expects(index >= 0);
_indexInBlock = index;
}
int indexInBlock() const {
Expects((_indexInBlock >= 0) == (_block != nullptr));
Expects((_block == nullptr) || (_block->messages[_indexInBlock].get() == this));
return _indexInBlock;
}
Message *previousInBlocks() const;
Message *nextInBlocks() const;
// ClickHandlerHost interface
void clickHandlerActiveChanged(
const ClickHandlerPtr &handler,
bool active) override;
void clickHandlerPressedChanged(
const ClickHandlerPtr &handler,
bool pressed) override;
~Message();
Message(not_null<HistoryMessage*> data, Context context);
private:
const not_null<HistoryItem*> _data;
int _y = 0;
Context _context;
HistoryBlock *_block = nullptr;
int _indexInBlock = -1;
not_null<HistoryMessage*> message() const;
};

View file

@ -171,6 +171,14 @@ void paintPreparedDate(Painter &p, const QString &dateText, int dateTextWidth, i
} // namepsace
Service::Service(not_null<HistoryService*> data, Context context)
: Element(data, context) {
}
not_null<HistoryService*> Service::message() const {
return static_cast<HistoryService*>(data().get());
}
int WideChatWidth() {
return st::msgMaxWidth + 2 * st::msgPhotoSkip + 2 * st::msgMargin.left();
}

View file

@ -7,10 +7,21 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "history/view/history_view_element.h"
class HistoryService;
namespace HistoryView {
class Service : public Element {
public:
Service(not_null<HistoryService*> data, Context context);
private:
not_null<HistoryService*> message() const;
};
int WideChatWidth();
struct PaintContext {

View file

@ -11,6 +11,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <rpl/event_stream.h>
#include "window/section_widget.h"
namespace Storage {
enum class SharedMediaType : char;
} // namespace Storage
namespace Ui {
class SettingsSlider;
class FadeShadow;

View file

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/rp_widget.h"
#include "info/media/info_media_widget.h"
#include "data/data_shared_media.h"
#include "history/view/history_view_cursor_state.h"
namespace Ui {
class PopupMenu;

View file

@ -17,6 +17,10 @@ template <typename Widget>
class SlideWrap;
} // namespace Ui
namespace Storage {
enum class SharedMediaType : char;
} // namespace Storage
namespace Info {
namespace Profile {

View file

@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "media/media_clip_reader.h"
#include "media/player/media_player_instance.h"
#include "history/history_location_manager.h"
#include "history/view/history_view_cursor_state.h"
#include "storage/localstorage.h"
#include "auth_session.h"
#include "lang/lang_keys.h"

View file

@ -27,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/scroll_area.h"
#include "ui/widgets/labels.h"
#include "observer_peer.h"
#include "history/view/history_view_cursor_state.h"
namespace InlineBots {
namespace Layout {

View file

@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/confirm_box.h"
#include "media/media_audio.h"
#include "storage/localstorage.h"
#include "history/view/history_view_cursor_state.h"
QString formatSizeText(qint64 size) {
if (size >= 1024 * 1024) { // more than 1 mb
@ -221,3 +222,15 @@ msp mst paf pif ps1 reg rgs sct shb shs u3p vb vbe vbs vbscript ws wsf\
auto lastDotIndex = filename.lastIndexOf('.');
return (lastDotIndex >= 0) && (executableTypes->indexOf(filename.mid(lastDotIndex + 1).toLower()) >= 0);
}
[[nodiscard]] HistoryTextState LayoutItemBase::getState(
QPoint point,
HistoryStateRequest request) const {
return {};
}
[[nodiscard]] TextSelection LayoutItemBase::adjustSelection(
TextSelection selection,
TextSelectType type) const {
return selection;
}

View file

@ -9,6 +9,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/runtime_composer.h"
struct HistoryTextState;
struct HistoryStateRequest;
constexpr auto FullSelection = TextSelection { 0xFFFF, 0xFFFF };
inline bool IsSubGroupSelection(TextSelection selection) {
@ -45,42 +48,6 @@ inline bool IsGroupItemSelection(
: selection;
}
enum RoundCorners {
SmallMaskCorners = 0x00, // for images
LargeMaskCorners,
BoxCorners,
MenuCorners,
BotKbOverCorners,
StickerCorners,
StickerSelectedCorners,
SelectedOverlaySmallCorners,
SelectedOverlayLargeCorners,
DateCorners,
DateSelectedCorners,
ForwardCorners,
MediaviewSaveCorners,
EmojiHoverCorners,
StickerHoverCorners,
BotKeyboardCorners,
PhotoSelectOverlayCorners,
Doc1Corners,
Doc2Corners,
Doc3Corners,
Doc4Corners,
InShadowCorners, // for photos without bg
InSelectedShadowCorners,
MessageInCorners, // with shadow
MessageInSelectedCorners,
MessageOutCorners,
MessageOutSelectedCorners,
RoundCornersCount
};
static const int32 FileStatusSizeReady = 0x7FFFFFF0;
static const int32 FileStatusSizeLoaded = 0x7FFFFFF1;
static const int32 FileStatusSizeFailed = 0x7FFFFFF2;
@ -133,15 +100,11 @@ public:
}
[[nodiscard]] virtual HistoryTextState getState(
QPoint point,
HistoryStateRequest request) const {
return {};
}
QPoint point,
HistoryStateRequest request) const;
[[nodiscard]] virtual TextSelection adjustSelection(
TextSelection selection,
TextSelectType type) const {
return selection;
}
TextSelection selection,
TextSelectType type) const;
int width() const {
return _width;

View file

@ -39,7 +39,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_message.h"
#include "history/history_media.h"
#include "history/view/history_view_service_message.h"
#include "history/view/history_view_message.h"
#include "history/view/history_view_element.h"
#include "lang/lang_keys.h"
#include "lang/lang_cloud_manager.h"
#include "boxes/add_contact_box.h"

View file

@ -894,10 +894,6 @@ void MainWindow::onClearFailed(int task, void *manager) {
emit tempDirClearFailed(task);
}
void MainWindow::app_activateClickHandler(ClickHandlerPtr handler, Qt::MouseButton button) {
handler->onClick(button);
}
void MainWindow::placeSmallCounter(QImage &img, int size, int count, style::color bg, const QPoint &shift, style::color color) {
QPainter p(&img);

View file

@ -168,8 +168,6 @@ public slots:
void onShowNewChannel();
void onLogout();
void app_activateClickHandler(ClickHandlerPtr handler, Qt::MouseButton button);
signals:
void tempDirCleared(int task);
void tempDirClearFailed(int task);

View file

@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "media/player/media_player_volume_controller.h"
#include "styles/style_media_player.h"
#include "styles/style_mediaview.h"
#include "layout.h"
namespace Media {
namespace Player {

View file

@ -21,6 +21,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "media/player/media_player_volume_controller.h"
#include "styles/style_media_player.h"
#include "styles/style_mediaview.h"
#include "history/history_item.h"
#include "layout.h"
namespace Media {
namespace Player {

View file

@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/effects/fade_animation.h"
#include "ui/widgets/buttons.h"
#include "media/media_audio.h"
#include "layout.h"
namespace Media {
namespace Clip {

View file

@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "observer_peer.h"
#include "auth_session.h"
#include "messenger.h"
#include "layout.h"
#include "storage/file_download.h"
#include "calls/calls_instance.h"
#include "styles/style_mediaview.h"

View file

@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "media/media_audio.h"
#include "media/player/media_player_instance.h"
#include "storage/localstorage.h"
#include "history/history_item.h"
#include "history/history_media_types.h"
#include "history/history_item_components.h"
#include "ui/effects/round_checkbox.h"
@ -114,6 +115,11 @@ void Checkbox::startAnimation() {
_pression.start(_updateCallback, showPressed ? 0. : 1., showPressed ? 1. : 0., st::overviewCheck.duration);
}
MsgId AbstractItem::msgId() const {
auto item = getItem();
return item ? item->id : 0;
}
ItemBase::ItemBase(not_null<HistoryItem*> parent) : _parent(parent) {
}

View file

@ -12,6 +12,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/effects/radial_animation.h"
#include "styles/style_overview.h"
struct HistoryTextState;
struct HistoryStateRequest;
namespace style {
struct RoundCheckbox;
} // namespace style
@ -47,10 +50,7 @@ public:
virtual DocumentData *getDocument() const {
return nullptr;
}
MsgId msgId() const {
auto item = getItem();
return item ? item->id : 0;
}
MsgId msgId() const;
virtual void invalidateCache() {
}

View file

@ -14,6 +14,7 @@ QString findValidCode(QString fullCode);
namespace Ui {
class MultiSelect;
class RippleAnimation;
} // namespace Ui
class CountryInput : public TWidget {

View file

@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/localstorage.h"
#include "platform/platform_specific.h"
#include "auth_session.h"
#include "history/history_item.h"
namespace Images {
namespace {

View file

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/text_options.h"
#include "styles/style_window.h"
#include "history/history_item.h"
namespace Ui {
namespace {

View file

@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "styles/style_window.h"
#include "storage/file_download.h"
#include "auth_session.h"
#include "history/history_item.h"
#include "platform/platform_specific.h"
namespace Window {
@ -63,6 +64,16 @@ Manager::Manager(System *system) : Notifications::Manager(system) {
_inputCheckTimer.setTimeoutHandler([this] { checkLastInput(); });
}
Manager::QueuedNotification::QueuedNotification(
not_null<HistoryItem*> item
, int forwardedCount)
: history(item->history())
, peer(history->peer)
, author((!peer->isUser() && !item->isPost()) ? item->author() : nullptr)
, item((forwardedCount < 2) ? item.get() : nullptr)
, forwardedCount(forwardedCount) {
}
QPixmap Manager::hiddenUserpicPlaceholder() const {
if (_hiddenUserpicPlaceholder.isNull()) {
_hiddenUserpicPlaceholder = App::pixmapFromImageInPlace(Messenger::Instance().logoNoMargin().scaled(st::notifyPhotoSize, st::notifyPhotoSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));

View file

@ -82,16 +82,10 @@ private:
SingleTimer _inputCheckTimer;
struct QueuedNotification {
QueuedNotification(HistoryItem *item, int forwardedCount)
: history(item->history())
, peer(history->peer)
, author((!peer->isUser() && !item->isPost()) ? item->author() : nullptr)
, item((forwardedCount > 1) ? nullptr : item)
, forwardedCount(forwardedCount) {
}
QueuedNotification(not_null<HistoryItem*> item, int forwardedCount);
History *history;
PeerData *peer;
not_null<History*> history;
not_null<PeerData*> peer;
PeerData *author;
HistoryItem *item;
int forwardedCount;

View file

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/themes/window_theme.h"
#include "window/themes/window_theme_editor_block.h"
#include "mainwindow.h"
#include "layout.h"
#include "storage/localstorage.h"
#include "boxes/confirm_box.h"
#include "styles/style_window.h"

View file

@ -9,7 +9,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/main_window.h"
#include "info/info_memento.h"
#include "history/view/history_view_element.h"
#include "history/view/history_view_message.h"
#include "history/view/history_view_service_message.h"
#include "history/history_item.h"
#include "mainwidget.h"
#include "mainwindow.h"
#include "styles/style_window.h"
@ -403,4 +406,16 @@ not_null<MainWidget*> Controller::chats() const {
return App::wnd()->chatsWidget();
}
std::unique_ptr<HistoryView::Element> Controller::createMessageView(
not_null<HistoryMessage*> message,
HistoryView::Context context) {
return std::make_unique<HistoryView::Message>(message, context);
}
std::unique_ptr<HistoryView::Element> Controller::createMessageView(
not_null<HistoryService*> message,
HistoryView::Context context) {
return std::make_unique<HistoryView::Service>(message, context);
}
} // namespace Window

View file

@ -11,6 +11,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/flags.h"
class MainWidget;
class HistoryMessage;
class HistoryService;
namespace HistoryView {
enum class Context : char;
} // namespace HistoryView
namespace Window {
@ -195,6 +201,13 @@ public:
return this;
}
std::unique_ptr<HistoryView::Element> createMessageView(
not_null<HistoryMessage*> message,
HistoryView::Context context);
std::unique_ptr<HistoryView::Element> createMessageView(
not_null<HistoryService*> message,
HistoryView::Context context);
private:
int minimalThreeColumnWidth() const;
not_null<MainWidget*> chats() const;

View file

@ -225,6 +225,10 @@
<(src_loc)/history/admin_log/history_admin_log_section.h
<(src_loc)/history/feed/history_feed_section.cpp
<(src_loc)/history/feed/history_feed_section.h
<(src_loc)/history/view/history_view_cursor_state.cpp
<(src_loc)/history/view/history_view_cursor_state.h
<(src_loc)/history/view/history_view_element.cpp
<(src_loc)/history/view/history_view_element.h
<(src_loc)/history/view/history_view_list_widget.cpp
<(src_loc)/history/view/history_view_list_widget.h
<(src_loc)/history/view/history_view_message.cpp
@ -249,6 +253,8 @@
<(src_loc)/history/history_media.cpp
<(src_loc)/history/history_media_grouped.h
<(src_loc)/history/history_media_grouped.cpp
<(src_loc)/history/history_media_pointer.h
<(src_loc)/history/history_media_pointer.cpp
<(src_loc)/history/history_media_types.cpp
<(src_loc)/history/history_media_types.h
<(src_loc)/history/history_message.cpp