OSDN Git Service

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