OSDN Git Service

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