Ejemplo n.º 1
0
void PWSGridTable::SaveSettings(void) const
{
  wxString colWidths, colShown;
  wxGrid* grid = GetView();
  const int nCols = grid->GetNumberCols();

  for(int idx = 0; idx < nCols; ++idx) {

    const int colID = grid->GetColAt(idx);

#if wxCHECK_VERSION(2, 9, 1)
    if (!grid->IsColShown(colID))
      continue;
#endif

    colShown << GetColumnFieldType(colID) << wxT(',');
    colWidths << grid->GetColSize(colID) << wxT(',');
  }

  if (!colShown.IsEmpty())
    colShown.RemoveLast();

  if (!colWidths.IsEmpty())
    colWidths.RemoveLast();

  //write these, even if colWidth and colShown are empty
  PWSprefs::GetInstance()->SetPref(PWSprefs::ListColumns, tostringx(colShown));
  PWSprefs::GetInstance()->SetPref(PWSprefs::ColumnWidths, tostringx(colWidths));
}
Ejemplo n.º 2
0
void EditShortcut::OnOkClick( wxCommandEvent& /* evt */ )
{
  if (Validate() && TransferDataFromWindow()) {
    bool modified = false;
    CItemData modified_item(*m_item);
    const wxString group = m_groupCtrl->GetValue();
    if (group != m_item->GetGroup().c_str()) {
      modified = true;
      modified_item.SetGroup(tostringx(group));
    }
    if (m_title != m_item->GetTitle().c_str()) {
      modified = true;
      modified_item.SetTitle(tostringx(m_title));
    }
    if (m_user != m_item->GetUser().c_str()) {
      modified = true;
      modified_item.SetUser(tostringx(m_user));
    }
    if (modified) {
      time_t t;
      time(&t);
      modified_item.SetRMTime(t);
      m_core.Execute(EditEntryCommand::Create(&m_core,*m_item,
                                              modified_item));
      m_ui->GUIRefreshEntry(modified_item);
    }
  }
  EndModal(wxID_OK);
}
Ejemplo n.º 3
0
void CSafeCombinationEntry::ProcessPhrase()
{
  int status = m_core.CheckPasskey(tostringx(m_filename), m_password);
  wxString errmess;
  switch (status) {
  case PWScore::SUCCESS:
    m_core.SetReadOnly(m_readOnly);
    m_core.SetCurFile(tostringx(m_filename));
    wxGetApp().recentDatabases().AddFileToHistory(m_filename);
    EndModal(wxID_OK);
    return;
  case PWScore::CANT_OPEN_FILE:
    { stringT str;
      LoadAString(str, IDSC_FILE_UNREADABLE);
      errmess = str.c_str();
    }
    break;
  case PWScore::WRONG_PASSWORD:
  default:
    if (m_tries >= 2) {
      errmess = _("Three strikes - yer out!");
    } else {
      m_tries++;
      errmess = _("Incorrect passkey, not a PasswordSafe database, or a corrupt database. (Backup database has same name as original, ending with '~')");
    }
    break;
  } // switch (status)
    // here iff CheckPasskey failed.
  wxMessageDialog err(this, errmess,
                      _("Error"), wxOK | wxICON_EXCLAMATION);
  err.ShowModal();
  wxTextCtrl *txt = (wxTextCtrl *)FindWindow(ID_COMBINATION);
  txt->SetSelection(-1,-1);
  txt->SetFocus();
}
Ejemplo n.º 4
0
void CSafeCombinationEntry::OnNewDbClick( wxCommandEvent& /* evt */ )
{
  // 1. Get a filename from a file dialog box
  // 2. Get a password
  // 3. Set m_filespec && m_passkey to returned value!
  wxString newfile;
  wxString cs_msg, cs_title, cs_temp;

  wxString cf(wxT("pwsafe")); // reasonable default for first time user
  stringT v3FileName = PWSUtil::GetNewFileName(tostdstring(cf), wxT("psafe3"));
  stringT dir = PWSdirs::GetSafeDir();

  while (1) {
    wxFileDialog fd(this, _("Please choose a name for the new database"),
                    dir.c_str(), v3FileName.c_str(),
                    _("Password Safe Databases (*.psafe3; *.dat)|*.psafe3;*.dat| All files (*.*; *)|*.*;*"),
                  (wxFD_SAVE | wxFD_OVERWRITE_PROMPT| wxFD_CHANGE_DIR));
    int rc = fd.ShowModal();
    if (rc == wxID_OK) {
      wxFileName wxfn(fd.GetPath());
      if (wxfn.GetExt().empty()) {
        wxfn.SetExt(DEFAULT_SUFFIX);
      }
      newfile = wxfn.GetFullPath();
      break;
    } else
      return;
  }
  // 2. Get a password
  CSafeCombinationSetup pksetup(this);
  int rc = pksetup.ShowModal();

  if (rc != wxID_OK)
    return;  //User cancelled password entry

  // 3. Set m_filespec && m_passkey to returned value!
  m_core.SetCurFile(tostringx(newfile));

  // Now lock the new file
  std::wstring locker(L""); // null init is important here
  m_core.LockFile(tostdstring(newfile), locker);

  m_core.SetReadOnly(false); // new file can't be read-only...
  m_core.NewFile(tostringx(pksetup.GetPassword()));
  if ((rc = m_core.WriteCurFile()) == PWSfile::SUCCESS) {
    wxGetApp().recentDatabases().AddFileToHistory(newfile);
    EndModal(wxID_OK);
  }
  else {
    wxMessageBox(wxString()<< newfile << wxT("\n\n") << _("Could not open file for writing!"),
                 _("Write Error"), wxOK | wxICON_ERROR, this);
  }
}
Ejemplo n.º 5
0
int ReadCore(PWScore& othercore, const wxString& file, const StringX& combination, 
                bool showMsgbox /*= true*/, wxWindow* msgboxParent /*= NULL*/)
{
  othercore.ClearData();

  // Reading a new file changes the preferences!
  const StringX sxSavePrefString(PWSprefs::GetInstance()->Store());
  const bool bDBPrefsChanged = PWSprefs::GetInstance()->IsDBprefsChanged();

  StringX dbpath(tostringx(file));
  int rc = othercore.ReadFile(dbpath, combination);

  // Reset database preferences - first to defaults then add saved changes!
  PWSprefs::GetInstance()->Load(sxSavePrefString);
  PWSprefs::GetInstance()->SetDBprefsChanged(bDBPrefsChanged);

  switch (rc) {
    case PWScore::SUCCESS:
      othercore.SetCurFile(tostringx(file));
      break;

    case PWScore::CANT_OPEN_FILE:
      if (showMsgbox)
        wxMessageBox(wxString(file) << _("\n\nCould not open file for reading!"),
                    _("File Read Error"), wxOK | wxICON_ERROR, msgboxParent );
      break;

    case PWScore::BAD_DIGEST:
      if (showMsgbox && wxMessageBox(wxString(file) << _("\n\nFile corrupt or truncated!\nData may have been lost or modified.\nContinue anyway?"), 
            _("File Read Error"), wxYES_NO | wxICON_QUESTION, msgboxParent) == wxYES) {
        rc = PWScore::SUCCESS;
      }
      break;

#ifdef DEMO
    case PWScore::LIMIT_REACHED:
      if( showMsgbox)
        wxMessageBox(wxString::Format(_("This version of PasswordSafe does not support more than %d entries in a database.\nTo get an unlimited version for the U3 platform, please visit http://software.u3.com\nNote: Saving this database will result in the removal of unread entries!"), MAXDEMO),
                        _("Trial Version Limitation"), wxOK | wxICON_WARNING, msgboxParent);
      break;
#endif

    default:
      if (showMsgbox)
        wxMessageBox( wxString(file) << _("\n\nUnknown error"), _("File Read Error"), wxOK | wxICON_ERROR, msgboxParent);
      break;
  }
  
  return rc;
}
bool CPasswordPolicy::Verify()
{
  wxString mess;
  bool retval = true;
  int id = 0;

  // Check that options, as set, are valid.
  if (m_pwUseHex &&
     (m_pwUseLowercase || m_pwUseUppercase || m_pwUseDigits ||
      m_pwUseSymbols || m_pwUseEasyVision || m_pwMakePronounceable)) {
    mess = _("Hexadecimal is mutually exculsive to all other options.");
    retval = false;
  } else if (m_pwUseHex) {
    if (m_pwdefaultlength % 2 != 0) {
      mess = _("Hexadecimal passwords must have even length - each byte is two characters");
      retval = false;
    }
  } else if (!m_pwUseLowercase && !m_pwUseUppercase &&
      !m_pwUseDigits && !m_pwUseSymbols) {
    mess = _("At least one type of character (lowercase, uppercase, digits, symbols or hexadecimal) must be chosen");
    retval = false;
  }

  if ((m_pwdefaultlength < 4) || (m_pwdefaultlength > 1024)) {
    mess = _("Password must be between 4 and 1024 characters");
    id = ID_PWLENSB;
    retval = false;
  }

  if (!(m_pwUseHex || m_pwUseEasyVision || m_pwMakePronounceable) &&
      (m_pwDigitMinLength + m_pwLowerMinLength +
       m_pwSymbolMinLength + m_pwUpperMinLength) > m_pwdefaultlength) {
    mess = _("Password length is less than sum of 'at least' constraints");
    id = ID_PWLENSB;
    retval = false;
  }

  if ((m_pwUseHex || m_pwUseEasyVision || m_pwMakePronounceable))
    m_pwDigitMinLength = m_pwLowerMinLength =
      m_pwSymbolMinLength = m_pwUpperMinLength = 1;

  if (m_polname.IsEmpty()) {
    mess = _("Policy name cannot be blank");
    id = ID_POLICYNAME;
    retval = false;
  } else if ((m_polname != m_oldpolname &&
              (m_MapPSWDPLC.find(tostringx(m_polname)) != m_MapPSWDPLC.end()))) {
    mess = _("Policy name is already in use");
    id = ID_POLICYNAME;
    retval = false;
  }

  if (!retval) {
    wxMessageDialog md(this, mess, _("Policy Error"), wxOK | wxICON_ERROR);
    md.ShowModal();
    if (id != 0)
      FindWindow(id)->SetFocus();
  }
  return retval;
}
Ejemplo n.º 7
0
void CompareDlg::OnCompare(wxCommandEvent& )
{
  if ( Validate() && TransferDataFromWindow()) {
    if (wxFileName(m_dbPanel->m_filepath).SameAs(towxstring(m_otherCore->GetCurFile())) ||
        ReadCore(*m_otherCore, m_dbPanel->m_filepath, m_dbPanel->m_combination,
                 true, this, true) == PWScore::SUCCESS) {
      m_otherCore->SetCurFile(tostringx(m_dbPanel->m_filepath));
      m_otherCore->SetReadOnly(true);

      // TODO: must copy the selectionCriteria from advanced options pane.  Or else
      // the search would always be conducted on default field criteria
      m_current->data.clear();
      m_comparison->data.clear();
      m_conflicts->data.clear();
      m_identical->data.clear();

      m_conflicts->pane->Collapse();
      m_current->pane->Collapse();
      m_comparison->pane->Collapse();
      m_identical->pane->Collapse();

      wxCommandEvent cmdEvent(EVT_START_COMPARISON, GetId());
      GetEventHandler()->AddPendingEvent(cmdEvent);
    }
  }
  else {
    m_otherCore->SetCurFile(StringX());
  }
}
Ejemplo n.º 8
0
void PasswordSafeSearch::OnDoSearchT(Iter begin, Iter end, Accessor afn)
{
  wxASSERT(m_toolbar);

  wxSearchCtrl* txtCtrl = wxDynamicCast(m_toolbar->FindControl(ID_FIND_EDITBOX), wxSearchCtrl);
  wxASSERT(txtCtrl);

  const wxString searchText = txtCtrl->GetLineText(0);

  if (searchText.IsEmpty())
    return;

  if (m_criteria->IsDirty() || txtCtrl->IsModified() || m_searchPointer.IsEmpty())  {
      m_searchPointer.Clear();

      if (!m_toolbar->GetToolState(ID_FIND_ADVANCED_OPTIONS))
        FindMatches(tostringx(searchText), m_toolbar->GetToolState(ID_FIND_IGNORE_CASE), m_searchPointer, begin, end, afn);
      else
        FindMatches(tostringx(searchText), m_toolbar->GetToolState(ID_FIND_IGNORE_CASE), m_searchPointer,
                      m_criteria->GetSelectedFields(), m_criteria->HasSubgroupRestriction(), m_criteria->SubgroupSearchText(),
                      m_criteria->SubgroupObject(), m_criteria->SubgroupFunction(),
                      m_criteria->CaseSensitive(), begin, end, afn);

      m_criteria->Clean();
      txtCtrl->SetModified(false);
      m_searchPointer.InitIndex();
  }
  else {
      ++m_searchPointer;
  }

  UpdateView();

  // Replace the "Find" menu item under Edit menu by "Find Next" and "Find Previous"
  wxMenu* editMenu = 0;
  wxMenuItem* findItem = m_parentFrame->GetMenuBar()->FindItem(wxID_FIND, &editMenu);
  if (findItem && editMenu)  {
      //Is there a way to do this without hard-coding the insert position?
    if (!m_parentFrame->GetMenuBar()->FindItem(ID_EDITMENU_FIND_NEXT) ) {
      editMenu->Insert(FIND_MENU_POSITION, ID_EDITMENU_FIND_NEXT, _("&Find next...\tF3"), wxT(""), wxITEM_NORMAL);
    }
    if (!m_parentFrame->GetMenuBar()->FindItem(ID_EDITMENU_FIND_PREVIOUS) ) {
      editMenu->Insert(FIND_MENU_POSITION+1, ID_EDITMENU_FIND_PREVIOUS, _("&Find previous...\tSHIFT+F3"), wxT(""), wxITEM_NORMAL);
    }
  }
}
Ejemplo n.º 9
0
int ReadCore(PWScore& othercore, const wxString& file, const StringX& combination,
             bool showMsgbox /*= true*/, wxWindow* msgboxParent /*= NULL*/,
        bool setupCopy /*= false*/)
{
  othercore.ClearData();

  StringX dbpath(tostringx(file));
  int rc = othercore.ReadFile(dbpath, combination);

  if (setupCopy)
    PWSprefs::GetInstance()->SetupCopyPrefs();

  switch (rc) {
    case PWScore::SUCCESS:
      othercore.SetCurFile(tostringx(file));
      break;

    case PWScore::CANT_OPEN_FILE:
      if (showMsgbox)
        wxMessageBox(wxString(file) << wxT("\n\n") << _("Could not open file for reading!"),
                    _("File Read Error"), wxOK | wxICON_ERROR, msgboxParent );
      break;

    case PWScore::BAD_DIGEST:
      if (showMsgbox && wxMessageBox(wxString(file) << wxT("\n\n") << _("File corrupt or truncated!\nData may have been lost or modified.\nContinue anyway?"),
            _("File Read Error"), wxYES_NO | wxICON_QUESTION, msgboxParent) == wxYES) {
        rc = PWScore::SUCCESS;
      }
      break;

    default:
      if (showMsgbox)
        wxMessageBox( wxString(file) << wxT("\n\n") << _("Unknown error"), _("File Read Error"), wxOK | wxICON_ERROR, msgboxParent);
      break;
  }

  return rc;
}
Ejemplo n.º 10
0
void CSafeCombinationPrompt::ProcessPhrase()
{
  if (m_core.CheckPasskey(tostringx(m_filename),
                          m_password) != PWScore::SUCCESS) {
    wxString errmess;
    if (m_tries >= 2) {
      errmess = _("Three strikes - yer out!");
    } else {
      m_tries++;
      errmess = _("Incorrect passkey, not a PasswordSafe database, or a corrupt database. (Backup database has same name as original, ending with '~')");
    }
    wxMessageDialog err(this, errmess,
                        _("Error"), wxOK | wxICON_EXCLAMATION);
    err.ShowModal();
    wxTextCtrl *txt = dynamic_cast<wxTextCtrl *>(FindWindow(ID_PASSWORD));
    txt->SetSelection(-1,-1);
    txt->SetFocus();
    return;
  }
  // m_core.SetReadOnly(m_readOnly);
  m_core.SetCurFile(tostringx(m_filename));
  EndModal(wxID_OK);
}
Ejemplo n.º 11
0
void CSafeCombinationSetup::OnOkClick( wxCommandEvent& /* evt */ )
{
  if (Validate() && TransferDataFromWindow()) {
    if (m_password != m_verify) {
      wxMessageDialog err(this, _("The two entries do not match."),
                          _("Error"), wxOK | wxICON_EXCLAMATION);
      err.ShowModal();
      return;
    }
    if (m_password.empty()) {
      wxMessageDialog err(this, _("Please enter the key and verify it."),
                          _("Error"), wxOK | wxICON_EXCLAMATION);
      err.ShowModal();
      return;
    }
    // Vox populi vox dei - folks want the ability to use a weak
    // passphrase, best we can do is warn them...
    // If someone want to build a version that insists on proper
    // passphrases, then just define the preprocessor macro
    // PWS_FORCE_STRONG_PASSPHRASE in the build properties/Makefile
    // (also used in CPasskeyChangeDlg)
#ifndef _DEBUG // for debug, we want no checks at all, to save time
    StringX errmess;
    if (!CPasswordCharPool::CheckPassword(tostringx(m_password), errmess)) {
      wxString cs_msg;
      cs_msg = _("Weak passphrase:");
      cs_msg += wxT("\n\n");
      cs_msg += errmess.c_str();
#ifndef PWS_FORCE_STRONG_PASSPHRASE
      cs_msg += wxT("\n");
      cs_msg += _("Use it anyway?");
      wxMessageDialog mb(this, cs_msg, _("Warning"),
                      wxYES_NO | wxNO_DEFAULT | wxICON_HAND);
      int rc = mb.ShowModal();
    if (rc == wxID_NO)
      return;
#else
    cs_msg += wxT("\n");
    cs_msg += _("Please try another");
    wxMessageDialog mb(this, cs_msg, _("Error"), wxOK | wxICON_HAND);
    mb.ShowModal();
    return;
#endif // PWS_FORCE_STRONG_PASSPHRASE
    }
#endif // _DEBUG
    EndModal(wxID_OK);
  }
}
Ejemplo n.º 12
0
void CSafeCombinationSetup::OnYubibtnClick( wxCommandEvent& /* event */ )
{
  if (Validate() && TransferDataFromWindow()) {
    if (m_password != m_verify) {
      wxMessageDialog err(this, _("The two entries do not match."),
                          _("Error"), wxOK | wxICON_EXCLAMATION);
      err.ShowModal();
      return;
    }
    StringX response;
    bool oldYubiChallenge = ::wxGetKeyState(WXK_SHIFT); // for pre-0.94 databases
    if (PerformChallengeResponse(this, tostringx(m_password), response, oldYubiChallenge)) {
      m_password = response.c_str();
      EndModal(wxID_OK);
    }
  }
}
Ejemplo n.º 13
0
PWPolicy CManagePasswordPolicies::GetSelectedPolicy() const
{
  /*
    If first row or no row selected, then fill in with the database default,
    otherwise use the name entry
  */

  int row = GetSelectedRow();
  if (row > 0) {
    const wxString policyname = m_PolicyNames->GetCellValue(row, 0);

    PSWDPolicyMapCIter iter = m_MapPSWDPLC.find(tostringx(policyname));
    if (iter == m_MapPSWDPLC.end())
      return m_st_default_pp;

    return iter->second;
  } else {
    return m_st_default_pp;
  }
}
Ejemplo n.º 14
0
bool CPasswordPolicy::Verify()
{
  wxString mess;
  bool retval = true;
  int id = 0;

  if (!m_pwUseLowercase && !m_pwUseUppercase &&
      !m_pwUseDigits && !m_pwUseSymbols) {
    mess = _("At least one type of character (lowercase, uppercase, digits, or symbols) must be chosen");
    retval = false;
  }

  if ((m_pwdefaultlength < 4) || (m_pwdefaultlength > 1024)) {
    mess = _("Password must be between 4 and 1024 characters");
    id = ID_PWLENSB;
    retval = false;
  }

  if (m_polname.IsEmpty()) {
    mess = _("Policy name cannot be blank");
    id = ID_POLICYNAME;
    retval = false;
  } else if ((m_polname != m_oldpolname &&
              (m_MapPSWDPLC.find(tostringx(m_polname)) != m_MapPSWDPLC.end()))) {
    mess = _("Policy name is already in use");
    id = ID_POLICYNAME;
    retval = false;
  }

  if (!retval) {
    wxMessageDialog md(this, mess, _("Policy Error"), wxOK | wxICON_ERROR);
    md.ShowModal();
    if (id != 0)
      FindWindow(id)->SetFocus();
  }
  return retval;
}
Ejemplo n.º 15
0
bool DbSelectionPanel::DoValidation()
{
  //the data has not been transferred from the window to our members yet, so get them from the controls
  if (wxWindow::Validate()) {

    wxFileName wxfn(m_filepicker->GetPath());
    
    //Did the user enter a valid file path
    if (!wxfn.FileExists()) {
      wxMessageBox( _("File or path not found."), _("Error"), wxOK | wxICON_EXCLAMATION, this);
      return false;
    }
    
    //Did he enter the same file that's currently open?
    if (wxfn.SameAs(wxFileName(towxstring(m_core->GetCurFile())))) {
      // It is the same damn file
      wxMessageBox(_("That file is already open."), _("Error"), wxOK | wxICON_WARNING, this);
      return false;
    }
    
    StringX combination = m_sc->GetCombination();
    //Does the combination match?
    if (m_core->CheckPasskey(tostringx(wxfn.GetFullPath()), combination) != PWScore::SUCCESS) {
      wxString errmess(_("Incorrect passkey, not a PasswordSafe database, or a corrupt database. (Backup database has same name as original, ending with '~')"));
      wxMessageBox(errmess, _("Error"), wxOK | wxICON_ERROR, this);
      SelectCombinationText();
      return false;
    }
    
    return true;
    
  }
  else {
    return false;
  }
}
Ejemplo n.º 16
0
void CManagePasswordPolicies::OnCopyPasswordClick( wxCommandEvent& )
{
  PWSclipboard::GetInstance()->SetData(tostringx(m_passwordCtrl->GetValue()));
}
Ejemplo n.º 17
0
void CManagePasswordPolicies::UpdatePolicy(const wxString &polname, const PWPolicy &pol,
                                           CPP_FLAGS mode)
{
  if (polname == _("Default Policy"))
    m_st_default_pp = pol;
  else
    m_MapPSWDPLC[tostringx(polname)] = pol;
#ifdef NOTYET
    // Save changes for Undo/Redo
    PWPolicyChange st_change;
    st_change.flags = mode;
    st_change.name = policyname;
    st_change.st_pp_save = m_iSelectedItem != 0 ? m_mapIter->second : m_st_default_pp;
    switch (mode) {
    case CPP_ADD:
      break;
    case CPP_MODIFIED:
      break;
    case CPP_DELETE:
      break;
    default:
      ASSERT(0);
    }

    if (m_iSelectedItem != 0) {
      // Changed a named password policy
      PSWDPolicyMapIter iter_new = m_MapPSWDPLC.find(StringX(policyname.c_str()));
      if (iter_new == m_MapPSWDPLC.end())
        ASSERT(0);
      st_change.st_pp_new = iter_new->second;
    } else {
      // Changed the database default policy
      st_change.st_pp_new = m_st_default_pp;
    }
  if (m_iundo_pos != (int)m_vchanges.size() - 1) {
    // We did have changes that could have been redone
    // But not anymore - delete all these to add new change on the end
    m_vchanges.resize(m_iundo_pos + 1);
  }

  // Add new change
  m_vchanges.push_back(st_change);
  // Update pointer to the one that is next to be undone
  m_iundo_pos++;
  // Update buttons appropriately
  FindWindow(wxID_UNDO)->Enable(true);
  FindWindow(wxID_REDO)->Enable(false);
#else
  UNREFERENCED_PARAMETER(mode);
#endif
  // Update lists
  UpdateNames();
  int N = m_PolicyNames->GetNumberRows();
  for (int row = 0; row < N; row++)
    if (m_PolicyNames->GetCellValue(row, 0) == polname) {
      m_PolicyNames->SelectRow(row);
      break;
    }

  UpdateDetails();
}
Ejemplo n.º 18
0
void PasswordSafeFrame::OnRestoreSafe(wxCommandEvent& /*evt*/)
{
  if (SaveIfChanged() != PWScore::SUCCESS)
    return;

  const wxFileName currbackup(towxstring(PWSprefs::GetInstance()->GetPref(PWSprefs::CurrentBackup)));

  wxString dir;
  if (m_core.GetCurFile().empty())
    dir = towxstring(PWSdirs::GetSafeDir());
  else {
    wxFileName::SplitPath(towxstring(m_core.GetCurFile()), &dir, NULL, NULL);
    wxCHECK_RET(!dir.IsEmpty(), _("Could not parse current file path"));
  }

  //returns empty string if user cancels
  wxString wxbf = wxFileSelector(_("Please Choose a Backup to Restore:"),
                                 dir,
                                 currbackup.GetFullName(),
                                 wxT("bak"),
                                 _("Password Safe Backups (*.bak)|*.bak|Password Safe Intermediate Backups (*.ibak)|*.ibak||"),
                                 wxFD_OPEN|wxFD_FILE_MUST_EXIST,
                                 this);
  if (wxbf.empty())
    return;

#ifdef NOT_YET
  if (m_inExit) {
    // If U3ExitNow called while in CPWFileDialog,
    // PostQuitMessage makes us return here instead
    // of exiting the app. Try resignalling
    PostQuitMessage(0);
    return PWScore::USER_CANCEL;
  }
#endif

  CSafeCombinationPrompt pwdprompt(this, m_core, wxbf);
  if (pwdprompt.ShowModal() == wxID_OK) {
    const StringX passkey = pwdprompt.GetPassword();
    // unlock the file we're leaving
    if (!m_core.GetCurFile().empty()) {
      m_core.UnlockFile(m_core.GetCurFile().c_str());
    }

    // Reset core and clear ALL associated data
    m_core.ReInit();

    // clear the application data before restoring
    ClearAppData();

    if (m_core.ReadFile(tostringx(wxbf), passkey, true, MAXTEXTCHARS) == PWScore::CANT_OPEN_FILE) {
      wxMessageBox(wxbf << wxT("\n\n") << _("Could not open file for reading!"),
                      _("File Read Error"), wxOK | wxICON_ERROR, this);
      return /*PWScore::CANT_OPEN_FILE*/;
    }

    m_core.SetCurFile(wxEmptyString);    // Force a Save As...
    m_bRestoredDBUnsaved = true; // So that the restored file will be saved

    SetTitle(_("Password Safe - <Untitled Restored Backup>"));

#ifdef NOT_YET
    app.SetTooltipText(L"PasswordSafe");
#endif

#ifdef NOT_YET
    ChangeOkUpdate();
#endif

    RefreshViews();
  }
}