~verzegnassi-stefano/+junk/ubuntu-terminal-app-uitk13

« back to all changes in this revision

Viewing changes to src/plugin/qmltermwidget/qtermwidget/lib/Filter.h

  • Committer: Filippo Scognamiglio
  • Date: 2014-10-25 04:42:31 UTC
  • Revision ID: flscogna@gmail.com-20141025044231-javjhusbqa171127
Initial reboot commit.

Show diffs side-by-side

added added

removed removed

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