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 this->OnArcClose(e);
\r
58 if (! this->IsIconized() && ! this->IsMaximized())
\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
68 this->conf.WriteId(CONF_WINDOW_SPLITTER_POS, this->window_splitter->GetSashPosition());
\r
71 this->conf.WriteId(CONF_WINDOW_STATUSBAR, this->statusbar->IsShown());
\r
72 this->conf.WriteId(CONF_WINDOW_TOOLBAR, this->toolbar->IsShown());
\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
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_C_COMMENT, this->list_ctrl->GetColumnWidth(10));
\r
89 this->conf.WriteId(CONF_LISTVIEW_S_COLUMN, g_nSortColumn);
\r
90 this->conf.WriteId(CONF_LISTVIEW_S_ASCEND, g_fSortAscend);
\r
96 //******************************************************************************
\r
98 //******************************************************************************
\r
100 BEGIN_EVENT_TABLE(MainFrame, wxFrame)
\r
101 EVT_INIT_DIALOG( MainFrame::OnInit)
\r
103 EVT_MENU(XRCID("Arc_Create"), MainFrame::OnArcCreate)
\r
104 EVT_MENU(XRCID("Arc_Open"), MainFrame::OnArcOpen)
\r
105 EVT_MENU(XRCID("Arc_Close"), MainFrame::OnArcClose)
\r
106 EVT_MENU(XRCID("Arc_Clone"), MainFrame::OnArcClone)
\r
107 EVT_MENU(XRCID("Arc_Add"), MainFrame::OnArcAdd)
\r
108 EVT_MENU(XRCID("Arc_SFX"), MainFrame::OnArcConvert)
\r
109 EVT_MENU(XRCID("Arc_UnSFX"), MainFrame::OnArcConvert)
\r
110 EVT_MENU(XRCID("Exe_Exit"), MainFrame::OnExit)
\r
111 EVT_MENU(XRCID("Arc_Extract"), MainFrame::OnArcExtract)
\r
112 EVT_MENU(XRCID("Arc_Delete"), MainFrame::OnArcDelete)
\r
113 EVT_MENU(XRCID("Arc_Test"), MainFrame::OnArcTest)
\r
114 EVT_MENU(XRCID("Arc_Repair"), MainFrame::OnArcRepair)
\r
115 EVT_MENU(XRCID("Exe_Copy"), MainFrame::OnExeCopy)
\r
116 EVT_MENU(XRCID("Exe_View_Icons"), MainFrame::OnViewMode)
\r
117 EVT_MENU(XRCID("Exe_View_Details"),MainFrame::OnViewMode)
\r
118 EVT_MENU(XRCID("Exe_View_List"), MainFrame::OnViewMode)
\r
119 EVT_MENU(XRCID("Exe_View_ToolBar"),MainFrame::OnShowToolBar)
\r
120 EVT_MENU(XRCID("Exe_View_StatusBar"),MainFrame::OnShowStatusBar)
\r
121 EVT_MENU(XRCID("Exe_View_SelectAll"),MainFrame::OnSelectAll)
\r
123 EVT_TREE_SEL_CHANGED(XRCID("TreeView"), MainFrame::OnTreeChanged)
\r
124 EVT_TREE_BEGIN_DRAG( XRCID("TreeView"), MainFrame::OnTreeBeginDrag)
\r
125 EVT_COMMAND_CONTEXT_MENU(XRCID("TreeView"), MainFrame::OnContextMenu)
\r
127 EVT_LIST_ITEM_SELECTED( XRCID("ListView"), MainFrame::OnListItemSelect)
\r
128 EVT_LIST_ITEM_DESELECTED(XRCID("ListView"), MainFrame::OnListItemSelect)
\r
129 EVT_LIST_ITEM_ACTIVATED( XRCID("ListView"), MainFrame::OnListItemDClick)
\r
130 EVT_LIST_BEGIN_DRAG( XRCID("ListView"), MainFrame::OnListBeginDrag)
\r
131 EVT_COMMAND_CONTEXT_MENU(XRCID("ListView"), MainFrame::OnContextMenu)
\r
133 EVT_TEXT(XRCID("tcFilter"), MainFrame::OnFilter)
\r
136 //******************************************************************************
\r
138 //******************************************************************************
\r
140 void MainFrame::OnInit(wxInitDialogEvent&)
\r
143 this->menubar = this->GetMenuBar();
\r
144 this->toolbar = this->GetToolBar();
\r
145 this->statusbar = XRCCTRL(* this, "statusbar", wxStatusBar);
\r
146 this->tree_ctrl = XRCCTRL(* this, "TreeView", wxTreeCtrl);
\r
147 this->list_ctrl = XRCCTRL(* this, "ListView", myListCtrl);
\r
148 this->window_splitter = XRCCTRL(* this, "window_splitter", wxSplitterWindow);
\r
149 this->tcFilter = XRCCTRL(* this->toolbar, "tcFilter", wxTextCtrl);
\r
152 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
153 wxTheMimeTypesManager->Initialize(wxMAILCAP_ALL);
\r
158 icon.CopyFromBitmap(wxBitmap(L_DIR_S_ICO wxT("app.png"), wxBITMAP_TYPE_ANY));
\r
159 this->SetIcon(icon);
\r
162 this->OnArcClose(e);
\r
163 this->SetDropTarget(new myFileDropTarget(this));
\r
166 this->window_splitter->SetSashPosition(this->conf.ReadId(CONF_WINDOW_SPLITTER_POS, 200l));
\r
169 int nIconMode = this->conf.ReadId(CONF_LISTVIEW_SHOWMODE, 0l);
\r
170 e.SetId(nIconMode == 1 ? XRCID("Exe_View_Icons") : (nIconMode == 2 ? XRCID("Exe_View_List") : XRCID("Exe_View_Details")));
\r
171 this->OnViewMode(e);
\r
172 // wxGTKでは直接wxLC_VIRTUALを指定しないと反映されない。
\r
173 this->list_ctrl->SetSingleStyle(wxLC_VIRTUAL);
\r
174 this->list_ctrl->InsertColumn(0, _("Filename"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_FILENAME, 140l));
\r
175 this->list_ctrl->InsertColumn(1, _("Unpacked"), wxLIST_FORMAT_RIGHT, this->conf.ReadId(CONF_LISTVIEW_C_UNPACKED, 80l));
\r
176 this->list_ctrl->InsertColumn(2, _("Packed"), wxLIST_FORMAT_RIGHT, this->conf.ReadId(CONF_LISTVIEW_C_PACKED, 80l));
\r
177 this->list_ctrl->InsertColumn(3, _("Ratio"), wxLIST_FORMAT_RIGHT, this->conf.ReadId(CONF_LISTVIEW_C_RATIO, 50l));
\r
178 this->list_ctrl->InsertColumn(4, _("Method"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_METHOD, 60l));
\r
179 this->list_ctrl->InsertColumn(5, _("Attr"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_ATTR, 50l));
\r
180 this->list_ctrl->InsertColumn(6, _("Last modified"), wxLIST_FORMAT_RIGHT, this->conf.ReadId(CONF_LISTVIEW_C_LASTMOD, 150l));
\r
181 this->list_ctrl->InsertColumn(7, _("Path"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_PATH, 100l));
\r
182 this->list_ctrl->InsertColumn(8, _("Type"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_TYPE, 100l));
\r
183 this->list_ctrl->InsertColumn(9, _("No."), wxLIST_FORMAT_RIGHT, this->conf.ReadId(CONF_LISTVIEW_C_NO, 35l));
\r
184 this->list_ctrl->InsertColumn(10,_("Comment"), wxLIST_FORMAT_LEFT, this->conf.ReadId(CONF_LISTVIEW_C_COMMENT, 35l));
\r
185 g_nSortColumn = this->conf.ReadId(CONF_LISTVIEW_S_COLUMN, 9l);
\r
186 g_fSortAscend = this->conf.ReadId(CONF_LISTVIEW_S_ASCEND, true);
\r
188 // ツールバー/ステータスバー設定。
\r
189 int nStatusBarParts[] = {70, 70, 180, 50, -1};
\r
190 this->statusbar->SetFieldsCount(5, nStatusBarParts);
\r
191 this->SetStatusBarPane(-1);
\r
192 bool fShow = this->conf.ReadId(CONF_WINDOW_STATUSBAR, true);
\r
193 this->menubar->Check(XRCID("Exe_View_StatusBar"), fShow);
\r
194 this->statusbar->Show(fShow);
\r
195 fShow = this->conf.ReadId(CONF_WINDOW_TOOLBAR, true);
\r
196 this->menubar->Check(XRCID("Exe_View_ToolBar"), fShow);
\r
197 this->toolbar->Show(fShow);
\r
202 void MainFrame::OnExit(wxCommandEvent&)
\r
207 void MainFrame::OnArcCreate(wxCommandEvent& e)
\r
209 TPI_SWITCHES swInfo;
\r
210 swInfo.pCustomSwitches = NULL;
\r
214 mkDlg.SetParent(this);
\r
215 if (e.GetClientData() == NULL)
\r
218 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
219 if (fd.ShowModal() == wxID_CANCEL)
\r
223 swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
\r
224 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
225 fd.GetFilenames(mkDlg.files);
\r
229 mkDlg.files = * (wxArrayString *) e.GetClientData();
\r
230 swInfo.fnDestinationDirectory = wxFileName::DirName(wxFileName(mkDlg.files[0]).GetPath());
\r
232 for (size_t n = 0; n < mkDlg.files.GetCount(); n++)
\r
234 wxFileName fn(mkDlg.files[n]);
\r
235 fn.MakeRelativeTo(swInfo.fnDestinationDirectory.GetPath());
\r
236 mkDlg.files[n] = fn.GetFullPath();
\r
240 this->OnArcClose(e);
\r
241 // 書庫名はファイル名の拡張子より前、もしくはディレクトリ名。
\r
242 this->fnArchive = wxFileName(mkDlg.files[0]);
\r
243 this->fnArchive.SetName(mkDlg.files.GetCount() == 1 ? (this->fnArchive.GetName().IsEmpty() ? this->fnArchive.GetDirs().Last() : this->fnArchive.GetName()) : swInfo.fnDestinationDirectory.GetDirs().Last());
\r
244 this->fnArchive.SetEmptyExt();
\r
245 this->fnArchive.SetPath(swInfo.fnDestinationDirectory.GetPath());
\r
248 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
254 int nSelected = mkDlg.chType->GetSelection();
\r
255 swInfo.nArchiveType = mkDlg.afInfo[nSelected].nTypeId;
\r
256 swInfo.fStoreDirectoryPathes= ! mkDlg.cbIgnorePath->IsChecked();
\r
257 swInfo.fMakeSFX = mkDlg.cbMakeSFX->IsChecked();
\r
258 swInfo.fSolid = mkDlg.cbSolid->IsChecked();
\r
259 swInfo.fMMOptimize = mkDlg.cbMMOptimize->IsChecked();
\r
260 swInfo.fEncryptHeader = mkDlg.cbEncryptHeader->IsChecked();
\r
261 swInfo.fCompressHeader = mkDlg.cbCompressHeader->IsChecked();
\r
262 swInfo.nCompressLevel = mkDlg.scLevel->GetValue();
\r
263 swInfo.nRecoveryRecord = mkDlg.scRR->GetValue();
\r
264 swInfo.szPassword = mkDlg.tcPassword->GetValue();
\r
265 swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
\r
266 swInfo.szComment = mkDlg.tcComment->GetValue();
\r
267 mkDlg.cbSplitSize->GetValue().ToULongLong(& swInfo.nSplitSize);
\r
270 this->fnArchive = wxFileName(mkDlg.cbDir->GetValue(), mkDlg.cbFileName->GetValue());
\r
271 if (! tpi.InitLibrary(mkDlg.afInfo[nSelected].szTPIName, this->fnArchive.GetFullPath(), TPICallbackProc, mkDlg.afInfo[nSelected].nTypeId))
\r
273 this->ErrorCheck(tpi.nErrorCode, wxT("InitLibrary"));
\r
279 ProcessDialog procDlg;
\r
280 procDlg.fnArchive = & this->fnArchive;
\r
281 procDlg.nFileCount = mkDlg.files.GetCount();
\r
282 procDlg.Show(true);
\r
284 tpi.Command(TPI_COMMAND_CREATE, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files);
\r
285 this->ErrorCheck(tpi.nErrorCode);
\r
286 procDlg.Show(false);
\r
290 if (mkDlg.cbOpenAfter->IsChecked())
\r
293 ::wxExecute(DIR_APP + QuoteString(swInfo.fnDestinationDirectory.GetFullPath()));
\r
296 if (mkDlg.cbExitAfter->IsChecked())
\r
303 this->OnArcOpen(e);
\r
306 void MainFrame::OnArcOpen(wxCommandEvent& e)
\r
308 // モード取得。通常は0, それ以外で開く場合は1, ファイルDnDなら2。
\r
309 int nMode = e.GetInt() == 2 ? 2 : e.GetId() == XRCID("Arc_Open") ? 0 : 1;
\r
314 wxFileDialog fd(this, _("Choose an archive"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0), wxEmptyString, wxFileSelectorDefaultWildcardStr, wxFD_OPEN | wxFD_FILE_MUST_EXIST);
\r
315 if (fd.ShowModal() == wxID_CANCEL)
\r
319 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
320 this->fnArchive = wxFileName(fd.GetPath());
\r
324 ProcessDialog procDlg;
\r
325 procDlg.fnArchive = & this->fnArchive;
\r
326 procDlg.Show(true);
\r
328 // DnD以外で書庫を開く場合、TPIを読み込み。
\r
329 TPI_PROCESSINFO piInfo;
\r
330 if (! this->LoadTPI(this->fnArchive.GetFullPath(), & piInfo.fiInfo.nUnpackedSize))
\r
332 procDlg.Show(false);
\r
336 this->OnArcCreate(e);
\r
338 else if (this->IsShown())
\r
341 this->statusbar->SetStatusText(_("No plug-in supporting this archive was found!"), 4);
\r
345 wxLogError(_("No plug-in supporting this archive was found!"));
\r
351 piInfo.eMessage = TPI_MESSAGE_STATUS;
\r
352 piInfo.eStatus = 0x1001;
\r
353 if (this->ErrorCheck(procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo), wxT("Callback")) == TPI_CALLBACK_CANCEL)
\r
355 procDlg.Show(false);
\r
356 tpi.CloseArchive();
\r
358 this->OnArcClose(e);
\r
363 this->fileinfo.Alloc(piInfo.fiInfo.nUnpackedSize);
\r
366 this->conf.WriteHistory(CONF_HISTORY_PATH, this->fnArchive.GetPath());
\r
367 this->conf.WriteHistory(CONF_HISTORY_NAME, this->fnArchive.GetFullName());
\r
368 this->conf.WriteHistory(CONF_HISTORY_FULL, this->fnArchive.GetFullPath());
\r
370 // 書庫のアイコンを取得し、書庫ルートを作成。
\r
371 g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_closed.png"), wxBITMAP_TYPE_ANY));
\r
372 g_hIconT.Add(wxBitmap(L_DIR_S_ICO wxT("folder_open.png"), wxBITMAP_TYPE_ANY));
\r
373 this->tree_ctrl->SetImageList(& g_hIconT);
\r
375 idRoot = this->tree_ctrl->AddRoot(wxEmptyString),
\r
377 idArchive = this->tree_ctrl->AppendItem(idRoot, this->fnArchive.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName))),
\r
379 idArchive = this->tree_ctrl->AppendItem(idRoot, this->fnArchive.GetFullName(), g_hIconT.Add(GetFileTypeIcon(piInfo.fiInfo.fnFileName).ConvertToImage().Rescale(16, 16))),
\r
381 idArcRoot = this->tree_ctrl->AppendItem(idRoot, wxT("-----"), 0, 1);
\r
383 // 巨大書庫のときにファイル名検査を省略するか。
\r
384 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
387 if (tpi.GetFileInformation(& piInfo.fiInfo, true))
\r
389 piInfo.eStatus = 0x1002;
\r
390 piInfo.nProcessedSize = 0;
\r
393 piInfo.nProcessedSize++;
\r
394 if (this->ErrorCheck(procDlg.CallbackProc(TPI_NOTIFY_COMMON, & piInfo), wxT("Callback")) == TPI_CALLBACK_CANCEL)
\r
396 procDlg.Show(false);
\r
397 tpi.CloseArchive();
\r
399 this->OnArcClose(e);
\r
404 if (piInfo.fiInfo.szStoredName.IsEmpty())
\r
406 piInfo.fiInfo.szStoredName = this->fnArchive.GetName();
\r
407 if (piInfo.fiInfo.fnFileName.HasExt())
\r
409 piInfo.fiInfo.szStoredName += wxT('.') + piInfo.fiInfo.fnFileName.GetExt();
\r
411 piInfo.fiInfo.fnFileName = wxFileName(piInfo.fiInfo.szStoredName);
\r
416 wxString szPath = piInfo.fiInfo.fnFileName.GetPathWithSep(wxPATH_UNIX);
\r
417 if (szPath.StartsWith(wxT("/")) || szPath.StartsWith(wxT("./")))
\r
419 piInfo.fiInfo.fnFileName = wxFileName(szPath.AfterFirst(wxT('/')), piInfo.fiInfo.fnFileName.GetFullName(), wxPATH_DOS);
\r
422 if (piInfo.fiInfo.fnFileName.GetFullPath().IsEmpty() || piInfo.fiInfo.fnFileName.GetFullPath() == wxT("."))
\r
428 if (piInfo.fiInfo.szStoredName.Find(wxT('\r')) != wxNOT_FOUND
\r
429 || piInfo.fiInfo.szStoredName.Find(wxT('\n')) != wxNOT_FOUND
\r
430 || piInfo.fiInfo.szStoredName.Find(wxT('\t')) != wxNOT_FOUND)
\r
432 wxString sz = piInfo.fiInfo.fnFileName.GetFullPath();
\r
433 sz.Replace(wxT("\r"), wxT(" "));
\r
434 sz.Replace(wxT("\n"), wxT(" "));
\r
435 sz.Replace(wxT("\t"), wxT(" "));
\r
436 piInfo.fiInfo.eDanger = TRUE;
\r
437 piInfo.fiInfo.fnFileName = wxFileName(sz);
\r
438 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
444 if (piInfo.fiInfo.fnFileName.GetPathWithSep(wxPATH_UNIX).Find(wxT("../")) != wxNOT_FOUND)
\r
446 piInfo.fiInfo.eDanger = TRUE;
\r
447 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
449 // 空白の連続による拡張子偽装を検査。
\r
450 if (piInfo.fiInfo.fnFileName.GetFullName().Find(wxT(" ")) != wxNOT_FOUND)
\r
452 piInfo.fiInfo.eDanger = TRUE;
\r
453 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
456 for (wxChar c = 0x200c; c <= 0x206f; c++)
\r
458 if (piInfo.fiInfo.fnFileName.GetFullName().Find(c) != wxNOT_FOUND)
\r
460 piInfo.fiInfo.eDanger = TRUE;
\r
461 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
465 case 0x200f: c = 0x2027; break;
\r
466 case 0x202e: c = 0x2060; break;
\r
472 bool fDir = piInfo.fiInfo.dwAttribute & TPI_ATTRIBUTE_DIRECTORY ? true : false;
\r
473 TreeView_CheckNewerItem(this->tree_ctrl, idArcRoot, fDir ? piInfo.fiInfo.fnFileName.GetFullPath() : piInfo.fiInfo.fnFileName.GetPath(), true);
\r
475 // ディレクトリ属性を含むものについては情報を保存しない。
\r
482 this->fileinfo.Add(piInfo.fiInfo);
\r
484 while (tpi.GetFileInformation(& piInfo.fiInfo));
\r
487 // GetFileInformationがエラー終了した場合。
\r
488 this->ErrorCheck(tpi.nErrorCode, wxT("GetFileInformation"));
\r
491 tpi.GetArchiveInformation(& this->aiArchive);
\r
492 this->ErrorCheck(tpi.nErrorCode, wxT("GetArchiveInformation"));
\r
495 tpi.CloseArchive();
\r
496 this->ErrorCheck(tpi.nErrorCode, wxT("CloseArchive"));
\r
499 this->fileinfo.Shrink();
\r
500 this->tree_ctrl->Freeze();
\r
501 if (this->fileinfo.Count() < 10000)
\r
503 this->tree_ctrl->ExpandAll();
\r
504 this->tree_ctrl->SelectItem(idArchive);
\r
508 // ファイル数が多いとソートに時間がかかるので、書庫のルートを表示させる。
\r
509 this->tree_ctrl->Expand(idArcRoot);
\r
510 this->tree_ctrl->SelectItem(idArcRoot);
\r
513 this->tree_ctrl->ScrollTo(idArchive);
\r
514 this->tree_ctrl->SetScrollPos(wxHORIZONTAL, 0);
\r
515 this->tree_ctrl->Thaw();
\r
516 this->list_ctrl->atDangerItem.SetTextColour(* wxRED);
\r
517 this->list_ctrl->atEncryptedItem.SetTextColour(wxColour(wxT("forest green")));
\r
520 this->statusbar->SetStatusText(this->aiArchive.fiInfo.szTypeName, 0);
\r
521 this->statusbar->SetStatusText(wxString::Format(_("%u file(s)"), this->fileinfo.GetCount()), 1);
\r
522 this->statusbar->SetStatusText(wxString::Format(wxString("%" wxLongLongFmtSpec "uB -> %" wxLongLongFmtSpec "uB"), this->aiArchive.nUnpackedSize, this->aiArchive.nPackedSize), 2);
\r
523 this->statusbar->SetStatusText(wxString::Format(wxT("%3.1f%%"), this->aiArchive.wCompressRatio / 10.0), 3);
\r
524 this->statusbar->SetStatusText(this->fnArchive.GetFullPath(), 4);
\r
525 this->statusbar->SetToolTip(
\r
527 _("%s(%s)\nTPI: %s(%s)\nAccess: %s\nModify: %s\nCreate: %s\nComment:\n%s"),
\r
528 this->fnArchive.GetFullName().c_str(), this->aiArchive.fiInfo.szTypeName.c_str(),
\r
529 this->aiArchive.fiInfo.szTPIName.c_str(), this->aiArchive.fiInfo.szEngineName.c_str(),
\r
530 this->aiArchive.tmAccess.Format(_("%Y/%m/%d %H:%M:%S")).c_str(),
\r
531 this->aiArchive.tmModify.Format(_("%Y/%m/%d %H:%M:%S")).c_str(),
\r
532 this->aiArchive.tmCreate.Format(_("%Y/%m/%d %H:%M:%S")).c_str(),
\r
533 this->aiArchive.szComment.c_str()
\r
537 // ツールバー・メニューバー設定。ファイル選択時しか動作しない削除などは別に設定。
\r
538 SetMenuToolState("Arc_Close", true);
\r
539 SetMenuToolState("Arc_Add", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_ADD) == TPI_COMMAND_ADD && this->aiArchive.fiInfo.fArchive);
\r
540 SetMenuToolState("Arc_SFX", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_SFX) == TPI_COMMAND_SFX && ! this->aiArchive.fSFX);
\r
541 SetMenuToolState("Arc_UnSFX", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_UNSFX) == TPI_COMMAND_UNSFX && this->aiArchive.fSFX);
\r
542 SetMenuToolState("Arc_Extract", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_EXTRACT)== TPI_COMMAND_EXTRACT);
\r
543 SetMenuToolState("Arc_Test", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_TEST) == TPI_COMMAND_TEST);
\r
544 SetMenuToolState("Arc_Repair", (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_REPAIR) == TPI_COMMAND_REPAIR);
\r
545 this->menubar->Enable(XRCID("Arc_Clone"), true);
\r
547 procDlg.Show(false);
\r
551 void MainFrame::OnArcClose(wxCommandEvent& e)
\r
553 // ツリービュー・リストビュー設定。
\r
554 this->tree_ctrl->DeleteAllItems();
\r
555 this->list_ctrl->DeleteAllItems();
\r
556 this->list_ctrl->apShowFile.Clear();
\r
559 SetMenuToolState("Arc_Close", false);
\r
560 SetMenuToolState("Arc_Add", false);
\r
561 SetMenuToolState("Arc_SFX", false);
\r
562 SetMenuToolState("Arc_UnSFX", false);
\r
563 SetMenuToolState("Arc_Extract", false);
\r
564 SetMenuToolState("Arc_Delete", false);
\r
565 SetMenuToolState("Arc_Test", false);
\r
566 SetMenuToolState("Arc_Repair", false);
\r
567 this->menubar->Enable(XRCID("Arc_Clone"), false);
\r
569 for (int i = 0; i < this->statusbar->GetFieldsCount(); i++)
\r
571 this->statusbar->SetStatusText(wxEmptyString, i);
\r
573 this->statusbar->SetToolTip(wxEmptyString);
\r
574 this->fileinfo.Clear();
\r
575 this->aiArchive.szComment.Empty();
\r
576 this->aiArchive.fnArchive.Clear();
\r
577 this->aiArchive.fiInfo.szTypeName.Empty();
\r
578 this->aiArchive.fiInfo.szSuffix.Empty();
\r
579 this->aiArchive.fiInfo.szEngineName.Empty();
\r
580 this->aiArchive.fiInfo.szTPIName.Empty();
\r
582 g_hIconT.RemoveAll();
\r
583 g_hIconLL.RemoveAll();
\r
584 g_hIconLS.RemoveAll();
\r
586 // DnDで書庫を開くときは既に読み込まれているTPIを用いるので、解放してはいけない。
\r
587 if (e.GetExtraLong() == 0)
\r
593 void MainFrame::OnArcClone(wxCommandEvent&)
\r
596 wxFileDialog fd(this, _("Clone archive"), this->fnArchive.GetPath(), this->fnArchive.GetFullName(), wxFileSelectorDefaultWildcardStr, wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
\r
597 if (fd.ShowModal() == wxID_CANCEL)
\r
601 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
604 ::wxCopyFile(this->fnArchive.GetFullPath(), fd.GetPath());
\r
605 wxFileName fn(fd.GetPath());
\r
606 wxDateTime dtAccess, dtModify, dtCreate;
\r
607 this->fnArchive.GetTimes(& dtAccess, & dtModify, & dtCreate);
\r
608 fn.SetTimes(& dtAccess, & dtModify, & dtCreate);
\r
611 void MainFrame::OnArcAdd(wxCommandEvent& e)
\r
615 mkDlg.SetParent(this);
\r
616 mkDlg.uCommand = TPI_COMMAND_ADD;
\r
618 TPI_SWITCHES swInfo;
\r
619 swInfo.pCustomSwitches = NULL;
\r
621 if (e.GetClientData() == NULL)
\r
623 if (::wxGetKeyState(WXK_SHIFT))
\r
626 wxDirDialog dd(this, _("Choose dir to add"), this->conf.ReadHistory(CONF_HISTORY_PATH, 0), wxDD_DIR_MUST_EXIST);
\r
627 if (dd.ShowModal() == wxID_CANCEL)
\r
631 swInfo.fnDestinationDirectory = wxFileName(dd.GetPath());
\r
632 this->conf.WriteHistory(CONF_HISTORY_PATH, swInfo.fnDestinationDirectory.GetPath());
\r
633 mkDlg.files.Add(swInfo.fnDestinationDirectory.GetFullName());
\r
638 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
639 if (fd.ShowModal() == wxID_CANCEL)
\r
643 fd.GetFilenames(mkDlg.files);
\r
644 swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
\r
645 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
650 mkDlg.files = * (wxArrayString *) e.GetClientData();
\r
651 swInfo.fnDestinationDirectory = wxFileName::DirName(wxFileName(mkDlg.files[0]).GetPath());
\r
653 for (size_t n = 0; n < mkDlg.files.GetCount(); n++)
\r
655 wxFileName fn(mkDlg.files[n]);
\r
656 fn.MakeRelativeTo(swInfo.fnDestinationDirectory.GetPath());
\r
657 mkDlg.files[n] = fn.GetFullPath();
\r
662 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
668 swInfo.fMakeSFX = false;
\r
669 swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();
\r
670 swInfo.fSolid = mkDlg.cbSolid->IsChecked();
\r
671 swInfo.fMMOptimize = mkDlg.cbMMOptimize->IsChecked();
\r
672 swInfo.fEncryptHeader = mkDlg.cbEncryptHeader->IsChecked();
\r
673 swInfo.nCompressLevel = mkDlg.scLevel->GetValue();
\r
674 swInfo.nRecoveryRecord = mkDlg.scRR->GetValue();
\r
675 swInfo.szPassword = mkDlg.tcPassword->GetValue();
\r
676 swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
\r
677 swInfo.szComment = mkDlg.tcComment->GetValue();
\r
681 ProcessDialog procDlg;
\r
682 procDlg.fnArchive = & this->fnArchive;
\r
683 procDlg.nFileCount = mkDlg.files.GetCount();
\r
684 procDlg.Show(true);
\r
686 tpi.Command(TPI_COMMAND_ADD, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files);
\r
687 this->ErrorCheck(tpi.nErrorCode);
\r
688 procDlg.Show(false);
\r
691 if (mkDlg.cbOpenAfter->IsChecked())
\r
694 ::wxExecute(DIR_APP + QuoteString(swInfo.fnDestinationDirectory.GetFullPath()));
\r
697 if (mkDlg.cbExitAfter->IsChecked())
\r
703 // 終了しない場合は書庫を再読み込み。
\r
704 this->OnArcOpen(e);
\r
707 void MainFrame::OnArcConvert(wxCommandEvent& e)
\r
709 TPI_SWITCHES swInfo;
\r
710 swInfo.fMakeSFX = e.GetId() == XRCID("Arc_SFX");
\r
713 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
714 if (fd.ShowModal() == wxID_CANCEL)
\r
718 swInfo.fnDestinationDirectory = wxFileName::DirName(fd.GetDirectory());
\r
719 this->conf.WriteHistory(CONF_HISTORY_PATH, fd.GetDirectory());
\r
721 wxArrayString files;
\r
722 files.Add(fd.GetPath());
\r
724 ProcessDialog procDlg;
\r
725 procDlg.Show(true);
\r
726 tpi.Command(swInfo.fMakeSFX ? TPI_COMMAND_SFX : TPI_COMMAND_UNSFX, & swInfo, this->fnArchive.GetFullPath(), files);
\r
727 this->ErrorCheck(tpi.nErrorCode);
\r
728 procDlg.Show(false);
\r
731 void MainFrame::OnArcExtract(wxCommandEvent& e)
\r
733 TPI_SWITCHES swInfo;
\r
734 swInfo.pCustomSwitches = NULL;
\r
736 // モード取得。通常は0, 実行なら1, ファイルDnDなら2、ディレクトリDnDなら3、クリップボードなら4、コンテキストメニューからなら8。
\r
737 int nMode = e.GetInt();
\r
738 if (e.GetInt() == 8)
\r
743 wxFileType * ftFile = NULL;
\r
745 // 展開ダイアログを作成。DnDまたは実行時は表示しない。
\r
747 mkDlg.SetParent(this);
\r
748 mkDlg.uCommand = TPI_COMMAND_EXTRACT;
\r
749 mkDlg.files = MakeTargetFileList(this, nMode == 1, nMode == 0);
\r
751 bool bMakeDir = false;
\r
755 swInfo.fStoreDirectoryPathes = false;
\r
756 wxString szDestDirBase = nMode == 3 ? this->tree_ctrl->GetItemText(this->tree_ctrl->GetSelection()) : wxT("tpi_tmp");
\r
758 if (szDestDirBase == wxT("-----"))
\r
760 // 書庫ルートのときは書庫名にしておく。
\r
761 szDestDirBase = this->fnArchive.GetName();
\r
763 swInfo.fnDestinationDirectory = MakeDirPath(wxFileName::DirName(p.GetTempDir()), szDestDirBase, true);
\r
764 if (! swInfo.fnDestinationDirectory.IsOk())
\r
766 wxLogError(_("Unable to make the temporary directory!"));
\r
772 if (mkDlg.ShowModal() == wxID_CANCEL)
\r
778 swInfo.fStoreDirectoryPathes = ! mkDlg.cbIgnorePath->IsChecked();
\r
779 swInfo.fnDestinationDirectory = wxFileName::DirName(mkDlg.cbDir->GetValue());
\r
780 swInfo.szPassword = mkDlg.tcPassword->GetValue();
\r
781 swInfo.szKeyFile = mkDlg.tcKeyfile->GetValue();
\r
783 // 必要なら書庫名でディレクトリを作成する。
\r
784 bMakeDir = WillMakeDirByArcName(this, & mkDlg);
\r
787 swInfo.fnDestinationDirectory = MakeDirPath(swInfo.fnDestinationDirectory, this->fnArchive.GetName(), true);
\r
788 if (! swInfo.fnDestinationDirectory.IsOk())
\r
790 wxLogError(_("Unable to make the destination directory!"));
\r
798 ProcessDialog procDlg;
\r
799 procDlg.fnArchive = & this->fnArchive;
\r
800 procDlg.nFileCount = mkDlg.files.GetCount();
\r
801 procDlg.Show(true);
\r
803 tpi.Command(TPI_COMMAND_EXTRACT, & swInfo, this->fnArchive.GetFullPath(), mkDlg.files);
\r
804 this->ErrorCheck(tpi.nErrorCode);
\r
805 procDlg.Show(false);
\r
810 if (mkDlg.cbOpenAfter->IsChecked())
\r
813 if (mkDlg.chDirMake->GetSelection() == 2 && ! bMakeDir)
\r
815 wxTreeItemId tiArcSub = this->tree_ctrl->GetLastChild(this->tree_ctrl->GetLastChild(this->tree_ctrl->GetRootItem()));
\r
816 if (tiArcSub.IsOk())
\r
818 swInfo.fnDestinationDirectory.SetFullName(this->tree_ctrl->GetItemText(tiArcSub));
\r
821 ::wxExecute(DIR_APP + QuoteString(swInfo.fnDestinationDirectory.GetFullPath()));
\r
824 if (mkDlg.cbExitAfter->IsChecked())
\r
835 ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(wxFileName(mkDlg.files[0], wxPATH_DOS).GetExt());
\r
836 if (! ftFile || ftFile->GetOpenCommand(wxEmptyString).IsEmpty())
\r
838 // 種類が取得できないときはテキストとみなす。
\r
839 ftFile = wxTheMimeTypesManager->GetFileTypeFromExtension(this->conf.ReadId(CONF_DEFAULT_EXT, (wxString) wxT("txt")));
\r
843 wxString szTempFile = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[0], wxPATH_DOS).GetFullName();
\r
844 bool fSuccess = tpi.nErrorCode == TPI_ERROR_SUCCESS && ftFile != NULL;
\r
845 myProcess * pCallback = new myProcess(szTempFile, swInfo.fnDestinationDirectory.GetPath());
\r
849 // Linuxでは引用符で囲む必要がある。
\r
850 fSuccess = ::wxExecute(ftFile->GetOpenCommand(QuoteString(szTempFile)), wxEXEC_ASYNC, pCallback) > 0;
\r
852 fSuccess = ::wxExecute(ftFile->GetOpenCommand(szTempFile), wxEXEC_ASYNC, pCallback) > 0;
\r
857 pCallback->OnTerminate(0, 0);
\r
863 wxArrayString asFiles;
\r
864 myFileDataObject * objFile = new myFileDataObject();
\r
865 objFile->szTempDir = nMode == 3 ? swInfo.fnDestinationDirectory.GetPath() : swInfo.fnDestinationDirectory.GetFullPath();
\r
866 for (size_t i = 0; i < mkDlg.files.GetCount(); i++)
\r
868 wxString szFileName = swInfo.fnDestinationDirectory.GetPathWithSep() + wxFileName(mkDlg.files[i], wxPATH_DOS).GetFullName();
\r
871 asFiles.Add(szFileName);
\r
876 objFile->AddFile(szFileName);
\r
881 objFile->AddFile(objFile->szTempDir);
\r
886 wxTheClipboard->SetData(objFile);
\r
890 // 自身にドロップされると煩雑なので、一時的にドロップを受け付けないようにしておく。
\r
891 this->SetDropTarget(NULL);
\r
894 wxDropSource dropSource(* objFile, this);
\r
895 wxDragResult drResult = dropSource.DoDragDrop();
\r
896 if (drResult != wxDragCancel && drResult != wxDragNone && drResult != wxDragMove)
\r
899 // Linuxではまだ処理が終わっていない(コンテキストメニューが表示されている)ので、とりあえず3秒だけ待つ。
\r
903 this->SetDropTarget(new myFileDropTarget(this));
\r
905 // ディレクトリDnDのときは、先にディレクトリの中のファイルを消しておく。
\r
908 for (size_t i = 0; i < asFiles.GetCount(); i++)
\r
910 chmod(asFiles[i].ToUTF8(), 0600);
\r
911 ::wxRemoveFile(asFiles[i]);
\r
921 void MainFrame::OnArcDelete(wxCommandEvent& e)
\r
923 // 全ファイル削除は危険ではないかと。
\r
924 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
926 // wxのバグで自動では無効化できないので、実行しようとしたときに無効化する。
\r
927 SetMenuToolState("Arc_Delete", false);
\r
931 if (::AskDlg(_("Are you sure to delete selected files?"), this) == wxNO)
\r
938 wxArrayString asFiles = MakeTargetFileList(this);
\r
939 ProcessDialog procDlg;
\r
940 procDlg.fnArchive = & this->fnArchive;
\r
941 procDlg.nFileCount = asFiles.GetCount();
\r
942 procDlg.Show(true);
\r
944 TPI_SWITCHES swInfo;
\r
945 tpi.Command(TPI_COMMAND_DELETE, & swInfo, this->fnArchive.GetFullPath(), asFiles);
\r
946 this->ErrorCheck(tpi.nErrorCode);
\r
947 procDlg.Show(false);
\r
951 this->OnArcOpen(e);
\r
954 void MainFrame::OnArcTest(wxCommandEvent&)
\r
957 wxArrayString asFiles = MakeTargetFileList(this);
\r
958 ProcessDialog procDlg;
\r
959 procDlg.fnArchive = & this->fnArchive;
\r
960 procDlg.nFileCount = asFiles.GetCount();
\r
961 procDlg.Show(true);
\r
963 TPI_SWITCHES swInfo;
\r
964 bool bIsCorrect = tpi.Command(TPI_COMMAND_TEST, & swInfo, this->fnArchive.GetFullPath(), asFiles);
\r
965 procDlg.Show(false);
\r
969 wxLogMessage(_("This is a correct archive."));
\r
973 this->ErrorCheck(tpi.nErrorCode);
\r
977 void MainFrame::OnArcRepair(wxCommandEvent&)
\r
980 wxArrayString asFiles = MakeTargetFileList(this);
\r
981 ProcessDialog procDlg;
\r
982 procDlg.fnArchive = & this->fnArchive;
\r
983 procDlg.nFileCount = asFiles.GetCount();
\r
984 procDlg.Show(true);
\r
986 TPI_SWITCHES swInfo;
\r
987 tpi.Command(TPI_COMMAND_REPAIR, & swInfo, this->fnArchive.GetFullPath(), asFiles);
\r
988 this->ErrorCheck(tpi.nErrorCode);
\r
989 procDlg.Show(false);
\r
992 void MainFrame::OnExeCopy(wxCommandEvent & e)
\r
994 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
996 // wxのバグで自動では無効化できないので、実行しようとしたときに無効化する。
\r
997 this->menubar->Enable(XRCID("Exe_Copy"), false);
\r
1001 if (! wxTheClipboard->Open())
\r
1007 this->OnArcExtract(e);
\r
1008 wxTheClipboard->Close();
\r
1011 void MainFrame::OnViewMode(wxCommandEvent & e)
\r
1013 int n = e.GetId();
\r
1014 this->menubar->Check(n, true);
\r
1015 this->list_ctrl->SetSingleStyle(wxLC_REPORT, n == XRCID("Exe_View_Details"));
\r
1016 this->list_ctrl->SetSingleStyle(wxLC_ICON, n == XRCID("Exe_View_Icons"));
\r
1017 this->list_ctrl->SetSingleStyle(wxLC_LIST, n == XRCID("Exe_View_List"));
\r
1020 void MainFrame::OnShowToolBar(wxCommandEvent & e)
\r
1022 this->toolbar->Show(e.IsChecked());
\r
1025 void MainFrame::OnShowStatusBar(wxCommandEvent & e)
\r
1027 this->statusbar->Show(e.IsChecked());
\r
1030 void MainFrame::OnSelectAll(wxCommandEvent &)
\r
1032 for (int i = 0; i < this->list_ctrl->GetItemCount(); i++)
\r
1034 this->list_ctrl->Select(i, true);
\r
1040 void MainFrame::OnTreeChanged(wxTreeEvent& e)
\r
1043 wxString szNodePath = TreeView_GetItemPath(this->tree_ctrl, e.GetItem());
\r
1045 this->list_ctrl->apShowFile.Clear();
\r
1046 this->list_ctrl->DeleteAllItems();
\r
1047 g_hIconLL.RemoveAll();
\r
1048 g_hIconLS.RemoveAll();
\r
1050 // 現在のアイテムの選択状態を無効にしておく。
\r
1051 long nSelected = this->list_ctrl->GetFirstSelected();
\r
1052 while (nSelected != -1)
\r
1054 this->list_ctrl->Select(nSelected, false);
\r
1055 nSelected = this->list_ctrl->GetNextSelected(nSelected);
\r
1059 this->list_ctrl->SetImageList(& g_hIconLL, wxIMAGE_LIST_NORMAL);
\r
1060 this->list_ctrl->SetImageList(& g_hIconLS, wxIMAGE_LIST_SMALL);
\r
1062 // 配列と比較し、パスが一致しなければ消す。
\r
1063 for (size_t i = 0; i < this->fileinfo.GetCount(); i++)
\r
1066 if (szNodePath == wxT("*") || szNodePath == this->fileinfo[i].fnFileName.GetPath())
\r
1068 // 項目がフォルダであるなら無視。
\r
1069 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
1074 // フィルタにかからなければ無視。
\r
1075 if (this->fileinfo[i].fnFileName.GetFullName().MakeLower().Find(this->tcFilter->GetValue().MakeLower()) == wxNOT_FOUND)
\r
1080 this->list_ctrl->apShowFile.Add(& this->fileinfo[i]);
\r
1085 this->list_ctrl->apShowFile.Sort(& ListCtrlCompareProc);
\r
1086 this->list_ctrl->SetItemCount(this->list_ctrl->apShowFile.GetCount());
\r
1089 void MainFrame::OnTreeBeginDrag(wxTreeEvent& e)
\r
1091 // TODO : アイテムが子階層を持っていても展開できない。
\r
1092 this->tree_ctrl->SelectItem(e.GetItem());
\r
1094 wxCommandEvent e1;
\r
1096 this->OnArcExtract(e1);
\r
1099 void MainFrame::OnContextMenu(wxContextMenuEvent& e)
\r
1101 wxPoint p = e.GetPosition();
\r
1102 this->list_ctrl->PopupMenu(this->menubar->GetMenu(1), p == wxDefaultPosition ? this->list_ctrl->GetPosition() : this->list_ctrl->ScreenToClient(p));
\r
1107 void MainFrame::OnListItemSelect(wxListEvent&)
\r
1109 // ファイルに対する動作の設定。但し、選択解除時はwxのバグで呼び出されない。
\r
1110 bool fEnable = this->list_ctrl->GetSelectedItemCount() > 0;
\r
1111 SetMenuToolState("Arc_Delete", fEnable && (this->aiArchive.fiInfo.eSupportedCommand & TPI_COMMAND_DELETE) == TPI_COMMAND_DELETE && this->aiArchive.fiInfo.fArchive);
\r
1112 this->menubar->Enable(XRCID("Exe_Copy"), fEnable);
\r
1115 void MainFrame::OnListItemDClick(wxListEvent&)
\r
1119 this->OnArcExtract(e);
\r
1122 void MainFrame::OnListBeginDrag(wxListEvent&)
\r
1124 if (this->list_ctrl->GetSelectedItemCount() == 0)
\r
1126 // アイテムを選択せずドラッグしようとした場合。
\r
1132 this->OnArcExtract(e);
\r
1137 void MainFrame::OnFilter(wxCommandEvent&)
\r
1140 e.SetItem(this->tree_ctrl->GetSelection());
\r
1141 this->OnTreeChanged(e);
\r
1146 bool MainFrame::LoadTPI(const wxString & szFileName, wxULongLong_t * llFileCount)
\r
1148 // 書庫を開いていれば閉じておく。
\r
1150 this->OnArcClose(e);
\r
1153 wxDir fs(L_DIR_B_LIB);
\r
1154 wxString szTPIName;
\r
1155 if (fs.GetFirst(& szTPIName, wxT("*" TPI_EXT)))
\r
1160 if (! tpi.InitLibrary(L_DIR_B_LIB + szTPIName, szFileName, TPICallbackProc))
\r
1162 tpi.FreeLibrary();
\r
1167 if (! tpi.OpenArchive(szFileName, llFileCount))
\r
1169 tpi.FreeLibrary();
\r
1170 * llFileCount = 0;
\r
1175 while (fs.GetNext(& szTPIName));
\r
1180 int MainFrame::ErrorCheck(int nErrorCode, const wxString & szAPIName)
\r
1182 switch (nErrorCode)
\r
1184 case TPI_ERROR_SUCCESS:
\r
1185 case TPI_ERROR_S_ENDOFDATA:
\r
1186 case TPI_CALLBACK_CONTINUE:
\r
1188 case TPI_ERROR_D_UNSUPPORTED:
\r
1189 wxLogError(_("Sorry, this function is not supported yet."));
\r
1191 case TPI_ERROR_D_SKIPPED:
\r
1192 case TPI_CALLBACK_CANCEL:
\r
1193 wxLogError(_("This operation is canceled by the user."));
\r
1196 wxLogError(_("Error: %s()!\nError code: %d"), szAPIName.c_str(), nErrorCode);
\r
1198 return nErrorCode;
\r