URL recognition (WiP)
[quassel.git] / src / qtui / chatitem.cpp
index 602a2c9..aea98db 100644 (file)
@@ -63,6 +63,7 @@ qreal ChatItem::setGeometry(qreal w, qreal h) {
   prepareGeometryChange();
   _boundingRect.setWidth(w);
   if(h < 0) h = computeHeight();
+  //if(h < 0) h = fontMetrics()->lineSpacing(); // only contents can be multi-line
   _boundingRect.setHeight(h);
   if(haveLayout()) updateLayout();
   return h;
@@ -153,10 +154,8 @@ void ChatItem::setFullSelection() {
 }
 
 void ChatItem::clearSelection() {
-  if(_selectionMode != NoSelection) {
-    _selectionMode = NoSelection;
-    update();
-  }
+  _selectionMode = NoSelection;
+  update();
 }
 
 void ChatItem::continueSelecting(const QPointF &pos) {
@@ -195,15 +194,10 @@ QList<QRectF> ChatItem::findWords(const QString &searchWord, Qt::CaseSensitivity
 
 void ChatItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
   if(event->buttons() == Qt::LeftButton) {
-    if(_selectionMode == NoSelection) {
-      chatScene()->setSelectingItem(this);  // removes earlier selection if exists
-      _selectionStart = _selectionEnd = posToCursor(event->pos());
-      //_selectionMode = PartialSelection;
-    } else {
-      chatScene()->setSelectingItem(0);
-      _selectionMode = NoSelection;
-      update();
-    }
+    chatScene()->setSelectingItem(this);
+    _selectionStart = _selectionEnd = posToCursor(event->pos());
+    _selectionMode = NoSelection; // will be set to PartialSelection by mouseMoveEvent
+    update();
     event->accept();
   } else {
     event->ignore();
@@ -216,8 +210,7 @@ void ChatItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
       qint16 end = posToCursor(event->pos());
       if(end != _selectionEnd) {
         _selectionEnd = end;
-        if(_selectionStart != _selectionEnd) _selectionMode = PartialSelection;
-        else _selectionMode = NoSelection;
+        _selectionMode = (_selectionStart != _selectionEnd ? PartialSelection : NoSelection);
         update();
       }
     } else {
@@ -302,6 +295,28 @@ void ContentsChatItem::updateLayout() {
     h += line.height() + fontMetrics()->leading();
   }
   layout()->endLayout();
+
+  analyze();
+}
+
+void ContentsChatItem::analyze() {
+  // Match an URL
+  static QString urlEnd("(?:>|[,.;:]?\\s|\\b)");
+  static QString urlChars("(?:[\\w\\-~@/?&=+$()!%#]|[,.;:]\\w)");
+  static QRegExp urlExp(QString("((?:(?:https?://|ftp://|irc://|mailto:)|www)%1+)%2").arg(urlChars, urlEnd));
+
+  // Match a channel name
+  // We don't match for channel names starting with + or &, because that gives us a lot of false positives.
+  static QRegExp chanExp("((?:#|![A-Z0-9]{5})[^,:\\s]+(?::[^,:\\s]+)?)\\b");
+  QString str = data(ChatLineModel::DisplayRole).toString();
+  quint16 idx = 0;
+  // first, we split on characters that might be URL separators
+  int i = str.indexOf(chanExp);
+  if(i >= 0) {
+    qDebug() << i << chanExp.cap(1);
+  }
+
+
 }
 
 void ContentsChatItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) {
@@ -340,13 +355,15 @@ void ContentsChatItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) {
 
 /*************************************************************************************************/
 
-ContentsChatItem::WrapColumnFinder::WrapColumnFinder(ChatItem *_item) : item(_item) {
-  wrapList = item->data(ChatLineModel::WrapListRole).value<ChatLineModel::WrapList>();
-  wordidx = 0;
-  layout = 0;
-  lastwrapcol = 0;
-  lastwrappos = 0;
-  w = 0;
+ContentsChatItem::WrapColumnFinder::WrapColumnFinder(ChatItem *_item)
+  : item(_item),
+    layout(0),
+    wrapList(item->data(ChatLineModel::WrapListRole).value<ChatLineModel::WrapList>()),
+    wordidx(0),
+    lastwrapcol(0),
+    lastwrappos(0),
+    w(0)
+{
 }
 
 ContentsChatItem::WrapColumnFinder::~WrapColumnFinder() {