diff options
Diffstat (limited to 'kcontrol/hwmanager')
20 files changed, 1864 insertions, 44 deletions
diff --git a/kcontrol/hwmanager/CMakeLists.txt b/kcontrol/hwmanager/CMakeLists.txt index 584eba7bc..dfe327740 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 @@ -25,6 +25,12 @@ link_directories( ##### other data ################################ install( FILES hwmanager.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} ) +install( FILES hwdevicetray.desktop + DESTINATION ${XDG_APPS_INSTALL_DIR} + RENAME tdehwdevicetray.desktop ) +install( FILES hwdevicetray-autostart.desktop + DESTINATION ${AUTOSTART_INSTALL_DIR} + RENAME tdehwdevicetray-autostart.desktop ) ##### kcm_iccconfig (module) #################### @@ -33,7 +39,18 @@ set_source_files_properties( hwmanager.cpp PROPERTIES COMPILE_FLAGS -DKDE_CONFDI tde_add_kpart( kcm_hwmanager AUTOMOC SOURCES - hwmanager.cpp deviceiconview.cpp devicepropsdlg.cpp devicepropsdlgbase.ui hwmanagerbase.ui hwmanager.skel + hwmanager.cpp deviceiconview.cpp devicepropsdlg.cpp devicepropsdlgbase.ui hwmanagerbase.ui + cryptpassworddlg.cpp cryptpassworddlgbase.ui hwmanager.skel 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/cryptpassworddlg.cpp b/kcontrol/hwmanager/cryptpassworddlg.cpp new file mode 100644 index 000000000..1d66d89c1 --- /dev/null +++ b/kcontrol/hwmanager/cryptpassworddlg.cpp @@ -0,0 +1,140 @@ +/* This file is part of TDE + Copyright (C) 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#include <config.h> + +#include <tqradiobutton.h> +#include <tqpushbutton.h> +#include <tqvalidator.h> +#include <tqlineedit.h> +#include <tqiconset.h> +#include <tqlabel.h> +#include <tqtabwidget.h> +#include <tqgroupbox.h> +#include <tqlayout.h> +#include <tqslider.h> +#include <tqpainter.h> +#include <tqstyle.h> +#include <tqfile.h> +#include <tqinternal_p.h> +#undef Unsorted // Required for --enable-final (tqdir.h) +#include <tqfiledialog.h> + +#include <kpassdlg.h> +#include <kbuttonbox.h> +#include <kcombobox.h> +#include <tdelocale.h> +#include <kiconloader.h> +#include <kurlrequester.h> +#include <tdeapplication.h> +#include <klineedit.h> +#include <kpushbutton.h> +#include <kstdguiitem.h> +#include <tdemessagebox.h> +#include <ksslcertificate.h> + +#include "cryptpassworddlg.h" + +CryptPasswordDialog::CryptPasswordDialog(TQWidget *parent, TQString passwordPrompt, TQString caption, bool allow_card, KSSLCertificate* card_cert, bool* use_card) + : KDialogBase(Plain, ((caption == "")?i18n("Enter Password"):caption), Ok|Cancel, Ok, parent, 0L, true, true), + m_useCard(use_card) +{ + m_base = new CryptPasswordDialogBase(plainPage()); + + TQGridLayout *mainGrid = new TQGridLayout(plainPage(), 1, 1, 0, spacingHint()); + mainGrid->setRowStretch(1, 1); + mainGrid->addWidget(m_base, 0, 0); + + m_base->passwordPrompt->setText(passwordPrompt); + m_base->passwordIcon->setPixmap(SmallIcon("password.png")); + + if (!allow_card) { + m_base->cardKeyButton->hide(); + m_base->cardKeyInfo->hide(); + } + else { + if (card_cert) { + m_base->cardKeyInfo->setText(card_cert->getSubject()); + } + } + + connect(m_base->textPasswordButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(processLockouts())); + connect(m_base->filePasswordButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(processLockouts())); + connect(m_base->cardKeyButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(processLockouts())); + connect(m_base->textPasswordEntry, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(processLockouts())); + connect(m_base->filePasswordURL, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(processLockouts())); + + m_base->textPasswordEntry->setFocus(); + + processLockouts(); +} + +CryptPasswordDialog::~CryptPasswordDialog() +{ +} + +TQByteArray CryptPasswordDialog::password() { + if (m_base->textPasswordButton->isOn() == true) { + m_password.duplicate(m_base->textPasswordEntry->password(), strlen(m_base->textPasswordEntry->password())); + if (m_useCard) *m_useCard = false; + } + else if (m_base->filePasswordButton->isOn() == true) { + m_password = TQFile(m_base->filePasswordURL->url()).readAll(); + if (m_useCard) *m_useCard = false; + } + else { + if (m_useCard) *m_useCard = true; + } + + return m_password; +} + +void CryptPasswordDialog::processLockouts() { + if (m_base->textPasswordButton->isOn() == true) { + m_base->textPasswordEntry->setEnabled(true); + m_base->filePasswordURL->setEnabled(false); + m_base->textPasswordEntry->setFocus(); + if (strlen(m_base->textPasswordEntry->password()) > 0) { + enableButtonOK(true); + } + else { + enableButtonOK(false); + } + } + else if (m_base->filePasswordButton->isOn() == true) { + m_base->textPasswordEntry->setEnabled(false); + m_base->filePasswordURL->setEnabled(true); + m_base->filePasswordURL->setFocus(); + if (TQFile(m_base->filePasswordURL->url()).exists()) { + enableButtonOK(true); + } + else { + enableButtonOK(false); + } + } + else { + m_base->textPasswordEntry->setEnabled(false); + m_base->filePasswordURL->setEnabled(false); + enableButtonOK(true); + } +} + +void CryptPasswordDialog::virtual_hook( int id, void* data ) +{ KDialogBase::virtual_hook( id, data ); } + +#include "cryptpassworddlg.moc" diff --git a/kcontrol/hwmanager/cryptpassworddlg.h b/kcontrol/hwmanager/cryptpassworddlg.h new file mode 100644 index 000000000..d595c4a73 --- /dev/null +++ b/kcontrol/hwmanager/cryptpassworddlg.h @@ -0,0 +1,64 @@ +/* This file is part of TDE + Copyright (C) 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#ifndef __cryptpassworddlg_h__ +#define __cryptpassworddlg_h__ + +#include <kdialogbase.h> + +#include "cryptpassworddlgbase.h" + +class KSSLCertificate; + +/** + * + * Dialog to enter LUKS passwords or password files + * + * @version 0.1 + * @author Timothy Pearson <kb9vqf@pearsoncomputing.net> + */ + +class TDEUI_EXPORT CryptPasswordDialog : public KDialogBase +{ + Q_OBJECT +public: + /** + * Create a dialog that allows a user to enter LUKS passwords or password files + * @param parent Parent widget + */ + CryptPasswordDialog(TQWidget *parent, TQString passwordPrompt, TQString caption=TQString::null, bool allow_card=false, KSSLCertificate* card_cert=NULL, bool* use_card=NULL); + virtual ~CryptPasswordDialog(); + + TQByteArray password(); + +protected: + virtual void virtual_hook( int id, void* data ); + +private slots: + void processLockouts(); + +private: + CryptPasswordDialogBase* m_base; + TQByteArray m_password; + bool* m_useCard; + + class CryptPasswordDialogPrivate; + CryptPasswordDialogPrivate* d; +}; + +#endif diff --git a/kcontrol/hwmanager/cryptpassworddlgbase.ui b/kcontrol/hwmanager/cryptpassworddlgbase.ui new file mode 100644 index 000000000..549a591b0 --- /dev/null +++ b/kcontrol/hwmanager/cryptpassworddlgbase.ui @@ -0,0 +1,148 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> + <class>CryptPasswordDialogBase</class> + <widget class="TQWidget"> + <property name="name"> + <cstring>CryptPasswordDialogBase</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0" colspan="1"> + <property name="name"> + <cstring>passwordIcon</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + <widget class="TQLabel" row="0" column="1" colspan="1"> + <property name="name"> + <cstring>passwordPrompt</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="TQGroupBox" row="1" column="0" colspan="2"> + <property name="name"> + <cstring>passwordProps</cstring> + </property> + <property name="title"> + <string>Password Source</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQButtonGroup" row="0" column="0" colspan="1"> + <property name="name"> + <cstring>enabledBox</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Plain</enum> + </property> + <property name="title"> + <string></string> + </property> + <property name="exclusive"> + <bool>true</bool> + </property> + <property name="radioButtonExclusive"> + <bool>true</bool> + </property> + <property name="margin"> + <number>0</number> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="TQRadioButton" row="0" column="0" colspan="1"> + <property name="name"> + <cstring>textPasswordButton</cstring> + </property> + <property name="text"> + <string>Text:</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="KPasswordEdit" row="0" column="1" colspan="1"> + <property name="name"> + <cstring>textPasswordEntry</cstring> + </property> + </widget> + <widget class="TQRadioButton" row="1" column="0" colspan="1"> + <property name="name"> + <cstring>filePasswordButton</cstring> + </property> + <property name="text"> + <string>File:</string> + </property> + </widget> + <widget class="KURLRequester" row="1" column="1" colspan="1"> + <property name="name"> + <cstring>filePasswordURL</cstring> + </property> + <property name="filter"> + <cstring>*</cstring> + </property> + <property name="mode"> + <number>17</number> + </property> + </widget> + <widget class="TQRadioButton" row="2" column="0" colspan="1"> + <property name="name"> + <cstring>cardKeyButton</cstring> + </property> + <property name="text"> + <string>Cryptographic Card</string> + </property> + </widget> + <widget class="TQLabel" row="2" column="1" colspan="1"> + <property name="name"> + <cstring>cardKeyInfo</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + </grid> + </widget> + </grid> + </widget> + </grid> + </widget> + <includes> + <include location="local" impldecl="in implementation">CryptPasswordDialogBase.ui.h</include> + </includes> + <Q_SLOTS> + <slot>enableSupport_toggled(bool)</slot> + </Q_SLOTS> + <includes> + <include location="local" impldecl="in implementation">kdialog.h</include> + </includes> + <layoutdefaults spacing="3" margin="6"/> + <layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +</UI> diff --git a/kcontrol/hwmanager/devicepropsdlg.cpp b/kcontrol/hwmanager/devicepropsdlg.cpp index 12de8cea9..885dc7a7a 100644 --- a/kcontrol/hwmanager/devicepropsdlg.cpp +++ b/kcontrol/hwmanager/devicepropsdlg.cpp @@ -32,13 +32,19 @@ #undef Unsorted // Required for --enable-final (tqdir.h) #include <tqfiledialog.h> +#include <kpassdlg.h> +#include <kactivelabel.h> #include <kbuttonbox.h> #include <kcombobox.h> #include <tdelocale.h> #include <tdeapplication.h> #include <klineedit.h> +#include <kpushbutton.h> #include <kstdguiitem.h> #include <tdemessagebox.h> +#include <ksslcertificate.h> + +#include "cryptpassworddlg.h" #include "devicepropsdlg.h" @@ -255,6 +261,7 @@ DevicePropertiesDialog::DevicePropertiesDialog(TDEGenericDevice* device, TQWidge // Remove all non-applicable tabs if (m_device->type() != TDEGenericDeviceType::Disk) { base->tabBarWidget->removePage(base->tabDisk); + base->tabBarWidget->removePage(base->tabDiskCrypt); } if (m_device->type() != TDEGenericDeviceType::CPU) { base->tabBarWidget->removePage(base->tabCPU); @@ -283,13 +290,29 @@ DevicePropertiesDialog::DevicePropertiesDialog(TDEGenericDevice* device, TQWidge if (m_device->type() != TDEGenericDeviceType::Event) { base->tabBarWidget->removePage(base->tabEvent); } + if (m_device->type() != TDEGenericDeviceType::CryptographicCard) { + base->tabBarWidget->removePage(base->tabCryptographicCard); + } if (m_device->type() == TDEGenericDeviceType::CPU) { connect(base->comboCPUGovernor, TQT_SIGNAL(activated(const TQString &)), this, TQT_SLOT(setCPUGovernor(const TQString &))); } if (m_device->type() == TDEGenericDeviceType::Disk) { + TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(m_device); connect(base->buttonDiskMount, TQT_SIGNAL(clicked()), this, TQT_SLOT(mountDisk())); connect(base->buttonDiskUnmount, TQT_SIGNAL(clicked()), this, TQT_SLOT(unmountDisk())); + if (sdevice->isDiskOfType(TDEDiskDeviceType::LUKS)) { + connect(base->cryptLUKSAddKey, TQT_SIGNAL(clicked()), this, TQT_SLOT(cryptLUKSAddKey())); + connect(base->cryptLUKSDelKey, TQT_SIGNAL(clicked()), this, TQT_SLOT(cryptLUKSDelKey())); + connect(base->cryptLUKSKeySlotList, TQT_SIGNAL(selectionChanged()), this, TQT_SLOT(processLockouts())); + base->cryptLUKSKeySlotList->setAllColumnsShowFocus(true); + base->cryptLUKSKeySlotList->setFullWidth(true); + cryptLUKSPopulateList(); + processLockouts(); + } + else { + base->tabBarWidget->removePage(base->tabDiskCrypt); + } } if ((m_device->type() == TDEGenericDeviceType::OtherSensor) || (m_device->type() == TDEGenericDeviceType::ThermalSensor)) { @@ -340,17 +363,21 @@ TQString assembleSwitchList(TDESwitchType::TDESwitchType switches) { return (TDEEventDevice::friendlySwitchList(switches).join("<br>")); } +static TQString formatDisplayString(TQString input) { + return TQStyleSheet::escape(input); +} + void DevicePropertiesDialog::populateDeviceInformation() { if (m_device) { base->labelDeviceType->setText(m_device->friendlyDeviceType()); base->iconDeviceType->setPixmap(m_device->icon(TDEIcon::SizeSmall)); - base->labelDeviceName->setText(m_device->friendlyName()); - base->labelDeviceNode->setText((m_device->deviceNode().isNull())?i18n("<none>"):m_device->deviceNode()); - base->labelSystemPath->setText(m_device->systemPath()); - base->labelSubsytemType->setText(m_device->subsystem()); - base->labelDeviceDriver->setText((m_device->deviceDriver().isNull())?i18n("<none>"):m_device->deviceDriver()); - base->labelDeviceClass->setText((m_device->PCIClass().isNull())?i18n("<n/a>"):m_device->PCIClass()); - base->labelModalias->setText((m_device->moduleAlias().isNull())?i18n("<none>"):m_device->moduleAlias()); + base->labelDeviceName->setText(formatDisplayString(m_device->friendlyName())); + base->labelDeviceNode->setText(formatDisplayString((m_device->deviceNode().isNull())?i18n("<none>"):m_device->deviceNode())); + base->labelSystemPath->setText(formatDisplayString(m_device->systemPath())); + base->labelSubsytemType->setText(formatDisplayString(m_device->subsystem())); + base->labelDeviceDriver->setText(formatDisplayString((m_device->deviceDriver().isNull())?i18n("<none>"):m_device->deviceDriver())); + base->labelDeviceClass->setText(formatDisplayString((m_device->PCIClass().isNull())?i18n("<n/a>"):m_device->PCIClass())); + base->labelModalias->setText(formatDisplayString((m_device->moduleAlias().isNull())?i18n("<none>"):m_device->moduleAlias())); // These might be redundant #if 0 @@ -362,10 +389,10 @@ void DevicePropertiesDialog::populateDeviceInformation() { base->labelVendorModel->hide(); base->stocklabelVendorModel->hide(); #endif - base->labelSerialNumber->setText((m_device->serialNumber().isNull())?i18n("<unknown>"):m_device->serialNumber()); + base->labelSerialNumber->setText(formatDisplayString((m_device->serialNumber().isNull())?i18n("<unknown>"):m_device->serialNumber())); if (m_device->subsystem() == "pci") { - base->labelBusID->setText(m_device->busID()); + base->labelBusID->setText(formatDisplayString(m_device->busID())); base->labelBusID->show(); base->stocklabelBusID->show(); } @@ -379,15 +406,15 @@ void DevicePropertiesDialog::populateDeviceInformation() { TQString mountPoint = sdevice->mountPath(); if (mountPoint == "") mountPoint = i18n("<none>"); - base->labelDiskMountpoint->setText(mountPoint); + base->labelDiskMountpoint->setText(formatDisplayString(mountPoint)); TQString fsName = sdevice->fileSystemName(); if (fsName == "") fsName = i18n("<unknown>"); - base->labelDiskFileSystemType->setText(fsName); + base->labelDiskFileSystemType->setText(formatDisplayString(fsName)); TQString volUUID = sdevice->diskUUID(); if (volUUID == "") volUUID = i18n("<none>"); - base->labelDiskUUID->setText(volUUID); + base->labelDiskUUID->setText(formatDisplayString(volUUID)); // Show status TQString status_text = "<qt>"; @@ -663,19 +690,22 @@ void DevicePropertiesDialog::populateDeviceInformation() { if ((*it) == TDESystemPowerState::Active) { powerStatesString += i18n("Active<br>"); } - if ((*it) == TDESystemPowerState::Standby) { + else if ((*it) == TDESystemPowerState::Standby) { powerStatesString += i18n("Standby<br>"); } - if ((*it) == TDESystemPowerState::Freeze) { + else if ((*it) == TDESystemPowerState::Freeze) { powerStatesString += i18n("Freeze<br>"); } - if ((*it) == TDESystemPowerState::Suspend) { + else if ((*it) == TDESystemPowerState::Suspend) { powerStatesString += i18n("Suspend<br>"); } - if ((*it) == TDESystemPowerState::Hibernate) { + else if ((*it) == TDESystemPowerState::Hibernate) { powerStatesString += i18n("Hibernate<br>"); } - if ((*it) == TDESystemPowerState::PowerOff) { + else if ((*it) == TDESystemPowerState::HybridSuspend) { + powerStatesString += i18n("Hybrid Suspend<br>"); + } + else if ((*it) == TDESystemPowerState::PowerOff) { powerStatesString += i18n("Power Off<br>"); } } @@ -697,19 +727,22 @@ void DevicePropertiesDialog::populateDeviceInformation() { if ((*it) == TDESystemHibernationMethod::Unsupported) { label = i18n("<none>"); } - if ((*it) == TDESystemHibernationMethod::Platform) { + else if ((*it) == TDESystemHibernationMethod::Platform) { label = i18n("Platform"); } - if ((*it) == TDESystemHibernationMethod::Shutdown) { + else if ((*it) == TDESystemHibernationMethod::Suspend) { + label = i18n("Suspend"); + } + else if ((*it) == TDESystemHibernationMethod::Shutdown) { label = i18n("Shutdown"); } - if ((*it) == TDESystemHibernationMethod::Reboot) { + else if ((*it) == TDESystemHibernationMethod::Reboot) { label = i18n("Reboot"); } - if ((*it) == TDESystemHibernationMethod::TestProc) { + else if ((*it) == TDESystemHibernationMethod::TestProc) { label = i18n("Test Procedure"); } - if ((*it) == TDESystemHibernationMethod::Test) { + else if ((*it) == TDESystemHibernationMethod::Test) { label = i18n("Test"); } base->comboSystemHibernationMethod->insertItem(label, i); @@ -723,6 +756,7 @@ void DevicePropertiesDialog::populateDeviceInformation() { base->labelSystemUserCanFreeze->setText((rdevice->canFreeze())?i18n("Yes"):i18n("No")); base->labelSystemUserCanSuspend->setText((rdevice->canSuspend())?i18n("Yes"):i18n("No")); base->labelSystemUserCanHibernate->setText((rdevice->canHibernate())?i18n("Yes"):i18n("No")); + base->labelSystemUserCanHybridSuspend->setText((rdevice->canHybridSuspend())?i18n("Yes"):i18n("No")); base->labelSystemUserCanPowerOff->setText((rdevice->canPowerOff())?i18n("Yes"):i18n("No")); base->labelSystemHibernationSpace->setText((rdevice->diskSpaceNeededForHibernation()<0)?i18n("<unknown>"):TDEHardwareDevices::bytesToFriendlySizeString(rdevice->diskSpaceNeededForHibernation())); @@ -753,6 +787,73 @@ void DevicePropertiesDialog::populateDeviceInformation() { } base->labelEventSwitchActive->setText(activeSwitches); } + + if (m_device->type() == TDEGenericDeviceType::CryptographicCard) { + TDECryptographicCardDevice* cdevice = static_cast<TDECryptographicCardDevice*>(m_device); + + connect(cdevice, TQT_SIGNAL(cardInserted(TDECryptographicCardDevice*)), this, TQT_SLOT(cryptographicCardInserted())); + connect(cdevice, TQT_SIGNAL(cardRemoved(TDECryptographicCardDevice*)), this, TQT_SLOT(cryptographicCardRemoved())); + + updateCryptographicCardStatusDisplay(); + } + } +} + +void DevicePropertiesDialog::cryptographicCardInserted() { + updateCryptographicCardStatusDisplay(); +} + +void DevicePropertiesDialog::cryptographicCardRemoved() { + updateCryptographicCardStatusDisplay(); +} + +void DevicePropertiesDialog::updateCryptographicCardStatusDisplay() { + TDECryptographicCardDevice* cdevice = static_cast<TDECryptographicCardDevice*>(m_device); + + int status = cdevice->cardPresent(); + if ((status < 0) ||(status > 1)) { + base->labelCardStatus->setText(i18n("Unknown")); + base->labelCardCertificates->setText(""); + base->groupCardCerts->hide(); + } + else if (status == 0) { + base->labelCardStatus->setText(i18n("Empty")); + base->labelCardCertificates->setText(""); + base->groupCardCerts->hide(); + } + else if (status == 1) { + base->labelCardStatus->setText(i18n("Inserted") + TQString("<br>") + i18n("ATR: %1").arg(cdevice->cardATR())); + + X509CertificatePtrList certList = cdevice->cardX509Certificates(); + + if (certList.count() > 0) { + // Assemble list of certificates on card + unsigned int certificate_number = 1; + TQString certInfo = "<qt>"; + X509CertificatePtrList::iterator it; + for (it = certList.begin(); it != certList.end(); ++it) { + KSSLCertificate* tdeCert = KSSLCertificate::fromX509(*it); + KSSLCertificate::KSSLValidation validationStatus = tdeCert->validate(); + certInfo += i18n("Certificate #%1").arg(certificate_number) + ":<br>"; + certInfo += i18n("Subject") + ": " + tdeCert->getSubject() + "<br>"; + certInfo += i18n("Issuer") + ": " + tdeCert->getIssuer() + "<br>"; + certInfo += i18n("Status") + ": " + KSSLCertificate::verifyText(validationStatus) + "<br>"; + certInfo += i18n("Valid From") + ": " + tdeCert->getNotBefore() + "<br>"; + certInfo += i18n("Valid Until") + ": " + tdeCert->getNotAfter() + "<br>"; + certInfo += i18n("Serial Number") + ": " + tdeCert->getSerialNumber() + "<br>"; + certInfo += i18n("MD5 Digest") + ": " + tdeCert->getMD5DigestText() + "<br>"; + certInfo += "<p>"; + delete tdeCert; + certificate_number++; + } + certInfo += "</qt>"; + base->labelCardCertificates->setText(certInfo); + base->groupCardCerts->show(); + } + else { + base->labelCardCertificates->setText(""); + base->groupCardCerts->hide(); + } } } @@ -825,6 +926,293 @@ void DevicePropertiesDialog::unmountDisk() { populateDeviceInformation(); } +void DevicePropertiesDialog::cryptLUKSAddKey() { + int retcode; + + if (m_device->type() == TDEGenericDeviceType::Disk) { + TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(m_device); + + TQListViewItem* lvi = base->cryptLUKSKeySlotList->selectedItem(); + if (lvi) { + TDECryptographicCardDevice* cdevice = NULL; + unsigned int key_slot = lvi->text(0).toUInt(); + bool allow_card = false; + bool use_card = false; + bool luks_card_key_modified = false; + KSSLCertificate* card_cert = NULL; + X509* card_cert_x509; + TQString disk_uuid = sdevice->diskUUID(); + TDEGenericDevice *hwdevice; + TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); + TDEGenericHardwareList cardReaderList = hwdevices->listByDeviceClass(TDEGenericDeviceType::CryptographicCard); + for (hwdevice = cardReaderList.first(); hwdevice; hwdevice = cardReaderList.next()) { + cdevice = static_cast<TDECryptographicCardDevice*>(hwdevice); + X509CertificatePtrList certList = cdevice->cardX509Certificates(); + if (certList.count() > 0) { + allow_card = true; + card_cert_x509 = certList[0]; + card_cert = KSSLCertificate::fromX509(certList[0]); + } + } + TQByteArray new_password; + CryptPasswordDialog* passDlg = new CryptPasswordDialog(this, i18n("Enter the new LUKS password for key slot %1").arg(key_slot), TQString::null, allow_card, card_cert, &use_card); + if (passDlg->exec() == TQDialog::Accepted) { + new_password = passDlg->password(); + if (allow_card && use_card) { + // Create new private key for disk device + if (!TQDir("/etc/trinity/luks").exists()) { + TQDir directory; + if (!directory.mkdir("/etc/trinity/luks", true)) { + KMessageBox::error(this, i18n("<qt><b>Key creation failed</b><br>Please check that you have write access to /etc/trinity and try again</qt>"), i18n("Key creation failure")); + delete card_cert; + return; + } + } + if (!TQDir("/etc/trinity/luks/card").exists()) { + TQDir directory; + if (!directory.mkdir("/etc/trinity/luks/card", true)) { + KMessageBox::error(this, i18n("<qt><b>Key creation failed</b><br>Please check that you have write access to /etc/trinity/luks and try again</qt>"), i18n("Key creation failure")); + delete card_cert; + return; + } + } + TQString cryptoFileName = TQString("/etc/trinity/luks/card/%1_slot%2").arg(disk_uuid).arg(key_slot); + TQFile file(cryptoFileName); + if (file.exists()) { + if (KMessageBox::warningYesNo(this, i18n("<qt><b>You are about to overwrite an existing card key for LUKS key slot %1</b><br>This action cannot be undone<p>Are you sure you want to proceed?</qt>").arg(key_slot), i18n("Confirmation Required")) != KMessageBox::Yes) { + delete card_cert; + return; + } + } + if (file.open(IO_WriteOnly)) { + TQByteArray randomKey; + TQByteArray encryptedRandomKey; + + // Create a new secret key using the public key from the card certificate + if (TDECryptographicCardDevice::createNewSecretRSAKeyFromCertificate(randomKey, encryptedRandomKey, card_cert_x509) < 0) { + KMessageBox::error(this, i18n("<qt><b>Key creation failed</b><br>Unable to create new secret key using the provided X509 certificate</qt>"), i18n("Key creation failure")); + delete card_cert; + return; + } + + // Write the encrypted key file to disk + file.writeBlock(encryptedRandomKey, encryptedRandomKey.size()); + file.close(); + + // Use the secret key as the LUKS passcode + new_password = randomKey; + luks_card_key_modified = true; + } + else { + KMessageBox::error(this, i18n("<qt><b>Key creation failed</b><br>Please check that you have write access to /etc/trinity/luks/card and try again</qt>"), i18n("Key creation failure")); + delete card_cert; + return; + } + } + delete passDlg; + if (!sdevice->cryptOperationsUnlockPasswordSet()) { + TQCString password; + passDlg = new CryptPasswordDialog(this, i18n("Enter the LUKS device unlock password"), TQString::null, allow_card, card_cert, &use_card); + if (passDlg->exec() == TQDialog::Accepted) { + TQByteArray unlockPassword = passDlg->password(); + if (use_card) { + // List all matching keys in directory and try each in turn... + TQDir luksKeyDir("/etc/trinity/luks/card/"); + luksKeyDir.setFilter(TQDir::Files); + luksKeyDir.setSorting(TQDir::Unsorted); + + TQValueList<TQByteArray> luksCryptedList; + TQValueList<TQByteArray> luksDecryptedList; + TQValueList<int> luksSlotNumberList; + + const TQFileInfoList *luksKeyDirList = luksKeyDir.entryInfoList(); + TQFileInfoListIterator it(*luksKeyDirList); + TQFileInfo *luksKeyFileInfo; + TQString errstr; + while ((luksKeyFileInfo = it.current()) != 0) { + if (luksKeyFileInfo->fileName().startsWith(disk_uuid) && luksKeyFileInfo->fileName().contains("_slot")) { + // Found candidate, try decryption + TQFile luksKeyFile(luksKeyFileInfo->absFilePath()); + if (luksKeyFile.open(IO_ReadOnly)) { + TQByteArray keycrypted = luksKeyFile.readAll(); + luksCryptedList.append(keycrypted); + + // Parse the file name and find the matching key slot + int current_card_keyslot = -1; + TQString fileName = luksKeyFile.name(); + int pos = fileName.find("_slot"); + if (pos >= 0) { + fileName.remove(0, pos + strlen("_slot")); + current_card_keyslot = fileName.toInt(); + luksSlotNumberList.append(current_card_keyslot); + } + } + } + ++it; + } + + // Decrypt LUKS keys + TQValueList<int> retCodeList; + retcode = cdevice->decryptDataEncryptedWithCertPublicKey(luksCryptedList, luksDecryptedList, retCodeList, &errstr); + TQValueList<TQByteArray>::iterator it2; + TQValueList<int>::iterator it3; + TQValueList<int>::iterator it4; + for (it2 = luksDecryptedList.begin(), it3 = retCodeList.begin(), it4 = luksSlotNumberList.begin(); it2 != luksDecryptedList.end(); ++it2, ++it3, ++it4) { + TQByteArray luksKeyData = *it2; + retcode = *it3; + int current_card_keyslot = *it4; + if (retcode == -3) { + // User cancelled + break; + } + if (retcode < 0) { + // ERROR + } + else { + // Key decryption successful, try to open LUKS device... + sdevice->cryptSetOperationsUnlockPassword(luksKeyData); + if (sdevice->cryptCheckKey(current_card_keyslot) == TDELUKSResult::Success) { + break; + } + else { + sdevice->cryptClearOperationsUnlockPassword(); + } + } + } + if (!sdevice->cryptOperationsUnlockPasswordSet()) { + KMessageBox::error(this, i18n("<qt><b>Key write failed</b><br>Please check the LUKS password and try again</qt>"), i18n("Key write failure")); + } + } + else { + sdevice->cryptSetOperationsUnlockPassword(unlockPassword); + } + } + delete passDlg; + } + if (sdevice->cryptOperationsUnlockPasswordSet()) { + if ((lvi->text(1) == sdevice->cryptKeySlotFriendlyName(TDELUKSKeySlotStatus::Inactive)) || (KMessageBox::warningYesNo(this, i18n("<qt><b>You are about to overwrite the key in key slot %1</b><br>This action cannot be undone<p>Are you sure you want to proceed?</qt>").arg(key_slot), i18n("Confirmation Required")) == KMessageBox::Yes)) { + if (sdevice->cryptAddKey(key_slot, new_password) != TDELUKSResult::Success) { + sdevice->cryptClearOperationsUnlockPassword(); + KMessageBox::error(this, i18n("<qt><b>Key write failed</b><br>Please check the LUKS password and try again</qt>"), i18n("Key write failure")); + } + else { + if (luks_card_key_modified) { + if (KMessageBox::warningYesNo(this, i18n("<qt><b>You have created a new card-dependent key</b><br>Card-dependent keys work in conjunction with an encrypted key file stored on the host system.<br>When a card is used to boot, card-dependent keys must be updated in the initramfs image to become usable.<p>Would you like to update the initramfs image now?</qt>"), i18n("Update Required")) == KMessageBox::Yes) { + // Update the initramfs + if (system("update-initramfs -u -k all") != 0) { + KMessageBox::error(this, i18n("<qt><b>Initramfs update failed</b><br>Card-dependent keys may not be available for use until the root storage device is available / unlocked</qt>"), i18n("Initramfs update failure")); + } + } + } + } + } + } + } + else { + delete passDlg; + } + delete card_cert; + } + } + + cryptLUKSPopulateList(); +} + +void DevicePropertiesDialog::cryptLUKSDelKey() { + if (m_device->type() == TDEGenericDeviceType::Disk) { + TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(m_device); + + TQListViewItem* lvi = base->cryptLUKSKeySlotList->selectedItem(); + if (lvi) { + unsigned int key_slot = lvi->text(0).toUInt(); + if (KMessageBox::warningYesNo(this, i18n("<qt><b>You are about to purge the key in key slot %1</b><br>This action cannot be undone<p>Are you sure you want to proceed?</qt>").arg(lvi->text(0)), i18n("Confirmation Required")) == KMessageBox::Yes) { + if (sdevice->cryptKeySlotStatus()[key_slot] & TDELUKSKeySlotStatus::Last) { + if (KMessageBox::warningYesNo(this, i18n("<qt><b>You are about to purge the last active key from the device!</b><p>This action will render the contents of the encrypted device permanently inaccessable and cannot be undone<p>Are you sure you want to proceed?</qt>"), i18n("Confirmation Required")) != KMessageBox::Yes) { + cryptLUKSPopulateList(); + return; + } + } + if (sdevice->cryptDelKey(key_slot) != TDELUKSResult::Success) { + sdevice->cryptClearOperationsUnlockPassword(); + KMessageBox::error(this, i18n("<qt><b>Key purge failed</b><br>The key in key slot %1 is still active</qt>").arg(lvi->text(0)), i18n("Key purge failure")); + } + else { + // See if there was a cryptographic card key associated with this device and slot + TQString disk_uuid = sdevice->diskUUID(); + TQDir luksKeyDir("/etc/trinity/luks/card/"); + luksKeyDir.setFilter(TQDir::Files); + luksKeyDir.setSorting(TQDir::Unsorted); + + const TQFileInfoList *luksKeyDirList = luksKeyDir.entryInfoList(); + TQFileInfoListIterator it(*luksKeyDirList); + TQFileInfo *luksKeyFileInfo; + TQString errstr; + while ((luksKeyFileInfo = it.current()) != 0) { + if (luksKeyFileInfo->fileName().startsWith(disk_uuid) && luksKeyFileInfo->fileName().contains("_slot")) { + // Parse the file name and find the matching key slot + int current_card_keyslot = -1; + TQString fileName = luksKeyFileInfo->absFilePath(); + TQString fileNameSlot = fileName; + int pos = fileNameSlot.find("_slot"); + if (pos >= 0) { + fileNameSlot.remove(0, pos + strlen("_slot")); + current_card_keyslot = fileNameSlot.toInt(); + if (current_card_keyslot >= 0) { + if ((unsigned int)current_card_keyslot == key_slot) { + if (!TQFile(fileName).remove()) { + KMessageBox::error(this, i18n("<qt><b>Card key purge failed</b><br>The card key for slot %1 has been fully deactivated but is still present on your system<br>This does not present a significant security risk</qt>").arg(lvi->text(0)), i18n("Key purge failure")); + } + break; + } + } + } + } + ++it; + } + } + } + } + } + + cryptLUKSPopulateList(); +} + +void DevicePropertiesDialog::cryptLUKSPopulateList() { + unsigned int i; + TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(m_device); + + base->cryptLUKSKeySlotList->clear(); + unsigned int count = sdevice->cryptKeySlotCount(); + TDELUKSKeySlotStatusList status = sdevice->cryptKeySlotStatus(); + for (i = 0; i < count; i++) { + new TQListViewItem(base->cryptLUKSKeySlotList, TQString("%1").arg(i), sdevice->cryptKeySlotFriendlyName(status[i])); + } + + processLockouts(); +} + +void DevicePropertiesDialog::processLockouts() { + if (m_device->type() == TDEGenericDeviceType::Disk) { + TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(m_device); + + TQListViewItem* lvi = base->cryptLUKSKeySlotList->selectedItem(); + if (lvi) { + if (lvi->text(1) == sdevice->cryptKeySlotFriendlyName(TDELUKSKeySlotStatus::Active)) { + base->cryptLUKSAddKey->setEnabled(true); + base->cryptLUKSDelKey->setEnabled(true); + } + else { + base->cryptLUKSAddKey->setEnabled(true); + base->cryptLUKSDelKey->setEnabled(false); + } + } + else { + base->cryptLUKSAddKey->setEnabled(false); + base->cryptLUKSDelKey->setEnabled(false); + } + } +} + void DevicePropertiesDialog::virtual_hook( int id, void* data ) { KDialogBase::virtual_hook( id, data ); } diff --git a/kcontrol/hwmanager/devicepropsdlg.h b/kcontrol/hwmanager/devicepropsdlg.h index bbff43977..e958d39ba 100644 --- a/kcontrol/hwmanager/devicepropsdlg.h +++ b/kcontrol/hwmanager/devicepropsdlg.h @@ -191,6 +191,16 @@ private slots: void mountDisk(); void unmountDisk(); + void cryptLUKSAddKey(); + void cryptLUKSDelKey(); + void cryptLUKSPopulateList(); + + void cryptographicCardInserted(); + void cryptographicCardRemoved(); + void updateCryptographicCardStatusDisplay(); + + void processLockouts(); + private: TDEGenericDevice* m_device; DevicePropertiesDialogBase* base; diff --git a/kcontrol/hwmanager/devicepropsdlgbase.ui b/kcontrol/hwmanager/devicepropsdlgbase.ui index 74afdf5f3..0ea911c71 100644 --- a/kcontrol/hwmanager/devicepropsdlgbase.ui +++ b/kcontrol/hwmanager/devicepropsdlgbase.ui @@ -80,7 +80,7 @@ <string>Device Name:</string> </property> </widget> - <widget class="TQLabel" row="1" column="1" colspan="3"> + <widget class="KActiveLabel" row="1" column="1" colspan="3"> <property name="name"> <cstring>labelDeviceName</cstring> </property> @@ -93,7 +93,7 @@ <string>Device Node:</string> </property> </widget> - <widget class="TQLabel" row="2" column="1" colspan="3"> + <widget class="KActiveLabel" row="2" column="1" colspan="3"> <property name="name"> <cstring>labelDeviceNode</cstring> </property> @@ -106,7 +106,7 @@ <string>System Path:</string> </property> </widget> - <widget class="TQLabel" row="3" column="1" colspan="3"> + <widget class="KActiveLabel" row="3" column="1" colspan="3"> <property name="name"> <cstring>labelSystemPath</cstring> </property> @@ -119,7 +119,7 @@ <string>Subsystem Type:</string> </property> </widget> - <widget class="TQLabel" row="4" column="1" colspan="3"> + <widget class="KActiveLabel" row="4" column="1" colspan="3"> <property name="name"> <cstring>labelSubsytemType</cstring> </property> @@ -132,7 +132,7 @@ <string>Device Driver:</string> </property> </widget> - <widget class="TQLabel" row="5" column="1" colspan="3"> + <widget class="KActiveLabel" row="5" column="1" colspan="3"> <property name="name"> <cstring>labelDeviceDriver</cstring> </property> @@ -145,7 +145,7 @@ <string>Device Class:</string> </property> </widget> - <widget class="TQLabel" row="6" column="1" colspan="3"> + <widget class="KActiveLabel" row="6" column="1" colspan="3"> <property name="name"> <cstring>labelDeviceClass</cstring> </property> @@ -158,7 +158,7 @@ <string>Manufacturer:</string> </property> </widget> - <widget class="TQLabel" row="7" column="1" colspan="3"> + <widget class="KActiveLabel" row="7" column="1" colspan="3"> <property name="name"> <cstring>labelVendorName</cstring> </property> @@ -171,7 +171,7 @@ <string>Model:</string> </property> </widget> - <widget class="TQLabel" row="8" column="1" colspan="3"> + <widget class="KActiveLabel" row="8" column="1" colspan="3"> <property name="name"> <cstring>labelVendorModel</cstring> </property> @@ -184,7 +184,7 @@ <string>Serial Number:</string> </property> </widget> - <widget class="TQLabel" row="9" column="1" colspan="3"> + <widget class="KActiveLabel" row="9" column="1" colspan="3"> <property name="name"> <cstring>labelSerialNumber</cstring> </property> @@ -197,7 +197,7 @@ <string>Bus ID:</string> </property> </widget> - <widget class="TQLabel" row="10" column="1" colspan="3"> + <widget class="KActiveLabel" row="10" column="1" colspan="3"> <property name="name"> <cstring>labelBusID</cstring> </property> @@ -210,7 +210,7 @@ <string>Technical Details:</string> </property> </widget> - <widget class="TQLabel" row="11" column="1" colspan="3"> + <widget class="KActiveLabel" row="11" column="1" colspan="3"> <property name="name"> <cstring>labelModalias</cstring> </property> @@ -266,7 +266,7 @@ <string>Mountpoint:</string> </property> </widget> - <widget class="TQLabel" row="0" column="1" colspan="1"> + <widget class="KActiveLabel" row="0" column="1" colspan="1"> <property name="name"> <cstring>labelDiskMountpoint</cstring> </property> @@ -279,7 +279,7 @@ <string>Filesystem Type:</string> </property> </widget> - <widget class="TQLabel" row="1" column="1" colspan="1"> + <widget class="KActiveLabel" row="1" column="1" colspan="1"> <property name="name"> <cstring>labelDiskFileSystemType</cstring> </property> @@ -292,7 +292,7 @@ <string>Volume UUID:</string> </property> </widget> - <widget class="TQLabel" row="2" column="1" colspan="1"> + <widget class="KActiveLabel" row="2" column="1" colspan="1"> <property name="name"> <cstring>labelDiskUUID</cstring> </property> @@ -308,7 +308,7 @@ <set>AlignTop|AlignLeft</set> </property> </widget> - <widget class="TQLabel" row="3" column="1" colspan="1"> + <widget class="KActiveLabel" row="3" column="1" colspan="1"> <property name="name"> <cstring>labelDiskStatus</cstring> </property> @@ -326,7 +326,7 @@ <property name="name"> <cstring>unnamed</cstring> </property> - <widget class="TQPushButton" row="0" column="0" colspan="1"> + <widget class="KPushButton" row="0" column="0" colspan="1"> <property name="name"> <cstring>buttonDiskMount</cstring> </property> @@ -334,7 +334,7 @@ <string>Mount</string> </property> </widget> - <widget class="TQPushButton" row="0" column="1" colspan="1"> + <widget class="KPushButton" row="0" column="1" colspan="1"> <property name="name"> <cstring>buttonDiskUnmount</cstring> </property> @@ -365,6 +365,95 @@ </widget> <widget class="TQWidget"> <property name="name"> + <cstring>tabDiskCrypt</cstring> + </property> + <attribute name="title"> + <string>LUKS</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQGroupBox" row="0" column="0"> + <property name="name"> + <cstring>groupLUKSProps</cstring> + </property> + <property name="title"> + <string>LUKS Information</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TDEListView" row="0" column="0" colspan="2"> + <column> + <property name="text"> + <string>Slot Number</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizeable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Status</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizeable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>cryptLUKSKeySlotList</cstring> + </property> + <property name="rootIsDecorated"> + <bool>false</bool> + </property> + </widget> + <widget class="KPushButton" row="1" column="0" colspan="1"> + <property name="name"> + <cstring>cryptLUKSAddKey</cstring> + </property> + <property name="text"> + <string>Install new password into keyslot</string> + </property> + </widget> + <widget class="KPushButton" row="1" column="1" colspan="1"> + <property name="name"> + <cstring>cryptLUKSDelKey</cstring> + </property> + <property name="text"> + <string>Delete existing password from keyslot</string> + </property> + </widget> + </grid> + </widget> + <spacer row="8" column="0"> + <property name="name" stdset="0"> + <cstring>Spacer4</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="TQWidget"> + <property name="name"> <cstring>tabCPU</cstring> </property> <attribute name="title"> @@ -1419,7 +1508,20 @@ <cstring>labelSystemUserCanHibernate</cstring> </property> </widget> - <widget class="TQLabel" row="7" column="0" colspan="1"> + <widget class="TQLabel" row="7" column="0" colspan="1"> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="text"> + <string>User Can Request Hybrid Suspend</string> + </property> + </widget> + <widget class="TQLabel" row="7" column="1" colspan="1"> + <property name="name"> + <cstring>labelSystemUserCanHybridSuspend</cstring> + </property> + </widget> + <widget class="TQLabel" row="8" column="0" colspan="1"> <property name="name"> <cstring>unnamed</cstring> </property> @@ -1427,7 +1529,7 @@ <string>User Can Request Shutdown</string> </property> </widget> - <widget class="TQLabel" row="7" column="1" colspan="1"> + <widget class="TQLabel" row="8" column="1" colspan="1"> <property name="name"> <cstring>labelSystemUserCanPowerOff</cstring> </property> @@ -1528,6 +1630,84 @@ </spacer> </grid> </widget> + <widget class="TQWidget"> + <property name="name"> + <cstring>tabCryptographicCard</cstring> + </property> + <attribute name="title"> + <string>Cryptographic Card</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQGroupBox" row="0" column="0"> + <property name="name"> + <cstring>groupInput</cstring> + </property> + <property name="title"> + <string>Card Status</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0" colspan="1"> + <property name="name"> + <cstring>labelCardStatus</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>AlignTop|AlignLeft</set> + </property> + </widget> + </grid> + </widget> + <widget class="TQGroupBox" row="1" column="0"> + <property name="name"> + <cstring>groupCardCerts</cstring> + </property> + <property name="title"> + <string>Card Certificates</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="TQLabel" row="0" column="0" colspan="1"> + <property name="name"> + <cstring>labelCardCertificates</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>AlignTop|AlignLeft</set> + </property> + </widget> + </grid> + </widget> + <spacer row="8" column="0"> + <property name="name" stdset="0"> + <cstring>Spacer4</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> </widget> </grid> </widget> diff --git a/kcontrol/hwmanager/hwdevicetray-autostart.desktop b/kcontrol/hwmanager/hwdevicetray-autostart.desktop new file mode 100644 index 000000000..57bd9b893 --- /dev/null +++ b/kcontrol/hwmanager/hwdevicetray-autostart.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Name=tdehwdevicetray +GenericName=Hardware Device Monitor +Comment=Monitor hardware devices from the system tray +Exec=tdehwdevicetray +Icon=kcmdevices +X-TDE-autostart-after=panel +X-TDE-StartupNotify=false +X-TDE-UniqueApplet=true +X-TDE-autostart-condition=tdehwdevicetrayrc:General:Autostart:true +Categories=System;Applet; diff --git a/kcontrol/hwmanager/hwdevicetray.cpp b/kcontrol/hwmanager/hwdevicetray.cpp new file mode 100644 index 000000000..b6ef8a6ad --- /dev/null +++ b/kcontrol/hwmanager/hwdevicetray.cpp @@ -0,0 +1,431 @@ +/* + * 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)))) + || (sdevice->isDiskOfType(TDEDiskDeviceType::Camera))) { + 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 (m_mountMenuIndexMap[lastMountIndex] == "") { + m_mountMenuIndexMap[lastMountIndex] = sdevice->systemPath(); + } + 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 (m_unmountMenuIndexMap[lastMountIndex] == "") { + m_unmountMenuIndexMap[lastMountIndex] = sdevice->systemPath(); + } + } + } + } + + 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) || (sdevice->systemPath() == uuid)) { + 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))); + } + 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) || (sdevice->systemPath() == 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)) { + TQString uuid = sdevice->diskUUID(); + if (uuid == "") { + uuid = sdevice->systemPath(); + } + m_hardwareNotifierContainer->displayMessage( + i18n("A disk device has been added!"), + i18n("%1 (%2)").arg(sdevice->friendlyName(), sdevice->deviceNode()), SmallIcon("drive-harddisk"), + 0, 0, "ADD: " + uuid); + } + } +#endif +} + +void HwDeviceSystemTray::deviceRemoved(TDEGenericDevice* device) { +#ifdef __TDE_HAVE_TDEHWLIB + if (device->type() == TDEGenericDeviceType::Disk) { + TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(device); + if (isMonitoredDevice(sdevice)) { + TQString uuid = sdevice->diskUUID(); + if (uuid == "") { + uuid = sdevice->systemPath(); + } + m_hardwareNotifierContainer->displayMessage( + i18n("A disk device has been removed!"), + i18n("%1 (%2)").arg(sdevice->friendlyName(), sdevice->deviceNode()), SmallIcon("drive-harddisk"), + 0, 0, "REMOVE: " + uuid); + } + } +#endif +} + +void HwDeviceSystemTray::deviceChanged(TDEGenericDevice* device) { +#ifdef __TDE_HAVE_TDEHWLIB + if (device->type() == TDEGenericDeviceType::Disk) { + TDEStorageDevice* sdevice = static_cast<TDEStorageDevice*>(device); + if (isMonitoredDevice(sdevice)) { + TQString uuid = sdevice->diskUUID(); + if (uuid == "") { + uuid = sdevice->systemPath(); + } + m_hardwareNotifierContainer->displayMessage( + i18n("A disk device has been changed!"), + i18n("%1 (%2)").arg(sdevice->friendlyName(), sdevice->deviceNode()), SmallIcon("drive-harddisk"), + 0, 0, "CHANGE: " + uuid); + } + } +#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) || (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"
\ No newline at end of file diff --git a/kcontrol/hwmanager/hwdevicetray.desktop b/kcontrol/hwmanager/hwdevicetray.desktop new file mode 100644 index 000000000..20a0297ce --- /dev/null +++ b/kcontrol/hwmanager/hwdevicetray.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Name=tdehwdevicetray +GenericName=Hardware Device Monitor +Comment=Monitor hardware devices from the system tray +Exec=tdehwdevicetray +Icon=kcmdevices +Type=Application +OnlyShowIn=TDE; +Categories=Qt;TDE;System; +X-DocPath=tdehwdevicetray/index.html 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/kcontrol/hwmanager/hwmanager.cpp b/kcontrol/hwmanager/hwmanager.cpp index a82daf1be..1cd8b04e0 100644 --- a/kcontrol/hwmanager/hwmanager.cpp +++ b/kcontrol/hwmanager/hwmanager.cpp @@ -42,11 +42,14 @@ #include <kgenericfactory.h> #include <unistd.h> +#include <kpassdlg.h> #include <ksimpleconfig.h> #include <string> #include <stdio.h> #include <tqstring.h> +#include <tdecryptographiccarddevice.h> + #include "hwmanager.h" using namespace std; @@ -144,6 +147,12 @@ void TDEHWManager::populateTreeView() TDEGenericHardwareList hwlist = hwdevices->listByDeviceClass(TDEGenericDeviceType::RootSystem); TDEGenericDevice *hwdevice; for ( hwdevice = hwlist.first(); hwdevice; hwdevice = hwlist.next() ) { + if (hwdevice->type() == TDEGenericDeviceType::CryptographicCard) { + TDECryptographicCardDevice* cdevice = static_cast<TDECryptographicCardDevice*>(hwdevice); + connect(cdevice, SIGNAL(pinRequested(TQString,TDECryptographicCardDevice*)), this, SLOT(cryptographicCardPinRequested(TQString,TDECryptographicCardDevice*))); + cdevice->enableCardMonitoring(true); + cdevice->enablePINEntryCallbacks(true); + } DeviceIconItem* item = new DeviceIconItem(base->deviceTree, hwdevice->detailedFriendlyName(), hwdevice->icon(base->deviceTree->iconSize()), hwdevice); if ((!selected_syspath.isNull()) && (hwdevice->systemPath() == selected_syspath)) { base->deviceTree->ensureItemVisible(item); @@ -160,6 +169,12 @@ void TDEHWManager::populateTreeView() TDEGenericDevice *hwdevice; TDEGenericHardwareList hwlist = hwdevices->listByDeviceClass((TDEGenericDeviceType::TDEGenericDeviceType)i); for ( hwdevice = hwlist.first(); hwdevice; hwdevice = hwlist.next() ) { + if (hwdevice->type() == TDEGenericDeviceType::CryptographicCard) { + TDECryptographicCardDevice* cdevice = static_cast<TDECryptographicCardDevice*>(hwdevice); + connect(cdevice, SIGNAL(pinRequested(TQString,TDECryptographicCardDevice*)), this, SLOT(cryptographicCardPinRequested(TQString,TDECryptographicCardDevice*))); + cdevice->enableCardMonitoring(true); + cdevice->enablePINEntryCallbacks(true); + } DeviceIconItem* item = new DeviceIconItem(rootitem, hwdevice->detailedFriendlyName(), hwdevice->icon(base->deviceTree->iconSize()), hwdevice); if ((!selected_syspath.isNull()) && (hwdevice->systemPath() == selected_syspath)) { base->deviceTree->ensureItemVisible(item); @@ -177,6 +192,12 @@ void TDEHWManager::populateTreeViewLeaf(DeviceIconItem *parent, bool show_by_con TDEGenericHardwareList hwlist = hwdevices->listAllPhysicalDevices(); TDEGenericDevice *hwdevice; for ( hwdevice = hwlist.first(); hwdevice; hwdevice = hwlist.next() ) { + if (hwdevice->type() == TDEGenericDeviceType::CryptographicCard) { + TDECryptographicCardDevice* cdevice = static_cast<TDECryptographicCardDevice*>(hwdevice); + connect(cdevice, SIGNAL(pinRequested(TQString,TDECryptographicCardDevice*)), this, SLOT(cryptographicCardPinRequested(TQString,TDECryptographicCardDevice*))); + cdevice->enableCardMonitoring(true); + cdevice->enablePINEntryCallbacks(true); + } if (hwdevice->parentDevice() == parent->device()) { DeviceIconItem* item = new DeviceIconItem(parent, hwdevice->detailedFriendlyName(), hwdevice->icon(base->deviceTree->iconSize()), hwdevice); if ((!selected_syspath.isNull()) && (hwdevice->systemPath() == selected_syspath)) { @@ -207,6 +228,17 @@ void TDEHWManager::deviceChanged(TDEGenericDevice* device) { } } +void TDEHWManager::cryptographicCardPinRequested(TQString prompt, TDECryptographicCardDevice* cdevice) { + TQCString password; + int result = KPasswordDialog::getPassword(password, prompt); + if (result == KPasswordDialog::Accepted) { + cdevice->setProvidedPin(password); + } + else { + cdevice->setProvidedPin(TQString::null); + } +} + TQString TDEHWManager::quickHelp() const { return i18n("<h1>TDE Hardware Device Manager</h1> This module allows you to configure hardware devices on your system"); diff --git a/kcontrol/hwmanager/hwmanager.desktop b/kcontrol/hwmanager/hwmanager.desktop index 161c331bd..d0ef60728 100644 --- a/kcontrol/hwmanager/hwmanager.desktop +++ b/kcontrol/hwmanager/hwmanager.desktop @@ -1,6 +1,6 @@ [Desktop Entry] Exec=tdecmshell hwmanager -Icon=background +Icon=hwinfo Type=Application X-DocPath=kcontrol/hwmanager/index.html diff --git a/kcontrol/hwmanager/hwmanager.h b/kcontrol/hwmanager/hwmanager.h index b75a494d9..abc05fa54 100644 --- a/kcontrol/hwmanager/hwmanager.h +++ b/kcontrol/hwmanager/hwmanager.h @@ -61,6 +61,7 @@ private slots: void populateTreeView(); void populateTreeViewLeaf(DeviceIconItem *parent, bool show_by_connection, TQString selected_syspath); void deviceChanged(TDEGenericDevice*); + void cryptographicCardPinRequested(TQString prompt, TDECryptographicCardDevice* cdevice); private: TDEHWManagerBase *base; |