1 /*******************************************************************************
\r
2 TPI - flexible but useless plug-in framework.
\r
3 Copyright (C) 2002-2009 Silky
\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
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
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
20 *******************************************************************************/
\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
30 #include <wx/arrimpl.cpp>
\r
32 WX_DEFINE_OBJARRAY(ArrayTPI_FILEINFO);
\r
34 #define SetMenuToolState(id, state) this->toolbar->EnableTool(XRCID(id), state); this->menubar->Enable(XRCID(id), state)
\r
36 //******************************************************************************
\r
38 //******************************************************************************
\r
40 wxImageList g_hIconT(16, 16), g_hIconLL(32, 32), g_hIconLS(16, 16);
\r
44 //******************************************************************************
\r
46 //******************************************************************************
\r
48 MainFrame::MainFrame(): wxFrame()
\r
52 MainFrame::~MainFrame()
\r
55 if (! this->IsIconized() && ! this->IsMaximized())
\r
58 this->GetSize(& a, & b);
\r
59 this->conf.WriteId(CONF_WINDOW_WIDTH, a);
\r
60 this->conf.WriteId(CONF_WINDOW_HEIGHT, b);
\r
61 this->GetPosition(& a, & b);
\r
62 this->conf.WriteId(CONF_WINDOW_X, a);
\r
63 this->conf.WriteId(CONF_WINDOW_Y, b);
\r
65 this->conf.WriteId(CONF_WINDOW_SPLITTER_POS, this->window_splitter->GetSashPosition());
\r
68 this->conf.WriteId(CONF_WINDOW_STATUSBAR, this->statusbar->IsShown());
\r
69 this->conf.WriteId(CONF_WINDOW_TOOLBAR, this->toolbar->IsShown());
\r
72 this->conf.WriteId(CONF_LISTVIEW_SHOWMODE, this->menubar->IsChecked(XRCID("Exe_View_Icons")) ? 1 : this->menubar->IsChecked(XRCID("Exe_View_List")) ? 2 : 0);
\r
73 if (this->menubar->IsChecked(XRCID("Exe_View_Details")))
\r
75 this->conf.WriteId(CONF_LISTVIEW_C_FILENAME, this->list_ctrl->GetColumnWidth(0));
\r
76 this->conf.WriteId(CONF_LISTVIEW_C_UNPACKED, this->list_ctrl->GetColumnWidth(1));
\r
77 this->conf.WriteId(CONF_LISTVIEW_C_PACKED, this->list_ctrl->GetColumnWidth(2));
\r
78 this->conf.WriteId(CONF_LISTVIEW_C_RATIO, this->list_ctrl->GetColumnWidth(3));
\r
79 this->conf.WriteId(CONF_LISTVIEW_C_METHOD, this->list_ctrl->GetColumnWidth(4));
\r
80 this->conf.WriteId(CONF_LISTVIEW_C_ATTR, this->list_ctrl->GetColumnWidth(5));
\r
81 this->conf.WriteId(CONF_LISTVIEW_C_LASTMOD, this->list_ctrl->GetColumnWidth(6));
\r
82 this->conf.WriteId(CONF_LISTVIEW_C_PATH, this->list_ctrl->GetColumnWidth(7));
\r
83 this->conf.WriteId(CONF_LISTVIEW_C_TYPE, this->list_ctrl->GetColumnWidth(8));
\r
84 this->conf.WriteId(CONF_LISTVIEW_C_NO, this->list_ctrl->GetColumnWidth(9));
\r
85 this->conf.WriteId(CONF_LISTVIEW_C_COMMENT, this->list_ctrl->GetColumnWidth(10));
\r
86 this->conf.WriteId(CONF_LISTVIEW_S_COLUMN, g_nSortColumn);
\r
87 this->conf.WriteId(CONF_LISTVIEW_S_ASCEND, g_fSortAscend);
\r
92 this->OnArcClose(e);
\r
95 //******************************************************************************
\r
97 //******************************************************************************
\r
99 BEGIN_EVENT_TABLE(MainFrame, wxFrame)
\r
100 EVT_INIT_DIALOG( MainFrame::OnInit)
\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_Clone"), MainFrame::OnArcClone)
\r
106 EVT_MENU(XRCID("Arc_Add"), MainFrame::OnArcAdd)
\r
107 EVT_MENU(XRCID("Arc_SFX"), MainFrame::OnArcConvert)
\r
108 EVT_MENU(XRCID("Arc_UnSFX"), MainFrame::OnArcConvert)
\r
109 EVT_MENU(XRCID("Exe_Exit"), MainFrame::OnExit)
\r
110 EVT_MENU(XRCID("Arc_Extract"), MainFrame::OnArcExtract)
\r
111 EVT_MENU(XRCID("Arc_Delete"), MainFrame::OnArcDelete)
\r
112 EVT_MENU(XRCID("Arc_Test"), MainFrame::OnArcTest)
\r
113 EVT_MENU(XRCID("Arc_Repair"), MainFrame::OnArcRepair)
\r
114 EVT_MENU(XRCID("Exe_Copy"), MainFrame::OnExeCopy)
\r
115 EVT_MENU(XRCID("Exe_View_Icons"), MainFrame::OnViewMode)
\r
116 EVT_MENU(XRCID("Exe_View_Details"),MainFrame::OnViewMode)
\r
117 EVT_MENU(XRCID("Exe_View_List"), MainFrame::OnViewMode)
\r
118 EVT_MENU(XRCID("Exe_View_ToolBar"),MainFrame::OnShowToolBar)
\r
119 EVT_MENU(XRCID("Exe_View_StatusBar"),MainFrame::OnShowStatusBar)
\r
120 EVT_MENU(XRCID("Exe_View_SelectAll"),MainFrame::OnSelectAll)
\r
122 EVT_TREE_SEL_CHANGED(XRCID("TreeView"), MainFrame::OnTreeChanged)
\r
123 EVT_TREE_BEGIN_DRAG( XRCID("TreeView"), MainFrame::OnTreeBeginDrag)
\r
124 EVT_COMMAND_CONTEXT_MENU(XRCID("TreeView"), MainFrame::OnContextMenu)
\r
126 EVT_LIST_ITEM_SELECTED( XRCID("ListView"), MainFrame::OnListItemSelect)
\r
127 EVT_LIST_ITEM_DESELECTED(XRCID("ListView"), MainFrame::OnListItemSelect)
\r
128 EVT_LIST_ITEM_ACTIVATED( XRCID("ListView"), MainFrame::OnListItemDClick)
\r
129 EVT_LIST_BEGIN_DRAG( XRCID("ListView"), MainFrame::OnListBeginDrag)
\r
130 EVT_COMMAND_CONTEXT_MENU(XRCID("ListView"), MainFrame::OnContextMenu)
\r
132 EVT_TEXT(XRCID("tcFilter"), MainFrame::OnFilter)
\r
135 //******************************************************************************
\r
137 //******************************************************************************
\r
139 void MainFrame::OnInit(wxInitDialogEvent&)
\r
142 this->menubar = this->GetMenuBar();
\r
143 this->toolbar = this->GetToolBar();
\r
144 this->statusbar = XRCCTRL(* this, "statusbar", wxStatusBar);
\r
145 this->tree_ctrl = XRCCTRL(* this, "TreeView", wxTreeCtrl);
\r
146 this->list_ctrl = XRCCTRL(* this, "ListView", myListCtrl);
\r
147 this->window_splitter = XRCCTRL(* this, "window_splitter", wxSplitterWindow);
\r
148 this->tcFilter = XRCCTRL(* this->toolbar, "tcFilter", wxTextCtrl);
\r
151 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
152 wxTheMimeTypesManager->Initialize(wxMAILCAP_ALL);
\r
157 icon.CopyFromBitmap(wxBitmap(L_DIR_S_ICO wxT("app.png"), wxBITMAP_TYPE_ANY));
\r
158 this->SetIcon(icon);
\r
161 this->OnArcClose(e);
\r
162 this->SetDropTarget(new myFileDropTarget(this));
\r
165 this->window_splitter->SetSashPosition(this->conf.ReadId(CONF_WINDOW_SPLITTER_POS, 200l));
\r
168 int nIconMode = this->conf.ReadId(CONF_LISTVIEW_SHOWMODE, 0l);
\r
169 e.SetId(nIconMode == 1 ? XRCID("Exe_View_Icons") : (nIconMode == 2 ? XRCID("Exe_View_List") : XRCID("Exe_View_Details")));
\r
170 this->OnViewMode(e);
\r
171 // wxGTKでは直接wxLC_VIRTUALを指定しないと反映されない。
\r
172 this->list_ctrl->SetSingleStyle(wxLC_VIRTUAL);
\r
173 this->list_ctrl->InsertColumn(0, _("Filename"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_FILENAME, 140l));
\r
174 this->list_ctrl->InsertColumn(1, _("Unpacked"), wxLIST_FORMAT_RIGHT, this->conf.ReadId(CONF_LISTVIEW_C_UNPACKED, 80l));
\r
175 this->list_ctrl->InsertColumn(2, _("Packed"), wxLIST_FORMAT_RIGHT, this->conf.ReadId(CONF_LISTVIEW_C_PACKED, 80l));
\r
176 this->list_ctrl->InsertColumn(3, _("Ratio"), wxLIST_FORMAT_RIGHT, this->conf.ReadId(CONF_LISTVIEW_C_RATIO, 50l));
\r
177 this->list_ctrl->InsertColumn(4, _("Method"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_METHOD, 60l));
\r
178 this->list_ctrl->InsertColumn(5, _("Attr"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_ATTR, 50l));
\r
179 this->list_ctrl->InsertColumn(6, _("Last modified"), wxLIST_FORMAT_RIGHT, this->conf.ReadId(CONF_LISTVIEW_C_LASTMOD, 150l));
\r
180 this->list_ctrl->InsertColumn(7, _("Path"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_PATH, 100l));
\r
181 this->list_ctrl->InsertColumn(8, _("Type"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_TYPE, 100l));
\r
182 this->list_ctrl->InsertColumn(9, _("No."), wxLIST_FORMAT_RIGHT, this->conf.ReadId(CONF_LISTVIEW_C_NO, 35l));
\r
183 this->list_ctrl->InsertColumn(10,_("Comment"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_COMMENT, 35l));
\r
184 g_nSortColumn = this->conf.ReadId(CONF_LISTVIEW_S_COLUMN, 9l);
\r
185 g_fSortAscend = this->conf.ReadId(CONF_LISTVIEW_S_ASCEND, true);
\r
187 // ツールバー/ステータスバー設定。
\r
188 int nStatusBarParts[] = {70, 70, 180, 50, -1};
\r
189 this->statusbar->SetFieldsCount(5, nStatusBarParts);
\r
190 this->SetStatusBarPane(-1);
\r
191 bool fShow = this->conf.ReadId(CONF_WINDOW_STATUSBAR, true);
\r
192 this->menubar->Check(XRCID("Exe_View_StatusBar"), fShow);
\r
193 this->statusbar->Show(fShow);
\r
194 fShow = this->conf.ReadId(CONF_WINDOW_TOOLBAR, true);
\r
195 this->menubar->Check(XRCID("Exe_View_ToolBar"), fShow);
\r
196 this->toolbar->Show(fShow);
\r
201 void MainFrame::OnExit(wxCommandEvent&)
\r
206 void MainFrame::OnArcCreate(wxCommandEvent& e)
\r
208 TPI_SWITCHES swInfo;
\r
209 swInfo.pCustomSwitches = NULL;
\r
212 MakeDialog mkDlg(this, TPI_COMMAND_CREATE);
\r
213 if (e.GetClientData() == NULL)
\r
216 wxFileDialog fd(this, _("Choose files to compress"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0), wxEmptyString, wxFileSelectorDefaultWildcardStr, wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
\r
217 if (fd.ShowModal() == wxID_CANCEL)
\r
221 swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
\r
222 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
223 fd.GetFilenames(mkDlg.files);
\r
227 mkDlg.files = * (wxArrayString *) e.GetClientData();
\r
228 swInfo.fnDestinationDirectory = wxFileName::DirName(wxFileName(mkDlg.files[0]).GetPath());
\r
230 for (size_t n = 0; n < mkDlg.files.GetCount(); n++)
\r
232 wxFileName fn(mkDlg.files[n]);
\r
233 fn.MakeRelativeTo(swInfo.fnDestinationDirectory.GetPath());
\r
234 mkDlg.files[n] = fn.GetFullPath();
\r
238 this->OnArcClose(e);
\r
239 // 書庫名はファイル名の拡張子より前、もしくはディレクトリ名。
\r
240 this->fnArchive = wxFileName(mkDlg.files[0]);
\r
241 this->fnArchive.SetName(mkDlg.files.GetCount() == 1 ? (this->fnArchive.GetName().IsEmpty() ? this->fnArchive.GetDirs().Last() : this->fnArchive.GetName()) : swInfo.fnDestinationDirectory.GetDirs().Last());
\r
242 this->fnArchive.SetEmptyExt();
\r
243 this->fnArchive.SetPath(swInfo.fnDestinationDirectory.GetPath());
\r
246 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
252 int nSelected = mkDlg.chType->GetSelection();
\r
253 swInfo.nArchiveType = mkDlg.afInfo[nSelected].nTypeId;
\r
254 swInfo.fStoreDirectoryPathes= ! mkDlg.cbIgnorePath->IsChecked();
\r
255 swInfo.fMakeSFX = mkDlg.cbMakeSFX->IsChecked();
\r
256 swInfo.fSolid = mkDlg.cbSolid->IsChecked();
\r
257 swInfo.fMMOptimize = mkDlg.cbMMOptimize->IsChecked();
\r
258 swInfo.fEncryptHeader = mkDlg.cbEncryptHeader->IsChecked();
\r
259 swInfo.fCompressHeader = mkDlg.cbCompressHeader->IsChecked();
\r
260 swInfo.nCompressLevel = mkDlg.scLevel->GetValue();
\r
261 swInfo.nRecoveryRecord = mkDlg.scRR->GetValue();
\r
262 swInfo.szPassword = mkDlg.tcPassword->GetValue();
\r
263 swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
\r
264 swInfo.szComment = mkDlg.tcComment->GetValue();
\r
265 mkDlg.cbSplitSize->GetValue().ToULongLong(& swInfo.nSplitSize);
\r
268 this->fnArchive = wxFileName(mkDlg.cbDir->GetValue(), mkDlg.cbFileName->GetValue());
\r
269 if (! tpi.InitLibrary(mkDlg.afInfo[nSelected].szTPIName, this->fnArchive.GetFullPath(), TPICallbackProc, mkDlg.afInfo[nSelected].nTypeId))
\r
271 this->ErrorCheck(tpi.nErrorCode, wxT("InitLibrary"));
\r
277 ProcessDialog procDlg(this, mkDlg.files.GetCount());
\r
278 procDlg.Show(true);
\r
280 tpi.Command(TPI_COMMAND_CREATE, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files);
\r
281 this->ErrorCheck(tpi.nErrorCode);
\r
282 procDlg.Show(false);
\r
286 if (mkDlg.cbOpenAfter->IsChecked())
\r
289 ::wxExecute(DIR_APP + QuoteString(swInfo.fnDestinationDirectory.GetFullPath()));
\r
292 if (mkDlg.cbExitAfter->IsChecked())
\r
299 this->OnArcOpen(e);
\r
302 void MainFrame::OnArcOpen(wxCommandEvent& e)
\r
304 // モード取得。通常は0, それ以外で開く場合は1, ファイルDnDなら2。
\r
305 int nMode = e.GetInt() == 2 ? 2 : e.GetId() == XRCID("Arc_Open") ? 0 : 1;
\r
310 wxFileDialog fd(this, _("Choose an archive"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0), wxEmptyString, wxFileSelectorDefaultWildcardStr, wxFD_OPEN | wxFD_FILE_MUST_EXIST);
\r
311 if (fd.ShowModal() == wxID_CANCEL)
\r
315 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
316 this->fnArchive = wxFileName(fd.GetPath());
\r
320 ProcessDialog procDlg(this);
\r
321 procDlg.Show(true);
\r
323 // DnD以外で書庫を開く場合、TPIを読み込み。
\r
324 TPI_PROCESSINFO piInfo;
\r
325 piInfo.fiInfo.nUnpackedSize = 0;
\r
326 if (! this->LoadTPI(this->fnArchive.GetFullPath(), & piInfo.fiInfo.nUnpackedSize))
\r
328 procDlg.Show(false);
\r
332 this->OnArcCreate(e);
\r
334 else if (this->IsShown())
\r
337 this->statusbar->SetStatusText(_("No plug-in supporting this archive was found!"), 4);
\r
341 wxLogError(_("No plug-in supporting this archive was found!"));
\r
347 piInfo.eMessage = TPI_MESSAGE_STATUS;
\r
348 piInfo.eStatus = 0x1001;
\r
349 if (this->ErrorCheck(procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo), wxT("Callback")) == TPI_CALLBACK_CANCEL)
\r
351 procDlg.Show(false);
\r
352 tpi.CloseArchive();
\r
354 this->OnArcClose(e);
\r
359 this->fileinfo.Alloc(piInfo.fiInfo.nUnpackedSize);
\r
362 this->conf.WriteHistory(CONF_HISTORY_PATH, this->fnArchive.GetPath());
\r
363 this->conf.WriteHistory(CONF_HISTORY_NAME, this->fnArchive.GetFullName());
\r
364 this->conf.WriteHistory(CONF_HISTORY_FULL, this->fnArchive.GetFullPath());
\r
366 // 書庫のアイコンを取得し、書庫ルートを作成。
\r
367 g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_closed.png"), wxBITMAP_TYPE_ANY));
\r
368 g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_open.png"), wxBITMAP_TYPE_ANY));
\r
369 this->tree_ctrl->SetImageList(& g_hIconT);
\r
371 idRoot = this->tree_ctrl->AddRoot(wxEmptyString),
\r
373 idArchive = this->tree_ctrl->AppendItem(idRoot, this->fnArchive.GetFullName(), g_hIconT.Add(GetFileTypeIcon(this->fnArchive))),
\r
375 idArchive = this->tree_ctrl->AppendItem(idRoot, this->fnArchive.GetFullName(), g_hIconT.Add(GetFileTypeIcon(this->fnArchive).ConvertToImage().Rescale(16, 16))),
\r
377 idArcRoot = this->tree_ctrl->AppendItem(idRoot, wxT("-----"), 0, 1);
\r
379 // 巨大書庫のときにファイル名検査を省略するか。
\r
380 bool bDTVCheck = piInfo.fiInfo.nUnpackedSize < 10000 || ::AskDlg(_("This archive contains so many files that it takes long to check Directory Traversal Vulnerability(DTV) problem. If you are sure this archive is safe, you can skip this scanning process. Do you want to scan for DTV problem?"), this) == wxNO;
\r
383 if (tpi.GetFileInformation(& piInfo.fiInfo, true))
\r
385 piInfo.eStatus = 0x1002;
\r
386 piInfo.nProcessedSize = 0;
\r
389 piInfo.nProcessedSize++;
\r
390 if (this->ErrorCheck(procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo), wxT("Callback")) == TPI_CALLBACK_CANCEL)
\r
392 procDlg.Show(false);
\r
393 tpi.CloseArchive();
\r
395 this->OnArcClose(e);
\r
400 if (piInfo.fiInfo.szStoredName.IsEmpty())
\r
402 piInfo.fiInfo.szStoredName = this->fnArchive.GetName();
\r
403 if (piInfo.fiInfo.fnFileName.HasExt())
\r
405 piInfo.fiInfo.szStoredName += wxT('.') + piInfo.fiInfo.fnFileName.GetExt();
\r
407 piInfo.fiInfo.fnFileName = wxFileName(piInfo.fiInfo.szStoredName);
\r
412 wxString szPath = piInfo.fiInfo.fnFileName.GetPathWithSep(wxPATH_UNIX);
\r
413 if (szPath.StartsWith(wxT("/")) || szPath.StartsWith(wxT("./")))
\r
415 piInfo.fiInfo.fnFileName = wxFileName(szPath.AfterFirst(wxT('/')), piInfo.fiInfo.fnFileName.GetFullName(), wxPATH_DOS);
\r
418 if (piInfo.fiInfo.fnFileName.GetFullPath().IsEmpty() || piInfo.fiInfo.fnFileName.GetFullPath() == wxT("."))
\r
424 if (piInfo.fiInfo.szStoredName.Find(wxT('\r')) != wxNOT_FOUND
\r
425 || piInfo.fiInfo.szStoredName.Find(wxT('\n')) != wxNOT_FOUND
\r
426 || piInfo.fiInfo.szStoredName.Find(wxT('\t')) != wxNOT_FOUND)
\r
428 wxString sz = piInfo.fiInfo.fnFileName.GetFullPath();
\r
429 sz.Replace(wxT("\r"), wxT(" "));
\r
430 sz.Replace(wxT("\n"), wxT(" "));
\r
431 sz.Replace(wxT("\t"), wxT(" "));
\r
432 piInfo.fiInfo.eDanger = TRUE;
\r
433 piInfo.fiInfo.fnFileName = wxFileName(sz);
\r
434 wxLogWarning(_("This archive may contain files whose name contains some special characters like CR(\\r), LF(\\n), Tab(\\t) and some problem would be happen if you extract these files. Don\'t extract these files carelessly.\nDanger file is:\n%s"), piInfo.fiInfo.fnFileName.GetFullPath().c_str());
\r
440 if (piInfo.fiInfo.fnFileName.GetPathWithSep(wxPATH_UNIX).Find(wxT("../")) != wxNOT_FOUND)
\r
442 piInfo.fiInfo.eDanger = TRUE;
\r
443 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
445 // 空白の連続による拡張子偽装を検査。
\r
446 if (piInfo.fiInfo.fnFileName.GetFullName().Find(wxT(" ")) != wxNOT_FOUND)
\r
448 piInfo.fiInfo.eDanger = TRUE;
\r
449 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
452 for (wxChar c = 0x200c; c <= 0x206f; c++)
\r
454 if (piInfo.fiInfo.fnFileName.GetFullName().Find(c) != wxNOT_FOUND)
\r
456 piInfo.fiInfo.eDanger = TRUE;
\r
457 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
461 case 0x200f: c = 0x2027; break;
\r
462 case 0x202e: c = 0x2060; break;
\r
468 bool fDir = piInfo.fiInfo.dwAttribute & TPI_ATTRIBUTE_DIRECTORY ? true : false;
\r
469 TreeView_CheckNewerItem(this->tree_ctrl, idArcRoot, fDir ? piInfo.fiInfo.fnFileName.GetFullPath() : piInfo.fiInfo.fnFileName.GetPath(), true);
\r
471 // ディレクトリ属性を含むものについては情報を保存しない。
\r
478 this->fileinfo.Add(piInfo.fiInfo);
\r
480 while (tpi.GetFileInformation(& piInfo.fiInfo));
\r
483 // GetFileInformationがエラー終了した場合。
\r
484 this->ErrorCheck(tpi.nErrorCode, wxT("GetFileInformation"));
\r
487 tpi.GetArchiveInformation(& this->aiArchive);
\r
488 this->ErrorCheck(tpi.nErrorCode, wxT("GetArchiveInformation"));
\r
489 this->szPassword = procDlg.szPassword;
\r
492 tpi.CloseArchive();
\r
493 this->ErrorCheck(tpi.nErrorCode, wxT("CloseArchive"));
\r
496 this->fileinfo.Shrink();
\r
497 this->tree_ctrl->Freeze();
\r
498 if (this->fileinfo.Count() < 10000)
\r
500 this->tree_ctrl->ExpandAll();
\r
501 this->tree_ctrl->SelectItem(idArchive);
\r
505 // ファイル数が多いとソートに時間がかかるので、書庫のルートを表示させる。
\r
506 this->tree_ctrl->Expand(idArcRoot);
\r
507 this->tree_ctrl->SelectItem(idArcRoot);
\r
510 this->tree_ctrl->ScrollTo(idArchive);
\r
511 this->tree_ctrl->SetScrollPos(wxHORIZONTAL, 0);
\r
512 this->tree_ctrl->Thaw();
\r
513 this->list_ctrl->atDangerItem.SetTextColour(* wxRED);
\r
514 this->list_ctrl->atEncryptedItem.SetTextColour(wxColour(wxT("forest green")));
\r
517 this->statusbar->SetStatusText(this->aiArchive.fiInfo.szTypeName, 0);
\r
518 this->statusbar->SetStatusText(wxString::Format(_("%u file(s)"), this->fileinfo.GetCount()), 1);
\r
519 this->statusbar->SetStatusText(wxString::Format(wxString("%" wxLongLongFmtSpec "uB -> %" wxLongLongFmtSpec "uB"), this->aiArchive.nUnpackedSize, this->aiArchive.nPackedSize), 2);
\r
520 this->statusbar->SetStatusText(wxString::Format(wxT("%3.1f%%"), this->aiArchive.wCompressRatio / 10.0), 3);
\r
521 this->statusbar->SetStatusText(this->fnArchive.GetFullPath(), 4);
\r
522 this->statusbar->SetToolTip(
\r
524 _("%s(%s)\nTPI: %s(%s)\nAccess: %s\nModify: %s\nCreate: %s\nComment:\n%s"),
\r
525 this->fnArchive.GetFullName().c_str(), this->aiArchive.fiInfo.szTypeName.c_str(),
\r
526 this->aiArchive.fiInfo.szTPIName.c_str(), this->aiArchive.fiInfo.szEngineName.c_str(),
\r
527 this->aiArchive.tmAccess.Format(_("%Y/%m/%d %H:%M:%S")).c_str(),
\r
528 this->aiArchive.tmModify.Format(_("%Y/%m/%d %H:%M:%S")).c_str(),
\r
529 this->aiArchive.tmCreate.Format(_("%Y/%m/%d %H:%M:%S")).c_str(),
\r
530 this->aiArchive.szComment.c_str()
\r
534 // ツールバー・メニューバー設定。ファイル選択時しか動作しない削除などは別に設定。
\r
535 SetMenuToolState("Arc_Close", true);
\r
536 SetMenuToolState("Arc_Add", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_ADD) == TPI_COMMAND_ADD && this->aiArchive.fiInfo.fArchive);
\r
537 SetMenuToolState("Arc_SFX", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_SFX) == TPI_COMMAND_SFX && ! this->aiArchive.fSFX);
\r
538 SetMenuToolState("Arc_UnSFX", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_UNSFX) == TPI_COMMAND_UNSFX && this->aiArchive.fSFX);
\r
539 SetMenuToolState("Arc_Extract", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_EXTRACT)== TPI_COMMAND_EXTRACT);
\r
540 SetMenuToolState("Arc_Test", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_TEST) == TPI_COMMAND_TEST);
\r
541 SetMenuToolState("Arc_Repair", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_REPAIR) == TPI_COMMAND_REPAIR);
\r
542 this->menubar->Enable(XRCID("Arc_Clone"), true);
\r
544 procDlg.Show(false);
\r
548 void MainFrame::OnArcClose(wxCommandEvent& e)
\r
550 // ツリービュー・リストビュー設定。
\r
551 this->tree_ctrl->DeleteAllItems();
\r
552 this->list_ctrl->DeleteAllItems();
\r
553 this->list_ctrl->apShowFile.Clear();
\r
556 SetMenuToolState("Arc_Close", false);
\r
557 SetMenuToolState("Arc_Add", false);
\r
558 SetMenuToolState("Arc_SFX", false);
\r
559 SetMenuToolState("Arc_UnSFX", false);
\r
560 SetMenuToolState("Arc_Extract", false);
\r
561 SetMenuToolState("Arc_Delete", false);
\r
562 SetMenuToolState("Arc_Test", false);
\r
563 SetMenuToolState("Arc_Repair", false);
\r
564 this->menubar->Enable(XRCID("Arc_Clone"), false);
\r
566 for (int i = 0; i < this->statusbar->GetFieldsCount(); i++)
\r
568 this->statusbar->SetStatusText(wxEmptyString, i);
\r
570 this->statusbar->SetToolTip(wxEmptyString);
\r
571 this->fileinfo.Clear();
\r
572 this->szPassword.Empty();
\r
573 this->aiArchive.szComment.Empty();
\r
574 this->aiArchive.fnArchive.Clear();
\r
575 this->aiArchive.fiInfo.szTypeName.Empty();
\r
576 this->aiArchive.fiInfo.szSuffix.Empty();
\r
577 this->aiArchive.fiInfo.szEngineName.Empty();
\r
578 this->aiArchive.fiInfo.szTPIName.Empty();
\r
580 g_hIconT.RemoveAll();
\r
581 g_hIconLL.RemoveAll();
\r
582 g_hIconLS.RemoveAll();
\r
584 // DnDで書庫を開くときは既に読み込まれているTPIを用いるので、解放してはいけない。
\r
585 if (e.GetExtraLong() == 0)
\r
591 void MainFrame::OnArcClone(wxCommandEvent&)
\r
594 wxFileDialog fd(this, _("Clone archive"), this->fnArchive.GetPath(), this->fnArchive.GetFullName(), wxFileSelectorDefaultWildcardStr, wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
\r
595 if (fd.ShowModal() == wxID_CANCEL)
\r
599 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
602 ::wxCopyFile(this->fnArchive.GetFullPath(), fd.GetPath());
\r
603 wxFileName fn(fd.GetPath());
\r
604 wxDateTime dtAccess, dtModify, dtCreate;
\r
605 this->fnArchive.GetTimes(& dtAccess, & dtModify, & dtCreate);
\r
606 fn.SetTimes(& dtAccess, & dtModify, & dtCreate);
\r
609 void MainFrame::OnArcAdd(wxCommandEvent& e)
\r
612 MakeDialog mkDlg(this, TPI_COMMAND_ADD);
\r
614 TPI_SWITCHES swInfo;
\r
615 swInfo.pCustomSwitches = NULL;
\r
617 if (e.GetClientData() == NULL)
\r
619 if (::wxGetKeyState(WXK_SHIFT))
\r
622 wxDirDialog dd(this, _("Choose dir to add"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0), wxDD_DIR_MUST_EXIST);
\r
623 if (dd.ShowModal() == wxID_CANCEL)
\r
627 swInfo.fnDestinationDirectory = wxFileName(dd.GetPath());
\r
628 this->conf.WriteHistory(CONF_HISTORY_PATH, swInfo.fnDestinationDirectory.GetPath());
\r
629 mkDlg.files.Add(swInfo.fnDestinationDirectory.GetFullName());
\r
634 wxFileDialog fd(this, _("Choose files to add"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0), wxEmptyString, wxFileSelectorDefaultWildcardStr, wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
\r
635 if (fd.ShowModal() == wxID_CANCEL)
\r
639 fd.GetFilenames(mkDlg.files);
\r
640 swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
\r
641 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
646 mkDlg.files = * (wxArrayString *) e.GetClientData();
\r
647 swInfo.fnDestinationDirectory = wxFileName::DirName(wxFileName(mkDlg.files[0]).GetPath());
\r
649 for (size_t n = 0; n < mkDlg.files.GetCount(); n++)
\r
651 wxFileName fn(mkDlg.files[n]);
\r
652 fn.MakeRelativeTo(swInfo.fnDestinationDirectory.GetPath());
\r
653 mkDlg.files[n] = fn.GetFullPath();
\r
658 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
664 swInfo.fMakeSFX = false;
\r
665 swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();
\r
666 swInfo.fSolid = mkDlg.cbSolid->IsChecked();
\r
667 swInfo.fMMOptimize = mkDlg.cbMMOptimize->IsChecked();
\r
668 swInfo.fEncryptHeader = mkDlg.cbEncryptHeader->IsChecked();
\r
669 swInfo.nCompressLevel = mkDlg.scLevel->GetValue();
\r
670 swInfo.nRecoveryRecord = mkDlg.scRR->GetValue();
\r
671 swInfo.szPassword = mkDlg.tcPassword->GetValue();
\r
672 swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
\r
673 swInfo.szComment = mkDlg.tcComment->GetValue();
\r
677 ProcessDialog procDlg(this, mkDlg.files.GetCount(), this->szPassword);
\r
678 procDlg.Show(true);
\r
680 tpi.Command(TPI_COMMAND_ADD, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files);
\r
681 this->ErrorCheck(tpi.nErrorCode);
\r
682 procDlg.Show(false);
\r
685 if (mkDlg.cbOpenAfter->IsChecked())
\r
688 ::wxExecute(DIR_APP + QuoteString(swInfo.fnDestinationDirectory.GetFullPath()));
\r
691 if (mkDlg.cbExitAfter->IsChecked())
\r
697 // 終了しない場合は書庫を再読み込み。
\r
698 this->OnArcOpen(e);
\r
701 void MainFrame::OnArcConvert(wxCommandEvent& e)
\r
703 TPI_SWITCHES swInfo;
\r
704 swInfo.fMakeSFX = e.GetId() == XRCID("Arc_SFX");
\r
707 wxFileDialog fd(this, swInfo.fMakeSFX ? _("Save as SFX") : _("Save as normal archive"), this->fnArchive.GetPath(), this->fnArchive.GetName() + (swInfo.fMakeSFX ? EXE_EXT : (wxString) wxEmptyString), wxFileSelectorDefaultWildcardStr, wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
\r
708 if (fd.ShowModal() == wxID_CANCEL)
\r
712 swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
\r
713 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
715 wxArrayString files;
\r
716 files.Add(fd.GetPath());
\r
718 ProcessDialog procDlg(this);
\r
719 procDlg.Show(true);
\r
720 tpi.Command(swInfo.fMakeSFX ? TPI_COMMAND_SFX : TPI_COMMAND_UNSFX, & swInfo, this->fnArchive.GetFullPath(), files);
\r
721 this->ErrorCheck(tpi.nErrorCode);
\r
722 procDlg.Show(false);
\r
725 void MainFrame::OnArcExtract(wxCommandEvent& e)
\r
727 TPI_SWITCHES swInfo;
\r
728 swInfo.pCustomSwitches = NULL;
\r
729 swInfo.szPassword = this->szPassword;
\r
731 // モード取得。通常は0, 実行なら1, ファイルDnDなら2、ディレクトリDnDなら3、クリップボードなら4、コンテキストメニューからなら8。
\r
732 int nMode = e.GetInt();
\r
733 if (e.GetInt() == 8)
\r
738 wxFileType * ftFile = NULL;
\r
740 // 展開ダイアログを作成。DnDまたは実行時は表示しない。
\r
741 MakeDialog mkDlg(this, TPI_COMMAND_EXTRACT);
\r
742 mkDlg.files = MakeTargetFileList(this, nMode == 1, nMode == 0);
\r
744 bool bMakeDir = false;
\r
748 swInfo.fStoreDirectoryPathes = false;
\r
749 wxString szDestDirBase = nMode == 3 ? this->tree_ctrl->GetItemText(this->tree_ctrl->GetSelection()) : wxT("tpi_tmp");
\r
750 if (szDestDirBase == wxT("-----"))
\r
752 // 書庫ルートのときは書庫名にしておく。
\r
753 szDestDirBase = this->fnArchive.GetName();
\r
755 swInfo.fnDestinationDirectory = MakeDirPath(wxFileName::DirName(wxStandardPaths::Get().GetTempDir()), szDestDirBase, true);
\r
756 if (! swInfo.fnDestinationDirectory.IsOk())
\r
758 wxLogError(_("Unable to make the temporary directory!"));
\r
764 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
770 swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();
\r
771 swInfo.fnDestinationDirectory = wxFileName::DirName(mkDlg.cbDir->GetValue());
\r
772 swInfo.szPassword = mkDlg.tcPassword->GetValue();
\r
773 swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
\r
775 // 必要なら書庫名でディレクトリを作成する。
\r
776 bMakeDir = WillMakeDirByArcName(this, & mkDlg);
\r
779 swInfo.fnDestinationDirectory = MakeDirPath(swInfo.fnDestinationDirectory, this->fnArchive.GetName(), true);
\r
780 if (! swInfo.fnDestinationDirectory.IsOk())
\r
782 wxLogError(_("Unable to make the destination directory!"));
\r
790 ProcessDialog procDlg(this, mkDlg.files.GetCount(), this->szPassword);
\r
791 procDlg.Show(true);
\r
793 tpi.Command(TPI_COMMAND_EXTRACT, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files);
\r
794 this->ErrorCheck(tpi.nErrorCode);
\r
795 procDlg.Show(false);
\r
800 if (mkDlg.cbOpenAfter->IsChecked())
\r
803 if (mkDlg.chDirMake->GetSelection() == 2 && ! bMakeDir)
\r
805 wxTreeItemId tiArcSub = this->tree_ctrl->GetLastChild(this->tree_ctrl->GetLastChild(this->tree_ctrl->GetRootItem()));
\r
806 if (tiArcSub.IsOk())
\r
808 swInfo.fnDestinationDirectory.SetFullName(this->tree_ctrl->GetItemText(tiArcSub));
\r
811 ::wxExecute(DIR_APP + QuoteString(swInfo.fnDestinationDirectory.GetFullPath()));
\r
814 if (mkDlg.cbExitAfter->IsChecked())
\r
825 ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(wxFileName(mkDlg.files[0], wxPATH_DOS).GetExt());
\r
826 if (! ftFile || ftFile->GetOpenCommand(wxEmptyString).IsEmpty())
\r
828 // 種類が取得できないときはテキストとみなす。
\r
829 ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(this->conf.ReadId(CONF_DEFAULT_EXT, (wxString) wxT("txt")));
\r
833 wxString szTempFile = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[0], wxPATH_DOS).GetFullName();
\r
834 bool fSuccess = tpi.nErrorCode == TPI_ERROR_SUCCESS && ftFile != NULL;
\r
835 myProcess * pCallback = new myProcess(szTempFile, swInfo.fnDestinationDirectory.GetPath());
\r
839 // Linuxでは引用符で囲む必要がある。
\r
840 fSuccess = ::wxExecute(ftFile->GetOpenCommand(QuoteString(szTempFile)), wxEXEC_ASYNC, pCallback) > 0;
\r
842 fSuccess = ::wxExecute(ftFile->GetOpenCommand(szTempFile), wxEXEC_ASYNC, pCallback) > 0;
\r
847 pCallback->OnTerminate(0, 0);
\r
853 wxArrayString asFiles;
\r
854 myFileDataObject * objFile = new myFileDataObject();
\r
855 objFile->szTempDir = nMode == 3 ? swInfo.fnDestinationDirectory.GetPath() : swInfo.fnDestinationDirectory.GetFullPath();
\r
856 for (size_t i = 0; i < mkDlg.files.GetCount(); i++)
\r
858 wxString szFileName = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[i], wxPATH_DOS).GetFullName();
\r
861 asFiles.Add(szFileName);
\r
866 objFile->AddFile(szFileName);
\r
871 objFile->AddFile(objFile->szTempDir);
\r
876 wxTheClipboard->SetData(objFile);
\r
880 // 自身にドロップされると煩雑なので、一時的にドロップを受け付けないようにしておく。
\r
881 this->SetDropTarget(NULL);
\r
884 wxDropSource dropSource(* objFile, this);
\r
885 wxDragResult drResult = dropSource.DoDragDrop();
\r
886 if (drResult != wxDragCancel && drResult != wxDragNone && drResult != wxDragMove)
\r
889 // Linuxではまだ処理が終わっていない(コンテキストメニューが表示されている)ので、とりあえず3秒だけ待つ。
\r
893 this->SetDropTarget(new myFileDropTarget(this));
\r
895 // ディレクトリDnDのときは、先にディレクトリの中のファイルを消しておく。
\r
898 for (size_t i = 0; i < asFiles.GetCount(); i++)
\r
900 chmod(asFiles[i].ToUTF8(), 0600);
\r
901 ::wxRemoveFile(asFiles[i]);
\r
911 void MainFrame::OnArcDelete(wxCommandEvent& e)
\r
913 // 全ファイル削除は危険ではないかと。
\r
914 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
916 // wxのバグで自動では無効化できないので、実行しようとしたときに無効化する。
\r
917 SetMenuToolState("Arc_Delete", false);
\r
921 if (::AskDlg(_("Are you sure to delete selected files?"), this) == wxNO)
\r
928 wxArrayString asFiles = MakeTargetFileList(this);
\r
929 ProcessDialog procDlg(this, asFiles.GetCount(), this->szPassword);
\r
930 procDlg.Show(true);
\r
932 TPI_SWITCHES swInfo;
\r
933 swInfo.szPassword = this->szPassword;
\r
934 tpi.Command(TPI_COMMAND_DELETE, & swInfo, this->fnArchive.GetFullPath(), asFiles);
\r
935 this->ErrorCheck(tpi.nErrorCode);
\r
936 procDlg.Show(false);
\r
940 this->OnArcOpen(e);
\r
943 void MainFrame::OnArcTest(wxCommandEvent&)
\r
946 wxArrayString asFiles = MakeTargetFileList(this);
\r
947 ProcessDialog procDlg(this, asFiles.GetCount(), this->szPassword);
\r
948 procDlg.Show(true);
\r
950 TPI_SWITCHES swInfo;
\r
951 swInfo.szPassword = this->szPassword;
\r
952 tpi.Command(TPI_COMMAND_TEST, & swInfo, this->fnArchive.GetFullPath(), asFiles);
\r
953 this->ErrorCheck(tpi.nErrorCode);
\r
954 procDlg.Show(false);
\r
957 void MainFrame::OnArcRepair(wxCommandEvent&)
\r
960 wxArrayString asFiles = MakeTargetFileList(this);
\r
961 ProcessDialog procDlg(this, asFiles.GetCount(), this->szPassword);
\r
962 procDlg.Show(true);
\r
964 TPI_SWITCHES swInfo;
\r
965 swInfo.szPassword = this->szPassword;
\r
966 tpi.Command(TPI_COMMAND_REPAIR, & swInfo, this->fnArchive.GetFullPath(), asFiles);
\r
967 this->ErrorCheck(tpi.nErrorCode);
\r
968 procDlg.Show(false);
\r
971 void MainFrame::OnExeCopy(wxCommandEvent & e)
\r
973 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
975 // wxのバグで自動では無効化できないので、実行しようとしたときに無効化する。
\r
976 this->menubar->Enable(XRCID("Exe_Copy"), false);
\r
980 if (! wxTheClipboard->Open())
\r
986 this->OnArcExtract(e);
\r
987 wxTheClipboard->Close();
\r
990 void MainFrame::OnViewMode(wxCommandEvent & e)
\r
993 this->menubar->Check(n, true);
\r
994 this->list_ctrl->SetSingleStyle(wxLC_REPORT, n == XRCID("Exe_View_Details"));
\r
995 this->list_ctrl->SetSingleStyle(wxLC_ICON, n == XRCID("Exe_View_Icons"));
\r
996 this->list_ctrl->SetSingleStyle(wxLC_LIST, n == XRCID("Exe_View_List"));
\r
999 void MainFrame::OnShowToolBar(wxCommandEvent & e)
\r
1001 this->toolbar->Show(e.IsChecked());
\r
1004 void MainFrame::OnShowStatusBar(wxCommandEvent & e)
\r
1006 this->statusbar->Show(e.IsChecked());
\r
1009 void MainFrame::OnSelectAll(wxCommandEvent &)
\r
1011 for (int i = 0; i < this->list_ctrl->GetItemCount(); i++)
\r
1013 this->list_ctrl->Select(i, true);
\r
1019 void MainFrame::OnTreeChanged(wxTreeEvent& e)
\r
1022 wxString szNodePath = TreeView_GetItemPath(this->tree_ctrl, e.GetItem());
\r
1024 this->list_ctrl->apShowFile.Clear();
\r
1025 this->list_ctrl->DeleteAllItems();
\r
1026 g_hIconLL.RemoveAll();
\r
1027 g_hIconLS.RemoveAll();
\r
1029 // 現在のアイテムの選択状態を無効にしておく。
\r
1030 long nSelected = this->list_ctrl->GetFirstSelected();
\r
1031 while (nSelected != -1)
\r
1033 this->list_ctrl->Select(nSelected, false);
\r
1034 nSelected = this->list_ctrl->GetNextSelected(nSelected);
\r
1038 this->list_ctrl->SetImageList(& g_hIconLL, wxIMAGE_LIST_NORMAL);
\r
1039 this->list_ctrl->SetImageList(& g_hIconLS, wxIMAGE_LIST_SMALL);
\r
1041 // 配列と比較し、パスが一致しなければ消す。
\r
1042 for (size_t i = 0; i < this->fileinfo.GetCount(); i++)
\r
1045 if (szNodePath == wxT("*") || szNodePath == this->fileinfo[i].fnFileName.GetPath())
\r
1047 // 項目がフォルダであるなら無視。
\r
1048 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
1053 // フィルタにかからなければ無視。
\r
1054 if (this->fileinfo[i].fnFileName.GetFullName().MakeLower().Find(this->tcFilter->GetValue().MakeLower()) == wxNOT_FOUND)
\r
1059 this->list_ctrl->apShowFile.Add(& this->fileinfo[i]);
\r
1064 this->list_ctrl->apShowFile.Sort(& ListCtrlCompareProc);
\r
1065 this->list_ctrl->SetItemCount(this->list_ctrl->apShowFile.GetCount());
\r
1068 void MainFrame::OnTreeBeginDrag(wxTreeEvent& e)
\r
1070 // TODO : アイテムが子階層を持っていても展開できない。
\r
1071 this->tree_ctrl->SelectItem(e.GetItem());
\r
1073 wxCommandEvent e1;
\r
1075 this->OnArcExtract(e1);
\r
1078 void MainFrame::OnContextMenu(wxContextMenuEvent& e)
\r
1080 wxPoint p = e.GetPosition();
\r
1081 this->list_ctrl->PopupMenu(this->menubar->GetMenu(1), p == wxDefaultPosition ? this->list_ctrl->GetPosition() : this->list_ctrl->ScreenToClient(p));
\r
1086 void MainFrame::OnListItemSelect(wxListEvent&)
\r
1088 // ファイルに対する動作の設定。但し、選択解除時はwxのバグで呼び出されない。
\r
1089 bool fEnable = this->list_ctrl->GetSelectedItemCount() > 0;
\r
1090 SetMenuToolState("Arc_Delete", fEnable && (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_DELETE) == TPI_COMMAND_DELETE && this->aiArchive.fiInfo.fArchive);
\r
1091 this->menubar->Enable(XRCID("Exe_Copy"), fEnable);
\r
1094 void MainFrame::OnListItemDClick(wxListEvent&)
\r
1098 this->OnArcExtract(e);
\r
1101 void MainFrame::OnListBeginDrag(wxListEvent&)
\r
1103 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
1105 // アイテムを選択せずドラッグしようとした場合。
\r
1111 this->OnArcExtract(e);
\r
1116 void MainFrame::OnFilter(wxCommandEvent&)
\r
1119 e.SetItem(this->tree_ctrl->GetSelection());
\r
1120 this->OnTreeChanged(e);
\r
1125 bool MainFrame::LoadTPI(const wxString & szFileName, wxULongLong_t * llFileCount)
\r
1127 // 書庫を開いていれば閉じておく。
\r
1129 this->OnArcClose(e);
\r
1132 wxDir fs(L_DIR_B_LIB);
\r
1133 wxString szTPIName;
\r
1134 if (fs.GetFirst(& szTPIName, wxT("*" TPI_EXT)))
\r
1139 if (! tpi.InitLibrary(L_DIR_B_LIB + szTPIName, szFileName, TPICallbackProc))
\r
1141 tpi.FreeLibrary();
\r
1146 if (! tpi.OpenArchive(szFileName, llFileCount))
\r
1148 tpi.FreeLibrary();
\r
1149 * llFileCount = 0;
\r
1154 while (fs.GetNext(& szTPIName));
\r
1159 int MainFrame::ErrorCheck(int nErrorCode, const wxString & szAPIName)
\r
1161 switch (nErrorCode)
\r
1163 case TPI_ERROR_SUCCESS:
\r
1164 case TPI_ERROR_S_ENDOFDATA:
\r
1165 case TPI_CALLBACK_CONTINUE:
\r
1167 case TPI_ERROR_D_UNSUPPORTED:
\r
1168 wxLogError(_("Sorry, this function is not supported yet."));
\r
1170 case TPI_ERROR_D_SKIPPED:
\r
1171 case TPI_CALLBACK_CANCEL:
\r
1174 wxLogError(_("Error: %s()!\nError code: %d"), szAPIName.c_str(), nErrorCode);
\r
1176 return nErrorCode;
\r