kstringhandler.cpp
/* This file is part of the KDE libraries
Copyright (C) 1999 Ian Zepp (icszepp@islc.net)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "kstringhandler.h"
#include "kglobal.h"
static void parsePythonRange( const QCString &range, uint &start, uint &end )
{
const int colon = range.find( ':' );
if ( colon == -1 ) {
start = range.toUInt();
end = start;
} else if ( colon == int( range.length() - 1 ) ) {
start = range.left( colon ).toUInt();
} else if ( colon == 0 ) {
end = range.mid( 1 ).toUInt();
} else {
start = range.left( colon ).toInt();
end = range.mid( colon + 1 ).toInt();
}
}
QString KStringHandler::word( const QString &text , uint pos )
{
return text.section( ' ', pos, pos );
}
QString KStringHandler::word( const QString &text , const char *range )
{
// Format in: START:END
// Note index starts a 0 (zero)
//
// 0: first word to end
// 1:3 second to fourth words
QStringList list = QStringList::split( " ", text , true );
QString tmp = "";
QString r = range;
if ( text.isEmpty() )
return tmp;
uint pos = 0, cnt = list.count();
parsePythonRange( range, pos, cnt );
//
// Extract words
//
int wordsToExtract = cnt-pos+1;
QStringList::Iterator it = list.at( pos);
while ( (it != list.end()) && (wordsToExtract-- > 0))
{
tmp += *it;
tmp += " ";
it++;
}
return tmp.stripWhiteSpace();
}
//
// Insertion and removal routines
//
QString KStringHandler::insword( const QString &text , const QString &word , uint pos )
{
if ( text.isEmpty() )
return word;
if ( word.isEmpty() )
return text;
// Split words and add into list
QStringList list = QStringList::split( " ", text, true );
if ( pos >= list.count() )
list.append( word );
else
list.insert( list.at(pos) , word );
// Rejoin
return list.join( " " );
}
QString KStringHandler::setword( const QString &text , const QString &word , uint pos )
{
if ( text.isEmpty() )
return word;
if ( word.isEmpty() )
return text;
// Split words and add into list
QStringList list = QStringList::split( " ", text, true );
if ( pos >= list.count() )
list.append( word );
else
{
list.insert( list.remove( list.at(pos) ) , word );
}
// Rejoin
return list.join( " " );
}
QString KStringHandler::remrange( const QString &text , const char *range )
{
// Format in: START:END
// Note index starts a 0 (zero)
//
// 0: first word to end
// 1:3 second to fourth words
QStringList list = QStringList::split( " ", text , true );
QString tmp = "";
QString r = range;
if ( text.isEmpty() )
return tmp;
uint pos = 0, cnt = list.count();
parsePythonRange( range, pos, cnt );
//
// Remove that range of words
//
int wordsToDelete = cnt-pos+1;
QStringList::Iterator it = list.at( pos);
while ( (it != list.end()) && (wordsToDelete-- > 0))
it = list.remove( it );
return list.join( " " );
}
QString KStringHandler::remword( const QString &text , uint pos )
{
QString tmp = "";
if ( text.isEmpty() )
return tmp;
// Split words and add into list
QStringList list = QStringList::split( " ", text, true );
if ( pos < list.count() )
list.remove( list.at( pos ) );
// Rejoin
return list.join( " " );
}
QString KStringHandler::remword( const QString &text , const QString &word )
{
QString tmp = "";
if ( text.isEmpty() )
return tmp;
if ( word.isEmpty() )
return text;
// Split words and add into list
QStringList list = QStringList::split( " ", text, true );
QStringList::Iterator it = list.find(word);
if (it != list.end())
list.remove( it );
// Rejoin
return list.join( " " );
}
//
// Capitalization routines
//
QString KStringHandler::capwords( const QString &text )
{
if ( text.isEmpty() ) {
return text;
}
const QString strippedText = text.stripWhiteSpace();
const QStringList words = capwords( QStringList::split( ' ', strippedText ) );
QString result = text;
result.replace( strippedText, words.join( " " ) );
return result;
}
QStringList KStringHandler::capwords( const QStringList &list )
{
QStringList tmp = list;
for ( QStringList::Iterator it = tmp.begin(); it != tmp.end(); ++it ) {
*it = ( *it )[ 0 ].upper() + ( *it ).mid( 1 );
}
return tmp;
}
//
// Reverse routines
//
QString KStringHandler::reverse( const QString &text )
{
QString tmp;
if ( text.isEmpty() )
return tmp;
QStringList list;
list = QStringList::split( " ", text, true );
list = reverse( list );
return list.join( " " );
}
QStringList KStringHandler::reverse( const QStringList &list )
{
QStringList tmp;
if ( list.count() == 0 )
return tmp;
for ( QStringList::ConstIterator it= list.begin();
it != list.end();
it++)
tmp.prepend( *it );
return tmp;
}
//
// Left, Right, Center justification
//
QString KStringHandler::ljust( const QString &text , uint width )
{
return text.stripWhiteSpace().leftJustify( width );
}
QString KStringHandler::rjust( const QString &text , uint width )
{
return text.stripWhiteSpace().rightJustify( width );
}
QString KStringHandler::center( const QString &text , uint width )
{
const QString s = text.stripWhiteSpace();
const unsigned int length = s.length();
if ( width <= length ) {
return s;
}
QString result;
result.fill( ' ', ( width - length ) / 2 );
result += s;
return result.leftJustify( width );
}
QString KStringHandler::lsqueeze( const QString & str, uint maxlen )
{
if (str.length() > maxlen) {
int part = maxlen-3;
return QString("..." + str.right(part));
}
else return str;
}
QString KStringHandler::csqueeze( const QString & str, uint maxlen )
{
if (str.length() > maxlen && maxlen > 3) {
int part = (maxlen-3)/2;
return QString(str.left(part) + "..." + str.right(part));
}
else return str;
}
QString KStringHandler::rsqueeze( const QString & str, uint maxlen )
{
if (str.length() > maxlen) {
int part = maxlen-3;
return QString(str.left(part) + "...");
}
else return str;
}
QString KStringHandler::lEmSqueeze(const QString &name, const QFontMetrics& fontMetrics, uint maxlen)
{
return lPixelSqueeze(name, fontMetrics, fontMetrics.maxWidth() * maxlen);
}
QString KStringHandler::lPixelSqueeze(const QString& name, const QFontMetrics& fontMetrics, uint maxPixels)
{
uint nameWidth = fontMetrics.width(name);
if (maxPixels < nameWidth)
{
QString tmp = name;
const uint em = fontMetrics.maxWidth();
maxPixels -= fontMetrics.width("...");
while (maxPixels < nameWidth && !tmp.isEmpty())
{
int delta = (nameWidth - maxPixels) / em;
delta = kClamp(delta, 1, delta); // no max
tmp.remove(0, delta);
nameWidth = fontMetrics.width(tmp);
}
return ("..." + tmp);
}
return name;
}
QString KStringHandler::cEmSqueeze(const QString& name, const QFontMetrics& fontMetrics, uint maxlen)
{
return cPixelSqueeze(name, fontMetrics, fontMetrics.maxWidth() * maxlen);
}
QString KStringHandler::cPixelSqueeze(const QString& s, const QFontMetrics& fm, uint width)
{
if ( s.isEmpty() || uint( fm.width( s ) ) <= width ) {
return s;
}
const unsigned int length = s.length();
if ( length == 2 ) {
return s;
}
const int maxWidth = width - fm.width( '.' ) * 3;
if ( maxWidth <= 0 ) {
return "...";
}
unsigned int leftIdx = 0, rightIdx = length;
unsigned int leftWidth = fm.charWidth( s, leftIdx++ );
unsigned int rightWidth = fm.charWidth( s, --rightIdx );
while ( leftWidth + rightWidth < uint( maxWidth ) ) {
while ( leftWidth <= rightWidth && leftWidth + rightWidth < uint( maxWidth ) ) {
leftWidth += fm.charWidth( s, leftIdx++ );
}
while ( rightWidth <= leftWidth && leftWidth + rightWidth < uint( maxWidth ) ) {
rightWidth += fm.charWidth( s, --rightIdx );
}
}
if ( leftWidth > rightWidth ) {
--leftIdx;
} else {
++rightIdx;
}
rightIdx = length - rightIdx;
if ( leftIdx == 0 && rightIdx == 1 || leftIdx == 1 && rightIdx == 0 ) {
return "...";
}
return s.left( leftIdx ) + "..." + s.right( rightIdx );
}
QString KStringHandler::rEmSqueeze(const QString& name, const QFontMetrics& fontMetrics, uint maxlen)
{
return rPixelSqueeze(name, fontMetrics, fontMetrics.maxWidth() * maxlen);
}
QString KStringHandler::rPixelSqueeze(const QString& name, const QFontMetrics& fontMetrics, uint maxPixels)
{
uint nameWidth = fontMetrics.width(name);
if (maxPixels < nameWidth)
{
QString tmp = name;
const uint em = fontMetrics.maxWidth();
maxPixels -= fontMetrics.width("...");
while (maxPixels < nameWidth && !tmp.isEmpty())
{
int length = tmp.length();
int delta = em ? (nameWidth - maxPixels) / em : length;
delta = kClamp(delta, 1, length) ;
tmp.remove(length - delta, delta);
nameWidth = fontMetrics.width(tmp);
}
return (tmp + "...");
}
return name;
}
bool KStringHandler::matchFileName( const QString& filename, const QString& pattern )
{
int len = filename.length();
int pattern_len = pattern.length();
if (!pattern_len)
return false;
// Patterns like "Makefile*"
if ( pattern[ pattern_len - 1 ] == '*' && len + 1 >= pattern_len ) {
if ( pattern[ 0 ] == '*' )
{
return filename.find(pattern.mid(1, pattern_len - 2)) != -1;
}
const QChar *c1 = pattern.unicode();
const QChar *c2 = filename.unicode();
int cnt = 1;
while ( cnt < pattern_len && *c1++ == *c2++ )
++cnt;
return cnt == pattern_len;
}
// Patterns like "*~", "*.extension"
if ( pattern[ 0 ] == '*' && len + 1 >= pattern_len )
{
const QChar *c1 = pattern.unicode() + pattern_len - 1;
const QChar *c2 = filename.unicode() + len - 1;
int cnt = 1;
while ( cnt < pattern_len && *c1-- == *c2-- )
++cnt;
return cnt == pattern_len;
}
// Patterns like "Makefile"
return ( filename == pattern );
}
QStringList
KStringHandler::perlSplit(const QString & sep, const QString & s, uint max)
{
bool ignoreMax = 0 == max;
QStringList l;
int searchStart = 0;
int tokenStart = s.find(sep, searchStart);
while (-1 != tokenStart && (ignoreMax || l.count() < max - 1))
{
if (!s.mid(searchStart, tokenStart - searchStart).isEmpty())
l << s.mid(searchStart, tokenStart - searchStart);
searchStart = tokenStart + sep.length();
tokenStart = s.find(sep, searchStart);
}
if (!s.mid(searchStart, s.length() - searchStart).isEmpty())
l << s.mid(searchStart, s.length() - searchStart);
return l;
}
QStringList
KStringHandler::perlSplit(const QChar & sep, const QString & s, uint max)
{
bool ignoreMax = 0 == max;
QStringList l;
int searchStart = 0;
int tokenStart = s.find(sep, searchStart);
while (-1 != tokenStart && (ignoreMax || l.count() < max - 1))
{
if (!s.mid(searchStart, tokenStart - searchStart).isEmpty())
l << s.mid(searchStart, tokenStart - searchStart);
searchStart = tokenStart + 1;
tokenStart = s.find(sep, searchStart);
}
if (!s.mid(searchStart, s.length() - searchStart).isEmpty())
l << s.mid(searchStart, s.length() - searchStart);
return l;
}
QStringList
KStringHandler::perlSplit(const QRegExp & sep, const QString & s, uint max)
{
bool ignoreMax = 0 == max;
QStringList l;
int searchStart = 0;
int tokenStart = sep.search(s, searchStart);
int len = sep.matchedLength();
while (-1 != tokenStart && (ignoreMax || l.count() < max - 1))
{
if (!s.mid(searchStart, tokenStart - searchStart).isEmpty())
l << s.mid(searchStart, tokenStart - searchStart);
searchStart = tokenStart + len;
tokenStart = sep.search(s, searchStart);
len = sep.matchedLength();
}
if (!s.mid(searchStart, s.length() - searchStart).isEmpty())
l << s.mid(searchStart, s.length() - searchStart);
return l;
}
QString
KStringHandler::tagURLs( const QString& text )
{
/*static*/ QRegExp urlEx("(www\\.(?!\\.)|(fish|(f|ht)tp(|s))://)[\\d\\w\\./,:_~\\?=&;#@\\-\\+\\%\\$]+[\\d\\w/]");
QString richText( text );
int urlPos = 0, urlLen;
while ((urlPos = urlEx.search(richText, urlPos)) >= 0)
{
urlLen = urlEx.matchedLength();
QString href = richText.mid( urlPos, urlLen );
// Qt doesn't support (?<=pattern) so we do it here
if((urlPos > 0) && richText[urlPos-1].isLetterOrNumber()){
urlPos++;
continue;
}
// Don't use QString::arg since %01, %20, etc could be in the string
QString anchor = "<a href=\"" + href + "\">" + href + "</a>";
richText.replace( urlPos, urlLen, anchor );
urlPos += anchor.length();
}
return richText;
}
QString KStringHandler::obscure( const QString &str )
{
QString result;
const QChar *unicode = str.unicode();
for ( uint i = 0; i < str.length(); ++i )
result += ( unicode[ i ].unicode() < 0x21 ) ? unicode[ i ] :
QChar( 0x1001F - unicode[ i ].unicode() );
return result;
}
bool KStringHandler::isUtf8(const char *buf)
{
int i, n;
register unsigned char c;
bool gotone = false;
if (!buf)
return true; // whatever, just don't crash
#define F 0 /* character never appears in text */
#define T 1 /* character appears in plain ASCII text */
#define I 2 /* character appears in ISO-8859 text */
#define X 3 /* character appears in non-ISO extended ASCII (Mac, IBM PC) */
static const unsigned char text_chars[256] = {
/* BEL BS HT LF FF CR */
F, F, F, F, F, F, F, T, T, T, T, F, T, T, F, F, /* 0x0X */
/* ESC */
F, F, F, F, F, F, F, F, F, F, F, T, F, F, F, F, /* 0x1X */
T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x2X */
T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x3X */
T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x4X */
T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x5X */
T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x6X */
T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, F, /* 0x7X */
/* NEL */
X, X, X, X, X, T, X, X, X, X, X, X, X, X, X, X, /* 0x8X */
X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, /* 0x9X */
I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xaX */
I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xbX */
I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xcX */
I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xdX */
I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xeX */
I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I /* 0xfX */
};
/* *ulen = 0; */
for (i = 0; (c = buf[i]); i++) {
if ((c & 0x80) == 0) { /* 0xxxxxxx is plain ASCII */
/*
* Even if the whole file is valid UTF-8 sequences,
* still reject it if it uses weird control characters.
*/
if (text_chars[c] != T)
return false;
} else if ((c & 0x40) == 0) { /* 10xxxxxx never 1st byte */
return false;
} else { /* 11xxxxxx begins UTF-8 */
int following;
if ((c & 0x20) == 0) { /* 110xxxxx */
following = 1;
} else if ((c & 0x10) == 0) { /* 1110xxxx */
following = 2;
} else if ((c & 0x08) == 0) { /* 11110xxx */
following = 3;
} else if ((c & 0x04) == 0) { /* 111110xx */
following = 4;
} else if ((c & 0x02) == 0) { /* 1111110x */
following = 5;
} else
return false;
for (n = 0; n < following; n++) {
i++;
if (!(c = buf[i]))
goto done;
if ((c & 0x80) == 0 || (c & 0x40))
return false;
}
gotone = true;
}
}
done:
return gotone; /* don't claim it's UTF-8 if it's all 7-bit */
}
#undef F
#undef T
#undef I
#undef X
QString KStringHandler::from8Bit( const char *str )
{
if (!str)
return QString::null;
if (!*str) {
static const QString &emptyString = KGlobal::staticQString("");
return emptyString;
}
return KStringHandler::isUtf8( str ) ?
QString::fromUtf8( str ) :
QString::fromLocal8Bit( str );
}
KStringHandler::remrange
static QString remrange(const QString &text, const char *range)
Removes a word or ranges of words from the string, and returns a new string.
Definition: kstringhandler.cpp:122
KStringHandler::ljust
static QString ljust(const QString &text, uint width) KDE_DEPRECATED
Left-justifies a string and returns a string at least 'width' characters wide.
Definition: kstringhandler.cpp:251
KStringHandler::obscure
static QString obscure(const QString &str)
Obscure string by using a simple symmetric encryption.
Definition: kstringhandler.cpp:556
KStringHandler::remword
static QString remword(const QString &text, uint pos)
Removes a word at the given index, and returns a new string.
Definition: kstringhandler.cpp:151
KStringHandler::lPixelSqueeze
static QString lPixelSqueeze(const QString &name, const QFontMetrics &fontMetrics, uint maxPixels)
Substitute characters at the beginning of a string by "...".
Definition: kstringhandler.cpp:308
KGlobal::staticQString
static const QString & staticQString(const char *str)
Creates a static QString.
Definition: kglobal.cpp:128
KStringHandler::matchFileName
static bool matchFileName(const QString &filename, const QString &pattern)
Match a filename.
Definition: kstringhandler.cpp:413
KStringHandler::rsqueeze
static QString rsqueeze(const QString &str, uint maxlen=40)
Substitute characters at the end of a string by "...".
Definition: kstringhandler.cpp:294
KStringHandler::tagURLs
static QString tagURLs(const QString &text)
This method auto-detects URLs in strings, and adds HTML markup to them so that richtext or HTML-enabl...
Definition: kstringhandler.cpp:531
KStringHandler::insword
static QString insword(const QString &text, const QString &word, uint pos)
Inserts a word into the string, and returns a new string with the word included.
Definition: kstringhandler.cpp:80
KStringHandler::center
static QString center(const QString &text, uint width)
Centers a string and returns a string at least 'width' characters wide.
Definition: kstringhandler.cpp:261
KStringHandler::csqueeze
static QString csqueeze(const QString &str, uint maxlen=40)
Substitute characters at the middle of a string by "...".
Definition: kstringhandler.cpp:285
KStringHandler::capwords
static QString capwords(const QString &text)
Capitalizes each word in the string "hello there" becomes "Hello There" (string)
Definition: kstringhandler.cpp:193
KStringHandler::lsqueeze
static QString lsqueeze(const QString &str, uint maxlen=40)
Substitute characters at the beginning of a string by "...".
Definition: kstringhandler.cpp:276
KStringHandler::cPixelSqueeze
static QString cPixelSqueeze(const QString &name, const QFontMetrics &fontMetrics, uint maxPixels)
Substitute characters in the middle of a string by "...".
Definition: kstringhandler.cpp:338
KStringHandler::lEmSqueeze
static QString lEmSqueeze(const QString &name, const QFontMetrics &fontMetrics, uint maxlen=30)
Substitute characters at the beginning of a string by "...".
Definition: kstringhandler.cpp:303
KStringHandler::setword
static QString setword(const QString &text, const QString &word, uint pos)
Replaces a word in the string, and returns a new string with the word included.
Definition: kstringhandler.cpp:100
KStringHandler::reverse
static QString reverse(const QString &text)
Reverses the order of the words in a string "hello there" becomes "there hello" (string) ...
Definition: kstringhandler.cpp:219
KStringHandler::rjust
static QString rjust(const QString &text, uint width) KDE_DEPRECATED
Right-justifies a string and returns a string at least 'width' characters wide.
Definition: kstringhandler.cpp:256
KStringHandler::word
static QString word(const QString &text, uint pos) KDE_DEPRECATED
Returns the nth word in the string if found Returns a EMPTY (not null) string otherwise.
Definition: kstringhandler.cpp:39
KStringHandler::cEmSqueeze
static QString cEmSqueeze(const QString &name, const QFontMetrics &fontMetrics, uint maxlen=30)
Substitute characters in the middle of a string by "...".
Definition: kstringhandler.cpp:333
KStringHandler::rPixelSqueeze
static QString rPixelSqueeze(const QString &name, const QFontMetrics &fontMetrics, uint maxPixels)
Substitute characters at the end of a string by "...".
Definition: kstringhandler.cpp:385
KStringHandler::isUtf8
static bool isUtf8(const char *str)
Guess whether a string is UTF8 encoded.
Definition: kstringhandler.cpp:567
KStringHandler::rEmSqueeze
static QString rEmSqueeze(const QString &name, const QFontMetrics &fontMetrics, uint maxlen=30)
Substitute characters at the end of a string by "...".
Definition: kstringhandler.cpp:380
KStringHandler::from8Bit
static QString from8Bit(const char *str)
Construct QString from a c string, guessing whether it is UTF8- or Local8Bit-encoded.
Definition: kstringhandler.cpp:652
KStringHandler::perlSplit
static QStringList perlSplit(const QString &sep, const QString &s, uint max=0)
Split a QString into a QStringList in a similar fashion to the static QStringList function in Qt...
Definition: kstringhandler.cpp:452

KDE Home | KDE Accessibility Home | Description of Access Keys