summaryrefslogtreecommitdiffstats
path: root/kbabel/kbabeldict/searchengine.h
blob: db7223624a94500d47fa4316519b3f9098145b1b (plain)
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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
/* ****************************************************************************
  This file is part of KBabel

  Copyright (C) 2000 by Matthias Kiefer
                            <matthias.kiefer@gmx.de>

  This program 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 2 of the License, or
  (at your option) any later version.

  This program 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 this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

  In addition, as a special exception, the copyright holders give
  permission to link the code of this program with any edition of
  the Qt library by Trolltech AS, Norway (or with modified versions
  of Qt that use the same license as Qt), and distribute linked
  combinations including the two.  You must obey the GNU General
  Public License in all respects for all of the code used other than
  Qt. If you modify this file, you may extend this exception to
  your version of the file, but you are not obligated to do so.  If
  you do not wish to do so, delete this exception statement from
  your version.
	    
**************************************************************************** */

#ifndef SEARCH_ENGINE_H
#define SEARCH_ENGINE_H

#include <qdatetime.h>
#include <qptrlist.h>
#include <qobject.h>
#include <qstring.h>
#include <qwidget.h>
#include <kaboutdata.h>
#include <kconfigbase.h>

 
/*
 * This class gives information about the translator, etc.  
 * Information, that is not available in a specific implementation of
 * the SearchEngine, should be left empty.
 */
class KDE_EXPORT TranslationInfo
{
public:
    /** 
     * Information about the location, where this entry was found.
     * For example the PO-file it was found in, etc. 
     * */
    QString location; 

    /**
     * The complete path of the file, where this entry was found
     */
    QString filePath;


    /** The date of the last change */
    QDateTime lastChange;
    
    /** The language, the translation belongs to */
    QString languageCode;

    /**
     * The translator of this string
     * For example the translator found in the header of the PO-file.
     */
    QString translator;
    
    /**
     * The name of a project this translation is a part of.
     */
    QString projectName;
    
    /**
     * Keywords defined for @ref projectName. For example KDE_3_1_BRANCH (project branch)
     */
    QStringList projectKeywords;
    
    /**
     * Part/context in a project, for example "multimedia", "admin", etc.
     */
    QString projectContext;
    
    /**
     * Status of the translation, for example "approved", "spellchecked", "unknown"
     */
    QString status;

    /**
     * Additional information to be presented to the user, for example a comment
     */
    QString description;    
};


/** 
 * This class contains a result from the search
 * plus additional information where it was found,
 * the date and time of the last change, the translator, etc.
 */
class KDE_EXPORT SearchResult
{
public:
    SearchResult();
    SearchResult(const SearchResult&);
        
    /** The requested string to search for */
    QString requested;
    
    /** The string that, was found (a list if it is a plural form) */
    QStringList found;

    /** The number of a plural form to search for */
    uint requestedPluralForm;

    /** The translation of the found string */
    QString translation;

    /** The number of a plural form of the translated string found */
    uint translationPluralForm;

    /** 
     * This string contains the plain translation if you are
     * using rich text. If you don't use rich text, you can leave
     * it empty
     */
    QString plainTranslation;

    /** 
     * This string contains the plain string, that was found, if you are
     * using rich text. If you don't use rich text, you can leave
     * it empty
     */
    QString plainFound;
    
    /** 
     * This string contains the plain requested string if you are
     * using rich text. If you don't use rich text, you can leave
     * it empty
     */
    QString plainRequested;
    
    /**
     * Constains a score for the found translation. 0 means exact matching.
     * The higher the score is, the worse is the matching.
     * How to compute the score is not yet really clear :-(
     */
    int score;

    QPtrList<TranslationInfo> descriptions;
};

/**
 *
 */
class KDE_EXPORT SearchFilter 
{
public:
    SearchFilter() : 
	_projects()
	, _location( QString::null )
	, _languageCode( QString::null )
	, _origLanguageCode( QString::null )
	, _translators()
	, _projectKeywords()
	, _projectContexts()
	, _translationStatus()
    {}
    
    virtual ~SearchFilter() {}

    void setProjectName( const QString& project ) { _projects = project; }
    void setProjectName( const QStringList& projects ) { _projects = projects; }

    /** 
     * Information about the location, where this entry was found.
     * For example the PO-file it was found in, etc. 
     * */
    void setLocation( const QString& location) { _location = location; }
    QString location() const { return _location; }

    /** The original language, the translation was made from */
    void setOriginalLanguage( const QString& languageCode) { _origLanguageCode = languageCode; }

    /** The language, the translation belongs to */
    void setTranslationLanguage( const QString& languageCode) { _languageCode = languageCode; }

    /**
     * The translator of this string
     * For example the translator found in the header of the PO-file.
     */
    void setTranslator( const QString& translator) { _translators = translator ; }
    void setTranslator( const QStringList& translators) { _translators = translators ; }
    
    /**
     * Keywords defined for @ref projectName. For example KDE_3_1_BRANCH (project branch)
     */
    void setProjectKeywords( const QStringList& projectKeywords ) { _projectKeywords = projectKeywords; }
    
    /**
     * Part/context in a project, for example "multimedia", "admin", etc.
     */
    void setProjectContext( const QString& projectContext) { _projectContexts = projectContext; } 
    void setProjectContext( const QStringList& projectContexts) { _projectContexts = projectContexts; }
    
    /**
     * Status of the translation, for example "approved", "spellchecked", "unknown"
     */
    void setStatus( const QString& translationStatus) { _translationStatus = translationStatus; }
    void setStatus( const QStringList& translationStati) { _translationStatus = translationStati; }

    /**
     *  The key method of the class - check, if the argument
     *  matches this filter.
     */
    virtual bool match( const TranslationInfo& toCheck );

private:
    QStringList _projects;
    QString _location; 
    QString _languageCode;
    QString _origLanguageCode;
    QStringList _translators;
    QStringList _projectKeywords ;
    QStringList _projectContexts;
    QStringList _translationStatus;
};

/**
 * This class is the base class for the preferences widget used to
 * setup the search engines. Inherit from this and reimplement all
 * necessary function. The widget should not be bigger than 400x400.
 * If you need more space, you maybe want to use a tabbed widget.
 */
class KDE_EXPORT PrefWidget : public QWidget
{
    Q_OBJECT
            
public:
    PrefWidget(QWidget *parent, const char* name=0);
    virtual ~PrefWidget();

public slots:
    /**
     * apply changes of the settings
     */
    virtual void apply()=0;
    /**
     * revert made changes
     */
    virtual void cancel()=0;
    /**
     * set settings to the standard options
     */
    virtual void standard()=0;
};


class KDE_EXPORT SearchEngine : public QObject
{
    Q_OBJECT
            
public:
    SearchEngine(QObject *parent=0, const char *name=0);
    virtual ~SearchEngine();

    

    /** @return the search result number n */
    virtual SearchResult *result(int n);
    
    /** @return the number of search results */
    virtual int numberOfResults() const;

    /** @return true, if a search is currently active */
    virtual bool isSearching() const = 0;
    

    /** save the settings in the given config object */
    virtual void saveSettings(KConfigBase *config) = 0;
    virtual void readSettings(KConfigBase *config) = 0;

    /** @returns true, if it was initialized correctly */
    virtual bool isReady() const =0;


    /** 
     * @returns the exact translation of text or a empty string
     * if no exact match was found.
     */
    virtual QString translate(const QString& text, const uint pluralForm = 0)=0;
 
    /** 
     * @returns the translation of text according to the plugin settings or a empty string
     * if no match was found.
     */
    virtual QString searchTranslation(const QString&, int &score, const uint pluralForm = 0) {
        Q_UNUSED(pluralForm);

	score = 0; return QString::null;
    }

    /** 
     * @returns a fuzzy translation of text or a empty string
     * if no good match was found.
     */
    virtual QString fuzzyTranslation(const QString& /*text*/, int &score, const uint pluralForm = 0) { 
        Q_UNUSED(pluralForm);

      score = 0; return QString::null; };
   

    /**
     * Finds all messages belonging to package package. If nothing is found,
     * the list is empty.
     * @param package The name of the file, something like "kbabel.po"
     * @param resultList Will contain the found messages afterwards
     * @param error If an error occured, this should contain a description
     * 
     * @return true, if successfull
     */
    virtual bool messagesForFilter(const SearchFilter* filter
                         , QValueList<SearchResult>& resultList, QString& error) 
    {
        Q_UNUSED(filter);
        Q_UNUSED(resultList);

	error = i18n("not implemented");
	return false;
    }
    
    /** 
     * @returns true, if the searchresults are given as rich text
     * the default implementation returns false
     */ 
    virtual bool usesRichTextResults();

    /** @returns true, if the the entries in the database can be edited */
    virtual bool isEditable();
    
    /** 
     * @returns a widget which lets the user setup all preferences of this
     * search engine. The returned widget should not be bigger than
     * 400x400. If you need more space, you maybe want to use
     * a tabbed widget.
     * @param parent the parent of the returned widget
     */
    virtual PrefWidget* preferencesWidget(QWidget *parent)=0;

    /** @returns information about this SearchEngine */
    virtual const KAboutData *about() const= 0;

    /** @returns the i18n name of this search engine */
    virtual QString name() const= 0;

    /** @returns a untranslated name of this engine */
    virtual QString id() const= 0;

    /** @returns the last error message */
    virtual QString lastError() = 0;
            

    /**
     * sets the engine to always ask the preferences dialog for settings
     * if is existing before starting the search.
     */
    virtual void setAutoUpdateOptions(bool activate);


    /**
     *  @returns how good @param text1 matches @param text2
     *  comparing 3-grams .. n-grams, the returned value is
     *  a number between 0 and 100. @param ngram_len should be
     *  a value between 3 and 5. 
     */
    static uint ngramMatch (const QString& text1, const QString& text2, 
			    uint ngram_len=3);

public slots:
    /**
     * starts a search for string s in the original text
     * @returns false, if an error occured. Use @ref lastError
     * to get the last error message
     */
    virtual bool startSearch(const QString& s, uint pluralForm = 0, const SearchFilter* filter = 0) = 0;

    /**
     * starts a search for string s in the translated text
     * @returns false, if an error occured. Use @ref lastError
     * to get the last error message
     */
    virtual bool startSearchInTranslation(const QString& s, uint pluralForm = 0, const SearchFilter* filter = 0);


    /** stops a search */
    virtual void stopSearch() = 0;

    /** @return the next search result */
    virtual SearchResult *nextResult();
    
    /** @return the previous search result */
    virtual SearchResult *prevResult();

    /** @return the first search result */
    virtual SearchResult *firstResult();

    /** @return the last search result */
    virtual SearchResult *lastResult();
    
    /** clears the result list */
    virtual void clearResults();
    

    /**
     * This method allows a search engine to use different settings depending
     * on the edited file. The default implementation does nothing.
     * @param file The edited file with path
     */
    virtual void setEditedFile(const QString& file);

    /**
     * This method allows a search engine to use different settings depending
     * on the edited package. The default implementation does nothing.
     * @param package The name of the package, that is currently translated.
     */
    virtual void setEditedPackage(const QString& package);

    /**
     * This method allows a search engine to use different settings depending
     * on the language code. The default implementation does nothing.
     * @param lang The current language code (e.g. de).
     */
    virtual void setLanguageCode(const QString& lang);
    virtual void setLanguage(const QString& languageCode, const QString& languageName);



    /**
     * This method is called, if something has been changed in the
     * current file. See @ref setEditedFile if you want to know the file
     * name
     * @param orig the original string (list of all plural forms)
     * @param translation the translated string  
     * @param pluralForm the number of the plural form of the translation
     * @param description the additional description, e.g., a PO comment
     */
     virtual void stringChanged( const QStringList& orig, const QString& translated
            , const uint translationPluralForm, const QString& description);
    
    /**
     * If the database is editable this slot should open an dialog to let
     * the user edit the contents of the database.
     */
    virtual void edit();

    /************ convenience functions for distring normalization, etc.**********/

    /** 
     * @returns the n-th directory name of path. Counting is started at
     * end of path. Example: directory("/usr/local/src/foobar, 0")
     * returns "foobar", while n=1 would return "src"
     * FIXME: isn't it a code duplication?
     */
    static QString directory(const QString& path, int n);

    /**
     * computes a score to assess the match of the two strings:
     * 0 means exact match, bigger means worse
     */
    static uint score(const QString& orig, const QString& found);
     
signals:
    /** signals, that a new search started */
    void started();
    
    /** 
     * signals progress in searching 
     * @param p should be between 0 and 100
     * */
    void progress(int p);
    
    /**
     * Use this, if you want to set your own message on the
     * progressbar or if you do something else then searching,
     * maybe loading a big file
     */
    void progressStarts(const QString&);

    void progressEnds();
    
    /** 
     * signals, that the number of search results has changed 
     * @param n the new number of results
     * */
    void numberOfResultsChanged(int n);

    /**
     * signals, that the order of the results in the list has changed.
     * For example because a better matching string has been prepended.
     */
    void resultsReordered();

    /**
     * signals, that a new result was found
     */
    void resultFound(const SearchResult*);

    /** 
     * signals, that search has finished
     */
    void finished();
    
    /**
     * signals, that an error occured, for example, that you wasn't
     * able to open a database.      
     */ 
     void hasError(const QString& error);

protected:
    QPtrList<SearchResult> results;
    bool autoUpdate;
};


#endif // SEARCH_ENGINE_H