OSDN Git Service

2286de8825da599e67555b91607b221b4668c41b
[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
335         g_hIconT.RemoveAll();
336         g_hIconLL.RemoveAll();
337         g_hIconLS.RemoveAll();
338         this->tpi.FreeLibrary();
339 }
340
341 void MainFrame::OnArcAdd(wxCommandEvent& e)
342 {
343         // \8f\88\97\9d\91Î\8fÛ\82Ì\83t\83@\83C\83\8b\82ð\91I\91ð\81B
344         wxArrayString files;
345         wxFileDialog fdDlg(this, wxT("Choose files to add"), wxEmptyString, wxEmptyString, wxFileSelectorDefaultWildcardStr, wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
346         if (fdDlg.ShowModal() == wxID_CANCEL)
347         {
348                 return;
349         }
350         fdDlg.GetFilenames(files);
351
352         // \8ae\8eí\90Ý\92è\81B
353         TPI_SWITCHES swInfo;
354         swInfo.fnDestinationDirectory = wxFileName::DirName(fdDlg.GetDirectory());
355         swInfo.fMakeSFX = false;
356         swInfo.pCustomSwitches = NULL;
357         wxString szArcName = this->statusbar->GetStatusText(5);
358
359         ProcessDialog procDlg;
360         ::wxXmlResource::Get()->Load(FE_DIR_S_XRC wxT("dlg_process.xrc"));
361         ::wxXmlResource::Get()->LoadDialog(& procDlg, this, wxT("dlg_process"));        
362         procDlg.InitDialog();
363         procDlg.Show(true);
364         this->ErrorCheck(this->tpi.Command(TPI_COMMAND_ADD, & swInfo, szArcName, files));
365         procDlg.Show(false);
366
367         // \8f\91\8cÉ\82ð\8dÄ\93Ç\82Ý\8d\9e\82Ý\81B
368         this->OnArcClose(e);
369         this->LoadArc(szArcName);
370 }
371
372 void MainFrame::OnArcSFX(wxCommandEvent&)
373 {
374         this->ConvertArc(true);
375 }
376
377 void MainFrame::OnArcUnSFX(wxCommandEvent&)
378 {
379         this->ConvertArc(false);
380 }
381
382 void MainFrame::OnArcExtract(wxCommandEvent&)
383 {
384         // \93W\8aJ\83_\83C\83A\83\8d\83O\82ð\8dì\90¬\81B
385         MakeDialog mkDlg;
386         ::wxXmlResource::Get()->Load(FE_DIR_S_XRC wxT("dlg_make.xrc"));
387         ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));
388         mkDlg.bIsMake = false;
389         mkDlg.files   = MakeTargetFileList(this, false);
390         mkDlg.InitDialog();
391         if (mkDlg.ShowModal() == wxID_CANCEL)
392         {
393                 return;
394         }
395
396         // \8ae\8eí\90Ý\92è\81B
397         TPI_SWITCHES swInfo;
398         swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();
399         swInfo.fnDestinationDirectory = wxFileName::DirName(mkDlg.cbDir->GetValue());
400         swInfo.szPassword           = mkDlg.tcPassword->GetValue();
401         swInfo.szKeyFile            = mkDlg.tcKeyfile->GetValue();
402         swInfo.pCustomSwitches = NULL;
403
404         // \95K\97v\82È\82ç\8f\91\8cÉ\96¼\82Å\83f\83B\83\8c\83N\83g\83\8a\82ð\8dì\90¬\82·\82é\81B
405         if (WillMakeDirByArcName(this, & mkDlg))
406         {
407                 swInfo.fnDestinationDirectory = MakeDirPath(swInfo.fnDestinationDirectory, wxFileName::FileName(this->statusbar->GetStatusText(5)).GetName(), true);
408                 if (! swInfo.fnDestinationDirectory.IsOk())
409                 {
410                         ::wxMessageBox(wxT("Fault: Unable to make the destination directory!"));
411                         return;
412                 }
413         }
414
415         ProcessDialog procDlg;
416         ::wxXmlResource::Get()->Load(FE_DIR_S_XRC wxT("dlg_process.xrc"));
417         ::wxXmlResource::Get()->LoadDialog(& procDlg, this, wxT("dlg_process"));        
418         procDlg.InitDialog();
419         procDlg.Show(true);
420         this->ErrorCheck(this->tpi.Command(TPI_COMMAND_EXTRACT, & swInfo, this->statusbar->GetStatusText(5), mkDlg.files));
421         procDlg.Show(false);
422
423         if (mkDlg.cbOpenAfter->IsChecked())
424         {
425                 // \93W\8aJ\90æ\82ð\8aJ\82­\81B
426 #ifdef __WINDOWS__
427                 ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());
428 #endif
429         }
430
431         if (mkDlg.cbExitAfter->IsChecked())
432         {
433                 // \8fI\97¹\81B
434                 this->Close(true);
435         }
436 }
437
438 void MainFrame::OnArcDelete(wxCommandEvent& e)
439 {
440         // \91S\83t\83@\83C\83\8b\8dí\8f\9c\82Í\8aë\8c¯\82Å\82Í\82È\82¢\82©\82Æ\81B
441         if (this->list_ctrl->GetSelectedItemCount() == 0)
442         {
443                 return;
444         }
445
446         if (::wxMessageBox(wxT("Are you sure to delete selected files?"), wxMessageBoxCaptionStr, wxYES_NO | wxICON_EXCLAMATION, this) == wxNO)
447         {
448                 return;
449         }
450
451         // \8ae\8eí\90Ý\92è\81B
452         TPI_SWITCHES swInfo;
453         wxString szArcName = this->statusbar->GetStatusText(5);
454         wxArrayString files = MakeTargetFileList(this, false);
455
456         ProcessDialog procDlg;
457         ::wxXmlResource::Get()->Load(FE_DIR_S_XRC wxT("dlg_process.xrc"));
458         ::wxXmlResource::Get()->LoadDialog(& procDlg, this, wxT("dlg_process"));        
459         procDlg.InitDialog();
460         procDlg.Show(true);
461         this->ErrorCheck(this->tpi.Command(TPI_COMMAND_DELETE, & swInfo, szArcName, files));
462         procDlg.Show(false);    
463
464         // \8f\91\8cÉ\82ð\8dÄ\93Ç\82Ý\8d\9e\82Ý\82·\82é\81B
465         this->OnArcClose(e);
466         this->LoadArc(szArcName);
467 }
468
469 void MainFrame::OnArcTest(wxCommandEvent&)
470 {
471         // \8ae\8eí\90Ý\92è\81B
472         wxArrayString files = MakeTargetFileList(this, false);
473         TPI_SWITCHES swInfo;
474
475         ProcessDialog procDlg;
476         ::wxXmlResource::Get()->Load(FE_DIR_S_XRC wxT("dlg_process.xrc"));
477         ::wxXmlResource::Get()->LoadDialog(& procDlg, this, wxT("dlg_process"));        
478         procDlg.InitDialog();
479         procDlg.Show(true);
480         if (this->ErrorCheck(this->tpi.Command(TPI_COMMAND_TEST, & swInfo, this->statusbar->GetStatusText(5), files)) == TPI_ERROR_SUCCESS)
481         {
482                 ::wxMessageBox(wxT("This is a correct archive."), wxT("Frontend"), wxOK | wxCENTRE | wxICON_INFORMATION, this);
483         }
484         procDlg.Show(false);
485 }
486
487 void MainFrame::OnArcRepair(wxCommandEvent&)
488 {
489         // \8ae\8eí\90Ý\92è\81B
490         wxArrayString files = MakeTargetFileList(this, false);
491         TPI_SWITCHES swInfo;
492
493         ProcessDialog procDlg;
494         ::wxXmlResource::Get()->Load(FE_DIR_S_XRC wxT("dlg_process.xrc"));
495         ::wxXmlResource::Get()->LoadDialog(& procDlg, this, wxT("dlg_process"));        
496         procDlg.InitDialog();
497         procDlg.Show(true);
498         this->ErrorCheck(this->tpi.Command(TPI_COMMAND_REPAIR, & swInfo, this->statusbar->GetStatusText(5), files));
499         procDlg.Show(false);    
500 }
501
502 void MainFrame::OnViewMode(wxCommandEvent & e)
503 {
504         int n = e.GetId();
505         this->menubar->Check(n, true);
506         this->list_ctrl->SetSingleStyle(wxLC_REPORT, n == XRCID("Exe_View_Details"));
507         this->list_ctrl->SetSingleStyle(wxLC_ICON,   n == XRCID("Exe_View_Icons"));
508 }
509
510 void MainFrame::OnSelectAll(wxCommandEvent &)
511 {
512         for (int i = 0; i < this->list_ctrl->GetItemCount(); i++)
513         {
514                 this->list_ctrl->SetItemState(i, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
515         }
516 }
517
518 // TreeView
519
520 void MainFrame::OnTreeChanged(wxTreeEvent& e)
521 {
522         // \83c\83\8a\81[\83r\83\85\81[\82©\82ç\83p\83X\82ð\8eæ\93¾\81B
523         wxString szNodePath = TreeView_GetItemPath(this->tree_ctrl, e.GetItem());
524         // \83\8a\83X\83g\83r\83\85\81[\82ð\8f\89\8aú\89»\81B
525         this->list_ctrl->showFileInfo.Clear();
526         g_hIconLL.RemoveAll();
527         g_hIconLS.RemoveAll();
528
529         // \83A\83C\83R\83\93\90Ý\92è\81B
530         this->list_ctrl->SetImageList(& g_hIconLL, wxIMAGE_LIST_NORMAL);
531         this->list_ctrl->SetImageList(& g_hIconLS, wxIMAGE_LIST_SMALL);
532
533         // \94z\97ñ\82Æ\94ä\8ar\82µ\81A\83p\83X\82ª\88ê\92v\82µ\82È\82¯\82ê\82Î\8fÁ\82·\81B
534         for (size_t i = 0; i < this->fileinfo.GetCount(); i++)
535         {
536                 // \83p\83X\82ð\94ä\8ar\81B
537                 if (szNodePath == wxT("*") || szNodePath == this->fileinfo[i].fnFileName.GetPath())
538                 {
539                         // \8d\80\96Ú\82ª\83t\83H\83\8b\83_\82Å\82 \82é\82È\82ç\96³\8e\8b\81B
540                         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))
541                         {
542                                 continue;
543                         }
544
545                         this->list_ctrl->showFileInfo.Add(this->fileinfo[i]);
546                 }
547         }
548         // \83\\81[\83g\82µ\82Ä\95\\8e¦\81B
549         this->list_ctrl->showFileInfo.Sort(& ListCtrlCompareProc);
550         this->list_ctrl->SetItemCount(this->list_ctrl->showFileInfo.Count());
551 }
552
553 // ListView
554
555 void MainFrame::OnListItemDClick(wxListEvent&)
556 {
557         // \93W\8aJ\91Î\8fÛ\82ð\8c\88\92è\81B
558         wxArrayString files = MakeTargetFileList(this, true);
559
560         // \83R\83}\83\93\83h\82ð\8eæ\93¾\81B
561         wxFileType * ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(wxFileName::FileName(files[0]).GetExt());
562         if (! ftFile)
563         {
564                 ::wxMessageBox(wxT("Fault: Unable to get the file type!"));
565                 return;
566         }
567
568         // \8ae\8eí\90Ý\92è\81B
569         TPI_SWITCHES swInfo;
570         swInfo.fStoreDirectoryPathes = false;
571         swInfo.pCustomSwitches = NULL;
572         swInfo.fnDestinationDirectory = MakeDirPath(wxFileName::DirName(::wxGetCwd()), wxT("tpi_tmp"), true);
573         if (! swInfo.fnDestinationDirectory.IsOk())
574         {
575                 ::wxMessageBox(wxT("Fault: Unable to make the temporary directory!"));
576                 return;
577         }
578
579         ProcessDialog procDlg;
580         ::wxXmlResource::Get()->Load(FE_DIR_S_XRC wxT("dlg_process.xrc"));
581         ::wxXmlResource::Get()->LoadDialog(& procDlg, this, wxT("dlg_process"));        
582         procDlg.InitDialog();
583         procDlg.Show(true);
584         int nErrorCode = this->ErrorCheck(this->tpi.Command(TPI_COMMAND_EXTRACT, & swInfo, this->statusbar->GetStatusText(5), files));
585         procDlg.Show(false);
586
587         // \83R\83}\83\93\83h\82ð\8eÀ\8ds\81B
588         wxString s = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName::FileName(files[0]).GetFullName();
589         if (nErrorCode == TPI_ERROR_SUCCESS)
590         {
591                 ::wxExecute(ftFile->GetOpenCommand(s), wxEXEC_SYNC);
592         }
593
594         // \88ê\8e\9e\83f\83B\83\8c\83N\83g\83\8a\82ð\8dí\8f\9c\81B
595         ::wxRemoveFile(s);
596         ::wxRmdir(swInfo.fnDestinationDirectory.GetFullPath());
597 }
598
599 void MainFrame::OnListBeginDrag(wxListEvent&)
600 {
601         if (this->list_ctrl->GetSelectedItemCount() == 0)
602         {
603                 // \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
604                 return;
605         }
606
607         // \8ae\8eí\90Ý\92è\81B
608         TPI_SWITCHES swInfo;
609         swInfo.fStoreDirectoryPathes = false;
610         swInfo.pCustomSwitches = NULL;
611         swInfo.fnDestinationDirectory = MakeDirPath(wxFileName::DirName(::wxGetCwd()), wxT("tpi_tmp"), true);
612         if (! swInfo.fnDestinationDirectory.IsOk())
613         {
614                 ::wxMessageBox(wxT("Fault: Unable to make the temporary directory!"));
615                 return;
616         }
617
618         // \93W\8aJ\91Î\8fÛ\82ð\8c\88\92è\81B
619         wxFileDataObject objFile;
620         wxArrayString files = MakeTargetFileList(this, false);
621         for (size_t i = 0; i < files.Count(); i++)
622         {
623                 // \83\8a\83X\83g\82É\92Ç\89Á\81B
624                 objFile.AddFile(swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName::FileName(files[i]).GetFullName());
625         }
626
627         this->ErrorCheck(tpi.Command(TPI_COMMAND_EXTRACT, & swInfo, this->statusbar->GetStatusText(5), files));
628
629         wxDropSource dropSource(objFile, this);
630         if (dropSource.DoDragDrop() != wxDragMove)
631         {
632 #ifdef __LINUX__
633                 // 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
634                 sleep(3);
635 #endif
636                 // \88ê\8e\9e\83f\83B\83\8c\83N\83g\83\8a\82ð\8dí\8f\9c\81B
637                 wxArrayString szFileNames = objFile.GetFilenames();
638                 for (size_t i = 0; i < szFileNames.GetCount(); i++)
639                 {
640                         ::wxRemoveFile(szFileNames[i]);
641                 }
642                 ::wxRmdir(swInfo.fnDestinationDirectory.GetFullPath());
643         }
644 }
645
646 // \83C\83x\83\93\83g\83n\83\93\83h\83\89\88È\8aO\81B
647
648 void MainFrame::LoadArc(wxString szFileName)
649 {
650         if (szFileName.IsEmpty())
651         {
652                 return;
653         }
654
655         // \90i\92»\83_\83C\83A\83\8d\83O\95\\8e¦\81B
656         ProcessDialog procDlg;
657         ::wxXmlResource::Get()->Load(FE_DIR_S_XRC wxT("dlg_process.xrc"));
658         ::wxXmlResource::Get()->LoadDialog(& procDlg, this, wxT("dlg_process"));        
659         procDlg.InitDialog();
660         procDlg.Show(true);
661
662         // TPI\82ð\93Ç\82Ý\8d\9e\82Ý\81B
663         wxFileSystem fs;
664         fs.ChangePathTo(FE_DIR_B_LIB, true);
665         wxString szTPIName = fs.FindFirst(wxT("*" TPI_EXT), wxFILE);
666         int nFileCount = -1;
667         while (! szTPIName.IsEmpty())
668         {
669                 // \91Î\89\9e\8am\94F\81B
670                 if (! tpi.InitLibrary(szTPIName, szFileName, 0) || ! tpi.CheckArchive(szFileName, & nFileCount) || nFileCount < 0)
671                 {
672                         tpi.FreeLibrary();
673                         szTPIName = fs.FindNext();
674                         continue;
675                 }
676                 break;
677         }
678         if (nFileCount == -1)
679         {
680                 procDlg.Show(false);
681                 tpi.FreeLibrary();
682                 ::wxMessageBox(wxT("Fault : No plug-in supporting this archive was found!"));
683                 return;
684         }
685
686         // \8dÅ\8f\89\82Ì\83R\81[\83\8b\83o\83b\83N\82ð\91\97\90M\81B
687         TPI_PROCESSINFO piInfo;
688         piInfo.uMessage = TPI_MESSAGE_STATUS;
689         piInfo.uStatus = 0x1000;
690         piInfo.llProcessedSize = 0;
691         piInfo.fiInfo.fnFileName = wxFileName::FileName(szFileName);
692         piInfo.fiInfo.llUnpackedSize = nFileCount;
693         TPICallbackProc(TPI_NOTIFY_COMMON, & piInfo);
694
695         // \8f\91\8cÉ\82ð\8aJ\82­\81B
696         void * hArc = NULL;
697         if (tpi.OpenArchive(szFileName, & hArc) != TPI_ERROR_SUCCESS)
698         {
699                 procDlg.Show(false);
700                 tpi.FreeLibrary();
701                 ::wxMessageBox(wxT("Fault : OpenArchive()!"));
702                 return;
703         }
704
705         // \89æ\91\9c\83\8a\83X\83g\82ð\8dì\90¬\81B
706         this->tree_ctrl->SetImageList(& g_hIconT);
707         this->tree_ctrl->AddRoot(wxEmptyString);
708
709         // \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
710         wxFileName fn(szFileName);
711         wxTreeItemId idRoot = this->tree_ctrl->GetRootItem();
712 #ifdef __WINDOWS__
713         wxTreeItemId idArchive = this->tree_ctrl->InsertItem(idRoot, idRoot, fn.GetFullName(), g_hIconT.Add(GetFileTypeIcon(fn)), -1);
714 #else
715         wxTreeItemId idArchive = this->tree_ctrl->InsertItem(idRoot, idRoot, fn.GetFullName(), g_hIconT.Add(GetFileTypeIcon(fn).ConvertToImage().Rescale(16, 16)), -1);
716 #endif
717
718         // \83\8b\81[\83g\83f\83B\83\8c\83N\83g\83\8a\82ð\8dì\90¬\81B
719         g_hIconT.Add(wxBitmap(FE_DIR_S_ICO wxT("folder_closed.png"), wxBITMAP_TYPE_ANY));
720         g_hIconT.Add(wxBitmap(FE_DIR_S_ICO wxT("folder_open.png"), wxBITMAP_TYPE_ANY));
721         wxTreeItemId idArcRoot = this->tree_ctrl->InsertItem(idRoot, idArchive, wxT("-----"), 1, 2);
722
723         // \94z\97ñ\82Ì\83T\83C\83Y\82ð\8am\95Û\81B
724         this->fileinfo.Alloc(nFileCount);
725
726         // \83t\83@\83C\83\8b\8fî\95ñ\82ð\83\8d\81[\83h\81B
727         if (tpi.GetFileInformation(hArc, & piInfo.fiInfo, true) == TPI_ERROR_SUCCESS)
728         {
729                 do
730                 {
731                         piInfo.uStatus = 0x1001;
732                         piInfo.llProcessedSize++;
733                         if (TPICallbackProc(TPI_NOTIFY_COMMON, & piInfo) == TPI_CALLBACK_CANCEL)
734                         {
735                                 procDlg.Show(false);
736                                 tpi.CloseArchive(hArc);
737                                 wxCommandEvent e;
738                                 this->OnArcClose(e);
739                                 ::wxMessageBox(wxT("Fault : Canceled by user!"));
740                                 return;
741                         }
742
743                         // \83c\83\8a\81[\83r\83\85\81[\82É\94½\89f\81B
744                         TreeView_CheckNewerItem(this->tree_ctrl, idArcRoot, piInfo.fiInfo.fnFileName.GetPath(wxPATH_GET_VOLUME), true);
745
746                         // \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
747                         if (piInfo.fiInfo.dwAttribute & TPI_ATTRIBUTE_DIRECTORY)
748                         {
749                                 continue;
750                         }
751
752                         // \83Z\83L\83\85\83\8a\83e\83B\83`\83F\83b\83N\81B
753                         // DTV\8c\9f\8d¸\81B
754                         if (piInfo.fiInfo.fnFileName.GetPathWithSep().Find(wxT("..")) != wxNOT_FOUND)
755                         {
756                                 piInfo.fiInfo.uDanger = TRUE;
757                                 ::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);
758                         }
759                         // \8bó\94\92\82Ì\98A\91±\82É\82æ\82é\8ag\92£\8eq\8bU\91\95\82ð\8c\9f\8d¸\81B
760                         if (piInfo.fiInfo.fnFileName.GetFullName().Find(wxT("        ")) != wxNOT_FOUND)
761                         {
762                                 piInfo.fiInfo.uDanger = TRUE;
763                                 ::wxMessageBox(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), wxMessageBoxCaptionStr, wxICON_EXCLAMATION);
764                         }
765                         // Unicode\90§\8cä\95\8e\9a\82ð\8c\9f\8d¸\81B
766                         for (wxChar c = 0x200c; c <= 0x206f; c++)
767                         {
768                                 if (piInfo.fiInfo.fnFileName.GetFullName().Find(c) != wxNOT_FOUND)
769                                 {
770                                         piInfo.fiInfo.uDanger = TRUE;
771                                         ::wxMessageBox(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), wxMessageBoxCaptionStr, wxICON_EXCLAMATION);
772                                 }
773                                 switch (c)
774                                 {
775                                 case 0x200f: c = 0x2027; break;
776                                 case 0x202e: c = 0x2060; break;
777                                 }
778                         }
779
780                         // \8fî\95ñ\82ð\95Û\91\82µ\82Ä\83J\83E\83\93\83g\83A\83b\83v\81B
781                         this->fileinfo.Add(piInfo.fiInfo);
782                 }
783                 while (tpi.GetFileInformation(hArc, & piInfo.fiInfo, false) == TPI_ERROR_SUCCESS);
784         }
785
786         // \8eG\91½\8f\88\97\9d\81B
787         this->fileinfo.Shrink();
788         this->tree_ctrl->ExpandAllChildren(idArcRoot);
789         this->tree_ctrl->ScrollTo(idArchive);
790         this->tree_ctrl->SelectItem(idArchive);
791         this->list_ctrl->atDangerItem.SetTextColour(* wxRED);
792
793         // \8f\91\8cÉ\82Ì\8fî\95ñ\82ð\8eæ\93¾\81B
794         TPI_ARCHIVEINFO aiInfo;
795         if (tpi.GetArchiveInformation(hArc, & aiInfo) != TPI_ERROR_SUCCESS)
796         {
797                 procDlg.Show(false);
798                 tpi.FreeLibrary();
799                 ::wxMessageBox(wxT("Fault : GetArchiveInformation()!"));
800                 return;
801         }
802
803         wxString szStatusText;
804         this->statusbar->SetStatusText(wxEmptyString, 0);
805         this->statusbar->SetStatusText(wxString::Format(wxT("%d file(s)"), this->fileinfo.Count()), 1);
806         this->statusbar->SetStatusText(wxT("Unpacked: ") + aiInfo.llUnpackedSize.ToString() + wxT(" B"), 2);
807         this->statusbar->SetStatusText(wxT("Packed: ")   + aiInfo.llPackedSize.ToString()   + wxT(" B"), 3);
808         this->statusbar->SetStatusText(wxString::Format(wxT("Ratio: %3.1f%%"), aiInfo.wCompressRatio / 10.0), 4);
809         this->statusbar->SetStatusText(szFileName, 5);
810
811         // \8f\91\8cÉ\82ð\95Â\82\82é\81B
812         if (tpi.CloseArchive(hArc) != TPI_ERROR_SUCCESS)
813         {
814                 ::wxMessageBox(wxT("Fault : CloseArchive()!"));
815         }
816
817         // \83R\81[\83\8b\83o\83b\83N\8aÖ\90\94\82ð\90Ý\92è\81B
818         if (tpi.SetCallbackProc(TPICallbackProc) != TPI_ERROR_SUCCESS)
819         {
820                 ::wxMessageBox(wxT("Fault : SetCallbackProc()!"));
821         }
822
823         // UI\8ae\8eí\90Ý\92è\81B
824         {
825                 // \83c\81[\83\8b\83o\81[\81E\83\81\83j\83\85\81[\83o\81[\90Ý\92è\81B
826                 SetMenuToolState("Arc_Close",   true);
827                 SetMenuToolState("Arc_Add",     true);
828                 SetMenuToolState("Arc_SFX",     aiInfo.nSFXType == 0);
829                 SetMenuToolState("Arc_UnSFX",   aiInfo.nSFXType != 0);
830                 SetMenuToolState("Arc_Extract", true);
831                 SetMenuToolState("Arc_Delete",  true);
832                 SetMenuToolState("Arc_Test",    true);
833                 SetMenuToolState("Arc_Repair",  true);
834         }
835
836         procDlg.Show(false);
837 }
838
839 void MainFrame::ConvertArc(bool fToSFX)
840 {
841         // \95Û\91\90æ\82ð\90q\82Ë\82é\81B
842         wxFileName fnArchive(this->statusbar->GetStatusText(5));
843         if (fToSFX)
844         {
845                 fnArchive.SetExt(EXE_EXT);
846         }
847         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);
848         if (fdDlg.ShowModal() == wxID_CANCEL)
849         {
850                 return;
851         }
852         this->fnLastOpenPath = wxFileName::DirName(fdDlg.GetDirectory());
853
854         wxArrayString files;
855         files.Add(fdDlg.GetPath());
856
857         TPI_SWITCHES swInfo;
858         swInfo.fMakeSFX = fToSFX;
859         swInfo.fnDestinationDirectory = wxFileName::DirName(fdDlg.GetDirectory());
860
861         ProcessDialog procDlg;
862         ::wxXmlResource::Get()->Load(FE_DIR_S_XRC wxT("dlg_process.xrc"));
863         ::wxXmlResource::Get()->LoadDialog(& procDlg, this, wxT("dlg_process"));        
864         procDlg.InitDialog();
865         procDlg.Show(true);
866         this->ErrorCheck(this->tpi.Command(fToSFX ? TPI_COMMAND_SFX : TPI_COMMAND_UNSFX, & swInfo, fnArchive.GetFullPath(), files));
867         procDlg.Show(false);
868 }
869
870 int MainFrame::ErrorCheck(int nErrorCode)
871 {
872         wxString s;
873         switch (nErrorCode)
874         {
875         case TPI_ERROR_SUCCESS:
876                 return TPI_ERROR_SUCCESS;
877         case TPI_ERROR_D_UNSUPPORTED:
878                 s = wxT("Sorry, this function is not supported yet.");
879                 break;
880         case TPI_ERROR_D_SKIPPED:
881                 s = wxT("This operation is canceled by the user.");
882                 break;
883         default:
884                 s.Printf(wxT("ErrorCode:%d"), nErrorCode);
885         }
886         ::wxMessageBox(s, wxT("Frontend"), wxOK | wxCENTRE | wxICON_ERROR, this);
887         return nErrorCode;
888 }