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

KDECore

  • sources
  • kde-4.14
  • kdelibs
  • 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
47 static int kurlDebugArea() { static int s_area = KDebug::registerArea("kdecore (KUrl)"); return s_area; }
48 #endif
49 
50 static 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
132 static 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 
160 bool 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 
184 KUrl::List::List(const KUrl &url)
185 {
186  append( url );
187 }
188 
189 KUrl::List::List(const QList<KUrl> &list)
190  : QList<KUrl>(list)
191 {
192 }
193 
194 KUrl::List::List(const QList<QUrl> &list)
195 {
196  foreach(const QUrl& url, list) {
197  append(KUrl(url));
198  }
199 }
200 
201 KUrl::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 
211 QStringList KUrl::List::toStringList() const
212 {
213  return toStringList(KUrl::LeaveTrailingSlash);
214 }
215 
216 QStringList 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 
226 static 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 
246 static const char s_kdeUriListMime[] = "application/x-kde4-urilist";
247 
248 void 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 
288 void 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 
299 bool 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 
305 QStringList KUrl::List::mimeDataTypes()
306 {
307  return QStringList() << QString::fromLatin1(s_kdeUriListMime) << QString::fromLatin1("text/uri-list");
308 }
309 
310 
311 KUrl::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 
369 KUrl::List KUrl::List::fromMimeData( const QMimeData *mimeData, KUrl::MetaDataMap* metaData )
370 {
371  return fromMimeData(mimeData, PreferKdeUrls, metaData);
372 }
373 
374 KUrl::List::operator QVariant() const
375 {
376  return qVariantFromValue(*this);
377 }
378 
379 KUrl::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 
390 KUrl::KUrl()
391  : QUrl(), d(0)
392 {
393 }
394 
395 KUrl::~KUrl()
396 {
397 }
398 
399 
400 KUrl::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 
434 KUrl::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 
468 KUrl::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 
489 KUrl::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 
497 KUrl::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 
505 KUrl::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 
602 KUrl& KUrl::operator=( const KUrl& _u )
603 {
604  QUrl::operator=( _u );
605  return *this;
606 }
607 
608 bool KUrl::operator==( const KUrl& _u ) const
609 {
610  return QUrl::operator==( _u );
611 }
612 
613 bool KUrl::operator==( const QString& _u ) const
614 {
615  KUrl u( _u );
616  return ( *this == u );
617 }
618 
619 KUrl::operator QVariant() const
620 {
621  return qVariantFromValue(*this);
622 }
623 
624 #ifndef KDE_NO_DEPRECATED
625 bool KUrl::cmp( const KUrl &u, bool ignore_trailing ) const
626 {
627  return equals( u, ignore_trailing ? CompareWithoutTrailingSlash : EqualsOptions(0) );
628 }
629 #endif
630 
631 bool 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 
672 QString KUrl::protocol() const
673 {
674  return scheme().toLower();
675 }
676 
677 void KUrl::setProtocol( const QString& proto )
678 {
679  setScheme( proto );
680 }
681 
682 QString KUrl::user() const
683 {
684  return userName();
685 }
686 
687 void KUrl::setUser( const QString& user )
688 {
689  setUserName( user );
690 }
691 
692 bool KUrl::hasUser() const
693 {
694  return !userName().isEmpty();
695 }
696 
697 QString KUrl::pass() const
698 {
699  return password();
700 }
701 
702 void KUrl::setPass( const QString& pass )
703 {
704  setPassword( pass );
705 }
706 
707 bool KUrl::hasPass() const
708 {
709  return !password().isEmpty();
710 }
711 
712 bool KUrl::hasHost() const
713 {
714  return !host().isEmpty();
715 }
716 
717 bool KUrl::hasPath() const
718 {
719  return !path().isEmpty();
720 }
721 
722 KUrl KUrl::fromPath( const QString& text )
723 {
724  KUrl u;
725  u.setPath( text );
726  return u;
727 }
728 
729 void 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 
759 void 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 
769 static 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 
802 void 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 
816 QString 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
844 void 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 
858 void 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 
873 QString 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 
885 QString 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 
903 inline static bool hasSubUrl( const QUrl& url );
904 
905 static 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 
924 bool KUrl::isLocalFile() const
925 {
926  return ::isLocalFile( *this );
927 }
928 
929 void 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 
958 QString 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 
983 inline 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 
1030 bool KUrl::hasSubUrl() const
1031 {
1032  return ::hasSubUrl( *this );
1033 }
1034 
1035 QString 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 
1063 static 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 
1086 QString 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
1152 QString 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 
1165 QString KUrl::pathOrUrl() const
1166 {
1167  return pathOrUrl(LeaveTrailingSlash);
1168 }
1169 
1170 QString 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
1180 QString 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 
1211 KUrl 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 
1219 KUrl::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 
1256 KUrl::List KUrl::split( const QString& _url )
1257 {
1258  return split(KUrl(_url));
1259 }
1260 
1261 KUrl 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 
1283 QString 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 
1344 void 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 
1380 QString 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 
1420 bool 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 
1477 KUrl 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 
1514 QString 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 
1525 QString 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 
1536 void 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 
1551 bool 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 
1562 void KUrl::setDirectory( const QString &dir)
1563 {
1564  if ( dir.endsWith(QLatin1Char('/')))
1565  setPath(dir);
1566  else
1567  setPath(dir + QLatin1Char('/'));
1568 }
1569 
1570 void 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 
1578 void 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 
1589 QString KUrl::query() const
1590 {
1591  if (!hasQuery()) {
1592  return QString();
1593  }
1594  return QString(QLatin1Char('?')) + QString::fromLatin1(encodedQuery());
1595 }
1596 
1597 void 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
1605 bool 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
1629 bool 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
1673 KUrl 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 
1688 static 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 
1724 QString 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 
1738 QString 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 
1772 void 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 ' '
1797 QMap< 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 
1808 QMap< 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 
1841 QString 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 
1868 void 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 
1880 void 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 
1888 bool KUrl::hasRef() const
1889 {
1890  return hasFragment();
1891 }
1892 
1893 void 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 
1901 QString KUrl::ref() const
1902 {
1903  if ( !hasFragment() )
1904  return QString();
1905  else
1906  return QString::fromLatin1( encodedFragment() );
1907 }
1908 
1909 bool KUrl::isParentOf( const KUrl& u ) const
1910 {
1911  return QUrl::isParentOf( u ) || equals( u, CompareWithoutTrailingSlash );
1912 }
1913 
1914 uint 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 }
KUrl::adjustPath
void adjustPath(AdjustPathOption trailing)
Add or remove a trailing slash to/from the path.
Definition: kurl.cpp:802
cleanpath
static QString cleanpath(const QString &_path, bool cleanDirSeparator, bool decodeDots)
KDE4 TODO: maybe we should use QUrl::resolved()
Definition: kurl.cpp:50
QString::indexOf
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
QString::append
QString & append(QChar ch)
KUrl::directory
QString directory(const DirectoryOptions &options=IgnoreTrailingSlash) const
Returns the directory of the path.
Definition: kurl.cpp:1380
QMimeData::data
QByteArray data(const QString &mimeType) const
KUrl::RemoveTrailingSlash
strips a trailing '/', except when the path is already just "/".
Definition: kurl.h:125
KUrl::relativeUrl
static QString relativeUrl(const KUrl &base_url, const KUrl &url)
Convenience function.
Definition: kurl.cpp:1738
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.kde.org#tar:/kde/README.hml#ref1 will be split in http://www.kde.org and tar:/kde/README.html::ref1.
Definition: kurl.cpp:1256
QString::truncate
void truncate(int position)
QUrl::setFragment
void setFragment(const QString &fragment)
kdebug.h
KUrl::relativePath
static QString relativePath(const QString &base_dir, const QString &path, bool *isParent=0)
Convenience function.
Definition: kurl.cpp:1724
KUrl::AddTrailingSlash
adds a trailing '/' if there is none yet
Definition: kurl.h:135
QDir::fromNativeSeparators
QString fromNativeSeparators(const QString &pathName)
KUrl::MimeDataFlags
MimeDataFlags
Definition: kurl.h:115
QUrl::userName
QString userName() const
kurl.h
QUrl::setPort
void setPort(int port)
QByteArray
QListIterator::previous
const T & previous()
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::hasHTMLRef
bool hasHTMLRef() const
Checks whether there is a HTML reference.
Definition: kurl.cpp:1551
KUrl::fileEncoding
QString fileEncoding() const
Returns encoding information from url, the content of the "charset" parameter.
Definition: kurl.cpp:958
QMimeData::hasFormat
virtual bool hasFormat(const QString &mimeType) const
QChar
QString::split
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
hasSubUrl
static bool hasSubUrl(const QUrl &url)
Definition: kurl.cpp:983
KUrl::hasHost
bool hasHost() const
Test to see if this URL has a hostname included in it.
Definition: kurl.cpp:712
QString::prepend
QString & prepend(QChar ch)
QUrl::queryItems
QList< QPair< QString, QString > > queryItems() const
KUrl::encodedHtmlRef
QString encodedHtmlRef() const
Returns the encoded reference (or "fragment") of the URL (everything after '#').
Definition: kurl.cpp:1525
KUrl::isRelativeUrl
static bool isRelativeUrl(const QString &_url)
Convenience function.
Definition: kurl.cpp:160
QUrl::operator==
bool operator==(const QUrl &url) const
QDir::convertSeparators
QString convertSeparators(const QString &pathName)
QList::at
const T & at(int i) const
IS_DRIVE_OR_DOUBLESLASH
#define IS_DRIVE_OR_DOUBLESLASH(isletter, char1, char2, colon, slash)
Definition: kurl.cpp:126
QMap
QByteArray::isNull
bool isNull() const
kshell.h
KUrl::ref
QString ref() const
Returns the encoded reference (or "fragment") of the URL (everything after '#').
Definition: kurl.cpp:1901
QUrl::host
QString host() const
KUrl::cleanPath
void cleanPath(const CleanPathOption &options=SimplifyDirSeparators)
Resolves "." and ".." components in path.
Definition: kurl.cpp:759
QByteArray::isEmpty
bool isEmpty() const
QByteArray::startsWith
bool startsWith(const QByteArray &ba) const
KUrl::urlcmp
bool urlcmp(const QString &_url1, const QString &_url2)
Definition: kurl.cpp:1605
IS_DRIVE_OR_DOUBLESLASH_0
#define IS_DRIVE_OR_DOUBLESLASH_0
KUrl::setRef
void setRef(const QString &fragment)
Sets the reference/fragment part (everything after '#').
Definition: kurl.cpp:1893
QUrl::setPassword
void setPassword(const QString &password)
KUrl::cd
bool cd(const QString &_dir)
Changes the directory by descending into the given directory.
Definition: kurl.cpp:1420
KUrl::setEncodedPathAndQuery
void setEncodedPathAndQuery(const QString &_txt)
This is useful for HTTP.
Definition: kurl.cpp:858
KUrl::fromPath
static KUrl fromPath(const QString &text)
Creates a KUrl object from a QString representing an absolute path.
Definition: kurl.cpp:722
QList::erase
iterator erase(iterator pos)
KUrl::toLocalFile
QString toLocalFile(AdjustPathOption trailing=LeaveTrailingSlash) const
Definition: kurl.cpp:885
KUrl::addQueryItem
void addQueryItem(const QString &_item, const QString &_value)
Add an additional query item.
Definition: kurl.cpp:1868
QStringList::join
QString join(const QString &separator) const
KUrl::CompareWithoutTrailingSlash
ignore trailing '/' characters.
Definition: kurl.h:917
KUrl::KUrl
KUrl()
Constructs an empty URL.
Definition: kurl.cpp:390
QString::remove
QString & remove(int position, int n)
QUrl::port
int port() const
KUrl::List::canDecode
static bool canDecode(const QMimeData *mimeData)
Return true if mimeData contains URI data.
Definition: kurl.cpp:299
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::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
QString::chop
void chop(int n)
KUrl::isParentOf
bool isParentOf(const KUrl &u) const
Checks whether the given URL is parent of this URL.
Definition: kurl.cpp:1909
KUrl::hasPass
bool hasPass() const
Test to see if this URL has a password included in it.
Definition: kurl.cpp:707
QUrl::isEmpty
bool isEmpty() const
QDir::homePath
QString homePath()
QList::const_iterator
QMimeData
KGlobal::ref
void ref()
Tells KGlobal about one more operations that should be finished before the application exits...
Definition: kglobal.cpp:321
KUrl
Represents and parses a URL.
Definition: kurl.h:111
KUrl::setQuery
void setQuery(const QString &query)
Definition: kurl.cpp:1570
QString::lastIndexOf
int lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
QString::isNull
bool isNull() const
KUrl::setPath
void setPath(const QString &path)
Definition: kurl.cpp:1772
QString::clear
void clear()
KUrl::setUser
void setUser(const QString &user)
Sets the user name (login, user id, ...) included in the URL.
Definition: kurl.cpp:687
QUrl::setPath
void setPath(const QString &path)
Kuit::Tag::None
Definition: kuitsemantics.cpp:82
KUrl::List::List
List()
Creates an empty List.
Definition: kurl.h:152
kglobal.h
KUrl::setProtocol
void setProtocol(const QString &proto)
Sets the protocol for the URL (i.e., file, http, etc.)
Definition: kurl.cpp:677
KUrl::addPath
void addPath(const QString &txt)
Adds to the current path.
Definition: kurl.cpp:1344
QString::number
QString number(int n, int base)
QList::count
int count(const T &value) const
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
QList< KUrl >::append
void append(const KUrl &value)
QString::fromUtf8
QString fromUtf8(const char *str, int size)
KUrl::hasRef
bool hasRef() const
Checks whether the URL has a reference/fragment part.
Definition: kurl.cpp:1888
QUrl::setUrl
void setUrl(const QString &url)
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
toPrettyPercentEncoding
static QString toPrettyPercentEncoding(const QString &input, bool forFragment)
Definition: kurl.cpp:1063
uriListData
static QByteArray uriListData(const KUrl::List &urls)
Definition: kurl.cpp:226
KUrl::user
QString user() const
Returns the decoded user name (login, user id, ...) included in the URL.
Definition: kurl.cpp:682
KUrl::protocol
QString protocol() const
Returns the protocol for the URL (i.e., file, http, etc.), lowercased.
Definition: kurl.cpp:672
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::pass
QString pass() const
Returns the decoded password (corresponding to user()) included in the URL.
Definition: kurl.cpp:697
QList::isEmpty
bool isEmpty() const
QString::isEmpty
bool isEmpty() const
QByteArray::constData
const char * constData() const
QUrl::fragment
QString fragment() const
QString::startsWith
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
KUrl::CompareWithoutFragment
disables comparison of HTML-style references.
Definition: kurl.h:921
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
KDebug::registerArea
static int registerArea(const QByteArray &areaName, bool enabled=true)
Definition: kdebug.cpp:856
QUrl::setScheme
void setScheme(const QString &scheme)
KUrl::setPass
void setPass(const QString &pass)
Sets the password (corresponding to user()) included in the URL.
Definition: kurl.cpp:702
QMap::const_iterator
QUrl::path
QString path() const
QString::endsWith
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
QList::Iterator
typedef Iterator
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::hasUser
bool hasUser() const
Test to see if this URL has a user name included in it.
Definition: kurl.cpp:692
QListIterator::toBack
void toBack()
IS_LETTER
#define IS_LETTER(c)
QString
QList< KUrl >
QMap::end
iterator end()
QChar::unicode
ushort unicode() const
KUrl::path
QString path(AdjustPathOption trailing=LeaveTrailingSlash) const
Definition: kurl.cpp:873
QUrl::fromPercentEncoding
QString fromPercentEncoding(const QByteArray &input)
KUrl::hasPath
bool hasPath() const
Test to see if this URL has a path is included in it.
Definition: kurl.cpp:717
QByteArray::mid
QByteArray mid(int pos, int len) const
QUrl::setEncodedPath
void setEncodedPath(const QByteArray &path)
QUrl::scheme
QString scheme() const
QUrl::encodedFragment
QByteArray encodedFragment() const
KUrl::CaseInsensitiveKeys
Definition: kurl.h:673
KUrl::setHTMLRef
void setHTMLRef(const QString &_ref)
Sets the HTML-style reference.
Definition: kurl.cpp:1536
QUrl::authority
QString authority() const
QMap::begin
iterator begin()
QStringList
QUrl::operator=
QUrl & operator=(const QUrl &url)
KUrl::htmlRef
QString htmlRef() const
Returns the unencoded reference (or "fragment") of the URL (everything after '#').
Definition: kurl.cpp:1514
QUrl::password
QString password() const
IS_SLASH_AND_DRIVE_OR_DOUBLESLASH_0
#define IS_SLASH_AND_DRIVE_OR_DOUBLESLASH_0
QPair
QString::right
QString right(int n) const
QUrl::toLocalFile
QString toLocalFile() const
QByteArray::append
QByteArray & append(char ch)
QFileInfo
QList::end
iterator end()
QString::toLower
QString toLower() const
QUrl::isParentOf
bool isParentOf(const QUrl &childUrl) const
QString::toLocal8Bit
QByteArray toLocal8Bit() const
QUrl::decode
void decode(QString &url)
KUrl::AdjustPathOption
AdjustPathOption
Options to be used in adjustPath.
Definition: kurl.h:120
qHash
uint qHash(const KUrl &kurl)
Definition: kurl.cpp:1914
QString::contains
bool contains(QChar ch, Qt::CaseSensitivity cs) const
QUrl::setUserName
void setUserName(const QString &userName)
QUrl::encodedPath
QByteArray encodedPath() const
QUrl
KUrl::operator==
bool operator==(const KUrl &_u) const
Definition: kurl.cpp:608
QLatin1Char
isalpha
#define isalpha(c)
Definition: ctype_test_p.h:85
kWarning
#define kWarning
Definition: kdebug.h:322
QChar::toLatin1
char toLatin1() const
QDir::isRelativePath
bool isRelativePath(const QString &path)
QUrl::fileName
QString fileName() const
_relativePath
static QString _relativePath(const QString &base_dir, const QString &path, bool &isParent)
Definition: kurl.cpp:1688
KGlobal::locale
KLocale * locale()
Returns the global locale object.
Definition: kglobal.cpp:170
KUrl::setFileEncoding
void setFileEncoding(const QString &encoding)
Adds encoding information to url by adding a "charset" parameter.
Definition: kurl.cpp:929
QString::replace
QString & replace(int position, int n, QChar after)
QString::unicode
const QChar * unicode() const
KUrl::List
KUrl::List is a QList that contains KUrls with a few convenience methods.
Definition: kurl.h:146
QDir::cleanPath
QString cleanPath(const QString &path)
removeSlashOrFilePrefix
static QString removeSlashOrFilePrefix(const QString &str)
Definition: kurl.cpp:132
QUrl::setEncodedQuery
void setEncodedQuery(const QByteArray &query)
QListIterator::hasPrevious
bool hasPrevious() const
QByteArray::left
QByteArray left(int len) const
KUrl::setFileName
void setFileName(const QString &_txt)
Sets the filename of the path.
Definition: kurl.cpp:729
QUrl::isValid
bool isValid() const
trailingSlash
static QString trailingSlash(KUrl::AdjustPathOption trailing, const QString &path)
Definition: kurl.cpp:769
QString::toLatin1
QByteArray toLatin1() const
KUrl::encodedPathAndQuery
QString encodedPathAndQuery(AdjustPathOption trailing=LeaveTrailingSlash, const EncodedPathAndQueryOptions &options=PermitEmptyPath) const
Returns the encoded path and the query.
Definition: kurl.cpp:816
QString::mid
QString mid(int position, int n) const
QFileInfo::isRelative
bool isRelative() const
QLatin1String
KUrl::fileName
QString fileName(const DirectoryOptions &options=IgnoreTrailingSlash) const
Returns the filename of the path.
Definition: kurl.cpp:1283
isLocalFile
static bool isLocalFile(const QUrl &url)
Definition: kurl.cpp:905
QDir::rootPath
QString rootPath()
KUrl::~KUrl
~KUrl()
Destructs the KUrl object.
Definition: kurl.cpp:395
QString::count
int count() const
QUrl::isRelative
bool isRelative() const
KUrl::CleanPathOption
CleanPathOption
Options to be used in cleanPath.
Definition: kurl.h:463
QString::at
const QChar at(int position) const
QUrl::encodedQuery
QByteArray encodedQuery() const
QList::last
T & last()
KUrl::ObeyTrailingSlash
This tells whether a trailing '/' should be ignored.
Definition: kurl.h:745
QList::ConstIterator
typedef ConstIterator
QUrl::toPercentEncoding
QByteArray toPercentEncoding(const QString &input, const QByteArray &exclude, const QByteArray &include)
KUrl::List::toStringList
QStringList toStringList() const
Converts the URLs of this list to a list of strings.
Definition: kurl.cpp:211
QList::removeLast
void removeLast()
KUrl::hasSubUrl
bool hasSubUrl() const
Checks whether the URL has any sub URLs.
Definition: kurl.cpp:1030
KUrl::AppendTrailingSlash
tells whether the returned result should end with '/' or not.
Definition: kurl.h:754
KShell::tildeExpand
QString tildeExpand(const QString &path)
Performs tilde expansion on path.
Definition: kshell.cpp:55
QString::length
int length() const
QString::reserve
void reserve(int size)
KUrl::query
QString query() const
Returns the query of the URL.
Definition: kurl.cpp:1589
QByteArray::data
char * data()
KUrl::KeepDirSeparators
The opposite of SimplifyDirSeparators.
Definition: kurl.h:474
QString::left
QString left(int n) const
QString::fromLatin1
QString fromLatin1(const char *str, int size)
kDebug
#define kDebug
Definition: kdebug.h:316
QStringList::indexOf
int indexOf(const QRegExp &rx, int from) const
KUrl::List::mimeDataTypes
static QStringList mimeDataTypes()
Return the list of mimeTypes that can be decoded by fromMimeData.
Definition: kurl.cpp:305
QUrl::setEncodedUrl
void setEncodedUrl(const QByteArray &encodedUrl)
QMap::insert
iterator insert(const Key &key, const T &value)
KUrl::setDirectory
void setDirectory(const QString &dir)
Set the directory to dir, leaving the filename empty.
Definition: kurl.cpp:1562
QListIterator
QUrl::setHost
void setHost(const QString &host)
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
QMap::isEmpty
bool isEmpty() const
isdigit
#define isdigit(c)
Definition: ctype_test_p.h:87
QMimeData::setData
void setData(const QString &mimeType, const QByteArray &data)
KGlobal::staticQString
const QString & staticQString(const char *str)
Creates a static QString.
Definition: kglobal.cpp:271
QUrl::hasFragment
bool hasFragment() const
KUrl::AvoidEmptyPath
If set to true then an empty path is substituted by "/" (this is the opposite of PermitEmptyPath) ...
Definition: kurl.h:534
QList::constEnd
const_iterator constEnd() const
QList::constBegin
const_iterator constBegin() const
s_kdeUriListMime
static const char s_kdeUriListMime[]
Definition: kurl.cpp:246
KUrl::fromPathOrUrl
static KUrl fromPathOrUrl(const QString &text)
Definition: kurl.cpp:1673
KUrl::isLocalFile
bool isLocalFile() const
Checks whether the file is local.
Definition: kurl.cpp:924
QByteArray::size
int size() const
QUrl::hasQuery
bool hasQuery() const
QUrl::setUserInfo
void setUserInfo(const QString &userInfo)
QString::compare
int compare(const QString &other) const
KUrl::List::DecodeOptions
DecodeOptions
Flags to be used in fromMimeData.
Definition: kurl.h:289
KUrl::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::LeaveTrailingSlash
Do not change the path.
Definition: kurl.h:130
KUrl::equals
bool equals(const KUrl &u, const EqualsOptions &options=0) const
Compares this url with u.
Definition: kurl.cpp:631
QList::begin
iterator begin()
KUrl::prettyUrl
QString prettyUrl(AdjustPathOption trailing=LeaveTrailingSlash) const
Returns the URL as string in human-friendly format.
Definition: kurl.cpp:1086
KUrl::NoTextExport
Definition: kurl.h:115
KUrl::join
static KUrl join(const List &_list)
Reverses split().
Definition: kurl.cpp:1261
QUrl::toEncoded
QByteArray toEncoded(QFlags< QUrl::FormattingOption > options) const
KUrl::operator=
KUrl & operator=(const KUrl &_u)
Definition: kurl.cpp:602
KUrl::queryItem
QString queryItem(const QString &item) const
Returns the value of a certain query item.
Definition: kurl.cpp:1841
QVariant
QUrl::userInfo
QString userInfo() const
QString::toUtf8
QByteArray toUtf8() const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:22:12 by doxygen 1.8.7 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 API Reference

Skip menu "kdelibs 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

Search



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