OSDN Git Service

暗号化されたファイルを緑色で示す機能を追加。
[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                 fd.GetFilenames(mkDlg.files);\r
246         }\r
247         else\r
248         {\r
249                 mkDlg.files = * (wxArrayString *) e.GetClientData();\r
250                 swInfo.fnDestinationDirectory = wxFileName::DirName(wxFileName(mkDlg.files[0]).GetPath());\r
251                 // 相対パスに変換。\r
252                 for (size_t n = 0; n < mkDlg.files.GetCount(); n++)\r
253                 {\r
254                         wxFileName fn(mkDlg.files[n]);\r
255                         fn.MakeRelativeTo(swInfo.fnDestinationDirectory.GetPath());\r
256                         mkDlg.files[n] = fn.GetFullPath();\r
257                 }\r
258         }\r
259 \r
260         this->OnArcClose(e);\r
261         // 書庫名はファイル名の拡張子より前、もしくはディレクトリ名。\r
262         this->fnArchive = wxFileName(mkDlg.files[0]);\r
263         this->fnArchive.SetName(mkDlg.files.GetCount() == 1 ? (this->fnArchive.GetName().IsEmpty() ? this->fnArchive.GetDirs().Last() : this->fnArchive.GetName()) : swInfo.fnDestinationDirectory.GetDirs().Last());\r
264         this->fnArchive.SetEmptyExt();\r
265         this->fnArchive.SetPath(swInfo.fnDestinationDirectory.GetPath());\r
266 \r
267         // ダイアログを表示。\r
268         mkDlg.InitDialog();\r
269         if (mkDlg.ShowModal() == wxID_CANCEL)\r
270         {\r
271                 return;\r
272         }\r
273 \r
274         // 各種設定。\r
275         swInfo.fStoreDirectoryPathes= ! mkDlg.cbIgnorePath->IsChecked();\r
276         swInfo.fMakeSFX                     = mkDlg.cbMakeSFX->IsChecked();\r
277         swInfo.fSolid               = mkDlg.cbSolid->IsChecked();\r
278         swInfo.fMMOptimize          = mkDlg.cbMMOptimize->IsChecked();\r
279         swInfo.fEncryptHeader       = mkDlg.cbEncryptHeader->IsChecked();\r
280         swInfo.sCompressLevel       = mkDlg.scLevel->GetValue();\r
281         swInfo.sRecoveryRecord      = mkDlg.scRR->GetValue();\r
282         swInfo.szPassword           = mkDlg.tcPassword->GetValue();\r
283         swInfo.szKeyFile            = mkDlg.tcKeyfile->GetValue();\r
284         swInfo.szComment            = mkDlg.tcComment->GetValue();\r
285         {\r
286                 wxULongLong_t ll;\r
287                 mkDlg.cbSplitSize->GetValue().ToULongLong(& ll);\r
288                 swInfo.llSplitSize      = ll;\r
289         }\r
290 \r
291         // TPIを読み込み。\r
292         int nSelected = mkDlg.chType->GetSelection();\r
293         this->fnArchive = wxFileName(mkDlg.cbDir->GetValue(), mkDlg.cbFileName->GetValue());\r
294         if (! tpi.InitLibrary(mkDlg.afInfo[nSelected].szTPIName, this->fnArchive.GetFullPath(), mkDlg.afInfo[nSelected].llTypeId))\r
295         {\r
296                 ::wxLogError(_("Error: %s!"), wxT("InitLibrary()!"));\r
297                 return;\r
298         }\r
299 \r
300         // コールバック関数を設定。\r
301         if (! tpi.SetCallbackProc(TPICallbackProc))\r
302         {\r
303                 ::wxLogError(_("Error: %s!"), wxT("SetCallbackProc()!"));\r
304         }\r
305 \r
306         // 処理を行う。\r
307         ProcessDialog procDlg;\r
308         procDlg.InitDialog();\r
309         procDlg.Show(true);\r
310         if (! tpi.Command(TPI_COMMAND_CREATE, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))\r
311         {\r
312                 this->ErrorCheck(tpi.nErrorCode);\r
313                 return;\r
314         }\r
315         procDlg.Show(false);\r
316         tpi.FreeLibrary();\r
317 \r
318         if (mkDlg.cbOpenAfter->IsChecked())\r
319         {\r
320                 // 作成先を開く。\r
321 #ifdef __WINDOWS__\r
322                 ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());\r
323 #endif\r
324         }\r
325 \r
326         if (mkDlg.cbExitAfter->IsChecked())\r
327         {\r
328                 // 終了。\r
329                 this->Close(true);\r
330         }\r
331 \r
332         // 終了しない場合は書庫を開く。\r
333         this->OnArcOpen(e);\r
334 }\r
335 \r
336 void MainFrame::OnArcOpen(wxCommandEvent& e)\r
337 {\r
338         // 書庫を選択。\r
339         if (e.GetId() == XRCID("Arc_Open"))\r
340         {\r
341                 wxFileDialog fd(this);\r
342                 fd.SetDirectory(this->conf.ReadHistory(CONF_HISTORY_PATH, 0));\r
343                 fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST);\r
344                 if (fd.ShowModal() == wxID_CANCEL)\r
345                 {\r
346                         return;\r
347                 }\r
348                 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());\r
349                 this->fnArchive = wxFileName(fd.GetPath());\r
350         }\r
351         this->OnArcClose(e);\r
352 \r
353         // 進捗ダイアログ表示。\r
354         ProcessDialog procDlg;\r
355         procDlg.InitDialog();\r
356         procDlg.Show(true);\r
357 \r
358         // TPIを読み込み、最初のコールバックを送信。\r
359         TPI_PROCESSINFO piInfo;\r
360         piInfo.uMessage = TPI_MESSAGE_STATUS;\r
361         piInfo.uStatus = 0x1000;\r
362         piInfo.llProcessedSize = 0;\r
363         piInfo.fiInfo.fnFileName = this->fnArchive;\r
364         piInfo.fiInfo.llUnpackedSize = this->LoadTPI(this->fnArchive.GetFullPath());\r
365         if (piInfo.fiInfo.llUnpackedSize.ToULong() == 0)\r
366         {\r
367                 procDlg.Show(false);\r
368                 tpi.FreeLibrary();\r
369                 ::wxLogError(_("No plug-in supporting this archive was found!"));\r
370                 return;\r
371         }\r
372         TPICallbackProc(TPI_NOTIFY_COMMON, & piInfo);\r
373 \r
374         // コールバック関数を設定。\r
375         tpi.SetCallbackProc(TPICallbackProc);\r
376 \r
377         // 配列のサイズを確保。\r
378         this->fileinfo.Alloc(piInfo.fiInfo.llUnpackedSize.ToULong());\r
379 \r
380         // 書庫を開く。\r
381         if (! tpi.OpenArchive(this->fnArchive.GetFullPath()))\r
382         {\r
383                 procDlg.Show(false);\r
384                 tpi.FreeLibrary();\r
385                 ::wxLogError(_("Error: %s!"), wxT("OpenArchive()"));\r
386                 return;\r
387         }\r
388 \r
389         // 履歴に追加。\r
390         this->conf.WriteHistory(CONF_HISTORY_PATH, this->fnArchive.GetPath());\r
391         this->conf.WriteHistory(CONF_HISTORY_NAME, this->fnArchive.GetFullName());\r
392         this->conf.WriteHistory(CONF_HISTORY_FULL, this->fnArchive.GetFullPath());\r
393 \r
394         // 書庫のアイコンを取得し、書庫ルートを作成。\r
395         g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_closed.png"), wxBITMAP_TYPE_ANY));\r
396         g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_open.png"), wxBITMAP_TYPE_ANY));\r
397         this->tree_ctrl->SetImageList(& g_hIconT);\r
398         wxTreeItemId\r
399                 idRoot = this->tree_ctrl->AddRoot(wxEmptyString),\r
400 #ifdef __WINDOWS__\r
401                 idArchive = this->tree_ctrl->AppendItem(idRoot, piInfo.fiInfo.fnFileName.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName))),\r
402 #else\r
403                 idArchive = this->tree_ctrl->AppendItem(idRoot, piInfo.fiInfo.fnFileName.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName).ConvertToImage().Rescale(16, 16))),\r
404 #endif\r
405                 idArcRoot = this->tree_ctrl->AppendItem(idRoot, wxT("-----"), 0, 1);\r
406 \r
407         // ファイル情報をロード。\r
408         if (tpi.GetFileInformation(& piInfo.fiInfo, true))\r
409         {\r
410                 piInfo.uStatus = 0x1001;\r
411                 do\r
412                 {\r
413                         piInfo.llProcessedSize++;\r
414                         if (this->ErrorCheck(TPICallbackProc(TPI_NOTIFY_COMMON, & piInfo)) == TPI_CALLBACK_CANCEL)\r
415                         {\r
416                                 procDlg.Show(false);\r
417                                 tpi.CloseArchive();\r
418                                 wxCommandEvent e;\r
419                                 this->OnArcClose(e);\r
420                                 return;\r
421                         }\r
422 \r
423                         // ツリービューに反映。\r
424                         TreeView_CheckNewerItem(this->tree_ctrl, idArcRoot, piInfo.fiInfo.fnFileName.GetPath(), true);\r
425 \r
426                         // ディレクトリ属性を含むものについては除去。\r
427                         if (piInfo.fiInfo.dwAttribute & TPI_ATTRIBUTE_DIRECTORY)\r
428                         {\r
429                                 continue;\r
430                         }\r
431 \r
432                         // セキュリティチェック。\r
433                         // DTV検査。\r
434                         if (piInfo.fiInfo.fnFileName.GetPathWithSep().Find(wxT("..")) != wxNOT_FOUND)\r
435                         {\r
436                                 piInfo.fiInfo.uDanger = TRUE;\r
437                                 ::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
438                         }\r
439                         // 空白の連続による拡張子偽装を検査。\r
440                         if (piInfo.fiInfo.fnFileName.GetFullName().Find(wxT("        ")) != wxNOT_FOUND)\r
441                         {\r
442                                 piInfo.fiInfo.uDanger = TRUE;\r
443                                 ::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:\n%s"), piInfo.fiInfo.szStoredName.c_str());\r
444                         }\r
445                         // Unicode制御文字を検査。\r
446                         for (wxChar c = 0x200c; c <= 0x206f; c++)\r
447                         {\r
448                                 if (piInfo.fiInfo.fnFileName.GetFullName().Find(c) != wxNOT_FOUND)\r
449                                 {\r
450                                         piInfo.fiInfo.uDanger = TRUE;\r
451                                         ::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%s"), piInfo.fiInfo.szStoredName.c_str());\r
452                                 }\r
453                                 switch (c)\r
454                                 {\r
455                                 case 0x200f: c = 0x2027; break;\r
456                                 case 0x202e: c = 0x2060; break;\r
457                                 }\r
458                         }\r
459 \r
460                         // 情報を保存してカウントアップ。\r
461                         this->fileinfo.Add(piInfo.fiInfo);\r
462                 }\r
463                 while (tpi.GetFileInformation(& piInfo.fiInfo, false));\r
464         }\r
465 \r
466         // 書庫の情報を取得。\r
467         if (! tpi.GetArchiveInformation(& this->aiArchive))\r
468         {\r
469                 procDlg.Show(false);\r
470                 tpi.FreeLibrary();\r
471                 ::wxLogError(_("Error: %s!"), wxT("GetArchiveInformation()"));\r
472                 return;\r
473         }\r
474 \r
475         // 書庫を閉じる。\r
476         if (! tpi.CloseArchive())\r
477         {\r
478                 ::wxLogError(_("Error: %s!"), wxT("CloseArchive()"));\r
479         }\r
480 \r
481         // 以下、UI処理。\r
482         this->fileinfo.Shrink();\r
483         this->tree_ctrl->ExpandAll();\r
484         this->tree_ctrl->ScrollTo(idArchive);\r
485         this->tree_ctrl->SelectItem(idArchive);\r
486         this->list_ctrl->atDangerItem.SetTextColour(* wxRED);\r
487         this->list_ctrl->atEncryptedItem.SetTextColour(wxColour(wxT("forest green")));\r
488 \r
489         // ステータスバー設定。\r
490         this->statusbar->SetStatusText(this->aiArchive.fiInfo.szTypeName, 0);\r
491         this->statusbar->SetStatusText(wxString::Format(_("%d file(s)"), this->fileinfo.GetCount()), 1);\r
492         this->statusbar->SetStatusText(this->aiArchive.llUnpackedSize.ToString() + _(" B -> ") + this->aiArchive.llPackedSize.ToString() + _(" B"), 2);\r
493         this->statusbar->SetStatusText(wxString::Format(wxT("%3.1f%%"), this->aiArchive.wCompressRatio / 10.0), 3);\r
494         this->statusbar->SetStatusText(this->fnArchive.GetFullPath(), 4);\r
495 \r
496         // ツールバー・メニューバー設定。\r
497         SetMenuToolState("Arc_Close",   true);\r
498         SetMenuToolState("Arc_Add",     (this->aiArchive.fiInfo.llSupportedCommand & TPI_COMMAND_ADD)   == TPI_COMMAND_ADD   && this->aiArchive.fiInfo.fArchive);\r
499         SetMenuToolState("Arc_SFX",     (this->aiArchive.fiInfo.llSupportedCommand & TPI_COMMAND_SFX)    == TPI_COMMAND_SFX   && this->aiArchive.nSFXType == 0);\r
500         SetMenuToolState("Arc_UnSFX",   (this->aiArchive.fiInfo.llSupportedCommand & TPI_COMMAND_UNSFX)  == TPI_COMMAND_UNSFX && this->aiArchive.nSFXType != 0);\r
501         SetMenuToolState("Arc_Extract", (this->aiArchive.fiInfo.llSupportedCommand & TPI_COMMAND_EXTRACT)== TPI_COMMAND_EXTRACT);\r
502         SetMenuToolState("Arc_Delete",  (this->aiArchive.fiInfo.llSupportedCommand & TPI_COMMAND_DELETE) == TPI_COMMAND_DELETE && this->aiArchive.fiInfo.fArchive);\r
503         SetMenuToolState("Arc_Test",    (this->aiArchive.fiInfo.llSupportedCommand & TPI_COMMAND_TEST)   == TPI_COMMAND_TEST);\r
504         SetMenuToolState("Arc_Repair",  (this->aiArchive.fiInfo.llSupportedCommand & TPI_COMMAND_REPAIR) == TPI_COMMAND_REPAIR);\r
505 \r
506         procDlg.Show(false);\r
507 }\r
508 \r
509 void MainFrame::OnArcClose(wxCommandEvent&)\r
510 {\r
511         // ツリービュー・リストビュー設定。\r
512         this->tree_ctrl->DeleteAllItems();\r
513         this->list_ctrl->DeleteAllItems();\r
514         this->list_ctrl->showFileInfo.Clear();\r
515 \r
516         // ツールバー・メニューバー設定。\r
517         SetMenuToolState("Arc_Close",   false);\r
518         SetMenuToolState("Arc_Add",     false);\r
519         SetMenuToolState("Arc_SFX",     false);\r
520         SetMenuToolState("Arc_UnSFX",   false);\r
521         SetMenuToolState("Arc_Extract", false);\r
522         SetMenuToolState("Arc_Delete",  false);\r
523         SetMenuToolState("Arc_Test",    false);\r
524         SetMenuToolState("Arc_Repair",  false);\r
525 \r
526         for (int i = 0; i < this->statusbar->GetFieldsCount(); i++)\r
527         {\r
528                 this->statusbar->SetStatusText(wxEmptyString, i);\r
529         }\r
530         this->fileinfo.Clear();\r
531         this->aiArchive.szComment.Clear();\r
532         this->aiArchive.fnArchive.Clear();\r
533         this->aiArchive.fiInfo.szTypeName.Clear();\r
534         this->aiArchive.fiInfo.szSuffix.Clear();\r
535         this->aiArchive.fiInfo.szEngineName.Clear();\r
536         this->aiArchive.fiInfo.szTPIName.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         MakeDialog mkDlg;\r
548         ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));\r
549         ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));\r
550         mkDlg.uCommand = TPI_COMMAND_ADD;\r
551 \r
552         // 処理対象のファイルを選択。\r
553         wxFileDialog fd(this, _("Choose files to add"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0));\r
554         fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);\r
555         if (fd.ShowModal() == wxID_CANCEL)\r
556         {\r
557                 return;\r
558         }\r
559         fd.GetFilenames(mkDlg.files);\r
560         this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());\r
561 \r
562         // ダイアログを表示。\r
563         mkDlg.InitDialog();\r
564         if (mkDlg.ShowModal() == wxID_CANCEL)\r
565         {\r
566                 return;\r
567         }\r
568 \r
569         // 各種設定。\r
570         TPI_SWITCHES swInfo;\r
571         swInfo.pCustomSwitches       = NULL;\r
572         swInfo.fMakeSFX              = false;\r
573         swInfo.fnDestinationDirectory= wxFileName::DirName(fd.GetDirectory());\r
574         swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();\r
575         swInfo.fSolid               = mkDlg.cbSolid->IsChecked();\r
576         swInfo.fMMOptimize          = mkDlg.cbMMOptimize->IsChecked();\r
577         swInfo.fEncryptHeader       = mkDlg.cbEncryptHeader->IsChecked();\r
578         swInfo.sCompressLevel       = mkDlg.scLevel->GetValue();\r
579         swInfo.sRecoveryRecord      = mkDlg.scRR->GetValue();\r
580         swInfo.szPassword           = mkDlg.tcPassword->GetValue();\r
581         swInfo.szKeyFile            = mkDlg.tcKeyfile->GetValue();\r
582         swInfo.szComment            = mkDlg.tcComment->GetValue();\r
583 \r
584         ProcessDialog procDlg;\r
585         procDlg.InitDialog();\r
586         procDlg.Show(true);\r
587         if (! this->tpi.Command(TPI_COMMAND_ADD, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))\r
588         {\r
589                 this->ErrorCheck(tpi.nErrorCode);\r
590         }\r
591         procDlg.Show(false);\r
592 \r
593         if (mkDlg.cbOpenAfter->IsChecked())\r
594         {\r
595                 // 作成先を開く。\r
596 #ifdef __WINDOWS__\r
597                 ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());\r
598 #endif\r
599         }\r
600 \r
601         if (mkDlg.cbExitAfter->IsChecked())\r
602         {\r
603                 // 終了。\r
604                 this->Close(true);\r
605         }\r
606 \r
607         // 終了しない場合は書庫を再読み込み。\r
608         this->OnArcOpen(e);\r
609 }\r
610 \r
611 void MainFrame::OnArcConvert(wxCommandEvent& e)\r
612 {\r
613         TPI_SWITCHES swInfo;\r
614         swInfo.fMakeSFX = e.GetId() == XRCID("Arc_SFX");\r
615 \r
616         // 保存先を尋ねる。\r
617         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
618         fd.SetWindowStyleFlag(wxFD_SAVE | wxFD_OVERWRITE_PROMPT);\r
619         if (fd.ShowModal() == wxID_CANCEL)\r
620         {\r
621                 return;\r
622         }\r
623         swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());\r
624         this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());\r
625 \r
626         wxArrayString files;\r
627         files.Add(fd.GetPath());\r
628 \r
629         ProcessDialog procDlg;\r
630         procDlg.InitDialog();\r
631         procDlg.Show(true);\r
632         if (! this->tpi.Command(swInfo.fMakeSFX ? TPI_COMMAND_SFX : TPI_COMMAND_UNSFX, & swInfo, this->fnArchive.GetFullPath(), files))\r
633         {\r
634                 this->ErrorCheck(tpi.nErrorCode);\r
635         }\r
636         procDlg.Show(false);\r
637 }\r
638 \r
639 void MainFrame::OnArcExtract(wxCommandEvent& e)\r
640 {\r
641         TPI_SWITCHES swInfo;\r
642         swInfo.pCustomSwitches = NULL;\r
643 \r
644         // モード取得。通常は0, 実行なら1, ファイルDnDなら2、ディレクトリDnDなら3。\r
645         int nMode = e.GetInt();\r
646         // 実行時のみ使用。\r
647         wxFileType * ftFile = NULL;\r
648 \r
649         // 展開ダイアログを作成。DnDまたは実行時は表示しない。\r
650         MakeDialog mkDlg;\r
651         ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));\r
652         ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));\r
653         mkDlg.uCommand = TPI_COMMAND_EXTRACT;\r
654         mkDlg.files    = MakeTargetFileList(this, nMode == 1);\r
655 \r
656         if (nMode != 0)\r
657         {\r
658                 if (nMode == 1)\r
659                 {\r
660                         // コマンドを取得。\r
661                         ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(wxFileName(mkDlg.files[0]).GetExt());\r
662                         if (! ftFile)\r
663                         {\r
664                                 // 種類が取得できないときは設定を読み込む。初期設定ではテキストとみなす。\r
665                                 ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(this->conf.ReadId(CONF_DEFAULT_EXT, (wxString) wxT("txt")));\r
666                                 if (! ftFile)\r
667                                 {\r
668                                         ::wxLogError(_("Unable to get the file type!"));\r
669                                         return;\r
670                                 }\r
671                         }\r
672                 }\r
673 \r
674                 // 作業ディレクトリ作成。\r
675                 swInfo.fStoreDirectoryPathes = false;\r
676                 wxString szDestDirBase = nMode == 3 ? this->tree_ctrl->GetItemText(this->tree_ctrl->GetSelection()) : wxT("tpi_tmp");\r
677                 if (szDestDirBase == wxT("-----"))\r
678                 {\r
679                         // 書庫ルートのときは書庫名にしておく。\r
680                         szDestDirBase = this->fnArchive.GetName();\r
681                 }\r
682                 swInfo.fnDestinationDirectory = MakeDirPath(wxFileName::DirName(::wxGetCwd()), szDestDirBase, true);\r
683                 if (! swInfo.fnDestinationDirectory.IsOk())\r
684                 {\r
685                         ::wxLogError(_("Unable to make the temporary directory!"));\r
686                         return;\r
687                 }\r
688         }\r
689         else\r
690         {\r
691                 mkDlg.InitDialog();\r
692                 if (mkDlg.ShowModal() == wxID_CANCEL)\r
693                 {\r
694                         return;\r
695                 }\r
696 \r
697                 // 各種設定。\r
698                 swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();\r
699                 swInfo.fnDestinationDirectory = wxFileName::DirName(mkDlg.cbDir->GetValue());\r
700                 swInfo.szPassword = mkDlg.tcPassword->GetValue();\r
701                 swInfo.szKeyFile  = mkDlg.tcKeyfile->GetValue();\r
702 \r
703                 // 必要なら書庫名でディレクトリを作成する。\r
704                 if (WillMakeDirByArcName(this, & mkDlg))\r
705                 {\r
706                         swInfo.fnDestinationDirectory = MakeDirPath(swInfo.fnDestinationDirectory, this->fnArchive.GetName(), true);\r
707                         if (! swInfo.fnDestinationDirectory.IsOk())\r
708                         {\r
709                                 ::wxLogError(_("Unable to make the destination directory!"));\r
710                                 return;\r
711                         }\r
712                 }\r
713         }\r
714 \r
715         ProcessDialog procDlg;\r
716         procDlg.InitDialog();\r
717         procDlg.Show(true);\r
718         if (! this->tpi.Command(TPI_COMMAND_EXTRACT, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))\r
719         {\r
720                 this->ErrorCheck(tpi.nErrorCode);\r
721         }\r
722         procDlg.Show(false);\r
723 \r
724         if (nMode == 0)\r
725         {\r
726                 if (mkDlg.cbOpenAfter->IsChecked())\r
727                 {\r
728                         // 展開先を開く。\r
729 #ifdef __WINDOWS__\r
730                         ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());\r
731 #endif\r
732                 }\r
733 \r
734                 if (mkDlg.cbExitAfter->IsChecked())\r
735                 {\r
736                         // 終了。\r
737                         this->Close(true);\r
738                 }\r
739         }\r
740         else\r
741         {\r
742                 wxArrayString asFiles;\r
743                 if (nMode == 1)\r
744                 {\r
745                         // コマンドを実行。\r
746                         asFiles.Add(swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[0]).GetFullName());\r
747                         if (tpi.nErrorCode == TPI_ERROR_SUCCESS)\r
748                         {\r
749 #ifdef __LINUX__\r
750                                 // Linuxでは引用符で囲む必要がある。\r
751                                 ::wxExecute(ftFile->GetOpenCommand(wxT('"') + asFiles[0] + wxT('"')), wxEXEC_SYNC);\r
752 #else\r
753                                 ::wxExecute(ftFile->GetOpenCommand(asFiles[0]), wxEXEC_SYNC);\r
754 #endif\r
755                         }\r
756                 }\r
757                 else\r
758                 {\r
759                         // 展開対象を決定。\r
760                         wxFileDataObject objFile;\r
761                         for (size_t i = 0; i < mkDlg.files.GetCount(); i++)\r
762                         {\r
763                                 wxString szFileName = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[i]).GetFullName();\r
764                                 if (nMode == 2)\r
765                                 {\r
766                                         // リストに追加。\r
767                                         objFile.AddFile(szFileName);\r
768                                 }\r
769                                 asFiles.Add(szFileName);\r
770                         }\r
771                         if (nMode == 3)\r
772                         {\r
773                                 objFile.AddFile(swInfo.fnDestinationDirectory.GetPath());\r
774                         }\r
775 \r
776                         // DnD開始。\r
777                         wxDropSource dropSource(objFile, this);\r
778                         if (dropSource.DoDragDrop() != wxDragMove)\r
779                         {\r
780 #ifdef __LINUX__\r
781                                 // Linuxではまだ処理が終わっていない(コンテキストメニューが表示されている)ので、とりあえず3秒だけ待つ。\r
782                                 sleep(3);\r
783 #endif\r
784                         }\r
785                 }\r
786 \r
787                 // ファイルと一時ディレクトリを削除。\r
788                 for (size_t i = 0; i < asFiles.GetCount(); i++)\r
789                 {\r
790                         ::wxRemoveFile(asFiles[i]);\r
791                 }\r
792                 ::wxRmdir(swInfo.fnDestinationDirectory.GetFullPath());\r
793         }\r
794 }\r
795 \r
796 void MainFrame::OnArcDelete(wxCommandEvent& e)\r
797 {\r
798         // 全ファイル削除は危険ではないかと。\r
799         if (this->list_ctrl->GetSelectedItemCount() == 0)\r
800         {\r
801                 return;\r
802         }\r
803 \r
804         if (::AskDlg(_("Are you sure to delete selected files?"), this) == wxNO)\r
805         {\r
806                 return;\r
807         }\r
808 \r
809         // 各種設定。\r
810         TPI_SWITCHES swInfo;\r
811         ProcessDialog procDlg;\r
812         procDlg.InitDialog();\r
813         procDlg.Show(true);\r
814         if (! this->tpi.Command(TPI_COMMAND_DELETE, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false)))\r
815         {\r
816                 this->ErrorCheck(tpi.nErrorCode);\r
817         }\r
818         procDlg.Show(false);    \r
819 \r
820         // 書庫を再読み込みする。\r
821         this->OnArcOpen(e);\r
822 }\r
823 \r
824 void MainFrame::OnArcTest(wxCommandEvent&)\r
825 {\r
826         TPI_SWITCHES swInfo;\r
827         ProcessDialog procDlg;\r
828         procDlg.InitDialog();\r
829         procDlg.Show(true);\r
830         bool bIsCorrect = this->tpi.Command(TPI_COMMAND_TEST, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false));\r
831         procDlg.Show(false);\r
832         if (bIsCorrect)\r
833         {\r
834                 ::wxLogMessage(_("This is a correct archive."));\r
835         }\r
836         else\r
837         {\r
838                 this->ErrorCheck(tpi.nErrorCode);\r
839         }\r
840 }\r
841 \r
842 void MainFrame::OnArcRepair(wxCommandEvent&)\r
843 {\r
844         TPI_SWITCHES swInfo;\r
845         ProcessDialog procDlg;\r
846         procDlg.InitDialog();\r
847         procDlg.Show(true);\r
848         if (! this->tpi.Command(TPI_COMMAND_REPAIR, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false)))\r
849         {\r
850                 this->ErrorCheck(tpi.nErrorCode);\r
851         }\r
852         procDlg.Show(false);    \r
853 }\r
854 \r
855 void MainFrame::OnViewMode(wxCommandEvent & e)\r
856 {\r
857         int n = e.GetId();\r
858         this->menubar->Check(n, true);\r
859         this->list_ctrl->SetSingleStyle(wxLC_REPORT, n == XRCID("Exe_View_Details"));\r
860         this->list_ctrl->SetSingleStyle(wxLC_ICON,   n == XRCID("Exe_View_Icons"));\r
861         this->list_ctrl->SetSingleStyle(wxLC_LIST,   n == XRCID("Exe_View_List"));\r
862 }\r
863 \r
864 void MainFrame::OnShowToolBar(wxCommandEvent & e)\r
865 {\r
866         this->toolbar->Show(e.IsChecked());\r
867 }\r
868 \r
869 void MainFrame::OnShowStatusBar(wxCommandEvent & e)\r
870 {\r
871         this->statusbar->Show(e.IsChecked());\r
872 }\r
873 \r
874 void MainFrame::OnSelectAll(wxCommandEvent &)\r
875 {\r
876         for (int i = 0; i < this->list_ctrl->GetItemCount(); i++)\r
877         {\r
878                 this->list_ctrl->Select(i, true);\r
879         }\r
880 }\r
881 \r
882 // TreeView\r
883 \r
884 void MainFrame::OnTreeChanged(wxTreeEvent& e)\r
885 {\r
886         // ツリービューからパスを取得。\r
887         wxString szNodePath = TreeView_GetItemPath(this->tree_ctrl, e.GetItem());\r
888         // リストビューを初期化。\r
889         this->list_ctrl->showFileInfo.Clear();\r
890         this->list_ctrl->DeleteAllItems();\r
891         g_hIconLL.RemoveAll();\r
892         g_hIconLS.RemoveAll();\r
893 \r
894         // 現在のアイテムの選択状態を無効にしておく。\r
895         long nSelected = this->list_ctrl->GetFirstSelected();\r
896         while (nSelected != -1)\r
897         {\r
898                 this->list_ctrl->Select(nSelected, false);\r
899                 nSelected = this->list_ctrl->GetNextSelected(nSelected);\r
900         }\r
901 \r
902         // アイコン設定。\r
903         this->list_ctrl->SetImageList(& g_hIconLL, wxIMAGE_LIST_NORMAL);\r
904         this->list_ctrl->SetImageList(& g_hIconLS, wxIMAGE_LIST_SMALL);\r
905 \r
906         // 配列と比較し、パスが一致しなければ消す。\r
907         for (size_t i = 0; i < this->fileinfo.GetCount(); i++)\r
908         {\r
909                 // パスを比較。\r
910                 if (szNodePath == wxT("*") || szNodePath == this->fileinfo[i].fnFileName.GetPath())\r
911                 {\r
912                         // 項目がフォルダであるなら無視。\r
913                         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
914                         {\r
915                                 continue;\r
916                         }\r
917 \r
918                         // フィルタにかからなければ無視。\r
919                         if (this->fileinfo[i].fnFileName.GetFullName().MakeLower().Find(this->tcFilter->GetValue().MakeLower()) == wxNOT_FOUND)\r
920                         {\r
921                                 continue;\r
922                         }\r
923 \r
924                         this->list_ctrl->showFileInfo.Add(this->fileinfo[i]);\r
925                 }\r
926         }\r
927 \r
928         // ソートして表示。\r
929         this->list_ctrl->showFileInfo.Sort(& ListCtrlCompareProc);\r
930         this->list_ctrl->SetItemCount(this->list_ctrl->showFileInfo.GetCount());\r
931 }\r
932 \r
933 void MainFrame::OnTreeBeginDrag(wxTreeEvent& e)\r
934 {\r
935         // TODO : アイテムが子階層を持っていても展開できない。\r
936         this->tree_ctrl->SelectItem(e.GetItem());\r
937 \r
938         wxCommandEvent e1;\r
939         e1.SetInt(3);\r
940         this->OnArcExtract(e1);\r
941 }\r
942 \r
943 // ListView\r
944 \r
945 void MainFrame::OnListItemDClick(wxListEvent&)\r
946 {\r
947         wxCommandEvent e;\r
948         e.SetInt(1);\r
949         this->OnArcExtract(e);\r
950 }\r
951 \r
952 void MainFrame::OnListBeginDrag(wxListEvent&)\r
953 {\r
954         if (this->list_ctrl->GetSelectedItemCount() == 0)\r
955         {\r
956                 // アイテムを選択せずドラッグしようとした場合。\r
957                 return;\r
958         }\r
959 \r
960         wxCommandEvent e;\r
961         e.SetInt(2);\r
962         this->OnArcExtract(e);\r
963 }\r
964 \r
965 // Filter\r
966 \r
967 void MainFrame::OnFilter(wxCommandEvent&)\r
968 {\r
969         wxTreeEvent e;\r
970         e.SetItem(this->tree_ctrl->GetSelection());\r
971         this->OnTreeChanged(e);\r
972 }\r
973 \r
974 // イベントハンドラ以外。\r
975 \r
976 wxULongLong MainFrame::LoadTPI(wxString szFileName)\r
977 {\r
978         // TPIを読み込み。\r
979         wxFileSystem fs;\r
980         fs.ChangePathTo(L_DIR_B_LIB, true);\r
981         wxString szTPIName = fs.FindFirst(wxT("*" TPI_EXT), wxFILE);\r
982         wxULongLong llFileCount = 0;\r
983         while (! szTPIName.IsEmpty())\r
984         {\r
985                 // 対応確認。\r
986                 if (! tpi.InitLibrary(szTPIName, szFileName, 0) || ! tpi.CheckArchive(szFileName, & llFileCount) || llFileCount == 0)\r
987                 {\r
988                         tpi.FreeLibrary();\r
989                         szTPIName = fs.FindNext();\r
990                         continue;\r
991                 }\r
992                 break;\r
993         }\r
994         return llFileCount;\r
995 }\r
996 \r
997 int MainFrame::ErrorCheck(int nErrorCode)\r
998 {\r
999         switch (nErrorCode)\r
1000         {\r
1001         case TPI_ERROR_SUCCESS:\r
1002         case TPI_CALLBACK_CONTINUE:\r
1003                 break;\r
1004         case TPI_ERROR_D_UNSUPPORTED:\r
1005                 ::wxLogError(_("Sorry, this function is not supported yet."));\r
1006                 break;\r
1007         case TPI_ERROR_D_SKIPPED:\r
1008         case TPI_CALLBACK_CANCEL:\r
1009                 ::wxLogError(_("This operation is canceled by the user."));\r
1010                 break;\r
1011         default:\r
1012                 ::wxLogError(_("Error code: %d"), nErrorCode);\r
1013         }\r
1014         return nErrorCode;\r
1015 }\r