Commit f667964c authored by Robert Knight's avatar Robert Knight
Browse files

* Implement basic highlighting of URLs in Konsole when the user mouses over them and launching

  that URL when clicked.
* Code for drawing markers.  Markers are translucent highlights over certain text (matched internally
  using regular expressions).


svn path=/branches/work/konsole-split-view/; revision=619661
parent 04fb8415
......@@ -86,7 +86,17 @@ Filter::HotSpot* FilterChain::hotSpotAt(int line , int column) const
return 0;
}
//QList<Filter::HotSpot*> FilterChain::hotSpots() const;
QList<Filter::HotSpot*> FilterChain::hotSpots() const
{
QList<Filter::HotSpot*> list;
QListIterator<Filter*> iter(*this);
while (iter.hasNext())
{
Filter* filter = iter.next();
list << filter->hotSpots();
}
return list;
}
//QList<Filter::HotSpot*> FilterChain::hotSpotsAtLine(int line) const;
void TerminalImageFilterChain::addImage(const ca* const image , int lines , int columns)
......@@ -202,7 +212,7 @@ Filter::HotSpot::HotSpot(int startLine , int startColumn , int endLine , int end
, _startColumn(startColumn)
, _endLine(endLine)
, _endColumn(endColumn)
, _type(NoType)
, _type(NotSpecified)
{
}
QList<QAction*> Filter::HotSpot::actions()
......@@ -240,11 +250,12 @@ RegExpFilter::RegExpFilter()
RegExpFilter::HotSpot::HotSpot(int startLine,int startColumn,int endLine,int endColumn)
: Filter::HotSpot(startLine,startColumn,endLine,endColumn)
{}
{
setType(Marker);
}
void RegExpFilter::HotSpot::activate()
{
qDebug() << "regexp hotspot activated";
}
void RegExpFilter::HotSpot::setCapturedTexts(const QStringList& texts)
......@@ -314,7 +325,7 @@ UrlFilter::HotSpot::HotSpot(int startLine,int startColumn,int endLine,int endCol
: RegExpFilter::HotSpot(startLine,startColumn,endLine,endColumn)
, _urlObject(new FilterObject(this))
{
setType(LinkType);
setType(Link);
}
void UrlFilter::HotSpot::activate()
{
......
......@@ -41,11 +41,11 @@ public:
enum Type
{
// the type of the hotspot is not specified
NoType,
NotSpecified,
// this hotspot represents a clickable link
LinkType,
Link,
// this hotspot represents a marker
MarkerType
Marker
};
int startLine() const;
......
......@@ -390,6 +390,9 @@ TEWidget::TEWidget(QWidget *parent)
,_filterChain(new TerminalImageFilterChain())
{
_filterChain->addFilter( new UrlFilter() );
RegExpFilter* ref = new RegExpFilter();
ref->setRegExp( QRegExp("kde") );
_filterChain->addFilter( ref );
// The offsets are not yet calculated.
// Do not calculate these too often to be more smoothly when resizing
......@@ -415,6 +418,8 @@ TEWidget::TEWidget(QWidget *parent)
qApp->installEventFilter( this ); //FIXME: see below
KCursor::setAutoHideCursor( this, true );
setMouseTracking(true);
// Init DnD ////////////////////////////////////////////////////////////////
setAcceptDrops(true); // attempt
dragInfo.state = diNone;
......@@ -1170,6 +1175,7 @@ void TEWidget::paintEvent( QPaintEvent* pe )
{
paintContents(paint, rect);
}
paintFilters(paint);
drawFrame( &paint );
......@@ -1252,6 +1258,45 @@ void TEWidget::print(QPainter &paint, bool friendly, bool exact)
blinking = save_blinking;
}
void TEWidget::paintFilters(QPainter& painter)
{
QList<Filter::HotSpot*> spots = _filterChain->hotSpots();
QListIterator<Filter::HotSpot*> iter(spots);
while (iter.hasNext())
{
Filter::HotSpot* spot = iter.next();
// Links need to be underlined
if ( spot->type() == Filter::HotSpot::Link )
{
QFontMetrics metrics(font());
QRect r;
r.setCoords(spot->startColumn()*font_w , spot->startLine()*font_h,
spot->endColumn()*font_w , (spot->endLine()+1)*font_h);
// find the baseline (which is the invisible line that the characters in the font sit on,
// with some having tails dangling below)
int baseline = r.bottom() - metrics.descent();
// find the position of the underline below that
int underlinePos = baseline + metrics.underlinePos();
if ( r.contains( mapFromGlobal(QCursor::pos()) ) )
painter.drawLine( r.left() , underlinePos ,
r.right() , underlinePos );
}
// Marker hotspots simply have a transparent rectanglular shape
// drawn on top of them
else if ( spot->type() == Filter::HotSpot::Marker )
{
QRect r;
r.setCoords(spot->startColumn()*font_w , spot->startLine()*font_h,
spot->endColumn()*font_w , (spot->endLine()+1)*font_h);
//TODO - Do not use a hardcoded colour for this
painter.fillRect(r,QBrush(QColor(255,0,0,120)));
}
}
}
void TEWidget::paintContents(QPainter &paint, const QRect &rect)
{
QPoint tL = contentsRect().topLeft();
......@@ -1589,9 +1634,35 @@ void TEWidget::mousePressEvent(QMouseEvent* ev)
void TEWidget::mouseMoveEvent(QMouseEvent* ev)
{
int charLine = 0;
int charColumn = 0;
characterPosition(ev->pos(),charLine,charColumn);
// handle filters
// change link hot-spot appearence on mouse-over
Filter::HotSpot* spot = _filterChain->hotSpotAt(charLine,charColumn);
if ( spot && spot->type() == Filter::HotSpot::Link)
{
_mouseOverHotspotArea.setCoords( qMin(spot->startColumn() , spot->endColumn()) * font_w,
spot->startLine() * font_h,
qMax(spot->startColumn() , spot->endColumn()) * font_h,
(spot->endLine()+1) * font_h );
update( _mouseOverHotspotArea );
}
else if ( _mouseOverHotspotArea.isValid() )
{
update( _mouseOverHotspotArea );
// set hotspot area to an invalid rectangle
_mouseOverHotspotArea = QRect();
}
// for auto-hiding the cursor, we need mouseTracking
if (ev->buttons() == Qt::NoButton ) return;
// if the terminal is interested in mouse movements
// then emit a mouse movement signal, unless the shift
// key is being held down, which overrides this.
if (!mouse_marks && !(ev->modifiers() & Qt::ShiftModifier))
{
int button = 3;
......@@ -1602,11 +1673,7 @@ void TEWidget::mouseMoveEvent(QMouseEvent* ev)
if (ev->buttons() & Qt::RightButton)
button = 2;
int charLine = 0;
int charColumn = 0;
characterPosition(ev->pos(),charLine,charColumn);
emit mouseSignal( button,
charColumn + 1,
charLine + 1 +scrollbar->value() -scrollbar->maximum(),
......@@ -1614,6 +1681,8 @@ void TEWidget::mouseMoveEvent(QMouseEvent* ev)
return;
}
if (dragInfo.state == diPending) {
// we had a mouse down, but haven't confirmed a drag yet
......
......@@ -58,7 +58,10 @@ class QGridLayout;
class QShowEvent;
class QHideEvent;
class TerminalImageFilterChain;
namespace Filter
{
class HotSpot;
};
/**
* A widget which displays output from a terminal emulation and sends input keypresses and mouse activity
* to the terminal.
......@@ -241,6 +244,7 @@ protected:
void paintEvent( QPaintEvent * );
void paintContents(QPainter &paint, const QRect &rect);
void paintFilters(QPainter& painter);
void showEvent(QShowEvent*);
void hideEvent(QHideEvent*);
......@@ -414,6 +418,7 @@ private:
QAction* m_lnAction;
TerminalImageFilterChain* _filterChain;
QRect _mouseOverHotspotArea;
//the delay in milliseconds between redrawing blinking text
static const int BLINK_DELAY = 750;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment