#include "chatline-old.h"
#include "qtui.h"
#include "uisettings.h"
-
-ChatWidget::ChatWidget(QWidget *parent) : QAbstractScrollArea(parent) {
+#include "client.h"
+#include "buffer.h"
+#include "clientbacklogmanager.h"
+
+ChatWidget::ChatWidget(BufferId bufid, QWidget *parent) : QAbstractScrollArea(parent), AbstractChatView(),
+ lastBacklogOffset(0),
+ lastBacklogSize(0)
+{
//setAutoFillBackground(false);
//QPalette palette;
//palette.setColor(backgroundRole(), QColor(0, 0, 0, 50));
scrollTimer = new QTimer(this);
scrollTimer->setSingleShot(false);
scrollTimer->setInterval(100);
+ // setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
- setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
- setMinimumSize(QSize(400,400));
+ setMinimumSize(QSize(20,20));
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
bottomLine = -1;
pointerPosition = QPoint(0,0);
connect(verticalScrollBar(), SIGNAL(actionTriggered(int)), this, SLOT(scrollBarAction(int)));
connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(scrollBarValChanged(int)));
+
+ init(bufid);
}
void ChatWidget::init(BufferId id) {
UiSettings s;
QVariant tsDef = s.value("DefaultTimestampColumnWidth", 90);
QVariant senderDef = s.value("DefaultSenderColumnWidth", 100);
- tsWidth = s.value(QString("%1/TimestampColumnWidth").arg(bufferId), tsDef).toInt();
- senderWidth = s.value(QString("%1/SenderColumnWidth").arg(bufferId), senderDef).toInt();
+ tsWidth = s.value(QString("%1/TimestampColumnWidth").arg(bufferId.toInt()), tsDef).toInt();
+ senderWidth = s.value(QString("%1/SenderColumnWidth").arg(bufferId.toInt()), senderDef).toInt();
computePositions();
adjustScrollBar();
verticalScrollBar()->setValue(verticalScrollBar()->maximum());
//verticalScrollBar()->setMinimum(0);
//verticalScrollBar()->setMaximum((int)height - verticalScrollBar()->pageStep());
- setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ // setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
setMouseTracking(true);
mouseMode = Normal;
selectionMode = NoSelection;
connect(scrollTimer, SIGNAL(timeout()), this, SLOT(handleScrollTimer()));
+
+ if(bufferId.isValid())
+ connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(viewportChanged(int)));
}
ChatWidget::~ChatWidget() {
//qDebug() << "destroying chatwidget" << bufferName;
- //foreach(ChatLine *l, lines) {
+ //foreach(ChatLineOld *l, lines) {
// delete l;
//}
UiSettings s;
s.setValue("DefaultTimestampColumnWidth", tsWidth); // FIXME stupid dirty quicky
s.setValue("DefaultSenderColumnWidth", senderWidth);
- s.setValue(QString("%1/TimestampColumnWidth").arg(bufferId), tsWidth);
- s.setValue(QString("%1/SenderColumnWidth").arg(bufferId), senderWidth);
+ s.setValue(QString("%1/TimestampColumnWidth").arg(bufferId.toInt()), tsWidth);
+ s.setValue(QString("%1/SenderColumnWidth").arg(bufferId.toInt()), senderWidth);
+}
+
+QSize ChatWidget::minimumSizeHint() const {
+ return QSize(20, 20);
}
QSize ChatWidget::sizeHint() const {
- //qDebug() << size();
- return size();
+ return QSize(400, 100);
}
+// QSize ChatWidget::sizeHint() const {
+// //qDebug() << size();
+// return size();
+// }
+
void ChatWidget::adjustScrollBar() {
verticalScrollBar()->setPageStep(viewport()->height());
verticalScrollBar()->setSingleStep(20);
}
void ChatWidget::prependMsg(AbstractUiMsg *msg) {
- ChatLine *line = dynamic_cast<ChatLine*>(msg);
+ ChatLineOld *line = dynamic_cast<ChatLineOld*>(msg);
Q_ASSERT(line);
prependChatLine(line);
}
-void ChatWidget::prependChatLine(ChatLine *line) {
+void ChatWidget::prependChatLine(ChatLineOld *line) {
qreal h = line->layout(tsWidth, senderWidth, textWidth);
for(int i = 1; i < ycoords.count(); i++) ycoords[i] += h;
ycoords.insert(1, h);
viewport()->update();
}
-void ChatWidget::prependChatLines(QList<ChatLine *> clist) {
+void ChatWidget::prependChatLines(QList<ChatLineOld *> clist) {
QList<qreal> tmpy; tmpy.append(0);
qreal h = 0;
- foreach(ChatLine *l, clist) {
+ foreach(ChatLineOld *l, clist) {
h += l->layout(tsWidth, senderWidth, textWidth);
tmpy.append(h);
}
}
void ChatWidget::appendMsg(AbstractUiMsg *msg) {
- ChatLine *line = dynamic_cast<ChatLine*>(msg);
+ ChatLineOld *line = dynamic_cast<ChatLineOld*>(msg);
Q_ASSERT(line);
appendChatLine(line);
}
-void ChatWidget::appendChatLine(ChatLine *line) {
+void ChatWidget::appendChatLine(ChatLineOld *line) {
qreal h = line->layout(tsWidth, senderWidth, textWidth);
ycoords.append(h + ycoords[ycoords.count() - 1]);
height += h;
}
-void ChatWidget::appendChatLines(QList<ChatLine *> list) {
- foreach(ChatLine *line, list) {
+void ChatWidget::appendChatLines(QList<ChatLineOld *> list) {
+ foreach(ChatLineOld *line, list) {
qreal h = line->layout(tsWidth, senderWidth, textWidth);
ycoords.append(h + ycoords[ycoords.count() - 1]);
height += h;
viewport()->update();
}
-void ChatWidget::setContents(QList<ChatLine *> list) {
+void ChatWidget::setContents(const QList<AbstractUiMsg *> &list) {
ycoords.clear();
ycoords.append(0);
height = 0;
lines.clear();
- appendChatLines(list);
+ QList<ChatLineOld *> cl;
+ foreach(AbstractUiMsg *msg, list) cl << dynamic_cast<ChatLineOld *>(msg);
+ appendChatLines(cl);
}
//!\brief Computes the different x position vars for given tsWidth and senderWidth.
/*if(event->oldSize().isValid())*/
//contents->setWidth(event->size().width());
//setAlignment(Qt::AlignBottom);
- if(event->size().width() != event->oldSize().width()) {
+ if(event->size() != event->oldSize()) {
computePositions();
layout();
}
}
}
-void ChatWidget::mouseDoubleClickEvent(QMouseEvent * /*event*/) {
-
+void ChatWidget::mouseDoubleClickEvent(QMouseEvent *event) {
+ // dirty and fast hack to make http:// urls klickable
+ if(lines.isEmpty())
+ return;
+ QPoint pos = event->pos() + QPoint(0, verticalScrollBar()->value());
+ int x = pos.x();
+ int y = pos.y();
+ int l = yToLineIdx(y);
+ if(lines.count() <= l)
+ return;
+
+ ChatLineOld *line = lines[l];
+ QString text = line->text();
+ int cursorAt = qMax(0, line->posToCursor(QPointF(x, y - ycoords[l])) - 1);
+
+ int start = 0;
+ if(cursorAt > 0) {
+ for(int i = cursorAt; i > 0; i--) {
+ if(text[i] == ' ') {
+ start = i + 1;
+ break;
+ }
+ }
+ }
+ int end = text.indexOf(" ", start);
+ int len = -1;
+ if(end != -1) {
+ len = end - start;
+ }
+ QString word = text.mid(start, len);
+ QRegExp regex("^(h|f)t{1,2}ps?:\\/\\/");
+ if(regex.indexIn(word) != -1) {
+ QDesktopServices::openUrl(QUrl(word));
+ }
+
}
void ChatWidget::mouseReleaseEvent(QMouseEvent *event) {
selectionStart = qMin(dragStartCursor, curCursor);
selectionEnd = qMax(dragStartCursor, curCursor);
// TODO Make X11SelectionMode configurable!
+#ifdef Q_WS_X11
+ QApplication::clipboard()->setText(selectionToString(), QClipboard::Selection);
+#else
QApplication::clipboard()->setText(selectionToString());
+#endif
break;
case MarkLines:
mouseMode = Normal;
selectionStart = qMin(dragStartLine, curLine);
selectionEnd = qMax(dragStartLine, curLine);
// TODO Make X11SelectionMode configurable!
+#ifdef Q_WS_X11
+ QApplication::clipboard()->setText(selectionToString(), QClipboard::Selection);
+#endif
+//#else
QApplication::clipboard()->setText(selectionToString());
+//#endif
break;
default:
mouseMode = Normal;
if(curLine == dragStartLine && c >= 0) {
if(c != curCursor) {
curCursor = c;
- lines[curLine]->setSelection(ChatLine::Partial, dragStartCursor, c);
+ lines[curLine]->setSelection(ChatLineOld::Partial, dragStartCursor, c);
viewport()->update();
}
} else {
mouseMode = MarkLines;
selectionStart = qMin(curLine, dragStartLine); selectionEnd = qMax(curLine, dragStartLine);
- for(int i = selectionStart; i <= selectionEnd; i++) lines[i]->setSelection(ChatLine::Full);
+ for(int i = selectionStart; i <= selectionEnd; i++) lines[i]->setSelection(ChatLineOld::Full);
viewport()->update();
}
} else if(mouseMode == MarkLines) {
selectionStart = qMin(l, dragStartLine); selectionEnd = qMax(l, dragStartLine);
if(curLine < 0) {
Q_ASSERT(selectionStart == selectionEnd);
- lines[l]->setSelection(ChatLine::Full);
+ lines[l]->setSelection(ChatLineOld::Full);
} else {
if(curLine < selectionStart) {
- for(int i = curLine; i < selectionStart; i++) lines[i]->setSelection(ChatLine::None);
+ for(int i = curLine; i < selectionStart; i++) lines[i]->setSelection(ChatLineOld::None);
} else if(curLine > selectionEnd) {
- for(int i = selectionEnd+1; i <= curLine; i++) lines[i]->setSelection(ChatLine::None);
+ for(int i = selectionEnd+1; i <= curLine; i++) lines[i]->setSelection(ChatLineOld::None);
} else if(selectionStart < curLine && l < curLine) {
- for(int i = selectionStart; i < curLine; i++) lines[i]->setSelection(ChatLine::Full);
+ for(int i = selectionStart; i < curLine; i++) lines[i]->setSelection(ChatLineOld::Full);
} else if(curLine < selectionEnd && l > curLine) {
- for(int i = curLine+1; i <= selectionEnd; i++) lines[i]->setSelection(ChatLine::Full);
+ for(int i = curLine+1; i <= selectionEnd; i++) lines[i]->setSelection(ChatLineOld::Full);
}
}
curLine = l;
//!\brief Clear current text selection.
void ChatWidget::clearSelection() {
if(selectionMode == TextSelected) {
- lines[selectionLine]->setSelection(ChatLine::None);
+ lines[selectionLine]->setSelection(ChatLineOld::None);
} else if(selectionMode == LinesSelected) {
for(int i = selectionStart; i <= selectionEnd; i++) {
- lines[i]->setSelection(ChatLine::None);
+ lines[i]->setSelection(ChatLineOld::None);
}
}
selectionMode = NoSelection;
return lines[selectionLine]->text().mid(selectionStart, selectionEnd - selectionStart);
}
+void ChatWidget::viewportChanged(int newPos) {
+ const int REQUEST_COUNT = 50;
+ QAbstractSlider *vbar = verticalScrollBar();
+ if(!vbar)
+ return;
+
+ int relativePos = 100;
+ if(vbar->maximum() - vbar->minimum() != 0)
+ relativePos = (newPos - vbar->minimum()) * 100 / (vbar->maximum() - vbar->minimum());
+
+ if(relativePos < 20) {
+ Buffer *buffer = Client::buffer(bufferId);
+ Q_CHECK_PTR(buffer);
+ if(buffer->contents().isEmpty())
+ return;
+ MsgId msgId = buffer->contents().first()->msgId();
+ if(!lastBacklogOffset.isValid() || (msgId < lastBacklogOffset && lastBacklogSize + REQUEST_COUNT <= buffer->contents().count())) {
+ Client::backlogManager()->requestBacklog(bufferId, REQUEST_COUNT, msgId.toInt());
+ lastBacklogOffset = msgId;
+ lastBacklogSize = buffer->contents().size();
+ }
+ }
+}