X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/396706a741c3bb43be2aac6f77cc8e6412c6187c..01e4f60a0931aba506b184d384a4e2f926b2233c:/src/search/filenamesearchprotocol.cpp diff --git a/src/search/filenamesearchprotocol.cpp b/src/search/filenamesearchprotocol.cpp index 59e49782f..b56a99580 100644 --- a/src/search/filenamesearchprotocol.cpp +++ b/src/search/filenamesearchprotocol.cpp @@ -16,14 +16,18 @@ * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***************************************************************************/ - + #include "filenamesearchprotocol.h" -#include -#include -#include -#include - +#include +#include +#include +#include +#include +#include +#include +#include + #include #include #include @@ -31,63 +35,65 @@ FileNameSearchProtocol::FileNameSearchProtocol( const QByteArray &pool, const QByteArray &app ) : SlaveBase("search", pool, app), m_checkContent(false), - m_regExp(0) + m_regExp(0), + m_iteratedDirs() { } FileNameSearchProtocol::~FileNameSearchProtocol() { - delete m_regExp; - m_regExp = 0; + cleanup(); } -void FileNameSearchProtocol::listDir(const KUrl& url) +void FileNameSearchProtocol::listDir(const QUrl& url) { - delete m_regExp; - m_regExp = 0; + cleanup(); - const QStringList searchValues = url.allQueryItemValues("search"); - if (!searchValues.isEmpty()) { - m_regExp = new QRegExp(searchValues.first(), Qt::CaseInsensitive, QRegExp::Wildcard); + const QString search = url.queryItemValue("search"); + if (!search.isEmpty()) { + m_regExp = new QRegExp(search, Qt::CaseInsensitive, QRegExp::Wildcard); } m_checkContent = false; - const QStringList checkContentValues = url.allQueryItemValues("checkContent"); - if (!checkContentValues.isEmpty() && (checkContentValues.first() == QLatin1String("yes"))) { + const QString checkContent = url.queryItemValue("checkContent"); + if (checkContent == QLatin1String("yes")) { m_checkContent = true; } - KUrl directory = url; - directory.setProtocol("file"); - directory.setEncodedQuery(QByteArray()); - - searchDirectory(directory); + const QString urlString = url.queryItemValue("url"); + searchDirectory(KUrl(urlString)); + cleanup(); finished(); } void FileNameSearchProtocol::searchDirectory(const KUrl& directory) { + if (directory.path() == QLatin1String("/proc")) { + // Don't try to iterate the /proc directory of Linux + return; + } + // Get all items of the directory KDirLister *dirLister = new KDirLister(); dirLister->setDelayedMimeTypes(false); dirLister->setAutoErrorHandlingEnabled(false, 0); dirLister->openUrl(directory); - + QEventLoop eventLoop; - QObject::connect(dirLister, SIGNAL(canceled()), &eventLoop, SLOT(quit())); - QObject::connect(dirLister, SIGNAL(completed()), &eventLoop, SLOT(quit())); + QObject::connect(dirLister, static_cast(&KDirLister::canceled), &eventLoop, &QEventLoop::quit); + QObject::connect(dirLister, static_cast(&KDirLister::completed), &eventLoop, &QEventLoop::quit); eventLoop.exec(); - + // Visualize all items that match the search pattern QList pendingDirs; const KFileItemList items = dirLister->items(); foreach (const KFileItem& item, items) { bool addItem = false; - if ((m_regExp == 0) || item.name().contains(*m_regExp)) { + if (!m_regExp || item.name().contains(*m_regExp)) { addItem = true; - } else if (m_checkContent && item.mimetype().startsWith(QLatin1String("text/"))) { - addItem = containsPattern(item.url()); + } else if (m_checkContent && item.determineMimeType().inherits(QLatin1String("text/plain"))) { + addItem = contentContainsPattern(item.url()); } if (addItem) { @@ -97,25 +103,59 @@ void FileNameSearchProtocol::searchDirectory(const KUrl& directory) } if (item.isDir()) { - pendingDirs.append(item.url()); + if (item.isLink()) { + // Assure that no endless searching is done in directories that + // have already been iterated. + const KUrl linkDest(item.url(), item.linkDest()); + if (!m_iteratedDirs.contains(linkDest.path())) { + pendingDirs.append(linkDest); + } + } else { + pendingDirs.append(item.url()); + } } } listEntry(KIO::UDSEntry(), true); + m_iteratedDirs.insert(directory.path()); + + delete dirLister; + dirLister = 0; + // Recursively iterate all sub directories foreach (const KUrl& pendingDir, pendingDirs) { searchDirectory(pendingDir); } } -bool FileNameSearchProtocol::containsPattern(const KUrl& fileName) const +bool FileNameSearchProtocol::contentContainsPattern(const KUrl& fileName) const { - Q_ASSERT(m_regExp != 0); + Q_ASSERT(m_regExp); + + QString path; + KTemporaryFile tempFile; + + if (fileName.isLocalFile()) { + path = fileName.path(); + } else if (tempFile.open()) { + KIO::Job* getJob = KIO::file_copy(fileName, + tempFile.fileName(), + -1, + KIO::Overwrite | KIO::HideProgressInfo); + if (!KIO::NetAccess::synchronousRun(getJob, 0)) { + // The non-local file could not be downloaded + return false; + } + path = tempFile.fileName(); + } else { + // No temporary file could be created for downloading non-local files + return false; + } - QFile file(fileName.path()); + QFile file(path); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return false; - } + } QTextStream in(&file); while (!in.atEnd()) { @@ -128,8 +168,15 @@ bool FileNameSearchProtocol::containsPattern(const KUrl& fileName) const return false; } +void FileNameSearchProtocol::cleanup() +{ + delete m_regExp; + m_regExp = 0; + m_iteratedDirs.clear(); +} + extern "C" int KDE_EXPORT kdemain( int argc, char **argv ) -{ +{ KComponentData instance("kio_search"); QCoreApplication app(argc, argv); @@ -137,9 +184,9 @@ extern "C" int KDE_EXPORT kdemain( int argc, char **argv ) fprintf(stderr, "Usage: kio_filenamesearch protocol domain-socket1 domain-socket2\n"); exit(-1); } - + FileNameSearchProtocol slave(argv[2], argv[3]); slave.dispatchLoop(); - + return 0; }