OSDN Git Service

GetFileInformationがエラーを返したときにダイアログを表示するよう変更。
[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         // GetFileInformationがエラー終了した場合。\r
467         if (tpi.nErrorCode != TPI_ERROR_S_ENDOFDATA)\r
468         {\r
469                 ::wxLogError(_("Error: %s!"), wxT("GetFileInformation()"));\r
470         }\r
471 \r
472         // 書庫の情報を取得。\r
473         if (! tpi.GetArchiveInformation(& this->aiArchive))\r
474         {\r
475                 ::wxLogError(_("Error: %s!"), wxT("GetArchiveInformation()"));\r
476         }\r
477 \r
478         // 書庫を閉じる。\r
479         if (! tpi.CloseArchive())\r
480         {\r
481                 ::wxLogError(_("Error: %s!"), wxT("CloseArchive()"));\r
482         }\r
483 \r
484         // 以下、UI処理。\r
485         this->fileinfo.Shrink();\r
486         this->tree_ctrl->ExpandAll();\r
487         this->tree_ctrl->ScrollTo(idArchive);\r
488         this->tree_ctrl->SelectItem(idArchive);\r
489         this->list_ctrl->atDangerItem.SetTextColour(* wxRED);\r
490         this->list_ctrl->atEncryptedItem.SetTextColour(wxColour(wxT("forest green")));\r
491 \r
492         // ステータスバー設定。\r
493         this->statusbar->SetStatusText(this->aiArchive.fiInfo.szTypeName, 0);\r
494         this->statusbar->SetStatusText(wxString::Format(_("%d file(s)"), this->fileinfo.GetCount()), 1);\r
495         this->statusbar->SetStatusText(this->aiArchive.llUnpackedSize.ToString() + _(" B -> ") + this->aiArchive.llPackedSize.ToString() + _(" B"), 2);\r
496         this->statusbar->SetStatusText(wxString::Format(wxT("%3.1f%%"), this->aiArchive.wCompressRatio / 10.0), 3);\r
497         this->statusbar->SetStatusText(this->fnArchive.GetFullPath(), 4);\r
498 \r
499         // ツールバー・メニューバー設定。\r
500         SetMenuToolState("Arc_Close",   true);\r
501         SetMenuToolState("Arc_Add",     (this->aiArchive.fiInfo.llSupportedCommand & TPI_COMMAND_ADD)   == TPI_COMMAND_ADD   && this->aiArchive.fiInfo.fArchive);\r
502         SetMenuToolState("Arc_SFX",     (this->aiArchive.fiInfo.llSupportedCommand & TPI_COMMAND_SFX)    == TPI_COMMAND_SFX   && this->aiArchive.nSFXType == 0);\r
503         SetMenuToolState("Arc_UnSFX",   (this->aiArchive.fiInfo.llSupportedCommand & TPI_COMMAND_UNSFX)  == TPI_COMMAND_UNSFX && this->aiArchive.nSFXType != 0);\r
504         SetMenuToolState("Arc_Extract", (this->aiArchive.fiInfo.llSupportedCommand & TPI_COMMAND_EXTRACT)== TPI_COMMAND_EXTRACT);\r
505         SetMenuToolState("Arc_Delete",  (this->aiArchive.fiInfo.llSupportedCommand & TPI_COMMAND_DELETE) == TPI_COMMAND_DELETE && this->aiArchive.fiInfo.fArchive);\r
506         SetMenuToolState("Arc_Test",    (this->aiArchive.fiInfo.llSupportedCommand & TPI_COMMAND_TEST)   == TPI_COMMAND_TEST);\r
507         SetMenuToolState("Arc_Repair",  (this->aiArchive.fiInfo.llSupportedCommand & TPI_COMMAND_REPAIR) == TPI_COMMAND_REPAIR);\r
508 \r
509         procDlg.Show(false);\r
510 }\r
511 \r
512 void MainFrame::OnArcClose(wxCommandEvent&)\r
513 {\r
514         // ツリービュー・リストビュー設定。\r
515         this->tree_ctrl->DeleteAllItems();\r
516         this->list_ctrl->DeleteAllItems();\r
517         this->list_ctrl->showFileInfo.Clear();\r
518 \r
519         // ツールバー・メニューバー設定。\r
520         SetMenuToolState("Arc_Close",   false);\r
521         SetMenuToolState("Arc_Add",     false);\r
522         SetMenuToolState("Arc_SFX",     false);\r
523         SetMenuToolState("Arc_UnSFX",   false);\r
524         SetMenuToolState("Arc_Extract", false);\r
525         SetMenuToolState("Arc_Delete",  false);\r
526         SetMenuToolState("Arc_Test",    false);\r
527         SetMenuToolState("Arc_Repair",  false);\r
528 \r
529         for (int i = 0; i < this->statusbar->GetFieldsCount(); i++)\r
530         {\r
531                 this->statusbar->SetStatusText(wxEmptyString, i);\r
532         }\r
533         this->fileinfo.Clear();\r
534         this->aiArchive.szComment.Clear();\r
535         this->aiArchive.fnArchive.Clear();\r
536         this->aiArchive.fiInfo.szTypeName.Clear();\r
537         this->aiArchive.fiInfo.szSuffix.Clear();\r
538         this->aiArchive.fiInfo.szEngineName.Clear();\r
539         this->aiArchive.fiInfo.szTPIName.Clear();\r
540 \r
541         g_hIconT.RemoveAll();\r
542         g_hIconLL.RemoveAll();\r
543         g_hIconLS.RemoveAll();\r
544         this->tpi.FreeLibrary();\r
545 }\r
546 \r
547 void MainFrame::OnArcAdd(wxCommandEvent& e)\r
548 {\r
549         // 作成ダイアログを設定。\r
550         MakeDialog mkDlg;\r
551         ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));\r
552         ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));\r
553         mkDlg.uCommand = TPI_COMMAND_ADD;\r
554 \r
555         // 処理対象のファイルを選択。\r
556         wxFileDialog fd(this, _("Choose files to add"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0));\r
557         fd.SetWindowStyleFlag(wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);\r
558         if (fd.ShowModal() == wxID_CANCEL)\r
559         {\r
560                 return;\r
561         }\r
562         fd.GetFilenames(mkDlg.files);\r
563         this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());\r
564 \r
565         // ダイアログを表示。\r
566         mkDlg.InitDialog();\r
567         if (mkDlg.ShowModal() == wxID_CANCEL)\r
568         {\r
569                 return;\r
570         }\r
571 \r
572         // 各種設定。\r
573         TPI_SWITCHES swInfo;\r
574         swInfo.pCustomSwitches       = NULL;\r
575         swInfo.fMakeSFX              = false;\r
576         swInfo.fnDestinationDirectory= wxFileName::DirName(fd.GetDirectory());\r
577         swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();\r
578         swInfo.fSolid               = mkDlg.cbSolid->IsChecked();\r
579         swInfo.fMMOptimize          = mkDlg.cbMMOptimize->IsChecked();\r
580         swInfo.fEncryptHeader       = mkDlg.cbEncryptHeader->IsChecked();\r
581         swInfo.sCompressLevel       = mkDlg.scLevel->GetValue();\r
582         swInfo.sRecoveryRecord      = mkDlg.scRR->GetValue();\r
583         swInfo.szPassword           = mkDlg.tcPassword->GetValue();\r
584         swInfo.szKeyFile            = mkDlg.tcKeyfile->GetValue();\r
585         swInfo.szComment            = mkDlg.tcComment->GetValue();\r
586 \r
587         ProcessDialog procDlg;\r
588         procDlg.InitDialog();\r
589         procDlg.Show(true);\r
590         if (! this->tpi.Command(TPI_COMMAND_ADD, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))\r
591         {\r
592                 this->ErrorCheck(tpi.nErrorCode);\r
593         }\r
594         procDlg.Show(false);\r
595 \r
596         if (mkDlg.cbOpenAfter->IsChecked())\r
597         {\r
598                 // 作成先を開く。\r
599 #ifdef __WINDOWS__\r
600                 ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());\r
601 #endif\r
602         }\r
603 \r
604         if (mkDlg.cbExitAfter->IsChecked())\r
605         {\r
606                 // 終了。\r
607                 this->Close(true);\r
608         }\r
609 \r
610         // 終了しない場合は書庫を再読み込み。\r
611         this->OnArcOpen(e);\r
612 }\r
613 \r
614 void MainFrame::OnArcConvert(wxCommandEvent& e)\r
615 {\r
616         TPI_SWITCHES swInfo;\r
617         swInfo.fMakeSFX = e.GetId() == XRCID("Arc_SFX");\r
618 \r
619         // 保存先を尋ねる。\r
620         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
621         fd.SetWindowStyleFlag(wxFD_SAVE | wxFD_OVERWRITE_PROMPT);\r
622         if (fd.ShowModal() == wxID_CANCEL)\r
623         {\r
624                 return;\r
625         }\r
626         swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());\r
627         this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());\r
628 \r
629         wxArrayString files;\r
630         files.Add(fd.GetPath());\r
631 \r
632         ProcessDialog procDlg;\r
633         procDlg.InitDialog();\r
634         procDlg.Show(true);\r
635         if (! this->tpi.Command(swInfo.fMakeSFX ? TPI_COMMAND_SFX : TPI_COMMAND_UNSFX, & swInfo, this->fnArchive.GetFullPath(), files))\r
636         {\r
637                 this->ErrorCheck(tpi.nErrorCode);\r
638         }\r
639         procDlg.Show(false);\r
640 }\r
641 \r
642 void MainFrame::OnArcExtract(wxCommandEvent& e)\r
643 {\r
644         TPI_SWITCHES swInfo;\r
645         swInfo.pCustomSwitches = NULL;\r
646 \r
647         // モード取得。通常は0, 実行なら1, ファイルDnDなら2、ディレクトリDnDなら3。\r
648         int nMode = e.GetInt();\r
649         // 実行時のみ使用。\r
650         wxFileType * ftFile = NULL;\r
651 \r
652         // 展開ダイアログを作成。DnDまたは実行時は表示しない。\r
653         MakeDialog mkDlg;\r
654         ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_make.xrc"));\r
655         ::wxXmlResource::Get()->LoadDialog(& mkDlg, this, wxT("dlg_make"));\r
656         mkDlg.uCommand = TPI_COMMAND_EXTRACT;\r
657         mkDlg.files    = MakeTargetFileList(this, nMode == 1);\r
658 \r
659         if (nMode != 0)\r
660         {\r
661                 if (nMode == 1)\r
662                 {\r
663                         // コマンドを取得。\r
664                         ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(wxFileName(mkDlg.files[0]).GetExt());\r
665                         if (! ftFile)\r
666                         {\r
667                                 // 種類が取得できないときは設定を読み込む。初期設定ではテキストとみなす。\r
668                                 ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(this->conf.ReadId(CONF_DEFAULT_EXT, (wxString) wxT("txt")));\r
669                                 if (! ftFile)\r
670                                 {\r
671                                         ::wxLogError(_("Unable to get the file type!"));\r
672                                         return;\r
673                                 }\r
674                         }\r
675                 }\r
676 \r
677                 // 作業ディレクトリ作成。\r
678                 swInfo.fStoreDirectoryPathes = false;\r
679                 wxString szDestDirBase = nMode == 3 ? this->tree_ctrl->GetItemText(this->tree_ctrl->GetSelection()) : wxT("tpi_tmp");\r
680                 if (szDestDirBase == wxT("-----"))\r
681                 {\r
682                         // 書庫ルートのときは書庫名にしておく。\r
683                         szDestDirBase = this->fnArchive.GetName();\r
684                 }\r
685                 swInfo.fnDestinationDirectory = MakeDirPath(wxFileName::DirName(::wxGetCwd()), szDestDirBase, true);\r
686                 if (! swInfo.fnDestinationDirectory.IsOk())\r
687                 {\r
688                         ::wxLogError(_("Unable to make the temporary directory!"));\r
689                         return;\r
690                 }\r
691         }\r
692         else\r
693         {\r
694                 mkDlg.InitDialog();\r
695                 if (mkDlg.ShowModal() == wxID_CANCEL)\r
696                 {\r
697                         return;\r
698                 }\r
699 \r
700                 // 各種設定。\r
701                 swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();\r
702                 swInfo.fnDestinationDirectory = wxFileName::DirName(mkDlg.cbDir->GetValue());\r
703                 swInfo.szPassword = mkDlg.tcPassword->GetValue();\r
704                 swInfo.szKeyFile  = mkDlg.tcKeyfile->GetValue();\r
705 \r
706                 // 必要なら書庫名でディレクトリを作成する。\r
707                 if (WillMakeDirByArcName(this, & mkDlg))\r
708                 {\r
709                         swInfo.fnDestinationDirectory = MakeDirPath(swInfo.fnDestinationDirectory, this->fnArchive.GetName(), true);\r
710                         if (! swInfo.fnDestinationDirectory.IsOk())\r
711                         {\r
712                                 ::wxLogError(_("Unable to make the destination directory!"));\r
713                                 return;\r
714                         }\r
715                 }\r
716         }\r
717 \r
718         ProcessDialog procDlg;\r
719         procDlg.InitDialog();\r
720         procDlg.Show(true);\r
721         if (! this->tpi.Command(TPI_COMMAND_EXTRACT, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files))\r
722         {\r
723                 this->ErrorCheck(tpi.nErrorCode);\r
724         }\r
725         procDlg.Show(false);\r
726 \r
727         if (nMode == 0)\r
728         {\r
729                 if (mkDlg.cbOpenAfter->IsChecked())\r
730                 {\r
731                         // 展開先を開く。\r
732 #ifdef __WINDOWS__\r
733                         ::wxExecute(wxT("explorer ") + swInfo.fnDestinationDirectory.GetFullPath());\r
734 #endif\r
735                 }\r
736 \r
737                 if (mkDlg.cbExitAfter->IsChecked())\r
738                 {\r
739                         // 終了。\r
740                         this->Close(true);\r
741                 }\r
742         }\r
743         else\r
744         {\r
745                 wxArrayString asFiles;\r
746                 if (nMode == 1)\r
747                 {\r
748                         // コマンドを実行。\r
749                         asFiles.Add(swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[0]).GetFullName());\r
750                         if (tpi.nErrorCode == TPI_ERROR_SUCCESS)\r
751                         {\r
752 #ifdef __LINUX__\r
753                                 // Linuxでは引用符で囲む必要がある。\r
754                                 ::wxExecute(ftFile->GetOpenCommand(wxT('"') + asFiles[0] + wxT('"')), wxEXEC_SYNC);\r
755 #else\r
756                                 ::wxExecute(ftFile->GetOpenCommand(asFiles[0]), wxEXEC_SYNC);\r
757 #endif\r
758                         }\r
759                 }\r
760                 else\r
761                 {\r
762                         // 展開対象を決定。\r
763                         wxFileDataObject objFile;\r
764                         for (size_t i = 0; i < mkDlg.files.GetCount(); i++)\r
765                         {\r
766                                 wxString szFileName = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[i]).GetFullName();\r
767                                 if (nMode == 2)\r
768                                 {\r
769                                         // リストに追加。\r
770                                         objFile.AddFile(szFileName);\r
771                                 }\r
772                                 asFiles.Add(szFileName);\r
773                         }\r
774                         if (nMode == 3)\r
775                         {\r
776                                 objFile.AddFile(swInfo.fnDestinationDirectory.GetPath());\r
777                         }\r
778 \r
779                         // DnD開始。\r
780                         wxDropSource dropSource(objFile, this);\r
781                         if (dropSource.DoDragDrop() != wxDragMove)\r
782                         {\r
783 #ifdef __LINUX__\r
784                                 // Linuxではまだ処理が終わっていない(コンテキストメニューが表示されている)ので、とりあえず3秒だけ待つ。\r
785                                 sleep(3);\r
786 #endif\r
787                         }\r
788                 }\r
789 \r
790                 // ファイルと一時ディレクトリを削除。\r
791                 for (size_t i = 0; i < asFiles.GetCount(); i++)\r
792                 {\r
793                         ::wxRemoveFile(asFiles[i]);\r
794                 }\r
795                 ::wxRmdir(swInfo.fnDestinationDirectory.GetFullPath());\r
796         }\r
797 }\r
798 \r
799 void MainFrame::OnArcDelete(wxCommandEvent& e)\r
800 {\r
801         // 全ファイル削除は危険ではないかと。\r
802         if (this->list_ctrl->GetSelectedItemCount() == 0)\r
803         {\r
804                 return;\r
805         }\r
806 \r
807         if (::AskDlg(_("Are you sure to delete selected files?"), this) == wxNO)\r
808         {\r
809                 return;\r
810         }\r
811 \r
812         // 各種設定。\r
813         TPI_SWITCHES swInfo;\r
814         ProcessDialog procDlg;\r
815         procDlg.InitDialog();\r
816         procDlg.Show(true);\r
817         if (! this->tpi.Command(TPI_COMMAND_DELETE, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false)))\r
818         {\r
819                 this->ErrorCheck(tpi.nErrorCode);\r
820         }\r
821         procDlg.Show(false);    \r
822 \r
823         // 書庫を再読み込みする。\r
824         this->OnArcOpen(e);\r
825 }\r
826 \r
827 void MainFrame::OnArcTest(wxCommandEvent&)\r
828 {\r
829         TPI_SWITCHES swInfo;\r
830         ProcessDialog procDlg;\r
831         procDlg.InitDialog();\r
832         procDlg.Show(true);\r
833         bool bIsCorrect = this->tpi.Command(TPI_COMMAND_TEST, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false));\r
834         procDlg.Show(false);\r
835         if (bIsCorrect)\r
836         {\r
837                 ::wxLogMessage(_("This is a correct archive."));\r
838         }\r
839         else\r
840         {\r
841                 this->ErrorCheck(tpi.nErrorCode);\r
842         }\r
843 }\r
844 \r
845 void MainFrame::OnArcRepair(wxCommandEvent&)\r
846 {\r
847         TPI_SWITCHES swInfo;\r
848         ProcessDialog procDlg;\r
849         procDlg.InitDialog();\r
850         procDlg.Show(true);\r
851         if (! this->tpi.Command(TPI_COMMAND_REPAIR, & swInfo, this->fnArchive.GetFullPath(), MakeTargetFileList(this, false)))\r
852         {\r
853                 this->ErrorCheck(tpi.nErrorCode);\r
854         }\r
855         procDlg.Show(false);    \r
856 }\r
857 \r
858 void MainFrame::OnViewMode(wxCommandEvent & e)\r
859 {\r
860         int n = e.GetId();\r
861         this->menubar->Check(n, true);\r
862         this->list_ctrl->SetSingleStyle(wxLC_REPORT, n == XRCID("Exe_View_Details"));\r
863         this->list_ctrl->SetSingleStyle(wxLC_ICON,   n == XRCID("Exe_View_Icons"));\r
864         this->list_ctrl->SetSingleStyle(wxLC_LIST,   n == XRCID("Exe_View_List"));\r
865 }\r
866 \r
867 void MainFrame::OnShowToolBar(wxCommandEvent & e)\r
868 {\r
869         this->toolbar->Show(e.IsChecked());\r
870 }\r
871 \r
872 void MainFrame::OnShowStatusBar(wxCommandEvent & e)\r
873 {\r
874         this->statusbar->Show(e.IsChecked());\r
875 }\r
876 \r
877 void MainFrame::OnSelectAll(wxCommandEvent &)\r
878 {\r
879         for (int i = 0; i < this->list_ctrl->GetItemCount(); i++)\r
880         {\r
881                 this->list_ctrl->Select(i, true);\r
882         }\r
883 }\r
884 \r
885 // TreeView\r
886 \r
887 void MainFrame::OnTreeChanged(wxTreeEvent& e)\r
888 {\r
889         // ツリービューからパスを取得。\r
890         wxString szNodePath = TreeView_GetItemPath(this->tree_ctrl, e.GetItem());\r
891         // リストビューを初期化。\r
892         this->list_ctrl->showFileInfo.Clear();\r
893         this->list_ctrl->DeleteAllItems();\r
894         g_hIconLL.RemoveAll();\r
895         g_hIconLS.RemoveAll();\r
896 \r
897         // 現在のアイテムの選択状態を無効にしておく。\r
898         long nSelected = this->list_ctrl->GetFirstSelected();\r
899         while (nSelected != -1)\r
900         {\r
901                 this->list_ctrl->Select(nSelected, false);\r
902                 nSelected = this->list_ctrl->GetNextSelected(nSelected);\r
903         }\r
904 \r
905         // アイコン設定。\r
906         this->list_ctrl->SetImageList(& g_hIconLL, wxIMAGE_LIST_NORMAL);\r
907         this->list_ctrl->SetImageList(& g_hIconLS, wxIMAGE_LIST_SMALL);\r
908 \r
909         // 配列と比較し、パスが一致しなければ消す。\r
910         for (size_t i = 0; i < this->fileinfo.GetCount(); i++)\r
911         {\r
912                 // パスを比較。\r
913                 if (szNodePath == wxT("*") || szNodePath == this->fileinfo[i].fnFileName.GetPath())\r
914                 {\r
915                         // 項目がフォルダであるなら無視。\r
916                         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
917                         {\r
918                                 continue;\r
919                         }\r
920 \r
921                         // フィルタにかからなければ無視。\r
922                         if (this->fileinfo[i].fnFileName.GetFullName().MakeLower().Find(this->tcFilter->GetValue().MakeLower()) == wxNOT_FOUND)\r
923                         {\r
924                                 continue;\r
925                         }\r
926 \r
927                         this->list_ctrl->showFileInfo.Add(this->fileinfo[i]);\r
928                 }\r
929         }\r
930 \r
931         // ソートして表示。\r
932         this->list_ctrl->showFileInfo.Sort(& ListCtrlCompareProc);\r
933         this->list_ctrl->SetItemCount(this->list_ctrl->showFileInfo.GetCount());\r
934 }\r
935 \r
936 void MainFrame::OnTreeBeginDrag(wxTreeEvent& e)\r
937 {\r
938         // TODO : アイテムが子階層を持っていても展開できない。\r
939         this->tree_ctrl->SelectItem(e.GetItem());\r
940 \r
941         wxCommandEvent e1;\r
942         e1.SetInt(3);\r
943         this->OnArcExtract(e1);\r
944 }\r
945 \r
946 // ListView\r
947 \r
948 void MainFrame::OnListItemDClick(wxListEvent&)\r
949 {\r
950         wxCommandEvent e;\r
951         e.SetInt(1);\r
952         this->OnArcExtract(e);\r
953 }\r
954 \r
955 void MainFrame::OnListBeginDrag(wxListEvent&)\r
956 {\r
957         if (this->list_ctrl->GetSelectedItemCount() == 0)\r
958         {\r
959                 // アイテムを選択せずドラッグしようとした場合。\r
960                 return;\r
961         }\r
962 \r
963         wxCommandEvent e;\r
964         e.SetInt(2);\r
965         this->OnArcExtract(e);\r
966 }\r
967 \r
968 // Filter\r
969 \r
970 void MainFrame::OnFilter(wxCommandEvent&)\r
971 {\r
972         wxTreeEvent e;\r
973         e.SetItem(this->tree_ctrl->GetSelection());\r
974         this->OnTreeChanged(e);\r
975 }\r
976 \r
977 // イベントハンドラ以外。\r
978 \r
979 wxULongLong MainFrame::LoadTPI(wxString szFileName)\r
980 {\r
981         // TPIを読み込み。\r
982         wxFileSystem fs;\r
983         fs.ChangePathTo(L_DIR_B_LIB, true);\r
984         wxString szTPIName = fs.FindFirst(wxT("*" TPI_EXT), wxFILE);\r
985         wxULongLong llFileCount = 0;\r
986         while (! szTPIName.IsEmpty())\r
987         {\r
988                 // 対応確認。\r
989                 if (! tpi.InitLibrary(szTPIName, szFileName, 0) || ! tpi.CheckArchive(szFileName, & llFileCount) || llFileCount == 0)\r
990                 {\r
991                         tpi.FreeLibrary();\r
992                         szTPIName = fs.FindNext();\r
993                         continue;\r
994                 }\r
995                 break;\r
996         }\r
997         return llFileCount;\r
998 }\r
999 \r
1000 int MainFrame::ErrorCheck(int nErrorCode)\r
1001 {\r
1002         switch (nErrorCode)\r
1003         {\r
1004         case TPI_ERROR_SUCCESS:\r
1005         case TPI_CALLBACK_CONTINUE:\r
1006                 break;\r
1007         case TPI_ERROR_D_UNSUPPORTED:\r
1008                 ::wxLogError(_("Sorry, this function is not supported yet."));\r
1009                 break;\r
1010         case TPI_ERROR_D_SKIPPED:\r
1011         case TPI_CALLBACK_CANCEL:\r
1012                 ::wxLogError(_("This operation is canceled by the user."));\r
1013                 break;\r
1014         default:\r
1015                 ::wxLogError(_("Error code: %d"), nErrorCode);\r
1016         }\r
1017         return nErrorCode;\r
1018 }\r