/* From WebMaker - KDE HTML Editor Copyright (C) 1998, 1999 Alexei Dets Rewritten for Quanta Plus: (C) 2002 Andras Mantia 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. */ //qt includes #include #include #include #include #include #include //kde includes #include #include #include #include #include #include #include #include //app includes #include "qextfileinfo.h" TQString QExtFileInfo::lastErrorMsg = ""; TQString QExtFileInfo::canonicalPath(const TQString& path) { if (!path.startsWith("/") || path == "/") return path; bool endsWithSlash = path.endsWith("/"); TQDir dir(path); if (dir.exists() || TQFileInfo(path).exists()) { TQString s = dir.canonicalPath(); if (endsWithSlash) s.append("/"); return s; } else { KURL u = KURL::fromPathOrURL(path).upURL(); TQString s = u.path(-1) + "/"; if (s == "//") s = "/"; TQString s2 = path.mid(s.length()); s2 = QExtFileInfo::canonicalPath(s) + s2; return s2; } } TQString QExtFileInfo::homeDirPath() { return TQDir(TQDir::homeDirPath()).canonicalPath(); } /** create a relative short url based in baseURL*/ KURL QExtFileInfo::toRelative(const KURL& _urlToConvert,const KURL& _baseURL, bool resolveSymlinks) { KURL urlToConvert = _urlToConvert; KURL baseURL = _baseURL; KURL resultURL = urlToConvert; if (urlToConvert.protocol() == baseURL.protocol()) { if (urlToConvert.isLocalFile()) { TQString path; if (resolveSymlinks) path = QExtFileInfo::canonicalPath(urlToConvert.path()); else path = urlToConvert.path(); if (!path.isEmpty()) urlToConvert.setPath(path); if (resolveSymlinks) path = QExtFileInfo::canonicalPath(baseURL.path()); else path = baseURL.path(); if (!path.isEmpty()) baseURL.setPath(path); } TQString path = urlToConvert.path(); TQString basePath = baseURL.path(1); if (path.startsWith("/")) { path.remove(0, 1); basePath.remove(0, 1); if ( basePath.right(1) != "/" ) basePath.append("/"); int pos=0; int pos1=0; for (;;) { pos=path.find("/"); pos1=basePath.find("/"); if ( pos<0 || pos1<0 ) break; if ( path.left(pos+1 ) == basePath.left(pos1+1) ) { path.remove(0, pos+1); basePath.remove(0, pos1+1); } else break; }; if ( basePath == "/" ) basePath=""; int level = basePath.contains("/"); for (int i=0; i=0 ) { cutname.remove( 0, pos+3 ); cutdir.remove( cutdir.length()-1, 1 ); cutdir.remove( cutdir.findRev('/')+1 , 1000); } resultURL.setPath(TQDir::cleanDirPath(cutdir+cutname)); } if (urlToConvert.path().endsWith("/")) resultURL.adjustPath(1); return resultURL; } /** All files in a dir. The return will also contain the name of the subdirectories. This is needed for empty directory adding/handling. (Andras) Currently works only for local directories */ KURL::List QExtFileInfo::allFiles( const KURL& path, const TQString& mask, TQWidget *window) { QExtFileInfo internalFileInfo; return internalFileInfo.allFilesInternal(path, mask, window); } KURL::List QExtFileInfo::allFilesRelative( const KURL& path, const TQString& mask, TQWidget *window, bool resolveSymlinks) { QExtFileInfo internalFileInfo; KURL::List r = internalFileInfo.allFilesInternal(path, mask, window); KURL::List::Iterator it; for ( it = r.begin(); it != r.end(); ++it ) { *it = QExtFileInfo::toRelative( *it, path, resolveSymlinks ); } return r; } TQDict QExtFileInfo::allFilesDetailed(const KURL& path, const TQString& mask, TQWidget *window) { QExtFileInfo internalFileInfo; return internalFileInfo.allFilesDetailedInternal(path, mask, window); } bool QExtFileInfo::createDir(const KURL& path, TQWidget *window) { int i = 0; bool result; KURL dir3; KURL dir2; KURL dir1 = path; dir1.setPath("/"); if (!exists(dir1, false, window) && path.protocol() != "webdav" ) { return false; //the root is not accessible, possible wrong username/password supplied } while (!exists(path, false, window) && dir2.path() != path.path()) { dir1 = path; dir2 = path; dir1=cdUp(dir1); while (!exists(dir1, false, window) && dir1.path() != "/") { dir1 = cdUp(dir1); dir2 = cdUp(dir2); // debug(d1); } dir3 = dir2; dir3.adjustPath(-1); //some servers refuse to create directories ending with a slash result = TDEIO::NetAccess::mkdir(dir3, window); if (dir2.path() == "/" || !result) break; i++; } result = exists(path, false, window); return result; } KURL QExtFileInfo::cdUp(const KURL &url) { KURL u = url; TQString dir = u.path(-1); while ( !dir.isEmpty() && dir.right(1) != "/" ) { dir.remove( dir.length()-1,1); } u.setPath(dir); return u; } TQString QExtFileInfo::shortName(const TQString &fname) { return fname.section("/", -1); } KURL QExtFileInfo::path( const KURL &url ) { KURL result = url; result.setPath(result.directory(false,false)); return result; } KURL QExtFileInfo::home() { KURL url; url.setPath(TQDir::currentDirPath()+"/"); return url; } bool QExtFileInfo::exists(const KURL& a_url, bool readingOnly, TQWidget *window) { // Andras: Don't use it now, as it brings up an extra dialog and need manual // intervention when usign fish // return TDEIO::NetAccess::exists(a_url, false); // No dialog when stating. if (a_url.isLocalFile()) { return TQFile::exists(a_url.path()); } else { QExtFileInfo internalFileInfo; return internalFileInfo.internalExists(a_url, readingOnly, window); } } /* Synchronous copy, like NetAccess::file_copy in KDE 3.2 */ bool QExtFileInfo::copy( const KURL& src, const KURL& target, int permissions, bool overwrite, bool resume, TQWidget* window ) { QExtFileInfo internalFileInfo; return internalFileInfo.internalCopy( src, target, permissions, overwrite, resume, window ); } /** No descriptions */ KURL::List QExtFileInfo::allFilesInternal(const KURL& startURL, const TQString& mask, TQWidget *window) { if (startURL.isLocalFile()) return allLocalFiles(startURL.path(-1), mask); dirListItems.clear(); if (internalExists(startURL, true, window)) { lstFilters.setAutoDelete(true); lstFilters.clear(); // Split on white space TQStringList list = TQStringList::split( ' ', mask ); for ( TQStringList::Iterator it = list.begin(); it != list.end(); ++it ) lstFilters.append( new TQRegExp(*it, false, true ) ); bJobOK = true; TDEIO::ListJob *job = TDEIO::listRecursive(startURL, false, true); job->setWindow(window); m_listJobCount = 1; connect(job, TQT_SIGNAL(entries(TDEIO::Job *, const TDEIO::UDSEntryList&)), this, TQT_SLOT(slotNewEntries(TDEIO::Job *, const TDEIO::UDSEntryList&))); connect( job, TQT_SIGNAL( result (TDEIO::Job *) ), this, TQT_SLOT( slotListResult (TDEIO::Job *) ) ); m_listStartURL = startURL.url(); //kdDebug(24000) << "Now listing: " << startURL.url() << endl; enter_loop(); //kdDebug(24000) << "Listing done: " << startURL.url() << endl; lstFilters.clear(); if (!bJobOK) { // kdDebug(24000) << "Error while listing "<< startURL.url() << endl; dirListItems.clear(); } } return dirListItems; } /** No descriptions */ TQDict QExtFileInfo::allFilesDetailedInternal(const KURL& startURL, const TQString& mask, TQWidget *window) { detailedDirListItems.setAutoDelete(true); detailedDirListItems.clear(); detailedDirListItems.setAutoDelete(false); if (internalExists(startURL, true, window)) { lstFilters.setAutoDelete(true); lstFilters.clear(); // Split on white space TQStringList list = TQStringList::split( ' ', mask ); for ( TQStringList::Iterator it = list.begin(); it != list.end(); ++it ) lstFilters.append( new TQRegExp(*it, false, true ) ); bJobOK = true; TDEIO::ListJob *job = TDEIO::listRecursive(startURL, false, true); job->setWindow(window); m_listJobCount = 1; connect(job, TQT_SIGNAL(entries(TDEIO::Job *, const TDEIO::UDSEntryList&)), this, TQT_SLOT(slotNewDetailedEntries(TDEIO::Job *, const TDEIO::UDSEntryList&))); connect( job, TQT_SIGNAL( result (TDEIO::Job *) ), this, TQT_SLOT( slotListResult (TDEIO::Job *) ) ); m_listStartURL = startURL.url(); //kdDebug(24000) << "Now listing: " << startURL.url() << endl; enter_loop(); //kdDebug(24000) << "Listing done: " << startURL.url() << endl; lstFilters.clear(); if (!bJobOK) { // kdDebug(24000) << "Error while listing "<< startURL.url() << endl; detailedDirListItems.clear(); } } return detailedDirListItems; } KURL::List QExtFileInfo::allLocalFiles(const TQString& startPath, const TQString& mask) { KURL::List list; TQDir d(startPath, mask); TQStringList l = d.entryList(); TQStringList::ConstIterator end = l.constEnd(); TQString path; for (TQStringList::ConstIterator it = l.constBegin(); it != end; ++it) { path = *it; if (path != "." && path != "..") { path = startPath + "/" + path; if (TQFileInfo(path).isDir()) path.append("/"); list.append(KURL::fromPathOrURL(path)); } } l = d.entryList("*", TQDir::Dirs); end = l.constEnd(); for (TQStringList::ConstIterator it = l.constBegin(); it != end; ++it) { if ((*it) != "." && (*it) != "..") list += allLocalFiles(startPath + "/" + (*it), mask); } return list; } //Some hackery from TDEIO::NetAccess as they do not do exactly what we want /* return true if the url exists*/ bool QExtFileInfo::internalExists(const KURL& url, bool readingOnly, TQWidget *window) { bJobOK = true; KURL url2 = url; url2.adjustPath(-1); // kdDebug(24000)<<"QExtFileInfo::internalExists"<setWindow(window); job->setDetails(0); job->setSide(readingOnly); connect( job, TQT_SIGNAL( result (TDEIO::Job *) ), this, TQT_SLOT( slotResult (TDEIO::Job *) ) ); //To avoid lock-ups, start a timer. TQTimer::singleShot(60*1000, this,TQT_SLOT(slotTimeout())); //kdDebug(24000)<<"QExtFileInfo::internalExists:before enter_loop"<setWindow (window); //connect( job2, TQT_SIGNAL( result (TDEIO::Job *) ), // this, TQT_SLOT( slotResult (TDEIO::Job *) ) ); //enter_loop(); //if (bJobOK) { // kdDebug(24000) << "Copying " << src << " to " << target << endl; // TDEIO::Job *job = TDEIO::copy( src, target, false ); job->setWindow (window); connect( job, TQT_SIGNAL( result (TDEIO::Job *) ), this, TQT_SLOT( slotResult (TDEIO::Job *) ) ); enter_loop(); } return bJobOK; } void tqt_enter_modal( TQWidget *widget ); void tqt_leave_modal( TQWidget *widget ); void QExtFileInfo::enter_loop() { TQWidget dummy(0,0,WType_Dialog | WShowModal); dummy.setFocusPolicy( TQ_NoFocus ); tqt_enter_modal(&dummy); //kdDebug(24000)<<"QExtFileInfo::enter_loop:before tqApp->enter_loop()"<< endl; tqApp->enter_loop(); // kdDebug(24000)<<"QExtFileInfo::enter_loop:after tqApp->enter_loop()"<error(); if ( !bJobOK ) { if ( !lastErrorMsg ) lastErrorMsg = job->errorString(); } if ( job->isA("TDEIO::StatJob") ) m_entry = static_cast(job)->statResult(); tqApp->exit_loop(); } void QExtFileInfo::slotNewEntries(TDEIO::Job *job, const TDEIO::UDSEntryList& udsList) { KURL url = static_cast(job)->url(); url.adjustPath(-1); // avoid creating these TQStrings again and again static const TQString& dot = TDEGlobal::staticQString("."); static const TQString& dotdot = TDEGlobal::staticQString(".."); TDEIO::UDSEntryListConstIterator it = udsList.begin(); TDEIO::UDSEntryListConstIterator end = udsList.end(); KURL itemURL; TQPtrList linkItems; linkItems.setAutoDelete(true); for ( ; it != end; ++it ) { TQString name; // find out about the name TDEIO::UDSEntry::ConstIterator entit = (*it).begin(); for( ; entit != (*it).end(); ++entit ) if ((*entit).m_uds == TDEIO::UDS_NAME) { name = (*entit).m_str; break; } if (!name.isEmpty() && name != dot && name != dotdot) { KFileItem* item = new KFileItem( *it, url, false, true ); if (item->isDir() && item->isLink()) { KURL u = item->url(); TQString linkDest = item->linkDest(); kdDebug(24000) << "Got link: " << name << " Points to:" << linkDest << endl; if (linkDest.startsWith("./") || linkDest.startsWith("../") ) { u.setPath(u.directory(false, true) + linkDest); u.cleanPath(); } else u.setPath(linkDest); u.adjustPath(+1); if (!dirListItems.contains(u) && u.url() != m_listStartURL && !u.isParentOf(item->url())) { linkItems.append(new KFileItem(*item)); } else { kdDebug(24000) << "Recursive link " << u.url() << endl; continue; } } itemURL = item->url(); if (item->isDir()) itemURL.adjustPath(1); for (TQPtrListIterator filterIt(lstFilters); filterIt.current(); ++filterIt ) { if (filterIt.current()->exactMatch(item->text())) dirListItems.append(itemURL); } delete item; } } for (TQPtrList::ConstIterator it = linkItems.constBegin(); it != linkItems.constEnd(); ++it) { TDEIO::ListJob *ljob = TDEIO::listRecursive((*it)->url(), false, true); m_listJobCount++; //kdDebug(24000) << "Now listing: " << (*it)->url() << endl; connect( ljob, TQT_SIGNAL(entries(TDEIO::Job *,const TDEIO::UDSEntryList &)), this,TQT_SLOT (slotNewEntries(TDEIO::Job *,const TDEIO::UDSEntryList &))); connect( ljob, TQT_SIGNAL(result(TDEIO::Job *)), this,TQT_SLOT (slotListResult(TDEIO::Job *))); } } void QExtFileInfo::slotNewDetailedEntries(TDEIO::Job *job, const TDEIO::UDSEntryList& udsList) { KURL url = static_cast(job)->url(); url.adjustPath(-1); // avoid creating these TQStrings again and again static const TQString& dot = TDEGlobal::staticQString("."); static const TQString& dotdot = TDEGlobal::staticQString(".."); TDEIO::UDSEntryListConstIterator it = udsList.begin(); TDEIO::UDSEntryListConstIterator end = udsList.end(); KURL itemURL; TQPtrList linkItems; linkItems.setAutoDelete(true); for ( ; it != end; ++it ) { TQString name; // find out about the name TDEIO::UDSEntry::ConstIterator entit = (*it).begin(); for( ; entit != (*it).end(); ++entit ) if ((*entit).m_uds == TDEIO::UDS_NAME) { name = (*entit).m_str; break; } if (!name.isEmpty() && name != dot && name != dotdot) { KFileItem *item= new KFileItem(*it, url, false, true ); if (item->isDir() && item->isLink()) { KURL u = item->url(); u.setPath(item->linkDest()); TQString urlStr = u.url(); if (detailedDirListItems.find(urlStr) == 0L && (urlStr != m_listStartURL)) { linkItems.append(new KFileItem(*item)); } else { kdDebug(24000) << "Recursive link" << item->url() << endl; continue; } } bool added = false; for (TQPtrListIterator filterIt( lstFilters ); filterIt.current(); ++filterIt) if (filterIt.current()->exactMatch(item->text())) { detailedDirListItems.insert(item->url().url(), item); added = true; } if (!added) delete item; } } for (TQPtrList::ConstIterator it = linkItems.constBegin(); it != linkItems.constEnd(); ++it) { TDEIO::ListJob *ljob = TDEIO::listRecursive((*it)->url(), false, true); m_listJobCount++; // kdDebug(24000) << "Now listing: " << (*it)->url() << endl; connect( ljob, TQT_SIGNAL(entries(TDEIO::Job *,const TDEIO::UDSEntryList &)), this,TQT_SLOT (slotNewDetailedEntries(TDEIO::Job *,const TDEIO::UDSEntryList &))); connect( ljob, TQT_SIGNAL(result(TDEIO::Job *)), this,TQT_SLOT (slotListResult(TDEIO::Job *))); } } /** Timeout occurred while waiting for some network function to return. */ void QExtFileInfo::slotTimeout() { bJobOK = false; tqApp->exit_loop(); } #include "qextfileinfo.moc"