OSDN Git Service

改行文字やタブ文字を名前に含むファイルを含む書庫を開こうとした場合に警告する機能を追加。
[tpi/lychee.git] / src / lychee / frm_main.cpp
index 7b8104b..3a02ef6 100644 (file)
-/*******************************************************************************
-  TPI - flexible but useless plug-in framework.
-  Copyright (C) 2002-2009 Silky
-
-  This library is free software; you can redistribute it and/or modify it under
-  the terms of the GNU Lesser General Public License as published by the Free
-  Software Foundation; either version 2.1 of the License, or (at your option)
-  any later version.
-
-  This library is distributed in the hope that it will be useful, but WITHOUT
-  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
-  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
-  for more details.
-
-  You should have received a copy of the GNU Lesser General Public License along
-  with this library; if not, write to the Free Software Foundation, Inc.,
-  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-  $Id$
-*******************************************************************************/
-
-#include "lychee.h"
-
-#include "frm_main.h"
-#include "cls_filedroptarget.h"
-#include "dlg_make.h"
-#include "dlg_process.h"
-#include "functions.h"
-
-#include <wx/arrimpl.cpp>
-
-WX_DEFINE_OBJARRAY(ArrayTPI_FILEINFO);
-
-#define SetMenuToolState(id, state) this->toolbar->EnableTool(XRCID(id), state); this->menubar->Enable(XRCID(id), state)
-
-//******************************************************************************
-//    \83O\83\8d\81[\83o\83\8b\95Ï\90\94
-//******************************************************************************
-
-wxImageList g_hIconT(16, 16), g_hIconLL(32, 32), g_hIconLS(16, 16);
-int g_nSortColumn;
-bool g_fSortAscend;
-
-//******************************************************************************
-// MainFrame
-//******************************************************************************
-
-MainFrame::MainFrame(): wxFrame(), conf(wxEmptyString, wxEmptyString, L_DIR_BIN wxT("lychee.conf"), wxEmptyString, wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_RELATIVE_PATH)
-{
-}
-
-MainFrame::~MainFrame()
-{
-       wxCommandEvent e;
-       this->OnArcClose(e);
-
-       // \90Ý\92è\82ð\8bL\98^\81B
-       if (! this->IsIconized() && ! this->IsMaximized())
-       {
-               int a, b;
-               this->GetSize(& a, & b);
-               this->conf.Write(wxT("Window-Width"), a);
-               this->conf.Write(wxT("Window-Height"), b);
-               this->GetPosition(& a, & b);
-               this->conf.Write(wxT("Window-X"), a);
-               this->conf.Write(wxT("Window-Y"), b);
-       }
-       this->conf.Write(wxT("Splitter-Pos"), this->window_splitter->GetSashPosition());
-
-       // \83c\81[\83\8b\83o\81[/\83X\83e\81[\83^\83X\83o\81[\8aÖ\98A\81B
-       this->conf.Write(wxT("StatusBar-Show"), this->statusbar->IsShown());
-       this->conf.Write(wxT("ToolBar-Show"),   this->toolbar->IsShown());
-
-       // ListView\8aÖ\98A\81B
-       this->conf.Write(wxT("ListView-IconMode"), this->menubar->IsChecked(XRCID("Exe_View_Icons")) ? 1 : this->menubar->IsChecked(XRCID("Exe_View_List")) ? 2 : 0);
-       if (this->menubar->IsChecked(XRCID("Exe_View_Details")))
-       {
-               this->conf.Write(wxT("ListView-C-Filename"), this->list_ctrl->GetColumnWidth(0));
-               this->conf.Write(wxT("ListView-C-Unpacked"), this->list_ctrl->GetColumnWidth(1));
-               this->conf.Write(wxT("ListView-C-Packed"), this->list_ctrl->GetColumnWidth(2));
-               this->conf.Write(wxT("ListView-C-Ratio"), this->list_ctrl->GetColumnWidth(3));
-               this->conf.Write(wxT("ListView-C-Method"), this->list_ctrl->GetColumnWidth(4));
-               this->conf.Write(wxT("ListView-C-Attr"), this->list_ctrl->GetColumnWidth(5));
-               this->conf.Write(wxT("ListView-C-Lastmodified"), this->list_ctrl->GetColumnWidth(6));
-               this->conf.Write(wxT("ListView-C-Path"), this->list_ctrl->GetColumnWidth(7));
-               this->conf.Write(wxT("ListView-C-Type"), this->list_ctrl->GetColumnWidth(8));
-               this->conf.Write(wxT("ListView-C-No"), this->list_ctrl->GetColumnWidth(9));
-               this->conf.Write(wxT("ListView-SortColumn"), g_nSortColumn);
-               this->conf.Write(wxT("ListView-SortAscend"), g_fSortAscend);
-       }
-
-       this->Close(true);
-}
-
-//******************************************************************************
-// Event Table.
-//******************************************************************************
-
-BEGIN_EVENT_TABLE(MainFrame, wxFrame)
-       EVT_INIT_DIALOG(      MainFrame::OnInit)
-       // Menu
-       EVT_MENU(XRCID("Arc_Create"),  MainFrame::OnArcCreate)
-       EVT_MENU(XRCID("Arc_Open"),    MainFrame::OnArcOpen)
-       EVT_MENU(XRCID("Arc_Close"),   MainFrame::OnArcClose)
-       EVT_MENU(XRCID("Arc_Add"),     MainFrame::OnArcAdd)
-       EVT_MENU(XRCID("Arc_SFX"),     MainFrame::OnArcConvert)
-       EVT_MENU(XRCID("Arc_UnSFX"),   MainFrame::OnArcConvert)
-       EVT_MENU(XRCID("Exe_Exit"),    MainFrame::OnExit)
-       EVT_MENU(XRCID("Arc_Extract"), MainFrame::OnArcExtract)
-       EVT_MENU(XRCID("Arc_Delete"),  MainFrame::OnArcDelete)
-       EVT_MENU(XRCID("Arc_Test"),    MainFrame::OnArcTest)
-       EVT_MENU(XRCID("Arc_Repair"),  MainFrame::OnArcRepair)
-       EVT_MENU(XRCID("Exe_View_Icons"),  MainFrame::OnViewMode)
-       EVT_MENU(XRCID("Exe_View_Details"),MainFrame::OnViewMode)
-       EVT_MENU(XRCID("Exe_View_List"),   MainFrame::OnViewMode)
-       EVT_MENU(XRCID("Exe_View_ToolBar"),MainFrame::OnShowToolBar)
-       EVT_MENU(XRCID("Exe_View_StatusBar"),MainFrame::OnShowStatusBar)
-       EVT_MENU(XRCID("Exe_View_SelectAll"),MainFrame::OnSelectAll)
-       // TreeView
-       EVT_TREE_SEL_CHANGED(XRCID("TreeView"), MainFrame::OnTreeChanged)
-       EVT_TREE_BEGIN_DRAG( XRCID("TreeView"), MainFrame::OnTreeBeginDrag)
-       // ListView
-       EVT_LIST_ITEM_ACTIVATED(XRCID("ListView"), MainFrame::OnListItemDClick)
-       EVT_LIST_BEGIN_DRAG(    XRCID("ListView"), MainFrame::OnListBeginDrag)
-       // Filter
-       EVT_TEXT(XRCID("tcFilter"), MainFrame::OnFilter)
-END_EVENT_TABLE()
-
-//******************************************************************************
-// Event handler.
-//******************************************************************************
-
-void MainFrame::OnInit(wxInitDialogEvent&)
-{
-       // XRC\82Æ\8c\8b\82Ñ\82Â\82¯\81B
-       this->menubar    = this->GetMenuBar();
-       this->toolbar    = this->GetToolBar();
-       this->statusbar = XRCCTRL(* this, "statusbar", wxStatusBar);
-       this->tree_ctrl = XRCCTRL(* this, "TreeView", wxTreeCtrl);
-       this->list_ctrl = XRCCTRL(* this, "ListView", myListCtrl);
-       this->window_splitter = XRCCTRL(* this, "window_splitter", wxSplitterWindow);
-       this->tcFilter  = XRCCTRL(* this->toolbar, "tcFilter", wxTextCtrl);
-
-       // \90Ý\92è\82ð\93Ç\82Ý\8d\9e\82Ý\81B
-       this->SetSize(this->conf.Read(wxT("Window-X"), 0l), this->conf.Read(wxT("Window-Y"), 0l), this->conf.Read(wxT("Window-Width"), 800), this->conf.Read(wxT("Window-Height"), 400));
-       wxTheMimeTypesManager->Initialize(wxMAILCAP_ALL);
-
-       // \8f\89\8aú\92l\90Ý\92è\81B
-       {
-               wxIcon icon;
-               icon.CopyFromBitmap(wxBitmap(L_DIR_S_ICO wxT("app.png"), wxBITMAP_TYPE_ANY));
-               this->SetIcon(icon);
-       }
-       wxCommandEvent e;
-       this->OnArcClose(e);
-
-       // \83X\83v\83\8a\83b\83^\81[\90Ý\92è\81B
-       this->window_splitter->SetSashPosition(this->conf.Read(wxT("Splitter-Pos"), 200));
-
-       // \83\8a\83X\83g\83r\83\85\81[\90Ý\92è\81B
-       int nIconMode = this->conf.Read(wxT("ListView-IconMode"), 0l);
-       e.SetId(nIconMode == 1 ? XRCID("Exe_View_Icons") : (nIconMode == 2 ? XRCID("Exe_View_List") : XRCID("Exe_View_Details")));
-       this->OnViewMode(e);
-       // wxGTK\82Å\82Í\92¼\90ÚwxLC_VIRTUAL\82ð\8ew\92è\82µ\82È\82¢\82Æ\94½\89f\82³\82ê\82È\82¢\81B
-       this->list_ctrl->SetSingleStyle(wxLC_VIRTUAL);
-       this->list_ctrl->InsertColumn(0, wxT("Filename"),      wxLIST_FORMAT_LEFT,   this->conf.Read(wxT("ListView-C-Filename"), 140));
-       this->list_ctrl->InsertColumn(1, wxT("Unpacked"),      wxLIST_FORMAT_RIGHT,  this->conf.Read(wxT("ListView-C-Unpacked"), 80));
-       this->list_ctrl->InsertColumn(2, wxT("Packed"),        wxLIST_FORMAT_RIGHT,  this->conf.Read(wxT("ListView-C-Packed"), 80));
-       this->list_ctrl->InsertColumn(3, wxT("Ratio"),         wxLIST_FORMAT_RIGHT,  this->conf.Read(wxT("ListView-C-Ratio"), 50));
-       this->list_ctrl->InsertColumn(4, wxT("Method"),        wxLIST_FORMAT_LEFT,   this->conf.Read(wxT("ListView-C-Method"), 60));
-       this->list_ctrl->InsertColumn(5, wxT("Attr"),          wxLIST_FORMAT_LEFT,   this->conf.Read(wxT("ListView-C-Attr"), 50));
-       this->list_ctrl->InsertColumn(6, wxT("Last modified"), wxLIST_FORMAT_RIGHT,  this->conf.Read(wxT("ListView-C-Lastmodified"), 150));
-       this->list_ctrl->InsertColumn(7, wxT("Path"),          wxLIST_FORMAT_LEFT,   this->conf.Read(wxT("ListView-C-Path"), 100));
-       this->list_ctrl->InsertColumn(8, wxT("Type"),          wxLIST_FORMAT_LEFT,   this->conf.Read(wxT("ListView-C-Type"), 100));
-       this->list_ctrl->InsertColumn(9, wxT("No."),           wxLIST_FORMAT_RIGHT,  this->conf.Read(wxT("ListView-C-No"), 35));
-       g_nSortColumn = this->conf.Read(wxT("ListView-SortColumn"), 9);
-       g_fSortAscend = this->conf.Read(wxT("ListView-SortAscend"), 1) == 1;
-       this->list_ctrl->SetDropTarget(new myFileDropTarget(this));
-
-       // \83c\81[\83\8b\83o\81[/\83X\83e\81[\83^\83X\83o\81[\90Ý\92è\81B
-       int nStatusBarParts[] = {70, 70, 180, 50, -1};
-       this->statusbar->SetFieldsCount(5, nStatusBarParts);
-       this->SetStatusBarPane(-1);
-       bool fShow = this->conf.Read(wxT("StatusBar-Show"), 1) == 1;
-       this->menubar->Check(XRCID("Exe_View_StatusBar"), fShow);
-       this->statusbar->Show(fShow);
-       fShow = this->conf.Read(wxT("ToolBar-Show"), 1) == 1;
-       this->menubar->Check(XRCID("Exe_View_ToolBar"), fShow);
-       this->toolbar->Show(fShow);
-
-       // \83R\83}\83\93\83h\83\89\83C\83\93\93Ç\82Ý\8d\9e\82Ý\81B
-       this->cmdLine.SetSwitchChars(wxT("-"));
-       this->cmdLine.AddSwitch(wxT("x"), wxEmptyString, wxT("(command) Extract filenames in archive."));
-       this->cmdLine.AddSwitch(wxT("l"), wxEmptyString, wxT("(command) List archive(default)."));
-       this->cmdLine.AddParam(wxT("archive"),   wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL);
-       this->cmdLine.AddParam(wxT("filenames"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE);
-       if (this->cmdLine.Parse() == 0)
-       {
-               if (this->cmdLine.GetParamCount() == 0)
-               {
-                       return;
-               }
-
-               // \8f\91\8cÉ\82ð\8aJ\82­\81B
-               this->fnArchive = wxFileName(this->cmdLine.GetParam(0));
-               this->fnArchive.Normalize(wxPATH_NORM_ALL, this->szCurrentPath);
-               this->OnArcOpen(e);
-               if (this->cmdLine.Found(wxT("x")))
-               {
-                       // \8f\91\8cÉ\82ð\93W\8aJ\81B
-                       this->OnArcExtract(e);
-                       this->Close(true);
-               }
-       }
-}
-
-// MenuBar
-
-void MainFrame::OnExit(wxCommandEvent&)
-{
-       this->Close(true);
-}
-
-void MainFrame::OnArcCreate(wxCommandEvent& e)
-{
-       TPI_SWITCHES swInfo;
-       swInfo.pCustomSwitches = NULL;
-
-       // \8dì\90¬\83_\83C\83A\83\8d\83O\82ð\90Ý\92è\81B
-       MakeDialog mkDlg;
-       ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));
-       ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));
-
-       if (e.GetClientData() == NULL)
-       {
-               // \8f\88\97\9d\91Î\8fÛ\82Ì\83t\83@\83C\83\8b\82ð\91I\91ð\81B
-               wxFileDialog fd(this, wxT("Choose files to compress"), this->conf.Read(wxT("LastOpenPath"), ::wxGetCwd()));
-               fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
-               if (fd.ShowModal() == wxID_CANCEL)
-               {
-                       return;
-               }
-               swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
-               this->conf.Write(wxT("LastOpenPath"), fd.GetDirectory());
-               this->statusbar->SetStatusText(swInfo.fnDestinationDirectory.GetFullPath(), 4);
-
-               fd.GetFilenames(mkDlg.files);
-       }
-       else
-       {
-               mkDlg.files = * (wxArrayString *) e.GetClientData();
-               swInfo.fnDestinationDirectory = wxFileName::DirName(wxFileName(mkDlg.files[0]).GetPath());
-               // \91\8a\91Î\83p\83X\82É\95Ï\8a·\81B
-               for (size_t n = 0; n < mkDlg.files.GetCount(); n++)
-               {
-                       wxFileName fn(mkDlg.files[n]);
-                       bool fIsDir = fn.DirExists() && ! fn.FileExists();
-                       fn.MakeRelativeTo(swInfo.fnDestinationDirectory.GetPath());
-                       mkDlg.files[n] = fn.GetFullPath();
-                       if (fIsDir)
-                       {
-                               mkDlg.files[n] += fn.GetPathSeparator();
-                       }
-               }
-       }
-
-       this->OnArcClose(e);
-       mkDlg.InitDialog();
-       mkDlg.cbDir->SetValue(swInfo.fnDestinationDirectory.GetPath());
-       // \8f\91\8cÉ\96¼\82Í\83t\83@\83C\83\8b\96¼\82Ì\8ag\92£\8eq\82æ\82è\91O\81A\82à\82µ\82­\82Í\83f\83B\83\8c\83N\83g\83\8a\96¼\81B
-       this->fnArchive = wxFileName(mkDlg.files[0]);
-       this->fnArchive.SetName(mkDlg.files.GetCount() == 1 ? (this->fnArchive.GetName().IsEmpty() ? this->fnArchive.GetDirs().Last() : this->fnArchive.GetName()) : swInfo.fnDestinationDirectory.GetDirs().Last());
-       this->fnArchive.SetPath(swInfo.fnDestinationDirectory.GetPath());
-       mkDlg.cbFileName->SetValue(this->fnArchive.GetName());
-
-       // \83_\83C\83A\83\8d\83O\82ð\95\\8e¦\81B
-       if (mkDlg.ShowModal() == wxID_CANCEL)
-       {
-               this->statusbar->SetStatusText(wxEmptyString, 4);
-               return;
-       }
-       this->statusbar->SetStatusText(wxEmptyString, 4);
-
-       // \8ae\8eí\90Ý\92è\81B
-       swInfo.fStoreDirectoryPathes= ! mkDlg.cbIgnorePath->IsChecked();
-       swInfo.fMakeSFX                     = mkDlg.cbMakeSFX->IsChecked();
-       swInfo.fSolid               = mkDlg.cbSolid->IsChecked();
-       swInfo.fMMOptimize          = mkDlg.cbMMOptimize->IsChecked();
-       swInfo.fEncryptHeader       = mkDlg.cbEncryptHeader->IsChecked();
-       swInfo.sCompressLevel       = mkDlg.scLevel->GetValue();
-       swInfo.sRecoveryRecord      = mkDlg.scRR->GetValue();
-       swInfo.szPassword           = mkDlg.tcPassword->GetValue();
-       swInfo.szKeyFile            = mkDlg.tcKeyfile->GetValue();
-       swInfo.szComment            = mkDlg.tcComment->GetValue();
-       {
-               wxULongLong_t ll;
-               mkDlg.cbSplitSize->GetValue().ToULongLong(& ll);
-               swInfo.llSplitSize      = ll;
-       }
-
-       // TPI\82ð\93Ç\82Ý\8d\9e\82Ý\81B
-       int nSelected = mkDlg.chType->GetSelection();
-       this->fnArchive = wxFileName(mkDlg.cbDir->GetValue(), mkDlg.cbFileName->GetValue(), swInfo.fMakeSFX ? EXE_EXT : mkDlg.afInfo[nSelected].szSuffix.BeforeFirst(wxT(';')));
-       if (! tpi.InitLibrary(mkDlg.afInfo[nSelected].szTPIName, this->fnArchive.GetFullPath(), mkDlg.afInfo[nSelected].llTypeId))
-       {
-               ::ErrDlg(wxT("InitLibrary()!"), this);
-               return;
-       }
-
-       // \83R\81[\83\8b\83o\83b\83N\8aÖ\90\94\82ð\90Ý\92è\81B
-       if (! tpi.SetCallbackProc(TPICallbackProc))
-       {
-               ::ErrDlg(wxT("SetCallbackProc()!"), this);
-       }
-
-       // \8f\88\97\9d\82ð\8ds\82¤\81B
-       ProcessDialog procDlg;
-       procDlg.InitDialog();
-       procDlg.Show(true);
-       if (! tpi.Command(TPI_COMMAND_ADD, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))
-       {
-               this->ErrorCheck(tpi.nErrorCode);
-               return;
-       }
-       procDlg.Show(false);
-       tpi.FreeLibrary();
-
-       if (mkDlg.cbOpenAfter->IsChecked())
-       {
-               // \8dì\90¬\90æ\82ð\8aJ\82­\81B
-#ifdef __WINDOWS__
-               ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());
-#endif
-       }
-
-       if (mkDlg.cbExitAfter->IsChecked())
-       {
-               // \8fI\97¹\81B
-               this->Close(true);
-       }
-
-       // \8fI\97¹\82µ\82È\82¢\8fê\8d\87\82Í\8f\91\8cÉ\82ð\8aJ\82­\81B
-       this->OnArcOpen(e);
-}
-
-void MainFrame::OnArcOpen(wxCommandEvent& e)
-{
-       // \8f\91\8cÉ\82ð\91I\91ð\81B
-       if (e.GetId() == XRCID("Arc_Open"))
-       {
-               wxFileDialog fd(this);
-               fd.SetDirectory(this->conf.Read(wxT("LastOpenPath"), ::wxGetCwd()));
-               fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST);
-               if (fd.ShowModal() == wxID_CANCEL)
-               {
-                       return;
-               }
-               this->conf.Write(wxT("LastOpenPath"), fd.GetDirectory());
-               this->fnArchive = wxFileName(fd.GetPath());
-       }
-       this->OnArcClose(e);
-
-       // \90i\92»\83_\83C\83A\83\8d\83O\95\\8e¦\81B
-       ProcessDialog procDlg;
-       procDlg.InitDialog();
-       procDlg.Show(true);
-
-       // TPI\82ð\93Ç\82Ý\8d\9e\82Ý\81A\8dÅ\8f\89\82Ì\83R\81[\83\8b\83o\83b\83N\82ð\91\97\90M\81B
-       TPI_PROCESSINFO piInfo;
-       piInfo.uMessage = TPI_MESSAGE_STATUS;
-       piInfo.uStatus = 0x1000;
-       piInfo.llProcessedSize = 0;
-       piInfo.fiInfo.fnFileName = this->fnArchive;
-       piInfo.fiInfo.llUnpackedSize = this->LoadTPI(this->fnArchive.GetFullPath());
-       if ((signed) piInfo.fiInfo.llUnpackedSize.ToULong() == -1)
-       {
-               procDlg.Show(false);
-               tpi.FreeLibrary();
-               ::ErrDlg(wxT("No plug-in supporting this archive was found!"), this);
-               return;
-       }
-       TPICallbackProc(TPI_NOTIFY_COMMON, & piInfo);
-
-       // \83R\81[\83\8b\83o\83b\83N\8aÖ\90\94\82ð\90Ý\92è\81B
-       tpi.SetCallbackProc(TPICallbackProc);
-
-       // \94z\97ñ\82Ì\83T\83C\83Y\82ð\8am\95Û\81B
-       this->fileinfo.Alloc(piInfo.fiInfo.llUnpackedSize.ToULong());
-
-       // \8f\91\8cÉ\82ð\8aJ\82­\81B
-       if (! tpi.OpenArchive(this->fnArchive.GetFullPath()))
-       {
-               procDlg.Show(false);
-               tpi.FreeLibrary();
-               ::ErrDlg(wxT("OpenArchive()!"), this);
-               return;
-       }
-
-       // \8f\91\8cÉ\82Ì\83A\83C\83R\83\93\82ð\8eæ\93¾\82µ\81A\8f\91\8cÉ\83\8b\81[\83g\82ð\8dì\90¬\81B
-       g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_closed.png"), wxBITMAP_TYPE_ANY));
-       g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_open.png"), wxBITMAP_TYPE_ANY));
-       this->tree_ctrl->SetImageList(& g_hIconT);
-       wxTreeItemId
-               idRoot = this->tree_ctrl->AddRoot(wxEmptyString),
-#ifdef __WINDOWS__
-               idArchive = this->tree_ctrl->AppendItem(idRoot, piInfo.fiInfo.fnFileName.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName))),
-#else
-               idArchive = this->tree_ctrl->AppendItem(idRoot, piInfo.fiInfo.fnFileName.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName).ConvertToImage().Rescale(16, 16))),
-#endif
-               idArcRoot = this->tree_ctrl->AppendItem(idRoot, wxT("-----"), 0, 1);
-
-       // \83t\83@\83C\83\8b\8fî\95ñ\82ð\83\8d\81[\83h\81B
-       if (tpi.GetFileInformation(& piInfo.fiInfo, true))
-       {
-               piInfo.uStatus = 0x1001;
-               do
-               {
-                       piInfo.llProcessedSize++;
-                       if (this->ErrorCheck(TPICallbackProc(TPI_NOTIFY_COMMON, & piInfo)) == TPI_CALLBACK_CANCEL)
-                       {
-                               procDlg.Show(false);
-                               tpi.CloseArchive();
-                               wxCommandEvent e;
-                               this->OnArcClose(e);
-                               return;
-                       }
-
-                       // \83c\83\8a\81[\83r\83\85\81[\82É\94½\89f\81B
-                       TreeView_CheckNewerItem(this->tree_ctrl, idArcRoot, piInfo.fiInfo.fnFileName.GetPath(), true);
-
-                       // \83f\83B\83\8c\83N\83g\83\8a\91®\90«\82ð\8aÜ\82Þ\82à\82Ì\82É\82Â\82¢\82Ä\82Í\8f\9c\8b\8e\81B
-                       if (piInfo.fiInfo.dwAttribute & TPI_ATTRIBUTE_DIRECTORY)
-                       {
-                               continue;
-                       }
-
-                       // \83Z\83L\83\85\83\8a\83e\83B\83`\83F\83b\83N\81B
-                       // DTV\8c\9f\8d¸\81B
-                       if (piInfo.fiInfo.fnFileName.GetPathWithSep().Find(wxT("..")) != wxNOT_FOUND)
-                       {
-                               piInfo.fiInfo.uDanger = TRUE;
-                               ::WrnDlg(wxT("This archive may have Directory Traversal Vulnerability(DTV) problem, and some danger files may be extracted to the unexpected system directory! You should use the \"Ignore file pathes\" option when extracting this archive.\nDanger file is:\n") + piInfo.fiInfo.szStoredName, this);
-                       }
-                       // \8bó\94\92\82Ì\98A\91±\82É\82æ\82é\8ag\92£\8eq\8bU\91\95\82ð\8c\9f\8d¸\81B
-                       if (piInfo.fiInfo.fnFileName.GetFullName().Find(wxT("        ")) != wxNOT_FOUND)
-                       {
-                               piInfo.fiInfo.uDanger = TRUE;
-                               ::WrnDlg(wxT("This archive may contain extension-disguised files whose real extension is hidden by using many blank charactor and you may mistake that it is a \"safe\" file. Don\'t execute these files carelessly.\nDanger file is:\n") + piInfo.fiInfo.szStoredName, this);
-                       }
-                       // Unicode\90§\8cä\95\8e\9a\82ð\8c\9f\8d¸\81B
-                       for (wxChar c = 0x200c; c <= 0x206f; c++)
-                       {
-                               if (piInfo.fiInfo.fnFileName.GetFullName().Find(c) != wxNOT_FOUND)
-                               {
-                                       piInfo.fiInfo.uDanger = TRUE;
-                                       ::WrnDlg(wxT("This archive may contain extension-disguised files whose real extension is hidden by using Unicode control character and you may mistake that it is a \"safe\" file. Don\'t execute these files carelessly.\nDanger file is:\n") + piInfo.fiInfo.szStoredName, this);
-                               }
-                               switch (c)
-                               {
-                               case 0x200f: c = 0x2027; break;
-                               case 0x202e: c = 0x2060; break;
-                               }
-                       }
-
-                       // \8fî\95ñ\82ð\95Û\91\82µ\82Ä\83J\83E\83\93\83g\83A\83b\83v\81B
-                       this->fileinfo.Add(piInfo.fiInfo);
-               }
-               while (tpi.GetFileInformation(& piInfo.fiInfo, false));
-       }
-
-       // \8f\91\8cÉ\82Ì\8fî\95ñ\82ð\8eæ\93¾\81B
-       TPI_ARCHIVEINFO aiInfo;
-       if (! tpi.GetArchiveInformation(& aiInfo))
-       {
-               procDlg.Show(false);
-               tpi.FreeLibrary();
-               ::ErrDlg(wxT("GetArchiveInformation()!"), this);
-               return;
-       }
-       this->szComment = aiInfo.szComment;
-
-       // \8f\91\8cÉ\82ð\95Â\82\82é\81B
-       if (! tpi.CloseArchive())
-       {
-               ::ErrDlg(wxT("CloseArchive()!"), this);
-       }
-
-       // \88È\89º\81AUI\8f\88\97\9d\81B
-       this->fileinfo.Shrink();
-       this->tree_ctrl->ExpandAll();
-       this->tree_ctrl->ScrollTo(idArchive);
-       this->tree_ctrl->SelectItem(idArchive);
-       this->list_ctrl->atDangerItem.SetTextColour(* wxRED);
-
-       // \83X\83e\81[\83^\83X\83o\81[\90Ý\92è\81B
-       this->statusbar->SetStatusText(aiInfo.fiInfo.szTypeName, 0);
-       this->statusbar->SetStatusText(wxString::Format(wxT("%d file(s)"), this->fileinfo.GetCount()), 1);
-       this->statusbar->SetStatusText(aiInfo.llUnpackedSize.ToString() + wxT(" B -> ") + aiInfo.llPackedSize.ToString() + wxT(" B"), 2);
-       this->statusbar->SetStatusText(wxString::Format(wxT("%3.1f%%"), aiInfo.wCompressRatio / 10.0), 3);
-       this->statusbar->SetStatusText(this->fnArchive.GetFullPath(), 4);
-
-       // \83c\81[\83\8b\83o\81[\81E\83\81\83j\83\85\81[\83o\81[\90Ý\92è\81B
-       SetMenuToolState("Arc_Close",   true);
-       SetMenuToolState("Arc_Add",     (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_ADD)   == TPI_COMMAND_ADD   && aiInfo.fiInfo.fArchive);
-       SetMenuToolState("Arc_SFX",     (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_SFX)    == TPI_COMMAND_SFX   && aiInfo.nSFXType == 0);
-       SetMenuToolState("Arc_UnSFX",   (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_UNSFX)  == TPI_COMMAND_UNSFX && aiInfo.nSFXType != 0);
-       SetMenuToolState("Arc_Extract", (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_EXTRACT)== TPI_COMMAND_EXTRACT);
-       SetMenuToolState("Arc_Delete",  (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_DELETE) == TPI_COMMAND_DELETE && aiInfo.fiInfo.fArchive);
-       SetMenuToolState("Arc_Test",    (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_TEST)   == TPI_COMMAND_TEST);
-       SetMenuToolState("Arc_Repair",  (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_REPAIR) == TPI_COMMAND_REPAIR);
-
-       procDlg.Show(false);
-}
-
-void MainFrame::OnArcClose(wxCommandEvent&)
-{
-       // \83c\83\8a\81[\83r\83\85\81[\81E\83\8a\83X\83g\83r\83\85\81[\90Ý\92è\81B
-       this->tree_ctrl->DeleteAllItems();
-       this->list_ctrl->DeleteAllItems();
-       this->list_ctrl->showFileInfo.Clear();
-
-       // \83c\81[\83\8b\83o\81[\81E\83\81\83j\83\85\81[\83o\81[\90Ý\92è\81B
-       SetMenuToolState("Arc_Close",   false);
-       SetMenuToolState("Arc_Add",     false);
-       SetMenuToolState("Arc_SFX",     false);
-       SetMenuToolState("Arc_UnSFX",   false);
-       SetMenuToolState("Arc_Extract", false);
-       SetMenuToolState("Arc_Delete",  false);
-       SetMenuToolState("Arc_Test",    false);
-       SetMenuToolState("Arc_Repair",  false);
-
-       for (int i = 0; i < this->statusbar->GetFieldsCount(); i++)
-       {
-               this->statusbar->SetStatusText(wxEmptyString, i);
-       }
-       this->fileinfo.Clear();
-       this->szComment.Clear();
-
-       g_hIconT.RemoveAll();
-       g_hIconLL.RemoveAll();
-       g_hIconLS.RemoveAll();
-       this->tpi.FreeLibrary();
-}
-
-void MainFrame::OnArcAdd(wxCommandEvent& e)
-{
-       // \8f\88\97\9d\91Î\8fÛ\82Ì\83t\83@\83C\83\8b\82ð\91I\91ð\81B
-       wxArrayString files;
-       wxFileDialog fd(this, wxT("Choose files to add"), this->conf.Read(wxT("LastOpenPath"), ::wxGetCwd()));
-       fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
-       if (fd.ShowModal() == wxID_CANCEL)
-       {
-               return;
-       }
-       fd.GetFilenames(files);
-       this->conf.Write(wxT("LastOpenPath"), fd.GetDirectory());
-
-       // \8ae\8eí\90Ý\92è\81B
-       TPI_SWITCHES swInfo;
-       swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
-       swInfo.fMakeSFX = false;
-       swInfo.pCustomSwitches = NULL;
-
-       ProcessDialog procDlg;
-       procDlg.InitDialog();
-       procDlg.Show(true);
-       if (! this->tpi.Command(TPI_COMMAND_ADD, & swInfo, this->fnArchive.GetFullPath(), files))
-       {
-               this->ErrorCheck(tpi.nErrorCode);
-       }
-       procDlg.Show(false);
-
-       // \8f\91\8cÉ\82ð\8dÄ\93Ç\82Ý\8d\9e\82Ý\81B
-       this->OnArcOpen(e);
-}
-
-void MainFrame::OnArcConvert(wxCommandEvent& e)
-{
-       TPI_SWITCHES swInfo;
-       swInfo.fMakeSFX = e.GetId() == XRCID("Arc_SFX");
-
-       // \95Û\91\90æ\82ð\90q\82Ë\82é\81B
-       wxFileDialog fd(this, swInfo.fMakeSFX ? wxT("Save as SFX") : wxT("Save as normal archive"), this->fnArchive.GetPath(), this->fnArchive.GetName() + (swInfo.fMakeSFX ? EXE_EXT : (wxString) wxEmptyString));
-       fd.SetWindowStyleFlag(wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
-       if (fd.ShowModal() == wxID_CANCEL)
-       {
-               return;
-       }
-       swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
-       this->conf.Write(wxT("LastOpenPath"), fd.GetDirectory());
-
-       wxArrayString files;
-       files.Add(fd.GetPath());
-
-       ProcessDialog procDlg;
-       procDlg.InitDialog();
-       procDlg.Show(true);
-       if (! this->tpi.Command(swInfo.fMakeSFX ? TPI_COMMAND_SFX : TPI_COMMAND_UNSFX, & swInfo, this->fnArchive.GetFullPath(), files))
-       {
-               this->ErrorCheck(tpi.nErrorCode);
-       }
-       procDlg.Show(false);
-}
-
-void MainFrame::OnArcExtract(wxCommandEvent& e)
-{
-       TPI_SWITCHES swInfo;
-       swInfo.pCustomSwitches = NULL;
-
-       // \83\82\81[\83h\8eæ\93¾\81B\92Ê\8fí\82Í0, \8eÀ\8ds\82È\82ç1, \83t\83@\83C\83\8bDnD\82È\82ç2\81A\83f\83B\83\8c\83N\83g\83\8aDnD\82È\82ç3\81B
-       int nMode = e.GetInt();
-       // \8eÀ\8ds\8e\9e\82Ì\82Ý\8eg\97p\81B
-       wxFileType * ftFile = NULL;
-
-       // \93W\8aJ\83_\83C\83A\83\8d\83O\82ð\8dì\90¬\81BDnD\82Ü\82½\82Í\8eÀ\8ds\8e\9e\82Í\95\\8e¦\82µ\82È\82¢\81B
-       MakeDialog mkDlg;
-       ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));
-       ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));
-       mkDlg.bIsMake = false;
-       mkDlg.files   = MakeTargetFileList(this, nMode == 1);
-
-       if (nMode != 0)
-       {
-               if (nMode == 1)
-               {
-                       // \83R\83}\83\93\83h\82ð\8eæ\93¾\81B
-                       ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(wxFileName(mkDlg.files[0]).GetExt());
-                       if (! ftFile)
-                       {
-                               // \8eí\97Þ\82ª\8eæ\93¾\82Å\82«\82È\82¢\82Æ\82«\82Í\90Ý\92è\82ð\93Ç\82Ý\8d\9e\82Þ\81B\8f\89\8aú\90Ý\92è\82Å\82Í\83e\83L\83X\83g\82Æ\82Ý\82È\82·\81B
-                               ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(this->conf.Read(wxT("DefaultExt"), wxT("txt")));
-                               if (! ftFile)
-                               {
-                                       ::ErrDlg(wxT("Unable to get the file type!"), this);
-                                       return;
-                               }
-                       }
-               }
-
-               // \8dì\8bÆ\83f\83B\83\8c\83N\83g\83\8a\8dì\90¬\81B
-               swInfo.fStoreDirectoryPathes = false;
-               wxString szDestDirBase = nMode == 3 ? this->tree_ctrl->GetItemText(this->tree_ctrl->GetSelection()) : wxT("tpi_tmp");
-               if (szDestDirBase == wxT("-----"))
-               {
-                       // \8f\91\8cÉ\83\8b\81[\83g\82Ì\82Æ\82«\82Í\8f\91\8cÉ\96¼\82É\82µ\82Ä\82¨\82­\81B
-                       szDestDirBase = this->fnArchive.GetName();
-               }
-               swInfo.fnDestinationDirectory = MakeDirPath(wxFileName::DirName(::wxGetCwd()), szDestDirBase, true);
-               if (! swInfo.fnDestinationDirectory.IsOk())
-               {
-                       ::ErrDlg(wxT("Unable to make the temporary directory!"), this);
-                       return;
-               }
-       }
-       else
-       {
-               mkDlg.InitDialog();
-               if (mkDlg.ShowModal() == wxID_CANCEL)
-               {
-                       return;
-               }
-
-               // \8ae\8eí\90Ý\92è\81B
-               swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();
-               swInfo.fnDestinationDirectory = wxFileName::DirName(mkDlg.cbDir->GetValue());
-               swInfo.szPassword = mkDlg.tcPassword->GetValue();
-               swInfo.szKeyFile  = mkDlg.tcKeyfile->GetValue();
-
-               // \95K\97v\82È\82ç\8f\91\8cÉ\96¼\82Å\83f\83B\83\8c\83N\83g\83\8a\82ð\8dì\90¬\82·\82é\81B
-               if (WillMakeDirByArcName(this, & mkDlg))
-               {
-                       swInfo.fnDestinationDirectory = MakeDirPath(swInfo.fnDestinationDirectory, this->fnArchive.GetName(), true);
-                       if (! swInfo.fnDestinationDirectory.IsOk())
-                       {
-                               ::ErrDlg(wxT("Unable to make the destination directory!"), this);
-                               return;
-                       }
-               }
-       }
-
-       ProcessDialog procDlg;
-       procDlg.InitDialog();
-       procDlg.Show(true);
-       if (! this->tpi.Command(TPI_COMMAND_EXTRACT, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))
-       {
-               this->ErrorCheck(tpi.nErrorCode);
-       }
-       procDlg.Show(false);
-
-       if (nMode == 0)
-       {
-               if (mkDlg.cbOpenAfter->IsChecked())
-               {
-                       // \93W\8aJ\90æ\82ð\8aJ\82­\81B
-#ifdef __WINDOWS__
-                       ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());
-#endif
-               }
-
-               if (mkDlg.cbExitAfter->IsChecked())
-               {
-                       // \8fI\97¹\81B
-                       this->Close(true);
-               }
-       }
-       else
-       {
-               wxArrayString asFiles;
-               if (nMode == 1)
-               {
-                       // \83R\83}\83\93\83h\82ð\8eÀ\8ds\81B
-                       asFiles.Add(swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[0]).GetFullName());
-                       if (tpi.nErrorCode == TPI_ERROR_SUCCESS)
-                       {
-#ifdef __LINUX__
-                               // Linux\82Å\82Í\88ø\97p\95\84\82Å\88Í\82Þ\95K\97v\82ª\82 \82é\81B
-                               ::wxExecute(ftFile->GetOpenCommand(wxT('"') + asFiles[0] + wxT('"')), wxEXEC_SYNC);
-#else
-                               ::wxExecute(ftFile->GetOpenCommand(asFiles[0]), wxEXEC_SYNC);
-#endif
-                       }
-               }
-               else
-               {
-                       // \93W\8aJ\91Î\8fÛ\82ð\8c\88\92è\81B
-                       wxFileDataObject objFile;
-                       for (size_t i = 0; i < mkDlg.files.GetCount(); i++)
-                       {
-                               wxString szFileName = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[i]).GetFullName();
-                               if (nMode == 2)
-                               {
-                                       // \83\8a\83X\83g\82É\92Ç\89Á\81B
-                                       objFile.AddFile(szFileName);
-                               }
-                               asFiles.Add(szFileName);
-                       }
-                       if (nMode == 3)
-                       {
-                               objFile.AddFile(swInfo.fnDestinationDirectory.GetPath());
-                       }
-
-                       // DnD\8aJ\8en\81B
-                       wxDropSource dropSource(objFile, this);
-                       if (dropSource.DoDragDrop() != wxDragMove)
-                       {
-#ifdef __LINUX__
-                               // Linux\82Å\82Í\82Ü\82¾\8f\88\97\9d\82ª\8fI\82í\82Á\82Ä\82¢\82È\82¢(\83R\83\93\83e\83L\83X\83g\83\81\83j\83\85\81[\82ª\95\\8e¦\82³\82ê\82Ä\82¢\82é)\82Ì\82Å\81A\82Æ\82è\82 \82¦\82¸3\95b\82¾\82¯\91Ò\82Â\81B
-                               sleep(3);
-#endif
-                       }
-               }
-
-               // \83t\83@\83C\83\8b\82Æ\88ê\8e\9e\83f\83B\83\8c\83N\83g\83\8a\82ð\8dí\8f\9c\81B
-               for (size_t i = 0; i < asFiles.GetCount(); i++)
-               {
-                       ::wxRemoveFile(asFiles[i]);
-               }
-               ::wxRmdir(swInfo.fnDestinationDirectory.GetFullPath());
-       }
-}
-
-void MainFrame::OnArcDelete(wxCommandEvent& e)
-{
-       // \91S\83t\83@\83C\83\8b\8dí\8f\9c\82Í\8aë\8c¯\82Å\82Í\82È\82¢\82©\82Æ\81B
-       if (this->list_ctrl->GetSelectedItemCount() == 0)
-       {
-               return;
-       }
-
-       if (::AskDlg(wxT("Are you sure to delete selected files?"), this) == wxNO)
-       {
-               return;
-       }
-
-       // \8ae\8eí\90Ý\92è\81B
-       TPI_SWITCHES swInfo;
-       ProcessDialog procDlg;
-       procDlg.InitDialog();
-       procDlg.Show(true);
-       if (! this->tpi.Command(TPI_COMMAND_DELETE, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false)))
-       {
-               this->ErrorCheck(tpi.nErrorCode);
-       }
-       procDlg.Show(false);    
-
-       // \8f\91\8cÉ\82ð\8dÄ\93Ç\82Ý\8d\9e\82Ý\82·\82é\81B
-       this->OnArcOpen(e);
-}
-
-void MainFrame::OnArcTest(wxCommandEvent&)
-{
-       TPI_SWITCHES swInfo;
-       ProcessDialog procDlg;
-       procDlg.InitDialog();
-       procDlg.Show(true);
-       if (this->tpi.Command(TPI_COMMAND_TEST, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false)))
-       {
-               ::MsgDlg(wxT("This is a correct archive."), & procDlg, wxICON_INFORMATION);
-       }
-       else
-       {
-               this->ErrorCheck(tpi.nErrorCode);
-       }
-       procDlg.Show(false);
-}
-
-void MainFrame::OnArcRepair(wxCommandEvent&)
-{
-       TPI_SWITCHES swInfo;
-       ProcessDialog procDlg;
-       procDlg.InitDialog();
-       procDlg.Show(true);
-       if (! this->tpi.Command(TPI_COMMAND_REPAIR, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false)))
-       {
-               this->ErrorCheck(tpi.nErrorCode);
-       }
-       procDlg.Show(false);    
-}
-
-void MainFrame::OnViewMode(wxCommandEvent & e)
-{
-       int n = e.GetId();
-       this->menubar->Check(n, true);
-       this->list_ctrl->SetSingleStyle(wxLC_REPORT, n == XRCID("Exe_View_Details"));
-       this->list_ctrl->SetSingleStyle(wxLC_ICON,   n == XRCID("Exe_View_Icons"));
-       this->list_ctrl->SetSingleStyle(wxLC_LIST,   n == XRCID("Exe_View_List"));
-}
-
-void MainFrame::OnShowToolBar(wxCommandEvent & e)
-{
-       this->toolbar->Show(e.IsChecked());
-}
-
-void MainFrame::OnShowStatusBar(wxCommandEvent & e)
-{
-       this->statusbar->Show(e.IsChecked());
-}
-
-void MainFrame::OnSelectAll(wxCommandEvent &)
-{
-       for (int i = 0; i < this->list_ctrl->GetItemCount(); i++)
-       {
-               this->list_ctrl->Select(i, true);
-       }
-}
-
-// TreeView
-
-void MainFrame::OnTreeChanged(wxTreeEvent& e)
-{
-       // \83c\83\8a\81[\83r\83\85\81[\82©\82ç\83p\83X\82ð\8eæ\93¾\81B
-       wxString szNodePath = TreeView_GetItemPath(this->tree_ctrl, e.GetItem());
-       // \83\8a\83X\83g\83r\83\85\81[\82ð\8f\89\8aú\89»\81B
-       this->list_ctrl->showFileInfo.Clear();
-       this->list_ctrl->DeleteAllItems();
-       g_hIconLL.RemoveAll();
-       g_hIconLS.RemoveAll();
-
-       // \8c»\8dÝ\82Ì\83A\83C\83e\83\80\82Ì\91I\91ð\8fó\91Ô\82ð\96³\8cø\82É\82µ\82Ä\82¨\82­\81B
-       long nSelected = this->list_ctrl->GetFirstSelected();
-       while (nSelected != -1)
-       {
-               this->list_ctrl->Select(nSelected, false);
-               nSelected = this->list_ctrl->GetNextSelected(nSelected);
-       }
-
-       // \83A\83C\83R\83\93\90Ý\92è\81B
-       this->list_ctrl->SetImageList(& g_hIconLL, wxIMAGE_LIST_NORMAL);
-       this->list_ctrl->SetImageList(& g_hIconLS, wxIMAGE_LIST_SMALL);
-
-       // \94z\97ñ\82Æ\94ä\8ar\82µ\81A\83p\83X\82ª\88ê\92v\82µ\82È\82¯\82ê\82Î\8fÁ\82·\81B
-       for (size_t i = 0; i < this->fileinfo.GetCount(); i++)
-       {
-               // \83p\83X\82ð\94ä\8ar\81B
-               if (szNodePath == wxT("*") || szNodePath == this->fileinfo[i].fnFileName.GetPath())
-               {
-                       // \8d\80\96Ú\82ª\83t\83H\83\8b\83_\82Å\82 \82é\82È\82ç\96³\8e\8b\81B
-                       if (this->fileinfo[i].fnFileName.IsDir() || ! TreeView_CheckNewerItem(this->tree_ctrl, this->tree_ctrl->GetLastChild(this->tree_ctrl->GetRootItem()), this->fileinfo[i].fnFileName.GetFullPath(), false))
-                       {
-                               continue;
-                       }
-
-                       // \83t\83B\83\8b\83^\82É\82©\82©\82ç\82È\82¯\82ê\82Î\96³\8e\8b\81B
-                       if (this->fileinfo[i].fnFileName.GetFullName().MakeLower().Find(this->tcFilter->GetValue().MakeLower()) == wxNOT_FOUND)
-                       {
-                               continue;
-                       }
-
-                       this->list_ctrl->showFileInfo.Add(this->fileinfo[i]);
-               }
-       }
-
-       // \83\\81[\83g\82µ\82Ä\95\\8e¦\81B
-       this->list_ctrl->showFileInfo.Sort(& ListCtrlCompareProc);
-       this->list_ctrl->SetItemCount(this->list_ctrl->showFileInfo.GetCount());
-}
-
-void MainFrame::OnTreeBeginDrag(wxTreeEvent& e)
-{
-       // TODO : \83A\83C\83e\83\80\82ª\8eq\8aK\91w\82ð\8e\9d\82Á\82Ä\82¢\82Ä\82à\93W\8aJ\82Å\82«\82È\82¢\81B
-       this->tree_ctrl->SelectItem(e.GetItem());
-
-       wxCommandEvent e1;
-       e1.SetInt(3);
-       this->OnArcExtract(e1);
-}
-
-// ListView
-
-void MainFrame::OnListItemDClick(wxListEvent&)
-{
-       wxCommandEvent e;
-       e.SetInt(1);
-       this->OnArcExtract(e);
-}
-
-void MainFrame::OnListBeginDrag(wxListEvent&)
-{
-       if (this->list_ctrl->GetSelectedItemCount() == 0)
-       {
-               // \83A\83C\83e\83\80\82ð\91I\91ð\82¹\82¸\83h\83\89\83b\83O\82µ\82æ\82¤\82Æ\82µ\82½\8fê\8d\87\81B
-               return;
-       }
-
-       wxCommandEvent e;
-       e.SetInt(2);
-       this->OnArcExtract(e);
-}
-
-// Filter
-
-void MainFrame::OnFilter(wxCommandEvent&)
-{
-       wxTreeEvent e;
-       e.SetItem(this->tree_ctrl->GetSelection());
-       this->OnTreeChanged(e);
-}
-
-// \83C\83x\83\93\83g\83n\83\93\83h\83\89\88È\8aO\81B
-
-int MainFrame::LoadTPI(wxString szFileName)
-{
-       // TPI\82ð\93Ç\82Ý\8d\9e\82Ý\81B
-       wxFileSystem fs;
-       fs.ChangePathTo(L_DIR_B_LIB, true);
-       wxString szTPIName = fs.FindFirst(wxT("*" TPI_EXT), wxFILE);
-       int nFileCount = -1;
-       while (! szTPIName.IsEmpty())
-       {
-               // \91Î\89\9e\8am\94F\81B
-               if (! tpi.InitLibrary(szTPIName, szFileName, 0) || ! tpi.CheckArchive(szFileName, & nFileCount) || nFileCount < 0)
-               {
-                       tpi.FreeLibrary();
-                       szTPIName = fs.FindNext();
-                       continue;
-               }
-               break;
-       }
-       return nFileCount;
-}
-
-int MainFrame::ErrorCheck(int nErrorCode)
-{
-       switch (nErrorCode)
-       {
-       case TPI_ERROR_SUCCESS:
-       case TPI_CALLBACK_CONTINUE:
-               break;
-       case TPI_ERROR_D_UNSUPPORTED:
-               ::ErrDlg(wxT("Sorry, this function is not supported yet."), this);
-               break;
-       case TPI_ERROR_D_SKIPPED:
-       case TPI_CALLBACK_CANCEL:
-               ::ErrDlg(wxT("This operation is canceled by the user."), this);
-               break;
-       default:
-               ::ErrDlg(wxT("Error code is ") + wxString::Format(wxT("%d."), nErrorCode), this);
-       }
-       return nErrorCode;
-}
+/*******************************************************************************\r
+  TPI - flexible but useless plug-in framework.\r
+  Copyright (C) 2002-2009 Silky\r
+\r
+  This library is free software; you can redistribute it and/or modify it under\r
+  the terms of the GNU Lesser General Public License as published by the Free\r
+  Software Foundation; either version 2.1 of the License, or (at your option)\r
+  any later version.\r
+\r
+  This library is distributed in the hope that it will be useful, but WITHOUT\r
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \r
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\r
+  for more details.\r
+\r
+  You should have received a copy of the GNU Lesser General Public License along\r
+  with this library; if not, write to the Free Software Foundation, Inc.,\r
+  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r
+\r
+  $Id$\r
+*******************************************************************************/\r
+\r
+#include "lychee.h"\r
+\r
+#include "frm_main.h"\r
+#include "cls_filedroptarget.h"\r
+#include "dlg_make.h"\r
+#include "dlg_process.h"\r
+#include "functions.h"\r
+\r
+#include <wx/arrimpl.cpp>\r
+\r
+WX_DEFINE_OBJARRAY(ArrayTPI_FILEINFO);\r
+\r
+#define SetMenuToolState(id, state) this->toolbar->EnableTool(XRCID(id), state); this->menubar->Enable(XRCID(id), state)\r
+\r
+//******************************************************************************\r
+//    グローバル変数\r
+//******************************************************************************\r
+\r
+wxImageList g_hIconT(16, 16), g_hIconLL(32, 32), g_hIconLS(16, 16);\r
+int g_nSortColumn;\r
+bool g_fSortAscend;\r
+\r
+//******************************************************************************\r
+// MainFrame\r
+//******************************************************************************\r
+\r
+MainFrame::MainFrame(): wxFrame()\r
+{\r
+}\r
+\r
+MainFrame::~MainFrame()\r
+{\r
+       wxCommandEvent e;\r
+       this->OnArcClose(e);\r
+\r
+       // 設定を記録。\r
+       if (! this->IsIconized() && ! this->IsMaximized())\r
+       {\r
+               int a, b;\r
+               this->GetSize(& a, & b);\r
+               this->conf.WriteId(CONF_WINDOW_WIDTH,  a);\r
+               this->conf.WriteId(CONF_WINDOW_HEIGHT, b);\r
+               this->GetPosition(& a, & b);\r
+               this->conf.WriteId(CONF_WINDOW_X, a);\r
+               this->conf.WriteId(CONF_WINDOW_Y, b);\r
+       }\r
+       this->conf.WriteId(CONF_WINDOW_SPLITTER_POS, this->window_splitter->GetSashPosition());\r
+\r
+       // ツールバー/ステータスバー関連。\r
+       this->conf.WriteId(CONF_WINDOW_STATUSBAR, this->statusbar->IsShown());\r
+       this->conf.WriteId(CONF_WINDOW_TOOLBAR,   this->toolbar->IsShown());\r
+\r
+       // ListView関連。\r
+       this->conf.WriteId(CONF_LISTVIEW_SHOWMODE, this->menubar->IsChecked(XRCID("Exe_View_Icons")) ? 1 : this->menubar->IsChecked(XRCID("Exe_View_List")) ? 2 : 0);\r
+       if (this->menubar->IsChecked(XRCID("Exe_View_Details")))\r
+       {\r
+               this->conf.WriteId(CONF_LISTVIEW_C_FILENAME, this->list_ctrl->GetColumnWidth(0));\r
+               this->conf.WriteId(CONF_LISTVIEW_C_UNPACKED, this->list_ctrl->GetColumnWidth(1));\r
+               this->conf.WriteId(CONF_LISTVIEW_C_PACKED,   this->list_ctrl->GetColumnWidth(2));\r
+               this->conf.WriteId(CONF_LISTVIEW_C_RATIO,    this->list_ctrl->GetColumnWidth(3));\r
+               this->conf.WriteId(CONF_LISTVIEW_C_METHOD,   this->list_ctrl->GetColumnWidth(4));\r
+               this->conf.WriteId(CONF_LISTVIEW_C_ATTR,         this->list_ctrl->GetColumnWidth(5));\r
+               this->conf.WriteId(CONF_LISTVIEW_C_LASTMOD,  this->list_ctrl->GetColumnWidth(6));\r
+               this->conf.WriteId(CONF_LISTVIEW_C_PATH,     this->list_ctrl->GetColumnWidth(7));\r
+               this->conf.WriteId(CONF_LISTVIEW_C_TYPE,     this->list_ctrl->GetColumnWidth(8));\r
+               this->conf.WriteId(CONF_LISTVIEW_C_NO,       this->list_ctrl->GetColumnWidth(9));\r
+               this->conf.WriteId(CONF_LISTVIEW_C_COMMENT,  this->list_ctrl->GetColumnWidth(10));\r
+               this->conf.WriteId(CONF_LISTVIEW_S_COLUMN,   g_nSortColumn);\r
+               this->conf.WriteId(CONF_LISTVIEW_S_ASCEND,   g_fSortAscend);\r
+       }\r
+\r
+       this->Close(true);\r
+}\r
+\r
+//******************************************************************************\r
+// Event Table.\r
+//******************************************************************************\r
+\r
+BEGIN_EVENT_TABLE(MainFrame, wxFrame)\r
+       EVT_INIT_DIALOG(      MainFrame::OnInit)\r
+       // Menu\r
+       EVT_MENU(XRCID("Arc_Create"),  MainFrame::OnArcCreate)\r
+       EVT_MENU(XRCID("Arc_Open"),    MainFrame::OnArcOpen)\r
+       EVT_MENU(XRCID("Arc_Close"),   MainFrame::OnArcClose)\r
+       EVT_MENU(XRCID("Arc_Clone"),   MainFrame::OnArcClone)\r
+       EVT_MENU(XRCID("Arc_Add"),     MainFrame::OnArcAdd)\r
+       EVT_MENU(XRCID("Arc_SFX"),     MainFrame::OnArcConvert)\r
+       EVT_MENU(XRCID("Arc_UnSFX"),   MainFrame::OnArcConvert)\r
+       EVT_MENU(XRCID("Exe_Exit"),    MainFrame::OnExit)\r
+       EVT_MENU(XRCID("Arc_Extract"), MainFrame::OnArcExtract)\r
+       EVT_MENU(XRCID("Arc_Delete"),  MainFrame::OnArcDelete)\r
+       EVT_MENU(XRCID("Arc_Test"),    MainFrame::OnArcTest)\r
+       EVT_MENU(XRCID("Arc_Repair"),  MainFrame::OnArcRepair)\r
+       EVT_MENU(XRCID("Exe_Copy"),    MainFrame::OnExeCopy)\r
+       EVT_MENU(XRCID("Exe_View_Icons"),  MainFrame::OnViewMode)\r
+       EVT_MENU(XRCID("Exe_View_Details"),MainFrame::OnViewMode)\r
+       EVT_MENU(XRCID("Exe_View_List"),   MainFrame::OnViewMode)\r
+       EVT_MENU(XRCID("Exe_View_ToolBar"),MainFrame::OnShowToolBar)\r
+       EVT_MENU(XRCID("Exe_View_StatusBar"),MainFrame::OnShowStatusBar)\r
+       EVT_MENU(XRCID("Exe_View_SelectAll"),MainFrame::OnSelectAll)\r
+       // TreeView\r
+       EVT_TREE_SEL_CHANGED(XRCID("TreeView"), MainFrame::OnTreeChanged)\r
+       EVT_TREE_BEGIN_DRAG( XRCID("TreeView"), MainFrame::OnTreeBeginDrag)\r
+       EVT_COMMAND_CONTEXT_MENU(XRCID("TreeView"), MainFrame::OnContextMenu)\r
+       // ListView\r
+       EVT_LIST_ITEM_SELECTED(  XRCID("ListView"), MainFrame::OnListItemSelect)\r
+       EVT_LIST_ITEM_DESELECTED(XRCID("ListView"), MainFrame::OnListItemSelect)\r
+       EVT_LIST_ITEM_ACTIVATED( XRCID("ListView"), MainFrame::OnListItemDClick)\r
+       EVT_LIST_BEGIN_DRAG(     XRCID("ListView"), MainFrame::OnListBeginDrag)\r
+       EVT_COMMAND_CONTEXT_MENU(XRCID("ListView"), MainFrame::OnContextMenu)\r
+       // Filter\r
+       EVT_TEXT(XRCID("tcFilter"), MainFrame::OnFilter)\r
+END_EVENT_TABLE()\r
+\r
+//******************************************************************************\r
+// Event handler.\r
+//******************************************************************************\r
+\r
+void MainFrame::OnInit(wxInitDialogEvent&)\r
+{\r
+       // XRCと結びつけ。\r
+       this->menubar    = this->GetMenuBar();\r
+       this->toolbar    = this->GetToolBar();\r
+       this->statusbar = XRCCTRL(* this, "statusbar", wxStatusBar);\r
+       this->tree_ctrl = XRCCTRL(* this, "TreeView", wxTreeCtrl);\r
+       this->list_ctrl = XRCCTRL(* this, "ListView", myListCtrl);\r
+       this->window_splitter = XRCCTRL(* this, "window_splitter", wxSplitterWindow);\r
+       this->tcFilter  = XRCCTRL(* this->toolbar, "tcFilter", wxTextCtrl);\r
+\r
+       // 設定を読み込み。\r
+       this->SetSize(this->conf.ReadId(CONF_WINDOW_X, 0l), this->conf.ReadId(CONF_WINDOW_Y, 0l), this->conf.ReadId(CONF_WINDOW_WIDTH, 800l), this->conf.ReadId(CONF_WINDOW_HEIGHT, 400l), wxSIZE_ALLOW_MINUS_ONE);\r
+       wxTheMimeTypesManager->Initialize(wxMAILCAP_ALL);\r
+\r
+       // 初期値設定。\r
+       {\r
+               wxIcon icon;\r
+               icon.CopyFromBitmap(wxBitmap(L_DIR_S_ICO wxT("app.png"), wxBITMAP_TYPE_ANY));\r
+               this->SetIcon(icon);\r
+       }\r
+       wxCommandEvent e;\r
+       this->OnArcClose(e);\r
+       this->SetDropTarget(new myFileDropTarget(this));\r
+\r
+       // スプリッター設定。\r
+       this->window_splitter->SetSashPosition(this->conf.ReadId(CONF_WINDOW_SPLITTER_POS, 200l));\r
+\r
+       // リストビュー設定。\r
+       int nIconMode = this->conf.ReadId(CONF_LISTVIEW_SHOWMODE, 0l);\r
+       e.SetId(nIconMode == 1 ? XRCID("Exe_View_Icons") : (nIconMode == 2 ? XRCID("Exe_View_List") : XRCID("Exe_View_Details")));\r
+       this->OnViewMode(e);\r
+       // wxGTKでは直接wxLC_VIRTUALを指定しないと反映されない。\r
+       this->list_ctrl->SetSingleStyle(wxLC_VIRTUAL);\r
+       this->list_ctrl->InsertColumn(0, _("Filename"),      wxLIST_FORMAT_LEFT,   this->conf.ReadId(CONF_LISTVIEW_C_FILENAME, 140l));\r
+       this->list_ctrl->InsertColumn(1, _("Unpacked"),      wxLIST_FORMAT_RIGHT,  this->conf.ReadId(CONF_LISTVIEW_C_UNPACKED,  80l));\r
+       this->list_ctrl->InsertColumn(2, _("Packed"),        wxLIST_FORMAT_RIGHT,  this->conf.ReadId(CONF_LISTVIEW_C_PACKED,    80l));\r
+       this->list_ctrl->InsertColumn(3, _("Ratio"),         wxLIST_FORMAT_RIGHT,  this->conf.ReadId(CONF_LISTVIEW_C_RATIO,     50l));\r
+       this->list_ctrl->InsertColumn(4, _("Method"),        wxLIST_FORMAT_LEFT,   this->conf.ReadId(CONF_LISTVIEW_C_METHOD,    60l));\r
+       this->list_ctrl->InsertColumn(5, _("Attr"),          wxLIST_FORMAT_LEFT,   this->conf.ReadId(CONF_LISTVIEW_C_ATTR,      50l));\r
+       this->list_ctrl->InsertColumn(6, _("Last modified"), wxLIST_FORMAT_RIGHT,  this->conf.ReadId(CONF_LISTVIEW_C_LASTMOD,  150l));\r
+       this->list_ctrl->InsertColumn(7, _("Path"),          wxLIST_FORMAT_LEFT,   this->conf.ReadId(CONF_LISTVIEW_C_PATH,     100l));\r
+       this->list_ctrl->InsertColumn(8, _("Type"),          wxLIST_FORMAT_LEFT,   this->conf.ReadId(CONF_LISTVIEW_C_TYPE,     100l));\r
+       this->list_ctrl->InsertColumn(9, _("No."),           wxLIST_FORMAT_RIGHT,  this->conf.ReadId(CONF_LISTVIEW_C_NO,        35l));\r
+       this->list_ctrl->InsertColumn(10,_("Comment"),       wxLIST_FORMAT_LEFT,   this->conf.ReadId(CONF_LISTVIEW_C_COMMENT,   35l));\r
+       g_nSortColumn = this->conf.ReadId(CONF_LISTVIEW_S_COLUMN, 9l);\r
+       g_fSortAscend = this->conf.ReadId(CONF_LISTVIEW_S_ASCEND, true);\r
+\r
+       // ツールバー/ステータスバー設定。\r
+       int nStatusBarParts[] = {70, 70, 180, 50, -1};\r
+       this->statusbar->SetFieldsCount(5, nStatusBarParts);\r
+       this->SetStatusBarPane(-1);\r
+       bool fShow = this->conf.ReadId(CONF_WINDOW_STATUSBAR, true);\r
+       this->menubar->Check(XRCID("Exe_View_StatusBar"), fShow);\r
+       this->statusbar->Show(fShow);\r
+       fShow = this->conf.ReadId(CONF_WINDOW_TOOLBAR, true);\r
+       this->menubar->Check(XRCID("Exe_View_ToolBar"), fShow);\r
+       this->toolbar->Show(fShow);\r
+}\r
+\r
+// MenuBar\r
+\r
+void MainFrame::OnExit(wxCommandEvent&)\r
+{\r
+       this->Close(true);\r
+}\r
+\r
+void MainFrame::OnArcCreate(wxCommandEvent& e)\r
+{\r
+       TPI_SWITCHES swInfo;\r
+       swInfo.pCustomSwitches = NULL;\r
+\r
+       // 作成ダイアログを設定。\r
+       MakeDialog mkDlg;\r
+       ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));\r
+       ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));\r
+\r
+       if (e.GetClientData() == NULL)\r
+       {\r
+               // 処理対象のファイルを選択。\r
+               wxFileDialog fd(this, _("Choose files to compress"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0), wxEmptyString, wxFileSelectorDefaultWildcardStr, wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);\r
+               if (fd.ShowModal() == wxID_CANCEL)\r
+               {\r
+                       return;\r
+               }\r
+               swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());\r
+               this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());\r
+               fd.GetFilenames(mkDlg.files);\r
+       }\r
+       else\r
+       {\r
+               mkDlg.files = * (wxArrayString *) e.GetClientData();\r
+               swInfo.fnDestinationDirectory = wxFileName::DirName(wxFileName(mkDlg.files[0]).GetPath());\r
+               // 相対パスに変換。\r
+               for (size_t n = 0; n < mkDlg.files.GetCount(); n++)\r
+               {\r
+                       wxFileName fn(mkDlg.files[n]);\r
+                       fn.MakeRelativeTo(swInfo.fnDestinationDirectory.GetPath());\r
+                       mkDlg.files[n] = fn.GetFullPath();\r
+               }\r
+       }\r
+\r
+       this->OnArcClose(e);\r
+       // 書庫名はファイル名の拡張子より前、もしくはディレクトリ名。\r
+       this->fnArchive = wxFileName(mkDlg.files[0]);\r
+       this->fnArchive.SetName(mkDlg.files.GetCount() == 1 ? (this->fnArchive.GetName().IsEmpty() ? this->fnArchive.GetDirs().Last() : this->fnArchive.GetName()) : swInfo.fnDestinationDirectory.GetDirs().Last());\r
+       this->fnArchive.SetEmptyExt();\r
+       this->fnArchive.SetPath(swInfo.fnDestinationDirectory.GetPath());\r
+\r
+       // ダイアログを表示。\r
+       if (mkDlg.ShowModal() == wxID_CANCEL)\r
+       {\r
+               return;\r
+       }\r
+\r
+       // 各種設定。\r
+       swInfo.fStoreDirectoryPathes= ! mkDlg.cbIgnorePath->IsChecked();\r
+       swInfo.fMakeSFX                     = mkDlg.cbMakeSFX->IsChecked();\r
+       swInfo.fSolid               = mkDlg.cbSolid->IsChecked();\r
+       swInfo.fMMOptimize          = mkDlg.cbMMOptimize->IsChecked();\r
+       swInfo.fEncryptHeader       = mkDlg.cbEncryptHeader->IsChecked();\r
+       swInfo.fCompressHeader      = mkDlg.cbCompressHeader->IsChecked();\r
+       swInfo.nCompressLevel       = mkDlg.scLevel->GetValue();\r
+       swInfo.nRecoveryRecord      = mkDlg.scRR->GetValue();\r
+       swInfo.szPassword           = mkDlg.tcPassword->GetValue();\r
+       swInfo.szKeyFile            = mkDlg.tcKeyfile->GetValue();\r
+       swInfo.szComment            = mkDlg.tcComment->GetValue();\r
+       mkDlg.cbSplitSize->GetValue().ToULongLong(& swInfo.nSplitSize);\r
+\r
+       // TPIを読み込み。\r
+       int nSelected = mkDlg.chType->GetSelection();\r
+       this->fnArchive = wxFileName(mkDlg.cbDir->GetValue(), mkDlg.cbFileName->GetValue());\r
+       if (! tpi.InitLibrary(mkDlg.afInfo[nSelected].szTPIName, this->fnArchive.GetFullPath(), mkDlg.afInfo[nSelected].nTypeId))\r
+       {\r
+               this->ErrorCheck(tpi.nErrorCode, wxT("InitLibrary"));\r
+               return;\r
+       }\r
+\r
+       // コールバック関数を設定。\r
+       tpi.SetCallbackProc(TPICallbackProc);\r
+       this->ErrorCheck(tpi.nErrorCode, wxT("SetCallbackProc"));\r
+\r
+       // 処理を行う。\r
+       {\r
+               ProcessDialog procDlg;\r
+               procDlg.Show(true);\r
+\r
+               // コールバックを送信。\r
+               TPI_PROCESSINFO piInfo;\r
+               piInfo.eMessage = TPI_MESSAGE_STATUS;\r
+               piInfo.eStatus = 0x1000;\r
+               piInfo.fiInfo.fnFileName = this->fnArchive;\r
+               piInfo.fiInfo.nUnpackedSize = mkDlg.files.GetCount();\r
+               procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo);\r
+\r
+               tpi.Command(TPI_COMMAND_CREATE, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files);\r
+               this->ErrorCheck(tpi.nErrorCode);\r
+               procDlg.Show(false);\r
+       }\r
+       tpi.FreeLibrary();\r
+\r
+       if (mkDlg.cbOpenAfter->IsChecked())\r
+       {\r
+               // 作成先を開く。\r
+               ::wxExecute(DIR_APP + QuoteString(swInfo.fnDestinationDirectory.GetFullPath()));\r
+       }\r
+\r
+       if (mkDlg.cbExitAfter->IsChecked())\r
+       {\r
+               // 終了。\r
+               this->Close(true);\r
+       }\r
+\r
+       // 終了しない場合は書庫を開く。\r
+       this->OnArcOpen(e);\r
+}\r
+\r
+void MainFrame::OnArcOpen(wxCommandEvent& e)\r
+{\r
+       // モード取得。通常は0, それ以外で開く場合は1, ファイルDnDなら2。\r
+       int nMode = e.GetInt() == 2 ? 2 : e.GetId() == XRCID("Arc_Open") ? 0 : 1;\r
+\r
+       // 書庫を選択。\r
+       if (nMode == 0)\r
+       {\r
+               wxFileDialog fd(this, _("Choose an archive"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0), wxEmptyString, wxFileSelectorDefaultWildcardStr, wxFD_OPEN | wxFD_FILE_MUST_EXIST);\r
+               if (fd.ShowModal() == wxID_CANCEL)\r
+               {\r
+                       return;\r
+               }\r
+               this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());\r
+               this->fnArchive = wxFileName(fd.GetPath());\r
+       }\r
+\r
+       // 進捗ダイアログ表示。\r
+       ProcessDialog procDlg;\r
+       procDlg.Show(true);\r
+\r
+       // DnD以外で書庫を開く場合、TPIを読み込み。\r
+       TPI_PROCESSINFO piInfo;\r
+       piInfo.fiInfo.nUnpackedSize = e.GetExtraLong();\r
+       if (nMode != 2 && ! this->LoadTPI(this->fnArchive.GetFullPath(), & piInfo.fiInfo.nUnpackedSize))\r
+       {\r
+               procDlg.Show(false);\r
+               tpi.FreeLibrary();\r
+               if (this->IsShown())\r
+               {\r
+                       wxBell();\r
+                       this->statusbar->SetStatusText(_("No plug-in supporting this archive was found!"), 4);\r
+               }\r
+               else\r
+               {\r
+                       wxLogError(_("No plug-in supporting this archive was found!"));\r
+                       this->Close(true);\r
+               }\r
+               return;\r
+       }\r
+\r
+       // 最初のコールバックを送信。\r
+       piInfo.eMessage = TPI_MESSAGE_STATUS;\r
+       piInfo.eStatus = 0x1000;\r
+       piInfo.nProcessedSize = 0;\r
+       piInfo.fiInfo.fnFileName = this->fnArchive;\r
+       procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo);\r
+\r
+       // 配列のサイズを確保。\r
+       this->fileinfo.Alloc(piInfo.fiInfo.nUnpackedSize);\r
+\r
+       // 履歴に追加。\r
+       this->conf.WriteHistory(CONF_HISTORY_PATH, this->fnArchive.GetPath());\r
+       this->conf.WriteHistory(CONF_HISTORY_NAME, this->fnArchive.GetFullName());\r
+       this->conf.WriteHistory(CONF_HISTORY_FULL, this->fnArchive.GetFullPath());\r
+\r
+       // 書庫のアイコンを取得し、書庫ルートを作成。\r
+       g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_closed.png"), wxBITMAP_TYPE_ANY));\r
+       g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_open.png"), wxBITMAP_TYPE_ANY));\r
+       this->tree_ctrl->SetImageList(& g_hIconT);\r
+       wxTreeItemId\r
+               idRoot = this->tree_ctrl->AddRoot(wxEmptyString),\r
+#ifdef __WINDOWS__\r
+               idArchive = this->tree_ctrl->AppendItem(idRoot, piInfo.fiInfo.fnFileName.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName))),\r
+#else\r
+               idArchive = this->tree_ctrl->AppendItem(idRoot, piInfo.fiInfo.fnFileName.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName).ConvertToImage().Rescale(16, 16))),\r
+#endif\r
+               idArcRoot = this->tree_ctrl->AppendItem(idRoot, wxT("-----"), 0, 1);\r
+\r
+       // ファイル情報をロード。\r
+       if (tpi.GetFileInformation(& piInfo.fiInfo, true))\r
+       {\r
+               piInfo.eStatus = 0x1001;\r
+               do\r
+               {\r
+                       piInfo.nProcessedSize++;\r
+                       if (this->ErrorCheck(procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo)) == TPI_CALLBACK_CANCEL)\r
+                       {\r
+                               procDlg.Show(false);\r
+                               tpi.CloseArchive();\r
+                               wxCommandEvent e;\r
+                               this->OnArcClose(e);\r
+                               return;\r
+                       }\r
+\r
+                       // 拡張子のみ設定されている場合。\r
+                       if (piInfo.fiInfo.szStoredName.IsEmpty())\r
+                       {\r
+                               piInfo.fiInfo.szStoredName = this->fnArchive.GetName();\r
+                               if (piInfo.fiInfo.fnFileName.HasExt())\r
+                               {\r
+                                       piInfo.fiInfo.szStoredName += wxT('.') + piInfo.fiInfo.fnFileName.GetExt();\r
+                               }\r
+                               piInfo.fiInfo.fnFileName = wxFileName(piInfo.fiInfo.szStoredName);\r
+                       }\r
+\r
+                       // セキュリティチェック。\r
+                       // ルート記号を削除。\r
+                       wxString szPath = piInfo.fiInfo.fnFileName.GetPathWithSep(wxPATH_UNIX);\r
+                       if (szPath.StartsWith(wxT("/")))\r
+                       {\r
+                               piInfo.fiInfo.fnFileName = wxFileName(szPath.AfterFirst(wxT('/')), piInfo.fiInfo.fnFileName.GetFullName(), wxPATH_DOS);\r
+                       }\r
+\r
+                       // 改行文字/タブ文字などを削除。\r
+                       if (piInfo.fiInfo.szStoredName.Find(wxT('\r')) != wxNOT_FOUND\r
+                       ||  piInfo.fiInfo.szStoredName.Find(wxT('\n')) != wxNOT_FOUND\r
+                       ||  piInfo.fiInfo.szStoredName.Find(wxT('\t')) != wxNOT_FOUND)\r
+                       {\r
+                               wxString sz = piInfo.fiInfo.fnFileName.GetFullPath();\r
+                               sz.Replace(wxT("\r"), wxT(" "));\r
+                               sz.Replace(wxT("\n"), wxT(" "));\r
+                               sz.Replace(wxT("\t"), wxT(" "));\r
+                               piInfo.fiInfo.eDanger = TRUE;\r
+                               piInfo.fiInfo.fnFileName = wxFileName(sz);\r
+                               wxLogWarning(_("This archive may contain files whose name contains some special characters like CR(\\r), LF(\\n), Tab(\\t) and some problem would be happen if you extract these files. Don\'t extract these files carelessly.\nDanger file is:\n%s"), piInfo.fiInfo.fnFileName.GetFullPath().c_str());\r
+                       }\r
+\r
+                       // DTV検査。\r
+                       if (piInfo.fiInfo.fnFileName.GetPathWithSep(wxPATH_UNIX).Find(wxT("../")) != wxNOT_FOUND)\r
+                       {\r
+                               piInfo.fiInfo.eDanger = TRUE;\r
+                               wxLogWarning(_("This archive may have Directory Traversal Vulnerability(DTV) problem, and some danger files may be extracted to the unexpected system directory! You should use the \"Ignore file pathes\" option when extracting this archive.\nDanger file is:\n%s"), piInfo.fiInfo.fnFileName.GetFullPath().c_str());\r
+                       }\r
+                       // 空白の連続による拡張子偽装を検査。\r
+                       if (piInfo.fiInfo.fnFileName.GetFullName().Find(wxT("        ")) != wxNOT_FOUND)\r
+                       {\r
+                               piInfo.fiInfo.eDanger = TRUE;\r
+                               wxLogWarning(_("This archive may contain extension-disguised files whose real extension is hidden by using many blank charactor and you may mistake that it is a \"safe\" file. Don\'t execute these files carelessly.\nDanger file is:\n%s"), piInfo.fiInfo.fnFileName.GetFullPath().c_str());\r
+                       }\r
+                       // Unicode制御文字を検査。\r
+                       for (wxChar c = 0x200c; c <= 0x206f; c++)\r
+                       {\r
+                               if (piInfo.fiInfo.fnFileName.GetFullName().Find(c) != wxNOT_FOUND)\r
+                               {\r
+                                       piInfo.fiInfo.eDanger = TRUE;\r
+                                       wxLogWarning(_("This archive may contain extension-disguised files whose real extension is hidden by using Unicode control character and you may mistake that it is a \"safe\" file. Don\'t execute these files carelessly.\nDanger file is:\n%s"), piInfo.fiInfo.fnFileName.GetFullPath().c_str());\r
+                               }\r
+                               switch (c)\r
+                               {\r
+                               case 0x200f: c = 0x2027; break;\r
+                               case 0x202e: c = 0x2060; break;\r
+                               }\r
+                       }\r
+\r
+                       // ツリービューに反映。\r
+                       bool fDir = piInfo.fiInfo.dwAttribute & TPI_ATTRIBUTE_DIRECTORY ? true : false;\r
+                       TreeView_CheckNewerItem(this->tree_ctrl, idArcRoot, fDir ? piInfo.fiInfo.fnFileName.GetFullPath() : piInfo.fiInfo.fnFileName.GetPath(), true);\r
+\r
+                       // ディレクトリ属性を含むものについては情報を保存しない。\r
+                       if (fDir)\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       // 情報を保存してカウントアップ。\r
+                       this->fileinfo.Add(piInfo.fiInfo);\r
+               }\r
+               while (tpi.GetFileInformation(& piInfo.fiInfo));\r
+       }\r
+\r
+       // GetFileInformationがエラー終了した場合。\r
+       this->ErrorCheck(tpi.nErrorCode, wxT("GetFileInformation"));\r
+\r
+       // 書庫の情報を取得。\r
+       tpi.GetArchiveInformation(& this->aiArchive);\r
+       this->ErrorCheck(tpi.nErrorCode, wxT("GetArchiveInformation"));\r
+\r
+       // 書庫を閉じる。\r
+       tpi.CloseArchive();\r
+       this->ErrorCheck(tpi.nErrorCode, wxT("CloseArchive"));\r
+\r
+       // 以下、UI処理。\r
+       this->fileinfo.Shrink();\r
+       this->tree_ctrl->ExpandAll();\r
+       this->tree_ctrl->ScrollTo(idArchive);\r
+       this->tree_ctrl->SelectItem(idArchive);\r
+       this->list_ctrl->atDangerItem.SetTextColour(* wxRED);\r
+       this->list_ctrl->atEncryptedItem.SetTextColour(wxColour(wxT("forest green")));\r
+\r
+       // ステータスバー設定。\r
+       this->statusbar->SetStatusText(this->aiArchive.fiInfo.szTypeName, 0);\r
+       this->statusbar->SetStatusText(wxString::Format(_("%u file(s)"), this->fileinfo.GetCount()), 1);\r
+       this->statusbar->SetStatusText(wxString::Format(wxString("%" wxLongLongFmtSpec "uB -> %" wxLongLongFmtSpec "uB"), this->aiArchive.nUnpackedSize, this->aiArchive.nPackedSize), 2);\r
+       this->statusbar->SetStatusText(wxString::Format(wxT("%3.1f%%"), this->aiArchive.wCompressRatio / 10.0), 3);\r
+       this->statusbar->SetStatusText(this->fnArchive.GetFullPath(), 4);\r
+\r
+       // ツールバー・メニューバー設定。ファイル選択時しか動作しない削除などは別に設定。\r
+       SetMenuToolState("Arc_Close",   true);\r
+       SetMenuToolState("Arc_Add",     (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_ADD)   == TPI_COMMAND_ADD   && this->aiArchive.fiInfo.fArchive);\r
+       SetMenuToolState("Arc_SFX",     (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_SFX)    == TPI_COMMAND_SFX   && ! this->aiArchive.fSFX);\r
+       SetMenuToolState("Arc_UnSFX",   (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_UNSFX)  == TPI_COMMAND_UNSFX && this->aiArchive.fSFX);\r
+       SetMenuToolState("Arc_Extract", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_EXTRACT)== TPI_COMMAND_EXTRACT);\r
+       SetMenuToolState("Arc_Test",    (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_TEST)   == TPI_COMMAND_TEST);\r
+       SetMenuToolState("Arc_Repair",  (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_REPAIR) == TPI_COMMAND_REPAIR);\r
+       this->menubar->Enable(XRCID("Arc_Clone"), true);\r
+\r
+       procDlg.Show(false);\r
+       this->Raise();\r
+}\r
+\r
+void MainFrame::OnArcClose(wxCommandEvent& e)\r
+{\r
+       // ツリービュー・リストビュー設定。\r
+       this->tree_ctrl->DeleteAllItems();\r
+       this->list_ctrl->DeleteAllItems();\r
+       this->list_ctrl->apShowFile.Clear();\r
+\r
+       // ツールバー・メニューバー設定。\r
+       SetMenuToolState("Arc_Close",   false);\r
+       SetMenuToolState("Arc_Add",     false);\r
+       SetMenuToolState("Arc_SFX",     false);\r
+       SetMenuToolState("Arc_UnSFX",   false);\r
+       SetMenuToolState("Arc_Extract", false);\r
+       SetMenuToolState("Arc_Delete",  false);\r
+       SetMenuToolState("Arc_Test",    false);\r
+       SetMenuToolState("Arc_Repair",  false);\r
+       this->menubar->Enable(XRCID("Arc_Clone"), false);\r
+\r
+       for (int i = 0; i < this->statusbar->GetFieldsCount(); i++)\r
+       {\r
+               this->statusbar->SetStatusText(wxEmptyString, i);\r
+       }\r
+       this->fileinfo.Clear();\r
+       this->aiArchive.szComment.Empty();\r
+       this->aiArchive.fnArchive.Clear();\r
+       this->aiArchive.fiInfo.szTypeName.Empty();\r
+       this->aiArchive.fiInfo.szSuffix.Empty();\r
+       this->aiArchive.fiInfo.szEngineName.Empty();\r
+       this->aiArchive.fiInfo.szTPIName.Empty();\r
+\r
+       g_hIconT.RemoveAll();\r
+       g_hIconLL.RemoveAll();\r
+       g_hIconLS.RemoveAll();\r
+\r
+       // DnDで書庫を開くときは既に読み込まれているTPIを用いるので、解放してはいけない。\r
+       if (e.GetExtraLong() == 0)\r
+       {\r
+               tpi.FreeLibrary();\r
+       }\r
+}\r
+\r
+void MainFrame::OnArcClone(wxCommandEvent&)\r
+{\r
+       // 保存先を尋ねる。\r
+       wxFileDialog fd(this, _("Clone archive"), this->fnArchive.GetPath(), this->fnArchive.GetFullName(), wxFileSelectorDefaultWildcardStr, wxFD_SAVE | wxFD_OVERWRITE_PROMPT);\r
+       if (fd.ShowModal() == wxID_CANCEL)\r
+       {\r
+               return;\r
+       }\r
+       this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());\r
+\r
+       // コピー。\r
+       ::wxCopyFile(this->fnArchive.GetFullPath(), fd.GetPath());\r
+       wxFileName fn(fd.GetPath());\r
+       wxDateTime dtAccess, dtModify, dtCreate;\r
+       this->fnArchive.GetTimes(& dtAccess, & dtModify, & dtCreate);\r
+       fn.SetTimes(& dtAccess, & dtModify, & dtCreate);\r
+}\r
+\r
+void MainFrame::OnArcAdd(wxCommandEvent& e)\r
+{\r
+       // 作成ダイアログを設定。\r
+       MakeDialog mkDlg;\r
+       ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));\r
+       ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));\r
+       mkDlg.uCommand = TPI_COMMAND_ADD;\r
+\r
+       // 処理対象のファイルを選択。\r
+       wxFileDialog fd(this, _("Choose files to add"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0), wxEmptyString, wxFileSelectorDefaultWildcardStr, wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);\r
+       if (fd.ShowModal() == wxID_CANCEL)\r
+       {\r
+               return;\r
+       }\r
+       fd.GetFilenames(mkDlg.files);\r
+       this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());\r
+\r
+       // ダイアログを表示。\r
+       if (mkDlg.ShowModal() == wxID_CANCEL)\r
+       {\r
+               return;\r
+       }\r
+\r
+       // 各種設定。\r
+       TPI_SWITCHES swInfo;\r
+       swInfo.pCustomSwitches       = NULL;\r
+       swInfo.fMakeSFX              = false;\r
+       swInfo.fnDestinationDirectory= wxFileName::DirName(fd.GetDirectory());\r
+       swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();\r
+       swInfo.fSolid               = mkDlg.cbSolid->IsChecked();\r
+       swInfo.fMMOptimize          = mkDlg.cbMMOptimize->IsChecked();\r
+       swInfo.fEncryptHeader       = mkDlg.cbEncryptHeader->IsChecked();\r
+       swInfo.nCompressLevel       = mkDlg.scLevel->GetValue();\r
+       swInfo.nRecoveryRecord      = mkDlg.scRR->GetValue();\r
+       swInfo.szPassword           = mkDlg.tcPassword->GetValue();\r
+       swInfo.szKeyFile            = mkDlg.tcKeyfile->GetValue();\r
+       swInfo.szComment            = mkDlg.tcComment->GetValue();\r
+\r
+       // 処理を行う。\r
+       {\r
+               ProcessDialog procDlg;\r
+               procDlg.Show(true);\r
+\r
+               // コールバックを送信。\r
+               TPI_PROCESSINFO piInfo;\r
+               piInfo.eMessage = TPI_MESSAGE_STATUS;\r
+               piInfo.eStatus = 0x1000;\r
+               piInfo.fiInfo.fnFileName = this->fnArchive;\r
+               piInfo.fiInfo.nUnpackedSize = mkDlg.files.GetCount();\r
+               procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo);\r
+\r
+               tpi.Command(TPI_COMMAND_ADD, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files);\r
+               this->ErrorCheck(tpi.nErrorCode);\r
+               procDlg.Show(false);\r
+       }\r
+\r
+       if (mkDlg.cbOpenAfter->IsChecked())\r
+       {\r
+               // 作成先を開く。\r
+               ::wxExecute(DIR_APP + QuoteString(swInfo.fnDestinationDirectory.GetFullPath()));\r
+       }\r
+\r
+       if (mkDlg.cbExitAfter->IsChecked())\r
+       {\r
+               // 終了。\r
+               this->Close(true);\r
+       }\r
+\r
+       // 終了しない場合は書庫を再読み込み。\r
+       this->OnArcOpen(e);\r
+}\r
+\r
+void MainFrame::OnArcConvert(wxCommandEvent& e)\r
+{\r
+       TPI_SWITCHES swInfo;\r
+       swInfo.fMakeSFX = e.GetId() == XRCID("Arc_SFX");\r
+\r
+       // 保存先を尋ねる。\r
+       wxFileDialog fd(this, swInfo.fMakeSFX ? _("Save as SFX") : _("Save as normal archive"), this->fnArchive.GetPath(), this->fnArchive.GetName() + (swInfo.fMakeSFX ? EXE_EXT : (wxString) wxEmptyString), wxFileSelectorDefaultWildcardStr, wxFD_SAVE | wxFD_OVERWRITE_PROMPT);\r
+       if (fd.ShowModal() == wxID_CANCEL)\r
+       {\r
+               return;\r
+       }\r
+       swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());\r
+       this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());\r
+\r
+       wxArrayString files;\r
+       files.Add(fd.GetPath());\r
+\r
+       ProcessDialog procDlg;\r
+       procDlg.Show(true);\r
+       tpi.Command(swInfo.fMakeSFX ? TPI_COMMAND_SFX : TPI_COMMAND_UNSFX, & swInfo, this->fnArchive.GetFullPath(), files);\r
+       this->ErrorCheck(tpi.nErrorCode);\r
+       procDlg.Show(false);\r
+}\r
+\r
+void MainFrame::OnArcExtract(wxCommandEvent& e)\r
+{\r
+       TPI_SWITCHES swInfo;\r
+       swInfo.pCustomSwitches = NULL;\r
+\r
+       // モード取得。通常は0, 実行なら1, ファイルDnDなら2、ディレクトリDnDなら3、クリップボードなら4、コンテキストメニューからなら8。\r
+       int nMode = e.GetInt();\r
+       if (e.GetInt() == 8)\r
+       {\r
+               nMode = 0;\r
+       }\r
+       // 実行時のみ使用。\r
+       wxFileType * ftFile = NULL;\r
+\r
+       // 展開ダイアログを作成。DnDまたは実行時は表示しない。\r
+       MakeDialog mkDlg;\r
+       ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));\r
+       ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));\r
+       mkDlg.uCommand = TPI_COMMAND_EXTRACT;\r
+       mkDlg.files    = MakeTargetFileList(this, nMode == 1);\r
+\r
+       if (nMode != 0)\r
+       {\r
+               // 作業ディレクトリ作成。\r
+               swInfo.fStoreDirectoryPathes = false;\r
+               wxString szDestDirBase = nMode == 3 ? this->tree_ctrl->GetItemText(this->tree_ctrl->GetSelection()) : wxT("tpi_tmp");\r
+               wxStandardPaths p;\r
+               if (szDestDirBase == wxT("-----"))\r
+               {\r
+                       // 書庫ルートのときは書庫名にしておく。\r
+                       szDestDirBase = this->fnArchive.GetName();\r
+               }\r
+               swInfo.fnDestinationDirectory = MakeDirPath(wxFileName::DirName(p.GetTempDir()), szDestDirBase, true);\r
+               if (! swInfo.fnDestinationDirectory.IsOk())\r
+               {\r
+                       wxLogError(_("Unable to make the temporary directory!"));\r
+                       return;\r
+               }\r
+       }\r
+       else\r
+       {\r
+               if (mkDlg.ShowModal() == wxID_CANCEL)\r
+               {\r
+                       return;\r
+               }\r
+\r
+               // 各種設定。\r
+               swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();\r
+               swInfo.fnDestinationDirectory = wxFileName::DirName(mkDlg.cbDir->GetValue());\r
+               swInfo.szPassword = mkDlg.tcPassword->GetValue();\r
+               swInfo.szKeyFile  = mkDlg.tcKeyfile->GetValue();\r
+\r
+               // 必要なら書庫名でディレクトリを作成する。\r
+               if (WillMakeDirByArcName(this, & mkDlg))\r
+               {\r
+                       swInfo.fnDestinationDirectory = MakeDirPath(swInfo.fnDestinationDirectory, this->fnArchive.GetName(), true);\r
+                       if (! swInfo.fnDestinationDirectory.IsOk())\r
+                       {\r
+                               wxLogError(_("Unable to make the destination directory!"));\r
+                               return;\r
+                       }\r
+               }\r
+       }\r
+\r
+       // 処理を行う。\r
+       {\r
+               ProcessDialog procDlg;\r
+               procDlg.Show(true);\r
+\r
+               // コールバックを送信。\r
+               TPI_PROCESSINFO piInfo;\r
+               piInfo.eMessage = TPI_MESSAGE_STATUS;\r
+               piInfo.eStatus = 0x1000;\r
+               piInfo.fiInfo.fnFileName = this->fnArchive;\r
+               piInfo.fiInfo.nUnpackedSize = mkDlg.files.GetCount();\r
+               procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo);\r
+\r
+               tpi.Command(TPI_COMMAND_EXTRACT, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files);\r
+               this->ErrorCheck(tpi.nErrorCode);\r
+               procDlg.Show(false);\r
+       }\r
+\r
+       if (nMode == 0)\r
+       {\r
+               if (mkDlg.cbOpenAfter->IsChecked())\r
+               {\r
+                       // 展開先を開く。\r
+                       ::wxExecute(DIR_APP + QuoteString(swInfo.fnDestinationDirectory.GetFullPath()));\r
+               }\r
+\r
+               if (mkDlg.cbExitAfter->IsChecked())\r
+               {\r
+                       // 終了。\r
+                       this->Close(true);\r
+               }\r
+       }\r
+       else\r
+       {\r
+               if (nMode == 1)\r
+               {\r
+                       // コマンドを取得。\r
+                       ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(wxFileName(mkDlg.files[0], wxPATH_DOS).GetExt());\r
+                       if (! ftFile || ftFile->GetOpenCommand(wxEmptyString).IsEmpty())\r
+                       {\r
+                               // 種類が取得できないときはテキストとみなす。\r
+                               ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(this->conf.ReadId(CONF_DEFAULT_EXT, (wxString) wxT("txt")));\r
+                       }\r
+\r
+                       // コマンドを実行。\r
+                       wxString szTempFile = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[0], wxPATH_DOS).GetFullName();\r
+                       bool fSuccess = tpi.nErrorCode == TPI_ERROR_SUCCESS && ftFile != NULL;\r
+                       myProcess * pCallback = new myProcess(szTempFile, swInfo.fnDestinationDirectory.GetPath());\r
+                       if (fSuccess)\r
+                       {\r
+#ifdef __LINUX__\r
+                               // Linuxでは引用符で囲む必要がある。\r
+                               fSuccess = ::wxExecute(ftFile->GetOpenCommand(QuoteString(szTempFile)), wxEXEC_ASYNC, pCallback) > 0;\r
+#else\r
+                               fSuccess = ::wxExecute(ftFile->GetOpenCommand(szTempFile), wxEXEC_ASYNC, pCallback) > 0;\r
+#endif\r
+                       }\r
+                       if (! fSuccess)\r
+                       {\r
+                               pCallback->OnTerminate(0, 0);\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       // 展開対象を決定。\r
+                       wxArrayString asFiles;\r
+                       myFileDataObject * objFile = new myFileDataObject();\r
+                       objFile->szTempDir = nMode == 3 ? swInfo.fnDestinationDirectory.GetPath() : swInfo.fnDestinationDirectory.GetFullPath();\r
+                       for (size_t i = 0; i < mkDlg.files.GetCount(); i++)\r
+                       {\r
+                               wxString szFileName = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[i], wxPATH_DOS).GetFullName();\r
+                               if (nMode == 3)\r
+                               {\r
+                                       asFiles.Add(szFileName);\r
+                               }\r
+                               else\r
+                               {\r
+                                       // リストに追加。\r
+                                       objFile->AddFile(szFileName);\r
+                               }\r
+                       }\r
+                       if (nMode == 3)\r
+                       {\r
+                               objFile->AddFile(objFile->szTempDir);\r
+                       }\r
+\r
+                       if (nMode == 4)\r
+                       {\r
+                               wxTheClipboard->SetData(objFile);\r
+                       }\r
+                       else\r
+                       {\r
+                               // 自身にドロップされると煩雑なので、一時的にドロップを受け付けないようにしておく。\r
+                               this->SetDropTarget(NULL);\r
+\r
+                               // DnD開始。\r
+                               wxDropSource dropSource(* objFile, this);\r
+                               wxDragResult drResult = dropSource.DoDragDrop();\r
+                               if (drResult != wxDragCancel && drResult != wxDragNone && drResult != wxDragMove)\r
+                               {\r
+#ifdef __LINUX__\r
+                                       // Linuxではまだ処理が終わっていない(コンテキストメニューが表示されている)ので、とりあえず3秒だけ待つ。\r
+                                       sleep(3);\r
+#endif\r
+                               }\r
+                               this->SetDropTarget(new myFileDropTarget(this));\r
+\r
+                               // ディレクトリDnDのときは、先にディレクトリの中のファイルを消しておく。\r
+                               if (nMode == 3)\r
+                               {\r
+                                       for (size_t i = 0; i < asFiles.GetCount(); i++)\r
+                                       {\r
+                                               chmod(asFiles[i].ToUTF8(), 0600);\r
+                                               ::wxRemoveFile(asFiles[i]);\r
+                                       }\r
+                               }\r
+\r
+                               delete objFile;\r
+                       }\r
+               }\r
+       }\r
+}\r
+\r
+void MainFrame::OnArcDelete(wxCommandEvent& e)\r
+{\r
+       // 全ファイル削除は危険ではないかと。\r
+       if (this->list_ctrl->GetSelectedItemCount() == 0)\r
+       {\r
+               // wxのバグで自動では無効化できないので、実行しようとしたときに無効化する。\r
+               SetMenuToolState("Arc_Delete", false);\r
+               return;\r
+       }\r
+\r
+       if (::AskDlg(_("Are you sure to delete selected files?"), this) == wxNO)\r
+       {\r
+               return;\r
+       }\r
+\r
+       // 処理を行う。\r
+       {\r
+               TPI_SWITCHES swInfo;\r
+               ProcessDialog procDlg;\r
+               procDlg.Show(true);\r
+               wxArrayString asFiles = MakeTargetFileList(this, false);\r
+\r
+               // コールバックを送信。\r
+               TPI_PROCESSINFO piInfo;\r
+               piInfo.eMessage = TPI_MESSAGE_STATUS;\r
+               piInfo.eStatus = 0x1000;\r
+               piInfo.fiInfo.fnFileName = this->fnArchive;\r
+               piInfo.fiInfo.nUnpackedSize = asFiles.GetCount();\r
+               procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo);\r
+\r
+               tpi.Command(TPI_COMMAND_DELETE, & swInfo, this->fnArchive.GetFullPath(), asFiles);\r
+               this->ErrorCheck(tpi.nErrorCode);\r
+               procDlg.Show(false);\r
+       }\r
+\r
+       // 書庫を再読み込みする。\r
+       this->OnArcOpen(e);\r
+}\r
+\r
+void MainFrame::OnArcTest(wxCommandEvent&)\r
+{\r
+       // 処理を行う。\r
+       ProcessDialog procDlg;\r
+       procDlg.Show(true);\r
+       wxArrayString asFiles = MakeTargetFileList(this, false);\r
+\r
+       // コールバックを送信。\r
+       TPI_PROCESSINFO piInfo;\r
+       piInfo.eMessage = TPI_MESSAGE_STATUS;\r
+       piInfo.eStatus = 0x1000;\r
+       piInfo.fiInfo.fnFileName = this->fnArchive;\r
+       piInfo.fiInfo.nUnpackedSize = asFiles.GetCount();\r
+       procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo);\r
+\r
+       TPI_SWITCHES swInfo;\r
+       bool bIsCorrect = tpi.Command(TPI_COMMAND_TEST, & swInfo, this->fnArchive.GetFullPath(), asFiles);\r
+       procDlg.Show(false);\r
+\r
+       if (bIsCorrect)\r
+       {\r
+               wxLogMessage(_("This is a correct archive."));\r
+       }\r
+       else\r
+       {\r
+               this->ErrorCheck(tpi.nErrorCode);\r
+       }\r
+}\r
+\r
+void MainFrame::OnArcRepair(wxCommandEvent&)\r
+{\r
+       // 処理を行う。\r
+       ProcessDialog procDlg;\r
+       procDlg.Show(true);\r
+       wxArrayString asFiles = MakeTargetFileList(this, false);\r
+\r
+       // コールバックを送信。\r
+       TPI_PROCESSINFO piInfo;\r
+       piInfo.eMessage = TPI_MESSAGE_STATUS;\r
+       piInfo.eStatus = 0x1000;\r
+       piInfo.fiInfo.fnFileName = this->fnArchive;\r
+       piInfo.fiInfo.nUnpackedSize = asFiles.GetCount();\r
+       procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo);\r
+\r
+       TPI_SWITCHES swInfo;\r
+       tpi.Command(TPI_COMMAND_REPAIR, & swInfo, this->fnArchive.GetFullPath(), asFiles);\r
+       this->ErrorCheck(tpi.nErrorCode);\r
+       procDlg.Show(false);    \r
+}\r
+\r
+void MainFrame::OnExeCopy(wxCommandEvent & e)\r
+{\r
+       if (this->list_ctrl->GetSelectedItemCount() == 0)\r
+       {\r
+               // wxのバグで自動では無効化できないので、実行しようとしたときに無効化する。\r
+               this->menubar->Enable(XRCID("Exe_Copy"), false);\r
+               return;\r
+       }\r
+\r
+       if (! wxTheClipboard->Open())\r
+       {\r
+               return;\r
+       }\r
+\r
+       e.SetInt(4);\r
+       this->OnArcExtract(e);\r
+       wxTheClipboard->Close();\r
+}\r
+\r
+void MainFrame::OnViewMode(wxCommandEvent & e)\r
+{\r
+       int n = e.GetId();\r
+       this->menubar->Check(n, true);\r
+       this->list_ctrl->SetSingleStyle(wxLC_REPORT, n == XRCID("Exe_View_Details"));\r
+       this->list_ctrl->SetSingleStyle(wxLC_ICON,   n == XRCID("Exe_View_Icons"));\r
+       this->list_ctrl->SetSingleStyle(wxLC_LIST,   n == XRCID("Exe_View_List"));\r
+}\r
+\r
+void MainFrame::OnShowToolBar(wxCommandEvent & e)\r
+{\r
+       this->toolbar->Show(e.IsChecked());\r
+}\r
+\r
+void MainFrame::OnShowStatusBar(wxCommandEvent & e)\r
+{\r
+       this->statusbar->Show(e.IsChecked());\r
+}\r
+\r
+void MainFrame::OnSelectAll(wxCommandEvent &)\r
+{\r
+       for (int i = 0; i < this->list_ctrl->GetItemCount(); i++)\r
+       {\r
+               this->list_ctrl->Select(i, true);\r
+       }\r
+}\r
+\r
+// TreeView\r
+\r
+void MainFrame::OnTreeChanged(wxTreeEvent& e)\r
+{\r
+       // ツリービューからパスを取得。\r
+       wxString szNodePath = TreeView_GetItemPath(this->tree_ctrl, e.GetItem());\r
+       // リストビューを初期化。\r
+       this->list_ctrl->apShowFile.Clear();\r
+       this->list_ctrl->DeleteAllItems();\r
+       g_hIconLL.RemoveAll();\r
+       g_hIconLS.RemoveAll();\r
+\r
+       // 現在のアイテムの選択状態を無効にしておく。\r
+       long nSelected = this->list_ctrl->GetFirstSelected();\r
+       while (nSelected != -1)\r
+       {\r
+               this->list_ctrl->Select(nSelected, false);\r
+               nSelected = this->list_ctrl->GetNextSelected(nSelected);\r
+       }\r
+\r
+       // アイコン設定。\r
+       this->list_ctrl->SetImageList(& g_hIconLL, wxIMAGE_LIST_NORMAL);\r
+       this->list_ctrl->SetImageList(& g_hIconLS, wxIMAGE_LIST_SMALL);\r
+\r
+       // 配列と比較し、パスが一致しなければ消す。\r
+       for (size_t i = 0; i < this->fileinfo.GetCount(); i++)\r
+       {\r
+               // パスを比較。\r
+               if (szNodePath == wxT("*") || szNodePath == this->fileinfo[i].fnFileName.GetPath())\r
+               {\r
+                       // 項目がフォルダであるなら無視。\r
+                       if (this->fileinfo[i].fnFileName.IsDir() || ! TreeView_CheckNewerItem(this->tree_ctrl, this->tree_ctrl->GetLastChild(this->tree_ctrl->GetRootItem()), this->fileinfo[i].fnFileName.GetFullPath(), false))\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       // フィルタにかからなければ無視。\r
+                       if (this->fileinfo[i].fnFileName.GetFullName().MakeLower().Find(this->tcFilter->GetValue().MakeLower()) == wxNOT_FOUND)\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       this->list_ctrl->apShowFile.Add(& this->fileinfo[i]);\r
+               }\r
+       }\r
+\r
+       // ソートして表示。\r
+       this->list_ctrl->apShowFile.Sort(& ListCtrlCompareProc);\r
+       this->list_ctrl->SetItemCount(this->list_ctrl->apShowFile.GetCount());\r
+}\r
+\r
+void MainFrame::OnTreeBeginDrag(wxTreeEvent& e)\r
+{\r
+       // TODO : アイテムが子階層を持っていても展開できない。\r
+       this->tree_ctrl->SelectItem(e.GetItem());\r
+\r
+       wxCommandEvent e1;\r
+       e1.SetInt(3);\r
+       this->OnArcExtract(e1);\r
+}\r
+\r
+void MainFrame::OnContextMenu(wxContextMenuEvent& e)\r
+{\r
+       wxPoint p = e.GetPosition();\r
+       this->list_ctrl->PopupMenu(this->menubar->GetMenu(1), p == wxDefaultPosition ? this->list_ctrl->GetPosition() : this->list_ctrl->ScreenToClient(p));\r
+}\r
+\r
+// ListView\r
+\r
+void MainFrame::OnListItemSelect(wxListEvent&)\r
+{\r
+       // ファイルに対する動作の設定。但し、選択解除時はwxのバグで呼び出されない。\r
+       bool fEnable = this->list_ctrl->GetSelectedItemCount() > 0;\r
+       SetMenuToolState("Arc_Delete", fEnable && (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_DELETE) == TPI_COMMAND_DELETE && this->aiArchive.fiInfo.fArchive);\r
+       this->menubar->Enable(XRCID("Exe_Copy"), fEnable);\r
+}\r
+\r
+void MainFrame::OnListItemDClick(wxListEvent&)\r
+{\r
+       wxCommandEvent e;\r
+       e.SetInt(1);\r
+       this->OnArcExtract(e);\r
+}\r
+\r
+void MainFrame::OnListBeginDrag(wxListEvent&)\r
+{\r
+       if (this->list_ctrl->GetSelectedItemCount() == 0)\r
+       {\r
+               // アイテムを選択せずドラッグしようとした場合。\r
+               return;\r
+       }\r
+\r
+       wxCommandEvent e;\r
+       e.SetInt(2);\r
+       this->OnArcExtract(e);\r
+}\r
+\r
+// Filter\r
+\r
+void MainFrame::OnFilter(wxCommandEvent&)\r
+{\r
+       wxTreeEvent e;\r
+       e.SetItem(this->tree_ctrl->GetSelection());\r
+       this->OnTreeChanged(e);\r
+}\r
+\r
+// イベントハンドラ以外。\r
+\r
+bool MainFrame::LoadTPI(const wxString & szFileName, wxULongLong_t * llFileCount)\r
+{\r
+       // 書庫を開いていれば閉じておく。\r
+       wxCommandEvent e;\r
+       this->OnArcClose(e);\r
+\r
+       // TPIを読み込み。\r
+       wxDir fs(L_DIR_B_LIB);\r
+       wxString szTPIName;\r
+       if (fs.GetFirst(& szTPIName, wxT("*" TPI_EXT)))\r
+       {\r
+               do\r
+               {\r
+                       // 初期化。\r
+                       if (! tpi.InitLibrary(L_DIR_B_LIB + szTPIName, szFileName))\r
+                       {\r
+                               tpi.FreeLibrary();\r
+                               continue;\r
+                       }\r
+\r
+                       // コールバック関数を設定。\r
+                       tpi.SetCallbackProc(TPICallbackProc);\r
+\r
+                       // 対応確認。\r
+                       if (! tpi.OpenArchive(szFileName, llFileCount))\r
+                       {\r
+                               tpi.FreeLibrary();\r
+                               * llFileCount = 0;\r
+                               continue;\r
+                       }\r
+                       return true;\r
+               }\r
+               while (fs.GetNext(& szTPIName));\r
+       }\r
+       return false;\r
+}\r
+\r
+int MainFrame::ErrorCheck(int nErrorCode, const wxString & szAPIName)\r
+{\r
+       switch (nErrorCode)\r
+       {\r
+       case TPI_ERROR_SUCCESS:\r
+       case TPI_ERROR_S_ENDOFDATA:\r
+       case TPI_CALLBACK_CONTINUE:\r
+               break;\r
+       case TPI_ERROR_D_UNSUPPORTED:\r
+               wxLogError(_("Sorry, this function is not supported yet."));\r
+               break;\r
+       case TPI_ERROR_D_SKIPPED:\r
+       case TPI_CALLBACK_CANCEL:\r
+               wxLogError(_("This operation is canceled by the user."));\r
+               break;\r
+       default:\r
+               wxLogError(_("Error: %s()!\nError code: %d"), szAPIName.c_str(), nErrorCode);\r
+       }\r
+       return nErrorCode;\r
+}\r