OSDN Git Service

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