/* * Copyright 2015 Timothy Pearson * * This file is part of hwdevicetray, the TDE Hardware Device Monitor System Tray Application * * hwdevicetray 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 3 * of the License, or (at your option) any later version. * * hwdevicetray 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 cryptocardwatcher. If not, see http://www.gnu.org/licenses/. */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include #include "kprocess.h" #include #include #include #include #include #include #include #include #include #include #include "tdepassivepopupstack.h" #include #include #include #include "hwdevicetray.h" #include "hwdevicetray_configdialog.h" // Storage Device Action namespace SDActions { // use 'int' as underlying type to avoid exposing a bunch of unnecessary // enums/structs in the class header file private methods' signature // Note: must start from 0 because the Type value is also used as index // of a TQValueVector enum Type : int { Open = 0, Mount, Unmount, Unlock, Lock, Eject, SafeRemove, Properties }; struct Details { const char *iconName; const char *actionName; const char *collectionName; }; // Allows to use a for loop to iterate over all action types static const Type All[] = { Open, Mount, Unmount, Unlock, Lock, Eject, SafeRemove, Properties }; static const TQMap populateMap() { TQMap map; map[Open] = { "window-new", I18N_NOOP("Open"), "open_menu" }; map[Mount] = { "drive-harddisk-mounted", I18N_NOOP("Mount"), "mount_menu" }; map[Unmount] = { "drive-harddisk-unmounted", I18N_NOOP("Unmount"), "unmount_menu" }; map[Unlock] = { "decrypted", I18N_NOOP("Unlock"), "unlock_menu" }; map[Lock] = { "encrypted", I18N_NOOP("Lock"), "lock_menu" }; map[Eject] = { "player_eject", I18N_NOOP("Eject"), "eject_menu" }; map[SafeRemove] = { "player_safe_removal", I18N_NOOP("Safe remove"), "safe_remove_menu" }; map[Properties] = { "edit", I18N_NOOP("Properties"), "properties_menu" }; return map; } static const TQMap Data = populateMap(); } // Storage Device Action Menu Entry, representing an action // and the storage device on which to perform it struct SDActionMenuEntry { SDActions::Type actionType; TQString uuid; }; struct KnownDiskDeviceInfo { TQString deviceLabel; TQString node; }; class HwDeviceSystemTrayPrivate { public: HwDeviceSystemTrayPrivate() { } ~HwDeviceSystemTrayPrivate() { } // Members TDEAction *m_deviceManagerAction; TDEAction *m_quitAction; TDEAction *m_shortcutKeysAction; KHelpMenu *m_helpMenu; TDEPopupMenu *m_LMBMenu; TDEPopupMenu *m_RMBMenu; TQMap m_actionMenuEntryMap; TQMap m_RMBActionMenuMap; TQMap m_knownDiskDevices; TDEPassivePopupStackContainer *m_hardwareNotifierContainer; }; HwDeviceSystemTray::HwDeviceSystemTray(TQWidget *parent, const char *name) : KSystemTray(parent, name), d(new HwDeviceSystemTrayPrivate()) { // Create notifier d->m_hardwareNotifierContainer = new TDEPassivePopupStackContainer(); connect(d->m_hardwareNotifierContainer, TQ_SIGNAL(popupClicked(KPassivePopup*, TQPoint, TQString)), this, TQ_SLOT(devicePopupClicked(KPassivePopup*, TQPoint, TQString))); initMenus(); setPixmap(KSystemTray::loadIcon("hwinfo")); setAlignment(TQt::AlignHCenter | TQt::AlignVCenter); connect(this, TQ_SIGNAL(quitSelected()), this, TQ_SLOT(quitApp())); TQToolTip::add(this, i18n("Device monitor")); globalKeys = new TDEGlobalAccel(this); TDEGlobalAccel* keys = globalKeys; #include "hwdevicetray_bindings.cpp" // the keys need to be read from tdeglobals, not kickerrc globalKeys->readSettings(); globalKeys->setEnabled(true); globalKeys->updateConnections(); connect(kapp, TQ_SIGNAL(settingsChanged(int)), TQ_SLOT(slotSettingsChanged(int))); TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); doDiskNotifications(true); connect(hwdevices, TQ_SIGNAL(hardwareAdded(TDEGenericDevice*)), this, TQ_SLOT(deviceAdded(TDEGenericDevice*))); connect(hwdevices, TQ_SIGNAL(hardwareRemoved(TDEGenericDevice*)), this, TQ_SLOT(deviceRemoved(TDEGenericDevice*))); connect(hwdevices, TQ_SIGNAL(hardwareUpdated(TDEGenericDevice*)), this, TQ_SLOT(deviceChanged(TDEGenericDevice*))); } HwDeviceSystemTray::~HwDeviceSystemTray() { delete d->m_hardwareNotifierContainer; delete d; } /*! * \b TQ_SLOT which called if hwdevicetray is exited by the user. In this case the user * is asked through a yes/no box if "HwDeviceTray should start automatically on log in" and the * result is written to the KDE configfile. */ void HwDeviceSystemTray::quitApp() { KSimpleConfig *config = new KSimpleConfig("tdehwdevicetrayrc"); TQString tmp1 = i18n("Start device monitor automatically when you log in?"); int tmp2 = KMessageBox::questionYesNo(0, tmp1, i18n("Question"), i18n("Start Automatically"), i18n("Do Not Start")); config->setGroup("General"); config->writeEntry("Autostart", tmp2 == KMessageBox::Yes); config->sync(); exit(0); } void HwDeviceSystemTray::resizeTrayIcon () { // Honor Free Desktop specifications that allow for arbitrary system tray icon sizes TQPixmap origpixmap; TQPixmap scaledpixmap; TQImage newIcon; origpixmap = KSystemTray::loadSizedIcon("hwinfo", width()); newIcon = origpixmap; newIcon = newIcon.smoothScale(width(), height()); scaledpixmap = newIcon; setPixmap(scaledpixmap); } void HwDeviceSystemTray::resizeEvent (TQResizeEvent *) { // Honor Free Desktop specifications that allow for arbitrary system tray icon sizes resizeTrayIcon(); } void HwDeviceSystemTray::showEvent (TQShowEvent *) { // Honor Free Desktop specifications that allow for arbitrary system tray icon sizes resizeTrayIcon(); } void HwDeviceSystemTray::mousePressEvent(TQMouseEvent* e) { switch (e->button()) { case TQt::LeftButton: populateLMBMenu(); d->m_LMBMenu->popup(e->globalPos()); break; case TQt::MidButton: TQTimer::singleShot(0, this, TQ_SLOT(slotHardwareConfig())); break; case TQt::RightButton: contextMenuAboutToShow(d->m_RMBMenu); d->m_RMBMenu->popup(e->globalPos()); break; default: // do nothing break; } } bool HwDeviceSystemTray::isMonitoredDevice(TDEStorageDevice* sdevice) { // Type selection logic largely duplicated from the media manager tdeioslave return ((sdevice->isDiskOfType(TDEDiskDeviceType::LUKS) || sdevice->checkDiskStatus(TDEDiskDeviceStatus::ContainsFilesystem) || sdevice->isDiskOfType(TDEDiskDeviceType::CDAudio) || sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank)) && !sdevice->checkDiskStatus(TDEDiskDeviceStatus::Hidden) && (sdevice->isDiskOfType(TDEDiskDeviceType::HDD) || sdevice->isDiskOfType(TDEDiskDeviceType::CDROM) || sdevice->isDiskOfType(TDEDiskDeviceType::CDR) || sdevice->isDiskOfType(TDEDiskDeviceType::CDRW) || sdevice->isDiskOfType(TDEDiskDeviceType::CDMO) || sdevice->isDiskOfType(TDEDiskDeviceType::CDMRRW) || sdevice->isDiskOfType(TDEDiskDeviceType::CDMRRWW) || sdevice->isDiskOfType(TDEDiskDeviceType::DVDROM) || sdevice->isDiskOfType(TDEDiskDeviceType::DVDRAM) || sdevice->isDiskOfType(TDEDiskDeviceType::DVDR) || sdevice->isDiskOfType(TDEDiskDeviceType::DVDRW) || sdevice->isDiskOfType(TDEDiskDeviceType::DVDRDL) || sdevice->isDiskOfType(TDEDiskDeviceType::DVDRWDL) || sdevice->isDiskOfType(TDEDiskDeviceType::DVDPLUSR) || sdevice->isDiskOfType(TDEDiskDeviceType::DVDPLUSRW) || sdevice->isDiskOfType(TDEDiskDeviceType::DVDPLUSRDL) || sdevice->isDiskOfType(TDEDiskDeviceType::DVDPLUSRWDL) || sdevice->isDiskOfType(TDEDiskDeviceType::BDROM) || sdevice->isDiskOfType(TDEDiskDeviceType::BDR) || sdevice->isDiskOfType(TDEDiskDeviceType::BDRW) || sdevice->isDiskOfType(TDEDiskDeviceType::HDDVDROM) || sdevice->isDiskOfType(TDEDiskDeviceType::HDDVDR) || sdevice->isDiskOfType(TDEDiskDeviceType::HDDVDRW) || sdevice->isDiskOfType(TDEDiskDeviceType::CDAudio) || sdevice->isDiskOfType(TDEDiskDeviceType::CDVideo) || sdevice->isDiskOfType(TDEDiskDeviceType::DVDVideo) || sdevice->isDiskOfType(TDEDiskDeviceType::BDVideo) || sdevice->isDiskOfType(TDEDiskDeviceType::Floppy) || sdevice->isDiskOfType(TDEDiskDeviceType::Zip) || sdevice->isDiskOfType(TDEDiskDeviceType::Jaz) || sdevice->isDiskOfType(TDEDiskDeviceType::Camera))); } void HwDeviceSystemTray::initMenus() { // RMB menu d->m_RMBMenu = contextMenu(); // Device actions for (const SDActions::Type &actionType : SDActions::All) { SDActions::Details ad = SDActions::Data[actionType]; d->m_RMBActionMenuMap.insert(actionType, new TDEActionMenu(i18n(ad.actionName), SmallIcon(ad.iconName, TQIconSet::Automatic), actionCollection(), ad.collectionName)); } // Global Configuration d->m_deviceManagerAction = new TDEAction(i18n("Show Device Manager..."), SmallIconSet("kcmpci"), TDEShortcut(), this, TQ_SLOT(slotHardwareConfig()), actionCollection()); d->m_shortcutKeysAction = new TDEAction(i18n("Configure Shortcut Keys..."), SmallIconSet("configure"), TDEShortcut(), this, TQ_SLOT(slotEditShortcutKeys()), actionCollection()); // Help & Quit d->m_helpMenu = new KHelpMenu(this, TDEGlobal::instance()->aboutData(), false, actionCollection()); d->m_helpMenu->menu()->connectItem(KHelpMenu::menuHelpContents, this, TQ_SLOT(slotHelpContents())); d->m_quitAction = actionCollection()->action(KStdAction::name(KStdAction::Quit)); // LMB menu d->m_LMBMenu = new TDEPopupMenu(this); } TQString HwDeviceSystemTray::getDeviceLabel(TDEStorageDevice *sdevice) { if (!sdevice) { return TQString::null; } DCOPRef mediamanager("kded", "mediamanager"); DCOPReply reply = mediamanager.call("properties", sdevice->deviceNode()); TQString deviceLabel = TQString::null; if (reply.isValid()) { // TODO R14.2.0: make sure the reply is a valid Medium // once the media library is part of tdelibs TQStringList properties = reply; if (properties.size() >= 4) { deviceLabel = properties[3]; // medium label } } if (deviceLabel.isEmpty()) { deviceLabel = !sdevice->diskLabel().isEmpty() ? sdevice->diskLabel() : sdevice->friendlyName(); deviceLabel += " (" + sdevice->deviceNode() + ")"; } return deviceLabel; } void HwDeviceSystemTray::addDeviceToLMBMenu(TDEStorageDevice *sdevice, const int type, TDEActionMenu *actionMenu, int &actionMenuIdx) { TQString uuid = !sdevice->diskUUID().isEmpty() ? sdevice->diskUUID() : sdevice->systemPath(); SDActions::Type actionType = (SDActions::Type)type; SDActions::Details ad = SDActions::Data[actionType]; actionMenu->popupMenu()->insertItem(SmallIcon(ad.iconName), i18n(ad.actionName), actionMenuIdx); actionMenu->popupMenu()->connectItem(actionMenuIdx, this, TQ_SLOT(slotExecuteDeviceAction(int))); d->m_actionMenuEntryMap[actionMenuIdx++] = { actionType, uuid }; } void HwDeviceSystemTray::addDeviceToRMBMenu(TDEStorageDevice *sdevice, const int type, int &actionMenuIdx) { TQString uuid = !sdevice->diskUUID().isEmpty() ? sdevice->diskUUID() : sdevice->systemPath(); SDActions::Type actionType = (SDActions::Type)type; TDEActionMenu *actionMenu = d->m_RMBActionMenuMap[actionType]; actionMenu->popupMenu()->insertItem(sdevice->icon(TDEIcon::SizeSmall), getDeviceLabel(sdevice), actionMenuIdx); actionMenu->popupMenu()->connectItem(actionMenuIdx, this, TQ_SLOT(slotExecuteDeviceAction(int))); actionMenu->setEnabled(true); d->m_actionMenuEntryMap[actionMenuIdx++] = { actionType, uuid }; } void HwDeviceSystemTray::contextMenuAboutToShow(TDEPopupMenu *menu) { d->m_RMBMenu = menu; menu->clear(); for (const SDActions::Type &actionType : SDActions::All) { TDEActionMenu *actionMenu = d->m_RMBActionMenuMap[actionType]; actionMenu->popupMenu()->clear(); actionMenu->setEnabled(false); actionMenu->unplug(d->m_RMBMenu); } d->m_actionMenuEntryMap.clear(); // Find all storage devices, sort them by label and add them to the popup menus TQValueVector*> rmbMenuEntries(sizeof(SDActions::All) / sizeof(SDActions::Type), nullptr); for (size_t idx = 0; idx < rmbMenuEntries.size(); ++idx) { rmbMenuEntries[idx] = new TQMap(); } TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); TDEGenericHardwareList diskDeviceList = hwdevices->listByDeviceClass(TDEGenericDeviceType::Disk); for (TDEGenericDevice *hwdevice = diskDeviceList.first(); hwdevice; hwdevice = diskDeviceList.next()) { TDEStorageDevice *sdevice = static_cast(hwdevice); if (isMonitoredDevice(sdevice)) { TQString deviceLabel = getDeviceLabel(sdevice); if (sdevice->isDiskOfType(TDEDiskDeviceType::LUKS) || sdevice->isDiskOfType(TDEDiskDeviceType::OtherCrypted)) { if (sdevice->isDiskOfType(TDEDiskDeviceType::UnlockedCrypt)) { (*rmbMenuEntries[SDActions::Lock])[deviceLabel] = sdevice; } else { (*rmbMenuEntries[SDActions::Unlock])[deviceLabel] = sdevice; } } if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Mountable)) { if (sdevice->mountPath().isEmpty()) { (*rmbMenuEntries[SDActions::Mount])[deviceLabel] = sdevice; } else { (*rmbMenuEntries[SDActions::Unmount])[deviceLabel] = sdevice; } // Mounted and unmounted disks can also be opened (*rmbMenuEntries[SDActions::Open])[deviceLabel] = sdevice; } if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Removable) || sdevice->checkDiskStatus(TDEDiskDeviceStatus::Hotpluggable)) { (*rmbMenuEntries[SDActions::Eject])[deviceLabel] = sdevice; (*rmbMenuEntries[SDActions::SafeRemove])[deviceLabel] = sdevice; } (*rmbMenuEntries[SDActions::Properties])[deviceLabel] = sdevice; } } // Plug in meaningful action menus d->m_RMBMenu->insertTitle(SmallIcon("drive-harddisk-unmounted"), i18n("Storage Device Actions"), 0); int actionMenuIdx = 0; for (const SDActions::Type &actionType : SDActions::All) { TDEActionMenu *actionMenu = d->m_RMBActionMenuMap[actionType]; for (TDEStorageDevice *sdevice : *rmbMenuEntries[actionType]) { addDeviceToRMBMenu(sdevice, actionType, actionMenuIdx); } if (actionMenu->isEnabled()) { actionMenu->plug(d->m_RMBMenu); } delete rmbMenuEntries[actionType]; rmbMenuEntries[actionType] = nullptr; } // Global Configuration menu->insertTitle(SmallIcon("configure"), i18n("Global Configuration")); d->m_deviceManagerAction->plug(menu); d->m_shortcutKeysAction->plug(menu); // Help & Quit menu->insertSeparator(); menu->insertItem(SmallIcon("help"), KStdGuiItem::help().text(), d->m_helpMenu->menu()); d->m_quitAction->plug(menu); } void HwDeviceSystemTray::populateLMBMenu() { d->m_LMBMenu->clear(); d->m_LMBMenu->insertTitle(SmallIcon("drive-harddisk-unmounted"), i18n("Storage Devices"), 0); d->m_actionMenuEntryMap.clear(); int actionMenuIdx = 0; // Find all storage devices and add them to the popup menus TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); TDEGenericHardwareList diskDeviceList = hwdevices->listByDeviceClass(TDEGenericDeviceType::Disk); TQMap lmbMenuEntries; for (TDEGenericDevice *hwdevice = diskDeviceList.first(); hwdevice; hwdevice = diskDeviceList.next()) { TDEStorageDevice *sdevice = static_cast(hwdevice); if (isMonitoredDevice(sdevice) && (sdevice->isDiskOfType(TDEDiskDeviceType::LUKS) || sdevice->isDiskOfType(TDEDiskDeviceType::OtherCrypted) || sdevice->checkDiskStatus(TDEDiskDeviceStatus::Mountable) || sdevice->checkDiskStatus(TDEDiskDeviceStatus::Removable) || sdevice->checkDiskStatus(TDEDiskDeviceStatus::Hotpluggable))) { TQString deviceLabel = getDeviceLabel(sdevice); TDEActionMenu *actionMenu = new TDEActionMenu(deviceLabel, sdevice->icon(TDEIcon::SizeSmall)); if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Mountable)) { // Mounted and unmounted disks can also be opened addDeviceToLMBMenu(sdevice, SDActions::Open, actionMenu, actionMenuIdx); if (sdevice->mountPath().isEmpty()) { addDeviceToLMBMenu(sdevice, SDActions::Mount, actionMenu, actionMenuIdx); } else { addDeviceToLMBMenu(sdevice, SDActions::Unmount, actionMenu, actionMenuIdx); } } if (sdevice->isDiskOfType(TDEDiskDeviceType::LUKS) || sdevice->isDiskOfType(TDEDiskDeviceType::OtherCrypted)) { if (sdevice->isDiskOfType(TDEDiskDeviceType::UnlockedCrypt)) { addDeviceToLMBMenu(sdevice, SDActions::Lock, actionMenu, actionMenuIdx); } else { addDeviceToLMBMenu(sdevice, SDActions::Unlock, actionMenu, actionMenuIdx); } } if (sdevice->checkDiskStatus(TDEDiskDeviceStatus::Removable) || sdevice->checkDiskStatus(TDEDiskDeviceStatus::Hotpluggable)) { addDeviceToLMBMenu(sdevice, SDActions::Eject, actionMenu, actionMenuIdx); addDeviceToLMBMenu(sdevice, SDActions::SafeRemove, actionMenu, actionMenuIdx); } addDeviceToLMBMenu(sdevice, SDActions::Properties, actionMenu, actionMenuIdx); lmbMenuEntries[deviceLabel] = actionMenu; } } // Insert menu entries in sorted order for (TDEActionMenu *am : lmbMenuEntries) { am->plug(d->m_LMBMenu); } } void HwDeviceSystemTray::slotExecuteDeviceAction(int parameter) { TQString uuid = d->m_actionMenuEntryMap[parameter].uuid; int actionType = d->m_actionMenuEntryMap[parameter].actionType; if (!uuid.isEmpty()) { TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); TDEGenericHardwareList diskDeviceList = hwdevices->listByDeviceClass(TDEGenericDeviceType::Disk); for (TDEGenericDevice *hwdevice = diskDeviceList.first(); hwdevice; hwdevice = diskDeviceList.next()) { TDEStorageDevice *sdevice = static_cast(hwdevice); if ((sdevice->diskUUID() == uuid) || (sdevice->systemPath() == uuid)) { if (actionType == SDActions::Open) { if (sdevice->isDiskOfType(TDEDiskDeviceType::Camera)) { new KRun(TQString("media:/%1").arg(sdevice->friendlyName())); } else { new KRun(TQString("system:/media/%1").arg(TQFileInfo(sdevice->deviceNode()).baseName(true))); } } else if (actionType == SDActions::Properties) { new KPropertiesDialog(KURL(TQString("media:/%1").arg(sdevice->deviceNode()))); } else { TQString opType = TQString::null; if (actionType == SDActions::Mount) { opType = "-m"; } else if (actionType == SDActions::Unmount) { opType = "-u"; } else if (actionType == SDActions::Unlock) { opType = "-k"; } else if (actionType == SDActions::Lock) { opType = "-l"; } else if (actionType == SDActions::Eject) { opType = "-e"; } else if (actionType == SDActions::SafeRemove) { opType = "-s"; } if (!opType.isEmpty()) { TDEProcess proc; proc << "tdeio_media_mounthelper" << opType << sdevice->deviceNode(); if (!proc.start(TDEProcess::DontCare)) { KMessageBox::error(this, i18n("Could not start tdeio_media_mounthelper process."), i18n("Device monitor")); } } } } } } } void HwDeviceSystemTray::slotHardwareConfig() { KCMultiDialog *kcm = new KCMultiDialog(KDialogBase::Plain, i18n("Configure"), this); kcm->addModule("hwmanager"); kcm->setPlainCaption(i18n("Configure Devices")); kcm->exec(); } void HwDeviceSystemTray::slotSettingsChanged(int category) { if (category == (int) TDEApplication::SETTINGS_SHORTCUTS) { globalKeys->readSettings(); globalKeys->updateConnections(); } } void HwDeviceSystemTray::slotEditShortcutKeys() { ConfigDialog *dlg = new ConfigDialog(globalKeys, true); if (dlg->exec() == TQDialog::Accepted) { dlg->commitShortcuts(); globalKeys->writeSettings(0, true); globalKeys->updateConnections(); } delete dlg; } void HwDeviceSystemTray::doDiskNotifications(bool scanOnly) { TDEConfig config("mediamanagerrc"); config.setGroup("Global"); bool popupEnable = config.readBoolEntry("DeviceMonitorPopupsEnabled", true); // Scan devices for changes and notify new devices if needed. // This is necessary because the device information may not be available // at the time the hardwareAdded signal is emitted TQMap oldKnownDevices = d->m_knownDiskDevices; d->m_knownDiskDevices.clear(); TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); TDEGenericHardwareList diskDeviceList = hwdevices->listByDeviceClass(TDEGenericDeviceType::Disk); for (TDEGenericDevice *hwdevice = diskDeviceList.first(); hwdevice; hwdevice = diskDeviceList.next()) { TDEStorageDevice *sdevice = static_cast(hwdevice); if (isMonitoredDevice(sdevice)) { TQString sysPath = sdevice->systemPath(); if (oldKnownDevices.contains(sysPath)) { d->m_knownDiskDevices[sysPath] = oldKnownDevices[sysPath]; oldKnownDevices.remove(sysPath); } else { TQString deviceLabel = getDeviceLabel(sdevice); d->m_knownDiskDevices[sysPath] = { deviceLabel, sdevice->deviceNode() }; if (!scanOnly && popupEnable) { d->m_hardwareNotifierContainer->displayMessage( i18n("A disk device has been added!"), deviceLabel, SmallIcon("drive-harddisk-unmounted"), 0, 0, "ADD: " + sysPath); } } } } // Notify devices which have been removed, if necessary if (!scanOnly && popupEnable) { TQMap::ConstIterator delIt; for (delIt = oldKnownDevices.begin(); delIt != oldKnownDevices.end(); delIt++) { d->m_hardwareNotifierContainer->displayMessage( i18n("A disk device has been removed!"), delIt.data().deviceLabel, SmallIcon("drive-harddisk-unmounted"), 0, 0, "REMOVE: " + delIt.key()); } } } void HwDeviceSystemTray::deviceAdded(TDEGenericDevice* device) { if (device->type() == TDEGenericDeviceType::Disk) { TDEStorageDevice *sdevice = static_cast(device); // The device information may not be available at the time the hardwareAdded signal is emitted. // In such case ignore the event and handle that at the subsequent hardwareUpdate signal emission. TQString sysPath = sdevice->systemPath(); if (isMonitoredDevice(sdevice) && !d->m_knownDiskDevices.contains(sysPath)) { TQString deviceLabel = getDeviceLabel(sdevice); d->m_knownDiskDevices[sysPath] = { deviceLabel, sdevice->deviceNode() }; TDEConfig config("mediamanagerrc"); config.setGroup("Global"); if (config.readBoolEntry("DeviceMonitorPopupsEnabled", true)) { d->m_hardwareNotifierContainer->displayMessage( i18n("A disk device has been added!"), deviceLabel, SmallIcon("drive-harddisk-unmounted"), 0, 0, "ADD: " + sysPath); } } } } void HwDeviceSystemTray::deviceRemoved(TDEGenericDevice* device) { if (device->type() == TDEGenericDeviceType::Disk) { TDEStorageDevice *sdevice = static_cast(device); TQString sysPath = sdevice->systemPath(); if (isMonitoredDevice(sdevice) && d->m_knownDiskDevices.contains(sysPath)) { TDEConfig config("mediamanagerrc"); config.setGroup("Global"); if (config.readBoolEntry("DeviceMonitorPopupsEnabled", true)) { TQString deviceLabel = getDeviceLabel(sdevice); d->m_hardwareNotifierContainer->displayMessage( i18n("A disk device has been removed!"), deviceLabel, SmallIcon("drive-harddisk-unmounted"), 0, 0, "REMOVE: " + sysPath); } d->m_knownDiskDevices.remove(sysPath); } } } void HwDeviceSystemTray::deviceChanged(TDEGenericDevice* device) { doDiskNotifications(false); } void HwDeviceSystemTray::devicePopupClicked(KPassivePopup* popup, TQPoint point, TQString uuid) { TDEGenericDevice *hwdevice; if (uuid.startsWith("ADD: ")) { TDEConfig config("mediamanagerrc"); config.setGroup("Global"); if (config.readBoolEntry("NotificationPopupsEnabled", true)) { return; } uuid = uuid.right(uuid.length() - strlen("ADD: ")); if (uuid != "") { TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); TDEGenericHardwareList diskDeviceList = hwdevices->listByDeviceClass(TDEGenericDeviceType::Disk); for (hwdevice = diskDeviceList.first(); hwdevice; hwdevice = diskDeviceList.next()) { TDEStorageDevice* sdevice = static_cast(hwdevice); if ((sdevice->diskUUID() == uuid) || (sdevice->systemPath() == uuid)) { // Pop up full media notification dialog DCOPClient* dcopClient = TDEApplication::dcopClient(); TQByteArray data; TQDataStream arg(data, IO_WriteOnly); bool allowNotification = true; if (sdevice->isDiskOfType(TDEDiskDeviceType::Camera)) { arg << sdevice->friendlyName(); } else { arg << TQFileInfo(sdevice->deviceNode()).baseName(true); } arg << allowNotification; dcopClient->send("kded", "medianotifier", "onMediumChange(TQString, bool)", data); return; } } } } } void HwDeviceSystemTray::slotHelpContents() { kapp->invokeHelp(TQString::null, "hwdevicetray"); } #include "hwdevicetray.moc"