OSDN Git Service

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