Warning, file /plasma/plasma-desktop/solid-device-automounter/kcm/DeviceAutomounterKCM.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2009-2010 Trever Fischer <tdfischer@fedoraproject.org> 0003 SPDX-FileCopyrightText: 2015 Kai UWe Broulik <kde@privat.broulik.de> 0004 SPDX-FileCopyrightText: 2021 Ismael Asensio <isma.af@gmail.com> 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "DeviceAutomounterKCM.h" 0010 #include <QDBusConnection> 0011 #include <QDBusMessage> 0012 #include <QItemSelectionModel> 0013 #include <QStandardItem> 0014 #include <QStandardItemModel> 0015 #include <kconfigwidgets_version.h> 0016 0017 #include <KAboutData> 0018 #include <KConfigGroup> 0019 #include <Solid/DeviceNotifier> 0020 #include <Solid/StorageVolume> 0021 0022 #include <KPluginFactory> 0023 0024 #include "AutomounterSettings.h" 0025 #include "DeviceAutomounterData.h" 0026 #include "DeviceModel.h" 0027 #include "LayoutSettings.h" 0028 0029 K_PLUGIN_FACTORY_WITH_JSON(DeviceAutomounterKCMFactory, "device_automounter_kcm.json", registerPlugin<DeviceAutomounterKCM>(); 0030 registerPlugin<DeviceAutomounterData>();) 0031 0032 DeviceAutomounterKCM::DeviceAutomounterKCM(QWidget *parent, const QVariantList &args) 0033 : KCModule(parent, args) // DeviceAutomounterKCMFactory::componentData(), parent) 0034 , m_settings(new AutomounterSettings(this)) 0035 , m_devices(new DeviceModel(m_settings, this)) 0036 { 0037 KAboutData *about = new KAboutData(QStringLiteral("kcm_device_automounter"), 0038 i18n("Device Automounter"), 0039 QStringLiteral("2.0"), 0040 QString(), 0041 KAboutLicense::GPL_V2, 0042 i18n("(c) 2009 Trever Fischer, (c) 2015 Kai Uwe Broulik")); 0043 about->addAuthor(i18n("Trever Fischer"), i18n("Original Author")); 0044 about->addAuthor(i18n("Kai Uwe Broulik"), i18n("Plasma 5 Port"), QStringLiteral("kde@privat.broulik.de")); 0045 0046 setAboutData(about); 0047 setupUi(this); 0048 0049 addConfig(m_settings, this); 0050 0051 deviceView->setModel(m_devices); 0052 0053 deviceView->header()->setSectionResizeMode(QHeaderView::ResizeToContents); 0054 deviceView->header()->setSectionResizeMode(0, QHeaderView::Stretch); 0055 0056 connect(kcfg_AutomountUnknownDevices, &QCheckBox::stateChanged, this, [this](int state) { 0057 m_devices->setAutomaticUnknown(state == Qt::Checked); 0058 }); 0059 0060 connect(deviceView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &DeviceAutomounterKCM::updateForgetDeviceButton); 0061 connect(forgetDevice, &QAbstractButton::clicked, this, &DeviceAutomounterKCM::forgetSelectedDevices); 0062 0063 connect(m_devices, &QAbstractItemModel::dataChanged, this, &DeviceAutomounterKCM::updateState); 0064 } 0065 0066 DeviceAutomounterKCM::~DeviceAutomounterKCM() 0067 { 0068 saveLayout(); 0069 } 0070 0071 void DeviceAutomounterKCM::updateState() 0072 { 0073 kcfg_AutomountUnknownDevices->setEnabled(m_settings->automountOnLogin() || m_settings->automountOnPlugin()); 0074 0075 unmanagedWidgetChangeState(m_unmanagedChanges || m_settings->usrIsSaveNeeded()); 0076 unmanagedWidgetDefaultState(m_settings->isDefaults()); 0077 } 0078 0079 void DeviceAutomounterKCM::updateForgetDeviceButton() 0080 { 0081 const auto selectedIndexes = deviceView->selectionModel()->selectedIndexes(); 0082 const bool isAnyDettached = std::any_of(selectedIndexes.cbegin(), selectedIndexes.cend(), [](const auto &idx) { 0083 return idx.data(DeviceModel::TypeRole) == DeviceModel::Detached; 0084 }); 0085 forgetDevice->setEnabled(isAnyDettached); 0086 } 0087 0088 void DeviceAutomounterKCM::forgetSelectedDevices() 0089 { 0090 QItemSelectionModel *selected = deviceView->selectionModel(); 0091 int offset = 0; 0092 while (!selected->selectedIndexes().isEmpty() && selected->selectedIndexes().size() > offset) { 0093 if (selected->selectedIndexes()[offset].data(DeviceModel::TypeRole) == DeviceModel::Attached) { 0094 offset++; 0095 } else { 0096 m_devices->forgetDevice(selected->selectedIndexes()[offset].data(DeviceModel::UdiRole).toString()); 0097 } 0098 } 0099 0100 m_unmanagedChanges = true; 0101 updateState(); 0102 } 0103 0104 void DeviceAutomounterKCM::load() 0105 { 0106 KCModule::load(); 0107 0108 m_devices->reload(); 0109 loadLayout(); 0110 0111 kcfg_AutomountUnknownDevices->setChecked(m_settings->automountUnknownDevices()); 0112 0113 m_unmanagedChanges = false; 0114 updateState(); 0115 } 0116 0117 void DeviceAutomounterKCM::save() 0118 { 0119 KCModule::save(); 0120 saveLayout(); 0121 0122 // Housekeeping before saving. 0123 // 1. Detect if any of the automount options is set to globally enable automounting 0124 // 2. Clean-up removed setting groups 0125 bool enabled = m_settings->automountOnLogin() || m_settings->automountOnPlugin(); 0126 QStringList validDevices; 0127 0128 for (const QModelIndex &idx : {m_devices->index(DeviceModel::RowAttached, 0), m_devices->index(DeviceModel::RowDetached, 0)}) { 0129 for (int j = 0; j < m_devices->rowCount(idx); ++j) { 0130 const QString udi = m_devices->index(j, 0, idx).data(DeviceModel::UdiRole).toString(); 0131 validDevices << udi; 0132 enabled |= m_settings->deviceSettings(udi)->mountOnLogin() | m_settings->deviceSettings(udi)->mountOnAttach(); 0133 } 0134 } 0135 0136 m_settings->setAutomountEnabled(enabled); 0137 0138 const auto knownDevices = m_settings->knownDevices(); 0139 for (const QString &possibleDevice : knownDevices) { 0140 if (!validDevices.contains(possibleDevice)) { 0141 m_settings->removeDeviceGroup(possibleDevice); 0142 } 0143 } 0144 0145 m_settings->save(); 0146 0147 // Now tell kded to automatically load the module if loaded 0148 QDBusConnection dbus = QDBusConnection::sessionBus(); 0149 QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kded5"), 0150 QStringLiteral("/kded"), 0151 QStringLiteral("org.kde.kded5"), 0152 QStringLiteral("setModuleAutoloading")); 0153 msg.setArguments({QVariant(QStringLiteral("device_automounter")), QVariant(enabled)}); 0154 dbus.call(msg, QDBus::NoBlock); 0155 0156 // Load or unload right away 0157 msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kded5"), 0158 QStringLiteral("/kded"), 0159 QStringLiteral("org.kde.kded5"), 0160 enabled ? QStringLiteral("loadModule") : QStringLiteral("unloadModule")); 0161 msg.setArguments({QVariant(QStringLiteral("device_automounter"))}); 0162 dbus.call(msg, QDBus::NoBlock); 0163 } 0164 0165 void DeviceAutomounterKCM::defaults() 0166 { 0167 KCModule::defaults(); 0168 0169 m_settings->setDefaults(); 0170 m_devices->updateCheckedColumns(); 0171 } 0172 0173 void DeviceAutomounterKCM::saveLayout() 0174 { 0175 QList<int> widths; 0176 const int nbColumn = m_devices->columnCount(); 0177 widths.reserve(nbColumn); 0178 0179 for (int i = 0; i < nbColumn; ++i) { 0180 widths << deviceView->columnWidth(i); 0181 } 0182 0183 LayoutSettings::setHeaderWidths(widths); 0184 LayoutSettings::setAttachedExpanded(deviceView->isExpanded(m_devices->index(DeviceModel::RowAttached, 0))); 0185 LayoutSettings::setDetachedExpanded(deviceView->isExpanded(m_devices->index(DeviceModel::RowDetached, 0))); 0186 LayoutSettings::self()->save(); 0187 } 0188 0189 void DeviceAutomounterKCM::loadLayout() 0190 { 0191 LayoutSettings::self()->load(); 0192 // Reset it first, just in case there isn't any layout saved for a particular column. 0193 int nbColumn = m_devices->columnCount(); 0194 for (int i = 0; i < nbColumn; ++i) { 0195 deviceView->resizeColumnToContents(i); 0196 } 0197 0198 QList<int> widths = LayoutSettings::headerWidths(); 0199 nbColumn = m_devices->columnCount(); 0200 for (int i = 0; i < nbColumn && i < widths.size(); ++i) { 0201 deviceView->setColumnWidth(i, widths[i]); 0202 } 0203 0204 deviceView->setExpanded(m_devices->index(DeviceModel::RowAttached, 0), LayoutSettings::attachedExpanded()); 0205 deviceView->setExpanded(m_devices->index(DeviceModel::RowDetached, 0), LayoutSettings::detachedExpanded()); 0206 } 0207 0208 #include "DeviceAutomounterKCM.moc"