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