#include "columnhandleitem.h"
#include "contextmenuactionprovider.h"
#include "iconloader.h"
+#include "mainwin.h"
+#include "markerlineitem.h"
#include "messagefilter.h"
#include "qtui.h"
#include "qtuistyle.h"
_sceneRect(0, 0, width, 0),
_firstLineRow(-1),
_viewportHeight(0),
+ _markerLine(new MarkerLineItem(width)),
+ _markerLineValid(false),
+ _markerLineVisible(false),
_cutoffMode(CutoffRight),
_selectingItem(0),
_selectionStart(-1),
_singleBufferId = filter->singleBufferId();
}
+ addItem(_markerLine);
+ connect(this, SIGNAL(sceneRectChanged(const QRectF &)), _markerLine, SLOT(sceneRectChanged(const QRectF &)));
+
ChatViewSettings defaultSettings;
int defaultFirstColHandlePos = defaultSettings.value("FirstColumnHandlePos", 80).toInt();
int defaultSecondColHandlePos = defaultSettings.value("SecondColumnHandlePos", 200).toInt();
this, SLOT(rowsInserted(const QModelIndex &, int, int)));
connect(model, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)),
this, SLOT(rowsAboutToBeRemoved(const QModelIndex &, int, int)));
+ connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
+ this, SLOT(rowsRemoved()));
connect(model, SIGNAL(dataChanged(QModelIndex, QModelIndex)), SLOT(dataChanged(QModelIndex, QModelIndex)));
#ifdef HAVE_WEBKIT
return _secondColHandle;
}
+ChatLine *ChatScene::chatLine(MsgId msgId, bool matchExact) const {
+ if(!_lines.count())
+ return 0;
+
+ QList<ChatLine*>::ConstIterator start = _lines.begin();
+ QList<ChatLine*>::ConstIterator end = _lines.end();
+ QList<ChatLine*>::ConstIterator middle;
+
+ int n = int(end - start);
+ int half;
+
+ while(n > 0) {
+ half = n >> 1;
+ middle = start + half;
+ if((*middle)->msgId() < msgId) {
+ start = middle + 1;
+ n -= half + 1;
+ } else {
+ n = half;
+ }
+ }
+
+ if(start != end && (*start)->msgId() == msgId)
+ return *start;
+
+ if(matchExact)
+ return 0;
+
+ // if we didn't find the exact msgId, take the next-lower one (this makes sense for lastSeen)
+ if(start == end) // higher than last element
+ return _lines.last();
+
+ if(start == _lines.begin()) // not (yet?) in our scene
+ return 0;
+
+ // return the next-lower line
+ return *(--start);
+}
+
ChatItem *ChatScene::chatItemAt(const QPointF &scenePos) const {
ChatLine *line = qgraphicsitem_cast<ChatLine*>(itemAt(scenePos));
if(line)
return false;
}
+void ChatScene::setMarkerLineVisible(bool visible) {
+ _markerLineVisible = visible;
+ if(visible && _markerLineValid)
+ _markerLine->setVisible(true);
+ else
+ _markerLine->setVisible(false);
+}
+
+void ChatScene::setMarkerLine(MsgId msgId) {
+ if(msgId.isValid()) {
+ ChatLine *line = chatLine(msgId, false);
+ if(line) {
+ // if this was the last line, we won't see it because it's outside the sceneRect
+ // .. which is exactly what we want :)
+ _markerLine->setPos(line->pos() + QPointF(0, line->height()));
+
+ // DayChange messages might have been hidden outside the scene rect, don't make the markerline visible then!
+ if(_markerLine->pos().y() >= sceneRect().y()) {
+ _markerLineValid = true;
+ if(_markerLineVisible)
+ _markerLine->setVisible(true);
+ return;
+ }
+ }
+ }
+ _markerLineValid = false;
+ _markerLine->setVisible(false);
+}
+
void ChatScene::rowsInserted(const QModelIndex &index, int start, int end) {
Q_UNUSED(index);
if(atBottom) {
emit lastLineChanged(_lines.last(), h);
}
+
+ // now move the marker line if necessary. we don't need to do anything if we appended lines though...
+ if(isSingleBufferScene()) {
+ if(!_markerLineValid || !atBottom) {
+ MsgId msgId = Client::markerLine(singleBufferId());
+ setMarkerLine(msgId);
+ }
+ }
}
void ChatScene::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) {
updateSceneRect();
}
+void ChatScene::rowsRemoved() {
+ // move the marker line if necessary
+ if(isSingleBufferScene()) {
+ MsgId msgId = Client::markerLine(singleBufferId());
+ setMarkerLine(msgId);
+ }
+}
+
void ChatScene::dataChanged(const QModelIndex &tl, const QModelIndex &br) {
layout(tl.row(), br.row(), _sceneRect.width());
}
void ChatScene::setHandleXLimits() {
_firstColHandle->setXLimits(0, _secondColHandle->sceneLeft());
_secondColHandle->setXLimits(_firstColHandle->sceneRight(), width() - minContentsWidth);
+ update();
}
void ChatScene::setSelectingItem(ChatItem *item) {