OSDN Git Service

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