OSDN Git Service

書庫を作成する際のコマンドコードとしてTPI_COMMAND_CREATEを追加。
[tpi/lychee.git] / src / lychee / frm_main.cpp
1 /*******************************************************************************\r
2   TPI - flexible but useless plug-in framework.\r
3   Copyright (C) 2002-2009 Silky\r
4 \r
5   This library is free software; you can redistribute it and/or modify it under\r
6   the terms of the GNU Lesser General Public License as published by the Free\r
7   Software Foundation; either version 2.1 of the License, or (at your option)\r
8   any later version.\r
9 \r
10   This library is distributed in the hope that it will be useful, but WITHOUT\r
11   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \r
12   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\r
13   for more details.\r
14 \r
15   You should have received a copy of the GNU Lesser General Public License along\r
16   with this library; if not, write to the Free Software Foundation, Inc.,\r
17   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r
18 \r
19   $Id$\r
20 *******************************************************************************/\r
21 \r
22 #include "lychee.h"\r
23 \r
24 #include "frm_main.h"\r
25 #include "cls_filedroptarget.h"\r
26 #include "dlg_make.h"\r
27 #include "dlg_process.h"\r
28 #include "functions.h"\r
29 \r
30 #include <wx/arrimpl.cpp>\r
31 \r
32 WX_DEFINE_OBJARRAY(ArrayTPI_FILEINFO);\r
33 \r
34 #define SetMenuToolState(id, state) this->toolbar->EnableTool(XRCID(id), state); this->menubar->Enable(XRCID(id), state)\r
35 \r
36 //******************************************************************************\r
37 //    グローバル変数\r
38 //******************************************************************************\r
39 \r
40 wxImageList g_hIconT(16, 16), g_hIconLL(32, 32), g_hIconLS(16, 16);\r
41 int g_nSortColumn;\r
42 bool g_fSortAscend;\r
43 \r
44 //******************************************************************************\r
45 // MainFrame\r
46 //******************************************************************************\r
47 \r
48 MainFrame::MainFrame(): wxFrame()\r
49 {\r
50 }\r
51 \r
52 MainFrame::~MainFrame()\r
53 {\r
54         wxCommandEvent e;\r
55         this->OnArcClose(e);\r
56 \r
57         // 設定を記録。\r
58         if (! this->IsIconized() && ! this->IsMaximized())\r
59         {\r
60                 int a, b;\r
61                 this->GetSize(& a, & b);\r
62                 this->conf.WriteId(CONF_WINDOW_WIDTH, (long) a);\r
63                 this->conf.WriteId(CONF_WINDOW_HEIGHT,(long) b);\r
64                 this->GetPosition(& a, & b);\r
65                 this->conf.WriteId(CONF_WINDOW_X, (long) a);\r
66                 this->conf.WriteId(CONF_WINDOW_Y, (long) b);\r
67         }\r
68         this->conf.WriteId(CONF_WINDOW_SPLITTER_POS, (long) this->window_splitter->GetSashPosition());\r
69 \r
70         // ツールバー/ステータスバー関連。\r
71         this->conf.WriteId(CONF_WINDOW_STATUSBAR, this->statusbar->IsShown());\r
72         this->conf.WriteId(CONF_WINDOW_TOOLBAR,   this->toolbar->IsShown());\r
73 \r
74         // ListView関連。\r
75         this->conf.WriteId(CONF_LISTVIEW_SHOWMODE, (long) (this->menubar->IsChecked(XRCID("Exe_View_Icons")) ? 1 : this->menubar->IsChecked(XRCID("Exe_View_List")) ? 2 : 0));\r
76         if (this->menubar->IsChecked(XRCID("Exe_View_Details")))\r
77         {\r
78                 this->conf.WriteId(CONF_LISTVIEW_C_FILENAME,(long) this->list_ctrl->GetColumnWidth(0));\r
79                 this->conf.WriteId(CONF_LISTVIEW_C_UNPACKED,(long) this->list_ctrl->GetColumnWidth(1));\r
80                 this->conf.WriteId(CONF_LISTVIEW_C_PACKED,  (long) this->list_ctrl->GetColumnWidth(2));\r
81                 this->conf.WriteId(CONF_LISTVIEW_C_RATIO,   (long) this->list_ctrl->GetColumnWidth(3));\r
82                 this->conf.WriteId(CONF_LISTVIEW_C_METHOD,  (long) this->list_ctrl->GetColumnWidth(4));\r
83                 this->conf.WriteId(CONF_LISTVIEW_C_ATTR,        (long) this->list_ctrl->GetColumnWidth(5));\r
84                 this->conf.WriteId(CONF_LISTVIEW_C_LASTMOD, (long) this->list_ctrl->GetColumnWidth(6));\r
85                 this->conf.WriteId(CONF_LISTVIEW_C_PATH,    (long) this->list_ctrl->GetColumnWidth(7));\r
86                 this->conf.WriteId(CONF_LISTVIEW_C_TYPE,    (long) this->list_ctrl->GetColumnWidth(8));\r
87                 this->conf.WriteId(CONF_LISTVIEW_C_NO,      (long) this->list_ctrl->GetColumnWidth(9));\r
88                 this->conf.WriteId(CONF_LISTVIEW_S_COLUMN,  (long) g_nSortColumn);\r
89                 this->conf.WriteId(CONF_LISTVIEW_S_ASCEND,  g_fSortAscend);\r
90         }\r
91 \r
92         this->Close(true);\r
93 }\r
94 \r
95 //******************************************************************************\r
96 // Event Table.\r
97 //******************************************************************************\r
98 \r
99 BEGIN_EVENT_TABLE(MainFrame, wxFrame)\r
100         EVT_INIT_DIALOG(      MainFrame::OnInit)\r
101         // Menu\r
102         EVT_MENU(XRCID("Arc_Create"),  MainFrame::OnArcCreate)\r
103         EVT_MENU(XRCID("Arc_Open"),    MainFrame::OnArcOpen)\r
104         EVT_MENU(XRCID("Arc_Close"),   MainFrame::OnArcClose)\r
105         EVT_MENU(XRCID("Arc_Add"),     MainFrame::OnArcAdd)\r
106         EVT_MENU(XRCID("Arc_SFX"),     MainFrame::OnArcConvert)\r
107         EVT_MENU(XRCID("Arc_UnSFX"),   MainFrame::OnArcConvert)\r
108         EVT_MENU(XRCID("Exe_Exit"),    MainFrame::OnExit)\r
109         EVT_MENU(XRCID("Arc_Extract"), MainFrame::OnArcExtract)\r
110         EVT_MENU(XRCID("Arc_Delete"),  MainFrame::OnArcDelete)\r
111         EVT_MENU(XRCID("Arc_Test"),    MainFrame::OnArcTest)\r
112         EVT_MENU(XRCID("Arc_Repair"),  MainFrame::OnArcRepair)\r
113         EVT_MENU(XRCID("Exe_View_Icons"),  MainFrame::OnViewMode)\r
114         EVT_MENU(XRCID("Exe_View_Details"),MainFrame::OnViewMode)\r
115         EVT_MENU(XRCID("Exe_View_List"),   MainFrame::OnViewMode)\r
116         EVT_MENU(XRCID("Exe_View_ToolBar"),MainFrame::OnShowToolBar)\r
117         EVT_MENU(XRCID("Exe_View_StatusBar"),MainFrame::OnShowStatusBar)\r
118         EVT_MENU(XRCID("Exe_View_SelectAll"),MainFrame::OnSelectAll)\r
119         // TreeView\r
120         EVT_TREE_SEL_CHANGED(XRCID("TreeView"), MainFrame::OnTreeChanged)\r
121         EVT_TREE_BEGIN_DRAG( XRCID("TreeView"), MainFrame::OnTreeBeginDrag)\r
122         // ListView\r
123         EVT_LIST_ITEM_ACTIVATED(XRCID("ListView"), MainFrame::OnListItemDClick)\r
124         EVT_LIST_BEGIN_DRAG(    XRCID("ListView"), MainFrame::OnListBeginDrag)\r
125         // Filter\r
126         EVT_TEXT(XRCID("tcFilter"), MainFrame::OnFilter)\r
127 END_EVENT_TABLE()\r
128 \r
129 //******************************************************************************\r
130 // Event handler.\r
131 //******************************************************************************\r
132 \r
133 void MainFrame::OnInit(wxInitDialogEvent&)\r
134 {\r
135         // XRCと結びつけ。\r
136         this->menubar    = this->GetMenuBar();\r
137         this->toolbar    = this->GetToolBar();\r
138         this->statusbar = XRCCTRL(* this, "statusbar", wxStatusBar);\r
139         this->tree_ctrl = XRCCTRL(* this, "TreeView", wxTreeCtrl);\r
140         this->list_ctrl = XRCCTRL(* this, "ListView", myListCtrl);\r
141         this->window_splitter = XRCCTRL(* this, "window_splitter", wxSplitterWindow);\r
142         this->tcFilter  = XRCCTRL(* this->toolbar, "tcFilter", wxTextCtrl);\r
143 \r
144         // 設定を読み込み。\r
145         this->SetSize(this->conf.ReadId(CONF_WINDOW_X, 0l), this->conf.ReadId(CONF_WINDOW_Y, 0l), this->conf.ReadId(CONF_WINDOW_WIDTH, 800l), this->conf.ReadId(CONF_WINDOW_HEIGHT, 400l));\r
146         wxTheMimeTypesManager->Initialize(wxMAILCAP_ALL);\r
147 \r
148         // 初期値設定。\r
149         {\r
150                 wxIcon icon;\r
151                 icon.CopyFromBitmap(wxBitmap(L_DIR_S_ICO wxT("app.png"), wxBITMAP_TYPE_ANY));\r
152                 this->SetIcon(icon);\r
153         }\r
154         wxCommandEvent e;\r
155         this->OnArcClose(e);\r
156 \r
157         // スプリッター設定。\r
158         this->window_splitter->SetSashPosition(this->conf.ReadId(CONF_WINDOW_SPLITTER_POS, 200l));\r
159 \r
160         // リストビュー設定。\r
161         int nIconMode = this->conf.ReadId(CONF_LISTVIEW_SHOWMODE, 0l);\r
162         e.SetId(nIconMode == 1 ? XRCID("Exe_View_Icons") : (nIconMode == 2 ? XRCID("Exe_View_List") : XRCID("Exe_View_Details")));\r
163         this->OnViewMode(e);\r
164         // wxGTKでは直接wxLC_VIRTUALを指定しないと反映されない。\r
165         this->list_ctrl->SetSingleStyle(wxLC_VIRTUAL);\r
166         this->list_ctrl->InsertColumn(0, _("Filename"),      wxLIST_FORMAT_LEFT,   this->conf.ReadId(CONF_LISTVIEW_C_FILENAME, 140l));\r
167         this->list_ctrl->InsertColumn(1, _("Unpacked"),      wxLIST_FORMAT_RIGHT,  this->conf.ReadId(CONF_LISTVIEW_C_UNPACKED,  80l));\r
168         this->list_ctrl->InsertColumn(2, _("Packed"),        wxLIST_FORMAT_RIGHT,  this->conf.ReadId(CONF_LISTVIEW_C_PACKED,    80l));\r
169         this->list_ctrl->InsertColumn(3, _("Ratio"),         wxLIST_FORMAT_RIGHT,  this->conf.ReadId(CONF_LISTVIEW_C_RATIO,     50l));\r
170         this->list_ctrl->InsertColumn(4, _("Method"),        wxLIST_FORMAT_LEFT,   this->conf.ReadId(CONF_LISTVIEW_C_METHOD,    60l));\r
171         this->list_ctrl->InsertColumn(5, _("Attr"),          wxLIST_FORMAT_LEFT,   this->conf.ReadId(CONF_LISTVIEW_C_ATTR,      50l));\r
172         this->list_ctrl->InsertColumn(6, _("Last modified"), wxLIST_FORMAT_RIGHT,  this->conf.ReadId(CONF_LISTVIEW_C_LASTMOD,  150l));\r
173         this->list_ctrl->InsertColumn(7, _("Path"),          wxLIST_FORMAT_LEFT,   this->conf.ReadId(CONF_LISTVIEW_C_PATH,     100l));\r
174         this->list_ctrl->InsertColumn(8, _("Type"),          wxLIST_FORMAT_LEFT,   this->conf.ReadId(CONF_LISTVIEW_C_TYPE,     100l));\r
175         this->list_ctrl->InsertColumn(9, _("No."),           wxLIST_FORMAT_RIGHT,  this->conf.ReadId(CONF_LISTVIEW_C_NO,        35l));\r
176         g_nSortColumn = this->conf.ReadId(CONF_LISTVIEW_S_COLUMN, 9l);\r
177         g_fSortAscend = this->conf.ReadId(CONF_LISTVIEW_S_ASCEND, true);\r
178         this->list_ctrl->SetDropTarget(new myFileDropTarget(this));\r
179 \r
180         // ツールバー/ステータスバー設定。\r
181         int nStatusBarParts[] = {70, 70, 180, 50, -1};\r
182         this->statusbar->SetFieldsCount(5, nStatusBarParts);\r
183         this->SetStatusBarPane(-1);\r
184         bool fShow = this->conf.ReadId(CONF_WINDOW_STATUSBAR, true);\r
185         this->menubar->Check(XRCID("Exe_View_StatusBar"), fShow);\r
186         this->statusbar->Show(fShow);\r
187         fShow = this->conf.ReadId(CONF_WINDOW_TOOLBAR, true);\r
188         this->menubar->Check(XRCID("Exe_View_ToolBar"), fShow);\r
189         this->toolbar->Show(fShow);\r
190 \r
191         // コマンドライン読み込み。\r
192         this->cmdLine.SetSwitchChars(wxT("-"));\r
193         this->cmdLine.AddSwitch(wxT("x"), wxEmptyString, _("(command) Extract filenames in archive."));\r
194         this->cmdLine.AddSwitch(wxT("l"), wxEmptyString, _("(command) List archive(default)."));\r
195         this->cmdLine.AddParam(_("archive"),   wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL);\r
196         this->cmdLine.AddParam(_("filenames"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE);\r
197         if (this->cmdLine.Parse() == 0)\r
198         {\r
199                 if (this->cmdLine.GetParamCount() == 0)\r
200                 {\r
201                         return;\r
202                 }\r
203 \r
204                 // 書庫を開く。\r
205                 this->fnArchive = wxFileName(this->cmdLine.GetParam(0));\r
206                 this->fnArchive.Normalize(wxPATH_NORM_ALL, this->szCurrentPath);\r
207                 this->OnArcOpen(e);\r
208                 if (this->cmdLine.Found(wxT("x")))\r
209                 {\r
210                         // 書庫を展開。\r
211                         this->OnArcExtract(e);\r
212                         this->Close(true);\r
213                 }\r
214         }\r
215 }\r
216 \r
217 // MenuBar\r
218 \r
219 void MainFrame::OnExit(wxCommandEvent&)\r
220 {\r
221         this->Close(true);\r
222 }\r
223 \r
224 void MainFrame::OnArcCreate(wxCommandEvent& e)\r
225 {\r
226         TPI_SWITCHES swInfo;\r
227         swInfo.pCustomSwitches = NULL;\r
228 \r
229         // 作成ダイアログを設定。\r
230         MakeDialog mkDlg;\r
231         ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));\r
232         ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));\r
233 \r
234         if (e.GetClientData() == NULL)\r
235         {\r
236                 // 処理対象のファイルを選択。\r
237                 wxFileDialog fd(this, _("Choose files to compress"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0));\r
238                 fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);\r
239                 if (fd.ShowModal() == wxID_CANCEL)\r
240                 {\r
241                         return;\r
242                 }\r
243                 swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());\r
244                 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());\r
245                 this->statusbar->SetStatusText(swInfo.fnDestinationDirectory.GetFullPath(), 4);\r
246 \r
247                 fd.GetFilenames(mkDlg.files);\r
248         }\r
249         else\r
250         {\r
251                 mkDlg.files = * (wxArrayString *) e.GetClientData();\r
252                 swInfo.fnDestinationDirectory = wxFileName::DirName(wxFileName(mkDlg.files[0]).GetPath());\r
253                 // 相対パスに変換。\r
254                 for (size_t n = 0; n < mkDlg.files.GetCount(); n++)\r
255                 {\r
256                         wxFileName fn(mkDlg.files[n]);\r
257                         fn.MakeRelativeTo(swInfo.fnDestinationDirectory.GetPath());\r
258                         mkDlg.files[n] = fn.GetFullPath();\r
259                 }\r
260         }\r
261 \r
262         this->OnArcClose(e);\r
263         // 書庫名はファイル名の拡張子より前、もしくはディレクトリ名。\r
264         this->fnArchive = wxFileName(mkDlg.files[0]);\r
265         this->fnArchive.SetName(mkDlg.files.GetCount() == 1 ? (this->fnArchive.GetName().IsEmpty() ? this->fnArchive.GetDirs().Last() : this->fnArchive.GetName()) : swInfo.fnDestinationDirectory.GetDirs().Last());\r
266         this->fnArchive.SetEmptyExt();\r
267         this->fnArchive.SetPath(swInfo.fnDestinationDirectory.GetPath());\r
268 \r
269         // ダイアログを表示。\r
270         mkDlg.InitDialog();\r
271         if (mkDlg.ShowModal() == wxID_CANCEL)\r
272         {\r
273                 this->statusbar->SetStatusText(wxEmptyString, 4);\r
274                 return;\r
275         }\r
276         this->statusbar->SetStatusText(wxEmptyString, 4);\r
277 \r
278         // 各種設定。\r
279         swInfo.fStoreDirectoryPathes= ! mkDlg.cbIgnorePath->IsChecked();\r
280         swInfo.fMakeSFX                     = mkDlg.cbMakeSFX->IsChecked();\r
281         swInfo.fSolid               = mkDlg.cbSolid->IsChecked();\r
282         swInfo.fMMOptimize          = mkDlg.cbMMOptimize->IsChecked();\r
283         swInfo.fEncryptHeader       = mkDlg.cbEncryptHeader->IsChecked();\r
284         swInfo.sCompressLevel       = mkDlg.scLevel->GetValue();\r
285         swInfo.sRecoveryRecord      = mkDlg.scRR->GetValue();\r
286         swInfo.szPassword           = mkDlg.tcPassword->GetValue();\r
287         swInfo.szKeyFile            = mkDlg.tcKeyfile->GetValue();\r
288         swInfo.szComment            = mkDlg.tcComment->GetValue();\r
289         {\r
290                 wxULongLong_t ll;\r
291                 mkDlg.cbSplitSize->GetValue().ToULongLong(& ll);\r
292                 swInfo.llSplitSize      = ll;\r
293         }\r
294 \r
295         // TPIを読み込み。\r
296         int nSelected = mkDlg.chType->GetSelection();\r
297         this->fnArchive = wxFileName(mkDlg.cbDir->GetValue(), mkDlg.cbFileName->GetValue());\r
298         if (! tpi.InitLibrary(mkDlg.afInfo[nSelected].szTPIName, this->fnArchive.GetFullPath(), mkDlg.afInfo[nSelected].llTypeId))\r
299         {\r
300                 ::wxLogError(_("Error: %s!"), wxT("InitLibrary()!"));\r
301                 return;\r
302         }\r
303 \r
304         // コールバック関数を設定。\r
305         if (! tpi.SetCallbackProc(TPICallbackProc))\r
306         {\r
307                 ::wxLogError(_("Error: %s!"), wxT("SetCallbackProc()!"));\r
308         }\r
309 \r
310         // 処理を行う。\r
311         ProcessDialog procDlg;\r
312         procDlg.InitDialog();\r
313         procDlg.Show(true);\r
314         if (! tpi.Command(TPI_COMMAND_CREATE, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))\r
315         {\r
316                 this->ErrorCheck(tpi.nErrorCode);\r
317                 return;\r
318         }\r
319         procDlg.Show(false);\r
320         tpi.FreeLibrary();\r
321 \r
322         if (mkDlg.cbOpenAfter->IsChecked())\r
323         {\r
324                 // 作成先を開く。\r
325 #ifdef __WINDOWS__\r
326                 ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());\r
327 #endif\r
328         }\r
329 \r
330         if (mkDlg.cbExitAfter->IsChecked())\r
331         {\r
332                 // 終了。\r
333                 this->Close(true);\r
334         }\r
335 \r
336         // 終了しない場合は書庫を開く。\r
337         this->OnArcOpen(e);\r
338 }\r
339 \r
340 void MainFrame::OnArcOpen(wxCommandEvent& e)\r
341 {\r
342         // 書庫を選択。\r
343         if (e.GetId() == XRCID("Arc_Open"))\r
344         {\r
345                 wxFileDialog fd(this);\r
346                 fd.SetDirectory(this->conf.ReadHistory(CONF_HISTORY_PATH, 0));\r
347                 fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST);\r
348                 if (fd.ShowModal() == wxID_CANCEL)\r
349                 {\r
350                         return;\r
351                 }\r
352                 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());\r
353                 this->fnArchive = wxFileName(fd.GetPath());\r
354         }\r
355         this->OnArcClose(e);\r
356 \r
357         // 進捗ダイアログ表示。\r
358         ProcessDialog procDlg;\r
359         procDlg.InitDialog();\r
360         procDlg.Show(true);\r
361 \r
362         // TPIを読み込み、最初のコールバックを送信。\r
363         TPI_PROCESSINFO piInfo;\r
364         piInfo.uMessage = TPI_MESSAGE_STATUS;\r
365         piInfo.uStatus = 0x1000;\r
366         piInfo.llProcessedSize = 0;\r
367         piInfo.fiInfo.fnFileName = this->fnArchive;\r
368         piInfo.fiInfo.llUnpackedSize = this->LoadTPI(this->fnArchive.GetFullPath());\r
369         if (piInfo.fiInfo.llUnpackedSize.ToULong() == 0)\r
370         {\r
371                 procDlg.Show(false);\r
372                 tpi.FreeLibrary();\r
373                 ::wxLogError(_("No plug-in supporting this archive was found!"));\r
374                 return;\r
375         }\r
376         TPICallbackProc(TPI_NOTIFY_COMMON, & piInfo);\r
377 \r
378         // コールバック関数を設定。\r
379         tpi.SetCallbackProc(TPICallbackProc);\r
380 \r
381         // 配列のサイズを確保。\r
382         this->fileinfo.Alloc(piInfo.fiInfo.llUnpackedSize.ToULong());\r
383 \r
384         // 書庫を開く。\r
385         if (! tpi.OpenArchive(this->fnArchive.GetFullPath()))\r
386         {\r
387                 procDlg.Show(false);\r
388                 tpi.FreeLibrary();\r
389                 ::wxLogError(_("Error: %s!"), wxT("OpenArchive()"));\r
390                 return;\r
391         }\r
392 \r
393         // 履歴に追加。\r
394         this->conf.WriteHistory(CONF_HISTORY_PATH, this->fnArchive.GetPath());\r
395         this->conf.WriteHistory(CONF_HISTORY_NAME, this->fnArchive.GetFullName());\r
396         this->conf.WriteHistory(CONF_HISTORY_FULL, this->fnArchive.GetFullPath());\r
397 \r
398         // 書庫のアイコンを取得し、書庫ルートを作成。\r
399         g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_closed.png"), wxBITMAP_TYPE_ANY));\r
400         g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_open.png"), wxBITMAP_TYPE_ANY));\r
401         this->tree_ctrl->SetImageList(& g_hIconT);\r
402         wxTreeItemId\r
403                 idRoot = this->tree_ctrl->AddRoot(wxEmptyString),\r
404 #ifdef __WINDOWS__\r
405                 idArchive = this->tree_ctrl->AppendItem(idRoot, piInfo.fiInfo.fnFileName.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName))),\r
406 #else\r
407                 idArchive = this->tree_ctrl->AppendItem(idRoot, piInfo.fiInfo.fnFileName.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName).ConvertToImage().Rescale(16, 16))),\r
408 #endif\r
409                 idArcRoot = this->tree_ctrl->AppendItem(idRoot, wxT("-----"), 0, 1);\r
410 \r
411         // ファイル情報をロード。\r
412         if (tpi.GetFileInformation(& piInfo.fiInfo, true))\r
413         {\r
414                 piInfo.uStatus = 0x1001;\r
415                 do\r
416                 {\r
417                         piInfo.llProcessedSize++;\r
418                         if (this->ErrorCheck(TPICallbackProc(TPI_NOTIFY_COMMON, & piInfo)) == TPI_CALLBACK_CANCEL)\r
419                         {\r
420                                 procDlg.Show(false);\r
421                                 tpi.CloseArchive();\r
422                                 wxCommandEvent e;\r
423                                 this->OnArcClose(e);\r
424                                 return;\r
425                         }\r
426 \r
427                         // ツリービューに反映。\r
428                         TreeView_CheckNewerItem(this->tree_ctrl, idArcRoot, piInfo.fiInfo.fnFileName.GetPath(), true);\r
429 \r
430                         // ディレクトリ属性を含むものについては除去。\r
431                         if (piInfo.fiInfo.dwAttribute & TPI_ATTRIBUTE_DIRECTORY)\r
432                         {\r
433                                 continue;\r
434                         }\r
435 \r
436                         // セキュリティチェック。\r
437                         // DTV検査。\r
438                         if (piInfo.fiInfo.fnFileName.GetPathWithSep().Find(wxT("..")) != wxNOT_FOUND)\r
439                         {\r
440                                 piInfo.fiInfo.uDanger = TRUE;\r
441                                 ::wxLogWarning(_("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%s"), piInfo.fiInfo.szStoredName.c_str());\r
442                         }\r
443                         // 空白の連続による拡張子偽装を検査。\r
444                         if (piInfo.fiInfo.fnFileName.GetFullName().Find(wxT("        ")) != wxNOT_FOUND)\r
445                         {\r
446                                 piInfo.fiInfo.uDanger = TRUE;\r
447                                 ::wxLogWarning(_("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:%s\n"), piInfo.fiInfo.szStoredName.c_str());\r
448                         }\r
449                         // Unicode制御文字を検査。\r
450                         for (wxChar c = 0x200c; c <= 0x206f; c++)\r
451                         {\r
452                                 if (piInfo.fiInfo.fnFileName.GetFullName().Find(c) != wxNOT_FOUND)\r
453                                 {\r
454                                         piInfo.fiInfo.uDanger = TRUE;\r
455                                         ::wxLogWarning(_("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.c_str());\r
456                                 }\r
457                                 switch (c)\r
458                                 {\r
459                                 case 0x200f: c = 0x2027; break;\r
460                                 case 0x202e: c = 0x2060; break;\r
461                                 }\r
462                         }\r
463 \r
464                         // 情報を保存してカウントアップ。\r
465                         this->fileinfo.Add(piInfo.fiInfo);\r
466                 }\r
467                 while (tpi.GetFileInformation(& piInfo.fiInfo, false));\r
468         }\r
469 \r
470         // 書庫の情報を取得。\r
471         TPI_ARCHIVEINFO aiInfo;\r
472         if (! tpi.GetArchiveInformation(& aiInfo))\r
473         {\r
474                 procDlg.Show(false);\r
475                 tpi.FreeLibrary();\r
476                 ::wxLogError(_("Error: %s!"), wxT("GetArchiveInformation()"));\r
477                 return;\r
478         }\r
479         this->szComment = aiInfo.szComment;\r
480 \r
481         // 書庫を閉じる。\r
482         if (! tpi.CloseArchive())\r
483         {\r
484                 ::wxLogError(_("Error: %s!"), wxT("CloseArchive()"));\r
485         }\r
486 \r
487         // 以下、UI処理。\r
488         this->fileinfo.Shrink();\r
489         this->tree_ctrl->ExpandAll();\r
490         this->tree_ctrl->ScrollTo(idArchive);\r
491         this->tree_ctrl->SelectItem(idArchive);\r
492         this->list_ctrl->atDangerItem.SetTextColour(* wxRED);\r
493 \r
494         // ステータスバー設定。\r
495         this->statusbar->SetStatusText(aiInfo.fiInfo.szTypeName, 0);\r
496         this->statusbar->SetStatusText(wxString::Format(_("%d file(s)"), this->fileinfo.GetCount()), 1);\r
497         this->statusbar->SetStatusText(aiInfo.llUnpackedSize.ToString() + _(" B -> ") + aiInfo.llPackedSize.ToString() + _(" B"), 2);\r
498         this->statusbar->SetStatusText(wxString::Format(wxT("%3.1f%%"), aiInfo.wCompressRatio / 10.0), 3);\r
499         this->statusbar->SetStatusText(this->fnArchive.GetFullPath(), 4);\r
500 \r
501         // ツールバー・メニューバー設定。\r
502         SetMenuToolState("Arc_Close",   true);\r
503         SetMenuToolState("Arc_Add",     (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_ADD)   == TPI_COMMAND_ADD   && aiInfo.fiInfo.fArchive);\r
504         SetMenuToolState("Arc_SFX",     (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_SFX)    == TPI_COMMAND_SFX   && aiInfo.nSFXType == 0);\r
505         SetMenuToolState("Arc_UnSFX",   (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_UNSFX)  == TPI_COMMAND_UNSFX && aiInfo.nSFXType != 0);\r
506         SetMenuToolState("Arc_Extract", (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_EXTRACT)== TPI_COMMAND_EXTRACT);\r
507         SetMenuToolState("Arc_Delete",  (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_DELETE) == TPI_COMMAND_DELETE && aiInfo.fiInfo.fArchive);\r
508         SetMenuToolState("Arc_Test",    (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_TEST)   == TPI_COMMAND_TEST);\r
509         SetMenuToolState("Arc_Repair",  (aiInfo.fiInfo.llSupportedCommand & TPI_COMMAND_REPAIR) == TPI_COMMAND_REPAIR);\r
510 \r
511         procDlg.Show(false);\r
512 }\r
513 \r
514 void MainFrame::OnArcClose(wxCommandEvent&)\r
515 {\r
516         // ツリービュー・リストビュー設定。\r
517         this->tree_ctrl->DeleteAllItems();\r
518         this->list_ctrl->DeleteAllItems();\r
519         this->list_ctrl->showFileInfo.Clear();\r
520 \r
521         // ツールバー・メニューバー設定。\r
522         SetMenuToolState("Arc_Close",   false);\r
523         SetMenuToolState("Arc_Add",     false);\r
524         SetMenuToolState("Arc_SFX",     false);\r
525         SetMenuToolState("Arc_UnSFX",   false);\r
526         SetMenuToolState("Arc_Extract", false);\r
527         SetMenuToolState("Arc_Delete",  false);\r
528         SetMenuToolState("Arc_Test",    false);\r
529         SetMenuToolState("Arc_Repair",  false);\r
530 \r
531         for (int i = 0; i < this->statusbar->GetFieldsCount(); i++)\r
532         {\r
533                 this->statusbar->SetStatusText(wxEmptyString, i);\r
534         }\r
535         this->fileinfo.Clear();\r
536         this->szComment.Clear();\r
537 \r
538         g_hIconT.RemoveAll();\r
539         g_hIconLL.RemoveAll();\r
540         g_hIconLS.RemoveAll();\r
541         this->tpi.FreeLibrary();\r
542 }\r
543 \r
544 void MainFrame::OnArcAdd(wxCommandEvent& e)\r
545 {\r
546         // 処理対象のファイルを選択。\r
547         wxArrayString files;\r
548         wxFileDialog fd(this, _("Choose files to add"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0));\r
549         fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);\r
550         if (fd.ShowModal() == wxID_CANCEL)\r
551         {\r
552                 return;\r
553         }\r
554         fd.GetFilenames(files);\r
555         this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());\r
556 \r
557         // 各種設定。\r
558         TPI_SWITCHES swInfo;\r
559         swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());\r
560         swInfo.fMakeSFX = false;\r
561         swInfo.pCustomSwitches = NULL;\r
562 \r
563         ProcessDialog procDlg;\r
564         procDlg.InitDialog();\r
565         procDlg.Show(true);\r
566         if (! this->tpi.Command(TPI_COMMAND_ADD, & swInfo, this->fnArchive.GetFullPath(), files))\r
567         {\r
568                 this->ErrorCheck(tpi.nErrorCode);\r
569         }\r
570         procDlg.Show(false);\r
571 \r
572         // 書庫を再読み込み。\r
573         this->OnArcOpen(e);\r
574 }\r
575 \r
576 void MainFrame::OnArcConvert(wxCommandEvent& e)\r
577 {\r
578         TPI_SWITCHES swInfo;\r
579         swInfo.fMakeSFX = e.GetId() == XRCID("Arc_SFX");\r
580 \r
581         // 保存先を尋ねる。\r
582         wxFileDialog fd(this, swInfo.fMakeSFX ? _("Save as SFX") : _("Save as normal archive"), this->fnArchive.GetPath(), this->fnArchive.GetName() + (swInfo.fMakeSFX ? EXE_EXT : (wxString) wxEmptyString));\r
583         fd.SetWindowStyleFlag(wxFD_SAVE | wxFD_OVERWRITE_PROMPT);\r
584         if (fd.ShowModal() == wxID_CANCEL)\r
585         {\r
586                 return;\r
587         }\r
588         swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());\r
589         this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());\r
590 \r
591         wxArrayString files;\r
592         files.Add(fd.GetPath());\r
593 \r
594         ProcessDialog procDlg;\r
595         procDlg.InitDialog();\r
596         procDlg.Show(true);\r
597         if (! this->tpi.Command(swInfo.fMakeSFX ? TPI_COMMAND_SFX : TPI_COMMAND_UNSFX, & swInfo, this->fnArchive.GetFullPath(), files))\r
598         {\r
599                 this->ErrorCheck(tpi.nErrorCode);\r
600         }\r
601         procDlg.Show(false);\r
602 }\r
603 \r
604 void MainFrame::OnArcExtract(wxCommandEvent& e)\r
605 {\r
606         TPI_SWITCHES swInfo;\r
607         swInfo.pCustomSwitches = NULL;\r
608 \r
609         // モード取得。通常は0, 実行なら1, ファイルDnDなら2、ディレクトリDnDなら3。\r
610         int nMode = e.GetInt();\r
611         // 実行時のみ使用。\r
612         wxFileType * ftFile = NULL;\r
613 \r
614         // 展開ダイアログを作成。DnDまたは実行時は表示しない。\r
615         MakeDialog mkDlg;\r
616         ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));\r
617         ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));\r
618         mkDlg.bIsMake = false;\r
619         mkDlg.files   = MakeTargetFileList(this, nMode == 1);\r
620 \r
621         if (nMode != 0)\r
622         {\r
623                 if (nMode == 1)\r
624                 {\r
625                         // コマンドを取得。\r
626                         ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(wxFileName(mkDlg.files[0]).GetExt());\r
627                         if (! ftFile)\r
628                         {\r
629                                 // 種類が取得できないときは設定を読み込む。初期設定ではテキストとみなす。\r
630                                 ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(this->conf.ReadId(CONF_DEFAULT_EXT, (wxString) wxT("txt")));\r
631                                 if (! ftFile)\r
632                                 {\r
633                                         ::wxLogError(_("Unable to get the file type!"));\r
634                                         return;\r
635                                 }\r
636                         }\r
637                 }\r
638 \r
639                 // 作業ディレクトリ作成。\r
640                 swInfo.fStoreDirectoryPathes = false;\r
641                 wxString szDestDirBase = nMode == 3 ? this->tree_ctrl->GetItemText(this->tree_ctrl->GetSelection()) : wxT("tpi_tmp");\r
642                 if (szDestDirBase == wxT("-----"))\r
643                 {\r
644                         // 書庫ルートのときは書庫名にしておく。\r
645                         szDestDirBase = this->fnArchive.GetName();\r
646                 }\r
647                 swInfo.fnDestinationDirectory = MakeDirPath(wxFileName::DirName(::wxGetCwd()), szDestDirBase, true);\r
648                 if (! swInfo.fnDestinationDirectory.IsOk())\r
649                 {\r
650                         ::wxLogError(_("Unable to make the temporary directory!"));\r
651                         return;\r
652                 }\r
653         }\r
654         else\r
655         {\r
656                 mkDlg.InitDialog();\r
657                 if (mkDlg.ShowModal() == wxID_CANCEL)\r
658                 {\r
659                         return;\r
660                 }\r
661 \r
662                 // 各種設定。\r
663                 swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();\r
664                 swInfo.fnDestinationDirectory = wxFileName::DirName(mkDlg.cbDir->GetValue());\r
665                 swInfo.szPassword = mkDlg.tcPassword->GetValue();\r
666                 swInfo.szKeyFile  = mkDlg.tcKeyfile->GetValue();\r
667 \r
668                 // 必要なら書庫名でディレクトリを作成する。\r
669                 if (WillMakeDirByArcName(this, & mkDlg))\r
670                 {\r
671                         swInfo.fnDestinationDirectory = MakeDirPath(swInfo.fnDestinationDirectory, this->fnArchive.GetName(), true);\r
672                         if (! swInfo.fnDestinationDirectory.IsOk())\r
673                         {\r
674                                 ::wxLogError(_("Unable to make the destination directory!"));\r
675                                 return;\r
676                         }\r
677                 }\r
678         }\r
679 \r
680         ProcessDialog procDlg;\r
681         procDlg.InitDialog();\r
682         procDlg.Show(true);\r
683         if (! this->tpi.Command(TPI_COMMAND_EXTRACT, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))\r
684         {\r
685                 this->ErrorCheck(tpi.nErrorCode);\r
686         }\r
687         procDlg.Show(false);\r
688 \r
689         if (nMode == 0)\r
690         {\r
691                 if (mkDlg.cbOpenAfter->IsChecked())\r
692                 {\r
693                         // 展開先を開く。\r
694 #ifdef __WINDOWS__\r
695                         ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());\r
696 #endif\r
697                 }\r
698 \r
699                 if (mkDlg.cbExitAfter->IsChecked())\r
700                 {\r
701                         // 終了。\r
702                         this->Close(true);\r
703                 }\r
704         }\r
705         else\r
706         {\r
707                 wxArrayString asFiles;\r
708                 if (nMode == 1)\r
709                 {\r
710                         // コマンドを実行。\r
711                         asFiles.Add(swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[0]).GetFullName());\r
712                         if (tpi.nErrorCode == TPI_ERROR_SUCCESS)\r
713                         {\r
714 #ifdef __LINUX__\r
715                                 // Linuxでは引用符で囲む必要がある。\r
716                                 ::wxExecute(ftFile->GetOpenCommand(wxT('"') + asFiles[0] + wxT('"')), wxEXEC_SYNC);\r
717 #else\r
718                                 ::wxExecute(ftFile->GetOpenCommand(asFiles[0]), wxEXEC_SYNC);\r
719 #endif\r
720                         }\r
721                 }\r
722                 else\r
723                 {\r
724                         // 展開対象を決定。\r
725                         wxFileDataObject objFile;\r
726                         for (size_t i = 0; i < mkDlg.files.GetCount(); i++)\r
727                         {\r
728                                 wxString szFileName = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[i]).GetFullName();\r
729                                 if (nMode == 2)\r
730                                 {\r
731                                         // リストに追加。\r
732                                         objFile.AddFile(szFileName);\r
733                                 }\r
734                                 asFiles.Add(szFileName);\r
735                         }\r
736                         if (nMode == 3)\r
737                         {\r
738                                 objFile.AddFile(swInfo.fnDestinationDirectory.GetPath());\r
739                         }\r
740 \r
741                         // DnD開始。\r
742                         wxDropSource dropSource(objFile, this);\r
743                         if (dropSource.DoDragDrop() != wxDragMove)\r
744                         {\r
745 #ifdef __LINUX__\r
746                                 // Linuxではまだ処理が終わっていない(コンテキストメニューが表示されている)ので、とりあえず3秒だけ待つ。\r
747                                 sleep(3);\r
748 #endif\r
749                         }\r
750                 }\r
751 \r
752                 // ファイルと一時ディレクトリを削除。\r
753                 for (size_t i = 0; i < asFiles.GetCount(); i++)\r
754                 {\r
755                         ::wxRemoveFile(asFiles[i]);\r
756                 }\r
757                 ::wxRmdir(swInfo.fnDestinationDirectory.GetFullPath());\r
758         }\r
759 }\r
760 \r
761 void MainFrame::OnArcDelete(wxCommandEvent& e)\r
762 {\r
763         // 全ファイル削除は危険ではないかと。\r
764         if (this->list_ctrl->GetSelectedItemCount() == 0)\r
765         {\r
766                 return;\r
767         }\r
768 \r
769         if (::AskDlg(_("Are you sure to delete selected files?"), this) == wxNO)\r
770         {\r
771                 return;\r
772         }\r
773 \r
774         // 各種設定。\r
775         TPI_SWITCHES swInfo;\r
776         ProcessDialog procDlg;\r
777         procDlg.InitDialog();\r
778         procDlg.Show(true);\r
779         if (! this->tpi.Command(TPI_COMMAND_DELETE, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false)))\r
780         {\r
781                 this->ErrorCheck(tpi.nErrorCode);\r
782         }\r
783         procDlg.Show(false);    \r
784 \r
785         // 書庫を再読み込みする。\r
786         this->OnArcOpen(e);\r
787 }\r
788 \r
789 void MainFrame::OnArcTest(wxCommandEvent&)\r
790 {\r
791         TPI_SWITCHES swInfo;\r
792         ProcessDialog procDlg;\r
793         procDlg.InitDialog();\r
794         procDlg.Show(true);\r
795         bool bIsCorrect = this->tpi.Command(TPI_COMMAND_TEST, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false));\r
796         procDlg.Show(false);\r
797         if (bIsCorrect)\r
798         {\r
799                 ::wxLogMessage(_("This is a correct archive."));\r
800         }\r
801         else\r
802         {\r
803                 this->ErrorCheck(tpi.nErrorCode);\r
804         }\r
805 }\r
806 \r
807 void MainFrame::OnArcRepair(wxCommandEvent&)\r
808 {\r
809         TPI_SWITCHES swInfo;\r
810         ProcessDialog procDlg;\r
811         procDlg.InitDialog();\r
812         procDlg.Show(true);\r
813         if (! this->tpi.Command(TPI_COMMAND_REPAIR, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false)))\r
814         {\r
815                 this->ErrorCheck(tpi.nErrorCode);\r
816         }\r
817         procDlg.Show(false);    \r
818 }\r
819 \r
820 void MainFrame::OnViewMode(wxCommandEvent & e)\r
821 {\r
822         int n = e.GetId();\r
823         this->menubar->Check(n, true);\r
824         this->list_ctrl->SetSingleStyle(wxLC_REPORT, n == XRCID("Exe_View_Details"));\r
825         this->list_ctrl->SetSingleStyle(wxLC_ICON,   n == XRCID("Exe_View_Icons"));\r
826         this->list_ctrl->SetSingleStyle(wxLC_LIST,   n == XRCID("Exe_View_List"));\r
827 }\r
828 \r
829 void MainFrame::OnShowToolBar(wxCommandEvent & e)\r
830 {\r
831         this->toolbar->Show(e.IsChecked());\r
832 }\r
833 \r
834 void MainFrame::OnShowStatusBar(wxCommandEvent & e)\r
835 {\r
836         this->statusbar->Show(e.IsChecked());\r
837 }\r
838 \r
839 void MainFrame::OnSelectAll(wxCommandEvent &)\r
840 {\r
841         for (int i = 0; i < this->list_ctrl->GetItemCount(); i++)\r
842         {\r
843                 this->list_ctrl->Select(i, true);\r
844         }\r
845 }\r
846 \r
847 // TreeView\r
848 \r
849 void MainFrame::OnTreeChanged(wxTreeEvent& e)\r
850 {\r
851         // ツリービューからパスを取得。\r
852         wxString szNodePath = TreeView_GetItemPath(this->tree_ctrl, e.GetItem());\r
853         // リストビューを初期化。\r
854         this->list_ctrl->showFileInfo.Clear();\r
855         this->list_ctrl->DeleteAllItems();\r
856         g_hIconLL.RemoveAll();\r
857         g_hIconLS.RemoveAll();\r
858 \r
859         // 現在のアイテムの選択状態を無効にしておく。\r
860         long nSelected = this->list_ctrl->GetFirstSelected();\r
861         while (nSelected != -1)\r
862         {\r
863                 this->list_ctrl->Select(nSelected, false);\r
864                 nSelected = this->list_ctrl->GetNextSelected(nSelected);\r
865         }\r
866 \r
867         // アイコン設定。\r
868         this->list_ctrl->SetImageList(& g_hIconLL, wxIMAGE_LIST_NORMAL);\r
869         this->list_ctrl->SetImageList(& g_hIconLS, wxIMAGE_LIST_SMALL);\r
870 \r
871         // 配列と比較し、パスが一致しなければ消す。\r
872         for (size_t i = 0; i < this->fileinfo.GetCount(); i++)\r
873         {\r
874                 // パスを比較。\r
875                 if (szNodePath == wxT("*") || szNodePath == this->fileinfo[i].fnFileName.GetPath())\r
876                 {\r
877                         // 項目がフォルダであるなら無視。\r
878                         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))\r
879                         {\r
880                                 continue;\r
881                         }\r
882 \r
883                         // フィルタにかからなければ無視。\r
884                         if (this->fileinfo[i].fnFileName.GetFullName().MakeLower().Find(this->tcFilter->GetValue().MakeLower()) == wxNOT_FOUND)\r
885                         {\r
886                                 continue;\r
887                         }\r
888 \r
889                         this->list_ctrl->showFileInfo.Add(this->fileinfo[i]);\r
890                 }\r
891         }\r
892 \r
893         // ソートして表示。\r
894         this->list_ctrl->showFileInfo.Sort(& ListCtrlCompareProc);\r
895         this->list_ctrl->SetItemCount(this->list_ctrl->showFileInfo.GetCount());\r
896 }\r
897 \r
898 void MainFrame::OnTreeBeginDrag(wxTreeEvent& e)\r
899 {\r
900         // TODO : アイテムが子階層を持っていても展開できない。\r
901         this->tree_ctrl->SelectItem(e.GetItem());\r
902 \r
903         wxCommandEvent e1;\r
904         e1.SetInt(3);\r
905         this->OnArcExtract(e1);\r
906 }\r
907 \r
908 // ListView\r
909 \r
910 void MainFrame::OnListItemDClick(wxListEvent&)\r
911 {\r
912         wxCommandEvent e;\r
913         e.SetInt(1);\r
914         this->OnArcExtract(e);\r
915 }\r
916 \r
917 void MainFrame::OnListBeginDrag(wxListEvent&)\r
918 {\r
919         if (this->list_ctrl->GetSelectedItemCount() == 0)\r
920         {\r
921                 // アイテムを選択せずドラッグしようとした場合。\r
922                 return;\r
923         }\r
924 \r
925         wxCommandEvent e;\r
926         e.SetInt(2);\r
927         this->OnArcExtract(e);\r
928 }\r
929 \r
930 // Filter\r
931 \r
932 void MainFrame::OnFilter(wxCommandEvent&)\r
933 {\r
934         wxTreeEvent e;\r
935         e.SetItem(this->tree_ctrl->GetSelection());\r
936         this->OnTreeChanged(e);\r
937 }\r
938 \r
939 // イベントハンドラ以外。\r
940 \r
941 wxULongLong MainFrame::LoadTPI(wxString szFileName)\r
942 {\r
943         // TPIを読み込み。\r
944         wxFileSystem fs;\r
945         fs.ChangePathTo(L_DIR_B_LIB, true);\r
946         wxString szTPIName = fs.FindFirst(wxT("*" TPI_EXT), wxFILE);\r
947         wxULongLong llFileCount = 0;\r
948         while (! szTPIName.IsEmpty())\r
949         {\r
950                 // 対応確認。\r
951                 if (! tpi.InitLibrary(szTPIName, szFileName, 0) || ! tpi.CheckArchive(szFileName, & llFileCount) || llFileCount == 0)\r
952                 {\r
953                         tpi.FreeLibrary();\r
954                         szTPIName = fs.FindNext();\r
955                         continue;\r
956                 }\r
957                 break;\r
958         }\r
959         return llFileCount;\r
960 }\r
961 \r
962 int MainFrame::ErrorCheck(int nErrorCode)\r
963 {\r
964         switch (nErrorCode)\r
965         {\r
966         case TPI_ERROR_SUCCESS:\r
967         case TPI_CALLBACK_CONTINUE:\r
968                 break;\r
969         case TPI_ERROR_D_UNSUPPORTED:\r
970                 ::wxLogError(_("Sorry, this function is not supported yet."));\r
971                 break;\r
972         case TPI_ERROR_D_SKIPPED:\r
973         case TPI_CALLBACK_CANCEL:\r
974                 ::wxLogError(_("This operation is canceled by the user."));\r
975                 break;\r
976         default:\r
977                 ::wxLogError(_("Error code: %d"), nErrorCode);\r
978         }\r
979         return nErrorCode;\r
980 }\r