OSDN Git Service

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