Subversion Repositories spk

Rev

Rev 18 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include "../StdAfx.h"
#include "SpkForm.h"

#include "Form1.h"
#include "ExtractDialog.h"
#include "AddDialog.h"
#include "DropFileDialog.h"

#include "..\..\Creator\src\Forms\SelectGame.h"

#include <spk.h>

using namespace System::Windows;
using namespace System::Windows::Forms;

namespace SpkExplorer {
        void SpkForm::SetPackage(CBaseFile *p, System::String ^filename)
        {
                this->splitContainer1->Panel1Collapsed = true;
                m_pPackage = p;

                m_pTabPage->Text = System::IO::FileInfo(filename).Name;
                if ( p->GetFilename().Empty() )
                        p->SetFilename(CyStringFromSystemString(filename));
                this->UpdateView(false);
                m_pPackage->SetChanged(false);

                this->Text = filename;

                m_sFilename = filename;
        }

        void SpkForm::SetMultiPackage(CMultiSpkFile *p, System::String ^filename)
        {
                this->splitContainer1->Panel1Collapsed = false;
                m_pMultiPackage = p;

                m_pTabPage->Text = System::IO::FileInfo(filename).Name;
                if ( p->GetFilename().Empty() )
                        p->SetFilename(CyStringFromSystemString(filename));

                this->UpdateView(false);

                this->Text = filename;

                m_sFilename = filename;

                // read the icons
                for ( SMultiSpkFile *package = p->GetFileList()->First(); package; package = p->GetFileList()->Next() )
                {
                        if ( !package->pFile )
                                continue;
                        if ( package->pFile->GetIcon() )
                        {
                                package->pFile->ReadIconFileToMemory();
                                CyString sIconFile = CyStringFromSystemString(IO::Path::GetTempPath()) + "\\" + CFileIO(package->sName).GetBaseName() + "." + package->pFile->GetIconExt();
                                if ( package->pFile->ExtractFile(package->pFile->GetIcon(), CFileIO(sIconFile).GetFullFilename(), false) )
                                {
                                        String ^iconFile = SystemStringFromCyString(sIconFile);
                                        if ( IO::File::Exists(iconFile) )
                                        {
                                                String ^file = SystemStringFromCyString(package->sName);
                                                String ^ext = System::IO::FileInfo(iconFile).Extension;
                                                if ( !String::Compare(ext, "bmp", false) || !String::Compare(ext, "ico", false) )
                                                        this->imageList1->Images->Add(file, Bitmap::FromFile(iconFile));
                                                else
                                                {
                                                        Bitmap ^myBitmap = gcnew Bitmap(iconFile);
                                                        if ( myBitmap )
                                                                this->imageList1->Images->Add(file, myBitmap);
                                                }
                                        }
                                }
                        }
                }
        }

        bool SpkForm::CheckFilename(System::String ^filename)
        {
                if ( filename == m_sFilename )
                        return true;
                return false;
        }

        void SpkForm::UpdateView(bool onlyPackage)
        {
                m_bLoading = true;

                m_bSortingAsc = true;
                m_iSortingCol = 0;

                m_bSortingAsc2 = true;
                m_iSortingCol2 = 0;

                this->listView1->Items->Clear();

                if ( m_pPackage )
                {
                        int pos = 0;
                        for ( C_File *file = m_pPackage->GetFileList()->First(); file; file = m_pPackage->GetFileList()->Next() )
                        {
                                file->SetPos(pos++);
                                this->AddFile(file);
                        }
                }
                listView1->ArrangeIcons();
                
                this->listView1->AutoResizeColumns(ColumnHeaderAutoResizeStyle::HeaderSize);
                this->listView1->ListViewItemSorter = gcnew ListViewItemComparer(m_iSortingCol, !m_bSortingAsc);

                if ( m_pMultiPackage && !onlyPackage )
                {
                        this->listView2->Items->Clear();
                        int pos = 0;
                        for ( SMultiSpkFile *file = m_pMultiPackage->GetFileList()->First(); file; file = m_pMultiPackage->GetFileList()->Next() )
                        {
                                file->iPos = pos++;
                                this->AddMultiFile(file);
                        }
                        listView2->ArrangeIcons();

                        this->listView2->AutoResizeColumns(ColumnHeaderAutoResizeStyle::HeaderSize);
                        this->listView2->ListViewItemSorter = gcnew ListViewItemComparer(m_iSortingCol2, !m_bSortingAsc2);
                }


                m_bLoading = false;
        }

        void SpkForm::AddImage(System::String ^filename, ImageList ^list, System::String ^key)
        {
                System::ComponentModel::ComponentResourceManager^  resources = (gcnew System::ComponentModel::ComponentResourceManager(SpkForm::typeid));

                bool added = false;
                if ( filename->StartsWith("$RESOURCE:") )
                {
                        filename = filename->Remove(0, 10);
                        if ( filename->StartsWith("BITMAP:") )
                        {
                                filename = filename->Remove(0, 7);
                                System::Drawing::Bitmap ^bitmap = (cli::safe_cast<System::Drawing::Bitmap^  >(resources->GetObject(filename)));
                                if ( bitmap )
                                {
                                        IntPtr Hicon = bitmap->GetHicon();
                                        System::Drawing::Icon ^newIcon = ::Icon::FromHandle(Hicon);
                                        list->Images->Add(key, newIcon);
                                        added = true;
                                }
                        }
                        else
                        {
                                System::Drawing::Icon ^icon = (cli::safe_cast<System::Drawing::Icon^  >(resources->GetObject(filename)));
                                list->Images->Add(key, icon);
                                added = true;
                        }
                }
                else if ( filename->StartsWith("$IMAGELIST:") )
                {
                        filename = filename->Remove(0, 11);
                        int index = this->imageList1->Images->IndexOfKey(filename);
                        if ( index != -1 )
                        {
                                list->Images->Add(key, this->imageList1->Images[index]);
                                added = true;
                        }
                }
                else if ( System::IO::File::Exists(filename) )
                {
                        CyString sF = CyStringFromSystemString(filename);
                        if ( CFileIO(sF).CheckFileExtension("bmp") )
                        {
                                list->Images->Add(key, Bitmap::FromFile(filename));
                                added = true;
                        }
                        else
                        {
                                Bitmap ^myBitmap = gcnew Bitmap(filename);
                                if ( myBitmap )
                                {
                                        IntPtr Hicon = myBitmap->GetHicon();
                                        System::Drawing::Icon ^newIcon = ::Icon::FromHandle(Hicon);
                                        list->Images->Add(key, newIcon);
                                        added = true;
                                }
                        }
                }

                if ( !added )
                {
                        System::Drawing::Icon ^icon = (cli::safe_cast<System::Drawing::Icon^  >(resources->GetObject(L"$this.Icon")));
                        list->Images->Add(key, icon);
                }
        }

        void SpkForm::AddFile(C_File *file)
        {
                ListViewItem ^item = gcnew ListViewItem(SystemStringFromCyString(file->GetNameDirectory(NULL)));
                item->SubItems->Add(SystemStringFromCyString(file->GetUncompressedSizeString()));
                item->SubItems->Add(SystemStringFromCyString(file->GetFileTypeString()));

                item->SubItems->Add(SystemStringFromCyString(file->GetCreationTimeString()));

                item->Tag = SystemStringFromCyString(CyString::Number(file->GetPos()));

                item->ImageKey = SystemStringFromCyString(CyString::Number(file->GetFileType()));

                if ( !file->GetGame() ) {
                        item->SubItems->Add("All Games");
                }
                else {
                        CPackages p;
                        p.Startup(".", ".", ".");
                        SGameExe *exe = p.GetGameExe()->GetGame(file->GetGame() - 1);
                        if ( exe ) {
                                item->SubItems->Add(SystemStringFromCyString(exe->sName));
                        }
                        else {
                                item->SubItems->Add("Game: " + file->GetGame());
                        }
                }

                this->listView1->Items->Add(item);
        }

        void SpkForm::AddMultiFile(SMultiSpkFile *file)
        {
                ListViewItem ^item = gcnew ListViewItem(SystemStringFromCyString(file->sName));
                if ( file->iType == TYPE_XSP )
                        item->SubItems->Add("Ship");
                else
                        item->SubItems->Add("Package");
                item->SubItems->Add(SystemStringFromCyString(SPK::GetSizeString(file->lSize)));


                item->Tag = SystemStringFromCyString(CyString::Number(file->iPos));

                if ( this->imageList1->Images->IndexOfKey(SystemStringFromCyString(file->sName)) == -1 )
                        item->ImageKey = "package";
                else
                        item->ImageKey = SystemStringFromCyString(file->sName);

                this->listView2->Items->Add(item);
        }

        System::Void SpkForm::Event_Activated(System::Object^  sender, System::EventArgs^  e)
        {
                m_pTabCtrl->SelectedTab = m_pTabPage;
                this->Text = m_pTabPage->Text;

                ((Form1 ^)this->MdiParent)->UpdateDisplay();

                this->SelectedCheck();
        }

        System::Void SpkForm::Event_Closing(System::Object^  sender, CancelEventArgs^  e)
        {
                delete m_pPackage;
                delete m_pTabPage;

                m_sFilename = "";

                ((Form1 ^)this->MdiParent)->RemoveCopied(true);

                ((Form1 ^)this->MdiParent)->UpdateDisplay();
                ((Form1 ^)this->MdiParent)->SelectedFile(false);
        }

        void SpkForm::SelectedCheck()
        {
                if ( m_pMultiPackage )
                {
                        ((Form1 ^)this->MdiParent)->SelectedPackage(this->IsSelected(), this->IsPackageSelected());
                        if ( this->IsPackageSelected() )
                        {
                                Point ^mousePoint = this->listView2->PointToClient(this->listView2->MousePosition);
                                ListViewItem ^item = this->listView2->GetItemAt(mousePoint->X, mousePoint->Y);
                                if ( item )
                                {
                                        int num = System::Convert::ToInt32(item->Tag);
                                        m_pSelectedPackage = m_pMultiPackage->GetFileList()->Get(num);
                                        if ( m_pSelectedPackage )
                                        {
                                                m_pPackage = m_pSelectedPackage->pFile;
                                                this->UpdateView(true);
                                        }
                                }
                        }
                        else
                        {
                                m_pPackage = NULL;
                                m_pSelectedPackage = NULL;
                                this->UpdateView(true);
                        }
                }
                else
                        ((Form1 ^)this->MdiParent)->SelectedFile(this->IsSelected());
        }

        bool SpkForm::IsSelected()
        {
                if ( this->listView1->SelectedItems->Count )
                        return true;
                return false;
        }

        bool SpkForm::IsPackageSelected()
        {
                if ( this->listView2->SelectedItems->Count )
                        return true;
                return false;
        }

        void SpkForm::DoExtract(CLinkList<C_File> *list, System::String ^toDir, int game)
        {
                if ( !toDir )
                        return;


                // read the spk file to memory before trying to extract its files
                if ( !this->ReadMultiPackage() )
                        return;

                ExtractDialog ^ed = gcnew ExtractDialog(list, toDir, m_pPackage, game);
                ed->ShowDialog((Form1 ^)this->MdiParent);

                if ( ed->OK() && !ed->Canceled() && ed->ExtractedCount() )
                        MessageBox::Show(this, "Files have been extracting successfully to:\n" + toDir, "Extacted", MessageBoxButtons::OK, MessageBoxIcon::Information);
        }

        bool SpkForm::ReadSelectedMultiPackage()
        {
                if ( m_pMultiPackage && m_pSelectedPackage )
                {
                        if ( !m_pMultiPackage->ReadSpk(m_pSelectedPackage, SPKREAD_ALL) )
                                return false;
                }

                return true;
        }
        bool SpkForm::ReadMultiPackage()
        {
                if ( m_pMultiPackage )
                {
                        if ( !m_pMultiPackage->ReadAllPackages(SPKREAD_ALL) )
                                return false;
                }

                return true;
        }
        void SpkForm::DoPackageExtract(CLinkList<SMultiSpkFile> *list, System::String ^toDir)
        {
                if ( !toDir )
                        return;

                ExtractDialog ^ed = gcnew ExtractDialog(list, toDir, m_pMultiPackage);
                ed->ShowDialog((Form1 ^)this->MdiParent);

                if ( ed->OK() && !ed->Canceled() )
                        MessageBox::Show(this, "Files have been extracting successfully to:\n" + toDir, "Extacted", MessageBoxButtons::OK, MessageBoxIcon::Information);
        }

        System::String ^SpkForm::GetExtractDir(bool package)
        {
                FolderBrowserDialog ^fbd = gcnew FolderBrowserDialog;
                if ( package )
                        fbd->Description = "Select the path to extract packages to";
                else
                        fbd->Description = "Select the path to extract files to";
                if ( fbd->ShowDialog(this) == System::Windows::Forms::DialogResult::OK )
                        return fbd->SelectedPath;

                return nullptr;
        }

        void SpkForm::ExtractSelected(System::String ^toDir)
        {
                if ( !m_pPackage )
                        return;

                CyString sToDir = CyStringFromSystemString(toDir);

                CLinkList<C_File> list;

                for ( int i = 0; i < this->listView1->SelectedItems->Count; i++ )
                {
                        int pos = CyStringFromSystemString(cli::safe_cast<System::String ^>(this->listView1->SelectedItems[i]->Tag)).ToInt();
                        C_File *f = m_pPackage->GetFileList()->Get(pos);
                        list.push_back(f);
                }

                this->DoExtract(&list, toDir, -1);
                list.clear();
        }

        void SpkForm::ExtractSelectedPackage(System::String ^toDir)
        {
                if ( !m_pMultiPackage )
                        return;

                CyString sToDir = CyStringFromSystemString(toDir);

                CLinkList<SMultiSpkFile> list;

                for ( int i = 0; i < this->listView2->SelectedItems->Count; i++ )
                {
                        int pos = CyStringFromSystemString(cli::safe_cast<System::String ^>(this->listView2->SelectedItems[i]->Tag)).ToInt();
                        SMultiSpkFile *mp = m_pMultiPackage->GetFileList()->Get(pos);
                        if ( mp )
                                list.push_back(mp);
                }

                this->DoPackageExtract(&list, toDir);
                list.clear();
        }

        void SpkForm::RemoveItem(ListViewItem ^item)
        {
                if ( !item )
                        return;

                AddDialog ^ad = gcnew AddDialog(m_pPackage, m_pMultiPackage);
                ad->SetRemove();

                int pos = CyStringFromSystemString(cli::safe_cast<System::String ^>(item->Tag)).ToInt();
                C_File *f = m_pPackage->GetFileList()->Get(pos);
                if ( f )
                        ad->AddFile(SystemStringFromCyString(f->GetName()), SystemStringFromCyString(f->GetDir()), f->GetFileType(), f->GetGame());

                // remove the dat or cat file as well
                if ( f->GetFileType() == FILETYPE_MOD )
                {
                        if ( f->CheckFileExt("cat") )
                        {
                                C_File *datFile = m_pPackage->FindFile(CFileIO(f).ChangeFileExtension("dat"), FILETYPE_MOD, "", f->GetGame());
                                if ( datFile )
                                        ad->AddFile(SystemStringFromCyString(datFile->GetName()), SystemStringFromCyString(datFile->GetDir()), datFile->GetFileType(), datFile->GetGame());
                        }
                        else if ( f->CheckFileExt("dat") )
                        {
                                C_File *datFile = m_pPackage->FindFile(CFileIO(f).ChangeFileExtension("cat"), FILETYPE_MOD, "", f->GetGame());
                                if ( datFile )
                                        ad->AddFile(SystemStringFromCyString(datFile->GetName()), SystemStringFromCyString(datFile->GetDir()), datFile->GetFileType(), datFile->GetGame());
                        }
                }
                ad->ShowDialog(this);
                this->UpdateView(true);
        }
        void SpkForm::RemoveSelected()
        {
                if ( !m_pPackage )
                        return;

                AddDialog ^ad = gcnew AddDialog(m_pPackage, m_pMultiPackage);
                ad->SetRemove();

                for ( int i = 0; i < this->listView1->SelectedItems->Count; i++ )
                {
                        int pos = CyStringFromSystemString(cli::safe_cast<System::String ^>(this->listView1->SelectedItems[i]->Tag)).ToInt();
                        C_File *f = m_pPackage->GetFileList()->Get(pos);
                        if ( f )
                                ad->AddFile(SystemStringFromCyString(f->GetName()), SystemStringFromCyString(f->GetDir()), f->GetFileType(), f->GetGame());

                        // remove the dat or cat file as well
                        if ( f->GetFileType() == FILETYPE_MOD )
                        {
                                if ( f->CheckFileExt("cat") )
                                {
                                        C_File *datFile = m_pPackage->FindFile(CFileIO(f).ChangeFileExtension("dat"), FILETYPE_MOD, "", f->GetGame());
                                        if ( datFile )
                                                ad->AddFile(SystemStringFromCyString(datFile->GetName()), SystemStringFromCyString(datFile->GetDir()), datFile->GetFileType(), datFile->GetGame());
                                }
                                else if ( f->CheckFileExt("dat") )
                                {
                                        C_File *datFile = m_pPackage->FindFile(CFileIO(f).ChangeFileExtension("cat"), FILETYPE_MOD, "", f->GetGame());
                                        if ( datFile )
                                                ad->AddFile(SystemStringFromCyString(datFile->GetName()), SystemStringFromCyString(datFile->GetDir()), datFile->GetFileType(), datFile->GetGame());
                                }
                        }
                }

                ad->ShowDialog(this);

                this->UpdateView(true);
        }

        void SpkForm::RemoveSelectedPackage()
        {
                if ( !m_pMultiPackage )
                        return;

                AddDialog ^ad = gcnew AddDialog(NULL, m_pMultiPackage);
                ad->SetRemove();

                for ( int i = 0; i < this->listView2->SelectedItems->Count; i++ )
                {
                        int pos = System::Convert::ToInt32(this->listView2->SelectedItems[i]->Tag);
                        SMultiSpkFile *mp = m_pMultiPackage->GetFileList()->Get(pos);
                        if ( mp )
                                ad->AddFile(SystemStringFromCyString(mp->sName), "", -1, 0);
                }

                if ( ad->AnyFiles() )
                {
                        ad->ShowDialog(this);
                        this->UpdateView(false);
                }
        }

        void SpkForm::ExtractAll(System::String ^toDir)
        {
                int game = 0;
                if ( m_pPackage->IsMultipleGamesInPackage() ) {
                        Creator::SelectGame ^selGame = gcnew Creator::SelectGame("Select game to extract", NULL);
                        if ( selGame->ShowDialog(this) == Windows::Forms::DialogResult::OK ) {
                                game = selGame->GetGame() + 1;
                        }
                        else
                                return;

                }
                else if ( m_pPackage->IsAnyGameInPackage() ) {
                        game = m_pPackage->FindFirstGameInPackage();
                }
                this->DoExtract(m_pPackage->GetFileList(), toDir, game);
        }

        void SpkForm::ExtractAllPackage(System::String ^toDir)
        {
                if ( !m_pMultiPackage )
                        return;
                this->DoPackageExtract(m_pMultiPackage->GetFileList(), toDir);
        }

        System::Void SpkForm::DragEnterEvent(System::Object ^Sender, DragEventArgs ^E)
        {
                E->Effect = DragDropEffects::None;

                if ( !m_pPackage )
                        return;

                if ( ((Form1 ^)this->MdiParent)->DragFromForm() && ((Form1 ^)this->MdiParent)->DragFromForm() != this )
                {
                        if ((E->KeyState & 4) == 4 && (E->AllowedEffect & DragDropEffects::Move) == DragDropEffects::Move) 
                                E->Effect = DragDropEffects::Move;
                        else if ((E->KeyState & 8) == 8 && (E->AllowedEffect & DragDropEffects::Copy) == DragDropEffects::Copy) 
                                E->Effect = DragDropEffects::Copy;
                        else if ((E->AllowedEffect & DragDropEffects::Move) == DragDropEffects::Move)  
                                E->Effect = DragDropEffects::Move;
                }
                else if ( E->Data->GetDataPresent(DataFormats::FileDrop) )
                        E->Effect = DragDropEffects::Copy;
        }

        void SpkForm::DropGetDirectories(String ^dir, CyStringList *list, bool packages)
        {
                cli::array<String ^> ^dirList = IO::Directory::GetFileSystemEntries(dir);
                for ( int j = 0; j < dirList->Length; j++ )
                {
                        if ( IO::DirectoryInfo(dirList[j]).Exists )
                                this->DropGetDirectories(dirList[j], list, packages);
                        else
                        {
                                if ( packages )
                                        list->PushBack(CyStringFromSystemString(dirList[j]), "-1");
                                else
                                        list->PushBack(CyStringFromSystemString(dirList[j]), CyString::Number(SPK::GetAutomaticFiletype(CyStringFromSystemString(dirList[j]), NULL, false)));
                        }
                }
        }

        System::Void SpkForm::listView2_DragDrop(System::Object^  sender, System::Windows::Forms::DragEventArgs^  E)
        {
                if ( !m_pMultiPackage )
                        return;

                if ( E->Data->GetDataPresent(DataFormats::FileDrop) )
                {
                        CyStringList fileList;
                        cli::array<String ^> ^a = (cli::array<String ^> ^)E->Data->GetData(DataFormats::FileDrop, false);
                        int i;
                        for(i = 0; i < a->Length; i++)
                        {
                                if ( IO::DirectoryInfo(a[i]).Exists )
                                        this->DropGetDirectories(a[i], &fileList, true);
                                else
                                        fileList.PushBack(CyStringFromSystemString(a[i]), "-1");
                        }

                        // remove invalid files
                        if ( !fileList.Empty() )
                        {
                                AddDialog ^ad = gcnew AddDialog(NULL, m_pMultiPackage);
                                for ( SStringList *str = fileList.Head(); str; str = str->next )
                                {
                                        if ( str->data != "-1" )
                                                continue;

                                        CyString ext = CFileIO(str->str).GetFileExtension();
                                        if ( !ext.Compare("xsp") && !ext.Compare("spk") )
                                                continue;
                                        
                                        ad->AddFile(SystemStringFromCyString(str->str), "", -1, 0);
                                }

                                ad->ShowDialog(this);
                                this->UpdateView(false);
                        }
                }
        }

        System::Void SpkForm::listView1_DragDrop(System::Object^  sender, System::Windows::Forms::DragEventArgs^ E)
        {
                // dropping from outside
                if ( E->Data->GetDataPresent(DataFormats::FileDrop) )
                {
                        CyStringList fileList;
                        cli::array<String ^> ^a = (cli::array<String ^> ^)E->Data->GetData(DataFormats::FileDrop, false);
                        int i;
                        for(i = 0; i < a->Length; i++)
                        {
                                if ( IO::DirectoryInfo(a[i]).Exists )
                                        this->DropGetDirectories(a[i], &fileList, false);
                                else
                                        fileList.PushBack(CyStringFromSystemString(a[i]), CyString::Number(SPK::GetAutomaticFiletype(CyStringFromSystemString(a[i]), NULL, false)));
                        }

                        SPK::AssignAutomaticFiletypes(&fileList);

                        if ( !fileList.Empty() )
                        {
                                DropFileDialog ^dropType = gcnew DropFileDialog(&fileList);
                                if ( dropType->ShowDialog(this) == Forms::DialogResult::OK )
                                {
                                        AddDialog ^ad = gcnew AddDialog(m_pPackage, NULL);
                                        for ( SStringList *str = fileList.Head(); str; str = str->next )
                                        {
                                                int type = str->data.GetToken(" ", 1, 1).ToInt();
                                                if ( type == -1 )
                                                        continue;
                                                ad->AddFile(SystemStringFromCyString(str->str), "", type, 0);
                                        }
                                        if ( ad->AnyFiles() )
                                        {
                                                ad->ShowDialog(this);
                                                this->UpdateView(false);
                                        }
                                }
                        }
                        return;
                }

                bool copy = false;
                
                if ((E->KeyState & 8) == 8 && (E->AllowedEffect & DragDropEffects::Copy) == DragDropEffects::Copy) 
                        copy = true;

                ((Form1 ^)this->MdiParent)->Dragged(this, copy);
        }

        System::Void SpkForm::ItemDragEvent(System::Object ^Sender, ItemDragEventArgs ^E)
        {
                if ( this->listView1->SelectedItems->Count )
                {
                        ListView::SelectedListViewItemCollection^ selected = this->listView1->SelectedItems;
                        System::Collections::IEnumerator^ myEnum = selected->GetEnumerator();
                        ArrayList ^list = gcnew ArrayList();
                        while ( myEnum->MoveNext() )
                        {
                                C_File *f = this->GetFileFromItem(safe_cast<ListViewItem ^>(myEnum->Current));
                                ((Form1 ^)this->MdiParent)->DragFile(f, this);
                                //f->GetFilePointer()
                                list->Add(safe_cast<ListViewItem ^>(myEnum->Current)->Text);
                        }

                        DataObject ^data = gcnew DataObject(DataFormats::FileDrop, list);

                        for ( int i = 0; i < list->Count; i++ )
                                data->SetData(DataFormats::StringFormat, Convert::ToString(list[i]));

                        this->listView1->DoDragDrop(data, DragDropEffects::Move | DragDropEffects::Copy);
                }               
        }

        System::Void SpkForm::OpenContextMenu(System::Object ^Sender, CancelEventArgs ^E)
        {
                ListViewItem ^item = this->FindSelectedItem();
                if ( item )
                {
                        m_pListItem = item;
                        this->ContextName->Text = System::IO::FileInfo(item->Text).Name;
                        if ( item->ImageKey )
                        {
                                int key = this->listView1->LargeImageList->Images->IndexOfKey(item->ImageKey);
                                if ( key != -1 )
                                        this->ContextName->Image = this->listView1->LargeImageList->Images[key];
                        }

                        if ( ((Form1 ^)this->MdiParent)->CopiedFiles()->empty() )
                                this->ToolPaste->Enabled = false;
                        else
                                this->ToolPaste->Enabled = true;

                        E->Cancel = false;
                }
                else
                        E->Cancel = true;

        }

        ListViewItem ^SpkForm::FindSelectedItem()
        {
                Point ^mousePoint = this->listView1->PointToClient(this->contextMenuStrip1->MousePosition);
                return  this->listView1->GetItemAt(mousePoint->X, mousePoint->Y);
        }

        C_File *SpkForm::GetFileFromItem(ListViewItem ^item)
        {
                int num = System::Convert::ToInt32(item->Tag);
                return m_pPackage->GetFileList()->Get(num);
        }

        void SpkForm::CopyFile()
        {
                if ( !m_pListItem )
                        return;
                C_File *f = this->GetFileFromItem(m_pListItem);
                if ( f )
                {
                        if ( m_pMultiPackage && m_pSelectedPackage )
                                m_pMultiPackage->ReadSpk(m_pSelectedPackage, SPKREAD_ALL);
                        else if ( !m_pMultiPackage )
                                m_pPackage->ReadFileToMemory(f);
                        else
                                return;

                        f = this->GetFileFromItem(m_pListItem);
                        ((Form1 ^)this->MdiParent)->CopyFile(f, true);
                }
        }

        void SpkForm::CutFile()
        {
                if ( !m_pListItem )
                        return;
                C_File *f = this->GetFileFromItem(m_pListItem);
                if ( f )
                {
                        if ( !this->ReadPackageFiles(false) )
                                return;
                        f = this->GetFileFromItem(m_pListItem);
                        if ( f )
                        {
                                ((Form1 ^)this->MdiParent)->CutFile(f, this, true);
                                m_pPackage->GetFileList()->remove(f, false);

                                this->WritePackage();
                                this->UpdateView(true);
                        }
                }
        }

        void SpkForm::DroppedFile(C_File *f)
        {
                if ( m_pPackage->GetFileList()->FindData(f) )
                        return;

                this->ReadPackageFiles(false);
                m_pPackage->AddFile(f);
                this->WritePackage();
                this->UpdateView(true);
        }

        void SpkForm::DraggedFile(C_File *f)
        {
                if ( !m_pPackage )
                        return;

                if ( !m_pPackage->GetFileList()->FindData(f) )
                        return;

                this->ReadPackageFiles(false);
                m_pPackage->GetFileList()->remove(f, false);
                this->WritePackage();
                this->UpdateView(true);
        }

        bool SpkForm::ReadPackageFiles(bool all)
        {
                if ( m_pMultiPackage )
                {
                        if ( all )
                        {
                                if ( !m_pMultiPackage->ReadAllPackages(SPKREAD_ALL) )
                                        return false;
                        }
                        else if ( m_pSelectedPackage )
                        {
                                if ( !m_pMultiPackage->ReadSpk(m_pSelectedPackage, SPKREAD_ALL) )
                                        return false;
                        }
                }
                else
                        m_pPackage->ReadAllFilesToMemory();
                return true;
        }

        void SpkForm::WritePackage()
        {
                if ( m_pMultiPackage )
                {
                        m_pMultiPackage->ReadAllPackages();
                        m_pMultiPackage->UpdatedPackage(m_pPackage);
                        m_pMultiPackage->WriteFile(m_pMultiPackage->GetFilename());
                }
                else
                        m_pPackage->WriteFile(m_pPackage->GetFilename());
        }

        void SpkForm::PasteFiles(CLinkList<C_File> *list)
        {
                if ( m_pMultiPackage && m_pSelectedPackage )
                        m_pMultiPackage->ReadSpk(m_pSelectedPackage, SPKREAD_ALL);
                else if ( !m_pMultiPackage )
                        m_pPackage->ReadAllFilesToMemory();
                else
                        return;

                for ( C_File *f = list->First(); f; f= list->Next() )
                {
                        // check if we copied this file already
                        if ( m_pPackage->GetFileList()->FindData(f) )
                                continue;

                        m_pPackage->AddFile(f);
                }
                ((Form1 ^)this->MdiParent)->PastedFiles();
                this->WritePackage();
                this->UpdateView(true);
        }

        void SpkForm::PasteFile()
        {
                if ( ((Form1 ^)this->MdiParent)->CopiedFiles()->empty() )
                        return;

                this->PasteFiles(((Form1 ^)this->MdiParent)->CopiedFiles());
        }

        void SpkForm::RestoreCut(CLinkList<C_File> *files)
        {
                for ( C_File *f = files->First(); f; f = files->Next() )
                        m_pPackage->AddFile(f);
                this->WritePackage();
                this->UpdateView(true);
        }

        void SpkForm::RunFile(ListViewItem ^item)
        {
                if ( !item )
                        return;

                C_File *f = this->GetFileFromItem(item);
                if ( !f )
                        return;

                if ( m_pMultiPackage && m_pSelectedPackage )
                {
                        m_pMultiPackage->ReadSpk(m_pSelectedPackage, SPKREAD_ALL);
                        C_File *f = this->GetFileFromItem(item);
                        if ( !f )
                                return;
                }

                Diagnostics::Process ^process = gcnew Diagnostics::Process();
                try {
                        process->StartInfo->WorkingDirectory = IO::Path::GetTempPath();

                        switch ( f->GetFileType() )
                        {
                                case FILETYPE_SCRIPT:
                                case FILETYPE_UNINSTALL:
                                        if ( m_pPackage->ExtractFile(f, CyStringFromSystemString(IO::Path::GetTempPath()), false) )
                                        {
                                                SPK::WriteScriptStyleSheet(CyStringFromSystemString(IO::Path::GetTempPath()));
                                                process->StartInfo->FileName = IO::Path::GetTempPath() + "\\" + SystemStringFromCyString(f->GetName());
                                        }
                                        break;

                                case FILETYPE_MOD:
                                        if ( m_pPackage->ExtractFile(f, CyStringFromSystemString(IO::Path::GetTempPath()), false) )
                                        {
                                                if ( f->CheckFileExt("cat") )
                                                {
                                                        C_File *datFile = m_pPackage->FindFile(CFileIO(f).ChangeFileExtension("dat"), FILETYPE_MOD, "");
                                                        if ( datFile )
                                                        {
                                                                if ( m_pPackage->ExtractFile(datFile, CyStringFromSystemString(IO::Path::GetTempPath()), false) )
                                                                        process->StartInfo->FileName = IO::Path::GetTempPath() + "\\" + SystemStringFromCyString(f->GetName());
                                                        }
                                                }
                                                else if ( f->CheckFileExt("dat") )
                                                {
                                                        C_File *catFile = m_pPackage->FindFile(CFileIO(f).ChangeFileExtension("cat"), FILETYPE_MOD, "");
                                                        if ( catFile )
                                                        {
                                                                if ( m_pPackage->ExtractFile(catFile, CyStringFromSystemString(IO::Path::GetTempPath()), false) )
                                                                        process->StartInfo->FileName = IO::Path::GetTempPath() + "\\" + SystemStringFromCyString(catFile->GetName());
                                                        }
                                                }
                                        }
                                        break;

                                case FILETYPE_MAP:
                                        break;

                                default:
                                        if ( m_pPackage->ExtractFile(f, CyStringFromSystemString(IO::Path::GetTempPath()), false) )
                                                process->StartInfo->FileName = IO::Path::GetTempPath() + "\\" + SystemStringFromCyString(f->GetName());
                        }

                        if ( process->StartInfo->FileName && process->StartInfo->FileName->Length )
                        {
                                process->StartInfo->CreateNoWindow = true;
                                process->Start();
                        }
                }
                catch (System::Exception ^E) 
                {
                        MessageBox::Show(this, "Error opening file:\n" + SystemStringFromCyString(f->GetName()) + "\n\nError: " + E->GetType()->Name, "Error", MessageBoxButtons::OK, MessageBoxIcon::Error);
                }
        }
}