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){
62 setUnifiedTitleAndToolBarOnMac(true);
67 #ifdef GLOBAL_AUTOTYPE
68 autoType->registerGlobalShortcut(config->globalShortcut());
70 setWindowModified(false);
71 QByteArray windowGeo = config->mainWindowGeometry();
72 if (!windowGeo.isEmpty())
73 restoreGeometry(windowGeo);
74 VSplitter->restoreState(config->vSplitterPos());
75 HSplitter->restoreState(config->hSplitterPos());
76 SysTray=new QSystemTrayIcon(this);
79 setStateFileOpen(false);
81 DetailView->setVisible(config->showEntryDetails());
82 StatusBarGeneral=new QLabel(statusBar());
83 //StatusBarSelection=new QLabel(statusBar());
84 statusBar()->addWidget(StatusBarGeneral,15);
85 //statusBar()->addWidget(StatusBarSelection,85);
86 statusBar()->setVisible(config->showStatusbar());
87 setStatusBarMsg(StatusBarReady);
89 if (config->alwaysOnTop())
90 setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
93 NormalCentralWidget=QMainWindow::centralWidget();
94 LockedCentralWidget=new QWidget(this);
95 WorkspaceLockedWidget.setupUi(LockedCentralWidget);
96 LockedCentralWidget->setVisible(false);
99 connect(qApp, SIGNAL(commitDataRequest(QSessionManager&)), SLOT(OnShutdown(QSessionManager&)));
101 inactivityTimer = new QTimer(this);
102 inactivityTimer->setInterval(500);
103 connect(inactivityTimer, SIGNAL(timeout()), SLOT(OnInactivityTimer()));
104 if (config->lockOnInactivity() && config->lockAfterSec()!=0)
105 inactivityTimer->start();
107 bool showWindow = !ArgMin;
109 if(!ArgFile.isEmpty()){
110 QString f = QDir::cleanPath(QDir::current().absoluteFilePath(ArgFile));
114 openDatabase(f,false);
116 else if(config->openLastFile() && !config->lastFile().isEmpty()){
117 QFileInfo file(config->lastFile());
119 QString f = QDir::cleanPath(QDir::current().absoluteFilePath(config->lastFile()));
121 showWindow = !config->startMinimized();
122 if (ArgLock || config->startLocked())
125 openDatabase(f,true);
128 config->setLastFile(QString());
132 /*HelpBrowser = new QAssistantClient(QString(),this);
133 HelpBrowser->setArguments(QStringList()<< "-profile" << "share/keepass/doc/keepassx.adp");*/
135 createBookmarkActions();
139 else if (!config->showSysTrayIcon())
143 void KeepassMainWindow::setupConnections(){
144 connect(FileNewAction, SIGNAL(triggered()), this, SLOT(OnFileNewKdb()));
145 connect(FileOpenAction, SIGNAL(triggered()), this, SLOT(OnFileOpen()));
146 connect(FileCloseAction, SIGNAL(triggered()), this, SLOT(OnFileClose()));
147 connect(FileSaveAction, SIGNAL(triggered()), this, SLOT(OnFileSave()));
148 connect(FileSaveAsAction, SIGNAL(triggered()), this, SLOT(OnFileSaveAs()));
149 connect(FileSettingsAction, SIGNAL(triggered()), this, SLOT(OnFileSettings()));
150 connect(FileChangeKeyAction, SIGNAL(triggered()), this, SLOT(OnFileChangeKey()));
151 connect(FileExitAction, SIGNAL(triggered()), this, SLOT(OnFileExit()));
152 connect(FileUnLockWorkspaceAction,SIGNAL(triggered()), this, SLOT(OnUnLockWorkspace()));
153 connect(menuImport,SIGNAL(triggered(QAction*)),this,SLOT(OnImport(QAction*)));
154 connect(menuExport,SIGNAL(triggered(QAction*)),this,SLOT(OnExport(QAction*)));
155 connect(menuBookmarks,SIGNAL(triggered(QAction*)),this,SLOT(OnBookmarkTriggered(QAction*)));
157 connect(EditNewGroupAction, SIGNAL(triggered()), GroupView, SLOT(OnNewGroup()));
158 connect(EditNewSubgroupAction, SIGNAL(triggered()), GroupView, SLOT(OnNewSubgroup()));
159 connect(EditEditGroupAction, SIGNAL(triggered()), GroupView, SLOT(OnEditGroup()));
160 connect(EditDeleteGroupAction, SIGNAL(triggered()), GroupView, SLOT(OnDeleteGroup()));
161 connect(EditGroupSortAction, SIGNAL(triggered()), GroupView, SLOT(OnSort()));
162 connect(EditNewEntryAction, SIGNAL(triggered()), EntryView, SLOT(OnNewEntry()));
163 connect(EditEditEntryAction, SIGNAL(triggered()), EntryView, SLOT(OnEditEntry()));
164 connect(EntryView, SIGNAL(requestCreateGroup(QString,quint32,GroupViewItem*)),
165 GroupView, SLOT(createGroup(QString,quint32,GroupViewItem*)));
166 connect(EditCloneEntryAction, SIGNAL(triggered()), EntryView, SLOT(OnCloneEntry()));
167 connect(EditDeleteEntryAction, SIGNAL(triggered()), EntryView, SLOT(OnDeleteEntry()));
168 connect(EditUsernameToClipboardAction, SIGNAL(triggered()), EntryView, SLOT(OnUsernameToClipboard()));
169 connect(EditPasswordToClipboardAction, SIGNAL(triggered()), EntryView, SLOT(OnPasswordToClipboard()));
170 connect(EditOpenUrlAction, SIGNAL(triggered()), EntryView, SLOT(OnEditOpenUrl()));
171 connect(EditCopyUrlAction, SIGNAL(triggered()), EntryView, SLOT(OnEditCopyUrl()));
172 connect(EditSaveAttachmentAction, SIGNAL(triggered()),EntryView, SLOT(OnSaveAttachment()));
173 connect(EditSearchAction, SIGNAL(triggered()), this, SLOT(OnSearch()));
174 connect(EditGroupSearchAction, SIGNAL(triggered()), this, SLOT(OnGroupSearch()));
176 connect(EditAutoTypeAction,SIGNAL(triggered()),EntryView,SLOT(OnAutoType()));
179 connect(ViewShowToolbarAction,SIGNAL(toggled(bool)),this,SLOT(OnViewShowToolbar(bool)));
180 connect(ViewShowEntryDetailsAction,SIGNAL(toggled(bool)),this,SLOT(OnViewShowEntryDetails(bool)));
181 connect(ViewHidePasswordsAction,SIGNAL(toggled(bool)), this, SLOT(OnUsernPasswVisibilityChanged()));
182 connect(ViewHideUsernamesAction,SIGNAL(toggled(bool)), this, SLOT(OnUsernPasswVisibilityChanged()));
184 connect(menuColumns,SIGNAL(triggered(QAction*)),this,SLOT(OnColumnVisibilityChanged()));
185 connect(ViewToolButtonSize16Action,SIGNAL(toggled(bool)), this, SLOT(OnViewToolbarIconSize16(bool)));
186 connect(ViewToolButtonSize22Action,SIGNAL(toggled(bool)), this, SLOT(OnViewToolbarIconSize22(bool)));
187 connect(ViewToolButtonSize28Action,SIGNAL(toggled(bool)), this, SLOT(OnViewToolbarIconSize28(bool)));
188 connect(ViewShowStatusbarAction,SIGNAL(toggled(bool)),statusBar(),SLOT(setVisible(bool)));
190 connect(ViewMinimizeAction, SIGNAL(triggered()), SLOT(showMinimized()));
193 connect(ExtrasSettingsAction,SIGNAL(triggered(bool)),this,SLOT(OnExtrasSettings()));
194 connect(ExtrasPasswordGenAction,SIGNAL(triggered(bool)),this,SLOT(OnExtrasPasswordGen()));
195 connect(ExtrasShowExpiredEntriesAction,SIGNAL(triggered(bool)),this,SLOT(OnExtrasShowExpiredEntries()));
196 //connect(ExtrasTrashCanAction,SIGNAL(triggered(bool)),this,SLOT(OnExtrasTrashCan())); //TODO ExtrasTrashCan
198 connect(HelpHandbookAction,SIGNAL(triggered()),this,SLOT(OnHelpHandbook()));
199 connect(HelpAboutAction,SIGNAL(triggered()),this,SLOT(OnHelpAbout()));
201 connect(QuickSearchEdit,SIGNAL(returnPressed()), this, SLOT(OnQuickSearch()));
202 connect(GroupView,SIGNAL(groupChanged(IGroupHandle*)),EntryView,SLOT(OnGroupChanged(IGroupHandle*)));
203 connect(GroupView,SIGNAL(groupChanged(IGroupHandle*)),this,SLOT(OnGroupSelectionChanged(IGroupHandle*)));
204 connect(GroupView,SIGNAL(fileModified()),this,SLOT(OnFileModified()));
205 connect(EntryView,SIGNAL(fileModified()),this,SLOT(OnFileModified()));
206 connect(EntryView,SIGNAL(selectionChanged(SelectionState)),this,SLOT(OnEntryChanged(SelectionState)));
207 connect(GroupView,SIGNAL(searchResultsSelected()),EntryView,SLOT(OnShowSearchResults()));
208 connect(GroupView,SIGNAL(searchResultsSelected()),this,SLOT(OnShowSearchResults()));
209 connect(GroupView,SIGNAL(entriesDropped()),EntryView,SLOT(removeDragItems()));
210 connect(HideSearchResultsAction,SIGNAL(triggered()),GroupView,SLOT(OnHideSearchResults()));
211 connect(EntryView, SIGNAL(viewModeChanged(bool)), SLOT(loadColumnVisibility()));
212 connect(EntryView, SIGNAL(viewModeChanged(bool)), ViewColumnsGroupAction, SLOT(setVisible(bool)));
214 connect(SysTray,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),this,SLOT(OnSysTrayActivated(QSystemTrayIcon::ActivationReason)));
215 connect(DetailView,SIGNAL(anchorClicked(const QUrl&)),this,SLOT(OnDetailViewUrlClicked(const QUrl&)));
216 connect(WorkspaceLockedWidget.Button_Unlock,SIGNAL(clicked()),this,SLOT(OnUnLockWorkspace()));
217 connect(WorkspaceLockedWidget.Button_CloseDatabase,SIGNAL(clicked()),this,SLOT(OnLockClose()));
220 void KeepassMainWindow::setupToolbar(){
221 toolBar=new QToolBar(this);
222 toolBar->setMovable(false);
224 toolBar->setIconSize(QSize(config->toolbarIconSize(),config->toolbarIconSize()));
225 ViewShowToolbarAction=toolBar->toggleViewAction();
226 toolBar->addAction(FileNewAction);
227 toolBar->addAction(FileOpenAction);
228 toolBar->addAction(FileSaveAction);
229 toolBar->addSeparator();
230 toolBar->addAction(EditNewEntryAction);
231 toolBar->addAction(EditEditEntryAction);
232 toolBar->addAction(EditDeleteEntryAction);
233 toolBar->addSeparator();
234 toolBar->addAction(EditUsernameToClipboardAction);
235 toolBar->addAction(EditPasswordToClipboardAction);
236 toolBar->addSeparator();
237 toolBar->addAction(FileUnLockWorkspaceAction);
238 toolBar->addSeparator();
239 QuickSearchEdit=new QLineEdit(toolBar);
240 QuickSearchEdit->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
241 toolBar->addWidget(QuickSearchEdit);
242 toolBar->setVisible(config->showToolbar());
245 void KeepassMainWindow::setupIcons(){
246 setWindowIcon(getIcon("keepassx_small"));
247 FileNewAction->setIcon(getIcon("filenew"));
248 FileOpenAction->setIcon(getIcon("fileopen"));
249 FileSaveAction->setIcon(getIcon("filesave"));
250 FileSaveAsAction->setIcon(getIcon("filesaveas"));
251 FileCloseAction->setIcon(getIcon("fileclose"));
252 FileSettingsAction->setIcon(getIcon("dbsettings"));
253 FileUnLockWorkspaceAction->setIcon(getIcon("lock"));
254 FileExitAction->setIcon(getIcon("exit"));
255 EditNewEntryAction->setIcon(getIcon("newentry"));
256 EditEditEntryAction->setIcon(getIcon("editentry"));
257 EditDeleteEntryAction->setIcon(getIcon("deleteentry"));
258 EditGroupSortAction->setIcon(getIcon("swap"));
259 EditUsernameToClipboardAction->setIcon(getIcon("copyusername"));
260 EditPasswordToClipboardAction->setIcon(getIcon("copypwd"));
261 EditCloneEntryAction->setIcon(getIcon("cloneentry"));
262 EditOpenUrlAction->setIcon(getIcon("openurl"));
263 EditSaveAttachmentAction->setIcon(getIcon("filesave"));
264 EditNewGroupAction->setIcon(getIcon("newgroup"));
265 EditNewSubgroupAction->setIcon(getIcon("newgroup"));
266 EditEditGroupAction->setIcon(getIcon("editgroup"));
267 EditDeleteGroupAction->setIcon(getIcon("deletegroup"));
268 EditSearchAction->setIcon(getIcon("dbsearch"));
269 EditGroupSearchAction->setIcon(getIcon("groupsearch"));
270 ExtrasShowExpiredEntriesAction->setIcon(getIcon("expired"));
271 ExtrasPasswordGenAction->setIcon(getIcon("generator"));
272 //ExtrasTrashCanAction->setIcon(getIcon("trashcan")); //TODO ExtrasTrashCan
273 ExtrasSettingsAction->setIcon(getIcon("appsettings"));
275 EditAutoTypeAction->setIcon(getIcon("autotype"));
277 EditAutoTypeAction->setVisible(false);
279 HelpHandbookAction->setIcon(getIcon("manual"));
280 HelpAboutAction->setIcon(getIcon("help_about"));
281 menuBookmarks->menuAction()->setIcon(getIcon("bookmark_folder"));
282 AddThisAsBookmarkAction->setIcon(getIcon("bookmark_this"));
283 AddBookmarkAction->setIcon(getIcon("bookmark_add"));
284 ManageBookmarksAction->setIcon(getIcon("bookmark"));
285 SysTray->setIcon(getIcon("keepassx"));
286 if(config->showSysTrayIcon())
290 void KeepassMainWindow::setupMenus(){
291 GroupView->ContextMenu->addAction(EditNewSubgroupAction);
292 GroupView->ContextMenu->addAction(EditEditGroupAction);
293 GroupView->ContextMenu->addAction(EditDeleteGroupAction);
294 GroupView->ContextMenu->addAction(EditGroupSortAction);
295 GroupView->ContextMenu->addSeparator();
296 GroupView->ContextMenu->addAction(EditNewEntryAction);
297 GroupView->ContextMenu->addSeparator();
298 GroupView->ContextMenu->addAction(EditGroupSearchAction);
299 GroupView->ContextMenuSearchGroup->addAction(HideSearchResultsAction);
301 EntryView->ContextMenu->addAction(EditUsernameToClipboardAction);
302 EntryView->ContextMenu->addAction(EditPasswordToClipboardAction);
303 EntryView->ContextMenu->addAction(EditOpenUrlAction);
304 EntryView->ContextMenu->addAction(EditCopyUrlAction);
305 EntryView->ContextMenu->addAction(EditSaveAttachmentAction);
307 EntryView->ContextMenu->addAction(EditAutoTypeAction);
309 EntryView->ContextMenu->addSeparator();
310 EntryView->ContextMenu->addAction(EditNewEntryAction);
311 EntryView->ContextMenu->addAction(EditEditEntryAction);
312 EntryView->ContextMenu->addAction(EditCloneEntryAction);
313 EntryView->ContextMenu->addAction(EditDeleteEntryAction);
315 ViewShowToolbarAction->setText(tr("Show &Toolbar"));
316 ViewMenu->insertAction(ViewShowEntryDetailsAction,ViewShowToolbarAction);
317 ViewShowToolbarAction->setChecked(config->showToolbar());
318 ViewShowEntryDetailsAction->setChecked(config->showEntryDetails());
319 ViewHidePasswordsAction->setChecked(config->hidePasswords());
320 ViewHideUsernamesAction->setChecked(config->hideUsernames());
321 loadColumnVisibility();
322 ViewShowStatusbarAction->setChecked(config->showStatusbar());
324 switch(config->toolbarIconSize()){
325 case 16: ViewToolButtonSize16Action->setChecked(true); break;
326 case 22: ViewToolButtonSize22Action->setChecked(true); break;
327 case 28: ViewToolButtonSize28Action->setChecked(true); break;
331 ViewMenu->addSeparator();
332 ViewMenu->addAction(ViewMinimizeAction);
335 SysTrayMenu = new QMenu(APP_DISPLAY_NAME,this);
336 SysTrayMenu->addAction(FileUnLockWorkspaceAction);
337 SysTrayMenu->addSeparator();
338 SysTrayMenu->addAction(FileExitAction);
339 SysTray->setContextMenu(SysTrayMenu);
342 #define _add_import(name){\
343 QAction* import=new QAction(this);\
344 import->setData(qVariantFromValue(dynamic_cast<QObject*>(&name)));\
345 import->setText(name.title());\
346 menuImport->addAction(import);}
348 #define _add_export(name){\
349 QAction* Export=new QAction(this);\
350 Export->setData(qVariantFromValue(dynamic_cast<QObject*>(&name)));\
351 Export->setText(name.title());\
352 menuExport->addAction(Export);}
354 _add_import(import_KeePassX_Xml)
355 _add_import(import_PwManager)
356 _add_import(import_KWalletXml)
357 _add_export(export_Txt);
358 _add_export(export_KeePassX_Xml);
360 FileNewAction->setShortcut(tr("Ctrl+N"));
361 FileOpenAction->setShortcut(tr("Ctrl+O"));
362 FileCloseAction->setShortcut(tr("Ctrl+W"));
363 FileSaveAction->setShortcut(tr("Ctrl+S"));
364 FileUnLockWorkspaceAction->setShortcut(tr("Ctrl+L"));
365 FileExitAction->setShortcut(tr("Ctrl+Q"));
366 EditNewGroupAction->setShortcut(tr("Ctrl+G"));
367 EditPasswordToClipboardAction->setShortcut(tr("Ctrl+C"));
368 EditUsernameToClipboardAction->setShortcut(tr("Ctrl+B"));
369 EditOpenUrlAction->setShortcut(tr("Ctrl+U"));
370 EditCopyUrlAction->setShortcut(tr("Ctrl+I"));
371 EditNewEntryAction->setShortcut(tr("Ctrl+Y"));
372 EditEditEntryAction->setShortcut(tr("Ctrl+E"));
373 EditDeleteEntryAction->setShortcut(tr("Ctrl+D"));
374 EditCloneEntryAction->setShortcut(tr("Ctrl+K"));
375 EditSearchAction->setShortcut(tr("Ctrl+F"));
376 ExtrasPasswordGenAction->setShortcut(tr("Ctrl+P"));
377 ExtrasShowExpiredEntriesAction->setShortcut(tr("Ctrl+X"));
379 EditAutoTypeAction->setShortcut(tr("Ctrl+V"));
382 FileSaveAsAction->setShortcut(tr("Shift+Ctrl+S"));
383 EditGroupSearchAction->setShortcut(tr("Shift+Ctrl+F"));
384 ViewMinimizeAction->setShortcut(tr("Ctrl+M"));
387 //ExtrasTrashCanAction->setVisible(false); //TODO For KP 2.x only
388 menuBookmarks->menuAction()->setVisible(config->featureBookmarks());
391 void KeepassMainWindow::loadColumnVisibility() {
392 ViewColumnsTitleAction->setChecked(EntryView->columnVisible(0));
393 ViewColumnsUsernameAction->setChecked(EntryView->columnVisible(1));
394 ViewColumnsUrlAction->setChecked(EntryView->columnVisible(2));
395 ViewColumnsPasswordAction->setChecked(EntryView->columnVisible(3));
396 ViewColumnsCommentAction->setChecked(EntryView->columnVisible(4));
397 ViewColumnsExpireAction->setChecked(EntryView->columnVisible(5));
398 ViewColumnsCreationAction->setChecked(EntryView->columnVisible(6));
399 ViewColumnsLastChangeAction->setChecked(EntryView->columnVisible(7));
400 ViewColumnsLastAccessAction->setChecked(EntryView->columnVisible(8));
401 ViewColumnsAttachmentAction->setChecked(EntryView->columnVisible(9));
402 ViewColumnsGroupAction->setChecked(EntryView->columnVisible(10));
405 void KeepassMainWindow::setupDatabaseConnections(IDatabase* DB){
406 ICustomIcons* CustomIconsDb=dynamic_cast<ICustomIcons*>(DB);
408 connect(CustomIconsDb,SIGNAL(iconsModified()),this,SLOT(OnFileModified()));
409 connect(CustomIconsDb,SIGNAL(iconsModified()),EntryView,SLOT(updateIcons()));
410 connect(CustomIconsDb,SIGNAL(iconsModified()),GroupView,SLOT(updateIcons()));
415 bool KeepassMainWindow::openDatabase(QString filename,bool IsAuto){
416 if (!QFile::exists(filename)){
417 QMessageBox::critical(this, tr("Error"), tr("The database file does not exist."));
423 if (QFile::exists(filename+".lock")){
424 QMessageBox msgBox(this);
425 msgBox.setIcon(QMessageBox::Question);
426 msgBox.setWindowTitle(tr("Database locked"));
427 msgBox.setText(tr("The database you are trying to open is locked.\n"
428 "This means that either someone else has opened the file or KeePassX crashed last time it opened the database.\n\n"
429 "Do you want to open it anyway?"
431 msgBox.addButton(QMessageBox::Yes);
432 msgBox.addButton(QMessageBox::No);
433 QPushButton* readOnlyButton = new QPushButton(tr("Open read-only"), &msgBox);
434 msgBox.addButton(readOnlyButton, QMessageBox::AcceptRole);
435 msgBox.setDefaultButton(readOnlyButton);
438 if (!msgBox.clickedButton() || msgBox.clickedButton() == msgBox.button(QMessageBox::No))
440 else if (msgBox.clickedButton() == readOnlyButton)
445 config->setLastKeyLocation(QString());
446 config->setLastKeyType(PASSWORD);
448 db = new Kdb3Database();
449 PasswordDialog::DlgFlags flags=PasswordDialog::Flag_None;
451 flags = PasswordDialog::Flag_Auto;
452 PasswordDialog dlg(this,PasswordDialog::Mode_Ask,flags,filename);
454 dlg.setWindowModality(Qt::WindowModal);
457 bool rejected = (dlg.exec()==PasswordDialog::Exit_Cancel);
463 if(dlg.selectedBookmark()!=QString())
464 filename=dlg.selectedBookmark();
468 setupDatabaseConnections(db);
470 setStatusBarMsg(StatusBarLoading);
471 db->setKey(dlg.password(),dlg.keyFile());
473 if (!dbReadOnly && !QFile::exists(filename+".lock")){
474 QFile lock(filename+".lock");
475 if (!lock.open(QIODevice::WriteOnly)){
476 setStatusBarMsg(StatusBarReadOnlyLock);
481 if(db->load(filename, dbReadOnly)){
484 updateCurrentFile(filename);
485 saveLastFilename(filename);
486 GroupView->createItems();
487 EntryView->showGroup(NULL);
488 setStateFileOpen(true);
489 setStateFileModified(static_cast<Kdb3Database*>(db)->hasPasswordEncodingChanged());
492 if (!dbReadOnly && QFile::exists(filename+".lock"))
493 QFile::remove(filename+".lock");
494 setStatusBarMsg(StatusBarLoadingFailed);
495 QString error=db->getError();
496 if(error.isEmpty())error=tr("Unknown error while loading database.");
497 QMessageBox::critical(this,tr("Error"),
498 QString("%1\n%2").arg(tr("The following error occured while opening the database:"))
500 if(db->isKeyError()){
502 return openDatabase(filename,IsAuto);
509 if (statusbarState != StatusBarReadOnlyLock)
510 setStatusBarMsg(StatusBarReady);
511 inactivityCounter = 0;
513 GroupView->selectFirstGroup();
518 void KeepassMainWindow::fakeOpenDatabase(const QString& filename){
519 if (!QFile::exists(filename)){
520 QMessageBox::critical(this, tr("Error"), tr("The database file does not exist."));
524 config->setLastFile(filename);
525 updateCurrentFile(filename);
529 bool KeepassMainWindow::closeDatabase(bool lock){
533 if(config->autoSave() && db->file()){
534 if(!OnFileSave()) return false;
537 QMessageBox::StandardButton r=QMessageBox::question(this,tr("Save modified file?"),
538 tr("The current file was modified.\nDo you want to save the changes?"),
539 QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel, QMessageBox::Yes);
540 if(r==QMessageBox::Cancel) return false; //Cancel
541 if(r==QMessageBox::Yes){ //Yes (Save file)
543 if(!OnFileSaveAs()) return false;
546 if(!OnFileSave()) return false;
554 if (!dbReadOnly && QFile::exists(currentFilePath+".lock")){
555 if (!QFile::remove(currentFilePath+".lock"))
556 QMessageBox::critical(this, tr("Error"), tr("Couldn't remove database lock file."));
560 EntryView->Items.clear();
563 GroupView->Items.clear();
564 SearchResults.clear();
567 setStateFileOpen(false);
569 updateCurrentFile(QString());
570 QuickSearchEdit->setText("");
577 void KeepassMainWindow::OnFileNewKdb(){
578 IDatabase* db_new=dynamic_cast<IDatabase*>(new Kdb3Database());
580 PasswordDialog dlg(this,PasswordDialog::Mode_Set,PasswordDialog::Flag_None,"New Database");
581 if(dlg.exec()==PasswordDialog::Exit_Ok){
583 if(!closeDatabase())return;
587 db->setKey(dlg.password(),dlg.keyFile());
588 db->generateMasterKey();
589 updateCurrentFile(QString());
592 GroupView->createItems();
593 EntryView->showGroup(NULL);
594 setStateFileOpen(true);
595 setStateFileModified(true);
596 setupDatabaseConnections(db);
597 setStateGroupSelected(NONE);
598 setStateEntrySelected(NONE);
599 GroupView->createGroup("Internet", 1);
600 GroupView->createGroup("eMail", 19);
607 void KeepassMainWindow::openFile(const QString& filename) {
612 openDatabase(filename);
615 void KeepassMainWindow::OnFileOpen(){
616 /*QFileDialog FileDlg(this,tr("Open Database..."),QDir::homePath());
617 FileDlg.setFilters(QStringList()<< tr("KeePass Databases (*.kdb)")<< tr("All Files (*)"));
618 FileDlg.setFileMode(QFileDialog::ExistingFile);
619 FileDlg.setAcceptMode(QFileDialog::AcceptOpen);
620 if(!FileDlg.exec())return;
621 if(!FileDlg.selectedFiles().size())return;*/
622 QString filename=KpxFileDialogs::openExistingFile(this,"MainWindow_FileOpen",
623 tr("Open Database..."),QStringList()<<tr("KeePass Databases (*.kdb)")<< tr("All Files (*)"));
624 if (!filename.isEmpty())
628 void KeepassMainWindow::OnFileClose(){
635 void KeepassMainWindow::setStateFileOpen(bool IsOpen){
637 FileSaveAction->setEnabled(IsOpen);
638 FileSaveAsAction->setEnabled(IsOpen);
639 FileCloseAction->setEnabled(IsOpen||IsLocked);
640 FileSettingsAction->setEnabled(IsOpen);
641 FileChangeKeyAction->setEnabled(IsOpen);
642 menuExport->setEnabled(IsOpen);
643 EditNewGroupAction->setEnabled(IsOpen);
644 EditSearchAction->setEnabled(IsOpen);
645 GroupView->setEnabled(IsOpen);
646 EntryView->setEnabled(IsOpen);
647 DetailView->setEnabled(IsOpen);
648 QuickSearchEdit->setEnabled(IsOpen);
649 ExtrasShowExpiredEntriesAction->setEnabled(IsOpen);
650 AddThisAsBookmarkAction->setEnabled(IsOpen && db->file());
651 FileUnLockWorkspaceAction->setEnabled(IsOpen||IsLocked);
654 EditNewSubgroupAction->setEnabled(false);
655 EditEditGroupAction->setEnabled(false);
656 EditDeleteGroupAction->setEnabled(false);
657 EditPasswordToClipboardAction->setEnabled(false);
658 EditUsernameToClipboardAction->setEnabled(false);
659 EditOpenUrlAction->setEnabled(false);
660 EditCopyUrlAction->setEnabled(false);
661 EditSaveAttachmentAction->setEnabled(false);
662 EditNewEntryAction->setEnabled(false);
663 EditEditEntryAction->setEnabled(false);
664 EditCloneEntryAction->setEnabled(false);
665 EditDeleteEntryAction->setEnabled(false);
666 EditGroupSearchAction->setEnabled(false);
668 EditAutoTypeAction->setEnabled(false);
677 void KeepassMainWindow::setStateFileModified(bool mod){
678 if (config->autoSaveChange() && mod && db->file()){
680 return; // return on success, so we don't set the state to modified
685 FileSaveAction->setIcon(getIcon("filesave"));
687 FileSaveAction->setIcon(getIcon("filesavedisabled"));
689 setWindowModified(mod);
692 void KeepassMainWindow::setStateGroupSelected(SelectionState s){
694 switch(GroupSelection){
696 EditNewSubgroupAction->setEnabled(false);
697 EditEditGroupAction->setEnabled(false);
698 EditDeleteGroupAction->setEnabled(false);
699 EditGroupSearchAction->setEnabled(false);
700 EditNewEntryAction->setEnabled(false);
703 EditNewSubgroupAction->setEnabled(true);
704 EditEditGroupAction->setEnabled(true);
705 EditDeleteGroupAction->setEnabled(true);
706 EditGroupSearchAction->setEnabled(true);
707 EditNewEntryAction->setEnabled(true);
710 EditNewSubgroupAction->setEnabled(false);
711 EditEditGroupAction->setEnabled(false);
712 EditDeleteGroupAction->setEnabled(false);
713 EditGroupSearchAction->setEnabled(false);
714 EditNewEntryAction->setEnabled(false);
716 default: Q_ASSERT(false);
720 void KeepassMainWindow::updateDetailView(){
721 if(EntryView->selectedItems().size()!=1){
722 DetailView->setPlainText("");
726 QString templ=DetailViewTemplate;
727 IEntryHandle* entry=((EntryViewItem*)(EntryView->selectedItems()[0]))->EntryHandle;
729 templ.replace("%group%", Qt::escape(entry->group()->title()));
730 templ.replace("%title%", Qt::escape(entry->title()));
731 if (config->hideUsernames())
732 templ.replace("%username%","****");
734 templ.replace("%username%", Qt::escape(entry->username()));
735 if (!config->hidePasswords()) {
736 SecString password=entry->password();
738 templ.replace("%password%", Qt::escape(password.string()));
741 templ.replace("%password%","****");
743 templ.replace("%url%", Qt::escape(entry->url()));
744 templ.replace("%creation%", Qt::escape(entry->creation().toString(Qt::SystemLocaleDate)));
745 templ.replace("%lastmod%", Qt::escape(entry->lastMod().toString(Qt::SystemLocaleDate)));
746 templ.replace("%lastaccess%", Qt::escape(entry->lastAccess().toString(Qt::SystemLocaleDate)));
747 templ.replace("%expire%", Qt::escape(entry->expire().toString(Qt::SystemLocaleDate)));
748 templ.replace("%comment%", Qt::escape(entry->comment()).replace("\n","<br/>"));
749 templ.replace("%attachment%", Qt::escape(entry->binaryDesc()));
751 if(entry->expire()!=Date_Never){
752 int secs=QDateTime::currentDateTime().secsTo(entry->expire());
754 templ.replace("%expire-timeleft%",tr("Expired"));
759 years=secs/(86400*365);
760 secs-=years*(86400*365);
761 months=secs/(86400*30);
762 secs-=months*(86400*30);
770 out=tr("%1 Months").arg(months);
776 out.prepend(tr("1 Year"));
778 out.prepend(tr("%1 Years").arg(years));
784 out.append(tr("1 Day"));
786 out.append(tr("%1 Days").arg(days));
789 if(!days && !years && !months)
790 out=tr("less than 1 day");
792 templ.replace("%expire-timeleft%","in " + out);
796 templ.replace("%expire-timeleft%","-");
798 DetailView->setHtml(templ);
802 void KeepassMainWindow::setStateEntrySelected(SelectionState s){
804 if (GroupSelection == NONE || GroupSelection == SINGLE){
805 switch (EntrySelection){
807 EditPasswordToClipboardAction->setEnabled(false);
808 EditUsernameToClipboardAction->setEnabled(false);
809 EditOpenUrlAction->setEnabled(false);
810 EditCopyUrlAction->setEnabled(false);
811 EditSaveAttachmentAction->setEnabled(false);
812 EditEditEntryAction->setEnabled(false);
813 EditCloneEntryAction->setEnabled(false);
814 EditCloneEntryAction->setText(tr("Clone Entry"));
815 EditDeleteEntryAction->setEnabled(false);
816 EditDeleteEntryAction->setText(tr("Delete Entry"));
818 EditAutoTypeAction->setEnabled(false);
822 EditPasswordToClipboardAction->setEnabled(true);
823 EditUsernameToClipboardAction->setEnabled(true);
824 EditOpenUrlAction->setEnabled(true);
825 EditCopyUrlAction->setEnabled(true);
826 EditSaveAttachmentAction->setEnabled(((EntryViewItem*)(EntryView->selectedItems()[0]))->EntryHandle->binarySize() > 0);
827 EditEditEntryAction->setEnabled(true);
828 EditCloneEntryAction->setEnabled(true);
829 EditCloneEntryAction->setText(tr("Clone Entry"));
830 EditDeleteEntryAction->setEnabled(true);
831 EditDeleteEntryAction->setText(tr("Delete Entry"));
833 EditAutoTypeAction->setEnabled(true);
837 EditPasswordToClipboardAction->setEnabled(false);
838 EditUsernameToClipboardAction->setEnabled(false);
839 EditOpenUrlAction->setEnabled(false);
840 EditCopyUrlAction->setEnabled(false);
841 EditSaveAttachmentAction->setEnabled(false);
842 EditEditEntryAction->setEnabled(false);
843 EditCloneEntryAction->setEnabled(true);
844 EditCloneEntryAction->setText(tr("Clone Entries"));
845 EditDeleteEntryAction->setEnabled(true);
846 EditDeleteEntryAction->setText(tr("Delete Entries"));
848 EditAutoTypeAction->setEnabled(false);
855 else if (GroupSelection == SEARCHGROUP){
856 switch(EntrySelection){
858 EditUsernameToClipboardAction->setEnabled(false);
859 EditPasswordToClipboardAction->setEnabled(false);
860 EditOpenUrlAction->setEnabled(false);
861 EditCopyUrlAction->setEnabled(false);
862 EditSaveAttachmentAction->setEnabled(false);
863 EditEditEntryAction->setEnabled(false);
864 EditCloneEntryAction->setEnabled(false);
865 EditCloneEntryAction->setText(tr("Clone Entry"));
866 EditDeleteEntryAction->setEnabled(false);
867 EditDeleteEntryAction->setText(tr("Delete Entry"));
869 EditAutoTypeAction->setEnabled(false);
873 EditUsernameToClipboardAction->setEnabled(true);
874 EditPasswordToClipboardAction->setEnabled(true);
875 EditOpenUrlAction->setEnabled(true);
876 EditCopyUrlAction->setEnabled(true);
877 EditSaveAttachmentAction->setEnabled(((EntryViewItem*)(EntryView->selectedItems()[0]))->EntryHandle->binarySize() > 0);
878 EditEditEntryAction->setEnabled(true);
879 EditCloneEntryAction->setEnabled(false);
880 EditCloneEntryAction->setText(tr("Clone Entry"));
881 EditDeleteEntryAction->setEnabled(true);
882 EditDeleteEntryAction->setText(tr("Delete Entry"));
884 EditAutoTypeAction->setEnabled(true);
888 EditUsernameToClipboardAction->setEnabled(false);
889 EditPasswordToClipboardAction->setEnabled(false);
890 EditOpenUrlAction->setEnabled(false);
891 EditCopyUrlAction->setEnabled(false);
892 EditSaveAttachmentAction->setEnabled(false);
893 EditEditEntryAction->setEnabled(false);
894 EditCloneEntryAction->setEnabled(false);
895 EditCloneEntryAction->setText(tr("Clone Entries"));
896 EditDeleteEntryAction->setEnabled(true);
897 EditDeleteEntryAction->setText(tr("Delete Entries"));
899 EditAutoTypeAction->setEnabled(false);
911 bool KeepassMainWindow::OnFileSave(){
913 return OnFileSaveAs();
914 saveLastFilename(db->file()->fileName());
916 setStateFileOpen(true); // necessary for AddThisAsBookmarkAction
917 setStateFileModified(false);
918 if (config->backup() && config->backupDelete() && config->backupDeleteAfter()>0){
919 IGroupHandle* backupGroup = db->backupGroup();
920 if (backupGroup && backupGroup==EntryView->getCurrentGroup())
921 EntryView->showGroup(backupGroup);
926 showErrMsg(QString("%1\n%2").arg(tr("File could not be saved.")).arg(db->getError()));
931 bool KeepassMainWindow::OnFileSaveAs(){
932 QString filename=KpxFileDialogs::saveFile(this,"MainWindow_FileSave",
933 tr("Save Database..."),QStringList()<<tr("KeePass Databases (*.kdb)")<< tr("All Files (*)"));
934 if (filename.isEmpty() || filename.compare(".kdb", Qt::CaseInsensitive)==0)
937 QFile lock(filename+".lock");
938 if (!lock.open(QIODevice::WriteOnly)){
939 QMessageBox::critical(this, tr("Error"), tr("Couldn't create database lock file."));
943 if(!db->changeFile(filename)){
944 showErrMsg(QString("%1\n%2").arg(tr("File could not be saved.")).arg(db->getError()));
945 QFile::remove( filename+".lock" );
949 if (!dbReadOnly && !currentFilePath.isEmpty() && QFile::exists(currentFilePath+".lock")){
950 if (!QFile::remove(currentFilePath+".lock"))
951 QMessageBox::critical(this, tr("Error"), tr("Couldn't remove database lock file."));
955 updateCurrentFile(filename);
962 void KeepassMainWindow::OnFileSettings(){
963 CDbSettingsDlg dlg(this,db);
965 db->generateMasterKey();
966 setStateFileModified(true);
970 void KeepassMainWindow::OnFileChangeKey(){
971 QFile* file=db->file();
972 QString filename = file ? file->fileName() : QString();
973 PasswordDialog dlg(this,PasswordDialog::Mode_Change,PasswordDialog::Flag_None,filename);
974 if(dlg.exec()==PasswordDialog::Exit_Ok){
975 db->setKey(dlg.password(),dlg.keyFile());
976 db->generateMasterKey();
977 setStateFileModified(true);
981 void KeepassMainWindow::OnFileExit(){
987 void KeepassMainWindow::OnExport(QAction* action){
988 dynamic_cast<IExport*>(action->data().value<QObject*>())->exportDatabase(this,db);
991 void KeepassMainWindow::OnImport(QAction* action){
993 if(!closeDatabase())return;
994 IDatabase* tmpdb=dynamic_cast<IDatabase*>(new Kdb3Database());
996 if(dynamic_cast<IImport*>(action->data().value<QObject*>())->importDatabase(this,tmpdb)){
997 PasswordDialog dlg(this,PasswordDialog::Mode_Set,PasswordDialog::Flag_None,QString());
998 if(dlg.exec()!=PasswordDialog::Exit_Ok){
1003 db->setKey(dlg.password(),dlg.keyFile());
1004 db->generateMasterKey();
1007 setupDatabaseConnections(db);
1008 GroupView->createItems();
1009 EntryView->showGroup(NULL);
1010 setStateFileOpen(true);
1011 setStateFileModified(true);
1018 void KeepassMainWindow::removeFromSearchResults(int id){
1019 for(int i=0; i<SearchResults.size();i++){
1020 if(SearchResults[i]==id){
1021 SearchResults.removeAt(i);
1028 void KeepassMainWindow::search(IGroupHandle* group){
1029 SearchDialog dlg(db,group,this);
1031 EntryView->SearchResults=dlg.Result;
1032 GroupView->showSearchResults();
1036 void KeepassMainWindow::OnSearch(){
1040 void KeepassMainWindow::OnGroupSearch(){
1041 Q_ASSERT(GroupView->currentItem());
1042 search(((GroupViewItem*)GroupView->currentItem())->GroupHandle);
1045 void KeepassMainWindow::OnQuickSearch(){
1046 EntryView->SearchResults=db->search(NULL,QuickSearchEdit->text(),false,false,false,NULL);
1047 GroupView->showSearchResults();
1050 void KeepassMainWindow::OnColumnVisibilityChanged(){
1051 EntryView->setColumnVisible(0, ViewColumnsTitleAction->isChecked());
1052 EntryView->setColumnVisible(1, ViewColumnsUsernameAction->isChecked());
1053 EntryView->setColumnVisible(2, ViewColumnsUrlAction->isChecked());
1054 EntryView->setColumnVisible(3, ViewColumnsPasswordAction->isChecked());
1055 EntryView->setColumnVisible(4, ViewColumnsCommentAction->isChecked());
1056 EntryView->setColumnVisible(5, ViewColumnsExpireAction->isChecked());
1057 EntryView->setColumnVisible(6, ViewColumnsCreationAction->isChecked());
1058 EntryView->setColumnVisible(7, ViewColumnsLastChangeAction->isChecked());
1059 EntryView->setColumnVisible(8, ViewColumnsLastAccessAction->isChecked());
1060 EntryView->setColumnVisible(9, ViewColumnsAttachmentAction->isChecked());
1061 EntryView->setColumnVisible(10, ViewColumnsGroupAction->isVisible() && ViewColumnsGroupAction->isChecked());
1064 void KeepassMainWindow::OnUsernPasswVisibilityChanged(){
1065 config->setHidePasswords(ViewHidePasswordsAction->isChecked());
1066 config->setHideUsernames(ViewHideUsernamesAction->isChecked());
1067 EntryView->refreshItems();
1070 void KeepassMainWindow::OnFileModified(){
1071 setStateFileModified(true);
1074 void KeepassMainWindow::closeEvent(QCloseEvent* e){
1075 if (!ShutingDown && config->showSysTrayIcon() && config->minimizeToTray()){
1077 if (config->lockOnMinimize() && !IsLocked && FileOpen)
1078 OnUnLockWorkspace();
1083 if(FileOpen && !closeDatabase()){
1084 ShutingDown = false;
1093 #ifdef GLOBAL_AUTOTYPE
1094 autoType->unregisterGlobalShortcut();
1097 config->setMainWindowGeometry(saveGeometry());
1098 // workaround if window has never been visible
1099 if (isVisible() || VSplitter->sizes()[0]!=VSplitter->sizes()[1])
1100 config->setVSplitterPos(VSplitter->saveState());
1101 if (config->showEntryDetails())
1102 config->setHSplitterPos(HSplitter->saveState());
1103 config->setShowStatusbar(statusBar()->isVisible());
1106 QMainWindow::closeEvent(e);
1107 QApplication::quit();
1110 void KeepassMainWindow::hideEvent(QHideEvent* event){
1111 if (event->spontaneous() && QApplication::activeModalWidget()==NULL){
1112 if (config->lockOnMinimize() && !IsLocked && FileOpen)
1113 OnUnLockWorkspace();
1114 if (config->showSysTrayIcon() && config->minimizeTray()){
1116 QTimer::singleShot(100, this, SLOT(hide()));
1125 QMainWindow::hideEvent(event);
1128 void KeepassMainWindow::showEvent(QShowEvent* event){
1129 if (IsLocked && !InUnLock && event->spontaneous()){
1131 showNormal(); // workaround for some graphic glitches
1133 OnUnLockWorkspace();
1136 QMainWindow::showEvent(event);
1139 void KeepassMainWindow::OnExtrasSettings(){
1140 QString oldLang = config->language();
1141 bool oldAlwaysOnTop = config->alwaysOnTop();
1142 CSettingsDlg dlg(this);
1144 if (config->language() != oldLang){
1145 retranslateUi(this);
1146 WorkspaceLockedWidget.retranslateUi(LockedCentralWidget);
1147 ViewShowToolbarAction->setText(tr("Show &Toolbar"));
1148 EntryView->retranslateColumns();
1149 GroupView->retranslateUi();
1150 updateWindowTitle();
1151 updateTrayTooltip();
1152 setStatusBarMsg(statusbarState);
1155 EntryView->setAlternatingRowColors(config->alternatingRowColors());
1156 SysTray->setVisible(config->showSysTrayIcon());
1157 menuBookmarks->menuAction()->setVisible(config->featureBookmarks());
1159 if (config->alwaysOnTop() != oldAlwaysOnTop) {
1160 if (config->alwaysOnTop())
1161 setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
1163 setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
1168 EventOccurred = true;
1169 if (config->lockOnInactivity() && config->lockAfterSec()!=0 && !inactivityTimer->isActive()){
1170 inactivityCounter = 0;
1171 inactivityTimer->start();
1173 else if ((!config->lockOnInactivity() || config->lockAfterSec()==0) && inactivityTimer->isActive()){
1174 inactivityTimer->stop();
1178 void KeepassMainWindow::OnHelpAbout(){
1179 AboutDialog dlg(this);
1183 void KeepassMainWindow::OnHelpHandbook(){
1184 QPointer<HelpDlg> dlg = new HelpDlg(this);
1189 void KeepassMainWindow::OnViewShowToolbar(bool show){
1190 config->setShowToolbar(show);
1191 toolBar->setVisible(show);
1194 void KeepassMainWindow::OnViewShowEntryDetails(bool show){
1195 config->setShowEntryDetails(show);
1196 DetailView->setVisible(show);
1199 /*void KeepassMainWindow::OnItemExpanded(QTreeWidgetItem* item){
1200 //((GroupViewItem*)item)->pGroup->UI_ItemIsExpanded=true;
1203 void KeepassMainWindow::OnItemCollaped(QTreeWidgetItem* item){
1204 //((GroupViewItem*)item)->pGroup->UI_ItemIsExpanded=false;
1207 void KeepassMainWindow::OnGroupSelectionChanged(IGroupHandle* group){
1209 setStateGroupSelected(SINGLE);
1211 setStateGroupSelected(NONE);
1214 void KeepassMainWindow::OnEntryChanged(SelectionState Selection){
1216 setStateEntrySelected(Selection);
1219 void KeepassMainWindow::OnShowSearchResults(){
1220 setStateGroupSelected(SEARCHGROUP);
1224 void KeepassMainWindow::OnViewToolbarIconSize16(bool state){
1226 ViewToolButtonSize22Action->setChecked(false);
1227 ViewToolButtonSize28Action->setChecked(false);
1228 config->setToolbarIconSize(16);
1229 toolBar->setIconSize(QSize(16,16));
1232 void KeepassMainWindow::OnViewToolbarIconSize22(bool state){
1234 ViewToolButtonSize16Action->setChecked(false);
1235 ViewToolButtonSize28Action->setChecked(false);
1236 config->setToolbarIconSize(22);
1237 toolBar->setIconSize(QSize(22,22));
1240 void KeepassMainWindow::OnViewToolbarIconSize28(bool state){
1242 ViewToolButtonSize16Action->setChecked(false);
1243 ViewToolButtonSize22Action->setChecked(false);
1244 config->setToolbarIconSize(28);
1245 toolBar->setIconSize(QSize(28,28));
1248 void KeepassMainWindow::OnSysTrayActivated(QSystemTrayIcon::ActivationReason reason){
1249 if(reason!=QSystemTrayIcon::Context){
1251 if (unlockDlg!=NULL)
1252 unlockDlg->reject();
1253 else if (config->lockOnMinimize() && !IsLocked && FileOpen)
1254 OnUnLockWorkspace();
1259 QTimer::singleShot(100, this, SLOT(restoreWindow()));
1267 void KeepassMainWindow::restoreWindow(){
1269 if (windowState() & Qt::WindowMaximized)
1278 OnUnLockWorkspace();
1281 void KeepassMainWindow::OnExtrasPasswordGen(){
1282 CGenPwDialog dlg(this,true);
1287 void KeepassMainWindow::saveLastFilename(const QString& filename){
1289 if(config->openLastFile()){
1290 if(config->saveRelativePaths()){
1291 QString Path=filename.left(filename.lastIndexOf("/"));
1292 Path=makePathRelative(Path,QDir::currentPath());
1293 config->setLastFile(Path+filename.right(filename.length()-filename.lastIndexOf("/")-1));
1296 config->setLastFile(filename);
1300 void KeepassMainWindow::OnExtrasShowExpiredEntries(){
1301 ExpiredEntriesDialog dlg(this,db,db->expiredEntries());
1302 if(dlg.exec()==QDialog::Accepted){
1303 GroupView->setCurrentGroup(dlg.SelectedEntry->group());
1304 EntryView->setCurrentEntry(dlg.SelectedEntry);
1310 /*void KeepassMainWindow::OnExtrasTrashCan(){
1311 TrashCanDialog dlg(this,db,db->expiredEntries());
1312 if(dlg.exec()==QDialog::Accepted){
1318 void KeepassMainWindow::OnDetailViewUrlClicked(const QUrl& url){
1319 openBrowser(url.toString());
1322 void KeepassMainWindow::OnUnLockWorkspace(){
1324 if (InUnLock) return;
1326 if ( openDatabase(currentFilePath,true) ){
1327 QTreeWidgetItem* item = GroupView->invisibleRootItem();
1328 if (lockGroup.size()>0){
1329 for (int i=0; i<lockGroup.size(); i++){
1330 item = item->child(lockGroup[i]);
1331 if (item==NULL) break;
1334 GroupView->setCurrentItem(item);
1341 QTreeWidgetItem* item = GroupView->currentItem();
1344 QTreeWidgetItem* parent = item->parent();
1345 if (parent==NULL && !root) {
1346 parent = GroupView->invisibleRootItem();
1350 lockGroup.prepend(parent->indexOfChild(item));
1354 if (closeDatabase(true)) {
1355 setStateFileModified(false);
1363 void KeepassMainWindow::OnLockClose(){
1365 setStateFileOpen(false);
1368 void KeepassMainWindow::setLock(){
1369 QuickSearchEdit->setEchoMode(QLineEdit::NoEcho);
1370 NormalCentralWidget->setVisible(false);
1371 NormalCentralWidget->setParent(NULL);
1372 setCentralWidget(LockedCentralWidget);
1373 LockedCentralWidget->setVisible(true);
1374 SysTray->setIcon(getIcon("keepassx_locked"));
1375 FileUnLockWorkspaceAction->setText(tr("Un&lock Workspace"));
1377 updateTrayTooltip();
1378 setStateFileOpen(false);
1381 void KeepassMainWindow::resetLock(){
1383 QuickSearchEdit->setText("");
1384 QuickSearchEdit->setEchoMode(QLineEdit::Normal);
1385 LockedCentralWidget->setVisible(false);
1386 LockedCentralWidget->setParent(NULL);
1387 setCentralWidget(NormalCentralWidget);
1388 NormalCentralWidget->setVisible(true);
1389 SysTray->setIcon(getIcon("keepassx"));
1390 FileUnLockWorkspaceAction->setText(tr("&Lock Workspace"));
1392 updateTrayTooltip();
1395 void KeepassMainWindow::OnInactivityTimer(){
1396 if (IsLocked || !FileOpen)
1399 if (QApplication::activeModalWidget()!=NULL || EventOccurredBlock){
1400 inactivityCounter = 0;
1405 inactivityCounter = 0;
1406 EventOccurred = false;
1409 inactivityCounter++;
1410 if (inactivityCounter*(inactivityTimer->interval()) >= config->lockAfterSec()*1000){
1411 QWidget* popUpWidget = QApplication::activePopupWidget();
1412 if (popUpWidget!=NULL)
1413 popUpWidget->hide();
1414 OnUnLockWorkspace();
1419 void KeepassMainWindow::OnShutdown(QSessionManager& manager) {
1422 /* QApplication::commitData() only closes visible windows,
1423 so we need to manually close mainwindow if it's hidden */
1424 if (manager.allowsInteraction() && !isVisible()) {
1429 void KeepassMainWindow::OnBookmarkTriggered(QAction* action){
1430 if(action==AddBookmarkAction){
1431 AddBookmarkDlg dlg(this);
1434 QAction* action=new QAction(this);
1435 action->setData(id);
1436 action->setText(KpxBookmarks::title(id));
1437 action->setIcon(getIcon("document"));
1438 menuBookmarks->addAction(action);
1441 else if(action==ManageBookmarksAction){
1442 ManageBookmarksDlg dlg(this);
1444 menuBookmarks->clear();
1445 createBookmarkActions();
1447 else if(action==AddThisAsBookmarkAction){
1448 AddBookmarkDlg dlg(this,db->file()->fileName());
1451 QAction* action=new QAction(this);
1452 action->setData(id);
1453 action->setText(KpxBookmarks::title(id));
1454 action->setIcon(getIcon("document"));
1455 menuBookmarks->addAction(action);
1459 openDatabase(KpxBookmarks::path(action->data().toInt()));
1463 void KeepassMainWindow::createBookmarkActions(){
1464 menuBookmarks->addAction(AddBookmarkAction);
1465 menuBookmarks->addAction(AddThisAsBookmarkAction);
1466 menuBookmarks->addAction(ManageBookmarksAction);
1467 menuBookmarks->addSeparator();
1468 for(int i=0;i<KpxBookmarks::count();i++){
1469 QAction* action=new QAction(this);
1471 action->setText(KpxBookmarks::title(i));
1472 action->setIcon(getIcon("document"));
1473 menuBookmarks->addAction(action);
1477 void KeepassMainWindow::setStatusBarMsg(StatusBarMsg statusBarMsg) {
1480 switch (statusBarMsg) {
1481 case StatusBarReady:
1484 case StatusBarLoading:
1485 text = tr("Loading Database...");
1487 case StatusBarLoadingFailed:
1488 text = tr("Loading Failed");
1490 case StatusBarReadOnlyLock:
1491 text = tr("Couldn't create lock file. Opening the database read-only.");
1495 statusbarState = statusBarMsg;
1496 StatusBarGeneral->setText(text);
1499 void KeepassMainWindow::updateWindowTitle() {
1500 if (!IsLocked && !FileOpen)
1501 setWindowTitle( QString("%1 - %2").arg(APP_DISPLAY_NAME, APP_SHORT_FUNC) );
1502 else if (currentFilePath.isEmpty())
1503 setWindowTitle( QString("[%1][*] - %2").arg(tr("new"), APP_DISPLAY_NAME) );
1505 setWindowTitle( QString("%1 (%2) - %3").arg(currentFilePath, tr("locked"), APP_DISPLAY_NAME) );
1507 setWindowTitle( QString("%1[*] - %2").arg(currentFilePath, APP_DISPLAY_NAME) );
1509 setWindowTitle( QString("%1 - %2").arg(currentFilePath, APP_DISPLAY_NAME) );
1512 void KeepassMainWindow::updateTrayTooltip() {
1513 if (!IsLocked && !FileOpen)
1514 SysTray->setToolTip(QString("%1 - %2").arg(APP_DISPLAY_NAME, APP_SHORT_FUNC));
1516 QString tooltip = QString("%1 - %2").arg(APP_DISPLAY_NAME, currentFilePath.isEmpty()
1517 ? QString("[%1]").arg(tr("new")) : currentFileName);
1519 tooltip.append( QString(" (%1)").arg(tr("locked")) );
1520 SysTray->setToolTip(tooltip);
1524 void KeepassMainWindow::updateCurrentFile(const QString& filePath) {
1525 currentFilePath = filePath;
1526 currentFileName = QFileInfo(filePath).fileName();