40 #include <QtCore/QDir>
41 #include <QtCore/QMutableStringListIterator>
42 #include <QtCore/QRegExp>
43 #include <QtCore/QMimeData>
44 #include <QtCore/QTextCodec>
47 static 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));
109 #ifdef Q_WS_WIN // prepend drive letter if exists (js)
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();
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) {
239 uriListData += urlStringList.at(i);
241 uriListData +=
"\r\n";
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() )
547 setEncodedFragment( strRef_encoded );
553 setEncodedQuery( QByteArray() );
555 if ( rUrl[0] == QLatin1Char(
'/') )
557 if ((rUrl.length() > 1) && (rUrl[1] == QLatin1Char(
'/')))
567 else if ( rUrl[0] != QLatin1Char(
'?') )
569 const int pos = strPath.lastIndexOf( QLatin1Char(
'/') );
571 strPath.truncate(pos);
572 strPath += QLatin1Char(
'/');
576 if ( strPath.isEmpty() )
577 strPath = QLatin1Char(
'/');
588 const KUrl tmp( rUrl );
592 if (!_u.userInfo().isEmpty() && userInfo().isEmpty()
593 && (_u.host() == host()) && (_u.scheme() == scheme()))
595 setUserInfo( _u.userInfo() );
603 QUrl::operator=( _u );
615 return ( *
this == u );
620 return qVariantFromValue(*
this);
623 #ifndef KDE_NO_DEPRECATED
632 if ( !isValid() || !_u.isValid() )
641 if (path1 == QLatin1String(
"/"))
643 if (path2 == QLatin1String(
"/"))
650 if ( !bLocal1 && bLocal2 || bLocal1 && !bLocal2 )
653 if ( bLocal1 && bLocal2 && 0 != QString::compare( path1, path2, Qt::CaseInsensitive ) )
656 if ( path1 != path2 )
659 if ( scheme() == _u.scheme() &&
660 authority() == _u.authority() &&
661 encodedQuery() == _u.encodedQuery() &&
668 return ( *
this == _u );
673 return scheme().toLower();
693 return !userName().isEmpty();
708 return !password().isEmpty();
713 return !host().isEmpty();
718 return !
path().isEmpty();
732 while( i < _txt.length() && _txt[i] == QLatin1Char(
'/') )
734 QString tmp = i ? _txt.mid( i ) : _txt;
737 if ( path.isEmpty() )
739 path =
isLocalFile() ? QDir::rootPath() : QLatin1String(
"/");
741 path = QDir::rootPath();
745 int lastSlash = path.lastIndexOf( QLatin1Char(
'/') );
746 if ( lastSlash == -1)
748 else if ( !path.endsWith( QLatin1Char(
'/') ) )
749 path.truncate( lastSlash+1 );
762 if (
path() != newPath )
778 int len = result.length();
779 if ((len > 0) && (result[ len - 1 ] != QLatin1Char(
'/')))
780 result += QLatin1Char(
'/');
785 if ( result == QLatin1String(
"/") )
787 int len = result.length();
788 while (len > 1 && result[ len - 1 ] == QLatin1Char(
'/'))
792 result.truncate( len );
804 if (!m_strPath_encoded.isEmpty())
806 m_strPath_encoded =
trailingSlash( _trailing, m_strPath_encoded );
810 if (
path() != newPath )
823 encodedPath = QString::fromLatin1(QUrl::toPercentEncoding(encodedPath,
"!$&'()*+,;=:@/"));
825 encodedPath =
trailingSlash(trailing, QString::fromLatin1(QUrl::encodedPath()));
828 encodedPath =
trailingSlash(trailing, QString::fromLatin1(QUrl::encodedPath()));
832 encodedPath.append(QLatin1Char(
'/'));
836 return encodedPath + QLatin1Char(
'?') + QString::fromLatin1(encodedQuery());
843 void KUrl::setEncodedPath(
const QString& _txt,
int encoding_hint )
845 m_strPath_encoded = _txt;
847 decode( m_strPath_encoded, m_strPath, m_strPath_encoded, encoding_hint );
849 if (m_strProtocol ==
"file")
850 m_strPath_encoded.clear();
852 if ( m_iUriMode == Auto )
859 const int pos = _txt.indexOf(QLatin1Char(
'?'));
862 setPath( QUrl::fromPercentEncoding( _txt.toLatin1() ) );
863 setEncodedQuery( QByteArray() );
867 setPath( QUrl::fromPercentEncoding(_txt.toLatin1().left(pos)) );
868 _setQuery( _txt.right( _txt.length() - pos - 1 ) );
876 kWarning() << (
isLocalFile() ?
"converted to local file - the related call should be converted to toLocalFile()" :
"") << QUrl::path();
887 KUrl urlWithoutHost(*
this);
888 urlWithoutHost.setHost(
QString());
892 #warning FIXME: Remove #ifdef below once upstream bug, QTBUG-20322, is fixed. Also see BR# 194746.
906 if ( ( url.scheme() != QLatin1String(
"file") ) ||
hasSubUrl( url ) )
909 if (url.host().isEmpty() || (url.host() == QLatin1String(
"localhost")))
912 char hostname[ 256 ];
913 hostname[ 0 ] =
'\0';
914 if (!gethostname( hostname, 255 ))
915 hostname[
sizeof(hostname)-1] =
'\0';
917 for(
char *p = hostname; *p; p++)
920 return (url.host() == QString::fromLatin1( hostname ));
935 if (!q.isEmpty() && q[0] == QLatin1Char(
'?'))
938 QStringList args = q.split(QLatin1Char(
'&'), QString::SkipEmptyParts);
939 for(QStringList::Iterator it = args.begin();
942 QString s = QUrl::fromPercentEncoding( (*it).toLatin1() );
943 if (s.startsWith(QLatin1String(
"charset=")))
948 if (!encoding.isEmpty())
949 args.append(QLatin1String(
"charset=") + QString::fromLatin1(QUrl::toPercentEncoding(encoding)));
954 _setQuery(args.join(
QString(QLatin1Char(
'&'))));
967 if (q[0] == QLatin1Char(
'?'))
970 const QStringList args = q.split(QLatin1Char(
'&'), QString::SkipEmptyParts);
971 for(QStringList::ConstIterator it = args.begin();
975 QString s = QUrl::fromPercentEncoding((*it).toLatin1());
976 if (s.startsWith(QLatin1String(
"charset=")))
986 const QString scheme = url.scheme();
987 if ( scheme.isEmpty() )
992 switch (
ref.at(0).unicode() ) {
994 if (
ref.startsWith(QLatin1String(
"gzip:")) )
998 if (
ref.startsWith(QLatin1String(
"bzip:")) ||
ref.startsWith(QLatin1String(
"bzip2:")) )
1002 if (
ref.startsWith(QLatin1String(
"lzma:")) )
1006 if (
ref.startsWith(QLatin1String(
"xz:")) )
1010 if (
ref.startsWith(QLatin1String(
"tar:")) )
1014 if (
ref.startsWith(QLatin1String(
"ar:")) )
1018 if (
ref.startsWith(QLatin1String(
"zip:")) )
1024 if ( scheme == QLatin1String(
"error") )
1036 if (QString::compare(scheme(), QLatin1String(
"mailto"), Qt::CaseInsensitive) == 0) {
1044 QUrl newUrl( *
this );
1045 newUrl.setPath(
path() + QLatin1Char(
'/') );
1046 return QString::fromLatin1(newUrl.toEncoded());
1050 if (cleanedPath == QLatin1String(
"/")) {
1051 if (
path() != QLatin1String(
"/")) {
1052 QUrl fixedUrl = *
this;
1053 fixedUrl.setPath(cleanedPath);
1054 return QLatin1String(fixedUrl.toEncoded(
None));
1056 return QLatin1String(toEncoded(
None));
1065 result.reserve(input.length());
1066 for (
int i = 0; i < input.length(); ++i) {
1067 const QChar c = input.at(i);
1068 register ushort u = c.unicode();
1070 || (!forFragment && u ==
'?')
1071 || u ==
'#' || u ==
'%'
1072 || (u ==
' ' && (i+1 == input.length() || input.at(i+1).unicode() ==
' '))) {
1073 static const char hexdigits[] =
"0123456789ABCDEF";
1074 result += QLatin1Char(
'%');
1075 result += QLatin1Char(hexdigits[(u & 0xf0) >> 4]);
1076 result += QLatin1Char(hexdigits[u & 0xf]);
1097 if (!result.isEmpty())
1099 if (!authority().isEmpty() || result == QLatin1String(
"file") ||
path().isEmpty())
1100 result += QLatin1String(
"://");
1102 result += QLatin1Char(
':');
1106 if (!tmp.isEmpty()) {
1107 result += QString::fromLatin1(QUrl::toPercentEncoding(tmp));
1108 result += QLatin1Char(
'@');
1113 if (tmp.contains(QLatin1Char(
':')))
1114 result += QLatin1Char(
'[') + tmp + QLatin1Char(
']');
1119 result += QLatin1Char(
':');
1120 result += QString::number(port());
1126 tmp.prepend(QLatin1Char(
'/'));
1132 result += QLatin1Char(
'/');
1133 else if (trailing ==
RemoveTrailingSlash && tmp.length() > 1 && tmp.endsWith(QLatin1Char(
'/')))
1137 result += QLatin1Char(
'?');
1138 result += QString::fromLatin1(encodedQuery());
1141 if (hasFragment()) {
1142 result += QLatin1Char(
'#');
1153 if (_flags & StripFileProtocol && u.startsWith(
"file://")) {
1156 return QDir::convertSeparators(u);
1170 if (
isLocalFile() && fragment().isNull() && encodedQuery().isNull() ) {
1189 if( !s.startsWith( QLatin1String (
"file://" ) ))
1192 if ( gethostname( hostname, 255 ) == 0 )
1194 hostname[256] =
'\0';
1195 return QString(
"file://" ) + hostname + s.mid( 5 );
1202 KUrl safeUrl(*
this);
1203 safeUrl.setPassword(
QString());
1204 return safeUrl.
url();
1211 if ( str.startsWith(
"file:" ) )
1231 url =
KUrl(url.fragment());
1235 ref = url.fragment();
1236 hasRef = url.hasFragment();
1244 KUrl::List::Iterator it;
1245 for( it = lst.begin() ; it != lst.end(); ++it )
1247 (*it).setFragment( ref );
1261 if (lst.isEmpty())
return KUrl();
1265 QListIterator<KUrl> it(lst);
1267 while (it.hasPrevious())
1269 KUrl u(it.previous());
1271 u.setEncodedFragment(tmp.
url().toLatin1() );
1283 Q_ASSERT( options != 0 );
1287 return list.last().fileName(options);
1291 int len = path.length();
1297 while ( len >= 1 && path[ len - 1 ] == QLatin1Char(
'/') )
1300 else if ( path[ len - 1 ] == QLatin1Char(
'/') )
1304 if ( len == 1 && path[ 0 ] == QLatin1Char(
'/') )
1310 if (!m_strPath_encoded.isEmpty())
1315 int i = m_strPath_encoded.lastIndexOf( QLatin1Char(
'/'), len - 1 );
1316 QString fileName_encoded = m_strPath_encoded.mid(i+1);
1317 n += fileName_encoded.count(
"%2f", Qt::CaseInsensitive);
1322 i = path.lastIndexOf( QLatin1Char(
'/'), i - 1 );
1324 while (--n && (i > 0));
1329 if ( len == (
int)path.length() )
1333 fname = path.left( len );
1337 fname = path.mid( i + 1, len - i - 1 );
1347 KUrl &u = lst.last();
1349 *
this =
join( lst );
1355 if ( _txt.isEmpty() )
1360 int len = strPath.length();
1362 if ( _txt[0] != QLatin1Char(
'/') && ( len == 0 || strPath[ len - 1 ] != QLatin1Char(
'/') ) )
1363 strPath += QLatin1Char(
'/');
1367 const int _txtlen = _txt.length();
1368 if ( strPath.endsWith( QLatin1Char(
'/') ) )
1370 while ( ( i < _txtlen ) && ( _txt[i] == QLatin1Char(
'/') ) )
1374 setPath( strPath + _txt.mid( i ) );
1380 Q_ASSERT( options != 0 );
1385 if ( result.isEmpty() || result == QLatin1String (
"/" ) )
1388 int i = result.lastIndexOf( QLatin1Char(
'/') );
1396 return QString(QLatin1Char(
'/'));
1400 if ( i == 2 && result[1] == QLatin1Char(
':') )
1402 return result.left(3);
1407 result = result.left( i + 1 );
1409 result = result.left( i );
1420 if ( _dir.isEmpty() || !isValid() )
1426 KUrl &u = lst.last();
1428 *
this =
join( lst );
1434 if ( !QFileInfo(_dir).isRelative() )
1436 if ( _dir[0] == QLatin1Char(
'/') )
1442 setEncodedQuery( QByteArray() );
1447 if (_dir[0] == QLatin1Char(
'~') && scheme() == QLatin1String (
"file"))
1450 QString strPath = QDir::homePath();
1451 strPath += QLatin1Char(
'/');
1452 strPath += _dir.right( strPath.length() - 1 );
1455 setEncodedQuery( QByteArray() );
1470 setEncodedQuery( QByteArray() );
1477 if (!isValid() || isRelative())
1480 if (!encodedQuery().isEmpty())
1483 u.setEncodedQuery(QByteArray());
1490 u.
cd(QLatin1String(
"../"));
1500 KUrl &u = lst.last();
1502 u.
cd(QLatin1String(
"../"));
1503 if (u.
path() != old)
1505 if (lst.count() == 1)
1520 return (*lst.begin()).fragment();
1531 return (*lst.begin()).
ref();
1538 setFragment( _ref );
1544 (*lst.begin()).setFragment( _ref );
1546 *
this =
join( lst );
1557 return (*lst.begin()).
hasRef();
1562 if ( dir.endsWith(QLatin1Char(
'/')))
1565 setPath(dir + QLatin1Char(
'/'));
1570 if (!_txt.isEmpty() && _txt[0] == QLatin1Char(
'?'))
1571 _setQuery( _txt.length() > 1 ? _txt.mid(1) : QString::fromLatin1(
"") );
1576 void KUrl::_setQuery(
const QString& query )
1578 if ( query.isNull() ) {
1579 setEncodedQuery( QByteArray() );
1580 }
else if ( query.isEmpty() ) {
1581 setEncodedQuery(
"");
1583 setEncodedQuery( query.toLatin1() );
1592 return QString(QLatin1Char(
'?')) + QString::fromLatin1(encodedQuery());
1595 void KUrl::_setEncodedUrl(
const QByteArray& url)
1597 setEncodedUrl(url, QUrl::TolerantMode);
1599 setUrl(QString::fromUtf8(url), QUrl::TolerantMode);
1602 #ifndef KDE_NO_DEPRECATED
1605 return QUrl( _url1, QUrl::TolerantMode ) ==
QUrl( _url2, QUrl::TolerantMode );
1608 if ( _url1.isEmpty() && _url2.isEmpty() )
1611 if ( _url1.isEmpty() || _url2.isEmpty() )
1618 if ( list1.isEmpty() || list2.isEmpty() )
1621 return ( list1 == list2 );
1626 #ifndef KDE_NO_DEPRECATED
1630 if (_url1.isEmpty() && _url2.isEmpty())
1633 if (_url1.isEmpty() || _url2.isEmpty())
1638 return u1.
equals(u2, _options);
1640 #if 0 // kde3 code that supported nested urls
1646 if ( list1.isEmpty() || list2.isEmpty() )
1649 int size = list1.count();
1650 if ( list2.count() != size )
1655 (*list1.begin()).setRef(
QString());
1656 (*list2.begin()).setRef(
QString());
1659 KUrl::List::Iterator it1 = list1.begin();
1660 KUrl::List::Iterator it2 = list2.begin();
1661 for( ; it1 != list1.end() ; ++it1, ++it2 )
1662 if ( !(*it1).equals( *it2, _ignore_trailing ) )
1670 #ifndef KDE_NO_DEPRECATED
1674 if ( !text.isEmpty() )
1676 if (!QDir::isRelativePath(text) || text[0] == QLatin1Char(
'~'))
1688 QString _base_dir(QDir::cleanPath(base_dir));
1689 QString _path(QDir::cleanPath(path.isEmpty() || QDir::isRelativePath(path) ? _base_dir+QLatin1Char(
'/')+path : path));
1691 if (_base_dir.isEmpty())
1694 if (_base_dir[_base_dir.length()-1] != QLatin1Char(
'/'))
1695 _base_dir.append(QLatin1Char(
'/') );
1697 const QStringList list1 = _base_dir.split(QLatin1Char(
'/'), QString::SkipEmptyParts);
1698 const QStringList list2 = _path.split(QLatin1Char(
'/'), QString::SkipEmptyParts);
1702 int maxLevel = qMin(list1.count(), list2.count());
1703 while((level < maxLevel) && (list1[level] == list2[level])) level++;
1707 for(
int i = level; i < list1.count(); i++)
1708 result.append(QLatin1String(
"../"));
1711 for(
int i = level; i < list2.count(); i++)
1712 result.append(list2[i]).append(QLatin1Char(
'/'));
1714 if ((level < list2.count()) && (path[path.length()-1] != QLatin1Char(
'/')))
1715 result.truncate(result.length()-1);
1717 isParent = (level == list1.count());
1724 bool parent =
false;
1727 result.prepend(QLatin1String(
"./"));
1739 (url.host() != base_url.host()) ||
1740 (url.port() && url.port() != base_url.port()) ||
1753 static const char s_pathExcludeChars[] =
"!$&'()*+,;=:@/";
1754 relURL = QString::fromLatin1(QUrl::toPercentEncoding(
_relativePath(basePath, url.
path(), dummy), s_pathExcludeChars));
1755 relURL += url.
query();
1760 relURL += QLatin1Char(
'#');
1761 relURL += url.
ref();
1764 if ( relURL.isEmpty() )
1765 return QLatin1String(
"./");
1772 #if defined(Q_WS_WIN) && defined(DEBUG_KURL)
1773 kDebug(kurlDebugArea()) <<
"KUrl::setPath " <<
" " << _path.toLatin1().data();
1775 if ( scheme().isEmpty() )
1776 setScheme( QLatin1String(
"file" ) );
1781 const int len = path.length();
1782 if( len == 2 &&
IS_LETTER(path[0]) && path[1] == QLatin1Char(
':') )
1783 path += QLatin1Char(
'/');
1788 if( len > 0 && path[0] != QLatin1Char(
'/') && scheme() == QLatin1String(
"file" ) )
1789 path = QLatin1Char(
'/') +
path;
1791 QUrl::setPath( path );
1794 #if 0 // this would be if we didn't decode '+' into ' '
1799 Q_FOREACH( item, items ) {
1800 result.insert( options &
CaseInsensitiveKeys ? item.first.toLower() : item.first, item.second );
1808 const QString strQueryEncoded = QString::fromLatin1(encodedQuery());
1809 if ( strQueryEncoded.isEmpty() )
1813 const QStringList items = strQueryEncoded.split( QLatin1Char(
'&'), QString::SkipEmptyParts );
1814 for ( QStringList::const_iterator it = items.begin() ; it != items.end() ; ++it ) {
1815 const int equal_pos = (*it).indexOf(QLatin1Char(
'='));
1816 if ( equal_pos > 0 ) {
1817 QString name = (*it).left( equal_pos );
1819 name = name.toLower();
1820 QString value = (*it).mid( equal_pos + 1 );
1821 if ( value.isEmpty() )
1822 result.insert( name, QString::fromLatin1(
"") );
1825 value.replace( QLatin1Char(
'+'), QLatin1Char(
' ') );
1826 result.insert( name, QUrl::fromPercentEncoding( value.toLatin1() ) );
1828 }
else if ( equal_pos < 0 ) {
1831 name = name.toLower();
1832 result.insert( name,
QString() );
1841 const QString strQueryEncoded = QString::fromLatin1(encodedQuery());
1842 const QString item = _item + QLatin1Char(
'=');
1843 if ( strQueryEncoded.length() <= 1 )
1846 const QStringList items = strQueryEncoded.split(
QString(QLatin1Char(
'&')), QString::SkipEmptyParts );
1847 const int _len = item.length();
1848 for ( QStringList::ConstIterator it = items.begin(); it != items.end(); ++it )
1850 if ( (*it).startsWith( item ) )
1852 if ( (*it).length() > _len )
1854 QString str = (*it).mid( _len );
1855 str.replace( QLatin1Char(
'+'), QLatin1Char(
' ') );
1856 return QUrl::fromPercentEncoding( str.toLatin1() );
1859 return QString::fromLatin1(
"");
1868 QString item = _item + QLatin1Char(
'=');
1869 QString value = QString::fromLatin1(QUrl::toPercentEncoding(_value));
1871 QString strQueryEncoded = QString::fromLatin1(encodedQuery());
1872 if (!strQueryEncoded.isEmpty())
1873 strQueryEncoded += QLatin1Char(
'&');
1874 strQueryEncoded += item + value;
1875 setEncodedQuery( strQueryEncoded.toLatin1() );
1888 return hasFragment();
1893 if ( fragment.isEmpty() )
1894 setFragment( fragment );
1896 setFragment( QUrl::fromPercentEncoding( fragment.toLatin1() ) );
1901 if ( fragment().isNull() )
1904 return QString::fromLatin1( QUrl::toPercentEncoding( fragment() ) );
void adjustPath(AdjustPathOption trailing)
Add or remove a trailing slash to/from the path.
static QString cleanpath(const QString &_path, bool cleanDirSeparator, bool decodeDots)
KDE4 TODO: maybe we should use QUrl::resolved()
QString directory(const DirectoryOptions &options=IgnoreTrailingSlash) const
Returns the directory of the path.
strips a trailing '/', except when the path is already just "/".
static QString relativeUrl(const KUrl &base_url, const KUrl &url)
Convenience function.
static List split(const QString &_url)
Splits nested URLs like file:///home/weis/kde.tgz#gzip:/#tar:/kdebase A URL like http://www.kde.org#tar:/kde/README.hml#ref1 will be split in http://www.kde.org and tar:/kde/README.html::ref1.
static QString relativePath(const QString &base_dir, const QString &path, bool *isParent=0)
Convenience function.
adds a trailing '/' if there is none yet
void populateMimeData(QMimeData *mimeData, const KUrl::MetaDataMap &metaData=MetaDataMap(), MimeDataFlags flags=DefaultMimeDataFlags) const
Adds URLs data into the given QMimeData.
bool hasHTMLRef() const
Checks whether there is a HTML reference.
QString fileEncoding() const
Returns encoding information from url, the content of the "charset" parameter.
static bool hasSubUrl(const QUrl &url)
bool hasHost() const
Test to see if this URL has a hostname included in it.
QString encodedHtmlRef() const
Returns the HTML reference (the part of the URL after "#") in encoded form.
static bool isRelativeUrl(const QString &_url)
Convenience function.
#define IS_DRIVE_OR_DOUBLESLASH(isletter, char1, char2, colon, slash)
QString ref() const
Returns the reference (or "fragment") of the URL.
void cleanPath(const CleanPathOption &options=SimplifyDirSeparators)
Resolves "." and ".." components in path.
bool urlcmp(const QString &_url1, const QString &_url2)
#define IS_DRIVE_OR_DOUBLESLASH_0
void setRef(const QString &fragment)
Sets the reference/fragment part (everything after '#').
QMap< QString, QString > queryItems(const QueryItemsOptions &options=0) const
Returns the list of query items as a map mapping keys to values.
bool cd(const QString &_dir)
Changes the directory by descending into the given directory.
void setEncodedPathAndQuery(const QString &_txt)
This is useful for HTTP.
static KUrl fromPath(const QString &text)
Creates a KUrl object from a QString representing an absolute path.
QString toLocalFile(AdjustPathOption trailing=LeaveTrailingSlash) const
void addQueryItem(const QString &_item, const QString &_value)
Add an additional query item.
ignore trailing '/' characters.
KUrl()
Constructs an empty URL.
static bool canDecode(const QMimeData *mimeData)
Return true if mimeData contains URI data.
void populateMimeData(QMimeData *mimeData, const MetaDataMap &metaData=MetaDataMap(), MimeDataFlags flags=DefaultMimeDataFlags) const
Adds URL data into the given QMimeData.
QString toMimeDataString() const
Returns the URL as a string, using the standard conventions for mime data (drag-n-drop or copy-n-past...
bool isParentOf(const KUrl &u) const
Checks whether the given URL is parent of this URL.
bool hasPass() const
Test to see if this URL has a password included in it.
void ref()
Tells KGlobal about one more operations that should be finished before the application exits...
Represents and parses a URL.
void setQuery(const QString &query)
void setPath(const QString &path)
void setUser(const QString &user)
Sets the user name (login, user id, ...) included in the URL.
bool operator==(const KEntry &k1, const KEntry &k2)
List()
Creates an empty List.
void setProtocol(const QString &proto)
Sets the protocol for the URL (i.e., file, http, etc.)
void addPath(const QString &txt)
Adds to the current path.
bool cmp(const KUrl &u, bool ignore_trailing=false) const
The same as equals(), just with a less obvious name.
bool hasRef() const
Checks whether the URL has a reference/fragment part.
static KUrl::List fromMimeData(const QMimeData *mimeData, KUrl::MetaDataMap *metaData=0)
Extract a list of KUrls from the contents of mimeData.
static QString toPrettyPercentEncoding(const QString &input, bool forFragment)
static QByteArray uriListData(const KUrl::List &urls)
QString user() const
Returns the decoded user name (login, user id, ...) included in the URL.
QString protocol() const
Returns the protocol for the URL (i.e., file, http, etc.), lowercased.
KUrl upUrl() const
This function is useful to implement the "Up" button in a file manager for example.
QString pass() const
Returns the decoded password (corresponding to user()) included in the URL.
disables comparison of HTML-style references.
QString pathOrUrl() const
Return the URL as a string, which will be either the URL (as prettyUrl would return) or...
static int registerArea(const QByteArray &areaName, bool enabled=true)
void setPass(const QString &pass)
Sets the password (corresponding to user()) included in the URL.
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...
bool hasUser() const
Test to see if this URL has a user name included in it.
QString path(AdjustPathOption trailing=LeaveTrailingSlash) const
bool hasPath() const
Test to see if this URL has a path is included in it.
void setHTMLRef(const QString &_ref)
Sets the HTML-style reference.
QString htmlRef() const
Returns the HTML reference (the part of the URL after "#").
#define IS_SLASH_AND_DRIVE_OR_DOUBLESLASH_0
AdjustPathOption
Options to be used in adjustPath.
uint qHash(const KUrl &kurl)
bool operator==(const KUrl &_u) const
static QString _relativePath(const QString &base_dir, const QString &path, bool &isParent)
KLocale * locale()
Returns the global locale object.
void setFileEncoding(const QString &encoding)
Adds encoding information to url by adding a "charset" parameter.
KUrl::List is a QList that contains KUrls with a few convenience methods.
static QString removeSlashOrFilePrefix(const QString &str)
void setFileName(const QString &_txt)
Sets the filename of the path.
static QString trailingSlash(KUrl::AdjustPathOption trailing, const QString &path)
QString encodedPathAndQuery(AdjustPathOption trailing=LeaveTrailingSlash, const EncodedPathAndQueryOptions &options=PermitEmptyPath) const
Returns the encoded path and the query.
QString fileName(const DirectoryOptions &options=IgnoreTrailingSlash) const
Returns the filename of the path.
static bool isLocalFile(const QUrl &url)
~KUrl()
Destructs the KUrl object.
CleanPathOption
Options to be used in cleanPath.
This tells whether a trailing '/' should be ignored.
QStringList toStringList() const
Converts the URLs of this list to a list of strings.
bool hasSubUrl() const
Checks whether the URL has any sub URLs.
tells whether the returned result should end with '/' or not.
QString tildeExpand(const QString &path)
Performs tilde expansion on path.
QString query() const
Returns the query of the URL.
The opposite of SimplifyDirSeparators.
static QStringList mimeDataTypes()
Return the list of mimeTypes that can be decoded by fromMimeData.
void setDirectory(const QString &dir)
Set the directory to dir, leaving the filename empty.
QString url(AdjustPathOption trailing=LeaveTrailingSlash) const
Returns the URL as string, with all escape sequences intact, encoded in a given charset.
const QString & staticQString(const char *str)
Creates a static QString.
If set to true then an empty path is substituted by "/" (this is the opposite of PermitEmptyPath) ...
static const char s_kdeUriListMime[]
static KUrl fromPathOrUrl(const QString &text)
bool isLocalFile() const
Checks whether the file is local.
DecodeOptions
Flags to be used in fromMimeData.
Treat a URL with no path as equal to a URL with a path of "/", when CompareWithoutTrailingSlash is se...
bool equals(const KUrl &u, const EqualsOptions &options=0) const
Compares this url with u.
QString prettyUrl(AdjustPathOption trailing=LeaveTrailingSlash) const
Returns the URL as string in human-friendly format.
static KUrl join(const List &_list)
Reverses split().
KUrl & operator=(const KUrl &_u)
QString queryItem(const QString &item) const
Returns the value of a certain query item.