source: ogBrowser-Git/qtermwidget/lib/Filter.h @ 9004d96

jenkinsmain
Last change on this file since 9004d96 was 64efc22, checked in by Vadim Troshchinskiy <vtroshchinskiy@…>, 19 months ago

Update qtermwidget to modern version

  • Property mode set to 100644
File size: 13.2 KB
Line 
1/*
2    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
3
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.
8
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.
13
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.
18*/
19
20#ifndef FILTER_H
21#define FILTER_H
22
23// Qt
24#include <QAction>
25#include <QList>
26#include <QObject>
27#include <QStringList>
28#include <QHash>
29#include <QRegExp>
30
31// Local
32#include "qtermwidget_export.h"
33
34namespace Konsole
35{
36
37typedef unsigned char LineProperty;
38class Character;
39
40/**
41 * A filter processes blocks of text looking for certain patterns (such as URLs or keywords from a list)
42 * and marks the areas which match the filter's patterns as 'hotspots'.
43 *
44 * Each hotspot has a type identifier associated with it ( such as a link or a highlighted section ),
45 * and an action.  When the user performs some activity such as a mouse-click in a hotspot area ( the exact
46 * action will depend on what is displaying the block of text which the filter is processing ), the hotspot's
47 * activate() method should be called.  Depending on the type of hotspot this will trigger a suitable response.
48 *
49 * For example, if a hotspot represents a URL then a suitable action would be opening that URL in a web browser.
50 * Hotspots may have more than one action, in which case the list of actions can be obtained using the
51 * actions() method.
52 *
53 * Different subclasses of filter will return different types of hotspot.
54 * Subclasses must reimplement the process() method to examine a block of text and identify sections of interest.
55 * When processing the text they should create instances of Filter::HotSpot subclasses for sections of interest
56 * and add them to the filter's list of hotspots using addHotSpot()
57 */
58class QTERMWIDGET_EXPORT Filter : public QObject
59{
60public:
61    /**
62    * Represents an area of text which matched the pattern a particular filter has been looking for.
63    *
64    * Each hotspot has a type identifier associated with it ( such as a link or a highlighted section ),
65    * and an action.  When the user performs some activity such as a mouse-click in a hotspot area ( the exact
66    * action will depend on what is displaying the block of text which the filter is processing ), the hotspot's
67    * activate() method should be called.  Depending on the type of hotspot this will trigger a suitable response.
68    *
69    * For example, if a hotspot represents a URL then a suitable action would be opening that URL in a web browser.
70    * Hotspots may have more than one action, in which case the list of actions can be obtained using the
71    * actions() method.  These actions may then be displayed in a popup menu or toolbar for example.
72    */
73    class HotSpot
74    {
75    public:
76       /**
77        * Constructs a new hotspot which covers the area from (@p startLine,@p startColumn) to (@p endLine,@p endColumn)
78        * in a block of text.
79        */
80       HotSpot(int startLine , int startColumn , int endLine , int endColumn);
81       virtual ~HotSpot();
82
83       enum Type
84       {
85            // the type of the hotspot is not specified
86            NotSpecified,
87            // this hotspot represents a clickable link
88            Link,
89            // this hotspot represents a marker
90            Marker
91       };
92
93       /** Returns the line when the hotspot area starts */
94       int startLine() const;
95       /** Returns the line where the hotspot area ends */
96       int endLine() const;
97       /** Returns the column on startLine() where the hotspot area starts */
98       int startColumn() const;
99       /** Returns the column on endLine() where the hotspot area ends */
100       int endColumn() const;
101       /**
102        * Returns the type of the hotspot.  This is usually used as a hint for views on how to represent
103        * the hotspot graphically.  eg.  Link hotspots are typically underlined when the user mouses over them
104        */
105       Type type() const;
106       /**
107        * Causes the an action associated with a hotspot to be triggered.
108        *
109        * @param action The action to trigger.  This is
110        * typically empty ( in which case the default action should be performed ) or
111        * one of the object names from the actions() list.  In which case the associated
112        * action should be performed.
113        */
114       virtual void activate(const QString& action = QString()) = 0;
115       /**
116        * Returns a list of actions associated with the hotspot which can be used in a
117        * menu or toolbar
118        */
119       virtual QList<QAction*> actions();
120
121    protected:
122       /** Sets the type of a hotspot.  This should only be set once */
123       void setType(Type type);
124
125    private:
126       int    _startLine;
127       int    _startColumn;
128       int    _endLine;
129       int    _endColumn;
130       Type _type;
131
132    };
133
134    /** Constructs a new filter. */
135    Filter();
136    ~Filter() override;
137
138    /** Causes the filter to process the block of text currently in its internal buffer */
139    virtual void process() = 0;
140
141    /**
142     * Empties the filters internal buffer and resets the line count back to 0.
143     * All hotspots are deleted.
144     */
145    void reset();
146
147    /** Adds a new line of text to the filter and increments the line count */
148    //void addLine(const QString& string);
149
150    /** Returns the hotspot which covers the given @p line and @p column, or 0 if no hotspot covers that area */
151    HotSpot* hotSpotAt(int line , int column) const;
152
153    /** Returns the list of hotspots identified by the filter */
154    QList<HotSpot*> hotSpots() const;
155
156    /** Returns the list of hotspots identified by the filter which occur on a given line */
157    QList<HotSpot*> hotSpotsAtLine(int line) const;
158
159    /**
160     * TODO: Document me
161     */
162    void setBuffer(const QString* buffer , const QList<int>* linePositions);
163
164protected:
165    /** Adds a new hotspot to the list */
166    void addHotSpot(HotSpot*);
167    /** Returns the internal buffer */
168    const QString* buffer();
169    /** Converts a character position within buffer() to a line and column */
170    void getLineColumn(int position , int& startLine , int& startColumn);
171
172private:
173    QMultiHash<int,HotSpot*> _hotspots;
174    QList<HotSpot*> _hotspotList;
175
176    const QList<int>* _linePositions;
177    const QString* _buffer;
178};
179
180/**
181 * A filter which searches for sections of text matching a regular expression and creates a new RegExpFilter::HotSpot
182 * instance for them.
183 *
184 * Subclasses can reimplement newHotSpot() to return custom hotspot types when matches for the regular expression
185 * are found.
186 */
187class QTERMWIDGET_EXPORT RegExpFilter : public Filter
188{
189public:
190    /**
191     * Type of hotspot created by RegExpFilter.  The capturedTexts() method can be used to find the text
192     * matched by the filter's regular expression.
193     */
194    class HotSpot : public Filter::HotSpot
195    {
196    public:
197        HotSpot(int startLine, int startColumn, int endLine , int endColumn);
198        void activate(const QString& action = QString()) override;
199
200        /** Sets the captured texts associated with this hotspot */
201        void setCapturedTexts(const QStringList& texts);
202        /** Returns the texts found by the filter when matching the filter's regular expression */
203        QStringList capturedTexts() const;
204    private:
205        QStringList _capturedTexts;
206    };
207
208    /** Constructs a new regular expression filter */
209    RegExpFilter();
210
211    /**
212     * Sets the regular expression which the filter searches for in blocks of text.
213     *
214     * Regular expressions which match the empty string are treated as not matching
215     * anything.
216     */
217    void setRegExp(const QRegExp& text);
218    /** Returns the regular expression which the filter searches for in blocks of text */
219    QRegExp regExp() const;
220
221    /**
222     * Reimplemented to search the filter's text buffer for text matching regExp()
223     *
224     * If regexp matches the empty string, then process() will return immediately
225     * without finding results.
226     */
227    void process() override;
228
229protected:
230    /**
231     * Called when a match for the regular expression is encountered.  Subclasses should reimplement this
232     * to return custom hotspot types
233     */
234    virtual RegExpFilter::HotSpot* newHotSpot(int startLine,int startColumn,
235                                    int endLine,int endColumn);
236
237private:
238    QRegExp _searchText;
239};
240
241class FilterObject;
242
243/** A filter which matches URLs in blocks of text */
244class QTERMWIDGET_EXPORT UrlFilter : public RegExpFilter
245{
246    Q_OBJECT
247public:
248    /**
249     * Hotspot type created by UrlFilter instances.  The activate() method opens a web browser
250     * at the given URL when called.
251     */
252    class HotSpot : public RegExpFilter::HotSpot
253    {
254    public:
255        HotSpot(int startLine,int startColumn,int endLine,int endColumn);
256        ~HotSpot() override;
257
258        FilterObject* getUrlObject() const;
259
260        QList<QAction*> actions() override;
261
262        /**
263         * Open a web browser at the current URL.  The url itself can be determined using
264         * the capturedTexts() method.
265         */
266        void activate(const QString& action = QString()) override;
267
268    private:
269        enum UrlType
270        {
271            StandardUrl,
272            Email,
273            Unknown
274        };
275        UrlType urlType() const;
276
277        FilterObject* _urlObject;
278    };
279
280    UrlFilter();
281
282protected:
283    RegExpFilter::HotSpot* newHotSpot(int,int,int,int) override;
284
285private:
286
287    static const QRegExp FullUrlRegExp;
288    static const QRegExp EmailAddressRegExp;
289
290    // combined OR of FullUrlRegExp and EmailAddressRegExp
291    static const QRegExp CompleteUrlRegExp;
292signals:
293    void activated(const QUrl& url, bool fromContextMenu);
294};
295
296class QTERMWIDGET_NO_EXPORT FilterObject : public QObject
297{
298    Q_OBJECT
299public:
300    FilterObject(Filter::HotSpot* filter) : _filter(filter) {}
301
302    void emitActivated(const QUrl& url, bool fromContextMenu);
303public slots:
304    void activate();
305private:
306    Filter::HotSpot* _filter;
307signals:
308    void activated(const QUrl& url, bool fromContextMenu);
309};
310
311/**
312 * A chain which allows a group of filters to be processed as one.
313 * The chain owns the filters added to it and deletes them when the chain itself is destroyed.
314 *
315 * Use addFilter() to add a new filter to the chain.
316 * When new text to be filtered arrives, use addLine() to add each additional
317 * line of text which needs to be processed and then after adding the last line, use
318 * process() to cause each filter in the chain to process the text.
319 *
320 * After processing a block of text, the reset() method can be used to set the filter chain's
321 * internal cursor back to the first line.
322 *
323 * The hotSpotAt() method will return the first hotspot which covers a given position.
324 *
325 * The hotSpots() and hotSpotsAtLine() method return all of the hotspots in the text and on
326 * a given line respectively.
327 */
328class QTERMWIDGET_EXPORT FilterChain : protected QList<Filter*>
329{
330public:
331    virtual ~FilterChain();
332
333    /** Adds a new filter to the chain.  The chain will delete this filter when it is destroyed */
334    void addFilter(Filter* filter);
335    /** Removes a filter from the chain.  The chain will no longer delete the filter when destroyed */
336    void removeFilter(Filter* filter);
337    /** Returns true if the chain contains @p filter */
338    bool containsFilter(Filter* filter);
339    /** Removes all filters from the chain */
340    void clear();
341
342    /** Resets each filter in the chain */
343    void reset();
344    /**
345     * Processes each filter in the chain
346     */
347    void process();
348
349    /** Sets the buffer for each filter in the chain to process. */
350    void setBuffer(const QString* buffer , const QList<int>* linePositions);
351
352    /** Returns the first hotspot which occurs at @p line, @p column or 0 if no hotspot was found */
353    Filter::HotSpot* hotSpotAt(int line , int column) const;
354    /** Returns a list of all the hotspots in all the chain's filters */
355    QList<Filter::HotSpot*> hotSpots() const;
356    /** Returns a list of all hotspots at the given line in all the chain's filters */
357    QList<Filter::HotSpot> hotSpotsAtLine(int line) const;
358
359};
360
361/** A filter chain which processes character images from terminal displays */
362class QTERMWIDGET_NO_EXPORT TerminalImageFilterChain : public FilterChain
363{
364public:
365    TerminalImageFilterChain();
366    ~TerminalImageFilterChain() override;
367
368    /**
369     * Set the current terminal image to @p image.
370     *
371     * @param image The terminal image
372     * @param lines The number of lines in the terminal image
373     * @param columns The number of columns in the terminal image
374     * @param lineProperties The line properties to set for image
375     */
376    void setImage(const Character* const image , int lines , int columns,
377                  const QVector<LineProperty>& lineProperties);
378
379private:
380    QString* _buffer;
381    QList<int>* _linePositions;
382};
383
384}
385
386typedef Konsole::Filter Filter;
387
388#endif //FILTER_H
Note: See TracBrowser for help on using the repository browser.