summaryrefslogtreecommitdiffstats
path: root/lib/qextfileinfo.cpp
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commite9ae80694875f869892f13f4fcaf1170a00dea41 (patch)
treeaa2f8d8a217e2d376224c8d46b7397b68d35de2d /lib/qextfileinfo.cpp
downloadtdewebdev-e9ae80694875f869892f13f4fcaf1170a00dea41.tar.gz
tdewebdev-e9ae80694875f869892f13f4fcaf1170a00dea41.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdewebdev@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'lib/qextfileinfo.cpp')
-rw-r--r--lib/qextfileinfo.cpp619
1 files changed, 619 insertions, 0 deletions
diff --git a/lib/qextfileinfo.cpp b/lib/qextfileinfo.cpp
new file mode 100644
index 00000000..b7c7e741
--- /dev/null
+++ b/lib/qextfileinfo.cpp
@@ -0,0 +1,619 @@
+/*
+ From WebMaker - KDE HTML Editor
+ Copyright (C) 1998, 1999 Alexei Dets <dets@services.ru>
+
+ Rewritten for Quanta Plus: (C) 2002 Andras Mantia <amantia@kde.org>
+
+ 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 <qdir.h>
+#include <qapplication.h>
+#include <qptrlist.h>
+#include <qstringlist.h>
+#include <qregexp.h>
+#include <qtimer.h>
+
+//kde includes
+#include <kurl.h>
+#include <kio/job.h>
+#include <kio/netaccess.h>
+#include <kio/scheduler.h>
+#include <kdirlister.h>
+#include <kfileitem.h>
+#include <kglobal.h>
+#include <kdebug.h>
+
+//app includes
+#include "qextfileinfo.h"
+
+QString QExtFileInfo::lastErrorMsg = "";
+
+QString QExtFileInfo::canonicalPath(const QString& path)
+{
+ if (!path.startsWith("/") || path == "/")
+ return path;
+ bool endsWithSlash = path.endsWith("/");
+ QDir dir(path);
+ if (dir.exists() || QFileInfo(path).exists())
+ {
+ QString s = dir.canonicalPath();
+ if (endsWithSlash)
+ s.append("/");
+ return s;
+ } else
+ {
+ KURL u = KURL::fromPathOrURL(path).upURL();
+ QString s = u.path(-1) + "/";
+ if (s == "//") s = "/";
+ QString s2 = path.mid(s.length());
+ s2 = QExtFileInfo::canonicalPath(s) + s2;
+ return s2;
+ }
+}
+
+QString QExtFileInfo::homeDirPath()
+{
+ return QDir(QDir::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())
+ {
+ QString 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);
+ }
+ QString path = urlToConvert.path();
+ QString 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<level; i++)
+ {
+ path="../"+path;
+ };
+ }
+
+ resultURL.setPath(QDir::cleanDirPath(path));
+ }
+
+ if (urlToConvert.path().endsWith("/") && !resultURL.path().isEmpty())
+ resultURL.adjustPath(1);
+ return resultURL;
+}
+/** convert relative filename to absolute */
+KURL QExtFileInfo::toAbsolute(const KURL& _urlToConvert,const KURL& _baseURL)
+{
+ KURL urlToConvert = _urlToConvert;
+ KURL baseURL = _baseURL;
+ KURL resultURL = urlToConvert;
+
+ if (urlToConvert.protocol() == baseURL.protocol() && !urlToConvert.path().startsWith("/"))
+ {
+ if (urlToConvert.isLocalFile())
+ {
+ QString path = QExtFileInfo::canonicalPath(baseURL.path());
+ if (!path.isEmpty())
+ baseURL.setPath(path);
+ }
+ int pos;
+ QString cutname = urlToConvert.path();
+ QString cutdir = baseURL.path(1);
+ while ( (pos = cutname.find("../")) >=0 )
+ {
+ cutname.remove( 0, pos+3 );
+ cutdir.remove( cutdir.length()-1, 1 );
+ cutdir.remove( cutdir.findRev('/')+1 , 1000);
+ }
+ resultURL.setPath(QDir::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 QString& mask, QWidget *window)
+{
+ QExtFileInfo internalFileInfo;
+ return internalFileInfo.allFilesInternal(path, mask, window);
+}
+
+KURL::List QExtFileInfo::allFilesRelative( const KURL& path, const QString& mask, QWidget *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;
+}
+
+QDict<KFileItem> QExtFileInfo::allFilesDetailed(const KURL& path, const QString& mask, QWidget *window)
+{
+ QExtFileInfo internalFileInfo;
+ return internalFileInfo.allFilesDetailedInternal(path, mask, window);
+}
+
+
+bool QExtFileInfo::createDir(const KURL& path, QWidget *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 = KIO::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;
+ QString dir = u.path(-1);
+ while ( !dir.isEmpty() && dir.right(1) != "/" )
+ {
+ dir.remove( dir.length()-1,1);
+ }
+ u.setPath(dir);
+ return u;
+}
+
+QString QExtFileInfo::shortName(const QString &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(QDir::currentDirPath()+"/");
+ return url;
+}
+
+
+bool QExtFileInfo::exists(const KURL& a_url, bool readingOnly, QWidget *window)
+{
+// Andras: Don't use it now, as it brings up an extra dialog and need manual
+// intervention when usign fish
+// return KIO::NetAccess::exists(a_url, false);
+
+// No dialog when stating.
+ if (a_url.isLocalFile())
+ {
+ return QFile::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, QWidget* window )
+{
+ QExtFileInfo internalFileInfo;
+ return internalFileInfo.internalCopy( src, target, permissions, overwrite, resume, window );
+}
+
+/** No descriptions */
+KURL::List QExtFileInfo::allFilesInternal(const KURL& startURL, const QString& mask, QWidget *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
+ QStringList list = QStringList::split( ' ', mask );
+ for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it )
+ lstFilters.append( new QRegExp(*it, false, true ) );
+
+ bJobOK = true;
+ KIO::ListJob *job = KIO::listRecursive(startURL, false, true);
+ job->setWindow(window);
+ m_listJobCount = 1;
+ connect(job, SIGNAL(entries(KIO::Job *, const KIO::UDSEntryList&)),
+ this, SLOT(slotNewEntries(KIO::Job *, const KIO::UDSEntryList&)));
+ connect( job, SIGNAL( result (KIO::Job *) ),
+ this, SLOT( slotListResult (KIO::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 */
+QDict<KFileItem> QExtFileInfo::allFilesDetailedInternal(const KURL& startURL, const QString& mask, QWidget *window)
+{
+ detailedDirListItems.setAutoDelete(true);
+ detailedDirListItems.clear();
+ detailedDirListItems.setAutoDelete(false);
+ if (internalExists(startURL, true, window))
+ {
+ lstFilters.setAutoDelete(true);
+ lstFilters.clear();
+ // Split on white space
+ QStringList list = QStringList::split( ' ', mask );
+ for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it )
+ lstFilters.append( new QRegExp(*it, false, true ) );
+
+ bJobOK = true;
+ KIO::ListJob *job = KIO::listRecursive(startURL, false, true);
+ job->setWindow(window);
+ m_listJobCount = 1;
+ connect(job, SIGNAL(entries(KIO::Job *, const KIO::UDSEntryList&)),
+ this, SLOT(slotNewDetailedEntries(KIO::Job *, const KIO::UDSEntryList&)));
+ connect( job, SIGNAL( result (KIO::Job *) ),
+ this, SLOT( slotListResult (KIO::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 QString& startPath, const QString& mask)
+{
+ KURL::List list;
+ QDir d(startPath, mask);
+ QStringList l = d.entryList();
+ QStringList::ConstIterator end = l.constEnd();
+ QString path;
+ for (QStringList::ConstIterator it = l.constBegin(); it != end; ++it)
+ {
+ path = *it;
+ if (path != "." && path != "..")
+ {
+ path = startPath + "/" + path;
+ if (QFileInfo(path).isDir())
+ path.append("/");
+ list.append(KURL::fromPathOrURL(path));
+ }
+ }
+ l = d.entryList("*", QDir::Dirs);
+ end = l.constEnd();
+ for (QStringList::ConstIterator it = l.constBegin(); it != end; ++it)
+ {
+ if ((*it) != "." && (*it) != "..")
+ list += allLocalFiles(startPath + "/" + (*it), mask);
+ }
+ return list;
+}
+
+
+//Some hackery from KIO::NetAccess as they do not do exactly what we want
+/* return true if the url exists*/
+bool QExtFileInfo::internalExists(const KURL& url, bool readingOnly, QWidget *window)
+{
+ bJobOK = true;
+ KURL url2 = url;
+ url2.adjustPath(-1);
+ // kdDebug(24000)<<"QExtFileInfo::internalExists"<<endl;
+ KIO::StatJob * job = KIO::stat(url2, false);
+ job->setWindow(window);
+ job->setDetails(0);
+ job->setSide(readingOnly);
+ connect( job, SIGNAL( result (KIO::Job *) ),
+ this, SLOT( slotResult (KIO::Job *) ) );
+
+ //To avoid lock-ups, start a timer.
+ QTimer::singleShot(60*1000, this,SLOT(slotTimeout()));
+ //kdDebug(24000)<<"QExtFileInfo::internalExists:before enter_loop"<<endl;
+ enter_loop();
+ //kdDebug(24000)<<"QExtFileInfo::internalExists:after enter_loop"<<endl;
+ return bJobOK;
+}
+
+bool QExtFileInfo::internalCopy(const KURL& src, const KURL& target, int permissions,
+ bool overwrite, bool resume, QWidget* window)
+{
+ bJobOK = true; // success unless further error occurs
+
+ KIO::Scheduler::checkSlaveOnHold(true);
+ KIO::Job * job = KIO::file_copy( src, target, permissions, overwrite, resume, false );
+// KIO::Job * job2 = KIO::del(target, false );
+ //job2->setWindow (window);
+ //connect( job2, SIGNAL( result (KIO::Job *) ),
+// this, SLOT( slotResult (KIO::Job *) ) );
+
+ //enter_loop();
+ //if (bJobOK)
+ {
+// kdDebug(24000) << "Copying " << src << " to " << target << endl;
+ // KIO::Job *job = KIO::copy( src, target, false );
+ job->setWindow (window);
+ connect( job, SIGNAL( result (KIO::Job *) ),
+ this, SLOT( slotResult (KIO::Job *) ) );
+ enter_loop();
+ }
+ return bJobOK;
+}
+
+
+void qt_enter_modal( QWidget *widget );
+void qt_leave_modal( QWidget *widget );
+
+void QExtFileInfo::enter_loop()
+{
+ QWidget dummy(0,0,WType_Dialog | WShowModal);
+ dummy.setFocusPolicy( QWidget::NoFocus );
+ qt_enter_modal(&dummy);
+ //kdDebug(24000)<<"QExtFileInfo::enter_loop:before qApp->enter_loop()"<< endl;
+ qApp->enter_loop();
+// kdDebug(24000)<<"QExtFileInfo::enter_loop:after qApp->enter_loop()"<<endl;
+ qt_leave_modal(&dummy);
+}
+
+void QExtFileInfo::slotListResult(KIO::Job *job)
+{
+ m_listJobCount--;
+ if (m_listJobCount == 0)
+ slotResult(job);
+}
+
+void QExtFileInfo::slotResult(KIO::Job *job)
+{
+ //kdDebug(24000)<<"QExtFileInfo::slotResult"<<endl;
+ bJobOK = !job->error();
+ if ( !bJobOK )
+ {
+ if ( !lastErrorMsg )
+ lastErrorMsg = job->errorString();
+ }
+ if ( job->isA("KIO::StatJob") )
+ m_entry = static_cast<KIO::StatJob *>(job)->statResult();
+ qApp->exit_loop();
+}
+
+void QExtFileInfo::slotNewEntries(KIO::Job *job, const KIO::UDSEntryList& udsList)
+{
+ KURL url = static_cast<KIO::ListJob *>(job)->url();
+ url.adjustPath(-1);
+ // avoid creating these QStrings again and again
+ static const QString& dot = KGlobal::staticQString(".");
+ static const QString& dotdot = KGlobal::staticQString("..");
+
+ KIO::UDSEntryListConstIterator it = udsList.begin();
+ KIO::UDSEntryListConstIterator end = udsList.end();
+ KURL itemURL;
+ QPtrList<KFileItem> linkItems;
+ linkItems.setAutoDelete(true);
+ for ( ; it != end; ++it )
+ {
+ QString name;
+
+ // find out about the name
+ KIO::UDSEntry::ConstIterator entit = (*it).begin();
+ for( ; entit != (*it).end(); ++entit )
+ if ((*entit).m_uds == KIO::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();
+ QString 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 (QPtrListIterator<QRegExp> filterIt(lstFilters); filterIt.current(); ++filterIt )
+ {
+ if (filterIt.current()->exactMatch(item->text()))
+ dirListItems.append(itemURL);
+ }
+ delete item;
+ }
+ }
+ for (QPtrList<KFileItem>::ConstIterator it = linkItems.constBegin(); it != linkItems.constEnd(); ++it)
+ {
+ KIO::ListJob *ljob = KIO::listRecursive((*it)->url(), false, true);
+ m_listJobCount++;
+ //kdDebug(24000) << "Now listing: " << (*it)->url() << endl;
+ connect( ljob, SIGNAL(entries(KIO::Job *,const KIO::UDSEntryList &)),
+ this,SLOT (slotNewEntries(KIO::Job *,const KIO::UDSEntryList &)));
+ connect( ljob, SIGNAL(result(KIO::Job *)),
+ this,SLOT (slotListResult(KIO::Job *)));
+ }
+}
+
+void QExtFileInfo::slotNewDetailedEntries(KIO::Job *job, const KIO::UDSEntryList& udsList)
+{
+ KURL url = static_cast<KIO::ListJob *>(job)->url();
+ url.adjustPath(-1);
+ // avoid creating these QStrings again and again
+ static const QString& dot = KGlobal::staticQString(".");
+ static const QString& dotdot = KGlobal::staticQString("..");
+
+ KIO::UDSEntryListConstIterator it = udsList.begin();
+ KIO::UDSEntryListConstIterator end = udsList.end();
+ KURL itemURL;
+ QPtrList<KFileItem> linkItems;
+ linkItems.setAutoDelete(true);
+ for ( ; it != end; ++it )
+ {
+ QString name;
+
+ // find out about the name
+ KIO::UDSEntry::ConstIterator entit = (*it).begin();
+ for( ; entit != (*it).end(); ++entit )
+ if ((*entit).m_uds == KIO::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());
+ QString 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 (QPtrListIterator<QRegExp> filterIt( lstFilters ); filterIt.current(); ++filterIt)
+ if (filterIt.current()->exactMatch(item->text()))
+ {
+ detailedDirListItems.insert(item->url().url(), item);
+ added = true;
+ }
+ if (!added)
+ delete item;
+ }
+ }
+ for (QPtrList<KFileItem>::ConstIterator it = linkItems.constBegin(); it != linkItems.constEnd(); ++it)
+ {
+ KIO::ListJob *ljob = KIO::listRecursive((*it)->url(), false, true);
+ m_listJobCount++;
+ // kdDebug(24000) << "Now listing: " << (*it)->url() << endl;
+ connect( ljob, SIGNAL(entries(KIO::Job *,const KIO::UDSEntryList &)),
+ this,SLOT (slotNewDetailedEntries(KIO::Job *,const KIO::UDSEntryList &)));
+ connect( ljob, SIGNAL(result(KIO::Job *)),
+ this,SLOT (slotListResult(KIO::Job *)));
+ }
+}
+
+/** Timeout occurred while waiting for some network function to return. */
+void QExtFileInfo::slotTimeout()
+{
+ bJobOK = false;
+ qApp->exit_loop();
+}
+#include "qextfileinfo.moc"