1 /***************************************************************************
2 * Copyright (C) 2005-2007 by Tarek Saidi *
3 * tarek.saidi@arcor.de *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; version 2 of the License. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
23 #include "mainwindow.h"
24 #include "lib/AutoType.h"
25 #include "import/Import_PwManager.h"
26 #include "import/Import_KWalletXml.h"
27 #include "import/Import_KeePassX_Xml.h"
28 #include "export/Export_Txt.h"
29 #include "export/Export_KeePassX_Xml.h"
31 #include "dialogs/AboutDlg.h"
32 #include "dialogs/SearchDlg.h"
33 #include "dialogs/SettingsDlg.h"
34 #include "dialogs/DatabaseSettingsDlg.h"
35 #include "dialogs/PasswordDlg.h"
36 #include "dialogs/SimplePasswordDlg.h"
37 #include "dialogs/PasswordGenDlg.h"
38 #include "dialogs/CollectEntropyDlg.h"
39 #include "dialogs/CustomizeDetailViewDlg.h"
40 #include "dialogs/ExpiredEntriesDlg.h"
41 //#include "dialogs/TrashCanDlg.h" //TODO TrashCan
42 #include "dialogs/AddBookmarkDlg.h"
43 #include "dialogs/ManageBookmarksDlg.h"
44 #include "dialogs/HelpDlg.h"
46 Import_KeePassX_Xml import_KeePassX_Xml;
47 Import_PwManager import_PwManager;
48 Import_KWalletXml import_KWalletXml;
49 Export_Txt export_Txt;
50 Export_KeePassX_Xml export_KeePassX_Xml;
52 KeepassMainWindow::KeepassMainWindow(const QString& ArgFile,bool ArgMin,bool ArgLock,QWidget *parent, Qt::WFlags flags) :QMainWindow(parent,flags){
61 setUnifiedTitleAndToolBarOnMac(true);
66 #ifdef GLOBAL_AUTOTYPE
67 autoType->registerGlobalShortcut(config->globalShortcut());
69 setWindowModified(false);
70 QByteArray windowGeo = config->mainWindowGeometry();
71 if (!windowGeo.isEmpty())
72 restoreGeometry(windowGeo);
73 VSplitter->restoreState(config->vSplitterPos());
74 HSplitter->restoreState(config->hSplitterPos());
75 SysTray=new QSystemTrayIcon(this);
78 setStateFileOpen(false);
80 DetailView->setVisible(config->showEntryDetails());
81 StatusBarGeneral=new QLabel(statusBar());
82 //StatusBarSelection=new QLabel(statusBar());
83 statusBar()->addWidget(StatusBarGeneral,15);
84 //statusBar()->addWidget(StatusBarSelection,85);
85 statusBar()->setVisible(config->showStatusbar());
86 setStatusBarMsg(StatusBarReady);
88 if (config->alwaysOnTop())
89 setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
92 NormalCentralWidget=QMainWindow::centralWidget();
93 LockedCentralWidget=new QWidget(this);
94 WorkspaceLockedWidget.setupUi(LockedCentralWidget);
95 LockedCentralWidget->setVisible(false);
98 connect(qApp, SIGNAL(commitDataRequest(QSessionManager&)), SLOT(OnShutdown(QSessionManager&)));
100 inactivityTimer = new QTimer(this);
101 inactivityTimer->setInterval(500);
102 connect(inactivityTimer, SIGNAL(timeout()), SLOT(OnInactivityTimer()));
103 if (config->lockOnInactivity() && config->lockAfterSec()!=0)
104 inactivityTimer->start();
106 bool showWindow = !ArgMin;
108 if(!ArgFile.isEmpty()){
109 QString f = QDir::cleanPath(QDir::current().absoluteFilePath(ArgFile));
113 openDatabase(f,false);
115 else if(config->openLastFile() && !config->lastFile().isEmpty()){
116 QFileInfo file(config->lastFile());
118 QString f = QDir::cleanPath(QDir::current().absoluteFilePath(config->lastFile()));
120 showWindow = !config->startMinimized();
121 if (ArgLock || config->startLocked())
124 openDatabase(f,true);
127 config->setLastFile(QString());
131 /*HelpBrowser = new QAssistantClient(QString(),this);
132 HelpBrowser->setArguments(QStringList()<< "-profile" << "share/keepass/doc/keepassx.adp");*/
134 createBookmarkActions();
138 else if (!config->showSysTrayIcon())
142 void KeepassMainWindow::setupConnections(){
143 connect(FileNewAction, SIGNAL(triggered()), this, SLOT(OnFileNewKdb()));
144 connect(FileOpenAction, SIGNAL(triggered()), this, SLOT(OnFileOpen()));
145 connect(FileCloseAction, SIGNAL(triggered()), this, SLOT(OnFileClose()));
146 connect(FileSaveAction, SIGNAL(triggered()), this, SLOT(OnFileSave()));
147 connect(FileSaveAsAction, SIGNAL(triggered()), this, SLOT(OnFileSaveAs()));
148 connect(FileSettingsAction, SIGNAL(triggered()), this, SLOT(OnFileSettings()));
149 connect(FileChangeKeyAction, SIGNAL(triggered()), this, SLOT(OnFileChangeKey()));
150 connect(FileExitAction, SIGNAL(triggered()), this, SLOT(OnFileExit()));
151 connect(FileUnLockWorkspaceAction,SIGNAL(triggered()), this, SLOT(OnUnLockWorkspace()));
152 connect(menuImport,SIGNAL(triggered(QAction*)),this,SLOT(OnImport(QAction*)));
153 connect(menuExport,SIGNAL(triggered(QAction*)),this,SLOT(OnExport(QAction*)));
154 connect(menuBookmarks,SIGNAL(triggered(QAction*)),this,SLOT(OnBookmarkTriggered(QAction*)));
156 connect(EditNewGroupAction, SIGNAL(triggered()), GroupView, SLOT(OnNewGroup()));
157 connect(EditNewSubgroupAction, SIGNAL(triggered()), GroupView, SLOT(OnNewSubgroup()));
158 connect(EditEditGroupAction, SIGNAL(triggered()), GroupView, SLOT(OnEditGroup()));
159 connect(EditDeleteGroupAction, SIGNAL(triggered()), GroupView, SLOT(OnDeleteGroup()));
160 connect(EditGroupSortAction, SIGNAL(triggered()), GroupView, SLOT(OnSort()));
161 connect(EditNewEntryAction, SIGNAL(triggered()), EntryView, SLOT(OnNewEntry()));
162 connect(EditEditEntryAction, SIGNAL(triggered()), EntryView, SLOT(OnEditEntry()));
163 connect(EntryView, SIGNAL(requestCreateGroup(QString,quint32,GroupViewItem*)),
164 GroupView, SLOT(createGroup(QString,quint32,GroupViewItem*)));
165 connect(EditCloneEntryAction, SIGNAL(triggered()), EntryView, SLOT(OnCloneEntry()));
166 connect(EditDeleteEntryAction, SIGNAL(triggered()), EntryView, SLOT(OnDeleteEntry()));
167 connect(EditUsernameToClipboardAction, SIGNAL(triggered()), EntryView, SLOT(OnUsernameToClipboard()));
168 connect(EditPasswordToClipboardAction, SIGNAL(triggered()), EntryView, SLOT(OnPasswordToClipboard()));
169 connect(EditOpenUrlAction, SIGNAL(triggered()), EntryView, SLOT(OnEditOpenUrl()));
170 connect(EditCopyUrlAction, SIGNAL(triggered()), EntryView, SLOT(OnEditCopyUrl()));
171 connect(EditSaveAttachmentAction, SIGNAL(triggered()),EntryView, SLOT(OnSaveAttachment()));
172 connect(EditSearchAction, SIGNAL(triggered()), this, SLOT(OnSearch()));
173 connect(EditGroupSearchAction, SIGNAL(triggered()), this, SLOT(OnGroupSearch()));
175 connect(EditAutoTypeAction,SIGNAL(triggered()),EntryView,SLOT(OnAutoType()));
178 connect(ViewShowToolbarAction,SIGNAL(toggled(bool)),this,SLOT(OnViewShowToolbar(bool)));
179 connect(ViewShowEntryDetailsAction,SIGNAL(toggled(bool)),this,SLOT(OnViewShowEntryDetails(bool)));
180 connect(ViewHidePasswordsAction,SIGNAL(toggled(bool)), this, SLOT(OnUsernPasswVisibilityChanged()));
181 connect(ViewHideUsernamesAction,SIGNAL(toggled(bool)), this, SLOT(OnUsernPasswVisibilityChanged()));
183 connect(menuColumns,SIGNAL(triggered(QAction*)),this,SLOT(OnColumnVisibilityChanged()));
184 connect(ViewToolButtonSize16Action,SIGNAL(toggled(bool)), this, SLOT(OnViewToolbarIconSize16(bool)));
185 connect(ViewToolButtonSize22Action,SIGNAL(toggled(bool)), this, SLOT(OnViewToolbarIconSize22(bool)));
186 connect(ViewToolButtonSize28Action,SIGNAL(toggled(bool)), this, SLOT(OnViewToolbarIconSize28(bool)));
187 connect(ViewShowStatusbarAction,SIGNAL(toggled(bool)),statusBar(),SLOT(setVisible(bool)));
189 connect(ExtrasSettingsAction,SIGNAL(triggered(bool)),this,SLOT(OnExtrasSettings()));
190 connect(ExtrasPasswordGenAction,SIGNAL(triggered(bool)),this,SLOT(OnExtrasPasswordGen()));
191 connect(ExtrasShowExpiredEntriesAction,SIGNAL(triggered(bool)),this,SLOT(OnExtrasShowExpiredEntries()));
192 //connect(ExtrasTrashCanAction,SIGNAL(triggered(bool)),this,SLOT(OnExtrasTrashCan())); //TODO ExtrasTrashCan
194 connect(HelpHandbookAction,SIGNAL(triggered()),this,SLOT(OnHelpHandbook()));
195 connect(HelpAboutAction,SIGNAL(triggered()),this,SLOT(OnHelpAbout()));
197 connect(QuickSearchEdit,SIGNAL(returnPressed()), this, SLOT(OnQuickSearch()));
198 connect(GroupView,SIGNAL(groupChanged(IGroupHandle*)),EntryView,SLOT(OnGroupChanged(IGroupHandle*)));
199 connect(GroupView,SIGNAL(groupChanged(IGroupHandle*)),this,SLOT(OnGroupSelectionChanged(IGroupHandle*)));
200 connect(GroupView,SIGNAL(fileModified()),this,SLOT(OnFileModified()));
201 connect(EntryView,SIGNAL(fileModified()),this,SLOT(OnFileModified()));
202 connect(EntryView,SIGNAL(selectionChanged(SelectionState)),this,SLOT(OnEntryChanged(SelectionState)));
203 connect(GroupView,SIGNAL(searchResultsSelected()),EntryView,SLOT(OnShowSearchResults()));
204 connect(GroupView,SIGNAL(searchResultsSelected()),this,SLOT(OnShowSearchResults()));
205 connect(GroupView,SIGNAL(entriesDropped()),EntryView,SLOT(removeDragItems()));
206 connect(HideSearchResultsAction,SIGNAL(triggered()),GroupView,SLOT(OnHideSearchResults()));
207 connect(EntryView, SIGNAL(viewModeChanged(bool)), SLOT(loadColumnVisibility()));
208 connect(EntryView, SIGNAL(viewModeChanged(bool)), ViewColumnsGroupAction, SLOT(setVisible(bool)));
210 connect(SysTray,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),this,SLOT(OnSysTrayActivated(QSystemTrayIcon::ActivationReason)));
211 connect(DetailView,SIGNAL(anchorClicked(const QUrl&)),this,SLOT(OnDetailViewUrlClicked(const QUrl&)));
212 connect(WorkspaceLockedWidget.Button_Unlock,SIGNAL(clicked()),this,SLOT(OnUnLockWorkspace()));
213 connect(WorkspaceLockedWidget.Button_CloseDatabase,SIGNAL(clicked()),this,SLOT(OnLockClose()));
216 void KeepassMainWindow::setupToolbar(){
217 toolBar=new QToolBar(this);
218 toolBar->setMovable(false);
220 toolBar->setIconSize(QSize(config->toolbarIconSize(),config->toolbarIconSize()));
221 ViewShowToolbarAction=toolBar->toggleViewAction();
222 toolBar->addAction(FileNewAction);
223 toolBar->addAction(FileOpenAction);
224 toolBar->addAction(FileSaveAction);
225 toolBar->addSeparator();
226 toolBar->addAction(EditNewEntryAction);
227 toolBar->addAction(EditEditEntryAction);
228 toolBar->addAction(EditDeleteEntryAction);
229 toolBar->addSeparator();
230 toolBar->addAction(EditUsernameToClipboardAction);
231 toolBar->addAction(EditPasswordToClipboardAction);
232 toolBar->addSeparator();
233 toolBar->addAction(FileUnLockWorkspaceAction);
234 toolBar->addSeparator();
235 QuickSearchEdit=new QLineEdit(toolBar);
236 QuickSearchEdit->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
237 toolBar->addWidget(QuickSearchEdit);
238 toolBar->setVisible(config->showToolbar());
241 void KeepassMainWindow::setupIcons(){
242 setWindowIcon(getIcon("keepassx_small"));
243 FileNewAction->setIcon(getIcon("filenew"));
244 FileOpenAction->setIcon(getIcon("fileopen"));
245 FileSaveAction->setIcon(getIcon("filesave"));
246 FileSaveAsAction->setIcon(getIcon("filesaveas"));
247 FileCloseAction->setIcon(getIcon("fileclose"));
248 FileSettingsAction->setIcon(getIcon("dbsettings"));
249 FileUnLockWorkspaceAction->setIcon(getIcon("lock"));
250 FileExitAction->setIcon(getIcon("exit"));
251 EditNewEntryAction->setIcon(getIcon("newentry"));
252 EditEditEntryAction->setIcon(getIcon("editentry"));
253 EditDeleteEntryAction->setIcon(getIcon("deleteentry"));
254 EditGroupSortAction->setIcon(getIcon("swap"));
255 EditUsernameToClipboardAction->setIcon(getIcon("copyusername"));
256 EditPasswordToClipboardAction->setIcon(getIcon("copypwd"));
257 EditCloneEntryAction->setIcon(getIcon("cloneentry"));
258 EditOpenUrlAction->setIcon(getIcon("openurl"));
259 EditSaveAttachmentAction->setIcon(getIcon("filesave"));
260 EditNewGroupAction->setIcon(getIcon("newgroup"));
261 EditNewSubgroupAction->setIcon(getIcon("newgroup"));
262 EditEditGroupAction->setIcon(getIcon("editgroup"));
263 EditDeleteGroupAction->setIcon(getIcon("deletegroup"));
264 EditSearchAction->setIcon(getIcon("dbsearch"));
265 EditGroupSearchAction->setIcon(getIcon("groupsearch"));
266 ExtrasShowExpiredEntriesAction->setIcon(getIcon("expired"));
267 ExtrasPasswordGenAction->setIcon(getIcon("generator"));
268 //ExtrasTrashCanAction->setIcon(getIcon("trashcan")); //TODO ExtrasTrashCan
269 ExtrasSettingsAction->setIcon(getIcon("appsettings"));
271 EditAutoTypeAction->setIcon(getIcon("autotype"));
273 EditAutoTypeAction->setVisible(false);
275 HelpHandbookAction->setIcon(getIcon("manual"));
276 HelpAboutAction->setIcon(getIcon("help_about"));
277 menuBookmarks->menuAction()->setIcon(getIcon("bookmark_folder"));
278 AddThisAsBookmarkAction->setIcon(getIcon("bookmark_this"));
279 AddBookmarkAction->setIcon(getIcon("bookmark_add"));
280 ManageBookmarksAction->setIcon(getIcon("bookmark"));
281 SysTray->setIcon(getIcon("keepassx"));
282 if(config->showSysTrayIcon())
286 void KeepassMainWindow::setupMenus(){
287 GroupView->ContextMenu->addAction(EditNewSubgroupAction);
288 GroupView->ContextMenu->addAction(EditEditGroupAction);
289 GroupView->ContextMenu->addAction(EditDeleteGroupAction);
290 GroupView->ContextMenu->addAction(EditGroupSortAction);
291 GroupView->ContextMenu->addSeparator();
292 GroupView->ContextMenu->addAction(EditNewEntryAction);
293 GroupView->ContextMenu->addSeparator();
294 GroupView->ContextMenu->addAction(EditGroupSearchAction);
295 GroupView->ContextMenuSearchGroup->addAction(HideSearchResultsAction);
297 EntryView->ContextMenu->addAction(EditUsernameToClipboardAction);
298 EntryView->ContextMenu->addAction(EditPasswordToClipboardAction);
299 EntryView->ContextMenu->addAction(EditOpenUrlAction);
300 EntryView->ContextMenu->addAction(EditCopyUrlAction);
301 EntryView->ContextMenu->addAction(EditSaveAttachmentAction);
303 EntryView->ContextMenu->addAction(EditAutoTypeAction);
305 EntryView->ContextMenu->addSeparator();
306 EntryView->ContextMenu->addAction(EditNewEntryAction);
307 EntryView->ContextMenu->addAction(EditEditEntryAction);
308 EntryView->ContextMenu->addAction(EditCloneEntryAction);
309 EntryView->ContextMenu->addAction(EditDeleteEntryAction);
311 ViewShowToolbarAction->setText(tr("Show &Toolbar"));
312 ViewMenu->insertAction(ViewShowEntryDetailsAction,ViewShowToolbarAction);
313 ViewShowToolbarAction->setChecked(config->showToolbar());
314 ViewShowEntryDetailsAction->setChecked(config->showEntryDetails());
315 ViewHidePasswordsAction->setChecked(config->hidePasswords());
316 ViewHideUsernamesAction->setChecked(config->hideUsernames());
317 loadColumnVisibility();
318 ViewShowStatusbarAction->setChecked(config->showStatusbar());
320 switch(config->toolbarIconSize()){
321 case 16: ViewToolButtonSize16Action->setChecked(true); break;
322 case 22: ViewToolButtonSize22Action->setChecked(true); break;
323 case 28: ViewToolButtonSize28Action->setChecked(true); break;
326 SysTrayMenu = new QMenu(APP_DISPLAY_NAME,this);
327 SysTrayMenu->addAction(FileUnLockWorkspaceAction);
328 SysTrayMenu->addSeparator();
329 SysTrayMenu->addAction(FileExitAction);
330 SysTray->setContextMenu(SysTrayMenu);
333 #define _add_import(name){\
334 QAction* import=new QAction(this);\
335 import->setData(qVariantFromValue(dynamic_cast<QObject*>(&name)));\
336 import->setText(name.title());\
337 menuImport->addAction(import);}
339 #define _add_export(name){\
340 QAction* Export=new QAction(this);\
341 Export->setData(qVariantFromValue(dynamic_cast<QObject*>(&name)));\
342 Export->setText(name.title());\
343 menuExport->addAction(Export);}
345 _add_import(import_KeePassX_Xml)
346 _add_import(import_PwManager)
347 _add_import(import_KWalletXml)
348 _add_export(export_Txt);
349 _add_export(export_KeePassX_Xml);
351 FileNewAction->setShortcut(tr("Ctrl+N"));
352 FileOpenAction->setShortcut(tr("Ctrl+O"));
353 FileCloseAction->setShortcut(tr("Ctrl+W"));
354 FileSaveAction->setShortcut(tr("Ctrl+S"));
355 FileUnLockWorkspaceAction->setShortcut(tr("Ctrl+L"));
356 FileExitAction->setShortcut(tr("Ctrl+Q"));
357 EditNewGroupAction->setShortcut(tr("Ctrl+G"));
358 EditPasswordToClipboardAction->setShortcut(tr("Ctrl+C"));
359 EditUsernameToClipboardAction->setShortcut(tr("Ctrl+B"));
360 EditOpenUrlAction->setShortcut(tr("Ctrl+U"));
361 EditCopyUrlAction->setShortcut(tr("Ctrl+I"));
362 EditNewEntryAction->setShortcut(tr("Ctrl+Y"));
363 EditEditEntryAction->setShortcut(tr("Ctrl+E"));
364 EditDeleteEntryAction->setShortcut(tr("Ctrl+D"));
365 EditCloneEntryAction->setShortcut(tr("Ctrl+K"));
366 EditSearchAction->setShortcut(tr("Ctrl+F"));
367 ExtrasPasswordGenAction->setShortcut(tr("Ctrl+P"));
368 ExtrasShowExpiredEntriesAction->setShortcut(tr("Ctrl+X"));
370 EditAutoTypeAction->setShortcut(tr("Ctrl+V"));
373 FileSaveAsAction->setShortcut(tr("Shift+Ctrl+S"));
374 EditGroupSearchAction->setShortcut(tr("Shift+Ctrl+F"));
377 //ExtrasTrashCanAction->setVisible(false); //TODO For KP 2.x only
378 menuBookmarks->menuAction()->setVisible(config->featureBookmarks());
381 void KeepassMainWindow::loadColumnVisibility() {
382 ViewColumnsTitleAction->setChecked(EntryView->columnVisible(0));
383 ViewColumnsUsernameAction->setChecked(EntryView->columnVisible(1));
384 ViewColumnsUrlAction->setChecked(EntryView->columnVisible(2));
385 ViewColumnsPasswordAction->setChecked(EntryView->columnVisible(3));
386 ViewColumnsCommentAction->setChecked(EntryView->columnVisible(4));
387 ViewColumnsExpireAction->setChecked(EntryView->columnVisible(5));
388 ViewColumnsCreationAction->setChecked(EntryView->columnVisible(6));
389 ViewColumnsLastChangeAction->setChecked(EntryView->columnVisible(7));
390 ViewColumnsLastAccessAction->setChecked(EntryView->columnVisible(8));
391 ViewColumnsAttachmentAction->setChecked(EntryView->columnVisible(9));
392 ViewColumnsGroupAction->setChecked(EntryView->columnVisible(10));
395 void KeepassMainWindow::setupDatabaseConnections(IDatabase* DB){
396 ICustomIcons* CustomIconsDb=dynamic_cast<ICustomIcons*>(DB);
398 connect(CustomIconsDb,SIGNAL(iconsModified()),this,SLOT(OnFileModified()));
399 connect(CustomIconsDb,SIGNAL(iconsModified()),EntryView,SLOT(updateIcons()));
400 connect(CustomIconsDb,SIGNAL(iconsModified()),GroupView,SLOT(updateIcons()));
405 bool KeepassMainWindow::openDatabase(QString filename,bool IsAuto){
406 if (!QFile::exists(filename)){
407 QMessageBox::critical(this, tr("Error"), tr("The database file does not exist."));
413 if (QFile::exists(filename+".lock")){
414 QMessageBox msgBox(this);
415 msgBox.setIcon(QMessageBox::Question);
416 msgBox.setWindowTitle(tr("Database locked"));
417 msgBox.setText(tr("The database you are trying to open is locked.\n"
418 "This means that either someone else has opened the file or KeePassX crashed last time it opened the database.\n\n"
419 "Do you want to open it anyway?"
421 msgBox.addButton(QMessageBox::Yes);
422 msgBox.addButton(QMessageBox::No);
423 QPushButton* readOnlyButton = new QPushButton(tr("Open read-only"), &msgBox);
424 msgBox.addButton(readOnlyButton, QMessageBox::AcceptRole);
425 msgBox.setDefaultButton(readOnlyButton);
428 if (!msgBox.clickedButton() || msgBox.clickedButton() == msgBox.button(QMessageBox::No))
430 else if (msgBox.clickedButton() == readOnlyButton)
435 config->setLastKeyLocation(QString());
436 config->setLastKeyType(PASSWORD);
438 db = new Kdb3Database();
439 PasswordDialog::DlgFlags flags=PasswordDialog::Flag_None;
441 flags = PasswordDialog::Flag_Auto;
442 PasswordDialog dlg(this,PasswordDialog::Mode_Ask,flags,filename);
444 dlg.setWindowModality(Qt::WindowModal);
447 bool rejected = (dlg.exec()==PasswordDialog::Exit_Cancel);
453 if(dlg.selectedBookmark()!=QString())
454 filename=dlg.selectedBookmark();
458 setupDatabaseConnections(db);
460 setStatusBarMsg(StatusBarLoading);
461 db->setKey(dlg.password(),dlg.keyFile());
463 if (!dbReadOnly && !QFile::exists(filename+".lock")){
464 QFile lock(filename+".lock");
465 if (!lock.open(QIODevice::WriteOnly)){
466 setStatusBarMsg(StatusBarReadOnlyLock);
471 if(db->load(filename, dbReadOnly)){
474 updateCurrentFile(filename);
475 saveLastFilename(filename);
476 GroupView->createItems();
477 EntryView->showGroup(NULL);
478 setStateFileOpen(true);
479 setStateFileModified(static_cast<Kdb3Database*>(db)->hasPasswordEncodingChanged());
482 if (!dbReadOnly && QFile::exists(filename+".lock"))
483 QFile::remove(filename+".lock");
484 setStatusBarMsg(StatusBarLoadingFailed);
485 QString error=db->getError();
486 if(error.isEmpty())error=tr("Unknown error while loading database.");
487 QMessageBox::critical(this,tr("Error"),
488 QString("%1\n%2").arg(tr("The following error occured while opening the database:"))
490 if(db->isKeyError()){
492 return openDatabase(filename,IsAuto);
499 if (statusbarState != StatusBarReadOnlyLock)
500 setStatusBarMsg(StatusBarReady);
501 inactivityCounter = 0;
503 GroupView->selectFirstGroup();
508 void KeepassMainWindow::fakeOpenDatabase(const QString& filename){
509 if (!QFile::exists(filename)){
510 QMessageBox::critical(this, tr("Error"), tr("The database file does not exist."));
514 config->setLastFile(filename);
515 updateCurrentFile(filename);
519 bool KeepassMainWindow::closeDatabase(bool lock){
523 if(config->autoSave() && db->file()){
524 if(!OnFileSave()) return false;
527 QMessageBox::StandardButton r=QMessageBox::question(this,tr("Save modified file?"),
528 tr("The current file was modified.\nDo you want to save the changes?"),
529 QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel, QMessageBox::Yes);
530 if(r==QMessageBox::Cancel) return false; //Cancel
531 if(r==QMessageBox::Yes){ //Yes (Save file)
533 if(!OnFileSaveAs()) return false;
536 if(!OnFileSave()) return false;
544 if (!dbReadOnly && QFile::exists(currentFilePath+".lock")){
545 if (!QFile::remove(currentFilePath+".lock"))
546 QMessageBox::critical(this, tr("Error"), tr("Couldn't remove database lock file."));
550 EntryView->Items.clear();
553 GroupView->Items.clear();
554 SearchResults.clear();
557 setStateFileOpen(false);
559 updateCurrentFile(QString());
560 QuickSearchEdit->setText("");
567 void KeepassMainWindow::OnFileNewKdb(){
568 IDatabase* db_new=dynamic_cast<IDatabase*>(new Kdb3Database());
570 PasswordDialog dlg(this,PasswordDialog::Mode_Set,PasswordDialog::Flag_None,"New Database");
571 if(dlg.exec()==PasswordDialog::Exit_Ok){
573 if(!closeDatabase())return;
577 db->setKey(dlg.password(),dlg.keyFile());
578 db->generateMasterKey();
579 updateCurrentFile(QString());
582 GroupView->createItems();
583 EntryView->showGroup(NULL);
584 setStateFileOpen(true);
585 setStateFileModified(true);
586 setupDatabaseConnections(db);
587 setStateGroupSelected(NONE);
588 setStateEntrySelected(NONE);
589 GroupView->createGroup("Internet", 1);
590 GroupView->createGroup("eMail", 19);
597 void KeepassMainWindow::openFile(const QString& filename) {
602 openDatabase(filename);
605 void KeepassMainWindow::OnFileOpen(){
606 /*QFileDialog FileDlg(this,tr("Open Database..."),QDir::homePath());
607 FileDlg.setFilters(QStringList()<< tr("KeePass Databases (*.kdb)")<< tr("All Files (*)"));
608 FileDlg.setFileMode(QFileDialog::ExistingFile);
609 FileDlg.setAcceptMode(QFileDialog::AcceptOpen);
610 if(!FileDlg.exec())return;
611 if(!FileDlg.selectedFiles().size())return;*/
612 QString filename=KpxFileDialogs::openExistingFile(this,"MainWindow_FileOpen",
613 tr("Open Database..."),QStringList()<<tr("KeePass Databases (*.kdb)")<< tr("All Files (*)"));
614 if (!filename.isEmpty())
618 void KeepassMainWindow::OnFileClose(){
625 void KeepassMainWindow::setStateFileOpen(bool IsOpen){
627 FileSaveAction->setEnabled(IsOpen);
628 FileSaveAsAction->setEnabled(IsOpen);
629 FileCloseAction->setEnabled(IsOpen||IsLocked);
630 FileSettingsAction->setEnabled(IsOpen);
631 FileChangeKeyAction->setEnabled(IsOpen);
632 menuExport->setEnabled(IsOpen);
633 EditNewGroupAction->setEnabled(IsOpen);
634 EditSearchAction->setEnabled(IsOpen);
635 GroupView->setEnabled(IsOpen);
636 EntryView->setEnabled(IsOpen);
637 DetailView->setEnabled(IsOpen);
638 QuickSearchEdit->setEnabled(IsOpen);
639 ExtrasShowExpiredEntriesAction->setEnabled(IsOpen);
640 AddThisAsBookmarkAction->setEnabled(IsOpen && db->file());
641 FileUnLockWorkspaceAction->setEnabled(IsOpen||IsLocked);
644 EditNewSubgroupAction->setEnabled(false);
645 EditEditGroupAction->setEnabled(false);
646 EditDeleteGroupAction->setEnabled(false);
647 EditPasswordToClipboardAction->setEnabled(false);
648 EditUsernameToClipboardAction->setEnabled(false);
649 EditOpenUrlAction->setEnabled(false);
650 EditCopyUrlAction->setEnabled(false);
651 EditSaveAttachmentAction->setEnabled(false);
652 EditNewEntryAction->setEnabled(false);
653 EditEditEntryAction->setEnabled(false);
654 EditCloneEntryAction->setEnabled(false);
655 EditDeleteEntryAction->setEnabled(false);
656 EditGroupSearchAction->setEnabled(false);
658 EditAutoTypeAction->setEnabled(false);
667 void KeepassMainWindow::setStateFileModified(bool mod){
668 if (config->autoSaveChange() && mod && db->file()){
670 return; // return on success, so we don't set the state to modified
675 FileSaveAction->setIcon(getIcon("filesave"));
677 FileSaveAction->setIcon(getIcon("filesavedisabled"));
679 setWindowModified(mod);
682 void KeepassMainWindow::setStateGroupSelected(SelectionState s){
684 switch(GroupSelection){
686 EditNewSubgroupAction->setEnabled(false);
687 EditEditGroupAction->setEnabled(false);
688 EditDeleteGroupAction->setEnabled(false);
689 EditGroupSearchAction->setEnabled(false);
690 EditNewEntryAction->setEnabled(false);
693 EditNewSubgroupAction->setEnabled(true);
694 EditEditGroupAction->setEnabled(true);
695 EditDeleteGroupAction->setEnabled(true);
696 EditGroupSearchAction->setEnabled(true);
697 EditNewEntryAction->setEnabled(true);
700 EditNewSubgroupAction->setEnabled(false);
701 EditEditGroupAction->setEnabled(false);
702 EditDeleteGroupAction->setEnabled(false);
703 EditGroupSearchAction->setEnabled(false);
704 EditNewEntryAction->setEnabled(false);
706 default: Q_ASSERT(false);
710 void KeepassMainWindow::updateDetailView(){
711 if(EntryView->selectedItems().size()!=1){
712 DetailView->setPlainText("");
716 QString templ=DetailViewTemplate;
717 IEntryHandle* entry=((EntryViewItem*)(EntryView->selectedItems()[0]))->EntryHandle;
719 templ.replace("%group%", Qt::escape(entry->group()->title()));
720 templ.replace("%title%", Qt::escape(entry->title()));
721 if (config->hideUsernames())
722 templ.replace("%username%","****");
724 templ.replace("%username%", Qt::escape(entry->username()));
725 if (!config->hidePasswords()) {
726 SecString password=entry->password();
728 templ.replace("%password%", Qt::escape(password.string()));
731 templ.replace("%password%","****");
733 templ.replace("%url%", Qt::escape(entry->url()));
734 templ.replace("%creation%", Qt::escape(entry->creation().toString(Qt::SystemLocaleDate)));
735 templ.replace("%lastmod%", Qt::escape(entry->lastMod().toString(Qt::SystemLocaleDate)));
736 templ.replace("%lastaccess%", Qt::escape(entry->lastAccess().toString(Qt::SystemLocaleDate)));
737 templ.replace("%expire%", Qt::escape(entry->expire().toString(Qt::SystemLocaleDate)));
738 templ.replace("%comment%", Qt::escape(entry->comment()).replace("\n","<br/>"));
739 templ.replace("%attachment%", Qt::escape(entry->binaryDesc()));
741 if(entry->expire()!=Date_Never){
742 int secs=QDateTime::currentDateTime().secsTo(entry->expire());
744 templ.replace("%expire-timeleft%",tr("Expired"));
749 years=secs/(86400*365);
750 secs-=years*(86400*365);
751 months=secs/(86400*30);
752 secs-=months*(86400*30);
760 out=tr("%1 Months").arg(months);
766 out.prepend(tr("1 Year"));
768 out.prepend(tr("%1 Years").arg(years));
774 out.append(tr("1 Day"));
776 out.append(tr("%1 Days").arg(days));
779 if(!days && !years && !months)
780 out=tr("less than 1 day");
782 templ.replace("%expire-timeleft%","in " + out);
786 templ.replace("%expire-timeleft%","-");
788 DetailView->setHtml(templ);
792 void KeepassMainWindow::setStateEntrySelected(SelectionState s){
794 if (GroupSelection == NONE || GroupSelection == SINGLE){
795 switch (EntrySelection){
797 EditPasswordToClipboardAction->setEnabled(false);
798 EditUsernameToClipboardAction->setEnabled(false);
799 EditOpenUrlAction->setEnabled(false);
800 EditCopyUrlAction->setEnabled(false);
801 EditSaveAttachmentAction->setEnabled(false);
802 EditEditEntryAction->setEnabled(false);
803 EditCloneEntryAction->setEnabled(false);
804 EditCloneEntryAction->setText(tr("Clone Entry"));
805 EditDeleteEntryAction->setEnabled(false);
806 EditDeleteEntryAction->setText(tr("Delete Entry"));
808 EditAutoTypeAction->setEnabled(false);
812 EditPasswordToClipboardAction->setEnabled(true);
813 EditUsernameToClipboardAction->setEnabled(true);
814 EditOpenUrlAction->setEnabled(true);
815 EditCopyUrlAction->setEnabled(true);
816 EditSaveAttachmentAction->setEnabled(((EntryViewItem*)(EntryView->selectedItems()[0]))->EntryHandle->binarySize() > 0);
817 EditEditEntryAction->setEnabled(true);
818 EditCloneEntryAction->setEnabled(true);
819 EditCloneEntryAction->setText(tr("Clone Entry"));
820 EditDeleteEntryAction->setEnabled(true);
821 EditDeleteEntryAction->setText(tr("Delete Entry"));
823 EditAutoTypeAction->setEnabled(true);
827 EditPasswordToClipboardAction->setEnabled(false);
828 EditUsernameToClipboardAction->setEnabled(false);
829 EditOpenUrlAction->setEnabled(false);
830 EditCopyUrlAction->setEnabled(false);
831 EditSaveAttachmentAction->setEnabled(false);
832 EditEditEntryAction->setEnabled(false);
833 EditCloneEntryAction->setEnabled(true);
834 EditCloneEntryAction->setText(tr("Clone Entries"));
835 EditDeleteEntryAction->setEnabled(true);
836 EditDeleteEntryAction->setText(tr("Delete Entries"));
838 EditAutoTypeAction->setEnabled(false);
845 else if (GroupSelection == SEARCHGROUP){
846 switch(EntrySelection){
848 EditUsernameToClipboardAction->setEnabled(false);
849 EditPasswordToClipboardAction->setEnabled(false);
850 EditOpenUrlAction->setEnabled(false);
851 EditCopyUrlAction->setEnabled(false);
852 EditSaveAttachmentAction->setEnabled(false);
853 EditEditEntryAction->setEnabled(false);
854 EditCloneEntryAction->setEnabled(false);
855 EditCloneEntryAction->setText(tr("Clone Entry"));
856 EditDeleteEntryAction->setEnabled(false);
857 EditDeleteEntryAction->setText(tr("Delete Entry"));
859 EditAutoTypeAction->setEnabled(false);
863 EditUsernameToClipboardAction->setEnabled(true);
864 EditPasswordToClipboardAction->setEnabled(true);
865 EditOpenUrlAction->setEnabled(true);
866 EditCopyUrlAction->setEnabled(true);
867 EditSaveAttachmentAction->setEnabled(((EntryViewItem*)(EntryView->selectedItems()[0]))->EntryHandle->binarySize() > 0);
868 EditEditEntryAction->setEnabled(true);
869 EditCloneEntryAction->setEnabled(false);
870 EditCloneEntryAction->setText(tr("Clone Entry"));
871 EditDeleteEntryAction->setEnabled(true);
872 EditDeleteEntryAction->setText(tr("Delete Entry"));
874 EditAutoTypeAction->setEnabled(true);
878 EditUsernameToClipboardAction->setEnabled(false);
879 EditPasswordToClipboardAction->setEnabled(false);
880 EditOpenUrlAction->setEnabled(false);
881 EditCopyUrlAction->setEnabled(false);
882 EditSaveAttachmentAction->setEnabled(false);
883 EditEditEntryAction->setEnabled(false);
884 EditCloneEntryAction->setEnabled(false);
885 EditCloneEntryAction->setText(tr("Clone Entries"));
886 EditDeleteEntryAction->setEnabled(true);
887 EditDeleteEntryAction->setText(tr("Delete Entries"));
889 EditAutoTypeAction->setEnabled(false);
901 bool KeepassMainWindow::OnFileSave(){
903 return OnFileSaveAs();
904 saveLastFilename(db->file()->fileName());
906 setStateFileOpen(true); // necessary for AddThisAsBookmarkAction
907 setStateFileModified(false);
908 if (config->backup() && config->backupDelete() && config->backupDeleteAfter()>0){
909 IGroupHandle* backupGroup = db->backupGroup();
910 if (backupGroup && backupGroup==EntryView->getCurrentGroup())
911 EntryView->showGroup(backupGroup);
916 showErrMsg(QString("%1\n%2").arg(tr("File could not be saved.")).arg(db->getError()));
921 bool KeepassMainWindow::OnFileSaveAs(){
922 QString filename=KpxFileDialogs::saveFile(this,"MainWindow_FileSave",
923 tr("Save Database..."),QStringList()<<tr("KeePass Databases (*.kdb)")<< tr("All Files (*)"));
924 if (filename.isEmpty() || filename.compare(".kdb", Qt::CaseInsensitive)==0)
927 QFile lock(filename+".lock");
928 if (!lock.open(QIODevice::WriteOnly)){
929 QMessageBox::critical(this, tr("Error"), tr("Couldn't create database lock file."));
933 if(!db->changeFile(filename)){
934 showErrMsg(QString("%1\n%2").arg(tr("File could not be saved.")).arg(db->getError()));
935 QFile::remove( filename+".lock" );
939 if (!dbReadOnly && !currentFilePath.isEmpty() && QFile::exists(currentFilePath+".lock")){
940 if (!QFile::remove(currentFilePath+".lock"))
941 QMessageBox::critical(this, tr("Error"), tr("Couldn't remove database lock file."));
945 updateCurrentFile(filename);
952 void KeepassMainWindow::OnFileSettings(){
953 CDbSettingsDlg dlg(this,db);
955 db->generateMasterKey();
956 setStateFileModified(true);
960 void KeepassMainWindow::OnFileChangeKey(){
961 QFile* file=db->file();
962 QString filename = file ? file->fileName() : QString();
963 PasswordDialog dlg(this,PasswordDialog::Mode_Change,PasswordDialog::Flag_None,filename);
964 if(dlg.exec()==PasswordDialog::Exit_Ok){
965 db->setKey(dlg.password(),dlg.keyFile());
966 db->generateMasterKey();
967 setStateFileModified(true);
971 void KeepassMainWindow::OnFileExit(){
976 void KeepassMainWindow::OnExport(QAction* action){
977 dynamic_cast<IExport*>(action->data().value<QObject*>())->exportDatabase(this,db);
980 void KeepassMainWindow::OnImport(QAction* action){
982 if(!closeDatabase())return;
983 IDatabase* tmpdb=dynamic_cast<IDatabase*>(new Kdb3Database());
985 if(dynamic_cast<IImport*>(action->data().value<QObject*>())->importDatabase(this,tmpdb)){
986 PasswordDialog dlg(this,PasswordDialog::Mode_Set,PasswordDialog::Flag_None,QString());
987 if(dlg.exec()!=PasswordDialog::Exit_Ok){
992 db->setKey(dlg.password(),dlg.keyFile());
993 db->generateMasterKey();
996 setupDatabaseConnections(db);
997 GroupView->createItems();
998 EntryView->showGroup(NULL);
999 setStateFileOpen(true);
1000 setStateFileModified(true);
1007 void KeepassMainWindow::removeFromSearchResults(int id){
1008 for(int i=0; i<SearchResults.size();i++){
1009 if(SearchResults[i]==id){
1010 SearchResults.removeAt(i);
1017 void KeepassMainWindow::search(IGroupHandle* group){
1018 SearchDialog dlg(db,group,this);
1020 EntryView->SearchResults=dlg.Result;
1021 GroupView->showSearchResults();
1025 void KeepassMainWindow::OnSearch(){
1029 void KeepassMainWindow::OnGroupSearch(){
1030 Q_ASSERT(GroupView->currentItem());
1031 search(((GroupViewItem*)GroupView->currentItem())->GroupHandle);
1034 void KeepassMainWindow::OnQuickSearch(){
1035 EntryView->SearchResults=db->search(NULL,QuickSearchEdit->text(),false,false,false,NULL);
1036 GroupView->showSearchResults();
1039 void KeepassMainWindow::OnColumnVisibilityChanged(){
1040 EntryView->setColumnVisible(0, ViewColumnsTitleAction->isChecked());
1041 EntryView->setColumnVisible(1, ViewColumnsUsernameAction->isChecked());
1042 EntryView->setColumnVisible(2, ViewColumnsUrlAction->isChecked());
1043 EntryView->setColumnVisible(3, ViewColumnsPasswordAction->isChecked());
1044 EntryView->setColumnVisible(4, ViewColumnsCommentAction->isChecked());
1045 EntryView->setColumnVisible(5, ViewColumnsExpireAction->isChecked());
1046 EntryView->setColumnVisible(6, ViewColumnsCreationAction->isChecked());
1047 EntryView->setColumnVisible(7, ViewColumnsLastChangeAction->isChecked());
1048 EntryView->setColumnVisible(8, ViewColumnsLastAccessAction->isChecked());
1049 EntryView->setColumnVisible(9, ViewColumnsAttachmentAction->isChecked());
1050 EntryView->setColumnVisible(10, ViewColumnsGroupAction->isVisible() && ViewColumnsGroupAction->isChecked());
1053 void KeepassMainWindow::OnUsernPasswVisibilityChanged(){
1054 config->setHidePasswords(ViewHidePasswordsAction->isChecked());
1055 config->setHideUsernames(ViewHideUsernamesAction->isChecked());
1056 EntryView->refreshItems();
1059 void KeepassMainWindow::OnFileModified(){
1060 setStateFileModified(true);
1063 void KeepassMainWindow::closeEvent(QCloseEvent* e){
1064 if(FileOpen && !closeDatabase()){
1073 #ifdef GLOBAL_AUTOTYPE
1074 autoType->unregisterGlobalShortcut();
1077 config->setMainWindowGeometry(saveGeometry());
1078 // workaround if window has never been visible
1079 if (isVisible() || VSplitter->sizes()[0]!=VSplitter->sizes()[1])
1080 config->setVSplitterPos(VSplitter->saveState());
1081 if (config->showEntryDetails())
1082 config->setHSplitterPos(HSplitter->saveState());
1083 config->setShowStatusbar(statusBar()->isVisible());
1086 QMainWindow::closeEvent(e);
1087 QApplication::quit();
1090 void KeepassMainWindow::hideEvent(QHideEvent* event){
1091 if (event->spontaneous() && QApplication::activeModalWidget()==NULL){
1092 if (config->lockOnMinimize() && !IsLocked && FileOpen)
1093 OnUnLockWorkspace();
1094 if (config->showSysTrayIcon() && config->minimizeTray()){
1096 QTimer::singleShot(100, this, SLOT(hide()));
1105 QMainWindow::hideEvent(event);
1108 void KeepassMainWindow::showEvent(QShowEvent* event){
1109 if (IsLocked && !InUnLock && event->spontaneous()){
1111 showNormal(); // workaround for some graphic glitches
1113 OnUnLockWorkspace();
1116 QMainWindow::showEvent(event);
1119 void KeepassMainWindow::OnExtrasSettings(){
1120 QString oldLang = config->language();
1121 bool oldAlwaysOnTop = config->alwaysOnTop();
1122 CSettingsDlg dlg(this);
1124 if (config->language() != oldLang){
1125 retranslateUi(this);
1126 WorkspaceLockedWidget.retranslateUi(LockedCentralWidget);
1127 ViewShowToolbarAction->setText(tr("Show &Toolbar"));
1128 EntryView->retranslateColumns();
1129 GroupView->retranslateUi();
1130 updateWindowTitle();
1131 updateTrayTooltip();
1132 setStatusBarMsg(statusbarState);
1135 EntryView->setAlternatingRowColors(config->alternatingRowColors());
1136 SysTray->setVisible(config->showSysTrayIcon());
1137 menuBookmarks->menuAction()->setVisible(config->featureBookmarks());
1139 if (config->alwaysOnTop() != oldAlwaysOnTop) {
1140 if (config->alwaysOnTop())
1141 setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
1143 setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
1148 EventOccurred = true;
1149 if (config->lockOnInactivity() && config->lockAfterSec()!=0 && !inactivityTimer->isActive()){
1150 inactivityCounter = 0;
1151 inactivityTimer->start();
1153 else if ((!config->lockOnInactivity() || config->lockAfterSec()==0) && inactivityTimer->isActive()){
1154 inactivityTimer->stop();
1158 void KeepassMainWindow::OnHelpAbout(){
1159 AboutDialog dlg(this);
1163 void KeepassMainWindow::OnHelpHandbook(){
1164 QPointer<HelpDlg> dlg = new HelpDlg(this);
1169 void KeepassMainWindow::OnViewShowToolbar(bool show){
1170 config->setShowToolbar(show);
1171 toolBar->setVisible(show);
1174 void KeepassMainWindow::OnViewShowEntryDetails(bool show){
1175 config->setShowEntryDetails(show);
1176 DetailView->setVisible(show);
1179 /*void KeepassMainWindow::OnItemExpanded(QTreeWidgetItem* item){
1180 //((GroupViewItem*)item)->pGroup->UI_ItemIsExpanded=true;
1183 void KeepassMainWindow::OnItemCollaped(QTreeWidgetItem* item){
1184 //((GroupViewItem*)item)->pGroup->UI_ItemIsExpanded=false;
1187 void KeepassMainWindow::OnGroupSelectionChanged(IGroupHandle* group){
1189 setStateGroupSelected(SINGLE);
1191 setStateGroupSelected(NONE);
1194 void KeepassMainWindow::OnEntryChanged(SelectionState Selection){
1196 setStateEntrySelected(Selection);
1199 void KeepassMainWindow::OnShowSearchResults(){
1200 setStateGroupSelected(SEARCHGROUP);
1204 void KeepassMainWindow::OnViewToolbarIconSize16(bool state){
1206 ViewToolButtonSize22Action->setChecked(false);
1207 ViewToolButtonSize28Action->setChecked(false);
1208 config->setToolbarIconSize(16);
1209 toolBar->setIconSize(QSize(16,16));
1212 void KeepassMainWindow::OnViewToolbarIconSize22(bool state){
1214 ViewToolButtonSize16Action->setChecked(false);
1215 ViewToolButtonSize28Action->setChecked(false);
1216 config->setToolbarIconSize(22);
1217 toolBar->setIconSize(QSize(22,22));
1220 void KeepassMainWindow::OnViewToolbarIconSize28(bool state){
1222 ViewToolButtonSize16Action->setChecked(false);
1223 ViewToolButtonSize22Action->setChecked(false);
1224 config->setToolbarIconSize(28);
1225 toolBar->setIconSize(QSize(28,28));
1228 void KeepassMainWindow::OnSysTrayActivated(QSystemTrayIcon::ActivationReason reason){
1229 if(reason!=QSystemTrayIcon::Context){
1231 if (unlockDlg!=NULL)
1232 unlockDlg->reject();
1233 else if (config->lockOnMinimize() && !IsLocked && FileOpen)
1234 OnUnLockWorkspace();
1239 QTimer::singleShot(100, this, SLOT(restoreWindow()));
1247 void KeepassMainWindow::restoreWindow(){
1251 OnUnLockWorkspace();
1254 void KeepassMainWindow::OnExtrasPasswordGen(){
1255 CGenPwDialog dlg(this,true);
1260 void KeepassMainWindow::saveLastFilename(const QString& filename){
1262 if(config->openLastFile()){
1263 if(config->saveRelativePaths()){
1264 QString Path=filename.left(filename.lastIndexOf("/"));
1265 Path=makePathRelative(Path,QDir::currentPath());
1266 config->setLastFile(Path+filename.right(filename.length()-filename.lastIndexOf("/")-1));
1269 config->setLastFile(filename);
1273 void KeepassMainWindow::OnExtrasShowExpiredEntries(){
1274 ExpiredEntriesDialog dlg(this,db,db->expiredEntries());
1275 if(dlg.exec()==QDialog::Accepted){
1276 GroupView->setCurrentGroup(dlg.SelectedEntry->group());
1277 EntryView->setCurrentEntry(dlg.SelectedEntry);
1283 /*void KeepassMainWindow::OnExtrasTrashCan(){
1284 TrashCanDialog dlg(this,db,db->expiredEntries());
1285 if(dlg.exec()==QDialog::Accepted){
1291 void KeepassMainWindow::OnDetailViewUrlClicked(const QUrl& url){
1292 openBrowser(url.toString());
1295 void KeepassMainWindow::OnUnLockWorkspace(){
1297 if (InUnLock) return;
1299 if ( openDatabase(currentFilePath,true) ){
1300 QTreeWidgetItem* item = GroupView->invisibleRootItem();
1301 if (lockGroup.size()>0){
1302 for (int i=0; i<lockGroup.size(); i++){
1303 item = item->child(lockGroup[i]);
1304 if (item==NULL) break;
1307 GroupView->setCurrentItem(item);
1314 QTreeWidgetItem* item = GroupView->currentItem();
1317 QTreeWidgetItem* parent = item->parent();
1318 if (parent==NULL && !root) {
1319 parent = GroupView->invisibleRootItem();
1323 lockGroup.prepend(parent->indexOfChild(item));
1327 if (closeDatabase(true)) {
1328 setStateFileModified(false);
1336 void KeepassMainWindow::OnLockClose(){
1338 setStateFileOpen(false);
1341 void KeepassMainWindow::setLock(){
1342 QuickSearchEdit->setEchoMode(QLineEdit::NoEcho);
1343 NormalCentralWidget->setVisible(false);
1344 NormalCentralWidget->setParent(NULL);
1345 setCentralWidget(LockedCentralWidget);
1346 LockedCentralWidget->setVisible(true);
1347 SysTray->setIcon(getIcon("keepassx_locked"));
1348 FileUnLockWorkspaceAction->setText(tr("Un&lock Workspace"));
1350 updateTrayTooltip();
1351 setStateFileOpen(false);
1354 void KeepassMainWindow::resetLock(){
1356 QuickSearchEdit->setText("");
1357 QuickSearchEdit->setEchoMode(QLineEdit::Normal);
1358 LockedCentralWidget->setVisible(false);
1359 LockedCentralWidget->setParent(NULL);
1360 setCentralWidget(NormalCentralWidget);
1361 NormalCentralWidget->setVisible(true);
1362 SysTray->setIcon(getIcon("keepassx"));
1363 FileUnLockWorkspaceAction->setText(tr("&Lock Workspace"));
1365 updateTrayTooltip();
1368 void KeepassMainWindow::OnInactivityTimer(){
1369 if (IsLocked || !FileOpen)
1372 if (QApplication::activeModalWidget()!=NULL || EventOccurredBlock){
1373 inactivityCounter = 0;
1378 inactivityCounter = 0;
1379 EventOccurred = false;
1382 inactivityCounter++;
1383 if (inactivityCounter*(inactivityTimer->interval()) >= config->lockAfterSec()*1000){
1384 QWidget* popUpWidget = QApplication::activePopupWidget();
1385 if (popUpWidget!=NULL)
1386 popUpWidget->hide();
1387 OnUnLockWorkspace();
1392 void KeepassMainWindow::OnShutdown(QSessionManager& manager) {
1393 /* QApplication::commitData() only closes visible windows,
1394 so we need to manually close mainwindow if it's hidden */
1395 if (manager.allowsInteraction() && !isVisible()) {
1400 void KeepassMainWindow::OnBookmarkTriggered(QAction* action){
1401 if(action==AddBookmarkAction){
1402 AddBookmarkDlg dlg(this);
1405 QAction* action=new QAction(this);
1406 action->setData(id);
1407 action->setText(KpxBookmarks::title(id));
1408 action->setIcon(getIcon("document"));
1409 menuBookmarks->addAction(action);
1412 else if(action==ManageBookmarksAction){
1413 ManageBookmarksDlg dlg(this);
1415 menuBookmarks->clear();
1416 createBookmarkActions();
1418 else if(action==AddThisAsBookmarkAction){
1419 AddBookmarkDlg dlg(this,db->file()->fileName());
1422 QAction* action=new QAction(this);
1423 action->setData(id);
1424 action->setText(KpxBookmarks::title(id));
1425 action->setIcon(getIcon("document"));
1426 menuBookmarks->addAction(action);
1430 openDatabase(KpxBookmarks::path(action->data().toInt()));
1434 void KeepassMainWindow::createBookmarkActions(){
1435 menuBookmarks->addAction(AddBookmarkAction);
1436 menuBookmarks->addAction(AddThisAsBookmarkAction);
1437 menuBookmarks->addAction(ManageBookmarksAction);
1438 menuBookmarks->addSeparator();
1439 for(int i=0;i<KpxBookmarks::count();i++){
1440 QAction* action=new QAction(this);
1442 action->setText(KpxBookmarks::title(i));
1443 action->setIcon(getIcon("document"));
1444 menuBookmarks->addAction(action);
1448 void KeepassMainWindow::setStatusBarMsg(StatusBarMsg statusBarMsg) {
1451 switch (statusBarMsg) {
1452 case StatusBarReady:
1455 case StatusBarLoading:
1456 text = tr("Loading Database...");
1458 case StatusBarLoadingFailed:
1459 text = tr("Loading Failed");
1461 case StatusBarReadOnlyLock:
1462 text = tr("Couldn't create lock file. Opening the database read-only.");
1466 statusbarState = statusBarMsg;
1467 StatusBarGeneral->setText(text);
1470 void KeepassMainWindow::updateWindowTitle() {
1471 if (!IsLocked && !FileOpen)
1472 setWindowTitle( QString("%1 - %2").arg(APP_DISPLAY_NAME, APP_SHORT_FUNC) );
1473 else if (currentFilePath.isEmpty())
1474 setWindowTitle( QString("[%1][*] - %2").arg(tr("new"), APP_DISPLAY_NAME) );
1476 setWindowTitle( QString("%1 (%2) - %3").arg(currentFilePath, tr("locked"), APP_DISPLAY_NAME) );
1478 setWindowTitle( QString("%1[*] - %2").arg(currentFilePath, APP_DISPLAY_NAME) );
1480 setWindowTitle( QString("%1 - %2").arg(currentFilePath, APP_DISPLAY_NAME) );
1483 void KeepassMainWindow::updateTrayTooltip() {
1484 if (!IsLocked && !FileOpen)
1485 SysTray->setToolTip(QString("%1 - %2").arg(APP_DISPLAY_NAME, APP_SHORT_FUNC));
1487 QString tooltip = QString("%1 - %2").arg(APP_DISPLAY_NAME, currentFilePath.isEmpty()
1488 ? QString("[%1]").arg(tr("new")) : currentFileName);
1490 tooltip.append( QString(" (%1)").arg(tr("locked")) );
1491 SysTray->setToolTip(tooltip);
1495 void KeepassMainWindow::updateCurrentFile(const QString& filePath) {
1496 currentFilePath = filePath;
1497 currentFileName = QFileInfo(filePath).fileName();