Warning, file /maui/mauikit-filebrowsing/src/code/placeslist.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 <email>
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 "placeslist.h"
0020 #include "tagging.h"
0021 
0022 #include <QDir>
0023 #include <QDebug>
0024 #include <QIcon>
0025 #include <QSettings>
0026 
0027 #ifdef KIO_AVAILABLE
0028 #include <KFilePlacesModel>
0029 #include <Solid/Device>
0030 #endif
0031 
0032 #include <KLocalizedString>
0033 
0034 #ifdef KIO_AVAILABLE
0035 int mapPathType(const FMStatic::PATHTYPE_KEY& value)
0036 {
0037     switch(value)
0038     {
0039         case FMStatic::PLACES_PATH: return KFilePlacesModel::GroupType::PlacesType;
0040         case FMStatic::REMOTE_PATH: return KFilePlacesModel::GroupType::RemoteType;
0041         case FMStatic::DRIVES_PATH: return KFilePlacesModel::GroupType::DevicesType;
0042         case FMStatic::REMOVABLE_PATH: return KFilePlacesModel::GroupType::RemovableDevicesType;
0043         case FMStatic::TAGS_PATH: return KFilePlacesModel::GroupType::TagsType;
0044         case FMStatic::UNKNOWN_TYPE: return KFilePlacesModel::GroupType::UnknownType;
0045         default: return value;
0046     }
0047 }
0048 #endif
0049 
0050 
0051 #ifdef KIO_AVAILABLE
0052 PlacesList::PlacesList(QObject *parent)
0053 : MauiList(parent)
0054 , model(new KFilePlacesModel(this))
0055 #else
0056 PlacesList::PlacesList(QObject *parent)
0057 : MauiList(parent)
0058 , model(nullptr)
0059 #endif
0060 {    
0061     #ifdef KIO_AVAILABLE
0062     connect(this->model, &KFilePlacesModel::reloaded, this, &PlacesList::setList);
0063     
0064     connect(this->model, &KFilePlacesModel::setupDone, this, &PlacesList::setList);
0065     
0066     connect(this->model, &KFilePlacesModel::rowsInserted, [this](const QModelIndex, int, int) 
0067     {
0068         this->setList();
0069         Q_EMIT this->bookmarksChanged();
0070         
0071         /*Q_EMIT this->preListChanged();
0072          * 
0073          *        for (int i = first; i <= last; i++)
0074          *        {
0075          *            const QModelIndex index = model->index(i, 0);
0076          * 
0077          *            if(this->groups.contains(model->groupType(index)))
0078          *            {
0079          *                this->list << getGroup(*this->model, static_cast<FMH::PATHTYPE_KEY>(model->groupType(index)));
0080     }
0081     }
0082     Q_EMIT this->postListChanged(); */
0083     }); // TODO improve the usage of the model
0084     #endif
0085 }
0086 
0087 void PlacesList::componentComplete()
0088 {
0089     connect(this, &PlacesList::groupsChanged, this, &PlacesList::setList);
0090     this->setList();
0091 }
0092 
0093 const FMH::MODEL_LIST &PlacesList::items() const
0094 {
0095     return this->list;
0096 }
0097 
0098 FMH::MODEL_LIST PlacesList::getGroup(const KFilePlacesModel &model, const FMStatic::PATHTYPE_KEY &type)
0099 {
0100     FMH::MODEL_LIST res;
0101     
0102     if (type == FMStatic::PATHTYPE_KEY::QUICK_PATH) 
0103     {
0104         res << FMH::MODEL {{FMH::MODEL_KEY::PATH, FMStatic::PATHTYPE_URI[FMStatic::PATHTYPE_KEY::TAGS_PATH] + QStringLiteral("fav")}, {FMH::MODEL_KEY::ICON, QStringLiteral("love")}, {FMH::MODEL_KEY::LABEL, i18n("Favorite")}, {FMH::MODEL_KEY::TYPE, QStringLiteral("Quick")}};
0105         
0106         // #ifdef KIO_AVAILABLE
0107         //     res << FMH::MODEL {{FMH::MODEL_KEY::PATH, "recentdocuments:///"}, {FMH::MODEL_KEY::ICON, "view-media-recent"}, {FMH::MODEL_KEY::LABEL, "Recent"}, {FMH::MODEL_KEY::TYPE, "Quick"}};
0108         // #endif
0109         
0110         res << FMH::MODEL {{FMH::MODEL_KEY::PATH, QStringLiteral("tags:///")}, {FMH::MODEL_KEY::ICON, QStringLiteral("tag")}, {FMH::MODEL_KEY::LABEL, i18n("Tags")}, {FMH::MODEL_KEY::TYPE, QStringLiteral("Quick")}};
0111         
0112         return res;
0113     }
0114     
0115     if (type == FMStatic::PATHTYPE_KEY::PLACES_PATH) 
0116     {
0117         res << FMStatic::getDefaultPaths();
0118         return res;
0119     }
0120     
0121     #ifdef KIO_AVAILABLE
0122     auto mappedType = mapPathType(type);
0123     
0124     const auto group = model.groupIndexes(static_cast<KFilePlacesModel::GroupType>(type == FMStatic::PATHTYPE_KEY::BOOKMARKS_PATH ? mapPathType(FMStatic::PATHTYPE_KEY::PLACES_PATH) : mappedType));
0125     
0126     res << std::accumulate(group.constBegin(), group.constEnd(), FMH::MODEL_LIST(), [&model, &type, this](FMH::MODEL_LIST &list, const QModelIndex &index) -> FMH::MODEL_LIST 
0127     {
0128         const QUrl url = model.url(index);
0129         if (type == FMStatic::PATHTYPE_KEY::BOOKMARKS_PATH && FMStatic::defaultPaths.contains(url.toString()))
0130             return list;
0131         
0132         auto data = FMH::MODEL {{FMH::MODEL_KEY::PATH, url.toString()},
0133                            {FMH::MODEL_KEY::URL, url.toString()},
0134                            {FMH::MODEL_KEY::ICON, model.icon(index).name()},
0135                            {FMH::MODEL_KEY::LABEL, model.text(index)},
0136                            {FMH::MODEL_KEY::NAME, model.text(index)},
0137                            {FMH::MODEL_KEY::TYPE, type == FMStatic::PATHTYPE_KEY::BOOKMARKS_PATH ? FMStatic::PathTypeLabel(FMStatic::PATHTYPE_KEY::BOOKMARKS_PATH) : FMStatic::PathTypeLabel(type)}};
0138                            
0139                            if(model.isDevice(index))
0140                            {
0141                                const auto udi =  model.deviceForIndex(index).udi();
0142                                qDebug() << "DEVICE" << udi;
0143                                
0144                                data.insert(FMH::MODEL_KEY::UDI, udi);
0145                                m_devices.insert(udi, index);
0146                            }
0147                            
0148                            list << data;
0149                            return list;
0150     });
0151     
0152     #else
0153     Q_UNUSED(model)
0154     switch (type) {
0155         case (FMStatic::PATHTYPE_KEY::BOOKMARKS_PATH):
0156         {
0157     QSettings settings(QStringLiteral("org.mauikit.filebrowsing")) ;
0158             settings.beginGroup(QStringLiteral("PREFERENCES"));
0159             auto bookmarks = settings.value(QStringLiteral("BOOKMARKS"), {}).toStringList();           
0160             settings.endGroup();
0161             
0162             res << FMStatic::packItems(bookmarks, FMStatic::PathTypeLabel(FMStatic::PATHTYPE_KEY::BOOKMARKS_PATH));
0163             
0164             break;
0165         }
0166         case (FMStatic::PATHTYPE_KEY::DRIVES_PATH):
0167             res = FMStatic::getDevices();
0168             break;
0169         default:
0170             break;
0171     }
0172     
0173     #endif
0174     
0175     return res;
0176 }
0177 
0178 void PlacesList::setList()
0179 {
0180     this->list.clear();
0181     
0182     qDebug() << "Setting PlacesList model" << groups;
0183     Q_EMIT this->preListChanged();
0184     
0185     if (!this->groups.isEmpty())
0186     {        
0187         for (const auto &group : qAsConst(this->groups)) 
0188         {
0189             switch (group.toInt()) {
0190                 case FMStatic::PATHTYPE_KEY::PLACES_PATH:
0191                     this->list << getGroup(*this->model, FMStatic::PATHTYPE_KEY::PLACES_PATH);
0192                     break;
0193                     
0194                 case FMStatic::PATHTYPE_KEY::BOOKMARKS_PATH:
0195                     this->list << getGroup(*this->model, FMStatic::PATHTYPE_KEY::BOOKMARKS_PATH);
0196                     break;
0197                     
0198                 case FMStatic::PATHTYPE_KEY::QUICK_PATH:
0199                     this->list << getGroup(*this->model, FMStatic::PATHTYPE_KEY::QUICK_PATH);
0200                     break;
0201                     
0202                 case FMStatic::PATHTYPE_KEY::DRIVES_PATH:
0203                     this->list << getGroup(*this->model, FMStatic::PATHTYPE_KEY::DRIVES_PATH);
0204                     break;
0205                     
0206                 case FMStatic::PATHTYPE_KEY::REMOTE_PATH:
0207                     this->list << getGroup(*this->model, FMStatic::PATHTYPE_KEY::REMOTE_PATH);
0208                     break;
0209                     
0210                 case FMStatic::PATHTYPE_KEY::REMOVABLE_PATH:
0211                     this->list << getGroup(*this->model, FMStatic::PATHTYPE_KEY::REMOVABLE_PATH);
0212                     break;
0213                     
0214                 case FMStatic::PATHTYPE_KEY::TAGS_PATH:
0215                     this->list << Tagging::getInstance()->getTags();
0216                     break;
0217             }
0218         }
0219     }
0220     
0221     Q_EMIT this->postListChanged();
0222     Q_EMIT this->countChanged();
0223 }
0224 
0225 QVariantList PlacesList::getGroups() const
0226 {
0227     return this->groups;
0228 }
0229 
0230 void PlacesList::setGroups(const QVariantList &value)
0231 {
0232     if (this->groups == value)
0233         return;
0234     
0235     this->groups = value;
0236     Q_EMIT this->groupsChanged();
0237 }
0238 
0239 void PlacesList::removePlace(const int &index)
0240 {
0241     if (index >= this->list.size() || index < 0)
0242         return;
0243     
0244     #ifdef KIO_AVAILABLE
0245     Q_EMIT this->preItemRemoved(index);
0246     this->model->removePlace(this->model->closestItem(QUrl(this->list.at(index)[FMH::MODEL_KEY::PATH])));
0247     this->list.removeAt(index);
0248     Q_EMIT this->postItemRemoved();
0249     #else
0250     QSettings settings (QStringLiteral("org.mauikit.filebrowsing"));
0251     settings.beginGroup(QStringLiteral("PREFERENCES"));
0252     auto bookmarks = settings.value(QStringLiteral("BOOKMARKS"), {}).toStringList();
0253     bookmarks.removeOne(this->list.at(index)[FMH::MODEL_KEY::PATH]);
0254     settings.setValue(QStringLiteral("BOOKMARKS"), bookmarks);
0255     settings.endGroup();    
0256     #endif
0257     Q_EMIT bookmarksChanged();
0258 }
0259 
0260 bool PlacesList::contains(const QUrl &path)
0261 {
0262     return this->exists(FMH::MODEL_KEY::PATH, path.toString());
0263 }
0264 
0265 bool PlacesList::isDevice(const int &index)
0266 {
0267     if (index >= this->list.size() || index < 0)
0268         return false;
0269     
0270     #ifdef KIO_AVAILABLE
0271     const auto item = this->list.at(index);
0272     return m_devices.contains(item[FMH::MODEL_KEY::UDI]);
0273     #endif
0274     
0275     return false;
0276 }
0277 
0278 bool PlacesList::setupNeeded(const int &index)
0279 {
0280     if (index >= this->list.size() || index < 0)
0281         return false;
0282     
0283     #ifdef KIO_AVAILABLE
0284     const auto item = this->list.at(index);
0285     if(m_devices.contains(item[FMH::MODEL_KEY::UDI]))
0286     {
0287         return this->model->setupNeeded(m_devices.value(item[FMH::MODEL_KEY::UDI]));
0288     }
0289     #endif
0290     
0291     return false;
0292 }
0293 
0294 void PlacesList::requestEject(const int &index)
0295 {
0296     if (index >= this->list.size() || index < 0)
0297         return;
0298     
0299     #ifdef KIO_AVAILABLE
0300     const auto item = this->list.at(index);
0301     if(m_devices.contains(item[FMH::MODEL_KEY::UDI]))
0302     {
0303         this->model->requestEject(m_devices.value(item[FMH::MODEL_KEY::UDI]));
0304     }
0305     #endif
0306 }
0307 
0308 void PlacesList::requestSetup(const int &index)
0309 {
0310     if (index >= this->list.size() || index < 0)
0311         return;
0312     
0313     #ifdef KIO_AVAILABLE
0314     const auto item = this->list.at(index);
0315     if(m_devices.contains(item[FMH::MODEL_KEY::UDI]))
0316     {
0317         this->model->requestSetup(m_devices.value(item[FMH::MODEL_KEY::UDI]));
0318     }
0319     #endif
0320 }
0321 
0322 void PlacesList::addBookmark(const QUrl& url)
0323 {
0324     #ifdef KIO_AVAILABLE
0325     KFilePlacesModel model;
0326     model.addPlace(QDir(url.toLocalFile()).dirName(), url, FMStatic::getIconName(url));
0327     #else
0328     // do android stuff until cmake works with android
0329     if (FMStatic::isDefaultPath(url.toString()))
0330         return;
0331     
0332     QSettings settings(QStringLiteral("org.mauikit.filebrowsing")) ;
0333     settings.beginGroup(QStringLiteral("PREFERENCES"));
0334     auto bookmarks = settings.value(QStringLiteral("BOOKMARKS"), {}).toStringList();
0335     bookmarks << url.toString();
0336     settings.setValue(QStringLiteral("BOOKMARKS"), bookmarks);
0337     settings.endGroup();
0338     #endif
0339 }
0340 
0341 int PlacesList::indexOfPath(const QUrl &url) const
0342 {
0343     return this->indexOf(FMH::MODEL_KEY::PATH, url.toString());
0344 }
0345 
0346 void PlacesList::toggleSection(const int& section)
0347 {
0348     if(this->groups.contains(section))
0349     {
0350         this->groups.removeAll(section);
0351     }else
0352     {
0353         this->groups.append(section);
0354     }
0355     
0356     Q_EMIT this->groupsChanged();
0357 }
0358 
0359 bool PlacesList::containsGroup(const int& group)
0360 {
0361     return this->groups.contains(group);
0362 }
0363