DeviceAutomounterKCM.cpp 8.65 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/**************************************************************************
*   Copyright (C) 2009-2010 Trever Fischer <tdfischer@fedoraproject.org>  *
*   Copyright (C) 2015 Kai UWe Broulik <kde@privat.broulik.de>            *
*                                                                         *
*   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 "DeviceAutomounterKCM.h"
Laurent Montel's avatar
Laurent Montel committed
22
#include <kconfigwidgets_version.h>
23 24
#include <QDBusConnection>
#include <QDBusMessage>
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
#include <QStandardItem>
#include <QStandardItemModel>
#include <QItemSelectionModel>

#include <KAboutData>
#include <KConfigGroup>
#include <Solid/DeviceNotifier>
#include <Solid/StorageVolume>

#include <KPluginFactory>

#include "AutomounterSettings.h"
#include "LayoutSettings.h"
#include "DeviceModel.h"

K_PLUGIN_FACTORY(DeviceAutomounterKCMFactory, registerPlugin<DeviceAutomounterKCM>();)

DeviceAutomounterKCM::DeviceAutomounterKCM(QWidget *parent, const QVariantList &args)
    : KCModule(parent, args)//DeviceAutomounterKCMFactory::componentData(), parent)
44 45
    , m_settings(new AutomounterSettings(this))
    , m_devices(new DeviceModel(m_settings, this))
46
{
Laurent Montel's avatar
Laurent Montel committed
47
    KAboutData *about = new KAboutData(QStringLiteral("kcm_device_automounter"),
48
                                       i18n("Device Automounter"),
Laurent Montel's avatar
Laurent Montel committed
49
                                       QStringLiteral("2.0"),
50 51 52 53
                                       QString(),
                                       KAboutLicense::GPL_V2,
                                       i18n("(c) 2009 Trever Fischer, (c) 2015 Kai Uwe Broulik"));
    about->addAuthor(i18n("Trever Fischer"), i18n("Original Author"));
Laurent Montel's avatar
Laurent Montel committed
54
    about->addAuthor(i18n("Kai Uwe Broulik"), i18n("Plasma 5 Port"), QStringLiteral("kde@privat.broulik.de"));
55 56 57 58

    setAboutData(about);
    setupUi(this);

59
    addConfig(m_settings, this);
60

61 62
    deviceView->setModel(m_devices);

63 64 65
    deviceView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
    deviceView->header()->setSectionResizeMode(0, QHeaderView::Stretch);

66
    auto emitChanged = [this] {
67 68
        m_devices->setAutomaticMountOnLogin(kcfg_AutomountOnLogin->isChecked());
        m_devices->setAutomaticMountOnPlugin(kcfg_AutomountOnPlugin->isChecked());
Laurent Montel's avatar
Laurent Montel committed
69
        emit markAsChanged();
70 71 72 73
    };

    connect(m_devices, &DeviceModel::dataChanged, this, emitChanged);

74
    connect(deviceView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &DeviceAutomounterKCM::updateForgetDeviceButton);
75

76
    connect(forgetDevice, &QAbstractButton::clicked, this, &DeviceAutomounterKCM::forgetSelectedDevices);
77 78 79 80 81 82 83 84 85 86 87

    forgetDevice->setEnabled(false);
}

DeviceAutomounterKCM::~DeviceAutomounterKCM()
{
    saveLayout();
}

void DeviceAutomounterKCM::updateForgetDeviceButton()
{
88 89
    const auto selectedIndex = deviceView->selectionModel()->selectedIndexes();
    for (const QModelIndex &idx : selectedIndex) {
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
		if (idx.data(DeviceModel::TypeRole) == DeviceModel::Detatched) {
			forgetDevice->setEnabled(true);
			return;
		}
	}
	forgetDevice->setEnabled(false);
}

void DeviceAutomounterKCM::forgetSelectedDevices()
{
    QItemSelectionModel *selected = deviceView->selectionModel();
	int offset = 0;
    while (!selected->selectedIndexes().isEmpty() && selected->selectedIndexes().size() > offset) {
        if (selected->selectedIndexes()[offset].data(DeviceModel::TypeRole) == DeviceModel::Attached) {
			offset++;
        } else {
            m_devices->forgetDevice(selected->selectedIndexes()[offset].data(DeviceModel::UdiRole).toString());
        }
    }
Méven Car's avatar
Méven Car committed
109

Laurent Montel's avatar
Laurent Montel committed
110
    emit markAsChanged();
111 112 113 114
}

void DeviceAutomounterKCM::load()
{
115 116
    KCModule::load();

117
    bool automountEnabled = m_settings->automountEnabled();
118

119 120 121
    kcfg_AutomountUnknownDevices->setEnabled(m_settings->automountEnabled());
    kcfg_AutomountOnLogin->setEnabled(m_settings->automountEnabled());
    kcfg_AutomountOnPlugin->setEnabled(m_settings->automountEnabled());
122 123 124 125 126 127 128

    m_devices->reload();
    loadLayout();
}

void DeviceAutomounterKCM::save()
{
129
    KCModule::save();
130 131
    saveLayout();

132
    const bool enabled = kcfg_AutomountEnabled->isChecked();
133 134 135 136 137 138 139 140 141 142 143

    QStringList validDevices;
    for (int i = 0; i < m_devices->rowCount(); ++i) {
        const QModelIndex &idx = m_devices->index(i, 0);

        for (int j = 0; j < m_devices->rowCount(idx); ++j) {
            QModelIndex dev = m_devices->index(j, 1, idx);
            const QString device = dev.data(DeviceModel::UdiRole).toString();
            validDevices << device;

            if (dev.data(Qt::CheckStateRole).toInt() == Qt::Checked) {
144
                m_settings->deviceSettings(device).writeEntry("ForceLoginAutomount", true);
145
            } else {
146
                m_settings->deviceSettings(device).writeEntry("ForceLoginAutomount", false);
147 148 149 150 151
            }

            dev = dev.sibling(j, 2);

            if (dev.data(Qt::CheckStateRole).toInt() == Qt::Checked) {
152
                m_settings->deviceSettings(device).writeEntry("ForceAttachAutomount", true);
153
            } else {
154
                m_settings->deviceSettings(device).writeEntry("ForceAttachAutomount", false);
155 156 157 158
            }
        }
    }

159
    const auto knownDevices = m_settings->knownDevices();
160
    for (const QString &possibleDevice : knownDevices) {
161
        if (!validDevices.contains(possibleDevice)) {
162
            m_settings->deviceSettings(possibleDevice).deleteGroup();
163 164 165
        }
    }

166
    m_settings->save();
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183

    // Now tell kded to automatically load the module if loaded
    QDBusConnection dbus = QDBusConnection::sessionBus();
    QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kded5"),
                                                      QStringLiteral("/kded"),
                                                      QStringLiteral("org.kde.kded5"),
                                                      QStringLiteral("setModuleAutoloading"));
    msg.setArguments({QVariant(QStringLiteral("device_automounter")), QVariant(enabled)});
    dbus.call(msg, QDBus::NoBlock);

    // Load or unload right away
    msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kded5"),
                                         QStringLiteral("/kded"),
                                         QStringLiteral("org.kde.kded5"),
                                         enabled ? QStringLiteral("loadModule") : QStringLiteral("unloadModule"));
    msg.setArguments({QVariant(QStringLiteral("device_automounter"))});
    dbus.call(msg, QDBus::NoBlock);
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
}

void DeviceAutomounterKCM::saveLayout()
{
    QList<int> widths;
    const int nbColumn = m_devices->columnCount();
    widths.reserve(nbColumn);

    for (int i = 0; i < nbColumn; ++i) {
        widths << deviceView->columnWidth(i);
    }

    LayoutSettings::setHeaderWidths(widths);
    //Check DeviceModel.cpp, thats where the magic row numbers come from.
    LayoutSettings::setAttachedExpanded(deviceView->isExpanded(m_devices->index(0,0)));
    LayoutSettings::setDetatchedExpanded(deviceView->isExpanded(m_devices->index(1,0)));
    LayoutSettings::self()->save();
}

void DeviceAutomounterKCM::loadLayout()
{
    LayoutSettings::self()->load();
    //Reset it first, just in case there isn't any layout saved for a particular column.
    int nbColumn = m_devices->columnCount();
    for (int i = 0; i < nbColumn; ++i) {
        deviceView->resizeColumnToContents(i);
    }

    QList<int> widths = LayoutSettings::headerWidths();
    nbColumn = m_devices->columnCount();
    for (int i = 0; i < nbColumn && i < widths.size(); ++i) {
        deviceView->setColumnWidth(i, widths[i]);
    }

    deviceView->setExpanded(m_devices->index(0,0), LayoutSettings::attachedExpanded());
    deviceView->setExpanded(m_devices->index(1,0), LayoutSettings::detatchedExpanded());
}

#include "DeviceAutomounterKCM.moc"