OSDN Git Service

18d8436418b2a5a55ab8112849e863c82d5f57c9
[tpi/lychee.git] / src / frontend / frm_main.cpp
1 /*******************************************************************************
2   TPI - flexible but useless plug-in framework.
3   Copyright (C) 2002-2009 Silky
4
5   This library is free software; you can redistribute it and/or modify it under
6   the terms of the GNU Lesser General Public License as published by the Free
7   Software Foundation; either version 2.1 of the License, or (at your option)
8   any later version.
9
10   This library is distributed in the hope that it will be useful, but WITHOUT
11   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
12   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
13   for more details.
14
15   You should have received a copy of the GNU Lesser General Public License along
16   with this library; if not, write to the Free Software Foundation, Inc.,
17   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18
19   $Id: frm_main.cpp,v 1.42 2009/09/05 03:24:58 sirakaba Exp $
20 *******************************************************************************/
21
22 #include "frontend.h"
23
24 #include "frm_main.h"
25 #include "cls_filedroptarget.h"
26 #include "dlg_make.h"
27 #include "dlg_process.h"
28 #include "functions.h"
29
30 #include <wx/fileconf.h>
31 #include <wx/arrimpl.cpp>
32
33 WX_DEFINE_OBJARRAY(ArrayTPI_FILEINFO);
34
35 #define SetMenuToolState(id, state) this->toolbar->EnableTool(XRCID(id), state); this->menubar->Enable(XRCID(id), state)
36
37 //******************************************************************************
38 //    \83O\83\8d\81[\83o\83\8b\95Ï\90\94
39 //******************************************************************************
40
41 wxImageList g_hIconT(16, 16), g_hIconLL(32, 32), g_hIconLS(16, 16);
42 int g_nSortColumn;
43 bool g_fSortAscend;
44
45 //******************************************************************************
46 // MainFrame
47 //******************************************************************************
48
49 MainFrame::MainFrame(): wxFrame()
50 {
51 }
52
53 MainFrame::~MainFrame()
54 {
55         wxCommandEvent e;
56         this->OnArcClose(e);
57
58         // \90Ý\92è\82ð\8bL\98^\81B
59         wxFileConfig fc(wxEmptyString, wxEmptyString, ::wxGetCwd() + wxT("/frontend.conf"), wxEmptyString, wxCONFIG_USE_LOCAL_FILE);
60         if (! this->IsIconized() && ! this->IsMaximized())
61         {
62                 int a, b;
63                 this->GetSize(& a, & b);
64                 fc.Write(wxT("Window-Width"), a);
65                 fc.Write(wxT("Window-Height"), b);
66                 this->GetPosition(& a, & b);
67                 fc.Write(wxT("Window-X"), a);
68                 fc.Write(wxT("Window-Y"), b);
69         }
70         fc.Write(wxT("Splitter-Pos"), this->window_splitter->GetSashPosition());
71         fc.Write(wxT("LastOpenPath"), this->fnLastOpenPath.GetFullPath());
72
73         // \83c\81[\83\8b\83o\81[/\83X\83e\81[\83^\83X\83o\81[\8aÖ\98A\81B
74         fc.Write(wxT("StatusBar-Show"), this->statusbar->IsShown());
75         fc.Write(wxT("ToolBar-Show"),   this->toolbar->IsShown());
76
77         // ListView\8aÖ\98A\81B
78         fc.Write(wxT("ListView-IconMode"), this->menubar->IsChecked(XRCID("Exe_View_Icons")) ? 1 : this->menubar->IsChecked(XRCID("Exe_View_List")) ? 2 : 0);
79         if (this->menubar->IsChecked(XRCID("Exe_View_Details")))
80         {
81                 fc.Write(wxT("ListView-C-Filename"), this->list_ctrl->GetColumnWidth(0));
82                 fc.Write(wxT("ListView-C-Unpacked"), this->list_ctrl->GetColumnWidth(1));
83                 fc.Write(wxT("ListView-C-Packed"), this->list_ctrl->GetColumnWidth(2));
84                 fc.Write(wxT("ListView-C-Ratio"), this->list_ctrl->GetColumnWidth(3));
85                 fc.Write(wxT("ListView-C-Method"), this->list_ctrl->GetColumnWidth(4));
86                 fc.Write(wxT("ListView-C-Attr"), this->list_ctrl->GetColumnWidth(5));
87                 fc.Write(wxT("ListView-C-Lastmodified"), this->list_ctrl->GetColumnWidth(6));
88                 fc.Write(wxT("ListView-C-Path"), this->list_ctrl->GetColumnWidth(7));
89                 fc.Write(wxT("ListView-C-Type"), this->list_ctrl->GetColumnWidth(8));
90                 fc.Write(wxT("ListView-C-No"), this->list_ctrl->GetColumnWidth(9));
91                 fc.Write(wxT("ListView-SortColumn"), g_nSortColumn);
92                 fc.Write(wxT("ListView-SortAscend"), g_fSortAscend);
93         }
94
95         this->Close(true);
96 }
97
98 //******************************************************************************
99 // Event Table.
100 //******************************************************************************
101
102 BEGIN_EVENT_TABLE(MainFrame, wxFrame)
103         EVT_INIT_DIALOG(      MainFrame::OnInit)
104         // Menu
105         EVT_MENU(XRCID("Arc_Create"),  MainFrame::OnArcCreate)
106         EVT_MENU(XRCID("Arc_Open"),    MainFrame::OnArcOpen)
107         EVT_MENU(XRCID("Arc_Close"),   MainFrame::OnArcClose)
108         EVT_MENU(XRCID("Arc_Add"),     MainFrame::OnArcAdd)
109         EVT_MENU(XRCID("Arc_SFX"),     MainFrame::OnArcConvert)
110         EVT_MENU(XRCID("Arc_UnSFX"),   MainFrame::OnArcConvert)
111         EVT_MENU(XRCID("Exe_Exit"),    MainFrame::OnExit)
112         EVT_MENU(XRCID("Arc_Extract"), MainFrame::OnArcExtract)
113         EVT_MENU(XRCID("Arc_Delete"),  MainFrame::OnArcDelete)
114         EVT_MENU(XRCID("Arc_Test"),    MainFrame::OnArcTest)
115         EVT_MENU(XRCID("Arc_Repair"),  MainFrame::OnArcRepair)
116         EVT_MENU(XRCID("Exe_View_Icons"),  MainFrame::OnViewMode)
117         EVT_MENU(XRCID("Exe_View_Details"),MainFrame::OnViewMode)
118         EVT_MENU(XRCID("Exe_View_List"),   MainFrame::OnViewMode)
119         EVT_MENU(XRCID("Exe_View_ToolBar"),MainFrame::OnShowToolBar)
120         EVT_MENU(XRCID("Exe_View_StatusBar"),MainFrame::OnShowStatusBar)
121         EVT_MENU(XRCID("Exe_View_SelectAll"),MainFrame::OnSelectAll)
122         // TreeView
123         EVT_TREE_SEL_CHANGED(XRCID("TreeView"), MainFrame::OnTreeChanged)
124         // ListView
125         EVT_LIST_ITEM_ACTIVATED(XRCID("ListView"), MainFrame::OnListItemDClick)
126         EVT_LIST_BEGIN_DRAG(XRCID("ListView"), MainFrame::OnListBeginDrag)
127         // Filter
128         EVT_TEXT(XRCID("tcFilter"), MainFrame::OnFilter)
129 END_EVENT_TABLE()
130
131 //******************************************************************************
132 // Event handler.
133 //******************************************************************************
134
135 void MainFrame::OnInit(wxInitDialogEvent&)
136 {
137         // XRC\82Æ\8c\8b\82Ñ\82Â\82¯\81B
138         this->menubar    = this->GetMenuBar();
139         this->toolbar    = this->GetToolBar();
140         this->statusbar = XRCCTRL(* this, "statusbar", wxStatusBar);
141         this->tree_ctrl = XRCCTRL(* this, "TreeView", wxTreeCtrl);
142         this->list_ctrl = XRCCTRL(* this, "ListView", myListCtrl);
143         this->tcFilter  = XRCCTRL(* this, "tcFilter", wxTextCtrl);
144         this->window_splitter = XRCCTRL(* this, "window_splitter", wxSplitterWindow);
145
146         // \90Ý\92è\82ð\93Ç\82Ý\8d\9e\82Ý\81B
147         wxFileConfig fc(wxEmptyString, wxEmptyString, ::wxGetCwd() + wxT("/frontend.conf"), wxEmptyString, wxCONFIG_USE_LOCAL_FILE);
148         this->SetSize(fc.Read(wxT("Window-X"), 0l), fc.Read(wxT("Window-Y"), 0l), fc.Read(wxT("Window-Width"), 800), fc.Read(wxT("Window-Height"), 400));
149         this->fnLastOpenPath = wxFileName::DirName(fc.Read(wxT("LastOpenPath"), ::wxGetCwd()));
150         wxTheMimeTypesManager->Initialize(wxMAILCAP_ALL);
151
152         // \8f\89\8aú\92l\90Ý\92è\81B
153         {
154                 wxIcon icon;
155                 icon.CopyFromBitmap(wxBitmap(FE_DIR_S_ICO wxT("app.png"), wxBITMAP_TYPE_ANY));
156                 this->SetIcon(icon);
157         }
158         wxCommandEvent e;
159         this->OnArcClose(e);
160
161         // \83X\83v\83\8a\83b\83^\81[\90Ý\92è\81B
162         this->window_splitter->SetSashPosition(fc.Read(wxT("Splitter-Pos"), 200));
163
164         // \83\8a\83X\83g\83r\83\85\81[\90Ý\92è\81B
165         int nIconMode = fc.Read(wxT("ListView-IconMode"), 0l);
166         e.SetId(nIconMode == 1 ? XRCID("Exe_View_Icons") : (nIconMode == 2 ? XRCID("Exe_View_List") : XRCID("Exe_View_Details")));
167         this->OnViewMode(e);
168         // wxGTK\82Å\82Í\92¼\90ÚwxLC_VIRTUAL\82ð\8ew\92è\82µ\82È\82¢\82Æ\94½\89f\82³\82ê\82È\82¢\81B
169         this->list_ctrl->SetSingleStyle(wxLC_VIRTUAL);
170         this->list_ctrl->InsertColumn(0, wxT("Filename"),      wxLIST_FORMAT_LEFT,   fc.Read(wxT("ListView-C-Filename"), 140));
171         this->list_ctrl->InsertColumn(1, wxT("Unpacked"),      wxLIST_FORMAT_RIGHT,  fc.Read(wxT("ListView-C-Unpacked"), 80));
172         this->list_ctrl->InsertColumn(2, wxT("Packed"),        wxLIST_FORMAT_RIGHT,  fc.Read(wxT("ListView-C-Packed"), 80));
173         this->list_ctrl->InsertColumn(3, wxT("Ratio"),         wxLIST_FORMAT_RIGHT,  fc.Read(wxT("ListView-C-Ratio"), 50));
174         this->list_ctrl->InsertColumn(4, wxT("Method"),        wxLIST_FORMAT_LEFT,   fc.Read(wxT("ListView-C-Method"), 60));
175         this->list_ctrl->InsertColumn(5, wxT("Attr"),          wxLIST_FORMAT_LEFT,   fc.Read(wxT("ListView-C-Attr"), 50));
176         this->list_ctrl->InsertColumn(6, wxT("Last modified"), wxLIST_FORMAT_RIGHT,  fc.Read(wxT("ListView-C-Lastmodified"), 150));
177         this->list_ctrl->InsertColumn(7, wxT("Path"),          wxLIST_FORMAT_LEFT,   fc.Read(wxT("ListView-C-Path"), 100));
178         this->list_ctrl->InsertColumn(8, wxT("Type"),          wxLIST_FORMAT_LEFT,   fc.Read(wxT("ListView-C-Type"), 100));
179         this->list_ctrl->InsertColumn(9, wxT("No."),           wxLIST_FORMAT_RIGHT,  fc.Read(wxT("ListView-C-No"), 35));
180         g_nSortColumn = fc.Read(wxT("ListView-SortColumn"), 9);
181         g_fSortAscend = fc.Read(wxT("ListView-SortAscend"), 1) == 1;
182         this->list_ctrl->SetDropTarget(new myFileDropTarget(this));
183
184         // \83c\81[\83\8b\83o\81[/\83X\83e\81[\83^\83X\83o\81[\90Ý\92è\81B
185         int nStatusBarParts[] = {70, 70, 180, 50, -1};
186         this->statusbar->SetFieldsCount(5, nStatusBarParts);
187         this->SetStatusBarPane(-1);
188         bool fShow = fc.Read(wxT("StatusBar-Show"), 1) == 1;
189         this->menubar->Check(XRCID("Exe_View_StatusBar"), fShow);
190         this->statusbar->Show(fShow);
191         fShow = fc.Read(wxT("ToolBar-Show"), 1) == 1;
192         this->menubar->Check(XRCID("Exe_View_ToolBar"), fShow);
193         this->toolbar->Show(fShow);
194
195         // \83R\83}\83\93\83h\83\89\83C\83\93\93Ç\82Ý\8d\9e\82Ý\81B
196         this->cmdLine.SetSwitchChars(wxT("-"));
197         this->cmdLine.AddSwitch(wxT("x"), wxEmptyString, wxT("(command) Extract filenames in archive."));
198         this->cmdLine.AddSwitch(wxT("l"), wxEmptyString, wxT("(command) List archive(default)."));
199         this->cmdLine.AddParam(wxT("archive"),   wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL);
200         this->cmdLine.AddParam(wxT("filenames"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE);
201         if (this->cmdLine.Parse() == 0)
202         {
203                 if (this->cmdLine.GetParamCount() == 0)
204                 {
205                         return;
206                 }
207
208                 // \8f\91\8cÉ\82ð\8aJ\82­\81B
209                 wxFileName fnArchive(this->cmdLine.GetParam(0));
210                 fnArchive.Normalize(wxPATH_NORM_ALL, this->szCurrentPath);
211                 e.SetString(fnArchive.GetFullPath());
212                 this->OnArcOpen(e);
213                 if (this->cmdLine.Found(wxT("x")))
214                 {
215                         // \8f\91\8cÉ\82ð\93W\8aJ\81B
216                         this->OnArcExtract(e);
217                         this->Close(true);
218                 }
219         }
220 }
221
222 // MenuBar
223
224 void MainFrame::OnExit(wxCommandEvent&)
225 {
226         this->Close(true);
227 }
228
229 void MainFrame::OnArcCreate(wxCommandEvent& e)
230 {
231         TPI_SWITCHES swInfo;
232         swInfo.pCustomSwitches = NULL;
233
234         // \8dì\90¬\83_\83C\83A\83\8d\83O\82ð\90Ý\92è\81B
235         MakeDialog mkDlg;
236         ::wxXmlResource::Get()->Load(FE_DIR_S_XRC wxT("dlg_make.xrc"));
237         ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));     
238
239         if (e.GetClientData() == NULL)
240         {
241                 // \8f\88\97\9d\91Î\8fÛ\82Ì\83t\83@\83C\83\8b\82ð\91I\91ð\81B
242                 wxFileDialog fd(this, wxT("Choose files to compress"), this->fnLastOpenPath.GetFullPath());
243                 fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
244                 if (fd.ShowModal() == wxID_CANCEL)
245                 {
246                         return;
247                 }
248                 // \82±\82±\82ÅwxFileName::FileName\82ð\97p\82¢\82Ä\82¢\82é\82Ì\82Í\81A\8cã\82Å\83f\83B\83\8c\83N\83g\83\8a\96¼\82ð\95K\97v\82Æ\82·\82é\8fê\8d\87\82ª\82 \82é\82½\82ß\81B
249                 // \82 \82Ü\82è\82æ\82¢\8ed\97l\82Å\82Í\82È\82¢\82ª\93®\82­\82Ì\82Å\82Æ\82è\82 \82¦\82¸\95ú\92u\81B
250                 this->fnLastOpenPath = wxFileName::FileName(fd.GetDirectory());
251                 swInfo.fnDestinationDirectory = wxFileName::DirName(this->fnLastOpenPath.GetFullPath());
252                 this->statusbar->SetStatusText(swInfo.fnDestinationDirectory.GetFullPath(), 4);
253
254                 fd.GetFilenames(mkDlg.files);
255         }
256         else
257         {
258                 mkDlg.files = * (wxArrayString *) e.GetClientData();
259                 swInfo.fnDestinationDirectory = wxFileName::DirName(wxFileName::FileName(mkDlg.files[0]).GetPath());
260                 // \91\8a\91Î\83p\83X\82É\95Ï\8a·\81B
261                 for (size_t n = 0; n < mkDlg.files.Count(); n++)
262                 {
263                         wxFileName fn(mkDlg.files[n]);
264                         bool fIsDir = fn.DirExists() && ! fn.FileExists();
265                         fn.MakeRelativeTo(swInfo.fnDestinationDirectory.GetPath());
266                         mkDlg.files[n] = fn.GetFullPath();
267                         if (fIsDir)
268                         {
269                                 mkDlg.files[n] += fn.GetPathSeparator();
270                         }
271                 }
272         }
273
274         mkDlg.InitDialog();
275         mkDlg.cbDir->SetValue(swInfo.fnDestinationDirectory.GetPath());
276         // \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
277         wxFileName fnFirstFile(mkDlg.files[0]);
278         mkDlg.cbFileName->SetValue(mkDlg.files.GetCount() == 1 ? (fnFirstFile.GetName().IsEmpty() ? fnFirstFile.GetDirs().Last() : fnFirstFile.GetName()) : swInfo.fnDestinationDirectory.GetDirs().Last());
279
280         // \83_\83C\83A\83\8d\83O\82ð\95\\8e¦\81B
281         if (mkDlg.ShowModal() == wxID_CANCEL)
282         {
283                 this->statusbar->SetStatusText(wxEmptyString, 4);
284                 return;
285         }
286         this->statusbar->SetStatusText(wxEmptyString, 4);
287
288         // \8ae\8eí\90Ý\92è\81B
289         swInfo.fStoreDirectoryPathes= ! mkDlg.cbIgnorePath->IsChecked();
290         swInfo.fMakeSFX                     = mkDlg.cbMakeSFX->IsChecked();
291         swInfo.fSolid               = mkDlg.cbSolid->IsChecked();
292         swInfo.fMMOptimize          = mkDlg.cbMMOptimize->IsChecked();
293         swInfo.fEncryptHeader       = mkDlg.cbEncryptHeader->IsChecked();
294         swInfo.sCompressLevel       = mkDlg.scLevel->GetValue();
295         swInfo.sRecoveryRecord      = mkDlg.scRR->GetValue();
296         swInfo.szPassword           = mkDlg.tcPassword->GetValue();
297         swInfo.szKeyFile            = mkDlg.tcKeyfile->GetValue();
298         swInfo.szComment            = mkDlg.tcComment->GetValue();
299         {
300                 wxULongLong_t ll;
301                 mkDlg.cbSplitSize->GetValue().ToULongLong(& ll);
302                 swInfo.llSplitSize      = ll;
303         }
304
305         // TPI\82ð\93Ç\82Ý\8d\9e\82Ý\81B
306         int nSelected = mkDlg.chType->GetSelection();
307         wxFileName fnArchive = wxFileName::DirName(mkDlg.cbDir->GetValue());
308         fnArchive.SetName(mkDlg.cbFileName->GetValue());
309         fnArchive.SetExt(swInfo.fMakeSFX ? EXE_EXT : mkDlg.afInfo[nSelected].szSuffix.BeforeFirst(wxT(';')));
310         if (! tpi.InitLibrary(mkDlg.afInfo[nSelected].szTPIName, fnArchive.GetFullPath(), mkDlg.afInfo[nSelected].llTypeId))
311         {
312                 ::ErrDlg(wxT("InitLibrary()!"), this);
313                 return;
314         }
315
316         // \83R\81[\83\8b\83o\83b\83N\8aÖ\90\94\82ð\90Ý\92è\81B
317         if (tpi.SetCallbackProc(TPICallbackProc) != TPI_ERROR_SUCCESS)
318         {
319                 ::ErrDlg(wxT("SetCallbackProc()!"), this);
320         }
321
322         // \8f\88\97\9d\82ð\8ds\82¤\81B
323         ProcessDialog procDlg;
324         ::wxXmlResource::Get()->Load(FE_DIR_S_XRC wxT("dlg_process.xrc"));
325         ::wxXmlResource::Get()->LoadDialog(& procDlg, this, wxT("dlg_process"));
326         procDlg.InitDialog();
327         procDlg.Show(true);
328         int nErrorCode = this->ErrorCheck(tpi.Command(TPI_COMMAND_ADD, & swInfo, fnArchive.GetFullPath(), mkDlg.files));
329         procDlg.Show(false);
330         tpi.FreeLibrary();
331         if (nErrorCode != TPI_ERROR_SUCCESS)
332         {
333                 return;
334         }
335
336         if (mkDlg.cbOpenAfter->IsChecked())
337         {
338                 // \8dì\90¬\90æ\82ð\8aJ\82­\81B
339 #ifdef __WINDOWS__
340                 ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());
341 #endif
342         }
343
344         if (mkDlg.cbExitAfter->IsChecked())
345         {
346                 // \8fI\97¹\81B
347                 this->Close(true);
348         }
349
350         // \8fI\97¹\82µ\82È\82¢\8fê\8d\87\82Í\8f\91\8cÉ\82ð\8aJ\82­\81B
351         e.SetString(fnArchive.GetFullPath());
352         this->OnArcOpen(e);
353 }
354
355 void MainFrame::OnArcOpen(wxCommandEvent& e)
356 {
357         // \8f\91\8cÉ\82ð\91I\91ð\81B
358         wxString szFileName = e.GetString();
359         if (szFileName.IsEmpty())
360         {
361                 wxFileDialog fd(this);
362                 fd.SetDirectory(this->fnLastOpenPath.GetFullPath());
363                 fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST);
364                 if (fd.ShowModal() == wxID_CANCEL)
365                 {
366                         return;
367                 }
368                 this->fnLastOpenPath = wxFileName::DirName(fd.GetDirectory());
369                 szFileName = fd.GetPath();
370         }
371         this->OnArcClose(e);
372
373         // \90i\92»\83_\83C\83A\83\8d\83O\95\\8e¦\81B
374         ProcessDialog procDlg;
375         ::wxXmlResource::Get()->Load(FE_DIR_S_XRC wxT("dlg_process.xrc"));
376         ::wxXmlResource::Get()->LoadDialog(& procDlg, this, wxT("dlg_process"));        
377         procDlg.InitDialog();
378         procDlg.Show(true);
379
380         // TPI\82ð\93Ç\82Ý\8d\9e\82Ý\81A\8dÅ\8f\89\82Ì\83R\81[\83\8b\83o\83b\83N\82ð\91\97\90M\81B
381         TPI_PROCESSINFO piInfo;
382         piInfo.uMessage = TPI_MESSAGE_STATUS;
383         piInfo.uStatus = 0x1000;
384         piInfo.llProcessedSize = 0;
385         piInfo.fiInfo.fnFileName = wxFileName::FileName(szFileName);
386         piInfo.fiInfo.llUnpackedSize = this->LoadTPI(szFileName);
387         if ((signed) piInfo.fiInfo.llUnpackedSize.ToULong() == -1)
388         {
389                 procDlg.Show(false);
390                 tpi.FreeLibrary();
391                 ::ErrDlg(wxT("No plug-in supporting this archive was found!"), this);
392                 return;
393         }
394         TPICallbackProc(TPI_NOTIFY_COMMON, & piInfo);
395
396         // \94z\97ñ\82Ì\83T\83C\83Y\82ð\8am\95Û\81B
397         this->fileinfo.Alloc(piInfo.fiInfo.llUnpackedSize.ToULong());
398
399         // \8f\91\8cÉ\82ð\8aJ\82­\81B
400         if (tpi.OpenArchive(szFileName) != TPI_ERROR_SUCCESS)
401         {
402                 procDlg.Show(false);
403                 tpi.FreeLibrary();
404                 ::ErrDlg(wxT("OpenArchive()!"), this);
405                 return;
406         }
407
408         // \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
409         g_hIconT.Add(wxBitmap(FE_DIR_S_ICO wxT("folder_closed.png"), wxBITMAP_TYPE_ANY));
410         g_hIconT.Add(wxBitmap(FE_DIR_S_ICO wxT("folder_open.png"), wxBITMAP_TYPE_ANY));
411         this->tree_ctrl->SetImageList(& g_hIconT);
412         wxTreeItemId
413                 idRoot = this->tree_ctrl->AddRoot(wxEmptyString),
414 #ifdef __WINDOWS__
415                 idArchive = this->tree_ctrl->AppendItem(idRoot, piInfo.fiInfo.fnFileName.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName))),
416 #else
417                 idArchive = this->tree_ctrl->AppendItem(idRoot, piInfo.fiInfo.fnFileName.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName).ConvertToImage().Rescale(16, 16))),
418 #endif
419                 idArcRoot = this->tree_ctrl->AppendItem(idRoot, wxT("-----"), 0, 1);
420
421         // \83t\83@\83C\83\8b\8fî\95ñ\82ð\83\8d\81[\83h\81B
422         if (tpi.GetFileInformation(& piInfo.fiInfo, true) == TPI_ERROR_SUCCESS)
423         {
424                 piInfo.uStatus = 0x1001;
425                 do
426                 {
427                         piInfo.llProcessedSize++;
428                         if (this->ErrorCheck(TPICallbackProc(TPI_NOTIFY_COMMON, & piInfo)) == TPI_CALLBACK_CANCEL)
429                         {
430                                 procDlg.Show(false);
431                                 tpi.CloseArchive();
432                                 wxCommandEvent e;
433                                 this->OnArcClose(e);
434                                 return;
435                         }
436
437                         // \83c\83\8a\81[\83r\83\85\81[\82É\94½\89f\81B
438                         TreeView_CheckNewerItem(this->tree_ctrl, idArcRoot, piInfo.fiInfo.fnFileName.GetPath(wxPATH_GET_VOLUME), true);
439
440                         // \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
441                         if (piInfo.fiInfo.dwAttribute & TPI_ATTRIBUTE_DIRECTORY)
442                         {
443                                 continue;
444                         }
445
446                         // \83Z\83L\83\85\83\8a\83e\83B\83`\83F\83b\83N\81B
447                         // DTV\8c\9f\8d¸\81B
448                         if (piInfo.fiInfo.fnFileName.GetPathWithSep().Find(wxT("..")) != wxNOT_FOUND)
449                         {
450                                 piInfo.fiInfo.uDanger = TRUE;
451                                 ::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);
452                         }
453                         // \8bó\94\92\82Ì\98A\91±\82É\82æ\82é\8ag\92£\8eq\8bU\91\95\82ð\8c\9f\8d¸\81B
454                         if (piInfo.fiInfo.fnFileName.GetFullName().Find(wxT("        ")) != wxNOT_FOUND)
455                         {
456                                 piInfo.fiInfo.uDanger = TRUE;
457                                 ::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);
458                         }
459                         // Unicode\90§\8cä\95\8e\9a\82ð\8c\9f\8d¸\81B
460                         for (wxChar c = 0x200c; c <= 0x206f; c++)
461                         {
462                                 if (piInfo.fiInfo.fnFileName.GetFullName().Find(c) != wxNOT_FOUND)
463                                 {
464                                         piInfo.fiInfo.uDanger = TRUE;
465                                         ::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);
466                                 }
467                                 switch (c)
468                                 {
469                                 case 0x200f: c = 0x2027; break;
470                                 case 0x202e: c = 0x2060; break;
471                                 }
472                         }
473
474                         // \8fî\95ñ\82ð\95Û\91\82µ\82Ä\83J\83E\83\93\83g\83A\83b\83v\81B
475                         this->fileinfo.Add(piInfo.fiInfo);
476                 }
477                 while (tpi.GetFileInformation(& piInfo.fiInfo, false) == TPI_ERROR_SUCCESS);
478         }
479
480         // \8f\91\8cÉ\82Ì\8fî\95ñ\82ð\8eæ\93¾\81B
481         TPI_ARCHIVEINFO aiInfo;
482         if (tpi.GetArchiveInformation(& aiInfo) != TPI_ERROR_SUCCESS)
483         {
484                 procDlg.Show(false);
485                 tpi.FreeLibrary();
486                 ::ErrDlg(wxT("GetArchiveInformation()!"), this);
487                 return;
488         }
489
490         // \8f\91\8cÉ\82ð\95Â\82\82é\81B
491         if (tpi.CloseArchive() != TPI_ERROR_SUCCESS)
492         {
493                 ::ErrDlg(wxT("CloseArchive()!"), this);
494         }
495
496         // \83R\81[\83\8b\83o\83b\83N\8aÖ\90\94\82ð\90Ý\92è\81B
497         if (tpi.SetCallbackProc(TPICallbackProc) != TPI_ERROR_SUCCESS)
498         {
499                 ::ErrDlg(wxT("SetCallbackProc()!"), this);
500         }
501
502         // \88È\89º\81AUI\8f\88\97\9d\81B
503         this->fileinfo.Shrink();
504         this->tree_ctrl->ExpandAll();
505         this->tree_ctrl->ScrollTo(idArchive);
506         this->tree_ctrl->SelectItem(idArchive);
507         this->list_ctrl->atDangerItem.SetTextColour(* wxRED);
508
509         // \83X\83e\81[\83^\83X\83o\81[\90Ý\92è\81B
510         this->statusbar->SetStatusText(aiInfo.fiInfo.szTypeName, 0);
511         this->statusbar->SetStatusText(wxString::Format(wxT("%d file(s)"), this->fileinfo.Count()), 1);
512         this->statusbar->SetStatusText(aiInfo.llUnpackedSize.ToString() + wxT(" B -> ") + aiInfo.llPackedSize.ToString()   + wxT(" B"), 2);
513         this->statusbar->SetStatusText(wxString::Format(wxT("%3.1f%%"), aiInfo.wCompressRatio / 10.0), 3);
514         this->statusbar->SetStatusText(szFileName, 4);
515
516         // \83c\81[\83\8b\83o\81[\81E\83\81\83j\83\85\81[\83o\81[\90Ý\92è\81B
517         SetMenuToolState("Arc_Close",   true);
518         SetMenuToolState("Arc_Add",     (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_ADD)    == TPI_COMMAND_ADD);
519         SetMenuToolState("Arc_SFX",     (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_SFX)    == TPI_COMMAND_SFX   && aiInfo.nSFXType == 0);
520         SetMenuToolState("Arc_UnSFX",   (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_UNSFX)  == TPI_COMMAND_UNSFX && aiInfo.nSFXType != 0);
521         SetMenuToolState("Arc_Extract", (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_EXTRACT)== TPI_COMMAND_EXTRACT);
522         SetMenuToolState("Arc_Delete",  (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_DELETE) == TPI_COMMAND_DELETE);
523         SetMenuToolState("Arc_Test",    (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_TEST)   == TPI_COMMAND_TEST);
524         SetMenuToolState("Arc_Repair",  (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_REPAIR) == TPI_COMMAND_REPAIR);
525
526         procDlg.Show(false);
527 }
528
529 void MainFrame::OnArcClose(wxCommandEvent&)
530 {
531         // \83c\83\8a\81[\83r\83\85\81[\81E\83\8a\83X\83g\83r\83\85\81[\90Ý\92è\81B
532         this->tree_ctrl->DeleteAllItems();
533         this->list_ctrl->DeleteAllItems();
534         this->list_ctrl->showFileInfo.Clear();
535
536         // \83c\81[\83\8b\83o\81[\81E\83\81\83j\83\85\81[\83o\81[\90Ý\92è\81B
537         SetMenuToolState("Arc_Close",   false);
538         SetMenuToolState("Arc_Add",     false);
539         SetMenuToolState("Arc_SFX",     false);
540         SetMenuToolState("Arc_UnSFX",   false);
541         SetMenuToolState("Arc_Extract", false);
542         SetMenuToolState("Arc_Delete",  false);
543         SetMenuToolState("Arc_Test",    false);
544         SetMenuToolState("Arc_Repair",  false);
545
546         for (int i = 0; i < this->statusbar->GetFieldsCount(); i++)
547         {
548                 this->statusbar->SetStatusText(wxEmptyString, i);
549         }
550         this->fileinfo.Clear();
551
552         g_hIconT.RemoveAll();
553         g_hIconLL.RemoveAll();
554         g_hIconLS.RemoveAll();
555         this->tpi.FreeLibrary();
556 }
557
558 void MainFrame::OnArcAdd(wxCommandEvent& e)
559 {
560         // \8f\88\97\9d\91Î\8fÛ\82Ì\83t\83@\83C\83\8b\82ð\91I\91ð\81B
561         wxArrayString files;
562         wxFileDialog fd(this, wxT("Choose files to add"), this->fnLastOpenPath.GetFullPath());
563         fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
564         if (fd.ShowModal() == wxID_CANCEL)
565         {
566                 return;
567         }
568         fd.GetFilenames(files);
569
570         // \8ae\8eí\90Ý\92è\81B
571         TPI_SWITCHES swInfo;
572         swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
573         swInfo.fMakeSFX = false;
574         swInfo.pCustomSwitches = NULL;
575         wxString szArcName = this->statusbar->GetStatusText(4);
576
577         ProcessDialog procDlg;
578         ::wxXmlResource::Get()->Load(FE_DIR_S_XRC wxT("dlg_process.xrc"));
579         ::wxXmlResource::Get()->LoadDialog(& procDlg, this, wxT("dlg_process"));        
580         procDlg.InitDialog();
581         procDlg.Show(true);
582         this->ErrorCheck(this->tpi.Command(TPI_COMMAND_ADD, & swInfo, szArcName, files));
583         procDlg.Show(false);
584
585         // \8f\91\8cÉ\82ð\8dÄ\93Ç\82Ý\8d\9e\82Ý\81B
586         e.SetString(szArcName);
587         this->OnArcOpen(e);
588 }
589
590 void MainFrame::OnArcConvert(wxCommandEvent& e)
591 {
592         TPI_SWITCHES swInfo;
593         swInfo.fMakeSFX = e.GetId() == XRCID("Arc_SFX");
594
595         // \95Û\91\90æ\82ð\90q\82Ë\82é\81B
596         wxFileName fnArchive(this->statusbar->GetStatusText(4));
597         wxFileDialog fd(this, swInfo.fMakeSFX ? wxT("Save as SFX") : wxT("Save as normal archive"), fnArchive.GetPath(wxPATH_GET_VOLUME), fnArchive.GetName() + (swInfo.fMakeSFX ? EXE_EXT : (wxString) wxEmptyString));
598         fd.SetWindowStyleFlag(wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
599         if (fd.ShowModal() == wxID_CANCEL)
600         {
601                 return;
602         }
603         swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
604         this->fnLastOpenPath = swInfo.fnDestinationDirectory;
605
606         wxArrayString files;
607         files.Add(fd.GetPath());
608
609         ProcessDialog procDlg;
610         ::wxXmlResource::Get()->Load(FE_DIR_S_XRC wxT("dlg_process.xrc"));
611         ::wxXmlResource::Get()->LoadDialog(& procDlg, this, wxT("dlg_process"));
612         procDlg.InitDialog();
613         procDlg.Show(true);
614         this->ErrorCheck(this->tpi.Command(swInfo.fMakeSFX ? TPI_COMMAND_SFX : TPI_COMMAND_UNSFX, & swInfo, fnArchive.GetFullPath(), files));
615         procDlg.Show(false);
616 }
617
618 void MainFrame::OnArcExtract(wxCommandEvent& e)
619 {
620         TPI_SWITCHES swInfo;
621         swInfo.pCustomSwitches = NULL;
622
623         // \83\82\81[\83h\8eæ\93¾\81B\92Ê\8fí\82Í0, \8eÀ\8ds\82È\82ç1, DnD\82È\82ç2\81B
624         int nMode = e.GetInt();
625         // \8eÀ\8ds\8e\9e\82Ì\82Ý\8eg\97p\81B
626         wxFileType * ftFile = NULL;
627
628         // \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
629         MakeDialog mkDlg;
630         mkDlg.bIsMake = false;
631         mkDlg.files   = MakeTargetFileList(this, nMode == 1);
632
633         if (nMode != 0)
634         {
635                 if (nMode == 1)
636                 {
637                         // \83R\83}\83\93\83h\82ð\8eæ\93¾\81B
638                         ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(wxFileName::FileName(mkDlg.files[0]).GetExt());
639                         if (! ftFile)
640                         {
641                                 ::ErrDlg(wxT("Unable to get the file type!"), this);
642                                 return;
643                         }
644                 }
645
646                 // \8dì\8bÆ\83f\83B\83\8c\83N\83g\83\8a\8dì\90¬\81B
647                 swInfo.fStoreDirectoryPathes = false;
648                 swInfo.fnDestinationDirectory = MakeDirPath(wxFileName::DirName(::wxGetCwd()), wxT("tpi_tmp"), true);
649                 if (! swInfo.fnDestinationDirectory.IsOk())
650                 {
651                         ::ErrDlg(wxT("Unable to make the temporary directory!"), this);
652                         return;
653                 }
654         }
655         else
656         {
657                 ::wxXmlResource::Get()->Load(FE_DIR_S_XRC wxT("dlg_make.xrc"));
658                 ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));
659                 mkDlg.InitDialog();
660                 if (mkDlg.ShowModal() == wxID_CANCEL)
661                 {
662                         return;
663                 }
664
665                 // \8ae\8eí\90Ý\92è\81B
666                 swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();
667                 swInfo.fnDestinationDirectory = wxFileName::DirName(mkDlg.cbDir->GetValue());
668                 swInfo.szPassword = mkDlg.tcPassword->GetValue();
669                 swInfo.szKeyFile  = mkDlg.tcKeyfile->GetValue();
670
671                 // \95K\97v\82È\82ç\8f\91\8cÉ\96¼\82Å\83f\83B\83\8c\83N\83g\83\8a\82ð\8dì\90¬\82·\82é\81B
672                 if (WillMakeDirByArcName(this, & mkDlg))
673                 {
674                         swInfo.fnDestinationDirectory = MakeDirPath(swInfo.fnDestinationDirectory, wxFileName::FileName(this->statusbar->GetStatusText(4)).GetName(), true);
675                         if (! swInfo.fnDestinationDirectory.IsOk())
676                         {
677                                 ::ErrDlg(wxT("Unable to make the destination directory!"), this);
678                                 return;
679                         }
680                 }
681         }
682
683         ProcessDialog procDlg;
684         ::wxXmlResource::Get()->Load(FE_DIR_S_XRC wxT("dlg_process.xrc"));
685         ::wxXmlResource::Get()->LoadDialog(& procDlg, this, wxT("dlg_process"));        
686         procDlg.InitDialog();
687         procDlg.Show(true);
688         int nErrorCode = this->ErrorCheck(this->tpi.Command(TPI_COMMAND_EXTRACT, & swInfo, this->statusbar->GetStatusText(4), mkDlg.files));
689         procDlg.Show(false);
690
691         if (nMode == 0)
692         {
693                 if (mkDlg.cbOpenAfter->IsChecked())
694                 {
695                         // \93W\8aJ\90æ\82ð\8aJ\82­\81B
696 #ifdef __WINDOWS__
697                         ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());
698 #endif
699                 }
700
701                 if (mkDlg.cbExitAfter->IsChecked())
702                 {
703                         // \8fI\97¹\81B
704                         this->Close(true);
705                 }
706         }
707         else
708         {
709                 wxArrayString asFiles;
710                 if (nMode == 1)
711                 {
712                         // \83R\83}\83\93\83h\82ð\8eÀ\8ds\81B
713                         asFiles.Add(swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName::FileName(mkDlg.files[0]).GetFullName());
714                         if (nErrorCode == TPI_ERROR_SUCCESS)
715                         {
716                                 ::wxExecute(ftFile->GetOpenCommand(asFiles[0]), wxEXEC_SYNC);
717                         }
718                 }
719                 else
720                 {
721                         // \93W\8aJ\91Î\8fÛ\82ð\8c\88\92è\81B
722                         wxFileDataObject objFile;
723                         for (size_t i = 0; i < mkDlg.files.Count(); i++)
724                         {
725                                 // \83\8a\83X\83g\82É\92Ç\89Á\81B
726                                 objFile.AddFile(swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName::FileName(mkDlg.files[i]).GetFullName());
727                         }
728
729                         // DnD\8aJ\8en\81B
730                         wxDropSource dropSource(objFile, this);
731                         if (dropSource.DoDragDrop() != wxDragMove)
732                         {
733 #ifdef __LINUX__
734                                 // 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
735                                 sleep(3);
736 #endif
737                         }
738                         asFiles = objFile.GetFilenames();
739                 }
740
741                 // \83t\83@\83C\83\8b\82Æ\88ê\8e\9e\83f\83B\83\8c\83N\83g\83\8a\82ð\8dí\8f\9c\81B
742                 for (size_t i = 0; i < asFiles.GetCount(); i++)
743                 {
744                         ::wxRemoveFile(asFiles[i]);
745                 }
746                 ::wxRmdir(swInfo.fnDestinationDirectory.GetFullPath());
747         }
748 }
749
750 void MainFrame::OnArcDelete(wxCommandEvent& e)
751 {
752         // \91S\83t\83@\83C\83\8b\8dí\8f\9c\82Í\8aë\8c¯\82Å\82Í\82È\82¢\82©\82Æ\81B
753         if (this->list_ctrl->GetSelectedItemCount() == 0)
754         {
755                 return;
756         }
757
758         if (::AskDlg(wxT("Are you sure to delete selected files?"), this) == wxNO)
759         {
760                 return;
761         }
762
763         // \8ae\8eí\90Ý\92è\81B
764         TPI_SWITCHES swInfo;
765         wxString szArcName = this->statusbar->GetStatusText(4);
766         wxArrayString files = MakeTargetFileList(this, false);
767
768         ProcessDialog procDlg;
769         ::wxXmlResource::Get()->Load(FE_DIR_S_XRC wxT("dlg_process.xrc"));
770         ::wxXmlResource::Get()->LoadDialog(& procDlg, this, wxT("dlg_process"));        
771         procDlg.InitDialog();
772         procDlg.Show(true);
773         this->ErrorCheck(this->tpi.Command(TPI_COMMAND_DELETE, & swInfo, szArcName, files));
774         procDlg.Show(false);    
775
776         // \8f\91\8cÉ\82ð\8dÄ\93Ç\82Ý\8d\9e\82Ý\82·\82é\81B
777         e.SetString(szArcName);
778         this->OnArcOpen(e);
779 }
780
781 void MainFrame::OnArcTest(wxCommandEvent&)
782 {
783         // \8ae\8eí\90Ý\92è\81B
784         wxArrayString files = MakeTargetFileList(this, false);
785         TPI_SWITCHES swInfo;
786
787         ProcessDialog procDlg;
788         ::wxXmlResource::Get()->Load(FE_DIR_S_XRC wxT("dlg_process.xrc"));
789         ::wxXmlResource::Get()->LoadDialog(& procDlg, this, wxT("dlg_process"));        
790         procDlg.InitDialog();
791         procDlg.Show(true);
792         if (this->ErrorCheck(this->tpi.Command(TPI_COMMAND_TEST, & swInfo, this->statusbar->GetStatusText(4), files)) == TPI_ERROR_SUCCESS)
793         {
794                 ::MsgDlg(wxT("This is a correct archive."), & procDlg, wxICON_INFORMATION);
795         }
796         procDlg.Show(false);
797 }
798
799 void MainFrame::OnArcRepair(wxCommandEvent&)
800 {
801         // \8ae\8eí\90Ý\92è\81B
802         wxArrayString files = MakeTargetFileList(this, false);
803         TPI_SWITCHES swInfo;
804
805         ProcessDialog procDlg;
806         ::wxXmlResource::Get()->Load(FE_DIR_S_XRC wxT("dlg_process.xrc"));
807         ::wxXmlResource::Get()->LoadDialog(& procDlg, this, wxT("dlg_process"));        
808         procDlg.InitDialog();
809         procDlg.Show(true);
810         this->ErrorCheck(this->tpi.Command(TPI_COMMAND_REPAIR, & swInfo, this->statusbar->GetStatusText(4), files));
811         procDlg.Show(false);    
812 }
813
814 void MainFrame::OnViewMode(wxCommandEvent & e)
815 {
816         int n = e.GetId();
817         this->menubar->Check(n, true);
818         this->list_ctrl->SetSingleStyle(wxLC_REPORT, n == XRCID("Exe_View_Details"));
819         this->list_ctrl->SetSingleStyle(wxLC_ICON,   n == XRCID("Exe_View_Icons"));
820         this->list_ctrl->SetSingleStyle(wxLC_LIST,   n == XRCID("Exe_View_List"));
821 }
822
823 void MainFrame::OnShowToolBar(wxCommandEvent & e)
824 {
825         this->toolbar->Show(e.IsChecked());
826 }
827
828 void MainFrame::OnShowStatusBar(wxCommandEvent & e)
829 {
830         this->statusbar->Show(e.IsChecked());
831 }
832
833 void MainFrame::OnSelectAll(wxCommandEvent &)
834 {
835         for (int i = 0; i < this->list_ctrl->GetItemCount(); i++)
836         {
837                 this->list_ctrl->SetItemState(i, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
838         }
839 }
840
841 // TreeView
842
843 void MainFrame::OnTreeChanged(wxTreeEvent& e)
844 {
845         // \83c\83\8a\81[\83r\83\85\81[\82©\82ç\83p\83X\82ð\8eæ\93¾\81B
846         wxString szNodePath = TreeView_GetItemPath(this->tree_ctrl, e.GetItem());
847         // \83\8a\83X\83g\83r\83\85\81[\82ð\8f\89\8aú\89»\81B
848         this->list_ctrl->showFileInfo.Clear();
849         g_hIconLL.RemoveAll();
850         g_hIconLS.RemoveAll();
851
852         // \83A\83C\83R\83\93\90Ý\92è\81B
853         this->list_ctrl->SetImageList(& g_hIconLL, wxIMAGE_LIST_NORMAL);
854         this->list_ctrl->SetImageList(& g_hIconLS, wxIMAGE_LIST_SMALL);
855
856         // \94z\97ñ\82Æ\94ä\8ar\82µ\81A\83p\83X\82ª\88ê\92v\82µ\82È\82¯\82ê\82Î\8fÁ\82·\81B
857         for (size_t i = 0; i < this->fileinfo.GetCount(); i++)
858         {
859                 // \83p\83X\82ð\94ä\8ar\81B
860                 if (szNodePath == wxT("*") || szNodePath == this->fileinfo[i].fnFileName.GetPath())
861                 {
862                         // \8d\80\96Ú\82ª\83t\83H\83\8b\83_\82Å\82 \82é\82È\82ç\96³\8e\8b\81B
863                         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))
864                         {
865                                 continue;
866                         }
867
868                         // \83t\83B\83\8b\83^\82É\82©\82©\82ç\82È\82¯\82ê\82Î\96³\8e\8b\81B
869                         if (this->fileinfo[i].fnFileName.GetFullName().MakeLower().Find(this->tcFilter->GetValue().MakeLower()) == wxNOT_FOUND)
870                         {
871                                 continue;
872                         }
873
874                         this->list_ctrl->showFileInfo.Add(this->fileinfo[i]);
875                 }
876         }
877         // \83\\81[\83g\82µ\82Ä\95\\8e¦\81B
878         this->list_ctrl->showFileInfo.Sort(& ListCtrlCompareProc);
879         this->list_ctrl->SetItemCount(this->list_ctrl->showFileInfo.Count());
880 }
881
882 // ListView
883
884 void MainFrame::OnListItemDClick(wxListEvent&)
885 {
886         wxCommandEvent e;
887         e.SetInt(1);
888         this->OnArcExtract(e);
889 }
890
891 void MainFrame::OnListBeginDrag(wxListEvent&)
892 {
893         if (this->list_ctrl->GetSelectedItemCount() == 0)
894         {
895                 // \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
896                 return;
897         }
898
899         wxCommandEvent e;
900         e.SetInt(2);
901         this->OnArcExtract(e);
902 }
903
904 // Filter
905
906 void MainFrame::OnFilter(wxCommandEvent&)
907 {
908         wxTreeEvent e;
909         e.SetItem(this->tree_ctrl->GetSelection());
910         this->OnTreeChanged(e);
911 }
912
913 // \83C\83x\83\93\83g\83n\83\93\83h\83\89\88È\8aO\81B
914
915 int MainFrame::LoadTPI(wxString & szFileName)
916 {
917         // TPI\82ð\93Ç\82Ý\8d\9e\82Ý\81B
918         wxFileSystem fs;
919         fs.ChangePathTo(FE_DIR_B_LIB, true);
920         wxString szTPIName = fs.FindFirst(wxT("*" TPI_EXT), wxFILE);
921         int nFileCount = -1;
922         while (! szTPIName.IsEmpty())
923         {
924                 // \91Î\89\9e\8am\94F\81B
925                 if (! tpi.InitLibrary(szTPIName, szFileName, 0) || ! tpi.CheckArchive(szFileName, & nFileCount) || nFileCount < 0)
926                 {
927                         tpi.FreeLibrary();
928                         szTPIName = fs.FindNext();
929                         continue;
930                 }
931                 break;
932         }
933         return nFileCount;
934 }
935
936 int MainFrame::ErrorCheck(int nErrorCode)
937 {
938         switch (nErrorCode)
939         {
940         // \82Ç\82¿\82ç\82à\92l\82ªTRUE\82È\82Ì\82Å\8eb\92è\93I\82É\83R\83\81\83\93\83g\83A\83E\83g\81B
941         case TPI_ERROR_SUCCESS:
942 //      case TPI_CALLBACK_CONTINUE:
943                 break;
944         case TPI_ERROR_D_UNSUPPORTED:
945                 ::ErrDlg(wxT("Sorry, this function is not supported yet."), this);
946                 break;
947         case TPI_ERROR_D_SKIPPED:
948         case TPI_CALLBACK_CANCEL:
949                 ::ErrDlg(wxT("This operation is canceled by the user."), this);
950                 break;
951         default:
952                 ::ErrDlg(wxT("Error code is ") + wxString::Format(wxT("%d."), nErrorCode), this);
953         }
954         return nErrorCode;
955 }