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

kiten/lib

DictQuery.cpp

Go to the documentation of this file.
00001 /* This file is part of Kiten, a KDE Japanese Reference Tool...
00002    Copyright (C) 2006 Joseph Kerian <jkerian@gmail.com>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017    Boston, MA 02110-1301, USA.
00018 */
00019 
00020 /*
00021 TODO: Add features to limit the number of hits on a per-search basis.
00022 
00023     Add a mechanism (either through subclassing, or directly) for use
00024         for marking "requested" fields for the dcop system.
00025 */
00026 
00027 #include "DictQuery.h"
00028 
00029 #include <QtCore/QStringList>
00030 #include <QtCore/QString>
00031 
00032 #include <kdebug.h>
00033 
00034 class DictQuery::Private {
00035 public:
00036     Private() : m_matchType(DictQuery::matchExact) {}
00038     QString m_meaning;
00040     QString m_pronunciation;
00042     QString m_word;
00044     QHash<QString,QString> m_extendedAttributes;
00047     QStringList m_entryOrder;
00049     QStringList m_targetDictionaries;
00051     MatchType m_matchType;
00052 
00054     static const QString pronunciationMarker;
00056     static const QString meaningMarker;
00058     static const QString wordMarker;
00059 };
00060 const QString DictQuery::Private::pronunciationMarker("__@\\p");
00061 const QString DictQuery::Private::meaningMarker("__@\\m");
00062 const QString DictQuery::Private::wordMarker("_@\\w");
00063 
00064 /*****************************************************************************
00065 *   Constructors, Destructors, Initilizers, and
00066 *   Global Status Indicators.
00067 *****************************************************************************/
00068 DictQuery::DictQuery() : d(new Private)
00069 { }
00070 
00071 DictQuery::DictQuery(const QString& str) : d(new Private) {
00072     this->operator=((QString)str);
00073 }
00074 
00075 DictQuery::DictQuery(const DictQuery& orig) : d(new Private) {
00076     this->operator=((DictQuery&)orig);
00077 }
00078 
00079 DictQuery *DictQuery::clone() const {
00080     return new DictQuery(*this);
00081 }
00082 
00083 DictQuery::operator QString() const {
00084     //kDebug() << "DictQuery toString operator called!";
00085     return toString();
00086 }
00087 
00088 DictQuery::~DictQuery()
00089 {
00090     delete d;
00091 }
00092 
00093 bool DictQuery::isEmpty() const {
00094 //We're only empty if the two strings are empty too
00095     return d->m_extendedAttributes.isEmpty() && d->m_meaning.isEmpty()
00096         && d->m_pronunciation.isEmpty() && d->m_word.isEmpty();
00097 }
00098 void DictQuery::clear() {
00099     d->m_extendedAttributes.clear();
00100     d->m_meaning="";
00101     d->m_pronunciation="";
00102     d->m_word="";
00103     d->m_entryOrder.clear();
00104 }
00105 
00106 /*****************************************************************************
00107 *   Methods that involve multiple instances of the class
00108 *   (comparison, copy etc)
00109 *****************************************************************************/
00110 DictQuery &DictQuery::operator=(const DictQuery &old) {
00111     if ( &old == this ) return *this;
00112     clear();
00113     d->m_matchType = old.d->m_matchType;
00114     d->m_extendedAttributes = old.d->m_extendedAttributes;
00115     d->m_meaning=old.d->m_meaning;
00116     d->m_pronunciation=old.d->m_pronunciation;
00117     d->m_word = old.d->m_word;
00118     d->m_entryOrder = old.d->m_entryOrder;
00119     return *this;
00120 }
00121 
00122 DictQuery &DictQuery::operator+=(const DictQuery &old) {
00123     foreach(const QString &item, old.d->m_entryOrder) {
00124         if(item == d->meaningMarker) {
00125             if(d->m_entryOrder.removeAll(d->meaningMarker) > 0 )
00126                 setMeaning(getMeaning() + mainDelimiter + old.getMeaning());
00127             else
00128                 setMeaning(old.getMeaning());
00129         } else if(item == d->pronunciationMarker) {
00130             if(d->m_entryOrder.removeAll(d->pronunciationMarker)>0)
00131                 setPronunciation(getPronunciation() + mainDelimiter + old.getPronunciation() );
00132             else
00133                 setPronunciation(old.getPronunciation());
00134         } else if(item == d->wordMarker) {
00135             d->m_entryOrder.removeAll(d->wordMarker);
00136             setWord( old.getWord() ); //Only one of these allowed
00137         } else {
00138             setProperty(item,old.getProperty(item));
00139         }
00140     }
00141     return *this;
00142 }
00143 
00144 DictQuery operator+(const DictQuery &a, const DictQuery &b) {
00145     DictQuery val(a);
00146     val += b;
00147     return val;
00148 }
00149 
00150 bool operator==(const DictQuery &other, const DictQuery &query ) {
00151     if( (other.d->m_pronunciation != query.d->m_pronunciation)
00152         || (other.d->m_meaning != query.d->m_meaning)
00153         || (other.d->m_word != query.d->m_word)
00154         || (other.d->m_entryOrder != query.d->m_entryOrder)
00155         || (other.d->m_extendedAttributes != query.d->m_extendedAttributes)
00156         || (other.d->m_matchType != query.d->m_matchType)
00157       )
00158         return false;
00159 
00160     return true;
00161 }
00162 bool operator!=(const DictQuery &other, const DictQuery &query ) {
00163     return !(other == query);
00164 }
00165 
00166 bool operator<(const DictQuery &A, const DictQuery &B) {
00167     QHash<QString,QString>::const_iterator it = A.d->m_extendedAttributes.begin();
00168     QHash<QString,QString>::const_iterator it_end = A.d->m_extendedAttributes.end();
00169     for(;it != it_end; ++it) {
00170         QString B_version = B.d->m_extendedAttributes.value(it.key());
00171         if(A.d->m_extendedAttributes[it.key()] != B_version) {
00172             if(!B_version.contains(",") && !B_version.contains("-"))
00173                 return false;
00174             //TODO: check for multi-values or ranges in DictQuery operator<
00175         }
00176     }
00177 
00178     if(!A.d->m_pronunciation.isEmpty()) {
00179         QStringList aList = A.d->m_pronunciation.split(DictQuery::mainDelimiter);
00180         QStringList bList = B.d->m_pronunciation.split(DictQuery::mainDelimiter);
00181         foreach( const QString &str, aList )
00182             if(bList.contains(str)==0)
00183                 return false;
00184     }
00185 
00186     if(!A.d->m_meaning.isEmpty()) {
00187         QStringList aList = A.d->m_meaning.split(DictQuery::mainDelimiter);
00188         QStringList bList = B.d->m_meaning.split(DictQuery::mainDelimiter);
00189         foreach( const QString &str, aList )
00190             if(bList.contains(str)==0)
00191                 return false;
00192     }
00193 
00194     //Assume only one entry for word
00195     if(!A.d->m_word.isEmpty())
00196         if(A.d->m_word != B.d->m_word)
00197             return false;
00198 
00199     return true;
00200 }
00201 
00202 /*****************************************************************************
00203 *   Methods to extract from QStrings and recreate QStrings
00204 *
00205 *****************************************************************************/
00206 const QString DictQuery::toString() const {
00207     if(isEmpty())
00208         return QString();
00209 
00210     QString reply;
00211     foreach( const QString &it, d->m_entryOrder ) {
00212         if(it == d->pronunciationMarker)
00213             reply += d->m_pronunciation+mainDelimiter;
00214         else if(it == d->meaningMarker)
00215             reply += d->m_meaning+mainDelimiter;
00216         else if(it == d->wordMarker)
00217             reply += d->m_word+mainDelimiter;
00218         else
00219             reply += it + propertySeperator + d->m_extendedAttributes.value(it)
00220                 + mainDelimiter;
00221     }
00222     reply.truncate(reply.length()-mainDelimiter.length());
00223 
00224     return reply;
00225 }
00226 
00227 DictQuery &DictQuery::operator=(const QString &str) {
00228     QStringList parts = str.split(mainDelimiter);
00229     DictQuery result;
00230     if(str.length() > 0)
00231         foreach( const QString &it, parts) {
00232             if(it.contains(propertySeperator)) {
00233                 QStringList prop = it.split(propertySeperator);
00234                 if(prop.count() != 2)
00235                     break;
00236                 result.setProperty(prop[0],prop[1]);
00237                 //replace or throw an error with duplicates?
00238             } else switch(stringTypeCheck(it)) {
00239                 case DictQuery::strTypeLatin :
00240                     if(result.d->m_entryOrder.removeAll(d->meaningMarker) > 0 )
00241                         result.setMeaning(result.getMeaning() + mainDelimiter + it);
00242                     else
00243                         result.setMeaning(it);
00244                     break;
00245                 case DictQuery::strTypeKana :
00246                     if(result.d->m_entryOrder.removeAll(d->pronunciationMarker)>0)
00247                         result.setPronunciation(result.getPronunciation()
00248                                                                          + mainDelimiter + it );
00249                     else
00250                         result.setPronunciation(it);
00251                     break;
00252 
00253                 case DictQuery::strTypeKanji :
00254                     result.d->m_entryOrder.removeAll(d->wordMarker);
00255                     result.setWord( it ); //Only one of these allowed
00256                     break;
00257 
00258                 case DictQuery::mixed :
00259                     kWarning() <<"DictQuery: String parsing error - mixed type";
00260                     break;
00261                 case DictQuery::stringParseError :
00262                     kWarning() << "DictQuery: String parsing error";
00263             }
00264         }
00265     //kDebug() << "Query: ("<<result.getWord() << ") ["<<result.getPronunciation()<<"] :"<<
00266     //  result.getMeaning()<<endl;
00267     this->operator=(result);
00268     return *this;
00269 }
00270 //Private utility method for the above... confirms that an entire string
00271 //is either completely japanese or completely english
00272 DictQuery::stringTypeEnum DictQuery::stringTypeCheck(const QString &in) {
00273     stringTypeEnum firstType;
00274     //Split into individual characters
00275     if(in.size() <= 0)
00276         return DictQuery::stringParseError;
00277 
00278     firstType = charTypeCheck(in.at(0));
00279     for(int i=1; i<in.size(); i++ ){
00280         stringTypeEnum newType = charTypeCheck(in.at(i));
00281         if(newType != firstType) {
00282             if(firstType == strTypeKana && newType == strTypeKanji) {
00283                 firstType = strTypeKanji;
00284             }
00285             else if(firstType == strTypeKanji && newType == strTypeKana)
00286                 ; //That's okay
00287             else
00288             {
00289                 return DictQuery::mixed;
00290             }
00291         }
00292     }
00293     return firstType;
00294 }
00295 //Private utility method for the stringTypeCheck
00296 //Just checks and returns the type of the first character in the string
00297 //that is passed to it.
00298 DictQuery::stringTypeEnum DictQuery::charTypeCheck(const QChar &ch) {
00299     if(ch.toLatin1()) {
00300         return strTypeLatin;
00301     }
00302     //The unicode character boundaries are:
00303     // 3040 - 309F Hiragana
00304     // 30A0 - 30FF Katakana
00305     // 31F0 - 31FF Katakana phonetic expressions (wtf?)
00306     if(0x3040 <= ch.unicode() && ch.unicode() <= 0x30FF /*|| ch.unicode() & 0x31F0*/)
00307         return strTypeKana;
00308     return strTypeKanji;
00309 }
00310 
00311 /*****************************************************************************
00312 *   An array of Property List accessors and mutators
00313 *
00314 *****************************************************************************/
00315 QString DictQuery::getProperty(const QString &key) const {
00316     return (*this)[key];
00317 }
00318 
00319 const QList<QString> DictQuery::listPropertyKeys() const {
00320     return d->m_extendedAttributes.keys();
00321 }
00322 const QString DictQuery::operator[] (const QString &key) const {
00323     return d->m_extendedAttributes.value(key);
00324 }
00325 QString DictQuery::operator[] (const QString &key) {
00326     return d->m_extendedAttributes[key];
00327 }
00328 
00329 bool DictQuery::hasProperty(const QString &key) const {
00330     return d->m_entryOrder.contains(key)>0;
00331 }
00332 
00333 //TODO: Add i18n handling and alternate versions of property names
00334 //TODO: further break down the barrier between different types
00335 bool DictQuery::setProperty(const QString& key,const QString& value) {
00336     if(key==d->pronunciationMarker || key==d->meaningMarker ||
00337         key.isEmpty() || value.isEmpty())
00338         return false;
00339     if ( ! d->m_extendedAttributes.contains( key ) )
00340         d->m_entryOrder.append(key);
00341     d->m_extendedAttributes.insert(key,value);
00342     return true;
00343 }
00344 
00345 bool DictQuery::removeProperty(const QString &key) {
00346     if(d->m_extendedAttributes.contains(key))
00347         return d->m_entryOrder.removeAll(key);
00348     return false;
00349 }
00350 
00351 QString DictQuery::takeProperty ( const QString & key ) {
00352     d->m_entryOrder.removeAll(key);
00353     return d->m_extendedAttributes.take(key);
00354 }
00355 
00356 /*****************************************************************************
00357 *   Meaning and Pronunciation Accessors and Mutators
00358 ****************************************************************************/
00359 QString DictQuery::getMeaning() const {
00360     return d->m_meaning;
00361 }
00362 
00363 bool DictQuery::setMeaning(const QString &newMeaning) {
00364     if(newMeaning.isEmpty())
00365 #ifdef USING_QUERY_EXCEPTIONS
00366         throw invalidQueryException(newMeaning);
00367 #else
00368         return false;
00369 #endif
00370     d->m_meaning=newMeaning;
00371     if(!d->m_entryOrder.contains(d->meaningMarker))
00372         d->m_entryOrder.append(d->meaningMarker);
00373     return true;
00374 }
00375 
00376 QString DictQuery::getPronunciation() const {
00377     return d->m_pronunciation;
00378 }
00379 
00380 bool DictQuery::setPronunciation(const QString &newPro) {
00381     if(newPro.isEmpty())
00382 #ifdef USING_QUERY_EXCEPTIONS
00383         throw invalidQueryException(newPro);
00384 #else
00385         return false;
00386 #endif
00387     d->m_pronunciation=newPro;
00388     if(!d->m_entryOrder.contains(d->pronunciationMarker))
00389         d->m_entryOrder.append(d->pronunciationMarker);
00390     return true;
00391 }
00392 
00393 QString DictQuery::getWord() const{
00394     return d->m_word;
00395 }
00396 
00397 bool DictQuery::setWord(const QString &newWord) {
00398     if(newWord.isEmpty())
00399 #ifdef USING_QUERY_EXCEPTIONS
00400         throw invalidQueryException(newWord);
00401 #else
00402         return false;
00403 #endif
00404     d->m_word=newWord;
00405     if(!d->m_entryOrder.contains(d->wordMarker))
00406         d->m_entryOrder.append(d->wordMarker);
00407     return true;
00408 }
00409 /*************************************************************
00410   Handlers for getting and setting dictionary types
00411   *************************************************************/
00412 QStringList DictQuery::getDictionaries() const {
00413     return d->m_targetDictionaries;
00414 }
00415 
00416 void DictQuery::setDictionaries(const QStringList &newDictionaries) {
00417     d->m_targetDictionaries = newDictionaries;
00418 }
00419 
00420 /**************************************************************
00421   Match Type Accessors and Mutators
00422   ************************************************************/
00423 DictQuery::MatchType DictQuery::getMatchType() const {
00424     return d->m_matchType;
00425 }
00426 
00427 void DictQuery::setMatchType(MatchType newType) {
00428     d->m_matchType = newType;
00429 }
00430 
00431 /**************************************************************
00432 *   Aliases to handle different forms of operator arguments
00433 *   Disabled at the moment
00434 *************************************************************
00435 bool operator==( const QString &other, const DictQuery &query ) {
00436     DictQuery x(other); return x == query;
00437 }
00438 bool operator==( const DictQuery &query, const QString &other ) {
00439     return other==query;
00440 }
00441 bool operator!=( const DictQuery &q1, const DictQuery &q2 ) {
00442     return !(q1==q2);
00443 }
00444 bool operator!=( const QString &other, const DictQuery &query ) {
00445     return !(other==query);
00446 }
00447 bool operator!=( const DictQuery &query, const QString &other ) {
00448     return !(query==other);
00449 }
00450 inline bool operator<=( const DictQuery &a, const DictQuery &b) {
00451     return (a<b || a==b);
00452 }
00453 bool operator>=( const DictQuery &a, const DictQuery &b) {
00454     return (b>a || a==b);
00455 }
00456 bool operator>( const DictQuery &a, const DictQuery &b) {
00457     return b < a;
00458 }
00459 DictQuery &operator+( const DictQuery &a, const QString &b) {
00460     return (*(new DictQuery(a))) += b;
00461 }
00462 DictQuery &operator+( const QString &a,   const DictQuery &b)  {
00463     return (*(new DictQuery(a))) += b;
00464 }
00465 DictQuery    &DictQuery::operator+=(const QString &str) {
00466     DictQuery x(str);
00467     return operator+=(x);
00468 }
00469 #ifndef QT_NO_CAST_ASCII
00470 DictQuery    &DictQuery::operator=(const char *str) {
00471     QString x(str);
00472     return operator=(x);
00473 }
00474 DictQuery    &DictQuery::operator+=(const char *str) {
00475     DictQuery x(str);
00476     return operator+=(x);
00477 }
00478 #endif
00479 */
00480 /**************************************************************
00481 *   Set our constants declared in the class
00482 **************************************************************/
00483 const QString DictQuery::mainDelimiter(" ");
00484 const QString DictQuery::propertySeperator(":");

kiten/lib

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

kdeedu

Skip menu "kdeedu"
  • kalzium
  • kanagram
  • kig
  •   lib
  • klettres
  • kstars
  • libkdeedu
  •   keduvocdocument
  •   docs
  •   src
  • parley
  •   stepcore
Generated for kdeedu by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal