Warning, file /utilities/mangonel/providers/Paths.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 * Copyright 2010-2012 Bart Kroon <bart@tarmack.eu> 0003 * 0004 * Redistribution and use in source and binary forms, with or without 0005 * modification, are permitted provided that the following conditions 0006 * are met: 0007 * 0008 * 1. Redistributions of source code must retain the above copyright 0009 * notice, this list of conditions and the following disclaimer. 0010 * 2. Redistributions in binary form must reproduce the above copyright 0011 * notice, this list of conditions and the following disclaimer in the 0012 * documentation and/or other materials provided with the distribution. 0013 * 0014 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 0015 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 0016 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 0017 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 0018 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 0019 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 0020 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 0021 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0022 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 0023 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0024 */ 0025 0026 #include "Paths.h" 0027 0028 #include <KLocalizedString> 0029 0030 #include <QDateTime> 0031 #include <QDesktopServices> 0032 #include <QDir> 0033 #include <QUrl> 0034 #include <QDebug> 0035 0036 #include <sys/stat.h> 0037 #include <dirent.h> 0038 0039 Paths::Paths(QObject *parent) : 0040 Provider(parent) 0041 { 0042 } 0043 0044 Paths::~Paths() 0045 {} 0046 0047 // QDir::entryList is very slow, so we do it ourself (on Linux, someone who knows the others need to fix them) 0048 static QStringList sortedDirList(const QString &dirPath, const QString &matchPrefix) 0049 { 0050 #ifdef Q_OS_LINUX 0051 QByteArray path = dirPath.toLocal8Bit(); 0052 if (!path.endsWith('/')) { 0053 path += '/'; 0054 } 0055 DIR *dir = opendir(path.constData()); 0056 if (!dir) { 0057 qWarning() << "Error opening dir:" << strerror(errno); 0058 return {}; 0059 } 0060 QHash<QString, qint64> entries; 0061 struct stat statbuf; 0062 dirent *ent; 0063 while ((ent = readdir(dir))) { 0064 if (ent->d_name[0] == '.') { 0065 continue; 0066 } 0067 const QString name = QString::fromLocal8Bit(ent->d_name); 0068 if (!name.startsWith(matchPrefix, Qt::CaseInsensitive)) { 0069 continue; 0070 } 0071 QByteArray new_path = path + static_cast<const char*>(ent->d_name); 0072 if (lstat(new_path.constData(), &statbuf) == -1) { 0073 qWarning() << "Error stating file:" << strerror(errno); 0074 continue; 0075 } 0076 if (S_ISCHR(statbuf.st_mode) || 0077 S_ISBLK(statbuf.st_mode) || 0078 S_ISFIFO(statbuf.st_mode)|| 0079 S_ISSOCK(statbuf.st_mode)) { 0080 continue; 0081 } 0082 entries[name] = statbuf.st_mtime; 0083 } 0084 closedir(dir); 0085 QStringList names = entries.keys(); 0086 std::sort(names.begin(), names.end(), [&](const QString &a, const QString &b) { 0087 return entries[a] > entries[b]; 0088 }); 0089 return names; 0090 #else 0091 return QDir(dirPath).entryList(QStringList(matchPrefix + '*'), QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files, QDir::Time); 0092 #endif 0093 } 0094 0095 QList<ProviderResult *> Paths::getResults(QString query) 0096 { 0097 QList<ProviderResult*> list; 0098 0099 QDir dir; 0100 if (query.startsWith("/")) { 0101 dir = QDir::root(); 0102 query.remove(0, 1); 0103 } else { 0104 dir = QDir::home(); 0105 0106 if (query.startsWith('~')) { 0107 query.remove(0, 1); 0108 } 0109 } 0110 0111 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) 0112 QStringList walk = query.split("/", QString::SkipEmptyParts); 0113 #else 0114 QStringList walk = query.split("/", Qt::SkipEmptyParts); 0115 #endif 0116 0117 if (walk.isEmpty() || query.endsWith('/')) { 0118 walk.append(""); 0119 } 0120 0121 QString part = walk.takeFirst(); 0122 while (walk.length() > 0) { 0123 if (!dir.exists(part)) { 0124 return list; 0125 } 0126 0127 dir.cd(part); 0128 part = walk.takeFirst(); 0129 } 0130 0131 QStringList paths = sortedDirList(dir.path(), part); 0132 0133 if (paths.size() > 100) { 0134 paths = paths.mid(0, 100); 0135 } 0136 0137 qint64 currentSecsSinceEpoch = QDateTime::currentSecsSinceEpoch(); 0138 0139 static const QString homePath = QDir::homePath(); 0140 0141 for(const QString &name : paths) { 0142 const QFileInfo path(dir.filePath(name)); 0143 ProviderResult *result = new ProviderResult(); 0144 0145 result->program = path.absoluteFilePath(); 0146 0147 if (result->program.startsWith(homePath)) { 0148 result->name = result->program.mid(homePath.length()); 0149 result->completion = "~" + result->name.left(result->name.lastIndexOf("/")) + "/" + path.fileName(); 0150 } else { 0151 result->name = result->program; 0152 result->completion = result->name.left(result->name.lastIndexOf("/")) + "/" + path.fileName(); 0153 } 0154 result->priority = currentSecsSinceEpoch - path.lastModified().toSecsSinceEpoch(); 0155 if (path.isDir()) { 0156 result->completion += "/"; 0157 result->icon = "system-file-manager"; 0158 } else { 0159 result->icon = m_mimeDb.mimeTypeForFile(path).iconName(); 0160 } 0161 0162 result->object = this; 0163 result->type = i18n("Open path"); 0164 list.append(result); 0165 } 0166 0167 return list; 0168 } 0169 0170 int Paths::launch(const QString &exec) 0171 { 0172 QDesktopServices::openUrl(QUrl::fromLocalFile(exec)); 0173 return 0; 0174 } 0175 0176 0177 0178 // kate: indent-mode cstyle; space-indent on; indent-width 4;