41#include <QtCore/QMutableStringListIterator>
42#include <QtCore/QRegExp>
43#include <QtCore/QMimeData>
44#include <QtCore/QTextCodec>
47static int kurlDebugArea() {
static int s_area =
KDebug::registerArea(
"kdecore (KUrl)");
return s_area; }
55 if (QFileInfo(_path).isRelative())
60 int len = path.length();
65 if (path.indexOf(encodedDot, 0, Qt::CaseInsensitive) != -1)
68 path.replace(encodedDot,
QString(QLatin1Char(
'.')));
69 path.replace(encodedDOT,
QString(QLatin1Char(
'.')));
74 const bool slash = (len && path[len-1] == QLatin1Char(
'/')) ||
75 (len > 1 && path[len-2] == QLatin1Char(
'/') && path[len-1] == QLatin1Char(
'.'));
84 int cdUp, orig_pos, pos;
88 while ( pos && (pos = path.lastIndexOf(QLatin1Char(
'/'),--pos)) != -1 )
90 len = orig_pos - pos - 1;
91 if ( len == 2 && path[pos+1] == QLatin1Char(
'.') && path[pos+2] == QLatin1Char(
'.') )
97 if ( (len || !cleanDirSeparator) &&
98 (len != 1 || path[pos+1] != QLatin1Char(
'.') ) )
101 result.prepend(path.mid(pos, len+1));
110 if (orig_pos >= 2 && path[0].isLetter() && path[1] == QLatin1Char(
':') ) {
111 result.prepend(
QString(path[0]) + QLatin1Char(
':') );
115 if ( result.isEmpty() )
116 result = QLatin1Char(
'/');
117 else if ( slash && result[result.length()-1] != QLatin1Char(
'/') )
118 result.append(QLatin1Char(
'/'));
126#define IS_DRIVE_OR_DOUBLESLASH(isletter, char1, char2, colon, slash) \
127 ((isletter && char2 == colon) || (char1 == slash && char2 == slash))
135 const int len = str.length();
136 if (str[0]==QLatin1Char(
'f')) {
137 if ( len > 10 && str.startsWith( QLatin1String(
"file:///" ) )
139 return QUrl::fromPercentEncoding( str.toLatin1() ).mid(8);
140 else if ( len > 9 && str.startsWith( QLatin1String(
"file://" ) )
142 return QUrl::fromPercentEncoding( str.toLatin1() ).mid(7);
143 else if ( len > 8 && str.startsWith( QLatin1String(
"file:/" ) )
145 return QUrl::fromPercentEncoding( str.toLatin1() ).mid(6);
150 if ( len > 2 && str[0] == QLatin1Char(
'/')
154 else if ( len >= 2 &&
IS_DRIVE_OR_DOUBLESLASH(str[0].isLetter(), str[0], str[1], QLatin1Char(
':'), QLatin1Char(
'/')) )
162 int len = _url.length();
163 if (!len)
return true;
164 const QChar *str = _url.unicode();
167 if (!
isalpha(str[0].toLatin1()))
170 for(
int i = 1; i < len; i++)
172 char c = str[i].toLatin1();
177 if (!
isalpha(c) && !
isdigit(c) && (c !=
'+') && (c !=
'-') && (c !=
'.'))
196 foreach(
const QUrl&
url, list) {
203 for (QStringList::ConstIterator it = list.begin();
219 for(KUrl::List::ConstIterator it = constBegin();
220 it != constEnd(); ++it) {
221 lst.append(it->url(trailing));
229 KUrl::List::ConstIterator uit = urls.constBegin();
230 const KUrl::List::ConstIterator uEnd = urls.constEnd();
231 for (; uit != uEnd ; ++uit) {
234 urlStringList.append((*uit).toMimeDataString().toLatin1());
238 for (
int i = 0, n = urlStringList.count(); i < n; ++i) {
252 mimeData->setData(QString::fromLatin1(
"text/uri-list"),
uriListData(*
this));
257 KUrl::List::ConstIterator uit = constBegin();
258 const KUrl::List::ConstIterator uEnd = constEnd();
259 for ( ; uit != uEnd ; ++uit ) {
260 QString prettyURL = (*uit).prettyUrl();
261 if ( (*uit).protocol() == QLatin1String(
"mailto") ) {
262 prettyURL = (*uit).path();
264 prettyURLsList.append( prettyURL );
267 QByteArray plainTextData = prettyURLsList.join(
QString(QLatin1Char(
'\n'))).toLocal8Bit();
269 plainTextData.append(
"\n" );
270 mimeData->setData( QString::fromLatin1(
"text/plain"), plainTextData );
273 if ( !metaData.isEmpty() )
275 QByteArray metaDataData;
276 for( KUrl::MetaDataMap::const_iterator it = metaData.begin(); it != metaData.end(); ++it )
278 metaDataData += it.key().toUtf8();
279 metaDataData +=
"$@@$";
280 metaDataData += it.value().toUtf8();
281 metaDataData +=
"$@@$";
283 mimeData->setData( QString::fromLatin1(
"application/x-kio-metadata"), metaDataData );
301 return mimeData->hasFormat(QString::fromLatin1(
"text/uri-list")) ||
318 const char* secondMimeType =
"text/uri-list";
319 if (decodeOptions == PreferLocalUrls) {
320 qSwap(firstMimeType, secondMimeType);
322 QByteArray payload = mimeData->data(QString::fromLatin1(firstMimeType));
323 if (payload.isEmpty())
324 payload = mimeData->data(QString::fromLatin1(secondMimeType));
325 if ( !payload.isEmpty() ) {
327 const char* d = payload.constData();
328 while ( c < payload.size() && d[c] ) {
331 while (c < payload.size() && d[c] && d[c]!=
'\r'
334 QByteArray s( d+f, c-f );
338 while ( c < payload.size() && d[c] &&
339 ( d[c] ==
'\n' || d[c] ==
'\r' ) )
345 const QByteArray metaDataPayload = mimeData->data(QLatin1String(
"application/x-kio-metadata"));
346 if ( !metaDataPayload.isEmpty() )
348 QString str = QString::fromUtf8( metaDataPayload );
349 Q_ASSERT(str.endsWith(QLatin1String(
"$@@$")));
350 str.truncate( str.length() - 4 );
351 const QStringList lst = str.split(QLatin1String(
"$@@$"));
352 QStringList::ConstIterator it = lst.begin();
353 bool readingKey =
true;
355 for ( ; it != lst.end(); ++it ) {
359 metaData->insert( key, *it );
360 readingKey = !readingKey;
362 Q_ASSERT( readingKey );
371 return fromMimeData(mimeData, PreferKdeUrls, metaData);
376 return qVariantFromValue(*
this);
382 foreach(
const KUrl&
url, *
this) {
403 if ( !str.isEmpty() ) {
406 kDebug(kurlDebugArea()) <<
"KUrl::KUrl ( const QString &str = " << str.toLatin1().data() <<
" )";
411 if (!str.startsWith(QLatin1String(
"file://")))
413 if ( !pathToSet.isEmpty() ) {
416 int index = pathToSet.lastIndexOf(QLatin1Char(
'?'));
420 setPath( pathToSet.left( index ) );
421 _setQuery( pathToSet.mid( index + 1 ) );
426 if ( str[0] == QLatin1Char(
'/') || str[0] == QLatin1Char(
'~') )
429 _setEncodedUrl( str.toUtf8() );
439 #define IS_LETTER(c) \
440 ((c >= QLatin1Char('A') && c <= QLatin1Char('Z')) || (c >= QLatin1Char('a') && c <= QLatin1Char('z')))
443 #define IS_SLASH_AND_DRIVE_OR_DOUBLESLASH_0 \
444 ( QLatin1Char(str[0]) == QLatin1Char('/') && IS_DRIVE_OR_DOUBLESLASH(IS_LETTER(QLatin1Char(str[1])), QLatin1Char(str[1]), QLatin1Char(str[2]), QLatin1Char(':'), QLatin1Char('/')) )
447 #define IS_DRIVE_OR_DOUBLESLASH_0 \
448 ( IS_DRIVE_OR_DOUBLESLASH(IS_LETTER(QLatin1Char(str[0])), QLatin1Char(str[0]), QLatin1Char(str[1]), QLatin1Char(':'), QLatin1Char('/')) )
450#if defined(DEBUG_KURL)
451 kDebug(kurlDebugArea()) <<
"KUrl::KUrl " <<
" " << str;
453 if ( str && str[0] && str[1] && str[2] ) {
455 setPath( QString::fromUtf8( str+1 ) );
457 setPath( QString::fromUtf8( str ) );
460 if ( str && str[0] ) {
461 if ( str[0] ==
'/' || str[0] ==
'~' )
462 setPath( QString::fromUtf8( str ) );
464 _setEncodedUrl( str );
471 if ( !str.isEmpty() ) {
474 kDebug(kurlDebugArea()) <<
"KUrl::KUrl " <<
" " << str.data();
477 setPath( QString::fromUtf8( str.mid( 1 ) ) );
479 setPath( QString::fromUtf8( str ) );
481 if ( str[0] ==
'/' || str[0] ==
'~' )
482 setPath( QString::fromUtf8( str ) );
485 _setEncodedUrl( str );
492#if defined(Q_WS_WIN) && defined(DEBUG_KURL)
493 kDebug(kurlDebugArea()) <<
"KUrl::KUrl(KUrl) " <<
" path " << _u.
path() <<
" toLocalFile " << _u.
toLocalFile();
500#if defined(Q_WS_WIN) && defined(DEBUG_KURL)
501 kDebug(kurlDebugArea()) <<
"KUrl::KUrl(Qurl) " <<
" path " << u.path() <<
" toLocalFile " << u.toLocalFile();
508#if defined(Q_WS_WIN) && defined(DEBUG_KURL)
509 kDebug(kurlDebugArea()) <<
"KUrl::KUrl(KUrl,QString rel_url) " <<
" path " << _u.
path() <<
" toLocalFile " << _u.
toLocalFile();
515 KUrl u(lst.last(), _rel_url);
516 lst.erase( --lst.end() );
527 const int len = _u.scheme().length();
528 if ( !_u.host().isEmpty() && !rUrl.isEmpty() &&
529 rUrl.indexOf( _u.scheme(), 0, Qt::CaseInsensitive ) == 0 &&
530 rUrl[len] == QLatin1Char(
':') && (rUrl[len+1] != QLatin1Char(
'/') ||
531 (rUrl[len+1] == QLatin1Char(
'/') && rUrl[len+2] != QLatin1Char(
'/'))) )
533 rUrl.remove( 0, rUrl.indexOf( QLatin1Char(
':') ) + 1 );
537 if ( rUrl.isEmpty() )
541 else if ( rUrl[0] == QLatin1Char(
'#') )
544 QByteArray strRef_encoded = rUrl.mid(1).toLatin1();
545 if ( strRef_encoded.isNull() )
546 setFragment(QString::fromLatin1(
""));
548 setFragment(QUrl::fromPercentEncoding(strRef_encoded));
554 setEncodedQuery( QByteArray() );
556 if ( rUrl[0] == QLatin1Char(
'/') )
558 if ((rUrl.length() > 1) && (rUrl[1] == QLatin1Char(
'/')))
568 else if ( rUrl[0] != QLatin1Char(
'?') )
570 const int pos = strPath.lastIndexOf( QLatin1Char(
'/') );
572 strPath.truncate(pos);
573 strPath += QLatin1Char(
'/');
577 if ( strPath.isEmpty() )
578 strPath = QLatin1Char(
'/');
589 const KUrl tmp( rUrl );
593 if (!_u.userInfo().isEmpty() && userInfo().isEmpty()
594 && (_u.host() == host()) && (_u.scheme() == scheme()))
596 setUserInfo( _u.userInfo() );
604 QUrl::operator=( _u );
610 return QUrl::operator==( _u );
616 return ( *
this == u );
621 return qVariantFromValue(*
this);
624#ifndef KDE_NO_DEPRECATED
633 if ( !isValid() || !_u.isValid() )
642 if (path1 == QLatin1String(
"/"))
644 if (path2 == QLatin1String(
"/"))
651 if ( !bLocal1 && bLocal2 || bLocal1 && !bLocal2 )
654 if ( bLocal1 && bLocal2 && 0 != QString::compare( path1, path2, Qt::CaseInsensitive ) )
657 if ( path1 != path2 )
660 if ( scheme() == _u.scheme() &&
661 authority() == _u.authority() &&
662 encodedQuery() == _u.encodedQuery() &&
663 (fragment() == _u.fragment() || options & CompareWithoutFragment ) )
669 return ( *
this == _u );
674 return scheme().toLower();
694 return !userName().isEmpty();
709 return !password().isEmpty();
714 return !host().isEmpty();
719 return !
path().isEmpty();
733 while( i < _txt.length() && _txt[i] == QLatin1Char(
'/') )
735 QString tmp = i ? _txt.mid( i ) : _txt;
738 if ( path.isEmpty() )
740 path =
isLocalFile() ? QDir::rootPath() : QLatin1String(
"/");
742 path = QDir::rootPath();
746 int lastSlash = path.lastIndexOf( QLatin1Char(
'/') );
747 if ( lastSlash == -1)
749 else if ( !path.endsWith( QLatin1Char(
'/') ) )
750 path.truncate( lastSlash+1 );
763 if (
path() != newPath )
779 int len = result.length();
780 if ((len > 0) && (result[ len - 1 ] != QLatin1Char(
'/')))
781 result += QLatin1Char(
'/');
786 if ( result == QLatin1String(
"/") )
788 int len = result.length();
789 while (len > 1 && result[ len - 1 ] == QLatin1Char(
'/'))
793 result.truncate( len );
805 if (!m_strPath_encoded.isEmpty())
807 m_strPath_encoded =
trailingSlash( _trailing, m_strPath_encoded );
811 if (
path() != newPath )
824 encodedPath = QString::fromLatin1(QUrl::toPercentEncoding(encodedPath,
"!$&'()*+,;=:@/"));
826 encodedPath =
trailingSlash(trailing, QString::fromLatin1(QUrl::encodedPath()));
829 encodedPath =
trailingSlash(trailing, QString::fromLatin1(QUrl::encodedPath()));
833 encodedPath.append(QLatin1Char(
'/'));
837 return encodedPath + QLatin1Char(
'?') + QString::fromLatin1(encodedQuery());
844void KUrl::setEncodedPath(
const QString& _txt,
int encoding_hint )
846 m_strPath_encoded = _txt;
848 decode( m_strPath_encoded, m_strPath, m_strPath_encoded, encoding_hint );
850 if (m_strProtocol ==
"file")
851 m_strPath_encoded.clear();
853 if ( m_iUriMode == Auto )
860 const int pos = _txt.indexOf(QLatin1Char(
'?'));
863 setPath( QUrl::fromPercentEncoding( _txt.toLatin1() ) );
864 setEncodedQuery( QByteArray() );
868 setPath( QUrl::fromPercentEncoding(_txt.toLatin1().left(pos)) );
869 _setQuery( _txt.right( _txt.length() - pos - 1 ) );
877 kWarning() << (
isLocalFile() ?
"converted to local file - the related call should be converted to toLocalFile()" :
"") << QUrl::path();
888 KUrl urlWithoutHost(*
this);
889 urlWithoutHost.setHost(
QString());
893#warning FIXME: Remove #ifdef below once upstream bug, QTBUG-20322, is fixed. Also see BR# 194746.
907 if ( url.scheme().compare(QLatin1String(
"file"), Qt::CaseInsensitive) != 0 ||
hasSubUrl( url ) )
910 if (url.host().isEmpty() || (url.host() == QLatin1String(
"localhost")))
913 char hostname[ 256 ];
914 hostname[ 0 ] =
'\0';
915 if (!gethostname( hostname, 255 ))
916 hostname[
sizeof(hostname)-1] =
'\0';
918 for(
char *p = hostname; *p; p++)
921 return (url.host() == QString::fromLatin1( hostname ));
926 return ::isLocalFile( *
this );
936 if (!q.isEmpty() && q[0] == QLatin1Char(
'?'))
939 QStringList args = q.split(QLatin1Char(
'&'), QString::SkipEmptyParts);
940 for(QStringList::Iterator it = args.begin();
943 QString s = QUrl::fromPercentEncoding( (*it).toLatin1() );
944 if (s.startsWith(QLatin1String(
"charset=")))
949 if (!encoding.isEmpty())
950 args.append(QLatin1String(
"charset=") + QString::fromLatin1(QUrl::toPercentEncoding(encoding)));
955 _setQuery(args.join(
QString(QLatin1Char(
'&'))));
968 if (q[0] == QLatin1Char(
'?'))
971 const QStringList args = q.split(QLatin1Char(
'&'), QString::SkipEmptyParts);
972 for(QStringList::ConstIterator it = args.begin();
976 QString s = QUrl::fromPercentEncoding((*it).toLatin1());
977 if (s.startsWith(QLatin1String(
"charset=")))
987 const QString scheme = url.scheme();
988 if ( scheme.isEmpty() )
990 const QString ref( url.fragment() );
993 switch ( ref.at(0).unicode() ) {
995 if ( ref.startsWith(QLatin1String(
"gzip:")) )
999 if ( ref.startsWith(QLatin1String(
"bzip:")) || ref.startsWith(QLatin1String(
"bzip2:")) )
1003 if ( ref.startsWith(QLatin1String(
"lzma:")) )
1007 if ( ref.startsWith(QLatin1String(
"xz:")) )
1011 if ( ref.startsWith(QLatin1String(
"tar:")) )
1015 if ( ref.startsWith(QLatin1String(
"ar:")) )
1019 if ( ref.startsWith(QLatin1String(
"zip:")) )
1025 if ( scheme == QLatin1String(
"error") )
1032 return ::hasSubUrl( *
this );
1037 if (QString::compare(scheme(), QLatin1String(
"mailto"), Qt::CaseInsensitive) == 0) {
1045 QUrl newUrl( *
this );
1046 newUrl.setPath(
path() + QLatin1Char(
'/') );
1047 return QString::fromLatin1(newUrl.toEncoded());
1051 if (cleanedPath == QLatin1String(
"/")) {
1052 if (
path() != QLatin1String(
"/")) {
1053 QUrl fixedUrl = *
this;
1054 fixedUrl.setPath(cleanedPath);
1055 return QLatin1String(fixedUrl.toEncoded(None));
1057 return QLatin1String(toEncoded(None));
1060 return QString::fromLatin1(toEncoded(trailing ==
RemoveTrailingSlash ? StripTrailingSlash : None));
1066 result.reserve(input.length());
1067 for (
int i = 0; i < input.length(); ++i) {
1068 const QChar c = input.at(i);
1069 register ushort u = c.unicode();
1071 || (!forFragment && u ==
'?')
1072 || u ==
'#' || u ==
'%'
1073 || (u ==
' ' && (i+1 == input.length() || input.at(i+1).unicode() ==
' '))) {
1074 static const char hexdigits[] =
"0123456789ABCDEF";
1075 result += QLatin1Char(
'%');
1076 result += QLatin1Char(hexdigits[(u & 0xf0) >> 4]);
1077 result += QLatin1Char(hexdigits[u & 0xf]);
1098 if (!result.isEmpty())
1100 if (!authority().isEmpty() || result == QLatin1String(
"file") || (
path().isEmpty()
1101 && scheme().compare(QLatin1String(
"mailto"), Qt::CaseInsensitive) != 0))
1102 result += QLatin1String(
"://");
1104 result += QLatin1Char(
':');
1108 if (!tmp.isEmpty()) {
1109 result += QString::fromLatin1(QUrl::toPercentEncoding(tmp));
1110 result += QLatin1Char(
'@');
1115 if (tmp.contains(QLatin1Char(
':')))
1116 result += QLatin1Char(
'[') + tmp + QLatin1Char(
']');
1121 result += QLatin1Char(
':');
1122 result += QString::number(port());
1128 tmp.prepend(QLatin1Char(
'/'));
1134 result += QLatin1Char(
'/');
1135 else if (trailing ==
RemoveTrailingSlash && tmp.length() > 1 && tmp.endsWith(QLatin1Char(
'/')))
1139 result += QLatin1Char(
'?');
1140 result += QString::fromLatin1(encodedQuery());
1143 if (hasFragment()) {
1144 result += QLatin1Char(
'#');
1154 QString u = prettyUrl(_trailing);
1155 if (_flags & StripFileProtocol && u.startsWith(
"file://")) {
1158 return QDir::convertSeparators(u);
1172 if (
isLocalFile() && fragment().isNull() && encodedQuery().isNull() ) {
1191 if( !s.startsWith( QLatin1String (
"file://" ) ))
1194 if ( gethostname( hostname, 255 ) == 0 )
1196 hostname[256] =
'\0';
1197 return QString(
"file://" ) + hostname + s.mid( 5 );
1204 KUrl safeUrl(*
this);
1205 safeUrl.setPassword(
QString());
1206 return safeUrl.
url();
1213 if ( str.startsWith(
"file:" ) )
1233 url =
KUrl(url.fragment());
1237 ref = url.fragment();
1238 hasRef = url.hasFragment();
1246 KUrl::List::Iterator it;
1247 for( it = lst.begin() ; it != lst.end(); ++it )
1249 (*it).setFragment( ref );
1263 if (lst.isEmpty())
return KUrl();
1267 QListIterator<KUrl> it(lst);
1269 while (it.hasPrevious())
1271 KUrl u(it.previous());
1273 u.setEncodedFragment(tmp.
url().toLatin1() );
1285 Q_ASSERT( options != 0 );
1289 return list.last().fileName(options);
1293 int len = path.length();
1299 while ( len >= 1 && path[ len - 1 ] == QLatin1Char(
'/') )
1302 else if ( path[ len - 1 ] == QLatin1Char(
'/') )
1306 if ( len == 1 && path[ 0 ] == QLatin1Char(
'/') )
1312 if (!m_strPath_encoded.isEmpty())
1317 int i = m_strPath_encoded.lastIndexOf( QLatin1Char(
'/'), len - 1 );
1318 QString fileName_encoded = m_strPath_encoded.mid(i+1);
1319 n += fileName_encoded.count(
"%2f", Qt::CaseInsensitive);
1324 i = path.lastIndexOf( QLatin1Char(
'/'), i - 1 );
1326 while (--n && (i > 0));
1331 if ( len == (
int)path.length() )
1335 fname = path.left( len );
1339 fname = path.mid( i + 1, len - i - 1 );
1349 KUrl &u = lst.last();
1351 *
this =
join( lst );
1357 if ( _txt.isEmpty() )
1362 int len = strPath.length();
1364 if ( _txt[0] != QLatin1Char(
'/') && ( len == 0 || strPath[ len - 1 ] != QLatin1Char(
'/') ) )
1365 strPath += QLatin1Char(
'/');
1369 const int _txtlen = _txt.length();
1370 if ( strPath.endsWith( QLatin1Char(
'/') ) )
1372 while ( ( i < _txtlen ) && ( _txt[i] == QLatin1Char(
'/') ) )
1376 setPath( strPath + _txt.mid( i ) );
1382 Q_ASSERT( options != 0 );
1387 if ( result.isEmpty() || result == QLatin1String (
"/" ) )
1390 int i = result.lastIndexOf( QLatin1Char(
'/') );
1398 return QString(QLatin1Char(
'/'));
1402 if ( i == 2 && result[1] == QLatin1Char(
':') )
1404 return result.left(3);
1409 result = result.left( i + 1 );
1411 result = result.left( i );
1422 if ( _dir.isEmpty() || !isValid() )
1428 KUrl &u = lst.last();
1430 *
this =
join( lst );
1436 if ( !QFileInfo(_dir).isRelative() )
1438 if ( _dir[0] == QLatin1Char(
'/') )
1444 setEncodedQuery( QByteArray() );
1449 if (_dir[0] == QLatin1Char(
'~') && scheme() == QLatin1String (
"file"))
1452 QString strPath = QDir::homePath();
1453 strPath += QLatin1Char(
'/');
1454 strPath += _dir.right( strPath.length() - 1 );
1457 setEncodedQuery( QByteArray() );
1472 setEncodedQuery( QByteArray() );
1479 if (!isValid() || isRelative())
1482 if (!encodedQuery().isEmpty())
1485 u.setEncodedQuery(QByteArray());
1492 u.
cd(QLatin1String(
"../"));
1502 KUrl &u = lst.last();
1504 u.
cd(QLatin1String(
"../"));
1505 if (u.
path() != old)
1507 if (lst.count() == 1)
1522 return (*lst.begin()).fragment();
1533 return (*lst.begin()).ref();
1540 setFragment( _ref );
1546 (*lst.begin()).setFragment( _ref );
1548 *
this =
join( lst );
1559 return (*lst.begin()).hasRef();
1564 if ( dir.endsWith(QLatin1Char(
'/')))
1567 setPath(dir + QLatin1Char(
'/'));
1572 if (!_txt.isEmpty() && _txt[0] == QLatin1Char(
'?'))
1573 _setQuery( _txt.length() > 1 ? _txt.mid(1) : QString::fromLatin1(
"") );
1578void KUrl::_setQuery(
const QString& query )
1580 if ( query.isNull() ) {
1581 setEncodedQuery( QByteArray() );
1582 }
else if ( query.isEmpty() ) {
1583 setEncodedQuery(
"");
1585 setEncodedQuery( query.toLatin1() );
1594 return QString(QLatin1Char(
'?')) + QString::fromLatin1(encodedQuery());
1597void KUrl::_setEncodedUrl(
const QByteArray& url)
1599 setEncodedUrl(url, QUrl::TolerantMode);
1601 setUrl(QString::fromUtf8(url), QUrl::TolerantMode);
1604#ifndef KDE_NO_DEPRECATED
1607 return QUrl( _url1, QUrl::TolerantMode ) ==
QUrl( _url2, QUrl::TolerantMode );
1610 if ( _url1.isEmpty() && _url2.isEmpty() )
1613 if ( _url1.isEmpty() || _url2.isEmpty() )
1620 if ( list1.isEmpty() || list2.isEmpty() )
1623 return ( list1 == list2 );
1628#ifndef KDE_NO_DEPRECATED
1632 if (_url1.isEmpty() && _url2.isEmpty())
1635 if (_url1.isEmpty() || _url2.isEmpty())
1640 return u1.
equals(u2, _options);
1648 if ( list1.isEmpty() || list2.isEmpty() )
1651 int size = list1.count();
1652 if ( list2.count() != size )
1657 (*list1.begin()).setRef(
QString());
1658 (*list2.begin()).setRef(
QString());
1661 KUrl::List::Iterator it1 = list1.begin();
1662 KUrl::List::Iterator it2 = list2.begin();
1663 for( ; it1 != list1.end() ; ++it1, ++it2 )
1664 if ( !(*it1).equals( *it2, _ignore_trailing ) )
1672#ifndef KDE_NO_DEPRECATED
1676 if ( !text.isEmpty() )
1678 if (!QDir::isRelativePath(text) || text[0] == QLatin1Char(
'~'))
1690 QString _base_dir(QDir::cleanPath(base_dir));
1691 QString _path(QDir::cleanPath(path.isEmpty() || QDir::isRelativePath(path) ? _base_dir+QLatin1Char(
'/')+path : path));
1693 if (_base_dir.isEmpty())
1696 if (_base_dir[_base_dir.length()-1] != QLatin1Char(
'/'))
1697 _base_dir.append(QLatin1Char(
'/') );
1699 const QStringList list1 = _base_dir.split(QLatin1Char(
'/'), QString::SkipEmptyParts);
1700 const QStringList list2 = _path.split(QLatin1Char(
'/'), QString::SkipEmptyParts);
1704 int maxLevel = qMin(list1.count(), list2.count());
1705 while((level < maxLevel) && (list1[level] == list2[level])) level++;
1709 for(
int i = level; i < list1.count(); i++)
1710 result.append(QLatin1String(
"../"));
1713 for(
int i = level; i < list2.count(); i++)
1714 result.append(list2[i]).append(QLatin1Char(
'/'));
1716 if ((level < list2.count()) && (path[path.length()-1] != QLatin1Char(
'/')))
1717 result.truncate(result.length()-1);
1719 isParent = (level == list1.count());
1726 bool parent =
false;
1729 result.prepend(QLatin1String(
"./"));
1741 (url.host() != base_url.host()) ||
1742 (url.port() && url.port() != base_url.port()) ||
1755 static const char s_pathExcludeChars[] =
"!$&'()*+,;=:@/";
1756 relURL = QString::fromLatin1(QUrl::toPercentEncoding(
_relativePath(basePath, url.
path(), dummy), s_pathExcludeChars));
1757 relURL += url.
query();
1762 relURL += QLatin1Char(
'#');
1763 relURL += url.
ref();
1766 if ( relURL.isEmpty() )
1767 return QLatin1String(
"./");
1774#if defined(Q_WS_WIN) && defined(DEBUG_KURL)
1775 kDebug(kurlDebugArea()) <<
"KUrl::setPath " <<
" " << _path.toLatin1().data();
1777 if ( scheme().isEmpty() )
1778 setScheme( QLatin1String(
"file" ) );
1783 const int len = path.length();
1784 if( len == 2 &&
IS_LETTER(path[0]) && path[1] == QLatin1Char(
':') )
1785 path += QLatin1Char(
'/');
1790 if( len > 0 && path[0] != QLatin1Char(
'/') && scheme() == QLatin1String(
"file" ) )
1791 path = QLatin1Char(
'/') + path;
1793 QUrl::setPath( path );
1801 Q_FOREACH( item, items ) {
1802 result.insert( options & CaseInsensitiveKeys ? item.first.toLower() : item.first, item.second );
1810 const QString strQueryEncoded = QString::fromLatin1(encodedQuery());
1811 if ( strQueryEncoded.isEmpty() )
1815 const QStringList items = strQueryEncoded.split( QLatin1Char(
'&'), QString::SkipEmptyParts );
1816 for ( QStringList::const_iterator it = items.begin() ; it != items.end() ; ++it ) {
1817 const int equal_pos = (*it).indexOf(QLatin1Char(
'='));
1818 if ( equal_pos > 0 ) {
1819 QString name = (*it).left( equal_pos );
1821 name = name.toLower();
1822 QString value = (*it).mid( equal_pos + 1 );
1823 if ( value.isEmpty() )
1824 result.insert( name, QString::fromLatin1(
"") );
1827 value.replace( QLatin1Char(
'+'), QLatin1Char(
' ') );
1828 result.insert( name, QUrl::fromPercentEncoding( value.toLatin1() ) );
1830 }
else if ( equal_pos < 0 ) {
1833 name = name.toLower();
1834 result.insert( name,
QString() );
1843 const QString strQueryEncoded = QString::fromLatin1(encodedQuery());
1844 const QString item = _item + QLatin1Char(
'=');
1845 if ( strQueryEncoded.length() <= 1 )
1848 const QStringList items = strQueryEncoded.split(
QString(QLatin1Char(
'&')), QString::SkipEmptyParts );
1849 const int _len = item.length();
1850 for ( QStringList::ConstIterator it = items.begin(); it != items.end(); ++it )
1852 if ( (*it).startsWith( item ) )
1854 if ( (*it).length() > _len )
1856 QString str = (*it).mid( _len );
1857 str.replace( QLatin1Char(
'+'), QLatin1Char(
' ') );
1858 return QUrl::fromPercentEncoding( str.toLatin1() );
1861 return QString::fromLatin1(
"");
1870 QString item = _item + QLatin1Char(
'=');
1871 QString value = QString::fromLatin1(QUrl::toPercentEncoding(_value));
1873 QString strQueryEncoded = QString::fromLatin1(encodedQuery());
1874 if (!strQueryEncoded.isEmpty())
1875 strQueryEncoded += QLatin1Char(
'&');
1876 strQueryEncoded += item + value;
1877 setEncodedQuery( strQueryEncoded.toLatin1() );
1890 return hasFragment();
1895 if ( fragment.isEmpty() )
1896 setFragment( fragment );
1898 setFragment( QUrl::fromPercentEncoding( fragment.toLatin1() ) );
1903 if ( !hasFragment() )
1906 return QString::fromLatin1( encodedFragment() );
static int registerArea(const QByteArray &areaName, bool enabled=true)
KUrl::List is a QList that contains KUrls with a few convenience methods.
QStringList toStringList() const
Converts the URLs of this list to a list of strings.
static KUrl::List fromMimeData(const QMimeData *mimeData, KUrl::MetaDataMap *metaData=0)
Extract a list of KUrls from the contents of mimeData.
static QStringList mimeDataTypes()
Return the list of mimeTypes that can be decoded by fromMimeData.
static bool canDecode(const QMimeData *mimeData)
Return true if mimeData contains URI data.
void populateMimeData(QMimeData *mimeData, const KUrl::MetaDataMap &metaData=MetaDataMap(), MimeDataFlags flags=DefaultMimeDataFlags) const
Adds URLs data into the given QMimeData.
List()
Creates an empty List.
DecodeOptions
Flags to be used in fromMimeData.
Represents and parses a URL.
QString encodedPathAndQuery(AdjustPathOption trailing=LeaveTrailingSlash, const EncodedPathAndQueryOptions &options=PermitEmptyPath) const
Returns the encoded path and the query.
~KUrl()
Destructs the KUrl object.
void cleanPath(const CleanPathOption &options=SimplifyDirSeparators)
Resolves "." and ".." components in path.
void populateMimeData(QMimeData *mimeData, const MetaDataMap &metaData=MetaDataMap(), MimeDataFlags flags=DefaultMimeDataFlags) const
Adds URL data into the given QMimeData.
QString encodedHtmlRef() const
Returns the encoded reference (or "fragment") of the URL (everything after '#').
void setFileEncoding(const QString &encoding)
Adds encoding information to url by adding a "charset" parameter.
QString toMimeDataString() const
Returns the URL as a string, using the standard conventions for mime data (drag-n-drop or copy-n-past...
QString pathOrUrl() const
Return the URL as a string, which will be either the URL (as prettyUrl would return) or,...
QString prettyUrl(AdjustPathOption trailing=LeaveTrailingSlash) const
Returns the URL as string in human-friendly format.
@ ObeyTrailingSlash
This tells whether a trailing '/' should be ignored.
@ AppendTrailingSlash
tells whether the returned result should end with '/' or not.
bool hasPath() const
Test to see if this URL has a path is included in it.
void addQueryItem(const QString &_item, const QString &_value)
Add an additional query item.
bool hasPass() const
Test to see if this URL has a password included in it.
static KUrl fromMimeDataByteArray(const QByteArray &str)
Creates a KUrl from a string, using the standard conventions for mime data (drag-n-drop or copy-n-pas...
@ AvoidEmptyPath
If set to true then an empty path is substituted by "/" (this is the opposite of PermitEmptyPath)
bool hasHTMLRef() const
Checks whether there is a HTML reference.
static KUrl fromPath(const QString &text)
Creates a KUrl object from a QString representing an absolute path.
AdjustPathOption
Options to be used in adjustPath.
@ LeaveTrailingSlash
Do not change the path.
@ RemoveTrailingSlash
strips a trailing '/', except when the path is already just "/".
@ AddTrailingSlash
adds a trailing '/' if there is none yet
void adjustPath(AdjustPathOption trailing)
Add or remove a trailing slash to/from the path.
static QString relativeUrl(const KUrl &base_url, const KUrl &url)
Convenience function.
QString url(AdjustPathOption trailing=LeaveTrailingSlash) const
Returns the URL as string, with all escape sequences intact, encoded in a given charset.
QString ref() const
Returns the encoded reference (or "fragment") of the URL (everything after '#').
QString path(AdjustPathOption trailing=LeaveTrailingSlash) const
KUrl upUrl() const
This function is useful to implement the "Up" button in a file manager for example.
void setFileName(const QString &_txt)
Sets the filename of the path.
static KUrl fromPathOrUrl(const QString &text)
KUrl & operator=(const KUrl &_u)
void setProtocol(const QString &proto)
Sets the protocol for the URL (i.e., file, http, etc.)
bool hasHost() const
Test to see if this URL has a hostname included in it.
bool equals(const KUrl &u, const EqualsOptions &options=0) const
Compares this url with u.
bool operator==(const KUrl &_u) const
bool cmp(const KUrl &u, bool ignore_trailing=false) const
The same as equals(), just with a less obvious name.
QString query() const
Returns the query of the URL.
CleanPathOption
Options to be used in cleanPath.
@ KeepDirSeparators
The opposite of SimplifyDirSeparators.
QString directory(const DirectoryOptions &options=IgnoreTrailingSlash) const
Returns the directory of the path.
bool isLocalFile() const
Checks whether the file is local.
QString htmlRef() const
Returns the unencoded reference (or "fragment") of the URL (everything after '#').
bool cd(const QString &_dir)
Changes the directory by descending into the given directory.
QString pass() const
Returns the decoded password (corresponding to user()) included in the URL.
QString user() const
Returns the decoded user name (login, user id, ...) included in the URL.
KUrl()
Constructs an empty URL.
static List split(const QString &_url)
Splits nested URLs like file:///home/weis/kde.tgz#gzip:/#tar:/kdebase A URL like http://www....
@ CompareWithoutTrailingSlash
ignore trailing '/' characters.
@ CompareWithoutFragment
disables comparison of HTML-style references.
@ AllowEmptyPath
Treat a URL with no path as equal to a URL with a path of "/", when CompareWithoutTrailingSlash is se...
void setPath(const QString &path)
void setQuery(const QString &query)
void setDirectory(const QString &dir)
Set the directory to dir, leaving the filename empty.
void setRef(const QString &fragment)
Sets the reference/fragment part (everything after '#').
void setEncodedPathAndQuery(const QString &_txt)
This is useful for HTTP.
bool isParentOf(const KUrl &u) const
Checks whether the given URL is parent of this URL.
void setPass(const QString &pass)
Sets the password (corresponding to user()) included in the URL.
QString fileName(const DirectoryOptions &options=IgnoreTrailingSlash) const
Returns the filename of the path.
QString protocol() const
Returns the protocol for the URL (i.e., file, http, etc.), lowercased.
static QString relativePath(const QString &base_dir, const QString &path, bool *isParent=0)
Convenience function.
QString queryItem(const QString &item) const
Returns the value of a certain query item.
QMap< QString, QString > queryItems(const QueryItemsOptions &options=0) const
Returns the list of query items as a map mapping keys to values.
static bool isRelativeUrl(const QString &_url)
Convenience function.
bool hasRef() const
Checks whether the URL has a reference/fragment part.
QString fileEncoding() const
Returns encoding information from url, the content of the "charset" parameter.
bool hasUser() const
Test to see if this URL has a user name included in it.
bool hasSubUrl() const
Checks whether the URL has any sub URLs.
static KUrl join(const List &_list)
Reverses split().
QString toLocalFile(AdjustPathOption trailing=LeaveTrailingSlash) const
void addPath(const QString &txt)
Adds to the current path.
void setUser(const QString &user)
Sets the user name (login, user id, ...) included in the URL.
void setHTMLRef(const QString &_ref)
Sets the HTML-style reference.
static QString cleanpath(const QString &_path, bool cleanDirSeparator, bool decodeDots)
KDE4 TODO: maybe we should use QUrl::resolved()
static QString trailingSlash(KUrl::AdjustPathOption trailing, const QString &path)
bool urlcmp(const QString &_url1, const QString &_url2)
static const char s_kdeUriListMime[]
uint qHash(const KUrl &kurl)
static bool isLocalFile(const QUrl &url)
static QString removeSlashOrFilePrefix(const QString &str)
static QString _relativePath(const QString &base_dir, const QString &path, bool &isParent)
#define IS_SLASH_AND_DRIVE_OR_DOUBLESLASH_0
static QString toPrettyPercentEncoding(const QString &input, bool forFragment)
#define IS_DRIVE_OR_DOUBLESLASH(isletter, char1, char2, colon, slash)
static bool hasSubUrl(const QUrl &url)
static QByteArray uriListData(const KUrl::List &urls)
#define IS_DRIVE_OR_DOUBLESLASH_0
const QString & staticQString(const char *str)
Creates a static QString.
KLocale * locale()
Returns the global locale object.
QString tildeExpand(const QString &path)
Performs tilde expansion on path.