diff options
Diffstat (limited to 'src/plugins/General/udisks/udisksplugin.cpp')
| -rw-r--r-- | src/plugins/General/udisks/udisksplugin.cpp | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/src/plugins/General/udisks/udisksplugin.cpp b/src/plugins/General/udisks/udisksplugin.cpp new file mode 100644 index 000000000..ac1559270 --- /dev/null +++ b/src/plugins/General/udisks/udisksplugin.cpp @@ -0,0 +1,253 @@ +/*************************************************************************** + * Copyright (C) 2013-2021 by Ilya Kotov * + * forkotov02@ya.ru * + * * + * 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. * + ***************************************************************************/ + +#include <QtDBus> +#include <QActionGroup> +#include <QApplication> +#include <QStyle> +#include <qmmpui/uihelper.h> +#include <qmmpui/playlistmanager.h> +#include <qmmpui/playlistitem.h> +#include <qmmp/qmmp.h> +#include "udisksdevice.h" +#include "udisksmanager.h" +#include "udisksplugin.h" + +UDisksPlugin::UDisksPlugin(QObject *parent) : QObject(parent) +{ + qDBusRegisterMetaType<QVariantMapMap>(); + qDBusRegisterMetaType<QByteArrayList>(); + + m_manager = new UDisksManager(this); + m_actions = new QActionGroup(this); + connect(m_manager,SIGNAL(deviceAdded(QDBusObjectPath)), SLOT(addDevice(QDBusObjectPath))); + connect(m_manager,SIGNAL(deviceRemoved(QDBusObjectPath)), SLOT(removeDevice(QDBusObjectPath))); + connect(m_actions,SIGNAL(triggered (QAction *)), SLOT(processAction(QAction *))); + //load settings + QSettings settings(Qmmp::configFile(), QSettings::IniFormat); + settings.beginGroup("UDisks2"); + m_detectCDA = settings.value("cda", true).toBool(); + m_detectRemovable = settings.value("removable", true).toBool(); + m_addTracks = false; //do not load tracks on startup + m_addFiles = false; + //find existing devices + const QList<QDBusObjectPath> devs = m_manager->findAllDevices(); + for(const QDBusObjectPath &o : qAsConst(devs)) + addDevice(o); + //load remaining settings + m_addTracks = settings.value("add_tracks", false).toBool(); + m_removeTracks = settings.value("remove_tracks", false).toBool(); + m_addFiles = settings.value("add_files", false).toBool(); + m_removeFiles = settings.value("remove_files", false).toBool(); + settings.endGroup(); +} + +UDisksPlugin::~UDisksPlugin() +{ +} + +void UDisksPlugin::removeDevice(QDBusObjectPath o) +{ + QList<UDisksDevice *>::iterator it = m_devices.begin(); + while(it != m_devices.end()) + { + if((*it)->objectPath() == o) + { + delete (*it); + it = m_devices.erase(it); + qDebug("UDisksPlugin: removed device: \"%s\"", qPrintable(o.path())); + updateActions(); + break; + } + else + { + ++it; + } + } +} + +void UDisksPlugin::addDevice(QDBusObjectPath o) +{ + for(const UDisksDevice *device : qAsConst(m_devices)) //is it already exists? + { + if (device->objectPath() == o) + return; + } + UDisksDevice *device = new UDisksDevice(o, this); + + if(device->isRemovable()) //detect removable devices only + { + qDebug("UDisksPlugin: added device: \"%s\"", qPrintable(o.path())); + m_devices << device; + updateActions(); + connect(device, SIGNAL(changed()), SLOT(updateActions())); + } + else + delete device; +} + +void UDisksPlugin::updateActions() +{ + // add action for cd audio or mounted volume + for(const UDisksDevice *device : qAsConst(m_devices)) + { + QString dev_path; + if (m_detectCDA && device->isAudio()) //cd audio + { + dev_path = "cdda://" + device->deviceFile(); + } + else if (m_detectRemovable && device->isMounted() && + device->property("Size").toLongLong() < 40000000000LL && + (device->property("IdType").toString() == "vfat" || + device->property("IdType").toString() == "iso9660" || + device->property("IdType").toString() == "udf" || + device->property("IdType").toString() == "ext2")) //mounted volume + { + dev_path = device->mountPoints().first(); + } + else + continue; + + if (!findAction(dev_path)) + { + QAction *action = new QAction(this); + QString actionText; + if (device->isAudio()) + { + actionText = QString(tr("Add CD \"%1\"")).arg(device->deviceFile()); + } + else + { + QString name = device->property("IdLabel").toString(); + if (name.isEmpty()) + name = dev_path; + + actionText = QString(tr("Add Volume \"%1\"")).arg(name); + } + + if (device->isOptical()) + { + if(device->property("IdType").toString() == "iso9660") + action->setIcon(qApp->style()->standardIcon(QStyle::SP_DriveDVDIcon)); + else + action->setIcon(qApp->style()->standardIcon(QStyle::SP_DriveCDIcon)); + } + else + action->setIcon(qApp->style()->standardIcon(QStyle::SP_DriveHDIcon)); + + qDebug("UDisksPlugin: added menu item: \"%s\"", qPrintable(dev_path)); + + action->setText(actionText); + action->setData(dev_path); + m_actions->addAction(action); + UiHelper::instance()->addAction(action, UiHelper::ADD_MENU); + addPath(dev_path); + } + } + // remove action if device is unmounted/removed + for(QAction *action : m_actions->actions()) + { + if (!findDevice(action)) + { + qDebug("UDisksPlugin: removed menu item: \"%s\"", qPrintable(action->data().toString())); + m_actions->removeAction(action); + UiHelper::instance()->removeAction(action); + removePath(action->data().toString()); + action->deleteLater(); + } + } +} + +void UDisksPlugin::processAction(QAction *action) +{ + qDebug("UDisksPlugin: action triggered: %s", qPrintable(action->data().toString())); + QString path = action->data().toString(); + PlayListManager::instance()->selectedPlayList()->add(path); +} + +QAction *UDisksPlugin::findAction(const QString &dev_path) +{ + for(QAction *action : m_actions->actions()) + { + if (action->data().toString() == dev_path) + return action; + } + return nullptr; +} + +UDisksDevice *UDisksPlugin::findDevice(QAction *action) +{ + for(UDisksDevice *device : qAsConst(m_devices)) + { + QString dev_path; + if (device->isAudio()) + { + dev_path = "cdda://" + device->deviceFile(); + if (dev_path == action->data().toString()) + return device; + } + if (device->isMounted()) + { + dev_path = device->mountPoints().first(); + if (dev_path == action->data().toString()) + return device; + } + } + return nullptr; +} + +void UDisksPlugin::addPath(const QString &path) +{ + PlayListModel *model = PlayListManager::instance()->selectedPlayList(); + + for(PlayListItem *item : model->items()) // Is it already exist? + { + if(item->isGroup()) + continue; + if (dynamic_cast<PlayListTrack *>(item)->path().startsWith(path)) + return; + } + + if (path.startsWith("cdda://") && m_addTracks) + { + PlayListManager::instance()->selectedPlayList()->add(path); + return; + } + else if (!path.startsWith("cdda://") && m_addFiles) + PlayListManager::instance()->selectedPlayList()->add(path); +} + +void UDisksPlugin::removePath(const QString &path) +{ + if ((path.startsWith("cdda://") && !m_removeTracks) || + (!path.startsWith("cdda://") && !m_removeFiles)) //process settings + return; + + PlayListModel *model = PlayListManager::instance()->selectedPlayList(); + + int i = 0; + while (model->count() > 0 && i < model->count()) + { + if (model->isTrack(i) && model->track(i)->path().startsWith(path)) + model->removeTrack(i); + else + ++i; + } +} |
