GNU Octave  3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Filter.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2007, 2013 by Robert Knight <robertknight@gmail.com>
3 
4  Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  02110-1301 USA.
20 */
21 
22 #ifndef FILTER_H
23 #define FILTER_H
24 
25 // Qt
26 #include <QAction>
27 #include <QtCore/QList>
28 #include <QtCore/QObject>
29 #include <QtCore/QStringList>
30 #include <QtCore/QHash>
31 #include <QtCore/QRegExp>
32 
33 // Local
34 #include "unix/Character.h"
35 
36 /**
37  * A filter processes blocks of text looking for certain patterns (such as URLs or keywords from a list)
38  * and marks the areas which match the filter's patterns as 'hotspots'.
39  *
40  * Each hotspot has a type identifier associated with it ( such as a link or a highlighted section ),
41  * and an action. When the user performs some activity such as a mouse-click in a hotspot area ( the exact
42  * action will depend on what is displaying the block of text which the filter is processing ), the hotspot's
43  * activate() method should be called. Depending on the type of hotspot this will trigger a suitable response.
44  *
45  * For example, if a hotspot represents a URL then a suitable action would be opening that URL in a web browser.
46  * Hotspots may have more than one action, in which case the list of actions can be obtained using the
47  * actions() method.
48  *
49  * Different subclasses of filter will return different types of hotspot.
50  * Subclasses must reimplement the process() method to examine a block of text and identify sections of interest.
51  * When processing the text they should create instances of Filter::HotSpot subclasses for sections of interest
52  * and add them to the filter's list of hotspots using addHotSpot()
53  */
54 class Filter
55 {
56 public:
57  /**
58  * Represents an area of text which matched the pattern a particular filter has been looking for.
59  *
60  * Each hotspot has a type identifier associated with it ( such as a link or a highlighted section ),
61  * and an action. When the user performs some activity such as a mouse-click in a hotspot area ( the exact
62  * action will depend on what is displaying the block of text which the filter is processing ), the hotspot's
63  * activate() method should be called. Depending on the type of hotspot this will trigger a suitable response.
64  *
65  * For example, if a hotspot represents a URL then a suitable action would be opening that URL in a web browser.
66  * Hotspots may have more than one action, in which case the list of actions can be obtained using the
67  * actions() method. These actions may then be displayed in a popup menu or toolbar for example.
68  */
69  class HotSpot
70  {
71  public:
72  /**
73  * Constructs a new hotspot which covers the area from (@p startLine,@p startColumn) to (@p endLine,@p endColumn)
74  * in a block of text.
75  */
76  HotSpot(int startLine , int startColumn , int endLine , int endColumn);
77  virtual ~HotSpot();
78 
79  enum Type
80  {
81  // the type of the hotspot is not specified
83  // this hotspot represents a clickable link
85  // this hotspot represents a marker
87  };
88 
89  /** Returns the line when the hotspot area starts */
90  int startLine() const;
91  /** Returns the line where the hotspot area ends */
92  int endLine() const;
93  /** Returns the column on startLine() where the hotspot area starts */
94  int startColumn() const;
95  /** Returns the column on endLine() where the hotspot area ends */
96  int endColumn() const;
97  /**
98  * Returns the type of the hotspot. This is usually used as a hint for views on how to represent
99  * the hotspot graphically. eg. Link hotspots are typically underlined when the user mouses over them
100  */
101  Type type() const;
102  /**
103  * Causes the an action associated with a hotspot to be triggered.
104  *
105  * @param object The object which caused the hotspot to be triggered. This is
106  * typically null ( in which case the default action should be performed ) or
107  * one of the objects from the actions() list. In which case the associated
108  * action should be performed.
109  */
110  virtual void activate(QObject* object = 0) = 0;
111  /**
112  * Returns a list of actions associated with the hotspot which can be used in a
113  * menu or toolbar
114  */
115  virtual QList<QAction*> actions();
116 
117  /**
118  * Returns the text of a tooltip to be shown when the mouse moves over the hotspot, or
119  * an empty string if there is no tooltip associated with this hotspot.
120  *
121  * The default implementation returns an empty string.
122  */
123  virtual QString tooltip() const;
124 
125  protected:
126  /** Sets the type of a hotspot. This should only be set once */
127  void setType(Type type);
128 
129  private:
132  int _endLine;
135 
136  };
137 
138  /** Constructs a new filter. */
139  Filter();
140  virtual ~Filter();
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 */
162 
163  /**
164  * TODO: Document me
165  */
166  void setBuffer(const QString* buffer , const QList<int>* linePositions);
167 
168 protected:
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 
176 private:
177  QMultiHash<int,HotSpot*> _hotspots;
179 
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  */
191 class RegExpFilter : public Filter
192 {
193 public:
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  virtual void activate(QObject* object = 0);
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  virtual void process();
232 
233 protected:
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 
241 private:
242  QRegExp _searchText;
243 };
244 
245 class FilterObject;
246 
247 /** A filter which matches URLs in blocks of text */
248 class UrlFilter : public RegExpFilter
249 {
250 public:
251  /**
252  * Hotspot type created by UrlFilter instances. The activate() method opens a web browser
253  * at the given URL when called.
254  */
256  {
257  public:
258  HotSpot(int startLine,int startColumn,int endLine,int endColumn);
259  virtual ~HotSpot();
260 
261  virtual QList<QAction*> actions();
262 
263  /**
264  * Open a web browser at the current URL. The url itself can be determined using
265  * the capturedTexts() method.
266  */
267  virtual void activate(QObject* object = 0);
268 
269  virtual QString tooltip() const;
270  private:
271  enum UrlType
272  {
276  };
277  UrlType urlType() const;
278 
280  };
281 
282  UrlFilter();
283 
284 protected:
285  virtual RegExpFilter::HotSpot* newHotSpot(int,int,int,int);
286 
287 private:
288 
289  static const QRegExp FullUrlRegExp;
290  static const QRegExp EmailAddressRegExp;
291 
292  // combined OR of FullUrlRegExp and EmailAddressRegExp
293  static const QRegExp CompleteUrlRegExp;
294 };
295 
296 class FilterObject : public QObject
297 {
298 Q_OBJECT
299 public:
301 private slots:
302  void activated();
303 private:
305 };
306 
307 /**
308  * A chain which allows a group of filters to be processed as one.
309  * The chain owns the filters added to it and deletes them when the chain itself is destroyed.
310  *
311  * Use addFilter() to add a new filter to the chain.
312  * When new text to be filtered arrives, use addLine() to add each additional
313  * line of text which needs to be processed and then after adding the last line, use
314  * process() to cause each filter in the chain to process the text.
315  *
316  * After processing a block of text, the reset() method can be used to set the filter chain's
317  * internal cursor back to the first line.
318  *
319  * The hotSpotAt() method will return the first hotspot which covers a given position.
320  *
321  * The hotSpots() and hotSpotsAtLine() method return all of the hotspots in the text and on
322  * a given line respectively.
323  */
324 class FilterChain : protected QList<Filter*>
325 {
326 public:
327  virtual ~FilterChain();
328 
329  /** Adds a new filter to the chain. The chain will delete this filter when it is destroyed */
330  void addFilter(Filter* filter);
331  /** Removes a filter from the chain. The chain will no longer delete the filter when destroyed */
332  void removeFilter(Filter* filter);
333  /** Returns true if the chain contains @p filter */
334  bool containsFilter(Filter* filter);
335  /** Removes all filters from the chain */
336  void clear();
337 
338  /** Resets each filter in the chain */
339  void reset();
340  /**
341  * Processes each filter in the chain
342  */
343  void process();
344 
345  /** Sets the buffer for each filter in the chain to process. */
346  void setBuffer(const QString* buffer , const QList<int>* linePositions);
347 
348  /** Returns the first hotspot which occurs at @p line, @p column or 0 if no hotspot was found */
349  Filter::HotSpot* hotSpotAt(int line , int column) const;
350  /** Returns a list of all the hotspots in all the chain's filters */
352  /** Returns a list of all hotspots at the given line in all the chain's filters */
353  QList<Filter::HotSpot> hotSpotsAtLine(int line) const;
354 
355 };
356 
357 /** A filter chain which processes character images from terminal displays */
359 {
360 public:
362  virtual ~TerminalImageFilterChain();
363 
364  /**
365  * Set the current terminal image to @p image.
366  *
367  * @param image The terminal image
368  * @param lines The number of lines in the terminal image
369  * @param columns The number of columns in the terminal image
370  */
371  void setImage(const Character* const image , int lines , int columns,
372  const QVector<LineProperty>& lineProperties);
373 
374 private:
375  QString* _buffer;
377 };
378 
379 #endif //FILTER_H