WARNING: USE THIS SOFTWARE AT YOUR OWN RISK! THIS IS EXPERIMENTAL SOFTWARE NOT INTENDED FOR PRODUCTION USE! Zuble is currently an early stage prototype. As such Zuble is minimally tested and inherently unstable. It is provided for experimental, development, and demonstration purposes only. Zuble QML Types   |  Zuble C++ Classes   |  Zuble Overview
Zuble  0.1
Zuble Framework C++/QML extension API
ZblLogScanner.cpp
Go to the documentation of this file.
1 #include "ZblLogScanner.h"
2 #include "ZblLogSearch.h"
3 #include "ZLogViewport.h"
4 #include "ZblLogManager.h"
5 #include <QSet>
6 
7 namespace Zbl
8 {
9 
10 const QString ZblLogScanner::m_highlightColor = "blue"; // TBD: should come from settings file
11 
13 {
14  m_params = NULL;
15  m_markupColumn = false;
16  m_findCompleteSent = false;
18 }
19 
21  const ZblLogSearchParams *searchParams,
22  controlFlags control,
23  bool markupColumn)
24 {
25  m_params = searchParams;
26  m_controlFlags = control;
27  m_markupColumn = markupColumn;
28 
29 
30  if(!m_markupColumn)
32 
34 }
35 
36 QVariantList ZblLogScanner::markupOrdinalRoleList(QVariantList data)
37 {
38  const QList<int> roles = m_params->roles();
39 
40  const int roleCount = roles.count();
41  //const int dataCount = data.count();
42 
43  for(int roleIndex=0; roleIndex < roleCount; roleIndex++)
44  {
45  if(roleIndex >= roleCount || roleIndex < 0)
46  continue;
47 
48  bool searchTextFound = false;
49 
50  const int role = roles.at(roleIndex);
51 
52  QVariant next = data.at(role);
53 
54  data[role] = scanTextValue(next, searchTextFound);
55  }
56 
57  return data;
58 }
59 
60 
61 // TBD: scanModelColumnRows method will take a model and chunk size, loop grabbing chunks
62 // from model and passing to markupTableColumnRows --> scanTableColumnRows(columnRows, markup, linklist*)
63 
64 
66  ZTableModel* model,
67  int chunkSize,
68  ZLogViewport* viewport,
69  qint64 currentRecordID)
70 {
71  ZblLogSearchList searchList;
72 
73  if(!chunkSize || !model)
74  return searchList;
75 
76  const int modelRowCount = model->modelRowCount();
77 
78  const int chunkActualSize = chunkSize < modelRowCount ? chunkSize : modelRowCount;
79 
80  const int chunkCount = modelRowCount / chunkActualSize;
81 
82  const int chunkFraction = modelRowCount % chunkActualSize;
83 
84  QList<int> scanRoles = m_params->roles();
85 
86  if(signalRowsMatched() || (viewport && signalFindComplete()))
87  {
88  if(!scanRoles.contains(ZblLogManager::LogFieldRecordNum))
89  scanRoles.append(ZblLogManager::LogFieldRecordNum);
90 
91  if(!scanRoles.contains(ZLogViewport::getSeekIndexRole()))
92  scanRoles.append(ZLogViewport::getSeekIndexRole());
93  }
94 
95  for(int i=0; i < chunkCount; i++)
96  {
97  const int startRow = i * chunkActualSize;
98 
99  QVariant vRows =
100  model->getTableColumnRows(scanRoles, startRow, 0, chunkActualSize);
101 
102  ZTableRowList rows = vRows.value<ZTableRowList>();
103 
104  rows = scanTableColumnRows(rows, searchList, viewport);
105 
106  vRows = QVariant::fromValue<ZTableRowList>(rows);
107 
108  model->putTableColumnRows(vRows, startRow, 1);
109  }
110 
111  if(chunkFraction)
112  {
113  const int startRow = chunkCount * chunkActualSize;
114 
115  QVariant vRows =
116  model->getTableColumnRows( m_params->roles(), startRow, 0, chunkFraction);
117 
118  ZTableRowList rows = vRows.value<ZTableRowList>();
119 
120  rows = scanTableColumnRows(rows, searchList, viewport);
121 
122  vRows = QVariant::fromValue<ZTableRowList>(rows);
123 
124  model->putTableColumnRows(vRows, startRow, 0);
125  }
126 
127 #if 0
128 
129  if(m_search && signalRowsMatched() && !searchList.m_links.isEmpty())
130  emit m_search->searchRowsMatched(searchList);
131 
132 #endif
133 
134  return searchList;
135 }
136 
138  ZTableRowList columnRows,
139  ZblLogSearchList &searchList,
140  ZLogViewport* viewport)
141 {
142  ZTableRowList outRows;
143 
144  if(!m_params)
145  return outRows;
146 
147  const int rowCount = columnRows.count();
148 
149  const QList<int>scanRoles = m_params->roles();
150 
151 
152  // TBD: optionally create link list for searchRowMatched --> searchRowsMatched, optionally do markup operation
153 
154  for(int row=0; row < rowCount; row++)
155  {
156 
157  QMap<int, QVariant> nextRow = columnRows.at(row);
158  QList<int> roles = nextRow.keys();
159 
160  QMap<int, QVariant> outRow;
161  QList<int> rolesFound;
162 
163 
164  const int roleCount = roles.count();
165 
166  //qint64 lastRecordID = -1;
167 
168  for(int roleIndex = 0; roleIndex < roleCount; roleIndex++)
169  {
170  bool searchTextFound = false;
171 
172  const int role = roles.at(roleIndex);
173 
174  QVariant nextValue = nextRow.value(role);
175 
176  if(scanRoles.contains(role))
177  nextValue = scanTextValue(nextValue, searchTextFound);
178 
180  outRow.insert(role, nextValue);
181 
182  if(searchTextFound)
183  {
184  rolesFound.append(role);
185  }
186  }
187 
189  {
190  outRows.append(outRow);
191  outRow.clear();
192  }
193 
194  if(signalRowsMatched() && !rolesFound.isEmpty())
195  {
196  searchList.addRow(
197  getRowID(nextRow),
198  getRowSeekPos(nextRow),
199  rolesFound);
200  }
201  }
202 
203  return outRows;
204 }
205 
206 QVariant ZblLogScanner::scanTextValue(QVariant data, bool &searchTextFound)
207 {
208  if(!m_params)
209  {
210  searchTextFound = false;
211  return QVariant();
212  }
213 
214  QString markup;
215  QString text = data.toString();
216 
217  const int textLen = text.length();
218  const int searchLen = m_params->phrase().length();
219 
220  if(!searchLen || !textLen)
221  return data;
222 
223  QString fontStart = QString("<font color=\"%1\">").arg(m_highlightColor);
224 
225  int lastIx = 0;
226 
227  QString searchPhrase(m_params->phrase());
228 
229  for(int nextIx = text.indexOf(searchPhrase, 0, Qt::CaseInsensitive); nextIx != -1;
230  nextIx = text.indexOf(searchPhrase, lastIx, Qt::CaseInsensitive))
231  {
232  searchTextFound = true;
233 
234  if(!outputHighlightedText())
235  return data;
236 
237  markup += text.mid(lastIx, nextIx) + fontStart
238  + text.mid(nextIx, searchLen)
239  + "</font>";
240 
241  lastIx = nextIx + searchLen;
242  }
243 
244  if(!searchTextFound)
245  return data;
246 
247  if(textLen > lastIx + 1)
248  markup += text.mid(lastIx);
249 
250  return QVariant(markup);
251 }
252 
253 qint64 ZblLogScanner::getRowID(QMap<int, QVariant> row)
254 {
255  return row.value(ZblLogManager::LogFieldRecordNum).toInt();
256 }
257 
258 qint64 ZblLogScanner::getRowSeekPos(QMap<int, QVariant> row)
259 {
260  return row.value(ZLogViewport::getSeekIndexRole()).toInt();
261 }
262 
263 } // Zbl
bool signalFindComplete()
Determine if scanner will send rowsMatched signals.
ZTableRowList scanTableColumnRows(ZTableRowList columnRows, ZblLogSearchList &searchList, ZLogViewport *viewport=NULL)
Scans a log viewport data model for search text.
qint64 getRowID(QMap< int, QVariant > row)
bool m_markupColumn
True if the data model has an optional markup column.
ZblLogScanner()
Constructs an invalid scanner/highlighter object.
static const QString m_highlightColor
The color to highlight text that mataches the search parameters.
bool signalRowsMatched()
Determine if scanner will send rowsMatched signals.
This class allows Zuble log file viewer text search operations to pass parameters between threads...
void addRow(qint64 recordID, qint64 seekPos, QList< int > rolesFound)
bool outputHighlightedText()
Determine if scanner is enabled.
QList< int > roles() const
QVariant scanTextValue(QVariant data, bool &searchTextFound)
Returns a highlighted text string for the specified QVariant object.
A log viewport encapsulates a ZTableModel containing a contiguous subset of log records from a Zuble ...
Definition: ZLogViewport.h:95
Definition: ZAndGate.cpp:6
QList< LinkNode > m_links
This two dimensional table model is used to store and manipulate data.
Definition: ZTableModel.h:96
const ZblLogSearchParams * m_params
Search parameters to be used by the text scanning algorithms.
QList< QMap< int, QVariant > > ZTableRowList
Represents multiple rows of data cell values for multiple roles for a single column.
Definition: ZTableModel.h:75
bool m_findCompleteSent
true if fineComplete signal has been sent, false otherwise;
Q_INVOKABLE int modelRowCount() const
Returns the number of rows in the data set. This method may block the current thread.
Q_INVOKABLE QVariant getTableColumnRows(QList< int > roles, int startRow, int col, int rowCount)
Obtain data values for a set of rows from a single model column.
controlFlags m_controlFlags
These flags control the output of the scanner.
This class allows Zuble log file viewer text search operations to pass search results between threads...
Q_INVOKABLE void putTableColumnRows(QVariant rows, int startRow, int col)
Replaces the current value for a set of rows for a single model column.
static int getSeekIndexRole()
Obtain the role number for the file seek position of a log record in the viewport&#39;s log record data m...
qint64 getRowSeekPos(QMap< int, QVariant > row)
QVariantList markupOrdinalRoleList(QVariantList data)
Returns a highlighted text string for the specified QVariant objects.
ZblLogSearchList scanModelColumnRows(ZTableModel *model, int chunkSize, ZLogViewport *viewport=NULL, qint64 currentRecordID=-1)
scanModelColumnRows