changeset 23403:fee531225679

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
author Torsten <mttl@mailbox.org>
date Mon, 17 Apr 2017 20:08:24 +0200
parents 1fadf480a63b
children 314ac710f2ae
files libgui/qterminal/libqterminal/QTerminal.cc libgui/qterminal/libqterminal/QTerminal.h libgui/qterminal/libqterminal/unix/Filter.cpp libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.cpp libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.h libgui/qterminal/libqterminal/unix/TerminalView.cpp
diffstat 6 files changed, 45 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/qterminal/libqterminal/QTerminal.cc	Sat Apr 15 14:20:40 2017 -0700
+++ b/libgui/qterminal/libqterminal/QTerminal.cc	Mon Apr 17 20:08:24 2017 +0200
@@ -123,7 +123,19 @@
     _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
--- a/libgui/qterminal/libqterminal/QTerminal.h	Sat Apr 15 14:20:40 2017 -0700
+++ b/libgui/qterminal/libqterminal/QTerminal.h	Mon Apr 17 20:08:24 2017 +0200
@@ -61,6 +61,9 @@
 
   virtual void has_extra_interrupt (bool extra) = 0;
 
+  virtual QList<QAction*> get_hotspot_actions (const QPoint&)
+      { return QList<QAction*> (); }
+
   enum CursorType
   {
     UnderlineCursor,
--- a/libgui/qterminal/libqterminal/unix/Filter.cpp	Sat Apr 15 14:20:40 2017 -0700
+++ b/libgui/qterminal/libqterminal/unix/Filter.cpp	Mon Apr 17 20:08:24 2017 +0200
@@ -26,6 +26,7 @@
 #include <iostream>
 
 // Qt
+#include <QDesktopServices>
 #include <QAction>
 #include <QApplication>
 #include <QClipboard>
@@ -482,7 +483,7 @@
             url.prepend("mailto:");
         }
 
-//        new KRun(url,QApplication::activeWindow());
+        QDesktopServices::openUrl (QUrl (url));
     }
 }
 
--- a/libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.cpp	Sat Apr 15 14:20:40 2017 -0700
+++ b/libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.cpp	Mon Apr 17 20:08:24 2017 +0200
@@ -43,6 +43,9 @@
     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 @@
     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
--- a/libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.h	Sat Apr 15 14:20:40 2017 -0700
+++ b/libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.h	Mon Apr 17 20:08:24 2017 +0200
@@ -50,6 +50,7 @@
     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();
--- a/libgui/qterminal/libqterminal/unix/TerminalView.cpp	Sat Apr 15 14:20:40 2017 -0700
+++ b/libgui/qterminal/libqterminal/unix/TerminalView.cpp	Mon Apr 17 20:08:24 2017 +0200
@@ -1390,6 +1390,9 @@
   QRect cursorRect = imageToWidget( QRect(cursorPosition(),QSize(1,1)) );
 
   update(cursorRect);
+
+  // use this timer event for updating the hot spots
+  processFilters ();
 }
 
 /* ------------------------------------------------------------------------- */
@@ -1559,6 +1562,16 @@
 
   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 @@
   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 @@
     }
   else if ( _mouseOverHotspotArea.isValid() )
     {
+      setUsesMouse (true);
       update( _mouseOverHotspotArea );
       // set hotspot area to an invalid rectangle
       _mouseOverHotspotArea = QRect();