Subversion Repositories spk

Rev

Rev 224 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include "../StdAfx.h"
#include "ExtractDialog.h"

#include "FileExists.h"

namespace SpkExplorer {
        void ExtractDialog::Background_DoWork(System::Object ^Sender, DoWorkEventArgs ^E)
        {
                System::Threading::Thread::Sleep(5);
                switch ( m_iWorkingStatus )
                {
                        case WORKER_READ:
                                if ( m_pMultiPackage )
                                {
                                        if ( !m_pMultiPackage->ReadSpk(m_pWorkingPackage, SPKREAD_ALL) )
                                                m_sFailed = "Reading";
                                }
                                else
                                {
                                        if ( m_iGame != -1 ) {
                                                if ( m_pWorkingFile->game() && !(m_pWorkingFile->game() & (1 << m_iGame))) {
                                                        m_iWorkingStatus = WORKER_WRITE;
                                                        break;
                                                }
                                                else if ( !m_iGame && m_pWorkingFile->game() ) {
                                                        m_iWorkingStatus = WORKER_WRITE;
                                                        break;
                                                }
                                        }

                                        if ( !m_pPackage->ReadFileToMemory(m_pWorkingFile) )
                                                m_sFailed = "Reading";
                                }
                                break;
                        case WORKER_UNCOMPRESS:
                                {
                                        if ( !m_pMultiPackage )
                                        {
                                                long size = 0;
                                                if ( m_pWorkingFile->GetDataSize() ) {
                                                        m_pUncompressData = m_pWorkingFile->UncompressData(&size, 0);
                                                        if ( !size || !m_pUncompressData )
                                                                m_sFailed = "Uncompressing";
                                                }
                                                m_iUncompressSize = size;
                                        }
                                }
                                break;
                        case WORKER_WRITE:
                                {
                                        Utils::WString sToDir = _WS(m_sToDir);
                                        if ( m_pMultiPackage )
                                        {
                                                if ( !m_pMultiPackage->extractFile(m_pWorkingPackage, sToDir) )
                                                        m_sFailed = "Writing";
                                        }
                                        else
                                        {
                                                // check for addon directory
                                                if (m_pWorkingFile->isFileInAddon())
                                                {
                                                        unsigned int game = m_iGame;
                                                        if (game <= 0)
                                                        {
                                                                unsigned int checkGame = m_pWorkingFile->game() & ~GAME_ALLNEW;
                                                                for (int i = 0; i < 31; ++i)
                                                                {
                                                                        if (checkGame == (1 << i))
                                                                        {
                                                                                game = i;
                                                                                break;
                                                                        }
                                                                }
                                                        }

                                                        if (game > 0)
                                                        {
                                                                SGameExe *exe = _pPackages->GetGameExe()->game(game - 1);
                                                                if (exe && !exe->sAddon.empty())
                                                                        sToDir += L"/" + exe->sAddon;
                                                        }
                                                }

                                                if ( !CDirIO(sToDir + L"/" + m_pWorkingFile->getDirectory(NULL)).exists() )
                                                {
                                                        if ( !CDirIO(sToDir + L"/" + m_pWorkingFile->getDirectory(NULL)).create() )
                                                        {
                                                                m_sFailed = "Creating Directory";
                                                                break;
                                                        }
                                                }

                                                if ( !m_pWorkingFile->writeToFile(CFileIO(sToDir + L"/" + m_pWorkingFile->getNameDirectory(NULL)).fullFilename(), m_pUncompressData, m_iUncompressSize) )
                                                        m_sFailed = "Writing";
                                                else
                                                        m_iExtractCount++;
                                        }
                                }
                                break;
                }
        }

        void ExtractDialog::DoNextFile()
        {
                ++m_iCount;
                this->progressBar1->Value = m_iCount;

                bool finished = false;
                if ( m_pMultiPackage )
                {
                        m_pWorkingPackage = m_pMultiList->Next();
                        if ( !m_pWorkingPackage )
                                finished = true;
                }
                else
                {
                        m_pWorkingFile = m_pList->Next();
                        if ( !m_pWorkingFile )
                                finished = true;
                }

                if ( !finished )
                {
                        this->UpdateDisplay();
                        this->StartWork(WORKER_READ);
                }
                else
                        this->Finished();
        }

        void ExtractDialog::Background_Finished(System::Object ^Sender, RunWorkerCompletedEventArgs ^E)
        {
                if ( m_sFailed->Length )
                {
                        if ( m_pMultiPackage )
                                m_pFailedList->pushBack(m_pWorkingPackage->sName, _WS(m_sFailed));
                        else
                                m_pFailedList->pushBack(m_pWorkingFile->getNameDirectory(NULL), _WS(m_sFailed));
                }

                if ( m_iWorkingStatus == WORKER_WRITE || m_sFailed->Length )
                        this->DoNextFile();
                else
                        this->StartWork(m_iWorkingStatus + 1);
        }

        void ExtractDialog::Finished()
        {
                m_bOK = true;
                if ( !m_pFailedList->empty() )
                {
                        Utils::WString s;
                        for (auto itr = m_pFailedList->begin(); itr != m_pFailedList->end(); itr++)
                                s += (*itr)->str + L" (" + (*itr)->data + L")\n";
                        MessageBox::Show(this, "Error Extracting Files:\n\n" + _US(s), "Extract Error", MessageBoxButtons::OK, MessageBoxIcon::Error);
                        m_bOK = false;
                }

                this->Close();
        }

        bool ExtractDialog::CheckExists(System::String ^file)
        {
                if ( m_bYesToAll )
                        return true;

                if ( !System::IO::File::Exists(file) )
                        return true;

                if ( m_bNoToAll )
                        return false;

                Utils::WString sFile = _WS(file);
                sFile = sFile.findReplace(L"/", L"\\");
                FileExists ^exists = gcnew FileExists(_US(sFile));
                System::Windows::Forms::DialogResult result = exists->ShowDialog(this);
                if ( result == System::Windows::Forms::DialogResult::Yes )
                        return true;
                else if ( result == System::Windows::Forms::DialogResult::Cancel )
                {
                        m_bCancel = true;
                        this->Close();
                        return false;
                }
                else if ( result == System::Windows::Forms::DialogResult::No )
                        return false;
                else if ( result == System::Windows::Forms::DialogResult::Ignore )
                {
                        m_bNoToAll = true;
                        return false;
                }
                else if ( result == System::Windows::Forms::DialogResult::OK )
                {
                        m_bYesToAll = true;
                        return true;
                }

                return false;
        }

        void ExtractDialog::StartWork(int status)
        {
                m_iWorkingStatus = status;
                bool start = true;
                switch ( m_iWorkingStatus )
                {
                        case WORKER_READ:
                                {
                                        String ^checkFile;
                                        if ( m_pMultiPackage )
                                                checkFile = m_sToDir + "/" + _US(m_pWorkingPackage->sName);
                                        else
                                                checkFile = m_sToDir + "/" + _US(m_pWorkingFile->getNameDirectory(NULL));
                                        if ( !this->CheckExists(checkFile) )
                                        {
                                                start = false;
                                                if ( !m_bCancel )
                                                        this->DoNextFile();
                                                break;
                                        }
                                        this->LabStatus->Text = "Reading file to memory";
                                }
                                break;
                        case WORKER_UNCOMPRESS:
                                this->LabStatus->Text = "Uncompressing...";
                                break;
                        case WORKER_WRITE:
                                this->LabStatus->Text = "Writing File...";
                                break;
                        default:
                                start = false;
                }

                if ( start )
                {
                        m_sFailed = "";
                        backgroundWorker1->RunWorkerAsync();
                }
        }


        void ExtractDialog::UpdateDisplay()
        {
                Utils::WString sToDir = _WS(m_sToDir);

                int max = 0;
                if ( m_pMultiPackage )
                        max = m_pMultiList->size();
                else
                        max = m_pList->size();

                this->Text = "Extracting Files [" + (m_iCount + 1) + "/" + max + "]";

                Utils::WString filename;
                if ( m_pMultiPackage )
                        filename = sToDir + L"/" + m_pWorkingPackage->sName;
                else
                        filename = sToDir + L"/" + m_pWorkingFile->getNameDirectory(NULL);

                Utils::WString displayFilename = filename;
                displayFilename = displayFilename.findReplace("/", "\\");
                this->LabFilename->Text = _US(displayFilename);

                if ( m_pMultiPackage )
                        this->LabSize->Text = _US(SPK::GetSizeString(m_pWorkingPackage->lSize));
                else
                        this->LabSize->Text = _US(m_pWorkingFile->uncompressedSizeString());
                this->LabStatus->Text = "Waiting";
        }

        void ExtractDialog::Start()
        {
                if ( m_pMultiPackage )
                {
                        this->progressBar1->Maximum = m_pMultiList->size();
                        m_pWorkingPackage = m_pMultiList->First();
                }
                else
                {
                        this->progressBar1->Maximum = m_pList->size();
                        m_pWorkingFile = m_pList->First();
                }
                this->progressBar1->Value = 0;

                m_iCount = 0;
                this->UpdateDisplay();
                this->StartWork(WORKER_READ);
        }
}