X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fqtui%2Fchatitem.cpp;h=c40fd34b96b687fba09b544763c9dbf4580a6226;hp=499ae7740b580e5c31a48ced0ab20b579034d5ba;hb=5bc6dee39199868071a4926ae9859daa587537f7;hpb=55579f53f3bd37f2a20d9be7458bdc54b345a052 diff --git a/src/qtui/chatitem.cpp b/src/qtui/chatitem.cpp index 499ae774..c40fd34b 100644 --- a/src/qtui/chatitem.cpp +++ b/src/qtui/chatitem.cpp @@ -426,7 +426,8 @@ qreal ContentsChatItem::setGeometryByWidth(qreal w) { WrapColumnFinder finder(this); while(finder.nextWrapColumn(w) > 0) lines++; - qreal h = lines * fontMetrics()->lineSpacing(); + qreal spacing = qMax(fontMetrics()->lineSpacing(), fontMetrics()->height()); // cope with negative leading() + qreal h = lines * spacing; delete _data; _data = 0; @@ -438,10 +439,12 @@ qreal ContentsChatItem::setGeometryByWidth(qreal w) { } void ContentsChatItem::doLayout(QTextLayout *layout) const { + // QString t = data(Qt::DisplayRole).toString(); bool d = t.contains("protien"); ChatLineModel::WrapList wrapList = data(ChatLineModel::WrapListRole).value(); if(!wrapList.count()) return; // empty chatitem qreal h = 0; + qreal spacing = qMax(fontMetrics()->lineSpacing(), fontMetrics()->height()); // cope with negative leading() WrapColumnFinder finder(this); layout->beginLayout(); forever { @@ -450,21 +453,31 @@ void ContentsChatItem::doLayout(QTextLayout *layout) const { break; int col = finder.nextWrapColumn(width()); - line.setNumColumns(col >= 0 ? col - line.textStart() : layout->text().length()); + if(col < 0) + col = layout->text().length(); + int num = col - line.textStart(); + + line.setNumColumns(num); + + // Sometimes, setNumColumns will create a line that's too long (cf. Qt bug 238249) + // We verify this and try setting the width again, making it shorter each time until the lengths match. + // Dead fugly, but seems to work… + for(int i = line.textLength()-1; i >= 0 && line.textLength() > num; i--) { + line.setNumColumns(i); + } + if(num != line.textLength()) { + qWarning() << "WARNING: Layout engine couldn't workaround Qt bug 238249, please report!"; + // qDebug() << num << line.textLength() << t.mid(line.textStart(), line.textLength()) << t.mid(line.textStart() + line.textLength()); + } + line.setPosition(QPointF(0, h)); - h += fontMetrics()->lineSpacing(); + h += spacing; } layout->endLayout(); } Clickable ContentsChatItem::clickableAt(const QPointF &pos) const { - qint16 idx = posToCursor(pos); - for(int i = 0; i < privateData()->clickables.count(); i++) { - Clickable click = privateData()->clickables.at(i); - if(idx >= click.start() && idx < click.start() + click.length()) - return click; - } - return Clickable(); + return privateData()->clickables.atCursorPos(posToCursor(pos)); } UiStyle::FormatList ContentsChatItem::formatList() const { @@ -505,30 +518,12 @@ void ContentsChatItem::endHoverMode() { void ContentsChatItem::handleClick(const QPointF &pos, ChatScene::ClickMode clickMode) { if(clickMode == ChatScene::SingleClick) { - Clickable click = clickableAt(pos); - if(click.isValid()) { - QString str = data(ChatLineModel::DisplayRole).toString().mid(click.start(), click.length()); - switch(click.type()) { - case Clickable::Url: - if(!str.contains("://")) - str = "http://" + str; - QDesktopServices::openUrl(QUrl::fromEncoded(str.toUtf8(), QUrl::TolerantMode)); - break; - case Clickable::Channel: { - NetworkId networkId = Client::networkModel()->networkId(data(MessageModel::BufferIdRole).value()); - BufferId bufId = Client::networkModel()->bufferId(networkId, str); - if(bufId.isValid()) { - QModelIndex targetIdx = Client::networkModel()->bufferIndex(bufId); - Client::bufferModel()->switchToBuffer(bufId); - if(!targetIdx.data(NetworkModel::ItemActiveRole).toBool()) - Client::userInput(BufferInfo::fakeStatusBuffer(networkId), QString("/JOIN %1").arg(str)); - } else - Client::userInput(BufferInfo::fakeStatusBuffer(networkId), QString("/JOIN %1").arg(str)); - break; - } - default: - break; - } + qint16 idx = posToCursor(pos); + Clickable foo = privateData()->clickables.atCursorPos(idx); + if(foo.isValid()) { + NetworkId networkId = Client::networkModel()->networkId(data(MessageModel::BufferIdRole).value()); + QString text = data(ChatLineModel::DisplayRole).toString(); + foo.activate(networkId, text); } } else if(clickMode == ChatScene::DoubleClick) { chatScene()->setSelectingItem(this); @@ -643,9 +638,10 @@ void ContentsChatItem::showWebPreview(const Clickable &click) { QPointF topLeft = scenePos() + QPointF(x, y); QRectF urlRect = QRectF(topLeft.x(), topLeft.y(), width, height); - QString url = data(ChatLineModel::DisplayRole).toString().mid(click.start(), click.length()); - if(!url.contains("://")) - url = "http://" + url; + QString urlstr = data(ChatLineModel::DisplayRole).toString().mid(click.start(), click.length()); + if(!urlstr.contains("://")) + urlstr= "http://" + urlstr; + QUrl url = QUrl::fromEncoded(urlstr.toUtf8(), QUrl::TolerantMode); chatScene()->loadWebPreview(this, url, urlRect); #endif }