• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kio/kio
 

kio/kio

  • kio
  • kio
kurlcompletion.cpp
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 <config.h>
27 #include <stdlib.h>
28 #include <assert.h>
29 #include <limits.h>
30 
31 #include <tqstring.h>
32 #include <tqstringlist.h>
33 #include <tqvaluelist.h>
34 #include <tqregexp.h>
35 #include <tqtimer.h>
36 #include <tqdir.h>
37 #include <tqfile.h>
38 #include <tqtextstream.h>
39 #include <tqdeepcopy.h>
40 #include <tqthread.h>
41 
42 #include <kapplication.h>
43 #include <kdebug.h>
44 #include <kcompletion.h>
45 #include <kurl.h>
46 #include <kio/jobclasses.h>
47 #include <kio/job.h>
48 #include <kprotocolinfo.h>
49 #include <kconfig.h>
50 #include <kglobal.h>
51 #include <klocale.h>
52 #include <kde_file.h>
53 
54 #include <sys/types.h>
55 #include <dirent.h>
56 #include <unistd.h>
57 #include <sys/stat.h>
58 #include <pwd.h>
59 #include <time.h>
60 #include <sys/param.h>
61 
62 #include "kurlcompletion.h"
63 
64 static bool expandTilde(TQString &);
65 static bool expandEnv(TQString &);
66 
67 static TQString unescape(const TQString &text);
68 
69 // Permission mask for files that are executable by
70 // user, group or other
71 #define MODE_EXE (S_IXUSR | S_IXGRP | S_IXOTH)
72 
73 // Constants for types of completion
74 enum ComplType {CTNone=0, CTEnv, CTUser, CTMan, CTExe, CTFile, CTUrl, CTInfo};
75 
76 class CompletionThread;
77 
83 class CompletionMatchEvent : public TQCustomEvent
84 {
85 public:
86  CompletionMatchEvent( CompletionThread *thread ) :
87  TQCustomEvent( uniqueType() ),
88  m_completionThread( thread )
89  {}
90 
91  CompletionThread *completionThread() const { return m_completionThread; }
92  static int uniqueType() { return User + 61080; }
93 
94 private:
95  CompletionThread *m_completionThread;
96 };
97 
98 class CompletionThread : public TQThread
99 {
100 protected:
101  CompletionThread( KURLCompletion *receiver ) :
102  TQThread(),
103  m_receiver( receiver ),
104  m_terminationRequested( false )
105  {}
106 
107 public:
108  void requestTermination() { m_terminationRequested = true; }
109  TQDeepCopy<TQStringList> matches() const { return m_matches; }
110 
111 protected:
112  void addMatch( const TQString &match ) { m_matches.append( match ); }
113  bool terminationRequested() const { return m_terminationRequested; }
114  void done()
115  {
116  if ( !m_terminationRequested )
117  kapp->postEvent( m_receiver, new CompletionMatchEvent( this ) );
118  else
119  delete this;
120  }
121 
122 private:
123  KURLCompletion *m_receiver;
124  TQStringList m_matches;
125  bool m_terminationRequested;
126 };
127 
133 class UserListThread : public CompletionThread
134 {
135 public:
136  UserListThread( KURLCompletion *receiver ) :
137  CompletionThread( receiver )
138  {}
139 
140 protected:
141  virtual void run()
142  {
143  static const TQChar tilde = '~';
144 
145  struct passwd *pw;
146  while ( ( pw = ::getpwent() ) && !terminationRequested() )
147  addMatch( tilde + TQString::fromLocal8Bit( pw->pw_name ) );
148 
149  ::endpwent();
150 
151  addMatch( tilde );
152 
153  done();
154  }
155 };
156 
157 class DirectoryListThread : public CompletionThread
158 {
159 public:
160  DirectoryListThread( KURLCompletion *receiver,
161  const TQStringList &dirList,
162  const TQString &filter,
163  bool onlyExe,
164  bool onlyDir,
165  bool noHidden,
166  bool appendSlashToDir ) :
167  CompletionThread( receiver ),
168  m_dirList( TQDeepCopy<TQStringList>( dirList ) ),
169  m_filter( TQDeepCopy<TQString>( filter ) ),
170  m_onlyExe( onlyExe ),
171  m_onlyDir( onlyDir ),
172  m_noHidden( noHidden ),
173  m_appendSlashToDir( appendSlashToDir )
174  {}
175 
176  virtual void run();
177 
178 private:
179  TQStringList m_dirList;
180  TQString m_filter;
181  bool m_onlyExe;
182  bool m_onlyDir;
183  bool m_noHidden;
184  bool m_appendSlashToDir;
185 };
186 
187 void DirectoryListThread::run()
188 {
189  // Thread safety notes:
190  //
191  // There very possibly may be thread safety issues here, but I've done a check
192  // of all of the things that would seem to be problematic. Here are a few
193  // things that I have checked to be safe here (some used indirectly):
194  //
195  // TQDir::currentDirPath(), TQDir::setCurrent(), TQFile::decodeName(), TQFile::encodeName()
196  // TQString::fromLocal8Bit(), TQString::local8Bit(), TQTextCodec::codecForLocale()
197  //
198  // Also see (for POSIX functions):
199  // http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_09.html
200 
201  DIR *dir = 0;
202 
203  for ( TQStringList::ConstIterator it = m_dirList.begin();
204  it != m_dirList.end() && !terminationRequested();
205  ++it )
206  {
207  // Open the next directory
208 
209  if ( !dir ) {
210  dir = ::opendir( TQFile::encodeName( *it ) );
211  if ( ! dir ) {
212  kdDebug() << "Failed to open dir: " << *it << endl;
213  done();
214  return;
215  }
216  }
217 
218  // A trick from KIO that helps performance by a little bit:
219  // chdir to the directroy so we won't have to deal with full paths
220  // with stat()
221 
222  TQString path = TQDir::currentDirPath();
223  TQDir::setCurrent( *it );
224 
225  // Loop through all directory entries
226  // Solaris and IRIX dirent structures do not allocate space for d_name. On
227  // systems that do (HP-UX, Linux, Tru64 UNIX), we overallocate space but
228  // that's ok.
229 #ifndef HAVE_READDIR_R
230  struct dirent *dirEntry = 0;
231  while ( !terminationRequested() &&
232  (dirEntry = ::readdir( dir)))
233 #else
234 #if !defined(MAXPATHLEN) && defined(__GNU__)
235 #define MAXPATHLEN UCHAR_MAX
236 #endif
237  struct dirent *dirPosition = (struct dirent *) malloc( sizeof( struct dirent ) + MAXPATHLEN + 1 );
238  struct dirent *dirEntry = 0;
239  while ( !terminationRequested() &&
240  ::readdir_r( dir, dirPosition, &dirEntry ) == 0 && dirEntry )
241 #endif
242 
243  {
244  // Skip hidden files if m_noHidden is true
245 
246  if ( dirEntry->d_name[0] == '.' && m_noHidden )
247  continue;
248 
249  // Skip "."
250 
251  if ( dirEntry->d_name[0] == '.' && dirEntry->d_name[1] == '\0' )
252  continue;
253 
254  // Skip ".."
255 
256  if ( dirEntry->d_name[0] == '.' && dirEntry->d_name[1] == '.' && dirEntry->d_name[2] == '\0' )
257  continue;
258 
259  TQString file = TQFile::decodeName( dirEntry->d_name );
260 
261  if ( m_filter.isEmpty() || file.startsWith( m_filter ) ) {
262 
263  if ( m_onlyExe || m_onlyDir || m_appendSlashToDir ) {
264  KDE_struct_stat sbuff;
265 
266  if ( KDE_stat( dirEntry->d_name, &sbuff ) == 0 ) {
267 
268  // Verify executable
269 
270  if ( m_onlyExe && ( sbuff.st_mode & MODE_EXE ) == 0 )
271  continue;
272 
273  // Verify directory
274 
275  if ( m_onlyDir && !S_ISDIR( sbuff.st_mode ) )
276  continue;
277 
278  // Add '/' to directories
279 
280  if ( m_appendSlashToDir && S_ISDIR( sbuff.st_mode ) )
281  file.append( '/' );
282 
283  }
284  else {
285  kdDebug() << "Could not stat file " << file << endl;
286  continue;
287  }
288  }
289 
290  addMatch( file );
291  }
292  }
293 
294  // chdir to the original directory
295 
296  TQDir::setCurrent( path );
297 
298  ::closedir( dir );
299  dir = 0;
300 #ifdef HAVE_READDIR_R
301  free( dirPosition );
302 #endif
303  }
304 
305  done();
306 }
307 
310 // MyURL - wrapper for KURL with some different functionality
311 //
312 
313 class KURLCompletion::MyURL
314 {
315 public:
316  MyURL(const TQString &url, const TQString &cwd);
317  MyURL(const MyURL &url);
318  ~MyURL();
319 
320  KURL *kurl() const { return m_kurl; }
321 
322  TQString protocol() const { return m_kurl->protocol(); }
323  // The directory with a trailing '/'
324  TQString dir() const { return m_kurl->directory(false, false); }
325  TQString file() const { return m_kurl->fileName(false); }
326 
327  // The initial, unparsed, url, as a string.
328  TQString url() const { return m_url; }
329 
330  // Is the initial string a URL, or just a path (whether absolute or relative)
331  bool isURL() const { return m_isURL; }
332 
333  void filter( bool replace_user_dir, bool replace_env );
334 
335 private:
336  void init(const TQString &url, const TQString &cwd);
337 
338  KURL *m_kurl;
339  TQString m_url;
340  bool m_isURL;
341 };
342 
343 KURLCompletion::MyURL::MyURL(const TQString &url, const TQString &cwd)
344 {
345  init(url, cwd);
346 }
347 
348 KURLCompletion::MyURL::MyURL(const MyURL &url)
349 {
350  m_kurl = new KURL( *(url.m_kurl) );
351  m_url = url.m_url;
352  m_isURL = url.m_isURL;
353 }
354 
355 void KURLCompletion::MyURL::init(const TQString &url, const TQString &cwd)
356 {
357  // Save the original text
358  m_url = url;
359 
360  // Non-const copy
361  TQString url_copy = url;
362 
363  // Special shortcuts for "man:" and "info:"
364  if ( url_copy[0] == '#' ) {
365  if ( url_copy[1] == '#' )
366  url_copy.replace( 0, 2, TQString("info:") );
367  else
368  url_copy.replace( 0, 1, TQString("man:") );
369  }
370 
371  // Look for a protocol in 'url'
372  TQRegExp protocol_regex = TQRegExp( "^[^/\\s\\\\]*:" );
373 
374  // Assume "file:" or whatever is given by 'cwd' if there is
375  // no protocol. (KURL does this only for absoute paths)
376  if ( protocol_regex.search( url_copy ) == 0 )
377  {
378  m_kurl = new KURL( url_copy );
379  m_isURL = true;
380  }
381  else // relative path or ~ or $something
382  {
383  m_isURL = false;
384  if ( cwd.isEmpty() )
385  {
386  m_kurl = new KURL();
387  if ( !TQDir::isRelativePath(url_copy) || url_copy[0] == '$' || url_copy[0] == '~' )
388  m_kurl->setPath( url_copy );
389  else
390  *m_kurl = url_copy;
391  }
392  else
393  {
394  KURL base = KURL::fromPathOrURL( cwd );
395  base.adjustPath(+1);
396 
397  if ( !TQDir::isRelativePath(url_copy) || url_copy[0] == '~' || url_copy[0] == '$' )
398  {
399  m_kurl = new KURL();
400  m_kurl->setPath( url_copy );
401  }
402  else // relative path
403  {
404  //m_kurl = new KURL( base, url_copy );
405  m_kurl = new KURL( base );
406  m_kurl->addPath( url_copy );
407  }
408  }
409  }
410 }
411 
412 KURLCompletion::MyURL::~MyURL()
413 {
414  delete m_kurl;
415 }
416 
417 void KURLCompletion::MyURL::filter( bool replace_user_dir, bool replace_env )
418 {
419  TQString d = dir() + file();
420  if ( replace_user_dir ) expandTilde( d );
421  if ( replace_env ) expandEnv( d );
422  m_kurl->setPath( d );
423 }
424 
427 // KURLCompletionPrivate
428 //
429 class KURLCompletionPrivate
430 {
431 public:
432  KURLCompletionPrivate() : url_auto_completion(true),
433  userListThread(0),
434  dirListThread(0) {}
435  ~KURLCompletionPrivate();
436 
437  TQValueList<KURL*> list_urls;
438 
439  bool onlyLocalProto;
440 
441  // urlCompletion() in Auto/Popup mode?
442  bool url_auto_completion;
443 
444  // Append '/' to directories in Popup mode?
445  // Doing that stat's all files and is slower
446  bool popup_append_slash;
447 
448  // Keep track of currently listed files to avoid reading them again
449  TQString last_path_listed;
450  TQString last_file_listed;
451  TQString last_prepend;
452  int last_compl_type;
453  int last_no_hidden;
454 
455  TQString cwd; // "current directory" = base dir for completion
456 
457  KURLCompletion::Mode mode; // ExeCompletion, FileCompletion, DirCompletion
458  bool replace_env;
459  bool replace_home;
460  bool complete_url; // if true completing a URL (i.e. 'prepend' is a URL), otherwise a path
461 
462  KIO::ListJob *list_job; // kio job to list directories
463 
464  TQString prepend; // text to prepend to listed items
465  TQString compl_text; // text to pass on to KCompletion
466 
467  // Filters for files read with kio
468  bool list_urls_only_exe; // true = only list executables
469  bool list_urls_no_hidden;
470  TQString list_urls_filter; // filter for listed files
471 
472  CompletionThread *userListThread;
473  CompletionThread *dirListThread;
474 };
475 
476 KURLCompletionPrivate::~KURLCompletionPrivate()
477 {
478  if ( userListThread )
479  userListThread->requestTermination();
480  if ( dirListThread )
481  dirListThread->requestTermination();
482 }
483 
486 // KURLCompletion
487 //
488 
489 KURLCompletion::KURLCompletion() : KCompletion()
490 {
491  init();
492 }
493 
494 
495 KURLCompletion::KURLCompletion( Mode mode ) : KCompletion()
496 {
497  init();
498  setMode ( mode );
499 }
500 
501 KURLCompletion::~KURLCompletion()
502 {
503  stop();
504  delete d;
505 }
506 
507 
508 void KURLCompletion::init()
509 {
510  d = new KURLCompletionPrivate;
511 
512  d->cwd = TQDir::homeDirPath();
513 
514  d->replace_home = true;
515  d->replace_env = true;
516  d->last_no_hidden = false;
517  d->last_compl_type = 0;
518  d->list_job = 0L;
519  d->mode = KURLCompletion::FileCompletion;
520 
521  // Read settings
522  KConfig *c = KGlobal::config();
523  KConfigGroupSaver cgs( c, "URLCompletion" );
524 
525  d->url_auto_completion = c->readBoolEntry("alwaysAutoComplete", true);
526  d->popup_append_slash = c->readBoolEntry("popupAppendSlash", true);
527  d->onlyLocalProto = c->readBoolEntry("LocalProtocolsOnly", false);
528 }
529 
530 void KURLCompletion::setDir(const TQString &dir)
531 {
532  d->cwd = dir;
533 }
534 
535 TQString KURLCompletion::dir() const
536 {
537  return d->cwd;
538 }
539 
540 KURLCompletion::Mode KURLCompletion::mode() const
541 {
542  return d->mode;
543 }
544 
545 void KURLCompletion::setMode( Mode mode )
546 {
547  d->mode = mode;
548 }
549 
550 bool KURLCompletion::replaceEnv() const
551 {
552  return d->replace_env;
553 }
554 
555 void KURLCompletion::setReplaceEnv( bool replace )
556 {
557  d->replace_env = replace;
558 }
559 
560 bool KURLCompletion::replaceHome() const
561 {
562  return d->replace_home;
563 }
564 
565 void KURLCompletion::setReplaceHome( bool replace )
566 {
567  d->replace_home = replace;
568 }
569 
570 /*
571  * makeCompletion()
572  *
573  * Entry point for file name completion
574  */
575 TQString KURLCompletion::makeCompletion(const TQString &text)
576 {
577  //kdDebug() << "KURLCompletion::makeCompletion: " << text << " d->cwd=" << d->cwd << endl;
578 
579  MyURL url(text, d->cwd);
580 
581  d->compl_text = text;
582 
583  // Set d->prepend to the original URL, with the filename [and ref/query] stripped.
584  // This is what gets prepended to the directory-listing matches.
585  int toRemove = url.file().length() - url.kurl()->query().length();
586  if ( url.kurl()->hasRef() )
587  toRemove += url.kurl()->ref().length() + 1;
588  d->prepend = text.left( text.length() - toRemove );
589  d->complete_url = url.isURL();
590 
591  TQString match;
592 
593  // Environment variables
594  //
595  if ( d->replace_env && envCompletion( url, &match ) )
596  return match;
597 
598  // User directories
599  //
600  if ( d->replace_home && userCompletion( url, &match ) )
601  return match;
602 
603  // Replace user directories and variables
604  url.filter( d->replace_home, d->replace_env );
605 
606  //kdDebug() << "Filtered: proto=" << url.protocol()
607  // << ", dir=" << url.dir()
608  // << ", file=" << url.file()
609  // << ", kurl url=" << *url.kurl() << endl;
610 
611  if ( d->mode == ExeCompletion ) {
612  // Executables
613  //
614  if ( exeCompletion( url, &match ) )
615  return match;
616 
617  // KRun can run "man:" and "info:" etc. so why not treat them
618  // as executables...
619 
620  if ( urlCompletion( url, &match ) )
621  return match;
622  }
623  else if ( d->mode == SystemExeCompletion ) {
624  // Executables
625  //
626  if ( systemexeCompletion( url, &match ) )
627  return match;
628 
629  // KRun can run "man:" and "info:" etc. so why not treat them
630  // as executables...
631 
632  if ( urlCompletion( url, &match ) )
633  return match;
634  }
635  else {
636  // Local files, directories
637  //
638  if ( fileCompletion( url, &match ) )
639  return match;
640 
641  // All other...
642  //
643  if ( urlCompletion( url, &match ) )
644  return match;
645  }
646 
647  setListedURL( CTNone );
648  stop();
649 
650  return TQString::null;
651 }
652 
653 /*
654  * finished
655  *
656  * Go on and call KCompletion.
657  * Called when all matches have been added
658  */
659 TQString KURLCompletion::finished()
660 {
661  if ( d->last_compl_type == CTInfo )
662  return KCompletion::makeCompletion( d->compl_text.lower() );
663  else
664  return KCompletion::makeCompletion( d->compl_text );
665 }
666 
667 /*
668  * isRunning
669  *
670  * Return true if either a KIO job or the DirLister
671  * is running
672  */
673 bool KURLCompletion::isRunning() const
674 {
675  return d->list_job || (d->dirListThread && !d->dirListThread->finished());
676 }
677 
678 /*
679  * stop
680  *
681  * Stop and delete a running KIO job or the DirLister
682  */
683 void KURLCompletion::stop()
684 {
685  if ( d->list_job ) {
686  d->list_job->kill();
687  d->list_job = 0L;
688  }
689 
690  if ( !d->list_urls.isEmpty() ) {
691  TQValueList<KURL*>::Iterator it = d->list_urls.begin();
692  for ( ; it != d->list_urls.end(); it++ )
693  delete (*it);
694  d->list_urls.clear();
695  }
696 
697  if ( d->dirListThread ) {
698  d->dirListThread->requestTermination();
699  d->dirListThread = 0;
700  }
701 }
702 
703 /*
704  * Keep track of the last listed directory
705  */
706 void KURLCompletion::setListedURL( int complType,
707  const TQString& dir,
708  const TQString& filter,
709  bool no_hidden )
710 {
711  d->last_compl_type = complType;
712  d->last_path_listed = dir;
713  d->last_file_listed = filter;
714  d->last_no_hidden = (int)no_hidden;
715  d->last_prepend = d->prepend;
716 }
717 
718 bool KURLCompletion::isListedURL( int complType,
719  const TQString& dir,
720  const TQString& filter,
721  bool no_hidden )
722 {
723  return d->last_compl_type == complType
724  && ( d->last_path_listed == dir
725  || (dir.isEmpty() && d->last_path_listed.isEmpty()) )
726  && ( filter.startsWith(d->last_file_listed)
727  || (filter.isEmpty() && d->last_file_listed.isEmpty()) )
728  && d->last_no_hidden == (int)no_hidden
729  && d->last_prepend == d->prepend; // e.g. relative path vs absolute
730 }
731 
732 /*
733  * isAutoCompletion
734  *
735  * Returns true if completion mode is Auto or Popup
736  */
737 bool KURLCompletion::isAutoCompletion()
738 {
739  return completionMode() == KGlobalSettings::CompletionAuto
740  || completionMode() == KGlobalSettings::CompletionPopup
741  || completionMode() == KGlobalSettings::CompletionMan
742  || completionMode() == KGlobalSettings::CompletionPopupAuto;
743 }
746 // User directories
747 //
748 
749 bool KURLCompletion::userCompletion(const MyURL &url, TQString *match)
750 {
751  if ( url.protocol() != "file"
752  || !url.dir().isEmpty()
753  || url.file().at(0) != '~' )
754  return false;
755 
756  if ( !isListedURL( CTUser ) ) {
757  stop();
758  clear();
759 
760  if ( !d->userListThread ) {
761  d->userListThread = new UserListThread( this );
762  d->userListThread->start();
763 
764  // If the thread finishes quickly make sure that the results
765  // are added to the first matching case.
766 
767  d->userListThread->wait( 200 );
768  TQStringList l = d->userListThread->matches();
769  addMatches( l );
770  }
771  }
772  *match = finished();
773  return true;
774 }
775 
778 // Environment variables
779 //
780 
781 #if !defined(__OpenBSD__) && !defined(__FreeBSD__)
782 extern char **environ; // Array of environment variables
783 #endif
784 
785 bool KURLCompletion::envCompletion(const MyURL &url, TQString *match)
786 {
787 #if defined(__OpenBSD__) || defined(__FreeBSD__)
788  return false;
789 #else
790  if ( url.file().at(0) != '$' )
791  return false;
792 
793  if ( !isListedURL( CTEnv ) ) {
794  stop();
795  clear();
796 
797  char **env = environ;
798 
799  TQString dollar = TQString("$");
800 
801  TQStringList l;
802 
803  while ( *env ) {
804  TQString s = TQString::fromLocal8Bit( *env );
805 
806  int pos = s.find('=');
807 
808  if ( pos == -1 )
809  pos = s.length();
810 
811  if ( pos > 0 )
812  l.append( dollar + s.left(pos) );
813 
814  env++;
815  }
816 
817  addMatches( l );
818  }
819 
820  setListedURL( CTEnv );
821 
822  *match = finished();
823  return true;
824 #endif
825 }
826 
829 // Executables
830 //
831 
832 bool KURLCompletion::exeCompletion(const MyURL &url, TQString *match)
833 {
834  if ( url.protocol() != "file" )
835  return false;
836 
837  TQString dir = url.dir();
838 
839  dir = unescape( dir ); // remove escapes
840 
841  // Find directories to search for completions, either
842  //
843  // 1. complete path given in url
844  // 2. current directory (d->cwd)
845  // 3. $PATH
846  // 4. no directory at all
847 
848  TQStringList dirList;
849 
850  if ( !TQDir::isRelativePath(dir) ) {
851  // complete path in url
852  dirList.append( dir );
853  }
854  else if ( !dir.isEmpty() && !d->cwd.isEmpty() ) {
855  // current directory
856  dirList.append( d->cwd + '/' + dir );
857  }
858  else if ( !url.file().isEmpty() ) {
859  // $PATH
860  dirList = TQStringList::split(KPATH_SEPARATOR,
861  TQString::fromLocal8Bit(::getenv("PATH")));
862 
863  TQStringList::Iterator it = dirList.begin();
864 
865  for ( ; it != dirList.end(); it++ )
866  (*it).append('/');
867  }
868 
869  // No hidden files unless the user types "."
870  bool no_hidden_files = url.file().at(0) != '.';
871 
872  // List files if needed
873  //
874  if ( !isListedURL( CTExe, dir, url.file(), no_hidden_files ) )
875  {
876  stop();
877  clear();
878 
879  setListedURL( CTExe, dir, url.file(), no_hidden_files );
880 
881  *match = listDirectories( dirList, url.file(), true, false, no_hidden_files );
882  }
883  else if ( !isRunning() ) {
884  *match = finished();
885  }
886  else {
887  if ( d->dirListThread )
888  setListedURL( CTExe, dir, url.file(), no_hidden_files );
889  *match = TQString::null;
890  }
891 
892  return true;
893 }
894 
897 // System Executables
898 //
899 
900 bool KURLCompletion::systemexeCompletion(const MyURL &url, TQString *match)
901 {
902  if ( url.protocol() != "file" )
903  return false;
904 
905  TQString dir = url.dir();
906 
907  dir = unescape( dir ); // remove escapes
908 
909  // Find directories to search for completions, either
910  //
911  // 1. complete path given in url
912  // 2. current directory (d->cwd)
913  // 3. $PATH
914  // 4. no directory at all
915 
916  TQStringList dirList;
917 
918  if ( !url.file().isEmpty() ) {
919  // $PATH
920  dirList = TQStringList::split(KPATH_SEPARATOR,
921  TQString::fromLocal8Bit(::getenv("PATH")));
922 
923  TQStringList::Iterator it = dirList.begin();
924 
925  for ( ; it != dirList.end(); it++ )
926  (*it).append('/');
927  }
928 
929  // No hidden files unless the user types "."
930  bool no_hidden_files = url.file().at(0) != '.';
931 
932  // List files if needed
933  //
934  if ( !isListedURL( CTExe, dir, url.file(), no_hidden_files ) )
935  {
936  stop();
937  clear();
938 
939  setListedURL( CTExe, dir, url.file(), no_hidden_files );
940 
941  *match = listDirectories( dirList, url.file(), true, false, no_hidden_files );
942  }
943  else if ( !isRunning() ) {
944  *match = finished();
945  }
946  else {
947  if ( d->dirListThread )
948  setListedURL( CTExe, dir, url.file(), no_hidden_files );
949  *match = TQString::null;
950  }
951 
952  return true;
953 }
954 
957 // Local files
958 //
959 
960 bool KURLCompletion::fileCompletion(const MyURL &url, TQString *match)
961 {
962  if ( url.protocol() != "file" )
963  return false;
964 
965  TQString dir = url.dir();
966 
967  if (url.url()[0] == '.')
968  {
969  if (url.url().length() == 1)
970  {
971  *match =
972  ( completionMode() == KGlobalSettings::CompletionMan )? "." : "..";
973  return true;
974  }
975  if (url.url().length() == 2 && url.url()[1]=='.')
976  {
977  *match="..";
978  return true;
979  }
980  }
981 
982  //kdDebug() << "fileCompletion " << url.url() << " dir=" << dir << endl;
983 
984  dir = unescape( dir ); // remove escapes
985 
986  // Find directories to search for completions, either
987  //
988  // 1. complete path given in url
989  // 2. current directory (d->cwd)
990  // 3. no directory at all
991 
992  TQStringList dirList;
993 
994  if ( !TQDir::isRelativePath(dir) ) {
995  // complete path in url
996  dirList.append( dir );
997  }
998  else if ( !d->cwd.isEmpty() ) {
999  // current directory
1000  dirList.append( d->cwd + '/' + dir );
1001  }
1002 
1003  // No hidden files unless the user types "."
1004  bool no_hidden_files = ( url.file().at(0) != '.' );
1005 
1006  // List files if needed
1007  //
1008  if ( !isListedURL( CTFile, dir, "", no_hidden_files ) )
1009  {
1010  stop();
1011  clear();
1012 
1013  setListedURL( CTFile, dir, "", no_hidden_files );
1014 
1015  // Append '/' to directories in Popup mode?
1016  bool append_slash = ( d->popup_append_slash
1017  && (completionMode() == KGlobalSettings::CompletionPopup ||
1018  completionMode() == KGlobalSettings::CompletionPopupAuto ) );
1019 
1020  bool only_dir = ( d->mode == DirCompletion );
1021 
1022  *match = listDirectories( dirList, "", false, only_dir, no_hidden_files,
1023  append_slash );
1024  }
1025  else if ( !isRunning() ) {
1026  *match = finished();
1027  }
1028  else {
1029  *match = TQString::null;
1030  }
1031 
1032  return true;
1033 }
1034 
1037 // URLs not handled elsewhere...
1038 //
1039 
1040 bool KURLCompletion::urlCompletion(const MyURL &url, TQString *match)
1041 {
1042  //kdDebug() << "urlCompletion: url = " << *url.kurl() << endl;
1043  if (d->onlyLocalProto && KProtocolInfo::protocolClass(url.protocol()) != ":local")
1044  return false;
1045 
1046  // Use d->cwd as base url in case url is not absolute
1047  KURL url_cwd = KURL::fromPathOrURL( d->cwd );
1048 
1049  // Create an URL with the directory to be listed
1050  KURL url_dir( url_cwd, url.kurl()->url() );
1051 
1052  // Don't try url completion if
1053  // 1. malformed url
1054  // 2. protocol that doesn't have listDir()
1055  // 3. there is no directory (e.g. "ftp://ftp.kd" shouldn't do anything)
1056  // 4. auto or popup completion mode depending on settings
1057 
1058  bool man_or_info = ( url_dir.protocol() == TQString("man")
1059  || url_dir.protocol() == TQString("info") );
1060 
1061  if ( !url_dir.isValid()
1062  || !KProtocolInfo::supportsListing( url_dir )
1063  || ( !man_or_info
1064  && ( url_dir.directory(false,false).isEmpty()
1065  || ( isAutoCompletion()
1066  && !d->url_auto_completion ) ) ) ) {
1067  return false;
1068  }
1069 
1070  url_dir.setFileName(""); // not really nesseccary, but clear the filename anyway...
1071 
1072  // Remove escapes
1073  TQString dir = url_dir.directory( false, false );
1074 
1075  dir = unescape( dir );
1076 
1077  url_dir.setPath( dir );
1078 
1079  // List files if needed
1080  //
1081  if ( !isListedURL( CTUrl, url_dir.prettyURL(), url.file() ) )
1082  {
1083  stop();
1084  clear();
1085 
1086  setListedURL( CTUrl, url_dir.prettyURL(), "" );
1087 
1088  TQValueList<KURL*> url_list;
1089  url_list.append( new KURL( url_dir ) );
1090 
1091  listURLs( url_list, "", false );
1092 
1093  *match = TQString::null;
1094  }
1095  else if ( !isRunning() ) {
1096  *match = finished();
1097  }
1098  else {
1099  *match = TQString::null;
1100  }
1101 
1102  return true;
1103 }
1104 
1107 // Directory and URL listing
1108 //
1109 
1110 /*
1111  * addMatches
1112  *
1113  * Called to add matches to KCompletion
1114  */
1115 void KURLCompletion::addMatches( const TQStringList &matches )
1116 {
1117  TQStringList::ConstIterator it = matches.begin();
1118  TQStringList::ConstIterator end = matches.end();
1119 
1120  if ( d->complete_url )
1121  for ( ; it != end; it++ )
1122  addItem( d->prepend + KURL::encode_string(*it));
1123  else
1124  for ( ; it != end; it++ )
1125  addItem( d->prepend + (*it));
1126 }
1127 
1128 /*
1129  * listDirectories
1130  *
1131  * List files starting with 'filter' in the given directories,
1132  * either using DirLister or listURLs()
1133  *
1134  * In either case, addMatches() is called with the listed
1135  * files, and eventually finished() when the listing is done
1136  *
1137  * Returns the match if available, or TQString::null if
1138  * DirLister timed out or using kio
1139  */
1140 TQString KURLCompletion::listDirectories(
1141  const TQStringList &dirList,
1142  const TQString &filter,
1143  bool only_exe,
1144  bool only_dir,
1145  bool no_hidden,
1146  bool append_slash_to_dir)
1147 {
1148  assert( !isRunning() );
1149 
1150  if ( !::getenv("KURLCOMPLETION_LOCAL_KIO") ) {
1151 
1152  //kdDebug() << "Listing (listDirectories): " << dirList << " filter=" << filter << " without KIO" << endl;
1153 
1154  // Don't use KIO
1155 
1156  if ( d->dirListThread )
1157  d->dirListThread->requestTermination();
1158 
1159  TQStringList dirs;
1160 
1161  for ( TQStringList::ConstIterator it = dirList.begin();
1162  it != dirList.end();
1163  ++it )
1164  {
1165  KURL url;
1166  url.setPath(*it);
1167  if ( kapp->authorizeURLAction( "list", KURL(), url ) )
1168  dirs.append( *it );
1169  }
1170 
1171  d->dirListThread = new DirectoryListThread( this, dirs, filter, only_exe, only_dir,
1172  no_hidden, append_slash_to_dir );
1173  d->dirListThread->start();
1174  d->dirListThread->wait( 200 );
1175  addMatches( d->dirListThread->matches() );
1176 
1177  return finished();
1178  }
1179  else {
1180 
1181  // Use KIO
1182  //kdDebug() << "Listing (listDirectories): " << dirList << " with KIO" << endl;
1183 
1184  TQValueList<KURL*> url_list;
1185 
1186  TQStringList::ConstIterator it = dirList.begin();
1187 
1188  for ( ; it != dirList.end(); it++ )
1189  url_list.append( new KURL(*it) );
1190 
1191  listURLs( url_list, filter, only_exe, no_hidden );
1192  // Will call addMatches() and finished()
1193 
1194  return TQString::null;
1195  }
1196 }
1197 
1198 /*
1199  * listURLs
1200  *
1201  * Use KIO to list the given urls
1202  *
1203  * addMatches() is called with the listed files
1204  * finished() is called when the listing is done
1205  */
1206 void KURLCompletion::listURLs(
1207  const TQValueList<KURL *> &urls,
1208  const TQString &filter,
1209  bool only_exe,
1210  bool no_hidden )
1211 {
1212  assert( d->list_urls.isEmpty() );
1213  assert( d->list_job == 0L );
1214 
1215  d->list_urls = urls;
1216  d->list_urls_filter = filter;
1217  d->list_urls_only_exe = only_exe;
1218  d->list_urls_no_hidden = no_hidden;
1219 
1220 // kdDebug() << "Listing URLs: " << urls[0]->prettyURL() << ",..." << endl;
1221 
1222  // Start it off by calling slotIOFinished
1223  //
1224  // This will start a new list job as long as there
1225  // are urls in d->list_urls
1226  //
1227  slotIOFinished(0L);
1228 }
1229 
1230 /*
1231  * slotEntries
1232  *
1233  * Receive files listed by KIO and call addMatches()
1234  */
1235 void KURLCompletion::slotEntries(KIO::Job*, const KIO::UDSEntryList& entries)
1236 {
1237  TQStringList matches;
1238 
1239  KIO::UDSEntryListConstIterator it = entries.begin();
1240  KIO::UDSEntryListConstIterator end = entries.end();
1241 
1242  TQString filter = d->list_urls_filter;
1243 
1244  int filter_len = filter.length();
1245 
1246  // Iterate over all files
1247  //
1248  for (; it != end; ++it) {
1249  TQString name;
1250  TQString url;
1251  bool is_exe = false;
1252  bool is_dir = false;
1253 
1254  KIO::UDSEntry e = *it;
1255  KIO::UDSEntry::ConstIterator it_2 = e.begin();
1256 
1257  for( ; it_2 != e.end(); it_2++ ) {
1258  switch ( (*it_2).m_uds ) {
1259  case KIO::UDS_NAME:
1260  name = (*it_2).m_str;
1261  break;
1262  case KIO::UDS_ACCESS:
1263  is_exe = ((*it_2).m_long & MODE_EXE) != 0;
1264  break;
1265  case KIO::UDS_FILE_TYPE:
1266  is_dir = ((*it_2).m_long & S_IFDIR) != 0;
1267  break;
1268  case KIO::UDS_URL:
1269  url = (*it_2).m_str;
1270  break;
1271  }
1272  }
1273 
1274  if (!url.isEmpty()) {
1275  // kdDebug() << "KURLCompletion::slotEntries url: " << url << endl;
1276  name = KURL(url).fileName();
1277  }
1278 
1279  // kdDebug() << "KURLCompletion::slotEntries name: " << name << endl;
1280 
1281  if ( name[0] == '.' &&
1282  ( d->list_urls_no_hidden ||
1283  name.length() == 1 ||
1284  ( name.length() == 2 && name[1] == '.' ) ) )
1285  continue;
1286 
1287  if ( d->mode == DirCompletion && !is_dir )
1288  continue;
1289 
1290  if ( filter_len == 0 || name.left(filter_len) == filter ) {
1291  if ( is_dir )
1292  name.append( '/' );
1293 
1294  if ( is_exe || !d->list_urls_only_exe )
1295  matches.append( name );
1296  }
1297  }
1298 
1299  addMatches( matches );
1300 }
1301 
1302 /*
1303  * slotIOFinished
1304  *
1305  * Called when a KIO job is finished.
1306  *
1307  * Start a new list job if there are still urls in
1308  * d->list_urls, otherwise call finished()
1309  */
1310 void KURLCompletion::slotIOFinished( KIO::Job * job )
1311 {
1312 // kdDebug() << "slotIOFinished() " << endl;
1313 
1314  assert( job == d->list_job );
1315 
1316  if ( d->list_urls.isEmpty() ) {
1317 
1318  d->list_job = 0L;
1319 
1320  finished(); // will call KCompletion::makeCompletion()
1321 
1322  }
1323  else {
1324 
1325  KURL *kurl = d->list_urls.first();
1326 
1327  d->list_urls.remove( kurl );
1328 
1329 // kdDebug() << "Start KIO: " << kurl->prettyURL() << endl;
1330 
1331  d->list_job = KIO::listDir( *kurl, false );
1332  d->list_job->addMetaData("no-auth-prompt", "true");
1333 
1334  assert( d->list_job );
1335 
1336  connect( d->list_job,
1337  TQT_SIGNAL(result(KIO::Job*)),
1338  TQT_SLOT(slotIOFinished(KIO::Job*)) );
1339 
1340  connect( d->list_job,
1341  TQT_SIGNAL( entries( KIO::Job*, const KIO::UDSEntryList&)),
1342  TQT_SLOT( slotEntries( KIO::Job*, const KIO::UDSEntryList&)) );
1343 
1344  delete kurl;
1345  }
1346 }
1347 
1350 
1351 /*
1352  * postProcessMatch, postProcessMatches
1353  *
1354  * Called by KCompletion before emitting match() and matches()
1355  *
1356  * Append '/' to directories for file completion. This is
1357  * done here to avoid stat()'ing a lot of files
1358  */
1359 void KURLCompletion::postProcessMatch( TQString *match ) const
1360 {
1361 // kdDebug() << "KURLCompletion::postProcess: " << *match << endl;
1362 
1363  if ( !match->isEmpty() ) {
1364 
1365  // Add '/' to directories in file completion mode
1366  // unless it has already been done
1367  if ( d->last_compl_type == CTFile )
1368  adjustMatch( *match );
1369  }
1370 }
1371 
1372 void KURLCompletion::adjustMatch( TQString& match ) const
1373 {
1374  if ( match.at( match.length()-1 ) != '/' )
1375  {
1376  TQString copy;
1377 
1378  if ( match.startsWith( TQString("file:") ) )
1379  copy = KURL(match).path();
1380  else
1381  copy = match;
1382 
1383  expandTilde( copy );
1384  expandEnv( copy );
1385  if ( TQDir::isRelativePath(copy) )
1386  copy.prepend( d->cwd + '/' );
1387 
1388 // kdDebug() << "postProcess: stating " << copy << endl;
1389 
1390  KDE_struct_stat sbuff;
1391 
1392  TQCString file = TQFile::encodeName( copy );
1393 
1394  if ( KDE_stat( (const char*)file, &sbuff ) == 0 ) {
1395  if ( S_ISDIR ( sbuff.st_mode ) )
1396  match.append( '/' );
1397  }
1398  else {
1399  kdDebug() << "Could not stat file " << copy << endl;
1400  }
1401  }
1402 }
1403 
1404 void KURLCompletion::postProcessMatches( TQStringList * matches ) const
1405 {
1406  if ( !matches->isEmpty() && d->last_compl_type == CTFile ) {
1407  TQStringList::Iterator it = matches->begin();
1408  for (; it != matches->end(); ++it ) {
1409  adjustMatch( (*it) );
1410  }
1411  }
1412 }
1413 
1414 void KURLCompletion::postProcessMatches( KCompletionMatches * matches ) const
1415 {
1416  if ( !matches->isEmpty() && d->last_compl_type == CTFile ) {
1417  KCompletionMatches::Iterator it = matches->begin();
1418  for (; it != matches->end(); ++it ) {
1419  adjustMatch( (*it).value() );
1420  }
1421  }
1422 }
1423 
1424 void KURLCompletion::customEvent(TQCustomEvent *e)
1425 {
1426  if ( e->type() == CompletionMatchEvent::uniqueType() ) {
1427 
1428  CompletionMatchEvent *event = static_cast<CompletionMatchEvent *>( e );
1429 
1430  event->completionThread()->wait();
1431 
1432  if ( !isListedURL( CTUser ) ) {
1433  stop();
1434  clear();
1435  addMatches( event->completionThread()->matches() );
1436  }
1437 
1438  setListedURL( CTUser );
1439 
1440  if ( d->userListThread == event->completionThread() )
1441  d->userListThread = 0;
1442 
1443  if ( d->dirListThread == event->completionThread() )
1444  d->dirListThread = 0;
1445 
1446  delete event->completionThread();
1447  }
1448 }
1449 
1450 // static
1451 TQString KURLCompletion::replacedPath( const TQString& text, bool replaceHome, bool replaceEnv )
1452 {
1453  if ( text.isEmpty() )
1454  return text;
1455 
1456  MyURL url( text, TQString::null ); // no need to replace something of our current cwd
1457  if ( !url.kurl()->isLocalFile() )
1458  return text;
1459 
1460  url.filter( replaceHome, replaceEnv );
1461  return url.dir() + url.file();
1462 }
1463 
1464 
1465 TQString KURLCompletion::replacedPath( const TQString& text )
1466 {
1467  return replacedPath( text, d->replace_home, d->replace_env );
1468 }
1469 
1472 // Static functions
1473 
1474 /*
1475  * expandEnv
1476  *
1477  * Expand environment variables in text. Escaped '$' are ignored.
1478  * Return true if expansion was made.
1479  */
1480 static bool expandEnv( TQString &text )
1481 {
1482  // Find all environment variables beginning with '$'
1483  //
1484  int pos = 0;
1485 
1486  bool expanded = false;
1487 
1488  while ( (pos = text.find('$', pos)) != -1 ) {
1489 
1490  // Skip escaped '$'
1491  //
1492  if ( text[pos-1] == '\\' ) {
1493  pos++;
1494  }
1495  // Variable found => expand
1496  //
1497  else {
1498  // Find the end of the variable = next '/' or ' '
1499  //
1500  int pos2 = text.find( ' ', pos+1 );
1501  int pos_tmp = text.find( '/', pos+1 );
1502 
1503  if ( pos2 == -1 || (pos_tmp != -1 && pos_tmp < pos2) )
1504  pos2 = pos_tmp;
1505 
1506  if ( pos2 == -1 )
1507  pos2 = text.length();
1508 
1509  // Replace if the variable is terminated by '/' or ' '
1510  // and defined
1511  //
1512  if ( pos2 >= 0 ) {
1513  int len = pos2 - pos;
1514  TQString key = text.mid( pos+1, len-1);
1515  TQString value =
1516  TQString::fromLocal8Bit( ::getenv(key.local8Bit()) );
1517 
1518  if ( !value.isEmpty() ) {
1519  expanded = true;
1520  text.replace( pos, len, value );
1521  pos = pos + value.length();
1522  }
1523  else {
1524  pos = pos2;
1525  }
1526  }
1527  }
1528  }
1529 
1530  return expanded;
1531 }
1532 
1533 /*
1534  * expandTilde
1535  *
1536  * Replace "~user" with the users home directory
1537  * Return true if expansion was made.
1538  */
1539 static bool expandTilde(TQString &text)
1540 {
1541  if ( text[0] != '~' )
1542  return false;
1543 
1544  bool expanded = false;
1545 
1546  // Find the end of the user name = next '/' or ' '
1547  //
1548  int pos2 = text.find( ' ', 1 );
1549  int pos_tmp = text.find( '/', 1 );
1550 
1551  if ( pos2 == -1 || (pos_tmp != -1 && pos_tmp < pos2) )
1552  pos2 = pos_tmp;
1553 
1554  if ( pos2 == -1 )
1555  pos2 = text.length();
1556 
1557  // Replace ~user if the user name is terminated by '/' or ' '
1558  //
1559  if ( pos2 >= 0 ) {
1560 
1561  TQString user = text.mid( 1, pos2-1 );
1562  TQString dir;
1563 
1564  // A single ~ is replaced with $HOME
1565  //
1566  if ( user.isEmpty() ) {
1567  dir = TQDir::homeDirPath();
1568  }
1569  // ~user is replaced with the dir from passwd
1570  //
1571  else {
1572  struct passwd *pw = ::getpwnam( user.local8Bit() );
1573 
1574  if ( pw )
1575  dir = TQFile::decodeName( pw->pw_dir );
1576 
1577  ::endpwent();
1578  }
1579 
1580  if ( !dir.isEmpty() ) {
1581  expanded = true;
1582  text.replace(0, pos2, dir);
1583  }
1584  }
1585 
1586  return expanded;
1587 }
1588 
1589 /*
1590  * unescape
1591  *
1592  * Remove escapes and return the result in a new string
1593  *
1594  */
1595 static TQString unescape(const TQString &text)
1596 {
1597  TQString result;
1598 
1599  for (uint pos = 0; pos < text.length(); pos++)
1600  if ( text[pos] != '\\' )
1601  result.insert( result.length(), text[pos] );
1602 
1603  return result;
1604 }
1605 
1606 void KURLCompletion::virtual_hook( int id, void* data )
1607 { KCompletion::virtual_hook( id, data ); }
1608 
1609 #include "kurlcompletion.moc"
1610 
KURLCompletion
This class does completion of URLs including user directories (~user) and environment variables...
Definition: kurlcompletion.h:41
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:565
KIO::ListJob
A ListJob is allows you to get the get the content of a directory.
Definition: jobclasses.h:1392
KURLCompletion::makeCompletion
virtual TQString makeCompletion(const TQString &text)
Finds completions to the given text.
Definition: kurlcompletion.cpp:575
KURLCompletion::Mode
Mode
Determines how completion is done.
Definition: kurlcompletion.h:53
KURLCompletion::setReplaceEnv
virtual void setReplaceEnv(bool replace)
Enables/disables completion and replacement (internally) of environment variables in URLs...
Definition: kurlcompletion.cpp:555
KURLCompletion::setMode
virtual void setMode(Mode mode)
Changes the completion mode: exe or file completion.
Definition: kurlcompletion.cpp:545
KURLCompletion::dir
virtual TQString dir() const
Returns the current directory, as it was given in setDir.
Definition: kurlcompletion.cpp:535
KIO::listDir
KIO_EXPORT ListJob * listDir(const KURL &url, bool showProgressInfo=true, bool includeHidden=true)
List the contents of url, which is assumed to be a directory.
Definition: job.cpp:2152
KIO::UDSEntry
TQValueList< UDSAtom > UDSEntry
An entry is the list of atoms containing all the information for a file or URL.
Definition: global.h:506
KIO::UDS_NAME
Filename - as displayed in directory listings etc.
Definition: global.h:334
KURLCompletion::setDir
virtual void setDir(const TQString &dir)
Sets the current directory (used as base for completion).
Definition: kurlcompletion.cpp:530
KProtocolInfo::supportsListing
static bool supportsListing(const KURL &url)
Returns whether the protocol can list files/objects.
Definition: kprotocolinfo.cpp:121
KURLCompletion::isRunning
virtual bool isRunning() const
Check whether asynchronous completion is in progress.
Definition: kurlcompletion.cpp:673
KIO::UDS_FILE_TYPE
File type, part of the mode returned by stat (for a link, this returns the file type of the pointed i...
Definition: global.h:365
KIO::copy
KIO_EXPORT CopyJob * copy(const KURL &src, const KURL &dest, bool showProgressInfo=true)
Copy a file or directory src into the destination dest, which can be a file (including the final file...
Definition: job.cpp:3886
KProtocolInfo::protocolClass
static TQString protocolClass(const TQString &protocol)
Returns the protocol class for the specified protocol.
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:560
KIO::UDS_ACCESS
Access permissions (part of the mode returned by stat)
Definition: global.h:355
KURLCompletion::mode
virtual Mode mode() const
Returns the completion mode: exe or file completion (default FileCompletion).
Definition: kurlcompletion.cpp:540
KURLCompletion::stop
virtual void stop()
Stops asynchronous completion.
Definition: kurlcompletion.cpp:683
KIO::Job
The base class for all jobs.
Definition: jobclasses.h:68
KIO::UDS_URL
An alternative URL (If different from the caption)
Definition: global.h:370
KURLCompletion::replaceEnv
virtual bool replaceEnv() const
Checks whether environment variables are completed and whether they are replaced internally while fin...
Definition: kurlcompletion.cpp:550
KURLCompletion::KURLCompletion
KURLCompletion()
Constructs a KURLCompletion object in FileCompletion mode.
Definition: kurlcompletion.cpp:489
KURLCompletion::replacedPath
TQString replacedPath(const TQString &text)
Replaces username and/or environment variables, depending on the current settings and returns the fil...
Definition: kurlcompletion.cpp:1465
KURLCompletion::~KURLCompletion
virtual ~KURLCompletion()
Destructs the KURLCompletion object.
Definition: kurlcompletion.cpp:501

kio/kio

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

kio/kio

Skip menu "kio/kio"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for kio/kio by doxygen 1.8.6
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |