File indexing completed on 2024-05-05 17:57:23
0001 /* 0002 SPDX-FileCopyrightText: 2001 Shie Erlich <krusader@users.sourceforge.net> 0003 SPDX-FileCopyrightText: 2001 Rafi Yanai <krusader@users.sourceforge.net> 0004 SPDX-FileCopyrightText: 2004-2022 Krusader Krew <https://krusader.org> 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "krsearchmod.h" 0010 0011 // QtCore 0012 #include <QDir> 0013 #include <QMimeDatabase> 0014 #include <QMimeType> 0015 #include <QRegExp> 0016 // QtWidgets 0017 #include <QApplication> 0018 #include <qplatformdefs.h> 0019 0020 #include <KIO/Global> 0021 0022 #include "../Archive/krarchandler.h" 0023 #include "../FileSystem/defaultfilesystem.h" 0024 #include "../FileSystem/fileitem.h" 0025 #include "../FileSystem/krpermhandler.h" 0026 #include "../FileSystem/krquery.h" 0027 #include "../FileSystem/virtualfilesystem.h" 0028 #include "../krglobal.h" 0029 0030 #define EVENT_PROCESS_DELAY 250 // milliseconds 0031 0032 static const QStringList TAR_TYPES = QStringList() << "tbz" 0033 << "tgz" 0034 << "tarz" 0035 << "tar" 0036 << "tlz"; 0037 0038 KrSearchMod::KrSearchMod(const KrQuery *query) 0039 : m_defaultFileSystem(nullptr) 0040 , m_virtualFileSystem(nullptr) 0041 , m_stopSearch(false) 0042 { 0043 m_query = new KrQuery(*query); 0044 connect(m_query, &KrQuery::status, this, &KrSearchMod::searching); 0045 connect(m_query, &KrQuery::processEvents, this, &KrSearchMod::slotProcessEvents); 0046 } 0047 0048 KrSearchMod::~KrSearchMod() 0049 { 0050 delete m_query; 0051 if (m_defaultFileSystem) 0052 delete m_defaultFileSystem; 0053 if (m_virtualFileSystem) 0054 delete m_virtualFileSystem; 0055 } 0056 0057 void KrSearchMod::start() 0058 { 0059 m_unScannedUrls.clear(); 0060 m_scannedUrls.clear(); 0061 m_timer.start(); 0062 0063 const QList<QUrl> whereToSearch = m_query->searchInDirs(); 0064 0065 // search every dir that needs to be searched 0066 for (int i = 0; i < whereToSearch.count(); ++i) 0067 scanUrl(whereToSearch[i]); 0068 0069 emit finished(); 0070 } 0071 0072 void KrSearchMod::stop() 0073 { 0074 m_stopSearch = true; 0075 } 0076 0077 void KrSearchMod::scanUrl(const QUrl &url) 0078 { 0079 if (m_stopSearch) 0080 return; 0081 0082 m_unScannedUrls.push(url); 0083 while (!m_unScannedUrls.isEmpty()) { 0084 const QUrl url = m_unScannedUrls.pop(); 0085 0086 if (m_stopSearch) 0087 return; 0088 0089 if (m_query->isExcluded(url)) { 0090 if (!m_query->searchInDirs().contains(url)) 0091 continue; 0092 } 0093 0094 if (m_scannedUrls.contains(url)) 0095 // avoid endless loop 0096 continue; 0097 0098 m_scannedUrls.push(url); 0099 0100 emit searching(url.toDisplayString(QUrl::PreferLocalFile)); 0101 0102 scanDirectory(url); 0103 } 0104 } 0105 0106 void KrSearchMod::scanDirectory(const QUrl &url) 0107 { 0108 FileSystem *fileSystem = getFileSystem(url); 0109 0110 // create file items 0111 const bool refreshed = fileSystem->scanDir(url); 0112 if (!refreshed) { 0113 emit error(url); 0114 return; 0115 } 0116 0117 for (FileItem *fileItem : fileSystem->fileItems()) { 0118 const QUrl fileUrl = fileItem->getUrl(); 0119 0120 if (m_query->isRecursive() && ((!fileItem->isSymLink() && fileItem->isDir()) || (fileItem->isSymLink() && m_query->followLinks()))) { 0121 // query search in subdirectory 0122 m_unScannedUrls.push(fileUrl); 0123 } 0124 0125 if (m_query->searchInArchives() && fileUrl.isLocalFile() && KrArcHandler::arcSupported(fileItem->getMime())) { 0126 // query search in archive; NOTE: only supported for local files 0127 QUrl archiveURL = fileUrl; 0128 bool encrypted; 0129 const QString type = krArcMan.getType(encrypted, fileUrl.path(), fileItem->getMime()); 0130 0131 if (!encrypted) { 0132 archiveURL.setScheme(TAR_TYPES.contains(type) ? "tar" : "krarc"); 0133 m_unScannedUrls.push(archiveURL); 0134 } 0135 } 0136 0137 if (m_query->match(fileItem)) { 0138 // found! 0139 emit found(*fileItem, m_query->foundText()); // emitting copy of file item 0140 } 0141 0142 if (m_timer.elapsed() >= EVENT_PROCESS_DELAY) { 0143 qApp->processEvents(); 0144 m_timer.start(); 0145 if (m_stopSearch) 0146 return; 0147 } 0148 } 0149 } 0150 0151 FileSystem *KrSearchMod::getFileSystem(const QUrl &url) 0152 { 0153 FileSystem *fileSystem; 0154 if (url.scheme() == QStringLiteral("virt")) { 0155 if (!m_virtualFileSystem) 0156 m_virtualFileSystem = new VirtualFileSystem(); 0157 fileSystem = m_virtualFileSystem; 0158 } else { 0159 if (!m_defaultFileSystem) 0160 m_defaultFileSystem = new DefaultFileSystem(); 0161 fileSystem = m_defaultFileSystem; 0162 } 0163 return fileSystem; 0164 } 0165 0166 void KrSearchMod::slotProcessEvents(bool &stopped) 0167 { 0168 qApp->processEvents(); 0169 stopped = m_stopSearch; 0170 }