source: ogBrowser-Git/qtermwidget/lib/Filter.h

jenkins
Last change on this file was fedf2a2, checked in by Vadim Troshchinskiy Shmelev <vtroshchinskiy@…>, 18 months ago

Update Qtermwidget to Qt6 version
Remove build files

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