From 317397e06353774e7e39dddbdffed0179e7d35de Mon Sep 17 00:00:00 2001 From: sniperbeamer Date: Sun, 9 Mar 2008 19:56:13 +0000 Subject: [PATCH] Added: automatically lock database after inactivity (closes #1906699) git-svn-id: https://svn.code.sf.net/p/keepassx/code/trunk@177 b624d157-de02-0410-bad0-e51aec6abb33 --- src/Application_X11.cpp | 18 +++++------ src/Application_X11.h | 4 ++- src/KpxConfig.h | 4 +++ src/dialogs/AutoTypeDlg.cpp | 9 ++++++ src/dialogs/AutoTypeDlg.h | 1 + src/dialogs/SettingsDlg.cpp | 9 ++++++ src/dialogs/SettingsDlg.h | 2 +- src/forms/SettingsDlg.ui | 42 ++++++++++++++++++++++++- src/keepassx.h | 1 + src/main.cpp | 1 + src/mainwindow.cpp | 62 +++++++++++++++++++++++++++++++++---- src/mainwindow.h | 4 +++ 12 files changed, 137 insertions(+), 20 deletions(-) diff --git a/src/Application_X11.cpp b/src/Application_X11.cpp index 5ed3f3f..e8c6870 100644 --- a/src/Application_X11.cpp +++ b/src/Application_X11.cpp @@ -22,22 +22,18 @@ #include "lib/AutoType.h" #include "lib/HelperX11.h" +const unsigned int KeepassApplication::remove_invalid = ControlMask|ShiftMask|Mod1Mask|Mod5Mask|Mod4Mask; + KeepassApplication::KeepassApplication(int& argc, char** argv) : QApplication(argc, argv){ } bool KeepassApplication::x11EventFilter(XEvent* event){ - if (x11KeyEvent(event)) - return true; - else - return QApplication::x11EventFilter(event); -} - -bool KeepassApplication::x11KeyEvent(XEvent* event){ - static const unsigned int remove_invalid = ControlMask|ShiftMask|Mod1Mask|Mod5Mask|Mod4Mask; - if (event->type==KeyPress && AutoType::shortcut.key!=0u && event->xkey.keycode==XKeysymToKeycode(event->xkey.display,HelperX11::getKeysym(AutoType::shortcut.key)) && (event->xkey.state&remove_invalid)==HelperX11::getShortcutModifierMask(AutoType::shortcut) && QApplication::focusWidget()==NULL ){ + if (event->type==KeyPress && AutoType::shortcut.key!=0u && event->xkey.keycode==XKeysymToKeycode(event->xkey.display,HelperX11::getKeysym(AutoType::shortcut.key)) && (event->xkey.state&remove_invalid)==HelperX11::getShortcutModifierMask(AutoType::shortcut) && focusWidget()==NULL ){ + EventOccurred = true; AutoType::performGlobal(); return true; } - else - return false; + else{ + return QApplication::x11EventFilter(event); + } } diff --git a/src/Application_X11.h b/src/Application_X11.h index 8b7d4b1..206da50 100644 --- a/src/Application_X11.h +++ b/src/Application_X11.h @@ -28,7 +28,9 @@ class KeepassApplication : public QApplication public: KeepassApplication(int& argc, char** argv); bool x11EventFilter(XEvent* event); - static bool x11KeyEvent(XEvent* event); + + private: + static const unsigned int remove_invalid; }; #endif // APPLICATION_X11_H diff --git a/src/KpxConfig.h b/src/KpxConfig.h index b394c0f..9571e1a 100644 --- a/src/KpxConfig.h +++ b/src/KpxConfig.h @@ -83,6 +83,8 @@ public: bool showPasswords(){return settings.value("Options/ShowPasswords",false).toBool();} bool showPasswordsPasswordDlg(){return settings.value("Options/ShowPasswordsPasswordDlg",false).toBool();} bool lockOnMinimize(){return settings.value("Options/LockOnMinimize",false).toBool();} + bool lockOnInactivity(){return settings.value("Options/LockOnInactivity",false).toBool();} + int lockAfterSec(){return settings.value("Options/LockAfterSec",30).toInt();} bool showStatusbar(){return settings.value("UI/ShowStatusbar",true).toBool();} bool showSysTrayIcon(){return settings.value("Options/ShowSysTrayIcon",false).toBool();} bool showToolbar(){return settings.value("UI/ShowToolbar",true).toBool();} @@ -140,6 +142,8 @@ public: void setShowPasswords(bool value){settings.setValue("Options/ShowPasswords",value);} void setShowPasswordsPasswordDlg(bool value){settings.setValue("Options/ShowPasswordsPasswordDlg",value);} void setLockOnMinimize(bool value){settings.setValue("Options/LockOnMinimize",value);} + void setLockOnInactivity(bool value){settings.setValue("Options/LockOnInactivity",value);} + void setLockAfterSec(int value){settings.setValue("Options/LockAfterSec",value);} void setShowStatusbar(bool value){settings.setValue("UI/ShowStatusbar",value);} void setShowSysTrayIcon(bool value){settings.setValue("Options/ShowSysTrayIcon",value);} void setShowToolbar(bool value){settings.setValue("UI/ShowToolbar",value);} diff --git a/src/dialogs/AutoTypeDlg.cpp b/src/dialogs/AutoTypeDlg.cpp index 274f6c1..1d4498b 100644 --- a/src/dialogs/AutoTypeDlg.cpp +++ b/src/dialogs/AutoTypeDlg.cpp @@ -87,6 +87,15 @@ void AutoTypeDlg::resizeEvent(QResizeEvent* event){ createBanner(&BannerPixmap,getPixmap("keepassx_large"),tr("Auto-Type"),width()); } +bool AutoTypeDlg::event(QEvent* event){ + if (!EventOccurred){ + int t = event->type(); + if ( t>=QEvent::MouseButtonPress&&t<=QEvent::KeyRelease || t>=QEvent::HoverEnter&&t<=QEvent::HoverMove ) + EventOccurred = true; + } + return QWidget::event(event); +} + void AutoTypeDlg::itemSelected(QTreeWidgetItem* item){ close(); QString err; diff --git a/src/dialogs/AutoTypeDlg.h b/src/dialogs/AutoTypeDlg.h index 201e261..89acfd1 100644 --- a/src/dialogs/AutoTypeDlg.h +++ b/src/dialogs/AutoTypeDlg.h @@ -29,6 +29,7 @@ class AutoTypeDlg : public QWidget, private Ui::AutoTypeDlg protected: void paintEvent(QPaintEvent* event); void resizeEvent(QResizeEvent* event); + bool event(QEvent* event); private slots: void itemSelected(QTreeWidgetItem* item); diff --git a/src/dialogs/SettingsDlg.cpp b/src/dialogs/SettingsDlg.cpp index 3b861ad..361c695 100644 --- a/src/dialogs/SettingsDlg.cpp +++ b/src/dialogs/SettingsDlg.cpp @@ -50,6 +50,7 @@ CSettingsDlg::CSettingsDlg(QWidget* parent):QDialog(parent,Qt::Dialog) connect(Radio_IntPlugin_Kde,SIGNAL(toggled(bool)),this,SLOT(OnIntPluginKde())); connect(Button_CustomizeEntryDetails,SIGNAL(clicked()),this,SLOT(OnCustomizeEntryDetails())); + connect(CheckBox_InactivityLock, SIGNAL(toggled(bool)), SLOT(OnInactivityLockChange(bool))); #if !defined(AUTOTYPE) Box_AutoType->setVisible(false); @@ -115,6 +116,8 @@ CSettingsDlg::CSettingsDlg(QWidget* parent):QDialog(parent,Qt::Dialog) CheckBox_ShowPasswords->setChecked(config->showPasswords()); CheckBox_ShowPasswords_PasswordDlg->setChecked(config->showPasswordsPasswordDlg()); CheckBox_LockMinimize->setChecked(config->lockOnMinimize()); + CheckBox_InactivityLock->setChecked(config->lockOnInactivity()); + SpinBox_InacitivtyTime->setValue(config->lockAfterSec()); //Features CheckBox_FeatureBookmarks->setChecked(config->featureBookmarks()); @@ -221,6 +224,8 @@ void CSettingsDlg::apply(){ config->setShowPasswords(CheckBox_ShowPasswords->isChecked()); config->setShowPasswordsPasswordDlg(CheckBox_ShowPasswords_PasswordDlg->isChecked()); config->setLockOnMinimize(CheckBox_LockMinimize->isChecked()); + config->setLockOnInactivity(CheckBox_InactivityLock->isChecked()); + config->setLockAfterSec(SpinBox_InacitivtyTime->value()); //Features config->setFeatureBookmarks(CheckBox_FeatureBookmarks->isChecked()); @@ -321,6 +326,10 @@ void CSettingsDlg::OnCustomizeEntryDetails(){ dlg.exec(); } +void CSettingsDlg::OnInactivityLockChange(bool checked){ + SpinBox_InacitivtyTime->setEnabled(checked); +} + #ifdef GLOBAL_AUTOTYPE void CSettingsDlg::resetGlobalShortcut(){ AutoType::unregisterGlobalShortcut(); diff --git a/src/dialogs/SettingsDlg.h b/src/dialogs/SettingsDlg.h index 4fff3fc..d0575c1 100644 --- a/src/dialogs/SettingsDlg.h +++ b/src/dialogs/SettingsDlg.h @@ -44,7 +44,7 @@ class CSettingsDlg : public QDialog, public Ui_SettingsDialog void OnMountDirBrowse(); void OnBrowserCmdBrowse(); void OnCustomizeEntryDetails(); - + void OnInactivityLockChange(bool checked); #ifdef GLOBAL_AUTOTYPE private slots: diff --git a/src/forms/SettingsDlg.ui b/src/forms/SettingsDlg.ui index c81a3e6..4d4564e 100644 --- a/src/forms/SettingsDlg.ui +++ b/src/forms/SettingsDlg.ui @@ -754,7 +754,7 @@ - Seconds + seconds @@ -767,6 +767,46 @@ + + + + + + Lock database after inactivity of + + + + + + + false + + + + 0 + 0 + + + + + 80 + 16777215 + + + + 50000 + + + + + + + seconds + + + + + diff --git a/src/keepassx.h b/src/keepassx.h index 10a87b0..92151e3 100644 --- a/src/keepassx.h +++ b/src/keepassx.h @@ -99,6 +99,7 @@ extern QString DataDir; extern bool TrActive; extern QString DetailViewTemplate; extern QPixmap *EntryIcons; +extern bool EventOccurred; #endif //__cplusplus #endif //KEEPASS_X_ diff --git a/src/main.cpp b/src/main.cpp index ed9ed94..4e98141 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -45,6 +45,7 @@ QString DataDir; QString PluginLoadError; bool TrActive; QString DetailViewTemplate; +bool EventOccurred; QPixmap* EntryIcons; //IIconTheme* IconLoader=NULL; //TODO plugins diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 40b9189..555c870 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -52,6 +52,8 @@ Export_KeePassX_Xml export_KeePassX_Xml; KeepassMainWindow::KeepassMainWindow(const QString& ArgFile,bool ArgMin,bool ArgLock,QWidget *parent, Qt::WFlags flags) :QMainWindow(parent,flags){ ShutingDown=false; IsLocked=false; + EventOccurred=true; + inactivityCounter=0; InUnLock=false; unlockDlg=NULL; db=NULL; @@ -87,6 +89,12 @@ KeepassMainWindow::KeepassMainWindow(const QString& ArgFile,bool ArgMin,bool Arg LockedCentralWidget->setVisible(false); setupConnections(); + + inactivityTimer = new QTimer(this); + inactivityTimer->setInterval(500); + connect(inactivityTimer, SIGNAL(timeout()), SLOT(OnInactivityTimer())); + if (config->lockOnInactivity() && config->lockAfterSec()!=0) + inactivityTimer->start(); bool showWindow=true; FileOpen=false; @@ -436,6 +444,7 @@ bool KeepassMainWindow::openDatabase(QString filename,bool IsAuto){ } } StatusBarGeneral->setText(tr("Ready")); + inactivityCounter = 0; return true; } @@ -1000,18 +1009,36 @@ void KeepassMainWindow::showEvent(QShowEvent* event){ QMainWindow::showEvent(event); } +bool KeepassMainWindow::event(QEvent* event){ + if (!EventOccurred){ + int t = event->type(); + if ( t>=QEvent::MouseButtonPress&&t<=QEvent::KeyRelease || t>=QEvent::HoverEnter&&t<=QEvent::HoverMove ) + EventOccurred = true; + } + return QMainWindow::event(event); +} + void KeepassMainWindow::OnExtrasSettings(){ CSettingsDlg dlg(this); - if(dlg.exec()==QDialog::Accepted){ - EntryView->setAlternatingRowColors(config->alternatingRowColors()); - SysTray->setVisible(config->showSysTrayIcon()); - menuBookmarks->menuAction()->setVisible(config->featureBookmarks()); + dlg.exec(); + + EntryView->setAlternatingRowColors(config->alternatingRowColors()); + SysTray->setVisible(config->showSysTrayIcon()); + menuBookmarks->menuAction()->setVisible(config->featureBookmarks()); + + EventOccurred = true; + if (config->lockOnInactivity() && config->lockAfterSec()!=0 && !inactivityTimer->isActive()){ + inactivityCounter = 0; + inactivityTimer->start(); + } + else if ((!config->lockOnInactivity() || config->lockAfterSec()==0) && inactivityTimer->isActive()){ + inactivityTimer->stop(); } } void KeepassMainWindow::OnHelpAbout(){ -AboutDialog dlg(this); -dlg.exec(); + AboutDialog dlg(this); + dlg.exec(); } //TODO Handbook @@ -1214,6 +1241,29 @@ void KeepassMainWindow::resetLock(){ IsLocked=false; } +void KeepassMainWindow::OnInactivityTimer(){ + if (IsLocked || !FileOpen) + return; + + QWidgetList widgets = QApplication::topLevelWidgets(); + for (int i=0; iwindowModality()==Qt::ApplicationModal){ + inactivityCounter = 0; + return; + } + } + + if (EventOccurred){ + inactivityCounter = 0; + EventOccurred = false; + } + else{ + inactivityCounter++; + if (inactivityCounter*(inactivityTimer->interval()) >= config->lockAfterSec()*1000) + OnUnLockWorkspace(); + } +} + void KeepassMainWindow::OnBookmarkTriggered(QAction* action){ if(action==AddBookmarkAction){ AddBookmarkDlg dlg(this); diff --git a/src/mainwindow.h b/src/mainwindow.h index 0ed6126..d9d880f 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -78,11 +78,13 @@ class KeepassMainWindow : public QMainWindow, public Ui_MainWindow{ void OnDetailViewUrlClicked(const QUrl& url); void OnUnLockWorkspace(); void OnLockClose(); + void OnInactivityTimer(); private: void closeEvent(QCloseEvent* event); void hideEvent(QHideEvent* event); void showEvent(QShowEvent* event); + bool event(QEvent* event); void setLock(); void resetLock(); SelectionState GroupSelection, EntrySelection; @@ -124,6 +126,8 @@ class KeepassMainWindow : public QMainWindow, public Ui_MainWindow{ QList lockGroup; QDialog* unlockDlg; QString currentFile; + int inactivityCounter; + QTimer* inactivityTimer; }; #endif