• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KDECore

  • kdecore
  • io
kurl.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 1999 Torben Weis <weis@kde.org>
3 Copyright (C) 2005-2006 David Faure <faure@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
22
23/*
24 * The currently active RFC for URL/URIs is RFC3986
25 * Previous (and now deprecated) RFCs are RFC1738 and RFC2396
26 */
27
28#include "kurl.h"
29
30#include <kdebug.h>
31#include <kglobal.h>
32#include <kshell.h>
33
34#include <stdio.h>
35#include <assert.h>
36#include <ctype.h>
37#include <stdlib.h>
38#include <unistd.h>
39
40#include <QtCore/QDir>
41#include <QtCore/QMutableStringListIterator>
42#include <QtCore/QRegExp>
43#include <QtCore/QMimeData>
44#include <QtCore/QTextCodec>
45
46#ifdef DEBUG_KURL
47static int kurlDebugArea() { static int s_area = KDebug::registerArea("kdecore (KUrl)"); return s_area; }
48#endif
49
50static QString cleanpath( const QString &_path, bool cleanDirSeparator, bool decodeDots )
51{
52 if (_path.isEmpty())
53 return QString();
54
55 if (QFileInfo(_path).isRelative())
56 return _path; // Don't mangle mailto-style URLs
57
58 QString path = _path;
59
60 int len = path.length();
61
62 if (decodeDots)
63 {
64 static const QString &encodedDot = KGlobal::staticQString("%2e");
65 if (path.indexOf(encodedDot, 0, Qt::CaseInsensitive) != -1)
66 {
67 static const QString &encodedDOT = KGlobal::staticQString("%2E"); // Uppercase!
68 path.replace(encodedDot, QString(QLatin1Char('.')));
69 path.replace(encodedDOT, QString(QLatin1Char('.')));
70 len = path.length();
71 }
72 }
73
74 const bool slash = (len && path[len-1] == QLatin1Char('/')) ||
75 (len > 1 && path[len-2] == QLatin1Char('/') && path[len-1] == QLatin1Char('.'));
76
77 // The following code cleans up directory path much like
78 // QDir::cleanPath() except it can be made to ignore multiple
79 // directory separators by setting the flag to false. That fixes
80 // bug# 15044, mail.altavista.com and other similar brain-dead server
81 // implementations that do not follow what has been specified in
82 // RFC 2396!! (dA)
83 QString result;
84 int cdUp, orig_pos, pos;
85
86 cdUp = 0;
87 pos = orig_pos = len;
88 while ( pos && (pos = path.lastIndexOf(QLatin1Char('/'),--pos)) != -1 )
89 {
90 len = orig_pos - pos - 1;
91 if ( len == 2 && path[pos+1] == QLatin1Char('.') && path[pos+2] == QLatin1Char('.') )
92 cdUp++;
93 else
94 {
95 // Ignore any occurrences of '.'
96 // This includes entries that simply do not make sense like /..../
97 if ( (len || !cleanDirSeparator) &&
98 (len != 1 || path[pos+1] != QLatin1Char('.') ) )
99 {
100 if ( !cdUp )
101 result.prepend(path.mid(pos, len+1));
102 else
103 cdUp--;
104 }
105 }
106 orig_pos = pos;
107 }
108
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(':') );
112 }
113#endif
114
115 if ( result.isEmpty() )
116 result = QLatin1Char('/');
117 else if ( slash && result[result.length()-1] != QLatin1Char('/') )
118 result.append(QLatin1Char('/'));
119
120 return result;
121}
122
123#ifdef Q_WS_WIN
124
125// returns true if provided arguments desinate letter+colon or double slash
126#define IS_DRIVE_OR_DOUBLESLASH(isletter, char1, char2, colon, slash) \
127 ((isletter && char2 == colon) || (char1 == slash && char2 == slash))
128
129// Removes file:/// or file:// or file:/ or / prefix assuming that str
130// is (nonempty) Windows absolute path with a drive letter or double slash.
131// If there was file protocol, the path is decoded from percent encoding
132static QString removeSlashOrFilePrefix(const QString& str)
133{
134 // FIXME this should maybe be replaced with some (faster?)/nicer logic
135 const int len = str.length();
136 if (str[0]==QLatin1Char('f')) {
137 if ( len > 10 && str.startsWith( QLatin1String( "file:///" ) )
138 && IS_DRIVE_OR_DOUBLESLASH(str[8].isLetter(), str[8], str[9], QLatin1Char(':'), QLatin1Char('/')) )
139 return QUrl::fromPercentEncoding( str.toLatin1() ).mid(8);
140 else if ( len > 9 && str.startsWith( QLatin1String( "file://" ) )
141 && IS_DRIVE_OR_DOUBLESLASH(str[7].isLetter(), str[7], str[8], QLatin1Char(':'), QLatin1Char('/')) )
142 return QUrl::fromPercentEncoding( str.toLatin1() ).mid(7);
143 else if ( len > 8 && str.startsWith( QLatin1String( "file:/" ) )
144 && IS_DRIVE_OR_DOUBLESLASH(str[6].isLetter(), str[6], str[7], QLatin1Char(':'), QLatin1Char('/')) )
145 return QUrl::fromPercentEncoding( str.toLatin1() ).mid(6);
146 }
147 /* No 'else' here since there can be "f:/" path. */
148
149 /* '/' + drive letter or // */
150 if ( len > 2 && str[0] == QLatin1Char('/')
151 && IS_DRIVE_OR_DOUBLESLASH(str[1].isLetter(), str[1], str[2], QLatin1Char(':'), QLatin1Char('/')) )
152 return str.mid(1);
153 /* drive letter or // */
154 else if ( len >= 2 && IS_DRIVE_OR_DOUBLESLASH(str[0].isLetter(), str[0], str[1], QLatin1Char(':'), QLatin1Char('/')) )
155 return str;
156 return QString();
157}
158#endif
159
160bool KUrl::isRelativeUrl(const QString &_url)
161{
162 int len = _url.length();
163 if (!len) return true; // Very short relative URL.
164 const QChar *str = _url.unicode();
165
166 // Absolute URL must start with alpha-character
167 if (!isalpha(str[0].toLatin1()))
168 return true; // Relative URL
169
170 for(int i = 1; i < len; i++)
171 {
172 char c = str[i].toLatin1(); // Note: non-latin1 chars return 0!
173 if (c == ':')
174 return false; // Absolute URL
175
176 // Protocol part may only contain alpha, digit, + or -
177 if (!isalpha(c) && !isdigit(c) && (c != '+') && (c != '-') && (c != '.'))
178 return true; // Relative URL
179 }
180 // URL did not contain ':'
181 return true; // Relative URL
182}
183
184KUrl::List::List(const KUrl &url)
185{
186 append( url );
187}
188
189KUrl::List::List(const QList<KUrl> &list)
190 : QList<KUrl>(list)
191{
192}
193
194KUrl::List::List(const QList<QUrl> &list)
195{
196 foreach(const QUrl& url, list) {
197 append(KUrl(url));
198 }
199}
200
201KUrl::List::List(const QStringList &list)
202{
203 for (QStringList::ConstIterator it = list.begin();
204 it != list.end();
205 ++it)
206 {
207 append( KUrl(*it) );
208 }
209}
210
211QStringList KUrl::List::toStringList() const
212{
213 return toStringList(KUrl::LeaveTrailingSlash);
214}
215
216QStringList KUrl::List::toStringList(KUrl::AdjustPathOption trailing) const
217{
218 QStringList lst;
219 for(KUrl::List::ConstIterator it = constBegin();
220 it != constEnd(); ++it) {
221 lst.append(it->url(trailing));
222 }
223 return lst;
224}
225
226static QByteArray uriListData(const KUrl::List& urls)
227{
228 QList<QByteArray> urlStringList;
229 KUrl::List::ConstIterator uit = urls.constBegin();
230 const KUrl::List::ConstIterator uEnd = urls.constEnd();
231 for (; uit != uEnd ; ++uit) {
232 // Get each URL encoded in utf8 - and since we get it in escaped
233 // form on top of that, .toLatin1() is fine.
234 urlStringList.append((*uit).toMimeDataString().toLatin1());
235 }
236
237 QByteArray uriListData;
238 for (int i = 0, n = urlStringList.count(); i < n; ++i) {
239 uriListData += urlStringList.at(i);
240 if (i < n-1)
241 uriListData += "\r\n";
242 }
243 return uriListData;
244}
245
246static const char s_kdeUriListMime[] = "application/x-kde4-urilist";
247
248void KUrl::List::populateMimeData( QMimeData* mimeData,
249 const KUrl::MetaDataMap& metaData,
250 MimeDataFlags flags ) const
251{
252 mimeData->setData(QString::fromLatin1("text/uri-list"), uriListData(*this));
253
254 if ( ( flags & KUrl::NoTextExport ) == 0 )
255 {
256 QStringList prettyURLsList;
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(); // remove mailto: when pasting into konsole
263 }
264 prettyURLsList.append( prettyURL );
265 }
266
267 QByteArray plainTextData = prettyURLsList.join(QString(QLatin1Char('\n'))).toLocal8Bit();
268 if( count() > 1 ) // terminate last line, unless it's the only line
269 plainTextData.append( "\n" );
270 mimeData->setData( QString::fromLatin1("text/plain"), plainTextData );
271 }
272
273 if ( !metaData.isEmpty() )
274 {
275 QByteArray metaDataData; // :)
276 for( KUrl::MetaDataMap::const_iterator it = metaData.begin(); it != metaData.end(); ++it )
277 {
278 metaDataData += it.key().toUtf8();
279 metaDataData += "$@@$";
280 metaDataData += it.value().toUtf8();
281 metaDataData += "$@@$";
282 }
283 mimeData->setData( QString::fromLatin1("application/x-kio-metadata"), metaDataData );
284 }
285}
286
287
288void KUrl::List::populateMimeData(const KUrl::List& mostLocalUrls,
289 QMimeData* mimeData,
290 const KUrl::MetaDataMap& metaData,
291 MimeDataFlags flags) const
292{
293 // Export the most local urls as text/uri-list and plain text.
294 mostLocalUrls.populateMimeData(mimeData, metaData, flags);
295
296 mimeData->setData(QString::fromLatin1(s_kdeUriListMime), uriListData(*this));
297}
298
299bool KUrl::List::canDecode( const QMimeData *mimeData )
300{
301 return mimeData->hasFormat(QString::fromLatin1("text/uri-list")) ||
302 mimeData->hasFormat(QString::fromLatin1(s_kdeUriListMime));
303}
304
305QStringList KUrl::List::mimeDataTypes()
306{
307 return QStringList() << QString::fromLatin1(s_kdeUriListMime) << QString::fromLatin1("text/uri-list");
308}
309
310
311KUrl::List KUrl::List::fromMimeData(const QMimeData *mimeData,
312 DecodeOptions decodeOptions,
313 KUrl::MetaDataMap* metaData)
314{
315
316 KUrl::List uris;
317 const char* firstMimeType = s_kdeUriListMime;
318 const char* secondMimeType = "text/uri-list";
319 if (decodeOptions == PreferLocalUrls) {
320 qSwap(firstMimeType, secondMimeType);
321 }
322 QByteArray payload = mimeData->data(QString::fromLatin1(firstMimeType));
323 if (payload.isEmpty())
324 payload = mimeData->data(QString::fromLatin1(secondMimeType));
325 if ( !payload.isEmpty() ) {
326 int c = 0;
327 const char* d = payload.constData();
328 while ( c < payload.size() && d[c] ) {
329 int f = c;
330 // Find line end
331 while (c < payload.size() && d[c] && d[c]!='\r'
332 && d[c] != '\n')
333 c++;
334 QByteArray s( d+f, c-f );
335 if ( s[0] != '#' ) // non-comment?
336 uris.append( KUrl::fromMimeDataByteArray( s ) );
337 // Skip junk
338 while ( c < payload.size() && d[c] &&
339 ( d[c] == '\n' || d[c] == '\r' ) )
340 ++c;
341 }
342 }
343 if ( metaData )
344 {
345 const QByteArray metaDataPayload = mimeData->data(QLatin1String("application/x-kio-metadata"));
346 if ( !metaDataPayload.isEmpty() )
347 {
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; // true, then false, then true, etc.
354 QString key;
355 for ( ; it != lst.end(); ++it ) {
356 if ( readingKey )
357 key = *it;
358 else
359 metaData->insert( key, *it );
360 readingKey = !readingKey;
361 }
362 Q_ASSERT( readingKey ); // an odd number of items would be, well, odd ;-)
363 }
364 }
365
366 return uris;
367}
368
369KUrl::List KUrl::List::fromMimeData( const QMimeData *mimeData, KUrl::MetaDataMap* metaData )
370{
371 return fromMimeData(mimeData, PreferKdeUrls, metaData);
372}
373
374KUrl::List::operator QVariant() const
375{
376 return qVariantFromValue(*this);
377}
378
379KUrl::List::operator QList<QUrl>() const
380{
381 QList<QUrl> list;
382 foreach(const KUrl& url, *this) {
383 list << url;
384 }
385 return list;
386}
387
389
390KUrl::KUrl()
391 : QUrl(), d(0)
392{
393}
394
395KUrl::~KUrl()
396{
397}
398
399
400KUrl::KUrl( const QString &str )
401 : QUrl(), d(0)
402{
403 if ( !str.isEmpty() ) {
404#ifdef Q_WS_WIN
405#ifdef DEBUG_KURL
406 kDebug(kurlDebugArea()) << "KUrl::KUrl ( const QString &str = " << str.toLatin1().data() << " )";
407#endif
408 QString pathToSet;
409 // when it starts with file:// it's a url and must be valid. we don't care if the
410 // path exist/ is valid or not
411 if (!str.startsWith(QLatin1String("file://")))
412 pathToSet = removeSlashOrFilePrefix( QDir::fromNativeSeparators(str) );
413 if ( !pathToSet.isEmpty() ) {
414 // we have a prefix indicating this is a local URL
415 // remember the possible query using _setEncodedUrl(), then set up the correct path without query protocol part
416 int index = pathToSet.lastIndexOf(QLatin1Char('?'));
417 if (index == -1)
418 setPath( pathToSet );
419 else {
420 setPath( pathToSet.left( index ) );
421 _setQuery( pathToSet.mid( index + 1 ) );
422 }
423 return;
424 }
425#endif
426 if ( str[0] == QLatin1Char('/') || str[0] == QLatin1Char('~') )
427 setPath( str );
428 else {
429 _setEncodedUrl( str.toUtf8() );
430 }
431 }
432}
433
434KUrl::KUrl( const char * str )
435 : QUrl(), d(0)
436{
437#ifdef Q_WS_WIN
438 // true if @a c is letter
439 #define IS_LETTER(c) \
440 ((c >= QLatin1Char('A') && c <= QLatin1Char('Z')) || (c >= QLatin1Char('a') && c <= QLatin1Char('z')))
441
442 // like IS_DRIVE_OR_DOUBLESLASH, but slash is prepended
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('/')) )
445
446 // like IS_DRIVE_OR_DOUBLESLASH, with characters == str[0] and str[1]
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('/')) )
449
450#if defined(DEBUG_KURL)
451 kDebug(kurlDebugArea()) << "KUrl::KUrl " << " " << str;
452#endif
453 if ( str && str[0] && str[1] && str[2] ) {
454 if ( IS_SLASH_AND_DRIVE_OR_DOUBLESLASH_0 )
455 setPath( QString::fromUtf8( str+1 ) );
456 else if ( IS_DRIVE_OR_DOUBLESLASH_0 )
457 setPath( QString::fromUtf8( str ) );
458 }
459#endif
460 if ( str && str[0] ) {
461 if ( str[0] == '/' || str[0] == '~' )
462 setPath( QString::fromUtf8( str ) );
463 else
464 _setEncodedUrl( str );
465 }
466}
467
468KUrl::KUrl( const QByteArray& str )
469 : QUrl(), d(0)
470{
471 if ( !str.isEmpty() ) {
472#ifdef Q_WS_WIN
473#ifdef DEBUG_KURL
474 kDebug(kurlDebugArea()) << "KUrl::KUrl " << " " << str.data();
475#endif
476 if ( IS_SLASH_AND_DRIVE_OR_DOUBLESLASH_0 )
477 setPath( QString::fromUtf8( str.mid( 1 ) ) );
478 else if ( IS_DRIVE_OR_DOUBLESLASH_0 )
479 setPath( QString::fromUtf8( str ) );
480#else
481 if ( str[0] == '/' || str[0] == '~' )
482 setPath( QString::fromUtf8( str ) );
483#endif
484 else
485 _setEncodedUrl( str );
486 }
487}
488
489KUrl::KUrl( const KUrl& _u )
490 : QUrl( _u ), d(0)
491{
492#if defined(Q_WS_WIN) && defined(DEBUG_KURL)
493 kDebug(kurlDebugArea()) << "KUrl::KUrl(KUrl) " << " path " << _u.path() << " toLocalFile " << _u.toLocalFile();
494#endif
495}
496
497KUrl::KUrl( const QUrl &u )
498 : QUrl( u ), d(0)
499{
500#if defined(Q_WS_WIN) && defined(DEBUG_KURL)
501 kDebug(kurlDebugArea()) << "KUrl::KUrl(Qurl) " << " path " << u.path() << " toLocalFile " << u.toLocalFile();
502#endif
503}
504
505KUrl::KUrl( const KUrl& _u, const QString& _rel_url )
506 : QUrl(), d(0)
507{
508#if defined(Q_WS_WIN) && defined(DEBUG_KURL)
509 kDebug(kurlDebugArea()) << "KUrl::KUrl(KUrl,QString rel_url) " << " path " << _u.path() << " toLocalFile " << _u.toLocalFile();
510#endif
511#if 0
512 if (_u.hasSubUrl()) // Operate on the last suburl, not the first
513 {
514 KUrl::List lst = split( _u );
515 KUrl u(lst.last(), _rel_url);
516 lst.erase( --lst.end() );
517 lst.append( u );
518 *this = join( lst );
519 return;
520 }
521#endif
522 QString rUrl = _rel_url;
523
524 // WORKAROUND THE RFC 1606 LOOPHOLE THAT ALLOWS
525 // http:/index.html AS A VALID SYNTAX FOR RELATIVE
526 // URLS. ( RFC 2396 section 5.2 item # 3 )
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('/'))) )
532 {
533 rUrl.remove( 0, rUrl.indexOf( QLatin1Char(':') ) + 1 );
534 }
535
536
537 if ( rUrl.isEmpty() )
538 {
539 *this = _u;
540 }
541 else if ( rUrl[0] == QLatin1Char('#') )
542 {
543 *this = _u;
544 QByteArray strRef_encoded = rUrl.mid(1).toLatin1();
545 if ( strRef_encoded.isNull() )
546 setFragment(QString::fromLatin1("")); // we know there was an (empty) html ref, we saw the '#'
547 else
548 setFragment(QUrl::fromPercentEncoding(strRef_encoded));
549 }
550 else if ( isRelativeUrl( rUrl ) )
551 {
552 *this = _u;
553 setFragment( QString() );
554 setEncodedQuery( QByteArray() );
555 QString strPath = path();
556 if ( rUrl[0] == QLatin1Char('/') )
557 {
558 if ((rUrl.length() > 1) && (rUrl[1] == QLatin1Char('/')))
559 {
560 setHost( QString() );
561 setPort( -1 );
562 // File protocol returns file:/// without host, strip // from rUrl
563 if ( _u.isLocalFile() )
564 rUrl.remove(0, 2);
565 }
566 strPath.clear();
567 }
568 else if ( rUrl[0] != QLatin1Char('?') )
569 {
570 const int pos = strPath.lastIndexOf( QLatin1Char('/') );
571 if (pos >= 0)
572 strPath.truncate(pos);
573 strPath += QLatin1Char('/');
574 }
575 else
576 {
577 if ( strPath.isEmpty() )
578 strPath = QLatin1Char('/');
579 }
580 setPath( strPath );
581 //kDebug(kurlDebugArea()) << "url()=" << url() << " rUrl=" << rUrl;
582 const KUrl tmp( url() + rUrl);
583 //kDebug(kurlDebugArea()) << "assigning tmp=" << tmp.url();
584 *this = tmp;
585 cleanPath(KeepDirSeparators);
586 }
587 else
588 {
589 const KUrl tmp( rUrl );
590 //kDebug(kurlDebugArea()) << "not relative; assigning tmp=" << tmp.url();
591 *this = tmp;
592 // Preserve userinfo if applicable.
593 if (!_u.userInfo().isEmpty() && userInfo().isEmpty()
594 && (_u.host() == host()) && (_u.scheme() == scheme()))
595 {
596 setUserInfo( _u.userInfo() );
597 }
598 cleanPath(KeepDirSeparators);
599 }
600}
601
602KUrl& KUrl::operator=( const KUrl& _u )
603{
604 QUrl::operator=( _u );
605 return *this;
606}
607
608bool KUrl::operator==( const KUrl& _u ) const
609{
610 return QUrl::operator==( _u );
611}
612
613bool KUrl::operator==( const QString& _u ) const
614{
615 KUrl u( _u );
616 return ( *this == u );
617}
618
619KUrl::operator QVariant() const
620{
621 return qVariantFromValue(*this);
622}
623
624#ifndef KDE_NO_DEPRECATED
625bool KUrl::cmp( const KUrl &u, bool ignore_trailing ) const
626{
627 return equals( u, ignore_trailing ? CompareWithoutTrailingSlash : EqualsOptions(0) );
628}
629#endif
630
631bool KUrl::equals( const KUrl &_u, const EqualsOptions& options ) const
632{
633 if ( !isValid() || !_u.isValid() )
634 return false;
635
636 if ( options & CompareWithoutTrailingSlash || options & CompareWithoutFragment )
637 {
638 QString path1 = path((options & CompareWithoutTrailingSlash) ? RemoveTrailingSlash : LeaveTrailingSlash);
639 QString path2 = _u.path((options & CompareWithoutTrailingSlash) ? RemoveTrailingSlash : LeaveTrailingSlash);
640
641 if (options & AllowEmptyPath) {
642 if (path1 == QLatin1String("/"))
643 path1.clear();
644 if (path2 == QLatin1String("/"))
645 path2.clear();
646 }
647
648#ifdef Q_WS_WIN
649 const bool bLocal1 = isLocalFile();
650 const bool bLocal2 = _u.isLocalFile();
651 if ( !bLocal1 && bLocal2 || bLocal1 && !bLocal2 )
652 return false;
653 // local files are case insensitive
654 if ( bLocal1 && bLocal2 && 0 != QString::compare( path1, path2, Qt::CaseInsensitive ) )
655 return false;
656#endif
657 if ( path1 != path2 )
658 return false;
659
660 if ( scheme() == _u.scheme() &&
661 authority() == _u.authority() && // user+pass+host+port
662 encodedQuery() == _u.encodedQuery() &&
663 (fragment() == _u.fragment() || options & CompareWithoutFragment ) )
664 return true;
665
666 return false;
667 }
668
669 return ( *this == _u );
670}
671
672QString KUrl::protocol() const
673{
674 return scheme().toLower();
675}
676
677void KUrl::setProtocol( const QString& proto )
678{
679 setScheme( proto );
680}
681
682QString KUrl::user() const
683{
684 return userName();
685}
686
687void KUrl::setUser( const QString& user )
688{
689 setUserName( user );
690}
691
692bool KUrl::hasUser() const
693{
694 return !userName().isEmpty();
695}
696
697QString KUrl::pass() const
698{
699 return password();
700}
701
702void KUrl::setPass( const QString& pass )
703{
704 setPassword( pass );
705}
706
707bool KUrl::hasPass() const
708{
709 return !password().isEmpty();
710}
711
712bool KUrl::hasHost() const
713{
714 return !host().isEmpty();
715}
716
717bool KUrl::hasPath() const
718{
719 return !path().isEmpty();
720}
721
722KUrl KUrl::fromPath( const QString& text )
723{
724 KUrl u;
725 u.setPath( text );
726 return u;
727}
728
729void KUrl::setFileName( const QString& _txt )
730{
731 setFragment( QString() );
732 int i = 0;
733 while( i < _txt.length() && _txt[i] == QLatin1Char('/') )
734 ++i;
735 QString tmp = i ? _txt.mid( i ) : _txt;
736
737 QString path = this->path();
738 if ( path.isEmpty() )
739#ifdef Q_OS_WIN
740 path = isLocalFile() ? QDir::rootPath() : QLatin1String("/");
741#else
742 path = QDir::rootPath();
743#endif
744 else
745 {
746 int lastSlash = path.lastIndexOf( QLatin1Char('/') );
747 if ( lastSlash == -1)
748 path.clear(); // there's only the file name, remove it
749 else if ( !path.endsWith( QLatin1Char('/') ) )
750 path.truncate( lastSlash+1 ); // keep the "/"
751 }
752
753 path += tmp;
754 setPath( path );
755
756 cleanPath();
757}
758
759void KUrl::cleanPath( const CleanPathOption& options )
760{
761 //if (m_iUriMode != URL) return;
762 const QString newPath = cleanpath(path(), !(options & KeepDirSeparators), false);
763 if ( path() != newPath )
764 setPath( newPath );
765 // WABA: Is this safe when "/../" is encoded with %?
766 //m_strPath_encoded = cleanpath(m_strPath_encoded, cleanDirSeparator, true);
767}
768
769static QString trailingSlash( KUrl::AdjustPathOption trailing, const QString &path )
770{
771 if ( trailing == KUrl::LeaveTrailingSlash ) {
772 return path;
773 }
774
775 QString result = path;
776
777 if ( trailing == KUrl::AddTrailingSlash )
778 {
779 int len = result.length();
780 if ((len > 0) && (result[ len - 1 ] != QLatin1Char('/')))
781 result += QLatin1Char('/');
782 return result;
783 }
784 else if ( trailing == KUrl::RemoveTrailingSlash )
785 {
786 if ( result == QLatin1String("/") )
787 return result;
788 int len = result.length();
789 while (len > 1 && result[ len - 1 ] == QLatin1Char('/'))
790 {
791 len--;
792 }
793 result.truncate( len );
794 return result;
795 }
796 else {
797 assert( 0 );
798 return result;
799 }
800}
801
802void KUrl::adjustPath( AdjustPathOption trailing )
803{
804#if 0
805 if (!m_strPath_encoded.isEmpty())
806 {
807 m_strPath_encoded = trailingSlash( _trailing, m_strPath_encoded );
808 }
809#endif
810 const QString newPath = trailingSlash( trailing, path() );
811 if ( path() != newPath )
812 setPath( newPath );
813}
814
815
816QString KUrl::encodedPathAndQuery( AdjustPathOption trailing , const EncodedPathAndQueryOptions &options) const
817{
818 QString encodedPath;
819#ifdef Q_OS_WIN
820 // see KUrl::path()
821 if (isLocalFile()) {
822 // ### this is probably broken
823 encodedPath = trailingSlash(trailing, QUrl::toLocalFile());
824 encodedPath = QString::fromLatin1(QUrl::toPercentEncoding(encodedPath, "!$&'()*+,;=:@/"));
825 } else {
826 encodedPath = trailingSlash(trailing, QString::fromLatin1(QUrl::encodedPath()));
827 }
828#else
829 encodedPath = trailingSlash(trailing, QString::fromLatin1(QUrl::encodedPath()));
830#endif
831
832 if ((options & AvoidEmptyPath) && encodedPath.isEmpty()) {
833 encodedPath.append(QLatin1Char('/'));
834 }
835
836 if (hasQuery()) {
837 return encodedPath + QLatin1Char('?') + QString::fromLatin1(encodedQuery());
838 } else {
839 return encodedPath;
840 }
841}
842
843#if 0
844void KUrl::setEncodedPath( const QString& _txt, int encoding_hint )
845{
846 m_strPath_encoded = _txt;
847
848 decode( m_strPath_encoded, m_strPath, m_strPath_encoded, encoding_hint );
849 // Throw away encoding for local files, makes file-operations faster.
850 if (m_strProtocol == "file")
851 m_strPath_encoded.clear();
852
853 if ( m_iUriMode == Auto )
854 m_iUriMode = URL;
855}
856#endif
857
858void KUrl::setEncodedPathAndQuery( const QString& _txt )
859{
860 const int pos = _txt.indexOf(QLatin1Char('?'));
861 if ( pos == -1 )
862 {
863 setPath( QUrl::fromPercentEncoding( _txt.toLatin1() ) );
864 setEncodedQuery( QByteArray() );
865 }
866 else
867 {
868 setPath( QUrl::fromPercentEncoding(_txt.toLatin1().left(pos)) );
869 _setQuery( _txt.right( _txt.length() - pos - 1 ) );
870 }
871}
872
873QString KUrl::path( AdjustPathOption trailing ) const
874{
875#ifdef Q_WS_WIN
876#ifdef DEBUG_KURL
877 kWarning() << (isLocalFile() ? "converted to local file - the related call should be converted to toLocalFile()" : "") << QUrl::path();
878#endif
879 return trailingSlash( trailing, isLocalFile() ? QUrl::toLocalFile() : QUrl::path() );
880#else
881 return trailingSlash( trailing, QUrl::path() );
882#endif
883}
884
885QString KUrl::toLocalFile( AdjustPathOption trailing ) const
886{
887 if (hasHost() && isLocalFile()) {
888 KUrl urlWithoutHost(*this);
889 urlWithoutHost.setHost(QString());
890 return trailingSlash(trailing, urlWithoutHost.toLocalFile());
891 }
892#ifdef __GNUC__
893#warning FIXME: Remove #ifdef below once upstream bug, QTBUG-20322, is fixed. Also see BR# 194746.
894#endif
895#ifndef Q_WS_WIN
896 if (isLocalFile()) {
897 return trailingSlash(trailing, QUrl::path());
898 }
899#endif
900 return trailingSlash(trailing, QUrl::toLocalFile());
901}
902
903inline static bool hasSubUrl( const QUrl& url );
904
905static inline bool isLocalFile( const QUrl& url )
906{
907 if ( url.scheme().compare(QLatin1String("file"), Qt::CaseInsensitive) != 0 || hasSubUrl( url ) )
908 return false;
909
910 if (url.host().isEmpty() || (url.host() == QLatin1String("localhost")))
911 return true;
912
913 char hostname[ 256 ];
914 hostname[ 0 ] = '\0';
915 if (!gethostname( hostname, 255 ))
916 hostname[sizeof(hostname)-1] = '\0';
917
918 for(char *p = hostname; *p; p++)
919 *p = tolower(*p);
920
921 return (url.host() == QString::fromLatin1( hostname ));
922}
923
924bool KUrl::isLocalFile() const
925{
926 return ::isLocalFile( *this );
927}
928
929void KUrl::setFileEncoding(const QString &encoding)
930{
931 if (!isLocalFile())
932 return;
933
934 QString q = query();
935
936 if (!q.isEmpty() && q[0] == QLatin1Char('?'))
937 q = q.mid(1);
938
939 QStringList args = q.split(QLatin1Char('&'), QString::SkipEmptyParts);
940 for(QStringList::Iterator it = args.begin();
941 it != args.end();)
942 {
943 QString s = QUrl::fromPercentEncoding( (*it).toLatin1() );
944 if (s.startsWith(QLatin1String("charset=")))
945 it = args.erase(it);
946 else
947 ++it;
948 }
949 if (!encoding.isEmpty())
950 args.append(QLatin1String("charset=") + QString::fromLatin1(QUrl::toPercentEncoding(encoding)));
951
952 if (args.isEmpty())
953 _setQuery(QString());
954 else
955 _setQuery(args.join(QString(QLatin1Char('&'))));
956}
957
958QString KUrl::fileEncoding() const
959{
960 if (!isLocalFile())
961 return QString();
962
963 QString q = query();
964
965 if (q.isEmpty())
966 return QString();
967
968 if (q[0] == QLatin1Char('?'))
969 q = q.mid(1);
970
971 const QStringList args = q.split(QLatin1Char('&'), QString::SkipEmptyParts);
972 for(QStringList::ConstIterator it = args.begin();
973 it != args.end();
974 ++it)
975 {
976 QString s = QUrl::fromPercentEncoding((*it).toLatin1());
977 if (s.startsWith(QLatin1String("charset=")))
978 return s.mid(8);
979 }
980 return QString();
981}
982
983inline static bool hasSubUrl( const QUrl& url )
984{
985 // The isValid call triggers QUrlPrivate::validate which needs the full encoded url,
986 // all this takes too much time for isLocalFile()
987 const QString scheme = url.scheme();
988 if ( scheme.isEmpty() /*|| !isValid()*/ )
989 return false;
990 const QString ref( url.fragment() );
991 if (ref.isEmpty())
992 return false;
993 switch ( ref.at(0).unicode() ) {
994 case 'g':
995 if ( ref.startsWith(QLatin1String("gzip:")) )
996 return true;
997 break;
998 case 'b':
999 if ( ref.startsWith(QLatin1String("bzip:")) || ref.startsWith(QLatin1String("bzip2:")) )
1000 return true;
1001 break;
1002 case 'l':
1003 if ( ref.startsWith(QLatin1String("lzma:")) )
1004 return true;
1005 break;
1006 case 'x':
1007 if ( ref.startsWith(QLatin1String("xz:")) )
1008 return true;
1009 break;
1010 case 't':
1011 if ( ref.startsWith(QLatin1String("tar:")) )
1012 return true;
1013 break;
1014 case 'a':
1015 if ( ref.startsWith(QLatin1String("ar:")) )
1016 return true;
1017 break;
1018 case 'z':
1019 if ( ref.startsWith(QLatin1String("zip:")) )
1020 return true;
1021 break;
1022 default:
1023 break;
1024 }
1025 if ( scheme == QLatin1String("error") ) // anything that starts with error: has suburls
1026 return true;
1027 return false;
1028}
1029
1030bool KUrl::hasSubUrl() const
1031{
1032 return ::hasSubUrl( *this );
1033}
1034
1035QString KUrl::url( AdjustPathOption trailing ) const
1036{
1037 if (QString::compare(scheme(), QLatin1String("mailto"), Qt::CaseInsensitive) == 0) {
1038 // mailto urls should be prettified, see the url183433 testcase.
1039 return prettyUrl(trailing);
1040 }
1041 if ( trailing == AddTrailingSlash && !path().endsWith( QLatin1Char('/') ) ) {
1042 // -1 and 0 are provided by QUrl, but not +1, so that one is a bit tricky.
1043 // To avoid reimplementing toEncoded() all over again, I just use another QUrl
1044 // Let's hope this is fast, or not called often...
1045 QUrl newUrl( *this );
1046 newUrl.setPath( path() + QLatin1Char('/') );
1047 return QString::fromLatin1(newUrl.toEncoded());
1048 }
1049 else if ( trailing == RemoveTrailingSlash) {
1050 const QString cleanedPath = trailingSlash(trailing, path());
1051 if (cleanedPath == QLatin1String("/")) {
1052 if (path() != QLatin1String("/")) {
1053 QUrl fixedUrl = *this;
1054 fixedUrl.setPath(cleanedPath);
1055 return QLatin1String(fixedUrl.toEncoded(None));
1056 }
1057 return QLatin1String(toEncoded(None));
1058 }
1059 }
1060 return QString::fromLatin1(toEncoded(trailing == RemoveTrailingSlash ? StripTrailingSlash : None));
1061}
1062
1063static QString toPrettyPercentEncoding(const QString &input, bool forFragment)
1064{
1065 QString result;
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();
1070 if (u < 0x20
1071 || (!forFragment && u == '?') // don't escape '?' in fragments, not needed and wrong (#173101)
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]);
1078 } else {
1079 result += c;
1080 }
1081 }
1082
1083 return result;
1084}
1085
1086QString KUrl::prettyUrl( AdjustPathOption trailing ) const
1087{
1088 // reconstruct the URL in a "pretty" form
1089 // a "pretty" URL is NOT suitable for data transfer. It's only for showing data to the user.
1090 // however, it must be parseable back to its original state, since
1091 // notably Konqueror displays it in the Location address.
1092
1093 // A pretty URL is the same as a normal URL, except that:
1094 // - the password is removed
1095 // - the hostname is shown in Unicode (as opposed to ACE/Punycode)
1096 // - the pathname and fragment parts are shown in Unicode (as opposed to %-encoding)
1097 QString result = scheme();
1098 if (!result.isEmpty())
1099 {
1100 if (!authority().isEmpty() || result == QLatin1String("file") || (path().isEmpty()
1101 && scheme().compare(QLatin1String("mailto"), Qt::CaseInsensitive) != 0))
1102 result += QLatin1String("://");
1103 else
1104 result += QLatin1Char(':');
1105 }
1106
1107 QString tmp = userName();
1108 if (!tmp.isEmpty()) {
1109 result += QString::fromLatin1(QUrl::toPercentEncoding(tmp));
1110 result += QLatin1Char('@');
1111 }
1112
1113 // Check if host is an ipv6 address
1114 tmp = host();
1115 if (tmp.contains(QLatin1Char(':')))
1116 result += QLatin1Char('[') + tmp + QLatin1Char(']');
1117 else
1118 result += tmp;
1119
1120 if (port() != -1) {
1121 result += QLatin1Char(':');
1122 result += QString::number(port());
1123 }
1124
1125 tmp = path();
1126#ifdef Q_WS_WIN
1127 if (isLocalFile())
1128 tmp.prepend(QLatin1Char('/')); // KUrl::path() returns toLocalFile() on windows so we need to add the / back to create a proper url
1129#endif
1130 result += toPrettyPercentEncoding(tmp, false);
1131
1132 // adjust the trailing slash, if necessary
1133 if (trailing == AddTrailingSlash && !tmp.endsWith(QLatin1Char('/')))
1134 result += QLatin1Char('/');
1135 else if (trailing == RemoveTrailingSlash && tmp.length() > 1 && tmp.endsWith(QLatin1Char('/')))
1136 result.chop(1);
1137
1138 if (hasQuery()) {
1139 result += QLatin1Char('?');
1140 result += QString::fromLatin1(encodedQuery());
1141 }
1142
1143 if (hasFragment()) {
1144 result += QLatin1Char('#');
1145 result += toPrettyPercentEncoding(fragment(), true);
1146 }
1147
1148 return result;
1149}
1150
1151#if 0
1152QString KUrl::prettyUrl( int _trailing, AdjustementFlags _flags) const
1153{
1154 QString u = prettyUrl(_trailing);
1155 if (_flags & StripFileProtocol && u.startsWith("file://")) {
1156 u.remove(0, 7);
1157#ifdef Q_WS_WIN
1158 return QDir::convertSeparators(u);
1159#endif
1160 }
1161 return u;
1162}
1163#endif
1164
1165QString KUrl::pathOrUrl() const
1166{
1167 return pathOrUrl(LeaveTrailingSlash);
1168}
1169
1170QString KUrl::pathOrUrl(AdjustPathOption trailing) const
1171{
1172 if ( isLocalFile() && fragment().isNull() && encodedQuery().isNull() ) {
1173 return toLocalFile(trailing);
1174 } else {
1175 return prettyUrl(trailing);
1176 }
1177}
1178
1179// Used for text/uri-list in the mime data
1180QString KUrl::toMimeDataString() const // don't fold this into populateMimeData, it's also needed by other code like konqdrag
1181{
1182 if ( isLocalFile() )
1183 {
1184#if 1
1185 return url();
1186#else
1187 // According to the XDND spec, file:/ URLs for DND must have
1188 // the hostname part. But in really it just breaks many apps,
1189 // so it's disabled for now.
1190 const QString s = url( 0, KGlobal::locale()->fileEncodingMib() );
1191 if( !s.startsWith( QLatin1String ( "file://" ) ))
1192 {
1193 char hostname[257];
1194 if ( gethostname( hostname, 255 ) == 0 )
1195 {
1196 hostname[256] = '\0';
1197 return QString( "file://" ) + hostname + s.mid( 5 );
1198 }
1199 }
1200#endif
1201 }
1202
1203 if (hasPass()) {
1204 KUrl safeUrl(*this);
1205 safeUrl.setPassword(QString());
1206 return safeUrl.url();
1207 }
1208 return url();
1209}
1210
1211KUrl KUrl::fromMimeDataByteArray( const QByteArray& str )
1212{
1213 if ( str.startsWith( "file:" ) ) // krazy:exclude=strings
1214 return KUrl( str /*, QTextCodec::codecForLocale()->mibEnum()*/ );
1215
1216 return KUrl( str /*, 106*/ ); // 106 is mib enum for utf8 codec;
1217}
1218
1219KUrl::List KUrl::split( const KUrl& _url )
1220{
1221 QString ref;
1222 bool hasRef;
1223 KUrl::List lst;
1224 KUrl url = _url;
1225
1226 while(true)
1227 {
1228 KUrl u = url;
1229 u.setFragment( QString() );
1230 lst.append(u);
1231 if (url.hasSubUrl())
1232 {
1233 url = KUrl(url.fragment());
1234 }
1235 else
1236 {
1237 ref = url.fragment();
1238 hasRef = url.hasFragment();
1239 break;
1240 }
1241 }
1242
1243 if ( hasRef )
1244 {
1245 // Set HTML ref in all URLs.
1246 KUrl::List::Iterator it;
1247 for( it = lst.begin() ; it != lst.end(); ++it )
1248 {
1249 (*it).setFragment( ref );
1250 }
1251 }
1252
1253 return lst;
1254}
1255
1256KUrl::List KUrl::split( const QString& _url )
1257{
1258 return split(KUrl(_url));
1259}
1260
1261KUrl KUrl::join( const KUrl::List & lst )
1262{
1263 if (lst.isEmpty()) return KUrl();
1264 KUrl tmp;
1265
1266 bool first = true;
1267 QListIterator<KUrl> it(lst);
1268 it.toBack();
1269 while (it.hasPrevious())
1270 {
1271 KUrl u(it.previous());
1272 if (!first) {
1273 u.setEncodedFragment(tmp.url().toLatin1() /* TODO double check encoding */);
1274 }
1275 tmp = u;
1276
1277 first = false;
1278 }
1279
1280 return tmp;
1281}
1282
1283QString KUrl::fileName( const DirectoryOptions& options ) const
1284{
1285 Q_ASSERT( options != 0 ); //Disallow options == false
1286 QString fname;
1287 if (hasSubUrl()) { // If we have a suburl, then return the filename from there
1288 const KUrl::List list = KUrl::split(*this);
1289 return list.last().fileName(options);
1290 }
1291 const QString path = this->path();
1292
1293 int len = path.length();
1294 if ( len == 0 )
1295 return fname;
1296
1297 if (!(options & ObeyTrailingSlash) )
1298 {
1299 while ( len >= 1 && path[ len - 1 ] == QLatin1Char('/') )
1300 len--;
1301 }
1302 else if ( path[ len - 1 ] == QLatin1Char('/') )
1303 return fname;
1304
1305 // Does the path only consist of '/' characters ?
1306 if ( len == 1 && path[ 0 ] == QLatin1Char('/') )
1307 return fname;
1308
1309 // Skip last n slashes
1310 int n = 1;
1311#if 0
1312 if (!m_strPath_encoded.isEmpty())
1313 {
1314 // This is hairy, we need the last unencoded slash.
1315 // Count in the encoded string how many encoded slashes follow the last
1316 // unencoded one.
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);
1320 }
1321#endif
1322 int i = len;
1323 do {
1324 i = path.lastIndexOf( QLatin1Char('/'), i - 1 );
1325 }
1326 while (--n && (i > 0));
1327
1328 // If ( i == -1 ) => the first character is not a '/'
1329 // So it's some URL like file:blah.tgz, return the whole path
1330 if ( i == -1 ) {
1331 if ( len == (int)path.length() )
1332 fname = path;
1333 else
1334 // Might get here if _strip_trailing_slash is true
1335 fname = path.left( len );
1336 }
1337 else
1338 {
1339 fname = path.mid( i + 1, len - i - 1 ); // TO CHECK
1340 }
1341 return fname;
1342}
1343
1344void KUrl::addPath( const QString& _txt )
1345{
1346 if (hasSubUrl())
1347 {
1348 KUrl::List lst = split( *this );
1349 KUrl &u = lst.last();
1350 u.addPath(_txt);
1351 *this = join( lst );
1352 return;
1353 }
1354
1355 //m_strPath_encoded.clear();
1356
1357 if ( _txt.isEmpty() )
1358 return;
1359
1360 QString strPath = path();
1361 int i = 0;
1362 int len = strPath.length();
1363 // Add the trailing '/' if it is missing
1364 if ( _txt[0] != QLatin1Char('/') && ( len == 0 || strPath[ len - 1 ] != QLatin1Char('/') ) )
1365 strPath += QLatin1Char('/');
1366
1367 // No double '/' characters
1368 i = 0;
1369 const int _txtlen = _txt.length();
1370 if ( strPath.endsWith( QLatin1Char('/') ) )
1371 {
1372 while ( ( i < _txtlen ) && ( _txt[i] == QLatin1Char('/') ) )
1373 ++i;
1374 }
1375
1376 setPath( strPath + _txt.mid( i ) );
1377 //kDebug(kurlDebugArea())<<"addPath: resultpath="<<path();
1378}
1379
1380QString KUrl::directory( const DirectoryOptions& options ) const
1381{
1382 Q_ASSERT( options != 0 ); //Disallow options == false
1383 QString result = path(); //m_strPath_encoded.isEmpty() ? m_strPath : m_strPath_encoded;
1384 if ( !(options & ObeyTrailingSlash) )
1385 result = trailingSlash( RemoveTrailingSlash, result );
1386
1387 if ( result.isEmpty() || result == QLatin1String ( "/" ) )
1388 return result;
1389
1390 int i = result.lastIndexOf( QLatin1Char('/') );
1391 // If ( i == -1 ) => the first character is not a '/'
1392 // So it's some URL like file:blah.tgz, with no path
1393 if ( i == -1 )
1394 return QString();
1395
1396 if ( i == 0 )
1397 {
1398 return QString(QLatin1Char('/'));
1399 }
1400
1401#ifdef Q_WS_WIN
1402 if ( i == 2 && result[1] == QLatin1Char(':') )
1403 {
1404 return result.left(3);
1405 }
1406#endif
1407
1408 if ( options & AppendTrailingSlash )
1409 result = result.left( i + 1 );
1410 else
1411 result = result.left( i );
1412
1413 //if (!m_strPath_encoded.isEmpty())
1414 // result = decode(result);
1415
1416 return result;
1417}
1418
1419
1420bool KUrl::cd( const QString& _dir )
1421{
1422 if ( _dir.isEmpty() || !isValid() )
1423 return false;
1424
1425 if (hasSubUrl())
1426 {
1427 KUrl::List lst = split( *this );
1428 KUrl &u = lst.last();
1429 u.cd(_dir);
1430 *this = join( lst );
1431 return true;
1432 }
1433
1434 // absolute path ?
1435#ifdef Q_OS_WIN
1436 if ( !QFileInfo(_dir).isRelative() )
1437#else
1438 if ( _dir[0] == QLatin1Char('/') )
1439#endif
1440 {
1441 //m_strPath_encoded.clear();
1442 setPath( _dir );
1443 setHTMLRef( QString() );
1444 setEncodedQuery( QByteArray() );
1445 return true;
1446 }
1447
1448 // Users home directory on the local disk ?
1449 if (_dir[0] == QLatin1Char('~') && scheme() == QLatin1String ("file"))
1450 {
1451 //m_strPath_encoded.clear();
1452 QString strPath = QDir::homePath();
1453 strPath += QLatin1Char('/');
1454 strPath += _dir.right( strPath.length() - 1 );
1455 setPath( strPath );
1456 setHTMLRef( QString() );
1457 setEncodedQuery( QByteArray() );
1458 return true;
1459 }
1460
1461 // relative path
1462 // we always work on the past of the first url.
1463 // Sub URLs are not touched.
1464
1465 // append '/' if necessary
1466 QString p = path(AddTrailingSlash);
1467 p += _dir;
1468 p = cleanpath( p, true, false );
1469 setPath( p );
1470
1471 setHTMLRef( QString() );
1472 setEncodedQuery( QByteArray() );
1473
1474 return true;
1475}
1476
1477KUrl KUrl::upUrl( ) const
1478{
1479 if (!isValid() || isRelative())
1480 return KUrl();
1481
1482 if (!encodedQuery().isEmpty())
1483 {
1484 KUrl u(*this);
1485 u.setEncodedQuery(QByteArray());
1486 return u;
1487 }
1488
1489 if (!hasSubUrl())
1490 {
1491 KUrl u(*this);
1492 u.cd(QLatin1String("../"));
1493 return u;
1494 }
1495
1496 // We have a subURL.
1497 KUrl::List lst = split( *this );
1498 if (lst.isEmpty())
1499 return KUrl(); // Huh?
1500 while (true)
1501 {
1502 KUrl &u = lst.last();
1503 const QString old = u.path();
1504 u.cd(QLatin1String("../"));
1505 if (u.path() != old)
1506 break; // Finished.
1507 if (lst.count() == 1)
1508 break; // Finished.
1509 lst.removeLast();
1510 }
1511 return join( lst );
1512}
1513
1514QString KUrl::htmlRef() const
1515{
1516 if ( !hasSubUrl() )
1517 {
1518 return fragment();
1519 }
1520
1521 const List lst = split( *this );
1522 return (*lst.begin()).fragment();
1523}
1524
1525QString KUrl::encodedHtmlRef() const
1526{
1527 if ( !hasSubUrl() )
1528 {
1529 return ref();
1530 }
1531
1532 const List lst = split( *this );
1533 return (*lst.begin()).ref();
1534}
1535
1536void KUrl::setHTMLRef( const QString& _ref )
1537{
1538 if ( !hasSubUrl() )
1539 {
1540 setFragment( _ref );
1541 return;
1542 }
1543
1544 List lst = split( *this );
1545
1546 (*lst.begin()).setFragment( _ref );
1547
1548 *this = join( lst );
1549}
1550
1551bool KUrl::hasHTMLRef() const
1552{
1553 if ( !hasSubUrl() )
1554 {
1555 return hasRef();
1556 }
1557
1558 const List lst = split( *this );
1559 return (*lst.begin()).hasRef();
1560}
1561
1562void KUrl::setDirectory( const QString &dir)
1563{
1564 if ( dir.endsWith(QLatin1Char('/')))
1565 setPath(dir);
1566 else
1567 setPath(dir + QLatin1Char('/'));
1568}
1569
1570void KUrl::setQuery( const QString &_txt )
1571{
1572 if (!_txt.isEmpty() && _txt[0] == QLatin1Char('?'))
1573 _setQuery( _txt.length() > 1 ? _txt.mid(1) : QString::fromLatin1("") /*empty, not null*/ );
1574 else
1575 _setQuery( _txt );
1576}
1577
1578void KUrl::_setQuery( const QString& query )
1579{
1580 if ( query.isNull() ) {
1581 setEncodedQuery( QByteArray() );
1582 } else if ( query.isEmpty() ) {
1583 setEncodedQuery("");
1584 } else {
1585 setEncodedQuery( query.toLatin1() ); // already percent-escaped, so toLatin1 is ok
1586 }
1587}
1588
1589QString KUrl::query() const
1590{
1591 if (!hasQuery()) {
1592 return QString();
1593 }
1594 return QString(QLatin1Char('?')) + QString::fromLatin1(encodedQuery());
1595}
1596
1597void KUrl::_setEncodedUrl(const QByteArray& url)
1598{
1599 setEncodedUrl(url, QUrl::TolerantMode);
1600 if (!isValid()) // see unit tests referring to N183630/task 183874
1601 setUrl(QString::fromUtf8(url), QUrl::TolerantMode);
1602}
1603
1604#ifndef KDE_NO_DEPRECATED
1605bool urlcmp( const QString& _url1, const QString& _url2 )
1606{
1607 return QUrl( _url1, QUrl::TolerantMode ) == QUrl( _url2, QUrl::TolerantMode );
1608#if 0
1609 // Both empty ?
1610 if ( _url1.isEmpty() && _url2.isEmpty() )
1611 return true;
1612 // Only one empty ?
1613 if ( _url1.isEmpty() || _url2.isEmpty() )
1614 return false;
1615
1616 KUrl::List list1 = KUrl::split( _url1 );
1617 KUrl::List list2 = KUrl::split( _url2 );
1618
1619 // Malformed ?
1620 if ( list1.isEmpty() || list2.isEmpty() )
1621 return false;
1622
1623 return ( list1 == list2 );
1624#endif
1625}
1626#endif
1627
1628#ifndef KDE_NO_DEPRECATED
1629bool urlcmp( const QString& _url1, const QString& _url2, const KUrl::EqualsOptions& _options )
1630{
1631 // Both empty ?
1632 if (_url1.isEmpty() && _url2.isEmpty())
1633 return true;
1634 // Only one empty ?
1635 if (_url1.isEmpty() || _url2.isEmpty())
1636 return false;
1637
1638 KUrl u1(_url1);
1639 KUrl u2(_url2);
1640 return u1.equals(u2, _options);
1641
1642#if 0 // kde3 code that supported nested urls
1643
1644 KUrl::List list1 = KUrl::split( _url1 );
1645 KUrl::List list2 = KUrl::split( _url2 );
1646
1647 // Malformed ?
1648 if ( list1.isEmpty() || list2.isEmpty() )
1649 return false;
1650
1651 int size = list1.count();
1652 if ( list2.count() != size )
1653 return false;
1654
1655 if ( _ignore_ref )
1656 {
1657 (*list1.begin()).setRef(QString());
1658 (*list2.begin()).setRef(QString());
1659 }
1660
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 ) )
1665 return false;
1666 return true;
1667#endif
1668}
1669#endif
1670
1671// static
1672#ifndef KDE_NO_DEPRECATED
1673KUrl KUrl::fromPathOrUrl( const QString& text )
1674{
1675 KUrl url;
1676 if ( !text.isEmpty() )
1677 {
1678 if (!QDir::isRelativePath(text) || text[0] == QLatin1Char('~'))
1679 url.setPath( text );
1680 else
1681 url = KUrl( text );
1682 }
1683
1684 return url;
1685}
1686#endif
1687
1688static QString _relativePath(const QString &base_dir, const QString &path, bool &isParent)
1689{
1690 QString _base_dir(QDir::cleanPath(base_dir));
1691 QString _path(QDir::cleanPath(path.isEmpty() || QDir::isRelativePath(path) ? _base_dir+QLatin1Char('/')+path : path));
1692
1693 if (_base_dir.isEmpty())
1694 return _path;
1695
1696 if (_base_dir[_base_dir.length()-1] != QLatin1Char('/'))
1697 _base_dir.append(QLatin1Char('/') );
1698
1699 const QStringList list1 = _base_dir.split(QLatin1Char('/'), QString::SkipEmptyParts);
1700 const QStringList list2 = _path.split(QLatin1Char('/'), QString::SkipEmptyParts);
1701
1702 // Find where they meet
1703 int level = 0;
1704 int maxLevel = qMin(list1.count(), list2.count());
1705 while((level < maxLevel) && (list1[level] == list2[level])) level++;
1706
1707 QString result;
1708 // Need to go down out of the first path to the common branch.
1709 for(int i = level; i < list1.count(); i++)
1710 result.append(QLatin1String("../"));
1711
1712 // Now up up from the common branch to the second path.
1713 for(int i = level; i < list2.count(); i++)
1714 result.append(list2[i]).append(QLatin1Char('/'));
1715
1716 if ((level < list2.count()) && (path[path.length()-1] != QLatin1Char('/')))
1717 result.truncate(result.length()-1);
1718
1719 isParent = (level == list1.count());
1720
1721 return result;
1722}
1723
1724QString KUrl::relativePath(const QString &base_dir, const QString &path, bool *isParent)
1725{
1726 bool parent = false;
1727 QString result = _relativePath(base_dir, path, parent);
1728 if (parent)
1729 result.prepend(QLatin1String("./"));
1730
1731 if (isParent)
1732 *isParent = parent;
1733
1734 return result;
1735}
1736
1737
1738QString KUrl::relativeUrl(const KUrl &base_url, const KUrl &url)
1739{
1740 if ((url.protocol() != base_url.protocol()) ||
1741 (url.host() != base_url.host()) ||
1742 (url.port() && url.port() != base_url.port()) ||
1743 (url.hasUser() && url.user() != base_url.user()) ||
1744 (url.hasPass() && url.pass() != base_url.pass()))
1745 {
1746 return url.url();
1747 }
1748
1749 QString relURL;
1750
1751 if ((base_url.path() != url.path()) || (base_url.query() != url.query()))
1752 {
1753 bool dummy;
1754 QString basePath = base_url.directory(KUrl::ObeyTrailingSlash);
1755 static const char s_pathExcludeChars[] = "!$&'()*+,;=:@/";
1756 relURL = QString::fromLatin1(QUrl::toPercentEncoding(_relativePath(basePath, url.path(), dummy), s_pathExcludeChars));
1757 relURL += url.query();
1758 }
1759
1760 if ( url.hasRef() )
1761 {
1762 relURL += QLatin1Char('#');
1763 relURL += url.ref();
1764 }
1765
1766 if ( relURL.isEmpty() )
1767 return QLatin1String("./");
1768
1769 return relURL;
1770}
1771
1772void KUrl::setPath( const QString& _path )
1773{
1774#if defined(Q_WS_WIN) && defined(DEBUG_KURL)
1775 kDebug(kurlDebugArea()) << "KUrl::setPath " << " " << _path.toLatin1().data();
1776#endif
1777 if ( scheme().isEmpty() )
1778 setScheme( QLatin1String( "file" ) );
1779 QString path = KShell::tildeExpand( _path );
1780 if (path.isEmpty())
1781 path = _path;
1782#ifdef Q_WS_WIN
1783 const int len = path.length();
1784 if( len == 2 && IS_LETTER(path[0]) && path[1] == QLatin1Char(':') )
1785 path += QLatin1Char('/');
1786 //This is necessary because QUrl has the "path" part including the first slash
1787 //Without this QUrl doesn't understand that this is a path, and some operations fail
1788 //e.g. C:/blah needs to become /C:/blah
1789 else
1790 if( len > 0 && path[0] != QLatin1Char('/') && scheme() == QLatin1String( "file" ) )
1791 path = QLatin1Char('/') + path;
1792#endif
1793 QUrl::setPath( path );
1794}
1795
1796#if 0 // this would be if we didn't decode '+' into ' '
1797QMap< QString, QString > KUrl::queryItems( int options ) const {
1798 QMap< QString, QString > result;
1799 const QList<QPair<QString, QString> > items = QUrl::queryItems();
1800 QPair<QString, QString> item;
1801 Q_FOREACH( item, items ) {
1802 result.insert( options & CaseInsensitiveKeys ? item.first.toLower() : item.first, item.second );
1803 }
1804 return result;
1805}
1806#endif
1807
1808QMap< QString, QString > KUrl::queryItems( const QueryItemsOptions &options ) const
1809{
1810 const QString strQueryEncoded = QString::fromLatin1(encodedQuery());
1811 if ( strQueryEncoded.isEmpty() )
1812 return QMap<QString,QString>();
1813
1814 QMap< QString, QString > result;
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 ) { // = is not the first char...
1819 QString name = (*it).left( equal_pos );
1820 if ( options & CaseInsensitiveKeys )
1821 name = name.toLower();
1822 QString value = (*it).mid( equal_pos + 1 );
1823 if ( value.isEmpty() )
1824 result.insert( name, QString::fromLatin1("") );
1825 else {
1826 // ### why is decoding name not necessary?
1827 value.replace( QLatin1Char('+'), QLatin1Char(' ') ); // + in queries means space
1828 result.insert( name, QUrl::fromPercentEncoding( value.toLatin1() ) );
1829 }
1830 } else if ( equal_pos < 0 ) { // no =
1831 QString name = (*it);
1832 if ( options & CaseInsensitiveKeys )
1833 name = name.toLower();
1834 result.insert( name, QString() );
1835 }
1836 }
1837
1838 return result;
1839}
1840
1841QString KUrl::queryItem( const QString& _item ) const
1842{
1843 const QString strQueryEncoded = QString::fromLatin1(encodedQuery());
1844 const QString item = _item + QLatin1Char('=');
1845 if ( strQueryEncoded.length() <= 1 )
1846 return QString();
1847
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 )
1851 {
1852 if ( (*it).startsWith( item ) )
1853 {
1854 if ( (*it).length() > _len )
1855 {
1856 QString str = (*it).mid( _len );
1857 str.replace( QLatin1Char('+'), QLatin1Char(' ') ); // + in queries means space.
1858 return QUrl::fromPercentEncoding( str.toLatin1() );
1859 }
1860 else // empty value
1861 return QString::fromLatin1("");
1862 }
1863 }
1864
1865 return QString();
1866}
1867
1868void KUrl::addQueryItem( const QString& _item, const QString& _value )
1869{
1870 QString item = _item + QLatin1Char('=');
1871 QString value = QString::fromLatin1(QUrl::toPercentEncoding(_value));
1872
1873 QString strQueryEncoded = QString::fromLatin1(encodedQuery());
1874 if (!strQueryEncoded.isEmpty())
1875 strQueryEncoded += QLatin1Char('&');
1876 strQueryEncoded += item + value;
1877 setEncodedQuery( strQueryEncoded.toLatin1() );
1878}
1879
1880void KUrl::populateMimeData( QMimeData* mimeData,
1881 const MetaDataMap& metaData,
1882 MimeDataFlags flags ) const
1883{
1884 KUrl::List lst( *this );
1885 lst.populateMimeData( mimeData, metaData, flags );
1886}
1887
1888bool KUrl::hasRef() const
1889{
1890 return hasFragment();
1891}
1892
1893void KUrl::setRef( const QString& fragment )
1894{
1895 if ( fragment.isEmpty() ) // empty or null
1896 setFragment( fragment );
1897 else
1898 setFragment( QUrl::fromPercentEncoding( fragment.toLatin1() ) );
1899}
1900
1901QString KUrl::ref() const
1902{
1903 if ( !hasFragment() )
1904 return QString();
1905 else
1906 return QString::fromLatin1( encodedFragment() );
1907}
1908
1909bool KUrl::isParentOf( const KUrl& u ) const
1910{
1911 return QUrl::isParentOf( u ) || equals( u, CompareWithoutTrailingSlash );
1912}
1913
1914uint qHash(const KUrl& kurl)
1915{
1916 // qHash(kurl.url()) was the worse implementation possible, since QUrl::toEncoded()
1917 // had to concatenate the bits of the url into the full url every time.
1918
1919 return qHash(kurl.protocol()) ^ qHash(kurl.path()) ^ qHash(kurl.fragment()) ^ qHash(kurl.query());
1920}
KDebug::registerArea
static int registerArea(const QByteArray &areaName, bool enabled=true)
Definition: kdebug.cpp:856
KUrl::List
KUrl::List is a QList that contains KUrls with a few convenience methods.
Definition: kurl.h:147
KUrl::List::toStringList
QStringList toStringList() const
Converts the URLs of this list to a list of strings.
Definition: kurl.cpp:211
KUrl::List::fromMimeData
static KUrl::List fromMimeData(const QMimeData *mimeData, KUrl::MetaDataMap *metaData=0)
Extract a list of KUrls from the contents of mimeData.
Definition: kurl.cpp:369
KUrl::List::mimeDataTypes
static QStringList mimeDataTypes()
Return the list of mimeTypes that can be decoded by fromMimeData.
Definition: kurl.cpp:305
KUrl::List::canDecode
static bool canDecode(const QMimeData *mimeData)
Return true if mimeData contains URI data.
Definition: kurl.cpp:299
KUrl::List::populateMimeData
void populateMimeData(QMimeData *mimeData, const KUrl::MetaDataMap &metaData=MetaDataMap(), MimeDataFlags flags=DefaultMimeDataFlags) const
Adds URLs data into the given QMimeData.
Definition: kurl.cpp:248
KUrl::List::List
List()
Creates an empty List.
Definition: kurl.h:152
KUrl::List::DecodeOptions
DecodeOptions
Flags to be used in fromMimeData.
Definition: kurl.h:289
KUrl
Represents and parses a URL.
Definition: kurl.h:112
KUrl::encodedPathAndQuery
QString encodedPathAndQuery(AdjustPathOption trailing=LeaveTrailingSlash, const EncodedPathAndQueryOptions &options=PermitEmptyPath) const
Returns the encoded path and the query.
Definition: kurl.cpp:816
KUrl::~KUrl
~KUrl()
Destructs the KUrl object.
Definition: kurl.cpp:395
KUrl::cleanPath
void cleanPath(const CleanPathOption &options=SimplifyDirSeparators)
Resolves "." and ".." components in path.
Definition: kurl.cpp:759
KUrl::populateMimeData
void populateMimeData(QMimeData *mimeData, const MetaDataMap &metaData=MetaDataMap(), MimeDataFlags flags=DefaultMimeDataFlags) const
Adds URL data into the given QMimeData.
Definition: kurl.cpp:1880
KUrl::encodedHtmlRef
QString encodedHtmlRef() const
Returns the encoded reference (or "fragment") of the URL (everything after '#').
Definition: kurl.cpp:1525
KUrl::setFileEncoding
void setFileEncoding(const QString &encoding)
Adds encoding information to url by adding a "charset" parameter.
Definition: kurl.cpp:929
KUrl::toMimeDataString
QString toMimeDataString() const
Returns the URL as a string, using the standard conventions for mime data (drag-n-drop or copy-n-past...
Definition: kurl.cpp:1180
KUrl::pathOrUrl
QString pathOrUrl() const
Return the URL as a string, which will be either the URL (as prettyUrl would return) or,...
Definition: kurl.cpp:1165
KUrl::prettyUrl
QString prettyUrl(AdjustPathOption trailing=LeaveTrailingSlash) const
Returns the URL as string in human-friendly format.
Definition: kurl.cpp:1086
KUrl::ObeyTrailingSlash
@ ObeyTrailingSlash
This tells whether a trailing '/' should be ignored.
Definition: kurl.h:745
KUrl::AppendTrailingSlash
@ AppendTrailingSlash
tells whether the returned result should end with '/' or not.
Definition: kurl.h:754
KUrl::hasPath
bool hasPath() const
Test to see if this URL has a path is included in it.
Definition: kurl.cpp:717
KUrl::addQueryItem
void addQueryItem(const QString &_item, const QString &_value)
Add an additional query item.
Definition: kurl.cpp:1868
KUrl::hasPass
bool hasPass() const
Test to see if this URL has a password included in it.
Definition: kurl.cpp:707
KUrl::fromMimeDataByteArray
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...
Definition: kurl.cpp:1211
KUrl::AvoidEmptyPath
@ AvoidEmptyPath
If set to true then an empty path is substituted by "/" (this is the opposite of PermitEmptyPath)
Definition: kurl.h:534
KUrl::hasHTMLRef
bool hasHTMLRef() const
Checks whether there is a HTML reference.
Definition: kurl.cpp:1551
KUrl::fromPath
static KUrl fromPath(const QString &text)
Creates a KUrl object from a QString representing an absolute path.
Definition: kurl.cpp:722
KUrl::AdjustPathOption
AdjustPathOption
Options to be used in adjustPath.
Definition: kurl.h:121
KUrl::LeaveTrailingSlash
@ LeaveTrailingSlash
Do not change the path.
Definition: kurl.h:130
KUrl::RemoveTrailingSlash
@ RemoveTrailingSlash
strips a trailing '/', except when the path is already just "/".
Definition: kurl.h:125
KUrl::AddTrailingSlash
@ AddTrailingSlash
adds a trailing '/' if there is none yet
Definition: kurl.h:135
KUrl::adjustPath
void adjustPath(AdjustPathOption trailing)
Add or remove a trailing slash to/from the path.
Definition: kurl.cpp:802
KUrl::relativeUrl
static QString relativeUrl(const KUrl &base_url, const KUrl &url)
Convenience function.
Definition: kurl.cpp:1738
KUrl::url
QString url(AdjustPathOption trailing=LeaveTrailingSlash) const
Returns the URL as string, with all escape sequences intact, encoded in a given charset.
Definition: kurl.cpp:1035
KUrl::ref
QString ref() const
Returns the encoded reference (or "fragment") of the URL (everything after '#').
Definition: kurl.cpp:1901
KUrl::path
QString path(AdjustPathOption trailing=LeaveTrailingSlash) const
Definition: kurl.cpp:873
KUrl::upUrl
KUrl upUrl() const
This function is useful to implement the "Up" button in a file manager for example.
Definition: kurl.cpp:1477
KUrl::setFileName
void setFileName(const QString &_txt)
Sets the filename of the path.
Definition: kurl.cpp:729
KUrl::fromPathOrUrl
static KUrl fromPathOrUrl(const QString &text)
Definition: kurl.cpp:1673
KUrl::operator=
KUrl & operator=(const KUrl &_u)
Definition: kurl.cpp:602
KUrl::setProtocol
void setProtocol(const QString &proto)
Sets the protocol for the URL (i.e., file, http, etc.)
Definition: kurl.cpp:677
KUrl::CaseInsensitiveKeys
@ CaseInsensitiveKeys
Definition: kurl.h:673
KUrl::hasHost
bool hasHost() const
Test to see if this URL has a hostname included in it.
Definition: kurl.cpp:712
KUrl::equals
bool equals(const KUrl &u, const EqualsOptions &options=0) const
Compares this url with u.
Definition: kurl.cpp:631
KUrl::operator==
bool operator==(const KUrl &_u) const
Definition: kurl.cpp:608
KUrl::cmp
bool cmp(const KUrl &u, bool ignore_trailing=false) const
The same as equals(), just with a less obvious name.
Definition: kurl.cpp:625
KUrl::query
QString query() const
Returns the query of the URL.
Definition: kurl.cpp:1589
KUrl::CleanPathOption
CleanPathOption
Options to be used in cleanPath.
Definition: kurl.h:464
KUrl::KeepDirSeparators
@ KeepDirSeparators
The opposite of SimplifyDirSeparators.
Definition: kurl.h:474
KUrl::directory
QString directory(const DirectoryOptions &options=IgnoreTrailingSlash) const
Returns the directory of the path.
Definition: kurl.cpp:1380
KUrl::isLocalFile
bool isLocalFile() const
Checks whether the file is local.
Definition: kurl.cpp:924
KUrl::htmlRef
QString htmlRef() const
Returns the unencoded reference (or "fragment") of the URL (everything after '#').
Definition: kurl.cpp:1514
KUrl::cd
bool cd(const QString &_dir)
Changes the directory by descending into the given directory.
Definition: kurl.cpp:1420
KUrl::pass
QString pass() const
Returns the decoded password (corresponding to user()) included in the URL.
Definition: kurl.cpp:697
KUrl::user
QString user() const
Returns the decoded user name (login, user id, ...) included in the URL.
Definition: kurl.cpp:682
KUrl::KUrl
KUrl()
Constructs an empty URL.
Definition: kurl.cpp:390
KUrl::split
static List split(const QString &_url)
Splits nested URLs like file:///home/weis/kde.tgz#gzip:/#tar:/kdebase A URL like http://www....
Definition: kurl.cpp:1256
KUrl::CompareWithoutTrailingSlash
@ CompareWithoutTrailingSlash
ignore trailing '/' characters.
Definition: kurl.h:917
KUrl::CompareWithoutFragment
@ CompareWithoutFragment
disables comparison of HTML-style references.
Definition: kurl.h:921
KUrl::AllowEmptyPath
@ AllowEmptyPath
Treat a URL with no path as equal to a URL with a path of "/", when CompareWithoutTrailingSlash is se...
Definition: kurl.h:931
KUrl::setPath
void setPath(const QString &path)
Definition: kurl.cpp:1772
KUrl::setQuery
void setQuery(const QString &query)
Definition: kurl.cpp:1570
KUrl::setDirectory
void setDirectory(const QString &dir)
Set the directory to dir, leaving the filename empty.
Definition: kurl.cpp:1562
KUrl::setRef
void setRef(const QString &fragment)
Sets the reference/fragment part (everything after '#').
Definition: kurl.cpp:1893
KUrl::setEncodedPathAndQuery
void setEncodedPathAndQuery(const QString &_txt)
This is useful for HTTP.
Definition: kurl.cpp:858
KUrl::isParentOf
bool isParentOf(const KUrl &u) const
Checks whether the given URL is parent of this URL.
Definition: kurl.cpp:1909
KUrl::setPass
void setPass(const QString &pass)
Sets the password (corresponding to user()) included in the URL.
Definition: kurl.cpp:702
KUrl::fileName
QString fileName(const DirectoryOptions &options=IgnoreTrailingSlash) const
Returns the filename of the path.
Definition: kurl.cpp:1283
KUrl::protocol
QString protocol() const
Returns the protocol for the URL (i.e., file, http, etc.), lowercased.
Definition: kurl.cpp:672
KUrl::relativePath
static QString relativePath(const QString &base_dir, const QString &path, bool *isParent=0)
Convenience function.
Definition: kurl.cpp:1724
KUrl::queryItem
QString queryItem(const QString &item) const
Returns the value of a certain query item.
Definition: kurl.cpp:1841
KUrl::queryItems
QMap< QString, QString > queryItems(const QueryItemsOptions &options=0) const
Returns the list of query items as a map mapping keys to values.
Definition: kurl.cpp:1808
KUrl::isRelativeUrl
static bool isRelativeUrl(const QString &_url)
Convenience function.
Definition: kurl.cpp:160
KUrl::hasRef
bool hasRef() const
Checks whether the URL has a reference/fragment part.
Definition: kurl.cpp:1888
KUrl::fileEncoding
QString fileEncoding() const
Returns encoding information from url, the content of the "charset" parameter.
Definition: kurl.cpp:958
KUrl::hasUser
bool hasUser() const
Test to see if this URL has a user name included in it.
Definition: kurl.cpp:692
KUrl::hasSubUrl
bool hasSubUrl() const
Checks whether the URL has any sub URLs.
Definition: kurl.cpp:1030
KUrl::join
static KUrl join(const List &_list)
Reverses split().
Definition: kurl.cpp:1261
KUrl::toLocalFile
QString toLocalFile(AdjustPathOption trailing=LeaveTrailingSlash) const
Definition: kurl.cpp:885
KUrl::addPath
void addPath(const QString &txt)
Adds to the current path.
Definition: kurl.cpp:1344
KUrl::MimeDataFlags
MimeDataFlags
Definition: kurl.h:115
KUrl::NoTextExport
@ NoTextExport
Definition: kurl.h:115
KUrl::setUser
void setUser(const QString &user)
Sets the user name (login, user id, ...) included in the URL.
Definition: kurl.cpp:687
KUrl::setHTMLRef
void setHTMLRef(const QString &_ref)
Sets the HTML-style reference.
Definition: kurl.cpp:1536
QList
Definition: kaboutdata.h:33
QMap
QPair
QStringList
QString
QUrl
QVariant
isalpha
#define isalpha(c)
Definition: ctype_test_p.h:85
isdigit
#define isdigit(c)
Definition: ctype_test_p.h:87
kDebug
#define kDebug
Definition: kdebug.h:316
kWarning
#define kWarning
Definition: kdebug.h:322
kdebug.h
kglobal.h
kshell.h
cleanpath
static QString cleanpath(const QString &_path, bool cleanDirSeparator, bool decodeDots)
KDE4 TODO: maybe we should use QUrl::resolved()
Definition: kurl.cpp:50
trailingSlash
static QString trailingSlash(KUrl::AdjustPathOption trailing, const QString &path)
Definition: kurl.cpp:769
urlcmp
bool urlcmp(const QString &_url1, const QString &_url2)
Definition: kurl.cpp:1605
s_kdeUriListMime
static const char s_kdeUriListMime[]
Definition: kurl.cpp:246
qHash
uint qHash(const KUrl &kurl)
Definition: kurl.cpp:1914
isLocalFile
static bool isLocalFile(const QUrl &url)
Definition: kurl.cpp:905
removeSlashOrFilePrefix
static QString removeSlashOrFilePrefix(const QString &str)
Definition: kurl.cpp:132
_relativePath
static QString _relativePath(const QString &base_dir, const QString &path, bool &isParent)
Definition: kurl.cpp:1688
IS_LETTER
#define IS_LETTER(c)
IS_SLASH_AND_DRIVE_OR_DOUBLESLASH_0
#define IS_SLASH_AND_DRIVE_OR_DOUBLESLASH_0
toPrettyPercentEncoding
static QString toPrettyPercentEncoding(const QString &input, bool forFragment)
Definition: kurl.cpp:1063
IS_DRIVE_OR_DOUBLESLASH
#define IS_DRIVE_OR_DOUBLESLASH(isletter, char1, char2, colon, slash)
Definition: kurl.cpp:126
hasSubUrl
static bool hasSubUrl(const QUrl &url)
Definition: kurl.cpp:983
uriListData
static QByteArray uriListData(const KUrl::List &urls)
Definition: kurl.cpp:226
IS_DRIVE_OR_DOUBLESLASH_0
#define IS_DRIVE_OR_DOUBLESLASH_0
kurl.h
KGlobal::staticQString
const QString & staticQString(const char *str)
Creates a static QString.
Definition: kglobal.cpp:271
KGlobal::locale
KLocale * locale()
Returns the global locale object.
Definition: kglobal.cpp:170
KShell::tildeExpand
QString tildeExpand(const QString &path)
Performs tilde expansion on path.
Definition: kshell.cpp:55
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

Skip menu "KDECore"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal