}
AbstractChatView *BufferWidget::createChatView(BufferId id) {
- QWidget *chatView;
+ ChatView *chatView;
chatView = new ChatView(Client::buffer(id), this);
_chatViews[id] = chatView;
ui.stackedWidget->addWidget(chatView);
chatView->setFocusProxy(this);
- return dynamic_cast<AbstractChatView*>(chatView);
+ chatView->setBufferForBacklogFetching(id);
+ return chatView;
}
void BufferWidget::removeChatView(BufferId id) {
#include "chatline.h"
#include "chatlinemodelitem.h"
#include "chatscene.h"
+#include "client.h"
+#include "clientbacklogmanager.h"
#include "columnhandleitem.h"
#include "qtui.h"
#include "qtuisettings.h"
_selectingItem = 0;
_isSelecting = false;
_selectionStart = -1;
+ _fetchingBacklog = false;
+
connect(this, SIGNAL(sceneRectChanged(const QRectF &)), this, SLOT(rectChanged(const QRectF &)));
connect(model, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(rowsInserted(const QModelIndex &, int, int)));
for(int i = end+1; i < _lines.count(); i++) {
_lines[i]->setRow(i);
}
-
+
if(h > 0) {
_height += h;
for(int i = end+1; i < _lines.count(); i++) {
setSceneRect(QRectF(0, 0, _width, _height));
emit heightChanged(_height);
}
+
+ requestBacklogIfNeeded();
}
void ChatScene::modelReset() {
}
return result;
}
+
+void ChatScene::setIsFetchingBacklog(bool fetch) {
+ if(!isBacklogFetchingEnabled()) return;
+
+ if(!fetch) {
+ _fetchingBacklog = false;
+ } else {
+ _fetchingBacklog = true;
+ requestBacklogIfNeeded();
+ }
+}
+
+void ChatScene::requestBacklogIfNeeded() {
+ const int REQUEST_COUNT = 50;
+
+ if(!isBacklogFetchingEnabled() || !isFetchingBacklog() || !model()->rowCount()) return;
+
+ MsgId msgId = model()->data(model()->index(0, 0), ChatLineModel::MsgIdRole).value<MsgId>();
+ if(!_lastBacklogOffset.isValid() || (msgId < _lastBacklogOffset && _lastBacklogSize + REQUEST_COUNT <= model()->rowCount())) {
+ Client::backlogManager()->requestBacklog(bufferForBacklogFetching(), REQUEST_COUNT, msgId.toInt());
+ _lastBacklogOffset = msgId;
+ _lastBacklogSize = model()->rowCount();
+ }
+}
#include <QGraphicsScene>
#include <QSet>
+#include "types.h"
+
class AbstractUiMsg;
class Buffer;
+class BufferId;
class ChatItem;
class ChatLine;
class ColumnHandleItem;
ChatScene(QAbstractItemModel *model, const QString &idString, QObject *parent);
virtual ~ChatScene();
- Buffer *buffer() const;
inline QAbstractItemModel *model() const { return _model; }
inline QString idString() const { return _idString; }
+ inline bool isFetchingBacklog() const;
+ inline bool isBacklogFetchingEnabled() const;
+ inline BufferId bufferForBacklogFetching() const;
+
public slots:
void setWidth(qreal);
ChatItem *selectingItem() const { return _selectingItem; }
void startGlobalSelection(ChatItem *item, const QPointF &itemPos);
+ void setIsFetchingBacklog(bool);
+ inline void setBufferForBacklogFetching(BufferId buffer);
+
signals:
void heightChanged(qreal height);
private:
void updateSelection(const QPointF &pos);
QString selectionToString() const;
+ void requestBacklogIfNeeded();
QString _idString;
qreal _width, _height;
int _selectionStart;
int _selectionEnd;
bool _isSelecting;
+
+ bool _fetchingBacklog;
+ BufferId _backlogFetchingBuffer;
+ MsgId _lastBacklogOffset;
+ int _lastBacklogSize;
};
+bool ChatScene::isFetchingBacklog() const {
+ return _fetchingBacklog;
+}
+
+bool ChatScene::isBacklogFetchingEnabled() const {
+ return _backlogFetchingBuffer.isValid();
+}
+
+BufferId ChatScene::bufferForBacklogFetching() const {
+ return _backlogFetchingBuffer;
+}
+
+void ChatScene::setBufferForBacklogFetching(BufferId buf) {
+ _backlogFetchingBuffer = buf;
+}
+
#endif
_scene = new ChatScene(filter, filter->idString(), this);
connect(_scene, SIGNAL(heightChanged(qreal)), this, SLOT(sceneHeightChanged(qreal)));
setScene(_scene);
+
+ connect(verticalScrollBar(), SIGNAL(sliderPressed()), this, SLOT(sliderPressed()));
+ connect(verticalScrollBar(), SIGNAL(sliderReleased()), this, SLOT(sliderReleased()));
+ connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(verticalScrollbarChanged(int)));
}
ChatView::~ChatView() {
}
-
ChatScene *ChatView::scene() const {
return _scene;
}
+void ChatView::clear() {
+
+}
+
void ChatView::resizeEvent(QResizeEvent *event) {
scene()->setWidth(event->size().width() - 2); // FIXME figure out why we have to hardcode the -2 here
verticalScrollBar()->setValue(verticalScrollBar()->maximum());
if(scrollable) verticalScrollBar()->setValue(verticalScrollBar()->maximum());
}
-void ChatView::clear()
-{
+void ChatView::setBufferForBacklogFetching(BufferId id) {
+ scene()->setBufferForBacklogFetching(id);
+}
+
+void ChatView::sliderPressed() {
+ verticalScrollbarChanged(verticalScrollBar()->value());
+}
+
+void ChatView::sliderReleased() {
+ if(scene()->isFetchingBacklog()) scene()->setIsFetchingBacklog(false);
+}
+
+void ChatView::verticalScrollbarChanged(int newPos) {
+ Q_UNUSED(newPos);
+ if(!scene()->isBacklogFetchingEnabled()) return;
+
+ QAbstractSlider *vbar = verticalScrollBar();
+ if(!vbar)
+ return;
+ if(vbar->isSliderDown()) {
+ /*
+ int relativePos = 100;
+ if(vbar->maximum() - vbar->minimum() != 0)
+ relativePos = (newPos - vbar->minimum()) * 100 / (vbar->maximum() - vbar->minimum());
+ scene()->setIsFetchingBacklog(relativePos < 20);
+ */
+ scene()->setIsFetchingBacklog(vbar->value() == vbar->minimum());
+ }
}
void clear();
+ void setBufferForBacklogFetching(BufferId buffer);
+
protected:
virtual void resizeEvent(QResizeEvent *event);
protected slots:
virtual void sceneHeightChanged(qreal height);
+ virtual void verticalScrollbarChanged(int);
+ virtual void sliderPressed();
+ virtual void sliderReleased();
private:
void init(MessageFilter *filter);
ChatScene *_scene;
};
+
#endif