#include <KUrlMimeData>
#include <Solid/DeviceNotifier>
#include <Solid/OpticalDrive>
+#include <KCoreAddons/KProcessList>
+#include <KCoreAddons/KListOpenFilesJob>
#include <QAction>
#include <QIcon>
#include <QMimeData>
#include <QTimer>
-namespace {
- static QList<QUrl> 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"))
- };
-}
-
PlacesItemModel::PlacesItemModel(QObject* parent) :
KStandardItemModel(parent),
m_hiddenItemsShown(false),
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 <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", ", ")));
+ }
+ emit errorMessage(errorString);
+ });
+ listOpenFilesJob->start();
+ } else {
+ emit errorMessage(errorData.toString());
+ }
}
disconnect(m_deviceToTearDown, &Solid::StorageAccess::teardownDone,
this, &PlacesItemModel::slotStorageTearDownDone);
const QVariant& errorData,
const QString& udi)
{
- Q_UNUSED(udi);
+ Q_UNUSED(udi)
const int index = m_storageSetupInProgress.take(sender());
const PlacesItem* item = placesItem(index);
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);
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;
void PlacesItemModel::onSourceModelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
{
- Q_UNUSED(roles);
+ Q_UNUSED(roles)
for (int r = topLeft.row(); r <= bottomRight.row(); r++) {
const QModelIndex sourceIndex = m_sourceModel->index(r, 0);
{
// 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<QUrl> 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);
bool PlacesItemModel::isDir(int index) const
{
- Q_UNUSED(index);
+ Q_UNUSED(index)
return true;
}