31 #include <tqstringlist.h>
32 #include <tqvaluelist.h>
37 #include <tqtextstream.h>
38 #include <tqdeepcopy.h>
41 #include <tdeapplication.h>
43 #include <kcompletion.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>
53 #include <sys/types.h>
59 #include <sys/param.h>
61 #include "kurlcompletion.h"
63 static bool expandTilde(TQString &);
64 static bool expandEnv(TQString &);
66 static TQString unescape(
const TQString &text);
70 #define MODE_EXE (S_IXUSR | S_IXGRP | S_IXOTH)
73 enum ComplType {CTNone=0, CTEnv, CTUser, CTMan, CTExe, CTFile, CTUrl, CTInfo};
75 class CompletionThread;
82 class CompletionMatchEvent :
public TQCustomEvent
85 CompletionMatchEvent( CompletionThread *thread ) :
86 TQCustomEvent( uniqueType() ),
87 m_completionThread( thread )
90 CompletionThread *completionThread()
const {
return m_completionThread; }
91 static int uniqueType() {
return User + 61080; }
94 CompletionThread *m_completionThread;
97 class CompletionThread :
public TQThread
102 m_receiver( receiver ),
103 m_terminationRequested( false )
107 void requestTermination() { m_terminationRequested =
true; }
108 TQDeepCopy<TQStringList> matches()
const {
return m_matches; }
111 void addMatch(
const TQString &match ) { m_matches.append( match ); }
112 bool terminationRequested()
const {
return m_terminationRequested; }
115 if ( !m_terminationRequested )
116 kapp->postEvent( m_receiver,
new CompletionMatchEvent(
this ) );
123 TQStringList m_matches;
124 bool m_terminationRequested;
132 class UserListThread :
public CompletionThread
136 CompletionThread( receiver )
142 static const TQChar tilde =
'~';
145 while ( ( pw = ::getpwent() ) && !terminationRequested() )
146 addMatch( tilde + TQString::fromLocal8Bit( pw->pw_name ) );
156 class DirectoryListThread :
public CompletionThread
160 const TQStringList &dirList,
161 const TQString &filter,
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 )
178 TQStringList m_dirList;
183 bool m_appendSlashToDir;
186 void DirectoryListThread::run()
202 for ( TQStringList::ConstIterator it = m_dirList.begin();
203 it != m_dirList.end() && !terminationRequested();
209 dir = ::opendir( TQFile::encodeName( *it ) );
211 kdDebug() <<
"Failed to open dir: " << *it << endl;
221 TQString path = TQDir::currentDirPath();
222 TQDir::setCurrent( *it );
228 #ifndef HAVE_READDIR_R
229 struct dirent *dirEntry = 0;
230 while ( !terminationRequested() &&
231 (dirEntry = ::readdir( dir)))
233 #if !defined(MAXPATHLEN) && defined(__GNU__)
234 #define MAXPATHLEN UCHAR_MAX
236 struct dirent *dirPosition = (
struct dirent *) malloc(
sizeof(
struct dirent ) + MAXPATHLEN + 1 );
237 struct dirent *dirEntry = 0;
238 while ( !terminationRequested() &&
239 ::readdir_r( dir, dirPosition, &dirEntry ) == 0 && dirEntry )
245 if ( dirEntry->d_name[0] ==
'.' && m_noHidden )
250 if ( dirEntry->d_name[0] ==
'.' && dirEntry->d_name[1] ==
'\0' )
255 if ( dirEntry->d_name[0] ==
'.' && dirEntry->d_name[1] ==
'.' && dirEntry->d_name[2] ==
'\0' )
258 TQString file = TQFile::decodeName( dirEntry->d_name );
260 if ( m_filter.isEmpty() || file.startsWith( m_filter ) ) {
262 if ( m_onlyExe || m_onlyDir || m_appendSlashToDir ) {
263 KDE_struct_stat sbuff;
265 if ( KDE_stat( dirEntry->d_name, &sbuff ) == 0 ) {
269 if ( m_onlyExe && ( sbuff.st_mode & MODE_EXE ) == 0 )
274 if ( m_onlyDir && !S_ISDIR( sbuff.st_mode ) )
279 if ( m_appendSlashToDir && S_ISDIR( sbuff.st_mode ) )
284 kdDebug() <<
"Could not stat file " << file << endl;
295 TQDir::setCurrent( path );
299 #ifdef HAVE_READDIR_R
312 class KURLCompletion::MyURL
315 MyURL(
const TQString &url,
const TQString &cwd);
316 MyURL(
const MyURL &url);
319 KURL *kurl()
const {
return m_kurl; }
321 TQString protocol()
const {
return m_kurl->protocol(); }
323 TQString
dir()
const {
return m_kurl->directory(
false,
false); }
324 TQString file()
const {
return m_kurl->fileName(
false); }
327 TQString url()
const {
return m_url; }
330 bool isURL()
const {
return m_isURL; }
332 void filter(
bool replace_user_dir,
bool replace_env );
335 void init(
const TQString &url,
const TQString &cwd);
342 KURLCompletion::MyURL::MyURL(
const TQString &url,
const TQString &cwd)
347 KURLCompletion::MyURL::MyURL(
const MyURL &url)
349 m_kurl =
new KURL( *(url.m_kurl) );
351 m_isURL = url.m_isURL;
354 void KURLCompletion::MyURL::init(
const TQString &url,
const TQString &cwd)
360 TQString url_copy = url;
363 if ( url_copy[0] ==
'#' ) {
364 if ( url_copy[1] ==
'#' )
365 url_copy.replace( 0, 2, TQString(
"info:") );
367 url_copy.replace( 0, 1, TQString(
"man:") );
371 TQRegExp protocol_regex = TQRegExp(
"^[^/\\s\\\\]*:" );
375 if ( protocol_regex.search( url_copy ) == 0 )
377 m_kurl =
new KURL( url_copy );
386 if ( !TQDir::isRelativePath(url_copy) || url_copy[0] ==
'$' || url_copy[0] ==
'~' )
387 m_kurl->setPath( url_copy );
393 KURL base = KURL::fromPathOrURL( cwd );
396 if ( !TQDir::isRelativePath(url_copy) || url_copy[0] ==
'~' || url_copy[0] ==
'$' )
399 m_kurl->setPath( url_copy );
404 m_kurl =
new KURL( base );
405 m_kurl->addPath( url_copy );
411 KURLCompletion::MyURL::~MyURL()
416 void KURLCompletion::MyURL::filter(
bool replace_user_dir,
bool replace_env )
418 TQString d = dir() + file();
419 if ( replace_user_dir ) expandTilde( d );
420 if ( replace_env ) expandEnv( d );
421 m_kurl->setPath( d );
428 class KURLCompletionPrivate
431 KURLCompletionPrivate() : url_auto_completion(true),
434 ~KURLCompletionPrivate();
436 TQValueList<KURL*> list_urls;
441 bool url_auto_completion;
445 bool popup_append_slash;
448 TQString last_path_listed;
449 TQString last_file_listed;
450 TQString last_prepend;
467 bool list_urls_only_exe;
468 bool list_urls_no_hidden;
469 TQString list_urls_filter;
471 CompletionThread *userListThread;
472 CompletionThread *dirListThread;
475 KURLCompletionPrivate::~KURLCompletionPrivate()
477 if ( userListThread )
478 userListThread->requestTermination();
480 dirListThread->requestTermination();
507 void KURLCompletion::init()
509 d =
new KURLCompletionPrivate;
511 d->cwd = TQDir::homeDirPath();
513 d->replace_home =
true;
514 d->replace_env =
true;
515 d->last_no_hidden =
false;
516 d->last_compl_type = 0;
518 d->mode = KURLCompletion::FileCompletion;
521 TDEConfig *c = TDEGlobal::config();
522 TDEConfigGroupSaver cgs( c,
"URLCompletion" );
524 d->url_auto_completion = c->readBoolEntry(
"alwaysAutoComplete",
true);
525 d->popup_append_slash = c->readBoolEntry(
"popupAppendSlash",
true);
526 d->onlyLocalProto = c->readBoolEntry(
"LocalProtocolsOnly",
false);
551 return d->replace_env;
556 d->replace_env = replace;
561 return d->replace_home;
566 d->replace_home = replace;
578 MyURL url(text, d->cwd);
580 d->compl_text = text;
584 int toRemove = url.file().length() - url.kurl()->query().length();
585 if ( url.kurl()->hasRef() )
586 toRemove += url.kurl()->ref().length() + 1;
587 d->prepend = text.left( text.length() - toRemove );
588 d->complete_url = url.isURL();
594 if ( d->replace_env && envCompletion( url, &match ) )
599 if ( d->replace_home && userCompletion( url, &match ) )
603 url.filter( d->replace_home, d->replace_env );
610 if ( d->mode == ExeCompletion ) {
613 if ( exeCompletion( url, &match ) )
619 if ( urlCompletion( url, &match ) )
622 else if ( d->mode == SystemExeCompletion ) {
625 if ( systemexeCompletion( url, &match ) )
631 if ( urlCompletion( url, &match ) )
637 if ( fileCompletion( url, &match ) )
642 if ( urlCompletion( url, &match ) )
646 setListedURL( CTNone );
649 return TQString::null;
658 TQString KURLCompletion::finished()
660 if ( d->last_compl_type == CTInfo )
661 return TDECompletion::makeCompletion( d->compl_text.lower() );
663 return TDECompletion::makeCompletion( d->compl_text );
674 return d->list_job || (d->dirListThread && !d->dirListThread->finished());
689 if ( !d->list_urls.isEmpty() ) {
690 TQValueList<KURL*>::Iterator it = d->list_urls.begin();
691 for ( ; it != d->list_urls.end(); it++ )
693 d->list_urls.clear();
696 if ( d->dirListThread ) {
697 d->dirListThread->requestTermination();
698 d->dirListThread = 0;
705 void KURLCompletion::setListedURL(
int complType,
707 const TQString& filter,
710 d->last_compl_type = complType;
711 d->last_path_listed =
dir;
712 d->last_file_listed = filter;
713 d->last_no_hidden = (int)no_hidden;
714 d->last_prepend = d->prepend;
717 bool KURLCompletion::isListedURL(
int complType,
719 const TQString& filter,
722 return d->last_compl_type == complType
723 && ( d->last_path_listed ==
dir
724 || (
dir.isEmpty() && d->last_path_listed.isEmpty()) )
725 && ( filter.startsWith(d->last_file_listed)
726 || (filter.isEmpty() && d->last_file_listed.isEmpty()) )
727 && d->last_no_hidden == (int)no_hidden
728 && d->last_prepend == d->prepend;
736 bool KURLCompletion::isAutoCompletion()
738 return completionMode() == TDEGlobalSettings::CompletionAuto
739 || completionMode() == TDEGlobalSettings::CompletionPopup
740 || completionMode() == TDEGlobalSettings::CompletionMan
741 || completionMode() == TDEGlobalSettings::CompletionPopupAuto;
748 bool KURLCompletion::userCompletion(
const MyURL &url, TQString *match)
750 if ( url.protocol() !=
"file"
751 || !url.dir().isEmpty()
752 || url.file().at(0) !=
'~' )
755 if ( !isListedURL( CTUser ) ) {
759 if ( !d->userListThread ) {
760 d->userListThread =
new UserListThread(
this );
761 d->userListThread->start();
766 d->userListThread->wait( 200 );
767 TQStringList l = d->userListThread->matches();
780 #if !defined(__OpenBSD__) && !defined(__FreeBSD__)
781 extern char **environ;
784 bool KURLCompletion::envCompletion(
const MyURL &url, TQString *match)
786 #if defined(__OpenBSD__) || defined(__FreeBSD__)
789 if ( url.file().at(0) !=
'$' )
792 if ( !isListedURL( CTEnv ) ) {
796 char **env = environ;
798 TQString dollar = TQString(
"$");
803 TQString s = TQString::fromLocal8Bit( *env );
805 int pos = s.find(
'=');
811 l.append( dollar + s.left(pos) );
819 setListedURL( CTEnv );
831 bool KURLCompletion::exeCompletion(
const MyURL &url, TQString *match)
833 if ( url.protocol() !=
"file" )
836 TQString
dir = url.dir();
847 TQStringList dirList;
849 if ( !TQDir::isRelativePath(
dir) ) {
851 dirList.append(
dir );
853 else if ( !
dir.isEmpty() && !d->cwd.isEmpty() ) {
855 dirList.append( d->cwd +
'/' +
dir );
857 else if ( !url.file().isEmpty() ) {
859 dirList = TQStringList::split(KPATH_SEPARATOR,
860 TQString::fromLocal8Bit(::getenv(
"PATH")));
862 TQStringList::Iterator it = dirList.begin();
864 for ( ; it != dirList.end(); it++ )
869 bool no_hidden_files = url.file().at(0) !=
'.';
873 if ( !isListedURL( CTExe,
dir, url.file(), no_hidden_files ) )
878 setListedURL( CTExe,
dir, url.file(), no_hidden_files );
880 *match = listDirectories( dirList, url.file(),
true,
false, no_hidden_files );
886 if ( d->dirListThread )
887 setListedURL( CTExe,
dir, url.file(), no_hidden_files );
888 *match = TQString::null;
899 bool KURLCompletion::systemexeCompletion(
const MyURL &url, TQString *match)
901 if ( url.protocol() !=
"file" )
904 TQString
dir = url.dir();
915 TQStringList dirList;
917 if ( !url.file().isEmpty() ) {
919 dirList = TQStringList::split(KPATH_SEPARATOR,
920 TQString::fromLocal8Bit(::getenv(
"PATH")));
922 TQStringList::Iterator it = dirList.begin();
924 for ( ; it != dirList.end(); it++ )
929 bool no_hidden_files = url.file().at(0) !=
'.';
933 if ( !isListedURL( CTExe,
dir, url.file(), no_hidden_files ) )
938 setListedURL( CTExe,
dir, url.file(), no_hidden_files );
940 *match = listDirectories( dirList, url.file(),
true,
false, no_hidden_files );
946 if ( d->dirListThread )
947 setListedURL( CTExe,
dir, url.file(), no_hidden_files );
948 *match = TQString::null;
959 bool KURLCompletion::fileCompletion(
const MyURL &url, TQString *match)
961 if ( url.protocol() !=
"file" )
964 TQString
dir = url.dir();
966 if (url.url()[0] ==
'.')
968 if (url.url().length() == 1)
971 ( completionMode() == TDEGlobalSettings::CompletionMan )?
"." :
"..";
974 if (url.url().length() == 2 && url.url()[1]==
'.')
991 TQStringList dirList;
993 if ( !TQDir::isRelativePath(
dir) ) {
995 dirList.append(
dir );
997 else if ( !d->cwd.isEmpty() ) {
999 dirList.append( d->cwd +
'/' +
dir );
1003 bool no_hidden_files = ( url.file().at(0) !=
'.' );
1007 if ( !isListedURL( CTFile,
dir,
"", no_hidden_files ) )
1012 setListedURL( CTFile,
dir,
"", no_hidden_files );
1015 bool append_slash = ( d->popup_append_slash
1016 && (completionMode() == TDEGlobalSettings::CompletionPopup ||
1017 completionMode() == TDEGlobalSettings::CompletionPopupAuto ) );
1019 bool only_dir = ( d->mode == DirCompletion );
1021 *match = listDirectories( dirList,
"",
false, only_dir, no_hidden_files,
1025 *match = finished();
1028 *match = TQString::null;
1039 bool KURLCompletion::urlCompletion(
const MyURL &url, TQString *match)
1046 KURL url_cwd = KURL::fromPathOrURL( d->cwd );
1049 KURL url_dir( url_cwd, url.kurl()->url() );
1057 bool man_or_info = ( url_dir.protocol() == TQString(
"man")
1058 || url_dir.protocol() == TQString(
"info") );
1060 if ( !url_dir.isValid()
1063 && ( url_dir.directory(
false,
false).isEmpty()
1064 || ( isAutoCompletion()
1065 && !d->url_auto_completion ) ) ) ) {
1069 url_dir.setFileName(
"");
1072 TQString
dir = url_dir.directory(
false,
false );
1076 url_dir.setPath(
dir );
1080 if ( !isListedURL( CTUrl, url_dir.prettyURL(), url.file() ) )
1085 setListedURL( CTUrl, url_dir.prettyURL(),
"" );
1087 TQValueList<KURL*> url_list;
1088 url_list.append(
new KURL( url_dir ) );
1090 listURLs( url_list,
"",
false );
1092 *match = TQString::null;
1095 *match = finished();
1098 *match = TQString::null;
1114 void KURLCompletion::addMatches(
const TQStringList &matches )
1116 TQStringList::ConstIterator it = matches.begin();
1117 TQStringList::ConstIterator end = matches.end();
1119 if ( d->complete_url )
1120 for ( ; it != end; it++ )
1121 addItem( d->prepend + KURL::encode_string(*it));
1123 for ( ; it != end; it++ )
1124 addItem( d->prepend + (*it));
1139 TQString KURLCompletion::listDirectories(
1140 const TQStringList &dirList,
1141 const TQString &filter,
1145 bool append_slash_to_dir)
1149 if ( !::getenv(
"KURLCOMPLETION_LOCAL_TDEIO") ) {
1155 if ( d->dirListThread )
1156 d->dirListThread->requestTermination();
1160 for ( TQStringList::ConstIterator it = dirList.begin();
1161 it != dirList.end();
1166 if ( kapp->authorizeURLAction(
"list", KURL(), url ) )
1170 d->dirListThread =
new DirectoryListThread(
this, dirs, filter, only_exe, only_dir,
1171 no_hidden, append_slash_to_dir );
1172 d->dirListThread->start();
1173 d->dirListThread->wait( 200 );
1174 addMatches( d->dirListThread->matches() );
1183 TQValueList<KURL*> url_list;
1185 TQStringList::ConstIterator it = dirList.begin();
1187 for ( ; it != dirList.end(); it++ )
1188 url_list.append(
new KURL(*it) );
1190 listURLs( url_list, filter, only_exe, no_hidden );
1193 return TQString::null;
1205 void KURLCompletion::listURLs(
1206 const TQValueList<KURL *> &urls,
1207 const TQString &filter,
1211 assert( d->list_urls.isEmpty() );
1212 assert( d->list_job == 0L );
1214 d->list_urls = urls;
1215 d->list_urls_filter = filter;
1216 d->list_urls_only_exe = only_exe;
1217 d->list_urls_no_hidden = no_hidden;
1234 void KURLCompletion::slotEntries(
TDEIO::Job*,
const TDEIO::UDSEntryList& entries)
1236 TQStringList matches;
1238 TDEIO::UDSEntryListConstIterator it = entries.begin();
1239 TDEIO::UDSEntryListConstIterator end = entries.end();
1241 TQString filter = d->list_urls_filter;
1243 int filter_len = filter.length();
1247 for (; it != end; ++it) {
1250 bool is_exe =
false;
1251 bool is_dir =
false;
1254 TDEIO::UDSEntry::ConstIterator it_2 = e.begin();
1256 for( ; it_2 != e.end(); it_2++ ) {
1257 switch ( (*it_2).m_uds ) {
1259 name = (*it_2).m_str;
1262 is_exe = ((*it_2).m_long & MODE_EXE) != 0;
1265 is_dir = ((*it_2).m_long & S_IFDIR) != 0;
1268 url = (*it_2).m_str;
1273 if (!url.isEmpty()) {
1275 name = KURL(url).fileName();
1280 if ( name[0] ==
'.' &&
1281 ( d->list_urls_no_hidden ||
1282 name.length() == 1 ||
1283 ( name.length() == 2 && name[1] ==
'.' ) ) )
1286 if ( d->mode == DirCompletion && !is_dir )
1289 if ( filter_len == 0 || name.left(filter_len) == filter ) {
1293 if ( is_exe || !d->list_urls_only_exe )
1294 matches.append( name );
1298 addMatches( matches );
1309 void KURLCompletion::slotIOFinished(
TDEIO::Job * job )
1313 assert( job == d->list_job );
1315 if ( d->list_urls.isEmpty() ) {
1324 KURL *kurl = d->list_urls.first();
1326 d->list_urls.remove( kurl );
1331 d->list_job->addMetaData(
"no-auth-prompt",
"true");
1333 assert( d->list_job );
1335 connect( d->list_job,
1339 connect( d->list_job,
1340 TQT_SIGNAL( entries(
TDEIO::Job*,
const TDEIO::UDSEntryList&)),
1341 TQT_SLOT( slotEntries(
TDEIO::Job*,
const TDEIO::UDSEntryList&)) );
1358 void KURLCompletion::postProcessMatch( TQString *match )
const
1362 if ( !match->isEmpty() ) {
1366 if ( d->last_compl_type == CTFile )
1367 adjustMatch( *match );
1371 void KURLCompletion::adjustMatch( TQString& match )
const
1373 if ( match.at( match.length()-1 ) !=
'/' )
1377 if ( match.startsWith( TQString(
"file:") ) )
1378 copy = KURL(match).path();
1382 expandTilde( copy );
1384 if ( TQDir::isRelativePath(copy) )
1385 copy.prepend( d->cwd +
'/' );
1389 KDE_struct_stat sbuff;
1391 TQCString file = TQFile::encodeName( copy );
1393 if ( KDE_stat( (
const char*)file, &sbuff ) == 0 ) {
1394 if ( S_ISDIR ( sbuff.st_mode ) )
1395 match.append(
'/' );
1398 kdDebug() <<
"Could not stat file " <<
copy << endl;
1403 void KURLCompletion::postProcessMatches( TQStringList * matches )
const
1405 if ( !matches->isEmpty() && d->last_compl_type == CTFile ) {
1406 TQStringList::Iterator it = matches->begin();
1407 for (; it != matches->end(); ++it ) {
1408 adjustMatch( (*it) );
1413 void KURLCompletion::postProcessMatches( TDECompletionMatches * matches )
const
1415 if ( !matches->isEmpty() && d->last_compl_type == CTFile ) {
1416 TDECompletionMatches::Iterator it = matches->begin();
1417 for (; it != matches->end(); ++it ) {
1418 adjustMatch( (*it).value() );
1423 void KURLCompletion::customEvent(TQCustomEvent *e)
1425 if ( e->type() == CompletionMatchEvent::uniqueType() ) {
1427 CompletionMatchEvent *
event =
static_cast<CompletionMatchEvent *
>( e );
1429 event->completionThread()->wait();
1431 if ( !isListedURL( CTUser ) ) {
1434 addMatches( event->completionThread()->matches() );
1437 setListedURL( CTUser );
1439 if ( d->userListThread == event->completionThread() )
1440 d->userListThread = 0;
1442 if ( d->dirListThread == event->completionThread() )
1443 d->dirListThread = 0;
1445 delete event->completionThread();
1452 if ( text.isEmpty() )
1455 MyURL url( text, TQString::null );
1456 if ( !url.kurl()->isLocalFile() )
1460 return url.dir() + url.file();
1466 return replacedPath( text, d->replace_home, d->replace_env );
1479 static bool expandEnv( TQString &text )
1485 bool expanded =
false;
1487 while ( (pos = text.find(
'$', pos)) != -1 ) {
1491 if ( text[pos-1] ==
'\\' ) {
1499 int pos2 = text.find(
' ', pos+1 );
1500 int pos_tmp = text.find(
'/', pos+1 );
1502 if ( pos2 == -1 || (pos_tmp != -1 && pos_tmp < pos2) )
1506 pos2 = text.length();
1512 int len = pos2 - pos;
1513 TQString key = text.mid( pos+1, len-1);
1515 TQString::fromLocal8Bit( ::getenv(key.local8Bit()) );
1517 if ( !value.isEmpty() ) {
1519 text.replace( pos, len, value );
1520 pos = pos + value.length();
1538 static bool expandTilde(TQString &text)
1540 if ( text[0] !=
'~' )
1543 bool expanded =
false;
1547 int pos2 = text.find(
' ', 1 );
1548 int pos_tmp = text.find(
'/', 1 );
1550 if ( pos2 == -1 || (pos_tmp != -1 && pos_tmp < pos2) )
1554 pos2 = text.length();
1560 TQString user = text.mid( 1, pos2-1 );
1565 if ( user.isEmpty() ) {
1566 dir = TQDir::homeDirPath();
1571 struct passwd *pw = ::getpwnam( user.local8Bit() );
1574 dir = TQFile::decodeName( pw->pw_dir );
1579 if ( !dir.isEmpty() ) {
1581 text.replace(0, pos2, dir);
1594 static TQString unescape(
const TQString &text)
1598 for (uint pos = 0; pos < text.length(); pos++)
1599 if ( text[pos] !=
'\\' )
1600 result.insert( result.length(), text[pos] );
1605 void KURLCompletion::virtual_hook(
int id,
void* data )
1606 { TDECompletion::virtual_hook(
id, data ); }
1608 #include "kurlcompletion.moc"