Esempio n. 1
0
void frmExtract::onExtract(wxCommandEvent &e)
{
  if(m_bIsDirectory)
  {
    RainString sFolder = m_pDestinationPath->GetValue();
    if(!_ensureDirectoryExists(sFolder))
        return;

    wxSizer *pMainSizer = GetSizer();
    if(m_pButtonsSizer)
    {
      FindWindow(wxID_OK)->Hide();
      FindWindow(wxID_CANCEL)->Hide();
      pMainSizer->Detach(m_pButtonsSizer);
    }
    pMainSizer->Add(new wxStaticLine(this), 0, wxEXPAND | wxALL, 4);
    wxGauge *pProgressBar = new wxGauge(this, wxID_ANY, 1, wxDefaultPosition, wxDefaultSize, wxGA_HORIZONTAL | wxGA_SMOOTH);
    wxStaticText *pCurrentItem = new wxStaticText(this, wxID_ANY, L"Initialising extraction...");
    pMainSizer->Add(pProgressBar, 0, wxEXPAND | wxALL, 2);
    pMainSizer->Add(pCurrentItem, 0, wxEXPAND | wxALL, 2);
    pMainSizer->RecalcSizes();
    SetSize(pMainSizer->GetMinSize());
    Layout();
    ::wxSafeYield(this);

    int iTotalCount = 1, iDoneCount = 0;
    std::queue<IDirectory*> qTodo;
    try
    {
      qTodo.push(m_pArchive->openDirectory(m_sPathToExtract));
      iTotalCount += static_cast<int>(qTodo.front()->getItemCount());
      size_t iSkipLength = qTodo.front()->getPath().length();
      pProgressBar->SetRange(iTotalCount);
      while(!qTodo.empty())
      {
        IDirectory *pDirectory = qTodo.front();
        pCurrentItem->SetLabel(pDirectory->getPath());
        pProgressBar->SetValue(++iDoneCount);
        ::wxSafeYield(this);

        RainString sDirectoryBase = pDirectory->getPath();
        sDirectoryBase = sFolder + sDirectoryBase.mid(iSkipLength, sDirectoryBase.length() - iSkipLength);
        if(!RainDoesDirectoryExist(sDirectoryBase))
          RainCreateDirectory(sDirectoryBase);
        for(IDirectory::iterator itr = pDirectory->begin(), itrEnd = pDirectory->end(); itr != itrEnd; ++itr)
        {
          if(itr->isDirectory())
          {
            IDirectory *pChild = itr->open();
            iTotalCount += 1 + static_cast<int>(pChild->getItemCount());
            qTodo.push(pChild);
            pProgressBar->SetRange(iTotalCount);
          }
          else
          {
            std::auto_ptr<IFile> pFile;
            pCurrentItem->SetLabel(pDirectory->getPath() + itr->name());
            pProgressBar->SetValue(++iDoneCount);
            ::wxSafeYield(this);
            pFile.reset(RainOpenFile(sDirectoryBase + itr->name(), FM_Write));
            itr->pump(&*pFile);
          }
        }

        delete pDirectory;
        qTodo.pop();
      }
    }
    catch(RainException *pE)
    {
      while(!qTodo.empty())
      {
        delete qTodo.front();
        qTodo.pop();
      }
      EXCEPTION_MESSAGE_BOX_1(L"Error extracting directory \'%s\'", m_sPathToExtract.getCharacters(), pE);
      SetReturnCode(GetEscapeId());
      return;
    }
  }
  else
  {
    wxFileName oFilename(m_pDestinationPath->GetValue());
    RainString sFolder = oFilename.GetPath();
    IFile *pFile = 0;
    try
    {
      if(!_ensureDirectoryExists(sFolder))
        return;
      pFile = RainOpenFile(m_pDestinationPath->GetValue(), FM_Write);
      m_pArchive->pumpFile(m_sPathToExtract, pFile);
    }
    catch(RainException *pE)
    {
      delete pFile;
      EXCEPTION_MESSAGE_BOX_1(L"Error extracting \'%s\'", m_sPathToExtract.getCharacters(), pE);
      return;
    }
    delete pFile;
  }
  wxString sMessage = L"Extracted " + m_sPathToExtract;
  if(m_pPositiveResultNoficiationBar)
    m_pPositiveResultNoficiationBar->SetStatusText(sMessage);
  else
    ::wxMessageBox(sMessage, GetLabel(), wxOK | wxCENTER | wxICON_INFORMATION, this);
  EndModal(GetAffirmativeId());
}