File: logfiltereddata.h

package info (click to toggle)
glogg 0.9.0-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 832 kB
  • sloc: cpp: 6,649; sh: 66; perl: 32; sed: 25; makefile: 11
file content (170 lines) | stat: -rw-r--r-- 6,123 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/*
 * Copyright (C) 2009, 2010, 2011, 2012 Nicolas Bonnefon and other contributors
 *
 * This file is part of glogg.
 *
 * glogg is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * glogg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with glogg.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef LOGFILTEREDDATA_H
#define LOGFILTEREDDATA_H

#include <QObject>
#include <QByteArray>
#include <QList>
#include <QVector>
#include <QStringList>
#include <QRegExp>

#include "abstractlogdata.h"
#include "logfiltereddataworkerthread.h"

class LogData;
class Marks;

// A list of matches found in a LogData, it stores all the matching lines,
// which can be accessed using the AbstractLogData interface, together with
// the original line number where they were found.
// Constructing such objet does not start the search.
// This object should be constructed by a LogData.
class LogFilteredData : public AbstractLogData {
  Q_OBJECT

  public:
    // Creates an empty LogFilteredData
    LogFilteredData();
    // Constructor used by LogData
    LogFilteredData( const LogData* logData );

    // Starts the async search, sending newDataAvailable() when new data found.
    // If a search is already in progress this function will block until
    // it is done, so the application should call interruptSearch() first.
    void runSearch( const QRegExp& regExp );
    // Add to the existing search, starting at the line when the search was
    // last stopped. Used when the file on disk has been added too.
    void updateSearch();
    // Interrupt the running search if one is in progress.
    // Nothing is done if no search is in progress.
    void interruptSearch();
    // Clear the search and the list of results.
    void clearSearch();
    // Returns the line number in the original LogData where the element
    // 'index' was found.
    qint64 getMatchingLineNumber( int index ) const;
    // Returns whether the line number passed is in our list of matching ones.
    bool isLineInMatchingList( qint64 lineNumber );

    // Returns the number of matches (independently of the visibility)
    int getNbMatches() const;
    // Returns the number of marks (independently of the visibility)
    int getNbMarks() const;

    // Returns the reason why the line at the passed index is in the filtered
    // data.  It can be because it is either a mark or a match.
    enum FilteredLineType { Match, Mark };
    FilteredLineType filteredLineTypeByIndex( int index ) const;

    // Marks interface (delegated to a Marks object)

    // Add a mark at the given line, optionally identified by the given char
    // If a mark for this char already exist, the previous one is replaced.
    void addMark( qint64 line, QChar mark = QChar() );
    // Get the (unique) mark identified by the passed char.
    qint64 getMark( QChar mark ) const;
    // Returns wheither the passed line has a mark on it.
    bool isLineMarked( qint64 line ) const;
    // Delete the mark identified by the passed char.
    void deleteMark( QChar mark );
    // Delete the mark present on the passed line or do nothing if there is
    // none.
    void deleteMark( qint64 line );
    // Completely clear the marks list.
    void clearMarks();

    // Changes what the AbstractLogData returns via its getXLines/getNbLines
    // API.
    enum Visibility { MatchesOnly, MarksOnly, MarksAndMatches };
    void setVisibility( Visibility visibility );

  signals:
    // Sent when the search has progressed, give the number of matches (so far)
    // and the percentage of completion
    void searchProgressed( int nbMatches, int progress );

  private slots:
    void handleSearchProgressed( int NbMatches, int progress );

  private:
    class FilteredItem;

    // Implementation of virtual functions
    QString doGetLineString( qint64 line ) const;
    QString doGetExpandedLineString( qint64 line ) const;
    QStringList doGetLines( qint64 first, int number ) const;
    QStringList doGetExpandedLines( qint64 first, int number ) const;
    qint64 doGetNbLine() const;
    int doGetMaxLength() const;
    int doGetLineLength( qint64 line ) const;

    QList<MatchingLine> matchingLineList;

    const LogData* sourceLogData_;
    QRegExp currentRegExp_;
    bool searchDone_;
    int maxLength_;
    int maxLengthMarks_;
    // Number of lines of the LogData that has been searched for:
    qint64 nbLinesProcessed_;

    Visibility visibility_;

    // Cache used to combine Marks and Matches
    // when visibility_ == MarksAndMatches
    // (QVector store actual objects instead of pointers)
    mutable QVector<FilteredItem> filteredItemsCache_;
    mutable bool filteredItemsCacheDirty_;

    LogFilteredDataWorkerThread* workerThread_;
    Marks* marks_;

    // Utility functions
    qint64 findLogDataLine( qint64 lineNum ) const;
    void regenerateFilteredItemsCache() const;
};

// A class representing a Mark or Match.
// Conceptually it should be a base class for Mark and MatchingLine,
// but we implement it this way for performance reason as we create plenty of
// those everytime we refresh the cache.
// Specifically it allows to store this in the cache by value instead
// of pointer (less small allocations and no RTTI).
class LogFilteredData::FilteredItem {
  public:
    // A default ctor seems to be necessary for QVector
    FilteredItem()
    { lineNumber_ = 0; }
    FilteredItem( qint64 lineNumber, FilteredLineType type )
    { lineNumber_ = lineNumber; type_ = type; }

    qint64 lineNumber() const
    { return lineNumber_; }
    FilteredLineType type() const
    { return type_; }

  private:
    qint64 lineNumber_;
    FilteredLineType type_;
};

#endif