From b5cb2797d65f2541a4c48ea00e6c325bb375ea46 Mon Sep 17 00:00:00 2001
From: Timothy Pearson <kb9vqf@pearsoncomputing.net>
Date: Mon, 21 Sep 2015 15:39:58 -0500
Subject: Add new hardware device tray application Allow removable media action
 request popups to be suppressed

---
 kcontrol/hwmanager/CMakeLists.txt                  |  12 +-
 kcontrol/hwmanager/hwdevicetray.cpp                | 407 +++++++++++++++++++++
 kcontrol/hwmanager/hwdevicetray.h                  |  95 +++++
 kcontrol/hwmanager/hwdevicetray_app.cpp            |  32 ++
 kcontrol/hwmanager/hwdevicetray_app.h              |  39 ++
 kcontrol/hwmanager/hwdevicetray_bindings.cpp       |  34 ++
 kcontrol/hwmanager/hwdevicetray_configdialog.cpp   |  78 ++++
 kcontrol/hwmanager/hwdevicetray_configdialog.h     |  59 +++
 kcontrol/hwmanager/hwdevicetray_main.cpp           |  51 +++
 kdesktop/lock/main.cc                              |  12 +-
 .../media/libmediacommon/mediamanagersettings.kcfg |   5 +
 .../media/mediamanager/tdehardwarebackend.cpp      |  17 +-
 tdeioslave/media/tdecmodule/managermoduleview.ui   |  12 +
 13 files changed, 842 insertions(+), 11 deletions(-)
 create mode 100644 kcontrol/hwmanager/hwdevicetray.cpp
 create mode 100644 kcontrol/hwmanager/hwdevicetray.h
 create mode 100644 kcontrol/hwmanager/hwdevicetray_app.cpp
 create mode 100644 kcontrol/hwmanager/hwdevicetray_app.h
 create mode 100644 kcontrol/hwmanager/hwdevicetray_bindings.cpp
 create mode 100644 kcontrol/hwmanager/hwdevicetray_configdialog.cpp
 create mode 100644 kcontrol/hwmanager/hwdevicetray_configdialog.h
 create mode 100644 kcontrol/hwmanager/hwdevicetray_main.cpp

diff --git a/kcontrol/hwmanager/CMakeLists.txt b/kcontrol/hwmanager/CMakeLists.txt
index 8b46dd98e..ed63faddb 100644
--- a/kcontrol/hwmanager/CMakeLists.txt
+++ b/kcontrol/hwmanager/CMakeLists.txt
@@ -1,6 +1,6 @@
 #################################################
 #
-#  (C) 2012 Timothy Pearson
+#  (C) 2012 - 2015 Timothy Pearson
 #  kb9vqf (AT) pearsoncomputing.net
 #
 #  Improvements and feedback are welcome
@@ -38,3 +38,13 @@ tde_add_kpart( kcm_hwmanager AUTOMOC
   LINK tdeio-shared
   DESTINATION ${PLUGIN_INSTALL_DIR}
 )
+
+##### tdehwdevicetray (executable) ##############
+
+tde_add_executable( tdehwdevicetray AUTOMOC
+  SOURCES
+    hwdevicetray_main.cpp hwdevicetray.cpp hwdevicetray_app.cpp
+    hwdevicetray_configdialog.cpp
+  LINK tdeio-shared tdeutils-shared tdeui-shared
+  DESTINATION ${BIN_INSTALL_DIR}
+)
\ No newline at end of file
diff --git a/kcontrol/hwmanager/hwdevicetray.cpp b/kcontrol/hwmanager/hwdevicetray.cpp
new file mode 100644
index 000000000..6927bc12e
--- /dev/null
+++ b/kcontrol/hwmanager/hwdevicetray.cpp
@@ -0,0 +1,407 @@
+/*
+ * Copyright 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net>
+ * 
+ * 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/.
+ */
+
+#include <tqtimer.h>
+#include <tqimage.h>
+#include <tqtooltip.h>
+#include <tqfileinfo.h>
+
+#include <krun.h>
+#include <tdeaction.h>
+#include <tdeapplication.h>
+#include <kcmultidialog.h>
+#include <kdebug.h>
+#include <khelpmenu.h>
+#include <kiconloader.h>
+#include <tdelocale.h>
+#include <tdepopupmenu.h>
+#include <kstdaction.h>
+#include <kstdguiitem.h>
+#include <tdeglobal.h>
+#include <tdemessagebox.h>
+#include <kpassivepopup.h>
+#include <kstandarddirs.h>
+
+#include <dcopclient.h>
+
+#include <cstdlib>
+#include <unistd.h>
+
+#include "hwdevicetray_configdialog.h"
+
+#include "hwdevicetray.h"
+
+HwDeviceSystemTray::HwDeviceSystemTray(TQWidget* parent, const char *name)
+	: KSystemTray(parent, name) {
+
+	// Create notifier
+	m_hardwareNotifierContainer = new TDEPassivePopupStackContainer();
+	connect(m_hardwareNotifierContainer, TQT_SIGNAL(popupClicked(KPassivePopup*, TQPoint, TQString)), this, TQT_SLOT(devicePopupClicked(KPassivePopup*, TQPoint, TQString)));
+
+	// Create help submenu
+	m_help = new KHelpMenu(this, TDEGlobal::instance()->aboutData(), false, actionCollection());
+	TDEPopupMenu *help = m_help->menu();
+	help->connectItem(KHelpMenu::menuHelpContents, this, TQT_SLOT(slotHelpContents()));
+
+	setPixmap(KSystemTray::loadIcon("kcmdevices"));
+	setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
+	connect(this, TQT_SIGNAL(quitSelected()), this, TQT_SLOT(_quit()));
+	TQToolTip::add(this, i18n("Hardware device monitor"));
+	m_parent = parent;
+
+	globalKeys = new TDEGlobalAccel(TQT_TQOBJECT(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, TQT_SIGNAL(settingsChanged(int)), TQT_SLOT(slotSettingsChanged(int)));
+
+	new TDEActionMenu(i18n("Open Device"), SmallIcon("connect_creating",  TQIconSet::Automatic), actionCollection(), "mount_menu");
+	new TDEActionMenu(i18n("Eject Device"), SmallIcon("connect_no",  TQIconSet::Automatic), actionCollection(), "unmount_menu");
+
+#ifdef __TDE_HAVE_TDEHWLIB
+	TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices();
+	connect(hwdevices, TQT_SIGNAL(hardwareAdded(TDEGenericDevice*)), this, TQT_SLOT(deviceAdded(TDEGenericDevice*)));
+	connect(hwdevices, TQT_SIGNAL(hardwareRemoved(TDEGenericDevice*)), this, TQT_SLOT(deviceRemoved(TDEGenericDevice*)));
+	connect(hwdevices, TQT_SIGNAL(hardwareUpdated(TDEGenericDevice*)), this, TQT_SLOT(deviceChanged(TDEGenericDevice*)));
+#endif
+}
+
+HwDeviceSystemTray::~HwDeviceSystemTray() {
+	delete m_hardwareNotifierContainer;
+}
+
+/*!
+ * \b TQT_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::_quit () {
+	r_config = new KSimpleConfig("hwdevicetrayrc");
+
+	TQString tmp1 = i18n ("Start hardware device tray automatically when you log in?");
+	int tmp2 = KMessageBox::questionYesNo (0, tmp1, i18n("Question"), i18n("Start Automatically"), i18n("Do Not Start"));
+	r_config->setGroup("General");
+	r_config->writeEntry ("Autostart", tmp2 == KMessageBox::Yes);
+	r_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("kcmdevices", 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) {
+	// Popup the context menu with left-click
+	if (e->button() == Qt::LeftButton) {
+		contextMenuAboutToShow(contextMenu());
+		contextMenu()->popup(e->globalPos());
+		e->accept();
+		return;
+	}
+
+	KSystemTray::mousePressEvent(e);
+}
+
+bool HwDeviceSystemTray::isMonitoredDevice(TDEStorageDevice* sdevice) {
+	// Type selection logic largely duplicated from the media manager tdeioslave
+	if ((sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)
+		|| sdevice->checkDiskStatus(TDEDiskDeviceStatus::ContainsFilesystem)
+		|| sdevice->isDiskOfType(TDEDiskDeviceType::CDAudio)
+		|| sdevice->checkDiskStatus(TDEDiskDeviceStatus::Blank))
+		&& !sdevice->checkDiskStatus(TDEDiskDeviceStatus::UsedByDevice)
+		&& !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)))) {
+		return true;
+	}
+	else {
+		return false;
+	}
+}
+
+void HwDeviceSystemTray::contextMenuAboutToShow(TDEPopupMenu* menu) {
+	menu->clear();
+	menu->setCheckable(true);
+
+	populateMenu(menu);
+
+	menu->insertTitle(SmallIcon("configure"), i18n("Global Configuration"));
+
+	TDEAction *actHardwareConfig = new TDEAction(i18n("Configure Hardware..."), SmallIconSet("kcmpci"), TDEShortcut(), TQT_TQOBJECT(this), TQT_SLOT(slotHardwareConfig()), actionCollection());
+	actHardwareConfig->plug(menu);
+
+	TDEAction *actShortcutKeys = new TDEAction(i18n("Configure Shortcut Keys..."), SmallIconSet("configure"), TDEShortcut(), TQT_TQOBJECT(this), TQT_SLOT(slotEditShortcutKeys()), actionCollection());
+	actShortcutKeys->plug(menu);
+
+	menu->insertItem(SmallIcon("help"), KStdGuiItem::help().text(), m_help->menu());
+	TDEAction *quitAction = actionCollection()->action(KStdAction::name(KStdAction::Quit));
+	quitAction->plug(menu);
+
+	m_menu = menu;
+}
+
+void HwDeviceSystemTray::configChanged() {
+	//
+}
+
+void HwDeviceSystemTray::populateMenu(TDEPopupMenu* menu) {
+	int lastMountIndex;
+	int lastUnmountIndex;
+	TDEGenericDevice *hwdevice;
+
+	TDEActionMenu* mountDiskActionMenu = static_cast<TDEActionMenu*>(actionCollection()->action("mount_menu"));
+	mountDiskActionMenu->popupMenu()->clear();
+	m_mountMenuIndexMap.clear();
+	TDEActionMenu* unmountDiskActionMenu = static_cast<TDEActionMenu*>(actionCollection()->action("unmount_menu"));
+	unmountDiskActionMenu->popupMenu()->clear();
+	m_mountMenuIndexMap.clear();
+
+	menu->insertTitle(SmallIcon("drive-harddisk"), i18n("Storage Devices"));
+
+	// Find all storage devices and add them to the popup menu
+	lastMountIndex = 1;
+	lastUnmountIndex = 1;
+	TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices();
+	TDEGenericHardwareList diskDeviceList = hwdevices->listByDeviceClass(TDEGenericDeviceType::Disk);
+	for (hwdevice = diskDeviceList.first(); hwdevice; hwdevice = diskDeviceList.next()) {
+		TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice);
+		if (isMonitoredDevice(sdevice)) {
+			lastMountIndex = mountDiskActionMenu->popupMenu()->insertItem(hwdevice->icon(TDEIcon::SizeSmall), i18n("%1 (%2)").arg(sdevice->friendlyName(), sdevice->deviceNode()));
+			mountDiskActionMenu->popupMenu()->connectItem(lastMountIndex, this, TQT_SLOT(slotMountDevice(int)));
+			m_mountMenuIndexMap[lastMountIndex] = sdevice->diskUUID();
+			if (sdevice->mountPath() != TQString::null) {
+				lastUnmountIndex = unmountDiskActionMenu->popupMenu()->insertItem(hwdevice->icon(TDEIcon::SizeSmall), i18n("%1 (%2)").arg(sdevice->friendlyName(), sdevice->deviceNode()));
+				unmountDiskActionMenu->popupMenu()->connectItem(lastUnmountIndex, this, TQT_SLOT(slotUnmountDevice(int)));
+				m_unmountMenuIndexMap[lastUnmountIndex] = sdevice->diskUUID();
+			}
+		}
+	}
+
+	if (lastMountIndex == 0) {
+		mountDiskActionMenu->setEnabled(false);
+	}
+	else {
+		mountDiskActionMenu->setEnabled(true);
+	}
+	if (lastUnmountIndex == 0) {
+		unmountDiskActionMenu->setEnabled(false);
+	}
+	else {
+		unmountDiskActionMenu->setEnabled(true);
+	}
+
+	mountDiskActionMenu->plug(menu);
+	unmountDiskActionMenu->plug(menu);
+}
+
+void HwDeviceSystemTray::slotMountDevice(int parameter)
+{
+	TDEGenericDevice *hwdevice;
+	TQString uuid = m_mountMenuIndexMap[parameter];
+	if (uuid != "") {
+		TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices();
+		TDEGenericHardwareList diskDeviceList = hwdevices->listByDeviceClass(TDEGenericDeviceType::Disk);
+		for (hwdevice = diskDeviceList.first(); hwdevice; hwdevice = diskDeviceList.next()) {
+			TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice);
+			if (sdevice->diskUUID() == uuid) {
+				if (sdevice->isDiskOfType(TDEDiskDeviceType::Camera)) {
+					new KRun(TQString("system:/media/%1").arg(sdevice->friendlyName()));
+				}
+				else {
+					new KRun(TQString("system:/media/%1").arg(TQFileInfo(sdevice->deviceNode()).baseName(true)));
+				}
+				return;
+			}
+		}
+	}
+}
+
+void HwDeviceSystemTray::slotUnmountDevice(int parameter)
+{
+	TDEGenericDevice *hwdevice;
+	TQString uuid = m_unmountMenuIndexMap[parameter];
+	if (uuid != "") {
+		TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices();
+		TDEGenericHardwareList diskDeviceList = hwdevices->listByDeviceClass(TDEGenericDeviceType::Disk);
+		for (hwdevice = diskDeviceList.first(); hwdevice; hwdevice = diskDeviceList.next()) {
+			TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(hwdevice);
+			if (sdevice->diskUUID() == uuid) {
+				if (sdevice->mountPath() != TQString::null) {
+					int retcode;
+					TQString errstr;
+					if (!sdevice->unmountDevice(&errstr, &retcode)) {
+						KMessageBox::error(0, i18n("<qt><b>Unable to eject device</b><p>Detailed error information:<br>%1 (code %2)</qt>").arg(errstr).arg(retcode), i18n("Eject Failed"));
+					}
+					return;
+				}
+			}
+		}
+	}
+}
+
+void HwDeviceSystemTray::slotHardwareConfig() {
+	KCMultiDialog *kcm = new KCMultiDialog(KDialogBase::Plain, i18n("Configure"), this);
+
+	kcm->addModule("hwmanager");
+	kcm->setPlainCaption(i18n("Configure Hardware"));
+	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::deviceAdded(TDEGenericDevice* device) {
+#ifdef __TDE_HAVE_TDEHWLIB
+	if (device->type() == TDEGenericDeviceType::Disk) {
+		TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(device);
+		if (isMonitoredDevice(sdevice)) {
+			m_hardwareNotifierContainer->displayMessage(
+				i18n("A disk device has been added!"),
+				i18n("%1 (%2)").arg(sdevice->friendlyName(), sdevice->deviceNode()), SmallIcon("drive-harddisk"),
+				0, 0, "ADD: " + sdevice->diskUUID());
+		}
+	}
+#endif
+}
+
+void HwDeviceSystemTray::deviceRemoved(TDEGenericDevice* device) {
+#ifdef __TDE_HAVE_TDEHWLIB
+	if (device->type() == TDEGenericDeviceType::Disk) {
+		TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(device);
+		if (isMonitoredDevice(sdevice)) {
+			m_hardwareNotifierContainer->displayMessage(
+				i18n("A disk device has been removed!"),
+				i18n("%1 (%2)").arg(sdevice->friendlyName(), sdevice->deviceNode()), SmallIcon("drive-harddisk"),
+				0, 0, "REMOVE: " + sdevice->diskUUID());
+		}
+	}
+#endif
+}
+
+void HwDeviceSystemTray::deviceChanged(TDEGenericDevice* device) {
+#ifdef __TDE_HAVE_TDEHWLIB
+	if (device->type() == TDEGenericDeviceType::Disk) {
+		TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(device);
+		if (isMonitoredDevice(sdevice)) {
+			m_hardwareNotifierContainer->displayMessage(
+				i18n("A disk device has been changed!"),
+				i18n("%1 (%2)").arg(sdevice->friendlyName(), sdevice->deviceNode()), SmallIcon("drive-harddisk"),
+				0, 0, "CHANGE: " + sdevice->diskUUID());
+		}
+	}
+#endif
+}
+
+void HwDeviceSystemTray::devicePopupClicked(KPassivePopup* popup, TQPoint point, TQString uuid) {
+	TDEGenericDevice *hwdevice;
+	if (uuid.startsWith("ADD: ")) {
+		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<TDEStorageDevice*>(hwdevice);
+				if (sdevice->diskUUID() == uuid) {
+					// Pop up full media notification dialog
+					DCOPClient* dcopClient = TDEApplication::dcopClient();
+					TQByteArray data;
+					TQDataStream arg(data, IO_WriteOnly);
+					bool allowNotification = true;
+					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"
\ No newline at end of file
diff --git a/kcontrol/hwmanager/hwdevicetray.h b/kcontrol/hwmanager/hwdevicetray.h
new file mode 100644
index 000000000..d49f5b4b3
--- /dev/null
+++ b/kcontrol/hwmanager/hwdevicetray.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net>
+ * 
+ * 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/.
+ */
+
+#ifndef TDEHWDEVICETRAY_H
+#define TDEHWDEVICETRAY_H
+
+#include <tqptrlist.h>
+
+#include <ksystemtray.h>
+#include <kglobalaccel.h>
+#include <ksimpleconfig.h>
+#include <tdepassivepopupstack.h>
+
+#ifdef __TDE_HAVE_TDEHWLIB
+#include <tdehardwaredevices.h>
+#else
+#define TDEGenericDevice void
+#endif
+
+class KHelpMenu;
+class TDEPopupMenu;
+
+typedef TQMap<int, TQString> TQStringMap;
+
+class HwDeviceSystemTray :  public KSystemTray
+{
+	Q_OBJECT
+
+public:
+	HwDeviceSystemTray(TQWidget* parent = 0, const char *name = 0);
+	~HwDeviceSystemTray();
+	TDEGlobalAccel *globalKeys;
+
+	virtual void contextMenuAboutToShow(TDEPopupMenu* menu);
+
+	void configChanged();
+
+protected slots:
+	void slotHardwareConfig();
+	void slotEditShortcutKeys();
+	void slotSettingsChanged(int category);
+	void slotHelpContents();
+
+	void slotMountDevice(int parameter);
+	void slotUnmountDevice(int parameter);
+
+protected:
+	void mousePressEvent(TQMouseEvent *e);
+	void resizeEvent(TQResizeEvent *);
+	void showEvent(TQShowEvent *);
+
+private slots:
+	void _quit();
+	void deviceAdded(TDEGenericDevice*);
+	void deviceRemoved(TDEGenericDevice*);
+	void deviceChanged(TDEGenericDevice*);
+
+	void devicePopupClicked(KPassivePopup*, TQPoint, TQString);
+
+private:
+	bool isMonitoredDevice(TDEStorageDevice* sdevice);
+
+private:
+	void populateMenu(TDEPopupMenu* menu);
+	void resizeTrayIcon();
+
+	bool m_popupUp;
+	KHelpMenu* m_help;
+
+	TQWidget* m_parent;
+	TDEPassivePopupStackContainer* m_hardwareNotifierContainer;
+
+	TQStringMap m_mountMenuIndexMap;
+	TQStringMap m_unmountMenuIndexMap;
+	TDEPopupMenu* m_menu;
+	KSimpleConfig *r_config;
+};
+
+#endif
diff --git a/kcontrol/hwmanager/hwdevicetray_app.cpp b/kcontrol/hwmanager/hwdevicetray_app.cpp
new file mode 100644
index 000000000..3f96f76a4
--- /dev/null
+++ b/kcontrol/hwmanager/hwdevicetray_app.cpp
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net>
+ * 
+ * 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/.
+ */
+
+#include <kdebug.h>
+
+#include "hwdevicetray_app.h"
+
+#include "hwdevicetray.h"
+
+HwDeviceApp::HwDeviceApp()
+	: m_tray(new HwDeviceSystemTray(0L, "HwDeviceTray"))
+{
+	m_tray->show();
+}
+
+#include "hwdevicetray_app.moc"
\ No newline at end of file
diff --git a/kcontrol/hwmanager/hwdevicetray_app.h b/kcontrol/hwmanager/hwdevicetray_app.h
new file mode 100644
index 000000000..fae4d6cd9
--- /dev/null
+++ b/kcontrol/hwmanager/hwdevicetray_app.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net>
+ * 
+ * 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/.
+ */
+
+#ifndef TDEHWDEVICEAPP_H
+#define TDEHWDEVICEAPP_H
+
+#include <tqtimer.h>
+#include <kuniqueapplication.h>
+
+class HwDeviceSystemTray;
+
+class HwDeviceApp : public KUniqueApplication
+{
+	Q_OBJECT
+	
+	public:
+		HwDeviceApp();
+	
+	private:
+		HwDeviceSystemTray* m_tray;
+};
+
+#endif
diff --git a/kcontrol/hwmanager/hwdevicetray_bindings.cpp b/kcontrol/hwmanager/hwdevicetray_bindings.cpp
new file mode 100644
index 000000000..216b1a709
--- /dev/null
+++ b/kcontrol/hwmanager/hwdevicetray_bindings.cpp
@@ -0,0 +1,34 @@
+// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8; -*-
+/* This file is part of the KDE project
+   Copyright (C) by Andrew Stanley-Jones
+
+   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; see the file COPYING.  If not, write to
+   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.
+*/
+#ifndef NOSLOTS
+# define DEF( name, key3, key4, fnSlot ) \
+   keys->insert( name, i18n(name), TQString(), key3, key4, TQT_TQOBJECT(this), TQT_SLOT(fnSlot) )
+#else
+# define DEF( name, key3, key4, fnSlot ) \
+   keys->insert( name, i18n(name), TQString(), key3, key4 )
+#endif
+#define WIN KKey::QtWIN
+
+	keys->insert( "Program:hwdevicetray", i18n("Hardware Device Control") );
+
+	// DEF( I18N_NOOP("Switch Displays"), TDEShortcut(TQString("XF86Display")), TDEShortcut(TQString("XF86Display")), slotCycleDisplays() );
+
+#undef DEF
+#undef WIN
diff --git a/kcontrol/hwmanager/hwdevicetray_configdialog.cpp b/kcontrol/hwmanager/hwdevicetray_configdialog.cpp
new file mode 100644
index 000000000..648cdd72f
--- /dev/null
+++ b/kcontrol/hwmanager/hwdevicetray_configdialog.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net>
+ * 
+ * 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/.
+ */
+
+#include <tqlabel.h>
+#include <tqlayout.h>
+#include <tqlistview.h>
+#include <tqpushbutton.h>
+#include <tqtooltip.h>
+#include <tqwhatsthis.h>
+#include <tqvbuttongroup.h>
+#include <assert.h>
+
+#include <kiconloader.h>
+#include <tdelocale.h>
+#include <tdepopupmenu.h>
+#include <twinmodule.h>
+#include <kregexpeditorinterface.h>
+#include <tdeparts/componentfactory.h>
+
+#include "hwdevicetray_configdialog.h"
+
+ConfigDialog::ConfigDialog(TDEGlobalAccel *accel, bool isApplet)
+	: KDialogBase(Tabbed, i18n("Configure"), Ok | Cancel | Help, Ok, 0L, "config dialog") {
+	if (isApplet) {
+		setHelp(TQString::null, "tderandrtray");
+	}
+	
+	TQFrame *w = 0L; // the parent for the widgets
+	
+	w = addVBoxPage(i18n("Global &Shortcuts"));
+	keysWidget = new KKeyChooser(accel, w);
+}
+
+
+ConfigDialog::~ConfigDialog() {
+}
+
+// prevent huge size due to long regexps in the action-widget
+void ConfigDialog::show() {
+	if (!isVisible()) {
+		KWinModule module(0, KWinModule::INFO_DESKTOP);
+		TQSize s1 = sizeHint();
+		TQSize s2 = module.workArea().size();
+		int w = s1.width();
+		int h = s1.height();
+	
+		if (s1.width() >= s2.width())
+		w = s2.width();
+		if (s1.height() >= s2.height())
+		h = s2.height();
+	
+		resize(w, h);
+	}
+	
+	KDialogBase::show();
+}
+
+void ConfigDialog::commitShortcuts() {
+	keysWidget->commitChanges();
+}
+
+#include "hwdevicetray_configdialog.moc"
diff --git a/kcontrol/hwmanager/hwdevicetray_configdialog.h b/kcontrol/hwmanager/hwdevicetray_configdialog.h
new file mode 100644
index 000000000..657b3ee43
--- /dev/null
+++ b/kcontrol/hwmanager/hwdevicetray_configdialog.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net>
+ * 
+ * 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/.
+ */
+
+#ifndef HWDEVICETRAY_CONFIGDIALOG_H
+#define HWDEVICETRAY_CONFIGDIALOG_H
+
+#include <tqcheckbox.h>
+#include <tqevent.h>
+#include <tqgroupbox.h>
+#include <tqheader.h>
+#include <tqradiobutton.h>
+#include <tqvbox.h>
+
+#include <kdialogbase.h>
+#include <keditlistbox.h>
+#include <kkeydialog.h>
+#include <tdelistview.h>
+#include <knuminput.h>
+
+class TDEGlobalAccel;
+class KKeyChooser;
+class TDEListView;
+class TQPushButton;
+class TQDialog;
+class ConfigDialog;
+
+class ConfigDialog : public KDialogBase
+{
+	Q_OBJECT
+	
+	public:
+		ConfigDialog(TDEGlobalAccel *accel, bool isApplet );
+		~ConfigDialog();
+
+		virtual void show();
+		void commitShortcuts();
+	
+	private:
+		KKeyChooser *keysWidget;
+	
+};
+
+#endif // CONFIGDIALOG_H
diff --git a/kcontrol/hwmanager/hwdevicetray_main.cpp b/kcontrol/hwmanager/hwdevicetray_main.cpp
new file mode 100644
index 000000000..b16f13509
--- /dev/null
+++ b/kcontrol/hwmanager/hwdevicetray_main.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net>
+ * 
+ * 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/.
+ */
+
+#include <stdlib.h>
+#include <kdebug.h>
+
+#include <tdelocale.h>
+#include <tdecmdlineargs.h>
+#include <tdeaboutdata.h>
+#include <tdeglobal.h>
+
+#include "hwdevicetray_app.h"
+
+static const char hwdevicetrayVersion[] = "0.1";
+static const TDECmdLineOptions options[] =
+{
+	{ "login", I18N_NOOP("Application is being auto-started at TDE session start"), 0L },
+	TDECmdLineLastOption
+};
+
+int main(int argc, char **argv)
+{
+	TDEAboutData aboutData("hwdevicetray", I18N_NOOP("Hardware Device Monitor"), hwdevicetrayVersion, I18N_NOOP("Hardware Device Monitor Tray Application"), TDEAboutData::License_GPL_V3, "(c) 2015 Timothy Pearson", 0L, "");
+	aboutData.addAuthor("Timothy Pearson",I18N_NOOP("Initial developer and maintainer"), "kb9vqf@pearsoncomputing.net");
+	aboutData.setProductName("hwdevices/hwdevicetray");
+	TDEGlobal::locale()->setMainCatalogue("hwdevicetray");
+
+	TDECmdLineArgs::init(argc,argv,&aboutData);
+	TDECmdLineArgs::addCmdLineOptions(options);
+	TDEApplication::addCmdLineOptions();
+
+	HwDeviceApp app;
+
+	return app.exec();
+}
diff --git a/kdesktop/lock/main.cc b/kdesktop/lock/main.cc
index 6937cbe6a..871c87a69 100644
--- a/kdesktop/lock/main.cc
+++ b/kdesktop/lock/main.cc
@@ -247,6 +247,12 @@ int main( int argc, char **argv )
 	MyApp* app = NULL;
 
 	while (1 == 1) {
+		sigset_t new_mask;
+		sigset_t orig_mask;
+
+		// Block reception of all signals in this thread
+		sigprocmask(SIG_BLOCK, &new_mask, NULL);
+
 		signalled_forcelock = FALSE;
 		signalled_dontlock = FALSE;
 		signalled_securedialog = FALSE;
@@ -372,12 +378,6 @@ int main( int argc, char **argv )
 		KSimpleConfig* tdmconfig;
 		OPEN_TDMCONFIG_AND_SET_GROUP
 
-		sigset_t new_mask;
-		sigset_t orig_mask;
-
-		// Block reception of all signals in this thread
-		sigprocmask(SIG_BLOCK, &new_mask, NULL);
-
 		// Create new LockProcess, which also spawns threads inheriting the blocked signal mask
 		trinity_desktop_lock_process = new LockProcess;
 
diff --git a/tdeioslave/media/libmediacommon/mediamanagersettings.kcfg b/tdeioslave/media/libmediacommon/mediamanagersettings.kcfg
index 2994680cd..32725c1bb 100644
--- a/tdeioslave/media/libmediacommon/mediamanagersettings.kcfg
+++ b/tdeioslave/media/libmediacommon/mediamanagersettings.kcfg
@@ -24,5 +24,10 @@
       <whatsthis>Allows TDE to autostart application after a medium mount if it contains an Autostart or an Autoopen file.</whatsthis>
       <default>true</default>
     </entry>
+    <entry name="NotificationPopupsEnabled" type="Bool">
+      <label>Enable notification popups</label>
+      <whatsthis>Deselect this if you do not want action request popups to be generated when devices are plugged in.</whatsthis>
+      <default>true</default>
+    </entry>
   </group>
 </kcfg>
diff --git a/tdeioslave/media/mediamanager/tdehardwarebackend.cpp b/tdeioslave/media/mediamanager/tdehardwarebackend.cpp
index a7cbb2260..5846e00af 100644
--- a/tdeioslave/media/mediamanager/tdehardwarebackend.cpp
+++ b/tdeioslave/media/mediamanager/tdehardwarebackend.cpp
@@ -146,6 +146,14 @@ void TDEBackend::AddDevice(TDEStorageDevice * sdevice, bool allowNotification)
 		allowNotification = false;
 	}
 
+	// Check if user wants the full popup to be suppressed
+	bool allowDialogNotification = allowNotification;
+	TDEConfig config("mediamanagerrc");
+	config.setGroup("Global");
+	if (!config.readBoolEntry("NotificationPopupsEnabled", true)) {
+		allowDialogNotification = false;
+	}
+
 	// Add volume block devices
 	if (sdevice->isDiskOfType(TDEDiskDeviceType::HDD)) {
 		/* We only list volumes that...
@@ -190,7 +198,7 @@ void TDEBackend::AddDevice(TDEStorageDevice * sdevice, bool allowNotification)
 			}
 
 			// Insert medium into list
-			m_mediaList.addMedium(medium, allowNotification);
+			m_mediaList.addMedium(medium, allowDialogNotification);
 
 			kdDebug(1219) << "TDEBackend::AddDevice inserted hard medium for " << sdevice->uniqueID() << endl;
 
@@ -233,7 +241,7 @@ void TDEBackend::AddDevice(TDEStorageDevice * sdevice, bool allowNotification)
 		setVolumeProperties(medium);
 
 		// Insert medium into list
-		m_mediaList.addMedium(medium, allowNotification);
+		m_mediaList.addMedium(medium, allowDialogNotification);
 
 		kdDebug(1219) << "TDEBackend::AddDevice inserted optical medium for " << sdevice->uniqueID() << endl;
 
@@ -248,6 +256,7 @@ void TDEBackend::AddDevice(TDEStorageDevice * sdevice, bool allowNotification)
 		) {
 		if ((sdevice->checkDiskStatus(TDEDiskDeviceStatus::Removable)) && (!(sdevice->checkDiskStatus(TDEDiskDeviceStatus::Inserted)))) {
 			allowNotification = false;
+			allowDialogNotification = false;
 		}
 
 		/* We only list volumes that...
@@ -278,7 +287,7 @@ void TDEBackend::AddDevice(TDEStorageDevice * sdevice, bool allowNotification)
 				}
 			}
 
-			m_mediaList.addMedium(medium, allowNotification);
+			m_mediaList.addMedium(medium, allowDialogNotification);
 
 			kdDebug(1219) << "TDEBackend::AddDevice inserted floppy medium for " << sdevice->uniqueID() << endl;
 
@@ -294,7 +303,7 @@ void TDEBackend::AddDevice(TDEStorageDevice * sdevice, bool allowNotification)
 			// Create medium
 			Medium* medium = new Medium(sdevice->uniqueID(), driveUDIFromDeviceUID(sdevice->uniqueID()), "");
 			setCameraProperties(medium);
-			m_mediaList.addMedium(medium, allowNotification);
+			m_mediaList.addMedium(medium, allowDialogNotification);
 
 			kdDebug(1219) << "TDEBackend::AddDevice inserted camera medium for " << sdevice->uniqueID() << endl;
 
diff --git a/tdeioslave/media/tdecmodule/managermoduleview.ui b/tdeioslave/media/tdecmodule/managermoduleview.ui
index 982da7d80..708d38c50 100644
--- a/tdeioslave/media/tdecmodule/managermoduleview.ui
+++ b/tdeioslave/media/tdecmodule/managermoduleview.ui
@@ -52,6 +52,17 @@
                 <string>Select this if you want to enable application autostart after mounting a device.</string>
             </property>
         </widget>
+        <widget class="TQCheckBox">
+            <property name="name">
+                <cstring>kcfg_NotificationPopupsEnabled</cstring>
+            </property>
+            <property name="text">
+                <string>Enable notification popups</string>
+            </property>
+            <property name="whatsThis" stdset="0">
+                <string>Deselect this if you do not want action request popups to be generated when devices are plugged in.</string>
+            </property>
+        </widget>
         <widget class="TQGroupBox">
             <property name="name">
                 <cstring>groupbox_mount</cstring>
@@ -330,6 +341,7 @@ Display the short name as is; store a long name when the short name is not all u
     <tabstop>kcfg_HalBackendEnabled</tabstop>
     <tabstop>kcfg_CdPollingEnabled</tabstop>
     <tabstop>kcfg_AutostartEnabled</tabstop>
+    <tabstop>kcfg_NotificationPopupsEnabled</tabstop>
     <tabstop>option_automount</tabstop>
     <tabstop>option_ro</tabstop>
     <tabstop>option_quiet</tabstop>
-- 
cgit v1.2.3

