• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.10.5 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
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 != '-'))
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  strRef_encoded = ""; // we know there was an (empty) html ref, we saw the '#'
547  setEncodedFragment( strRef_encoded );
548  }
549  else if ( isRelativeUrl( rUrl ) )
550  {
551  *this = _u;
552  setFragment( QString() );
553  setEncodedQuery( QByteArray() );
554  QString strPath = path();
555  if ( rUrl[0] == QLatin1Char('/') )
556  {
557  if ((rUrl.length() > 1) && (rUrl[1] == QLatin1Char('/')))
558  {
559  setHost( QString() );
560  setPort( -1 );
561  // File protocol returns file:/// without host, strip // from rUrl
562  if ( _u.isLocalFile() )
563  rUrl.remove(0, 2);
564  }
565  strPath.clear();
566  }
567  else if ( rUrl[0] != QLatin1Char('?') )
568  {
569  const int pos = strPath.lastIndexOf( QLatin1Char('/') );
570  if (pos >= 0)
571  strPath.truncate(pos);
572  strPath += QLatin1Char('/');
573  }
574  else
575  {
576  if ( strPath.isEmpty() )
577  strPath = QLatin1Char('/');
578  }
579  setPath( strPath );
580  //kDebug(kurlDebugArea()) << "url()=" << url() << " rUrl=" << rUrl;
581  const KUrl tmp( url() + rUrl);
582  //kDebug(kurlDebugArea()) << "assigning tmp=" << tmp.url();
583  *this = tmp;
584  cleanPath(KeepDirSeparators);
585  }
586  else
587  {
588  const KUrl tmp( rUrl );
589  //kDebug(kurlDebugArea()) << "not relative; assigning tmp=" << tmp.url();
590  *this = tmp;
591  // Preserve userinfo if applicable.
592  if (!_u.userInfo().isEmpty() && userInfo().isEmpty()
593  && (_u.host() == host()) && (_u.scheme() == scheme()))
594  {
595  setUserInfo( _u.userInfo() );
596  }
597  cleanPath(KeepDirSeparators);
598  }
599 }
600 
601 KUrl& KUrl::operator=( const KUrl& _u )
602 {
603  QUrl::operator=( _u );
604  return *this;
605 }
606 
607 bool KUrl::operator==( const KUrl& _u ) const
608 {
609  return QUrl::operator==( _u );
610 }
611 
612 bool KUrl::operator==( const QString& _u ) const
613 {
614  KUrl u( _u );
615  return ( *this == u );
616 }
617 
618 KUrl::operator QVariant() const
619 {
620  return qVariantFromValue(*this);
621 }
622 
623 #ifndef KDE_NO_DEPRECATED
624 bool KUrl::cmp( const KUrl &u, bool ignore_trailing ) const
625 {
626  return equals( u, ignore_trailing ? CompareWithoutTrailingSlash : EqualsOptions(0) );
627 }
628 #endif
629 
630 bool KUrl::equals( const KUrl &_u, const EqualsOptions& options ) const
631 {
632  if ( !isValid() || !_u.isValid() )
633  return false;
634 
635  if ( options & CompareWithoutTrailingSlash || options & CompareWithoutFragment )
636  {
637  QString path1 = path((options & CompareWithoutTrailingSlash) ? RemoveTrailingSlash : LeaveTrailingSlash);
638  QString path2 = _u.path((options & CompareWithoutTrailingSlash) ? RemoveTrailingSlash : LeaveTrailingSlash);
639 
640  if (options & AllowEmptyPath) {
641  if (path1 == QLatin1String("/"))
642  path1.clear();
643  if (path2 == QLatin1String("/"))
644  path2.clear();
645  }
646 
647 #ifdef Q_WS_WIN
648  const bool bLocal1 = isLocalFile();
649  const bool bLocal2 = _u.isLocalFile();
650  if ( !bLocal1 && bLocal2 || bLocal1 && !bLocal2 )
651  return false;
652  // local files are case insensitive
653  if ( bLocal1 && bLocal2 && 0 != QString::compare( path1, path2, Qt::CaseInsensitive ) )
654  return false;
655 #endif
656  if ( path1 != path2 )
657  return false;
658 
659  if ( scheme() == _u.scheme() &&
660  authority() == _u.authority() && // user+pass+host+port
661  encodedQuery() == _u.encodedQuery() &&
662  (fragment() == _u.fragment() || options & CompareWithoutFragment ) )
663  return true;
664 
665  return false;
666  }
667 
668  return ( *this == _u );
669 }
670 
671 QString KUrl::protocol() const
672 {
673  return scheme().toLower();
674 }
675 
676 void KUrl::setProtocol( const QString& proto )
677 {
678  setScheme( proto );
679 }
680 
681 QString KUrl::user() const
682 {
683  return userName();
684 }
685 
686 void KUrl::setUser( const QString& user )
687 {
688  setUserName( user );
689 }
690 
691 bool KUrl::hasUser() const
692 {
693  return !userName().isEmpty();
694 }
695 
696 QString KUrl::pass() const
697 {
698  return password();
699 }
700 
701 void KUrl::setPass( const QString& pass )
702 {
703  setPassword( pass );
704 }
705 
706 bool KUrl::hasPass() const
707 {
708  return !password().isEmpty();
709 }
710 
711 bool KUrl::hasHost() const
712 {
713  return !host().isEmpty();
714 }
715 
716 bool KUrl::hasPath() const
717 {
718  return !path().isEmpty();
719 }
720 
721 KUrl KUrl::fromPath( const QString& text )
722 {
723  KUrl u;
724  u.setPath( text );
725  return u;
726 }
727 
728 void KUrl::setFileName( const QString& _txt )
729 {
730  setFragment( QString() );
731  int i = 0;
732  while( i < _txt.length() && _txt[i] == QLatin1Char('/') )
733  ++i;
734  QString tmp = i ? _txt.mid( i ) : _txt;
735 
736  QString path = this->path();
737  if ( path.isEmpty() )
738 #ifdef Q_OS_WIN
739  path = isLocalFile() ? QDir::rootPath() : QLatin1String("/");
740 #else
741  path = QDir::rootPath();
742 #endif
743  else
744  {
745  int lastSlash = path.lastIndexOf( QLatin1Char('/') );
746  if ( lastSlash == -1)
747  path.clear(); // there's only the file name, remove it
748  else if ( !path.endsWith( QLatin1Char('/') ) )
749  path.truncate( lastSlash+1 ); // keep the "/"
750  }
751 
752  path += tmp;
753  setPath( path );
754 
755  cleanPath();
756 }
757 
758 void KUrl::cleanPath( const CleanPathOption& options )
759 {
760  //if (m_iUriMode != URL) return;
761  const QString newPath = cleanpath(path(), !(options & KeepDirSeparators), false);
762  if ( path() != newPath )
763  setPath( newPath );
764  // WABA: Is this safe when "/../" is encoded with %?
765  //m_strPath_encoded = cleanpath(m_strPath_encoded, cleanDirSeparator, true);
766 }
767 
768 static QString trailingSlash( KUrl::AdjustPathOption trailing, const QString &path )
769 {
770  if ( trailing == KUrl::LeaveTrailingSlash ) {
771  return path;
772  }
773 
774  QString result = path;
775 
776  if ( trailing == KUrl::AddTrailingSlash )
777  {
778  int len = result.length();
779  if ((len > 0) && (result[ len - 1 ] != QLatin1Char('/')))
780  result += QLatin1Char('/');
781  return result;
782  }
783  else if ( trailing == KUrl::RemoveTrailingSlash )
784  {
785  if ( result == QLatin1String("/") )
786  return result;
787  int len = result.length();
788  while (len > 1 && result[ len - 1 ] == QLatin1Char('/'))
789  {
790  len--;
791  }
792  result.truncate( len );
793  return result;
794  }
795  else {
796  assert( 0 );
797  return result;
798  }
799 }
800 
801 void KUrl::adjustPath( AdjustPathOption trailing )
802 {
803 #if 0
804  if (!m_strPath_encoded.isEmpty())
805  {
806  m_strPath_encoded = trailingSlash( _trailing, m_strPath_encoded );
807  }
808 #endif
809  const QString newPath = trailingSlash( trailing, path() );
810  if ( path() != newPath )
811  setPath( newPath );
812 }
813 
814 
815 QString KUrl::encodedPathAndQuery( AdjustPathOption trailing , const EncodedPathAndQueryOptions &options) const
816 {
817  QString encodedPath;
818 #ifdef Q_OS_WIN
819  // see KUrl::path()
820  if (isLocalFile()) {
821  // ### this is probably broken
822  encodedPath = trailingSlash(trailing, QUrl::toLocalFile());
823  encodedPath = QString::fromLatin1(QUrl::toPercentEncoding(encodedPath, "!$&'()*+,;=:@/"));
824  } else {
825  encodedPath = trailingSlash(trailing, QString::fromLatin1(QUrl::encodedPath()));
826  }
827 #else
828  encodedPath = trailingSlash(trailing, QString::fromLatin1(QUrl::encodedPath()));
829 #endif
830 
831  if ((options & AvoidEmptyPath) && encodedPath.isEmpty()) {
832  encodedPath.append(QLatin1Char('/'));
833  }
834 
835  if (hasQuery()) {
836  return encodedPath + QLatin1Char('?') + QString::fromLatin1(encodedQuery());
837  } else {
838  return encodedPath;
839  }
840 }
841 
842 #if 0
843 void KUrl::setEncodedPath( const QString& _txt, int encoding_hint )
844 {
845  m_strPath_encoded = _txt;
846 
847  decode( m_strPath_encoded, m_strPath, m_strPath_encoded, encoding_hint );
848  // Throw away encoding for local files, makes file-operations faster.
849  if (m_strProtocol == "file")
850  m_strPath_encoded.clear();
851 
852  if ( m_iUriMode == Auto )
853  m_iUriMode = URL;
854 }
855 #endif
856 
857 void KUrl::setEncodedPathAndQuery( const QString& _txt )
858 {
859  const int pos = _txt.indexOf(QLatin1Char('?'));
860  if ( pos == -1 )
861  {
862  setPath( QUrl::fromPercentEncoding( _txt.toLatin1() ) );
863  setEncodedQuery( QByteArray() );
864  }
865  else
866  {
867  setPath( QUrl::fromPercentEncoding(_txt.toLatin1().left(pos)) );
868  _setQuery( _txt.right( _txt.length() - pos - 1 ) );
869  }
870 }
871 
872 QString KUrl::path( AdjustPathOption trailing ) const
873 {
874 #ifdef Q_WS_WIN
875 #ifdef DEBUG_KURL
876  kWarning() << (isLocalFile() ? "converted to local file - the related call should be converted to toLocalFile()" : "") << QUrl::path();
877 #endif
878  return trailingSlash( trailing, isLocalFile() ? QUrl::toLocalFile() : QUrl::path() );
879 #else
880  return trailingSlash( trailing, QUrl::path() );
881 #endif
882 }
883 
884 QString KUrl::toLocalFile( AdjustPathOption trailing ) const
885 {
886  if (hasHost() && isLocalFile()) {
887  KUrl urlWithoutHost(*this);
888  urlWithoutHost.setHost(QString());
889  return trailingSlash(trailing, urlWithoutHost.toLocalFile());
890  }
891 #ifdef __GNUC__
892 #warning FIXME: Remove #ifdef below once upstream bug, QTBUG-20322, is fixed. Also see BR# 194746.
893 #endif
894 #ifndef Q_WS_WIN
895  if (isLocalFile()) {
896  return trailingSlash(trailing, QUrl::path());
897  }
898 #endif
899  return trailingSlash(trailing, QUrl::toLocalFile());
900 }
901 
902 inline static bool hasSubUrl( const QUrl& url );
903 
904 static inline bool isLocalFile( const QUrl& url )
905 {
906  if ( ( url.scheme() != QLatin1String("file") ) || hasSubUrl( url ) )
907  return false;
908 
909  if (url.host().isEmpty() || (url.host() == QLatin1String("localhost")))
910  return true;
911 
912  char hostname[ 256 ];
913  hostname[ 0 ] = '\0';
914  if (!gethostname( hostname, 255 ))
915  hostname[sizeof(hostname)-1] = '\0';
916 
917  for(char *p = hostname; *p; p++)
918  *p = tolower(*p);
919 
920  return (url.host() == QString::fromLatin1( hostname ));
921 }
922 
923 bool KUrl::isLocalFile() const
924 {
925  return ::isLocalFile( *this );
926 }
927 
928 void KUrl::setFileEncoding(const QString &encoding)
929 {
930  if (!isLocalFile())
931  return;
932 
933  QString q = query();
934 
935  if (!q.isEmpty() && q[0] == QLatin1Char('?'))
936  q = q.mid(1);
937 
938  QStringList args = q.split(QLatin1Char('&'), QString::SkipEmptyParts);
939  for(QStringList::Iterator it = args.begin();
940  it != args.end();)
941  {
942  QString s = QUrl::fromPercentEncoding( (*it).toLatin1() );
943  if (s.startsWith(QLatin1String("charset=")))
944  it = args.erase(it);
945  else
946  ++it;
947  }
948  if (!encoding.isEmpty())
949  args.append(QLatin1String("charset=") + QString::fromLatin1(QUrl::toPercentEncoding(encoding)));
950 
951  if (args.isEmpty())
952  _setQuery(QString());
953  else
954  _setQuery(args.join(QString(QLatin1Char('&'))));
955 }
956 
957 QString KUrl::fileEncoding() const
958 {
959  if (!isLocalFile())
960  return QString();
961 
962  QString q = query();
963 
964  if (q.isEmpty())
965  return QString();
966 
967  if (q[0] == QLatin1Char('?'))
968  q = q.mid(1);
969 
970  const QStringList args = q.split(QLatin1Char('&'), QString::SkipEmptyParts);
971  for(QStringList::ConstIterator it = args.begin();
972  it != args.end();
973  ++it)
974  {
975  QString s = QUrl::fromPercentEncoding((*it).toLatin1());
976  if (s.startsWith(QLatin1String("charset=")))
977  return s.mid(8);
978  }
979  return QString();
980 }
981 
982 inline static bool hasSubUrl( const QUrl& url )
983 {
984  // The isValid call triggers QUrlPrivate::validate which needs the full encoded url,
985  // all this takes too much time for isLocalFile()
986  const QString scheme = url.scheme();
987  if ( scheme.isEmpty() /*|| !isValid()*/ )
988  return false;
989  const QString ref( url.fragment() );
990  if (ref.isEmpty())
991  return false;
992  switch ( ref.at(0).unicode() ) {
993  case 'g':
994  if ( ref.startsWith(QLatin1String("gzip:")) )
995  return true;
996  break;
997  case 'b':
998  if ( ref.startsWith(QLatin1String("bzip:")) || ref.startsWith(QLatin1String("bzip2:")) )
999  return true;
1000  break;
1001  case 'l':
1002  if ( ref.startsWith(QLatin1String("lzma:")) )
1003  return true;
1004  break;
1005  case 'x':
1006  if ( ref.startsWith(QLatin1String("xz:")) )
1007  return true;
1008  break;
1009  case 't':
1010  if ( ref.startsWith(QLatin1String("tar:")) )
1011  return true;
1012  break;
1013  case 'a':
1014  if ( ref.startsWith(QLatin1String("ar:")) )
1015  return true;
1016  break;
1017  case 'z':
1018  if ( ref.startsWith(QLatin1String("zip:")) )
1019  return true;
1020  break;
1021  default:
1022  break;
1023  }
1024  if ( scheme == QLatin1String("error") ) // anything that starts with error: has suburls
1025  return true;
1026  return false;
1027 }
1028 
1029 bool KUrl::hasSubUrl() const
1030 {
1031  return ::hasSubUrl( *this );
1032 }
1033 
1034 QString KUrl::url( AdjustPathOption trailing ) const
1035 {
1036  if (QString::compare(scheme(), QLatin1String("mailto"), Qt::CaseInsensitive) == 0) {
1037  // mailto urls should be prettified, see the url183433 testcase.
1038  return prettyUrl(trailing);
1039  }
1040  if ( trailing == AddTrailingSlash && !path().endsWith( QLatin1Char('/') ) ) {
1041  // -1 and 0 are provided by QUrl, but not +1, so that one is a bit tricky.
1042  // To avoid reimplementing toEncoded() all over again, I just use another QUrl
1043  // Let's hope this is fast, or not called often...
1044  QUrl newUrl( *this );
1045  newUrl.setPath( path() + QLatin1Char('/') );
1046  return QString::fromLatin1(newUrl.toEncoded());
1047  }
1048  else if ( trailing == RemoveTrailingSlash) {
1049  const QString cleanedPath = trailingSlash(trailing, path());
1050  if (cleanedPath == QLatin1String("/")) {
1051  if (path() != QLatin1String("/")) {
1052  QUrl fixedUrl = *this;
1053  fixedUrl.setPath(cleanedPath);
1054  return QLatin1String(fixedUrl.toEncoded(None));
1055  }
1056  return QLatin1String(toEncoded(None));
1057  }
1058  }
1059  return QString::fromLatin1(toEncoded(trailing == RemoveTrailingSlash ? StripTrailingSlash : None));
1060 }
1061 
1062 static QString toPrettyPercentEncoding(const QString &input, bool forFragment)
1063 {
1064  QString result;
1065  result.reserve(input.length());
1066  for (int i = 0; i < input.length(); ++i) {
1067  const QChar c = input.at(i);
1068  register ushort u = c.unicode();
1069  if (u < 0x20
1070  || (!forFragment && u == '?') // don't escape '?' in fragments, not needed and wrong (#173101)
1071  || u == '#' || u == '%'
1072  || (u == ' ' && (i+1 == input.length() || input.at(i+1).unicode() == ' '))) {
1073  static const char hexdigits[] = "0123456789ABCDEF";
1074  result += QLatin1Char('%');
1075  result += QLatin1Char(hexdigits[(u & 0xf0) >> 4]);
1076  result += QLatin1Char(hexdigits[u & 0xf]);
1077  } else {
1078  result += c;
1079  }
1080  }
1081 
1082  return result;
1083 }
1084 
1085 QString KUrl::prettyUrl( AdjustPathOption trailing ) const
1086 {
1087  // reconstruct the URL in a "pretty" form
1088  // a "pretty" URL is NOT suitable for data transfer. It's only for showing data to the user.
1089  // however, it must be parseable back to its original state, since
1090  // notably Konqueror displays it in the Location address.
1091 
1092  // A pretty URL is the same as a normal URL, except that:
1093  // - the password is removed
1094  // - the hostname is shown in Unicode (as opposed to ACE/Punycode)
1095  // - the pathname and fragment parts are shown in Unicode (as opposed to %-encoding)
1096  QString result = scheme();
1097  if (!result.isEmpty())
1098  {
1099  if (!authority().isEmpty() || result == QLatin1String("file") || path().isEmpty())
1100  result += QLatin1String("://");
1101  else
1102  result += QLatin1Char(':');
1103  }
1104 
1105  QString tmp = userName();
1106  if (!tmp.isEmpty()) {
1107  result += QString::fromLatin1(QUrl::toPercentEncoding(tmp));
1108  result += QLatin1Char('@');
1109  }
1110 
1111  // Check if host is an ipv6 address
1112  tmp = host();
1113  if (tmp.contains(QLatin1Char(':')))
1114  result += QLatin1Char('[') + tmp + QLatin1Char(']');
1115  else
1116  result += tmp;
1117 
1118  if (port() != -1) {
1119  result += QLatin1Char(':');
1120  result += QString::number(port());
1121  }
1122 
1123  tmp = path();
1124 #ifdef Q_WS_WIN
1125  if (isLocalFile())
1126  tmp.prepend(QLatin1Char('/')); // KUrl::path() returns toLocalFile() on windows so we need to add the / back to create a proper url
1127 #endif
1128  result += toPrettyPercentEncoding(tmp, false);
1129 
1130  // adjust the trailing slash, if necessary
1131  if (trailing == AddTrailingSlash && !tmp.endsWith(QLatin1Char('/')))
1132  result += QLatin1Char('/');
1133  else if (trailing == RemoveTrailingSlash && tmp.length() > 1 && tmp.endsWith(QLatin1Char('/')))
1134  result.chop(1);
1135 
1136  if (hasQuery()) {
1137  result += QLatin1Char('?');
1138  result += QString::fromLatin1(encodedQuery());
1139  }
1140 
1141  if (hasFragment()) {
1142  result += QLatin1Char('#');
1143  result += toPrettyPercentEncoding(fragment(), true);
1144  }
1145 
1146  return result;
1147 }
1148 
1149 #if 0
1150 QString KUrl::prettyUrl( int _trailing, AdjustementFlags _flags) const
1151 {
1152  QString u = prettyUrl(_trailing);
1153  if (_flags & StripFileProtocol && u.startsWith("file://")) {
1154  u.remove(0, 7);
1155 #ifdef Q_WS_WIN
1156  return QDir::convertSeparators(u);
1157 #endif
1158  }
1159  return u;
1160 }
1161 #endif
1162 
1163 QString KUrl::pathOrUrl() const
1164 {
1165  return pathOrUrl(LeaveTrailingSlash);
1166 }
1167 
1168 QString KUrl::pathOrUrl(AdjustPathOption trailing) const
1169 {
1170  if ( isLocalFile() && fragment().isNull() && encodedQuery().isNull() ) {
1171  return toLocalFile(trailing);
1172  } else {
1173  return prettyUrl(trailing);
1174  }
1175 }
1176 
1177 // Used for text/uri-list in the mime data
1178 QString KUrl::toMimeDataString() const // don't fold this into populateMimeData, it's also needed by other code like konqdrag
1179 {
1180  if ( isLocalFile() )
1181  {
1182 #if 1
1183  return url();
1184 #else
1185  // According to the XDND spec, file:/ URLs for DND must have
1186  // the hostname part. But in really it just breaks many apps,
1187  // so it's disabled for now.
1188  const QString s = url( 0, KGlobal::locale()->fileEncodingMib() );
1189  if( !s.startsWith( QLatin1String ( "file://" ) ))
1190  {
1191  char hostname[257];
1192  if ( gethostname( hostname, 255 ) == 0 )
1193  {
1194  hostname[256] = '\0';
1195  return QString( "file://" ) + hostname + s.mid( 5 );
1196  }
1197  }
1198 #endif
1199  }
1200 
1201  if (hasPass()) {
1202  KUrl safeUrl(*this);
1203  safeUrl.setPassword(QString());
1204  return safeUrl.url();
1205  }
1206  return url();
1207 }
1208 
1209 KUrl KUrl::fromMimeDataByteArray( const QByteArray& str )
1210 {
1211  if ( str.startsWith( "file:" ) ) // krazy:exclude=strings
1212  return KUrl( str /*, QTextCodec::codecForLocale()->mibEnum()*/ );
1213 
1214  return KUrl( str /*, 106*/ ); // 106 is mib enum for utf8 codec;
1215 }
1216 
1217 KUrl::List KUrl::split( const KUrl& _url )
1218 {
1219  QString ref;
1220  bool hasRef;
1221  KUrl::List lst;
1222  KUrl url = _url;
1223 
1224  while(true)
1225  {
1226  KUrl u = url;
1227  u.setFragment( QString() );
1228  lst.append(u);
1229  if (url.hasSubUrl())
1230  {
1231  url = KUrl(url.fragment());
1232  }
1233  else
1234  {
1235  ref = url.fragment();
1236  hasRef = url.hasFragment();
1237  break;
1238  }
1239  }
1240 
1241  if ( hasRef )
1242  {
1243  // Set HTML ref in all URLs.
1244  KUrl::List::Iterator it;
1245  for( it = lst.begin() ; it != lst.end(); ++it )
1246  {
1247  (*it).setFragment( ref );
1248  }
1249  }
1250 
1251  return lst;
1252 }
1253 
1254 KUrl::List KUrl::split( const QString& _url )
1255 {
1256  return split(KUrl(_url));
1257 }
1258 
1259 KUrl KUrl::join( const KUrl::List & lst )
1260 {
1261  if (lst.isEmpty()) return KUrl();
1262  KUrl tmp;
1263 
1264  bool first = true;
1265  QListIterator<KUrl> it(lst);
1266  it.toBack();
1267  while (it.hasPrevious())
1268  {
1269  KUrl u(it.previous());
1270  if (!first) {
1271  u.setEncodedFragment(tmp.url().toLatin1() /* TODO double check encoding */);
1272  }
1273  tmp = u;
1274 
1275  first = false;
1276  }
1277 
1278  return tmp;
1279 }
1280 
1281 QString KUrl::fileName( const DirectoryOptions& options ) const
1282 {
1283  Q_ASSERT( options != 0 ); //Disallow options == false
1284  QString fname;
1285  if (hasSubUrl()) { // If we have a suburl, then return the filename from there
1286  const KUrl::List list = KUrl::split(*this);
1287  return list.last().fileName(options);
1288  }
1289  const QString path = this->path();
1290 
1291  int len = path.length();
1292  if ( len == 0 )
1293  return fname;
1294 
1295  if (!(options & ObeyTrailingSlash) )
1296  {
1297  while ( len >= 1 && path[ len - 1 ] == QLatin1Char('/') )
1298  len--;
1299  }
1300  else if ( path[ len - 1 ] == QLatin1Char('/') )
1301  return fname;
1302 
1303  // Does the path only consist of '/' characters ?
1304  if ( len == 1 && path[ 0 ] == QLatin1Char('/') )
1305  return fname;
1306 
1307  // Skip last n slashes
1308  int n = 1;
1309 #if 0
1310  if (!m_strPath_encoded.isEmpty())
1311  {
1312  // This is hairy, we need the last unencoded slash.
1313  // Count in the encoded string how many encoded slashes follow the last
1314  // unencoded one.
1315  int i = m_strPath_encoded.lastIndexOf( QLatin1Char('/'), len - 1 );
1316  QString fileName_encoded = m_strPath_encoded.mid(i+1);
1317  n += fileName_encoded.count("%2f", Qt::CaseInsensitive);
1318  }
1319 #endif
1320  int i = len;
1321  do {
1322  i = path.lastIndexOf( QLatin1Char('/'), i - 1 );
1323  }
1324  while (--n && (i > 0));
1325 
1326  // If ( i == -1 ) => the first character is not a '/'
1327  // So it's some URL like file:blah.tgz, return the whole path
1328  if ( i == -1 ) {
1329  if ( len == (int)path.length() )
1330  fname = path;
1331  else
1332  // Might get here if _strip_trailing_slash is true
1333  fname = path.left( len );
1334  }
1335  else
1336  {
1337  fname = path.mid( i + 1, len - i - 1 ); // TO CHECK
1338  }
1339  return fname;
1340 }
1341 
1342 void KUrl::addPath( const QString& _txt )
1343 {
1344  if (hasSubUrl())
1345  {
1346  KUrl::List lst = split( *this );
1347  KUrl &u = lst.last();
1348  u.addPath(_txt);
1349  *this = join( lst );
1350  return;
1351  }
1352 
1353  //m_strPath_encoded.clear();
1354 
1355  if ( _txt.isEmpty() )
1356  return;
1357 
1358  QString strPath = path();
1359  int i = 0;
1360  int len = strPath.length();
1361  // Add the trailing '/' if it is missing
1362  if ( _txt[0] != QLatin1Char('/') && ( len == 0 || strPath[ len - 1 ] != QLatin1Char('/') ) )
1363  strPath += QLatin1Char('/');
1364 
1365  // No double '/' characters
1366  i = 0;
1367  const int _txtlen = _txt.length();
1368  if ( strPath.endsWith( QLatin1Char('/') ) )
1369  {
1370  while ( ( i < _txtlen ) && ( _txt[i] == QLatin1Char('/') ) )
1371  ++i;
1372  }
1373 
1374  setPath( strPath + _txt.mid( i ) );
1375  //kDebug(kurlDebugArea())<<"addPath: resultpath="<<path();
1376 }
1377 
1378 QString KUrl::directory( const DirectoryOptions& options ) const
1379 {
1380  Q_ASSERT( options != 0 ); //Disallow options == false
1381  QString result = path(); //m_strPath_encoded.isEmpty() ? m_strPath : m_strPath_encoded;
1382  if ( !(options & ObeyTrailingSlash) )
1383  result = trailingSlash( RemoveTrailingSlash, result );
1384 
1385  if ( result.isEmpty() || result == QLatin1String ( "/" ) )
1386  return result;
1387 
1388  int i = result.lastIndexOf( QLatin1Char('/') );
1389  // If ( i == -1 ) => the first character is not a '/'
1390  // So it's some URL like file:blah.tgz, with no path
1391  if ( i == -1 )
1392  return QString();
1393 
1394  if ( i == 0 )
1395  {
1396  return QString(QLatin1Char('/'));
1397  }
1398 
1399 #ifdef Q_WS_WIN
1400  if ( i == 2 && result[1] == QLatin1Char(':') )
1401  {
1402  return result.left(3);
1403  }
1404 #endif
1405 
1406  if ( options & AppendTrailingSlash )
1407  result = result.left( i + 1 );
1408  else
1409  result = result.left( i );
1410 
1411  //if (!m_strPath_encoded.isEmpty())
1412  // result = decode(result);
1413 
1414  return result;
1415 }
1416 
1417 
1418 bool KUrl::cd( const QString& _dir )
1419 {
1420  if ( _dir.isEmpty() || !isValid() )
1421  return false;
1422 
1423  if (hasSubUrl())
1424  {
1425  KUrl::List lst = split( *this );
1426  KUrl &u = lst.last();
1427  u.cd(_dir);
1428  *this = join( lst );
1429  return true;
1430  }
1431 
1432  // absolute path ?
1433 #ifdef Q_OS_WIN
1434  if ( !QFileInfo(_dir).isRelative() )
1435 #else
1436  if ( _dir[0] == QLatin1Char('/') )
1437 #endif
1438  {
1439  //m_strPath_encoded.clear();
1440  setPath( _dir );
1441  setHTMLRef( QString() );
1442  setEncodedQuery( QByteArray() );
1443  return true;
1444  }
1445 
1446  // Users home directory on the local disk ?
1447  if (_dir[0] == QLatin1Char('~') && scheme() == QLatin1String ("file"))
1448  {
1449  //m_strPath_encoded.clear();
1450  QString strPath = QDir::homePath();
1451  strPath += QLatin1Char('/');
1452  strPath += _dir.right( strPath.length() - 1 );
1453  setPath( strPath );
1454  setHTMLRef( QString() );
1455  setEncodedQuery( QByteArray() );
1456  return true;
1457  }
1458 
1459  // relative path
1460  // we always work on the past of the first url.
1461  // Sub URLs are not touched.
1462 
1463  // append '/' if necessary
1464  QString p = path(AddTrailingSlash);
1465  p += _dir;
1466  p = cleanpath( p, true, false );
1467  setPath( p );
1468 
1469  setHTMLRef( QString() );
1470  setEncodedQuery( QByteArray() );
1471 
1472  return true;
1473 }
1474 
1475 KUrl KUrl::upUrl( ) const
1476 {
1477  if (!isValid() || isRelative())
1478  return KUrl();
1479 
1480  if (!encodedQuery().isEmpty())
1481  {
1482  KUrl u(*this);
1483  u.setEncodedQuery(QByteArray());
1484  return u;
1485  }
1486 
1487  if (!hasSubUrl())
1488  {
1489  KUrl u(*this);
1490  u.cd(QLatin1String("../"));
1491  return u;
1492  }
1493 
1494  // We have a subURL.
1495  KUrl::List lst = split( *this );
1496  if (lst.isEmpty())
1497  return KUrl(); // Huh?
1498  while (true)
1499  {
1500  KUrl &u = lst.last();
1501  const QString old = u.path();
1502  u.cd(QLatin1String("../"));
1503  if (u.path() != old)
1504  break; // Finished.
1505  if (lst.count() == 1)
1506  break; // Finished.
1507  lst.removeLast();
1508  }
1509  return join( lst );
1510 }
1511 
1512 QString KUrl::htmlRef() const
1513 {
1514  if ( !hasSubUrl() )
1515  {
1516  return fragment();
1517  }
1518 
1519  const List lst = split( *this );
1520  return (*lst.begin()).fragment();
1521 }
1522 
1523 QString KUrl::encodedHtmlRef() const
1524 {
1525  if ( !hasSubUrl() )
1526  {
1527  return ref();
1528  }
1529 
1530  const List lst = split( *this );
1531  return (*lst.begin()).ref();
1532 }
1533 
1534 void KUrl::setHTMLRef( const QString& _ref )
1535 {
1536  if ( !hasSubUrl() )
1537  {
1538  setFragment( _ref );
1539  return;
1540  }
1541 
1542  List lst = split( *this );
1543 
1544  (*lst.begin()).setFragment( _ref );
1545 
1546  *this = join( lst );
1547 }
1548 
1549 bool KUrl::hasHTMLRef() const
1550 {
1551  if ( !hasSubUrl() )
1552  {
1553  return hasRef();
1554  }
1555 
1556  const List lst = split( *this );
1557  return (*lst.begin()).hasRef();
1558 }
1559 
1560 void KUrl::setDirectory( const QString &dir)
1561 {
1562  if ( dir.endsWith(QLatin1Char('/')))
1563  setPath(dir);
1564  else
1565  setPath(dir + QLatin1Char('/'));
1566 }
1567 
1568 void KUrl::setQuery( const QString &_txt )
1569 {
1570  if (!_txt.isEmpty() && _txt[0] == QLatin1Char('?'))
1571  _setQuery( _txt.length() > 1 ? _txt.mid(1) : QString::fromLatin1("") /*empty, not null*/ );
1572  else
1573  _setQuery( _txt );
1574 }
1575 
1576 void KUrl::_setQuery( const QString& query )
1577 {
1578  if ( query.isNull() ) {
1579  setEncodedQuery( QByteArray() );
1580  } else if ( query.isEmpty() ) {
1581  setEncodedQuery("");
1582  } else {
1583  setEncodedQuery( query.toLatin1() ); // already percent-escaped, so toLatin1 is ok
1584  }
1585 }
1586 
1587 QString KUrl::query() const
1588 {
1589  if (!hasQuery()) {
1590  return QString();
1591  }
1592  return QString(QLatin1Char('?')) + QString::fromLatin1(encodedQuery());
1593 }
1594 
1595 void KUrl::_setEncodedUrl(const QByteArray& url)
1596 {
1597  setEncodedUrl(url, QUrl::TolerantMode);
1598  if (!isValid()) // see unit tests referring to N183630/task 183874
1599  setUrl(QString::fromUtf8(url), QUrl::TolerantMode);
1600 }
1601 
1602 #ifndef KDE_NO_DEPRECATED
1603 bool urlcmp( const QString& _url1, const QString& _url2 )
1604 {
1605  return QUrl( _url1, QUrl::TolerantMode ) == QUrl( _url2, QUrl::TolerantMode );
1606 #if 0
1607  // Both empty ?
1608  if ( _url1.isEmpty() && _url2.isEmpty() )
1609  return true;
1610  // Only one empty ?
1611  if ( _url1.isEmpty() || _url2.isEmpty() )
1612  return false;
1613 
1614  KUrl::List list1 = KUrl::split( _url1 );
1615  KUrl::List list2 = KUrl::split( _url2 );
1616 
1617  // Malformed ?
1618  if ( list1.isEmpty() || list2.isEmpty() )
1619  return false;
1620 
1621  return ( list1 == list2 );
1622 #endif
1623 }
1624 #endif
1625 
1626 #ifndef KDE_NO_DEPRECATED
1627 bool urlcmp( const QString& _url1, const QString& _url2, const KUrl::EqualsOptions& _options )
1628 {
1629  // Both empty ?
1630  if (_url1.isEmpty() && _url2.isEmpty())
1631  return true;
1632  // Only one empty ?
1633  if (_url1.isEmpty() || _url2.isEmpty())
1634  return false;
1635 
1636  KUrl u1(_url1);
1637  KUrl u2(_url2);
1638  return u1.equals(u2, _options);
1639 
1640 #if 0 // kde3 code that supported nested urls
1641 
1642  KUrl::List list1 = KUrl::split( _url1 );
1643  KUrl::List list2 = KUrl::split( _url2 );
1644 
1645  // Malformed ?
1646  if ( list1.isEmpty() || list2.isEmpty() )
1647  return false;
1648 
1649  int size = list1.count();
1650  if ( list2.count() != size )
1651  return false;
1652 
1653  if ( _ignore_ref )
1654  {
1655  (*list1.begin()).setRef(QString());
1656  (*list2.begin()).setRef(QString());
1657  }
1658 
1659  KUrl::List::Iterator it1 = list1.begin();
1660  KUrl::List::Iterator it2 = list2.begin();
1661  for( ; it1 != list1.end() ; ++it1, ++it2 )
1662  if ( !(*it1).equals( *it2, _ignore_trailing ) )
1663  return false;
1664  return true;
1665 #endif
1666 }
1667 #endif
1668 
1669 // static
1670 #ifndef KDE_NO_DEPRECATED
1671 KUrl KUrl::fromPathOrUrl( const QString& text )
1672 {
1673  KUrl url;
1674  if ( !text.isEmpty() )
1675  {
1676  if (!QDir::isRelativePath(text) || text[0] == QLatin1Char('~'))
1677  url.setPath( text );
1678  else
1679  url = KUrl( text );
1680  }
1681 
1682  return url;
1683 }
1684 #endif
1685 
1686 static QString _relativePath(const QString &base_dir, const QString &path, bool &isParent)
1687 {
1688  QString _base_dir(QDir::cleanPath(base_dir));
1689  QString _path(QDir::cleanPath(path.isEmpty() || QDir::isRelativePath(path) ? _base_dir+QLatin1Char('/')+path : path));
1690 
1691  if (_base_dir.isEmpty())
1692  return _path;
1693 
1694  if (_base_dir[_base_dir.length()-1] != QLatin1Char('/'))
1695  _base_dir.append(QLatin1Char('/') );
1696 
1697  const QStringList list1 = _base_dir.split(QLatin1Char('/'), QString::SkipEmptyParts);
1698  const QStringList list2 = _path.split(QLatin1Char('/'), QString::SkipEmptyParts);
1699 
1700  // Find where they meet
1701  int level = 0;
1702  int maxLevel = qMin(list1.count(), list2.count());
1703  while((level < maxLevel) && (list1[level] == list2[level])) level++;
1704 
1705  QString result;
1706  // Need to go down out of the first path to the common branch.
1707  for(int i = level; i < list1.count(); i++)
1708  result.append(QLatin1String("../"));
1709 
1710  // Now up up from the common branch to the second path.
1711  for(int i = level; i < list2.count(); i++)
1712  result.append(list2[i]).append(QLatin1Char('/'));
1713 
1714  if ((level < list2.count()) && (path[path.length()-1] != QLatin1Char('/')))
1715  result.truncate(result.length()-1);
1716 
1717  isParent = (level == list1.count());
1718 
1719  return result;
1720 }
1721 
1722 QString KUrl::relativePath(const QString &base_dir, const QString &path, bool *isParent)
1723 {
1724  bool parent = false;
1725  QString result = _relativePath(base_dir, path, parent);
1726  if (parent)
1727  result.prepend(QLatin1String("./"));
1728 
1729  if (isParent)
1730  *isParent = parent;
1731 
1732  return result;
1733 }
1734 
1735 
1736 QString KUrl::relativeUrl(const KUrl &base_url, const KUrl &url)
1737 {
1738  if ((url.protocol() != base_url.protocol()) ||
1739  (url.host() != base_url.host()) ||
1740  (url.port() && url.port() != base_url.port()) ||
1741  (url.hasUser() && url.user() != base_url.user()) ||
1742  (url.hasPass() && url.pass() != base_url.pass()))
1743  {
1744  return url.url();
1745  }
1746 
1747  QString relURL;
1748 
1749  if ((base_url.path() != url.path()) || (base_url.query() != url.query()))
1750  {
1751  bool dummy;
1752  QString basePath = base_url.directory(KUrl::ObeyTrailingSlash);
1753  static const char s_pathExcludeChars[] = "!$&'()*+,;=:@/";
1754  relURL = QString::fromLatin1(QUrl::toPercentEncoding(_relativePath(basePath, url.path(), dummy), s_pathExcludeChars));
1755  relURL += url.query();
1756  }
1757 
1758  if ( url.hasRef() )
1759  {
1760  relURL += QLatin1Char('#');
1761  relURL += url.ref();
1762  }
1763 
1764  if ( relURL.isEmpty() )
1765  return QLatin1String("./");
1766 
1767  return relURL;
1768 }
1769 
1770 void KUrl::setPath( const QString& _path )
1771 {
1772 #if defined(Q_WS_WIN) && defined(DEBUG_KURL)
1773  kDebug(kurlDebugArea()) << "KUrl::setPath " << " " << _path.toLatin1().data();
1774 #endif
1775  if ( scheme().isEmpty() )
1776  setScheme( QLatin1String( "file" ) );
1777  QString path = KShell::tildeExpand( _path );
1778  if (path.isEmpty())
1779  path = _path;
1780 #ifdef Q_WS_WIN
1781  const int len = path.length();
1782  if( len == 2 && IS_LETTER(path[0]) && path[1] == QLatin1Char(':') )
1783  path += QLatin1Char('/');
1784  //This is necessary because QUrl has the "path" part including the first slash
1785  //Without this QUrl doesn't understand that this is a path, and some operations fail
1786  //e.g. C:/blah needs to become /C:/blah
1787  else
1788  if( len > 0 && path[0] != QLatin1Char('/') && scheme() == QLatin1String( "file" ) )
1789  path = QLatin1Char('/') + path;
1790 #endif
1791  QUrl::setPath( path );
1792 }
1793 
1794 #if 0 // this would be if we didn't decode '+' into ' '
1795 QMap< QString, QString > KUrl::queryItems( int options ) const {
1796  QMap< QString, QString > result;
1797  const QList<QPair<QString, QString> > items = QUrl::queryItems();
1798  QPair<QString, QString> item;
1799  Q_FOREACH( item, items ) {
1800  result.insert( options & CaseInsensitiveKeys ? item.first.toLower() : item.first, item.second );
1801  }
1802  return result;
1803 }
1804 #endif
1805 
1806 QMap< QString, QString > KUrl::queryItems( const QueryItemsOptions &options ) const
1807 {
1808  const QString strQueryEncoded = QString::fromLatin1(encodedQuery());
1809  if ( strQueryEncoded.isEmpty() )
1810  return QMap<QString,QString>();
1811 
1812  QMap< QString, QString > result;
1813  const QStringList items = strQueryEncoded.split( QLatin1Char('&'), QString::SkipEmptyParts );
1814  for ( QStringList::const_iterator it = items.begin() ; it != items.end() ; ++it ) {
1815  const int equal_pos = (*it).indexOf(QLatin1Char('='));
1816  if ( equal_pos > 0 ) { // = is not the first char...
1817  QString name = (*it).left( equal_pos );
1818  if ( options & CaseInsensitiveKeys )
1819  name = name.toLower();
1820  QString value = (*it).mid( equal_pos + 1 );
1821  if ( value.isEmpty() )
1822  result.insert( name, QString::fromLatin1("") );
1823  else {
1824  // ### why is decoding name not necessary?
1825  value.replace( QLatin1Char('+'), QLatin1Char(' ') ); // + in queries means space
1826  result.insert( name, QUrl::fromPercentEncoding( value.toLatin1() ) );
1827  }
1828  } else if ( equal_pos < 0 ) { // no =
1829  QString name = (*it);
1830  if ( options & CaseInsensitiveKeys )
1831  name = name.toLower();
1832  result.insert( name, QString() );
1833  }
1834  }
1835 
1836  return result;
1837 }
1838 
1839 QString KUrl::queryItem( const QString& _item ) const
1840 {
1841  const QString strQueryEncoded = QString::fromLatin1(encodedQuery());
1842  const QString item = _item + QLatin1Char('=');
1843  if ( strQueryEncoded.length() <= 1 )
1844  return QString();
1845 
1846  const QStringList items = strQueryEncoded.split( QString(QLatin1Char('&')), QString::SkipEmptyParts );
1847  const int _len = item.length();
1848  for ( QStringList::ConstIterator it = items.begin(); it != items.end(); ++it )
1849  {
1850  if ( (*it).startsWith( item ) )
1851  {
1852  if ( (*it).length() > _len )
1853  {
1854  QString str = (*it).mid( _len );
1855  str.replace( QLatin1Char('+'), QLatin1Char(' ') ); // + in queries means space.
1856  return QUrl::fromPercentEncoding( str.toLatin1() );
1857  }
1858  else // empty value
1859  return QString::fromLatin1("");
1860  }
1861  }
1862 
1863  return QString();
1864 }
1865 
1866 void KUrl::addQueryItem( const QString& _item, const QString& _value )
1867 {
1868  QString item = _item + QLatin1Char('=');
1869  QString value = QString::fromLatin1(QUrl::toPercentEncoding(_value));
1870 
1871  QString strQueryEncoded = QString::fromLatin1(encodedQuery());
1872  if (!strQueryEncoded.isEmpty())
1873  strQueryEncoded += QLatin1Char('&');
1874  strQueryEncoded += item + value;
1875  setEncodedQuery( strQueryEncoded.toLatin1() );
1876 }
1877 
1878 void KUrl::populateMimeData( QMimeData* mimeData,
1879  const MetaDataMap& metaData,
1880  MimeDataFlags flags ) const
1881 {
1882  KUrl::List lst( *this );
1883  lst.populateMimeData( mimeData, metaData, flags );
1884 }
1885 
1886 bool KUrl::hasRef() const
1887 {
1888  return hasFragment();
1889 }
1890 
1891 void KUrl::setRef( const QString& fragment )
1892 {
1893  if ( fragment.isEmpty() ) // empty or null
1894  setFragment( fragment );
1895  else
1896  setFragment( QUrl::fromPercentEncoding( fragment.toLatin1() ) );
1897 }
1898 
1899 QString KUrl::ref() const
1900 {
1901  if ( fragment().isNull() )
1902  return QString();
1903  else
1904  return QString::fromLatin1( QUrl::toPercentEncoding( fragment() ) );
1905 }
1906 
1907 bool KUrl::isParentOf( const KUrl& u ) const
1908 {
1909  return QUrl::isParentOf( u ) || equals( u, CompareWithoutTrailingSlash );
1910 }
1911 
1912 uint qHash(const KUrl& kurl)
1913 {
1914  // qHash(kurl.url()) was the worse implementation possible, since QUrl::toEncoded()
1915  // had to concatenate the bits of the url into the full url every time.
1916 
1917  return qHash(kurl.protocol()) ^ qHash(kurl.path()) ^ qHash(kurl.fragment()) ^ qHash(kurl.query());
1918 }
QVariant
KUrl::adjustPath
void adjustPath(AdjustPathOption trailing)
Add or remove a trailing slash to/from the path.
Definition: kurl.cpp:801
cleanpath
static QString cleanpath(const QString &_path, bool cleanDirSeparator, bool decodeDots)
KDE4 TODO: maybe we should use QUrl::resolved()
Definition: kurl.cpp:50
KUrl::directory
QString directory(const DirectoryOptions &options=IgnoreTrailingSlash) const
Returns the directory of the path.
Definition: kurl.cpp:1378
KUrl::RemoveTrailingSlash
strips a trailing &#39;/&#39;, except when the path is already just &quot;/&quot;.
Definition: kurl.h:125
KUrl::relativeUrl
static QString relativeUrl(const KUrl &base_url, const KUrl &url)
Convenience function.
Definition: kurl.cpp:1736
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:1254
kdebug.h
KUrl::relativePath
static QString relativePath(const QString &base_dir, const QString &path, bool *isParent=0)
Convenience function.
Definition: kurl.cpp:1722
KUrl::AddTrailingSlash
adds a trailing &#39;/&#39; if there is none yet
Definition: kurl.h:135
KUrl::MimeDataFlags
MimeDataFlags
Definition: kurl.h:115
kurl.h
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:1549
KUrl::fileEncoding
QString fileEncoding() const
Returns encoding information from url, the content of the &quot;charset&quot; parameter.
Definition: kurl.cpp:957
hasSubUrl
static bool hasSubUrl(const QUrl &url)
Definition: kurl.cpp:982
KUrl::hasHost
bool hasHost() const
Test to see if this URL has a hostname included in it.
Definition: kurl.cpp:711
KUrl::encodedHtmlRef
QString encodedHtmlRef() const
Returns the HTML reference (the part of the URL after &quot;#&quot;) in encoded form.
Definition: kurl.cpp:1523
KUrl::isRelativeUrl
static bool isRelativeUrl(const QString &_url)
Convenience function.
Definition: kurl.cpp:160
IS_DRIVE_OR_DOUBLESLASH
#define IS_DRIVE_OR_DOUBLESLASH(isletter, char1, char2, colon, slash)
Definition: kurl.cpp:126
kshell.h
KUrl::ref
QString ref() const
Returns the reference (or &quot;fragment&quot;) of the URL.
Definition: kurl.cpp:1899
KUrl::cleanPath
void cleanPath(const CleanPathOption &options=SimplifyDirSeparators)
Resolves &quot;.&quot; and &quot;..&quot; components in path.
Definition: kurl.cpp:758
KUrl::urlcmp
bool urlcmp(const QString &_url1, const QString &_url2)
Definition: kurl.cpp:1603
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 &#39;#&#39;).
Definition: kurl.cpp:1891
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:1806
KUrl::cd
bool cd(const QString &_dir)
Changes the directory by descending into the given directory.
Definition: kurl.cpp:1418
KUrl::setEncodedPathAndQuery
void setEncodedPathAndQuery(const QString &_txt)
This is useful for HTTP.
Definition: kurl.cpp:857
KUrl::fromPath
static KUrl fromPath(const QString &text)
Creates a KUrl object from a QString representing an absolute path.
Definition: kurl.cpp:721
KUrl::toLocalFile
QString toLocalFile(AdjustPathOption trailing=LeaveTrailingSlash) const
Definition: kurl.cpp:884
KUrl::addQueryItem
void addQueryItem(const QString &_item, const QString &_value)
Add an additional query item.
Definition: kurl.cpp:1866
QUrl
QString
KUrl::CompareWithoutTrailingSlash
ignore trailing &#39;/&#39; characters.
Definition: kurl.h:915
KUrl::KUrl
KUrl()
Constructs an empty URL.
Definition: kurl.cpp:390
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:1878
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:1178
KUrl::isParentOf
bool isParentOf(const KUrl &u) const
Checks whether the given URL is parent of this URL.
Definition: kurl.cpp:1907
KUrl::hasPass
bool hasPass() const
Test to see if this URL has a password included in it.
Definition: kurl.cpp:706
KGlobal::ref
void ref()
Tells KGlobal about one more operations that should be finished before the application exits...
Definition: kglobal.cpp:320
KUrl
Represents and parses a URL.
Definition: kurl.h:111
KUrl::setQuery
void setQuery(const QString &query)
Definition: kurl.cpp:1568
KUrl::setPath
void setPath(const QString &path)
Definition: kurl.cpp:1770
KUrl::setUser
void setUser(const QString &user)
Sets the user name (login, user id, ...) included in the URL.
Definition: kurl.cpp:686
operator==
bool operator==(const KEntry &k1, const KEntry &k2)
Definition: kconfigdata.h:72
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:676
KUrl::addPath
void addPath(const QString &txt)
Adds to the current path.
Definition: kurl.cpp:1342
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:624
KUrl::hasRef
bool hasRef() const
Checks whether the URL has a reference/fragment part.
Definition: kurl.cpp:1886
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:1062
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:681
KUrl::protocol
QString protocol() const
Returns the protocol for the URL (i.e., file, http, etc.), lowercased.
Definition: kurl.cpp:671
KUrl::upUrl
KUrl upUrl() const
This function is useful to implement the &quot;Up&quot; button in a file manager for example.
Definition: kurl.cpp:1475
KUrl::pass
QString pass() const
Returns the decoded password (corresponding to user()) included in the URL.
Definition: kurl.cpp:696
QStringList
KUrl::CompareWithoutFragment
disables comparison of HTML-style references.
Definition: kurl.h:919
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:1163
KDebug::registerArea
static int registerArea(const QByteArray &areaName, bool enabled=true)
Definition: kdebug.cpp:856
KUrl::setPass
void setPass(const QString &pass)
Sets the password (corresponding to user()) included in the URL.
Definition: kurl.cpp:701
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:1209
KUrl::hasUser
bool hasUser() const
Test to see if this URL has a user name included in it.
Definition: kurl.cpp:691
IS_LETTER
#define IS_LETTER(c)
KUrl::path
QString path(AdjustPathOption trailing=LeaveTrailingSlash) const
Definition: kurl.cpp:872
KUrl::hasPath
bool hasPath() const
Test to see if this URL has a path is included in it.
Definition: kurl.cpp:716
KUrl::CaseInsensitiveKeys
Definition: kurl.h:671
KUrl::setHTMLRef
void setHTMLRef(const QString &_ref)
Sets the HTML-style reference.
Definition: kurl.cpp:1534
KUrl::htmlRef
QString htmlRef() const
Returns the HTML reference (the part of the URL after &quot;#&quot;).
Definition: kurl.cpp:1512
IS_SLASH_AND_DRIVE_OR_DOUBLESLASH_0
#define IS_SLASH_AND_DRIVE_OR_DOUBLESLASH_0
KUrl::AdjustPathOption
AdjustPathOption
Options to be used in adjustPath.
Definition: kurl.h:120
qHash
uint qHash(const KUrl &kurl)
Definition: kurl.cpp:1912
KUrl::operator==
bool operator==(const KUrl &_u) const
Definition: kurl.cpp:607
isalpha
#define isalpha(c)
Definition: ctype_test_p.h:85
kWarning
#define kWarning
Definition: kdebug.h:322
_relativePath
static QString _relativePath(const QString &base_dir, const QString &path, bool &isParent)
Definition: kurl.cpp:1686
KGlobal::locale
KLocale * locale()
Returns the global locale object.
Definition: kglobal.cpp:169
KUrl::setFileEncoding
void setFileEncoding(const QString &encoding)
Adds encoding information to url by adding a &quot;charset&quot; parameter.
Definition: kurl.cpp:928
KUrl::List
KUrl::List is a QList that contains KUrls with a few convenience methods.
Definition: kurl.h:146
removeSlashOrFilePrefix
static QString removeSlashOrFilePrefix(const QString &str)
Definition: kurl.cpp:132
KUrl::setFileName
void setFileName(const QString &_txt)
Sets the filename of the path.
Definition: kurl.cpp:728
trailingSlash
static QString trailingSlash(KUrl::AdjustPathOption trailing, const QString &path)
Definition: kurl.cpp:768
KUrl::encodedPathAndQuery
QString encodedPathAndQuery(AdjustPathOption trailing=LeaveTrailingSlash, const EncodedPathAndQueryOptions &options=PermitEmptyPath) const
Returns the encoded path and the query.
Definition: kurl.cpp:815
KUrl::fileName
QString fileName(const DirectoryOptions &options=IgnoreTrailingSlash) const
Returns the filename of the path.
Definition: kurl.cpp:1281
isLocalFile
static bool isLocalFile(const QUrl &url)
Definition: kurl.cpp:904
KUrl::~KUrl
~KUrl()
Destructs the KUrl object.
Definition: kurl.cpp:395
KUrl::CleanPathOption
CleanPathOption
Options to be used in cleanPath.
Definition: kurl.h:463
KUrl::ObeyTrailingSlash
This tells whether a trailing &#39;/&#39; should be ignored.
Definition: kurl.h:743
KUrl::List::toStringList
QStringList toStringList() const
Converts the URLs of this list to a list of strings.
Definition: kurl.cpp:211
KUrl::hasSubUrl
bool hasSubUrl() const
Checks whether the URL has any sub URLs.
Definition: kurl.cpp:1029
KUrl::AppendTrailingSlash
tells whether the returned result should end with &#39;/&#39; or not.
Definition: kurl.h:752
KShell::tildeExpand
QString tildeExpand(const QString &path)
Performs tilde expansion on path.
Definition: kshell.cpp:55
KUrl::query
QString query() const
Returns the query of the URL.
Definition: kurl.cpp:1587
KUrl::KeepDirSeparators
The opposite of SimplifyDirSeparators.
Definition: kurl.h:474
QPair
kDebug
#define kDebug
Definition: kdebug.h:316
KUrl::List::mimeDataTypes
static QStringList mimeDataTypes()
Return the list of mimeTypes that can be decoded by fromMimeData.
Definition: kurl.cpp:305
KUrl::setDirectory
void setDirectory(const QString &dir)
Set the directory to dir, leaving the filename empty.
Definition: kurl.cpp:1560
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:1034
isdigit
#define isdigit(c)
Definition: ctype_test_p.h:87
KGlobal::staticQString
const QString & staticQString(const char *str)
Creates a static QString.
Definition: kglobal.cpp:270
KUrl::AvoidEmptyPath
If set to true then an empty path is substituted by &quot;/&quot; (this is the opposite of PermitEmptyPath) ...
Definition: kurl.h:534
s_kdeUriListMime
static const char s_kdeUriListMime[]
Definition: kurl.cpp:246
KUrl::fromPathOrUrl
static KUrl fromPathOrUrl(const QString &text)
Definition: kurl.cpp:1671
KUrl::isLocalFile
bool isLocalFile() const
Checks whether the file is local.
Definition: kurl.cpp:923
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 &quot;/&quot;, when CompareWithoutTrailingSlash is se...
Definition: kurl.h:929
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:630
KUrl::prettyUrl
QString prettyUrl(AdjustPathOption trailing=LeaveTrailingSlash) const
Returns the URL as string in human-friendly format.
Definition: kurl.cpp:1085
KUrl::NoTextExport
Definition: kurl.h:115
KUrl::join
static KUrl join(const List &_list)
Reverses split().
Definition: kurl.cpp:1259
KUrl::operator=
KUrl & operator=(const KUrl &_u)
Definition: kurl.cpp:601
KUrl::queryItem
QString queryItem(const QString &item) const
Returns the value of a certain query item.
Definition: kurl.cpp:1839
QMap
QList< KUrl >
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Jun 17 2014 17:06:51 by doxygen 1.8.5 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.10.5 API Reference

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