Places Panel: Delegate open file error to KIO

This functionality is now provided by `KFilePlacesModel` as long as
you tell it to do the teardown rather than calling into the device yourself.
This commit is contained in:
Kai Uwe Broulik 2022-11-29 10:22:19 +00:00 committed by Felix Ernst
parent f5bb760186
commit de289800b2
2 changed files with 18 additions and 41 deletions

View file

@ -21,7 +21,6 @@
#include <KFilePlacesModel> #include <KFilePlacesModel>
#include <KIO/DropJob> #include <KIO/DropJob>
#include <KIO/Job> #include <KIO/Job>
#include <KListOpenFilesJob>
#include <KLocalizedString> #include <KLocalizedString>
#include <KProtocolManager> #include <KProtocolManager>
@ -86,11 +85,12 @@ void PlacesPanel::setCustomContextMenuActions(const QList<QAction *> &actions)
void PlacesPanel::proceedWithTearDown() void PlacesPanel::proceedWithTearDown()
{ {
Q_ASSERT(m_deviceToTearDown); if (m_indexToTearDown.isValid()) {
auto *placesModel = static_cast<KFilePlacesModel *>(model());
connect(m_deviceToTearDown, &Solid::StorageAccess::teardownDone, placesModel->requestTeardown(m_indexToTearDown);
this, &PlacesPanel::slotTearDownDone); } else {
m_deviceToTearDown->teardown(); qWarning() << "Places entry to tear down is no longer valid";
}
} }
void PlacesPanel::readSettings() void PlacesPanel::readSettings()
@ -114,6 +114,7 @@ void PlacesPanel::showEvent(QShowEvent* event)
setModel(placesModel); setModel(placesModel);
connect(placesModel, &KFilePlacesModel::errorMessage, this, &PlacesPanel::errorMessage); connect(placesModel, &KFilePlacesModel::errorMessage, this, &PlacesPanel::errorMessage);
connect(placesModel, &KFilePlacesModel::teardownDone, this, &PlacesPanel::slotTearDownDone);
connect(placesModel, &QAbstractItemModel::rowsInserted, this, &PlacesPanel::slotRowsInserted); connect(placesModel, &QAbstractItemModel::rowsInserted, this, &PlacesPanel::slotRowsInserted);
connect(placesModel, &QAbstractItemModel::rowsAboutToBeRemoved, this, &PlacesPanel::slotRowsAboutToBeRemoved); connect(placesModel, &QAbstractItemModel::rowsAboutToBeRemoved, this, &PlacesPanel::slotRowsAboutToBeRemoved);
@ -212,7 +213,7 @@ void PlacesPanel::slotTearDownRequested(const QModelIndex &index)
return; return;
} }
m_deviceToTearDown = storageAccess; m_indexToTearDown = QPersistentModelIndex(index);
// disconnect the Solid::StorageAccess::teardownRequested // disconnect the Solid::StorageAccess::teardownRequested
// to prevent emitting PlacesPanel::storageTearDownExternallyRequested // to prevent emitting PlacesPanel::storageTearDownExternallyRequested
@ -229,41 +230,17 @@ void PlacesPanel::slotTearDownRequestedExternally(const QString &udi)
Q_EMIT storageTearDownExternallyRequested(storageAccess->filePath()); Q_EMIT storageTearDownExternallyRequested(storageAccess->filePath());
} }
void PlacesPanel::slotTearDownDone(Solid::ErrorType error, const QVariant& errorData) void PlacesPanel::slotTearDownDone(const QModelIndex &index, Solid::ErrorType error, const QVariant &errorData)
{ {
if (error && errorData.isValid()) { Q_UNUSED(errorData); // All error handling is currently done in frameworks.
if (error == Solid::ErrorType::UserCanceled) {
// No need to tell the user what they just did. if (index == m_indexToTearDown) {
} else if (error == Solid::ErrorType::DeviceBusy) { if (error == Solid::ErrorType::NoError) {
KListOpenFilesJob* listOpenFilesJob = new KListOpenFilesJob(m_deviceToTearDown->filePath()); // No error; it must have been unmounted successfully
connect(listOpenFilesJob, &KIO::Job::result, this, [this, listOpenFilesJob](KJob*) { Q_EMIT storageTearDownSuccessful();
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 <application>\"%2\"</application>.",
"One or more files on this device are opened in following applications: <application>%2</application>.",
blockingApps.count(), blockingApps.join(i18nc("separator in list of apps blocking device unmount", ", ")));
}
Q_EMIT errorMessage(errorString);
});
listOpenFilesJob->start();
} else {
Q_EMIT errorMessage(errorData.toString());
} }
} else { m_indexToTearDown = QPersistentModelIndex();
// No error; it must have been unmounted successfully
Q_EMIT storageTearDownSuccessful();
} }
disconnect(m_deviceToTearDown, &Solid::StorageAccess::teardownDone,
this, &PlacesPanel::slotTearDownDone);
m_deviceToTearDown = nullptr;
} }
void PlacesPanel::slotRowsInserted(const QModelIndex &parent, int first, int last) void PlacesPanel::slotRowsInserted(const QModelIndex &parent, int first, int last)

View file

@ -62,7 +62,7 @@ private Q_SLOTS:
void slotContextMenuAboutToShow(const QModelIndex &index, QMenu *menu); void slotContextMenuAboutToShow(const QModelIndex &index, QMenu *menu);
void slotTearDownRequested(const QModelIndex &index); void slotTearDownRequested(const QModelIndex &index);
void slotTearDownRequestedExternally(const QString &udi); void slotTearDownRequestedExternally(const QString &udi);
void slotTearDownDone(Solid::ErrorType error, const QVariant& errorData); void slotTearDownDone(const QModelIndex &index, Solid::ErrorType error, const QVariant &errorData);
void slotRowsInserted(const QModelIndex &parent, int first, int last); void slotRowsInserted(const QModelIndex &parent, int first, int last);
void slotRowsAboutToBeRemoved(const QModelIndex &parent, int first, int last); void slotRowsAboutToBeRemoved(const QModelIndex &parent, int first, int last);
@ -72,7 +72,7 @@ private:
QUrl m_url; // only used for initial setUrl QUrl m_url; // only used for initial setUrl
QList<QAction*> m_customContextMenuActions; QList<QAction*> m_customContextMenuActions;
Solid::StorageAccess *m_deviceToTearDown = nullptr; QPersistentModelIndex m_indexToTearDown;
QAction *m_configureTrashAction; QAction *m_configureTrashAction;
QAction *m_lockPanelsAction; QAction *m_lockPanelsAction;