OSDN Git Service

展開ダイアログで書庫のコメントを閲覧できる機能を追加。
[tpi/lychee.git] / src / lychee / 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$
20 *******************************************************************************/
21
22 #include "lychee.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("lychee.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))
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         if (! tpi.Command(TPI_COMMAND_ADD, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))
321         {
322                 this->ErrorCheck(tpi.nErrorCode);
323                 return;
324         }
325         procDlg.Show(false);
326         tpi.FreeLibrary();
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))
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()))
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))
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));
472         }
473
474         // \8f\91\8cÉ\82Ì\8fî\95ñ\82ð\8eæ\93¾\81B
475         TPI_ARCHIVEINFO aiInfo;
476         if (! tpi.GetArchiveInformation(& aiInfo))
477         {
478                 procDlg.Show(false);
479                 tpi.FreeLibrary();
480                 ::ErrDlg(wxT("GetArchiveInformation()!"), this);
481                 return;
482         }
483         this->szComment = aiInfo.szComment;
484
485         // \8f\91\8cÉ\82ð\95Â\82\82é\81B
486         if (! tpi.CloseArchive())
487         {
488                 ::ErrDlg(wxT("CloseArchive()!"), this);
489         }
490
491         // \88È\89º\81AUI\8f\88\97\9d\81B
492         this->fileinfo.Shrink();
493         this->tree_ctrl->ExpandAll();
494         this->tree_ctrl->ScrollTo(idArchive);
495         this->tree_ctrl->SelectItem(idArchive);
496         this->list_ctrl->atDangerItem.SetTextColour(* wxRED);
497
498         // \83X\83e\81[\83^\83X\83o\81[\90Ý\92è\81B
499         this->statusbar->SetStatusText(aiInfo.fiInfo.szTypeName, 0);
500         this->statusbar->SetStatusText(wxString::Format(wxT("%d file(s)"), this->fileinfo.GetCount()), 1);
501         this->statusbar->SetStatusText(aiInfo.llUnpackedSize.ToString() + wxT(" B -> ") + aiInfo.llPackedSize.ToString() + wxT(" B"), 2);
502         this->statusbar->SetStatusText(wxString::Format(wxT("%3.1f%%"), aiInfo.wCompressRatio / 10.0), 3);
503         this->statusbar->SetStatusText(this->fnArchive.GetFullPath(), 4);
504
505         // \83c\81[\83\8b\83o\81[\81E\83\81\83j\83\85\81[\83o\81[\90Ý\92è\81B
506         SetMenuToolState("Arc_Close",   true);
507         SetMenuToolState("Arc_Add",     (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_ADD)    == TPI_COMMAND_ADD);
508         SetMenuToolState("Arc_SFX",     (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_SFX)    == TPI_COMMAND_SFX   && aiInfo.nSFXType == 0);
509         SetMenuToolState("Arc_UnSFX",   (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_UNSFX)  == TPI_COMMAND_UNSFX && aiInfo.nSFXType != 0);
510         SetMenuToolState("Arc_Extract", (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_EXTRACT)== TPI_COMMAND_EXTRACT);
511         SetMenuToolState("Arc_Delete",  (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_DELETE) == TPI_COMMAND_DELETE);
512         SetMenuToolState("Arc_Test",    (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_TEST)   == TPI_COMMAND_TEST);
513         SetMenuToolState("Arc_Repair",  (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_REPAIR) == TPI_COMMAND_REPAIR);
514
515         procDlg.Show(false);
516 }
517
518 void MainFrame::OnArcClose(wxCommandEvent&)
519 {
520         // \83c\83\8a\81[\83r\83\85\81[\81E\83\8a\83X\83g\83r\83\85\81[\90Ý\92è\81B
521         this->tree_ctrl->DeleteAllItems();
522         this->list_ctrl->DeleteAllItems();
523         this->list_ctrl->showFileInfo.Clear();
524
525         // \83c\81[\83\8b\83o\81[\81E\83\81\83j\83\85\81[\83o\81[\90Ý\92è\81B
526         SetMenuToolState("Arc_Close",   false);
527         SetMenuToolState("Arc_Add",     false);
528         SetMenuToolState("Arc_SFX",     false);
529         SetMenuToolState("Arc_UnSFX",   false);
530         SetMenuToolState("Arc_Extract", false);
531         SetMenuToolState("Arc_Delete",  false);
532         SetMenuToolState("Arc_Test",    false);
533         SetMenuToolState("Arc_Repair",  false);
534
535         for (int i = 0; i < this->statusbar->GetFieldsCount(); i++)
536         {
537                 this->statusbar->SetStatusText(wxEmptyString, i);
538         }
539         this->fileinfo.Clear();
540         this->szComment.Clear();
541
542         g_hIconT.RemoveAll();
543         g_hIconLL.RemoveAll();
544         g_hIconLS.RemoveAll();
545         this->tpi.FreeLibrary();
546 }
547
548 void MainFrame::OnArcAdd(wxCommandEvent& e)
549 {
550         // \8f\88\97\9d\91Î\8fÛ\82Ì\83t\83@\83C\83\8b\82ð\91I\91ð\81B
551         wxArrayString files;
552         wxFileDialog fd(this, wxT("Choose files to add"), this->conf.Read(wxT("LastOpenPath"), ::wxGetCwd()));
553         fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
554         if (fd.ShowModal() == wxID_CANCEL)
555         {
556                 return;
557         }
558         fd.GetFilenames(files);
559         this->conf.Write(wxT("LastOpenPath"), fd.GetDirectory());
560
561         // \8ae\8eí\90Ý\92è\81B
562         TPI_SWITCHES swInfo;
563         swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
564         swInfo.fMakeSFX = false;
565         swInfo.pCustomSwitches = NULL;
566
567         ProcessDialog procDlg;
568         procDlg.InitDialog();
569         procDlg.Show(true);
570         if (! this->tpi.Command(TPI_COMMAND_ADD, & swInfo, this->fnArchive.GetFullPath(), files))
571         {
572                 this->ErrorCheck(tpi.nErrorCode);
573         }
574         procDlg.Show(false);
575
576         // \8f\91\8cÉ\82ð\8dÄ\93Ç\82Ý\8d\9e\82Ý\81B
577         this->OnArcOpen(e);
578 }
579
580 void MainFrame::OnArcConvert(wxCommandEvent& e)
581 {
582         TPI_SWITCHES swInfo;
583         swInfo.fMakeSFX = e.GetId() == XRCID("Arc_SFX");
584
585         // \95Û\91\90æ\82ð\90q\82Ë\82é\81B
586         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));
587         fd.SetWindowStyleFlag(wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
588         if (fd.ShowModal() == wxID_CANCEL)
589         {
590                 return;
591         }
592         swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
593         this->conf.Write(wxT("LastOpenPath"), fd.GetDirectory());
594
595         wxArrayString files;
596         files.Add(fd.GetPath());
597
598         ProcessDialog procDlg;
599         procDlg.InitDialog();
600         procDlg.Show(true);
601         if (! this->tpi.Command(swInfo.fMakeSFX ? TPI_COMMAND_SFX : TPI_COMMAND_UNSFX, & swInfo, this->fnArchive.GetFullPath(), files))
602         {
603                 this->ErrorCheck(tpi.nErrorCode);
604         }
605         procDlg.Show(false);
606 }
607
608 void MainFrame::OnArcExtract(wxCommandEvent& e)
609 {
610         TPI_SWITCHES swInfo;
611         swInfo.pCustomSwitches = NULL;
612
613         // \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
614         int nMode = e.GetInt();
615         // \8eÀ\8ds\8e\9e\82Ì\82Ý\8eg\97p\81B
616         wxFileType * ftFile = NULL;
617
618         // \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
619         MakeDialog mkDlg;
620         ::wxXmlResource::Get()->Load(FE_DIR_S_XRC wxT("dlg_make.xrc"));
621         ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));
622         mkDlg.bIsMake = false;
623         mkDlg.files   = MakeTargetFileList(this, nMode == 1);
624
625         if (nMode != 0)
626         {
627                 if (nMode == 1)
628                 {
629                         // \83R\83}\83\93\83h\82ð\8eæ\93¾\81B
630                         ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(wxFileName(mkDlg.files[0]).GetExt());
631                         if (! ftFile)
632                         {
633                                 // \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
634                                 ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(this->conf.Read(wxT("DefaultExt"), wxT("txt")));
635                                 if (! ftFile)
636                                 {
637                                         ::ErrDlg(wxT("Unable to get the file type!"), this);
638                                         return;
639                                 }
640                         }
641                 }
642
643                 // \8dì\8bÆ\83f\83B\83\8c\83N\83g\83\8a\8dì\90¬\81B
644                 swInfo.fStoreDirectoryPathes = false;
645                 wxString szDestDirBase = nMode == 3 ? this->tree_ctrl->GetItemText(this->tree_ctrl->GetSelection()) : wxT("tpi_tmp");
646                 if (szDestDirBase == wxT("-----"))
647                 {
648                         // \8f\91\8cÉ\83\8b\81[\83g\82Ì\82Æ\82«\82Í\8f\91\8cÉ\96¼\82É\82µ\82Ä\82¨\82­\81B
649                         szDestDirBase = this->fnArchive.GetName();
650                 }
651                 swInfo.fnDestinationDirectory = MakeDirPath(wxFileName::DirName(::wxGetCwd()), szDestDirBase, true);
652                 if (! swInfo.fnDestinationDirectory.IsOk())
653                 {
654                         ::ErrDlg(wxT("Unable to make the temporary directory!"), this);
655                         return;
656                 }
657         }
658         else
659         {
660                 mkDlg.InitDialog();
661                 if (mkDlg.ShowModal() == wxID_CANCEL)
662                 {
663                         return;
664                 }
665
666                 // \8ae\8eí\90Ý\92è\81B
667                 swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();
668                 swInfo.fnDestinationDirectory = wxFileName::DirName(mkDlg.cbDir->GetValue());
669                 swInfo.szPassword = mkDlg.tcPassword->GetValue();
670                 swInfo.szKeyFile  = mkDlg.tcKeyfile->GetValue();
671
672                 // \95K\97v\82È\82ç\8f\91\8cÉ\96¼\82Å\83f\83B\83\8c\83N\83g\83\8a\82ð\8dì\90¬\82·\82é\81B
673                 if (WillMakeDirByArcName(this, & mkDlg))
674                 {
675                         swInfo.fnDestinationDirectory = MakeDirPath(swInfo.fnDestinationDirectory, this->fnArchive.GetName(), true);
676                         if (! swInfo.fnDestinationDirectory.IsOk())
677                         {
678                                 ::ErrDlg(wxT("Unable to make the destination directory!"), this);
679                                 return;
680                         }
681                 }
682         }
683
684         ProcessDialog procDlg;
685         procDlg.InitDialog();
686         procDlg.Show(true);
687         if (! this->tpi.Command(TPI_COMMAND_EXTRACT, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))
688         {
689                 this->ErrorCheck(tpi.nErrorCode);
690         }
691         procDlg.Show(false);
692
693         if (nMode == 0)
694         {
695                 if (mkDlg.cbOpenAfter->IsChecked())
696                 {
697                         // \93W\8aJ\90æ\82ð\8aJ\82­\81B
698 #ifdef __WINDOWS__
699                         ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());
700 #endif
701                 }
702
703                 if (mkDlg.cbExitAfter->IsChecked())
704                 {
705                         // \8fI\97¹\81B
706                         this->Close(true);
707                 }
708         }
709         else
710         {
711                 wxArrayString asFiles;
712                 if (nMode == 1)
713                 {
714                         // \83R\83}\83\93\83h\82ð\8eÀ\8ds\81B
715                         asFiles.Add(swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[0]).GetFullName());
716                         if (tpi.nErrorCode == TPI_ERROR_SUCCESS)
717                         {
718                                 ::wxExecute(ftFile->GetOpenCommand(wxT('"') + asFiles[0] + wxT('"')), wxEXEC_SYNC);
719                         }
720                 }
721                 else
722                 {
723                         // \93W\8aJ\91Î\8fÛ\82ð\8c\88\92è\81B
724                         wxFileDataObject objFile;
725                         for (size_t i = 0; i < mkDlg.files.GetCount(); i++)
726                         {
727                                 wxString szFileName = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[i]).GetFullName();
728                                 if (nMode == 2)
729                                 {
730                                         // \83\8a\83X\83g\82É\92Ç\89Á\81B
731                                         objFile.AddFile(szFileName);
732                                 }
733                                 asFiles.Add(szFileName);
734                         }
735                         if (nMode == 3)
736                         {
737                                 objFile.AddFile(swInfo.fnDestinationDirectory.GetPath());
738                         }
739
740                         // DnD\8aJ\8en\81B
741                         wxDropSource dropSource(objFile, this);
742                         if (dropSource.DoDragDrop() != wxDragMove)
743                         {
744 #ifdef __LINUX__
745                                 // 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
746                                 sleep(3);
747 #endif
748                         }
749                 }
750
751                 // \83t\83@\83C\83\8b\82Æ\88ê\8e\9e\83f\83B\83\8c\83N\83g\83\8a\82ð\8dí\8f\9c\81B
752                 for (size_t i = 0; i < asFiles.GetCount(); i++)
753                 {
754                         ::wxRemoveFile(asFiles[i]);
755                 }
756                 ::wxRmdir(swInfo.fnDestinationDirectory.GetFullPath());
757         }
758 }
759
760 void MainFrame::OnArcDelete(wxCommandEvent& e)
761 {
762         // \91S\83t\83@\83C\83\8b\8dí\8f\9c\82Í\8aë\8c¯\82Å\82Í\82È\82¢\82©\82Æ\81B
763         if (this->list_ctrl->GetSelectedItemCount() == 0)
764         {
765                 return;
766         }
767
768         if (::AskDlg(wxT("Are you sure to delete selected files?"), this) == wxNO)
769         {
770                 return;
771         }
772
773         // \8ae\8eí\90Ý\92è\81B
774         TPI_SWITCHES swInfo;
775         ProcessDialog procDlg;
776         procDlg.InitDialog();
777         procDlg.Show(true);
778         if (! this->tpi.Command(TPI_COMMAND_DELETE, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false)))
779         {
780                 this->ErrorCheck(tpi.nErrorCode);
781         }
782         procDlg.Show(false);    
783
784         // \8f\91\8cÉ\82ð\8dÄ\93Ç\82Ý\8d\9e\82Ý\82·\82é\81B
785         this->OnArcOpen(e);
786 }
787
788 void MainFrame::OnArcTest(wxCommandEvent&)
789 {
790         TPI_SWITCHES swInfo;
791         ProcessDialog procDlg;
792         procDlg.InitDialog();
793         procDlg.Show(true);
794         if (this->tpi.Command(TPI_COMMAND_TEST, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false)))
795         {
796                 ::MsgDlg(wxT("This is a correct archive."), & procDlg, wxICON_INFORMATION);
797         }
798         else
799         {
800                 this->ErrorCheck(tpi.nErrorCode);
801         }
802         procDlg.Show(false);
803 }
804
805 void MainFrame::OnArcRepair(wxCommandEvent&)
806 {
807         TPI_SWITCHES swInfo;
808         ProcessDialog procDlg;
809         procDlg.InitDialog();
810         procDlg.Show(true);
811         if (! this->tpi.Command(TPI_COMMAND_REPAIR, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false)))
812         {
813                 this->ErrorCheck(tpi.nErrorCode);
814         }
815         procDlg.Show(false);    
816 }
817
818 void MainFrame::OnViewMode(wxCommandEvent & e)
819 {
820         int n = e.GetId();
821         this->menubar->Check(n, true);
822         this->list_ctrl->SetSingleStyle(wxLC_REPORT, n == XRCID("Exe_View_Details"));
823         this->list_ctrl->SetSingleStyle(wxLC_ICON,   n == XRCID("Exe_View_Icons"));
824         this->list_ctrl->SetSingleStyle(wxLC_LIST,   n == XRCID("Exe_View_List"));
825 }
826
827 void MainFrame::OnShowToolBar(wxCommandEvent & e)
828 {
829         this->toolbar->Show(e.IsChecked());
830 }
831
832 void MainFrame::OnShowStatusBar(wxCommandEvent & e)
833 {
834         this->statusbar->Show(e.IsChecked());
835 }
836
837 void MainFrame::OnSelectAll(wxCommandEvent &)
838 {
839         for (int i = 0; i < this->list_ctrl->GetItemCount(); i++)
840         {
841                 this->list_ctrl->Select(i, true);
842         }
843 }
844
845 // TreeView
846
847 void MainFrame::OnTreeChanged(wxTreeEvent& e)
848 {
849         // \83c\83\8a\81[\83r\83\85\81[\82©\82ç\83p\83X\82ð\8eæ\93¾\81B
850         wxString szNodePath = TreeView_GetItemPath(this->tree_ctrl, e.GetItem());
851         // \83\8a\83X\83g\83r\83\85\81[\82ð\8f\89\8aú\89»\81B
852         this->list_ctrl->showFileInfo.Clear();
853         this->list_ctrl->DeleteAllItems();
854         g_hIconLL.RemoveAll();
855         g_hIconLS.RemoveAll();
856
857         // \8c»\8dÝ\82Ì\83A\83C\83e\83\80\82Ì\91I\91ð\8fó\91Ô\82ð\96³\8cø\82É\82µ\82Ä\82¨\82­\81B
858         long nSelected = this->list_ctrl->GetFirstSelected();
859         while (nSelected != -1)
860         {
861                 this->list_ctrl->Select(nSelected, false);
862                 nSelected = this->list_ctrl->GetNextSelected(nSelected);
863         }
864
865         // \83A\83C\83R\83\93\90Ý\92è\81B
866         this->list_ctrl->SetImageList(& g_hIconLL, wxIMAGE_LIST_NORMAL);
867         this->list_ctrl->SetImageList(& g_hIconLS, wxIMAGE_LIST_SMALL);
868
869         // \94z\97ñ\82Æ\94ä\8ar\82µ\81A\83p\83X\82ª\88ê\92v\82µ\82È\82¯\82ê\82Î\8fÁ\82·\81B
870         for (size_t i = 0; i < this->fileinfo.GetCount(); i++)
871         {
872                 // \83p\83X\82ð\94ä\8ar\81B
873                 if (szNodePath == wxT("*") || szNodePath == this->fileinfo[i].fnFileName.GetPath())
874                 {
875                         // \8d\80\96Ú\82ª\83t\83H\83\8b\83_\82Å\82 \82é\82È\82ç\96³\8e\8b\81B
876                         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))
877                         {
878                                 continue;
879                         }
880
881                         // \83t\83B\83\8b\83^\82É\82©\82©\82ç\82È\82¯\82ê\82Î\96³\8e\8b\81B
882                         if (this->fileinfo[i].fnFileName.GetFullName().MakeLower().Find(this->tcFilter->GetValue().MakeLower()) == wxNOT_FOUND)
883                         {
884                                 continue;
885                         }
886
887                         this->list_ctrl->showFileInfo.Add(this->fileinfo[i]);
888                 }
889         }
890
891         // \83\\81[\83g\82µ\82Ä\95\\8e¦\81B
892         this->list_ctrl->showFileInfo.Sort(& ListCtrlCompareProc);
893         this->list_ctrl->SetItemCount(this->list_ctrl->showFileInfo.GetCount());
894 }
895
896 void MainFrame::OnTreeBeginDrag(wxTreeEvent& e)
897 {
898         // 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
899         this->tree_ctrl->SelectItem(e.GetItem());
900
901         wxCommandEvent e1;
902         e1.SetInt(3);
903         this->OnArcExtract(e1);
904 }
905
906 // ListView
907
908 void MainFrame::OnListItemDClick(wxListEvent&)
909 {
910         wxCommandEvent e;
911         e.SetInt(1);
912         this->OnArcExtract(e);
913 }
914
915 void MainFrame::OnListBeginDrag(wxListEvent&)
916 {
917         if (this->list_ctrl->GetSelectedItemCount() == 0)
918         {
919                 // \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
920                 return;
921         }
922
923         wxCommandEvent e;
924         e.SetInt(2);
925         this->OnArcExtract(e);
926 }
927
928 // Filter
929
930 void MainFrame::OnFilter(wxCommandEvent&)
931 {
932         wxTreeEvent e;
933         e.SetItem(this->tree_ctrl->GetSelection());
934         this->OnTreeChanged(e);
935 }
936
937 // \83C\83x\83\93\83g\83n\83\93\83h\83\89\88È\8aO\81B
938
939 int MainFrame::LoadTPI(wxString szFileName)
940 {
941         // TPI\82ð\93Ç\82Ý\8d\9e\82Ý\81B
942         wxFileSystem fs;
943         fs.ChangePathTo(FE_DIR_B_LIB, true);
944         wxString szTPIName = fs.FindFirst(wxT("*" TPI_EXT), wxFILE);
945         int nFileCount = -1;
946         while (! szTPIName.IsEmpty())
947         {
948                 // \91Î\89\9e\8am\94F\81B
949                 if (! tpi.InitLibrary(szTPIName, szFileName, 0) || ! tpi.CheckArchive(szFileName, & nFileCount) || nFileCount < 0)
950                 {
951                         tpi.FreeLibrary();
952                         szTPIName = fs.FindNext();
953                         continue;
954                 }
955                 break;
956         }
957         return nFileCount;
958 }
959
960 int MainFrame::ErrorCheck(int nErrorCode)
961 {
962         switch (nErrorCode)
963         {
964         case TPI_ERROR_SUCCESS:
965         case TPI_CALLBACK_CONTINUE:
966                 break;
967         case TPI_ERROR_D_UNSUPPORTED:
968                 ::ErrDlg(wxT("Sorry, this function is not supported yet."), this);
969                 break;
970         case TPI_ERROR_D_SKIPPED:
971         case TPI_CALLBACK_CANCEL:
972                 ::ErrDlg(wxT("This operation is canceled by the user."), this);
973                 break;
974         default:
975                 ::ErrDlg(wxT("Error code is ") + wxString::Format(wxT("%d."), nErrorCode), this);
976         }
977         return nErrorCode;
978 }