OSDN Git Service

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