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()); }