giving the chatscene more control over the webpreview thus making it less crashy
[quassel.git] / src / qtui / chatitem.cpp
index 261182f..df093d7 100644 (file)
@@ -274,9 +274,7 @@ qreal ContentsChatItem::setGeometryByWidth(qreal w) {
 
 void ContentsChatItem::updateLayout() {
   if(!privateData()) {
-    ContentsChatItemPrivate *data = new ContentsChatItemPrivate(createLayout(QTextOption::WrapAnywhere),
-                                                               findClickables());
-    // data->clickables = findClickables();
+    ContentsChatItemPrivate *data = new ContentsChatItemPrivate(createLayout(QTextOption::WrapAnywhere), findClickables(), this);
     setPrivateData(data);
   }
 
@@ -378,9 +376,12 @@ QVector<QTextLayout::FormatRange> ContentsChatItem::additionalFormats() const {
 }
 
 void ContentsChatItem::endHoverMode() {
-  if(privateData()->currentClickable.isValid()) {
-    setCursor(Qt::ArrowCursor);
-    privateData()->currentClickable = Clickable();
+  if(hasLayout()) {
+    if(privateData()->currentClickable.isValid()) {
+      setCursor(Qt::ArrowCursor);
+      privateData()->currentClickable = Clickable();
+    }
+    clearWebPreview();
     update();
   }
 }
@@ -398,6 +399,8 @@ void ContentsChatItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
       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(str);
           break;
         case Clickable::Channel:
@@ -415,7 +418,7 @@ void ContentsChatItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
   // mouse move events always mean we're not hovering anymore...
   endHoverMode();
   // also, check if we have dragged the mouse
-  if(!privateData()->hasDragged && event->buttons() & Qt::LeftButton
+  if(hasLayout() && !privateData()->hasDragged && event->buttons() & Qt::LeftButton
     && (event->buttonDownScreenPos(Qt::LeftButton) - event->screenPos()).manhattanLength() >= QApplication::startDragDistance())
     privateData()->hasDragged = true;
   ChatItem::mouseMoveEvent(event);
@@ -432,9 +435,10 @@ void ContentsChatItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) {
   for(int i = 0; i < privateData()->clickables.count(); i++) {
     Clickable click = privateData()->clickables.at(i);
     if(idx >= click.start && idx < click.start + click.length) {
-      if(click.type == Clickable::Url)
+      if(click.type == Clickable::Url) {
         onClickable = true;
-      else if(click.type == Clickable::Channel) {
+       showWebPreview(click);
+      } else if(click.type == Clickable::Channel) {
         // TODO: don't make clickable if it's our own name
         //onClickable = true; //FIXME disabled for now
       }
@@ -450,6 +454,33 @@ void ContentsChatItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) {
   event->accept();
 }
 
+void ContentsChatItem::showWebPreview(const Clickable &click) {
+#ifdef HAVE_WEBKIT
+  if(!hasLayout())
+    updateLayout();
+
+  QTextLine line = layout()->lineForTextPosition(click.start);
+  qreal x = line.cursorToX(click.start);
+  qreal width = line.cursorToX(click.start + click.length) - x;
+  qreal height = line.height();
+  qreal y = height * line.lineNumber();
+
+  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;
+  chatScene()->loadWebPreview(this, url, urlRect);
+#endif
+}
+
+void ContentsChatItem::clearWebPreview() {
+#ifdef HAVE_WEBKIT
+  chatScene()->clearWebPreview(this);
+#endif
+}
+
 /*************************************************************************************************/
 
 ContentsChatItem::WrapColumnFinder::WrapColumnFinder(ChatItem *_item)
@@ -459,9 +490,6 @@ ContentsChatItem::WrapColumnFinder::WrapColumnFinder(ChatItem *_item)
     wordidx(0),
     lineCount(0),
     choppedTrailing(0)
-//     lastwrapcol(0),
-//     lastwrappos(0),
-//     width(0)
 {
 }
 
@@ -508,7 +536,7 @@ qint16 ContentsChatItem::WrapColumnFinder::nextWrapColumn() {
     }
 
     qint16 pivot = (end + start) / 2;
-    if(wrapList.at(pivot).endX > targetWidth && wordidx != pivot) {
+    if(wrapList.at(pivot).endX > targetWidth) {
       end = pivot;
     } else {
       start = pivot;