diff --git a/src/fm/fmlist.cpp b/src/fm/fmlist.cpp index 5cecee9..c996b06 100644 --- a/src/fm/fmlist.cpp +++ b/src/fm/fmlist.cpp @@ -1,780 +1,780 @@ /* * * Copyright (C) 2018 camilo higuita * * 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 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "fmlist.h" #include "fm.h" #include "utils.h" #include #include #ifdef COMPONENT_SYNCING #include "syncing.h" #endif #if defined Q_OS_LINUX && !defined Q_OS_ANDROID #include #endif #include #include #include #include FMList::FMList(QObject *parent) : MauiList(parent), fm(new FM(this)), watcher(new QFileSystemWatcher(this)) { connect(this->fm, &FM::cloudServerContentReady, [&](const FMH::MODEL_LIST &list, const QUrl &url) { if(this->path == url) { this->assignList(list); } }); connect(this->fm, &FM::pathContentReady, [&](const FMH::PATH_CONTENT &res) { // if(res.path != this->path) // return; this->assignList(res.content); }); connect(this->fm, &FM::warningMessage, [&](const QString &message) { emit this->warning(message); }); connect(this->fm, &FM::loadProgress, [&](const int &percent) { emit this->progress(percent); }); // with kio based on android it watches the directory itself, so better relay on that #ifdef Q_OS_ANDROID connect(this->watcher, &QFileSystemWatcher::directoryChanged, [&](const QString &path) { qDebug()<< "FOLDER PATH CHANGED" << path; this->reset(); }); #else connect(this->fm, &FM::pathContentChanged, [&](const QUrl &path) { qDebug()<< "FOLDER PATH CHANGED" << path; if(path != this->path) return; this->sortList(); }); #endif connect(this->fm, &FM::newItem, [&] (const FMH::MODEL &item, const QUrl &url) { if(this->path == url) { emit this->preItemAppended(); this->list << item; emit this->postItemAppended(); } }); const auto value = UTIL::loadSettings("SaveDirProps", "SETTINGS", this->saveDirProps).toBool(); this->setSaveDirProps(value); connect(this, &FMList::pathChanged, this, &FMList::reset); } void FMList::watchPath(const QString& path, const bool& clear) { #ifdef Q_OS_ANDROID if(!this->watcher->directories().isEmpty() && clear) this->watcher->removePaths(this->watcher->directories()); if(path.isEmpty() || !FMH::fileExists(path) || !QUrl(path).isLocalFile()) return; this->watcher->addPath(QString(path).replace("file://", "")); qDebug()<< "WATCHING PATHS" << this->watcher->directories(); #else Q_UNUSED(path) Q_UNUSED(clear) #endif } void FMList::assignList(const FMH::MODEL_LIST& list) { emit this->preListChanged(); this->list =list; this->sortList(); this->count = static_cast(this->list.size()); emit this->countChanged(); this->setStatus({STATUS_CODE::READY, this->list.isEmpty() ? "Nothing here!" : "", this->list.isEmpty() ? "This place seems to be empty" : "",this->list.isEmpty() ? "folder-add" : "", this->list.isEmpty(), true}); emit this->postListChanged(); } void FMList::setList() { qDebug()<< "PATHTYPE FOR URL"<< pathType << this->path.toString() << this->filters << this; switch(this->pathType) { case FMList::PATHTYPE::SEARCH_PATH: this->search(this->path.fileName(), this->searchPath, this->hidden, this->onlyDirs, this->filters); break; //ASYNC case FMList::PATHTYPE::TAGS_PATH: this->assignList(this->fm->getTagContent(this->path.fileName(), QStringList() <filters << FMH::FILTER_LIST[static_cast(this->filterType)])); break; //SYNC case FMList::PATHTYPE::CLOUD_PATH: this->fm->getCloudServerContent(this->path.toString(), this->filters, this->cloudDepth); break; //ASYNC default: { emit this->preListChanged(); this->list.clear(); emit this->postListChanged(); const bool exists = this->path.isLocalFile() ? FMH::fileExists(this->path) : true; if(!exists) this->setStatus({STATUS_CODE::ERROR, "Error", "This URL cannot be listed", "documentinfo", this->list.isEmpty(), exists}); else{ this->fm->getPathContent(this->path, this->hidden, this->onlyDirs, QStringList() <filters << FMH::FILTER_LIST[static_cast(this->filterType)]); } break;//ASYNC } } } void FMList::reset() { if(this->saveDirProps) { auto conf = FMH::dirConf(this->path.toString()+"/.directory"); this->sort = static_cast(conf[FMH::MODEL_NAME[FMH::MODEL_KEY::SORTBY]].toInt()); this->hidden = conf[FMH::MODEL_NAME[FMH::MODEL_KEY::HIDDEN]].toBool(); this->foldersFirst = conf[FMH::MODEL_NAME[FMH::MODEL_KEY::FOLDERSFIRST]].toBool(); }else { this->hidden = UTIL::loadSettings("HiddenFilesShown", "SETTINGS", this->hidden).toBool(); this->foldersFirst = UTIL::loadSettings("FoldersFirst", "SETTINGS", this->foldersFirst).toBool(); this->sort = static_cast(UTIL::loadSettings("SortBy", "SETTINGS", this->sort).toInt()); } emit this->sortByChanged(); emit this->hiddenChanged(); emit this->foldersFirstChanged(); this->setList(); } FMH::MODEL_LIST FMList::items() const { return this->list; } FMList::SORTBY FMList::getSortBy() const { return this->sort; } void FMList::setSortBy(const FMList::SORTBY &key) { if(this->sort == key) return; emit this->preListChanged(); this->sort = key; this->sortList(); if(this->pathType == FMList::PATHTYPE::PLACES_PATH && this->trackChanges && this->saveDirProps) FMH::setDirConf(this->path.toString()+"/.directory", "MAUIFM", "SortBy", this->sort); else UTIL::saveSettings("SortBy", this->sort, "SETTINGS"); emit this->sortByChanged(); emit this->postListChanged(); } void FMList::sortList() { const FMH::MODEL_KEY key = static_cast(this->sort); auto index = 0; if(this->foldersFirst) { qSort(this->list.begin(), this->list.end(), [](const FMH::MODEL& e1, const FMH::MODEL& e2) -> bool { Q_UNUSED(e2) const auto key = FMH::MODEL_KEY::MIME; if(e1[key] == "inode/directory") return true; return false; }); for(const auto &item : this->list) if(item[FMH::MODEL_KEY::MIME] == "inode/directory") index++; else break; std::sort(this->list.begin(),this->list.begin() + index, [&key](const FMH::MODEL& e1, const FMH::MODEL& e2) -> bool { switch(key) { case FMH::MODEL_KEY::SIZE: { if(e1[key].toDouble() > e2[key].toDouble()) return true; break; } case FMH::MODEL_KEY::MODIFIED: case FMH::MODEL_KEY::DATE: { auto currentTime = QDateTime::currentDateTime(); auto date1 = QDateTime::fromString(e1[key], Qt::TextDate); auto date2 = QDateTime::fromString(e2[key], Qt::TextDate); if(date1.secsTo(currentTime) < date2.secsTo(currentTime)) return true; break; } case FMH::MODEL_KEY::LABEL: { const auto str1 = QString(e1[key]).toLower(); const auto str2 = QString(e2[key]).toLower(); if(str1 < str2) return true; break; } default: if(e1[key] < e2[key]) return true; } return false; }); } std::sort(this->list.begin() + index, this->list.end(), [key](const FMH::MODEL& e1, const FMH::MODEL& e2) -> bool { const auto role = key; switch(role) { case FMH::MODEL_KEY::MIME: if(e1[role] == "inode/directory") return true; break; case FMH::MODEL_KEY::SIZE: { if(e1[role].toDouble() > e2[role].toDouble()) return true; break; } case FMH::MODEL_KEY::MODIFIED: case FMH::MODEL_KEY::DATE: { auto currentTime = QDateTime::currentDateTime(); auto date1 = QDateTime::fromString(e1[role], Qt::TextDate); auto date2 = QDateTime::fromString(e2[role], Qt::TextDate); if(date1.secsTo(currentTime) < date2.secsTo(currentTime)) return true; break; } case FMH::MODEL_KEY::LABEL: { const auto str1 = QString(e1[role]).toLower(); const auto str2 = QString(e2[role]).toLower(); if(str1 < str2) return true; break; } default: if(e1[role] < e2[role]) return true; } return false; }); } QString FMList::getPathName() const { return this->pathName; } QUrl FMList::getPath() const { return this->path; } void FMList::setPath(const QUrl &path) { if(this->path == path) return; this->searchPath = this->path; this->path = path; NavHistory.appendPath(this->path); this->setStatus({STATUS_CODE::LOADING, "Loading content", "Almost ready!", "view-refresh", true, false}); const auto __scheme = this->path.scheme(); this->pathName = this->path.fileName(); if(__scheme == FMH::PATHTYPE_SCHEME[FMH::PATHTYPE_KEY::SEARCH_PATH]) { this->pathType = FMList::PATHTYPE::SEARCH_PATH; this->watchPath(QString()); }else if(__scheme == FMH::PATHTYPE_SCHEME[FMH::PATHTYPE_KEY::CLOUD_PATH]) { this->pathType = FMList::PATHTYPE::CLOUD_PATH; this->watchPath(QString()); }else if(__scheme == FMH::PATHTYPE_SCHEME[FMH::PATHTYPE_KEY::APPS_PATH]) { this->pathType = FMList::PATHTYPE::APPS_PATH; this->watchPath(QString()); }else if(__scheme == FMH::PATHTYPE_SCHEME[FMH::PATHTYPE_KEY::TAGS_PATH]) { this->pathType = FMList::PATHTYPE::TAGS_PATH; this->watchPath(QString()); }else if(__scheme == FMH::PATHTYPE_SCHEME[FMH::PATHTYPE_KEY::TRASH_PATH]) { this->pathType = FMList::PATHTYPE::TRASH_PATH; this->pathName = "Trash"; this->watchPath(QString()); }else if(__scheme == FMH::PATHTYPE_SCHEME[FMH::PATHTYPE_KEY::PLACES_PATH]) { this->watchPath(this->path.toString()); this->pathType = FMList::PATHTYPE::PLACES_PATH; this->pathName = FMH::getDirInfoModel(this->path)[FMH::MODEL_KEY::LABEL]; }else if(__scheme == FMH::PATHTYPE_SCHEME[FMH::PATHTYPE_KEY::MTP_PATH]) { this->pathType = FMList::PATHTYPE::MTP_PATH; }else if(__scheme == FMH::PATHTYPE_SCHEME[FMH::PATHTYPE_KEY::FISH_PATH] ) { this->pathType = FMList::PATHTYPE::FISH_PATH; }else if(__scheme == FMH::PATHTYPE_SCHEME[FMH::PATHTYPE_KEY::REMOTE_PATH] ) { this->pathType = FMList::PATHTYPE::REMOTE_PATH; }else if(__scheme == FMH::PATHTYPE_SCHEME[FMH::PATHTYPE_KEY::DRIVES_PATH] ) { this->pathType = FMList::PATHTYPE::DRIVES_PATH; }else { this->pathType = FMList::PATHTYPE::OTHER_PATH; } emit this->pathNameChanged(); emit this->pathTypeChanged(); emit this->pathChanged(); } FMList::PATHTYPE FMList::getPathType() const { return this->pathType; } QStringList FMList::getFilters() const { return this->filters; } void FMList::setFilters(const QStringList &filters) { if(this->filters == filters) return; this->filters = filters; emit this->filtersChanged(); this->reset(); } FMList::FILTER FMList::getFilterType() const { return this->filterType; } void FMList::setFilterType(const FMList::FILTER &type) { if(this->filterType == type) return; this->filterType = type; emit this->filterTypeChanged(); this->reset(); } bool FMList::getHidden() const { return this->hidden; } void FMList::setHidden(const bool &state) { if(this->hidden == state) return; this->hidden = state; if(this->pathType == FMList::PATHTYPE::PLACES_PATH && this->trackChanges && this->saveDirProps) FMH::setDirConf(this->path.toString()+"/.directory", "Settings", "HiddenFilesShown", this->hidden); else UTIL::saveSettings("HiddenFilesShown", this->hidden, "SETTINGS"); emit this->hiddenChanged(); this->reset(); } bool FMList::getOnlyDirs() const { return this->onlyDirs; } void FMList::setOnlyDirs(const bool &state) { if(this->onlyDirs == state) return; this->onlyDirs = state; emit this->onlyDirsChanged(); this->reset(); } QVariantMap FMList::get(const int &index) const { if(index >= this->list.size() || index < 0) return QVariantMap(); const auto model = this->list.at(index); return FMH::toMap(model); } void FMList::refresh() { emit this->pathChanged(); } void FMList::createDir(const QString& name) { if(this->pathType == FMList::PATHTYPE::CLOUD_PATH) { #ifdef COMPONENT_SYNCING this->fm->createCloudDir(QString(this->path.toString()).replace(FMH::PATHTYPE_SCHEME[FMH::PATHTYPE_KEY::CLOUD_PATH]+"/"+this->fm->sync->getUser(), ""), name); #endif }else { FMStatic::createDir(this->path, name); } } void FMList::copyInto(const QStringList& urls) { this->fm->copy(QUrl::fromStringList(urls), this->path); } void FMList::cutInto(const QStringList& urls) { this->fm->cut(QUrl::fromStringList(urls), this->path); // else if(this->pathType == FMList::PATHTYPE::CLOUD_PATH) // { // this->fm->createCloudDir(QString(this->path).replace(FMH::PATHTYPE_NAME[FMList::PATHTYPE::CLOUD_PATH]+"/"+this->fm->sync->getUser(), ""), name); // } } void FMList::setDirIcon(const int &index, const QString &iconName) { if(index >= this->list.size() || index < 0) return; const auto path = QUrl(this->list.at(index)[FMH::MODEL_KEY::PATH]); if(!FMStatic::isDir(path)) return; FMH::setDirConf(path.toString()+"/.directory", "Desktop Entry", "Icon", iconName); this->list[index][FMH::MODEL_KEY::ICON] = iconName; emit this->updateModel(index, QVector {FMH::MODEL_KEY::ICON}); } const QUrl FMList::getParentPath() { switch(this->pathType) { case FMList::PATHTYPE::PLACES_PATH: return FMStatic::parentDir(this->path).toString(); default: return this->getPreviousPath(); } } QList FMList::getPosteriorPathHistory() { return QList (); // todo : implement signal } QList FMList::getPreviousPathHistory() { return QList (); // todo : implement signal } const QUrl FMList::getPosteriorPath() { const auto url = NavHistory.getPosteriorPath(); if(url.isEmpty()) return this->path; return url; } const QUrl FMList::getPreviousPath() { const auto url = NavHistory.getPreviousPath(); if(url.isEmpty()) return this->path; return url; } bool FMList::getTrackChanges() const { return this->trackChanges; } void FMList::setTrackChanges(const bool& value) { if(this->trackChanges == value) return; this->trackChanges = value; emit this->trackChangesChanged(); } bool FMList::getFoldersFirst() const { return this->foldersFirst; } void FMList::setFoldersFirst(const bool &value) { if(this->foldersFirst == value) return; emit this->preListChanged(); this->foldersFirst = value; if(this->pathType == FMList::PATHTYPE::PLACES_PATH && this->trackChanges && this->saveDirProps) FMH::setDirConf(this->path.toString()+"/.directory", "MAUIFM", "FoldersFirst", this->foldersFirst); else UTIL::saveSettings("FoldersFirst", this->foldersFirst, "SETTINGS"); emit this->foldersFirstChanged(); this->sortList(); emit this->postListChanged(); } void FMList::setSaveDirProps(const bool& value) { if(this->saveDirProps == value) return; this->saveDirProps = value; UTIL::saveSettings("SaveDirProps", this->saveDirProps, "SETTINGS"); emit this->saveDirPropsChanged(); } bool FMList::getSaveDirProps() const { return this->saveDirProps; } void FMList::search(const QString& query, const QUrl &path, const bool &hidden, const bool &onlyDirs, const QStringList &filters) { qDebug()<< "SEARCHING FOR" << query << path; if(!path.isLocalFile()) { qWarning() << "URL recived is not a local file. So search will only filter the content" << path; this->filterContent(query, path, hidden, onlyDirs, filters); return; } QFutureWatcher *watcher = new QFutureWatcher; connect(watcher, &QFutureWatcher::finished, [=]() { if(this->pathType != FMList::PATHTYPE::SEARCH_PATH) return; const auto res = watcher->future().result(); if(res.path != this->searchPath.toString()) return; this->assignList(res.content); emit this->searchResultReady(); watcher->deleteLater(); }); QFuture t1 = QtConcurrent::run([=]() -> FMH::PATH_CONTENT { FMH::PATH_CONTENT res; res.path = path.toString(); res.content = FMStatic::search(query, path, hidden, onlyDirs, filters); return res; }); watcher->setFuture(t1); } void FMList::filterContent(const QString &query, const QUrl &path, const bool &hidden, const bool &onlyDirs, const QStringList &filters) { if(this->list.isEmpty()) { qDebug() << "Can not filter content. List is empty"; return; } QFutureWatcher *watcher = new QFutureWatcher; connect(watcher, &QFutureWatcher::finished, [=]() { if(this->pathType != FMList::PATHTYPE::SEARCH_PATH) return; const auto res = watcher->future().result(); if(res.path != this->searchPath.toString()) return; this->assignList(res.content); emit this->searchResultReady(); watcher->deleteLater(); }); QFuture t1 = QtConcurrent::run([=]() -> FMH::PATH_CONTENT { FMH::MODEL_LIST m_content; FMH::PATH_CONTENT res; for(const auto &item : this->list) { 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)) { if(onlyDirs && item[FMH::MODEL_KEY::IS_DIR] == "true") { m_content << item; continue; } m_content << item; } } res.path = path.toString(); res.content = m_content; return res; }); watcher->setFuture(t1); } int FMList::getCloudDepth() const { return this->cloudDepth; } void FMList::setCloudDepth(const int& value) { if(this->cloudDepth == value) return; this->cloudDepth = value; emit this->cloudDepthChanged(); this->reset(); } uint FMList::getCount() const { return this->count; } PathStatus FMList::getStatus() const { return this->m_status; } void FMList::setStatus(const PathStatus &status) { this->m_status = status; emit this->statusChanged(); } bool FMList::itemIsFav(const QUrl &path) { return FMStatic::isFav(path); } bool FMList::favItem(const QUrl &path) { - return FMStatic::fav(path); + return FMStatic::toggleFav(path); } diff --git a/src/utils/fmstatic.cpp b/src/utils/fmstatic.cpp index 36fe3a6..9c2a827 100644 --- a/src/utils/fmstatic.cpp +++ b/src/utils/fmstatic.cpp @@ -1,443 +1,450 @@ #include "fmstatic.h" #include #include "utils.h" #if defined(Q_OS_ANDROID) #include "mauiandroid.h" #elif defined Q_OS_LINUX #include "mauikde.h" #include #include #include #include #include #include #include #include #include #include #endif #ifdef COMPONENT_TAGGING #include "tagging.h" #endif FMStatic::FMStatic(QObject *parent) : QObject(parent) {} FMH::MODEL_LIST FMStatic::packItems(const QStringList &items, const QString &type) { FMH::MODEL_LIST data; for(const auto &path : items) { if(QUrl(path).isLocalFile() && !FMH::fileExists(path)) continue; auto model = FMH::getFileInfoModel(path); model.insert(FMH::MODEL_KEY::TYPE, type); data << model; } return data; } FMH::MODEL_LIST FMStatic::getDefaultPaths() { return FMStatic::packItems(FMH::defaultPaths, FMH::PATHTYPE_LABEL[FMH::PATHTYPE_KEY::PLACES_PATH]); } FMH::MODEL_LIST FMStatic::search(const QString& query, const QUrl &path, const bool &hidden, const bool &onlyDirs, const QStringList &filters) { FMH::MODEL_LIST content; if(!path.isLocalFile()) { qWarning() << "URL recived is not a local file. FM::search" << path; return content; } if (FMStatic::isDir(path)) { QDir::Filters dirFilter; dirFilter = (onlyDirs ? QDir::AllDirs | QDir::NoDotDot | QDir::NoDot : QDir::Files | QDir::AllDirs | QDir::NoDotDot | QDir::NoDot); if(hidden) dirFilter = dirFilter | QDir::Hidden | QDir::System; QDirIterator it (path.toLocalFile(), filters, dirFilter, QDirIterator::Subdirectories); while (it.hasNext()) { auto url = it.next(); if(it.fileName().contains(query, Qt::CaseInsensitive)) { content << FMH::getFileInfoModel(QUrl::fromLocalFile(url)); } } }else qWarning() << "Search path does not exists" << path; qDebug()<< content; return content; } FMH::MODEL_LIST FMStatic::getDevices() { FMH::MODEL_LIST drives; #if defined(Q_OS_ANDROID) drives << packItems(MAUIAndroid::sdDirs(), FMH::PATHTYPE_LABEL[FMH::PATHTYPE_KEY::DRIVES_PATH]); return drives; #endif return drives; } QVariantMap FMStatic::getDirInfo(const QUrl &path, const QString &type) { return FMH::getDirInfo(path, type); } QVariantMap FMStatic::getFileInfo(const QUrl &path) { return FMH::getFileInfo(path); } bool FMStatic::isDefaultPath(const QString &path) { return FMH::defaultPaths.contains(path); } QUrl FMStatic::parentDir(const QUrl &path) { return FMH::parentDir(path); } bool FMStatic::isDir(const QUrl &path) { if(!path.isLocalFile()) { qWarning() << "URL recived is not a local file. FM::isDir" << path; return false; } QFileInfo file(path.toLocalFile()); return file.isDir(); } bool FMStatic::isApp(const QString& path) { return /*QFileInfo(path).isExecutable() ||*/ path.endsWith(".desktop"); } bool FMStatic::isCloud(const QUrl &path) { return path.scheme() == FMH::PATHTYPE_SCHEME[FMH::PATHTYPE_KEY::CLOUD_PATH]; } bool FMStatic::fileExists(const QUrl &path) { return FMH::fileExists(path); } QString FMStatic::fileDir(const QUrl& path) // the directory path of the file { return FMH::fileDir(path); } void FMStatic::saveSettings(const QString &key, const QVariant &value, const QString &group) { UTIL::saveSettings(key, value, group); } QVariant FMStatic::loadSettings(const QString &key, const QString &group, const QVariant &defaultValue) { return UTIL::loadSettings(key, group, defaultValue); } QString FMStatic::formatSize(const int &size) { QLocale locale; return locale.formattedDataSize(size); } QString FMStatic::formatDate(const QString &dateStr, const QString &format, const QString &initFormat) { QDateTime date; if( initFormat.isEmpty() ) date = QDateTime::fromString(dateStr, Qt::TextDate); else date = QDateTime::fromString(dateStr, initFormat); return date.toString(format); } QString FMStatic::formatTime(const qint64 &value) { QString tStr; if (value) { QTime time((value/3600)%60, (value/60)%60, value%60, (value*1000)%1000); QString format = "mm:ss"; if (value > 3600) format = "hh:mm:ss"; tStr = time.toString(format); } return tStr.isEmpty() ? "00:00" : tStr; } QString FMStatic::homePath() { return FMH::HomePath; } bool FMStatic::copy(const QUrl &url, const QUrl &destinationDir, const bool &overWriteDirectory) { #if defined Q_OS_ANDROID || defined Q_OS_WIN32 QFileInfo fileInfo(url.toLocalFile()); if(fileInfo.isFile()) QFile::copy(url.toLocalFile(), destinationDir.toLocalFile()); QDir originDirectory(url.toLocalFile()); if (!originDirectory.exists()) return false; QDir destinationDirectory(destinationDir.toLocalFile()); if(destinationDirectory.exists() && !overWriteDirectory) return false; else if(destinationDirectory.exists() && overWriteDirectory) destinationDirectory.removeRecursively(); originDirectory.mkpath(destinationDir.toLocalFile()); foreach(QString directoryName, originDirectory.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { QString destinationPath = destinationDir.toLocalFile() + "/" + directoryName; originDirectory.mkpath(destinationPath); copy(url.toLocalFile() + "/" + directoryName, destinationPath, overWriteDirectory); } foreach (QString fileName, originDirectory.entryList(QDir::Files)) { QFile::copy(url.toLocalFile() + "/" + fileName, destinationDir.toLocalFile() + "/" + fileName); } /*! Possible race-condition mitigation? */ QDir finalDestination(destinationDir.toLocalFile()); finalDestination.refresh(); if(finalDestination.exists()) return true; return false; #else auto job = KIO::copy(url, destinationDir); job->start(); return true; #endif } bool FMStatic::cut(const QUrl &url, const QUrl &where) { return FMStatic::cut(url, where, QString()); } bool FMStatic::cut(const QUrl &url, const QUrl &where, const QString &name) { QUrl _where; if(name.isEmpty()) _where = QUrl(where.toString()+"/"+FMH::getFileInfoModel(url)[FMH::MODEL_KEY::LABEL]); else _where = QUrl(where.toString()+"/"+name); #if defined Q_OS_ANDROID || defined Q_OS_WIN32 QFile file(url.toLocalFile()); file.rename(_where.toLocalFile()); #else auto job = KIO::move(url, _where, KIO::HideProgressInfo); job->start(); #endif #ifdef COMPONENT_TAGGING Tagging::getInstance()->updateUrl(url.toString(), _where.toString()); #endif return true; } bool FMStatic::removeFile(const QUrl &path) { if(!path.isLocalFile()) qWarning() << "URL recived is not a local file, FM::removeFile" << path; qDebug()<< "TRYING TO REMOVE FILE: " << path; #ifdef COMPONENT_TAGGING Tagging::getInstance()->removeUrl(path.toString()); #endif #if defined Q_OS_ANDROID || defined Q_OS_WIN32 if(QFileInfo(path.toLocalFile()).isDir()) return FMStatic::removeDir(path); else return QFile(path.toLocalFile()).remove(); #else auto job = KIO::del(path); job->start(); return true; #endif } void FMStatic::moveToTrash(const QUrl &path) { if(!path.isLocalFile()) qWarning() << "URL recived is not a local file, FM::moveToTrash" << path; #if defined Q_OS_LINUX && !defined Q_OS_ANDROID auto job = KIO::trash(path); job->start(); #endif } void FMStatic::emptyTrash() { #if defined Q_OS_LINUX && !defined Q_OS_ANDROID auto job = KIO::emptyTrash(); job->start(); #endif } bool FMStatic::removeDir(const QUrl &path) { bool result = true; QDir dir(path.toLocalFile()); qDebug()<< "TRYING TO REMOVE DIR" << path << path.toLocalFile(); if (dir.exists()) { Q_FOREACH(QFileInfo info, dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst)) { if (info.isDir()) { result = removeDir(QUrl::fromLocalFile(info.absoluteFilePath())); } else { result = QFile::remove(info.absoluteFilePath()); } if (!result) { return result; } } result = dir.rmdir(path.toLocalFile()); } return result; } bool FMStatic::rename(const QUrl &url, const QString &name) { return FMStatic::cut(url, QUrl(url.toString().left(url.toString().lastIndexOf("/"))), name); } bool FMStatic::createDir(const QUrl &path, const QString &name) { #if defined Q_OS_ANDROID || defined Q_OS_WIN32 QFileInfo dd(path.toLocalFile()); return QDir(path.toLocalFile()).mkdir(name); #else auto job = KIO::mkdir(name.isEmpty() ? path : QUrl(path.toString() + "/" + name)); job->start(); return true; #endif } bool FMStatic::createFile(const QUrl &path, const QString &name) { QFile file(path.toLocalFile() + "/" + name); if(file.open(QIODevice::ReadWrite)) { file.close(); return true; } return false; } bool FMStatic::createSymlink(const QUrl &path, const QUrl &where) { #if defined Q_OS_ANDROID || defined Q_OS_WIN32 return QFile::link(path.toLocalFile(), where.toLocalFile() + "/" + QFileInfo(path.toLocalFile()).fileName()); #else const auto job = KIO::link({path}, where); job->start(); return true; #endif } bool FMStatic::openUrl(const QUrl &url) { #ifdef Q_OS_ANDROID MAUIAndroid::openUrl(url.toString()); return true; #elif defined Q_OS_LINUX // return QDesktopServices::openUrl(QUrl::fromUserInput(url)); return KRun::runUrl(url, FMH::getFileInfoModel(url)[FMH::MODEL_KEY::MIME], nullptr, false, KRun::RunFlag::DeleteTemporaryFiles); #elif defined Q_OS_WIN32 return QDesktopServices::openUrl(url); #endif } void FMStatic::openLocation(const QStringList &urls) { for(const auto &url : urls) QDesktopServices::openUrl(QUrl::fromLocalFile(QFileInfo(url).dir().absolutePath())); } const QVariantMap FMStatic::dirConf(const QUrl &path) { return FMH::dirConf(path); } void FMStatic::setDirConf(const QUrl &path, const QString &group, const QString &key, const QVariant &value) { FMH::setDirConf(path, group, key, value); } bool FMStatic::checkFileType(const int& type, const QString& mimeTypeName) { return FMH::SUPPORTED_MIMETYPES[static_cast(type)].contains(mimeTypeName); } -bool FMStatic::fav(const QUrl& url) +bool FMStatic::toggleFav(const QUrl& url) { - #ifdef COMPONENT_TAGGING if(FMStatic::isFav(url)) - FMStatic::unFav(url); + return FMStatic::unFav(url); - return Tagging::getInstance()->tagUrl(url.toString(), "fav", "#e91e63"); + return FMStatic::fav(url); +} + +bool FMStatic::fav(const QUrl& url) +{ + #ifdef COMPONENT_TAGGING + return Tagging::getInstance()->tagUrl(url.toString(), "fav", "#e91e63"); #endif } bool FMStatic::unFav(const QUrl& url) { #ifdef COMPONENT_TAGGING return Tagging::getInstance()->removeUrlTag(url.toString(), "fav"); #endif } bool FMStatic::isFav(const QUrl& url, const bool &strict) { #ifdef COMPONENT_TAGGING return Tagging::getInstance()->urlTagExists(url.toString(), "fav", strict); #endif } + + diff --git a/src/utils/fmstatic.h b/src/utils/fmstatic.h index 086da19..b015fe7 100644 --- a/src/utils/fmstatic.h +++ b/src/utils/fmstatic.h @@ -1,78 +1,79 @@ #ifndef FMSTATIC_H #define FMSTATIC_H #include #include "fmh.h" #ifndef STATIC_MAUIKIT #include "mauikit_export.h" #endif #ifdef STATIC_MAUIKIT class FMStatic : public QObject #else class MAUIKIT_EXPORT FMStatic : public QObject #endif { Q_OBJECT public: explicit FMStatic(QObject *parent = nullptr); public slots: static FMH::MODEL_LIST search(const QString &query, const QUrl &path, const bool &hidden = false, const bool &onlyDirs = false, const QStringList &filters = QStringList()); static FMH::MODEL_LIST getDevices(); static FMH::MODEL_LIST getDefaultPaths(); static FMH::MODEL_LIST packItems(const QStringList &items, const QString &type); static bool copy(const QUrl &url, const QUrl &destinationDir, const bool &overWriteDirectory = false); static bool cut(const QUrl &url, const QUrl &where); static bool cut(const QUrl &url, const QUrl &where, const QString &name); static bool removeDir(const QUrl &path); static QString formatSize(const int &size); static QString formatTime(const qint64 &value); static QString formatDate(const QString &dateStr, const QString &format = QString("dd/MM/yyyy"), const QString &initFormat = QString()); static QString homePath(); static QUrl parentDir(const QUrl &path); static QVariantMap getDirInfo(const QUrl &path, const QString &type); static QVariantMap getFileInfo(const QUrl &path); static bool isDefaultPath(const QString &path); static bool isDir(const QUrl &path); static bool isApp(const QString &path); static bool isCloud(const QUrl &path); static bool fileExists(const QUrl &path); /** * if the url is a file path then it returns its directory * and if it is a directory returns the same path * */ static QString fileDir(const QUrl &path); /* SETTINGS */ static void saveSettings(const QString &key, const QVariant &value, const QString &group); static QVariant loadSettings(const QString &key, const QString &group, const QVariant &defaultValue); static const QVariantMap dirConf(const QUrl &path); static void setDirConf(const QUrl &path, const QString &group, const QString &key, const QVariant &value); static bool checkFileType(const int &type, const QString &mimeTypeName); static bool removeFile(const QUrl &path); static void moveToTrash(const QUrl &path); static void emptyTrash(); static bool rename(const QUrl &url, const QString &name); static bool createDir(const QUrl &path, const QString &name); static bool createFile(const QUrl &path, const QString &name); static bool createSymlink(const QUrl &path, const QUrl &where); static bool openUrl(const QUrl &url); static void openLocation(const QStringList &urls); static bool isFav(const QUrl &url, const bool &strict = false); static bool unFav(const QUrl &url); static bool fav(const QUrl &url); + static bool toggleFav(const QUrl &url); }; #endif // FMSTATIC_H