GNU Octave  4.2.1
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.cpp
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 // Own
23 #include "unix/Filter.h"
24 
25 // System
26 #include <iostream>
27 
28 // Qt
29 #include <QAction>
30 #include <QApplication>
31 #include <QClipboard>
32 #include <QtCore/QString>
33 
34 #include <QtCore/QSharedData>
35 #include <QtCore>
36 
37 // Konsole
39 
41 {
42  QMutableListIterator<Filter*> iter(*this);
43 
44  while ( iter.hasNext() )
45  {
46  Filter* filter = iter.next();
47  iter.remove();
48  delete filter;
49  }
50 }
51 
53 {
54  append(filter);
55 }
57 {
58  removeAll(filter);
59 }
61 {
62  return contains(filter);
63 }
65 {
66  QListIterator<Filter*> iter(*this);
67  while (iter.hasNext())
68  iter.next()->reset();
69 }
70 void FilterChain::setBuffer(const QString* buffer , const QList<int>* linePositions)
71 {
72  QListIterator<Filter*> iter(*this);
73  while (iter.hasNext())
74  iter.next()->setBuffer(buffer,linePositions);
75 }
77 {
78  QListIterator<Filter*> iter(*this);
79  while (iter.hasNext())
80  iter.next()->process();
81 }
83 {
85 }
87 {
88  QListIterator<Filter*> iter(*this);
89  while (iter.hasNext())
90  {
91  Filter* filter = iter.next();
92  Filter::HotSpot* spot = filter->hotSpotAt(line,column);
93  if ( spot != 0 )
94  {
95  return spot;
96  }
97  }
98 
99  return 0;
100 }
101 
103 {
105  QListIterator<Filter*> iter(*this);
106  while (iter.hasNext())
107  {
108  Filter* filter = iter.next();
109  list << filter->hotSpots();
110  }
111  return list;
112 }
113 
115 : _buffer(0)
116 , _linePositions(0)
117 {
118 }
119 
121 {
122  delete _buffer;
123  delete _linePositions;
124 }
125 
126 void TerminalImageFilterChain::setImage(const Character* const image , int lines , int columns, const QVector<LineProperty>& lineProperties)
127 {
128 //qDebug("%s %d", __FILE__, __LINE__);
129  if (empty())
130  return;
131 //qDebug("%s %d", __FILE__, __LINE__);
132 
133  // reset all filters and hotspots
134  reset();
135 //qDebug("%s %d", __FILE__, __LINE__);
136 
137  PlainTextDecoder decoder;
138  decoder.setTrailingWhitespace(false);
139 
140 //qDebug("%s %d", __FILE__, __LINE__);
141  // setup new shared buffers for the filters to process on
142  QString* newBuffer = new QString();
143  QList<int>* newLinePositions = new QList<int>();
144  setBuffer( newBuffer , newLinePositions );
145 
146  // free the old buffers
147  delete _buffer;
148  delete _linePositions;
149 
150  _buffer = newBuffer;
151  _linePositions = newLinePositions;
152 
153  QTextStream lineStream(_buffer);
154  decoder.begin(&lineStream);
155 
156  for (int i=0 ; i < lines ; i++)
157  {
158  _linePositions->append(_buffer->length());
159  decoder.decodeLine(image + i*columns,columns,LINE_DEFAULT);
160 
161  // pretend that each line ends with a newline character.
162  // this prevents a link that occurs at the end of one line
163  // being treated as part of a link that occurs at the start of the next line
164  //
165  // the downside is that links which are spread over more than one line are not
166  // highlighted.
167  //
168  // TODO - Use the "line wrapped" attribute associated with lines in a
169  // terminal image to avoid adding this imaginary character for wrapped
170  // lines
171  if ( !(lineProperties.value(i,LINE_DEFAULT) & LINE_WRAPPED) )
172  lineStream << QChar('\n');
173  }
174  decoder.end();
175 // qDebug("%s %d", __FILE__, __LINE__);
176 }
177 
179 _linePositions(0),
180 _buffer(0)
181 {
182 }
183 
185 {
186  QListIterator<HotSpot*> iter(_hotspotList);
187  while (iter.hasNext())
188  {
189  delete iter.next();
190  }
191 }
193 {
194  _hotspots.clear();
195  _hotspotList.clear();
196 }
197 
198 void Filter::setBuffer(const QString* buffer , const QList<int>* linePositions)
199 {
200  _buffer = buffer;
201  _linePositions = linePositions;
202 }
203 
204 void Filter::getLineColumn(int position , int& startLine , int& startColumn)
205 {
206  Q_ASSERT( _linePositions );
207  Q_ASSERT( _buffer );
208 
209 
210  for (int i = 0 ; i < _linePositions->count() ; i++)
211  {
212  //kDebug() << "line position at " << i << " = " << _linePositions[i];
213  int nextLine = 0;
214 
215  if ( i == _linePositions->count()-1 )
216  {
217  nextLine = _buffer->length() + 1;
218  }
219  else
220  {
221  nextLine = _linePositions->value(i+1);
222  }
223 
224  // kDebug() << "pos - " << position << " line pos(" << i<< ") " << _linePositions->value(i) <<
225  // " next = " << nextLine << " buffer len = " << _buffer->length();
226 
227  if ( _linePositions->value(i) <= position && position < nextLine )
228  {
229  startLine = i;
230  startColumn = position - _linePositions->value(i);
231  return;
232  }
233  }
234 }
235 
236 
237 /*void Filter::addLine(const QString& text)
238 {
239  _linePositions << _buffer.length();
240  _buffer.append(text);
241 }*/
242 
243 const QString* Filter::buffer()
244 {
245  return _buffer;
246 }
248 {
249 }
251 {
252  _hotspotList << spot;
253 
254  for (int line = spot->startLine() ; line <= spot->endLine() ; line++)
255  {
256  _hotspots.insert(line,spot);
257  }
258 }
260 {
261  return _hotspotList;
262 }
264 {
265  return _hotspots.values(line);
266 }
267 
269 {
270  QListIterator<HotSpot*> spotIter(_hotspots.values(line));
271 
272  while (spotIter.hasNext())
273  {
274  HotSpot* spot = spotIter.next();
275 
276  if ( spot->startLine() == line && spot->startColumn() > column )
277  continue;
278  if ( spot->endLine() == line && spot->endColumn() < column )
279  continue;
280 
281  return spot;
282  }
283 
284  return 0;
285 }
286 
287 Filter::HotSpot::HotSpot(int startLine , int startColumn , int endLine , int endColumn)
288  : _startLine(startLine)
289  , _startColumn(startColumn)
290  , _endLine(endLine)
291  , _endColumn(endColumn)
292  , _type(NotSpecified)
293 {
294 }
296 {
297  return QString();
298 }
300 {
301  return QList<QAction*>();
302 }
304 {
305  return _startLine;
306 }
308 {
309  return _endLine;
310 }
312 {
313  return _startColumn;
314 }
316 {
317  return _endColumn;
318 }
320 {
321  return _type;
322 }
324 {
325  _type = type;
326 }
327 
329 {
330 }
331 
332 RegExpFilter::HotSpot::HotSpot(int startLine,int startColumn,int endLine,int endColumn)
333  : Filter::HotSpot(startLine,startColumn,endLine,endColumn)
334 {
335  setType(Marker);
336 }
337 
339 {
340 }
341 
342 void RegExpFilter::HotSpot::setCapturedTexts(const QStringList& texts)
343 {
344  _capturedTexts = texts;
345 }
347 {
348  return _capturedTexts;
349 }
350 
351 void RegExpFilter::setRegExp(const QRegExp& regExp)
352 {
354 }
355 QRegExp RegExpFilter::regExp() const
356 {
357  return _searchText;
358 }
359 /*void RegExpFilter::reset(int)
360 {
361  _buffer = QString();
362 }*/
364 {
365  int pos = 0;
366  const QString* text = buffer();
367 
368  Q_ASSERT( text );
369 
370  // ignore any regular expressions which match an empty string.
371  // otherwise the while loop below will run indefinitely
372  static const QString emptyString("");
373  if ( _searchText.exactMatch(emptyString) )
374  return;
375 
376  while(pos >= 0)
377  {
378  pos = _searchText.indexIn(*text,pos);
379 
380  if ( pos >= 0 )
381  {
382 
383  int startLine = 0;
384  int endLine = 0;
385  int startColumn = 0;
386  int endColumn = 0;
387 
388 
389  //kDebug() << "pos from " << pos << " to " << pos + _searchText.matchedLength();
390 
391  getLineColumn(pos,startLine,startColumn);
392  getLineColumn(pos + _searchText.matchedLength(),endLine,endColumn);
393 
394  //kDebug() << "start " << startLine << " / " << startColumn;
395  //kDebug() << "end " << endLine << " / " << endColumn;
396 
397  RegExpFilter::HotSpot* spot = newHotSpot(startLine,startColumn,
398  endLine,endColumn);
399  spot->setCapturedTexts(_searchText.capturedTexts());
400 
401  addHotSpot( spot );
402  pos += _searchText.matchedLength();
403 
404  // if matchedLength == 0, the program will get stuck in an infinite loop
405  Q_ASSERT( _searchText.matchedLength() > 0 );
406  }
407  }
408 }
409 
410 RegExpFilter::HotSpot* RegExpFilter::newHotSpot(int startLine,int startColumn,
411  int endLine,int endColumn)
412 {
413  return new RegExpFilter::HotSpot(startLine,startColumn,
414  endLine,endColumn);
415 }
416 RegExpFilter::HotSpot* UrlFilter::newHotSpot(int startLine,int startColumn,int endLine,
417  int endColumn)
418 {
419  return new UrlFilter::HotSpot(startLine,startColumn,
420  endLine,endColumn);
421 }
422 UrlFilter::HotSpot::HotSpot(int startLine,int startColumn,int endLine,int endColumn)
423 : RegExpFilter::HotSpot(startLine,startColumn,endLine,endColumn)
424 , _urlObject(new FilterObject(this))
425 {
426  setType(Link);
427 }
429 {
430  QString url = capturedTexts().first();
431 
432  const UrlType kind = urlType();
433 
434  if ( kind == StandardUrl )
435  return QString();
436  else if ( kind == Email )
437  return QString();
438  else
439  return QString();
440 }
442 {
443  QString url = capturedTexts().first();
444 
445  if ( FullUrlRegExp.exactMatch(url) )
446  return StandardUrl;
447  else if ( EmailAddressRegExp.exactMatch(url) )
448  return Email;
449  else
450  return Unknown;
451 }
452 
454 {
455  QString url = capturedTexts().first();
456 
457  const UrlType kind = urlType();
458 
459  const QString& actionName = object ? object->objectName() : QString();
460 
461  if ( actionName == "copy-action" )
462  {
463  //kDebug() << "Copying url to clipboard:" << url;
464 
465  QApplication::clipboard()->setText(url);
466  return;
467  }
468 
469  if ( !object || actionName == "open-action" )
470  {
471  if ( kind == StandardUrl )
472  {
473  // if the URL path does not include the protocol ( eg. "www.kde.org" ) then
474  // prepend http:// ( eg. "www.kde.org" --> "http://www.kde.org" )
475  if (!url.contains("://"))
476  {
477  url.prepend("http://");
478  }
479  }
480  else if ( kind == Email )
481  {
482  url.prepend("mailto:");
483  }
484 
485 // new KRun(url,QApplication::activeWindow());
486  }
487 }
488 
489 // Note: Altering these regular expressions can have a major effect on the performance of the filters
490 // used for finding URLs in the text, especially if they are very general and could match very long
491 // pieces of text.
492 // Please be careful when altering them.
493 
494 //regexp matches:
495 // full url:
496 // protocolname:// or www. followed by anything other than whitespaces, <, >, ' or ", and ends before whitespaces, <, >, ', ", ], !, comma and dot
497 const QRegExp UrlFilter::FullUrlRegExp("(www\\.(?!\\.)|[a-z][a-z0-9+.-]*://)[^\\s<>'\"]+[^!,\\.\\s<>'\"\\]]");
498 // email address:
499 // [word chars, dots or dashes]@[word chars, dots or dashes].[word chars]
500 const QRegExp UrlFilter::EmailAddressRegExp("\\b(\\w|\\.|-)+@(\\w|\\.|-)+\\.\\w+\\b");
501 
502 // matches full url or email address
503 const QRegExp UrlFilter::CompleteUrlRegExp('('+FullUrlRegExp.pattern()+'|'+
504  EmailAddressRegExp.pattern()+')');
505 
507 {
509 }
511 {
512  delete _urlObject;
513 }
515 {
516  _filter->activate(sender());
517 }
519 {
521 
522  const UrlType kind = urlType();
523 
524  QAction* openAction = new QAction(_urlObject);
525  QAction* copyAction = new QAction(_urlObject);;
526 
527  Q_ASSERT( kind == StandardUrl || kind == Email );
528 
529  if ( kind == StandardUrl )
530  {
531  openAction->setText(("Open Link"));
532  copyAction->setText(("Copy Link Address"));
533  }
534  else if ( kind == Email )
535  {
536  openAction->setText(("Send Email To..."));
537  copyAction->setText(("Copy Email Address"));
538  }
539 
540  // object names are set here so that the hotspot performs the
541  // correct action when activated() is called with the triggered
542  // action passed as a parameter.
543  openAction->setObjectName("open-action");
544  copyAction->setObjectName("copy-action");
545 
546  QObject::connect( openAction , SIGNAL(triggered()) , _urlObject , SLOT(activated()) );
547  QObject::connect( copyAction , SIGNAL(triggered()) , _urlObject , SLOT(activated()) );
548 
549  list << openAction;
550  list << copyAction;
551 
552  return list;
553 }
554 
555 //#include "moc_Filter.cpp"
virtual QList< QAction * > actions()
Returns a list of actions associated with the hotspot which can be used in a menu or toolbar...
Definition: Filter.cpp:299
int startColumn() const
Returns the column on startLine() where the hotspot area starts.
Definition: Filter.cpp:311
QStringList capturedTexts() const
Returns the texts found by the filter when matching the filter's regular expression.
Definition: Filter.cpp:346
int endLine() const
Returns the line where the hotspot area ends.
Definition: Filter.cpp:307
const QList< int > * _linePositions
Definition: Filter.h:180
OCTAVE_EXPORT octave_value_list column
Definition: sparse.cc:123
void addHotSpot(HotSpot *)
Adds a new hotspot to the list.
Definition: Filter.cpp:250
virtual ~Filter()
Definition: Filter.cpp:184
void reset()
Resets each filter in the chain.
Definition: Filter.cpp:64
void clear()
Removes all filters from the chain.
Definition: Filter.cpp:82
The value of lines which begin with a space character are not saved in the history list A value of all commands are saved on the history list
Definition: oct-hist.cc:728
const QString * buffer()
Returns the internal buffer.
Definition: Filter.cpp:243
UrlFilter()
Definition: Filter.cpp:506
virtual ~HotSpot()
Definition: Filter.cpp:510
HotSpot(int startLine, int startColumn, int endLine, int endColumn)
Definition: Filter.cpp:422
A single character in the terminal which consists of a unicode character value, foreground and backgr...
Definition: Character.h:55
void addFilter(Filter *filter)
Adds a new filter to the chain.
Definition: Filter.cpp:52
void getLineColumn(int position, int &startLine, int &startColumn)
Converts a character position within buffer() to a line and column.
Definition: Filter.cpp:204
virtual QString tooltip() const
Returns the text of a tooltip to be shown when the mouse moves over the hotspot, or an empty string i...
Definition: Filter.cpp:428
bool containsFilter(Filter *filter)
Returns true if the chain contains filter.
Definition: Filter.cpp:60
Represents an area of text which matched the pattern a particular filter has been looking for...
Definition: Filter.h:69
Filter::HotSpot * hotSpotAt(int line, int column) const
Returns the first hotspot which occurs at line, column or 0 if no hotspot was found.
Definition: Filter.cpp:86
A filter which searches for sections of text matching a regular expression and creates a new RegExpFi...
Definition: Filter.h:191
QList< int > * _linePositions
Definition: Filter.h:376
virtual ~TerminalImageFilterChain()
Definition: Filter.cpp:120
QRegExp regExp() const
Returns the regular expression which the filter searches for in blocks of text.
Definition: Filter.cpp:355
A filter processes blocks of text looking for certain patterns (such as URLs or keywords from a list)...
Definition: Filter.h:54
int startLine() const
Returns the line when the hotspot area starts.
Definition: Filter.cpp:303
void process()
Processes each filter in the chain.
Definition: Filter.cpp:76
virtual RegExpFilter::HotSpot * newHotSpot(int startLine, int startColumn, int endLine, int endColumn)
Called when a match for the regular expression is encountered.
Definition: Filter.cpp:410
HotSpot(int startLine, int startColumn, int endLine, int endColumn)
Constructs a new hotspot which covers the area from (startLine,startColumn) to (endLine,endColumn) in a block of text.
Definition: Filter.cpp:287
QList< HotSpot * > hotSpotsAtLine(int line) const
Returns the list of hotspots identified by the filter which occur on a given line.
Definition: Filter.cpp:263
virtual QList< QAction * > actions()
Returns a list of actions associated with the hotspot which can be used in a menu or toolbar...
Definition: Filter.cpp:518
const QString * _buffer
Definition: Filter.h:181
QList< HotSpot * > _hotspotList
Definition: Filter.h:178
QList< Filter::HotSpot * > hotSpots() const
Returns a list of all the hotspots in all the chain's filters.
Definition: Filter.cpp:102
HotSpot(int startLine, int startColumn, int endLine, int endColumn)
Definition: Filter.cpp:332
virtual void process()
Reimplemented to search the filter's text buffer for text matching regExp()
Definition: Filter.cpp:363
static const int LINE_WRAPPED
Definition: Character.h:37
void setBuffer(const QString *buffer, const QList< int > *linePositions)
Sets the buffer for each filter in the chain to process.
Definition: Filter.cpp:70
A terminal character decoder which produces plain text, ignoring colours and other appearance-related...
virtual ~FilterChain()
Definition: Filter.cpp:40
create a structure array and initialize its values The dimensions of each cell array of values must match Singleton cells and non cell values are repeated so that they fill the entire array If the cells are empty
Definition: ov-struct.cc:1688
QList< HotSpot * > hotSpots() const
Returns the list of hotspots identified by the filter.
Definition: Filter.cpp:259
void reset()
Empties the filters internal buffer and resets the line count back to 0.
Definition: Filter.cpp:192
virtual RegExpFilter::HotSpot * newHotSpot(int, int, int, int)
Called when a match for the regular expression is encountered.
Definition: Filter.cpp:416
void setType(Type type)
Sets the type of a hotspot.
Definition: Filter.cpp:323
Filter()
Constructs a new filter.
Definition: Filter.cpp:178
UrlType urlType() const
Definition: Filter.cpp:441
HotSpot * hotSpotAt(int line, int column) const
Adds a new line of text to the filter and increments the line count.
Definition: Filter.cpp:268
static const QRegExp EmailAddressRegExp
Definition: Filter.h:290
void setRegExp(const QRegExp &text)
Sets the regular expression which the filter searches for in blocks of text.
Definition: Filter.cpp:351
QRegExp _searchText
Definition: Filter.h:242
static const QRegExp FullUrlRegExp
Definition: Filter.h:289
bool append
Definition: load-save.cc:1582
RegExpFilter()
Constructs a new regular expression filter.
Definition: Filter.cpp:328
returns the type of the matrix and caches it for future use Called with more than one the function will not attempt to guess the type if it is still unknown This is useful for debugging purposes The possible matrix types depend on whether the matrix is full or and can be one of the following able sis tem and mark type as unknown tem as the structure of the matrix explicitly gives this(Sparse matrices only) tem code
Definition: matrix_type.cc:120
virtual void activate(QObject *object=0)
Open a web browser at the current URL.
Definition: Filter.cpp:453
virtual ~HotSpot()
Definition: Filter.cpp:247
idx type
Definition: ov.cc:3129
MArray< T > filter(MArray< T > &b, MArray< T > &a, MArray< T > &x, MArray< T > &si, int dim=0)
Definition: filter.cc:43
virtual void decodeLine(const Character *const characters, int count, LineProperty properties)
Converts a line of terminal characters with associated properties into a text string and writes the s...
std::string url
Definition: urlwrite.cc:337
void removeFilter(Filter *filter)
Removes a filter from the chain.
Definition: Filter.cpp:56
Type of hotspot created by RegExpFilter.
Definition: Filter.h:198
void setTrailingWhitespace(bool enable)
Set whether trailing whitespace at the end of lines should be included in the output.
static const QRegExp CompleteUrlRegExp
Definition: Filter.h:293
=val(i)}if ode{val(i)}occurs in table i
Definition: lookup.cc:239
virtual QString tooltip() const
Returns the text of a tooltip to be shown when the mouse moves over the hotspot, or an empty string i...
Definition: Filter.cpp:295
void setImage(const Character *const image, int lines, int columns, const QVector< LineProperty > &lineProperties)
Set the current terminal image to image.
Definition: Filter.cpp:126
void activated()
Definition: Filter.cpp:514
static const int LINE_DEFAULT
Definition: Character.h:36
int endColumn() const
Returns the column on endLine() where the hotspot area ends.
Definition: Filter.cpp:315
void setBuffer(const QString *buffer, const QList< int > *linePositions)
TODO: Document me.
Definition: Filter.cpp:198
virtual void end()
End decoding.
Type type() const
Returns the type of the hotspot.
Definition: Filter.cpp:319
void setCapturedTexts(const QStringList &texts)
Sets the captured texts associated with this hotspot.
Definition: Filter.cpp:342
static void clear(octave::dynamic_library &oct_file)
Definition: dynamic-ld.cc:230
QMultiHash< int, HotSpot * > _hotspots
Definition: Filter.h:177
virtual void begin(QTextStream *output)
Begin decoding characters.
virtual void activate(QObject *object=0)
Causes the an action associated with a hotspot to be triggered.
Definition: Filter.cpp:338
Hotspot type created by UrlFilter instances.
Definition: Filter.h:255