summaryrefslogtreecommitdiff
path: root/qtermwidget/Filter.h
diff options
context:
space:
mode:
Diffstat (limited to 'qtermwidget/Filter.h')
-rw-r--r--qtermwidget/Filter.h383
1 files changed, 383 insertions, 0 deletions
diff --git a/qtermwidget/Filter.h b/qtermwidget/Filter.h
new file mode 100644
index 0000000..06ea5e3
--- /dev/null
+++ b/qtermwidget/Filter.h
@@ -0,0 +1,383 @@
+/*
+ Copyright (C) 2007 by Robert Knight <robertknight@gmail.com>
+
+ Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA.
+*/
+
+#ifndef FILTER_H
+#define FILTER_H
+
+// Qt
+#include <QtGui/QAction>
+#include <QtCore/QList>
+#include <QtCore/QObject>
+#include <QtCore/QStringList>
+#include <QtCore/QHash>
+#include <QtCore/QRegExp>
+
+// Local
+#include "Character.h"
+
+namespace Konsole
+{
+
+/**
+ * A filter processes blocks of text looking for certain patterns (such as URLs or keywords from a list)
+ * and marks the areas which match the filter's patterns as 'hotspots'.
+ *
+ * Each hotspot has a type identifier associated with it ( such as a link or a highlighted section ),
+ * and an action. When the user performs some activity such as a mouse-click in a hotspot area ( the exact
+ * action will depend on what is displaying the block of text which the filter is processing ), the hotspot's
+ * activate() method should be called. Depending on the type of hotspot this will trigger a suitable response.
+ *
+ * For example, if a hotspot represents a URL then a suitable action would be opening that URL in a web browser.
+ * Hotspots may have more than one action, in which case the list of actions can be obtained using the
+ * actions() method.
+ *
+ * Different subclasses of filter will return different types of hotspot.
+ * Subclasses must reimplement the process() method to examine a block of text and identify sections of interest.
+ * 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
+{
+public:
+ /**
+ * Represents an area of text which matched the pattern a particular filter has been looking for.
+ *
+ * Each hotspot has a type identifier associated with it ( such as a link or a highlighted section ),
+ * and an action. When the user performs some activity such as a mouse-click in a hotspot area ( the exact
+ * action will depend on what is displaying the block of text which the filter is processing ), the hotspot's
+ * activate() method should be called. Depending on the type of hotspot this will trigger a suitable response.
+ *
+ * For example, if a hotspot represents a URL then a suitable action would be opening that URL in a web browser.
+ * Hotspots may have more than one action, in which case the list of actions can be obtained using the
+ * actions() method. These actions may then be displayed in a popup menu or toolbar for example.
+ */
+ class HotSpot
+ {
+ public:
+ /**
+ * Constructs a new hotspot which covers the area from (@p startLine,@p startColumn) to (@p endLine,@p endColumn)
+ * in a block of text.
+ */
+ HotSpot(int startLine , int startColumn , int endLine , int endColumn);
+ virtual ~HotSpot();
+
+ enum Type
+ {
+ // the type of the hotspot is not specified
+ NotSpecified,
+ // this hotspot represents a clickable link
+ Link,
+ // this hotspot represents a marker
+ Marker
+ };
+
+ /** Returns the line when the hotspot area starts */
+ int startLine() const;
+ /** Returns the line where the hotspot area ends */
+ int endLine() const;
+ /** Returns the column on startLine() where the hotspot area starts */
+ int startColumn() const;
+ /** Returns the column on endLine() where the hotspot area ends */
+ int endColumn() const;
+ /**
+ * Returns the type of the hotspot. This is usually used as a hint for views on how to represent
+ * the hotspot graphically. eg. Link hotspots are typically underlined when the user mouses over them
+ */
+ Type type() const;
+ /**
+ * Causes the an action associated with a hotspot to be triggered.
+ *
+ * @param object The object which caused the hotspot to be triggered. This is
+ * typically null ( in which case the default action should be performed ) or
+ * one of the objects from the actions() list. In which case the associated
+ * action should be performed.
+ */
+ virtual void activate(QObject* object = 0) = 0;
+ /**
+ * Returns a list of actions associated with the hotspot which can be used in a
+ * menu or toolbar
+ */
+ virtual QList<QAction*> actions();
+
+ /**
+ * Returns the text of a tooltip to be shown when the mouse moves over the hotspot, or
+ * an empty string if there is no tooltip associated with this hotspot.
+ *
+ * The default implementation returns an empty string.
+ */
+ virtual QString tooltip() const;
+
+ protected:
+ /** Sets the type of a hotspot. This should only be set once */
+ void setType(Type type);
+
+ private:
+ int _startLine;
+ int _startColumn;
+ int _endLine;
+ int _endColumn;
+ Type _type;
+
+ };
+
+ /** Constructs a new filter. */
+ Filter();
+ virtual ~Filter();
+
+ /** Causes the filter to process the block of text currently in its internal buffer */
+ virtual void process() = 0;
+
+ /**
+ * Empties the filters internal buffer and resets the line count back to 0.
+ * All hotspots are deleted.
+ */
+ void reset();
+
+ /** Adds a new line of text to the filter and increments the line count */
+ //void addLine(const QString& string);
+
+ /** Returns the hotspot which covers the given @p line and @p column, or 0 if no hotspot covers that area */
+ HotSpot* hotSpotAt(int line , int column) const;
+
+ /** Returns the list of hotspots identified by the filter */
+ QList<HotSpot*> hotSpots() const;
+
+ /** Returns the list of hotspots identified by the filter which occur on a given line */
+ QList<HotSpot*> hotSpotsAtLine(int line) const;
+
+ /**
+ * TODO: Document me
+ */
+ void setBuffer(const QString* buffer , const QList<int>* linePositions);
+
+protected:
+ /** Adds a new hotspot to the list */
+ void addHotSpot(HotSpot*);
+ /** Returns the internal buffer */
+ const QString* buffer();
+ /** Converts a character position within buffer() to a line and column */
+ void getLineColumn(int position , int& startLine , int& startColumn);
+
+private:
+ QMultiHash<int,HotSpot*> _hotspots;
+ QList<HotSpot*> _hotspotList;
+
+ const QList<int>* _linePositions;
+ const QString* _buffer;
+};
+
+/**
+ * A filter which searches for sections of text matching a regular expression and creates a new RegExpFilter::HotSpot
+ * instance for them.
+ *
+ * Subclasses can reimplement newHotSpot() to return custom hotspot types when matches for the regular expression
+ * are found.
+ */
+class RegExpFilter : public Filter
+{
+public:
+ /**
+ * Type of hotspot created by RegExpFilter. The capturedTexts() method can be used to find the text
+ * matched by the filter's regular expression.
+ */
+ class HotSpot : public Filter::HotSpot
+ {
+ public:
+ HotSpot(int startLine, int startColumn, int endLine , int endColumn);
+ virtual void activate(QObject* object = 0);
+
+ /** Sets the captured texts associated with this hotspot */
+ void setCapturedTexts(const QStringList& texts);
+ /** Returns the texts found by the filter when matching the filter's regular expression */
+ QStringList capturedTexts() const;
+ private:
+ QStringList _capturedTexts;
+ };
+
+ /** Constructs a new regular expression filter */
+ RegExpFilter();
+
+ /**
+ * Sets the regular expression which the filter searches for in blocks of text.
+ *
+ * Regular expressions which match the empty string are treated as not matching
+ * anything.
+ */
+ void setRegExp(const QRegExp& text);
+ /** Returns the regular expression which the filter searches for in blocks of text */
+ QRegExp regExp() const;
+
+ /**
+ * Reimplemented to search the filter's text buffer for text matching regExp()
+ *
+ * If regexp matches the empty string, then process() will return immediately
+ * without finding results.
+ */
+ virtual void process();
+
+protected:
+ /**
+ * Called when a match for the regular expression is encountered. Subclasses should reimplement this
+ * to return custom hotspot types
+ */
+ virtual RegExpFilter::HotSpot* newHotSpot(int startLine,int startColumn,
+ int endLine,int endColumn);
+
+private:
+ QRegExp _searchText;
+};
+
+class FilterObject;
+
+/** A filter which matches URLs in blocks of text */
+class UrlFilter : public RegExpFilter
+{
+public:
+ /**
+ * Hotspot type created by UrlFilter instances. The activate() method opens a web browser
+ * at the given URL when called.
+ */
+ class HotSpot : public RegExpFilter::HotSpot
+ {
+ public:
+ HotSpot(int startLine,int startColumn,int endLine,int endColumn);
+ virtual ~HotSpot();
+
+ virtual QList<QAction*> actions();
+
+ /**
+ * Open a web browser at the current URL. The url itself can be determined using
+ * the capturedTexts() method.
+ */
+ virtual void activate(QObject* object = 0);
+
+ virtual QString tooltip() const;
+ private:
+ enum UrlType
+ {
+ StandardUrl,
+ Email,
+ Unknown
+ };
+ UrlType urlType() const;
+
+ FilterObject* _urlObject;
+ };
+
+ UrlFilter();
+
+protected:
+ virtual RegExpFilter::HotSpot* newHotSpot(int,int,int,int);
+
+private:
+
+ static const QRegExp FullUrlRegExp;
+ static const QRegExp EmailAddressRegExp;
+
+ // combined OR of FullUrlRegExp and EmailAddressRegExp
+ static const QRegExp CompleteUrlRegExp;
+};
+
+class FilterObject : public QObject
+{
+Q_OBJECT
+public:
+ FilterObject(Filter::HotSpot* filter) : _filter(filter) {}
+private slots:
+ void activated();
+private:
+ Filter::HotSpot* _filter;
+};
+
+/**
+ * A chain which allows a group of filters to be processed as one.
+ * The chain owns the filters added to it and deletes them when the chain itself is destroyed.
+ *
+ * Use addFilter() to add a new filter to the chain.
+ * When new text to be filtered arrives, use addLine() to add each additional
+ * line of text which needs to be processed and then after adding the last line, use
+ * process() to cause each filter in the chain to process the text.
+ *
+ * After processing a block of text, the reset() method can be used to set the filter chain's
+ * internal cursor back to the first line.
+ *
+ * The hotSpotAt() method will return the first hotspot which covers a given position.
+ *
+ * The hotSpots() and hotSpotsAtLine() method return all of the hotspots in the text and on
+ * a given line respectively.
+ */
+class FilterChain : protected QList<Filter*>
+{
+public:
+ virtual ~FilterChain();
+
+ /** Adds a new filter to the chain. The chain will delete this filter when it is destroyed */
+ void addFilter(Filter* filter);
+ /** Removes a filter from the chain. The chain will no longer delete the filter when destroyed */
+ void removeFilter(Filter* filter);
+ /** Returns true if the chain contains @p filter */
+ bool containsFilter(Filter* filter);
+ /** Removes all filters from the chain */
+ void clear();
+
+ /** Resets each filter in the chain */
+ void reset();
+ /**
+ * Processes each filter in the chain
+ */
+ void process();
+
+ /** Sets the buffer for each filter in the chain to process. */
+ void setBuffer(const QString* buffer , const QList<int>* linePositions);
+
+ /** Returns the first hotspot which occurs at @p line, @p column or 0 if no hotspot was found */
+ Filter::HotSpot* hotSpotAt(int line , int column) const;
+ /** Returns a list of all the hotspots in all the chain's filters */
+ QList<Filter::HotSpot*> hotSpots() const;
+ /** Returns a list of all hotspots at the given line in all the chain's filters */
+ QList<Filter::HotSpot> hotSpotsAtLine(int line) const;
+
+};
+
+/** A filter chain which processes character images from terminal displays */
+class TerminalImageFilterChain : public FilterChain
+{
+public:
+ TerminalImageFilterChain();
+ virtual ~TerminalImageFilterChain();
+
+ /**
+ * Set the current terminal image to @p image.
+ *
+ * @param image The terminal image
+ * @param lines The number of lines in the terminal image
+ * @param columns The number of columns in the terminal image
+ */
+ void setImage(const Character* const image , int lines , int columns,
+ const QVector<LineProperty>& lineProperties);
+
+private:
+ QString* _buffer;
+ QList<int>* _linePositions;
+};
+
+}
+#endif //FILTER_H