diff --git a/lib/Filter.cpp b/lib/Filter.cpp index 0982f48..4738974 100644 --- a/lib/Filter.cpp +++ b/lib/Filter.cpp @@ -405,15 +405,19 @@ RegExpFilter::HotSpot* RegExpFilter::newHotSpot(int startLine,int startColumn, RegExpFilter::HotSpot* UrlFilter::newHotSpot(int startLine,int startColumn,int endLine, int endColumn) { - return new UrlFilter::HotSpot(startLine,startColumn, + HotSpot *spot = new UrlFilter::HotSpot(startLine,startColumn, endLine,endColumn); + connect(spot->getUrlObject(), SIGNAL(activated(QUrl)), this, SIGNAL(activated(QUrl))); + return spot; } + UrlFilter::HotSpot::HotSpot(int startLine,int startColumn,int endLine,int endColumn) : RegExpFilter::HotSpot(startLine,startColumn,endLine,endColumn) , _urlObject(new FilterObject(this)) { setType(Link); } + QString UrlFilter::HotSpot::tooltip() const { QString url = capturedTexts().first(); @@ -469,8 +473,7 @@ void UrlFilter::HotSpot::activate(QObject* object) url.prepend("mailto:"); } - QDesktopServices::openUrl(QUrl(url)); - //new KRun(url,QApplication::activeWindow()); + _urlObject->emitActivated(url); } } @@ -495,14 +498,27 @@ UrlFilter::UrlFilter() { setRegExp( CompleteUrlRegExp ); } + UrlFilter::HotSpot::~HotSpot() { delete _urlObject; } + +void FilterObject::emitActivated(const QUrl& url) +{ + emit activated(url); +} + void FilterObject::activated() { _filter->activate(sender()); } + +FilterObject* UrlFilter::HotSpot::getUrlObject() const +{ + return _urlObject; +} + QList UrlFilter::HotSpot::actions() { QList list; diff --git a/lib/Filter.h b/lib/Filter.h index e94195d..2daae09 100644 --- a/lib/Filter.h +++ b/lib/Filter.h @@ -52,7 +52,7 @@ namespace Konsole * When processing the text they should create instances of Filter::HotSpot subclasses for sections of interest * and add them to the filter's list of hotspots using addHotSpot() */ -class Filter +class Filter : public QObject { public: /** @@ -248,6 +248,7 @@ class FilterObject; /** A filter which matches URLs in blocks of text */ class UrlFilter : public RegExpFilter { + Q_OBJECT public: /** * Hotspot type created by UrlFilter instances. The activate() method opens a web browser @@ -259,6 +260,8 @@ public: HotSpot(int startLine,int startColumn,int endLine,int endColumn); virtual ~HotSpot(); + FilterObject* getUrlObject() const; + virtual QList actions(); /** @@ -292,17 +295,23 @@ private: // combined OR of FullUrlRegExp and EmailAddressRegExp static const QRegExp CompleteUrlRegExp; +signals: + void activated(const QUrl& url); }; class FilterObject : public QObject { -Q_OBJECT + Q_OBJECT public: FilterObject(Filter::HotSpot* filter) : _filter(filter) {} + + void emitActivated(const QUrl& url); private slots: void activated(); private: Filter::HotSpot* _filter; +signals: + void activated(const QUrl& url); }; /** diff --git a/lib/TerminalDisplay.cpp b/lib/TerminalDisplay.cpp index abf71fe..774b08b 100644 --- a/lib/TerminalDisplay.cpp +++ b/lib/TerminalDisplay.cpp @@ -141,6 +141,8 @@ void TerminalDisplay::setScreenWindow(ScreenWindow* window) //#warning "The order here is not specified - does it matter whether updateImage or updateLineProperties comes first?" connect( _screenWindow , SIGNAL(outputChanged()) , this , SLOT(updateLineProperties()) ); connect( _screenWindow , SIGNAL(outputChanged()) , this , SLOT(updateImage()) ); + connect( _screenWindow , SIGNAL(outputChanged()) , this , SLOT(updateFilters()) ); + connect( _screenWindow , SIGNAL(scrolled(int)) , this , SLOT(updateFilters()) ); window->setWindowLines(_lines); } } @@ -1577,6 +1579,7 @@ void TerminalDisplay::blinkCursorEvent() void TerminalDisplay::resizeEvent(QResizeEvent*) { updateImageSize(); + processFilters(); } void TerminalDisplay::propagateSize() @@ -1772,6 +1775,17 @@ void TerminalDisplay::mousePressEvent(QMouseEvent* ev) { emit mouseSignal( 0, charColumn + 1, charLine + 1 +_scrollBar->value() -_scrollBar->maximum() , 0); } + + if (ev->modifiers() & Qt::ControlModifier) + { + Filter::HotSpot *spot = _filterChain->hotSpotAt(charLine, charColumn); + if (spot && spot->type() == Filter::HotSpot::Link) + { + QObject action; + action.setObjectName ("open-action"); + spot->activate(&action); + } + } } } else if ( ev->button() == Qt::MidButton ) @@ -2197,6 +2211,14 @@ void TerminalDisplay::getCharacterPosition(const QPoint& widgetPoint,int& line,i column = _usedColumns; } +void TerminalDisplay::updateFilters() +{ + if ( !_screenWindow ) + return; + + processFilters(); +} + void TerminalDisplay::updateLineProperties() { if ( !_screenWindow ) diff --git a/lib/TerminalDisplay.h b/lib/TerminalDisplay.h index 1a8a391..b0ec240 100644 --- a/lib/TerminalDisplay.h +++ b/lib/TerminalDisplay.h @@ -436,6 +436,11 @@ public slots: * terminal screen ( see setScreenWindow() ) and redraw the display. */ void updateImage(); + + /** Essentially calles processFilters(). + */ + void updateFilters(); + /** * Causes the terminal display to fetch the latest line status flags from the * associated terminal screen ( see setScreenWindow() ). diff --git a/lib/qtermwidget.cpp b/lib/qtermwidget.cpp index c452df5..bc92774 100644 --- a/lib/qtermwidget.cpp +++ b/lib/qtermwidget.cpp @@ -238,6 +238,11 @@ void QTermWidget::init(int startnow) m_impl->m_terminalDisplay->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); m_layout->addWidget(m_impl->m_terminalDisplay); + // That's OK, FilterChain's dtor takes care of UrlFilter. + UrlFilter *urlFilter = new UrlFilter(); + connect(urlFilter, SIGNAL(activated(QUrl)), this, SIGNAL(urlActivated(QUrl))); + m_impl->m_terminalDisplay->filterChain()->addFilter(urlFilter); + m_searchBar = new SearchBar(this); m_searchBar->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum); connect(m_searchBar, SIGNAL(searchCriteriaChanged()), this, SLOT(find())); diff --git a/lib/qtermwidget.h b/lib/qtermwidget.h index f52f37b..7de0ccf 100644 --- a/lib/qtermwidget.h +++ b/lib/qtermwidget.h @@ -25,7 +25,7 @@ class QVBoxLayout; struct TermWidgetImpl; class SearchBar; - +class QUrl; class QTermWidget : public QWidget { Q_OBJECT @@ -154,6 +154,8 @@ signals: void termKeyPressed(QKeyEvent *); + void urlActivated(const QUrl&); + public slots: // Copy selection to clipboard void copyClipboard();