X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/a8a3fa51a0649ffc43b0d740c268e39a6dd6672b..954e8c47906c12edaaf6e6aebdd41516eceb0d44:/src/panels/places/placesitemmodel.cpp diff --git a/src/panels/places/placesitemmodel.cpp b/src/panels/places/placesitemmodel.cpp index 077c9044c..de858389b 100644 --- a/src/panels/places/placesitemmodel.cpp +++ b/src/panels/places/placesitemmodel.cpp @@ -1,102 +1,67 @@ -/*************************************************************************** - * Copyright (C) 2012 by Peter Penz * - * * - * Based on KFilePlacesModel from kdelibs: * - * Copyright (C) 2007 Kevin Ottens * - * Copyright (C) 2007 David Faure * - * * - * 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 2 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, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ +/* + * SPDX-FileCopyrightText: 2012 Peter Penz + * + * Based on KFilePlacesModel from kdelibs: + * SPDX-FileCopyrightText: 2007 Kevin Ottens + * SPDX-FileCopyrightText: 2007 David Faure + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ #include "placesitemmodel.h" -#include "placesitemsignalhandler.h" #include "dolphin_generalsettings.h" - -#include -#include #include "dolphindebug.h" -#include -#include -#include -#include -#include +#include "dolphinplacesmodelsingleton.h" #include "placesitem.h" -#include -#include -#include -#include -#include -#include +#include "placesitemsignalhandler.h" +#include "views/dolphinview.h" +#include "views/viewproperties.h" -#include +#include +#include +#include #include -#include #include -#include -#include - -#include -#include +#include +#include -namespace { - // A suffix to the application-name of the stored bookmarks is - // added, which is only read by PlacesItemModel. - const QString AppNameSuffix = QStringLiteral("-places-panel"); - static QList balooURLs = { - QUrl(QStringLiteral("timeline:/today")), - QUrl(QStringLiteral("timeline:/yesterday")), - QUrl(QStringLiteral("timeline:/thismonth")), - QUrl(QStringLiteral("timeline:/lastmonth")), - QUrl(QStringLiteral("search:/documents")), - QUrl(QStringLiteral("search:/images")), - QUrl(QStringLiteral("search:/audio")), - QUrl(QStringLiteral("search:/videos")) - }; -} +#include +#include +#include +#include PlacesItemModel::PlacesItemModel(QObject* parent) : KStandardItemModel(parent), m_hiddenItemsShown(false), m_deviceToTearDown(nullptr), m_storageSetupInProgress(), - m_sourceModel(new KFilePlacesModel(KAboutData::applicationData().componentName() + AppNameSuffix, this)) + m_sourceModel(DolphinPlacesModelSingleton::instance().placesModel()) { cleanupBookmarks(); loadBookmarks(); initializeDefaultViewProperties(); - connect(m_sourceModel.data(), &KFilePlacesModel::rowsInserted, this, &PlacesItemModel::onSourceModelRowsInserted); - connect(m_sourceModel.data(), &KFilePlacesModel::rowsAboutToBeRemoved, this, &PlacesItemModel::onSourceModelRowsAboutToBeRemoved); - connect(m_sourceModel.data(), &KFilePlacesModel::dataChanged, this, &PlacesItemModel::onSourceModelDataChanged); - connect(m_sourceModel.data(), &KFilePlacesModel::rowsAboutToBeMoved, this, &PlacesItemModel::onSourceModelRowsAboutToBeMoved); - connect(m_sourceModel.data(), &KFilePlacesModel::rowsMoved, this, &PlacesItemModel::onSourceModelRowsMoved); - connect(m_sourceModel.data(), &KFilePlacesModel::groupHiddenChanged, this, &PlacesItemModel::onSourceModelGroupHiddenChanged); + connect(m_sourceModel, &KFilePlacesModel::rowsInserted, this, &PlacesItemModel::onSourceModelRowsInserted); + connect(m_sourceModel, &KFilePlacesModel::rowsAboutToBeRemoved, this, &PlacesItemModel::onSourceModelRowsAboutToBeRemoved); + connect(m_sourceModel, &KFilePlacesModel::dataChanged, this, &PlacesItemModel::onSourceModelDataChanged); + connect(m_sourceModel, &KFilePlacesModel::rowsAboutToBeMoved, this, &PlacesItemModel::onSourceModelRowsAboutToBeMoved); + connect(m_sourceModel, &KFilePlacesModel::rowsMoved, this, &PlacesItemModel::onSourceModelRowsMoved); + connect(m_sourceModel, &KFilePlacesModel::groupHiddenChanged, this, &PlacesItemModel::onSourceModelGroupHiddenChanged); } PlacesItemModel::~PlacesItemModel() { } -void PlacesItemModel::createPlacesItem(const QString& text, - const QUrl& url, - const QString& iconName, - int after) +void PlacesItemModel::createPlacesItem(const QString &text, const QUrl &url, const QString &iconName, const QString &appName) { - m_sourceModel->addPlace(text, url, iconName, {}, mapToSource(after)); + createPlacesItem(text, url, iconName, appName, -1); +} + +void PlacesItemModel::createPlacesItem(const QString &text, const QUrl &url, const QString &iconName, const QString &appName, int after) +{ + m_sourceModel->addPlace(text, url, iconName, appName, mapToSource(after)); } PlacesItem* PlacesItemModel::placesItem(int index) const @@ -133,11 +98,6 @@ void PlacesItemModel::setHiddenItemsShown(bool show) } } } - -#ifdef PLACESITEMMODEL_DEBUG - qCDebug(DolphinDebug) << "Changed visibility of hidden items"; - showModelState(); -#endif } bool PlacesItemModel::hiddenItemsShown() const @@ -182,10 +142,6 @@ void PlacesItemModel::insertSortedItem(PlacesItem* item) void PlacesItemModel::onItemInserted(int index) { KStandardItemModel::onItemInserted(index); -#ifdef PLACESITEMMODEL_DEBUG - qCDebug(DolphinDebug) << "Inserted item" << index; - showModelState(); -#endif } void PlacesItemModel::onItemRemoved(int index, KStandardItem* removedItem) @@ -193,10 +149,6 @@ void PlacesItemModel::onItemRemoved(int index, KStandardItem* removedItem) m_indexMap.removeAt(index); KStandardItemModel::onItemRemoved(index, removedItem); -#ifdef PLACESITEMMODEL_DEBUG - qCDebug(DolphinDebug) << "Removed item" << index; - showModelState(); -#endif } void PlacesItemModel::onItemChanged(int index, const QSet& changedRoles) @@ -377,7 +329,10 @@ void PlacesItemModel::dropMimeDataBefore(int index, const QMimeData* mimeData) int oldIndex; stream >> oldIndex; - m_sourceModel->movePlace(oldIndex, index); + QModelIndex sourceIndex = mapToSource(index); + QModelIndex oldSourceIndex = mapToSource(oldIndex); + + m_sourceModel->movePlace(oldSourceIndex.row(), sourceIndex.row()); } else if (mimeData->hasFormat(QStringLiteral("text/uri-list"))) { // One or more items must be added to the model const QList urls = KUrlMimeData::urlsFromMimeData(mimeData); @@ -395,7 +350,7 @@ void PlacesItemModel::dropMimeDataBefore(int index, const QMimeData* mimeData) continue; } - createPlacesItem(text, url, KIO::iconNameForUrl(url), qMax(0, index - 1)); + createPlacesItem(text, url, KIO::iconNameForUrl(url), {}, qMax(0, index - 1)); } } // will save bookmark alteration and fix sort if that is broken by the drag/drop operation @@ -410,10 +365,7 @@ void PlacesItemModel::addItemFromSourceModel(const QModelIndex &index) const KBookmark bookmark = m_sourceModel->bookmarkForIndex(index); Q_ASSERT(!bookmark.isNull()); - PlacesItem *item = itemFromBookmark(bookmark); - if (!item) { - item = new PlacesItem(bookmark); - } + PlacesItem *item = new PlacesItem(bookmark); updateItem(item, index); insertSortedItem(item); @@ -469,7 +421,7 @@ void PlacesItemModel::initializeDefaultViewProperties() const } else if (path == QLatin1String("/images")) { props.setViewMode(DolphinView::IconsView); props.setPreviewsShown(true); - props.setVisibleRoles({"text", "imageSize"}); + props.setVisibleRoles({"text", "height", "width"}); } else if (path == QLatin1String("/audio")) { props.setViewMode(DolphinView::DetailsView); props.setPreviewsShown(false); @@ -498,9 +450,32 @@ void PlacesItemModel::updateItem(PlacesItem *item, const QModelIndex &index) void PlacesItemModel::slotStorageTearDownDone(Solid::ErrorType error, const QVariant& errorData) { if (error && errorData.isValid()) { - emit errorMessage(errorData.toString()); + if (error == Solid::ErrorType::DeviceBusy) { + KListOpenFilesJob* listOpenFilesJob = new KListOpenFilesJob(m_deviceToTearDown->filePath()); + connect(listOpenFilesJob, &KIO::Job::result, this, [this, listOpenFilesJob](KJob*) { + const KProcessList::KProcessInfoList blockingProcesses = listOpenFilesJob->processInfoList(); + QString errorString; + if (blockingProcesses.isEmpty()) { + errorString = i18n("One or more files on this device are open within an application."); + } else { + QStringList blockingApps; + for (const auto& process : blockingProcesses) { + blockingApps << process.name(); + } + blockingApps.removeDuplicates(); + errorString = xi18np("One or more files on this device are opened in application \"%2\".", + "One or more files on this device are opened in following applications: %2.", + blockingApps.count(), blockingApps.join(i18nc("separator in list of apps blocking device unmount", ", "))); + } + emit errorMessage(errorString); + }); + listOpenFilesJob->start(); + } else { + emit errorMessage(errorData.toString()); + } } - m_deviceToTearDown->disconnect(); + disconnect(m_deviceToTearDown, &Solid::StorageAccess::teardownDone, + this, &PlacesItemModel::slotStorageTearDownDone); m_deviceToTearDown = nullptr; } @@ -508,7 +483,7 @@ void PlacesItemModel::slotStorageSetupDone(Solid::ErrorType error, const QVariant& errorData, const QString& udi) { - Q_UNUSED(udi); + Q_UNUSED(udi) const int index = m_storageSetupInProgress.take(sender()); const PlacesItem* item = placesItem(index); @@ -552,8 +527,8 @@ void PlacesItemModel::onSourceModelRowsAboutToBeRemoved(const QModelIndex &paren void PlacesItemModel::onSourceModelRowsAboutToBeMoved(const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row) { - Q_UNUSED(destination); - Q_UNUSED(row); + Q_UNUSED(destination) + Q_UNUSED(row) for(int r = start; r <= end; r++) { const QModelIndex sourceIndex = m_sourceModel->index(r, 0, parent); @@ -564,8 +539,8 @@ void PlacesItemModel::onSourceModelRowsAboutToBeMoved(const QModelIndex &parent, void PlacesItemModel::onSourceModelRowsMoved(const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row) { - Q_UNUSED(destination); - Q_UNUSED(parent); + Q_UNUSED(destination) + Q_UNUSED(parent) const int blockSize = (end - start) + 1; @@ -580,7 +555,7 @@ void PlacesItemModel::onSourceModelRowsMoved(const QModelIndex &parent, int star void PlacesItemModel::onSourceModelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles) { - Q_UNUSED(roles); + Q_UNUSED(roles) for (int r = topLeft.row(); r <= bottomRight.row(); r++) { const QModelIndex sourceIndex = m_sourceModel->index(r, 0); @@ -600,11 +575,6 @@ void PlacesItemModel::onSourceModelDataChanged(const QModelIndex &topLeft, const } if (placeItem && !m_sourceModel->isDevice(sourceIndex)) { - placeItem->setText(bookmark.text()); - placeItem->setIcon(sourceIndex.data(KFilePlacesModel::IconNameRole).toString()); - placeItem->setUrl(m_sourceModel->url(sourceIndex)); - placeItem->bookmark().setMetaDataItem(QStringLiteral("OnlyInApp"), - bookmark.metaDataItem(QStringLiteral("OnlyInApp"))); // must update the bookmark object placeItem->setBookmark(bookmark); } @@ -613,7 +583,8 @@ void PlacesItemModel::onSourceModelDataChanged(const QModelIndex &topLeft, const void PlacesItemModel::onSourceModelGroupHiddenChanged(KFilePlacesModel::GroupType group, bool hidden) { - for(const QModelIndex &sourceIndex : m_sourceModel->groupIndexes(group)) { + const auto groupIndexes = m_sourceModel->groupIndexes(group); + for (const QModelIndex &sourceIndex : groupIndexes) { PlacesItem *item = placesItem(mapFromSource(sourceIndex)); if (item) { item->setGroupHidden(hidden); @@ -625,6 +596,18 @@ void PlacesItemModel::cleanupBookmarks() { // KIO model now provides support for baloo urls, and because of that we // need to remove old URLs that were visible only in Dolphin to avoid duplication + + static const QVector balooURLs = { + QUrl(QStringLiteral("timeline:/today")), + QUrl(QStringLiteral("timeline:/yesterday")), + QUrl(QStringLiteral("timeline:/thismonth")), + QUrl(QStringLiteral("timeline:/lastmonth")), + QUrl(QStringLiteral("search:/documents")), + QUrl(QStringLiteral("search:/images")), + QUrl(QStringLiteral("search:/audio")), + QUrl(QStringLiteral("search:/videos")) + }; + int row = 0; do { const QModelIndex sourceIndex = m_sourceModel->index(row, 0); @@ -633,7 +616,7 @@ void PlacesItemModel::cleanupBookmarks() const QString appName = bookmark.metaDataItem(QStringLiteral("OnlyInApp")); if ((appName == KAboutData::applicationData().componentName() || - appName == KAboutData::applicationData().componentName() + AppNameSuffix) && balooURLs.contains(url)) { + appName == KAboutData::applicationData().componentName() + DolphinPlacesModelSingleton::applicationNameSuffix()) && balooURLs.contains(url)) { qCDebug(DolphinDebug) << "Removing old baloo url:" << url; m_sourceModel->removePlace(sourceIndex); } else { @@ -650,11 +633,6 @@ void PlacesItemModel::loadBookmarks() addItemFromSourceModel(sourceIndex); } } - -#ifdef PLACESITEMMODEL_DEBUG - qCDebug(DolphinDebug) << "Loaded bookmarks"; - showModelState(); -#endif } void PlacesItemModel::clear() { @@ -764,7 +742,7 @@ int PlacesItemModel::mapFromSource(const QModelIndex &index) const bool PlacesItemModel::isDir(int index) const { - Q_UNUSED(index); + Q_UNUSED(index) return true; } @@ -801,44 +779,3 @@ PlacesItem *PlacesItemModel::itemFromBookmark(const KBookmark &bookmark) const return nullptr; } -#ifdef PLACESITEMMODEL_DEBUG -void PlacesItemModel::showModelState() -{ - qCDebug(DolphinDebug) << "================================="; - qCDebug(DolphinDebug) << "Model:"; - qCDebug(DolphinDebug) << "hidden-index model-index text"; - int modelIndex = 0; - for (int i = 0; i < m_bookmarkedItems.count(); ++i) { - if (m_bookmarkedItems[i]) { - qCDebug(DolphinDebug) << i << "(Hidden) " << " " << m_bookmarkedItems[i]->dataValue("text").toString(); - } else { - if (item(modelIndex)) { - qCDebug(DolphinDebug) << i << " " << modelIndex << " " << item(modelIndex)->dataValue("text").toString(); - } else { - qCDebug(DolphinDebug) << i << " " << modelIndex << " " << "(not available yet)"; - } - ++modelIndex; - } - } - - qCDebug(DolphinDebug); - qCDebug(DolphinDebug) << "Bookmarks:"; - - int bookmarkIndex = 0; - KBookmarkGroup root = m_bookmarkManager->root(); - KBookmark bookmark = root.first(); - while (!bookmark.isNull()) { - const QString udi = bookmark.metaDataItem("UDI"); - const QString text = udi.isEmpty() ? bookmark.text() : udi; - if (bookmark.metaDataItem("IsHidden") == QLatin1String("true")) { - qCDebug(DolphinDebug) << bookmarkIndex << "(Hidden)" << text; - } else { - qCDebug(DolphinDebug) << bookmarkIndex << " " << text; - } - - bookmark = root.next(bookmark); - ++bookmarkIndex; - } -} -#endif -