Make a branch to make krunner Good Enough For Aaron™.
[kdebase/uwolfer.git] / apps / konsole / src / Filter.h
blob191b7988721199a360ed4ad26adbdb577b5ba575
1 /*
2 Copyright (C) 2007 by Robert Knight <robertknight@gmail.com>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301 USA.
20 #ifndef FILTER_H
21 #define FILTER_H
23 // Qt
24 #include <QtGui/QAction>
25 #include <QtCore/QList>
26 #include <QtCore/QObject>
27 #include <QtCore/QStringList>
28 #include <QtCore/QHash>
29 #include <QtCore/QRegExp>
31 // Local
32 #include "Character.h"
34 namespace Konsole
37 /**
38 * A filter processes blocks of text looking for certain patterns (such as URLs or keywords from a list)
39 * and marks the areas which match the filter's patterns as 'hotspots'.
41 * Each hotspot has a type identifier associated with it ( such as a link or a highlighted section ),
42 * and an action. When the user performs some activity such as a mouse-click in a hotspot area ( the exact
43 * action will depend on what is displaying the block of text which the filter is processing ), the hotspot's
44 * activate() method should be called. Depending on the type of hotspot this will trigger a suitable response.
46 * For example, if a hotspot represents a URL then a suitable action would be opening that URL in a web browser.
47 * Hotspots may have more than one action, in which case the list of actions can be obtained using the
48 * actions() method.
50 * Different subclasses of filter will return different types of hotspot.
51 * Subclasses must reimplement the process() method to examine a block of text and identify sections of interest.
52 * When processing the text they should create instances of Filter::HotSpot subclasses for sections of interest
53 * and add them to the filter's list of hotspots using addHotSpot()
55 class Filter
57 public:
58 /**
59 * Represents an area of text which matched the pattern a particular filter has been looking for.
61 * Each hotspot has a type identifier associated with it ( such as a link or a highlighted section ),
62 * and an action. When the user performs some activity such as a mouse-click in a hotspot area ( the exact
63 * action will depend on what is displaying the block of text which the filter is processing ), the hotspot's
64 * activate() method should be called. Depending on the type of hotspot this will trigger a suitable response.
66 * For example, if a hotspot represents a URL then a suitable action would be opening that URL in a web browser.
67 * Hotspots may have more than one action, in which case the list of actions can be obtained using the
68 * actions() method. These actions may then be displayed in a popup menu or toolbar for example.
70 class HotSpot
72 public:
73 /**
74 * Constructs a new hotspot which covers the area from (@p startLine,@p startColumn) to (@p endLine,@p endColumn)
75 * in a block of text.
77 HotSpot(int startLine , int startColumn , int endLine , int endColumn);
78 virtual ~HotSpot();
80 enum Type
82 // the type of the hotspot is not specified
83 NotSpecified,
84 // this hotspot represents a clickable link
85 Link,
86 // this hotspot represents a marker
87 Marker
88 };
90 /** Returns the line when the hotspot area starts */
91 int startLine() const;
92 /** Returns the line where the hotspot area ends */
93 int endLine() const;
94 /** Returns the column on startLine() where the hotspot area starts */
95 int startColumn() const;
96 /** Returns the column on endLine() where the hotspot area ends */
97 int endColumn() const;
98 /**
99 * Returns the type of the hotspot. This is usually used as a hint for views on how to represent
100 * the hotspot graphically. eg. Link hotspots are typically underlined when the user mouses over them
102 Type type() const;
103 /**
104 * Causes the an action associated with a hotspot to be triggered.
106 * @param object The object which caused the hotspot to be triggered. This is
107 * typically null ( in which case the default action should be performed ) or
108 * one of the objects from the actions() list. In which case the associated
109 * action should be performed.
111 virtual void activate(QObject* object = 0) = 0;
112 /**
113 * Returns a list of actions associated with the hotspot which can be used in a
114 * menu or toolbar
116 virtual QList<QAction*> actions();
118 /**
119 * Returns the text of a tooltip to be shown when the mouse moves over the hotspot, or
120 * an empty string if there is no tooltip associated with this hotspot.
122 * The default implementation returns an empty string.
124 virtual QString tooltip() const;
126 protected:
127 /** Sets the type of a hotspot. This should only be set once */
128 void setType(Type type);
130 private:
131 int _startLine;
132 int _startColumn;
133 int _endLine;
134 int _endColumn;
135 Type _type;
139 /** Constructs a new filter. */
140 Filter();
141 virtual ~Filter();
143 /** Causes the filter to process the block of text currently in its internal buffer */
144 virtual void process() = 0;
146 /**
147 * Empties the filters internal buffer and resets the line count back to 0.
148 * All hotspots are deleted.
150 void reset();
152 /** Adds a new line of text to the filter and increments the line count */
153 //void addLine(const QString& string);
155 /** Returns the hotspot which covers the given @p line and @p column, or 0 if no hotspot covers that area */
156 HotSpot* hotSpotAt(int line , int column) const;
158 /** Returns the list of hotspots identified by the filter */
159 QList<HotSpot*> hotSpots() const;
161 /** Returns the list of hotspots identified by the filter which occur on a given line */
162 QList<HotSpot*> hotSpotsAtLine(int line) const;
164 /**
165 * TODO: Document me
167 void setBuffer(const QString* buffer , const QList<int>* linePositions);
169 protected:
170 /** Adds a new hotspot to the list */
171 void addHotSpot(HotSpot*);
172 /** Returns the internal buffer */
173 const QString* buffer();
174 /** Converts a character position within buffer() to a line and column */
175 void getLineColumn(int position , int& startLine , int& startColumn);
177 private:
178 QMultiHash<int,HotSpot*> _hotspots;
179 QList<HotSpot*> _hotspotList;
181 const QList<int>* _linePositions;
182 const QString* _buffer;
185 /**
186 * A filter which searches for sections of text matching a regular expression and creates a new RegExpFilter::HotSpot
187 * instance for them.
189 * Subclasses can reimplement newHotSpot() to return custom hotspot types when matches for the regular expression
190 * are found.
192 class RegExpFilter : public Filter
194 public:
195 /**
196 * Type of hotspot created by RegExpFilter. The capturedTexts() method can be used to find the text
197 * matched by the filter's regular expression.
199 class HotSpot : public Filter::HotSpot
201 public:
202 HotSpot(int startLine, int startColumn, int endLine , int endColumn);
203 virtual void activate(QObject* object = 0);
205 /** Sets the captured texts associated with this hotspot */
206 void setCapturedTexts(const QStringList& texts);
207 /** Returns the texts found by the filter when matching the filter's regular expression */
208 QStringList capturedTexts() const;
209 private:
210 QStringList _capturedTexts;
213 /** Constructs a new regular expression filter */
214 RegExpFilter();
216 /**
217 * Sets the regular expression which the filter searches for in blocks of text.
219 * Regular expressions which match the empty string are treated as not matching
220 * anything.
222 void setRegExp(const QRegExp& text);
223 /** Returns the regular expression which the filter searches for in blocks of text */
224 QRegExp regExp() const;
226 /**
227 * Reimplemented to search the filter's text buffer for text matching regExp()
229 * If regexp matches the empty string, then process() will return immediately
230 * without finding results.
232 virtual void process();
234 protected:
235 /**
236 * Called when a match for the regular expression is encountered. Subclasses should reimplement this
237 * to return custom hotspot types
239 virtual RegExpFilter::HotSpot* newHotSpot(int startLine,int startColumn,
240 int endLine,int endColumn);
242 private:
243 QRegExp _searchText;
246 class FilterObject;
248 /** A filter which matches URLs in blocks of text */
249 class UrlFilter : public RegExpFilter
251 public:
252 /**
253 * Hotspot type created by UrlFilter instances. The activate() method opens a web browser
254 * at the given URL when called.
256 class HotSpot : public RegExpFilter::HotSpot
258 public:
259 HotSpot(int startLine,int startColumn,int endLine,int endColumn);
260 virtual ~HotSpot();
262 virtual QList<QAction*> actions();
264 /**
265 * Open a web browser at the current URL. The url itself can be determined using
266 * the capturedTexts() method.
268 virtual void activate(QObject* object = 0);
270 virtual QString tooltip() const;
271 private:
272 enum UrlType
274 StandardUrl,
275 Email,
276 Unknown
278 UrlType urlType() const;
280 FilterObject* _urlObject;
283 UrlFilter();
285 protected:
286 virtual RegExpFilter::HotSpot* newHotSpot(int,int,int,int);
288 private:
290 static const QRegExp FullUrlRegExp;
291 static const QRegExp EmailAddressRegExp;
293 // combined OR of FullUrlRegExp and EmailAddressRegExp
294 static const QRegExp CompleteUrlRegExp;
297 class FilterObject : public QObject
299 Q_OBJECT
300 public:
301 FilterObject(Filter::HotSpot* filter) : _filter(filter) {}
302 private slots:
303 void activated();
304 private:
305 Filter::HotSpot* _filter;
308 /**
309 * A chain which allows a group of filters to be processed as one.
310 * The chain owns the filters added to it and deletes them when the chain itself is destroyed.
312 * Use addFilter() to add a new filter to the chain.
313 * When new text to be filtered arrives, use addLine() to add each additional
314 * line of text which needs to be processed and then after adding the last line, use
315 * process() to cause each filter in the chain to process the text.
317 * After processing a block of text, the reset() method can be used to set the filter chain's
318 * internal cursor back to the first line.
320 * The hotSpotAt() method will return the first hotspot which covers a given position.
322 * The hotSpots() and hotSpotsAtLine() method return all of the hotspots in the text and on
323 * a given line respectively.
325 class FilterChain : protected QList<Filter*>
327 public:
328 virtual ~FilterChain();
330 /** Adds a new filter to the chain. The chain will delete this filter when it is destroyed */
331 void addFilter(Filter* filter);
332 /** Removes a filter from the chain. The chain will no longer delete the filter when destroyed */
333 void removeFilter(Filter* filter);
334 /** Returns true if the chain contains @p filter */
335 bool containsFilter(Filter* filter);
336 /** Removes all filters from the chain */
337 void clear();
339 /** Resets each filter in the chain */
340 void reset();
342 * Processes each filter in the chain
344 void process();
346 /** Sets the buffer for each filter in the chain to process. */
347 void setBuffer(const QString* buffer , const QList<int>* linePositions);
349 /** Returns the first hotspot which occurs at @p line, @p column or 0 if no hotspot was found */
350 Filter::HotSpot* hotSpotAt(int line , int column) const;
351 /** Returns a list of all the hotspots in all the chain's filters */
352 QList<Filter::HotSpot*> hotSpots() const;
353 /** Returns a list of all hotspots at the given line in all the chain's filters */
354 QList<Filter::HotSpot> hotSpotsAtLine(int line) const;
358 /** A filter chain which processes character images from terminal displays */
359 class TerminalImageFilterChain : public FilterChain
361 public:
362 TerminalImageFilterChain();
363 virtual ~TerminalImageFilterChain();
366 * Set the current terminal image to @p image.
368 * @param image The terminal image
369 * @param lines The number of lines in the terminal image
370 * @param columns The number of columns in the terminal image
372 void setImage(const Character* const image , int lines , int columns,
373 const QVector<LineProperty>& lineProperties);
375 private:
376 QString* _buffer;
377 QList<int>* _linePositions;
381 #endif //FILTER_H