# HG changeset patch
# User Torsten <mttl@mailbox.org>
# Date 1490214828 -3600
#      Wed Mar 22 21:33:48 2017 +0100
# Node ID 38fa82eb239dc595b1216677b96226393f4d705b
# Parent  c4aebfe51a1705835f7b97b923bdd990484850e6
make url in the console window clickable under linux (bug #41076)

* QTerminal.cc (handleCustomContextMenuReques): before showing the context
  menu, get possible actions related to a hotspot (text matching url-filter)
  and append these actions to the context menu

* QTerminal.h: virtual function for getting hotspot actions, returning an
  empty list by default

* Filter.cpp (UrlFilter::HotSpot::activate): replace KRun function by
  QDesktopServices::openUrl for opening urls

* QUnixTerminalImpl.cpp (initialize): create a new UrlFilter and add it
  to the filter chain;
  (get_hotspot_actions): reimplemented function returning actions of a
  possible matching hotspot at a specific location;

* QUnixTerminalImpl.h: reimplemented get_hotspot_actions

* TerminalView.cpp (blinkCursorEvent): use this timer event for processing
  the filter chain;
  (mousePressEvent): check for a left click in a link hotspot and trigger
  the first action of all actions related to the hotspot;
  (mouseMoveEvent): change the mouse cursor when hovering over a link hotspot

diff -r c4aebfe51a17 -r 38fa82eb239d libgui/qterminal/libqterminal/QTerminal.cc
--- a/libgui/qterminal/libqterminal/QTerminal.cc	Tue Mar 21 20:25:27 2017 +0100
+++ b/libgui/qterminal/libqterminal/QTerminal.cc	Wed Mar 22 21:33:48 2017 +0100
@@ -123,7 +123,19 @@ QTerminal::handleCustomContextMenuReques
     _paste_action->setEnabled (cb->text().length() > 0);
     _copy_action->setEnabled (has_selected_text);
 
+    // Get the actions of any hotspots the filters may have found
+    QList<QAction*> actions = get_hotspot_actions (at);
+    if (actions.length ())
+      _contextMenu->addSeparator ();
+    for (int i = 0; i < actions.length (); i++)
+      _contextMenu->addAction (actions.at(i));
+
+    // Finally, show the context menu
     _contextMenu->exec (mapToGlobal (at));
+
+    // Cleaning up, remove actions of the hotspot
+    for (int i = 0; i < actions.length (); i++)
+      _contextMenu->removeAction (actions.at(i));
   }
 
 // slot for edit files in error messages
diff -r c4aebfe51a17 -r 38fa82eb239d libgui/qterminal/libqterminal/QTerminal.h
--- a/libgui/qterminal/libqterminal/QTerminal.h	Tue Mar 21 20:25:27 2017 +0100
+++ b/libgui/qterminal/libqterminal/QTerminal.h	Wed Mar 22 21:33:48 2017 +0100
@@ -61,6 +61,9 @@ public:
 
   virtual void has_extra_interrupt (bool extra) = 0;
 
+  virtual QList<QAction*> get_hotspot_actions (const QPoint&)
+      { return QList<QAction*> (); }
+
   enum CursorType
   {
     UnderlineCursor,
diff -r c4aebfe51a17 -r 38fa82eb239d libgui/qterminal/libqterminal/unix/Filter.cpp
--- a/libgui/qterminal/libqterminal/unix/Filter.cpp	Tue Mar 21 20:25:27 2017 +0100
+++ b/libgui/qterminal/libqterminal/unix/Filter.cpp	Wed Mar 22 21:33:48 2017 +0100
@@ -26,6 +26,7 @@
 #include <iostream>
 
 // Qt
+#include <QDesktopServices>
 #include <QAction>
 #include <QApplication>
 #include <QClipboard>
@@ -482,7 +483,7 @@ void UrlFilter::HotSpot::activate(QObjec
             url.prepend("mailto:");
         }
 
-//        new KRun(url,QApplication::activeWindow());
+        QDesktopServices::openUrl (QUrl (url));
     }
 }
 
diff -r c4aebfe51a17 -r 38fa82eb239d libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.cpp
--- a/libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.cpp	Tue Mar 21 20:25:27 2017 +0100
+++ b/libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.cpp	Wed Mar 22 21:33:48 2017 +0100
@@ -43,6 +43,9 @@ void QUnixTerminalImpl::initialize()
     m_terminalView->setSize(80, 40);
     m_terminalView->setScrollBarPosition(TerminalView::ScrollBarRight);
 
+    UrlFilter *url_filter = new UrlFilter();
+    m_terminalView->filterChain ()->addFilter (url_filter);
+
     connect(m_terminalView, SIGNAL(customContextMenuRequested(QPoint)),
             this, SLOT(handleCustomContextMenuRequested(QPoint)));
 
@@ -87,6 +90,12 @@ void QUnixTerminalImpl::setScrollBufferS
     m_terminalModel->setHistoryType (HistoryTypeNone ());
 }
 
+QList<QAction*>
+QUnixTerminalImpl::get_hotspot_actions (const QPoint& at)
+{
+  return m_terminalView->filterActions (at);
+}
+
 void QUnixTerminalImpl::connectToPty()
 {
     // Store the file descriptor associated with the STDERR stream onto
diff -r c4aebfe51a17 -r 38fa82eb239d libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.h
--- a/libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.h	Tue Mar 21 20:25:27 2017 +0100
+++ b/libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.h	Wed Mar 22 21:33:48 2017 +0100
@@ -50,6 +50,7 @@ public:
     void setScrollBufferSize(int value);
     QString selectedText();
     void has_extra_interrupt (bool extra_interrupt);
+    QList<QAction*> get_hotspot_actions (const QPoint& at);
 
 public slots:
     void copyClipboard();
diff -r c4aebfe51a17 -r 38fa82eb239d libgui/qterminal/libqterminal/unix/TerminalView.cpp
--- a/libgui/qterminal/libqterminal/unix/TerminalView.cpp	Tue Mar 21 20:25:27 2017 +0100
+++ b/libgui/qterminal/libqterminal/unix/TerminalView.cpp	Wed Mar 22 21:33:48 2017 +0100
@@ -1390,6 +1390,9 @@ void TerminalView::blinkCursorEvent()
   QRect cursorRect = imageToWidget( QRect(cursorPosition(),QSize(1,1)) );
 
   update(cursorRect);
+
+  // use this timer event for updating the hot spots
+  processFilters ();
 }
 
 /* ------------------------------------------------------------------------- */
@@ -1559,6 +1562,16 @@ void TerminalView::mousePressEvent(QMous
 
   if ( ev->button() == Qt::LeftButton)
     {
+
+      Filter::HotSpot* spot = _filterChain->hotSpotAt(charLine,charColumn);
+      if ( spot && spot->type() == Filter::HotSpot::Link)
+        {
+          QList<QAction*> actions = spot->actions ();
+          if (actions.length ())
+            actions.at (0)->activate (QAction::Trigger);
+          return;
+        }
+
       _lineSelectionMode = false;
       _wordSelectionMode = false;
 
@@ -1645,6 +1658,10 @@ void TerminalView::mouseMoveEvent(QMouse
   Filter::HotSpot* spot = _filterChain->hotSpotAt(charLine,charColumn);
   if ( spot && spot->type() == Filter::HotSpot::Link)
     {
+      // change mouse cursor when mouse is over links
+      if (! _mouseOverHotspotArea.isValid())
+        setCursor (Qt::PointingHandCursor);
+
       QRect previousHotspotArea = _mouseOverHotspotArea;
       _mouseOverHotspotArea.setCoords( qMin(spot->startColumn() , spot->endColumn()) * _fontWidth,
                                        spot->startLine() * _fontHeight,
@@ -1663,6 +1680,7 @@ void TerminalView::mouseMoveEvent(QMouse
     }
   else if ( _mouseOverHotspotArea.isValid() )
     {
+      setUsesMouse (true);
       update( _mouseOverHotspotArea );
       // set hotspot area to an invalid rectangle
       _mouseOverHotspotArea = QRect();
