/*************************************************************************** * Copyright (C) 2005-2006 Nicolas Hadacek * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include "purl.h" #include #include #include #include #include # include #include "common/common/synchronous.h" #include "process.h" #if !defined(NO_KDE) # include # include # include #endif //----------------------------------------------------------------------------- PURL::Http::Http(const TQString &hostname) : TQHttp(hostname) { connect(this, TQT_SIGNAL(responseHeaderReceived(const TQHttpResponseHeader &)), TQT_SLOT(responseHeaderReceivedSlot(const TQHttpResponseHeader &))); } //----------------------------------------------------------------------------- class PURL::Private { public: TQString convertWindowsFilepath(const TQString &filepath); private: TQMap _winDrives; // drive -> unix path TQMap _winPaths; // windows path -> unix path TQString getWindowsDrivePath(char drive); bool checkCachedPath(TQString &filepath) const; TQString cachePath(const TQString &origin, const TQString &filepath); TQString convertWindowsShortFilepath(const TQString &filepath); TQString findName(const TQString &path, const TQString &name); static TQString findName(const TQString &filepath); }; TQString PURL::Private::getWindowsDrivePath(char drive) { #if defined(Q_OS_UNIX) if ( !_winDrives.tqcontains(drive) ) { TQStringList args; args += "-u"; TQString s; s += drive; args += s + ":\\"; ::Process::StringOutput process; process.setup("winepath", args, false); ::Process::State state = ::Process::runSynchronously(process, ::Process::Start, 3000); if ( state!=::Process::Exited ) qWarning("Error running \"winepath\" with \"%s\" (%i)", args.join(" ").latin1(), state); s = process.sout() + process.serr(); TQDir dir(s.stripWhiteSpace()); _winDrives[drive] = dir.canonicalPath(); } return _winDrives[drive]; #else return TQString("%1:\\").tqarg(drive); #endif } bool PURL::Private::checkCachedPath(TQString &filepath) const { if ( !_winPaths.tqcontains(filepath) ) return false; filepath = _winPaths[filepath]; return true; } TQString PURL::Private::cachePath(const TQString &origin, const TQString &filepath) { _winPaths[origin] = filepath; return filepath; } TQString PURL::Private::convertWindowsFilepath(const TQString &filepath) { // appears to be an absolute windows path if ( filepath[0]=='\\' ) { TQString tmp = filepath; if ( checkCachedPath(tmp) ) return tmp; return cachePath(filepath, convertWindowsShortFilepath(tmp.tqreplace('\\', "/"))); } // appears to be a windows path with a drive if ( (filepath.length()>=2 && filepath[0].isLetter() && filepath[1]==':') ) { TQString tmp = filepath; if ( checkCachedPath(tmp) ) return tmp; tmp = getWindowsDrivePath(filepath[0]) + tmp.mid(2).tqreplace('\\', "/"); return cachePath(filepath, convertWindowsShortFilepath(tmp)); } return filepath; } TQString PURL::Private::findName(const TQString &path, const TQString &name) { TQString filepath = path + '/' + name; if ( checkCachedPath(filepath) ) return filepath; return cachePath(filepath, findName(filepath)); } TQString PURL::Private::findName(const TQString &filepath) { TQFileInfo finfo(filepath); if ( finfo.exists() || !finfo.dir().exists() ) return finfo.filePath(); TQStringList list = finfo.dir().entryList(TQDir::All, TQDir::Name); // find if name is just in a different case for (uint j=0; jconvertWindowsFilepath(filepath); #else TQString tmp = filepath; #endif if ( tmp.startsWith("~") ) tmp = TQDir::homeDirPath() + tmp.mid(1); _relative = Q3Url::isRelativeUrl(tmp); #if defined(Q_OS_UNIX) if ( !tmp.startsWith("/") ) tmp = '/' + tmp; #endif #if defined(NO_KDE) _url.setPath(tmp); #else _url = KURL::fromPathOrURL(tmp); #endif _url.cleanPath(); } } PURL::Base::Base(const KURL &url) : _relative(false), _url(url) { _url.cleanPath(); } bool PURL::Base::isLocal() const { return ( _url.protocol().isEmpty() || _url.protocol()=="file" ); } bool PURL::Base::operator ==(const Base &url) const { if ( _url.isEmpty() ) return url._url.isEmpty(); return _url==url._url; } TQString PURL::Base::path(SeparatorType type) const { #if defined(NO_KDE) TQString s = _url.dirPath(); if ( !s.isEmpty() && !s.endsWith("/") ) s += '/'; #else TQString s = _url.directory(false, false); #endif if ( type==WindowsSeparator ) { for (uint i=0; imainWidget()) ) return false; KFileItem item(uds, _url); lastModified->setTime_t(item.time(KIO::UDS_MODIFICATION_TIME)); return true; } else { // assume file exists if ioslave cannot tell... return KIO::NetAccess::exists(_url, true, tqApp->mainWidget()); } #else if (lastModified) lastModified->setTime_t(0); // assume file exists return true; #endif } //---------------------------------------------------------------------------- PURL::Url PURL::Url::fromPathOrUrl(const TQString &s) { KURL kurl = KURL::fromPathOrURL(s); if ( !kurl.protocol().isEmpty() && kurl.protocol()!="file" && kurl.protocol().length()!=1 ) return kurl; return Url(s.startsWith("file://") ? s.mid(7) : s); } PURL::Url::Url(const Directory &dir, const TQString &filename, FileType type) : Base(dir.path() + '/' + addExtension(filename, type)) {} PURL::Url::Url(const Directory &dir, const TQString &filepath) : Base(dir.path() + '/' + filepath) {} PURL::FileType PURL::Url::fileType() const { TQFileInfo info(filename()); FOR_EACH(FileType, type) for (uint i=0; type.data().extensions[i]; i++) if ( info.extension(false).lower()==type.data().extensions[i] ) return type; return Unknown; } TQString PURL::Url::basename() const { TQFileInfo info(_url.fileName(false)); return info.baseName(true); } TQString PURL::Url::filename() const { TQFileInfo info(_url.fileName(false)); return info.fileName(); } TQString PURL::Url::filepath(SeparatorType type) const { return path(type) + filename(); } PURL::Url PURL::Url::toExtension(const TQString &extension) const { TQFileInfo info(filename()); return Url(directory().path() + info.baseName(true) + '.' + extension); } PURL::Url PURL::Url::appendExtension(const TQString &extension) const { TQFileInfo info(filename()); return Url(directory().path() + info.fileName() + '.' + extension); } TQString PURL::Url::relativeTo(const Directory &dir, SeparatorType type) const { TQString s = filepath(type); if ( !isInto(dir) ) return s; return s.right(s.length() - dir.path(type).length()); } PURL::Url PURL::Url::toAbsolute(const Directory &dir) const { if ( isRelative() ) return Url(dir, filepath()); return *this; } bool PURL::findExistingUrl(Url &url) { if ( url.exists() ) return true; TQFileInfo info(url.filename()); Url tmp = url.toExtension(info.extension(false).upper()); if ( !tmp.exists() ) { tmp = url.toExtension(info.extension(false).lower()); if ( !tmp.exists() ) return false; } url = tmp; return true; } //----------------------------------------------------------------------------- #if !defined(NO_KDE) PURL::UrlList::UrlList(const KURL::List &list) { KURL::List::const_iterator it; for (it=list.begin(); it!=list.end(); ++it) append(*it); } #endif //----------------------------------------------------------------------------- PURL::Directory::Directory(const TQString &path) : Base(path.isEmpty() ? TQString() : path + '/') {} PURL::Directory PURL::Directory::up() const { TQDir dir(path()); dir.cdUp(); return PURL::Directory(dir.path()); } PURL::Directory PURL::Directory::down(const TQString &subPath) const { Q_ASSERT( TQDir::isRelativePath(subPath) ); TQDir dir(path()); dir.cd(subPath); return PURL::Directory(dir.path()); } TQStringList PURL::Directory::files(const TQString &filter) const { TQDir dir(path()); return dir.entryList(filter, TQDir::Files); } PURL::Url PURL::Directory::findMatchingFilename(const TQString &filename) const { TQDir dir(path()); TQStringList files = dir.entryList(TQDir::Files); for (uint i=0; i