Warning, file /maui/mauikit-filebrowsing/src/code/fmlist.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 * <one line to give the program's name and a brief idea of what it does.> 0003 * Copyright (C) 2018 camilo higuita <milo.h@aol.com> 0004 * 0005 * This program is free software: you can redistribute it and/or modify 0006 * it under the terms of the GNU General Public License as published by 0007 * the Free Software Foundation, either version 3 of the License, or 0008 * (at your option) any later version. 0009 * 0010 * This program is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 * GNU General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU General Public License 0016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0017 */ 0018 0019 #include "fmlist.h" 0020 #include "fm.h" 0021 #include "tagging.h" 0022 0023 #ifdef COMPONENT_SYNCING 0024 #include "syncing.h" 0025 #endif 0026 0027 #include <QFuture> 0028 #include <QThread> 0029 #include <QtConcurrent/QtConcurrentRun> 0030 #include <QtConcurrent> 0031 0032 #include <QClipboard> 0033 #include <QGuiApplication> 0034 0035 #include <KLocalizedString> 0036 0037 FMList::FMList(QObject *parent) 0038 : MauiList(parent) 0039 , fm(new FM(this)) 0040 { 0041 qRegisterMetaType<FMList *>("const FMList*"); // this is needed for QML to know of FMList in the search method 0042 connect(this->fm, &FM::cloudServerContentReady, [this](FMStatic::PATH_CONTENT res) { 0043 if (this->path == res.path) { 0044 this->assignList(res.content); 0045 } 0046 }); 0047 0048 connect(this->fm, &FM::pathContentReady, [this](QUrl) { 0049 Q_EMIT this->preListChanged(); 0050 this->sortList(); 0051 this->setStatus({PathStatus::STATUS_CODE::READY, this->list.isEmpty() ? i18n("Nothing here!") : QStringLiteral(""), this->list.isEmpty() ? i18n("This place seems to be empty") : QStringLiteral(""), this->list.isEmpty() ? QStringLiteral("folder-add") : QStringLiteral(""), this->list.isEmpty(), true}); 0052 Q_EMIT this->postListChanged(); 0053 Q_EMIT this->countChanged(); 0054 }); 0055 0056 connect(this->fm, &FM::pathContentItemsChanged, [this](QVector<QPair<FMH::MODEL, FMH::MODEL>> res) { 0057 for (const auto &item : qAsConst(res)) { 0058 const auto index = this->indexOf(FMH::MODEL_KEY::PATH, item.first[FMH::MODEL_KEY::PATH]); 0059 0060 if (index >= this->list.size() || index < 0) 0061 return; 0062 0063 this->list[index] = item.second; 0064 Q_EMIT this->updateModel(index, FMH::modelRoles(item.second)); 0065 } 0066 }); 0067 0068 connect(this->fm, &FM::pathContentItemsReady, [this](FMStatic::PATH_CONTENT res) { 0069 if (res.path != this->path) 0070 return; 0071 0072 this->appendToList(res.content); 0073 }); 0074 0075 connect(this->fm, &FM::pathContentItemsRemoved, [this](FMStatic::PATH_CONTENT res) { 0076 if (res.path != this->path) 0077 return; 0078 0079 if (!FMH::fileExists(res.path)) { 0080 this->setStatus({PathStatus::STATUS_CODE::ERROR, i18n("Error"), i18n("This URL cannot be listed"), QStringLiteral("documentinfo"), true, false}); 0081 return; 0082 } 0083 0084 for (const auto &item : qAsConst(res.content)) { 0085 const auto index = this->indexOf(FMH::MODEL_KEY::PATH, item[FMH::MODEL_KEY::PATH]); 0086 qDebug() << "SUPOSSED TO REMOVED THIS FORM THE LIST" << index << this->list.count() << item[FMH::MODEL_KEY::PATH]; 0087 0088 this->remove(index); 0089 } 0090 0091 this->setStatus({PathStatus::STATUS_CODE::READY, this->list.isEmpty() ? i18n("Nothing here!") : QStringLiteral(""), this->list.isEmpty() ? i18n("This place seems to be empty") : QStringLiteral(""), this->list.isEmpty() ? QStringLiteral("folder-add") : QStringLiteral(""), this->list.isEmpty(), true}); 0092 }); 0093 0094 connect(this->fm, &FM::warningMessage, [this](const QString &message) { 0095 Q_EMIT this->warning(message); 0096 }); 0097 0098 connect(this->fm, &FM::loadProgress, [this](const int &percent) { 0099 Q_EMIT this->progress(percent); 0100 }); 0101 0102 connect(this->fm, &FM::pathContentChanged, [this](const QUrl &path) { 0103 qDebug() << "FOLDER PATH CHANGED" << path; 0104 if (path != this->path) 0105 return; 0106 this->sortList(); 0107 }); 0108 0109 connect(this->fm, &FM::newItem, [this](const FMH::MODEL &item, const QUrl &url) { 0110 if (this->path == url) { 0111 Q_EMIT this->preItemAppended(); 0112 this->list << item; 0113 Q_EMIT this->postItemAppended(); 0114 Q_EMIT this->countChanged(); 0115 } 0116 }); 0117 0118 connect(Tagging::getInstance(), &Tagging::urlTagged, [this](QString, QString tag) 0119 { 0120 if(this->getPathType() == FMList::PATHTYPE::TAGS_PATH) 0121 { 0122 const auto url = this->path.toString(); 0123 if(url.endsWith(tag)) 0124 { 0125 this->refresh(); 0126 } 0127 } 0128 }); 0129 0130 connect(Tagging::getInstance(), &Tagging::tagged, [this](QVariantMap) 0131 { 0132 if(this->pathType == PATHTYPE::TAGS_PATH) 0133 { 0134 this->refresh(); 0135 } 0136 }); 0137 0138 connect(Tagging::getInstance(), &Tagging::tagRemoved, [this](QString) 0139 { 0140 if(this->pathType == PATHTYPE::TAGS_PATH) 0141 { 0142 this->refresh(); 0143 } 0144 }); 0145 } 0146 0147 void FMList::assignList(const FMH::MODEL_LIST &list) 0148 { 0149 Q_EMIT this->preListChanged(); 0150 this->list = list; 0151 this->sortList(); 0152 this->setStatus({PathStatus::STATUS_CODE::READY, this->list.isEmpty() ? i18n("Nothing here!") : QStringLiteral(""), this->list.isEmpty() ? i18n("This place seems to be empty") : QStringLiteral(""), this->list.isEmpty() ? QStringLiteral("folder-add") : QStringLiteral(""), this->list.isEmpty(), true}); 0153 Q_EMIT this->postListChanged(); 0154 Q_EMIT this->countChanged(); 0155 } 0156 0157 void FMList::appendToList(const FMH::MODEL_LIST &list) 0158 { 0159 Q_EMIT this->preItemsAppended(list.size()); 0160 this->list << list; 0161 Q_EMIT this->postItemAppended(); 0162 Q_EMIT this->countChanged(); 0163 } 0164 0165 void FMList::clear() 0166 { 0167 Q_EMIT this->preListChanged(); 0168 this->list.clear(); 0169 Q_EMIT this->postListChanged(); 0170 Q_EMIT this->countChanged(); 0171 } 0172 0173 FMH::MODEL_LIST FMList::getTagContent(const QString &tag, const QStringList &filters) 0174 { 0175 if (tag.isEmpty()) { 0176 return Tagging::getInstance()->getTags(); 0177 } else { 0178 FMH::MODEL_LIST content; 0179 const auto urls = Tagging::getInstance()->getTagUrls(tag, filters, false); 0180 for (const auto &url : urls) { 0181 content << FMStatic::getFileInfoModel(url); 0182 } 0183 0184 return content; 0185 } 0186 } 0187 0188 void FMList::setList() 0189 { 0190 qDebug() << "PATHTYPE FOR URL" << pathType << this->path.toString() << this->filters << this; 0191 0192 if(this->path.isEmpty() || !m_autoLoad) 0193 { 0194 return; 0195 } 0196 0197 this->clear(); 0198 0199 switch (this->pathType) 0200 { 0201 case FMList::PATHTYPE::TAGS_PATH: 0202 this->assignList(getTagContent(this->path.fileName(), QStringList() << this->filters << FMStatic::FILTER_LIST[static_cast<FMStatic::FILTER_TYPE>(this->filterType)])); 0203 break; // SYNC 0204 0205 case FMList::PATHTYPE::CLOUD_PATH: 0206 this->fm->getCloudServerContent(this->path, this->filters, this->cloudDepth); 0207 break; // ASYNC 0208 0209 default: { 0210 const bool exists = this->path.isLocalFile() ? FMH::fileExists(this->path) : true; 0211 if (!exists) 0212 this->setStatus({PathStatus::STATUS_CODE::ERROR, i18n("Error"), i18n("This URL cannot be listed"), QStringLiteral("documentinfo"), this->list.isEmpty(), exists}); 0213 else { 0214 this->fm->getPathContent(this->path, this->hidden, this->onlyDirs, QStringList() << this->filters << FMStatic::FILTER_LIST[static_cast<FMStatic::FILTER_TYPE>(this->filterType)]); 0215 } 0216 break; // ASYNC 0217 } 0218 } 0219 } 0220 0221 void FMList::reset() 0222 { 0223 this->setList(); 0224 } 0225 0226 const FMH::MODEL_LIST &FMList::items() const 0227 { 0228 return this->list; 0229 } 0230 0231 FMList::SORTBY FMList::getSortBy() const 0232 { 0233 return this->sort; 0234 } 0235 0236 void FMList::setSortBy(const FMList::SORTBY &key) 0237 { 0238 if (this->sort == key) 0239 return; 0240 0241 this->sort = key; 0242 Q_EMIT this->sortByChanged(); 0243 } 0244 0245 void FMList::sortList() 0246 { 0247 const FMH::MODEL_KEY key = static_cast<FMH::MODEL_KEY>(this->sort); 0248 auto it = this->list.begin(); 0249 0250 const auto sortFunc = [key](const FMH::MODEL &e1, const FMH::MODEL &e2) -> bool 0251 { 0252 switch (key) { 0253 case FMH::MODEL_KEY::SIZE: { 0254 if (e1[key].toDouble() > e2[key].toDouble()) 0255 return true; 0256 break; 0257 } 0258 0259 case FMH::MODEL_KEY::ADDDATE: 0260 case FMH::MODEL_KEY::MODIFIED: 0261 case FMH::MODEL_KEY::DATE: { 0262 auto currentTime = QDateTime::currentDateTime(); 0263 0264 auto date1 = QDateTime::fromString(e1[key], Qt::TextDate); 0265 auto date2 = QDateTime::fromString(e2[key], Qt::TextDate); 0266 0267 if (date1.secsTo(currentTime) < date2.secsTo(currentTime)) 0268 return true; 0269 0270 break; 0271 } 0272 0273 case FMH::MODEL_KEY::MIME: 0274 case FMH::MODEL_KEY::LABEL: { 0275 const auto str1 = QString(e1[key]).toLower(); 0276 const auto str2 = QString(e2[key]).toLower(); 0277 0278 if (str1 < str2) 0279 return true; 0280 break; 0281 } 0282 0283 default: 0284 if (e1[key] < e2[key]) 0285 return true; 0286 } 0287 0288 return false; 0289 }; 0290 0291 if (this->foldersFirst) { 0292 0293 it = std::partition(this->list.begin(), 0294 this->list.end(), 0295 [](const FMH::MODEL &e1) -> bool { 0296 return e1[FMH::MODEL_KEY::MIME] == QStringLiteral("inode/directory"); 0297 }); 0298 0299 if(this->list.begin() != it) 0300 { 0301 std::sort(this->list.begin(), it, sortFunc); 0302 } 0303 } 0304 0305 if(it != this->list.end()) 0306 { 0307 std::sort(it, this->list.end(), sortFunc); 0308 } 0309 } 0310 0311 QString FMList::getPathName() const 0312 { 0313 return this->pathName; 0314 } 0315 0316 QString FMList::getPath() const 0317 { 0318 return this->path.toString(); 0319 } 0320 0321 void FMList::setPath(const QString &path) 0322 { 0323 QUrl path_ = QUrl::fromUserInput(path.simplified(), QStringLiteral("/"), QUrl::AssumeLocalFile).adjusted(QUrl::PreferLocalFile | QUrl::StripTrailingSlash | QUrl::NormalizePathSegments); 0324 0325 if (this->path == path_) 0326 return; 0327 0328 this->path = path_; 0329 m_navHistory.appendPath(this->path); 0330 0331 this->setStatus({PathStatus::STATUS_CODE::LOADING, i18n("Loading content"), i18n("Almost ready!"), QStringLiteral("view-refresh"), true, false}); 0332 0333 const auto __scheme = this->path.scheme(); 0334 this->pathName = QDir(this->path.toLocalFile()).dirName(); 0335 0336 if (__scheme == FMStatic::PATHTYPE_SCHEME[FMStatic::PATHTYPE_KEY::CLOUD_PATH]) { 0337 this->pathType = FMList::PATHTYPE::CLOUD_PATH; 0338 0339 } else if (__scheme == FMStatic::PATHTYPE_SCHEME[FMStatic::PATHTYPE_KEY::APPS_PATH]) { 0340 this->pathType = FMList::PATHTYPE::APPS_PATH; 0341 0342 } else if (__scheme == FMStatic::PATHTYPE_SCHEME[FMStatic::PATHTYPE_KEY::TAGS_PATH]) { 0343 this->pathType = FMList::PATHTYPE::TAGS_PATH; 0344 this->pathName = this->path.path(); 0345 0346 } else if (__scheme == FMStatic::PATHTYPE_SCHEME[FMStatic::PATHTYPE_KEY::TRASH_PATH]) { 0347 this->pathType = FMList::PATHTYPE::TRASH_PATH; 0348 this->pathName = QStringLiteral("Trash"); 0349 0350 } else if (__scheme == FMStatic::PATHTYPE_SCHEME[FMStatic::PATHTYPE_KEY::PLACES_PATH]) { 0351 this->pathType = FMList::PATHTYPE::PLACES_PATH; 0352 0353 } else if (__scheme == FMStatic::PATHTYPE_SCHEME[FMStatic::PATHTYPE_KEY::MTP_PATH]) { 0354 this->pathType = FMList::PATHTYPE::MTP_PATH; 0355 0356 } else if (__scheme == FMStatic::PATHTYPE_SCHEME[FMStatic::PATHTYPE_KEY::FISH_PATH]) { 0357 this->pathType = FMList::PATHTYPE::FISH_PATH; 0358 0359 } else if (__scheme == FMStatic::PATHTYPE_SCHEME[FMStatic::PATHTYPE_KEY::REMOTE_PATH]) { 0360 this->pathType = FMList::PATHTYPE::REMOTE_PATH; 0361 0362 } else if (__scheme == FMStatic::PATHTYPE_SCHEME[FMStatic::PATHTYPE_KEY::DRIVES_PATH]) { 0363 this->pathType = FMList::PATHTYPE::DRIVES_PATH; 0364 } else { 0365 this->pathType = FMList::PATHTYPE::OTHER_PATH; 0366 } 0367 0368 Q_EMIT this->pathNameChanged(); 0369 Q_EMIT this->pathTypeChanged(); 0370 Q_EMIT this->pathChanged(); 0371 } 0372 0373 FMList::PATHTYPE FMList::getPathType() const 0374 { 0375 return this->pathType; 0376 } 0377 0378 QStringList FMList::getFilters() const 0379 { 0380 return this->filters; 0381 } 0382 0383 void FMList::setFilters(const QStringList &filters) 0384 { 0385 if (this->filters == filters) 0386 return; 0387 0388 this->filters = filters; 0389 0390 Q_EMIT this->filtersChanged(); 0391 } 0392 0393 void FMList::resetFilters() 0394 { 0395 this->setFilters(QStringList()); 0396 } 0397 0398 FMList::FILTER FMList::getFilterType() const 0399 { 0400 return this->filterType; 0401 } 0402 0403 void FMList::setFilterType(const FMList::FILTER &type) 0404 { 0405 if (this->filterType == type) 0406 return; 0407 0408 this->filterType = type; 0409 0410 Q_EMIT this->filterTypeChanged(); 0411 } 0412 0413 void FMList::resetFilterType() 0414 { 0415 this->setFilterType(FMList::FILTER::NONE); 0416 } 0417 0418 bool FMList::getHidden() const 0419 { 0420 return this->hidden; 0421 } 0422 0423 void FMList::setHidden(const bool &state) 0424 { 0425 if (this->hidden == state) 0426 return; 0427 0428 this->hidden = state; 0429 Q_EMIT this->hiddenChanged(); 0430 } 0431 0432 bool FMList::getOnlyDirs() const 0433 { 0434 return this->onlyDirs; 0435 } 0436 0437 void FMList::setOnlyDirs(const bool &state) 0438 { 0439 if (this->onlyDirs == state) 0440 return; 0441 0442 this->onlyDirs = state; 0443 0444 Q_EMIT this->onlyDirsChanged(); 0445 } 0446 0447 void FMList::refresh() 0448 { 0449 Q_EMIT this->pathChanged(); 0450 } 0451 0452 void FMList::createDir(const QString &name) 0453 { 0454 if(m_readOnly) 0455 return; 0456 0457 if (this->pathType == FMList::PATHTYPE::CLOUD_PATH) { 0458 #ifdef COMPONENT_SYNCING 0459 this->fm->createCloudDir(QString(this->path.toString()).replace(FMStatic::PATHTYPE_SCHEME[FMStatic::PATHTYPE_KEY::CLOUD_PATH] + "/" + this->fm->sync->getUser(), ""), name); 0460 #endif 0461 } else { 0462 FMStatic::createDir(this->path, name); 0463 } 0464 } 0465 0466 void FMList::createFile(const QString& name) 0467 { 0468 if(m_readOnly) 0469 return; 0470 0471 FMStatic::createFile(this->path, name); 0472 } 0473 0474 void FMList::renameFile(const QString& url, const QString& newName) 0475 { 0476 if(m_readOnly) 0477 return; 0478 0479 FMStatic::rename(QUrl(url), newName); 0480 } 0481 0482 void FMList::moveToTrash(const QStringList& urls) 0483 { 0484 if(m_readOnly) 0485 return; 0486 0487 FMStatic::moveToTrash(QUrl::fromStringList(urls)); 0488 } 0489 0490 void FMList::removeFiles(const QStringList& urls) 0491 { 0492 if(m_readOnly) 0493 return; 0494 0495 FMStatic::removeFiles(QUrl::fromStringList(urls)); 0496 } 0497 0498 void FMList::createSymlink(const QString& url) 0499 { 0500 if(m_readOnly) 0501 return; 0502 0503 FMStatic::createSymlink(QUrl(url), this->path); 0504 } 0505 0506 bool FMList::saveImageFile(const QImage& image) 0507 { 0508 QString fileName = QString(QStringLiteral("%1/pasted_image-0.%2")).arg(path.toLocalFile(), QStringLiteral("png")); 0509 0510 int idx = 1; 0511 while ( QFile::exists( fileName ) ) 0512 { 0513 fileName = QString(QStringLiteral("%1/pasted_image-%2.%3")).arg(path.toLocalFile(), QString::number(idx), QStringLiteral("png")); 0514 idx++; 0515 } 0516 0517 return image.save(fileName); 0518 } 0519 0520 bool FMList::saveTextFile(const QString& data, const QString &format) 0521 { 0522 QString fileName = QString(QStringLiteral("%1/pasted_text-0.%2")).arg(path.toLocalFile(), format); 0523 0524 int idx = 1; 0525 while ( QFile::exists( fileName ) ) 0526 { 0527 fileName = QString(QStringLiteral("%1/pasted_text-%2.%3")).arg(path.toLocalFile(), QString::number(idx), format); 0528 idx++; 0529 } 0530 0531 QFile file(fileName); 0532 0533 if (file.open(QIODevice::ReadWrite)) 0534 { 0535 QTextStream out(&file); 0536 out << data; 0537 file.close(); 0538 return true; 0539 } 0540 0541 return false; 0542 } 0543 0544 void FMList::paste() 0545 { 0546 if(m_readOnly) 0547 return; 0548 0549 const QClipboard *clipboard = QGuiApplication::clipboard(); 0550 const QMimeData *mimeData = clipboard->mimeData(); 0551 0552 if(!mimeData) 0553 { 0554 qWarning() << "Could not get mime data from the clipboard"; 0555 return; 0556 } 0557 0558 if (mimeData->hasImage()) 0559 { 0560 saveImageFile(qvariant_cast<QImage>(mimeData->imageData())); 0561 } else if (mimeData->hasUrls()) 0562 { 0563 const QByteArray a = mimeData->data(QStringLiteral("application/x-kde-cutselection")); 0564 const bool cut = (!a.isEmpty() && a.at(0) == '1'); 0565 0566 if(cut) 0567 { 0568 cutInto(QUrl::toStringList(mimeData->urls())); 0569 // mimeData->clear(); 0570 }else 0571 { 0572 copyInto(QUrl::toStringList(mimeData->urls())); 0573 } 0574 0575 } else if (mimeData->hasText()) 0576 { 0577 saveTextFile(mimeData->text(), QStringLiteral("txt")); 0578 } else 0579 { 0580 qWarning() << "Unexpected mime type from clipboard content for performing a paste"; 0581 } 0582 } 0583 0584 bool FMList::clipboardHasContent() const 0585 { 0586 const QClipboard *clipboard = QGuiApplication::clipboard(); 0587 const QMimeData *mimeData = clipboard->mimeData(); 0588 0589 if(!mimeData) 0590 { 0591 qWarning() << "Could not get mime data from the clipboard"; 0592 return false; 0593 } 0594 0595 return mimeData->hasUrls() || mimeData->hasImage() || mimeData->hasText(); 0596 } 0597 0598 0599 void FMList::copyInto(const QStringList &urls) 0600 { 0601 if(m_readOnly) 0602 return; 0603 0604 this->fm->copy(QUrl::fromStringList(urls), this->path); 0605 } 0606 0607 void FMList::cutInto(const QStringList &urls) 0608 { 0609 if(m_readOnly) 0610 return; 0611 0612 this->fm->cut(QUrl::fromStringList(urls), this->path); 0613 } 0614 0615 void FMList::setDirIcon(const int &index, const QString &iconName) 0616 { 0617 if (index >= this->list.size() || index < 0) 0618 return; 0619 0620 const auto path = QUrl(this->list.at(index)[FMH::MODEL_KEY::PATH]); 0621 0622 if (!FMStatic::isDir(path)) 0623 return; 0624 0625 FMStatic::setDirConf(QUrl(path.toString() + QStringLiteral("/.directory")), QStringLiteral("Desktop Entry"), QStringLiteral("Icon"), iconName); 0626 0627 this->list[index][FMH::MODEL_KEY::ICON] = iconName; 0628 Q_EMIT this->updateModel(index, QVector<int> {FMH::MODEL_KEY::ICON}); 0629 } 0630 0631 const QUrl FMList::getParentPath() 0632 { 0633 switch (this->pathType) 0634 { 0635 case FMList::PATHTYPE::PLACES_PATH: 0636 return FMStatic::parentDir(this->path); 0637 default: 0638 return this->previousPath(); 0639 } 0640 } 0641 0642 const QUrl FMList::posteriorPath() 0643 { 0644 const auto url = m_navHistory.getPosteriorPath(); 0645 0646 if (url.isEmpty()) 0647 return this->path; 0648 0649 return url; 0650 } 0651 0652 const QUrl FMList::previousPath() 0653 { 0654 const auto url = m_navHistory.getPreviousPath(); 0655 0656 if (url.isEmpty()) 0657 return this->path; 0658 0659 return url; 0660 } 0661 0662 bool FMList::getFoldersFirst() const 0663 { 0664 return this->foldersFirst; 0665 } 0666 0667 void FMList::setFoldersFirst(const bool &value) 0668 { 0669 if (this->foldersFirst == value) 0670 return; 0671 0672 Q_EMIT this->preListChanged(); 0673 0674 this->foldersFirst = value; 0675 0676 Q_EMIT this->foldersFirstChanged(); 0677 0678 this->sortList(); 0679 0680 Q_EMIT this->postListChanged(); 0681 Q_EMIT this->countChanged(); 0682 } 0683 0684 void FMList::componentComplete() 0685 { 0686 connect(this, &FMList::pathChanged, this, &FMList::setList); 0687 connect(this, &FMList::filtersChanged, this, &FMList::setList); 0688 connect(this, &FMList::filterTypeChanged, this, &FMList::setList); 0689 connect(this, &FMList::hiddenChanged, this, &FMList::setList); 0690 connect(this, &FMList::onlyDirsChanged, this, &FMList::setList); 0691 0692 connect(this, &FMList::sortByChanged, [this]() 0693 { 0694 if(this->list.size() > 0) 0695 { 0696 Q_EMIT this->preListChanged(); 0697 this->sortList(); 0698 Q_EMIT this->postListChanged(); 0699 Q_EMIT this->countChanged(); 0700 } 0701 }); 0702 0703 if(!this->path.isEmpty() && this->path.isValid()) 0704 { 0705 this->setList(); 0706 } 0707 } 0708 0709 void FMList::search(const QString &query, bool recursive) 0710 { 0711 if(this->path.isEmpty()) 0712 { 0713 this->setStatus({PathStatus::ERROR, i18n("Error"), i18n("No path to perform the search"), QStringLiteral("document-info"), true, false}); 0714 } 0715 0716 qDebug() << "SEARCHING FOR" << query << this->path; 0717 0718 if (!this->path.isLocalFile() || !recursive) 0719 { //if the path is not local then search will not be performed and instead will be filtered 0720 qWarning() << "URL recived is not a local file. So search will only filter the content" << this->path; 0721 this->filterContent(query, this->path); 0722 return; 0723 } 0724 0725 QFutureWatcher<FMStatic::PATH_CONTENT> *watcher = new QFutureWatcher<FMStatic::PATH_CONTENT>; 0726 connect(watcher, &QFutureWatcher<FMH::MODEL_LIST>::finished, [=]() { 0727 const auto res = watcher->future().result(); 0728 0729 this->assignList(res.content); 0730 watcher->deleteLater(); 0731 }); 0732 0733 QFuture<FMStatic::PATH_CONTENT> t1 = QtConcurrent::run([=]() -> FMStatic::PATH_CONTENT { 0734 FMStatic::PATH_CONTENT res; 0735 res.path = path; 0736 res.content = FMStatic::search(query, this->path, this->hidden, this->onlyDirs, this->filters); 0737 return res; 0738 }); 0739 watcher->setFuture(t1); 0740 } 0741 0742 void FMList::filterContent(const QString &query, const QUrl &path) 0743 { 0744 if (this->list.isEmpty()) { 0745 qDebug() << "Can not filter content. List is empty"; 0746 return; 0747 } 0748 0749 QFutureWatcher<FMStatic::PATH_CONTENT> *watcher = new QFutureWatcher<FMStatic::PATH_CONTENT>; 0750 connect(watcher, &QFutureWatcher<FMH::MODEL_LIST>::finished, [=]() { 0751 const auto res = watcher->future().result(); 0752 0753 this->assignList(res.content); 0754 watcher->deleteLater(); 0755 }); 0756 0757 QFuture<FMStatic::PATH_CONTENT> t1 = QtConcurrent::run([=]() -> FMStatic::PATH_CONTENT { 0758 FMH::MODEL_LIST m_content; 0759 FMStatic::PATH_CONTENT res; 0760 0761 for (const auto &item : qAsConst(this->list)) 0762 { 0763 if (item[FMH::MODEL_KEY::LABEL].contains(query, Qt::CaseInsensitive) || item[FMH::MODEL_KEY::SUFFIX].contains(query, Qt::CaseInsensitive) || item[FMH::MODEL_KEY::MIME].contains(query, Qt::CaseInsensitive)) { 0764 m_content << item; 0765 } 0766 } 0767 0768 res.path = path; 0769 res.content = m_content; 0770 return res; 0771 }); 0772 watcher->setFuture(t1); 0773 } 0774 0775 int FMList::getCloudDepth() const 0776 { 0777 return this->cloudDepth; 0778 } 0779 0780 void FMList::setCloudDepth(const int &value) 0781 { 0782 if (this->cloudDepth == value) 0783 return; 0784 0785 this->cloudDepth = value; 0786 0787 Q_EMIT this->cloudDepthChanged(); 0788 } 0789 0790 PathStatus FMList::getStatus() const 0791 { 0792 return this->m_status; 0793 } 0794 0795 void FMList::setStatus(const PathStatus &status) 0796 { 0797 this->m_status = status; 0798 Q_EMIT this->statusChanged(); 0799 } 0800 0801 void FMList::remove(const int &index) 0802 { 0803 if (index >= this->list.size() || index < 0) 0804 return; 0805 0806 Q_EMIT this->preItemRemoved(index); 0807 this->list.remove(index); 0808 Q_EMIT this->postItemRemoved(); 0809 Q_EMIT this->countChanged(); 0810 } 0811 0812 int FMList::indexOfName(const QString& query) 0813 { 0814 const auto it = std::find_if(this->items().constBegin(), this->items().constEnd(), [query](const FMH::MODEL &item) -> bool { 0815 return item[FMH::MODEL_KEY::LABEL].startsWith(query, Qt::CaseInsensitive); 0816 }); 0817 0818 if (it != this->items().constEnd()) 0819 return (std::distance(this->items().constBegin(), it)); 0820 else 0821 return -1; 0822 } 0823 0824 bool FMList::getAutoLoad() const 0825 { 0826 return m_autoLoad; 0827 } 0828 0829 void FMList::setAutoLoad(bool value) 0830 { 0831 if(value == m_autoLoad) 0832 { 0833 return; 0834 } 0835 0836 m_autoLoad = value; 0837 Q_EMIT autoLoadChanged(); 0838 } 0839 0840 bool FMList::readOnly() const 0841 { 0842 return m_readOnly; 0843 } 0844 0845 void FMList::setReadOnly(bool value) 0846 { 0847 if(m_readOnly == value) 0848 return; 0849 0850 m_readOnly = value; 0851 Q_EMIT readOnlyChanged(); 0852 } 0853 0854 int FMList::indexOfFile(const QString& url) 0855 { 0856 const auto it = std::find_if(this->items().constBegin(), this->items().constEnd(), [url](const FMH::MODEL &item) -> bool { 0857 return item[FMH::MODEL_KEY::URL] == url; 0858 }); 0859 0860 if (it != this->items().constEnd()) 0861 return (std::distance(this->items().constBegin(), it)); 0862 else 0863 return -1; 0864 } 0865 0866 0867