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

KIO

  • sources
  • kde-4.14
  • kdelibs
  • kio
  • kio
kurlcompletion.cpp
Go to the documentation of this file.
1 /* -*- indent-tabs-mode: t; tab-width: 4; c-basic-offset:4 -*-
2 
3  This file is part of the KDE libraries
4  Copyright (C) 2000 David Smith <dsmith@algonet.se>
5  Copyright (C) 2004 Scott Wheeler <wheeler@kde.org>
6 
7  This class was inspired by a previous KUrlCompletion by
8  Henner Zeller <zeller@think.de>
9 
10  This library is free software; you can redistribute it and/or
11  modify it under the terms of the GNU Library General Public
12  License as published by the Free Software Foundation; either
13  version 2 of the License, or (at your option) any later version.
14 
15  This library is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  Library General Public License for more details.
19 
20  You should have received a copy of the GNU Library General Public License
21  along with this library; see the file COPYING.LIB. If not, write to
22  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23  Boston, MA 02110-1301, USA.
24 */
25 
26 #include "kurlcompletion.h"
27 
28 #include <config.h>
29 
30 #include <stdlib.h>
31 #include <assert.h>
32 #include <limits.h>
33 
34 #include <QtCore/QCoreApplication>
35 #include <QtCore/QMutableStringListIterator>
36 #include <QtCore/QRegExp>
37 #include <QtCore/QTimer>
38 #include <QtCore/QDir>
39 #include <QtCore/QDirIterator>
40 #include <QtCore/QFile>
41 #include <QtCore/QTextIStream>
42 #include <QtCore/QThread>
43 #include <QtGui/QActionEvent>
44 
45 #include <kauthorized.h>
46 #include <kdebug.h>
47 #include <kurl.h>
48 #include <kio/job.h>
49 #include <kprotocolmanager.h>
50 #include <kconfig.h>
51 #include <kglobal.h>
52 #include <kglobalsettings.h>
53 #include <kde_file.h>
54 
55 #include <sys/types.h>
56 #include <dirent.h>
57 #include <unistd.h>
58 #include <sys/stat.h>
59 #include <pwd.h>
60 #include <time.h>
61 #include <sys/param.h>
62 #include <kconfiggroup.h>
63 
64 #ifdef Q_WS_WIN
65 #include <kkernel_win.h>
66 #endif
67 
68 static bool expandTilde(QString&);
69 static bool expandEnv(QString&);
70 
71 static QString unescape(const QString& text);
72 
73 // Permission mask for files that are executable by
74 // user, group or other
75 #define MODE_EXE (S_IXUSR | S_IXGRP | S_IXOTH)
76 
77 // Constants for types of completion
78 enum ComplType {CTNone = 0, CTEnv, CTUser, CTMan, CTExe, CTFile, CTUrl, CTInfo};
79 
80 class CompletionThread;
81 
84 // KUrlCompletionPrivate
85 //
86 class KUrlCompletionPrivate
87 {
88 public:
89  KUrlCompletionPrivate(KUrlCompletion* parent)
90  : q(parent),
91  url_auto_completion(true),
92  userListThread(0),
93  dirListThread(0) {
94  }
95 
96  ~KUrlCompletionPrivate();
97 
98  void _k_slotEntries(KIO::Job*, const KIO::UDSEntryList&);
99  void _k_slotIOFinished(KJob*);
100 
101  class MyURL;
102  bool userCompletion(const MyURL& url, QString* match);
103  bool envCompletion(const MyURL& url, QString* match);
104  bool exeCompletion(const MyURL& url, QString* match);
105  bool fileCompletion(const MyURL& url, QString* match);
106  bool urlCompletion(const MyURL& url, QString* match);
107 
108  bool isAutoCompletion();
109 
110  // List the next dir in m_dirs
111  QString listDirectories(const QStringList&,
112  const QString&,
113  bool only_exe = false,
114  bool only_dir = false,
115  bool no_hidden = false,
116  bool stat_files = true);
117 
118  void listUrls(const QList<KUrl> &urls,
119  const QString& filter = QString(),
120  bool only_exe = false,
121  bool no_hidden = false);
122 
123  void addMatches(const QStringList&);
124  QString finished();
125 
126  void init();
127 
128  void setListedUrl(int compl_type /* enum ComplType */,
129  const QString& dir = QString(),
130  const QString& filter = QString(),
131  bool no_hidden = false);
132 
133  bool isListedUrl(int compl_type /* enum ComplType */,
134  const QString& dir = QString(),
135  const QString& filter = QString(),
136  bool no_hidden = false);
137 
138  KUrlCompletion* q;
139  QList<KUrl> list_urls;
140 
141  bool onlyLocalProto;
142 
143  // urlCompletion() in Auto/Popup mode?
144  bool url_auto_completion;
145 
146  // Append '/' to directories in Popup mode?
147  // Doing that stat's all files and is slower
148  bool popup_append_slash;
149 
150  // Keep track of currently listed files to avoid reading them again
151  QString last_path_listed;
152  QString last_file_listed;
153  QString last_prepend;
154  int last_compl_type;
155  int last_no_hidden;
156 
157  QString cwd; // "current directory" = base dir for completion
158 
159  KUrlCompletion::Mode mode; // ExeCompletion, FileCompletion, DirCompletion
160  bool replace_env;
161  bool replace_home;
162  bool complete_url; // if true completing a URL (i.e. 'prepend' is a URL), otherwise a path
163 
164  KIO::ListJob* list_job; // kio job to list directories
165 
166  QString prepend; // text to prepend to listed items
167  QString compl_text; // text to pass on to KCompletion
168 
169  // Filters for files read with kio
170  bool list_urls_only_exe; // true = only list executables
171  bool list_urls_no_hidden;
172  QString list_urls_filter; // filter for listed files
173 
174  CompletionThread* userListThread;
175  CompletionThread* dirListThread;
176 };
177 
183 class CompletionMatchEvent : public QEvent
184 {
185 public:
186  CompletionMatchEvent(CompletionThread* thread) :
187  QEvent(uniqueType()),
188  m_completionThread(thread)
189  {}
190 
191  CompletionThread* completionThread() const {
192  return m_completionThread;
193  }
194  static Type uniqueType() {
195  return Type(User + 61080);
196  }
197 
198 private:
199  CompletionThread* m_completionThread;
200 };
201 
202 class CompletionThread : public QThread
203 {
204 protected:
205  CompletionThread(KUrlCompletionPrivate* receiver) :
206  QThread(),
207  m_prepend(receiver->prepend),
208  m_complete_url(receiver->complete_url),
209  m_receiver(receiver),
210  m_terminationRequested(false)
211  {}
212 
213 public:
214  void requestTermination() {
215  m_terminationRequested = true;
216  }
217  QStringList matches() const {
218  return m_matches;
219  }
220 
221 protected:
222  void addMatch(const QString& match) {
223  m_matches.append(match);
224  }
225  bool terminationRequested() const {
226  return m_terminationRequested;
227  }
228  void done() {
229  if (!m_terminationRequested)
230  qApp->postEvent(m_receiver->q, new CompletionMatchEvent(this));
231  else
232  deleteLater();
233  }
234 
235  const QString m_prepend;
236  const bool m_complete_url; // if true completing a URL (i.e. 'm_prepend' is a URL), otherwise a path
237 
238 private:
239  KUrlCompletionPrivate* m_receiver;
240  QStringList m_matches;
241  bool m_terminationRequested;
242 };
243 
249 class UserListThread : public CompletionThread
250 {
251 public:
252  UserListThread(KUrlCompletionPrivate* receiver) :
253  CompletionThread(receiver)
254  {}
255 
256 protected:
257  virtual void run() {
258  static const QChar tilde = '~';
259 
260  // we don't need to handle prepend here, right? ~user is always at pos 0
261  assert(m_prepend.isEmpty());
262  struct passwd* pw;
263  while ((pw = ::getpwent()) && !terminationRequested())
264  addMatch(tilde + QString::fromLocal8Bit(pw->pw_name));
265 
266  ::endpwent();
267 
268  addMatch(QString(tilde));
269 
270  done();
271  }
272 };
273 
274 class DirectoryListThread : public CompletionThread
275 {
276 public:
277  DirectoryListThread(KUrlCompletionPrivate* receiver,
278  const QStringList& dirList,
279  const QString& filter,
280  bool onlyExe,
281  bool onlyDir,
282  bool noHidden,
283  bool appendSlashToDir) :
284  CompletionThread(receiver),
285  m_dirList(dirList),
286  m_filter(filter),
287  m_onlyExe(onlyExe),
288  m_onlyDir(onlyDir),
289  m_noHidden(noHidden),
290  m_appendSlashToDir(appendSlashToDir)
291  {}
292 
293  virtual void run();
294 
295 private:
296  QStringList m_dirList;
297  QString m_filter;
298  bool m_onlyExe;
299  bool m_onlyDir;
300  bool m_noHidden;
301  bool m_appendSlashToDir;
302 };
303 
304 void DirectoryListThread::run()
305 {
306  // Thread safety notes:
307  //
308  // There very possibly may be thread safety issues here, but I've done a check
309  // of all of the things that would seem to be problematic. Here are a few
310  // things that I have checked to be safe here (some used indirectly):
311  //
312  // QDir::currentPath(), QDir::setCurrent(), QFile::decodeName(), QFile::encodeName()
313  // QString::fromLocal8Bit(), QString::toLocal8Bit(), QTextCodec::codecForLocale()
314  //
315  // Also see (for POSIX functions):
316  // http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_09.html
317 
318  // kDebug() << "Entered DirectoryListThread::run(), m_filter=" << m_filter << ", m_onlyExe=" << m_onlyExe << ", m_onlyDir=" << m_onlyDir << ", m_appendSlashToDir=" << m_appendSlashToDir << ", m_dirList.size()=" << m_dirList.size();
319 
320  QStringList::ConstIterator end = m_dirList.constEnd();
321  for (QStringList::ConstIterator it = m_dirList.constBegin();
322  it != end && !terminationRequested();
323  ++it) {
324  // kDebug() << "Scanning directory" << *it;
325 
326  // A trick from KIO that helps performance by a little bit:
327  // chdir to the directory so we won't have to deal with full paths
328  // with stat()
329 
330  QString path = QDir::currentPath();
331  QDir::setCurrent(*it);
332 
333  QDir::Filters iterator_filter = (m_noHidden ? QDir::Filter(0) : QDir::Hidden) | QDir::Readable | QDir::NoDotAndDotDot;
334 
335  if (m_onlyExe)
336  iterator_filter |= (QDir::Dirs | QDir::Files | QDir::Executable);
337  else if (m_onlyDir)
338  iterator_filter |= QDir::Dirs;
339  else
340  iterator_filter |= (QDir::Dirs | QDir::Files);
341 
342  QDirIterator current_dir_iterator(*it, iterator_filter);
343 
344  while (current_dir_iterator.hasNext()) {
345  current_dir_iterator.next();
346 
347  QFileInfo file_info = current_dir_iterator.fileInfo();
348  const QString file_name = file_info.fileName();
349 
350  //kDebug() << "Found" << file_name;
351 
352  if (m_filter.isEmpty() || file_name.startsWith(m_filter)) {
353 
354  QString toAppend = file_name;
355  // Add '/' to directories
356  if (m_appendSlashToDir && file_info.isDir())
357  toAppend.append(QLatin1Char('/'));
358 
359  if (m_complete_url) {
360  KUrl url(m_prepend);
361  url.addPath(toAppend);
362  addMatch(url.prettyUrl());
363  } else {
364  addMatch(m_prepend + toAppend);
365  }
366  }
367  }
368 
369  // chdir to the original directory
370  QDir::setCurrent(path);
371  }
372 
373  done();
374 }
375 
376 KUrlCompletionPrivate::~KUrlCompletionPrivate()
377 {
378  if (userListThread)
379  userListThread->requestTermination();
380  if (dirListThread)
381  dirListThread->requestTermination();
382 }
383 
386 // MyURL - wrapper for KUrl with some different functionality
387 //
388 
389 class KUrlCompletionPrivate::MyURL
390 {
391 public:
392  MyURL(const QString& url, const QString& cwd);
393  MyURL(const MyURL& url);
394  ~MyURL();
395 
396  KUrl kurl() const {
397  return m_kurl;
398  }
399 
400  QString protocol() const {
401  return m_kurl.protocol();
402  }
403  // The directory with a trailing '/'
404  QString dir() const {
405  return m_kurl.directory(KUrl::AppendTrailingSlash | KUrl::ObeyTrailingSlash);
406  }
407  QString file() const {
408  return m_kurl.fileName(KUrl::ObeyTrailingSlash);
409  }
410 
411  // The initial, unparsed, url, as a string.
412  QString url() const {
413  return m_url;
414  }
415 
416  // Is the initial string a URL, or just a path (whether absolute or relative)
417  bool isURL() const {
418  return m_isURL;
419  }
420 
421  void filter(bool replace_user_dir, bool replace_env);
422 
423 private:
424  void init(const QString& url, const QString& cwd);
425 
426  KUrl m_kurl;
427  QString m_url;
428  bool m_isURL;
429 };
430 
431 KUrlCompletionPrivate::MyURL::MyURL(const QString& _url, const QString& cwd)
432 {
433  init(_url, cwd);
434 }
435 
436 KUrlCompletionPrivate::MyURL::MyURL(const MyURL& _url)
437  : m_kurl(_url.m_kurl)
438 {
439  m_url = _url.m_url;
440  m_isURL = _url.m_isURL;
441 }
442 
443 void KUrlCompletionPrivate::MyURL::init(const QString& _url, const QString& cwd)
444 {
445  // Save the original text
446  m_url = _url;
447 
448  // Non-const copy
449  QString url_copy = _url;
450 
451  // Special shortcuts for "man:" and "info:"
452  if (url_copy.startsWith(QLatin1Char('#'))) {
453  if (url_copy.length() > 1 && url_copy.at(1) == QLatin1Char('#'))
454  url_copy.replace(0, 2, QLatin1String("info:"));
455  else
456  url_copy.replace(0, 1, QLatin1String("man:"));
457  }
458 
459  // Look for a protocol in 'url'
460  QRegExp protocol_regex = QRegExp("^(?![A-Za-z]:)[^/\\s\\\\]*:");
461 
462  // Assume "file:" or whatever is given by 'cwd' if there is
463  // no protocol. (KUrl does this only for absolute paths)
464  if (protocol_regex.indexIn(url_copy) == 0) {
465  m_kurl = KUrl(url_copy);
466  m_isURL = true;
467  } else { // relative path or ~ or $something
468  m_isURL = false;
469  if (!QDir::isRelativePath(url_copy) ||
470  url_copy.startsWith(QLatin1Char('~')) ||
471  url_copy.startsWith(QLatin1Char('$'))) {
472  m_kurl = KUrl();
473  m_kurl.setPath(url_copy);
474  } else {
475  if (cwd.isEmpty()) {
476  m_kurl = KUrl(url_copy);
477  } else {
478  m_kurl = KUrl(cwd);
479  m_kurl.addPath(url_copy);
480  }
481  }
482  }
483 }
484 
485 KUrlCompletionPrivate::MyURL::~MyURL()
486 {
487 }
488 
489 void KUrlCompletionPrivate::MyURL::filter(bool replace_user_dir, bool replace_env)
490 {
491  QString d = dir() + file();
492  if (replace_user_dir) expandTilde(d);
493  if (replace_env) expandEnv(d);
494  m_kurl.setPath(d);
495 }
496 
499 // KUrlCompletion
500 //
501 
502 KUrlCompletion::KUrlCompletion() : KCompletion(), d(new KUrlCompletionPrivate(this))
503 {
504  d->init();
505 }
506 
507 
508 KUrlCompletion::KUrlCompletion(Mode _mode)
509  : KCompletion(),
510  d(new KUrlCompletionPrivate(this))
511 {
512  d->init();
513  setMode(_mode);
514 }
515 
516 KUrlCompletion::~KUrlCompletion()
517 {
518  stop();
519  delete d;
520 }
521 
522 
523 void KUrlCompletionPrivate::init()
524 {
525  cwd = QDir::homePath();
526 
527  replace_home = true;
528  replace_env = true;
529  last_no_hidden = false;
530  last_compl_type = 0;
531  list_job = 0L;
532  mode = KUrlCompletion::FileCompletion;
533 
534  // Read settings
535  KConfigGroup cg(KGlobal::config(), "URLCompletion");
536 
537  url_auto_completion = cg.readEntry("alwaysAutoComplete", true);
538  popup_append_slash = cg.readEntry("popupAppendSlash", true);
539  onlyLocalProto = cg.readEntry("LocalProtocolsOnly", false);
540 
541  q->setIgnoreCase(true);
542 }
543 
544 void KUrlCompletion::setDir(const QString& _dir)
545 {
546  d->cwd = _dir;
547 }
548 
549 QString KUrlCompletion::dir() const
550 {
551  return d->cwd;
552 }
553 
554 KUrlCompletion::Mode KUrlCompletion::mode() const
555 {
556  return d->mode;
557 }
558 
559 void KUrlCompletion::setMode(Mode _mode)
560 {
561  d->mode = _mode;
562 }
563 
564 bool KUrlCompletion::replaceEnv() const
565 {
566  return d->replace_env;
567 }
568 
569 void KUrlCompletion::setReplaceEnv(bool replace)
570 {
571  d->replace_env = replace;
572 }
573 
574 bool KUrlCompletion::replaceHome() const
575 {
576  return d->replace_home;
577 }
578 
579 void KUrlCompletion::setReplaceHome(bool replace)
580 {
581  d->replace_home = replace;
582 }
583 
584 /*
585  * makeCompletion()
586  *
587  * Entry point for file name completion
588  */
589 QString KUrlCompletion::makeCompletion(const QString& text)
590 {
591  //kDebug() << text << "d->cwd=" << d->cwd;
592 
593  KUrlCompletionPrivate::MyURL url(text, d->cwd);
594 
595  d->compl_text = text;
596 
597  // Set d->prepend to the original URL, with the filename [and ref/query] stripped.
598  // This is what gets prepended to the directory-listing matches.
599  int toRemove = url.file().length() - url.kurl().query().length();
600  if (url.kurl().hasRef())
601  toRemove += url.kurl().ref().length() + 1;
602  d->prepend = text.left(text.length() - toRemove);
603  d->complete_url = url.isURL();
604 
605  QString aMatch;
606 
607  // Environment variables
608  //
609  if (d->replace_env && d->envCompletion(url, &aMatch))
610  return aMatch;
611 
612  // User directories
613  //
614  if (d->replace_home && d->userCompletion(url, &aMatch))
615  return aMatch;
616 
617  // Replace user directories and variables
618  url.filter(d->replace_home, d->replace_env);
619 
620  //kDebug() << "Filtered: proto=" << url.protocol()
621  // << ", dir=" << url.dir()
622  // << ", file=" << url.file()
623  // << ", kurl url=" << *url.kurl();
624 
625  if (d->mode == ExeCompletion) {
626  // Executables
627  //
628  if (d->exeCompletion(url, &aMatch))
629  return aMatch;
630 
631  // KRun can run "man:" and "info:" etc. so why not treat them
632  // as executables...
633 
634  if (d->urlCompletion(url, &aMatch))
635  return aMatch;
636  } else {
637  // Local files, directories
638  //
639  if (d->fileCompletion(url, &aMatch))
640  return aMatch;
641 
642  // All other...
643  //
644  if (d->urlCompletion(url, &aMatch))
645  return aMatch;
646  }
647 
648  d->setListedUrl(CTNone);
649  stop();
650 
651  return QString();
652 }
653 
654 /*
655  * finished
656  *
657  * Go on and call KCompletion.
658  * Called when all matches have been added
659  */
660 QString KUrlCompletionPrivate::finished()
661 {
662  if (last_compl_type == CTInfo)
663  return q->KCompletion::makeCompletion(compl_text.toLower());
664  else
665  return q->KCompletion::makeCompletion(compl_text);
666 }
667 
668 /*
669  * isRunning
670  *
671  * Return true if either a KIO job or the DirLister
672  * is running
673  */
674 bool KUrlCompletion::isRunning() const
675 {
676  return d->list_job || (d->dirListThread && !d->dirListThread->isFinished());
677 }
678 
679 /*
680  * stop
681  *
682  * Stop and delete a running KIO job or the DirLister
683  */
684 void KUrlCompletion::stop()
685 {
686  if (d->list_job) {
687  d->list_job->kill();
688  d->list_job = 0L;
689  }
690 
691  if (d->dirListThread) {
692  d->dirListThread->requestTermination();
693  d->dirListThread = 0;
694  }
695 }
696 
697 /*
698  * Keep track of the last listed directory
699  */
700 void KUrlCompletionPrivate::setListedUrl(int complType,
701  const QString& directory,
702  const QString& filter,
703  bool no_hidden)
704 {
705  last_compl_type = complType;
706  last_path_listed = directory;
707  last_file_listed = filter;
708  last_no_hidden = (int) no_hidden;
709  last_prepend = prepend;
710 }
711 
712 bool KUrlCompletionPrivate::isListedUrl(int complType,
713  const QString& directory,
714  const QString& filter,
715  bool no_hidden)
716 {
717  return last_compl_type == complType
718  && (last_path_listed == directory
719  || (directory.isEmpty() && last_path_listed.isEmpty()))
720  && (filter.startsWith (last_file_listed)
721  || (filter.isEmpty() && last_file_listed.isEmpty()))
722  && last_no_hidden == (int) no_hidden
723  && last_prepend == prepend; // e.g. relative path vs absolute
724 }
725 
726 /*
727  * isAutoCompletion
728  *
729  * Returns true if completion mode is Auto or Popup
730  */
731 bool KUrlCompletionPrivate::isAutoCompletion()
732 {
733  return q->completionMode() == KGlobalSettings::CompletionAuto
734  || q->completionMode() == KGlobalSettings::CompletionPopup
735  || q->completionMode() == KGlobalSettings::CompletionMan
736  || q->completionMode() == KGlobalSettings::CompletionPopupAuto;
737 }
740 // User directories
741 //
742 
743 bool KUrlCompletionPrivate::userCompletion(const KUrlCompletionPrivate::MyURL& url, QString* pMatch)
744 {
745  if (url.protocol() != QLatin1String("file")
746  || !url.dir().isEmpty()
747  || !url.file().startsWith(QLatin1Char('~')))
748  return false;
749 
750  if (!isListedUrl(CTUser)) {
751  q->stop();
752  q->clear();
753 
754  if (!userListThread) {
755  userListThread = new UserListThread(this);
756  userListThread->start();
757 
758  // If the thread finishes quickly make sure that the results
759  // are added to the first matching case.
760 
761  userListThread->wait(200);
762  const QStringList l = userListThread->matches();
763  addMatches(l);
764  }
765  }
766  *pMatch = finished();
767  return true;
768 }
769 
772 // Environment variables
773 //
774 
775 #ifndef Q_OS_WIN
776 extern char** environ; // Array of environment variables
777 #endif
778 
779 bool KUrlCompletionPrivate::envCompletion(const KUrlCompletionPrivate::MyURL& url, QString* pMatch)
780 {
781  if (url.file().isEmpty() || url.file().at(0) != QLatin1Char('$'))
782  return false;
783 
784  if (!isListedUrl(CTEnv)) {
785  q->stop();
786  q->clear();
787 
788  char** env = environ;
789 
790  QString dollar = QLatin1String("$");
791 
792  QStringList l;
793 
794  while (*env) {
795  QString s = QString::fromLocal8Bit(*env);
796 
797  int pos = s.indexOf(QLatin1Char('='));
798 
799  if (pos == -1)
800  pos = s.length();
801 
802  if (pos > 0)
803  l.append(prepend + dollar + s.left(pos));
804 
805  env++;
806  }
807 
808  addMatches(l);
809  }
810 
811  setListedUrl(CTEnv);
812 
813  *pMatch = finished();
814  return true;
815 }
816 
819 // Executables
820 //
821 
822 bool KUrlCompletionPrivate::exeCompletion(const KUrlCompletionPrivate::MyURL& url, QString* pMatch)
823 {
824  if (url.protocol() != QLatin1String("file"))
825  return false;
826 
827  QString directory = unescape(url.dir()); // remove escapes
828 
829  // Find directories to search for completions, either
830  //
831  // 1. complete path given in url
832  // 2. current directory (d->cwd)
833  // 3. $PATH
834  // 4. no directory at all
835 
836  QStringList dirList;
837 
838  if (!url.file().isEmpty()) {
839  // $PATH
840  dirList = QString::fromLocal8Bit(qgetenv("PATH")).split(
841  KPATH_SEPARATOR, QString::SkipEmptyParts);
842 
843  QStringList::Iterator it = dirList.begin();
844 
845  for (; it != dirList.end(); ++it)
846  it->append(QLatin1Char('/'));
847  } else if (!QDir::isRelativePath(directory)) {
848  // complete path in url
849  dirList.append(directory);
850  } else if (!directory.isEmpty() && !cwd.isEmpty()) {
851  // current directory
852  dirList.append(cwd + QLatin1Char('/') + directory);
853  }
854 
855  // No hidden files unless the user types "."
856  bool no_hidden_files = url.file().isEmpty() || url.file().at(0) != QLatin1Char('.');
857 
858  // List files if needed
859  //
860  if (!isListedUrl(CTExe, directory, url.file(), no_hidden_files)) {
861  q->stop();
862  q->clear();
863 
864  setListedUrl(CTExe, directory, url.file(), no_hidden_files);
865 
866  *pMatch = listDirectories(dirList, url.file(), true, false, no_hidden_files);
867  } else if (!q->isRunning()) {
868  *pMatch = finished();
869  } else {
870  if (dirListThread)
871  setListedUrl(CTExe, directory, url.file(), no_hidden_files);
872  pMatch->clear();
873  }
874 
875  return true;
876 }
877 
880 // Local files
881 //
882 
883 bool KUrlCompletionPrivate::fileCompletion(const KUrlCompletionPrivate::MyURL& url, QString* pMatch)
884 {
885  if (url.protocol() != QLatin1String("file"))
886  return false;
887 
888  QString directory = unescape(url.dir());
889 
890  if (url.url().length() && url.url().at(0) == QLatin1Char('.')) {
891  if (url.url().length() == 1) {
892  *pMatch = (q->completionMode() == KGlobalSettings::CompletionMan) ?
893  QLatin1String(".") :
894  QLatin1String("..");
895  return true;
896  } else if (url.url().length() == 2 && url.url().at(1) == QLatin1Char('.')) {
897  *pMatch = QLatin1String("..");
898  return true;
899  }
900  }
901 
902  //kDebug() << "fileCompletion" << url << "dir=" << dir;
903 
904  // Find directories to search for completions, either
905  //
906  // 1. complete path given in url
907  // 2. current directory (d->cwd)
908  // 3. no directory at all
909 
910  QStringList dirList;
911 
912  if (!QDir::isRelativePath(directory)) {
913  // complete path in url
914  dirList.append(directory);
915  } else if (!cwd.isEmpty()) {
916  // current directory
917  QString dirToAdd = cwd;
918  if (!directory.isEmpty()) {
919  if (!cwd.endsWith('/'))
920  dirToAdd.append(QLatin1Char('/'));
921  dirToAdd.append(directory);
922  }
923  dirList.append(dirToAdd);
924  }
925 
926  // No hidden files unless the user types "."
927  bool no_hidden_files = !url.file().startsWith(QLatin1Char('.'));
928 
929  // List files if needed
930  //
931  if (!isListedUrl(CTFile, directory, QString(), no_hidden_files)) {
932  q->stop();
933  q->clear();
934 
935  setListedUrl(CTFile, directory, QString(), no_hidden_files);
936 
937  // Append '/' to directories in Popup mode?
938  bool append_slash = (popup_append_slash
939  && (q->completionMode() == KGlobalSettings::CompletionPopup ||
940  q->completionMode() == KGlobalSettings::CompletionPopupAuto));
941 
942  bool only_dir = (mode == KUrlCompletion::DirCompletion);
943 
944  *pMatch = listDirectories(dirList, QString(), false, only_dir, no_hidden_files,
945  append_slash);
946  } else if (!q->isRunning()) {
947  *pMatch = finished();
948  } else {
949  pMatch->clear();
950  }
951 
952  return true;
953 }
954 
957 // URLs not handled elsewhere...
958 //
959 
960 static bool isLocalProtocol(const QString& protocol)
961 {
962  return (KProtocolInfo::protocolClass(protocol) == QLatin1String(":local"));
963 }
964 
965 bool KUrlCompletionPrivate::urlCompletion(const KUrlCompletionPrivate::MyURL& url, QString* pMatch)
966 {
967  //kDebug() << *url.kurl();
968  if (onlyLocalProto && isLocalProtocol(url.protocol()))
969  return false;
970 
971  // Use d->cwd as base url in case url is not absolute
972  KUrl url_dir = url.kurl();
973  if (url_dir.isRelative() && !cwd.isEmpty()) {
974  const KUrl url_cwd (cwd);
975  // Create an URL with the directory to be listed
976  url_dir = KUrl(url_cwd, url_dir.url());
977  }
978 
979  // url is malformed
980  if (!url_dir.isValid())
981  return false;
982 
983  // non local urls
984  if (!isLocalProtocol(url.protocol())) {
985  // url does not specify host
986  if (url_dir.host().isEmpty())
987  return false;
988 
989  // url does not specify a valid directory
990  if (url_dir.directory(KUrl::AppendTrailingSlash | KUrl::ObeyTrailingSlash).isEmpty())
991  return false;
992 
993  // automatic completion is disabled
994  if (isAutoCompletion() && !url_auto_completion)
995  return false;
996  }
997 
998  // url handler doesn't support listing
999  if (!KProtocolManager::supportsListing(url_dir))
1000  return false;
1001 
1002  url_dir.setFileName(QString()); // not really nesseccary, but clear the filename anyway...
1003 
1004  // Remove escapes
1005  QString directory = unescape(url_dir.directory(KUrl::AppendTrailingSlash | KUrl::ObeyTrailingSlash));
1006 
1007  url_dir.setPath(directory);
1008 
1009  // List files if needed
1010  //
1011  if (!isListedUrl(CTUrl, url_dir.prettyUrl(), url.file())) {
1012  q->stop();
1013  q->clear();
1014 
1015  setListedUrl(CTUrl, url_dir.prettyUrl(), QString());
1016 
1017  QList<KUrl> url_list;
1018  url_list.append(url_dir);
1019 
1020  listUrls(url_list, QString(), false);
1021 
1022  pMatch->clear();
1023  } else if (!q->isRunning()) {
1024  *pMatch = finished();
1025  } else {
1026  pMatch->clear();
1027  }
1028 
1029  return true;
1030 }
1031 
1034 // Directory and URL listing
1035 //
1036 
1037 /*
1038  * addMatches
1039  *
1040  * Called to add matches to KCompletion
1041  */
1042 void KUrlCompletionPrivate::addMatches(const QStringList& matchList)
1043 {
1044  q->insertItems(matchList);
1045 }
1046 
1047 /*
1048  * listDirectories
1049  *
1050  * List files starting with 'filter' in the given directories,
1051  * either using DirLister or listURLs()
1052  *
1053  * In either case, addMatches() is called with the listed
1054  * files, and eventually finished() when the listing is done
1055  *
1056  * Returns the match if available, or QString() if
1057  * DirLister timed out or using kio
1058  */
1059 QString KUrlCompletionPrivate::listDirectories(
1060  const QStringList& dirList,
1061  const QString& filter,
1062  bool only_exe,
1063  bool only_dir,
1064  bool no_hidden,
1065  bool append_slash_to_dir)
1066 {
1067  assert(!q->isRunning());
1068 
1069  if (qgetenv("KURLCOMPLETION_LOCAL_KIO").isEmpty()) {
1070 
1071  //kDebug() << "Listing (listDirectories):" << dirList << "filter=" << filter << "without KIO";
1072 
1073  // Don't use KIO
1074 
1075  if (dirListThread)
1076  dirListThread->requestTermination();
1077 
1078  QStringList dirs;
1079 
1080  QStringList::ConstIterator end = dirList.constEnd();
1081  for (QStringList::ConstIterator it = dirList.constBegin();
1082  it != end;
1083  ++it) {
1084  KUrl url;
1085  url.setPath(*it);
1086  if (KAuthorized::authorizeUrlAction(QLatin1String("list"), KUrl(), url))
1087  dirs.append(*it);
1088  }
1089 
1090  dirListThread = new DirectoryListThread(this, dirs, filter, only_exe, only_dir,
1091  no_hidden, append_slash_to_dir);
1092  dirListThread->start();
1093  dirListThread->wait(200);
1094  addMatches(dirListThread->matches());
1095 
1096  return finished();
1097  }
1098 
1099  // Use KIO
1100  //kDebug() << "Listing (listDirectories):" << dirList << "with KIO";
1101 
1102  QList<KUrl> url_list;
1103 
1104  QStringList::ConstIterator it = dirList.constBegin();
1105  QStringList::ConstIterator end = dirList.constEnd();
1106 
1107  for (; it != end; ++it) {
1108  url_list.append(KUrl(*it));
1109  }
1110 
1111  listUrls(url_list, filter, only_exe, no_hidden);
1112  // Will call addMatches() and finished()
1113 
1114  return QString();
1115 }
1116 
1117 /*
1118  * listURLs
1119  *
1120  * Use KIO to list the given urls
1121  *
1122  * addMatches() is called with the listed files
1123  * finished() is called when the listing is done
1124  */
1125 void KUrlCompletionPrivate::listUrls(
1126  const QList<KUrl> &urls,
1127  const QString& filter,
1128  bool only_exe,
1129  bool no_hidden)
1130 {
1131  assert(list_urls.isEmpty());
1132  assert(list_job == 0L);
1133 
1134  list_urls = urls;
1135  list_urls_filter = filter;
1136  list_urls_only_exe = only_exe;
1137  list_urls_no_hidden = no_hidden;
1138 
1139  //kDebug() << "Listing URLs:" << *urls[0] << ",...";
1140 
1141  // Start it off by calling _k_slotIOFinished
1142  //
1143  // This will start a new list job as long as there
1144  // are urls in d->list_urls
1145  //
1146  _k_slotIOFinished(0);
1147 }
1148 
1149 /*
1150  * _k_slotEntries
1151  *
1152  * Receive files listed by KIO and call addMatches()
1153  */
1154 void KUrlCompletionPrivate::_k_slotEntries(KIO::Job*, const KIO::UDSEntryList& entries)
1155 {
1156  QStringList matchList;
1157 
1158  KIO::UDSEntryList::ConstIterator it = entries.constBegin();
1159  const KIO::UDSEntryList::ConstIterator end = entries.constEnd();
1160 
1161  QString filter = list_urls_filter;
1162 
1163  int filter_len = filter.length();
1164 
1165  // Iterate over all files
1166  //
1167  for (; it != end; ++it) {
1168  const KIO::UDSEntry& entry = *it;
1169  const QString url = entry.stringValue(KIO::UDSEntry::UDS_URL);
1170 
1171  QString entry_name;
1172  if (!url.isEmpty()) {
1173  // kDebug() << "url:" << url;
1174  entry_name = KUrl(url).fileName();
1175  } else {
1176  entry_name = entry.stringValue(KIO::UDSEntry::UDS_NAME);
1177  }
1178 
1179  // kDebug() << "name:" << name;
1180 
1181  if ((!entry_name.isEmpty() && entry_name.at(0) == QLatin1Char('.')) &&
1182  (list_urls_no_hidden ||
1183  entry_name.length() == 1 ||
1184  (entry_name.length() == 2 && entry_name.at(1) == QLatin1Char('.'))))
1185  continue;
1186 
1187  const bool isDir = entry.isDir();
1188 
1189  if (mode == KUrlCompletion::DirCompletion && !isDir)
1190  continue;
1191 
1192  if (filter_len == 0 || entry_name.left(filter_len) == filter) {
1193 
1194  QString toAppend = entry_name;
1195 
1196  if (isDir)
1197  toAppend.append(QLatin1Char('/'));
1198 
1199  if (!list_urls_only_exe ||
1200  (entry.numberValue(KIO::UDSEntry::UDS_ACCESS) & MODE_EXE) // true if executable
1201  ) {
1202  if (complete_url) {
1203  KUrl url(prepend);
1204  url.addPath(toAppend);
1205  matchList.append(url.prettyUrl());
1206  } else {
1207  matchList.append(prepend + toAppend);
1208  }
1209  }
1210  }
1211  }
1212 
1213  addMatches(matchList);
1214 }
1215 
1216 /*
1217  * _k_slotIOFinished
1218  *
1219  * Called when a KIO job is finished.
1220  *
1221  * Start a new list job if there are still urls in
1222  * list_urls, otherwise call finished()
1223  */
1224 void KUrlCompletionPrivate::_k_slotIOFinished(KJob* job)
1225 {
1226  assert(job == list_job); Q_UNUSED(job)
1227 
1228  if (list_urls.isEmpty()) {
1229 
1230  list_job = 0L;
1231 
1232  finished(); // will call KCompletion::makeCompletion()
1233 
1234  } else {
1235 
1236  KUrl kurl(list_urls.takeFirst());
1237 
1238 // list_urls.removeAll( kurl );
1239 
1240 // kDebug() << "Start KIO::listDir" << kurl;
1241 
1242  list_job = KIO::listDir(kurl, KIO::HideProgressInfo);
1243  list_job->addMetaData("no-auth-prompt", "true");
1244 
1245  assert(list_job);
1246 
1247  q->connect(list_job,
1248  SIGNAL(result(KJob*)),
1249  SLOT(_k_slotIOFinished(KJob*)));
1250 
1251  q->connect(list_job,
1252  SIGNAL(entries(KIO::Job*,KIO::UDSEntryList)),
1253  SLOT(_k_slotEntries(KIO::Job*,KIO::UDSEntryList)));
1254  }
1255 }
1256 
1259 
1260 /*
1261  * postProcessMatch, postProcessMatches
1262  *
1263  * Called by KCompletion before emitting match() and matches()
1264  *
1265  * Append '/' to directories for file completion. This is
1266  * done here to avoid stat()'ing a lot of files
1267  */
1268 void KUrlCompletion::postProcessMatch(QString* pMatch) const
1269 {
1270 // kDebug() << *pMatch;
1271 
1272  if (!pMatch->isEmpty()) {
1273 
1274  // Add '/' to directories in file completion mode
1275  // unless it has already been done
1276  if (d->last_compl_type == CTFile
1277  && pMatch->at(pMatch->length() - 1) != QLatin1Char('/')) {
1278  QString copy;
1279 
1280  if (pMatch->startsWith(QLatin1String("file:")))
1281  copy = KUrl(*pMatch).toLocalFile();
1282  else
1283  copy = *pMatch;
1284 
1285  expandTilde(copy);
1286  expandEnv(copy);
1287 #ifdef Q_WS_WIN
1288  DWORD dwAttr = GetFileAttributesW((LPCWSTR) copy.utf16());
1289  if (dwAttr == INVALID_FILE_ATTRIBUTES) {
1290  kDebug() << "Could not get file attribs ( "
1291  << GetLastError()
1292  << " ) for "
1293  << copy;
1294  } else if ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
1295  pMatch->append(QLatin1Char('/'));
1296 #else
1297  if (QDir::isRelativePath(copy))
1298  copy.prepend(d->cwd + QLatin1Char('/'));
1299 
1300 // kDebug() << "stat'ing" << copy;
1301 
1302  KDE_struct_stat sbuff;
1303 
1304  QByteArray file = QFile::encodeName(copy);
1305 
1306  if (KDE_stat(file.data(), &sbuff) == 0) {
1307  if (S_ISDIR(sbuff.st_mode))
1308  pMatch->append(QLatin1Char('/'));
1309  } else {
1310  kDebug() << "Could not stat file" << copy;
1311  }
1312 #endif
1313  }
1314  }
1315 }
1316 
1317 void KUrlCompletion::postProcessMatches(QStringList* /*matches*/) const
1318 {
1319  // Maybe '/' should be added to directories here as in
1320  // postProcessMatch() but it would slow things down
1321  // when there are a lot of matches...
1322 }
1323 
1324 void KUrlCompletion::postProcessMatches(KCompletionMatches* /*matches*/) const
1325 {
1326  // Maybe '/' should be added to directories here as in
1327  // postProcessMatch() but it would slow things down
1328  // when there are a lot of matches...
1329 }
1330 
1331 void KUrlCompletion::customEvent(QEvent* e)
1332 {
1333  if (e->type() == CompletionMatchEvent::uniqueType()) {
1334 
1335  CompletionMatchEvent* matchEvent = static_cast<CompletionMatchEvent*>(e);
1336 
1337  matchEvent->completionThread()->wait();
1338 
1339  if (!d->isListedUrl(CTUser)) {
1340  stop();
1341  clear();
1342  d->addMatches(matchEvent->completionThread()->matches());
1343  } else {
1344  d->setListedUrl(CTUser);
1345  }
1346 
1347  if (d->userListThread == matchEvent->completionThread())
1348  d->userListThread = 0;
1349 
1350  if (d->dirListThread == matchEvent->completionThread())
1351  d->dirListThread = 0;
1352 
1353  delete matchEvent->completionThread();
1354  }
1355 }
1356 
1357 // static
1358 QString KUrlCompletion::replacedPath(const QString& text, bool replaceHome, bool replaceEnv)
1359 {
1360  if (text.isEmpty())
1361  return text;
1362 
1363  KUrlCompletionPrivate::MyURL url(text, QString()); // no need to replace something of our current cwd
1364  if (!url.kurl().isLocalFile())
1365  return text;
1366 
1367  url.filter(replaceHome, replaceEnv);
1368  return url.dir() + url.file();
1369 }
1370 
1371 
1372 QString KUrlCompletion::replacedPath(const QString& text) const
1373 {
1374  return replacedPath(text, d->replace_home, d->replace_env);
1375 }
1376 
1379 // Static functions
1380 
1381 /*
1382  * expandEnv
1383  *
1384  * Expand environment variables in text. Escaped '$' are ignored.
1385  * Return true if expansion was made.
1386  */
1387 static bool expandEnv(QString& text)
1388 {
1389  // Find all environment variables beginning with '$'
1390  //
1391  int pos = 0;
1392 
1393  bool expanded = false;
1394 
1395  while ((pos = text.indexOf(QLatin1Char('$'), pos)) != -1) {
1396 
1397  // Skip escaped '$'
1398  //
1399  if (pos > 0 && text.at(pos - 1) == QLatin1Char('\\')) {
1400  pos++;
1401  }
1402  // Variable found => expand
1403  //
1404  else {
1405  // Find the end of the variable = next '/' or ' '
1406  //
1407  int pos2 = text.indexOf(QLatin1Char(' '), pos + 1);
1408  int pos_tmp = text.indexOf(QLatin1Char('/'), pos + 1);
1409 
1410  if (pos2 == -1 || (pos_tmp != -1 && pos_tmp < pos2))
1411  pos2 = pos_tmp;
1412 
1413  if (pos2 == -1)
1414  pos2 = text.length();
1415 
1416  // Replace if the variable is terminated by '/' or ' '
1417  // and defined
1418  //
1419  if (pos2 >= 0) {
1420  int len = pos2 - pos;
1421  QString key = text.mid(pos + 1, len - 1);
1422  QString value =
1423  QString::fromLocal8Bit(qgetenv(key.toLocal8Bit()));
1424 
1425  if (!value.isEmpty()) {
1426  expanded = true;
1427  text.replace(pos, len, value);
1428  pos = pos + value.length();
1429  } else {
1430  pos = pos2;
1431  }
1432  }
1433  }
1434  }
1435 
1436  return expanded;
1437 }
1438 
1439 /*
1440  * expandTilde
1441  *
1442  * Replace "~user" with the users home directory
1443  * Return true if expansion was made.
1444  */
1445 static bool expandTilde(QString& text)
1446 {
1447  if (text.isEmpty() || (text.at(0) != QLatin1Char('~')))
1448  return false;
1449 
1450  bool expanded = false;
1451 
1452  // Find the end of the user name = next '/' or ' '
1453  //
1454  int pos2 = text.indexOf(QLatin1Char(' '), 1);
1455  int pos_tmp = text.indexOf(QLatin1Char('/'), 1);
1456 
1457  if (pos2 == -1 || (pos_tmp != -1 && pos_tmp < pos2))
1458  pos2 = pos_tmp;
1459 
1460  if (pos2 == -1)
1461  pos2 = text.length();
1462 
1463  // Replace ~user if the user name is terminated by '/' or ' '
1464  //
1465  if (pos2 >= 0) {
1466 
1467  QString user = text.mid(1, pos2 - 1);
1468  QString dir;
1469 
1470  // A single ~ is replaced with $HOME
1471  //
1472  if (user.isEmpty()) {
1473  dir = QDir::homePath();
1474  }
1475  // ~user is replaced with the dir from passwd
1476  //
1477  else {
1478  struct passwd* pw = ::getpwnam(user.toLocal8Bit());
1479 
1480  if (pw)
1481  dir = QFile::decodeName(pw->pw_dir);
1482 
1483  ::endpwent();
1484  }
1485 
1486  if (!dir.isEmpty()) {
1487  expanded = true;
1488  text.replace(0, pos2, dir);
1489  }
1490  }
1491 
1492  return expanded;
1493 }
1494 
1495 /*
1496  * unescape
1497  *
1498  * Remove escapes and return the result in a new string
1499  *
1500  */
1501 static QString unescape(const QString& text)
1502 {
1503  QString result;
1504 
1505  for (int pos = 0; pos < text.length(); pos++)
1506  if (text.at(pos) != QLatin1Char('\\'))
1507  result.insert(result.length(), text.at(pos));
1508 
1509  return result;
1510 }
1511 
1512 #include "kurlcompletion.moc"
KIO::UDSEntry::UDS_URL
An alternative URL (If different from the caption).
Definition: udsentry.h:190
KUrlCompletion::FileCompletion
Definition: kurlcompletion.h:53
KUrlCompletion::KUrlCompletion
KUrlCompletion()
Constructs a KUrlCompletion object in FileCompletion mode.
Definition: kurlcompletion.cpp:502
unescape
static QString unescape(const QString &text)
Definition: kurlcompletion.cpp:1501
MODE_EXE
#define MODE_EXE
Definition: kurlcompletion.cpp:75
KCompletion::clear
virtual void clear()
QString::indexOf
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
QEvent
KUrlCompletion::replaceHome
virtual bool replaceHome() const
Returns whether ~username is completed and whether ~username is replaced internally with the user's h...
Definition: kurlcompletion.cpp:574
QString::append
QString & append(QChar ch)
QEvent::type
Type type() const
KUrl::directory
QString directory(const DirectoryOptions &options=IgnoreTrailingSlash) const
Type
Type
kdebug.h
kurl.h
QByteArray
KIO::UDSEntry
Universal Directory Service.
Definition: udsentry.h:58
expandEnv
static bool expandEnv(QString &)
Definition: kurlcompletion.cpp:1387
kglobalsettings.h
KUrlCompletion::setMode
virtual void setMode(Mode mode)
Changes the completion mode: exe or file completion.
Definition: kurlcompletion.cpp:559
kauthorized.h
KUrlCompletion::isRunning
virtual bool isRunning() const
Check whether asynchronous completion is in progress.
Definition: kurlcompletion.cpp:674
KUrlCompletion::customEvent
virtual void customEvent(QEvent *e)
Definition: kurlcompletion.cpp:1331
QChar
QString::split
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
CTEnv
Definition: kurlcompletion.cpp:78
KIO::ListJob
A ListJob is allows you to get the get the content of a directory.
Definition: jobclasses.h:936
QString::prepend
QString & prepend(QChar ch)
KIO::HideProgressInfo
Hide progress information dialog, i.e.
Definition: jobclasses.h:51
kconfig.h
CTInfo
Definition: kurlcompletion.cpp:78
QUrl::host
QString host() const
dirs
KStandardDirs * dirs()
KUrlCompletion::Mode
Mode
Determines how completion is done.
Definition: kurlcompletion.h:53
KIO::UDSEntry::isDir
bool isDir() const
Definition: udsentry.cpp:84
CTFile
Definition: kurlcompletion.cpp:78
CTUrl
Definition: kurlcompletion.cpp:78
KUrlCompletion::mode
virtual Mode mode() const
Returns the completion mode: exe or file completion (default FileCompletion).
Definition: kurlcompletion.cpp:554
KUrl::toLocalFile
QString toLocalFile(AdjustPathOption trailing=LeaveTrailingSlash) const
QDir::currentPath
QString currentPath()
kDebug
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
QDir::homePath
QString homePath()
KDesktopFileActions::run
bool run(const KUrl &_url, bool _is_local)
Invokes the default action for the desktop entry.
Definition: kdesktopfileactions.cpp:54
KUrl
KGlobal::config
KSharedConfigPtr config()
kprotocolmanager.h
KUrl::setPath
void setPath(const QString &path)
QString::clear
void clear()
KIO::listDir
ListJob * listDir(const KUrl &url, JobFlags flags=DefaultFlags, bool includeHidden=true)
List the contents of url, which is assumed to be a directory.
Definition: job.cpp:2735
QRegExp::indexIn
int indexIn(const QString &str, int offset, CaretMode caretMode) const
QRegExp
kglobal.h
QString::fromLocal8Bit
QString fromLocal8Bit(const char *str, int size)
QList::append
void append(const T &value)
QString::insert
QString & insert(int position, QChar ch)
KUrlCompletion::makeCompletion
virtual QString makeCompletion(const QString &text)
Finds completions to the given text.
Definition: kurlcompletion.cpp:589
KIO::UDSEntry::numberValue
long long numberValue(uint field, long long defaultValue=0) const
Definition: udsentry.cpp:78
QFileInfo::isDir
bool isDir() const
QFileInfo::fileName
QString fileName() const
QDir::Filters
typedef Filters
KUrlCompletion::replaceEnv
virtual bool replaceEnv() const
Checks whether environment variables are completed and whether they are replaced internally while fin...
Definition: kurlcompletion.cpp:564
KAuthorized::authorizeUrlAction
bool authorizeUrlAction(const QString &action, const KUrl &baseUrl, const KUrl &destUrl)
KUrlCompletion::postProcessMatch
void postProcessMatch(QString *match) const
Definition: kurlcompletion.cpp:1268
QString::isEmpty
bool isEmpty() const
KCompletion
KGlobalSettings::CompletionAuto
QString::startsWith
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
KIO::UDSEntry::stringValue
QString stringValue(uint field) const
Definition: udsentry.cpp:73
QString::endsWith
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
KUrlCompletion::setDir
virtual void setDir(const QString &dir)
Sets the current directory (used as base for completion).
Definition: kurlcompletion.cpp:544
QDir::setCurrent
bool setCurrent(const QString &path)
QList::Iterator
typedef Iterator
QObject::deleteLater
void deleteLater()
QString
QList< UDSEntry >
isLocalProtocol
static bool isLocalProtocol(const QString &protocol)
Definition: kurlcompletion.cpp:960
KCompletionMatches
KProtocolInfo::protocolClass
static QString protocolClass(const QString &protocol)
QStringList
expandTilde
static bool expandTilde(QString &)
Definition: kurlcompletion.cpp:1445
kkernel_win.h
QFileInfo
QDirIterator
QString::toLocal8Bit
QByteArray toLocal8Bit() const
KUrlCompletion::DirCompletion
Definition: kurlcompletion.h:53
QLatin1Char
QDir::isRelativePath
bool isRelativePath(const QString &path)
KGlobalSettings::CompletionPopup
QDir
job.h
KConfigGroup
QString::replace
QString & replace(int position, int n, QChar after)
KGlobalSettings::CompletionMan
KUrlCompletion::~KUrlCompletion
virtual ~KUrlCompletion()
Destructs the KUrlCompletion object.
Definition: kurlcompletion.cpp:516
KUrl::setFileName
void setFileName(const QString &_txt)
QUrl::isValid
bool isValid() const
QString::utf16
const ushort * utf16() const
QString::mid
QString mid(int position, int n) const
KUrlCompletion::ExeCompletion
Definition: kurlcompletion.h:53
KRecentDirs::dir
QString dir(const QString &fileClass)
Returns the most recently used directory accociated with this file-class.
Definition: krecentdirs.cpp:68
KUrlCompletion::replacedPath
QString replacedPath(const QString &text) const
Replaces username and/or environment variables, depending on the current settings and returns the fil...
Definition: kurlcompletion.cpp:1372
QLatin1String
KIO::UDSEntry::UDS_ACCESS
Access permissions (part of the mode returned by stat)
Definition: udsentry.h:171
KUrl::fileName
QString fileName(const DirectoryOptions &options=IgnoreTrailingSlash) const
CTNone
Definition: kurlcompletion.cpp:78
CTUser
Definition: kurlcompletion.cpp:78
QUrl::isRelative
bool isRelative() const
KUrlCompletion::setReplaceEnv
virtual void setReplaceEnv(bool replace)
Enables/disables completion and replacement (internally) of environment variables in URLs...
Definition: kurlcompletion.cpp:569
KIO::UDSEntry::UDS_NAME
Filename - as displayed in directory listings etc.
Definition: udsentry.h:163
QString::at
const QChar at(int position) const
KUrl::ObeyTrailingSlash
QList::ConstIterator
typedef ConstIterator
KIO::Job
The base class for all jobs.
Definition: jobclasses.h:94
KIO::copy
CopyJob * copy(const KUrl &src, const KUrl &dest, JobFlags flags=DefaultFlags)
Copy a file or directory src into the destination dest, which can be a file (including the final file...
Definition: copyjob.cpp:2164
KUrl::AppendTrailingSlash
QString::length
int length() const
QByteArray::data
char * data()
QString::left
QString left(int n) const
ComplType
ComplType
Definition: kurlcompletion.cpp:78
KUrlCompletion::dir
virtual QString dir() const
Returns the current directory, as it was given in setDir.
Definition: kurlcompletion.cpp:549
KUrl::url
QString url(AdjustPathOption trailing=LeaveTrailingSlash) const
QtConcurrent::filter
QFuture< void > filter(Sequence &sequence, FilterFunction filterFunction)
KProtocolManager::supportsListing
static bool supportsListing(const KUrl &url)
Returns whether the protocol can list files/objects.
Definition: kprotocolmanager.cpp:1032
QList::constEnd
const_iterator constEnd() const
QList::constBegin
const_iterator constBegin() const
QThread
CTMan
Definition: kurlcompletion.cpp:78
end
const KShortcut & end()
KUrlCompletion::postProcessMatches
void postProcessMatches(QStringList *matches) const
Definition: kurlcompletion.cpp:1317
KUrlCompletion::setReplaceHome
virtual void setReplaceHome(bool replace)
Enables/disables completion of ~username and replacement (internally) of ~username with the user's ho...
Definition: kurlcompletion.cpp:579
KJob
KUrl::prettyUrl
QString prettyUrl(AdjustPathOption trailing=LeaveTrailingSlash) const
KGlobalSettings::CompletionPopupAuto
KUrlCompletion
This class does completion of URLs including user directories (~user) and environment variables...
Definition: kurlcompletion.h:41
QFile::encodeName
QByteArray encodeName(const QString &fileName)
QFile::decodeName
QString decodeName(const QByteArray &localFileName)
kconfiggroup.h
KUrlCompletion::stop
virtual void stop()
Stops asynchronous completion.
Definition: kurlcompletion.cpp:684
CTExe
Definition: kurlcompletion.cpp:78
kurlcompletion.h
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:24:53 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KIO

Skip menu "KIO"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • 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