00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023
00024 #include "kstringhandler.h"
00025 #include "kglobal.h"
00026
00027 QString KStringHandler::word( const QString &text , uint pos )
00028 {
00029 QStringList list = QStringList::split( " ", text , true );
00030
00031 if ( pos < list.count() )
00032 return list[ pos ];
00033
00034 return "";
00035 }
00036
00037 QString KStringHandler::word( const QString &text , const char *range )
00038 {
00039
00040
00041
00042
00043
00044 QStringList list = QStringList::split( " ", text , true );
00045 QString tmp = "";
00046 QString r = range;
00047
00048 if ( text.isEmpty() )
00049 return tmp;
00050
00051
00052 QRegExp reg;
00053
00054 int at = 0;
00055 int pos = 0;
00056 int cnt = 0;
00057
00058 if ( r.find(QRegExp("[0-9]+:[0-9]+")) != -1 )
00059 {
00060 at = r.find(":");
00061 pos = atoi( r.left(at).ascii() );
00062 cnt = atoi( r.remove(0,at+1).ascii() );
00063 }
00064 else if ( r.find(QRegExp(":+[0-9]+")) != -1 )
00065 {
00066 at = r.find(":");
00067 pos = 0;
00068 cnt = atoi( r.remove(0,at+1).ascii() );
00069 }
00070 else if ( r.find(QRegExp("[0-9]+:+")) != -1 )
00071 {
00072 at = r.find(":");
00073 pos = atoi( r.left(at).ascii() );
00074 cnt = list.count();
00075 }
00076 else if ( r.find(QRegExp("[0-9]+")) != -1 )
00077 {
00078 pos = atoi( r.ascii() );
00079 cnt = pos;
00080 }
00081 else
00082 {
00083 return tmp;
00084 }
00085
00086
00087
00088
00089 int wordsToExtract = cnt-pos+1;
00090 QStringList::Iterator it = list.at( pos);
00091
00092 while ( (it != list.end()) && (wordsToExtract-- > 0))
00093 {
00094 tmp += *it;
00095 tmp += " ";
00096 it++;
00097 }
00098
00099 return tmp.stripWhiteSpace();
00100 }
00101
00102
00103
00104
00105 QString KStringHandler::insword( const QString &text , const QString &word , uint pos )
00106 {
00107 if ( text.isEmpty() )
00108 return word;
00109
00110 if ( word.isEmpty() )
00111 return text;
00112
00113
00114 QStringList list = QStringList::split( " ", text, true );
00115
00116 if ( pos >= list.count() )
00117 list.append( word );
00118 else
00119 list.insert( list.at(pos) , word );
00120
00121
00122 return list.join( " " );
00123 }
00124
00125 QString KStringHandler::setword( const QString &text , const QString &word , uint pos )
00126 {
00127 if ( text.isEmpty() )
00128 return word;
00129
00130 if ( word.isEmpty() )
00131 return text;
00132
00133
00134 QStringList list = QStringList::split( " ", text, true );
00135
00136 if ( pos >= list.count() )
00137 list.append( word );
00138 else
00139 {
00140 list.insert( list.remove( list.at(pos) ) , word );
00141 }
00142
00143
00144 return list.join( " " );
00145 }
00146
00147 QString KStringHandler::remrange( const QString &text , const char *range )
00148 {
00149
00150
00151
00152
00153
00154 QStringList list = QStringList::split( " ", text , true );
00155 QString tmp = "";
00156 QString r = range;
00157
00158 if ( text.isEmpty() )
00159 return tmp;
00160
00161
00162 QRegExp reg;
00163
00164 int at = 0;
00165 int pos = 0;
00166 int cnt = 0;
00167
00168 if ( r.find(QRegExp("[0-9]+:[0-9]+")) != -1 )
00169 {
00170 at = r.find(':');
00171 pos = atoi( r.left(at).ascii() );
00172 cnt = atoi( r.remove(0,at+1).ascii() );
00173 }
00174 else if ( r.find(QRegExp(":+[0-9]+")) != -1 )
00175 {
00176 at = r.find(':');
00177 pos = 0;
00178 cnt = atoi( r.remove(0,at+1).ascii() );
00179 }
00180 else if ( r.find(QRegExp("[0-9]+:+")) != -1 )
00181 {
00182 at = r.find(':');
00183 pos = atoi( r.left(at).ascii() );
00184 cnt = list.count();
00185 }
00186 else if ( r.find(QRegExp("[0-9]+")) != -1 )
00187 {
00188 pos = atoi( r.ascii() );
00189 cnt = pos;
00190 }
00191 else
00192 {
00193 return text;
00194 }
00195
00196
00197
00198
00199 int wordsToDelete = cnt-pos+1;
00200 QStringList::Iterator it = list.at( pos);
00201
00202 while ( (it != list.end()) && (wordsToDelete-- > 0))
00203 it = list.remove( it );
00204
00205 return list.join( " " );
00206 }
00207
00208 QString KStringHandler::remword( const QString &text , uint pos )
00209 {
00210 QString tmp = "";
00211
00212 if ( text.isEmpty() )
00213 return tmp;
00214
00215
00216 QStringList list = QStringList::split( " ", text, true );
00217
00218 if ( pos < list.count() )
00219 list.remove( list.at( pos ) );
00220
00221
00222 return list.join( " " );
00223 }
00224
00225 QString KStringHandler::remword( const QString &text , const QString &word )
00226 {
00227 QString tmp = "";
00228
00229 if ( text.isEmpty() )
00230 return tmp;
00231
00232 if ( word.isEmpty() )
00233 return text;
00234
00235
00236 QStringList list = QStringList::split( " ", text, true );
00237
00238 QStringList::Iterator it = list.find(word);
00239
00240 if (it != list.end())
00241 list.remove( it );
00242
00243
00244 return list.join( " " );
00245 }
00246
00247
00248
00249
00250 QString KStringHandler::capwords( const QString &text )
00251 {
00252 QString tmp = "";
00253
00254 if ( text.isEmpty() )
00255 return tmp;
00256
00257 QStringList list = QStringList::split( " ", text, true );
00258
00259 return capwords( QStringList::split( " ", text, true )).join( " " );
00260 }
00261
00262 QStringList KStringHandler::capwords( const QStringList &list )
00263 {
00264 QStringList tmp;
00265 QString word;
00266
00267 if ( list.count() == 0 )
00268 return tmp;
00269
00270 for ( QStringList::ConstIterator it= list.begin();
00271 it != list.end();
00272 it++)
00273 {
00274 word = *it;
00275 word = word.left(1).upper() + word.remove(0,1);
00276
00277 tmp.append( word );
00278 }
00279
00280 return tmp;
00281 }
00282
00283
00284
00285
00286 QString KStringHandler::reverse( const QString &text )
00287 {
00288 QString tmp;
00289
00290 if ( text.isEmpty() )
00291 return tmp;
00292
00293 QStringList list;
00294 list = QStringList::split( " ", text, true );
00295 list = reverse( list );
00296
00297 return list.join( " " );
00298 }
00299
00300 QStringList KStringHandler::reverse( const QStringList &list )
00301 {
00302 QStringList tmp;
00303
00304 if ( list.count() == 0 )
00305 return tmp;
00306
00307 for ( QStringList::ConstIterator it= list.begin();
00308 it != list.end();
00309 it++)
00310 tmp.prepend( *it );
00311
00312 return tmp;
00313 }
00314
00315
00316
00317
00318 QString KStringHandler::ljust( const QString &text , uint width )
00319 {
00320 QString tmp = text;
00321 tmp = tmp.stripWhiteSpace();
00322
00323 if ( tmp.length() >= width )
00324 return tmp;
00325
00326 for ( uint pos = tmp.length() ; pos < width ; pos++ )
00327 tmp.append(" ");
00328
00329 return tmp;
00330 }
00331
00332 QString KStringHandler::rjust( const QString &text , uint width )
00333 {
00334 QString tmp = text;
00335 tmp = tmp.stripWhiteSpace();
00336
00337 if ( tmp.length() >= width )
00338 return tmp;
00339
00340 for ( uint pos = tmp.length() ; pos < width ; pos++ )
00341 tmp.prepend(" ");
00342
00343 return tmp;
00344 }
00345
00346 QString KStringHandler::center( const QString &text , uint width )
00347 {
00348
00349
00350
00351
00352 QString tmp = text;
00353 tmp = tmp.stripWhiteSpace();
00354
00355 if ( tmp.length() >= width )
00356 return tmp;
00357
00358 bool left = false;
00359
00360 for ( uint pos = tmp.length() ; pos < width ; pos++ )
00361 {
00362 if ( left )
00363 tmp.prepend(" ");
00364 else
00365 tmp.append(" ");
00366
00367
00368 left = !left;
00369 }
00370
00371 return tmp;
00372 }
00373
00374 QString KStringHandler::lsqueeze( const QString & str, uint maxlen )
00375 {
00376 if (str.length() > maxlen) {
00377 int part = maxlen-3;
00378 return QString("..." + str.right(part));
00379 }
00380 else return str;
00381 }
00382
00383 QString KStringHandler::csqueeze( const QString & str, uint maxlen )
00384 {
00385 if (str.length() > maxlen && maxlen > 3) {
00386 int part = (maxlen-3)/2;
00387 return QString(str.left(part) + "..." + str.right(part));
00388 }
00389 else return str;
00390 }
00391
00392 QString KStringHandler::rsqueeze( const QString & str, uint maxlen )
00393 {
00394 if (str.length() > maxlen) {
00395 int part = maxlen-3;
00396 return QString(str.left(part) + "...");
00397 }
00398 else return str;
00399 }
00400
00401 QString KStringHandler::lEmSqueeze(const QString &name, const QFontMetrics& fontMetrics, uint maxlen)
00402 {
00403 return lPixelSqueeze(name, fontMetrics, fontMetrics.maxWidth() * maxlen);
00404 }
00405
00406 static inline int emSqueezeLimit(int delta, int min, int max)
00407 {
00408 if (delta < min) return min;
00409 if (delta > max) return max;
00410 return delta;
00411 }
00412
00413 QString KStringHandler::lPixelSqueeze(const QString& name, const QFontMetrics& fontMetrics, uint maxPixels)
00414 {
00415 uint nameWidth = fontMetrics.width(name);
00416
00417 if (maxPixels < nameWidth)
00418 {
00419 QString tmp = name;
00420 const uint em = fontMetrics.maxWidth();
00421 maxPixels -= fontMetrics.width("...");
00422
00423 while (maxPixels < nameWidth && !tmp.isEmpty())
00424 {
00425 int delta = (nameWidth - maxPixels) / em;
00426 delta = emSqueezeLimit(delta, 1, delta);
00427
00428 tmp.remove(0, delta);
00429 nameWidth = fontMetrics.width(tmp);
00430 }
00431
00432 return ("..." + tmp);
00433 }
00434
00435 return name;
00436 }
00437
00438 QString KStringHandler::cEmSqueeze(const QString& name, const QFontMetrics& fontMetrics, uint maxlen)
00439 {
00440 return cPixelSqueeze(name, fontMetrics, fontMetrics.maxWidth() * maxlen);
00441 }
00442
00443 QString KStringHandler::cPixelSqueeze(const QString& name, const QFontMetrics& fontMetrics, uint maxPixels)
00444 {
00445 uint nameWidth = fontMetrics.width(name);
00446
00447 if (maxPixels < nameWidth)
00448 {
00449 QString tmp = name;
00450 const uint em = fontMetrics.maxWidth();
00451 maxPixels -= fontMetrics.width("...");
00452
00453 while (maxPixels < nameWidth && !tmp.isEmpty())
00454 {
00455 int length = tmp.length();
00456 int delta = (nameWidth - maxPixels) / em;
00457 delta = emSqueezeLimit(delta, 1, length) ;
00458
00459 tmp.remove((length / 2) - (delta / 2), delta);
00460 nameWidth = fontMetrics.width(tmp);
00461 }
00462
00463 return tmp.insert((tmp.length() + 1) / 2, "...");
00464 }
00465
00466 return name;
00467 }
00468
00469 QString KStringHandler::rEmSqueeze(const QString& name, const QFontMetrics& fontMetrics, uint maxlen)
00470 {
00471 return rPixelSqueeze(name, fontMetrics, fontMetrics.maxWidth() * maxlen);
00472 }
00473
00474 QString KStringHandler::rPixelSqueeze(const QString& name, const QFontMetrics& fontMetrics, uint maxPixels)
00475 {
00476 uint nameWidth = fontMetrics.width(name);
00477
00478 if (maxPixels < nameWidth)
00479 {
00480 QString tmp = name;
00481 const uint em = fontMetrics.maxWidth();
00482 maxPixels -= fontMetrics.width("...");
00483
00484 while (maxPixels < nameWidth && !tmp.isEmpty())
00485 {
00486 int length = tmp.length();
00487 int delta = (nameWidth - maxPixels) / em;
00488 delta = emSqueezeLimit(delta, 1, length) ;
00489
00490 tmp.remove(length - delta, delta);
00491 nameWidth = fontMetrics.width(tmp);
00492 }
00493
00494 return (tmp + "...");
00495 }
00496
00497 return name;
00498 }
00499
00501
00502 bool KStringHandler::matchFileName( const QString& filename, const QString& pattern )
00503 {
00504 int len = filename.length();
00505 int pattern_len = pattern.length();
00506
00507 if (!pattern_len)
00508 return false;
00509
00510
00511 if ( pattern[ pattern_len - 1 ] == '*' && len + 1 >= pattern_len ) {
00512 if ( pattern[ 0 ] == '*' )
00513 {
00514 return filename.find(pattern.mid(1, pattern_len - 2)) != -1;
00515 }
00516
00517 const QChar *c1 = pattern.unicode();
00518 const QChar *c2 = filename.unicode();
00519 int cnt = 1;
00520 while ( cnt < pattern_len && *c1++ == *c2++ )
00521 ++cnt;
00522 return cnt == pattern_len;
00523 }
00524
00525
00526 if ( pattern[ 0 ] == '*' && len + 1 >= pattern_len )
00527 {
00528 const QChar *c1 = pattern.unicode() + pattern_len - 1;
00529 const QChar *c2 = filename.unicode() + len - 1;
00530 int cnt = 1;
00531 while ( cnt < pattern_len && *c1-- == *c2-- )
00532 ++cnt;
00533 return cnt == pattern_len;
00534 }
00535
00536
00537 return ( filename == pattern );
00538 }
00539
00540 QStringList
00541 KStringHandler::perlSplit(const QString & sep, const QString & s, uint max)
00542 {
00543 bool ignoreMax = 0 == max;
00544
00545 QStringList l;
00546
00547 int searchStart = 0;
00548
00549 int tokenStart = s.find(sep, searchStart);
00550
00551 while (-1 != tokenStart && (ignoreMax || l.count() < max - 1))
00552 {
00553 if (!s.mid(searchStart, tokenStart - searchStart).isEmpty())
00554 l << s.mid(searchStart, tokenStart - searchStart);
00555
00556 searchStart = tokenStart + sep.length();
00557 tokenStart = s.find(sep, searchStart);
00558 }
00559
00560 if (!s.mid(searchStart, s.length() - searchStart).isEmpty())
00561 l << s.mid(searchStart, s.length() - searchStart);
00562
00563 return l;
00564 }
00565
00566 QStringList
00567 KStringHandler::perlSplit(const QChar & sep, const QString & s, uint max)
00568 {
00569 bool ignoreMax = 0 == max;
00570
00571 QStringList l;
00572
00573 int searchStart = 0;
00574
00575 int tokenStart = s.find(sep, searchStart);
00576
00577 while (-1 != tokenStart && (ignoreMax || l.count() < max - 1))
00578 {
00579 if (!s.mid(searchStart, tokenStart - searchStart).isEmpty())
00580 l << s.mid(searchStart, tokenStart - searchStart);
00581
00582 searchStart = tokenStart + 1;
00583 tokenStart = s.find(sep, searchStart);
00584 }
00585
00586 if (!s.mid(searchStart, s.length() - searchStart).isEmpty())
00587 l << s.mid(searchStart, s.length() - searchStart);
00588
00589 return l;
00590 }
00591
00592 QStringList
00593 KStringHandler::perlSplit(const QRegExp & sep, const QString & s, uint max)
00594 {
00595 bool ignoreMax = 0 == max;
00596
00597 QStringList l;
00598
00599 int searchStart = 0;
00600 int tokenStart = sep.search(s, searchStart);
00601 int len = sep.matchedLength();
00602
00603 while (-1 != tokenStart && (ignoreMax || l.count() < max - 1))
00604 {
00605 if (!s.mid(searchStart, tokenStart - searchStart).isEmpty())
00606 l << s.mid(searchStart, tokenStart - searchStart);
00607
00608 searchStart = tokenStart + len;
00609 tokenStart = sep.search(s, searchStart);
00610 len = sep.matchedLength();
00611 }
00612
00613 if (!s.mid(searchStart, s.length() - searchStart).isEmpty())
00614 l << s.mid(searchStart, s.length() - searchStart);
00615
00616 return l;
00617 }
00618
00619 QString
00620 KStringHandler::tagURLs( const QString& text )
00621 {
00622 QRegExp urlEx("(www\\.(?!\\.)|(f|ht)tp(|s)://)[\\d\\w\\./,:_~\\?=&;#@\\-\\+\\%]+[\\d\\w/]");
00623
00624 QString richText( text );
00625 int urlPos = 0, urlLen;
00626 while ((urlPos = urlEx.search(richText, urlPos)) >= 0)
00627 {
00628 urlLen = urlEx.matchedLength();
00629 QString href = richText.mid( urlPos, urlLen );
00630
00631 if((urlPos > 0) && richText[urlPos-1].isLetterOrNumber()){
00632 urlPos++;
00633 continue;
00634 }
00635
00636 QString anchor = "<a href=\"" + href + "\">" + href + "</a>";
00637 richText.replace( urlPos, urlLen, anchor );
00638
00639
00640 urlPos += anchor.length();
00641 }
00642 return richText;
00643 }
00644
00645 QString KStringHandler::obscure( const QString &str )
00646 {
00647 QString result;
00648 const QChar *unicode = str.unicode();
00649 for ( uint i = 0; i < str.length(); ++i )
00650 result += ( unicode[ i ].unicode() < 0x20 ) ? unicode[ i ] :
00651 QChar( 0x1001F - unicode[ i ].unicode() );
00652
00653 return result;
00654 }
00655
00656 bool KStringHandler::isUtf8(const char *buf)
00657 {
00658 int i, n;
00659 register unsigned char c;
00660 bool gotone = false;
00661
00662 #define F 0
00663 #define T 1
00664 #define I 2
00665 #define X 3
00666
00667 static const unsigned char text_chars[256] = {
00668
00669 F, F, F, F, F, F, F, T, T, T, T, F, T, T, F, F,
00670
00671 F, F, F, F, F, F, F, F, F, F, F, T, F, F, F, F,
00672 T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,
00673 T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,
00674 T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,
00675 T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,
00676 T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,
00677 T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, F,
00678
00679 X, X, X, X, X, T, X, X, X, X, X, X, X, X, X, X,
00680 X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
00681 I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I,
00682 I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I,
00683 I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I,
00684 I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I,
00685 I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I,
00686 I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I
00687 };
00688
00689
00690 for (i = 0; (c = buf[i]); i++) {
00691 if ((c & 0x80) == 0) {
00692
00693
00694
00695
00696
00697 if (text_chars[c] != T)
00698 return false;
00699
00700 } else if ((c & 0x40) == 0) {
00701 return false;
00702 } else {
00703 int following;
00704
00705 if ((c & 0x20) == 0) {
00706 following = 1;
00707 } else if ((c & 0x10) == 0) {
00708 following = 2;
00709 } else if ((c & 0x08) == 0) {
00710 following = 3;
00711 } else if ((c & 0x04) == 0) {
00712 following = 4;
00713 } else if ((c & 0x02) == 0) {
00714 following = 5;
00715 } else
00716 return false;
00717
00718 for (n = 0; n < following; n++) {
00719 i++;
00720 if (!(c = buf[i]))
00721 goto done;
00722
00723 if ((c & 0x80) == 0 || (c & 0x40))
00724 return false;
00725 }
00726 gotone = true;
00727 }
00728 }
00729 done:
00730 return gotone;
00731 }
00732
00733 #undef F
00734 #undef T
00735 #undef I
00736 #undef X
00737
00738 QString KStringHandler::from8Bit( const char *str )
00739 {
00740 if (!str)
00741 return QString::null;
00742 if (!*str) {
00743 static const QString &emptyString = KGlobal::staticQString("");
00744 return emptyString;
00745 }
00746 return KStringHandler::isUtf8( str ) ?
00747 QString::fromUtf8( str ) :
00748 QString::fromLocal8Bit( str );
00749 }