• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

kiten/lib

  • sources
  • kde-4.14
  • kdeedu
  • kiten
  • lib
  • DictEdict
dictfileedict.cpp
Go to the documentation of this file.
1 /*****************************************************************************
2  * This file is part of Kiten, a KDE Japanese Reference Tool *
3  * Copyright (C) 2001 Jason Katz-Brown <jason@katzbrown.com> *
4  * Copyright (C) 2006 Joseph Kerian <jkerian@gmail.com> *
5  * Copyright (C) 2006 Eric Kjeldergaard <kjelderg@gmail.com> *
6  * Copyright (C) 2011 Daniel E. Moctezuma <democtezuma@gmail.com> *
7  * *
8  * This library is free software; you can redistribute it and/or *
9  * modify it under the terms of the GNU Library General Public *
10  * License as published by the Free Software Foundation; either *
11  * version 2 of the License, or (at your option) any later version. *
12  * *
13  * This library is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16  * Library General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU Library General Public License *
19  * along with this library; see the file COPYING.LIB. If not, write to *
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
21  * Boston, MA 02110-1301, USA. *
22  *****************************************************************************/
23 
24 #include "dictfileedict.h"
25 
26 #include <KApplication>
27 #include <KConfig>
28 #include <KConfigSkeleton>
29 #include <KDebug>
30 #include <KGlobal>
31 #include <KProcess>
32 #include <KStandardDirs>
33 
34 #include <QByteArray>
35 #include <QFile>
36 #include <QString>
37 #include <QTextCodec>
38 #include <QTextStream>
39 #include <QVector>
40 
41 #include "deinflection.h"
42 #include "dictfilefieldselector.h"
43 #include "dictquery.h"
44 #include "entryedict.h"
45 #include "entrylist.h"
46 #include "kitenmacros.h"
47 
48 QString *DictFileEdict::deinflectionLabel = NULL;
49 QStringList *DictFileEdict::displayFields = NULL;
50 QString *DictFileEdict::wordType = NULL;
51 
56 DictFileEdict::DictFileEdict()
57 : DictFile( EDICT )
58 , m_deinflection( 0 )
59 , m_hasDeinflection( false )
60 {
61  m_dictionaryType = EDICT;
62  m_searchableAttributes.insert( "common", "common" );
63 }
64 
69 DictFileEdict::~DictFileEdict()
70 {
71  delete m_deinflection;
72  m_deinflection = 0;
73 }
74 
75 QMap<QString,QString> DictFileEdict::displayOptions() const
76 {
77  QMap<QString,QString> list;
78  list[ "Part of speech(type)" ] = "type";
79  return list;
80 }
81 
88 EntryList *DictFileEdict::doSearch( const DictQuery &query )
89 {
90  if( query.isEmpty() || ! m_edictFile.valid() ) //No query or dict, no results.
91  {
92  return new EntryList();
93  }
94 
95  kDebug()<< "Search from : " << getName();
96 
97  QString firstChoice = query.getWord();
98  if( firstChoice.length() == 0 )
99  {
100  firstChoice = query.getPronunciation();
101  if( firstChoice.length() == 0 )
102  {
103  firstChoice = query.getMeaning().split( ' ' ).first().toLower();
104  if( firstChoice.length() == 0 )
105  {
106  //The nastiest situation... we have to assemble a search string
107  //from the first property
108  QList<QString> keys = query.listPropertyKeys();
109  if( keys.size() == 0 ) //Shouldn't happen... but maybe in the future
110  {
111  return new EntryList();
112  }
113  firstChoice = keys[ 0 ];
114  firstChoice = firstChoice + query.getProperty( firstChoice );
115  //TODO: doSearch: some accomodation for searching for ranges and such of properties
116  }
117  }
118  }
119  else
120  {
121  // Only search for one kanji or the
122  // binary lookup mechanism breaks
123  firstChoice = firstChoice.at( 0 );
124  }
125 
126  QVector<QString> preliminaryResults = m_edictFile.findMatches( firstChoice );
127 
128  if( preliminaryResults.size() == 0 ) //If there were no matches... return an empty list
129  {
130  return new EntryList();
131  }
132 
133  EntryList *results = new EntryList();
134  foreach( const QString &it, preliminaryResults )
135  {
136 // kDebug() << "result: " << it << endl;
137  Entry *result = makeEntry( it );
138  EntryEdict *resultEdict = static_cast<EntryEdict*>( result );
139  if( result->matchesQuery( query ) && resultEdict->matchesWordType( query ) )
140  {
141  results->append( result );
142  }
143  else
144  {
145  delete result;
146  }
147  }
148 
149  // At this point we should have some preliminary results
150  // and if there were no matches, it probably means the user
151  // input was a verb or adjective, so we have to deinflect it.
152  bool isAnyQuery = query.getMatchWordType() == DictQuery::Any;
153  bool isVerbQuery = query.getMatchWordType() == DictQuery::Verb;
154  bool isAdjectiveQuery = query.getMatchWordType() == DictQuery::Adjective;
155  if( results->count() == 0 && ( isAnyQuery || isVerbQuery || isAdjectiveQuery ) )
156  {
157  delete results;
158  results = m_deinflection->search( query, preliminaryResults );
159  QString *label = m_deinflection->getDeinflectionLabel();
160  if( ! label->isEmpty() && ! m_hasDeinflection )
161  {
162  deinflectionLabel = label;
163  m_hasDeinflection = true;
164  wordType = m_deinflection->getWordType();
165  }
166  }
167  else
168  {
169  deinflectionLabel = NULL;
170  wordType = NULL;
171  m_hasDeinflection = false;
172  }
173 
174  if( results )
175  {
176  EntryList *common = new EntryList();
177  EntryList *uncommon = new EntryList();
178  EntryList::EntryIterator i( *results );
179  while( i.hasNext() )
180  {
181  EntryEdict *entry = static_cast<EntryEdict*>( i.next() );
182  if( entry->isCommon() )
183  {
184  common->append( entry );
185  }
186  else
187  {
188  uncommon->append( entry );
189  }
190  }
191 
192  delete results;
193  results = new EntryList();
194  results->appendList( common );
195  results->appendList( uncommon );
196  delete common;
197  delete uncommon;
198 
199  EntryList *exact = new EntryList();
200  EntryList *beginning = new EntryList();
201  EntryList *ending = new EntryList();
202  EntryList *anywhere = new EntryList();
203  EntryList::EntryIterator it( *results );
204  while( it.hasNext() )
205  {
206  Entry *entry = it.next();
207 
208  if( entry->getWord() == query.getWord() )
209  {
210  exact->append( entry );
211  }
212  else if( entry->getWord().startsWith( query.getWord() ) )
213  {
214  beginning->append( entry );
215  }
216  else if( entry->getWord().endsWith( query.getWord() ) )
217  {
218  ending->append( entry );
219  }
220  else
221  {
222  anywhere->append( entry );
223  }
224  }
225 
226  delete results;
227  results = new EntryList();
228  results->appendList( exact );
229  results->appendList( beginning );
230  results->appendList( ending );
231  results->appendList( anywhere );
232  delete exact;
233  delete beginning;
234  delete ending;
235  delete anywhere;
236  }
237 
238  return results;
239 }
240 
245 QStringList DictFileEdict::listDictDisplayOptions( QStringList x ) const
246 {
247  x += displayOptions().keys();
248  return x;
249 }
250 
254 bool DictFileEdict::loadDictionary( const QString &fileName, const QString &dictName )
255 {
256  if( m_edictFile.valid() )
257  {
258  return false; //Already loaded
259  }
260 
261  if( m_edictFile.loadFile( fileName ) )
262  {
263  m_dictionaryName = dictName;
264  m_dictionaryFile = fileName;
265 
266  m_deinflection = new Deinflection( m_dictionaryName );
267  m_deinflection->load();
268 
269  return true;
270  }
271 
272  return false;
273 }
274 
275 QMap<QString,QString> DictFileEdict::loadDisplayOptions() const
276 {
277  QMap<QString,QString> list = displayOptions();
278  list[ "Word/Kanji" ] = "Word/Kanji";
279  list[ "Reading" ] = "Reading";
280  list[ "Meaning" ] = "Meaning";
281  list[ "--Newline--" ] = "--Newline--";
282 
283  return list;
284 }
285 
286 QStringList* DictFileEdict::loadListType( KConfigSkeletonItem *item
287  , QStringList *list
288  , const QMap<QString,QString> &long2short )
289 {
290  QStringList listFromItem;
291 
292  if( item != NULL )
293  {
294  listFromItem = item->property().toStringList();
295  }
296 
297  if( ! listFromItem.isEmpty() )
298  {
299  delete list;
300 
301  list = new QStringList();
302  foreach( const QString &it, listFromItem )
303  {
304  if( long2short.contains( it ) )
305  {
306  list->append( long2short[ it ] );
307  }
308  }
309  }
310 
311  return list;
312 }
313 
314 void DictFileEdict::loadSettings()
315 {
316  this->displayFields = new QStringList( loadDisplayOptions().values() );
317 }
318 
319 void DictFileEdict::loadSettings( KConfigSkeleton *config )
320 {
321  QMap<QString,QString> long2short = displayOptions();
322  long2short[ "Word/Kanji" ] = "Word/Kanji";
323  long2short[ "Reading" ] = "Reading";
324  long2short[ "Meaning" ] = "Meaning";
325  long2short[ "--Newline--" ] = "--Newline--";
326 
327  KConfigSkeletonItem *item = config->findItem( getType() + "__displayFields" );
328  this->displayFields = loadListType( item, this->displayFields, long2short );
329 }
330 
331 inline Entry* DictFileEdict::makeEntry( const QString &entry )
332 {
333  return new EntryEdict( getName(), entry );
334 }
335 
336 DictionaryPreferenceDialog *DictFileEdict::preferencesWidget( KConfigSkeleton *config, QWidget *parent )
337 {
338  DictFileFieldSelector *dialog = new DictFileFieldSelector( config, getType(), parent );
339  dialog->addAvailable( listDictDisplayOptions( QStringList() ) );
340  return dialog;
341 }
342 
351 bool DictFileEdict::validDictionaryFile( const QString &filename )
352 {
353  QFile file( filename );
354  bool returnFlag = true;
355 
356  if( ! file.exists() || ! file.open( QIODevice::ReadOnly ) )
357  {
358  return false;
359  }
360 
361  //Now we can actually check the file
362  QTextStream fileStream( &file );
363  fileStream.setCodec( QTextCodec::codecForName( "eucJP" ) );
364  QString commentMarker( "????" ); //Note: Don't touch this! vim seems to have
365  //An odd text codec error here too :(
366  QRegExp formattedLine( "^\\S+\\s+(\\[\\S+\\]\\s+)?/.*/$" );
367  while( ! fileStream.atEnd() )
368  {
369  QString line = fileStream.readLine();
370 
371  if( line.left( 4 ) == commentMarker )
372  {
373  continue;
374  }
375  if( line.contains( formattedLine ) ) //If it matches our regex
376  {
377  continue;
378  }
379 
380  returnFlag = false;
381  break;
382  }
383 
384  file.close();
385  return returnFlag;
386 }
387 
391 //TODO: Actually write this method (validQuery)
392 bool DictFileEdict::validQuery( const DictQuery &query )
393 {
394  return true;
395 }
QTextStream::setCodec
void setCodec(QTextCodec *codec)
DictQuery::Any
Definition: dictquery.h:307
QWidget
QMap::contains
bool contains(const Key &key) const
DictFileFieldSelector
Definition: dictfilefieldselector.h:36
QListIterator::next
const T & next()
DictionaryPreferenceDialog
This abstract base class specifies the interface for dictionary preference dialogs in user applicatio...
Definition: dictionarypreferencedialog.h:42
DictFileEdict::validQuery
bool validQuery(const DictQuery &query)
Reject queries that specify anything we don't understand.
Definition: dictfileedict.cpp:392
QTextStream::readLine
QString readLine(qint64 maxlen)
Deinflection::search
EntryList * search(const DictQuery &query, const QVector< QString > &preliminaryResults)
Definition: deinflection.cpp:70
DictQuery::isEmpty
bool isEmpty() const
Definition: dictquery.cpp:111
deinflection.h
Entry
The Entry class is a generic base class for each particular entry in a given dictionary.
Definition: entry.h:44
DictFileEdict::EntryEdict
friend class EntryEdict
Definition: dictfileedict.h:51
EntryEdict::matchesWordType
bool matchesWordType(const DictQuery &query) const
Definition: entryedict.cpp:333
QString::split
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
DictQuery::getPronunciation
QString getPronunciation() const
Accessor for the Pronunciation field (generally kana)
Definition: dictquery.cpp:528
Entry::getWord
QString getWord() const
Get the word from this Entry.
Definition: entry.cpp:100
QMap< QString, QString >
EDICT
#define EDICT
Definition: kitenmacros.h:24
DictFileEdict::wordType
static QString * wordType
Definition: dictfileedict.h:69
Deinflection::getDeinflectionLabel
QString * getDeinflectionLabel()
Definition: deinflection.cpp:60
Deinflection
Definition: deinflection.h:36
QFile::exists
bool exists() const
Deinflection::load
bool load()
Definition: deinflection.cpp:164
DictQuery::Adjective
Definition: dictquery.h:310
DictFileFieldSelector::addAvailable
void addAvailable(const QStringList &list)
Definition: dictfilefieldselector.cpp:76
DictFile::getName
virtual QString getName() const
Returns the name of the dictionary.
Definition: dictfile.h:132
QFile
DictFileEdict::deinflectionLabel
static QString * deinflectionLabel
Definition: dictfileedict.h:68
QTextStream
DictFileEdict::makeEntry
virtual Entry * makeEntry(const QString &entry)
Definition: dictfileedict.cpp:331
DictFile::m_dictionaryName
QString m_dictionaryName
Name is the 'primary key' of the list of dictionaries.
Definition: dictfile.h:152
QList::size
int size() const
entryedict.h
QMap::keys
QList< Key > keys() const
QRegExp
DictFileEdict::doSearch
virtual EntryList * doSearch(const DictQuery &query)
Do a search, respond with a list of entries.
Definition: dictfileedict.cpp:88
Entry::matchesQuery
virtual bool matchesQuery(const DictQuery &) const
Fairly important method, this tests if this particular entry matches a query.
Definition: entry.cpp:294
DictFile::m_dictionaryType
QString m_dictionaryType
This MUST BE SET IN THE CONSTRUCTOR.
Definition: dictfile.h:168
QList::count
int count(const T &value) const
DictFileEdict::displayFields
static QStringList * displayFields
Definition: dictfileedict.h:81
QList::append
void append(const T &value)
QTextStream::atEnd
bool atEnd() const
EntryEdict
Definition: entryedict.h:60
DictFileEdict::loadSettings
void loadSettings()
Definition: dictfileedict.cpp:314
DictFile::m_dictionaryFile
QString m_dictionaryFile
This is mostly a placeholder, but your class will get asked what file it is using, so either be sure to put something here, or override getFile() and respond with something that will be sensical in a dictionary selection dialog box.
Definition: dictfile.h:160
DictFileEdict::loadListType
QStringList * loadListType(KConfigSkeletonItem *item, QStringList *list, const QMap< QString, QString > &long2short)
Definition: dictfileedict.cpp:286
DictQuery::getMeaning
QString getMeaning() const
Accessor for the non-japanese meaning field.
Definition: dictquery.cpp:502
QList::isEmpty
bool isEmpty() const
QString::isEmpty
bool isEmpty() const
DictFileEdict::~DictFileEdict
virtual ~DictFileEdict()
The destructor...
Definition: dictfileedict.cpp:69
QString::startsWith
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
DictQuery::getProperty
QString getProperty(const QString &key) const
Get a specific property by key (is the same as using operator[] const)
Definition: dictquery.cpp:440
QString::endsWith
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
DictQuery::getWord
QString getWord() const
Accessor for the Word/Kanji field (this is usually used for anything containing kanji).
Definition: dictquery.cpp:554
DictFile::getType
virtual QString getType() const
Returns the type of files this dictFile object deals with.
Definition: dictfile.h:136
QList::first
T & first()
QString
EntryList::appendList
void appendList(const EntryList *other)
Append another EntryList onto this one.
Definition: entrylist.cpp:306
QList< QString >
QFile::open
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
QStringList
dictfilefieldselector.h
QString::contains
bool contains(QChar ch, Qt::CaseSensitivity cs) const
LinearEdictFile::findMatches
QVector< QString > findMatches(const QString &searchString) const
Get everything that looks remotely like a given search string.
Definition: linearedictfile.cpp:45
DictQuery::getMatchWordType
MatchWordType getMatchWordType() const
Get which word type is currently set on the DictQuery.
Definition: dictquery.cpp:616
QFile::close
virtual void close()
Deinflection::getWordType
QString * getWordType()
Definition: deinflection.cpp:65
LinearEdictFile::loadFile
bool loadFile(const QString &filename)
Load a file, generate the index if it doesn't already exist.
Definition: linearedictfile.cpp:59
DictFile::m_searchableAttributes
QMap< QString, QString > m_searchableAttributes
This allows the programming user to see a list of possible search types (probably through a drop down...
Definition: dictfile.h:178
QVector
EntryEdict::isCommon
bool isCommon() const
Definition: entryedict.cpp:102
QString::at
const QChar at(int position) const
QTextCodec::codecForName
QTextCodec * codecForName(const QByteArray &name)
DictQuery
A class to allow users of libkiten to properly setup a database query.
Definition: dictquery.h:89
kitenmacros.h
DictFileEdict::m_edictFile
LinearEdictFile m_edictFile
Definition: dictfileedict.h:79
QString::length
int length() const
QString::left
QString left(int n) const
DictFileEdict::preferencesWidget
virtual DictionaryPreferenceDialog * preferencesWidget(KConfigSkeleton *config, QWidget *parent=NULL)
If you want your own dialog to pick preferences for your dict, then override this.
Definition: dictfileedict.cpp:336
DictFileEdict::loadDictionary
bool loadDictionary(const QString &file, const QString &name)
Load up the dictionary.
Definition: dictfileedict.cpp:254
dictquery.h
QMap::insert
iterator insert(const Key &key, const T &value)
QListIterator
DictFile
Abstract base class, used internally by the library for handling different types of dictionaries This...
Definition: dictfile.h:47
dictfileedict.h
DictFileEdict::displayOptions
virtual QMap< QString, QString > displayOptions() const
Definition: dictfileedict.cpp:75
QVector::size
int size() const
DictFileEdict::listDictDisplayOptions
virtual QStringList listDictDisplayOptions(QStringList x) const
Make a list of all the extra fields in our db.
Definition: dictfileedict.cpp:245
EntryList
EntryList is a simple container for Entry objects, and is-a QList A few simple overrides allo...
Definition: entrylist.h:38
DictFileEdict::DictFileEdict
DictFileEdict()
Per instructions in the super-class, this constructor basically sets the dictionaryType member variab...
Definition: dictfileedict.cpp:56
entrylist.h
DictFileEdict::validDictionaryFile
virtual bool validDictionaryFile(const QString &filename)
Scan a potential file for the correct format, remembering to skip comment characters.
Definition: dictfileedict.cpp:351
DictQuery::listPropertyKeys
const QList< QString > listPropertyKeys() const
Use this to get a list of all the property keys in the query.
Definition: dictquery.cpp:445
LinearEdictFile::valid
bool valid() const
Test if the file was properly loaded.
Definition: linearedictfile.cpp:91
DictQuery::Verb
Definition: dictquery.h:308
QListIterator::hasNext
bool hasNext() const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:16:38 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kiten/lib

Skip menu "kiten/lib"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal