~ubuntu-branches/ubuntu/trusty/kvirc/trusty-proposed

« back to all changes in this revision

Viewing changes to src/modules/help/HelpIndex.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Kai Wasserbäch, Kai Wasserbäch, Raúl Sánchez Siles
  • Date: 2011-02-12 10:40:21 UTC
  • mfrom: (14.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20110212104021-5mh4f75jlku20mnt
The combined "Twisted Experiment" and "Nocturnal Raid" release.

[ Kai Wasserbäch ]
* Synced to upstream's SVN revision 5467.
* debian/rules:
  - Added .PHONY line.
  - Resurrect -DMANUAL_REVISION, got lost somewhere and we build SVN
    revisions again.
  - Replace "-DWITH_NO_EMBEDDED_CODE=YES" with "-DWANT_CRYPTOPP=YES".
  - Change the remaining -DWITH/-DWITHOUT to the new -DWANT syntax.
* debian/control:
  - Removed DMUA, I'm a DD now.
  - Changed my e-mail address.
  - Removed unneeded relationships (no upgrades over two releases are
    supported).
  - Fix Suggests for kvirc-dbg.
  - kvirc-data: Make the "Suggests: kvirc" a Recommends, doesn't make much
    sense to install the -data package without the program.
* debian/source/local-options: Added with "unapply-patches".
* debian/kvirc.lintian-overrides: Updated to work for 4.1.1.
* debian/patches/21_make_shared-mime-info_B-D_superfluous.patch: Updated.
* debian/kvirc-data.install: Added .notifyrc.

[ Raúl Sánchez Siles ]
* Stating the right version where kvirc-data break and replace should happen.
* Fixing link to license file.
* Added French and Portuguese man pages.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
 
4
** Contact: Qt Software Information (qt-info@nokia.com)
 
5
**
 
6
** This file is part of the Qt Assistant of the Qt Toolkit.
 
7
**
 
8
** Commercial Usage
 
9
** Licensees holding valid Qt Commercial licenses may use this file in
 
10
** accordance with the Qt Commercial License Agreement provided with the
 
11
** Software or, alternatively, in accordance with the terms contained in
 
12
** a written agreement between you and Nokia.
 
13
**
 
14
**
 
15
** GNU General Public License Usage
 
16
** Alternatively, this file may be used under the terms of the GNU
 
17
** General Public License versions 2.0 or 3.0 as published by the Free
 
18
** Software Foundation and appearing in the file LICENSE.GPL included in
 
19
** the packaging of this file.  Please review the following information
 
20
** to ensure GNU General Public Licensing requirements will be met:
 
21
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
 
22
** http://www.gnu.org/copyleft/gpl.html.  In addition, as a special
 
23
** exception, Nokia gives you certain additional rights. These rights
 
24
** are described in the Nokia Qt GPL Exception version 1.3, included in
 
25
** the file GPL_EXCEPTION.txt in this package.
 
26
**
 
27
** Qt for Windows(R) Licensees
 
28
** As a special exception, Nokia, as the sole copyright holder for Qt
 
29
** Designer, grants users of the Qt/Eclipse Integration plug-in the
 
30
** right for the Qt/Eclipse Integration to link to functionality
 
31
** provided by Qt Designer and its related libraries.
 
32
**
 
33
** If you are unsure which license is appropriate for your use, please
 
34
** contact the sales department at qt-sales@nokia.com.
 
35
**
 
36
****************************************************************************/
 
37
 
 
38
#include "HelpIndex.h"
 
39
 
 
40
#include <QFile>
 
41
#include <QDir>
 
42
#include <QStringList>
 
43
#include <QApplication>
 
44
#include <QByteArray>
 
45
#include <QTextStream>
 
46
#include <QtAlgorithms>
 
47
#include <QUrl>
 
48
#include <QTextCodec>
 
49
#include <ctype.h>
 
50
#include <QTextDocument>
 
51
#include <QTimer>
 
52
 
 
53
QT_BEGIN_NAMESPACE
 
54
 
 
55
struct Term {
 
56
    Term() : frequency(-1) {}
 
57
    Term( const QString &t, int f, QVector<Document> l ) : term( t ), frequency( f ), documents( l ) {}
 
58
    QString term;
 
59
    int frequency;
 
60
    QVector<Document>documents;
 
61
    bool operator<( const Term &i2 ) const { return frequency < i2.frequency; }
 
62
};
 
63
 
 
64
QDataStream &operator>>( QDataStream &s, Document &l )
 
65
{
 
66
    s >> l.docNumber;
 
67
    s >> l.frequency;
 
68
    return s;
 
69
}
 
70
 
 
71
QDataStream &operator<<( QDataStream &s, const Document &l )
 
72
{
 
73
    s << (qint16)l.docNumber;
 
74
    s << (qint16)l.frequency;
 
75
    return s;
 
76
}
 
77
 
 
78
HelpIndex::HelpIndex( const QString &dp, const QString &hp )
 
79
    : QObject( 0 ), docPath( dp )
 
80
{
 
81
    Q_UNUSED(hp);
 
82
 
 
83
    alreadyHaveDocList = false;
 
84
    lastWindowClosed = false;
 
85
    connect( qApp, SIGNAL(lastWindowClosed()),
 
86
             this, SLOT(setLastWinClosed()) );
 
87
 
 
88
        m_pTimer = new QTimer(this);
 
89
        m_pTimer->setSingleShot(true);
 
90
        m_pTimer->setInterval(0);
 
91
        connect(m_pTimer, SIGNAL(timeout()), this, SLOT(filterNext()));
 
92
}
 
93
 
 
94
HelpIndex::HelpIndex( const QStringList &dl, const QString &hp )
 
95
    : QObject( 0 )
 
96
{
 
97
    Q_UNUSED(hp);
 
98
    docList = dl;
 
99
    alreadyHaveDocList = true;
 
100
    lastWindowClosed = false;
 
101
    connect( qApp, SIGNAL(lastWindowClosed()),
 
102
             this, SLOT(setLastWinClosed()) );
 
103
}
 
104
 
 
105
void HelpIndex::setLastWinClosed()
 
106
{
 
107
    lastWindowClosed = true;
 
108
}
 
109
 
 
110
void HelpIndex::setDictionaryFile( const QString &f )
 
111
{
 
112
    dictFile = f;
 
113
}
 
114
 
 
115
void HelpIndex::setDocListFile( const QString &f )
 
116
{
 
117
    docListFile = f;
 
118
}
 
119
 
 
120
void HelpIndex::setDocList( const QStringList &lst )
 
121
{
 
122
    docList = lst;
 
123
}
 
124
 
 
125
void HelpIndex::makeIndex()
 
126
{
 
127
        if ( !alreadyHaveDocList )
 
128
                setupDocumentList();
 
129
 
 
130
        lastWindowClosed = false;
 
131
        emit indexingStart( docList.count() );
 
132
        dict.clear();
 
133
        m_iCurItem = 0;
 
134
        m_pTimer->start(); //singleshot
 
135
}
 
136
 
 
137
void HelpIndex::filterNext()
 
138
{
 
139
        if(m_iCurItem < docList.count() && !lastWindowClosed)
 
140
        {
 
141
                QUrl url(docList.at(m_iCurItem));
 
142
                parseDocument( url.toLocalFile(), m_iCurItem );
 
143
                emit indexingProgress( m_iCurItem );
 
144
                m_iCurItem++;
 
145
                m_pTimer->start(); //singleshot
 
146
        } else {
 
147
                emit indexingEnd();
 
148
        }
 
149
}
 
150
 
 
151
void HelpIndex::setupDocumentList()
 
152
{
 
153
    docList.clear();
 
154
    titleList.clear();
 
155
    QDir d( docPath );
 
156
    QStringList filters;
 
157
    filters.append(QLatin1String("*.html"));
 
158
    QStringList lst = d.entryList(filters);
 
159
    QStringList::ConstIterator it = lst.constBegin();
 
160
    for ( ; it != lst.constEnd(); ++it )
 
161
    {
 
162
        QString filename=QLatin1String("file:") + docPath + QLatin1String("/") + *it ;
 
163
        docList.append(filename);
 
164
        titleList.append(getDocumentTitle(filename));
 
165
    }
 
166
}
 
167
 
 
168
void HelpIndex::insertInDict( const QString &str, int docNum )
 
169
{
 
170
    if ( str == QLatin1String("amp") || str == QLatin1String("nbsp"))
 
171
        return;
 
172
    Entry *e = 0;
 
173
    if ( dict.count() )
 
174
        e = dict[ str ];
 
175
 
 
176
    if ( e ) {
 
177
        if ( e->documents.last().docNumber != docNum )
 
178
            e->documents.append( Document(docNum, 1 ) );
 
179
        else
 
180
            e->documents.last().frequency++;
 
181
    } else {
 
182
        dict.insert( str, new Entry( docNum ) );
 
183
    }
 
184
}
 
185
 
 
186
QString HelpIndex::getCharsetForDocument(QFile *file)
 
187
{
 
188
    QTextStream s(file);
 
189
    QString contents = s.readAll();
 
190
 
 
191
    QString encoding;
 
192
    int start = contents.indexOf(QLatin1String("<meta"), 0, Qt::CaseInsensitive);
 
193
    if (start > 0) {
 
194
        int end = contents.indexOf(QLatin1String(">"), start);
 
195
        QString meta = contents.mid(start+5, end-start);
 
196
        meta = meta.toLower();
 
197
        QRegExp r(QLatin1String("charset=([^\"\\s]+)"));
 
198
        if (r.indexIn(meta) != -1) {
 
199
            encoding = r.cap(1);        
 
200
        }
 
201
    }
 
202
 
 
203
    file->seek(0);
 
204
    if (encoding.isEmpty())
 
205
        return QLatin1String("utf-8");
 
206
    return encoding;
 
207
}
 
208
 
 
209
void HelpIndex::parseDocument( const QString &filename, int docNum )
 
210
{
 
211
    QFile file( filename );
 
212
    if ( !file.open(QFile::ReadOnly) ) {
 
213
        qWarning( "can not open file %s", qPrintable(filename) );
 
214
        return;
 
215
    }
 
216
 
 
217
    QTextStream s(&file);
 
218
    QString en = getCharsetForDocument(&file);
 
219
    s.setCodec(QTextCodec::codecForName(en.toLatin1().constData()));
 
220
 
 
221
    QString text = s.readAll();
 
222
    if (text.isNull())
 
223
        return;
 
224
 
 
225
    bool valid = true;
 
226
    const QChar *buf = text.unicode();
 
227
    QChar str[64];
 
228
    QChar c = buf[0];
 
229
    int j = 0;
 
230
    int i = 0;
 
231
    while ( j < text.length() ) {
 
232
        if ( c == QLatin1Char('<') || c == QLatin1Char('&') ) {
 
233
            valid = false;
 
234
            if ( i > 1 )
 
235
                insertInDict( QString(str,i), docNum );
 
236
            i = 0;
 
237
            c = buf[++j];
 
238
            continue;
 
239
        }
 
240
        if ( ( c == QLatin1Char('>') || c == QLatin1Char(';') ) && !valid ) {
 
241
            valid = true;
 
242
            c = buf[++j];
 
243
            continue;
 
244
        }
 
245
        if ( !valid ) {
 
246
            c = buf[++j];
 
247
            continue;
 
248
        }
 
249
        if ( ( c.isLetterOrNumber() || c == QLatin1Char('_') ) && i < 63 ) {
 
250
            str[i] = c.toLower();
 
251
            ++i;
 
252
        } else {
 
253
            if ( i > 1 )
 
254
                insertInDict( QString(str,i), docNum );
 
255
            i = 0;
 
256
        }
 
257
        c = buf[++j];
 
258
    }
 
259
    if ( i > 1 )
 
260
        insertInDict( QString(str,i), docNum );
 
261
    file.close();
 
262
}
 
263
 
 
264
void HelpIndex::writeDict()
 
265
{
 
266
    QFile f( dictFile );
 
267
    if ( !f.open(QFile::WriteOnly ) )
 
268
        return;
 
269
    QDataStream s( &f );
 
270
    for(QHash<QString, Entry *>::Iterator it = dict.begin(); it != dict.end(); ++it) {
 
271
        s << it.key();
 
272
        s << it.value()->documents.count();
 
273
        s << it.value()->documents;
 
274
    }
 
275
    f.close();
 
276
    writeDocumentList();
 
277
}
 
278
 
 
279
void HelpIndex::writeDocumentList()
 
280
{
 
281
    QFile f( docListFile );
 
282
    if ( !f.open(QFile::WriteOnly ) )
 
283
        return;
 
284
    QDataStream s( &f );
 
285
    s << docList;
 
286
    
 
287
    QFile f1( docListFile+".titles" );
 
288
    if ( !f1.open(QFile::WriteOnly ) )
 
289
        return;
 
290
    QDataStream s1( &f1 );
 
291
    s1 << titleList;
 
292
    
 
293
}
 
294
 
 
295
void HelpIndex::readDict()
 
296
{
 
297
    QFile f( dictFile );
 
298
    if ( !f.open(QFile::ReadOnly ) )
 
299
        return;
 
300
 
 
301
    dict.clear();
 
302
    QDataStream s( &f );
 
303
    QString key;
 
304
    int numOfDocs;
 
305
    QVector<Document> docs;
 
306
    while ( !s.atEnd() ) {
 
307
        s >> key;
 
308
        s >> numOfDocs;
 
309
        docs.resize(numOfDocs);
 
310
        s >> docs;
 
311
        dict.insert( key, new Entry( docs ) );
 
312
    }
 
313
    f.close();
 
314
    readDocumentList();
 
315
}
 
316
 
 
317
void HelpIndex::readDocumentList()
 
318
{
 
319
    QFile f( docListFile );
 
320
    if ( !f.open(QFile::ReadOnly ) )
 
321
        return;
 
322
    QDataStream s( &f );
 
323
    s >> docList;
 
324
    QFile f1( docListFile+".titles" );
 
325
    if ( !f1.open(QFile::ReadOnly ) )
 
326
        return;
 
327
    QDataStream s1( &f1 );
 
328
    s1 >> titleList;
 
329
}
 
330
 
 
331
QStringList HelpIndex::query( const QStringList &terms, const QStringList &termSeq, const QStringList &seqWords )
 
332
{
 
333
    QList<Term> termList;
 
334
    for (QStringList::ConstIterator it = terms.begin(); it != terms.end(); ++it ) {
 
335
        Entry *e = 0;
 
336
        if ( (*it).contains(QLatin1Char('*')) ) {
 
337
            QVector<Document> wcts = setupDummyTerm( getWildcardTerms( *it ) );
 
338
            termList.append( Term(QLatin1String("dummy"), wcts.count(), wcts ) );
 
339
        } else if ( dict[ *it ] ) {
 
340
            e = dict[ *it ];
 
341
            termList.append( Term( *it, e->documents.count(), e->documents ) );
 
342
        } else {
 
343
            return QStringList();
 
344
        }
 
345
    }
 
346
    if ( !termList.count() )
 
347
        return QStringList();
 
348
    qSort(termList);
 
349
 
 
350
    QVector<Document> minDocs = termList.takeFirst().documents;
 
351
    for(QList<Term>::Iterator it = termList.begin(); it != termList.end(); ++it) {
 
352
        Term *t = &(*it);
 
353
        QVector<Document> docs = t->documents;
 
354
        for(QVector<Document>::Iterator minDoc_it = minDocs.begin(); minDoc_it != minDocs.end(); ) {
 
355
            bool found = false;
 
356
            for (QVector<Document>::ConstIterator doc_it = docs.constBegin(); doc_it != docs.constEnd(); ++doc_it ) {
 
357
                if ( (*minDoc_it).docNumber == (*doc_it).docNumber ) {
 
358
                    (*minDoc_it).frequency += (*doc_it).frequency;
 
359
                    found = true;
 
360
                    break;
 
361
                }
 
362
            }
 
363
            if ( !found )
 
364
                minDoc_it = minDocs.erase( minDoc_it );
 
365
            else
 
366
                ++minDoc_it;
 
367
        }
 
368
    }
 
369
 
 
370
    QStringList results;
 
371
    qSort( minDocs );
 
372
    if ( termSeq.isEmpty() ) {
 
373
        for(QVector<Document>::Iterator it = minDocs.begin(); it != minDocs.end(); ++it)
 
374
            results << docList.at((int)(*it).docNumber);
 
375
        return results;
 
376
    }
 
377
 
 
378
    QString fileName;
 
379
    for(QVector<Document>::Iterator it = minDocs.begin(); it != minDocs.end(); ++it) {
 
380
        fileName =  docList[ (int)(*it).docNumber ];
 
381
        if ( searchForPattern( termSeq, seqWords, fileName ) )
 
382
            results << fileName;
 
383
    }
 
384
    return results;
 
385
}
 
386
 
 
387
QString HelpIndex::getDocumentTitle( const QString &fullFileName )
 
388
{
 
389
    QUrl url(fullFileName);
 
390
    QString fileName = url.toLocalFile();
 
391
 
 
392
    if (documentTitleCache.contains(fileName))
 
393
        return documentTitleCache.value(fileName);
 
394
 
 
395
    QFile file( fileName );
 
396
    if ( !file.open( QFile::ReadOnly ) ) {
 
397
        qWarning( "cannot open file %s", qPrintable(fileName) );
 
398
        return fileName;
 
399
    }
 
400
    QTextStream s( &file );
 
401
    QString text = s.readAll();
 
402
 
 
403
    int start = text.indexOf(QLatin1String("<title>"), 0, Qt::CaseInsensitive) + 7;
 
404
    int end = text.indexOf(QLatin1String("</title>"), 0, Qt::CaseInsensitive);
 
405
 
 
406
    QString title = tr("Untitled");
 
407
    if (end - start > 0) {
 
408
        title = text.mid(start, end - start);
 
409
        if (Qt::mightBeRichText(title)) {
 
410
            QTextDocument doc;
 
411
            doc.setHtml(title);
 
412
            title = doc.toPlainText();
 
413
        }
 
414
    }
 
415
    documentTitleCache.insert(fileName, title);
 
416
    return title;
 
417
}
 
418
 
 
419
QStringList HelpIndex::getWildcardTerms( const QString &term )
 
420
{
 
421
    QStringList lst;
 
422
    QStringList terms = split( term );
 
423
    QStringList::Iterator iter;
 
424
 
 
425
    for(QHash<QString, Entry*>::Iterator it = dict.begin(); it != dict.end(); ++it) {
 
426
        int index = 0;
 
427
        bool found = false;
 
428
        QString text( it.key() );
 
429
        for ( iter = terms.begin(); iter != terms.end(); ++iter ) {
 
430
            if ( *iter == QLatin1String("*") ) {
 
431
                found = true;
 
432
                continue;
 
433
            }
 
434
            if ( iter == terms.begin() && (*iter)[0] != text[0] ) {
 
435
                found = false;
 
436
                break;
 
437
            }
 
438
            index = text.indexOf( *iter, index );
 
439
            if ( *iter == terms.last() && index != (int)text.length()-1 ) {
 
440
                index = text.lastIndexOf( *iter );
 
441
                if ( index != (int)text.length() - (int)(*iter).length() ) {
 
442
                    found = false;
 
443
                    break;
 
444
                }
 
445
            }
 
446
            if ( index != -1 ) {
 
447
                found = true;
 
448
                index += (*iter).length();
 
449
                continue;
 
450
            } else {
 
451
                found = false;
 
452
                break;
 
453
            }
 
454
        }
 
455
        if ( found )
 
456
            lst << text;
 
457
    }
 
458
 
 
459
    return lst;
 
460
}
 
461
 
 
462
QStringList HelpIndex::split( const QString &str )
 
463
{
 
464
    QStringList lst;
 
465
    int j = 0;
 
466
    int i = str.indexOf(QLatin1Char('*'), j );
 
467
 
 
468
    if (str.startsWith(QLatin1String("*")))
 
469
        lst << QLatin1String("*");
 
470
 
 
471
    while ( i != -1 ) {
 
472
        if ( i > j && i <= (int)str.length() ) {
 
473
            lst << str.mid( j, i - j );
 
474
            lst << QLatin1String("*");
 
475
        }
 
476
        j = i + 1;
 
477
        i = str.indexOf(QLatin1Char('*'), j );
 
478
    }
 
479
 
 
480
    int l = str.length() - 1;
 
481
    if ( str.mid( j, l - j + 1 ).length() > 0 )
 
482
        lst << str.mid( j, l - j + 1 );
 
483
 
 
484
    return lst;
 
485
}
 
486
 
 
487
QVector<Document> HelpIndex::setupDummyTerm( const QStringList &terms )
 
488
{
 
489
    QList<Term> termList;
 
490
    for (QStringList::ConstIterator it = terms.begin(); it != terms.end(); ++it) {
 
491
        Entry *e = 0;
 
492
        if ( dict[ *it ] ) {
 
493
            e = dict[ *it ];
 
494
            termList.append( Term( *it, e->documents.count(), e->documents ) );
 
495
        }
 
496
    }
 
497
    QVector<Document> maxList(0);
 
498
    if ( !termList.count() )
 
499
        return maxList;
 
500
    qSort(termList);
 
501
 
 
502
    maxList = termList.takeLast().documents;
 
503
    for(QList<Term>::Iterator it = termList.begin(); it != termList.end(); ++it) {
 
504
        Term *t = &(*it);
 
505
        QVector<Document> docs = t->documents;
 
506
        for (QVector<Document>::iterator docIt = docs.begin(); docIt != docs.end(); ++docIt ) {
 
507
            if ( maxList.indexOf( *docIt ) == -1 )
 
508
                maxList.append( *docIt );
 
509
        }
 
510
    }
 
511
    return maxList;
 
512
}
 
513
 
 
514
void HelpIndex::buildMiniDict( const QString &str )
 
515
{
 
516
    if ( miniDict[ str ] )
 
517
        miniDict[ str ]->positions.append( wordNum );
 
518
    ++wordNum;
 
519
}
 
520
 
 
521
bool HelpIndex::searchForPattern( const QStringList &patterns, const QStringList &words, const QString &fileName )
 
522
{
 
523
    QUrl url(fileName);
 
524
    QString fName = url.toLocalFile();
 
525
    QFile file( fName );
 
526
    if ( !file.open( QFile::ReadOnly ) ) {
 
527
        qWarning( "cannot open file %s", qPrintable(fName) );
 
528
        return false;
 
529
    }
 
530
 
 
531
    wordNum = 3;
 
532
    miniDict.clear();
 
533
    QStringList::ConstIterator cIt = words.begin();
 
534
    for ( ; cIt != words.end(); ++cIt )
 
535
        miniDict.insert( *cIt, new PosEntry( 0 ) );
 
536
 
 
537
    QTextStream s( &file );
 
538
    QString text = s.readAll();
 
539
    bool valid = true;
 
540
    const QChar *buf = text.unicode();
 
541
    QChar str[64];
 
542
    QChar c = buf[0];
 
543
    int j = 0;
 
544
    int i = 0;
 
545
    while ( j < text.length() ) {
 
546
        if ( c == QLatin1Char('<') || c == QLatin1Char('&') ) {
 
547
            valid = false;
 
548
            if ( i > 1 )
 
549
                buildMiniDict( QString(str,i) );
 
550
            i = 0;
 
551
            c = buf[++j];
 
552
            continue;
 
553
        }
 
554
        if ( ( c == QLatin1Char('>') || c == QLatin1Char(';') ) && !valid ) {
 
555
            valid = true;
 
556
            c = buf[++j];
 
557
            continue;
 
558
        }
 
559
        if ( !valid ) {
 
560
            c = buf[++j];
 
561
            continue;
 
562
        }
 
563
        if ( ( c.isLetterOrNumber() || c == QLatin1Char('_') ) && i < 63 ) {
 
564
            str[i] = c.toLower();
 
565
            ++i;
 
566
        } else {
 
567
            if ( i > 1 )
 
568
                buildMiniDict( QString(str,i) );
 
569
            i = 0;
 
570
        }
 
571
        c = buf[++j];
 
572
    }
 
573
    if ( i > 1 )
 
574
        buildMiniDict( QString(str,i) );
 
575
    file.close();
 
576
 
 
577
    QStringList::ConstIterator patIt = patterns.begin();
 
578
    QStringList wordLst;
 
579
    QList<uint> a, b;
 
580
    QList<uint>::iterator aIt;
 
581
    for ( ; patIt != patterns.end(); ++patIt ) {
 
582
        wordLst = (*patIt).split(QLatin1Char(' '));
 
583
        a = miniDict[ wordLst[0] ]->positions;
 
584
        for ( int j = 1; j < (int)wordLst.count(); ++j ) {
 
585
            b = miniDict[ wordLst[j] ]->positions;
 
586
            aIt = a.begin();
 
587
            while ( aIt != a.end() ) {
 
588
                if ( b.contains( *aIt + 1 )) {
 
589
                    (*aIt)++;
 
590
                    ++aIt;
 
591
                } else {
 
592
                    aIt = a.erase( aIt );
 
593
                }
 
594
            }
 
595
        }
 
596
    }
 
597
    if ( a.count() )
 
598
        return true;
 
599
    return false;
 
600
}
 
601
 
 
602
QT_END_NAMESPACE