summaryrefslogtreecommitdiffabout
path: root/microkde/kdecore/kstandarddirs.cpp
Unidiff
Diffstat (limited to 'microkde/kdecore/kstandarddirs.cpp') (more/less context) (show whitespace changes)
-rw-r--r--microkde/kdecore/kstandarddirs.cpp1620
1 files changed, 1620 insertions, 0 deletions
diff --git a/microkde/kdecore/kstandarddirs.cpp b/microkde/kdecore/kstandarddirs.cpp
new file mode 100644
index 0000000..5abe05c
--- a/dev/null
+++ b/microkde/kdecore/kstandarddirs.cpp
@@ -0,0 +1,1620 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 1999 Sirtaj Singh Kang <taj@kde.org>
3 Copyright (C) 1999 Stephan Kulow <coolo@kde.org>
4 Copyright (C) 1999 Waldo Bastian <bastian@kde.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License version 2 as published by the Free Software Foundation.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/*
22 * Author: Stephan Kulow <coolo@kde.org> and Sirtaj Singh Kang <taj@kde.org>
23 * Version:$Id$
24 * Generated:Thu Mar 5 16:05:28 EST 1998
25 */
26
27//US #include "config.h"
28
29#include <stdlib.h>
30#include <assert.h>
31//US#include <errno.h>
32//US #ifdef HAVE_SYS_STAT_H
33//US #include <sys/stat.h>
34//US #endif
35//US#include <sys/types.h>
36//US#include <dirent.h>
37//US#include <pwd.h>
38
39#include <qregexp.h>
40#include <qasciidict.h>
41#include <qdict.h>
42#include <qdir.h>
43#include <qfileinfo.h>
44#include <qstring.h>
45#include <qstringlist.h>
46
47#include "kstandarddirs.h"
48#include "kconfig.h"
49#include "kdebug.h"
50//US #include "kinstance.h"
51#include "kshell.h"
52//US#include <sys/param.h>
53//US#include <unistd.h>
54
55//US
56QString KStandardDirs::mAppDir = QString::null;
57
58
59template class QDict<QStringList>;
60
61#if 0
62#include <qtextedit.h>
63void ddd( QString op )
64{
65 static QTextEdit * dot = 0;
66 if ( ! dot )
67 dot = new QTextEdit();
68
69 dot->show();
70
71 dot->append( op );
72
73}
74#endif
75class KStandardDirs::KStandardDirsPrivate
76{
77public:
78 KStandardDirsPrivate()
79 : restrictionsActive(false),
80 dataRestrictionActive(false)
81 { }
82
83 bool restrictionsActive;
84 bool dataRestrictionActive;
85 QAsciiDict<bool> restrictions;
86 QStringList xdgdata_prefixes;
87 QStringList xdgconf_prefixes;
88};
89
90static const char* const types[] = {"html", "icon", "apps", "sound",
91 "data", "locale", "services", "mime",
92 "servicetypes", "config", "exe",
93 "wallpaper", "lib", "pixmap", "templates",
94 "module", "qtplugins",
95 "xdgdata-apps", "xdgdata-dirs", "xdgconf-menu", 0 };
96
97static int tokenize( QStringList& token, const QString& str,
98 const QString& delim );
99
100KStandardDirs::KStandardDirs( ) : addedCustoms(false)
101{
102 d = new KStandardDirsPrivate;
103 dircache.setAutoDelete(true);
104 relatives.setAutoDelete(true);
105 absolutes.setAutoDelete(true);
106 savelocations.setAutoDelete(true);
107 addKDEDefaults();
108}
109
110KStandardDirs::~KStandardDirs()
111{
112 delete d;
113}
114
115bool KStandardDirs::isRestrictedResource(const char *type, const QString& relPath) const
116{
117 if (!d || !d->restrictionsActive)
118 return false;
119
120 if (d->restrictions[type])
121 return true;
122
123 if (strcmp(type, "data")==0)
124 {
125 applyDataRestrictions(relPath);
126 if (d->dataRestrictionActive)
127 {
128 d->dataRestrictionActive = false;
129 return true;
130 }
131 }
132 return false;
133}
134
135void KStandardDirs::applyDataRestrictions(const QString &relPath) const
136{
137 QString key;
138 int i = relPath.find('/');
139 if (i != -1)
140 key = "data_"+relPath.left(i);
141 else
142 key = "data_"+relPath;
143
144 if (d && d->restrictions[key.latin1()])
145 d->dataRestrictionActive = true;
146}
147
148
149QStringList KStandardDirs::allTypes() const
150{
151 QStringList list;
152 for (int i = 0; types[i] != 0; ++i)
153 list.append(QString::fromLatin1(types[i]));
154 return list;
155}
156
157void KStandardDirs::addPrefix( const QString& _dir )
158{
159 if (_dir.isNull())
160 return;
161
162 QString dir = _dir;
163 if (dir.at(dir.length() - 1) != '/')
164 dir += '/';
165
166 if (!prefixes.contains(dir)) {
167 prefixes.append(dir);
168 dircache.clear();
169 }
170}
171
172void KStandardDirs::addXdgConfigPrefix( const QString& _dir )
173{
174 if (_dir.isNull())
175 return;
176
177 QString dir = _dir;
178 if (dir.at(dir.length() - 1) != '/')
179 dir += '/';
180
181 if (!d->xdgconf_prefixes.contains(dir)) {
182 d->xdgconf_prefixes.append(dir);
183 dircache.clear();
184 }
185}
186
187void KStandardDirs::addXdgDataPrefix( const QString& _dir )
188{
189 if (_dir.isNull())
190 return;
191
192 QString dir = _dir;
193 if (dir.at(dir.length() - 1) != '/')
194 dir += '/';
195
196 if (!d->xdgdata_prefixes.contains(dir)) {
197 d->xdgdata_prefixes.append(dir);
198 dircache.clear();
199 }
200}
201
202
203QString KStandardDirs::kfsstnd_prefixes()
204{
205 return prefixes.join(":");
206}
207
208bool KStandardDirs::addResourceType( const char *type,
209 const QString& relativename )
210{
211 if (relativename.isNull())
212 return false;
213
214 QStringList *rels = relatives.find(type);
215 if (!rels) {
216 rels = new QStringList();
217 relatives.insert(type, rels);
218 }
219 QString copy = relativename;
220 if (copy.at(copy.length() - 1) != '/')
221 copy += '/';
222 if (!rels->contains(copy)) {
223 rels->prepend(copy);
224 dircache.remove(type); // clean the cache
225 return true;
226 }
227 return false;
228}
229
230bool KStandardDirs::addResourceDir( const char *type,
231 const QString& absdir)
232{
233 QStringList *paths = absolutes.find(type);
234 if (!paths) {
235 paths = new QStringList();
236 absolutes.insert(type, paths);
237 }
238 QString copy = absdir;
239 if (copy.at(copy.length() - 1) != '/')
240 copy += '/';
241
242 if (!paths->contains(copy)) {
243 paths->append(copy);
244 dircache.remove(type); // clean the cache
245 return true;
246 }
247 return false;
248}
249
250QString KStandardDirs::findResource( const char *type,
251 const QString& filename ) const
252{
253 if (filename.at(0) == '/')
254 return filename; // absolute dirs are absolute dirs, right? :-/
255
256#if 0
257kdDebug() << "Find resource: " << type << endl;
258for (QStringList::ConstIterator pit = prefixes.begin();
259 pit != prefixes.end();
260 pit++)
261{
262 kdDebug() << "Prefix: " << *pit << endl;
263}
264#endif
265
266 QString dir = findResourceDir(type, filename);
267 if (dir.isNull())
268 return dir;
269 else return dir + filename;
270}
271/*US
272static Q_UINT32 updateHash(const QString &file, Q_UINT32 hash)
273{
274 QCString cFile = QFile::encodeName(file);
275//US struct stat buff;
276//US if ((access(cFile, R_OK) == 0) &&
277//US (stat( cFile, &buff ) == 0) &&
278//US (S_ISREG( buff.st_mode )))
279 QFileInfo pathfnInfo(cFile);
280 if (( pathfnInfo.isReadable() == true ) &&
281 ( pathfnInfo.isFile()) )
282 {
283//US hash = hash + (Q_UINT32) buff.st_ctime;
284 hash = hash + (Q_UINT32) pathfnInfo.lastModified();
285 }
286 return hash;
287}
288*/
289/*US
290Q_UINT32 KStandardDirs::calcResourceHash( const char *type,
291 const QString& filename, bool deep) const
292{
293 Q_UINT32 hash = 0;
294
295 if (filename.at(0) == '/')
296 {
297 // absolute dirs are absolute dirs, right? :-/
298 return updateHash(filename, hash);
299 }
300 if (d && d->restrictionsActive && (strcmp(type, "data")==0))
301 applyDataRestrictions(filename);
302 QStringList candidates = resourceDirs(type);
303 QString fullPath;
304
305 for (QStringList::ConstIterator it = candidates.begin();
306 it != candidates.end(); it++)
307 {
308 hash = updateHash(*it + filename, hash);
309 if (!deep && hash)
310 return hash;
311 }
312 return hash;
313}
314*/
315
316QStringList KStandardDirs::findDirs( const char *type,
317 const QString& reldir ) const
318{
319 QStringList list;
320
321 checkConfig();
322
323 if (d && d->restrictionsActive && (strcmp(type, "data")==0))
324 applyDataRestrictions(reldir);
325 QStringList candidates = resourceDirs(type);
326 QDir testdir;
327
328 for (QStringList::ConstIterator it = candidates.begin();
329 it != candidates.end(); it++) {
330 testdir.setPath(*it + reldir);
331 if (testdir.exists())
332 list.append(testdir.absPath() + '/');
333 }
334
335 return list;
336}
337
338QString KStandardDirs::findResourceDir( const char *type,
339 const QString& filename) const
340{
341#ifndef NDEBUG
342 if (filename.isEmpty()) {
343 kdWarning() << "filename for type " << type << " in KStandardDirs::findResourceDir is not supposed to be empty!!" << endl;
344 return QString::null;
345 }
346#endif
347
348 if (d && d->restrictionsActive && (strcmp(type, "data")==0))
349 applyDataRestrictions(filename);
350 QStringList candidates = resourceDirs(type);
351 QString fullPath;
352
353 for (QStringList::ConstIterator it = candidates.begin();
354 it != candidates.end(); it++)
355 if (exists(*it + filename))
356 return *it;
357
358#ifndef NDEBUG
359 if(false && type != "locale")
360 kdDebug() << "KStdDirs::findResDir(): can't find \"" << filename << "\" in type \"" << type << "\"." << endl;
361#endif
362
363 return QString::null;
364}
365
366bool KStandardDirs::exists(const QString &fullPath)
367{
368//US struct stat buff;
369 QFileInfo fullPathInfo(QFile::encodeName(fullPath));
370
371//US if (access(QFile::encodeName(fullPath), R_OK) == 0 && fullPathInfo.isReadable())
372 if (fullPathInfo.isReadable())
373 {
374 if (fullPath.at(fullPath.length() - 1) != '/') {
375 //US if (S_ISREG( buff.st_mode ))
376 if (fullPathInfo.isFile())
377 return true;
378 }
379 else {
380 //US if (S_ISDIR( buff.st_mode ))
381 if (fullPathInfo.isDir())
382 return true;
383 }
384 }
385 return false;
386}
387
388static void lookupDirectory(const QString& path, const QString &relPart,
389 const QRegExp &regexp,
390 QStringList& list,
391 QStringList& relList,
392 bool recursive, bool uniq)
393{
394 QString pattern = regexp.pattern();
395 if (recursive || pattern.contains('?') || pattern.contains('*'))
396 {
397 // We look for a set of files.
398//US DIR *dp = opendir( QFile::encodeName(path));
399 QDir dp(QFile::encodeName(path));
400 if (!dp.exists())
401 return;
402 static int iii = 0;
403 ++iii;
404 if ( iii == 5 )
405 abort();
406 assert(path.at(path.length() - 1) == '/');
407
408//US struct dirent *ep;
409//US struct stat buff;
410
411 QString _dot(".");
412 QString _dotdot("..");
413
414//US while( ( ep = readdir( dp ) ) != 0L )
415 QStringList direntries = dp.entryList();
416 QStringList::Iterator it = direntries.begin();
417
418 while ( it != list.end() ) // for each file...
419 {
420
421//US QString fn( QFile::decodeName(ep->d_name));
422 QString fn = (*it); // dp.entryList already decodes
423 it++;
424 if ( fn.isNull() )
425 break;
426
427 if (fn == _dot || fn == _dotdot || fn.at(fn.length() - 1).latin1() == '~' )
428 continue;
429
430/*US
431 if (!recursive && !regexp.exactMatch(fn))
432 continue; // No match
433*/
434//US this should do the same:
435 int pos = regexp.match(fn);
436 if (!recursive && !pos == 0)
437 continue; // No match
438
439 QString pathfn = path + fn;
440/*US
441 if ( stat( QFile::encodeName(pathfn), &buff ) != 0 ) {
442 kdDebug() << "Error stat'ing " << pathfn << " : " << perror << endl;
443 continue; // Couldn't stat (e.g. no read permissions)
444 }
445
446 if ( recursive )
447 {
448 if ( S_ISDIR( buff.st_mode )) {
449 lookupDirectory(pathfn + '/', relPart + fn + '/', regexp, list, relList, recursive, uniq);
450 }
451*/
452//US replacement:
453 QFileInfo pathfnInfo(QFile::encodeName(pathfn));
454 if ( pathfnInfo.isReadable() == false )
455 {
456//US kdDebug() << "Error stat'ing " << pathfn << " : " << perror << endl;
457 continue; // Couldn't stat (e.g. no read permissions)
458 }
459
460 if ( recursive )
461 {
462 if ( pathfnInfo.isDir()) {
463 lookupDirectory(pathfn + '/', relPart + fn + '/', regexp, list, relList, recursive, uniq);
464 }
465
466
467/*US
468 if (!regexp.exactMatch(fn))
469 continue; // No match
470*/
471//US this should do the same:
472 pos = regexp.match(fn);
473 if (!pos == 0)
474 continue; // No match
475 }
476
477//US if ( S_ISREG( buff.st_mode))
478 if ( pathfnInfo.isFile())
479 {
480 if (!uniq || !relList.contains(relPart + fn))
481 {
482 list.append( pathfn );
483 relList.append( relPart + fn );
484 }
485 }
486 }
487//US closedir( dp );
488 }
489 else
490 {
491 // We look for a single file.
492 QString fn = pattern;
493 QString pathfn = path + fn;
494//US struct stat buff;
495 QFileInfo pathfnInfo(QFile::encodeName(pathfn));
496
497
498//US if ( stat( QFile::encodeName(pathfn), &buff ) != 0 )
499 if ( pathfnInfo.isReadable() == false )
500 return; // File not found
501
502//US if ( S_ISREG( buff.st_mode))
503 if ( pathfnInfo.isFile())
504 {
505 if (!uniq || !relList.contains(relPart + fn))
506 {
507 list.append( pathfn );
508 relList.append( relPart + fn );
509 }
510 }
511 }
512}
513
514static void lookupPrefix(const QString& prefix, const QString& relpath,
515 const QString& relPart,
516 const QRegExp &regexp,
517 QStringList& list,
518 QStringList& relList,
519 bool recursive, bool uniq)
520{
521 if (relpath.isNull()) {
522 lookupDirectory(prefix, relPart, regexp, list,
523 relList, recursive, uniq);
524 return;
525 }
526 QString path;
527 QString rest;
528
529 if (relpath.length())
530 {
531 int slash = relpath.find('/');
532 if (slash < 0)
533 rest = relpath.left(relpath.length() - 1);
534 else {
535 path = relpath.left(slash);
536 rest = relpath.mid(slash + 1);
537 }
538 }
539 assert(prefix.at(prefix.length() - 1) == '/');
540
541//US struct stat buff;
542
543 if (path.contains('*') || path.contains('?')) {
544 QRegExp pathExp(path, true, true);
545 //USDIR *dp = opendir( QFile::encodeName(prefix) );
546 QDir dp(QFile::encodeName(prefix));
547
548 //USif (!dp)
549 if (!dp.exists())
550 {
551 return;
552 }
553
554 //USstruct dirent *ep;
555
556 QString _dot(".");
557 QString _dotdot("..");
558
559 //USwhile( ( ep = readdir( dp ) ) != 0L )
560 QStringList direntries = dp.entryList();
561 QStringList::Iterator it = direntries.begin();
562
563 while ( it != list.end() ) // for each file...
564 {
565//US QString fn( QFile::decodeName(ep->d_name));
566 QString fn = (*it); // dp.entryList() already encodes the strings
567 it++;
568
569 if (fn == _dot || fn == _dotdot || fn.at(fn.length() - 1) == '~')
570 continue;
571
572#ifdef DESKTOP_VERSION
573
574 if (pathExp.search(fn) == -1)
575 continue; // No match
576
577#else
578//US this should do the same:
579 if (pathExp.find(fn, 0) == -1)
580 continue; // No match
581#endif
582 QString rfn = relPart+fn;
583 fn = prefix + fn;
584//US if ( stat( QFile::encodeName(fn), &buff ) != 0 )
585 QFileInfo fnInfo(QFile::encodeName(fn));
586 if ( fnInfo.isReadable() == false )
587 {
588//US kdDebug() << "Error statting " << fn << " : " << perror << endl;
589 continue; // Couldn't stat (e.g. no permissions)
590 }
591 //US if ( S_ISDIR( buff.st_mode ))
592 if ( fnInfo.isDir() )
593
594 lookupPrefix(fn + '/', rest, rfn + '/', regexp, list, relList, recursive, uniq);
595 }
596
597 //USclosedir( dp );
598 } else {
599 // Don't stat, if the dir doesn't exist we will find out
600 // when we try to open it.
601 lookupPrefix(prefix + path + '/', rest,
602 relPart + path + '/', regexp, list,
603 relList, recursive, uniq);
604 }
605}
606
607QStringList
608KStandardDirs::findAllResources( const char *type,
609 const QString& filter,
610 bool recursive,
611 bool uniq,
612 QStringList &relList) const
613{
614 QStringList list;
615 if (filter.at(0) == '/') // absolute paths we return
616 {
617 list.append( filter);
618 return list;
619 }
620
621 QString filterPath;
622 QString filterFile;
623
624 if (filter.length())
625 {
626 int slash = filter.findRev('/');
627 if (slash < 0)
628 filterFile = filter;
629 else {
630 filterPath = filter.left(slash + 1);
631 filterFile = filter.mid(slash + 1);
632 }
633 }
634 checkConfig();
635
636 if (d && d->restrictionsActive && (strcmp(type, "data")==0))
637 applyDataRestrictions(filter);
638 QStringList candidates = resourceDirs(type);
639 if (filterFile.isEmpty())
640 filterFile = "*";
641
642 QRegExp regExp(filterFile, true, true);
643 for (QStringList::ConstIterator it = candidates.begin();
644 it != candidates.end(); it++)
645 {
646 lookupPrefix(*it, filterPath, "", regExp, list,
647 relList, recursive, uniq);
648 }
649 return list;
650}
651
652QStringList
653KStandardDirs::findAllResources( const char *type,
654 const QString& filter,
655 bool recursive,
656 bool uniq) const
657{
658 QStringList relList;
659 return findAllResources(type, filter, recursive, uniq, relList);
660}
661
662QString
663KStandardDirs::realPath(const QString &dirname)
664{
665#ifdef _WIN32_
666 return dirname;
667#else
668//US char realpath_buffer[MAXPATHLEN + 1];
669//US memset(realpath_buffer, 0, MAXPATHLEN + 1);
670 char realpath_buffer[250 + 1];
671 memset(realpath_buffer, 0, 250 + 1);
672
673 /* If the path contains symlinks, get the real name */
674 if (realpath( QFile::encodeName(dirname).data(), realpath_buffer) != 0) {
675 // succes, use result from realpath
676 int len = strlen(realpath_buffer);
677 realpath_buffer[len] = '/';
678 realpath_buffer[len+1] = 0;
679 return QFile::decodeName(realpath_buffer);
680 }
681
682 return dirname;
683#endif
684}
685/*US
686void KStandardDirs::createSpecialResource(const char *type)
687{
688 char hostname[256];
689 hostname[0] = 0;
690 gethostname(hostname, 255);
691 QString dir = QString("%1%2-%3").arg(localkdedir()).arg(type).arg(hostname);
692 char link[1024];
693 link[1023] = 0;
694 int result = readlink(QFile::encodeName(dir).data(), link, 1023);
695 if ((result == -1) && (errno == ENOENT))
696 {
697 QString srv = findExe(QString::fromLatin1("lnusertemp"), KDEDIR+QString::fromLatin1("/bin"));
698 if (srv.isEmpty())
699 srv = findExe(QString::fromLatin1("lnusertemp"));
700 if (!srv.isEmpty())
701 {
702 system(QFile::encodeName(srv)+" "+type);
703 result = readlink(QFile::encodeName(dir).data(), link, 1023);
704 }
705 }
706 if (result > 0)
707 {
708 link[result] = 0;
709 if (link[0] == '/')
710 dir = QFile::decodeName(link);
711 else
712 dir = QDir::cleanDirPath(dir+QFile::decodeName(link));
713 }
714 addResourceDir(type, dir+'/');
715}
716*/
717
718QStringList KStandardDirs::resourceDirs(const char *type) const
719{
720 QStringList *candidates = dircache.find(type);
721
722 if (!candidates) { // filling cache
723/*US
724 if (strcmp(type, "socket") == 0)
725 const_cast<KStandardDirs *>(this)->createSpecialResource(type);
726 else if (strcmp(type, "tmp") == 0)
727 const_cast<KStandardDirs *>(this)->createSpecialResource(type);
728 else if (strcmp(type, "cache") == 0)
729 const_cast<KStandardDirs *>(this)->createSpecialResource(type);
730*/
731 QDir testdir;
732
733 candidates = new QStringList();
734 QStringList *dirs;
735
736 bool restrictionActive = false;
737 if (d && d->restrictionsActive)
738 {
739 if (d->dataRestrictionActive)
740 restrictionActive = true;
741 else if (d->restrictions["all"])
742 restrictionActive = true;
743 else if (d->restrictions[type])
744 restrictionActive = true;
745 d->dataRestrictionActive = false; // Reset
746 }
747
748 dirs = relatives.find(type);
749 if (dirs)
750 {
751 bool local = true;
752 const QStringList *prefixList = 0;
753 if (strncmp(type, "xdgdata-", 8) == 0)
754 prefixList = &(d->xdgdata_prefixes);
755 else if (strncmp(type, "xdgconf-", 8) == 0)
756 prefixList = &(d->xdgconf_prefixes);
757 else
758 prefixList = &prefixes;
759
760 for (QStringList::ConstIterator pit = prefixList->begin();
761 pit != prefixList->end();
762 pit++)
763 {
764 for (QStringList::ConstIterator it = dirs->begin();
765 it != dirs->end(); ++it) {
766 QString path = realPath(*pit + *it);
767 testdir.setPath(path);
768 if (local && restrictionActive)
769 continue;
770 if ((local || testdir.exists()) && !candidates->contains(path))
771 candidates->append(path);
772 }
773 local = false;
774 }
775 }
776 dirs = absolutes.find(type);
777 if (dirs)
778 for (QStringList::ConstIterator it = dirs->begin();
779 it != dirs->end(); ++it)
780 {
781 testdir.setPath(*it);
782 if (testdir.exists())
783 {
784 QString filename = realPath(*it);
785 if (!candidates->contains(filename))
786 candidates->append(filename);
787 }
788 }
789 dircache.insert(type, candidates);
790 }
791
792#if 0
793 kdDebug() << "found dirs for resource " << type << ":" << endl;
794 for (QStringList::ConstIterator pit = candidates->begin();
795 pit != candidates->end();
796 pit++)
797 {
798 fprintf(stderr, "%s\n", (*pit).latin1());
799 }
800#endif
801
802
803 return *candidates;
804}
805
806/*US
807QString KStandardDirs::findExe( const QString& appname,
808 const QString& pstr, bool ignore)
809{
810 QFileInfo info;
811
812 // absolute path ?
813 if (appname.startsWith(QString::fromLatin1("/")))
814 {
815 info.setFile( appname );
816 if( info.exists() && ( ignore || info.isExecutable() )
817 && info.isFile() ) {
818 return appname;
819 }
820 return QString::null;
821 }
822
823//US QString p = QString("%1/%2").arg(__KDE_BINDIR).arg(appname);
824 QString p = QString("%1/%2").arg(appname).arg(appname);
825 qDebug("KStandardDirs::findExe this is probably wrong");
826
827 info.setFile( p );
828 if( info.exists() && ( ignore || info.isExecutable() )
829 && ( info.isFile() || info.isSymLink() ) ) {
830 return p;
831 }
832
833 QStringList tokens;
834 p = pstr;
835
836 if( p.isNull() ) {
837 p = getenv( "PATH" );
838 }
839
840 tokenize( tokens, p, ":\b" );
841
842 // split path using : or \b as delimiters
843 for( unsigned i = 0; i < tokens.count(); i++ ) {
844 p = tokens[ i ];
845
846 if ( p[ 0 ] == '~' )
847 {
848 int len = p.find( '/' );
849 if ( len == -1 )
850 len = p.length();
851 if ( len == 1 )
852 p.replace( 0, 1, QDir::homeDirPath() );
853 else
854 {
855 QString user = p.mid( 1, len - 1 );
856 struct passwd *dir = getpwnam( user.local8Bit().data() );
857 if ( dir && strlen( dir->pw_dir ) )
858 p.replace( 0, len, QString::fromLocal8Bit( dir->pw_dir ) );
859 }
860 }
861
862 p += "/";
863 p += appname;
864
865 // Check for executable in this tokenized path
866 info.setFile( p );
867
868 if( info.exists() && ( ignore || info.isExecutable() )
869 && ( info.isFile() || info.isSymLink() ) ) {
870 return p;
871 }
872 }
873
874 // If we reach here, the executable wasn't found.
875 // So return empty string.
876
877 return QString::null;
878}
879
880int KStandardDirs::findAllExe( QStringList& list, const QString& appname,
881 const QString& pstr, bool ignore )
882{
883 QString p = pstr;
884 QFileInfo info;
885 QStringList tokens;
886
887 if( p.isNull() ) {
888 p = getenv( "PATH" );
889 }
890
891 list.clear();
892 tokenize( tokens, p, ":\b" );
893
894 for ( unsigned i = 0; i < tokens.count(); i++ ) {
895 p = tokens[ i ];
896 p += "/";
897 p += appname;
898
899 info.setFile( p );
900
901 if( info.exists() && (ignore || info.isExecutable())
902 && info.isFile() ) {
903 list.append( p );
904 }
905
906 }
907
908 return list.count();
909}
910*/
911
912static int tokenize( QStringList& tokens, const QString& str,
913 const QString& delim )
914{
915 int len = str.length();
916 QString token = "";
917
918 for( int index = 0; index < len; index++)
919 {
920 if ( delim.find( str[ index ] ) >= 0 )
921 {
922 tokens.append( token );
923 token = "";
924 }
925 else
926 {
927 token += str[ index ];
928 }
929 }
930 if ( token.length() > 0 )
931 {
932 tokens.append( token );
933 }
934
935 return tokens.count();
936}
937
938QString KStandardDirs::kde_default(const char *type) {
939 if (!strcmp(type, "data"))
940 return "apps/";
941 if (!strcmp(type, "html"))
942 return "share/doc/HTML/";
943 if (!strcmp(type, "icon"))
944 return "share/icons/";
945 if (!strcmp(type, "config"))
946 return "config/";
947 if (!strcmp(type, "pixmap"))
948 return "share/pixmaps/";
949 if (!strcmp(type, "apps"))
950 return "share/applnk/";
951 if (!strcmp(type, "sound"))
952 return "share/sounds/";
953 if (!strcmp(type, "locale"))
954 return "share/locale/";
955 if (!strcmp(type, "services"))
956 return "share/services/";
957 if (!strcmp(type, "servicetypes"))
958 return "share/servicetypes/";
959 if (!strcmp(type, "mime"))
960 return "share/mimelnk/";
961 if (!strcmp(type, "cgi"))
962 return "cgi-bin/";
963 if (!strcmp(type, "wallpaper"))
964 return "share/wallpapers/";
965 if (!strcmp(type, "templates"))
966 return "share/templates/";
967 if (!strcmp(type, "exe"))
968 return "bin/";
969 if (!strcmp(type, "lib"))
970 return "lib/";
971 if (!strcmp(type, "module"))
972 return "lib/kde3/";
973 if (!strcmp(type, "qtplugins"))
974 return "lib/kde3/plugins";
975 if (!strcmp(type, "xdgdata-apps"))
976 return "applications/";
977 if (!strcmp(type, "xdgdata-dirs"))
978 return "desktop-directories/";
979 if (!strcmp(type, "xdgconf-menu"))
980 return "menus/";
981 qFatal("unknown resource type %s", type);
982 return QString::null;
983}
984
985QString KStandardDirs::saveLocation(const char *type,
986 const QString& suffix,
987 bool create) const
988{
989 //qDebug("KStandardDirs::saveLocation called %s %s", type,suffix.latin1() );
990 //return "";
991 checkConfig();
992
993 QString *pPath = savelocations.find(type);
994 if (!pPath)
995 {
996 QStringList *dirs = relatives.find(type);
997 if (!dirs && (
998 (strcmp(type, "socket") == 0) ||
999 (strcmp(type, "tmp") == 0) ||
1000 (strcmp(type, "cache") == 0) ))
1001 {
1002 (void) resourceDirs(type); // Generate socket|tmp|cache resource.
1003 dirs = relatives.find(type); // Search again.
1004 }
1005 if (dirs)
1006 {
1007 // Check for existance of typed directory + suffix
1008 if (strncmp(type, "xdgdata-", 8) == 0)
1009 pPath = new QString(realPath(localxdgdatadir() + dirs->last()));
1010 else if (strncmp(type, "xdgconf-", 8) == 0)
1011 pPath = new QString(realPath(localxdgconfdir() + dirs->last()));
1012 else
1013 pPath = new QString(realPath(localkdedir() + dirs->last()));
1014 }
1015 else {
1016 dirs = absolutes.find(type);
1017 if (!dirs)
1018 qFatal("KStandardDirs: The resource type %s is not registered", type);
1019 pPath = new QString(realPath(dirs->last()));
1020 }
1021
1022 savelocations.insert(type, pPath);
1023 }
1024
1025 QString fullPath = *pPath + suffix;
1026//US struct stat st;
1027//US if (stat(QFile::encodeName(fullPath), &st) != 0 || !(S_ISDIR(st.st_mode)))
1028 QFileInfo fullPathInfo(QFile::encodeName(fullPath));
1029 if (fullPathInfo.isReadable() || !fullPathInfo.isDir())
1030
1031
1032 {
1033 if(!create) {
1034#ifndef NDEBUG
1035 qDebug("save location %s doesn't exist", fullPath.latin1());
1036#endif
1037 return fullPath;
1038 }
1039 if(!makeDir(fullPath, 0700)) {
1040 qWarning("failed to create %s", fullPath.latin1());
1041 return fullPath;
1042 }
1043 dircache.remove(type);
1044 }
1045 return fullPath;
1046}
1047
1048QString KStandardDirs::relativeLocation(const char *type, const QString &absPath)
1049{
1050 QString fullPath = absPath;
1051 int i = absPath.findRev('/');
1052 if (i != -1)
1053 {
1054 fullPath = realPath(absPath.left(i+1))+absPath.mid(i+1); // Normalize
1055 }
1056
1057 QStringList candidates = resourceDirs(type);
1058
1059 for (QStringList::ConstIterator it = candidates.begin();
1060 it != candidates.end(); it++)
1061 if (fullPath.startsWith(*it))
1062 {
1063 return fullPath.mid((*it).length());
1064 }
1065
1066 return absPath;
1067}
1068
1069
1070bool KStandardDirs::makeDir(const QString& dir2, int mode)
1071{
1072 QString dir = QDir::convertSeparators( dir2 );
1073#if 0
1074 //LR
1075
1076 // we want an absolute path
1077 if (dir.at(0) != '/')
1078 return false;
1079
1080 QString target = dir;
1081 uint len = target.length();
1082
1083 // append trailing slash if missing
1084 if (dir.at(len - 1) != '/')
1085 target += '/';
1086
1087 QString base("");
1088 uint i = 1;
1089
1090 while( i < len )
1091 {
1092//US struct stat st;
1093 int pos = target.find('/', i);
1094 base += target.mid(i - 1, pos - i + 1);
1095 QCString baseEncoded = QFile::encodeName(base);
1096 // bail out if we encountered a problem
1097//US if (stat(baseEncoded, &st) != 0)
1098 QFileInfo baseEncodedInfo(baseEncoded);
1099 if (!baseEncodedInfo.exists())
1100 {
1101 // Directory does not exist....
1102 // Or maybe a dangling symlink ?
1103//US if (lstat(baseEncoded, &st) == 0)
1104 if (baseEncodedInfo.isSymLink()) {
1105//US (void)unlink(baseEncoded); // try removing
1106 QFile(baseEncoded).remove();
1107 }
1108
1109 //US if ( mkdir(baseEncoded, (mode_t) mode) != 0)
1110 QDir dirObj;
1111 if ( dirObj.mkdir(baseEncoded) != true )
1112 {
1113 //US perror("trying to create local folder");
1114 return false; // Couldn't create it :-(
1115 }
1116 }
1117 i = pos + 1;
1118 }
1119 return true;
1120#endif
1121
1122 // ********************************************
1123 // new code for WIN32
1124 QDir dirObj;
1125
1126
1127 // we want an absolute path
1128#ifndef _WIN32_
1129 if (dir.at(0) != '/')
1130 return false;
1131#endif
1132
1133 QString target = dir;
1134 uint len = target.length();
1135#ifndef _WIN32_
1136 // append trailing slash if missing
1137 if (dir.at(len - 1) != '/')
1138 target += '/';
1139#endif
1140
1141 QString base("");
1142 uint i = 1;
1143
1144 while( i < len )
1145 {
1146//US struct stat st;
1147#ifndef _WIN32_
1148 int pos = target.find('/', i);
1149#else
1150 int pos = target.find('\\', i);
1151#endif
1152 if ( pos < 0 )
1153 return true;
1154 base += target.mid(i - 1, pos - i + 1);
1155 //QMessageBox::information( 0,"cap111", base, 1 );
1156/*US
1157 QCString baseEncoded = QFile::encodeName(base);
1158 // bail out if we encountered a problem
1159 if (stat(baseEncoded, &st) != 0)
1160 {
1161 // Directory does not exist....
1162 // Or maybe a dangling symlink ?
1163 if (lstat(baseEncoded, &st) == 0)
1164 (void)unlink(baseEncoded); // try removing
1165
1166
1167 if ( mkdir(baseEncoded, (mode_t) mode) != 0) {
1168 perror("trying to create local folder");
1169 return false; // Couldn't create it :-(
1170 }
1171 }
1172*/
1173
1174 if (dirObj.exists(base) == false)
1175 {
1176 //qDebug("KStandardDirs::makeDir try to create : %s" , base.latin1());
1177 if (dirObj.mkdir(base) != true)
1178 {
1179 qDebug("KStandardDirs::makeDir could not create: %s" , base.latin1());
1180 return false;
1181 }
1182 }
1183
1184 i = pos + 1;
1185 }
1186 return true;
1187
1188}
1189
1190static QString readEnvPath(const char *env)
1191{
1192#ifdef _WIN32_
1193 return "";
1194#else
1195 QCString c_path = getenv(env);
1196 if (c_path.isEmpty())
1197 return QString::null;
1198 return QFile::decodeName(c_path);
1199#endif
1200}
1201
1202void KStandardDirs::addKDEDefaults()
1203{
1204 //qDebug("ERROR: KStandardDirs::addKDEDefaults() called ");
1205 //return;
1206 QStringList kdedirList;
1207
1208 // begin KDEDIRS
1209 QString kdedirs = readEnvPath("MICROKDEDIRS");
1210 if (!kdedirs.isEmpty())
1211 {
1212 tokenize(kdedirList, kdedirs, ":");
1213 }
1214 else
1215 {
1216 QString kdedir = readEnvPath("MICROKDEDIR");
1217 if (!kdedir.isEmpty())
1218 {
1219 kdedir = KShell::tildeExpand(kdedir);
1220 kdedirList.append(kdedir);
1221 }
1222 }
1223//US kdedirList.append(KDEDIR);
1224
1225#ifdef __KDE_EXECPREFIX
1226 QString execPrefix(__KDE_EXECPREFIX);
1227 if (execPrefix!="NONE")
1228 kdedirList.append(execPrefix);
1229#endif
1230
1231 QString localKdeDir;
1232
1233//US if (getuid())
1234 if (true)
1235 {
1236 localKdeDir = readEnvPath("MICROKDEHOME");
1237 if (!localKdeDir.isEmpty())
1238 {
1239 if (localKdeDir.at(localKdeDir.length()-1) != '/')
1240 localKdeDir += '/';
1241 }
1242 else
1243 {
1244 localKdeDir = QDir::homeDirPath() + "/kdepim/";
1245 }
1246 }
1247 else
1248 {
1249 // We treat root different to prevent root messing up the
1250 // file permissions in the users home directory.
1251 localKdeDir = readEnvPath("MICROKDEROOTHOME");
1252 if (!localKdeDir.isEmpty())
1253 {
1254 if (localKdeDir.at(localKdeDir.length()-1) != '/')
1255 localKdeDir += '/';
1256 }
1257 else
1258 {
1259//US struct passwd *pw = getpwuid(0);
1260//US localKdeDir = QFile::decodeName((pw && pw->pw_dir) ? pw->pw_dir : "/root") + "/.microkde/";
1261 qDebug("KStandardDirs::addKDEDefaults: 1 has to be fixed");
1262 }
1263
1264 }
1265
1266//US localKdeDir = appDir();
1267
1268//US
1269// qDebug("KStandardDirs::addKDEDefaults: localKdeDir=%s", localKdeDir.latin1());
1270 if (localKdeDir != "-/")
1271 {
1272 localKdeDir = KShell::tildeExpand(localKdeDir);
1273 addPrefix(localKdeDir);
1274 }
1275
1276 for (QStringList::ConstIterator it = kdedirList.begin();
1277 it != kdedirList.end(); it++)
1278 {
1279 QString dir = KShell::tildeExpand(*it);
1280 addPrefix(dir);
1281 }
1282 // end KDEDIRS
1283
1284 // begin XDG_CONFIG_XXX
1285 QStringList xdgdirList;
1286 QString xdgdirs = readEnvPath("XDG_CONFIG_DIRS");
1287 if (!xdgdirs.isEmpty())
1288 {
1289 tokenize(xdgdirList, xdgdirs, ":");
1290 }
1291 else
1292 {
1293 xdgdirList.clear();
1294 xdgdirList.append("/etc/xdg");
1295 }
1296
1297 QString localXdgDir = readEnvPath("XDG_CONFIG_HOME");
1298 if (!localXdgDir.isEmpty())
1299 {
1300 if (localXdgDir.at(localXdgDir.length()-1) != '/')
1301 localXdgDir += '/';
1302 }
1303 else
1304 {
1305//US if (getuid())
1306 if (true)
1307 {
1308 localXdgDir = QDir::homeDirPath() + "/.config/";
1309 }
1310 else
1311 {
1312//US struct passwd *pw = getpwuid(0);
1313//US localXdgDir = QFile::decodeName((pw && pw->pw_dir) ? pw->pw_dir : "/root") + "/.config/";
1314 qDebug("KStandardDirs::addKDEDefaults: 2 has to be fixed");
1315 }
1316 }
1317
1318 localXdgDir = KShell::tildeExpand(localXdgDir);
1319 addXdgConfigPrefix(localXdgDir);
1320
1321 for (QStringList::ConstIterator it = xdgdirList.begin();
1322 it != xdgdirList.end(); it++)
1323 {
1324 QString dir = KShell::tildeExpand(*it);
1325 addXdgConfigPrefix(dir);
1326 }
1327 // end XDG_CONFIG_XXX
1328
1329 // begin XDG_DATA_XXX
1330 xdgdirs = readEnvPath("XDG_DATA_DIRS");
1331 if (!xdgdirs.isEmpty())
1332 {
1333 tokenize(xdgdirList, xdgdirs, ":");
1334 }
1335 else
1336 {
1337 xdgdirList.clear();
1338 for (QStringList::ConstIterator it = kdedirList.begin();
1339 it != kdedirList.end(); it++)
1340 {
1341 QString dir = *it;
1342 if (dir.at(dir.length()-1) != '/')
1343 dir += '/';
1344 xdgdirList.append(dir+"share/");
1345 }
1346
1347 xdgdirList.append("/usr/local/share/");
1348 xdgdirList.append("/usr/share/");
1349 }
1350
1351 localXdgDir = readEnvPath("XDG_DATA_HOME");
1352 if (!localXdgDir.isEmpty())
1353 {
1354 if (localXdgDir.at(localXdgDir.length()-1) != '/')
1355 localXdgDir += '/';
1356 }
1357 else
1358 {
1359//US if (getuid())
1360 if (true)
1361 {
1362 localXdgDir = QDir::homeDirPath() + "/.local/share/";
1363 }
1364 else
1365 {
1366//US struct passwd *pw = getpwuid(0);
1367//US localXdgDir = QFile::decodeName((pw && pw->pw_dir) ? pw->pw_dir : "/root") + "/.local/share/";
1368 qDebug("KStandardDirs::addKDEDefaults: 3 has to be fixed");
1369 }
1370 }
1371
1372 localXdgDir = KShell::tildeExpand(localXdgDir);
1373 addXdgDataPrefix(localXdgDir);
1374
1375 for (QStringList::ConstIterator it = xdgdirList.begin();
1376 it != xdgdirList.end(); it++)
1377 {
1378 QString dir = KShell::tildeExpand(*it);
1379
1380 addXdgDataPrefix(dir);
1381 }
1382 // end XDG_DATA_XXX
1383
1384
1385 uint index = 0;
1386 while (types[index] != 0) {
1387 addResourceType(types[index], kde_default(types[index]));
1388 index++;
1389 }
1390
1391 addResourceDir("home", QDir::homeDirPath());
1392}
1393
1394void KStandardDirs::checkConfig() const
1395{
1396/*US
1397 if (!addedCustoms && KGlobal::_instance && KGlobal::_instance->_config)
1398 const_cast<KStandardDirs*>(this)->addCustomized(KGlobal::_instance->_config);
1399*/
1400 if (!addedCustoms && KGlobal::config())
1401 const_cast<KStandardDirs*>(this)->addCustomized(KGlobal::config());
1402}
1403
1404bool KStandardDirs::addCustomized(KConfig *config)
1405{
1406 if (addedCustoms) // there are already customized entries
1407 return false; // we just quite and hope they are the right ones
1408
1409 // save the numbers of config directories. If this changes,
1410 // we will return true to give KConfig a chance to reparse
1411 uint configdirs = resourceDirs("config").count();
1412
1413 // reading the prefixes in
1414 QString oldGroup = config->group();
1415 config->setGroup("Directories");
1416
1417 QStringList list;
1418 QStringList::ConstIterator it;
1419 list = config->readListEntry("prefixes");
1420 for (it = list.begin(); it != list.end(); it++)
1421 addPrefix(*it);
1422
1423 // iterating over all entries in the group Directories
1424 // to find entries that start with dir_$type
1425/*US
1426 QMap<QString, QString> entries = config->entryMap("Directories");
1427
1428 QMap<QString, QString>::ConstIterator it2;
1429 for (it2 = entries.begin(); it2 != entries.end(); it2++)
1430 {
1431 QString key = it2.key();
1432 if (key.left(4) == "dir_") {
1433 // generate directory list, there may be more than 1.
1434 QStringList dirs = QStringList::split(',', *it2);
1435 QStringList::Iterator sIt(dirs.begin());
1436 QString resType = key.mid(4, key.length());
1437 for (; sIt != dirs.end(); ++sIt) {
1438 addResourceDir(resType.latin1(), *sIt);
1439 }
1440 }
1441 }
1442
1443 // Process KIOSK restrictions.
1444 config->setGroup("KDE Resource Restrictions");
1445 entries = config->entryMap("KDE Resource Restrictions");
1446 for (it2 = entries.begin(); it2 != entries.end(); it2++)
1447 {
1448 QString key = it2.key();
1449 if (!config->readBoolEntry(key, true))
1450 {
1451 d->restrictionsActive = true;
1452 d->restrictions.insert(key.latin1(), &d->restrictionsActive); // Anything will do
1453 dircache.remove(key.latin1());
1454 }
1455 }
1456*/
1457 // save it for future calls - that will return
1458 addedCustoms = true;
1459 config->setGroup(oldGroup);
1460
1461 // return true if the number of config dirs changed
1462 return (resourceDirs("config").count() != configdirs);
1463}
1464
1465QString KStandardDirs::localkdedir() const
1466{
1467 // Return the prefix to use for saving
1468 return prefixes.first();
1469}
1470
1471QString KStandardDirs::localxdgdatadir() const
1472{
1473 // Return the prefix to use for saving
1474 return d->xdgdata_prefixes.first();
1475}
1476
1477QString KStandardDirs::localxdgconfdir() const
1478{
1479 // Return the prefix to use for saving
1480 return d->xdgconf_prefixes.first();
1481}
1482
1483void KStandardDirs::setAppDir( const QString &appDir )
1484{
1485 mAppDir = appDir;
1486
1487 if ( mAppDir.right( 1 ) != "/" )
1488 mAppDir += "/";
1489}
1490
1491QString KStandardDirs::appDir()
1492{
1493 return mAppDir;
1494}
1495
1496// just to make code more readable without macros
1497QString locate( const char *type,
1498 const QString& filename/*US , const KInstance* inst*/ )
1499{
1500//US return inst->dirs()->findResource(type, filename);
1501 return KGlobal::dirs()->findResource(type, filename);
1502}
1503
1504QString locateLocal( const char *type,
1505 const QString& filename/*US , const KInstance* inst*/ )
1506{
1507
1508 QString path = locateLocal(type, filename, true /*US, inst*/);
1509
1510
1511/*
1512 static int ccc = 0;
1513 ++ccc;
1514 if ( ccc > 13 )
1515 abort();
1516*/
1517 qDebug("locatelocal: %s" , path.latin1());
1518 return path;
1519
1520/*US why do we put all files into one directory. It is quit complicated.
1521why not staying with the original directorystructure ?
1522
1523
1524 QString escapedFilename = filename;
1525 escapedFilename.replace( QRegExp( "/" ), "_" );
1526
1527 QString path = KStandardDirs::appDir() + type + "_" + escapedFilename;
1528
1529 kdDebug() << "locate: '" << path << "'" << endl;
1530 qDebug("locate: %s" , path.latin1());
1531 return path;
1532*/
1533//US so my proposal is this:
1534
1535// QString escapedFilename = filename;
1536// escapedFilename.replace( QRegExp( "/" ), "_" );
1537
1538#if 0
1539#ifdef _WIN32_
1540 QString path = QDir::convertSeparators(KStandardDirs::appDir() + type + "/" + filename);
1541#else
1542 QString path = KStandardDirs::appDir() + type + "/" + filename;
1543#endif
1544
1545 //US Create the containing dir if needed
1546 QFileInfo fi ( path );
1547
1548 // QString dir=pathurl.directory();
1549 //QMessageBox::information( 0,"path", path, 1 );
1550
1551#ifdef _WIN32_
1552 KStandardDirs::makeDir(path);
1553#else
1554 KStandardDirs::makeDir(fi.dirPath( true ));
1555#endif
1556
1557 qDebug("locate22: %s" , path.latin1());
1558 return path;
1559
1560#endif
1561
1562}
1563
1564QString locateLocal( const char *type,
1565 const QString& filename, bool createDir/*US , const KInstance* inst*/ )
1566{
1567 // try to find slashes. If there are some, we have to
1568 // create the subdir first
1569 int slash = filename.findRev('/')+1;
1570 if (!slash) // only one filename
1571 //USreturn inst->dirs()->saveLocation(type, QString::null, createDir) + filename;
1572 return KGlobal::dirs()->saveLocation(type, QString::null, createDir) + filename;
1573
1574 // split path from filename
1575 QString dir = filename.left(slash);
1576 QString file = filename.mid(slash);
1577//US return inst->dirs()->saveLocation(type, dir, createDir) + file;
1578 return KGlobal::dirs()->saveLocation(type, dir, createDir) + file;
1579
1580 // ***************************************************************
1581#if 0
1582
1583/*US why do we put all files into one directory. It is quit complicated.
1584why not staying with the original directorystructure ?
1585
1586
1587 QString escapedFilename = filename;
1588 escapedFilename.replace( QRegExp( "/" ), "_" );
1589
1590 QString path = KStandardDirs::appDir() + type + "_" + escapedFilename;
1591
1592 kdDebug() << "locate: '" << path << "'" << endl;
1593 qDebug("locate: %s" , path.latin1());
1594 return path;
1595*/
1596//US so my proposal is this:
1597
1598// QString escapedFilename = filename;
1599// escapedFilename.replace( QRegExp( "/" ), "_" );
1600
1601#ifdef _WIN32_
1602 QString path = QDir::convertSeparators(KStandardDirs::appDir() + type + "/" + filename);
1603#else
1604 QString path = KStandardDirs::appDir() + type + "/" + filename;
1605#endif
1606
1607 //US Create the containing dir if needed
1608 KURL pathurl;
1609 pathurl.setPath(path);
1610 QString dir=pathurl.directory();
1611 //QMessageBox::information( 0,"path", path, 1 );
1612#ifdef _WIN32_
1613 KStandardDirs::makeDir(path);
1614#else
1615 KStandardDirs::makeDir(dir);
1616#endif
1617
1618 return path;
1619#endif
1620}