diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ca9d0c..c734a66 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,338 +1,341 @@ cmake_minimum_required(VERSION 3.0) set(REQUIRED_QT_VERSION 5.8.0) set(CMAKE_CXX_STANDARD 17) set(MAUIKIT_VERSION 0.0.5) set(CMAKE_AUTOMOC ON) set(AUTOMOC_MOC_OPTIONS -Muri=org.kde.maui) set(CMAKE_INCLUDE_CURRENT_DIR ON) project(mauikit VERSION ${MAUIKIT_VERSION}) find_package(ECM 5.45.0 NO_MODULE) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) include(GenerateExportHeader) include(ECMSetupVersion) include(ECMGenerateHeaders) include(CMakePackageConfigHelpers) include(ECMPoQmTools) include(ECMQMLModules) include(KDEInstallDirs) include(KDECMakeSettings) include(ECMQtDeclareLoggingCategory) include(ECMAddQch) include(KDECompilerSettings NO_POLICY_SCOPE) find_package(Qt5 ${REQUIRED_QT_VERSION} REQUIRED NO_MODULE COMPONENTS Qml Sql Core Quick Gui Svg QuickControls2 Network DBus Xml) ecm_find_qmlmodule(QtGraphicalEffects 1.0) include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/src/utils ${CMAKE_CURRENT_BINARY_DIR}/src/utils + ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/model_template + ${CMAKE_CURRENT_BINARY_DIR}/src/utils/model_template + ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/tagging ${CMAKE_CURRENT_BINARY_DIR}/src/utils/tagging ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/editor ${CMAKE_CURRENT_BINARY_DIR}/src/utils/editor ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/syncing ${CMAKE_CURRENT_BINARY_DIR}/src/utils/syncing ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/store ${CMAKE_CURRENT_BINARY_DIR}/src/utils/store ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/syncing/libwebdavclient/lib ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/syncing/libwebdavclient/lib/utils ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/syncing/libwebdavclient/lib/dto ${CMAKE_CURRENT_SOURCE_DIR}/src/fm ${CMAKE_CURRENT_BINARY_DIR}/src/fm ${CMAKE_CURRENT_SOURCE_DIR}/src/kde ${CMAKE_CURRENT_BINARY_DIR}/src/kde ) set(mauikit_SRCS src/mauikit.cpp src/utils/mauiapp.cpp src/utils/handy.cpp + src/utils/model_template/mauilist.cpp + src/utils/model_template/mauimodel.cpp ) set(mauikit_HDRS src/mauikit.h src/utils.h src/utils/handy.h src/utils/mauiapp.h + src/utils/model_template/mauilist.h + src/utils/model_template/mauimodel.h ) set(editor_SRCS src/utils/editor/documenthandler.cpp ) set(editor_HDRS src/utils/editor/documenthandler.cpp ) set(fm_SRCS src/fm/fm.cpp src/fm/fmdb.cpp src/fm/fmlist.cpp src/fm/placeslist.cpp - src/fm/modellist.cpp - src/fm/basemodel.cpp src/fm/pathlist.cpp ) set(fm_HDRS src/fm/fmh.h src/fm/fm.h src/fm/fmdb.h src/fm/fmlist.h src/fm/placeslist.h - src/fm/modellist.h - src/fm/basemodel.h src/fm/pathlist.h ) set(tagging_SRCS src/utils/tagging/tagging.cpp src/utils/tagging/tagdb.cpp src/utils/tagging/tagsmodel.cpp src/utils/tagging/tagslist.cpp ) set(tagging_HDRS src/utils/tagging/tag.h src/utils/tagging/tagging.h src/utils/tagging/tagdb.h src/utils/tagging/tagsmodel.h src/utils/tagging/tagslist.h ) set(syncing_SRCS src/utils/syncing/syncing.cpp src/utils/syncing/syncingmodel.cpp src/utils/syncing/syncinglist.cpp src/utils/syncing/libwebdavclient/lib/WebDAVClient.cpp src/utils/syncing/libwebdavclient/lib/dto/WebDAVItem.cpp src/utils/syncing/libwebdavclient/lib/utils/Environment.cpp src/utils/syncing/libwebdavclient/lib/utils/NetworkHelper.cpp src/utils/syncing/libwebdavclient/lib/utils/WebDAVReply.cpp src/utils/syncing/libwebdavclient/lib/utils/XMLHelper.cpp ) set(syncing_HDRS src/utils/syncing/syncing.h src/utils/syncing/syncingmodel.h src/utils/syncing/syncinglist.h src/utils/syncing/libwebdavclient/lib/WebDAVClient.hpp src/utils/syncing/libwebdavclient/lib/dto/WebDAVItem.hpp src/utils/syncing/libwebdavclient/lib/utils/Environment.hpp src/utils/syncing/libwebdavclient/lib/utils/NetworkHelper.hpp src/utils/syncing/libwebdavclient/lib/utils/WebDAVReply.hpp src/utils/syncing/libwebdavclient/lib/utils/XMLHelper.hpp ) set(store_SRCS src/utils/store/store.cpp src/utils/store/storemodel.cpp src/utils/store/storelist.cpp ) set(store_HDRS src/utils/store/store.h src/utils/store/storemodel.h src/utils/store/storelist.h ) #use dbus on linux, bsd etc, but not andoid and apple stuff if(ANDROID) find_package(Qt5 REQUIRED COMPONENTS AndroidExtras Xml WebView Network) qt5_add_resources(MauiAndroid_RESOURCES src/android/android.qrc src/android/icons.qrc) set(MAUIANDROID_LIBS Qt5::Xml Qt5::AndroidExtras Qt5::Network Qt5::WebView ) if (NOT EXISTS ${CMAKE_SOURCE_DIR}/src/android/icons/luv-icon-theme/.git) find_package(Git REQUIRED) execute_process(COMMAND ${GIT_EXECUTABLE} clone --depth 1 https://github.com/Nitrux/luv-icon-theme.git ${CMAKE_SOURCE_DIR}/src/android/icons/luv-icon-theme) endif() set(mauikit_Android_SRCS src/android/mauiandroid.cpp ${MauiAndroid_RESOURCES} ${MauiAndroid_icons_RESOURCES} ) else() find_package(Qt5 REQUIRED COMPONENTS WebEngine) find_package(KF5 ${KF5_VERSION} REQUIRED COMPONENTS I18n Notifications Config Service KIO ConfigWidgets Attica) set(mauikit_KDE_SRCS src/kde/mauikde.cpp src/kde/kdeconnect.cpp ) set(mauikit_KDE_HDRS src/kde/mauikde.h src/kde/kdeconnect.h ) set(MAUIKDE_KF5LIBS KF5::ConfigCore KF5::Notifications KF5::I18n KF5::Service KF5::KIOCore KF5::KIOWidgets KF5::KIOFileWidgets KF5::Service KF5::KIONTLM KF5::ConfigWidgets KF5::Attica Qt5::WebEngine ) endif() # set(CMAKE_AUTORCC ON) qt5_add_resources(mauikit_ASSETS ${CMAKE_CURRENT_SOURCE_DIR}/assets.qrc) qt5_add_resources(tagging_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/tagging/tagging.qrc) qt5_add_resources(fm_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/fm/fm.qrc) qt5_add_resources(store_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/store/store.qrc) # qt5_add_resources(mauikit_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/mauikit.qrc) add_library(MauiKit ${fm_HDRS} ${fm_SRCS} ${fm_RESOURCES} ${editor_HDRS} ${editor_SRCS} ${syncing_HDRS} ${syncing_SRCS} ${store_SRCS} ${store_HDRS} ${store_RESOURCES} ${tagging_HDRS} ${tagging_SRCS} ${tagging_RESOURCES} ${mauikit_HDRS} ${mauikit_SRCS} ${mauikit_RESOURCES} ${mauikit_ASSETS} ${mauikit_Android_SRCS} ${mauikit_KDE_HDRS} ${mauikit_KDE_SRCS} ) target_link_libraries(MauiKit PUBLIC Qt5::Core Qt5::Sql Qt5::Qml Qt5::Quick Qt5::QuickControls2 Qt5::Svg Qt5::Gui Qt5::Network Qt5::Xml ${MAUIKDE_KF5LIBS} ${MAUIANDROID_LIBS} # # webdavclient ) if (ANDROID) kde_enable_exceptions(MauiKit PRIVATE) target_include_directories(MauiKit PRIVATE src/android) install(FILES src/android/mauiandroid.h DESTINATION ${KDE_INSTALL_INCLUDEDIR}/MauiKit COMPONENT Devel) install(DIRECTORY src/android/ DESTINATION ${KDE_INSTALL_DATAROOTDIR}/MauiKitAndroid COMPONENT Devel) endif() generate_export_header(MauiKit BASE_NAME MauiKit) install(TARGETS MauiKit EXPORT MauiKitTargets ${INSTALL_TARGETS_DEFAULT_ARGS}) target_include_directories(MauiKit INTERFACE "$") add_custom_target(copy) file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/bin/org/kde/mauikit) add_custom_command(TARGET copy PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/src/controls ${CMAKE_BINARY_DIR}/bin/org/kde/mauikit/) add_dependencies(MauiKit copy) install(DIRECTORY src/controls/ DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/mauikit) install(TARGETS MauiKit DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/mauikit) install(FILES ${mauikit_HDRS} ${mauikit_KDE_HDRS} ${tagging_HDRS} ${fm_HDRS} ${syncing_HDRS} ${store_HDRS} ${CMAKE_CURRENT_BINARY_DIR}/mauikit_export.h DESTINATION ${KDE_INSTALL_INCLUDEDIR}/MauiKit COMPONENT Devel) ##INSTALL MAUI STYLE install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/maui-style DESTINATION ${KDE_INSTALL_QMLDIR}/QtQuick/Controls.2) ##CMAKE PARTS set(CMAKECONFIG_INSTALL_DIR "${KDE_INSTALL_CMAKEPACKAGEDIR}/MauiKit") ecm_setup_version(${MAUIKIT_VERSION} VARIABLE_PREFIX MAUIKIT VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/mauikit_version.h" PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/MauiKitConfigVersion.cmake" SOVERSION 5 ) configure_package_config_file( "${CMAKE_CURRENT_SOURCE_DIR}/MauiKitConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/MauiKitConfig.cmake" INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR} PATH_VARS KF5_INCLUDE_INSTALL_DIR CMAKE_INSTALL_PREFIX ) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/MauiKitConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/MauiKitConfigVersion.cmake" DESTINATION "${CMAKECONFIG_INSTALL_DIR}" COMPONENT Devel ) install(EXPORT MauiKitTargets DESTINATION "${CMAKECONFIG_INSTALL_DIR}" FILE MauiKitTargets.cmake ) diff --git a/src/fm/fmlist.cpp b/src/fm/fmlist.cpp index 9ba060f..c4de226 100644 --- a/src/fm/fmlist.cpp +++ b/src/fm/fmlist.cpp @@ -1,825 +1,825 @@ /* * * Copyright (C) 2018 camilo * * 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 #include #include #include #include #include FMList::FMList(QObject *parent) : -ModelList(parent), +MauiList(parent), fm(new FM(this)), watcher(new QFileSystemWatcher(this)) { connect(this->fm, &FM::cloudServerContentReady, [this](const FMH::MODEL_LIST &list, const QString &url) { if(this->path == url) { this->pre(); this->list = list; this->pathEmpty = this->list.isEmpty(); emit this->pathEmptyChanged(); this->pos(); this->setContentReady(true); } }); connect(this->fm, &FM::warningMessage, [this](const QString &message) { emit this->warning(message); }); connect(this->fm, &FM::loadProgress, [this](const int &percent) { emit this->progress(percent); }); connect(this->watcher, &QFileSystemWatcher::directoryChanged, [this](const QString &path) { Q_UNUSED(path); this->reset(); }); connect(this->fm, &FM::newItem, [this] (const FMH::MODEL &item, const QString &url) { if(this->path == url) { emit this->preItemAppended(); this->list << item; this->pathEmpty = this->list.isEmpty(); emit this->pathEmptyChanged(); emit this->postListChanged(); } }); connect(this, &FMList::pathChanged, this, &FMList::reset); // connect(this, &FMList::hiddenChanged, this, &FMList::setList); // connect(this, &FMList::onlyDirsChanged, this, &FMList::setList); // connect(this, &FMList::filtersChanged, this, &FMList::setList); const auto value = UTIL::loadSettings("SaveDirProps", "SETTINGS", this->saveDirProps).toBool(); this->setSaveDirProps(value); } FMList::~FMList() {} void FMList::pre() { emit this->preListChanged(); // this->setContentReady(false); } void FMList::pos() { // this->setContentReady(true); emit this->postListChanged(); } void FMList::watchPath(const QString& path, const bool& clear) { if(!this->watcher->directories().isEmpty() && clear) this->watcher->removePaths(this->watcher->directories()); if(path.isEmpty() || !FMH::fileExists(path)) return; this->watcher->addPath(path); } void FMList::setList() { this->setContentReady(true); switch(this->pathType) { case FMList::PATHTYPE::PLACES_PATH: this->list.clear(); this->setContentReady(false); this->getPathContent(); return; //ASYNC case FMList::PATHTYPE::SEARCH_PATH: this->list.clear(); this->setContentReady(false); this->search(QString(this->path).right(this->path.length()- 1 - this->path.lastIndexOf("/")), this->searchPath); return; //ASYNC case FMList::PATHTYPE::APPS_PATH: this->list = FM::getAppsContent(this->path); break; case FMList::PATHTYPE::TAGS_PATH: this->list = this->fm->getTagContent(QString(this->path).right(this->path.length()- 1 - this->path.lastIndexOf("/"))); break; case FMList::PATHTYPE::CLOUD_PATH: this->list.clear(); if(this->fm->getCloudServerContent(this->path, this->filters, this->cloudDepth)) { this->setContentReady(false); return; }else break; case FMList::PATHTYPE::TRASH_PATH: case FMList::PATHTYPE::DRIVES_PATH: this->list = FMH::MODEL_LIST(); break; } this->pathEmpty = this->list.isEmpty() && FM::fileExists(this->path); emit this->pathEmptyChanged(); this->sortList(); } void FMList::reset() { this->pre(); switch(this->pathType) { case FMList::PATHTYPE::APPS_PATH: this->hidden = false; this->preview = false; break; case FMList::PATHTYPE::CLOUD_PATH: case FMList::PATHTYPE::SEARCH_PATH: case FMList::PATHTYPE::TAGS_PATH: this->hidden = false; this->preview = true; break; case FMList::PATHTYPE::PLACES_PATH: { if(this->saveDirProps) { auto conf = FMH::dirConf(this->path+"/.directory"); this->hidden = conf[FMH::MODEL_NAME[FMH::MODEL_KEY::HIDDEN]].toBool(); this->preview = conf[FMH::MODEL_NAME[FMH::MODEL_KEY::SHOWTHUMBNAIL]].toBool(); this->foldersFirst = conf[FMH::MODEL_NAME[FMH::MODEL_KEY::FOLDERSFIRST]].toBool(); }else { this->hidden = UTIL::loadSettings("HiddenFilesShown", "SETTINGS", this->hidden).toBool(); this->preview = UTIL::loadSettings("ShowThumbnail", "SETTINGS", this->preview).toBool(); this->foldersFirst = UTIL::loadSettings("FoldersFirst", "SETTINGS", this->foldersFirst).toBool(); } break; } case FMList::PATHTYPE::TRASH_PATH: case FMList::PATHTYPE::DRIVES_PATH: break; } if(this->saveDirProps) { auto conf = FMH::dirConf(this->path+"/.directory"); this->sort = static_cast(conf[FMH::MODEL_NAME[FMH::MODEL_KEY::SORTBY]].toInt()); this->viewType = static_cast(conf[FMH::MODEL_NAME[FMH::MODEL_KEY::VIEWTYPE]].toInt()); }else { this->sort = static_cast(UTIL::loadSettings("SortBy", "SETTINGS", this->sort).toInt()); this->viewType = static_cast(UTIL::loadSettings("ViewType", "SETTINGS", this->viewType).toInt()); } emit this->sortByChanged(); emit this->viewTypeChanged(); emit this->hiddenChanged(); emit this->previewChanged(); this->setList(); this->pos(); } 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; this->pre(); this->sort = key; this->sortList(); if(this->pathType == FMList::PATHTYPE::PLACES_PATH && this->trackChanges && this->saveDirProps) FMH::setDirConf(this->path+"/.directory", "MAUIFM", "SortBy", this->sort); else UTIL::saveSettings("SortBy", this->sort, "SETTINGS"); emit this->sortByChanged(); this->pos(); } void FMList::sortList() { 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(auto item : this->list) if(item[FMH::MODEL_KEY::MIME] == "inode/directory") index++; else break; qSort(this->list.begin(),this->list.begin() + index, [key](const FMH::MODEL& e1, const FMH::MODEL& e2) -> bool { auto role = key; switch(role) { 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; }); } qSort(this->list.begin() + index, this->list.end(), [key](const FMH::MODEL& e1, const FMH::MODEL& e2) -> bool { 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::getPath() const { return this->path; } void FMList::setPath(const QString &path) { if(this->path == path) return; if(this->pathType == FMList::PATHTYPE::PLACES_PATH) this->searchPath = this->path; this->path = path; this->setPreviousPath(this->path); qDebug()<< "Prev History" << this->prevHistory; if(path.startsWith(FMH::PATHTYPE_NAME[FMH::PATHTYPE_KEY::SEARCH_PATH]+"/")) { this->pathExists = true; this->pathType = FMList::PATHTYPE::SEARCH_PATH; emit this->pathExistsChanged(); emit this->pathTypeChanged(); this->watchPath(QString()); }else if(path.startsWith(FMH::PATHTYPE_NAME[FMH::PATHTYPE_KEY::CLOUD_PATH]+"/")) { this->pathExists = true; this->pathType = FMList::PATHTYPE::CLOUD_PATH; emit this->pathExistsChanged(); emit this->pathTypeChanged(); this->watchPath(QString()); }else if(path.startsWith(FMH::PATHTYPE_NAME[FMH::PATHTYPE_KEY::APPS_PATH]+"/")) { this->pathExists = true; this->pathType = FMList::PATHTYPE::APPS_PATH; emit this->pathExistsChanged(); emit this->pathTypeChanged(); this->watchPath(QString()); }else if(path.startsWith(FMH::PATHTYPE_NAME[FMH::PATHTYPE_KEY::TAGS_PATH]+"/")) { this->pathExists = true; this->pathType = FMList::PATHTYPE::TAGS_PATH; emit this->pathExistsChanged(); emit this->pathTypeChanged(); this->watchPath(QString()); }else { this->watchPath(this->path); this->pathExists = FMH::fileExists(this->path); this->pathType = FMList::PATHTYPE::PLACES_PATH; emit this->pathExistsChanged(); 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) { this->filterType = type; this->filters = FMH::FILTER_LIST[static_cast(this->filterType)]; emit this->filtersChanged(); 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+"/.directory", "Settings", "HiddenFilesShown", this->hidden); else UTIL::saveSettings("HiddenFilesShown", this->hidden, "SETTINGS"); emit this->hiddenChanged(); this->reset(); } bool FMList::getPreview() const { return this->preview; } void FMList::setPreview(const bool &state) { if(this->preview == state) return; this->preview = state; if(this->pathType == FMList::PATHTYPE::PLACES_PATH && this->trackChanges && this->saveDirProps) FMH::setDirConf(this->path+"/.directory", "MAUIFM", "ShowThumbnail", this->preview); else UTIL::saveSettings("ShowThumbnail", this->preview, "SETTINGS"); emit this->previewChanged(); } 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 FM::toMap(model); } void FMList::refresh() { emit this->pathChanged(); } void FMList::createDir(const QString& name) { if(this->pathType == FMList::PATHTYPE::PLACES_PATH) this->fm->createDir(this->path, name); else if(this->pathType == FMList::PATHTYPE::CLOUD_PATH) { this->fm->createCloudDir(QString(this->path).replace(FMH::PATHTYPE_NAME[FMH::PATHTYPE_KEY::CLOUD_PATH]+"/"+this->fm->sync->getUser(), ""), name); } } void FMList::copyInto(const QVariantList& files) { if(this->pathType == FMList::PATHTYPE::PLACES_PATH || this->pathType == FMList::PATHTYPE::CLOUD_PATH) this->fm->copy(files, this->path); } void FMList::cutInto(const QVariantList& files) { if(this->pathType == FMList::PATHTYPE::PLACES_PATH) this->fm->cut(files, 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); // } } QString FMList::getParentPath() { switch(this->pathType) { case FMList::PATHTYPE::PLACES_PATH: return FM::parentDir(this->path); default: return this->getPreviousPath(); } } QString FMList::getPosteriorPath() { if(this->postHistory.isEmpty()) return this->path; return this->postHistory.takeAt(this->postHistory.length()-1); } void FMList::setPosteriorPath(const QString& path) { this->postHistory.append(path); } QString FMList::getPreviousPath() { if(this->prevHistory.isEmpty()) return this->path; if(this->prevHistory.length() < 2) return this->prevHistory.at(0); auto post = this->prevHistory.takeAt(this->prevHistory.length()-1); this->setPosteriorPath(post); return this->prevHistory.takeAt(this->prevHistory.length()-1); } void FMList::setPreviousPath(const QString& path) { this->prevHistory.append(path); } bool FMList::getPathEmpty() const { return this->pathEmpty; } bool FMList::getPathExists() const { return this->pathExists; } 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; this->pre(); this->foldersFirst = value; if(this->pathType == FMList::PATHTYPE::PLACES_PATH && this->trackChanges && this->saveDirProps) FMH::setDirConf(this->path+"/.directory", "MAUIFM", "FoldersFirst", this->foldersFirst); else UTIL::saveSettings("FoldersFirst", this->foldersFirst, "SETTINGS"); emit this->foldersFirstChanged(); this->sortList(); this->pos(); } 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::setContentReady(const bool& value) { this->contentReady = value; emit this->contentReadyChanged(); } bool FMList::getContentReady() const { return this->contentReady; } FMList::VIEW_TYPE FMList::getViewType() const { return this->viewType; } void FMList::setViewType(const FMList::VIEW_TYPE& value) { if(this->viewType == value) return; this->viewType = value; if(this->trackChanges && this->saveDirProps) FMH::setDirConf(this->path+"/.directory", "MAUIFM", "ViewType", this->viewType); else UTIL::saveSettings("ViewType", this->viewType, "SETTINGS"); emit this->viewTypeChanged(); } void FMList::search(const QString& query, const QString &path, const bool &hidden, const bool &onlyDirs, const QStringList &filters) { 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) return; emit this->preListChanged(); this->list = res.content; emit this->postListChanged(); emit this->searchResultReady(); this->pathEmpty = this->list.isEmpty() && FM::fileExists(this->path); emit this->pathEmptyChanged(); this->sortList(); this->setContentReady(true); watcher->deleteLater(); }); QFuture t1 = QtConcurrent::run([=]() -> PathContent { PathContent res; res.path = path; FMH::MODEL_LIST content; if (FM::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, filters, dirFilter, QDirIterator::Subdirectories); while (it.hasNext()) { auto url = it.next(); auto info = it.fileInfo(); if(info.completeBaseName().contains(query, Qt::CaseInsensitive)) content << FMH::getFileInfoModel(url); } } res.content = content; return res; }); watcher->setFuture(t1); } void FMList::getPathContent() { qDebug()<< "Getting async path contents"; QFutureWatcher *watcher = new QFutureWatcher; connect(watcher, &QFutureWatcher::finished, [=]() { if(this->pathType != FMList::PATHTYPE::PLACES_PATH) return; const auto res = watcher->future().result(); if(res.path != this->path) return; emit this->preListChanged(); this->list = res.content; this->pathEmpty = this->list.isEmpty() && FM::fileExists(this->path); emit this->pathEmptyChanged(); this->sortList(); emit this->postListChanged(); this->setContentReady(true); watcher->deleteLater(); }); QFuture t1 = QtConcurrent::run([=]() -> PathContent { PathContent res; res.path = this->path; res.content = FM::getPathContent(this->path, this->hidden, this->onlyDirs, this->filters); 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(); } diff --git a/src/fm/fmlist.h b/src/fm/fmlist.h index 16b848b..3e13155 100644 --- a/src/fm/fmlist.h +++ b/src/fm/fmlist.h @@ -1,242 +1,242 @@ /* * * 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 . */ #ifndef FMLIST_H #define FMLIST_H #include #include "fmh.h" -#include "modellist.h" +#include "mauilist.h" struct PathContent { QString path; FMH::MODEL_LIST content; }; class FM; class QFileSystemWatcher; -class FMList : public ModelList +class FMList : public MauiList { Q_OBJECT Q_PROPERTY(QString path READ getPath WRITE setPath NOTIFY pathChanged()) Q_PROPERTY(bool hidden READ getHidden WRITE setHidden NOTIFY hiddenChanged()) Q_PROPERTY(bool onlyDirs READ getOnlyDirs WRITE setOnlyDirs NOTIFY onlyDirsChanged()) Q_PROPERTY(bool preview READ getPreview WRITE setPreview NOTIFY previewChanged()) Q_PROPERTY(FMList::VIEW_TYPE viewType READ getViewType WRITE setViewType NOTIFY viewTypeChanged()) Q_PROPERTY(int cloudDepth READ getCloudDepth WRITE setCloudDepth NOTIFY cloudDepthChanged()) Q_PROPERTY(bool contentReady READ getContentReady NOTIFY contentReadyChanged()) Q_PROPERTY(QStringList filters READ getFilters WRITE setFilters NOTIFY filtersChanged()) Q_PROPERTY(FMList::FILTER filterType READ getFilterType WRITE setFilterType NOTIFY filterTypeChanged()) Q_PROPERTY(FMList::SORTBY sortBy READ getSortBy WRITE setSortBy NOTIFY sortByChanged()) Q_PROPERTY(bool foldersFirst READ getFoldersFirst WRITE setFoldersFirst NOTIFY foldersFirstChanged()) Q_PROPERTY(FMList::PATHTYPE pathType READ getPathType NOTIFY pathTypeChanged()) Q_PROPERTY(bool trackChanges READ getTrackChanges WRITE setTrackChanges NOTIFY trackChangesChanged()) Q_PROPERTY(bool saveDirProps READ getSaveDirProps WRITE setSaveDirProps NOTIFY saveDirPropsChanged()) Q_PROPERTY(bool pathExists READ getPathExists NOTIFY pathExistsChanged()) Q_PROPERTY(bool pathEmpty READ getPathEmpty NOTIFY pathEmptyChanged()) Q_PROPERTY(QString previousPath READ getPreviousPath) Q_PROPERTY(QString posteriorPath READ getPosteriorPath) Q_PROPERTY(QString parentPath READ getParentPath) public: enum SORTBY : uint_fast8_t { SIZE = FMH::MODEL_KEY::SIZE, MODIFIED = FMH::MODEL_KEY::MODIFIED, DATE = FMH::MODEL_KEY::DATE, LABEL = FMH::MODEL_KEY::LABEL, MIME = FMH::MODEL_KEY::MIME, ADDDATE = FMH::MODEL_KEY::MIME, TITLE = FMH::MODEL_KEY::TITLE, PLACE = FMH::MODEL_KEY::PLACE, FORMAT = FMH::MODEL_KEY::FORMAT }; Q_ENUM(SORTBY) enum FILTER : uint_fast8_t { AUDIO = FMH::FILTER_TYPE::AUDIO, VIDEO= FMH::FILTER_TYPE::VIDEO, TEXT = FMH::FILTER_TYPE::TEXT, IMAGE = FMH::FILTER_TYPE::IMAGE, NONE = FMH::FILTER_TYPE::NONE }; Q_ENUM(FILTER) enum PATHTYPE : uint_fast8_t { PLACES_PATH = FMH::PATHTYPE_KEY::PLACES_PATH, REMOTE_PATH = FMH::PATHTYPE_KEY::REMOTE_PATH, DRIVES_PATH = FMH::PATHTYPE_KEY::DRIVES_PATH, REMOVABLE_PATH = FMH::PATHTYPE_KEY::REMOVABLE_PATH, TAGS_PATH = FMH::PATHTYPE_KEY::TAGS_PATH, APPS_PATH = FMH::PATHTYPE_KEY::APPS_PATH, TRASH_PATH = FMH::PATHTYPE_KEY::TRASH_PATH, SEARCH_PATH = FMH::PATHTYPE_KEY::SEARCH_PATH, CLOUD_PATH = FMH::PATHTYPE_KEY::CLOUD_PATH }; Q_ENUM(PATHTYPE) enum VIEW_TYPE : uint_fast8_t { ICON_VIEW, LIST_VIEW, MILLERS_VIEW }; Q_ENUM(VIEW_TYPE) FMList(QObject *parent = nullptr); ~FMList(); FMH::MODEL_LIST items() const override; FMList::SORTBY getSortBy() const; void setSortBy(const FMList::SORTBY &key); QString getPath() const; void setPath(const QString &path); FMList::PATHTYPE getPathType() const; QStringList getFilters() const; void setFilters(const QStringList &filters); FMList::FILTER getFilterType() const; void setFilterType(const FMList::FILTER &type); bool getHidden() const; void setHidden(const bool &state); bool getPreview() const; void setPreview(const bool &state); bool getOnlyDirs() const; void setOnlyDirs(const bool &state); QString getParentPath(); QString getPreviousPath(); void setPreviousPath(const QString &path); QString getPosteriorPath(); void setPosteriorPath(const QString &path); bool getPathEmpty() const; bool getPathExists() const; bool getTrackChanges() const; void setTrackChanges(const bool &value); bool getFoldersFirst() const; void setFoldersFirst(const bool &value); bool getSaveDirProps() const; void setSaveDirProps(const bool &value); bool getContentReady() const; void setContentReady(const bool &value); VIEW_TYPE getViewType() const; void setViewType(const VIEW_TYPE &value); int getCloudDepth() const; void setCloudDepth(const int &value); private: FM *fm; QFileSystemWatcher *watcher; void pre(); void pos(); void reset(); void setList(); void sortList(); void watchPath(const QString &path, const bool &clear = true); void search(const QString &query, const QString &path, const bool &hidden = false, const bool &onlyDirs = false, const QStringList &filters = QStringList()); void getPathContent(); FMH::MODEL_LIST list = {{}}; QString path = QString(); QStringList filters = {}; bool onlyDirs = false; bool hidden = false; bool preview = false; bool pathExists = false; bool pathEmpty = true; bool trackChanges = true; bool foldersFirst = false; bool saveDirProps = false; bool contentReady = false; int cloudDepth = 1; QString searchPath; VIEW_TYPE viewType = VIEW_TYPE::ICON_VIEW; FMList::SORTBY sort = FMList::SORTBY::MODIFIED; FMList::FILTER filterType = FMList::FILTER::NONE; FMList::PATHTYPE pathType = FMList::PATHTYPE::PLACES_PATH; QStringList prevHistory = {}; QStringList postHistory = {}; public slots: QVariantMap get(const int &index) const; void refresh(); void createDir(const QString &name); void copyInto(const QVariantList &files); void cutInto(const QVariantList &files); signals: void pathChanged(); void pathTypeChanged(); void filtersChanged(); void filterTypeChanged(); void hiddenChanged(); void previewChanged(); void onlyDirsChanged(); void sortByChanged(); void trackChangesChanged(); void foldersFirstChanged(); void saveDirPropsChanged(); void contentReadyChanged(); void viewTypeChanged(); void cloudDepthChanged(); void pathEmptyChanged(); void pathExistsChanged(); void warning(QString message); void progress(int percent); void searchResultReady(); }; #endif // FMLIST_H diff --git a/src/fm/pathlist.cpp b/src/fm/pathlist.cpp index c023e0d..a1d2f5a 100644 --- a/src/fm/pathlist.cpp +++ b/src/fm/pathlist.cpp @@ -1,92 +1,92 @@ /* * * Copyright (C) 2019 camilo * * 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 "pathlist.h" #include "fm.h" -PathList::PathList(QObject *parent) : ModelList(parent) +PathList::PathList(QObject *parent) : MauiList(parent) { connect(this, &PathList::pathChanged, [&]() { if(!this->list.isEmpty() && FM::parentDir(this->m_path) == this->list.last()[FMH::MODEL_KEY::PATH]) { // qDebug() << "APPENDING PATHS TO MODEL << "<< FM::parentDir(this->m_path) << this->list.last()[FMH::MODEL_KEY::PATH]; emit this->preItemAppended(); this->list << FMH::getDirInfoModel(this->m_path); emit this->postItemAppended(); }else{ emit this->preListChanged(); this->list.clear(); this->list << PathList::splitPath(this->m_path); emit this->postListChanged(); } }); } PathList::~PathList() {} QVariantMap PathList::get(const int& index) const { if(this->list.isEmpty()) return QVariantMap(); if(index >= this->list.size() || index < 0) return QVariantMap(); const auto model = this->list.at(index); return FM::toMap(model); } QString PathList::getPath() const { return this->m_path; } FMH::MODEL_LIST PathList::items() const { return this->list; } void PathList::setPath(const QString& path) { if(path == this->m_path) return; this->m_path = path; emit this->pathChanged(); } FMH::MODEL_LIST PathList::splitPath(const QString& path) { const auto paths = path.split("/", QString::SplitBehavior::SkipEmptyParts); return std::accumulate(paths.constBegin(), paths.constEnd(), FMH::MODEL_LIST(), [](FMH::MODEL_LIST &list, const QString &part) -> FMH::MODEL_LIST { const auto url = list.isEmpty() ? QString("/"+part) : list.last()[FMH::MODEL_KEY::PATH] + QString("/"+part); if(!url.isEmpty()) list << (FMH::fileExists(url) ? FMH::getDirInfoModel(url) : FMH::MODEL { {FMH::MODEL_KEY::LABEL, part}, {FMH::MODEL_KEY::PATH, url} }); return list; }); } diff --git a/src/fm/pathlist.h b/src/fm/pathlist.h index 3eeea1f..86e3e5a 100644 --- a/src/fm/pathlist.h +++ b/src/fm/pathlist.h @@ -1,54 +1,54 @@ /* * * Copyright (C) 2019 camilo * * 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 . */ #ifndef PATHLIST_H #define PATHLIST_H -#include "modellist.h" +#include "mauilist.h" /** * @todo write docs */ -class PathList : public ModelList +class PathList : public MauiList { Q_OBJECT Q_PROPERTY(QString path READ getPath WRITE setPath NOTIFY pathChanged) public: PathList(QObject *parent = nullptr); ~PathList(); FMH::MODEL_LIST items() const override; void setPath(const QString &path); QString getPath() const; private: FMH::MODEL_LIST list; QString m_path; static FMH::MODEL_LIST splitPath(const QString &path); public slots: QVariantMap get(const int &index) const; signals: void pathChanged(); }; #endif // PATHLIST_H diff --git a/src/fm/placeslist.cpp b/src/fm/placeslist.cpp index 8eda525..5e1f355 100644 --- a/src/fm/placeslist.cpp +++ b/src/fm/placeslist.cpp @@ -1,254 +1,254 @@ /* * * Copyright (C) 2018 camilo * * 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 "placeslist.h" #include "fm.h" #include #include #include #include #ifdef Q_OS_ANDROID #else #include #endif #ifdef Q_OS_ANDROID -PlacesList::PlacesList(QObject *parent) : ModelList(parent), +PlacesList::PlacesList(QObject *parent) : MauiList(parent), fm(new FM(this)), model(nullptr), watcher(new QFileSystemWatcher(this)) #else -PlacesList::PlacesList(QObject *parent) : ModelList(parent), +PlacesList::PlacesList(QObject *parent) : MauiList(parent), fm(new FM(this)), model(new KFilePlacesModel(this)), watcher(new QFileSystemWatcher(this)) #endif { connect(watcher, &QFileSystemWatcher::directoryChanged, [this](const QString &path) { if(this->count.contains(path)) { const auto oldCount = this->count[path]; const auto index = this->indexOf(path); const auto newCount = FMH::getFileInfoModel(path)[FMH::MODEL_KEY::COUNT].toInt(); const auto count = newCount - oldCount; this->list[index][FMH::MODEL_KEY::COUNT] = QString::number(count); emit this->updateModel(index, {FMH::MODEL_KEY::COUNT}); } }); connect(fm, &FM::cloudAccountInserted, this, &PlacesList::reset); connect(fm, &FM::cloudAccountRemoved, this, &PlacesList::reset); connect(this, &PlacesList::groupsChanged, this, &PlacesList::reset); this->setList(); } void PlacesList::watchPath(const QString& path) { if(path.isEmpty() || !FMH::fileExists(path)) return; this->watcher->addPath(path); } PlacesList::~PlacesList() {} FMH::MODEL_LIST PlacesList::items() const { return this->list; } #ifdef Q_OS_ANDROID #else static FMH::MODEL modelPlaceInfo(const KFilePlacesModel &model, const QModelIndex &index, const FMH::PATHTYPE_KEY &type) { return FMH::MODEL { {FMH::MODEL_KEY::PATH, model.url(index).toString().replace("file://", "")}, {FMH::MODEL_KEY::URL, model.url(index).toString().replace("file://", "")}, {FMH::MODEL_KEY::ICON, model.icon(index).name()}, {FMH::MODEL_KEY::LABEL, model.text(index)}, {FMH::MODEL_KEY::NAME, model.text(index)}, {FMH::MODEL_KEY::TYPE, FMH::PATHTYPE_NAME[type]} }; } #endif static FMH::MODEL_LIST getGroup(const KFilePlacesModel &model, const FMH::PATHTYPE_KEY &type) { #ifdef Q_OS_ANDROID //do android stuff until cmake works with android return FMH::MODEL_LIST(); #else const auto group = model.groupIndexes(static_cast(type)); return std::accumulate(group.begin(), group.end(), FMH::MODEL_LIST(), [&model, &type](FMH::MODEL_LIST &list, const QModelIndex &index) -> FMH::MODEL_LIST { list << modelPlaceInfo(model, index, type); return list; }); #endif } void PlacesList::setList() { this->list.clear(); for(const auto &group : this->groups) switch(group) { case FMH::PATHTYPE_KEY::PLACES_PATH: this->list << getGroup(*this->model, FMH::PATHTYPE_KEY::PLACES_PATH); break; case FMH::PATHTYPE_KEY::APPS_PATH: this->list << FM::getAppsPath(); break; case FMH::PATHTYPE_KEY::DRIVES_PATH: this->list << getGroup(*this->model, FMH::PATHTYPE_KEY::DRIVES_PATH); break; case FMH::PATHTYPE_KEY::REMOTE_PATH: this->list << getGroup(*this->model, FMH::PATHTYPE_KEY::REMOTE_PATH); break; case FMH::PATHTYPE_KEY::REMOVABLE_PATH: this->list << getGroup(*this->model, FMH::PATHTYPE_KEY::REMOVABLE_PATH); break; case FMH::PATHTYPE_KEY::TAGS_PATH: this->list << this->fm->getTags(); break; case FMH::PATHTYPE_KEY::CLOUD_PATH: this->list << this->fm->getCloudAccounts(); break; } this->setCount(); } void PlacesList::setCount() { this->watcher->removePaths(this->watcher->directories()); for(auto &data : this->list) { const auto path = data[FMH::MODEL_KEY::PATH]; if(FM::isDir(path)) { data.insert(FMH::MODEL_KEY::COUNT, "0"); const auto count = FMH::getFileInfoModel(path)[FMH::MODEL_KEY::COUNT]; this->count.insert(path, count.toInt()); this->watchPath(path); } } } int PlacesList::indexOf(const QString& path) { const auto index = std::find_if(this->list.begin(), this->list.end(), [&path](const FMH::MODEL &item) -> bool { return item[FMH::MODEL_KEY::PATH] == path; }); return std::distance(this->list.begin(), index); } void PlacesList::reset() { emit this->preListChanged(); this->setList(); emit this->postListChanged(); } QList PlacesList::getGroups() const { return this->groups; } void PlacesList::setGroups(const QList &value) { if(this->groups == value) return; this->groups = value; emit this->groupsChanged(); } QVariantMap PlacesList::get(const int& index) const { if(index >= this->list.size() || index < 0) return QVariantMap(); const auto model = this->list.at(index); return FM::toMap(model); } void PlacesList::refresh() { this->reset(); } void PlacesList::clearBadgeCount(const int& index) { this->list[index][FMH::MODEL_KEY::COUNT] = "0"; emit this->updateModel(index, {FMH::MODEL_KEY::COUNT}); } void PlacesList::addPlace(const QString& path) { const auto it = std::find_if(this->list.rbegin(), this->list.rend(), [](const FMH::MODEL &item) -> bool{ return item[FMH::MODEL_KEY::TYPE] == FMH::PATHTYPE_NAME[FMH::PATHTYPE_KEY::PLACES_PATH]; }); const auto index = std::distance(it, this->list.rend()); qDebug()<< "trying to add path to places" << path<< QDir(path).dirName(); emit this->preItemAppendedAt(index); const auto url = QStringLiteral("file://")+path; #ifdef Q_OS_ANDROID //do android stuff until cmake works with android #else this->model->addPlace(QDir(path).dirName(), url); this->list.insert(index, modelPlaceInfo(*this->model, this->model->closestItem(QUrl(url)), FMH::PATHTYPE_KEY::PLACES_PATH)); #endif emit this->postItemAppended(); } void PlacesList::removePlace(const int& index) { emit this->preItemRemoved(index); #ifdef Q_OS_ANDROID //do android stuff until cmake works with android #else this->model->removePlace(this->model->index(index, 0)); #endif this->list.removeAt(index); emit this->postItemRemoved(); } diff --git a/src/fm/placeslist.h b/src/fm/placeslist.h index 3cd1323..178dcc7 100644 --- a/src/fm/placeslist.h +++ b/src/fm/placeslist.h @@ -1,70 +1,70 @@ /* * * Copyright (C) 2018 camilo * * 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 . */ #ifndef PLACESLIST_H #define PLACESLIST_H #include -#include "modellist.h" +#include "mauilist.h" class FM; class KFilePlacesModel; class QFileSystemWatcher; -class PlacesList : public ModelList +class PlacesList : public MauiList { Q_OBJECT Q_PROPERTY(QList groups READ getGroups WRITE setGroups NOTIFY groupsChanged()) public: PlacesList(QObject *parent = nullptr); ~PlacesList(); FMH::MODEL_LIST items() const override; QList getGroups() const; void setGroups(const QList &value); protected: void setList(); void reset(); public slots: QVariantMap get(const int &index) const; void refresh(); void clearBadgeCount(const int &index); void addPlace(const QString &path); void removePlace(const int &index); private: FM *fm; FMH::MODEL_LIST list; KFilePlacesModel *model; QHash count; QList groups; QFileSystemWatcher *watcher; void watchPath(const QString &path); void setCount(); int indexOf(const QString &path); signals: void groupsChanged(); }; #endif // PLACESLIST_H diff --git a/src/mauikit.cpp b/src/mauikit.cpp index 4dec7f5..d27968c 100644 --- a/src/mauikit.cpp +++ b/src/mauikit.cpp @@ -1,175 +1,175 @@ /* * Copyright 2018 Camilo Higuita * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, 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 Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "mauikit.h" #include #include #include "fm.h" #include "fmh.h" -#include "basemodel.h" -#include "modellist.h" +#include "mauimodel.h" +#include "mauilist.h" #include "placeslist.h" #include "fmlist.h" #include "pathlist.h" #include "syncingmodel.h" #include "syncinglist.h" #include "tagsmodel.h" #include "tagslist.h" #include "storemodel.h" #include "storelist.h" #include "handy.h" #include "documenthandler.h" #include "mauiapp.h" #ifdef Q_OS_ANDROID #include "mauiandroid.h" #include #else #include "mauikde.h" #endif QUrl MauiKit::componentUrl(const QString &fileName) const { #ifdef MAUI_APP return QUrl(QStringLiteral("qrc:/maui/kit/") + fileName); #else return QUrl(resolveFileUrl(fileName)); #endif } void MauiKit::registerTypes(const char *uri) { Q_ASSERT(uri == QLatin1String("org.kde.mauikit")); qmlRegisterSingletonType(componentUrl(QStringLiteral("Style.qml")), uri, 1, 0, "Style"); qmlRegisterType(componentUrl(QStringLiteral("ToolBar.qml")), uri, 1, 0, "ToolBar"); qmlRegisterType(componentUrl(QStringLiteral("ApplicationWindow.qml")), uri, 1, 0, "ApplicationWindow"); qmlRegisterType(componentUrl(QStringLiteral("Page.qml")), uri, 1, 0, "Page"); qmlRegisterType(componentUrl(QStringLiteral("ShareDialog.qml")), uri, 1, 0, "ShareDialog"); qmlRegisterType(componentUrl(QStringLiteral("PieButton.qml")), uri, 1, 0, "PieButton"); qmlRegisterType(componentUrl(QStringLiteral("SideBar.qml")), uri, 1, 0, "SideBar"); qmlRegisterType(componentUrl(QStringLiteral("Holder.qml")), uri, 1, 0, "Holder"); qmlRegisterType(componentUrl(QStringLiteral("Drawer.qml")), uri, 1, 0, "Drawer"); qmlRegisterType(componentUrl(QStringLiteral("GlobalDrawer.qml")), uri, 1, 0, "GlobalDrawer"); qmlRegisterType(componentUrl(QStringLiteral("ListDelegate.qml")), uri, 1, 0, "ListDelegate"); qmlRegisterType(componentUrl(QStringLiteral("SelectionBar.qml")), uri, 1, 0, "SelectionBar"); qmlRegisterType(componentUrl(QStringLiteral("IconDelegate.qml")), uri, 1, 0, "IconDelegate"); qmlRegisterType(componentUrl(QStringLiteral("LabelDelegate.qml")), uri, 1, 0, "LabelDelegate"); qmlRegisterType(componentUrl(QStringLiteral("NewDialog.qml")), uri, 1, 0, "NewDialog"); qmlRegisterType(componentUrl(QStringLiteral("Dialog.qml")), uri, 1, 0, "Dialog"); qmlRegisterType(componentUrl(QStringLiteral("AboutDialog.qml")), uri, 1, 0, "AboutDialog"); qmlRegisterType(componentUrl(QStringLiteral("Popup.qml")), uri, 1, 0, "Popup"); qmlRegisterType(componentUrl(QStringLiteral("TextField.qml")), uri, 1, 0, "TextField"); qmlRegisterType(componentUrl(QStringLiteral("SearchBar.qml")), uri, 1, 0, "SearchBar"); qmlRegisterType(componentUrl(QStringLiteral("TagsBar.qml")), uri, 1, 0, "TagsBar"); qmlRegisterType(componentUrl(QStringLiteral("TagsDialog.qml")), uri, 1, 0, "TagsDialog"); qmlRegisterType(componentUrl(QStringLiteral("Badge.qml")), uri, 1, 0, "Badge"); qmlRegisterType(componentUrl(QStringLiteral("GridView.qml")), uri, 1, 0, "GridView"); qmlRegisterType(componentUrl(QStringLiteral("ColorsBar.qml")), uri, 1, 0, "ColorsBar"); qmlRegisterType(componentUrl(QStringLiteral("ComboBox.qml")), uri, 1, 0, "ComboBox"); qmlRegisterType(componentUrl(QStringLiteral("ImageViewer.qml")), uri, 1, 0, "ImageViewer"); qmlRegisterType(componentUrl(QStringLiteral("private/TagList.qml")), uri, 1, 0, "TagList"); /** STORE CONTROLS **/ qmlRegisterType(componentUrl(QStringLiteral("private/StoreDelegate.qml")), uri, 1, 0, "StoreDelegate"); qmlRegisterType(componentUrl(QStringLiteral("Store.qml")), uri, 1, 0, "Store"); /** BROWSING CONTROLS **/ qmlRegisterType(componentUrl(QStringLiteral("ListBrowser.qml")), uri, 1, 0, "ListBrowser"); qmlRegisterType(componentUrl(QStringLiteral("GridBrowser.qml")), uri, 1, 0, "GridBrowser"); /** FM CONTROLS **/ qmlRegisterType(componentUrl(QStringLiteral("FileBrowser.qml")), uri, 1, 0, "FileBrowser"); qmlRegisterType(componentUrl(QStringLiteral("PlacesSidebar.qml")), uri, 1, 0, "PlacesSidebar"); qmlRegisterType(componentUrl(QStringLiteral("FilePreviewer.qml")), uri, 1, 0, "FilePreviewer"); qmlRegisterType(componentUrl(QStringLiteral("FileDialog.qml")), uri, 1, 0, "FileDialog"); qmlRegisterType(componentUrl(QStringLiteral("PathBar.qml")), uri, 1, 0, "PathBar"); qmlRegisterType(componentUrl(QStringLiteral("SyncDialog.qml")), uri, 1, 0, "SyncDialog"); qmlRegisterType(componentUrl(QStringLiteral("SyncDialog.qml")), uri, 1, 0, "SyncDialog"); /** EDITOR CONTROLS **/ qmlRegisterType(componentUrl(QStringLiteral("Editor.qml")), uri, 1, 0, "Editor"); #ifdef Q_OS_ANDROID qmlRegisterSingletonType(uri, 1, 0, "Android", [](QQmlEngine*, QJSEngine*) -> QObject* { MAUIAndroid *android = new MAUIAndroid; return android; }); #else qmlRegisterType(componentUrl(QStringLiteral("Terminal.qml")), uri, 1, 0, "Terminal"); qmlRegisterSingletonType(uri, 1, 0, "KDE", [](QQmlEngine*, QJSEngine*) -> QObject* { MAUIKDE *kde = new MAUIKDE; return kde; }); #endif - qmlRegisterType(uri, 1, 0, "BaseModel"); //BASE MODEL - qmlRegisterUncreatableType(uri, 1, 0, "ModelList", QStringLiteral("ModelList should not be created in QML")); + qmlRegisterType(uri, 1, 0, "BaseModel"); //BASE MODEL + qmlRegisterUncreatableType(uri, 1, 0, "ModelList", QStringLiteral("ModelList should not be created in QML")); qmlRegisterType(uri, 1, 0, "PlacesList"); qmlRegisterType(uri, 1, 0, "FMList"); qmlRegisterType(uri, 1, 0, "PathList"); qmlRegisterType("SyncingList", 1, 0, "SyncingList"); qmlRegisterType("SyncingModel", 1, 0, "SyncingModel"); qmlRegisterType("TagsList", 1, 0, "TagsList"); qmlRegisterType("TagsModel", 1, 0, "TagsModel"); qmlRegisterType("StoreList", 1, 0, "StoreList"); qmlRegisterType("StoreModel", 1, 0, "StoreModel"); // qmlRegisterType(uri, 1, 0, "App"); qmlRegisterType("DocumentHandler", 1, 0, "DocumentHandler"); qmlRegisterSingletonType(uri, 1, 0, "FM", [](QQmlEngine*, QJSEngine*) -> QObject* { auto fm = new FM(); return fm; }); qmlRegisterSingletonType(uri, 1, 0, "Handy", [](QQmlEngine*, QJSEngine*) -> QObject* { auto handy = new Handy; return handy; }); #ifdef Q_OS_ANDROID QIcon::setThemeSearchPaths({":/icons/luv-icon-theme"}); QIcon::setThemeName("Luv"); QQuickStyle::setStyle(":/style"); // #else // QQuickStyle::setStyle("maui-style"); #endif qmlProtectModule(uri, 1); } diff --git a/src/fm/modellist.cpp b/src/utils/model_template/mauilist.cpp similarity index 88% rename from src/fm/modellist.cpp rename to src/utils/model_template/mauilist.cpp index 40ab211..3cc44b8 100644 --- a/src/fm/modellist.cpp +++ b/src/utils/model_template/mauilist.cpp @@ -1,27 +1,27 @@ /* * * Copyright (C) 2019 camilo * * 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 "modellist.h" +#include "mauilist.h" -ModelList::ModelList(QObject *parent) : QObject(parent) +MauiList::MauiList(QObject *parent) : QObject(parent) { } -ModelList::~ModelList() +MauiList::~MauiList() { } diff --git a/src/fm/modellist.h b/src/utils/model_template/mauilist.h similarity index 88% rename from src/fm/modellist.h rename to src/utils/model_template/mauilist.h index 7ad8989..9d1af1d 100644 --- a/src/fm/modellist.h +++ b/src/utils/model_template/mauilist.h @@ -1,53 +1,53 @@ /* * * Copyright (C) 2019 camilo * * 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 . */ -#ifndef MODELLIST_H -#define MODELLIST_H +#ifndef MAUILIST_H +#define MAUILIST_H #include "fmh.h" /** * @todo write docs */ #include -class ModelList : public QObject +class MauiList : public QObject { Q_OBJECT public: /** * Default constructor */ - explicit ModelList(QObject *parent = nullptr); - ~ModelList(); + explicit MauiList(QObject *parent = nullptr); + ~MauiList(); virtual FMH::MODEL_LIST items() const {return FMH::MODEL_LIST();}; signals: void preItemAppended(); void postItemAppended(); void preItemAppendedAt(int index); void preItemRemoved(int index); void postItemRemoved(); void updateModel(int index, QVector roles); void preListChanged(); void postListChanged(); }; -#endif // MODELLIST_H +#endif // MAUILIST_H diff --git a/src/fm/basemodel.cpp b/src/utils/model_template/mauimodel.cpp similarity index 66% rename from src/fm/basemodel.cpp rename to src/utils/model_template/mauimodel.cpp index 1b9e472..a61e7b8 100644 --- a/src/fm/basemodel.cpp +++ b/src/utils/model_template/mauimodel.cpp @@ -1,132 +1,132 @@ /* * * Copyright (C) 2019 camilo * * 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 "basemodel.h" -#include "modellist.h" +#include "mauimodel.h" +#include "mauilist.h" -BaseModel::~BaseModel() +MauiModel::~MauiModel() { } -BaseModel::BaseModel(QObject *parent) +MauiModel::MauiModel(QObject *parent) : QAbstractListModel(parent), list(nullptr) {} -int BaseModel::rowCount(const QModelIndex &parent) const +int MauiModel::rowCount(const QModelIndex &parent) const { if (parent.isValid() || !list) return 0; return list->items().size(); } -QVariant BaseModel::data(const QModelIndex &index, int role) const +QVariant MauiModel::data(const QModelIndex &index, int role) const { if (!index.isValid() || !list) return QVariant(); return list->items().at(index.row())[static_cast(role)]; } -bool BaseModel::setData(const QModelIndex &index, const QVariant &value, int role) +bool MauiModel::setData(const QModelIndex &index, const QVariant &value, int role) { Q_UNUSED(index); Q_UNUSED(value); Q_UNUSED(role); return false; } -Qt::ItemFlags BaseModel::flags(const QModelIndex &index) const +Qt::ItemFlags MauiModel::flags(const QModelIndex &index) const { if (!index.isValid()) return Qt::NoItemFlags; return Qt::ItemIsEditable; // FIXME: Implement me! } -QHash BaseModel::roleNames() const +QHash MauiModel::roleNames() const { QHash names; for(auto key : FMH::MODEL_NAME.keys()) names[key] = QString(FMH::MODEL_NAME[key]).toUtf8(); return names; } -ModelList *BaseModel::getList() const +MauiList *MauiModel::getList() const { return this->list; } -void BaseModel::setList(ModelList *value) +void MauiModel::setList(MauiList *value) { beginResetModel(); if(list) list->disconnect(this); list = value; if(list) { - connect(this->list, &ModelList::preItemAppendedAt, this, [=](int index) + connect(this->list, &MauiList::preItemAppendedAt, this, [=](int index) { beginInsertRows(QModelIndex(), index, index); }); - connect(this->list, &ModelList::preItemAppended, this, [=]() + connect(this->list, &MauiList::preItemAppended, this, [=]() { const int index = list->items().size(); beginInsertRows(QModelIndex(), index, index); }); - connect(this->list, &ModelList::postItemAppended, this, [=]() + connect(this->list, &MauiList::postItemAppended, this, [=]() { endInsertRows(); }); - connect(this->list, &ModelList::preItemRemoved, this, [=](int index) + connect(this->list, &MauiList::preItemRemoved, this, [=](int index) { beginRemoveRows(QModelIndex(), index, index); }); - connect(this->list, &ModelList::postItemRemoved, this, [=]() + connect(this->list, &MauiList::postItemRemoved, this, [=]() { endRemoveRows(); }); - connect(this->list, &ModelList::updateModel, this, [=](int index, QVector roles) + connect(this->list, &MauiList::updateModel, this, [=](int index, QVector roles) { emit this->dataChanged(this->index(index), this->index(index), roles); }); - connect(this->list, &ModelList::preListChanged, this, [=]() + connect(this->list, &MauiList::preListChanged, this, [=]() { beginResetModel(); }); - connect(this->list, &ModelList::postListChanged, this, [=]() + connect(this->list, &MauiList::postListChanged, this, [=]() { endResetModel(); }); } endResetModel(); } diff --git a/src/fm/basemodel.h b/src/utils/model_template/mauimodel.h similarity index 80% rename from src/fm/basemodel.h rename to src/utils/model_template/mauimodel.h index c1caa25..7a19e5e 100644 --- a/src/fm/basemodel.h +++ b/src/utils/model_template/mauimodel.h @@ -1,57 +1,57 @@ /* * * Copyright (C) 2019 camilo * * 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 . */ -#ifndef BASEMODEL_H -#define BASEMODEL_H +#ifndef MAUIMODEL_H +#define MAUIMODEL_H #include #include #include -class ModelList; -class BaseModel : public QAbstractListModel +class MauiList; +class MauiModel : public QAbstractListModel { Q_OBJECT - Q_PROPERTY(ModelList *list READ getList WRITE setList) + Q_PROPERTY(MauiList *list READ getList WRITE setList) public: - BaseModel(QObject *parent = nullptr); - ~BaseModel(); + MauiModel(QObject *parent = nullptr); + ~MauiModel(); int rowCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; // Editable: bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; Qt::ItemFlags flags(const QModelIndex& index) const override; virtual QHash roleNames() const override; - ModelList* getList() const; - void setList(ModelList *value); + MauiList* getList() const; + void setList(MauiList *value); private: - ModelList *list; + MauiList *list; signals: void listChanged(); }; -#endif // BASEMODEL_H +#endif // MAUIMODEL_H