kiten/lib
DictQuery.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
00066
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
00085 return toString();
00086 }
00087
00088 DictQuery::~DictQuery()
00089 {
00090 delete d;
00091 }
00092
00093 bool DictQuery::isEmpty() const {
00094
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
00108
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() );
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
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
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
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
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 );
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
00266
00267 this->operator=(result);
00268 return *this;
00269 }
00270
00271
00272 DictQuery::stringTypeEnum DictQuery::stringTypeCheck(const QString &in) {
00273 stringTypeEnum firstType;
00274
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 ;
00287 else
00288 {
00289 return DictQuery::mixed;
00290 }
00291 }
00292 }
00293 return firstType;
00294 }
00295
00296
00297
00298 DictQuery::stringTypeEnum DictQuery::charTypeCheck(const QChar &ch) {
00299 if(ch.toLatin1()) {
00300 return strTypeLatin;
00301 }
00302
00303
00304
00305
00306 if(0x3040 <= ch.unicode() && ch.unicode() <= 0x30FF )
00307 return strTypeKana;
00308 return strTypeKanji;
00309 }
00310
00311
00312
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
00334
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
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
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
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
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483 const QString DictQuery::mainDelimiter(" ");
00484 const QString DictQuery::propertySeperator(":");