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

tdeio/tdeio

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

tdeio/tdeio

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

tdeio/tdeio

Skip menu "tdeio/tdeio"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeio/tdeio by doxygen 1.9.4
This website is maintained by Timothy Pearson.