📄 dboxview.cpp
字号:
/// file DboxView.cpp//// View-related methods of DboxMain//-----------------------------------------------------------------------------#include "PasswordSafe.h"#include "ThisMfcApp.h"#if defined(POCKET_PC) #include "pocketpc/resource.h"#else #include <errno.h> #include "resource.h"#endif#include "DboxMain.h"#include "AddDlg.h"#include "ConfirmDeleteDlg.h"#include "EditDlg.h"#include "QuerySetDef.h"#include "RemindSaveDlg.h"#include "TryAgainDlg.h"#include "corelib/pwsprefs.h"#include "KeySend.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endifstatic void FixListIndexes(CListCtrl &clist){ int N = clist.GetItemCount(); for (int i = 0; i < N; i++) { CItemData *ci = (CItemData *)clist.GetItemData(i); ASSERT(ci != NULL); DisplayInfo *di = (DisplayInfo *)ci->GetDisplayInfo(); ASSERT(di != NULL); if (di->list_index != i) di->list_index = i; }}//----------------------------------------------------------------------------- /* * Compare function used by m_ctlItemList.SortItems() * "The comparison function must return a negative value if the first item should precede * the second, a positive value if the first item should follow the second, or zero if * the two items are equivalent." * * If sorting is by title (username) , username (title) is the secondary field if the * primary fields are identical. */int CALLBACK DboxMain::CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM closure){ // closure is "this" of the calling DboxMain, from which we use: // m_iSortedColumn to determine which column is getting sorted: // 0 - title // 1 - user name // 2 - note // 3 - password // m_bSortAscending to determine the direction of the sort (duh) DboxMain *self = (DboxMain*)closure; const int nRecurseFlag = 500; // added to the desired sort column when recursing bool bAlreadyRecursed = false; int nSortColumn = self->m_iSortedColumn; CItemData* pLHS = (CItemData *)lParam1; CItemData* pRHS = (CItemData *)lParam2; CMyString title1, username1; CMyString title2, username2; // if the sort column is really big, then we must be being called via recursion if ( nSortColumn >= nRecurseFlag ) { bAlreadyRecursed = true; // prevents further recursion nSortColumn -= nRecurseFlag; // normalizes sort column } int iResult; switch(nSortColumn) { case 0: title1 = pLHS->GetTitle(); title2 = pRHS->GetTitle(); iResult = ((CString)title1).CompareNoCase(title2); if (iResult == 0 && !bAlreadyRecursed) { // making a recursed call, add nRecurseFlag const int savedSortColumn = self->m_iSortedColumn; self->m_iSortedColumn = 1 + nRecurseFlag; iResult = CompareFunc(lParam1, lParam2, closure); self->m_iSortedColumn = savedSortColumn; } break; case 1: username1 = pLHS->GetUser(); username2 = pRHS->GetUser(); iResult = ((CString)username1).CompareNoCase(username2); if (iResult == 0 && !bAlreadyRecursed) { // making a recursed call, add nRecurseFlag const int savedSortColumn = self->m_iSortedColumn; self->m_iSortedColumn = 0 + nRecurseFlag; iResult = CompareFunc(lParam1, lParam2, closure); self->m_iSortedColumn = savedSortColumn; } break; case 2: iResult = ((CString)pLHS->GetNotes()).CompareNoCase(pRHS->GetNotes()); break; case 3: iResult = ((CString)pLHS->GetPassword()).CompareNoCase(pRHS->GetPassword()); break; default: iResult = 0; // should never happen - just keep compiler happy ASSERT(FALSE); } if (!self->m_bSortAscending) { iResult *= -1; } return iResult;}voidDboxMain::DoDataExchange(CDataExchange* pDX){ CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(DboxMain) DDX_Control(pDX, IDC_ITEMLIST, m_ctlItemList); DDX_Control(pDX, IDC_ITEMTREE, m_ctlItemTree); //}}AFX_DATA_MAP}voidDboxMain::setupBars(){#if !defined(POCKET_PC) // This code is copied from the DLGCBR32 example that comes with MFC const UINT statustext = IDS_STATMESSAGE; // Add the status bar if (m_statusBar.Create(this)) { m_statusBar.SetIndicators(&statustext, 1); // Make a sunken or recessed border around the first pane m_statusBar.SetPaneInfo(0, m_statusBar.GetItemID(0), SBPS_STRETCH, NULL); } // Add the ToolBar. if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT | TBSTYLE_TRANSPARENT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || !m_wndToolBar.LoadToolBar(IDR_MAINBAR)) { TRACE0("Failed to create toolbar\n"); return; // fail to create } // Set toolbar according to graphic capabilities, overridable by user choice. CDC* pDC = this->GetDC(); int NumBits = ( pDC ? pDC->GetDeviceCaps(12 /*BITSPIXEL*/) : 32 ); if (NumBits < 16 || !PWSprefs::GetInstance()->GetPref(PWSprefs::BoolPrefs::UseNewToolbar)) { SetToolbar(ID_MENUITEM_OLD_TOOLBAR); } else { SetToolbar(ID_MENUITEM_NEW_TOOLBAR); } // Set flag m_toolbarsSetup = TRUE;#endif}//Add an itemvoidDboxMain::OnAdd() { CAddDlg dataDlg(this); m_LockDisabled = true; if (m_core.GetUseDefUser()) { dataDlg.m_username = m_core.GetDefUsername(); } dataDlg.m_group = m_TreeViewGroup; m_TreeViewGroup = _T(""); // for next time app.DisableAccelerator(); int rc = dataDlg.DoModal(); app.EnableAccelerator(); if (rc == IDOK) { PWSprefs *prefs = PWSprefs::GetInstance(); //Check if they wish to set a default username if (!m_core.GetUseDefUser() && (prefs->GetPref(PWSprefs::BoolPrefs::QuerySetDef)) && (!dataDlg.m_username.IsEmpty())) { CQuerySetDef defDlg(this); defDlg.m_message = _T("Would you like to set \"") + (const CString&)dataDlg.m_username + _T("\" as your default username?\n\nIt would then automatically be ") + _T("put in the dialog each time you add a new item."); int rc2 = defDlg.DoModal(); if (rc2 == IDOK) { prefs->SetPref(PWSprefs::BoolPrefs::UseDefUser, true); prefs->SetPref(PWSprefs::StringPrefs::DefUserName, dataDlg.m_username); m_core.SetUseDefUser(true); m_core.SetDefUsername(dataDlg.m_username); RefreshList(); } } //Finish Check (Does that make any geographical sense?) CItemData temp; CMyString user; if (dataDlg.m_username.IsEmpty() && m_core.GetUseDefUser()) user = m_core.GetDefUsername(); else user = dataDlg.m_username; temp.CreateUUID(); temp.SetGroup(dataDlg.m_group); temp.SetTitle(dataDlg.m_title); temp.SetUser(user); temp.SetPassword(dataDlg.m_password); temp.SetNotes(dataDlg.m_notes); m_core.AddEntryToTail(temp); int newpos = insertItem(m_core.GetTailEntry()); SelectEntry(newpos); FixListIndexes(m_ctlItemList); m_ctlItemList.SetFocus(); if (prefs->GetPref(PWSprefs::BoolPrefs::SaveImmediately)) { Save(); } ChangeOkUpdate(); } else if (rc == IDCANCEL) { } m_LockDisabled = false;}//Add a group (tree view only)voidDboxMain::OnAddGroup(){ if (m_ctlItemTree.IsWindowVisible()) { // This can be reached by right clicking over an existing group node // or by clicking over "whitespace". // If the former, add a child node to the current one // If the latter, add to root. if (m_TreeViewGroup.IsEmpty()) m_TreeViewGroup = _T("New Group"); else m_TreeViewGroup += _T(".New Group"); HTREEITEM newGroup = m_ctlItemTree.AddGroup(m_TreeViewGroup); m_ctlItemTree.SelectItem(newGroup); m_TreeViewGroup = _T(""); // for next time m_ctlItemTree.EditLabel(newGroup); }}// Delete key was pressed (in list view or tree view) to delete an entry.voidDboxMain::OnDelete() { m_LockDisabled = true; if (SelItemOk() == TRUE) { BOOL dodelete = TRUE; //Confirm whether to delete the file CConfirmDeleteDlg deleteDlg(this); if (deleteDlg.m_dontaskquestion == FALSE) { int rc = deleteDlg.DoModal(); if (rc == IDOK) { dodelete = TRUE; } else if (rc == IDCANCEL) { dodelete = FALSE; } } if (dodelete == TRUE) { CItemData *ci = getSelectedItem(); ASSERT(ci != NULL); DisplayInfo *di = (DisplayInfo *)ci->GetDisplayInfo(); ASSERT(di != NULL); int curSel = di->list_index; POSITION listindex = Find(curSel); // Must Find before delete from m_ctlItemList m_ctlItemList.DeleteItem(curSel); m_ctlItemTree.DeleteWithParents(di->tree_item); delete di; m_core.RemoveEntryAt(listindex); FixListIndexes(m_ctlItemList); if (m_core.GetNumEntries() > 0) { SelectEntry(curSel < m_core.GetNumEntries() ? curSel : m_core.GetNumEntries() - 1); } if (m_ctlItemList.IsWindowVisible()) m_ctlItemList.SetFocus(); else // tree view visible m_ctlItemTree.SetFocus(); ChangeOkUpdate(); } } else { // see if the user is just asking to delete an empty group. if (m_ctlItemTree.IsWindowVisible()) { HTREEITEM ti = m_ctlItemTree.GetSelectedItem(); if (ti != NULL && !m_ctlItemTree.IsLeafNode(ti) && !m_ctlItemTree.ItemHasChildren(ti)) { HTREEITEM parent = m_ctlItemTree.GetParentItem(ti); m_ctlItemTree.DeleteItem(ti); m_ctlItemTree.SelectItem(parent); } } } m_LockDisabled = false;}voidDboxMain::OnRename() { // Renaming is only allowed while in Tree mode. if (m_ctlItemTree.IsWindowVisible()) { HTREEITEM hItem = m_ctlItemTree.GetSelectedItem(); if (hItem != NULL) m_ctlItemTree.EditLabel(hItem); }}voidDboxMain::OnEdit() { m_LockDisabled = true; if (SelItemOk() == TRUE) { CItemData *ci = getSelectedItem(); ASSERT(ci != NULL); DisplayInfo *di = (DisplayInfo *)ci->GetDisplayInfo(); ASSERT(di != NULL); POSITION listpos = Find(di->list_index); CEditDlg dlg_edit(this); dlg_edit.m_group = ci->GetGroup(); dlg_edit.m_title = ci->GetTitle(); dlg_edit.m_username = ci->GetUser(); dlg_edit.m_realpassword = ci->GetPassword(); dlg_edit.m_password = HIDDEN_PASSWORD; dlg_edit.m_notes = ci->GetNotes(); dlg_edit.m_listindex = listpos; // for future reference, this is not multi-user friendly app.DisableAccelerator(); int rc = dlg_edit.DoModal(); app.EnableAccelerator(); if (rc == IDOK) { CMyString temptitle; CMyString user; if (dlg_edit.m_username.IsEmpty() && m_core.GetUseDefUser()) user = m_core.GetDefUsername(); else user = dlg_edit.m_username; ci->SetGroup(dlg_edit.m_group); ci->SetTitle(dlg_edit.m_title); ci->SetUser(user); ci->SetPassword(dlg_edit.m_realpassword); ci->SetNotes(dlg_edit.m_notes); /* Out with the old, in with the new */ CItemData editedItem(*ci); // 'cause next line deletes *ci m_core.RemoveEntryAt(listpos); m_core.AddEntryToTail(editedItem); m_ctlItemList.DeleteItem(di->list_index); m_ctlItemTree.DeleteWithParents(di->tree_item); di->list_index = -1; // so that insertItem will set new values insertItem(m_core.GetTailEntry()); FixListIndexes(m_ctlItemList); if (PWSprefs::GetInstance()-> GetPref(PWSprefs::BoolPrefs::SaveImmediately)) { Save(); } rc = SelectEntry(di->list_index); if (rc == LB_ERR) { SelectEntry(m_ctlItemList.GetItemCount() - 1); } ChangeOkUpdate(); } // rc == IDOK } m_LockDisabled = false;}voidDboxMain::OnOK() { int rc, rc2; PWSprefs::IntPrefs WidthPrefs[] = { PWSprefs::IntPrefs::Column1Width, PWSprefs::IntPrefs::Column2Width, PWSprefs::IntPrefs::Column3Width, PWSprefs::IntPrefs::Column4Width, }; PWSprefs *prefs = PWSprefs::GetInstance(); LVCOLUMN lvColumn; lvColumn.mask = LVCF_WIDTH; for (int i = 0; i < 4; i++) { if (m_ctlItemList.GetColumn(i, &lvColumn)) { prefs->SetPref(WidthPrefs[i], lvColumn.cx); } }#if !defined(POCKET_PC) if (!IsIconic()) { CRect rect; GetWindowRect(&rect); prefs->SetPrefRect(rect.top, rect.bottom, rect.left, rect.right); }#endif prefs->SetPref(PWSprefs::IntPrefs::SortedColumn, m_iSortedColumn); prefs->SetPref(PWSprefs::BoolPrefs::SortAscending, m_bSortAscending); if (m_core.IsChanged()) { rc = MessageBox(_T("Do you want to save changes to the password list?"), AfxGetAppName(), MB_ICONQUESTION|MB_YESNOCANCEL); switch (rc) { case IDCANCEL: return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -